@nectary/components 2.8.6 → 2.8.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/select-menu/index.js +35 -10
- package/select-menu/types.d.ts +12 -0
package/package.json
CHANGED
package/select-menu/index.js
CHANGED
|
@@ -41,6 +41,7 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
41
41
|
this.#$search.addEventListener('-change', this.#onSearchChange, options);
|
|
42
42
|
this.#$searchClear.addEventListener('-click', this.#onSearchClearClick, options);
|
|
43
43
|
this.#$optionSlot.addEventListener('slotchange', this.#onOptionSlotChange, options);
|
|
44
|
+
this.addEventListener('-search-change', this.#onSearchChangeReactHandler, options);
|
|
44
45
|
this.addEventListener('-change', this.#onChangeReactHandler, options);
|
|
45
46
|
subscribeContext(this, 'keydown', this.#onContextKeyDown, this.#controller.signal);
|
|
46
47
|
subscribeContext(this, 'visibility', this.#onContextVisibility, this.#controller.signal);
|
|
@@ -52,7 +53,7 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
52
53
|
this.#controller = null;
|
|
53
54
|
}
|
|
54
55
|
static get observedAttributes() {
|
|
55
|
-
return ['value', 'rows', 'multiple'];
|
|
56
|
+
return ['value', 'rows', 'multiple', 'search-placeholder'];
|
|
56
57
|
}
|
|
57
58
|
attributeChangedCallback(name, oldVal, newVal) {
|
|
58
59
|
switch (name) {
|
|
@@ -75,6 +76,11 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
75
76
|
});
|
|
76
77
|
break;
|
|
77
78
|
}
|
|
79
|
+
case 'search-placeholder':
|
|
80
|
+
{
|
|
81
|
+
updateAttribute(this.#$search, 'placeholder', newVal);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
78
84
|
}
|
|
79
85
|
}
|
|
80
86
|
set value(value) {
|
|
@@ -95,6 +101,12 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
95
101
|
get multiple() {
|
|
96
102
|
return getBooleanAttribute(this, 'multiple');
|
|
97
103
|
}
|
|
104
|
+
set 'search-placeholder'(placeholder) {
|
|
105
|
+
updateAttribute(this.#$search, 'placeholder', placeholder);
|
|
106
|
+
}
|
|
107
|
+
get 'search-placeholder'() {
|
|
108
|
+
return getAttribute(this.#$search, 'placeholder', '');
|
|
109
|
+
}
|
|
98
110
|
get focusable() {
|
|
99
111
|
return true;
|
|
100
112
|
}
|
|
@@ -128,15 +140,22 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
128
140
|
};
|
|
129
141
|
#updateSearch = () => {
|
|
130
142
|
const searchValue = this.#$search.value.toLowerCase();
|
|
131
|
-
const
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
143
|
+
const searchChangedEvent = new CustomEvent('-search-change', {
|
|
144
|
+
detail: searchValue,
|
|
145
|
+
cancelable: true
|
|
146
|
+
});
|
|
147
|
+
this.dispatchEvent(searchChangedEvent);
|
|
148
|
+
if (!searchChangedEvent.defaultPrevented) {
|
|
149
|
+
const $options = this.#getOptionElements();
|
|
150
|
+
let someFound = false;
|
|
151
|
+
for (const $opt of $options) {
|
|
152
|
+
const isHidden = searchValue.length > 0 && !$opt.matchesSearch(searchValue);
|
|
153
|
+
someFound ||= !isHidden;
|
|
154
|
+
setClass($opt, 'hidden', isHidden);
|
|
155
|
+
}
|
|
156
|
+
setClass(this.#$notFound, 'active', !someFound);
|
|
157
|
+
this.#selectOption(null);
|
|
137
158
|
}
|
|
138
|
-
setClass(this.#$notFound, 'active', !someFound);
|
|
139
|
-
this.#selectOption(null);
|
|
140
159
|
};
|
|
141
160
|
#onContextKeyDown = e => {
|
|
142
161
|
this.#handleKeydown(e.detail);
|
|
@@ -179,7 +198,10 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
179
198
|
}
|
|
180
199
|
}
|
|
181
200
|
#onOptionSlotChange = () => {
|
|
182
|
-
const
|
|
201
|
+
const hasSearchableAttribute = this.hasAttribute('searchable');
|
|
202
|
+
const options = this.#$optionSlot.assignedElements();
|
|
203
|
+
const isEnoughOptions = options.length >= NUM_ITEMS_SEARCH;
|
|
204
|
+
const isSearchActive = isEnoughOptions || hasSearchableAttribute;
|
|
183
205
|
if (!isSearchActive) {
|
|
184
206
|
updateAttribute(this.#$search, 'value', null);
|
|
185
207
|
}
|
|
@@ -304,4 +326,7 @@ defineCustomElement('sinch-select-menu', class extends NectaryElement {
|
|
|
304
326
|
#onChangeReactHandler = e => {
|
|
305
327
|
getReactEventHandler(this, 'on-change')?.(e);
|
|
306
328
|
};
|
|
329
|
+
#onSearchChangeReactHandler = e => {
|
|
330
|
+
getReactEventHandler(this, 'on-search-change')?.(e);
|
|
331
|
+
};
|
|
307
332
|
});
|
package/select-menu/types.d.ts
CHANGED
|
@@ -6,8 +6,14 @@ export type TSinchSelectMenuElement = HTMLElement & {
|
|
|
6
6
|
rows: number | null;
|
|
7
7
|
/** Allows multiple selection */
|
|
8
8
|
multiple: boolean;
|
|
9
|
+
/** Enforce the search bar appearing, by default it appears above a certain number of options */
|
|
10
|
+
searchable: boolean;
|
|
11
|
+
/** Text for search bar's placeholder */
|
|
12
|
+
'search-placeholder': string;
|
|
9
13
|
/** Change value event */
|
|
10
14
|
addEventListener(type: '-change', listener: (e: CustomEvent<string>) => void): void;
|
|
15
|
+
/** Change value event */
|
|
16
|
+
addEventListener(type: '-search-change', listener: (e: CustomEvent<string>) => void): void;
|
|
11
17
|
/** Selected value, CSV when multiple */
|
|
12
18
|
setAttribute(name: 'value', value: string): void;
|
|
13
19
|
/** How many rows to show and scroll the rest */
|
|
@@ -22,8 +28,14 @@ export type TSinchSelectMenuReact = TSinchElementReact<TSinchSelectMenuElement>
|
|
|
22
28
|
rows?: number;
|
|
23
29
|
/** Allows multiple selection */
|
|
24
30
|
multiple?: boolean;
|
|
31
|
+
/** Enforce the search bar appearing, by default it appears above a certain number of options */
|
|
32
|
+
searchable?: boolean;
|
|
33
|
+
/** Text for search bar's placeholder */
|
|
34
|
+
'search-placeholder'?: string;
|
|
25
35
|
/** Label that is used for a11y */
|
|
26
36
|
'aria-label': string;
|
|
27
37
|
/** Change value handler */
|
|
38
|
+
'on-search-change'?: (e: CustomEvent<string>) => void;
|
|
39
|
+
/** Change value handler */
|
|
28
40
|
'on-change'?: (e: CustomEvent<string>) => void;
|
|
29
41
|
};
|