react-ui-suite 0.1.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,
@@ -1803,7 +1865,19 @@ function Select({
1803
1865
  const id = React11.useId();
1804
1866
  const listboxId = `${id}-listbox`;
1805
1867
  const [open, setOpen] = React11.useState(false);
1806
- const [activeIndex, setActiveIndex] = React11.useState(-1);
1868
+ const [activeIndexState, setActiveIndexState] = React11.useState(-1);
1869
+ const activeIndexRef = React11.useRef(activeIndexState);
1870
+ const setActiveIndex = React11.useCallback(
1871
+ (value2) => {
1872
+ setActiveIndexState((prev) => {
1873
+ const next = typeof value2 === "function" ? value2(prev) : value2;
1874
+ activeIndexRef.current = next;
1875
+ return next;
1876
+ });
1877
+ },
1878
+ []
1879
+ );
1880
+ const activeIndex = activeIndexState;
1807
1881
  const [selected, setSelected] = useControlledState(value, defaultValue != null ? defaultValue : null);
1808
1882
  useOutsideClick(
1809
1883
  [containerRef],
@@ -1900,7 +1974,7 @@ function Select({
1900
1974
  case "Enter":
1901
1975
  case " ":
1902
1976
  e.preventDefault();
1903
- if (activeIndex >= 0) commitSelection(activeIndex);
1977
+ if (activeIndexRef.current >= 0) commitSelection(activeIndexRef.current);
1904
1978
  break;
1905
1979
  case "Escape":
1906
1980
  e.preventDefault();
@@ -1916,10 +1990,10 @@ function Select({
1916
1990
  el == null ? void 0 : el.scrollIntoView({ block: "nearest" });
1917
1991
  }, [open, activeIndex]);
1918
1992
  const displayValue = (_b = selectedOption == null ? void 0 : selectedOption.label) != null ? _b : "";
1919
- const highlightBorder = "border-slate-400 dark:border-slate-500";
1993
+ const highlightBorder = "rui-select__highlightBorder";
1920
1994
  const listboxHighlight = open ? highlightBorder : "";
1921
- return /* @__PURE__ */ jsxs11("div", { className: "space-y-1.5", children: [
1922
- 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,
1923
1997
  /* @__PURE__ */ jsx13(
1924
1998
  Dropdown,
1925
1999
  {
@@ -1929,12 +2003,12 @@ function Select({
1929
2003
  placeholder,
1930
2004
  displayValue,
1931
2005
  query: displayValue,
1932
- className: twMerge12(
1933
- "w-full",
1934
- 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",
1935
2009
  className
1936
2010
  ),
1937
- inputClassName: "font-semibold",
2011
+ inputClassName: "rui-select__input",
1938
2012
  highlightClass: highlightBorder,
1939
2013
  ariaControls: listboxId,
1940
2014
  ariaLabel: label,
@@ -1975,7 +2049,7 @@ function Select({
1975
2049
  }
1976
2050
  setOpen((o) => !o);
1977
2051
  },
1978
- children: open && /* @__PURE__ */ jsx13(Popover, { className: listboxHighlight, children: ({ scrollRef }) => {
2052
+ children: open && /* @__PURE__ */ jsx13(Popover, { anchorRef: containerRef, className: listboxHighlight, children: ({ scrollRef }) => {
1979
2053
  popoverListRef.current = scrollRef;
1980
2054
  return /* @__PURE__ */ jsx13(
1981
2055
  "ul",
@@ -1983,11 +2057,11 @@ function Select({
1983
2057
  ref: scrollRef,
1984
2058
  id: listboxId,
1985
2059
  role: "listbox",
1986
- className: "combobox-scrollbar max-h-64 overflow-auto px-1 pr-4",
2060
+ className: "rui-select__list",
1987
2061
  children: options.map((opt, index) => {
1988
2062
  const isSelected = selected === opt.value;
1989
2063
  const isActive = activeIndex === index;
1990
- 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(
1991
2065
  "button",
1992
2066
  {
1993
2067
  type: "button",
@@ -1996,18 +2070,17 @@ function Select({
1996
2070
  disabled: opt.disabled,
1997
2071
  onMouseEnter: () => !opt.disabled && setActiveIndex(index),
1998
2072
  onClick: () => commitSelection(index),
1999
- className: twMerge12(
2000
- "flex w-full items-center gap-3 rounded-xl px-3 py-2 text-left text-sm transition",
2001
- 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",
2002
- isSelected && "font-semibold",
2003
- 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"
2004
2077
  ),
2005
2078
  children: [
2006
- /* @__PURE__ */ jsxs11("span", { className: "flex-1 text-left", children: [
2007
- /* @__PURE__ */ jsx13("span", { className: "block text-slate-900 dark:text-zinc-100", children: opt.label }),
2008
- 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
2009
2082
  ] }),
2010
- 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" })
2011
2084
  ]
2012
2085
  }
2013
2086
  ) }, opt.value);
@@ -2017,12 +2090,14 @@ function Select({
2017
2090
  } })
2018
2091
  }
2019
2092
  ),
2020
- description ? /* @__PURE__ */ jsx13("p", { className: "text-xs text-slate-500 dark:text-zinc-400", children: description }) : null,
2021
- 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
2022
2095
  ] });
2023
2096
  }
2024
2097
 
2025
2098
  // components/DatePicker/DatePicker.tsx
2099
+ import clsx13 from "clsx";
2100
+ import "./DatePicker-ICNOIGZ2.css";
2026
2101
  import { Fragment, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
2027
2102
  function formatLocalDateString(year, month, day) {
2028
2103
  const y = String(year).padStart(4, "0");
@@ -2030,7 +2105,10 @@ function formatLocalDateString(year, month, day) {
2030
2105
  const d = String(day).padStart(2, "0");
2031
2106
  return `${y}-${m}-${d}`;
2032
2107
  }
2033
- 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) {
2034
2112
  if (!value) return null;
2035
2113
  const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value.trim());
2036
2114
  if (!match) return null;
@@ -2038,19 +2116,19 @@ function parseLocalDateString(value) {
2038
2116
  const year = Number(y);
2039
2117
  const month = Number(m) - 1;
2040
2118
  const day = Number(d);
2041
- const date = new Date(year, month, day);
2119
+ const date = toDateFromParts(mode, year, month, day);
2042
2120
  if (Number.isNaN(date.getTime())) return null;
2043
2121
  return { date, year, month, day };
2044
2122
  }
2045
- function getMonthDays(year, month) {
2046
- const first = new Date(year, month, 1);
2047
- const start = first.getDay();
2048
- 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();
2049
2128
  const grid = [];
2050
2129
  for (let i = 0; i < start; i += 1) grid.push({ day: null });
2051
2130
  for (let d = 1; d <= days; d += 1) {
2052
- const date = new Date(year, month, d);
2053
- grid.push({ day: d, date: date.toISOString().slice(0, 10) });
2131
+ grid.push({ day: d, date: formatLocalDateString(year, month, d) });
2054
2132
  }
2055
2133
  return grid;
2056
2134
  }
@@ -2065,7 +2143,8 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2065
2143
  onChange,
2066
2144
  type = "date",
2067
2145
  timeIntervalMinutes = 30,
2068
- use24HourClock = true
2146
+ use24HourClock = true,
2147
+ dateMode = "local"
2069
2148
  }, ref) {
2070
2149
  const isDate = type === "date";
2071
2150
  const clampInterval = Math.max(1, Math.min(60, Math.floor(timeIntervalMinutes)));
@@ -2089,7 +2168,7 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2089
2168
  [use24HourClock]
2090
2169
  );
2091
2170
  const initial = (() => {
2092
- var _a, _b, _c;
2171
+ var _a, _b;
2093
2172
  if (!isDate) {
2094
2173
  return (_b = (_a = normalizeTimeString(value)) != null ? _a : normalizeTimeString(defaultValue)) != null ? _b : (() => {
2095
2174
  const now = /* @__PURE__ */ new Date();
@@ -2101,27 +2180,36 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2101
2180
  return `${String(safeH).padStart(2, "0")}:${String(m).padStart(2, "0")}`;
2102
2181
  })();
2103
2182
  }
2104
- const normalized = (_c = parseLocalDateString(value != null ? value : defaultValue)) == null ? void 0 : _c.date;
2105
- if (normalized)
2106
- return formatLocalDateString(
2107
- normalized.getFullYear(),
2108
- normalized.getMonth(),
2109
- normalized.getDate()
2110
- );
2183
+ const normalized = parseDateString(value != null ? value : defaultValue, dateMode);
2184
+ if (normalized) return formatLocalDateString(normalized.year, normalized.month, normalized.day);
2111
2185
  const today = /* @__PURE__ */ new Date();
2112
- 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);
2113
2190
  })();
2114
2191
  const [open, setOpen] = React12.useState(false);
2115
2192
  const [current, setCurrent] = React12.useState(initial);
2116
2193
  const [month, setMonth] = React12.useState(() => {
2117
- var _a, _b;
2118
- const base = (_b = (_a = parseLocalDateString(initial)) == null ? void 0 : _a.date) != null ? _b : /* @__PURE__ */ new Date();
2119
- 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
+ };
2120
2207
  });
2121
2208
  const [viewMode, setViewMode] = React12.useState("day");
2122
2209
  const dropdownRef = React12.useRef(null);
2123
2210
  const toggleRef = React12.useRef(null);
2124
2211
  const inputInnerRef = React12.useRef(null);
2212
+ const popoverRef = React12.useRef(null);
2125
2213
  const suppressToggleRef = React12.useRef(false);
2126
2214
  const canvasRef = React12.useRef(null);
2127
2215
  const [useShortLabel, setUseShortLabel] = React12.useState(false);
@@ -2134,10 +2222,14 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2134
2222
  },
2135
2223
  [ref]
2136
2224
  );
2137
- useOutsideClick(
2138
- [dropdownRef],
2139
- () => setOpen(false)
2225
+ const outsideClickRefs = React12.useMemo(
2226
+ () => [
2227
+ dropdownRef,
2228
+ popoverRef
2229
+ ],
2230
+ []
2140
2231
  );
2232
+ useOutsideClick(outsideClickRefs, () => setOpen(false));
2141
2233
  const commit = (next) => {
2142
2234
  setCurrent(next);
2143
2235
  onChange == null ? void 0 : onChange(next);
@@ -2146,26 +2238,28 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2146
2238
  };
2147
2239
  const parsedDate = React12.useMemo(() => {
2148
2240
  var _a;
2149
- const parsed = parseLocalDateString(current);
2241
+ const parsed = parseDateString(current, dateMode);
2150
2242
  return (_a = parsed == null ? void 0 : parsed.date) != null ? _a : null;
2151
- }, [current]);
2243
+ }, [current, dateMode]);
2152
2244
  const longDisplayLabel = React12.useMemo(() => {
2153
2245
  if (!parsedDate) return current;
2154
2246
  return parsedDate.toLocaleDateString(void 0, {
2155
2247
  weekday: "short",
2156
2248
  month: "short",
2157
2249
  day: "numeric",
2158
- year: "numeric"
2250
+ year: "numeric",
2251
+ timeZone: dateMode === "utc" ? "UTC" : void 0
2159
2252
  });
2160
- }, [parsedDate, current]);
2253
+ }, [parsedDate, current, dateMode]);
2161
2254
  const shortDisplayLabel = React12.useMemo(() => {
2162
2255
  if (!parsedDate) return current;
2163
2256
  return parsedDate.toLocaleDateString(void 0, {
2164
2257
  month: "2-digit",
2165
2258
  day: "2-digit",
2166
- year: "2-digit"
2259
+ year: "2-digit",
2260
+ timeZone: dateMode === "utc" ? "UTC" : void 0
2167
2261
  });
2168
- }, [parsedDate, current]);
2262
+ }, [parsedDate, current, dateMode]);
2169
2263
  const displayLabel = useShortLabel ? shortDisplayLabel : longDisplayLabel;
2170
2264
  const timeOptions = React12.useMemo(() => {
2171
2265
  const opts = [];
@@ -2179,7 +2273,7 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2179
2273
  }
2180
2274
  return opts;
2181
2275
  }, [clampInterval, formatTimeLabel]);
2182
- 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";
2183
2277
  const monthNames = React12.useMemo(
2184
2278
  () => ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
2185
2279
  []
@@ -2211,14 +2305,18 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2211
2305
  };
2212
2306
  const rangeStart = decadeStart - 1;
2213
2307
  const rangeEnd = decadeStart + 10;
2214
- 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", {
2215
2309
  month: "long",
2216
- year: "numeric"
2310
+ year: "numeric",
2311
+ timeZone: dateMode === "utc" ? "UTC" : void 0
2217
2312
  });
2218
2313
  function openPicker() {
2219
2314
  if (disabled) return;
2220
2315
  const base = parsedDate != null ? parsedDate : /* @__PURE__ */ new Date();
2221
- 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
+ });
2222
2320
  setViewMode("day");
2223
2321
  setOpen(true);
2224
2322
  }
@@ -2267,13 +2365,13 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2267
2365
  placeholder: "Select time",
2268
2366
  disabled,
2269
2367
  className,
2270
- 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" }) })
2271
2369
  }
2272
2370
  );
2273
2371
  }
2274
- return /* @__PURE__ */ jsxs12("div", { className: "space-y-1.5", children: [
2275
- label ? /* @__PURE__ */ jsx14("p", { className: "text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-zinc-400", children: label }) : null,
2276
- /* @__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(
2277
2375
  Dropdown,
2278
2376
  {
2279
2377
  ref: dropdownRef,
@@ -2282,12 +2380,12 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2282
2380
  placeholder: "",
2283
2381
  displayValue: displayLabel,
2284
2382
  query: displayLabel,
2285
- className: "w-full",
2286
- inputClassName: twMerge13("min-w-0 font-semibold", className),
2287
- shellClassName: twMerge13(
2288
- 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"
2289
2387
  ),
2290
- 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" }) }),
2291
2389
  highlightClass: highlightBorder,
2292
2390
  ariaControls: popoverId,
2293
2391
  ariaLabel: label,
@@ -2338,109 +2436,118 @@ var DatePicker = React12.forwardRef(function DatePicker2({
2338
2436
  }
2339
2437
  setOpen((o) => !o);
2340
2438
  },
2341
- children: open && /* @__PURE__ */ jsx14(Popover, { className: twMerge13("p-3", highlightBorder), children: () => /* @__PURE__ */ jsxs12("div", { className: "space-y-3", id: popoverId, children: [
2342
- /* @__PURE__ */ jsxs12("div", { className: "flex items-center justify-between text-sm text-slate-600 dark:text-zinc-300", children: [
2343
- /* @__PURE__ */ jsx14(
2344
- Button,
2345
- {
2346
- type: "button",
2347
- onClick: goPrev,
2348
- 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",
2349
- children: /* @__PURE__ */ jsx14("span", { style: { transform: "translateY(-1.5px)" }, children: "<" })
2350
- }
2351
- ),
2352
- viewMode === "year" ? /* @__PURE__ */ jsx14("span", { className: "font-semibold text-slate-900 dark:text-zinc-100", children: headerLabel }) : /* @__PURE__ */ jsx14(
2353
- "button",
2354
- {
2355
- type: "button",
2356
- onClick: () => setViewMode((prev) => prev === "day" ? "month" : "year"),
2357
- className: "font-semibold text-slate-900 transition hover:underline dark:text-zinc-100",
2358
- children: headerLabel
2359
- }
2360
- ),
2361
- /* @__PURE__ */ jsx14(
2362
- Button,
2363
- {
2364
- type: "button",
2365
- onClick: goNext,
2366
- 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",
2367
- children: /* @__PURE__ */ jsx14("span", { style: { transform: "translateY(-1.5px)" }, children: ">" })
2368
- }
2369
- )
2370
- ] }),
2371
- viewMode === "day" ? /* @__PURE__ */ jsxs12(Fragment, { children: [
2372
- /* @__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)) }),
2373
- /* @__PURE__ */ jsx14("div", { className: "grid grid-cols-7 gap-1", children: getMonthDays(month.year, month.month).map((cell, idx) => {
2374
- var _a, _b;
2375
- const isSelected = cell.date === current;
2376
- return /* @__PURE__ */ jsx14(
2377
- "button",
2378
- {
2379
- type: "button",
2380
- disabled: !cell.date,
2381
- onClick: () => {
2382
- if (!cell.date) return;
2383
- commit(cell.date);
2384
- },
2385
- className: twMerge13(
2386
- "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",
2387
- 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",
2388
- !cell.date && "opacity-30"
2389
- ),
2390
- children: (_b = cell.day) != null ? _b : ""
2391
- },
2392
- `${(_a = cell.date) != null ? _a : "empty"}-${idx}`
2393
- );
2394
- }) })
2395
- ] }) : viewMode === "month" ? /* @__PURE__ */ jsx14("div", { className: "grid grid-cols-3 gap-2", children: monthNames.map((name, idx) => {
2396
- const isSelected = (parsedDate == null ? void 0 : parsedDate.getFullYear()) === month.year && (parsedDate == null ? void 0 : parsedDate.getMonth()) === idx;
2397
- return /* @__PURE__ */ jsx14(
2398
- "button",
2399
- {
2400
- type: "button",
2401
- onClick: () => {
2402
- setMonth((prev) => ({ ...prev, month: idx }));
2403
- setViewMode("day");
2404
- },
2405
- className: twMerge13(
2406
- "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",
2407
- 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
+ }
2408
2455
  ),
2409
- children: name
2410
- },
2411
- name
2412
- );
2413
- }) }) : /* @__PURE__ */ jsx14("div", { className: "grid grid-cols-3 gap-2", children: Array.from({ length: 12 }, (_, i) => rangeStart + i).map((yr) => {
2414
- const isSelected = (parsedDate == null ? void 0 : parsedDate.getFullYear()) === yr;
2415
- return /* @__PURE__ */ jsx14(
2416
- "button",
2417
- {
2418
- type: "button",
2419
- onClick: () => {
2420
- setMonth((prev) => ({ ...prev, year: yr }));
2421
- setViewMode("month");
2422
- },
2423
- className: twMerge13(
2424
- "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",
2425
- 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
+ }
2426
2464
  ),
2427
- children: yr
2428
- },
2429
- yr
2430
- );
2431
- }) })
2432
- ] }) })
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
+ )
2433
2539
  }
2434
2540
  ) }),
2435
- description ? /* @__PURE__ */ jsx14("p", { className: "text-xs text-slate-500 dark:text-zinc-400", children: description }) : null,
2436
- 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
2437
2543
  ] });
2438
2544
  });
2439
2545
 
2440
2546
  // components/Dialog/Dialog.tsx
2441
2547
  import * as React13 from "react";
2442
- import { createPortal } from "react-dom";
2443
- 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";
2444
2551
  import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
2445
2552
  function Dialog({
2446
2553
  open,
@@ -2454,6 +2561,8 @@ function Dialog({
2454
2561
  }) {
2455
2562
  const overlayRef = React13.useRef(null);
2456
2563
  const dialogRef = React13.useRef(null);
2564
+ const titleId = React13.useId();
2565
+ const descriptionId = React13.useId();
2457
2566
  const dragState = React13.useRef(null);
2458
2567
  const [dragOffset, setDragOffset] = React13.useState({ x: 0, y: 0 });
2459
2568
  React13.useEffect(() => {
@@ -2462,11 +2571,40 @@ function Dialog({
2462
2571
  if (event.key === "Escape") {
2463
2572
  event.preventDefault();
2464
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
+ }
2465
2603
  }
2466
2604
  };
2467
2605
  window.addEventListener("keydown", handleKey);
2468
2606
  return () => window.removeEventListener("keydown", handleKey);
2469
- }, [open, onClose]);
2607
+ }, [open, onClose, modal]);
2470
2608
  React13.useEffect(() => {
2471
2609
  var _a;
2472
2610
  if (!open) return;
@@ -2561,56 +2699,58 @@ function Dialog({
2561
2699
  ref: dialogRef,
2562
2700
  role: "dialog",
2563
2701
  "aria-modal": modal || void 0,
2702
+ "aria-labelledby": titleId,
2703
+ "aria-describedby": description ? descriptionId : void 0,
2564
2704
  tabIndex: -1,
2565
- "aria-label": title,
2566
- className: twMerge14(
2567
- "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",
2568
- modal ? "" : "pointer-events-auto",
2569
- 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"
2570
2709
  ),
2571
2710
  style: { transform: `translate(${dragOffset.x}px, ${dragOffset.y}px)` },
2572
2711
  onPointerDown: onDragPointerDown,
2573
2712
  children: [
2574
- /* @__PURE__ */ jsxs13("div", { className: "flex items-start justify-between gap-3", children: [
2713
+ /* @__PURE__ */ jsxs13("div", { className: "rui-dialog__header", children: [
2575
2714
  /* @__PURE__ */ jsxs13("div", { children: [
2576
- /* @__PURE__ */ jsx15("p", { className: "text-xs font-semibold uppercase tracking-[0.3em] text-slate-500 dark:text-zinc-400", children: "Dialog" }),
2577
- /* @__PURE__ */ jsx15("h2", { className: "text-xl font-semibold text-slate-900 dark:text-zinc-100", children: title }),
2578
- 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
2579
2718
  ] }),
2580
2719
  /* @__PURE__ */ jsx15(
2581
2720
  Button,
2582
2721
  {
2583
2722
  onClick: onClose,
2584
2723
  "aria-label": "Close dialog",
2585
- className: "size-8 !px-0 !py-0 text-sm font-semibold",
2586
- children: "X"
2724
+ className: "rui-dialog__close-button",
2725
+ children: "\xD7"
2587
2726
  }
2588
2727
  )
2589
2728
  ] }),
2590
- /* @__PURE__ */ jsx15("div", { className: "mt-4 space-y-3 text-sm text-slate-700 dark:text-zinc-300", children }),
2591
- 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
2592
2731
  ]
2593
2732
  }
2594
2733
  );
2595
- return createPortal(
2734
+ return createPortal2(
2596
2735
  modal ? /* @__PURE__ */ jsx15(
2597
2736
  "div",
2598
2737
  {
2599
2738
  ref: overlayRef,
2600
- className: "fixed inset-0 z-50 flex items-center justify-center bg-zinc-950/60 backdrop-blur-sm",
2601
- onMouseDown: (e) => {
2739
+ className: "rui-overlay-root rui-dialog__overlay",
2740
+ onPointerDown: (e) => {
2602
2741
  if (e.target === overlayRef.current) onClose();
2603
2742
  },
2604
2743
  children: dialogCard
2605
2744
  }
2606
- ) : /* @__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 }),
2607
2746
  document.body
2608
2747
  );
2609
2748
  }
2610
2749
 
2611
2750
  // components/Disclosure/Disclosure.tsx
2612
2751
  import * as React14 from "react";
2613
- import { twMerge as twMerge15 } from "tailwind-merge";
2752
+ import clsx15 from "clsx";
2753
+ import "./Disclosure-YZNVFFHQ.css";
2614
2754
  import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
2615
2755
  var Disclosure = React14.forwardRef(function Disclosure2({ title, children, className, subtle, ...rest }, ref) {
2616
2756
  const summaryId = React14.useId();
@@ -2619,9 +2759,10 @@ var Disclosure = React14.forwardRef(function Disclosure2({ title, children, clas
2619
2759
  {
2620
2760
  ...rest,
2621
2761
  ref,
2622
- className: twMerge15(
2623
- "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",
2624
- 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",
2625
2766
  className
2626
2767
  ),
2627
2768
  children: [
@@ -2629,13 +2770,13 @@ var Disclosure = React14.forwardRef(function Disclosure2({ title, children, clas
2629
2770
  "summary",
2630
2771
  {
2631
2772
  id: summaryId,
2632
- 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",
2633
2774
  children: [
2634
- /* @__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 }) }),
2635
2776
  /* @__PURE__ */ jsx16(
2636
2777
  "span",
2637
2778
  {
2638
- className: "text-slate-400 transition-transform duration-200 group-open:rotate-180 dark:text-zinc-500",
2779
+ className: "rui-disclosure__caret",
2639
2780
  "aria-hidden": "true",
2640
2781
  children: "\u25BE"
2641
2782
  }
@@ -2643,7 +2784,7 @@ var Disclosure = React14.forwardRef(function Disclosure2({ title, children, clas
2643
2784
  ]
2644
2785
  }
2645
2786
  ),
2646
- /* @__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 })
2647
2788
  ]
2648
2789
  }
2649
2790
  );
@@ -2651,7 +2792,8 @@ var Disclosure = React14.forwardRef(function Disclosure2({ title, children, clas
2651
2792
 
2652
2793
  // components/InputField/InputField.tsx
2653
2794
  import * as React15 from "react";
2654
- import { twMerge as twMerge16 } from "tailwind-merge";
2795
+ import clsx16 from "clsx";
2796
+ import "./InputField-TKTNGOH3.css";
2655
2797
  import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
2656
2798
  var InputField = React15.forwardRef(function InputField2({ label, description, error, leadingIcon, trailingLabel, className, id, disabled, ...rest }, ref) {
2657
2799
  const generatedId = React15.useId();
@@ -2660,27 +2802,26 @@ var InputField = React15.forwardRef(function InputField2({ label, description, e
2660
2802
  const errorId = React15.useId();
2661
2803
  const hintIds = [description ? descriptionId : null, error ? errorId : null].filter(Boolean);
2662
2804
  const resolvedAriaDescribedBy = hintIds.length ? hintIds.join(" ") : void 0;
2663
- const containerClasses = twMerge16(
2664
- "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",
2665
- disabled && "opacity-60",
2666
- 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"
2667
2808
  );
2668
- const inputClasses = twMerge16(
2669
- "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",
2670
2811
  className
2671
2812
  );
2672
- const leadingElm = leadingIcon ? /* @__PURE__ */ jsx17("span", { className: "text-slate-400 dark:text-zinc-500", "aria-hidden": "true", children: leadingIcon }) : null;
2673
- const trailingElm = trailingLabel ? /* @__PURE__ */ jsx17("span", { className: "text-xs font-semibold uppercase tracking-wide text-slate-400 dark:text-zinc-500", children: trailingLabel }) : null;
2674
- 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: [
2675
2816
  label ? /* @__PURE__ */ jsx17(
2676
2817
  "label",
2677
2818
  {
2678
2819
  htmlFor: inputId,
2679
- 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",
2680
2821
  children: label
2681
2822
  }
2682
2823
  ) : null,
2683
- /* @__PURE__ */ jsxs15("div", { className: containerClasses, children: [
2824
+ /* @__PURE__ */ jsxs15("div", { className: clsx16("rui-input-field__shell", containerClasses), children: [
2684
2825
  leadingElm,
2685
2826
  /* @__PURE__ */ jsx17(
2686
2827
  "input",
@@ -2696,14 +2837,15 @@ var InputField = React15.forwardRef(function InputField2({ label, description, e
2696
2837
  ),
2697
2838
  trailingElm
2698
2839
  ] }),
2699
- description ? /* @__PURE__ */ jsx17("p", { id: descriptionId, className: "text-xs text-slate-500 dark:text-zinc-400", children: description }) : null,
2700
- 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
2701
2842
  ] });
2702
2843
  });
2703
2844
 
2704
2845
  // components/NumberInput/NumberInput.tsx
2705
2846
  import * as React16 from "react";
2706
- import { twMerge as twMerge17 } from "tailwind-merge";
2847
+ import clsx17 from "clsx";
2848
+ import "./NumberInput-KTYVXS7K.css";
2707
2849
  import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
2708
2850
  var NumberInput = React16.forwardRef(
2709
2851
  function NumberInput2({
@@ -2711,6 +2853,7 @@ var NumberInput = React16.forwardRef(
2711
2853
  description,
2712
2854
  error,
2713
2855
  className,
2856
+ style,
2714
2857
  disabled,
2715
2858
  value,
2716
2859
  defaultValue = 0,
@@ -2718,7 +2861,8 @@ var NumberInput = React16.forwardRef(
2718
2861
  step = 1,
2719
2862
  suffix,
2720
2863
  min,
2721
- max
2864
+ max,
2865
+ scale = 1
2722
2866
  }, ref) {
2723
2867
  const [internal, setInternal] = React16.useState(defaultValue);
2724
2868
  const isControlled = typeof value === "number";
@@ -2728,38 +2872,82 @@ var NumberInput = React16.forwardRef(
2728
2872
  if (!isControlled) setInternal(clamped);
2729
2873
  onChange == null ? void 0 : onChange(clamped);
2730
2874
  };
2731
- return /* @__PURE__ */ jsxs16("div", { className: "space-y-1.5", children: [
2732
- 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,
2733
2887
  /* @__PURE__ */ jsxs16(
2734
2888
  "div",
2735
2889
  {
2736
- className: twMerge17(
2737
- "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",
2738
- disabled && "opacity-60",
2739
- 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"
2740
2894
  ),
2741
2895
  children: [
2742
- /* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1", children: [
2896
+ /* @__PURE__ */ jsxs16("div", { className: "rui-number-input__stepper", children: [
2743
2897
  /* @__PURE__ */ jsx18(
2744
- "button",
2898
+ Button,
2745
2899
  {
2746
2900
  type: "button",
2747
2901
  "aria-label": "Increase",
2748
2902
  onClick: () => update(resolved + step),
2749
- 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",
2750
2904
  disabled,
2751
- 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
+ )
2752
2923
  }
2753
2924
  ),
2754
2925
  /* @__PURE__ */ jsx18(
2755
- "button",
2926
+ Button,
2756
2927
  {
2757
2928
  type: "button",
2758
2929
  "aria-label": "Decrease",
2759
2930
  onClick: () => update(resolved - step),
2760
- 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",
2761
2932
  disabled,
2762
- 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
+ )
2763
2951
  }
2764
2952
  )
2765
2953
  ] }),
@@ -2774,56 +2962,46 @@ var NumberInput = React16.forwardRef(
2774
2962
  max,
2775
2963
  step,
2776
2964
  disabled,
2777
- className: twMerge17(
2778
- "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",
2779
2967
  className
2780
2968
  )
2781
2969
  }
2782
2970
  ),
2783
- 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
2784
2972
  ]
2785
2973
  }
2786
2974
  ),
2787
- description ? /* @__PURE__ */ jsx18("p", { className: "text-xs text-slate-500 dark:text-zinc-400", children: description }) : null,
2788
- 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
2789
2977
  ] });
2790
2978
  }
2791
2979
  );
2792
2980
 
2793
2981
  // components/OutputChip/OutputChip.tsx
2794
2982
  import * as React17 from "react";
2795
- import { twMerge as twMerge18 } from "tailwind-merge";
2983
+ import clsx18 from "clsx";
2984
+ import "./OutputChip-CN7R243G.css";
2796
2985
  import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
2797
- var toneStyles = {
2798
- neutral: { bg: "bg-slate-900", text: "text-white", ring: "ring-slate-300" },
2799
- success: { bg: "bg-emerald-500", text: "text-white", ring: "ring-emerald-200" },
2800
- warning: { bg: "bg-amber-500", text: "text-white", ring: "ring-amber-200" },
2801
- danger: { bg: "bg-rose-500", text: "text-white", ring: "ring-rose-200" }
2802
- };
2803
2986
  var OutputChip = React17.forwardRef(function OutputChip2({ children, className, tone = "neutral", label, ...rest }, ref) {
2804
- const styles = toneStyles[tone];
2805
2987
  return /* @__PURE__ */ jsxs17(
2806
2988
  "output",
2807
2989
  {
2808
2990
  ...rest,
2809
2991
  ref,
2810
- className: twMerge18(
2811
- "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",
2812
- styles.bg,
2813
- styles.text,
2814
- styles.ring,
2815
- className
2816
- ),
2992
+ "data-tone": tone,
2993
+ className: clsx18("rui-root", "rui-output-chip", className),
2817
2994
  children: [
2818
- label ? /* @__PURE__ */ jsx19("span", { className: "opacity-70", children: label }) : null,
2819
- /* @__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 })
2820
2997
  ]
2821
2998
  }
2822
2999
  );
2823
3000
  });
2824
3001
 
2825
3002
  // components/ProgressMeter/ProgressMeter.tsx
2826
- import { twMerge as twMerge19 } from "tailwind-merge";
3003
+ import clsx19 from "clsx";
3004
+ import "./ProgressMeter-6EOIFB3Y.css";
2827
3005
  import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
2828
3006
  function Progress({
2829
3007
  label,
@@ -2835,29 +3013,29 @@ function Progress({
2835
3013
  }) {
2836
3014
  const clamped = Math.min(max, Math.max(0, value));
2837
3015
  const percent = max === 0 ? 0 : Math.round(clamped / max * 100);
2838
- return /* @__PURE__ */ jsxs18("div", { className: twMerge19("space-y-1.5", className), children: [
2839
- label ? /* @__PURE__ */ jsxs18("div", { className: "flex items-center justify-between gap-3", children: [
2840
- /* @__PURE__ */ jsx20("p", { className: "text-xs font-semibold uppercase tracking-[0.24em] text-slate-500 dark:text-zinc-400", children: label }),
2841
- 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: [
2842
3020
  percent,
2843
3021
  "%"
2844
3022
  ] }) : null
2845
3023
  ] }) : null,
2846
- description ? /* @__PURE__ */ jsx20("p", { className: "text-[11px] text-slate-500 dark:text-zinc-400", children: description }) : null,
2847
- /* @__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: [
2848
3026
  /* @__PURE__ */ jsx20(
2849
3027
  "progress",
2850
3028
  {
2851
3029
  value: clamped,
2852
3030
  max,
2853
- className: "absolute inset-0 h-full w-full appearance-none",
3031
+ className: "rui-progress-meter__native",
2854
3032
  "aria-label": label
2855
3033
  }
2856
3034
  ),
2857
3035
  /* @__PURE__ */ jsx20(
2858
3036
  "div",
2859
3037
  {
2860
- 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",
2861
3039
  style: { width: `${percent}%` }
2862
3040
  }
2863
3041
  )
@@ -2880,27 +3058,27 @@ function Meter({
2880
3058
  (acc, t) => clamped >= t.value ? t.color : acc,
2881
3059
  (_b = (_a = thresholds[0]) == null ? void 0 : _a.color) != null ? _b : "linear-gradient(90deg, #22c55e, #0ea5e9)"
2882
3060
  ) : "linear-gradient(90deg, #22c55e, #0ea5e9)";
2883
- return /* @__PURE__ */ jsxs18("div", { className: twMerge19("space-y-1.5", className), children: [
2884
- label ? /* @__PURE__ */ jsxs18("div", { className: "flex items-center justify-between gap-3", children: [
2885
- /* @__PURE__ */ jsx20("p", { className: "text-xs font-semibold uppercase tracking-[0.24em] text-slate-500 dark:text-zinc-400", children: label }),
2886
- /* @__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 })
2887
3065
  ] }) : null,
2888
- description ? /* @__PURE__ */ jsx20("p", { className: "text-[11px] text-slate-500 dark:text-zinc-400", children: description }) : null,
2889
- /* @__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: [
2890
3068
  /* @__PURE__ */ jsx20(
2891
3069
  "meter",
2892
3070
  {
2893
3071
  value: clamped,
2894
3072
  min,
2895
3073
  max,
2896
- className: "absolute inset-0 h-full w-full appearance-none",
3074
+ className: "rui-progress-meter__native",
2897
3075
  "aria-label": label
2898
3076
  }
2899
3077
  ),
2900
3078
  /* @__PURE__ */ jsx20(
2901
3079
  "div",
2902
3080
  {
2903
- 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",
2904
3082
  style: { width: `${percent}%`, background: activeColor }
2905
3083
  }
2906
3084
  )
@@ -2910,11 +3088,13 @@ function Meter({
2910
3088
 
2911
3089
  // components/Radio/Radio.tsx
2912
3090
  import * as React18 from "react";
2913
- import { twMerge as twMerge20 } from "tailwind-merge";
3091
+ import clsx20 from "clsx";
3092
+ import "./Radio-K6CDDBCQ.css";
2914
3093
  import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
2915
3094
  var Radio = React18.forwardRef(function Radio2({
2916
3095
  label,
2917
3096
  description,
3097
+ color,
2918
3098
  extra,
2919
3099
  checked,
2920
3100
  defaultChecked = false,
@@ -2941,14 +3121,15 @@ var Radio = React18.forwardRef(function Radio2({
2941
3121
  "label",
2942
3122
  {
2943
3123
  htmlFor: radioId,
2944
- className: twMerge20(
2945
- "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",
2946
- 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",
2947
3128
  className
2948
3129
  ),
2949
3130
  children: [
2950
- /* @__PURE__ */ jsxs19("span", { className: "flex flex-1 items-center gap-3", children: [
2951
- /* @__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: [
2952
3133
  /* @__PURE__ */ jsx21(
2953
3134
  "input",
2954
3135
  {
@@ -2956,7 +3137,7 @@ var Radio = React18.forwardRef(function Radio2({
2956
3137
  ref: forwardedRef,
2957
3138
  id: radioId,
2958
3139
  type: "radio",
2959
- className: "peer sr-only",
3140
+ className: "rui-radio__input",
2960
3141
  checked: resolvedChecked,
2961
3142
  onChange: handleChange,
2962
3143
  "aria-describedby": description ? descriptionId : rest["aria-describedby"],
@@ -2966,29 +3147,17 @@ var Radio = React18.forwardRef(function Radio2({
2966
3147
  /* @__PURE__ */ jsx21(
2967
3148
  "span",
2968
3149
  {
2969
- className: twMerge20(
2970
- "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",
2971
- 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"
2972
- ),
2973
- "aria-hidden": "true",
2974
- children: /* @__PURE__ */ jsx21(
2975
- "span",
2976
- {
2977
- className: twMerge20(
2978
- "block h-2.5 w-2.5 rounded-full bg-slate-900 opacity-0 transition duration-200 dark:bg-zinc-100",
2979
- resolvedChecked && "opacity-100"
2980
- )
2981
- }
2982
- )
3150
+ className: "rui-radio__control",
3151
+ "aria-hidden": "true"
2983
3152
  }
2984
3153
  )
2985
3154
  ] }),
2986
- /* @__PURE__ */ jsxs19("span", { className: "flex flex-1 flex-col", children: [
2987
- /* @__PURE__ */ jsx21("span", { className: "text-sm font-semibold text-slate-900 dark:text-zinc-100", children: label }),
2988
- 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
2989
3158
  ] })
2990
3159
  ] }),
2991
- 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
2992
3161
  ]
2993
3162
  }
2994
3163
  );
@@ -2996,7 +3165,8 @@ var Radio = React18.forwardRef(function Radio2({
2996
3165
 
2997
3166
  // components/Slider/Slider.tsx
2998
3167
  import * as React19 from "react";
2999
- import { twMerge as twMerge21 } from "tailwind-merge";
3168
+ import clsx21 from "clsx";
3169
+ import "./Slider-KHMHINU4.css";
3000
3170
  import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
3001
3171
  function clampValue(value, min, max) {
3002
3172
  return Math.min(max, Math.max(min, value));
@@ -3097,7 +3267,7 @@ var Slider = React19.forwardRef(function Slider2({
3097
3267
  const trackOffset = trackMetrics.mainOffset;
3098
3268
  const trackCrossOffset = trackMetrics.crossOffset;
3099
3269
  const trackThickness = trackMetrics.thickness;
3100
- const overlap = Math.max(edgeOverlap, 0);
3270
+ const overlap = Math.max(renderThumb ? 0 : edgeOverlap, 0);
3101
3271
  const minCenter = Math.max(thumbRadius - overlap, 0);
3102
3272
  const maxCenter = Math.max(trackLength - thumbRadius + overlap, minCenter);
3103
3273
  const usableLength = Math.max(maxCenter - minCenter, 0);
@@ -3201,11 +3371,17 @@ var Slider = React19.forwardRef(function Slider2({
3201
3371
  },
3202
3372
  [isControlled, max, min, onChange, step]
3203
3373
  );
3204
- const handleInputChange = (event) => {
3205
- const next = Number(event.target.value);
3374
+ const applyInputValue = (value2) => {
3375
+ const next = Number(value2);
3206
3376
  if (Number.isNaN(next)) return;
3207
3377
  commitValue(next);
3208
3378
  };
3379
+ const handleInputChange = (event) => {
3380
+ applyInputValue(event.currentTarget.value);
3381
+ };
3382
+ const handleInputEvent = (event) => {
3383
+ applyInputValue(event.currentTarget.value);
3384
+ };
3209
3385
  const formattedValue = formatValue(resolvedValue);
3210
3386
  const setValueFromPointer = React19.useCallback(
3211
3387
  (clientX, clientY) => {
@@ -3264,11 +3440,10 @@ var Slider = React19.forwardRef(function Slider2({
3264
3440
  "div",
3265
3441
  {
3266
3442
  ref: trackRef,
3267
- className: twMerge21(
3268
- "relative overflow-hidden rounded-full shadow-inner ring-1 ring-slate-200/80 dark:ring-white/10",
3269
- "bg-[length:100%_100%]",
3270
- isVertical ? "mx-auto h-full w-3" : "h-3 w-full",
3271
- disabled && "opacity-60",
3443
+ className: clsx21(
3444
+ "rui-slider__track",
3445
+ isVertical && "rui-slider__track--vertical",
3446
+ disabled && "rui-slider__track--disabled",
3272
3447
  trackClassName
3273
3448
  ),
3274
3449
  style: { backgroundImage: trackGradient },
@@ -3277,10 +3452,10 @@ var Slider = React19.forwardRef(function Slider2({
3277
3452
  /* @__PURE__ */ jsx22(
3278
3453
  "div",
3279
3454
  {
3280
- className: twMerge21(
3281
- "absolute rounded-full shadow-[0_0_0_1px_rgba(59,130,246,0.18)]",
3282
- dragging ? "transition-none" : "transition-[width,height] duration-150 ease-out",
3283
- 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"
3284
3459
  ),
3285
3460
  style: {
3286
3461
  ...progressStyle,
@@ -3290,122 +3465,133 @@ var Slider = React19.forwardRef(function Slider2({
3290
3465
  }
3291
3466
  }
3292
3467
  ),
3293
- /* @__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" })
3294
3469
  ]
3295
3470
  }
3296
3471
  );
3297
3472
  const defaultThumb = /* @__PURE__ */ jsx22(
3298
3473
  "span",
3299
3474
  {
3300
- className: twMerge21(
3301
- "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",
3302
- focused && "scale-[1.04] ring-slate-300 dark:ring-slate-500",
3303
- 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",
3304
3479
  thumbClassName
3305
3480
  ),
3306
3481
  style: { ...thumbStyle, width: thumbDiameter, height: thumbDiameter },
3307
3482
  "aria-hidden": "true",
3308
- children: /* @__PURE__ */ jsxs20("span", { className: "relative block h-full w-full", children: [
3309
- /* @__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" }),
3310
- /* @__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" })
3311
3486
  ] })
3312
3487
  }
3313
3488
  );
3314
- return /* @__PURE__ */ jsxs20("div", { className: twMerge21("w-full space-y-2", isVertical && "max-w-[120px]", className), children: [
3315
- label ? /* @__PURE__ */ jsxs20("div", { className: "flex items-center justify-between gap-3", children: [
3316
- /* @__PURE__ */ jsx22(
3317
- "label",
3318
- {
3319
- htmlFor: inputId,
3320
- className: "text-[11px] font-semibold uppercase tracking-[0.25em] text-slate-500 dark:text-zinc-400",
3321
- children: label
3322
- }
3489
+ return /* @__PURE__ */ jsxs20(
3490
+ "div",
3491
+ {
3492
+ className: clsx21(
3493
+ "rui-root rui-slider",
3494
+ isVertical && "rui-slider--vertical",
3495
+ className
3323
3496
  ),
3324
- /* @__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 })
3325
- ] }) : null,
3326
- /* @__PURE__ */ jsxs20(
3327
- "div",
3328
- {
3329
- ref: trackContainerRef,
3330
- className: twMerge21(
3331
- "relative w-full pt-2 pb-3",
3332
- isVertical && "flex h-48 items-center justify-center px-4 pb-4 pt-4"
3333
- ),
3334
- "data-orientation": orientation,
3335
- children: [
3336
- renderTrack ? renderTrack({ ...renderProps, children: defaultTrack }) : defaultTrack,
3337
- renderThumb ? renderThumb(renderProps) : defaultThumb,
3497
+ children: [
3498
+ label ? /* @__PURE__ */ jsxs20("div", { className: "rui-slider__header", children: [
3338
3499
  /* @__PURE__ */ jsx22(
3339
- "input",
3500
+ "label",
3340
3501
  {
3341
- ...rest,
3342
- ref: mergedRef,
3343
- id: inputId,
3344
- type: "range",
3345
- min,
3346
- max,
3347
- step,
3348
- value: resolvedValue,
3349
- onChange: handleInputChange,
3350
- onInput: handleInputChange,
3351
- onFocus: () => setFocused(true),
3352
- onBlur: () => setFocused(false),
3353
- disabled,
3354
- "aria-valuetext": formattedValue,
3355
- "aria-orientation": orientation,
3356
- "data-orientation": orientation,
3357
- 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
3358
3505
  }
3359
3506
  ),
3360
- /* @__PURE__ */ jsx22(
3361
- "div",
3362
- {
3363
- ref: interactionRef,
3364
- "aria-hidden": "true",
3365
- onPointerDown: handlePointerDown,
3366
- className: twMerge21(
3367
- "absolute inset-0 cursor-pointer bg-transparent",
3368
- 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
+ }
3369
3554
  )
3370
- }
3371
- )
3372
- ]
3373
- }
3374
- )
3375
- ] });
3555
+ ]
3556
+ }
3557
+ )
3558
+ ]
3559
+ }
3560
+ );
3376
3561
  });
3377
3562
 
3378
3563
  // components/StackedList/StackedList.tsx
3379
- import { twMerge as twMerge22 } from "tailwind-merge";
3564
+ import clsx22 from "clsx";
3565
+ import "./StackedList-QF5242GF.css";
3380
3566
  import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
3381
3567
  function StackedList({ items, dense, className, ...rest }) {
3382
3568
  return /* @__PURE__ */ jsx23(
3383
3569
  "div",
3384
3570
  {
3385
3571
  ...rest,
3386
- className: twMerge22(
3387
- "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",
3388
3574
  className
3389
3575
  ),
3390
- 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(
3391
3577
  "li",
3392
3578
  {
3393
- 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"),
3394
3580
  children: [
3395
3581
  item.icon ? /* @__PURE__ */ jsx23(
3396
3582
  "div",
3397
3583
  {
3398
- 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",
3399
3585
  "aria-hidden": "true",
3400
3586
  children: item.icon
3401
3587
  }
3402
3588
  ) : null,
3403
- /* @__PURE__ */ jsxs21("div", { className: "flex-1", children: [
3404
- /* @__PURE__ */ jsx23("p", { className: "text-sm font-semibold text-slate-900 dark:text-zinc-100", children: item.title }),
3405
- 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
3406
3592
  ] }),
3407
- /* @__PURE__ */ jsxs21("div", { className: "flex flex-col items-end gap-1 text-right", children: [
3408
- 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,
3409
3595
  item.action
3410
3596
  ] })
3411
3597
  ]
@@ -3416,22 +3602,312 @@ function StackedList({ items, dense, className, ...rest }) {
3416
3602
  );
3417
3603
  }
3418
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
+
3419
3894
  // components/Table/Table.tsx
3420
- import * as React20 from "react";
3421
- import { twMerge as twMerge23 } from "tailwind-merge";
3422
- 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";
3423
3899
  var MIN_THUMB = 24;
3424
3900
  var TRACK_PADDING2 = 6;
3425
3901
  var TRACK_THICKNESS = 6;
3426
3902
  var TRACK_INSET = 8;
3427
3903
  var V_TRACK_INSET = 10;
3428
3904
  function useScrollbarMetrics(ref, axis, extraSpace) {
3429
- const [state, setState] = React20.useState({
3905
+ const [state, setState] = React21.useState({
3430
3906
  visible: false,
3431
3907
  size: MIN_THUMB,
3432
3908
  offset: 0
3433
3909
  });
3434
- React20.useLayoutEffect(() => {
3910
+ React21.useLayoutEffect(() => {
3435
3911
  const el = ref.current;
3436
3912
  if (!el) return;
3437
3913
  let raf = 0;
@@ -3467,7 +3943,7 @@ function useScrollbarMetrics(ref, axis, extraSpace) {
3467
3943
  return state;
3468
3944
  }
3469
3945
  function useThumbDrag(ref, axis, thumbState, extraSpace) {
3470
- const startDrag = React20.useCallback(
3946
+ const startDrag = React21.useCallback(
3471
3947
  (event, startScrollOverride) => {
3472
3948
  var _a, _b;
3473
3949
  const el = ref.current;
@@ -3498,7 +3974,7 @@ function useThumbDrag(ref, axis, thumbState, extraSpace) {
3498
3974
  },
3499
3975
  [axis, ref, thumbState.size, extraSpace]
3500
3976
  );
3501
- const onThumbPointerDown = React20.useCallback(
3977
+ const onThumbPointerDown = React21.useCallback(
3502
3978
  (event) => {
3503
3979
  event.stopPropagation();
3504
3980
  startDrag(event);
@@ -3515,15 +3991,15 @@ function Table({
3515
3991
  scrollAreaStyle,
3516
3992
  style
3517
3993
  }) {
3518
- const scrollRef = React20.useRef(null);
3519
- const [padRight, setPadRight] = React20.useState(0);
3520
- 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);
3521
3997
  const vThumb = useScrollbarMetrics(scrollRef, "vertical", padBottom);
3522
3998
  const hThumb = useScrollbarMetrics(scrollRef, "horizontal", padRight);
3523
- React20.useEffect(() => {
3999
+ React21.useEffect(() => {
3524
4000
  setPadRight(vThumb.visible ? TRACK_PADDING2 + 10 : 0);
3525
4001
  }, [vThumb.visible]);
3526
- React20.useEffect(() => {
4002
+ React21.useEffect(() => {
3527
4003
  setPadBottom(hThumb.visible ? TRACK_PADDING2 + 10 : 0);
3528
4004
  }, [hThumb.visible]);
3529
4005
  const { onThumbPointerDown: handleVThumbDown, startDrag: startVDrag } = useThumbDrag(
@@ -3538,7 +4014,7 @@ function Table({
3538
4014
  hThumb,
3539
4015
  padRight
3540
4016
  );
3541
- const handleTrackPointerDown = React20.useCallback(
4017
+ const handleTrackPointerDown = React21.useCallback(
3542
4018
  (axis, thumb, startDrag, event) => {
3543
4019
  const el = scrollRef.current;
3544
4020
  if (!el) return;
@@ -3563,55 +4039,55 @@ function Table({
3563
4039
  const vOffset = Math.max(TRACK_PADDING2, (vSlot - TRACK_THICKNESS) / 2);
3564
4040
  const hOffset = Math.max(TRACK_PADDING2, (hSlot - TRACK_THICKNESS) / 2);
3565
4041
  const hBottom = Math.max(TRACK_PADDING2 / 2, (hSlot - TRACK_THICKNESS) / 2);
3566
- return /* @__PURE__ */ jsx24(
4042
+ return /* @__PURE__ */ jsx25(
3567
4043
  "div",
3568
4044
  {
3569
- className: twMerge23(
3570
- "overflow-hidden rounded-3xl border border-slate-200 shadow-sm dark:border-zinc-800",
4045
+ className: clsx23(
4046
+ "rui-table",
3571
4047
  className
3572
4048
  ),
3573
4049
  style,
3574
- children: /* @__PURE__ */ jsxs22(
4050
+ children: /* @__PURE__ */ jsxs23(
3575
4051
  "div",
3576
4052
  {
3577
- className: "relative overflow-hidden bg-white/90 dark:bg-zinc-950/80",
4053
+ className: "rui-table__container",
3578
4054
  style: { paddingRight: padRight, paddingBottom: padBottom },
3579
4055
  children: [
3580
- /* @__PURE__ */ jsx24(
4056
+ /* @__PURE__ */ jsx25(
3581
4057
  "div",
3582
4058
  {
3583
4059
  ref: scrollRef,
3584
- className: "table-scrollbar overflow-auto",
4060
+ className: "rui-table__scroll",
3585
4061
  style: { ...scrollAreaStyle },
3586
- children: /* @__PURE__ */ jsxs22("table", { className: "w-full border-collapse text-sm text-slate-700 dark:text-zinc-200", children: [
3587
- 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,
3588
- /* @__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(
3589
4065
  "th",
3590
4066
  {
3591
4067
  scope: "col",
3592
- className: twMerge23(
3593
- "px-4 py-3 text-left font-semibold",
3594
- col.align === "right" && "text-right",
3595
- 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"
3596
4072
  ),
3597
4073
  children: col.header
3598
4074
  },
3599
4075
  String(col.key)
3600
4076
  )) }) }),
3601
- /* @__PURE__ */ jsx24("tbody", { children: data.map((row, rowIndex) => /* @__PURE__ */ jsx24(
4077
+ /* @__PURE__ */ jsx25("tbody", { children: data.map((row, rowIndex) => /* @__PURE__ */ jsx25(
3602
4078
  "tr",
3603
4079
  {
3604
- className: twMerge23(
3605
- "border-t border-slate-100 transition dark:border-zinc-800",
3606
- 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"
3607
4083
  ),
3608
- children: columns.map((col) => /* @__PURE__ */ jsx24(
4084
+ children: columns.map((col) => /* @__PURE__ */ jsx25(
3609
4085
  "td",
3610
4086
  {
3611
- className: twMerge23(
3612
- "px-4 py-3 align-middle",
3613
- col.align === "right" && "text-right",
3614
- 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"
3615
4091
  ),
3616
4092
  children: col.render ? col.render(row[col.key], row) : row[col.key]
3617
4093
  },
@@ -3623,10 +4099,10 @@ function Table({
3623
4099
  ] })
3624
4100
  }
3625
4101
  ),
3626
- vThumb.visible ? /* @__PURE__ */ jsx24(
4102
+ vThumb.visible ? /* @__PURE__ */ jsx25(
3627
4103
  "div",
3628
4104
  {
3629
- 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",
3630
4106
  style: {
3631
4107
  right: vOffset,
3632
4108
  top: TRACK_PADDING2 + V_TRACK_INSET,
@@ -3634,20 +4110,22 @@ function Table({
3634
4110
  width: TRACK_THICKNESS
3635
4111
  },
3636
4112
  onPointerDown: (e) => handleTrackPointerDown("vertical", vThumb, startVDrag, e),
3637
- 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(
3638
4114
  "div",
3639
4115
  {
3640
- 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
+ ),
3641
4119
  style: { height: `${vThumb.size}px`, top: `${vThumb.offset}px` },
3642
4120
  onPointerDown: handleVThumbDown
3643
4121
  }
3644
4122
  ) })
3645
4123
  }
3646
4124
  ) : null,
3647
- hThumb.visible ? /* @__PURE__ */ jsx24(
4125
+ hThumb.visible ? /* @__PURE__ */ jsx25(
3648
4126
  "div",
3649
4127
  {
3650
- 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",
3651
4129
  style: {
3652
4130
  left: hOffset + TRACK_INSET,
3653
4131
  right: hOffset + TRACK_INSET,
@@ -3655,10 +4133,12 @@ function Table({
3655
4133
  height: TRACK_THICKNESS
3656
4134
  },
3657
4135
  onPointerDown: (e) => handleTrackPointerDown("horizontal", hThumb, startHDrag, e),
3658
- 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(
3659
4137
  "div",
3660
4138
  {
3661
- 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
+ ),
3662
4142
  style: { width: `${hThumb.size}px`, left: `${hThumb.offset}px` },
3663
4143
  onPointerDown: handleHThumbDown
3664
4144
  }
@@ -3673,16 +4153,17 @@ function Table({
3673
4153
  }
3674
4154
 
3675
4155
  // components/Textarea/Textarea.tsx
3676
- import * as React21 from "react";
3677
- import { twMerge as twMerge24 } from "tailwind-merge";
3678
- 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";
3679
4160
  var MIN_THUMB2 = 24;
3680
4161
  var TRACK_THICKNESS2 = 6;
3681
4162
  var TRACK_TOP = 8;
3682
4163
  var TRACK_BOTTOM = 22;
3683
4164
  var TRACK_REDUCTION = 20;
3684
4165
  var TRACK_REDUCTION_HALF = TRACK_REDUCTION / 2;
3685
- var Textarea = React21.forwardRef(function Textarea2({
4166
+ var Textarea = React22.forwardRef(function Textarea2({
3686
4167
  label,
3687
4168
  description,
3688
4169
  error,
@@ -3695,24 +4176,24 @@ var Textarea = React21.forwardRef(function Textarea2({
3695
4176
  ...rest
3696
4177
  }, ref) {
3697
4178
  var _a, _b;
3698
- const generatedId = React21.useId();
4179
+ const generatedId = React22.useId();
3699
4180
  const textareaId = id != null ? id : generatedId;
3700
- const descriptionId = React21.useId();
3701
- const errorId = React21.useId();
3702
- const textareaRef = React21.useRef(null);
3703
- const shellRef = React21.useRef(null);
3704
- const resizeListenersRef = React21.useRef({});
3705
- 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({
3706
4187
  visible: false,
3707
4188
  size: MIN_THUMB2,
3708
4189
  offset: 0
3709
4190
  });
3710
4191
  const hintIds = [description ? descriptionId : null, error ? errorId : null].filter(Boolean);
3711
4192
  const resolvedAriaDescribedBy = hintIds.length ? hintIds.join(" ") : void 0;
3712
- const [value, setValue] = React21.useState((_b = (_a = rest.defaultValue) == null ? void 0 : _a.toString()) != null ? _b : "");
3713
- const [height, setHeight] = React21.useState(void 0);
3714
- const [width, setWidth] = React21.useState(void 0);
3715
- 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(
3716
4197
  (node) => {
3717
4198
  textareaRef.current = node;
3718
4199
  if (typeof ref === "function") {
@@ -3723,17 +4204,17 @@ var Textarea = React21.forwardRef(function Textarea2({
3723
4204
  },
3724
4205
  [ref]
3725
4206
  );
3726
- React21.useEffect(() => {
4207
+ React22.useEffect(() => {
3727
4208
  if (typeof rest.value === "string") {
3728
4209
  setValue(rest.value);
3729
4210
  }
3730
4211
  }, [rest.value]);
3731
- React21.useLayoutEffect(() => {
4212
+ React22.useLayoutEffect(() => {
3732
4213
  if (textareaRef.current && height === void 0) {
3733
4214
  setHeight(textareaRef.current.offsetHeight);
3734
4215
  }
3735
4216
  }, [height]);
3736
- React21.useLayoutEffect(() => {
4217
+ React22.useLayoutEffect(() => {
3737
4218
  const el = textareaRef.current;
3738
4219
  if (!el) return;
3739
4220
  let raf = 0;
@@ -3768,26 +4249,24 @@ var Textarea = React21.forwardRef(function Textarea2({
3768
4249
  cancelAnimationFrame(raf);
3769
4250
  };
3770
4251
  }, [height]);
3771
- React21.useLayoutEffect(() => {
3772
- if (!shellRef.current || width !== void 0) return;
3773
- setWidth(shellRef.current.offsetWidth);
3774
- }, [width]);
3775
- React21.useEffect(() => {
4252
+ React22.useEffect(() => {
3776
4253
  return () => {
3777
4254
  if (resizeListenersRef.current.move) {
3778
- window.removeEventListener("mousemove", resizeListenersRef.current.move);
4255
+ window.removeEventListener("pointermove", resizeListenersRef.current.move);
3779
4256
  }
3780
4257
  if (resizeListenersRef.current.up) {
3781
- window.removeEventListener("mouseup", resizeListenersRef.current.up);
4258
+ window.removeEventListener("pointerup", resizeListenersRef.current.up);
4259
+ window.removeEventListener("pointercancel", resizeListenersRef.current.up);
3782
4260
  }
3783
4261
  };
3784
4262
  }, []);
3785
4263
  const handleResizeStart = (event) => {
3786
- var _a2, _b2, _c, _d, _e;
4264
+ var _a2, _b2, _c, _d, _e, _f, _g;
4265
+ if (event.pointerType === "mouse" && event.button !== 0) return;
3787
4266
  event.preventDefault();
3788
4267
  if (!textareaRef.current) return;
3789
4268
  const allowY = resizeDirection === "vertical" || resizeDirection === "both";
3790
- const allowX = resizeDirection === "horizontal" || resizeDirection === "both";
4269
+ const allowX2 = resizeDirection === "horizontal" || resizeDirection === "both";
3791
4270
  const startY = event.clientY;
3792
4271
  const startX = event.clientX;
3793
4272
  const startHeight = textareaRef.current.offsetHeight;
@@ -3800,22 +4279,25 @@ var Textarea = React21.forwardRef(function Textarea2({
3800
4279
  const nextHeight = Math.max(minHeight, startHeight + (moveEvent.clientY - startY));
3801
4280
  setHeight(nextHeight);
3802
4281
  }
3803
- if (allowX) {
4282
+ if (allowX2) {
3804
4283
  const proposed = startWidth + (moveEvent.clientX - startX);
3805
4284
  const nextWidth = Math.min(parentWidth, Math.max(minWidth, proposed));
3806
4285
  setWidth(nextWidth);
3807
4286
  }
3808
4287
  };
3809
4288
  const onUp = () => {
3810
- window.removeEventListener("mousemove", onMove);
3811
- window.removeEventListener("mouseup", onUp);
4289
+ window.removeEventListener("pointermove", onMove);
4290
+ window.removeEventListener("pointerup", onUp);
4291
+ window.removeEventListener("pointercancel", onUp);
3812
4292
  resizeListenersRef.current = {};
3813
4293
  };
3814
4294
  resizeListenersRef.current = { move: onMove, up: onUp };
3815
- window.addEventListener("mousemove", onMove);
3816
- 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);
3817
4299
  };
3818
- const handleThumbDrag = React21.useCallback(
4300
+ const handleThumbDrag = React22.useCallback(
3819
4301
  (event, startScrollOverride) => {
3820
4302
  var _a2, _b2;
3821
4303
  const el = textareaRef.current;
@@ -3846,13 +4328,15 @@ var Textarea = React21.forwardRef(function Textarea2({
3846
4328
  },
3847
4329
  [thumb.size]
3848
4330
  );
3849
- const shellClasses = twMerge24(
3850
- "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",
3851
- disabled && "opacity-60",
3852
- 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"
3853
4336
  );
3854
- const textareaClasses = twMerge24(
3855
- "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}`,
3856
4340
  className
3857
4341
  );
3858
4342
  const count = value.length;
@@ -3860,22 +4344,21 @@ var Textarea = React21.forwardRef(function Textarea2({
3860
4344
  const { style, ...restProps } = rest;
3861
4345
  const textareaStyle = {
3862
4346
  ...style,
3863
- ...height !== void 0 ? { height } : null,
3864
- ...width !== void 0 ? { width } : null,
3865
- maxWidth: "100%"
4347
+ ...height !== void 0 ? { height } : null
3866
4348
  };
3867
- const shellStyle = width !== void 0 ? { width, maxWidth: "100%" } : { maxWidth: "100%" };
3868
- return /* @__PURE__ */ jsxs23("div", { className: "space-y-1.5", children: [
3869
- 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(
3870
4353
  "label",
3871
4354
  {
3872
4355
  htmlFor: textareaId,
3873
- className: "text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-zinc-400",
4356
+ className: "rui-textarea__label rui-text-wrap",
3874
4357
  children: label
3875
4358
  }
3876
4359
  ) : null,
3877
- /* @__PURE__ */ jsxs23("div", { className: shellClasses, ref: shellRef, style: shellStyle, children: [
3878
- /* @__PURE__ */ jsx25(
4360
+ /* @__PURE__ */ jsxs24("div", { className: shellClasses, ref: shellRef, style: shellStyle, children: [
4361
+ /* @__PURE__ */ jsx26(
3879
4362
  "textarea",
3880
4363
  {
3881
4364
  ...restProps,
@@ -3894,10 +4377,10 @@ var Textarea = React21.forwardRef(function Textarea2({
3894
4377
  }
3895
4378
  }
3896
4379
  ),
3897
- thumb.visible ? /* @__PURE__ */ jsx25(
4380
+ thumb.visible ? /* @__PURE__ */ jsx26(
3898
4381
  "div",
3899
4382
  {
3900
- 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",
3901
4384
  style: {
3902
4385
  right: 4,
3903
4386
  top: TRACK_TOP + TRACK_REDUCTION_HALF,
@@ -3920,10 +4403,10 @@ var Textarea = React21.forwardRef(function Textarea2({
3920
4403
  el.scrollTop = target;
3921
4404
  handleThumbDrag(event, target);
3922
4405
  },
3923
- 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(
3924
4407
  "div",
3925
4408
  {
3926
- 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",
3927
4410
  style: { height: `${thumb.size}px`, top: `${thumb.offset}px` },
3928
4411
  onPointerDown: (event) => {
3929
4412
  event.stopPropagation();
@@ -3933,57 +4416,442 @@ var Textarea = React21.forwardRef(function Textarea2({
3933
4416
  ) })
3934
4417
  }
3935
4418
  ) : null,
3936
- 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: [
3937
- 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: [
3938
4421
  count,
3939
4422
  "/",
3940
4423
  limit
3941
4424
  ] }) : null,
3942
- /* @__PURE__ */ jsx25(
4425
+ /* @__PURE__ */ jsx26(
3943
4426
  "button",
3944
4427
  {
3945
4428
  type: "button",
3946
4429
  "aria-label": "Resize textarea",
3947
- onMouseDown: handleResizeStart,
3948
- 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",
3949
4432
  style: {
3950
4433
  border: "none",
3951
4434
  boxShadow: "none",
3952
4435
  appearance: "none",
3953
4436
  background: "transparent"
3954
4437
  },
3955
- children: /* @__PURE__ */ jsx25(
4438
+ children: /* @__PURE__ */ jsx26(
3956
4439
  "svg",
3957
4440
  {
3958
- viewBox: "0 0 12 12",
4441
+ viewBox: "0 0 16 16",
3959
4442
  "aria-hidden": "true",
3960
- className: "h-3 w-3 text-slate-400 dark:text-zinc-400",
3961
- children: /* @__PURE__ */ jsx25(
3962
- "path",
3963
- {
3964
- d: "M2 10.5 10.5 2M4.5 10.5 10.5 4.5M7 10.5 10.5 7",
3965
- stroke: "currentColor",
3966
- strokeWidth: "1.1"
3967
- }
3968
- )
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" })
3969
4449
  }
3970
4450
  )
3971
4451
  }
3972
4452
  )
3973
4453
  ] }) : null
3974
4454
  ] }),
3975
- description ? /* @__PURE__ */ jsx25("p", { id: descriptionId, className: "text-xs text-slate-500 dark:text-zinc-400", children: description }) : null,
3976
- 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
3977
4457
  ] });
3978
4458
  });
3979
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
+
3980
4847
  // components/Toggle/Toggle.tsx
3981
- import * as React22 from "react";
3982
- import { twMerge as twMerge25 } from "tailwind-merge";
3983
- import { jsx as jsx26 } from "react/jsx-runtime";
3984
- 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) {
3985
4853
  const isControlled = typeof checked === "boolean";
3986
- const [internalChecked, setInternalChecked] = React22.useState(defaultChecked);
4854
+ const [internalChecked, setInternalChecked] = React24.useState(defaultChecked);
3987
4855
  const resolvedChecked = isControlled ? !!checked : internalChecked;
3988
4856
  const handleClick = (event) => {
3989
4857
  if (disabled) {
@@ -3997,18 +4865,18 @@ var Toggle = React22.forwardRef(function Toggle2({ checked, defaultChecked = fal
3997
4865
  onChange == null ? void 0 : onChange(next);
3998
4866
  onClick == null ? void 0 : onClick(event);
3999
4867
  };
4000
- const buttonClasses = twMerge25(
4001
- "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",
4002
- "dark:border-zinc-700/70 dark:bg-zinc-900/70 dark:focus-visible:ring-offset-slate-950",
4003
- 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",
4004
- 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",
4005
4872
  className
4006
4873
  );
4007
- const thumbClasses = twMerge25(
4008
- "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",
4009
- 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"
4010
4878
  );
4011
- return /* @__PURE__ */ jsx26(
4879
+ return /* @__PURE__ */ jsx28(
4012
4880
  "button",
4013
4881
  {
4014
4882
  ...rest,
@@ -4020,7 +4888,7 @@ var Toggle = React22.forwardRef(function Toggle2({ checked, defaultChecked = fal
4020
4888
  "data-state": resolvedChecked ? "on" : "off",
4021
4889
  className: buttonClasses,
4022
4890
  onClick: handleClick,
4023
- children: /* @__PURE__ */ jsx26("span", { "aria-hidden": "true", className: thumbClasses })
4891
+ children: /* @__PURE__ */ jsx28("span", { "aria-hidden": "true", className: thumbClasses })
4024
4892
  }
4025
4893
  );
4026
4894
  });
@@ -4045,9 +4913,11 @@ export {
4045
4913
  Popover,
4046
4914
  Progress,
4047
4915
  Radio,
4916
+ ResizableContainer,
4048
4917
  Select,
4049
4918
  Slider,
4050
4919
  StackedList,
4920
+ TabGroup,
4051
4921
  Table,
4052
4922
  Textarea,
4053
4923
  Toggle_default as Toggle