diff --git a/.changeset/funny-masks-laugh.md b/.changeset/funny-masks-laugh.md new file mode 100644 index 000000000..f9ea57003 --- /dev/null +++ b/.changeset/funny-masks-laugh.md @@ -0,0 +1,5 @@ +--- +'@equinor/fusion-wc-person': patch +--- + +Remove dependency for searchable-dropdown component \ No newline at end of file diff --git a/.changeset/yellow-carrots-play.md b/.changeset/yellow-carrots-play.md new file mode 100644 index 000000000..c71b74f81 --- /dev/null +++ b/.changeset/yellow-carrots-play.md @@ -0,0 +1,16 @@ +--- +'@equinor/fusion-wc-searchable-dropdown': major +'@equinor/fusion-wc-storybook': patch +--- + +### @equinor/fusion-wc-searchable-dropdown + +- Fix: support for setting selectedId in initalItems. +- Fix: better handling of multiple selections. +- Removed need for mutating result with isSelected, we now keep track of that in selectedItems set. +- Removed controllers _listItems array since we added getter method for flattening the elements to be able to select by index, and more easily loop over all list items. +- Renamed methods to align naming scheme with functionality. + +### @equinor/fusion-wc-storybook + +Fix: can use selectedId in stories and eslint diff --git a/packages/person/package.json b/packages/person/package.json index 9590baef7..942a99885 100644 --- a/packages/person/package.json +++ b/packages/person/package.json @@ -70,7 +70,6 @@ "@equinor/fusion-wc-core": "workspace:^", "@equinor/fusion-wc-icon": "workspace:^", "@equinor/fusion-wc-list": "workspace:^", - "@equinor/fusion-wc-searchable-dropdown": "workspace:^", "@equinor/fusion-wc-skeleton": "workspace:^", "@equinor/fusion-wc-textinput": "workspace:^", "@equinor/fusion-web-theme": "^0.1.10", diff --git a/packages/person/src/components/select/controller.ts b/packages/person/src/components/select/controller.ts index b4f7b789b..71e0e6268 100644 --- a/packages/person/src/components/select/controller.ts +++ b/packages/person/src/components/select/controller.ts @@ -1,9 +1,15 @@ import { ReactiveController } from 'lit'; import { PersonSelectElement } from './element'; -import { ExplicitEventTarget } from '@equinor/fusion-wc-searchable-dropdown'; import { PersonInfo } from '../../types'; +export interface ExplicitEventTarget extends Event { + readonly detail: { + index: number; + }; + readonly explicitOriginalTarget: HTMLInputElement; +} + type PersonSelectEventDetail = { selected: PersonInfo | null; }; @@ -62,7 +68,7 @@ export class PersonSelectController implements ReactiveController { } return selectedPerson; })(); - + // there are no selected person if (selectedPersonId === undefined) return; @@ -74,7 +80,7 @@ export class PersonSelectController implements ReactiveController { this.#host.upn = selectedPersonId; this.#host.azureId = undefined; return; - } + } // check if azureId is a valid guid if (selectedPersonId.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i)) { this.#host.azureId = selectedPersonId; diff --git a/packages/person/src/components/select/element.css.ts b/packages/person/src/components/select/element.css.ts index c1eb90135..9a3b5bdf2 100644 --- a/packages/person/src/components/select/element.css.ts +++ b/packages/person/src/components/select/element.css.ts @@ -1,9 +1,138 @@ -import { css, type CSSResult } from 'lit'; -import { sddStyles } from '@equinor/fusion-wc-searchable-dropdown'; +import { css, unsafeCSS, type CSSResult } from 'lit'; + +import { styles as theme } from '@equinor/fusion-web-theme'; + +const fwcsdd: CSSResult = css` + :host { + position: relative; + width: 100%; + --textinput-dense-size: 32px; + --fwc-list-item-vertical-padding: 0.5rem; + --fwc-text-field-base-color: ${unsafeCSS(theme.colors.text.static_icons__tertiary.getVariable('color'))}; + --fwc-text-field-fill-color: ${unsafeCSS(theme.colors.ui.background__light.getVariable('color'))}; + --fwc-text-field-ink-color: ${unsafeCSS(theme.colors.text.static_icons__default.getVariable('color'))}; + --fwc-text-field-disabled-ink-color: ${unsafeCSS(theme.colors.text.static_icons__default.getVariable('color'))}; + } + .input { + posistion: relative; + } + fwc-textinput { + width: 100%; + } + fwc-textinput[disabled] { + opacity: 0.5; + } + fwc-textinput[dense] { + --mdc-text-field-outlined-idle-border-color: transparent; + --mdc-shape-small: 0; + --mdc-text-field-outlined-hover-border-color: ${unsafeCSS( + theme.colors.interactive.primary__resting.getVariable('color'), + )}; + } + .interactive { + cursor: pointer; + } + [slot='trailing'] { + display: block; + position: absolute; + top: 2px; + right: 2px; + bottom: 2px; + display: flex; + justify-content: center; + align-items: center; + width: var(--textinput-dense-size); + color: ${unsafeCSS(theme.colors.interactive.primary__resting.getVariable('color'))}; + font-size: 0.8em; + } + .list { + position: absolute; + top: calc(100% + 4px); + left: 0; + width: 100%; + height: auto; + overflow: hidden; + z-index: 99; + box-shadow: + 0px 1px 5px rgba(0, 0, 0, 0.2), + 0px 3px 4px rgba(0, 0, 0, 0.12), + 0px 2px 4px rgba(0, 0, 0, 0.14); + border-radius: 4px; + } + .list-scroll { + width: 100%; + height: auto; + overflow: hidden auto; + scrollbar-width: thin; + scrollbar-color: ${unsafeCSS(theme.colors.ui.background__medium.getVariable('color'))} transparent; + } + fwc-list { + background-color: ${unsafeCSS(theme.colors.ui.background__light.getVariable('color'))}; + } + .variant-outlined fwc-list { + background-color: ${unsafeCSS(theme.colors.ui.background__default.getVariable('color'))}; + } + fwc-list-item { + --fwc-list-item-vertical-padding: 0.5rem; + } + fwc-list-item[disabled] { + background-color: ${unsafeCSS(theme.colors.ui.background__light.getVariable('color'))}; + } + fwc-list-item[disabled] [slot='graphic'], + fwc-list-item[disabled] [slot='meta'], + fwc-list-item[disabled] .item-text { + opacity: 0.6; + } + fwc-list-item[twoline] [slot='graphic'] svg { + font-size: 1.5rem; + } + .item-text { + display: flex; + flex-direction: column; + font-size: 1em; + } + .item-title { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + font-size: 1em; + line-height: 1.6; + } + .item-subtitle { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + font-size: 0.8em; + font-style: italic; + line-height: 1.6; + } + [slot='graphic'] { + display: flex; + } + [slot='graphic'] svg { + height: 1em; + width: auto; + } + fwc-divider { + display: flex; + align-items: center; + height: 1em; + } + .section-title { + font-weight: 600; + font-size: 16px; + padding: 0 1em; + margin: 1em 0 0; + } + .item-error { + --fwc-list-item-ink-color: ${unsafeCSS(theme.colors.interactive.danger__resting.getVariable('color'))}; + color: ${unsafeCSS(theme.colors.interactive.danger__resting.getVariable('color'))}; + } +`; // TODO - maybe this styling should be changed in parent! export const styles: CSSResult[] = [ - ...sddStyles, + ...[fwcsdd], css` fwc-list { --fwc-list-side-padding: 0.5rem; diff --git a/packages/person/src/components/select/element.ts b/packages/person/src/components/select/element.ts index 5bd05c4be..5945254e3 100644 --- a/packages/person/src/components/select/element.ts +++ b/packages/person/src/components/select/element.ts @@ -12,8 +12,6 @@ import { PersonSelectController } from './controller'; import { styles as psStyles } from './element.css'; import { PersonSearchTask, PersonSearchControllerHost, PersonInfoTask } from '../../tasks'; -import { SearchableDropdownControllerHost } from '@equinor/fusion-wc-searchable-dropdown'; - import type { PersonInfo, PersonSearchResult } from '../../types'; import type { SelectedPersonProp } from './index'; @@ -58,10 +56,7 @@ PersonAvatarElement; * interface renderListItems(items: TResult): HTMLTemplateResult; * ``` */ -export class PersonSelectElement - extends LitElement - implements SearchableDropdownControllerHost, PersonSearchControllerHost, SelectedPersonProp -{ +export class PersonSelectElement extends LitElement implements PersonSearchControllerHost, SelectedPersonProp { /* style object css */ static styles: CSSResult[] = psStyles; diff --git a/packages/searchable-dropdown/package.json b/packages/searchable-dropdown/package.json index b1312b508..4cdc477bf 100644 --- a/packages/searchable-dropdown/package.json +++ b/packages/searchable-dropdown/package.json @@ -20,7 +20,6 @@ "@equinor/fusion-wc-textinput": "workspace:^", "@equinor/fusion-web-theme": "^0.1.10", "@lit-labs/task": "^3.1.0", - "@material/mwc-textfield": "^0.27.0", "@types/uuid": "^10.0.0", "lit": "3.2.1", "uuid": "^10.0.0" @@ -28,7 +27,6 @@ "devDependencies": { "@custom-elements-manifest/analyzer": "^0.10.4", "@equinor/fusion-wc-builder": "workspace:^", - "@material/mwc-list": "^0.27.0", "tslib": "^2.8.1", "typescript": "^5.6.2" }, diff --git a/packages/searchable-dropdown/src/dropdown/element.css.ts b/packages/searchable-dropdown/src/dropdown/element.css.ts index 385cf0cb2..4f12b2b4e 100644 --- a/packages/searchable-dropdown/src/dropdown/element.css.ts +++ b/packages/searchable-dropdown/src/dropdown/element.css.ts @@ -1,11 +1,5 @@ import { css, unsafeCSS, type CSSResult } from 'lit'; import { styles as theme } from '@equinor/fusion-web-theme'; -/** - * @todo - * @eikeland - * Why this import, shouldn`t this come from @equinor/fusion-wc-textfield? - */ -import { styles as mdcStyle } from '@material/mwc-textfield/mwc-textfield.css'; export const fwcsdd: CSSResult = css` :host { @@ -118,6 +112,9 @@ export const fwcsdd: CSSResult = css` height: 1em; width: auto; } + [slot='meta'] { + display: flex; + } fwc-divider { display: flex; align-items: center; @@ -135,6 +132,6 @@ export const fwcsdd: CSSResult = css` } `; -export const sddStyles: CSSResult[] = [mdcStyle, fwcsdd]; +export const sddStyles: CSSResult[] = [fwcsdd]; export default sddStyles; diff --git a/packages/searchable-dropdown/src/dropdown/element.ts b/packages/searchable-dropdown/src/dropdown/element.ts index 82ee29929..c62baabb9 100644 --- a/packages/searchable-dropdown/src/dropdown/element.ts +++ b/packages/searchable-dropdown/src/dropdown/element.ts @@ -1,7 +1,7 @@ -import { html, LitElement, type HTMLTemplateResult, type CSSResult } from 'lit'; +import { html, LitElement, type HTMLTemplateResult, type CSSResult, PropertyValues } from 'lit'; import { unsafeHTML } from 'lit/directives/unsafe-html.js'; import { unsafeSVG } from 'lit/directives/unsafe-svg.js'; -import { property } from 'lit/decorators.js'; +import { property, state } from 'lit/decorators.js'; import { query } from 'lit/decorators/query.js'; @@ -43,12 +43,13 @@ import { sddStyles } from './element.css'; * @property {string} dropdownHeight Sets max-height of list so user can scroll trough results * @property {string} graphic Icon to show before each fwc-list-item. If you want an icon only on one list-item then use the meta property on the SearchableDropdownResultItem * @property {string} initialText Text to display in dropdown before/without querystring in fwc-textinput + * @property {string} noContentText Text to display in dropdown when no matches are found * @property {string} label Label for fwc-textinput element * @property {string} leadingIcon Leading Icon to display in fwc-text-input * @property {string} meta Icon to show after each fwc-list-item. If you want an icon only on one list-item then use the meta property on the SearchableDropdownResultItem * @property {string} multiple Able to select multiple items * @property {string} placeholder Placeholder text for fwc-textinput element - * @property {string} selectedId ID that should be highlighted in dropdown + * @property {string} selectedId ID that should be selected * @property {string} value value for TextInput element * @property {'page' | 'page-outlined' | 'page-dense' | 'header' | 'header-filled'} variant Set variant to header|page style * @@ -84,7 +85,7 @@ export class SearchableDropdownElement /* The trailing icon to display in fwc-textinput */ @property({ attribute: false, state: true }) - trailingIcon = ''; + trailingIcon = 'close'; @query('.trailing') trailingIconElement?: IconElement; @@ -105,6 +106,9 @@ export class SearchableDropdownElement @property() initialText = 'Start typing to search'; + @property() + noContentText = 'No content found'; + /* The leading icon to display in fwc-textinput */ @property() multiple = false; @@ -131,12 +135,26 @@ export class SearchableDropdownElement @query('fwc-list') listElement: ListElement | undefined; + @state() + selectedItems: Set = new Set([]); + + updated(props: PropertyValues) { + if (props.has('selectedId')) { + this.controller.updateSelectedByProp(); + } + } + /* Build fwc-list-items */ protected buildListItem(item: SearchableDropdownResultItem): HTMLTemplateResult { - this.controller._listItems.push(item.id); + const disabled = item.isDisabled || item.isError ? true : undefined; + + const graphic = item.graphic ?? this.graphic; + + const isSelected = this.selectedItems.has(item.id) || undefined; + const itemClasses = { 'list-item': true, - 'item-selected': !!item.isSelected, + 'item-selected': !!isSelected, 'item-error': !!item.isError, }; @@ -147,11 +165,6 @@ export class SearchableDropdownElement `; - const disabled = item.isDisabled || item.isError ? true : undefined; - const selected = item.isSelected ? true : undefined; - - const graphic = item.graphic ?? this.graphic; - /* Sett checkmark on selected items */ if (item.meta === 'check') { return html` @@ -180,14 +193,14 @@ export class SearchableDropdownElement key=${item.id} class=${classMap(itemClasses)} disabled=${ifDefined(disabled)} - selected=${ifDefined(selected)} + selected=${ifDefined(isSelected)} twoline=${ifDefined(item.subTitle)} graphic=${graphic ? 'icon' : ''} ?hasMeta=${!!item.meta} >
${this.renderItemGraphic(item)}
${text} -
${unsafeHTML(item.meta)}
+
${this.renderItemMeta(item)}
`; } @@ -205,6 +218,20 @@ export class SearchableDropdownElement } } + protected renderItemMeta(item: SearchableDropdownResultItem): ReturnType | void { + const { meta, metaType } = item; + switch (metaType) { + case 'inline-html': + return unsafeHTML(meta); + case 'inline-svg': + return unsafeSVG(meta); + default: + if (meta) { + return html``; + } + } + } + /** * Render the menu if state is open * @returns HTMLTemplateResult @@ -222,12 +249,6 @@ export class SearchableDropdownElement > ${this.controller.task.render({ complete: (result: SearchableDropdownResult) => { - /* - * clear previous render items. - * we need to save rendered items in state to be able to select them by index from action event - */ - this.controller._listItems = []; - /* Loop over task result */ return result.map((item, index) => { if (item.type === 'section') { @@ -264,6 +285,19 @@ export class SearchableDropdownElement `; } + protected renderCloseIcon(): HTMLTemplateResult { + if (this.controller.isOpen || this.selectedItems.size) { + return html``; + } + + return html``; + } /** * The main render function * @returns HTMLTemplateResult @@ -297,18 +331,10 @@ export class SearchableDropdownElement this.controller.isOpen = true; this.selectTextOnFocus && this.textInputElement?.select(); }} - @keyup=${this.controller.handleKeyup} + @input=${this.controller.handleKeyup} > - - - + ${this.renderCloseIcon()}
diff --git a/packages/searchable-dropdown/src/provider/controller.ts b/packages/searchable-dropdown/src/provider/controller.ts index e8c74fc9e..368dc56b8 100644 --- a/packages/searchable-dropdown/src/provider/controller.ts +++ b/packages/searchable-dropdown/src/provider/controller.ts @@ -5,7 +5,6 @@ import { SearchableDropdownResult, SearchableDropdownResolver, SearchableDropdownControllerHost, - SearchableDropdownResultItem, SearchableDropdownSelectEvent, } from '../types'; import { SearchableDropdownConnectEvent, ExplicitEventTarget } from '../types'; @@ -16,8 +15,6 @@ export class SearchableDropdownController implements ReactiveController { protected _isOpen = false; protected resolver?: SearchableDropdownResolver; - public _listItems: Array = []; - public _selectedItems: SearchableDropdownResult = []; public result?: SearchableDropdownResult; public task!: Task<[string], SearchableDropdownResult>; @@ -48,10 +45,14 @@ export class SearchableDropdownController implements ReactiveController { } } else { result = await this.resolver.searchQuery(qs); + if (!result.length) { + result = [{ id: 'no-result', title: this.#host.noContentText, isDisabled: true }]; + } } - // set isSelected on result items - this.result = this.mutateResult(result); - return this.result; + + this.result = result; + + return result; }, () => [this.#queryString], ); @@ -134,36 +135,70 @@ export class SearchableDropdownController implements ReactiveController { }; /** - * Mutates result to set parameters like isSelected. - * @param result SearchableDropdownResult - * @returns result + * Mutates the initialResult to set parameters like isSelected and selectedItems. */ - private mutateResult(result: SearchableDropdownResult) { - if (result) { - const { selectedId } = this.#host; - for (let i = 0; i < result.length; i++) { - const item = result[i]; - - if (item.type === 'section' && item.children?.length) { - for (let x = 0; x < item.children.length; x++) { - const kid = item.children[x]; - if (this._selectedItems.find((s) => s.id === kid.id) || selectedId === kid.id) { - kid.isSelected = true; - } else { - kid.isSelected = false; - } - } - } else { - if (this._selectedItems.find((s) => s.id === item.id) || selectedId === item.id) { - item.isSelected = true; - } else { - item.isSelected = false; - } - } + public updateSelectedByProp() { + const { selectedId } = this.#host; + + // clear any previous selectedItems when changing property + this.#host.selectedItems.clear(); + + // set selectedItems based on selectedId + if (selectedId !== null) { + const results = this.flatResult; + const item = results.find((item) => item.id === selectedId); + if (item) { + this.#host.selectedItems.add(item.id); } } - return result; + //set input value based on selectedItems + this.setHostValue(); + } + + /** + * Set host value based on selectedItems + */ + private setHostValue(): void { + this.#host.value = this.allSelectedItems.map((item) => item.title).join(', '); + } + + /** + * Get selectedItems objects from result array. + */ + private get allSelectedItems(): SearchableDropdownResult { + return this.flatResult.filter((item) => this.#host.selectedItems.has(item.id)); + } + + /** + * Helper that flattens result array to a single array. + * used to easily find selected items in result array and set isSelected by index. + * @important This method must return results in the same order as resolvers result + * to be able to use index to set selectedItems. + * @returns SearchableDropdownResult + */ + private get flatResult(): SearchableDropdownResult { + if (!this.result) { + return []; + } + + /** + * Create SearchableDropdownResult with all toplevel and child items + * excluding dividers and sections. + */ + return this.result.reduce((acc: SearchableDropdownResult, item) => { + // do not add dividers to acc + if (item.type === 'divider') { + return acc; + } + + // add sectioned children flatlist + if (item.type === 'section' && item.children) { + return [...acc, ...item.children]; + } + + return [...acc, item]; + }, []); } /** @@ -181,57 +216,31 @@ export class SearchableDropdownController implements ReactiveController { return; } - if (this.result && this._listItems) { - const id = this._listItems[event.detail.index]; - - /* Find selected item in resolver result list */ - let selectedItem: SearchableDropdownResultItem | undefined; - - // get selected item from result - for (const item of this.result) { - if (item.id === id) { - selectedItem = item; - break; - } else if (item.children) { - for (const childItem of item.children) { - if (childItem.id === id) { - selectedItem = childItem; - break; - } - } - } - } + // get a flat list of result to select by index + const results = this.flatResult; + if (!results.length) { + throw new Error('SearchableDropdownController could not find result set in resolver'); + } - /* Set Error if none matched the resolver result */ - if (!selectedItem?.id) { - throw new Error('SearchableDropdownController could not find a match in result provided by resolver.'); - } + // extract id from results by index + const { id } = results[event.detail.index]; + if (!id) { + throw new Error('SearchableDropdownController could not find selected item in resolver'); + } - /* Set active state and save selected item in state */ - if (this.#host.multiple) { - if (this._selectedItems.find((si) => si.id === selectedItem?.id)) { - /* Already selected so clear it from selections */ - selectedItem.isSelected = false; - this._selectedItems = this._selectedItems.filter((i) => i.id !== selectedItem?.id); - this.#host.value = ''; - } else { - /* Adds new item to selections */ - selectedItem.isSelected = true; - this._selectedItems.push(selectedItem); - this.#host.value = selectedItem?.title || ''; - } - } else { - /* Adds new item to selections */ - this._selectedItems = [selectedItem]; - this.#host.value = selectedItem?.title || ''; - } + /* De-select if already selected */ + if (this.#host.selectedItems.has(id)) { + this.#host.selectedItems.delete(id); } else { - /* FALSE === this.result && this._listItems */ - /* Clear selected states */ - this._selectedItems = []; - this.#host.value = ''; + if (!this.#host.multiple) { + this.#host.selectedItems.clear(); + } + this.#host.selectedItems.add(id); } + // set input value based on selectedItems + this.setHostValue(); + if (!this.#host.multiple) { this.isOpen = false; } @@ -240,17 +249,11 @@ export class SearchableDropdownController implements ReactiveController { this.#host.dispatchEvent( new SearchableDropdownSelectEvent({ detail: { - selected: this._selectedItems, + selected: this.allSelectedItems, }, bubbles: true, }), ); - - /* Sets items isSelected in task */ - this.task.run(); - - /* Refresh host */ - this.#host.requestUpdate(); } /** @@ -274,12 +277,12 @@ export class SearchableDropdownController implements ReactiveController { /* needed to clear user input */ if (this.#host.textInputElement) { - this.#host.textInputElement.value = ''; this.#host.textInputElement.blur(); } - this.#host.value = ''; - this._selectedItems = []; + this.#host.selectedItems.clear(); + this.setHostValue(); + this.#queryString = ''; /* also runs task */ @@ -304,11 +307,8 @@ export class SearchableDropdownController implements ReactiveController { public set isOpen(state: boolean) { this._isOpen = state; - // toogle close icon - this.#host.trailingIcon = state ? 'close' : ''; - /* syncs dropdown list with textinput */ - if (this._selectedItems) { + if (this.#host.selectedItems.size) { this.task.run(); } @@ -351,6 +351,7 @@ export class SearchableDropdownController implements ReactiveController { if (this.timer) { clearTimeout(this.timer); } + this.timer = setTimeout(() => { this.#queryString = target.value.trim().toLowerCase(); this.#host.requestUpdate(); diff --git a/packages/searchable-dropdown/src/types.ts b/packages/searchable-dropdown/src/types.ts index 5944d1cc6..fcd4d6991 100644 --- a/packages/searchable-dropdown/src/types.ts +++ b/packages/searchable-dropdown/src/types.ts @@ -1,5 +1,4 @@ import { ReactiveControllerHost } from 'lit'; -import { type ActionDetail } from '@material/mwc-list/mwc-list-foundation'; import { TextInputElement } from '@equinor/fusion-wc-textinput'; import { ListElement } from '@equinor/fusion-wc-list'; import { IconElement, IconType } from '@equinor/fusion-wc-icon'; @@ -66,6 +65,7 @@ export interface SearchableDropdownResultItem { isError?: boolean; isSelected?: boolean; meta?: string; + metaType?: IconType | 'inline-svg' | 'inline-html'; subTitle?: string; title?: string; type?: 'section' | 'divider' | null; @@ -89,11 +89,15 @@ export interface SearchableDropdownControllerHost extends SearchableDropdownProp renderRoot: HTMLElement | DocumentFragment; trailingIcon: string; trailingIconElement?: IconElement; + selectedItems: Set; + noContentText: string; id: string; } export interface ExplicitEventTarget extends Event { - readonly detail: ActionDetail; + readonly detail: { + index: number; + }; readonly explicitOriginalTarget: HTMLInputElement; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ecd025a2e..f843a3ebe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -481,9 +481,6 @@ importers: '@equinor/fusion-wc-list': specifier: workspace:^ version: link:../list - '@equinor/fusion-wc-searchable-dropdown': - specifier: workspace:^ - version: link:../searchable-dropdown '@equinor/fusion-wc-skeleton': specifier: workspace:^ version: link:../skeleton @@ -670,9 +667,6 @@ importers: '@lit-labs/task': specifier: ^3.1.0 version: 3.1.0 - '@material/mwc-textfield': - specifier: ^0.27.0 - version: 0.27.0 '@types/uuid': specifier: ^10.0.0 version: 10.0.0 @@ -689,9 +683,6 @@ importers: '@equinor/fusion-wc-builder': specifier: workspace:^ version: link:../../utils/builder - '@material/mwc-list': - specifier: ^0.27.0 - version: 0.27.0 tslib: specifier: ^2.8.1 version: 2.8.1 diff --git a/storybook/stories/input/searchable-dropdown-provider.ts b/storybook/stories/input/searchable-dropdown-provider.ts index 798df4d83..d63f29bf0 100644 --- a/storybook/stories/input/searchable-dropdown-provider.ts +++ b/storybook/stories/input/searchable-dropdown-provider.ts @@ -7,6 +7,9 @@ import { faker } from '@faker-js/faker'; import { html } from 'lit'; import appIconSvgTemplate from './appIconSvg.svg'; +import { ChipElement } from '@equinor/fusion-wc-chip'; +ChipElement; + SearchableDropdownProviderElement; faker.seed(123); @@ -52,8 +55,9 @@ const resolver: SearchableDropdownResolver = { graphic: `
${appIconSvgTemplate}
`, graphicType: 'inline-svg', meta: '', + metaType: 'inline-html', }), - item({ title: 'Context 1', graphic: 'list' }), + item({ title: 'Context 1', graphic: 'list', meta: 'alarm' }), item({ title: 'Context 2', graphic: 'list', isDisabled: true }), item({ title: 'Context 3', subTitle: 'sub title 3', graphic: 'list' }), item({ title: 'Context 4', subTitle: 'sub title 4', graphic: 'list', isError: true }), @@ -73,6 +77,6 @@ const resolver: SearchableDropdownResolver = { ], }; -export const searchableDropdownProviderDecorator = (story) => { - return html` ${story()} `; +export const searchableDropdownProviderDecorator = (story: CallableFunction) => { + return html`${story()} `; }; diff --git a/storybook/stories/input/searchable-dropdown.stories.ts b/storybook/stories/input/searchable-dropdown.stories.ts index 7eae78adc..295e78c11 100644 --- a/storybook/stories/input/searchable-dropdown.stories.ts +++ b/storybook/stories/input/searchable-dropdown.stories.ts @@ -28,6 +28,7 @@ const render = (props: SearchableDropdownProps) => html` placeholder="${ifDefined(props.placeholder)}" leadingIcon="${ifDefined(props.leadingIcon)}" multiple="${ifDefined(props.multiple)}" + selectedId="${ifDefined(props.selectedId)}" select-text-on-focus="${ifDefined(props.selectTextOnFocus)}" > `; @@ -39,17 +40,17 @@ export const Default: Story = { export const Label: Story = { ...Default, - render: (props) => render({ ...props, label: "Label" }), + render: (props) => render({ ...props, label: 'Label' }), }; export const Placeholder: Story = { ...Default, - render: (props) => render({ ...props, placeholder: "Placeholder" }), + render: (props) => render({ ...props, placeholder: 'Placeholder' }), }; export const LeadingIcon: Story = { ...Default, - render: (props) => render({ ...props, leadingIcon: "list" }), + render: (props) => render({ ...props, leadingIcon: 'list' }), }; export const Multiple: Story = { diff --git a/storybook/stories/person/person-select.stories.ts b/storybook/stories/person/person-select.stories.ts index c7e356ac4..3cff5c0af 100644 --- a/storybook/stories/person/person-select.stories.ts +++ b/storybook/stories/person/person-select.stories.ts @@ -73,7 +73,8 @@ export const SetSelectedPersonAttributeWithAzureId: Story = { export const SetSelectedPersonAttributeWithPersonInfo: Story = { args: { // selectedPerson: JSON.stringify({ azureID: '49132c24-6ea4-41fe-8221-112f314573f0' }), - selectedPerson: '{"azureId":"49132c24-6ea4-41fe-8221-112f314573f0"}', + selectedPerson: + '{"azureId": "b4f6b901-902e-486a-979e-86d8eeee6365", "upn": "Noe.Rice@equinor.com", "name": "Naomi Steuber", "accountType": "Consultant", "accountClassification": "External", "jobTitle": "Product Assurance Representative", "department": "Automotive", "mail": "Noe.Rice@equinor.com", "mobilePhone": "(763) 255-9520", "officeLocation": "Catherinefield", "positions": [], "manager": { "azureUniqueId": "8da7cab8-5c43-4c99-9689-8c22501f6071","name": "Allan Kulas","department": "Health"}', }, render, };