@hellboy/ds 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/README.md +111 -0
  2. package/dist/index.css +3699 -0
  3. package/dist/index.css.map +1 -0
  4. package/dist/index.d.mts +1087 -0
  5. package/dist/index.d.ts +1087 -0
  6. package/dist/index.js +3391 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/index.mjs +3287 -0
  9. package/dist/index.mjs.map +1 -0
  10. package/dist/theme.css +55 -0
  11. package/hellboy-ds-0.1.2.tgz +0 -0
  12. package/package.json +42 -0
  13. package/src/components/badge/Badge.tsx +29 -0
  14. package/src/components/badge/index.ts +1 -0
  15. package/src/components/banner/Banner.tsx +48 -0
  16. package/src/components/banner/banner.css +44 -0
  17. package/src/components/banner/index.ts +1 -0
  18. package/src/components/button/button.tsx +127 -0
  19. package/src/components/button/index.ts +1 -0
  20. package/src/components/card/card.tsx +57 -0
  21. package/src/components/card/index.ts +1 -0
  22. package/src/components/checkbox/Checkbox.tsx +98 -0
  23. package/src/components/checkbox/index.ts +1 -0
  24. package/src/components/code-block/code-block.tsx +44 -0
  25. package/src/components/code-block/index.ts +1 -0
  26. package/src/components/color-control/color-control.tsx +322 -0
  27. package/src/components/color-control/index.ts +1 -0
  28. package/src/components/drag-handle/DragHandle.tsx +78 -0
  29. package/src/components/drag-handle/index.ts +1 -0
  30. package/src/components/drawer/drawer.tsx +82 -0
  31. package/src/components/drawer/index.ts +1 -0
  32. package/src/components/floating-bar/floating-bar.tsx +52 -0
  33. package/src/components/floating-bar/index.ts +2 -0
  34. package/src/components/footer/footer.tsx +28 -0
  35. package/src/components/footer/index.ts +1 -0
  36. package/src/components/grid/Grid.tsx +53 -0
  37. package/src/components/grid/index.ts +1 -0
  38. package/src/components/header/header.tsx +57 -0
  39. package/src/components/header/index.ts +1 -0
  40. package/src/components/icons/icons.tsx +44 -0
  41. package/src/components/icons/index.ts +1 -0
  42. package/src/components/index.ts +29 -0
  43. package/src/components/input/DatePicker.tsx +133 -0
  44. package/src/components/input/Input.tsx +220 -0
  45. package/src/components/input/InputDate.tsx +10 -0
  46. package/src/components/input/InputDateTime.tsx +10 -0
  47. package/src/components/input/InputEmail.tsx +10 -0
  48. package/src/components/input/InputField.tsx +137 -0
  49. package/src/components/input/InputNumber.tsx +10 -0
  50. package/src/components/input/InputPassword.tsx +10 -0
  51. package/src/components/input/InputSearch.tsx +10 -0
  52. package/src/components/input/InputTel.tsx +10 -0
  53. package/src/components/input/InputText.tsx +10 -0
  54. package/src/components/input/InputTime.tsx +10 -0
  55. package/src/components/input/InputUrl.tsx +10 -0
  56. package/src/components/input/TimePicker.tsx +151 -0
  57. package/src/components/input/index.ts +11 -0
  58. package/src/components/layout/Layout.tsx +244 -0
  59. package/src/components/layout/index.ts +1 -0
  60. package/src/components/list/List.tsx +159 -0
  61. package/src/components/list/index.ts +1 -0
  62. package/src/components/navbar/MenuCategory.tsx +20 -0
  63. package/src/components/navbar/MenuGroup.tsx +288 -0
  64. package/src/components/navbar/MenuItem.tsx +65 -0
  65. package/src/components/navbar/Navbar.tsx +23 -0
  66. package/src/components/navbar/index.ts +4 -0
  67. package/src/components/page/index.ts +1 -0
  68. package/src/components/page/page.tsx +46 -0
  69. package/src/components/page-index/PageIndex.tsx +275 -0
  70. package/src/components/page-index/index.ts +1 -0
  71. package/src/components/popover/index.ts +1 -0
  72. package/src/components/popover/popover.tsx +199 -0
  73. package/src/components/radio/Radio.tsx +176 -0
  74. package/src/components/radio/index.ts +1 -0
  75. package/src/components/section/index.ts +1 -0
  76. package/src/components/section/section.tsx +66 -0
  77. package/src/components/select/Select.tsx +212 -0
  78. package/src/components/select/index.ts +1 -0
  79. package/src/components/slider/Slider.tsx +267 -0
  80. package/src/components/slider/index.ts +1 -0
  81. package/src/components/switch/index.ts +1 -0
  82. package/src/components/switch/switch.tsx +99 -0
  83. package/src/components/table/Table.tsx +147 -0
  84. package/src/components/table/index.ts +1 -0
  85. package/src/components/theme-control/index.ts +1 -0
  86. package/src/components/theme-control/theme-control.tsx +78 -0
  87. package/src/components/tooltip/index.ts +1 -0
  88. package/src/components/tooltip/tooltip.tsx +207 -0
  89. package/src/contexts/NavbarTooltipContext.tsx +48 -0
  90. package/src/contexts/index.ts +1 -0
  91. package/src/foundations/motion.md +136 -0
  92. package/src/index.ts +40 -0
  93. package/src/style/_shared/field.css +69 -0
  94. package/src/style/components/badge/badge.css +74 -0
  95. package/src/style/components/button/button.css +244 -0
  96. package/src/style/components/card/card.css +69 -0
  97. package/src/style/components/checkbox.css +142 -0
  98. package/src/style/components/code-block/code-block.css +34 -0
  99. package/src/style/components/color-control/color-control.css +126 -0
  100. package/src/style/components/drag-handle/drag-handle.css +68 -0
  101. package/src/style/components/drawer/drawer.css +210 -0
  102. package/src/style/components/floating-bar/floating-bar.css +39 -0
  103. package/src/style/components/footer/footer.css +108 -0
  104. package/src/style/components/grid/grid.css +33 -0
  105. package/src/style/components/header/header.css +44 -0
  106. package/src/style/components/icons/icons.css +44 -0
  107. package/src/style/components/input/input.css +393 -0
  108. package/src/style/components/layout/layout.css +205 -0
  109. package/src/style/components/list/list.css +140 -0
  110. package/src/style/components/navbar/navbar.css +342 -0
  111. package/src/style/components/page/page.css +46 -0
  112. package/src/style/components/page-index/page-index.css +158 -0
  113. package/src/style/components/popover/popover.css +44 -0
  114. package/src/style/components/radio.css +178 -0
  115. package/src/style/components/section/section.css +67 -0
  116. package/src/style/components/select/select.css +143 -0
  117. package/src/style/components/slider/slider.css +159 -0
  118. package/src/style/components/switch/switch.css +267 -0
  119. package/src/style/components/table/table.css +108 -0
  120. package/src/style/components/theme-control/theme-control.css +35 -0
  121. package/src/style/components/tooltip/tooltip.css +52 -0
  122. package/src/style/foundations/global.css +316 -0
  123. package/src/style/foundations/motion.css +164 -0
  124. package/src/style/foundations/spacing.css +51 -0
  125. package/src/style/foundations/typography.css +39 -0
  126. package/src/style/foundations/z-index.css +81 -0
  127. package/src/style/modes/dark.css +146 -0
  128. package/src/style/modes/light.css +147 -0
  129. package/src/style/semantic.css +52 -0
  130. package/src/style/styles.css +51 -0
  131. package/src/style/themes/theme.json +37 -0
  132. package/src/utils/README.md +305 -0
  133. package/src/utils/USER_PREFERENCES.md +558 -0
  134. package/src/utils/theme.ts +127 -0
  135. package/src/utils/user-preferences.ts +577 -0
  136. package/tsconfig.json +25 -0
  137. package/tsup.config.ts +52 -0
package/dist/index.js ADDED
@@ -0,0 +1,3391 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
31
+
32
+ // src/index.ts
33
+ var index_exports = {};
34
+ __export(index_exports, {
35
+ Badge: () => Badge,
36
+ Banner: () => Banner,
37
+ Button: () => Button,
38
+ Card: () => Card,
39
+ Checkbox: () => Checkbox,
40
+ CodeBlock: () => CodeBlock,
41
+ ColorControl: () => ColorControl,
42
+ DragHandle: () => DragHandle,
43
+ Drawer: () => Drawer,
44
+ FloatingBar: () => FloatingBar,
45
+ Footer: () => Footer,
46
+ Grid: () => Grid,
47
+ Header: () => Header,
48
+ Icon: () => Icon,
49
+ InputDate: () => InputDate,
50
+ InputDateTime: () => InputDateTime,
51
+ InputEmail: () => InputEmail,
52
+ InputNumber: () => InputNumber,
53
+ InputPassword: () => InputPassword,
54
+ InputSearch: () => InputSearch,
55
+ InputTel: () => InputTel,
56
+ InputText: () => InputText,
57
+ InputTime: () => InputTime,
58
+ InputUrl: () => InputUrl,
59
+ Layout: () => Layout,
60
+ List: () => List,
61
+ ListItem: () => ListItem,
62
+ MenuCategory: () => MenuCategory,
63
+ MenuGroup: () => MenuGroup,
64
+ MenuItem: () => MenuItem,
65
+ Navbar: () => Navbar,
66
+ NavbarTooltipProvider: () => NavbarTooltipProvider,
67
+ Page: () => Page,
68
+ PageIndex: () => PageIndex,
69
+ Popover: () => Popover,
70
+ Radio: () => Radio,
71
+ RadioGroup: () => RadioGroup,
72
+ Section: () => Section,
73
+ Select: () => Select,
74
+ Slider: () => Slider,
75
+ Switch: () => Switch,
76
+ Table: () => Table,
77
+ TableBody: () => TableBody,
78
+ TableCell: () => TableCell,
79
+ TableContainer: () => TableContainer,
80
+ TableHead: () => TableHead,
81
+ TableRow: () => TableRow,
82
+ ThemeControl: () => ThemeControl,
83
+ Tooltip: () => Tooltip,
84
+ applyTheme: () => applyTheme,
85
+ clearPreferences: () => clearPreferences,
86
+ clearPreferencesAsync: () => clearPreferencesAsync,
87
+ configurePreferences: () => configurePreferences,
88
+ createPreferenceNamespace: () => createPreferenceNamespace,
89
+ exportPreferences: () => exportPreferences,
90
+ getAllPreferences: () => getAllPreferences,
91
+ getPreference: () => getPreference,
92
+ getPreferenceAsync: () => getPreferenceAsync,
93
+ getSavedTheme: () => getSavedTheme,
94
+ getTheme: () => getTheme,
95
+ importPreferences: () => importPreferences,
96
+ initializeTheme: () => initializeTheme,
97
+ onSystemThemeChange: () => onSystemThemeChange,
98
+ removePreference: () => removePreference,
99
+ removePreferenceAsync: () => removePreferenceAsync,
100
+ setPreference: () => setPreference,
101
+ setPreferenceAsync: () => setPreferenceAsync,
102
+ setTheme: () => setTheme,
103
+ toggleTheme: () => toggleTheme,
104
+ useNavbarTooltip: () => useNavbarTooltip
105
+ });
106
+ module.exports = __toCommonJS(index_exports);
107
+
108
+ // src/contexts/NavbarTooltipContext.tsx
109
+ var React = __toESM(require("react"));
110
+ var import_jsx_runtime = require("react/jsx-runtime");
111
+ var NavbarTooltipContext = React.createContext(void 0);
112
+ var NavbarTooltipProvider = ({ children }) => {
113
+ const [hasOpenPopover, setHasOpenPopover] = React.useState(false);
114
+ const [activePopoverId, setActivePopoverId] = React.useState(null);
115
+ const openPopover = React.useCallback((id) => {
116
+ setActivePopoverId(id);
117
+ setHasOpenPopover(true);
118
+ }, []);
119
+ const closePopover = React.useCallback((id) => {
120
+ if (activePopoverId === id) {
121
+ setActivePopoverId(null);
122
+ setHasOpenPopover(false);
123
+ }
124
+ }, [activePopoverId]);
125
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(NavbarTooltipContext.Provider, { value: {
126
+ hasOpenPopover,
127
+ setHasOpenPopover,
128
+ openPopover,
129
+ closePopover,
130
+ activePopoverId
131
+ }, children });
132
+ };
133
+ var useNavbarTooltip = () => {
134
+ const context = React.useContext(NavbarTooltipContext);
135
+ if (!context) {
136
+ throw new Error("useNavbarTooltip must be used within a NavbarTooltipProvider");
137
+ }
138
+ return context;
139
+ };
140
+
141
+ // src/components/button/button.tsx
142
+ var import_react2 = __toESM(require("react"));
143
+ var import_react3 = require("@ariakit/react");
144
+
145
+ // src/components/icons/icons.tsx
146
+ var import_react = require("@iconify/react");
147
+ var import_jsx_runtime2 = require("react/jsx-runtime");
148
+ var Icon = ({ name, size = 24, className, loading = false, ...rest }) => {
149
+ const iconName = name.startsWith("famicons:") ? name : `famicons:${name}`;
150
+ const classes = ["icon", className].filter(Boolean).join(" ");
151
+ if (loading) {
152
+ const style = { width: size, height: size };
153
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
154
+ "span",
155
+ {
156
+ className: `${classes} icon--skeleton`,
157
+ style,
158
+ "aria-hidden": rest["aria-label"] ? "false" : "true",
159
+ ...rest["aria-label"] ? { "aria-label": rest["aria-label"] } : {}
160
+ }
161
+ );
162
+ }
163
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
164
+ import_react.Icon,
165
+ {
166
+ icon: iconName,
167
+ width: size,
168
+ height: size,
169
+ className: classes,
170
+ ...rest
171
+ }
172
+ );
173
+ };
174
+
175
+ // src/components/button/button.tsx
176
+ var import_jsx_runtime3 = require("react/jsx-runtime");
177
+ var Button = import_react2.default.forwardRef(
178
+ ({
179
+ variant = "primary",
180
+ size = "md",
181
+ children,
182
+ isLoading = false,
183
+ disabled = false,
184
+ fullWidth = false,
185
+ startIcon,
186
+ endIcon,
187
+ iconOnly = false,
188
+ href,
189
+ className,
190
+ onClick,
191
+ ...props
192
+ }, ref) => {
193
+ const buttonClasses = [
194
+ "btn",
195
+ `btn--${variant}`,
196
+ `btn--${size}`,
197
+ fullWidth && "btn--full-width",
198
+ iconOnly && "btn--icon-only",
199
+ className
200
+ ].filter(Boolean).join(" ");
201
+ const iconSize = size === "xs" ? 14 : size === "sm" ? 16 : size === "lg" ? 24 : 20;
202
+ const buttonContent = /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
203
+ isLoading && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "btn__spinner" }),
204
+ startIcon && (isLoading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "btn__icon-placeholder", style: { width: iconSize, height: iconSize } }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon, { name: startIcon, size: iconSize, className: "btn__icon" })),
205
+ !iconOnly && children,
206
+ endIcon && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Icon, { name: endIcon, size: iconSize, className: "btn__icon" })
207
+ ] });
208
+ const handleClick = (e) => {
209
+ if (href && !isLoading && !disabled) {
210
+ window.location.href = href;
211
+ }
212
+ onClick?.(e);
213
+ };
214
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
215
+ import_react3.Button,
216
+ {
217
+ ref,
218
+ disabled: disabled || isLoading,
219
+ className: buttonClasses,
220
+ onClick: handleClick,
221
+ ...props,
222
+ children: buttonContent
223
+ }
224
+ );
225
+ }
226
+ );
227
+ Button.displayName = "Button";
228
+
229
+ // src/components/badge/Badge.tsx
230
+ var import_jsx_runtime4 = require("react/jsx-runtime");
231
+ var Badge = ({
232
+ variant = "primary",
233
+ size = "md",
234
+ className = "",
235
+ children,
236
+ ...props
237
+ }) => {
238
+ const classes = ["badge", `badge--${variant}`, `badge--${size}`, className].filter(Boolean).join(" ");
239
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: classes, ...props, children });
240
+ };
241
+
242
+ // src/components/checkbox/Checkbox.tsx
243
+ var import_react4 = __toESM(require("react"));
244
+ var import_react5 = require("@ariakit/react");
245
+ var import_jsx_runtime5 = require("react/jsx-runtime");
246
+ var Checkbox = import_react4.default.forwardRef(
247
+ ({
248
+ size = "md",
249
+ label,
250
+ error,
251
+ helperText,
252
+ indeterminate = false,
253
+ disabled = false,
254
+ className,
255
+ checked,
256
+ ...props
257
+ }, ref) => {
258
+ const checkboxClasses = [
259
+ "checkbox",
260
+ `checkbox--${size}`,
261
+ error && "checkbox--error",
262
+ disabled && "checkbox--disabled",
263
+ className
264
+ ].filter(Boolean).join(" ");
265
+ const iconSize = size === "sm" ? 14 : size === "lg" ? 20 : 16;
266
+ const isChecked = checked === true;
267
+ const isIndeterminate = indeterminate && !isChecked;
268
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: checkboxClasses, children: [
269
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "checkbox__container", children: [
270
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
271
+ import_react5.Checkbox,
272
+ {
273
+ ref,
274
+ checked,
275
+ disabled,
276
+ className: "checkbox__input",
277
+ ...props
278
+ }
279
+ ),
280
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "checkbox__box", children: [
281
+ isChecked && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "checkmark-sharp", size: iconSize, className: "checkbox__icon" }),
282
+ isIndeterminate && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "minus", size: iconSize, className: "checkbox__icon" })
283
+ ] }),
284
+ label && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "checkbox__label", children: label })
285
+ ] }),
286
+ (error || helperText) && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "checkbox__feedback", children: [
287
+ error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "checkbox__error-text", children: error }),
288
+ !error && helperText && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "checkbox__helper-text", children: helperText })
289
+ ] })
290
+ ] });
291
+ }
292
+ );
293
+ Checkbox.displayName = "Checkbox";
294
+
295
+ // src/components/switch/switch.tsx
296
+ var import_react6 = __toESM(require("react"));
297
+ var import_jsx_runtime6 = require("react/jsx-runtime");
298
+ var Switch = import_react6.default.forwardRef(
299
+ ({
300
+ size = "md",
301
+ label,
302
+ onIcon,
303
+ offIcon,
304
+ error,
305
+ helperText,
306
+ disabled = false,
307
+ className,
308
+ checked,
309
+ ...props
310
+ }, ref) => {
311
+ const switchClasses = [
312
+ "switch",
313
+ `switch--${size}`,
314
+ checked && "switch--checked",
315
+ disabled && "switch--disabled",
316
+ error && "switch--error",
317
+ className
318
+ ].filter(Boolean).join(" ");
319
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "switch__wrapper", children: [
320
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "switch__label", children: [
321
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
322
+ "input",
323
+ {
324
+ type: "checkbox",
325
+ ref,
326
+ checked,
327
+ disabled,
328
+ className: "switch__input",
329
+ ...props
330
+ }
331
+ ),
332
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: switchClasses, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "switch__track", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "switch__thumb", children: [
333
+ onIcon && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: onIcon, size: 16, className: "switch__icon switch__icon--on" }),
334
+ offIcon && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: offIcon, size: 16, className: "switch__icon switch__icon--off" })
335
+ ] }) }) }),
336
+ label && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "switch__text", children: label })
337
+ ] }),
338
+ (error || helperText) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "switch__message", children: [
339
+ error && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "switch__error-text", children: error }),
340
+ helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "switch__helper-text", children: helperText })
341
+ ] })
342
+ ] });
343
+ }
344
+ );
345
+ Switch.displayName = "Switch";
346
+
347
+ // src/components/layout/Layout.tsx
348
+ var React6 = __toESM(require("react"));
349
+
350
+ // src/components/drag-handle/DragHandle.tsx
351
+ var import_react7 = __toESM(require("react"));
352
+ var import_jsx_runtime7 = require("react/jsx-runtime");
353
+ var DragHandle = ({
354
+ onResize,
355
+ onResizeEnd,
356
+ orientation = "vertical",
357
+ className = ""
358
+ }) => {
359
+ const [isDragging, setIsDragging] = (0, import_react7.useState)(false);
360
+ const dragHandleRef = (0, import_react7.useRef)(null);
361
+ const startPosRef = (0, import_react7.useRef)(0);
362
+ const handleMouseDown = (0, import_react7.useCallback)((e) => {
363
+ setIsDragging(true);
364
+ startPosRef.current = orientation === "vertical" ? e.clientX : e.clientY;
365
+ e.preventDefault();
366
+ }, [orientation]);
367
+ const handleMouseMove = (0, import_react7.useCallback)((e) => {
368
+ if (!isDragging) return;
369
+ const currentPos = orientation === "vertical" ? e.clientX : e.clientY;
370
+ const delta = currentPos - startPosRef.current;
371
+ onResize(delta);
372
+ startPosRef.current = currentPos;
373
+ }, [isDragging, onResize, orientation]);
374
+ const handleMouseUp = (0, import_react7.useCallback)(() => {
375
+ setIsDragging(false);
376
+ onResizeEnd?.();
377
+ }, [onResizeEnd]);
378
+ import_react7.default.useEffect(() => {
379
+ if (isDragging) {
380
+ document.addEventListener("mousemove", handleMouseMove);
381
+ document.addEventListener("mouseup", handleMouseUp);
382
+ document.body.style.cursor = orientation === "vertical" ? "col-resize" : "row-resize";
383
+ document.body.style.userSelect = "none";
384
+ } else {
385
+ document.removeEventListener("mousemove", handleMouseMove);
386
+ document.removeEventListener("mouseup", handleMouseUp);
387
+ document.body.style.cursor = "";
388
+ document.body.style.userSelect = "";
389
+ }
390
+ return () => {
391
+ document.removeEventListener("mousemove", handleMouseMove);
392
+ document.removeEventListener("mouseup", handleMouseUp);
393
+ document.body.style.cursor = "";
394
+ document.body.style.userSelect = "";
395
+ };
396
+ }, [isDragging, handleMouseMove, handleMouseUp, orientation]);
397
+ const classes = [
398
+ "drag-handle",
399
+ `drag-handle--${orientation}`,
400
+ isDragging && "drag-handle--dragging",
401
+ className
402
+ ].filter(Boolean).join(" ");
403
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
404
+ "div",
405
+ {
406
+ ref: dragHandleRef,
407
+ className: classes,
408
+ onMouseDown: handleMouseDown,
409
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "drag-handle__indicator" })
410
+ }
411
+ );
412
+ };
413
+
414
+ // src/utils/user-preferences.ts
415
+ var DEFAULT_CONFIG = {
416
+ backend: "localStorage",
417
+ prefix: "hellboy-ds",
418
+ dbName: "hellboy-ds-prefs",
419
+ storeName: "preferences"
420
+ };
421
+ var config = { ...DEFAULT_CONFIG };
422
+ var configurePreferences = (userConfig) => {
423
+ config = { ...config, ...userConfig };
424
+ };
425
+ var getStorageKey = (key) => {
426
+ return `${config.prefix}:${key}`;
427
+ };
428
+ var isLocalStorageAvailable = () => {
429
+ try {
430
+ const test = "__storage_test__";
431
+ localStorage.setItem(test, test);
432
+ localStorage.removeItem(test);
433
+ return true;
434
+ } catch {
435
+ return false;
436
+ }
437
+ };
438
+ var IndexedDBStore = class {
439
+ constructor() {
440
+ __publicField(this, "db", null);
441
+ }
442
+ async init() {
443
+ if (typeof window === "undefined" || !window.indexedDB) {
444
+ throw new Error("IndexedDB not available");
445
+ }
446
+ return new Promise((resolve, reject) => {
447
+ const request = indexedDB.open(config.dbName, 1);
448
+ request.onerror = () => reject(request.error);
449
+ request.onsuccess = () => {
450
+ this.db = request.result;
451
+ resolve();
452
+ };
453
+ request.onupgradeneeded = (event) => {
454
+ const db = event.target.result;
455
+ if (!db.objectStoreNames.contains(config.storeName)) {
456
+ db.createObjectStore(config.storeName, { keyPath: "key" });
457
+ }
458
+ };
459
+ });
460
+ }
461
+ async get(key) {
462
+ if (!this.db) await this.init();
463
+ return new Promise((resolve, reject) => {
464
+ const transaction = this.db.transaction([config.storeName], "readonly");
465
+ const store = transaction.objectStore(config.storeName);
466
+ const request = store.get(key);
467
+ request.onsuccess = () => resolve(request.result?.value);
468
+ request.onerror = () => reject(request.error);
469
+ });
470
+ }
471
+ async set(key, value) {
472
+ if (!this.db) await this.init();
473
+ return new Promise((resolve, reject) => {
474
+ const transaction = this.db.transaction([config.storeName], "readwrite");
475
+ const store = transaction.objectStore(config.storeName);
476
+ const request = store.put({ key, value });
477
+ request.onsuccess = () => resolve();
478
+ request.onerror = () => reject(request.error);
479
+ });
480
+ }
481
+ async remove(key) {
482
+ if (!this.db) await this.init();
483
+ return new Promise((resolve, reject) => {
484
+ const transaction = this.db.transaction([config.storeName], "readwrite");
485
+ const store = transaction.objectStore(config.storeName);
486
+ const request = store.delete(key);
487
+ request.onsuccess = () => resolve();
488
+ request.onerror = () => reject(request.error);
489
+ });
490
+ }
491
+ async clear() {
492
+ if (!this.db) await this.init();
493
+ return new Promise((resolve, reject) => {
494
+ const transaction = this.db.transaction([config.storeName], "readwrite");
495
+ const store = transaction.objectStore(config.storeName);
496
+ const request = store.clear();
497
+ request.onsuccess = () => resolve();
498
+ request.onerror = () => reject(request.error);
499
+ });
500
+ }
501
+ };
502
+ var indexedDBStore = new IndexedDBStore();
503
+ var getPreference = (key, defaultValue) => {
504
+ try {
505
+ if (config.backend === "localStorage" && isLocalStorageAvailable()) {
506
+ const stored = localStorage.getItem(getStorageKey(key));
507
+ if (stored !== null) {
508
+ return JSON.parse(stored);
509
+ }
510
+ }
511
+ return defaultValue;
512
+ } catch (error) {
513
+ console.warn(`Failed to get preference "${key}":`, error);
514
+ return defaultValue;
515
+ }
516
+ };
517
+ var getPreferenceAsync = async (key, defaultValue) => {
518
+ try {
519
+ if (config.backend === "indexedDB") {
520
+ const value = await indexedDBStore.get(getStorageKey(key));
521
+ return value !== void 0 ? value : defaultValue;
522
+ }
523
+ return getPreference(key, defaultValue);
524
+ } catch (error) {
525
+ console.warn(`Failed to get preference "${key}":`, error);
526
+ return defaultValue;
527
+ }
528
+ };
529
+ var setPreference = (key, value) => {
530
+ try {
531
+ if (config.backend === "localStorage" && isLocalStorageAvailable()) {
532
+ localStorage.setItem(getStorageKey(key), JSON.stringify(value));
533
+ }
534
+ } catch (error) {
535
+ console.warn(`Failed to set preference "${key}":`, error);
536
+ }
537
+ };
538
+ var setPreferenceAsync = async (key, value) => {
539
+ try {
540
+ if (config.backend === "indexedDB") {
541
+ await indexedDBStore.set(getStorageKey(key), value);
542
+ } else {
543
+ setPreference(key, value);
544
+ }
545
+ } catch (error) {
546
+ console.warn(`Failed to set preference "${key}":`, error);
547
+ }
548
+ };
549
+ var removePreference = (key) => {
550
+ try {
551
+ if (config.backend === "localStorage" && isLocalStorageAvailable()) {
552
+ localStorage.removeItem(getStorageKey(key));
553
+ }
554
+ } catch (error) {
555
+ console.warn(`Failed to remove preference "${key}":`, error);
556
+ }
557
+ };
558
+ var removePreferenceAsync = async (key) => {
559
+ try {
560
+ if (config.backend === "indexedDB") {
561
+ await indexedDBStore.remove(getStorageKey(key));
562
+ } else {
563
+ removePreference(key);
564
+ }
565
+ } catch (error) {
566
+ console.warn(`Failed to remove preference "${key}":`, error);
567
+ }
568
+ };
569
+ var clearPreferences = () => {
570
+ try {
571
+ if (config.backend === "localStorage" && isLocalStorageAvailable()) {
572
+ const prefix = `${config.prefix}:`;
573
+ const keysToRemove = [];
574
+ for (let i = 0; i < localStorage.length; i++) {
575
+ const key = localStorage.key(i);
576
+ if (key?.startsWith(prefix)) {
577
+ keysToRemove.push(key);
578
+ }
579
+ }
580
+ keysToRemove.forEach((key) => localStorage.removeItem(key));
581
+ }
582
+ } catch (error) {
583
+ console.warn("Failed to clear preferences:", error);
584
+ }
585
+ };
586
+ var clearPreferencesAsync = async () => {
587
+ try {
588
+ if (config.backend === "indexedDB") {
589
+ await indexedDBStore.clear();
590
+ } else {
591
+ clearPreferences();
592
+ }
593
+ } catch (error) {
594
+ console.warn("Failed to clear preferences:", error);
595
+ }
596
+ };
597
+ var getAllPreferences = () => {
598
+ const preferences = {};
599
+ try {
600
+ if (config.backend === "localStorage" && isLocalStorageAvailable()) {
601
+ const prefix = `${config.prefix}:`;
602
+ for (let i = 0; i < localStorage.length; i++) {
603
+ const key = localStorage.key(i);
604
+ if (key?.startsWith(prefix)) {
605
+ const prefKey = key.substring(prefix.length);
606
+ const value = localStorage.getItem(key);
607
+ if (value !== null) {
608
+ try {
609
+ preferences[prefKey] = JSON.parse(value);
610
+ } catch {
611
+ preferences[prefKey] = value;
612
+ }
613
+ }
614
+ }
615
+ }
616
+ }
617
+ } catch (error) {
618
+ console.warn("Failed to get all preferences:", error);
619
+ }
620
+ return preferences;
621
+ };
622
+ var exportPreferences = () => {
623
+ const prefs = getAllPreferences();
624
+ return JSON.stringify(prefs, null, 2);
625
+ };
626
+ var importPreferences = (json, merge = false) => {
627
+ try {
628
+ const prefs = JSON.parse(json);
629
+ if (!merge) {
630
+ clearPreferences();
631
+ }
632
+ Object.entries(prefs).forEach(([key, value]) => {
633
+ setPreference(key, value);
634
+ });
635
+ } catch (error) {
636
+ console.warn("Failed to import preferences:", error);
637
+ }
638
+ };
639
+ var createPreferenceNamespace = (namespace) => {
640
+ const getKey = (key) => `${namespace}.${key}`;
641
+ return {
642
+ get: (key, defaultValue) => getPreference(getKey(key), defaultValue),
643
+ set: (key, value) => setPreference(getKey(key), value),
644
+ remove: (key) => removePreference(getKey(key)),
645
+ clear: () => {
646
+ const prefs = getAllPreferences();
647
+ const prefix = `${namespace}.`;
648
+ Object.keys(prefs).filter((key) => key.startsWith(prefix)).forEach((key) => removePreference(key));
649
+ }
650
+ };
651
+ };
652
+
653
+ // src/components/layout/Layout.tsx
654
+ var import_jsx_runtime8 = require("react/jsx-runtime");
655
+ var Layout = ({
656
+ variant = "stacked",
657
+ header,
658
+ footer,
659
+ sidebarLeft,
660
+ sidebarRight,
661
+ bottomBar,
662
+ resizable = false,
663
+ children,
664
+ className = "",
665
+ ...props
666
+ }) => {
667
+ const classes = ["layout", `layout--${variant}`, className].filter(Boolean).join(" ");
668
+ const NAVBAR_COLLAPSED_WIDTH = 72;
669
+ const NAVBAR_EXPAND_THRESHOLD = 210;
670
+ const NAVBAR_MIN_PERSIST_WIDTH = 211;
671
+ const NAVBAR_MAX_WIDTH = 600;
672
+ const hasSidebarLeft = sidebarLeft != null;
673
+ const hasSidebarRight = sidebarRight != null;
674
+ const sidebarLeftIsNavbar = hasSidebarLeft && React6.isValidElement(sidebarLeft) && Boolean(sidebarLeft.props?.isNavbar);
675
+ const columnCount = [hasSidebarLeft, true, hasSidebarRight].filter(Boolean).length;
676
+ const shouldShowResizers = resizable && columnCount >= 2;
677
+ const [leftSidebarWidth, setLeftSidebarWidth] = React6.useState(() => {
678
+ const v = getPreference("layout.leftSidebarWidth", 280);
679
+ return typeof v === "number" ? v : 280;
680
+ });
681
+ const preferredLeftSidebarWidth = React6.useMemo(() => {
682
+ const v = getPreference("layout.leftSidebarPreferredWidth", leftSidebarWidth);
683
+ if (typeof v === "number" && v >= NAVBAR_MIN_PERSIST_WIDTH) {
684
+ return v;
685
+ }
686
+ return Math.max(NAVBAR_MIN_PERSIST_WIDTH, leftSidebarWidth);
687
+ }, [leftSidebarWidth]);
688
+ const [rightSidebarWidth, setRightSidebarWidth] = React6.useState(() => {
689
+ const v = getPreference("layout.rightSidebarWidth", 300);
690
+ return typeof v === "number" ? v : 300;
691
+ });
692
+ const clampLeftWidth = React6.useCallback((width) => {
693
+ console.log("clampLeftWidth called with:", width);
694
+ if (width <= NAVBAR_COLLAPSED_WIDTH) {
695
+ console.log("Returning 72 (collapsed)");
696
+ return NAVBAR_COLLAPSED_WIDTH;
697
+ }
698
+ const result = Math.max(NAVBAR_COLLAPSED_WIDTH, Math.min(NAVBAR_MAX_WIDTH, Math.round(width)));
699
+ console.log("Returning clamped result:", result);
700
+ return result;
701
+ }, []);
702
+ const updateLeftSidebarWidth = React6.useCallback((width) => {
703
+ console.log("updateLeftSidebarWidth called with:", width);
704
+ const newWidth = clampLeftWidth(width);
705
+ console.log("clampLeftWidth result:", newWidth);
706
+ setLeftSidebarWidth(newWidth);
707
+ if (newWidth >= NAVBAR_MIN_PERSIST_WIDTH) {
708
+ setPreference("layout.leftSidebarWidth", newWidth);
709
+ }
710
+ }, [clampLeftWidth]);
711
+ const handleLeftResize = React6.useCallback((delta) => {
712
+ setLeftSidebarWidth((prev = 300) => {
713
+ const newWidthRaw = prev + delta;
714
+ const newWidth = clampLeftWidth(newWidthRaw);
715
+ if (newWidth >= NAVBAR_MIN_PERSIST_WIDTH) {
716
+ setPreference("layout.leftSidebarWidth", newWidth);
717
+ }
718
+ if (sidebarLeftIsNavbar && Math.abs(delta) > 5 && newWidth < NAVBAR_EXPAND_THRESHOLD) {
719
+ setPreference("layout.leftSidebarWidth", NAVBAR_COLLAPSED_WIDTH);
720
+ return NAVBAR_COLLAPSED_WIDTH;
721
+ }
722
+ if (newWidth >= NAVBAR_MIN_PERSIST_WIDTH) {
723
+ setPreference("layout.leftSidebarPreferredWidth", newWidth);
724
+ }
725
+ return newWidth;
726
+ });
727
+ }, [clampLeftWidth, sidebarLeftIsNavbar]);
728
+ const handleLeftResizeEnd = React6.useCallback(() => {
729
+ setLeftSidebarWidth((currentWidth) => {
730
+ if (currentWidth < NAVBAR_EXPAND_THRESHOLD) {
731
+ const collapsed = NAVBAR_COLLAPSED_WIDTH;
732
+ setPreference("layout.leftSidebarWidth", collapsed);
733
+ return collapsed;
734
+ }
735
+ return currentWidth;
736
+ });
737
+ }, []);
738
+ const handleRightResize = React6.useCallback((delta) => {
739
+ setRightSidebarWidth((prev = 300) => {
740
+ const newWidth = Math.max(200, Math.min(600, prev - delta));
741
+ setPreference("layout.rightSidebarWidth", newWidth);
742
+ return newWidth;
743
+ });
744
+ }, []);
745
+ if (variant === "single") {
746
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: classes, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "layout__container", children: [
747
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("main", { className: "layout__main", children: [
748
+ header && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("header", { className: "layout__header", children: header }),
749
+ children,
750
+ footer && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("footer", { className: "layout__footer", children: footer })
751
+ ] }),
752
+ bottomBar && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "layout__bottom-bar", children: bottomBar })
753
+ ] }) });
754
+ }
755
+ if (variant === "stacked") {
756
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: classes, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "layout__container", children: [
757
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("main", { className: "layout__main", children: [
758
+ header && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("header", { className: "layout__header", children: header }),
759
+ children,
760
+ footer && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("footer", { className: "layout__footer", children: footer })
761
+ ] }),
762
+ bottomBar && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "layout__bottom-bar", children: bottomBar })
763
+ ] }) });
764
+ }
765
+ if (variant === "sidebar-main-sidebar") {
766
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: classes, ...props, children: [
767
+ hasSidebarLeft && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
768
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
769
+ "aside",
770
+ {
771
+ className: "layout__sidebar layout__sidebar--left",
772
+ style: { width: leftSidebarWidth },
773
+ children: React6.isValidElement(sidebarLeft) ? React6.cloneElement(sidebarLeft, {
774
+ sidebarWidth: leftSidebarWidth,
775
+ setSidebarWidth: updateLeftSidebarWidth,
776
+ preferredSidebarWidth: preferredLeftSidebarWidth,
777
+ setPreferredSidebarWidth: (w) => {
778
+ const newW = clampLeftWidth(w);
779
+ if (newW >= NAVBAR_MIN_PERSIST_WIDTH) {
780
+ setPreference("layout.leftSidebarPreferredWidth", newW);
781
+ }
782
+ if (leftSidebarWidth > NAVBAR_COLLAPSED_WIDTH) {
783
+ setLeftSidebarWidth(newW);
784
+ setPreference("layout.leftSidebarWidth", newW);
785
+ }
786
+ }
787
+ }) : sidebarLeft
788
+ }
789
+ ),
790
+ shouldShowResizers && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
791
+ DragHandle,
792
+ {
793
+ orientation: "vertical",
794
+ onResize: handleLeftResize,
795
+ onResizeEnd: handleLeftResizeEnd
796
+ }
797
+ )
798
+ ] }),
799
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "layout__container", children: [
800
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("main", { className: "layout__main", children: [
801
+ header && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("header", { className: "layout__header", children: header }),
802
+ children,
803
+ footer && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("footer", { className: "layout__footer", children: footer })
804
+ ] }),
805
+ bottomBar && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "layout__bottom-bar", children: bottomBar })
806
+ ] }),
807
+ hasSidebarRight && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
808
+ shouldShowResizers && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
809
+ DragHandle,
810
+ {
811
+ orientation: "vertical",
812
+ onResize: handleRightResize
813
+ }
814
+ ),
815
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
816
+ "aside",
817
+ {
818
+ className: "layout__sidebar layout__sidebar--right",
819
+ style: { width: rightSidebarWidth },
820
+ children: React6.isValidElement(sidebarRight) ? React6.cloneElement(sidebarRight, {
821
+ sidebarWidth: rightSidebarWidth,
822
+ setSidebarWidth: (w) => {
823
+ const newW = Math.max(200, Math.min(600, w));
824
+ setRightSidebarWidth(newW);
825
+ setPreference("layout.rightSidebarWidth", newW);
826
+ }
827
+ }) : sidebarRight
828
+ }
829
+ )
830
+ ] })
831
+ ] });
832
+ }
833
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: classes, ...props, children });
834
+ };
835
+
836
+ // src/components/page/page.tsx
837
+ var import_jsx_runtime9 = require("react/jsx-runtime");
838
+ var Page = ({ width = "medium", children, className }) => {
839
+ const pageClasses = [
840
+ "page",
841
+ `page--${width}`,
842
+ className
843
+ ].filter(Boolean).join(" ");
844
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("main", { className: pageClasses, children });
845
+ };
846
+
847
+ // src/components/header/header.tsx
848
+ var import_react8 = require("react");
849
+ var import_jsx_runtime10 = require("react/jsx-runtime");
850
+ var Header = ({ title, subtitle, children, className }) => {
851
+ const headerId = (0, import_react8.useMemo)(() => {
852
+ if (typeof title === "string" && title.trim()) {
853
+ return title.toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").trim();
854
+ }
855
+ return void 0;
856
+ }, [title]);
857
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("header", { className: `header ${className || ""}`, id: headerId, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "header__container", children: children ? children : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
858
+ title && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h1", { className: "header__title", children: title }),
859
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "header__subtitle", children: subtitle })
860
+ ] }) }) });
861
+ };
862
+
863
+ // src/components/section/section.tsx
864
+ var import_react9 = require("react");
865
+ var import_jsx_runtime11 = require("react/jsx-runtime");
866
+ var Section = ({ title, children, size = "md", className }) => {
867
+ const sectionClasses = [
868
+ "section",
869
+ size !== "md" && `section--${size}`,
870
+ className
871
+ ].filter(Boolean).join(" ");
872
+ const sectionId = (0, import_react9.useMemo)(() => {
873
+ if (typeof title === "string" && title.trim()) {
874
+ return title.toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").trim();
875
+ }
876
+ return void 0;
877
+ }, [title]);
878
+ const titleText = typeof title === "string" ? title : void 0;
879
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
880
+ "section",
881
+ {
882
+ className: sectionClasses,
883
+ id: sectionId,
884
+ "data-section-title": titleText,
885
+ children: [
886
+ title && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h2", { className: "section__title", children: title }),
887
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "section__content", children })
888
+ ]
889
+ }
890
+ );
891
+ };
892
+
893
+ // src/components/code-block/code-block.tsx
894
+ var import_jsx_runtime12 = require("react/jsx-runtime");
895
+ var CodeBlock = ({ children, variant = "block", className }) => {
896
+ const classes = [
897
+ "code-block",
898
+ variant === "inline" && "code-block--inline",
899
+ className
900
+ ].filter(Boolean).join(" ");
901
+ if (variant === "inline") {
902
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("code", { className: classes, children });
903
+ }
904
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("pre", { className: classes, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("code", { children }) });
905
+ };
906
+
907
+ // src/components/navbar/Navbar.tsx
908
+ var import_jsx_runtime13 = require("react/jsx-runtime");
909
+ var Navbar = ({
910
+ children,
911
+ className = ""
912
+ }) => {
913
+ const classes = ["navbar", className].filter(Boolean).join(" ");
914
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("nav", { className: classes, role: "navigation", "aria-label": "Main navigation", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "navbar__content", children }) });
915
+ };
916
+
917
+ // src/components/tooltip/tooltip.tsx
918
+ var React9 = __toESM(require("react"));
919
+ var ReactDOM = __toESM(require("react-dom"));
920
+ var import_jsx_runtime14 = require("react/jsx-runtime");
921
+ var Tooltip = ({
922
+ content,
923
+ children,
924
+ placement = "top",
925
+ delay = 0,
926
+ disabled = false
927
+ }) => {
928
+ const [isVisible, setIsVisible] = React9.useState(false);
929
+ const [tooltipStyle, setTooltipStyle] = React9.useState({});
930
+ const [resolvedPlacement, setResolvedPlacement] = React9.useState(placement);
931
+ const triggerRef = React9.useRef(null);
932
+ const tooltipRef = React9.useRef(null);
933
+ const timeoutRef = React9.useRef();
934
+ React9.useEffect(() => {
935
+ if (!isVisible || !triggerRef.current || !tooltipRef.current) {
936
+ return;
937
+ }
938
+ const updatePosition = () => {
939
+ if (!triggerRef.current || !tooltipRef.current) {
940
+ console.log("Tooltip refs not ready:", { trigger: !!triggerRef.current, tooltip: !!tooltipRef.current });
941
+ return;
942
+ }
943
+ const triggerRect = triggerRef.current.getBoundingClientRect();
944
+ const tooltipRect = tooltipRef.current.getBoundingClientRect();
945
+ if (tooltipRect.width === 0 || tooltipRect.height === 0) {
946
+ setTimeout(updatePosition, 10);
947
+ return;
948
+ }
949
+ const gap = 8;
950
+ const viewportWidth = window.innerWidth;
951
+ const viewportHeight = window.innerHeight;
952
+ const spaceTop = triggerRect.top;
953
+ const spaceBottom = viewportHeight - triggerRect.bottom;
954
+ const spaceLeft = triggerRect.left;
955
+ const spaceRight = viewportWidth - triggerRect.right;
956
+ let finalPlacement = placement;
957
+ if (placement === "right" && spaceRight < tooltipRect.width + gap) {
958
+ finalPlacement = spaceLeft >= tooltipRect.width + gap ? "left" : "bottom";
959
+ } else if (placement === "left" && spaceLeft < tooltipRect.width + gap) {
960
+ finalPlacement = spaceRight >= tooltipRect.width + gap ? "right" : "bottom";
961
+ } else if (placement === "bottom" && spaceBottom < tooltipRect.height + gap) {
962
+ finalPlacement = spaceTop >= tooltipRect.height + gap ? "top" : "bottom";
963
+ } else if (placement === "top" && spaceTop < tooltipRect.height + gap) {
964
+ finalPlacement = spaceBottom >= tooltipRect.height + gap ? "bottom" : "top";
965
+ }
966
+ setResolvedPlacement(finalPlacement);
967
+ const newStyle = {
968
+ position: "fixed",
969
+ zIndex: 1e4,
970
+ opacity: 1,
971
+ visibility: "visible",
972
+ pointerEvents: "auto"
973
+ };
974
+ switch (finalPlacement) {
975
+ case "right":
976
+ newStyle.top = triggerRect.top + (triggerRect.height - tooltipRect.height) / 2;
977
+ newStyle.left = triggerRect.right + gap;
978
+ break;
979
+ case "left":
980
+ newStyle.top = triggerRect.top + (triggerRect.height - tooltipRect.height) / 2;
981
+ newStyle.left = triggerRect.left - tooltipRect.width - gap;
982
+ break;
983
+ case "top":
984
+ newStyle.top = triggerRect.top - tooltipRect.height - gap;
985
+ newStyle.left = triggerRect.left + (triggerRect.width - tooltipRect.width) / 2;
986
+ break;
987
+ case "bottom":
988
+ default:
989
+ newStyle.top = triggerRect.bottom + gap;
990
+ newStyle.left = triggerRect.left + (triggerRect.width - tooltipRect.width) / 2;
991
+ }
992
+ if (newStyle.left < 0) {
993
+ newStyle.left = 0;
994
+ } else if (newStyle.left + tooltipRect.width > viewportWidth) {
995
+ newStyle.left = viewportWidth - tooltipRect.width;
996
+ }
997
+ if (newStyle.top < 0) {
998
+ newStyle.top = 0;
999
+ } else if (newStyle.top + tooltipRect.height > viewportHeight) {
1000
+ newStyle.top = viewportHeight - tooltipRect.height;
1001
+ }
1002
+ setTooltipStyle(newStyle);
1003
+ console.log("Calculated position:", newStyle);
1004
+ };
1005
+ console.log("Tooltip isVisible:", isVisible, "tooltipStyle:", tooltipStyle);
1006
+ requestAnimationFrame(updatePosition);
1007
+ window.addEventListener("resize", updatePosition);
1008
+ window.addEventListener("scroll", updatePosition, true);
1009
+ return () => {
1010
+ window.removeEventListener("resize", updatePosition);
1011
+ window.removeEventListener("scroll", updatePosition, true);
1012
+ };
1013
+ }, [isVisible, placement]);
1014
+ const handleMouseEnter = () => {
1015
+ if (disabled) return;
1016
+ console.log("Tooltip mouse enter");
1017
+ if (timeoutRef.current) {
1018
+ clearTimeout(timeoutRef.current);
1019
+ }
1020
+ timeoutRef.current = setTimeout(() => {
1021
+ console.log("Tooltip setting visible");
1022
+ setIsVisible(true);
1023
+ }, delay);
1024
+ };
1025
+ const handleMouseLeave = () => {
1026
+ console.log("Tooltip mouse leave");
1027
+ if (timeoutRef.current) {
1028
+ clearTimeout(timeoutRef.current);
1029
+ }
1030
+ timeoutRef.current = setTimeout(() => {
1031
+ console.log("Tooltip setting invisible");
1032
+ setIsVisible(false);
1033
+ }, 150);
1034
+ };
1035
+ const handleClick = () => {
1036
+ if (timeoutRef.current) {
1037
+ clearTimeout(timeoutRef.current);
1038
+ }
1039
+ setIsVisible(false);
1040
+ };
1041
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
1042
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1043
+ "div",
1044
+ {
1045
+ ref: triggerRef,
1046
+ onMouseEnter: handleMouseEnter,
1047
+ onMouseLeave: handleMouseLeave,
1048
+ onClick: handleClick,
1049
+ style: { display: "inline-block" },
1050
+ children
1051
+ }
1052
+ ),
1053
+ isVisible && !disabled && ReactDOM.createPortal(
1054
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1055
+ "div",
1056
+ {
1057
+ ref: tooltipRef,
1058
+ className: `tooltip tooltip--${resolvedPlacement}`,
1059
+ style: {
1060
+ ...tooltipStyle,
1061
+ // Start with opacity 0 and visibility hidden to prevent initial flash
1062
+ opacity: tooltipStyle.top !== void 0 ? 1 : 0,
1063
+ visibility: tooltipStyle.top !== void 0 ? "visible" : "hidden"
1064
+ },
1065
+ onMouseEnter: () => {
1066
+ console.log("Tooltip mouse enter on tooltip");
1067
+ if (timeoutRef.current) {
1068
+ clearTimeout(timeoutRef.current);
1069
+ }
1070
+ },
1071
+ onMouseLeave: handleMouseLeave,
1072
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "tooltip__content", children: content })
1073
+ }
1074
+ ),
1075
+ document.body
1076
+ )
1077
+ ] });
1078
+ };
1079
+
1080
+ // src/components/navbar/MenuItem.tsx
1081
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1082
+ var MenuItem = ({
1083
+ icon,
1084
+ active = false,
1085
+ children,
1086
+ className = "",
1087
+ as: Component = "button",
1088
+ isCollapsed = false,
1089
+ showTooltipWhenCollapsed = false,
1090
+ ...props
1091
+ }) => {
1092
+ const { hasOpenPopover } = useNavbarTooltip();
1093
+ const classes = [
1094
+ "navbar__menu-item",
1095
+ active && "navbar__menu-item--active",
1096
+ className
1097
+ ].filter(Boolean).join(" ");
1098
+ const menuItem = isCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1099
+ Button,
1100
+ {
1101
+ variant: active ? "primary" : "ghost",
1102
+ iconOnly: true,
1103
+ startIcon: icon,
1104
+ ...props
1105
+ }
1106
+ ) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1107
+ Component,
1108
+ {
1109
+ className: classes,
1110
+ type: Component === "button" ? "button" : void 0,
1111
+ ...props,
1112
+ children: [
1113
+ icon && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "navbar__menu-item-icon", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, { name: icon, size: 16 }) }),
1114
+ !isCollapsed && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "navbar__menu-item-label", children })
1115
+ ]
1116
+ }
1117
+ );
1118
+ if (showTooltipWhenCollapsed && isCollapsed) {
1119
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Tooltip, { content: typeof children === "string" ? children : "", placement: "right", disabled: hasOpenPopover, children: menuItem });
1120
+ }
1121
+ return menuItem;
1122
+ };
1123
+
1124
+ // src/components/navbar/MenuGroup.tsx
1125
+ var React11 = __toESM(require("react"));
1126
+
1127
+ // src/components/popover/popover.tsx
1128
+ var React10 = __toESM(require("react"));
1129
+ var ReactDOM2 = __toESM(require("react-dom"));
1130
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1131
+ var Popover = ({
1132
+ trigger,
1133
+ children,
1134
+ isOpen = false,
1135
+ onToggle,
1136
+ placement = "bottom"
1137
+ }) => {
1138
+ const [internalOpen, setInternalOpen] = React10.useState(false);
1139
+ const triggerRef = React10.useRef(null);
1140
+ const popoverRef = React10.useRef(null);
1141
+ const [popoverStyle, setPopoverStyle] = React10.useState({});
1142
+ const [resolvedPlacement, setResolvedPlacement] = React10.useState(placement);
1143
+ const open = isOpen !== void 0 ? isOpen : internalOpen;
1144
+ const toggle = onToggle || (() => setInternalOpen(!internalOpen));
1145
+ React10.useEffect(() => {
1146
+ const handleClickOutside = (event) => {
1147
+ if (triggerRef.current && !triggerRef.current.contains(event.target) && popoverRef.current && !popoverRef.current.contains(event.target)) {
1148
+ if (onToggle) {
1149
+ onToggle();
1150
+ } else {
1151
+ setInternalOpen(false);
1152
+ }
1153
+ }
1154
+ };
1155
+ if (open) {
1156
+ document.addEventListener("mousedown", handleClickOutside);
1157
+ }
1158
+ return () => {
1159
+ document.removeEventListener("mousedown", handleClickOutside);
1160
+ };
1161
+ }, [open, onToggle]);
1162
+ React10.useEffect(() => {
1163
+ if (!open || !triggerRef.current || !popoverRef.current) {
1164
+ return;
1165
+ }
1166
+ const updatePosition = () => {
1167
+ if (!triggerRef.current || !popoverRef.current) {
1168
+ return;
1169
+ }
1170
+ const triggerRect = triggerRef.current.getBoundingClientRect();
1171
+ const popoverRect = popoverRef.current.getBoundingClientRect();
1172
+ const gap = 8;
1173
+ const viewportWidth = window.innerWidth;
1174
+ const viewportHeight = window.innerHeight;
1175
+ const spaceTop = triggerRect.top;
1176
+ const spaceBottom = viewportHeight - triggerRect.bottom;
1177
+ const spaceLeft = triggerRect.left;
1178
+ const spaceRight = viewportWidth - triggerRect.right;
1179
+ let finalPlacement = placement;
1180
+ if (placement === "right" && spaceRight < popoverRect.width + gap) {
1181
+ finalPlacement = spaceLeft >= popoverRect.width + gap ? "left" : "bottom";
1182
+ } else if (placement === "left" && spaceLeft < popoverRect.width + gap) {
1183
+ finalPlacement = spaceRight >= popoverRect.width + gap ? "right" : "bottom";
1184
+ } else if (placement === "bottom" && spaceBottom < popoverRect.height + gap) {
1185
+ finalPlacement = spaceTop >= popoverRect.height + gap ? "top" : "bottom";
1186
+ } else if (placement === "top" && spaceTop < popoverRect.height + gap) {
1187
+ finalPlacement = spaceBottom >= popoverRect.height + gap ? "bottom" : "top";
1188
+ }
1189
+ setResolvedPlacement(finalPlacement);
1190
+ const newStyle = {
1191
+ position: "fixed",
1192
+ zIndex: 9999,
1193
+ opacity: 1,
1194
+ visibility: "visible",
1195
+ pointerEvents: "auto"
1196
+ };
1197
+ switch (finalPlacement) {
1198
+ case "right":
1199
+ newStyle.top = triggerRect.top;
1200
+ newStyle.left = triggerRect.right + gap;
1201
+ break;
1202
+ case "left":
1203
+ newStyle.top = triggerRect.top;
1204
+ newStyle.left = triggerRect.left - popoverRect.width - gap;
1205
+ break;
1206
+ case "top":
1207
+ newStyle.top = triggerRect.top - popoverRect.height - gap;
1208
+ newStyle.left = triggerRect.left;
1209
+ break;
1210
+ case "bottom":
1211
+ default:
1212
+ newStyle.top = triggerRect.bottom + gap;
1213
+ newStyle.left = triggerRect.left;
1214
+ }
1215
+ if (typeof newStyle.left === "number") {
1216
+ if (newStyle.left + popoverRect.width > viewportWidth - gap) {
1217
+ newStyle.left = viewportWidth - popoverRect.width - gap;
1218
+ }
1219
+ if (newStyle.left < gap) {
1220
+ newStyle.left = gap;
1221
+ }
1222
+ }
1223
+ if (typeof newStyle.top === "number") {
1224
+ if (newStyle.top + popoverRect.height > viewportHeight - gap) {
1225
+ newStyle.top = viewportHeight - popoverRect.height - gap;
1226
+ }
1227
+ if (newStyle.top < gap) {
1228
+ newStyle.top = gap;
1229
+ }
1230
+ }
1231
+ setPopoverStyle(newStyle);
1232
+ };
1233
+ requestAnimationFrame(updatePosition);
1234
+ window.addEventListener("resize", updatePosition);
1235
+ window.addEventListener("scroll", updatePosition, true);
1236
+ return () => {
1237
+ window.removeEventListener("resize", updatePosition);
1238
+ window.removeEventListener("scroll", updatePosition, true);
1239
+ };
1240
+ }, [open, placement]);
1241
+ const handleTriggerClick = () => {
1242
+ toggle();
1243
+ };
1244
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
1245
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1246
+ "div",
1247
+ {
1248
+ ref: triggerRef,
1249
+ onClick: handleTriggerClick,
1250
+ style: { display: "inline-block", position: "relative" },
1251
+ children: React10.isValidElement(trigger) ? React10.cloneElement(trigger, {
1252
+ onClick: (e) => {
1253
+ e.stopPropagation();
1254
+ handleTriggerClick();
1255
+ trigger.props?.onClick?.(e);
1256
+ }
1257
+ }) : trigger
1258
+ }
1259
+ ),
1260
+ open && ReactDOM2.createPortal(
1261
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1262
+ "div",
1263
+ {
1264
+ ref: popoverRef,
1265
+ className: `popover popover--${resolvedPlacement}`,
1266
+ style: {
1267
+ ...popoverStyle,
1268
+ // Start with opacity 0 and visibility hidden to prevent initial flash
1269
+ opacity: popoverStyle.top !== void 0 ? 1 : 0,
1270
+ visibility: popoverStyle.top !== void 0 ? "visible" : "hidden"
1271
+ },
1272
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "popover__content", children })
1273
+ }
1274
+ ),
1275
+ document.body
1276
+ )
1277
+ ] });
1278
+ };
1279
+
1280
+ // src/components/navbar/MenuGroup.tsx
1281
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1282
+ var MenuGroup = ({
1283
+ title,
1284
+ icon,
1285
+ children,
1286
+ defaultExpanded = false,
1287
+ autoExpand = false,
1288
+ expandable = true,
1289
+ isCollapsed = false
1290
+ }) => {
1291
+ const [expanded, setExpanded] = React11.useState(defaultExpanded);
1292
+ const [userInteracted, setUserInteracted] = React11.useState(false);
1293
+ const { openPopover, closePopover, activePopoverId } = useNavbarTooltip();
1294
+ const groupId = React11.useMemo(() => `menu-group-${title.replace(/\s+/g, "-").toLowerCase()}`, [title]);
1295
+ const popoverOpen = activePopoverId === groupId;
1296
+ const triggerRef = React11.useRef(null);
1297
+ const popoverContentRef = React11.useRef(null);
1298
+ React11.useEffect(() => {
1299
+ if (popoverOpen && popoverContentRef.current) {
1300
+ setTimeout(() => {
1301
+ const firstFocusable = popoverContentRef.current?.querySelector(
1302
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
1303
+ );
1304
+ firstFocusable?.focus();
1305
+ }, 10);
1306
+ }
1307
+ }, [popoverOpen]);
1308
+ const findNextFocusableElement = React11.useCallback((currentElement) => {
1309
+ const navbar = currentElement.closest(".navbar");
1310
+ if (!navbar) return null;
1311
+ const focusableElements = navbar.querySelectorAll(
1312
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
1313
+ );
1314
+ const rootFocusableElements = Array.from(focusableElements).filter((el) => {
1315
+ return !el.closest(".popover");
1316
+ });
1317
+ const currentIndex = rootFocusableElements.indexOf(currentElement);
1318
+ if (currentIndex >= 0 && currentIndex < rootFocusableElements.length - 1) {
1319
+ return rootFocusableElements[currentIndex + 1];
1320
+ }
1321
+ return null;
1322
+ }, []);
1323
+ const handleKeyDown = React11.useCallback((event) => {
1324
+ if (event.key === "Tab" && !event.shiftKey) {
1325
+ if (popoverContentRef.current) {
1326
+ const focusableElements = popoverContentRef.current.querySelectorAll(
1327
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
1328
+ );
1329
+ const currentElement = event.target;
1330
+ const currentIndex = Array.from(focusableElements).indexOf(currentElement);
1331
+ if (currentIndex >= 0 && currentIndex === focusableElements.length - 1) {
1332
+ event.preventDefault();
1333
+ const nextElement = findNextFocusableElement(currentElement);
1334
+ if (nextElement) {
1335
+ nextElement.focus();
1336
+ } else {
1337
+ closePopover(groupId);
1338
+ triggerRef.current?.focus();
1339
+ }
1340
+ }
1341
+ }
1342
+ } else if (event.key === "Tab" && event.shiftKey) {
1343
+ if (popoverContentRef.current) {
1344
+ const focusableElements = popoverContentRef.current.querySelectorAll(
1345
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
1346
+ );
1347
+ const currentElement = event.target;
1348
+ const currentIndex = Array.from(focusableElements).indexOf(currentElement);
1349
+ if (currentIndex === 0) {
1350
+ event.preventDefault();
1351
+ triggerRef.current?.focus();
1352
+ }
1353
+ }
1354
+ } else if (event.key === "Escape") {
1355
+ closePopover(groupId);
1356
+ setTimeout(() => {
1357
+ triggerRef.current?.focus();
1358
+ }, 10);
1359
+ }
1360
+ }, [closePopover, groupId, findNextFocusableElement]);
1361
+ const hasActiveItem = React11.useMemo(() => {
1362
+ const checkForActiveItems = (children2) => {
1363
+ return React11.Children.toArray(children2).some((child) => {
1364
+ if (React11.isValidElement(child)) {
1365
+ if (child.props && child.props.active === true) {
1366
+ return true;
1367
+ }
1368
+ if (child.props && child.props.children) {
1369
+ return checkForActiveItems(child.props.children);
1370
+ }
1371
+ }
1372
+ return false;
1373
+ });
1374
+ };
1375
+ return checkForActiveItems(children);
1376
+ }, [children]);
1377
+ React11.useEffect(() => {
1378
+ if (autoExpand && hasActiveItem && !userInteracted) {
1379
+ setExpanded(true);
1380
+ }
1381
+ }, [autoExpand, hasActiveItem, userInteracted]);
1382
+ const toggleExpanded = () => {
1383
+ setUserInteracted(true);
1384
+ setExpanded(!expanded);
1385
+ };
1386
+ const popoverContent = /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "navbar__menu-group-popover", children: [
1387
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "navbar__menu-group-popover-title", children: title }),
1388
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1389
+ "div",
1390
+ {
1391
+ className: "navbar__menu-group-popover-content",
1392
+ ref: popoverContentRef,
1393
+ onKeyDown: handleKeyDown,
1394
+ onClick: () => {
1395
+ setTimeout(() => {
1396
+ closePopover(groupId);
1397
+ }, 0);
1398
+ },
1399
+ children: React11.Children.map(children, (child) => {
1400
+ if (React11.isValidElement(child)) {
1401
+ return React11.cloneElement(child, {
1402
+ onKeyDown: (e) => {
1403
+ child.props.onKeyDown?.(e);
1404
+ handleKeyDown(e);
1405
+ }
1406
+ });
1407
+ }
1408
+ return child;
1409
+ })
1410
+ }
1411
+ )
1412
+ ] });
1413
+ const expandedHeader = !expandable ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "navbar__menu-group-header navbar__menu-group-header--static", children: [
1414
+ icon && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "navbar__menu-group-icon", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { name: icon, size: 16 }) }),
1415
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "navbar__menu-group-title", children: title })
1416
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1417
+ "button",
1418
+ {
1419
+ className: `navbar__menu-group-header ${!expanded && hasActiveItem ? "navbar__menu-group-header--active" : ""}`,
1420
+ onClick: toggleExpanded,
1421
+ "aria-expanded": expanded,
1422
+ "aria-controls": `menu-group-${title.replace(/\s+/g, "-").toLowerCase()}`,
1423
+ type: "button",
1424
+ children: [
1425
+ icon && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "navbar__menu-group-icon", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { name: icon, size: 16 }) }),
1426
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "navbar__menu-group-title", children: title }),
1427
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: `navbar__menu-group-chevron ${expanded ? "navbar__menu-group-chevron--expanded" : ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Icon, { name: "chevron-down", size: 12 }) })
1428
+ ]
1429
+ }
1430
+ );
1431
+ const collapsedHeader = /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1432
+ Popover,
1433
+ {
1434
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Tooltip, { content: title, placement: "right", disabled: popoverOpen, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1435
+ Button,
1436
+ {
1437
+ ref: triggerRef,
1438
+ variant: popoverOpen ? "secondary" : hasActiveItem ? "primary" : "ghost",
1439
+ iconOnly: true,
1440
+ startIcon: icon,
1441
+ "aria-label": title,
1442
+ "aria-haspopup": "menu",
1443
+ "aria-expanded": popoverOpen,
1444
+ onKeyDown: (event) => {
1445
+ if (event.key === "Tab" && !event.shiftKey && popoverOpen) {
1446
+ event.preventDefault();
1447
+ const firstFocusable = popoverContentRef.current?.querySelector(
1448
+ 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
1449
+ );
1450
+ firstFocusable?.focus();
1451
+ }
1452
+ },
1453
+ onClick: () => {
1454
+ if (popoverOpen) {
1455
+ closePopover(groupId);
1456
+ } else {
1457
+ openPopover(groupId);
1458
+ }
1459
+ }
1460
+ }
1461
+ ) }),
1462
+ isOpen: popoverOpen,
1463
+ onToggle: () => {
1464
+ if (popoverOpen) {
1465
+ closePopover(groupId);
1466
+ } else {
1467
+ openPopover(groupId);
1468
+ }
1469
+ },
1470
+ placement: "right",
1471
+ children: popoverContent
1472
+ }
1473
+ ) });
1474
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "navbar__menu-group", children: [
1475
+ isCollapsed ? collapsedHeader : expandedHeader,
1476
+ !isCollapsed && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1477
+ "div",
1478
+ {
1479
+ className: "navbar__menu-group-content",
1480
+ id: `menu-group-${title.replace(/\s+/g, "-").toLowerCase()}`,
1481
+ "aria-hidden": !expandable || !expanded,
1482
+ style: { display: expandable ? expanded ? "block" : "none" : "block" },
1483
+ children
1484
+ }
1485
+ )
1486
+ ] });
1487
+ };
1488
+
1489
+ // src/components/navbar/MenuCategory.tsx
1490
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1491
+ var MenuCategory = ({
1492
+ title,
1493
+ children
1494
+ }) => {
1495
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "navbar__menu-category", children: [
1496
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "navbar__menu-category-title", children: title }),
1497
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "navbar__menu-category-content", children })
1498
+ ] });
1499
+ };
1500
+
1501
+ // src/components/theme-control/theme-control.tsx
1502
+ var React12 = __toESM(require("react"));
1503
+
1504
+ // src/utils/theme.ts
1505
+ var THEME_KEY = "theme";
1506
+ var ATTR_NAME = "data-theme";
1507
+ var applyTheme = (theme) => {
1508
+ document.documentElement.setAttribute(ATTR_NAME, theme);
1509
+ };
1510
+ var getTheme = () => {
1511
+ const dataTheme = document.documentElement.getAttribute(ATTR_NAME);
1512
+ if (dataTheme === "light" || dataTheme === "dark") return dataTheme;
1513
+ try {
1514
+ const stored = getPreference(THEME_KEY);
1515
+ if (stored === "light" || stored === "dark") return stored;
1516
+ } catch (e) {
1517
+ }
1518
+ if (typeof window !== "undefined" && window.matchMedia("(prefers-color-scheme: dark)").matches) {
1519
+ return "dark";
1520
+ }
1521
+ return "light";
1522
+ };
1523
+ var getSavedTheme = () => getTheme();
1524
+ var setTheme = (theme) => {
1525
+ if (!["light", "dark"].includes(theme)) {
1526
+ console.warn(`Invalid theme: ${theme}. Using 'light' as fallback.`);
1527
+ theme = "light";
1528
+ }
1529
+ try {
1530
+ setPreference(THEME_KEY, theme);
1531
+ } catch (e) {
1532
+ }
1533
+ applyTheme(theme);
1534
+ };
1535
+ var initializeTheme = () => {
1536
+ const theme = getTheme();
1537
+ applyTheme(theme);
1538
+ };
1539
+ var onSystemThemeChange = (callback) => {
1540
+ if (typeof window === "undefined") return () => {
1541
+ };
1542
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
1543
+ const listener = (e) => {
1544
+ const theme = e.matches ? "dark" : "light";
1545
+ const hasStored = (() => {
1546
+ try {
1547
+ const stored = getPreference(THEME_KEY);
1548
+ return stored === "light" || stored === "dark";
1549
+ } catch {
1550
+ return false;
1551
+ }
1552
+ })();
1553
+ const dataTheme = document.documentElement.getAttribute(ATTR_NAME);
1554
+ if (!hasStored && !dataTheme) callback(theme);
1555
+ };
1556
+ if (mediaQuery.addEventListener) {
1557
+ mediaQuery.addEventListener("change", listener);
1558
+ return () => mediaQuery.removeEventListener("change", listener);
1559
+ }
1560
+ mediaQuery.addListener(listener);
1561
+ return () => mediaQuery.removeListener(listener);
1562
+ };
1563
+ var toggleTheme = () => {
1564
+ const current = getTheme();
1565
+ const next = current === "light" ? "dark" : "light";
1566
+ setTheme(next);
1567
+ return next;
1568
+ };
1569
+
1570
+ // src/components/theme-control/theme-control.tsx
1571
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1572
+ var themeOptions = [
1573
+ {
1574
+ value: "light",
1575
+ label: "Light",
1576
+ icon: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("svg", { className: "theme-control__icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
1577
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("circle", { cx: "12", cy: "12", r: "5" }),
1578
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("line", { x1: "12", y1: "1", x2: "12", y2: "3" }),
1579
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("line", { x1: "12", y1: "21", x2: "12", y2: "23" }),
1580
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64" }),
1581
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78" }),
1582
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("line", { x1: "1", y1: "12", x2: "3", y2: "12" }),
1583
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("line", { x1: "21", y1: "12", x2: "23", y2: "12" }),
1584
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36" }),
1585
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22" })
1586
+ ] })
1587
+ },
1588
+ {
1589
+ value: "dark",
1590
+ label: "Dark",
1591
+ icon: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("svg", { className: "theme-control__icon", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("path", { d: "M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" }) })
1592
+ }
1593
+ ];
1594
+ var ThemeControl = ({ onThemeChange }) => {
1595
+ const [currentTheme, setCurrentTheme] = React12.useState(() => {
1596
+ return getSavedTheme();
1597
+ });
1598
+ React12.useEffect(() => {
1599
+ setTheme(currentTheme);
1600
+ onThemeChange?.(currentTheme);
1601
+ }, [currentTheme, onThemeChange]);
1602
+ const handleThemeSelect = (theme) => {
1603
+ setCurrentTheme(theme);
1604
+ };
1605
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "theme-control", children: themeOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1606
+ "div",
1607
+ {
1608
+ className: `theme-control__option ${currentTheme === option.value ? "theme-control__option--active" : ""}`,
1609
+ onClick: () => handleThemeSelect(option.value),
1610
+ children: [
1611
+ option.icon,
1612
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: option.label })
1613
+ ]
1614
+ },
1615
+ option.value
1616
+ )) });
1617
+ };
1618
+
1619
+ // src/components/card/card.tsx
1620
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1621
+ var Card = ({
1622
+ variant = "default",
1623
+ children,
1624
+ className = "",
1625
+ onClick,
1626
+ ...props
1627
+ }) => {
1628
+ const cardClasses = [
1629
+ "card",
1630
+ `card--${variant}`,
1631
+ onClick && "card--interactive",
1632
+ className
1633
+ ].filter(Boolean).join(" ");
1634
+ const Component = onClick ? "button" : "div";
1635
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1636
+ Component,
1637
+ {
1638
+ className: cardClasses,
1639
+ onClick,
1640
+ ...onClick && { type: "button" },
1641
+ ...props,
1642
+ children
1643
+ }
1644
+ );
1645
+ };
1646
+
1647
+ // src/components/color-control/color-control.tsx
1648
+ var import_react11 = require("react");
1649
+
1650
+ // src/components/slider/Slider.tsx
1651
+ var import_react10 = __toESM(require("react"));
1652
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1653
+ var Slider = ({
1654
+ min = 0,
1655
+ max = 100,
1656
+ value,
1657
+ step = 1,
1658
+ onChange,
1659
+ onDragStart,
1660
+ onChangeEnd,
1661
+ label,
1662
+ showValue = true,
1663
+ className = "",
1664
+ disabled = false,
1665
+ type = "default",
1666
+ baseHue = 0,
1667
+ baseSaturation = 70
1668
+ }) => {
1669
+ const [isDragging, setIsDragging] = (0, import_react10.useState)(false);
1670
+ const inputRef = (0, import_react10.useRef)(null);
1671
+ const containerRef = (0, import_react10.useRef)(null);
1672
+ const valueRef = (0, import_react10.useRef)(value);
1673
+ import_react10.default.useEffect(() => {
1674
+ valueRef.current = value;
1675
+ }, [value]);
1676
+ const handleChange = (0, import_react10.useCallback)((event) => {
1677
+ const newValue = parseFloat(event.target.value);
1678
+ onChange(newValue);
1679
+ }, [onChange]);
1680
+ const getValueFromPosition = (0, import_react10.useCallback)((clientX) => {
1681
+ if (!containerRef.current) return value;
1682
+ const rect = containerRef.current.getBoundingClientRect();
1683
+ const percentage = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
1684
+ const rawValue = min + percentage * (max - min);
1685
+ const steppedValue = Math.round(rawValue / step) * step;
1686
+ return Math.max(min, Math.min(max, steppedValue));
1687
+ }, [min, max, step, value]);
1688
+ const handleMouseDown = (0, import_react10.useCallback)((event) => {
1689
+ if (disabled) return;
1690
+ event.preventDefault();
1691
+ setIsDragging(true);
1692
+ onDragStart?.();
1693
+ const newValue = getValueFromPosition(event.clientX);
1694
+ onChange(newValue);
1695
+ }, [disabled, onDragStart, getValueFromPosition, onChange]);
1696
+ const handleMouseMove = (0, import_react10.useCallback)((event) => {
1697
+ if (!isDragging) return;
1698
+ event.preventDefault();
1699
+ const newValue = getValueFromPosition(event.clientX);
1700
+ onChange(newValue);
1701
+ }, [isDragging, getValueFromPosition, onChange]);
1702
+ const handleMouseUp = (0, import_react10.useCallback)(() => {
1703
+ if (!isDragging) return;
1704
+ setIsDragging(false);
1705
+ onChangeEnd?.(valueRef.current);
1706
+ }, [isDragging, onChangeEnd]);
1707
+ import_react10.default.useEffect(() => {
1708
+ if (!isDragging) return;
1709
+ document.addEventListener("mousemove", handleMouseMove);
1710
+ document.addEventListener("mouseup", handleMouseUp);
1711
+ return () => {
1712
+ document.removeEventListener("mousemove", handleMouseMove);
1713
+ document.removeEventListener("mouseup", handleMouseUp);
1714
+ };
1715
+ }, [isDragging, handleMouseMove, handleMouseUp]);
1716
+ const handleTouchStart = (0, import_react10.useCallback)((event) => {
1717
+ if (disabled) return;
1718
+ event.preventDefault();
1719
+ setIsDragging(true);
1720
+ onDragStart?.();
1721
+ const touch = event.touches[0];
1722
+ const newValue = getValueFromPosition(touch.clientX);
1723
+ onChange(newValue);
1724
+ }, [disabled, onDragStart, getValueFromPosition, onChange]);
1725
+ const handleTouchMove = (0, import_react10.useCallback)((event) => {
1726
+ if (!isDragging) return;
1727
+ event.preventDefault();
1728
+ const touch = event.touches[0];
1729
+ const newValue = getValueFromPosition(touch.clientX);
1730
+ onChange(newValue);
1731
+ }, [isDragging, getValueFromPosition, onChange]);
1732
+ const handleTouchEnd = (0, import_react10.useCallback)(() => {
1733
+ if (!isDragging) return;
1734
+ setIsDragging(false);
1735
+ onChangeEnd?.(valueRef.current);
1736
+ }, [isDragging, onChangeEnd]);
1737
+ import_react10.default.useEffect(() => {
1738
+ if (!isDragging) return;
1739
+ document.addEventListener("touchmove", handleTouchMove);
1740
+ document.addEventListener("touchend", handleTouchEnd);
1741
+ return () => {
1742
+ document.removeEventListener("touchmove", handleTouchMove);
1743
+ document.removeEventListener("touchend", handleTouchEnd);
1744
+ };
1745
+ }, [isDragging, handleTouchMove, handleTouchEnd]);
1746
+ const sliderClasses = [
1747
+ "slider",
1748
+ `slider--${type}`,
1749
+ isDragging && "slider--dragging",
1750
+ disabled && "slider--disabled",
1751
+ className
1752
+ ].filter(Boolean).join(" ");
1753
+ const getBackground = () => {
1754
+ switch (type) {
1755
+ case "hue":
1756
+ return "linear-gradient(to right, hsl(0, 70%, 50%), hsl(60, 70%, 50%), hsl(120, 70%, 50%), hsl(180, 70%, 50%), hsl(240, 70%, 50%), hsl(300, 70%, 50%), hsl(360, 70%, 50%))";
1757
+ case "saturation":
1758
+ return `linear-gradient(to right, hsl(${baseHue}, 0%, 50%), hsl(${baseHue}, 100%, 50%))`;
1759
+ case "lightness":
1760
+ return `linear-gradient(to right, hsl(${baseHue}, ${baseSaturation}%, 0%), hsl(${baseHue}, ${baseSaturation}%, 50%), hsl(${baseHue}, ${baseSaturation}%, 100%))`;
1761
+ default:
1762
+ return "var(--color-action-primary)";
1763
+ }
1764
+ };
1765
+ const inputStyle = { background: getBackground() };
1766
+ const stepMarks = step > 1 ? Array.from({ length: Math.floor((max - min) / step) + 1 }, (_, i) => min + i * step) : [];
1767
+ const thumbPosition = (value - min) / (max - min) * 100;
1768
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: sliderClasses, children: [
1769
+ (label || showValue) && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "slider__header", children: [
1770
+ label && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { className: "slider__label", children: label }),
1771
+ showValue && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "slider__value", children: value })
1772
+ ] }),
1773
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "slider__container", ref: containerRef, onMouseDown: handleMouseDown, onTouchStart: handleTouchStart, children: [
1774
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1775
+ "input",
1776
+ {
1777
+ ref: inputRef,
1778
+ type: "range",
1779
+ min,
1780
+ max,
1781
+ step,
1782
+ value,
1783
+ onChange: handleChange,
1784
+ className: "slider__input",
1785
+ style: inputStyle,
1786
+ disabled,
1787
+ readOnly: true
1788
+ }
1789
+ ),
1790
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1791
+ "div",
1792
+ {
1793
+ className: "slider__thumb",
1794
+ style: {
1795
+ left: `${thumbPosition}%`,
1796
+ transform: "translateX(-50%)"
1797
+ },
1798
+ children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "slider__thumb-icon", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Icon, { name: "arrow-down", size: 16 }) })
1799
+ }
1800
+ ),
1801
+ stepMarks.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "slider__marks", children: stepMarks.map((mark) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1802
+ "div",
1803
+ {
1804
+ className: "slider__mark",
1805
+ style: {
1806
+ left: `${(mark - min) / (max - min) * 100}%`
1807
+ }
1808
+ },
1809
+ mark
1810
+ )) })
1811
+ ] })
1812
+ ] });
1813
+ };
1814
+
1815
+ // src/components/color-control/color-control.tsx
1816
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1817
+ var getCSSVariable = (variable) => {
1818
+ if (typeof window === "undefined") return 0;
1819
+ const value = getComputedStyle(document.documentElement).getPropertyValue(variable).trim();
1820
+ return value ? parseInt(value, 10) : 0;
1821
+ };
1822
+ var loadColorsFromCSS = () => {
1823
+ return {
1824
+ hues: {
1825
+ primary: getCSSVariable("--primary-hue"),
1826
+ secondary: getCSSVariable("--secondary-hue"),
1827
+ accent: getCSSVariable("--accent-hue"),
1828
+ success: getCSSVariable("--success-hue"),
1829
+ warning: getCSSVariable("--warning-hue"),
1830
+ error: getCSSVariable("--error-hue"),
1831
+ info: getCSSVariable("--info-hue")
1832
+ },
1833
+ saturations: {
1834
+ primary: getCSSVariable("--primary-saturation"),
1835
+ secondary: getCSSVariable("--secondary-saturation"),
1836
+ accent: getCSSVariable("--accent-saturation"),
1837
+ success: getCSSVariable("--success-saturation"),
1838
+ warning: getCSSVariable("--warning-saturation"),
1839
+ error: getCSSVariable("--error-saturation"),
1840
+ info: getCSSVariable("--info-saturation")
1841
+ },
1842
+ lightnesses: {
1843
+ primary: getCSSVariable("--primary-lightness"),
1844
+ secondary: getCSSVariable("--secondary-lightness"),
1845
+ accent: getCSSVariable("--accent-lightness"),
1846
+ success: getCSSVariable("--success-lightness"),
1847
+ warning: getCSSVariable("--warning-lightness"),
1848
+ error: getCSSVariable("--error-lightness"),
1849
+ info: getCSSVariable("--info-lightness")
1850
+ }
1851
+ };
1852
+ };
1853
+ var ColorControl = () => {
1854
+ const [colors, setColors] = (0, import_react11.useState)(() => {
1855
+ const saved = localStorage.getItem("color-config");
1856
+ return saved ? JSON.parse(saved) : loadColorsFromCSS();
1857
+ });
1858
+ const [pendingColors, setPendingColors] = (0, import_react11.useState)(colors);
1859
+ (0, import_react11.useEffect)(() => {
1860
+ const root = document.documentElement;
1861
+ root.style.setProperty("--hue-primary", colors.hues.primary.toString());
1862
+ root.style.setProperty("--hue-secondary", colors.hues.secondary.toString());
1863
+ root.style.setProperty("--hue-accent", colors.hues.accent.toString());
1864
+ root.style.setProperty("--hue-success", colors.hues.success.toString());
1865
+ root.style.setProperty("--hue-warning", colors.hues.warning.toString());
1866
+ root.style.setProperty("--hue-error", colors.hues.error.toString());
1867
+ root.style.setProperty("--hue-info", colors.hues.info.toString());
1868
+ root.style.setProperty("--saturation-primary", `${colors.saturations.primary}%`);
1869
+ root.style.setProperty("--saturation-secondary", `${colors.saturations.secondary}%`);
1870
+ root.style.setProperty("--saturation-accent", `${colors.saturations.accent}%`);
1871
+ root.style.setProperty("--saturation-success", `${colors.saturations.success}%`);
1872
+ root.style.setProperty("--saturation-warning", `${colors.saturations.warning}%`);
1873
+ root.style.setProperty("--saturation-error", `${colors.saturations.error}%`);
1874
+ root.style.setProperty("--saturation-info", `${colors.saturations.info}%`);
1875
+ root.style.setProperty("--lightness-primary", `${colors.lightnesses.primary}%`);
1876
+ root.style.setProperty("--lightness-secondary", `${colors.lightnesses.secondary}%`);
1877
+ root.style.setProperty("--lightness-accent", `${colors.lightnesses.accent}%`);
1878
+ root.style.setProperty("--lightness-success", `${colors.lightnesses.success}%`);
1879
+ root.style.setProperty("--lightness-warning", `${colors.lightnesses.warning}%`);
1880
+ root.style.setProperty("--lightness-error", `${colors.lightnesses.error}%`);
1881
+ root.style.setProperty("--lightness-info", `${colors.lightnesses.info}%`);
1882
+ }, []);
1883
+ const commitColorChange = (0, import_react11.useCallback)((color, property, value) => {
1884
+ setColors((prev) => {
1885
+ const newColors = {
1886
+ ...prev,
1887
+ [property === "hue" ? "hues" : property === "saturation" ? "saturations" : "lightnesses"]: {
1888
+ ...prev[property === "hue" ? "hues" : property === "saturation" ? "saturations" : "lightnesses"],
1889
+ [color]: value
1890
+ }
1891
+ };
1892
+ const root = document.documentElement;
1893
+ const cssVar = property === "hue" ? `--hue-${color}` : `--${property}-${color}`;
1894
+ const cssValue = property === "hue" ? value.toString() : `${value}%`;
1895
+ root.style.setProperty(cssVar, cssValue);
1896
+ localStorage.setItem("color-config", JSON.stringify(newColors));
1897
+ return newColors;
1898
+ });
1899
+ }, []);
1900
+ const resetToDefaults = (0, import_react11.useCallback)(() => {
1901
+ const cssColors = loadColorsFromCSS();
1902
+ setColors(cssColors);
1903
+ setPendingColors(cssColors);
1904
+ }, []);
1905
+ const renderColorControls = (colorName) => {
1906
+ const hue = pendingColors.hues[colorName];
1907
+ const saturation = pendingColors.saturations[colorName];
1908
+ const lightness = pendingColors.lightnesses[colorName];
1909
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "color-control__color-group", children: [
1910
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h4", { className: "color-control__color-title", children: colorName.charAt(0).toUpperCase() + colorName.slice(1) }),
1911
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "color-control__controls-row", children: [
1912
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "color-control__control", children: [
1913
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { className: "color-control__label", children: "Hue" }),
1914
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1915
+ Slider,
1916
+ {
1917
+ label: "",
1918
+ value: hue,
1919
+ min: 0,
1920
+ max: 360,
1921
+ step: 1,
1922
+ onChange: (v) => setPendingColors((prev) => ({
1923
+ ...prev,
1924
+ hues: { ...prev.hues, [colorName]: v }
1925
+ })),
1926
+ onChangeEnd: (v) => {
1927
+ setPendingColors((prev) => ({
1928
+ ...prev,
1929
+ hues: { ...prev.hues, [colorName]: v }
1930
+ }));
1931
+ commitColorChange(colorName, "hue", v);
1932
+ },
1933
+ type: "hue",
1934
+ showValue: false
1935
+ }
1936
+ )
1937
+ ] }),
1938
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "color-control__control", children: [
1939
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { className: "color-control__label", children: "Saturation" }),
1940
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1941
+ Slider,
1942
+ {
1943
+ label: "",
1944
+ value: saturation,
1945
+ min: 0,
1946
+ max: 100,
1947
+ step: 1,
1948
+ onChange: (v) => setPendingColors((prev) => ({
1949
+ ...prev,
1950
+ saturations: { ...prev.saturations, [colorName]: v }
1951
+ })),
1952
+ onChangeEnd: (v) => {
1953
+ setPendingColors((prev) => ({
1954
+ ...prev,
1955
+ saturations: { ...prev.saturations, [colorName]: v }
1956
+ }));
1957
+ commitColorChange(colorName, "saturation", v);
1958
+ },
1959
+ type: "saturation",
1960
+ baseHue: hue,
1961
+ showValue: false
1962
+ }
1963
+ )
1964
+ ] }),
1965
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "color-control__control", children: [
1966
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { className: "color-control__label", children: "Lightness" }),
1967
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1968
+ Slider,
1969
+ {
1970
+ label: "",
1971
+ value: lightness,
1972
+ min: 0,
1973
+ max: 100,
1974
+ step: 1,
1975
+ onChange: (v) => setPendingColors((prev) => ({
1976
+ ...prev,
1977
+ lightnesses: { ...prev.lightnesses, [colorName]: v }
1978
+ })),
1979
+ onChangeEnd: (v) => {
1980
+ setPendingColors((prev) => ({
1981
+ ...prev,
1982
+ lightnesses: { ...prev.lightnesses, [colorName]: v }
1983
+ }));
1984
+ commitColorChange(colorName, "lightness", v);
1985
+ },
1986
+ type: "lightness",
1987
+ baseHue: hue,
1988
+ baseSaturation: saturation,
1989
+ showValue: false
1990
+ }
1991
+ )
1992
+ ] }),
1993
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1994
+ "div",
1995
+ {
1996
+ className: "color-control__preview",
1997
+ style: {
1998
+ backgroundColor: `hsl(${hue}, ${saturation}%, ${lightness}%)`,
1999
+ border: "2px solid var(--color-neutral-300)"
2000
+ }
2001
+ }
2002
+ )
2003
+ ] })
2004
+ ] }, colorName);
2005
+ };
2006
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "color-control", children: [
2007
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "color-control__header", children: [
2008
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "color-control__title", children: "Paleta de Cores" }),
2009
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "color-control__description", children: "Ajuste o matiz, satura\xE7\xE3o e luminosidade das cores. As mudan\xE7as s\xE3o aplicadas instantaneamente." })
2010
+ ] }),
2011
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "color-control__sliders", children: [
2012
+ renderColorControls("primary"),
2013
+ renderColorControls("secondary"),
2014
+ renderColorControls("accent"),
2015
+ renderColorControls("success"),
2016
+ renderColorControls("warning"),
2017
+ renderColorControls("error"),
2018
+ renderColorControls("info")
2019
+ ] }),
2020
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "color-control__actions", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2021
+ "button",
2022
+ {
2023
+ onClick: resetToDefaults,
2024
+ className: "color-control__reset-btn",
2025
+ children: "Restaurar Padr\xF5es"
2026
+ }
2027
+ ) }),
2028
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "color-control__preview-section", children: [
2029
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h4", { className: "color-control__preview-title", children: "Pr\xE9via das Cores" }),
2030
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "color-control__color-grid", children: [
2031
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2032
+ "div",
2033
+ {
2034
+ className: "color-control__color-sample",
2035
+ style: { backgroundColor: `hsl(${pendingColors.hues.primary}, ${pendingColors.saturations.primary}%, ${pendingColors.lightnesses.primary}%)` },
2036
+ children: "Primary"
2037
+ }
2038
+ ),
2039
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2040
+ "div",
2041
+ {
2042
+ className: "color-control__color-sample",
2043
+ style: { backgroundColor: `hsl(${pendingColors.hues.secondary}, ${pendingColors.saturations.secondary}%, ${pendingColors.lightnesses.secondary}%)` },
2044
+ children: "Secondary"
2045
+ }
2046
+ ),
2047
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2048
+ "div",
2049
+ {
2050
+ className: "color-control__color-sample",
2051
+ style: { backgroundColor: `hsl(${pendingColors.hues.accent}, ${pendingColors.saturations.accent}%, ${pendingColors.lightnesses.accent}%)` },
2052
+ children: "Accent"
2053
+ }
2054
+ ),
2055
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2056
+ "div",
2057
+ {
2058
+ className: "color-control__color-sample",
2059
+ style: { backgroundColor: `hsl(${pendingColors.hues.success}, ${pendingColors.saturations.success}%, ${pendingColors.lightnesses.success}%)` },
2060
+ children: "Success"
2061
+ }
2062
+ ),
2063
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2064
+ "div",
2065
+ {
2066
+ className: "color-control__color-sample",
2067
+ style: { backgroundColor: `hsl(${pendingColors.hues.warning}, ${pendingColors.saturations.warning}%, ${pendingColors.lightnesses.warning}%)` },
2068
+ children: "Warning"
2069
+ }
2070
+ ),
2071
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2072
+ "div",
2073
+ {
2074
+ className: "color-control__color-sample",
2075
+ style: { backgroundColor: `hsl(${pendingColors.hues.error}, ${pendingColors.saturations.error}%, ${pendingColors.lightnesses.error}%)` },
2076
+ children: "Error"
2077
+ }
2078
+ ),
2079
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2080
+ "div",
2081
+ {
2082
+ className: "color-control__color-sample",
2083
+ style: { backgroundColor: `hsl(${pendingColors.hues.info}, ${pendingColors.saturations.info}%, ${pendingColors.lightnesses.info}%)` },
2084
+ children: "Info"
2085
+ }
2086
+ )
2087
+ ] })
2088
+ ] })
2089
+ ] });
2090
+ };
2091
+
2092
+ // src/components/grid/Grid.tsx
2093
+ var import_jsx_runtime23 = require("react/jsx-runtime");
2094
+ var Grid = ({
2095
+ columns = "auto-fit",
2096
+ minWidth = "250px",
2097
+ gap = "1rem",
2098
+ maxColumns,
2099
+ className = "",
2100
+ children,
2101
+ ...props
2102
+ }) => {
2103
+ const gridClass = [
2104
+ "grid",
2105
+ typeof columns === "number" ? `grid--cols-${Math.min(columns, maxColumns || columns)}` : `grid--${columns}`,
2106
+ className
2107
+ ].filter(Boolean).join(" ");
2108
+ const style = {
2109
+ "--grid-min-width": minWidth,
2110
+ "--grid-gap": gap
2111
+ };
2112
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: gridClass, style, ...props, children });
2113
+ };
2114
+
2115
+ // src/components/footer/footer.tsx
2116
+ var import_jsx_runtime24 = require("react/jsx-runtime");
2117
+ var Footer = ({ className = "", children, ...props }) => {
2118
+ const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
2119
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("footer", { className: `footer ${className}`.trim(), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "footer__container", children: children ? children : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "footer__bottom", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("p", { className: "footer__copyright", children: [
2120
+ "\xA9 ",
2121
+ currentYear,
2122
+ " ",
2123
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("strong", { children: "HellboyDS" }),
2124
+ " is a design system package published on npm by user ",
2125
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("strong", { children: "@hellboy" }),
2126
+ ". This project is not affiliated with any comic book, film, television, or other artistic works."
2127
+ ] }) }) }) }) });
2128
+ };
2129
+
2130
+ // src/components/input/InputText.tsx
2131
+ var import_react12 = __toESM(require("react"));
2132
+
2133
+ // src/components/input/Input.tsx
2134
+ var React18 = __toESM(require("react"));
2135
+
2136
+ // src/components/input/InputField.tsx
2137
+ var React15 = __toESM(require("react"));
2138
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2139
+ var InputField = React15.forwardRef(
2140
+ ({
2141
+ type = "text",
2142
+ label,
2143
+ helperText,
2144
+ error,
2145
+ icon,
2146
+ iconRight,
2147
+ fullWidth = false,
2148
+ size = "md",
2149
+ className = "",
2150
+ disabled,
2151
+ id,
2152
+ onRightIconClick,
2153
+ ...props
2154
+ }, ref) => {
2155
+ const inputId = id || `input-${React15.useId()}`;
2156
+ const containerClasses = [
2157
+ "input-container",
2158
+ fullWidth && "input-container--full-width",
2159
+ className
2160
+ ].filter(Boolean).join(" ");
2161
+ const inputClasses = [
2162
+ "input",
2163
+ `input--${size}`,
2164
+ error && "input--error",
2165
+ disabled && "input--disabled",
2166
+ icon && "input--has-icon-left",
2167
+ iconRight && "input--has-icon-right"
2168
+ ].filter(Boolean).join(" ");
2169
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: containerClasses, children: [
2170
+ label && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("label", { htmlFor: inputId, className: "input__label", children: label }),
2171
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "input__wrapper", children: [
2172
+ icon && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "input__icon input__icon--left", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon, { name: icon, size: 16 }) }),
2173
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2174
+ "input",
2175
+ {
2176
+ ref,
2177
+ type,
2178
+ id: inputId,
2179
+ className: inputClasses,
2180
+ disabled,
2181
+ ...props
2182
+ }
2183
+ ),
2184
+ iconRight && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2185
+ "button",
2186
+ {
2187
+ type: "button",
2188
+ className: "input__icon input__icon--right",
2189
+ onClick: onRightIconClick,
2190
+ tabIndex: -1,
2191
+ "aria-label": "Icon action",
2192
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Icon, { name: iconRight, size: 16 })
2193
+ }
2194
+ )
2195
+ ] }),
2196
+ error && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "input__message input__message--error", children: error }),
2197
+ helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "input__message", children: helperText })
2198
+ ] });
2199
+ }
2200
+ );
2201
+
2202
+ // src/components/input/DatePicker.tsx
2203
+ var React16 = __toESM(require("react"));
2204
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2205
+ var MONTHS = [
2206
+ "January",
2207
+ "February",
2208
+ "March",
2209
+ "April",
2210
+ "May",
2211
+ "June",
2212
+ "July",
2213
+ "August",
2214
+ "September",
2215
+ "October",
2216
+ "November",
2217
+ "December"
2218
+ ];
2219
+ var DAYS_OF_WEEK = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
2220
+ var DatePicker = ({ value, onChange, disabled }) => {
2221
+ const parseDate = (dateStr) => {
2222
+ if (!dateStr) {
2223
+ const today = /* @__PURE__ */ new Date();
2224
+ return { year: today.getFullYear(), month: today.getMonth(), day: today.getDate() };
2225
+ }
2226
+ const [year, month, day] = dateStr.split("-").map(Number);
2227
+ return { year, month: month - 1, day };
2228
+ };
2229
+ const { year: initialYear, month: initialMonth, day: selectedDay } = parseDate(value);
2230
+ const [currentYear, setCurrentYear] = React16.useState(initialYear);
2231
+ const [currentMonth, setCurrentMonth] = React16.useState(initialMonth);
2232
+ const getDaysInMonth = (year, month) => {
2233
+ return new Date(year, month + 1, 0).getDate();
2234
+ };
2235
+ const getFirstDayOfMonth = (year, month) => {
2236
+ return new Date(year, month, 1).getDay();
2237
+ };
2238
+ const handleDateSelect = (day) => {
2239
+ if (disabled) return;
2240
+ const formattedDate = `${currentYear}-${String(currentMonth + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
2241
+ onChange(formattedDate);
2242
+ };
2243
+ const handlePrevMonth = () => {
2244
+ if (currentMonth === 0) {
2245
+ setCurrentMonth(11);
2246
+ setCurrentYear(currentYear - 1);
2247
+ } else {
2248
+ setCurrentMonth(currentMonth - 1);
2249
+ }
2250
+ };
2251
+ const handleNextMonth = () => {
2252
+ if (currentMonth === 11) {
2253
+ setCurrentMonth(0);
2254
+ setCurrentYear(currentYear + 1);
2255
+ } else {
2256
+ setCurrentMonth(currentMonth + 1);
2257
+ }
2258
+ };
2259
+ const daysInMonth = getDaysInMonth(currentYear, currentMonth);
2260
+ const firstDay = getFirstDayOfMonth(currentYear, currentMonth);
2261
+ const days = [
2262
+ ...Array(firstDay).fill(null),
2263
+ ...Array.from({ length: daysInMonth }, (_, i) => i + 1)
2264
+ ];
2265
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "date-picker", children: [
2266
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "date-picker__header", children: [
2267
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2268
+ "button",
2269
+ {
2270
+ type: "button",
2271
+ className: "date-picker__nav",
2272
+ onClick: handlePrevMonth,
2273
+ disabled,
2274
+ "aria-label": "Previous month",
2275
+ children: "\u2039"
2276
+ }
2277
+ ),
2278
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "date-picker__title", children: [
2279
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2280
+ "select",
2281
+ {
2282
+ className: "date-picker__select",
2283
+ value: currentMonth,
2284
+ onChange: (e) => setCurrentMonth(Number(e.target.value)),
2285
+ disabled,
2286
+ children: MONTHS.map((month, idx) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: idx, children: month }, month))
2287
+ }
2288
+ ),
2289
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2290
+ "select",
2291
+ {
2292
+ className: "date-picker__select",
2293
+ value: currentYear,
2294
+ onChange: (e) => setCurrentYear(Number(e.target.value)),
2295
+ disabled,
2296
+ children: Array.from({ length: 100 }, (_, i) => currentYear - 50 + i).map((year) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("option", { value: year, children: year }, year))
2297
+ }
2298
+ )
2299
+ ] }),
2300
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2301
+ "button",
2302
+ {
2303
+ type: "button",
2304
+ className: "date-picker__nav",
2305
+ onClick: handleNextMonth,
2306
+ disabled,
2307
+ "aria-label": "Next month",
2308
+ children: "\u203A"
2309
+ }
2310
+ )
2311
+ ] }),
2312
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "date-picker__weekdays", children: DAYS_OF_WEEK.map((day) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "date-picker__weekday", children: day }, day)) }),
2313
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "date-picker__days", children: days.map((day, idx) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
2314
+ "button",
2315
+ {
2316
+ type: "button",
2317
+ className: `date-picker__day ${day === selectedDay ? "date-picker__day--selected" : ""} ${!day ? "date-picker__day--empty" : ""}`,
2318
+ onClick: () => day && handleDateSelect(day),
2319
+ disabled: !day || disabled,
2320
+ children: day || ""
2321
+ },
2322
+ idx
2323
+ )) })
2324
+ ] });
2325
+ };
2326
+
2327
+ // src/components/input/TimePicker.tsx
2328
+ var React17 = __toESM(require("react"));
2329
+ var import_jsx_runtime27 = require("react/jsx-runtime");
2330
+ var parseTime = (timeStr) => {
2331
+ if (!timeStr) return { hours: 0, minutes: 0, seconds: 0, milliseconds: 0 };
2332
+ const parts = timeStr.split(":");
2333
+ const hours = parseInt(parts[0] || "0", 10);
2334
+ const minutes = parseInt(parts[1] || "0", 10);
2335
+ const secondsParts = (parts[2] || "0").split(".");
2336
+ const seconds = parseInt(secondsParts[0] || "0", 10);
2337
+ const milliseconds = parseInt(secondsParts[1] || "0", 10);
2338
+ return { hours, minutes, seconds, milliseconds };
2339
+ };
2340
+ var TimeColumn = ({
2341
+ label,
2342
+ value,
2343
+ max,
2344
+ field,
2345
+ step,
2346
+ disabled,
2347
+ onChange
2348
+ }) => {
2349
+ const items = Array.from({ length: Math.floor(max / step) + 1 }, (_, i) => i * step);
2350
+ const columnRef = React17.useRef(null);
2351
+ React17.useEffect(() => {
2352
+ if (columnRef.current) {
2353
+ const selected = columnRef.current.querySelector(".time-picker__item--selected");
2354
+ if (selected) {
2355
+ selected.scrollIntoView({ block: "center", behavior: "smooth" });
2356
+ }
2357
+ }
2358
+ }, [value]);
2359
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "time-picker__column", children: [
2360
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "time-picker__label", children: label }),
2361
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "time-picker__scroll", ref: columnRef, children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2362
+ "button",
2363
+ {
2364
+ type: "button",
2365
+ className: `time-picker__item ${item === value ? "time-picker__item--selected" : ""}`,
2366
+ onClick: () => onChange(field, item),
2367
+ disabled,
2368
+ children: String(item).padStart(field === "milliseconds" ? 3 : 2, "0")
2369
+ },
2370
+ item
2371
+ )) })
2372
+ ] });
2373
+ };
2374
+ var TimePicker = ({
2375
+ value,
2376
+ onChange,
2377
+ disabled,
2378
+ showMilliseconds = false,
2379
+ minuteStep = 1
2380
+ }) => {
2381
+ const [internalTime, setInternalTime] = React17.useState(value);
2382
+ React17.useEffect(() => {
2383
+ setInternalTime(value);
2384
+ }, [value]);
2385
+ const { hours, minutes, seconds, milliseconds } = parseTime(internalTime);
2386
+ const handleChange = (field, newValue) => {
2387
+ if (disabled) return;
2388
+ const currentParsed = parseTime(internalTime);
2389
+ const updated = { ...currentParsed, [field]: newValue };
2390
+ let formattedTime = `${String(updated.hours).padStart(2, "0")}:${String(updated.minutes).padStart(2, "0")}:${String(updated.seconds).padStart(2, "0")}`;
2391
+ if (showMilliseconds && updated.milliseconds > 0) {
2392
+ formattedTime += `.${String(updated.milliseconds).padStart(3, "0")}`;
2393
+ }
2394
+ setInternalTime(formattedTime);
2395
+ onChange(formattedTime);
2396
+ };
2397
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "time-picker", children: [
2398
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2399
+ TimeColumn,
2400
+ {
2401
+ label: "Hours",
2402
+ value: hours,
2403
+ max: 23,
2404
+ field: "hours",
2405
+ step: 1,
2406
+ disabled,
2407
+ onChange: handleChange
2408
+ }
2409
+ ),
2410
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2411
+ TimeColumn,
2412
+ {
2413
+ label: "Minutes",
2414
+ value: minutes,
2415
+ max: 59,
2416
+ field: "minutes",
2417
+ step: minuteStep,
2418
+ disabled,
2419
+ onChange: handleChange
2420
+ }
2421
+ ),
2422
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2423
+ TimeColumn,
2424
+ {
2425
+ label: "Seconds",
2426
+ value: seconds,
2427
+ max: 59,
2428
+ field: "seconds",
2429
+ step: 1,
2430
+ disabled,
2431
+ onChange: handleChange
2432
+ }
2433
+ ),
2434
+ showMilliseconds && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
2435
+ TimeColumn,
2436
+ {
2437
+ label: "ms",
2438
+ value: milliseconds,
2439
+ max: 999,
2440
+ field: "milliseconds",
2441
+ step: 1,
2442
+ disabled,
2443
+ onChange: handleChange
2444
+ }
2445
+ )
2446
+ ] });
2447
+ };
2448
+
2449
+ // src/components/input/Input.tsx
2450
+ var import_jsx_runtime28 = require("react/jsx-runtime");
2451
+ var TYPE_ICON_MAP = {
2452
+ email: "mail",
2453
+ password: "lock-closed",
2454
+ search: "search",
2455
+ date: "calendar",
2456
+ time: "time",
2457
+ "datetime-local": "calendar",
2458
+ tel: "call",
2459
+ url: "link"
2460
+ };
2461
+ var formatDisplayValue = (val, inputType) => {
2462
+ if (!val) return "";
2463
+ if (inputType === "date") {
2464
+ const [year, month, day] = val.split("-");
2465
+ return `${day}/${month}/${year}`;
2466
+ }
2467
+ if (inputType === "time") {
2468
+ return val;
2469
+ }
2470
+ if (inputType === "datetime-local") {
2471
+ const [datePart, timePart] = val.split("T");
2472
+ if (datePart && timePart) {
2473
+ const [year, month, day] = datePart.split("-");
2474
+ return `${day}/${month}/${year} ${timePart}`;
2475
+ }
2476
+ return val;
2477
+ }
2478
+ return val;
2479
+ };
2480
+ var Input = React18.forwardRef(
2481
+ ({
2482
+ type = "text",
2483
+ label,
2484
+ helperText,
2485
+ error,
2486
+ icon,
2487
+ fullWidth = false,
2488
+ size = "md",
2489
+ className = "",
2490
+ disabled,
2491
+ id,
2492
+ showMilliseconds = false,
2493
+ minuteStep = 1,
2494
+ showClear = true,
2495
+ ...props
2496
+ }, ref) => {
2497
+ const [showPassword, setShowPassword] = React18.useState(false);
2498
+ const [showDateTimePicker, setShowDateTimePicker] = React18.useState(false);
2499
+ const inputRef = React18.useRef(null);
2500
+ const leftIcon = icon || TYPE_ICON_MAP[type];
2501
+ const isPasswordType = type === "password";
2502
+ const actualType = isPasswordType && showPassword ? "text" : type !== "date" && type !== "time" && type !== "datetime-local" ? type : "text";
2503
+ const isDateTimeType = type === "date" || type === "time" || type === "datetime-local";
2504
+ const isSearchType = type === "search";
2505
+ const hasValue = props.value && String(props.value).length > 0;
2506
+ const rightIconName = isPasswordType ? showPassword ? "eye-off" : "eye" : isDateTimeType ? "chevron-down" : isSearchType && hasValue && showClear ? "x" : void 0;
2507
+ const handleRightIconClick = () => {
2508
+ if (isPasswordType) {
2509
+ setShowPassword(!showPassword);
2510
+ } else if (isDateTimeType) {
2511
+ setShowDateTimePicker(!showDateTimePicker);
2512
+ } else if (isSearchType && hasValue && showClear) {
2513
+ if (props.onChange) {
2514
+ props.onChange({ target: { value: "" } });
2515
+ }
2516
+ }
2517
+ };
2518
+ const handleDateTimeChange = (newValue) => {
2519
+ if (props.onChange) {
2520
+ props.onChange({ target: { value: newValue } });
2521
+ }
2522
+ };
2523
+ if (!isDateTimeType) {
2524
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2525
+ InputField,
2526
+ {
2527
+ ref: ref || inputRef,
2528
+ type: actualType,
2529
+ label,
2530
+ helperText,
2531
+ error,
2532
+ icon: leftIcon,
2533
+ iconRight: rightIconName,
2534
+ onRightIconClick: handleRightIconClick,
2535
+ fullWidth,
2536
+ size,
2537
+ className,
2538
+ disabled,
2539
+ id,
2540
+ ...props
2541
+ }
2542
+ );
2543
+ }
2544
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: `input-container ${fullWidth ? "input-container--full-width" : ""} ${className}`.trim(), children: [
2545
+ label && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("label", { htmlFor: id, className: "input__label", children: label }),
2546
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2547
+ Popover,
2548
+ {
2549
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2550
+ InputField,
2551
+ {
2552
+ ref: ref || inputRef,
2553
+ type: "text",
2554
+ icon: leftIcon,
2555
+ iconRight: rightIconName,
2556
+ onRightIconClick: () => setShowDateTimePicker(!showDateTimePicker),
2557
+ fullWidth,
2558
+ size,
2559
+ disabled,
2560
+ id,
2561
+ value: formatDisplayValue(String(props.value || ""), type),
2562
+ placeholder: props.placeholder,
2563
+ readOnly: true
2564
+ }
2565
+ ),
2566
+ isOpen: showDateTimePicker,
2567
+ onToggle: () => setShowDateTimePicker(!showDateTimePicker),
2568
+ placement: "bottom",
2569
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { style: { padding: "1rem" }, children: [
2570
+ (type === "date" || type === "datetime-local") && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2571
+ DatePicker,
2572
+ {
2573
+ value: String(props.value || "").split("T")[0],
2574
+ onChange: (newDate) => {
2575
+ if (type === "datetime-local") {
2576
+ const time = String(props.value || "").split("T")[1] || "00:00:00";
2577
+ handleDateTimeChange(`${newDate}T${time}`);
2578
+ } else {
2579
+ handleDateTimeChange(newDate);
2580
+ setShowDateTimePicker(false);
2581
+ }
2582
+ },
2583
+ disabled
2584
+ }
2585
+ ),
2586
+ (type === "time" || type === "datetime-local") && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2587
+ TimePicker,
2588
+ {
2589
+ value: String(props.value || "").split("T")[1] || "00:00:00",
2590
+ onChange: (newTime) => {
2591
+ if (type === "datetime-local") {
2592
+ const date = String(props.value || "").split("T")[0] || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
2593
+ handleDateTimeChange(`${date}T${newTime}`);
2594
+ } else {
2595
+ handleDateTimeChange(newTime);
2596
+ }
2597
+ },
2598
+ disabled,
2599
+ showMilliseconds,
2600
+ minuteStep
2601
+ }
2602
+ )
2603
+ ] })
2604
+ }
2605
+ ),
2606
+ error && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "input__message input__message--error", children: error }),
2607
+ helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "input__message", children: helperText })
2608
+ ] });
2609
+ }
2610
+ );
2611
+ Input.displayName = "Input";
2612
+
2613
+ // src/components/input/InputText.tsx
2614
+ var import_jsx_runtime29 = require("react/jsx-runtime");
2615
+ var InputText = import_react12.default.forwardRef((props, ref) => {
2616
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Input, { ref, ...props, type: "text" });
2617
+ });
2618
+ InputText.displayName = "InputText";
2619
+
2620
+ // src/components/input/InputEmail.tsx
2621
+ var import_react13 = __toESM(require("react"));
2622
+ var import_jsx_runtime30 = require("react/jsx-runtime");
2623
+ var InputEmail = import_react13.default.forwardRef((props, ref) => {
2624
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Input, { ref, ...props, type: "email" });
2625
+ });
2626
+ InputEmail.displayName = "InputEmail";
2627
+
2628
+ // src/components/input/InputPassword.tsx
2629
+ var import_react14 = __toESM(require("react"));
2630
+ var import_jsx_runtime31 = require("react/jsx-runtime");
2631
+ var InputPassword = import_react14.default.forwardRef((props, ref) => {
2632
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Input, { ref, ...props, type: "password" });
2633
+ });
2634
+ InputPassword.displayName = "InputPassword";
2635
+
2636
+ // src/components/input/InputSearch.tsx
2637
+ var import_react15 = __toESM(require("react"));
2638
+ var import_jsx_runtime32 = require("react/jsx-runtime");
2639
+ var InputSearch = import_react15.default.forwardRef((props, ref) => {
2640
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Input, { ref, ...props, type: "search" });
2641
+ });
2642
+ InputSearch.displayName = "InputSearch";
2643
+
2644
+ // src/components/input/InputTel.tsx
2645
+ var import_react16 = __toESM(require("react"));
2646
+ var import_jsx_runtime33 = require("react/jsx-runtime");
2647
+ var InputTel = import_react16.default.forwardRef((props, ref) => {
2648
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Input, { ref, ...props, type: "tel" });
2649
+ });
2650
+ InputTel.displayName = "InputTel";
2651
+
2652
+ // src/components/input/InputUrl.tsx
2653
+ var import_react17 = __toESM(require("react"));
2654
+ var import_jsx_runtime34 = require("react/jsx-runtime");
2655
+ var InputUrl = import_react17.default.forwardRef((props, ref) => {
2656
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Input, { ref, ...props, type: "url" });
2657
+ });
2658
+ InputUrl.displayName = "InputUrl";
2659
+
2660
+ // src/components/input/InputNumber.tsx
2661
+ var import_react18 = __toESM(require("react"));
2662
+ var import_jsx_runtime35 = require("react/jsx-runtime");
2663
+ var InputNumber = import_react18.default.forwardRef((props, ref) => {
2664
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Input, { ref, ...props, type: "number" });
2665
+ });
2666
+ InputNumber.displayName = "InputNumber";
2667
+
2668
+ // src/components/input/InputDate.tsx
2669
+ var import_react19 = __toESM(require("react"));
2670
+ var import_jsx_runtime36 = require("react/jsx-runtime");
2671
+ var InputDate = import_react19.default.forwardRef((props, ref) => {
2672
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Input, { ref, ...props, type: "date" });
2673
+ });
2674
+ InputDate.displayName = "InputDate";
2675
+
2676
+ // src/components/input/InputTime.tsx
2677
+ var import_react20 = __toESM(require("react"));
2678
+ var import_jsx_runtime37 = require("react/jsx-runtime");
2679
+ var InputTime = import_react20.default.forwardRef((props, ref) => {
2680
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Input, { ref, ...props, type: "time" });
2681
+ });
2682
+ InputTime.displayName = "InputTime";
2683
+
2684
+ // src/components/input/InputDateTime.tsx
2685
+ var import_react21 = __toESM(require("react"));
2686
+ var import_jsx_runtime38 = require("react/jsx-runtime");
2687
+ var InputDateTime = import_react21.default.forwardRef((props, ref) => {
2688
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Input, { ref, ...props, type: "datetime-local" });
2689
+ });
2690
+ InputDateTime.displayName = "InputDateTime";
2691
+
2692
+ // src/components/list/List.tsx
2693
+ var import_jsx_runtime39 = require("react/jsx-runtime");
2694
+ var ListItem = ({
2695
+ children,
2696
+ icon,
2697
+ selected = false,
2698
+ disabled = false,
2699
+ onClick,
2700
+ category,
2701
+ className = "",
2702
+ ...props
2703
+ }) => {
2704
+ const classes = [
2705
+ "list-item",
2706
+ selected && "list-item--selected",
2707
+ disabled && "list-item--disabled",
2708
+ onClick && !disabled && "list-item--interactive",
2709
+ className
2710
+ ].filter(Boolean).join(" ");
2711
+ const handleClick = () => {
2712
+ if (!disabled && onClick) {
2713
+ onClick();
2714
+ }
2715
+ };
2716
+ const handleKeyDown = (e) => {
2717
+ if (!disabled && onClick && (e.key === "Enter" || e.key === " ")) {
2718
+ e.preventDefault();
2719
+ onClick();
2720
+ }
2721
+ };
2722
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
2723
+ "div",
2724
+ {
2725
+ className: classes,
2726
+ onClick: handleClick,
2727
+ onKeyDown: handleKeyDown,
2728
+ role: onClick ? "button" : void 0,
2729
+ tabIndex: onClick && !disabled ? 0 : void 0,
2730
+ "aria-selected": selected,
2731
+ "aria-disabled": disabled,
2732
+ ...props,
2733
+ children: [
2734
+ icon && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "list-item__icon", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Icon, { name: icon, size: 20 }) }),
2735
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "list-item__content", children: [
2736
+ category && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "list-item__category", children: category }),
2737
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { children })
2738
+ ] }),
2739
+ selected && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "list-item__indicator", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Icon, { name: "checkmark", size: 16 }) })
2740
+ ]
2741
+ }
2742
+ );
2743
+ };
2744
+ var List = ({ children, className = "", ...props }) => {
2745
+ const classes = ["list", className].filter(Boolean).join(" ");
2746
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: classes, role: "list", ...props, children });
2747
+ };
2748
+
2749
+ // src/components/radio/Radio.tsx
2750
+ var import_react22 = __toESM(require("react"));
2751
+ var import_react23 = require("@ariakit/react");
2752
+ var import_jsx_runtime40 = require("react/jsx-runtime");
2753
+ var Radio = import_react22.default.forwardRef(
2754
+ ({
2755
+ size = "md",
2756
+ label,
2757
+ error = false,
2758
+ disabled = false,
2759
+ className,
2760
+ ...props
2761
+ }, ref) => {
2762
+ const radioClasses = [
2763
+ "radio",
2764
+ `radio--${size}`,
2765
+ error && "radio--error",
2766
+ disabled && "radio--disabled",
2767
+ className
2768
+ ].filter(Boolean).join(" ");
2769
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("label", { className: radioClasses, children: [
2770
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2771
+ import_react23.Radio,
2772
+ {
2773
+ ref,
2774
+ disabled,
2775
+ className: "radio__input",
2776
+ ...props
2777
+ }
2778
+ ),
2779
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "radio__box", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "radio__dot" }) }),
2780
+ label && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "radio__label", children: label })
2781
+ ] });
2782
+ }
2783
+ );
2784
+ Radio.displayName = "Radio";
2785
+ var RadioGroup = import_react22.default.forwardRef(
2786
+ ({
2787
+ size = "md",
2788
+ label,
2789
+ error,
2790
+ helperText,
2791
+ children,
2792
+ orientation = "vertical",
2793
+ disabled = false,
2794
+ className,
2795
+ value,
2796
+ onChange,
2797
+ ...props
2798
+ }, ref) => {
2799
+ const groupClasses = [
2800
+ "radio-group",
2801
+ `radio-group--${orientation}`,
2802
+ error && "radio-group--error",
2803
+ disabled && "radio-group--disabled",
2804
+ className
2805
+ ].filter(Boolean).join(" ");
2806
+ const radioGroupStore = (0, import_react23.useRadioStore)({
2807
+ value,
2808
+ setValue: onChange
2809
+ });
2810
+ const childrenWithProps = import_react22.default.Children.map(children, (child) => {
2811
+ if (import_react22.default.isValidElement(child) && child.type === Radio) {
2812
+ return import_react22.default.cloneElement(child, {
2813
+ size: child.props.size || size,
2814
+ error: error ? true : child.props.error,
2815
+ disabled: disabled || child.props.disabled
2816
+ });
2817
+ }
2818
+ return child;
2819
+ });
2820
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: groupClasses, children: [
2821
+ label && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "radio-group__label", children: label }),
2822
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2823
+ import_react23.RadioGroup,
2824
+ {
2825
+ ref,
2826
+ store: radioGroupStore,
2827
+ className: "radio-group__container",
2828
+ ...props,
2829
+ children: childrenWithProps
2830
+ }
2831
+ ),
2832
+ (error || helperText) && /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: "radio-group__feedback", children: [
2833
+ error && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "radio-group__error-text", children: error }),
2834
+ !error && helperText && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "radio-group__helper-text", children: helperText })
2835
+ ] })
2836
+ ] });
2837
+ }
2838
+ );
2839
+ RadioGroup.displayName = "RadioGroup";
2840
+
2841
+ // src/components/select/Select.tsx
2842
+ var React30 = __toESM(require("react"));
2843
+ var import_jsx_runtime41 = require("react/jsx-runtime");
2844
+ var Select = ({
2845
+ options,
2846
+ value,
2847
+ onChange,
2848
+ label,
2849
+ placeholder = "Select an option",
2850
+ helperText,
2851
+ error,
2852
+ disabled = false,
2853
+ fullWidth = false,
2854
+ size = "md",
2855
+ className = "",
2856
+ id
2857
+ }) => {
2858
+ const [isOpen, setIsOpen] = React30.useState(false);
2859
+ const selectId = id || `select-${React30.useId()}`;
2860
+ const selectedOption = options.find((opt) => opt.value === value);
2861
+ const handleSelect = (optionValue) => {
2862
+ onChange?.(optionValue);
2863
+ setIsOpen(false);
2864
+ };
2865
+ const handleKeyDown = (e) => {
2866
+ if (disabled) return;
2867
+ if (e.key === "Enter" || e.key === " ") {
2868
+ e.preventDefault();
2869
+ setIsOpen(!isOpen);
2870
+ } else if (e.key === "Escape") {
2871
+ setIsOpen(false);
2872
+ } else if (e.key === "ArrowDown" || e.key === "ArrowUp") {
2873
+ e.preventDefault();
2874
+ if (!isOpen) {
2875
+ setIsOpen(true);
2876
+ }
2877
+ }
2878
+ };
2879
+ const containerClasses = [
2880
+ "select-container",
2881
+ fullWidth && "select-container--full-width",
2882
+ className
2883
+ ].filter(Boolean).join(" ");
2884
+ const triggerClasses = [
2885
+ "select__trigger",
2886
+ `select__trigger--${size}`,
2887
+ error && "select__trigger--error",
2888
+ disabled && "select__trigger--disabled",
2889
+ isOpen && "select__trigger--open"
2890
+ ].filter(Boolean).join(" ");
2891
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: containerClasses, children: [
2892
+ label && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("label", { htmlFor: selectId, className: "select__label", children: label }),
2893
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2894
+ Popover,
2895
+ {
2896
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
2897
+ "button",
2898
+ {
2899
+ id: selectId,
2900
+ type: "button",
2901
+ className: triggerClasses,
2902
+ onClick: () => !disabled && setIsOpen(!isOpen),
2903
+ onKeyDown: handleKeyDown,
2904
+ disabled,
2905
+ "aria-haspopup": "listbox",
2906
+ "aria-expanded": isOpen,
2907
+ "aria-labelledby": label ? `${selectId}-label` : void 0,
2908
+ "aria-describedby": error ? `${selectId}-error` : helperText ? `${selectId}-helper` : void 0,
2909
+ "aria-invalid": error ? "true" : "false",
2910
+ children: [
2911
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("span", { className: "select__trigger-content", children: [
2912
+ selectedOption?.icon && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2913
+ Icon,
2914
+ {
2915
+ name: selectedOption.icon,
2916
+ size: size === "sm" ? 16 : size === "lg" ? 24 : 20
2917
+ }
2918
+ ),
2919
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "select__trigger-text", children: selectedOption ? selectedOption.label : placeholder })
2920
+ ] }),
2921
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2922
+ Icon,
2923
+ {
2924
+ name: "chevron-down",
2925
+ size: size === "sm" ? 16 : size === "lg" ? 24 : 20,
2926
+ className: "select__trigger-icon"
2927
+ }
2928
+ )
2929
+ ]
2930
+ }
2931
+ ),
2932
+ isOpen,
2933
+ onToggle: () => !disabled && setIsOpen(!isOpen),
2934
+ placement: "bottom",
2935
+ children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "select__dropdown", role: "listbox", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(List, { children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
2936
+ ListItem,
2937
+ {
2938
+ icon: option.icon,
2939
+ selected: option.value === value,
2940
+ disabled: option.disabled,
2941
+ onClick: () => !option.disabled && handleSelect(option.value),
2942
+ role: "option",
2943
+ "aria-selected": option.value === value,
2944
+ children: option.label
2945
+ },
2946
+ option.value
2947
+ )) }) })
2948
+ }
2949
+ ),
2950
+ error && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("p", { id: `${selectId}-error`, className: "select__message select__message--error", children: error }),
2951
+ helperText && !error && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("p", { id: `${selectId}-helper`, className: "select__message", children: helperText })
2952
+ ] });
2953
+ };
2954
+
2955
+ // src/components/banner/Banner.tsx
2956
+ var import_jsx_runtime42 = require("react/jsx-runtime");
2957
+ var Banner = ({
2958
+ type = "info",
2959
+ children,
2960
+ icon,
2961
+ onDismiss
2962
+ }) => {
2963
+ const defaultIcons = {
2964
+ info: "information-circle",
2965
+ warning: "warning",
2966
+ error: "close-circle",
2967
+ success: "checkmark-circle"
2968
+ };
2969
+ const displayIcon = icon || defaultIcons[type];
2970
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: `banner banner--${type}`, children: [
2971
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "banner__content", children: [
2972
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Icon, { name: displayIcon, size: 32 }),
2973
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "banner__message", children })
2974
+ ] }),
2975
+ onDismiss && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2976
+ Button,
2977
+ {
2978
+ variant: "ghost",
2979
+ size: "xs",
2980
+ onClick: onDismiss,
2981
+ "aria-label": "Dismiss banner",
2982
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Icon, { name: "close", size: 20 })
2983
+ }
2984
+ )
2985
+ ] });
2986
+ };
2987
+
2988
+ // src/components/floating-bar/floating-bar.tsx
2989
+ var import_jsx_runtime43 = require("react/jsx-runtime");
2990
+ var FloatingBar = ({
2991
+ position = "bottom",
2992
+ children,
2993
+ className = "",
2994
+ ...props
2995
+ }) => {
2996
+ const classes = [
2997
+ "floating-bar",
2998
+ `floating-bar--${position}`,
2999
+ className
3000
+ ].filter(Boolean).join(" ");
3001
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3002
+ "div",
3003
+ {
3004
+ className: classes,
3005
+ ...props,
3006
+ children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "floating-bar__content", children })
3007
+ }
3008
+ );
3009
+ };
3010
+
3011
+ // src/components/drawer/drawer.tsx
3012
+ var import_react24 = require("@ariakit/react");
3013
+ var import_jsx_runtime44 = require("react/jsx-runtime");
3014
+ var Drawer = ({
3015
+ children,
3016
+ title,
3017
+ placement = "right",
3018
+ size = "400px",
3019
+ store,
3020
+ ...props
3021
+ }) => {
3022
+ const sizeValue = typeof size === "number" ? `${size}px` : size;
3023
+ const getDrawerStyles = () => {
3024
+ const baseStyles = {
3025
+ zIndex: 1e3
3026
+ };
3027
+ switch (placement) {
3028
+ case "top":
3029
+ return {
3030
+ ...baseStyles,
3031
+ height: sizeValue
3032
+ };
3033
+ case "bottom":
3034
+ return {
3035
+ ...baseStyles,
3036
+ height: sizeValue
3037
+ };
3038
+ case "left":
3039
+ return {
3040
+ ...baseStyles,
3041
+ width: sizeValue
3042
+ };
3043
+ case "right":
3044
+ default:
3045
+ return {
3046
+ ...baseStyles,
3047
+ width: sizeValue
3048
+ };
3049
+ }
3050
+ };
3051
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3052
+ import_react24.Dialog,
3053
+ {
3054
+ store,
3055
+ ...props,
3056
+ className: `drawer drawer--${placement}`,
3057
+ style: getDrawerStyles(),
3058
+ backdrop: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "drawer__backdrop" }),
3059
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "drawer__content", children: [
3060
+ title && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "drawer__header", children: [
3061
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react24.DialogHeading, { className: "drawer__title", children: title }),
3062
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3063
+ "button",
3064
+ {
3065
+ className: "drawer__close",
3066
+ onClick: store.hide,
3067
+ "aria-label": "Close drawer",
3068
+ children: "\u2715"
3069
+ }
3070
+ )
3071
+ ] }),
3072
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "drawer__body", children })
3073
+ ] })
3074
+ }
3075
+ );
3076
+ };
3077
+
3078
+ // src/components/table/Table.tsx
3079
+ var import_jsx_runtime45 = require("react/jsx-runtime");
3080
+ var Table = ({
3081
+ bordered = false,
3082
+ striped = true,
3083
+ hover = true,
3084
+ size = "md",
3085
+ className = "",
3086
+ children,
3087
+ ...props
3088
+ }) => {
3089
+ const classes = [
3090
+ "table",
3091
+ bordered && "table--bordered",
3092
+ striped && "table--striped",
3093
+ hover && "table--hover",
3094
+ size && `table--${size}`,
3095
+ className
3096
+ ].filter(Boolean).join(" ");
3097
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("table", { className: classes, ...props, children });
3098
+ };
3099
+ var TableHead = ({
3100
+ className = "",
3101
+ children,
3102
+ ...props
3103
+ }) => {
3104
+ const classes = ["table__head", className].filter(Boolean).join(" ");
3105
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("thead", { className: classes, ...props, children });
3106
+ };
3107
+ var TableBody = ({
3108
+ className = "",
3109
+ children,
3110
+ ...props
3111
+ }) => {
3112
+ const classes = ["table__body", className].filter(Boolean).join(" ");
3113
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("tbody", { className: classes, ...props, children });
3114
+ };
3115
+ var TableRow = ({
3116
+ className = "",
3117
+ children,
3118
+ ...props
3119
+ }) => {
3120
+ const classes = ["table__row", className].filter(Boolean).join(" ");
3121
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("tr", { className: classes, ...props, children });
3122
+ };
3123
+ var TableCell = ({
3124
+ header = false,
3125
+ className = "",
3126
+ children,
3127
+ ...props
3128
+ }) => {
3129
+ const classes = [
3130
+ header ? "table__cell--header" : "table__cell",
3131
+ className
3132
+ ].filter(Boolean).join(" ");
3133
+ if (header) {
3134
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("th", { className: classes, ...props, children });
3135
+ }
3136
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("td", { className: classes, ...props, children });
3137
+ };
3138
+ var TableContainer = ({
3139
+ className = "",
3140
+ children,
3141
+ ...props
3142
+ }) => {
3143
+ const classes = ["table-container", className].filter(Boolean).join(" ");
3144
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: classes, ...props, children });
3145
+ };
3146
+
3147
+ // src/components/page-index/PageIndex.tsx
3148
+ var React31 = __toESM(require("react"));
3149
+ var import_jsx_runtime46 = require("react/jsx-runtime");
3150
+ var PageIndex = ({
3151
+ title = "On this page",
3152
+ collapsed = false,
3153
+ className = "",
3154
+ ...props
3155
+ }) => {
3156
+ const [items, setItems] = React31.useState([]);
3157
+ const [activeId, setActiveId] = React31.useState("");
3158
+ const [manualNavigation, setManualNavigation] = React31.useState(false);
3159
+ const getTextContent = React31.useCallback((element) => {
3160
+ if (element.tagName.match(/^H[1-6]$/)) {
3161
+ return element.textContent || "";
3162
+ }
3163
+ return element.getAttribute("data-page-index-title") || element.getAttribute("title") || element.textContent || "";
3164
+ }, []);
3165
+ const generateId = React31.useCallback((text) => {
3166
+ return text.toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").trim();
3167
+ }, []);
3168
+ const scanPage = React31.useCallback(() => {
3169
+ const newItems = [];
3170
+ const seenIds = /* @__PURE__ */ new Set();
3171
+ const pages = document.querySelectorAll("main");
3172
+ pages.forEach((page) => {
3173
+ const pageElement = page;
3174
+ if (pageElement.closest(".page-index")) {
3175
+ return;
3176
+ }
3177
+ const sections = pageElement.querySelectorAll("section");
3178
+ sections.forEach((section) => {
3179
+ const sectionElement = section;
3180
+ if (sectionElement.closest(".page-index")) {
3181
+ return;
3182
+ }
3183
+ const childElements = Array.from(sectionElement.children);
3184
+ const headings = childElements.filter(
3185
+ (child) => child.tagName.match(/^H[1-6]$/)
3186
+ );
3187
+ headings.forEach((element) => {
3188
+ const text = getTextContent(element);
3189
+ if (text.trim()) {
3190
+ if (element.closest('.component-preview, [data-demo], .demo, .example, .drawer, [role="dialog"]')) {
3191
+ return;
3192
+ }
3193
+ const id = element.id || generateId(text);
3194
+ if (seenIds.has(id)) {
3195
+ return;
3196
+ }
3197
+ seenIds.add(id);
3198
+ if (!element.id) {
3199
+ element.id = id;
3200
+ }
3201
+ const tagName = element.tagName.toLowerCase();
3202
+ const level = parseInt(tagName.substring(1));
3203
+ newItems.push({
3204
+ id,
3205
+ title: text.trim(),
3206
+ level,
3207
+ element
3208
+ });
3209
+ }
3210
+ });
3211
+ });
3212
+ });
3213
+ newItems.sort((a, b) => {
3214
+ const aRect = a.element.getBoundingClientRect();
3215
+ const bRect = b.element.getBoundingClientRect();
3216
+ return aRect.top - bRect.top;
3217
+ });
3218
+ setItems(newItems);
3219
+ }, [getTextContent, generateId]);
3220
+ React31.useEffect(() => {
3221
+ const observer = new IntersectionObserver(
3222
+ (entries) => {
3223
+ if (manualNavigation) return;
3224
+ entries.forEach((entry) => {
3225
+ if (entry.isIntersecting) {
3226
+ setActiveId(entry.target.id);
3227
+ }
3228
+ });
3229
+ },
3230
+ {
3231
+ rootMargin: "-80px 0px -80% 0px",
3232
+ threshold: 0
3233
+ }
3234
+ );
3235
+ items.forEach((item) => {
3236
+ observer.observe(item.element);
3237
+ });
3238
+ return () => {
3239
+ items.forEach((item) => {
3240
+ observer.unobserve(item.element);
3241
+ });
3242
+ };
3243
+ }, [items, manualNavigation]);
3244
+ React31.useEffect(() => {
3245
+ const timer = setTimeout(() => {
3246
+ scanPage();
3247
+ }, 100);
3248
+ const handleLocationChange = () => {
3249
+ setTimeout(() => {
3250
+ scanPage();
3251
+ }, 150);
3252
+ };
3253
+ window.addEventListener("popstate", handleLocationChange);
3254
+ window.addEventListener("locationchange", handleLocationChange);
3255
+ const observer = new MutationObserver(() => {
3256
+ clearTimeout(timer);
3257
+ setTimeout(() => {
3258
+ scanPage();
3259
+ }, 200);
3260
+ });
3261
+ const mainContent = document.querySelector("main") || document.body;
3262
+ observer.observe(mainContent, {
3263
+ childList: true,
3264
+ subtree: true,
3265
+ attributes: true,
3266
+ attributeFilter: ["data-section-title", "id"]
3267
+ });
3268
+ return () => {
3269
+ clearTimeout(timer);
3270
+ window.removeEventListener("popstate", handleLocationChange);
3271
+ window.removeEventListener("locationchange", handleLocationChange);
3272
+ observer.disconnect();
3273
+ };
3274
+ }, [scanPage]);
3275
+ const handleItemClick = React31.useCallback((id) => {
3276
+ const element = document.getElementById(id);
3277
+ if (element) {
3278
+ setManualNavigation(true);
3279
+ setActiveId(id);
3280
+ element.scrollIntoView({
3281
+ behavior: "smooth",
3282
+ block: "start"
3283
+ });
3284
+ setTimeout(() => {
3285
+ setManualNavigation(false);
3286
+ }, 1e3);
3287
+ }
3288
+ }, []);
3289
+ const classes = [
3290
+ "page-index",
3291
+ collapsed && "page-index--collapsed",
3292
+ className
3293
+ ].filter(Boolean).join(" ");
3294
+ if (items.length === 0) {
3295
+ return null;
3296
+ }
3297
+ const { sidebarWidth, setSidebarWidth, ...domProps } = props;
3298
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: classes, ...domProps, children: [
3299
+ !collapsed && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("h3", { className: "page-index__title", children: title }),
3300
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("nav", { className: "page-index__nav", "aria-label": "Page contents", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("ul", { className: "page-index__list", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3301
+ "li",
3302
+ {
3303
+ className: `page-index__item page-index__item--level-${item.level}`,
3304
+ children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3305
+ "button",
3306
+ {
3307
+ className: `page-index__link ${activeId === item.id ? "page-index__link--active" : ""}`,
3308
+ onClick: () => handleItemClick(item.id),
3309
+ "aria-current": activeId === item.id ? "location" : void 0,
3310
+ children: collapsed ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "page-index__link-text--collapsed", children: item.title.charAt(0) }) : item.title
3311
+ }
3312
+ )
3313
+ },
3314
+ item.id
3315
+ )) }) })
3316
+ ] });
3317
+ };
3318
+ // Annotate the CommonJS export names for ESM import in node:
3319
+ 0 && (module.exports = {
3320
+ Badge,
3321
+ Banner,
3322
+ Button,
3323
+ Card,
3324
+ Checkbox,
3325
+ CodeBlock,
3326
+ ColorControl,
3327
+ DragHandle,
3328
+ Drawer,
3329
+ FloatingBar,
3330
+ Footer,
3331
+ Grid,
3332
+ Header,
3333
+ Icon,
3334
+ InputDate,
3335
+ InputDateTime,
3336
+ InputEmail,
3337
+ InputNumber,
3338
+ InputPassword,
3339
+ InputSearch,
3340
+ InputTel,
3341
+ InputText,
3342
+ InputTime,
3343
+ InputUrl,
3344
+ Layout,
3345
+ List,
3346
+ ListItem,
3347
+ MenuCategory,
3348
+ MenuGroup,
3349
+ MenuItem,
3350
+ Navbar,
3351
+ NavbarTooltipProvider,
3352
+ Page,
3353
+ PageIndex,
3354
+ Popover,
3355
+ Radio,
3356
+ RadioGroup,
3357
+ Section,
3358
+ Select,
3359
+ Slider,
3360
+ Switch,
3361
+ Table,
3362
+ TableBody,
3363
+ TableCell,
3364
+ TableContainer,
3365
+ TableHead,
3366
+ TableRow,
3367
+ ThemeControl,
3368
+ Tooltip,
3369
+ applyTheme,
3370
+ clearPreferences,
3371
+ clearPreferencesAsync,
3372
+ configurePreferences,
3373
+ createPreferenceNamespace,
3374
+ exportPreferences,
3375
+ getAllPreferences,
3376
+ getPreference,
3377
+ getPreferenceAsync,
3378
+ getSavedTheme,
3379
+ getTheme,
3380
+ importPreferences,
3381
+ initializeTheme,
3382
+ onSystemThemeChange,
3383
+ removePreference,
3384
+ removePreferenceAsync,
3385
+ setPreference,
3386
+ setPreferenceAsync,
3387
+ setTheme,
3388
+ toggleTheme,
3389
+ useNavbarTooltip
3390
+ });
3391
+ //# sourceMappingURL=index.js.map