@juv/codego-react-ui 1.0.7 → 1.0.8
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.cjs +1624 -799
- package/dist/index.d.cts +208 -28
- package/dist/index.d.ts +208 -28
- package/dist/index.global.js +1684 -863
- package/dist/index.js +1640 -824
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -54,14 +54,20 @@ __export(index_exports, {
|
|
|
54
54
|
DateRangePicker: () => DateRangePicker,
|
|
55
55
|
Drawer: () => Drawer,
|
|
56
56
|
Dropdown: () => Dropdown,
|
|
57
|
+
DropdownItem: () => DropdownItem,
|
|
58
|
+
DropdownLabel: () => DropdownLabel,
|
|
59
|
+
DropdownSeparator: () => DropdownSeparator,
|
|
57
60
|
FileUpload: () => FileUpload,
|
|
61
|
+
FlexItem: () => FlexItem,
|
|
58
62
|
FlexLayout: () => FlexLayout,
|
|
63
|
+
GridItem: () => GridItem,
|
|
59
64
|
GridLayout: () => GridLayout,
|
|
60
65
|
GroupNavigation: () => GroupNavigation,
|
|
61
66
|
Input: () => Input,
|
|
62
67
|
KanbanBoard: () => KanbanBoard,
|
|
63
68
|
Label: () => Label,
|
|
64
69
|
LeftSidebar: () => LeftSidebar,
|
|
70
|
+
MetricRow: () => MetricRow,
|
|
65
71
|
Modal: () => Modal,
|
|
66
72
|
ModalConfirmation: () => ModalConfirmation,
|
|
67
73
|
ModalUnchange: () => ModalUnchange,
|
|
@@ -76,6 +82,7 @@ __export(index_exports, {
|
|
|
76
82
|
PanelSidebarItem: () => PanelSidebarItem,
|
|
77
83
|
Popover: () => Popover,
|
|
78
84
|
Progress: () => Progress,
|
|
85
|
+
PropsTable: () => PropsTable,
|
|
79
86
|
RadioGroup: () => RadioGroup,
|
|
80
87
|
RangeSlider: () => RangeSlider,
|
|
81
88
|
Repeater: () => Repeater,
|
|
@@ -85,6 +92,7 @@ __export(index_exports, {
|
|
|
85
92
|
ScrollArea: () => ScrollArea,
|
|
86
93
|
SectionBlock: () => SectionBlock,
|
|
87
94
|
Select: () => Select,
|
|
95
|
+
Settings: () => Settings,
|
|
88
96
|
Skeleton: () => Skeleton,
|
|
89
97
|
Slider: () => Slider,
|
|
90
98
|
StatCard: () => StatCard,
|
|
@@ -102,6 +110,7 @@ __export(index_exports, {
|
|
|
102
110
|
Topbar: () => Topbar,
|
|
103
111
|
TreeView: () => TreeView,
|
|
104
112
|
Widget: () => Widget,
|
|
113
|
+
Wizard: () => Wizard,
|
|
105
114
|
useToast: () => useToast
|
|
106
115
|
});
|
|
107
116
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -1759,6 +1768,32 @@ function ComposableWidget({
|
|
|
1759
1768
|
] })
|
|
1760
1769
|
] });
|
|
1761
1770
|
}
|
|
1771
|
+
function MetricRow({ items, divided = true, className }) {
|
|
1772
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Card, { className: cn("overflow-hidden", className), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CardContent, { className: "p-0", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: cn("grid", `grid-cols-${Math.min(items.length, 4)}`), children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1773
|
+
"div",
|
|
1774
|
+
{
|
|
1775
|
+
className: cn(
|
|
1776
|
+
"flex flex-col gap-1 px-5 py-4",
|
|
1777
|
+
divided && i > 0 && "border-l border-border"
|
|
1778
|
+
),
|
|
1779
|
+
children: [
|
|
1780
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-xs font-medium text-muted-foreground", children: item.label }),
|
|
1781
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: cn("text-xl font-bold tabular-nums", item.color && semanticText[item.color]), children: item.value }),
|
|
1782
|
+
item.trendValue && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: cn(
|
|
1783
|
+
"text-xs font-medium",
|
|
1784
|
+
item.trend === "up" && "text-success",
|
|
1785
|
+
item.trend === "down" && "text-danger",
|
|
1786
|
+
item.trend === "neutral" && "text-muted-foreground"
|
|
1787
|
+
), children: [
|
|
1788
|
+
item.trend === "up" && "\u2191 ",
|
|
1789
|
+
item.trend === "down" && "\u2193 ",
|
|
1790
|
+
item.trendValue
|
|
1791
|
+
] })
|
|
1792
|
+
]
|
|
1793
|
+
},
|
|
1794
|
+
i
|
|
1795
|
+
)) }) }) });
|
|
1796
|
+
}
|
|
1762
1797
|
|
|
1763
1798
|
// src/components/ui/data-grid.tsx
|
|
1764
1799
|
var React12 = __toESM(require("react"), 1);
|
|
@@ -2763,6 +2798,42 @@ function Dropdown({
|
|
|
2763
2798
|
)
|
|
2764
2799
|
] });
|
|
2765
2800
|
}
|
|
2801
|
+
function DropdownItem({
|
|
2802
|
+
children,
|
|
2803
|
+
onClick,
|
|
2804
|
+
icon,
|
|
2805
|
+
disabled = false,
|
|
2806
|
+
variant = "default",
|
|
2807
|
+
className
|
|
2808
|
+
}) {
|
|
2809
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
2810
|
+
"button",
|
|
2811
|
+
{
|
|
2812
|
+
onClick,
|
|
2813
|
+
disabled,
|
|
2814
|
+
className: cn(
|
|
2815
|
+
"flex w-full items-center gap-2.5 px-3.5 py-2 text-left text-sm rounded-lg mx-1 transition-colors duration-100",
|
|
2816
|
+
"w-[calc(100%-0.5rem)]",
|
|
2817
|
+
variant === "danger" ? "text-red-400 hover:bg-red-500/15 hover:text-red-300" : "hover:bg-white/8 hover:text-accent-foreground",
|
|
2818
|
+
disabled && "opacity-40 cursor-not-allowed pointer-events-none",
|
|
2819
|
+
className
|
|
2820
|
+
),
|
|
2821
|
+
children: [
|
|
2822
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "shrink-0 opacity-70", children: icon }),
|
|
2823
|
+
children
|
|
2824
|
+
]
|
|
2825
|
+
}
|
|
2826
|
+
);
|
|
2827
|
+
}
|
|
2828
|
+
function DropdownSeparator({ className }) {
|
|
2829
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: cn("my-1.5 h-px bg-white/8", className) });
|
|
2830
|
+
}
|
|
2831
|
+
function DropdownLabel({
|
|
2832
|
+
children,
|
|
2833
|
+
className
|
|
2834
|
+
}) {
|
|
2835
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: cn("px-3.5 py-1.5 text-xs font-semibold uppercase tracking-wider text-muted-foreground/60", className), children });
|
|
2836
|
+
}
|
|
2766
2837
|
|
|
2767
2838
|
// src/components/ui/file-upload.tsx
|
|
2768
2839
|
var React17 = __toESM(require("react"), 1);
|
|
@@ -3202,6 +3273,13 @@ var justifyMap = {
|
|
|
3202
3273
|
around: "justify-around",
|
|
3203
3274
|
evenly: "justify-evenly"
|
|
3204
3275
|
};
|
|
3276
|
+
var selfMap = {
|
|
3277
|
+
start: "self-start",
|
|
3278
|
+
center: "self-center",
|
|
3279
|
+
end: "self-end",
|
|
3280
|
+
stretch: "self-stretch",
|
|
3281
|
+
baseline: "self-baseline"
|
|
3282
|
+
};
|
|
3205
3283
|
function FlexLayout({
|
|
3206
3284
|
direction = "row",
|
|
3207
3285
|
wrap = "nowrap",
|
|
@@ -3222,6 +3300,29 @@ function FlexLayout({
|
|
|
3222
3300
|
className
|
|
3223
3301
|
), children });
|
|
3224
3302
|
}
|
|
3303
|
+
function FlexItem({
|
|
3304
|
+
grow,
|
|
3305
|
+
shrink,
|
|
3306
|
+
basis,
|
|
3307
|
+
order,
|
|
3308
|
+
alignSelf,
|
|
3309
|
+
children,
|
|
3310
|
+
className
|
|
3311
|
+
}) {
|
|
3312
|
+
const style = {};
|
|
3313
|
+
if (grow !== void 0) style.flexGrow = grow === true ? 1 : grow === false ? 0 : grow;
|
|
3314
|
+
if (shrink !== void 0) style.flexShrink = shrink === true ? 1 : shrink === false ? 0 : shrink;
|
|
3315
|
+
if (basis) style.flexBasis = basis;
|
|
3316
|
+
if (order !== void 0) style.order = order;
|
|
3317
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3318
|
+
"div",
|
|
3319
|
+
{
|
|
3320
|
+
className: cn(alignSelf && selfMap[alignSelf], className),
|
|
3321
|
+
style,
|
|
3322
|
+
children
|
|
3323
|
+
}
|
|
3324
|
+
);
|
|
3325
|
+
}
|
|
3225
3326
|
|
|
3226
3327
|
// src/components/ui/grid-layout.tsx
|
|
3227
3328
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
@@ -3297,6 +3398,17 @@ var justifyMap2 = {
|
|
|
3297
3398
|
end: "justify-items-end",
|
|
3298
3399
|
stretch: "justify-items-stretch"
|
|
3299
3400
|
};
|
|
3401
|
+
var spanMap = {
|
|
3402
|
+
1: "col-span-1",
|
|
3403
|
+
2: "col-span-2",
|
|
3404
|
+
3: "col-span-3",
|
|
3405
|
+
4: "col-span-4",
|
|
3406
|
+
5: "col-span-5",
|
|
3407
|
+
6: "col-span-6",
|
|
3408
|
+
12: "col-span-12",
|
|
3409
|
+
full: "col-span-full"
|
|
3410
|
+
};
|
|
3411
|
+
var rowSpanMap = { 1: "row-span-1", 2: "row-span-2", 3: "row-span-3" };
|
|
3300
3412
|
function GridLayout({
|
|
3301
3413
|
cols = 3,
|
|
3302
3414
|
smCols,
|
|
@@ -3324,6 +3436,13 @@ function GridLayout({
|
|
|
3324
3436
|
className
|
|
3325
3437
|
), children });
|
|
3326
3438
|
}
|
|
3439
|
+
function GridItem({ span, rowSpan, children, className }) {
|
|
3440
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: cn(
|
|
3441
|
+
span && spanMap[String(span)],
|
|
3442
|
+
rowSpan && rowSpanMap[rowSpan],
|
|
3443
|
+
className
|
|
3444
|
+
), children });
|
|
3445
|
+
}
|
|
3327
3446
|
|
|
3328
3447
|
// src/components/ui/input.tsx
|
|
3329
3448
|
var React18 = __toESM(require("react"), 1);
|
|
@@ -5044,111 +5163,398 @@ function OtpInput({
|
|
|
5044
5163
|
] }, i)) });
|
|
5045
5164
|
}
|
|
5046
5165
|
|
|
5047
|
-
// src/components/ui/
|
|
5166
|
+
// src/components/ui/panel.tsx
|
|
5167
|
+
var React30 = __toESM(require("react"), 1);
|
|
5168
|
+
var import_lucide_react20 = require("lucide-react");
|
|
5169
|
+
|
|
5170
|
+
// src/components/ui/tooltip.tsx
|
|
5048
5171
|
var React28 = __toESM(require("react"), 1);
|
|
5172
|
+
var ReactDOM = __toESM(require("react-dom"), 1);
|
|
5049
5173
|
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
5050
|
-
|
|
5051
|
-
"top": "bottom-full left-1/2 -translate-x-1/2 mb-2",
|
|
5052
|
-
"bottom": "top-full left-1/2 -translate-x-1/2 mt-2",
|
|
5053
|
-
"left": "right-full top-1/2 -translate-y-1/2 mr-2",
|
|
5054
|
-
"right": "left-full top-1/2 -translate-y-1/2 ml-2",
|
|
5055
|
-
"top-start": "bottom-full left-0 mb-2",
|
|
5056
|
-
"top-end": "bottom-full right-0 mb-2",
|
|
5057
|
-
"bottom-start": "top-full left-0 mt-2",
|
|
5058
|
-
"bottom-end": "top-full right-0 mt-2"
|
|
5059
|
-
};
|
|
5060
|
-
function Popover({
|
|
5061
|
-
trigger,
|
|
5174
|
+
function Tooltip({
|
|
5062
5175
|
content,
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
className
|
|
5176
|
+
children,
|
|
5177
|
+
side = "right",
|
|
5178
|
+
className,
|
|
5179
|
+
enabled = true
|
|
5068
5180
|
}) {
|
|
5069
|
-
const [
|
|
5181
|
+
const [visible, setVisible] = React28.useState(false);
|
|
5182
|
+
const [coords, setCoords] = React28.useState({ top: 0, left: 0 });
|
|
5070
5183
|
const ref = React28.useRef(null);
|
|
5071
|
-
|
|
5072
|
-
function
|
|
5073
|
-
|
|
5074
|
-
|
|
5184
|
+
if (!enabled) return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_jsx_runtime33.Fragment, { children });
|
|
5185
|
+
function calcCoords() {
|
|
5186
|
+
const r = ref.current?.getBoundingClientRect();
|
|
5187
|
+
if (!r) return;
|
|
5188
|
+
const GAP = 8;
|
|
5189
|
+
switch (side) {
|
|
5190
|
+
case "right":
|
|
5191
|
+
setCoords({ top: r.top + r.height / 2, left: r.right + GAP });
|
|
5192
|
+
break;
|
|
5193
|
+
case "left":
|
|
5194
|
+
setCoords({ top: r.top + r.height / 2, left: r.left - GAP });
|
|
5195
|
+
break;
|
|
5196
|
+
case "top":
|
|
5197
|
+
setCoords({ top: r.top - GAP, left: r.left + r.width / 2 });
|
|
5198
|
+
break;
|
|
5199
|
+
case "bottom":
|
|
5200
|
+
setCoords({ top: r.bottom + GAP, left: r.left + r.width / 2 });
|
|
5201
|
+
break;
|
|
5202
|
+
}
|
|
5075
5203
|
}
|
|
5076
|
-
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5204
|
+
const transformClass = {
|
|
5205
|
+
right: "-translate-y-1/2",
|
|
5206
|
+
left: "-translate-y-1/2 -translate-x-full",
|
|
5207
|
+
top: "-translate-x-1/2 -translate-y-full",
|
|
5208
|
+
bottom: "-translate-x-1/2"
|
|
5209
|
+
}[side];
|
|
5210
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
5211
|
+
"div",
|
|
5212
|
+
{
|
|
5213
|
+
ref,
|
|
5214
|
+
className: "relative inline-flex",
|
|
5215
|
+
onMouseEnter: () => {
|
|
5216
|
+
calcCoords();
|
|
5217
|
+
setVisible(true);
|
|
5218
|
+
},
|
|
5219
|
+
onMouseLeave: () => setVisible(false),
|
|
5220
|
+
onFocus: () => {
|
|
5221
|
+
calcCoords();
|
|
5222
|
+
setVisible(true);
|
|
5223
|
+
},
|
|
5224
|
+
onBlur: () => setVisible(false),
|
|
5225
|
+
children: [
|
|
5226
|
+
children,
|
|
5227
|
+
visible && ReactDOM.createPortal(
|
|
5228
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
5229
|
+
"div",
|
|
5230
|
+
{
|
|
5231
|
+
role: "tooltip",
|
|
5232
|
+
style: { top: coords.top, left: coords.left },
|
|
5233
|
+
className: cn(
|
|
5234
|
+
"fixed z-[9999] whitespace-nowrap rounded-md bg-foreground px-2.5 py-1 text-xs font-medium text-background shadow-lg pointer-events-none",
|
|
5235
|
+
transformClass,
|
|
5236
|
+
className
|
|
5237
|
+
),
|
|
5238
|
+
children: content
|
|
5239
|
+
}
|
|
5240
|
+
),
|
|
5241
|
+
document.body
|
|
5242
|
+
)
|
|
5243
|
+
]
|
|
5080
5244
|
}
|
|
5081
|
-
|
|
5082
|
-
return () => document.removeEventListener("mousedown", handler);
|
|
5083
|
-
}, [triggerOn]);
|
|
5084
|
-
const hoverProps = triggerOn === "hover" ? { onMouseEnter: () => setOpen(true), onMouseLeave: () => setOpen(false) } : {};
|
|
5085
|
-
return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { ref, className: "relative inline-block", ...hoverProps, children: [
|
|
5086
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { onClick: () => triggerOn === "click" && setOpen(!open), children: trigger }),
|
|
5087
|
-
open && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: cn(
|
|
5088
|
-
"absolute z-50 min-w-max rounded-xl border border-border glass shadow-2xl",
|
|
5089
|
-
PLACEMENT_CLASSES[placement],
|
|
5090
|
-
className
|
|
5091
|
-
), children: content })
|
|
5092
|
-
] });
|
|
5245
|
+
);
|
|
5093
5246
|
}
|
|
5094
5247
|
|
|
5095
|
-
// src/components/
|
|
5248
|
+
// src/components/theme-provider.tsx
|
|
5249
|
+
var import_react = require("react");
|
|
5096
5250
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
5097
|
-
var
|
|
5098
|
-
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
info: "
|
|
5251
|
+
var defaultColors = {
|
|
5252
|
+
primary: "#8b5cf6",
|
|
5253
|
+
primaryHover: "#7c3aed",
|
|
5254
|
+
secondary: "#171717",
|
|
5255
|
+
secondaryHover: "#262626",
|
|
5256
|
+
info: "#3b82f6",
|
|
5257
|
+
infoHover: "#2563eb",
|
|
5258
|
+
warning: "#f59e0b",
|
|
5259
|
+
warningHover: "#d97706",
|
|
5260
|
+
danger: "#ef4444",
|
|
5261
|
+
dangerHover: "#dc2626"
|
|
5103
5262
|
};
|
|
5104
|
-
var
|
|
5105
|
-
|
|
5106
|
-
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
|
|
5263
|
+
var initialState = {
|
|
5264
|
+
theme: "system",
|
|
5265
|
+
colors: defaultColors,
|
|
5266
|
+
fontSize: "16px",
|
|
5267
|
+
fontFamily: '"Space Grotesk", "Inter", sans-serif',
|
|
5268
|
+
setTheme: () => null,
|
|
5269
|
+
setColors: () => null,
|
|
5270
|
+
setFontSize: () => null,
|
|
5271
|
+
setFontFamily: () => null,
|
|
5272
|
+
resetSettings: () => null
|
|
5110
5273
|
};
|
|
5111
|
-
var
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5274
|
+
var ThemeProviderContext = (0, import_react.createContext)(initialState);
|
|
5275
|
+
var COLOR_PALETTE = [
|
|
5276
|
+
{ base: "#6366f1", hover: "#4f46e5" },
|
|
5277
|
+
// Indigo
|
|
5278
|
+
{ base: "#8b5cf6", hover: "#7c3aed" },
|
|
5279
|
+
// Violet
|
|
5280
|
+
{ base: "#3b82f6", hover: "#2563eb" },
|
|
5281
|
+
// Blue
|
|
5282
|
+
{ base: "#10b981", hover: "#059669" },
|
|
5283
|
+
// Emerald
|
|
5284
|
+
{ base: "#22c55e", hover: "#16a34a" },
|
|
5285
|
+
// Green
|
|
5286
|
+
{ base: "#eab308", hover: "#ca8a04" },
|
|
5287
|
+
// Yellow
|
|
5288
|
+
{ base: "#f59e0b", hover: "#d97706" },
|
|
5289
|
+
// Amber
|
|
5290
|
+
{ base: "#f97316", hover: "#ea580c" },
|
|
5291
|
+
// Orange
|
|
5292
|
+
{ base: "#ef4444", hover: "#dc2626" },
|
|
5293
|
+
// Red
|
|
5294
|
+
{ base: "#ec4899", hover: "#db2777" }
|
|
5295
|
+
// Pink
|
|
5296
|
+
];
|
|
5297
|
+
var useTheme = () => {
|
|
5298
|
+
const context = (0, import_react.useContext)(ThemeProviderContext);
|
|
5299
|
+
if (context === void 0)
|
|
5300
|
+
throw new Error("useTheme must be used within a ThemeProvider");
|
|
5301
|
+
return context;
|
|
5116
5302
|
};
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5303
|
+
|
|
5304
|
+
// src/components/ui/panel.tsx
|
|
5305
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
5306
|
+
var PanelCollapsedContext = React30.createContext(false);
|
|
5307
|
+
function PanelThemeToggle() {
|
|
5308
|
+
const { theme, setTheme } = useTheme();
|
|
5309
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
5310
|
+
"button",
|
|
5311
|
+
{
|
|
5312
|
+
type: "button",
|
|
5313
|
+
onClick: () => setTheme(theme === "light" ? "dark" : "light"),
|
|
5314
|
+
className: "text-muted-foreground hover:text-foreground transition-colors",
|
|
5315
|
+
"aria-label": "Toggle theme",
|
|
5316
|
+
children: [
|
|
5317
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react20.Sun, { className: "h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" }),
|
|
5318
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react20.Moon, { className: "absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" })
|
|
5319
|
+
]
|
|
5320
|
+
}
|
|
5321
|
+
);
|
|
5322
|
+
}
|
|
5323
|
+
function Panel({
|
|
5324
|
+
sidebar,
|
|
5325
|
+
sidebarHeader,
|
|
5326
|
+
sidebarFooter,
|
|
5327
|
+
sidebarWidth = "w-56",
|
|
5328
|
+
topbar,
|
|
5329
|
+
topbarTrailing,
|
|
5330
|
+
defaultCollapsed = false,
|
|
5331
|
+
collapsible = false,
|
|
5332
|
+
showThemeToggle = false,
|
|
5333
|
+
defaultPage,
|
|
5334
|
+
height = "h-[520px]",
|
|
5335
|
+
children,
|
|
5127
5336
|
className
|
|
5128
5337
|
}) {
|
|
5129
|
-
const
|
|
5130
|
-
return /* @__PURE__ */ (0,
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5338
|
+
const [collapsed, setCollapsed] = React30.useState(defaultCollapsed);
|
|
5339
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(PanelCollapsedContext.Provider, { value: collapsed, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
5340
|
+
"div",
|
|
5341
|
+
{
|
|
5342
|
+
className: cn(
|
|
5343
|
+
"relative flex overflow-hidden rounded-xl border border-border bg-background shadow-lg",
|
|
5344
|
+
height,
|
|
5345
|
+
className
|
|
5346
|
+
),
|
|
5347
|
+
children: [
|
|
5348
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "pointer-events-none absolute inset-0 overflow-hidden", children: [
|
|
5349
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "absolute -top-[40%] -left-[20%] h-[80%] w-[60%] rounded-full bg-primary/10 blur-[120px]" }),
|
|
5350
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "absolute -bottom-[40%] -right-[20%] h-[80%] w-[60%] rounded-full bg-info/10 blur-[120px]" })
|
|
5351
|
+
] }),
|
|
5352
|
+
sidebar && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
5353
|
+
"aside",
|
|
5354
|
+
{
|
|
5355
|
+
className: cn(
|
|
5356
|
+
"relative z-10 flex flex-col shrink-0 border-r border-border transition-all duration-200",
|
|
5357
|
+
collapsed ? "w-14" : sidebarWidth
|
|
5358
|
+
),
|
|
5359
|
+
children: [
|
|
5360
|
+
sidebarHeader && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
5361
|
+
"div",
|
|
5362
|
+
{
|
|
5363
|
+
className: cn(
|
|
5364
|
+
"shrink-0 border-b border-border",
|
|
5365
|
+
collapsed ? "flex items-center justify-center py-3" : "px-4 py-3 text-sm font-semibold"
|
|
5366
|
+
),
|
|
5367
|
+
children: sidebarHeader
|
|
5368
|
+
}
|
|
5369
|
+
),
|
|
5370
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "flex-1 overflow-y-auto py-2", children: sidebar }),
|
|
5371
|
+
sidebarFooter && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
5372
|
+
"div",
|
|
5373
|
+
{
|
|
5374
|
+
className: cn(
|
|
5375
|
+
"shrink-0 border-t border-border",
|
|
5376
|
+
collapsed ? "flex items-center justify-center py-3" : "px-4 py-3"
|
|
5377
|
+
),
|
|
5378
|
+
children: !collapsed && sidebarFooter
|
|
5379
|
+
}
|
|
5380
|
+
)
|
|
5381
|
+
]
|
|
5382
|
+
}
|
|
5383
|
+
),
|
|
5384
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "relative z-10 flex flex-1 min-w-0 flex-col", children: [
|
|
5385
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("header", { className: "flex h-14 shrink-0 items-center justify-between border-b glass px-4 gap-2", children: [
|
|
5386
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5387
|
+
collapsible && sidebar && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
5388
|
+
Tooltip,
|
|
5389
|
+
{
|
|
5390
|
+
content: collapsed ? "Expand sidebar" : "Collapse sidebar",
|
|
5391
|
+
side: "bottom",
|
|
5392
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
5393
|
+
"button",
|
|
5394
|
+
{
|
|
5395
|
+
type: "button",
|
|
5396
|
+
onClick: () => setCollapsed((c) => !c),
|
|
5397
|
+
className: "text-muted-foreground hover:text-foreground transition-colors",
|
|
5398
|
+
"aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
|
|
5399
|
+
children: collapsed ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react20.PanelLeftOpen, { className: "h-5 w-5" }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_lucide_react20.PanelLeftClose, { className: "h-5 w-5" })
|
|
5400
|
+
}
|
|
5401
|
+
)
|
|
5402
|
+
}
|
|
5403
|
+
),
|
|
5404
|
+
topbar && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "flex items-center gap-2", children: topbar })
|
|
5405
|
+
] }),
|
|
5406
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5407
|
+
topbarTrailing,
|
|
5408
|
+
showThemeToggle && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(PanelThemeToggle, {})
|
|
5409
|
+
] })
|
|
5410
|
+
] }),
|
|
5411
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("main", { className: "flex-1 overflow-y-auto p-4", children })
|
|
5412
|
+
] })
|
|
5413
|
+
]
|
|
5414
|
+
}
|
|
5415
|
+
) });
|
|
5416
|
+
}
|
|
5417
|
+
function PanelSidebarItem({
|
|
5418
|
+
icon: Icon,
|
|
5419
|
+
label,
|
|
5420
|
+
active,
|
|
5421
|
+
onClick
|
|
5422
|
+
}) {
|
|
5423
|
+
const collapsed = React30.useContext(PanelCollapsedContext);
|
|
5424
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Tooltip, { content: label, side: "right", enabled: collapsed, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
5425
|
+
"button",
|
|
5426
|
+
{
|
|
5427
|
+
type: "button",
|
|
5428
|
+
onClick,
|
|
5429
|
+
className: cn(
|
|
5430
|
+
"flex w-full items-center rounded-md text-sm font-medium transition-colors",
|
|
5431
|
+
collapsed ? "justify-center h-9 w-9 mx-auto px-0" : "gap-2 px-3 py-2",
|
|
5432
|
+
active ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-primary/20 hover:text-primary cursor-pointer"
|
|
5433
|
+
),
|
|
5434
|
+
children: [
|
|
5435
|
+
Icon && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Icon, { className: "h-4 w-4 shrink-0" }),
|
|
5436
|
+
!collapsed && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "truncate", children: label })
|
|
5437
|
+
]
|
|
5438
|
+
}
|
|
5439
|
+
) });
|
|
5440
|
+
}
|
|
5441
|
+
function PanelSidebarGroup({
|
|
5442
|
+
title,
|
|
5443
|
+
children
|
|
5444
|
+
}) {
|
|
5445
|
+
const collapsed = React30.useContext(PanelCollapsedContext);
|
|
5446
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "px-2 py-1", children: [
|
|
5447
|
+
title && !collapsed && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: "mb-1 px-2 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground", children: title }),
|
|
5448
|
+
title && collapsed && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "mx-1 mb-1 h-px bg-border" }),
|
|
5449
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("main", { className: "space-y-0.5", children })
|
|
5450
|
+
] });
|
|
5451
|
+
}
|
|
5452
|
+
|
|
5453
|
+
// src/components/ui/popover.tsx
|
|
5454
|
+
var React31 = __toESM(require("react"), 1);
|
|
5455
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
5456
|
+
var PLACEMENT_CLASSES = {
|
|
5457
|
+
"top": "bottom-full left-1/2 -translate-x-1/2 mb-2",
|
|
5458
|
+
"bottom": "top-full left-1/2 -translate-x-1/2 mt-2",
|
|
5459
|
+
"left": "right-full top-1/2 -translate-y-1/2 mr-2",
|
|
5460
|
+
"right": "left-full top-1/2 -translate-y-1/2 ml-2",
|
|
5461
|
+
"top-start": "bottom-full left-0 mb-2",
|
|
5462
|
+
"top-end": "bottom-full right-0 mb-2",
|
|
5463
|
+
"bottom-start": "top-full left-0 mt-2",
|
|
5464
|
+
"bottom-end": "top-full right-0 mt-2"
|
|
5465
|
+
};
|
|
5466
|
+
function Popover({
|
|
5467
|
+
trigger,
|
|
5468
|
+
content,
|
|
5469
|
+
placement = "bottom-start",
|
|
5470
|
+
triggerOn = "click",
|
|
5471
|
+
open: controlled,
|
|
5472
|
+
onOpenChange,
|
|
5473
|
+
className
|
|
5474
|
+
}) {
|
|
5475
|
+
const [internal, setInternal] = React31.useState(false);
|
|
5476
|
+
const ref = React31.useRef(null);
|
|
5477
|
+
const open = controlled ?? internal;
|
|
5478
|
+
function setOpen(v) {
|
|
5479
|
+
if (controlled === void 0) setInternal(v);
|
|
5480
|
+
onOpenChange?.(v);
|
|
5481
|
+
}
|
|
5482
|
+
React31.useEffect(() => {
|
|
5483
|
+
if (triggerOn !== "click") return;
|
|
5484
|
+
function handler(e) {
|
|
5485
|
+
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
5486
|
+
}
|
|
5487
|
+
document.addEventListener("mousedown", handler);
|
|
5488
|
+
return () => document.removeEventListener("mousedown", handler);
|
|
5489
|
+
}, [triggerOn]);
|
|
5490
|
+
const hoverProps = triggerOn === "hover" ? { onMouseEnter: () => setOpen(true), onMouseLeave: () => setOpen(false) } : {};
|
|
5491
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { ref, className: "relative inline-block", ...hoverProps, children: [
|
|
5492
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { onClick: () => triggerOn === "click" && setOpen(!open), children: trigger }),
|
|
5493
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: cn(
|
|
5494
|
+
"absolute z-50 min-w-max rounded-xl border border-border glass shadow-2xl",
|
|
5495
|
+
PLACEMENT_CLASSES[placement],
|
|
5496
|
+
className
|
|
5497
|
+
), children: content })
|
|
5498
|
+
] });
|
|
5499
|
+
}
|
|
5500
|
+
|
|
5501
|
+
// src/components/ui/progress.tsx
|
|
5502
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
5503
|
+
var BAR_COLOR = {
|
|
5504
|
+
default: "bg-primary",
|
|
5505
|
+
success: "bg-success",
|
|
5506
|
+
error: "bg-danger",
|
|
5507
|
+
warning: "bg-warning",
|
|
5508
|
+
info: "bg-info"
|
|
5509
|
+
};
|
|
5510
|
+
var STROKE_COLOR = {
|
|
5511
|
+
default: "stroke-primary",
|
|
5512
|
+
success: "stroke-success",
|
|
5513
|
+
error: "stroke-danger",
|
|
5514
|
+
warning: "stroke-warning",
|
|
5515
|
+
info: "stroke-info"
|
|
5516
|
+
};
|
|
5517
|
+
var HEIGHT = {
|
|
5518
|
+
xs: "h-1",
|
|
5519
|
+
sm: "h-1.5",
|
|
5520
|
+
md: "h-2.5",
|
|
5521
|
+
lg: "h-4"
|
|
5522
|
+
};
|
|
5523
|
+
function Progress({
|
|
5524
|
+
value = 0,
|
|
5525
|
+
max = 100,
|
|
5526
|
+
variant = "default",
|
|
5527
|
+
size = "md",
|
|
5528
|
+
label,
|
|
5529
|
+
showValue = false,
|
|
5530
|
+
animated = false,
|
|
5531
|
+
striped = false,
|
|
5532
|
+
indeterminate = false,
|
|
5533
|
+
className
|
|
5534
|
+
}) {
|
|
5535
|
+
const pct2 = indeterminate ? 100 : Math.min(100, Math.max(0, value / max * 100));
|
|
5536
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: cn("w-full space-y-1.5", className), children: [
|
|
5537
|
+
(label || showValue) && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center justify-between text-xs text-muted-foreground", children: [
|
|
5538
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { children: label }),
|
|
5539
|
+
showValue && !indeterminate && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { children: [
|
|
5540
|
+
Math.round(pct2),
|
|
5541
|
+
"%"
|
|
5542
|
+
] })
|
|
5543
|
+
] }),
|
|
5544
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: cn("w-full overflow-hidden rounded-full bg-muted", HEIGHT[size]), children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
5545
|
+
"div",
|
|
5546
|
+
{
|
|
5547
|
+
className: cn(
|
|
5548
|
+
"h-full rounded-full transition-all duration-500",
|
|
5549
|
+
BAR_COLOR[variant],
|
|
5550
|
+
striped && "bg-[repeating-linear-gradient(45deg,transparent,transparent_6px,rgba(255,255,255,0.15)_6px,rgba(255,255,255,0.15)_12px)]",
|
|
5551
|
+
animated && !indeterminate && "transition-none animate-pulse",
|
|
5552
|
+
indeterminate && "animate-[indeterminate_1.5s_ease-in-out_infinite]"
|
|
5553
|
+
),
|
|
5554
|
+
style: { width: indeterminate ? "40%" : `${pct2}%` }
|
|
5555
|
+
}
|
|
5556
|
+
) })
|
|
5557
|
+
] });
|
|
5152
5558
|
}
|
|
5153
5559
|
function CircularProgress({
|
|
5154
5560
|
value = 0,
|
|
@@ -5165,10 +5571,10 @@ function CircularProgress({
|
|
|
5165
5571
|
const circ = 2 * Math.PI * r;
|
|
5166
5572
|
const pct2 = indeterminate ? 0.75 : Math.min(1, Math.max(0, value / max));
|
|
5167
5573
|
const dash = pct2 * circ;
|
|
5168
|
-
return /* @__PURE__ */ (0,
|
|
5169
|
-
/* @__PURE__ */ (0,
|
|
5170
|
-
/* @__PURE__ */ (0,
|
|
5171
|
-
/* @__PURE__ */ (0,
|
|
5574
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: cn("inline-flex flex-col items-center gap-1", className), children: [
|
|
5575
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "relative", style: { width: size, height: size }, children: [
|
|
5576
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("svg", { width: size, height: size, className: cn(indeterminate && "animate-spin"), children: [
|
|
5577
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
5172
5578
|
"circle",
|
|
5173
5579
|
{
|
|
5174
5580
|
cx: size / 2,
|
|
@@ -5179,7 +5585,7 @@ function CircularProgress({
|
|
|
5179
5585
|
className: "stroke-muted"
|
|
5180
5586
|
}
|
|
5181
5587
|
),
|
|
5182
|
-
/* @__PURE__ */ (0,
|
|
5588
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
5183
5589
|
"circle",
|
|
5184
5590
|
{
|
|
5185
5591
|
cx: size / 2,
|
|
@@ -5194,18 +5600,55 @@ function CircularProgress({
|
|
|
5194
5600
|
}
|
|
5195
5601
|
)
|
|
5196
5602
|
] }),
|
|
5197
|
-
showValue && !indeterminate && /* @__PURE__ */ (0,
|
|
5603
|
+
showValue && !indeterminate && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "absolute inset-0 flex items-center justify-center text-xs font-semibold", children: [
|
|
5198
5604
|
Math.round(pct2 * 100),
|
|
5199
5605
|
"%"
|
|
5200
5606
|
] })
|
|
5201
5607
|
] }),
|
|
5202
|
-
label && /* @__PURE__ */ (0,
|
|
5608
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "text-xs text-muted-foreground", children: label })
|
|
5609
|
+
] });
|
|
5610
|
+
}
|
|
5611
|
+
|
|
5612
|
+
// src/components/ui/props-table.tsx
|
|
5613
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
5614
|
+
function PropsTable({ rows }) {
|
|
5615
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "w-full space-y-3", children: [
|
|
5616
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { children: [
|
|
5617
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("h2", { className: "text-2xl font-bold tracking-tight text-gradient", children: "Props" }),
|
|
5618
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("p", { className: "text-muted-foreground", children: "All available props for this component." })
|
|
5619
|
+
] }),
|
|
5620
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "rounded-xl border border-border overflow-hidden bg-card/50 backdrop-blur-sm shadow-sm", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "w-full overflow-auto", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("table", { className: "w-full text-sm", children: [
|
|
5621
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("tr", { className: "border-b border-border bg-muted/40", children: ["Prop", "Type", "Default", "Description"].map((h) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("th", { className: "h-11 px-4 text-left text-xs font-semibold uppercase tracking-wider text-muted-foreground whitespace-nowrap", children: h }, h)) }) }),
|
|
5622
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("tbody", { children: rows.map((row, i) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
5623
|
+
"tr",
|
|
5624
|
+
{
|
|
5625
|
+
className: cn(
|
|
5626
|
+
"border-b border-border/60 last:border-0 transition-colors hover:bg-muted/20",
|
|
5627
|
+
i % 2 !== 0 && "bg-muted/5"
|
|
5628
|
+
),
|
|
5629
|
+
children: [
|
|
5630
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("td", { className: "px-4 py-3 align-top whitespace-nowrap", children: [
|
|
5631
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("code", { className: "font-mono text-xs font-semibold text-primary", children: row.prop }),
|
|
5632
|
+
row.required && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "ml-1 text-[10px] font-bold text-danger", children: "*" })
|
|
5633
|
+
] }),
|
|
5634
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("td", { className: "px-4 py-3 align-top", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("code", { className: "font-mono text-xs text-info/90 whitespace-pre-wrap", children: row.type }) }),
|
|
5635
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("td", { className: "px-4 py-3 align-top whitespace-nowrap", children: row.default ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("code", { className: "font-mono text-xs text-muted-foreground", children: row.default }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-muted-foreground/40 text-xs", children: "\u2014" }) }),
|
|
5636
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("td", { className: "px-4 py-3 align-top text-xs text-muted-foreground leading-relaxed", children: row.description })
|
|
5637
|
+
]
|
|
5638
|
+
},
|
|
5639
|
+
row.prop
|
|
5640
|
+
)) })
|
|
5641
|
+
] }) }) }),
|
|
5642
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("p", { className: "text-xs text-muted-foreground", children: [
|
|
5643
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-danger font-bold", children: "*" }),
|
|
5644
|
+
" Required prop"
|
|
5645
|
+
] })
|
|
5203
5646
|
] });
|
|
5204
5647
|
}
|
|
5205
5648
|
|
|
5206
5649
|
// src/components/ui/radio-group.tsx
|
|
5207
|
-
var
|
|
5208
|
-
var
|
|
5650
|
+
var React32 = __toESM(require("react"), 1);
|
|
5651
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
5209
5652
|
var SIZE_RADIO = {
|
|
5210
5653
|
sm: "h-3.5 w-3.5",
|
|
5211
5654
|
md: "h-4 w-4",
|
|
@@ -5227,14 +5670,14 @@ function RadioGroup({
|
|
|
5227
5670
|
name,
|
|
5228
5671
|
className
|
|
5229
5672
|
}) {
|
|
5230
|
-
const [internal, setInternal] =
|
|
5673
|
+
const [internal, setInternal] = React32.useState(defaultValue ?? "");
|
|
5231
5674
|
const active = controlledValue ?? internal;
|
|
5232
5675
|
function select(val) {
|
|
5233
5676
|
if (!controlledValue) setInternal(val);
|
|
5234
5677
|
onChange?.(val);
|
|
5235
5678
|
}
|
|
5236
5679
|
if (variant === "card") {
|
|
5237
|
-
return /* @__PURE__ */ (0,
|
|
5680
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cn("grid gap-3", orientation === "horizontal" ? "grid-flow-col auto-cols-fr" : "grid-cols-1", className), children: options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
5238
5681
|
"label",
|
|
5239
5682
|
{
|
|
5240
5683
|
className: cn(
|
|
@@ -5243,7 +5686,7 @@ function RadioGroup({
|
|
|
5243
5686
|
active === opt.value ? "border-primary bg-primary/5 ring-1 ring-primary" : "border-border hover:border-primary/40 hover:bg-accent/30"
|
|
5244
5687
|
),
|
|
5245
5688
|
children: [
|
|
5246
|
-
/* @__PURE__ */ (0,
|
|
5689
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
5247
5690
|
"input",
|
|
5248
5691
|
{
|
|
5249
5692
|
type: "radio",
|
|
@@ -5255,17 +5698,17 @@ function RadioGroup({
|
|
|
5255
5698
|
className: "sr-only"
|
|
5256
5699
|
}
|
|
5257
5700
|
),
|
|
5258
|
-
/* @__PURE__ */ (0,
|
|
5259
|
-
opt.icon && /* @__PURE__ */ (0,
|
|
5260
|
-
/* @__PURE__ */ (0,
|
|
5261
|
-
/* @__PURE__ */ (0,
|
|
5262
|
-
opt.description && /* @__PURE__ */ (0,
|
|
5701
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex w-full gap-3", children: [
|
|
5702
|
+
opt.icon && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "shrink-0 mt-0.5 text-muted-foreground", children: opt.icon }),
|
|
5703
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
5704
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: cn("font-medium", SIZE_TEXT[size], active === opt.value && "text-primary"), children: opt.label }),
|
|
5705
|
+
opt.description && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "text-xs text-muted-foreground mt-0.5", children: opt.description })
|
|
5263
5706
|
] }),
|
|
5264
|
-
/* @__PURE__ */ (0,
|
|
5707
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: cn(
|
|
5265
5708
|
"shrink-0 mt-0.5 rounded-full border-2 flex items-center justify-center transition-colors",
|
|
5266
5709
|
SIZE_RADIO[size],
|
|
5267
5710
|
active === opt.value ? "border-primary" : "border-muted-foreground/40"
|
|
5268
|
-
), children: active === opt.value && /* @__PURE__ */ (0,
|
|
5711
|
+
), children: active === opt.value && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: cn("rounded-full bg-primary", size === "sm" ? "h-1.5 w-1.5" : size === "lg" ? "h-2.5 w-2.5" : "h-2 w-2") }) })
|
|
5269
5712
|
] })
|
|
5270
5713
|
]
|
|
5271
5714
|
},
|
|
@@ -5273,7 +5716,7 @@ function RadioGroup({
|
|
|
5273
5716
|
)) });
|
|
5274
5717
|
}
|
|
5275
5718
|
if (variant === "button") {
|
|
5276
|
-
return /* @__PURE__ */ (0,
|
|
5719
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cn("flex flex-wrap gap-2", className), children: options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
5277
5720
|
"label",
|
|
5278
5721
|
{
|
|
5279
5722
|
className: cn(
|
|
@@ -5281,390 +5724,125 @@ function RadioGroup({
|
|
|
5281
5724
|
SIZE_TEXT[size],
|
|
5282
5725
|
opt.disabled && "opacity-40 cursor-not-allowed pointer-events-none",
|
|
5283
5726
|
active === opt.value ? "border-primary bg-primary text-primary-foreground" : "border-border hover:border-primary/40 hover:bg-accent/30 text-muted-foreground"
|
|
5284
|
-
),
|
|
5285
|
-
children: [
|
|
5286
|
-
/* @__PURE__ */ (0,
|
|
5287
|
-
"input",
|
|
5288
|
-
{
|
|
5289
|
-
type: "radio",
|
|
5290
|
-
name,
|
|
5291
|
-
value: opt.value,
|
|
5292
|
-
checked: active === opt.value,
|
|
5293
|
-
disabled: opt.disabled,
|
|
5294
|
-
onChange: () => select(opt.value),
|
|
5295
|
-
className: "sr-only"
|
|
5296
|
-
}
|
|
5297
|
-
),
|
|
5298
|
-
opt.icon && /* @__PURE__ */ (0,
|
|
5299
|
-
opt.label
|
|
5300
|
-
]
|
|
5301
|
-
},
|
|
5302
|
-
opt.value
|
|
5303
|
-
)) });
|
|
5304
|
-
}
|
|
5305
|
-
return /* @__PURE__ */ (0,
|
|
5306
|
-
"label",
|
|
5307
|
-
{
|
|
5308
|
-
className: cn(
|
|
5309
|
-
"flex items-start gap-3 cursor-pointer",
|
|
5310
|
-
opt.disabled && "opacity-40 cursor-not-allowed pointer-events-none"
|
|
5311
|
-
),
|
|
5312
|
-
children: [
|
|
5313
|
-
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: cn(
|
|
5314
|
-
"mt-0.5 shrink-0 rounded-full border-2 flex items-center justify-center transition-colors",
|
|
5315
|
-
SIZE_RADIO[size],
|
|
5316
|
-
active === opt.value ? "border-primary" : "border-muted-foreground/40"
|
|
5317
|
-
), children: active === opt.value && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: cn("rounded-full bg-primary", size === "sm" ? "h-1.5 w-1.5" : size === "lg" ? "h-2.5 w-2.5" : "h-2 w-2") }) }),
|
|
5318
|
-
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
5319
|
-
"input",
|
|
5320
|
-
{
|
|
5321
|
-
type: "radio",
|
|
5322
|
-
name,
|
|
5323
|
-
value: opt.value,
|
|
5324
|
-
checked: active === opt.value,
|
|
5325
|
-
disabled: opt.disabled,
|
|
5326
|
-
onChange: () => select(opt.value),
|
|
5327
|
-
className: "sr-only"
|
|
5328
|
-
}
|
|
5329
|
-
),
|
|
5330
|
-
/* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { children: [
|
|
5331
|
-
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: cn("font-medium leading-tight", SIZE_TEXT[size]), children: opt.label }),
|
|
5332
|
-
opt.description && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: "text-xs text-muted-foreground mt-0.5", children: opt.description })
|
|
5333
|
-
] })
|
|
5334
|
-
]
|
|
5335
|
-
},
|
|
5336
|
-
opt.value
|
|
5337
|
-
)) });
|
|
5338
|
-
}
|
|
5339
|
-
|
|
5340
|
-
// src/components/ui/repeater.tsx
|
|
5341
|
-
var import_lucide_react20 = require("lucide-react");
|
|
5342
|
-
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
5343
|
-
function Repeater({
|
|
5344
|
-
items,
|
|
5345
|
-
onAdd,
|
|
5346
|
-
onRemove,
|
|
5347
|
-
renderItem,
|
|
5348
|
-
addButtonText = "Add Item",
|
|
5349
|
-
className
|
|
5350
|
-
}) {
|
|
5351
|
-
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: cn("space-y-3", className), children: [
|
|
5352
|
-
items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
5353
|
-
"div",
|
|
5354
|
-
{
|
|
5355
|
-
className: "group relative flex items-start gap-3 rounded-xl border border-border bg-card/50 backdrop-blur-sm p-4 shadow-sm transition-all duration-200 hover:border-primary/30 hover:shadow-md hover:shadow-primary/5",
|
|
5356
|
-
style: { animation: "fadeSlideIn 0.2s ease-out" },
|
|
5357
|
-
children: [
|
|
5358
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "mt-1 cursor-grab text-muted-foreground/30 group-hover:text-muted-foreground/60 transition-colors shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.GripVertical, { className: "h-4 w-4" }) }),
|
|
5359
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "mt-1 flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-primary/10 text-[10px] font-semibold text-primary", children: index + 1 }),
|
|
5360
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex-1 min-w-0", children: renderItem(item, index) }),
|
|
5361
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
5362
|
-
Button,
|
|
5363
|
-
{
|
|
5364
|
-
type: "button",
|
|
5365
|
-
variant: "ghost",
|
|
5366
|
-
size: "sm",
|
|
5367
|
-
className: "mt-0.5 h-7 w-7 shrink-0 opacity-0 group-hover:opacity-100 text-muted-foreground hover:text-danger hover:bg-danger/10 transition-all duration-150 p-0",
|
|
5368
|
-
onClick: () => onRemove(index),
|
|
5369
|
-
children: [
|
|
5370
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.Trash2, { className: "h-3.5 w-3.5" }),
|
|
5371
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "sr-only", children: "Remove item" })
|
|
5372
|
-
]
|
|
5373
|
-
}
|
|
5374
|
-
)
|
|
5375
|
-
]
|
|
5376
|
-
},
|
|
5377
|
-
index
|
|
5378
|
-
)),
|
|
5379
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
5380
|
-
"button",
|
|
5381
|
-
{
|
|
5382
|
-
type: "button",
|
|
5383
|
-
onClick: onAdd,
|
|
5384
|
-
className: "group flex w-full items-center justify-center gap-2 rounded-xl border border-dashed border-border py-3 text-sm font-medium text-muted-foreground transition-all duration-200 hover:border-primary/50 hover:bg-primary/5 hover:text-primary",
|
|
5385
|
-
children: [
|
|
5386
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-muted group-hover:bg-primary/10 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.Plus, { className: "h-3 w-3" }) }),
|
|
5387
|
-
addButtonText
|
|
5388
|
-
]
|
|
5389
|
-
}
|
|
5390
|
-
),
|
|
5391
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("style", { children: `
|
|
5392
|
-
@keyframes fadeSlideIn {
|
|
5393
|
-
from { opacity: 0; transform: translateY(-6px); }
|
|
5394
|
-
to { opacity: 1; transform: translateY(0); }
|
|
5395
|
-
}
|
|
5396
|
-
` })
|
|
5397
|
-
] });
|
|
5398
|
-
}
|
|
5399
|
-
|
|
5400
|
-
// src/components/ui/panel.tsx
|
|
5401
|
-
var React32 = __toESM(require("react"), 1);
|
|
5402
|
-
var import_lucide_react21 = require("lucide-react");
|
|
5403
|
-
|
|
5404
|
-
// src/components/ui/tooltip.tsx
|
|
5405
|
-
var React30 = __toESM(require("react"), 1);
|
|
5406
|
-
var ReactDOM = __toESM(require("react-dom"), 1);
|
|
5407
|
-
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
5408
|
-
function Tooltip({
|
|
5409
|
-
content,
|
|
5410
|
-
children,
|
|
5411
|
-
side = "right",
|
|
5412
|
-
className,
|
|
5413
|
-
enabled = true
|
|
5414
|
-
}) {
|
|
5415
|
-
const [visible, setVisible] = React30.useState(false);
|
|
5416
|
-
const [coords, setCoords] = React30.useState({ top: 0, left: 0 });
|
|
5417
|
-
const ref = React30.useRef(null);
|
|
5418
|
-
if (!enabled) return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_jsx_runtime37.Fragment, { children });
|
|
5419
|
-
function calcCoords() {
|
|
5420
|
-
const r = ref.current?.getBoundingClientRect();
|
|
5421
|
-
if (!r) return;
|
|
5422
|
-
const GAP = 8;
|
|
5423
|
-
switch (side) {
|
|
5424
|
-
case "right":
|
|
5425
|
-
setCoords({ top: r.top + r.height / 2, left: r.right + GAP });
|
|
5426
|
-
break;
|
|
5427
|
-
case "left":
|
|
5428
|
-
setCoords({ top: r.top + r.height / 2, left: r.left - GAP });
|
|
5429
|
-
break;
|
|
5430
|
-
case "top":
|
|
5431
|
-
setCoords({ top: r.top - GAP, left: r.left + r.width / 2 });
|
|
5432
|
-
break;
|
|
5433
|
-
case "bottom":
|
|
5434
|
-
setCoords({ top: r.bottom + GAP, left: r.left + r.width / 2 });
|
|
5435
|
-
break;
|
|
5436
|
-
}
|
|
5437
|
-
}
|
|
5438
|
-
const transformClass = {
|
|
5439
|
-
right: "-translate-y-1/2",
|
|
5440
|
-
left: "-translate-y-1/2 -translate-x-full",
|
|
5441
|
-
top: "-translate-x-1/2 -translate-y-full",
|
|
5442
|
-
bottom: "-translate-x-1/2"
|
|
5443
|
-
}[side];
|
|
5444
|
-
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
5445
|
-
"div",
|
|
5446
|
-
{
|
|
5447
|
-
ref,
|
|
5448
|
-
className: "relative inline-flex",
|
|
5449
|
-
onMouseEnter: () => {
|
|
5450
|
-
calcCoords();
|
|
5451
|
-
setVisible(true);
|
|
5452
|
-
},
|
|
5453
|
-
onMouseLeave: () => setVisible(false),
|
|
5454
|
-
onFocus: () => {
|
|
5455
|
-
calcCoords();
|
|
5456
|
-
setVisible(true);
|
|
5457
|
-
},
|
|
5458
|
-
onBlur: () => setVisible(false),
|
|
5459
|
-
children: [
|
|
5460
|
-
children,
|
|
5461
|
-
visible && ReactDOM.createPortal(
|
|
5462
|
-
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
5463
|
-
"div",
|
|
5464
|
-
{
|
|
5465
|
-
role: "tooltip",
|
|
5466
|
-
style: { top: coords.top, left: coords.left },
|
|
5467
|
-
className: cn(
|
|
5468
|
-
"fixed z-[9999] whitespace-nowrap rounded-md bg-foreground px-2.5 py-1 text-xs font-medium text-background shadow-lg pointer-events-none",
|
|
5469
|
-
transformClass,
|
|
5470
|
-
className
|
|
5471
|
-
),
|
|
5472
|
-
children: content
|
|
5473
|
-
}
|
|
5474
|
-
),
|
|
5475
|
-
document.body
|
|
5476
|
-
)
|
|
5477
|
-
]
|
|
5478
|
-
}
|
|
5479
|
-
);
|
|
5480
|
-
}
|
|
5481
|
-
|
|
5482
|
-
// src/components/theme-provider.tsx
|
|
5483
|
-
var import_react = require("react");
|
|
5484
|
-
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
5485
|
-
var defaultColors = {
|
|
5486
|
-
primary: "#8b5cf6",
|
|
5487
|
-
primaryHover: "#7c3aed",
|
|
5488
|
-
secondary: "#171717",
|
|
5489
|
-
secondaryHover: "#262626",
|
|
5490
|
-
info: "#3b82f6",
|
|
5491
|
-
infoHover: "#2563eb",
|
|
5492
|
-
warning: "#f59e0b",
|
|
5493
|
-
warningHover: "#d97706",
|
|
5494
|
-
danger: "#ef4444",
|
|
5495
|
-
dangerHover: "#dc2626"
|
|
5496
|
-
};
|
|
5497
|
-
var initialState = {
|
|
5498
|
-
theme: "system",
|
|
5499
|
-
colors: defaultColors,
|
|
5500
|
-
fontSize: "16px",
|
|
5501
|
-
fontFamily: '"Space Grotesk", "Inter", sans-serif',
|
|
5502
|
-
setTheme: () => null,
|
|
5503
|
-
setColors: () => null,
|
|
5504
|
-
setFontSize: () => null,
|
|
5505
|
-
setFontFamily: () => null,
|
|
5506
|
-
resetSettings: () => null
|
|
5507
|
-
};
|
|
5508
|
-
var ThemeProviderContext = (0, import_react.createContext)(initialState);
|
|
5509
|
-
var useTheme = () => {
|
|
5510
|
-
const context = (0, import_react.useContext)(ThemeProviderContext);
|
|
5511
|
-
if (context === void 0)
|
|
5512
|
-
throw new Error("useTheme must be used within a ThemeProvider");
|
|
5513
|
-
return context;
|
|
5514
|
-
};
|
|
5515
|
-
|
|
5516
|
-
// src/components/ui/panel.tsx
|
|
5517
|
-
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
5518
|
-
var PanelCollapsedContext = React32.createContext(false);
|
|
5519
|
-
function PanelThemeToggle() {
|
|
5520
|
-
const { theme, setTheme } = useTheme();
|
|
5521
|
-
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
5522
|
-
"button",
|
|
5523
|
-
{
|
|
5524
|
-
type: "button",
|
|
5525
|
-
onClick: () => setTheme(theme === "light" ? "dark" : "light"),
|
|
5526
|
-
className: "text-muted-foreground hover:text-foreground transition-colors",
|
|
5527
|
-
"aria-label": "Toggle theme",
|
|
5528
|
-
children: [
|
|
5529
|
-
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react21.Sun, { className: "h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" }),
|
|
5530
|
-
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react21.Moon, { className: "absolute h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" })
|
|
5531
|
-
]
|
|
5532
|
-
}
|
|
5533
|
-
);
|
|
5534
|
-
}
|
|
5535
|
-
function Panel({
|
|
5536
|
-
sidebar,
|
|
5537
|
-
sidebarHeader,
|
|
5538
|
-
sidebarFooter,
|
|
5539
|
-
sidebarWidth = "w-56",
|
|
5540
|
-
topbar,
|
|
5541
|
-
topbarTrailing,
|
|
5542
|
-
defaultCollapsed = false,
|
|
5543
|
-
collapsible = false,
|
|
5544
|
-
showThemeToggle = false,
|
|
5545
|
-
defaultPage,
|
|
5546
|
-
height = "h-[520px]",
|
|
5547
|
-
children,
|
|
5548
|
-
className
|
|
5549
|
-
}) {
|
|
5550
|
-
const [collapsed, setCollapsed] = React32.useState(defaultCollapsed);
|
|
5551
|
-
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PanelCollapsedContext.Provider, { value: collapsed, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
5552
|
-
"div",
|
|
5553
|
-
{
|
|
5554
|
-
className: cn(
|
|
5555
|
-
"relative flex overflow-hidden rounded-xl border border-border bg-background shadow-lg",
|
|
5556
|
-
height,
|
|
5557
|
-
className
|
|
5558
|
-
),
|
|
5559
|
-
children: [
|
|
5560
|
-
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "pointer-events-none absolute inset-0 overflow-hidden", children: [
|
|
5561
|
-
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "absolute -top-[40%] -left-[20%] h-[80%] w-[60%] rounded-full bg-primary/10 blur-[120px]" }),
|
|
5562
|
-
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "absolute -bottom-[40%] -right-[20%] h-[80%] w-[60%] rounded-full bg-info/10 blur-[120px]" })
|
|
5563
|
-
] }),
|
|
5564
|
-
sidebar && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
5565
|
-
"aside",
|
|
5566
|
-
{
|
|
5567
|
-
className: cn(
|
|
5568
|
-
"relative z-10 flex flex-col shrink-0 border-r border-border transition-all duration-200",
|
|
5569
|
-
collapsed ? "w-14" : sidebarWidth
|
|
5570
|
-
),
|
|
5571
|
-
children: [
|
|
5572
|
-
sidebarHeader && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
5573
|
-
"div",
|
|
5574
|
-
{
|
|
5575
|
-
className: cn(
|
|
5576
|
-
"shrink-0 border-b border-border",
|
|
5577
|
-
collapsed ? "flex items-center justify-center py-3" : "px-4 py-3 text-sm font-semibold"
|
|
5578
|
-
),
|
|
5579
|
-
children: sidebarHeader
|
|
5580
|
-
}
|
|
5581
|
-
),
|
|
5582
|
-
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "flex-1 overflow-y-auto py-2", children: sidebar }),
|
|
5583
|
-
sidebarFooter && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
5584
|
-
"div",
|
|
5585
|
-
{
|
|
5586
|
-
className: cn(
|
|
5587
|
-
"shrink-0 border-t border-border",
|
|
5588
|
-
collapsed ? "flex items-center justify-center py-3" : "px-4 py-3"
|
|
5589
|
-
),
|
|
5590
|
-
children: !collapsed && sidebarFooter
|
|
5591
|
-
}
|
|
5592
|
-
)
|
|
5593
|
-
]
|
|
5594
|
-
}
|
|
5595
|
-
),
|
|
5596
|
-
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "relative z-10 flex flex-1 min-w-0 flex-col", children: [
|
|
5597
|
-
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("header", { className: "flex h-14 shrink-0 items-center justify-between border-b glass px-4 gap-2", children: [
|
|
5598
|
-
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5599
|
-
collapsible && sidebar && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
5600
|
-
Tooltip,
|
|
5601
|
-
{
|
|
5602
|
-
content: collapsed ? "Expand sidebar" : "Collapse sidebar",
|
|
5603
|
-
side: "bottom",
|
|
5604
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
5605
|
-
"button",
|
|
5606
|
-
{
|
|
5607
|
-
type: "button",
|
|
5608
|
-
onClick: () => setCollapsed((c) => !c),
|
|
5609
|
-
className: "text-muted-foreground hover:text-foreground transition-colors",
|
|
5610
|
-
"aria-label": collapsed ? "Expand sidebar" : "Collapse sidebar",
|
|
5611
|
-
children: collapsed ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react21.PanelLeftOpen, { className: "h-5 w-5" }) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_lucide_react21.PanelLeftClose, { className: "h-5 w-5" })
|
|
5612
|
-
}
|
|
5613
|
-
)
|
|
5614
|
-
}
|
|
5615
|
-
),
|
|
5616
|
-
topbar && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "flex items-center gap-2", children: topbar })
|
|
5617
|
-
] }),
|
|
5618
|
-
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
5619
|
-
topbarTrailing,
|
|
5620
|
-
showThemeToggle && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PanelThemeToggle, {})
|
|
5621
|
-
] })
|
|
5622
|
-
] }),
|
|
5623
|
-
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("main", { className: "flex-1 overflow-y-auto p-4", children })
|
|
5624
|
-
] })
|
|
5625
|
-
]
|
|
5626
|
-
}
|
|
5627
|
-
) });
|
|
5628
|
-
}
|
|
5629
|
-
function PanelSidebarItem({
|
|
5630
|
-
icon: Icon,
|
|
5631
|
-
label,
|
|
5632
|
-
active,
|
|
5633
|
-
onClick
|
|
5634
|
-
}) {
|
|
5635
|
-
const collapsed = React32.useContext(PanelCollapsedContext);
|
|
5636
|
-
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Tooltip, { content: label, side: "right", enabled: collapsed, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
5637
|
-
"button",
|
|
5727
|
+
),
|
|
5728
|
+
children: [
|
|
5729
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
5730
|
+
"input",
|
|
5731
|
+
{
|
|
5732
|
+
type: "radio",
|
|
5733
|
+
name,
|
|
5734
|
+
value: opt.value,
|
|
5735
|
+
checked: active === opt.value,
|
|
5736
|
+
disabled: opt.disabled,
|
|
5737
|
+
onChange: () => select(opt.value),
|
|
5738
|
+
className: "sr-only"
|
|
5739
|
+
}
|
|
5740
|
+
),
|
|
5741
|
+
opt.icon && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "shrink-0", children: opt.icon }),
|
|
5742
|
+
opt.label
|
|
5743
|
+
]
|
|
5744
|
+
},
|
|
5745
|
+
opt.value
|
|
5746
|
+
)) });
|
|
5747
|
+
}
|
|
5748
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: cn("flex gap-3", orientation === "horizontal" ? "flex-row flex-wrap" : "flex-col", className), children: options.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
|
|
5749
|
+
"label",
|
|
5638
5750
|
{
|
|
5639
|
-
type: "button",
|
|
5640
|
-
onClick,
|
|
5641
5751
|
className: cn(
|
|
5642
|
-
"flex
|
|
5643
|
-
|
|
5644
|
-
active ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-primary/20 hover:text-primary cursor-pointer"
|
|
5752
|
+
"flex items-start gap-3 cursor-pointer",
|
|
5753
|
+
opt.disabled && "opacity-40 cursor-not-allowed pointer-events-none"
|
|
5645
5754
|
),
|
|
5646
5755
|
children: [
|
|
5647
|
-
|
|
5648
|
-
|
|
5756
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: cn(
|
|
5757
|
+
"mt-0.5 shrink-0 rounded-full border-2 flex items-center justify-center transition-colors",
|
|
5758
|
+
SIZE_RADIO[size],
|
|
5759
|
+
active === opt.value ? "border-primary" : "border-muted-foreground/40"
|
|
5760
|
+
), children: active === opt.value && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: cn("rounded-full bg-primary", size === "sm" ? "h-1.5 w-1.5" : size === "lg" ? "h-2.5 w-2.5" : "h-2 w-2") }) }),
|
|
5761
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
5762
|
+
"input",
|
|
5763
|
+
{
|
|
5764
|
+
type: "radio",
|
|
5765
|
+
name,
|
|
5766
|
+
value: opt.value,
|
|
5767
|
+
checked: active === opt.value,
|
|
5768
|
+
disabled: opt.disabled,
|
|
5769
|
+
onChange: () => select(opt.value),
|
|
5770
|
+
className: "sr-only"
|
|
5771
|
+
}
|
|
5772
|
+
),
|
|
5773
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { children: [
|
|
5774
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: cn("font-medium leading-tight", SIZE_TEXT[size]), children: opt.label }),
|
|
5775
|
+
opt.description && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "text-xs text-muted-foreground mt-0.5", children: opt.description })
|
|
5776
|
+
] })
|
|
5649
5777
|
]
|
|
5650
|
-
}
|
|
5651
|
-
|
|
5778
|
+
},
|
|
5779
|
+
opt.value
|
|
5780
|
+
)) });
|
|
5652
5781
|
}
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5782
|
+
|
|
5783
|
+
// src/components/ui/repeater.tsx
|
|
5784
|
+
var import_lucide_react21 = require("lucide-react");
|
|
5785
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
5786
|
+
function Repeater({
|
|
5787
|
+
items,
|
|
5788
|
+
onAdd,
|
|
5789
|
+
onRemove,
|
|
5790
|
+
renderItem,
|
|
5791
|
+
addButtonText = "Add Item",
|
|
5792
|
+
className
|
|
5656
5793
|
}) {
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5794
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("div", { className: cn("space-y-3", className), children: [
|
|
5795
|
+
items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
5796
|
+
"div",
|
|
5797
|
+
{
|
|
5798
|
+
className: "group relative flex items-start gap-3 rounded-xl border border-border bg-card/50 backdrop-blur-sm p-4 shadow-sm transition-all duration-200 hover:border-primary/30 hover:shadow-md hover:shadow-primary/5",
|
|
5799
|
+
style: { animation: "fadeSlideIn 0.2s ease-out" },
|
|
5800
|
+
children: [
|
|
5801
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "mt-1 cursor-grab text-muted-foreground/30 group-hover:text-muted-foreground/60 transition-colors shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react21.GripVertical, { className: "h-4 w-4" }) }),
|
|
5802
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "mt-1 flex h-5 w-5 shrink-0 items-center justify-center rounded-full bg-primary/10 text-[10px] font-semibold text-primary", children: index + 1 }),
|
|
5803
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("div", { className: "flex-1 min-w-0", children: renderItem(item, index) }),
|
|
5804
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
5805
|
+
Button,
|
|
5806
|
+
{
|
|
5807
|
+
type: "button",
|
|
5808
|
+
variant: "ghost",
|
|
5809
|
+
size: "sm",
|
|
5810
|
+
className: "mt-0.5 h-7 w-7 shrink-0 opacity-0 group-hover:opacity-100 text-muted-foreground hover:text-danger hover:bg-danger/10 transition-all duration-150 p-0",
|
|
5811
|
+
onClick: () => onRemove(index),
|
|
5812
|
+
children: [
|
|
5813
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react21.Trash2, { className: "h-3.5 w-3.5" }),
|
|
5814
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "sr-only", children: "Remove item" })
|
|
5815
|
+
]
|
|
5816
|
+
}
|
|
5817
|
+
)
|
|
5818
|
+
]
|
|
5819
|
+
},
|
|
5820
|
+
index
|
|
5821
|
+
)),
|
|
5822
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
5823
|
+
"button",
|
|
5824
|
+
{
|
|
5825
|
+
type: "button",
|
|
5826
|
+
onClick: onAdd,
|
|
5827
|
+
className: "group flex w-full items-center justify-center gap-2 rounded-xl border border-dashed border-border py-3 text-sm font-medium text-muted-foreground transition-all duration-200 hover:border-primary/50 hover:bg-primary/5 hover:text-primary",
|
|
5828
|
+
children: [
|
|
5829
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-muted group-hover:bg-primary/10 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react21.Plus, { className: "h-3 w-3" }) }),
|
|
5830
|
+
addButtonText
|
|
5831
|
+
]
|
|
5832
|
+
}
|
|
5833
|
+
),
|
|
5834
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("style", { children: `
|
|
5835
|
+
@keyframes fadeSlideIn {
|
|
5836
|
+
from { opacity: 0; transform: translateY(-6px); }
|
|
5837
|
+
to { opacity: 1; transform: translateY(0); }
|
|
5838
|
+
}
|
|
5839
|
+
` })
|
|
5662
5840
|
] });
|
|
5663
5841
|
}
|
|
5664
5842
|
|
|
5665
5843
|
// src/components/ui/resizable-panels.tsx
|
|
5666
5844
|
var React33 = __toESM(require("react"), 1);
|
|
5667
|
-
var
|
|
5845
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
5668
5846
|
function ResizablePanels({
|
|
5669
5847
|
children,
|
|
5670
5848
|
orientation = "horizontal",
|
|
@@ -5701,7 +5879,7 @@ function ResizablePanels({
|
|
|
5701
5879
|
document.removeEventListener("mouseup", onUp);
|
|
5702
5880
|
};
|
|
5703
5881
|
}, [dragging, isHorizontal, minSize, maxSize]);
|
|
5704
|
-
return /* @__PURE__ */ (0,
|
|
5882
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
5705
5883
|
"div",
|
|
5706
5884
|
{
|
|
5707
5885
|
ref: containerRef,
|
|
@@ -5712,7 +5890,7 @@ function ResizablePanels({
|
|
|
5712
5890
|
className
|
|
5713
5891
|
),
|
|
5714
5892
|
children: [
|
|
5715
|
-
/* @__PURE__ */ (0,
|
|
5893
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5716
5894
|
"div",
|
|
5717
5895
|
{
|
|
5718
5896
|
className: "overflow-auto",
|
|
@@ -5720,7 +5898,7 @@ function ResizablePanels({
|
|
|
5720
5898
|
children: children[0]
|
|
5721
5899
|
}
|
|
5722
5900
|
),
|
|
5723
|
-
/* @__PURE__ */ (0,
|
|
5901
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5724
5902
|
"div",
|
|
5725
5903
|
{
|
|
5726
5904
|
onMouseDown,
|
|
@@ -5730,13 +5908,13 @@ function ResizablePanels({
|
|
|
5730
5908
|
dragging && (isHorizontal ? "w-1.5 bg-primary/60" : "h-1.5 bg-primary/60"),
|
|
5731
5909
|
handleClassName
|
|
5732
5910
|
),
|
|
5733
|
-
children: /* @__PURE__ */ (0,
|
|
5911
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: cn(
|
|
5734
5912
|
"rounded-full bg-muted-foreground/40",
|
|
5735
5913
|
isHorizontal ? "h-8 w-0.5" : "w-8 h-0.5"
|
|
5736
5914
|
) })
|
|
5737
5915
|
}
|
|
5738
5916
|
),
|
|
5739
|
-
/* @__PURE__ */ (0,
|
|
5917
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5740
5918
|
"div",
|
|
5741
5919
|
{
|
|
5742
5920
|
className: "flex-1 overflow-auto",
|
|
@@ -5752,24 +5930,24 @@ function ResizablePanels({
|
|
|
5752
5930
|
// src/components/ui/rich-text-editor.tsx
|
|
5753
5931
|
var React34 = __toESM(require("react"), 1);
|
|
5754
5932
|
var import_lucide_react22 = require("lucide-react");
|
|
5755
|
-
var
|
|
5933
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
5756
5934
|
var TOOLBAR = [
|
|
5757
|
-
{ icon: /* @__PURE__ */ (0,
|
|
5758
|
-
{ icon: /* @__PURE__ */ (0,
|
|
5935
|
+
{ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react22.Undo, { className: "h-3.5 w-3.5" }), command: "undo", title: "Undo" },
|
|
5936
|
+
{ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react22.Redo, { className: "h-3.5 w-3.5" }), command: "redo", title: "Redo" },
|
|
5759
5937
|
"divider",
|
|
5760
|
-
{ icon: /* @__PURE__ */ (0,
|
|
5761
|
-
{ icon: /* @__PURE__ */ (0,
|
|
5938
|
+
{ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react22.Heading2, { className: "h-3.5 w-3.5" }), command: "formatBlock", value: "h2", title: "Heading 2" },
|
|
5939
|
+
{ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react22.Heading3, { className: "h-3.5 w-3.5" }), command: "formatBlock", value: "h3", title: "Heading 3" },
|
|
5762
5940
|
"divider",
|
|
5763
|
-
{ icon: /* @__PURE__ */ (0,
|
|
5764
|
-
{ icon: /* @__PURE__ */ (0,
|
|
5765
|
-
{ icon: /* @__PURE__ */ (0,
|
|
5766
|
-
{ icon: /* @__PURE__ */ (0,
|
|
5941
|
+
{ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react22.Bold, { className: "h-3.5 w-3.5" }), command: "bold", title: "Bold" },
|
|
5942
|
+
{ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react22.Italic, { className: "h-3.5 w-3.5" }), command: "italic", title: "Italic" },
|
|
5943
|
+
{ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react22.Underline, { className: "h-3.5 w-3.5" }), command: "underline", title: "Underline" },
|
|
5944
|
+
{ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react22.Code, { className: "h-3.5 w-3.5" }), command: "formatBlock", value: "pre", title: "Code block" },
|
|
5767
5945
|
"divider",
|
|
5768
|
-
{ icon: /* @__PURE__ */ (0,
|
|
5769
|
-
{ icon: /* @__PURE__ */ (0,
|
|
5770
|
-
{ icon: /* @__PURE__ */ (0,
|
|
5946
|
+
{ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react22.List, { className: "h-3.5 w-3.5" }), command: "insertUnorderedList", title: "Bullet list" },
|
|
5947
|
+
{ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react22.ListOrdered, { className: "h-3.5 w-3.5" }), command: "insertOrderedList", title: "Numbered list" },
|
|
5948
|
+
{ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react22.Quote, { className: "h-3.5 w-3.5" }), command: "formatBlock", value: "blockquote", title: "Quote" },
|
|
5771
5949
|
"divider",
|
|
5772
|
-
{ icon: /* @__PURE__ */ (0,
|
|
5950
|
+
{ icon: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react22.Link, { className: "h-3.5 w-3.5" }), command: "createLink", title: "Insert link" }
|
|
5773
5951
|
];
|
|
5774
5952
|
function RichTextEditor({
|
|
5775
5953
|
value: controlled,
|
|
@@ -5818,14 +5996,14 @@ function RichTextEditor({
|
|
|
5818
5996
|
return false;
|
|
5819
5997
|
}
|
|
5820
5998
|
}
|
|
5821
|
-
return /* @__PURE__ */ (0,
|
|
5999
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: cn(
|
|
5822
6000
|
"rounded-xl border border-border overflow-hidden transition-colors",
|
|
5823
6001
|
focused && "ring-2 ring-ring border-primary",
|
|
5824
6002
|
disabled && "opacity-50 pointer-events-none",
|
|
5825
6003
|
className
|
|
5826
6004
|
), children: [
|
|
5827
|
-
/* @__PURE__ */ (0,
|
|
5828
|
-
(item, i) => item === "divider" ? /* @__PURE__ */ (0,
|
|
6005
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "flex flex-wrap items-center gap-0.5 border-b border-border bg-muted/30 px-2 py-1.5", children: TOOLBAR.map(
|
|
6006
|
+
(item, i) => item === "divider" ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "mx-1 h-4 w-px bg-border" }, i) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
5829
6007
|
"button",
|
|
5830
6008
|
{
|
|
5831
6009
|
type: "button",
|
|
@@ -5843,9 +6021,9 @@ function RichTextEditor({
|
|
|
5843
6021
|
i
|
|
5844
6022
|
)
|
|
5845
6023
|
) }),
|
|
5846
|
-
/* @__PURE__ */ (0,
|
|
5847
|
-
isEmpty && !focused && /* @__PURE__ */ (0,
|
|
5848
|
-
/* @__PURE__ */ (0,
|
|
6024
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "relative", children: [
|
|
6025
|
+
isEmpty && !focused && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { className: "absolute top-3 left-4 text-sm text-muted-foreground pointer-events-none select-none", children: placeholder }),
|
|
6026
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
5849
6027
|
"div",
|
|
5850
6028
|
{
|
|
5851
6029
|
ref: editorRef,
|
|
@@ -5872,7 +6050,7 @@ function RichTextEditor({
|
|
|
5872
6050
|
}
|
|
5873
6051
|
|
|
5874
6052
|
// src/components/ui/scroll-area.tsx
|
|
5875
|
-
var
|
|
6053
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
5876
6054
|
function ScrollArea({
|
|
5877
6055
|
maxHeight,
|
|
5878
6056
|
maxWidth,
|
|
@@ -5887,7 +6065,7 @@ function ScrollArea({
|
|
|
5887
6065
|
horizontal: "overflow-x-auto overflow-y-hidden",
|
|
5888
6066
|
both: "overflow-auto"
|
|
5889
6067
|
}[orientation];
|
|
5890
|
-
return /* @__PURE__ */ (0,
|
|
6068
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
5891
6069
|
"div",
|
|
5892
6070
|
{
|
|
5893
6071
|
className: cn(
|
|
@@ -5909,7 +6087,7 @@ function ScrollArea({
|
|
|
5909
6087
|
// src/components/ui/section.tsx
|
|
5910
6088
|
var React35 = __toESM(require("react"), 1);
|
|
5911
6089
|
var import_lucide_react23 = require("lucide-react");
|
|
5912
|
-
var
|
|
6090
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
5913
6091
|
var variantWrap = {
|
|
5914
6092
|
default: "",
|
|
5915
6093
|
card: "rounded-xl glass shadow-lg overflow-hidden",
|
|
@@ -5942,8 +6120,8 @@ function SectionBlock({
|
|
|
5942
6120
|
contentClassName
|
|
5943
6121
|
}) {
|
|
5944
6122
|
const [open, setOpen] = React35.useState(defaultOpen);
|
|
5945
|
-
return /* @__PURE__ */ (0,
|
|
5946
|
-
(title || description || action) && /* @__PURE__ */ (0,
|
|
6123
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: cn(variantWrap[variant], className), children: [
|
|
6124
|
+
(title || description || action) && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
5947
6125
|
"div",
|
|
5948
6126
|
{
|
|
5949
6127
|
className: cn(
|
|
@@ -5954,16 +6132,16 @@ function SectionBlock({
|
|
|
5954
6132
|
),
|
|
5955
6133
|
onClick: collapsible ? () => setOpen((o) => !o) : void 0,
|
|
5956
6134
|
children: [
|
|
5957
|
-
/* @__PURE__ */ (0,
|
|
5958
|
-
icon && /* @__PURE__ */ (0,
|
|
5959
|
-
/* @__PURE__ */ (0,
|
|
5960
|
-
title && /* @__PURE__ */ (0,
|
|
5961
|
-
description && /* @__PURE__ */ (0,
|
|
6135
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-start gap-3 min-w-0", children: [
|
|
6136
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "mt-0.5 shrink-0 text-primary", children: icon }),
|
|
6137
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "min-w-0", children: [
|
|
6138
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("h3", { className: "text-base font-semibold leading-tight", children: title }),
|
|
6139
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", { className: "mt-0.5 text-sm text-muted-foreground", children: description })
|
|
5962
6140
|
] })
|
|
5963
6141
|
] }),
|
|
5964
|
-
/* @__PURE__ */ (0,
|
|
5965
|
-
action && /* @__PURE__ */ (0,
|
|
5966
|
-
collapsible && /* @__PURE__ */ (0,
|
|
6142
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
6143
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { onClick: (e) => e.stopPropagation(), children: action }),
|
|
6144
|
+
collapsible && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5967
6145
|
import_lucide_react23.ChevronDown,
|
|
5968
6146
|
{
|
|
5969
6147
|
className: cn(
|
|
@@ -5976,17 +6154,286 @@ function SectionBlock({
|
|
|
5976
6154
|
]
|
|
5977
6155
|
}
|
|
5978
6156
|
),
|
|
5979
|
-
(!collapsible || open) && /* @__PURE__ */ (0,
|
|
6157
|
+
(!collapsible || open) && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: cn(variantBody[variant], contentClassName), children })
|
|
6158
|
+
] });
|
|
6159
|
+
}
|
|
6160
|
+
|
|
6161
|
+
// src/components/ui/settings.tsx
|
|
6162
|
+
var import_lucide_react24 = require("lucide-react");
|
|
6163
|
+
|
|
6164
|
+
// src/components/ui/tabs.tsx
|
|
6165
|
+
var React36 = __toESM(require("react"), 1);
|
|
6166
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
6167
|
+
var sizeMap = {
|
|
6168
|
+
sm: "px-3 py-1.5 text-xs",
|
|
6169
|
+
md: "px-4 py-2 text-sm",
|
|
6170
|
+
lg: "px-5 py-2.5 text-base"
|
|
6171
|
+
};
|
|
6172
|
+
var variantTrack = {
|
|
6173
|
+
line: "border-b border-border gap-0",
|
|
6174
|
+
pill: "bg-muted/50 rounded-xl p-1 gap-1",
|
|
6175
|
+
boxed: "border border-border rounded-xl p-1 gap-1",
|
|
6176
|
+
lifted: "gap-0"
|
|
6177
|
+
};
|
|
6178
|
+
function tabClass(variant, size, active, disabled) {
|
|
6179
|
+
const base = cn(
|
|
6180
|
+
"inline-flex items-center gap-2 font-medium transition-all duration-150 select-none whitespace-nowrap",
|
|
6181
|
+
sizeMap[size],
|
|
6182
|
+
disabled && "opacity-40 cursor-not-allowed pointer-events-none"
|
|
6183
|
+
);
|
|
6184
|
+
if (variant === "line") return cn(
|
|
6185
|
+
base,
|
|
6186
|
+
"rounded-none border-b-2 -mb-px",
|
|
6187
|
+
active ? "border-primary text-primary" : "border-transparent text-muted-foreground hover:text-foreground hover:border-border"
|
|
6188
|
+
);
|
|
6189
|
+
if (variant === "pill") return cn(
|
|
6190
|
+
base,
|
|
6191
|
+
"rounded-lg",
|
|
6192
|
+
active ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:text-foreground hover:bg-background/60"
|
|
6193
|
+
);
|
|
6194
|
+
if (variant === "boxed") return cn(
|
|
6195
|
+
base,
|
|
6196
|
+
"rounded-lg",
|
|
6197
|
+
active ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
|
|
6198
|
+
);
|
|
6199
|
+
if (variant === "lifted") return cn(
|
|
6200
|
+
base,
|
|
6201
|
+
"rounded-t-lg border border-b-0",
|
|
6202
|
+
active ? "border-border bg-background text-foreground -mb-px" : "border-transparent text-muted-foreground hover:text-foreground"
|
|
6203
|
+
);
|
|
6204
|
+
return base;
|
|
6205
|
+
}
|
|
6206
|
+
function Tabs({
|
|
6207
|
+
items,
|
|
6208
|
+
value: controlledValue,
|
|
6209
|
+
defaultValue,
|
|
6210
|
+
onChange,
|
|
6211
|
+
variant = "line",
|
|
6212
|
+
size = "md",
|
|
6213
|
+
fullWidth = false,
|
|
6214
|
+
className
|
|
6215
|
+
}) {
|
|
6216
|
+
const [internal, setInternal] = React36.useState(defaultValue ?? items[0]?.value ?? "");
|
|
6217
|
+
const active = controlledValue ?? internal;
|
|
6218
|
+
const select = (v) => {
|
|
6219
|
+
if (!controlledValue) setInternal(v);
|
|
6220
|
+
onChange?.(v);
|
|
6221
|
+
};
|
|
6222
|
+
const activeItem = items.find((i) => i.value === active);
|
|
6223
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: cn("w-full", className), children: [
|
|
6224
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: cn("flex", fullWidth && "w-full", variantTrack[variant]), children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
6225
|
+
"button",
|
|
6226
|
+
{
|
|
6227
|
+
type: "button",
|
|
6228
|
+
disabled: item.disabled,
|
|
6229
|
+
onClick: () => select(item.value),
|
|
6230
|
+
className: cn(
|
|
6231
|
+
tabClass(variant, size, active === item.value, !!item.disabled),
|
|
6232
|
+
fullWidth && "flex-1 justify-center"
|
|
6233
|
+
),
|
|
6234
|
+
children: [
|
|
6235
|
+
item.icon && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "shrink-0", children: item.icon }),
|
|
6236
|
+
item.label,
|
|
6237
|
+
item.badge && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "shrink-0", children: item.badge })
|
|
6238
|
+
]
|
|
6239
|
+
},
|
|
6240
|
+
item.value
|
|
6241
|
+
)) }),
|
|
6242
|
+
activeItem?.content && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "mt-4", children: activeItem.content })
|
|
6243
|
+
] });
|
|
6244
|
+
}
|
|
6245
|
+
|
|
6246
|
+
// src/components/ui/settings.tsx
|
|
6247
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
6248
|
+
var FONT_SIZES = [
|
|
6249
|
+
{ value: "14px", label: "Small (14px)" },
|
|
6250
|
+
{ value: "16px", label: "Medium (16px)" },
|
|
6251
|
+
{ value: "18px", label: "Large (18px)" },
|
|
6252
|
+
{ value: "20px", label: "Extra Large (20px)" }
|
|
6253
|
+
];
|
|
6254
|
+
var FONT_FAMILIES = [
|
|
6255
|
+
{ value: '"Space Grotesk", "Inter", sans-serif', label: "Space Grotesk" },
|
|
6256
|
+
{ value: '"Inter", sans-serif', label: "Inter" },
|
|
6257
|
+
{ value: '"JetBrains Mono", monospace', label: "JetBrains Mono" },
|
|
6258
|
+
{ value: "system-ui, sans-serif", label: "System UI" }
|
|
6259
|
+
];
|
|
6260
|
+
var THEME_OPTIONS = [
|
|
6261
|
+
{ value: "light", label: "Light" },
|
|
6262
|
+
{ value: "dark", label: "Dark" },
|
|
6263
|
+
{ value: "system", label: "System" }
|
|
6264
|
+
];
|
|
6265
|
+
var COLOR_PAIRS = [
|
|
6266
|
+
{ base: "primary", hover: "primaryHover", label: "Primary" },
|
|
6267
|
+
{ base: "secondary", hover: "secondaryHover", label: "Secondary" },
|
|
6268
|
+
{ base: "info", hover: "infoHover", label: "Info" },
|
|
6269
|
+
{ base: "warning", hover: "warningHover", label: "Warning" },
|
|
6270
|
+
{ base: "danger", hover: "dangerHover", label: "Danger" }
|
|
6271
|
+
];
|
|
6272
|
+
function SettingRow({ label, description, children }) {
|
|
6273
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-start justify-between gap-4 py-3 border-b border-border/60 last:border-0", children: [
|
|
6274
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "min-w-0", children: [
|
|
6275
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "text-sm font-medium", children: label }),
|
|
6276
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "text-xs text-muted-foreground mt-0.5", children: description })
|
|
6277
|
+
] }),
|
|
6278
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "shrink-0", children })
|
|
6279
|
+
] });
|
|
6280
|
+
}
|
|
6281
|
+
function SectionHeading({ children }) {
|
|
6282
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-3 mt-1", children });
|
|
6283
|
+
}
|
|
6284
|
+
function AppearancePanel({ onThemeChange }) {
|
|
6285
|
+
const { theme, setTheme } = useTheme();
|
|
6286
|
+
const handleTheme = (v) => {
|
|
6287
|
+
const t = v;
|
|
6288
|
+
setTheme(t);
|
|
6289
|
+
onThemeChange?.(t);
|
|
6290
|
+
};
|
|
6291
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "space-y-1", children: [
|
|
6292
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(SectionHeading, { children: "Display" }),
|
|
6293
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(SettingRow, { label: "Theme", description: "Choose between light, dark, or follow system preference.", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
6294
|
+
Select,
|
|
6295
|
+
{
|
|
6296
|
+
options: THEME_OPTIONS,
|
|
6297
|
+
value: theme,
|
|
6298
|
+
onChange: handleTheme,
|
|
6299
|
+
className: "w-32"
|
|
6300
|
+
}
|
|
6301
|
+
) })
|
|
6302
|
+
] });
|
|
6303
|
+
}
|
|
6304
|
+
function ColorsPanel({ onColorsChange }) {
|
|
6305
|
+
const { colors, setColors } = useTheme();
|
|
6306
|
+
const handleColor = (key, value) => {
|
|
6307
|
+
setColors({ [key]: value });
|
|
6308
|
+
onColorsChange?.({ [key]: value });
|
|
6309
|
+
};
|
|
6310
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "space-y-4", children: [
|
|
6311
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { children: [
|
|
6312
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(SectionHeading, { children: "Quick Palette" }),
|
|
6313
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "grid grid-cols-10 gap-1.5", children: COLOR_PALETTE.map((c) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
6314
|
+
"button",
|
|
6315
|
+
{
|
|
6316
|
+
type: "button",
|
|
6317
|
+
title: c.base,
|
|
6318
|
+
onClick: () => {
|
|
6319
|
+
setColors({ primary: c.base, primaryHover: c.hover });
|
|
6320
|
+
onColorsChange?.({ primary: c.base, primaryHover: c.hover });
|
|
6321
|
+
},
|
|
6322
|
+
className: cn(
|
|
6323
|
+
"h-7 w-full rounded-md border border-white/10 transition-transform hover:scale-110 focus:outline-none focus:ring-2 focus:ring-ring",
|
|
6324
|
+
colors.primary === c.base && "ring-2 ring-ring ring-offset-1"
|
|
6325
|
+
),
|
|
6326
|
+
style: { backgroundColor: c.base }
|
|
6327
|
+
},
|
|
6328
|
+
c.base
|
|
6329
|
+
)) })
|
|
6330
|
+
] }),
|
|
6331
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { children: [
|
|
6332
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(SectionHeading, { children: "Custom Colors" }),
|
|
6333
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "space-y-0", children: COLOR_PAIRS.map((pair) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "py-3 border-b border-border/60 last:border-0", children: [
|
|
6334
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "text-xs font-semibold mb-2", children: pair.label }),
|
|
6335
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "grid grid-cols-2 gap-3", children: ["base", "hover"].map((variant) => {
|
|
6336
|
+
const key = variant === "base" ? pair.base : pair.hover;
|
|
6337
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
6338
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
6339
|
+
Input,
|
|
6340
|
+
{
|
|
6341
|
+
type: "color",
|
|
6342
|
+
value: colors[key],
|
|
6343
|
+
onChange: (e) => handleColor(key, e.target.value),
|
|
6344
|
+
className: "h-7 w-12 cursor-pointer p-0.5 rounded"
|
|
6345
|
+
}
|
|
6346
|
+
),
|
|
6347
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { children: [
|
|
6348
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "text-[10px] text-muted-foreground capitalize", children: variant }),
|
|
6349
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "text-xs font-mono", children: colors[key] })
|
|
6350
|
+
] })
|
|
6351
|
+
] }, variant);
|
|
6352
|
+
}) })
|
|
6353
|
+
] }, pair.base)) })
|
|
6354
|
+
] })
|
|
6355
|
+
] });
|
|
6356
|
+
}
|
|
6357
|
+
function TypographyPanel({
|
|
6358
|
+
onFontSizeChange,
|
|
6359
|
+
onFontFamilyChange
|
|
6360
|
+
}) {
|
|
6361
|
+
const { fontSize, setFontSize, fontFamily, setFontFamily } = useTheme();
|
|
6362
|
+
const handleSize = (v) => {
|
|
6363
|
+
setFontSize(v);
|
|
6364
|
+
onFontSizeChange?.(v);
|
|
6365
|
+
};
|
|
6366
|
+
const handleFamily = (v) => {
|
|
6367
|
+
setFontFamily(v);
|
|
6368
|
+
onFontFamilyChange?.(v);
|
|
6369
|
+
};
|
|
6370
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "space-y-1", children: [
|
|
6371
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(SectionHeading, { children: "Font" }),
|
|
6372
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(SettingRow, { label: "Font Size", description: "Base font size applied across the UI.", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Select, { options: FONT_SIZES, value: fontSize, onChange: handleSize, className: "w-44" }) }),
|
|
6373
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(SettingRow, { label: "Font Family", description: "Primary typeface used for all text.", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Select, { options: FONT_FAMILIES, value: fontFamily, onChange: handleFamily, className: "w-44" }) }),
|
|
6374
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "pt-4", children: [
|
|
6375
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(SectionHeading, { children: "Preview" }),
|
|
6376
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
6377
|
+
"div",
|
|
6378
|
+
{
|
|
6379
|
+
className: "rounded-lg border border-border bg-muted/30 p-4 space-y-1",
|
|
6380
|
+
style: { fontFamily, fontSize },
|
|
6381
|
+
children: [
|
|
6382
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "font-bold text-foreground", children: "The quick brown fox" }),
|
|
6383
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { className: "text-muted-foreground", children: "jumps over the lazy dog. 0123456789" })
|
|
6384
|
+
]
|
|
6385
|
+
}
|
|
6386
|
+
)
|
|
6387
|
+
] })
|
|
6388
|
+
] });
|
|
6389
|
+
}
|
|
6390
|
+
function Settings({
|
|
6391
|
+
defaultTab = "appearance",
|
|
6392
|
+
onThemeChange,
|
|
6393
|
+
onColorsChange,
|
|
6394
|
+
onFontSizeChange,
|
|
6395
|
+
onFontFamilyChange,
|
|
6396
|
+
onReset,
|
|
6397
|
+
className
|
|
6398
|
+
}) {
|
|
6399
|
+
const { resetSettings } = useTheme();
|
|
6400
|
+
const handleReset = () => {
|
|
6401
|
+
resetSettings();
|
|
6402
|
+
onReset?.();
|
|
6403
|
+
};
|
|
6404
|
+
const tabs = [
|
|
6405
|
+
{
|
|
6406
|
+
value: "appearance",
|
|
6407
|
+
label: "Appearance",
|
|
6408
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(AppearancePanel, { onThemeChange })
|
|
6409
|
+
},
|
|
6410
|
+
{
|
|
6411
|
+
value: "colors",
|
|
6412
|
+
label: "Colors",
|
|
6413
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ColorsPanel, { onColorsChange })
|
|
6414
|
+
},
|
|
6415
|
+
{
|
|
6416
|
+
value: "typography",
|
|
6417
|
+
label: "Typography",
|
|
6418
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(TypographyPanel, { onFontSizeChange, onFontFamilyChange })
|
|
6419
|
+
}
|
|
6420
|
+
];
|
|
6421
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: cn("flex flex-col gap-4", className), children: [
|
|
6422
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(Tabs, { items: tabs, defaultValue: defaultTab, variant: "pill" }),
|
|
6423
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "flex justify-end pt-1", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(Button, { variant: "outline", size: "sm", onClick: handleReset, children: [
|
|
6424
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react24.RotateCcw, { className: "h-3.5 w-3.5 mr-1.5" }),
|
|
6425
|
+
"Reset to Defaults"
|
|
6426
|
+
] }) })
|
|
5980
6427
|
] });
|
|
5981
6428
|
}
|
|
5982
6429
|
|
|
5983
6430
|
// src/components/ui/skeleton.tsx
|
|
5984
|
-
var
|
|
6431
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
5985
6432
|
function Skeleton({
|
|
5986
6433
|
className,
|
|
5987
6434
|
...props
|
|
5988
6435
|
}) {
|
|
5989
|
-
return /* @__PURE__ */ (0,
|
|
6436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
5990
6437
|
"div",
|
|
5991
6438
|
{
|
|
5992
6439
|
className: cn("animate-pulse rounded-md bg-white/5 backdrop-blur-sm", className),
|
|
@@ -5996,8 +6443,8 @@ function Skeleton({
|
|
|
5996
6443
|
}
|
|
5997
6444
|
|
|
5998
6445
|
// src/components/ui/slider.tsx
|
|
5999
|
-
var
|
|
6000
|
-
var
|
|
6446
|
+
var React37 = __toESM(require("react"), 1);
|
|
6447
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
6001
6448
|
function pct(val, min, max) {
|
|
6002
6449
|
return (val - min) / (max - min) * 100;
|
|
6003
6450
|
}
|
|
@@ -6016,8 +6463,8 @@ function Slider({
|
|
|
6016
6463
|
showValue = false,
|
|
6017
6464
|
className
|
|
6018
6465
|
}) {
|
|
6019
|
-
const [internal, setInternal] =
|
|
6020
|
-
const [hovering, setHovering] =
|
|
6466
|
+
const [internal, setInternal] = React37.useState(defaultValue);
|
|
6467
|
+
const [hovering, setHovering] = React37.useState(false);
|
|
6021
6468
|
const val = controlled ?? internal;
|
|
6022
6469
|
function handleChange(e) {
|
|
6023
6470
|
const v = Number(e.target.value);
|
|
@@ -6025,20 +6472,20 @@ function Slider({
|
|
|
6025
6472
|
onChange?.(v);
|
|
6026
6473
|
}
|
|
6027
6474
|
const p = pct(val, min, max);
|
|
6028
|
-
return /* @__PURE__ */ (0,
|
|
6029
|
-
(label || showValue) && /* @__PURE__ */ (0,
|
|
6030
|
-
label && /* @__PURE__ */ (0,
|
|
6031
|
-
showValue && /* @__PURE__ */ (0,
|
|
6475
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: cn("w-full space-y-2", className), children: [
|
|
6476
|
+
(label || showValue) && /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center justify-between text-sm", children: [
|
|
6477
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "font-medium", children: label }),
|
|
6478
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-muted-foreground tabular-nums", children: val })
|
|
6032
6479
|
] }),
|
|
6033
|
-
/* @__PURE__ */ (0,
|
|
6480
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
6034
6481
|
"div",
|
|
6035
6482
|
{
|
|
6036
6483
|
className: "relative flex items-center h-5",
|
|
6037
6484
|
onMouseEnter: () => setHovering(true),
|
|
6038
6485
|
onMouseLeave: () => setHovering(false),
|
|
6039
6486
|
children: [
|
|
6040
|
-
/* @__PURE__ */ (0,
|
|
6041
|
-
showTooltip && hovering && !disabled && /* @__PURE__ */ (0,
|
|
6487
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "absolute w-full h-1.5 rounded-full bg-muted overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "h-full rounded-full bg-primary", style: { width: `${p}%` } }) }),
|
|
6488
|
+
showTooltip && hovering && !disabled && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6042
6489
|
"div",
|
|
6043
6490
|
{
|
|
6044
6491
|
className: "absolute -top-8 -translate-x-1/2 bg-foreground text-background text-xs font-medium px-2 py-0.5 rounded-md pointer-events-none",
|
|
@@ -6046,7 +6493,7 @@ function Slider({
|
|
|
6046
6493
|
children: val
|
|
6047
6494
|
}
|
|
6048
6495
|
),
|
|
6049
|
-
/* @__PURE__ */ (0,
|
|
6496
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6050
6497
|
"input",
|
|
6051
6498
|
{
|
|
6052
6499
|
type: "range",
|
|
@@ -6062,7 +6509,7 @@ function Slider({
|
|
|
6062
6509
|
)
|
|
6063
6510
|
}
|
|
6064
6511
|
),
|
|
6065
|
-
/* @__PURE__ */ (0,
|
|
6512
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6066
6513
|
"div",
|
|
6067
6514
|
{
|
|
6068
6515
|
className: cn(
|
|
@@ -6075,9 +6522,9 @@ function Slider({
|
|
|
6075
6522
|
]
|
|
6076
6523
|
}
|
|
6077
6524
|
),
|
|
6078
|
-
(showMarks || marks) && /* @__PURE__ */ (0,
|
|
6079
|
-
/* @__PURE__ */ (0,
|
|
6080
|
-
m.label && /* @__PURE__ */ (0,
|
|
6525
|
+
(showMarks || marks) && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "relative w-full flex justify-between px-0", children: (marks ?? [{ value: min }, { value: max }]).map((m) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex flex-col items-center gap-0.5", style: { position: "absolute", left: `${pct(m.value, min, max)}%`, transform: "translateX(-50%)" }, children: [
|
|
6526
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "h-1 w-0.5 bg-border" }),
|
|
6527
|
+
m.label && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-[10px] text-muted-foreground", children: m.label })
|
|
6081
6528
|
] }, m.value)) })
|
|
6082
6529
|
] });
|
|
6083
6530
|
}
|
|
@@ -6094,8 +6541,8 @@ function RangeSlider({
|
|
|
6094
6541
|
showValue = false,
|
|
6095
6542
|
className
|
|
6096
6543
|
}) {
|
|
6097
|
-
const [internal, setInternal] =
|
|
6098
|
-
const [active, setActive] =
|
|
6544
|
+
const [internal, setInternal] = React37.useState(defaultValue);
|
|
6545
|
+
const [active, setActive] = React37.useState(null);
|
|
6099
6546
|
const val = controlled ?? internal;
|
|
6100
6547
|
function handleChange(idx, e) {
|
|
6101
6548
|
const v = Number(e.target.value);
|
|
@@ -6105,21 +6552,21 @@ function RangeSlider({
|
|
|
6105
6552
|
}
|
|
6106
6553
|
const p0 = pct(val[0], min, max);
|
|
6107
6554
|
const p1 = pct(val[1], min, max);
|
|
6108
|
-
return /* @__PURE__ */ (0,
|
|
6109
|
-
(label || showValue) && /* @__PURE__ */ (0,
|
|
6110
|
-
label && /* @__PURE__ */ (0,
|
|
6111
|
-
showValue && /* @__PURE__ */ (0,
|
|
6555
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: cn("w-full space-y-2", className), children: [
|
|
6556
|
+
(label || showValue) && /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center justify-between text-sm", children: [
|
|
6557
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "font-medium", children: label }),
|
|
6558
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("span", { className: "text-muted-foreground tabular-nums", children: [
|
|
6112
6559
|
val[0],
|
|
6113
6560
|
" \u2013 ",
|
|
6114
6561
|
val[1]
|
|
6115
6562
|
] })
|
|
6116
6563
|
] }),
|
|
6117
|
-
/* @__PURE__ */ (0,
|
|
6118
|
-
/* @__PURE__ */ (0,
|
|
6564
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "relative flex items-center h-5", children: [
|
|
6565
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "absolute w-full h-1.5 rounded-full bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "absolute h-full rounded-full bg-primary", style: { left: `${p0}%`, width: `${p1 - p0}%` } }) }),
|
|
6119
6566
|
[0, 1].map((idx) => {
|
|
6120
6567
|
const p = idx === 0 ? p0 : p1;
|
|
6121
|
-
return /* @__PURE__ */ (0,
|
|
6122
|
-
showTooltip && active === idx && !disabled && /* @__PURE__ */ (0,
|
|
6568
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(React37.Fragment, { children: [
|
|
6569
|
+
showTooltip && active === idx && !disabled && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6123
6570
|
"div",
|
|
6124
6571
|
{
|
|
6125
6572
|
className: "absolute -top-8 -translate-x-1/2 bg-foreground text-background text-xs font-medium px-2 py-0.5 rounded-md pointer-events-none z-10",
|
|
@@ -6127,7 +6574,7 @@ function RangeSlider({
|
|
|
6127
6574
|
children: val[idx]
|
|
6128
6575
|
}
|
|
6129
6576
|
),
|
|
6130
|
-
/* @__PURE__ */ (0,
|
|
6577
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6131
6578
|
"input",
|
|
6132
6579
|
{
|
|
6133
6580
|
type: "range",
|
|
@@ -6143,7 +6590,7 @@ function RangeSlider({
|
|
|
6143
6590
|
style: { zIndex: idx === 1 ? 2 : 1 }
|
|
6144
6591
|
}
|
|
6145
6592
|
),
|
|
6146
|
-
/* @__PURE__ */ (0,
|
|
6593
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
6147
6594
|
"div",
|
|
6148
6595
|
{
|
|
6149
6596
|
className: "absolute h-4 w-4 rounded-full border-2 border-primary bg-background shadow-md pointer-events-none",
|
|
@@ -6157,8 +6604,8 @@ function RangeSlider({
|
|
|
6157
6604
|
}
|
|
6158
6605
|
|
|
6159
6606
|
// src/components/ui/stat-card.tsx
|
|
6160
|
-
var
|
|
6161
|
-
var
|
|
6607
|
+
var import_lucide_react25 = require("lucide-react");
|
|
6608
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
6162
6609
|
function Sparkline2({ data, trend }) {
|
|
6163
6610
|
if (data.length < 2) return null;
|
|
6164
6611
|
const min = Math.min(...data);
|
|
@@ -6172,7 +6619,7 @@ function Sparkline2({ data, trend }) {
|
|
|
6172
6619
|
return `${x},${y}`;
|
|
6173
6620
|
}).join(" ");
|
|
6174
6621
|
const color = trend === "up" ? "stroke-success" : trend === "down" ? "stroke-danger" : "stroke-primary";
|
|
6175
|
-
return /* @__PURE__ */ (0,
|
|
6622
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("svg", { width: w, height: h, className: "overflow-visible", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
6176
6623
|
"polyline",
|
|
6177
6624
|
{
|
|
6178
6625
|
points: pts,
|
|
@@ -6197,41 +6644,41 @@ function StatCard({
|
|
|
6197
6644
|
className
|
|
6198
6645
|
}) {
|
|
6199
6646
|
const autoTrend = trend ?? (change === void 0 ? "neutral" : change > 0 ? "up" : change < 0 ? "down" : "neutral");
|
|
6200
|
-
const TrendIcon = autoTrend === "up" ?
|
|
6647
|
+
const TrendIcon = autoTrend === "up" ? import_lucide_react25.TrendingUp : autoTrend === "down" ? import_lucide_react25.TrendingDown : import_lucide_react25.Minus;
|
|
6201
6648
|
const trendColor = autoTrend === "up" ? "text-success" : autoTrend === "down" ? "text-danger" : "text-muted-foreground";
|
|
6202
6649
|
if (loading) {
|
|
6203
|
-
return /* @__PURE__ */ (0,
|
|
6204
|
-
/* @__PURE__ */ (0,
|
|
6205
|
-
/* @__PURE__ */ (0,
|
|
6206
|
-
/* @__PURE__ */ (0,
|
|
6650
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: cn("rounded-xl glass p-5 space-y-3 animate-pulse", className), children: [
|
|
6651
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "h-3 w-24 rounded bg-muted" }),
|
|
6652
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "h-7 w-32 rounded bg-muted" }),
|
|
6653
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "h-3 w-16 rounded bg-muted" })
|
|
6207
6654
|
] });
|
|
6208
6655
|
}
|
|
6209
|
-
return /* @__PURE__ */ (0,
|
|
6210
|
-
/* @__PURE__ */ (0,
|
|
6211
|
-
/* @__PURE__ */ (0,
|
|
6212
|
-
icon && /* @__PURE__ */ (0,
|
|
6656
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: cn("rounded-xl glass p-5 space-y-3", className), children: [
|
|
6657
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
|
|
6658
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { className: "text-sm text-muted-foreground font-medium", children: title }),
|
|
6659
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "flex h-9 w-9 items-center justify-center rounded-lg bg-primary/10 text-primary shrink-0", children: icon })
|
|
6213
6660
|
] }),
|
|
6214
|
-
/* @__PURE__ */ (0,
|
|
6215
|
-
/* @__PURE__ */ (0,
|
|
6216
|
-
sparkline && /* @__PURE__ */ (0,
|
|
6661
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-end justify-between gap-2", children: [
|
|
6662
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { className: "text-3xl font-bold tracking-tight", children: value }),
|
|
6663
|
+
sparkline && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Sparkline2, { data: sparkline, trend: autoTrend })
|
|
6217
6664
|
] }),
|
|
6218
|
-
/* @__PURE__ */ (0,
|
|
6219
|
-
change !== void 0 && /* @__PURE__ */ (0,
|
|
6220
|
-
/* @__PURE__ */ (0,
|
|
6665
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "flex items-center gap-1.5", children: [
|
|
6666
|
+
change !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("span", { className: cn("flex items-center gap-0.5 text-xs font-semibold", trendColor), children: [
|
|
6667
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(TrendIcon, { className: "h-3.5 w-3.5" }),
|
|
6221
6668
|
change > 0 ? "+" : "",
|
|
6222
6669
|
change,
|
|
6223
6670
|
"%"
|
|
6224
6671
|
] }),
|
|
6225
|
-
changeLabel && /* @__PURE__ */ (0,
|
|
6226
|
-
description && !changeLabel && /* @__PURE__ */ (0,
|
|
6672
|
+
changeLabel && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-xs text-muted-foreground", children: changeLabel }),
|
|
6673
|
+
description && !changeLabel && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-xs text-muted-foreground", children: description })
|
|
6227
6674
|
] })
|
|
6228
6675
|
] });
|
|
6229
6676
|
}
|
|
6230
6677
|
|
|
6231
|
-
// src/components/ui/stepper.tsx
|
|
6232
|
-
var
|
|
6233
|
-
var
|
|
6234
|
-
var
|
|
6678
|
+
// src/components/ui/stepper.tsx
|
|
6679
|
+
var React38 = __toESM(require("react"), 1);
|
|
6680
|
+
var import_lucide_react26 = require("lucide-react");
|
|
6681
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
6235
6682
|
function getStatus(idx, current) {
|
|
6236
6683
|
if (idx < current) return "complete";
|
|
6237
6684
|
if (idx === current) return "current";
|
|
@@ -6252,7 +6699,7 @@ function Stepper({
|
|
|
6252
6699
|
clickable = false,
|
|
6253
6700
|
className
|
|
6254
6701
|
}) {
|
|
6255
|
-
const [internal, setInternal] =
|
|
6702
|
+
const [internal, setInternal] = React38.useState(defaultCurrent);
|
|
6256
6703
|
const current = controlled ?? internal;
|
|
6257
6704
|
function go(idx) {
|
|
6258
6705
|
if (!clickable) return;
|
|
@@ -6260,20 +6707,20 @@ function Stepper({
|
|
|
6260
6707
|
onChange?.(idx);
|
|
6261
6708
|
}
|
|
6262
6709
|
const isHorizontal = orientation === "horizontal";
|
|
6263
|
-
return /* @__PURE__ */ (0,
|
|
6264
|
-
/* @__PURE__ */ (0,
|
|
6710
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: cn("w-full", className), children: [
|
|
6711
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: cn(
|
|
6265
6712
|
"flex",
|
|
6266
6713
|
isHorizontal ? "flex-row items-start" : "flex-col gap-0"
|
|
6267
6714
|
), children: steps.map((step, i) => {
|
|
6268
6715
|
const status = getStatus(i, current);
|
|
6269
6716
|
const isLast = i === steps.length - 1;
|
|
6270
|
-
return /* @__PURE__ */ (0,
|
|
6717
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(React38.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: cn(
|
|
6271
6718
|
"flex",
|
|
6272
6719
|
isHorizontal ? "flex-col items-center flex-1" : "flex-row gap-4"
|
|
6273
6720
|
), children: [
|
|
6274
|
-
/* @__PURE__ */ (0,
|
|
6275
|
-
isHorizontal && i > 0 && /* @__PURE__ */ (0,
|
|
6276
|
-
/* @__PURE__ */ (0,
|
|
6721
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: cn("flex items-center", isHorizontal ? "w-full" : "flex-col"), children: [
|
|
6722
|
+
isHorizontal && i > 0 && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: cn("flex-1 h-0.5 transition-colors", i <= current ? "bg-primary" : "bg-border") }),
|
|
6723
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
6277
6724
|
"button",
|
|
6278
6725
|
{
|
|
6279
6726
|
type: "button",
|
|
@@ -6285,35 +6732,35 @@ function Stepper({
|
|
|
6285
6732
|
clickable && "cursor-pointer hover:scale-110",
|
|
6286
6733
|
!clickable && "cursor-default"
|
|
6287
6734
|
),
|
|
6288
|
-
children: status === "complete" ? /* @__PURE__ */ (0,
|
|
6735
|
+
children: status === "complete" ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_lucide_react26.Check, { className: "h-4 w-4" }) : status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_lucide_react26.X, { className: "h-4 w-4" }) : step.icon ?? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { children: i + 1 })
|
|
6289
6736
|
}
|
|
6290
6737
|
),
|
|
6291
|
-
isHorizontal && !isLast && /* @__PURE__ */ (0,
|
|
6292
|
-
!isHorizontal && !isLast && /* @__PURE__ */ (0,
|
|
6738
|
+
isHorizontal && !isLast && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: cn("flex-1 h-0.5 transition-colors", i < current ? "bg-primary" : "bg-border") }),
|
|
6739
|
+
!isHorizontal && !isLast && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: cn("w-0.5 flex-1 min-h-8 transition-colors mt-1", i < current ? "bg-primary" : "bg-border") })
|
|
6293
6740
|
] }),
|
|
6294
|
-
/* @__PURE__ */ (0,
|
|
6741
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: cn(
|
|
6295
6742
|
isHorizontal ? "mt-2 text-center px-1" : "pb-6 min-w-0"
|
|
6296
6743
|
), children: [
|
|
6297
|
-
/* @__PURE__ */ (0,
|
|
6744
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("p", { className: cn(
|
|
6298
6745
|
"text-sm font-medium leading-tight",
|
|
6299
6746
|
status === "current" ? "text-primary" : status === "complete" ? "text-foreground" : "text-muted-foreground"
|
|
6300
6747
|
), children: [
|
|
6301
6748
|
step.label,
|
|
6302
|
-
step.optional && /* @__PURE__ */ (0,
|
|
6749
|
+
step.optional && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "ml-1 text-xs text-muted-foreground", children: "(optional)" })
|
|
6303
6750
|
] }),
|
|
6304
|
-
step.description && /* @__PURE__ */ (0,
|
|
6305
|
-
!isHorizontal && step.content && i === current && /* @__PURE__ */ (0,
|
|
6751
|
+
step.description && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("p", { className: "text-xs text-muted-foreground mt-0.5", children: step.description }),
|
|
6752
|
+
!isHorizontal && step.content && i === current && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "mt-3", children: step.content })
|
|
6306
6753
|
] })
|
|
6307
6754
|
] }) }, i);
|
|
6308
6755
|
}) }),
|
|
6309
|
-
isHorizontal && steps[current]?.content && /* @__PURE__ */ (0,
|
|
6756
|
+
isHorizontal && steps[current]?.content && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "mt-6", children: steps[current].content })
|
|
6310
6757
|
] });
|
|
6311
6758
|
}
|
|
6312
6759
|
|
|
6313
6760
|
// src/components/ui/table.tsx
|
|
6314
|
-
var
|
|
6315
|
-
var
|
|
6316
|
-
var
|
|
6761
|
+
var React39 = __toESM(require("react"), 1);
|
|
6762
|
+
var import_lucide_react27 = require("lucide-react");
|
|
6763
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
6317
6764
|
var BADGE_COLORS = {
|
|
6318
6765
|
active: "bg-success/10 text-success border-success/20",
|
|
6319
6766
|
inactive: "bg-muted text-muted-foreground border-border",
|
|
@@ -6336,11 +6783,11 @@ function Table({
|
|
|
6336
6783
|
idKey = "id",
|
|
6337
6784
|
className
|
|
6338
6785
|
}) {
|
|
6339
|
-
const [search, setSearch] =
|
|
6340
|
-
const [currentPage, setCurrentPage] =
|
|
6341
|
-
const [selectedIds, setSelectedIds] =
|
|
6342
|
-
const [sortKey, setSortKey] =
|
|
6343
|
-
const [sortDir, setSortDir] =
|
|
6786
|
+
const [search, setSearch] = React39.useState("");
|
|
6787
|
+
const [currentPage, setCurrentPage] = React39.useState(1);
|
|
6788
|
+
const [selectedIds, setSelectedIds] = React39.useState([]);
|
|
6789
|
+
const [sortKey, setSortKey] = React39.useState(null);
|
|
6790
|
+
const [sortDir, setSortDir] = React39.useState(null);
|
|
6344
6791
|
const handleSort = (key) => {
|
|
6345
6792
|
if (sortKey !== key) {
|
|
6346
6793
|
setSortKey(key);
|
|
@@ -6354,7 +6801,7 @@ function Table({
|
|
|
6354
6801
|
setSortKey(null);
|
|
6355
6802
|
setSortDir(null);
|
|
6356
6803
|
};
|
|
6357
|
-
const filteredData =
|
|
6804
|
+
const filteredData = React39.useMemo(() => {
|
|
6358
6805
|
let d = search ? data.filter(
|
|
6359
6806
|
(item) => Object.values(item).some(
|
|
6360
6807
|
(val) => val && typeof val === "string" && val.toLowerCase().includes(search.toLowerCase())
|
|
@@ -6372,18 +6819,18 @@ function Table({
|
|
|
6372
6819
|
}, [data, search, sortKey, sortDir]);
|
|
6373
6820
|
const totalPages = Math.max(1, Math.ceil(filteredData.length / itemsPerPage));
|
|
6374
6821
|
const safePage = Math.min(currentPage, totalPages);
|
|
6375
|
-
const paginatedData =
|
|
6822
|
+
const paginatedData = React39.useMemo(() => {
|
|
6376
6823
|
if (!pagination) return filteredData;
|
|
6377
6824
|
const start = (safePage - 1) * itemsPerPage;
|
|
6378
6825
|
return filteredData.slice(start, start + itemsPerPage);
|
|
6379
6826
|
}, [filteredData, pagination, safePage, itemsPerPage]);
|
|
6380
|
-
|
|
6827
|
+
React39.useEffect(() => {
|
|
6381
6828
|
setCurrentPage(1);
|
|
6382
6829
|
}, [search]);
|
|
6383
6830
|
const handleSelectAll = (checked) => setSelectedIds(checked ? paginatedData.map((item) => String(item[idKey])) : []);
|
|
6384
6831
|
const handleSelect = (id, checked) => setSelectedIds((prev) => checked ? [...prev, id] : prev.filter((i) => i !== id));
|
|
6385
6832
|
const allSelected = paginatedData.length > 0 && selectedIds.length === paginatedData.length;
|
|
6386
|
-
const pagePills =
|
|
6833
|
+
const pagePills = React39.useMemo(() => {
|
|
6387
6834
|
if (totalPages <= 5) return Array.from({ length: totalPages }, (_, i) => i + 1);
|
|
6388
6835
|
if (safePage <= 3) return [1, 2, 3, 4, 5];
|
|
6389
6836
|
if (safePage >= totalPages - 2) return [totalPages - 4, totalPages - 3, totalPages - 2, totalPages - 1, totalPages];
|
|
@@ -6391,14 +6838,14 @@ function Table({
|
|
|
6391
6838
|
}, [totalPages, safePage]);
|
|
6392
6839
|
const SortIcon = ({ col }) => {
|
|
6393
6840
|
if (!col.sortable) return null;
|
|
6394
|
-
if (sortKey !== String(col.key)) return /* @__PURE__ */ (0,
|
|
6395
|
-
return sortDir === "asc" ? /* @__PURE__ */ (0,
|
|
6841
|
+
if (sortKey !== String(col.key)) return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react27.ChevronsUpDown, { className: "ml-1.5 h-3.5 w-3.5 opacity-40" });
|
|
6842
|
+
return sortDir === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react27.ChevronUp, { className: "ml-1.5 h-3.5 w-3.5 text-primary" }) : /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react27.ChevronDown, { className: "ml-1.5 h-3.5 w-3.5 text-primary" });
|
|
6396
6843
|
};
|
|
6397
|
-
return /* @__PURE__ */ (0,
|
|
6398
|
-
/* @__PURE__ */ (0,
|
|
6399
|
-
searchable && /* @__PURE__ */ (0,
|
|
6400
|
-
/* @__PURE__ */ (0,
|
|
6401
|
-
/* @__PURE__ */ (0,
|
|
6844
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: cn("w-full space-y-3", className), children: [
|
|
6845
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center justify-between gap-3 flex-wrap", children: [
|
|
6846
|
+
searchable && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "relative w-72", children: [
|
|
6847
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react27.Search, { className: "absolute text-primary left-3 top-1/2 -translate-y-1/2 h-4 w-4 z-10" }),
|
|
6848
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6402
6849
|
"input",
|
|
6403
6850
|
{
|
|
6404
6851
|
placeholder: searchPlaceholder,
|
|
@@ -6407,17 +6854,17 @@ function Table({
|
|
|
6407
6854
|
className: "h-9 w-full rounded-xl border border-border bg-background/50 backdrop-blur-sm pl-9 pr-8 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 transition-colors hover:bg-background/80"
|
|
6408
6855
|
}
|
|
6409
6856
|
),
|
|
6410
|
-
search && /* @__PURE__ */ (0,
|
|
6857
|
+
search && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6411
6858
|
"button",
|
|
6412
6859
|
{
|
|
6413
6860
|
onClick: () => setSearch(""),
|
|
6414
6861
|
className: "absolute right-2.5 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground transition-colors",
|
|
6415
|
-
children: /* @__PURE__ */ (0,
|
|
6862
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react27.X, { className: "h-3.5 w-3.5" })
|
|
6416
6863
|
}
|
|
6417
6864
|
)
|
|
6418
6865
|
] }),
|
|
6419
|
-
/* @__PURE__ */ (0,
|
|
6420
|
-
selectable && onBulkDelete && selectedIds.length > 0 && /* @__PURE__ */ (0,
|
|
6866
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center gap-2 ml-auto", children: [
|
|
6867
|
+
selectable && onBulkDelete && selectedIds.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
6421
6868
|
"button",
|
|
6422
6869
|
{
|
|
6423
6870
|
onClick: () => {
|
|
@@ -6426,14 +6873,14 @@ function Table({
|
|
|
6426
6873
|
},
|
|
6427
6874
|
className: "inline-flex items-center gap-1.5 rounded-lg bg-danger/10 border border-danger/20 px-3 py-1.5 text-xs font-medium text-danger hover:bg-danger/20 transition-colors",
|
|
6428
6875
|
children: [
|
|
6429
|
-
/* @__PURE__ */ (0,
|
|
6876
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react27.Trash2, { className: "h-3.5 w-3.5" }),
|
|
6430
6877
|
"Delete ",
|
|
6431
6878
|
selectedIds.length,
|
|
6432
6879
|
" selected"
|
|
6433
6880
|
]
|
|
6434
6881
|
}
|
|
6435
6882
|
),
|
|
6436
|
-
/* @__PURE__ */ (0,
|
|
6883
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
|
|
6437
6884
|
filteredData.length,
|
|
6438
6885
|
" ",
|
|
6439
6886
|
filteredData.length === 1 ? "row" : "rows",
|
|
@@ -6441,16 +6888,16 @@ function Table({
|
|
|
6441
6888
|
] })
|
|
6442
6889
|
] })
|
|
6443
6890
|
] }),
|
|
6444
|
-
/* @__PURE__ */ (0,
|
|
6445
|
-
/* @__PURE__ */ (0,
|
|
6446
|
-
selectable && /* @__PURE__ */ (0,
|
|
6891
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "rounded-xl border border-border overflow-hidden bg-card/50 backdrop-blur-sm shadow-sm", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "w-full overflow-auto", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("table", { className: "w-full caption-bottom text-sm", children: [
|
|
6892
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("tr", { className: "border-b border-border bg-muted/40", children: [
|
|
6893
|
+
selectable && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("th", { className: "h-11 w-[46px] px-4 text-left align-middle", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6447
6894
|
Checkbox,
|
|
6448
6895
|
{
|
|
6449
6896
|
checked: allSelected,
|
|
6450
6897
|
onChange: (e) => handleSelectAll(e.target.checked)
|
|
6451
6898
|
}
|
|
6452
6899
|
) }),
|
|
6453
|
-
columns.map((col) => /* @__PURE__ */ (0,
|
|
6900
|
+
columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6454
6901
|
"th",
|
|
6455
6902
|
{
|
|
6456
6903
|
onClick: () => col.sortable && handleSort(String(col.key)),
|
|
@@ -6458,29 +6905,29 @@ function Table({
|
|
|
6458
6905
|
"h-11 px-4 text-left align-middle text-xs font-semibold uppercase tracking-wider text-muted-foreground select-none whitespace-nowrap",
|
|
6459
6906
|
col.sortable && "cursor-pointer hover:text-foreground transition-colors"
|
|
6460
6907
|
),
|
|
6461
|
-
children: /* @__PURE__ */ (0,
|
|
6908
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { className: "inline-flex items-center", children: [
|
|
6462
6909
|
col.title,
|
|
6463
|
-
/* @__PURE__ */ (0,
|
|
6910
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(SortIcon, { col })
|
|
6464
6911
|
] })
|
|
6465
6912
|
},
|
|
6466
6913
|
String(col.key)
|
|
6467
6914
|
))
|
|
6468
6915
|
] }) }),
|
|
6469
|
-
/* @__PURE__ */ (0,
|
|
6916
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("tbody", { children: paginatedData.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6470
6917
|
"td",
|
|
6471
6918
|
{
|
|
6472
6919
|
colSpan: columns.length + (selectable ? 1 : 0),
|
|
6473
6920
|
className: "h-32 text-center align-middle",
|
|
6474
|
-
children: /* @__PURE__ */ (0,
|
|
6475
|
-
/* @__PURE__ */ (0,
|
|
6476
|
-
/* @__PURE__ */ (0,
|
|
6477
|
-
search && /* @__PURE__ */ (0,
|
|
6921
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex flex-col items-center gap-1 text-muted-foreground", children: [
|
|
6922
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react27.Search, { className: "h-8 w-8 opacity-20" }),
|
|
6923
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "text-sm", children: "No results found" }),
|
|
6924
|
+
search && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("button", { onClick: () => setSearch(""), className: "text-xs text-primary hover:underline", children: "Clear search" })
|
|
6478
6925
|
] })
|
|
6479
6926
|
}
|
|
6480
6927
|
) }) : paginatedData.map((item, i) => {
|
|
6481
6928
|
const id = String(item[idKey] || i);
|
|
6482
6929
|
const isSelected = selectedIds.includes(id);
|
|
6483
|
-
return /* @__PURE__ */ (0,
|
|
6930
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
6484
6931
|
"tr",
|
|
6485
6932
|
{
|
|
6486
6933
|
className: cn(
|
|
@@ -6488,38 +6935,38 @@ function Table({
|
|
|
6488
6935
|
isSelected ? "bg-primary/5 hover:bg-primary/8" : "hover:bg-muted/30"
|
|
6489
6936
|
),
|
|
6490
6937
|
children: [
|
|
6491
|
-
selectable && /* @__PURE__ */ (0,
|
|
6938
|
+
selectable && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("td", { className: "px-4 py-3 align-middle", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6492
6939
|
Checkbox,
|
|
6493
6940
|
{
|
|
6494
6941
|
checked: isSelected,
|
|
6495
6942
|
onChange: (e) => handleSelect(id, e.target.checked)
|
|
6496
6943
|
}
|
|
6497
6944
|
) }),
|
|
6498
|
-
columns.map((col) => /* @__PURE__ */ (0,
|
|
6945
|
+
columns.map((col) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("td", { className: "px-4 py-3 align-middle", children: col.render ? col.render(item) : col.type === "image" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6499
6946
|
"img",
|
|
6500
6947
|
{
|
|
6501
6948
|
src: item[col.key],
|
|
6502
6949
|
alt: item[col.key],
|
|
6503
6950
|
className: "h-9 w-9 rounded-lg object-cover ring-1 ring-border"
|
|
6504
6951
|
}
|
|
6505
|
-
) : col.type === "badge" ? /* @__PURE__ */ (0,
|
|
6952
|
+
) : col.type === "badge" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { className: cn(
|
|
6506
6953
|
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-medium",
|
|
6507
6954
|
badgeClass(String(item[col.key]))
|
|
6508
6955
|
), children: [
|
|
6509
|
-
/* @__PURE__ */ (0,
|
|
6956
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: cn(
|
|
6510
6957
|
"mr-1.5 h-1.5 w-1.5 rounded-full",
|
|
6511
6958
|
badgeClass(String(item[col.key])).includes("success") ? "bg-success" : badgeClass(String(item[col.key])).includes("warning") ? "bg-warning" : badgeClass(String(item[col.key])).includes("danger") ? "bg-danger" : badgeClass(String(item[col.key])).includes("info") ? "bg-info" : "bg-primary"
|
|
6512
6959
|
) }),
|
|
6513
6960
|
item[col.key]
|
|
6514
|
-
] }) : col.type === "stack" ? /* @__PURE__ */ (0,
|
|
6961
|
+
] }) : col.type === "stack" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(AvatarStack, { images: Array.isArray(item[col.key]) ? item[col.key] : [], ...col.stackProps ?? {} }) : col.type === "icon" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "flex items-center", children: item[col.key] }) : col.type === "select" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6515
6962
|
"select",
|
|
6516
6963
|
{
|
|
6517
6964
|
value: item[col.key],
|
|
6518
6965
|
onChange: (e) => col.onChange?.(item, e.target.value),
|
|
6519
6966
|
className: "h-8 rounded-lg border border-border bg-background/50 px-2 text-xs text-foreground focus:outline-none focus:ring-2 focus:ring-ring transition-colors",
|
|
6520
|
-
children: (col.selectOptions ?? []).map((opt) => /* @__PURE__ */ (0,
|
|
6967
|
+
children: (col.selectOptions ?? []).map((opt) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("option", { value: opt, children: opt }, opt))
|
|
6521
6968
|
}
|
|
6522
|
-
) : col.type === "toggle" ? /* @__PURE__ */ (0,
|
|
6969
|
+
) : col.type === "toggle" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6523
6970
|
"button",
|
|
6524
6971
|
{
|
|
6525
6972
|
role: "switch",
|
|
@@ -6529,13 +6976,13 @@ function Table({
|
|
|
6529
6976
|
"relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
6530
6977
|
item[col.key] ? "bg-primary" : "bg-muted"
|
|
6531
6978
|
),
|
|
6532
|
-
children: /* @__PURE__ */ (0,
|
|
6979
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: cn(
|
|
6533
6980
|
"pointer-events-none inline-block h-4 w-4 rounded-full bg-white shadow-sm transition-transform",
|
|
6534
6981
|
item[col.key] ? "translate-x-4" : "translate-x-0"
|
|
6535
6982
|
) })
|
|
6536
6983
|
}
|
|
6537
|
-
) : col.type === "color" ? /* @__PURE__ */ (0,
|
|
6538
|
-
/* @__PURE__ */ (0,
|
|
6984
|
+
) : col.type === "color" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
6985
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6539
6986
|
"input",
|
|
6540
6987
|
{
|
|
6541
6988
|
type: "color",
|
|
@@ -6544,22 +6991,22 @@ function Table({
|
|
|
6544
6991
|
className: "h-7 w-7 cursor-pointer rounded border border-border bg-transparent p-0.5"
|
|
6545
6992
|
}
|
|
6546
6993
|
),
|
|
6547
|
-
/* @__PURE__ */ (0,
|
|
6548
|
-
] }) : col.type === "checkbox" ? /* @__PURE__ */ (0,
|
|
6994
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "text-xs text-muted-foreground font-mono", children: item[col.key] })
|
|
6995
|
+
] }) : col.type === "checkbox" ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6549
6996
|
Checkbox,
|
|
6550
6997
|
{
|
|
6551
6998
|
checked: !!item[col.key],
|
|
6552
6999
|
onChange: (e) => col.onChange?.(item, e.target.checked)
|
|
6553
7000
|
}
|
|
6554
|
-
) : /* @__PURE__ */ (0,
|
|
7001
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "text-foreground/90", children: item[col.key] }) }, String(col.key)))
|
|
6555
7002
|
]
|
|
6556
7003
|
},
|
|
6557
7004
|
id
|
|
6558
7005
|
);
|
|
6559
7006
|
}) })
|
|
6560
7007
|
] }) }) }),
|
|
6561
|
-
pagination && totalPages > 1 && /* @__PURE__ */ (0,
|
|
6562
|
-
/* @__PURE__ */ (0,
|
|
7008
|
+
pagination && totalPages > 1 && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
|
|
7009
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
|
|
6563
7010
|
"Showing ",
|
|
6564
7011
|
(safePage - 1) * itemsPerPage + 1,
|
|
6565
7012
|
"\u2013",
|
|
@@ -6567,21 +7014,21 @@ function Table({
|
|
|
6567
7014
|
" of ",
|
|
6568
7015
|
filteredData.length
|
|
6569
7016
|
] }),
|
|
6570
|
-
/* @__PURE__ */ (0,
|
|
6571
|
-
/* @__PURE__ */ (0,
|
|
7017
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
7018
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6572
7019
|
"button",
|
|
6573
7020
|
{
|
|
6574
7021
|
onClick: () => setCurrentPage((p) => Math.max(1, p - 1)),
|
|
6575
7022
|
disabled: safePage === 1,
|
|
6576
7023
|
className: "flex h-8 w-8 items-center justify-center rounded-lg border border-border text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-40 disabled:pointer-events-none",
|
|
6577
|
-
children: /* @__PURE__ */ (0,
|
|
7024
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react27.ChevronLeft, { className: "h-4 w-4" })
|
|
6578
7025
|
}
|
|
6579
7026
|
),
|
|
6580
|
-
pagePills[0] > 1 && /* @__PURE__ */ (0,
|
|
6581
|
-
/* @__PURE__ */ (0,
|
|
6582
|
-
pagePills[0] > 2 && /* @__PURE__ */ (0,
|
|
7027
|
+
pagePills[0] > 1 && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [
|
|
7028
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("button", { onClick: () => setCurrentPage(1), className: "flex h-8 w-8 items-center justify-center rounded-lg border border-border text-xs text-muted-foreground hover:bg-muted transition-colors", children: "1" }),
|
|
7029
|
+
pagePills[0] > 2 && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "px-1 text-muted-foreground text-xs", children: "\u2026" })
|
|
6583
7030
|
] }),
|
|
6584
|
-
pagePills.map((p) => /* @__PURE__ */ (0,
|
|
7031
|
+
pagePills.map((p) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6585
7032
|
"button",
|
|
6586
7033
|
{
|
|
6587
7034
|
onClick: () => setCurrentPage(p),
|
|
@@ -6593,17 +7040,17 @@ function Table({
|
|
|
6593
7040
|
},
|
|
6594
7041
|
p
|
|
6595
7042
|
)),
|
|
6596
|
-
pagePills[pagePills.length - 1] < totalPages && /* @__PURE__ */ (0,
|
|
6597
|
-
pagePills[pagePills.length - 1] < totalPages - 1 && /* @__PURE__ */ (0,
|
|
6598
|
-
/* @__PURE__ */ (0,
|
|
7043
|
+
pagePills[pagePills.length - 1] < totalPages && /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [
|
|
7044
|
+
pagePills[pagePills.length - 1] < totalPages - 1 && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "px-1 text-muted-foreground text-xs", children: "\u2026" }),
|
|
7045
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("button", { onClick: () => setCurrentPage(totalPages), className: "flex h-8 w-8 items-center justify-center rounded-lg border border-border text-xs text-muted-foreground hover:bg-muted transition-colors", children: totalPages })
|
|
6599
7046
|
] }),
|
|
6600
|
-
/* @__PURE__ */ (0,
|
|
7047
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6601
7048
|
"button",
|
|
6602
7049
|
{
|
|
6603
7050
|
onClick: () => setCurrentPage((p) => Math.min(totalPages, p + 1)),
|
|
6604
7051
|
disabled: safePage === totalPages,
|
|
6605
7052
|
className: "flex h-8 w-8 items-center justify-center rounded-lg border border-border text-muted-foreground transition-colors hover:bg-muted hover:text-foreground disabled:opacity-40 disabled:pointer-events-none",
|
|
6606
|
-
children: /* @__PURE__ */ (0,
|
|
7053
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react27.ChevronRight, { className: "h-4 w-4" })
|
|
6607
7054
|
}
|
|
6608
7055
|
)
|
|
6609
7056
|
] })
|
|
@@ -6611,91 +7058,9 @@ function Table({
|
|
|
6611
7058
|
] });
|
|
6612
7059
|
}
|
|
6613
7060
|
|
|
6614
|
-
// src/components/ui/tabs.tsx
|
|
6615
|
-
var React39 = __toESM(require("react"), 1);
|
|
6616
|
-
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
6617
|
-
var sizeMap = {
|
|
6618
|
-
sm: "px-3 py-1.5 text-xs",
|
|
6619
|
-
md: "px-4 py-2 text-sm",
|
|
6620
|
-
lg: "px-5 py-2.5 text-base"
|
|
6621
|
-
};
|
|
6622
|
-
var variantTrack = {
|
|
6623
|
-
line: "border-b border-border gap-0",
|
|
6624
|
-
pill: "bg-muted/50 rounded-xl p-1 gap-1",
|
|
6625
|
-
boxed: "border border-border rounded-xl p-1 gap-1",
|
|
6626
|
-
lifted: "gap-0"
|
|
6627
|
-
};
|
|
6628
|
-
function tabClass(variant, size, active, disabled) {
|
|
6629
|
-
const base = cn(
|
|
6630
|
-
"inline-flex items-center gap-2 font-medium transition-all duration-150 select-none whitespace-nowrap",
|
|
6631
|
-
sizeMap[size],
|
|
6632
|
-
disabled && "opacity-40 cursor-not-allowed pointer-events-none"
|
|
6633
|
-
);
|
|
6634
|
-
if (variant === "line") return cn(
|
|
6635
|
-
base,
|
|
6636
|
-
"rounded-none border-b-2 -mb-px",
|
|
6637
|
-
active ? "border-primary text-primary" : "border-transparent text-muted-foreground hover:text-foreground hover:border-border"
|
|
6638
|
-
);
|
|
6639
|
-
if (variant === "pill") return cn(
|
|
6640
|
-
base,
|
|
6641
|
-
"rounded-lg",
|
|
6642
|
-
active ? "bg-primary text-primary-foreground shadow-sm" : "text-muted-foreground hover:text-foreground hover:bg-background/60"
|
|
6643
|
-
);
|
|
6644
|
-
if (variant === "boxed") return cn(
|
|
6645
|
-
base,
|
|
6646
|
-
"rounded-lg",
|
|
6647
|
-
active ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
|
|
6648
|
-
);
|
|
6649
|
-
if (variant === "lifted") return cn(
|
|
6650
|
-
base,
|
|
6651
|
-
"rounded-t-lg border border-b-0",
|
|
6652
|
-
active ? "border-border bg-background text-foreground -mb-px" : "border-transparent text-muted-foreground hover:text-foreground"
|
|
6653
|
-
);
|
|
6654
|
-
return base;
|
|
6655
|
-
}
|
|
6656
|
-
function Tabs({
|
|
6657
|
-
items,
|
|
6658
|
-
value: controlledValue,
|
|
6659
|
-
defaultValue,
|
|
6660
|
-
onChange,
|
|
6661
|
-
variant = "line",
|
|
6662
|
-
size = "md",
|
|
6663
|
-
fullWidth = false,
|
|
6664
|
-
className
|
|
6665
|
-
}) {
|
|
6666
|
-
const [internal, setInternal] = React39.useState(defaultValue ?? items[0]?.value ?? "");
|
|
6667
|
-
const active = controlledValue ?? internal;
|
|
6668
|
-
const select = (v) => {
|
|
6669
|
-
if (!controlledValue) setInternal(v);
|
|
6670
|
-
onChange?.(v);
|
|
6671
|
-
};
|
|
6672
|
-
const activeItem = items.find((i) => i.value === active);
|
|
6673
|
-
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: cn("w-full", className), children: [
|
|
6674
|
-
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: cn("flex", fullWidth && "w-full", variantTrack[variant]), children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
6675
|
-
"button",
|
|
6676
|
-
{
|
|
6677
|
-
type: "button",
|
|
6678
|
-
disabled: item.disabled,
|
|
6679
|
-
onClick: () => select(item.value),
|
|
6680
|
-
className: cn(
|
|
6681
|
-
tabClass(variant, size, active === item.value, !!item.disabled),
|
|
6682
|
-
fullWidth && "flex-1 justify-center"
|
|
6683
|
-
),
|
|
6684
|
-
children: [
|
|
6685
|
-
item.icon && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "shrink-0", children: item.icon }),
|
|
6686
|
-
item.label,
|
|
6687
|
-
item.badge && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "shrink-0", children: item.badge })
|
|
6688
|
-
]
|
|
6689
|
-
},
|
|
6690
|
-
item.value
|
|
6691
|
-
)) }),
|
|
6692
|
-
activeItem?.content && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "mt-4", children: activeItem.content })
|
|
6693
|
-
] });
|
|
6694
|
-
}
|
|
6695
|
-
|
|
6696
7061
|
// src/components/ui/tag-input.tsx
|
|
6697
7062
|
var React40 = __toESM(require("react"), 1);
|
|
6698
|
-
var
|
|
7063
|
+
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
6699
7064
|
function TagInput({
|
|
6700
7065
|
value: controlled,
|
|
6701
7066
|
defaultValue = [],
|
|
@@ -6733,7 +7098,7 @@ function TagInput({
|
|
|
6733
7098
|
removeTag(tags.length - 1);
|
|
6734
7099
|
}
|
|
6735
7100
|
}
|
|
6736
|
-
return /* @__PURE__ */ (0,
|
|
7101
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
|
|
6737
7102
|
"div",
|
|
6738
7103
|
{
|
|
6739
7104
|
className: cn(
|
|
@@ -6744,8 +7109,8 @@ function TagInput({
|
|
|
6744
7109
|
),
|
|
6745
7110
|
onClick: () => inputRef.current?.focus(),
|
|
6746
7111
|
children: [
|
|
6747
|
-
tags.map((tag, i) => /* @__PURE__ */ (0,
|
|
6748
|
-
/* @__PURE__ */ (0,
|
|
7112
|
+
tags.map((tag, i) => /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Badge, { variant: "default", size: "sm", removable: true, onRemove: () => removeTag(i), children: tag }, i)),
|
|
7113
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
6749
7114
|
"input",
|
|
6750
7115
|
{
|
|
6751
7116
|
ref: inputRef,
|
|
@@ -6764,8 +7129,8 @@ function TagInput({
|
|
|
6764
7129
|
}
|
|
6765
7130
|
|
|
6766
7131
|
// src/components/ui/timeline.tsx
|
|
6767
|
-
var
|
|
6768
|
-
var
|
|
7132
|
+
var import_lucide_react28 = require("lucide-react");
|
|
7133
|
+
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
6769
7134
|
var DOT_COLOR = {
|
|
6770
7135
|
default: "bg-primary border-primary/30",
|
|
6771
7136
|
success: "bg-success border-success/30",
|
|
@@ -6781,32 +7146,32 @@ var ICON_COLOR = {
|
|
|
6781
7146
|
info: "text-info"
|
|
6782
7147
|
};
|
|
6783
7148
|
var DEFAULT_ICON = {
|
|
6784
|
-
default: /* @__PURE__ */ (0,
|
|
6785
|
-
success: /* @__PURE__ */ (0,
|
|
6786
|
-
error: /* @__PURE__ */ (0,
|
|
6787
|
-
warning: /* @__PURE__ */ (0,
|
|
6788
|
-
info: /* @__PURE__ */ (0,
|
|
7149
|
+
default: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react28.Circle, { className: "h-3 w-3" }),
|
|
7150
|
+
success: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react28.CheckCircle, { className: "h-3.5 w-3.5" }),
|
|
7151
|
+
error: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react28.XCircle, { className: "h-3.5 w-3.5" }),
|
|
7152
|
+
warning: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react28.AlertTriangle, { className: "h-3.5 w-3.5" }),
|
|
7153
|
+
info: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react28.Info, { className: "h-3.5 w-3.5" })
|
|
6789
7154
|
};
|
|
6790
7155
|
function Timeline({ items, align = "left", className }) {
|
|
6791
|
-
return /* @__PURE__ */ (0,
|
|
7156
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: cn("relative", className), children: items.map((item, i) => {
|
|
6792
7157
|
const variant = item.variant ?? "default";
|
|
6793
7158
|
const isLast = i === items.length - 1;
|
|
6794
7159
|
const isRight = align === "alternate" && i % 2 === 1;
|
|
6795
|
-
return /* @__PURE__ */ (0,
|
|
6796
|
-
/* @__PURE__ */ (0,
|
|
6797
|
-
/* @__PURE__ */ (0,
|
|
7160
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: cn("relative flex gap-4", align === "alternate" && "justify-center", isRight && "flex-row-reverse"), children: [
|
|
7161
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "flex flex-col items-center", children: [
|
|
7162
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: cn(
|
|
6798
7163
|
"flex h-8 w-8 shrink-0 items-center justify-center rounded-full border-2 z-10",
|
|
6799
7164
|
item.icon ? "bg-background border-border" : DOT_COLOR[variant]
|
|
6800
|
-
), children: /* @__PURE__ */ (0,
|
|
6801
|
-
!isLast && /* @__PURE__ */ (0,
|
|
7165
|
+
), children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: cn("shrink-0", item.icon ? ICON_COLOR[variant] : "text-white"), children: item.icon ?? DEFAULT_ICON[variant] }) }),
|
|
7166
|
+
!isLast && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "w-0.5 flex-1 bg-border mt-1 mb-1 min-h-4" })
|
|
6802
7167
|
] }),
|
|
6803
|
-
/* @__PURE__ */ (0,
|
|
6804
|
-
/* @__PURE__ */ (0,
|
|
6805
|
-
/* @__PURE__ */ (0,
|
|
6806
|
-
item.time && /* @__PURE__ */ (0,
|
|
7168
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: cn("flex-1 pb-6 min-w-0", isRight && "text-right"), children: [
|
|
7169
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: cn("flex items-start justify-between gap-2", isRight && "flex-row-reverse"), children: [
|
|
7170
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "text-sm font-semibold leading-tight", children: item.title }),
|
|
7171
|
+
item.time && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground whitespace-nowrap", children: item.time })
|
|
6807
7172
|
] }),
|
|
6808
|
-
item.description && /* @__PURE__ */ (0,
|
|
6809
|
-
item.content && /* @__PURE__ */ (0,
|
|
7173
|
+
item.description && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "mt-0.5 text-xs text-muted-foreground leading-snug", children: item.description }),
|
|
7174
|
+
item.content && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "mt-2", children: item.content })
|
|
6810
7175
|
] })
|
|
6811
7176
|
] }, item.id ?? i);
|
|
6812
7177
|
}) });
|
|
@@ -6814,7 +7179,7 @@ function Timeline({ items, align = "left", className }) {
|
|
|
6814
7179
|
|
|
6815
7180
|
// src/components/ui/toggle-switch.tsx
|
|
6816
7181
|
var React41 = __toESM(require("react"), 1);
|
|
6817
|
-
var
|
|
7182
|
+
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
6818
7183
|
var ToggleSwitch = React41.forwardRef(
|
|
6819
7184
|
({
|
|
6820
7185
|
className,
|
|
@@ -6845,13 +7210,13 @@ var ToggleSwitch = React41.forwardRef(
|
|
|
6845
7210
|
if (!isControlled) setInternalChecked(e.target.checked);
|
|
6846
7211
|
onChange?.(e);
|
|
6847
7212
|
};
|
|
6848
|
-
const toggle = /* @__PURE__ */ (0,
|
|
7213
|
+
const toggle = /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
|
|
6849
7214
|
"label",
|
|
6850
7215
|
{
|
|
6851
7216
|
htmlFor: toggleId,
|
|
6852
7217
|
className: cn("relative inline-flex items-center cursor-pointer", disabled && "opacity-50 cursor-not-allowed"),
|
|
6853
7218
|
children: [
|
|
6854
|
-
/* @__PURE__ */ (0,
|
|
7219
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
6855
7220
|
"input",
|
|
6856
7221
|
{
|
|
6857
7222
|
type: "checkbox",
|
|
@@ -6864,7 +7229,7 @@ var ToggleSwitch = React41.forwardRef(
|
|
|
6864
7229
|
...props
|
|
6865
7230
|
}
|
|
6866
7231
|
),
|
|
6867
|
-
/* @__PURE__ */ (0,
|
|
7232
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
6868
7233
|
"div",
|
|
6869
7234
|
{
|
|
6870
7235
|
className: cn(
|
|
@@ -6877,7 +7242,7 @@ var ToggleSwitch = React41.forwardRef(
|
|
|
6877
7242
|
height: trackH,
|
|
6878
7243
|
...stateColor ? { backgroundColor: stateColor } : {}
|
|
6879
7244
|
},
|
|
6880
|
-
children: /* @__PURE__ */ (0,
|
|
7245
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
6881
7246
|
"span",
|
|
6882
7247
|
{
|
|
6883
7248
|
className: `absolute top-[1px] ${isOn ? "bg-slate-50/40" : "bg-primary"} rounded-full border border-slate-300/50 shadow transition-transform duration-200`,
|
|
@@ -6895,9 +7260,9 @@ var ToggleSwitch = React41.forwardRef(
|
|
|
6895
7260
|
}
|
|
6896
7261
|
);
|
|
6897
7262
|
if (inline && label) {
|
|
6898
|
-
return /* @__PURE__ */ (0,
|
|
7263
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "inline-flex items-center gap-2 select-none", children: [
|
|
6899
7264
|
toggle,
|
|
6900
|
-
/* @__PURE__ */ (0,
|
|
7265
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("label", { htmlFor: toggleId, className: cn("text-sm cursor-pointer", disabled && "opacity-50 cursor-not-allowed"), children: label })
|
|
6901
7266
|
] });
|
|
6902
7267
|
}
|
|
6903
7268
|
return toggle;
|
|
@@ -6907,15 +7272,15 @@ ToggleSwitch.displayName = "ToggleSwitch";
|
|
|
6907
7272
|
|
|
6908
7273
|
// src/components/ui/tree-view.tsx
|
|
6909
7274
|
var React42 = __toESM(require("react"), 1);
|
|
6910
|
-
var
|
|
6911
|
-
var
|
|
7275
|
+
var import_lucide_react29 = require("lucide-react");
|
|
7276
|
+
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
6912
7277
|
function TreeNodeItem({ node, depth, selected, expanded, onToggleExpand, onSelect, multiple }) {
|
|
6913
7278
|
const hasChildren = !!node.children?.length;
|
|
6914
7279
|
const isExpanded = expanded.includes(node.id);
|
|
6915
7280
|
const isSelected = selected.includes(node.id);
|
|
6916
|
-
const defaultIcon = hasChildren ? isExpanded ? /* @__PURE__ */ (0,
|
|
6917
|
-
return /* @__PURE__ */ (0,
|
|
6918
|
-
/* @__PURE__ */ (0,
|
|
7281
|
+
const defaultIcon = hasChildren ? isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_lucide_react29.FolderOpen, { className: "h-4 w-4 text-warning" }) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_lucide_react29.Folder, { className: "h-4 w-4 text-warning" }) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_lucide_react29.File, { className: "h-4 w-4 text-muted-foreground" });
|
|
7282
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { children: [
|
|
7283
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
|
|
6919
7284
|
"div",
|
|
6920
7285
|
{
|
|
6921
7286
|
className: cn(
|
|
@@ -6929,13 +7294,13 @@ function TreeNodeItem({ node, depth, selected, expanded, onToggleExpand, onSelec
|
|
|
6929
7294
|
onSelect(node.id);
|
|
6930
7295
|
},
|
|
6931
7296
|
children: [
|
|
6932
|
-
hasChildren ? /* @__PURE__ */ (0,
|
|
6933
|
-
/* @__PURE__ */ (0,
|
|
6934
|
-
/* @__PURE__ */ (0,
|
|
7297
|
+
hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_lucide_react29.ChevronRight, { className: cn("h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform", isExpanded && "rotate-90") }) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "w-3.5 shrink-0" }),
|
|
7298
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "shrink-0", children: node.icon ?? defaultIcon }),
|
|
7299
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "truncate", children: node.label })
|
|
6935
7300
|
]
|
|
6936
7301
|
}
|
|
6937
7302
|
),
|
|
6938
|
-
hasChildren && isExpanded && /* @__PURE__ */ (0,
|
|
7303
|
+
hasChildren && isExpanded && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { children: node.children.map((child) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6939
7304
|
TreeNodeItem,
|
|
6940
7305
|
{
|
|
6941
7306
|
node: child,
|
|
@@ -6976,7 +7341,7 @@ function TreeView({
|
|
|
6976
7341
|
function toggleExpand(id) {
|
|
6977
7342
|
setExpanded((prev) => prev.includes(id) ? prev.filter((v) => v !== id) : [...prev, id]);
|
|
6978
7343
|
}
|
|
6979
|
-
return /* @__PURE__ */ (0,
|
|
7344
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: cn("w-full", className), children: nodes.map((node) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6980
7345
|
TreeNodeItem,
|
|
6981
7346
|
{
|
|
6982
7347
|
node,
|
|
@@ -6993,7 +7358,7 @@ function TreeView({
|
|
|
6993
7358
|
|
|
6994
7359
|
// src/components/ui/widget.tsx
|
|
6995
7360
|
var React43 = __toESM(require("react"), 1);
|
|
6996
|
-
var
|
|
7361
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
6997
7362
|
var iconColorMap = {
|
|
6998
7363
|
primary: "bg-primary/10 text-primary",
|
|
6999
7364
|
info: "bg-info/10 text-info",
|
|
@@ -7065,7 +7430,7 @@ function Widget({
|
|
|
7065
7430
|
const counted = useCountUp(isNumeric ? value : 0, animate && isNumeric);
|
|
7066
7431
|
const displayValue = animate && isNumeric ? counted : value;
|
|
7067
7432
|
const s = sizeMap2[size];
|
|
7068
|
-
return /* @__PURE__ */ (0,
|
|
7433
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
7069
7434
|
Card,
|
|
7070
7435
|
{
|
|
7071
7436
|
className: cn(
|
|
@@ -7076,27 +7441,27 @@ function Widget({
|
|
|
7076
7441
|
),
|
|
7077
7442
|
onClick,
|
|
7078
7443
|
...props,
|
|
7079
|
-
children: /* @__PURE__ */ (0,
|
|
7080
|
-
/* @__PURE__ */ (0,
|
|
7081
|
-
/* @__PURE__ */ (0,
|
|
7082
|
-
/* @__PURE__ */ (0,
|
|
7083
|
-
/* @__PURE__ */ (0,
|
|
7084
|
-
badge && /* @__PURE__ */ (0,
|
|
7444
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(CardContent, { className: s.card, children: [
|
|
7445
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
|
|
7446
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "min-w-0 flex-1 space-y-1", children: [
|
|
7447
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
7448
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-sm font-medium text-muted-foreground truncate", children: title }),
|
|
7449
|
+
badge && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "shrink-0", children: badge })
|
|
7085
7450
|
] }),
|
|
7086
|
-
loading ? /* @__PURE__ */ (0,
|
|
7087
|
-
description && /* @__PURE__ */ (0,
|
|
7451
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "h-8 w-24 animate-pulse rounded-md bg-muted" }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: cn("font-bold tabular-nums", s.value), children: displayValue }),
|
|
7452
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("p", { className: "text-xs text-muted-foreground", children: description })
|
|
7088
7453
|
] }),
|
|
7089
|
-
icon && /* @__PURE__ */ (0,
|
|
7454
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: cn(
|
|
7090
7455
|
"relative flex shrink-0 items-center justify-center rounded-full",
|
|
7091
7456
|
s.icon,
|
|
7092
7457
|
iconColorMap[iconColor]
|
|
7093
7458
|
), children: [
|
|
7094
|
-
pulse && /* @__PURE__ */ (0,
|
|
7095
|
-
/* @__PURE__ */ (0,
|
|
7459
|
+
pulse && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "absolute inset-0 rounded-full animate-ping opacity-30 bg-current" }),
|
|
7460
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: s.iconSize, children: icon })
|
|
7096
7461
|
] })
|
|
7097
7462
|
] }),
|
|
7098
|
-
trendValue && !loading && /* @__PURE__ */ (0,
|
|
7099
|
-
/* @__PURE__ */ (0,
|
|
7463
|
+
trendValue && !loading && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "mt-3 flex items-center gap-1.5 text-sm", children: [
|
|
7464
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: cn(
|
|
7100
7465
|
"font-medium",
|
|
7101
7466
|
trend === "up" && "text-success",
|
|
7102
7467
|
trend === "down" && "text-danger",
|
|
@@ -7106,21 +7471,21 @@ function Widget({
|
|
|
7106
7471
|
trend === "down" && "\u2193 ",
|
|
7107
7472
|
trendValue
|
|
7108
7473
|
] }),
|
|
7109
|
-
previousValue !== void 0 && /* @__PURE__ */ (0,
|
|
7474
|
+
previousValue !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: "text-muted-foreground", children: [
|
|
7110
7475
|
"vs ",
|
|
7111
7476
|
previousValue
|
|
7112
7477
|
] }),
|
|
7113
|
-
/* @__PURE__ */ (0,
|
|
7478
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "text-muted-foreground", children: trendLabel })
|
|
7114
7479
|
] }),
|
|
7115
|
-
progress !== void 0 && /* @__PURE__ */ (0,
|
|
7116
|
-
/* @__PURE__ */ (0,
|
|
7117
|
-
/* @__PURE__ */ (0,
|
|
7118
|
-
/* @__PURE__ */ (0,
|
|
7480
|
+
progress !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "mt-4 space-y-1", children: [
|
|
7481
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex justify-between text-xs text-muted-foreground", children: [
|
|
7482
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { children: "Progress" }),
|
|
7483
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { children: [
|
|
7119
7484
|
Math.min(100, Math.max(0, progress)),
|
|
7120
7485
|
"%"
|
|
7121
7486
|
] })
|
|
7122
7487
|
] }),
|
|
7123
|
-
/* @__PURE__ */ (0,
|
|
7488
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "h-1.5 w-full rounded-full bg-muted overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
7124
7489
|
"div",
|
|
7125
7490
|
{
|
|
7126
7491
|
className: cn("h-full rounded-full transition-all duration-700", progressColorMap[progressColor]),
|
|
@@ -7128,10 +7493,461 @@ function Widget({
|
|
|
7128
7493
|
}
|
|
7129
7494
|
) })
|
|
7130
7495
|
] }),
|
|
7131
|
-
footer && /* @__PURE__ */ (0,
|
|
7496
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "mt-4 border-t pt-3 text-sm text-muted-foreground", children: footer })
|
|
7497
|
+
] })
|
|
7498
|
+
}
|
|
7499
|
+
);
|
|
7500
|
+
}
|
|
7501
|
+
|
|
7502
|
+
// src/components/ui/wizard.tsx
|
|
7503
|
+
var React44 = __toESM(require("react"), 1);
|
|
7504
|
+
var import_lucide_react30 = require("lucide-react");
|
|
7505
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
7506
|
+
var SIZE_MAP = {
|
|
7507
|
+
sm: "max-w-sm",
|
|
7508
|
+
md: "max-w-lg",
|
|
7509
|
+
lg: "max-w-2xl",
|
|
7510
|
+
xl: "max-w-4xl",
|
|
7511
|
+
full: "max-w-full"
|
|
7512
|
+
};
|
|
7513
|
+
function stepStatus(idx, current) {
|
|
7514
|
+
if (idx < current) return "complete";
|
|
7515
|
+
if (idx === current) return "current";
|
|
7516
|
+
return "upcoming";
|
|
7517
|
+
}
|
|
7518
|
+
function HeaderDefault({
|
|
7519
|
+
steps,
|
|
7520
|
+
current,
|
|
7521
|
+
clickable,
|
|
7522
|
+
onGo
|
|
7523
|
+
}) {
|
|
7524
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "flex items-start w-full", children: steps.map((step, i) => {
|
|
7525
|
+
const status = stepStatus(i, current);
|
|
7526
|
+
const isLast = i === steps.length - 1;
|
|
7527
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(React44.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex flex-col items-center flex-1 min-w-0", children: [
|
|
7528
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex items-center w-full", children: [
|
|
7529
|
+
i > 0 && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: cn("flex-1 h-0.5 transition-colors", i <= current ? "bg-primary" : "bg-border") }),
|
|
7530
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
7531
|
+
"button",
|
|
7532
|
+
{
|
|
7533
|
+
type: "button",
|
|
7534
|
+
disabled: !clickable || status === "upcoming",
|
|
7535
|
+
onClick: () => clickable && status !== "upcoming" && onGo(i),
|
|
7536
|
+
className: cn(
|
|
7537
|
+
"flex h-8 w-8 shrink-0 items-center justify-center rounded-full border-2 text-xs font-semibold transition-all",
|
|
7538
|
+
status === "complete" && "bg-primary border-primary text-primary-foreground",
|
|
7539
|
+
status === "current" && "bg-background border-primary text-primary ring-4 ring-primary/20",
|
|
7540
|
+
status === "upcoming" && "bg-background border-border text-muted-foreground",
|
|
7541
|
+
clickable && status !== "upcoming" && "cursor-pointer hover:scale-110"
|
|
7542
|
+
),
|
|
7543
|
+
children: status === "complete" ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react30.Check, { className: "h-3.5 w-3.5" }) : step.icon ?? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { children: i + 1 })
|
|
7544
|
+
}
|
|
7545
|
+
),
|
|
7546
|
+
!isLast && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: cn("flex-1 h-0.5 transition-colors", i < current ? "bg-primary" : "bg-border") })
|
|
7547
|
+
] }),
|
|
7548
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "mt-2 text-center px-1 max-w-[80px]", children: [
|
|
7549
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: cn(
|
|
7550
|
+
"text-xs font-medium leading-tight truncate",
|
|
7551
|
+
status === "current" ? "text-primary" : status === "complete" ? "text-foreground" : "text-muted-foreground"
|
|
7552
|
+
), children: step.title }),
|
|
7553
|
+
step.optional && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "text-[10px] text-muted-foreground", children: "(optional)" })
|
|
7554
|
+
] })
|
|
7555
|
+
] }) }, i);
|
|
7556
|
+
}) });
|
|
7557
|
+
}
|
|
7558
|
+
function HeaderDots({ steps, current, clickable, onGo }) {
|
|
7559
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex flex-col items-center gap-3 w-full", children: [
|
|
7560
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "flex items-center gap-2", children: steps.map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
7561
|
+
"button",
|
|
7562
|
+
{
|
|
7563
|
+
type: "button",
|
|
7564
|
+
disabled: !clickable || i > current,
|
|
7565
|
+
onClick: () => clickable && i <= current && onGo(i),
|
|
7566
|
+
className: cn(
|
|
7567
|
+
"rounded-full transition-all duration-200",
|
|
7568
|
+
i === current ? "w-6 h-2.5 bg-primary" : i < current ? "w-2.5 h-2.5 bg-primary/60 hover:bg-primary cursor-pointer" : "w-2.5 h-2.5 bg-border"
|
|
7569
|
+
)
|
|
7570
|
+
},
|
|
7571
|
+
i
|
|
7572
|
+
)) }),
|
|
7573
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "text-center", children: [
|
|
7574
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "text-sm font-semibold", children: steps[current]?.title }),
|
|
7575
|
+
steps[current]?.description && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "text-xs text-muted-foreground mt-0.5", children: steps[current].description })
|
|
7576
|
+
] })
|
|
7577
|
+
] });
|
|
7578
|
+
}
|
|
7579
|
+
function HeaderMinimal({ steps, current }) {
|
|
7580
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex items-center justify-between w-full", children: [
|
|
7581
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { children: [
|
|
7582
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "text-base font-semibold", children: steps[current]?.title }),
|
|
7583
|
+
steps[current]?.description && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "text-xs text-muted-foreground mt-0.5", children: steps[current].description })
|
|
7584
|
+
] }),
|
|
7585
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("span", { className: "text-xs font-medium text-muted-foreground shrink-0 ml-4", children: [
|
|
7586
|
+
"Step ",
|
|
7587
|
+
current + 1,
|
|
7588
|
+
" of ",
|
|
7589
|
+
steps.length
|
|
7590
|
+
] })
|
|
7591
|
+
] });
|
|
7592
|
+
}
|
|
7593
|
+
function HeaderCards({ steps, current, clickable, onGo }) {
|
|
7594
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "flex gap-2 flex-wrap", children: steps.map((step, i) => {
|
|
7595
|
+
const status = stepStatus(i, current);
|
|
7596
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
|
|
7597
|
+
"button",
|
|
7598
|
+
{
|
|
7599
|
+
type: "button",
|
|
7600
|
+
disabled: !clickable || status === "upcoming",
|
|
7601
|
+
onClick: () => clickable && status !== "upcoming" && onGo(i),
|
|
7602
|
+
className: cn(
|
|
7603
|
+
"flex items-center gap-1.5 rounded-full px-3 py-1.5 text-xs font-medium border transition-all",
|
|
7604
|
+
status === "complete" && "bg-primary/10 border-primary/30 text-primary cursor-pointer",
|
|
7605
|
+
status === "current" && "bg-primary border-primary text-primary-foreground shadow-sm",
|
|
7606
|
+
status === "upcoming" && "bg-muted/40 border-border text-muted-foreground",
|
|
7607
|
+
clickable && status !== "upcoming" && "hover:scale-105"
|
|
7608
|
+
),
|
|
7609
|
+
children: [
|
|
7610
|
+
status === "complete" ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react30.Check, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { children: i + 1 }),
|
|
7611
|
+
step.title,
|
|
7612
|
+
step.optional && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "opacity-60", children: "(opt)" })
|
|
7613
|
+
]
|
|
7614
|
+
},
|
|
7615
|
+
i
|
|
7616
|
+
);
|
|
7617
|
+
}) });
|
|
7618
|
+
}
|
|
7619
|
+
function SidebarNav({ steps, current, clickable, onGo }) {
|
|
7620
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("nav", { className: "flex flex-col gap-0.5 w-48 shrink-0 border-r border-border pr-4 py-1", children: steps.map((step, i) => {
|
|
7621
|
+
const status = stepStatus(i, current);
|
|
7622
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
|
|
7623
|
+
"button",
|
|
7624
|
+
{
|
|
7625
|
+
type: "button",
|
|
7626
|
+
disabled: !clickable || status === "upcoming",
|
|
7627
|
+
onClick: () => clickable && status !== "upcoming" && onGo(i),
|
|
7628
|
+
className: cn(
|
|
7629
|
+
"flex items-center gap-2.5 rounded-lg px-3 py-2.5 text-sm text-left transition-colors w-full",
|
|
7630
|
+
status === "current" && "bg-primary text-primary-foreground",
|
|
7631
|
+
status === "complete" && "text-foreground hover:bg-muted/60 cursor-pointer",
|
|
7632
|
+
status === "upcoming" && "text-muted-foreground"
|
|
7633
|
+
),
|
|
7634
|
+
children: [
|
|
7635
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: cn(
|
|
7636
|
+
"flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-[10px] font-bold border",
|
|
7637
|
+
status === "complete" && "bg-primary/20 border-primary/40 text-primary",
|
|
7638
|
+
status === "current" && "bg-primary-foreground/20 border-primary-foreground/40 text-primary-foreground",
|
|
7639
|
+
status === "upcoming" && "bg-muted border-border text-muted-foreground"
|
|
7640
|
+
), children: status === "complete" ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react30.Check, { className: "h-3 w-3" }) : i + 1 }),
|
|
7641
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("span", { className: "min-w-0", children: [
|
|
7642
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "block truncate font-medium", children: step.title }),
|
|
7643
|
+
step.optional && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "text-[10px] opacity-60", children: "Optional" })
|
|
7644
|
+
] })
|
|
7645
|
+
]
|
|
7646
|
+
},
|
|
7647
|
+
i
|
|
7648
|
+
);
|
|
7649
|
+
}) });
|
|
7650
|
+
}
|
|
7651
|
+
function ProgressBar({ current, total }) {
|
|
7652
|
+
const pct2 = Math.round(current / (total - 1) * 100);
|
|
7653
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "w-full h-1 bg-border rounded-full overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
7654
|
+
"div",
|
|
7655
|
+
{
|
|
7656
|
+
className: "h-full bg-primary transition-all duration-300 rounded-full",
|
|
7657
|
+
style: { width: `${pct2}%` }
|
|
7658
|
+
}
|
|
7659
|
+
) });
|
|
7660
|
+
}
|
|
7661
|
+
function DefaultActions({
|
|
7662
|
+
step,
|
|
7663
|
+
total,
|
|
7664
|
+
onBack,
|
|
7665
|
+
onNext,
|
|
7666
|
+
onClose,
|
|
7667
|
+
isLast,
|
|
7668
|
+
isFirst,
|
|
7669
|
+
backLabel,
|
|
7670
|
+
nextLabel,
|
|
7671
|
+
finishLabel,
|
|
7672
|
+
cancelLabel,
|
|
7673
|
+
showCancel,
|
|
7674
|
+
showBackOnFirst,
|
|
7675
|
+
loading
|
|
7676
|
+
}) {
|
|
7677
|
+
const showBack = !isFirst || showBackOnFirst;
|
|
7678
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex items-center justify-between gap-2 w-full", children: [
|
|
7679
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "flex items-center gap-2", children: showCancel && onClose && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
7680
|
+
"button",
|
|
7681
|
+
{
|
|
7682
|
+
type: "button",
|
|
7683
|
+
onClick: onClose,
|
|
7684
|
+
className: "inline-flex items-center justify-center rounded-md border border-border bg-background px-4 py-2 text-sm font-medium text-foreground hover:bg-accent transition-colors",
|
|
7685
|
+
children: cancelLabel ?? "Cancel"
|
|
7686
|
+
}
|
|
7687
|
+
) }),
|
|
7688
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
7689
|
+
showBack && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
|
|
7690
|
+
"button",
|
|
7691
|
+
{
|
|
7692
|
+
type: "button",
|
|
7693
|
+
onClick: onBack,
|
|
7694
|
+
disabled: isFirst,
|
|
7695
|
+
className: "inline-flex items-center gap-1.5 rounded-md border border-border bg-background px-4 py-2 text-sm font-medium text-foreground hover:bg-accent transition-colors disabled:opacity-40 disabled:pointer-events-none",
|
|
7696
|
+
children: [
|
|
7697
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react30.ChevronLeft, { className: "h-4 w-4" }),
|
|
7698
|
+
backLabel ?? "Back"
|
|
7699
|
+
]
|
|
7700
|
+
}
|
|
7701
|
+
),
|
|
7702
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
7703
|
+
"button",
|
|
7704
|
+
{
|
|
7705
|
+
type: "button",
|
|
7706
|
+
onClick: onNext,
|
|
7707
|
+
disabled: loading,
|
|
7708
|
+
className: "inline-flex items-center gap-1.5 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary-hover transition-colors disabled:opacity-60 disabled:pointer-events-none",
|
|
7709
|
+
children: loading ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("span", { className: "flex items-center gap-1.5", children: [
|
|
7710
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("svg", { className: "animate-spin h-3.5 w-3.5", viewBox: "0 0 24 24", fill: "none", children: [
|
|
7711
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
7712
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8v8z" })
|
|
7713
|
+
] }),
|
|
7714
|
+
"Processing..."
|
|
7715
|
+
] }) : isLast ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_jsx_runtime57.Fragment, { children: [
|
|
7716
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react30.Check, { className: "h-4 w-4" }),
|
|
7717
|
+
finishLabel ?? "Finish"
|
|
7718
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_jsx_runtime57.Fragment, { children: [
|
|
7719
|
+
nextLabel ?? "Next",
|
|
7720
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react30.ChevronRight, { className: "h-4 w-4" })
|
|
7721
|
+
] })
|
|
7722
|
+
}
|
|
7723
|
+
)
|
|
7724
|
+
] })
|
|
7725
|
+
] });
|
|
7726
|
+
}
|
|
7727
|
+
function WizardPanel({
|
|
7728
|
+
steps,
|
|
7729
|
+
current,
|
|
7730
|
+
onGo,
|
|
7731
|
+
variant,
|
|
7732
|
+
size,
|
|
7733
|
+
title,
|
|
7734
|
+
description,
|
|
7735
|
+
hideHeader,
|
|
7736
|
+
footer,
|
|
7737
|
+
renderActions,
|
|
7738
|
+
backLabel,
|
|
7739
|
+
nextLabel,
|
|
7740
|
+
finishLabel,
|
|
7741
|
+
cancelLabel,
|
|
7742
|
+
showCancel,
|
|
7743
|
+
showBackOnFirst,
|
|
7744
|
+
loading,
|
|
7745
|
+
clickableSteps,
|
|
7746
|
+
onBack,
|
|
7747
|
+
onNext,
|
|
7748
|
+
onClose,
|
|
7749
|
+
className,
|
|
7750
|
+
contentClassName
|
|
7751
|
+
}) {
|
|
7752
|
+
const isFirst = current === 0;
|
|
7753
|
+
const isLast = current === steps.length - 1;
|
|
7754
|
+
const isSidebar = variant === "sidebar";
|
|
7755
|
+
const [validationError, setValidationError] = React44.useState(null);
|
|
7756
|
+
const handleNext = () => {
|
|
7757
|
+
const validate = steps[current]?.validate;
|
|
7758
|
+
if (validate) {
|
|
7759
|
+
const result = validate();
|
|
7760
|
+
if (result === false) {
|
|
7761
|
+
setValidationError("Please complete this step before continuing.");
|
|
7762
|
+
return;
|
|
7763
|
+
}
|
|
7764
|
+
if (typeof result === "string") {
|
|
7765
|
+
setValidationError(result);
|
|
7766
|
+
return;
|
|
7767
|
+
}
|
|
7768
|
+
}
|
|
7769
|
+
setValidationError(null);
|
|
7770
|
+
onNext();
|
|
7771
|
+
};
|
|
7772
|
+
const actionProps = {
|
|
7773
|
+
step: current,
|
|
7774
|
+
total: steps.length,
|
|
7775
|
+
onBack,
|
|
7776
|
+
onNext: handleNext,
|
|
7777
|
+
onClose,
|
|
7778
|
+
isFirst,
|
|
7779
|
+
isLast,
|
|
7780
|
+
loading
|
|
7781
|
+
};
|
|
7782
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: cn(
|
|
7783
|
+
"flex flex-col w-full",
|
|
7784
|
+
size && !isSidebar && SIZE_MAP[size ?? "md"],
|
|
7785
|
+
className
|
|
7786
|
+
), children: [
|
|
7787
|
+
!hideHeader && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: cn(
|
|
7788
|
+
"shrink-0 px-6 pt-5 pb-4",
|
|
7789
|
+
variant !== "sidebar" && "border-b border-border"
|
|
7790
|
+
), children: [
|
|
7791
|
+
(title || description) && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "mb-4", children: [
|
|
7792
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("h2", { className: "text-lg font-semibold", children: title }),
|
|
7793
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "text-sm text-muted-foreground mt-0.5", children: description })
|
|
7794
|
+
] }),
|
|
7795
|
+
variant === "default" && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(HeaderDefault, { steps, current, clickable: !!clickableSteps, onGo }),
|
|
7796
|
+
variant === "dots" && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(HeaderDots, { steps, current, clickable: !!clickableSteps, onGo }),
|
|
7797
|
+
variant === "minimal" && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(HeaderMinimal, { steps, current }),
|
|
7798
|
+
variant === "cards" && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(HeaderCards, { steps, current, clickable: !!clickableSteps, onGo }),
|
|
7799
|
+
(variant === "default" || variant === "minimal") && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "mt-3", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ProgressBar, { current, total: steps.length }) })
|
|
7800
|
+
] }),
|
|
7801
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: cn("flex flex-1 min-h-0", isSidebar && "gap-6 px-6 py-5"), children: [
|
|
7802
|
+
isSidebar && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(SidebarNav, { steps, current, clickable: !!clickableSteps, onGo }),
|
|
7803
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: cn(
|
|
7804
|
+
"flex-1 min-w-0",
|
|
7805
|
+
!isSidebar && "px-6 py-5",
|
|
7806
|
+
contentClassName
|
|
7807
|
+
), children: [
|
|
7808
|
+
validationError && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "flex items-center gap-2 rounded-lg border border-danger/30 bg-danger/10 px-3 py-2 text-sm text-danger mb-4", children: [
|
|
7809
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react30.AlertCircle, { className: "h-4 w-4 shrink-0" }),
|
|
7810
|
+
validationError
|
|
7811
|
+
] }),
|
|
7812
|
+
steps[current]?.content
|
|
7132
7813
|
] })
|
|
7814
|
+
] }),
|
|
7815
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "shrink-0 border-t border-border px-6 py-4", children: footer ?? (renderActions ? renderActions(actionProps) : /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
7816
|
+
DefaultActions,
|
|
7817
|
+
{
|
|
7818
|
+
...actionProps,
|
|
7819
|
+
backLabel,
|
|
7820
|
+
nextLabel,
|
|
7821
|
+
finishLabel,
|
|
7822
|
+
cancelLabel,
|
|
7823
|
+
showCancel,
|
|
7824
|
+
showBackOnFirst,
|
|
7825
|
+
loading
|
|
7826
|
+
}
|
|
7827
|
+
)) })
|
|
7828
|
+
] });
|
|
7829
|
+
}
|
|
7830
|
+
function Wizard({
|
|
7831
|
+
steps,
|
|
7832
|
+
step: controlledStep,
|
|
7833
|
+
defaultStep = 0,
|
|
7834
|
+
onStepChange,
|
|
7835
|
+
onFinish,
|
|
7836
|
+
onClose,
|
|
7837
|
+
layout = "inline",
|
|
7838
|
+
variant = "default",
|
|
7839
|
+
size = "md",
|
|
7840
|
+
isOpen = false,
|
|
7841
|
+
showClose = true,
|
|
7842
|
+
unchange = false,
|
|
7843
|
+
title,
|
|
7844
|
+
description,
|
|
7845
|
+
hideHeader = false,
|
|
7846
|
+
footer,
|
|
7847
|
+
renderActions,
|
|
7848
|
+
backLabel,
|
|
7849
|
+
nextLabel,
|
|
7850
|
+
finishLabel,
|
|
7851
|
+
cancelLabel,
|
|
7852
|
+
showCancel = false,
|
|
7853
|
+
showBackOnFirst = false,
|
|
7854
|
+
loading = false,
|
|
7855
|
+
clickableSteps = false,
|
|
7856
|
+
className,
|
|
7857
|
+
contentClassName
|
|
7858
|
+
}) {
|
|
7859
|
+
const [internalStep, setInternalStep] = React44.useState(defaultStep);
|
|
7860
|
+
const current = controlledStep ?? internalStep;
|
|
7861
|
+
const go = (idx) => {
|
|
7862
|
+
const clamped = Math.max(0, Math.min(steps.length - 1, idx));
|
|
7863
|
+
if (controlledStep === void 0) setInternalStep(clamped);
|
|
7864
|
+
onStepChange?.(clamped);
|
|
7865
|
+
};
|
|
7866
|
+
const handleBack = () => go(current - 1);
|
|
7867
|
+
const handleNext = () => {
|
|
7868
|
+
if (current === steps.length - 1) {
|
|
7869
|
+
onFinish?.();
|
|
7870
|
+
return;
|
|
7871
|
+
}
|
|
7872
|
+
go(current + 1);
|
|
7873
|
+
};
|
|
7874
|
+
React44.useEffect(() => {
|
|
7875
|
+
if (layout !== "modal" || !isOpen || unchange) return;
|
|
7876
|
+
const handler = (e) => {
|
|
7877
|
+
if (e.key === "Escape") onClose?.();
|
|
7878
|
+
};
|
|
7879
|
+
window.addEventListener("keydown", handler);
|
|
7880
|
+
return () => window.removeEventListener("keydown", handler);
|
|
7881
|
+
}, [layout, isOpen, unchange, onClose]);
|
|
7882
|
+
const panel = /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
7883
|
+
WizardPanel,
|
|
7884
|
+
{
|
|
7885
|
+
steps,
|
|
7886
|
+
current,
|
|
7887
|
+
onGo: go,
|
|
7888
|
+
onBack: handleBack,
|
|
7889
|
+
onNext: handleNext,
|
|
7890
|
+
onClose,
|
|
7891
|
+
variant,
|
|
7892
|
+
size,
|
|
7893
|
+
title,
|
|
7894
|
+
description,
|
|
7895
|
+
hideHeader,
|
|
7896
|
+
footer,
|
|
7897
|
+
renderActions,
|
|
7898
|
+
backLabel,
|
|
7899
|
+
nextLabel,
|
|
7900
|
+
finishLabel,
|
|
7901
|
+
cancelLabel,
|
|
7902
|
+
showCancel,
|
|
7903
|
+
showBackOnFirst,
|
|
7904
|
+
loading,
|
|
7905
|
+
clickableSteps,
|
|
7906
|
+
contentClassName
|
|
7133
7907
|
}
|
|
7134
7908
|
);
|
|
7909
|
+
if (layout === "modal") {
|
|
7910
|
+
if (!isOpen) return null;
|
|
7911
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4", children: [
|
|
7912
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
7913
|
+
"div",
|
|
7914
|
+
{
|
|
7915
|
+
className: "absolute inset-0 bg-background/80 backdrop-blur-sm",
|
|
7916
|
+
onClick: () => !unchange && onClose?.()
|
|
7917
|
+
}
|
|
7918
|
+
),
|
|
7919
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: cn(
|
|
7920
|
+
"relative z-10 w-full rounded-2xl border border-border bg-background/90 backdrop-blur-xl shadow-2xl overflow-hidden",
|
|
7921
|
+
SIZE_MAP[size],
|
|
7922
|
+
className
|
|
7923
|
+
), children: [
|
|
7924
|
+
showClose && onClose && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
|
|
7925
|
+
"button",
|
|
7926
|
+
{
|
|
7927
|
+
type: "button",
|
|
7928
|
+
onClick: onClose,
|
|
7929
|
+
className: "absolute right-4 top-4 z-10 rounded-sm opacity-60 hover:opacity-100 transition-opacity",
|
|
7930
|
+
children: [
|
|
7931
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react30.X, { className: "h-4 w-4" }),
|
|
7932
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "sr-only", children: "Close" })
|
|
7933
|
+
]
|
|
7934
|
+
}
|
|
7935
|
+
),
|
|
7936
|
+
panel
|
|
7937
|
+
] })
|
|
7938
|
+
] });
|
|
7939
|
+
}
|
|
7940
|
+
if (layout === "page") {
|
|
7941
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: cn("w-full min-h-screen flex items-start justify-center p-6 bg-background", className), children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: cn(
|
|
7942
|
+
"w-full rounded-2xl border border-border bg-card shadow-lg overflow-hidden",
|
|
7943
|
+
SIZE_MAP[size]
|
|
7944
|
+
), children: panel }) });
|
|
7945
|
+
}
|
|
7946
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: cn(
|
|
7947
|
+
"w-full rounded-xl border border-border bg-card shadow-sm overflow-hidden",
|
|
7948
|
+
SIZE_MAP[size],
|
|
7949
|
+
className
|
|
7950
|
+
), children: panel });
|
|
7135
7951
|
}
|
|
7136
7952
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7137
7953
|
0 && (module.exports = {
|
|
@@ -7160,14 +7976,20 @@ function Widget({
|
|
|
7160
7976
|
DateRangePicker,
|
|
7161
7977
|
Drawer,
|
|
7162
7978
|
Dropdown,
|
|
7979
|
+
DropdownItem,
|
|
7980
|
+
DropdownLabel,
|
|
7981
|
+
DropdownSeparator,
|
|
7163
7982
|
FileUpload,
|
|
7983
|
+
FlexItem,
|
|
7164
7984
|
FlexLayout,
|
|
7985
|
+
GridItem,
|
|
7165
7986
|
GridLayout,
|
|
7166
7987
|
GroupNavigation,
|
|
7167
7988
|
Input,
|
|
7168
7989
|
KanbanBoard,
|
|
7169
7990
|
Label,
|
|
7170
7991
|
LeftSidebar,
|
|
7992
|
+
MetricRow,
|
|
7171
7993
|
Modal,
|
|
7172
7994
|
ModalConfirmation,
|
|
7173
7995
|
ModalUnchange,
|
|
@@ -7182,6 +8004,7 @@ function Widget({
|
|
|
7182
8004
|
PanelSidebarItem,
|
|
7183
8005
|
Popover,
|
|
7184
8006
|
Progress,
|
|
8007
|
+
PropsTable,
|
|
7185
8008
|
RadioGroup,
|
|
7186
8009
|
RangeSlider,
|
|
7187
8010
|
Repeater,
|
|
@@ -7191,6 +8014,7 @@ function Widget({
|
|
|
7191
8014
|
ScrollArea,
|
|
7192
8015
|
SectionBlock,
|
|
7193
8016
|
Select,
|
|
8017
|
+
Settings,
|
|
7194
8018
|
Skeleton,
|
|
7195
8019
|
Slider,
|
|
7196
8020
|
StatCard,
|
|
@@ -7208,5 +8032,6 @@ function Widget({
|
|
|
7208
8032
|
Topbar,
|
|
7209
8033
|
TreeView,
|
|
7210
8034
|
Widget,
|
|
8035
|
+
Wizard,
|
|
7211
8036
|
useToast
|
|
7212
8037
|
});
|