kr-elements 0.0.1-alpha.3 → 0.0.1-alpha.31
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 +112 -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 +112 -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 +5 -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;
|
|
@@ -11,6 +11,8 @@ class ComboboxMarkup {
|
|
|
11
11
|
dropdown = null;
|
|
12
12
|
placeholder = null;
|
|
13
13
|
searchInput = null;
|
|
14
|
+
tagTemplate = null;
|
|
15
|
+
options;
|
|
14
16
|
connected = false;
|
|
15
17
|
constructor(shadowRoot, internals) {
|
|
16
18
|
this.#shadowRoot = shadowRoot;
|
|
@@ -24,30 +26,37 @@ class ComboboxMarkup {
|
|
|
24
26
|
connect() {
|
|
25
27
|
const placeholder = this.#shadowRoot.host.getAttribute('placeholder') || '';
|
|
26
28
|
this.tagsContainer = this.#shadowRoot.querySelector('#tags');
|
|
27
|
-
this.optionsContainer = this.#shadowRoot.querySelector('[part
|
|
28
|
-
this.clearAllButton = this.#shadowRoot.querySelector('[part
|
|
29
|
+
this.optionsContainer = this.#shadowRoot.querySelector('[part*="options"]');
|
|
30
|
+
this.clearAllButton = this.#shadowRoot.querySelector('[part*="clear-all-button"]');
|
|
29
31
|
this.dropdown = this.#shadowRoot.querySelector('#dropdown');
|
|
30
32
|
this.placeholder = this.#shadowRoot.querySelector('#placeholder');
|
|
31
33
|
this.placeholder.innerText = placeholder;
|
|
32
|
-
this.searchInput = this.#shadowRoot.querySelector('[part
|
|
33
|
-
this.searchInput.value = this.#shadowRoot.host.getAttribute('
|
|
34
|
+
this.searchInput = this.#shadowRoot.querySelector('[part*="search-input"]');
|
|
35
|
+
this.searchInput.value = this.#shadowRoot.host.getAttribute('query');
|
|
34
36
|
this.searchInput.placeholder = placeholder;
|
|
37
|
+
const innerTemplate = this.#shadowRoot.querySelector('#tag-template');
|
|
38
|
+
const doc = document.importNode(innerTemplate.content, true);
|
|
39
|
+
this.tagTemplate = doc.querySelector('box-tag');
|
|
35
40
|
this.connected = true;
|
|
36
41
|
}
|
|
42
|
+
invalidateOptionsCache() {
|
|
43
|
+
this.options = this.optionsContainer.querySelectorAll('box-option');
|
|
44
|
+
}
|
|
45
|
+
#timer = undefined;
|
|
37
46
|
sort(query) {
|
|
38
|
-
|
|
39
|
-
this
|
|
40
|
-
.
|
|
41
|
-
|
|
42
|
-
option.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
});
|
|
47
|
+
clearTimeout(this.#timer);
|
|
48
|
+
this.#timer = setTimeout(() => {
|
|
49
|
+
const regex = new RegExp(query.trim(), 'i');
|
|
50
|
+
this.options.forEach((option) => {
|
|
51
|
+
if (!regex.test(option.textContent)) {
|
|
52
|
+
option.style.display = "none";
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
option.style.display = "flex";
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
this.dropdown.scrollTo({ top: 0, behavior: 'smooth' });
|
|
59
|
+
}, 200);
|
|
51
60
|
}
|
|
52
61
|
disconnect() {
|
|
53
62
|
this.#shadowRoot.host.removeEventListener('focus', this.showDropdown);
|
|
@@ -85,42 +94,75 @@ class ComboboxMarkup {
|
|
|
85
94
|
try {
|
|
86
95
|
this.setDropdownPosition(this.#shadowRoot.host.getBoundingClientRect());
|
|
87
96
|
this.dropdown.style.display = 'flex';
|
|
97
|
+
// @ts-ignore
|
|
88
98
|
this.dropdown.showPopover();
|
|
89
99
|
this.#internals.ariaExpanded = "true";
|
|
100
|
+
if (this.tagsContainer?.children.length === 0) {
|
|
101
|
+
this.searchInput?.focus();
|
|
102
|
+
}
|
|
103
|
+
this.placeholder.innerText = '';
|
|
90
104
|
}
|
|
91
105
|
catch {
|
|
92
106
|
this.#internals.ariaExpanded = "false";
|
|
93
107
|
}
|
|
94
108
|
};
|
|
95
|
-
|
|
96
|
-
if (event.composedPath().includes(this.#shadowRoot.host))
|
|
97
|
-
return;
|
|
109
|
+
closeDropdown() {
|
|
98
110
|
try {
|
|
111
|
+
// @ts-ignore
|
|
99
112
|
this.dropdown.hidePopover();
|
|
100
113
|
this.dropdown.style.display = 'none';
|
|
101
114
|
this.#internals.ariaExpanded = "false";
|
|
115
|
+
this.placeholder.innerText = this.#shadowRoot.host.getAttribute('placeholder');
|
|
102
116
|
}
|
|
103
|
-
catch {
|
|
117
|
+
catch (e) {
|
|
104
118
|
this.#internals.ariaExpanded = "true";
|
|
105
119
|
}
|
|
120
|
+
}
|
|
121
|
+
hideDropdown = (event) => {
|
|
122
|
+
if (event.composedPath().includes(this.#shadowRoot.host))
|
|
123
|
+
return;
|
|
124
|
+
this.closeDropdown();
|
|
106
125
|
};
|
|
107
126
|
createAndAppendTag(option) {
|
|
108
|
-
const
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
127
|
+
const value = option.value;
|
|
128
|
+
const userTagTemplate = this.#shadowRoot.host.firstElementChild;
|
|
129
|
+
let tag;
|
|
130
|
+
let button;
|
|
131
|
+
if (userTagTemplate && userTagTemplate instanceof HTML_combobox_tag_element_js_1.HTMLComboboxTagElement) {
|
|
132
|
+
tag = userTagTemplate.cloneNode(true);
|
|
133
|
+
tag.querySelectorAll('[part]')
|
|
134
|
+
.forEach(node => {
|
|
135
|
+
const tokens = Array.from(node.part.values());
|
|
136
|
+
for (const token of tokens) {
|
|
137
|
+
const relatedPart = option.querySelector(`[part*="${token}"]`);
|
|
138
|
+
if (relatedPart) {
|
|
139
|
+
const newNode = relatedPart.cloneNode(true);
|
|
140
|
+
newNode.part.add(...tokens);
|
|
141
|
+
const exportedParts = option.getAttribute('exportparts');
|
|
142
|
+
if (exportedParts) {
|
|
143
|
+
tag.part.add(exportedParts);
|
|
144
|
+
}
|
|
145
|
+
tag.replaceChild(newNode, node);
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
button = tag.querySelector('[part*="tag-clear-button"]');
|
|
151
|
+
if (!button && this.#shadowRoot.host.hasAttribute('multiple')) {
|
|
152
|
+
throw new Error(`A button with part "tag-clear-button"`);
|
|
120
153
|
}
|
|
121
|
-
}
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
const template = this.tagTemplate;
|
|
157
|
+
tag = template.cloneNode(true);
|
|
158
|
+
const label = tag.querySelector('[part="tag-label"]');
|
|
159
|
+
label.textContent = option.label;
|
|
160
|
+
button = tag.querySelector('[part="tag-clear-button"]');
|
|
161
|
+
}
|
|
162
|
+
button.setAttribute('value', value);
|
|
163
|
+
tag.setAttribute('value', value);
|
|
122
164
|
this.tagsContainer.appendChild(tag);
|
|
123
|
-
return
|
|
165
|
+
return button;
|
|
124
166
|
}
|
|
125
167
|
getTagByValue(value) {
|
|
126
168
|
return this.tagsContainer.querySelector(`box-tag[value="${value}"]`);
|
|
@@ -128,15 +170,6 @@ class ComboboxMarkup {
|
|
|
128
170
|
getOptionByValue(value) {
|
|
129
171
|
return this.optionsContainer.querySelector(`box-option[value="${value}"]`);
|
|
130
172
|
}
|
|
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
173
|
get selectedOptions() {
|
|
141
174
|
return this.optionsContainer
|
|
142
175
|
.querySelectorAll('box-option[selected]');
|
|
@@ -165,24 +198,34 @@ class ComboboxMarkup {
|
|
|
165
198
|
overflow-y: scroll;
|
|
166
199
|
flex-direction: column;
|
|
167
200
|
border-radius: inherit;
|
|
201
|
+
border-color: ButtonFace;
|
|
202
|
+
border-width: inherit;
|
|
168
203
|
}
|
|
169
204
|
|
|
170
205
|
[part="options"] {
|
|
171
206
|
display: flex;
|
|
172
207
|
flex-direction: column;
|
|
208
|
+
justify-content: start;
|
|
173
209
|
gap: 2px;
|
|
174
210
|
padding-block: .5rem;
|
|
175
211
|
border-radius: inherit;
|
|
176
212
|
}
|
|
177
213
|
|
|
178
|
-
|
|
214
|
+
box-option {
|
|
179
215
|
display: flex;
|
|
180
216
|
border-radius: inherit;
|
|
181
217
|
content-visibility: auto;
|
|
218
|
+
cursor: pointer;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
box-option:hover {
|
|
222
|
+
background-color: color-mix(in srgb, Highlight, transparent 70%);
|
|
182
223
|
}
|
|
183
224
|
|
|
184
|
-
|
|
225
|
+
box-option[selected] {
|
|
185
226
|
background-color: Highlight;
|
|
227
|
+
cursor: not-allowed;
|
|
228
|
+
pointer-events: none;
|
|
186
229
|
}
|
|
187
230
|
|
|
188
231
|
[part="search-input"] {
|
|
@@ -193,6 +236,7 @@ class ComboboxMarkup {
|
|
|
193
236
|
border-radius: inherit;
|
|
194
237
|
border-style: inherit;
|
|
195
238
|
border-width: inherit;
|
|
239
|
+
border-color: inherit;
|
|
196
240
|
padding: inherit;
|
|
197
241
|
}
|
|
198
242
|
|
|
@@ -202,7 +246,11 @@ class ComboboxMarkup {
|
|
|
202
246
|
}
|
|
203
247
|
|
|
204
248
|
#placeholder {
|
|
249
|
+
text-align: left;
|
|
205
250
|
overflow: hidden;
|
|
251
|
+
padding-inline-start: 2px;
|
|
252
|
+
font-size: smaller;
|
|
253
|
+
color: dimgrey;
|
|
206
254
|
}
|
|
207
255
|
|
|
208
256
|
#tags:not(:empty) + #placeholder {
|
|
@@ -222,10 +270,9 @@ class ComboboxMarkup {
|
|
|
222
270
|
border-radius: inherit;
|
|
223
271
|
}
|
|
224
272
|
|
|
225
|
-
[part
|
|
273
|
+
[part*="box-tag"] {
|
|
226
274
|
width: 100%;
|
|
227
275
|
justify-self: start;
|
|
228
|
-
font-size: inherit;
|
|
229
276
|
box-sizing: border-box;
|
|
230
277
|
display: flex;
|
|
231
278
|
align-items: center;
|
|
@@ -234,15 +281,17 @@ class ComboboxMarkup {
|
|
|
234
281
|
padding-inline-end: .2rem;
|
|
235
282
|
background-color: transparent;
|
|
236
283
|
gap: 5px;
|
|
284
|
+
font-size: medium;
|
|
285
|
+
text-transform: uppercase;
|
|
237
286
|
}
|
|
238
287
|
|
|
239
|
-
:host([multiple]) [part
|
|
288
|
+
:host([multiple]) [part*="box-tag"] {
|
|
240
289
|
background-color: Highlight;
|
|
241
290
|
width: fit-content;
|
|
242
291
|
max-width: 100%;
|
|
243
292
|
}
|
|
244
293
|
|
|
245
|
-
[part
|
|
294
|
+
[part*="tag-label"] {
|
|
246
295
|
white-space: nowrap;
|
|
247
296
|
text-overflow: ellipsis;
|
|
248
297
|
overflow: hidden;
|
|
@@ -251,11 +300,11 @@ class ComboboxMarkup {
|
|
|
251
300
|
flex-grow: 1;
|
|
252
301
|
}
|
|
253
302
|
|
|
254
|
-
:host([multiple]) [part
|
|
303
|
+
:host([multiple]) [part*="tag-label"] {
|
|
255
304
|
flex-grow: unset;
|
|
256
305
|
}
|
|
257
306
|
|
|
258
|
-
[part
|
|
307
|
+
[part*="tag-clear-button"], [part*="clear-all-button"] {
|
|
259
308
|
border-radius: 100%;
|
|
260
309
|
border: none;
|
|
261
310
|
aspect-ratio: 1;
|
|
@@ -265,39 +314,40 @@ class ComboboxMarkup {
|
|
|
265
314
|
background-color: transparent;
|
|
266
315
|
}
|
|
267
316
|
|
|
268
|
-
[part
|
|
317
|
+
[part*="tag-clear-button"] {
|
|
269
318
|
inline-size: 1em;
|
|
270
319
|
block-size: 1em;
|
|
271
320
|
font-size: 80%;
|
|
272
321
|
display: none;
|
|
273
322
|
}
|
|
274
323
|
|
|
275
|
-
:host([multiple]) [part
|
|
276
|
-
:host([clearable]) [part
|
|
324
|
+
:host([multiple]) [part*="tag-clear-button"],
|
|
325
|
+
:host([clearable]) [part*="tag-clear-button"] {
|
|
277
326
|
display: block;
|
|
278
327
|
}
|
|
279
328
|
|
|
280
|
-
[part
|
|
329
|
+
[part*="clear-all-button"] {
|
|
281
330
|
font-size: inherit;
|
|
282
331
|
inline-size: 1.2em;
|
|
283
332
|
block-size: 1.2em;
|
|
284
333
|
display: none;
|
|
285
334
|
}
|
|
286
335
|
|
|
287
|
-
:host([multiple]) [part
|
|
336
|
+
:host([multiple]) [part*="clear-all-button"] {
|
|
288
337
|
display: block;
|
|
289
338
|
}
|
|
290
339
|
|
|
291
|
-
[part
|
|
292
|
-
[part
|
|
340
|
+
[part*="clear-all-button"]:hover,
|
|
341
|
+
[part*="tag-clear-button"]:hover {
|
|
293
342
|
color: ActiveText;
|
|
343
|
+
cursor: pointer;
|
|
294
344
|
}
|
|
295
345
|
|
|
296
|
-
[part
|
|
346
|
+
[part*="clear-all-button"]:hover {
|
|
297
347
|
background-color: ButtonFace;
|
|
298
348
|
}
|
|
299
349
|
|
|
300
|
-
:host:has(#tags:empty) [part
|
|
350
|
+
:host:has(#tags:empty) [part*="clear-all-button"] {
|
|
301
351
|
pointer-events: none;
|
|
302
352
|
color: darkgrey;
|
|
303
353
|
}
|
|
@@ -305,7 +355,7 @@ class ComboboxMarkup {
|
|
|
305
355
|
</style>
|
|
306
356
|
|
|
307
357
|
<div id="tags"></div>
|
|
308
|
-
<div id="placeholder"
|
|
358
|
+
<div id="placeholder"> </div>
|
|
309
359
|
<button part="clear-all-button">✕</button>
|
|
310
360
|
<div id="dropdown" popover="manual">
|
|
311
361
|
<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
|
}
|