@bmsuisse/ui 0.4.5
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/LICENSE +21 -0
- package/README.md +35 -0
- package/dist/index.d.ts +416 -0
- package/dist/index.js +1336 -0
- package/dist/index.js.map +1 -0
- package/package.json +76 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1336 @@
|
|
|
1
|
+
// src/primitives/button.tsx
|
|
2
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
3
|
+
import { cva } from "class-variance-authority";
|
|
4
|
+
import { forwardRef } from "react";
|
|
5
|
+
|
|
6
|
+
// src/lib/utils.ts
|
|
7
|
+
import { clsx } from "clsx";
|
|
8
|
+
import { twMerge } from "tailwind-merge";
|
|
9
|
+
function cn(...inputs) {
|
|
10
|
+
return twMerge(clsx(inputs));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// src/primitives/button.tsx
|
|
14
|
+
import { jsx } from "react/jsx-runtime";
|
|
15
|
+
var buttonVariants = cva(
|
|
16
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
17
|
+
{
|
|
18
|
+
variants: {
|
|
19
|
+
variant: {
|
|
20
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
21
|
+
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
22
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
23
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
24
|
+
secondary: "bg-muted text-muted-foreground hover:bg-muted/80",
|
|
25
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
26
|
+
// "Swiss design" red CTA, ported from akeneo_editor's old .btn-primary-swiss
|
|
27
|
+
// naive-ui override. Relies on --color-swiss-primary/-hover and
|
|
28
|
+
// --color-swiss-primary-foreground tokens defined by the consuming app's own
|
|
29
|
+
// Tailwind theme (this package doesn't define them) — same pattern as AlertBox's
|
|
30
|
+
// warning/info/success colors, which assume tokens the shared theme doesn't have.
|
|
31
|
+
"swiss-primary": "bg-swiss-primary text-swiss-primary-foreground font-semibold shadow-sm hover:bg-swiss-primary-hover hover:-translate-y-px active:translate-y-px",
|
|
32
|
+
"swiss-secondary": "border border-input bg-background font-semibold text-foreground shadow-sm hover:bg-accent hover:-translate-y-px active:translate-y-px"
|
|
33
|
+
},
|
|
34
|
+
size: {
|
|
35
|
+
default: "h-9 px-3",
|
|
36
|
+
xs: "h-7 px-2 text-xs",
|
|
37
|
+
sm: "h-8 px-2 text-xs",
|
|
38
|
+
lg: "h-10 px-4",
|
|
39
|
+
icon: "h-9 w-9",
|
|
40
|
+
"icon-xs": "h-7 w-7",
|
|
41
|
+
"icon-sm": "h-8 w-8",
|
|
42
|
+
"icon-lg": "h-10 w-10"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
defaultVariants: {
|
|
46
|
+
variant: "default",
|
|
47
|
+
size: "default"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
var Button = forwardRef(
|
|
52
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
53
|
+
const Comp = asChild ? Slot : "button";
|
|
54
|
+
return /* @__PURE__ */ jsx(Comp, { className: cn(buttonVariants({ variant, size, className })), ref, ...props });
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
Button.displayName = "Button";
|
|
58
|
+
|
|
59
|
+
// src/primitives/input.tsx
|
|
60
|
+
import { forwardRef as forwardRef2 } from "react";
|
|
61
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
62
|
+
var Input = forwardRef2(({ className, type, ...props }, ref) => {
|
|
63
|
+
return /* @__PURE__ */ jsx2(
|
|
64
|
+
"input",
|
|
65
|
+
{
|
|
66
|
+
type,
|
|
67
|
+
className: cn(
|
|
68
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
|
|
69
|
+
className
|
|
70
|
+
),
|
|
71
|
+
ref,
|
|
72
|
+
...props
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
Input.displayName = "Input";
|
|
77
|
+
|
|
78
|
+
// src/primitives/label.tsx
|
|
79
|
+
import { forwardRef as forwardRef3 } from "react";
|
|
80
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
81
|
+
var Label = forwardRef3(
|
|
82
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx3(
|
|
83
|
+
"label",
|
|
84
|
+
{
|
|
85
|
+
ref,
|
|
86
|
+
className: cn(
|
|
87
|
+
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
|
88
|
+
className
|
|
89
|
+
),
|
|
90
|
+
...props
|
|
91
|
+
}
|
|
92
|
+
)
|
|
93
|
+
);
|
|
94
|
+
Label.displayName = "Label";
|
|
95
|
+
|
|
96
|
+
// src/primitives/textarea.tsx
|
|
97
|
+
import { forwardRef as forwardRef4 } from "react";
|
|
98
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
99
|
+
var Textarea = forwardRef4(
|
|
100
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx4(
|
|
101
|
+
"textarea",
|
|
102
|
+
{
|
|
103
|
+
className: cn(
|
|
104
|
+
"flex min-h-16 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
|
|
105
|
+
className
|
|
106
|
+
),
|
|
107
|
+
ref,
|
|
108
|
+
...props
|
|
109
|
+
}
|
|
110
|
+
)
|
|
111
|
+
);
|
|
112
|
+
Textarea.displayName = "Textarea";
|
|
113
|
+
|
|
114
|
+
// src/primitives/card.tsx
|
|
115
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
116
|
+
var Card = ({ className, ...props }) => /* @__PURE__ */ jsx5("div", { className: cn("rounded-lg border bg-background text-foreground shadow-sm", className), ...props });
|
|
117
|
+
var CardHeader = ({
|
|
118
|
+
className,
|
|
119
|
+
...props
|
|
120
|
+
}) => /* @__PURE__ */ jsx5("div", { className: cn("flex flex-col gap-1.5 p-6", className), ...props });
|
|
121
|
+
var CardTitle = ({ className, ...props }) => /* @__PURE__ */ jsx5("div", { className: cn("text-lg font-semibold leading-none tracking-tight", className), ...props });
|
|
122
|
+
var CardDescription = ({
|
|
123
|
+
className,
|
|
124
|
+
...props
|
|
125
|
+
}) => /* @__PURE__ */ jsx5("div", { className: cn("text-sm text-muted-foreground", className), ...props });
|
|
126
|
+
var CardContent = ({
|
|
127
|
+
className,
|
|
128
|
+
...props
|
|
129
|
+
}) => /* @__PURE__ */ jsx5("div", { className: cn("p-6 pt-0", className), ...props });
|
|
130
|
+
var CardFooter = ({
|
|
131
|
+
className,
|
|
132
|
+
...props
|
|
133
|
+
}) => /* @__PURE__ */ jsx5("div", { className: cn("flex items-center gap-2 p-6 pt-0", className), ...props });
|
|
134
|
+
|
|
135
|
+
// src/primitives/badge.tsx
|
|
136
|
+
import { cva as cva2 } from "class-variance-authority";
|
|
137
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
138
|
+
var badgeVariants = cva2(
|
|
139
|
+
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-ring",
|
|
140
|
+
{
|
|
141
|
+
variants: {
|
|
142
|
+
variant: {
|
|
143
|
+
default: "border-transparent bg-primary text-primary-foreground",
|
|
144
|
+
secondary: "border-transparent bg-muted text-muted-foreground",
|
|
145
|
+
destructive: "border-transparent bg-destructive text-destructive-foreground",
|
|
146
|
+
outline: "border-input text-foreground",
|
|
147
|
+
// Amber warning tone — same fixed-palette choice as AlertBox/StatusBadge's
|
|
148
|
+
// warning tone, since the shared theme has no warning token yet.
|
|
149
|
+
warning: "border-transparent bg-amber-100 text-amber-900 dark:bg-amber-900/40 dark:text-amber-200"
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
defaultVariants: {
|
|
153
|
+
variant: "default"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
var Badge = ({ className, variant, ...props }) => /* @__PURE__ */ jsx6("div", { className: cn(badgeVariants({ variant }), className), ...props });
|
|
158
|
+
|
|
159
|
+
// src/primitives/dialog.tsx
|
|
160
|
+
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
161
|
+
import { X } from "lucide-react";
|
|
162
|
+
import { forwardRef as forwardRef5 } from "react";
|
|
163
|
+
import { jsx as jsx7, jsxs } from "react/jsx-runtime";
|
|
164
|
+
var Dialog = DialogPrimitive.Root;
|
|
165
|
+
var DialogTrigger = DialogPrimitive.Trigger;
|
|
166
|
+
var DialogOverlay = forwardRef5(({ className, ...props }, ref) => /* @__PURE__ */ jsx7(
|
|
167
|
+
DialogPrimitive.Overlay,
|
|
168
|
+
{
|
|
169
|
+
ref,
|
|
170
|
+
className: cn("fixed inset-0 z-50 bg-black/50", className),
|
|
171
|
+
...props
|
|
172
|
+
}
|
|
173
|
+
));
|
|
174
|
+
DialogOverlay.displayName = "DialogOverlay";
|
|
175
|
+
var DialogContent = forwardRef5(({ className, children, showCloseButton = true, closeButtonTestId, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [
|
|
176
|
+
/* @__PURE__ */ jsx7(DialogOverlay, {}),
|
|
177
|
+
/* @__PURE__ */ jsxs(
|
|
178
|
+
DialogPrimitive.Content,
|
|
179
|
+
{
|
|
180
|
+
ref,
|
|
181
|
+
className: cn(
|
|
182
|
+
"fixed left-1/2 top-1/2 z-50 max-h-[85vh] w-full max-w-md -translate-x-1/2 -translate-y-1/2 overflow-y-auto rounded-lg border bg-background p-6 shadow-lg",
|
|
183
|
+
className
|
|
184
|
+
),
|
|
185
|
+
...props,
|
|
186
|
+
children: [
|
|
187
|
+
children,
|
|
188
|
+
showCloseButton ? /* @__PURE__ */ jsxs(
|
|
189
|
+
DialogPrimitive.Close,
|
|
190
|
+
{
|
|
191
|
+
"data-testid": closeButtonTestId,
|
|
192
|
+
className: "absolute right-4 top-4 rounded-sm opacity-70 hover:opacity-100",
|
|
193
|
+
children: [
|
|
194
|
+
/* @__PURE__ */ jsx7(X, { className: "h-4 w-4" }),
|
|
195
|
+
/* @__PURE__ */ jsx7("span", { className: "sr-only", children: "Close" })
|
|
196
|
+
]
|
|
197
|
+
}
|
|
198
|
+
) : null
|
|
199
|
+
]
|
|
200
|
+
}
|
|
201
|
+
)
|
|
202
|
+
] }));
|
|
203
|
+
DialogContent.displayName = "DialogContent";
|
|
204
|
+
var DialogHeader = ({
|
|
205
|
+
className,
|
|
206
|
+
...props
|
|
207
|
+
}) => /* @__PURE__ */ jsx7("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
208
|
+
var DialogTitle = forwardRef5(({ className, ...props }, ref) => /* @__PURE__ */ jsx7(DialogPrimitive.Title, { ref, className: cn("text-lg font-semibold", className), ...props }));
|
|
209
|
+
DialogTitle.displayName = "DialogTitle";
|
|
210
|
+
var DialogDescription = forwardRef5(({ className, ...props }, ref) => /* @__PURE__ */ jsx7(
|
|
211
|
+
DialogPrimitive.Description,
|
|
212
|
+
{
|
|
213
|
+
ref,
|
|
214
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
215
|
+
...props
|
|
216
|
+
}
|
|
217
|
+
));
|
|
218
|
+
DialogDescription.displayName = "DialogDescription";
|
|
219
|
+
var DialogFooter = ({
|
|
220
|
+
className,
|
|
221
|
+
...props
|
|
222
|
+
}) => /* @__PURE__ */ jsx7("div", { className: cn("flex justify-end gap-2", className), ...props });
|
|
223
|
+
|
|
224
|
+
// src/primitives/popover.tsx
|
|
225
|
+
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
226
|
+
import { forwardRef as forwardRef6 } from "react";
|
|
227
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
228
|
+
var Popover = PopoverPrimitive.Root;
|
|
229
|
+
var PopoverTrigger = PopoverPrimitive.Trigger;
|
|
230
|
+
var PopoverAnchor = PopoverPrimitive.Anchor;
|
|
231
|
+
var PopoverContent = forwardRef6(({ className, align = "start", sideOffset = 4, container, ...props }, ref) => /* @__PURE__ */ jsx8(PopoverPrimitive.Portal, { container, children: /* @__PURE__ */ jsx8(
|
|
232
|
+
PopoverPrimitive.Content,
|
|
233
|
+
{
|
|
234
|
+
ref,
|
|
235
|
+
align,
|
|
236
|
+
sideOffset,
|
|
237
|
+
className: cn(
|
|
238
|
+
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none",
|
|
239
|
+
className
|
|
240
|
+
),
|
|
241
|
+
...props
|
|
242
|
+
}
|
|
243
|
+
) }));
|
|
244
|
+
PopoverContent.displayName = "PopoverContent";
|
|
245
|
+
|
|
246
|
+
// src/primitives/select.tsx
|
|
247
|
+
import * as SelectPrimitive from "@radix-ui/react-select";
|
|
248
|
+
import { Check, ChevronDown } from "lucide-react";
|
|
249
|
+
import { forwardRef as forwardRef7 } from "react";
|
|
250
|
+
import { jsx as jsx9, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
251
|
+
var Select = SelectPrimitive.Root;
|
|
252
|
+
var SelectGroup = SelectPrimitive.Group;
|
|
253
|
+
var SelectValue = SelectPrimitive.Value;
|
|
254
|
+
var SelectTrigger = forwardRef7(
|
|
255
|
+
({ className, children, size = "default", ...props }, ref) => /* @__PURE__ */ jsxs2(
|
|
256
|
+
SelectPrimitive.Trigger,
|
|
257
|
+
{
|
|
258
|
+
ref,
|
|
259
|
+
className: cn(
|
|
260
|
+
"flex w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
|
|
261
|
+
size === "sm" ? "h-8" : "h-9",
|
|
262
|
+
className
|
|
263
|
+
),
|
|
264
|
+
...props,
|
|
265
|
+
children: [
|
|
266
|
+
children,
|
|
267
|
+
/* @__PURE__ */ jsx9(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx9(ChevronDown, { className: "h-4 w-4 opacity-50" }) })
|
|
268
|
+
]
|
|
269
|
+
}
|
|
270
|
+
)
|
|
271
|
+
);
|
|
272
|
+
SelectTrigger.displayName = "SelectTrigger";
|
|
273
|
+
var SelectContent = forwardRef7(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx9(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsx9(
|
|
274
|
+
SelectPrimitive.Content,
|
|
275
|
+
{
|
|
276
|
+
ref,
|
|
277
|
+
position,
|
|
278
|
+
className: cn(
|
|
279
|
+
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md",
|
|
280
|
+
position === "popper" && "translate-y-1",
|
|
281
|
+
className
|
|
282
|
+
),
|
|
283
|
+
...props,
|
|
284
|
+
children: /* @__PURE__ */ jsx9(SelectPrimitive.Viewport, { className: "p-1", children })
|
|
285
|
+
}
|
|
286
|
+
) }));
|
|
287
|
+
SelectContent.displayName = "SelectContent";
|
|
288
|
+
var SelectItem = forwardRef7(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs2(
|
|
289
|
+
SelectPrimitive.Item,
|
|
290
|
+
{
|
|
291
|
+
ref,
|
|
292
|
+
className: cn(
|
|
293
|
+
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
294
|
+
className
|
|
295
|
+
),
|
|
296
|
+
...props,
|
|
297
|
+
children: [
|
|
298
|
+
/* @__PURE__ */ jsx9("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx9(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx9(Check, { className: "h-4 w-4" }) }) }),
|
|
299
|
+
/* @__PURE__ */ jsx9(SelectPrimitive.ItemText, { children })
|
|
300
|
+
]
|
|
301
|
+
}
|
|
302
|
+
));
|
|
303
|
+
SelectItem.displayName = "SelectItem";
|
|
304
|
+
|
|
305
|
+
// src/primitives/skeleton.tsx
|
|
306
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
307
|
+
var Skeleton = ({ className, ...props }) => /* @__PURE__ */ jsx10("div", { className: cn("animate-pulse rounded-md bg-muted", className), ...props });
|
|
308
|
+
|
|
309
|
+
// src/primitives/checkbox.tsx
|
|
310
|
+
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
|
|
311
|
+
import { Check as Check2 } from "lucide-react";
|
|
312
|
+
import { forwardRef as forwardRef8 } from "react";
|
|
313
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
314
|
+
var Checkbox = forwardRef8(({ className, ...props }, ref) => /* @__PURE__ */ jsx11(
|
|
315
|
+
CheckboxPrimitive.Root,
|
|
316
|
+
{
|
|
317
|
+
ref,
|
|
318
|
+
className: cn(
|
|
319
|
+
"peer h-4 w-4 shrink-0 rounded-sm border border-input shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary",
|
|
320
|
+
className
|
|
321
|
+
),
|
|
322
|
+
...props,
|
|
323
|
+
children: /* @__PURE__ */ jsx11(CheckboxPrimitive.Indicator, { className: "flex items-center justify-center text-current", children: /* @__PURE__ */ jsx11(Check2, { className: "h-3.5 w-3.5" }) })
|
|
324
|
+
}
|
|
325
|
+
));
|
|
326
|
+
Checkbox.displayName = "Checkbox";
|
|
327
|
+
|
|
328
|
+
// src/primitives/switch.tsx
|
|
329
|
+
import * as SwitchPrimitive from "@radix-ui/react-switch";
|
|
330
|
+
import { forwardRef as forwardRef9 } from "react";
|
|
331
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
332
|
+
var Switch = forwardRef9(
|
|
333
|
+
({ className, size = "default", ...props }, ref) => /* @__PURE__ */ jsx12(
|
|
334
|
+
SwitchPrimitive.Root,
|
|
335
|
+
{
|
|
336
|
+
ref,
|
|
337
|
+
className: cn(
|
|
338
|
+
"peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
|
|
339
|
+
size === "sm" ? "h-3.5 w-6" : "h-5 w-9",
|
|
340
|
+
className
|
|
341
|
+
),
|
|
342
|
+
...props,
|
|
343
|
+
children: /* @__PURE__ */ jsx12(
|
|
344
|
+
SwitchPrimitive.Thumb,
|
|
345
|
+
{
|
|
346
|
+
className: cn(
|
|
347
|
+
"pointer-events-none block rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=unchecked]:translate-x-0",
|
|
348
|
+
size === "sm" ? "h-3 w-3 data-[state=checked]:translate-x-2.5" : "h-4 w-4 data-[state=checked]:translate-x-4"
|
|
349
|
+
)
|
|
350
|
+
}
|
|
351
|
+
)
|
|
352
|
+
}
|
|
353
|
+
)
|
|
354
|
+
);
|
|
355
|
+
Switch.displayName = "Switch";
|
|
356
|
+
|
|
357
|
+
// src/primitives/tabs.tsx
|
|
358
|
+
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
359
|
+
import { forwardRef as forwardRef10 } from "react";
|
|
360
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
361
|
+
var Tabs = TabsPrimitive.Root;
|
|
362
|
+
var TabsList = forwardRef10(({ className, ...props }, ref) => /* @__PURE__ */ jsx13(
|
|
363
|
+
TabsPrimitive.List,
|
|
364
|
+
{
|
|
365
|
+
ref,
|
|
366
|
+
className: cn(
|
|
367
|
+
"inline-flex h-9 w-fit items-center justify-center rounded-lg bg-muted p-[3px] text-muted-foreground",
|
|
368
|
+
className
|
|
369
|
+
),
|
|
370
|
+
...props
|
|
371
|
+
}
|
|
372
|
+
));
|
|
373
|
+
TabsList.displayName = "TabsList";
|
|
374
|
+
var TabsTrigger = forwardRef10(({ className, ...props }, ref) => /* @__PURE__ */ jsx13(
|
|
375
|
+
TabsPrimitive.Trigger,
|
|
376
|
+
{
|
|
377
|
+
ref,
|
|
378
|
+
className: cn(
|
|
379
|
+
"inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-2 py-1 text-sm font-medium text-foreground/60 transition-all hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
|
|
380
|
+
className
|
|
381
|
+
),
|
|
382
|
+
...props
|
|
383
|
+
}
|
|
384
|
+
));
|
|
385
|
+
TabsTrigger.displayName = "TabsTrigger";
|
|
386
|
+
var TabsContent = forwardRef10(({ className, ...props }, ref) => /* @__PURE__ */ jsx13(TabsPrimitive.Content, { ref, className: cn("flex-1 outline-none", className), ...props }));
|
|
387
|
+
TabsContent.displayName = "TabsContent";
|
|
388
|
+
|
|
389
|
+
// src/primitives/separator.tsx
|
|
390
|
+
import * as SeparatorPrimitive from "@radix-ui/react-separator";
|
|
391
|
+
import { forwardRef as forwardRef11 } from "react";
|
|
392
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
393
|
+
var Separator = forwardRef11(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => /* @__PURE__ */ jsx14(
|
|
394
|
+
SeparatorPrimitive.Root,
|
|
395
|
+
{
|
|
396
|
+
ref,
|
|
397
|
+
decorative,
|
|
398
|
+
orientation,
|
|
399
|
+
className: cn(
|
|
400
|
+
"shrink-0 bg-border",
|
|
401
|
+
orientation === "horizontal" ? "h-px w-full" : "h-full w-px",
|
|
402
|
+
className
|
|
403
|
+
),
|
|
404
|
+
...props
|
|
405
|
+
}
|
|
406
|
+
));
|
|
407
|
+
Separator.displayName = "Separator";
|
|
408
|
+
|
|
409
|
+
// src/primitives/scroll-area.tsx
|
|
410
|
+
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
|
411
|
+
import { forwardRef as forwardRef12 } from "react";
|
|
412
|
+
import { jsx as jsx15, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
413
|
+
var ScrollBar = forwardRef12(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ jsx15(
|
|
414
|
+
ScrollAreaPrimitive.ScrollAreaScrollbar,
|
|
415
|
+
{
|
|
416
|
+
ref,
|
|
417
|
+
orientation,
|
|
418
|
+
className: cn(
|
|
419
|
+
"flex touch-none select-none transition-colors",
|
|
420
|
+
orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent p-[1px]",
|
|
421
|
+
orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent p-[1px]",
|
|
422
|
+
className
|
|
423
|
+
),
|
|
424
|
+
...props,
|
|
425
|
+
children: /* @__PURE__ */ jsx15(ScrollAreaPrimitive.ScrollAreaThumb, { className: "relative flex-1 rounded-full bg-border" })
|
|
426
|
+
}
|
|
427
|
+
));
|
|
428
|
+
ScrollBar.displayName = "ScrollBar";
|
|
429
|
+
var ScrollArea = forwardRef12(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs3(ScrollAreaPrimitive.Root, { ref, className: cn("relative overflow-hidden", className), ...props, children: [
|
|
430
|
+
/* @__PURE__ */ jsx15(ScrollAreaPrimitive.Viewport, { className: "h-full w-full rounded-[inherit]", children }),
|
|
431
|
+
/* @__PURE__ */ jsx15(ScrollBar, {}),
|
|
432
|
+
/* @__PURE__ */ jsx15(ScrollAreaPrimitive.Corner, {})
|
|
433
|
+
] }));
|
|
434
|
+
ScrollArea.displayName = "ScrollArea";
|
|
435
|
+
|
|
436
|
+
// src/primitives/table.tsx
|
|
437
|
+
import { forwardRef as forwardRef13 } from "react";
|
|
438
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
439
|
+
var Table = forwardRef13(
|
|
440
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx16("div", { className: "relative w-full overflow-x-auto", children: /* @__PURE__ */ jsx16("table", { ref, className: cn("w-full caption-bottom text-sm", className), ...props }) })
|
|
441
|
+
);
|
|
442
|
+
Table.displayName = "Table";
|
|
443
|
+
var TableHeader = forwardRef13(
|
|
444
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx16("thead", { ref, className: cn("[&_tr]:border-b", className), ...props })
|
|
445
|
+
);
|
|
446
|
+
TableHeader.displayName = "TableHeader";
|
|
447
|
+
var TableBody = forwardRef13(
|
|
448
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx16("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props })
|
|
449
|
+
);
|
|
450
|
+
TableBody.displayName = "TableBody";
|
|
451
|
+
var TableFooter = forwardRef13(
|
|
452
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx16(
|
|
453
|
+
"tfoot",
|
|
454
|
+
{
|
|
455
|
+
ref,
|
|
456
|
+
className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className),
|
|
457
|
+
...props
|
|
458
|
+
}
|
|
459
|
+
)
|
|
460
|
+
);
|
|
461
|
+
TableFooter.displayName = "TableFooter";
|
|
462
|
+
var TableRow = forwardRef13(
|
|
463
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx16(
|
|
464
|
+
"tr",
|
|
465
|
+
{
|
|
466
|
+
ref,
|
|
467
|
+
className: cn("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted", className),
|
|
468
|
+
...props
|
|
469
|
+
}
|
|
470
|
+
)
|
|
471
|
+
);
|
|
472
|
+
TableRow.displayName = "TableRow";
|
|
473
|
+
var TableHead = forwardRef13(
|
|
474
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx16(
|
|
475
|
+
"th",
|
|
476
|
+
{
|
|
477
|
+
ref,
|
|
478
|
+
className: cn(
|
|
479
|
+
"h-10 whitespace-nowrap px-2 text-left align-middle font-medium text-foreground [&:has([role=checkbox])]:pr-0",
|
|
480
|
+
className
|
|
481
|
+
),
|
|
482
|
+
...props
|
|
483
|
+
}
|
|
484
|
+
)
|
|
485
|
+
);
|
|
486
|
+
TableHead.displayName = "TableHead";
|
|
487
|
+
var TableCell = forwardRef13(
|
|
488
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx16(
|
|
489
|
+
"td",
|
|
490
|
+
{
|
|
491
|
+
ref,
|
|
492
|
+
className: cn("whitespace-nowrap p-2 align-middle [&:has([role=checkbox])]:pr-0", className),
|
|
493
|
+
...props
|
|
494
|
+
}
|
|
495
|
+
)
|
|
496
|
+
);
|
|
497
|
+
TableCell.displayName = "TableCell";
|
|
498
|
+
var TableCaption = forwardRef13(
|
|
499
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsx16("caption", { ref, className: cn("mt-4 text-sm text-muted-foreground", className), ...props })
|
|
500
|
+
);
|
|
501
|
+
TableCaption.displayName = "TableCaption";
|
|
502
|
+
|
|
503
|
+
// src/primitives/dropdown-menu.tsx
|
|
504
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
505
|
+
import { Check as Check3, ChevronRight, Circle } from "lucide-react";
|
|
506
|
+
import { forwardRef as forwardRef14 } from "react";
|
|
507
|
+
import { jsx as jsx17, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
508
|
+
var DropdownMenu = DropdownMenuPrimitive.Root;
|
|
509
|
+
var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
|
510
|
+
var DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
|
511
|
+
var DropdownMenuPortal = DropdownMenuPrimitive.Portal;
|
|
512
|
+
var DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
|
513
|
+
var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
|
514
|
+
var DropdownMenuContent = forwardRef14(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx17(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx17(
|
|
515
|
+
DropdownMenuPrimitive.Content,
|
|
516
|
+
{
|
|
517
|
+
ref,
|
|
518
|
+
sideOffset,
|
|
519
|
+
className: cn(
|
|
520
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md",
|
|
521
|
+
className
|
|
522
|
+
),
|
|
523
|
+
...props
|
|
524
|
+
}
|
|
525
|
+
) }));
|
|
526
|
+
DropdownMenuContent.displayName = "DropdownMenuContent";
|
|
527
|
+
var DropdownMenuItem = forwardRef14(({ className, danger, ...props }, ref) => /* @__PURE__ */ jsx17(
|
|
528
|
+
DropdownMenuPrimitive.Item,
|
|
529
|
+
{
|
|
530
|
+
ref,
|
|
531
|
+
className: cn(
|
|
532
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
533
|
+
danger && "text-destructive focus:bg-destructive/10 focus:text-destructive",
|
|
534
|
+
className
|
|
535
|
+
),
|
|
536
|
+
...props
|
|
537
|
+
}
|
|
538
|
+
));
|
|
539
|
+
DropdownMenuItem.displayName = "DropdownMenuItem";
|
|
540
|
+
var DropdownMenuCheckboxItem = forwardRef14(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs4(
|
|
541
|
+
DropdownMenuPrimitive.CheckboxItem,
|
|
542
|
+
{
|
|
543
|
+
ref,
|
|
544
|
+
checked,
|
|
545
|
+
className: cn(
|
|
546
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
547
|
+
className
|
|
548
|
+
),
|
|
549
|
+
...props,
|
|
550
|
+
children: [
|
|
551
|
+
/* @__PURE__ */ jsx17("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx17(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx17(Check3, { className: "h-4 w-4" }) }) }),
|
|
552
|
+
children
|
|
553
|
+
]
|
|
554
|
+
}
|
|
555
|
+
));
|
|
556
|
+
DropdownMenuCheckboxItem.displayName = "DropdownMenuCheckboxItem";
|
|
557
|
+
var DropdownMenuRadioItem = forwardRef14(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs4(
|
|
558
|
+
DropdownMenuPrimitive.RadioItem,
|
|
559
|
+
{
|
|
560
|
+
ref,
|
|
561
|
+
className: cn(
|
|
562
|
+
"relative flex cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
563
|
+
className
|
|
564
|
+
),
|
|
565
|
+
...props,
|
|
566
|
+
children: [
|
|
567
|
+
/* @__PURE__ */ jsx17("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx17(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx17(Circle, { className: "h-2 w-2 fill-current" }) }) }),
|
|
568
|
+
children
|
|
569
|
+
]
|
|
570
|
+
}
|
|
571
|
+
));
|
|
572
|
+
DropdownMenuRadioItem.displayName = "DropdownMenuRadioItem";
|
|
573
|
+
var DropdownMenuSeparator = forwardRef14(({ className, ...props }, ref) => /* @__PURE__ */ jsx17(
|
|
574
|
+
DropdownMenuPrimitive.Separator,
|
|
575
|
+
{
|
|
576
|
+
ref,
|
|
577
|
+
className: cn("-mx-1 my-1 h-px bg-muted", className),
|
|
578
|
+
...props
|
|
579
|
+
}
|
|
580
|
+
));
|
|
581
|
+
DropdownMenuSeparator.displayName = "DropdownMenuSeparator";
|
|
582
|
+
var DropdownMenuLabel = forwardRef14(({ className, ...props }, ref) => /* @__PURE__ */ jsx17(
|
|
583
|
+
DropdownMenuPrimitive.Label,
|
|
584
|
+
{
|
|
585
|
+
ref,
|
|
586
|
+
className: cn("px-2 py-1.5 text-xs font-medium text-muted-foreground", className),
|
|
587
|
+
...props
|
|
588
|
+
}
|
|
589
|
+
));
|
|
590
|
+
DropdownMenuLabel.displayName = "DropdownMenuLabel";
|
|
591
|
+
var DropdownMenuShortcut = ({
|
|
592
|
+
className,
|
|
593
|
+
...props
|
|
594
|
+
}) => /* @__PURE__ */ jsx17("span", { className: cn("ml-auto text-xs tracking-widest text-muted-foreground", className), ...props });
|
|
595
|
+
var DropdownMenuSubTrigger = forwardRef14(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs4(
|
|
596
|
+
DropdownMenuPrimitive.SubTrigger,
|
|
597
|
+
{
|
|
598
|
+
ref,
|
|
599
|
+
className: cn(
|
|
600
|
+
"flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
|
|
601
|
+
className
|
|
602
|
+
),
|
|
603
|
+
...props,
|
|
604
|
+
children: [
|
|
605
|
+
children,
|
|
606
|
+
/* @__PURE__ */ jsx17(ChevronRight, { className: "ml-auto h-4 w-4" })
|
|
607
|
+
]
|
|
608
|
+
}
|
|
609
|
+
));
|
|
610
|
+
DropdownMenuSubTrigger.displayName = "DropdownMenuSubTrigger";
|
|
611
|
+
var DropdownMenuSubContent = forwardRef14(({ className, ...props }, ref) => /* @__PURE__ */ jsx17(
|
|
612
|
+
DropdownMenuPrimitive.SubContent,
|
|
613
|
+
{
|
|
614
|
+
ref,
|
|
615
|
+
className: cn(
|
|
616
|
+
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md",
|
|
617
|
+
className
|
|
618
|
+
),
|
|
619
|
+
...props
|
|
620
|
+
}
|
|
621
|
+
));
|
|
622
|
+
DropdownMenuSubContent.displayName = "DropdownMenuSubContent";
|
|
623
|
+
|
|
624
|
+
// src/primitives/sheet.tsx
|
|
625
|
+
import { cva as cva3 } from "class-variance-authority";
|
|
626
|
+
import * as DialogPrimitive2 from "@radix-ui/react-dialog";
|
|
627
|
+
import { X as X2 } from "lucide-react";
|
|
628
|
+
import { forwardRef as forwardRef15 } from "react";
|
|
629
|
+
import { jsx as jsx18, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
630
|
+
var Sheet = DialogPrimitive2.Root;
|
|
631
|
+
var SheetTrigger = DialogPrimitive2.Trigger;
|
|
632
|
+
var SheetClose = DialogPrimitive2.Close;
|
|
633
|
+
var SheetPortal = DialogPrimitive2.Portal;
|
|
634
|
+
var SheetOverlay = forwardRef15(({ className, ...props }, ref) => /* @__PURE__ */ jsx18(
|
|
635
|
+
DialogPrimitive2.Overlay,
|
|
636
|
+
{
|
|
637
|
+
ref,
|
|
638
|
+
className: cn("fixed inset-0 z-50 bg-black/50", className),
|
|
639
|
+
...props
|
|
640
|
+
}
|
|
641
|
+
));
|
|
642
|
+
SheetOverlay.displayName = "SheetOverlay";
|
|
643
|
+
var sheetVariants = cva3(
|
|
644
|
+
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition-transform duration-300 ease-in-out",
|
|
645
|
+
{
|
|
646
|
+
variants: {
|
|
647
|
+
side: {
|
|
648
|
+
top: "inset-x-0 top-0 border-b data-[state=closed]:-translate-y-full data-[state=open]:translate-y-0",
|
|
649
|
+
bottom: "inset-x-0 bottom-0 border-t data-[state=closed]:translate-y-full data-[state=open]:translate-y-0",
|
|
650
|
+
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:-translate-x-full data-[state=open]:translate-x-0 sm:max-w-sm",
|
|
651
|
+
right: "inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:translate-x-full data-[state=open]:translate-x-0 sm:max-w-sm"
|
|
652
|
+
}
|
|
653
|
+
},
|
|
654
|
+
defaultVariants: {
|
|
655
|
+
side: "right"
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
);
|
|
659
|
+
var SheetContent = forwardRef15(
|
|
660
|
+
({ side = "right", className, children, ...props }, ref) => /* @__PURE__ */ jsxs5(SheetPortal, { children: [
|
|
661
|
+
/* @__PURE__ */ jsx18(SheetOverlay, {}),
|
|
662
|
+
/* @__PURE__ */ jsxs5(DialogPrimitive2.Content, { ref, className: cn(sheetVariants({ side }), className), ...props, children: [
|
|
663
|
+
children,
|
|
664
|
+
/* @__PURE__ */ jsxs5(DialogPrimitive2.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 hover:opacity-100", children: [
|
|
665
|
+
/* @__PURE__ */ jsx18(X2, { className: "h-4 w-4" }),
|
|
666
|
+
/* @__PURE__ */ jsx18("span", { className: "sr-only", children: "Close" })
|
|
667
|
+
] })
|
|
668
|
+
] })
|
|
669
|
+
] })
|
|
670
|
+
);
|
|
671
|
+
SheetContent.displayName = "SheetContent";
|
|
672
|
+
var SheetHeader = ({
|
|
673
|
+
className,
|
|
674
|
+
...props
|
|
675
|
+
}) => /* @__PURE__ */ jsx18("div", { className: cn("flex flex-col gap-1.5", className), ...props });
|
|
676
|
+
var SheetFooter = ({
|
|
677
|
+
className,
|
|
678
|
+
...props
|
|
679
|
+
}) => /* @__PURE__ */ jsx18("div", { className: cn("flex justify-end gap-2", className), ...props });
|
|
680
|
+
var SheetTitle = forwardRef15(({ className, ...props }, ref) => /* @__PURE__ */ jsx18(DialogPrimitive2.Title, { ref, className: cn("text-lg font-semibold", className), ...props }));
|
|
681
|
+
SheetTitle.displayName = "SheetTitle";
|
|
682
|
+
var SheetDescription = forwardRef15(({ className, ...props }, ref) => /* @__PURE__ */ jsx18(
|
|
683
|
+
DialogPrimitive2.Description,
|
|
684
|
+
{
|
|
685
|
+
ref,
|
|
686
|
+
className: cn("text-sm text-muted-foreground", className),
|
|
687
|
+
...props
|
|
688
|
+
}
|
|
689
|
+
));
|
|
690
|
+
SheetDescription.displayName = "SheetDescription";
|
|
691
|
+
|
|
692
|
+
// src/primitives/tooltip.tsx
|
|
693
|
+
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
|
|
694
|
+
import { forwardRef as forwardRef16 } from "react";
|
|
695
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
696
|
+
var TooltipProvider = TooltipPrimitive.Provider;
|
|
697
|
+
var Tooltip = TooltipPrimitive.Root;
|
|
698
|
+
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
699
|
+
var TooltipContent = forwardRef16(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx19(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsx19(
|
|
700
|
+
TooltipPrimitive.Content,
|
|
701
|
+
{
|
|
702
|
+
ref,
|
|
703
|
+
sideOffset,
|
|
704
|
+
className: cn(
|
|
705
|
+
"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-xs text-popover-foreground shadow-md",
|
|
706
|
+
className
|
|
707
|
+
),
|
|
708
|
+
...props
|
|
709
|
+
}
|
|
710
|
+
) }));
|
|
711
|
+
TooltipContent.displayName = "TooltipContent";
|
|
712
|
+
|
|
713
|
+
// src/patterns/modal/Modal.tsx
|
|
714
|
+
import { jsx as jsx20, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
715
|
+
var Modal = ({
|
|
716
|
+
open,
|
|
717
|
+
onOpenChange,
|
|
718
|
+
title,
|
|
719
|
+
description,
|
|
720
|
+
children,
|
|
721
|
+
footer,
|
|
722
|
+
className
|
|
723
|
+
}) => /* @__PURE__ */ jsx20(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs6(DialogContent, { className, children: [
|
|
724
|
+
/* @__PURE__ */ jsxs6(DialogHeader, { children: [
|
|
725
|
+
/* @__PURE__ */ jsx20(DialogTitle, { children: title }),
|
|
726
|
+
description ? /* @__PURE__ */ jsx20(DialogDescription, { children: description }) : null
|
|
727
|
+
] }),
|
|
728
|
+
children,
|
|
729
|
+
footer ? /* @__PURE__ */ jsx20(DialogFooter, { children: footer }) : null
|
|
730
|
+
] }) });
|
|
731
|
+
|
|
732
|
+
// src/patterns/modal/ConfirmDialog.tsx
|
|
733
|
+
import { useState } from "react";
|
|
734
|
+
import { Fragment, jsx as jsx21, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
735
|
+
var ConfirmDialog = ({
|
|
736
|
+
open,
|
|
737
|
+
onOpenChange,
|
|
738
|
+
title,
|
|
739
|
+
description,
|
|
740
|
+
confirmLabel = "Confirm",
|
|
741
|
+
cancelLabel = "Cancel",
|
|
742
|
+
onConfirm,
|
|
743
|
+
variant = "default",
|
|
744
|
+
confirmTestId,
|
|
745
|
+
cancelTestId
|
|
746
|
+
}) => {
|
|
747
|
+
const [pending, setPending] = useState(false);
|
|
748
|
+
const handleCancel = () => {
|
|
749
|
+
onOpenChange(false);
|
|
750
|
+
};
|
|
751
|
+
const handleConfirm = async () => {
|
|
752
|
+
setPending(true);
|
|
753
|
+
try {
|
|
754
|
+
await onConfirm();
|
|
755
|
+
onOpenChange(false);
|
|
756
|
+
} catch (error) {
|
|
757
|
+
console.error(error);
|
|
758
|
+
} finally {
|
|
759
|
+
setPending(false);
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
return /* @__PURE__ */ jsx21(
|
|
763
|
+
Modal,
|
|
764
|
+
{
|
|
765
|
+
open,
|
|
766
|
+
onOpenChange,
|
|
767
|
+
title,
|
|
768
|
+
description,
|
|
769
|
+
footer: /* @__PURE__ */ jsxs7(Fragment, { children: [
|
|
770
|
+
/* @__PURE__ */ jsx21(Button, { variant: "outline", onClick: handleCancel, disabled: pending, "data-testid": cancelTestId, children: cancelLabel }),
|
|
771
|
+
/* @__PURE__ */ jsx21(
|
|
772
|
+
Button,
|
|
773
|
+
{
|
|
774
|
+
variant: variant === "destructive" ? "destructive" : "default",
|
|
775
|
+
onClick: handleConfirm,
|
|
776
|
+
disabled: pending,
|
|
777
|
+
"data-testid": confirmTestId,
|
|
778
|
+
children: pending ? `${confirmLabel}\u2026` : confirmLabel
|
|
779
|
+
}
|
|
780
|
+
)
|
|
781
|
+
] }),
|
|
782
|
+
children: null
|
|
783
|
+
}
|
|
784
|
+
);
|
|
785
|
+
};
|
|
786
|
+
|
|
787
|
+
// src/patterns/modal/FormModal.tsx
|
|
788
|
+
import { useState as useState2 } from "react";
|
|
789
|
+
import { jsx as jsx22, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
790
|
+
var FormModal = ({
|
|
791
|
+
open,
|
|
792
|
+
onOpenChange,
|
|
793
|
+
title,
|
|
794
|
+
description,
|
|
795
|
+
children,
|
|
796
|
+
onSubmit,
|
|
797
|
+
submitLabel = "Save",
|
|
798
|
+
cancelLabel = "Cancel",
|
|
799
|
+
submitDisabled = false,
|
|
800
|
+
className,
|
|
801
|
+
submitTestId,
|
|
802
|
+
cancelTestId
|
|
803
|
+
}) => {
|
|
804
|
+
const [pending, setPending] = useState2(false);
|
|
805
|
+
const handleSubmit = async (event) => {
|
|
806
|
+
event.preventDefault();
|
|
807
|
+
setPending(true);
|
|
808
|
+
try {
|
|
809
|
+
await onSubmit();
|
|
810
|
+
} finally {
|
|
811
|
+
setPending(false);
|
|
812
|
+
}
|
|
813
|
+
};
|
|
814
|
+
const handleCancel = () => {
|
|
815
|
+
onOpenChange(false);
|
|
816
|
+
};
|
|
817
|
+
return /* @__PURE__ */ jsx22(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsx22(DialogContent, { className, children: /* @__PURE__ */ jsxs8("form", { onSubmit: handleSubmit, children: [
|
|
818
|
+
/* @__PURE__ */ jsxs8(DialogHeader, { children: [
|
|
819
|
+
/* @__PURE__ */ jsx22(DialogTitle, { children: title }),
|
|
820
|
+
description ? /* @__PURE__ */ jsx22(DialogDescription, { children: description }) : null
|
|
821
|
+
] }),
|
|
822
|
+
children,
|
|
823
|
+
/* @__PURE__ */ jsxs8(DialogFooter, { children: [
|
|
824
|
+
/* @__PURE__ */ jsx22(
|
|
825
|
+
Button,
|
|
826
|
+
{
|
|
827
|
+
type: "button",
|
|
828
|
+
variant: "outline",
|
|
829
|
+
onClick: handleCancel,
|
|
830
|
+
disabled: pending,
|
|
831
|
+
"data-testid": cancelTestId,
|
|
832
|
+
children: cancelLabel
|
|
833
|
+
}
|
|
834
|
+
),
|
|
835
|
+
/* @__PURE__ */ jsx22(Button, { type: "submit", disabled: pending || submitDisabled, "data-testid": submitTestId, children: pending ? `${submitLabel}\u2026` : submitLabel })
|
|
836
|
+
] })
|
|
837
|
+
] }) }) });
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
// src/patterns/form-field/FormField.tsx
|
|
841
|
+
import { cloneElement, isValidElement, useId } from "react";
|
|
842
|
+
import { jsx as jsx23, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
843
|
+
function FormField({
|
|
844
|
+
label,
|
|
845
|
+
htmlFor,
|
|
846
|
+
error,
|
|
847
|
+
description,
|
|
848
|
+
required,
|
|
849
|
+
children,
|
|
850
|
+
className
|
|
851
|
+
}) {
|
|
852
|
+
const generatedId = useId();
|
|
853
|
+
const resolvedId = htmlFor ?? generatedId;
|
|
854
|
+
const isSingleElement = isValidElement(children);
|
|
855
|
+
const existingChildId = isSingleElement ? children.props.id : void 0;
|
|
856
|
+
const effectiveId = existingChildId ?? resolvedId;
|
|
857
|
+
const message = error ?? description;
|
|
858
|
+
const messageId = message ? `${effectiveId}-message` : void 0;
|
|
859
|
+
const child = isSingleElement ? cloneElement(
|
|
860
|
+
children,
|
|
861
|
+
{
|
|
862
|
+
id: effectiveId,
|
|
863
|
+
...error ? { "aria-invalid": true } : {},
|
|
864
|
+
...messageId ? { "aria-describedby": messageId } : {}
|
|
865
|
+
}
|
|
866
|
+
) : children;
|
|
867
|
+
return /* @__PURE__ */ jsxs9("div", { className: cn("flex flex-col gap-1.5", className), children: [
|
|
868
|
+
/* @__PURE__ */ jsxs9(Label, { htmlFor: effectiveId, children: [
|
|
869
|
+
label,
|
|
870
|
+
required ? /* @__PURE__ */ jsxs9("span", { className: "text-destructive", "aria-hidden": "true", children: [
|
|
871
|
+
" ",
|
|
872
|
+
"*"
|
|
873
|
+
] }) : null
|
|
874
|
+
] }),
|
|
875
|
+
child,
|
|
876
|
+
error ? /* @__PURE__ */ jsx23("p", { id: messageId, className: "text-sm text-destructive", children: error }) : description ? /* @__PURE__ */ jsx23("p", { id: messageId, className: "text-sm text-muted-foreground", children: description }) : null
|
|
877
|
+
] });
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
// src/patterns/combobox/Combobox.tsx
|
|
881
|
+
import { Check as Check4, ChevronsUpDown, X as X3 } from "lucide-react";
|
|
882
|
+
import { useEffect, useMemo, useRef, useState as useState3 } from "react";
|
|
883
|
+
import { jsx as jsx24, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
884
|
+
function groupMembers(options, group) {
|
|
885
|
+
return options.filter((o) => o.group === group && !o.disabled).map((o) => o.value);
|
|
886
|
+
}
|
|
887
|
+
function groupCheckState(options, selectedValues, group) {
|
|
888
|
+
const members = groupMembers(options, group);
|
|
889
|
+
const selectedCount = members.filter((v) => selectedValues.includes(v)).length;
|
|
890
|
+
if (selectedCount === 0) return "unchecked";
|
|
891
|
+
return selectedCount === members.length ? "checked" : "indeterminate";
|
|
892
|
+
}
|
|
893
|
+
function resolveGroupTriggerLabel(options, selectedValues, groupLabel) {
|
|
894
|
+
const selectedSet = new Set(selectedValues);
|
|
895
|
+
const groupsPresent = Array.from(
|
|
896
|
+
new Set(options.filter((o) => selectedSet.has(o.value) && o.group).map((o) => o.group))
|
|
897
|
+
);
|
|
898
|
+
if (groupsPresent.length === 0) return null;
|
|
899
|
+
const coveredValues = /* @__PURE__ */ new Set();
|
|
900
|
+
const fullyCoveredGroups = [];
|
|
901
|
+
for (const group of groupsPresent) {
|
|
902
|
+
const members = groupMembers(options, group);
|
|
903
|
+
if (members.length > 0 && members.every((v) => selectedSet.has(v))) {
|
|
904
|
+
fullyCoveredGroups.push(group);
|
|
905
|
+
for (const v of members) coveredValues.add(v);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
const hasLeftover = selectedValues.some((v) => !coveredValues.has(v));
|
|
909
|
+
if (fullyCoveredGroups.length === 0 || hasLeftover) return null;
|
|
910
|
+
return fullyCoveredGroups.map(groupLabel).join(", ");
|
|
911
|
+
}
|
|
912
|
+
function buildOptionRows(visibleOptions) {
|
|
913
|
+
let lastGroup;
|
|
914
|
+
return visibleOptions.map((option, index) => {
|
|
915
|
+
const headerGroup = option.group && option.group !== lastGroup ? option.group : void 0;
|
|
916
|
+
lastGroup = option.group ?? lastGroup;
|
|
917
|
+
return { option, index, headerGroup };
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
function Combobox(props) {
|
|
921
|
+
const {
|
|
922
|
+
options,
|
|
923
|
+
placeholder = "Select\u2026",
|
|
924
|
+
searchPlaceholder = "Search\u2026",
|
|
925
|
+
emptyMessage = "No matches.",
|
|
926
|
+
disabled,
|
|
927
|
+
loading = false,
|
|
928
|
+
loadingMessage = "Loading\u2026",
|
|
929
|
+
clearable = true,
|
|
930
|
+
className,
|
|
931
|
+
id,
|
|
932
|
+
groupLabels,
|
|
933
|
+
container,
|
|
934
|
+
onSearchChange,
|
|
935
|
+
selectedLabel
|
|
936
|
+
} = props;
|
|
937
|
+
const testId = props["data-testid"];
|
|
938
|
+
const [open, setOpen] = useState3(false);
|
|
939
|
+
const [search, setSearch] = useState3("");
|
|
940
|
+
const [activeIndex, setActiveIndex] = useState3(0);
|
|
941
|
+
const inputRef = useRef(null);
|
|
942
|
+
const selectedValues = useMemo(
|
|
943
|
+
() => props.multiple ? props.value : props.value ? [props.value] : [],
|
|
944
|
+
[props.multiple, props.value]
|
|
945
|
+
);
|
|
946
|
+
const selectedOptions = useMemo(
|
|
947
|
+
() => options.filter((option) => selectedValues.includes(option.value)),
|
|
948
|
+
[options, selectedValues]
|
|
949
|
+
);
|
|
950
|
+
const visibleOptions = useMemo(() => {
|
|
951
|
+
if (onSearchChange) return options;
|
|
952
|
+
const term = search.trim().toLowerCase();
|
|
953
|
+
if (!term) return options;
|
|
954
|
+
return options.filter((option) => option.label.toLowerCase().includes(term));
|
|
955
|
+
}, [options, search, onSearchChange]);
|
|
956
|
+
useEffect(() => {
|
|
957
|
+
if (!open) return;
|
|
958
|
+
setSearch("");
|
|
959
|
+
onSearchChange?.("");
|
|
960
|
+
const firstSelected = selectedValues[0];
|
|
961
|
+
const selectedIdx = firstSelected ? options.findIndex((option) => option.value === firstSelected) : -1;
|
|
962
|
+
setActiveIndex(selectedIdx >= 0 ? selectedIdx : 0);
|
|
963
|
+
inputRef.current?.focus();
|
|
964
|
+
}, [open]);
|
|
965
|
+
useEffect(() => {
|
|
966
|
+
setActiveIndex((i) => Math.min(i, Math.max(visibleOptions.length - 1, 0)));
|
|
967
|
+
}, [visibleOptions.length]);
|
|
968
|
+
function selectOption(option) {
|
|
969
|
+
if (option.disabled) return;
|
|
970
|
+
if (props.multiple) {
|
|
971
|
+
const next = props.value.includes(option.value) ? props.value.filter((v) => v !== option.value) : [...props.value, option.value];
|
|
972
|
+
props.onChange(next);
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
props.onChange(option.value);
|
|
976
|
+
setOpen(false);
|
|
977
|
+
}
|
|
978
|
+
function handleKeyDown(event) {
|
|
979
|
+
if (event.key === "ArrowDown") {
|
|
980
|
+
event.preventDefault();
|
|
981
|
+
setActiveIndex((i) => Math.min(i + 1, visibleOptions.length - 1));
|
|
982
|
+
} else if (event.key === "ArrowUp") {
|
|
983
|
+
event.preventDefault();
|
|
984
|
+
setActiveIndex((i) => Math.max(i - 1, 0));
|
|
985
|
+
} else if (event.key === "Enter") {
|
|
986
|
+
event.preventDefault();
|
|
987
|
+
const option = visibleOptions[activeIndex];
|
|
988
|
+
if (option) selectOption(option);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
const groupLabel = (group) => groupLabels?.[group] ?? group;
|
|
992
|
+
function toggleGroup(group) {
|
|
993
|
+
if (!props.multiple) return;
|
|
994
|
+
const members = groupMembers(options, group);
|
|
995
|
+
const next = groupCheckState(options, selectedValues, group) === "checked" ? props.value.filter((v) => !members.includes(v)) : Array.from(/* @__PURE__ */ new Set([...props.value, ...members]));
|
|
996
|
+
props.onChange(next);
|
|
997
|
+
}
|
|
998
|
+
const triggerLabel = loading ? loadingMessage : selectedOptions.length === 0 ? selectedValues.length > 0 ? selectedLabel ?? placeholder : placeholder : selectedOptions.length === 1 ? selectedOptions[0]?.label ?? placeholder : (props.multiple ? resolveGroupTriggerLabel(options, selectedValues, groupLabel) : null) ?? `${selectedOptions.length} selected`;
|
|
999
|
+
const optionRows = useMemo(() => buildOptionRows(visibleOptions), [visibleOptions]);
|
|
1000
|
+
return /* @__PURE__ */ jsxs10(Popover, { open, onOpenChange: setOpen, children: [
|
|
1001
|
+
/* @__PURE__ */ jsx24(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs10(
|
|
1002
|
+
Button,
|
|
1003
|
+
{
|
|
1004
|
+
id,
|
|
1005
|
+
"data-testid": testId,
|
|
1006
|
+
type: "button",
|
|
1007
|
+
variant: "outline",
|
|
1008
|
+
role: "combobox",
|
|
1009
|
+
"aria-expanded": open,
|
|
1010
|
+
disabled: disabled || loading,
|
|
1011
|
+
className: cn(
|
|
1012
|
+
"w-full justify-between font-normal",
|
|
1013
|
+
(selectedOptions.length === 0 || loading) && "text-muted-foreground",
|
|
1014
|
+
className
|
|
1015
|
+
),
|
|
1016
|
+
children: [
|
|
1017
|
+
/* @__PURE__ */ jsx24("span", { className: "truncate", children: triggerLabel }),
|
|
1018
|
+
/* @__PURE__ */ jsxs10("span", { className: "flex items-center gap-1", children: [
|
|
1019
|
+
clearable && !loading && selectedValues.length > 0 ? /* @__PURE__ */ jsx24(
|
|
1020
|
+
"span",
|
|
1021
|
+
{
|
|
1022
|
+
role: "button",
|
|
1023
|
+
"aria-label": "Clear selection",
|
|
1024
|
+
tabIndex: -1,
|
|
1025
|
+
className: "rounded-sm p-0.5 opacity-60 hover:bg-accent hover:opacity-100",
|
|
1026
|
+
onClick: (event) => {
|
|
1027
|
+
event.stopPropagation();
|
|
1028
|
+
if (props.multiple) {
|
|
1029
|
+
props.onChange([]);
|
|
1030
|
+
} else {
|
|
1031
|
+
props.onChange(null);
|
|
1032
|
+
}
|
|
1033
|
+
},
|
|
1034
|
+
children: /* @__PURE__ */ jsx24(X3, { className: "h-3.5 w-3.5" })
|
|
1035
|
+
}
|
|
1036
|
+
) : null,
|
|
1037
|
+
/* @__PURE__ */ jsx24(ChevronsUpDown, { className: "h-4 w-4 shrink-0 opacity-50", "aria-hidden": "true" })
|
|
1038
|
+
] })
|
|
1039
|
+
]
|
|
1040
|
+
}
|
|
1041
|
+
) }),
|
|
1042
|
+
/* @__PURE__ */ jsx24(
|
|
1043
|
+
PopoverContent,
|
|
1044
|
+
{
|
|
1045
|
+
align: "start",
|
|
1046
|
+
container,
|
|
1047
|
+
className: "w-[var(--radix-popover-trigger-width)] min-w-[10rem] p-2",
|
|
1048
|
+
onOpenAutoFocus: (event) => event.preventDefault(),
|
|
1049
|
+
children: /* @__PURE__ */ jsxs10("div", { className: "flex flex-col gap-2", children: [
|
|
1050
|
+
/* @__PURE__ */ jsx24(
|
|
1051
|
+
Input,
|
|
1052
|
+
{
|
|
1053
|
+
ref: inputRef,
|
|
1054
|
+
value: search,
|
|
1055
|
+
onChange: (event) => {
|
|
1056
|
+
setSearch(event.target.value);
|
|
1057
|
+
onSearchChange?.(event.target.value);
|
|
1058
|
+
},
|
|
1059
|
+
onKeyDown: handleKeyDown,
|
|
1060
|
+
placeholder: searchPlaceholder,
|
|
1061
|
+
"aria-label": searchPlaceholder
|
|
1062
|
+
}
|
|
1063
|
+
),
|
|
1064
|
+
/* @__PURE__ */ jsx24("div", { role: "listbox", className: "flex max-h-60 flex-col gap-0.5 overflow-y-auto", children: optionRows.length === 0 ? /* @__PURE__ */ jsx24("p", { className: "py-2 text-center text-sm text-muted-foreground", children: emptyMessage }) : optionRows.map(({ option, index, headerGroup }) => {
|
|
1065
|
+
const isSelected = selectedValues.includes(option.value);
|
|
1066
|
+
const isActive = index === activeIndex;
|
|
1067
|
+
const headerState = headerGroup ? groupCheckState(options, selectedValues, headerGroup) : void 0;
|
|
1068
|
+
return /* @__PURE__ */ jsxs10("div", { children: [
|
|
1069
|
+
headerGroup ? /* @__PURE__ */ jsxs10(
|
|
1070
|
+
"div",
|
|
1071
|
+
{
|
|
1072
|
+
"data-group-header": true,
|
|
1073
|
+
className: "mt-1 flex items-center gap-2 rounded-sm bg-muted/50 px-2 py-1.5 text-sm font-semibold text-foreground first:mt-0",
|
|
1074
|
+
children: [
|
|
1075
|
+
props.multiple ? /* @__PURE__ */ jsx24(
|
|
1076
|
+
"input",
|
|
1077
|
+
{
|
|
1078
|
+
type: "checkbox",
|
|
1079
|
+
checked: headerState === "checked",
|
|
1080
|
+
ref: (el) => {
|
|
1081
|
+
if (el) el.indeterminate = headerState === "indeterminate";
|
|
1082
|
+
},
|
|
1083
|
+
onChange: () => toggleGroup(headerGroup),
|
|
1084
|
+
onClick: (event) => event.stopPropagation(),
|
|
1085
|
+
className: "h-3.5 w-3.5 shrink-0 accent-primary",
|
|
1086
|
+
"aria-label": `Select all of ${groupLabel(headerGroup)}`
|
|
1087
|
+
}
|
|
1088
|
+
) : null,
|
|
1089
|
+
/* @__PURE__ */ jsx24("span", { className: "truncate", children: groupLabel(headerGroup) })
|
|
1090
|
+
]
|
|
1091
|
+
}
|
|
1092
|
+
) : null,
|
|
1093
|
+
/* @__PURE__ */ jsxs10(
|
|
1094
|
+
"button",
|
|
1095
|
+
{
|
|
1096
|
+
type: "button",
|
|
1097
|
+
role: "option",
|
|
1098
|
+
"aria-selected": isSelected,
|
|
1099
|
+
disabled: option.disabled,
|
|
1100
|
+
"data-testid": testId ? `${testId}-option` : void 0,
|
|
1101
|
+
"data-option-value": option.value,
|
|
1102
|
+
onMouseEnter: () => setActiveIndex(index),
|
|
1103
|
+
onClick: () => selectOption(option),
|
|
1104
|
+
className: cn(
|
|
1105
|
+
"flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm outline-none disabled:pointer-events-none disabled:opacity-50",
|
|
1106
|
+
isActive && "bg-accent text-accent-foreground"
|
|
1107
|
+
),
|
|
1108
|
+
children: [
|
|
1109
|
+
props.multiple ? /* @__PURE__ */ jsx24(
|
|
1110
|
+
"input",
|
|
1111
|
+
{
|
|
1112
|
+
type: "checkbox",
|
|
1113
|
+
checked: isSelected,
|
|
1114
|
+
readOnly: true,
|
|
1115
|
+
tabIndex: -1,
|
|
1116
|
+
className: "pointer-events-none h-3.5 w-3.5 shrink-0 accent-primary"
|
|
1117
|
+
}
|
|
1118
|
+
) : /* @__PURE__ */ jsx24(Check4, { className: cn("h-4 w-4 shrink-0", isSelected ? "opacity-100" : "opacity-0") }),
|
|
1119
|
+
/* @__PURE__ */ jsx24("span", { className: "truncate", children: option.label })
|
|
1120
|
+
]
|
|
1121
|
+
}
|
|
1122
|
+
)
|
|
1123
|
+
] }, option.value);
|
|
1124
|
+
}) })
|
|
1125
|
+
] })
|
|
1126
|
+
}
|
|
1127
|
+
)
|
|
1128
|
+
] });
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
// src/patterns/alert-box/AlertBox.tsx
|
|
1132
|
+
import { AlertCircle, AlertTriangle, CheckCircle2, Info } from "lucide-react";
|
|
1133
|
+
import { jsx as jsx25, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1134
|
+
var variantStyles = {
|
|
1135
|
+
error: "border-destructive bg-destructive/10 text-destructive",
|
|
1136
|
+
warning: "border-amber-500 bg-amber-500/10 text-amber-700 dark:text-amber-300",
|
|
1137
|
+
info: "border-sky-500 bg-sky-500/10 text-sky-700 dark:text-sky-300",
|
|
1138
|
+
success: "border-emerald-500 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300"
|
|
1139
|
+
};
|
|
1140
|
+
var defaultIcons = {
|
|
1141
|
+
error: /* @__PURE__ */ jsx25(AlertCircle, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }),
|
|
1142
|
+
warning: /* @__PURE__ */ jsx25(AlertTriangle, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }),
|
|
1143
|
+
info: /* @__PURE__ */ jsx25(Info, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" }),
|
|
1144
|
+
success: /* @__PURE__ */ jsx25(CheckCircle2, { className: "h-4 w-4 shrink-0", "aria-hidden": "true" })
|
|
1145
|
+
};
|
|
1146
|
+
var AlertBox = ({ variant, title, children, className, icon }) => {
|
|
1147
|
+
const resolvedIcon = icon === void 0 ? defaultIcons[variant] : icon;
|
|
1148
|
+
return /* @__PURE__ */ jsx25("div", { className: cn("rounded-md border p-3 text-sm", variantStyles[variant], className), children: /* @__PURE__ */ jsxs11("div", { className: "flex flex-row items-start gap-2", children: [
|
|
1149
|
+
resolvedIcon != null && /* @__PURE__ */ jsx25("span", { className: "mt-0.5 shrink-0", children: resolvedIcon }),
|
|
1150
|
+
/* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-1", children: [
|
|
1151
|
+
title && /* @__PURE__ */ jsx25("p", { className: "font-bold", children: title }),
|
|
1152
|
+
/* @__PURE__ */ jsx25("div", { children })
|
|
1153
|
+
] })
|
|
1154
|
+
] }) });
|
|
1155
|
+
};
|
|
1156
|
+
|
|
1157
|
+
// src/patterns/status-badge/StatusBadge.tsx
|
|
1158
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
1159
|
+
var TONE_CLASSES = {
|
|
1160
|
+
success: "border-transparent bg-emerald-500/15 text-emerald-700 dark:bg-emerald-500/20 dark:text-emerald-300",
|
|
1161
|
+
warning: "border-transparent bg-amber-500/15 text-amber-700 dark:bg-amber-500/20 dark:text-amber-300",
|
|
1162
|
+
info: "border-transparent bg-sky-500/15 text-sky-700 dark:bg-sky-500/20 dark:text-sky-300",
|
|
1163
|
+
error: "border-transparent bg-destructive/15 text-destructive",
|
|
1164
|
+
neutral: "border-transparent bg-muted text-muted-foreground"
|
|
1165
|
+
};
|
|
1166
|
+
var DEFAULT_TONE_MAP = {
|
|
1167
|
+
active: "success",
|
|
1168
|
+
approved: "success",
|
|
1169
|
+
completed: "success",
|
|
1170
|
+
paid: "success",
|
|
1171
|
+
done: "success",
|
|
1172
|
+
pending: "warning",
|
|
1173
|
+
draft: "warning",
|
|
1174
|
+
in_review: "warning",
|
|
1175
|
+
inreview: "warning",
|
|
1176
|
+
rejected: "error",
|
|
1177
|
+
failed: "error",
|
|
1178
|
+
cancelled: "error",
|
|
1179
|
+
canceled: "error",
|
|
1180
|
+
overdue: "error",
|
|
1181
|
+
inactive: "neutral",
|
|
1182
|
+
archived: "neutral",
|
|
1183
|
+
new: "info"
|
|
1184
|
+
};
|
|
1185
|
+
function deriveLabel(status) {
|
|
1186
|
+
return status.replace(/[_-]+/g, " ").trim().split(/\s+/).filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
1187
|
+
}
|
|
1188
|
+
function resolveTone(status, tone, toneMap) {
|
|
1189
|
+
if (tone) {
|
|
1190
|
+
return tone;
|
|
1191
|
+
}
|
|
1192
|
+
const key = status.toLowerCase();
|
|
1193
|
+
if (toneMap) {
|
|
1194
|
+
for (const [candidate, candidateTone] of Object.entries(toneMap)) {
|
|
1195
|
+
if (candidate.toLowerCase() === key) {
|
|
1196
|
+
return candidateTone;
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
return DEFAULT_TONE_MAP[key] ?? "neutral";
|
|
1201
|
+
}
|
|
1202
|
+
var StatusBadge = ({ status, label, tone, toneMap, className, ...props }) => {
|
|
1203
|
+
const resolvedTone = resolveTone(status, tone, toneMap);
|
|
1204
|
+
const displayLabel = label ?? deriveLabel(status);
|
|
1205
|
+
return /* @__PURE__ */ jsx26(Badge, { variant: "outline", className: cn(TONE_CLASSES[resolvedTone], className), ...props, children: displayLabel });
|
|
1206
|
+
};
|
|
1207
|
+
|
|
1208
|
+
// src/patterns/loading-spinner/LoadingSpinner.tsx
|
|
1209
|
+
import { cva as cva4 } from "class-variance-authority";
|
|
1210
|
+
import { Loader2 } from "lucide-react";
|
|
1211
|
+
import { jsx as jsx27, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1212
|
+
var loadingSpinnerIconVariants = cva4("animate-spin text-muted-foreground", {
|
|
1213
|
+
variants: {
|
|
1214
|
+
size: {
|
|
1215
|
+
sm: "h-3.5 w-3.5",
|
|
1216
|
+
default: "h-4 w-4",
|
|
1217
|
+
lg: "h-6 w-6"
|
|
1218
|
+
}
|
|
1219
|
+
},
|
|
1220
|
+
defaultVariants: {
|
|
1221
|
+
size: "default"
|
|
1222
|
+
}
|
|
1223
|
+
});
|
|
1224
|
+
var LoadingSpinner = ({
|
|
1225
|
+
size,
|
|
1226
|
+
label,
|
|
1227
|
+
className,
|
|
1228
|
+
...props
|
|
1229
|
+
}) => /* @__PURE__ */ jsxs12("span", { role: "status", className: cn("inline-flex items-center gap-2", className), ...props, children: [
|
|
1230
|
+
/* @__PURE__ */ jsx27(Loader2, { className: cn(loadingSpinnerIconVariants({ size })), "aria-hidden": "true" }),
|
|
1231
|
+
label ? /* @__PURE__ */ jsx27("span", { children: label }) : null
|
|
1232
|
+
] });
|
|
1233
|
+
var LoadingOverlay = ({
|
|
1234
|
+
size = "lg",
|
|
1235
|
+
label,
|
|
1236
|
+
className,
|
|
1237
|
+
...props
|
|
1238
|
+
}) => /* @__PURE__ */ jsx27(
|
|
1239
|
+
"div",
|
|
1240
|
+
{
|
|
1241
|
+
className: cn("flex h-full min-h-32 w-full items-center justify-center", className),
|
|
1242
|
+
...props,
|
|
1243
|
+
children: /* @__PURE__ */ jsx27(LoadingSpinner, { size, label })
|
|
1244
|
+
}
|
|
1245
|
+
);
|
|
1246
|
+
export {
|
|
1247
|
+
AlertBox,
|
|
1248
|
+
Badge,
|
|
1249
|
+
Button,
|
|
1250
|
+
Card,
|
|
1251
|
+
CardContent,
|
|
1252
|
+
CardDescription,
|
|
1253
|
+
CardFooter,
|
|
1254
|
+
CardHeader,
|
|
1255
|
+
CardTitle,
|
|
1256
|
+
Checkbox,
|
|
1257
|
+
Combobox,
|
|
1258
|
+
ConfirmDialog,
|
|
1259
|
+
Dialog,
|
|
1260
|
+
DialogContent,
|
|
1261
|
+
DialogDescription,
|
|
1262
|
+
DialogFooter,
|
|
1263
|
+
DialogHeader,
|
|
1264
|
+
DialogTitle,
|
|
1265
|
+
DialogTrigger,
|
|
1266
|
+
DropdownMenu,
|
|
1267
|
+
DropdownMenuCheckboxItem,
|
|
1268
|
+
DropdownMenuContent,
|
|
1269
|
+
DropdownMenuGroup,
|
|
1270
|
+
DropdownMenuItem,
|
|
1271
|
+
DropdownMenuLabel,
|
|
1272
|
+
DropdownMenuPortal,
|
|
1273
|
+
DropdownMenuRadioGroup,
|
|
1274
|
+
DropdownMenuRadioItem,
|
|
1275
|
+
DropdownMenuSeparator,
|
|
1276
|
+
DropdownMenuShortcut,
|
|
1277
|
+
DropdownMenuSub,
|
|
1278
|
+
DropdownMenuSubContent,
|
|
1279
|
+
DropdownMenuSubTrigger,
|
|
1280
|
+
DropdownMenuTrigger,
|
|
1281
|
+
FormField,
|
|
1282
|
+
FormModal,
|
|
1283
|
+
Input,
|
|
1284
|
+
Label,
|
|
1285
|
+
LoadingOverlay,
|
|
1286
|
+
LoadingSpinner,
|
|
1287
|
+
Modal,
|
|
1288
|
+
Popover,
|
|
1289
|
+
PopoverAnchor,
|
|
1290
|
+
PopoverContent,
|
|
1291
|
+
PopoverTrigger,
|
|
1292
|
+
ScrollArea,
|
|
1293
|
+
ScrollBar,
|
|
1294
|
+
Select,
|
|
1295
|
+
SelectContent,
|
|
1296
|
+
SelectGroup,
|
|
1297
|
+
SelectItem,
|
|
1298
|
+
SelectTrigger,
|
|
1299
|
+
SelectValue,
|
|
1300
|
+
Separator,
|
|
1301
|
+
Sheet,
|
|
1302
|
+
SheetClose,
|
|
1303
|
+
SheetContent,
|
|
1304
|
+
SheetDescription,
|
|
1305
|
+
SheetFooter,
|
|
1306
|
+
SheetHeader,
|
|
1307
|
+
SheetPortal,
|
|
1308
|
+
SheetTitle,
|
|
1309
|
+
SheetTrigger,
|
|
1310
|
+
Skeleton,
|
|
1311
|
+
StatusBadge,
|
|
1312
|
+
Switch,
|
|
1313
|
+
Table,
|
|
1314
|
+
TableBody,
|
|
1315
|
+
TableCaption,
|
|
1316
|
+
TableCell,
|
|
1317
|
+
TableFooter,
|
|
1318
|
+
TableHead,
|
|
1319
|
+
TableHeader,
|
|
1320
|
+
TableRow,
|
|
1321
|
+
Tabs,
|
|
1322
|
+
TabsContent,
|
|
1323
|
+
TabsList,
|
|
1324
|
+
TabsTrigger,
|
|
1325
|
+
Textarea,
|
|
1326
|
+
Tooltip,
|
|
1327
|
+
TooltipContent,
|
|
1328
|
+
TooltipProvider,
|
|
1329
|
+
TooltipTrigger,
|
|
1330
|
+
badgeVariants,
|
|
1331
|
+
buttonVariants,
|
|
1332
|
+
cn,
|
|
1333
|
+
loadingSpinnerIconVariants,
|
|
1334
|
+
sheetVariants
|
|
1335
|
+
};
|
|
1336
|
+
//# sourceMappingURL=index.js.map
|