Skip to content

Commit 20844f1

Browse files
committed
Feat: Add dropdown search
1 parent 5fd0494 commit 20844f1

File tree

7 files changed

+63
-4
lines changed

7 files changed

+63
-4
lines changed

packages/components/src/components/hds/advanced-table/filter-bar/dropdown.hbs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
{{! @glint-nocheck }}
22
<Hds::Dropdown
33
@listPosition="bottom-left"
4-
@height="180px"
4+
@height="240px"
5+
@searchEnabled={{@searchEnabled}}
6+
@searchPlaceholder="Search {{@key}}"
57
class={{this.classNames}}
68
{{this._updateInternalFilters}}
79
as |D|

packages/components/src/components/hds/advanced-table/filter-bar/dropdown.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export interface HdsAdvancedTableFilterBarDropdownSignature {
2929
isMultiSelect?: boolean;
3030
isLiveFilter?: boolean;
3131
activeFilterableColumns?: string[];
32+
searchEnabled?: boolean;
3233
onChange: (key: string, keyFilter?: HdsAdvancedTableFilter[]) => void;
3334
};
3435
Blocks: {

packages/components/src/components/hds/dropdown/index.hbs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
SPDX-License-Identifier: MPL-2.0
44
}}
55
<Hds::PopoverPrimitive @isOpen={{@isOpen}} @onClose={{@onClose}} @enableClickEvents={{true}} as |PP|>
6-
<div class={{this.classNames}} ...attributes {{PP.setupPrimitiveContainer}}>
6+
<div class={{this.classNames}} ...attributes {{PP.setupPrimitiveContainer}} {{this._setUpDropdown}}>
77
{{yield
88
(hash
99
ToggleButton=(component
@@ -21,6 +21,15 @@
2121
>
2222
{{#if (or PP.isOpen @preserveContentInDom)}}
2323
{{yield (hash Header=(component "hds/dropdown/header") close=PP.hidePopover)}}
24+
{{#if @searchEnabled}}
25+
<div class="hds-dropdown__search">
26+
<Hds::Form::TextInput::Base
27+
@type="search"
28+
placeholder={{if @searchPlaceholder @searchPlaceholder "Search"}}
29+
{{on "input" this.onSearch}}
30+
/>
31+
</div>
32+
{{/if}}
2433
<ul class="hds-dropdown__list" {{did-insert this.didInsertList}}>
2534
{{yield
2635
(hash

packages/components/src/components/hds/dropdown/index.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import Component from '@glimmer/component';
77
import { action } from '@ember/object';
88
import { assert } from '@ember/debug';
9+
import { modifier } from 'ember-modifier';
910

1011
import {
1112
// map Dropdown's `listPosition` values to PopoverPrimitive's `placement` values
@@ -48,6 +49,8 @@ export interface HdsDropdownSignature {
4849
enableCollisionDetection?: HdsAnchoredPositionOptions['enableCollisionDetection'];
4950
preserveContentInDom?: boolean;
5051
matchToggleWidth?: boolean;
52+
searchEnabled?: boolean;
53+
searchPlaceholder?: string;
5154
};
5255
Blocks: {
5356
default: [
@@ -73,6 +76,15 @@ export interface HdsDropdownSignature {
7376
}
7477

7578
export default class HdsDropdown extends Component<HdsDropdownSignature> {
79+
80+
private _element!: HTMLDivElement;
81+
82+
private _setUpDropdown = modifier((element: HTMLDivElement) => {
83+
this._element = element;
84+
85+
return () => {};
86+
});
87+
7688
/**
7789
* @param listPosition
7890
* @type {string}
@@ -169,4 +181,20 @@ export default class HdsDropdown extends Component<HdsDropdownSignature> {
169181
}
170182
}
171183
}
184+
185+
onSearch = (event: Event) => {
186+
const listItems = this._element.querySelectorAll('.hds-dropdown-list-item') as NodeListOf<HTMLLIElement>;
187+
const input = event.target as HTMLInputElement;
188+
listItems.forEach((item) => {
189+
if (item.textContent) {
190+
const text = item.textContent.toLowerCase();
191+
const searchText = input.value.toLowerCase();
192+
if (text.includes(searchText)) {
193+
item.style.display = '';
194+
} else {
195+
item.style.display = 'none';
196+
}
197+
}
198+
});
199+
}
172200
}

packages/components/src/styles/components/advanced-table.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -785,7 +785,7 @@ $hds-advanced-table-drag-preview-background-color: rgba(204, 227, 254, 30%);
785785
padding-top: 8px;
786786
border-top: 1px solid var(--token-color-border-primary);
787787

788-
.hds-form-text-input {
788+
.hds-dropdown__list .hds-form-text-input {
789789
width: auto;
790790
}
791791
}

packages/components/src/styles/components/dropdown.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,3 +602,11 @@ $hds-dropdown-toggle-border-radius: $hds-button-border-radius;
602602
vertical-align: bottom;
603603
}
604604
}
605+
606+
// SEARCH
607+
608+
.hds-dropdown__search {
609+
flex: none;
610+
padding: 8px;
611+
border-bottom: 1px solid var(--token-color-border-primary);
612+
}

showcase/app/components/mock/app/main/generic-advanced-table.gts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,9 @@ const SAMPLE_MODEL = [
387387
];
388388

389389
const SAMPLE_MODEL_VALUES = {
390+
name: Array.from(new Set(SAMPLE_MODEL.map((item) => item['name']))).map(
391+
(value) => ({ value, label: value }),
392+
),
390393
'project-name': Array.from(
391394
new Set(SAMPLE_MODEL.map((item) => item['project-name'])),
392395
).map((value) => ({ value, label: value })),
@@ -410,6 +413,7 @@ const SAMPLE_COLUMNS = [
410413
label: 'Name',
411414
key: 'name',
412415
width: 'max-content',
416+
filterType: 'checkbox',
413417
},
414418
{
415419
label: 'Project name',
@@ -639,11 +643,18 @@ export default class MockAppMainGenericAdvancedTable extends Component<MockAppMa
639643
<D.Checkbox>memories</D.Checkbox>
640644
</F.ActionsDropdown>
641645
<F.FiltersDropdown as |D|>
646+
<D.Checkbox @value="name">Name</D.Checkbox>
642647
<D.Checkbox @value="project-name">Project name</D.Checkbox>
643648
<D.Checkbox @value="run-status">Run status</D.Checkbox>
644649
<D.Checkbox @value="terraform-version">Terraform version</D.Checkbox>
645650
</F.FiltersDropdown>
646-
<F.Dropdown @key="project-name" as |D|>
651+
<F.Dropdown @key="name" @searchEnabled={{true}} as |D|>
652+
<D.ToggleButton @text="Name" />
653+
{{#each (get SAMPLE_MODEL_VALUES "name") as |option|}}
654+
<D.Checkbox @value={{option.value}}>{{option.label}}</D.Checkbox>
655+
{{/each}}
656+
</F.Dropdown>
657+
<F.Dropdown @key="project-name" @searchEnabled={{true}} as |D|>
647658
<D.ToggleButton @text="Project name" />
648659
{{#each (get SAMPLE_MODEL_VALUES "project-name") as |option|}}
649660
<D.Checkbox @value={{option.value}}>{{option.label}}</D.Checkbox>

0 commit comments

Comments
 (0)