react-ui-suite 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,65 +1,44 @@
1
+ // index.ts
2
+ import "./utility-vars-EJQQEY4Z.css";
3
+ import "./tokens-SXYSRKNB.css";
4
+ import "./layout-safety-HVFX63T3.css";
5
+
1
6
  // components/Alert/Alert.tsx
2
7
  import * as React from "react";
3
- import { twMerge } from "tailwind-merge";
8
+ import clsx from "clsx";
9
+ import "./Alert-AVVBZ6TP.css";
4
10
  import { jsx, jsxs } from "react/jsx-runtime";
5
- var variantStyles = {
6
- info: {
7
- container: "bg-sky-50 text-sky-900 ring-1 ring-sky-100 dark:bg-sky-500/10 dark:text-sky-100",
8
- accent: "bg-sky-400",
9
- icon: "\u2139\uFE0F"
10
- },
11
- success: {
12
- container: "bg-emerald-50 text-emerald-900 ring-1 ring-emerald-100 dark:bg-emerald-500/10 dark:text-emerald-100",
13
- accent: "bg-emerald-400",
14
- icon: "\u2714\uFE0F"
15
- },
16
- warning: {
17
- container: "bg-amber-50 text-amber-900 ring-1 ring-amber-100 dark:bg-amber-400/10 dark:text-amber-100",
18
- accent: "bg-amber-400",
19
- icon: "\u26A0\uFE0F"
20
- },
21
- danger: {
22
- container: "bg-rose-50 text-rose-900 ring-1 ring-rose-100 dark:bg-rose-500/10 dark:text-rose-100",
23
- accent: "bg-rose-400",
24
- icon: "\u26D4"
25
- }
11
+ var variantIcons = {
12
+ info: "\u2139\uFE0F",
13
+ success: "\u2705",
14
+ warning: "\u26A0\uFE0F",
15
+ danger: "\u26D4"
26
16
  };
27
17
  var Alert = React.forwardRef(function Alert2({ title, description, variant = "info", onDismiss, className, ...rest }, ref) {
28
- const style = variantStyles[variant];
29
18
  return /* @__PURE__ */ jsxs(
30
19
  "div",
31
20
  {
32
21
  ...rest,
33
22
  ref,
34
23
  role: "alert",
35
- className: twMerge(
36
- "relative flex items-start gap-3 rounded-2xl px-4 py-3 text-sm shadow-sm",
37
- style.container,
38
- className
39
- ),
24
+ className: clsx("rui-alert", "rui-root", "rui-surface", `rui-alert--${variant}`, className),
40
25
  children: [
41
- /* @__PURE__ */ jsx("span", { className: "mt-[2px] text-base", "aria-hidden": "true", children: style.icon }),
42
- /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
43
- /* @__PURE__ */ jsx("p", { className: "font-semibold", children: title }),
44
- description ? /* @__PURE__ */ jsx("p", { className: "text-sm/relaxed opacity-90", children: description }) : null
26
+ /* @__PURE__ */ jsx("span", { className: "rui-alert__icon", "aria-hidden": "true", children: variantIcons[variant] }),
27
+ /* @__PURE__ */ jsxs("div", { className: "rui-alert__content", children: [
28
+ /* @__PURE__ */ jsx("p", { className: "rui-alert__title rui-text-wrap", children: title }),
29
+ description ? /* @__PURE__ */ jsx("p", { className: "rui-alert__description rui-text-wrap", children: description }) : null
45
30
  ] }),
46
31
  onDismiss ? /* @__PURE__ */ jsx(
47
32
  "button",
48
33
  {
49
34
  type: "button",
50
35
  onClick: onDismiss,
51
- className: "rounded-full p-1 text-xs font-semibold uppercase tracking-wide text-current/70 hover:text-current focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent",
36
+ className: "rui-alert__dismiss",
52
37
  "aria-label": "Dismiss alert",
53
38
  children: "\xD7"
54
39
  }
55
40
  ) : null,
56
- /* @__PURE__ */ jsx(
57
- "span",
58
- {
59
- className: twMerge("absolute inset-y-2 left-1 w-1 rounded-full", style.accent),
60
- "aria-hidden": "true"
61
- }
62
- )
41
+ /* @__PURE__ */ jsx("span", { className: "rui-alert__accent", "aria-hidden": "true" })
63
42
  ]
64
43
  }
65
44
  );
@@ -67,26 +46,16 @@ var Alert = React.forwardRef(function Alert2({ title, description, variant = "in
67
46
 
68
47
  // components/Badge/Badge.tsx
69
48
  import * as React2 from "react";
70
- import { twMerge as twMerge2 } from "tailwind-merge";
49
+ import clsx2 from "clsx";
50
+ import "./Badge-FPJ2X7KC.css";
71
51
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
72
- var variantClasses = {
73
- neutral: "bg-slate-100 text-slate-700 ring-1 ring-slate-200 dark:bg-zinc-900/60 dark:text-zinc-100 dark:ring-zinc-700/60",
74
- info: "bg-sky-50 text-sky-700 ring-1 ring-sky-200 dark:bg-sky-500/10 dark:text-sky-300",
75
- success: "bg-emerald-50 text-emerald-700 ring-1 ring-emerald-200 dark:bg-emerald-500/10 dark:text-emerald-300",
76
- warning: "bg-amber-50 text-amber-700 ring-1 ring-amber-200 dark:bg-amber-500/10 dark:text-amber-200",
77
- danger: "bg-rose-50 text-rose-700 ring-1 ring-rose-200 dark:bg-rose-500/10 dark:text-rose-300"
78
- };
79
52
  var Badge = React2.forwardRef(function Badge2({ variant = "neutral", icon, className, children, ...rest }, ref) {
80
53
  return /* @__PURE__ */ jsxs2(
81
54
  "span",
82
55
  {
83
56
  ...rest,
84
57
  ref,
85
- className: twMerge2(
86
- "inline-flex items-center gap-1 rounded-full px-3 py-1 text-[0.7rem] font-semibold uppercase tracking-wide",
87
- variantClasses[variant],
88
- className
89
- ),
58
+ className: clsx2("rui-badge", "rui-root", "rui-text-wrap", `rui-badge--${variant}`, className),
90
59
  children: [
91
60
  icon ? /* @__PURE__ */ jsx2("span", { "aria-hidden": "true", children: icon }) : null,
92
61
  children
@@ -96,21 +65,20 @@ var Badge = React2.forwardRef(function Badge2({ variant = "neutral", icon, class
96
65
  });
97
66
 
98
67
  // components/Button/Button.tsx
99
- import { twMerge as twMerge3 } from "tailwind-merge";
68
+ import clsx3 from "clsx";
69
+ import "./Button-S5BQ425L.css";
100
70
  import { jsx as jsx3 } from "react/jsx-runtime";
101
71
  function Button({
102
72
  children,
103
73
  onClick,
104
74
  disabled = false,
105
- className = "",
75
+ className,
106
76
  type = "button",
107
77
  style,
108
78
  ...rest
109
79
  }) {
110
80
  const hasCustomBackground = typeof className === "string" && /bg-/.test(className);
111
81
  const hasCustomText = typeof className === "string" && /text-/.test(className);
112
- const backgroundClasses = hasCustomBackground ? "" : "bg-white hover:bg-slate-100 dark:bg-zinc-900/70 dark:hover:bg-zinc-800";
113
- const textClasses = hasCustomText ? "" : "text-slate-900 dark:text-zinc-100";
114
82
  return /* @__PURE__ */ jsx3(
115
83
  "button",
116
84
  {
@@ -119,13 +87,11 @@ function Button({
119
87
  disabled,
120
88
  style,
121
89
  ...rest,
122
- className: twMerge3(
123
- "inline-flex items-center justify-center gap-2 rounded-xl border border-slate-300 px-4 py-2 text-sm font-semibold shadow-sm transition",
124
- backgroundClasses,
125
- textClasses,
126
- "hover:border-slate-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-500",
127
- "disabled:cursor-not-allowed disabled:opacity-60",
128
- "dark:border-zinc-700/60 dark:hover:border-zinc-500 dark:shadow-slate-950/20",
90
+ className: clsx3(
91
+ "rui-button",
92
+ "rui-root",
93
+ !hasCustomBackground && "rui-button--bg-default",
94
+ !hasCustomText && "rui-button--text-default",
129
95
  className
130
96
  ),
131
97
  children
@@ -135,37 +101,34 @@ function Button({
135
101
 
136
102
  // components/Card/Card.tsx
137
103
  import * as React3 from "react";
138
- import { twMerge as twMerge4 } from "tailwind-merge";
104
+ import clsx4 from "clsx";
105
+ import "./Card-SS7L6RAU.css";
139
106
  import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
140
107
  var Card = React3.forwardRef(function Card2({ eyebrow, title, actions, children, footer, muted, className, ...rest }, ref) {
141
- const hasHeader = eyebrow || actions;
108
+ const hasHeader = Boolean(eyebrow || actions);
142
109
  return /* @__PURE__ */ jsxs3(
143
110
  "div",
144
111
  {
145
112
  ...rest,
146
113
  ref,
147
- className: twMerge4(
148
- "flex h-full flex-col rounded-3xl border border-slate-200 bg-white p-5 shadow-lg shadow-slate-200/40 dark:border-zinc-700/60 dark:bg-zinc-900/70 dark:shadow-none",
149
- muted && "bg-slate-50/70 dark:bg-zinc-900/40",
150
- className
151
- ),
114
+ className: clsx4("rui-card", "rui-root", "rui-surface", muted && "rui-card--muted", className),
152
115
  children: [
153
- hasHeader && /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between gap-4", children: [
154
- eyebrow ? /* @__PURE__ */ jsx4("p", { className: "text-xs font-semibold uppercase tracking-[0.2em] text-slate-400 dark:text-zinc-400", children: eyebrow }) : /* @__PURE__ */ jsx4("span", {}),
155
- actions ? /* @__PURE__ */ jsx4("div", { className: "text-sm text-slate-500 dark:text-zinc-400", children: actions }) : null
116
+ hasHeader && /* @__PURE__ */ jsxs3("div", { className: "rui-card__header", children: [
117
+ eyebrow ? /* @__PURE__ */ jsx4("p", { className: "rui-card__eyebrow rui-text-wrap", children: eyebrow }) : /* @__PURE__ */ jsx4("p", { className: "rui-card__eyebrow rui-text-wrap rui-card__eyebrow--placeholder", children: "Eyebrow" }),
118
+ actions ? /* @__PURE__ */ jsx4("div", { className: "rui-card__actions", children: actions }) : null
156
119
  ] }),
157
120
  title ? /* @__PURE__ */ jsx4(
158
121
  "h3",
159
122
  {
160
- className: twMerge4(
161
- "text-lg font-semibold text-slate-900 dark:text-zinc-100",
162
- hasHeader ? "mt-3" : "mt-0"
123
+ className: clsx4(
124
+ "rui-card__title rui-text-wrap",
125
+ hasHeader && "rui-card__title--offset"
163
126
  ),
164
127
  children: title
165
128
  }
166
129
  ) : null,
167
- children ? /* @__PURE__ */ jsx4("div", { className: "mt-3 flex-1 text-sm text-slate-600 dark:text-zinc-300", children }) : null,
168
- footer ? /* @__PURE__ */ jsx4("div", { className: "mt-4 border-t border-slate-100 pt-3 text-xs text-slate-500 dark:border-zinc-800 dark:text-zinc-400", children: footer }) : null
130
+ children ? /* @__PURE__ */ jsx4("div", { className: "rui-card__body rui-text-wrap", children }) : null,
131
+ footer ? /* @__PURE__ */ jsx4("div", { className: "rui-card__footer rui-text-wrap", children: footer }) : null
169
132
  ]
170
133
  }
171
134
  );
@@ -173,7 +136,6 @@ var Card = React3.forwardRef(function Card2({ eyebrow, title, actions, children,
173
136
 
174
137
  // components/Checkbox/Checkbox.tsx
175
138
  import * as React4 from "react";
176
- import { twMerge as twMerge5 } from "tailwind-merge";
177
139
 
178
140
  // components/Combobox/icons.tsx
179
141
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
@@ -223,6 +185,8 @@ function assignRef(ref, value) {
223
185
  }
224
186
 
225
187
  // components/Checkbox/Checkbox.tsx
188
+ import clsx5 from "clsx";
189
+ import "./Checkbox-DH24P7XS.css";
226
190
  import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
227
191
  var Checkbox = React4.forwardRef(function Checkbox2({
228
192
  label,
@@ -233,6 +197,10 @@ var Checkbox = React4.forwardRef(function Checkbox2({
233
197
  disabled,
234
198
  className,
235
199
  indeterminate,
200
+ uncheckedBoxColor,
201
+ checkedBoxColor,
202
+ uncheckedBorderColor,
203
+ checkedBorderColor,
236
204
  id,
237
205
  ...rest
238
206
  }, forwardedRef) {
@@ -265,14 +233,20 @@ var Checkbox = React4.forwardRef(function Checkbox2({
265
233
  "label",
266
234
  {
267
235
  htmlFor: checkboxId,
268
- className: twMerge5(
269
- "flex cursor-pointer gap-3 rounded-2xl border border-transparent px-2 py-2 text-left transition hover:bg-slate-50 dark:hover:bg-zinc-900/60",
270
- "items-center",
271
- disabled && "cursor-not-allowed opacity-60",
236
+ className: clsx5(
237
+ "rui-root",
238
+ "rui-checkbox",
239
+ disabled && "rui-checkbox--disabled",
272
240
  className
273
241
  ),
242
+ style: {
243
+ "--rui-checkbox-box-bg": uncheckedBoxColor,
244
+ "--rui-checkbox-box-bg-checked": checkedBoxColor,
245
+ "--rui-checkbox-box-border": uncheckedBorderColor,
246
+ "--rui-checkbox-box-border-checked": checkedBorderColor
247
+ },
274
248
  children: [
275
- /* @__PURE__ */ jsxs5("span", { className: "flex h-6 w-6 items-center justify-center", children: [
249
+ /* @__PURE__ */ jsxs5("span", { className: "rui-checkbox__control", children: [
276
250
  /* @__PURE__ */ jsx6(
277
251
  "input",
278
252
  {
@@ -280,7 +254,7 @@ var Checkbox = React4.forwardRef(function Checkbox2({
280
254
  ref: mergedRef,
281
255
  id: checkboxId,
282
256
  type: "checkbox",
283
- className: "peer sr-only",
257
+ className: "rui-checkbox__input",
284
258
  checked: resolvedChecked,
285
259
  onChange: handleChange,
286
260
  disabled
@@ -289,18 +263,19 @@ var Checkbox = React4.forwardRef(function Checkbox2({
289
263
  /* @__PURE__ */ jsx6(
290
264
  "span",
291
265
  {
292
- className: twMerge5(
293
- "grid size-5 place-items-center rounded-lg border border-slate-300 bg-white text-[0.65rem] font-semibold text-slate-600 transition drop-shadow-sm peer-focus-visible:outline peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-slate-400 dark:border-zinc-600 dark:bg-zinc-950/70 dark:text-zinc-200",
294
- resolvedChecked && "border-slate-400 bg-slate-100 text-slate-900 shadow-[0_0_0_1px_rgba(148,163,184,0.45)] dark:border-zinc-500 dark:bg-zinc-500 dark:text-white"
266
+ className: clsx5(
267
+ "rui-checkbox__box",
268
+ resolvedChecked && "rui-checkbox__box--checked",
269
+ indeterminate && !resolvedChecked && "rui-checkbox__box--indeterminate"
295
270
  ),
296
271
  "aria-hidden": "true",
297
- children: resolvedChecked ? /* @__PURE__ */ jsx6(Check, { className: "h-3 w-3" }) : indeterminate ? /* @__PURE__ */ jsx6("span", { className: "h-[2px] w-2 rounded-full bg-current" }) : null
272
+ children: resolvedChecked ? /* @__PURE__ */ jsx6(Check, { className: "rui-checkbox__check" }) : indeterminate ? /* @__PURE__ */ jsx6("span", { className: "rui-checkbox__dash" }) : null
298
273
  }
299
274
  )
300
275
  ] }),
301
- /* @__PURE__ */ jsxs5("span", { className: "flex flex-1 flex-col", children: [
302
- /* @__PURE__ */ jsx6("span", { className: "text-sm font-semibold text-slate-900 dark:text-zinc-100", children: label }),
303
- description ? /* @__PURE__ */ jsx6("span", { className: "text-xs text-slate-500 dark:text-zinc-400", children: description }) : null
276
+ /* @__PURE__ */ jsxs5("span", { className: "rui-checkbox__text", children: [
277
+ /* @__PURE__ */ jsx6("span", { className: "rui-checkbox__label rui-text-wrap", children: label }),
278
+ description ? /* @__PURE__ */ jsx6("span", { className: "rui-checkbox__description rui-text-wrap", children: description }) : null
304
279
  ] })
305
280
  ]
306
281
  }
@@ -309,7 +284,8 @@ var Checkbox = React4.forwardRef(function Checkbox2({
309
284
 
310
285
  // components/ColorPicker/ColorPicker.tsx
311
286
  import * as React5 from "react";
312
- import { twMerge as twMerge6 } from "tailwind-merge";
287
+ import clsx6 from "clsx";
288
+ import "./ColorPicker-K6LXYYSW.css";
313
289
  import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
314
290
  var defaultSwatches = ["#0ea5e9", "#22c55e", "#f97316", "#f43f5e", "#6366f1", "#facc15"];
315
291
  var formatOrder = ["hex", "rgb", "hsl"];
@@ -553,6 +529,7 @@ var ColorPicker = React5.forwardRef(
553
529
  const [hue, setHue] = React5.useState(resolvedHsv.h);
554
530
  const [saturation, setSaturation] = React5.useState(resolvedHsv.s);
555
531
  const [valueLevel, setValueLevel] = React5.useState(resolvedHsv.v);
532
+ const lastColorUpdateSource = React5.useRef(null);
556
533
  const generatedId = React5.useId();
557
534
  const inputId = id != null ? id : generatedId;
558
535
  const inputRef = React5.useRef(null);
@@ -572,9 +549,12 @@ var ColorPicker = React5.forwardRef(
572
549
  );
573
550
  const shouldLockHue = (s, v) => s <= 1 || v <= 1;
574
551
  React5.useEffect(() => {
575
- setHue((prev) => shouldLockHue(resolvedHsv.s, resolvedHsv.v) ? prev : resolvedHsv.h);
552
+ if (lastColorUpdateSource.current !== "gradient") {
553
+ setHue((prev) => shouldLockHue(resolvedHsv.s, resolvedHsv.v) ? prev : resolvedHsv.h);
554
+ }
576
555
  setSaturation(resolvedHsv.s);
577
556
  setValueLevel(resolvedHsv.v);
557
+ lastColorUpdateSource.current = null;
578
558
  }, [resolvedHsv.h, resolvedHsv.s, resolvedHsv.v]);
579
559
  React5.useEffect(() => {
580
560
  setSwatchList(normalizedSwatches);
@@ -595,6 +575,7 @@ var ColorPicker = React5.forwardRef(
595
575
  if (!normalized) return;
596
576
  const hsv = hexToHsv(normalized);
597
577
  if (hsv) {
578
+ lastColorUpdateSource.current = "swatch";
598
579
  setHue((prev) => shouldLockHue(hsv.s, hsv.v) ? prev : hsv.h);
599
580
  setSaturation(hsv.s);
600
581
  setValueLevel(hsv.v);
@@ -626,6 +607,7 @@ var ColorPicker = React5.forwardRef(
626
607
  }
627
608
  const parsed = channelsToHex(updated, format);
628
609
  if (parsed) {
610
+ lastColorUpdateSource.current = "channel";
629
611
  applyColor(parsed);
630
612
  }
631
613
  return updated;
@@ -675,6 +657,7 @@ var ColorPicker = React5.forwardRef(
675
657
  const nextV = Math.round((1 - yRatio) * 100);
676
658
  setSaturation(nextS);
677
659
  setValueLevel(nextV);
660
+ lastColorUpdateSource.current = "gradient";
678
661
  applyColor(hsvToHex(hue, nextS, nextV));
679
662
  },
680
663
  [applyColor, hue]
@@ -710,6 +693,7 @@ var ColorPicker = React5.forwardRef(
710
693
  const ratio = clamp((clientX - rect.left) / rect.width, 0, 1);
711
694
  const nextHue = Math.round(ratio * 360);
712
695
  setHue(nextHue);
696
+ lastColorUpdateSource.current = "hue";
713
697
  applyColor(hsvToHex(nextHue, saturation, valueLevel));
714
698
  },
715
699
  [applyColor, saturation, valueLevel]
@@ -745,8 +729,8 @@ var ColorPicker = React5.forwardRef(
745
729
  };
746
730
  }, []);
747
731
  const activeLabels = channelLabels[format];
748
- return /* @__PURE__ */ jsxs6("div", { className: "relative inline-flex flex-col items-center gap-2", children: [
749
- label ? /* @__PURE__ */ jsx7("p", { className: "text-[10px] font-semibold uppercase tracking-[0.3em] text-slate-400 dark:text-zinc-500", children: label }) : null,
732
+ return /* @__PURE__ */ jsxs6("div", { className: "rui-root rui-color-picker", children: [
733
+ label ? /* @__PURE__ */ jsx7("p", { className: "rui-color-picker__label rui-text-wrap", children: label }) : null,
750
734
  /* @__PURE__ */ jsxs6(
751
735
  "button",
752
736
  {
@@ -756,12 +740,12 @@ var ColorPicker = React5.forwardRef(
756
740
  "aria-haspopup": "dialog",
757
741
  "aria-expanded": isOpen,
758
742
  "aria-label": label ? `Adjust ${label}` : "Choose color",
759
- className: "relative inline-flex h-12 w-12 items-center justify-center rounded-full border border-slate-200 bg-white shadow-sm transition hover:shadow-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-400 dark:border-zinc-700 dark:bg-zinc-900",
743
+ className: "rui-color-picker__trigger",
760
744
  children: [
761
745
  /* @__PURE__ */ jsx7(
762
746
  "span",
763
747
  {
764
- className: "absolute inset-1 rounded-full border border-white/30 shadow-inner dark:border-zinc-900/60",
748
+ className: "rui-color-picker__trigger-fill",
765
749
  style: { background: resolvedValue },
766
750
  "aria-hidden": "true"
767
751
  }
@@ -769,7 +753,7 @@ var ColorPicker = React5.forwardRef(
769
753
  /* @__PURE__ */ jsx7(
770
754
  "span",
771
755
  {
772
- className: "relative text-xl drop-shadow-[0_1px_1px_rgba(15,23,42,0.55)]",
756
+ className: "rui-color-picker__trigger-icon",
773
757
  style: { transform: "translateX(0.5px) translateY(-1.5px)" },
774
758
  "aria-hidden": "true",
775
759
  children: "\u{1F3A8}"
@@ -784,15 +768,15 @@ var ColorPicker = React5.forwardRef(
784
768
  ref: panelRef,
785
769
  role: "dialog",
786
770
  "aria-label": label ? `${label} color picker` : "Color picker dialog",
787
- className: "absolute left-1/2 top-full z-20 mt-3 w-[340px] max-w-[90vw] -translate-x-1/2 rounded-2xl border border-slate-200/80 bg-white/95 p-4 shadow-2xl backdrop-blur-sm dark:border-zinc-700/60 dark:bg-zinc-900/95",
788
- children: /* @__PURE__ */ jsxs6("div", { className: "space-y-4", children: [
789
- /* @__PURE__ */ jsxs6("div", { className: "space-y-3", children: [
771
+ className: "rui-color-picker__panel",
772
+ children: /* @__PURE__ */ jsxs6("div", { className: "rui-color-picker__panel-body", children: [
773
+ /* @__PURE__ */ jsxs6("div", { className: "rui-color-picker__gradient-section", children: [
790
774
  /* @__PURE__ */ jsx7(
791
775
  "div",
792
776
  {
793
777
  ref: gradientRef,
794
778
  onPointerDown: handleGradientPointerDown,
795
- className: "relative h-40 w-full cursor-crosshair overflow-hidden rounded-xl shadow-[inset_0_1px_2px_rgba(15,23,42,.25)] ring-1 ring-black/5 dark:ring-white/10",
779
+ className: "rui-color-picker__gradient",
796
780
  style: {
797
781
  backgroundColor: `hsl(${hue}, 100%, 50%)`,
798
782
  backgroundImage: "linear-gradient(to top, rgba(0,0,0,1), rgba(0,0,0,0)), linear-gradient(to right, #fff, rgba(255,255,255,0))"
@@ -801,7 +785,7 @@ var ColorPicker = React5.forwardRef(
801
785
  children: /* @__PURE__ */ jsx7(
802
786
  "span",
803
787
  {
804
- className: "pointer-events-none absolute h-4 w-4 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white shadow-[0_1px_2px_rgba(15,23,42,.4)]",
788
+ className: "rui-color-picker__gradient-thumb",
805
789
  style: {
806
790
  left: `${saturation}%`,
807
791
  top: `${100 - valueLevel}%`,
@@ -816,7 +800,7 @@ var ColorPicker = React5.forwardRef(
816
800
  {
817
801
  ref: hueRef,
818
802
  onPointerDown: handleHuePointerDown,
819
- className: "relative h-3 w-full cursor-pointer rounded-full border border-white/40 shadow-inner dark:border-zinc-800/60",
803
+ className: "rui-color-picker__hue",
820
804
  style: {
821
805
  background: "linear-gradient(90deg, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00)"
822
806
  },
@@ -824,69 +808,73 @@ var ColorPicker = React5.forwardRef(
824
808
  children: /* @__PURE__ */ jsx7(
825
809
  "span",
826
810
  {
827
- className: "pointer-events-none absolute top-1/2 h-5 w-2 -translate-x-1/2 -translate-y-1/2 rounded-full border border-slate-900/40 bg-white shadow",
811
+ className: "rui-color-picker__hue-thumb",
828
812
  style: { left: `${hue / 360 * 100}%` }
829
813
  }
830
814
  )
831
815
  }
832
816
  )
833
817
  ] }),
834
- /* @__PURE__ */ jsxs6("div", { className: "flex flex-wrap items-center gap-2", children: [
835
- swatchList.map((color) => /* @__PURE__ */ jsxs6("div", { className: "relative group", children: [
836
- /* @__PURE__ */ jsx7(
837
- "button",
838
- {
839
- type: "button",
840
- onClick: () => handleSwatchClick(color),
841
- className: twMerge6(
842
- "h-7 w-7 rounded-full border border-white/30 transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-400 dark:border-zinc-900/70",
843
- color.toLowerCase() === resolvedValue.toLowerCase() && "ring-2 ring-offset-2 ring-slate-500 dark:ring-offset-slate-900"
844
- ),
845
- style: { background: color },
846
- "aria-label": `Select ${color}`
847
- }
848
- ),
849
- /* @__PURE__ */ jsx7(
850
- "button",
851
- {
852
- type: "button",
853
- onClick: () => handleRemoveSwatch(color),
854
- className: "absolute -top-1.5 -right-1.5 hidden h-5 w-5 items-center justify-center rounded-full bg-white text-[10px] font-bold text-slate-600 shadow-sm ring-1 ring-slate-200 transition group-hover:flex group-focus-within:flex dark:bg-zinc-900 dark:text-zinc-200 dark:ring-zinc-700",
855
- "aria-label": `Remove ${color} swatch`,
856
- children: "\xD7"
857
- }
858
- )
859
- ] }, color)),
818
+ /* @__PURE__ */ jsxs6("div", { className: "rui-color-picker__swatch-row", children: [
819
+ swatchList.map((color) => {
820
+ const isActive = color.toLowerCase() === resolvedValue.toLowerCase();
821
+ return /* @__PURE__ */ jsxs6("div", { className: "rui-color-picker__swatch", children: [
822
+ /* @__PURE__ */ jsx7(
823
+ "button",
824
+ {
825
+ type: "button",
826
+ onClick: () => handleSwatchClick(color),
827
+ className: clsx6(
828
+ "rui-color-picker__swatch-button",
829
+ isActive && "rui-color-picker__swatch-button--active"
830
+ ),
831
+ style: { background: color },
832
+ "aria-label": `Select ${color}`
833
+ }
834
+ ),
835
+ /* @__PURE__ */ jsx7(
836
+ "button",
837
+ {
838
+ type: "button",
839
+ onClick: () => handleRemoveSwatch(color),
840
+ className: "rui-color-picker__swatch-remove",
841
+ "aria-label": `Remove ${color} swatch`,
842
+ children: "\xD7"
843
+ }
844
+ )
845
+ ] }, color);
846
+ }),
860
847
  /* @__PURE__ */ jsx7(
861
848
  "button",
862
849
  {
863
850
  type: "button",
864
851
  onClick: handleAddSwatch,
865
- className: "inline-flex h-7 items-center gap-1 rounded-full border border-dashed border-slate-300 px-3 text-xs font-semibold uppercase tracking-wide text-slate-500 transition hover:border-slate-400 hover:text-slate-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-400 dark:border-zinc-600 dark:text-zinc-300 dark:hover:border-zinc-500",
866
- children: "+ Add swatch"
852
+ className: "rui-color-picker__add-swatch",
853
+ "aria-label": "+ Add swatch",
854
+ children: "+"
867
855
  }
868
856
  )
869
857
  ] }),
870
- /* @__PURE__ */ jsxs6("div", { className: "space-y-2", children: [
871
- /* @__PURE__ */ jsxs6("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
872
- /* @__PURE__ */ jsx7("p", { className: "text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-400 dark:text-zinc-500", children: "Channels" }),
873
- /* @__PURE__ */ jsx7("div", { className: "inline-flex overflow-hidden rounded-xl border border-slate-200 bg-white/80 text-[11px] font-semibold uppercase text-slate-500 dark:border-zinc-700 dark:bg-zinc-900/80 dark:text-zinc-300", children: formatOrder.map((option) => /* @__PURE__ */ jsx7(
858
+ /* @__PURE__ */ jsxs6("div", { className: "rui-color-picker__channels", children: [
859
+ /* @__PURE__ */ jsxs6("div", { className: "rui-color-picker__channels-header", children: [
860
+ /* @__PURE__ */ jsx7("span", { children: "Channels" }),
861
+ /* @__PURE__ */ jsx7("div", { className: "rui-color-picker__format-toggle", children: formatOrder.map((option) => /* @__PURE__ */ jsx7(
874
862
  "button",
875
863
  {
876
864
  type: "button",
877
865
  onClick: () => setFormat(option),
878
866
  "aria-pressed": format === option,
879
- className: twMerge6(
880
- "px-3 py-1.5 transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-400/60",
881
- format === option ? "bg-white text-slate-900 shadow-[inset_0_0_0_1px_rgba(15,23,42,0.08)] dark:bg-white/15 dark:text-white" : "text-slate-500 dark:text-zinc-400"
867
+ className: clsx6(
868
+ "rui-color-picker__format-button",
869
+ format === option && "is-active"
882
870
  ),
883
871
  children: option.toUpperCase()
884
872
  },
885
873
  option
886
874
  )) })
887
875
  ] }),
888
- /* @__PURE__ */ jsx7("div", { className: "flex flex-wrap gap-2", children: format === "hex" ? /* @__PURE__ */ jsxs6("label", { className: "flex min-w-[180px] flex-1 items-center gap-2 rounded-xl border border-slate-200 bg-white/60 px-3 py-1.5 font-mono text-sm text-slate-900 focus-within:border-slate-400 dark:border-zinc-700 dark:bg-zinc-900/70 dark:text-zinc-100", children: [
889
- /* @__PURE__ */ jsx7("span", { className: "text-base font-semibold text-slate-400 dark:text-zinc-500", children: "#" }),
876
+ /* @__PURE__ */ jsx7("div", { className: "rui-color-picker__channel-grid", children: format === "hex" ? /* @__PURE__ */ jsxs6("label", { className: "rui-color-picker__channel-field rui-color-picker__channel-field--hex", children: [
877
+ /* @__PURE__ */ jsx7("span", { className: "rui-color-picker__channel-prefix", children: "#" }),
890
878
  /* @__PURE__ */ jsx7(
891
879
  "input",
892
880
  {
@@ -896,15 +884,15 @@ var ColorPicker = React5.forwardRef(
896
884
  onBlur: resetChannels,
897
885
  inputMode: "text",
898
886
  maxLength: 6,
899
- className: "h-6 min-w-0 flex-1 border-none bg-transparent p-0 text-left text-sm uppercase tracking-[0.2em] text-slate-900 placeholder:text-slate-400 focus:outline-none dark:text-zinc-50"
887
+ className: "rui-color-picker__channel-input rui-color-picker__channel-input--hex"
900
888
  }
901
889
  )
902
890
  ] }) : channelValues.map((value2, index) => /* @__PURE__ */ jsxs6(
903
891
  "label",
904
892
  {
905
- className: "flex min-w-[90px] flex-1 items-center gap-2 rounded-xl border border-slate-200 bg-white/60 px-3 py-1.5 font-mono text-sm text-slate-900 focus-within:border-slate-400 dark:border-zinc-700 dark:bg-zinc-900/70 dark:text-zinc-100",
893
+ className: "rui-color-picker__channel-field",
906
894
  children: [
907
- /* @__PURE__ */ jsx7("span", { className: "text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-400 dark:text-zinc-500", children: activeLabels[index] }),
895
+ /* @__PURE__ */ jsx7("span", { className: "rui-color-picker__channel-prefix", children: activeLabels[index] }),
908
896
  /* @__PURE__ */ jsx7(
909
897
  "input",
910
898
  {
@@ -913,7 +901,7 @@ var ColorPicker = React5.forwardRef(
913
901
  onChange: (event) => handleChannelChange(index, event.target.value),
914
902
  onBlur: resetChannels,
915
903
  inputMode: "numeric",
916
- className: "h-6 min-w-0 flex-1 border-none bg-transparent p-0 text-right text-sm text-slate-900 placeholder:text-slate-400 focus:outline-none dark:text-zinc-50"
904
+ className: "rui-color-picker__channel-input"
917
905
  }
918
906
  )
919
907
  ]
@@ -942,11 +930,11 @@ var ColorPicker = React5.forwardRef(
942
930
 
943
931
  // components/Combobox/Combobox.tsx
944
932
  import * as React9 from "react";
945
- import { twMerge as twMerge10 } from "tailwind-merge";
946
933
 
947
934
  // components/Dropdown/Dropdown.tsx
948
935
  import * as React6 from "react";
949
- import { twMerge as twMerge7 } from "tailwind-merge";
936
+ import clsx7 from "clsx";
937
+ import "./Dropdown-RQAPUZUJ.css";
950
938
  import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
951
939
  var Dropdown = React6.forwardRef(
952
940
  ({
@@ -978,32 +966,28 @@ var Dropdown = React6.forwardRef(
978
966
  onChevronClick,
979
967
  children
980
968
  }, ref) => {
981
- const focusClasses = !isOpen ? "focus-within:border-slate-400 focus-within:shadow-[0_0_0_1px_rgba(148,163,184,0.45)] dark:focus-within:border-slate-500" : "";
982
- const buttonClasses = "inline-flex h-9 w-10 items-center justify-center rounded-xl bg-transparent text-sm text-slate-600 transition focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 dark:text-zinc-200";
983
- const inputClasses = twMerge7(
984
- "w-full bg-transparent text-sm text-slate-900 placeholder:text-slate-400 focus:outline-none dark:text-zinc-100 dark:placeholder:text-zinc-500",
985
- inputClassName,
986
- inputProps == null ? void 0 : inputProps.className
987
- );
969
+ const focusClasses = !isOpen ? "rui-dropdown__focusWhenClosed" : "";
970
+ const buttonClasses = "rui-dropdown__chevronButton";
971
+ const inputClasses = clsx7("rui-dropdown__input", inputClassName, inputProps == null ? void 0 : inputProps.className);
988
972
  const mergedPlaceholder = placeholder != null ? placeholder : inputProps == null ? void 0 : inputProps.placeholder;
989
973
  const mergedAriaLabel = ariaLabel != null ? ariaLabel : inputProps == null ? void 0 : inputProps["aria-label"];
990
- return /* @__PURE__ */ jsxs7("div", { ref, className: twMerge7("relative w-full", className), children: [
974
+ return /* @__PURE__ */ jsxs7("div", { ref, className: clsx7("rui-dropdown", "rui-root", className), children: [
991
975
  /* @__PURE__ */ jsxs7(
992
976
  "div",
993
977
  {
994
978
  onKeyDownCapture,
995
- onMouseDown: onShellMouseDown,
979
+ onPointerDown: onShellMouseDown,
996
980
  onFocusCapture: onShellFocusCapture,
997
981
  onBlurCapture: onShellBlurCapture,
998
- className: twMerge7(
999
- "flex h-11 items-center gap-1 rounded-2xl border border-slate-300 bg-white pl-3 pr-1 text-slate-900 shadow-sm transition dark:border-zinc-700/60 dark:bg-zinc-900/70 dark:text-zinc-100",
982
+ className: clsx7(
983
+ "rui-dropdown__shell",
1000
984
  focusClasses,
1001
- isOpen && twMerge7("rounded-b-none border-b-0 dark:border-b-0", highlightClass),
1002
- disabled && "opacity-60",
985
+ isOpen && clsx7("rui-dropdown__shell--open", highlightClass),
986
+ disabled && "rui-dropdown__shell--disabled",
1003
987
  shellClassName
1004
988
  ),
1005
989
  children: [
1006
- leadingContent ? /* @__PURE__ */ jsx8("div", { className: "flex items-center", children: leadingContent }) : null,
990
+ leadingContent ? /* @__PURE__ */ jsx8("div", { className: "rui-dropdown__leading", children: leadingContent }) : null,
1007
991
  /* @__PURE__ */ jsx8(
1008
992
  "input",
1009
993
  {
@@ -1016,8 +1000,8 @@ var Dropdown = React6.forwardRef(
1016
1000
  "aria-activedescendant": ariaActiveDescendant,
1017
1001
  "aria-label": mergedAriaLabel,
1018
1002
  disabled: !!disabled || (inputProps == null ? void 0 : inputProps.disabled),
1019
- readOnly: !isOpen,
1020
- onMouseDown: onInputMouseDown,
1003
+ readOnly: !isOpen || !onInputChange,
1004
+ onPointerDown: onInputMouseDown,
1021
1005
  value: isOpen ? query : displayValue,
1022
1006
  onFocus: onInputFocus,
1023
1007
  onChange: onInputChange,
@@ -1025,7 +1009,7 @@ var Dropdown = React6.forwardRef(
1025
1009
  className: inputClasses
1026
1010
  }
1027
1011
  ),
1028
- inlineContent ? /* @__PURE__ */ jsx8("div", { className: "flex items-center gap-2", children: inlineContent }) : null,
1012
+ inlineContent ? /* @__PURE__ */ jsx8("div", { className: "rui-dropdown__inline", children: inlineContent }) : null,
1029
1013
  showChevron ? /* @__PURE__ */ jsx8(
1030
1014
  "button",
1031
1015
  {
@@ -1038,7 +1022,7 @@ var Dropdown = React6.forwardRef(
1038
1022
  children: /* @__PURE__ */ jsx8(
1039
1023
  ChevronDown,
1040
1024
  {
1041
- className: twMerge7("size-4 transition-transform", isOpen && "rotate-180")
1025
+ className: clsx7("rui-dropdown__chevronIcon", isOpen && "rui-dropdown__chevronIcon--open")
1042
1026
  }
1043
1027
  )
1044
1028
  }
@@ -1054,10 +1038,21 @@ Dropdown.displayName = "Dropdown";
1054
1038
 
1055
1039
  // components/Popover/Popover.tsx
1056
1040
  import * as React7 from "react";
1057
- import { twMerge as twMerge8 } from "tailwind-merge";
1041
+ import { createPortal } from "react-dom";
1042
+ import clsx8 from "clsx";
1043
+ import "./Popover-UQEO2HLP.css";
1058
1044
  import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1059
1045
  var MIN_THUMB_SIZE = 28;
1060
1046
  var TRACK_PADDING = 6;
1047
+ function getAnchorPosition(anchor) {
1048
+ if (!anchor) return null;
1049
+ const rect = anchor.getBoundingClientRect();
1050
+ return {
1051
+ top: rect.bottom - 1,
1052
+ left: rect.left,
1053
+ width: rect.width
1054
+ };
1055
+ }
1061
1056
  function Scrollbar({ scrollRef }) {
1062
1057
  const [{ visible, size, offset }, setThumbState] = React7.useState({
1063
1058
  visible: false,
@@ -1163,16 +1158,16 @@ function Scrollbar({ scrollRef }) {
1163
1158
  "div",
1164
1159
  {
1165
1160
  "aria-hidden": "true",
1166
- className: "pointer-events-none absolute inset-y-[6px] right-[2px] flex w-3 justify-center",
1161
+ className: "rui-popover__scrollbar",
1167
1162
  children: /* @__PURE__ */ jsx9(
1168
1163
  "div",
1169
1164
  {
1170
- className: "pointer-events-auto relative h-full w-1 rounded-full bg-slate-900/5 shadow-inner dark:bg-white/10",
1165
+ className: "rui-popover__scrollbar-track",
1171
1166
  onPointerDown: handleTrackPointerDown,
1172
1167
  children: /* @__PURE__ */ jsx9(
1173
1168
  "div",
1174
1169
  {
1175
- className: "pointer-events-auto absolute left-1/2 w-1.5 -translate-x-1/2 rounded-full bg-slate-400/80 shadow-sm transition-colors dark:bg-zinc-200/70",
1170
+ className: "rui-popover__scrollbar-thumb",
1176
1171
  style: { height: `${size}px`, top: `${offset}px` },
1177
1172
  onPointerDown: handleThumbPointerDown
1178
1173
  }
@@ -1182,21 +1177,56 @@ function Scrollbar({ scrollRef }) {
1182
1177
  }
1183
1178
  );
1184
1179
  }
1185
- function Popover({ className, children }) {
1180
+ function Popover({ className, anchorRef, rootRef, children }) {
1186
1181
  const scrollRef = React7.useRef(null);
1187
- return /* @__PURE__ */ jsx9(
1182
+ const [position, setPosition] = React7.useState(
1183
+ () => {
1184
+ var _a;
1185
+ return getAnchorPosition((_a = anchorRef == null ? void 0 : anchorRef.current) != null ? _a : null);
1186
+ }
1187
+ );
1188
+ const shouldPortal = Boolean(anchorRef) && typeof document !== "undefined";
1189
+ React7.useLayoutEffect(() => {
1190
+ if (!(anchorRef == null ? void 0 : anchorRef.current)) return;
1191
+ let raf = 0;
1192
+ const update = () => {
1193
+ cancelAnimationFrame(raf);
1194
+ raf = window.requestAnimationFrame(() => {
1195
+ setPosition(getAnchorPosition(anchorRef.current));
1196
+ });
1197
+ };
1198
+ update();
1199
+ const onScroll = () => update();
1200
+ window.addEventListener("resize", update);
1201
+ window.addEventListener("scroll", onScroll, true);
1202
+ const observer = typeof ResizeObserver !== "undefined" ? new ResizeObserver(update) : null;
1203
+ observer == null ? void 0 : observer.observe(anchorRef.current);
1204
+ return () => {
1205
+ window.removeEventListener("resize", update);
1206
+ window.removeEventListener("scroll", onScroll, true);
1207
+ observer == null ? void 0 : observer.disconnect();
1208
+ cancelAnimationFrame(raf);
1209
+ };
1210
+ }, [anchorRef]);
1211
+ const popoverStyle = shouldPortal ? position ? { top: position.top, left: position.left, width: position.width } : { visibility: "hidden" } : void 0;
1212
+ const popover = /* @__PURE__ */ jsx9(
1188
1213
  "div",
1189
1214
  {
1190
- className: twMerge8(
1191
- "absolute left-0 right-0 top-full z-[999] -mt-px rounded-b-2xl rounded-t-none border border-slate-300 bg-white/95 py-1 shadow-xl shadow-slate-200/60 backdrop-blur dark:border-zinc-600 dark:bg-zinc-900/95 dark:shadow-zinc-900/40",
1215
+ ref: rootRef,
1216
+ className: clsx8(
1217
+ "rui-popover",
1218
+ "rui-overlay-root",
1219
+ shouldPortal && "rui-popover--portal",
1192
1220
  className
1193
1221
  ),
1194
- children: /* @__PURE__ */ jsxs8("div", { className: "relative", children: [
1222
+ style: popoverStyle,
1223
+ children: /* @__PURE__ */ jsxs8("div", { className: "rui-popover__inner", children: [
1195
1224
  children({ scrollRef }),
1196
1225
  /* @__PURE__ */ jsx9(Scrollbar, { scrollRef })
1197
1226
  ] })
1198
1227
  }
1199
1228
  );
1229
+ return shouldPortal ? createPortal(popover, document.body) : popover;
1200
1230
  }
1201
1231
 
1202
1232
  // components/Combobox/hooks.ts
@@ -1222,14 +1252,15 @@ function useOutsideClick(refs, handler) {
1222
1252
  const inside = refs.some((r) => r.current && r.current.contains(target));
1223
1253
  if (!inside) handler();
1224
1254
  }
1225
- document.addEventListener("mousedown", onDoc);
1226
- return () => document.removeEventListener("mousedown", onDoc);
1255
+ document.addEventListener("pointerdown", onDoc);
1256
+ return () => document.removeEventListener("pointerdown", onDoc);
1227
1257
  }, [refs, handler]);
1228
1258
  }
1229
1259
 
1230
1260
  // components/Combobox/Listbox.tsx
1231
1261
  import * as React8 from "react";
1232
- import { twMerge as twMerge9 } from "tailwind-merge";
1262
+ import clsx9 from "clsx";
1263
+ import "./Combobox-UQBN7KFK.css";
1233
1264
  import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1234
1265
  function Listbox({
1235
1266
  id,
@@ -1254,9 +1285,9 @@ function Listbox({
1254
1285
  ref: listRef,
1255
1286
  id,
1256
1287
  role: "listbox",
1257
- className: twMerge9("combobox-scrollbar max-h-64 overflow-auto px-1 pr-4"),
1288
+ className: clsx9("rui-combobox__listbox"),
1258
1289
  children: [
1259
- options.length === 0 && /* @__PURE__ */ jsx10("li", { "aria-disabled": true, className: "select-none", children: /* @__PURE__ */ jsx10("div", { className: "px-3 py-2 text-sm text-slate-500 dark:text-zinc-500", children: emptyState != null ? emptyState : "No results" }) }),
1290
+ options.length === 0 && /* @__PURE__ */ jsx10("li", { "aria-disabled": true, className: "rui-combobox__empty", children: /* @__PURE__ */ jsx10("div", { className: "rui-combobox__empty-content", children: emptyState != null ? emptyState : "No results" }) }),
1260
1291
  options.map((opt, i) => {
1261
1292
  const selected = opt.id === selectedId;
1262
1293
  const active = i === activeIndex;
@@ -1269,21 +1300,26 @@ function Listbox({
1269
1300
  "aria-selected": selected,
1270
1301
  "aria-disabled": opt.disabled,
1271
1302
  "data-index": i,
1272
- className: "list-none",
1303
+ className: "rui-combobox__option",
1273
1304
  onMouseEnter: () => !opt.disabled && onHoverIndex(i),
1274
- onMouseDown: (e) => e.preventDefault(),
1275
- onClick: () => !opt.disabled && onSelectIndex(i),
1305
+ onPointerDown: (e) => {
1306
+ if (opt.disabled) return;
1307
+ e.preventDefault();
1308
+ e.stopPropagation();
1309
+ onSelectIndex(i);
1310
+ },
1276
1311
  children: renderOption ? renderOption(opt, optionState) : /* @__PURE__ */ jsxs9(
1277
1312
  "div",
1278
1313
  {
1279
- className: twMerge9(
1280
- "flex cursor-pointer items-center gap-3 rounded-xl px-3 py-2 text-sm",
1281
- active ? "bg-slate-100 text-slate-900 dark:bg-zinc-800/70 dark:text-zinc-100" : "text-slate-700 hover:bg-slate-100 dark:text-zinc-200 dark:hover:bg-zinc-800/70",
1282
- opt.disabled && "cursor-not-allowed opacity-50"
1314
+ className: clsx9(
1315
+ "rui-combobox__option-row",
1316
+ active && "rui-combobox__option-row--active",
1317
+ selected && "rui-combobox__option-row--selected",
1318
+ opt.disabled && "rui-combobox__option-row--disabled"
1283
1319
  ),
1284
1320
  children: [
1285
- /* @__PURE__ */ jsx10("span", { className: "truncate", children: opt.label }),
1286
- selected ? /* @__PURE__ */ jsx10(Check, { className: "ml-auto h-3 w-3 text-slate-600 dark:text-zinc-300" }) : /* @__PURE__ */ jsx10("span", { className: "ml-auto inline-flex h-3 w-3" })
1321
+ /* @__PURE__ */ jsx10("span", { className: "rui-combobox__option-label", children: opt.label }),
1322
+ selected ? /* @__PURE__ */ jsx10(Check, { className: "rui-combobox__option-icon" }) : /* @__PURE__ */ jsx10("span", { className: "rui-combobox__option-icon-placeholder" })
1287
1323
  ]
1288
1324
  }
1289
1325
  )
@@ -1297,6 +1333,8 @@ function Listbox({
1297
1333
  }
1298
1334
 
1299
1335
  // components/Combobox/Combobox.tsx
1336
+ import clsx10 from "clsx";
1337
+ import "./Combobox-UQBN7KFK.css";
1300
1338
  import { jsx as jsx11 } from "react/jsx-runtime";
1301
1339
  function InnerCombobox({
1302
1340
  options,
@@ -1318,9 +1356,13 @@ function InnerCombobox({
1318
1356
  const inputRef = React9.useRef(null);
1319
1357
  const containerRef = React9.useRef(null);
1320
1358
  const chevronRef = React9.useRef(null);
1359
+ const popoverRef = React9.useRef(null);
1321
1360
  const outsideClickRefs = React9.useMemo(
1322
- () => [containerRef],
1323
- [containerRef]
1361
+ () => [
1362
+ containerRef,
1363
+ popoverRef
1364
+ ],
1365
+ [containerRef, popoverRef]
1324
1366
  );
1325
1367
  const mergedInputRef = (node) => {
1326
1368
  inputRef.current = node;
@@ -1331,7 +1373,7 @@ function InnerCombobox({
1331
1373
  const [query, setQuery] = React9.useState("");
1332
1374
  const [activeIndex, setActiveIndex] = React9.useState(-1);
1333
1375
  const suppressNextOpenRef = React9.useRef(false);
1334
- const suppressToggleRef = React9.useRef(false);
1376
+ const closeAfterSelectRef = React9.useRef(false);
1335
1377
  const prevOpenRef = React9.useRef(open);
1336
1378
  const [selected, setSelected] = useControlledState(
1337
1379
  valueProp,
@@ -1430,14 +1472,24 @@ function InnerCombobox({
1430
1472
  setOpen(false);
1431
1473
  }
1432
1474
  }, [open]);
1475
+ React9.useEffect(() => {
1476
+ if (!closeAfterSelectRef.current) return;
1477
+ if (open) {
1478
+ setOpen(false);
1479
+ return;
1480
+ }
1481
+ closeAfterSelectRef.current = false;
1482
+ }, [open]);
1433
1483
  useOutsideClick(outsideClickRefs, closeOnOutsideClick);
1434
1484
  function commitSelection(opt, opts = {}) {
1435
1485
  const { refocus = true } = opts;
1486
+ closeAfterSelectRef.current = true;
1436
1487
  setSelected(opt);
1437
1488
  onChange == null ? void 0 : onChange(opt);
1438
1489
  if (opt) setQuery("");
1439
1490
  setOpen(false);
1440
1491
  if (refocus) {
1492
+ suppressNextOpenRef.current = true;
1441
1493
  requestAnimationFrame(() => {
1442
1494
  var _a2;
1443
1495
  return (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
@@ -1513,7 +1565,7 @@ function InnerCombobox({
1513
1565
  }
1514
1566
  const selectedLabel = (_a = selected == null ? void 0 : selected.label) != null ? _a : "";
1515
1567
  const selectedId = (_b = selected == null ? void 0 : selected.id) != null ? _b : null;
1516
- const highlightBorder = "border-slate-400 dark:border-slate-500";
1568
+ const highlightBorder = "rui-combobox__highlightBorder";
1517
1569
  const listboxHighlight = isEffectivelyOpen ? highlightBorder : "";
1518
1570
  function openList() {
1519
1571
  if (disabled) return;
@@ -1546,13 +1598,10 @@ function InnerCombobox({
1546
1598
  chevronRef,
1547
1599
  onKeyDownCapture: onKeyDown,
1548
1600
  onShellMouseDown: (e) => {
1549
- var _a2;
1550
1601
  if (disabled) return;
1551
- if ((_a2 = chevronRef.current) == null ? void 0 : _a2.contains(e.target)) return;
1552
1602
  if (!isEffectivelyOpen) {
1553
1603
  e.preventDefault();
1554
1604
  openList();
1555
- suppressToggleRef.current = true;
1556
1605
  }
1557
1606
  },
1558
1607
  onInputMouseDown: (e) => {
@@ -1582,28 +1631,37 @@ function InnerCombobox({
1582
1631
  },
1583
1632
  onChevronClick: () => {
1584
1633
  if (disabled) return;
1585
- if (suppressToggleRef.current) {
1586
- suppressToggleRef.current = false;
1587
- setOpen((o) => !o);
1634
+ if (!isEffectivelyOpen) {
1635
+ openList();
1588
1636
  return;
1589
1637
  }
1590
- suppressNextOpenRef.current = false;
1591
- setOpen((o) => !o);
1638
+ requestAnimationFrame(() => {
1639
+ var _a2;
1640
+ return (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
1641
+ });
1592
1642
  },
1593
- children: isEffectivelyOpen && /* @__PURE__ */ jsx11(Popover, { className: twMerge10(listboxHighlight, listClassName), children: ({ scrollRef }) => /* @__PURE__ */ jsx11(
1594
- Listbox,
1643
+ children: isEffectivelyOpen && /* @__PURE__ */ jsx11(
1644
+ Popover,
1595
1645
  {
1596
- id: listboxId,
1597
- options: visibleOptions,
1598
- activeIndex,
1599
- selectedId,
1600
- onHoverIndex: setActiveIndex,
1601
- onSelectIndex: (i) => commitSelection(visibleOptions[i]),
1602
- listRef: scrollRef,
1603
- emptyState,
1604
- renderOption
1646
+ anchorRef: containerRef,
1647
+ rootRef: popoverRef,
1648
+ className: clsx10(listboxHighlight, listClassName),
1649
+ children: ({ scrollRef }) => /* @__PURE__ */ jsx11(
1650
+ Listbox,
1651
+ {
1652
+ id: listboxId,
1653
+ options: visibleOptions,
1654
+ activeIndex,
1655
+ selectedId,
1656
+ onHoverIndex: setActiveIndex,
1657
+ onSelectIndex: (i) => commitSelection(visibleOptions[i]),
1658
+ listRef: scrollRef,
1659
+ emptyState,
1660
+ renderOption
1661
+ }
1662
+ )
1605
1663
  }
1606
- ) })
1664
+ )
1607
1665
  }
1608
1666
  );
1609
1667
  }
@@ -1611,7 +1669,8 @@ var Combobox = React9.forwardRef(InnerCombobox);
1611
1669
 
1612
1670
  // components/DatalistInput/DatalistInput.tsx
1613
1671
  import * as React10 from "react";
1614
- import { twMerge as twMerge11 } from "tailwind-merge";
1672
+ import clsx11 from "clsx";
1673
+ import "./DatalistInput-72UMJ3OM.css";
1615
1674
  import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
1616
1675
  var DatalistInput = React10.forwardRef(
1617
1676
  function DatalistInput2({ label, description, options, className, id, disabled, ...rest }, ref) {
@@ -1654,6 +1713,7 @@ var DatalistInput = React10.forwardRef(
1654
1713
  });
1655
1714
  };
1656
1715
  const handleKeyDown = (e) => {
1716
+ if (disabled) return;
1657
1717
  if (!open && (e.key === "ArrowDown" || e.key === "ArrowUp")) {
1658
1718
  setOpen(true);
1659
1719
  setActiveIndex(0);
@@ -1687,6 +1747,7 @@ var DatalistInput = React10.forwardRef(
1687
1747
  };
1688
1748
  const handleInputChange = (e) => {
1689
1749
  var _a2;
1750
+ if (disabled) return;
1690
1751
  setQuery(e.target.value);
1691
1752
  setOpen(true);
1692
1753
  setActiveIndex(0);
@@ -1696,12 +1757,12 @@ var DatalistInput = React10.forwardRef(
1696
1757
  scrollRef.current = node;
1697
1758
  listboxRef.current = node;
1698
1759
  };
1699
- return /* @__PURE__ */ jsxs10("div", { className: "space-y-1.5", children: [
1760
+ return /* @__PURE__ */ jsxs10("div", { className: "rui-datalist-input rui-root", children: [
1700
1761
  label ? /* @__PURE__ */ jsx12(
1701
1762
  "label",
1702
1763
  {
1703
1764
  htmlFor: inputId,
1704
- className: "text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-zinc-400",
1765
+ className: "rui-datalist-input__label rui-text-wrap",
1705
1766
  children: label
1706
1767
  }
1707
1768
  ) : null,
@@ -1716,11 +1777,11 @@ var DatalistInput = React10.forwardRef(
1716
1777
  query: displayValue,
1717
1778
  inputRef: mergedRef,
1718
1779
  showChevron: false,
1719
- inlineContent: /* @__PURE__ */ jsx12("span", { className: "text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-400 dark:text-zinc-500", children: "CMD" }),
1780
+ inlineContent: /* @__PURE__ */ jsx12("span", { className: "rui-datalist-input__inline-key", children: "CMD" }),
1720
1781
  onKeyDownCapture: handleKeyDown,
1721
- onShellMouseDown: () => setOpen(true),
1722
- onInputFocus: () => setOpen(true),
1723
- onInputMouseDown: () => setOpen(true),
1782
+ onShellMouseDown: () => !disabled && setOpen(true),
1783
+ onInputFocus: () => !disabled && setOpen(true),
1784
+ onInputMouseDown: () => !disabled && setOpen(true),
1724
1785
  onInputChange: handleInputChange,
1725
1786
  ariaControls: listboxId,
1726
1787
  ariaActiveDescendant: activeDescendant,
@@ -1731,32 +1792,33 @@ var DatalistInput = React10.forwardRef(
1731
1792
  id: inputId,
1732
1793
  "aria-describedby": description ? descriptionId : rest["aria-describedby"]
1733
1794
  },
1734
- children: open && filtered.length ? /* @__PURE__ */ jsx12(Popover, { children: ({ scrollRef }) => /* @__PURE__ */ jsx12(
1795
+ children: open && filtered.length ? /* @__PURE__ */ jsx12(Popover, { anchorRef: dropdownRef, children: ({ scrollRef }) => /* @__PURE__ */ jsx12(
1735
1796
  "ul",
1736
1797
  {
1737
1798
  ref: (node) => setListRef(node, scrollRef),
1738
1799
  id: listboxId,
1739
1800
  role: "listbox",
1740
- className: "combobox-scrollbar max-h-56 overflow-auto py-1 text-sm text-slate-800 dark:text-zinc-100",
1801
+ className: "rui-datalist-input__list",
1741
1802
  children: filtered.map((opt, index) => /* @__PURE__ */ jsx12(
1742
1803
  "li",
1743
1804
  {
1744
1805
  id: `${listboxId}-option-${index}`,
1745
1806
  role: "option",
1746
1807
  "aria-selected": index === activeIndex,
1808
+ className: "rui-datalist-input__option",
1747
1809
  children: /* @__PURE__ */ jsxs10(
1748
1810
  "button",
1749
1811
  {
1750
1812
  type: "button",
1751
1813
  onMouseEnter: () => setActiveIndex(index),
1752
1814
  onClick: () => handleSelect(opt),
1753
- className: twMerge11(
1754
- "flex w-full items-center gap-3 px-3 py-2 text-left transition hover:bg-slate-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-400/70 dark:hover:bg-zinc-800/60",
1755
- index === activeIndex && "bg-slate-50 dark:bg-zinc-800/60"
1815
+ className: clsx11(
1816
+ "rui-datalist-input__option-button",
1817
+ index === activeIndex && "is-active"
1756
1818
  ),
1757
1819
  children: [
1758
- /* @__PURE__ */ jsx12("span", { className: "text-[10px] uppercase tracking-[0.2em] text-slate-400 dark:text-zinc-500", children: "cmd" }),
1759
- /* @__PURE__ */ jsx12("span", { className: "font-semibold", children: opt })
1820
+ /* @__PURE__ */ jsx12("span", { className: "rui-datalist-input__option-key", children: "cmd" }),
1821
+ /* @__PURE__ */ jsx12("span", { className: "rui-datalist-input__option-text rui-text-truncate", children: opt })
1760
1822
  ]
1761
1823
  }
1762
1824
  )
@@ -1767,18 +1829,18 @@ var DatalistInput = React10.forwardRef(
1767
1829
  ) }) : null
1768
1830
  }
1769
1831
  ),
1770
- description ? /* @__PURE__ */ jsx12("p", { id: descriptionId, className: "text-xs text-slate-500 dark:text-zinc-400", children: description }) : null
1832
+ description ? /* @__PURE__ */ jsx12("p", { id: descriptionId, className: "rui-datalist-input__description rui-text-wrap", children: description }) : null
1771
1833
  ] });
1772
1834
  }
1773
1835
  );
1774
1836
 
1775
1837
  // components/DatePicker/DatePicker.tsx
1776
1838
  import * as React12 from "react";
1777
- import { twMerge as twMerge13 } from "tailwind-merge";
1778
1839
 
1779
1840
  // components/Select/Select.tsx
1780
1841
  import * as React11 from "react";
1781
- import { twMerge as twMerge12 } from "tailwind-merge";
1842
+ import clsx12 from "clsx";
1843
+ import "./Select-UA2CM52H.css";
1782
1844
  import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
1783
1845
  function Select({
1784
1846
  label,
@@ -1928,10 +1990,10 @@ function Select({
1928
1990
  el == null ? void 0 : el.scrollIntoView({ block: "nearest" });
1929
1991
  }, [open, activeIndex]);
1930
1992
  const displayValue = (_b = selectedOption == null ? void 0 : selectedOption.label) != null ? _b : "";
1931
- const highlightBorder = "border-slate-400 dark:border-slate-500";
1993
+ const highlightBorder = "rui-select__highlightBorder";
1932
1994
  const listboxHighlight = open ? highlightBorder : "";
1933
- return /* @__PURE__ */ jsxs11("div", { className: "space-y-1.5", children: [
1934
- label ? /* @__PURE__ */ jsx13("p", { className: "text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-zinc-400", children: label }) : null,
1995
+ return /* @__PURE__ */ jsxs11("div", { className: "rui-select rui-root", children: [
1996
+ label ? /* @__PURE__ */ jsx13("p", { className: "rui-select__label rui-text-wrap", children: label }) : null,
1935
1997
  /* @__PURE__ */ jsx13(
1936
1998
  Dropdown,
1937
1999
  {
@@ -1941,12 +2003,12 @@ function Select({
1941
2003
  placeholder,
1942
2004
  displayValue,
1943
2005
  query: displayValue,
1944
- className: twMerge12(
1945
- "w-full",
1946
- error && "border-rose-300 focus-within:border-rose-400 focus-within:shadow-[0_0_0_1px_rgba(248,113,113,0.35)] dark:border-rose-500/60",
2006
+ className: clsx12(
2007
+ "rui-select__dropdown",
2008
+ error && "rui-select__dropdown--error",
1947
2009
  className
1948
2010
  ),
1949
- inputClassName: "font-semibold",
2011
+ inputClassName: "rui-select__input",
1950
2012
  highlightClass: highlightBorder,
1951
2013
  ariaControls: listboxId,
1952
2014
  ariaLabel: label,
@@ -1987,7 +2049,7 @@ function Select({
1987
2049
  }
1988
2050
  setOpen((o) => !o);
1989
2051
  },
1990
- children: open && /* @__PURE__ */ jsx13(Popover, { className: listboxHighlight, children: ({ scrollRef }) => {
2052
+ children: open && /* @__PURE__ */ jsx13(Popover, { anchorRef: containerRef, className: listboxHighlight, children: ({ scrollRef }) => {
1991
2053
  popoverListRef.current = scrollRef;
1992
2054
  return /* @__PURE__ */ jsx13(
1993
2055
  "ul",
@@ -1995,11 +2057,11 @@ function Select({
1995
2057
  ref: scrollRef,
1996
2058
  id: listboxId,
1997
2059
  role: "listbox",
1998
- className: "combobox-scrollbar max-h-64 overflow-auto px-1 pr-4",
2060
+ className: "rui-select__list",
1999
2061
  children: options.map((opt, index) => {
2000
2062
  const isSelected = selected === opt.value;
2001
2063
  const isActive = activeIndex === index;
2002
- return /* @__PURE__ */ jsx13("li", { className: "list-none", "data-index": index, children: /* @__PURE__ */ jsxs11(
2064
+ return /* @__PURE__ */ jsx13("li", { className: "rui-select__option", "data-index": index, children: /* @__PURE__ */ jsxs11(
2003
2065
  "button",
2004
2066
  {
2005
2067
  type: "button",
@@ -2008,18 +2070,17 @@ function Select({
2008
2070
  disabled: opt.disabled,
2009
2071
  onMouseEnter: () => !opt.disabled && setActiveIndex(index),
2010
2072
  onClick: () => commitSelection(index),
2011
- className: twMerge12(
2012
- "flex w-full items-center gap-3 rounded-xl px-3 py-2 text-left text-sm transition",
2013
- isActive ? "bg-slate-100 text-slate-900 dark:bg-zinc-800/70 dark:text-zinc-100" : "text-slate-700 hover:bg-slate-100 dark:text-zinc-200 dark:hover:bg-zinc-800/70",
2014
- isSelected && "font-semibold",
2015
- opt.disabled && "cursor-not-allowed opacity-50"
2073
+ className: clsx12(
2074
+ "rui-select__option-button",
2075
+ isActive && "rui-select__option-button--active",
2076
+ isSelected && "rui-select__option-button--selected"
2016
2077
  ),
2017
2078
  children: [
2018
- /* @__PURE__ */ jsxs11("span", { className: "flex-1 text-left", children: [
2019
- /* @__PURE__ */ jsx13("span", { className: "block text-slate-900 dark:text-zinc-100", children: opt.label }),
2020
- opt.description ? /* @__PURE__ */ jsx13("span", { className: "block text-xs text-slate-500 dark:text-zinc-400", children: opt.description }) : null
2079
+ /* @__PURE__ */ jsxs11("span", { className: "rui-select__option-content", children: [
2080
+ /* @__PURE__ */ jsx13("span", { className: "rui-select__option-label rui-text-wrap", children: opt.label }),
2081
+ opt.description ? /* @__PURE__ */ jsx13("span", { className: "rui-select__option-description rui-text-wrap", children: opt.description }) : null
2021
2082
  ] }),
2022
- isSelected ? /* @__PURE__ */ jsx13(Check, { className: "ml-auto h-3 w-3 text-slate-600 dark:text-zinc-300" }) : /* @__PURE__ */ jsx13("span", { className: "ml-auto inline-flex h-3 w-3" })
2083
+ isSelected ? /* @__PURE__ */ jsx13(Check, { className: "rui-select__option-check" }) : /* @__PURE__ */ jsx13("span", { className: "rui-select__option-check-placeholder" })
2023
2084
  ]
2024
2085
  }
2025
2086
  ) }, opt.value);
@@ -2029,12 +2090,14 @@ function Select({
2029
2090
  } })
2030
2091
  }
2031
2092
  ),
2032
- description ? /* @__PURE__ */ jsx13("p", { className: "text-xs text-slate-500 dark:text-zinc-400", children: description }) : null,
2033
- error ? /* @__PURE__ */ jsx13("p", { className: "text-xs font-medium text-rose-500 dark:text-rose-400", children: error }) : null
2093
+ description ? /* @__PURE__ */ jsx13("p", { className: "rui-select__description rui-text-wrap", children: description }) : null,
2094
+ error ? /* @__PURE__ */ jsx13("p", { className: "rui-select__error rui-text-wrap", children: error }) : null
2034
2095
  ] });
2035
2096
  }
2036
2097
 
2037
2098
  // components/DatePicker/DatePicker.tsx
2099
+ import clsx13 from "clsx";
2100
+ import "./DatePicker-ICNOIGZ2.css";
2038
2101
  import { Fragment, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
2039
2102
  function formatLocalDateString(year, month, day) {
2040
2103
  const y = String(year).padStart(4, "0");
@@ -2042,7 +2105,10 @@ function formatLocalDateString(year, month, day) {
2042
2105
  const d = String(day).padStart(2, "0");
2043
2106
  return `${y}-${m}-${d}`;
2044
2107
  }
2045
- function parseLocalDateString(value) {
2108
+ function toDateFromParts(mode, year, month, day) {
2109
+ return mode === "utc" ? new Date(Date.UTC(year, month, day)) : new Date(year, month, day);
2110
+ }
2111
+ function parseDateString(value, mode) {
2046
2112
  if (!value) return null;
2047
2113
  const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value.trim());
2048
2114
  if (!match) return null;
@@ -2050,19 +2116,19 @@ function parseLocalDateString(value) {
2050
2116
  const year = Number(y);
2051
2117
  const month = Number(m) - 1;
2052
2118
  const day = Number(d);
2053
- const date = new Date(year, month, day);
2119
+ const date = toDateFromParts(mode, year, month, day);
2054
2120
  if (Number.isNaN(date.getTime())) return null;
2055
2121
  return { date, year, month, day };
2056
2122
  }
2057
- function getMonthDays(year, month) {
2058
- const first = new Date(year, month, 1);
2059
- const start = first.getDay();
2060
- const days = new Date(year, month + 1, 0).getDate();
2123
+ function getMonthDays(year, month, mode) {
2124
+ const first = toDateFromParts(mode, year, month, 1);
2125
+ const start = mode === "utc" ? first.getUTCDay() : first.getDay();
2126
+ const endOfMonth = toDateFromParts(mode, year, month + 1, 0);
2127
+ const days = mode === "utc" ? endOfMonth.getUTCDate() : endOfMonth.getDate();
2061
2128
  const grid = [];
2062
2129
  for (let i = 0; i < start; i += 1) grid.push({ day: null });
2063
2130
  for (let d = 1; d <= days; d += 1) {
2064
- const date = new Date(year, month, d);
2065
- grid.push({ day: d, date: date.toISOString().slice(0, 10) });
2131
+ grid.push({ day: d, date: formatLocalDateString(year, month, d) });
2066
2132
  }
2067
2133
  return grid;
2068
2134
  }
@@ -2077,7 +2143,8 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2077
2143
  onChange,
2078
2144
  type = "date",
2079
2145
  timeIntervalMinutes = 30,
2080
- use24HourClock = true
2146
+ use24HourClock = true,
2147
+ dateMode = "local"
2081
2148
  }, ref) {
2082
2149
  const isDate = type === "date";
2083
2150
  const clampInterval = Math.max(1, Math.min(60, Math.floor(timeIntervalMinutes)));
@@ -2101,7 +2168,7 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2101
2168
  [use24HourClock]
2102
2169
  );
2103
2170
  const initial = (() => {
2104
- var _a, _b, _c;
2171
+ var _a, _b;
2105
2172
  if (!isDate) {
2106
2173
  return (_b = (_a = normalizeTimeString(value)) != null ? _a : normalizeTimeString(defaultValue)) != null ? _b : (() => {
2107
2174
  const now = /* @__PURE__ */ new Date();
@@ -2113,27 +2180,36 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2113
2180
  return `${String(safeH).padStart(2, "0")}:${String(m).padStart(2, "0")}`;
2114
2181
  })();
2115
2182
  }
2116
- const normalized = (_c = parseLocalDateString(value != null ? value : defaultValue)) == null ? void 0 : _c.date;
2117
- if (normalized)
2118
- return formatLocalDateString(
2119
- normalized.getFullYear(),
2120
- normalized.getMonth(),
2121
- normalized.getDate()
2122
- );
2183
+ const normalized = parseDateString(value != null ? value : defaultValue, dateMode);
2184
+ if (normalized) return formatLocalDateString(normalized.year, normalized.month, normalized.day);
2123
2185
  const today = /* @__PURE__ */ new Date();
2124
- return formatLocalDateString(today.getFullYear(), today.getMonth(), today.getDate());
2186
+ const year = dateMode === "utc" ? today.getUTCFullYear() : today.getFullYear();
2187
+ const month2 = dateMode === "utc" ? today.getUTCMonth() : today.getMonth();
2188
+ const day = dateMode === "utc" ? today.getUTCDate() : today.getDate();
2189
+ return formatLocalDateString(year, month2, day);
2125
2190
  })();
2126
2191
  const [open, setOpen] = React12.useState(false);
2127
2192
  const [current, setCurrent] = React12.useState(initial);
2128
2193
  const [month, setMonth] = React12.useState(() => {
2129
- var _a, _b;
2130
- const base = (_b = (_a = parseLocalDateString(initial)) == null ? void 0 : _a.date) != null ? _b : /* @__PURE__ */ new Date();
2131
- return { year: base.getFullYear(), month: base.getMonth() };
2194
+ var _a;
2195
+ const parsed = (_a = parseDateString(initial, dateMode)) == null ? void 0 : _a.date;
2196
+ if (parsed) {
2197
+ return {
2198
+ year: dateMode === "utc" ? parsed.getUTCFullYear() : parsed.getFullYear(),
2199
+ month: dateMode === "utc" ? parsed.getUTCMonth() : parsed.getMonth()
2200
+ };
2201
+ }
2202
+ const now = /* @__PURE__ */ new Date();
2203
+ return {
2204
+ year: dateMode === "utc" ? now.getUTCFullYear() : now.getFullYear(),
2205
+ month: dateMode === "utc" ? now.getUTCMonth() : now.getMonth()
2206
+ };
2132
2207
  });
2133
2208
  const [viewMode, setViewMode] = React12.useState("day");
2134
2209
  const dropdownRef = React12.useRef(null);
2135
2210
  const toggleRef = React12.useRef(null);
2136
2211
  const inputInnerRef = React12.useRef(null);
2212
+ const popoverRef = React12.useRef(null);
2137
2213
  const suppressToggleRef = React12.useRef(false);
2138
2214
  const canvasRef = React12.useRef(null);
2139
2215
  const [useShortLabel, setUseShortLabel] = React12.useState(false);
@@ -2146,10 +2222,14 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2146
2222
  },
2147
2223
  [ref]
2148
2224
  );
2149
- useOutsideClick(
2150
- [dropdownRef],
2151
- () => setOpen(false)
2225
+ const outsideClickRefs = React12.useMemo(
2226
+ () => [
2227
+ dropdownRef,
2228
+ popoverRef
2229
+ ],
2230
+ []
2152
2231
  );
2232
+ useOutsideClick(outsideClickRefs, () => setOpen(false));
2153
2233
  const commit = (next) => {
2154
2234
  setCurrent(next);
2155
2235
  onChange == null ? void 0 : onChange(next);
@@ -2158,26 +2238,28 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2158
2238
  };
2159
2239
  const parsedDate = React12.useMemo(() => {
2160
2240
  var _a;
2161
- const parsed = parseLocalDateString(current);
2241
+ const parsed = parseDateString(current, dateMode);
2162
2242
  return (_a = parsed == null ? void 0 : parsed.date) != null ? _a : null;
2163
- }, [current]);
2243
+ }, [current, dateMode]);
2164
2244
  const longDisplayLabel = React12.useMemo(() => {
2165
2245
  if (!parsedDate) return current;
2166
2246
  return parsedDate.toLocaleDateString(void 0, {
2167
2247
  weekday: "short",
2168
2248
  month: "short",
2169
2249
  day: "numeric",
2170
- year: "numeric"
2250
+ year: "numeric",
2251
+ timeZone: dateMode === "utc" ? "UTC" : void 0
2171
2252
  });
2172
- }, [parsedDate, current]);
2253
+ }, [parsedDate, current, dateMode]);
2173
2254
  const shortDisplayLabel = React12.useMemo(() => {
2174
2255
  if (!parsedDate) return current;
2175
2256
  return parsedDate.toLocaleDateString(void 0, {
2176
2257
  month: "2-digit",
2177
2258
  day: "2-digit",
2178
- year: "2-digit"
2259
+ year: "2-digit",
2260
+ timeZone: dateMode === "utc" ? "UTC" : void 0
2179
2261
  });
2180
- }, [parsedDate, current]);
2262
+ }, [parsedDate, current, dateMode]);
2181
2263
  const displayLabel = useShortLabel ? shortDisplayLabel : longDisplayLabel;
2182
2264
  const timeOptions = React12.useMemo(() => {
2183
2265
  const opts = [];
@@ -2191,7 +2273,7 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2191
2273
  }
2192
2274
  return opts;
2193
2275
  }, [clampInterval, formatTimeLabel]);
2194
- const highlightBorder = "border-slate-400 shadow-[0_0_0_1px_rgba(148,163,184,0.45)] dark:border-slate-500";
2276
+ const highlightBorder = "rui-date-picker__highlightBorder";
2195
2277
  const monthNames = React12.useMemo(
2196
2278
  () => ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
2197
2279
  []
@@ -2223,14 +2305,18 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2223
2305
  };
2224
2306
  const rangeStart = decadeStart - 1;
2225
2307
  const rangeEnd = decadeStart + 10;
2226
- const headerLabel = viewMode === "year" ? `${rangeStart} - ${rangeEnd}` : viewMode === "month" ? `${month.year}` : new Date(month.year, month.month).toLocaleString("default", {
2308
+ const headerLabel = viewMode === "year" ? `${rangeStart} - ${rangeEnd}` : viewMode === "month" ? `${month.year}` : toDateFromParts(dateMode, month.year, month.month, 1).toLocaleString("default", {
2227
2309
  month: "long",
2228
- year: "numeric"
2310
+ year: "numeric",
2311
+ timeZone: dateMode === "utc" ? "UTC" : void 0
2229
2312
  });
2230
2313
  function openPicker() {
2231
2314
  if (disabled) return;
2232
2315
  const base = parsedDate != null ? parsedDate : /* @__PURE__ */ new Date();
2233
- setMonth({ year: base.getFullYear(), month: base.getMonth() });
2316
+ setMonth({
2317
+ year: dateMode === "utc" ? base.getUTCFullYear() : base.getFullYear(),
2318
+ month: dateMode === "utc" ? base.getUTCMonth() : base.getMonth()
2319
+ });
2234
2320
  setViewMode("day");
2235
2321
  setOpen(true);
2236
2322
  }
@@ -2279,13 +2365,13 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2279
2365
  placeholder: "Select time",
2280
2366
  disabled,
2281
2367
  className,
2282
- leadingContent: /* @__PURE__ */ jsx14("span", { className: "pointer-events-none rounded-xl bg-slate-100 px-2 py-1 shadow-inner dark:bg-zinc-800/70", children: /* @__PURE__ */ jsx14(Clock, { className: "h-4 w-4 text-slate-500 dark:text-zinc-300" }) })
2368
+ leadingContent: /* @__PURE__ */ jsx14("span", { className: "rui-date-picker__leading-icon", children: /* @__PURE__ */ jsx14(Clock, { className: "rui-date-picker__leading-icon-mark" }) })
2283
2369
  }
2284
2370
  );
2285
2371
  }
2286
- return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
2287
- label ? /* @__PURE__ */ jsx14("p", { className: "text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-zinc-400", children: label }) : null,
2288
- /* @__PURE__ */ jsx14("div", { className: "relative", children: /* @__PURE__ */ jsx14(
2372
+ return /* @__PURE__ */ jsxs12("div", { className: "rui-date-picker rui-root", children: [
2373
+ label ? /* @__PURE__ */ jsx14("p", { className: "rui-date-picker__label rui-text-wrap", children: label }) : null,
2374
+ /* @__PURE__ */ jsx14("div", { className: "rui-date-picker__field", children: /* @__PURE__ */ jsx14(
2289
2375
  Dropdown,
2290
2376
  {
2291
2377
  ref: dropdownRef,
@@ -2294,12 +2380,12 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2294
2380
  placeholder: "",
2295
2381
  displayValue: displayLabel,
2296
2382
  query: displayLabel,
2297
- className: "w-full",
2298
- inputClassName: twMerge13("min-w-0 font-semibold", className),
2299
- shellClassName: twMerge13(
2300
- error && "border-rose-300 focus-within:border-rose-400 focus-within:shadow-[0_0_0_1px_rgba(248,113,113,0.35)] dark:border-rose-500/60"
2383
+ className: "rui-date-picker__dropdown",
2384
+ inputClassName: clsx13("rui-date-picker__input", className),
2385
+ shellClassName: clsx13(
2386
+ error && "rui-date-picker__shell--error"
2301
2387
  ),
2302
- leadingContent: /* @__PURE__ */ jsx14("span", { className: "pointer-events-none rounded-xl bg-slate-100 px-2 py-1 shadow-inner dark:bg-zinc-800/70", children: /* @__PURE__ */ jsx14(Calendar, { className: "h-4 w-4 text-slate-500 dark:text-zinc-300" }) }),
2388
+ leadingContent: /* @__PURE__ */ jsx14("span", { className: "rui-date-picker__leading-icon", children: /* @__PURE__ */ jsx14(Calendar, { className: "rui-date-picker__leading-icon-mark" }) }),
2303
2389
  highlightClass: highlightBorder,
2304
2390
  ariaControls: popoverId,
2305
2391
  ariaLabel: label,
@@ -2350,109 +2436,118 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2350
2436
  }
2351
2437
  setOpen((o) => !o);
2352
2438
  },
2353
- children: open && /* @__PURE__ */ jsx14(Popover, { className: twMerge13("p-3", highlightBorder), children: () => /* @__PURE__ */ jsxs12("div", { className: "space-y-3", id: popoverId, children: [
2354
- /* @__PURE__ */ jsxs12("div", { className: "flex items-center justify-between text-sm text-slate-600 dark:text-zinc-300", children: [
2355
- /* @__PURE__ */ jsx14(
2356
- Button,
2357
- {
2358
- type: "button",
2359
- onClick: goPrev,
2360
- className: "h-8 w-8 min-w-0 rounded-xl border border-slate-200 bg-white p-0 text-sm font-semibold text-slate-700 shadow-sm dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100",
2361
- children: /* @__PURE__ */ jsx14("span", { style: { transform: "translateY(-1.5px)" }, children: "<" })
2362
- }
2363
- ),
2364
- viewMode === "year" ? /* @__PURE__ */ jsx14("span", { className: "font-semibold text-slate-900 dark:text-zinc-100", children: headerLabel }) : /* @__PURE__ */ jsx14(
2365
- "button",
2366
- {
2367
- type: "button",
2368
- onClick: () => setViewMode((prev) => prev === "day" ? "month" : "year"),
2369
- className: "font-semibold text-slate-900 transition hover:underline dark:text-zinc-100",
2370
- children: headerLabel
2371
- }
2372
- ),
2373
- /* @__PURE__ */ jsx14(
2374
- Button,
2375
- {
2376
- type: "button",
2377
- onClick: goNext,
2378
- className: "h-8 w-8 min-w-0 rounded-xl border border-slate-200 bg-white p-0 text-sm font-semibold text-slate-700 shadow-sm dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100",
2379
- children: /* @__PURE__ */ jsx14("span", { style: { transform: "translateY(-1.5px)" }, children: ">" })
2380
- }
2381
- )
2382
- ] }),
2383
- viewMode === "day" ? /* @__PURE__ */ jsxs12(Fragment, { children: [
2384
- /* @__PURE__ */ jsx14("div", { className: "grid grid-cols-7 gap-1 text-center text-[11px] uppercase tracking-[0.2em] text-slate-400 dark:text-zinc-500", children: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((d) => /* @__PURE__ */ jsx14("span", { children: d }, d)) }),
2385
- /* @__PURE__ */ jsx14("div", { className: "grid grid-cols-7 gap-1", children: getMonthDays(month.year, month.month).map((cell, idx) => {
2386
- var _a, _b;
2387
- const isSelected = cell.date === current;
2388
- return /* @__PURE__ */ jsx14(
2389
- "button",
2390
- {
2391
- type: "button",
2392
- disabled: !cell.date,
2393
- onClick: () => {
2394
- if (!cell.date) return;
2395
- commit(cell.date);
2396
- },
2397
- className: twMerge13(
2398
- "h-9 rounded-xl text-sm font-semibold text-slate-700 transition hover:bg-slate-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-400/70 dark:text-zinc-200 dark:hover:bg-zinc-800",
2399
- isSelected && "bg-slate-200 text-slate-900 ring-1 ring-slate-400/70 shadow-sm dark:bg-zinc-800 dark:hover:bg-zinc-700/80 dark:text-zinc-100 dark:ring-zinc-500/70",
2400
- !cell.date && "opacity-30"
2401
- ),
2402
- children: (_b = cell.day) != null ? _b : ""
2403
- },
2404
- `${(_a = cell.date) != null ? _a : "empty"}-${idx}`
2405
- );
2406
- }) })
2407
- ] }) : viewMode === "month" ? /* @__PURE__ */ jsx14("div", { className: "grid grid-cols-3 gap-2", children: monthNames.map((name, idx) => {
2408
- const isSelected = (parsedDate == null ? void 0 : parsedDate.getFullYear()) === month.year && (parsedDate == null ? void 0 : parsedDate.getMonth()) === idx;
2409
- return /* @__PURE__ */ jsx14(
2410
- "button",
2411
- {
2412
- type: "button",
2413
- onClick: () => {
2414
- setMonth((prev) => ({ ...prev, month: idx }));
2415
- setViewMode("day");
2416
- },
2417
- className: twMerge13(
2418
- "h-10 rounded-xl border border-slate-200 bg-white text-sm font-semibold text-slate-700 shadow-sm transition hover:-translate-y-[1px] hover:shadow-md dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100",
2419
- isSelected && "border-slate-400 bg-slate-100 dark:border-slate-500 dark:bg-zinc-800"
2439
+ children: open && /* @__PURE__ */ jsx14(
2440
+ Popover,
2441
+ {
2442
+ anchorRef: dropdownRef,
2443
+ rootRef: popoverRef,
2444
+ className: clsx13("rui-date-picker__popover", highlightBorder),
2445
+ children: () => /* @__PURE__ */ jsxs12("div", { className: "rui-date-picker__panel", id: popoverId, children: [
2446
+ /* @__PURE__ */ jsxs12("div", { className: "rui-date-picker__header", children: [
2447
+ /* @__PURE__ */ jsx14(
2448
+ Button,
2449
+ {
2450
+ type: "button",
2451
+ onClick: goPrev,
2452
+ className: "rui-date-picker__nav-button",
2453
+ children: /* @__PURE__ */ jsx14("span", { style: { transform: "translateY(-1.5px)" }, children: "<" })
2454
+ }
2420
2455
  ),
2421
- children: name
2422
- },
2423
- name
2424
- );
2425
- }) }) : /* @__PURE__ */ jsx14("div", { className: "grid grid-cols-3 gap-2", children: Array.from({ length: 12 }, (_, i) => rangeStart + i).map((yr) => {
2426
- const isSelected = (parsedDate == null ? void 0 : parsedDate.getFullYear()) === yr;
2427
- return /* @__PURE__ */ jsx14(
2428
- "button",
2429
- {
2430
- type: "button",
2431
- onClick: () => {
2432
- setMonth((prev) => ({ ...prev, year: yr }));
2433
- setViewMode("month");
2434
- },
2435
- className: twMerge13(
2436
- "h-10 rounded-xl border border-slate-200 bg-white text-sm font-semibold text-slate-700 shadow-sm transition hover:-translate-y-[1px] hover:shadow-md dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100",
2437
- isSelected && "border-slate-400 bg-slate-100 dark:border-slate-500 dark:bg-zinc-800"
2456
+ viewMode === "year" ? /* @__PURE__ */ jsx14("span", { className: "rui-date-picker__header-title rui-text-wrap", children: headerLabel }) : /* @__PURE__ */ jsx14(
2457
+ "button",
2458
+ {
2459
+ type: "button",
2460
+ onClick: () => setViewMode((prev) => prev === "day" ? "month" : "year"),
2461
+ className: "rui-date-picker__header-title rui-text-wrap rui-date-picker__header-title-button",
2462
+ children: headerLabel
2463
+ }
2438
2464
  ),
2439
- children: yr
2440
- },
2441
- yr
2442
- );
2443
- }) })
2444
- ] }) })
2465
+ /* @__PURE__ */ jsx14(
2466
+ Button,
2467
+ {
2468
+ type: "button",
2469
+ onClick: goNext,
2470
+ className: "rui-date-picker__nav-button",
2471
+ children: /* @__PURE__ */ jsx14("span", { style: { transform: "translateY(-1.5px)" }, children: ">" })
2472
+ }
2473
+ )
2474
+ ] }),
2475
+ viewMode === "day" ? /* @__PURE__ */ jsxs12(Fragment, { children: [
2476
+ /* @__PURE__ */ jsx14("div", { className: "rui-date-picker__weekday-row", children: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((d) => /* @__PURE__ */ jsx14("span", { children: d }, d)) }),
2477
+ /* @__PURE__ */ jsx14("div", { className: "rui-date-picker__day-grid", children: getMonthDays(month.year, month.month, dateMode).map((cell, idx) => {
2478
+ var _a, _b;
2479
+ const isSelected = cell.date === current;
2480
+ return /* @__PURE__ */ jsx14(
2481
+ "button",
2482
+ {
2483
+ type: "button",
2484
+ disabled: !cell.date,
2485
+ onClick: () => {
2486
+ if (!cell.date) return;
2487
+ commit(cell.date);
2488
+ },
2489
+ className: clsx13(
2490
+ "rui-date-picker__day",
2491
+ isSelected && "is-selected",
2492
+ !cell.date && "is-empty"
2493
+ ),
2494
+ children: (_b = cell.day) != null ? _b : ""
2495
+ },
2496
+ `${(_a = cell.date) != null ? _a : "empty"}-${idx}`
2497
+ );
2498
+ }) })
2499
+ ] }) : viewMode === "month" ? /* @__PURE__ */ jsx14("div", { className: "rui-date-picker__month-grid", children: monthNames.map((name, idx) => {
2500
+ const isSelected = (parsedDate == null ? void 0 : parsedDate.getFullYear()) === month.year && (parsedDate == null ? void 0 : parsedDate.getMonth()) === idx;
2501
+ return /* @__PURE__ */ jsx14(
2502
+ "button",
2503
+ {
2504
+ type: "button",
2505
+ onClick: () => {
2506
+ setMonth((prev) => ({ ...prev, month: idx }));
2507
+ setViewMode("day");
2508
+ },
2509
+ className: clsx13(
2510
+ "rui-date-picker__tile",
2511
+ isSelected && "is-selected"
2512
+ ),
2513
+ children: name
2514
+ },
2515
+ name
2516
+ );
2517
+ }) }) : /* @__PURE__ */ jsx14("div", { className: "rui-date-picker__year-grid", children: Array.from({ length: 12 }, (_, i) => rangeStart + i).map((yr) => {
2518
+ const isSelected = (parsedDate == null ? void 0 : parsedDate.getFullYear()) === yr;
2519
+ return /* @__PURE__ */ jsx14(
2520
+ "button",
2521
+ {
2522
+ type: "button",
2523
+ onClick: () => {
2524
+ setMonth((prev) => ({ ...prev, year: yr }));
2525
+ setViewMode("month");
2526
+ },
2527
+ className: clsx13(
2528
+ "rui-date-picker__tile",
2529
+ isSelected && "is-selected"
2530
+ ),
2531
+ children: yr
2532
+ },
2533
+ yr
2534
+ );
2535
+ }) })
2536
+ ] })
2537
+ }
2538
+ )
2445
2539
  }
2446
2540
  ) }),
2447
- description ? /* @__PURE__ */ jsx14("p", { className: "text-xs text-slate-500 dark:text-zinc-400", children: description }) : null,
2448
- error ? /* @__PURE__ */ jsx14("p", { className: "text-xs font-medium text-rose-500 dark:text-rose-400", children: error }) : null
2541
+ description ? /* @__PURE__ */ jsx14("p", { className: "rui-date-picker__description rui-text-wrap", children: description }) : null,
2542
+ error ? /* @__PURE__ */ jsx14("p", { className: "rui-date-picker__error rui-text-wrap", children: error }) : null
2449
2543
  ] });
2450
2544
  });
2451
2545
 
2452
2546
  // components/Dialog/Dialog.tsx
2453
2547
  import * as React13 from "react";
2454
- import { createPortal } from "react-dom";
2455
- import { twMerge as twMerge14 } from "tailwind-merge";
2548
+ import { createPortal as createPortal2 } from "react-dom";
2549
+ import clsx14 from "clsx";
2550
+ import "./Dialog-ZY5E3VZ4.css";
2456
2551
  import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
2457
2552
  function Dialog({
2458
2553
  open,
@@ -2466,6 +2561,8 @@ function Dialog({
2466
2561
  }) {
2467
2562
  const overlayRef = React13.useRef(null);
2468
2563
  const dialogRef = React13.useRef(null);
2564
+ const titleId = React13.useId();
2565
+ const descriptionId = React13.useId();
2469
2566
  const dragState = React13.useRef(null);
2470
2567
  const [dragOffset, setDragOffset] = React13.useState({ x: 0, y: 0 });
2471
2568
  React13.useEffect(() => {
@@ -2474,11 +2571,40 @@ function Dialog({
2474
2571
  if (event.key === "Escape") {
2475
2572
  event.preventDefault();
2476
2573
  onClose();
2574
+ return;
2575
+ }
2576
+ if (event.key === "Tab" && modal) {
2577
+ const dialog = dialogRef.current;
2578
+ if (!dialog) return;
2579
+ const focusable = Array.from(
2580
+ dialog.querySelectorAll(
2581
+ 'a[href],button:not([disabled]),textarea:not([disabled]),input:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex="-1"])'
2582
+ )
2583
+ ).filter((el) => !el.hasAttribute("disabled") && el.tabIndex >= 0);
2584
+ if (focusable.length === 0) {
2585
+ event.preventDefault();
2586
+ dialog.focus();
2587
+ return;
2588
+ }
2589
+ const first = focusable[0];
2590
+ const last = focusable[focusable.length - 1];
2591
+ const active = document.activeElement;
2592
+ if (event.shiftKey) {
2593
+ if (active === first || active === dialog) {
2594
+ event.preventDefault();
2595
+ last.focus();
2596
+ }
2597
+ return;
2598
+ }
2599
+ if (active === last) {
2600
+ event.preventDefault();
2601
+ first.focus();
2602
+ }
2477
2603
  }
2478
2604
  };
2479
2605
  window.addEventListener("keydown", handleKey);
2480
2606
  return () => window.removeEventListener("keydown", handleKey);
2481
- }, [open, onClose]);
2607
+ }, [open, onClose, modal]);
2482
2608
  React13.useEffect(() => {
2483
2609
  var _a;
2484
2610
  if (!open) return;
@@ -2573,56 +2699,58 @@ function Dialog({
2573
2699
  ref: dialogRef,
2574
2700
  role: "dialog",
2575
2701
  "aria-modal": modal || void 0,
2702
+ "aria-labelledby": titleId,
2703
+ "aria-describedby": description ? descriptionId : void 0,
2576
2704
  tabIndex: -1,
2577
- "aria-label": title,
2578
- className: twMerge14(
2579
- "w-[min(640px,92vw)] rounded-3xl border border-slate-200 bg-white/95 p-6 shadow-2xl ring-1 ring-white/80 dark:border-zinc-700/60 dark:bg-zinc-900/95 dark:ring-zinc-800/80",
2580
- modal ? "" : "pointer-events-auto",
2581
- draggable && "cursor-grab active:cursor-grabbing"
2705
+ className: clsx14(
2706
+ "rui-dialog__card",
2707
+ modal ? "" : "rui-dialog__card--floating",
2708
+ draggable && "rui-dialog__card--draggable"
2582
2709
  ),
2583
2710
  style: { transform: `translate(${dragOffset.x}px, ${dragOffset.y}px)` },
2584
2711
  onPointerDown: onDragPointerDown,
2585
2712
  children: [
2586
- /* @__PURE__ */ jsxs13("div", { className: "flex items-start justify-between gap-3", children: [
2713
+ /* @__PURE__ */ jsxs13("div", { className: "rui-dialog__header", children: [
2587
2714
  /* @__PURE__ */ jsxs13("div", { children: [
2588
- /* @__PURE__ */ jsx15("p", { className: "text-xs font-semibold uppercase tracking-[0.3em] text-slate-500 dark:text-zinc-400", children: "Dialog" }),
2589
- /* @__PURE__ */ jsx15("h2", { className: "text-xl font-semibold text-slate-900 dark:text-zinc-100", children: title }),
2590
- description ? /* @__PURE__ */ jsx15("p", { className: "mt-1 text-sm text-slate-600 dark:text-zinc-400", children: description }) : null
2715
+ /* @__PURE__ */ jsx15("p", { className: "rui-dialog__eyebrow", children: "Dialog" }),
2716
+ /* @__PURE__ */ jsx15("h2", { id: titleId, className: "rui-dialog__title", children: title }),
2717
+ description ? /* @__PURE__ */ jsx15("p", { id: descriptionId, className: "rui-dialog__description", children: description }) : null
2591
2718
  ] }),
2592
2719
  /* @__PURE__ */ jsx15(
2593
2720
  Button,
2594
2721
  {
2595
2722
  onClick: onClose,
2596
2723
  "aria-label": "Close dialog",
2597
- className: "size-8 !px-0 !py-0 text-sm font-semibold",
2598
- children: "X"
2724
+ className: "rui-dialog__close-button",
2725
+ children: "\xD7"
2599
2726
  }
2600
2727
  )
2601
2728
  ] }),
2602
- /* @__PURE__ */ jsx15("div", { className: "mt-4 space-y-3 text-sm text-slate-700 dark:text-zinc-300", children }),
2603
- footer ? /* @__PURE__ */ jsx15("div", { className: "mt-6 flex flex-wrap justify-end gap-2", children: footer }) : null
2729
+ /* @__PURE__ */ jsx15("div", { className: "rui-dialog__content", children }),
2730
+ footer ? /* @__PURE__ */ jsx15("div", { className: "rui-dialog__footer", children: footer }) : null
2604
2731
  ]
2605
2732
  }
2606
2733
  );
2607
- return createPortal(
2734
+ return createPortal2(
2608
2735
  modal ? /* @__PURE__ */ jsx15(
2609
2736
  "div",
2610
2737
  {
2611
2738
  ref: overlayRef,
2612
- className: "fixed inset-0 z-50 flex items-center justify-center bg-zinc-950/60 backdrop-blur-sm",
2613
- onMouseDown: (e) => {
2739
+ className: "rui-overlay-root rui-dialog__overlay",
2740
+ onPointerDown: (e) => {
2614
2741
  if (e.target === overlayRef.current) onClose();
2615
2742
  },
2616
2743
  children: dialogCard
2617
2744
  }
2618
- ) : /* @__PURE__ */ jsx15("div", { className: "pointer-events-none fixed bottom-6 right-6 z-50 flex justify-end", children: dialogCard }),
2745
+ ) : /* @__PURE__ */ jsx15("div", { className: "rui-overlay-root rui-dialog__dock", children: dialogCard }),
2619
2746
  document.body
2620
2747
  );
2621
2748
  }
2622
2749
 
2623
2750
  // components/Disclosure/Disclosure.tsx
2624
2751
  import * as React14 from "react";
2625
- import { twMerge as twMerge15 } from "tailwind-merge";
2752
+ import clsx15 from "clsx";
2753
+ import "./Disclosure-YZNVFFHQ.css";
2626
2754
  import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
2627
2755
  var Disclosure = React14.forwardRef(function Disclosure2({ title, children, className, subtle, ...rest }, ref) {
2628
2756
  const summaryId = React14.useId();
@@ -2631,9 +2759,10 @@ var Disclosure = React14.forwardRef(function Disclosure2({ title, children, clas
2631
2759
  {
2632
2760
  ...rest,
2633
2761
  ref,
2634
- className: twMerge15(
2635
- "group rounded-2xl border border-slate-200 bg-white/90 p-3 shadow-sm transition dark:border-zinc-700/60 dark:bg-zinc-900/70",
2636
- subtle && "border-transparent bg-white/60 shadow-none dark:bg-zinc-900/40",
2762
+ className: clsx15(
2763
+ "rui-disclosure",
2764
+ "rui-root",
2765
+ subtle && "rui-disclosure--subtle",
2637
2766
  className
2638
2767
  ),
2639
2768
  children: [
@@ -2641,13 +2770,13 @@ var Disclosure = React14.forwardRef(function Disclosure2({ title, children, clas
2641
2770
  "summary",
2642
2771
  {
2643
2772
  id: summaryId,
2644
- className: "flex cursor-pointer list-none items-center justify-between gap-3 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-400/70",
2773
+ className: "rui-disclosure__summary",
2645
2774
  children: [
2646
- /* @__PURE__ */ jsx16("span", { className: "flex flex-1 items-center gap-2", children: /* @__PURE__ */ jsx16("span", { className: "rounded-lg bg-slate-100 px-2 py-1 text-[11px] font-semibold uppercase tracking-[0.2em] text-slate-500 shadow-inner dark:bg-zinc-800/70 dark:text-zinc-300", children: title }) }),
2775
+ /* @__PURE__ */ jsx16("span", { className: "rui-disclosure__header", children: /* @__PURE__ */ jsx16("span", { className: "rui-disclosure__title rui-text-wrap", children: title }) }),
2647
2776
  /* @__PURE__ */ jsx16(
2648
2777
  "span",
2649
2778
  {
2650
- className: "text-slate-400 transition-transform duration-200 group-open:rotate-180 dark:text-zinc-500",
2779
+ className: "rui-disclosure__caret",
2651
2780
  "aria-hidden": "true",
2652
2781
  children: "\u25BE"
2653
2782
  }
@@ -2655,7 +2784,7 @@ var Disclosure = React14.forwardRef(function Disclosure2({ title, children, clas
2655
2784
  ]
2656
2785
  }
2657
2786
  ),
2658
- /* @__PURE__ */ jsx16("div", { className: "mt-3 space-y-2 text-sm text-slate-600 dark:text-zinc-300", children })
2787
+ /* @__PURE__ */ jsx16("div", { className: "rui-disclosure__content rui-text-wrap", children })
2659
2788
  ]
2660
2789
  }
2661
2790
  );
@@ -2663,7 +2792,8 @@ var Disclosure = React14.forwardRef(function Disclosure2({ title, children, clas
2663
2792
 
2664
2793
  // components/InputField/InputField.tsx
2665
2794
  import * as React15 from "react";
2666
- import { twMerge as twMerge16 } from "tailwind-merge";
2795
+ import clsx16 from "clsx";
2796
+ import "./InputField-TKTNGOH3.css";
2667
2797
  import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
2668
2798
  var InputField = React15.forwardRef(function InputField2({ label, description, error, leadingIcon, trailingLabel, className, id, disabled, ...rest }, ref) {
2669
2799
  const generatedId = React15.useId();
@@ -2672,27 +2802,26 @@ var InputField = React15.forwardRef(function InputField2({ label, description, e
2672
2802
  const errorId = React15.useId();
2673
2803
  const hintIds = [description ? descriptionId : null, error ? errorId : null].filter(Boolean);
2674
2804
  const resolvedAriaDescribedBy = hintIds.length ? hintIds.join(" ") : void 0;
2675
- const containerClasses = twMerge16(
2676
- "flex items-center gap-3 rounded-2xl border border-slate-300 bg-white/70 px-3 py-2 transition focus-within:border-slate-400 focus-within:shadow-[0_0_0_1px_rgba(148,163,184,0.45)] dark:border-zinc-700 dark:bg-zinc-900/70 dark:focus-within:border-slate-500",
2677
- disabled && "opacity-60",
2678
- error && "border-rose-300 focus-within:border-rose-400 focus-within:shadow-[0_0_0_1px_rgba(248,113,113,0.35)] dark:border-rose-500/60"
2805
+ const containerClasses = clsx16(
2806
+ disabled && "rui-input-field__shell--disabled",
2807
+ error && "rui-input-field__shell--error"
2679
2808
  );
2680
- const inputClasses = twMerge16(
2681
- "flex-1 border-none bg-transparent text-sm text-slate-900 placeholder:text-slate-400 focus:outline-none disabled:cursor-not-allowed dark:text-zinc-100 dark:placeholder:text-zinc-500",
2809
+ const inputClasses = clsx16(
2810
+ "rui-input-field__input",
2682
2811
  className
2683
2812
  );
2684
- const leadingElm = leadingIcon ? /* @__PURE__ */ jsx17("span", { className: "text-slate-400 dark:text-zinc-500", "aria-hidden": "true", children: leadingIcon }) : null;
2685
- const trailingElm = trailingLabel ? /* @__PURE__ */ jsx17("span", { className: "text-xs font-semibold uppercase tracking-wide text-slate-400 dark:text-zinc-500", children: trailingLabel }) : null;
2686
- return /* @__PURE__ */ jsxs15("div", { className: "space-y-1.5", children: [
2813
+ const leadingElm = leadingIcon ? /* @__PURE__ */ jsx17("span", { className: "rui-input-field__leading", "aria-hidden": "true", children: leadingIcon }) : null;
2814
+ const trailingElm = trailingLabel ? /* @__PURE__ */ jsx17("span", { className: "rui-input-field__trailing rui-text-wrap", children: trailingLabel }) : null;
2815
+ return /* @__PURE__ */ jsxs15("div", { className: "rui-input-field rui-root", children: [
2687
2816
  label ? /* @__PURE__ */ jsx17(
2688
2817
  "label",
2689
2818
  {
2690
2819
  htmlFor: inputId,
2691
- className: "text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-zinc-400",
2820
+ className: "rui-input-field__label rui-text-wrap",
2692
2821
  children: label
2693
2822
  }
2694
2823
  ) : null,
2695
- /* @__PURE__ */ jsxs15("div", { className: containerClasses, children: [
2824
+ /* @__PURE__ */ jsxs15("div", { className: clsx16("rui-input-field__shell", containerClasses), children: [
2696
2825
  leadingElm,
2697
2826
  /* @__PURE__ */ jsx17(
2698
2827
  "input",
@@ -2708,14 +2837,15 @@ var InputField = React15.forwardRef(function InputField2({ label, description, e
2708
2837
  ),
2709
2838
  trailingElm
2710
2839
  ] }),
2711
- description ? /* @__PURE__ */ jsx17("p", { id: descriptionId, className: "text-xs text-slate-500 dark:text-zinc-400", children: description }) : null,
2712
- error ? /* @__PURE__ */ jsx17("p", { id: errorId, className: "text-xs font-medium text-rose-500 dark:text-rose-400", children: error }) : null
2840
+ description ? /* @__PURE__ */ jsx17("p", { id: descriptionId, className: "rui-input-field__description rui-text-wrap", children: description }) : null,
2841
+ error ? /* @__PURE__ */ jsx17("p", { id: errorId, className: "rui-input-field__error rui-text-wrap", children: error }) : null
2713
2842
  ] });
2714
2843
  });
2715
2844
 
2716
2845
  // components/NumberInput/NumberInput.tsx
2717
2846
  import * as React16 from "react";
2718
- import { twMerge as twMerge17 } from "tailwind-merge";
2847
+ import clsx17 from "clsx";
2848
+ import "./NumberInput-KTYVXS7K.css";
2719
2849
  import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
2720
2850
  var NumberInput = React16.forwardRef(
2721
2851
  function NumberInput2({
@@ -2723,6 +2853,7 @@ var NumberInput = React16.forwardRef(
2723
2853
  description,
2724
2854
  error,
2725
2855
  className,
2856
+ style,
2726
2857
  disabled,
2727
2858
  value,
2728
2859
  defaultValue = 0,
@@ -2730,7 +2861,8 @@ var NumberInput = React16.forwardRef(
2730
2861
  step = 1,
2731
2862
  suffix,
2732
2863
  min,
2733
- max
2864
+ max,
2865
+ scale = 1
2734
2866
  }, ref) {
2735
2867
  const [internal, setInternal] = React16.useState(defaultValue);
2736
2868
  const isControlled = typeof value === "number";
@@ -2740,38 +2872,82 @@ var NumberInput = React16.forwardRef(
2740
2872
  if (!isControlled) setInternal(clamped);
2741
2873
  onChange == null ? void 0 : onChange(clamped);
2742
2874
  };
2743
- return /* @__PURE__ */ jsxs16("div", { className: "space-y-1.5", children: [
2744
- label ? /* @__PURE__ */ jsx18("p", { className: "text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-zinc-400", children: label }) : null,
2875
+ const resolvedText = `${resolved}`;
2876
+ const valueChars = Math.max(resolvedText.length, 1);
2877
+ const rootStyle = React16.useMemo(
2878
+ () => ({
2879
+ "--rui-number-input-scale": scale,
2880
+ "--rui-number-input-value-ch": valueChars,
2881
+ ...style
2882
+ }),
2883
+ [scale, style, valueChars]
2884
+ );
2885
+ return /* @__PURE__ */ jsxs16("div", { className: "rui-number-input rui-root", style: rootStyle, children: [
2886
+ label ? /* @__PURE__ */ jsx18("p", { className: "rui-number-input__label rui-text-wrap", children: label }) : null,
2745
2887
  /* @__PURE__ */ jsxs16(
2746
2888
  "div",
2747
2889
  {
2748
- className: twMerge17(
2749
- "flex items-center gap-3 rounded-2xl border border-slate-300 bg-white/80 px-3 py-2 shadow-sm transition focus-within:border-slate-400 focus-within:shadow-[0_0_0_1px_rgba(148,163,184,0.45)] dark:border-zinc-700 dark:bg-zinc-900/70 dark:focus-within:border-slate-500",
2750
- disabled && "opacity-60",
2751
- error && "border-rose-300 focus-within:border-rose-400 focus-within:shadow-[0_0_0_1px_rgba(248,113,113,0.35)] dark:border-rose-500/60"
2890
+ className: clsx17(
2891
+ "rui-number-input__shell",
2892
+ disabled && "rui-number-input__shell--disabled",
2893
+ error && "rui-number-input__shell--error"
2752
2894
  ),
2753
2895
  children: [
2754
- /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1", children: [
2896
+ /* @__PURE__ */ jsxs16("div", { className: "rui-number-input__stepper", children: [
2755
2897
  /* @__PURE__ */ jsx18(
2756
- "button",
2898
+ Button,
2757
2899
  {
2758
2900
  type: "button",
2759
2901
  "aria-label": "Increase",
2760
2902
  onClick: () => update(resolved + step),
2761
- className: "grid size-7 place-items-center rounded-xl border border-slate-200 bg-white text-xs font-semibold text-slate-700 shadow-sm transition hover:-translate-y-[1px] hover:shadow-md disabled:opacity-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100",
2903
+ className: "rui-number-input__step-button",
2762
2904
  disabled,
2763
- children: "+"
2905
+ children: /* @__PURE__ */ jsx18(
2906
+ "svg",
2907
+ {
2908
+ viewBox: "0 0 20 20",
2909
+ fill: "currentColor",
2910
+ "aria-hidden": "true",
2911
+ width: "1.1em",
2912
+ height: "1.1em",
2913
+ children: /* @__PURE__ */ jsx18(
2914
+ "path",
2915
+ {
2916
+ fillRule: "evenodd",
2917
+ d: "M5.23 12.79a.75.75 0 0 0 1.06-.02L10 8.828l3.71 3.94a.75.75 0 1 0 1.08-1.04l-4.24-4.5a.75.75 0 0 0-1.08 0l-4.24 4.5a.75.75 0 0 0 .02 1.06z",
2918
+ clipRule: "evenodd"
2919
+ }
2920
+ )
2921
+ }
2922
+ )
2764
2923
  }
2765
2924
  ),
2766
2925
  /* @__PURE__ */ jsx18(
2767
- "button",
2926
+ Button,
2768
2927
  {
2769
2928
  type: "button",
2770
2929
  "aria-label": "Decrease",
2771
2930
  onClick: () => update(resolved - step),
2772
- className: "grid size-7 place-items-center rounded-xl border border-slate-200 bg-white text-xs font-semibold text-slate-700 shadow-sm transition hover:-translate-y-[1px] hover:shadow-md disabled:opacity-50 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-100",
2931
+ className: "rui-number-input__step-button",
2773
2932
  disabled,
2774
- children: "-"
2933
+ children: /* @__PURE__ */ jsx18(
2934
+ "svg",
2935
+ {
2936
+ viewBox: "0 0 20 20",
2937
+ fill: "currentColor",
2938
+ "aria-hidden": "true",
2939
+ width: "1.1em",
2940
+ height: "1.1em",
2941
+ children: /* @__PURE__ */ jsx18(
2942
+ "path",
2943
+ {
2944
+ fillRule: "evenodd",
2945
+ d: "M5.23 7.21a.75.75 0 0 1 1.06.02L10 11.172l3.71-3.94a.75.75 0 1 1 1.08 1.04l-4.24 4.5a.75.75 0 0 1-1.08 0l-4.24-4.5a.75.75 0 0 1 .02-1.06z",
2946
+ clipRule: "evenodd"
2947
+ }
2948
+ )
2949
+ }
2950
+ )
2775
2951
  }
2776
2952
  )
2777
2953
  ] }),
@@ -2786,56 +2962,46 @@ var NumberInput = React16.forwardRef(
2786
2962
  max,
2787
2963
  step,
2788
2964
  disabled,
2789
- className: twMerge17(
2790
- "flex-1 border-none bg-transparent text-2xl font-semibold tabular-nums text-slate-900 placeholder:text-slate-400 focus:outline-none dark:text-zinc-100 dark:placeholder:text-zinc-500 appearance-none [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none",
2965
+ className: clsx17(
2966
+ "rui-number-input__input",
2791
2967
  className
2792
2968
  )
2793
2969
  }
2794
2970
  ),
2795
- suffix ? /* @__PURE__ */ jsx18("span", { className: "text-sm font-semibold uppercase tracking-wide text-slate-500 dark:text-zinc-300", children: suffix }) : null
2971
+ suffix ? /* @__PURE__ */ jsx18("span", { className: "rui-number-input__suffix rui-text-wrap", children: suffix }) : null
2796
2972
  ]
2797
2973
  }
2798
2974
  ),
2799
- description ? /* @__PURE__ */ jsx18("p", { className: "text-xs text-slate-500 dark:text-zinc-400", children: description }) : null,
2800
- error ? /* @__PURE__ */ jsx18("p", { className: "text-xs font-medium text-rose-500 dark:text-rose-400", children: error }) : null
2975
+ description ? /* @__PURE__ */ jsx18("p", { className: "rui-number-input__helper rui-number-input__helper--description rui-text-wrap", children: description }) : null,
2976
+ error ? /* @__PURE__ */ jsx18("p", { className: "rui-number-input__helper rui-number-input__helper--error rui-text-wrap", children: error }) : null
2801
2977
  ] });
2802
2978
  }
2803
2979
  );
2804
2980
 
2805
2981
  // components/OutputChip/OutputChip.tsx
2806
2982
  import * as React17 from "react";
2807
- import { twMerge as twMerge18 } from "tailwind-merge";
2983
+ import clsx18 from "clsx";
2984
+ import "./OutputChip-CN7R243G.css";
2808
2985
  import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
2809
- var toneStyles = {
2810
- neutral: { bg: "bg-slate-900", text: "text-white", ring: "ring-slate-300" },
2811
- success: { bg: "bg-emerald-500", text: "text-white", ring: "ring-emerald-200" },
2812
- warning: { bg: "bg-amber-500", text: "text-white", ring: "ring-amber-200" },
2813
- danger: { bg: "bg-rose-500", text: "text-white", ring: "ring-rose-200" }
2814
- };
2815
2986
  var OutputChip = React17.forwardRef(function OutputChip2({ children, className, tone = "neutral", label, ...rest }, ref) {
2816
- const styles = toneStyles[tone];
2817
2987
  return /* @__PURE__ */ jsxs17(
2818
2988
  "output",
2819
2989
  {
2820
2990
  ...rest,
2821
2991
  ref,
2822
- className: twMerge18(
2823
- "inline-flex items-center justify-center gap-2 rounded-full px-3 py-1 text-xs font-semibold uppercase tracking-[0.25em] shadow-sm ring-1 text-center",
2824
- styles.bg,
2825
- styles.text,
2826
- styles.ring,
2827
- className
2828
- ),
2992
+ "data-tone": tone,
2993
+ className: clsx18("rui-root", "rui-output-chip", className),
2829
2994
  children: [
2830
- label ? /* @__PURE__ */ jsx19("span", { className: "opacity-70", children: label }) : null,
2831
- /* @__PURE__ */ jsx19("span", { children })
2995
+ label ? /* @__PURE__ */ jsx19("span", { className: "rui-output-chip__label rui-text-wrap", children: label }) : null,
2996
+ /* @__PURE__ */ jsx19("span", { className: "rui-output-chip__value rui-text-wrap", children })
2832
2997
  ]
2833
2998
  }
2834
2999
  );
2835
3000
  });
2836
3001
 
2837
3002
  // components/ProgressMeter/ProgressMeter.tsx
2838
- import { twMerge as twMerge19 } from "tailwind-merge";
3003
+ import clsx19 from "clsx";
3004
+ import "./ProgressMeter-6EOIFB3Y.css";
2839
3005
  import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
2840
3006
  function Progress({
2841
3007
  label,
@@ -2847,29 +3013,29 @@ function Progress({
2847
3013
  }) {
2848
3014
  const clamped = Math.min(max, Math.max(0, value));
2849
3015
  const percent = max === 0 ? 0 : Math.round(clamped / max * 100);
2850
- return /* @__PURE__ */ jsxs18("div", { className: twMerge19("space-y-1.5", className), children: [
2851
- label ? /* @__PURE__ */ jsxs18("div", { className: "flex items-center justify-between gap-3", children: [
2852
- /* @__PURE__ */ jsx20("p", { className: "text-xs font-semibold uppercase tracking-[0.24em] text-slate-500 dark:text-zinc-400", children: label }),
2853
- showValue ? /* @__PURE__ */ jsxs18("span", { className: "text-xs font-semibold text-slate-600 dark:text-zinc-300", children: [
3016
+ return /* @__PURE__ */ jsxs18("div", { className: clsx19("rui-progress-meter rui-root", className), children: [
3017
+ label ? /* @__PURE__ */ jsxs18("div", { className: "rui-progress-meter__header", children: [
3018
+ /* @__PURE__ */ jsx20("p", { className: "rui-progress-meter__label rui-text-wrap", children: label }),
3019
+ showValue ? /* @__PURE__ */ jsxs18("span", { className: "rui-progress-meter__value", children: [
2854
3020
  percent,
2855
3021
  "%"
2856
3022
  ] }) : null
2857
3023
  ] }) : null,
2858
- description ? /* @__PURE__ */ jsx20("p", { className: "text-[11px] text-slate-500 dark:text-zinc-400", children: description }) : null,
2859
- /* @__PURE__ */ jsxs18("div", { className: "relative h-3 w-full overflow-hidden rounded-full border border-slate-200 bg-white shadow-inner ring-1 ring-slate-100/80 dark:border-zinc-700 dark:bg-zinc-900/80 dark:ring-zinc-800/70", children: [
3024
+ description ? /* @__PURE__ */ jsx20("p", { className: "rui-progress-meter__description rui-text-wrap", children: description }) : null,
3025
+ /* @__PURE__ */ jsxs18("div", { className: "rui-progress-meter__track", children: [
2860
3026
  /* @__PURE__ */ jsx20(
2861
3027
  "progress",
2862
3028
  {
2863
3029
  value: clamped,
2864
3030
  max,
2865
- className: "absolute inset-0 h-full w-full appearance-none",
3031
+ className: "rui-progress-meter__native",
2866
3032
  "aria-label": label
2867
3033
  }
2868
3034
  ),
2869
3035
  /* @__PURE__ */ jsx20(
2870
3036
  "div",
2871
3037
  {
2872
- className: "absolute inset-y-0 left-0 rounded-full bg-gradient-to-r from-slate-900 via-slate-700 to-slate-900 shadow-[0_0_0_1px_rgba(15,23,42,0.2)] transition-[width]",
3038
+ className: "rui-progress-meter__fill rui-progress-meter__fill--gradient",
2873
3039
  style: { width: `${percent}%` }
2874
3040
  }
2875
3041
  )
@@ -2892,27 +3058,27 @@ function Meter({
2892
3058
  (acc, t) => clamped >= t.value ? t.color : acc,
2893
3059
  (_b = (_a = thresholds[0]) == null ? void 0 : _a.color) != null ? _b : "linear-gradient(90deg, #22c55e, #0ea5e9)"
2894
3060
  ) : "linear-gradient(90deg, #22c55e, #0ea5e9)";
2895
- return /* @__PURE__ */ jsxs18("div", { className: twMerge19("space-y-1.5", className), children: [
2896
- label ? /* @__PURE__ */ jsxs18("div", { className: "flex items-center justify-between gap-3", children: [
2897
- /* @__PURE__ */ jsx20("p", { className: "text-xs font-semibold uppercase tracking-[0.24em] text-slate-500 dark:text-zinc-400", children: label }),
2898
- /* @__PURE__ */ jsx20("span", { className: "text-xs font-semibold text-slate-600 dark:text-zinc-300", children: clamped })
3061
+ return /* @__PURE__ */ jsxs18("div", { className: clsx19("rui-progress-meter rui-root", className), children: [
3062
+ label ? /* @__PURE__ */ jsxs18("div", { className: "rui-progress-meter__header", children: [
3063
+ /* @__PURE__ */ jsx20("p", { className: "rui-progress-meter__label rui-text-wrap", children: label }),
3064
+ /* @__PURE__ */ jsx20("span", { className: "rui-progress-meter__value", children: clamped })
2899
3065
  ] }) : null,
2900
- description ? /* @__PURE__ */ jsx20("p", { className: "text-[11px] text-slate-500 dark:text-zinc-400", children: description }) : null,
2901
- /* @__PURE__ */ jsxs18("div", { className: "relative h-3 w-full overflow-hidden rounded-full border border-slate-200 bg-white shadow-inner ring-1 ring-slate-100/80 dark:border-zinc-700 dark:bg-zinc-900/80 dark:ring-zinc-800/70", children: [
3066
+ description ? /* @__PURE__ */ jsx20("p", { className: "rui-progress-meter__description rui-text-wrap", children: description }) : null,
3067
+ /* @__PURE__ */ jsxs18("div", { className: "rui-progress-meter__track", children: [
2902
3068
  /* @__PURE__ */ jsx20(
2903
3069
  "meter",
2904
3070
  {
2905
3071
  value: clamped,
2906
3072
  min,
2907
3073
  max,
2908
- className: "absolute inset-0 h-full w-full appearance-none",
3074
+ className: "rui-progress-meter__native",
2909
3075
  "aria-label": label
2910
3076
  }
2911
3077
  ),
2912
3078
  /* @__PURE__ */ jsx20(
2913
3079
  "div",
2914
3080
  {
2915
- className: "absolute inset-y-0 left-0 rounded-full shadow-[0_0_0_1px_rgba(15,23,42,0.2)] transition-[width]",
3081
+ className: "rui-progress-meter__fill",
2916
3082
  style: { width: `${percent}%`, background: activeColor }
2917
3083
  }
2918
3084
  )
@@ -2922,11 +3088,13 @@ function Meter({
2922
3088
 
2923
3089
  // components/Radio/Radio.tsx
2924
3090
  import * as React18 from "react";
2925
- import { twMerge as twMerge20 } from "tailwind-merge";
3091
+ import clsx20 from "clsx";
3092
+ import "./Radio-K6CDDBCQ.css";
2926
3093
  import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
2927
3094
  var Radio = React18.forwardRef(function Radio2({
2928
3095
  label,
2929
3096
  description,
3097
+ color,
2930
3098
  extra,
2931
3099
  checked,
2932
3100
  defaultChecked = false,
@@ -2953,14 +3121,15 @@ var Radio = React18.forwardRef(function Radio2({
2953
3121
  "label",
2954
3122
  {
2955
3123
  htmlFor: radioId,
2956
- className: twMerge20(
2957
- "flex items-center justify-between gap-3 rounded-2xl border border-transparent px-3 py-2 text-left transition hover:bg-slate-50 focus-within:bg-slate-50 dark:hover:bg-zinc-900/60 dark:focus-within:bg-zinc-900/60",
2958
- disabled && "cursor-not-allowed opacity-60",
3124
+ className: clsx20(
3125
+ "rui-radio rui-root",
3126
+ color && `rui-radio--color-${color}`,
3127
+ disabled && "rui-radio--disabled",
2959
3128
  className
2960
3129
  ),
2961
3130
  children: [
2962
- /* @__PURE__ */ jsxs19("span", { className: "flex flex-1 items-center gap-3", children: [
2963
- /* @__PURE__ */ jsxs19("span", { className: "flex h-6 w-6 items-center justify-center", children: [
3131
+ /* @__PURE__ */ jsxs19("span", { className: "rui-radio__content", children: [
3132
+ /* @__PURE__ */ jsxs19("span", { className: "rui-radio__indicator", children: [
2964
3133
  /* @__PURE__ */ jsx21(
2965
3134
  "input",
2966
3135
  {
@@ -2968,7 +3137,7 @@ var Radio = React18.forwardRef(function Radio2({
2968
3137
  ref: forwardedRef,
2969
3138
  id: radioId,
2970
3139
  type: "radio",
2971
- className: "peer sr-only",
3140
+ className: "rui-radio__input",
2972
3141
  checked: resolvedChecked,
2973
3142
  onChange: handleChange,
2974
3143
  "aria-describedby": description ? descriptionId : rest["aria-describedby"],
@@ -2978,29 +3147,17 @@ var Radio = React18.forwardRef(function Radio2({
2978
3147
  /* @__PURE__ */ jsx21(
2979
3148
  "span",
2980
3149
  {
2981
- className: twMerge20(
2982
- "grid size-5 place-items-center rounded-full border border-slate-300 bg-white text-slate-600 shadow-sm transition duration-150 peer-focus-visible:outline peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-slate-400 dark:border-zinc-600 dark:bg-zinc-950/70 dark:text-zinc-200",
2983
- resolvedChecked && "border-slate-400 bg-slate-100 shadow-[0_0_0_1px_rgba(148,163,184,0.45)] dark:border-zinc-500 dark:bg-zinc-700/70"
2984
- ),
2985
- "aria-hidden": "true",
2986
- children: /* @__PURE__ */ jsx21(
2987
- "span",
2988
- {
2989
- className: twMerge20(
2990
- "block h-2.5 w-2.5 rounded-full bg-slate-900 opacity-0 transition duration-200 dark:bg-zinc-100",
2991
- resolvedChecked && "opacity-100"
2992
- )
2993
- }
2994
- )
3150
+ className: "rui-radio__control",
3151
+ "aria-hidden": "true"
2995
3152
  }
2996
3153
  )
2997
3154
  ] }),
2998
- /* @__PURE__ */ jsxs19("span", { className: "flex flex-1 flex-col", children: [
2999
- /* @__PURE__ */ jsx21("span", { className: "text-sm font-semibold text-slate-900 dark:text-zinc-100", children: label }),
3000
- description ? /* @__PURE__ */ jsx21("span", { id: descriptionId, className: "text-xs text-slate-500 dark:text-zinc-400", children: description }) : null
3155
+ /* @__PURE__ */ jsxs19("span", { className: "rui-radio__meta", children: [
3156
+ /* @__PURE__ */ jsx21("span", { className: "rui-radio__label rui-text-wrap", children: label }),
3157
+ description ? /* @__PURE__ */ jsx21("span", { id: descriptionId, className: "rui-radio__description rui-text-wrap", children: description }) : null
3001
3158
  ] })
3002
3159
  ] }),
3003
- extra ? /* @__PURE__ */ jsx21("span", { className: "self-center rounded-xl border border-slate-200 bg-white/80 px-3 py-1 text-xs font-semibold text-slate-600 dark:border-zinc-700 dark:bg-zinc-900/60 dark:text-zinc-200", children: extra }) : null
3160
+ extra ? /* @__PURE__ */ jsx21("span", { className: "rui-radio__extra rui-text-wrap", children: extra }) : null
3004
3161
  ]
3005
3162
  }
3006
3163
  );
@@ -3008,7 +3165,8 @@ var Radio = React18.forwardRef(function Radio2({
3008
3165
 
3009
3166
  // components/Slider/Slider.tsx
3010
3167
  import * as React19 from "react";
3011
- import { twMerge as twMerge21 } from "tailwind-merge";
3168
+ import clsx21 from "clsx";
3169
+ import "./Slider-KHMHINU4.css";
3012
3170
  import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
3013
3171
  function clampValue(value, min, max) {
3014
3172
  return Math.min(max, Math.max(min, value));
@@ -3109,7 +3267,7 @@ var Slider = React19.forwardRef(function Slider2({
3109
3267
  const trackOffset = trackMetrics.mainOffset;
3110
3268
  const trackCrossOffset = trackMetrics.crossOffset;
3111
3269
  const trackThickness = trackMetrics.thickness;
3112
- const overlap = Math.max(edgeOverlap, 0);
3270
+ const overlap = Math.max(renderThumb ? 0 : edgeOverlap, 0);
3113
3271
  const minCenter = Math.max(thumbRadius - overlap, 0);
3114
3272
  const maxCenter = Math.max(trackLength - thumbRadius + overlap, minCenter);
3115
3273
  const usableLength = Math.max(maxCenter - minCenter, 0);
@@ -3213,11 +3371,17 @@ var Slider = React19.forwardRef(function Slider2({
3213
3371
  },
3214
3372
  [isControlled, max, min, onChange, step]
3215
3373
  );
3216
- const handleInputChange = (event) => {
3217
- const next = Number(event.target.value);
3374
+ const applyInputValue = (value2) => {
3375
+ const next = Number(value2);
3218
3376
  if (Number.isNaN(next)) return;
3219
3377
  commitValue(next);
3220
3378
  };
3379
+ const handleInputChange = (event) => {
3380
+ applyInputValue(event.currentTarget.value);
3381
+ };
3382
+ const handleInputEvent = (event) => {
3383
+ applyInputValue(event.currentTarget.value);
3384
+ };
3221
3385
  const formattedValue = formatValue(resolvedValue);
3222
3386
  const setValueFromPointer = React19.useCallback(
3223
3387
  (clientX, clientY) => {
@@ -3276,11 +3440,10 @@ var Slider = React19.forwardRef(function Slider2({
3276
3440
  "div",
3277
3441
  {
3278
3442
  ref: trackRef,
3279
- className: twMerge21(
3280
- "relative overflow-hidden rounded-full shadow-inner ring-1 ring-slate-200/80 dark:ring-white/10",
3281
- "bg-[length:100%_100%]",
3282
- isVertical ? "mx-auto h-full w-3" : "h-3 w-full",
3283
- disabled && "opacity-60",
3443
+ className: clsx21(
3444
+ "rui-slider__track",
3445
+ isVertical && "rui-slider__track--vertical",
3446
+ disabled && "rui-slider__track--disabled",
3284
3447
  trackClassName
3285
3448
  ),
3286
3449
  style: { backgroundImage: trackGradient },
@@ -3289,10 +3452,10 @@ var Slider = React19.forwardRef(function Slider2({
3289
3452
  /* @__PURE__ */ jsx22(
3290
3453
  "div",
3291
3454
  {
3292
- className: twMerge21(
3293
- "absolute rounded-full shadow-[0_0_0_1px_rgba(59,130,246,0.18)]",
3294
- dragging ? "transition-none" : "transition-[width,height] duration-150 ease-out",
3295
- isVertical ? "left-0 right-0" : "inset-y-0"
3455
+ className: clsx21(
3456
+ "rui-slider__track-fill",
3457
+ dragging && "rui-slider__track-fill--dragging",
3458
+ isVertical ? "rui-slider__track-fill--vertical" : "rui-slider__track-fill--horizontal"
3296
3459
  ),
3297
3460
  style: {
3298
3461
  ...progressStyle,
@@ -3302,122 +3465,133 @@ var Slider = React19.forwardRef(function Slider2({
3302
3465
  }
3303
3466
  }
3304
3467
  ),
3305
- /* @__PURE__ */ jsx22("div", { className: "pointer-events-none absolute inset-0 rounded-full ring-1 ring-black/5 dark:ring-white/10" })
3468
+ /* @__PURE__ */ jsx22("div", { className: "rui-slider__track-overlay" })
3306
3469
  ]
3307
3470
  }
3308
3471
  );
3309
3472
  const defaultThumb = /* @__PURE__ */ jsx22(
3310
3473
  "span",
3311
3474
  {
3312
- className: twMerge21(
3313
- "absolute top-1/2 -translate-y-1/2 -translate-x-1/2 rounded-full border border-white bg-white shadow-md shadow-slate-900/20 ring-1 ring-slate-200 transition-transform duration-150 dark:border-zinc-700/60 dark:bg-zinc-800 dark:shadow-black/30 dark:ring-zinc-700",
3314
- focused && "scale-[1.04] ring-slate-300 dark:ring-slate-500",
3315
- disabled && "opacity-60 shadow-none dark:shadow-none",
3475
+ className: clsx21(
3476
+ "rui-slider__thumb",
3477
+ focused && "rui-slider__thumb--focused",
3478
+ disabled && "rui-slider__thumb--disabled",
3316
3479
  thumbClassName
3317
3480
  ),
3318
3481
  style: { ...thumbStyle, width: thumbDiameter, height: thumbDiameter },
3319
3482
  "aria-hidden": "true",
3320
- children: /* @__PURE__ */ jsxs20("span", { className: "relative block h-full w-full", children: [
3321
- /* @__PURE__ */ jsx22("span", { className: "absolute inset-[5px] rounded-full bg-gradient-to-br from-slate-50 to-slate-200 dark:from-slate-600 dark:to-slate-700" }),
3322
- /* @__PURE__ */ jsx22("span", { className: "absolute inset-0 rounded-full bg-slate-950/5 backdrop-blur-[1px] dark:bg-white/5" })
3483
+ children: /* @__PURE__ */ jsxs20("span", { className: "rui-slider__thumb-core", children: [
3484
+ /* @__PURE__ */ jsx22("span", { className: "rui-slider__thumb-gradient" }),
3485
+ /* @__PURE__ */ jsx22("span", { className: "rui-slider__thumb-overlay" })
3323
3486
  ] })
3324
3487
  }
3325
3488
  );
3326
- return /* @__PURE__ */ jsxs20("div", { className: twMerge21("w-full space-y-2", isVertical && "max-w-[120px]", className), children: [
3327
- label ? /* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between gap-3", children: [
3328
- /* @__PURE__ */ jsx22(
3329
- "label",
3330
- {
3331
- htmlFor: inputId,
3332
- className: "text-[11px] font-semibold uppercase tracking-[0.25em] text-slate-500 dark:text-zinc-400",
3333
- children: label
3334
- }
3489
+ return /* @__PURE__ */ jsxs20(
3490
+ "div",
3491
+ {
3492
+ className: clsx21(
3493
+ "rui-root rui-slider",
3494
+ isVertical && "rui-slider--vertical",
3495
+ className
3335
3496
  ),
3336
- /* @__PURE__ */ jsx22("span", { className: "rounded-full bg-white/90 px-2 py-0.5 text-xs font-semibold text-slate-700 shadow-sm ring-1 ring-slate-200 dark:bg-zinc-900/80 dark:text-zinc-200 dark:ring-zinc-700", children: formattedValue })
3337
- ] }) : null,
3338
- /* @__PURE__ */ jsxs20(
3339
- "div",
3340
- {
3341
- ref: trackContainerRef,
3342
- className: twMerge21(
3343
- "relative w-full pt-2 pb-3",
3344
- isVertical && "flex h-48 items-center justify-center px-4 pb-4 pt-4"
3345
- ),
3346
- "data-orientation": orientation,
3347
- children: [
3348
- renderTrack ? renderTrack({ ...renderProps, children: defaultTrack }) : defaultTrack,
3349
- renderThumb ? renderThumb(renderProps) : defaultThumb,
3497
+ children: [
3498
+ label ? /* @__PURE__ */ jsxs20("div", { className: "rui-slider__header", children: [
3350
3499
  /* @__PURE__ */ jsx22(
3351
- "input",
3500
+ "label",
3352
3501
  {
3353
- ...rest,
3354
- ref: mergedRef,
3355
- id: inputId,
3356
- type: "range",
3357
- min,
3358
- max,
3359
- step,
3360
- value: resolvedValue,
3361
- onChange: handleInputChange,
3362
- onInput: handleInputChange,
3363
- onFocus: () => setFocused(true),
3364
- onBlur: () => setFocused(false),
3365
- disabled,
3366
- "aria-valuetext": formattedValue,
3367
- "aria-orientation": orientation,
3368
- "data-orientation": orientation,
3369
- className: "absolute inset-0 h-10 w-full appearance-none opacity-0 pointer-events-none"
3502
+ htmlFor: inputId,
3503
+ className: "rui-slider__label rui-text-wrap",
3504
+ children: label
3370
3505
  }
3371
3506
  ),
3372
- /* @__PURE__ */ jsx22(
3373
- "div",
3374
- {
3375
- ref: interactionRef,
3376
- "aria-hidden": "true",
3377
- onPointerDown: handlePointerDown,
3378
- className: twMerge21(
3379
- "absolute inset-0 cursor-pointer bg-transparent",
3380
- isVertical ? "left-1/2 w-8 -translate-x-1/2" : "top-1/2 h-8 -translate-y-1/2"
3507
+ /* @__PURE__ */ jsx22("span", { className: "rui-slider__value", children: formattedValue })
3508
+ ] }) : null,
3509
+ /* @__PURE__ */ jsxs20(
3510
+ "div",
3511
+ {
3512
+ ref: trackContainerRef,
3513
+ className: clsx21(
3514
+ "rui-slider__track-container",
3515
+ isVertical && "rui-slider__track-container--vertical"
3516
+ ),
3517
+ "data-orientation": orientation,
3518
+ children: [
3519
+ renderTrack ? renderTrack({ ...renderProps, children: defaultTrack }) : defaultTrack,
3520
+ renderThumb ? renderThumb(renderProps) : defaultThumb,
3521
+ /* @__PURE__ */ jsx22(
3522
+ "input",
3523
+ {
3524
+ ...rest,
3525
+ ref: mergedRef,
3526
+ id: inputId,
3527
+ type: "range",
3528
+ min,
3529
+ max,
3530
+ step,
3531
+ value: resolvedValue,
3532
+ onChange: handleInputChange,
3533
+ onInput: handleInputEvent,
3534
+ onFocus: () => setFocused(true),
3535
+ onBlur: () => setFocused(false),
3536
+ disabled,
3537
+ "aria-valuetext": formattedValue,
3538
+ "aria-orientation": orientation,
3539
+ "data-orientation": orientation,
3540
+ className: "rui-slider__input"
3541
+ }
3542
+ ),
3543
+ /* @__PURE__ */ jsx22(
3544
+ "div",
3545
+ {
3546
+ ref: interactionRef,
3547
+ "aria-hidden": "true",
3548
+ onPointerDown: handlePointerDown,
3549
+ className: clsx21(
3550
+ "rui-slider__interaction",
3551
+ isVertical ? "rui-slider__interaction--vertical" : "rui-slider__interaction--horizontal"
3552
+ )
3553
+ }
3381
3554
  )
3382
- }
3383
- )
3384
- ]
3385
- }
3386
- )
3387
- ] });
3555
+ ]
3556
+ }
3557
+ )
3558
+ ]
3559
+ }
3560
+ );
3388
3561
  });
3389
3562
 
3390
3563
  // components/StackedList/StackedList.tsx
3391
- import { twMerge as twMerge22 } from "tailwind-merge";
3564
+ import clsx22 from "clsx";
3565
+ import "./StackedList-QF5242GF.css";
3392
3566
  import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
3393
3567
  function StackedList({ items, dense, className, ...rest }) {
3394
3568
  return /* @__PURE__ */ jsx23(
3395
3569
  "div",
3396
3570
  {
3397
3571
  ...rest,
3398
- className: twMerge22(
3399
- "rounded-3xl border border-slate-200 bg-white/80 shadow-xl shadow-slate-200/40 dark:border-zinc-800 dark:bg-zinc-900/80 dark:shadow-none",
3572
+ className: clsx22(
3573
+ "rui-stacked-list rui-root rui-surface",
3400
3574
  className
3401
3575
  ),
3402
- children: /* @__PURE__ */ jsx23("ul", { role: "list", className: "divide-y divide-slate-100 dark:divide-zinc-800", children: items.map((item) => /* @__PURE__ */ jsxs21(
3576
+ children: /* @__PURE__ */ jsx23("ul", { role: "list", className: "rui-stacked-list__list", children: items.map((item) => /* @__PURE__ */ jsxs21(
3403
3577
  "li",
3404
3578
  {
3405
- className: twMerge22("flex items-start gap-4 px-5 py-4", dense && "py-3"),
3579
+ className: clsx22("rui-stacked-list__item", dense && "rui-stacked-list__item--dense"),
3406
3580
  children: [
3407
3581
  item.icon ? /* @__PURE__ */ jsx23(
3408
3582
  "div",
3409
3583
  {
3410
- className: "mt-0.5 rounded-2xl bg-slate-100 p-2 text-slate-600 dark:bg-zinc-900/50 dark:text-zinc-200",
3584
+ className: "rui-stacked-list__icon",
3411
3585
  "aria-hidden": "true",
3412
3586
  children: item.icon
3413
3587
  }
3414
3588
  ) : null,
3415
- /* @__PURE__ */ jsxs21("div", { className: "flex-1", children: [
3416
- /* @__PURE__ */ jsx23("p", { className: "text-sm font-semibold text-slate-900 dark:text-zinc-100", children: item.title }),
3417
- item.description ? /* @__PURE__ */ jsx23("p", { className: "text-sm text-slate-500 dark:text-zinc-400", children: item.description }) : null
3589
+ /* @__PURE__ */ jsxs21("div", { className: "rui-stacked-list__content", children: [
3590
+ /* @__PURE__ */ jsx23("p", { className: "rui-stacked-list__title rui-text-wrap", children: item.title }),
3591
+ item.description ? /* @__PURE__ */ jsx23("p", { className: "rui-stacked-list__description rui-text-wrap", children: item.description }) : null
3418
3592
  ] }),
3419
- /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-end gap-1 text-right", children: [
3420
- item.meta ? /* @__PURE__ */ jsx23("span", { className: "text-xs uppercase tracking-wide text-slate-400 dark:text-zinc-500", children: item.meta }) : null,
3593
+ /* @__PURE__ */ jsxs21("div", { className: "rui-stacked-list__meta", children: [
3594
+ item.meta ? /* @__PURE__ */ jsx23("span", { className: "rui-stacked-list__meta-text rui-text-wrap", children: item.meta }) : null,
3421
3595
  item.action
3422
3596
  ] })
3423
3597
  ]
@@ -3428,22 +3602,312 @@ function StackedList({ items, dense, className, ...rest }) {
3428
3602
  );
3429
3603
  }
3430
3604
 
3605
+ // components/TabGroup/TabGroup.tsx
3606
+ import React20 from "react";
3607
+ import "./TabGroup-CV2AC3EO.css";
3608
+ import { Fragment as Fragment2, jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
3609
+ function TabGroup({
3610
+ align = "start",
3611
+ position = "top",
3612
+ fill = "full",
3613
+ rotation = "horizontal",
3614
+ size = 50,
3615
+ tabs,
3616
+ active,
3617
+ defaultActive = 0,
3618
+ onActiveChange
3619
+ }) {
3620
+ var _a, _b;
3621
+ const rootRef = React20.useRef(null);
3622
+ const tabStripRef = React20.useRef(null);
3623
+ const idBase = React20.useId();
3624
+ const [effectiveFill, setEffectiveFill] = React20.useState(fill);
3625
+ const [availableMain, setAvailableMain] = React20.useState(0);
3626
+ const [minMain, setMinMain] = React20.useState(32);
3627
+ const count = tabs.length;
3628
+ const clampIndex = React20.useCallback(
3629
+ (i) => {
3630
+ if (count <= 0) {
3631
+ return 0;
3632
+ }
3633
+ if (!Number.isFinite(i)) {
3634
+ return 0;
3635
+ }
3636
+ return Math.max(0, Math.min(count - 1, Math.trunc(i)));
3637
+ },
3638
+ [count]
3639
+ );
3640
+ const isControlled = active !== void 0;
3641
+ const [activeInternal, setActiveInternal] = React20.useState(() => clampIndex(defaultActive));
3642
+ React20.useEffect(() => {
3643
+ if (!isControlled) {
3644
+ setActiveInternal((i) => clampIndex(i));
3645
+ }
3646
+ }, [clampIndex, isControlled]);
3647
+ const currentActive = clampIndex(isControlled ? active : activeInternal);
3648
+ const setActive = React20.useCallback(
3649
+ (next) => {
3650
+ const i = clampIndex(next);
3651
+ if (!isControlled) {
3652
+ setActiveInternal(i);
3653
+ }
3654
+ onActiveChange == null ? void 0 : onActiveChange(i);
3655
+ },
3656
+ [clampIndex, isControlled, onActiveChange]
3657
+ );
3658
+ const tabsFirst = position === "top" || position === "left";
3659
+ const updateEffectiveFill = React20.useCallback(() => {
3660
+ const root = rootRef.current;
3661
+ if (!root) {
3662
+ setEffectiveFill(fill);
3663
+ return;
3664
+ }
3665
+ const rect = root.getBoundingClientRect();
3666
+ const computed = getComputedStyle(root);
3667
+ const radius = parseFloat(computed.getPropertyValue("--rui-tab-panel-radius")) || 0;
3668
+ const border = parseFloat(computed.getPropertyValue("--rui-tab-border")) || 0;
3669
+ const minMainValue = parseFloat(computed.getPropertyValue("--rui-tab-min-main")) || 32;
3670
+ const wiggle = border * 2 + 1;
3671
+ const available = position === "top" || position === "bottom" ? rect.width : rect.height;
3672
+ const required = (size != null ? size : 0) * tabs.length;
3673
+ const slots2 = minMainValue > 0 ? Math.floor(available / minMainValue) : tabs.length;
3674
+ const hasOverflowControls = slots2 < tabs.length;
3675
+ const shouldFill = available - 2 * radius - wiggle <= required;
3676
+ setEffectiveFill(shouldFill || hasOverflowControls ? "full" : "partial");
3677
+ }, [fill, position, size, tabs.length]);
3678
+ React20.useLayoutEffect(() => {
3679
+ if (fill === "full") {
3680
+ setEffectiveFill("full");
3681
+ return;
3682
+ }
3683
+ updateEffectiveFill();
3684
+ const node = rootRef.current;
3685
+ if (!node || typeof ResizeObserver === "undefined") {
3686
+ return;
3687
+ }
3688
+ const observer = new ResizeObserver(() => updateEffectiveFill());
3689
+ observer.observe(node);
3690
+ return () => observer.disconnect();
3691
+ }, [fill, updateEffectiveFill]);
3692
+ const isVertical = position === "left" || position === "right";
3693
+ React20.useLayoutEffect(() => {
3694
+ const root = rootRef.current;
3695
+ if (!root) return;
3696
+ const computed = getComputedStyle(root);
3697
+ const cssMin = parseFloat(computed.getPropertyValue("--rui-tab-min-main"));
3698
+ setMinMain(Number.isFinite(cssMin) && cssMin > 0 ? cssMin : 32);
3699
+ }, [position]);
3700
+ React20.useLayoutEffect(() => {
3701
+ const node = tabStripRef.current;
3702
+ if (!node) return;
3703
+ const measure = () => {
3704
+ const rect = node.getBoundingClientRect();
3705
+ setAvailableMain(isVertical ? rect.height : rect.width);
3706
+ };
3707
+ measure();
3708
+ if (typeof ResizeObserver === "undefined") return;
3709
+ const observer = new ResizeObserver(() => measure());
3710
+ observer.observe(node);
3711
+ return () => observer.disconnect();
3712
+ }, [isVertical]);
3713
+ const slots = availableMain > 0 && minMain > 0 ? Math.floor(availableMain / minMain) : count;
3714
+ const overflow = slots < count;
3715
+ const windowSize = overflow ? Math.max(1, slots - 2) : count;
3716
+ const maxStart = Math.max(0, count - windowSize);
3717
+ const [startIndex, setStartIndex] = React20.useState(0);
3718
+ React20.useEffect(() => {
3719
+ if (!overflow) {
3720
+ setStartIndex(0);
3721
+ return;
3722
+ }
3723
+ setStartIndex((prev) => Math.min(Math.max(0, prev), maxStart));
3724
+ }, [overflow, maxStart]);
3725
+ React20.useEffect(() => {
3726
+ if (!overflow) return;
3727
+ setStartIndex((prev) => {
3728
+ if (currentActive < prev) return currentActive;
3729
+ const end = prev + windowSize;
3730
+ if (currentActive >= end) return currentActive - windowSize + 1;
3731
+ return prev;
3732
+ });
3733
+ }, [currentActive, overflow, windowSize]);
3734
+ const visibleTabs = overflow ? tabs.slice(startIndex, startIndex + windowSize) : tabs;
3735
+ const slotSize = overflow && slots > 0 ? availableMain / slots : 0;
3736
+ const overflowMainStyle = overflow && slotSize > 0 ? isVertical ? { height: slotSize } : { width: slotSize } : void 0;
3737
+ const mainStyle = overflow ? overflowMainStyle : effectiveFill === "partial" ? isVertical ? { height: size } : { width: size } : void 0;
3738
+ const scrollLabels = isVertical ? { back: "Scroll tabs up", forward: "Scroll tabs down" } : { back: "Scroll tabs left", forward: "Scroll tabs right" };
3739
+ const scrollMainStyle = overflowMainStyle;
3740
+ const panelId = `${idBase}-panel`;
3741
+ const getTabId = React20.useCallback(
3742
+ (index) => `${idBase}-tab-${index}`,
3743
+ [idBase]
3744
+ );
3745
+ const focusTabAt = React20.useCallback((index) => {
3746
+ var _a2;
3747
+ const node = (_a2 = rootRef.current) == null ? void 0 : _a2.querySelector(`[data-tab-index="${index}"]`);
3748
+ node == null ? void 0 : node.focus();
3749
+ }, []);
3750
+ const moveActiveBy = React20.useCallback(
3751
+ (direction) => {
3752
+ var _a2;
3753
+ if (count === 0) return;
3754
+ for (let i = 0; i < count; i += 1) {
3755
+ const next = (currentActive + direction * (i + 1) + count) % count;
3756
+ if (!((_a2 = tabs[next]) == null ? void 0 : _a2.disabled)) {
3757
+ setActive(next);
3758
+ requestAnimationFrame(() => focusTabAt(next));
3759
+ return;
3760
+ }
3761
+ }
3762
+ },
3763
+ [count, currentActive, focusTabAt, setActive, tabs]
3764
+ );
3765
+ const moveToEdge = React20.useCallback(
3766
+ (edge) => {
3767
+ var _a2;
3768
+ if (count === 0) return;
3769
+ const range = edge === "start" ? [0, count, 1] : [count - 1, -1, -1];
3770
+ for (let i = range[0]; i !== range[1]; i += range[2]) {
3771
+ if (!((_a2 = tabs[i]) == null ? void 0 : _a2.disabled)) {
3772
+ setActive(i);
3773
+ requestAnimationFrame(() => focusTabAt(i));
3774
+ return;
3775
+ }
3776
+ }
3777
+ },
3778
+ [count, focusTabAt, setActive, tabs]
3779
+ );
3780
+ const handleTabListKeyDown = React20.useCallback(
3781
+ (event) => {
3782
+ const key = event.key;
3783
+ const prevKey = isVertical ? "ArrowUp" : "ArrowLeft";
3784
+ const nextKey = isVertical ? "ArrowDown" : "ArrowRight";
3785
+ if (key === prevKey) {
3786
+ event.preventDefault();
3787
+ moveActiveBy(-1);
3788
+ return;
3789
+ }
3790
+ if (key === nextKey) {
3791
+ event.preventDefault();
3792
+ moveActiveBy(1);
3793
+ return;
3794
+ }
3795
+ if (key === "Home") {
3796
+ event.preventDefault();
3797
+ moveToEdge("start");
3798
+ } else if (key === "End") {
3799
+ event.preventDefault();
3800
+ moveToEdge("end");
3801
+ }
3802
+ },
3803
+ [isVertical, moveActiveBy, moveToEdge]
3804
+ );
3805
+ const tabList = /* @__PURE__ */ jsxs22("div", { className: "rui-tab-group__tabstrip", ref: tabStripRef, children: [
3806
+ overflow && /* @__PURE__ */ jsx24(
3807
+ "button",
3808
+ {
3809
+ type: "button",
3810
+ className: "rui-tab-group__scroll is-back",
3811
+ "aria-label": scrollLabels.back,
3812
+ disabled: startIndex === 0,
3813
+ onClick: () => setStartIndex((i) => Math.max(0, i - 1)),
3814
+ style: scrollMainStyle,
3815
+ children: /* @__PURE__ */ jsx24("span", { "aria-hidden": "true", className: "rui-tab-group__scrollIcon", children: isVertical ? "\u25B2" : "\u25C0" })
3816
+ }
3817
+ ),
3818
+ /* @__PURE__ */ jsx24(
3819
+ "div",
3820
+ {
3821
+ className: "rui-tab-group__tablist",
3822
+ role: "tablist",
3823
+ "aria-orientation": isVertical ? "vertical" : "horizontal",
3824
+ onKeyDown: handleTabListKeyDown,
3825
+ children: visibleTabs.map((tab, localIndex) => {
3826
+ const index = overflow ? startIndex + localIndex : localIndex;
3827
+ return /* @__PURE__ */ jsx24(
3828
+ "button",
3829
+ {
3830
+ type: "button",
3831
+ role: "tab",
3832
+ className: `rui-tab-group__tab ${index === currentActive ? "is-active" : ""}`,
3833
+ style: mainStyle,
3834
+ disabled: tab.disabled,
3835
+ "aria-selected": index === currentActive,
3836
+ "aria-controls": panelId,
3837
+ id: getTabId(index),
3838
+ "data-tab-index": index,
3839
+ tabIndex: index === currentActive ? 0 : -1,
3840
+ onClick: () => !tab.disabled && setActive(index),
3841
+ children: /* @__PURE__ */ jsx24("span", { className: "rui-tab-group__label", children: tab.label })
3842
+ },
3843
+ index
3844
+ );
3845
+ })
3846
+ }
3847
+ ),
3848
+ overflow && /* @__PURE__ */ jsx24(
3849
+ "button",
3850
+ {
3851
+ type: "button",
3852
+ className: "rui-tab-group__scroll is-forward",
3853
+ "aria-label": scrollLabels.forward,
3854
+ disabled: startIndex === maxStart,
3855
+ onClick: () => setStartIndex((i) => Math.min(maxStart, i + 1)),
3856
+ style: scrollMainStyle,
3857
+ children: /* @__PURE__ */ jsx24("span", { "aria-hidden": "true", className: "rui-tab-group__scrollIcon", children: isVertical ? "\u25BC" : "\u25B6" })
3858
+ }
3859
+ )
3860
+ ] });
3861
+ const panel = /* @__PURE__ */ jsx24(
3862
+ "div",
3863
+ {
3864
+ className: "rui-tab-group__panel",
3865
+ role: "tabpanel",
3866
+ id: panelId,
3867
+ "aria-labelledby": getTabId(currentActive),
3868
+ tabIndex: 0,
3869
+ children: (_b = (_a = tabs[currentActive]) == null ? void 0 : _a.content) != null ? _b : null
3870
+ }
3871
+ );
3872
+ return /* @__PURE__ */ jsx24(
3873
+ "div",
3874
+ {
3875
+ ref: rootRef,
3876
+ className: "rui-tab-group",
3877
+ "data-align": align,
3878
+ "data-position": position,
3879
+ "data-fill": effectiveFill,
3880
+ "data-requested-fill": fill,
3881
+ "data-rotation": rotation,
3882
+ "data-overflow": overflow ? "true" : "false",
3883
+ children: tabsFirst ? /* @__PURE__ */ jsxs22(Fragment2, { children: [
3884
+ tabList,
3885
+ panel
3886
+ ] }) : /* @__PURE__ */ jsxs22(Fragment2, { children: [
3887
+ panel,
3888
+ tabList
3889
+ ] })
3890
+ }
3891
+ );
3892
+ }
3893
+
3431
3894
  // components/Table/Table.tsx
3432
- import * as React20 from "react";
3433
- import { twMerge as twMerge23 } from "tailwind-merge";
3434
- import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
3895
+ import * as React21 from "react";
3896
+ import clsx23 from "clsx";
3897
+ import "./Table-GHEVUAUZ.css";
3898
+ import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
3435
3899
  var MIN_THUMB = 24;
3436
3900
  var TRACK_PADDING2 = 6;
3437
3901
  var TRACK_THICKNESS = 6;
3438
3902
  var TRACK_INSET = 8;
3439
3903
  var V_TRACK_INSET = 10;
3440
3904
  function useScrollbarMetrics(ref, axis, extraSpace) {
3441
- const [state, setState] = React20.useState({
3905
+ const [state, setState] = React21.useState({
3442
3906
  visible: false,
3443
3907
  size: MIN_THUMB,
3444
3908
  offset: 0
3445
3909
  });
3446
- React20.useLayoutEffect(() => {
3910
+ React21.useLayoutEffect(() => {
3447
3911
  const el = ref.current;
3448
3912
  if (!el) return;
3449
3913
  let raf = 0;
@@ -3479,7 +3943,7 @@ function useScrollbarMetrics(ref, axis, extraSpace) {
3479
3943
  return state;
3480
3944
  }
3481
3945
  function useThumbDrag(ref, axis, thumbState, extraSpace) {
3482
- const startDrag = React20.useCallback(
3946
+ const startDrag = React21.useCallback(
3483
3947
  (event, startScrollOverride) => {
3484
3948
  var _a, _b;
3485
3949
  const el = ref.current;
@@ -3510,7 +3974,7 @@ function useThumbDrag(ref, axis, thumbState, extraSpace) {
3510
3974
  },
3511
3975
  [axis, ref, thumbState.size, extraSpace]
3512
3976
  );
3513
- const onThumbPointerDown = React20.useCallback(
3977
+ const onThumbPointerDown = React21.useCallback(
3514
3978
  (event) => {
3515
3979
  event.stopPropagation();
3516
3980
  startDrag(event);
@@ -3527,15 +3991,15 @@ function Table({
3527
3991
  scrollAreaStyle,
3528
3992
  style
3529
3993
  }) {
3530
- const scrollRef = React20.useRef(null);
3531
- const [padRight, setPadRight] = React20.useState(0);
3532
- const [padBottom, setPadBottom] = React20.useState(0);
3994
+ const scrollRef = React21.useRef(null);
3995
+ const [padRight, setPadRight] = React21.useState(0);
3996
+ const [padBottom, setPadBottom] = React21.useState(0);
3533
3997
  const vThumb = useScrollbarMetrics(scrollRef, "vertical", padBottom);
3534
3998
  const hThumb = useScrollbarMetrics(scrollRef, "horizontal", padRight);
3535
- React20.useEffect(() => {
3999
+ React21.useEffect(() => {
3536
4000
  setPadRight(vThumb.visible ? TRACK_PADDING2 + 10 : 0);
3537
4001
  }, [vThumb.visible]);
3538
- React20.useEffect(() => {
4002
+ React21.useEffect(() => {
3539
4003
  setPadBottom(hThumb.visible ? TRACK_PADDING2 + 10 : 0);
3540
4004
  }, [hThumb.visible]);
3541
4005
  const { onThumbPointerDown: handleVThumbDown, startDrag: startVDrag } = useThumbDrag(
@@ -3550,7 +4014,7 @@ function Table({
3550
4014
  hThumb,
3551
4015
  padRight
3552
4016
  );
3553
- const handleTrackPointerDown = React20.useCallback(
4017
+ const handleTrackPointerDown = React21.useCallback(
3554
4018
  (axis, thumb, startDrag, event) => {
3555
4019
  const el = scrollRef.current;
3556
4020
  if (!el) return;
@@ -3575,55 +4039,55 @@ function Table({
3575
4039
  const vOffset = Math.max(TRACK_PADDING2, (vSlot - TRACK_THICKNESS) / 2);
3576
4040
  const hOffset = Math.max(TRACK_PADDING2, (hSlot - TRACK_THICKNESS) / 2);
3577
4041
  const hBottom = Math.max(TRACK_PADDING2 / 2, (hSlot - TRACK_THICKNESS) / 2);
3578
- return /* @__PURE__ */ jsx24(
4042
+ return /* @__PURE__ */ jsx25(
3579
4043
  "div",
3580
4044
  {
3581
- className: twMerge23(
3582
- "overflow-hidden rounded-3xl border border-slate-200 shadow-sm dark:border-zinc-800",
4045
+ className: clsx23(
4046
+ "rui-table",
3583
4047
  className
3584
4048
  ),
3585
4049
  style,
3586
- children: /* @__PURE__ */ jsxs22(
4050
+ children: /* @__PURE__ */ jsxs23(
3587
4051
  "div",
3588
4052
  {
3589
- className: "relative overflow-hidden bg-white/90 dark:bg-zinc-950/80",
4053
+ className: "rui-table__container",
3590
4054
  style: { paddingRight: padRight, paddingBottom: padBottom },
3591
4055
  children: [
3592
- /* @__PURE__ */ jsx24(
4056
+ /* @__PURE__ */ jsx25(
3593
4057
  "div",
3594
4058
  {
3595
4059
  ref: scrollRef,
3596
- className: "table-scrollbar overflow-auto",
4060
+ className: "rui-table__scroll",
3597
4061
  style: { ...scrollAreaStyle },
3598
- children: /* @__PURE__ */ jsxs22("table", { className: "w-full border-collapse text-sm text-slate-700 dark:text-zinc-200", children: [
3599
- caption ? /* @__PURE__ */ jsx24("caption", { className: "bg-slate-50 px-4 py-2 text-left text-xs font-semibold uppercase tracking-[0.25em] text-slate-500 dark:bg-zinc-900/70 dark:text-zinc-400", children: caption }) : null,
3600
- /* @__PURE__ */ jsx24("thead", { className: "bg-white/90 text-xs uppercase tracking-[0.16em] text-slate-500 dark:bg-zinc-900/80 dark:text-zinc-400", children: /* @__PURE__ */ jsx24("tr", { children: columns.map((col) => /* @__PURE__ */ jsx24(
4062
+ children: /* @__PURE__ */ jsxs23("table", { className: "rui-table__table", children: [
4063
+ caption ? /* @__PURE__ */ jsx25("caption", { className: "rui-table__caption rui-text-wrap", children: caption }) : null,
4064
+ /* @__PURE__ */ jsx25("thead", { className: "rui-table__head", children: /* @__PURE__ */ jsx25("tr", { children: columns.map((col) => /* @__PURE__ */ jsx25(
3601
4065
  "th",
3602
4066
  {
3603
4067
  scope: "col",
3604
- className: twMerge23(
3605
- "px-4 py-3 text-left font-semibold",
3606
- col.align === "right" && "text-right",
3607
- col.align === "center" && "text-center"
4068
+ className: clsx23(
4069
+ "rui-table__header-cell",
4070
+ col.align === "right" && "rui-table__header-cell--align-right",
4071
+ col.align === "center" && "rui-table__header-cell--align-center"
3608
4072
  ),
3609
4073
  children: col.header
3610
4074
  },
3611
4075
  String(col.key)
3612
4076
  )) }) }),
3613
- /* @__PURE__ */ jsx24("tbody", { children: data.map((row, rowIndex) => /* @__PURE__ */ jsx24(
4077
+ /* @__PURE__ */ jsx25("tbody", { children: data.map((row, rowIndex) => /* @__PURE__ */ jsx25(
3614
4078
  "tr",
3615
4079
  {
3616
- className: twMerge23(
3617
- "border-t border-slate-100 transition dark:border-zinc-800",
3618
- rowIndex % 2 === 0 ? "bg-slate-100/70 hover:bg-slate-200 dark:bg-zinc-950/70 dark:hover:bg-zinc-800" : "bg-white/80 hover:bg-slate-200 dark:bg-zinc-900/60 dark:hover:bg-zinc-800"
4080
+ className: clsx23(
4081
+ "rui-table__row",
4082
+ rowIndex % 2 === 0 && "rui-table__row--alt"
3619
4083
  ),
3620
- children: columns.map((col) => /* @__PURE__ */ jsx24(
4084
+ children: columns.map((col) => /* @__PURE__ */ jsx25(
3621
4085
  "td",
3622
4086
  {
3623
- className: twMerge23(
3624
- "px-4 py-3 align-middle",
3625
- col.align === "right" && "text-right",
3626
- col.align === "center" && "text-center"
4087
+ className: clsx23(
4088
+ "rui-table__cell",
4089
+ col.align === "right" && "rui-table__cell--align-right",
4090
+ col.align === "center" && "rui-table__cell--align-center"
3627
4091
  ),
3628
4092
  children: col.render ? col.render(row[col.key], row) : row[col.key]
3629
4093
  },
@@ -3635,10 +4099,10 @@ function Table({
3635
4099
  ] })
3636
4100
  }
3637
4101
  ),
3638
- vThumb.visible ? /* @__PURE__ */ jsx24(
4102
+ vThumb.visible ? /* @__PURE__ */ jsx25(
3639
4103
  "div",
3640
4104
  {
3641
- className: "absolute z-20 pointer-events-auto rounded-full bg-white/80 shadow-inner dark:bg-zinc-900/70",
4105
+ className: "rui-table__track rui-table__track--vertical",
3642
4106
  style: {
3643
4107
  right: vOffset,
3644
4108
  top: TRACK_PADDING2 + V_TRACK_INSET,
@@ -3646,20 +4110,22 @@ function Table({
3646
4110
  width: TRACK_THICKNESS
3647
4111
  },
3648
4112
  onPointerDown: (e) => handleTrackPointerDown("vertical", vThumb, startVDrag, e),
3649
- children: /* @__PURE__ */ jsx24("div", { className: "relative h-full w-full rounded-full bg-slate-900/5 shadow-inner dark:bg-white/10", children: /* @__PURE__ */ jsx24(
4113
+ children: /* @__PURE__ */ jsx25("div", { className: "rui-table__track-inner", children: /* @__PURE__ */ jsx25(
3650
4114
  "div",
3651
4115
  {
3652
- className: "absolute left-1/2 w-full -translate-x-1/2 rounded-full bg-slate-400/80 shadow-sm transition-colors dark:bg-zinc-500/70",
4116
+ className: clsx23(
4117
+ "rui-table__thumb rui-table__thumb--vertical"
4118
+ ),
3653
4119
  style: { height: `${vThumb.size}px`, top: `${vThumb.offset}px` },
3654
4120
  onPointerDown: handleVThumbDown
3655
4121
  }
3656
4122
  ) })
3657
4123
  }
3658
4124
  ) : null,
3659
- hThumb.visible ? /* @__PURE__ */ jsx24(
4125
+ hThumb.visible ? /* @__PURE__ */ jsx25(
3660
4126
  "div",
3661
4127
  {
3662
- className: "absolute z-20 pointer-events-auto rounded-full bg-white/80 shadow-inner dark:bg-zinc-900/70",
4128
+ className: "rui-table__track rui-table__track--horizontal",
3663
4129
  style: {
3664
4130
  left: hOffset + TRACK_INSET,
3665
4131
  right: hOffset + TRACK_INSET,
@@ -3667,10 +4133,12 @@ function Table({
3667
4133
  height: TRACK_THICKNESS
3668
4134
  },
3669
4135
  onPointerDown: (e) => handleTrackPointerDown("horizontal", hThumb, startHDrag, e),
3670
- children: /* @__PURE__ */ jsx24("div", { className: "relative h-full w-full rounded-full bg-slate-900/5 shadow-inner dark:bg-white/10", children: /* @__PURE__ */ jsx24(
4136
+ children: /* @__PURE__ */ jsx25("div", { className: "rui-table__track-inner", children: /* @__PURE__ */ jsx25(
3671
4137
  "div",
3672
4138
  {
3673
- className: "absolute top-1/2 h-full -translate-y-1/2 rounded-full bg-slate-400/80 shadow-sm transition-colors dark:bg-zinc-500/70",
4139
+ className: clsx23(
4140
+ "rui-table__thumb rui-table__thumb--horizontal"
4141
+ ),
3674
4142
  style: { width: `${hThumb.size}px`, left: `${hThumb.offset}px` },
3675
4143
  onPointerDown: handleHThumbDown
3676
4144
  }
@@ -3685,16 +4153,17 @@ function Table({
3685
4153
  }
3686
4154
 
3687
4155
  // components/Textarea/Textarea.tsx
3688
- import * as React21 from "react";
3689
- import { twMerge as twMerge24 } from "tailwind-merge";
3690
- import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
4156
+ import * as React22 from "react";
4157
+ import clsx24 from "clsx";
4158
+ import "./Textarea-ETXFJO7T.css";
4159
+ import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
3691
4160
  var MIN_THUMB2 = 24;
3692
4161
  var TRACK_THICKNESS2 = 6;
3693
4162
  var TRACK_TOP = 8;
3694
4163
  var TRACK_BOTTOM = 22;
3695
4164
  var TRACK_REDUCTION = 20;
3696
4165
  var TRACK_REDUCTION_HALF = TRACK_REDUCTION / 2;
3697
- var Textarea = React21.forwardRef(function Textarea2({
4166
+ var Textarea = React22.forwardRef(function Textarea2({
3698
4167
  label,
3699
4168
  description,
3700
4169
  error,
@@ -3707,24 +4176,24 @@ var Textarea = React21.forwardRef(function Textarea2({
3707
4176
  ...rest
3708
4177
  }, ref) {
3709
4178
  var _a, _b;
3710
- const generatedId = React21.useId();
4179
+ const generatedId = React22.useId();
3711
4180
  const textareaId = id != null ? id : generatedId;
3712
- const descriptionId = React21.useId();
3713
- const errorId = React21.useId();
3714
- const textareaRef = React21.useRef(null);
3715
- const shellRef = React21.useRef(null);
3716
- const resizeListenersRef = React21.useRef({});
3717
- const [thumb, setThumb] = React21.useState({
4181
+ const descriptionId = React22.useId();
4182
+ const errorId = React22.useId();
4183
+ const textareaRef = React22.useRef(null);
4184
+ const shellRef = React22.useRef(null);
4185
+ const resizeListenersRef = React22.useRef({});
4186
+ const [thumb, setThumb] = React22.useState({
3718
4187
  visible: false,
3719
4188
  size: MIN_THUMB2,
3720
4189
  offset: 0
3721
4190
  });
3722
4191
  const hintIds = [description ? descriptionId : null, error ? errorId : null].filter(Boolean);
3723
4192
  const resolvedAriaDescribedBy = hintIds.length ? hintIds.join(" ") : void 0;
3724
- const [value, setValue] = React21.useState((_b = (_a = rest.defaultValue) == null ? void 0 : _a.toString()) != null ? _b : "");
3725
- const [height, setHeight] = React21.useState(void 0);
3726
- const [width, setWidth] = React21.useState(void 0);
3727
- const setRefs = React21.useCallback(
4193
+ const [value, setValue] = React22.useState((_b = (_a = rest.defaultValue) == null ? void 0 : _a.toString()) != null ? _b : "");
4194
+ const [height, setHeight] = React22.useState(void 0);
4195
+ const [width, setWidth] = React22.useState(void 0);
4196
+ const setRefs = React22.useCallback(
3728
4197
  (node) => {
3729
4198
  textareaRef.current = node;
3730
4199
  if (typeof ref === "function") {
@@ -3735,17 +4204,17 @@ var Textarea = React21.forwardRef(function Textarea2({
3735
4204
  },
3736
4205
  [ref]
3737
4206
  );
3738
- React21.useEffect(() => {
4207
+ React22.useEffect(() => {
3739
4208
  if (typeof rest.value === "string") {
3740
4209
  setValue(rest.value);
3741
4210
  }
3742
4211
  }, [rest.value]);
3743
- React21.useLayoutEffect(() => {
4212
+ React22.useLayoutEffect(() => {
3744
4213
  if (textareaRef.current && height === void 0) {
3745
4214
  setHeight(textareaRef.current.offsetHeight);
3746
4215
  }
3747
4216
  }, [height]);
3748
- React21.useLayoutEffect(() => {
4217
+ React22.useLayoutEffect(() => {
3749
4218
  const el = textareaRef.current;
3750
4219
  if (!el) return;
3751
4220
  let raf = 0;
@@ -3780,26 +4249,24 @@ var Textarea = React21.forwardRef(function Textarea2({
3780
4249
  cancelAnimationFrame(raf);
3781
4250
  };
3782
4251
  }, [height]);
3783
- React21.useLayoutEffect(() => {
3784
- if (!shellRef.current || width !== void 0) return;
3785
- setWidth(shellRef.current.offsetWidth);
3786
- }, [width]);
3787
- React21.useEffect(() => {
4252
+ React22.useEffect(() => {
3788
4253
  return () => {
3789
4254
  if (resizeListenersRef.current.move) {
3790
- window.removeEventListener("mousemove", resizeListenersRef.current.move);
4255
+ window.removeEventListener("pointermove", resizeListenersRef.current.move);
3791
4256
  }
3792
4257
  if (resizeListenersRef.current.up) {
3793
- window.removeEventListener("mouseup", resizeListenersRef.current.up);
4258
+ window.removeEventListener("pointerup", resizeListenersRef.current.up);
4259
+ window.removeEventListener("pointercancel", resizeListenersRef.current.up);
3794
4260
  }
3795
4261
  };
3796
4262
  }, []);
3797
4263
  const handleResizeStart = (event) => {
3798
- var _a2, _b2, _c, _d, _e;
4264
+ var _a2, _b2, _c, _d, _e, _f, _g;
4265
+ if (event.pointerType === "mouse" && event.button !== 0) return;
3799
4266
  event.preventDefault();
3800
4267
  if (!textareaRef.current) return;
3801
4268
  const allowY = resizeDirection === "vertical" || resizeDirection === "both";
3802
- const allowX = resizeDirection === "horizontal" || resizeDirection === "both";
4269
+ const allowX2 = resizeDirection === "horizontal" || resizeDirection === "both";
3803
4270
  const startY = event.clientY;
3804
4271
  const startX = event.clientX;
3805
4272
  const startHeight = textareaRef.current.offsetHeight;
@@ -3812,22 +4279,25 @@ var Textarea = React21.forwardRef(function Textarea2({
3812
4279
  const nextHeight = Math.max(minHeight, startHeight + (moveEvent.clientY - startY));
3813
4280
  setHeight(nextHeight);
3814
4281
  }
3815
- if (allowX) {
4282
+ if (allowX2) {
3816
4283
  const proposed = startWidth + (moveEvent.clientX - startX);
3817
4284
  const nextWidth = Math.min(parentWidth, Math.max(minWidth, proposed));
3818
4285
  setWidth(nextWidth);
3819
4286
  }
3820
4287
  };
3821
4288
  const onUp = () => {
3822
- window.removeEventListener("mousemove", onMove);
3823
- window.removeEventListener("mouseup", onUp);
4289
+ window.removeEventListener("pointermove", onMove);
4290
+ window.removeEventListener("pointerup", onUp);
4291
+ window.removeEventListener("pointercancel", onUp);
3824
4292
  resizeListenersRef.current = {};
3825
4293
  };
3826
4294
  resizeListenersRef.current = { move: onMove, up: onUp };
3827
- window.addEventListener("mousemove", onMove);
3828
- window.addEventListener("mouseup", onUp);
4295
+ (_g = (_f = event.currentTarget).setPointerCapture) == null ? void 0 : _g.call(_f, event.pointerId);
4296
+ window.addEventListener("pointermove", onMove);
4297
+ window.addEventListener("pointerup", onUp);
4298
+ window.addEventListener("pointercancel", onUp);
3829
4299
  };
3830
- const handleThumbDrag = React21.useCallback(
4300
+ const handleThumbDrag = React22.useCallback(
3831
4301
  (event, startScrollOverride) => {
3832
4302
  var _a2, _b2;
3833
4303
  const el = textareaRef.current;
@@ -3858,13 +4328,15 @@ var Textarea = React21.forwardRef(function Textarea2({
3858
4328
  },
3859
4329
  [thumb.size]
3860
4330
  );
3861
- const shellClasses = twMerge24(
3862
- "relative rounded-2xl border border-slate-300 bg-white/80 px-3 py-2 shadow-sm transition focus-within:border-slate-400 focus-within:shadow-[0_0_0_1px_rgba(148,163,184,0.45)] dark:border-zinc-700 dark:bg-zinc-900/70 dark:focus-within:border-slate-500",
3863
- disabled && "opacity-60",
3864
- error && "border-rose-300 focus-within:border-rose-400 focus-within:shadow-[0_0_0_1px_rgba(248,113,113,0.35)] dark:border-rose-500/60"
4331
+ const rootClasses = clsx24("rui-textarea", "rui-root", disabled && "rui-textarea--disabled");
4332
+ const shellClasses = clsx24(
4333
+ "rui-textarea__shell",
4334
+ disabled && "rui-textarea__shell--disabled",
4335
+ error && "rui-textarea__shell--error"
3865
4336
  );
3866
- const textareaClasses = twMerge24(
3867
- "textarea-scrollbar min-h-[120px] w-full resize-none border-none bg-transparent pb-4 pr-5 text-sm text-slate-900 placeholder:text-slate-400 focus:outline-none dark:text-zinc-100 dark:placeholder:text-zinc-500",
4337
+ const textareaClasses = clsx24(
4338
+ "rui-textarea__control",
4339
+ `rui-textarea__control--resize-${resizeDirection}`,
3868
4340
  className
3869
4341
  );
3870
4342
  const count = value.length;
@@ -3872,22 +4344,21 @@ var Textarea = React21.forwardRef(function Textarea2({
3872
4344
  const { style, ...restProps } = rest;
3873
4345
  const textareaStyle = {
3874
4346
  ...style,
3875
- ...height !== void 0 ? { height } : null,
3876
- ...width !== void 0 ? { width } : null,
3877
- maxWidth: "100%"
4347
+ ...height !== void 0 ? { height } : null
3878
4348
  };
3879
- const shellStyle = width !== void 0 ? { width, maxWidth: "100%" } : { maxWidth: "100%" };
3880
- return /* @__PURE__ */ jsxs23("div", { className: "space-y-1.5", children: [
3881
- label ? /* @__PURE__ */ jsx25(
4349
+ const allowX = resizeDirection === "horizontal" || resizeDirection === "both";
4350
+ const shellStyle = width !== void 0 && allowX ? { width } : void 0;
4351
+ return /* @__PURE__ */ jsxs24("div", { className: rootClasses, children: [
4352
+ label ? /* @__PURE__ */ jsx26(
3882
4353
  "label",
3883
4354
  {
3884
4355
  htmlFor: textareaId,
3885
- className: "text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-zinc-400",
4356
+ className: "rui-textarea__label rui-text-wrap",
3886
4357
  children: label
3887
4358
  }
3888
4359
  ) : null,
3889
- /* @__PURE__ */ jsxs23("div", { className: shellClasses, ref: shellRef, style: shellStyle, children: [
3890
- /* @__PURE__ */ jsx25(
4360
+ /* @__PURE__ */ jsxs24("div", { className: shellClasses, ref: shellRef, style: shellStyle, children: [
4361
+ /* @__PURE__ */ jsx26(
3891
4362
  "textarea",
3892
4363
  {
3893
4364
  ...restProps,
@@ -3906,10 +4377,10 @@ var Textarea = React21.forwardRef(function Textarea2({
3906
4377
  }
3907
4378
  }
3908
4379
  ),
3909
- thumb.visible ? /* @__PURE__ */ jsx25(
4380
+ thumb.visible ? /* @__PURE__ */ jsx26(
3910
4381
  "div",
3911
4382
  {
3912
- className: "pointer-events-auto absolute z-20 rounded-full bg-white/60 shadow-inner backdrop-blur-sm transition-colors dark:bg-zinc-800/70",
4383
+ className: "rui-textarea__scrollbar",
3913
4384
  style: {
3914
4385
  right: 4,
3915
4386
  top: TRACK_TOP + TRACK_REDUCTION_HALF,
@@ -3932,10 +4403,10 @@ var Textarea = React21.forwardRef(function Textarea2({
3932
4403
  el.scrollTop = target;
3933
4404
  handleThumbDrag(event, target);
3934
4405
  },
3935
- children: /* @__PURE__ */ jsx25("div", { className: "relative h-full w-full rounded-full bg-slate-900/5 shadow-inner dark:bg-white/10", children: /* @__PURE__ */ jsx25(
4406
+ children: /* @__PURE__ */ jsx26("div", { className: "rui-textarea__scrollbar-track", children: /* @__PURE__ */ jsx26(
3936
4407
  "div",
3937
4408
  {
3938
- className: "absolute left-1/2 w-full -translate-x-1/2 rounded-full bg-slate-400/80 shadow-sm transition-colors dark:bg-zinc-500/70",
4409
+ className: "rui-textarea__scrollbar-thumb",
3939
4410
  style: { height: `${thumb.size}px`, top: `${thumb.offset}px` },
3940
4411
  onPointerDown: (event) => {
3941
4412
  event.stopPropagation();
@@ -3945,57 +4416,442 @@ var Textarea = React21.forwardRef(function Textarea2({
3945
4416
  ) })
3946
4417
  }
3947
4418
  ) : null,
3948
- resizeDirection !== "none" ? /* @__PURE__ */ jsxs23("div", { className: "pointer-events-none absolute bottom-2 right-2 flex items-center gap-2 text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-400 dark:text-zinc-500", children: [
3949
- showCount && limit ? /* @__PURE__ */ jsxs23("div", { className: "pointer-events-auto", children: [
4419
+ resizeDirection !== "none" ? /* @__PURE__ */ jsxs24("div", { className: "rui-textarea__footer", children: [
4420
+ showCount && limit ? /* @__PURE__ */ jsxs24("div", { className: "rui-textarea__footer-count", children: [
3950
4421
  count,
3951
4422
  "/",
3952
4423
  limit
3953
4424
  ] }) : null,
3954
- /* @__PURE__ */ jsx25(
4425
+ /* @__PURE__ */ jsx26(
3955
4426
  "button",
3956
4427
  {
3957
4428
  type: "button",
3958
4429
  "aria-label": "Resize textarea",
3959
- onMouseDown: handleResizeStart,
3960
- className: "pointer-events-auto inline-flex h-[14px] w-[14px] items-center justify-center rounded-[3px] bg-transparent text-slate-400 outline-none transition hover:text-slate-500 focus-visible:ring-2 focus-visible:ring-slate-300 focus-visible:ring-offset-1 focus-visible:ring-offset-white active:cursor-grab dark:bg-transparent dark:text-zinc-400 dark:hover:text-zinc-200 dark:focus-visible:ring-slate-500 dark:focus-visible:ring-offset-zinc-900",
4430
+ onPointerDown: handleResizeStart,
4431
+ className: "rui-textarea__resize-handle",
3961
4432
  style: {
3962
4433
  border: "none",
3963
4434
  boxShadow: "none",
3964
4435
  appearance: "none",
3965
4436
  background: "transparent"
3966
4437
  },
3967
- children: /* @__PURE__ */ jsx25(
4438
+ children: /* @__PURE__ */ jsx26(
3968
4439
  "svg",
3969
4440
  {
3970
- viewBox: "0 0 12 12",
4441
+ viewBox: "0 0 16 16",
3971
4442
  "aria-hidden": "true",
3972
- className: "h-3 w-3 text-slate-400 dark:text-zinc-400",
3973
- children: /* @__PURE__ */ jsx25(
3974
- "path",
3975
- {
3976
- d: "M2 10.5 10.5 2M4.5 10.5 10.5 4.5M7 10.5 10.5 7",
3977
- stroke: "currentColor",
3978
- strokeWidth: "1.1"
3979
- }
3980
- )
4443
+ className: "rui-textarea__resize-handle-icon",
4444
+ fill: "none",
4445
+ stroke: "currentColor",
4446
+ strokeWidth: "1.5",
4447
+ strokeLinecap: "round",
4448
+ children: /* @__PURE__ */ jsx26("path", { d: "M7 15 L15 7 M11 15 L15 11 M3 15 L15 3" })
3981
4449
  }
3982
4450
  )
3983
4451
  }
3984
4452
  )
3985
4453
  ] }) : null
3986
4454
  ] }),
3987
- description ? /* @__PURE__ */ jsx25("p", { id: descriptionId, className: "text-xs text-slate-500 dark:text-zinc-400", children: description }) : null,
3988
- error ? /* @__PURE__ */ jsx25("p", { id: errorId, className: "text-xs font-medium text-rose-500 dark:text-rose-400", children: error }) : null
4455
+ description ? /* @__PURE__ */ jsx26("p", { id: descriptionId, className: "rui-textarea__description rui-text-wrap", children: description }) : null,
4456
+ error ? /* @__PURE__ */ jsx26("p", { id: errorId, className: "rui-textarea__error rui-text-wrap", children: error }) : null
3989
4457
  ] });
3990
4458
  });
3991
4459
 
4460
+ // components/ResizableContainer/ResizableContainer.tsx
4461
+ import * as React23 from "react";
4462
+ import clsx25 from "clsx";
4463
+ import "./ResizableContainer-KIX7YKZJ.css";
4464
+ import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
4465
+ var DEFAULT_MIN_WIDTH = 240;
4466
+ var DEFAULT_MIN_HEIGHT = 120;
4467
+ var DEFAULT_STEP = 8;
4468
+ var MIN_THUMB3 = 24;
4469
+ var TRACK_PADDING3 = 6;
4470
+ var TRACK_THICKNESS3 = 6;
4471
+ var TRACK_INSET2 = 8;
4472
+ var V_TRACK_INSET2 = 10;
4473
+ function useScrollbarMetrics2(ref, axis, extraSpace) {
4474
+ const [state, setState] = React23.useState({
4475
+ visible: false,
4476
+ size: MIN_THUMB3,
4477
+ offset: 0
4478
+ });
4479
+ React23.useLayoutEffect(() => {
4480
+ const el = ref.current;
4481
+ if (!el) return;
4482
+ let raf = 0;
4483
+ const update = () => {
4484
+ const target = ref.current;
4485
+ if (!target) return;
4486
+ const scrollRange = axis === "vertical" ? target.scrollHeight - target.clientHeight : target.scrollWidth - target.clientWidth;
4487
+ const trackLength = axis === "vertical" ? Math.max(0, target.clientHeight + extraSpace - TRACK_PADDING3 * 2 - V_TRACK_INSET2 * 2) : Math.max(0, target.clientWidth + extraSpace - 2 * (TRACK_PADDING3 + TRACK_INSET2));
4488
+ if (scrollRange <= 0 || trackLength <= 0) {
4489
+ setState((prev) => prev.visible ? { ...prev, visible: false } : prev);
4490
+ return;
4491
+ }
4492
+ const ratio = axis === "vertical" ? target.clientHeight / target.scrollHeight : target.clientWidth / target.scrollWidth;
4493
+ const thumbSize = Math.max(trackLength * ratio, MIN_THUMB3);
4494
+ const maxOffset = Math.max(0, trackLength - thumbSize);
4495
+ const currentOffset = maxOffset > 0 ? (axis === "vertical" ? target.scrollTop : target.scrollLeft) / scrollRange * maxOffset : 0;
4496
+ setState({ visible: true, size: thumbSize, offset: currentOffset });
4497
+ };
4498
+ const handleScroll = () => {
4499
+ cancelAnimationFrame(raf);
4500
+ raf = window.requestAnimationFrame(update);
4501
+ };
4502
+ const resizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(update) : null;
4503
+ resizeObserver == null ? void 0 : resizeObserver.observe(el);
4504
+ el.addEventListener("scroll", handleScroll, { passive: true });
4505
+ update();
4506
+ return () => {
4507
+ resizeObserver == null ? void 0 : resizeObserver.disconnect();
4508
+ el.removeEventListener("scroll", handleScroll);
4509
+ cancelAnimationFrame(raf);
4510
+ };
4511
+ }, [ref, axis, extraSpace]);
4512
+ return state;
4513
+ }
4514
+ function useThumbDrag2(ref, axis, thumbState, extraSpace) {
4515
+ const startDrag = React23.useCallback(
4516
+ (event, startScrollOverride) => {
4517
+ var _a, _b;
4518
+ const el = ref.current;
4519
+ if (!el) return;
4520
+ event.preventDefault();
4521
+ const startPos = axis === "vertical" ? event.clientY : event.clientX;
4522
+ const startScroll = startScrollOverride != null ? startScrollOverride : axis === "vertical" ? el.scrollTop : el.scrollLeft;
4523
+ const thumbSize = thumbState.size;
4524
+ const handleMove = (moveEvent) => {
4525
+ const delta = (axis === "vertical" ? moveEvent.clientY : moveEvent.clientX) - startPos;
4526
+ const scrollRange = axis === "vertical" ? el.scrollHeight - el.clientHeight : el.scrollWidth - el.clientWidth;
4527
+ const trackLength = axis === "vertical" ? el.clientHeight + extraSpace - TRACK_PADDING3 * 2 - V_TRACK_INSET2 * 2 : el.clientWidth + extraSpace - 2 * (TRACK_PADDING3 + TRACK_INSET2);
4528
+ if (scrollRange <= 0 || trackLength <= thumbSize) return;
4529
+ const ratio = scrollRange / (trackLength - thumbSize);
4530
+ const next = startScroll + delta * ratio;
4531
+ if (axis === "vertical") el.scrollTop = Math.min(scrollRange, Math.max(0, next));
4532
+ else el.scrollLeft = Math.min(scrollRange, Math.max(0, next));
4533
+ };
4534
+ const handleUp = () => {
4535
+ window.removeEventListener("pointermove", handleMove);
4536
+ window.removeEventListener("pointerup", handleUp);
4537
+ window.removeEventListener("pointercancel", handleUp);
4538
+ };
4539
+ (_b = (_a = event.currentTarget).setPointerCapture) == null ? void 0 : _b.call(_a, event.pointerId);
4540
+ window.addEventListener("pointermove", handleMove);
4541
+ window.addEventListener("pointerup", handleUp);
4542
+ window.addEventListener("pointercancel", handleUp);
4543
+ },
4544
+ [axis, ref, thumbState.size, extraSpace]
4545
+ );
4546
+ const onThumbPointerDown = React23.useCallback(
4547
+ (event) => {
4548
+ event.stopPropagation();
4549
+ startDrag(event);
4550
+ },
4551
+ [startDrag]
4552
+ );
4553
+ return { onThumbPointerDown, startDrag };
4554
+ }
4555
+ var ResizableContainer = React23.forwardRef(
4556
+ function ResizableContainer2({
4557
+ axis = "both",
4558
+ minWidth = DEFAULT_MIN_WIDTH,
4559
+ minHeight = DEFAULT_MIN_HEIGHT,
4560
+ maxWidth,
4561
+ maxHeight,
4562
+ defaultWidth,
4563
+ defaultHeight,
4564
+ width,
4565
+ height,
4566
+ step = DEFAULT_STEP,
4567
+ className,
4568
+ style,
4569
+ children,
4570
+ onSizeChange,
4571
+ ...rest
4572
+ }, ref) {
4573
+ const rootRef = React23.useRef(null);
4574
+ const contentRef = React23.useRef(null);
4575
+ const [internalWidth, setInternalWidth] = React23.useState(defaultWidth);
4576
+ const [internalHeight, setInternalHeight] = React23.useState(defaultHeight);
4577
+ const [isResizing, setIsResizing] = React23.useState(false);
4578
+ const [padRight, setPadRight] = React23.useState(0);
4579
+ const [padBottom, setPadBottom] = React23.useState(0);
4580
+ const resizeStateRef = React23.useRef({
4581
+ startX: 0,
4582
+ startY: 0,
4583
+ startWidth: 0,
4584
+ startHeight: 0,
4585
+ pointerId: null
4586
+ });
4587
+ const widthControlled = typeof width === "number";
4588
+ const heightControlled = typeof height === "number";
4589
+ const allowX = axis === "both" || axis === "x";
4590
+ const allowY = axis === "both" || axis === "y";
4591
+ const maxWidthLimit = maxWidth;
4592
+ const maxHeightLimit = maxHeight;
4593
+ const vThumb = useScrollbarMetrics2(contentRef, "vertical", padBottom);
4594
+ const hThumb = useScrollbarMetrics2(contentRef, "horizontal", padRight);
4595
+ React23.useEffect(() => {
4596
+ setPadRight(vThumb.visible ? TRACK_PADDING3 + 10 : 0);
4597
+ }, [vThumb.visible]);
4598
+ React23.useEffect(() => {
4599
+ setPadBottom(hThumb.visible ? TRACK_PADDING3 + 10 : 0);
4600
+ }, [hThumb.visible]);
4601
+ const { onThumbPointerDown: handleVThumbDown, startDrag: startVDrag } = useThumbDrag2(
4602
+ contentRef,
4603
+ "vertical",
4604
+ vThumb,
4605
+ padBottom
4606
+ );
4607
+ const { onThumbPointerDown: handleHThumbDown, startDrag: startHDrag } = useThumbDrag2(
4608
+ contentRef,
4609
+ "horizontal",
4610
+ hThumb,
4611
+ padRight
4612
+ );
4613
+ const handleTrackPointerDown = React23.useCallback(
4614
+ (axis2, thumb, startDrag, event) => {
4615
+ const el = contentRef.current;
4616
+ if (!el) return;
4617
+ event.preventDefault();
4618
+ event.stopPropagation();
4619
+ const rect = event.currentTarget.getBoundingClientRect();
4620
+ const clickOffset = axis2 === "vertical" ? event.clientY - rect.top : event.clientX - rect.left;
4621
+ const trackLength = axis2 === "vertical" ? rect.height : rect.width;
4622
+ const scrollRange = axis2 === "vertical" ? el.scrollHeight - el.clientHeight : el.scrollWidth - el.clientWidth;
4623
+ if (scrollRange <= 0 || trackLength <= 0) return;
4624
+ const effective = Math.max(1, trackLength - thumb.size);
4625
+ const ratio = Math.max(0, Math.min(effective, clickOffset - thumb.size / 2)) / effective;
4626
+ const target = ratio * scrollRange;
4627
+ if (axis2 === "vertical") el.scrollTop = target;
4628
+ else el.scrollLeft = target;
4629
+ startDrag(event, axis2 === "vertical" ? el.scrollTop : el.scrollLeft);
4630
+ },
4631
+ []
4632
+ );
4633
+ const setRefs = React23.useCallback(
4634
+ (node) => {
4635
+ rootRef.current = node;
4636
+ if (typeof ref === "function") {
4637
+ ref(node);
4638
+ } else if (ref) {
4639
+ ref.current = node;
4640
+ }
4641
+ },
4642
+ [ref]
4643
+ );
4644
+ const clamp2 = React23.useCallback((value, min, max) => {
4645
+ return Math.max(min != null ? min : -Infinity, Math.min(max != null ? max : Infinity, value));
4646
+ }, []);
4647
+ const handlePointerDown = (event) => {
4648
+ var _a, _b;
4649
+ if (event.pointerType === "mouse" && event.button !== 0) return;
4650
+ event.preventDefault();
4651
+ const node = rootRef.current;
4652
+ if (!node) return;
4653
+ const startWidth = node.offsetWidth;
4654
+ const startHeight = node.offsetHeight;
4655
+ resizeStateRef.current = {
4656
+ startX: event.clientX,
4657
+ startY: event.clientY,
4658
+ startWidth,
4659
+ startHeight,
4660
+ pointerId: event.pointerId,
4661
+ maxWidthLimit,
4662
+ maxHeightLimit
4663
+ };
4664
+ setIsResizing(true);
4665
+ (_b = (_a = event.currentTarget).setPointerCapture) == null ? void 0 : _b.call(_a, event.pointerId);
4666
+ };
4667
+ const applySize = React23.useCallback(
4668
+ (nextWidth, nextHeight) => {
4669
+ if (allowX && !widthControlled) {
4670
+ setInternalWidth(nextWidth);
4671
+ }
4672
+ if (allowY && !heightControlled) {
4673
+ setInternalHeight(nextHeight);
4674
+ }
4675
+ onSizeChange == null ? void 0 : onSizeChange({ width: nextWidth, height: nextHeight });
4676
+ },
4677
+ [allowX, allowY, heightControlled, onSizeChange, widthControlled]
4678
+ );
4679
+ const handlePointerMove = (event) => {
4680
+ if (!isResizing) return;
4681
+ const { startX, startY, startWidth, startHeight } = resizeStateRef.current;
4682
+ const maxWidthLimit2 = resizeStateRef.current.maxWidthLimit;
4683
+ const maxHeightLimit2 = resizeStateRef.current.maxHeightLimit;
4684
+ const deltaX = event.clientX - startX;
4685
+ const deltaY = event.clientY - startY;
4686
+ const nextWidth = allowX ? clamp2(startWidth + deltaX, minWidth, maxWidthLimit2) : widthControlled ? width != null ? width : startWidth : internalWidth != null ? internalWidth : startWidth;
4687
+ const nextHeight = allowY ? clamp2(startHeight + deltaY, minHeight, maxHeightLimit2) : heightControlled ? height != null ? height : startHeight : internalHeight != null ? internalHeight : startHeight;
4688
+ applySize(nextWidth, nextHeight);
4689
+ };
4690
+ const handlePointerUp = (event) => {
4691
+ var _a, _b;
4692
+ if (!isResizing) return;
4693
+ setIsResizing(false);
4694
+ if (resizeStateRef.current.pointerId !== null) {
4695
+ (_b = (_a = event.currentTarget).releasePointerCapture) == null ? void 0 : _b.call(_a, resizeStateRef.current.pointerId);
4696
+ }
4697
+ resizeStateRef.current.pointerId = null;
4698
+ };
4699
+ const handleKeyDown = (event) => {
4700
+ var _a, _b;
4701
+ let deltaX = 0;
4702
+ let deltaY = 0;
4703
+ switch (event.key) {
4704
+ case "ArrowLeft":
4705
+ if (allowX) deltaX = -step;
4706
+ break;
4707
+ case "ArrowRight":
4708
+ if (allowX) deltaX = step;
4709
+ break;
4710
+ case "ArrowUp":
4711
+ if (allowY) deltaY = -step;
4712
+ break;
4713
+ case "ArrowDown":
4714
+ if (allowY) deltaY = step;
4715
+ break;
4716
+ default:
4717
+ return;
4718
+ }
4719
+ if (deltaX === 0 && deltaY === 0) {
4720
+ return;
4721
+ }
4722
+ event.preventDefault();
4723
+ const node = rootRef.current;
4724
+ const measuredWidth = (_a = node == null ? void 0 : node.offsetWidth) != null ? _a : 0;
4725
+ const measuredHeight = (_b = node == null ? void 0 : node.offsetHeight) != null ? _b : 0;
4726
+ const limitWidth = maxWidthLimit;
4727
+ const limitHeight = maxHeightLimit;
4728
+ const baseWidth = widthControlled ? width != null ? width : measuredWidth : internalWidth != null ? internalWidth : measuredWidth;
4729
+ const baseHeight = heightControlled ? height != null ? height : measuredHeight : internalHeight != null ? internalHeight : measuredHeight;
4730
+ const nextWidth = allowX ? clamp2(baseWidth + deltaX, minWidth, limitWidth) : baseWidth;
4731
+ const nextHeight = allowY ? clamp2(baseHeight + deltaY, minHeight, limitHeight) : baseHeight;
4732
+ applySize(nextWidth, nextHeight);
4733
+ };
4734
+ const resolvedWidth = widthControlled ? width : internalWidth;
4735
+ const resolvedHeight = heightControlled ? height : internalHeight;
4736
+ const sizeStyle = {
4737
+ ...resolvedWidth !== void 0 ? { width: resolvedWidth } : null,
4738
+ ...resolvedHeight !== void 0 ? { height: resolvedHeight } : null,
4739
+ ...minWidth !== void 0 ? { minWidth } : null,
4740
+ ...minHeight !== void 0 ? { minHeight } : null,
4741
+ ...maxWidthLimit !== void 0 ? { maxWidth: maxWidthLimit } : null,
4742
+ ...maxHeightLimit !== void 0 ? { maxHeight: maxHeightLimit } : null
4743
+ };
4744
+ const vSlot = padRight || TRACK_PADDING3;
4745
+ const hSlot = padBottom || TRACK_PADDING3;
4746
+ const vOffset = Math.max(TRACK_PADDING3, (vSlot - TRACK_THICKNESS3) / 2);
4747
+ const hOffset = Math.max(TRACK_PADDING3, (hSlot - TRACK_THICKNESS3) / 2);
4748
+ const hBottom = Math.max(TRACK_PADDING3 / 2, (hSlot - TRACK_THICKNESS3) / 2);
4749
+ return /* @__PURE__ */ jsxs25(
4750
+ "div",
4751
+ {
4752
+ ...rest,
4753
+ ref: setRefs,
4754
+ className: clsx25("rui-resizable", "rui-root", className),
4755
+ style: { ...style, ...sizeStyle },
4756
+ "data-axis": axis,
4757
+ "data-resizing": isResizing ? "true" : void 0,
4758
+ "data-scrollbar-x": hThumb.visible ? "true" : void 0,
4759
+ "data-scrollbar-y": vThumb.visible ? "true" : void 0,
4760
+ children: [
4761
+ /* @__PURE__ */ jsx27(
4762
+ "div",
4763
+ {
4764
+ ref: contentRef,
4765
+ className: "rui-resizable__content",
4766
+ style: {
4767
+ paddingRight: `calc(var(--rui-resize-content-padding) + ${padRight}px)`,
4768
+ paddingBottom: `calc(var(--rui-resize-content-padding) + ${padBottom}px)`
4769
+ },
4770
+ children
4771
+ }
4772
+ ),
4773
+ vThumb.visible ? /* @__PURE__ */ jsx27(
4774
+ "div",
4775
+ {
4776
+ className: "rui-resizable__scrollbar rui-resizable__scrollbar--vertical",
4777
+ style: {
4778
+ right: vOffset,
4779
+ top: TRACK_PADDING3 + V_TRACK_INSET2,
4780
+ bottom: TRACK_PADDING3 + V_TRACK_INSET2,
4781
+ width: TRACK_THICKNESS3
4782
+ },
4783
+ onPointerDown: (e) => handleTrackPointerDown("vertical", vThumb, startVDrag, e),
4784
+ children: /* @__PURE__ */ jsx27("div", { className: "rui-resizable__scrollbar-track", children: /* @__PURE__ */ jsx27(
4785
+ "div",
4786
+ {
4787
+ className: "rui-resizable__scrollbar-thumb",
4788
+ style: { height: `${vThumb.size}px`, top: `${vThumb.offset}px` },
4789
+ onPointerDown: handleVThumbDown
4790
+ }
4791
+ ) })
4792
+ }
4793
+ ) : null,
4794
+ hThumb.visible ? /* @__PURE__ */ jsx27(
4795
+ "div",
4796
+ {
4797
+ className: "rui-resizable__scrollbar rui-resizable__scrollbar--horizontal",
4798
+ style: {
4799
+ left: hOffset + TRACK_INSET2,
4800
+ right: hOffset + TRACK_INSET2,
4801
+ bottom: hBottom,
4802
+ height: TRACK_THICKNESS3
4803
+ },
4804
+ onPointerDown: (e) => handleTrackPointerDown("horizontal", hThumb, startHDrag, e),
4805
+ children: /* @__PURE__ */ jsx27("div", { className: "rui-resizable__scrollbar-track", children: /* @__PURE__ */ jsx27(
4806
+ "div",
4807
+ {
4808
+ className: "rui-resizable__scrollbar-thumb",
4809
+ style: { width: `${hThumb.size}px`, left: `${hThumb.offset}px` },
4810
+ onPointerDown: handleHThumbDown
4811
+ }
4812
+ ) })
4813
+ }
4814
+ ) : null,
4815
+ /* @__PURE__ */ jsx27(
4816
+ "button",
4817
+ {
4818
+ type: "button",
4819
+ className: "rui-resizable__handle",
4820
+ "aria-label": "Resize",
4821
+ onPointerDown: handlePointerDown,
4822
+ onPointerMove: handlePointerMove,
4823
+ onPointerUp: handlePointerUp,
4824
+ onPointerCancel: handlePointerUp,
4825
+ onKeyDown: handleKeyDown,
4826
+ children: /* @__PURE__ */ jsx27(
4827
+ "svg",
4828
+ {
4829
+ viewBox: "0 0 16 16",
4830
+ "aria-hidden": "true",
4831
+ className: "rui-resizable__handle-icon",
4832
+ fill: "none",
4833
+ stroke: "currentColor",
4834
+ strokeWidth: "1.5",
4835
+ strokeLinecap: "round",
4836
+ children: /* @__PURE__ */ jsx27("path", { d: "M7 15 L15 7 M11 15 L15 11 M3 15 L15 3" })
4837
+ }
4838
+ )
4839
+ }
4840
+ )
4841
+ ]
4842
+ }
4843
+ );
4844
+ }
4845
+ );
4846
+
3992
4847
  // components/Toggle/Toggle.tsx
3993
- import * as React22 from "react";
3994
- import { twMerge as twMerge25 } from "tailwind-merge";
3995
- import { jsx as jsx26 } from "react/jsx-runtime";
3996
- var Toggle = React22.forwardRef(function Toggle2({ checked, defaultChecked = false, onChange, disabled, className, onClick, ...rest }, ref) {
4848
+ import * as React24 from "react";
4849
+ import clsx26 from "clsx";
4850
+ import "./Toggle-H2VEMC4W.css";
4851
+ import { jsx as jsx28 } from "react/jsx-runtime";
4852
+ var Toggle = React24.forwardRef(function Toggle2({ checked, defaultChecked = false, onChange, disabled, className, onClick, ...rest }, ref) {
3997
4853
  const isControlled = typeof checked === "boolean";
3998
- const [internalChecked, setInternalChecked] = React22.useState(defaultChecked);
4854
+ const [internalChecked, setInternalChecked] = React24.useState(defaultChecked);
3999
4855
  const resolvedChecked = isControlled ? !!checked : internalChecked;
4000
4856
  const handleClick = (event) => {
4001
4857
  if (disabled) {
@@ -4009,18 +4865,18 @@ var Toggle = React22.forwardRef(function Toggle2({ checked, defaultChecked = fal
4009
4865
  onChange == null ? void 0 : onChange(next);
4010
4866
  onClick == null ? void 0 : onClick(event);
4011
4867
  };
4012
- const buttonClasses = twMerge25(
4013
- "relative inline-flex h-7 w-12 shrink-0 cursor-pointer items-center rounded-full border border-slate-300 bg-slate-200 transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-slate-500 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-100",
4014
- "dark:border-zinc-700/70 dark:bg-zinc-900/70 dark:focus-visible:ring-offset-slate-950",
4015
- resolvedChecked && "border-slate-400 bg-slate-500/40 shadow-[0_0_0_1px_rgba(148,163,184,0.45)] dark:border-zinc-500 dark:bg-zinc-500",
4016
- disabled && "cursor-not-allowed opacity-60",
4868
+ const buttonClasses = clsx26(
4869
+ "rui-toggle__button rui-root",
4870
+ resolvedChecked && "rui-toggle__button--checked",
4871
+ disabled && "rui-toggle__button--disabled rui-toggle__is-disabled",
4017
4872
  className
4018
4873
  );
4019
- const thumbClasses = twMerge25(
4020
- "pointer-events-none absolute left-1 top-[3px] size-5 rounded-full bg-white text-zinc-900 shadow-lg shadow-black/30 transition-transform duration-200",
4021
- resolvedChecked ? "translate-x-[19px]" : "translate-x-0"
4874
+ const thumbClasses = clsx26(
4875
+ "rui-toggle__thumb",
4876
+ resolvedChecked ? "rui-toggle__thumb--checked" : "rui-toggle__thumb--unchecked",
4877
+ disabled && "rui-toggle__thumb--disabled"
4022
4878
  );
4023
- return /* @__PURE__ */ jsx26(
4879
+ return /* @__PURE__ */ jsx28(
4024
4880
  "button",
4025
4881
  {
4026
4882
  ...rest,
@@ -4032,7 +4888,7 @@ var Toggle = React22.forwardRef(function Toggle2({ checked, defaultChecked = fal
4032
4888
  "data-state": resolvedChecked ? "on" : "off",
4033
4889
  className: buttonClasses,
4034
4890
  onClick: handleClick,
4035
- children: /* @__PURE__ */ jsx26("span", { "aria-hidden": "true", className: thumbClasses })
4891
+ children: /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", className: thumbClasses })
4036
4892
  }
4037
4893
  );
4038
4894
  });
@@ -4057,9 +4913,11 @@ export {
4057
4913
  Popover,
4058
4914
  Progress,
4059
4915
  Radio,
4916
+ ResizableContainer,
4060
4917
  Select,
4061
4918
  Slider,
4062
4919
  StackedList,
4920
+ TabGroup,
4063
4921
  Table,
4064
4922
  Textarea,
4065
4923
  Toggle_default as Toggle