@nuykon/basecoat-react 0.0.0-stage → 1.0.1

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