@timbal-ai/timbal-react 1.2.0 → 1.4.0
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/CHANGELOG.md +38 -0
- package/LICENSE +201 -0
- package/README.md +17 -4
- package/dist/app.cjs +1299 -1137
- package/dist/app.d.cts +21 -5
- package/dist/app.d.ts +21 -5
- package/dist/app.esm.js +17 -7
- package/dist/{chart-artifact-E58ve76I.d.cts → chart-artifact-C8-Py6lc.d.cts} +97 -27
- package/dist/{chart-artifact-_PEJgCpQ.d.ts → chart-artifact-CMnDys2t.d.ts} +97 -27
- package/dist/chat.esm.js +3 -3
- package/dist/{chunk-UY7AKWJL.esm.js → chunk-GQBYZRD7.esm.js} +1 -1
- package/dist/{chunk-AGJKK6R7.esm.js → chunk-OFWC4MIY.esm.js} +2 -2
- package/dist/{chunk-4VULP3CJ.esm.js → chunk-OH23AX2V.esm.js} +757 -56
- package/dist/{chunk-BMXFXLVV.esm.js → chunk-QU7ET55D.esm.js} +0 -1
- package/dist/{chunk-MTYXREHK.esm.js → chunk-THBA27QY.esm.js} +4 -4
- package/dist/{chunk-FEYZUVBM.esm.js → chunk-UCGVL7ZY.esm.js} +1 -1
- package/dist/{chunk-XDIY2WSL.esm.js → chunk-VOWNCS3F.esm.js} +649 -494
- package/dist/{chunk-NAMKO2MU.esm.js → chunk-VXMM2HX7.esm.js} +1 -1
- package/dist/{pill-segmented-tabs-BsIOW1Lo.d.ts → circular-progress-Ci8L-Hfa.d.cts} +199 -3
- package/dist/{pill-segmented-tabs-BsIOW1Lo.d.cts → circular-progress-Ci8L-Hfa.d.ts} +199 -3
- package/dist/index.cjs +1797 -938
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.esm.js +28 -10
- package/dist/studio.esm.js +5 -5
- package/dist/ui.cjs +758 -49
- package/dist/ui.d.cts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.esm.js +24 -4
- package/package.json +1 -1
package/dist/ui.cjs
CHANGED
|
@@ -52,8 +52,10 @@ __export(ui_exports, {
|
|
|
52
52
|
AspectRatio: () => AspectRatio,
|
|
53
53
|
Avatar: () => Avatar,
|
|
54
54
|
AvatarFallback: () => AvatarFallback,
|
|
55
|
+
AvatarGroup: () => AvatarGroup,
|
|
55
56
|
AvatarImage: () => AvatarImage,
|
|
56
57
|
Badge: () => Badge,
|
|
58
|
+
Banner: () => Banner,
|
|
57
59
|
Breadcrumb: () => Breadcrumb,
|
|
58
60
|
BreadcrumbEllipsis: () => BreadcrumbEllipsis,
|
|
59
61
|
BreadcrumbItem: () => BreadcrumbItem,
|
|
@@ -78,6 +80,7 @@ __export(ui_exports, {
|
|
|
78
80
|
ChartTooltip: () => ChartTooltip,
|
|
79
81
|
ChartTooltipContent: () => ChartTooltipContent,
|
|
80
82
|
Checkbox: () => Checkbox,
|
|
83
|
+
CircularProgress: () => CircularProgress,
|
|
81
84
|
Collapsible: () => Collapsible,
|
|
82
85
|
CollapsibleContent: () => CollapsibleContent,
|
|
83
86
|
CollapsibleTrigger: () => CollapsibleTrigger,
|
|
@@ -116,6 +119,7 @@ __export(ui_exports, {
|
|
|
116
119
|
ContextMenuSubContent: () => ContextMenuSubContent,
|
|
117
120
|
ContextMenuSubTrigger: () => ContextMenuSubTrigger,
|
|
118
121
|
ContextMenuTrigger: () => ContextMenuTrigger,
|
|
122
|
+
CopyButton: () => CopyButton,
|
|
119
123
|
DatePicker: () => DatePicker,
|
|
120
124
|
DatePickerButton: () => DatePickerButton,
|
|
121
125
|
DatePickerCalendar: () => DatePickerCalendar,
|
|
@@ -191,6 +195,7 @@ __export(ui_exports, {
|
|
|
191
195
|
NavigationMenuList: () => NavigationMenuList,
|
|
192
196
|
NavigationMenuTrigger: () => NavigationMenuTrigger,
|
|
193
197
|
NavigationMenuViewport: () => NavigationMenuViewport,
|
|
198
|
+
NumberField: () => NumberField,
|
|
194
199
|
Pagination: () => Pagination,
|
|
195
200
|
PaginationContent: () => PaginationContent,
|
|
196
201
|
PaginationEllipsis: () => PaginationEllipsis,
|
|
@@ -206,6 +211,7 @@ __export(ui_exports, {
|
|
|
206
211
|
Progress: () => Progress,
|
|
207
212
|
RadioGroup: () => RadioGroup,
|
|
208
213
|
RadioGroupItem: () => RadioGroupItem,
|
|
214
|
+
Rating: () => Rating,
|
|
209
215
|
ScrollArea: () => ScrollArea,
|
|
210
216
|
ScrollBar: () => ScrollBar,
|
|
211
217
|
Select: () => Select,
|
|
@@ -230,7 +236,9 @@ __export(ui_exports, {
|
|
|
230
236
|
Shimmer: () => Shimmer,
|
|
231
237
|
Skeleton: () => Skeleton,
|
|
232
238
|
Slider: () => Slider,
|
|
239
|
+
Snippet: () => Snippet,
|
|
233
240
|
Spinner: () => Spinner,
|
|
241
|
+
Stepper: () => Stepper,
|
|
234
242
|
Switch: () => Switch,
|
|
235
243
|
Table: () => Table,
|
|
236
244
|
TableBody: () => TableBody,
|
|
@@ -240,8 +248,10 @@ __export(ui_exports, {
|
|
|
240
248
|
TableHead: () => TableHead,
|
|
241
249
|
TableHeader: () => TableHeader,
|
|
242
250
|
TableRow: () => TableRow,
|
|
251
|
+
TagInput: () => TagInput,
|
|
243
252
|
Textarea: () => Textarea,
|
|
244
253
|
TimbalV2Button: () => TimbalV2Button,
|
|
254
|
+
Timeline: () => Timeline,
|
|
245
255
|
Toast: () => Toast,
|
|
246
256
|
ToastAction: () => ToastAction,
|
|
247
257
|
ToastClose: () => ToastClose,
|
|
@@ -481,12 +491,12 @@ var TimbalV2Button = React.forwardRef(function TimbalV2Button2({
|
|
|
481
491
|
...props
|
|
482
492
|
}, ref) {
|
|
483
493
|
const isDisabled = disabled || isLoading;
|
|
484
|
-
const
|
|
494
|
+
const sizeClass2 = isIconOnly ? TIMBAL_V2_SIZE_ICON[size] : TIMBAL_V2_SIZE_HEIGHT[size];
|
|
485
495
|
const radiusClass = "rounded-full";
|
|
486
496
|
const sharedRootClass = cn(
|
|
487
497
|
"relative box-border inline-flex items-center justify-center gap-2 whitespace-nowrap border-0 text-sm font-normal shadow-none transition duration-200 ease-in-out",
|
|
488
498
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/60 focus-visible:ring-offset-1 focus-visible:ring-offset-background",
|
|
489
|
-
|
|
499
|
+
sizeClass2,
|
|
490
500
|
radiusClass,
|
|
491
501
|
TIMBAL_V2_BORDER[variant],
|
|
492
502
|
TIMBAL_V2_SHADOW[variant],
|
|
@@ -2425,56 +2435,71 @@ function Calendar({
|
|
|
2425
2435
|
showOutsideDays = true,
|
|
2426
2436
|
...props
|
|
2427
2437
|
}) {
|
|
2438
|
+
const defaults = (0, import_react_day_picker.getDefaultClassNames)();
|
|
2428
2439
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2429
2440
|
import_react_day_picker.DayPicker,
|
|
2430
2441
|
{
|
|
2431
2442
|
showOutsideDays,
|
|
2432
|
-
className: cn("p-
|
|
2443
|
+
className: cn("p-4", className),
|
|
2433
2444
|
classNames: {
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
buttonVariants({ variant: "outline" }),
|
|
2441
|
-
"absolute left-1 size-7 bg-transparent p-0 opacity-70 hover:opacity-100"
|
|
2445
|
+
root: cn("w-fit", defaults.root),
|
|
2446
|
+
months: cn("relative flex flex-col gap-4 sm:flex-row", defaults.months),
|
|
2447
|
+
month: cn("flex w-full flex-col gap-3", defaults.month),
|
|
2448
|
+
nav: cn(
|
|
2449
|
+
"absolute inset-x-0 top-0 flex items-center justify-between",
|
|
2450
|
+
defaults.nav
|
|
2442
2451
|
),
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2452
|
+
button_previous: cn(navButtonClass, defaults.button_previous),
|
|
2453
|
+
button_next: cn(navButtonClass, defaults.button_next),
|
|
2454
|
+
month_caption: cn(
|
|
2455
|
+
"flex h-10 items-center justify-center",
|
|
2456
|
+
defaults.month_caption
|
|
2457
|
+
),
|
|
2458
|
+
caption_label: cn("text-sm font-semibold", defaults.caption_label),
|
|
2459
|
+
dropdowns: cn(
|
|
2460
|
+
"flex h-10 items-center justify-center gap-1.5 text-sm font-semibold",
|
|
2461
|
+
defaults.dropdowns
|
|
2462
|
+
),
|
|
2463
|
+
dropdown_root: cn(
|
|
2464
|
+
"relative rounded-md border border-border focus-within:ring-2 focus-within:ring-foreground/10",
|
|
2465
|
+
defaults.dropdown_root
|
|
2466
|
+
),
|
|
2467
|
+
dropdown: cn("absolute inset-0 bg-popover opacity-0", defaults.dropdown),
|
|
2468
|
+
month_grid: cn("border-separate border-spacing-y-1", defaults.month_grid),
|
|
2469
|
+
weekdays: cn(defaults.weekdays),
|
|
2470
|
+
weekday: cn(
|
|
2471
|
+
"size-10 pb-2 text-xs font-medium text-muted-foreground",
|
|
2472
|
+
defaults.weekday
|
|
2473
|
+
),
|
|
2474
|
+
week: cn(defaults.week),
|
|
2475
|
+
week_number_header: cn("size-10", defaults.week_number_header),
|
|
2476
|
+
week_number: cn(
|
|
2477
|
+
"text-xs text-muted-foreground",
|
|
2478
|
+
defaults.week_number
|
|
2446
2479
|
),
|
|
2447
|
-
month_grid: "w-full border-collapse",
|
|
2448
|
-
weekdays: "flex",
|
|
2449
|
-
weekday: "w-9 rounded-md text-[0.8rem] font-normal text-muted-foreground",
|
|
2450
|
-
week: "mt-2 flex w-full",
|
|
2451
2480
|
day: cn(
|
|
2452
|
-
"relative size-
|
|
2453
|
-
|
|
2454
|
-
"[&:has([aria-selected].day-outside)]:bg-accent/50",
|
|
2455
|
-
"[&:has([aria-selected])]:bg-accent",
|
|
2456
|
-
"first:[&:has([aria-selected])]:rounded-l-md",
|
|
2457
|
-
"last:[&:has([aria-selected])]:rounded-r-md",
|
|
2458
|
-
"focus-within:relative focus-within:z-10"
|
|
2481
|
+
"relative size-10 p-0 text-center text-sm focus-within:relative focus-within:z-10",
|
|
2482
|
+
defaults.day
|
|
2459
2483
|
),
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2484
|
+
range_start: cn("rounded-l-md", defaults.range_start),
|
|
2485
|
+
range_middle: cn("rounded-none", defaults.range_middle),
|
|
2486
|
+
range_end: cn("rounded-r-md", defaults.range_end),
|
|
2487
|
+
today: cn(
|
|
2488
|
+
"[&>button]:font-semibold [&>button:not([data-selected-single=true]):not([data-range-middle=true])]:text-primary",
|
|
2489
|
+
defaults.today
|
|
2463
2490
|
),
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
disabled: "text-muted-foreground opacity-50",
|
|
2471
|
-
hidden: "invisible",
|
|
2491
|
+
outside: cn(
|
|
2492
|
+
"text-muted-foreground/60 aria-selected:text-muted-foreground",
|
|
2493
|
+
defaults.outside
|
|
2494
|
+
),
|
|
2495
|
+
disabled: cn("text-muted-foreground opacity-50", defaults.disabled),
|
|
2496
|
+
hidden: cn("invisible", defaults.hidden),
|
|
2472
2497
|
...classNames
|
|
2473
2498
|
},
|
|
2474
2499
|
components: {
|
|
2475
|
-
Chevron: ({ orientation, className:
|
|
2476
|
-
const Icon = orientation === "left" ? import_lucide_react11.ChevronLeftIcon : import_lucide_react11.ChevronRightIcon;
|
|
2477
|
-
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon, { className: cn("size-4",
|
|
2500
|
+
Chevron: ({ orientation, className: chevronClass, ...chevronProps }) => {
|
|
2501
|
+
const Icon = orientation === "left" ? import_lucide_react11.ChevronLeftIcon : orientation === "right" ? import_lucide_react11.ChevronRightIcon : import_lucide_react11.ChevronDownIcon;
|
|
2502
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(Icon, { className: cn("size-4", chevronClass), ...chevronProps });
|
|
2478
2503
|
},
|
|
2479
2504
|
DayButton: CalendarDayButton
|
|
2480
2505
|
},
|
|
@@ -2482,6 +2507,12 @@ function Calendar({
|
|
|
2482
2507
|
}
|
|
2483
2508
|
);
|
|
2484
2509
|
}
|
|
2510
|
+
var navButtonClass = cn(
|
|
2511
|
+
"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground transition-colors",
|
|
2512
|
+
"hover:bg-accent hover:text-accent-foreground",
|
|
2513
|
+
"disabled:pointer-events-none disabled:opacity-40",
|
|
2514
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/10"
|
|
2515
|
+
);
|
|
2485
2516
|
function CalendarDayButton({
|
|
2486
2517
|
className,
|
|
2487
2518
|
day,
|
|
@@ -2492,25 +2523,26 @@ function CalendarDayButton({
|
|
|
2492
2523
|
React3.useEffect(() => {
|
|
2493
2524
|
if (modifiers.focused) ref.current?.focus();
|
|
2494
2525
|
}, [modifiers.focused]);
|
|
2526
|
+
const isSingle = modifiers.selected && !modifiers.range_start && !modifiers.range_end && !modifiers.range_middle;
|
|
2495
2527
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2496
2528
|
"button",
|
|
2497
2529
|
{
|
|
2498
2530
|
ref,
|
|
2499
2531
|
type: "button",
|
|
2500
2532
|
"data-day": day.date.toLocaleDateString(),
|
|
2501
|
-
"data-selected-single":
|
|
2502
|
-
"data-range-start": modifiers.range_start,
|
|
2503
|
-
"data-range-end": modifiers.range_end,
|
|
2504
|
-
"data-range-middle": modifiers.range_middle,
|
|
2533
|
+
"data-selected-single": isSingle || void 0,
|
|
2534
|
+
"data-range-start": modifiers.range_start || void 0,
|
|
2535
|
+
"data-range-end": modifiers.range_end || void 0,
|
|
2536
|
+
"data-range-middle": modifiers.range_middle || void 0,
|
|
2505
2537
|
className: cn(
|
|
2506
|
-
"inline-flex items-center justify-center
|
|
2538
|
+
"inline-flex size-full items-center justify-center rounded-md text-sm font-normal transition-colors",
|
|
2507
2539
|
"hover:bg-accent hover:text-accent-foreground",
|
|
2508
|
-
"focus-visible:
|
|
2540
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/15",
|
|
2509
2541
|
"disabled:pointer-events-none disabled:opacity-50",
|
|
2510
|
-
"data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground",
|
|
2511
|
-
"data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground",
|
|
2512
|
-
"data-[range-start=true]:rounded-l-md data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground",
|
|
2513
|
-
"data-[range-end=true]:rounded-r-md data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground",
|
|
2542
|
+
"data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[selected-single=true]:hover:bg-primary",
|
|
2543
|
+
"data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground",
|
|
2544
|
+
"data-[range-start=true]:rounded-l-md data-[range-start=true]:rounded-r-none data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground",
|
|
2545
|
+
"data-[range-end=true]:rounded-r-md data-[range-end=true]:rounded-l-none data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground",
|
|
2514
2546
|
className
|
|
2515
2547
|
),
|
|
2516
2548
|
...props
|
|
@@ -4578,6 +4610,673 @@ var PillSegmentedTabs = ({
|
|
|
4578
4610
|
)) });
|
|
4579
4611
|
};
|
|
4580
4612
|
var MemoPillSegmentedTabs = (0, import_react3.memo)(PillSegmentedTabs);
|
|
4613
|
+
|
|
4614
|
+
// src/ui/avatar-group.tsx
|
|
4615
|
+
var React7 = __toESM(require("react"), 1);
|
|
4616
|
+
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
4617
|
+
var spacingClass = {
|
|
4618
|
+
sm: "-space-x-2",
|
|
4619
|
+
md: "-space-x-3"
|
|
4620
|
+
};
|
|
4621
|
+
function AvatarGroup({
|
|
4622
|
+
className,
|
|
4623
|
+
children,
|
|
4624
|
+
max,
|
|
4625
|
+
spacing = "sm",
|
|
4626
|
+
...props
|
|
4627
|
+
}) {
|
|
4628
|
+
const items = React7.Children.toArray(children);
|
|
4629
|
+
const overflow = typeof max === "number" ? items.length - max : 0;
|
|
4630
|
+
const visible = typeof max === "number" ? items.slice(0, max) : items;
|
|
4631
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
|
|
4632
|
+
"div",
|
|
4633
|
+
{
|
|
4634
|
+
"data-slot": "avatar-group",
|
|
4635
|
+
className: cn(
|
|
4636
|
+
"flex items-center",
|
|
4637
|
+
spacingClass[spacing],
|
|
4638
|
+
"[&>*]:rounded-full [&>*]:ring-2 [&>*]:ring-background",
|
|
4639
|
+
className
|
|
4640
|
+
),
|
|
4641
|
+
...props,
|
|
4642
|
+
children: [
|
|
4643
|
+
visible,
|
|
4644
|
+
overflow > 0 ? /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
|
|
4645
|
+
"span",
|
|
4646
|
+
{
|
|
4647
|
+
"aria-label": `${overflow} more`,
|
|
4648
|
+
className: "inline-flex size-8 items-center justify-center rounded-full bg-muted text-xs font-medium text-muted-foreground ring-2 ring-background",
|
|
4649
|
+
children: [
|
|
4650
|
+
"+",
|
|
4651
|
+
overflow
|
|
4652
|
+
]
|
|
4653
|
+
}
|
|
4654
|
+
) : null
|
|
4655
|
+
]
|
|
4656
|
+
}
|
|
4657
|
+
);
|
|
4658
|
+
}
|
|
4659
|
+
|
|
4660
|
+
// src/ui/stepper.tsx
|
|
4661
|
+
var import_lucide_react19 = require("lucide-react");
|
|
4662
|
+
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
4663
|
+
function Stepper({
|
|
4664
|
+
steps,
|
|
4665
|
+
current,
|
|
4666
|
+
orientation = "horizontal",
|
|
4667
|
+
className,
|
|
4668
|
+
...props
|
|
4669
|
+
}) {
|
|
4670
|
+
const isVertical = orientation === "vertical";
|
|
4671
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
4672
|
+
"ol",
|
|
4673
|
+
{
|
|
4674
|
+
"data-slot": "stepper",
|
|
4675
|
+
className: cn(
|
|
4676
|
+
"flex",
|
|
4677
|
+
isVertical ? "flex-col gap-0" : "items-start gap-2",
|
|
4678
|
+
className
|
|
4679
|
+
),
|
|
4680
|
+
...props,
|
|
4681
|
+
children: steps.map((step, index) => {
|
|
4682
|
+
const complete = index < current;
|
|
4683
|
+
const active = index === current;
|
|
4684
|
+
const last = index === steps.length - 1;
|
|
4685
|
+
const connectorFilled = index < current;
|
|
4686
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
|
|
4687
|
+
"li",
|
|
4688
|
+
{
|
|
4689
|
+
"aria-current": active ? "step" : void 0,
|
|
4690
|
+
className: cn(
|
|
4691
|
+
"flex min-w-0",
|
|
4692
|
+
isVertical ? "gap-3" : "flex-1 flex-col gap-1.5",
|
|
4693
|
+
last && !isVertical && "flex-none"
|
|
4694
|
+
),
|
|
4695
|
+
children: [
|
|
4696
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: cn("flex items-center gap-2", isVertical && "flex-col"), children: [
|
|
4697
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
4698
|
+
"span",
|
|
4699
|
+
{
|
|
4700
|
+
className: cn(
|
|
4701
|
+
"inline-flex size-7 shrink-0 items-center justify-center rounded-full border text-xs font-medium transition-colors",
|
|
4702
|
+
complete && "border-primary bg-primary text-primary-foreground",
|
|
4703
|
+
active && "border-primary text-primary",
|
|
4704
|
+
!complete && !active && "border-border text-muted-foreground"
|
|
4705
|
+
),
|
|
4706
|
+
children: complete ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react19.CheckIcon, { className: "size-3.5", "aria-hidden": true }) : index + 1
|
|
4707
|
+
}
|
|
4708
|
+
),
|
|
4709
|
+
!last ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
4710
|
+
"span",
|
|
4711
|
+
{
|
|
4712
|
+
"aria-hidden": true,
|
|
4713
|
+
className: cn(
|
|
4714
|
+
isVertical ? "w-px flex-1" : "h-px flex-1",
|
|
4715
|
+
connectorFilled ? "bg-primary" : "bg-border",
|
|
4716
|
+
isVertical && "min-h-6"
|
|
4717
|
+
)
|
|
4718
|
+
}
|
|
4719
|
+
) : null
|
|
4720
|
+
] }),
|
|
4721
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: cn("min-w-0", isVertical && "pb-4"), children: [
|
|
4722
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
4723
|
+
"p",
|
|
4724
|
+
{
|
|
4725
|
+
className: cn(
|
|
4726
|
+
"truncate text-sm font-medium",
|
|
4727
|
+
active ? "text-foreground" : "text-muted-foreground"
|
|
4728
|
+
),
|
|
4729
|
+
children: step.label
|
|
4730
|
+
}
|
|
4731
|
+
),
|
|
4732
|
+
step.description ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { className: "truncate text-xs text-muted-foreground", children: step.description }) : null
|
|
4733
|
+
] })
|
|
4734
|
+
]
|
|
4735
|
+
},
|
|
4736
|
+
step.id
|
|
4737
|
+
);
|
|
4738
|
+
})
|
|
4739
|
+
}
|
|
4740
|
+
);
|
|
4741
|
+
}
|
|
4742
|
+
|
|
4743
|
+
// src/ui/timeline.tsx
|
|
4744
|
+
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
4745
|
+
var dotToneClass = {
|
|
4746
|
+
default: "border-border bg-card",
|
|
4747
|
+
primary: "border-primary bg-primary",
|
|
4748
|
+
success: "border-emerald-500 bg-emerald-500",
|
|
4749
|
+
warn: "border-amber-500 bg-amber-500",
|
|
4750
|
+
danger: "border-destructive bg-destructive"
|
|
4751
|
+
};
|
|
4752
|
+
function Timeline({ items, className, ...props }) {
|
|
4753
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("ol", { "data-slot": "timeline", className: cn("flex flex-col", className), ...props, children: items.map((item, index) => {
|
|
4754
|
+
const last = index === items.length - 1;
|
|
4755
|
+
const tone = item.tone ?? "default";
|
|
4756
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("li", { className: "relative flex gap-3 pb-5 last:pb-0", children: [
|
|
4757
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex flex-col items-center", children: [
|
|
4758
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
4759
|
+
"span",
|
|
4760
|
+
{
|
|
4761
|
+
className: cn(
|
|
4762
|
+
"z-[1] mt-0.5 inline-flex size-3 shrink-0 items-center justify-center rounded-full border-2",
|
|
4763
|
+
dotToneClass[tone],
|
|
4764
|
+
item.icon && "size-6"
|
|
4765
|
+
),
|
|
4766
|
+
children: item.icon
|
|
4767
|
+
}
|
|
4768
|
+
),
|
|
4769
|
+
!last ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { "aria-hidden": true, className: "w-px flex-1 bg-border" }) : null
|
|
4770
|
+
] }),
|
|
4771
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "min-w-0 flex-1 pb-0.5", children: [
|
|
4772
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "flex items-start justify-between gap-2", children: [
|
|
4773
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "text-sm font-medium text-foreground", children: item.title }),
|
|
4774
|
+
item.meta ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground tabular-nums", children: item.meta }) : null
|
|
4775
|
+
] }),
|
|
4776
|
+
item.description ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("p", { className: "mt-0.5 text-sm text-muted-foreground", children: item.description }) : null
|
|
4777
|
+
] })
|
|
4778
|
+
] }, item.id);
|
|
4779
|
+
}) });
|
|
4780
|
+
}
|
|
4781
|
+
|
|
4782
|
+
// src/ui/rating.tsx
|
|
4783
|
+
var React8 = __toESM(require("react"), 1);
|
|
4784
|
+
var import_lucide_react20 = require("lucide-react");
|
|
4785
|
+
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
4786
|
+
var sizeClass = { sm: "size-4", md: "size-5", lg: "size-6" };
|
|
4787
|
+
function Rating({
|
|
4788
|
+
value: valueProp,
|
|
4789
|
+
defaultValue = 0,
|
|
4790
|
+
onChange,
|
|
4791
|
+
max = 5,
|
|
4792
|
+
readOnly = false,
|
|
4793
|
+
disabled = false,
|
|
4794
|
+
size = "md",
|
|
4795
|
+
label = "Rating",
|
|
4796
|
+
className
|
|
4797
|
+
}) {
|
|
4798
|
+
const [uncontrolled, setUncontrolled] = React8.useState(defaultValue);
|
|
4799
|
+
const isControlled = valueProp !== void 0;
|
|
4800
|
+
const value = isControlled ? valueProp : uncontrolled;
|
|
4801
|
+
const [hover, setHover] = React8.useState(null);
|
|
4802
|
+
const interactive = !readOnly && !disabled;
|
|
4803
|
+
const shown = hover ?? value;
|
|
4804
|
+
const set = (next) => {
|
|
4805
|
+
if (!interactive) return;
|
|
4806
|
+
if (!isControlled) setUncontrolled(next);
|
|
4807
|
+
onChange?.(next);
|
|
4808
|
+
};
|
|
4809
|
+
if (!interactive) {
|
|
4810
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
4811
|
+
"span",
|
|
4812
|
+
{
|
|
4813
|
+
"data-slot": "rating",
|
|
4814
|
+
role: "img",
|
|
4815
|
+
"aria-label": `${label}: ${value} of ${max}`,
|
|
4816
|
+
className: cn("inline-flex items-center gap-0.5", disabled && "opacity-50", className),
|
|
4817
|
+
children: Array.from({ length: max }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
4818
|
+
import_lucide_react20.StarIcon,
|
|
4819
|
+
{
|
|
4820
|
+
"aria-hidden": true,
|
|
4821
|
+
className: cn(
|
|
4822
|
+
sizeClass[size],
|
|
4823
|
+
i < value ? "fill-amber-400 text-amber-400" : "fill-transparent text-muted-foreground/40"
|
|
4824
|
+
)
|
|
4825
|
+
},
|
|
4826
|
+
i
|
|
4827
|
+
))
|
|
4828
|
+
}
|
|
4829
|
+
);
|
|
4830
|
+
}
|
|
4831
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
4832
|
+
"span",
|
|
4833
|
+
{
|
|
4834
|
+
"data-slot": "rating",
|
|
4835
|
+
role: "radiogroup",
|
|
4836
|
+
"aria-label": label,
|
|
4837
|
+
className: cn("inline-flex items-center gap-0.5", className),
|
|
4838
|
+
onMouseLeave: () => setHover(null),
|
|
4839
|
+
children: Array.from({ length: max }, (_, i) => {
|
|
4840
|
+
const unit = i + 1;
|
|
4841
|
+
const filled = unit <= shown;
|
|
4842
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
4843
|
+
"button",
|
|
4844
|
+
{
|
|
4845
|
+
type: "button",
|
|
4846
|
+
role: "radio",
|
|
4847
|
+
"aria-checked": unit === value,
|
|
4848
|
+
"aria-label": `${unit} ${unit === 1 ? "star" : "stars"}`,
|
|
4849
|
+
onClick: () => set(unit === value ? 0 : unit),
|
|
4850
|
+
onMouseEnter: () => setHover(unit),
|
|
4851
|
+
onFocus: () => setHover(unit),
|
|
4852
|
+
onBlur: () => setHover(null),
|
|
4853
|
+
className: "rounded-sm p-0.5 transition-transform hover:scale-110 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/15",
|
|
4854
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
4855
|
+
import_lucide_react20.StarIcon,
|
|
4856
|
+
{
|
|
4857
|
+
className: cn(
|
|
4858
|
+
sizeClass[size],
|
|
4859
|
+
"transition-colors",
|
|
4860
|
+
filled ? "fill-amber-400 text-amber-400" : "fill-transparent text-muted-foreground/40"
|
|
4861
|
+
)
|
|
4862
|
+
}
|
|
4863
|
+
)
|
|
4864
|
+
},
|
|
4865
|
+
i
|
|
4866
|
+
);
|
|
4867
|
+
})
|
|
4868
|
+
}
|
|
4869
|
+
);
|
|
4870
|
+
}
|
|
4871
|
+
|
|
4872
|
+
// src/ui/number-field.tsx
|
|
4873
|
+
var React9 = __toESM(require("react"), 1);
|
|
4874
|
+
var import_lucide_react21 = require("lucide-react");
|
|
4875
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
4876
|
+
var heightClass = { sm: "h-9", default: "h-10" };
|
|
4877
|
+
var stepButtonClass = "inline-flex aspect-square h-full items-center justify-center text-muted-foreground transition-colors hover:bg-accent hover:text-foreground disabled:pointer-events-none disabled:opacity-40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-foreground/15";
|
|
4878
|
+
function clamp(n, min, max) {
|
|
4879
|
+
if (typeof min === "number" && n < min) return min;
|
|
4880
|
+
if (typeof max === "number" && n > max) return max;
|
|
4881
|
+
return n;
|
|
4882
|
+
}
|
|
4883
|
+
function NumberField({
|
|
4884
|
+
value: valueProp,
|
|
4885
|
+
defaultValue = 0,
|
|
4886
|
+
onValueChange,
|
|
4887
|
+
min,
|
|
4888
|
+
max,
|
|
4889
|
+
step = 1,
|
|
4890
|
+
size = "default",
|
|
4891
|
+
disabled,
|
|
4892
|
+
ariaLabel,
|
|
4893
|
+
className,
|
|
4894
|
+
...inputProps
|
|
4895
|
+
}) {
|
|
4896
|
+
const [uncontrolled, setUncontrolled] = React9.useState(defaultValue);
|
|
4897
|
+
const isControlled = valueProp !== void 0;
|
|
4898
|
+
const value = isControlled ? valueProp : uncontrolled;
|
|
4899
|
+
const commit = (next) => {
|
|
4900
|
+
const clamped = clamp(next, min, max);
|
|
4901
|
+
if (!isControlled) setUncontrolled(clamped);
|
|
4902
|
+
onValueChange?.(clamped);
|
|
4903
|
+
};
|
|
4904
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
|
|
4905
|
+
"div",
|
|
4906
|
+
{
|
|
4907
|
+
"data-slot": "number-field",
|
|
4908
|
+
className: cn(
|
|
4909
|
+
controlSurfaceClass,
|
|
4910
|
+
"inline-flex w-full items-stretch overflow-hidden rounded-lg p-0",
|
|
4911
|
+
heightClass[size],
|
|
4912
|
+
disabled && "opacity-50",
|
|
4913
|
+
className
|
|
4914
|
+
),
|
|
4915
|
+
children: [
|
|
4916
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
4917
|
+
"button",
|
|
4918
|
+
{
|
|
4919
|
+
type: "button",
|
|
4920
|
+
tabIndex: -1,
|
|
4921
|
+
"aria-hidden": true,
|
|
4922
|
+
disabled: disabled || typeof min === "number" && value <= min,
|
|
4923
|
+
onClick: () => commit(value - step),
|
|
4924
|
+
className: cn(stepButtonClass, "border-r border-border"),
|
|
4925
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react21.MinusIcon, { className: "size-4" })
|
|
4926
|
+
}
|
|
4927
|
+
),
|
|
4928
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
4929
|
+
"input",
|
|
4930
|
+
{
|
|
4931
|
+
type: "number",
|
|
4932
|
+
inputMode: "decimal",
|
|
4933
|
+
role: "spinbutton",
|
|
4934
|
+
"aria-label": ariaLabel,
|
|
4935
|
+
"aria-valuenow": value,
|
|
4936
|
+
"aria-valuemin": min,
|
|
4937
|
+
"aria-valuemax": max,
|
|
4938
|
+
value: Number.isNaN(value) ? "" : value,
|
|
4939
|
+
disabled,
|
|
4940
|
+
onChange: (e) => {
|
|
4941
|
+
const next = e.target.valueAsNumber;
|
|
4942
|
+
if (Number.isNaN(next)) {
|
|
4943
|
+
if (!isControlled) setUncontrolled(Number.NaN);
|
|
4944
|
+
return;
|
|
4945
|
+
}
|
|
4946
|
+
commit(next);
|
|
4947
|
+
},
|
|
4948
|
+
className: "w-full min-w-0 [appearance:textfield] bg-transparent px-2 text-center text-sm text-foreground outline-none disabled:cursor-not-allowed [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none",
|
|
4949
|
+
...inputProps
|
|
4950
|
+
}
|
|
4951
|
+
),
|
|
4952
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
4953
|
+
"button",
|
|
4954
|
+
{
|
|
4955
|
+
type: "button",
|
|
4956
|
+
tabIndex: -1,
|
|
4957
|
+
"aria-hidden": true,
|
|
4958
|
+
disabled: disabled || typeof max === "number" && value >= max,
|
|
4959
|
+
onClick: () => commit(value + step),
|
|
4960
|
+
className: cn(stepButtonClass, "border-l border-border"),
|
|
4961
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react21.PlusIcon, { className: "size-4" })
|
|
4962
|
+
}
|
|
4963
|
+
)
|
|
4964
|
+
]
|
|
4965
|
+
}
|
|
4966
|
+
);
|
|
4967
|
+
}
|
|
4968
|
+
|
|
4969
|
+
// src/ui/tag-input.tsx
|
|
4970
|
+
var React10 = __toESM(require("react"), 1);
|
|
4971
|
+
var import_lucide_react22 = require("lucide-react");
|
|
4972
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
4973
|
+
function TagInput({
|
|
4974
|
+
value: valueProp,
|
|
4975
|
+
defaultValue = [],
|
|
4976
|
+
onChange,
|
|
4977
|
+
placeholder,
|
|
4978
|
+
separators = ["Enter", ","],
|
|
4979
|
+
dedupe = true,
|
|
4980
|
+
max,
|
|
4981
|
+
disabled,
|
|
4982
|
+
ariaLabel,
|
|
4983
|
+
className,
|
|
4984
|
+
inputClassName
|
|
4985
|
+
}) {
|
|
4986
|
+
const [uncontrolled, setUncontrolled] = React10.useState(defaultValue);
|
|
4987
|
+
const isControlled = valueProp !== void 0;
|
|
4988
|
+
const tags = isControlled ? valueProp : uncontrolled;
|
|
4989
|
+
const [draft, setDraft] = React10.useState("");
|
|
4990
|
+
const setTags = (next) => {
|
|
4991
|
+
if (!isControlled) setUncontrolled(next);
|
|
4992
|
+
onChange?.(next);
|
|
4993
|
+
};
|
|
4994
|
+
const addTag = (raw) => {
|
|
4995
|
+
const tag = raw.trim();
|
|
4996
|
+
if (!tag) return;
|
|
4997
|
+
if (typeof max === "number" && tags.length >= max) return;
|
|
4998
|
+
if (dedupe && tags.some((t) => t.toLowerCase() === tag.toLowerCase())) {
|
|
4999
|
+
setDraft("");
|
|
5000
|
+
return;
|
|
5001
|
+
}
|
|
5002
|
+
setTags([...tags, tag]);
|
|
5003
|
+
setDraft("");
|
|
5004
|
+
};
|
|
5005
|
+
const removeAt = (index) => {
|
|
5006
|
+
setTags(tags.filter((_, i) => i !== index));
|
|
5007
|
+
};
|
|
5008
|
+
const handleKeyDown = (event) => {
|
|
5009
|
+
if (separators.includes(event.key)) {
|
|
5010
|
+
event.preventDefault();
|
|
5011
|
+
addTag(draft);
|
|
5012
|
+
} else if (event.key === "Backspace" && draft === "" && tags.length > 0) {
|
|
5013
|
+
removeAt(tags.length - 1);
|
|
5014
|
+
}
|
|
5015
|
+
};
|
|
5016
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
|
|
5017
|
+
"div",
|
|
5018
|
+
{
|
|
5019
|
+
"data-slot": "tag-input",
|
|
5020
|
+
className: cn(
|
|
5021
|
+
controlSurfaceClass,
|
|
5022
|
+
"flex min-h-10 w-full flex-wrap items-center gap-1.5 rounded-lg px-2 py-1.5",
|
|
5023
|
+
disabled && "pointer-events-none opacity-50",
|
|
5024
|
+
className
|
|
5025
|
+
),
|
|
5026
|
+
children: [
|
|
5027
|
+
tags.map((tag, index) => /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
|
|
5028
|
+
"span",
|
|
5029
|
+
{
|
|
5030
|
+
className: "inline-flex items-center gap-1 rounded-md bg-muted py-0.5 pl-2 pr-1 text-xs font-medium text-foreground",
|
|
5031
|
+
children: [
|
|
5032
|
+
tag,
|
|
5033
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
5034
|
+
"button",
|
|
5035
|
+
{
|
|
5036
|
+
type: "button",
|
|
5037
|
+
"aria-label": `Remove ${tag}`,
|
|
5038
|
+
onClick: () => removeAt(index),
|
|
5039
|
+
className: "inline-flex size-4 items-center justify-center rounded-sm text-muted-foreground transition-colors hover:bg-foreground/10 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/20",
|
|
5040
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react22.XIcon, { className: "size-3", "aria-hidden": true })
|
|
5041
|
+
}
|
|
5042
|
+
)
|
|
5043
|
+
]
|
|
5044
|
+
},
|
|
5045
|
+
`${tag}-${index}`
|
|
5046
|
+
)),
|
|
5047
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
5048
|
+
"input",
|
|
5049
|
+
{
|
|
5050
|
+
type: "text",
|
|
5051
|
+
"aria-label": ariaLabel ?? placeholder ?? "Add tag",
|
|
5052
|
+
value: draft,
|
|
5053
|
+
disabled,
|
|
5054
|
+
placeholder: tags.length === 0 ? placeholder : void 0,
|
|
5055
|
+
onChange: (e) => setDraft(e.target.value),
|
|
5056
|
+
onKeyDown: handleKeyDown,
|
|
5057
|
+
onBlur: () => addTag(draft),
|
|
5058
|
+
className: cn(
|
|
5059
|
+
"min-w-[6rem] flex-1 bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground/70",
|
|
5060
|
+
inputClassName
|
|
5061
|
+
)
|
|
5062
|
+
}
|
|
5063
|
+
)
|
|
5064
|
+
]
|
|
5065
|
+
}
|
|
5066
|
+
);
|
|
5067
|
+
}
|
|
5068
|
+
|
|
5069
|
+
// src/ui/banner.tsx
|
|
5070
|
+
var import_lucide_react23 = require("lucide-react");
|
|
5071
|
+
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
5072
|
+
var bannerToneClass = {
|
|
5073
|
+
default: "border-border bg-muted/50 text-foreground",
|
|
5074
|
+
primary: "border-primary/20 bg-primary/10 text-foreground",
|
|
5075
|
+
success: "border-emerald-500/25 bg-emerald-500/10 text-foreground [&_[data-banner-icon]]:text-emerald-600 dark:[&_[data-banner-icon]]:text-emerald-400",
|
|
5076
|
+
warn: "border-amber-500/25 bg-amber-500/10 text-foreground [&_[data-banner-icon]]:text-amber-600 dark:[&_[data-banner-icon]]:text-amber-400",
|
|
5077
|
+
danger: "border-destructive/25 bg-destructive/10 text-foreground [&_[data-banner-icon]]:text-destructive"
|
|
5078
|
+
};
|
|
5079
|
+
function Banner({
|
|
5080
|
+
tone = "default",
|
|
5081
|
+
icon,
|
|
5082
|
+
title,
|
|
5083
|
+
actions,
|
|
5084
|
+
onDismiss,
|
|
5085
|
+
className,
|
|
5086
|
+
children,
|
|
5087
|
+
...props
|
|
5088
|
+
}) {
|
|
5089
|
+
return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(
|
|
5090
|
+
"div",
|
|
5091
|
+
{
|
|
5092
|
+
"data-slot": "banner",
|
|
5093
|
+
role: "status",
|
|
5094
|
+
className: cn(
|
|
5095
|
+
"flex w-full items-start gap-3 rounded-lg border px-4 py-3 text-sm",
|
|
5096
|
+
bannerToneClass[tone],
|
|
5097
|
+
className
|
|
5098
|
+
),
|
|
5099
|
+
...props,
|
|
5100
|
+
children: [
|
|
5101
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { "data-banner-icon": true, className: "mt-0.5 shrink-0 [&_svg]:size-4", children: icon }) : null,
|
|
5102
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
5103
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "font-medium", children: title }) : null,
|
|
5104
|
+
children ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: cn("text-muted-foreground", title && "mt-0.5"), children }) : null
|
|
5105
|
+
] }),
|
|
5106
|
+
actions ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "flex shrink-0 items-center gap-2", children: actions }) : null,
|
|
5107
|
+
onDismiss ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
5108
|
+
"button",
|
|
5109
|
+
{
|
|
5110
|
+
type: "button",
|
|
5111
|
+
"aria-label": "Dismiss",
|
|
5112
|
+
onClick: onDismiss,
|
|
5113
|
+
className: "-mr-1 -mt-0.5 inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-foreground/10 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/15",
|
|
5114
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_lucide_react23.XIcon, { className: "size-4", "aria-hidden": true })
|
|
5115
|
+
}
|
|
5116
|
+
) : null
|
|
5117
|
+
]
|
|
5118
|
+
}
|
|
5119
|
+
);
|
|
5120
|
+
}
|
|
5121
|
+
|
|
5122
|
+
// src/ui/copy-button.tsx
|
|
5123
|
+
var React11 = __toESM(require("react"), 1);
|
|
5124
|
+
var import_lucide_react24 = require("lucide-react");
|
|
5125
|
+
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
5126
|
+
function CopyButton({
|
|
5127
|
+
value,
|
|
5128
|
+
timeout = 1500,
|
|
5129
|
+
onCopied,
|
|
5130
|
+
className,
|
|
5131
|
+
children,
|
|
5132
|
+
onClick,
|
|
5133
|
+
...props
|
|
5134
|
+
}) {
|
|
5135
|
+
const [copied, setCopied] = React11.useState(false);
|
|
5136
|
+
const timer = React11.useRef(void 0);
|
|
5137
|
+
React11.useEffect(() => () => clearTimeout(timer.current), []);
|
|
5138
|
+
const handleClick = async (event) => {
|
|
5139
|
+
onClick?.(event);
|
|
5140
|
+
if (event.defaultPrevented) return;
|
|
5141
|
+
try {
|
|
5142
|
+
await navigator.clipboard.writeText(value);
|
|
5143
|
+
setCopied(true);
|
|
5144
|
+
onCopied?.(value);
|
|
5145
|
+
clearTimeout(timer.current);
|
|
5146
|
+
timer.current = setTimeout(() => setCopied(false), timeout);
|
|
5147
|
+
} catch {
|
|
5148
|
+
}
|
|
5149
|
+
};
|
|
5150
|
+
const Icon = copied ? import_lucide_react24.CheckIcon : import_lucide_react24.CopyIcon;
|
|
5151
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
|
|
5152
|
+
"button",
|
|
5153
|
+
{
|
|
5154
|
+
type: "button",
|
|
5155
|
+
"data-slot": "copy-button",
|
|
5156
|
+
"data-copied": copied || void 0,
|
|
5157
|
+
"aria-label": copied ? "Copied" : "Copy",
|
|
5158
|
+
onClick: handleClick,
|
|
5159
|
+
className: cn(
|
|
5160
|
+
"inline-flex items-center justify-center gap-1.5 rounded-md text-sm font-medium text-muted-foreground transition-colors",
|
|
5161
|
+
"hover:bg-accent hover:text-foreground data-[copied=true]:text-emerald-600 dark:data-[copied=true]:text-emerald-400",
|
|
5162
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-foreground/15",
|
|
5163
|
+
children ? "h-8 px-2" : "size-8",
|
|
5164
|
+
className
|
|
5165
|
+
),
|
|
5166
|
+
...props,
|
|
5167
|
+
children: [
|
|
5168
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Icon, { className: "size-4 shrink-0", "aria-hidden": true }),
|
|
5169
|
+
children
|
|
5170
|
+
]
|
|
5171
|
+
}
|
|
5172
|
+
);
|
|
5173
|
+
}
|
|
5174
|
+
|
|
5175
|
+
// src/ui/snippet.tsx
|
|
5176
|
+
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
5177
|
+
function Snippet({
|
|
5178
|
+
children,
|
|
5179
|
+
symbol,
|
|
5180
|
+
hideCopy = false,
|
|
5181
|
+
className,
|
|
5182
|
+
...props
|
|
5183
|
+
}) {
|
|
5184
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
|
|
5185
|
+
"div",
|
|
5186
|
+
{
|
|
5187
|
+
"data-slot": "snippet",
|
|
5188
|
+
className: cn(
|
|
5189
|
+
"flex items-center gap-2 rounded-lg border border-border bg-muted/40 py-1.5 pl-3 pr-1.5 font-mono text-sm",
|
|
5190
|
+
className
|
|
5191
|
+
),
|
|
5192
|
+
...props,
|
|
5193
|
+
children: [
|
|
5194
|
+
symbol ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { "aria-hidden": true, className: "select-none text-muted-foreground", children: symbol }) : null,
|
|
5195
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("code", { className: "min-w-0 flex-1 truncate text-foreground", children }),
|
|
5196
|
+
hideCopy ? null : /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(CopyButton, { value: children, className: "size-7 shrink-0" })
|
|
5197
|
+
]
|
|
5198
|
+
}
|
|
5199
|
+
);
|
|
5200
|
+
}
|
|
5201
|
+
|
|
5202
|
+
// src/ui/circular-progress.tsx
|
|
5203
|
+
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
5204
|
+
var toneClass = {
|
|
5205
|
+
primary: "text-primary",
|
|
5206
|
+
success: "text-emerald-500",
|
|
5207
|
+
warn: "text-amber-500",
|
|
5208
|
+
danger: "text-destructive"
|
|
5209
|
+
};
|
|
5210
|
+
function CircularProgress({
|
|
5211
|
+
value = 0,
|
|
5212
|
+
max = 100,
|
|
5213
|
+
size = 40,
|
|
5214
|
+
thickness = 4,
|
|
5215
|
+
showLabel = false,
|
|
5216
|
+
label,
|
|
5217
|
+
tone = "primary",
|
|
5218
|
+
className,
|
|
5219
|
+
...props
|
|
5220
|
+
}) {
|
|
5221
|
+
const indeterminate = value === null || value === void 0;
|
|
5222
|
+
const radius = (size - thickness) / 2;
|
|
5223
|
+
const circumference = 2 * Math.PI * radius;
|
|
5224
|
+
const pct = indeterminate ? 0.25 : Math.min(Math.max(value / max, 0), 1);
|
|
5225
|
+
const dashOffset = circumference * (1 - pct);
|
|
5226
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
|
|
5227
|
+
"div",
|
|
5228
|
+
{
|
|
5229
|
+
"data-slot": "circular-progress",
|
|
5230
|
+
role: "progressbar",
|
|
5231
|
+
"aria-valuenow": indeterminate ? void 0 : Math.round(pct * 100),
|
|
5232
|
+
"aria-valuemin": 0,
|
|
5233
|
+
"aria-valuemax": 100,
|
|
5234
|
+
className: cn("relative inline-flex shrink-0", className),
|
|
5235
|
+
style: { width: size, height: size },
|
|
5236
|
+
...props,
|
|
5237
|
+
children: [
|
|
5238
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
|
|
5239
|
+
"svg",
|
|
5240
|
+
{
|
|
5241
|
+
width: size,
|
|
5242
|
+
height: size,
|
|
5243
|
+
viewBox: `0 0 ${size} ${size}`,
|
|
5244
|
+
className: cn(toneClass[tone], indeterminate && "animate-spin"),
|
|
5245
|
+
children: [
|
|
5246
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
5247
|
+
"circle",
|
|
5248
|
+
{
|
|
5249
|
+
cx: size / 2,
|
|
5250
|
+
cy: size / 2,
|
|
5251
|
+
r: radius,
|
|
5252
|
+
fill: "none",
|
|
5253
|
+
strokeWidth: thickness,
|
|
5254
|
+
className: "stroke-current opacity-15"
|
|
5255
|
+
}
|
|
5256
|
+
),
|
|
5257
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
5258
|
+
"circle",
|
|
5259
|
+
{
|
|
5260
|
+
cx: size / 2,
|
|
5261
|
+
cy: size / 2,
|
|
5262
|
+
r: radius,
|
|
5263
|
+
fill: "none",
|
|
5264
|
+
strokeWidth: thickness,
|
|
5265
|
+
strokeLinecap: "round",
|
|
5266
|
+
strokeDasharray: circumference,
|
|
5267
|
+
strokeDashoffset: dashOffset,
|
|
5268
|
+
transform: `rotate(-90 ${size / 2} ${size / 2})`,
|
|
5269
|
+
className: cn("stroke-current", !indeterminate && "transition-[stroke-dashoffset] duration-500")
|
|
5270
|
+
}
|
|
5271
|
+
)
|
|
5272
|
+
]
|
|
5273
|
+
}
|
|
5274
|
+
),
|
|
5275
|
+
showLabel && !indeterminate ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "absolute inset-0 flex items-center justify-center text-[0.7rem] font-medium tabular-nums text-foreground", children: label ?? `${Math.round(pct * 100)}%` }) : null
|
|
5276
|
+
]
|
|
5277
|
+
}
|
|
5278
|
+
);
|
|
5279
|
+
}
|
|
4581
5280
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4582
5281
|
0 && (module.exports = {
|
|
4583
5282
|
AVATAR_PRIMARY_FALLBACK_CLASS,
|
|
@@ -4602,8 +5301,10 @@ var MemoPillSegmentedTabs = (0, import_react3.memo)(PillSegmentedTabs);
|
|
|
4602
5301
|
AspectRatio,
|
|
4603
5302
|
Avatar,
|
|
4604
5303
|
AvatarFallback,
|
|
5304
|
+
AvatarGroup,
|
|
4605
5305
|
AvatarImage,
|
|
4606
5306
|
Badge,
|
|
5307
|
+
Banner,
|
|
4607
5308
|
Breadcrumb,
|
|
4608
5309
|
BreadcrumbEllipsis,
|
|
4609
5310
|
BreadcrumbItem,
|
|
@@ -4628,6 +5329,7 @@ var MemoPillSegmentedTabs = (0, import_react3.memo)(PillSegmentedTabs);
|
|
|
4628
5329
|
ChartTooltip,
|
|
4629
5330
|
ChartTooltipContent,
|
|
4630
5331
|
Checkbox,
|
|
5332
|
+
CircularProgress,
|
|
4631
5333
|
Collapsible,
|
|
4632
5334
|
CollapsibleContent,
|
|
4633
5335
|
CollapsibleTrigger,
|
|
@@ -4666,6 +5368,7 @@ var MemoPillSegmentedTabs = (0, import_react3.memo)(PillSegmentedTabs);
|
|
|
4666
5368
|
ContextMenuSubContent,
|
|
4667
5369
|
ContextMenuSubTrigger,
|
|
4668
5370
|
ContextMenuTrigger,
|
|
5371
|
+
CopyButton,
|
|
4669
5372
|
DatePicker,
|
|
4670
5373
|
DatePickerButton,
|
|
4671
5374
|
DatePickerCalendar,
|
|
@@ -4741,6 +5444,7 @@ var MemoPillSegmentedTabs = (0, import_react3.memo)(PillSegmentedTabs);
|
|
|
4741
5444
|
NavigationMenuList,
|
|
4742
5445
|
NavigationMenuTrigger,
|
|
4743
5446
|
NavigationMenuViewport,
|
|
5447
|
+
NumberField,
|
|
4744
5448
|
Pagination,
|
|
4745
5449
|
PaginationContent,
|
|
4746
5450
|
PaginationEllipsis,
|
|
@@ -4756,6 +5460,7 @@ var MemoPillSegmentedTabs = (0, import_react3.memo)(PillSegmentedTabs);
|
|
|
4756
5460
|
Progress,
|
|
4757
5461
|
RadioGroup,
|
|
4758
5462
|
RadioGroupItem,
|
|
5463
|
+
Rating,
|
|
4759
5464
|
ScrollArea,
|
|
4760
5465
|
ScrollBar,
|
|
4761
5466
|
Select,
|
|
@@ -4780,7 +5485,9 @@ var MemoPillSegmentedTabs = (0, import_react3.memo)(PillSegmentedTabs);
|
|
|
4780
5485
|
Shimmer,
|
|
4781
5486
|
Skeleton,
|
|
4782
5487
|
Slider,
|
|
5488
|
+
Snippet,
|
|
4783
5489
|
Spinner,
|
|
5490
|
+
Stepper,
|
|
4784
5491
|
Switch,
|
|
4785
5492
|
Table,
|
|
4786
5493
|
TableBody,
|
|
@@ -4790,8 +5497,10 @@ var MemoPillSegmentedTabs = (0, import_react3.memo)(PillSegmentedTabs);
|
|
|
4790
5497
|
TableHead,
|
|
4791
5498
|
TableHeader,
|
|
4792
5499
|
TableRow,
|
|
5500
|
+
TagInput,
|
|
4793
5501
|
Textarea,
|
|
4794
5502
|
TimbalV2Button,
|
|
5503
|
+
Timeline,
|
|
4795
5504
|
Toast,
|
|
4796
5505
|
ToastAction,
|
|
4797
5506
|
ToastClose,
|