@matheusrizzati/ui 0.1.1 → 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.
package/dist/index.js CHANGED
@@ -1,23 +1,96 @@
1
1
  import { clsx } from 'clsx';
2
2
  import { twMerge } from 'tailwind-merge';
3
- import { forwardRef, createContext, useState, useCallback, useContext } from 'react';
3
+ import React26, { createContext, forwardRef, useRef, useEffect, useState, useMemo, useCallback, useContext } from 'react';
4
4
  import { cva } from 'class-variance-authority';
5
- import { jsxs, jsx } from 'react/jsx-runtime';
6
- import * as Dialog from '@radix-ui/react-dialog';
5
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
6
+ import * as PopoverPrimitive3 from '@radix-ui/react-popover';
7
+ import * as TooltipPrimitive from '@radix-ui/react-tooltip';
8
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
7
9
  import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
10
+ import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
8
11
 
9
12
  // src/utils/cn.ts
10
13
  function cn(...inputs) {
11
14
  return twMerge(clsx(inputs));
12
15
  }
16
+ var ThemeContext = createContext(void 0);
17
+ function getSystemTheme() {
18
+ if (typeof window === "undefined") return "dark";
19
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
20
+ }
21
+ function ThemeProvider({
22
+ children,
23
+ defaultTheme = "system",
24
+ storageKey = "rizhel-theme",
25
+ forcedTheme
26
+ }) {
27
+ const [theme, setThemeState] = useState(() => {
28
+ if (forcedTheme) return forcedTheme;
29
+ if (typeof window === "undefined") return defaultTheme;
30
+ try {
31
+ const stored = localStorage.getItem(storageKey);
32
+ if (stored === "light" || stored === "dark" || stored === "system") {
33
+ return stored;
34
+ }
35
+ } catch {
36
+ }
37
+ return defaultTheme;
38
+ });
39
+ const resolvedTheme = useMemo(() => {
40
+ if (forcedTheme) return forcedTheme;
41
+ if (theme === "system") return getSystemTheme();
42
+ return theme;
43
+ }, [theme, forcedTheme]);
44
+ const setTheme = useCallback(
45
+ (newTheme) => {
46
+ if (forcedTheme) return;
47
+ setThemeState(newTheme);
48
+ try {
49
+ localStorage.setItem(storageKey, newTheme);
50
+ } catch {
51
+ }
52
+ },
53
+ [forcedTheme, storageKey]
54
+ );
55
+ const toggleTheme = useCallback(() => {
56
+ setTheme(resolvedTheme === "dark" ? "light" : "dark");
57
+ }, [resolvedTheme, setTheme]);
58
+ useEffect(() => {
59
+ const root = document.documentElement;
60
+ if (resolvedTheme === "dark") {
61
+ root.classList.add("dark");
62
+ } else {
63
+ root.classList.remove("dark");
64
+ }
65
+ }, [resolvedTheme]);
66
+ useEffect(() => {
67
+ if (theme !== "system") return;
68
+ const mql = window.matchMedia("(prefers-color-scheme: dark)");
69
+ const handler = () => setThemeState("system");
70
+ mql.addEventListener("change", handler);
71
+ return () => mql.removeEventListener("change", handler);
72
+ }, [theme]);
73
+ const value = useMemo(
74
+ () => ({ theme, resolvedTheme, setTheme, toggleTheme }),
75
+ [theme, resolvedTheme, setTheme, toggleTheme]
76
+ );
77
+ return React26.createElement(ThemeContext.Provider, { value }, children);
78
+ }
79
+ function useTheme() {
80
+ const context = useContext(ThemeContext);
81
+ if (!context) {
82
+ throw new Error("useTheme must be used within a <ThemeProvider>");
83
+ }
84
+ return context;
85
+ }
13
86
  var buttonVariants = cva(
14
87
  [
15
88
  "inline-flex items-center justify-center gap-2",
16
89
  "font-medium whitespace-nowrap select-none",
17
90
  "transition-all duration-[var(--transition-fast)]",
18
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring-color)] focus-visible:ring-offset-[var(--ring-offset)]",
91
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring-color)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--color-bg)]",
19
92
  "disabled:pointer-events-none disabled:opacity-50",
20
- "active:scale-[0.97]",
93
+ "active:scale-[0.98]",
21
94
  "cursor-pointer"
22
95
  ],
23
96
  {
@@ -26,28 +99,29 @@ var buttonVariants = cva(
26
99
  primary: [
27
100
  "bg-[var(--color-primary)] text-[var(--color-primary-foreground)]",
28
101
  "hover:bg-[var(--color-primary-hover)]",
29
- "shadow-[var(--shadow-sm)]"
102
+ "shadow-[0_1px_2px_0_rgba(0,0,0,0.4),0_0_0_1px_rgba(255,255,255,0.1)_inset]",
103
+ "hover:shadow-[0_0_20px_-5px_var(--color-primary-500),0_0_0_1px_rgba(255,255,255,0.1)_inset]",
104
+ "transition-all duration-300"
30
105
  ],
31
106
  secondary: [
32
107
  "bg-[var(--color-surface)] text-[var(--color-text-primary)]",
33
- "border border-[var(--color-border)]",
34
- "hover:bg-[var(--color-surface-hover)] hover:border-[var(--color-border-hover)]"
108
+ "border border-[var(--color-slate-700)] shadow-sm",
109
+ "hover:bg-[var(--color-slate-800)] hover:border-[var(--color-slate-600)]"
35
110
  ],
36
111
  ghost: [
37
112
  "text-[var(--color-text-secondary)]",
38
- "hover:bg-[var(--color-surface)] hover:text-[var(--color-text-primary)]"
113
+ "hover:bg-[var(--color-slate-800)/50] hover:text-[var(--color-text-primary)]"
39
114
  ],
40
115
  danger: [
41
- "bg-[var(--color-danger)] text-white",
42
- "hover:brightness-110",
43
- "shadow-[var(--shadow-sm)]"
116
+ "bg-[var(--color-danger)] text-white shadow-sm",
117
+ "hover:brightness-110 hover:shadow-[0_0_15px_-3px_var(--color-danger)]"
44
118
  ]
45
119
  },
46
120
  size: {
47
121
  sm: "h-8 px-3 text-[var(--text-xs)] rounded-[var(--radius-sm)]",
48
- md: "h-9 px-4 text-[var(--text-sm)] rounded-[var(--radius)]",
49
- lg: "h-11 px-6 text-[var(--text-base)] rounded-[var(--radius-md)]",
50
- icon: "h-9 w-9 rounded-[var(--radius)]"
122
+ md: "h-10 px-4 text-[var(--text-sm)] rounded-[var(--radius)]",
123
+ lg: "h-12 px-6 text-[var(--text-base)] rounded-[var(--radius-md)]",
124
+ icon: "h-10 w-10 rounded-[var(--radius)]"
51
125
  }
52
126
  },
53
127
  defaultVariants: {
@@ -107,11 +181,11 @@ Button.displayName = "Button";
107
181
  var inputVariants = cva(
108
182
  [
109
183
  "w-full bg-[var(--color-surface)] text-[var(--color-text-primary)]",
110
- "border border-[var(--color-border)]",
184
+ "border border-[var(--color-slate-700)] shadow-sm",
111
185
  "placeholder:text-[var(--color-text-muted)]",
112
186
  "transition-all duration-[var(--transition-fast)]",
113
- "focus:outline-none focus:ring-2 focus:ring-[var(--ring-color)] focus:border-[var(--color-primary)]",
114
- "hover:border-[var(--color-border-hover)]",
187
+ "focus:outline-none focus:border-[var(--color-primary)] focus:ring-1 focus:ring-[var(--color-primary)] focus:shadow-[0_0_0_1px_var(--color-primary),0_0_15px_-3px_var(--color-primary-500)]",
188
+ "hover:border-[var(--color-slate-600)]",
115
189
  "disabled:opacity-50 disabled:cursor-not-allowed",
116
190
  "font-[var(--font-sans)]"
117
191
  ],
@@ -119,12 +193,12 @@ var inputVariants = cva(
119
193
  variants: {
120
194
  inputSize: {
121
195
  sm: "h-8 px-3 text-[var(--text-xs)] rounded-[var(--radius-sm)]",
122
- md: "h-9 px-3 text-[var(--text-sm)] rounded-[var(--radius)]",
123
- lg: "h-11 px-4 text-[var(--text-base)] rounded-[var(--radius-md)]"
196
+ md: "h-10 px-3 text-[var(--text-sm)] rounded-[var(--radius)]",
197
+ lg: "h-12 px-4 text-[var(--text-base)] rounded-[var(--radius-md)]"
124
198
  },
125
199
  state: {
126
200
  default: "",
127
- error: "border-[var(--color-danger)] focus:ring-[var(--color-danger)]/30"
201
+ error: "border-[var(--color-danger)] focus:ring-[var(--color-danger)] focus:shadow-[0_0_0_1px_var(--color-danger),0_0_15px_-3px_var(--color-danger)]"
128
202
  }
129
203
  },
130
204
  defaultVariants: {
@@ -146,6 +220,7 @@ var Input = forwardRef(
146
220
  error,
147
221
  startIcon,
148
222
  endIcon,
223
+ onClear,
149
224
  id,
150
225
  ...props
151
226
  }, ref) => {
@@ -163,13 +238,25 @@ var Input = forwardRef(
163
238
  className: cn(
164
239
  inputVariants({ inputSize, state: effectiveState }),
165
240
  startIcon && "pl-9",
166
- endIcon && "pr-9",
241
+ (endIcon || onClear) && "pr-9",
167
242
  className
168
243
  ),
169
244
  ...props
170
245
  }
171
246
  ),
172
- endIcon && /* @__PURE__ */ jsx("div", { className: "absolute right-3 top-1/2 -translate-y-1/2 text-[var(--color-text-muted)]", children: endIcon })
247
+ onClear && props.value ? /* @__PURE__ */ jsx(
248
+ "button",
249
+ {
250
+ type: "button",
251
+ tabIndex: -1,
252
+ onClick: onClear,
253
+ className: "absolute right-3 top-1/2 -translate-y-1/2 text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] transition-colors cursor-pointer p-0.5 rounded-[var(--radius-sm)]",
254
+ children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
255
+ /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
256
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
257
+ ] })
258
+ }
259
+ ) : endIcon ? /* @__PURE__ */ jsx("div", { className: "absolute right-3 top-1/2 -translate-y-1/2 text-[var(--color-text-muted)]", children: endIcon }) : null
173
260
  ] }),
174
261
  error && /* @__PURE__ */ jsx("p", { className: errorStyles, children: error }),
175
262
  !error && helperText && /* @__PURE__ */ jsx("p", { className: helperStyles, children: helperText })
@@ -177,159 +264,1181 @@ var Input = forwardRef(
177
264
  }
178
265
  );
179
266
  Input.displayName = "Input";
180
- var cardVariants = cva(
267
+ var textareaVariants = cva(
181
268
  [
182
- "rounded-[var(--radius-lg)]",
183
- "transition-all duration-[var(--transition-base)]"
269
+ "w-full bg-[var(--color-surface)] text-[var(--color-text-primary)]",
270
+ "border border-[var(--color-border)]",
271
+ "placeholder:text-[var(--color-text-muted)]",
272
+ "transition-all duration-[var(--transition-fast)]",
273
+ "focus:outline-none focus:border-[var(--color-primary)] focus:ring-1 focus:ring-[var(--color-primary)]",
274
+ "hover:border-[var(--color-border-hover)]",
275
+ "disabled:opacity-50 disabled:cursor-not-allowed",
276
+ "font-[var(--font-sans)]",
277
+ "resize-y min-h-[80px]"
184
278
  ],
185
279
  {
186
280
  variants: {
187
- variant: {
188
- elevated: [
189
- "bg-[var(--color-surface)] border border-[var(--color-border)]",
190
- "shadow-[var(--shadow-md)]"
191
- ],
192
- outlined: [
193
- "bg-transparent border border-[var(--color-border)]"
194
- ],
195
- ghost: [
196
- "bg-[var(--color-surface)]/50"
197
- ]
281
+ inputSize: {
282
+ sm: "px-3 py-2 text-[var(--text-xs)] rounded-[var(--radius-sm)]",
283
+ md: "px-3 py-2.5 text-[var(--text-sm)] rounded-[var(--radius)]",
284
+ lg: "px-4 py-3 text-[var(--text-base)] rounded-[var(--radius-md)]"
198
285
  },
199
- hoverable: {
200
- true: "hover:border-[var(--color-border-hover)] hover:shadow-[var(--shadow-lg)] cursor-pointer",
201
- false: ""
286
+ state: {
287
+ default: "",
288
+ error: "border-[var(--color-danger)] focus:ring-[var(--color-danger)]"
202
289
  }
203
290
  },
204
291
  defaultVariants: {
205
- variant: "elevated",
206
- hoverable: false
292
+ inputSize: "md",
293
+ state: "default"
207
294
  }
208
295
  }
209
296
  );
210
- var cardHeaderStyles = "px-[var(--space-lg)] pt-[var(--space-lg)] pb-[var(--space-sm)]";
211
- var cardBodyStyles = "px-[var(--space-lg)] py-[var(--space-md)]";
212
- var cardFooterStyles = "px-[var(--space-lg)] pt-[var(--space-sm)] pb-[var(--space-lg)] border-t border-[var(--color-border)]";
213
- var Card = forwardRef(
214
- ({ className, variant, hoverable, ...props }, ref) => /* @__PURE__ */ jsx(
215
- "div",
216
- {
217
- ref,
218
- className: cn(cardVariants({ variant, hoverable }), className),
219
- ...props
220
- }
221
- )
297
+ var labelStyles2 = "block text-[var(--text-sm)] font-medium text-[var(--color-text-secondary)] mb-1.5";
298
+ var helperStyles2 = "mt-1.5 text-[var(--text-xs)] text-[var(--color-text-muted)]";
299
+ var errorStyles2 = "mt-1.5 text-[var(--text-xs)] text-[var(--color-danger)]";
300
+ var counterStyles = "mt-1.5 text-[var(--text-xs)] text-[var(--color-text-muted)] text-right";
301
+ var Textarea = forwardRef(
302
+ ({
303
+ className,
304
+ inputSize,
305
+ state,
306
+ label,
307
+ helperText,
308
+ error,
309
+ autoResize,
310
+ showCount,
311
+ maxLength,
312
+ id,
313
+ value,
314
+ defaultValue,
315
+ onChange,
316
+ ...props
317
+ }, ref) => {
318
+ const inputId = id || (label ? label.toLowerCase().replace(/\s+/g, "-") : void 0);
319
+ const effectiveState = error ? "error" : state;
320
+ const internalRef = useRef(null);
321
+ const textareaRef = ref || internalRef;
322
+ useEffect(() => {
323
+ if (autoResize && textareaRef.current) {
324
+ const el = textareaRef.current;
325
+ el.style.height = "auto";
326
+ el.style.height = el.scrollHeight + "px";
327
+ }
328
+ }, [autoResize, value, defaultValue, textareaRef]);
329
+ const handleChange = (e) => {
330
+ if (autoResize) {
331
+ e.target.style.height = "auto";
332
+ e.target.style.height = e.target.scrollHeight + "px";
333
+ }
334
+ onChange?.(e);
335
+ };
336
+ const currentLength = typeof value === "string" ? value.length : 0;
337
+ return /* @__PURE__ */ jsxs("div", { className: "w-full", children: [
338
+ label && /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: labelStyles2, children: label }),
339
+ /* @__PURE__ */ jsx(
340
+ "textarea",
341
+ {
342
+ ref: textareaRef,
343
+ id: inputId,
344
+ className: cn(
345
+ textareaVariants({ inputSize, state: effectiveState }),
346
+ autoResize && "resize-none overflow-hidden",
347
+ className
348
+ ),
349
+ value,
350
+ defaultValue,
351
+ maxLength,
352
+ onChange: handleChange,
353
+ rows: props.rows || 3,
354
+ ...props
355
+ }
356
+ ),
357
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between", children: [
358
+ /* @__PURE__ */ jsxs("div", { children: [
359
+ error && /* @__PURE__ */ jsx("p", { className: errorStyles2, children: error }),
360
+ !error && helperText && /* @__PURE__ */ jsx("p", { className: helperStyles2, children: helperText })
361
+ ] }),
362
+ showCount && maxLength && /* @__PURE__ */ jsxs("p", { className: counterStyles, children: [
363
+ currentLength,
364
+ "/",
365
+ maxLength
366
+ ] })
367
+ ] })
368
+ ] });
369
+ }
222
370
  );
223
- Card.displayName = "Card";
224
- var CardHeader = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn(cardHeaderStyles, className), ...props }));
225
- CardHeader.displayName = "CardHeader";
226
- var CardBody = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn(cardBodyStyles, className), ...props }));
227
- CardBody.displayName = "CardBody";
228
- var CardFooter = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn(cardFooterStyles, className), ...props }));
229
- CardFooter.displayName = "CardFooter";
371
+ Textarea.displayName = "Textarea";
230
372
 
231
- // src/components/modal/modal.styles.ts
232
- var modalOverlayStyles = [
233
- "fixed inset-0 z-50 bg-black/60 backdrop-blur-sm",
234
- "data-[state=open]:animate-in data-[state=open]:fade-in-0",
235
- "data-[state=closed]:animate-out data-[state=closed]:fade-out-0"
373
+ // src/components/select/select.styles.ts
374
+ var selectTriggerStyles = [
375
+ "flex items-center justify-between w-full",
376
+ "bg-[var(--color-surface)] text-[var(--color-text-primary)]",
377
+ "border border-[var(--color-border)]",
378
+ "transition-all duration-[var(--transition-fast)]",
379
+ "focus:outline-none focus:border-[var(--color-primary)] focus:ring-1 focus:ring-[var(--color-primary)]",
380
+ "hover:border-[var(--color-border-hover)]",
381
+ "disabled:opacity-50 disabled:cursor-not-allowed",
382
+ "font-[var(--font-sans)] cursor-pointer"
236
383
  ].join(" ");
237
- var modalContentStyles = [
238
- "fixed left-1/2 top-1/2 z-50 -translate-x-1/2 -translate-y-1/2",
239
- "w-full max-w-lg",
240
- "bg-[var(--color-surface)] border border-[var(--color-border)]",
241
- "rounded-[var(--radius-xl)] shadow-[var(--shadow-lg)]",
242
- "p-[var(--space-lg)]",
243
- "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
244
- "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]",
245
- "duration-200"
384
+ var selectTriggerSizes = {
385
+ sm: "h-8 px-3 text-[var(--text-xs)] rounded-[var(--radius-sm)] gap-2",
386
+ md: "h-10 px-3 text-[var(--text-sm)] rounded-[var(--radius)] gap-2",
387
+ lg: "h-12 px-4 text-[var(--text-base)] rounded-[var(--radius-md)] gap-3"
388
+ };
389
+ var selectContentStyles = [
390
+ "z-[var(--z-popover)]",
391
+ "w-[var(--radix-popover-trigger-width)] overflow-hidden",
392
+ "rounded-[var(--radius-md)]",
393
+ "bg-[var(--color-surface)] text-[var(--color-text-primary)]",
394
+ "border border-[var(--color-border)]",
395
+ "shadow-lg",
396
+ "animate-in fade-in-0 zoom-in-[0.98]",
397
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-[0.98]"
246
398
  ].join(" ");
247
- var modalTitleStyles = "text-[var(--text-lg)] font-semibold text-[var(--color-text-primary)]";
248
- var modalDescriptionStyles = "text-[var(--text-sm)] text-[var(--color-text-secondary)] mt-2";
249
- var modalCloseStyles = [
250
- "absolute right-4 top-4",
251
- "rounded-[var(--radius-sm)] p-1",
252
- "text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)]",
253
- "hover:bg-[var(--color-surface-hover)]",
399
+ var selectSearchStyles = [
400
+ "w-full bg-transparent text-[var(--color-text-primary)]",
401
+ "text-[var(--text-sm)] px-3 py-2.5",
402
+ "placeholder:text-[var(--color-text-muted)]",
403
+ "border-b border-[var(--color-border)]",
404
+ "focus:outline-none",
405
+ "font-[var(--font-sans)]"
406
+ ].join(" ");
407
+ var selectItemStyles = [
408
+ "relative flex items-center gap-2 w-full",
409
+ "px-3 py-2 cursor-pointer select-none",
410
+ "text-[var(--text-sm)] text-[var(--color-text-secondary)]",
411
+ "rounded-[var(--radius-sm)]",
254
412
  "transition-colors duration-[var(--transition-fast)]",
255
- "focus:outline-none focus:ring-2 focus:ring-[var(--ring-color)]"
413
+ "hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)]",
414
+ "outline-none"
256
415
  ].join(" ");
257
- var Modal = Dialog.Root;
258
- var ModalTrigger = Dialog.Trigger;
259
- var ModalOverlay = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(Dialog.Overlay, { ref, className: cn(modalOverlayStyles, className), ...props }));
260
- ModalOverlay.displayName = "ModalOverlay";
261
- var ModalContent = forwardRef(({ className, children, showClose = true, ...props }, ref) => /* @__PURE__ */ jsxs(Dialog.Portal, { children: [
262
- /* @__PURE__ */ jsx(ModalOverlay, {}),
263
- /* @__PURE__ */ jsxs(Dialog.Content, { ref, className: cn(modalContentStyles, className), ...props, children: [
264
- children,
265
- showClose && /* @__PURE__ */ jsxs(Dialog.Close, { className: modalCloseStyles, children: [
266
- /* @__PURE__ */ jsxs(
267
- "svg",
416
+ var selectItemActiveStyles = "bg-[var(--color-surface-hover)] text-[var(--color-text-primary)]";
417
+ var selectItemSelectedStyles = "text-[var(--color-primary-400)] font-medium";
418
+ var selectGroupLabelStyles = [
419
+ "px-3 py-1.5",
420
+ "text-[var(--text-xs)] font-semibold uppercase tracking-wider",
421
+ "text-[var(--color-text-muted)]"
422
+ ].join(" ");
423
+ var selectPlaceholderStyles = "text-[var(--color-text-muted)]";
424
+ var selectClearStyles = [
425
+ "shrink-0 p-0.5 rounded-[var(--radius-sm)]",
426
+ "text-[var(--color-text-muted)]",
427
+ "hover:text-[var(--color-text-primary)] hover:bg-[var(--color-surface-hover)]",
428
+ "transition-colors duration-[var(--transition-fast)]"
429
+ ].join(" ");
430
+ var selectLabelStyles = "block text-[var(--text-sm)] font-medium text-[var(--color-text-secondary)] mb-1.5";
431
+ var selectHelperStyles = "mt-1.5 text-[var(--text-xs)] text-[var(--color-text-muted)]";
432
+ var selectErrorStyles = "mt-1.5 text-[var(--text-xs)] text-[var(--color-danger)]";
433
+ var selectErrorTriggerStyles = "border-[var(--color-danger)] focus:ring-[var(--color-danger)]";
434
+ var Select = forwardRef(
435
+ ({
436
+ options = [],
437
+ groups,
438
+ value,
439
+ onChange,
440
+ placeholder = "Select an option...",
441
+ label,
442
+ helperText,
443
+ error,
444
+ emptyMessage = "No results found.",
445
+ searchable = false,
446
+ searchPlaceholder = "Search...",
447
+ clearable = false,
448
+ size = "md",
449
+ disabled,
450
+ className,
451
+ renderOption
452
+ }, ref) => {
453
+ const [open, setOpen] = useState(false);
454
+ const [search, setSearch] = useState("");
455
+ const [activeIndex, setActiveIndex] = useState(-1);
456
+ const searchRef = useRef(null);
457
+ const listRef = useRef(null);
458
+ const allOptions = useMemo(() => {
459
+ if (groups) {
460
+ return groups.flatMap((g) => g.options);
461
+ }
462
+ return options;
463
+ }, [groups, options]);
464
+ const filterOptions = useCallback(
465
+ (opts) => search ? opts.filter(
466
+ (o) => o.label.toLowerCase().includes(search.toLowerCase())
467
+ ) : opts,
468
+ [search]
469
+ );
470
+ const filteredAll = useMemo(() => filterOptions(allOptions), [filterOptions, allOptions]);
471
+ const filteredGroups = useMemo(() => {
472
+ if (!groups) return null;
473
+ return groups.map((g) => ({
474
+ ...g,
475
+ options: filterOptions(g.options)
476
+ })).filter((g) => g.options.length > 0);
477
+ }, [groups, filterOptions]);
478
+ const selectedOption = allOptions.find((o) => o.value === value);
479
+ const handleSelect = useCallback(
480
+ (optValue) => {
481
+ onChange?.(optValue);
482
+ setOpen(false);
483
+ setSearch("");
484
+ },
485
+ [onChange]
486
+ );
487
+ const handleClear = useCallback(
488
+ (e) => {
489
+ e.stopPropagation();
490
+ onChange?.("");
491
+ setSearch("");
492
+ },
493
+ [onChange]
494
+ );
495
+ const handleKeyDown = (e) => {
496
+ const items = filteredAll.filter((o) => !o.disabled);
497
+ if (e.key === "ArrowDown") {
498
+ e.preventDefault();
499
+ if (!open) {
500
+ setOpen(true);
501
+ return;
502
+ }
503
+ setActiveIndex((i) => Math.min(i + 1, items.length - 1));
504
+ } else if (e.key === "ArrowUp") {
505
+ e.preventDefault();
506
+ setActiveIndex((i) => Math.max(i - 1, 0));
507
+ } else if (e.key === "Enter" && activeIndex >= 0) {
508
+ e.preventDefault();
509
+ const opt = items[activeIndex];
510
+ if (opt) handleSelect(opt.value);
511
+ } else if (e.key === "Escape") {
512
+ setOpen(false);
513
+ }
514
+ };
515
+ useEffect(() => {
516
+ setActiveIndex(-1);
517
+ }, [search]);
518
+ useEffect(() => {
519
+ if (open && searchable) {
520
+ const timer = setTimeout(() => searchRef.current?.focus(), 50);
521
+ return () => clearTimeout(timer);
522
+ }
523
+ }, [open, searchable]);
524
+ const renderItem = (opt, flatIndex2) => {
525
+ const isSelected = opt.value === value;
526
+ return /* @__PURE__ */ jsx(
527
+ "div",
268
528
  {
269
- xmlns: "http://www.w3.org/2000/svg",
270
- width: "16",
271
- height: "16",
272
- viewBox: "0 0 24 24",
273
- fill: "none",
274
- stroke: "currentColor",
275
- strokeWidth: "2",
276
- strokeLinecap: "round",
277
- strokeLinejoin: "round",
278
- children: [
279
- /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
280
- /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
281
- ]
529
+ role: "option",
530
+ "aria-selected": isSelected,
531
+ "aria-disabled": opt.disabled,
532
+ className: cn(
533
+ selectItemStyles,
534
+ flatIndex2 === activeIndex && selectItemActiveStyles,
535
+ isSelected && selectItemSelectedStyles,
536
+ opt.disabled && "opacity-50 pointer-events-none"
537
+ ),
538
+ onClick: () => !opt.disabled && handleSelect(opt.value),
539
+ onMouseEnter: () => setActiveIndex(flatIndex2),
540
+ children: renderOption ? renderOption(opt, isSelected) : /* @__PURE__ */ jsxs(Fragment, { children: [
541
+ opt.icon && /* @__PURE__ */ jsx("span", { className: "shrink-0 w-5 h-5 flex items-center justify-center", children: opt.icon }),
542
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
543
+ /* @__PURE__ */ jsx("span", { className: "block truncate", children: opt.label }),
544
+ opt.description && /* @__PURE__ */ jsx("span", { className: "block text-[var(--text-xs)] text-[var(--color-text-muted)] truncate", children: opt.description })
545
+ ] }),
546
+ isSelected && /* @__PURE__ */ jsx(
547
+ "svg",
548
+ {
549
+ className: "ml-auto shrink-0 text-[var(--color-primary)]",
550
+ width: "16",
551
+ height: "16",
552
+ viewBox: "0 0 24 24",
553
+ fill: "none",
554
+ stroke: "currentColor",
555
+ strokeWidth: "2",
556
+ strokeLinecap: "round",
557
+ strokeLinejoin: "round",
558
+ children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" })
559
+ }
560
+ )
561
+ ] })
562
+ },
563
+ opt.value
564
+ );
565
+ };
566
+ let flatIndex = 0;
567
+ return /* @__PURE__ */ jsxs("div", { className: cn("w-full", className), children: [
568
+ label && /* @__PURE__ */ jsx("label", { className: selectLabelStyles, children: label }),
569
+ /* @__PURE__ */ jsxs(PopoverPrimitive3.Root, { open, onOpenChange: setOpen, children: [
570
+ /* @__PURE__ */ jsx(PopoverPrimitive3.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
571
+ "button",
572
+ {
573
+ ref,
574
+ type: "button",
575
+ role: "combobox",
576
+ "aria-expanded": open,
577
+ disabled,
578
+ onKeyDown: !searchable ? handleKeyDown : void 0,
579
+ className: cn(
580
+ selectTriggerStyles,
581
+ selectTriggerSizes[size],
582
+ error && selectErrorTriggerStyles
583
+ ),
584
+ children: [
585
+ selectedOption ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2 min-w-0 truncate", children: [
586
+ selectedOption.icon && /* @__PURE__ */ jsx("span", { className: "shrink-0 w-5 h-5 flex items-center justify-center", children: selectedOption.icon }),
587
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: selectedOption.label })
588
+ ] }) : /* @__PURE__ */ jsx("span", { className: selectPlaceholderStyles, children: placeholder }),
589
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 shrink-0", children: [
590
+ clearable && value && /* @__PURE__ */ jsx(
591
+ "span",
592
+ {
593
+ role: "button",
594
+ tabIndex: -1,
595
+ onClick: handleClear,
596
+ className: selectClearStyles,
597
+ children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
598
+ /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
599
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
600
+ ] })
601
+ }
602
+ ),
603
+ /* @__PURE__ */ jsx(
604
+ "svg",
605
+ {
606
+ className: cn(
607
+ "shrink-0 text-[var(--color-text-muted)] transition-transform duration-200",
608
+ open && "rotate-180"
609
+ ),
610
+ width: "16",
611
+ height: "16",
612
+ viewBox: "0 0 24 24",
613
+ fill: "none",
614
+ stroke: "currentColor",
615
+ strokeWidth: "2",
616
+ strokeLinecap: "round",
617
+ strokeLinejoin: "round",
618
+ children: /* @__PURE__ */ jsx("polyline", { points: "6 9 12 15 18 9" })
619
+ }
620
+ )
621
+ ] })
622
+ ]
623
+ }
624
+ ) }),
625
+ /* @__PURE__ */ jsx(PopoverPrimitive3.Portal, { children: /* @__PURE__ */ jsxs(
626
+ PopoverPrimitive3.Content,
627
+ {
628
+ ref: listRef,
629
+ sideOffset: 4,
630
+ className: selectContentStyles,
631
+ onOpenAutoFocus: (e) => e.preventDefault(),
632
+ children: [
633
+ searchable && /* @__PURE__ */ jsx(
634
+ "input",
635
+ {
636
+ ref: searchRef,
637
+ type: "text",
638
+ placeholder: searchPlaceholder,
639
+ value: search,
640
+ onChange: (e) => setSearch(e.target.value),
641
+ onKeyDown: handleKeyDown,
642
+ className: selectSearchStyles
643
+ }
644
+ ),
645
+ /* @__PURE__ */ jsx("div", { className: "p-1 max-h-60 overflow-auto", role: "listbox", children: filteredGroups ? filteredGroups.length === 0 ? /* @__PURE__ */ jsx("div", { className: "py-6 text-center text-[var(--text-sm)] text-[var(--color-text-muted)]", children: emptyMessage }) : filteredGroups.map((group) => /* @__PURE__ */ jsxs("div", { children: [
646
+ /* @__PURE__ */ jsx("div", { className: selectGroupLabelStyles, children: group.label }),
647
+ group.options.map((opt) => {
648
+ const item = renderItem(opt, flatIndex);
649
+ flatIndex++;
650
+ return item;
651
+ })
652
+ ] }, group.label)) : filteredAll.length === 0 ? /* @__PURE__ */ jsx("div", { className: "py-6 text-center text-[var(--text-sm)] text-[var(--color-text-muted)]", children: emptyMessage }) : filteredAll.map((opt) => {
653
+ const item = renderItem(opt, flatIndex);
654
+ flatIndex++;
655
+ return item;
656
+ }) })
657
+ ]
658
+ }
659
+ ) })
660
+ ] }),
661
+ error && /* @__PURE__ */ jsx("p", { className: selectErrorStyles, children: error }),
662
+ !error && helperText && /* @__PURE__ */ jsx("p", { className: selectHelperStyles, children: helperText })
663
+ ] });
664
+ }
665
+ );
666
+ Select.displayName = "Select";
667
+
668
+ // src/components/combobox/combobox.styles.ts
669
+ var comboboxInputStyles = [
670
+ "w-full bg-[var(--color-surface)] text-[var(--color-text-primary)]",
671
+ "border border-[var(--color-border)]",
672
+ "placeholder:text-[var(--color-text-muted)]",
673
+ "transition-all duration-[var(--transition-fast)]",
674
+ "focus:outline-none focus:border-[var(--color-primary)] focus:ring-1 focus:ring-[var(--color-primary)]",
675
+ "hover:border-[var(--color-border-hover)]",
676
+ "disabled:opacity-50 disabled:cursor-not-allowed",
677
+ "font-[var(--font-sans)]",
678
+ "h-10 px-3 text-[var(--text-sm)] rounded-[var(--radius)]"
679
+ ].join(" ");
680
+ var comboboxListStyles = [
681
+ "z-[var(--z-popover)]",
682
+ "w-[var(--radix-popover-trigger-width)] max-h-60 overflow-auto",
683
+ "rounded-[var(--radius-md)] p-1",
684
+ "bg-[var(--color-surface)] text-[var(--color-text-primary)]",
685
+ "border border-[var(--color-border)]",
686
+ "shadow-lg"
687
+ ].join(" ");
688
+ var comboboxItemStyles = [
689
+ "flex items-center gap-2 w-full px-2.5 py-2",
690
+ "text-[var(--text-sm)] text-[var(--color-text-secondary)]",
691
+ "rounded-[var(--radius-sm)] cursor-pointer",
692
+ "transition-colors duration-[var(--transition-fast)]",
693
+ "hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)]",
694
+ "outline-none"
695
+ ].join(" ");
696
+ var comboboxItemActiveStyles = "bg-[var(--color-surface-hover)] text-[var(--color-text-primary)]";
697
+ var comboboxItemSelectedStyles = "text-[var(--color-primary-400)]";
698
+ var comboboxEmptyStyles = "py-6 text-center text-[var(--text-sm)] text-[var(--color-text-muted)]";
699
+ var comboboxLabelStyles = "block text-[var(--text-sm)] font-medium text-[var(--color-text-secondary)] mb-1.5";
700
+ var comboboxChipStyles = [
701
+ "inline-flex items-center gap-1 px-2 py-0.5",
702
+ "text-[var(--text-xs)] font-medium",
703
+ "bg-[var(--color-surface-raised)] text-[var(--color-text-secondary)]",
704
+ "border border-[var(--color-border)] rounded-full",
705
+ "cursor-pointer hover:border-[var(--color-border-hover)]"
706
+ ].join(" ");
707
+ var Combobox = forwardRef(
708
+ ({
709
+ options = [],
710
+ groups,
711
+ value,
712
+ onChange,
713
+ placeholder = "Search...",
714
+ label,
715
+ emptyMessage = "No results found.",
716
+ multiple = false,
717
+ creatable = false,
718
+ createLabel = (s) => `Create "${s}"`,
719
+ loading = false,
720
+ disabled,
721
+ className
722
+ }, ref) => {
723
+ const [open, setOpen] = useState(false);
724
+ const [search, setSearch] = useState("");
725
+ const [activeIndex, setActiveIndex] = useState(-1);
726
+ const listRef = useRef(null);
727
+ const allOptions = useMemo(() => {
728
+ if (groups) return groups.flatMap((g) => g.options);
729
+ return options;
730
+ }, [groups, options]);
731
+ const selectedValues = multiple ? Array.isArray(value) ? value : [] : typeof value === "string" ? [value] : [];
732
+ const filterOptions = useCallback(
733
+ (opts) => search ? opts.filter(
734
+ (o) => o.label.toLowerCase().includes(search.toLowerCase())
735
+ ) : opts,
736
+ [search]
737
+ );
738
+ const filtered = useMemo(() => filterOptions(allOptions), [filterOptions, allOptions]);
739
+ const filteredGroups = useMemo(() => {
740
+ if (!groups) return null;
741
+ return groups.map((g) => ({ ...g, options: filterOptions(g.options) })).filter((g) => g.options.length > 0);
742
+ }, [groups, filterOptions]);
743
+ const showCreate = creatable && search.trim().length > 0 && !allOptions.some((o) => o.label.toLowerCase() === search.toLowerCase());
744
+ const totalItems = filtered.filter((o) => !o.disabled).length + (showCreate ? 1 : 0);
745
+ const handleSelect = useCallback(
746
+ (optValue) => {
747
+ if (multiple) {
748
+ const current = Array.isArray(value) ? value : [];
749
+ const next = current.includes(optValue) ? current.filter((v) => v !== optValue) : [...current, optValue];
750
+ onChange?.(next);
751
+ } else {
752
+ onChange?.(optValue);
753
+ setSearch(allOptions.find((o) => o.value === optValue)?.label || optValue);
754
+ setOpen(false);
282
755
  }
283
- ),
284
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
285
- ] })
286
- ] })
287
- ] }));
288
- ModalContent.displayName = "ModalContent";
289
- var ModalTitle = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(Dialog.Title, { ref, className: cn(modalTitleStyles, className), ...props }));
290
- ModalTitle.displayName = "ModalTitle";
291
- var ModalDescription = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
292
- Dialog.Description,
756
+ },
757
+ [multiple, value, onChange, allOptions]
758
+ );
759
+ const handleCreate = useCallback(() => {
760
+ const newValue = search.trim();
761
+ if (!newValue) return;
762
+ handleSelect(newValue);
763
+ if (!multiple) setSearch(newValue);
764
+ }, [search, handleSelect, multiple]);
765
+ const handleKeyDown = (e) => {
766
+ if (e.key === "ArrowDown") {
767
+ e.preventDefault();
768
+ setActiveIndex((i) => Math.min(i + 1, totalItems - 1));
769
+ } else if (e.key === "ArrowUp") {
770
+ e.preventDefault();
771
+ setActiveIndex((i) => Math.max(i - 1, 0));
772
+ } else if (e.key === "Enter" && activeIndex >= 0) {
773
+ e.preventDefault();
774
+ const enabledItems = filtered.filter((o) => !o.disabled);
775
+ if (activeIndex < enabledItems.length) {
776
+ const opt = enabledItems[activeIndex];
777
+ if (opt) handleSelect(opt.value);
778
+ } else if (showCreate) {
779
+ handleCreate();
780
+ }
781
+ } else if (e.key === "Escape") {
782
+ setOpen(false);
783
+ }
784
+ };
785
+ useEffect(() => {
786
+ setActiveIndex(-1);
787
+ }, [search]);
788
+ const displayValue = multiple ? search : search || (typeof value === "string" ? allOptions.find((o) => o.value === value)?.label || "" : "");
789
+ let flatIndex = 0;
790
+ const renderItem = (opt, idx) => /* @__PURE__ */ jsxs(
791
+ "div",
792
+ {
793
+ role: "option",
794
+ "aria-selected": selectedValues.includes(opt.value),
795
+ "aria-disabled": opt.disabled,
796
+ className: cn(
797
+ comboboxItemStyles,
798
+ idx === activeIndex && comboboxItemActiveStyles,
799
+ selectedValues.includes(opt.value) && comboboxItemSelectedStyles,
800
+ opt.disabled && "opacity-50 pointer-events-none"
801
+ ),
802
+ onClick: () => !opt.disabled && handleSelect(opt.value),
803
+ onMouseEnter: () => setActiveIndex(idx),
804
+ children: [
805
+ multiple && /* @__PURE__ */ jsx("div", { className: cn(
806
+ "h-4 w-4 rounded-[3px] border border-[var(--color-border)] flex items-center justify-center shrink-0",
807
+ selectedValues.includes(opt.value) && "bg-[var(--color-primary)] border-[var(--color-primary)]"
808
+ ), children: selectedValues.includes(opt.value) && /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M2 5L4 7L8 3", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
809
+ opt.icon && /* @__PURE__ */ jsx("span", { className: "shrink-0 w-5 h-5 flex items-center justify-center", children: opt.icon }),
810
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: opt.label }),
811
+ !multiple && selectedValues.includes(opt.value) && /* @__PURE__ */ jsx("svg", { className: "ml-auto shrink-0", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" }) })
812
+ ]
813
+ },
814
+ opt.value
815
+ );
816
+ return /* @__PURE__ */ jsxs("div", { className: cn("w-full", className), children: [
817
+ label && /* @__PURE__ */ jsx("label", { className: comboboxLabelStyles, children: label }),
818
+ multiple && selectedValues.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5 mb-2", children: selectedValues.map((v) => {
819
+ const opt = allOptions.find((o) => o.value === v);
820
+ return /* @__PURE__ */ jsxs(
821
+ "span",
822
+ {
823
+ className: comboboxChipStyles,
824
+ onClick: () => handleSelect(v),
825
+ children: [
826
+ opt?.label || v,
827
+ /* @__PURE__ */ jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
828
+ /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
829
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
830
+ ] })
831
+ ]
832
+ },
833
+ v
834
+ );
835
+ }) }),
836
+ /* @__PURE__ */ jsxs(PopoverPrimitive3.Root, { open, onOpenChange: setOpen, children: [
837
+ /* @__PURE__ */ jsx(PopoverPrimitive3.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
838
+ "input",
839
+ {
840
+ ref,
841
+ type: "text",
842
+ role: "combobox",
843
+ "aria-expanded": open,
844
+ disabled,
845
+ placeholder,
846
+ value: displayValue,
847
+ onChange: (e) => {
848
+ setSearch(e.target.value);
849
+ if (!open) setOpen(true);
850
+ },
851
+ onFocus: () => setOpen(true),
852
+ onKeyDown: handleKeyDown,
853
+ className: comboboxInputStyles
854
+ }
855
+ ) }),
856
+ /* @__PURE__ */ jsx(PopoverPrimitive3.Portal, { children: /* @__PURE__ */ jsx(
857
+ PopoverPrimitive3.Content,
858
+ {
859
+ ref: listRef,
860
+ sideOffset: 4,
861
+ className: comboboxListStyles,
862
+ onOpenAutoFocus: (e) => e.preventDefault(),
863
+ children: loading ? /* @__PURE__ */ jsxs("div", { className: "py-6 flex items-center justify-center gap-2 text-[var(--text-sm)] text-[var(--color-text-muted)]", children: [
864
+ /* @__PURE__ */ jsxs("svg", { className: "animate-spin h-4 w-4", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
865
+ /* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
866
+ /* @__PURE__ */ jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
867
+ ] }),
868
+ "Loading..."
869
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
870
+ filteredGroups ? filteredGroups.length === 0 && !showCreate ? /* @__PURE__ */ jsx("div", { className: comboboxEmptyStyles, children: emptyMessage }) : filteredGroups.map((group) => /* @__PURE__ */ jsxs("div", { children: [
871
+ /* @__PURE__ */ jsx("div", { className: "px-2.5 py-1.5 text-[var(--text-xs)] font-semibold uppercase tracking-wider text-[var(--color-text-muted)]", children: group.label }),
872
+ group.options.map((opt) => {
873
+ const item = renderItem(opt, flatIndex);
874
+ flatIndex++;
875
+ return item;
876
+ })
877
+ ] }, group.label)) : filtered.length === 0 && !showCreate ? /* @__PURE__ */ jsx("div", { className: comboboxEmptyStyles, children: emptyMessage }) : filtered.map((opt) => {
878
+ const item = renderItem(opt, flatIndex);
879
+ flatIndex++;
880
+ return item;
881
+ }),
882
+ showCreate && /* @__PURE__ */ jsxs(
883
+ "div",
884
+ {
885
+ className: cn(
886
+ comboboxItemStyles,
887
+ flatIndex === activeIndex && comboboxItemActiveStyles,
888
+ "text-[var(--color-primary)] font-medium"
889
+ ),
890
+ onClick: handleCreate,
891
+ onMouseEnter: () => setActiveIndex(flatIndex),
892
+ children: [
893
+ /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
894
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
895
+ /* @__PURE__ */ jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
896
+ ] }),
897
+ createLabel(search.trim())
898
+ ]
899
+ }
900
+ )
901
+ ] })
902
+ }
903
+ ) })
904
+ ] })
905
+ ] });
906
+ }
907
+ );
908
+ Combobox.displayName = "Combobox";
909
+ var checkboxVariants = cva(
910
+ [
911
+ "relative shrink-0 appearance-none cursor-pointer",
912
+ "border border-[var(--color-border)]",
913
+ "bg-[var(--color-surface)]",
914
+ "transition-all duration-[var(--transition-fast)]",
915
+ "hover:border-[var(--color-border-hover)]",
916
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring-color)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--color-bg)]",
917
+ "checked:bg-[var(--color-primary)] checked:border-[var(--color-primary)]",
918
+ "checked:hover:bg-[var(--color-primary-hover)]",
919
+ "disabled:opacity-50 disabled:cursor-not-allowed"
920
+ ],
293
921
  {
294
- ref,
295
- className: cn(modalDescriptionStyles, className),
296
- ...props
922
+ variants: {
923
+ size: {
924
+ sm: "h-4 w-4 rounded-[3px]",
925
+ md: "h-[18px] w-[18px] rounded-[var(--radius-sm)]"
926
+ }
927
+ },
928
+ defaultVariants: {
929
+ size: "md"
930
+ }
297
931
  }
298
- ));
299
- ModalDescription.displayName = "ModalDescription";
300
- var ModalFooter = forwardRef(
301
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
932
+ );
933
+ var checkboxWrapperStyles = "flex items-start gap-2.5";
934
+ var checkboxLabelStyles = "text-[var(--text-sm)] text-[var(--color-text-primary)] cursor-pointer select-none leading-tight";
935
+ var checkboxDescriptionStyles = "text-[var(--text-xs)] text-[var(--color-text-muted)] mt-0.5";
936
+ var checkmarkStyles = "absolute inset-0 flex items-center justify-center pointer-events-none text-[var(--color-primary-foreground)]";
937
+ var Checkbox = forwardRef(
938
+ ({ className, size, label, description, indeterminate, id, ...props }, ref) => {
939
+ const inputId = id || (label ? `cb-${label.toLowerCase().replace(/\s+/g, "-")}` : void 0);
940
+ const internalRef = useRef(null);
941
+ const inputRef = ref || internalRef;
942
+ useEffect(() => {
943
+ if (inputRef.current) {
944
+ inputRef.current.indeterminate = !!indeterminate;
945
+ }
946
+ }, [indeterminate, inputRef]);
947
+ return /* @__PURE__ */ jsxs("div", { className: checkboxWrapperStyles, children: [
948
+ /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center mt-0.5", children: [
949
+ /* @__PURE__ */ jsx(
950
+ "input",
951
+ {
952
+ ref: inputRef,
953
+ id: inputId,
954
+ type: "checkbox",
955
+ className: cn(checkboxVariants({ size }), className),
956
+ ...props
957
+ }
958
+ ),
959
+ /* @__PURE__ */ jsx("div", { className: checkmarkStyles, children: indeterminate ? /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ jsx("rect", { x: "1", y: "4", width: "8", height: "2", rx: "1", fill: "currentColor" }) }) : /* @__PURE__ */ jsx("svg", { width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", className: "opacity-0 [input:checked~div>&]:opacity-100 transition-opacity", children: /* @__PURE__ */ jsx("path", { d: "M2 5L4 7L8 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })
960
+ ] }),
961
+ (label || description) && /* @__PURE__ */ jsxs("div", { children: [
962
+ label && /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: checkboxLabelStyles, children: label }),
963
+ description && /* @__PURE__ */ jsx("p", { className: checkboxDescriptionStyles, children: description })
964
+ ] })
965
+ ] });
966
+ }
967
+ );
968
+ Checkbox.displayName = "Checkbox";
969
+
970
+ // src/components/radio/radio.styles.ts
971
+ var radioGroupStyles = "flex flex-col gap-2.5";
972
+ var radioGroupHorizontalStyles = "flex-row gap-4";
973
+ var radioWrapperStyles = "flex items-start gap-2.5";
974
+ var radioInputStyles = [
975
+ "relative shrink-0 appearance-none cursor-pointer",
976
+ "h-[18px] w-[18px] rounded-full",
977
+ "border border-[var(--color-border)]",
978
+ "bg-[var(--color-surface)]",
979
+ "transition-all duration-[var(--transition-fast)]",
980
+ "hover:border-[var(--color-border-hover)]",
981
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring-color)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--color-bg)]",
982
+ "checked:border-[var(--color-primary)] checked:bg-[var(--color-primary)]",
983
+ "checked:hover:bg-[var(--color-primary-hover)]",
984
+ "disabled:opacity-50 disabled:cursor-not-allowed"
985
+ ].join(" ");
986
+ var radioDotStyles = "absolute inset-0 flex items-center justify-center pointer-events-none";
987
+ var radioLabelStyles = "text-[var(--text-sm)] text-[var(--color-text-primary)] cursor-pointer select-none leading-tight";
988
+ var radioDescriptionStyles = "text-[var(--text-xs)] text-[var(--color-text-muted)] mt-0.5";
989
+ var RadioGroupContext = createContext({});
990
+ var RadioGroup = forwardRef(
991
+ ({ className, name, value, onChange, orientation = "vertical", disabled, children, ...props }, ref) => /* @__PURE__ */ jsx(RadioGroupContext.Provider, { value: { name, value, onChange, disabled }, children: /* @__PURE__ */ jsx(
302
992
  "div",
303
993
  {
304
994
  ref,
995
+ role: "radiogroup",
305
996
  className: cn(
306
- "flex justify-end gap-[var(--space-sm)] mt-[var(--space-lg)]",
997
+ radioGroupStyles,
998
+ orientation === "horizontal" && radioGroupHorizontalStyles,
307
999
  className
308
1000
  ),
309
- ...props
1001
+ ...props,
1002
+ children
310
1003
  }
311
- )
1004
+ ) })
312
1005
  );
313
- ModalFooter.displayName = "ModalFooter";
314
-
315
- // src/components/dropdown/dropdown.styles.ts
316
- var dropdownContentStyles = [
317
- "z-50 min-w-[180px] overflow-hidden",
318
- "bg-[var(--color-surface)] border border-[var(--color-border)]",
319
- "rounded-[var(--radius-md)] shadow-[var(--shadow-lg)]",
320
- "p-1",
321
- "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
322
- "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
323
- "data-[side=top]:slide-in-from-bottom-2",
324
- "data-[side=bottom]:slide-in-from-top-2",
325
- "data-[side=left]:slide-in-from-right-2",
326
- "data-[side=right]:slide-in-from-left-2"
327
- ].join(" ");
328
- var dropdownItemStyles = [
329
- "relative flex items-center gap-2",
330
- "rounded-[var(--radius-sm)] px-2 py-1.5",
331
- "text-[var(--text-sm)] text-[var(--color-text-secondary)]",
332
- "cursor-pointer select-none outline-none",
1006
+ RadioGroup.displayName = "RadioGroup";
1007
+ var Radio = forwardRef(
1008
+ ({ className, label, description, value, id, disabled: itemDisabled, ...props }, ref) => {
1009
+ const ctx = useContext(RadioGroupContext);
1010
+ const inputId = id || (label ? `radio-${label.toLowerCase().replace(/\s+/g, "-")}` : void 0);
1011
+ const isDisabled = itemDisabled || ctx.disabled;
1012
+ return /* @__PURE__ */ jsxs("div", { className: radioWrapperStyles, children: [
1013
+ /* @__PURE__ */ jsxs("div", { className: "relative flex items-center justify-center mt-0.5", children: [
1014
+ /* @__PURE__ */ jsx(
1015
+ "input",
1016
+ {
1017
+ ref,
1018
+ id: inputId,
1019
+ type: "radio",
1020
+ name: ctx.name,
1021
+ value,
1022
+ checked: ctx.value !== void 0 ? ctx.value === value : void 0,
1023
+ onChange: () => ctx.onChange?.(value),
1024
+ disabled: isDisabled,
1025
+ className: cn(radioInputStyles, className),
1026
+ ...props
1027
+ }
1028
+ ),
1029
+ /* @__PURE__ */ jsx("div", { className: radioDotStyles, children: /* @__PURE__ */ jsx("div", { className: "h-2 w-2 rounded-full bg-white scale-0 transition-transform duration-150 [input:checked~div>&]:scale-100" }) })
1030
+ ] }),
1031
+ (label || description) && /* @__PURE__ */ jsxs("div", { children: [
1032
+ label && /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: radioLabelStyles, children: label }),
1033
+ description && /* @__PURE__ */ jsx("p", { className: radioDescriptionStyles, children: description })
1034
+ ] })
1035
+ ] });
1036
+ }
1037
+ );
1038
+ Radio.displayName = "Radio";
1039
+ var switchTrackVariants = cva(
1040
+ [
1041
+ "relative inline-flex shrink-0 cursor-pointer",
1042
+ "rounded-full border-2 border-transparent",
1043
+ "transition-colors duration-[var(--transition-base)]",
1044
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring-color)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--color-bg)]",
1045
+ "disabled:opacity-50 disabled:cursor-not-allowed"
1046
+ ],
1047
+ {
1048
+ variants: {
1049
+ size: {
1050
+ sm: "h-5 w-9",
1051
+ md: "h-6 w-11"
1052
+ },
1053
+ checked: {
1054
+ true: "bg-[var(--color-primary)]",
1055
+ false: "bg-[var(--color-surface-raised)]"
1056
+ }
1057
+ },
1058
+ defaultVariants: {
1059
+ size: "md",
1060
+ checked: false
1061
+ }
1062
+ }
1063
+ );
1064
+ var switchThumbVariants = cva(
1065
+ [
1066
+ "pointer-events-none inline-block rounded-full bg-white",
1067
+ "shadow-sm transition-transform duration-[var(--transition-base)]",
1068
+ "ring-0"
1069
+ ],
1070
+ {
1071
+ variants: {
1072
+ size: {
1073
+ sm: "h-4 w-4",
1074
+ md: "h-5 w-5"
1075
+ },
1076
+ checked: {
1077
+ true: "",
1078
+ false: "translate-x-0"
1079
+ }
1080
+ },
1081
+ compoundVariants: [
1082
+ { size: "sm", checked: true, className: "translate-x-4" },
1083
+ { size: "md", checked: true, className: "translate-x-5" }
1084
+ ],
1085
+ defaultVariants: {
1086
+ size: "md",
1087
+ checked: false
1088
+ }
1089
+ }
1090
+ );
1091
+ var switchWrapperStyles = "flex items-center gap-3";
1092
+ var switchLabelStyles = "text-[var(--text-sm)] text-[var(--color-text-primary)] cursor-pointer select-none";
1093
+ var switchDescriptionStyles = "text-[var(--text-xs)] text-[var(--color-text-muted)]";
1094
+ var Switch = forwardRef(
1095
+ ({ className, checked = false, onChange, label, description, size = "md", disabled, id, ...props }, ref) => {
1096
+ const inputId = id || (label ? `switch-${label.toLowerCase().replace(/\s+/g, "-")}` : void 0);
1097
+ return /* @__PURE__ */ jsxs("div", { className: switchWrapperStyles, children: [
1098
+ /* @__PURE__ */ jsx(
1099
+ "button",
1100
+ {
1101
+ ref,
1102
+ id: inputId,
1103
+ type: "button",
1104
+ role: "switch",
1105
+ "aria-checked": checked,
1106
+ disabled,
1107
+ onClick: () => onChange?.(!checked),
1108
+ className: cn(
1109
+ switchTrackVariants({ size, checked }),
1110
+ className
1111
+ ),
1112
+ ...props,
1113
+ children: /* @__PURE__ */ jsx("span", { className: switchThumbVariants({ size, checked }) })
1114
+ }
1115
+ ),
1116
+ (label || description) && /* @__PURE__ */ jsxs("div", { children: [
1117
+ label && /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: switchLabelStyles, onClick: () => !disabled && onChange?.(!checked), children: label }),
1118
+ description && /* @__PURE__ */ jsx("p", { className: switchDescriptionStyles, children: description })
1119
+ ] })
1120
+ ] });
1121
+ }
1122
+ );
1123
+ Switch.displayName = "Switch";
1124
+ var Separator = forwardRef(
1125
+ ({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx(
1126
+ "div",
1127
+ {
1128
+ ref,
1129
+ role: decorative ? "none" : "separator",
1130
+ "aria-orientation": !decorative ? orientation : void 0,
1131
+ className: cn(
1132
+ "shrink-0 bg-[var(--color-border)]",
1133
+ orientation === "horizontal" ? "h-px w-full" : "w-px h-full",
1134
+ className
1135
+ ),
1136
+ ...props
1137
+ }
1138
+ )
1139
+ );
1140
+ Separator.displayName = "Separator";
1141
+ var avatarVariants = cva(
1142
+ [
1143
+ "relative inline-flex items-center justify-center shrink-0",
1144
+ "bg-[var(--color-surface-raised)] text-[var(--color-text-secondary)]",
1145
+ "font-medium overflow-hidden",
1146
+ "border border-[var(--color-border)]"
1147
+ ],
1148
+ {
1149
+ variants: {
1150
+ size: {
1151
+ xs: "h-6 w-6 text-[10px]",
1152
+ sm: "h-8 w-8 text-[var(--text-xs)]",
1153
+ md: "h-10 w-10 text-[var(--text-sm)]",
1154
+ lg: "h-12 w-12 text-[var(--text-base)]",
1155
+ xl: "h-16 w-16 text-[var(--text-lg)]"
1156
+ },
1157
+ shape: {
1158
+ circle: "rounded-full",
1159
+ rounded: "rounded-[var(--radius-md)]"
1160
+ }
1161
+ },
1162
+ defaultVariants: {
1163
+ size: "md",
1164
+ shape: "circle"
1165
+ }
1166
+ }
1167
+ );
1168
+ var avatarImageStyles = "h-full w-full object-cover";
1169
+ var avatarStatusVariants = cva(
1170
+ [
1171
+ "absolute bottom-0 right-0 block rounded-full ring-2 ring-[var(--color-bg)]"
1172
+ ],
1173
+ {
1174
+ variants: {
1175
+ status: {
1176
+ online: "bg-[var(--color-success)]",
1177
+ offline: "bg-[var(--color-text-muted)]",
1178
+ busy: "bg-[var(--color-danger)]",
1179
+ away: "bg-[var(--color-warning)]"
1180
+ },
1181
+ size: {
1182
+ xs: "h-1.5 w-1.5",
1183
+ sm: "h-2 w-2",
1184
+ md: "h-2.5 w-2.5",
1185
+ lg: "h-3 w-3",
1186
+ xl: "h-3.5 w-3.5"
1187
+ }
1188
+ },
1189
+ defaultVariants: {
1190
+ status: "online",
1191
+ size: "md"
1192
+ }
1193
+ }
1194
+ );
1195
+ function getInitials(name) {
1196
+ return name.split(" ").map((n) => n[0]).slice(0, 2).join("").toUpperCase();
1197
+ }
1198
+ var Avatar = forwardRef(
1199
+ ({ className, src, alt, name, size = "md", shape, status, ...props }, ref) => {
1200
+ const [imgError, setImgError] = useState(false);
1201
+ return /* @__PURE__ */ jsxs(
1202
+ "div",
1203
+ {
1204
+ ref,
1205
+ className: cn(avatarVariants({ size, shape }), className),
1206
+ children: [
1207
+ src && !imgError ? /* @__PURE__ */ jsx(
1208
+ "img",
1209
+ {
1210
+ src,
1211
+ alt: alt || name || "Avatar",
1212
+ className: avatarImageStyles,
1213
+ onError: () => setImgError(true),
1214
+ ...props
1215
+ }
1216
+ ) : /* @__PURE__ */ jsx("span", { children: name ? getInitials(name) : "?" }),
1217
+ status && /* @__PURE__ */ jsx("span", { className: avatarStatusVariants({ status, size }) })
1218
+ ]
1219
+ }
1220
+ );
1221
+ }
1222
+ );
1223
+ Avatar.displayName = "Avatar";
1224
+
1225
+ // src/components/tooltip/tooltip.styles.ts
1226
+ var tooltipContentStyles = [
1227
+ "z-[var(--z-tooltip)]",
1228
+ "overflow-hidden rounded-[var(--radius)] px-3 py-1.5",
1229
+ "bg-[var(--color-slate-800)] text-[var(--color-text-primary)]",
1230
+ "text-[var(--text-xs)] font-medium",
1231
+ "border border-[var(--color-border)]",
1232
+ "shadow-md",
1233
+ "animate-in fade-in-0 zoom-in-95",
1234
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
1235
+ ].join(" ");
1236
+ var TooltipProvider = TooltipPrimitive.Provider;
1237
+ function Tooltip({
1238
+ children,
1239
+ content,
1240
+ side = "top",
1241
+ align = "center",
1242
+ delayDuration = 300,
1243
+ sideOffset = 6
1244
+ }) {
1245
+ return /* @__PURE__ */ jsxs(TooltipPrimitive.Root, { delayDuration, children: [
1246
+ /* @__PURE__ */ jsx(TooltipPrimitive.Trigger, { asChild: true, children }),
1247
+ /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx(
1248
+ TooltipPrimitive.Content,
1249
+ {
1250
+ side,
1251
+ align,
1252
+ sideOffset,
1253
+ className: cn(tooltipContentStyles),
1254
+ children: content
1255
+ }
1256
+ ) })
1257
+ ] });
1258
+ }
1259
+ Tooltip.displayName = "Tooltip";
1260
+
1261
+ // src/components/popover/popover.styles.ts
1262
+ var popoverContentStyles = [
1263
+ "z-[var(--z-popover)]",
1264
+ "w-72 rounded-[var(--radius-md)] p-4",
1265
+ "bg-[var(--color-surface)] text-[var(--color-text-primary)]",
1266
+ "border border-[var(--color-border)]",
1267
+ "shadow-lg",
1268
+ "outline-none"
1269
+ ].join(" ");
1270
+ var Popover = PopoverPrimitive3.Root;
1271
+ var PopoverTrigger = PopoverPrimitive3.Trigger;
1272
+ var PopoverAnchor = PopoverPrimitive3.Anchor;
1273
+ var PopoverClose = PopoverPrimitive3.Close;
1274
+ var PopoverContent = forwardRef(({ className, sideOffset = 6, align = "center", ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive3.Portal, { children: /* @__PURE__ */ jsx(
1275
+ PopoverPrimitive3.Content,
1276
+ {
1277
+ ref,
1278
+ sideOffset,
1279
+ align,
1280
+ className: cn(popoverContentStyles, className),
1281
+ ...props
1282
+ }
1283
+ ) }));
1284
+ PopoverContent.displayName = "PopoverContent";
1285
+ var cardVariants = cva(
1286
+ [
1287
+ "rounded-[var(--radius-lg)]",
1288
+ "transition-all duration-[var(--transition-base)]"
1289
+ ],
1290
+ {
1291
+ variants: {
1292
+ variant: {
1293
+ elevated: [
1294
+ "bg-[var(--color-surface)] border border-[var(--color-slate-800)]",
1295
+ "shadow-[var(--shadow-sm)]"
1296
+ ],
1297
+ outlined: [
1298
+ "bg-transparent border border-[var(--color-slate-700)]"
1299
+ ],
1300
+ ghost: [
1301
+ "bg-[var(--color-surface)]/50 border border-transparent"
1302
+ ],
1303
+ glass: [
1304
+ "bg-[var(--color-surface)]/70 backdrop-blur-md border border-[var(--color-overlay)]",
1305
+ "shadow-lg"
1306
+ ]
1307
+ },
1308
+ hoverable: {
1309
+ true: "hover:border-[var(--color-border-hover)] hover:shadow-[var(--shadow-lg)] cursor-pointer",
1310
+ false: ""
1311
+ }
1312
+ },
1313
+ defaultVariants: {
1314
+ variant: "elevated",
1315
+ hoverable: false
1316
+ }
1317
+ }
1318
+ );
1319
+ var cardHeaderStyles = "px-[var(--space-lg)] pt-[var(--space-lg)] pb-[var(--space-sm)]";
1320
+ var cardBodyStyles = "px-[var(--space-lg)] py-[var(--space-md)]";
1321
+ var cardFooterStyles = "px-[var(--space-lg)] pt-[var(--space-sm)] pb-[var(--space-lg)] border-t border-[var(--color-border)]";
1322
+ var Card = forwardRef(
1323
+ ({ className, variant, hoverable, ...props }, ref) => /* @__PURE__ */ jsx(
1324
+ "div",
1325
+ {
1326
+ ref,
1327
+ className: cn(cardVariants({ variant, hoverable }), className),
1328
+ ...props
1329
+ }
1330
+ )
1331
+ );
1332
+ Card.displayName = "Card";
1333
+ var CardHeader = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn(cardHeaderStyles, className), ...props }));
1334
+ CardHeader.displayName = "CardHeader";
1335
+ var CardBody = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn(cardBodyStyles, className), ...props }));
1336
+ CardBody.displayName = "CardBody";
1337
+ var CardFooter = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn(cardFooterStyles, className), ...props }));
1338
+ CardFooter.displayName = "CardFooter";
1339
+
1340
+ // src/components/modal/modal.styles.ts
1341
+ var modalOverlayStyles = [
1342
+ "fixed inset-0 z-[var(--z-overlay)] bg-black/60 backdrop-blur-sm",
1343
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0",
1344
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0"
1345
+ ].join(" ");
1346
+ var modalContentStyles = [
1347
+ "fixed left-1/2 top-1/2 z-[var(--z-modal)] -translate-x-1/2 -translate-y-1/2",
1348
+ "w-full max-w-lg",
1349
+ "bg-[var(--color-surface)] border border-[var(--color-border)]",
1350
+ "rounded-[var(--radius-xl)] shadow-lg",
1351
+ "p-[var(--space-lg)]",
1352
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
1353
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]",
1354
+ "duration-200"
1355
+ ].join(" ");
1356
+ var modalTitleStyles = "text-[var(--text-lg)] font-semibold text-[var(--color-text-primary)]";
1357
+ var modalDescriptionStyles = "text-[var(--text-sm)] text-[var(--color-text-secondary)] mt-2";
1358
+ var modalCloseStyles = [
1359
+ "absolute right-4 top-4",
1360
+ "rounded-[var(--radius-sm)] p-1",
1361
+ "text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)]",
1362
+ "hover:bg-[var(--color-surface-hover)]",
1363
+ "transition-colors duration-[var(--transition-fast)]",
1364
+ "focus:outline-none focus:ring-2 focus:ring-[var(--ring-color)]"
1365
+ ].join(" ");
1366
+ var Modal = DialogPrimitive.Root;
1367
+ var ModalTrigger = DialogPrimitive.Trigger;
1368
+ var ModalOverlay = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Overlay, { ref, className: cn(modalOverlayStyles, className), ...props }));
1369
+ ModalOverlay.displayName = "ModalOverlay";
1370
+ var ModalContent = forwardRef(({ className, children, showClose = true, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [
1371
+ /* @__PURE__ */ jsx(ModalOverlay, {}),
1372
+ /* @__PURE__ */ jsxs(DialogPrimitive.Content, { ref, className: cn(modalContentStyles, className), ...props, children: [
1373
+ children,
1374
+ showClose && /* @__PURE__ */ jsxs(DialogPrimitive.Close, { className: modalCloseStyles, children: [
1375
+ /* @__PURE__ */ jsxs(
1376
+ "svg",
1377
+ {
1378
+ xmlns: "http://www.w3.org/2000/svg",
1379
+ width: "16",
1380
+ height: "16",
1381
+ viewBox: "0 0 24 24",
1382
+ fill: "none",
1383
+ stroke: "currentColor",
1384
+ strokeWidth: "2",
1385
+ strokeLinecap: "round",
1386
+ strokeLinejoin: "round",
1387
+ children: [
1388
+ /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1389
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1390
+ ]
1391
+ }
1392
+ ),
1393
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
1394
+ ] })
1395
+ ] })
1396
+ ] }));
1397
+ ModalContent.displayName = "ModalContent";
1398
+ var ModalTitle = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Title, { ref, className: cn(modalTitleStyles, className), ...props }));
1399
+ ModalTitle.displayName = "ModalTitle";
1400
+ var ModalDescription = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1401
+ DialogPrimitive.Description,
1402
+ {
1403
+ ref,
1404
+ className: cn(modalDescriptionStyles, className),
1405
+ ...props
1406
+ }
1407
+ ));
1408
+ ModalDescription.displayName = "ModalDescription";
1409
+ var ModalFooter = forwardRef(
1410
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1411
+ "div",
1412
+ {
1413
+ ref,
1414
+ className: cn(
1415
+ "flex justify-end gap-[var(--space-sm)] mt-[var(--space-lg)]",
1416
+ className
1417
+ ),
1418
+ ...props
1419
+ }
1420
+ )
1421
+ );
1422
+ ModalFooter.displayName = "ModalFooter";
1423
+
1424
+ // src/components/dropdown/dropdown.styles.ts
1425
+ var dropdownContentStyles = [
1426
+ "z-[var(--z-dropdown)] min-w-[180px] overflow-hidden",
1427
+ "bg-[var(--color-surface)] border border-[var(--color-border)]",
1428
+ "rounded-[var(--radius-md)] shadow-lg",
1429
+ "p-1",
1430
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
1431
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
1432
+ "data-[side=top]:slide-in-from-bottom-2",
1433
+ "data-[side=bottom]:slide-in-from-top-2",
1434
+ "data-[side=left]:slide-in-from-right-2",
1435
+ "data-[side=right]:slide-in-from-left-2"
1436
+ ].join(" ");
1437
+ var dropdownItemStyles = [
1438
+ "relative flex items-center gap-2",
1439
+ "rounded-[var(--radius-sm)] px-2 py-1.5",
1440
+ "text-[var(--text-sm)] text-[var(--color-text-secondary)]",
1441
+ "cursor-pointer select-none outline-none",
333
1442
  "transition-colors duration-[var(--transition-fast)]",
334
1443
  "data-[highlighted]:bg-[var(--color-surface-hover)] data-[highlighted]:text-[var(--color-text-primary)]",
335
1444
  "data-[disabled]:pointer-events-none data-[disabled]:opacity-50"
@@ -385,12 +1494,12 @@ var badgeVariants = cva(
385
1494
  {
386
1495
  variants: {
387
1496
  variant: {
388
- default: "bg-[var(--color-surface-raised)] text-[var(--color-text-secondary)] border border-[var(--color-border)]",
389
- primary: "bg-[var(--color-primary)]/15 text-[var(--color-primary-hover)] border border-[var(--color-primary)]/25",
390
- success: "bg-[var(--color-success)]/15 text-[var(--color-success)] border border-[var(--color-success)]/25",
391
- warning: "bg-[var(--color-warning)]/15 text-[var(--color-warning)] border border-[var(--color-warning)]/25",
392
- danger: "bg-[var(--color-danger)]/15 text-[var(--color-danger)] border border-[var(--color-danger)]/25",
393
- info: "bg-[var(--color-info)]/15 text-[var(--color-info)] border border-[var(--color-info)]/25"
1497
+ default: "bg-[var(--color-slate-800)] text-[var(--color-slate-300)] border border-[var(--color-slate-700)]",
1498
+ primary: "bg-[var(--color-primary)]/10 text-[var(--color-primary-400)] border border-[var(--color-primary)]/20 shadow-[0_0_10px_-4px_var(--color-primary-500)]",
1499
+ success: "bg-[var(--color-success)]/10 text-[var(--color-success)] border border-[var(--color-success)]/20",
1500
+ warning: "bg-[var(--color-warning)]/10 text-[var(--color-warning)] border border-[var(--color-warning)]/20",
1501
+ danger: "bg-[var(--color-danger)]/10 text-[var(--color-danger)] border border-[var(--color-danger)]/20",
1502
+ info: "bg-[var(--color-info)]/10 text-[var(--color-info)] border border-[var(--color-info)]/20"
394
1503
  },
395
1504
  size: {
396
1505
  sm: "px-2 py-0.5 text-[10px]",
@@ -435,7 +1544,7 @@ var tabsTriggerStyles = [
435
1544
  ].join(" ");
436
1545
  var tabsTriggerActiveStyles = [
437
1546
  "bg-[var(--color-surface)] text-[var(--color-text-primary)]",
438
- "shadow-[var(--shadow-sm)]"
1547
+ "shadow-sm"
439
1548
  ].join(" ");
440
1549
  var tabsContentStyles = [
441
1550
  "mt-[var(--space-md)]",
@@ -590,17 +1699,17 @@ var sidebarItemStyles = [
590
1699
  "rounded-[var(--radius)]",
591
1700
  "cursor-pointer select-none",
592
1701
  "transition-all duration-[var(--transition-fast)]",
593
- "hover:bg-[var(--color-surface)] hover:text-[var(--color-text-primary)]"
1702
+ "hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)]"
594
1703
  ].join(" ");
595
1704
  var sidebarItemActiveStyles = [
596
- "bg-[var(--color-primary)]/10 text-[var(--color-primary-hover)]",
1705
+ "bg-[var(--color-primary)]/10 text-[var(--color-primary-400)]",
597
1706
  "hover:bg-[var(--color-primary)]/15"
598
1707
  ].join(" ");
599
1708
  var sidebarToggleStyles = [
600
1709
  "flex items-center justify-center",
601
1710
  "h-7 w-7 rounded-[var(--radius)]",
602
1711
  "text-[var(--color-text-muted)]",
603
- "hover:bg-[var(--color-surface)] hover:text-[var(--color-text-primary)]",
1712
+ "hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)]",
604
1713
  "transition-colors duration-[var(--transition-fast)]",
605
1714
  "cursor-pointer"
606
1715
  ].join(" ");
@@ -729,7 +1838,1355 @@ var SidebarToggle = forwardRef(
729
1838
  }
730
1839
  );
731
1840
  SidebarToggle.displayName = "SidebarToggle";
1841
+ var statCardStyles = [
1842
+ "rounded-[var(--radius-lg)] p-5",
1843
+ "bg-[var(--color-surface)] border border-[var(--color-border)]",
1844
+ "transition-all duration-[var(--transition-base)]",
1845
+ "hover:border-[var(--color-border-hover)]"
1846
+ ].join(" ");
1847
+ var statCardTitleStyles = "text-[var(--text-sm)] font-medium text-[var(--color-text-muted)]";
1848
+ var statCardValueStyles = "text-2xl font-semibold text-[var(--color-text-primary)] mt-1";
1849
+ var statCardChangeVariants = cva(
1850
+ "inline-flex items-center gap-1 text-[var(--text-xs)] font-medium mt-2",
1851
+ {
1852
+ variants: {
1853
+ changeType: {
1854
+ positive: "text-[var(--color-success)]",
1855
+ negative: "text-[var(--color-danger)]",
1856
+ neutral: "text-[var(--color-text-muted)]"
1857
+ }
1858
+ },
1859
+ defaultVariants: {
1860
+ changeType: "neutral"
1861
+ }
1862
+ }
1863
+ );
1864
+ var statCardIconStyles = "h-10 w-10 rounded-[var(--radius-md)] bg-[var(--color-primary)]/10 text-[var(--color-primary-400)] flex items-center justify-center";
1865
+ var StatCard = forwardRef(
1866
+ ({ className, title, value, change, changeType = "neutral", icon, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn(statCardStyles, className), ...props, children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between", children: [
1867
+ /* @__PURE__ */ jsxs("div", { children: [
1868
+ /* @__PURE__ */ jsx("p", { className: statCardTitleStyles, children: title }),
1869
+ /* @__PURE__ */ jsx("p", { className: statCardValueStyles, children: value }),
1870
+ change && /* @__PURE__ */ jsxs("span", { className: statCardChangeVariants({ changeType }), children: [
1871
+ changeType === "positive" && /* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("polyline", { points: "18 15 12 9 6 15" }) }),
1872
+ changeType === "negative" && /* @__PURE__ */ jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("polyline", { points: "6 9 12 15 18 9" }) }),
1873
+ change
1874
+ ] })
1875
+ ] }),
1876
+ icon && /* @__PURE__ */ jsx("div", { className: statCardIconStyles, children: icon })
1877
+ ] }) })
1878
+ );
1879
+ StatCard.displayName = "StatCard";
1880
+
1881
+ // src/components/empty-state/empty-state.styles.ts
1882
+ var emptyStateStyles = [
1883
+ "flex flex-col items-center justify-center py-12 px-6 text-center"
1884
+ ].join(" ");
1885
+ var emptyStateIconStyles = "h-12 w-12 text-[var(--color-text-muted)] mb-4";
1886
+ var emptyStateTitleStyles = "text-[var(--text-base)] font-medium text-[var(--color-text-primary)] mb-1";
1887
+ var emptyStateDescriptionStyles = "text-[var(--text-sm)] text-[var(--color-text-muted)] max-w-sm mb-4";
1888
+ var EmptyState = forwardRef(
1889
+ ({ className, icon, title, description, action, ...props }, ref) => /* @__PURE__ */ jsxs("div", { ref, className: cn(emptyStateStyles, className), ...props, children: [
1890
+ icon && /* @__PURE__ */ jsx("div", { className: emptyStateIconStyles, children: icon }),
1891
+ /* @__PURE__ */ jsx("h3", { className: emptyStateTitleStyles, children: title }),
1892
+ description && /* @__PURE__ */ jsx("p", { className: emptyStateDescriptionStyles, children: description }),
1893
+ action && /* @__PURE__ */ jsx("div", { children: action })
1894
+ ] })
1895
+ );
1896
+ EmptyState.displayName = "EmptyState";
1897
+ var alertVariants = cva(
1898
+ [
1899
+ "relative flex gap-3 p-4 rounded-[var(--radius-md)]",
1900
+ "border text-[var(--text-sm)]"
1901
+ ],
1902
+ {
1903
+ variants: {
1904
+ variant: {
1905
+ info: "bg-[var(--color-info)]/10 border-[var(--color-info)]/20 text-[var(--color-info)]",
1906
+ success: "bg-[var(--color-success)]/10 border-[var(--color-success)]/20 text-[var(--color-success)]",
1907
+ warning: "bg-[var(--color-warning)]/10 border-[var(--color-warning)]/20 text-[var(--color-warning)]",
1908
+ danger: "bg-[var(--color-danger)]/10 border-[var(--color-danger)]/20 text-[var(--color-danger)]"
1909
+ }
1910
+ },
1911
+ defaultVariants: {
1912
+ variant: "info"
1913
+ }
1914
+ }
1915
+ );
1916
+ var alertTitleStyles = "font-semibold leading-tight";
1917
+ var alertDescriptionStyles = "text-[var(--text-sm)] opacity-80 mt-0.5";
1918
+ var alertDismissStyles = "absolute top-3 right-3 p-1 rounded-[var(--radius-sm)] opacity-60 hover:opacity-100 transition-opacity cursor-pointer";
1919
+ var alertIconStyles = "shrink-0 mt-0.5";
1920
+ var defaultIcons = {
1921
+ info: /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1922
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
1923
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "16", x2: "12", y2: "12" }),
1924
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "8", x2: "12.01", y2: "8" })
1925
+ ] }),
1926
+ success: /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1927
+ /* @__PURE__ */ jsx("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
1928
+ /* @__PURE__ */ jsx("polyline", { points: "22 4 12 14.01 9 11.01" })
1929
+ ] }),
1930
+ warning: /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1931
+ /* @__PURE__ */ jsx("path", { d: "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" }),
1932
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
1933
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
1934
+ ] }),
1935
+ danger: /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1936
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
1937
+ /* @__PURE__ */ jsx("line", { x1: "15", y1: "9", x2: "9", y2: "15" }),
1938
+ /* @__PURE__ */ jsx("line", { x1: "9", y1: "9", x2: "15", y2: "15" })
1939
+ ] })
1940
+ };
1941
+ var Alert = forwardRef(
1942
+ ({ className, variant = "info", title, description, icon, dismissible, onDismiss, action, children, ...props }, ref) => /* @__PURE__ */ jsxs("div", { ref, role: "alert", className: cn(alertVariants({ variant }), className), ...props, children: [
1943
+ /* @__PURE__ */ jsx("div", { className: alertIconStyles, children: icon || defaultIcons[variant || "info"] }),
1944
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
1945
+ title && /* @__PURE__ */ jsx("p", { className: alertTitleStyles, children: title }),
1946
+ description && /* @__PURE__ */ jsx("p", { className: alertDescriptionStyles, children: description }),
1947
+ children,
1948
+ action && /* @__PURE__ */ jsx("div", { className: "mt-2", children: action })
1949
+ ] }),
1950
+ dismissible && /* @__PURE__ */ jsx("button", { onClick: onDismiss, className: alertDismissStyles, "aria-label": "Dismiss", children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
1951
+ /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1952
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1953
+ ] }) })
1954
+ ] })
1955
+ );
1956
+ Alert.displayName = "Alert";
1957
+ var skeletonVariants = cva(
1958
+ "animate-pulse bg-[var(--color-surface-raised)]",
1959
+ {
1960
+ variants: {
1961
+ variant: {
1962
+ text: "h-4 w-full rounded-[var(--radius-sm)]",
1963
+ circle: "rounded-full",
1964
+ rect: "rounded-[var(--radius)]"
1965
+ }
1966
+ },
1967
+ defaultVariants: {
1968
+ variant: "rect"
1969
+ }
1970
+ }
1971
+ );
1972
+ var SkeletonBase = forwardRef(
1973
+ ({ className, variant, width, height, style, ...props }, ref) => /* @__PURE__ */ jsx(
1974
+ "div",
1975
+ {
1976
+ ref,
1977
+ className: cn(skeletonVariants({ variant }), className),
1978
+ style: { width, height, ...style },
1979
+ ...props
1980
+ }
1981
+ )
1982
+ );
1983
+ SkeletonBase.displayName = "Skeleton";
1984
+ var SkeletonText = ({
1985
+ lines = 3,
1986
+ lastLineWidth = "60%",
1987
+ className,
1988
+ ...props
1989
+ }) => /* @__PURE__ */ jsx("div", { className: cn("space-y-2.5", className), ...props, children: Array.from({ length: lines }).map((_, i) => /* @__PURE__ */ jsx(
1990
+ "div",
1991
+ {
1992
+ className: "h-4 rounded-[var(--radius-sm)] animate-pulse bg-[var(--color-surface-raised)]",
1993
+ style: { width: i === lines - 1 ? lastLineWidth : "100%" }
1994
+ },
1995
+ i
1996
+ )) });
1997
+ SkeletonText.displayName = "SkeletonText";
1998
+ var Skeleton = Object.assign(SkeletonBase, {
1999
+ Text: SkeletonText
2000
+ });
2001
+ var progressTrackVariants = cva(
2002
+ "relative w-full overflow-hidden rounded-full bg-[var(--color-surface-raised)]",
2003
+ {
2004
+ variants: {
2005
+ size: {
2006
+ sm: "h-1.5",
2007
+ md: "h-2.5",
2008
+ lg: "h-4"
2009
+ }
2010
+ },
2011
+ defaultVariants: {
2012
+ size: "md"
2013
+ }
2014
+ }
2015
+ );
2016
+ var progressBarVariants = cva(
2017
+ "h-full rounded-full transition-all duration-500 ease-out",
2018
+ {
2019
+ variants: {
2020
+ variant: {
2021
+ default: "bg-[var(--color-primary)]",
2022
+ success: "bg-[var(--color-success)]",
2023
+ warning: "bg-[var(--color-warning)]",
2024
+ danger: "bg-[var(--color-danger)]"
2025
+ }
2026
+ },
2027
+ defaultVariants: {
2028
+ variant: "default"
2029
+ }
2030
+ }
2031
+ );
2032
+ var progressLabelStyles = "flex justify-between items-center mb-1.5 text-[var(--text-sm)] text-[var(--color-text-primary)]";
2033
+ var progressValueStyles = "text-[var(--text-xs)] font-medium text-[var(--color-text-secondary)]";
2034
+ var Progress = forwardRef(
2035
+ ({
2036
+ className,
2037
+ value = 0,
2038
+ max = 100,
2039
+ size,
2040
+ variant,
2041
+ label,
2042
+ showValue,
2043
+ indeterminate,
2044
+ ...props
2045
+ }, ref) => {
2046
+ const percentage = Math.min(Math.max(value / max * 100, 0), 100);
2047
+ return /* @__PURE__ */ jsxs("div", { ref, className: cn("w-full", className), ...props, children: [
2048
+ (label || showValue) && /* @__PURE__ */ jsxs("div", { className: progressLabelStyles, children: [
2049
+ label && /* @__PURE__ */ jsx("span", { className: "text-[var(--color-text-secondary)] font-medium", children: label }),
2050
+ showValue && !indeterminate && /* @__PURE__ */ jsxs("span", { className: progressValueStyles, children: [
2051
+ Math.round(percentage),
2052
+ "%"
2053
+ ] })
2054
+ ] }),
2055
+ /* @__PURE__ */ jsx(
2056
+ "div",
2057
+ {
2058
+ role: "progressbar",
2059
+ "aria-valuenow": indeterminate ? void 0 : value,
2060
+ "aria-valuemin": 0,
2061
+ "aria-valuemax": max,
2062
+ className: progressTrackVariants({ size }),
2063
+ children: /* @__PURE__ */ jsx(
2064
+ "div",
2065
+ {
2066
+ className: cn(
2067
+ progressBarVariants({ variant }),
2068
+ indeterminate && "w-1/3 animate-[progress-indeterminate_1.5s_ease-in-out_infinite]"
2069
+ ),
2070
+ style: !indeterminate ? { width: `${percentage}%` } : void 0
2071
+ }
2072
+ )
2073
+ }
2074
+ )
2075
+ ] });
2076
+ }
2077
+ );
2078
+ Progress.displayName = "Progress";
2079
+
2080
+ // src/components/pagination/pagination.styles.ts
2081
+ var paginationStyles = "flex items-center gap-1";
2082
+ var paginationButtonStyles = [
2083
+ "inline-flex items-center justify-center",
2084
+ "h-9 min-w-[36px] px-3",
2085
+ "text-[var(--text-sm)] font-medium text-[var(--color-text-secondary)]",
2086
+ "rounded-[var(--radius)] border border-transparent",
2087
+ "transition-all duration-[var(--transition-fast)]",
2088
+ "hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)]",
2089
+ "disabled:opacity-40 disabled:pointer-events-none",
2090
+ "cursor-pointer"
2091
+ ].join(" ");
2092
+ var paginationButtonActiveStyles = [
2093
+ "bg-[var(--color-primary)] text-[var(--color-primary-foreground)]",
2094
+ "hover:bg-[var(--color-primary-hover)] hover:text-[var(--color-primary-foreground)]",
2095
+ "border-[var(--color-primary)]"
2096
+ ].join(" ");
2097
+ var paginationEllipsisStyles = "flex items-center justify-center h-9 w-9 text-[var(--color-text-muted)]";
2098
+ var paginationInfoStyles = "text-[var(--text-sm)] text-[var(--color-text-muted)] mr-3";
2099
+ function getPages(page, totalPages, siblingCount) {
2100
+ const totalNumbers = siblingCount * 2 + 5;
2101
+ if (totalNumbers >= totalPages) {
2102
+ return Array.from({ length: totalPages }, (_, i) => i + 1);
2103
+ }
2104
+ const leftSibling = Math.max(page - siblingCount, 1);
2105
+ const rightSibling = Math.min(page + siblingCount, totalPages);
2106
+ const showLeftDots = leftSibling > 2;
2107
+ const showRightDots = rightSibling < totalPages - 1;
2108
+ if (!showLeftDots && showRightDots) {
2109
+ const leftRange = 3 + 2 * siblingCount;
2110
+ const pages = Array.from({ length: leftRange }, (_, i) => i + 1);
2111
+ return [...pages, "...", totalPages];
2112
+ }
2113
+ if (showLeftDots && !showRightDots) {
2114
+ const rightRange = 3 + 2 * siblingCount;
2115
+ const pages = Array.from({ length: rightRange }, (_, i) => totalPages - rightRange + i + 1);
2116
+ return [1, "...", ...pages];
2117
+ }
2118
+ const middlePages = [];
2119
+ for (let i = leftSibling; i <= rightSibling; i++) middlePages.push(i);
2120
+ return [1, "...", ...middlePages, "...", totalPages];
2121
+ }
2122
+ var Pagination = forwardRef(
2123
+ ({
2124
+ className,
2125
+ page,
2126
+ totalPages,
2127
+ onPageChange,
2128
+ siblingCount = 1,
2129
+ showInfo,
2130
+ totalItems,
2131
+ pageSize,
2132
+ ...props
2133
+ }, ref) => {
2134
+ const pages = getPages(page, totalPages, siblingCount);
2135
+ return /* @__PURE__ */ jsxs("nav", { ref, "aria-label": "Pagination", className: cn("flex items-center gap-2", className), ...props, children: [
2136
+ showInfo && totalItems !== void 0 && pageSize && /* @__PURE__ */ jsxs("span", { className: paginationInfoStyles, children: [
2137
+ (page - 1) * pageSize + 1,
2138
+ "-",
2139
+ Math.min(page * pageSize, totalItems),
2140
+ " of ",
2141
+ totalItems
2142
+ ] }),
2143
+ /* @__PURE__ */ jsxs("div", { className: paginationStyles, children: [
2144
+ /* @__PURE__ */ jsx(
2145
+ "button",
2146
+ {
2147
+ className: paginationButtonStyles,
2148
+ onClick: () => onPageChange(page - 1),
2149
+ disabled: page <= 1,
2150
+ "aria-label": "Previous page",
2151
+ children: /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("polyline", { points: "15 18 9 12 15 6" }) })
2152
+ }
2153
+ ),
2154
+ pages.map(
2155
+ (p, i) => p === "..." ? /* @__PURE__ */ jsx("span", { className: paginationEllipsisStyles, children: "\u2026" }, `dots-${i}`) : /* @__PURE__ */ jsx(
2156
+ "button",
2157
+ {
2158
+ className: cn(
2159
+ paginationButtonStyles,
2160
+ p === page && paginationButtonActiveStyles
2161
+ ),
2162
+ onClick: () => onPageChange(p),
2163
+ "aria-current": p === page ? "page" : void 0,
2164
+ children: p
2165
+ },
2166
+ p
2167
+ )
2168
+ ),
2169
+ /* @__PURE__ */ jsx(
2170
+ "button",
2171
+ {
2172
+ className: paginationButtonStyles,
2173
+ onClick: () => onPageChange(page + 1),
2174
+ disabled: page >= totalPages,
2175
+ "aria-label": "Next page",
2176
+ children: /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("polyline", { points: "9 18 15 12 9 6" }) })
2177
+ }
2178
+ )
2179
+ ] })
2180
+ ] });
2181
+ }
2182
+ );
2183
+ Pagination.displayName = "Pagination";
2184
+
2185
+ // src/components/breadcrumb/breadcrumb.styles.ts
2186
+ var breadcrumbStyles = "flex items-center gap-1.5 text-[var(--text-sm)]";
2187
+ var breadcrumbItemStyles = "text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] transition-colors duration-[var(--transition-fast)] cursor-pointer inline-flex items-center gap-1.5";
2188
+ var breadcrumbItemActiveStyles = "text-[var(--color-text-primary)] pointer-events-none font-medium";
2189
+ var breadcrumbSeparatorStyles = "text-[var(--color-text-muted)]/50 select-none";
2190
+ var Breadcrumb = forwardRef(
2191
+ ({ className, separator = "/", children, ...props }, ref) => {
2192
+ const items = React26.Children.toArray(children);
2193
+ return /* @__PURE__ */ jsx("nav", { ref, "aria-label": "Breadcrumb", className: cn(breadcrumbStyles, className), ...props, children: items.map((child, i) => /* @__PURE__ */ jsxs(React26.Fragment, { children: [
2194
+ child,
2195
+ i < items.length - 1 && /* @__PURE__ */ jsx("span", { className: breadcrumbSeparatorStyles, "aria-hidden": "true", children: separator })
2196
+ ] }, i)) });
2197
+ }
2198
+ );
2199
+ Breadcrumb.displayName = "Breadcrumb";
2200
+ var BreadcrumbItem = forwardRef(
2201
+ ({ className, href, active, icon, children, ...props }, ref) => {
2202
+ const Comp = href && !active ? "a" : "span";
2203
+ return /* @__PURE__ */ jsxs(
2204
+ Comp,
2205
+ {
2206
+ ref,
2207
+ href: href && !active ? href : void 0,
2208
+ "aria-current": active ? "page" : void 0,
2209
+ className: cn(
2210
+ breadcrumbItemStyles,
2211
+ active && breadcrumbItemActiveStyles,
2212
+ className
2213
+ ),
2214
+ ...props,
2215
+ children: [
2216
+ icon,
2217
+ children
2218
+ ]
2219
+ }
2220
+ );
2221
+ }
2222
+ );
2223
+ BreadcrumbItem.displayName = "BreadcrumbItem";
2224
+ var ToastContext = createContext({
2225
+ toast: () => {
2226
+ },
2227
+ dismiss: () => {
2228
+ }
2229
+ });
2230
+ var useToast = () => useContext(ToastContext);
2231
+ var containerStyles = "fixed top-4 right-4 z-[var(--z-toast)] flex flex-col gap-2 w-[380px] max-w-[calc(100vw-2rem)]";
2232
+ var toastBase = [
2233
+ "relative flex gap-3 items-start p-4 pr-10",
2234
+ "rounded-[var(--radius-md)]",
2235
+ "bg-[var(--color-surface)] border border-[var(--color-border)]",
2236
+ "shadow-[var(--shadow-lg)]",
2237
+ "text-[var(--text-sm)]",
2238
+ "animate-[toast-in_0.3s_ease-out]"
2239
+ ].join(" ");
2240
+ var variantMap = {
2241
+ default: "border-[var(--color-border)]",
2242
+ success: "border-[var(--color-success)]/30",
2243
+ warning: "border-[var(--color-warning)]/30",
2244
+ danger: "border-[var(--color-danger)]/30"
2245
+ };
2246
+ var variantIconMap = {
2247
+ success: /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "var(--color-success)", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "shrink-0 mt-0.5", children: [
2248
+ /* @__PURE__ */ jsx("path", { d: "M22 11.08V12a10 10 0 1 1-5.93-9.14" }),
2249
+ /* @__PURE__ */ jsx("polyline", { points: "22 4 12 14.01 9 11.01" })
2250
+ ] }),
2251
+ warning: /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "var(--color-warning)", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "shrink-0 mt-0.5", children: [
2252
+ /* @__PURE__ */ jsx("path", { d: "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" }),
2253
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
2254
+ /* @__PURE__ */ jsx("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
2255
+ ] }),
2256
+ danger: /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "var(--color-danger)", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "shrink-0 mt-0.5", children: [
2257
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "10" }),
2258
+ /* @__PURE__ */ jsx("line", { x1: "15", y1: "9", x2: "9", y2: "15" }),
2259
+ /* @__PURE__ */ jsx("line", { x1: "9", y1: "9", x2: "15", y2: "15" })
2260
+ ] })
2261
+ };
2262
+ function ToastItem({ data, onDismiss }) {
2263
+ const [exiting, setExiting] = useState(false);
2264
+ const timerRef = useRef();
2265
+ useEffect(() => {
2266
+ const dur = data.duration ?? 4e3;
2267
+ if (dur > 0) {
2268
+ timerRef.current = setTimeout(() => {
2269
+ setExiting(true);
2270
+ setTimeout(() => onDismiss(data.id), 200);
2271
+ }, dur);
2272
+ }
2273
+ return () => clearTimeout(timerRef.current);
2274
+ }, [data.duration, data.id, onDismiss]);
2275
+ return /* @__PURE__ */ jsxs(
2276
+ "div",
2277
+ {
2278
+ className: cn(
2279
+ toastBase,
2280
+ variantMap[data.variant || "default"],
2281
+ exiting && "animate-[toast-out_0.2s_ease-in_forwards]"
2282
+ ),
2283
+ role: "alert",
2284
+ children: [
2285
+ data.variant && data.variant !== "default" && variantIconMap[data.variant],
2286
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
2287
+ data.title && /* @__PURE__ */ jsx("p", { className: "font-medium text-[var(--color-text-primary)]", children: data.title }),
2288
+ data.description && /* @__PURE__ */ jsx("p", { className: "text-[var(--color-text-secondary)] mt-0.5", children: data.description }),
2289
+ data.action && /* @__PURE__ */ jsx("div", { className: "mt-2", children: data.action })
2290
+ ] }),
2291
+ /* @__PURE__ */ jsx(
2292
+ "button",
2293
+ {
2294
+ onClick: () => {
2295
+ setExiting(true);
2296
+ setTimeout(() => onDismiss(data.id), 200);
2297
+ },
2298
+ className: "absolute top-3 right-3 text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] transition-colors p-1",
2299
+ "aria-label": "Dismiss",
2300
+ children: /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2301
+ /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2302
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2303
+ ] })
2304
+ }
2305
+ )
2306
+ ]
2307
+ }
2308
+ );
2309
+ }
2310
+ function ToastProvider({ children }) {
2311
+ const [toasts, setToasts] = useState([]);
2312
+ const toast = useCallback((input) => {
2313
+ const id = Math.random().toString(36).slice(2, 9);
2314
+ setToasts((prev) => [...prev, { ...input, id }]);
2315
+ }, []);
2316
+ const dismiss = useCallback((id) => {
2317
+ setToasts((prev) => prev.filter((t) => t.id !== id));
2318
+ }, []);
2319
+ return /* @__PURE__ */ jsxs(ToastContext.Provider, { value: { toast, dismiss }, children: [
2320
+ children,
2321
+ toasts.length > 0 && /* @__PURE__ */ jsx("div", { className: containerStyles, children: toasts.map((t) => /* @__PURE__ */ jsx(ToastItem, { data: t, onDismiss: dismiss }, t.id)) })
2322
+ ] });
2323
+ }
2324
+ ToastProvider.displayName = "ToastProvider";
2325
+ var overlayStyles = "fixed inset-0 z-[var(--z-modal)] bg-[var(--color-overlay)] backdrop-blur-sm";
2326
+ var contentStyles = [
2327
+ "fixed top-[20%] left-1/2 -translate-x-1/2 z-[var(--z-modal)]",
2328
+ "w-full max-w-lg",
2329
+ "bg-[var(--color-surface)] border border-[var(--color-border)]",
2330
+ "rounded-[var(--radius-lg)] shadow-[var(--shadow-lg)]",
2331
+ "overflow-hidden"
2332
+ ].join(" ");
2333
+ var inputStyles = [
2334
+ "w-full bg-transparent text-[var(--color-text-primary)]",
2335
+ "px-4 py-3 text-[var(--text-base)]",
2336
+ "placeholder:text-[var(--color-text-muted)]",
2337
+ "border-b border-[var(--color-border)]",
2338
+ "focus:outline-none"
2339
+ ].join(" ");
2340
+ var listStyles = "max-h-72 overflow-y-auto p-2";
2341
+ var groupLabelStyles = "px-2 py-1.5 text-[var(--text-xs)] font-medium text-[var(--color-text-muted)] uppercase tracking-wider";
2342
+ var itemStyles = [
2343
+ "flex items-center gap-3 w-full px-3 py-2.5",
2344
+ "text-[var(--text-sm)] text-[var(--color-text-secondary)]",
2345
+ "rounded-[var(--radius)] cursor-pointer",
2346
+ "transition-colors duration-[var(--transition-fast)]",
2347
+ "outline-none"
2348
+ ].join(" ");
2349
+ var itemActiveStyles = "bg-[var(--color-surface-hover)] text-[var(--color-text-primary)]";
2350
+ var shortcutStyles = "ml-auto flex items-center gap-0.5 text-[10px] text-[var(--color-text-muted)]";
2351
+ var kbdStyles = "px-1.5 py-0.5 rounded-[3px] bg-[var(--color-surface-raised)] border border-[var(--color-border)] font-mono";
2352
+ var emptyStyles = "py-8 text-center text-[var(--text-sm)] text-[var(--color-text-muted)]";
2353
+ function CommandPalette({
2354
+ commands,
2355
+ placeholder = "Type a command or search\u2026",
2356
+ open: controlledOpen,
2357
+ onOpenChange,
2358
+ emptyMessage = "No results found."
2359
+ }) {
2360
+ const [internalOpen, setInternalOpen] = useState(false);
2361
+ const [search, setSearch] = useState("");
2362
+ const [activeIndex, setActiveIndex] = useState(0);
2363
+ const listRef = useRef(null);
2364
+ const isOpen = controlledOpen ?? internalOpen;
2365
+ const setOpen = onOpenChange ?? setInternalOpen;
2366
+ useEffect(() => {
2367
+ const handler = (e) => {
2368
+ if ((e.metaKey || e.ctrlKey) && e.key === "k") {
2369
+ e.preventDefault();
2370
+ setOpen(!isOpen);
2371
+ }
2372
+ };
2373
+ window.addEventListener("keydown", handler);
2374
+ return () => window.removeEventListener("keydown", handler);
2375
+ }, [isOpen, setOpen]);
2376
+ const filtered = commands.filter(
2377
+ (cmd) => cmd.label.toLowerCase().includes(search.toLowerCase())
2378
+ );
2379
+ const groups = /* @__PURE__ */ new Map();
2380
+ filtered.forEach((cmd) => {
2381
+ const g = cmd.group || "";
2382
+ if (!groups.has(g)) groups.set(g, []);
2383
+ groups.get(g).push(cmd);
2384
+ });
2385
+ const flatItems = filtered;
2386
+ const handleKeyDown = useCallback(
2387
+ (e) => {
2388
+ if (e.key === "ArrowDown") {
2389
+ e.preventDefault();
2390
+ setActiveIndex((i) => Math.min(i + 1, flatItems.length - 1));
2391
+ } else if (e.key === "ArrowUp") {
2392
+ e.preventDefault();
2393
+ setActiveIndex((i) => Math.max(i - 1, 0));
2394
+ } else if (e.key === "Enter" && flatItems[activeIndex]) {
2395
+ e.preventDefault();
2396
+ flatItems[activeIndex].onAction();
2397
+ setOpen(false);
2398
+ setSearch("");
2399
+ }
2400
+ },
2401
+ [activeIndex, flatItems, setOpen]
2402
+ );
2403
+ useEffect(() => {
2404
+ setActiveIndex(0);
2405
+ }, [search]);
2406
+ useEffect(() => {
2407
+ if (!isOpen) setSearch("");
2408
+ }, [isOpen]);
2409
+ let itemIndex = -1;
2410
+ return /* @__PURE__ */ jsx(DialogPrimitive.Root, { open: isOpen, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [
2411
+ /* @__PURE__ */ jsx(DialogPrimitive.Overlay, { className: overlayStyles }),
2412
+ /* @__PURE__ */ jsxs(DialogPrimitive.Content, { className: contentStyles, "aria-label": "Command palette", children: [
2413
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-4", children: [
2414
+ /* @__PURE__ */ jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "var(--color-text-muted)", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "shrink-0", children: [
2415
+ /* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "8" }),
2416
+ /* @__PURE__ */ jsx("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" })
2417
+ ] }),
2418
+ /* @__PURE__ */ jsx(
2419
+ "input",
2420
+ {
2421
+ value: search,
2422
+ onChange: (e) => setSearch(e.target.value),
2423
+ onKeyDown: handleKeyDown,
2424
+ placeholder,
2425
+ className: inputStyles,
2426
+ autoFocus: true
2427
+ }
2428
+ )
2429
+ ] }),
2430
+ /* @__PURE__ */ jsx("div", { ref: listRef, className: listStyles, children: filtered.length === 0 ? /* @__PURE__ */ jsx("div", { className: emptyStyles, children: emptyMessage }) : Array.from(groups.entries()).map(([group, cmds]) => /* @__PURE__ */ jsxs("div", { children: [
2431
+ group && /* @__PURE__ */ jsx("div", { className: groupLabelStyles, children: group }),
2432
+ cmds.map((cmd) => {
2433
+ itemIndex++;
2434
+ const idx = itemIndex;
2435
+ return /* @__PURE__ */ jsxs(
2436
+ "button",
2437
+ {
2438
+ type: "button",
2439
+ className: cn(
2440
+ itemStyles,
2441
+ idx === activeIndex && itemActiveStyles
2442
+ ),
2443
+ onClick: () => {
2444
+ cmd.onAction();
2445
+ setOpen(false);
2446
+ setSearch("");
2447
+ },
2448
+ onMouseEnter: () => setActiveIndex(idx),
2449
+ children: [
2450
+ cmd.icon && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[var(--color-text-muted)]", children: cmd.icon }),
2451
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: cmd.label }),
2452
+ cmd.shortcut && /* @__PURE__ */ jsx("span", { className: shortcutStyles, children: cmd.shortcut.split("+").map((key, i) => /* @__PURE__ */ jsx("kbd", { className: kbdStyles, children: key }, i)) })
2453
+ ]
2454
+ },
2455
+ cmd.id
2456
+ );
2457
+ })
2458
+ ] }, group)) })
2459
+ ] })
2460
+ ] }) });
2461
+ }
2462
+ CommandPalette.displayName = "CommandPalette";
2463
+ var wrapperStyles = "w-full overflow-auto rounded-[var(--radius-lg)] border border-[var(--color-border)]";
2464
+ var tableStyles2 = "w-full border-collapse";
2465
+ var thStyles2 = [
2466
+ "px-4 py-3 text-left text-[var(--text-xs)] font-medium text-[var(--color-text-muted)]",
2467
+ "uppercase tracking-wider bg-[var(--color-bg-secondary)]",
2468
+ "border-b border-[var(--color-border)]"
2469
+ ].join(" ");
2470
+ var tdStyles2 = [
2471
+ "px-4 py-3 text-[var(--text-sm)] text-[var(--color-text-secondary)]",
2472
+ "border-b border-[var(--color-border)]"
2473
+ ].join(" ");
2474
+ var trHoverStyles = "hover:bg-[var(--color-surface-hover)] transition-colors duration-[var(--transition-fast)]";
2475
+ var trSelectedStyles = "bg-[var(--color-primary)]/5";
2476
+ var sortButtonStyles = "inline-flex items-center gap-1 cursor-pointer hover:text-[var(--color-text-primary)] transition-colors";
2477
+ var checkboxStyles = [
2478
+ "h-4 w-4 rounded-[3px] cursor-pointer appearance-none",
2479
+ "border border-[var(--color-border)] bg-[var(--color-surface)]",
2480
+ "checked:bg-[var(--color-primary)] checked:border-[var(--color-primary)]",
2481
+ "transition-all duration-[var(--transition-fast)]"
2482
+ ].join(" ");
2483
+ var emptyRowStyles = "px-4 py-12 text-center text-[var(--text-sm)] text-[var(--color-text-muted)]";
2484
+ function DataTableInner({
2485
+ className,
2486
+ columns,
2487
+ data,
2488
+ sortable = false,
2489
+ onSort,
2490
+ selectable = false,
2491
+ selectedRows: controlledSelected,
2492
+ onSelectionChange,
2493
+ emptyMessage = "No data available.",
2494
+ stickyHeader = false,
2495
+ ...props
2496
+ }, ref) {
2497
+ const [internalSort, setInternalSort] = useState(null);
2498
+ const [internalSelected, setInternalSelected] = useState(/* @__PURE__ */ new Set());
2499
+ const selected = controlledSelected ?? internalSelected;
2500
+ const setSelected = onSelectionChange ?? setInternalSelected;
2501
+ const sortedData = useMemo(() => {
2502
+ if (!internalSort || onSort) return data;
2503
+ return [...data].sort((a, b) => {
2504
+ const aVal = a[internalSort.key];
2505
+ const bVal = b[internalSort.key];
2506
+ const cmp = aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
2507
+ return internalSort.dir === "asc" ? cmp : -cmp;
2508
+ });
2509
+ }, [data, internalSort, onSort]);
2510
+ const handleSort = (key) => {
2511
+ const newDir = internalSort?.key === key && internalSort.dir === "asc" ? "desc" : "asc";
2512
+ setInternalSort({ key, dir: newDir });
2513
+ onSort?.(key, newDir);
2514
+ };
2515
+ const toggleRow = (i) => {
2516
+ const next = new Set(selected);
2517
+ if (next.has(i)) next.delete(i);
2518
+ else next.add(i);
2519
+ setSelected(next);
2520
+ };
2521
+ const toggleAll = () => {
2522
+ if (selected.size === data.length) setSelected(/* @__PURE__ */ new Set());
2523
+ else setSelected(new Set(data.map((_, i) => i)));
2524
+ };
2525
+ return /* @__PURE__ */ jsx("div", { ref, className: cn(wrapperStyles, className), ...props, children: /* @__PURE__ */ jsxs("table", { className: tableStyles2, children: [
2526
+ /* @__PURE__ */ jsx("thead", { className: stickyHeader ? "sticky top-0 z-10" : void 0, children: /* @__PURE__ */ jsxs("tr", { children: [
2527
+ selectable && /* @__PURE__ */ jsx("th", { className: cn(thStyles2, "w-12"), children: /* @__PURE__ */ jsx(
2528
+ "input",
2529
+ {
2530
+ type: "checkbox",
2531
+ checked: data.length > 0 && selected.size === data.length,
2532
+ onChange: toggleAll,
2533
+ className: checkboxStyles
2534
+ }
2535
+ ) }),
2536
+ columns.map((col) => /* @__PURE__ */ jsx(
2537
+ "th",
2538
+ {
2539
+ className: cn(thStyles2, col.align === "center" && "text-center", col.align === "right" && "text-right"),
2540
+ style: col.width ? { width: col.width } : void 0,
2541
+ children: sortable || col.sortable ? /* @__PURE__ */ jsxs("button", { type: "button", className: sortButtonStyles, onClick: () => handleSort(col.key), children: [
2542
+ col.header,
2543
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex flex-col", children: [
2544
+ /* @__PURE__ */ jsx("svg", { width: "8", height: "8", viewBox: "0 0 8 8", className: cn("opacity-30", internalSort?.key === col.key && internalSort.dir === "asc" && "opacity-100"), children: /* @__PURE__ */ jsx("path", { d: "M4 1L7 5H1L4 1Z", fill: "currentColor" }) }),
2545
+ /* @__PURE__ */ jsx("svg", { width: "8", height: "8", viewBox: "0 0 8 8", className: cn("-mt-0.5 opacity-30", internalSort?.key === col.key && internalSort.dir === "desc" && "opacity-100"), children: /* @__PURE__ */ jsx("path", { d: "M4 7L1 3H7L4 7Z", fill: "currentColor" }) })
2546
+ ] })
2547
+ ] }) : col.header
2548
+ },
2549
+ col.key
2550
+ ))
2551
+ ] }) }),
2552
+ /* @__PURE__ */ jsx("tbody", { children: sortedData.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: columns.length + (selectable ? 1 : 0), className: emptyRowStyles, children: emptyMessage }) }) : sortedData.map((row, i) => /* @__PURE__ */ jsxs(
2553
+ "tr",
2554
+ {
2555
+ className: cn(trHoverStyles, selected.has(i) && trSelectedStyles),
2556
+ children: [
2557
+ selectable && /* @__PURE__ */ jsx("td", { className: tdStyles2, children: /* @__PURE__ */ jsx(
2558
+ "input",
2559
+ {
2560
+ type: "checkbox",
2561
+ checked: selected.has(i),
2562
+ onChange: () => toggleRow(i),
2563
+ className: checkboxStyles
2564
+ }
2565
+ ) }),
2566
+ columns.map((col) => /* @__PURE__ */ jsx(
2567
+ "td",
2568
+ {
2569
+ className: cn(tdStyles2, col.align === "center" && "text-center", col.align === "right" && "text-right"),
2570
+ children: col.render ? col.render(row[col.key], row, i) : row[col.key]
2571
+ },
2572
+ col.key
2573
+ ))
2574
+ ]
2575
+ },
2576
+ i
2577
+ )) })
2578
+ ] }) });
2579
+ }
2580
+ var DataTable = forwardRef(DataTableInner);
2581
+ DataTable.displayName = "DataTable";
2582
+ var stepsHorizontalStyles = "flex items-start gap-0";
2583
+ var stepsVerticalStyles = "flex flex-col gap-0";
2584
+ var stepWrapperVerticalStyles = "flex items-start gap-3";
2585
+ var stepCircleBase = [
2586
+ "flex items-center justify-center shrink-0",
2587
+ "h-8 w-8 rounded-full text-[var(--text-xs)] font-medium",
2588
+ "border-2 transition-all duration-[var(--transition-base)]"
2589
+ ].join(" ");
2590
+ var stepCircleComplete = "bg-[var(--color-primary)] border-[var(--color-primary)] text-[var(--color-primary-foreground)]";
2591
+ var stepCircleCurrent = "border-[var(--color-primary)] text-[var(--color-primary)] bg-[var(--color-primary)]/10";
2592
+ var stepCircleUpcoming = "border-[var(--color-border)] text-[var(--color-text-muted)] bg-[var(--color-surface)]";
2593
+ var connectorHorizontalStyles = "flex-1 h-0.5 mx-2 transition-colors duration-[var(--transition-base)]";
2594
+ var connectorVerticalStyles = "w-0.5 ml-[15px] min-h-[24px] transition-colors duration-[var(--transition-base)]";
2595
+ var connectorComplete = "bg-[var(--color-primary)]";
2596
+ var connectorIncomplete = "bg-[var(--color-border)]";
2597
+ var stepTitleStyles = "text-[var(--text-sm)] font-medium text-[var(--color-text-primary)]";
2598
+ var stepDescriptionStyles = "text-[var(--text-xs)] text-[var(--color-text-muted)] mt-0.5";
2599
+ var Steps = forwardRef(
2600
+ ({ className, steps, current, orientation = "horizontal", ...props }, ref) => {
2601
+ const isHorizontal = orientation === "horizontal";
2602
+ return /* @__PURE__ */ jsx(
2603
+ "div",
2604
+ {
2605
+ ref,
2606
+ className: cn(
2607
+ isHorizontal ? stepsHorizontalStyles : stepsVerticalStyles,
2608
+ className
2609
+ ),
2610
+ ...props,
2611
+ children: steps.map((step, i) => {
2612
+ const status = i < current ? "complete" : i === current ? "current" : "upcoming";
2613
+ const isLast = i === steps.length - 1;
2614
+ if (isHorizontal) {
2615
+ return /* @__PURE__ */ jsxs(React26.Fragment, { children: [
2616
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 min-w-0", children: [
2617
+ /* @__PURE__ */ jsx(
2618
+ "div",
2619
+ {
2620
+ className: cn(
2621
+ stepCircleBase,
2622
+ status === "complete" && stepCircleComplete,
2623
+ status === "current" && stepCircleCurrent,
2624
+ status === "upcoming" && stepCircleUpcoming
2625
+ ),
2626
+ children: status === "complete" ? /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" }) }) : step.icon || i + 1
2627
+ }
2628
+ ),
2629
+ /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
2630
+ /* @__PURE__ */ jsx("p", { className: stepTitleStyles, children: step.title }),
2631
+ step.description && /* @__PURE__ */ jsx("p", { className: stepDescriptionStyles, children: step.description })
2632
+ ] })
2633
+ ] }),
2634
+ !isLast && /* @__PURE__ */ jsx("div", { className: cn(
2635
+ connectorHorizontalStyles,
2636
+ "mt-4",
2637
+ i < current ? connectorComplete : connectorIncomplete
2638
+ ) })
2639
+ ] }, i);
2640
+ }
2641
+ return /* @__PURE__ */ jsxs(React26.Fragment, { children: [
2642
+ /* @__PURE__ */ jsxs("div", { className: stepWrapperVerticalStyles, children: [
2643
+ /* @__PURE__ */ jsx(
2644
+ "div",
2645
+ {
2646
+ className: cn(
2647
+ stepCircleBase,
2648
+ status === "complete" && stepCircleComplete,
2649
+ status === "current" && stepCircleCurrent,
2650
+ status === "upcoming" && stepCircleUpcoming
2651
+ ),
2652
+ children: status === "complete" ? /* @__PURE__ */ jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" }) }) : step.icon || i + 1
2653
+ }
2654
+ ),
2655
+ /* @__PURE__ */ jsxs("div", { className: "pt-1", children: [
2656
+ /* @__PURE__ */ jsx("p", { className: stepTitleStyles, children: step.title }),
2657
+ step.description && /* @__PURE__ */ jsx("p", { className: stepDescriptionStyles, children: step.description })
2658
+ ] })
2659
+ ] }),
2660
+ !isLast && /* @__PURE__ */ jsx("div", { className: cn(
2661
+ connectorVerticalStyles,
2662
+ i < current ? connectorComplete : connectorIncomplete
2663
+ ) })
2664
+ ] }, i);
2665
+ })
2666
+ }
2667
+ );
2668
+ }
2669
+ );
2670
+ Steps.displayName = "Steps";
2671
+ var shellStyles = "flex h-screen w-full overflow-hidden bg-[var(--color-bg)]";
2672
+ var mainStyles = "flex-1 flex flex-col overflow-hidden";
2673
+ var contentStyles2 = "flex-1 overflow-auto";
2674
+ var AppShell = forwardRef(
2675
+ ({ className, sidebar, navbar, children, ...props }, ref) => /* @__PURE__ */ jsxs("div", { ref, className: cn(shellStyles, className), ...props, children: [
2676
+ sidebar,
2677
+ /* @__PURE__ */ jsxs("div", { className: mainStyles, children: [
2678
+ navbar,
2679
+ /* @__PURE__ */ jsx("main", { className: contentStyles2, children })
2680
+ ] })
2681
+ ] })
2682
+ );
2683
+ AppShell.displayName = "AppShell";
2684
+
2685
+ // src/components/page-header/page-header.styles.ts
2686
+ var pageHeaderStyles = [
2687
+ "flex items-start justify-between gap-4 pb-6"
2688
+ ].join(" ");
2689
+ var pageHeaderTitleStyles = "text-xl font-semibold text-[var(--color-text-primary)] tracking-tight";
2690
+ var pageHeaderDescriptionStyles = "text-[var(--text-sm)] text-[var(--color-text-muted)] mt-1";
2691
+ var PageHeader = forwardRef(
2692
+ ({ className, title, description, breadcrumbs, actions, ...props }, ref) => /* @__PURE__ */ jsxs("div", { ref, className: cn("w-full", className), ...props, children: [
2693
+ breadcrumbs && /* @__PURE__ */ jsx("div", { className: "mb-3", children: breadcrumbs }),
2694
+ /* @__PURE__ */ jsxs("div", { className: pageHeaderStyles, children: [
2695
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
2696
+ /* @__PURE__ */ jsx("h1", { className: pageHeaderTitleStyles, children: title }),
2697
+ description && /* @__PURE__ */ jsx("p", { className: pageHeaderDescriptionStyles, children: description })
2698
+ ] }),
2699
+ actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 shrink-0", children: actions })
2700
+ ] })
2701
+ ] })
2702
+ );
2703
+ PageHeader.displayName = "PageHeader";
2704
+
2705
+ // src/components/navbar/navbar.styles.ts
2706
+ var navbarStyles = [
2707
+ "flex items-center justify-between h-14 px-6",
2708
+ "bg-[var(--color-surface)] border-b border-[var(--color-border)]",
2709
+ "shrink-0"
2710
+ ].join(" ");
2711
+ var Navbar = forwardRef(
2712
+ ({ className, leftContent, centerContent, rightContent, children, ...props }, ref) => /* @__PURE__ */ jsxs("header", { ref, className: cn(navbarStyles, className), ...props, children: [
2713
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3", children: leftContent }),
2714
+ /* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-center", children: centerContent }),
2715
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3", children: rightContent })
2716
+ ] })
2717
+ );
2718
+ Navbar.displayName = "Navbar";
2719
+
2720
+ // src/components/drawer/drawer.styles.ts
2721
+ var drawerOverlayStyles = [
2722
+ "fixed inset-0 z-[var(--z-overlay)]",
2723
+ "bg-[var(--color-overlay)]",
2724
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0",
2725
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0"
2726
+ ].join(" ");
2727
+ var drawerContentBase = [
2728
+ "fixed z-[var(--z-modal)] bg-[var(--color-surface)]",
2729
+ "border-[var(--color-border)]",
2730
+ "shadow-lg flex flex-col",
2731
+ "focus:outline-none"
2732
+ ].join(" ");
2733
+ var drawerSides = {
2734
+ right: "inset-y-0 right-0 border-l data-[state=open]:animate-in data-[state=open]:slide-in-from-right data-[state=closed]:animate-out data-[state=closed]:slide-out-to-right",
2735
+ left: "inset-y-0 left-0 border-r data-[state=open]:animate-in data-[state=open]:slide-in-from-left data-[state=closed]:animate-out data-[state=closed]:slide-out-to-left",
2736
+ top: "inset-x-0 top-0 border-b data-[state=open]:animate-in data-[state=open]:slide-in-from-top data-[state=closed]:animate-out data-[state=closed]:slide-out-to-top",
2737
+ bottom: "inset-x-0 bottom-0 border-t data-[state=open]:animate-in data-[state=open]:slide-in-from-bottom data-[state=closed]:animate-out data-[state=closed]:slide-out-to-bottom"
2738
+ };
2739
+ var drawerSizes = {
2740
+ right: { sm: "w-[320px]", md: "w-[420px]", lg: "w-[560px]", xl: "w-[720px]", full: "w-screen" },
2741
+ left: { sm: "w-[320px]", md: "w-[420px]", lg: "w-[560px]", xl: "w-[720px]", full: "w-screen" },
2742
+ top: { sm: "h-[200px]", md: "h-[320px]", lg: "h-[480px]", xl: "h-[640px]", full: "h-screen" },
2743
+ bottom: { sm: "h-[200px]", md: "h-[320px]", lg: "h-[480px]", xl: "h-[640px]", full: "h-screen" }
2744
+ };
2745
+ var drawerHeaderStyles = [
2746
+ "flex items-center justify-between px-6 py-4",
2747
+ "border-b border-[var(--color-border)]",
2748
+ "shrink-0"
2749
+ ].join(" ");
2750
+ var drawerTitleStyles = "text-lg font-semibold text-[var(--color-text-primary)]";
2751
+ var drawerDescriptionStyles = "text-[var(--text-sm)] text-[var(--color-text-muted)] mt-1";
2752
+ var drawerBodyStyles = "flex-1 overflow-y-auto p-6";
2753
+ var drawerFooterStyles = [
2754
+ "flex items-center justify-end gap-3 px-6 py-4",
2755
+ "border-t border-[var(--color-border)]",
2756
+ "shrink-0"
2757
+ ].join(" ");
2758
+ var drawerCloseStyles = [
2759
+ "p-1.5 rounded-[var(--radius)]",
2760
+ "text-[var(--color-text-muted)]",
2761
+ "hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)]",
2762
+ "transition-colors duration-[var(--transition-fast)]",
2763
+ "cursor-pointer"
2764
+ ].join(" ");
2765
+ var Drawer = ({ children, ...props }) => /* @__PURE__ */ jsx(DialogPrimitive.Root, { ...props, children });
2766
+ var DrawerTrigger = DialogPrimitive.Trigger;
2767
+ var DrawerClose = DialogPrimitive.Close;
2768
+ var DrawerContent = forwardRef(
2769
+ ({ children, side = "right", size = "md", className }, ref) => /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [
2770
+ /* @__PURE__ */ jsx(DialogPrimitive.Overlay, { className: drawerOverlayStyles }),
2771
+ /* @__PURE__ */ jsx(
2772
+ DialogPrimitive.Content,
2773
+ {
2774
+ ref,
2775
+ className: cn(
2776
+ drawerContentBase,
2777
+ drawerSides[side],
2778
+ drawerSizes[side]?.[size],
2779
+ className
2780
+ ),
2781
+ children
2782
+ }
2783
+ )
2784
+ ] })
2785
+ );
2786
+ DrawerContent.displayName = "DrawerContent";
2787
+ var DrawerHeader = ({
2788
+ children,
2789
+ className,
2790
+ onClose
2791
+ }) => /* @__PURE__ */ jsxs("div", { className: cn(drawerHeaderStyles, className), children: [
2792
+ /* @__PURE__ */ jsx("div", { children }),
2793
+ onClose !== void 0 ? /* @__PURE__ */ jsx("button", { type: "button", onClick: onClose, className: drawerCloseStyles, children: /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2794
+ /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2795
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2796
+ ] }) }) : /* @__PURE__ */ jsx(DialogPrimitive.Close, { className: drawerCloseStyles, children: /* @__PURE__ */ jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2797
+ /* @__PURE__ */ jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2798
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2799
+ ] }) })
2800
+ ] });
2801
+ var DrawerTitle = ({ children, className }) => /* @__PURE__ */ jsx(DialogPrimitive.Title, { className: cn(drawerTitleStyles, className), children });
2802
+ var DrawerDescription = ({ children, className }) => /* @__PURE__ */ jsx(DialogPrimitive.Description, { className: cn(drawerDescriptionStyles, className), children });
2803
+ var DrawerBody = ({ children, className }) => /* @__PURE__ */ jsx("div", { className: cn(drawerBodyStyles, className), children });
2804
+ var DrawerFooter = ({ children, className }) => /* @__PURE__ */ jsx("div", { className: cn(drawerFooterStyles, className), children });
2805
+ Drawer.displayName = "Drawer";
2806
+
2807
+ // src/components/accordion/accordion.styles.ts
2808
+ var accordionStyles = "divide-y divide-[var(--color-border)] border border-[var(--color-border)] rounded-[var(--radius-lg)] overflow-hidden";
2809
+ var accordionItemStyles = "bg-[var(--color-surface)]";
2810
+ var accordionTriggerStyles = [
2811
+ "flex items-center justify-between w-full",
2812
+ "px-4 py-3",
2813
+ "text-[var(--text-sm)] font-medium text-[var(--color-text-primary)]",
2814
+ "hover:bg-[var(--color-surface-hover)]",
2815
+ "transition-colors duration-[var(--transition-fast)]",
2816
+ "cursor-pointer select-none",
2817
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring-color)] focus-visible:ring-inset"
2818
+ ].join(" ");
2819
+ var accordionContentStyles = [
2820
+ "px-4 pb-4 pt-0",
2821
+ "text-[var(--text-sm)] text-[var(--color-text-secondary)]"
2822
+ ].join(" ");
2823
+ var accordionChevronStyles = [
2824
+ "shrink-0 text-[var(--color-text-muted)]",
2825
+ "transition-transform duration-200"
2826
+ ].join(" ");
2827
+ function Accordion({
2828
+ items,
2829
+ type = "single",
2830
+ defaultValue,
2831
+ className
2832
+ }) {
2833
+ const [openItems, setOpenItems] = useState(() => {
2834
+ if (!defaultValue) return /* @__PURE__ */ new Set();
2835
+ return new Set(Array.isArray(defaultValue) ? defaultValue : [defaultValue]);
2836
+ });
2837
+ const toggle = useCallback(
2838
+ (value) => {
2839
+ setOpenItems((prev) => {
2840
+ const next = new Set(prev);
2841
+ if (next.has(value)) {
2842
+ next.delete(value);
2843
+ } else {
2844
+ if (type === "single") {
2845
+ next.clear();
2846
+ }
2847
+ next.add(value);
2848
+ }
2849
+ return next;
2850
+ });
2851
+ },
2852
+ [type]
2853
+ );
2854
+ return /* @__PURE__ */ jsx("div", { className: cn(accordionStyles, className), children: items.map((item) => {
2855
+ const isOpen = openItems.has(item.value);
2856
+ return /* @__PURE__ */ jsxs("div", { className: accordionItemStyles, children: [
2857
+ /* @__PURE__ */ jsxs(
2858
+ "button",
2859
+ {
2860
+ type: "button",
2861
+ onClick: () => !item.disabled && toggle(item.value),
2862
+ disabled: item.disabled,
2863
+ "aria-expanded": isOpen,
2864
+ className: cn(
2865
+ accordionTriggerStyles,
2866
+ item.disabled && "opacity-50 cursor-not-allowed"
2867
+ ),
2868
+ children: [
2869
+ /* @__PURE__ */ jsx("span", { children: item.trigger }),
2870
+ /* @__PURE__ */ jsx(
2871
+ "svg",
2872
+ {
2873
+ width: "16",
2874
+ height: "16",
2875
+ viewBox: "0 0 24 24",
2876
+ fill: "none",
2877
+ stroke: "currentColor",
2878
+ strokeWidth: "2",
2879
+ strokeLinecap: "round",
2880
+ strokeLinejoin: "round",
2881
+ className: cn(
2882
+ accordionChevronStyles,
2883
+ isOpen && "rotate-180"
2884
+ ),
2885
+ children: /* @__PURE__ */ jsx("polyline", { points: "6 9 12 15 18 9" })
2886
+ }
2887
+ )
2888
+ ]
2889
+ }
2890
+ ),
2891
+ /* @__PURE__ */ jsx(
2892
+ "div",
2893
+ {
2894
+ className: "overflow-hidden transition-all duration-200",
2895
+ style: {
2896
+ maxHeight: isOpen ? "1000px" : "0px",
2897
+ opacity: isOpen ? 1 : 0
2898
+ },
2899
+ children: /* @__PURE__ */ jsx("div", { className: accordionContentStyles, children: item.content })
2900
+ }
2901
+ )
2902
+ ] }, item.value);
2903
+ }) });
2904
+ }
2905
+ Accordion.displayName = "Accordion";
2906
+
2907
+ // src/components/slider/slider.styles.ts
2908
+ var sliderTrackStyles = [
2909
+ "relative w-full rounded-full cursor-pointer",
2910
+ "bg-[var(--color-surface-raised)]"
2911
+ ].join(" ");
2912
+ var sliderTrackSizes = {
2913
+ sm: "h-1",
2914
+ md: "h-2",
2915
+ lg: "h-3"
2916
+ };
2917
+ var sliderFillStyles = "absolute left-0 top-0 h-full rounded-full bg-[var(--color-primary)] transition-all duration-75";
2918
+ var sliderThumbStyles = [
2919
+ "absolute top-1/2 -translate-y-1/2 -translate-x-1/2",
2920
+ "rounded-full bg-white border-2 border-[var(--color-primary)]",
2921
+ "shadow-sm cursor-grab active:cursor-grabbing",
2922
+ "transition-shadow duration-[var(--transition-fast)]",
2923
+ "hover:shadow-[0_0_0_4px_var(--color-primary)]/20",
2924
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring-color)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--color-bg)]"
2925
+ ].join(" ");
2926
+ var sliderThumbSizes = {
2927
+ sm: "h-3.5 w-3.5",
2928
+ md: "h-5 w-5",
2929
+ lg: "h-6 w-6"
2930
+ };
2931
+ var sliderLabelStyles = "flex justify-between items-center mb-2 text-[var(--text-sm)] text-[var(--color-text-primary)]";
2932
+ var sliderValueStyles = "text-[var(--text-xs)] font-medium text-[var(--color-text-secondary)] tabular-nums";
2933
+ function Slider({
2934
+ value = 0,
2935
+ onChange,
2936
+ min = 0,
2937
+ max = 100,
2938
+ step = 1,
2939
+ label,
2940
+ showValue = false,
2941
+ formatValue = (v) => String(v),
2942
+ size = "md",
2943
+ disabled = false,
2944
+ className
2945
+ }) {
2946
+ const trackRef = useRef(null);
2947
+ const [isDragging, setIsDragging] = useState(false);
2948
+ const clamp = (val) => Math.min(max, Math.max(min, val));
2949
+ const snap = (val) => Math.round((val - min) / step) * step + min;
2950
+ const percent = (clamp(value) - min) / (max - min) * 100;
2951
+ const getValueFromPosition = useCallback(
2952
+ (clientX) => {
2953
+ const track = trackRef.current;
2954
+ if (!track) return value;
2955
+ const rect = track.getBoundingClientRect();
2956
+ const fraction = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));
2957
+ return snap(clamp(min + fraction * (max - min)));
2958
+ },
2959
+ [min, max, step, value]
2960
+ );
2961
+ const handlePointerDown = useCallback(
2962
+ (e) => {
2963
+ if (disabled) return;
2964
+ e.preventDefault();
2965
+ setIsDragging(true);
2966
+ const newValue = getValueFromPosition(e.clientX);
2967
+ if (newValue !== value) onChange?.(newValue);
2968
+ e.target.setPointerCapture(e.pointerId);
2969
+ },
2970
+ [disabled, getValueFromPosition, onChange, value]
2971
+ );
2972
+ const handlePointerMove = useCallback(
2973
+ (e) => {
2974
+ if (!isDragging || disabled) return;
2975
+ const newValue = getValueFromPosition(e.clientX);
2976
+ if (newValue !== value) onChange?.(newValue);
2977
+ },
2978
+ [isDragging, disabled, getValueFromPosition, onChange, value]
2979
+ );
2980
+ const handlePointerUp = useCallback(() => {
2981
+ setIsDragging(false);
2982
+ }, []);
2983
+ const handleKeyDown = useCallback(
2984
+ (e) => {
2985
+ if (disabled) return;
2986
+ let newValue = value;
2987
+ switch (e.key) {
2988
+ case "ArrowRight":
2989
+ case "ArrowUp":
2990
+ newValue = clamp(value + step);
2991
+ break;
2992
+ case "ArrowLeft":
2993
+ case "ArrowDown":
2994
+ newValue = clamp(value - step);
2995
+ break;
2996
+ case "Home":
2997
+ newValue = min;
2998
+ break;
2999
+ case "End":
3000
+ newValue = max;
3001
+ break;
3002
+ default:
3003
+ return;
3004
+ }
3005
+ e.preventDefault();
3006
+ onChange?.(newValue);
3007
+ },
3008
+ [disabled, value, step, min, max, onChange]
3009
+ );
3010
+ return /* @__PURE__ */ jsxs("div", { className: cn("w-full", disabled && "opacity-50 pointer-events-none", className), children: [
3011
+ (label || showValue) && /* @__PURE__ */ jsxs("div", { className: sliderLabelStyles, children: [
3012
+ label && /* @__PURE__ */ jsx("span", { children: label }),
3013
+ showValue && /* @__PURE__ */ jsx("span", { className: sliderValueStyles, children: formatValue(clamp(value)) })
3014
+ ] }),
3015
+ /* @__PURE__ */ jsxs(
3016
+ "div",
3017
+ {
3018
+ ref: trackRef,
3019
+ className: cn(sliderTrackStyles, sliderTrackSizes[size]),
3020
+ onPointerDown: handlePointerDown,
3021
+ onPointerMove: handlePointerMove,
3022
+ onPointerUp: handlePointerUp,
3023
+ children: [
3024
+ /* @__PURE__ */ jsx(
3025
+ "div",
3026
+ {
3027
+ className: sliderFillStyles,
3028
+ style: { width: `${percent}%` }
3029
+ }
3030
+ ),
3031
+ /* @__PURE__ */ jsx(
3032
+ "div",
3033
+ {
3034
+ role: "slider",
3035
+ tabIndex: disabled ? -1 : 0,
3036
+ "aria-valuemin": min,
3037
+ "aria-valuemax": max,
3038
+ "aria-valuenow": clamp(value),
3039
+ "aria-label": label,
3040
+ className: cn(sliderThumbStyles, sliderThumbSizes[size]),
3041
+ style: { left: `${percent}%` },
3042
+ onKeyDown: handleKeyDown
3043
+ }
3044
+ )
3045
+ ]
3046
+ }
3047
+ )
3048
+ ] });
3049
+ }
3050
+ Slider.displayName = "Slider";
3051
+ var sizeMap = {
3052
+ xs: { dimension: "h-6 w-6", text: "text-[10px]", overlap: "-ml-1.5" },
3053
+ sm: { dimension: "h-8 w-8", text: "text-[var(--text-xs)]", overlap: "-ml-2" },
3054
+ md: { dimension: "h-10 w-10", text: "text-[var(--text-sm)]", overlap: "-ml-2.5" },
3055
+ lg: { dimension: "h-12 w-12", text: "text-[var(--text-sm)]", overlap: "-ml-3" },
3056
+ xl: { dimension: "h-16 w-16", text: "text-[var(--text-base)]", overlap: "-ml-4" }
3057
+ };
3058
+ function AvatarGroup({ children, max = 5, size = "md", className }) {
3059
+ const childArray = React26.Children.toArray(children);
3060
+ const visible = childArray.slice(0, max);
3061
+ const overflow = childArray.length - max;
3062
+ const s = sizeMap[size] || sizeMap.md;
3063
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center", className), children: [
3064
+ visible.map((child, i) => /* @__PURE__ */ jsx(
3065
+ "div",
3066
+ {
3067
+ className: cn(
3068
+ i > 0 && s.overlap,
3069
+ "ring-2 ring-[var(--color-bg)] rounded-full"
3070
+ ),
3071
+ children: child
3072
+ },
3073
+ i
3074
+ )),
3075
+ overflow > 0 && /* @__PURE__ */ jsxs(
3076
+ "div",
3077
+ {
3078
+ className: cn(
3079
+ s.overlap,
3080
+ s.dimension,
3081
+ s.text,
3082
+ "inline-flex items-center justify-center",
3083
+ "rounded-full font-medium",
3084
+ "bg-[var(--color-surface-raised)] text-[var(--color-text-secondary)]",
3085
+ "border-2 border-[var(--color-bg)]"
3086
+ ),
3087
+ children: [
3088
+ "+",
3089
+ overflow
3090
+ ]
3091
+ }
3092
+ )
3093
+ ] });
3094
+ }
3095
+ AvatarGroup.displayName = "AvatarGroup";
3096
+ var overlayStyles2 = [
3097
+ "fixed inset-0 z-[var(--z-overlay)]",
3098
+ "bg-[var(--color-overlay)]",
3099
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0",
3100
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0"
3101
+ ].join(" ");
3102
+ var contentStyles3 = [
3103
+ "fixed left-1/2 top-1/2 z-[var(--z-modal)]",
3104
+ "-translate-x-1/2 -translate-y-1/2",
3105
+ "w-full max-w-md p-6",
3106
+ "rounded-[var(--radius-lg)]",
3107
+ "bg-[var(--color-surface)] border border-[var(--color-border)]",
3108
+ "shadow-lg",
3109
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
3110
+ "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
3111
+ "focus:outline-none"
3112
+ ].join(" ");
3113
+ var titleStyles = "text-lg font-semibold text-[var(--color-text-primary)]";
3114
+ var descriptionStyles = "mt-2 text-[var(--text-sm)] text-[var(--color-text-muted)] leading-relaxed";
3115
+ var actionsStyles = "mt-6 flex items-center justify-end gap-3";
3116
+ var cancelBtnStyles = [
3117
+ "inline-flex items-center justify-center h-9 px-4",
3118
+ "text-[var(--text-sm)] font-medium",
3119
+ "rounded-[var(--radius)]",
3120
+ "bg-transparent border border-[var(--color-border)]",
3121
+ "text-[var(--color-text-secondary)]",
3122
+ "hover:bg-[var(--color-surface-hover)] hover:text-[var(--color-text-primary)]",
3123
+ "transition-colors duration-[var(--transition-fast)]",
3124
+ "cursor-pointer"
3125
+ ].join(" ");
3126
+ var confirmBtnBase = [
3127
+ "inline-flex items-center justify-center h-9 px-4",
3128
+ "text-[var(--text-sm)] font-medium",
3129
+ "rounded-[var(--radius)]",
3130
+ "text-white",
3131
+ "transition-colors duration-[var(--transition-fast)]",
3132
+ "disabled:opacity-50 disabled:pointer-events-none",
3133
+ "cursor-pointer"
3134
+ ].join(" ");
3135
+ var confirmBtnVariants = {
3136
+ danger: "bg-[var(--color-danger)] hover:bg-[var(--color-danger)]/90",
3137
+ primary: "bg-[var(--color-primary)] hover:bg-[var(--color-primary-hover)]"
3138
+ };
3139
+ function ConfirmDialog({
3140
+ open,
3141
+ onOpenChange,
3142
+ title,
3143
+ description,
3144
+ confirmText = "Confirm",
3145
+ cancelText = "Cancel",
3146
+ variant = "danger",
3147
+ onConfirm,
3148
+ onCancel,
3149
+ trigger,
3150
+ loading = false
3151
+ }) {
3152
+ return /* @__PURE__ */ jsxs(AlertDialogPrimitive.Root, { open, onOpenChange, children: [
3153
+ trigger && /* @__PURE__ */ jsx(AlertDialogPrimitive.Trigger, { asChild: true, children: trigger }),
3154
+ /* @__PURE__ */ jsxs(AlertDialogPrimitive.Portal, { children: [
3155
+ /* @__PURE__ */ jsx(AlertDialogPrimitive.Overlay, { className: overlayStyles2 }),
3156
+ /* @__PURE__ */ jsxs(AlertDialogPrimitive.Content, { className: contentStyles3, children: [
3157
+ /* @__PURE__ */ jsx(AlertDialogPrimitive.Title, { className: titleStyles, children: title }),
3158
+ description && /* @__PURE__ */ jsx(AlertDialogPrimitive.Description, { className: descriptionStyles, children: description }),
3159
+ /* @__PURE__ */ jsxs("div", { className: actionsStyles, children: [
3160
+ /* @__PURE__ */ jsx(
3161
+ AlertDialogPrimitive.Cancel,
3162
+ {
3163
+ className: cancelBtnStyles,
3164
+ onClick: onCancel,
3165
+ children: cancelText
3166
+ }
3167
+ ),
3168
+ /* @__PURE__ */ jsxs(
3169
+ AlertDialogPrimitive.Action,
3170
+ {
3171
+ className: cn(confirmBtnBase, confirmBtnVariants[variant]),
3172
+ onClick: onConfirm,
3173
+ disabled: loading,
3174
+ children: [
3175
+ loading && /* @__PURE__ */ jsxs("svg", { className: "animate-spin h-4 w-4 mr-2", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
3176
+ /* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
3177
+ /* @__PURE__ */ jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
3178
+ ] }),
3179
+ confirmText
3180
+ ]
3181
+ }
3182
+ )
3183
+ ] })
3184
+ ] })
3185
+ ] })
3186
+ ] });
3187
+ }
3188
+ ConfirmDialog.displayName = "ConfirmDialog";
732
3189
 
733
- export { Badge, Button, Card, CardBody, CardFooter, CardHeader, Dropdown, DropdownContent, DropdownGroup, DropdownItem, DropdownLabel, DropdownSeparator, DropdownTrigger, Input, Modal, ModalContent, ModalDescription, ModalFooter, ModalTitle, ModalTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarItem, SidebarSection, SidebarToggle, Table, TableWrapper, Tabs, TabsContent, TabsList, TabsTrigger, Tbody, Td, Th, Thead, Tr, badgeVariants, buttonVariants, cardVariants, cn, inputVariants, useSidebar };
3190
+ export { Accordion, Alert, AppShell, Avatar, AvatarGroup, Badge, Breadcrumb, BreadcrumbItem, Button, Card, CardBody, CardFooter, CardHeader, Checkbox, Combobox, CommandPalette, ConfirmDialog, DataTable, Drawer, DrawerBody, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger, Dropdown, DropdownContent, DropdownGroup, DropdownItem, DropdownLabel, DropdownSeparator, DropdownTrigger, EmptyState, Input, Modal, ModalContent, ModalDescription, ModalFooter, ModalTitle, ModalTrigger, Navbar, PageHeader, Pagination, Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger, Progress, Radio, RadioGroup, Select, Separator, Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarItem, SidebarSection, SidebarToggle, Skeleton, Slider, StatCard, Steps, Switch, Table, TableWrapper, Tabs, TabsContent, TabsList, TabsTrigger, Tbody, Td, Textarea, Th, Thead, ThemeProvider, ToastProvider, Tooltip, TooltipProvider, Tr, badgeVariants, buttonVariants, cardVariants, cn, inputVariants, textareaVariants, useSidebar, useTheme, useToast };
734
3191
  //# sourceMappingURL=index.js.map
735
3192
  //# sourceMappingURL=index.js.map