@deepfuture/dui-components 0.0.12 → 0.0.14
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/_deprecated/center/center.js +2 -2
- package/_deprecated/hstack/hstack.js +79 -33
- package/_deprecated/page-inset/page-inset.js +104 -56
- package/_deprecated/vstack/vstack.js +61 -19
- package/accordion/accordion-item.js +217 -147
- package/accordion/accordion.js +214 -149
- package/alert-dialog/alert-dialog-close.js +2 -2
- package/alert-dialog/alert-dialog-popup.js +230 -166
- package/alert-dialog/alert-dialog-trigger.js +2 -2
- package/alert-dialog/alert-dialog.js +128 -73
- package/avatar/avatar.js +175 -115
- package/badge/badge.js +2 -2
- package/breadcrumb/breadcrumb-ellipsis.js +2 -2
- package/breadcrumb/breadcrumb-item.js +2 -2
- package/breadcrumb/breadcrumb-link.js +2 -2
- package/breadcrumb/breadcrumb-page.js +2 -2
- package/breadcrumb/breadcrumb-separator.js +2 -2
- package/breadcrumb/breadcrumb.js +2 -2
- package/button/button.js +109 -65
- package/calendar/calendar.js +368 -290
- package/checkbox/checkbox-group.js +146 -87
- package/checkbox/checkbox.js +232 -167
- package/collapsible/collapsible.js +210 -132
- package/combobox/combobox.js +318 -252
- package/command/command-empty.js +67 -25
- package/command/command-group.js +87 -47
- package/command/command-input.js +84 -44
- package/command/command-item.js +168 -124
- package/command/command-list.js +60 -18
- package/command/command-separator.js +2 -2
- package/command/command-shortcut.js +2 -2
- package/command/command.js +297 -232
- package/data-table/data-table.js +225 -153
- package/dialog/dialog-close.js +2 -2
- package/dialog/dialog-popup.js +247 -181
- package/dialog/dialog-trigger.js +2 -2
- package/dialog/dialog.js +128 -73
- package/dropzone/dropzone.js +310 -249
- package/icon/icon.js +2 -2
- package/input/input.js +204 -143
- package/link/link.js +62 -24
- package/menu/menu-item.js +66 -24
- package/menu/menu.js +189 -136
- package/menubar/menubar.js +142 -91
- package/number-field/number-field.js +277 -204
- package/package.json +2 -3
- package/popover/popover-close.js +2 -2
- package/popover/popover-popup.js +126 -76
- package/popover/popover-trigger.js +2 -2
- package/popover/popover.js +181 -120
- package/portal/portal.js +128 -86
- package/preview-card/preview-card-popup.js +114 -66
- package/preview-card/preview-card-trigger.js +2 -2
- package/preview-card/preview-card.js +211 -142
- package/progress/progress.js +91 -45
- package/radio/radio-group.js +153 -90
- package/radio/radio.js +137 -94
- package/scroll-area/scroll-area.js +382 -283
- package/select/select.js +260 -203
- package/separator/separator.js +60 -18
- package/sidebar/sidebar-content.js +2 -2
- package/sidebar/sidebar-footer.js +2 -2
- package/sidebar/sidebar-group-label.js +2 -2
- package/sidebar/sidebar-group.js +2 -2
- package/sidebar/sidebar-header.js +2 -2
- package/sidebar/sidebar-inset.js +2 -2
- package/sidebar/sidebar-menu-button.js +118 -74
- package/sidebar/sidebar-menu-item.js +2 -2
- package/sidebar/sidebar-menu.js +2 -2
- package/sidebar/sidebar-provider.js +202 -129
- package/sidebar/sidebar-separator.js +2 -2
- package/sidebar/sidebar-trigger.js +2 -2
- package/sidebar/sidebar.js +150 -85
- package/slider/slider.js +217 -159
- package/spinner/spinner.js +70 -28
- package/switch/switch.js +174 -111
- package/tabs/tab.js +89 -47
- package/tabs/tabs-indicator.js +2 -2
- package/tabs/tabs-list.js +92 -54
- package/tabs/tabs-panel.js +90 -44
- package/tabs/tabs.js +130 -71
- package/textarea/textarea.js +153 -95
- package/toggle/toggle-group.js +184 -125
- package/toggle/toggle.js +131 -76
- package/toolbar/toolbar.js +79 -33
- package/tooltip/tooltip-popup.js +108 -60
- package/tooltip/tooltip-trigger.js +93 -55
- package/tooltip/tooltip.js +225 -154
- package/trunc/trunc.js +78 -34
package/combobox/combobox.js
CHANGED
|
@@ -1,12 +1,44 @@
|
|
|
1
1
|
/** Ported from original DUI: deep-future-app/app/client/components/dui/combobox */
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
5
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
6
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
7
|
+
var _, done = false;
|
|
8
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
9
|
+
var context = {};
|
|
10
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
11
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
12
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
13
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
14
|
+
if (kind === "accessor") {
|
|
15
|
+
if (result === void 0) continue;
|
|
16
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
17
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
18
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
19
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
20
|
+
}
|
|
21
|
+
else if (_ = accept(result)) {
|
|
22
|
+
if (kind === "field") initializers.unshift(_);
|
|
23
|
+
else descriptor[key] = _;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
27
|
+
done = true;
|
|
28
|
+
};
|
|
29
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
30
|
+
var useValue = arguments.length > 2;
|
|
31
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
32
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
33
|
+
}
|
|
34
|
+
return useValue ? value : void 0;
|
|
35
|
+
};
|
|
36
|
+
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
37
|
+
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
38
|
+
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
7
39
|
};
|
|
8
40
|
import { css, html, LitElement, nothing } from "lit";
|
|
9
|
-
import { property } from "lit/decorators.js";
|
|
41
|
+
import { property, state } from "lit/decorators.js";
|
|
10
42
|
import { repeat } from "lit/directives/repeat.js";
|
|
11
43
|
import { live } from "lit/directives/live.js";
|
|
12
44
|
import { base } from "@deepfuture/dui-core/base";
|
|
@@ -137,68 +169,121 @@ const portalPopupStyles = [
|
|
|
137
169
|
* @fires values-change - Multi-select: fired when a value is toggled.
|
|
138
170
|
* Detail: { value: string, selected: boolean, values: Set<string> }
|
|
139
171
|
*/
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
:
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
this
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
this
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
172
|
+
let DuiCombobox = (() => {
|
|
173
|
+
let _classSuper = LitElement;
|
|
174
|
+
let _options_decorators;
|
|
175
|
+
let _options_initializers = [];
|
|
176
|
+
let _options_extraInitializers = [];
|
|
177
|
+
let _value_decorators;
|
|
178
|
+
let _value_initializers = [];
|
|
179
|
+
let _value_extraInitializers = [];
|
|
180
|
+
let _values_decorators;
|
|
181
|
+
let _values_initializers = [];
|
|
182
|
+
let _values_extraInitializers = [];
|
|
183
|
+
let _multiple_decorators;
|
|
184
|
+
let _multiple_initializers = [];
|
|
185
|
+
let _multiple_extraInitializers = [];
|
|
186
|
+
let _placeholder_decorators;
|
|
187
|
+
let _placeholder_initializers = [];
|
|
188
|
+
let _placeholder_extraInitializers = [];
|
|
189
|
+
let _disabled_decorators;
|
|
190
|
+
let _disabled_initializers = [];
|
|
191
|
+
let _disabled_extraInitializers = [];
|
|
192
|
+
let _name_decorators;
|
|
193
|
+
let _name_initializers = [];
|
|
194
|
+
let _name_extraInitializers = [];
|
|
195
|
+
let _private_highlightedIndex_decorators;
|
|
196
|
+
let _private_highlightedIndex_initializers = [];
|
|
197
|
+
let _private_highlightedIndex_extraInitializers = [];
|
|
198
|
+
let _private_highlightedIndex_descriptor;
|
|
199
|
+
let _private_inputValue_decorators;
|
|
200
|
+
let _private_inputValue_initializers = [];
|
|
201
|
+
let _private_inputValue_extraInitializers = [];
|
|
202
|
+
let _private_inputValue_descriptor;
|
|
203
|
+
return class DuiCombobox extends _classSuper {
|
|
204
|
+
static {
|
|
205
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
206
|
+
_options_decorators = [property({ attribute: false })];
|
|
207
|
+
_value_decorators = [property({ type: String })];
|
|
208
|
+
_values_decorators = [property({ attribute: false })];
|
|
209
|
+
_multiple_decorators = [property({ type: Boolean, reflect: true })];
|
|
210
|
+
_placeholder_decorators = [property({ type: String })];
|
|
211
|
+
_disabled_decorators = [property({ type: Boolean, reflect: true })];
|
|
212
|
+
_name_decorators = [property({ type: String })];
|
|
213
|
+
_private_highlightedIndex_decorators = [state()];
|
|
214
|
+
_private_inputValue_decorators = [state()];
|
|
215
|
+
__esDecorate(this, null, _options_decorators, { kind: "accessor", name: "options", static: false, private: false, access: { has: obj => "options" in obj, get: obj => obj.options, set: (obj, value) => { obj.options = value; } }, metadata: _metadata }, _options_initializers, _options_extraInitializers);
|
|
216
|
+
__esDecorate(this, null, _value_decorators, { kind: "accessor", name: "value", static: false, private: false, access: { has: obj => "value" in obj, get: obj => obj.value, set: (obj, value) => { obj.value = value; } }, metadata: _metadata }, _value_initializers, _value_extraInitializers);
|
|
217
|
+
__esDecorate(this, null, _values_decorators, { kind: "accessor", name: "values", static: false, private: false, access: { has: obj => "values" in obj, get: obj => obj.values, set: (obj, value) => { obj.values = value; } }, metadata: _metadata }, _values_initializers, _values_extraInitializers);
|
|
218
|
+
__esDecorate(this, null, _multiple_decorators, { kind: "accessor", name: "multiple", static: false, private: false, access: { has: obj => "multiple" in obj, get: obj => obj.multiple, set: (obj, value) => { obj.multiple = value; } }, metadata: _metadata }, _multiple_initializers, _multiple_extraInitializers);
|
|
219
|
+
__esDecorate(this, null, _placeholder_decorators, { kind: "accessor", name: "placeholder", static: false, private: false, access: { has: obj => "placeholder" in obj, get: obj => obj.placeholder, set: (obj, value) => { obj.placeholder = value; } }, metadata: _metadata }, _placeholder_initializers, _placeholder_extraInitializers);
|
|
220
|
+
__esDecorate(this, null, _disabled_decorators, { kind: "accessor", name: "disabled", static: false, private: false, access: { has: obj => "disabled" in obj, get: obj => obj.disabled, set: (obj, value) => { obj.disabled = value; } }, metadata: _metadata }, _disabled_initializers, _disabled_extraInitializers);
|
|
221
|
+
__esDecorate(this, null, _name_decorators, { kind: "accessor", name: "name", static: false, private: false, access: { has: obj => "name" in obj, get: obj => obj.name, set: (obj, value) => { obj.name = value; } }, metadata: _metadata }, _name_initializers, _name_extraInitializers);
|
|
222
|
+
__esDecorate(this, _private_highlightedIndex_descriptor = { get: __setFunctionName(function () { return this.#highlightedIndex_accessor_storage; }, "#highlightedIndex", "get"), set: __setFunctionName(function (value) { this.#highlightedIndex_accessor_storage = value; }, "#highlightedIndex", "set") }, _private_highlightedIndex_decorators, { kind: "accessor", name: "#highlightedIndex", static: false, private: true, access: { has: obj => #highlightedIndex in obj, get: obj => obj.#highlightedIndex, set: (obj, value) => { obj.#highlightedIndex = value; } }, metadata: _metadata }, _private_highlightedIndex_initializers, _private_highlightedIndex_extraInitializers);
|
|
223
|
+
__esDecorate(this, _private_inputValue_descriptor = { get: __setFunctionName(function () { return this.#inputValue_accessor_storage; }, "#inputValue", "get"), set: __setFunctionName(function (value) { this.#inputValue_accessor_storage = value; }, "#inputValue", "set") }, _private_inputValue_decorators, { kind: "accessor", name: "#inputValue", static: false, private: true, access: { has: obj => #inputValue in obj, get: obj => obj.#inputValue, set: (obj, value) => { obj.#inputValue = value; } }, metadata: _metadata }, _private_inputValue_initializers, _private_inputValue_extraInitializers);
|
|
224
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
225
|
+
}
|
|
226
|
+
static tagName = "dui-combobox";
|
|
227
|
+
static styles = [base, hostStyles, componentStyles];
|
|
228
|
+
#options_accessor_storage = __runInitializers(this, _options_initializers, []);
|
|
229
|
+
/** The available options. */
|
|
230
|
+
get options() { return this.#options_accessor_storage; }
|
|
231
|
+
set options(value) { this.#options_accessor_storage = value; }
|
|
232
|
+
#value_accessor_storage = (__runInitializers(this, _options_extraInitializers), __runInitializers(this, _value_initializers, ""));
|
|
233
|
+
/** Currently selected value (single-select mode). */
|
|
234
|
+
get value() { return this.#value_accessor_storage; }
|
|
235
|
+
set value(value) { this.#value_accessor_storage = value; }
|
|
236
|
+
#values_accessor_storage = (__runInitializers(this, _value_extraInitializers), __runInitializers(this, _values_initializers, new Set()));
|
|
237
|
+
/** Currently selected values (multi-select mode). */
|
|
238
|
+
get values() { return this.#values_accessor_storage; }
|
|
239
|
+
set values(value) { this.#values_accessor_storage = value; }
|
|
240
|
+
#multiple_accessor_storage = (__runInitializers(this, _values_extraInitializers), __runInitializers(this, _multiple_initializers, false));
|
|
241
|
+
/** Enable multi-select mode with chips. */
|
|
242
|
+
get multiple() { return this.#multiple_accessor_storage; }
|
|
243
|
+
set multiple(value) { this.#multiple_accessor_storage = value; }
|
|
244
|
+
#placeholder_accessor_storage = (__runInitializers(this, _multiple_extraInitializers), __runInitializers(this, _placeholder_initializers, "Search..."));
|
|
245
|
+
/** Placeholder text for the input. */
|
|
246
|
+
get placeholder() { return this.#placeholder_accessor_storage; }
|
|
247
|
+
set placeholder(value) { this.#placeholder_accessor_storage = value; }
|
|
248
|
+
#disabled_accessor_storage = (__runInitializers(this, _placeholder_extraInitializers), __runInitializers(this, _disabled_initializers, false));
|
|
249
|
+
/** Whether the combobox is disabled. */
|
|
250
|
+
get disabled() { return this.#disabled_accessor_storage; }
|
|
251
|
+
set disabled(value) { this.#disabled_accessor_storage = value; }
|
|
252
|
+
#name_accessor_storage = (__runInitializers(this, _disabled_extraInitializers), __runInitializers(this, _name_initializers, ""));
|
|
253
|
+
/** Name for form submission. */
|
|
254
|
+
get name() { return this.#name_accessor_storage; }
|
|
255
|
+
set name(value) { this.#name_accessor_storage = value; }
|
|
256
|
+
#highlightedIndex_accessor_storage = (__runInitializers(this, _name_extraInitializers), __runInitializers(this, _private_highlightedIndex_initializers, -1));
|
|
257
|
+
get #highlightedIndex() { return _private_highlightedIndex_descriptor.get.call(this); }
|
|
258
|
+
set #highlightedIndex(value) { return _private_highlightedIndex_descriptor.set.call(this, value); }
|
|
259
|
+
#inputValue_accessor_storage = (__runInitializers(this, _private_highlightedIndex_extraInitializers), __runInitializers(this, _private_inputValue_initializers, ""));
|
|
260
|
+
get #inputValue() { return _private_inputValue_descriptor.get.call(this); }
|
|
261
|
+
set #inputValue(value) { return _private_inputValue_descriptor.set.call(this, value); }
|
|
262
|
+
#popup = (__runInitializers(this, _private_inputValue_extraInitializers), new FloatingPortalController(this, {
|
|
263
|
+
getAnchor: () => this.multiple
|
|
264
|
+
? this.shadowRoot?.querySelector(".Chips")
|
|
265
|
+
: this.shadowRoot?.querySelector(".InputWrapper"),
|
|
266
|
+
styles: portalPopupStyles,
|
|
267
|
+
onOpen: () => {
|
|
268
|
+
this.#highlightedIndex = -1;
|
|
269
|
+
if (!this.multiple) {
|
|
270
|
+
this.#inputValue = "";
|
|
271
|
+
const input = this.shadowRoot?.querySelector(".Input");
|
|
272
|
+
if (input)
|
|
273
|
+
input.value = "";
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
onClose: () => {
|
|
277
|
+
this.#highlightedIndex = -1;
|
|
278
|
+
if (!this.multiple) {
|
|
279
|
+
const selected = this.options.find((o) => o.value === this.value);
|
|
280
|
+
this.#inputValue = selected?.label ?? "";
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
renderPopup: (portal) => {
|
|
284
|
+
const filtered = this.#filteredOptions;
|
|
285
|
+
const isEmpty = filtered.length === 0;
|
|
286
|
+
return html `
|
|
202
287
|
<div
|
|
203
288
|
class="Popup"
|
|
204
289
|
?data-starting-style="${portal.isStarting}"
|
|
@@ -220,159 +305,159 @@ export class DuiCombobox extends LitElement {
|
|
|
220
305
|
</dui-scroll-area>
|
|
221
306
|
</div>
|
|
222
307
|
`;
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
// ---- Input handling ----
|
|
236
|
-
#onInput = (event) => {
|
|
237
|
-
const target = event.target;
|
|
238
|
-
this.#inputValue = target.value;
|
|
239
|
-
if (!this.#popup.isOpen) {
|
|
240
|
-
if (!this.disabled)
|
|
241
|
-
this.#popup.open();
|
|
308
|
+
},
|
|
309
|
+
}));
|
|
310
|
+
#inputId = `combobox-input-${crypto.randomUUID().slice(0, 8)}`;
|
|
311
|
+
#listId = `combobox-list-${crypto.randomUUID().slice(0, 8)}`;
|
|
312
|
+
/** Filtered options based on current input text. */
|
|
313
|
+
get #filteredOptions() {
|
|
314
|
+
const query = this.#inputValue.toLowerCase();
|
|
315
|
+
const opts = this.options;
|
|
316
|
+
if (!query)
|
|
317
|
+
return opts;
|
|
318
|
+
return opts.filter((opt) => opt.label.toLowerCase().includes(query));
|
|
242
319
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
this.#popup.
|
|
248
|
-
|
|
249
|
-
};
|
|
250
|
-
#onInputKeyDown = (event) => {
|
|
251
|
-
const filtered = this.#filteredOptions;
|
|
252
|
-
switch (event.key) {
|
|
253
|
-
case "ArrowDown":
|
|
254
|
-
event.preventDefault();
|
|
255
|
-
if (!this.#popup.isOpen) {
|
|
256
|
-
if (!this.disabled)
|
|
257
|
-
this.#popup.open();
|
|
258
|
-
}
|
|
259
|
-
else {
|
|
260
|
-
this.#highlightedIndex = Math.min(this.#highlightedIndex + 1, filtered.length - 1);
|
|
261
|
-
}
|
|
262
|
-
break;
|
|
263
|
-
case "ArrowUp":
|
|
264
|
-
event.preventDefault();
|
|
265
|
-
if (!this.#popup.isOpen) {
|
|
266
|
-
if (!this.disabled)
|
|
267
|
-
this.#popup.open();
|
|
268
|
-
}
|
|
269
|
-
else {
|
|
270
|
-
this.#highlightedIndex = Math.max(this.#highlightedIndex - 1, 0);
|
|
271
|
-
}
|
|
272
|
-
break;
|
|
273
|
-
case "Enter": {
|
|
274
|
-
event.preventDefault();
|
|
275
|
-
if (this.#popup.isOpen) {
|
|
276
|
-
const index = this.#highlightedIndex >= 0 ? this.#highlightedIndex : 0;
|
|
277
|
-
const option = filtered[index];
|
|
278
|
-
if (option) {
|
|
279
|
-
this.#selectOption(option);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
else if (!this.disabled) {
|
|
320
|
+
// ---- Input handling ----
|
|
321
|
+
#onInput = (event) => {
|
|
322
|
+
const target = event.target;
|
|
323
|
+
this.#inputValue = target.value;
|
|
324
|
+
if (!this.#popup.isOpen) {
|
|
325
|
+
if (!this.disabled)
|
|
283
326
|
this.#popup.open();
|
|
284
|
-
}
|
|
285
|
-
break;
|
|
286
327
|
}
|
|
287
|
-
|
|
288
|
-
|
|
328
|
+
this.#highlightedIndex = -1;
|
|
329
|
+
};
|
|
330
|
+
#onInputFocus = () => {
|
|
331
|
+
if (!this.#popup.isOpen && !this.disabled) {
|
|
332
|
+
this.#popup.open();
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
#onInputKeyDown = (event) => {
|
|
336
|
+
const filtered = this.#filteredOptions;
|
|
337
|
+
switch (event.key) {
|
|
338
|
+
case "ArrowDown":
|
|
289
339
|
event.preventDefault();
|
|
290
|
-
this.#
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
case "Home":
|
|
300
|
-
if (this.#popup.isOpen) {
|
|
340
|
+
if (!this.#popup.isOpen) {
|
|
341
|
+
if (!this.disabled)
|
|
342
|
+
this.#popup.open();
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
this.#highlightedIndex = Math.min(this.#highlightedIndex + 1, filtered.length - 1);
|
|
346
|
+
}
|
|
347
|
+
break;
|
|
348
|
+
case "ArrowUp":
|
|
301
349
|
event.preventDefault();
|
|
302
|
-
this.#
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
350
|
+
if (!this.#popup.isOpen) {
|
|
351
|
+
if (!this.disabled)
|
|
352
|
+
this.#popup.open();
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
this.#highlightedIndex = Math.max(this.#highlightedIndex - 1, 0);
|
|
356
|
+
}
|
|
357
|
+
break;
|
|
358
|
+
case "Enter": {
|
|
307
359
|
event.preventDefault();
|
|
308
|
-
this.#
|
|
360
|
+
if (this.#popup.isOpen) {
|
|
361
|
+
const index = this.#highlightedIndex >= 0 ? this.#highlightedIndex : 0;
|
|
362
|
+
const option = filtered[index];
|
|
363
|
+
if (option) {
|
|
364
|
+
this.#selectOption(option);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
else if (!this.disabled) {
|
|
368
|
+
this.#popup.open();
|
|
369
|
+
}
|
|
370
|
+
break;
|
|
309
371
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
372
|
+
case "Escape":
|
|
373
|
+
if (this.#popup.isOpen) {
|
|
374
|
+
event.preventDefault();
|
|
375
|
+
this.#inputValue = "";
|
|
376
|
+
this.#popup.close();
|
|
377
|
+
}
|
|
378
|
+
break;
|
|
379
|
+
case "Tab":
|
|
380
|
+
if (this.#popup.isOpen) {
|
|
381
|
+
this.#popup.close();
|
|
382
|
+
}
|
|
383
|
+
break;
|
|
384
|
+
case "Home":
|
|
385
|
+
if (this.#popup.isOpen) {
|
|
386
|
+
event.preventDefault();
|
|
387
|
+
this.#highlightedIndex = 0;
|
|
316
388
|
}
|
|
389
|
+
break;
|
|
390
|
+
case "End":
|
|
391
|
+
if (this.#popup.isOpen) {
|
|
392
|
+
event.preventDefault();
|
|
393
|
+
this.#highlightedIndex = filtered.length - 1;
|
|
394
|
+
}
|
|
395
|
+
break;
|
|
396
|
+
case "Backspace":
|
|
397
|
+
if (this.multiple && this.#inputValue === "" && this.values.size > 0) {
|
|
398
|
+
const lastValue = Array.from(this.values).at(-1);
|
|
399
|
+
if (lastValue) {
|
|
400
|
+
this.#removeValue(lastValue);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
break;
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
// ---- Selection ----
|
|
407
|
+
#selectOption(option) {
|
|
408
|
+
if (this.multiple) {
|
|
409
|
+
const newValues = new Set(this.values);
|
|
410
|
+
const selected = !newValues.has(option.value);
|
|
411
|
+
if (selected) {
|
|
412
|
+
newValues.add(option.value);
|
|
317
413
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
414
|
+
else {
|
|
415
|
+
newValues.delete(option.value);
|
|
416
|
+
}
|
|
417
|
+
this.values = newValues;
|
|
418
|
+
this.#inputValue = "";
|
|
419
|
+
this.#highlightedIndex = -1;
|
|
420
|
+
this.dispatchEvent(valuesChangeEvent({
|
|
421
|
+
value: option.value,
|
|
422
|
+
selected,
|
|
423
|
+
values: newValues,
|
|
424
|
+
}));
|
|
425
|
+
const input = this.shadowRoot?.querySelector(".Input");
|
|
426
|
+
input?.focus();
|
|
328
427
|
}
|
|
329
428
|
else {
|
|
330
|
-
|
|
429
|
+
this.value = option.value;
|
|
430
|
+
this.#inputValue = option.label;
|
|
431
|
+
this.dispatchEvent(valueChangeEvent({ value: option.value, option }));
|
|
432
|
+
this.#popup.close();
|
|
331
433
|
}
|
|
434
|
+
}
|
|
435
|
+
#removeValue(value) {
|
|
436
|
+
const newValues = new Set(this.values);
|
|
437
|
+
newValues.delete(value);
|
|
332
438
|
this.values = newValues;
|
|
333
|
-
this
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
439
|
+
this.dispatchEvent(valuesChangeEvent({ value, selected: false, values: newValues }));
|
|
440
|
+
}
|
|
441
|
+
#onItemClick = (option) => {
|
|
442
|
+
this.#selectOption(option);
|
|
443
|
+
};
|
|
444
|
+
#onListMouseDown = (event) => {
|
|
445
|
+
event.preventDefault();
|
|
446
|
+
};
|
|
447
|
+
#onListMouseMove = () => {
|
|
448
|
+
if (this.#highlightedIndex !== -1) {
|
|
449
|
+
this.#highlightedIndex = -1;
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
#onChipsClick = () => {
|
|
340
453
|
const input = this.shadowRoot?.querySelector(".Input");
|
|
341
454
|
input?.focus();
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
#removeValue(value) {
|
|
351
|
-
const newValues = new Set(this.values);
|
|
352
|
-
newValues.delete(value);
|
|
353
|
-
this.values = newValues;
|
|
354
|
-
this.dispatchEvent(valuesChangeEvent({ value, selected: false, values: newValues }));
|
|
355
|
-
}
|
|
356
|
-
#onItemClick = (option) => {
|
|
357
|
-
this.#selectOption(option);
|
|
358
|
-
};
|
|
359
|
-
#onListMouseDown = (event) => {
|
|
360
|
-
event.preventDefault();
|
|
361
|
-
};
|
|
362
|
-
#onListMouseMove = () => {
|
|
363
|
-
if (this.#highlightedIndex !== -1) {
|
|
364
|
-
this.#highlightedIndex = -1;
|
|
365
|
-
}
|
|
366
|
-
};
|
|
367
|
-
#onChipsClick = () => {
|
|
368
|
-
const input = this.shadowRoot?.querySelector(".Input");
|
|
369
|
-
input?.focus();
|
|
370
|
-
};
|
|
371
|
-
// ---- Render ----
|
|
372
|
-
#renderChip = (value) => {
|
|
373
|
-
const option = this.options.find((o) => o.value === value);
|
|
374
|
-
const label = option?.label ?? value;
|
|
375
|
-
return html `
|
|
455
|
+
};
|
|
456
|
+
// ---- Render ----
|
|
457
|
+
#renderChip = (value) => {
|
|
458
|
+
const option = this.options.find((o) => o.value === value);
|
|
459
|
+
const label = option?.label ?? value;
|
|
460
|
+
return html `
|
|
376
461
|
<span class="Chip">
|
|
377
462
|
<span class="ChipLabel">${label}</span>
|
|
378
463
|
<button
|
|
@@ -381,21 +466,21 @@ export class DuiCombobox extends LitElement {
|
|
|
381
466
|
tabindex="-1"
|
|
382
467
|
@mousedown="${(e) => e.preventDefault()}"
|
|
383
468
|
@click="${(e) => {
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
469
|
+
e.stopPropagation();
|
|
470
|
+
this.#removeValue(value);
|
|
471
|
+
}}"
|
|
387
472
|
>
|
|
388
473
|
<dui-icon><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg></dui-icon>
|
|
389
474
|
</button>
|
|
390
475
|
</span>
|
|
391
476
|
`;
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
477
|
+
};
|
|
478
|
+
#renderItem = (option, index) => {
|
|
479
|
+
const isSelected = this.multiple
|
|
480
|
+
? this.values.has(option.value)
|
|
481
|
+
: option.value === this.value;
|
|
482
|
+
const isHighlighted = index === this.#highlightedIndex;
|
|
483
|
+
return html `
|
|
399
484
|
<div
|
|
400
485
|
class="Item"
|
|
401
486
|
role="option"
|
|
@@ -411,9 +496,9 @@ export class DuiCombobox extends LitElement {
|
|
|
411
496
|
</span>
|
|
412
497
|
</div>
|
|
413
498
|
`;
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
499
|
+
};
|
|
500
|
+
render() {
|
|
501
|
+
const inputHtml = html `
|
|
417
502
|
<input
|
|
418
503
|
class="Input"
|
|
419
504
|
id="${this.#inputId}"
|
|
@@ -424,8 +509,8 @@ export class DuiCombobox extends LitElement {
|
|
|
424
509
|
aria-expanded="${this.#popup.isOpen}"
|
|
425
510
|
aria-controls="${this.#listId}"
|
|
426
511
|
aria-activedescendant="${this.#highlightedIndex >= 0
|
|
427
|
-
|
|
428
|
-
|
|
512
|
+
? `${this.#listId}-option-${this.#highlightedIndex}`
|
|
513
|
+
: nothing}"
|
|
429
514
|
.value="${live(this.#inputValue)}"
|
|
430
515
|
.placeholder="${this.placeholder}"
|
|
431
516
|
?disabled="${this.disabled}"
|
|
@@ -434,8 +519,8 @@ export class DuiCombobox extends LitElement {
|
|
|
434
519
|
@keydown="${this.#onInputKeyDown}"
|
|
435
520
|
/>
|
|
436
521
|
`;
|
|
437
|
-
|
|
438
|
-
|
|
522
|
+
if (this.multiple) {
|
|
523
|
+
return html `
|
|
439
524
|
<div
|
|
440
525
|
class="Chips"
|
|
441
526
|
part="chips"
|
|
@@ -447,43 +532,24 @@ export class DuiCombobox extends LitElement {
|
|
|
447
532
|
<dui-icon class="Arrow"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg></dui-icon>
|
|
448
533
|
</div>
|
|
449
534
|
${this.name
|
|
450
|
-
|
|
535
|
+
? repeat(Array.from(this.values), (v) => v, (v) => html `
|
|
451
536
|
<input type="hidden" name="${this.name}" .value="${v}" />
|
|
452
537
|
`)
|
|
453
|
-
|
|
538
|
+
: nothing}
|
|
454
539
|
`;
|
|
455
|
-
|
|
456
|
-
|
|
540
|
+
}
|
|
541
|
+
return html `
|
|
457
542
|
<div class="InputWrapper" part="input-wrapper">
|
|
458
543
|
${inputHtml}
|
|
459
544
|
<dui-icon class="Arrow"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg></dui-icon>
|
|
460
545
|
</div>
|
|
461
546
|
${this.name
|
|
462
|
-
|
|
547
|
+
? html `
|
|
463
548
|
<input type="hidden" name="${this.name}" .value="${this.value}" />
|
|
464
549
|
`
|
|
465
|
-
|
|
550
|
+
: nothing}
|
|
466
551
|
`;
|
|
467
|
-
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
], DuiCombobox.prototype, "options", null);
|
|
472
|
-
__decorate([
|
|
473
|
-
property({ type: String })
|
|
474
|
-
], DuiCombobox.prototype, "value", null);
|
|
475
|
-
__decorate([
|
|
476
|
-
property({ attribute: false })
|
|
477
|
-
], DuiCombobox.prototype, "values", null);
|
|
478
|
-
__decorate([
|
|
479
|
-
property({ type: Boolean, reflect: true })
|
|
480
|
-
], DuiCombobox.prototype, "multiple", null);
|
|
481
|
-
__decorate([
|
|
482
|
-
property({ type: String })
|
|
483
|
-
], DuiCombobox.prototype, "placeholder", null);
|
|
484
|
-
__decorate([
|
|
485
|
-
property({ type: Boolean, reflect: true })
|
|
486
|
-
], DuiCombobox.prototype, "disabled", null);
|
|
487
|
-
__decorate([
|
|
488
|
-
property({ type: String })
|
|
489
|
-
], DuiCombobox.prototype, "name", null);
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
})();
|
|
555
|
+
export { DuiCombobox };
|