@boostdev/design-system-components 0.1.2 → 0.1.3

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.
@@ -0,0 +1,2274 @@
1
+ 'use client';
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/client.ts
22
+ var client_exports = {};
23
+ __export(client_exports, {
24
+ Accordion: () => Accordion,
25
+ Alert: () => Alert,
26
+ Avatar: () => Avatar,
27
+ Badge: () => Badge,
28
+ Breadcrumb: () => Breadcrumb,
29
+ Button: () => Button,
30
+ ButtonGroup: () => ButtonGroup,
31
+ Calendar: () => Calendar,
32
+ Card: () => Card,
33
+ Carousel: () => Carousel,
34
+ Checkbox: () => Checkbox,
35
+ Combobox: () => Combobox,
36
+ Command: () => Command,
37
+ DescriptionList: () => DescriptionList,
38
+ Dialog: () => Dialog,
39
+ Drawer: () => Drawer,
40
+ DropdownMenu: () => DropdownMenu,
41
+ FileInput: () => FileInput,
42
+ FormInput: () => FormInput,
43
+ IconWrapper: () => IconWrapper,
44
+ Link: () => Link,
45
+ Loading: () => Loading,
46
+ NotificationBanner: () => NotificationBanner,
47
+ NumberInput: () => NumberInput,
48
+ Pagination: () => Pagination,
49
+ Popover: () => Popover,
50
+ Progress: () => Progress,
51
+ ProgressCircle: () => ProgressCircle,
52
+ Radio: () => Radio,
53
+ Rating: () => Rating,
54
+ SectionHeader: () => SectionHeader,
55
+ Select: () => Select,
56
+ Separator: () => Separator,
57
+ Skeleton: () => Skeleton,
58
+ SkipLink: () => SkipLink,
59
+ Slider: () => Slider,
60
+ Switch: () => Switch,
61
+ Table: () => Table,
62
+ Tabs: () => Tabs,
63
+ Textarea: () => Textarea,
64
+ ToastProvider: () => ToastProvider,
65
+ Tooltip: () => Tooltip,
66
+ Typography: () => Typography,
67
+ cn: () => import_design_system_foundation44.cn,
68
+ useToast: () => useToast
69
+ });
70
+ module.exports = __toCommonJS(client_exports);
71
+
72
+ // src/components/ui/Accordion/Accordion.tsx
73
+ var import_react = require("react");
74
+
75
+ // src/components/ui/Accordion/Accordion.module.css
76
+ var Accordion_default = {};
77
+
78
+ // src/components/ui/Accordion/Accordion.tsx
79
+ var import_design_system_foundation = require("@boostdev/design-system-foundation");
80
+ var import_jsx_runtime = require("react/jsx-runtime");
81
+ function Accordion({
82
+ items,
83
+ allowMultiple = false,
84
+ defaultOpen = [],
85
+ className
86
+ }) {
87
+ const baseId = (0, import_react.useId)();
88
+ const [openIds, setOpenIds] = (0, import_react.useState)(defaultOpen);
89
+ const toggle = (id) => {
90
+ setOpenIds((prev) => {
91
+ const isOpen = prev.includes(id);
92
+ if (isOpen) return prev.filter((i) => i !== id);
93
+ return allowMultiple ? [...prev, id] : [id];
94
+ });
95
+ };
96
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_design_system_foundation.cn)(Accordion_default.accordion, className), children: items.map((item) => {
97
+ const isOpen = openIds.includes(item.id);
98
+ const triggerId = `${baseId}-trigger-${item.id}`;
99
+ const panelId = `${baseId}-panel-${item.id}`;
100
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: (0, import_design_system_foundation.cn)(Accordion_default.item, isOpen ? Accordion_default["--open"] : void 0), children: [
101
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: Accordion_default.heading, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
102
+ "button",
103
+ {
104
+ type: "button",
105
+ id: triggerId,
106
+ "aria-expanded": isOpen,
107
+ "aria-controls": panelId,
108
+ disabled: item.disabled,
109
+ className: Accordion_default.trigger,
110
+ onClick: () => toggle(item.id),
111
+ children: [
112
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: Accordion_default.triggerLabel, children: item.title }),
113
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
114
+ "svg",
115
+ {
116
+ "aria-hidden": "true",
117
+ className: Accordion_default.chevron,
118
+ viewBox: "0 0 24 24",
119
+ fill: "none",
120
+ stroke: "currentColor",
121
+ strokeWidth: "2",
122
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 9l6 6 6-6" })
123
+ }
124
+ )
125
+ ]
126
+ }
127
+ ) }),
128
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
129
+ "div",
130
+ {
131
+ id: panelId,
132
+ role: "region",
133
+ "aria-labelledby": triggerId,
134
+ hidden: !isOpen,
135
+ className: Accordion_default.panel,
136
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: Accordion_default.panelContent, children: item.content })
137
+ }
138
+ )
139
+ ] }, item.id);
140
+ }) });
141
+ }
142
+
143
+ // src/components/ui/Alert/Alert.module.css
144
+ var Alert_default = {};
145
+
146
+ // src/components/ui/Alert/Alert.tsx
147
+ var import_design_system_foundation2 = require("@boostdev/design-system-foundation");
148
+ var import_jsx_runtime2 = require("react/jsx-runtime");
149
+ function Alert({
150
+ variant = "info",
151
+ icon,
152
+ title,
153
+ children,
154
+ onDismiss,
155
+ className
156
+ }) {
157
+ const isUrgent = variant === "error" || variant === "warning";
158
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
159
+ "div",
160
+ {
161
+ role: isUrgent ? "alert" : "status",
162
+ "aria-live": isUrgent ? "assertive" : "polite",
163
+ "aria-atomic": "true",
164
+ className: (0, import_design_system_foundation2.cn)(Alert_default.alert, Alert_default[`--variant_${variant}`], className),
165
+ children: [
166
+ icon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: Alert_default.icon, "aria-hidden": "true", children: icon }),
167
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: Alert_default.content, children: [
168
+ title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { className: Alert_default.title, children: title }),
169
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: Alert_default.body, children })
170
+ ] }),
171
+ onDismiss && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
172
+ "button",
173
+ {
174
+ type: "button",
175
+ className: Alert_default.dismiss,
176
+ onClick: onDismiss,
177
+ "aria-label": "Dismiss alert",
178
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M18 6L6 18M6 6l12 12" }) })
179
+ }
180
+ )
181
+ ]
182
+ }
183
+ );
184
+ }
185
+
186
+ // src/components/ui/Avatar/Avatar.module.css
187
+ var Avatar_default = {};
188
+
189
+ // src/components/ui/Avatar/Avatar.tsx
190
+ var import_design_system_foundation3 = require("@boostdev/design-system-foundation");
191
+ var import_jsx_runtime3 = require("react/jsx-runtime");
192
+ function getInitials(name) {
193
+ return name.split(" ").filter(Boolean).slice(0, 2).map((word) => word[0].toUpperCase()).join("");
194
+ }
195
+ function Avatar({ src, alt, name, size = "medium", className }) {
196
+ const sizeClass = Avatar_default[`--size_${size}`];
197
+ if (src) {
198
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: (0, import_design_system_foundation3.cn)(Avatar_default.avatar, sizeClass, className), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("img", { src, alt: alt ?? name ?? "", className: Avatar_default.image }) });
199
+ }
200
+ const initials = name ? getInitials(name) : "";
201
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
202
+ "span",
203
+ {
204
+ role: "img",
205
+ "aria-label": name ?? "User avatar",
206
+ className: (0, import_design_system_foundation3.cn)(Avatar_default.avatar, Avatar_default["--fallback"], sizeClass, className),
207
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: Avatar_default.initials, "aria-hidden": "true", children: initials })
208
+ }
209
+ );
210
+ }
211
+
212
+ // src/components/ui/Badge/Badge.module.css
213
+ var Badge_default = {};
214
+
215
+ // src/components/ui/Badge/Badge.tsx
216
+ var import_design_system_foundation4 = require("@boostdev/design-system-foundation");
217
+ var import_jsx_runtime4 = require("react/jsx-runtime");
218
+ function Badge({ children, variant = "primary", className }) {
219
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: (0, import_design_system_foundation4.cn)(Badge_default.badge, Badge_default[`--variant_${variant}`], className), children });
220
+ }
221
+
222
+ // src/components/ui/Breadcrumb/Breadcrumb.module.css
223
+ var Breadcrumb_default = {};
224
+
225
+ // src/components/ui/Breadcrumb/Breadcrumb.tsx
226
+ var import_design_system_foundation5 = require("@boostdev/design-system-foundation");
227
+ var import_jsx_runtime5 = require("react/jsx-runtime");
228
+ function Breadcrumb({ items, className }) {
229
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("nav", { "aria-label": "Breadcrumb", className: (0, import_design_system_foundation5.cn)(Breadcrumb_default.breadcrumb, className), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ol", { className: Breadcrumb_default.list, children: items.map((item, index) => {
230
+ const isLast = index === items.length - 1;
231
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { className: Breadcrumb_default.item, children: isLast ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { "aria-current": "page", className: Breadcrumb_default.current, children: item.label }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
232
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", { href: item.href, className: Breadcrumb_default.link, children: item.label }),
233
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: Breadcrumb_default.separator, "aria-hidden": "true", children: "\u203A" })
234
+ ] }) }, item.label);
235
+ }) }) });
236
+ }
237
+
238
+ // src/components/ui/Calendar/Calendar.tsx
239
+ var import_react2 = require("react");
240
+
241
+ // src/components/ui/Calendar/Calendar.module.css
242
+ var Calendar_default = {};
243
+
244
+ // src/components/ui/Calendar/Calendar.tsx
245
+ var import_design_system_foundation6 = require("@boostdev/design-system-foundation");
246
+ var import_jsx_runtime6 = require("react/jsx-runtime");
247
+ var DAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
248
+ var MONTHS = [
249
+ "January",
250
+ "February",
251
+ "March",
252
+ "April",
253
+ "May",
254
+ "June",
255
+ "July",
256
+ "August",
257
+ "September",
258
+ "October",
259
+ "November",
260
+ "December"
261
+ ];
262
+ function isSameDay(a, b) {
263
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
264
+ }
265
+ function isOutOfRange(date, min, max) {
266
+ if (min && date < min) return true;
267
+ if (max && date > max) return true;
268
+ return false;
269
+ }
270
+ function getDaysInMonth(year, month) {
271
+ return new Date(year, month + 1, 0).getDate();
272
+ }
273
+ function getFirstDayOfMonth(year, month) {
274
+ return new Date(year, month, 1).getDay();
275
+ }
276
+ function Calendar({ value, defaultValue, min, max, onChange, className }) {
277
+ const today = /* @__PURE__ */ new Date();
278
+ const controlled = value !== void 0;
279
+ const [internal, setInternal] = (0, import_react2.useState)(defaultValue);
280
+ const selected = controlled ? value : internal;
281
+ const [viewYear, setViewYear] = (0, import_react2.useState)(selected?.getFullYear() ?? today.getFullYear());
282
+ const [viewMonth, setViewMonth] = (0, import_react2.useState)(selected?.getMonth() ?? today.getMonth());
283
+ const [focusedDay, setFocusedDay] = (0, import_react2.useState)();
284
+ const titleId = (0, import_react2.useId)();
285
+ const daysInMonth = getDaysInMonth(viewYear, viewMonth);
286
+ const firstDay = getFirstDayOfMonth(viewYear, viewMonth);
287
+ const navigate = (delta) => {
288
+ const d = new Date(viewYear, viewMonth + delta, 1);
289
+ setViewYear(d.getFullYear());
290
+ setViewMonth(d.getMonth());
291
+ setFocusedDay(void 0);
292
+ };
293
+ const selectDay = (day) => {
294
+ const date = new Date(viewYear, viewMonth, day);
295
+ if (isOutOfRange(date, min, max)) return;
296
+ if (!controlled) setInternal(date);
297
+ onChange?.(date);
298
+ };
299
+ const handleKeyDown = (e, day) => {
300
+ const map = {
301
+ ArrowRight: 1,
302
+ ArrowLeft: -1,
303
+ ArrowDown: 7,
304
+ ArrowUp: -7
305
+ };
306
+ if (e.key in map) {
307
+ e.preventDefault();
308
+ const current = new Date(viewYear, viewMonth, day);
309
+ const next = new Date(current);
310
+ next.setDate(next.getDate() + map[e.key]);
311
+ setViewYear(next.getFullYear());
312
+ setViewMonth(next.getMonth());
313
+ setFocusedDay(next.getDate());
314
+ } else if (e.key === "Home") {
315
+ e.preventDefault();
316
+ setFocusedDay(1);
317
+ } else if (e.key === "End") {
318
+ e.preventDefault();
319
+ setFocusedDay(daysInMonth);
320
+ } else if (e.key === "Enter" || e.key === " ") {
321
+ e.preventDefault();
322
+ selectDay(day);
323
+ }
324
+ };
325
+ const cells = [
326
+ ...Array.from({ length: firstDay }, () => null),
327
+ ...Array.from({ length: daysInMonth }, (_, i) => ({ day: i + 1 }))
328
+ ];
329
+ while (cells.length % 7 !== 0) cells.push(null);
330
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: (0, import_design_system_foundation6.cn)(Calendar_default.calendar, className), role: "group", "aria-labelledby": titleId, children: [
331
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: Calendar_default.header, children: [
332
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
333
+ "button",
334
+ {
335
+ type: "button",
336
+ className: Calendar_default.navBtn,
337
+ "aria-label": "Previous month",
338
+ onClick: () => navigate(-1),
339
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 19l-7-7 7-7" }) })
340
+ }
341
+ ),
342
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { id: titleId, className: Calendar_default.monthYear, "aria-live": "polite", children: [
343
+ MONTHS[viewMonth],
344
+ " ",
345
+ viewYear
346
+ ] }),
347
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
348
+ "button",
349
+ {
350
+ type: "button",
351
+ className: Calendar_default.navBtn,
352
+ "aria-label": "Next month",
353
+ onClick: () => navigate(1),
354
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) })
355
+ }
356
+ )
357
+ ] }),
358
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
359
+ "table",
360
+ {
361
+ className: Calendar_default.grid,
362
+ role: "grid",
363
+ "aria-labelledby": titleId,
364
+ children: [
365
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("tr", { children: DAYS.map((d) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("th", { scope: "col", abbr: d, className: Calendar_default.weekday, children: d }, d)) }) }),
366
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("tbody", { children: Array.from({ length: cells.length / 7 }, (_, row) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("tr", { children: cells.slice(row * 7, row * 7 + 7).map((cell, col) => {
367
+ if (!cell) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("td", { className: Calendar_default.empty, "aria-hidden": "true" }, col);
368
+ const date = new Date(viewYear, viewMonth, cell.day);
369
+ const isSelected = selected ? isSameDay(date, selected) : false;
370
+ const isToday = isSameDay(date, today);
371
+ const disabled = isOutOfRange(date, min, max);
372
+ const isFocused = focusedDay === cell.day;
373
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("td", { role: "gridcell", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
374
+ "button",
375
+ {
376
+ type: "button",
377
+ className: (0, import_design_system_foundation6.cn)(
378
+ Calendar_default.day,
379
+ isSelected && Calendar_default.selected,
380
+ isToday && !isSelected && Calendar_default.today,
381
+ disabled && Calendar_default.disabled
382
+ ),
383
+ "aria-label": date.toLocaleDateString("en", { month: "long", day: "numeric", year: "numeric" }),
384
+ "aria-pressed": isSelected,
385
+ "aria-current": isToday ? "date" : void 0,
386
+ "aria-disabled": disabled,
387
+ disabled,
388
+ tabIndex: isFocused || !focusedDay && isSelected || !focusedDay && !selected && isToday ? 0 : -1,
389
+ onClick: () => selectDay(cell.day),
390
+ onKeyDown: (e) => handleKeyDown(e, cell.day),
391
+ children: cell.day
392
+ }
393
+ ) }, col);
394
+ }) }, row)) })
395
+ ]
396
+ }
397
+ )
398
+ ] });
399
+ }
400
+
401
+ // src/components/ui/Carousel/Carousel.tsx
402
+ var import_react3 = require("react");
403
+
404
+ // src/components/ui/Carousel/Carousel.module.css
405
+ var Carousel_default = {};
406
+
407
+ // src/components/ui/Carousel/Carousel.tsx
408
+ var import_design_system_foundation7 = require("@boostdev/design-system-foundation");
409
+ var import_jsx_runtime7 = require("react/jsx-runtime");
410
+ function Carousel({ items, label, className }) {
411
+ const trackRef = (0, import_react3.useRef)(null);
412
+ const listId = (0, import_react3.useId)();
413
+ const scroll = (direction) => {
414
+ if (!trackRef.current) return;
415
+ const { scrollLeft, clientWidth } = trackRef.current;
416
+ trackRef.current.scrollTo({
417
+ left: scrollLeft + (direction === "next" ? clientWidth : -clientWidth),
418
+ behavior: "smooth"
419
+ });
420
+ };
421
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { "aria-label": label, className: (0, import_design_system_foundation7.cn)(Carousel_default.carousel, className), children: [
422
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
423
+ "button",
424
+ {
425
+ type: "button",
426
+ className: (0, import_design_system_foundation7.cn)(Carousel_default.navBtn, Carousel_default["--prev"]),
427
+ "aria-label": "Previous",
428
+ "aria-controls": listId,
429
+ onClick: () => scroll("prev"),
430
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 19l-7-7 7-7" }) })
431
+ }
432
+ ),
433
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
434
+ "div",
435
+ {
436
+ ref: trackRef,
437
+ id: listId,
438
+ role: "list",
439
+ className: Carousel_default.track,
440
+ children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { role: "listitem", className: Carousel_default.slide, children: item }, i))
441
+ }
442
+ ),
443
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
444
+ "button",
445
+ {
446
+ type: "button",
447
+ className: (0, import_design_system_foundation7.cn)(Carousel_default.navBtn, Carousel_default["--next"]),
448
+ "aria-label": "Next",
449
+ "aria-controls": listId,
450
+ onClick: () => scroll("next"),
451
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) })
452
+ }
453
+ )
454
+ ] });
455
+ }
456
+
457
+ // src/components/ui/DescriptionList/DescriptionList.module.css
458
+ var DescriptionList_default = {};
459
+
460
+ // src/components/ui/DescriptionList/DescriptionList.tsx
461
+ var import_design_system_foundation8 = require("@boostdev/design-system-foundation");
462
+ var import_jsx_runtime8 = require("react/jsx-runtime");
463
+ function DescriptionList({ items, layout = "stacked", className }) {
464
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("dl", { className: (0, import_design_system_foundation8.cn)(DescriptionList_default.list, DescriptionList_default[`--layout_${layout}`], className), children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: DescriptionList_default.group, children: [
465
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("dt", { className: DescriptionList_default.term, children: item.term }),
466
+ Array.isArray(item.details) ? item.details.map((d, j) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("dd", { className: DescriptionList_default.details, children: d }, j)) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("dd", { className: DescriptionList_default.details, children: item.details })
467
+ ] }, i)) });
468
+ }
469
+
470
+ // src/components/ui/Link/Link.module.css
471
+ var Link_default = {};
472
+
473
+ // src/components/ui/Link/Link.tsx
474
+ var import_design_system_foundation9 = require("@boostdev/design-system-foundation");
475
+ var import_jsx_runtime9 = require("react/jsx-runtime");
476
+ function Link({
477
+ as,
478
+ children,
479
+ variant = "default",
480
+ external = false,
481
+ className,
482
+ ...props
483
+ }) {
484
+ const Component = as ?? "a";
485
+ const externalProps = external ? { target: "_blank", rel: "noreferrer noopener" } : {};
486
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
487
+ Component,
488
+ {
489
+ className: (0, import_design_system_foundation9.cn)(Link_default.link, Link_default[`--variant_${variant}`], className),
490
+ ...externalProps,
491
+ ...props,
492
+ children: [
493
+ children,
494
+ external && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: Link_default.externalLabel, children: " (opens in new tab)" })
495
+ ]
496
+ }
497
+ );
498
+ }
499
+
500
+ // src/components/ui/Loading/Loading.module.css
501
+ var Loading_default = {};
502
+
503
+ // src/components/ui/Loading/Loading.tsx
504
+ var import_design_system_foundation10 = require("@boostdev/design-system-foundation");
505
+ var import_jsx_runtime10 = require("react/jsx-runtime");
506
+ function Loading({ size = "medium", className }) {
507
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: (0, import_design_system_foundation10.cn)(Loading_default.loading, Loading_default[`--size_${size}`], className), children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: Loading_default.spinner, role: "status", "aria-label": "Loading" }) });
508
+ }
509
+
510
+ // src/components/ui/NotificationBanner/NotificationBanner.module.css
511
+ var NotificationBanner_default = {};
512
+
513
+ // src/components/ui/NotificationBanner/NotificationBanner.tsx
514
+ var import_design_system_foundation11 = require("@boostdev/design-system-foundation");
515
+ var import_jsx_runtime11 = require("react/jsx-runtime");
516
+ function NotificationBanner({
517
+ variant = "info",
518
+ children,
519
+ action,
520
+ onDismiss,
521
+ className
522
+ }) {
523
+ const isUrgent = variant === "error" || variant === "warning";
524
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
525
+ "div",
526
+ {
527
+ role: isUrgent ? "alert" : "status",
528
+ "aria-live": isUrgent ? "assertive" : "polite",
529
+ "aria-atomic": "true",
530
+ className: (0, import_design_system_foundation11.cn)(NotificationBanner_default.banner, NotificationBanner_default[`--variant_${variant}`], className),
531
+ children: [
532
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: NotificationBanner_default.content, children }),
533
+ action && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: NotificationBanner_default.action, children: action }),
534
+ onDismiss && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
535
+ "button",
536
+ {
537
+ type: "button",
538
+ className: NotificationBanner_default.dismiss,
539
+ onClick: onDismiss,
540
+ "aria-label": "Dismiss notification",
541
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M18 6L6 18M6 6l12 12" }) })
542
+ }
543
+ )
544
+ ]
545
+ }
546
+ );
547
+ }
548
+
549
+ // src/components/ui/Pagination/Pagination.module.css
550
+ var Pagination_default = {};
551
+
552
+ // src/components/ui/Pagination/Pagination.tsx
553
+ var import_design_system_foundation12 = require("@boostdev/design-system-foundation");
554
+ var import_jsx_runtime12 = require("react/jsx-runtime");
555
+ function getPageRange(current, total) {
556
+ const delta = 1;
557
+ const range = [];
558
+ for (let i = 1; i <= total; i++) {
559
+ if (i === 1 || i === total || i >= current - delta && i <= current + delta) {
560
+ range.push(i);
561
+ } else if (range[range.length - 1] !== "...") {
562
+ range.push("...");
563
+ }
564
+ }
565
+ return range;
566
+ }
567
+ function Pagination({
568
+ currentPage,
569
+ totalPages,
570
+ onPageChange,
571
+ className
572
+ }) {
573
+ const pages = getPageRange(currentPage, totalPages);
574
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("nav", { "aria-label": "Pagination", className: (0, import_design_system_foundation12.cn)(Pagination_default.pagination, className), children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("ul", { className: Pagination_default.list, children: [
575
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
576
+ "button",
577
+ {
578
+ type: "button",
579
+ className: (0, import_design_system_foundation12.cn)(Pagination_default.button, Pagination_default["--nav"]),
580
+ onClick: () => onPageChange(currentPage - 1),
581
+ disabled: currentPage <= 1,
582
+ "aria-label": "Previous page",
583
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 19l-7-7 7-7" }) })
584
+ }
585
+ ) }),
586
+ pages.map(
587
+ (page, index) => page === "..." ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: Pagination_default.ellipsis, "aria-hidden": "true", children: "\u2026" }) }, `ellipsis-${index}`) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
588
+ "button",
589
+ {
590
+ type: "button",
591
+ className: (0, import_design_system_foundation12.cn)(Pagination_default.button, currentPage === page ? Pagination_default["--active"] : void 0),
592
+ onClick: () => onPageChange(page),
593
+ "aria-label": `Page ${page}`,
594
+ "aria-current": currentPage === page ? "page" : void 0,
595
+ children: page
596
+ }
597
+ ) }, page)
598
+ ),
599
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
600
+ "button",
601
+ {
602
+ type: "button",
603
+ className: (0, import_design_system_foundation12.cn)(Pagination_default.button, Pagination_default["--nav"]),
604
+ onClick: () => onPageChange(currentPage + 1),
605
+ disabled: currentPage >= totalPages,
606
+ "aria-label": "Next page",
607
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) })
608
+ }
609
+ ) })
610
+ ] }) });
611
+ }
612
+
613
+ // src/components/ui/Progress/Progress.module.css
614
+ var Progress_default = {};
615
+
616
+ // src/components/ui/Progress/Progress.tsx
617
+ var import_design_system_foundation13 = require("@boostdev/design-system-foundation");
618
+ var import_jsx_runtime13 = require("react/jsx-runtime");
619
+ function Progress({
620
+ value,
621
+ max = 100,
622
+ label,
623
+ showLabel = false,
624
+ size = "medium",
625
+ className
626
+ }) {
627
+ const percentage = Math.min(100, Math.max(0, value / max * 100));
628
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: (0, import_design_system_foundation13.cn)(Progress_default.container, className), children: [
629
+ showLabel && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: Progress_default.labelRow, children: [
630
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: Progress_default.label, children: label }),
631
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: Progress_default.value, children: [
632
+ Math.round(percentage),
633
+ "%"
634
+ ] })
635
+ ] }),
636
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
637
+ "div",
638
+ {
639
+ role: "progressbar",
640
+ "aria-label": label,
641
+ "aria-valuenow": value,
642
+ "aria-valuemin": 0,
643
+ "aria-valuemax": max,
644
+ className: (0, import_design_system_foundation13.cn)(Progress_default.track, Progress_default[`--size_${size}`]),
645
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: Progress_default.fill, style: { width: `${percentage}%` } })
646
+ }
647
+ )
648
+ ] });
649
+ }
650
+
651
+ // src/components/ui/ProgressCircle/ProgressCircle.module.css
652
+ var ProgressCircle_default = {};
653
+
654
+ // src/components/ui/ProgressCircle/ProgressCircle.tsx
655
+ var import_design_system_foundation14 = require("@boostdev/design-system-foundation");
656
+ var import_jsx_runtime14 = require("react/jsx-runtime");
657
+ var SIZE_PX = { small: 40, medium: 64, large: 96 };
658
+ var STROKE_WIDTH = 4;
659
+ function ProgressCircle({
660
+ value,
661
+ max = 100,
662
+ label,
663
+ showValue = false,
664
+ size = "medium",
665
+ className
666
+ }) {
667
+ const percentage = Math.min(100, Math.max(0, value / max * 100));
668
+ const px = SIZE_PX[size];
669
+ const radius = (px - STROKE_WIDTH * 2) / 2;
670
+ const circumference = 2 * Math.PI * radius;
671
+ const offset = circumference - percentage / 100 * circumference;
672
+ const cx = px / 2;
673
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
674
+ "div",
675
+ {
676
+ role: "progressbar",
677
+ "aria-label": label,
678
+ "aria-valuenow": value,
679
+ "aria-valuemin": 0,
680
+ "aria-valuemax": max,
681
+ className: (0, import_design_system_foundation14.cn)(ProgressCircle_default.wrapper, ProgressCircle_default[`--size_${size}`], className),
682
+ children: [
683
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
684
+ "svg",
685
+ {
686
+ width: px,
687
+ height: px,
688
+ viewBox: `0 0 ${px} ${px}`,
689
+ "aria-hidden": "true",
690
+ className: ProgressCircle_default.svg,
691
+ children: [
692
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
693
+ "circle",
694
+ {
695
+ className: ProgressCircle_default.track,
696
+ cx,
697
+ cy: cx,
698
+ r: radius,
699
+ strokeWidth: STROKE_WIDTH,
700
+ fill: "none"
701
+ }
702
+ ),
703
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
704
+ "circle",
705
+ {
706
+ className: ProgressCircle_default.fill,
707
+ cx,
708
+ cy: cx,
709
+ r: radius,
710
+ strokeWidth: STROKE_WIDTH,
711
+ fill: "none",
712
+ strokeDasharray: circumference,
713
+ strokeDashoffset: offset,
714
+ strokeLinecap: "round",
715
+ transform: `rotate(-90 ${cx} ${cx})`
716
+ }
717
+ )
718
+ ]
719
+ }
720
+ ),
721
+ showValue && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: ProgressCircle_default.value, "aria-hidden": "true", children: [
722
+ Math.round(percentage),
723
+ "%"
724
+ ] })
725
+ ]
726
+ }
727
+ );
728
+ }
729
+
730
+ // src/components/ui/Separator/Separator.module.css
731
+ var Separator_default = {};
732
+
733
+ // src/components/ui/Separator/Separator.tsx
734
+ var import_design_system_foundation15 = require("@boostdev/design-system-foundation");
735
+ var import_jsx_runtime15 = require("react/jsx-runtime");
736
+ function Separator({ orientation = "horizontal", className }) {
737
+ if (orientation === "vertical") {
738
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
739
+ "div",
740
+ {
741
+ role: "separator",
742
+ "aria-orientation": "vertical",
743
+ className: (0, import_design_system_foundation15.cn)(Separator_default.separator, Separator_default["--vertical"], className)
744
+ }
745
+ );
746
+ }
747
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("hr", { className: (0, import_design_system_foundation15.cn)(Separator_default.separator, Separator_default["--horizontal"], className) });
748
+ }
749
+
750
+ // src/components/ui/Skeleton/Skeleton.tsx
751
+ var import_design_system_foundation16 = require("@boostdev/design-system-foundation");
752
+
753
+ // src/components/ui/Skeleton/Skeleton.module.css
754
+ var Skeleton_default = {};
755
+
756
+ // src/components/ui/Skeleton/Skeleton.tsx
757
+ var import_jsx_runtime16 = require("react/jsx-runtime");
758
+ function Skeleton({ className }) {
759
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { "aria-hidden": "true", className: (0, import_design_system_foundation16.cn)(Skeleton_default.skeleton, className) });
760
+ }
761
+
762
+ // src/components/ui/SkipLink/SkipLink.module.css
763
+ var SkipLink_default = {};
764
+
765
+ // src/components/ui/SkipLink/SkipLink.tsx
766
+ var import_jsx_runtime17 = require("react/jsx-runtime");
767
+ function SkipLink({ href = "#main", children = "Skip to main content" }) {
768
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("a", { href, className: SkipLink_default.skipLink, children });
769
+ }
770
+
771
+ // src/components/ui/Table/Table.module.css
772
+ var Table_default = {};
773
+
774
+ // src/components/ui/Table/Table.tsx
775
+ var import_design_system_foundation17 = require("@boostdev/design-system-foundation");
776
+ var import_jsx_runtime18 = require("react/jsx-runtime");
777
+ function Table({
778
+ columns,
779
+ rows,
780
+ caption,
781
+ sortKey,
782
+ sortDirection,
783
+ onSort,
784
+ className
785
+ }) {
786
+ const handleSort = (key) => {
787
+ if (!onSort) return;
788
+ const nextDirection = sortKey === key && sortDirection === "asc" ? "desc" : "asc";
789
+ onSort(key, nextDirection);
790
+ };
791
+ const getAriaSort = (key) => {
792
+ if (sortKey !== key) return "none";
793
+ return sortDirection === "asc" ? "ascending" : "descending";
794
+ };
795
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: (0, import_design_system_foundation17.cn)(Table_default.wrapper, className), children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("table", { className: Table_default.table, children: [
796
+ caption && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("caption", { className: Table_default.caption, children: caption }),
797
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("thead", { className: Table_default.thead, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("tr", { children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
798
+ "th",
799
+ {
800
+ scope: "col",
801
+ "aria-sort": col.sortable ? getAriaSort(col.key) : void 0,
802
+ className: (0, import_design_system_foundation17.cn)(Table_default.th, col.sortable ? Table_default["--sortable"] : void 0),
803
+ children: col.sortable ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
804
+ "button",
805
+ {
806
+ type: "button",
807
+ className: Table_default.sortButton,
808
+ onClick: () => handleSort(col.key),
809
+ children: [
810
+ col.header,
811
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
812
+ "svg",
813
+ {
814
+ "aria-hidden": "true",
815
+ className: (0, import_design_system_foundation17.cn)(
816
+ Table_default.sortIcon,
817
+ sortKey === col.key ? Table_default["--sort-active"] : void 0,
818
+ sortKey === col.key && sortDirection === "desc" ? Table_default["--sort-desc"] : void 0
819
+ ),
820
+ viewBox: "0 0 24 24",
821
+ fill: "none",
822
+ stroke: "currentColor",
823
+ strokeWidth: "2",
824
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 9l6 6 6-6" })
825
+ }
826
+ )
827
+ ]
828
+ }
829
+ ) : col.header
830
+ },
831
+ col.key
832
+ )) }) }),
833
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("tbody", { className: Table_default.tbody, children: rows.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("tr", { className: Table_default.tr, children: columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("td", { className: Table_default.td, children: col.render ? col.render(row) : String(row[col.key] ?? "") }, col.key)) }, rowIndex)) })
834
+ ] }) });
835
+ }
836
+
837
+ // src/components/ui/Tabs/Tabs.tsx
838
+ var import_react4 = require("react");
839
+
840
+ // src/components/ui/Tabs/Tabs.module.css
841
+ var Tabs_default = {};
842
+
843
+ // src/components/ui/Tabs/Tabs.tsx
844
+ var import_design_system_foundation18 = require("@boostdev/design-system-foundation");
845
+ var import_jsx_runtime19 = require("react/jsx-runtime");
846
+ function Tabs({ tabs, defaultTab, className }) {
847
+ const baseId = (0, import_react4.useId)();
848
+ const [activeTab, setActiveTab] = (0, import_react4.useState)(defaultTab ?? tabs[0]?.id);
849
+ const tabRefs = (0, import_react4.useRef)([]);
850
+ const enabledIndexes = tabs.map((tab, i) => ({ tab, i })).filter(({ tab }) => !tab.disabled).map(({ i }) => i);
851
+ const handleKeyDown = (e, index) => {
852
+ const pos = enabledIndexes.indexOf(index);
853
+ const focusAt = (i) => {
854
+ tabRefs.current[i]?.focus();
855
+ setActiveTab(tabs[i].id);
856
+ };
857
+ if (e.key === "ArrowRight") {
858
+ e.preventDefault();
859
+ focusAt(enabledIndexes[(pos + 1) % enabledIndexes.length]);
860
+ } else if (e.key === "ArrowLeft") {
861
+ e.preventDefault();
862
+ focusAt(enabledIndexes[(pos - 1 + enabledIndexes.length) % enabledIndexes.length]);
863
+ } else if (e.key === "Home") {
864
+ e.preventDefault();
865
+ focusAt(enabledIndexes[0]);
866
+ } else if (e.key === "End") {
867
+ e.preventDefault();
868
+ focusAt(enabledIndexes[enabledIndexes.length - 1]);
869
+ }
870
+ };
871
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: (0, import_design_system_foundation18.cn)(Tabs_default.tabs, className), children: [
872
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { role: "tablist", className: Tabs_default.tabList, children: tabs.map((tab, i) => {
873
+ const tabId = `${baseId}-tab-${tab.id}`;
874
+ const panelId = `${baseId}-panel-${tab.id}`;
875
+ const isActive = activeTab === tab.id;
876
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
877
+ "button",
878
+ {
879
+ ref: (el) => {
880
+ tabRefs.current[i] = el;
881
+ },
882
+ id: tabId,
883
+ type: "button",
884
+ role: "tab",
885
+ "aria-selected": isActive,
886
+ "aria-controls": panelId,
887
+ tabIndex: isActive ? 0 : -1,
888
+ disabled: tab.disabled,
889
+ className: (0, import_design_system_foundation18.cn)(Tabs_default.tab, isActive ? Tabs_default["--active"] : void 0),
890
+ onClick: () => setActiveTab(tab.id),
891
+ onKeyDown: (e) => handleKeyDown(e, i),
892
+ children: tab.label
893
+ },
894
+ tab.id
895
+ );
896
+ }) }),
897
+ tabs.map((tab) => {
898
+ const tabId = `${baseId}-tab-${tab.id}`;
899
+ const panelId = `${baseId}-panel-${tab.id}`;
900
+ const isActive = activeTab === tab.id;
901
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
902
+ "div",
903
+ {
904
+ id: panelId,
905
+ role: "tabpanel",
906
+ "aria-labelledby": tabId,
907
+ tabIndex: 0,
908
+ hidden: !isActive,
909
+ className: Tabs_default.panel,
910
+ children: tab.content
911
+ },
912
+ tab.id
913
+ );
914
+ })
915
+ ] });
916
+ }
917
+
918
+ // src/components/ui/Tooltip/Tooltip.tsx
919
+ var import_react5 = require("react");
920
+
921
+ // src/components/ui/Tooltip/Tooltip.module.css
922
+ var Tooltip_default = {};
923
+
924
+ // src/components/ui/Tooltip/Tooltip.tsx
925
+ var import_design_system_foundation19 = require("@boostdev/design-system-foundation");
926
+ var import_jsx_runtime20 = require("react/jsx-runtime");
927
+ function Tooltip({
928
+ content,
929
+ placement = "top",
930
+ children,
931
+ className
932
+ }) {
933
+ const tooltipId = (0, import_react5.useId)();
934
+ const trigger = (0, import_react5.isValidElement)(children) ? (0, import_react5.cloneElement)(children, {
935
+ "aria-describedby": tooltipId
936
+ }) : children;
937
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: (0, import_design_system_foundation19.cn)(Tooltip_default.wrapper, className), children: [
938
+ trigger,
939
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
940
+ "span",
941
+ {
942
+ id: tooltipId,
943
+ role: "tooltip",
944
+ className: (0, import_design_system_foundation19.cn)(Tooltip_default.tooltip, Tooltip_default[`--placement_${placement}`]),
945
+ children: content
946
+ }
947
+ )
948
+ ] });
949
+ }
950
+
951
+ // src/components/ui/Typography/Typography.module.css
952
+ var Typography_default = {};
953
+
954
+ // src/components/ui/Typography/Typography.tsx
955
+ var import_design_system_foundation20 = require("@boostdev/design-system-foundation");
956
+ var import_jsx_runtime21 = require("react/jsx-runtime");
957
+ var variantToElement = {
958
+ h1: "h1",
959
+ h2: "h2",
960
+ h3: "h3",
961
+ body: "p",
962
+ body_s: "p"
963
+ };
964
+ function Typography({ variant = "body", component, children, className }) {
965
+ const Component = component || variantToElement[variant];
966
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Component, { className: (0, import_design_system_foundation20.cn)(Typography_default.typography, Typography_default[`--${variant}`], className), children });
967
+ }
968
+
969
+ // src/components/interaction/Button/Button.module.css
970
+ var Button_default = {};
971
+
972
+ // src/components/interaction/Button/Button.tsx
973
+ var import_design_system_foundation21 = require("@boostdev/design-system-foundation");
974
+ var import_jsx_runtime22 = require("react/jsx-runtime");
975
+ function Button({
976
+ children,
977
+ className = "",
978
+ variant = "primary",
979
+ type = "button",
980
+ iconStart,
981
+ iconEnd,
982
+ size = "medium",
983
+ hasPulse = false,
984
+ href,
985
+ target,
986
+ rel,
987
+ disabled,
988
+ onClick,
989
+ ...rest
990
+ }) {
991
+ const classNames = (0, import_design_system_foundation21.cn)(
992
+ Button_default.button,
993
+ Button_default[`--${variant}`],
994
+ Button_default[`--size_${size}`],
995
+ hasPulse && Button_default["--hasPulse"],
996
+ className
997
+ );
998
+ const allChildren = /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
999
+ !!iconStart && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: Button_default.prefix, children: iconStart }),
1000
+ children,
1001
+ !!iconEnd && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: Button_default.suffix, children: iconEnd })
1002
+ ] });
1003
+ if (href) {
1004
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("a", { className: classNames, href, target, rel, onClick, ...rest, children: allChildren });
1005
+ }
1006
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { type, className: classNames, disabled, onClick, ...rest, children: allChildren });
1007
+ }
1008
+
1009
+ // src/components/interaction/Command/Command.tsx
1010
+ var import_react6 = require("react");
1011
+
1012
+ // src/components/interaction/Command/Command.module.css
1013
+ var Command_default = {};
1014
+
1015
+ // src/components/interaction/Command/Command.tsx
1016
+ var import_design_system_foundation22 = require("@boostdev/design-system-foundation");
1017
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1018
+ function Command({
1019
+ isOpen,
1020
+ onClose,
1021
+ items,
1022
+ placeholder = "Search commands\u2026",
1023
+ className
1024
+ }) {
1025
+ const [query, setQuery] = (0, import_react6.useState)("");
1026
+ const [activeIndex, setActiveIndex] = (0, import_react6.useState)(0);
1027
+ const dialogRef = (0, import_react6.useRef)(null);
1028
+ const inputRef = (0, import_react6.useRef)(null);
1029
+ const listboxId = (0, import_react6.useId)();
1030
+ const filtered = (0, import_react6.useMemo)(() => {
1031
+ const q = query.toLowerCase().trim();
1032
+ return q ? items.filter(
1033
+ (item) => item.label.toLowerCase().includes(q) || item.description?.toLowerCase().includes(q)
1034
+ ) : items;
1035
+ }, [query, items]);
1036
+ const groups = (0, import_react6.useMemo)(() => {
1037
+ const map = /* @__PURE__ */ new Map();
1038
+ filtered.forEach((item) => {
1039
+ const g = item.group ?? "";
1040
+ const list = map.get(g) ?? [];
1041
+ list.push(item);
1042
+ map.set(g, list);
1043
+ });
1044
+ return map;
1045
+ }, [filtered]);
1046
+ (0, import_react6.useEffect)(() => {
1047
+ const dialog = dialogRef.current;
1048
+ if (!dialog) return;
1049
+ if (isOpen) {
1050
+ dialog.showModal();
1051
+ setQuery("");
1052
+ setActiveIndex(0);
1053
+ setTimeout(() => inputRef.current?.focus(), 0);
1054
+ } else if (dialog.open) {
1055
+ dialog.close();
1056
+ }
1057
+ }, [isOpen]);
1058
+ (0, import_react6.useEffect)(() => {
1059
+ setActiveIndex(0);
1060
+ }, [query]);
1061
+ const handleCancel = (e) => {
1062
+ e.preventDefault();
1063
+ onClose();
1064
+ };
1065
+ const handleKeyDown = (e) => {
1066
+ if (e.key === "ArrowDown") {
1067
+ e.preventDefault();
1068
+ setActiveIndex((i) => Math.min(i + 1, filtered.length - 1));
1069
+ } else if (e.key === "ArrowUp") {
1070
+ e.preventDefault();
1071
+ setActiveIndex((i) => Math.max(i - 1, 0));
1072
+ } else if (e.key === "Enter") {
1073
+ e.preventDefault();
1074
+ filtered[activeIndex]?.onSelect();
1075
+ onClose();
1076
+ } else if (e.key === "Escape") {
1077
+ onClose();
1078
+ }
1079
+ };
1080
+ const selectItem = (item) => {
1081
+ item.onSelect();
1082
+ onClose();
1083
+ };
1084
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1085
+ "dialog",
1086
+ {
1087
+ ref: dialogRef,
1088
+ className: (0, import_design_system_foundation22.cn)(Command_default.dialog, className),
1089
+ "aria-label": "Command palette",
1090
+ onCancel: handleCancel,
1091
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: Command_default.palette, onKeyDown: handleKeyDown, children: [
1092
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: Command_default.searchRow, children: [
1093
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("svg", { "aria-hidden": "true", className: Command_default.searchIcon, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
1094
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("circle", { cx: "11", cy: "11", r: "8" }),
1095
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("path", { strokeLinecap: "round", d: "M21 21l-4.35-4.35" })
1096
+ ] }),
1097
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1098
+ "input",
1099
+ {
1100
+ ref: inputRef,
1101
+ type: "search",
1102
+ role: "combobox",
1103
+ "aria-expanded": filtered.length > 0,
1104
+ "aria-controls": listboxId,
1105
+ "aria-autocomplete": "list",
1106
+ "aria-activedescendant": filtered[activeIndex] ? `cmd-${filtered[activeIndex].id}` : void 0,
1107
+ className: Command_default.search,
1108
+ placeholder,
1109
+ value: query,
1110
+ onChange: (e) => setQuery(e.target.value)
1111
+ }
1112
+ ),
1113
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("kbd", { className: Command_default.escHint, children: "Esc" })
1114
+ ] }),
1115
+ filtered.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("ul", { id: listboxId, role: "listbox", className: Command_default.list, "aria-label": "Commands", children: Array.from(groups.entries()).map(([group, groupItems]) => /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("li", { role: "presentation", children: [
1116
+ group && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: Command_default.group, role: "presentation", children: group }),
1117
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("ul", { role: "group", "aria-label": group || void 0, className: Command_default.groupList, children: groupItems.map((item) => {
1118
+ const flatIndex = filtered.indexOf(item);
1119
+ const isActive = flatIndex === activeIndex;
1120
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
1121
+ "li",
1122
+ {
1123
+ id: `cmd-${item.id}`,
1124
+ role: "option",
1125
+ "aria-selected": isActive,
1126
+ className: (0, import_design_system_foundation22.cn)(Command_default.item, isActive && Command_default.itemActive),
1127
+ onPointerDown: (e) => e.preventDefault(),
1128
+ onClick: () => selectItem(item),
1129
+ children: [
1130
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: Command_default.itemLabel, children: item.label }),
1131
+ item.description && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: Command_default.itemDesc, children: item.description }),
1132
+ item.shortcut && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("kbd", { className: Command_default.shortcut, children: item.shortcut })
1133
+ ]
1134
+ },
1135
+ item.id
1136
+ );
1137
+ }) })
1138
+ ] }, group)) }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: Command_default.empty, "aria-live": "polite", children: [
1139
+ "No results for \u201C",
1140
+ query,
1141
+ "\u201D"
1142
+ ] })
1143
+ ] })
1144
+ }
1145
+ );
1146
+ }
1147
+
1148
+ // src/components/interaction/Dialog/Dialog.tsx
1149
+ var import_react7 = require("react");
1150
+
1151
+ // src/components/interaction/Dialog/Dialog.module.css
1152
+ var Dialog_default = {};
1153
+
1154
+ // src/components/interaction/Dialog/Dialog.tsx
1155
+ var import_design_system_foundation23 = require("@boostdev/design-system-foundation");
1156
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1157
+ function Dialog({ children, isVisible = false, className, handleClose }) {
1158
+ const dialogRef = (0, import_react7.useRef)(null);
1159
+ (0, import_react7.useEffect)(() => {
1160
+ const dialog = dialogRef.current;
1161
+ if (!dialog) return;
1162
+ if (isVisible) {
1163
+ dialog.showModal();
1164
+ } else if (dialog.open) {
1165
+ dialog.close();
1166
+ }
1167
+ }, [isVisible]);
1168
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("dialog", { ref: dialogRef, className: (0, import_design_system_foundation23.cn)(className, Dialog_default.dialog), children: [
1169
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("form", { method: "dialog", className: Dialog_default.closeForm, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1170
+ "button",
1171
+ {
1172
+ type: "submit",
1173
+ className: Dialog_default.closeButton,
1174
+ onClick: handleClose,
1175
+ "aria-label": "Close dialog",
1176
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M18 6L6 18M6 6l12 12" }) })
1177
+ }
1178
+ ) }),
1179
+ children
1180
+ ] });
1181
+ }
1182
+
1183
+ // src/components/interaction/Drawer/Drawer.tsx
1184
+ var import_react8 = require("react");
1185
+
1186
+ // src/components/interaction/Drawer/Drawer.module.css
1187
+ var Drawer_default = {};
1188
+
1189
+ // src/components/interaction/Drawer/Drawer.tsx
1190
+ var import_design_system_foundation24 = require("@boostdev/design-system-foundation");
1191
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1192
+ function Drawer({
1193
+ isOpen,
1194
+ onClose,
1195
+ title,
1196
+ children,
1197
+ side = "right",
1198
+ className
1199
+ }) {
1200
+ const dialogRef = (0, import_react8.useRef)(null);
1201
+ (0, import_react8.useEffect)(() => {
1202
+ const dialog = dialogRef.current;
1203
+ if (!dialog) return;
1204
+ if (isOpen) {
1205
+ dialog.showModal();
1206
+ } else if (dialog.open) {
1207
+ dialog.close();
1208
+ }
1209
+ }, [isOpen]);
1210
+ const handleClick = (e) => {
1211
+ if (e.target === dialogRef.current) onClose();
1212
+ };
1213
+ const handleCancel = (e) => {
1214
+ e.preventDefault();
1215
+ onClose();
1216
+ };
1217
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1218
+ "dialog",
1219
+ {
1220
+ ref: dialogRef,
1221
+ className: (0, import_design_system_foundation24.cn)(Drawer_default.drawer, Drawer_default[`--side_${side}`], className),
1222
+ "aria-label": title,
1223
+ onClick: handleClick,
1224
+ onCancel: handleCancel,
1225
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: Drawer_default.panel, children: [
1226
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: Drawer_default.header, children: [
1227
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h2", { className: Drawer_default.title, children: title }),
1228
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1229
+ "button",
1230
+ {
1231
+ type: "button",
1232
+ className: Drawer_default.closeButton,
1233
+ onClick: onClose,
1234
+ "aria-label": "Close drawer",
1235
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M18 6L6 18M6 6l12 12" }) })
1236
+ }
1237
+ )
1238
+ ] }),
1239
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: Drawer_default.body, children })
1240
+ ] })
1241
+ }
1242
+ );
1243
+ }
1244
+
1245
+ // src/components/interaction/DropdownMenu/DropdownMenu.tsx
1246
+ var import_react9 = require("react");
1247
+
1248
+ // src/components/interaction/DropdownMenu/DropdownMenu.module.css
1249
+ var DropdownMenu_default = {};
1250
+
1251
+ // src/components/interaction/DropdownMenu/DropdownMenu.tsx
1252
+ var import_design_system_foundation25 = require("@boostdev/design-system-foundation");
1253
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1254
+ function DropdownMenu({
1255
+ trigger,
1256
+ items,
1257
+ placement = "bottom-start",
1258
+ className
1259
+ }) {
1260
+ const [isOpen, setIsOpen] = (0, import_react9.useState)(false);
1261
+ const containerRef = (0, import_react9.useRef)(null);
1262
+ const menuId = (0, import_react9.useId)();
1263
+ const itemRefs = (0, import_react9.useRef)([]);
1264
+ const open = () => {
1265
+ setIsOpen(true);
1266
+ };
1267
+ const close = () => setIsOpen(false);
1268
+ (0, import_react9.useEffect)(() => {
1269
+ if (isOpen) {
1270
+ itemRefs.current[0]?.focus();
1271
+ }
1272
+ }, [isOpen]);
1273
+ (0, import_react9.useEffect)(() => {
1274
+ if (!isOpen) return;
1275
+ const handlePointerDown = (e) => {
1276
+ if (!containerRef.current?.contains(e.target)) close();
1277
+ };
1278
+ const handleKeyDown = (e) => {
1279
+ if (e.key === "Escape") close();
1280
+ };
1281
+ document.addEventListener("pointerdown", handlePointerDown);
1282
+ document.addEventListener("keydown", handleKeyDown);
1283
+ return () => {
1284
+ document.removeEventListener("pointerdown", handlePointerDown);
1285
+ document.removeEventListener("keydown", handleKeyDown);
1286
+ };
1287
+ }, [isOpen]);
1288
+ const handleItemKeyDown = (e, index) => {
1289
+ const enabledIndexes = items.map((item, i) => ({ item, i })).filter(({ item }) => !item.disabled).map(({ i }) => i);
1290
+ const pos = enabledIndexes.indexOf(index);
1291
+ if (e.key === "ArrowDown") {
1292
+ e.preventDefault();
1293
+ itemRefs.current[enabledIndexes[(pos + 1) % enabledIndexes.length]]?.focus();
1294
+ } else if (e.key === "ArrowUp") {
1295
+ e.preventDefault();
1296
+ itemRefs.current[enabledIndexes[(pos - 1 + enabledIndexes.length) % enabledIndexes.length]]?.focus();
1297
+ } else if (e.key === "Home") {
1298
+ e.preventDefault();
1299
+ itemRefs.current[enabledIndexes[0]]?.focus();
1300
+ } else if (e.key === "End") {
1301
+ e.preventDefault();
1302
+ itemRefs.current[enabledIndexes[enabledIndexes.length - 1]]?.focus();
1303
+ } else if (e.key === "Tab") {
1304
+ close();
1305
+ }
1306
+ };
1307
+ const triggerEl = (0, import_react9.isValidElement)(trigger) ? (0, import_react9.cloneElement)(trigger, {
1308
+ "aria-haspopup": "menu",
1309
+ "aria-expanded": isOpen,
1310
+ "aria-controls": menuId,
1311
+ onClick: (e) => {
1312
+ if (isOpen) {
1313
+ close();
1314
+ } else {
1315
+ open();
1316
+ }
1317
+ const existingOnClick = trigger.props.onClick;
1318
+ if (typeof existingOnClick === "function") existingOnClick(e);
1319
+ }
1320
+ }) : trigger;
1321
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { ref: containerRef, className: (0, import_design_system_foundation25.cn)(DropdownMenu_default.wrapper, className), children: [
1322
+ triggerEl,
1323
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1324
+ "ul",
1325
+ {
1326
+ id: menuId,
1327
+ role: "menu",
1328
+ className: (0, import_design_system_foundation25.cn)(DropdownMenu_default.menu, DropdownMenu_default[`--placement_${placement}`]),
1329
+ children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("li", { role: "presentation", children: [
1330
+ item.separator && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("hr", { className: DropdownMenu_default.separator, role: "separator" }),
1331
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1332
+ "button",
1333
+ {
1334
+ ref: (el) => {
1335
+ itemRefs.current[index] = el;
1336
+ },
1337
+ type: "button",
1338
+ role: "menuitem",
1339
+ disabled: item.disabled,
1340
+ className: DropdownMenu_default.item,
1341
+ onClick: () => {
1342
+ item.onClick?.();
1343
+ close();
1344
+ },
1345
+ onKeyDown: (e) => handleItemKeyDown(e, index),
1346
+ children: [
1347
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: DropdownMenu_default.icon, "aria-hidden": "true", children: item.icon }),
1348
+ item.label
1349
+ ]
1350
+ }
1351
+ )
1352
+ ] }, item.id))
1353
+ }
1354
+ )
1355
+ ] });
1356
+ }
1357
+
1358
+ // src/components/interaction/Popover/Popover.tsx
1359
+ var import_react10 = require("react");
1360
+
1361
+ // src/components/interaction/Popover/Popover.module.css
1362
+ var Popover_default = {};
1363
+
1364
+ // src/components/interaction/Popover/Popover.tsx
1365
+ var import_design_system_foundation26 = require("@boostdev/design-system-foundation");
1366
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1367
+ function Popover({
1368
+ children,
1369
+ content,
1370
+ placement = "bottom",
1371
+ className
1372
+ }) {
1373
+ const [isOpen, setIsOpen] = (0, import_react10.useState)(false);
1374
+ const containerRef = (0, import_react10.useRef)(null);
1375
+ const panelId = (0, import_react10.useId)();
1376
+ (0, import_react10.useEffect)(() => {
1377
+ if (!isOpen) return;
1378
+ const handlePointerDown = (e) => {
1379
+ if (!containerRef.current?.contains(e.target)) {
1380
+ setIsOpen(false);
1381
+ }
1382
+ };
1383
+ const handleKeyDown = (e) => {
1384
+ if (e.key === "Escape") setIsOpen(false);
1385
+ };
1386
+ document.addEventListener("pointerdown", handlePointerDown);
1387
+ document.addEventListener("keydown", handleKeyDown);
1388
+ return () => {
1389
+ document.removeEventListener("pointerdown", handlePointerDown);
1390
+ document.removeEventListener("keydown", handleKeyDown);
1391
+ };
1392
+ }, [isOpen]);
1393
+ const trigger = (0, import_react10.isValidElement)(children) ? (0, import_react10.cloneElement)(children, {
1394
+ "aria-expanded": isOpen,
1395
+ "aria-controls": panelId,
1396
+ onClick: (e) => {
1397
+ setIsOpen((prev) => !prev);
1398
+ const existingOnClick = children.props.onClick;
1399
+ if (typeof existingOnClick === "function") existingOnClick(e);
1400
+ }
1401
+ }) : children;
1402
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { ref: containerRef, className: (0, import_design_system_foundation26.cn)(Popover_default.wrapper, className), children: [
1403
+ trigger,
1404
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
1405
+ "div",
1406
+ {
1407
+ id: panelId,
1408
+ role: "dialog",
1409
+ "aria-modal": "false",
1410
+ className: (0, import_design_system_foundation26.cn)(Popover_default.panel, Popover_default[`--placement_${placement}`]),
1411
+ children: content
1412
+ }
1413
+ )
1414
+ ] });
1415
+ }
1416
+
1417
+ // src/components/interaction/Rating/Rating.module.css
1418
+ var Rating_default = {};
1419
+
1420
+ // src/components/interaction/Rating/Rating.tsx
1421
+ var import_design_system_foundation27 = require("@boostdev/design-system-foundation");
1422
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1423
+ function Rating({ value, max = 5, className }) {
1424
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1425
+ "div",
1426
+ {
1427
+ className: (0, import_design_system_foundation27.cn)(Rating_default.rating, className),
1428
+ role: "img",
1429
+ "aria-label": `${value} out of ${max} stars`,
1430
+ children: Array.from({ length: max }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1431
+ "svg",
1432
+ {
1433
+ "aria-hidden": "true",
1434
+ className: (0, import_design_system_foundation27.cn)(Rating_default.star, i < value && Rating_default["--filled"]),
1435
+ fill: "currentColor",
1436
+ viewBox: "0 0 24 24",
1437
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("path", { d: "M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" })
1438
+ },
1439
+ i
1440
+ ))
1441
+ }
1442
+ );
1443
+ }
1444
+
1445
+ // src/components/interaction/Toast/Toast.tsx
1446
+ var import_react11 = require("react");
1447
+
1448
+ // src/components/interaction/Toast/Toast.module.css
1449
+ var Toast_default = {};
1450
+
1451
+ // src/components/interaction/Toast/Toast.tsx
1452
+ var import_design_system_foundation28 = require("@boostdev/design-system-foundation");
1453
+ var import_jsx_runtime29 = require("react/jsx-runtime");
1454
+ var ToastContext = (0, import_react11.createContext)(void 0);
1455
+ function ToastProvider({ children }) {
1456
+ const [toasts, setToasts] = (0, import_react11.useState)([]);
1457
+ const showToast = (0, import_react11.useCallback)((message, variant) => {
1458
+ const id = Math.random().toString(36).substring(2, 9);
1459
+ setToasts((prev) => [...prev, { id, message, variant }]);
1460
+ }, []);
1461
+ const removeToast = (0, import_react11.useCallback)((id) => {
1462
+ setToasts((prev) => prev.filter((toast) => toast.id !== id));
1463
+ }, []);
1464
+ const value = (0, import_react11.useMemo)(() => ({ showToast }), [showToast]);
1465
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(ToastContext.Provider, { value, children: [
1466
+ children,
1467
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: Toast_default.toastContainer, children: toasts.map((toast) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1468
+ ToastItem,
1469
+ {
1470
+ toast,
1471
+ onRemove: () => removeToast(toast.id)
1472
+ },
1473
+ toast.id
1474
+ )) })
1475
+ ] });
1476
+ }
1477
+ function ToastItem({ toast, onRemove }) {
1478
+ (0, import_react11.useEffect)(() => {
1479
+ const timer = setTimeout(onRemove, 5e3);
1480
+ return () => clearTimeout(timer);
1481
+ }, [onRemove]);
1482
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: (0, import_design_system_foundation28.cn)(Toast_default.toast, Toast_default[`--variant_${toast.variant}`]), children: toast.message });
1483
+ }
1484
+ function useToast() {
1485
+ const context = (0, import_react11.useContext)(ToastContext);
1486
+ if (!context) {
1487
+ throw new Error("useToast must be used within a ToastProvider");
1488
+ }
1489
+ return context;
1490
+ }
1491
+
1492
+ // src/components/interaction/form/Checkbox/Checkbox.tsx
1493
+ var import_react12 = require("react");
1494
+
1495
+ // src/components/interaction/form/Checkbox/Checkbox.module.css
1496
+ var Checkbox_default = {};
1497
+
1498
+ // src/components/interaction/form/atoms/Message.module.css
1499
+ var Message_default = {};
1500
+
1501
+ // src/components/interaction/form/atoms/Message.tsx
1502
+ var import_jsx_runtime30 = require("react/jsx-runtime");
1503
+ var Message = ({ message, type, inputId }) => {
1504
+ if (!message) return null;
1505
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("label", { id: inputId + type, htmlFor: inputId, className: Message_default[type], children: message });
1506
+ };
1507
+
1508
+ // src/components/interaction/form/atoms/Label.module.css
1509
+ var Label_default = {};
1510
+
1511
+ // src/components/interaction/form/atoms/Label.tsx
1512
+ var import_jsx_runtime31 = require("react/jsx-runtime");
1513
+ var Label = ({ label, id }) => {
1514
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("label", { htmlFor: id, className: Label_default.label, children: label });
1515
+ };
1516
+
1517
+ // src/components/interaction/form/Checkbox/Checkbox.tsx
1518
+ var import_design_system_foundation30 = require("@boostdev/design-system-foundation");
1519
+
1520
+ // src/components/interaction/form/atoms/InputContainer.module.css
1521
+ var InputContainer_default = {};
1522
+
1523
+ // src/components/interaction/form/atoms/InputContainer.tsx
1524
+ var import_design_system_foundation29 = require("@boostdev/design-system-foundation");
1525
+ var import_jsx_runtime32 = require("react/jsx-runtime");
1526
+ var InputContainer = ({ children, className }) => {
1527
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: (0, import_design_system_foundation29.cn)(InputContainer_default.container, className), children });
1528
+ };
1529
+
1530
+ // src/components/interaction/form/Checkbox/Checkbox.tsx
1531
+ var import_jsx_runtime33 = require("react/jsx-runtime");
1532
+ function Checkbox({ label, name, error, hint, className, ...props }) {
1533
+ const id = name + (0, import_react12.useId)();
1534
+ const hintId = id + "hint";
1535
+ const errorId = id + "error";
1536
+ const describedBy = !!error ? errorId : hintId;
1537
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(InputContainer, { className: (0, import_design_system_foundation30.cn)(Checkbox_default.checkboxGroup, className), children: [
1538
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: Checkbox_default.inputWrapper, children: [
1539
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
1540
+ "input",
1541
+ {
1542
+ "aria-describedby": describedBy,
1543
+ type: "checkbox",
1544
+ id,
1545
+ name,
1546
+ className: `${Checkbox_default.checkbox} ${error ? Checkbox_default.checkboxError : ""}`,
1547
+ ...props
1548
+ }
1549
+ ),
1550
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Label, { id, label })
1551
+ ] }),
1552
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Message, { inputId: id, type: "error", message: error }),
1553
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Message, { inputId: id, type: "hint", message: hint })
1554
+ ] });
1555
+ }
1556
+
1557
+ // src/components/interaction/form/Combobox/Combobox.tsx
1558
+ var import_react13 = require("react");
1559
+
1560
+ // src/components/interaction/form/Combobox/Combobox.module.css
1561
+ var Combobox_default = {};
1562
+
1563
+ // src/components/interaction/form/Combobox/Combobox.tsx
1564
+ var import_design_system_foundation31 = require("@boostdev/design-system-foundation");
1565
+ var import_jsx_runtime34 = require("react/jsx-runtime");
1566
+ function Combobox({
1567
+ label,
1568
+ name,
1569
+ options,
1570
+ placeholder,
1571
+ value,
1572
+ onChange,
1573
+ error,
1574
+ hint,
1575
+ className
1576
+ }) {
1577
+ const id = name + (0, import_react13.useId)();
1578
+ const listboxId = id + "listbox";
1579
+ const hintId = id + "hint";
1580
+ const errorId = id + "error";
1581
+ const describedBy = error ? errorId : hintId;
1582
+ const selectedOption = options.find((o) => o.value === value);
1583
+ const [inputValue, setInputValue] = (0, import_react13.useState)(selectedOption?.label ?? "");
1584
+ const [isOpen, setIsOpen] = (0, import_react13.useState)(false);
1585
+ const [highlightedIndex, setHighlightedIndex] = (0, import_react13.useState)(-1);
1586
+ const containerRef = (0, import_react13.useRef)(null);
1587
+ const inputRef = (0, import_react13.useRef)(null);
1588
+ const filtered = options.filter(
1589
+ (o) => o.label.toLowerCase().includes(inputValue.toLowerCase())
1590
+ );
1591
+ const getOptionId = (index) => `${id}-option-${index}`;
1592
+ (0, import_react13.useEffect)(() => {
1593
+ if (!isOpen) return;
1594
+ const handlePointerDown = (e) => {
1595
+ if (!containerRef.current?.contains(e.target)) setIsOpen(false);
1596
+ };
1597
+ document.addEventListener("pointerdown", handlePointerDown);
1598
+ return () => document.removeEventListener("pointerdown", handlePointerDown);
1599
+ }, [isOpen]);
1600
+ const selectOption = (option) => {
1601
+ setInputValue(option.label);
1602
+ setIsOpen(false);
1603
+ setHighlightedIndex(-1);
1604
+ onChange?.(option.value);
1605
+ };
1606
+ const handleInputChange = (e) => {
1607
+ setInputValue(e.target.value);
1608
+ setIsOpen(true);
1609
+ setHighlightedIndex(-1);
1610
+ };
1611
+ const handleKeyDown = (e) => {
1612
+ const enabledIndexes = filtered.map((opt, i) => ({ opt, i })).filter(({ opt }) => !opt.disabled).map(({ i }) => i);
1613
+ if (e.key === "ArrowDown") {
1614
+ e.preventDefault();
1615
+ if (!isOpen) {
1616
+ setIsOpen(true);
1617
+ return;
1618
+ }
1619
+ const pos = enabledIndexes.indexOf(highlightedIndex);
1620
+ setHighlightedIndex(enabledIndexes[(pos + 1) % enabledIndexes.length] ?? 0);
1621
+ } else if (e.key === "ArrowUp") {
1622
+ e.preventDefault();
1623
+ const pos = enabledIndexes.indexOf(highlightedIndex);
1624
+ setHighlightedIndex(
1625
+ enabledIndexes[(pos - 1 + enabledIndexes.length) % enabledIndexes.length] ?? 0
1626
+ );
1627
+ } else if (e.key === "Enter") {
1628
+ e.preventDefault();
1629
+ if (highlightedIndex >= 0 && filtered[highlightedIndex]) {
1630
+ selectOption(filtered[highlightedIndex]);
1631
+ }
1632
+ } else if (e.key === "Escape") {
1633
+ setIsOpen(false);
1634
+ setHighlightedIndex(-1);
1635
+ } else if (e.key === "Tab") {
1636
+ setIsOpen(false);
1637
+ }
1638
+ };
1639
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(InputContainer, { className: (0, import_design_system_foundation31.cn)(Combobox_default.formGroup, className), children: [
1640
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Label, { id, label }),
1641
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { ref: containerRef, className: Combobox_default.inputWrapper, children: [
1642
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1643
+ "input",
1644
+ {
1645
+ ref: inputRef,
1646
+ id,
1647
+ name,
1648
+ type: "text",
1649
+ role: "combobox",
1650
+ "aria-expanded": isOpen,
1651
+ "aria-haspopup": "listbox",
1652
+ "aria-autocomplete": "list",
1653
+ "aria-controls": listboxId,
1654
+ "aria-activedescendant": highlightedIndex >= 0 ? getOptionId(highlightedIndex) : void 0,
1655
+ "aria-invalid": !!error,
1656
+ "aria-describedby": describedBy,
1657
+ autoComplete: "off",
1658
+ placeholder,
1659
+ value: inputValue,
1660
+ className: (0, import_design_system_foundation31.cn)(Combobox_default.input, error ? Combobox_default.inputError : void 0),
1661
+ onChange: handleInputChange,
1662
+ onKeyDown: handleKeyDown,
1663
+ onFocus: () => setIsOpen(true)
1664
+ }
1665
+ ),
1666
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: Combobox_default.chevron, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 9l6 6 6-6" }) }) }),
1667
+ isOpen && filtered.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1668
+ "ul",
1669
+ {
1670
+ id: listboxId,
1671
+ role: "listbox",
1672
+ "aria-label": String(label),
1673
+ className: Combobox_default.listbox,
1674
+ children: filtered.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1675
+ "li",
1676
+ {
1677
+ id: getOptionId(index),
1678
+ role: "option",
1679
+ "aria-selected": option.value === value,
1680
+ "aria-disabled": option.disabled,
1681
+ className: (0, import_design_system_foundation31.cn)(
1682
+ Combobox_default.option,
1683
+ index === highlightedIndex ? Combobox_default["--highlighted"] : void 0,
1684
+ option.value === value ? Combobox_default["--selected"] : void 0,
1685
+ option.disabled ? Combobox_default["--disabled"] : void 0
1686
+ ),
1687
+ onPointerDown: (e) => {
1688
+ e.preventDefault();
1689
+ if (!option.disabled) selectOption(option);
1690
+ },
1691
+ children: option.label
1692
+ },
1693
+ option.value
1694
+ ))
1695
+ }
1696
+ )
1697
+ ] }),
1698
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Message, { inputId: id, type: "error", message: error }),
1699
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Message, { inputId: id, type: "hint", message: hint })
1700
+ ] });
1701
+ }
1702
+
1703
+ // src/components/interaction/form/FileInput/FileInput.tsx
1704
+ var import_react14 = require("react");
1705
+
1706
+ // src/components/interaction/form/FileInput/FileInput.module.css
1707
+ var FileInput_default = {};
1708
+
1709
+ // src/components/interaction/form/FileInput/FileInput.tsx
1710
+ var import_design_system_foundation32 = require("@boostdev/design-system-foundation");
1711
+ var import_jsx_runtime35 = require("react/jsx-runtime");
1712
+ function FileInput({
1713
+ label,
1714
+ name,
1715
+ accept,
1716
+ multiple = false,
1717
+ disabled = false,
1718
+ error,
1719
+ hint,
1720
+ onChange,
1721
+ className
1722
+ }) {
1723
+ const uid = name + (0, import_react14.useId)();
1724
+ const hintId = uid + "hint";
1725
+ const errorId = uid + "error";
1726
+ const describedBy = error ? errorId : hintId;
1727
+ const inputRef = (0, import_react14.useRef)(null);
1728
+ const [isDragging, setIsDragging] = (0, import_react14.useState)(false);
1729
+ const [fileNames, setFileNames] = (0, import_react14.useState)([]);
1730
+ const handleFiles = (files) => {
1731
+ if (!files) return;
1732
+ setFileNames(Array.from(files).map((f) => f.name));
1733
+ onChange?.(files);
1734
+ };
1735
+ const handleChange = (e) => handleFiles(e.target.files);
1736
+ const handleDrop = (e) => {
1737
+ e.preventDefault();
1738
+ setIsDragging(false);
1739
+ if (disabled) return;
1740
+ handleFiles(e.dataTransfer.files);
1741
+ };
1742
+ const handleDragOver = (e) => {
1743
+ e.preventDefault();
1744
+ if (!disabled) setIsDragging(true);
1745
+ };
1746
+ const handleDragLeave = () => setIsDragging(false);
1747
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(InputContainer, { className: (0, import_design_system_foundation32.cn)(FileInput_default.formGroup, className), children: [
1748
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Label, { id: uid, label }),
1749
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
1750
+ "label",
1751
+ {
1752
+ htmlFor: uid,
1753
+ className: (0, import_design_system_foundation32.cn)(FileInput_default.dropZone, isDragging && FileInput_default.isDragging, error && FileInput_default.hasError, disabled && FileInput_default.isDisabled),
1754
+ onDrop: handleDrop,
1755
+ onDragOver: handleDragOver,
1756
+ onDragLeave: handleDragLeave,
1757
+ children: [
1758
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("svg", { "aria-hidden": "true", className: FileInput_default.icon, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5m-13.5-9L12 3m0 0l4.5 4.5M12 3v13.5" }) }),
1759
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: FileInput_default.prompt, children: fileNames.length > 0 ? fileNames.join(", ") : /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(import_jsx_runtime35.Fragment, { children: [
1760
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("strong", { children: "Click to upload" }),
1761
+ " or drag and drop"
1762
+ ] }) }),
1763
+ accept && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: FileInput_default.acceptHint, children: accept }),
1764
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
1765
+ "input",
1766
+ {
1767
+ ref: inputRef,
1768
+ id: uid,
1769
+ type: "file",
1770
+ name,
1771
+ accept,
1772
+ multiple,
1773
+ disabled,
1774
+ "aria-invalid": !!error,
1775
+ "aria-describedby": describedBy,
1776
+ className: FileInput_default.hiddenInput,
1777
+ onChange: handleChange
1778
+ }
1779
+ )
1780
+ ]
1781
+ }
1782
+ ),
1783
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Message, { inputId: uid, type: "error", message: error }),
1784
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Message, { inputId: uid, type: "hint", message: hint })
1785
+ ] });
1786
+ }
1787
+
1788
+ // src/components/interaction/form/FormInput/FormInput.tsx
1789
+ var import_react15 = require("react");
1790
+
1791
+ // src/components/interaction/form/FormInput/FormInput.module.css
1792
+ var FormInput_default = {};
1793
+
1794
+ // src/components/interaction/form/FormInput/FormInput.tsx
1795
+ var import_design_system_foundation33 = require("@boostdev/design-system-foundation");
1796
+ var import_jsx_runtime36 = require("react/jsx-runtime");
1797
+ function FormInput({
1798
+ label,
1799
+ name,
1800
+ ariaLabel,
1801
+ error,
1802
+ hint,
1803
+ className,
1804
+ ...props
1805
+ }) {
1806
+ const id = name + (0, import_react15.useId)();
1807
+ const hintId = id + "hint";
1808
+ const errorId = id + "error";
1809
+ const describedBy = !!error ? errorId : hintId;
1810
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(InputContainer, { className: (0, import_design_system_foundation33.cn)(FormInput_default.formGroup, className), children: [
1811
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Label, { id, label }),
1812
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
1813
+ "input",
1814
+ {
1815
+ "aria-invalid": !!error,
1816
+ "aria-describedby": describedBy,
1817
+ "aria-label": ariaLabel,
1818
+ id,
1819
+ name,
1820
+ className: `${FormInput_default.input} ${error ? FormInput_default.inputError : ""}`,
1821
+ ...props
1822
+ }
1823
+ ),
1824
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Message, { inputId: id, type: "error", message: error }),
1825
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Message, { inputId: id, type: "hint", message: hint })
1826
+ ] });
1827
+ }
1828
+
1829
+ // src/components/interaction/form/NumberInput/NumberInput.tsx
1830
+ var import_react16 = require("react");
1831
+
1832
+ // src/components/interaction/form/NumberInput/NumberInput.module.css
1833
+ var NumberInput_default = {};
1834
+
1835
+ // src/components/interaction/form/NumberInput/NumberInput.tsx
1836
+ var import_design_system_foundation34 = require("@boostdev/design-system-foundation");
1837
+ var import_jsx_runtime37 = require("react/jsx-runtime");
1838
+ function NumberInput({
1839
+ label,
1840
+ name,
1841
+ value,
1842
+ defaultValue,
1843
+ min,
1844
+ max,
1845
+ step = 1,
1846
+ disabled = false,
1847
+ error,
1848
+ hint,
1849
+ onChange,
1850
+ className
1851
+ }) {
1852
+ const uid = name + (0, import_react16.useId)();
1853
+ const hintId = uid + "hint";
1854
+ const errorId = uid + "error";
1855
+ const describedBy = error ? errorId : hintId;
1856
+ const inputRef = (0, import_react16.useRef)(null);
1857
+ const clamp = (v) => {
1858
+ const withMin = min !== void 0 ? Math.max(min, v) : v;
1859
+ const withMax = max !== void 0 ? Math.min(max, withMin) : withMin;
1860
+ return withMax;
1861
+ };
1862
+ const adjust = (delta) => {
1863
+ if (!inputRef.current) return;
1864
+ const current = parseFloat(inputRef.current.value) || 0;
1865
+ const next = clamp(current + delta);
1866
+ inputRef.current.value = String(next);
1867
+ onChange?.(next);
1868
+ };
1869
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(InputContainer, { className: (0, import_design_system_foundation34.cn)(NumberInput_default.formGroup, className), children: [
1870
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Label, { id: uid, label }),
1871
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: NumberInput_default.inputRow, children: [
1872
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1873
+ "button",
1874
+ {
1875
+ type: "button",
1876
+ className: NumberInput_default.stepper,
1877
+ "aria-label": "Decrease",
1878
+ disabled: disabled || min !== void 0 && (value ?? defaultValue ?? 0) <= min,
1879
+ onClick: () => adjust(-step),
1880
+ tabIndex: -1,
1881
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M5 12h14" }) })
1882
+ }
1883
+ ),
1884
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1885
+ "input",
1886
+ {
1887
+ ref: inputRef,
1888
+ id: uid,
1889
+ type: "number",
1890
+ name,
1891
+ defaultValue,
1892
+ value,
1893
+ min,
1894
+ max,
1895
+ step,
1896
+ disabled,
1897
+ "aria-invalid": !!error,
1898
+ "aria-describedby": describedBy,
1899
+ className: (0, import_design_system_foundation34.cn)(NumberInput_default.input, error ? NumberInput_default.inputError : void 0),
1900
+ onChange: (e) => onChange?.(parseFloat(e.target.value))
1901
+ }
1902
+ ),
1903
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
1904
+ "button",
1905
+ {
1906
+ type: "button",
1907
+ className: NumberInput_default.stepper,
1908
+ "aria-label": "Increase",
1909
+ disabled: disabled || max !== void 0 && (value ?? defaultValue ?? 0) >= max,
1910
+ onClick: () => adjust(step),
1911
+ tabIndex: -1,
1912
+ children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 5v14M5 12h14" }) })
1913
+ }
1914
+ )
1915
+ ] }),
1916
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Message, { inputId: uid, type: "error", message: error }),
1917
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Message, { inputId: uid, type: "hint", message: hint })
1918
+ ] });
1919
+ }
1920
+
1921
+ // src/components/interaction/form/Radio/Radio.tsx
1922
+ var import_react17 = require("react");
1923
+
1924
+ // src/components/interaction/form/Radio/Radio.module.css
1925
+ var Radio_default = {};
1926
+
1927
+ // src/components/interaction/form/Radio/Radio.tsx
1928
+ var import_design_system_foundation35 = require("@boostdev/design-system-foundation");
1929
+ var import_jsx_runtime38 = require("react/jsx-runtime");
1930
+ function Radio({ label, name, error, hint, className, ...props }) {
1931
+ const id = name + (0, import_react17.useId)();
1932
+ const hintId = id + "hint";
1933
+ const errorId = id + "error";
1934
+ const describedBy = !!error ? errorId : hintId;
1935
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(InputContainer, { className: (0, import_design_system_foundation35.cn)(Radio_default.radioGroup, className), children: [
1936
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: Radio_default.inputWrapper, children: [
1937
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
1938
+ "input",
1939
+ {
1940
+ "aria-describedby": describedBy,
1941
+ type: "radio",
1942
+ id,
1943
+ name,
1944
+ className: `${Radio_default.radio} ${error ? Radio_default.radioError : ""}`,
1945
+ ...props
1946
+ }
1947
+ ),
1948
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Label, { id, label })
1949
+ ] }),
1950
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Message, { inputId: id, type: "error", message: error }),
1951
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Message, { inputId: id, type: "hint", message: hint })
1952
+ ] });
1953
+ }
1954
+
1955
+ // src/components/interaction/form/Select/Select.tsx
1956
+ var import_react18 = require("react");
1957
+
1958
+ // src/components/interaction/form/Select/Select.module.css
1959
+ var Select_default = {};
1960
+
1961
+ // src/components/interaction/form/Select/Select.tsx
1962
+ var import_design_system_foundation36 = require("@boostdev/design-system-foundation");
1963
+ var import_jsx_runtime39 = require("react/jsx-runtime");
1964
+ function Select({
1965
+ label,
1966
+ name,
1967
+ options,
1968
+ placeholder,
1969
+ error,
1970
+ hint,
1971
+ className,
1972
+ ...props
1973
+ }) {
1974
+ const id = name + (0, import_react18.useId)();
1975
+ const hintId = id + "hint";
1976
+ const errorId = id + "error";
1977
+ const describedBy = error ? errorId : hintId;
1978
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(InputContainer, { className: (0, import_design_system_foundation36.cn)(Select_default.formGroup, className), children: [
1979
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Label, { id, label }),
1980
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: Select_default.selectWrapper, children: [
1981
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
1982
+ "select",
1983
+ {
1984
+ id,
1985
+ name,
1986
+ "aria-invalid": !!error,
1987
+ "aria-describedby": describedBy,
1988
+ className: (0, import_design_system_foundation36.cn)(Select_default.select, error ? Select_default.selectError : void 0),
1989
+ ...props,
1990
+ children: [
1991
+ placeholder && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("option", { value: "", disabled: true, children: placeholder }),
1992
+ options.map(({ value, label: optLabel, disabled }) => /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("option", { value, disabled, children: optLabel }, value))
1993
+ ]
1994
+ }
1995
+ ),
1996
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: Select_default.chevron, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 9l6 6 6-6" }) }) })
1997
+ ] }),
1998
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Message, { inputId: id, type: "error", message: error }),
1999
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Message, { inputId: id, type: "hint", message: hint })
2000
+ ] });
2001
+ }
2002
+
2003
+ // src/components/interaction/form/Slider/Slider.tsx
2004
+ var import_react19 = require("react");
2005
+
2006
+ // src/components/interaction/form/Slider/Slider.module.css
2007
+ var Slider_default = {};
2008
+
2009
+ // src/components/interaction/form/Slider/Slider.tsx
2010
+ var import_design_system_foundation37 = require("@boostdev/design-system-foundation");
2011
+ var import_jsx_runtime40 = require("react/jsx-runtime");
2012
+ function Slider({
2013
+ label,
2014
+ name,
2015
+ min = 0,
2016
+ max = 100,
2017
+ showValue = false,
2018
+ error,
2019
+ hint,
2020
+ className,
2021
+ onChange,
2022
+ ...props
2023
+ }) {
2024
+ const id = name + (0, import_react19.useId)();
2025
+ const hintId = id + "hint";
2026
+ const errorId = id + "error";
2027
+ const describedBy = error ? errorId : hintId;
2028
+ const initialValue = Number(props.value ?? props.defaultValue ?? min);
2029
+ const [currentValue, setCurrentValue] = (0, import_react19.useState)(initialValue);
2030
+ const fillPct = (currentValue - min) / (max - min) * 100;
2031
+ const handleChange = (e) => {
2032
+ setCurrentValue(Number(e.target.value));
2033
+ onChange?.(e);
2034
+ };
2035
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(InputContainer, { className: (0, import_design_system_foundation37.cn)(Slider_default.formGroup, className), children: [
2036
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: Slider_default.labelRow, children: [
2037
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Label, { id, label }),
2038
+ showValue && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: Slider_default.value, children: currentValue })
2039
+ ] }),
2040
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2041
+ "input",
2042
+ {
2043
+ type: "range",
2044
+ id,
2045
+ name,
2046
+ min,
2047
+ max,
2048
+ "aria-describedby": describedBy,
2049
+ "aria-valuemin": min,
2050
+ "aria-valuemax": max,
2051
+ "aria-valuenow": currentValue,
2052
+ className: (0, import_design_system_foundation37.cn)(Slider_default.slider, error ? Slider_default.sliderError : void 0),
2053
+ style: { "--slider_fill": `${fillPct}%` },
2054
+ onChange: handleChange,
2055
+ ...props
2056
+ }
2057
+ ),
2058
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Message, { inputId: id, type: "error", message: error }),
2059
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Message, { inputId: id, type: "hint", message: hint })
2060
+ ] });
2061
+ }
2062
+
2063
+ // src/components/interaction/form/Switch/Switch.tsx
2064
+ var import_react20 = require("react");
2065
+
2066
+ // src/components/interaction/form/Switch/Switch.module.css
2067
+ var Switch_default = {};
2068
+
2069
+ // src/components/interaction/form/Switch/Switch.tsx
2070
+ var import_design_system_foundation38 = require("@boostdev/design-system-foundation");
2071
+ var import_jsx_runtime41 = require("react/jsx-runtime");
2072
+ function Switch({
2073
+ label,
2074
+ name,
2075
+ size = "medium",
2076
+ error,
2077
+ hint,
2078
+ className,
2079
+ ...props
2080
+ }) {
2081
+ const id = name + (0, import_react20.useId)();
2082
+ const hintId = id + "hint";
2083
+ const errorId = id + "error";
2084
+ const describedBy = error ? errorId : hintId;
2085
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(InputContainer, { className: (0, import_design_system_foundation38.cn)(Switch_default.switchGroup, Switch_default[`--size_${size}`], className), children: [
2086
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: Switch_default.inputWrapper, children: [
2087
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: Switch_default.trackWrapper, children: [
2088
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2089
+ "input",
2090
+ {
2091
+ type: "checkbox",
2092
+ role: "switch",
2093
+ id,
2094
+ name,
2095
+ "aria-describedby": describedBy,
2096
+ className: (0, import_design_system_foundation38.cn)(Switch_default.switch, error ? Switch_default.switchError : void 0),
2097
+ ...props
2098
+ }
2099
+ ),
2100
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: Switch_default.track, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: Switch_default.thumb }) })
2101
+ ] }),
2102
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Label, { id, label })
2103
+ ] }),
2104
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Message, { inputId: id, type: "error", message: error }),
2105
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Message, { inputId: id, type: "hint", message: hint })
2106
+ ] });
2107
+ }
2108
+
2109
+ // src/components/interaction/form/Textarea/Textarea.tsx
2110
+ var import_react21 = require("react");
2111
+
2112
+ // src/components/interaction/form/Textarea/Textarea.module.css
2113
+ var Textarea_default = {};
2114
+
2115
+ // src/components/interaction/form/Textarea/Textarea.tsx
2116
+ var import_design_system_foundation39 = require("@boostdev/design-system-foundation");
2117
+ var import_jsx_runtime42 = require("react/jsx-runtime");
2118
+ function Textarea({
2119
+ label,
2120
+ name,
2121
+ error,
2122
+ hint,
2123
+ className,
2124
+ ...props
2125
+ }) {
2126
+ const id = name + (0, import_react21.useId)();
2127
+ const hintId = id + "hint";
2128
+ const errorId = id + "error";
2129
+ const describedBy = error ? errorId : hintId;
2130
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(InputContainer, { className: (0, import_design_system_foundation39.cn)(Textarea_default.formGroup, className), children: [
2131
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Label, { id, label }),
2132
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2133
+ "textarea",
2134
+ {
2135
+ id,
2136
+ name,
2137
+ "aria-invalid": !!error,
2138
+ "aria-describedby": describedBy,
2139
+ className: (0, import_design_system_foundation39.cn)(Textarea_default.textarea, error ? Textarea_default.textareaError : void 0),
2140
+ ...props
2141
+ }
2142
+ ),
2143
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Message, { inputId: id, type: "error", message: error }),
2144
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Message, { inputId: id, type: "hint", message: hint })
2145
+ ] });
2146
+ }
2147
+
2148
+ // src/components/layout/ButtonGroup/ButtonGroup.module.css
2149
+ var ButtonGroup_default = {};
2150
+
2151
+ // src/components/layout/ButtonGroup/ButtonGroup.tsx
2152
+ var import_design_system_foundation40 = require("@boostdev/design-system-foundation");
2153
+ var import_jsx_runtime43 = require("react/jsx-runtime");
2154
+ function ButtonGroup({ children, className, variant }) {
2155
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: (0, import_design_system_foundation40.cn)(ButtonGroup_default.buttonGroup, className, variant && ButtonGroup_default[`--variant__${variant}`]), children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: ButtonGroup_default.container, children }) });
2156
+ }
2157
+
2158
+ // src/components/layout/Card/Card.module.css
2159
+ var Card_default = {};
2160
+
2161
+ // src/components/layout/Card/Card.tsx
2162
+ var import_design_system_foundation41 = require("@boostdev/design-system-foundation");
2163
+ var import_jsx_runtime44 = require("react/jsx-runtime");
2164
+ function Card({
2165
+ children,
2166
+ className,
2167
+ variant = "default",
2168
+ padding = "medium",
2169
+ textAlign = "start",
2170
+ style,
2171
+ onClick
2172
+ }) {
2173
+ const classNames = (0, import_design_system_foundation41.cn)(
2174
+ Card_default.card,
2175
+ Card_default[`--${variant}`],
2176
+ Card_default[`--padding-${padding}`],
2177
+ Card_default[`--text-${textAlign}`],
2178
+ onClick && Card_default["--clickable"],
2179
+ className
2180
+ );
2181
+ const Component = onClick ? "button" : "div";
2182
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2183
+ Component,
2184
+ {
2185
+ className: classNames,
2186
+ onClick,
2187
+ style,
2188
+ ...onClick && { type: "button" },
2189
+ children
2190
+ }
2191
+ );
2192
+ }
2193
+
2194
+ // src/components/layout/SectionHeader/SectionHeader.module.css
2195
+ var SectionHeader_default = {};
2196
+
2197
+ // src/components/layout/SectionHeader/SectionHeader.tsx
2198
+ var import_design_system_foundation42 = require("@boostdev/design-system-foundation");
2199
+ var import_jsx_runtime45 = require("react/jsx-runtime");
2200
+ function SectionHeader({
2201
+ title,
2202
+ subtitle,
2203
+ className,
2204
+ alignment = "start",
2205
+ size = "medium",
2206
+ titleAs = "h2"
2207
+ }) {
2208
+ const Title = titleAs;
2209
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("header", { className: (0, import_design_system_foundation42.cn)(SectionHeader_default.sectionHeader, SectionHeader_default[`--${alignment}`], SectionHeader_default[`--${size}`], className), children: [
2210
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Title, { className: SectionHeader_default.title, children: title }),
2211
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: SectionHeader_default.subtitle, children: subtitle })
2212
+ ] });
2213
+ }
2214
+
2215
+ // src/components/layout/IconWrapper/IconWrapper.module.css
2216
+ var IconWrapper_default = {};
2217
+
2218
+ // src/components/layout/IconWrapper/IconWrapper.tsx
2219
+ var import_design_system_foundation43 = require("@boostdev/design-system-foundation");
2220
+ var import_jsx_runtime46 = require("react/jsx-runtime");
2221
+ function IconWrapper({ children, className }) {
2222
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: (0, import_design_system_foundation43.cn)(className, IconWrapper_default.wrapper), children });
2223
+ }
2224
+
2225
+ // src/index.ts
2226
+ var import_design_system_foundation44 = require("@boostdev/design-system-foundation");
2227
+ // Annotate the CommonJS export names for ESM import in node:
2228
+ 0 && (module.exports = {
2229
+ Accordion,
2230
+ Alert,
2231
+ Avatar,
2232
+ Badge,
2233
+ Breadcrumb,
2234
+ Button,
2235
+ ButtonGroup,
2236
+ Calendar,
2237
+ Card,
2238
+ Carousel,
2239
+ Checkbox,
2240
+ Combobox,
2241
+ Command,
2242
+ DescriptionList,
2243
+ Dialog,
2244
+ Drawer,
2245
+ DropdownMenu,
2246
+ FileInput,
2247
+ FormInput,
2248
+ IconWrapper,
2249
+ Link,
2250
+ Loading,
2251
+ NotificationBanner,
2252
+ NumberInput,
2253
+ Pagination,
2254
+ Popover,
2255
+ Progress,
2256
+ ProgressCircle,
2257
+ Radio,
2258
+ Rating,
2259
+ SectionHeader,
2260
+ Select,
2261
+ Separator,
2262
+ Skeleton,
2263
+ SkipLink,
2264
+ Slider,
2265
+ Switch,
2266
+ Table,
2267
+ Tabs,
2268
+ Textarea,
2269
+ ToastProvider,
2270
+ Tooltip,
2271
+ Typography,
2272
+ cn,
2273
+ useToast
2274
+ });