fix(LionInputDatePicker): remove endless loop on InvalidDate modelValue (#1984)
* refactor: used IsDate validator instead of custom isValidDate function * fix: used IsDate validator to validate modelValue before it's passed to lion-calendar's selctedDate * test: Updated lion-input-datepicker tests to include example of handling invalid modelValue * docs: Updated docs to include example with invalid modelValue * refactor: updated returned type of __getSyncDownValue method * changset: updated changeset for @lion/ui * refactor: linting fix * refactor: import path updated Co-authored-by: gerjanvangeest <gerjanvangeest@users.noreply.github.com> * refactor: label added to Faulty prefilled datepicker input Co-authored-by: gerjanvangeest <gerjanvangeest@users.noreply.github.com> * test: updated test to include more obvious invalid date value --------- Co-authored-by: gerjanvangeest <gerjanvangeest@users.noreply.github.com>
This commit is contained in:
parent
d4085cc8c0
commit
e310c08af1
5 changed files with 43 additions and 13 deletions
5
.changeset/nasty-dodos-fold.md
Normal file
5
.changeset/nasty-dodos-fold.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@lion/ui': minor
|
||||
---
|
||||
|
||||
fix: LionInputDatePicker enters an endless loop on InvalidDate modelValue
|
||||
|
|
@ -76,3 +76,14 @@ export const readOnly = () => html`
|
|||
</lion-input-datepicker>
|
||||
`;
|
||||
```
|
||||
|
||||
## Faulty prefilled
|
||||
|
||||
Faulty prefilled input will be cleared
|
||||
|
||||
```js preview-story
|
||||
export const faultyPrefilled = () => html`
|
||||
<lion-input-datepicker label="Faulty prefiiled" .modelValue="${new Date('30/01/2022')}">
|
||||
</lion-input-datepicker>
|
||||
`;
|
||||
```
|
||||
|
|
|
|||
|
|
@ -2,16 +2,6 @@ import { IsDate } from '@lion/ui/form-core.js';
|
|||
import { LionInput } from '@lion/ui/input.js';
|
||||
import { formatDate, LocalizeMixin, parseDate } from '@lion/ui/localize-no-side-effects.js';
|
||||
|
||||
/**
|
||||
* @param {Date|number} date
|
||||
*/
|
||||
function isValidDate(date) {
|
||||
// to make sure it is a valid date we use isNaN and not Number.isNaN
|
||||
// @ts-ignore [allow]: dirty hack, you're not supposed to pass Date instances to isNaN
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
return date instanceof Date && !isNaN(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* `LionInputDate` has a .modelValue of type Date. It parses, formats and validates based
|
||||
* on locale.
|
||||
|
|
@ -51,7 +41,8 @@ export class LionInputDate extends LocalizeMixin(LionInput) {
|
|||
*/
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
serializer(modelValue) {
|
||||
if (!isValidDate(modelValue)) {
|
||||
const isDate = new IsDate();
|
||||
if (isDate.execute(modelValue)) {
|
||||
return '';
|
||||
}
|
||||
// modelValue is localized, so we take the timezone offset in milliseconds and subtract it
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { ScopedElementsMixin } from '@open-wc/scoped-elements';
|
|||
import { html, css } from 'lit';
|
||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||
import { LionInputDate } from '@lion/ui/input-date.js';
|
||||
import { IsDate } from '@lion/ui/form-core.js';
|
||||
import {
|
||||
OverlayMixin,
|
||||
withBottomSheetConfig,
|
||||
|
|
@ -376,7 +377,9 @@ export class LionInputDatepicker extends ScopedElementsMixin(
|
|||
* @returns {Date | undefined} a 'guarded' modelValue
|
||||
*/
|
||||
static __getSyncDownValue(modelValue) {
|
||||
return modelValue instanceof Date ? modelValue : undefined;
|
||||
const isDate = new IsDate();
|
||||
const hasError = isDate.execute(modelValue);
|
||||
return hasError ? undefined : modelValue;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -360,6 +360,26 @@ describe('<lion-input-datepicker>', () => {
|
|||
expect(el.__calendarMaxDate.toString()).to.equal(new Date('2019/07/15').toString());
|
||||
});
|
||||
|
||||
it('should show error on invalid date passed to modelValue', async () => {
|
||||
const myDate = new Date('foo');
|
||||
const el = await fixture(html`
|
||||
<lion-input-datepicker .modelValue="${myDate}"></lion-input-datepicker>
|
||||
`);
|
||||
expect(el.hasFeedbackFor).to.include('error');
|
||||
expect(el.validationStates).to.have.property('error');
|
||||
expect(el.validationStates.error).to.have.property('IsDate');
|
||||
});
|
||||
|
||||
it('should show error on date with invalid format passed to modelValue', async () => {
|
||||
const myDate = new Date('30/01/2022');
|
||||
const el = await fixture(html`
|
||||
<lion-input-datepicker .modelValue="${myDate}"></lion-input-datepicker>
|
||||
`);
|
||||
expect(el.hasFeedbackFor).to.include('error');
|
||||
expect(el.validationStates).to.have.property('error');
|
||||
expect(el.validationStates.error).to.have.property('IsDate');
|
||||
});
|
||||
|
||||
/**
|
||||
* Not in scope:
|
||||
* - min/max attr (like platform has): could be added in future if observers needed
|
||||
|
|
|
|||
Loading…
Reference in a new issue