@krollins/blueprint 0.1.12 → 0.1.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.
Files changed (109) hide show
  1. package/README.md +9 -3
  2. package/README.npm.md +9 -3
  3. package/dist/components/accordion.js +393 -0
  4. package/dist/components/accordion.js.map +1 -0
  5. package/dist/components/alert.js +213 -0
  6. package/dist/components/alert.js.map +1 -0
  7. package/dist/components/avatar.js +237 -0
  8. package/dist/components/avatar.js.map +1 -0
  9. package/dist/components/badge/badge.d.ts.map +1 -1
  10. package/dist/components/badge.js +144 -0
  11. package/dist/components/badge.js.map +1 -0
  12. package/dist/components/breadcrumb.js +481 -0
  13. package/dist/components/breadcrumb.js.map +1 -0
  14. package/dist/components/button.js +192 -0
  15. package/dist/components/button.js.map +1 -0
  16. package/dist/components/card.js +223 -0
  17. package/dist/components/card.js.map +1 -0
  18. package/dist/components/checkbox.js +336 -0
  19. package/dist/components/checkbox.js.map +1 -0
  20. package/dist/components/code-block/code-block.d.ts +143 -0
  21. package/dist/components/code-block/code-block.d.ts.map +1 -0
  22. package/dist/components/code-block/code-block.style.d.ts +2 -0
  23. package/dist/components/code-block/code-block.style.d.ts.map +1 -0
  24. package/dist/components/code-block.js +587 -0
  25. package/dist/components/code-block.js.map +1 -0
  26. package/dist/components/color-picker/color-picker.d.ts.map +1 -1
  27. package/dist/components/color-picker.js +1660 -0
  28. package/dist/components/color-picker.js.map +1 -0
  29. package/dist/components/combobox.js +595 -0
  30. package/dist/components/combobox.js.map +1 -0
  31. package/dist/components/date-picker.js +726 -0
  32. package/dist/components/date-picker.js.map +1 -0
  33. package/dist/components/divider.js +214 -0
  34. package/dist/components/divider.js.map +1 -0
  35. package/dist/components/drawer.js +568 -0
  36. package/dist/components/drawer.js.map +1 -0
  37. package/dist/components/dropdown.js +377 -0
  38. package/dist/components/dropdown.js.map +1 -0
  39. package/dist/components/file-upload.js +669 -0
  40. package/dist/components/file-upload.js.map +1 -0
  41. package/dist/components/heading.js +161 -0
  42. package/dist/components/heading.js.map +1 -0
  43. package/dist/components/icon.js +599 -0
  44. package/dist/components/icon.js.map +1 -0
  45. package/dist/components/index.d.ts +3 -0
  46. package/dist/components/index.d.ts.map +1 -1
  47. package/dist/components/input.js +363 -0
  48. package/dist/components/input.js.map +1 -0
  49. package/dist/components/link.js +178 -0
  50. package/dist/components/link.js.map +1 -0
  51. package/dist/components/menu.js +331 -0
  52. package/dist/components/menu.js.map +1 -0
  53. package/dist/components/modal.js +317 -0
  54. package/dist/components/modal.js.map +1 -0
  55. package/dist/components/multi-select.js +642 -0
  56. package/dist/components/multi-select.js.map +1 -0
  57. package/dist/components/notification.js +429 -0
  58. package/dist/components/notification.js.map +1 -0
  59. package/dist/components/number-input.js +556 -0
  60. package/dist/components/number-input.js.map +1 -0
  61. package/dist/components/pagination.js +320 -0
  62. package/dist/components/pagination.js.map +1 -0
  63. package/dist/components/popover.js +597 -0
  64. package/dist/components/popover.js.map +1 -0
  65. package/dist/components/progress.js +219 -0
  66. package/dist/components/progress.js.map +1 -0
  67. package/dist/components/radio.js +321 -0
  68. package/dist/components/radio.js.map +1 -0
  69. package/dist/components/select.js +498 -0
  70. package/dist/components/select.js.map +1 -0
  71. package/dist/components/skeleton.js +240 -0
  72. package/dist/components/skeleton.js.map +1 -0
  73. package/dist/components/slider.js +9 -0
  74. package/dist/components/slider.js.map +1 -0
  75. package/dist/components/spinner.js +133 -0
  76. package/dist/components/spinner.js.map +1 -0
  77. package/dist/components/stepper.js +812 -0
  78. package/dist/components/stepper.js.map +1 -0
  79. package/dist/components/switch.js +379 -0
  80. package/dist/components/switch.js.map +1 -0
  81. package/dist/components/table.js +642 -0
  82. package/dist/components/table.js.map +1 -0
  83. package/dist/components/tabs.js +547 -0
  84. package/dist/components/tabs.js.map +1 -0
  85. package/dist/components/tag/tag.d.ts.map +1 -1
  86. package/dist/components/tag.js +291 -0
  87. package/dist/components/tag.js.map +1 -0
  88. package/dist/components/text.js +278 -0
  89. package/dist/components/text.js.map +1 -0
  90. package/dist/components/textarea.js +380 -0
  91. package/dist/components/textarea.js.map +1 -0
  92. package/dist/components/time-picker.js +457 -0
  93. package/dist/components/time-picker.js.map +1 -0
  94. package/dist/components/tooltip.js +239 -0
  95. package/dist/components/tooltip.js.map +1 -0
  96. package/dist/components/tree.js +582 -0
  97. package/dist/components/tree.js.map +1 -0
  98. package/dist/index.js +96 -17799
  99. package/dist/index.js.map +1 -1
  100. package/dist/shared/boolean-converter-XDGfS9LC.js +12 -0
  101. package/dist/shared/boolean-converter-XDGfS9LC.js.map +1 -0
  102. package/dist/shared/debounce-BckY30Sf.js +23 -0
  103. package/dist/shared/debounce-BckY30Sf.js.map +1 -0
  104. package/dist/shared/memoize-DlOFy-92.js +16 -0
  105. package/dist/shared/memoize-DlOFy-92.js.map +1 -0
  106. package/dist/shared/slider-BNt5TITl.js +484 -0
  107. package/dist/shared/slider-BNt5TITl.js.map +1 -0
  108. package/dist/utilities/memoize.d.ts.map +1 -1
  109. package/package.json +44 -2
@@ -0,0 +1,498 @@
1
+ import { css as v, LitElement as f, html as p } from "lit";
2
+ import { property as c, state as h, customElement as g } from "lit/decorators.js";
3
+ import { classMap as m } from "lit/directives/class-map.js";
4
+ import { ifDefined as b } from "lit/directives/if-defined.js";
5
+ import { repeat as w } from "lit/directives/repeat.js";
6
+ const x = v`
7
+ /* Base styles */
8
+ :host {
9
+ display: inline-block;
10
+ width: 100%;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ *,
15
+ *::before,
16
+ *::after {
17
+ box-sizing: border-box;
18
+ }
19
+
20
+ .select {
21
+ position: relative;
22
+ font-family: var(--bp-font-family);
23
+ }
24
+
25
+ .select-label {
26
+ display: block;
27
+ font-family: var(--bp-font-family);
28
+ font-size: var(--bp-font-size-sm);
29
+ font-weight: var(--bp-font-weight-medium);
30
+ color: var(--bp-color-text);
31
+ line-height: var(--bp-line-height-normal);
32
+ margin-bottom: var(--bp-spacing-xs);
33
+ }
34
+
35
+ .select-required {
36
+ color: var(--bp-color-error);
37
+ margin-left: var(--bp-spacing-xs);
38
+ }
39
+
40
+ .select-trigger {
41
+ display: flex;
42
+ align-items: center;
43
+ justify-content: space-between;
44
+ width: 100%;
45
+ padding: var(--bp-spacing-sm) var(--bp-spacing-md);
46
+ background-color: var(--bp-color-background);
47
+ border: var(--bp-border-width) solid var(--bp-color-border);
48
+ border-radius: var(--bp-border-radius-md);
49
+ font-size: var(--bp-font-size-base);
50
+ line-height: var(--bp-line-height-normal);
51
+ color: var(--bp-color-text);
52
+ cursor: pointer;
53
+ box-shadow: inset 0 1px 2px oklch(0 0 0 / 0.05);
54
+ transition:
55
+ border-color var(--bp-transition-fast),
56
+ box-shadow var(--bp-transition-fast);
57
+ }
58
+
59
+ .select-value {
60
+ flex: 1;
61
+ overflow: hidden;
62
+ text-overflow: ellipsis;
63
+ white-space: nowrap;
64
+ position: relative;
65
+ }
66
+
67
+ /* Hidden sizer keeps the trigger width stable across placeholder/option changes */
68
+ .select-value__sizer {
69
+ display: block;
70
+ height: 0;
71
+ overflow: hidden;
72
+ visibility: hidden;
73
+ white-space: nowrap;
74
+ }
75
+
76
+ .select-value__display {
77
+ display: block;
78
+ overflow: hidden;
79
+ text-overflow: ellipsis;
80
+ white-space: nowrap;
81
+ }
82
+
83
+ /* Placeholder state - when no value is selected */
84
+ .select-trigger:not([aria-label]) .select-value:empty {
85
+ opacity: 0.6;
86
+ }
87
+
88
+ .select-icon {
89
+ width: var(--bp-spacing-4);
90
+ height: var(--bp-spacing-4);
91
+ flex-shrink: 0;
92
+ margin-left: var(--bp-spacing-xs);
93
+ transition:
94
+ transform var(--bp-transition-base),
95
+ color var(--bp-transition-fast);
96
+ }
97
+
98
+ .select-dropdown {
99
+ position: absolute;
100
+ top: calc(100% + var(--bp-spacing-2xs));
101
+ left: 0;
102
+ right: 0;
103
+ overflow-y: auto;
104
+ background-color: var(--bp-color-background);
105
+ border: var(--bp-border-width) solid var(--bp-color-border);
106
+ border-radius: var(--bp-border-radius-md);
107
+ box-shadow: var(--bp-shadow-lg);
108
+ z-index: var(--bp-z-dropdown);
109
+ animation: slideDown 150ms ease-out;
110
+ transform-origin: top;
111
+ contain: layout style paint;
112
+ }
113
+
114
+ @keyframes slideDown {
115
+ from {
116
+ opacity: 0;
117
+ transform: translateY(calc(-1 * var(--bp-spacing-2)));
118
+ }
119
+ to {
120
+ opacity: 1;
121
+ transform: translateY(0);
122
+ }
123
+ }
124
+
125
+ .select-option {
126
+ padding: var(--bp-spacing-sm) var(--bp-spacing-md);
127
+ cursor: pointer;
128
+ transition: background-color var(--bp-transition-fast);
129
+ }
130
+
131
+ .select-option:hover:not(.select-option--focused) {
132
+ background-color: var(--bp-color-surface-elevated);
133
+ }
134
+
135
+ .select-option--focused {
136
+ background-color: var(--bp-color-surface-subdued);
137
+ outline: var(--bp-focus-width) solid var(--bp-color-primary);
138
+ outline-offset: calc(-1 * var(--bp-focus-width));
139
+ }
140
+
141
+ .select-option--selected {
142
+ background-color: color-mix(
143
+ in srgb,
144
+ var(--bp-color-primary) 8%,
145
+ transparent
146
+ );
147
+ color: var(--bp-color-primary);
148
+ font-weight: var(--bp-font-weight-semibold);
149
+ position: relative;
150
+ padding-right: var(--bp-spacing-2xl);
151
+ }
152
+
153
+ /* Checkmark for selected option */
154
+ .select-option--selected::after {
155
+ content: '✓';
156
+ position: absolute;
157
+ right: var(--bp-spacing-md);
158
+ color: var(--bp-color-primary);
159
+ font-weight: var(--bp-font-weight-bold);
160
+ font-size: var(--bp-font-size-lg);
161
+ }
162
+
163
+ /* Sizes */
164
+ .select--sm .select-trigger {
165
+ padding: var(--bp-spacing-xs) var(--bp-spacing-sm);
166
+ font-size: var(--bp-font-size-sm);
167
+ }
168
+
169
+ .select--sm .select-option {
170
+ padding: var(--bp-spacing-xs) var(--bp-spacing-sm);
171
+ font-size: var(--bp-font-size-sm);
172
+ }
173
+
174
+ .select--md .select-trigger {
175
+ padding: var(--bp-spacing-sm) var(--bp-spacing-md);
176
+ font-size: var(--bp-font-size-base);
177
+ }
178
+
179
+ .select--md .select-option {
180
+ padding: var(--bp-spacing-sm) var(--bp-spacing-md);
181
+ font-size: var(--bp-font-size-base);
182
+ }
183
+
184
+ .select--lg .select-trigger {
185
+ padding: var(--bp-spacing-md) var(--bp-spacing-lg);
186
+ font-size: var(--bp-font-size-lg);
187
+ }
188
+
189
+ .select--lg .select-option {
190
+ padding: var(--bp-spacing-md) var(--bp-spacing-lg);
191
+ font-size: var(--bp-font-size-lg);
192
+ }
193
+
194
+ /* States */
195
+ .select-trigger:hover:not(.select--disabled .select-trigger) {
196
+ border-color: var(--bp-color-primary);
197
+ }
198
+
199
+ .select-trigger:focus {
200
+ outline: none;
201
+ }
202
+
203
+ .select-trigger:focus-visible {
204
+ outline: var(--bp-focus-width) solid var(--bp-color-primary);
205
+ outline-offset: var(--bp-focus-offset);
206
+ border-color: var(--bp-color-primary);
207
+ }
208
+
209
+ .select--open .select-trigger {
210
+ border-color: var(--bp-color-primary);
211
+ }
212
+
213
+ .select--open .select-icon {
214
+ transform: rotate(180deg);
215
+ color: var(--bp-color-primary);
216
+ }
217
+
218
+ .select--disabled .select-trigger {
219
+ opacity: 0.5;
220
+ cursor: not-allowed;
221
+ background-color: var(--bp-color-surface-subdued);
222
+ }
223
+
224
+ /* iOS zoom prevention: ensure 16px minimum on touch devices */
225
+ @media (max-width: 768px) {
226
+ .select--sm .select-trigger {
227
+ font-size: 16px;
228
+ }
229
+
230
+ .select--sm .select-option {
231
+ font-size: 16px;
232
+ }
233
+ }
234
+ `;
235
+ var y = Object.defineProperty, O = Object.getOwnPropertyDescriptor, n = (t, s, o, e) => {
236
+ for (var i = e > 1 ? void 0 : e ? O(s, o) : s, r = t.length - 1, l; r >= 0; r--)
237
+ (l = t[r]) && (i = (e ? l(s, o, i) : l(i)) || i);
238
+ return e && i && y(s, o, i), i;
239
+ };
240
+ let a = class extends f {
241
+ constructor() {
242
+ super(), this.isOpen = !1, this.selectedLabel = "", this.focusedIndex = -1, this.handleSlotChange = () => {
243
+ this.updateSelectedLabel();
244
+ }, this.handleDocumentClick = (t) => {
245
+ this.contains(t.target) || (this.isOpen = !1);
246
+ }, this.handleToggle = (t) => {
247
+ t?.stopPropagation(), !this.disabled && (this.isOpen = !this.isOpen);
248
+ }, this.handleOptionClick = (t) => {
249
+ if (this.disabled) return;
250
+ const s = t.currentTarget, o = s.dataset.value || "", e = s.dataset.label || "", i = this.value;
251
+ this.value = o, this.selectedLabel = e, this.isOpen = !1, this.focusedIndex = -1, this.dispatchEvent(
252
+ new CustomEvent("bp-change", {
253
+ detail: {
254
+ value: this.value,
255
+ label: this.selectedLabel,
256
+ previousValue: i
257
+ },
258
+ bubbles: !0,
259
+ composed: !0
260
+ })
261
+ );
262
+ const r = this.shadowRoot?.querySelector('input[type="hidden"]');
263
+ r && (r.value = this.value, r.dispatchEvent(new Event("change", { bubbles: !0 })));
264
+ }, this.handleKeyDown = (t) => {
265
+ if (this.disabled) return;
266
+ const s = this.getOptions();
267
+ switch (t.key) {
268
+ case "Enter":
269
+ case " ":
270
+ if (t.preventDefault(), this.isOpen && this.focusedIndex >= 0) {
271
+ const o = s[this.focusedIndex];
272
+ if (o) {
273
+ const e = o.value || o.textContent || "", i = o.textContent || "", r = this.value;
274
+ this.value = e, this.selectedLabel = i, this.isOpen = !1, this.focusedIndex = -1, this.dispatchEvent(
275
+ new CustomEvent("bp-change", {
276
+ detail: {
277
+ value: this.value,
278
+ label: this.selectedLabel,
279
+ previousValue: r
280
+ },
281
+ bubbles: !0,
282
+ composed: !0
283
+ })
284
+ );
285
+ const l = this.shadowRoot?.querySelector(
286
+ 'input[type="hidden"]'
287
+ );
288
+ l && (l.value = this.value, l.dispatchEvent(new Event("change", { bubbles: !0 })));
289
+ }
290
+ } else
291
+ this.handleToggle();
292
+ break;
293
+ case "Escape":
294
+ this.isOpen = !1, this.focusedIndex = -1;
295
+ break;
296
+ case "ArrowDown":
297
+ t.preventDefault(), this.isOpen ? this.focusedIndex = Math.min(
298
+ this.focusedIndex + 1,
299
+ s.length - 1
300
+ ) : (this.isOpen = !0, this.focusedIndex = 0), this.scrollFocusedOptionIntoView();
301
+ break;
302
+ case "ArrowUp":
303
+ t.preventDefault(), this.isOpen ? this.focusedIndex = Math.max(this.focusedIndex - 1, 0) : (this.isOpen = !0, this.focusedIndex = s.length - 1), this.scrollFocusedOptionIntoView();
304
+ break;
305
+ case "Home":
306
+ this.isOpen && (t.preventDefault(), this.focusedIndex = 0, this.scrollFocusedOptionIntoView());
307
+ break;
308
+ case "End":
309
+ this.isOpen && (t.preventDefault(), this.focusedIndex = s.length - 1, this.scrollFocusedOptionIntoView());
310
+ break;
311
+ }
312
+ }, this.getOptionElements = () => {
313
+ const o = (this.shadowRoot?.querySelector("slot")?.assignedElements() || []).filter(
314
+ (e) => e.tagName === "OPTION"
315
+ );
316
+ return w(
317
+ o,
318
+ (e) => e.value || e.textContent || "",
319
+ (e, i) => {
320
+ const r = e.value || e.textContent || "", l = e.textContent || "", d = this.value === r, u = this.focusedIndex === i;
321
+ return d && !this.selectedLabel && (this.selectedLabel = l), p`
322
+ <div
323
+ class="select-option ${d ? "select-option--selected" : ""} ${u ? "select-option--focused" : ""}"
324
+ part="option"
325
+ role="option"
326
+ aria-selected="${d ? "true" : "false"}"
327
+ data-value="${r}"
328
+ data-label="${l}"
329
+ tabindex="-1"
330
+ @click=${this.handleOptionClick}
331
+ >
332
+ ${l}
333
+ </div>
334
+ `;
335
+ }
336
+ );
337
+ }, this.value = "", this.name = "", this.label = "", this.placeholder = "Select an option", this.disabled = !1, this.required = !1, this.size = "md";
338
+ }
339
+ connectedCallback() {
340
+ super.connectedCallback(), document.addEventListener("click", this.handleDocumentClick, {
341
+ passive: !0
342
+ }), this.updateComplete.then(() => this.updateSelectedLabel());
343
+ }
344
+ disconnectedCallback() {
345
+ super.disconnectedCallback(), document.removeEventListener("click", this.handleDocumentClick, {
346
+ passive: !0
347
+ });
348
+ }
349
+ updateSelectedLabel() {
350
+ if (!this.value) return;
351
+ (this.shadowRoot?.querySelector("slot")?.assignedElements() || []).filter(
352
+ (e) => e.tagName === "OPTION"
353
+ ).forEach((e) => {
354
+ (e.value || e.textContent) === this.value && (this.selectedLabel = e.textContent || "");
355
+ });
356
+ }
357
+ getOptions() {
358
+ return (this.shadowRoot?.querySelector("slot")?.assignedElements() || []).filter(
359
+ (e) => e.tagName === "OPTION"
360
+ ).map((e) => ({
361
+ value: e.value || e.textContent || "",
362
+ textContent: e.textContent || ""
363
+ }));
364
+ }
365
+ scrollFocusedOptionIntoView() {
366
+ this.updateComplete.then(() => {
367
+ const t = this.shadowRoot?.querySelector(
368
+ ".select-option--focused"
369
+ );
370
+ t && t.scrollIntoView({ block: "nearest", behavior: "smooth" });
371
+ });
372
+ }
373
+ /**
374
+ * Returns the longest text among all options and the placeholder.
375
+ * Used by a hidden sizer element to keep the trigger width stable.
376
+ */
377
+ getSizerText() {
378
+ const t = this.getOptions();
379
+ let s = this.placeholder || "";
380
+ for (const o of t) {
381
+ const e = o.textContent || "";
382
+ e.length > s.length && (s = e);
383
+ }
384
+ return s;
385
+ }
386
+ render() {
387
+ const t = {
388
+ select: !0,
389
+ [`select--${this.size}`]: !0,
390
+ "select--disabled": this.disabled,
391
+ "select--open": this.isOpen
392
+ }, s = this.selectedLabel || this.placeholder, o = this.label ? "select-label" : void 0;
393
+ return p`
394
+ <div class=${m(t)} part="container">
395
+ ${this.label ? p`
396
+ <label class="select-label" id="select-label" part="label">
397
+ ${this.label}
398
+ ${this.required ? p`<span class="select-required">*</span>` : ""}
399
+ </label>
400
+ ` : ""}
401
+ <!-- Hidden input for form integration (using input instead of select to avoid Firefox conflict) -->
402
+ <input
403
+ type="hidden"
404
+ name=${b(this.name || void 0)}
405
+ .value=${this.value}
406
+ />
407
+
408
+ <!-- Slot for option elements (not rendered, just for content projection) -->
409
+ <slot
410
+ @slotchange=${this.handleSlotChange}
411
+ style="display: none;"
412
+ ></slot>
413
+
414
+ <!-- Custom select trigger -->
415
+ <div
416
+ class="select-trigger"
417
+ part="trigger"
418
+ role="combobox"
419
+ aria-expanded="${this.isOpen ? "true" : "false"}"
420
+ aria-haspopup="listbox"
421
+ aria-labelledby="${b(o)}"
422
+ aria-disabled="${this.disabled ? "true" : "false"}"
423
+ aria-required="${this.required ? "true" : "false"}"
424
+ tabindex="${this.disabled ? "-1" : "0"}"
425
+ @click=${this.handleToggle}
426
+ @keydown=${this.handleKeyDown}
427
+ >
428
+ <span class="select-value" part="display">
429
+ <span class="select-value__sizer" aria-hidden="true"
430
+ >${this.getSizerText()}</span
431
+ >
432
+ <span class="select-value__display">${s}</span>
433
+ </span>
434
+ <svg
435
+ class="select-icon"
436
+ part="icon"
437
+ viewBox="0 0 16 16"
438
+ fill="none"
439
+ xmlns="http://www.w3.org/2000/svg"
440
+ >
441
+ <path
442
+ d="M4 6L8 10L12 6"
443
+ stroke="currentColor"
444
+ stroke-width="2"
445
+ stroke-linecap="round"
446
+ stroke-linejoin="round"
447
+ />
448
+ </svg>
449
+ </div>
450
+
451
+ <!-- Dropdown menu -->
452
+ ${this.isOpen ? p`
453
+ <div class="select-dropdown" part="dropdown" role="listbox">
454
+ ${this.getOptionElements()}
455
+ </div>
456
+ ` : null}
457
+ </div>
458
+ `;
459
+ }
460
+ };
461
+ a.styles = [x];
462
+ n([
463
+ c({ type: String, reflect: !0 })
464
+ ], a.prototype, "value", 2);
465
+ n([
466
+ c({ type: String })
467
+ ], a.prototype, "name", 2);
468
+ n([
469
+ c({ type: String, reflect: !0 })
470
+ ], a.prototype, "label", 2);
471
+ n([
472
+ c({ type: String })
473
+ ], a.prototype, "placeholder", 2);
474
+ n([
475
+ c({ type: Boolean, reflect: !0 })
476
+ ], a.prototype, "disabled", 2);
477
+ n([
478
+ c({ type: Boolean, reflect: !0 })
479
+ ], a.prototype, "required", 2);
480
+ n([
481
+ c({ type: String, reflect: !0 })
482
+ ], a.prototype, "size", 2);
483
+ n([
484
+ h()
485
+ ], a.prototype, "isOpen", 2);
486
+ n([
487
+ h()
488
+ ], a.prototype, "selectedLabel", 2);
489
+ n([
490
+ h()
491
+ ], a.prototype, "focusedIndex", 2);
492
+ a = n([
493
+ g("bp-select")
494
+ ], a);
495
+ export {
496
+ a as BpSelect
497
+ };
498
+ //# sourceMappingURL=select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.js","sources":["../../source/components/select/select.style.ts","../../source/components/select/select.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const selectStyles = css`\n /* Base styles */\n :host {\n display: inline-block;\n width: 100%;\n box-sizing: border-box;\n }\n\n *,\n *::before,\n *::after {\n box-sizing: border-box;\n }\n\n .select {\n position: relative;\n font-family: var(--bp-font-family);\n }\n\n .select-label {\n display: block;\n font-family: var(--bp-font-family);\n font-size: var(--bp-font-size-sm);\n font-weight: var(--bp-font-weight-medium);\n color: var(--bp-color-text);\n line-height: var(--bp-line-height-normal);\n margin-bottom: var(--bp-spacing-xs);\n }\n\n .select-required {\n color: var(--bp-color-error);\n margin-left: var(--bp-spacing-xs);\n }\n\n .select-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n padding: var(--bp-spacing-sm) var(--bp-spacing-md);\n background-color: var(--bp-color-background);\n border: var(--bp-border-width) solid var(--bp-color-border);\n border-radius: var(--bp-border-radius-md);\n font-size: var(--bp-font-size-base);\n line-height: var(--bp-line-height-normal);\n color: var(--bp-color-text);\n cursor: pointer;\n box-shadow: inset 0 1px 2px oklch(0 0 0 / 0.05);\n transition:\n border-color var(--bp-transition-fast),\n box-shadow var(--bp-transition-fast);\n }\n\n .select-value {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n position: relative;\n }\n\n /* Hidden sizer keeps the trigger width stable across placeholder/option changes */\n .select-value__sizer {\n display: block;\n height: 0;\n overflow: hidden;\n visibility: hidden;\n white-space: nowrap;\n }\n\n .select-value__display {\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n /* Placeholder state - when no value is selected */\n .select-trigger:not([aria-label]) .select-value:empty {\n opacity: 0.6;\n }\n\n .select-icon {\n width: var(--bp-spacing-4);\n height: var(--bp-spacing-4);\n flex-shrink: 0;\n margin-left: var(--bp-spacing-xs);\n transition:\n transform var(--bp-transition-base),\n color var(--bp-transition-fast);\n }\n\n .select-dropdown {\n position: absolute;\n top: calc(100% + var(--bp-spacing-2xs));\n left: 0;\n right: 0;\n overflow-y: auto;\n background-color: var(--bp-color-background);\n border: var(--bp-border-width) solid var(--bp-color-border);\n border-radius: var(--bp-border-radius-md);\n box-shadow: var(--bp-shadow-lg);\n z-index: var(--bp-z-dropdown);\n animation: slideDown 150ms ease-out;\n transform-origin: top;\n contain: layout style paint;\n }\n\n @keyframes slideDown {\n from {\n opacity: 0;\n transform: translateY(calc(-1 * var(--bp-spacing-2)));\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n .select-option {\n padding: var(--bp-spacing-sm) var(--bp-spacing-md);\n cursor: pointer;\n transition: background-color var(--bp-transition-fast);\n }\n\n .select-option:hover:not(.select-option--focused) {\n background-color: var(--bp-color-surface-elevated);\n }\n\n .select-option--focused {\n background-color: var(--bp-color-surface-subdued);\n outline: var(--bp-focus-width) solid var(--bp-color-primary);\n outline-offset: calc(-1 * var(--bp-focus-width));\n }\n\n .select-option--selected {\n background-color: color-mix(\n in srgb,\n var(--bp-color-primary) 8%,\n transparent\n );\n color: var(--bp-color-primary);\n font-weight: var(--bp-font-weight-semibold);\n position: relative;\n padding-right: var(--bp-spacing-2xl);\n }\n\n /* Checkmark for selected option */\n .select-option--selected::after {\n content: '✓';\n position: absolute;\n right: var(--bp-spacing-md);\n color: var(--bp-color-primary);\n font-weight: var(--bp-font-weight-bold);\n font-size: var(--bp-font-size-lg);\n }\n\n /* Sizes */\n .select--sm .select-trigger {\n padding: var(--bp-spacing-xs) var(--bp-spacing-sm);\n font-size: var(--bp-font-size-sm);\n }\n\n .select--sm .select-option {\n padding: var(--bp-spacing-xs) var(--bp-spacing-sm);\n font-size: var(--bp-font-size-sm);\n }\n\n .select--md .select-trigger {\n padding: var(--bp-spacing-sm) var(--bp-spacing-md);\n font-size: var(--bp-font-size-base);\n }\n\n .select--md .select-option {\n padding: var(--bp-spacing-sm) var(--bp-spacing-md);\n font-size: var(--bp-font-size-base);\n }\n\n .select--lg .select-trigger {\n padding: var(--bp-spacing-md) var(--bp-spacing-lg);\n font-size: var(--bp-font-size-lg);\n }\n\n .select--lg .select-option {\n padding: var(--bp-spacing-md) var(--bp-spacing-lg);\n font-size: var(--bp-font-size-lg);\n }\n\n /* States */\n .select-trigger:hover:not(.select--disabled .select-trigger) {\n border-color: var(--bp-color-primary);\n }\n\n .select-trigger:focus {\n outline: none;\n }\n\n .select-trigger:focus-visible {\n outline: var(--bp-focus-width) solid var(--bp-color-primary);\n outline-offset: var(--bp-focus-offset);\n border-color: var(--bp-color-primary);\n }\n\n .select--open .select-trigger {\n border-color: var(--bp-color-primary);\n }\n\n .select--open .select-icon {\n transform: rotate(180deg);\n color: var(--bp-color-primary);\n }\n\n .select--disabled .select-trigger {\n opacity: 0.5;\n cursor: not-allowed;\n background-color: var(--bp-color-surface-subdued);\n }\n\n /* iOS zoom prevention: ensure 16px minimum on touch devices */\n @media (max-width: 768px) {\n .select--sm .select-trigger {\n font-size: 16px;\n }\n\n .select--sm .select-option {\n font-size: 16px;\n }\n }\n`;\n","import { LitElement, html } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { selectStyles } from './select.style.js';\n\nexport type SelectSize = 'sm' | 'md' | 'lg';\n\n@customElement('bp-select')\nexport class BpSelect extends LitElement {\n /** The current value of the select */\n @property({ type: String, reflect: true }) declare value: string;\n\n /** Name attribute for form submission */\n @property({ type: String }) declare name: string;\n\n /** Visible label text displayed above the select */\n @property({ type: String, reflect: true }) declare label: string;\n\n /** Placeholder text when no value is selected */\n @property({ type: String }) declare placeholder: string;\n\n /** Whether the select is disabled */\n @property({ type: Boolean, reflect: true }) declare disabled: boolean;\n\n /** Whether the select is required */\n @property({ type: Boolean, reflect: true }) declare required: boolean;\n\n /** Size variant of the select */\n @property({ type: String, reflect: true }) declare size: SelectSize;\n\n /** Whether the dropdown is currently open */\n @state() private isOpen = false;\n\n /** Label for the selected option */\n @state() private selectedLabel = '';\n\n /** Index of the focused option for keyboard navigation */\n @state() private focusedIndex = -1;\n\n static styles = [selectStyles];\n\n constructor() {\n super();\n this.value = '';\n this.name = '';\n this.label = '';\n this.placeholder = 'Select an option';\n this.disabled = false;\n this.required = false;\n this.size = 'md';\n }\n\n connectedCallback() {\n super.connectedCallback();\n document.addEventListener('click', this.handleDocumentClick, {\n passive: true,\n });\n // Update selected label on initial load\n this.updateComplete.then(() => this.updateSelectedLabel());\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n document.removeEventListener('click', this.handleDocumentClick, {\n passive: true,\n } as EventListenerOptions);\n }\n\n private handleSlotChange = () => {\n this.updateSelectedLabel();\n };\n\n private updateSelectedLabel() {\n if (!this.value) return;\n\n const slot = this.shadowRoot?.querySelector('slot');\n const assignedElements = slot?.assignedElements() || [];\n const options = assignedElements.filter(\n (el): el is globalThis.HTMLOptionElement => el.tagName === 'OPTION'\n );\n\n options.forEach((option) => {\n if ((option.value || option.textContent) === this.value) {\n this.selectedLabel = option.textContent || '';\n }\n });\n }\n\n private handleDocumentClick = (event: MouseEvent) => {\n if (!this.contains(event.target as unknown as globalThis.Node)) {\n this.isOpen = false;\n }\n };\n\n private handleToggle = (event?: Event) => {\n event?.stopPropagation();\n if (this.disabled) return;\n this.isOpen = !this.isOpen;\n };\n\n private handleOptionClick = (event: Event) => {\n if (this.disabled) return;\n\n const target = event.currentTarget as HTMLElement;\n const optionValue = target.dataset.value || '';\n const optionLabel = target.dataset.label || '';\n\n const previousValue = this.value;\n this.value = optionValue;\n this.selectedLabel = optionLabel;\n this.isOpen = false;\n this.focusedIndex = -1;\n\n // Dispatch change event\n this.dispatchEvent(\n new CustomEvent('bp-change', {\n detail: {\n value: this.value,\n label: this.selectedLabel,\n previousValue,\n },\n bubbles: true,\n composed: true,\n })\n );\n\n // Update the underlying hidden input for form integration\n const hiddenInput = this.shadowRoot?.querySelector('input[type=\"hidden\"]');\n if (hiddenInput) {\n (hiddenInput as HTMLInputElement).value = this.value;\n hiddenInput.dispatchEvent(new Event('change', { bubbles: true }));\n }\n };\n\n private handleKeyDown = (event: globalThis.KeyboardEvent) => {\n if (this.disabled) return;\n\n const options = this.getOptions();\n\n switch (event.key) {\n case 'Enter':\n case ' ':\n event.preventDefault();\n if (this.isOpen && this.focusedIndex >= 0) {\n // Select the focused option\n const option = options[this.focusedIndex];\n if (option) {\n const optionValue = option.value || option.textContent || '';\n const optionLabel = option.textContent || '';\n const previousValue = this.value;\n this.value = optionValue;\n this.selectedLabel = optionLabel;\n this.isOpen = false;\n this.focusedIndex = -1;\n\n this.dispatchEvent(\n new CustomEvent('bp-change', {\n detail: {\n value: this.value,\n label: this.selectedLabel,\n previousValue,\n },\n bubbles: true,\n composed: true,\n })\n );\n\n const hiddenInput = this.shadowRoot?.querySelector(\n 'input[type=\"hidden\"]'\n );\n if (hiddenInput) {\n (hiddenInput as HTMLInputElement).value = this.value;\n hiddenInput.dispatchEvent(new Event('change', { bubbles: true }));\n }\n }\n } else {\n this.handleToggle();\n }\n break;\n case 'Escape':\n this.isOpen = false;\n this.focusedIndex = -1;\n break;\n case 'ArrowDown':\n event.preventDefault();\n if (!this.isOpen) {\n this.isOpen = true;\n this.focusedIndex = 0;\n } else {\n this.focusedIndex = Math.min(\n this.focusedIndex + 1,\n options.length - 1\n );\n }\n this.scrollFocusedOptionIntoView();\n break;\n case 'ArrowUp':\n event.preventDefault();\n if (!this.isOpen) {\n this.isOpen = true;\n this.focusedIndex = options.length - 1;\n } else {\n this.focusedIndex = Math.max(this.focusedIndex - 1, 0);\n }\n this.scrollFocusedOptionIntoView();\n break;\n case 'Home':\n if (this.isOpen) {\n event.preventDefault();\n this.focusedIndex = 0;\n this.scrollFocusedOptionIntoView();\n }\n break;\n case 'End':\n if (this.isOpen) {\n event.preventDefault();\n this.focusedIndex = options.length - 1;\n this.scrollFocusedOptionIntoView();\n }\n break;\n }\n };\n\n private getOptions(): Array<{ value: string; textContent: string }> {\n const slot = this.shadowRoot?.querySelector('slot');\n const assignedElements = slot?.assignedElements() || [];\n const options = assignedElements.filter(\n (el): el is globalThis.HTMLOptionElement => el.tagName === 'OPTION'\n );\n return options.map((option) => ({\n value: option.value || option.textContent || '',\n textContent: option.textContent || '',\n }));\n }\n\n private scrollFocusedOptionIntoView() {\n this.updateComplete.then(() => {\n const focusedOption = this.shadowRoot?.querySelector(\n '.select-option--focused'\n ) as HTMLElement;\n if (focusedOption) {\n focusedOption.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\n }\n });\n }\n\n /**\n * Returns the longest text among all options and the placeholder.\n * Used by a hidden sizer element to keep the trigger width stable.\n */\n private getSizerText(): string {\n const options = this.getOptions();\n let longestText = this.placeholder || '';\n\n for (const option of options) {\n const text = option.textContent || '';\n if (text.length > longestText.length) {\n longestText = text;\n }\n }\n\n return longestText;\n }\n\n private getOptionElements = () => {\n const slot = this.shadowRoot?.querySelector('slot');\n const assignedElements = slot?.assignedElements() || [];\n const options = assignedElements.filter(\n (el): el is globalThis.HTMLOptionElement => el.tagName === 'OPTION'\n );\n\n return repeat(\n options,\n (option) => option.value || option.textContent || '',\n (option, index) => {\n const optionValue = option.value || option.textContent || '';\n const optionLabel = option.textContent || '';\n const isSelected = this.value === optionValue;\n const isFocused = this.focusedIndex === index;\n\n if (isSelected && !this.selectedLabel) {\n this.selectedLabel = optionLabel;\n }\n\n return html`\n <div\n class=\"select-option ${isSelected\n ? 'select-option--selected'\n : ''} ${isFocused ? 'select-option--focused' : ''}\"\n part=\"option\"\n role=\"option\"\n aria-selected=\"${isSelected ? 'true' : 'false'}\"\n data-value=\"${optionValue}\"\n data-label=\"${optionLabel}\"\n tabindex=\"-1\"\n @click=${this.handleOptionClick}\n >\n ${optionLabel}\n </div>\n `;\n }\n );\n };\n\n render() {\n const selectClasses = {\n select: true,\n [`select--${this.size}`]: true,\n 'select--disabled': this.disabled,\n 'select--open': this.isOpen,\n };\n\n const displayLabel = this.selectedLabel || this.placeholder;\n\n const labelId = this.label ? 'select-label' : undefined;\n\n return html`\n <div class=${classMap(selectClasses)} part=\"container\">\n ${this.label\n ? html`\n <label class=\"select-label\" id=\"select-label\" part=\"label\">\n ${this.label}\n ${this.required\n ? html`<span class=\"select-required\">*</span>`\n : ''}\n </label>\n `\n : ''}\n <!-- Hidden input for form integration (using input instead of select to avoid Firefox conflict) -->\n <input\n type=\"hidden\"\n name=${ifDefined(this.name || undefined)}\n .value=${this.value}\n />\n\n <!-- Slot for option elements (not rendered, just for content projection) -->\n <slot\n @slotchange=${this.handleSlotChange}\n style=\"display: none;\"\n ></slot>\n\n <!-- Custom select trigger -->\n <div\n class=\"select-trigger\"\n part=\"trigger\"\n role=\"combobox\"\n aria-expanded=\"${this.isOpen ? 'true' : 'false'}\"\n aria-haspopup=\"listbox\"\n aria-labelledby=\"${ifDefined(labelId)}\"\n aria-disabled=\"${this.disabled ? 'true' : 'false'}\"\n aria-required=\"${this.required ? 'true' : 'false'}\"\n tabindex=\"${this.disabled ? '-1' : '0'}\"\n @click=${this.handleToggle}\n @keydown=${this.handleKeyDown}\n >\n <span class=\"select-value\" part=\"display\">\n <span class=\"select-value__sizer\" aria-hidden=\"true\"\n >${this.getSizerText()}</span\n >\n <span class=\"select-value__display\">${displayLabel}</span>\n </span>\n <svg\n class=\"select-icon\"\n part=\"icon\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M4 6L8 10L12 6\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </div>\n\n <!-- Dropdown menu -->\n ${this.isOpen\n ? html`\n <div class=\"select-dropdown\" part=\"dropdown\" role=\"listbox\">\n ${this.getOptionElements()}\n </div>\n `\n : null}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'bp-select': BpSelect;\n }\n}\n"],"names":["selectStyles","css","BpSelect","LitElement","event","target","optionValue","optionLabel","previousValue","hiddenInput","options","option","el","repeat","index","isSelected","isFocused","html","focusedOption","longestText","text","selectClasses","displayLabel","labelId","classMap","ifDefined","__decorateClass","property","state","customElement"],"mappings":";;;;;AAEO,MAAMA,IAAeC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;;;;ACQrB,IAAMC,IAAN,cAAuBC,EAAW;AAAA,EAiCvC,cAAc;AACZ,UAAA,GAXO,KAAQ,SAAS,IAGjB,KAAQ,gBAAgB,IAGxB,KAAQ,eAAe,IA+BhC,KAAQ,mBAAmB,MAAM;AAC/B,WAAK,oBAAA;AAAA,IACP,GAkBA,KAAQ,sBAAsB,CAACC,MAAsB;AACnD,MAAK,KAAK,SAASA,EAAM,MAAoC,MAC3D,KAAK,SAAS;AAAA,IAElB,GAEA,KAAQ,eAAe,CAACA,MAAkB;AAExC,MADAA,GAAO,gBAAA,GACH,MAAK,aACT,KAAK,SAAS,CAAC,KAAK;AAAA,IACtB,GAEA,KAAQ,oBAAoB,CAACA,MAAiB;AAC5C,UAAI,KAAK,SAAU;AAEnB,YAAMC,IAASD,EAAM,eACfE,IAAcD,EAAO,QAAQ,SAAS,IACtCE,IAAcF,EAAO,QAAQ,SAAS,IAEtCG,IAAgB,KAAK;AAC3B,WAAK,QAAQF,GACb,KAAK,gBAAgBC,GACrB,KAAK,SAAS,IACd,KAAK,eAAe,IAGpB,KAAK;AAAA,QACH,IAAI,YAAY,aAAa;AAAA,UAC3B,QAAQ;AAAA,YACN,OAAO,KAAK;AAAA,YACZ,OAAO,KAAK;AAAA,YACZ,eAAAC;AAAA,UAAA;AAAA,UAEF,SAAS;AAAA,UACT,UAAU;AAAA,QAAA,CACX;AAAA,MAAA;AAIH,YAAMC,IAAc,KAAK,YAAY,cAAc,sBAAsB;AACzE,MAAIA,MACDA,EAAiC,QAAQ,KAAK,OAC/CA,EAAY,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,GAAA,CAAM,CAAC;AAAA,IAEpE,GAEA,KAAQ,gBAAgB,CAACL,MAAoC;AAC3D,UAAI,KAAK,SAAU;AAEnB,YAAMM,IAAU,KAAK,WAAA;AAErB,cAAQN,EAAM,KAAA;AAAA,QACZ,KAAK;AAAA,QACL,KAAK;AAEH,cADAA,EAAM,eAAA,GACF,KAAK,UAAU,KAAK,gBAAgB,GAAG;AAEzC,kBAAMO,IAASD,EAAQ,KAAK,YAAY;AACxC,gBAAIC,GAAQ;AACV,oBAAML,IAAcK,EAAO,SAASA,EAAO,eAAe,IACpDJ,IAAcI,EAAO,eAAe,IACpCH,IAAgB,KAAK;AAC3B,mBAAK,QAAQF,GACb,KAAK,gBAAgBC,GACrB,KAAK,SAAS,IACd,KAAK,eAAe,IAEpB,KAAK;AAAA,gBACH,IAAI,YAAY,aAAa;AAAA,kBAC3B,QAAQ;AAAA,oBACN,OAAO,KAAK;AAAA,oBACZ,OAAO,KAAK;AAAA,oBACZ,eAAAC;AAAA,kBAAA;AAAA,kBAEF,SAAS;AAAA,kBACT,UAAU;AAAA,gBAAA,CACX;AAAA,cAAA;AAGH,oBAAMC,IAAc,KAAK,YAAY;AAAA,gBACnC;AAAA,cAAA;AAEF,cAAIA,MACDA,EAAiC,QAAQ,KAAK,OAC/CA,EAAY,cAAc,IAAI,MAAM,UAAU,EAAE,SAAS,GAAA,CAAM,CAAC;AAAA,YAEpE;AAAA,UACF;AACE,iBAAK,aAAA;AAEP;AAAA,QACF,KAAK;AACH,eAAK,SAAS,IACd,KAAK,eAAe;AACpB;AAAA,QACF,KAAK;AACH,UAAAL,EAAM,eAAA,GACD,KAAK,SAIR,KAAK,eAAe,KAAK;AAAA,YACvB,KAAK,eAAe;AAAA,YACpBM,EAAQ,SAAS;AAAA,UAAA,KALnB,KAAK,SAAS,IACd,KAAK,eAAe,IAOtB,KAAK,4BAAA;AACL;AAAA,QACF,KAAK;AACH,UAAAN,EAAM,eAAA,GACD,KAAK,SAIR,KAAK,eAAe,KAAK,IAAI,KAAK,eAAe,GAAG,CAAC,KAHrD,KAAK,SAAS,IACd,KAAK,eAAeM,EAAQ,SAAS,IAIvC,KAAK,4BAAA;AACL;AAAA,QACF,KAAK;AACH,UAAI,KAAK,WACPN,EAAM,eAAA,GACN,KAAK,eAAe,GACpB,KAAK,4BAAA;AAEP;AAAA,QACF,KAAK;AACH,UAAI,KAAK,WACPA,EAAM,eAAA,GACN,KAAK,eAAeM,EAAQ,SAAS,GACrC,KAAK,4BAAA;AAEP;AAAA,MAAA;AAAA,IAEN,GA2CA,KAAQ,oBAAoB,MAAM;AAGhC,YAAMA,KAFO,KAAK,YAAY,cAAc,MAAM,GACnB,iBAAA,KAAsB,CAAA,GACpB;AAAA,QAC/B,CAACE,MAA2CA,EAAG,YAAY;AAAA,MAAA;AAG7D,aAAOC;AAAA,QACLH;AAAA,QACA,CAACC,MAAWA,EAAO,SAASA,EAAO,eAAe;AAAA,QAClD,CAACA,GAAQG,MAAU;AACjB,gBAAMR,IAAcK,EAAO,SAASA,EAAO,eAAe,IACpDJ,IAAcI,EAAO,eAAe,IACpCI,IAAa,KAAK,UAAUT,GAC5BU,IAAY,KAAK,iBAAiBF;AAExC,iBAAIC,KAAc,CAAC,KAAK,kBACtB,KAAK,gBAAgBR,IAGhBU;AAAA;AAAA,mCAEoBF,IACnB,4BACA,EAAE,IAAIC,IAAY,2BAA2B,EAAE;AAAA;AAAA;AAAA,6BAGlCD,IAAa,SAAS,OAAO;AAAA,0BAChCT,CAAW;AAAA,0BACXC,CAAW;AAAA;AAAA,qBAEhB,KAAK,iBAAiB;AAAA;AAAA,cAE7BA,CAAW;AAAA;AAAA;AAAA,QAGnB;AAAA,MAAA;AAAA,IAEJ,GAnQE,KAAK,QAAQ,IACb,KAAK,OAAO,IACZ,KAAK,QAAQ,IACb,KAAK,cAAc,oBACnB,KAAK,WAAW,IAChB,KAAK,WAAW,IAChB,KAAK,OAAO;AAAA,EACd;AAAA,EAEA,oBAAoB;AAClB,UAAM,kBAAA,GACN,SAAS,iBAAiB,SAAS,KAAK,qBAAqB;AAAA,MAC3D,SAAS;AAAA,IAAA,CACV,GAED,KAAK,eAAe,KAAK,MAAM,KAAK,qBAAqB;AAAA,EAC3D;AAAA,EAEA,uBAAuB;AACrB,UAAM,qBAAA,GACN,SAAS,oBAAoB,SAAS,KAAK,qBAAqB;AAAA,MAC9D,SAAS;AAAA,IAAA,CACc;AAAA,EAC3B;AAAA,EAMQ,sBAAsB;AAC5B,QAAI,CAAC,KAAK,MAAO;AAQjB,KANa,KAAK,YAAY,cAAc,MAAM,GACnB,iBAAA,KAAsB,CAAA,GACpB;AAAA,MAC/B,CAACK,MAA2CA,EAAG,YAAY;AAAA,IAAA,EAGrD,QAAQ,CAACD,MAAW;AAC1B,OAAKA,EAAO,SAASA,EAAO,iBAAiB,KAAK,UAChD,KAAK,gBAAgBA,EAAO,eAAe;AAAA,IAE/C,CAAC;AAAA,EACH;AAAA,EAyIQ,aAA4D;AAMlE,YALa,KAAK,YAAY,cAAc,MAAM,GACnB,iBAAA,KAAsB,CAAA,GACpB;AAAA,MAC/B,CAACC,MAA2CA,EAAG,YAAY;AAAA,IAAA,EAE9C,IAAI,CAACD,OAAY;AAAA,MAC9B,OAAOA,EAAO,SAASA,EAAO,eAAe;AAAA,MAC7C,aAAaA,EAAO,eAAe;AAAA,IAAA,EACnC;AAAA,EACJ;AAAA,EAEQ,8BAA8B;AACpC,SAAK,eAAe,KAAK,MAAM;AAC7B,YAAMO,IAAgB,KAAK,YAAY;AAAA,QACrC;AAAA,MAAA;AAEF,MAAIA,KACFA,EAAc,eAAe,EAAE,OAAO,WAAW,UAAU,UAAU;AAAA,IAEzE,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,eAAuB;AAC7B,UAAMR,IAAU,KAAK,WAAA;AACrB,QAAIS,IAAc,KAAK,eAAe;AAEtC,eAAWR,KAAUD,GAAS;AAC5B,YAAMU,IAAOT,EAAO,eAAe;AACnC,MAAIS,EAAK,SAASD,EAAY,WAC5BA,IAAcC;AAAA,IAElB;AAEA,WAAOD;AAAA,EACT;AAAA,EA0CA,SAAS;AACP,UAAME,IAAgB;AAAA,MACpB,QAAQ;AAAA,MACR,CAAC,WAAW,KAAK,IAAI,EAAE,GAAG;AAAA,MAC1B,oBAAoB,KAAK;AAAA,MACzB,gBAAgB,KAAK;AAAA,IAAA,GAGjBC,IAAe,KAAK,iBAAiB,KAAK,aAE1CC,IAAU,KAAK,QAAQ,iBAAiB;AAE9C,WAAON;AAAA,mBACQO,EAASH,CAAa,CAAC;AAAA,UAChC,KAAK,QACHJ;AAAA;AAAA,kBAEM,KAAK,KAAK;AAAA,kBACV,KAAK,WACHA,4CACA,EAAE;AAAA;AAAA,gBAGV,EAAE;AAAA;AAAA;AAAA;AAAA,iBAIGQ,EAAU,KAAK,QAAQ,MAAS,CAAC;AAAA,mBAC/B,KAAK,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,wBAKL,KAAK,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,2BASlB,KAAK,SAAS,SAAS,OAAO;AAAA;AAAA,6BAE5BA,EAAUF,CAAO,CAAC;AAAA,2BACpB,KAAK,WAAW,SAAS,OAAO;AAAA,2BAChC,KAAK,WAAW,SAAS,OAAO;AAAA,sBACrC,KAAK,WAAW,OAAO,GAAG;AAAA,mBAC7B,KAAK,YAAY;AAAA,qBACf,KAAK,aAAa;AAAA;AAAA;AAAA;AAAA,iBAItB,KAAK,cAAc;AAAA;AAAA,kDAEcD,CAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAoBpD,KAAK,SACHL;AAAA;AAAA,kBAEM,KAAK,mBAAmB;AAAA;AAAA,gBAG9B,IAAI;AAAA;AAAA;AAAA,EAGd;AACF;AA7Xaf,EA+BJ,SAAS,CAACF,CAAY;AA7BsB0B,EAAA;AAAA,EAAlDC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAF9BzB,EAEwC,WAAA,SAAA,CAAA;AAGfwB,EAAA;AAAA,EAAnCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GALfzB,EAKyB,WAAA,QAAA,CAAA;AAGewB,EAAA;AAAA,EAAlDC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GAR9BzB,EAQwC,WAAA,SAAA,CAAA;AAGfwB,EAAA;AAAA,EAAnCC,EAAS,EAAE,MAAM,OAAA,CAAQ;AAAA,GAXfzB,EAWyB,WAAA,eAAA,CAAA;AAGgBwB,EAAA;AAAA,EAAnDC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAd/BzB,EAcyC,WAAA,YAAA,CAAA;AAGAwB,EAAA;AAAA,EAAnDC,EAAS,EAAE,MAAM,SAAS,SAAS,IAAM;AAAA,GAjB/BzB,EAiByC,WAAA,YAAA,CAAA;AAGDwB,EAAA;AAAA,EAAlDC,EAAS,EAAE,MAAM,QAAQ,SAAS,IAAM;AAAA,GApB9BzB,EAoBwC,WAAA,QAAA,CAAA;AAGlCwB,EAAA;AAAA,EAAhBE,EAAA;AAAM,GAvBI1B,EAuBM,WAAA,UAAA,CAAA;AAGAwB,EAAA;AAAA,EAAhBE,EAAA;AAAM,GA1BI1B,EA0BM,WAAA,iBAAA,CAAA;AAGAwB,EAAA;AAAA,EAAhBE,EAAA;AAAM,GA7BI1B,EA6BM,WAAA,gBAAA,CAAA;AA7BNA,IAANwB,EAAA;AAAA,EADNG,EAAc,WAAW;AAAA,GACb3B,CAAA;"}