@nectary/components 5.31.3 → 5.31.4
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/bundle.js +28 -13
- package/package.json +1 -1
- package/select-menu/index.d.ts +2 -2
- package/select-menu/index.js +29 -14
- package/select-menu/types.d.ts +1 -1
package/bundle.js
CHANGED
|
@@ -12975,7 +12975,6 @@ defineCustomElement("sinch-select-menu-option", SelectMenuOption);
|
|
|
12975
12975
|
const isSelectMenuOption = (el) => el.localName === "sinch-select-menu-option";
|
|
12976
12976
|
const templateHTML$h = '<style>:host{display:block;outline:0}#listbox{overflow-y:auto;max-height:var(--sinch-comp-select-menu-font-max-height)}#search{display:none;margin:10px}#search.active{display:block}#search-clear:not(.active){display:none}#not-found{display:flex;align-items:center;justify-content:center;width:100%;height:30px;margin-bottom:10px;pointer-events:none;user-select:none;--sinch-comp-text-font:var(--sinch-comp-select-menu-font-not-found-text);--sinch-global-color-text:var(--sinch-comp-select-menu-color-default-not-found-text-initial)}#not-found:not(.active){display:none}::slotted(.hidden){display:none}::slotted(sinch-title){padding:8px 16px;--sinch-global-color-text:var(--sinch-comp-select-menu-color-default-title-initial)}</style><sinch-input id="search" size="s" placeholder="Search"><sinch-icon icons-version="2" name="magnifying-glass" id="icon-search" slot="icon"></sinch-icon><sinch-button id="search-clear" slot="right"><sinch-icon icons-version="2" name="fa-xmark" slot="icon"></sinch-icon></sinch-button></sinch-input><div id="not-found"><sinch-text type="m">No results</sinch-text></div><div id="listbox" role="presentation"><slot></slot></div>';
|
|
12977
12977
|
const ITEM_HEIGHT = 40;
|
|
12978
|
-
const NUM_ITEMS_SEARCH = 7;
|
|
12979
12978
|
const template$h = document.createElement("template");
|
|
12980
12979
|
template$h.innerHTML = templateHTML$h;
|
|
12981
12980
|
class SelectMenu extends NectaryElement {
|
|
@@ -13076,6 +13075,7 @@ class SelectMenu extends NectaryElement {
|
|
|
13076
13075
|
"value",
|
|
13077
13076
|
"rows",
|
|
13078
13077
|
"multiple",
|
|
13078
|
+
"searchable",
|
|
13079
13079
|
"search-value",
|
|
13080
13080
|
"search-placeholder",
|
|
13081
13081
|
"search-autocomplete"
|
|
@@ -13093,6 +13093,10 @@ class SelectMenu extends NectaryElement {
|
|
|
13093
13093
|
this.#internals.ariaMultiSelectable = isAttrTrue(newVal).toString();
|
|
13094
13094
|
break;
|
|
13095
13095
|
}
|
|
13096
|
+
case "searchable": {
|
|
13097
|
+
this.#onOptionSlotChange();
|
|
13098
|
+
break;
|
|
13099
|
+
}
|
|
13096
13100
|
case "search-autocomplete": {
|
|
13097
13101
|
updateAttribute(this.#$search, "autocomplete", newVal);
|
|
13098
13102
|
break;
|
|
@@ -13102,13 +13106,7 @@ class SelectMenu extends NectaryElement {
|
|
|
13102
13106
|
break;
|
|
13103
13107
|
}
|
|
13104
13108
|
case "rows": {
|
|
13105
|
-
|
|
13106
|
-
const maxNumberOfRows = parseInt(newVal ?? "0", 10);
|
|
13107
|
-
this.#$listbox.style.maxHeight = attrValueToPixels(newVal, {
|
|
13108
|
-
min: 2,
|
|
13109
|
-
itemSizeMultiplier: ITEM_HEIGHT,
|
|
13110
|
-
addExtraSpace: numberOfItems > maxNumberOfRows
|
|
13111
|
-
});
|
|
13109
|
+
this.#updateListboxMaxHeight();
|
|
13112
13110
|
break;
|
|
13113
13111
|
}
|
|
13114
13112
|
case "search-placeholder": {
|
|
@@ -13148,7 +13146,13 @@ class SelectMenu extends NectaryElement {
|
|
|
13148
13146
|
return getBooleanAttribute(this, "multiple");
|
|
13149
13147
|
}
|
|
13150
13148
|
set searchable(isSearchable) {
|
|
13151
|
-
|
|
13149
|
+
if (isSearchable === false) {
|
|
13150
|
+
this.setAttribute("searchable", "false");
|
|
13151
|
+
} else if (isSearchable === true) {
|
|
13152
|
+
updateBooleanAttribute(this, "searchable", true);
|
|
13153
|
+
} else {
|
|
13154
|
+
this.removeAttribute("searchable");
|
|
13155
|
+
}
|
|
13152
13156
|
}
|
|
13153
13157
|
get searchable() {
|
|
13154
13158
|
const searchableAttribute = this.getAttribute("searchable");
|
|
@@ -13234,7 +13238,7 @@ class SelectMenu extends NectaryElement {
|
|
|
13234
13238
|
someFound ||= !isHidden;
|
|
13235
13239
|
setClass($opt, "hidden", isHidden);
|
|
13236
13240
|
}
|
|
13237
|
-
setClass(this.#$notFound, "active", !someFound);
|
|
13241
|
+
setClass(this.#$notFound, "active", searchValue.length > 0 && !someFound);
|
|
13238
13242
|
this.#selectOption(null);
|
|
13239
13243
|
};
|
|
13240
13244
|
#onContextKeyDown = (e) => {
|
|
@@ -13282,16 +13286,27 @@ class SelectMenu extends NectaryElement {
|
|
|
13282
13286
|
}
|
|
13283
13287
|
};
|
|
13284
13288
|
#onOptionSlotChange = () => {
|
|
13289
|
+
if (this.hasAttribute("rows")) {
|
|
13290
|
+
this.#updateListboxMaxHeight();
|
|
13291
|
+
}
|
|
13285
13292
|
const searchable = this.searchable;
|
|
13286
|
-
const
|
|
13287
|
-
const isEnoughOptions = options.length >= NUM_ITEMS_SEARCH;
|
|
13288
|
-
const isSearchActive = isEnoughOptions && searchable !== false || Boolean(searchable);
|
|
13293
|
+
const isSearchActive = searchable !== false;
|
|
13289
13294
|
if (!isSearchActive) {
|
|
13290
13295
|
updateAttribute(this.#$search, "value", null);
|
|
13291
13296
|
}
|
|
13292
13297
|
setClass(this.#$search, "active", isSearchActive);
|
|
13293
13298
|
this.#onValueChange(this.value);
|
|
13294
13299
|
};
|
|
13300
|
+
#updateListboxMaxHeight = () => {
|
|
13301
|
+
const rowsAttr = this.getAttribute("rows");
|
|
13302
|
+
const numberOfItems = this.#$optionSlot.assignedElements().length;
|
|
13303
|
+
const maxNumberOfRows = parseInt(rowsAttr ?? "0", 10);
|
|
13304
|
+
this.#$listbox.style.maxHeight = attrValueToPixels(rowsAttr, {
|
|
13305
|
+
min: 2,
|
|
13306
|
+
itemSizeMultiplier: ITEM_HEIGHT,
|
|
13307
|
+
addExtraSpace: numberOfItems > maxNumberOfRows
|
|
13308
|
+
});
|
|
13309
|
+
};
|
|
13295
13310
|
#onValueChange(csv) {
|
|
13296
13311
|
if (this.multiple) {
|
|
13297
13312
|
const values = unpackCsv(csv);
|
package/package.json
CHANGED
package/select-menu/index.d.ts
CHANGED
|
@@ -22,8 +22,8 @@ export declare class SelectMenu extends NectaryElement {
|
|
|
22
22
|
get rows(): number | null;
|
|
23
23
|
set multiple(isMultiple: boolean);
|
|
24
24
|
get multiple(): boolean;
|
|
25
|
-
set searchable(isSearchable: boolean | null);
|
|
26
|
-
get searchable(): boolean | null;
|
|
25
|
+
set searchable(isSearchable: boolean | null | undefined);
|
|
26
|
+
get searchable(): boolean | null | undefined;
|
|
27
27
|
set 'search-autocomplete'(autocomplete: string);
|
|
28
28
|
get 'search-autocomplete'(): string;
|
|
29
29
|
set 'search-placeholder'(placeholder: string);
|
package/select-menu/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import "../text/index.js";
|
|
|
4
4
|
import { isSelectMenuOption } from "../select-menu-option/utils.js";
|
|
5
5
|
import { subscribeContext } from "../utils/context.js";
|
|
6
6
|
import { unpackCsv, getFirstCsvValue, updateCsv } from "../utils/csv.js";
|
|
7
|
-
import { getBooleanAttribute, updateAttribute,
|
|
7
|
+
import { getBooleanAttribute, updateAttribute, updateExplicitBooleanAttribute, isAttrTrue, getAttribute, updateIntegerAttribute, getIntegerAttribute, updateBooleanAttribute, hasClass, setClass, attrValueToPixels } from "../utils/dom.js";
|
|
8
8
|
import { defineCustomElement, NectaryElement } from "../utils/element.js";
|
|
9
9
|
import { debounceTimeout } from "../utils/debounce.js";
|
|
10
10
|
import { getReactEventHandler } from "../utils/get-react-event-handler.js";
|
|
@@ -12,7 +12,6 @@ import { isTargetEqual } from "../utils/event-target.js";
|
|
|
12
12
|
import { setFormValue, CSVToFormData } from "../utils/form.js";
|
|
13
13
|
const templateHTML = '<style>:host{display:block;outline:0}#listbox{overflow-y:auto;max-height:var(--sinch-comp-select-menu-font-max-height)}#search{display:none;margin:10px}#search.active{display:block}#search-clear:not(.active){display:none}#not-found{display:flex;align-items:center;justify-content:center;width:100%;height:30px;margin-bottom:10px;pointer-events:none;user-select:none;--sinch-comp-text-font:var(--sinch-comp-select-menu-font-not-found-text);--sinch-global-color-text:var(--sinch-comp-select-menu-color-default-not-found-text-initial)}#not-found:not(.active){display:none}::slotted(.hidden){display:none}::slotted(sinch-title){padding:8px 16px;--sinch-global-color-text:var(--sinch-comp-select-menu-color-default-title-initial)}</style><sinch-input id="search" size="s" placeholder="Search"><sinch-icon icons-version="2" name="magnifying-glass" id="icon-search" slot="icon"></sinch-icon><sinch-button id="search-clear" slot="right"><sinch-icon icons-version="2" name="fa-xmark" slot="icon"></sinch-icon></sinch-button></sinch-input><div id="not-found"><sinch-text type="m">No results</sinch-text></div><div id="listbox" role="presentation"><slot></slot></div>';
|
|
14
14
|
const ITEM_HEIGHT = 40;
|
|
15
|
-
const NUM_ITEMS_SEARCH = 7;
|
|
16
15
|
const template = document.createElement("template");
|
|
17
16
|
template.innerHTML = templateHTML;
|
|
18
17
|
class SelectMenu extends NectaryElement {
|
|
@@ -113,6 +112,7 @@ class SelectMenu extends NectaryElement {
|
|
|
113
112
|
"value",
|
|
114
113
|
"rows",
|
|
115
114
|
"multiple",
|
|
115
|
+
"searchable",
|
|
116
116
|
"search-value",
|
|
117
117
|
"search-placeholder",
|
|
118
118
|
"search-autocomplete"
|
|
@@ -130,6 +130,10 @@ class SelectMenu extends NectaryElement {
|
|
|
130
130
|
this.#internals.ariaMultiSelectable = isAttrTrue(newVal).toString();
|
|
131
131
|
break;
|
|
132
132
|
}
|
|
133
|
+
case "searchable": {
|
|
134
|
+
this.#onOptionSlotChange();
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
133
137
|
case "search-autocomplete": {
|
|
134
138
|
updateAttribute(this.#$search, "autocomplete", newVal);
|
|
135
139
|
break;
|
|
@@ -139,13 +143,7 @@ class SelectMenu extends NectaryElement {
|
|
|
139
143
|
break;
|
|
140
144
|
}
|
|
141
145
|
case "rows": {
|
|
142
|
-
|
|
143
|
-
const maxNumberOfRows = parseInt(newVal ?? "0", 10);
|
|
144
|
-
this.#$listbox.style.maxHeight = attrValueToPixels(newVal, {
|
|
145
|
-
min: 2,
|
|
146
|
-
itemSizeMultiplier: ITEM_HEIGHT,
|
|
147
|
-
addExtraSpace: numberOfItems > maxNumberOfRows
|
|
148
|
-
});
|
|
146
|
+
this.#updateListboxMaxHeight();
|
|
149
147
|
break;
|
|
150
148
|
}
|
|
151
149
|
case "search-placeholder": {
|
|
@@ -185,7 +183,13 @@ class SelectMenu extends NectaryElement {
|
|
|
185
183
|
return getBooleanAttribute(this, "multiple");
|
|
186
184
|
}
|
|
187
185
|
set searchable(isSearchable) {
|
|
188
|
-
|
|
186
|
+
if (isSearchable === false) {
|
|
187
|
+
this.setAttribute("searchable", "false");
|
|
188
|
+
} else if (isSearchable === true) {
|
|
189
|
+
updateBooleanAttribute(this, "searchable", true);
|
|
190
|
+
} else {
|
|
191
|
+
this.removeAttribute("searchable");
|
|
192
|
+
}
|
|
189
193
|
}
|
|
190
194
|
get searchable() {
|
|
191
195
|
const searchableAttribute = this.getAttribute("searchable");
|
|
@@ -271,7 +275,7 @@ class SelectMenu extends NectaryElement {
|
|
|
271
275
|
someFound ||= !isHidden;
|
|
272
276
|
setClass($opt, "hidden", isHidden);
|
|
273
277
|
}
|
|
274
|
-
setClass(this.#$notFound, "active", !someFound);
|
|
278
|
+
setClass(this.#$notFound, "active", searchValue.length > 0 && !someFound);
|
|
275
279
|
this.#selectOption(null);
|
|
276
280
|
};
|
|
277
281
|
#onContextKeyDown = (e) => {
|
|
@@ -319,16 +323,27 @@ class SelectMenu extends NectaryElement {
|
|
|
319
323
|
}
|
|
320
324
|
};
|
|
321
325
|
#onOptionSlotChange = () => {
|
|
326
|
+
if (this.hasAttribute("rows")) {
|
|
327
|
+
this.#updateListboxMaxHeight();
|
|
328
|
+
}
|
|
322
329
|
const searchable = this.searchable;
|
|
323
|
-
const
|
|
324
|
-
const isEnoughOptions = options.length >= NUM_ITEMS_SEARCH;
|
|
325
|
-
const isSearchActive = isEnoughOptions && searchable !== false || Boolean(searchable);
|
|
330
|
+
const isSearchActive = searchable !== false;
|
|
326
331
|
if (!isSearchActive) {
|
|
327
332
|
updateAttribute(this.#$search, "value", null);
|
|
328
333
|
}
|
|
329
334
|
setClass(this.#$search, "active", isSearchActive);
|
|
330
335
|
this.#onValueChange(this.value);
|
|
331
336
|
};
|
|
337
|
+
#updateListboxMaxHeight = () => {
|
|
338
|
+
const rowsAttr = this.getAttribute("rows");
|
|
339
|
+
const numberOfItems = this.#$optionSlot.assignedElements().length;
|
|
340
|
+
const maxNumberOfRows = parseInt(rowsAttr ?? "0", 10);
|
|
341
|
+
this.#$listbox.style.maxHeight = attrValueToPixels(rowsAttr, {
|
|
342
|
+
min: 2,
|
|
343
|
+
itemSizeMultiplier: ITEM_HEIGHT,
|
|
344
|
+
addExtraSpace: numberOfItems > maxNumberOfRows
|
|
345
|
+
});
|
|
346
|
+
};
|
|
332
347
|
#onValueChange(csv) {
|
|
333
348
|
if (this.multiple) {
|
|
334
349
|
const values = unpackCsv(csv);
|
package/select-menu/types.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type TSinchSelectMenuProps = {
|
|
|
8
8
|
rows?: number;
|
|
9
9
|
/** Allows multiple selection */
|
|
10
10
|
multiple?: boolean;
|
|
11
|
-
/**
|
|
11
|
+
/** Show the search bar, shown by default unless explicitly set to false */
|
|
12
12
|
searchable?: boolean | null;
|
|
13
13
|
/** Value for the search input */
|
|
14
14
|
'search-value'?: string;
|