diff --git a/packages/angular/src/components.ts b/packages/angular/src/components.ts index eb1f8f57d4d..a1c16f394a1 100644 --- a/packages/angular/src/components.ts +++ b/packages/angular/src/components.ts @@ -321,21 +321,21 @@ export declare interface IxCardTitle extends Components.IxCardTitle {} @ProxyCmp({ - inputs: ['categories', 'filterState', 'hideIcon', 'i18nPlainText', 'icon', 'initialState', 'labelCategories', 'nonSelectableCategories', 'placeholder', 'repeatCategories', 'suggestions'] + inputs: ['categories', 'disabled', 'filterState', 'hideIcon', 'i18nPlainText', 'icon', 'labelCategories', 'nonSelectableCategories', 'placeholder', 'readonly', 'repeatCategories', 'suggestions'] }) @Component({ selector: 'ix-category-filter', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: ['categories', 'filterState', 'hideIcon', 'i18nPlainText', 'icon', 'initialState', 'labelCategories', 'nonSelectableCategories', 'placeholder', 'repeatCategories', 'suggestions'], + inputs: ['categories', 'disabled', 'filterState', 'hideIcon', 'i18nPlainText', 'icon', 'labelCategories', 'nonSelectableCategories', 'placeholder', 'readonly', 'repeatCategories', 'suggestions'], }) export class IxCategoryFilter { protected el: HTMLElement; constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) { c.detach(); this.el = r.nativeElement; - proxyOutputs(this, this.el, ['inputChanged', 'filterChanged']); + proxyOutputs(this, this.el, ['categoryChanged', 'inputChanged', 'filterChanged']); } } @@ -344,6 +344,10 @@ import type { InputState as IIxCategoryFilterInputState } from '@siemens/ix'; import type { FilterState as IIxCategoryFilterFilterState } from '@siemens/ix'; export declare interface IxCategoryFilter extends Components.IxCategoryFilter { + /** + * Event dispatched whenever the a category gets selected in the dropdown + */ + categoryChanged: EventEmitter>; /** * Event dispatched whenever the text input changes. */ @@ -792,14 +796,14 @@ export declare interface IxExpandingSearch extends Components.IxExpandingSearch @ProxyCmp({ - inputs: ['disabled'] + inputs: ['disabled', 'readonly'] }) @Component({ selector: 'ix-filter-chip', changeDetection: ChangeDetectionStrategy.OnPush, template: '', // eslint-disable-next-line @angular-eslint/no-inputs-metadata-property - inputs: ['disabled'], + inputs: ['disabled', 'readonly'], }) export class IxFilterChip { protected el: HTMLElement; diff --git a/packages/core/component-doc.json b/packages/core/component-doc.json index c47d01cd8d3..9175cd3437b 100644 --- a/packages/core/component-doc.json +++ b/packages/core/component-doc.json @@ -1300,20 +1300,22 @@ "usage": {}, "docs": "", "docsTags": [], - "encapsulation": "scoped", + "encapsulation": "shadow", "dependents": [], "dependencies": [ "ix-icon-button", "ix-icon", "ix-filter-chip", - "ix-dropdown" + "ix-dropdown", + "ix-spinner" ], "dependencyGraph": { "ix-category-filter": [ "ix-icon-button", "ix-icon", "ix-filter-chip", - "ix-dropdown" + "ix-dropdown", + "ix-spinner" ], "ix-icon-button": [ "ix-spinner", @@ -1339,6 +1341,23 @@ "optional": false, "required": false }, + { + "name": "disabled", + "type": "boolean", + "mutable": false, + "attr": "disabled", + "reflectToAttr": false, + "docs": "If true the filter will be in disabled state", + "docsTags": [], + "default": "false", + "values": [ + { + "type": "boolean" + } + ], + "optional": false, + "required": false + }, { "name": "filterState", "type": "FilterState", @@ -1404,27 +1423,6 @@ "optional": false, "required": false }, - { - "name": "initialState", - "type": "FilterState", - "mutable": false, - "reflectToAttr": false, - "docs": "When set this will initially populate the component with the provided search criteria.\nThis will trigger all input events accordingly.", - "docsTags": [ - { - "name": "deprecated", - "text": "Will be removed with 2.0.0. Use the member filterState instead." - } - ], - "deprecation": "Will be removed with 2.0.0. Use the member filterState instead.", - "values": [ - { - "type": "FilterState" - } - ], - "optional": false, - "required": false - }, { "name": "labelCategories", "type": "string", @@ -1474,6 +1472,23 @@ "optional": false, "required": false }, + { + "name": "readonly", + "type": "boolean", + "mutable": false, + "attr": "readonly", + "reflectToAttr": false, + "docs": "If true the filter will be in readonly mode", + "docsTags": [], + "default": "false", + "values": [ + { + "type": "boolean" + } + ], + "optional": false, + "required": false + }, { "name": "repeatCategories", "type": "boolean", @@ -1509,6 +1524,15 @@ ], "methods": [], "events": [ + { + "event": "categoryChanged", + "detail": "string", + "bubbles": true, + "cancelable": true, + "composed": true, + "docs": "Event dispatched whenever the a category gets selected in the dropdown", + "docsTags": [] + }, { "event": "filterChanged", "detail": "FilterState", @@ -4117,6 +4141,28 @@ ], "optional": false, "required": false + }, + { + "name": "readonly", + "type": "boolean", + "mutable": false, + "attr": "readonly", + "reflectToAttr": false, + "docs": "If true the filter chip will be in readonly mode", + "docsTags": [ + { + "name": "since", + "text": "2.0.0" + } + ], + "default": "false", + "values": [ + { + "type": "boolean" + } + ], + "optional": false, + "required": false } ], "methods": [], @@ -8798,6 +8844,7 @@ "ix-breadcrumb-item", "ix-burger-menu", "ix-button", + "ix-category-filter", "ix-icon-button", "ix-icon-toggle-button", "ix-modal-loading", @@ -8816,6 +8863,9 @@ "ix-button": [ "ix-spinner" ], + "ix-category-filter": [ + "ix-spinner" + ], "ix-icon-button": [ "ix-spinner" ], diff --git a/packages/core/scss/legacy/components/_forms.scss b/packages/core/scss/legacy/components/_forms.scss index 34bc6788f27..6eef2a855ff 100755 --- a/packages/core/scss/legacy/components/_forms.scss +++ b/packages/core/scss/legacy/components/_forms.scss @@ -159,4 +159,9 @@ input { &:disabled { color: var(--theme-input--color--disabled); } + + &:read-only, + &.readonly { + cursor: default; + } } diff --git a/packages/core/src/components.d.ts b/packages/core/src/components.d.ts index cc3e81a14b4..0b936bd1cd5 100644 --- a/packages/core/src/components.d.ts +++ b/packages/core/src/components.d.ts @@ -289,6 +289,10 @@ export namespace Components { options: string[]; }; }; + /** + * If true the filter will be in disabled state + */ + "disabled": boolean; /** * A set of search criteria to populate the component with. */ @@ -305,11 +309,6 @@ export namespace Components { * The icon next to the actual text input Defaults to 'search' */ "icon": string; - /** - * When set this will initially populate the component with the provided search criteria. This will trigger all input events accordingly. - * @deprecated Will be removed with 2.0.0. Use the member filterState instead. - */ - "initialState": FilterState; /** * i18n */ @@ -324,6 +323,10 @@ export namespace Components { * Placeholder text to be displayed in an empty input field. */ "placeholder": string; + /** + * If true the filter will be in readonly mode + */ + "readonly": boolean; /** * If set to true allows that a single category can be set more than once. An already set category will not appear in the category dropdown if set to false. Defaults to true */ @@ -798,6 +801,11 @@ export namespace Components { * If true the filter chip will be in disabled state */ "disabled": boolean; + /** + * If true the filter chip will be in readonly mode + * @since 2.0.0 + */ + "readonly": boolean; } interface IxFlipTile { /** @@ -3160,6 +3168,10 @@ declare namespace LocalJSX { options: string[]; }; }; + /** + * If true the filter will be in disabled state + */ + "disabled"?: boolean; /** * A set of search criteria to populate the component with. */ @@ -3176,11 +3188,6 @@ declare namespace LocalJSX { * The icon next to the actual text input Defaults to 'search' */ "icon"?: string; - /** - * When set this will initially populate the component with the provided search criteria. This will trigger all input events accordingly. - * @deprecated Will be removed with 2.0.0. Use the member filterState instead. - */ - "initialState"?: FilterState; /** * i18n */ @@ -3191,6 +3198,10 @@ declare namespace LocalJSX { "nonSelectableCategories"?: { [id: string]: string; }; + /** + * Event dispatched whenever the a category gets selected in the dropdown + */ + "onCategoryChanged"?: (event: IxCategoryFilterCustomEvent) => void; /** * Event dispatched whenever the filter state changes. */ @@ -3203,6 +3214,10 @@ declare namespace LocalJSX { * Placeholder text to be displayed in an empty input field. */ "placeholder"?: string; + /** + * If true the filter will be in readonly mode + */ + "readonly"?: boolean; /** * If set to true allows that a single category can be set more than once. An already set category will not appear in the category dropdown if set to false. Defaults to true */ @@ -3745,6 +3760,11 @@ declare namespace LocalJSX { * Close clicked */ "onCloseClick"?: (event: IxFilterChipCustomEvent) => void; + /** + * If true the filter chip will be in readonly mode + * @since 2.0.0 + */ + "readonly"?: boolean; } interface IxFlipTile { /** diff --git a/packages/core/src/components/button/base-button.tsx b/packages/core/src/components/button/base-button.tsx index 1a4d9a043e5..5b89da8f900 100644 --- a/packages/core/src/components/button/base-button.tsx +++ b/packages/core/src/components/button/base-button.tsx @@ -71,7 +71,7 @@ export function BaseButton(props: BaseButtonProps, children) { return ( + {this.renderOperatorButton()} @@ -539,7 +564,7 @@ export class CategoryFilter { private renderDropdownContent() { if (this.hasCategorySelection()) { - if (this.category) { + if (this.category !== undefined) { return this.renderCategoryValues(); } else { return this.renderCategorySelection(); @@ -559,7 +584,10 @@ export class CategoryFilter { data-id={id} title={this.categories[id].label} key={id} - onClick={() => this.selectCategory(id)} + onClick={(e) => { + e.preventDefault(); + this.selectCategory(id); + }} tabindex="0" > {this.categories[id]?.label} @@ -570,8 +598,8 @@ export class CategoryFilter { } private getDropdownHeader() { - if (this.categories) { - if (this.category) { + if (this.categories !== undefined) { + if (this.category !== undefined) { return null; } else { return this.labelCategories; @@ -596,31 +624,45 @@ export class CategoryFilter { onClick={() => this.resetFilter()} class={{ 'reset-button': true, - 'hide-reset-button': !this.filterTokens.length && !this.category, + 'hide-reset-button': + !this.filterTokens.length && this.category === undefined, }} - variant="primary" ghost oval icon="clear" size="16" - tabindex="1" > ); } + private getIconColor() { + if (this.disabled) { + return 'color-componentn-1'; + } + + if (this.readonly) { + return 'color-std-txt'; + } + + return 'color-primary'; + } + render() { return (
(this.formElement = el)}>
this.removeToken(index)} > {this.getFilterChipLabel(value)} @@ -648,7 +692,7 @@ export class CategoryFilter {
  • {this.categories[this.category]?.label} @@ -657,8 +701,13 @@ export class CategoryFilter { (this.textInput = el)} type="text" placeholder={this.placeholder} @@ -669,15 +718,19 @@ export class CategoryFilter {
  • - - {this.renderDropdownContent()} - + {this.disabled || this.readonly ? ( + '' + ) : ( + + {this.renderDropdownContent()} + + )}
    ); } diff --git a/packages/core/src/components/filter-chip/filter-chip.scss b/packages/core/src/components/filter-chip/filter-chip.scss index dc07a2fe830..707b1c45084 100644 --- a/packages/core/src/components/filter-chip/filter-chip.scss +++ b/packages/core/src/components/filter-chip/filter-chip.scss @@ -55,6 +55,10 @@ cursor: default; } +:host(.readonly) { + padding-right: $small-space; +} + @include host-hover { background-color: var(--theme-color-ghost-primary--hover); border-color: var(--theme-chip-primary-outline--border-color--hover); diff --git a/packages/core/src/components/filter-chip/filter-chip.tsx b/packages/core/src/components/filter-chip/filter-chip.tsx index 54679cd9cbe..3fd3ae1c2be 100644 --- a/packages/core/src/components/filter-chip/filter-chip.tsx +++ b/packages/core/src/components/filter-chip/filter-chip.tsx @@ -30,6 +30,12 @@ export class FilterChip { */ @Prop() disabled = false; + /** + * If true the filter chip will be in readonly mode + * @since 2.0.0 + */ + @Prop() readonly = false; + /** * Close clicked */ @@ -43,11 +49,14 @@ export class FilterChip { render() { return ( - +
    - {!this.disabled ? ( + {!this.disabled && !this.readonly ? ( Stencil Component Starter - diff --git a/packages/core/src/tests/category-filter/categories/index.html b/packages/core/src/tests/category-filter/categories/index.html index f1e4e3f5381..e5de45b4dd8 100644 --- a/packages/core/src/tests/category-filter/categories/index.html +++ b/packages/core/src/tests/category-filter/categories/index.html @@ -13,18 +13,16 @@ /> Stencil Component Starter + + + diff --git a/packages/core/src/tests/category-filter/category-filter.e2e.ts b/packages/core/src/tests/category-filter/category-filter.e2e.ts index 534d0810daa..6772f245d86 100644 --- a/packages/core/src/tests/category-filter/category-filter.e2e.ts +++ b/packages/core/src/tests/category-filter/category-filter.e2e.ts @@ -20,7 +20,7 @@ regressionTest.describe('category-filter', () => { regressionTest('categories', async ({ page }) => { await page.goto('category-filter/categories'); - await page.locator('input').click(); + await page.locator('input').first().click(); expect(await page.screenshot({ fullPage: true })).toMatchSnapshot(); }); diff --git a/packages/core/src/tests/category-filter/category-filter.e2e.ts-snapshots/category-filter-basic-1-chromium---theme-classic-dark-linux.png b/packages/core/src/tests/category-filter/category-filter.e2e.ts-snapshots/category-filter-basic-1-chromium---theme-classic-dark-linux.png index 4f2736f082f..6e80c9acc68 100644 Binary files a/packages/core/src/tests/category-filter/category-filter.e2e.ts-snapshots/category-filter-basic-1-chromium---theme-classic-dark-linux.png and b/packages/core/src/tests/category-filter/category-filter.e2e.ts-snapshots/category-filter-basic-1-chromium---theme-classic-dark-linux.png differ diff --git a/packages/core/src/tests/category-filter/category-filter.e2e.ts-snapshots/category-filter-basic-1-chromium---theme-classic-light-linux.png b/packages/core/src/tests/category-filter/category-filter.e2e.ts-snapshots/category-filter-basic-1-chromium---theme-classic-light-linux.png index 6a726b82659..731bce8863c 100644 Binary files a/packages/core/src/tests/category-filter/category-filter.e2e.ts-snapshots/category-filter-basic-1-chromium---theme-classic-light-linux.png and b/packages/core/src/tests/category-filter/category-filter.e2e.ts-snapshots/category-filter-basic-1-chromium---theme-classic-light-linux.png differ diff --git a/packages/core/src/tests/category-filter/category-filter.e2e.ts-snapshots/category-filter-categories-1-chromium---theme-classic-dark-linux.png b/packages/core/src/tests/category-filter/category-filter.e2e.ts-snapshots/category-filter-categories-1-chromium---theme-classic-dark-linux.png index f83b228b520..a3c00bef444 100644 Binary files a/packages/core/src/tests/category-filter/category-filter.e2e.ts-snapshots/category-filter-categories-1-chromium---theme-classic-dark-linux.png and b/packages/core/src/tests/category-filter/category-filter.e2e.ts-snapshots/category-filter-categories-1-chromium---theme-classic-dark-linux.png differ diff --git a/packages/core/src/tests/category-filter/category-filter.e2e.ts-snapshots/category-filter-categories-1-chromium---theme-classic-light-linux.png b/packages/core/src/tests/category-filter/category-filter.e2e.ts-snapshots/category-filter-categories-1-chromium---theme-classic-light-linux.png index 5076823eb26..0265bd9b9c5 100644 Binary files a/packages/core/src/tests/category-filter/category-filter.e2e.ts-snapshots/category-filter-categories-1-chromium---theme-classic-light-linux.png and b/packages/core/src/tests/category-filter/category-filter.e2e.ts-snapshots/category-filter-categories-1-chromium---theme-classic-light-linux.png differ diff --git a/packages/vue/src/components.ts b/packages/vue/src/components.ts index 7a451a593cb..a8dac6dc57d 100644 --- a/packages/vue/src/components.ts +++ b/packages/vue/src/components.ts @@ -110,7 +110,8 @@ export const IxCardTitle = /*@__PURE__*/ defineContainer('ix-ca export const IxCategoryFilter = /*@__PURE__*/ defineContainer('ix-category-filter', undefined, [ - 'initialState', + 'disabled', + 'readonly', 'filterState', 'placeholder', 'categories', @@ -122,6 +123,7 @@ export const IxCategoryFilter = /*@__PURE__*/ defineContainer('ix-filter-chip', undefined, [ 'disabled', + 'readonly', 'closeClick' ]);