@neasg/design-system 0.4.7 → 0.4.9
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/README.md +121 -0
- package/dist/alert.d.ts +21 -2
- package/dist/alert.js +10 -3
- package/dist/avatar.d.ts +5 -2
- package/dist/avatar.js +76 -8
- package/dist/back-button.d.ts +2 -0
- package/dist/back-button.js +1 -1
- package/dist/badge.d.ts +3 -2
- package/dist/badge.js +9 -3
- package/dist/breadcrumb.js +2 -1
- package/dist/button.d.ts +1 -1
- package/dist/button.js +13 -10
- package/dist/calendar.js +10 -9
- package/dist/card.d.ts +29 -1
- package/dist/card.js +61 -7
- package/dist/checkbox.d.ts +2 -0
- package/dist/checkbox.js +2 -2
- package/dist/close-button.d.ts +6 -0
- package/dist/close-button.js +8 -0
- package/dist/collapsible.d.ts +7 -1
- package/dist/collapsible.js +2 -2
- package/dist/command-search.d.ts +16 -1
- package/dist/command-search.js +42 -16
- package/dist/command.js +3 -3
- package/dist/copy-button.d.ts +3 -1
- package/dist/copy-button.js +4 -2
- package/dist/count-badge.d.ts +3 -1
- package/dist/count-badge.js +10 -5
- package/dist/date-input.d.ts +18 -3
- package/dist/date-input.js +94 -21
- package/dist/dialog-primitive.js +4 -3
- package/dist/draggable-tabs.d.ts +7 -0
- package/dist/draggable-tabs.js +6 -5
- package/dist/drawer.js +2 -2
- package/dist/dropdown-button.d.ts +18 -0
- package/dist/dropdown-button.js +31 -0
- package/dist/edit-button.d.ts +10 -0
- package/dist/edit-button.js +7 -0
- package/dist/editable-table.d.ts +3 -1
- package/dist/editable-table.js +25 -12
- package/dist/field.d.ts +2 -2
- package/dist/field.js +4 -3
- package/dist/file-upload-status-toast.d.ts +28 -0
- package/dist/file-upload-status-toast.js +136 -0
- package/dist/file-upload.js +8 -7
- package/dist/filter-popover.d.ts +37 -0
- package/dist/filter-popover.js +73 -0
- package/dist/filter-toggle.js +2 -2
- package/dist/index.d.ts +45 -14
- package/dist/index.js +19 -4
- package/dist/input-control.d.ts +3 -2
- package/dist/input-control.js +3 -2
- package/dist/label-value-grid.d.ts +4 -2
- package/dist/label-value-grid.js +7 -6
- package/dist/label-value.js +3 -1
- package/dist/layout-right-panel-edge.d.ts +6 -0
- package/dist/layout-right-panel-edge.js +6 -0
- package/dist/layout.d.ts +77 -5
- package/dist/layout.js +439 -35
- package/dist/lib/date-utils.d.ts +10 -2
- package/dist/lib/date-utils.js +91 -11
- package/dist/lib/utils.js +8 -1
- package/dist/link.js +2 -2
- package/dist/message-item.d.ts +62 -0
- package/dist/message-item.js +148 -0
- package/dist/multi-select.js +31 -5
- package/dist/notification.d.ts +82 -0
- package/dist/notification.js +121 -0
- package/dist/otp-input.js +1 -1
- package/dist/page-header.js +1 -1
- package/dist/page-section.d.ts +2 -1
- package/dist/page-section.js +4 -3
- package/dist/pagination.js +2 -2
- package/dist/popover-menu.d.ts +23 -1
- package/dist/popover-menu.js +75 -5
- package/dist/popover-primitive.js +1 -1
- package/dist/progress.d.ts +5 -2
- package/dist/progress.js +6 -3
- package/dist/radio-group.d.ts +21 -0
- package/dist/radio-group.js +41 -0
- package/dist/rich-text-editor.d.ts +56 -0
- package/dist/rich-text-editor.js +394 -0
- package/dist/routing-timeline.d.ts +22 -0
- package/dist/routing-timeline.js +58 -0
- package/dist/scroll-hint.d.ts +8 -0
- package/dist/scroll-hint.js +7 -0
- package/dist/search-input-shell.js +1 -1
- package/dist/search-input.js +2 -2
- package/dist/section-nav.js +4 -4
- package/dist/select-primitive.js +3 -3
- package/dist/select.js +1 -1
- package/dist/skeleton.js +1 -1
- package/dist/styles.css +235 -57
- package/dist/table-column-visibility.d.ts +21 -0
- package/dist/table-column-visibility.js +74 -0
- package/dist/table-toolbar.js +1 -1
- package/dist/table.d.ts +12 -1
- package/dist/table.js +67 -33
- package/dist/tabs.d.ts +14 -3
- package/dist/tabs.js +60 -6
- package/dist/tailwind-preset.js +46 -0
- package/dist/task-mode-shell.d.ts +24 -0
- package/dist/task-mode-shell.js +110 -0
- package/dist/textarea.js +2 -1
- package/dist/theme-switcher.d.ts +28 -0
- package/dist/theme-switcher.js +27 -0
- package/dist/theme.d.ts +167 -0
- package/dist/theme.js +112 -0
- package/dist/toaster.js +5 -4
- package/dist/tooltip.js +1 -1
- package/dist/typography.d.ts +1 -1
- package/dist/typography.js +5 -5
- package/dist/workspace-header.d.ts +13 -0
- package/dist/workspace-header.js +11 -0
- package/package.json +15 -1
package/dist/date-input.js
CHANGED
|
@@ -2,26 +2,41 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { format, parse } from "date-fns";
|
|
5
|
+
import { CalendarIcon } from "lucide-react";
|
|
5
6
|
import { Calendar } from "./calendar";
|
|
6
7
|
import { inputControlClassName } from "./input-control";
|
|
7
8
|
import { Field, FieldDescription, FieldError, FieldLabel } from "./field";
|
|
8
9
|
import { PopoverContent, PopoverRoot, PopoverTrigger } from "./popover-primitive";
|
|
9
10
|
import { cn } from "./lib/utils";
|
|
11
|
+
function createLocalDate(year, monthIndex, day) {
|
|
12
|
+
const date = new Date(year, monthIndex, day);
|
|
13
|
+
if (date.getFullYear() !== year ||
|
|
14
|
+
date.getMonth() !== monthIndex ||
|
|
15
|
+
date.getDate() !== day) {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
return date;
|
|
19
|
+
}
|
|
10
20
|
function parseDateString(dateStr) {
|
|
11
21
|
if (!(dateStr === null || dateStr === void 0 ? void 0 : dateStr.trim()))
|
|
12
22
|
return undefined;
|
|
13
23
|
try {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
24
|
+
const normalizedDateStr = dateStr.trim();
|
|
25
|
+
const isoDateMatch = normalizedDateStr.match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/);
|
|
26
|
+
if (isoDateMatch) {
|
|
27
|
+
const [, year, month, day] = isoDateMatch;
|
|
28
|
+
return createLocalDate(parseInt(year, 10), parseInt(month, 10) - 1, parseInt(day, 10));
|
|
29
|
+
}
|
|
30
|
+
const ddmmyyyyMatch = normalizedDateStr.match(/^(\d{1,2})\/(\d{1,2})\/(\d{4})/);
|
|
18
31
|
if (ddmmyyyyMatch) {
|
|
19
32
|
const [, day, month, year] = ddmmyyyyMatch;
|
|
20
|
-
|
|
21
|
-
if (!isNaN(date.getTime()))
|
|
22
|
-
return date;
|
|
33
|
+
return createLocalDate(parseInt(year, 10), parseInt(month, 10) - 1, parseInt(day, 10));
|
|
23
34
|
}
|
|
24
|
-
const
|
|
35
|
+
const nativeDate = new Date(normalizedDateStr);
|
|
36
|
+
if (!isNaN(nativeDate.getTime())) {
|
|
37
|
+
return nativeDate;
|
|
38
|
+
}
|
|
39
|
+
const date = parse(normalizedDateStr, "yyyy-MM-dd", new Date());
|
|
25
40
|
if (!isNaN(date.getTime()))
|
|
26
41
|
return date;
|
|
27
42
|
return undefined;
|
|
@@ -33,7 +48,51 @@ function parseDateString(dateStr) {
|
|
|
33
48
|
function formatISODate(date) {
|
|
34
49
|
return format(date, "yyyy-MM-dd");
|
|
35
50
|
}
|
|
36
|
-
|
|
51
|
+
function formatDisplayDate(date) {
|
|
52
|
+
return format(date, "d MMM yyyy");
|
|
53
|
+
}
|
|
54
|
+
function getDateTime(date) {
|
|
55
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
|
|
56
|
+
}
|
|
57
|
+
function isDateOutsideBounds(date, minDate, maxDate) {
|
|
58
|
+
const dateTime = getDateTime(date);
|
|
59
|
+
if (minDate && dateTime < getDateTime(minDate))
|
|
60
|
+
return true;
|
|
61
|
+
if (maxDate && dateTime > getDateTime(maxDate))
|
|
62
|
+
return true;
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
function parseDateRangeValue(value) {
|
|
66
|
+
const from = parseDateString(value.from);
|
|
67
|
+
const to = parseDateString(value.to);
|
|
68
|
+
if (!from && !to)
|
|
69
|
+
return undefined;
|
|
70
|
+
return { from, to };
|
|
71
|
+
}
|
|
72
|
+
function formatDateRangeValue(range) {
|
|
73
|
+
if (!(range === null || range === void 0 ? void 0 : range.from) && !(range === null || range === void 0 ? void 0 : range.to)) {
|
|
74
|
+
return {};
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
...(range.from ? { from: formatISODate(range.from) } : {}),
|
|
78
|
+
...(range.to ? { to: formatISODate(range.to) } : {}),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function formatDisplayRange(range) {
|
|
82
|
+
if ((range === null || range === void 0 ? void 0 : range.from) && range.to) {
|
|
83
|
+
return `${formatDisplayDate(range.from)} - ${formatDisplayDate(range.to)}`;
|
|
84
|
+
}
|
|
85
|
+
if (range === null || range === void 0 ? void 0 : range.from) {
|
|
86
|
+
return `${formatDisplayDate(range.from)} -`;
|
|
87
|
+
}
|
|
88
|
+
if (range === null || range === void 0 ? void 0 : range.to) {
|
|
89
|
+
return `- ${formatDisplayDate(range.to)}`;
|
|
90
|
+
}
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
const DateInput = React.forwardRef((props, ref) => {
|
|
94
|
+
var _a, _b, _c;
|
|
95
|
+
const { label, appearance = "field", description, error, invalid = false, hideLabel = false, disabled = false, minDate, maxDate, className, triggerClassName, labelClassName, descriptionClassName, errorClassName, id, } = props;
|
|
37
96
|
const [open, setOpen] = React.useState(false);
|
|
38
97
|
const generatedId = React.useId();
|
|
39
98
|
const inputId = id !== null && id !== void 0 ? id : `date-input-${generatedId}`;
|
|
@@ -41,21 +100,35 @@ const DateInput = React.forwardRef(({ label, value, onValueChange, description,
|
|
|
41
100
|
const showDescription = Boolean(description) && !error;
|
|
42
101
|
const descriptionId = showDescription ? `${inputId}-description` : undefined;
|
|
43
102
|
const isInvalid = invalid || Boolean(error);
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
103
|
+
const isRange = props.mode === "range";
|
|
104
|
+
const selectedDate = React.useMemo(() => (isRange ? undefined : parseDateString(props.value)), [isRange, props.value]);
|
|
105
|
+
const selectedRange = React.useMemo(() => (isRange ? parseDateRangeValue(props.value) : undefined), [isRange, props.value]);
|
|
106
|
+
const displayValue = isRange
|
|
107
|
+
? formatDisplayRange(selectedRange)
|
|
108
|
+
: selectedDate
|
|
109
|
+
? formatDisplayDate(selectedDate)
|
|
110
|
+
: undefined;
|
|
111
|
+
const placeholder = (_a = props.placeholder) !== null && _a !== void 0 ? _a : (isRange ? "Pick range" : "Pick a date");
|
|
48
112
|
const handleSelect = (date) => {
|
|
49
|
-
|
|
113
|
+
if (props.mode === "range")
|
|
114
|
+
return;
|
|
115
|
+
props.onValueChange(date ? formatISODate(date) : "");
|
|
50
116
|
setOpen(false);
|
|
51
117
|
};
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
118
|
+
const handleRangeSelect = (range) => {
|
|
119
|
+
if (props.mode !== "range")
|
|
120
|
+
return;
|
|
121
|
+
props.onValueChange(formatDateRangeValue(range));
|
|
122
|
+
if ((range === null || range === void 0 ? void 0 : range.from) && range.to) {
|
|
123
|
+
setOpen(false);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
const disabledDays = (date) => isDateOutsideBounds(date, minDate, maxDate);
|
|
127
|
+
const calendarContent = (_jsx(PopoverContent, { className: "w-auto p-0", align: "start", children: props.mode === "range" ? (_jsx(Calendar, { mode: "range", selected: selectedRange, onSelect: handleRangeSelect, disabled: disabledDays, defaultMonth: (_b = selectedRange === null || selectedRange === void 0 ? void 0 : selectedRange.from) !== null && _b !== void 0 ? _b : selectedRange === null || selectedRange === void 0 ? void 0 : selectedRange.to, numberOfMonths: (_c = props.numberOfMonths) !== null && _c !== void 0 ? _c : 2, autoFocus: true })) : (_jsx(Calendar, { mode: "single", selected: selectedDate, onSelect: handleSelect, disabled: disabledDays, defaultMonth: selectedDate, autoFocus: true })) }));
|
|
128
|
+
if (appearance === "inline") {
|
|
129
|
+
return (_jsxs("span", { className: cn("inline-flex", className), "data-disabled": disabled ? "true" : undefined, "data-invalid": isInvalid ? "true" : undefined, children: [_jsxs(PopoverRoot, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { ref: ref, type: "button", id: inputId, disabled: disabled, "aria-invalid": isInvalid ? "true" : undefined, "aria-describedby": [descriptionId, errorId].filter(Boolean).join(" ") || undefined, className: cn("inline-flex cursor-pointer items-baseline rounded-sm border-0 bg-transparent p-0 font-medium text-primary underline decoration-primary/40 underline-offset-4 transition-colors hover:decoration-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50", !displayValue && "text-muted-foreground decoration-border", isInvalid && "text-destructive decoration-destructive", triggerClassName), children: [_jsxs("span", { className: "sr-only", children: [label, ": "] }), _jsx("span", { children: displayValue !== null && displayValue !== void 0 ? displayValue : placeholder })] }) }), calendarContent] }), showDescription ? (_jsx("span", { id: descriptionId, className: "sr-only", children: description })) : null, error ? (_jsx("span", { id: errorId, role: "alert", className: "sr-only", children: error })) : null] }));
|
|
130
|
+
}
|
|
131
|
+
return (_jsxs(Field, { className: className, "data-disabled": disabled ? "true" : undefined, "data-invalid": isInvalid ? "true" : undefined, children: [_jsx(FieldLabel, { htmlFor: inputId, className: cn(hideLabel && "sr-only", labelClassName), children: label }), _jsxs(PopoverRoot, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs("button", { ref: ref, type: "button", id: inputId, disabled: disabled, "aria-invalid": isInvalid ? "true" : undefined, "aria-describedby": [descriptionId, errorId].filter(Boolean).join(" ") || undefined, className: cn(inputControlClassName, "relative cursor-pointer pr-9 text-left", !displayValue && "text-muted-foreground", isInvalid && "border-destructive focus-visible:ring-destructive", triggerClassName), children: [_jsx("span", { className: "block truncate", children: displayValue !== null && displayValue !== void 0 ? displayValue : placeholder }), _jsx(CalendarIcon, { "aria-hidden": "true", className: "pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground", strokeWidth: 2 })] }) }), calendarContent] }), showDescription ? (_jsx(FieldDescription, { id: descriptionId, className: descriptionClassName, children: description })) : null, _jsx(FieldError, { id: errorId, className: errorClassName, children: error })] }));
|
|
59
132
|
});
|
|
60
133
|
DateInput.displayName = "DateInput";
|
|
61
134
|
export { DateInput };
|
package/dist/dialog-primitive.js
CHANGED
|
@@ -4,20 +4,21 @@ import * as React from "react";
|
|
|
4
4
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
5
5
|
import { XIcon } from "./animated-icons/x";
|
|
6
6
|
import { cn } from "./lib/utils";
|
|
7
|
+
import { typographyVariants } from "./typography";
|
|
7
8
|
const DialogRoot = DialogPrimitive.Root;
|
|
8
9
|
const DialogTrigger = DialogPrimitive.Trigger;
|
|
9
10
|
const DialogPortal = DialogPrimitive.Portal;
|
|
10
11
|
const DialogClose = DialogPrimitive.Close;
|
|
11
12
|
const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => (_jsx(DialogPrimitive.Overlay, { ref: ref, className: cn("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", className), ...props })));
|
|
12
13
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
13
|
-
const DialogSurface = React.forwardRef(({ className, children, hideCloseButton, ...props }, ref) => (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { ref: ref, className: cn("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-
|
|
14
|
+
const DialogSurface = React.forwardRef(({ className, children, hideCloseButton, ...props }, ref) => (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { ref: ref, className: cn("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-3 border bg-background p-4 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-overlay", className), ...props, children: [children, !hideCloseButton ? (_jsxs(DialogPrimitive.Close, { className: "absolute right-2 top-2 flex h-6 w-6 cursor-pointer items-center justify-center rounded-control text-muted-foreground ring-offset-background transition-colors hover:bg-accent hover:text-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none", children: [_jsx(XIcon, { size: 16 }), _jsx("span", { className: "sr-only", children: "Close" })] })) : null] })] })));
|
|
14
15
|
DialogSurface.displayName = DialogPrimitive.Content.displayName;
|
|
15
16
|
const DialogHeader = ({ className, ...props }) => (_jsx("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props }));
|
|
16
17
|
DialogHeader.displayName = "DialogHeader";
|
|
17
18
|
const DialogFooter = ({ className, ...props }) => (_jsx("div", { className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className), ...props }));
|
|
18
19
|
DialogFooter.displayName = "DialogFooter";
|
|
19
|
-
const DialogTitle = React.forwardRef(({ className, ...props }, ref) => (_jsx(DialogPrimitive.Title, { ref: ref, className: cn(
|
|
20
|
+
const DialogTitle = React.forwardRef(({ className, ...props }, ref) => (_jsx(DialogPrimitive.Title, { ref: ref, className: cn(typographyVariants({ variant: "subheading" }), className), ...props })));
|
|
20
21
|
DialogTitle.displayName = DialogPrimitive.Title.displayName;
|
|
21
|
-
const DialogDescription = React.forwardRef(({ className, ...props }, ref) => (_jsx(DialogPrimitive.Description, { ref: ref, className: cn("
|
|
22
|
+
const DialogDescription = React.forwardRef(({ className, ...props }, ref) => (_jsx(DialogPrimitive.Description, { ref: ref, className: cn(typographyVariants({ variant: "bodySm" }), "text-muted-foreground", className), ...props })));
|
|
22
23
|
DialogDescription.displayName = DialogPrimitive.Description.displayName;
|
|
23
24
|
export { DialogRoot, DialogPortal, DialogOverlay, DialogTrigger, DialogClose, DialogSurface, DialogHeader, DialogFooter, DialogTitle, DialogDescription, };
|
package/dist/draggable-tabs.d.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
import { type BadgeProps } from "./badge";
|
|
2
3
|
import { type TooltipProps } from "./tooltip";
|
|
4
|
+
export interface DraggableTabBadge {
|
|
5
|
+
label: React.ReactNode;
|
|
6
|
+
variant?: BadgeProps["variant"];
|
|
7
|
+
bordered?: BadgeProps["bordered"];
|
|
8
|
+
}
|
|
3
9
|
export interface DraggableTabItem {
|
|
4
10
|
id: string;
|
|
5
11
|
label: React.ReactNode;
|
|
6
12
|
active?: boolean;
|
|
7
13
|
disabled?: boolean;
|
|
14
|
+
badge?: DraggableTabBadge;
|
|
8
15
|
leading?: React.ReactNode;
|
|
9
16
|
trailing?: React.ReactNode;
|
|
10
17
|
tooltip?: React.ReactNode;
|
package/dist/draggable-tabs.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors, } from "@dnd-kit/core";
|
|
4
4
|
import { SortableContext, horizontalListSortingStrategy, sortableKeyboardCoordinates, useSortable, } from "@dnd-kit/sortable";
|
|
5
5
|
import { CSS } from "@dnd-kit/utilities";
|
|
6
6
|
import { XIcon } from "./animated-icons/x";
|
|
7
|
+
import { Badge } from "./badge";
|
|
7
8
|
import { cn } from "./lib/utils";
|
|
8
9
|
import { Tooltip } from "./tooltip";
|
|
9
10
|
function TabButton({ item, dragHandleProps, }) {
|
|
@@ -14,13 +15,13 @@ function TabButton({ item, dragHandleProps, }) {
|
|
|
14
15
|
: item.active
|
|
15
16
|
? "text-foreground"
|
|
16
17
|
: "text-muted-foreground hover:text-foreground";
|
|
17
|
-
const content = (_jsxs("div", { className: cn("group flex items-center gap-
|
|
18
|
+
const content = (_jsxs("div", { className: cn("group flex items-center gap-1.5 border-b-2 px-2.5 transition-colors select-none", item.disabled
|
|
18
19
|
? "cursor-not-allowed opacity-50"
|
|
19
20
|
: isDraggable
|
|
20
21
|
? "cursor-grab active:cursor-grabbing"
|
|
21
22
|
: "cursor-pointer", item.active
|
|
22
|
-
? (_a = item.activeClassName) !== null && _a !== void 0 ? _a : "border-
|
|
23
|
-
: (_b = item.inactiveClassName) !== null && _b !== void 0 ? _b : "border-transparent hover:bg-
|
|
23
|
+
? (_a = item.activeClassName) !== null && _a !== void 0 ? _a : "border-[hsl(var(--tab-indicator))] bg-transparent hover:bg-transparent"
|
|
24
|
+
: (_b = item.inactiveClassName) !== null && _b !== void 0 ? _b : "border-transparent hover:bg-[hsl(var(--tab-trigger-hover-background))]", item.className), ...dragHandleProps, children: [_jsxs("button", { type: "button", onClick: item.disabled ? undefined : item.onSelect, disabled: item.disabled, className: cn("flex cursor-pointer items-center gap-1.5 py-2 pr-1 text-sm font-medium whitespace-nowrap disabled:cursor-not-allowed", labelClassName), children: [item.badge ? (_jsx(Badge, { variant: item.badge.variant, bordered: item.badge.bordered, size: "icon", children: item.badge.label })) : null, item.leading, item.label, item.trailing] }), item.onClose ? (_jsx("button", { type: "button", onClick: (event) => {
|
|
24
25
|
var _a;
|
|
25
26
|
event.stopPropagation();
|
|
26
27
|
(_a = item.onClose) === null || _a === void 0 ? void 0 : _a.call(item);
|
|
@@ -56,6 +57,6 @@ function DraggableTabs({ staticTabs = [], tabs, onReorder, className, ...props }
|
|
|
56
57
|
onReorder(oldIndex, newIndex);
|
|
57
58
|
}
|
|
58
59
|
};
|
|
59
|
-
return (_jsxs("div", { className: cn("flex items-end gap-1 border-b overflow-x-auto overflow-y-hidden bg-
|
|
60
|
+
return (_jsxs("div", { "data-slot": "draggable-tabs", className: cn("flex items-end gap-1 border-b overflow-x-auto overflow-y-hidden bg-transparent", "border-[hsl(var(--layout-surface-border))]", className), ...props, children: [staticTabs.map((tab) => (_jsx(TabButton, { item: tab }, tab.id))), _jsx(DndContext, { sensors: sensors, collisionDetection: closestCenter, onDragEnd: handleDragEnd, children: _jsx(SortableContext, { items: tabs.map((tab) => tab.id), strategy: horizontalListSortingStrategy, children: tabs.map((tab) => (_jsx(SortableTab, { item: tab }, tab.id))) }) })] }));
|
|
60
61
|
}
|
|
61
62
|
export { DraggableTabs };
|
package/dist/drawer.js
CHANGED
|
@@ -34,7 +34,7 @@ function renderDrawerAction({ action, close, defaultVariant, }) {
|
|
|
34
34
|
}
|
|
35
35
|
}, children: label }));
|
|
36
36
|
}
|
|
37
|
-
const drawerSurfaceVariants = cva("fixed z-50 flex flex-col gap-
|
|
37
|
+
const drawerSurfaceVariants = cva("fixed z-50 flex flex-col gap-3 overflow-y-auto bg-background p-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out", {
|
|
38
38
|
variants: {
|
|
39
39
|
side: {
|
|
40
40
|
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-lg",
|
|
@@ -46,7 +46,7 @@ const drawerSurfaceVariants = cva("fixed z-50 flex flex-col gap-4 overflow-y-aut
|
|
|
46
46
|
},
|
|
47
47
|
});
|
|
48
48
|
function DrawerSurface({ side, className, children, hideCloseButton, ...props }) {
|
|
49
|
-
return (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { className: cn(drawerSurfaceVariants({ side }), className), ...props, children: [children, !hideCloseButton ? (_jsxs(DialogPrimitive.Close, { className: "absolute right-2 top-2 flex h-6 w-6 cursor-pointer items-center justify-center rounded-
|
|
49
|
+
return (_jsxs(DialogPortal, { children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { className: cn(drawerSurfaceVariants({ side }), className), ...props, children: [children, !hideCloseButton ? (_jsxs(DialogPrimitive.Close, { className: "absolute right-2 top-2 flex h-6 w-6 cursor-pointer items-center justify-center rounded-control text-muted-foreground ring-offset-background transition-colors hover:bg-accent hover:text-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none", children: [_jsx(XIcon, { size: 16 }), _jsx("span", { className: "sr-only", children: "Close" })] })) : null] })] }));
|
|
50
50
|
}
|
|
51
51
|
function Drawer({ open, defaultOpen, onOpenChange, modal, trigger, title, description, children, footer, primaryAction, secondaryAction, side = "right", contentClassName, bodyClassName, hideCloseButton, }) {
|
|
52
52
|
const [isOpen, setIsOpen] = useControllableOpen({
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type ButtonProps } from "./button";
|
|
3
|
+
import { type PopoverProps } from "./popover";
|
|
4
|
+
type DropdownButtonPopoverProps = Pick<PopoverProps, "align" | "alignOffset" | "avoidCollisions" | "collisionPadding" | "defaultOpen" | "hideWhenDetached" | "modal" | "onOpenChange" | "open" | "side" | "sideOffset" | "sticky">;
|
|
5
|
+
export interface DropdownButtonProps extends Omit<ButtonProps, "children">, DropdownButtonPopoverProps {
|
|
6
|
+
label: React.ReactNode;
|
|
7
|
+
leadingIcon?: React.ReactNode;
|
|
8
|
+
children: React.ReactNode;
|
|
9
|
+
contentClassName?: string;
|
|
10
|
+
dropdownAriaLabel?: string;
|
|
11
|
+
menuWidth?: "trigger" | "content";
|
|
12
|
+
/**
|
|
13
|
+
* Renders separate primary and menu triggers. Set `false` to keep one popover trigger even when `onClick` is provided.
|
|
14
|
+
*/
|
|
15
|
+
split?: boolean;
|
|
16
|
+
}
|
|
17
|
+
declare function DropdownButton({ label, leadingIcon, children, className, contentClassName, dropdownAriaLabel, menuWidth, align, alignOffset, avoidCollisions, collisionPadding, defaultOpen, disabled, hideWhenDetached, loading, loadingIndicator, loadingText, modal, onClick, onOpenChange, open, side, sideOffset, split: splitProp, sticky, type, variant, size, ...buttonProps }: DropdownButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export { DropdownButton };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ChevronDownIcon } from "./animated-icons";
|
|
4
|
+
import { Button } from "./button";
|
|
5
|
+
import { Popover } from "./popover";
|
|
6
|
+
import { PopoverAnchor, PopoverContent, PopoverRoot, PopoverTrigger, } from "./popover-primitive";
|
|
7
|
+
import { cn } from "./lib/utils";
|
|
8
|
+
const splitButtonDividerClassNames = {
|
|
9
|
+
default: "before:bg-primary-foreground/30",
|
|
10
|
+
destructive: "before:bg-destructive-foreground/30",
|
|
11
|
+
outline: "before:bg-[hsl(var(--button-outline-border))]",
|
|
12
|
+
secondary: "before:bg-secondary-foreground/20",
|
|
13
|
+
ghost: "before:bg-border",
|
|
14
|
+
link: "before:bg-primary/25",
|
|
15
|
+
};
|
|
16
|
+
function DropdownButton({ label, leadingIcon, children, className, contentClassName, dropdownAriaLabel, menuWidth = "trigger", align = "end", alignOffset, avoidCollisions, collisionPadding, defaultOpen, disabled, hideWhenDetached, loading, loadingIndicator, loadingText, modal, onClick, onOpenChange, open, side, sideOffset = 4, split: splitProp, sticky, type = "button", variant, size, ...buttonProps }) {
|
|
17
|
+
const menuContentClassName = cn("shadow-overlay-strong border-border/80 bg-popover ring-1 ring-border/50", menuWidth === "trigger" &&
|
|
18
|
+
"w-[var(--radix-popover-trigger-width)] min-w-56", contentClassName);
|
|
19
|
+
const labelContent = (_jsxs("span", { className: "inline-flex min-w-0 items-center gap-1.5", children: [leadingIcon ? (_jsx("span", { className: "inline-flex shrink-0 items-center", children: leadingIcon })) : null, _jsx("span", { className: "truncate", children: label })] }));
|
|
20
|
+
const menuButtonLabel = dropdownAriaLabel !== null && dropdownAriaLabel !== void 0 ? dropdownAriaLabel : (typeof label === "string" ? `${label} menu` : "Open menu");
|
|
21
|
+
const menuButtonSizeClassName = size === "sm" || size === "compact" || size === "compactIcon"
|
|
22
|
+
? "w-8"
|
|
23
|
+
: "w-control";
|
|
24
|
+
const resolvedVariant = variant !== null && variant !== void 0 ? variant : "default";
|
|
25
|
+
const split = splitProp !== null && splitProp !== void 0 ? splitProp : Boolean(onClick);
|
|
26
|
+
if (split) {
|
|
27
|
+
return (_jsxs(PopoverRoot, { defaultOpen: defaultOpen, modal: modal, onOpenChange: onOpenChange, open: open, children: [_jsx(PopoverAnchor, { asChild: true, children: _jsxs("div", { className: cn("inline-flex items-stretch", className), children: [_jsx(Button, { type: type, variant: variant, size: size, className: cn("min-w-0 flex-1 justify-start rounded-r-none", variant === "outline" && "border-r-0"), disabled: disabled, loading: loading, loadingIndicator: loadingIndicator, loadingText: loadingText, onClick: onClick, ...buttonProps, children: labelContent }), _jsx(PopoverTrigger, { asChild: true, children: _jsx(Button, { type: "button", variant: variant, size: size, "aria-label": menuButtonLabel, className: cn("relative shrink-0 rounded-l-none px-0 before:absolute before:inset-y-0 before:left-0 before:w-px before:content-['']", menuButtonSizeClassName, splitButtonDividerClassNames[resolvedVariant], variant === "outline" && "border-l-0"), disabled: disabled || loading, children: _jsx(ChevronDownIcon, { size: 14 }) }) })] }) }), _jsx(PopoverContent, { align: align, alignOffset: alignOffset, avoidCollisions: avoidCollisions, collisionPadding: collisionPadding, hideWhenDetached: hideWhenDetached, side: side, sideOffset: sideOffset, sticky: sticky, className: cn("overflow-hidden p-1", menuContentClassName), children: children })] }));
|
|
28
|
+
}
|
|
29
|
+
return (_jsx(Popover, { surface: "menu", align: align, alignOffset: alignOffset, avoidCollisions: avoidCollisions, collisionPadding: collisionPadding, defaultOpen: defaultOpen, hideWhenDetached: hideWhenDetached, modal: modal, onOpenChange: onOpenChange, open: open, side: side, sideOffset: sideOffset, sticky: sticky, contentClassName: menuContentClassName, trigger: _jsxs(Button, { type: type, variant: variant, size: size, className: cn("justify-between", className), disabled: disabled, loading: loading, loadingIndicator: loadingIndicator, loadingText: loadingText, onClick: onClick, ...buttonProps, children: [labelContent, _jsx(ChevronDownIcon, { className: "ml-auto", size: 14 })] }), children: children }));
|
|
30
|
+
}
|
|
31
|
+
export { DropdownButton };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type ButtonProps } from "./button";
|
|
3
|
+
export interface EditButtonProps extends Omit<ButtonProps, "children" | "size" | "variant"> {
|
|
4
|
+
label?: React.ReactNode;
|
|
5
|
+
targetLabel?: string;
|
|
6
|
+
size?: Extract<ButtonProps["size"], "sm" | "compact" | "default">;
|
|
7
|
+
variant?: Extract<ButtonProps["variant"], "outline" | "ghost" | "secondary">;
|
|
8
|
+
}
|
|
9
|
+
declare function EditButton({ label, targetLabel, size, variant, "aria-label": ariaLabel, ...props }: EditButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export { EditButton };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { PencilIcon } from "./animated-icons";
|
|
3
|
+
import { Button } from "./button";
|
|
4
|
+
function EditButton({ label = "Edit", targetLabel, size = "compact", variant = "outline", "aria-label": ariaLabel, ...props }) {
|
|
5
|
+
return (_jsxs(Button, { variant: variant, size: size, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : (targetLabel ? `Edit ${targetLabel}` : undefined), ...props, children: [_jsx(PencilIcon, { size: 14 }), label] }));
|
|
6
|
+
}
|
|
7
|
+
export { EditButton };
|
package/dist/editable-table.d.ts
CHANGED
|
@@ -23,10 +23,12 @@ export interface EditableTableProps {
|
|
|
23
23
|
className?: string;
|
|
24
24
|
emptyPlaceholder?: string;
|
|
25
25
|
checkable?: boolean;
|
|
26
|
+
checkableHeader?: React.ReactNode;
|
|
26
27
|
activeField?: string;
|
|
28
|
+
addRowLabel?: React.ReactNode;
|
|
27
29
|
renderRowActions?: (context: EditableTableRowActionContext) => React.ReactNode;
|
|
28
30
|
}
|
|
29
|
-
declare function EditableTable({ value, onChange, columns, isEditing, className, emptyPlaceholder, checkable, activeField, renderRowActions, }: EditableTableProps): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
declare function EditableTable({ value, onChange, columns, isEditing, className, emptyPlaceholder, checkable, checkableHeader, activeField, addRowLabel, renderRowActions, }: EditableTableProps): import("react/jsx-runtime").JSX.Element;
|
|
30
32
|
declare namespace EditableTable {
|
|
31
33
|
var displayName: string;
|
|
32
34
|
}
|
package/dist/editable-table.js
CHANGED
|
@@ -4,6 +4,7 @@ import { Button } from "./button";
|
|
|
4
4
|
import { PlusIcon } from "./animated-icons/plus";
|
|
5
5
|
import { TrashIcon } from "./animated-icons/trash";
|
|
6
6
|
import { Checkbox } from "./checkbox";
|
|
7
|
+
import { EmptyState } from "./empty-state";
|
|
7
8
|
import { InputControl } from "./input-control";
|
|
8
9
|
import { TableRoot as Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "./table";
|
|
9
10
|
import { cn } from "./lib/utils";
|
|
@@ -32,7 +33,7 @@ function setNestedValue(obj, path, value) {
|
|
|
32
33
|
current[parts[parts.length - 1]] = value;
|
|
33
34
|
return result;
|
|
34
35
|
}
|
|
35
|
-
function EditableTable({ value, onChange, columns, isEditing = false, className, emptyPlaceholder = "
|
|
36
|
+
function EditableTable({ value, onChange, columns, isEditing = false, className, emptyPlaceholder = "Enter text...", checkable = false, checkableHeader, activeField = "active", addRowLabel = "Add Row", renderRowActions, }) {
|
|
36
37
|
const [editingCell, setEditingCell] = React.useState(null);
|
|
37
38
|
const [editValue, setEditValue] = React.useState("");
|
|
38
39
|
const inputRef = React.useRef(null);
|
|
@@ -48,8 +49,12 @@ function EditableTable({ value, onChange, columns, isEditing = false, className,
|
|
|
48
49
|
if (!isEditing) {
|
|
49
50
|
return;
|
|
50
51
|
}
|
|
52
|
+
if ((editingCell === null || editingCell === void 0 ? void 0 : editingCell.rowIndex) === rowIndex &&
|
|
53
|
+
(editingCell === null || editingCell === void 0 ? void 0 : editingCell.colPath) === colPath) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
51
56
|
const cellValue = getNestedValue(value[rowIndex], colPath);
|
|
52
|
-
setEditValue(cellValue
|
|
57
|
+
setEditValue(isEmptyCellValue(cellValue) ? "" : String(cellValue));
|
|
53
58
|
setEditingCell({ rowIndex, colPath });
|
|
54
59
|
};
|
|
55
60
|
const commitEdit = () => {
|
|
@@ -102,27 +107,35 @@ function EditableTable({ value, onChange, columns, isEditing = false, className,
|
|
|
102
107
|
};
|
|
103
108
|
onChange(nextRows);
|
|
104
109
|
}, [activeField, onChange, value]);
|
|
110
|
+
const isEmptyCellValue = (cellValue) => cellValue === null ||
|
|
111
|
+
cellValue === undefined ||
|
|
112
|
+
cellValue === "" ||
|
|
113
|
+
(typeof cellValue === "string" && cellValue.trim() === "-");
|
|
105
114
|
const formatCellValue = (cellValue) => {
|
|
106
|
-
if (cellValue
|
|
107
|
-
return
|
|
115
|
+
if (isEmptyCellValue(cellValue)) {
|
|
116
|
+
return "";
|
|
108
117
|
}
|
|
109
118
|
return String(cellValue);
|
|
110
119
|
};
|
|
111
120
|
const hasActionsColumn = isEditing || Boolean(renderRowActions);
|
|
112
|
-
|
|
121
|
+
const checkableColumnWidth = checkableHeader ? "9rem" : "48px";
|
|
122
|
+
return (_jsxs("div", { className: cn("space-y-2", className), children: [_jsx("div", { className: "overflow-x-auto rounded-surface border", children: _jsxs(Table, { children: [_jsx(TableHeader, { children: _jsxs(TableRow, { children: [checkable ? (_jsx(TableHead, { width: checkableColumnWidth, minWidth: checkableColumnWidth, children: checkableHeader })) : null, columns.map((column, index) => (_jsx(TableHead, { width: column.width, minWidth: getColumnMinWidth(column), children: _jsx("div", { className: "whitespace-nowrap", children: column.header }) }, `header-${index}`))), hasActionsColumn ? (_jsx(TableHead, { width: renderRowActions ? undefined : "72px", minWidth: renderRowActions ? "120px" : "72px" })) : null] }) }), _jsx(TableBody, { children: value.length === 0 ? (_jsx(TableRow, { children: _jsx(TableCell, { colSpan: columns.length +
|
|
113
123
|
(checkable ? 1 : 0) +
|
|
114
|
-
(hasActionsColumn ? 1 : 0), className: "
|
|
124
|
+
(hasActionsColumn ? 1 : 0), className: "p-0", children: _jsx(EmptyState, { message: "No data available", description: "There are no rows to display in this table yet.", className: "border-0 bg-transparent px-0 py-[var(--space-6)]" }) }) })) : (value.map((row, rowIndex) => (_jsxs(TableRow, { className: rowIndex % 2 === 0
|
|
125
|
+
? "bg-[hsl(var(--table-row-striped-background))]"
|
|
126
|
+
: undefined, children: [checkable ? (_jsx(TableCell, { width: checkableColumnWidth, minWidth: checkableColumnWidth, children: _jsx("div", { className: "flex items-center", onClick: (event) => event.stopPropagation(), children: _jsx(Checkbox, { checked: Boolean(row[activeField]), disabled: !isEditing, onChange: isEditing
|
|
115
127
|
? (event) => handleToggleRow(rowIndex, event.currentTarget.checked)
|
|
116
128
|
: undefined }) }) })) : null, columns.map((column, columnIndex) => {
|
|
117
129
|
const cellValue = getNestedValue(row, column.path);
|
|
130
|
+
const isEmptyCell = isEmptyCellValue(cellValue);
|
|
118
131
|
const isEditingCell = (editingCell === null || editingCell === void 0 ? void 0 : editingCell.rowIndex) === rowIndex &&
|
|
119
132
|
(editingCell === null || editingCell === void 0 ? void 0 : editingCell.colPath) === column.path;
|
|
120
|
-
return (_jsx(TableCell, { className: cn("whitespace-normal", isEditing && "cursor-pointer hover:bg-muted/50"), width: column.width, minWidth: getColumnMinWidth(column), maxWidth: getColumnMaxWidth(column), onClick: () => handleCellClick(rowIndex, column.path), children: isEditingCell ? (_jsx(InputControl, { ref: inputRef, value: editValue, onChange: (event) => setEditValue(event.target.value), onBlur: commitEdit, onKeyDown: handleKeyDown, className: "h-
|
|
121
|
-
cellValue === undefined ||
|
|
122
|
-
cellValue === ""
|
|
133
|
+
return (_jsx(TableCell, { className: cn("whitespace-normal", isEditing && "cursor-pointer hover:bg-muted/50"), width: column.width, minWidth: getColumnMinWidth(column), maxWidth: getColumnMaxWidth(column), onClick: () => handleCellClick(rowIndex, column.path), children: isEditingCell ? (_jsx("div", { className: "flex min-h-8 items-center", children: _jsx(InputControl, { ref: inputRef, value: editValue, placeholder: emptyPlaceholder, onChange: (event) => setEditValue(event.target.value), onClick: (event) => event.stopPropagation(), onBlur: commitEdit, onKeyDown: handleKeyDown, className: "h-8 w-full px-2 py-1 text-sm" }) })) : (_jsx("span", { className: cn("flex min-h-8 items-center whitespace-normal break-words", isEmptyCell
|
|
123
134
|
? "text-muted-foreground"
|
|
124
|
-
: undefined), style: { maxWidth: getColumnMaxWidth(column) }, children:
|
|
125
|
-
|
|
135
|
+
: undefined), style: { maxWidth: getColumnMaxWidth(column) }, children: isEmptyCell && isEditing
|
|
136
|
+
? emptyPlaceholder
|
|
137
|
+
: formatCellValue(cellValue) })) }, `cell-${rowIndex}-${columnIndex}`));
|
|
138
|
+
}), hasActionsColumn ? (_jsx(TableCell, { width: renderRowActions ? undefined : "72px", minWidth: renderRowActions ? "120px" : "72px", children: _jsxs("div", { className: "flex min-h-8 items-center justify-end gap-1", children: [renderRowActions
|
|
126
139
|
? renderRowActions({
|
|
127
140
|
row,
|
|
128
141
|
rowIndex,
|
|
@@ -132,7 +145,7 @@ function EditableTable({ value, onChange, columns, isEditing = false, className,
|
|
|
132
145
|
insertRow: (nextRow, index = rowIndex + 1) => handleInsertRow(nextRow, index),
|
|
133
146
|
removeRow: () => handleDeleteRow(rowIndex),
|
|
134
147
|
})
|
|
135
|
-
: null, isEditing ? (_jsx(Button, { type: "button", variant: "ghost", size: "
|
|
148
|
+
: null, isEditing ? (_jsx(Button, { type: "button", variant: "ghost", size: "compactIcon", className: "text-muted-foreground hover:bg-destructive/10 hover:text-destructive focus-visible:text-destructive", onClick: () => handleDeleteRow(rowIndex), "aria-label": `Delete row ${rowIndex + 1}`, children: _jsx(TrashIcon, { size: 16 }) })) : null] }) })) : null] }, `row-${rowIndex}`)))) })] }) }), isEditing ? (_jsxs(Button, { type: "button", variant: "outline", onClick: handleAddRow, className: "w-full justify-center", children: [_jsx(PlusIcon, { size: 16 }), addRowLabel] })) : null] }));
|
|
136
149
|
}
|
|
137
150
|
EditableTable.displayName = "EditableTable";
|
|
138
151
|
export { EditableTable };
|
package/dist/field.d.ts
CHANGED
|
@@ -4,6 +4,6 @@ interface FieldLabelProps extends React.ComponentProps<"label"> {
|
|
|
4
4
|
required?: boolean;
|
|
5
5
|
}
|
|
6
6
|
declare function FieldLabel({ className, required, children, ...props }: FieldLabelProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
-
declare function FieldDescription({ className, ...props }: React.ComponentProps<"p">): import("react/jsx-runtime").JSX.Element;
|
|
8
|
-
declare function FieldError({ className, ...props }: React.ComponentProps<"p">): import("react/jsx-runtime").JSX.Element | null;
|
|
7
|
+
declare function FieldDescription({ className, ...props }: Omit<React.ComponentProps<"p">, "color">): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
declare function FieldError({ className, ...props }: Omit<React.ComponentProps<"p">, "color">): import("react/jsx-runtime").JSX.Element | null;
|
|
9
9
|
export { Field, FieldDescription, FieldError, FieldLabel };
|
package/dist/field.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from "./lib/utils";
|
|
3
|
+
import { Typography } from "./typography";
|
|
3
4
|
function Field({ className, ...props }) {
|
|
4
5
|
return (_jsx("div", { "data-slot": "field", className: cn("group/field flex w-full flex-col gap-2", className), ...props }));
|
|
5
6
|
}
|
|
6
7
|
function FieldLabel({ className, required, children, ...props }) {
|
|
7
|
-
return (
|
|
8
|
+
return (_jsx(Typography, { asChild: true, variant: "label", className: cn("group-data-[disabled=true]/field:cursor-not-allowed group-data-[disabled=true]/field:opacity-50 group-data-[invalid=true]/field:text-destructive", className), children: _jsxs("label", { "data-slot": "field-label", ...props, children: [children, required ? (_jsx("span", { "aria-hidden": "true", className: "ml-0.5 text-destructive", children: "*" })) : null] }) }));
|
|
8
9
|
}
|
|
9
10
|
function FieldDescription({ className, ...props }) {
|
|
10
|
-
return (_jsx("p",
|
|
11
|
+
return (_jsx(Typography, { as: "p", variant: "bodySm", color: "muted", "data-slot": "field-description", className: className, ...props }));
|
|
11
12
|
}
|
|
12
13
|
function FieldError({ className, ...props }) {
|
|
13
14
|
if (!props.children) {
|
|
14
15
|
return null;
|
|
15
16
|
}
|
|
16
|
-
return (_jsx("p",
|
|
17
|
+
return (_jsx(Typography, { as: "p", variant: "bodySm", role: "alert", "data-slot": "field-error", className: cn("text-destructive", className), ...props }));
|
|
17
18
|
}
|
|
18
19
|
export { Field, FieldDescription, FieldError, FieldLabel };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { FileUploadProgress, FileUploadResult, FileUploadStatus } from "./use-file-upload";
|
|
3
|
+
export interface FileUploadStatusToastFile {
|
|
4
|
+
name: string;
|
|
5
|
+
size?: number | string;
|
|
6
|
+
type?: string;
|
|
7
|
+
progress?: number;
|
|
8
|
+
status?: FileUploadStatus;
|
|
9
|
+
error?: string;
|
|
10
|
+
result?: FileUploadResult;
|
|
11
|
+
}
|
|
12
|
+
export interface FileUploadStatusToastProps {
|
|
13
|
+
files: FileUploadStatusToastFile[];
|
|
14
|
+
uploadProgress?: Map<string, FileUploadProgress> | FileUploadProgress[];
|
|
15
|
+
title?: React.ReactNode;
|
|
16
|
+
description?: React.ReactNode;
|
|
17
|
+
className?: string;
|
|
18
|
+
onCancel?: (file: FileUploadStatusToastFile) => void;
|
|
19
|
+
onRemove?: (file: FileUploadStatusToastFile) => void;
|
|
20
|
+
onDismiss?: () => void;
|
|
21
|
+
}
|
|
22
|
+
export interface ShowFileUploadStatusToastOptions extends FileUploadStatusToastProps {
|
|
23
|
+
id?: string | number;
|
|
24
|
+
duration?: number;
|
|
25
|
+
dismissible?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare function FileUploadStatusToast({ files, uploadProgress, title, description, className, onCancel, onRemove, onDismiss, }: FileUploadStatusToastProps): import("react/jsx-runtime").JSX.Element;
|
|
28
|
+
export declare function showFileUploadStatusToast({ id, duration, dismissible, onDismiss, ...props }: ShowFileUploadStatusToastOptions): string | number;
|