diff --git a/.changeset/nasty-dodos-fold.md b/.changeset/nasty-dodos-fold.md
new file mode 100644
index 000000000..83ca0b14f
--- /dev/null
+++ b/.changeset/nasty-dodos-fold.md
@@ -0,0 +1,5 @@
+---
+'@lion/ui': minor
+---
+
+fix: LionInputDatePicker enters an endless loop on InvalidDate modelValue
diff --git a/docs/components/input-datepicker/use-cases.md b/docs/components/input-datepicker/use-cases.md
index f968371ac..38b663e7d 100644
--- a/docs/components/input-datepicker/use-cases.md
+++ b/docs/components/input-datepicker/use-cases.md
@@ -76,3 +76,14 @@ export const readOnly = () => html`
`;
```
+
+## Faulty prefilled
+
+Faulty prefilled input will be cleared
+
+```js preview-story
+export const faultyPrefilled = () => html`
+
+
+`;
+```
diff --git a/packages/ui/components/input-date/src/LionInputDate.js b/packages/ui/components/input-date/src/LionInputDate.js
index 7ef8edb85..3191033c5 100644
--- a/packages/ui/components/input-date/src/LionInputDate.js
+++ b/packages/ui/components/input-date/src/LionInputDate.js
@@ -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
diff --git a/packages/ui/components/input-datepicker/src/LionInputDatepicker.js b/packages/ui/components/input-datepicker/src/LionInputDatepicker.js
index 8598442d1..d32569d27 100644
--- a/packages/ui/components/input-datepicker/src/LionInputDatepicker.js
+++ b/packages/ui/components/input-datepicker/src/LionInputDatepicker.js
@@ -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,
@@ -373,10 +374,12 @@ export class LionInputDatepicker extends ScopedElementsMixin(
* The LionCalendar shouldn't know anything about the modelValue;
* it can't handle Unparseable dates, but does handle 'undefined'
* @param {?} modelValue
- * @returns {Date|undefined} a 'guarded' modelValue
+ * @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;
}
/**
diff --git a/packages/ui/components/input-datepicker/test/lion-input-datepicker.test.js b/packages/ui/components/input-datepicker/test/lion-input-datepicker.test.js
index 56060448f..f5be2b4f3 100644
--- a/packages/ui/components/input-datepicker/test/lion-input-datepicker.test.js
+++ b/packages/ui/components/input-datepicker/test/lion-input-datepicker.test.js
@@ -360,6 +360,26 @@ describe('', () => {
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`
+
+ `);
+ 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`
+
+ `);
+ 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