diff --git a/packages/components/src/components/input-text/input-text.clear-button.e2e.ts b/packages/components/src/components/input-text/input-text.clear-button.e2e.ts new file mode 100644 index 00000000000..9d510c5a6ac --- /dev/null +++ b/packages/components/src/components/input-text/input-text.clear-button.e2e.ts @@ -0,0 +1,50 @@ +import { expect } from '@playwright/test'; +import { test } from '@stencil/playwright'; + +test.describe('kol-input-text clear button', () => { + test('should render clear button when type is search and input has value', async ({ page }) => { + await page.setContent(''); + const clearButton = page.getByTestId('kol-input-text-clear-button'); + await expect(clearButton).toBeVisible(); + }); + + test('should not render clear button when type is not search', async ({ page }) => { + await page.setContent(''); + const clearButton = page.getByTestId('kol-input-text-clear-button'); + await expect(clearButton).not.toBeVisible(); + }); + + test('should not render clear button when input is empty', async ({ page }) => { + await page.setContent(''); + const clearButton = page.getByTestId('kol-input-text-clear-button'); + await expect(clearButton).not.toBeVisible(); + }); + + test('should render clear button when input has value', async ({ page }) => { + await page.setContent(''); + const clearButton = page.getByTestId('kol-input-text-clear-button'); + await expect(clearButton).toBeVisible(); + }); + + test('should clear input value when clear button is clicked', async ({ page }) => { + await page.setContent(''); + const input = page.locator('kol-input-text input'); + const clearButton = page.getByTestId('kol-input-text-clear-button'); + + await expect(input).toHaveValue('test'); + await clearButton.click(); + await expect(input).toHaveValue(''); + }); + + test('should not render clear button when disabled', async ({ page }) => { + await page.setContent(''); + const clearButton = page.getByTestId('kol-input-text-clear-button'); + await expect(clearButton).not.toBeVisible(); + }); + + test('should have correct aria-label', async ({ page }) => { + await page.setContent(''); + const clearButton = page.getByTestId('kol-input-text-clear-button'); + await expect(clearButton).toHaveAttribute('aria-label', 'Suche löschen'); + }); +}); diff --git a/packages/components/src/components/input-text/shadow.tsx b/packages/components/src/components/input-text/shadow.tsx index 48a61346e5c..46c5a7bbc9e 100644 --- a/packages/components/src/components/input-text/shadow.tsx +++ b/packages/components/src/components/input-text/shadow.tsx @@ -1,10 +1,12 @@ -import type { JSX } from '@stencil/core'; +import type { JSX, VNode } from '@stencil/core'; import { Component, Element, h, Method, Prop, State, Watch } from '@stencil/core'; import clsx from '../../utils/clsx'; import KolFormFieldStateWrapperFc, { type FormFieldStateWrapperProps } from '../../functional-component-wrappers/FormFieldStateWrapper/FormFieldStateWrapper'; import KolInputContainerFc from '../../functional-component-wrappers/InputContainerStateWrapper/InputContainerStateWrapper'; import KolInputStateWrapperFc, { type InputStateWrapperProps } from '../../functional-component-wrappers/InputStateWrapper/InputStateWrapper'; +import KolIconButtonFc from '../../functional-components/IconButton'; +import { translate } from '../../i18n'; import type { AccessKeyPropType, AriaDetailsPropType, @@ -100,6 +102,30 @@ export class KolInputText implements ClickableElement, FocusableElement, InputTe } }; + private readonly translateClearSearch = translate('kol-clear-search'); + + private getClearButton(): VNode | null { + if (this.state._type === 'search' && !this._disabled && this.state._hasValue) { + return ( + { + this._value = ''; + this.ctaRef.el?.focus(); + }} + icon="kolicon-x" + disabled={this._disabled} + /> + ); + } + + return null; + } + /** * Returns the current value. */ @@ -208,7 +234,7 @@ export class KolInputText implements ClickableElement, FocusableElement, InputTe public render(): JSX.Element { return ( - + diff --git a/packages/components/src/locales/de.ts b/packages/components/src/locales/de.ts index 3ad822762f7..21d6093e126 100644 --- a/packages/components/src/locales/de.ts +++ b/packages/components/src/locales/de.ts @@ -57,6 +57,7 @@ export default { 'close-alert': 'Benachrichtigung schließen', 'show-password': 'einblenden', 'hide-password': 'ausblenden', +t'clear-search': 'Suche löschen', 'no-results-message': 'Keine Ergebnisse gefunden.', 'delete-selection': 'Auswahl entfernen', 'filename-text': 'Datei auswählen oder hier ablegen...', diff --git a/packages/components/src/locales/en.ts b/packages/components/src/locales/en.ts index 77cb06efacb..1b7689c32c5 100644 --- a/packages/components/src/locales/en.ts +++ b/packages/components/src/locales/en.ts @@ -57,6 +57,7 @@ export default { 'close-alert': 'Close notification', 'show-password': 'Show', 'hide-password': 'Hide', +t'clear-search': 'Clear search', 'no-results-message': 'No results found.', 'delete-selection': 'Delete selection', 'filename-text': 'Choose a file or drop it here...', diff --git a/packages/samples/react/src/components/input-text/basic.tsx b/packages/samples/react/src/components/input-text/basic.tsx index 580ae794e56..c80c7526c16 100644 --- a/packages/samples/react/src/components/input-text/basic.tsx +++ b/packages/samples/react/src/components/input-text/basic.tsx @@ -7,7 +7,7 @@ import { SampleDescription } from '../SampleDescription'; export const InputTextBasic: FC = () => ( <> -

This story showcases the most important InputText variants: default, required, validation error, disabled, read-only, and with icons.

+

This story showcases the most important InputText variants: default, required, validation error, disabled, read-only, search with clear button, and with icons.

@@ -34,6 +34,7 @@ export const InputTextBasic: FC = () => ( +
); diff --git a/packages/samples/react/src/components/input-text/clear-button.tsx b/packages/samples/react/src/components/input-text/clear-button.tsx new file mode 100644 index 00000000000..52bb18df579 --- /dev/null +++ b/packages/samples/react/src/components/input-text/clear-button.tsx @@ -0,0 +1,19 @@ +import { KolInputText } from '@public-ui/react-v19'; +import type { FC } from 'react'; +import React from 'react'; +import { SampleDescription } from '../SampleDescription'; + +export const InputTextClearButton: FC = () => ( + <> + +

This sample demonstrates the clear button for search type input fields.

+
+ +
+ + + + +
+ +);