Skip to content

Commit

Permalink
feat(datepicker): add is-required watcher
Browse files Browse the repository at this point in the history
  • Loading branch information
aesteves60 authored and dpellier committed Nov 28, 2024
1 parent ed820c0 commit c28d8ce
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const VALUE_DEFAULT_VALUE = null;
export class OdsDatepicker {
private datepickerInstance?: Datepicker;
private inputElement?: HTMLInputElement;
private observer?: MutationObserver;
private shouldUpdateIsInvalidState: boolean = false;

@Element() el!: HTMLElement;
Expand Down Expand Up @@ -198,6 +199,17 @@ export class OdsDatepicker {
if (!this.value && this.value !== 0 && (this.value !== VALUE_DEFAULT_VALUE || this.defaultValue)) {
this.value = this.defaultValue ? new Date(Datepicker.parseDate(this.defaultValue, this.format)) : null;
}

this.observer = new MutationObserver((mutations: MutationRecord[]) => {
for (const mutation of mutations) {
// When observing is-required, the inner element validity is not yet up-to-date
// so we observe the element required attribute instead
if (mutation.attributeName === 'required') {
updateInternals(this.internals, formatDate(this.value, this.format), this.inputElement);
this.isInvalid = !this.internals.validity.valid;
}
}
});
}

componentDidLoad(): void {
Expand Down Expand Up @@ -246,6 +258,17 @@ export class OdsDatepicker {

// Init the internals correctly as native element validity is now up-to-date
this.onValueChange(formatDate(this.value, this.format));

if (this.inputElement) {
this.observer?.observe(this.inputElement, {
attributeFilter: ['required'],
attributeOldValue: false,
});
}
}

disconnectedCallback(): void {
this.observer?.disconnect();
}

async formResetCallback(): Promise<void> {
Expand Down
6 changes: 3 additions & 3 deletions packages/ods/src/components/datepicker/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -122,20 +122,20 @@
<button id="datepicker-clear-button">Clear</button>
<button id="datepicker-reset-button">Reset</button>
<button id="datepicker-get-validity-button">GetValidity</button>
<button id="datepicker-update-value-button">update Value</button>
<button id="datepicker-update-required-button">update required</button>
<button id="datepicker-close-button">Close</button>
<script>
const datepickerMethods = document.getElementById('datepicker-methods');
// setTimeout(() => datepickerMethods.value = new Date(), 0);
const datepickerClearButton = document.getElementById('datepicker-clear-button');
const datepickerResetButton = document.getElementById('datepicker-reset-button');
const datepickerGetValidityButton = document.getElementById('datepicker-get-validity-button');
const datepickerUpdateValueButton = document.getElementById('datepicker-update-value-button');
const datepickerUpdateRequiredButton = document.getElementById('datepicker-update-required-button');
const datepickerCloseButton = document.getElementById('datepicker-close-button');

datepickerClearButton.addEventListener('click', () => datepickerMethods.clear());
datepickerResetButton.addEventListener('click', () => datepickerMethods.reset());
datepickerUpdateValueButton.addEventListener('click', () => datepickerMethods.value = new Date());
datepickerUpdateRequiredButton.addEventListener('click', () => datepickerMethods.isRequired = !datepickerMethods.isRequired);
datepickerCloseButton.addEventListener('click', () => datepickerMethods.close());
datepickerGetValidityButton.addEventListener('click', async() => {
console.log(await datepickerMethods.getValidity());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import type { SpecPage } from '@stencil/core/testing';
import { newSpecPage } from '@stencil/core/testing';
import { OdsDatepicker } from '../../src';

// @ts-ignore for test purposes
global.MutationObserver = jest.fn(() => ({
disconnect: jest.fn(),
observe: jest.fn(),
}));

describe('ods-datepicker rendering', () => {
let page: SpecPage;
let root: HTMLElement | undefined;
Expand Down

0 comments on commit c28d8ce

Please sign in to comment.