@nuykon/basecoat-react 0.0.0-stage → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,2328 @@
1
+ 'use client';
2
+ "use client";
3
+
4
+ // src/primitives.tsx
5
+ import {
6
+ cloneElement,
7
+ createElement,
8
+ forwardRef,
9
+ useEffect,
10
+ useRef,
11
+ isValidElement
12
+ } from "react";
13
+
14
+ // ../core/src/chart.ts
15
+ function attachCanvasChart(canvas, config) {
16
+ const doc = canvas.ownerDocument, win = doc.defaultView, ctx = canvas.getContext("2d");
17
+ if (!ctx) return () => {
18
+ };
19
+ const data = config.data ?? [], series = Object.entries(config.series ?? {}), labelKey = config.labelKey ?? "label";
20
+ const color = (value) => value.startsWith("var(") ? win.getComputedStyle(canvas).getPropertyValue(value.slice(4, -1)).trim() || "#888" : value;
21
+ const legend = doc.createElement("ul");
22
+ legend.className = "chart-legend";
23
+ if (config.legend) {
24
+ for (const [index, [key, options]] of series.entries()) {
25
+ const item = doc.createElement("li"), content = doc.createElement("span"), indicator = doc.createElement("span");
26
+ content.className = "chart-legend-item";
27
+ indicator.className = "chart-legend-indicator";
28
+ indicator.style.setProperty(
29
+ "--chart-indicator-color",
30
+ options.color ?? `var(--chart-${index + 1})`
31
+ );
32
+ content.append(indicator, doc.createTextNode(options.label ?? key));
33
+ item.append(content);
34
+ legend.append(item);
35
+ }
36
+ canvas.after(legend);
37
+ }
38
+ canvas.style.width = "100%";
39
+ canvas.style.aspectRatio = "16 / 9";
40
+ canvas.style.display = "block";
41
+ const draw = () => {
42
+ const width = Math.max(200, canvas.parentElement?.clientWidth ?? 400), height = width * 9 / 16, ratio = win.devicePixelRatio || 1;
43
+ canvas.width = Math.round(width * ratio);
44
+ canvas.height = Math.round(height * ratio);
45
+ canvas.style.height = `${height}px`;
46
+ ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
47
+ ctx.clearRect(0, 0, width, height);
48
+ const padding = { left: 30, top: 10, right: 10, bottom: 30 }, w = width - padding.left - padding.right, h = height - padding.top - padding.bottom;
49
+ const max = Math.max(
50
+ 1,
51
+ ...data.map(
52
+ (row) => config.options?.scales?.y?.stacked ? series.reduce((sum, [key]) => sum + Number(row[key] ?? 0), 0) : Math.max(...series.map(([key]) => Number(row[key] ?? 0)))
53
+ )
54
+ );
55
+ const x = (index) => padding.left + index / Math.max(1, data.length - 1) * w, y = (value) => padding.top + h - value / max * h;
56
+ ctx.font = '12px "Geist Sans",system-ui';
57
+ ctx.fillStyle = color("var(--muted-foreground)");
58
+ ctx.strokeStyle = color("var(--border)");
59
+ ctx.lineWidth = 0.5;
60
+ if (config.type !== "doughnut" && config.type !== "radar") {
61
+ for (let index = 0; index <= 4; index++) {
62
+ const top = padding.top + index * h / 4;
63
+ ctx.beginPath();
64
+ ctx.moveTo(padding.left, top);
65
+ ctx.lineTo(width - padding.right, top);
66
+ ctx.stroke();
67
+ ctx.fillText(String(Math.round(max * (4 - index) / 4)), 0, top + 4);
68
+ }
69
+ for (let index = 0; index < data.length; index++)
70
+ if (index % Math.max(1, Math.ceil(data.length / 6)) === 0)
71
+ ctx.fillText(String(data[index][labelKey] ?? ""), x(index) - 10, height - 8);
72
+ }
73
+ if (config.type === "doughnut") {
74
+ const key = series[0]?.[0] ?? "value", values = data.map((row) => Number(row[key] ?? 0)), total = values.reduce((a, b) => a + b, 0) || 1, radius = Math.min(w, h) * 0.45, cx2 = width / 2, cy = height / 2;
75
+ let start = -Math.PI / 2;
76
+ values.forEach((value, index) => {
77
+ const end = start + value / total * Math.PI * 2;
78
+ ctx.beginPath();
79
+ ctx.arc(cx2, cy, radius, start, end);
80
+ ctx.arc(cx2, cy, radius * 0.62, end, start, true);
81
+ ctx.closePath();
82
+ ctx.fillStyle = color(`var(--chart-${index % 5 + 1})`);
83
+ ctx.fill();
84
+ start = end;
85
+ });
86
+ } else if (config.type === "radar") {
87
+ const radius = Math.min(w, h) * 0.4, cx2 = width / 2, cy = height / 2;
88
+ const point = (index, scale) => {
89
+ const angle = index / Math.max(1, data.length) * Math.PI * 2 - Math.PI / 2;
90
+ return [
91
+ cx2 + Math.cos(angle) * radius * scale,
92
+ cy + Math.sin(angle) * radius * scale
93
+ ];
94
+ };
95
+ for (let ring = 1; ring <= 4; ring++) {
96
+ ctx.beginPath();
97
+ data.forEach((_, i) => {
98
+ const [x2, y2] = point(i, ring / 4);
99
+ if (i === 0) ctx.moveTo(x2, y2);
100
+ else ctx.lineTo(x2, y2);
101
+ });
102
+ ctx.closePath();
103
+ ctx.stroke();
104
+ }
105
+ series.forEach(([key, options], index) => {
106
+ ctx.beginPath();
107
+ data.forEach((row, i) => {
108
+ const [x2, y2] = point(i, Number(row[key] ?? 0) / max);
109
+ if (i === 0) ctx.moveTo(x2, y2);
110
+ else ctx.lineTo(x2, y2);
111
+ });
112
+ ctx.closePath();
113
+ ctx.strokeStyle = color(options.color ?? `var(--chart-${index + 1})`);
114
+ ctx.stroke();
115
+ ctx.globalAlpha = 0.2;
116
+ ctx.fillStyle = ctx.strokeStyle;
117
+ ctx.fill();
118
+ ctx.globalAlpha = 1;
119
+ });
120
+ ctx.fillStyle = color("var(--muted-foreground)");
121
+ data.forEach((row, i) => {
122
+ const [x2, y2] = point(i, 1.15);
123
+ ctx.fillText(String(row[labelKey] ?? ""), x2 - 15, y2);
124
+ });
125
+ } else {
126
+ const stacks2 = data.map(() => 0);
127
+ series.forEach(([key, options], seriesIndex) => {
128
+ const fill = color(options.color ?? `var(--chart-${seriesIndex + 1})`);
129
+ ctx.strokeStyle = fill;
130
+ ctx.fillStyle = fill;
131
+ ctx.lineWidth = 1.5;
132
+ if (config.type === "bar")
133
+ data.forEach((row, index) => {
134
+ const value = Number(row[key] ?? 0), stacked = config.options?.scales?.y?.stacked, group = w / Math.max(1, data.length), barWidth = group * 0.65 / (stacked ? 1 : series.length), left = padding.left + index * group + group * 0.15 + (stacked ? 0 : seriesIndex * barWidth), base = stacks2[index];
135
+ ctx.beginPath();
136
+ ctx.roundRect(
137
+ left,
138
+ y(value + base),
139
+ Math.max(1, barWidth - 2),
140
+ Math.max(0, y(base) - y(value + base)),
141
+ 3
142
+ );
143
+ ctx.fill();
144
+ if (stacked) stacks2[index] += value;
145
+ });
146
+ else {
147
+ ctx.beginPath();
148
+ data.forEach((row, index) => {
149
+ const top = y(Number(row[key] ?? 0));
150
+ if (index === 0) ctx.moveTo(x(index), top);
151
+ else if (options.dataset?.stepped) {
152
+ ctx.lineTo(x(index), y(Number(data[index - 1][key] ?? 0)));
153
+ ctx.lineTo(x(index), top);
154
+ } else ctx.lineTo(x(index), top);
155
+ });
156
+ ctx.stroke();
157
+ if (options.dataset?.fill || options.surface === "gradient") {
158
+ ctx.lineTo(x(data.length - 1), y(0));
159
+ ctx.lineTo(x(0), y(0));
160
+ ctx.closePath();
161
+ const gradient = ctx.createLinearGradient(0, 0, 0, height);
162
+ gradient.addColorStop(0, fill);
163
+ gradient.addColorStop(1, "transparent");
164
+ ctx.globalAlpha = 0.3;
165
+ ctx.fillStyle = gradient;
166
+ ctx.fill();
167
+ ctx.globalAlpha = 1;
168
+ }
169
+ }
170
+ });
171
+ }
172
+ };
173
+ const resize = new win.ResizeObserver(draw), themes = new win.MutationObserver(draw);
174
+ resize.observe(canvas.parentElement ?? canvas);
175
+ themes.observe(doc.documentElement, {
176
+ attributes: true,
177
+ attributeFilter: ["class", "data-style-variant"]
178
+ });
179
+ doc.addEventListener("basecoat:stylechange", draw);
180
+ draw();
181
+ return () => {
182
+ resize.disconnect();
183
+ themes.disconnect();
184
+ legend.remove();
185
+ doc.removeEventListener("basecoat:stylechange", draw);
186
+ };
187
+ }
188
+
189
+ // ../core/src/widgets.ts
190
+ function attachWidget(root) {
191
+ const abort = new AbortController(), signal = abort.signal, cleanups = [];
192
+ const on = (element, name, fn) => element?.addEventListener(name, fn, { signal });
193
+ const emit = (detail) => root.dispatchEvent(new CustomEvent("basecoat:change", { bubbles: true, detail }));
194
+ if (root instanceof HTMLCanvasElement && root.dataset.chartConfig)
195
+ cleanups.push(attachCanvasChart(root, JSON.parse(root.dataset.chartConfig)));
196
+ if (root.classList.contains("sidebar")) {
197
+ const media = root.ownerDocument.defaultView.matchMedia("(min-width: 768px)");
198
+ root.dataset.sidebarInitialized = "true";
199
+ const set = (open) => root.setAttribute("aria-hidden", String(!open));
200
+ const toggle = () => set(root.getAttribute("aria-hidden") === "true");
201
+ const sidebar = root;
202
+ sidebar.toggle = toggle;
203
+ set(media.matches);
204
+ on(media, "change", () => set(media.matches));
205
+ on(root, "click", (event) => {
206
+ if (event.target === root && !media.matches) set(false);
207
+ });
208
+ on(root.ownerDocument, "keydown", (event) => {
209
+ if (event.key === "Escape" && !media.matches) set(false);
210
+ });
211
+ cleanups.push(() => {
212
+ delete sidebar.toggle;
213
+ delete root.dataset.sidebarInitialized;
214
+ });
215
+ }
216
+ if (root.classList.contains("toaster")) {
217
+ const timers = /* @__PURE__ */ new Set();
218
+ const toast = (message) => {
219
+ const item = root.ownerDocument.createElement("div");
220
+ item.className = "toast";
221
+ item.setAttribute("role", "status");
222
+ const content = root.ownerDocument.createElement("div");
223
+ content.className = "toast-content";
224
+ const section = root.ownerDocument.createElement("section"), heading = root.ownerDocument.createElement("h2");
225
+ heading.textContent = message.title ?? "";
226
+ section.append(heading);
227
+ if (message.description) {
228
+ const description = root.ownerDocument.createElement("p");
229
+ description.textContent = message.description;
230
+ section.append(description);
231
+ }
232
+ const footer = root.ownerDocument.createElement("footer"), close = root.ownerDocument.createElement("button");
233
+ close.type = "button";
234
+ close.className = "btn";
235
+ close.dataset.variant = "outline";
236
+ close.dataset.toastCancel = "";
237
+ close.textContent = message.cancel?.label ?? "Dismiss";
238
+ close.addEventListener("click", () => item.remove(), { signal });
239
+ footer.append(close);
240
+ if (message.action) {
241
+ const action = root.ownerDocument.createElement("button");
242
+ action.type = "button";
243
+ action.className = "btn";
244
+ action.textContent = message.action.label ?? "Action";
245
+ action.addEventListener(
246
+ "click",
247
+ () => {
248
+ message.action?.onclick?.();
249
+ item.remove();
250
+ },
251
+ { signal }
252
+ );
253
+ footer.append(action);
254
+ }
255
+ content.append(section, footer);
256
+ item.append(content);
257
+ root.append(item);
258
+ if ((message.duration ?? 5e3) > 0) {
259
+ const timer = setTimeout(() => {
260
+ item.remove();
261
+ timers.delete(timer);
262
+ }, message.duration ?? 5e3);
263
+ timers.add(timer);
264
+ }
265
+ return item;
266
+ };
267
+ root.toast = toast;
268
+ on(root, "click", (event) => {
269
+ const button = event.target.closest("[data-toast-cancel]");
270
+ button?.closest(".toast")?.remove();
271
+ });
272
+ cleanups.push(() => {
273
+ timers.forEach(clearTimeout);
274
+ delete root.toast;
275
+ });
276
+ }
277
+ if (root.classList.contains("tabs")) {
278
+ const tabs = [...root.querySelectorAll("[role=tab]")].filter(
279
+ (tab) => tab.closest(".tabs") === root
280
+ );
281
+ const set = (target) => {
282
+ if (target.disabled || target.getAttribute("aria-disabled") === "true") return;
283
+ for (const tab of tabs) {
284
+ const active = tab === target;
285
+ tab.setAttribute("aria-selected", String(active));
286
+ tab.tabIndex = active ? 0 : -1;
287
+ const panel = root.ownerDocument.getElementById(tab.getAttribute("aria-controls") ?? "");
288
+ if (panel) {
289
+ panel.hidden = !active;
290
+ panel.setAttribute("aria-selected", String(active));
291
+ }
292
+ }
293
+ emit(target.id);
294
+ };
295
+ for (const [index, tab] of tabs.entries()) {
296
+ on(tab, "click", () => set(tab));
297
+ on(tab, "keydown", (event) => {
298
+ const key = event.key, vertical = tab.parentElement?.getAttribute("aria-orientation") === "vertical";
299
+ if (!(vertical ? ["ArrowUp", "ArrowDown"] : ["ArrowLeft", "ArrowRight"]).includes(key) && !["Home", "End"].includes(key))
300
+ return;
301
+ event.preventDefault();
302
+ const target = tabs[nextIndex(
303
+ tabs.map((item) => ({
304
+ disabled: item.disabled || item.getAttribute("aria-disabled") === "true"
305
+ })),
306
+ index,
307
+ key
308
+ )];
309
+ target?.focus();
310
+ if (target) set(target);
311
+ });
312
+ }
313
+ }
314
+ if (root.classList.contains("accordion")) {
315
+ const summaries = [...root.querySelectorAll("summary")];
316
+ on(root, "keydown", (event) => {
317
+ const index = summaries.indexOf(event.target), key = event.key;
318
+ if (index >= 0 && ["ArrowUp", "ArrowDown", "Home", "End"].includes(key)) {
319
+ event.preventDefault();
320
+ summaries[nextIndex(
321
+ summaries.map((el) => ({ disabled: el.getAttribute("aria-disabled") === "true" })),
322
+ index,
323
+ key
324
+ )]?.focus();
325
+ }
326
+ });
327
+ on(root, "click", (event) => {
328
+ const summary = event.target.closest("summary");
329
+ if (summary?.getAttribute("aria-disabled") === "true" || summary?.parentElement?.getAttribute("aria-disabled") === "true")
330
+ event.preventDefault();
331
+ });
332
+ }
333
+ const kind = ["select", "combobox", "dropdown-menu", "popover"].find(
334
+ (kind2) => root.classList.contains(kind2)
335
+ );
336
+ if (kind) {
337
+ const trigger = root.querySelector(
338
+ ":scope > button, :scope > input[role=combobox], :scope > .input-group input[role=combobox]"
339
+ ), popup = root.querySelector(":scope > [data-popover]");
340
+ const search = root.querySelector(
341
+ "[data-popover] input, input[role=combobox]"
342
+ );
343
+ if (trigger && popup) {
344
+ let open = false, active = -1, disposePosition, disposeLayer;
345
+ const selector = kind === "dropdown-menu" ? "[role=menuitem], [role=menuitemcheckbox], [role=menuitemradio]" : "[role=option]";
346
+ const items = () => [...popup.querySelectorAll(selector)].filter(
347
+ (item) => !item.hidden && item.getAttribute("aria-hidden") !== "true"
348
+ );
349
+ const disabled = (item) => item.matches(":disabled") || item.getAttribute("aria-disabled") === "true";
350
+ const cursor = () => items().map((item) => ({
351
+ value: item.dataset.value ?? item.id,
352
+ label: item.textContent?.trim() ?? "",
353
+ disabled: disabled(item)
354
+ }));
355
+ const typeahead = createTypeahead();
356
+ const highlight = (index) => {
357
+ active = index;
358
+ const all = items();
359
+ for (const [i, item2] of all.entries()) {
360
+ item2.classList.toggle("active", i === index);
361
+ if (kind === "dropdown-menu") item2.tabIndex = i === index ? 0 : -1;
362
+ }
363
+ const item = all[index];
364
+ if (item) {
365
+ if (kind === "dropdown-menu") item.focus();
366
+ else {
367
+ const list = popup.querySelector("[role=listbox]");
368
+ if (list) {
369
+ list.setAttribute("aria-activedescendant", item.id);
370
+ scrollWithin(list, item);
371
+ }
372
+ search?.setAttribute("aria-activedescendant", item.id);
373
+ }
374
+ }
375
+ };
376
+ const close = (restore = false) => {
377
+ if (!open) return;
378
+ open = false;
379
+ disposeLayer?.();
380
+ disposePosition?.();
381
+ trigger.setAttribute("aria-expanded", "false");
382
+ popup.setAttribute("aria-hidden", "true");
383
+ popup.hidden = true;
384
+ if (restore) trigger.focus();
385
+ };
386
+ const show = (last = false) => {
387
+ if (open || disabled(trigger)) return;
388
+ open = true;
389
+ popup.hidden = false;
390
+ popup.setAttribute("aria-hidden", "false");
391
+ popup.setAttribute("popover", "manual");
392
+ popup.classList.add("bc-floating");
393
+ trigger.setAttribute("aria-expanded", "true");
394
+ disposePosition = attachFloating(trigger, popup, {
395
+ side: popup.dataset.side,
396
+ align: popup.dataset.align,
397
+ matchWidth: kind === "select" || kind === "combobox"
398
+ });
399
+ disposeLayer = dismissableLayer(root.ownerDocument, {
400
+ elements: () => [trigger, popup],
401
+ dismiss: (reason) => close(reason === "escape")
402
+ });
403
+ const list = popup.querySelector("[role=listbox],[role=menu]");
404
+ if (list) {
405
+ list.tabIndex = -1;
406
+ (search ?? list).focus();
407
+ }
408
+ if (kind === "popover") focusFirst(popup);
409
+ else highlight(nextIndex(cursor(), -1, last ? "End" : "Home"));
410
+ };
411
+ const choose = (item) => {
412
+ if (disabled(item)) return;
413
+ if (kind === "select" || kind === "combobox") {
414
+ const multiple = popup.querySelector("[aria-multiselectable=true]") !== null;
415
+ if (!multiple)
416
+ items().forEach(
417
+ (option) => option.setAttribute("aria-selected", String(option === item))
418
+ );
419
+ else
420
+ item.setAttribute(
421
+ "aria-selected",
422
+ String(item.getAttribute("aria-selected") !== "true")
423
+ );
424
+ const selected = items().filter(
425
+ (option) => option.getAttribute("aria-selected") === "true"
426
+ ), values = selected.map(
427
+ (option) => option.dataset.value ?? option.textContent?.trim() ?? ""
428
+ );
429
+ if (trigger instanceof HTMLInputElement) trigger.value = item.textContent?.trim() ?? "";
430
+ else {
431
+ const label = trigger.querySelector("span");
432
+ if (label)
433
+ label.textContent = selected.map((option) => option.textContent?.trim()).join(", ");
434
+ }
435
+ const hidden = root.querySelector("input[type=hidden]");
436
+ if (hidden) {
437
+ hidden.value = multiple ? JSON.stringify(values) : values[0] ?? "";
438
+ hidden.dispatchEvent(new Event("change", { bubbles: true }));
439
+ }
440
+ emit(multiple ? values : values[0]);
441
+ if (!multiple) close(true);
442
+ } else if (kind === "dropdown-menu") {
443
+ if (item.getAttribute("role") === "menuitemcheckbox") {
444
+ item.setAttribute("aria-checked", String(item.getAttribute("aria-checked") !== "true"));
445
+ emit(item.id);
446
+ } else close(true);
447
+ }
448
+ };
449
+ popup.hidden = popup.getAttribute("aria-hidden") !== "false";
450
+ on(trigger, "click", () => open ? close() : show());
451
+ on(trigger, "keydown", (event) => {
452
+ const key = event.key;
453
+ if (!open && ["ArrowDown", "ArrowUp", "Enter", " "].includes(key)) {
454
+ event.preventDefault();
455
+ show(key === "ArrowUp");
456
+ }
457
+ });
458
+ on(popup, "keydown", (event) => {
459
+ const keyboard = event;
460
+ if (["ArrowDown", "ArrowUp", "Home", "End"].includes(keyboard.key)) {
461
+ event.preventDefault();
462
+ highlight(nextIndex(cursor(), active, keyboard.key));
463
+ } else if (keyboard.key === "Enter" || !search && keyboard.key === " ") {
464
+ event.preventDefault();
465
+ const item = items()[active];
466
+ if (item) {
467
+ choose(item);
468
+ if (item instanceof HTMLAnchorElement) item.click();
469
+ }
470
+ } else if (keyboard.key === "Tab") close();
471
+ else if (!search && keyboard.key.length === 1 && !keyboard.ctrlKey && !keyboard.metaKey) {
472
+ event.preventDefault();
473
+ highlight(typeahead(keyboard.key, cursor(), active));
474
+ }
475
+ });
476
+ on(popup, "click", (event) => {
477
+ const item = event.target.closest(selector);
478
+ if (item) {
479
+ if (disabled(item)) event.preventDefault();
480
+ else choose(item);
481
+ }
482
+ });
483
+ on(popup, "pointermove", (event) => {
484
+ const pointer = event, item = event.target.closest(selector);
485
+ if (item && !disabled(item) && (pointer.movementX || pointer.movementY))
486
+ highlight(items().indexOf(item));
487
+ });
488
+ on(search, "input", () => {
489
+ for (const item of popup.querySelectorAll(selector)) {
490
+ const hidden = !item.textContent?.toLocaleLowerCase().includes(search.value.toLocaleLowerCase());
491
+ item.hidden = hidden;
492
+ item.setAttribute("aria-hidden", String(hidden));
493
+ }
494
+ if (!open) show();
495
+ highlight(nextIndex(cursor(), -1, "Home"));
496
+ });
497
+ cleanups.push(() => close());
498
+ }
499
+ }
500
+ if (root.classList.contains("command")) {
501
+ const input = root.querySelector("input"), list = root.querySelector("[role=menu],[role=listbox]");
502
+ let active = 0;
503
+ const items = () => [...list?.querySelectorAll("[role=menuitem],[role=option]") ?? []].filter(
504
+ (item) => !item.hidden
505
+ );
506
+ const refresh = () => {
507
+ const all = items();
508
+ all.forEach((item, index) => item.classList.toggle("active", index === active));
509
+ const current = all[active];
510
+ if (current) input?.setAttribute("aria-activedescendant", current.id);
511
+ };
512
+ on(input, "input", () => {
513
+ list?.querySelectorAll("[role=menuitem],[role=option]").forEach((item) => {
514
+ item.hidden = !item.textContent?.toLocaleLowerCase().includes(input.value.toLocaleLowerCase());
515
+ item.setAttribute("aria-hidden", String(item.hidden));
516
+ });
517
+ active = 0;
518
+ refresh();
519
+ });
520
+ on(input, "keydown", (event) => {
521
+ const key = event.key;
522
+ if (["ArrowUp", "ArrowDown", "Home", "End"].includes(key)) {
523
+ event.preventDefault();
524
+ active = nextIndex(
525
+ items().map((item) => ({ disabled: item.getAttribute("aria-disabled") === "true" })),
526
+ active,
527
+ key
528
+ );
529
+ refresh();
530
+ } else if (key === "Enter") {
531
+ event.preventDefault();
532
+ items()[active]?.click();
533
+ }
534
+ });
535
+ root.refresh = refresh;
536
+ }
537
+ if (root.matches("input[type=range]")) {
538
+ const range = root, update = () => range.style.setProperty(
539
+ "--slider-value",
540
+ `${percentage(range.valueAsNumber, Number(range.min || 0), Number(range.max || 100))}%`
541
+ );
542
+ on(range, "input", update);
543
+ update();
544
+ }
545
+ return () => {
546
+ abort.abort();
547
+ cleanups.forEach((cleanup) => cleanup());
548
+ };
549
+ }
550
+
551
+ // ../core/src/index.ts
552
+ function cx(...values) {
553
+ return values.filter(Boolean).join(" ");
554
+ }
555
+ function percentage(value, min = 0, max = 100) {
556
+ return Number.isFinite(value) && max > min ? Math.min(100, Math.max(0, (value - min) / (max - min) * 100)) : 0;
557
+ }
558
+ function nextIndex(items, current, key, loop = true) {
559
+ const enabled = items.map((item, index) => item.disabled ? -1 : index).filter((index) => index >= 0);
560
+ if (!enabled.length) return -1;
561
+ if (key === "Home") return enabled[0];
562
+ if (key === "End") return enabled[enabled.length - 1];
563
+ const direction = key === "ArrowUp" || key === "ArrowLeft" ? -1 : 1;
564
+ const position = enabled.indexOf(current);
565
+ if (position < 0) return direction < 0 ? enabled[enabled.length - 1] : enabled[0];
566
+ const next = position + direction;
567
+ return enabled[loop ? (next + enabled.length) % enabled.length : Math.min(enabled.length - 1, Math.max(0, next))];
568
+ }
569
+ function createTypeahead() {
570
+ let buffer = "", last = 0;
571
+ return (key, items, current) => {
572
+ const now = Date.now();
573
+ buffer = now - last > 700 ? key : buffer + key;
574
+ last = now;
575
+ const query = [...buffer].every((char) => char === buffer[0]) ? buffer[0] : buffer;
576
+ for (let offset = 1; offset <= items.length; offset++) {
577
+ const index = (current + offset + items.length) % items.length;
578
+ if (!items[index].disabled && items[index].label.toLocaleLowerCase().startsWith(query.toLocaleLowerCase()))
579
+ return index;
580
+ }
581
+ return current;
582
+ };
583
+ }
584
+ var stacks = /* @__PURE__ */ new WeakMap();
585
+ function dismissableLayer(doc, layer) {
586
+ let stack = stacks.get(doc);
587
+ if (!stack) {
588
+ const layers = [];
589
+ const pointer = (event) => {
590
+ const top = layers.at(-1);
591
+ if (top && !top.elements().some((el) => el && event.composedPath().includes(el)))
592
+ top.dismiss("outside");
593
+ };
594
+ const keyboard = (event) => {
595
+ if (event.key === "Escape" && !event.defaultPrevented && layers.length) {
596
+ event.preventDefault();
597
+ event.stopPropagation();
598
+ layers.at(-1)?.dismiss("escape");
599
+ }
600
+ };
601
+ doc.addEventListener("pointerdown", pointer, true);
602
+ doc.addEventListener("keydown", keyboard);
603
+ stack = {
604
+ layers,
605
+ dispose: () => {
606
+ doc.removeEventListener("pointerdown", pointer, true);
607
+ doc.removeEventListener("keydown", keyboard);
608
+ }
609
+ };
610
+ stacks.set(doc, stack);
611
+ }
612
+ stack.layers.push(layer);
613
+ return () => {
614
+ const index = stack.layers.indexOf(layer);
615
+ if (index >= 0) stack.layers.splice(index, 1);
616
+ if (!stack.layers.length) {
617
+ stack.dispose();
618
+ stacks.delete(doc);
619
+ }
620
+ };
621
+ }
622
+ function floatingPosition(anchor, popup, width, height, options = {}) {
623
+ let side = options.side ?? "bottom";
624
+ const align = options.align ?? "start", offset = options.offset ?? 6, padding = 8;
625
+ const available = {
626
+ bottom: height - anchor.bottom,
627
+ top: anchor.top,
628
+ right: width - anchor.right,
629
+ left: anchor.left
630
+ };
631
+ const opposite = {
632
+ top: "bottom",
633
+ bottom: "top",
634
+ left: "right",
635
+ right: "left"
636
+ };
637
+ const required = (side === "top" || side === "bottom" ? popup.height : popup.width) + offset + padding;
638
+ if (available[side] < required && available[opposite[side]] > available[side])
639
+ side = opposite[side];
640
+ const vertical = side === "top" || side === "bottom";
641
+ let x = vertical ? anchor.left : side === "left" ? anchor.left - popup.width - offset : anchor.right + offset;
642
+ let y = vertical ? side === "top" ? anchor.top - popup.height - offset : anchor.bottom + offset : anchor.top;
643
+ if (vertical)
644
+ x += align === "end" ? anchor.width - popup.width : align === "center" ? (anchor.width - popup.width) / 2 : 0;
645
+ else
646
+ y += align === "end" ? anchor.height - popup.height : align === "center" ? (anchor.height - popup.height) / 2 : 0;
647
+ return {
648
+ x: Math.max(padding, Math.min(x, width - popup.width - padding)),
649
+ y: Math.max(padding, Math.min(y, height - popup.height - padding)),
650
+ side,
651
+ maxHeight: Math.max(40, available[side] - offset - padding)
652
+ };
653
+ }
654
+ function attachFloating(anchor, popup, options = {}) {
655
+ const win = anchor.ownerDocument.defaultView;
656
+ if (typeof popup.showPopover === "function") popup.showPopover();
657
+ const update = () => {
658
+ const rect = anchor.getBoundingClientRect();
659
+ if (options.matchWidth) popup.style.minWidth = `${rect.width}px`;
660
+ const viewport = win.visualViewport;
661
+ const result = floatingPosition(
662
+ rect,
663
+ popup.getBoundingClientRect(),
664
+ viewport?.width ?? win.innerWidth,
665
+ viewport?.height ?? win.innerHeight,
666
+ options
667
+ );
668
+ Object.assign(popup.style, {
669
+ left: `${result.x + (viewport?.offsetLeft ?? 0)}px`,
670
+ top: `${result.y + (viewport?.offsetTop ?? 0)}px`,
671
+ maxHeight: `${result.maxHeight}px`
672
+ });
673
+ popup.dataset.side = result.side;
674
+ };
675
+ let frame = 0;
676
+ const schedule = () => {
677
+ win.cancelAnimationFrame(frame);
678
+ frame = win.requestAnimationFrame(update);
679
+ };
680
+ const observer = typeof win.ResizeObserver === "function" ? new win.ResizeObserver(schedule) : null;
681
+ observer?.observe(anchor);
682
+ observer?.observe(popup);
683
+ win.addEventListener("resize", schedule);
684
+ win.addEventListener("scroll", schedule, true);
685
+ win.visualViewport?.addEventListener("resize", schedule);
686
+ win.visualViewport?.addEventListener("scroll", schedule);
687
+ update();
688
+ return () => {
689
+ win.cancelAnimationFrame(frame);
690
+ observer?.disconnect();
691
+ win.removeEventListener("resize", schedule);
692
+ win.removeEventListener("scroll", schedule, true);
693
+ win.visualViewport?.removeEventListener("resize", schedule);
694
+ win.visualViewport?.removeEventListener("scroll", schedule);
695
+ if (typeof popup.hidePopover === "function" && popup.matches(":popover-open"))
696
+ popup.hidePopover();
697
+ };
698
+ }
699
+ var scrollLocks = /* @__PURE__ */ new WeakMap();
700
+ function lockScroll(doc) {
701
+ const record = scrollLocks.get(doc) ?? { count: 0, overflow: doc.documentElement.style.overflow };
702
+ record.count++;
703
+ scrollLocks.set(doc, record);
704
+ doc.documentElement.style.overflow = "hidden";
705
+ let disposed = false;
706
+ return () => {
707
+ if (disposed) return;
708
+ disposed = true;
709
+ if (--record.count === 0) {
710
+ doc.documentElement.style.overflow = record.overflow;
711
+ scrollLocks.delete(doc);
712
+ }
713
+ };
714
+ }
715
+ function focusFirst(root) {
716
+ const target = root.querySelector(
717
+ '[autofocus],button:not(:disabled),[href],input:not(:disabled),select:not(:disabled),textarea:not(:disabled),[tabindex="0"]'
718
+ );
719
+ (target ?? root).focus({ preventScroll: true });
720
+ }
721
+ function scrollWithin(container, item) {
722
+ const parent = container.scrollHeight > container.clientHeight ? container : container.parentElement ?? container;
723
+ const outer = parent.getBoundingClientRect(), inner = item.getBoundingClientRect();
724
+ if (inner.top < outer.top) parent.scrollTop -= outer.top - inner.top;
725
+ else if (inner.bottom > outer.bottom) parent.scrollTop += inner.bottom - outer.bottom;
726
+ }
727
+ function formReset(element, reset) {
728
+ const form = element.closest("form");
729
+ let timer;
730
+ const listener = (event) => {
731
+ clearTimeout(timer);
732
+ timer = setTimeout(() => {
733
+ if (!event.defaultPrevented) reset();
734
+ }, 0);
735
+ };
736
+ form?.addEventListener("reset", listener);
737
+ return () => {
738
+ clearTimeout(timer);
739
+ form?.removeEventListener("reset", listener);
740
+ };
741
+ }
742
+ var primitiveDefinitions = {
743
+ ChartRoot: ["canvas", "chart-canvas"],
744
+ SelectRoot: ["div", "select"],
745
+ ComboboxRoot: ["div", "combobox"],
746
+ DropdownMenuRoot: ["div", "dropdown-menu"],
747
+ PopoverRoot: ["div", "popover"],
748
+ TabsRoot: ["div", "tabs"],
749
+ AccordionRoot: ["div", "accordion"],
750
+ CommandRoot: ["div", "command"],
751
+ SidebarRoot: ["div", "sidebar"],
752
+ DialogRoot: ["dialog", "dialog"],
753
+ DrawerRoot: ["dialog", "drawer"],
754
+ AlertDialogRoot: ["dialog", "alert-dialog"],
755
+ Button: ["button", "btn"],
756
+ Badge: ["span", "badge"],
757
+ Card: ["article", "card"],
758
+ CardHeader: ["header", ""],
759
+ CardTitle: ["h3", "card-title"],
760
+ CardDescription: ["p", ""],
761
+ CardContent: ["section", ""],
762
+ CardFooter: ["footer", ""],
763
+ CardAction: ["div", "card-action"],
764
+ Alert: ["div", "alert"],
765
+ AlertTitle: ["h2", ""],
766
+ AlertDescription: ["section", ""],
767
+ Avatar: ["span", "avatar"],
768
+ AvatarImage: ["img", ""],
769
+ AvatarFallback: ["span", ""],
770
+ Breadcrumb: ["nav", "breadcrumb"],
771
+ BreadcrumbList: ["ol", ""],
772
+ BreadcrumbItem: ["li", ""],
773
+ BreadcrumbLink: ["a", ""],
774
+ BreadcrumbSeparator: ["li", ""],
775
+ ButtonGroup: ["div", "button-group"],
776
+ Field: ["div", "field"],
777
+ FieldLabel: ["label", "label"],
778
+ FieldDescription: ["p", ""],
779
+ FieldError: ["p", ""],
780
+ Label: ["label", "label"],
781
+ Input: ["input", "input"],
782
+ Textarea: ["textarea", "textarea"],
783
+ NativeSelect: ["select", "select"],
784
+ InputGroup: ["div", "input-group"],
785
+ InputGroupAddon: ["div", ""],
786
+ Empty: ["div", "empty"],
787
+ EmptyHeader: ["header", ""],
788
+ EmptyTitle: ["h3", ""],
789
+ EmptyDescription: ["p", ""],
790
+ EmptyContent: ["section", ""],
791
+ Item: ["div", "item"],
792
+ ItemContent: ["section", ""],
793
+ ItemTitle: ["h3", ""],
794
+ ItemDescription: ["p", ""],
795
+ ItemActions: ["div", ""],
796
+ Kbd: ["kbd", "kbd"],
797
+ ScrollArea: ["div", "scrollbar"],
798
+ Skeleton: ["div", "skeleton"],
799
+ Spinner: ["span", "bc-spinner"],
800
+ Separator: ["hr", ""],
801
+ Table: ["table", "table"],
802
+ TableHeader: ["thead", ""],
803
+ TableBody: ["tbody", ""],
804
+ TableFooter: ["tfoot", ""],
805
+ TableRow: ["tr", ""],
806
+ TableHead: ["th", ""],
807
+ TableCell: ["td", ""],
808
+ TableCaption: ["caption", ""],
809
+ DialogHeader: ["header", ""],
810
+ DialogTitle: ["h2", ""],
811
+ DialogDescription: ["p", ""],
812
+ DialogContent: ["section", ""],
813
+ DialogFooter: ["footer", ""],
814
+ SidebarHeader: ["header", ""],
815
+ SidebarContent: ["section", ""],
816
+ SidebarFooter: ["footer", ""],
817
+ SidebarGroup: ["section", ""],
818
+ SidebarItem: ["a", ""]
819
+ };
820
+
821
+ // src/primitives.tsx
822
+ function primitive(name, tag) {
823
+ const Component = forwardRef((props, ref) => {
824
+ const local = useRef(null);
825
+ useEffect(
826
+ () => name.endsWith("Root") && local.current ? attachWidget(local.current) : void 0,
827
+ [props.as]
828
+ );
829
+ const composedRef = (element) => {
830
+ local.current = element;
831
+ if (typeof ref === "function") ref(element);
832
+ else if (ref) ref.current = element;
833
+ };
834
+ const { className, variant, size, asChild, as, children, ...rest } = props;
835
+ const attributes = {
836
+ ...rest,
837
+ ref: composedRef,
838
+ className: cx(primitiveDefinitions[name][1], className)
839
+ };
840
+ if (variant !== void 0) attributes["data-variant"] = variant;
841
+ if (size !== void 0) attributes["data-size"] = size;
842
+ if (tag === "button") attributes.type ??= "button";
843
+ if (name === "Alert") attributes.role ??= "alert";
844
+ if (name === "Breadcrumb") attributes["aria-label"] ??= "Breadcrumb";
845
+ if (name === "BreadcrumbSeparator") {
846
+ attributes["aria-hidden"] = true;
847
+ attributes.role = "presentation";
848
+ }
849
+ if (name === "Skeleton") attributes["aria-hidden"] = true;
850
+ if (name === "Spinner") {
851
+ attributes.role ??= "status";
852
+ attributes["aria-label"] ??= "Loading";
853
+ }
854
+ if (name === "FieldError") attributes.role ??= "alert";
855
+ if (name === "ScrollArea") attributes.style = { overflow: "auto", ...rest.style ?? {} };
856
+ if (asChild) {
857
+ if (!isValidElement(children))
858
+ throw new Error(`${name} with asChild expects a single element.`);
859
+ const child = children;
860
+ const merged = {
861
+ ...attributes,
862
+ ...child.props,
863
+ className: cx(attributes.className, child.props.className)
864
+ };
865
+ for (const key of Object.keys(attributes)) {
866
+ if (key.startsWith("on") && typeof attributes[key] === "function" && typeof child.props[key] === "function") {
867
+ merged[key] = (event) => {
868
+ child.props[key](event);
869
+ if (!event.defaultPrevented) attributes[key](event);
870
+ };
871
+ }
872
+ }
873
+ const childRef = child.props.ref;
874
+ merged.ref = (element) => {
875
+ composedRef(element);
876
+ if (typeof childRef === "function") childRef(element);
877
+ else if (childRef && typeof childRef === "object")
878
+ childRef.current = element;
879
+ };
880
+ return cloneElement(child, merged);
881
+ }
882
+ return createElement(as ?? tag, attributes, children);
883
+ });
884
+ Component.displayName = name;
885
+ return Component;
886
+ }
887
+
888
+ // src/components/ChartRoot.tsx
889
+ var ChartRoot = /* @__PURE__ */ primitive("ChartRoot", "canvas");
890
+
891
+ // src/components/SelectRoot.tsx
892
+ var SelectRoot = /* @__PURE__ */ primitive("SelectRoot", "div");
893
+
894
+ // src/components/ComboboxRoot.tsx
895
+ var ComboboxRoot = /* @__PURE__ */ primitive("ComboboxRoot", "div");
896
+
897
+ // src/components/DropdownMenuRoot.tsx
898
+ var DropdownMenuRoot = /* @__PURE__ */ primitive("DropdownMenuRoot", "div");
899
+
900
+ // src/components/PopoverRoot.tsx
901
+ var PopoverRoot = /* @__PURE__ */ primitive("PopoverRoot", "div");
902
+
903
+ // src/components/TabsRoot.tsx
904
+ var TabsRoot = /* @__PURE__ */ primitive("TabsRoot", "div");
905
+
906
+ // src/components/AccordionRoot.tsx
907
+ var AccordionRoot = /* @__PURE__ */ primitive("AccordionRoot", "div");
908
+
909
+ // src/components/CommandRoot.tsx
910
+ var CommandRoot = /* @__PURE__ */ primitive("CommandRoot", "div");
911
+
912
+ // src/components/SidebarRoot.tsx
913
+ var SidebarRoot = /* @__PURE__ */ primitive("SidebarRoot", "div");
914
+
915
+ // src/components/DialogRoot.tsx
916
+ var DialogRoot = /* @__PURE__ */ primitive("DialogRoot", "dialog");
917
+
918
+ // src/components/DrawerRoot.tsx
919
+ var DrawerRoot = /* @__PURE__ */ primitive("DrawerRoot", "dialog");
920
+
921
+ // src/components/AlertDialogRoot.tsx
922
+ var AlertDialogRoot = /* @__PURE__ */ primitive("AlertDialogRoot", "dialog");
923
+
924
+ // src/components/Button.tsx
925
+ var Button = /* @__PURE__ */ primitive("Button", "button");
926
+
927
+ // src/components/Badge.tsx
928
+ var Badge = /* @__PURE__ */ primitive("Badge", "span");
929
+
930
+ // src/components/Card.tsx
931
+ var Card = /* @__PURE__ */ primitive("Card", "article");
932
+
933
+ // src/components/CardHeader.tsx
934
+ var CardHeader = /* @__PURE__ */ primitive("CardHeader", "header");
935
+
936
+ // src/components/CardTitle.tsx
937
+ var CardTitle = /* @__PURE__ */ primitive("CardTitle", "h3");
938
+
939
+ // src/components/CardDescription.tsx
940
+ var CardDescription = /* @__PURE__ */ primitive("CardDescription", "p");
941
+
942
+ // src/components/CardContent.tsx
943
+ var CardContent = /* @__PURE__ */ primitive("CardContent", "section");
944
+
945
+ // src/components/CardFooter.tsx
946
+ var CardFooter = /* @__PURE__ */ primitive("CardFooter", "footer");
947
+
948
+ // src/components/CardAction.tsx
949
+ var CardAction = /* @__PURE__ */ primitive("CardAction", "div");
950
+
951
+ // src/components/Alert.tsx
952
+ var Alert = /* @__PURE__ */ primitive("Alert", "div");
953
+
954
+ // src/components/AlertTitle.tsx
955
+ var AlertTitle = /* @__PURE__ */ primitive("AlertTitle", "h2");
956
+
957
+ // src/components/AlertDescription.tsx
958
+ var AlertDescription = /* @__PURE__ */ primitive("AlertDescription", "section");
959
+
960
+ // src/components/Avatar.tsx
961
+ var Avatar = /* @__PURE__ */ primitive("Avatar", "span");
962
+
963
+ // src/components/AvatarImage.tsx
964
+ var AvatarImage = /* @__PURE__ */ primitive("AvatarImage", "img");
965
+
966
+ // src/components/AvatarFallback.tsx
967
+ var AvatarFallback = /* @__PURE__ */ primitive("AvatarFallback", "span");
968
+
969
+ // src/components/Breadcrumb.tsx
970
+ var Breadcrumb = /* @__PURE__ */ primitive("Breadcrumb", "nav");
971
+
972
+ // src/components/BreadcrumbList.tsx
973
+ var BreadcrumbList = /* @__PURE__ */ primitive("BreadcrumbList", "ol");
974
+
975
+ // src/components/BreadcrumbItem.tsx
976
+ var BreadcrumbItem = /* @__PURE__ */ primitive("BreadcrumbItem", "li");
977
+
978
+ // src/components/BreadcrumbLink.tsx
979
+ var BreadcrumbLink = /* @__PURE__ */ primitive("BreadcrumbLink", "a");
980
+
981
+ // src/components/BreadcrumbSeparator.tsx
982
+ var BreadcrumbSeparator = /* @__PURE__ */ primitive("BreadcrumbSeparator", "li");
983
+
984
+ // src/components/ButtonGroup.tsx
985
+ var ButtonGroup = /* @__PURE__ */ primitive("ButtonGroup", "div");
986
+
987
+ // src/components/Field.tsx
988
+ var Field = /* @__PURE__ */ primitive("Field", "div");
989
+
990
+ // src/components/FieldLabel.tsx
991
+ var FieldLabel = /* @__PURE__ */ primitive("FieldLabel", "label");
992
+
993
+ // src/components/FieldDescription.tsx
994
+ var FieldDescription = /* @__PURE__ */ primitive("FieldDescription", "p");
995
+
996
+ // src/components/FieldError.tsx
997
+ var FieldError = /* @__PURE__ */ primitive("FieldError", "p");
998
+
999
+ // src/components/Label.tsx
1000
+ var Label = /* @__PURE__ */ primitive("Label", "label");
1001
+
1002
+ // src/components/Input.tsx
1003
+ var Input = /* @__PURE__ */ primitive("Input", "input");
1004
+
1005
+ // src/components/Textarea.tsx
1006
+ var Textarea = /* @__PURE__ */ primitive("Textarea", "textarea");
1007
+
1008
+ // src/components/NativeSelect.tsx
1009
+ var NativeSelect = /* @__PURE__ */ primitive("NativeSelect", "select");
1010
+
1011
+ // src/components/InputGroup.tsx
1012
+ var InputGroup = /* @__PURE__ */ primitive("InputGroup", "div");
1013
+
1014
+ // src/components/InputGroupAddon.tsx
1015
+ var InputGroupAddon = /* @__PURE__ */ primitive("InputGroupAddon", "div");
1016
+
1017
+ // src/components/Empty.tsx
1018
+ var Empty = /* @__PURE__ */ primitive("Empty", "div");
1019
+
1020
+ // src/components/EmptyHeader.tsx
1021
+ var EmptyHeader = /* @__PURE__ */ primitive("EmptyHeader", "header");
1022
+
1023
+ // src/components/EmptyTitle.tsx
1024
+ var EmptyTitle = /* @__PURE__ */ primitive("EmptyTitle", "h3");
1025
+
1026
+ // src/components/EmptyDescription.tsx
1027
+ var EmptyDescription = /* @__PURE__ */ primitive("EmptyDescription", "p");
1028
+
1029
+ // src/components/EmptyContent.tsx
1030
+ var EmptyContent = /* @__PURE__ */ primitive("EmptyContent", "section");
1031
+
1032
+ // src/components/Item.tsx
1033
+ var Item = /* @__PURE__ */ primitive("Item", "div");
1034
+
1035
+ // src/components/ItemContent.tsx
1036
+ var ItemContent = /* @__PURE__ */ primitive("ItemContent", "section");
1037
+
1038
+ // src/components/ItemTitle.tsx
1039
+ var ItemTitle = /* @__PURE__ */ primitive("ItemTitle", "h3");
1040
+
1041
+ // src/components/ItemDescription.tsx
1042
+ var ItemDescription = /* @__PURE__ */ primitive("ItemDescription", "p");
1043
+
1044
+ // src/components/ItemActions.tsx
1045
+ var ItemActions = /* @__PURE__ */ primitive("ItemActions", "div");
1046
+
1047
+ // src/components/Kbd.tsx
1048
+ var Kbd = /* @__PURE__ */ primitive("Kbd", "kbd");
1049
+
1050
+ // src/components/ScrollArea.tsx
1051
+ var ScrollArea = /* @__PURE__ */ primitive("ScrollArea", "div");
1052
+
1053
+ // src/components/Skeleton.tsx
1054
+ var Skeleton = /* @__PURE__ */ primitive("Skeleton", "div");
1055
+
1056
+ // src/components/Spinner.tsx
1057
+ var Spinner = /* @__PURE__ */ primitive("Spinner", "span");
1058
+
1059
+ // src/components/Separator.tsx
1060
+ var Separator = /* @__PURE__ */ primitive("Separator", "hr");
1061
+
1062
+ // src/components/Table.tsx
1063
+ var Table = /* @__PURE__ */ primitive("Table", "table");
1064
+
1065
+ // src/components/TableHeader.tsx
1066
+ var TableHeader = /* @__PURE__ */ primitive("TableHeader", "thead");
1067
+
1068
+ // src/components/TableBody.tsx
1069
+ var TableBody = /* @__PURE__ */ primitive("TableBody", "tbody");
1070
+
1071
+ // src/components/TableFooter.tsx
1072
+ var TableFooter = /* @__PURE__ */ primitive("TableFooter", "tfoot");
1073
+
1074
+ // src/components/TableRow.tsx
1075
+ var TableRow = /* @__PURE__ */ primitive("TableRow", "tr");
1076
+
1077
+ // src/components/TableHead.tsx
1078
+ var TableHead = /* @__PURE__ */ primitive("TableHead", "th");
1079
+
1080
+ // src/components/TableCell.tsx
1081
+ var TableCell = /* @__PURE__ */ primitive("TableCell", "td");
1082
+
1083
+ // src/components/TableCaption.tsx
1084
+ var TableCaption = /* @__PURE__ */ primitive("TableCaption", "caption");
1085
+
1086
+ // src/components/DialogHeader.tsx
1087
+ var DialogHeader = /* @__PURE__ */ primitive("DialogHeader", "header");
1088
+
1089
+ // src/components/DialogTitle.tsx
1090
+ var DialogTitle = /* @__PURE__ */ primitive("DialogTitle", "h2");
1091
+
1092
+ // src/components/DialogDescription.tsx
1093
+ var DialogDescription = /* @__PURE__ */ primitive("DialogDescription", "p");
1094
+
1095
+ // src/components/DialogContent.tsx
1096
+ var DialogContent = /* @__PURE__ */ primitive("DialogContent", "section");
1097
+
1098
+ // src/components/DialogFooter.tsx
1099
+ var DialogFooter = /* @__PURE__ */ primitive("DialogFooter", "footer");
1100
+
1101
+ // src/components/SidebarHeader.tsx
1102
+ var SidebarHeader = /* @__PURE__ */ primitive("SidebarHeader", "header");
1103
+
1104
+ // src/components/SidebarContent.tsx
1105
+ var SidebarContent = /* @__PURE__ */ primitive("SidebarContent", "section");
1106
+
1107
+ // src/components/SidebarFooter.tsx
1108
+ var SidebarFooter = /* @__PURE__ */ primitive("SidebarFooter", "footer");
1109
+
1110
+ // src/components/SidebarGroup.tsx
1111
+ var SidebarGroup = /* @__PURE__ */ primitive("SidebarGroup", "section");
1112
+
1113
+ // src/components/SidebarItem.tsx
1114
+ var SidebarItem = /* @__PURE__ */ primitive("SidebarItem", "a");
1115
+
1116
+ // src/components/Checkbox.tsx
1117
+ import { forwardRef as forwardRef2, useEffect as useEffect3, useRef as useRef3 } from "react";
1118
+
1119
+ // src/hooks.ts
1120
+ import { useCallback, useEffect as useEffect2, useRef as useRef2, useState } from "react";
1121
+ function useValue(value, defaultValue, onChange) {
1122
+ const [internal, setInternal] = useState(defaultValue);
1123
+ const current = value === void 0 ? internal : value;
1124
+ const latest = useRef2({ value, current, onChange });
1125
+ latest.current = { value, current, onChange };
1126
+ const set = useCallback((next) => {
1127
+ if (Object.is(latest.current.current, next)) return;
1128
+ if (latest.current.value === void 0) setInternal(next);
1129
+ latest.current.onChange?.(next);
1130
+ }, []);
1131
+ return [current, set];
1132
+ }
1133
+ function useLatest(value) {
1134
+ const ref = useRef2(value);
1135
+ ref.current = value;
1136
+ return ref;
1137
+ }
1138
+ function useFloating(open, close, options = {}) {
1139
+ const anchor = useRef2(null), popup = useRef2(null);
1140
+ const latest = useLatest(close);
1141
+ useEffect2(() => {
1142
+ if (!open || !anchor.current || !popup.current) return;
1143
+ const trigger = anchor.current, content = popup.current;
1144
+ const position = attachFloating(trigger, content, options);
1145
+ const layer = dismissableLayer(trigger.ownerDocument, {
1146
+ elements: () => [trigger, content],
1147
+ dismiss: (reason) => latest.current(reason === "escape")
1148
+ });
1149
+ return () => {
1150
+ layer();
1151
+ position();
1152
+ };
1153
+ }, [open, options.side, options.align, options.offset, options.matchWidth]);
1154
+ return { anchor, popup };
1155
+ }
1156
+
1157
+ // src/components/Checkbox.tsx
1158
+ import { jsx } from "react/jsx-runtime";
1159
+ var Checkbox = forwardRef2(
1160
+ ({
1161
+ checked,
1162
+ defaultChecked = false,
1163
+ onCheckedChange,
1164
+ indeterminate = false,
1165
+ className,
1166
+ onChange,
1167
+ ...props
1168
+ }, forwarded) => {
1169
+ const ref = useRef3(null);
1170
+ const [value, set] = useValue(checked, defaultChecked, onCheckedChange);
1171
+ useEffect3(() => {
1172
+ if (ref.current) ref.current.indeterminate = indeterminate;
1173
+ }, [indeterminate]);
1174
+ useEffect3(
1175
+ () => ref.current ? formReset(ref.current, () => set(defaultChecked)) : void 0,
1176
+ [defaultChecked, set]
1177
+ );
1178
+ return /* @__PURE__ */ jsx(
1179
+ "input",
1180
+ {
1181
+ ...props,
1182
+ className: cx("input", className),
1183
+ type: "checkbox",
1184
+ checked: value,
1185
+ ref: (element) => {
1186
+ ref.current = element;
1187
+ if (typeof forwarded === "function") forwarded(element);
1188
+ else if (forwarded) forwarded.current = element;
1189
+ },
1190
+ onChange: (event) => {
1191
+ onChange?.(event);
1192
+ if (!event.defaultPrevented) set(event.currentTarget.checked);
1193
+ }
1194
+ }
1195
+ );
1196
+ }
1197
+ );
1198
+ Checkbox.displayName = "Checkbox";
1199
+
1200
+ // src/components/Switch.tsx
1201
+ import { forwardRef as forwardRef3 } from "react";
1202
+ import { jsx as jsx2 } from "react/jsx-runtime";
1203
+ var Switch = forwardRef3(
1204
+ (props, ref) => /* @__PURE__ */ jsx2(Checkbox, { ...props, role: "switch", ref })
1205
+ );
1206
+ Switch.displayName = "Switch";
1207
+
1208
+ // src/components/Slider.tsx
1209
+ import { forwardRef as forwardRef4, useEffect as useEffect4, useRef as useRef4 } from "react";
1210
+ import { jsx as jsx3 } from "react/jsx-runtime";
1211
+ var Slider = forwardRef4(
1212
+ ({ value, defaultValue = 0, onValueChange, min = 0, max = 100, onChange, style, ...props }, ref) => {
1213
+ const [current, set] = useValue(value, defaultValue, onValueChange);
1214
+ const local = useRef4(null);
1215
+ useEffect4(
1216
+ () => local.current ? formReset(local.current, () => set(defaultValue)) : void 0,
1217
+ [defaultValue, set]
1218
+ );
1219
+ return /* @__PURE__ */ jsx3(
1220
+ Input,
1221
+ {
1222
+ ...props,
1223
+ ref: (element) => {
1224
+ local.current = element;
1225
+ if (typeof ref === "function") ref(element);
1226
+ else if (ref) ref.current = element;
1227
+ },
1228
+ type: "range",
1229
+ min,
1230
+ max,
1231
+ value: current,
1232
+ style: {
1233
+ ...style,
1234
+ "--slider-value": `${percentage(current, Number(min), Number(max))}%`
1235
+ },
1236
+ onChange: (event) => {
1237
+ onChange?.(event);
1238
+ if (!event.defaultPrevented) set(event.currentTarget.valueAsNumber);
1239
+ }
1240
+ }
1241
+ );
1242
+ }
1243
+ );
1244
+ Slider.displayName = "Slider";
1245
+
1246
+ // src/components/RadioGroup.tsx
1247
+ import { useEffect as useEffect5, useId, useRef as useRef5 } from "react";
1248
+ import { jsx as jsx4, jsxs } from "react/jsx-runtime";
1249
+ function RadioGroup({
1250
+ options,
1251
+ value,
1252
+ defaultValue = "",
1253
+ onValueChange,
1254
+ name,
1255
+ disabled,
1256
+ required,
1257
+ className,
1258
+ ...props
1259
+ }) {
1260
+ const generated = useId(), root = useRef5(null);
1261
+ const [current, set] = useValue(value, defaultValue, onValueChange);
1262
+ useEffect5(
1263
+ () => root.current ? formReset(root.current, () => set(defaultValue)) : void 0,
1264
+ [defaultValue, set]
1265
+ );
1266
+ return /* @__PURE__ */ jsx4("div", { ...props, ref: root, role: "radiogroup", className: cx("bc-radio-group", className), children: options.map((option) => /* @__PURE__ */ jsxs("label", { children: [
1267
+ /* @__PURE__ */ jsx4(
1268
+ "input",
1269
+ {
1270
+ className: "input",
1271
+ type: "radio",
1272
+ name: name ?? generated,
1273
+ value: option.value,
1274
+ checked: current === option.value,
1275
+ disabled: disabled || option.disabled,
1276
+ required,
1277
+ onChange: () => set(option.value)
1278
+ }
1279
+ ),
1280
+ " ",
1281
+ option.label
1282
+ ] }, option.value)) });
1283
+ }
1284
+
1285
+ // src/components/Progress.tsx
1286
+ import { jsx as jsx5 } from "react/jsx-runtime";
1287
+ function Progress({
1288
+ value,
1289
+ max = 100,
1290
+ className,
1291
+ ...props
1292
+ }) {
1293
+ return /* @__PURE__ */ jsx5(
1294
+ "div",
1295
+ {
1296
+ ...props,
1297
+ className: cx("progress", className),
1298
+ role: "progressbar",
1299
+ "aria-valuemin": 0,
1300
+ "aria-valuemax": max,
1301
+ "aria-valuenow": value,
1302
+ "aria-busy": value === void 0,
1303
+ children: /* @__PURE__ */ jsx5("span", { style: { width: value === void 0 ? "100%" : `${percentage(value, 0, max)}%` } })
1304
+ }
1305
+ );
1306
+ }
1307
+
1308
+ // src/components/Tabs.tsx
1309
+ import { useId as useId2, useRef as useRef6 } from "react";
1310
+ import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
1311
+ function Tabs({
1312
+ items,
1313
+ value,
1314
+ defaultValue,
1315
+ onValueChange,
1316
+ orientation = "horizontal",
1317
+ activation = "automatic",
1318
+ variant,
1319
+ renderPanel,
1320
+ keepMounted = false,
1321
+ className,
1322
+ ...props
1323
+ }) {
1324
+ const id = useId2(), refs = useRef6([]);
1325
+ const [current, set] = useValue(
1326
+ value,
1327
+ defaultValue ?? items.find((item) => !item.disabled)?.value ?? "",
1328
+ onValueChange
1329
+ );
1330
+ const active = items.findIndex((item) => item.value === current && !item.disabled);
1331
+ const selected = active >= 0 ? active : items.findIndex((item) => !item.disabled);
1332
+ return /* @__PURE__ */ jsxs2("div", { ...props, className: cx("tabs", className), children: [
1333
+ /* @__PURE__ */ jsx6(
1334
+ "div",
1335
+ {
1336
+ role: "tablist",
1337
+ "aria-label": props["aria-label"],
1338
+ "aria-orientation": orientation,
1339
+ "data-variant": variant,
1340
+ children: items.map((item, index) => /* @__PURE__ */ jsx6(
1341
+ "button",
1342
+ {
1343
+ ref: (el) => {
1344
+ refs.current[index] = el;
1345
+ },
1346
+ type: "button",
1347
+ role: "tab",
1348
+ id: `${id}-tab-${index}`,
1349
+ "aria-controls": `${id}-panel-${index}`,
1350
+ "aria-selected": index === selected,
1351
+ disabled: item.disabled,
1352
+ tabIndex: index === selected ? 0 : -1,
1353
+ onClick: () => set(item.value),
1354
+ onKeyDown: (event) => {
1355
+ const arrows = orientation === "vertical" ? ["ArrowUp", "ArrowDown"] : ["ArrowLeft", "ArrowRight"];
1356
+ if (!arrows.includes(event.key) && !["Home", "End"].includes(event.key)) return;
1357
+ event.preventDefault();
1358
+ const key = orientation === "horizontal" && event.currentTarget.closest('[dir="rtl"]') ? event.key === "ArrowLeft" ? "ArrowRight" : event.key === "ArrowRight" ? "ArrowLeft" : event.key : event.key;
1359
+ const next = nextIndex(items, index, key);
1360
+ refs.current[next]?.focus();
1361
+ if (activation === "automatic" && next >= 0) set(items[next].value);
1362
+ },
1363
+ children: item.label
1364
+ },
1365
+ item.value
1366
+ ))
1367
+ }
1368
+ ),
1369
+ items.map((item, index) => /* @__PURE__ */ jsx6(
1370
+ "div",
1371
+ {
1372
+ role: "tabpanel",
1373
+ id: `${id}-panel-${index}`,
1374
+ "aria-labelledby": `${id}-tab-${index}`,
1375
+ tabIndex: 0,
1376
+ hidden: index !== selected,
1377
+ children: keepMounted || index === selected ? renderPanel(item) : null
1378
+ },
1379
+ item.value
1380
+ ))
1381
+ ] });
1382
+ }
1383
+
1384
+ // src/components/Accordion.tsx
1385
+ import { useRef as useRef7 } from "react";
1386
+ import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
1387
+ function Accordion({
1388
+ items,
1389
+ value,
1390
+ defaultValue = [],
1391
+ onValueChange,
1392
+ multiple = false,
1393
+ renderPanel,
1394
+ className,
1395
+ ...props
1396
+ }) {
1397
+ const [current, set] = useValue(value, defaultValue, onValueChange);
1398
+ const refs = useRef7([]);
1399
+ return /* @__PURE__ */ jsx7("div", { ...props, className: cx("accordion", className), children: items.map((item, index) => /* @__PURE__ */ jsxs3(
1400
+ "details",
1401
+ {
1402
+ open: current.includes(item.value),
1403
+ "aria-disabled": item.disabled || void 0,
1404
+ children: [
1405
+ /* @__PURE__ */ jsxs3(
1406
+ "summary",
1407
+ {
1408
+ ref: (el) => {
1409
+ refs.current[index] = el;
1410
+ },
1411
+ "aria-disabled": item.disabled || void 0,
1412
+ tabIndex: item.disabled ? -1 : 0,
1413
+ onClick: (event) => {
1414
+ event.preventDefault();
1415
+ if (!item.disabled)
1416
+ set(
1417
+ current.includes(item.value) ? current.filter((key) => key !== item.value) : multiple ? [...current, item.value] : [item.value]
1418
+ );
1419
+ },
1420
+ onKeyDown: (event) => {
1421
+ if (["ArrowUp", "ArrowDown", "Home", "End"].includes(event.key)) {
1422
+ event.preventDefault();
1423
+ refs.current[nextIndex(items, index, event.key)]?.focus();
1424
+ }
1425
+ },
1426
+ children: [
1427
+ item.label,
1428
+ /* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: "\u2304" })
1429
+ ]
1430
+ }
1431
+ ),
1432
+ /* @__PURE__ */ jsx7("section", { children: renderPanel(item) })
1433
+ ]
1434
+ },
1435
+ item.value
1436
+ )) });
1437
+ }
1438
+
1439
+ // src/components/Collapsible.tsx
1440
+ import { useId as useId3 } from "react";
1441
+ import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
1442
+ function Collapsible({
1443
+ open,
1444
+ defaultOpen = false,
1445
+ onOpenChange,
1446
+ trigger,
1447
+ children,
1448
+ className,
1449
+ ...props
1450
+ }) {
1451
+ const [current, set] = useValue(open, defaultOpen, onOpenChange);
1452
+ const id = useId3();
1453
+ return /* @__PURE__ */ jsxs4("div", { ...props, className: cx("collapsible", className), children: [
1454
+ /* @__PURE__ */ jsx8(
1455
+ Button,
1456
+ {
1457
+ variant: "ghost",
1458
+ "aria-expanded": current,
1459
+ "aria-controls": id,
1460
+ onClick: () => set(!current),
1461
+ children: trigger
1462
+ }
1463
+ ),
1464
+ /* @__PURE__ */ jsx8("div", { id, hidden: !current, children })
1465
+ ] });
1466
+ }
1467
+
1468
+ // src/components/Dialog.tsx
1469
+ import { useEffect as useEffect6, useId as useId4, useRef as useRef8 } from "react";
1470
+ import { Fragment, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
1471
+ function Dialog({
1472
+ open,
1473
+ defaultOpen = false,
1474
+ onOpenChange,
1475
+ trigger,
1476
+ title,
1477
+ description,
1478
+ footer,
1479
+ children,
1480
+ closeOnOutside = true,
1481
+ closeOnEscape = true,
1482
+ closeLabel = "Close",
1483
+ kind = "dialog",
1484
+ side = "right",
1485
+ className,
1486
+ ...props
1487
+ }) {
1488
+ const [current, set] = useValue(open, defaultOpen, onOpenChange);
1489
+ const ref = useRef8(null), id = useId4();
1490
+ const latest = useLatest(current);
1491
+ useEffect6(() => {
1492
+ const dialog = ref.current;
1493
+ if (!current) {
1494
+ if (dialog.open) dialog.close();
1495
+ return;
1496
+ }
1497
+ if (!dialog.open) dialog.showModal();
1498
+ const unlock = lockScroll(dialog.ownerDocument);
1499
+ return () => {
1500
+ unlock();
1501
+ if (dialog.open) dialog.close();
1502
+ };
1503
+ }, [current]);
1504
+ return /* @__PURE__ */ jsxs5(Fragment, { children: [
1505
+ trigger !== void 0 && /* @__PURE__ */ jsx9(Button, { variant: "outline", onClick: () => set(true), children: trigger }),
1506
+ /* @__PURE__ */ jsx9(
1507
+ "dialog",
1508
+ {
1509
+ ...props,
1510
+ className: cx(kind, className),
1511
+ "data-side": kind === "drawer" ? side : void 0,
1512
+ ref,
1513
+ "aria-labelledby": `${id}-title`,
1514
+ "aria-describedby": description ? `${id}-description` : void 0,
1515
+ onCancel: (event) => {
1516
+ event.preventDefault();
1517
+ if (closeOnEscape) set(false);
1518
+ },
1519
+ onClose: () => {
1520
+ if (latest.current) {
1521
+ set(false);
1522
+ queueMicrotask(() => {
1523
+ if (latest.current && ref.current?.isConnected && !ref.current.open)
1524
+ ref.current.showModal();
1525
+ });
1526
+ }
1527
+ },
1528
+ onClick: (event) => {
1529
+ props.onClick?.(event);
1530
+ if (!event.defaultPrevented && closeOnOutside && event.target === event.currentTarget)
1531
+ set(false);
1532
+ },
1533
+ children: /* @__PURE__ */ jsxs5("div", { className: kind === "drawer" ? "bc-drawer-surface" : "bc-dialog-surface", children: [
1534
+ /* @__PURE__ */ jsxs5("header", { children: [
1535
+ /* @__PURE__ */ jsx9("h2", { id: `${id}-title`, children: title }),
1536
+ description && /* @__PURE__ */ jsx9("p", { id: `${id}-description`, children: description })
1537
+ ] }),
1538
+ /* @__PURE__ */ jsx9("section", { children }),
1539
+ footer && /* @__PURE__ */ jsx9("footer", { children: footer }),
1540
+ kind !== "alert-dialog" && /* @__PURE__ */ jsx9(
1541
+ Button,
1542
+ {
1543
+ variant: "ghost",
1544
+ size: "icon-sm",
1545
+ "aria-label": closeLabel,
1546
+ onClick: () => set(false),
1547
+ children: "\xD7"
1548
+ }
1549
+ )
1550
+ ] })
1551
+ }
1552
+ )
1553
+ ] });
1554
+ }
1555
+
1556
+ // src/components/AlertDialog.tsx
1557
+ import { jsx as jsx10 } from "react/jsx-runtime";
1558
+ function AlertDialog(props) {
1559
+ return /* @__PURE__ */ jsx10(Dialog, { ...props, kind: "alert-dialog", role: "alertdialog", closeOnOutside: false });
1560
+ }
1561
+
1562
+ // src/components/Drawer.tsx
1563
+ import { jsx as jsx11 } from "react/jsx-runtime";
1564
+ function Drawer(props) {
1565
+ return /* @__PURE__ */ jsx11(Dialog, { ...props, kind: "drawer" });
1566
+ }
1567
+
1568
+ // src/components/Popover.tsx
1569
+ import { useEffect as useEffect7, useId as useId5 } from "react";
1570
+ import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
1571
+ function Popover({
1572
+ open,
1573
+ defaultOpen = false,
1574
+ onOpenChange,
1575
+ trigger,
1576
+ side,
1577
+ align,
1578
+ label = "Popover",
1579
+ children,
1580
+ className,
1581
+ ...props
1582
+ }) {
1583
+ const [current, set] = useValue(open, defaultOpen, onOpenChange);
1584
+ const id = useId5();
1585
+ const { anchor, popup } = useFloating(
1586
+ current,
1587
+ (restore) => {
1588
+ set(false);
1589
+ if (restore) anchor.current?.focus();
1590
+ },
1591
+ { side, align }
1592
+ );
1593
+ useEffect7(() => {
1594
+ if (current && popup.current) focusFirst(popup.current);
1595
+ }, [current]);
1596
+ return /* @__PURE__ */ jsxs6("div", { ...props, className: cx("popover", className), children: [
1597
+ /* @__PURE__ */ jsx12(
1598
+ Button,
1599
+ {
1600
+ ref: anchor,
1601
+ variant: "outline",
1602
+ "aria-haspopup": "dialog",
1603
+ "aria-expanded": current,
1604
+ "aria-controls": id,
1605
+ onClick: () => set(!current),
1606
+ children: trigger
1607
+ }
1608
+ ),
1609
+ current && /* @__PURE__ */ jsx12(
1610
+ "div",
1611
+ {
1612
+ ref: popup,
1613
+ id,
1614
+ "data-popover": "",
1615
+ popover: "manual",
1616
+ className: "bc-floating",
1617
+ role: "dialog",
1618
+ "aria-label": label,
1619
+ tabIndex: -1,
1620
+ children
1621
+ }
1622
+ )
1623
+ ] });
1624
+ }
1625
+
1626
+ // src/components/Tooltip.tsx
1627
+ import { useEffect as useEffect8, useId as useId6, useRef as useRef9 } from "react";
1628
+ import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
1629
+ function Tooltip({
1630
+ content,
1631
+ children,
1632
+ delay = 300,
1633
+ side = "top"
1634
+ }) {
1635
+ const [open, set] = useValue(void 0, false);
1636
+ const id = useId6();
1637
+ const timer = useRef9(void 0);
1638
+ const { anchor, popup } = useFloating(open, () => set(false), { side, align: "center" });
1639
+ const close = () => {
1640
+ clearTimeout(timer.current);
1641
+ set(false);
1642
+ };
1643
+ useEffect8(() => () => clearTimeout(timer.current), []);
1644
+ return /* @__PURE__ */ jsxs7(
1645
+ "span",
1646
+ {
1647
+ onPointerEnter: () => {
1648
+ timer.current = setTimeout(() => set(true), delay);
1649
+ },
1650
+ onPointerLeave: close,
1651
+ onFocus: () => set(true),
1652
+ onBlur: close,
1653
+ children: [
1654
+ /* @__PURE__ */ jsx13(Button, { asChild: true, ref: anchor, "aria-describedby": open ? id : void 0, children }),
1655
+ open && /* @__PURE__ */ jsx13("div", { ref: popup, id, role: "tooltip", popover: "manual", className: "bc-floating tooltip", children: content })
1656
+ ]
1657
+ }
1658
+ );
1659
+ }
1660
+
1661
+ // src/components/Select.tsx
1662
+ import { useEffect as useEffect9, useId as useId7, useRef as useRef10, useState as useState2 } from "react";
1663
+ import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
1664
+ function Select({
1665
+ options,
1666
+ value,
1667
+ defaultValue,
1668
+ onValueChange,
1669
+ multiple = false,
1670
+ disabled,
1671
+ name,
1672
+ required,
1673
+ placeholder = "Select\u2026",
1674
+ label,
1675
+ searchable = false,
1676
+ searchPlaceholder = "Search\u2026",
1677
+ emptyLabel = "No results",
1678
+ className,
1679
+ ...props
1680
+ }) {
1681
+ const [current, set] = useValue(
1682
+ value,
1683
+ defaultValue ?? (multiple ? [] : ""),
1684
+ onValueChange
1685
+ );
1686
+ const [open, setOpen] = useState2(false), [query, setQuery] = useState2(""), [active, setActive] = useState2(-1);
1687
+ const id = useId7(), list = useRef10(null), search = useRef10(null), native = useRef10(null), typeahead = useRef10(createTypeahead());
1688
+ const visible = options.filter(
1689
+ (option) => !searchable || option.label.toLocaleLowerCase().includes(query.toLocaleLowerCase())
1690
+ );
1691
+ const selected = Array.isArray(current) ? current : [current];
1692
+ const close = (restore) => {
1693
+ setOpen(false);
1694
+ setQuery("");
1695
+ if (restore) anchor.current?.focus();
1696
+ };
1697
+ const { anchor, popup } = useFloating(open, close, { matchWidth: true });
1698
+ useEffect9(() => {
1699
+ if (disabled) setOpen(false);
1700
+ }, [disabled]);
1701
+ useEffect9(() => {
1702
+ if (open) (search.current ?? list.current)?.focus();
1703
+ }, [open]);
1704
+ useEffect9(() => {
1705
+ const item = list.current?.querySelector(`[data-index="${active}"]`);
1706
+ if (list.current && item) scrollWithin(list.current, item);
1707
+ }, [active]);
1708
+ useEffect9(
1709
+ () => native.current ? formReset(native.current, () => set(defaultValue ?? (multiple ? [] : ""))) : void 0,
1710
+ [defaultValue, multiple, set]
1711
+ );
1712
+ const choose = (index) => {
1713
+ const option = visible[index];
1714
+ if (!option || option.disabled) return;
1715
+ set(
1716
+ multiple ? selected.includes(option.value) ? selected.filter((value2) => value2 !== option.value) : [...selected.filter(Boolean), option.value] : option.value
1717
+ );
1718
+ if (!multiple) close(true);
1719
+ };
1720
+ const keyboard = (event) => {
1721
+ if (["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
1722
+ event.preventDefault();
1723
+ setActive(nextIndex(visible, active, event.key));
1724
+ } else if (event.key === "Enter" || !searchable && event.key === " ") {
1725
+ event.preventDefault();
1726
+ choose(active);
1727
+ } else if (event.key === "Tab") close(false);
1728
+ else if (!searchable && event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
1729
+ event.preventDefault();
1730
+ setActive(typeahead.current(event.key, visible, active));
1731
+ }
1732
+ };
1733
+ return /* @__PURE__ */ jsxs8("div", { ...props, className: cx(searchable ? "combobox" : "select", className), children: [
1734
+ /* @__PURE__ */ jsxs8(
1735
+ Button,
1736
+ {
1737
+ ref: anchor,
1738
+ disabled,
1739
+ variant: "outline",
1740
+ role: "combobox",
1741
+ "aria-label": label,
1742
+ "aria-haspopup": "listbox",
1743
+ "aria-expanded": open,
1744
+ "aria-controls": `${id}-list`,
1745
+ "aria-required": required,
1746
+ onClick: () => {
1747
+ setActive(nextIndex(visible, -1, "Home"));
1748
+ setOpen(!open);
1749
+ },
1750
+ onKeyDown: (event) => {
1751
+ if (["ArrowDown", "ArrowUp"].includes(event.key)) {
1752
+ event.preventDefault();
1753
+ setActive(nextIndex(visible, -1, event.key === "ArrowUp" ? "End" : "Home"));
1754
+ setOpen(true);
1755
+ }
1756
+ },
1757
+ children: [
1758
+ /* @__PURE__ */ jsx14("span", { children: options.filter((option) => selected.includes(option.value)).map((option) => option.label).join(", ") || placeholder }),
1759
+ /* @__PURE__ */ jsx14("span", { "aria-hidden": "true", children: "\u2304" })
1760
+ ]
1761
+ }
1762
+ ),
1763
+ open && /* @__PURE__ */ jsxs8("div", { ref: popup, "data-popover": "", popover: "manual", className: "bc-floating", children: [
1764
+ searchable && /* @__PURE__ */ jsx14(
1765
+ Input,
1766
+ {
1767
+ ref: search,
1768
+ className: "bc-search",
1769
+ value: query,
1770
+ role: "combobox",
1771
+ "aria-label": searchPlaceholder,
1772
+ "aria-autocomplete": "list",
1773
+ "aria-expanded": "true",
1774
+ "aria-controls": `${id}-list`,
1775
+ "aria-activedescendant": active >= 0 ? `${id}-option-${active}` : void 0,
1776
+ placeholder: searchPlaceholder,
1777
+ onChange: (event) => {
1778
+ setQuery(event.target.value);
1779
+ setActive(
1780
+ nextIndex(
1781
+ options.filter(
1782
+ (option) => option.label.toLocaleLowerCase().includes(event.target.value.toLocaleLowerCase())
1783
+ ),
1784
+ -1,
1785
+ "Home"
1786
+ )
1787
+ );
1788
+ },
1789
+ onKeyDown: keyboard
1790
+ }
1791
+ ),
1792
+ /* @__PURE__ */ jsx14(
1793
+ "div",
1794
+ {
1795
+ ref: list,
1796
+ id: `${id}-list`,
1797
+ role: "listbox",
1798
+ tabIndex: -1,
1799
+ "aria-label": label,
1800
+ "aria-multiselectable": multiple || void 0,
1801
+ "aria-activedescendant": active >= 0 ? `${id}-option-${active}` : void 0,
1802
+ onKeyDown: searchable ? void 0 : keyboard,
1803
+ "data-empty": emptyLabel,
1804
+ children: visible.map((option, index) => /* @__PURE__ */ jsx14(
1805
+ "div",
1806
+ {
1807
+ id: `${id}-option-${index}`,
1808
+ "data-index": index,
1809
+ "data-value": option.value,
1810
+ role: "option",
1811
+ "aria-selected": selected.includes(option.value),
1812
+ "aria-disabled": option.disabled || void 0,
1813
+ className: index === active ? "active" : void 0,
1814
+ onPointerMove: (event) => {
1815
+ if ((event.movementX || event.movementY) && !option.disabled) setActive(index);
1816
+ },
1817
+ onPointerDown: (event) => event.preventDefault(),
1818
+ onClick: () => choose(index),
1819
+ children: option.label
1820
+ },
1821
+ option.value
1822
+ ))
1823
+ }
1824
+ )
1825
+ ] }),
1826
+ /* @__PURE__ */ jsxs8(
1827
+ "select",
1828
+ {
1829
+ ref: native,
1830
+ className: "bc-form-control",
1831
+ tabIndex: -1,
1832
+ "aria-hidden": "true",
1833
+ name,
1834
+ disabled,
1835
+ required,
1836
+ multiple,
1837
+ value: current,
1838
+ onChange: (event) => set(
1839
+ multiple ? [...event.target.selectedOptions].map((option) => option.value) : event.target.value
1840
+ ),
1841
+ onInvalid: (event) => {
1842
+ event.preventDefault();
1843
+ anchor.current?.focus();
1844
+ anchor.current?.setAttribute("aria-invalid", "true");
1845
+ },
1846
+ children: [
1847
+ !multiple && /* @__PURE__ */ jsx14("option", { value: "", children: placeholder }),
1848
+ options.map((option) => /* @__PURE__ */ jsx14("option", { value: option.value, disabled: option.disabled, children: option.label }, option.value))
1849
+ ]
1850
+ }
1851
+ )
1852
+ ] });
1853
+ }
1854
+
1855
+ // src/components/Combobox.tsx
1856
+ import { jsx as jsx15 } from "react/jsx-runtime";
1857
+ function Combobox(props) {
1858
+ return /* @__PURE__ */ jsx15(Select, { ...props, searchable: true });
1859
+ }
1860
+
1861
+ // src/components/DropdownMenu.tsx
1862
+ import { useEffect as useEffect10, useId as useId8, useRef as useRef11 } from "react";
1863
+ import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
1864
+ function DropdownMenu({
1865
+ items,
1866
+ trigger,
1867
+ onSelect,
1868
+ open,
1869
+ defaultOpen = false,
1870
+ onOpenChange,
1871
+ side,
1872
+ align,
1873
+ label = "Menu",
1874
+ className,
1875
+ ...props
1876
+ }) {
1877
+ const [current, set] = useValue(open, defaultOpen, onOpenChange);
1878
+ const refs = useRef11([]), id = useId8(), initialKey = useRef11("Home"), typeahead = useRef11(createTypeahead());
1879
+ const enabled = items.map((item) => ({ ...item, disabled: item.disabled || item.separator }));
1880
+ const { anchor, popup } = useFloating(
1881
+ current,
1882
+ (restore) => {
1883
+ set(false);
1884
+ if (restore) anchor.current?.focus();
1885
+ },
1886
+ { side, align }
1887
+ );
1888
+ useEffect10(() => {
1889
+ if (current) refs.current[nextIndex(enabled, -1, initialKey.current)]?.focus();
1890
+ }, [current]);
1891
+ return /* @__PURE__ */ jsxs9("div", { ...props, className: cx("dropdown-menu", className), children: [
1892
+ /* @__PURE__ */ jsx16(
1893
+ Button,
1894
+ {
1895
+ ref: anchor,
1896
+ variant: "outline",
1897
+ "aria-haspopup": "menu",
1898
+ "aria-controls": id,
1899
+ "aria-expanded": current,
1900
+ onClick: () => {
1901
+ initialKey.current = "Home";
1902
+ set(!current);
1903
+ },
1904
+ onKeyDown: (event) => {
1905
+ if (["ArrowDown", "ArrowUp"].includes(event.key)) {
1906
+ event.preventDefault();
1907
+ initialKey.current = event.key === "ArrowUp" ? "End" : "Home";
1908
+ set(true);
1909
+ }
1910
+ },
1911
+ children: trigger
1912
+ }
1913
+ ),
1914
+ current && /* @__PURE__ */ jsx16("div", { ref: popup, "data-popover": "", popover: "manual", className: "bc-floating", children: /* @__PURE__ */ jsx16("div", { id, role: "menu", "aria-label": label, children: items.map(
1915
+ (item, index) => item.separator ? /* @__PURE__ */ jsx16("hr", { role: "separator" }, item.value) : /* @__PURE__ */ jsxs9(
1916
+ Button,
1917
+ {
1918
+ as: item.href ? "a" : "button",
1919
+ ...item.href ? { href: item.href } : {},
1920
+ ref: (el) => {
1921
+ refs.current[index] = el;
1922
+ },
1923
+ role: "menuitem",
1924
+ tabIndex: -1,
1925
+ "aria-disabled": item.disabled || void 0,
1926
+ disabled: !item.href && item.disabled,
1927
+ variant: "ghost",
1928
+ onClick: (event) => {
1929
+ if (item.disabled) {
1930
+ event.preventDefault();
1931
+ return;
1932
+ }
1933
+ item.onSelect?.();
1934
+ onSelect?.(item.value);
1935
+ set(false);
1936
+ anchor.current?.focus();
1937
+ },
1938
+ onKeyDown: (event) => {
1939
+ if (["ArrowUp", "ArrowDown", "Home", "End"].includes(event.key)) {
1940
+ event.preventDefault();
1941
+ refs.current[nextIndex(enabled, index, event.key)]?.focus();
1942
+ } else if (event.key === "Tab") set(false);
1943
+ else if (event.key.length === 1 && !event.ctrlKey && !event.metaKey) {
1944
+ refs.current[typeahead.current(event.key, enabled, index)]?.focus();
1945
+ }
1946
+ },
1947
+ children: [
1948
+ item.label,
1949
+ item.shortcut && /* @__PURE__ */ jsx16("kbd", { "data-shortcut": "", children: item.shortcut })
1950
+ ]
1951
+ },
1952
+ item.value
1953
+ )
1954
+ ) }) })
1955
+ ] });
1956
+ }
1957
+
1958
+ // src/components/Command.tsx
1959
+ import { useId as useId9, useState as useState3 } from "react";
1960
+ import { jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
1961
+ function Command({
1962
+ items,
1963
+ onSelect,
1964
+ label = "Commands",
1965
+ placeholder = "Search commands\u2026",
1966
+ emptyLabel = "No results"
1967
+ }) {
1968
+ const [query, setQuery] = useState3(""), [active, setActive] = useState3(0);
1969
+ const id = useId9();
1970
+ const visible = items.filter(
1971
+ (item) => !item.separator && item.label.toLocaleLowerCase().includes(query.toLocaleLowerCase())
1972
+ );
1973
+ const choose = (index) => {
1974
+ const item = visible[index];
1975
+ if (item && !item.disabled) {
1976
+ item.onSelect?.();
1977
+ onSelect?.(item.value);
1978
+ }
1979
+ };
1980
+ return /* @__PURE__ */ jsxs10("div", { className: "command", children: [
1981
+ /* @__PURE__ */ jsx17("header", { children: /* @__PURE__ */ jsx17(
1982
+ Input,
1983
+ {
1984
+ role: "combobox",
1985
+ "aria-label": label,
1986
+ "aria-autocomplete": "list",
1987
+ "aria-expanded": "true",
1988
+ "aria-controls": id,
1989
+ "aria-activedescendant": visible[active] ? `${id}-${active}` : void 0,
1990
+ value: query,
1991
+ placeholder,
1992
+ onChange: (event) => {
1993
+ setQuery(event.target.value);
1994
+ setActive(0);
1995
+ },
1996
+ onKeyDown: (event) => {
1997
+ if (["ArrowDown", "ArrowUp", "Home", "End"].includes(event.key)) {
1998
+ event.preventDefault();
1999
+ setActive(nextIndex(visible, active, event.key));
2000
+ } else if (event.key === "Enter") {
2001
+ event.preventDefault();
2002
+ choose(active);
2003
+ }
2004
+ }
2005
+ }
2006
+ ) }),
2007
+ /* @__PURE__ */ jsxs10("div", { id, role: "listbox", "aria-label": label, children: [
2008
+ visible.map((item, index) => /* @__PURE__ */ jsx17(
2009
+ "div",
2010
+ {
2011
+ id: `${id}-${index}`,
2012
+ role: "option",
2013
+ "aria-selected": index === active,
2014
+ "aria-disabled": item.disabled || void 0,
2015
+ className: index === active ? "active" : void 0,
2016
+ onPointerMove: (event) => {
2017
+ if ((event.movementX || event.movementY) && !item.disabled) setActive(index);
2018
+ },
2019
+ onClick: () => choose(index),
2020
+ children: item.label
2021
+ },
2022
+ item.value
2023
+ )),
2024
+ !visible.length && /* @__PURE__ */ jsx17("p", { role: "status", children: emptyLabel })
2025
+ ] })
2026
+ ] });
2027
+ }
2028
+
2029
+ // src/components/Pagination.tsx
2030
+ import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
2031
+ function Pagination({
2032
+ page,
2033
+ count,
2034
+ onPageChange,
2035
+ label = "Pagination"
2036
+ }) {
2037
+ const total = Math.max(1, Math.floor(count));
2038
+ const current = Math.max(1, Math.min(page, total));
2039
+ return /* @__PURE__ */ jsxs11("nav", { className: "bc-pagination", "aria-label": label, children: [
2040
+ /* @__PURE__ */ jsx18(
2041
+ Button,
2042
+ {
2043
+ variant: "outline",
2044
+ disabled: current === 1,
2045
+ "aria-label": "Previous page",
2046
+ onClick: () => onPageChange(current - 1),
2047
+ children: "\u2039"
2048
+ }
2049
+ ),
2050
+ /* @__PURE__ */ jsxs11("span", { "aria-live": "polite", children: [
2051
+ current,
2052
+ " / ",
2053
+ total
2054
+ ] }),
2055
+ /* @__PURE__ */ jsx18(
2056
+ Button,
2057
+ {
2058
+ variant: "outline",
2059
+ disabled: current === total,
2060
+ "aria-label": "Next page",
2061
+ onClick: () => onPageChange(current + 1),
2062
+ children: "\u203A"
2063
+ }
2064
+ )
2065
+ ] });
2066
+ }
2067
+
2068
+ // src/components/Sidebar.tsx
2069
+ import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
2070
+ function Sidebar({
2071
+ collapsed,
2072
+ defaultCollapsed = false,
2073
+ onCollapsedChange,
2074
+ children,
2075
+ label = "Navigation",
2076
+ className,
2077
+ ...props
2078
+ }) {
2079
+ const [current, set] = useValue(collapsed, defaultCollapsed, onCollapsedChange);
2080
+ return /* @__PURE__ */ jsxs12("aside", { ...props, className: cx("bc-sidebar", className), "data-collapsed": current, children: [
2081
+ /* @__PURE__ */ jsx19(
2082
+ Button,
2083
+ {
2084
+ variant: "ghost",
2085
+ "aria-label": current ? "Expand sidebar" : "Collapse sidebar",
2086
+ "aria-expanded": !current,
2087
+ onClick: () => set(!current),
2088
+ children: "\u2630"
2089
+ }
2090
+ ),
2091
+ /* @__PURE__ */ jsx19("nav", { "aria-label": label, children })
2092
+ ] });
2093
+ }
2094
+
2095
+ // src/components/ThemeSwitcher.tsx
2096
+ import { jsx as jsx20 } from "react/jsx-runtime";
2097
+ function ThemeSwitcher({
2098
+ value,
2099
+ defaultValue = "light",
2100
+ onValueChange,
2101
+ label = "Dark mode"
2102
+ }) {
2103
+ const [current, set] = useValue(value, defaultValue, onValueChange);
2104
+ return /* @__PURE__ */ jsx20(
2105
+ Button,
2106
+ {
2107
+ variant: "outline",
2108
+ role: "switch",
2109
+ "aria-label": label,
2110
+ "aria-checked": current === "dark",
2111
+ onClick: () => set(current === "dark" ? "light" : "dark"),
2112
+ children: current === "dark" ? "\u263E" : "\u2600"
2113
+ }
2114
+ );
2115
+ }
2116
+
2117
+ // src/components/Toast.tsx
2118
+ import { useEffect as useEffect11, useRef as useRef12 } from "react";
2119
+ import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
2120
+ function Toast({ message, dismiss }) {
2121
+ const timer = useRef12(void 0), remaining = useRef12(message.duration ?? 5e3), started = useRef12(0), latest = useRef12(dismiss);
2122
+ latest.current = dismiss;
2123
+ const pause = () => {
2124
+ clearTimeout(timer.current);
2125
+ if (started.current)
2126
+ remaining.current = Math.max(0, remaining.current - (Date.now() - started.current));
2127
+ started.current = 0;
2128
+ };
2129
+ const resume = () => {
2130
+ if ((message.duration ?? 5e3) <= 0 || started.current) return;
2131
+ started.current = Date.now();
2132
+ timer.current = setTimeout(() => latest.current(), remaining.current);
2133
+ };
2134
+ useEffect11(() => {
2135
+ resume();
2136
+ return pause;
2137
+ }, [message.id]);
2138
+ return /* @__PURE__ */ jsx21(
2139
+ "div",
2140
+ {
2141
+ className: "toast",
2142
+ "data-variant": message.variant,
2143
+ onPointerEnter: pause,
2144
+ onPointerLeave: resume,
2145
+ onFocus: pause,
2146
+ onBlur: (event) => {
2147
+ if (!event.currentTarget.contains(event.relatedTarget)) resume();
2148
+ },
2149
+ children: /* @__PURE__ */ jsxs13("div", { className: "toast-content", children: [
2150
+ /* @__PURE__ */ jsxs13("section", { children: [
2151
+ /* @__PURE__ */ jsx21("h2", { children: message.title }),
2152
+ message.description && /* @__PURE__ */ jsx21("p", { children: message.description })
2153
+ ] }),
2154
+ /* @__PURE__ */ jsx21("footer", { children: /* @__PURE__ */ jsx21(
2155
+ Button,
2156
+ {
2157
+ variant: "ghost",
2158
+ size: "icon-sm",
2159
+ "aria-label": "Dismiss notification",
2160
+ onClick: dismiss,
2161
+ children: "\xD7"
2162
+ }
2163
+ ) })
2164
+ ] })
2165
+ }
2166
+ );
2167
+ }
2168
+
2169
+ // src/components/Toaster.tsx
2170
+ import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
2171
+ function Toaster({
2172
+ messages,
2173
+ onDismiss,
2174
+ label = "Notifications"
2175
+ }) {
2176
+ return /* @__PURE__ */ jsxs14("section", { className: "toaster", "aria-label": label, children: [
2177
+ /* @__PURE__ */ jsx22("div", { className: "bc-live", role: "status", "aria-live": "polite", "aria-atomic": "true", children: messages.at(-1)?.title }),
2178
+ messages.map((message) => /* @__PURE__ */ jsx22(Toast, { message, dismiss: () => onDismiss(message.id) }, message.id))
2179
+ ] });
2180
+ }
2181
+
2182
+ // src/components/Chart.tsx
2183
+ import { useId as useId10 } from "react";
2184
+ import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
2185
+ function Chart({
2186
+ data,
2187
+ label,
2188
+ kind = "line"
2189
+ }) {
2190
+ const id = useId10();
2191
+ const finite = data.map((point) => Number.isFinite(point.value) ? point.value : 0), min = Math.min(0, ...finite), max = Math.max(1, ...finite), span = max - min;
2192
+ const y = (value) => 180 - (value - min) / span * 160;
2193
+ return /* @__PURE__ */ jsxs15("figure", { className: "chart", children: [
2194
+ /* @__PURE__ */ jsxs15("svg", { className: "bc-chart", viewBox: "0 0 400 200", role: "img", "aria-labelledby": id, children: [
2195
+ /* @__PURE__ */ jsx23("title", { id, children: label }),
2196
+ kind === "line" ? /* @__PURE__ */ jsx23(
2197
+ "polyline",
2198
+ {
2199
+ fill: "none",
2200
+ stroke: "currentColor",
2201
+ strokeWidth: "3",
2202
+ points: finite.map(
2203
+ (value, index) => `${20 + index / Math.max(1, data.length - 1) * 360},${y(value)}`
2204
+ ).join(" ")
2205
+ }
2206
+ ) : finite.map((value, index) => /* @__PURE__ */ jsx23(
2207
+ "rect",
2208
+ {
2209
+ x: 20 + index / Math.max(1, data.length) * 360,
2210
+ y: Math.min(y(0), y(value)),
2211
+ width: Math.max(1, 360 / Math.max(1, data.length) - 8),
2212
+ height: Math.abs(y(value) - y(0)),
2213
+ fill: "currentColor"
2214
+ },
2215
+ index
2216
+ ))
2217
+ ] }),
2218
+ /* @__PURE__ */ jsx23("figcaption", { children: label }),
2219
+ /* @__PURE__ */ jsxs15("table", { className: "bc-live", children: [
2220
+ /* @__PURE__ */ jsx23("caption", { children: label }),
2221
+ /* @__PURE__ */ jsx23("tbody", { children: data.map((point, index) => /* @__PURE__ */ jsxs15("tr", { children: [
2222
+ /* @__PURE__ */ jsx23("th", { scope: "row", children: point.label }),
2223
+ /* @__PURE__ */ jsx23("td", { children: point.value })
2224
+ ] }, index)) })
2225
+ ] })
2226
+ ] });
2227
+ }
2228
+ export {
2229
+ Accordion,
2230
+ AccordionRoot,
2231
+ Alert,
2232
+ AlertDescription,
2233
+ AlertDialog,
2234
+ AlertDialogRoot,
2235
+ AlertTitle,
2236
+ Avatar,
2237
+ AvatarFallback,
2238
+ AvatarImage,
2239
+ Badge,
2240
+ Breadcrumb,
2241
+ BreadcrumbItem,
2242
+ BreadcrumbLink,
2243
+ BreadcrumbList,
2244
+ BreadcrumbSeparator,
2245
+ Button,
2246
+ ButtonGroup,
2247
+ Card,
2248
+ CardAction,
2249
+ CardContent,
2250
+ CardDescription,
2251
+ CardFooter,
2252
+ CardHeader,
2253
+ CardTitle,
2254
+ Chart,
2255
+ ChartRoot,
2256
+ Checkbox,
2257
+ Collapsible,
2258
+ Combobox,
2259
+ ComboboxRoot,
2260
+ Command,
2261
+ CommandRoot,
2262
+ Dialog,
2263
+ DialogContent,
2264
+ DialogDescription,
2265
+ DialogFooter,
2266
+ DialogHeader,
2267
+ DialogRoot,
2268
+ DialogTitle,
2269
+ Drawer,
2270
+ DrawerRoot,
2271
+ DropdownMenu,
2272
+ DropdownMenuRoot,
2273
+ Empty,
2274
+ EmptyContent,
2275
+ EmptyDescription,
2276
+ EmptyHeader,
2277
+ EmptyTitle,
2278
+ Field,
2279
+ FieldDescription,
2280
+ FieldError,
2281
+ FieldLabel,
2282
+ Input,
2283
+ InputGroup,
2284
+ InputGroupAddon,
2285
+ Item,
2286
+ ItemActions,
2287
+ ItemContent,
2288
+ ItemDescription,
2289
+ ItemTitle,
2290
+ Kbd,
2291
+ Label,
2292
+ NativeSelect,
2293
+ Pagination,
2294
+ Popover,
2295
+ PopoverRoot,
2296
+ Progress,
2297
+ RadioGroup,
2298
+ ScrollArea,
2299
+ Select,
2300
+ SelectRoot,
2301
+ Separator,
2302
+ Sidebar,
2303
+ SidebarContent,
2304
+ SidebarFooter,
2305
+ SidebarGroup,
2306
+ SidebarHeader,
2307
+ SidebarItem,
2308
+ SidebarRoot,
2309
+ Skeleton,
2310
+ Slider,
2311
+ Spinner,
2312
+ Switch,
2313
+ Table,
2314
+ TableBody,
2315
+ TableCaption,
2316
+ TableCell,
2317
+ TableFooter,
2318
+ TableHead,
2319
+ TableHeader,
2320
+ TableRow,
2321
+ Tabs,
2322
+ TabsRoot,
2323
+ Textarea,
2324
+ ThemeSwitcher,
2325
+ Toaster,
2326
+ Tooltip
2327
+ };
2328
+ //# sourceMappingURL=index.js.map