diff --git a/.changeset/orange-eyes-pump.md b/.changeset/orange-eyes-pump.md new file mode 100644 index 000000000000..56b05abcb789 --- /dev/null +++ b/.changeset/orange-eyes-pump.md @@ -0,0 +1,5 @@ +--- +"@db-ux/ngx-core-components": patch +--- + +DBInput: inserting an empty string doesn't reset/empty date or time related form fields diff --git a/.gitignore b/.gitignore index e7d0292811a6..27f36cbc3f4b 100644 --- a/.gitignore +++ b/.gitignore @@ -76,3 +76,4 @@ showcases/patternhub/public/iframe-resizer/* /packages/agent-cli/test/.amazonq/rules/db-ux.md /core-web.iml /build-storybooks/ +blob-report/ diff --git a/packages/components/scripts/post-build/components.ts b/packages/components/scripts/post-build/components.ts index 9177fff99b1d..ae1dea9fe8ec 100644 --- a/packages/components/scripts/post-build/components.ts +++ b/packages/components/scripts/post-build/components.ts @@ -368,7 +368,7 @@ export const getComponents = (): Component[] => [ from: 'writeValue(value: any) {', to: 'writeValue(value: any) {\n' + - 'if (!value && (this.type() === "date" ||\n' + + 'if (!value && value !== "" && (this.type() === "date" ||\n' + ' this.type() === "time" ||\n' + ' this.type() === "week" ||\n' + ' this.type() === "month" ||\n' + diff --git a/packages/components/src/components/input/input.spec.tsx b/packages/components/src/components/input/input.spec.tsx index 92b18ff851fe..584e81a5cd7a 100644 --- a/packages/components/src/components/input/input.spec.tsx +++ b/packages/components/src/components/input/input.spec.tsx @@ -76,8 +76,99 @@ const testAction = () => { await expect(input).not.toHaveAttribute('enterkeyhint'); await expect(input).not.toHaveAttribute('inputmode'); }); + + test('should handle empty string value for date input without clearing', async ({ + mount + }) => { + // Test with controlled value prop + let component = await mount( + + ); + let input = component.locator('input'); + await expect(input).toHaveValue('2024-01-15'); + + // Remount with empty string value - should accept empty string + await component.unmount(); + component = await mount(); + input = component.locator('input'); + + // The internal input value should be empty string, not null + const internalValue = await input.evaluate( + (el: HTMLInputElement) => el.value + ); + expect(internalValue).toBe(''); + }); + + test('should distinguish between undefined, null, and empty string for date input', async ({ + mount + }) => { + // Test with initial date value + let component = await mount( + + ); + let input = component.locator('input'); + await expect(input).toHaveValue('2024-01-15'); + + // Test empty string - should accept empty string as valid value + await component.unmount(); + component = await mount(); + input = component.locator('input'); + await expect(input).toHaveValue(''); + + // Test null - should also result in empty value + await component.unmount(); + component = await mount( + + ); + input = component.locator('input'); + await expect(input).toHaveValue(''); + + // Test undefined - should also result in empty value + await component.unmount(); + component = await mount( + + ); + input = component.locator('input'); + await expect(input).toHaveValue(''); + }); + + test('should handle empty string for datetime-local input', async ({ + mount + }) => { + // Test with initial datetime value + let component = await mount( + + ); + let input = component.locator('input'); + await expect(input).toHaveValue('2024-01-15T10:30'); + + // Test empty string - should accept empty string as valid value + await component.unmount(); + component = await mount( + + ); + input = component.locator('input'); + + await expect(input).toHaveValue(''); + }); }; +test('should handle null as empty for datetime-local input', async ({ mount }) => { + const component = await mount(); + const input = component.locator('input'); + await expect(input).toHaveValue(''); +}); + +test('should handle undefined as empty for datetime-local input', async ({ mount }) => { + const component = await mount(); + const input = component.locator('input'); + await expect(input).toHaveValue(''); +}); + test.describe('DBInput', () => { test.use({ viewport: DEFAULT_VIEWPORT }); testComponent(); diff --git a/showcases/angular-showcase/src/app/components/form/form.component.ts b/showcases/angular-showcase/src/app/components/form/form.component.ts index bfaca1fce4d1..d62371bf00ce 100644 --- a/showcases/angular-showcase/src/app/components/form/form.component.ts +++ b/showcases/angular-showcase/src/app/components/form/form.component.ts @@ -111,7 +111,7 @@ export class FormComponent { this.model.checkbox2 = false; this.form.get('input')?.setValue('reset'); this.form.get('textarea')?.setValue('reset'); - this.form.get('dateinput')?.setValue('reset'); + this.form.get('dateinput')?.setValue(''); this.form.get('checkbox')?.setValue(false); }