From a69f108ba8676b5f4c6f0d3dc4cfa9d483c89f53 Mon Sep 17 00:00:00 2001 From: matthiashader <144090716+matthiashader@users.noreply.github.com> Date: Mon, 9 Sep 2024 09:19:05 +0200 Subject: [PATCH] fix(core/category-filter): does not clear category preview (#1441) --- .changeset/brown-forks-repeat.md | 5 ++ packages/core/component-doc.json | 9 +-- packages/core/src/components.d.ts | 8 +-- .../category-filter/category-filter.tsx | 24 +++++--- .../test/category-filter.ct.ts | 61 +++++++++++++++++++ 5 files changed, 89 insertions(+), 18 deletions(-) create mode 100644 .changeset/brown-forks-repeat.md create mode 100644 packages/core/src/components/category-filter/test/category-filter.ct.ts diff --git a/.changeset/brown-forks-repeat.md b/.changeset/brown-forks-repeat.md new file mode 100644 index 0000000000..a76101e014 --- /dev/null +++ b/.changeset/brown-forks-repeat.md @@ -0,0 +1,5 @@ +--- +'@siemens/ix': patch +--- + +fix(core/category-filter): does not clear category preview diff --git a/packages/core/component-doc.json b/packages/core/component-doc.json index 4c763c577b..e3e9fa69e5 100644 --- a/packages/core/component-doc.json +++ b/packages/core/component-doc.json @@ -2170,7 +2170,7 @@ "type": "{ [id: string]: { label: string; options: string[]; }; }" } ], - "optional": false, + "optional": true, "required": false }, { @@ -2218,7 +2218,7 @@ "type": "FilterState" } ], - "optional": false, + "optional": true, "required": false }, { @@ -2234,6 +2234,7 @@ "reflectToAttr": false, "docs": "Allows to hide the icon inside the text input.\nDefaults to false", "docsTags": [], + "default": "false", "values": [ { "type": "boolean" @@ -2347,7 +2348,7 @@ "type": "string" } ], - "optional": false, + "optional": true, "required": false }, { @@ -2446,7 +2447,7 @@ "type": "string[]" } ], - "optional": false, + "optional": true, "required": false } ], diff --git a/packages/core/src/components.d.ts b/packages/core/src/components.d.ts index c6a0d1f467..730da09e6c 100644 --- a/packages/core/src/components.d.ts +++ b/packages/core/src/components.d.ts @@ -369,7 +369,7 @@ export namespace Components { /** * Configuration object hash used to populate the dropdown menu for type-ahead and quick selection functionality. Each ID maps to an object with a label and an array of options to select from. */ - "categories": { + "categories"?: { [id: string]: { label: string; options: string[]; @@ -382,7 +382,7 @@ export namespace Components { /** * A set of search criteria to populate the component with. */ - "filterState": FilterState; + "filterState"?: FilterState; /** * Allows to hide the icon inside the text input. Defaults to false */ @@ -408,7 +408,7 @@ export namespace Components { /** * Placeholder text to be displayed in an empty input field. */ - "placeholder": string; + "placeholder"?: string; /** * If true the filter will be in readonly mode */ @@ -425,7 +425,7 @@ export namespace Components { /** * A list of strings that will be supplied as type-ahead suggestions not tied to any categories. */ - "suggestions": string[]; + "suggestions"?: string[]; "tmpDisableScrollIntoView": boolean; } interface IxChip { diff --git a/packages/core/src/components/category-filter/category-filter.tsx b/packages/core/src/components/category-filter/category-filter.tsx index bc98eb1ec5..6a572a0545 100644 --- a/packages/core/src/components/category-filter/category-filter.tsx +++ b/packages/core/src/components/category-filter/category-filter.tsx @@ -34,9 +34,9 @@ export class CategoryFilter { @State() showDropdown: boolean; @State() private textInput?: HTMLInputElement; private formElement?: HTMLFormElement; - private isScrollStateDirty: boolean; + private isScrollStateDirty?: boolean; - @Element() hostElement: HTMLIxCategoryFilterElement; + @Element() hostElement!: HTMLIxCategoryFilterElement; @State() hasFocus: boolean; @State() categoryLogicalOperator = LogicalFilterOperator.EQUAL; @@ -61,18 +61,18 @@ export class CategoryFilter { /** * A set of search criteria to populate the component with. */ - @Prop() filterState: FilterState; + @Prop() filterState?: FilterState; /** * Placeholder text to be displayed in an empty input field. */ - @Prop() placeholder: string; + @Prop() placeholder?: string; /** * Configuration object hash used to populate the dropdown menu for type-ahead and quick selection functionality. * Each ID maps to an object with a label and an array of options to select from. */ - @Prop() categories: { + @Prop() categories?: { [id: string]: { label: string; options: string[]; @@ -93,7 +93,7 @@ export class CategoryFilter { /** * A list of strings that will be supplied as type-ahead suggestions not tied to any categories. */ - @Prop() suggestions: string[]; + @Prop() suggestions?: string[]; /** * The icon next to the actual text input @@ -105,7 +105,7 @@ export class CategoryFilter { * Allows to hide the icon inside the text input. * Defaults to false */ - @Prop() hideIcon: boolean; + @Prop() hideIcon: boolean = false; /** * If set categories will always be filtered via the respective logical operator. @@ -141,17 +141,17 @@ export class CategoryFilter { /** * Event dispatched whenever a category gets selected in the dropdown */ - @Event() categoryChanged: EventEmitter; + @Event() categoryChanged!: EventEmitter; /** * Event dispatched whenever the text input changes. */ - @Event() inputChanged: EventEmitter; + @Event() inputChanged!: EventEmitter; /** * Event dispatched whenever the filter state changes. */ - @Event() filterChanged: EventEmitter; + @Event() filterChanged!: EventEmitter; get dropdown() { return this.hostElement.shadowRoot.querySelector('ix-dropdown'); @@ -417,6 +417,10 @@ export class CategoryFilter { e.stopPropagation(); this.closeDropdown(); this.filterTokens = []; + if (this.category) { + this.category = undefined; + this.categoryChanged.emit(this.category); + } this.emitFilterEvent(); } diff --git a/packages/core/src/components/category-filter/test/category-filter.ct.ts b/packages/core/src/components/category-filter/test/category-filter.ct.ts new file mode 100644 index 0000000000..079395f06e --- /dev/null +++ b/packages/core/src/components/category-filter/test/category-filter.ct.ts @@ -0,0 +1,61 @@ +/* + * SPDX-FileCopyrightText: 2024 Siemens AG + * + * SPDX-License-Identifier: MIT + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import { test } from '@utils/test'; +import { expect } from '@playwright/test'; + +test('renders', async ({ mount, page }) => { + await mount(``); + const categoryFilter = page.locator('ix-category-filter'); + await expect(categoryFilter).toHaveClass(/hydrated/); +}); + +test.describe('category-preview test', () => { + test.beforeEach(async ({ mount, page }) => { + await mount( + ` + + ` + ); + + const categoryFilter = page.locator('ix-category-filter'); + await categoryFilter.evaluate((el: HTMLIxCategoryFilterElement) => { + el.categories = { + ID_1: { + label: 'Vendor', + options: ['Apple', 'MS', 'Siemens'], + }, + ID_2: { + label: 'Product', + options: ['iPhone X', 'Windows', 'APS'], + }, + }; + }); + }); + + test('clear category-preview', async ({ page }) => { + await page.waitForSelector('ix-category-filter'); + await page.locator('input').first().click(); + await page.locator('.category-item').first().click(); + + const categoryPreviewPromise = page.evaluate(() => { + return new Promise((resolve) => { + function onCategoryChanged(event) { + resolve(event.detail); + } + + document.addEventListener('categoryChanged', onCategoryChanged); + }); + }); + + await page.locator('ix-icon-button').first().click(); + const categoryPreview = await categoryPreviewPromise; + + expect(categoryPreview).toEqual(null); + }); +});