From 6f113c2346849590eea768edfcfca2e77b911309 Mon Sep 17 00:00:00 2001 From: Stephane Comeau Date: Thu, 13 Jul 2023 08:52:26 -0700 Subject: [PATCH 1/5] picker zero items --- .../fast-foundation/src/picker/picker.spec.md | 2 +- .../fast-foundation/src/picker/picker.ts | 49 ++++++++++--------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/packages/web-components/fast-foundation/src/picker/picker.spec.md b/packages/web-components/fast-foundation/src/picker/picker.spec.md index 1b86faa5301..f3d816283f2 100644 --- a/packages/web-components/fast-foundation/src/picker/picker.spec.md +++ b/packages/web-components/fast-foundation/src/picker/picker.spec.md @@ -42,7 +42,7 @@ Picker is the top level container which hosts both a `picker-list` component to *Attributes:* - `selection`: List of currently selected items. Comma delineated string ie. "apples,oranges". - `options`: Currently available options. Comma delineated string ie. "apples,oranges". -- `max-selected`: The maximum number of items that can be selected. Unset by default (ie. no maximum). +- `max-selected`: The maximum number of items that can be selected. Unset by default (ie. no maximum). If the value is "0" selecting an item updates the query instead. - `no-suggestions-text`: The text to present when no suggestions are available. - `suggestions-available-text`: The text to present when suggestions are available. - `loading-text`: The text to present when suggestions are loading. diff --git a/packages/web-components/fast-foundation/src/picker/picker.ts b/packages/web-components/fast-foundation/src/picker/picker.ts index 2918cea34cb..4311b598dc1 100644 --- a/packages/web-components/fast-foundation/src/picker/picker.ts +++ b/packages/web-components/fast-foundation/src/picker/picker.ts @@ -2,6 +2,7 @@ import { attr, html, HTMLView, + nullableNumberConverter, observable, oneWay, ref, @@ -117,7 +118,7 @@ export class FASTPicker extends FormAssociatedPicker { * @remarks * HTML Attribute: max-selected */ - @attr({ attribute: "max-selected" }) + @attr({ attribute: "max-selected", converter: nullableNumberConverter }) public maxSelected: number | undefined; /** @@ -710,8 +711,9 @@ export class FASTPicker extends FormAssociatedPicker { } const selectedItems: Element[] = Array.from(this.listElement.children); - const currentFocusedItemIndex: number = - selectedItems.indexOf(activeElement); + const currentFocusedItemIndex: number = selectedItems.indexOf( + activeElement + ); if (currentFocusedItemIndex > -1) { // delete currently focused item @@ -719,11 +721,9 @@ export class FASTPicker extends FormAssociatedPicker { .splice(currentFocusedItemIndex, 1) .toString(); Updates.enqueue(() => { - ( - selectedItems[ - Math.min(selectedItems.length, currentFocusedItemIndex) - ] as HTMLElement - ).focus(); + (selectedItems[ + Math.min(selectedItems.length, currentFocusedItemIndex) + ] as HTMLElement).focus(); }); return false; } @@ -807,15 +807,16 @@ export class FASTPicker extends FormAssociatedPicker { } if ( this.maxSelected !== undefined && + this.maxSelected !== 0 && this.selectedItems.length >= this.maxSelected ) { if (this.getRootActiveElement() === this.inputElement) { const selectedItemInstances: Element[] = Array.from( this.listElement.querySelectorAll("[role='listitem']") ); - ( - selectedItemInstances[selectedItemInstances.length - 1] as HTMLElement - ).focus(); + (selectedItemInstances[ + selectedItemInstances.length - 1 + ] as HTMLElement).focus(); } this.inputElement.hidden = true; } else { @@ -867,21 +868,22 @@ export class FASTPicker extends FormAssociatedPicker { return false; } - if (e.target instanceof FASTPickerMenuOption) { - if (e.target.value !== undefined) { + if (e.target instanceof FASTPickerMenuOption && e.target.value !== undefined) { + if (this.maxSelected === 0) { + // if we don't allow selection just update the query + this.query = e.target.value; + } else { + this.query = ""; this.selection = `${this.selection}${this.selection === "" ? "" : ","}${ e.target.value }`; } - this.inputElement.value = ""; - this.query = ""; - this.inputElement.focus(); + this.toggleFlyout(false); + this.inputElement.focus(); return false; } - // const value: string = (e.target as PickerMenuOption).value; - return true; } @@ -900,8 +902,9 @@ export class FASTPicker extends FormAssociatedPicker { const activeElement = this.getRootActiveElement(); if (activeElement !== null) { - let currentFocusedItemIndex: number = - selectedItemsAsElements.indexOf(activeElement); + let currentFocusedItemIndex: number = selectedItemsAsElements.indexOf( + activeElement + ); if (currentFocusedItemIndex === -1) { // use the input element currentFocusedItemIndex = selectedItemsAsElements.length; @@ -916,9 +919,9 @@ export class FASTPicker extends FormAssociatedPicker { this.maxSelected !== undefined && this.selectedItems.length >= this.maxSelected ) { - ( - selectedItemsAsElements[newFocusedItemIndex - 1] as HTMLElement - ).focus(); + (selectedItemsAsElements[ + newFocusedItemIndex - 1 + ] as HTMLElement).focus(); } else { this.inputElement.focus(); } From 0e33b90339d76469dc1d6d7b5c41f5ce56b1aa23 Mon Sep 17 00:00:00 2001 From: Stephane Comeau Date: Thu, 13 Jul 2023 09:10:13 -0700 Subject: [PATCH 2/5] Change files --- ...st-foundation-2b6fd22d-b799-4e12-ba59-696ca95be77b.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@microsoft-fast-foundation-2b6fd22d-b799-4e12-ba59-696ca95be77b.json diff --git a/change/@microsoft-fast-foundation-2b6fd22d-b799-4e12-ba59-696ca95be77b.json b/change/@microsoft-fast-foundation-2b6fd22d-b799-4e12-ba59-696ca95be77b.json new file mode 100644 index 00000000000..d40596f9813 --- /dev/null +++ b/change/@microsoft-fast-foundation-2b6fd22d-b799-4e12-ba59-696ca95be77b.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "picker zero items", + "packageName": "@microsoft/fast-foundation", + "email": "stephcomeau@msn.com", + "dependentChangeType": "prerelease" +} From 58135c56f10bf6d3e839bcc1a0f7e98ead441993 Mon Sep 17 00:00:00 2001 From: Stephane Comeau Date: Thu, 13 Jul 2023 09:45:57 -0700 Subject: [PATCH 3/5] prettier --- .../fast-foundation/src/picker/picker.ts | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/web-components/fast-foundation/src/picker/picker.ts b/packages/web-components/fast-foundation/src/picker/picker.ts index 4311b598dc1..977d99f1861 100644 --- a/packages/web-components/fast-foundation/src/picker/picker.ts +++ b/packages/web-components/fast-foundation/src/picker/picker.ts @@ -711,9 +711,8 @@ export class FASTPicker extends FormAssociatedPicker { } const selectedItems: Element[] = Array.from(this.listElement.children); - const currentFocusedItemIndex: number = selectedItems.indexOf( - activeElement - ); + const currentFocusedItemIndex: number = + selectedItems.indexOf(activeElement); if (currentFocusedItemIndex > -1) { // delete currently focused item @@ -721,9 +720,11 @@ export class FASTPicker extends FormAssociatedPicker { .splice(currentFocusedItemIndex, 1) .toString(); Updates.enqueue(() => { - (selectedItems[ - Math.min(selectedItems.length, currentFocusedItemIndex) - ] as HTMLElement).focus(); + ( + selectedItems[ + Math.min(selectedItems.length, currentFocusedItemIndex) + ] as HTMLElement + ).focus(); }); return false; } @@ -814,9 +815,9 @@ export class FASTPicker extends FormAssociatedPicker { const selectedItemInstances: Element[] = Array.from( this.listElement.querySelectorAll("[role='listitem']") ); - (selectedItemInstances[ - selectedItemInstances.length - 1 - ] as HTMLElement).focus(); + ( + selectedItemInstances[selectedItemInstances.length - 1] as HTMLElement + ).focus(); } this.inputElement.hidden = true; } else { @@ -902,9 +903,8 @@ export class FASTPicker extends FormAssociatedPicker { const activeElement = this.getRootActiveElement(); if (activeElement !== null) { - let currentFocusedItemIndex: number = selectedItemsAsElements.indexOf( - activeElement - ); + let currentFocusedItemIndex: number = + selectedItemsAsElements.indexOf(activeElement); if (currentFocusedItemIndex === -1) { // use the input element currentFocusedItemIndex = selectedItemsAsElements.length; @@ -919,9 +919,9 @@ export class FASTPicker extends FormAssociatedPicker { this.maxSelected !== undefined && this.selectedItems.length >= this.maxSelected ) { - (selectedItemsAsElements[ - newFocusedItemIndex - 1 - ] as HTMLElement).focus(); + ( + selectedItemsAsElements[newFocusedItemIndex - 1] as HTMLElement + ).focus(); } else { this.inputElement.focus(); } From 108ba8d01bb698a59362c4d76eb6634031aef70d Mon Sep 17 00:00:00 2001 From: Stephane Comeau Date: Thu, 13 Jul 2023 10:53:13 -0700 Subject: [PATCH 4/5] default to null --- .../web-components/fast-foundation/src/picker/picker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/web-components/fast-foundation/src/picker/picker.ts b/packages/web-components/fast-foundation/src/picker/picker.ts index 977d99f1861..0ca85da99b2 100644 --- a/packages/web-components/fast-foundation/src/picker/picker.ts +++ b/packages/web-components/fast-foundation/src/picker/picker.ts @@ -119,7 +119,7 @@ export class FASTPicker extends FormAssociatedPicker { * HTML Attribute: max-selected */ @attr({ attribute: "max-selected", converter: nullableNumberConverter }) - public maxSelected: number | undefined; + public maxSelected: number | null = null; /** * The text to present to assistive technolgies when no suggestions are available. @@ -807,7 +807,7 @@ export class FASTPicker extends FormAssociatedPicker { return; } if ( - this.maxSelected !== undefined && + this.maxSelected !== null && this.maxSelected !== 0 && this.selectedItems.length >= this.maxSelected ) { @@ -916,7 +916,7 @@ export class FASTPicker extends FormAssociatedPicker { ); if (newFocusedItemIndex === selectedItemsAsElements.length) { if ( - this.maxSelected !== undefined && + this.maxSelected !== null && this.selectedItems.length >= this.maxSelected ) { ( From 774161c5285efc9744bdda29c98bd29927e75efd Mon Sep 17 00:00:00 2001 From: Stephane Comeau Date: Tue, 8 Aug 2023 08:52:30 -0700 Subject: [PATCH 5/5] update files --- packages/web-components/fast-foundation/docs/api-report.md | 2 +- packages/web-components/fast-foundation/src/picker/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web-components/fast-foundation/docs/api-report.md b/packages/web-components/fast-foundation/docs/api-report.md index dd87f8f6af6..2f911d7778b 100644 --- a/packages/web-components/fast-foundation/docs/api-report.md +++ b/packages/web-components/fast-foundation/docs/api-report.md @@ -1547,7 +1547,7 @@ export class FASTPicker extends FormAssociatedPicker { // (undocumented) protected listItemTemplateChanged(): void; loadingText: string; - maxSelected: number | undefined; + maxSelected: number | null; // @internal menuConfig: AnchoredRegionConfig; // @internal diff --git a/packages/web-components/fast-foundation/src/picker/README.md b/packages/web-components/fast-foundation/src/picker/README.md index 0be5da500c9..2be6dda1a1c 100644 --- a/packages/web-components/fast-foundation/src/picker/README.md +++ b/packages/web-components/fast-foundation/src/picker/README.md @@ -195,7 +195,7 @@ export class FASTTextField extends TextField {} | `options` | public | `string` | | Currently available options. Comma delineated string ie. "apples,oranges". | | | `filterSelected` | public | `boolean` | `true` | Whether the component should remove an option from the list when it is in the selection | | | `filterQuery` | public | `boolean` | `true` | Whether the component should remove options based on the current query | | -| `maxSelected` | public | `number or undefined` | | The maximum number of items that can be selected. | | +| `maxSelected` | public | `number or null` | `null` | The maximum number of items that can be selected. | | | `noSuggestionsText` | public | `string` | `"No suggestions available"` | The text to present to assistive technolgies when no suggestions are available. | | | `suggestionsAvailableText` | public | `string` | `"Suggestions available"` | The text to present to assistive technolgies when suggestions are available. | | | `loadingText` | public | `string` | `"Loading suggestions"` | The text to present to assistive technologies when suggestions are loading. | |