Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: picker attributes always true #6773

Merged
merged 12 commits into from
Jun 14, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "no options missing",
"packageName": "@microsoft/fast-foundation",
"email": "stephcomeau@msn.com",
"dependentChangeType": "prerelease"
}
14 changes: 12 additions & 2 deletions packages/web-components/fast-foundation/docs/api-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -1541,14 +1541,24 @@ export class FASTPicker extends FormAssociatedPicker {
disabled: boolean;
// (undocumented)
disabledChanged(previous: boolean, next: boolean): void;
disableQueryFilter: boolean;
// (undocumented)
protected disableQueryFilterChanged(): void;
disableSelectionFilter: boolean;
// (undocumented)
protected disableSelectionFilterChanged(): void;
// (undocumented)
disconnectedCallback(): void;
// @internal
filteredOptionsList: string[];
// (undocumented)
protected filteredOptionsListChanged(): void;
// @deprecated
filterQuery: boolean;
// (undocumented)
protected filterQueryChanged(): void;
// @deprecated
filterSelected: boolean;
// (undocumented)
protected filterSelectedChanged(): void;
// @internal
flyoutOpen: boolean;
// (undocumented)
Expand Down
15 changes: 10 additions & 5 deletions packages/web-components/fast-foundation/src/picker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,10 @@ export class FASTTextField extends TextField {}
| ---------------------------- | ------- | --------------------------- | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| `selection` | public | `string` | `""` | Currently selected items. Comma delineated string ie. "apples,oranges". | |
| `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 | |
| `filterSelected` | public | `boolean` | `false` | Indicates whether the component should remove an option from the list when it is in the selection. | |
| `disableSelectionFilter` | public | `boolean` | `false` | Indicates whether the component should remove an option from the list when it is in the selection. | |
| `filterQuery` | public | `boolean` | `true` | Indicates whether the component should remove options based on the current query. | |
| `disableQueryFilter` | public | `boolean` | `false` | Indicates whether the component should remove options based on the current query. | |
| `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. | |
Expand Down Expand Up @@ -237,6 +239,10 @@ export class FASTTextField extends TextField {}
| ---------------------------------- | --------- | ------------------------------------------------------------- | ---------------------------------- | --------- | -------------- |
| `selectionChanged` | protected | | | `void` | |
| `optionsChanged` | protected | | | `void` | |
| `filterSelectedChanged` | protected | | | `void` | |
| `disableSelectionFilterChanged` | protected | | | `void` | |
| `filterQueryChanged` | protected | | | `void` | |
| `disableQueryFilterChanged` | protected | | | `void` | |
| `disabledChanged` | public | | `previous: boolean, next: boolean` | `void` | |
| `menuPlacementChanged` | protected | | | `void` | |
| `showLoadingChanged` | protected | | | `void` | |
Expand All @@ -245,7 +251,6 @@ export class FASTTextField extends TextField {}
| `menuOptionTemplateChanged` | protected | | | `void` | |
| `defaultMenuOptionTemplateChanged` | protected | | | `void` | |
| `queryChanged` | protected | | | `void` | |
| `filteredOptionsListChanged` | protected | | | `void` | |
| `flyoutOpenChanged` | protected | | | `void` | |
| `focus` | public | Move focus to the input element | | | |
| `handleKeyDown` | public | Handle key down events. | `e: KeyboardEvent` | `boolean` | |
Expand All @@ -262,8 +267,8 @@ export class FASTTextField extends TextField {}
| ---------------------------- | ------------------------ | -------------- |
| `selection` | selection | |
| `options` | options | |
| `filter-selected` | filterSelected | |
| `filter-query` | filterQuery | |
| `disable-selection-filter` | disableSelectionFilter | |
| `disable-query-filter` | disableQueryFilter | |
| `max-selected` | maxSelected | |
| `no-suggestions-text` | noSuggestionsText | |
| `suggestions-available-text` | suggestionsAvailableText | |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ Picker is the top level container which hosts both a `picker-list` component to
- `label`: The text applied to the `aria-label` attribute of the internal input element.
- `labelledby`: The text applied to the `aria-labelledby` attribute of the internal input element.
- `placeholder`: The text used as the `placeholder` value for the internal input element.
- `filter-selected`: Whether to remove selected elements from the option list (default=true)
- `filter-query`: Whether to remove elements that don't match the query string (default=true)
- `filter-selected`: Whether to remove selected elements from the option list (default=false)
- `disable-query-filter`: Whether to remove elements that don't match the query string (default=false)
- `menu-placement`: Controls the placement of the menu relative to the input element.
(default="bottom-fill")

Expand Down
99 changes: 60 additions & 39 deletions packages/web-components/fast-foundation/src/picker/picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,22 +100,62 @@ export class FASTPicker extends FormAssociatedPicker {
}

/**
* Whether the component should remove an option from the list when it is in the selection
* Indicates whether the component should remove an option from the list when it is in the selection.
*
* @remarks
* HTML Attribute: filter-selected
* @deprecated - use `Picker.disableSelectionFilter`.
*/
@attr({ attribute: "filter-selected", mode: "boolean" })
public filterSelected: boolean = true;
@observable
public filterSelected: boolean = false;
protected filterSelectedChanged(): void {
// keep the main prop in sync
if (this.disableSelectionFilter === this.filterSelected) {
this.disableSelectionFilter = !this.filterSelected;
}
}
janechu marked this conversation as resolved.
Show resolved Hide resolved

/**
* Whether the component should remove options based on the current query
* Indicates whether the component should remove an option from the list when it is in the selection.
*
* @remarks
* HTML Attribute: filter-query
* HTML Attribute: disable-selection-filter
*/
@attr({ attribute: "filter-query", mode: "boolean" })
@attr({ attribute: "disable-selection-filter", mode: "boolean" })
public disableSelectionFilter: boolean = false;
protected disableSelectionFilterChanged(): void {
// keep depracated prop in sync
if (this.disableSelectionFilter === this.filterQuery) {
this.filterSelected = !this.disableSelectionFilter;
}
}
janechu marked this conversation as resolved.
Show resolved Hide resolved

/**
* Indicates whether the component should remove options based on the current query.
*
* @deprecated - use `Picker.disableQueryFilter`.
*/
@observable
public filterQuery: boolean = true;
protected filterQueryChanged(): void {
// keep the main prop in sync
if (this.disableQueryFilter === this.filterQuery) {
this.disableQueryFilter = !this.filterQuery;
}
}
janechu marked this conversation as resolved.
Show resolved Hide resolved

/**
* Indicates whether the component should remove options based on the current query.
*
* @remarks
* HTML Attribute: disable-query-filter
*/
@attr({ attribute: "disable-query-filter", mode: "boolean" })
public disableQueryFilter: boolean = false;
protected disableQueryFilterChanged(): void {
// keep depracated prop in sync
if (this.disableQueryFilter === this.filterQuery) {
this.filterQuery = !this.disableQueryFilter;
}
}
janechu marked this conversation as resolved.
Show resolved Hide resolved

/**
* The maximum number of items that can be selected.
Expand Down Expand Up @@ -336,15 +376,6 @@ export class FASTPicker extends FormAssociatedPicker {
*/
@observable
public filteredOptionsList: string[] = [];
protected filteredOptionsListChanged(): void {
if (this.$fastController.isConnected) {
Updates.enqueue(() => {
this.showNoOptions =
this.menuElement.querySelectorAll('[role="option"]').length === 0;
this.setFocusedOption(this.showNoOptions ? -1 : 0);
});
}
}

/**
* Indicates if the flyout menu is open or not
Expand Down Expand Up @@ -408,14 +439,7 @@ export class FASTPicker extends FormAssociatedPicker {
* @internal
*/
@observable
public showNoOptions: boolean = false;
private showNoOptionsChanged(): void {
if (this.$fastController.isConnected) {
Updates.enqueue(() => {
this.setFocusedOption(0);
});
}
}
public showNoOptions: boolean = true;

/**
* The anchored region config to apply.
Expand Down Expand Up @@ -585,13 +609,6 @@ export class FASTPicker extends FormAssociatedPicker {

if (open && getRootActiveElement(this) === this.inputElement) {
this.flyoutOpen = open;
Updates.enqueue(() => {
if (this.menuElement !== undefined) {
this.setFocusedOption(0);
} else {
this.disableMenu();
}
});
return;
}

Expand Down Expand Up @@ -621,12 +638,12 @@ export class FASTPicker extends FormAssociatedPicker {
/**
* Handle the menu options updated event from the child menu
*/
private handleMenuOptionsUpdated(e: Event): void {
private handleMenuOptionsUpdated = (e: Event): void => {
e.preventDefault();
if (this.flyoutOpen) {
Updates.enqueue(() => {
this.setFocusedOption(0);
}
}
});
};

/**
* Handle key down events.
Expand Down Expand Up @@ -809,7 +826,6 @@ export class FASTPicker extends FormAssociatedPicker {
*/
public handleRegionLoaded(e: Event): void {
Updates.enqueue(() => {
this.setFocusedOption(0);
this.$emit("menuloaded", { bubbles: false });
});
}
Expand Down Expand Up @@ -966,6 +982,7 @@ export class FASTPicker extends FormAssociatedPicker {
* Sets the currently focused menu option by index
*/
private setFocusedOption(optionIndex: number): void {
this.updateNoOptions();
if (
!this.flyoutOpen ||
optionIndex === -1 ||
Expand Down Expand Up @@ -1023,12 +1040,12 @@ export class FASTPicker extends FormAssociatedPicker {
*/
private updateFilteredOptions(): void {
this.filteredOptionsList = this.optionsList.slice(0);
if (this.filterSelected) {
if (!this.disableSelectionFilter) {
this.filteredOptionsList = this.filteredOptionsList.filter(
el => this.selectedItems.indexOf(el) === -1
);
}
if (this.filterQuery && this.query !== "" && this.query !== undefined) {
if (!this.disableQueryFilter && this.query !== "" && this.query !== undefined) {
// compare case-insensitive
const filterQuery = this.query.toLowerCase();
this.filteredOptionsList = this.filteredOptionsList.filter(
Expand Down Expand Up @@ -1067,4 +1084,8 @@ export class FASTPicker extends FormAssociatedPicker {
"bottom-fill": FlyoutPosBottomFill,
"tallest-fill": FlyoutPosTallestFill,
};

private updateNoOptions(): void {
this.showNoOptions = this.menuElement.optionElements.length === 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const pickerStyles = css`
min-height: calc(
(var(--base-height-multiplier) + var(--density)) * var(--design-unit) * 1px
);
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ const storyTemplate = html<StoryArgs<FASTPicker>>`
<fast-picker
selection="${x => x.selection}"
options="${x => x.options}"
?filter-selected="${x => x.filterSelected}"
?filter-query="${x => x.filterQuery}"
disable-selection-filter="${x => x.disableSelectionFilter}"
disable-query-filter="${x => x.disableQueryFilter}"
:showLoading="${x => x.showLoading}"
?disabled="${x => x.disabled}"
max-selected="${x => x.maxSelected}"
no-suggestions-text="${x => x.noSuggestionsText}"
Expand All @@ -24,16 +25,13 @@ const storyTemplate = html<StoryArgs<FASTPicker>>`

export default {
title: "Picker",
args: {
// TODO: These are always true https://github.com/microsoft/fast/issues/6311
filterQuery: true,
filterSelected: true,
disabled: false,
},
args: {},
argTypes: {
filterQuery: { control: "boolean" },
filterSelected: { control: "boolean" },
queryFilterDisabled: { control: "boolean" },
disabled: { control: "boolean" },
disableQueryFilter: { control: "boolean" },
disableSelectionFilter: { control: "boolean" },
showLoading: { control: "boolean" },
label: { control: "text" },
labelledBy: { control: "text" },
loadingText: { control: "text" },
Expand All @@ -49,10 +47,21 @@ export const Picker: Story<FASTPicker> = renderComponent(storyTemplate).bind({})
Picker.args = {
label: "Fruit picker",
loadingText: "Loading",
noSuggestionsText: "No such fruit",
noSuggestionsText: "No suggestions available",
options: "apple, orange, banana, mango, strawberry, raspberry, blueberry",
placeholder: "Choose fruit",
selection: "apple",
suggestionsAvailableText: "Found some fruit",
disabled: false,
};

export const PickerEmpty: Story<FASTPicker> = renderComponent(storyTemplate).bind({});
PickerEmpty.args = {
label: "Fruit picker",
loadingText: "Loading",
noSuggestionsText: "No suggestions available",
options: "",
placeholder: "Choose fruit",
selection: "",
suggestionsAvailableText: "Found some fruit",
};
Loading