Skip to content

Commit

Permalink
Add secondaryFilterAttribute to DropdownList (#349)
Browse files Browse the repository at this point in the history
* Add secondaryFilter support to DropdownList

* Improve `inputIsShown` arg
  • Loading branch information
jeffdaley authored Sep 26, 2023
1 parent 0a243ef commit e180132
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 51 deletions.
1 change: 1 addition & 0 deletions web/app/components/inputs/badge-dropdown-list.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
@selected={{@selected}}
@placement={{@placement}}
@renderOut={{@renderOut}}
@secondaryFilterAttribute={{@secondaryFilterAttribute}}
...attributes
>
<:anchor as |dd|>
Expand Down
2 changes: 1 addition & 1 deletion web/app/components/inputs/badge-dropdown-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ interface InputsBadgeDropdownListComponentSignature {
isSaving?: boolean;
placement?: Placement;
renderOut?: boolean;

onItemClick: ((e: Event) => void) | ((e: string) => void);
icon: string;
secondaryFilterAttribute?: string;
};
Blocks: {
default: [];
Expand Down
2 changes: 2 additions & 0 deletions web/app/components/inputs/product-select/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
@placement={{@placement}}
@isSaving={{@isSaving}}
@renderOut={{@renderOut}}
@secondaryFilterAttribute="abbreviation"
@icon={{this.icon}}
class="product-select-dropdown-list w-80"
...attributes
Expand All @@ -32,6 +33,7 @@
@placement={{@placement}}
@isSaving={{@isSaving}}
@renderOut={{@renderOut}}
@secondaryFilterAttribute="abbreviation"
class="product-select-dropdown-list w-[300px]"
...attributes
>
Expand Down
2 changes: 1 addition & 1 deletion web/app/components/inputs/product-select/item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ interface InputsProductSelectItemComponentSignature {
Args: {
product: string;
isSelected?: boolean;
abbreviation?: boolean;
abbreviation?: string;
};
}

Expand Down
34 changes: 24 additions & 10 deletions web/app/components/x/dropdown-list/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ interface XDropdownListComponentSignature {
label?: string;
matchAnchorWidth?: MatchAnchorWidthOptions;

/**
* An additional attribute by which to search.
* Used to include secondary information when filtering.
* For example, we specify "abbreviation" for the `ProductSelect`
* component so that users can search by product's abbreviation
* in addition to its name.
*/
secondaryFilterAttribute?: string;

/**
* Whether an asynchronous list is loading.
* Used to determine if a loading UI is shown.
Expand Down Expand Up @@ -144,8 +153,8 @@ export default class XDropdownListComponent extends Component<XDropdownListCompo
* aria-roles for various elements.
*/
get inputIsShown() {
if (this.args.inputIsShown === false) {
return false;
if (this.args.inputIsShown !== undefined) {
return this.args.inputIsShown;
}

if (!this.args.items) {
Expand Down Expand Up @@ -232,10 +241,10 @@ export default class XDropdownListComponent extends Component<XDropdownListCompo
@action protected didInsertContent() {
assert(
"didInsertContent expects a _scrollContainer",
this._scrollContainer
this._scrollContainer,
);
this.assignMenuItemIDs(
this._scrollContainer.querySelectorAll(`[role=${this.listItemRole}]`)
this._scrollContainer.querySelectorAll(`[role=${this.listItemRole}]`),
);
}

Expand Down Expand Up @@ -277,7 +286,7 @@ export default class XDropdownListComponent extends Component<XDropdownListCompo
@action protected onTriggerKeydown(
contentIsShown: boolean,
showContent: () => void,
event: KeyboardEvent
event: KeyboardEvent,
) {
if (contentIsShown) {
return;
Expand Down Expand Up @@ -311,7 +320,7 @@ export default class XDropdownListComponent extends Component<XDropdownListCompo
*/
@action protected setFocusedItemIndex(
focusDirectionOrNumber: FocusDirection | number,
maybeScrollIntoView = true
maybeScrollIntoView = true,
) {
let { _menuItems: menuItems, focusedItemIndex } = this;

Expand Down Expand Up @@ -401,6 +410,11 @@ export default class XDropdownListComponent extends Component<XDropdownListCompo
for (const [key, value] of Object.entries(items)) {
if (key.toLowerCase().includes(this.query.toLowerCase())) {
shownItems[key] = value;
} else if (this.args.secondaryFilterAttribute) {
const maybeValue = (value as any)[this.args.secondaryFilterAttribute];
if (maybeValue.toLowerCase().includes(this.query.toLowerCase())) {
shownItems[key] = value;
}
}
}

Expand All @@ -427,18 +441,18 @@ export default class XDropdownListComponent extends Component<XDropdownListCompo
schedule("afterRender", () => {
assert(
"scheduleAssignMenuItemIDs expects a _scrollContainer",
this._scrollContainer
this._scrollContainer,
);
this.assignMenuItemIDs(
this._scrollContainer.querySelectorAll(
`[role=${this.listItemRole}]`
)
`[role=${this.listItemRole}]`,
),
);
});
} else {
if (i === 3) {
throw new Error(
"scheduleAssignMenuItemIDs expects a _scrollContainer"
"scheduleAssignMenuItemIDs expects a _scrollContainer",
);
} else {
await timeout(1);
Expand Down
Loading

0 comments on commit e180132

Please sign in to comment.