@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,377 @@
1
+ import { css as w, LitElement as h, nothing as c, html as l } from "lit";
2
+ import { property as n, query as _, customElement as b } from "lit/decorators.js";
3
+ const m = w`
4
+ /* Base styles */
5
+ :host {
6
+ display: inline-block;
7
+ position: relative;
8
+ }
9
+
10
+ .dropdown {
11
+ position: relative;
12
+ display: inline-block;
13
+ }
14
+
15
+ /* Trigger */
16
+ .dropdown__trigger {
17
+ display: inline-flex;
18
+ align-items: center;
19
+ cursor: pointer;
20
+ outline: none;
21
+ user-select: none;
22
+ }
23
+
24
+ .dropdown__trigger:focus-visible {
25
+ outline: var(--bp-focus-width) var(--bp-focus-style) var(--bp-color-focus);
26
+ outline-offset: var(--bp-focus-offset);
27
+ border-radius: var(--bp-border-radius-sm);
28
+ }
29
+
30
+ /* Panel */
31
+ .dropdown__panel {
32
+ position: absolute;
33
+ z-index: 1000; /* Overlay layer - above page content, below modals */
34
+ min-width: 200px;
35
+ background-color: var(--bp-color-surface-elevated);
36
+ border: var(--bp-border-width) solid var(--bp-color-border);
37
+ border-radius: var(--bp-border-radius-lg);
38
+ box-shadow: var(--bp-shadow-lg);
39
+ padding: var(--bp-spacing-sm);
40
+ opacity: 0;
41
+ will-change: opacity, transform;
42
+ transition:
43
+ opacity var(--bp-transition-fast) var(--bp-ease-out),
44
+ transform var(--bp-transition-fast) var(--bp-ease-out);
45
+ contain: layout style;
46
+ }
47
+
48
+ /* Placement: Bottom variants */
49
+ .dropdown__panel--bottom-start {
50
+ top: 100%;
51
+ left: 0;
52
+ margin-top: var(--dropdown-distance, 4px);
53
+ transform: translateY(-8px);
54
+ }
55
+
56
+ .dropdown__panel--bottom-start.dropdown__panel--open {
57
+ opacity: 1;
58
+ transform: translateY(0);
59
+ }
60
+
61
+ .dropdown__panel--bottom {
62
+ top: 100%;
63
+ left: 50%;
64
+ transform: translateX(-50%) translateY(-8px);
65
+ margin-top: var(--dropdown-distance, 4px);
66
+ }
67
+
68
+ .dropdown__panel--bottom.dropdown__panel--open {
69
+ opacity: 1;
70
+ transform: translateX(-50%) translateY(0);
71
+ }
72
+
73
+ .dropdown__panel--bottom-end {
74
+ top: 100%;
75
+ right: 0;
76
+ margin-top: var(--dropdown-distance, 4px);
77
+ transform: translateY(-8px);
78
+ }
79
+
80
+ .dropdown__panel--bottom-end.dropdown__panel--open {
81
+ opacity: 1;
82
+ transform: translateY(0);
83
+ }
84
+
85
+ /* Placement: Top variants */
86
+ .dropdown__panel--top-start {
87
+ bottom: 100%;
88
+ left: 0;
89
+ margin-bottom: var(--dropdown-distance, 4px);
90
+ transform: translateY(8px);
91
+ }
92
+
93
+ .dropdown__panel--top-start.dropdown__panel--open {
94
+ opacity: 1;
95
+ transform: translateY(0);
96
+ }
97
+
98
+ .dropdown__panel--top {
99
+ bottom: 100%;
100
+ left: 50%;
101
+ transform: translateX(-50%) translateY(8px);
102
+ margin-bottom: var(--dropdown-distance, 4px);
103
+ }
104
+
105
+ .dropdown__panel--top.dropdown__panel--open {
106
+ opacity: 1;
107
+ transform: translateX(-50%) translateY(0);
108
+ }
109
+
110
+ .dropdown__panel--top-end {
111
+ bottom: 100%;
112
+ right: 0;
113
+ margin-bottom: var(--dropdown-distance, 4px);
114
+ transform: translateY(8px);
115
+ }
116
+
117
+ .dropdown__panel--top-end.dropdown__panel--open {
118
+ opacity: 1;
119
+ transform: translateY(0);
120
+ }
121
+
122
+ /* Placement: Side variants */
123
+ .dropdown__panel--left {
124
+ right: 100%;
125
+ top: 50%;
126
+ transform: translateY(-50%);
127
+ margin-right: var(--dropdown-distance, 4px);
128
+ }
129
+
130
+ .dropdown__panel--left.dropdown__panel--open {
131
+ opacity: 1;
132
+ }
133
+
134
+ .dropdown__panel--right {
135
+ left: 100%;
136
+ top: 50%;
137
+ transform: translateY(-50%);
138
+ margin-left: var(--dropdown-distance, 4px);
139
+ }
140
+
141
+ .dropdown__panel--right.dropdown__panel--open {
142
+ opacity: 1;
143
+ }
144
+
145
+ /* Arrow */
146
+ .dropdown__arrow {
147
+ position: absolute;
148
+ width: 12px;
149
+ height: 12px;
150
+ background-color: var(--bp-color-surface-elevated);
151
+ border: var(--bp-border-width) solid var(--bp-color-border);
152
+ transform: rotate(45deg);
153
+ border-bottom: none;
154
+ border-right: none;
155
+ }
156
+
157
+ /* Arrow positioning: Bottom variants */
158
+ .dropdown__panel--bottom .dropdown__arrow {
159
+ top: -7px;
160
+ left: 50%;
161
+ margin-left: -6px;
162
+ }
163
+
164
+ .dropdown__panel--bottom-start .dropdown__arrow {
165
+ top: -7px;
166
+ left: 16px;
167
+ }
168
+
169
+ .dropdown__panel--bottom-end .dropdown__arrow {
170
+ top: -7px;
171
+ right: 16px;
172
+ }
173
+
174
+ /* Arrow positioning: Top variants */
175
+ .dropdown__panel--top .dropdown__arrow {
176
+ bottom: -7px;
177
+ left: 50%;
178
+ margin-left: -6px;
179
+ transform: rotate(225deg);
180
+ }
181
+
182
+ .dropdown__panel--top-start .dropdown__arrow {
183
+ bottom: -7px;
184
+ left: 16px;
185
+ transform: rotate(225deg);
186
+ }
187
+
188
+ .dropdown__panel--top-end .dropdown__arrow {
189
+ bottom: -7px;
190
+ right: 16px;
191
+ transform: rotate(225deg);
192
+ }
193
+
194
+ /* Arrow positioning: Side variants */
195
+ .dropdown__panel--left .dropdown__arrow {
196
+ right: -7px;
197
+ top: 50%;
198
+ margin-top: -6px;
199
+ transform: rotate(135deg);
200
+ }
201
+
202
+ .dropdown__panel--right .dropdown__arrow {
203
+ left: -7px;
204
+ top: 50%;
205
+ margin-top: -6px;
206
+ transform: rotate(-45deg);
207
+ }
208
+
209
+ /* Disabled state */
210
+ .dropdown--disabled .dropdown__trigger {
211
+ cursor: not-allowed;
212
+ opacity: 0.6;
213
+ filter: grayscale(50%);
214
+ pointer-events: none;
215
+ }
216
+ `;
217
+ var u = Object.defineProperty, f = Object.getOwnPropertyDescriptor, e = (t, r, p, d) => {
218
+ for (var a = d > 1 ? void 0 : d ? f(r, p) : r, s = t.length - 1, i; s >= 0; s--)
219
+ (i = t[s]) && (a = (d ? i(r, p, a) : i(a)) || a);
220
+ return d && a && u(r, p, a), a;
221
+ };
222
+ let o = class extends h {
223
+ constructor() {
224
+ super(), this.clickOutsideHandler = this.handleClickOutside.bind(this), this.keydownHandler = this.handleKeydown.bind(this), this.open = !1, this.placement = "bottom-start", this.closeOnClickOutside = !0, this.closeOnEscape = !0, this.closeOnSelect = !0, this.disabled = !1, this.distance = 4, this.arrow = !1, this.panelRole = "menu";
225
+ }
226
+ connectedCallback() {
227
+ super.connectedCallback(), document.addEventListener("click", this.clickOutsideHandler, {
228
+ passive: !0
229
+ }), document.addEventListener("keydown", this.keydownHandler);
230
+ }
231
+ disconnectedCallback() {
232
+ super.disconnectedCallback(), document.removeEventListener("click", this.clickOutsideHandler, {
233
+ passive: !0
234
+ }), document.removeEventListener("keydown", this.keydownHandler);
235
+ }
236
+ updated(t) {
237
+ super.updated(t), t.has("open") && this.open;
238
+ }
239
+ /** Show the dropdown */
240
+ show() {
241
+ this.disabled || this.open || (this.open = !0, this.dispatchEvent(
242
+ new CustomEvent("bp-show", { bubbles: !0, composed: !0 })
243
+ ), this.dispatchEvent(
244
+ new CustomEvent("bp-toggle", {
245
+ detail: { open: !0 },
246
+ bubbles: !0,
247
+ composed: !0
248
+ })
249
+ ));
250
+ }
251
+ /** Hide the dropdown */
252
+ hide() {
253
+ this.open && (this.open = !1, this.dispatchEvent(
254
+ new CustomEvent("bp-hide", { bubbles: !0, composed: !0 })
255
+ ), this.dispatchEvent(
256
+ new CustomEvent("bp-toggle", {
257
+ detail: { open: !1 },
258
+ bubbles: !0,
259
+ composed: !0
260
+ })
261
+ ));
262
+ }
263
+ /** Toggle the dropdown open/closed */
264
+ toggle() {
265
+ this.open ? this.hide() : this.show();
266
+ }
267
+ /**
268
+ * Toggles dropdown when trigger is clicked.
269
+ * Stops propagation to prevent immediate outside click detection.
270
+ */
271
+ handleTriggerClick(t) {
272
+ t.stopPropagation(), this.disabled || this.toggle();
273
+ }
274
+ /**
275
+ * Handles keyboard interaction on the trigger.
276
+ * Enter/Space toggle, ArrowDown opens when closed.
277
+ */
278
+ handleTriggerKeydown(t) {
279
+ this.disabled || (t.key === "Enter" || t.key === " " ? (t.preventDefault(), this.toggle()) : t.key === "ArrowDown" && !this.open && (t.preventDefault(), this.show()));
280
+ }
281
+ /**
282
+ * Closes the dropdown when user clicks outside the component.
283
+ * Only runs if closeOnClickOutside is true and dropdown is open.
284
+ */
285
+ handleClickOutside(t) {
286
+ if (!this.closeOnClickOutside || !this.open) return;
287
+ t.composedPath().includes(this) || this.hide();
288
+ }
289
+ /**
290
+ * Closes dropdown on Escape key and returns focus to trigger.
291
+ * Only runs if closeOnEscape is true and dropdown is open.
292
+ */
293
+ handleKeydown(t) {
294
+ !this.closeOnEscape || !this.open || t.key === "Escape" && (t.preventDefault(), this.hide(), this.triggerElement?.focus());
295
+ }
296
+ /**
297
+ * Handles clicks inside the panel to auto-close on item selection.
298
+ * Detects menu items or elements with data-dropdown-close attribute.
299
+ */
300
+ handlePanelClick(t) {
301
+ if (this.closeOnSelect) {
302
+ const r = t.target;
303
+ (r.closest("bp-menu-item") || r.closest("[data-dropdown-close]") || r.hasAttribute("data-dropdown-close")) && this.hide();
304
+ }
305
+ }
306
+ render() {
307
+ return l`
308
+ <div
309
+ class="dropdown ${this.open ? "dropdown--open" : ""} ${this.disabled ? "dropdown--disabled" : ""}"
310
+ >
311
+ <div
312
+ class="dropdown__trigger"
313
+ part="trigger"
314
+ tabindex=${this.disabled ? -1 : 0}
315
+ role="button"
316
+ aria-haspopup="true"
317
+ aria-expanded=${this.open}
318
+ aria-disabled=${this.disabled}
319
+ @click=${this.handleTriggerClick}
320
+ @keydown=${this.handleTriggerKeydown}
321
+ >
322
+ <slot></slot>
323
+ </div>
324
+ ${this.open ? l`
325
+ <div
326
+ class="dropdown__panel dropdown__panel--${this.placement} ${this.open ? "dropdown__panel--open" : ""}"
327
+ part="panel"
328
+ role=${this.panelRole}
329
+ style="--dropdown-distance: ${this.distance}px;"
330
+ @click=${this.handlePanelClick}
331
+ >
332
+ ${this.arrow ? l`<div class="dropdown__arrow"></div>` : c}
333
+ <slot name="content"></slot>
334
+ </div>
335
+ ` : c}
336
+ </div>
337
+ `;
338
+ }
339
+ };
340
+ o.styles = [m];
341
+ e([
342
+ n({ type: Boolean, reflect: !0 })
343
+ ], o.prototype, "open", 2);
344
+ e([
345
+ n({ type: String })
346
+ ], o.prototype, "placement", 2);
347
+ e([
348
+ n({ type: Boolean })
349
+ ], o.prototype, "closeOnClickOutside", 2);
350
+ e([
351
+ n({ type: Boolean })
352
+ ], o.prototype, "closeOnEscape", 2);
353
+ e([
354
+ n({ type: Boolean })
355
+ ], o.prototype, "closeOnSelect", 2);
356
+ e([
357
+ n({ type: Boolean })
358
+ ], o.prototype, "disabled", 2);
359
+ e([
360
+ n({ type: Number })
361
+ ], o.prototype, "distance", 2);
362
+ e([
363
+ n({ type: Boolean })
364
+ ], o.prototype, "arrow", 2);
365
+ e([
366
+ n({ type: String })
367
+ ], o.prototype, "panelRole", 2);
368
+ e([
369
+ _(".dropdown__trigger")
370
+ ], o.prototype, "triggerElement", 2);
371
+ o = e([
372
+ b("bp-dropdown")
373
+ ], o);
374
+ export {
375
+ o as BpDropdown
376
+ };
377
+ //# sourceMappingURL=dropdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dropdown.js","sources":["../../source/components/dropdown/dropdown.style.ts","../../source/components/dropdown/dropdown.ts"],"sourcesContent":["import { css } from 'lit';\r\n\r\nexport const dropdownStyles = css`\r\n /* Base styles */\r\n :host {\r\n display: inline-block;\r\n position: relative;\r\n }\r\n\r\n .dropdown {\r\n position: relative;\r\n display: inline-block;\r\n }\r\n\r\n /* Trigger */\r\n .dropdown__trigger {\r\n display: inline-flex;\r\n align-items: center;\r\n cursor: pointer;\r\n outline: none;\r\n user-select: none;\r\n }\r\n\r\n .dropdown__trigger:focus-visible {\r\n outline: var(--bp-focus-width) var(--bp-focus-style) var(--bp-color-focus);\r\n outline-offset: var(--bp-focus-offset);\r\n border-radius: var(--bp-border-radius-sm);\r\n }\r\n\r\n /* Panel */\r\n .dropdown__panel {\r\n position: absolute;\r\n z-index: 1000; /* Overlay layer - above page content, below modals */\r\n min-width: 200px;\r\n background-color: var(--bp-color-surface-elevated);\r\n border: var(--bp-border-width) solid var(--bp-color-border);\r\n border-radius: var(--bp-border-radius-lg);\r\n box-shadow: var(--bp-shadow-lg);\r\n padding: var(--bp-spacing-sm);\r\n opacity: 0;\r\n will-change: opacity, transform;\r\n transition:\r\n opacity var(--bp-transition-fast) var(--bp-ease-out),\r\n transform var(--bp-transition-fast) var(--bp-ease-out);\r\n contain: layout style;\r\n }\r\n\r\n /* Placement: Bottom variants */\r\n .dropdown__panel--bottom-start {\r\n top: 100%;\r\n left: 0;\r\n margin-top: var(--dropdown-distance, 4px);\r\n transform: translateY(-8px);\r\n }\r\n\r\n .dropdown__panel--bottom-start.dropdown__panel--open {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n\r\n .dropdown__panel--bottom {\r\n top: 100%;\r\n left: 50%;\r\n transform: translateX(-50%) translateY(-8px);\r\n margin-top: var(--dropdown-distance, 4px);\r\n }\r\n\r\n .dropdown__panel--bottom.dropdown__panel--open {\r\n opacity: 1;\r\n transform: translateX(-50%) translateY(0);\r\n }\r\n\r\n .dropdown__panel--bottom-end {\r\n top: 100%;\r\n right: 0;\r\n margin-top: var(--dropdown-distance, 4px);\r\n transform: translateY(-8px);\r\n }\r\n\r\n .dropdown__panel--bottom-end.dropdown__panel--open {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n\r\n /* Placement: Top variants */\r\n .dropdown__panel--top-start {\r\n bottom: 100%;\r\n left: 0;\r\n margin-bottom: var(--dropdown-distance, 4px);\r\n transform: translateY(8px);\r\n }\r\n\r\n .dropdown__panel--top-start.dropdown__panel--open {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n\r\n .dropdown__panel--top {\r\n bottom: 100%;\r\n left: 50%;\r\n transform: translateX(-50%) translateY(8px);\r\n margin-bottom: var(--dropdown-distance, 4px);\r\n }\r\n\r\n .dropdown__panel--top.dropdown__panel--open {\r\n opacity: 1;\r\n transform: translateX(-50%) translateY(0);\r\n }\r\n\r\n .dropdown__panel--top-end {\r\n bottom: 100%;\r\n right: 0;\r\n margin-bottom: var(--dropdown-distance, 4px);\r\n transform: translateY(8px);\r\n }\r\n\r\n .dropdown__panel--top-end.dropdown__panel--open {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n\r\n /* Placement: Side variants */\r\n .dropdown__panel--left {\r\n right: 100%;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n margin-right: var(--dropdown-distance, 4px);\r\n }\r\n\r\n .dropdown__panel--left.dropdown__panel--open {\r\n opacity: 1;\r\n }\r\n\r\n .dropdown__panel--right {\r\n left: 100%;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n margin-left: var(--dropdown-distance, 4px);\r\n }\r\n\r\n .dropdown__panel--right.dropdown__panel--open {\r\n opacity: 1;\r\n }\r\n\r\n /* Arrow */\r\n .dropdown__arrow {\r\n position: absolute;\r\n width: 12px;\r\n height: 12px;\r\n background-color: var(--bp-color-surface-elevated);\r\n border: var(--bp-border-width) solid var(--bp-color-border);\r\n transform: rotate(45deg);\r\n border-bottom: none;\r\n border-right: none;\r\n }\r\n\r\n /* Arrow positioning: Bottom variants */\r\n .dropdown__panel--bottom .dropdown__arrow {\r\n top: -7px;\r\n left: 50%;\r\n margin-left: -6px;\r\n }\r\n\r\n .dropdown__panel--bottom-start .dropdown__arrow {\r\n top: -7px;\r\n left: 16px;\r\n }\r\n\r\n .dropdown__panel--bottom-end .dropdown__arrow {\r\n top: -7px;\r\n right: 16px;\r\n }\r\n\r\n /* Arrow positioning: Top variants */\r\n .dropdown__panel--top .dropdown__arrow {\r\n bottom: -7px;\r\n left: 50%;\r\n margin-left: -6px;\r\n transform: rotate(225deg);\r\n }\r\n\r\n .dropdown__panel--top-start .dropdown__arrow {\r\n bottom: -7px;\r\n left: 16px;\r\n transform: rotate(225deg);\r\n }\r\n\r\n .dropdown__panel--top-end .dropdown__arrow {\r\n bottom: -7px;\r\n right: 16px;\r\n transform: rotate(225deg);\r\n }\r\n\r\n /* Arrow positioning: Side variants */\r\n .dropdown__panel--left .dropdown__arrow {\r\n right: -7px;\r\n top: 50%;\r\n margin-top: -6px;\r\n transform: rotate(135deg);\r\n }\r\n\r\n .dropdown__panel--right .dropdown__arrow {\r\n left: -7px;\r\n top: 50%;\r\n margin-top: -6px;\r\n transform: rotate(-45deg);\r\n }\r\n\r\n /* Disabled state */\r\n .dropdown--disabled .dropdown__trigger {\r\n cursor: not-allowed;\r\n opacity: 0.6;\r\n filter: grayscale(50%);\r\n pointer-events: none;\r\n }\r\n`;\r\n","import { LitElement, html, nothing } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { dropdownStyles } from './dropdown.style.js';\n\n/**\n * A generic dropdown component that displays content in a floating panel.\n *\n * @fires bp-show - Dispatched when the dropdown opens\n * @fires bp-hide - Dispatched when the dropdown closes\n * @fires bp-toggle - Dispatched when the dropdown toggles\n *\n * @slot - Default slot for the dropdown trigger element\n * @slot content - Content to display in the dropdown panel\n *\n * @csspart trigger - The trigger button container\n * @csspart panel - The dropdown panel container\n */\n@customElement('bp-dropdown')\nexport class BpDropdown extends LitElement {\n /** Whether the dropdown is open */\n @property({ type: Boolean, reflect: true }) declare open: boolean;\n\n /** Placement of the dropdown panel relative to the trigger */\n @property({ type: String }) declare placement:\n | 'top'\n | 'top-start'\n | 'top-end'\n | 'bottom'\n | 'bottom-start'\n | 'bottom-end'\n | 'left'\n | 'right';\n\n /** Whether the dropdown should close when clicking outside */\n @property({ type: Boolean }) declare closeOnClickOutside: boolean;\n\n /** Whether the dropdown should close when pressing Escape */\n @property({ type: Boolean }) declare closeOnEscape: boolean;\n\n /** Whether the dropdown should close when an item inside is clicked */\n @property({ type: Boolean }) declare closeOnSelect: boolean;\n\n /** Whether the dropdown is disabled */\n @property({ type: Boolean }) declare disabled: boolean;\n\n /** Distance in pixels between the trigger and the panel */\n @property({ type: Number }) declare distance: number;\n\n /** Whether to show an arrow pointing to the trigger */\n @property({ type: Boolean }) declare arrow: boolean;\n\n /** ARIA role for the dropdown panel */\n @property({ type: String }) declare panelRole: 'menu' | 'dialog' | 'listbox';\n\n @query('.dropdown__trigger') private triggerElement!: HTMLElement;\n\n private clickOutsideHandler = this.handleClickOutside.bind(this);\n private keydownHandler = this.handleKeydown.bind(this);\n\n static styles = [dropdownStyles];\n\n constructor() {\n super();\n this.open = false;\n this.placement = 'bottom-start';\n this.closeOnClickOutside = true;\n this.closeOnEscape = true;\n this.closeOnSelect = true;\n this.disabled = false;\n this.distance = 4;\n this.arrow = false;\n this.panelRole = 'menu';\n }\n\n connectedCallback() {\n super.connectedCallback();\n document.addEventListener('click', this.clickOutsideHandler, {\n passive: true,\n });\n document.addEventListener('keydown', this.keydownHandler);\n }\n\n disconnectedCallback() {\n super.disconnectedCallback();\n document.removeEventListener('click', this.clickOutsideHandler, {\n passive: true,\n } as EventListenerOptions);\n document.removeEventListener('keydown', this.keydownHandler);\n }\n\n updated(changedProperties: Map<string, unknown>) {\n super.updated(changedProperties);\n if (changedProperties.has('open') && this.open) {\n // Trigger width available via this.triggerElement.offsetWidth if needed\n }\n }\n\n /** Show the dropdown */\n show() {\n if (this.disabled || this.open) return;\n\n this.open = true;\n this.dispatchEvent(\n new CustomEvent('bp-show', { bubbles: true, composed: true })\n );\n this.dispatchEvent(\n new CustomEvent('bp-toggle', {\n detail: { open: true },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n /** Hide the dropdown */\n hide() {\n if (!this.open) return;\n\n this.open = false;\n this.dispatchEvent(\n new CustomEvent('bp-hide', { bubbles: true, composed: true })\n );\n this.dispatchEvent(\n new CustomEvent('bp-toggle', {\n detail: { open: false },\n bubbles: true,\n composed: true,\n })\n );\n }\n\n /** Toggle the dropdown open/closed */\n toggle() {\n if (this.open) {\n this.hide();\n } else {\n this.show();\n }\n }\n\n /**\n * Toggles dropdown when trigger is clicked.\n * Stops propagation to prevent immediate outside click detection.\n */\n private handleTriggerClick(event: MouseEvent) {\n event.stopPropagation();\n if (!this.disabled) {\n this.toggle();\n }\n }\n\n /**\n * Handles keyboard interaction on the trigger.\n * Enter/Space toggle, ArrowDown opens when closed.\n */\n private handleTriggerKeydown(event: KeyboardEvent) {\n if (this.disabled) return;\n\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.toggle();\n } else if (event.key === 'ArrowDown' && !this.open) {\n event.preventDefault();\n this.show();\n }\n }\n\n /**\n * Closes the dropdown when user clicks outside the component.\n * Only runs if closeOnClickOutside is true and dropdown is open.\n */\n private handleClickOutside(event: MouseEvent) {\n if (!this.closeOnClickOutside || !this.open) return;\n\n const path = event.composedPath();\n if (!path.includes(this)) {\n this.hide();\n }\n }\n\n /**\n * Closes dropdown on Escape key and returns focus to trigger.\n * Only runs if closeOnEscape is true and dropdown is open.\n */\n private handleKeydown(event: KeyboardEvent) {\n if (!this.closeOnEscape || !this.open) return;\n\n if (event.key === 'Escape') {\n event.preventDefault();\n this.hide();\n this.triggerElement?.focus();\n }\n }\n\n /**\n * Handles clicks inside the panel to auto-close on item selection.\n * Detects menu items or elements with data-dropdown-close attribute.\n */\n private handlePanelClick(event: MouseEvent) {\n if (this.closeOnSelect) {\n // Check if clicked element or its parent is a menu item or similar\n const target = event.target as HTMLElement;\n const isSelectableItem =\n target.closest('bp-menu-item') ||\n target.closest('[data-dropdown-close]') ||\n target.hasAttribute('data-dropdown-close');\n\n if (isSelectableItem) {\n this.hide();\n }\n }\n }\n\n render() {\n return html`\n <div\n class=\"dropdown ${this.open ? 'dropdown--open' : ''} ${this.disabled\n ? 'dropdown--disabled'\n : ''}\"\n >\n <div\n class=\"dropdown__trigger\"\n part=\"trigger\"\n tabindex=${this.disabled ? -1 : 0}\n role=\"button\"\n aria-haspopup=\"true\"\n aria-expanded=${this.open}\n aria-disabled=${this.disabled}\n @click=${this.handleTriggerClick}\n @keydown=${this.handleTriggerKeydown}\n >\n <slot></slot>\n </div>\n ${this.open\n ? html`\n <div\n class=\"dropdown__panel dropdown__panel--${this.placement} ${this\n .open\n ? 'dropdown__panel--open'\n : ''}\"\n part=\"panel\"\n role=${this.panelRole}\n style=\"--dropdown-distance: ${this.distance}px;\"\n @click=${this.handlePanelClick}\n >\n ${this.arrow\n ? html`<div class=\"dropdown__arrow\"></div>`\n : nothing}\n <slot name=\"content\"></slot>\n </div>\n `\n : nothing}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'bp-dropdown': BpDropdown;\n }\n}\n"],"names":["dropdownStyles","css","BpDropdown","LitElement","changedProperties","event","target","html","nothing","__decorateClass","property","query","customElement"],"mappings":"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"}