@krollins/blueprint 0.1.11 → 0.1.13

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 (95) hide show
  1. package/dist/components/accordion.js +393 -0
  2. package/dist/components/accordion.js.map +1 -0
  3. package/dist/components/alert.js +213 -0
  4. package/dist/components/alert.js.map +1 -0
  5. package/dist/components/avatar.js +237 -0
  6. package/dist/components/avatar.js.map +1 -0
  7. package/dist/components/badge.js +144 -0
  8. package/dist/components/badge.js.map +1 -0
  9. package/dist/components/breadcrumb.js +481 -0
  10. package/dist/components/breadcrumb.js.map +1 -0
  11. package/dist/components/button.js +192 -0
  12. package/dist/components/button.js.map +1 -0
  13. package/dist/components/card.js +223 -0
  14. package/dist/components/card.js.map +1 -0
  15. package/dist/components/checkbox.js +337 -0
  16. package/dist/components/checkbox.js.map +1 -0
  17. package/dist/components/color-picker.js +1660 -0
  18. package/dist/components/color-picker.js.map +1 -0
  19. package/dist/components/combobox.js +595 -0
  20. package/dist/components/combobox.js.map +1 -0
  21. package/dist/components/date-picker.js +726 -0
  22. package/dist/components/date-picker.js.map +1 -0
  23. package/dist/components/divider.js +214 -0
  24. package/dist/components/divider.js.map +1 -0
  25. package/dist/components/drawer.js +568 -0
  26. package/dist/components/drawer.js.map +1 -0
  27. package/dist/components/dropdown.js +377 -0
  28. package/dist/components/dropdown.js.map +1 -0
  29. package/dist/components/file-upload.js +669 -0
  30. package/dist/components/file-upload.js.map +1 -0
  31. package/dist/components/heading.js +161 -0
  32. package/dist/components/heading.js.map +1 -0
  33. package/dist/components/icon.js +599 -0
  34. package/dist/components/icon.js.map +1 -0
  35. package/dist/components/input.js +363 -0
  36. package/dist/components/input.js.map +1 -0
  37. package/dist/components/link.js +178 -0
  38. package/dist/components/link.js.map +1 -0
  39. package/dist/components/menu.js +331 -0
  40. package/dist/components/menu.js.map +1 -0
  41. package/dist/components/modal.js +317 -0
  42. package/dist/components/modal.js.map +1 -0
  43. package/dist/components/multi-select.js +642 -0
  44. package/dist/components/multi-select.js.map +1 -0
  45. package/dist/components/notification.js +429 -0
  46. package/dist/components/notification.js.map +1 -0
  47. package/dist/components/number-input.js +556 -0
  48. package/dist/components/number-input.js.map +1 -0
  49. package/dist/components/pagination.js +320 -0
  50. package/dist/components/pagination.js.map +1 -0
  51. package/dist/components/popover.js +597 -0
  52. package/dist/components/popover.js.map +1 -0
  53. package/dist/components/progress.js +219 -0
  54. package/dist/components/progress.js.map +1 -0
  55. package/dist/components/radio.js +321 -0
  56. package/dist/components/radio.js.map +1 -0
  57. package/dist/components/select.js +498 -0
  58. package/dist/components/select.js.map +1 -0
  59. package/dist/components/skeleton.js +240 -0
  60. package/dist/components/skeleton.js.map +1 -0
  61. package/dist/components/slider.js +9 -0
  62. package/dist/components/slider.js.map +1 -0
  63. package/dist/components/spinner.js +133 -0
  64. package/dist/components/spinner.js.map +1 -0
  65. package/dist/components/stepper.js +812 -0
  66. package/dist/components/stepper.js.map +1 -0
  67. package/dist/components/switch.js +380 -0
  68. package/dist/components/switch.js.map +1 -0
  69. package/dist/components/table.js +642 -0
  70. package/dist/components/table.js.map +1 -0
  71. package/dist/components/tabs.js +547 -0
  72. package/dist/components/tabs.js.map +1 -0
  73. package/dist/components/tag.js +291 -0
  74. package/dist/components/tag.js.map +1 -0
  75. package/dist/components/text.js +278 -0
  76. package/dist/components/text.js.map +1 -0
  77. package/dist/components/textarea.js +380 -0
  78. package/dist/components/textarea.js.map +1 -0
  79. package/dist/components/time-picker.js +457 -0
  80. package/dist/components/time-picker.js.map +1 -0
  81. package/dist/components/tooltip.js +239 -0
  82. package/dist/components/tooltip.js.map +1 -0
  83. package/dist/components/tree.js +582 -0
  84. package/dist/components/tree.js.map +1 -0
  85. package/dist/index.js +93 -17799
  86. package/dist/index.js.map +1 -1
  87. package/dist/shared/boolean-converter-XDGfS9LC.js +12 -0
  88. package/dist/shared/boolean-converter-XDGfS9LC.js.map +1 -0
  89. package/dist/shared/debounce-BckY30Sf.js +23 -0
  90. package/dist/shared/debounce-BckY30Sf.js.map +1 -0
  91. package/dist/shared/memoize-DlOFy-92.js +16 -0
  92. package/dist/shared/memoize-DlOFy-92.js.map +1 -0
  93. package/dist/shared/slider-BNt5TITl.js +484 -0
  94. package/dist/shared/slider-BNt5TITl.js.map +1 -0
  95. package/package.json +49 -3
@@ -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';\r\n\r\nexport const selectStyles = css`\r\n /* Base styles */\r\n :host {\r\n display: inline-block;\r\n width: 100%;\r\n box-sizing: border-box;\r\n }\r\n\r\n *,\r\n *::before,\r\n *::after {\r\n box-sizing: border-box;\r\n }\r\n\r\n .select {\r\n position: relative;\r\n font-family: var(--bp-font-family);\r\n }\r\n\r\n .select-label {\r\n display: block;\r\n font-family: var(--bp-font-family);\r\n font-size: var(--bp-font-size-sm);\r\n font-weight: var(--bp-font-weight-medium);\r\n color: var(--bp-color-text);\r\n line-height: var(--bp-line-height-normal);\r\n margin-bottom: var(--bp-spacing-xs);\r\n }\r\n\r\n .select-required {\r\n color: var(--bp-color-error);\r\n margin-left: var(--bp-spacing-xs);\r\n }\r\n\r\n .select-trigger {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n width: 100%;\r\n padding: var(--bp-spacing-sm) var(--bp-spacing-md);\r\n background-color: var(--bp-color-background);\r\n border: var(--bp-border-width) solid var(--bp-color-border);\r\n border-radius: var(--bp-border-radius-md);\r\n font-size: var(--bp-font-size-base);\r\n line-height: var(--bp-line-height-normal);\r\n color: var(--bp-color-text);\r\n cursor: pointer;\r\n box-shadow: inset 0 1px 2px oklch(0 0 0 / 0.05);\r\n transition:\r\n border-color var(--bp-transition-fast),\r\n box-shadow var(--bp-transition-fast);\r\n }\r\n\r\n .select-value {\r\n flex: 1;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n position: relative;\r\n }\r\n\r\n /* Hidden sizer keeps the trigger width stable across placeholder/option changes */\r\n .select-value__sizer {\r\n display: block;\r\n height: 0;\r\n overflow: hidden;\r\n visibility: hidden;\r\n white-space: nowrap;\r\n }\r\n\r\n .select-value__display {\r\n display: block;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n }\r\n\r\n /* Placeholder state - when no value is selected */\r\n .select-trigger:not([aria-label]) .select-value:empty {\r\n opacity: 0.6;\r\n }\r\n\r\n .select-icon {\r\n width: var(--bp-spacing-4);\r\n height: var(--bp-spacing-4);\r\n flex-shrink: 0;\r\n margin-left: var(--bp-spacing-xs);\r\n transition:\r\n transform var(--bp-transition-base),\r\n color var(--bp-transition-fast);\r\n }\r\n\r\n .select-dropdown {\r\n position: absolute;\r\n top: calc(100% + var(--bp-spacing-2xs));\r\n left: 0;\r\n right: 0;\r\n overflow-y: auto;\r\n background-color: var(--bp-color-background);\r\n border: var(--bp-border-width) solid var(--bp-color-border);\r\n border-radius: var(--bp-border-radius-md);\r\n box-shadow: var(--bp-shadow-lg);\r\n z-index: var(--bp-z-dropdown);\r\n animation: slideDown 150ms ease-out;\r\n transform-origin: top;\r\n contain: layout style paint;\r\n }\r\n\r\n @keyframes slideDown {\r\n from {\r\n opacity: 0;\r\n transform: translateY(calc(-1 * var(--bp-spacing-2)));\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n }\r\n\r\n .select-option {\r\n padding: var(--bp-spacing-sm) var(--bp-spacing-md);\r\n cursor: pointer;\r\n transition: background-color var(--bp-transition-fast);\r\n }\r\n\r\n .select-option:hover:not(.select-option--focused) {\r\n background-color: var(--bp-color-surface-elevated);\r\n }\r\n\r\n .select-option--focused {\r\n background-color: var(--bp-color-surface-subdued);\r\n outline: var(--bp-focus-width) solid var(--bp-color-primary);\r\n outline-offset: calc(-1 * var(--bp-focus-width));\r\n }\r\n\r\n .select-option--selected {\r\n background-color: color-mix(\r\n in srgb,\r\n var(--bp-color-primary) 8%,\r\n transparent\r\n );\r\n color: var(--bp-color-primary);\r\n font-weight: var(--bp-font-weight-semibold);\r\n position: relative;\r\n padding-right: var(--bp-spacing-2xl);\r\n }\r\n\r\n /* Checkmark for selected option */\r\n .select-option--selected::after {\r\n content: '✓';\r\n position: absolute;\r\n right: var(--bp-spacing-md);\r\n color: var(--bp-color-primary);\r\n font-weight: var(--bp-font-weight-bold);\r\n font-size: var(--bp-font-size-lg);\r\n }\r\n\r\n /* Sizes */\r\n .select--sm .select-trigger {\r\n padding: var(--bp-spacing-xs) var(--bp-spacing-sm);\r\n font-size: var(--bp-font-size-sm);\r\n }\r\n\r\n .select--sm .select-option {\r\n padding: var(--bp-spacing-xs) var(--bp-spacing-sm);\r\n font-size: var(--bp-font-size-sm);\r\n }\r\n\r\n .select--md .select-trigger {\r\n padding: var(--bp-spacing-sm) var(--bp-spacing-md);\r\n font-size: var(--bp-font-size-base);\r\n }\r\n\r\n .select--md .select-option {\r\n padding: var(--bp-spacing-sm) var(--bp-spacing-md);\r\n font-size: var(--bp-font-size-base);\r\n }\r\n\r\n .select--lg .select-trigger {\r\n padding: var(--bp-spacing-md) var(--bp-spacing-lg);\r\n font-size: var(--bp-font-size-lg);\r\n }\r\n\r\n .select--lg .select-option {\r\n padding: var(--bp-spacing-md) var(--bp-spacing-lg);\r\n font-size: var(--bp-font-size-lg);\r\n }\r\n\r\n /* States */\r\n .select-trigger:hover:not(.select--disabled .select-trigger) {\r\n border-color: var(--bp-color-primary);\r\n }\r\n\r\n .select-trigger:focus {\r\n outline: none;\r\n }\r\n\r\n .select-trigger:focus-visible {\r\n outline: var(--bp-focus-width) solid var(--bp-color-primary);\r\n outline-offset: var(--bp-focus-offset);\r\n border-color: var(--bp-color-primary);\r\n }\r\n\r\n .select--open .select-trigger {\r\n border-color: var(--bp-color-primary);\r\n }\r\n\r\n .select--open .select-icon {\r\n transform: rotate(180deg);\r\n color: var(--bp-color-primary);\r\n }\r\n\r\n .select--disabled .select-trigger {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n background-color: var(--bp-color-surface-subdued);\r\n }\r\n\r\n /* iOS zoom prevention: ensure 16px minimum on touch devices */\r\n @media (max-width: 768px) {\r\n .select--sm .select-trigger {\r\n font-size: 16px;\r\n }\r\n\r\n .select--sm .select-option {\r\n font-size: 16px;\r\n }\r\n }\r\n`;\r\n","import { LitElement, html } from 'lit';\r\nimport { customElement, property, state } from 'lit/decorators.js';\r\nimport { classMap } from 'lit/directives/class-map.js';\r\nimport { ifDefined } from 'lit/directives/if-defined.js';\r\nimport { repeat } from 'lit/directives/repeat.js';\r\nimport { selectStyles } from './select.style.js';\r\n\r\nexport type SelectSize = 'sm' | 'md' | 'lg';\r\n\r\n@customElement('bp-select')\r\nexport class BpSelect extends LitElement {\r\n /** The current value of the select */\r\n @property({ type: String, reflect: true }) declare value: string;\r\n\r\n /** Name attribute for form submission */\r\n @property({ type: String }) declare name: string;\r\n\r\n /** Visible label text displayed above the select */\r\n @property({ type: String, reflect: true }) declare label: string;\r\n\r\n /** Placeholder text when no value is selected */\r\n @property({ type: String }) declare placeholder: string;\r\n\r\n /** Whether the select is disabled */\r\n @property({ type: Boolean, reflect: true }) declare disabled: boolean;\r\n\r\n /** Whether the select is required */\r\n @property({ type: Boolean, reflect: true }) declare required: boolean;\r\n\r\n /** Size variant of the select */\r\n @property({ type: String, reflect: true }) declare size: SelectSize;\r\n\r\n /** Whether the dropdown is currently open */\r\n @state() private isOpen = false;\r\n\r\n /** Label for the selected option */\r\n @state() private selectedLabel = '';\r\n\r\n /** Index of the focused option for keyboard navigation */\r\n @state() private focusedIndex = -1;\r\n\r\n static styles = [selectStyles];\r\n\r\n constructor() {\r\n super();\r\n this.value = '';\r\n this.name = '';\r\n this.label = '';\r\n this.placeholder = 'Select an option';\r\n this.disabled = false;\r\n this.required = false;\r\n this.size = 'md';\r\n }\r\n\r\n connectedCallback() {\r\n super.connectedCallback();\r\n document.addEventListener('click', this.handleDocumentClick, {\r\n passive: true,\r\n });\r\n // Update selected label on initial load\r\n this.updateComplete.then(() => this.updateSelectedLabel());\r\n }\r\n\r\n disconnectedCallback() {\r\n super.disconnectedCallback();\r\n document.removeEventListener('click', this.handleDocumentClick, {\r\n passive: true,\r\n } as EventListenerOptions);\r\n }\r\n\r\n private handleSlotChange = () => {\r\n this.updateSelectedLabel();\r\n };\r\n\r\n private updateSelectedLabel() {\r\n if (!this.value) return;\r\n\r\n const slot = this.shadowRoot?.querySelector('slot');\r\n const assignedElements = slot?.assignedElements() || [];\r\n const options = assignedElements.filter(\r\n (el): el is globalThis.HTMLOptionElement => el.tagName === 'OPTION'\r\n );\r\n\r\n options.forEach((option) => {\r\n if ((option.value || option.textContent) === this.value) {\r\n this.selectedLabel = option.textContent || '';\r\n }\r\n });\r\n }\r\n\r\n private handleDocumentClick = (event: MouseEvent) => {\r\n if (!this.contains(event.target as unknown as globalThis.Node)) {\r\n this.isOpen = false;\r\n }\r\n };\r\n\r\n private handleToggle = (event?: Event) => {\r\n event?.stopPropagation();\r\n if (this.disabled) return;\r\n this.isOpen = !this.isOpen;\r\n };\r\n\r\n private handleOptionClick = (event: Event) => {\r\n if (this.disabled) return;\r\n\r\n const target = event.currentTarget as HTMLElement;\r\n const optionValue = target.dataset.value || '';\r\n const optionLabel = target.dataset.label || '';\r\n\r\n const previousValue = this.value;\r\n this.value = optionValue;\r\n this.selectedLabel = optionLabel;\r\n this.isOpen = false;\r\n this.focusedIndex = -1;\r\n\r\n // Dispatch change event\r\n this.dispatchEvent(\r\n new CustomEvent('bp-change', {\r\n detail: {\r\n value: this.value,\r\n label: this.selectedLabel,\r\n previousValue,\r\n },\r\n bubbles: true,\r\n composed: true,\r\n })\r\n );\r\n\r\n // Update the underlying hidden input for form integration\r\n const hiddenInput = this.shadowRoot?.querySelector('input[type=\"hidden\"]');\r\n if (hiddenInput) {\r\n (hiddenInput as HTMLInputElement).value = this.value;\r\n hiddenInput.dispatchEvent(new Event('change', { bubbles: true }));\r\n }\r\n };\r\n\r\n private handleKeyDown = (event: globalThis.KeyboardEvent) => {\r\n if (this.disabled) return;\r\n\r\n const options = this.getOptions();\r\n\r\n switch (event.key) {\r\n case 'Enter':\r\n case ' ':\r\n event.preventDefault();\r\n if (this.isOpen && this.focusedIndex >= 0) {\r\n // Select the focused option\r\n const option = options[this.focusedIndex];\r\n if (option) {\r\n const optionValue = option.value || option.textContent || '';\r\n const optionLabel = option.textContent || '';\r\n const previousValue = this.value;\r\n this.value = optionValue;\r\n this.selectedLabel = optionLabel;\r\n this.isOpen = false;\r\n this.focusedIndex = -1;\r\n\r\n this.dispatchEvent(\r\n new CustomEvent('bp-change', {\r\n detail: {\r\n value: this.value,\r\n label: this.selectedLabel,\r\n previousValue,\r\n },\r\n bubbles: true,\r\n composed: true,\r\n })\r\n );\r\n\r\n const hiddenInput = this.shadowRoot?.querySelector(\r\n 'input[type=\"hidden\"]'\r\n );\r\n if (hiddenInput) {\r\n (hiddenInput as HTMLInputElement).value = this.value;\r\n hiddenInput.dispatchEvent(new Event('change', { bubbles: true }));\r\n }\r\n }\r\n } else {\r\n this.handleToggle();\r\n }\r\n break;\r\n case 'Escape':\r\n this.isOpen = false;\r\n this.focusedIndex = -1;\r\n break;\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n if (!this.isOpen) {\r\n this.isOpen = true;\r\n this.focusedIndex = 0;\r\n } else {\r\n this.focusedIndex = Math.min(\r\n this.focusedIndex + 1,\r\n options.length - 1\r\n );\r\n }\r\n this.scrollFocusedOptionIntoView();\r\n break;\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n if (!this.isOpen) {\r\n this.isOpen = true;\r\n this.focusedIndex = options.length - 1;\r\n } else {\r\n this.focusedIndex = Math.max(this.focusedIndex - 1, 0);\r\n }\r\n this.scrollFocusedOptionIntoView();\r\n break;\r\n case 'Home':\r\n if (this.isOpen) {\r\n event.preventDefault();\r\n this.focusedIndex = 0;\r\n this.scrollFocusedOptionIntoView();\r\n }\r\n break;\r\n case 'End':\r\n if (this.isOpen) {\r\n event.preventDefault();\r\n this.focusedIndex = options.length - 1;\r\n this.scrollFocusedOptionIntoView();\r\n }\r\n break;\r\n }\r\n };\r\n\r\n private getOptions(): Array<{ value: string; textContent: string }> {\r\n const slot = this.shadowRoot?.querySelector('slot');\r\n const assignedElements = slot?.assignedElements() || [];\r\n const options = assignedElements.filter(\r\n (el): el is globalThis.HTMLOptionElement => el.tagName === 'OPTION'\r\n );\r\n return options.map((option) => ({\r\n value: option.value || option.textContent || '',\r\n textContent: option.textContent || '',\r\n }));\r\n }\r\n\r\n private scrollFocusedOptionIntoView() {\r\n this.updateComplete.then(() => {\r\n const focusedOption = this.shadowRoot?.querySelector(\r\n '.select-option--focused'\r\n ) as HTMLElement;\r\n if (focusedOption) {\r\n focusedOption.scrollIntoView({ block: 'nearest', behavior: 'smooth' });\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Returns the longest text among all options and the placeholder.\r\n * Used by a hidden sizer element to keep the trigger width stable.\r\n */\r\n private getSizerText(): string {\r\n const options = this.getOptions();\r\n let longestText = this.placeholder || '';\r\n\r\n for (const option of options) {\r\n const text = option.textContent || '';\r\n if (text.length > longestText.length) {\r\n longestText = text;\r\n }\r\n }\r\n\r\n return longestText;\r\n }\r\n\r\n private getOptionElements = () => {\r\n const slot = this.shadowRoot?.querySelector('slot');\r\n const assignedElements = slot?.assignedElements() || [];\r\n const options = assignedElements.filter(\r\n (el): el is globalThis.HTMLOptionElement => el.tagName === 'OPTION'\r\n );\r\n\r\n return repeat(\r\n options,\r\n (option) => option.value || option.textContent || '',\r\n (option, index) => {\r\n const optionValue = option.value || option.textContent || '';\r\n const optionLabel = option.textContent || '';\r\n const isSelected = this.value === optionValue;\r\n const isFocused = this.focusedIndex === index;\r\n\r\n if (isSelected && !this.selectedLabel) {\r\n this.selectedLabel = optionLabel;\r\n }\r\n\r\n return html`\r\n <div\r\n class=\"select-option ${isSelected\r\n ? 'select-option--selected'\r\n : ''} ${isFocused ? 'select-option--focused' : ''}\"\r\n part=\"option\"\r\n role=\"option\"\r\n aria-selected=\"${isSelected ? 'true' : 'false'}\"\r\n data-value=\"${optionValue}\"\r\n data-label=\"${optionLabel}\"\r\n tabindex=\"-1\"\r\n @click=${this.handleOptionClick}\r\n >\r\n ${optionLabel}\r\n </div>\r\n `;\r\n }\r\n );\r\n };\r\n\r\n render() {\r\n const selectClasses = {\r\n select: true,\r\n [`select--${this.size}`]: true,\r\n 'select--disabled': this.disabled,\r\n 'select--open': this.isOpen,\r\n };\r\n\r\n const displayLabel = this.selectedLabel || this.placeholder;\r\n\r\n const labelId = this.label ? 'select-label' : undefined;\r\n\r\n return html`\r\n <div class=${classMap(selectClasses)} part=\"container\">\r\n ${this.label\r\n ? html`\r\n <label class=\"select-label\" id=\"select-label\" part=\"label\">\r\n ${this.label}\r\n ${this.required\r\n ? html`<span class=\"select-required\">*</span>`\r\n : ''}\r\n </label>\r\n `\r\n : ''}\r\n <!-- Hidden input for form integration (using input instead of select to avoid Firefox conflict) -->\r\n <input\r\n type=\"hidden\"\r\n name=${ifDefined(this.name || undefined)}\r\n .value=${this.value}\r\n />\r\n\r\n <!-- Slot for option elements (not rendered, just for content projection) -->\r\n <slot\r\n @slotchange=${this.handleSlotChange}\r\n style=\"display: none;\"\r\n ></slot>\r\n\r\n <!-- Custom select trigger -->\r\n <div\r\n class=\"select-trigger\"\r\n part=\"trigger\"\r\n role=\"combobox\"\r\n aria-expanded=\"${this.isOpen ? 'true' : 'false'}\"\r\n aria-haspopup=\"listbox\"\r\n aria-labelledby=\"${ifDefined(labelId)}\"\r\n aria-disabled=\"${this.disabled ? 'true' : 'false'}\"\r\n aria-required=\"${this.required ? 'true' : 'false'}\"\r\n tabindex=\"${this.disabled ? '-1' : '0'}\"\r\n @click=${this.handleToggle}\r\n @keydown=${this.handleKeyDown}\r\n >\r\n <span class=\"select-value\" part=\"display\">\r\n <span class=\"select-value__sizer\" aria-hidden=\"true\"\r\n >${this.getSizerText()}</span\r\n >\r\n <span class=\"select-value__display\">${displayLabel}</span>\r\n </span>\r\n <svg\r\n class=\"select-icon\"\r\n part=\"icon\"\r\n viewBox=\"0 0 16 16\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <path\r\n d=\"M4 6L8 10L12 6\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </div>\r\n\r\n <!-- Dropdown menu -->\r\n ${this.isOpen\r\n ? html`\r\n <div class=\"select-dropdown\" part=\"dropdown\" role=\"listbox\">\r\n ${this.getOptionElements()}\r\n </div>\r\n `\r\n : null}\r\n </div>\r\n `;\r\n }\r\n}\r\n\r\ndeclare global {\r\n interface HTMLElementTagNameMap {\r\n 'bp-select': BpSelect;\r\n }\r\n}\r\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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"}