kr-elements 0.0.1-alpha.3 → 0.0.1-alpha.30
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/dist/cjs/combobox/Boolean.attribute.value.normalizer.js +2 -2
- package/dist/cjs/combobox/Combobox.markup.js +113 -62
- package/dist/cjs/combobox/HTML.combobox.element.js +40 -15
- package/dist/cjs/combobox/HTML.combobox.option.element.js +41 -37
- package/dist/cjs/combobox/HTML.combobox.tag.element.js +0 -3
- package/dist/cjs/index.js +67 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/esm/combobox/Boolean.attribute.value.normalizer.js +1 -0
- package/dist/esm/combobox/Combobox.markup.js +113 -62
- package/dist/esm/combobox/HTML.combobox.element.js +26 -3
- package/dist/esm/combobox/HTML.combobox.option.element.js +33 -31
- package/dist/esm/combobox/HTML.combobox.tag.element.js +0 -3
- package/dist/esm/index.js +67 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
- package/dist/types/combobox/Boolean.attribute.value.normalizer.d.ts +2 -0
- package/dist/types/combobox/Boolean.attribute.value.normalizer.d.ts.map +1 -0
- package/dist/types/combobox/Combobox.markup.d.ts +6 -1
- package/dist/types/combobox/Combobox.markup.d.ts.map +1 -0
- package/dist/types/combobox/HTML.combobox.element.d.ts +1 -0
- package/dist/types/combobox/HTML.combobox.element.d.ts.map +1 -0
- package/dist/types/combobox/HTML.combobox.option.element.d.ts +1 -0
- package/dist/types/combobox/HTML.combobox.option.element.d.ts.map +1 -0
- package/dist/types/combobox/HTML.combobox.tag.element.d.ts +1 -0
- package/dist/types/combobox/HTML.combobox.tag.element.d.ts.map +1 -0
- package/dist/types/combobox/index.d.ts +1 -0
- package/dist/types/combobox/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +213 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -0
- package/dist/types/types.d.ts +198 -0
- package/package.json +14 -14
- package/dist/cjs/Boolean.attribute.value.normalizer.js +0 -11
- package/dist/cjs/Combobox.markup.js +0 -315
- package/dist/cjs/HTML.combobox.element.js +0 -317
- package/dist/cjs/HTML.combobox.option.element.js +0 -95
- package/dist/cjs/HTML.combobox.tag.element.js +0 -22
- package/dist/esm/Boolean.attribute.value.normalizer.js +0 -7
- package/dist/esm/Combobox.markup.js +0 -311
- package/dist/esm/HTML.combobox.element.js +0 -313
- package/dist/esm/HTML.combobox.option.element.js +0 -91
- package/dist/esm/HTML.combobox.tag.element.js +0 -18
- package/dist/types/Boolean.attribute.value.normalizer.d.ts +0 -2
- package/dist/types/Boolean.attribute.value.normalizer.d.ts.map +0 -1
- package/dist/types/Combobox.markup.d.ts +0 -26
- package/dist/types/Combobox.markup.d.ts.map +0 -1
- package/dist/types/HTML.combobox.element.d.ts +0 -50
- package/dist/types/HTML.combobox.element.d.ts.map +0 -1
- package/dist/types/HTML.combobox.option.element.d.ts +0 -15
- package/dist/types/HTML.combobox.option.element.d.ts.map +0 -1
- package/dist/types/HTML.combobox.tag.element.d.ts +0 -4
- package/dist/types/HTML.combobox.tag.element.d.ts.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toBoolean =
|
|
3
|
+
exports.toBoolean = toBoolean;
|
|
4
|
+
/** Transform invalid (nullish or stringed) values to correct boolean value */
|
|
4
5
|
function toBoolean(value) {
|
|
5
6
|
if (value == null || value === 'false' || value === false)
|
|
6
7
|
value = false;
|
|
@@ -8,4 +9,3 @@ function toBoolean(value) {
|
|
|
8
9
|
value = true;
|
|
9
10
|
return Boolean(value);
|
|
10
11
|
}
|
|
11
|
-
exports.toBoolean = toBoolean;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ComboboxMarkup = void 0;
|
|
4
4
|
const HTML_combobox_tag_element_js_1 = require("./HTML.combobox.tag.element.js");
|
|
5
5
|
class ComboboxMarkup {
|
|
6
|
+
static scrollToTopOptions = { top: 0, behavior: 'smooth' };
|
|
6
7
|
#shadowRoot;
|
|
7
8
|
#internals;
|
|
8
9
|
tagsContainer = null;
|
|
@@ -11,6 +12,8 @@ class ComboboxMarkup {
|
|
|
11
12
|
dropdown = null;
|
|
12
13
|
placeholder = null;
|
|
13
14
|
searchInput = null;
|
|
15
|
+
tagTemplate = null;
|
|
16
|
+
options;
|
|
14
17
|
connected = false;
|
|
15
18
|
constructor(shadowRoot, internals) {
|
|
16
19
|
this.#shadowRoot = shadowRoot;
|
|
@@ -24,30 +27,37 @@ class ComboboxMarkup {
|
|
|
24
27
|
connect() {
|
|
25
28
|
const placeholder = this.#shadowRoot.host.getAttribute('placeholder') || '';
|
|
26
29
|
this.tagsContainer = this.#shadowRoot.querySelector('#tags');
|
|
27
|
-
this.optionsContainer = this.#shadowRoot.querySelector('[part
|
|
28
|
-
this.clearAllButton = this.#shadowRoot.querySelector('[part
|
|
30
|
+
this.optionsContainer = this.#shadowRoot.querySelector('[part*="options"]');
|
|
31
|
+
this.clearAllButton = this.#shadowRoot.querySelector('[part*="clear-all-button"]');
|
|
29
32
|
this.dropdown = this.#shadowRoot.querySelector('#dropdown');
|
|
30
33
|
this.placeholder = this.#shadowRoot.querySelector('#placeholder');
|
|
31
34
|
this.placeholder.innerText = placeholder;
|
|
32
|
-
this.searchInput = this.#shadowRoot.querySelector('[part
|
|
33
|
-
this.searchInput.value = this.#shadowRoot.host.getAttribute('
|
|
35
|
+
this.searchInput = this.#shadowRoot.querySelector('[part*="search-input"]');
|
|
36
|
+
this.searchInput.value = this.#shadowRoot.host.getAttribute('query');
|
|
34
37
|
this.searchInput.placeholder = placeholder;
|
|
38
|
+
const innerTemplate = this.#shadowRoot.querySelector('#tag-template');
|
|
39
|
+
const doc = document.importNode(innerTemplate.content, true);
|
|
40
|
+
this.tagTemplate = doc.querySelector('box-tag');
|
|
35
41
|
this.connected = true;
|
|
36
42
|
}
|
|
43
|
+
invalidateOptionsCache() {
|
|
44
|
+
this.options = this.optionsContainer.querySelectorAll('box-option');
|
|
45
|
+
}
|
|
46
|
+
#timer = undefined;
|
|
37
47
|
sort(query) {
|
|
38
|
-
|
|
39
|
-
this
|
|
40
|
-
.
|
|
41
|
-
|
|
42
|
-
option.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
});
|
|
48
|
+
clearTimeout(this.#timer);
|
|
49
|
+
this.#timer = setTimeout(() => {
|
|
50
|
+
const regex = new RegExp(query.trim(), 'i');
|
|
51
|
+
this.options.forEach(option => {
|
|
52
|
+
if (!regex.test(option.textContent)) {
|
|
53
|
+
option.style.display = "none";
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
option.style.display = "flex";
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
this.dropdown.scrollTo(ComboboxMarkup.scrollToTopOptions);
|
|
60
|
+
}, 200);
|
|
51
61
|
}
|
|
52
62
|
disconnect() {
|
|
53
63
|
this.#shadowRoot.host.removeEventListener('focus', this.showDropdown);
|
|
@@ -85,42 +95,75 @@ class ComboboxMarkup {
|
|
|
85
95
|
try {
|
|
86
96
|
this.setDropdownPosition(this.#shadowRoot.host.getBoundingClientRect());
|
|
87
97
|
this.dropdown.style.display = 'flex';
|
|
98
|
+
// @ts-ignore
|
|
88
99
|
this.dropdown.showPopover();
|
|
89
100
|
this.#internals.ariaExpanded = "true";
|
|
101
|
+
if (this.tagsContainer?.children.length === 0) {
|
|
102
|
+
this.searchInput?.focus();
|
|
103
|
+
}
|
|
104
|
+
this.placeholder.innerText = '';
|
|
90
105
|
}
|
|
91
106
|
catch {
|
|
92
107
|
this.#internals.ariaExpanded = "false";
|
|
93
108
|
}
|
|
94
109
|
};
|
|
95
|
-
|
|
96
|
-
if (event.composedPath().includes(this.#shadowRoot.host))
|
|
97
|
-
return;
|
|
110
|
+
closeDropdown() {
|
|
98
111
|
try {
|
|
112
|
+
// @ts-ignore
|
|
99
113
|
this.dropdown.hidePopover();
|
|
100
114
|
this.dropdown.style.display = 'none';
|
|
101
115
|
this.#internals.ariaExpanded = "false";
|
|
116
|
+
this.placeholder.innerText = this.#shadowRoot.host.getAttribute('placeholder');
|
|
102
117
|
}
|
|
103
|
-
catch {
|
|
118
|
+
catch (e) {
|
|
104
119
|
this.#internals.ariaExpanded = "true";
|
|
105
120
|
}
|
|
121
|
+
}
|
|
122
|
+
hideDropdown = (event) => {
|
|
123
|
+
if (event.composedPath().includes(this.#shadowRoot.host))
|
|
124
|
+
return;
|
|
125
|
+
this.closeDropdown();
|
|
106
126
|
};
|
|
107
127
|
createAndAppendTag(option) {
|
|
108
|
-
const
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
128
|
+
const value = option.value;
|
|
129
|
+
const userTagTemplate = this.#shadowRoot.host.firstElementChild;
|
|
130
|
+
let tag;
|
|
131
|
+
let button;
|
|
132
|
+
if (userTagTemplate && userTagTemplate instanceof HTML_combobox_tag_element_js_1.HTMLComboboxTagElement) {
|
|
133
|
+
tag = userTagTemplate.cloneNode(true);
|
|
134
|
+
tag.querySelectorAll('[part]')
|
|
135
|
+
.forEach(node => {
|
|
136
|
+
const tokens = Array.from(node.part.values());
|
|
137
|
+
for (const token of tokens) {
|
|
138
|
+
const relatedPart = option.querySelector(`[part*="${token}"]`);
|
|
139
|
+
if (relatedPart) {
|
|
140
|
+
const newNode = relatedPart.cloneNode(true);
|
|
141
|
+
newNode.part.add(...tokens);
|
|
142
|
+
const exportedParts = option.getAttribute('exportparts');
|
|
143
|
+
if (exportedParts) {
|
|
144
|
+
tag.part.add(exportedParts);
|
|
145
|
+
}
|
|
146
|
+
tag.replaceChild(newNode, node);
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
button = tag.querySelector('[part*="tag-clear-button"]');
|
|
152
|
+
if (!button && this.#shadowRoot.host.hasAttribute('multiple')) {
|
|
153
|
+
throw new Error(`A button with part "tag-clear-button"`);
|
|
120
154
|
}
|
|
121
|
-
}
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
const template = this.tagTemplate;
|
|
158
|
+
tag = template.cloneNode(true);
|
|
159
|
+
const label = tag.querySelector('[part="tag-label"]');
|
|
160
|
+
label.textContent = option.label;
|
|
161
|
+
button = tag.querySelector('[part="tag-clear-button"]');
|
|
162
|
+
}
|
|
163
|
+
button.setAttribute('value', value);
|
|
164
|
+
tag.setAttribute('value', value);
|
|
122
165
|
this.tagsContainer.appendChild(tag);
|
|
123
|
-
return
|
|
166
|
+
return button;
|
|
124
167
|
}
|
|
125
168
|
getTagByValue(value) {
|
|
126
169
|
return this.tagsContainer.querySelector(`box-tag[value="${value}"]`);
|
|
@@ -128,15 +171,6 @@ class ComboboxMarkup {
|
|
|
128
171
|
getOptionByValue(value) {
|
|
129
172
|
return this.optionsContainer.querySelector(`box-option[value="${value}"]`);
|
|
130
173
|
}
|
|
131
|
-
get tagTemplate() {
|
|
132
|
-
let template = this.#shadowRoot.host.firstElementChild;
|
|
133
|
-
if (!template || !(template instanceof HTML_combobox_tag_element_js_1.HTMLComboboxTagElement)) {
|
|
134
|
-
const innerTemplate = this.#shadowRoot.querySelector('#tag-template');
|
|
135
|
-
const doc = document.importNode(innerTemplate.content, true);
|
|
136
|
-
template = doc.querySelector('box-tag');
|
|
137
|
-
}
|
|
138
|
-
return template;
|
|
139
|
-
}
|
|
140
174
|
get selectedOptions() {
|
|
141
175
|
return this.optionsContainer
|
|
142
176
|
.querySelectorAll('box-option[selected]');
|
|
@@ -165,24 +199,34 @@ class ComboboxMarkup {
|
|
|
165
199
|
overflow-y: scroll;
|
|
166
200
|
flex-direction: column;
|
|
167
201
|
border-radius: inherit;
|
|
202
|
+
border-color: ButtonFace;
|
|
203
|
+
border-width: inherit;
|
|
168
204
|
}
|
|
169
205
|
|
|
170
206
|
[part="options"] {
|
|
171
207
|
display: flex;
|
|
172
208
|
flex-direction: column;
|
|
209
|
+
justify-content: start;
|
|
173
210
|
gap: 2px;
|
|
174
211
|
padding-block: .5rem;
|
|
175
212
|
border-radius: inherit;
|
|
176
213
|
}
|
|
177
214
|
|
|
178
|
-
|
|
215
|
+
box-option {
|
|
179
216
|
display: flex;
|
|
180
217
|
border-radius: inherit;
|
|
181
218
|
content-visibility: auto;
|
|
219
|
+
cursor: pointer;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
box-option:hover {
|
|
223
|
+
background-color: color-mix(in srgb, Highlight, transparent 70%);
|
|
182
224
|
}
|
|
183
225
|
|
|
184
|
-
|
|
226
|
+
box-option[selected] {
|
|
185
227
|
background-color: Highlight;
|
|
228
|
+
cursor: not-allowed;
|
|
229
|
+
pointer-events: none;
|
|
186
230
|
}
|
|
187
231
|
|
|
188
232
|
[part="search-input"] {
|
|
@@ -193,6 +237,7 @@ class ComboboxMarkup {
|
|
|
193
237
|
border-radius: inherit;
|
|
194
238
|
border-style: inherit;
|
|
195
239
|
border-width: inherit;
|
|
240
|
+
border-color: inherit;
|
|
196
241
|
padding: inherit;
|
|
197
242
|
}
|
|
198
243
|
|
|
@@ -202,7 +247,11 @@ class ComboboxMarkup {
|
|
|
202
247
|
}
|
|
203
248
|
|
|
204
249
|
#placeholder {
|
|
250
|
+
text-align: left;
|
|
205
251
|
overflow: hidden;
|
|
252
|
+
padding-inline-start: 2px;
|
|
253
|
+
font-size: smaller;
|
|
254
|
+
color: dimgrey;
|
|
206
255
|
}
|
|
207
256
|
|
|
208
257
|
#tags:not(:empty) + #placeholder {
|
|
@@ -222,10 +271,9 @@ class ComboboxMarkup {
|
|
|
222
271
|
border-radius: inherit;
|
|
223
272
|
}
|
|
224
273
|
|
|
225
|
-
[part
|
|
274
|
+
[part*="box-tag"] {
|
|
226
275
|
width: 100%;
|
|
227
276
|
justify-self: start;
|
|
228
|
-
font-size: inherit;
|
|
229
277
|
box-sizing: border-box;
|
|
230
278
|
display: flex;
|
|
231
279
|
align-items: center;
|
|
@@ -234,15 +282,17 @@ class ComboboxMarkup {
|
|
|
234
282
|
padding-inline-end: .2rem;
|
|
235
283
|
background-color: transparent;
|
|
236
284
|
gap: 5px;
|
|
285
|
+
font-size: medium;
|
|
286
|
+
text-transform: uppercase;
|
|
237
287
|
}
|
|
238
288
|
|
|
239
|
-
:host([multiple]) [part
|
|
289
|
+
:host([multiple]) [part*="box-tag"] {
|
|
240
290
|
background-color: Highlight;
|
|
241
291
|
width: fit-content;
|
|
242
292
|
max-width: 100%;
|
|
243
293
|
}
|
|
244
294
|
|
|
245
|
-
[part
|
|
295
|
+
[part*="tag-label"] {
|
|
246
296
|
white-space: nowrap;
|
|
247
297
|
text-overflow: ellipsis;
|
|
248
298
|
overflow: hidden;
|
|
@@ -251,11 +301,11 @@ class ComboboxMarkup {
|
|
|
251
301
|
flex-grow: 1;
|
|
252
302
|
}
|
|
253
303
|
|
|
254
|
-
:host([multiple]) [part
|
|
304
|
+
:host([multiple]) [part*="tag-label"] {
|
|
255
305
|
flex-grow: unset;
|
|
256
306
|
}
|
|
257
307
|
|
|
258
|
-
[part
|
|
308
|
+
[part*="tag-clear-button"], [part*="clear-all-button"] {
|
|
259
309
|
border-radius: 100%;
|
|
260
310
|
border: none;
|
|
261
311
|
aspect-ratio: 1;
|
|
@@ -265,39 +315,40 @@ class ComboboxMarkup {
|
|
|
265
315
|
background-color: transparent;
|
|
266
316
|
}
|
|
267
317
|
|
|
268
|
-
[part
|
|
318
|
+
[part*="tag-clear-button"] {
|
|
269
319
|
inline-size: 1em;
|
|
270
320
|
block-size: 1em;
|
|
271
321
|
font-size: 80%;
|
|
272
322
|
display: none;
|
|
273
323
|
}
|
|
274
324
|
|
|
275
|
-
:host([multiple]) [part
|
|
276
|
-
:host([clearable]) [part
|
|
325
|
+
:host([multiple]) [part*="tag-clear-button"],
|
|
326
|
+
:host([clearable]) [part*="tag-clear-button"] {
|
|
277
327
|
display: block;
|
|
278
328
|
}
|
|
279
329
|
|
|
280
|
-
[part
|
|
330
|
+
[part*="clear-all-button"] {
|
|
281
331
|
font-size: inherit;
|
|
282
332
|
inline-size: 1.2em;
|
|
283
333
|
block-size: 1.2em;
|
|
284
334
|
display: none;
|
|
285
335
|
}
|
|
286
336
|
|
|
287
|
-
:host([multiple]) [part
|
|
337
|
+
:host([multiple]) [part*="clear-all-button"] {
|
|
288
338
|
display: block;
|
|
289
339
|
}
|
|
290
340
|
|
|
291
|
-
[part
|
|
292
|
-
[part
|
|
341
|
+
[part*="clear-all-button"]:hover,
|
|
342
|
+
[part*="tag-clear-button"]:hover {
|
|
293
343
|
color: ActiveText;
|
|
344
|
+
cursor: pointer;
|
|
294
345
|
}
|
|
295
346
|
|
|
296
|
-
[part
|
|
347
|
+
[part*="clear-all-button"]:hover {
|
|
297
348
|
background-color: ButtonFace;
|
|
298
349
|
}
|
|
299
350
|
|
|
300
|
-
:host:has(#tags:empty) [part
|
|
351
|
+
:host:has(#tags:empty) [part*="clear-all-button"] {
|
|
301
352
|
pointer-events: none;
|
|
302
353
|
color: darkgrey;
|
|
303
354
|
}
|
|
@@ -305,7 +356,7 @@ class ComboboxMarkup {
|
|
|
305
356
|
</style>
|
|
306
357
|
|
|
307
358
|
<div id="tags"></div>
|
|
308
|
-
<div id="placeholder"
|
|
359
|
+
<div id="placeholder"> </div>
|
|
309
360
|
<button part="clear-all-button">✕</button>
|
|
310
361
|
<div id="dropdown" popover="manual">
|
|
311
362
|
<input name="search-input" part="search-input" />
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var _a;
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
exports.HTMLComboboxElement = void 0;
|
|
4
5
|
const Combobox_markup_js_1 = require("./Combobox.markup.js");
|
|
@@ -22,14 +23,15 @@ class HTMLComboboxElement extends HTMLElement {
|
|
|
22
23
|
this.shadowRoot = this.attachShadow({ mode: 'closed', delegatesFocus: true });
|
|
23
24
|
this.#markup = new Combobox_markup_js_1.ComboboxMarkup(this.shadowRoot, this.internals);
|
|
24
25
|
this.shadowRoot.innerHTML = Combobox_markup_js_1.ComboboxMarkup.template;
|
|
25
|
-
this.shadowRoot.adoptedStyleSheets =
|
|
26
|
+
this.shadowRoot.adoptedStyleSheets = _a.styleSheet;
|
|
26
27
|
this.#observer = new MutationObserver(this.#onOptionsChanges);
|
|
27
28
|
}
|
|
29
|
+
// Lifecycle callbacks
|
|
28
30
|
connectedCallback() {
|
|
29
31
|
this.#markup.connect();
|
|
30
32
|
this.#initialAttributesSynchronization();
|
|
31
33
|
this.#onOptionsChanges([{ addedNodes: Array.from(this.children) }]);
|
|
32
|
-
this.#observer.observe(this,
|
|
34
|
+
this.#observer.observe(this, _a.observerOptions);
|
|
33
35
|
this.#markup.clearAllButton.addEventListener('click', this.#onClickClearAllButton);
|
|
34
36
|
this.#markup.searchInput.addEventListener('input', this.#onInput);
|
|
35
37
|
}
|
|
@@ -47,6 +49,8 @@ class HTMLComboboxElement extends HTMLElement {
|
|
|
47
49
|
formDisabledCallback(isDisabled) {
|
|
48
50
|
this.disabled = isDisabled;
|
|
49
51
|
}
|
|
52
|
+
// Instance properties
|
|
53
|
+
// readonly
|
|
50
54
|
get valueAsArray() {
|
|
51
55
|
return Array.from(this.#values);
|
|
52
56
|
}
|
|
@@ -59,6 +63,7 @@ class HTMLComboboxElement extends HTMLElement {
|
|
|
59
63
|
get willValidate() {
|
|
60
64
|
return this.internals.willValidate;
|
|
61
65
|
}
|
|
66
|
+
// configurable
|
|
62
67
|
get value() {
|
|
63
68
|
return this.valueAsArray.join(',');
|
|
64
69
|
}
|
|
@@ -154,23 +159,24 @@ class HTMLComboboxElement extends HTMLElement {
|
|
|
154
159
|
this.#markup.searchInput.placeholder = value;
|
|
155
160
|
}
|
|
156
161
|
}
|
|
162
|
+
// Instance methods
|
|
157
163
|
setAttribute(name, value) {
|
|
158
|
-
if (
|
|
164
|
+
if (_a.booleanAttributes.has(name)) {
|
|
159
165
|
Reflect.set(this, name, (0, Boolean_attribute_value_normalizer_js_1.toBoolean)(value));
|
|
160
166
|
return;
|
|
161
167
|
}
|
|
162
|
-
if (
|
|
168
|
+
if (_a.stringAttributes.has(name)) {
|
|
163
169
|
Reflect.set(this, name, value);
|
|
164
170
|
return;
|
|
165
171
|
}
|
|
166
172
|
super.setAttribute(name, value);
|
|
167
173
|
}
|
|
168
174
|
removeAttribute(name) {
|
|
169
|
-
if (
|
|
175
|
+
if (_a.booleanAttributes.has(name)) {
|
|
170
176
|
Reflect.set(this, name, false);
|
|
171
177
|
return;
|
|
172
178
|
}
|
|
173
|
-
if (
|
|
179
|
+
if (_a.stringAttributes.has(name)) {
|
|
174
180
|
return;
|
|
175
181
|
}
|
|
176
182
|
super.removeAttribute(name);
|
|
@@ -189,6 +195,7 @@ class HTMLComboboxElement extends HTMLElement {
|
|
|
189
195
|
this.internals.setValidity({ customError: true }, message);
|
|
190
196
|
}
|
|
191
197
|
}
|
|
198
|
+
// Internal
|
|
192
199
|
#onInput = (event) => {
|
|
193
200
|
if (this.filterable) {
|
|
194
201
|
if (event.target && event.target instanceof HTMLInputElement) {
|
|
@@ -215,6 +222,7 @@ class HTMLComboboxElement extends HTMLElement {
|
|
|
215
222
|
}
|
|
216
223
|
});
|
|
217
224
|
});
|
|
225
|
+
this.#markup.invalidateOptionsCache();
|
|
218
226
|
this.#setValidityAndFormValue();
|
|
219
227
|
};
|
|
220
228
|
#selectOption(option) {
|
|
@@ -225,6 +233,9 @@ class HTMLComboboxElement extends HTMLElement {
|
|
|
225
233
|
option.toggleAttribute('selected', true);
|
|
226
234
|
const control = this.#markup.createAndAppendTag(option);
|
|
227
235
|
control.addEventListener('click', this.#onClickTagClearButton);
|
|
236
|
+
if (!this.multiple) {
|
|
237
|
+
this.#markup.closeDropdown();
|
|
238
|
+
}
|
|
228
239
|
}
|
|
229
240
|
#onSelectOption = (event) => {
|
|
230
241
|
let option;
|
|
@@ -246,18 +257,31 @@ class HTMLComboboxElement extends HTMLElement {
|
|
|
246
257
|
this.#values.clear();
|
|
247
258
|
this.#markup.tagsContainer.replaceChildren();
|
|
248
259
|
}
|
|
260
|
+
if (!this.multiple) {
|
|
261
|
+
event.stopPropagation();
|
|
262
|
+
}
|
|
249
263
|
this.#selectOption(option);
|
|
250
264
|
this.#setValidityAndFormValue();
|
|
251
265
|
this.dispatchEvent(new Event('change'));
|
|
252
266
|
}
|
|
253
267
|
};
|
|
254
268
|
#onClickTagClearButton = (event) => {
|
|
255
|
-
|
|
256
|
-
|
|
269
|
+
let button;
|
|
270
|
+
if (event.target instanceof HTMLButtonElement) {
|
|
271
|
+
button = event.target;
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
button = event.composedPath()
|
|
275
|
+
.find(el => {
|
|
276
|
+
return el instanceof HTMLElement && el.part.contains('tag-clear-button');
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
if (button) {
|
|
280
|
+
const value = button.value;
|
|
257
281
|
const option = this.#markup.getOptionByValue(value);
|
|
258
282
|
const tag = this.#markup.getTagByValue(value);
|
|
259
283
|
option.removeAttribute('selected');
|
|
260
|
-
this.#values.delete(
|
|
284
|
+
this.#values.delete(value);
|
|
261
285
|
tag.remove();
|
|
262
286
|
this.#setValidityAndFormValue();
|
|
263
287
|
this.dispatchEvent(new Event('change'));
|
|
@@ -276,11 +300,11 @@ class HTMLComboboxElement extends HTMLElement {
|
|
|
276
300
|
}
|
|
277
301
|
}
|
|
278
302
|
#initialAttributesSynchronization() {
|
|
279
|
-
for (const key of
|
|
303
|
+
for (const key of _a.booleanAttributes) {
|
|
280
304
|
const value = (0, Boolean_attribute_value_normalizer_js_1.toBoolean)(this.getAttribute(key));
|
|
281
305
|
Reflect.set(this, key, value);
|
|
282
306
|
}
|
|
283
|
-
for (const key of
|
|
307
|
+
for (const key of _a.stringAttributes) {
|
|
284
308
|
if (this.hasAttribute(key)) {
|
|
285
309
|
Reflect.set(this, key, this.getAttribute(key));
|
|
286
310
|
}
|
|
@@ -290,17 +314,17 @@ class HTMLComboboxElement extends HTMLElement {
|
|
|
290
314
|
}
|
|
291
315
|
static loadCssFromDocumentStyleSheets() {
|
|
292
316
|
if (document.readyState === 'complete') {
|
|
293
|
-
|
|
317
|
+
_a.#loadDocumentStyleSheets();
|
|
294
318
|
}
|
|
295
319
|
if (document.readyState === 'loading') {
|
|
296
|
-
document.addEventListener('DOMContentLoaded',
|
|
320
|
+
document.addEventListener('DOMContentLoaded', _a.#loadDocumentStyleSheets);
|
|
297
321
|
}
|
|
298
322
|
if (document.readyState === 'interactive') {
|
|
299
|
-
queueMicrotask(
|
|
323
|
+
queueMicrotask(_a.#loadDocumentStyleSheets);
|
|
300
324
|
}
|
|
301
325
|
}
|
|
302
326
|
static #loadDocumentStyleSheets() {
|
|
303
|
-
const [innerSheet] =
|
|
327
|
+
const [innerSheet] = _a.styleSheet;
|
|
304
328
|
for (const outerSheet of document.styleSheets) {
|
|
305
329
|
for (const rule of outerSheet.cssRules) {
|
|
306
330
|
innerSheet.insertRule(rule.cssText, innerSheet.cssRules.length);
|
|
@@ -309,6 +333,7 @@ class HTMLComboboxElement extends HTMLElement {
|
|
|
309
333
|
}
|
|
310
334
|
}
|
|
311
335
|
exports.HTMLComboboxElement = HTMLComboboxElement;
|
|
336
|
+
_a = HTMLComboboxElement;
|
|
312
337
|
document.addEventListener('keypress', (event) => {
|
|
313
338
|
if (document.activeElement instanceof HTMLComboboxElement) {
|
|
314
339
|
if (document.activeElement.shadowRoot.activeElement instanceof HTML_combobox_option_element_js_1.HTMLComboboxOptionElement) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var _a;
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
exports.HTMLComboboxOptionElement = void 0;
|
|
4
5
|
const Boolean_attribute_value_normalizer_js_1 = require("./Boolean.attribute.value.normalizer.js");
|
|
@@ -10,23 +11,47 @@ class HTMLComboboxOptionElement extends HTMLElement {
|
|
|
10
11
|
super.setAttribute('part', 'box-option');
|
|
11
12
|
super.setAttribute('tabindex', "0");
|
|
12
13
|
super.setAttribute('role', "option");
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
const value = this.value;
|
|
15
|
+
const label = this.label;
|
|
16
|
+
const hasNoMarkup = this.children.length === 0;
|
|
17
|
+
const text = this.textContent.trim();
|
|
18
|
+
const hasText = text.length > 0;
|
|
19
|
+
if (!value && !label) {
|
|
20
|
+
if (hasNoMarkup && hasText) {
|
|
21
|
+
this.value = text;
|
|
22
|
+
this.label = text;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
throw new Error('box-option must have value and label attributes');
|
|
26
|
+
}
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (value && !label) {
|
|
30
|
+
if (hasNoMarkup && hasText) {
|
|
31
|
+
this.label = text;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
this.label = value;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (!value && label) {
|
|
38
|
+
this.value = label;
|
|
39
|
+
}
|
|
40
|
+
if (hasNoMarkup && !hasText) {
|
|
41
|
+
this.textContent = label || value;
|
|
15
42
|
}
|
|
16
43
|
}
|
|
17
44
|
get value() {
|
|
18
45
|
return this.getAttribute('value');
|
|
19
46
|
}
|
|
20
47
|
set value(value) {
|
|
21
|
-
|
|
22
|
-
super.setAttribute('value', value);
|
|
48
|
+
super.setAttribute('value', String(value));
|
|
23
49
|
}
|
|
24
50
|
get label() {
|
|
25
|
-
return this.getAttribute('
|
|
51
|
+
return this.getAttribute('label');
|
|
26
52
|
}
|
|
27
53
|
set label(value) {
|
|
28
|
-
|
|
29
|
-
super.setAttribute('label', value);
|
|
54
|
+
super.setAttribute('label', String(value));
|
|
30
55
|
}
|
|
31
56
|
get selected() {
|
|
32
57
|
return this.hasAttribute('selected');
|
|
@@ -35,61 +60,40 @@ class HTMLComboboxOptionElement extends HTMLElement {
|
|
|
35
60
|
super.toggleAttribute('selected', (0, Boolean_attribute_value_normalizer_js_1.toBoolean)(value));
|
|
36
61
|
}
|
|
37
62
|
#initialAttributesSynchronization() {
|
|
38
|
-
for (const key of
|
|
63
|
+
for (const key of _a.booleanAttributes) {
|
|
39
64
|
const value = (0, Boolean_attribute_value_normalizer_js_1.toBoolean)(this.getAttribute(key));
|
|
40
65
|
Reflect.set(this, key, value);
|
|
41
66
|
}
|
|
42
|
-
for (const key of
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
get #optionHasOnlyTextNode() {
|
|
47
|
-
return this.children.length === 0 && this.textContent.length > 0;
|
|
48
|
-
}
|
|
49
|
-
#getOrExtractValue(value, name) {
|
|
50
|
-
if (typeof value === 'string')
|
|
51
|
-
return value;
|
|
52
|
-
if (value == null) {
|
|
53
|
-
const opposite = name === 'label' ? 'value' : 'label';
|
|
54
|
-
const oppositeValue = this.getAttribute(opposite);
|
|
55
|
-
if (oppositeValue) {
|
|
56
|
-
value = oppositeValue;
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
if (this.#optionHasOnlyTextNode) {
|
|
60
|
-
value = this.textContent;
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
throw new TypeError('No value, or label or textContent found');
|
|
64
|
-
}
|
|
67
|
+
for (const key of _a.stringAttributes) {
|
|
68
|
+
if (this.hasAttribute(key)) {
|
|
69
|
+
Reflect.set(this, key, this.getAttribute(key));
|
|
65
70
|
}
|
|
66
|
-
return value;
|
|
67
71
|
}
|
|
68
|
-
throw new TypeError('Invalid value');
|
|
69
72
|
}
|
|
70
73
|
setAttribute(name, value) {
|
|
71
|
-
if (
|
|
74
|
+
if (_a.booleanAttributes.has(name)) {
|
|
72
75
|
Reflect.set(this, name, (0, Boolean_attribute_value_normalizer_js_1.toBoolean)(value));
|
|
73
76
|
return;
|
|
74
77
|
}
|
|
75
|
-
if (
|
|
78
|
+
if (_a.stringAttributes.has(name)) {
|
|
76
79
|
Reflect.set(this, name, value);
|
|
77
80
|
return;
|
|
78
81
|
}
|
|
79
82
|
super.setAttribute(name, value);
|
|
80
83
|
}
|
|
81
84
|
removeAttribute(name) {
|
|
82
|
-
if (
|
|
85
|
+
if (_a.stringAttributes.has(name)) {
|
|
83
86
|
Reflect.set(this, name, false);
|
|
84
87
|
return;
|
|
85
88
|
}
|
|
86
|
-
if (
|
|
89
|
+
if (_a.stringAttributes.has(name)) {
|
|
87
90
|
return;
|
|
88
91
|
}
|
|
89
92
|
super.removeAttribute(name);
|
|
90
93
|
}
|
|
91
94
|
}
|
|
92
95
|
exports.HTMLComboboxOptionElement = HTMLComboboxOptionElement;
|
|
96
|
+
_a = HTMLComboboxOptionElement;
|
|
93
97
|
if (!window.customElements.get('box-option')) {
|
|
94
98
|
window.customElements.define('box-option', HTMLComboboxOptionElement);
|
|
95
99
|
}
|
|
@@ -10,9 +10,6 @@ class HTMLComboboxTagElement extends HTMLElement {
|
|
|
10
10
|
throw new Error(`A <button> with part="tag-clear-button" is required for <combo-box> with multiple attribute`);
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
-
if (!this.querySelector('[part="tag-label"]')) {
|
|
14
|
-
throw new Error(`Invalid <box-tag-template>, an element with part="tag-label" is required as a descendant`);
|
|
15
|
-
}
|
|
16
13
|
}
|
|
17
14
|
}
|
|
18
15
|
}
|