@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
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { AlertCircle, CheckCircle2, Paperclip, Trash2, X, } from "lucide-react";
|
|
4
|
+
import { Button } from "./button";
|
|
5
|
+
import { cn } from "./lib/utils";
|
|
6
|
+
import { Progress } from "./progress";
|
|
7
|
+
import { toast } from "./toaster";
|
|
8
|
+
import { Typography } from "./typography";
|
|
9
|
+
const DEFAULT_TOAST_ID = "file-upload-status";
|
|
10
|
+
function formatUploadFileSize(size) {
|
|
11
|
+
if (typeof size === "string")
|
|
12
|
+
return size;
|
|
13
|
+
if (typeof size !== "number")
|
|
14
|
+
return "";
|
|
15
|
+
if (size === 0)
|
|
16
|
+
return "0 B";
|
|
17
|
+
const k = 1024;
|
|
18
|
+
const sizes = ["B", "KB", "MB", "GB"];
|
|
19
|
+
const i = Math.min(Math.floor(Math.log(size) / Math.log(k)), sizes.length - 1);
|
|
20
|
+
return `${parseFloat((size / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
|
|
21
|
+
}
|
|
22
|
+
function getProgress(uploadProgress, fileName) {
|
|
23
|
+
if (!uploadProgress)
|
|
24
|
+
return undefined;
|
|
25
|
+
if (Array.isArray(uploadProgress)) {
|
|
26
|
+
return uploadProgress.find((progress) => progress.name === fileName);
|
|
27
|
+
}
|
|
28
|
+
return uploadProgress.get(fileName);
|
|
29
|
+
}
|
|
30
|
+
function normalizeFiles({ files, uploadProgress, }) {
|
|
31
|
+
return files.map((file) => {
|
|
32
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
33
|
+
const progress = getProgress(uploadProgress, file.name);
|
|
34
|
+
const result = (_a = progress === null || progress === void 0 ? void 0 : progress.result) !== null && _a !== void 0 ? _a : file.result;
|
|
35
|
+
return {
|
|
36
|
+
...file,
|
|
37
|
+
progress: (_c = (_b = progress === null || progress === void 0 ? void 0 : progress.progress) !== null && _b !== void 0 ? _b : file.progress) !== null && _c !== void 0 ? _c : 0,
|
|
38
|
+
status: (_e = (_d = progress === null || progress === void 0 ? void 0 : progress.status) !== null && _d !== void 0 ? _d : file.status) !== null && _e !== void 0 ? _e : "pending",
|
|
39
|
+
error: (_f = progress === null || progress === void 0 ? void 0 : progress.error) !== null && _f !== void 0 ? _f : file.error,
|
|
40
|
+
result,
|
|
41
|
+
size: (_g = result === null || result === void 0 ? void 0 : result.size) !== null && _g !== void 0 ? _g : file.size,
|
|
42
|
+
type: (_h = result === null || result === void 0 ? void 0 : result.type) !== null && _h !== void 0 ? _h : file.type,
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
function pluralize(count, singular, plural = `${singular}s`) {
|
|
47
|
+
return `${count} ${count === 1 ? singular : plural}`;
|
|
48
|
+
}
|
|
49
|
+
function getDefaultTitle(files) {
|
|
50
|
+
const failed = files.filter((file) => file.status === "error").length;
|
|
51
|
+
const uploading = files.filter((file) => file.status === "pending" || file.status === "uploading").length;
|
|
52
|
+
const complete = files.filter((file) => file.status === "complete").length;
|
|
53
|
+
if (failed > 0)
|
|
54
|
+
return `${pluralize(failed, "file")} failed to upload`;
|
|
55
|
+
if (uploading > 0)
|
|
56
|
+
return `Uploading ${pluralize(files.length, "file")}`;
|
|
57
|
+
if (complete === files.length && files.length > 0) {
|
|
58
|
+
return `Uploaded ${pluralize(files.length, "file")}`;
|
|
59
|
+
}
|
|
60
|
+
return "File upload status";
|
|
61
|
+
}
|
|
62
|
+
function getDefaultDescription(files) {
|
|
63
|
+
const complete = files.filter((file) => file.status === "complete").length;
|
|
64
|
+
const failed = files.filter((file) => file.status === "error").length;
|
|
65
|
+
const uploading = files.filter((file) => file.status === "uploading").length;
|
|
66
|
+
const pending = files.filter((file) => file.status === "pending").length;
|
|
67
|
+
const parts = [
|
|
68
|
+
complete > 0 ? `${complete} complete` : null,
|
|
69
|
+
uploading > 0 ? `${uploading} uploading` : null,
|
|
70
|
+
pending > 0 ? `${pending} pending` : null,
|
|
71
|
+
failed > 0 ? `${failed} failed` : null,
|
|
72
|
+
].filter(Boolean);
|
|
73
|
+
return parts.length > 0 ? parts.join(" / ") : undefined;
|
|
74
|
+
}
|
|
75
|
+
function getStatusIcon(status) {
|
|
76
|
+
if (status === "complete") {
|
|
77
|
+
return (_jsx(CheckCircle2, { "aria-hidden": "true", className: "h-4 w-4 text-[hsl(var(--status-success-foreground))]" }));
|
|
78
|
+
}
|
|
79
|
+
if (status === "error") {
|
|
80
|
+
return (_jsx(AlertCircle, { "aria-hidden": "true", className: "h-4 w-4 text-[hsl(var(--status-destructive-foreground))]" }));
|
|
81
|
+
}
|
|
82
|
+
return (_jsx(Paperclip, { "aria-hidden": "true", className: "h-4 w-4 text-muted-foreground" }));
|
|
83
|
+
}
|
|
84
|
+
function FileUploadStatusRow({ file, onCancel, onRemove, }) {
|
|
85
|
+
var _a;
|
|
86
|
+
const isUploading = file.status === "uploading";
|
|
87
|
+
const isPending = file.status === "pending";
|
|
88
|
+
const isComplete = file.status === "complete";
|
|
89
|
+
const isError = file.status === "error";
|
|
90
|
+
const sizeLabel = formatUploadFileSize(file.size);
|
|
91
|
+
const canCancel = (isUploading || isPending) && onCancel;
|
|
92
|
+
const canRemove = (isComplete || isError) && onRemove;
|
|
93
|
+
const action = canCancel ? "cancel" : canRemove ? "remove" : null;
|
|
94
|
+
return (_jsxs("li", { className: cn("rounded-control border bg-background px-2.5 py-2", isError && "border-destructive/80 bg-destructive/5"), children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx("span", { className: "mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center", children: getStatusIcon(file.status) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx(Typography, { as: "p", variant: "label", className: cn("truncate", isComplete && "text-[hsl(var(--status-success-foreground))]"), title: file.name, children: file.name }), isError ? (_jsx(Typography, { as: "p", variant: "bodySm", className: "mt-0.5 text-destructive", children: (_a = file.error) !== null && _a !== void 0 ? _a : "Upload failed" })) : null] }), sizeLabel ? (_jsx(Typography, { as: "span", variant: "bodySm", className: "shrink-0 text-muted-foreground", children: sizeLabel })) : null, action ? (_jsx(Button, { type: "button", variant: "ghost", size: "compactIcon", className: "h-7 w-7 shrink-0", onClick: () => {
|
|
95
|
+
if (action === "cancel") {
|
|
96
|
+
onCancel === null || onCancel === void 0 ? void 0 : onCancel(file);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
onRemove === null || onRemove === void 0 ? void 0 : onRemove(file);
|
|
100
|
+
}
|
|
101
|
+
}, "aria-label": action === "cancel"
|
|
102
|
+
? `Cancel upload for ${file.name}`
|
|
103
|
+
: `Remove ${file.name}`, children: action === "cancel" ? (_jsx(X, { "aria-hidden": "true" })) : (_jsx(Trash2, { "aria-hidden": "true" })) })) : null] }), (isUploading || isPending) ? (_jsx(Progress, { className: "mt-2", value: file.progress, size: "sm", label: `Uploading ${file.name}` })) : null] }));
|
|
104
|
+
}
|
|
105
|
+
export function FileUploadStatusToast({ files, uploadProgress, title, description, className, onCancel, onRemove, onDismiss, }) {
|
|
106
|
+
const normalizedFiles = normalizeFiles({ files, uploadProgress });
|
|
107
|
+
const resolvedTitle = title !== null && title !== void 0 ? title : getDefaultTitle(normalizedFiles);
|
|
108
|
+
const resolvedDescription = description !== null && description !== void 0 ? description : getDefaultDescription(normalizedFiles);
|
|
109
|
+
return (_jsxs("section", { className: cn("w-[min(40rem,calc(100vw-2rem))] overflow-hidden rounded-overlay border border-border bg-background text-foreground shadow-overlay", className), "aria-label": "File upload status", children: [_jsxs("div", { className: "flex items-start gap-3 border-b px-3 py-2.5", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx(Typography, { as: "p", variant: "label", className: "truncate", children: resolvedTitle }), resolvedDescription ? (_jsx(Typography, { as: "p", variant: "caption", className: "mt-0.5", children: resolvedDescription })) : null] }), onDismiss ? (_jsx(Button, { type: "button", variant: "ghost", size: "compactIcon", className: "h-7 w-7 shrink-0", onClick: onDismiss, "aria-label": "Dismiss file upload status", children: _jsx(X, { "aria-hidden": "true" }) })) : null] }), _jsx("ul", { className: "max-h-80 space-y-2 overflow-y-auto p-2.5", children: normalizedFiles.map((file, index) => {
|
|
110
|
+
var _a;
|
|
111
|
+
return (_jsx(FileUploadStatusRow, { file: file, onCancel: onCancel, onRemove: onRemove }, `${file.name}-${(_a = file.size) !== null && _a !== void 0 ? _a : "unknown"}-${index}`));
|
|
112
|
+
}) })] }));
|
|
113
|
+
}
|
|
114
|
+
export function showFileUploadStatusToast({ id = DEFAULT_TOAST_ID, duration = Number.POSITIVE_INFINITY, dismissible = true, onDismiss, ...props }) {
|
|
115
|
+
if (props.files.length === 0) {
|
|
116
|
+
toast.dismiss(id);
|
|
117
|
+
onDismiss === null || onDismiss === void 0 ? void 0 : onDismiss();
|
|
118
|
+
return id;
|
|
119
|
+
}
|
|
120
|
+
return toast.custom((toastId) => (_jsx(FileUploadStatusToast, { ...props, onDismiss: dismissible
|
|
121
|
+
? () => {
|
|
122
|
+
toast.dismiss(toastId);
|
|
123
|
+
onDismiss === null || onDismiss === void 0 ? void 0 : onDismiss();
|
|
124
|
+
}
|
|
125
|
+
: undefined })), {
|
|
126
|
+
id,
|
|
127
|
+
duration,
|
|
128
|
+
dismissible,
|
|
129
|
+
onDismiss,
|
|
130
|
+
classNames: {
|
|
131
|
+
toast: "!block !rounded-none !border-0 !bg-transparent !p-0 !pr-0 !shadow-none",
|
|
132
|
+
content: "!block !min-w-0 !flex-none !gap-0",
|
|
133
|
+
title: "!block !font-normal !leading-normal !text-foreground",
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
}
|
package/dist/file-upload.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { useCallback, useState } from "react";
|
|
5
|
-
import { File, ImageIcon } from "lucide-react";
|
|
5
|
+
import { File as FileIcon, ImageIcon } from "lucide-react";
|
|
6
6
|
import { CheckIcon } from "./animated-icons/check";
|
|
7
7
|
import { FileTextIcon } from "./animated-icons/file-text";
|
|
8
8
|
import { UploadIcon } from "./animated-icons/upload";
|
|
@@ -10,6 +10,7 @@ import { XIcon } from "./animated-icons/x";
|
|
|
10
10
|
import { Button } from "./button";
|
|
11
11
|
import { cn } from "./lib/utils";
|
|
12
12
|
import { Progress } from "./progress";
|
|
13
|
+
import { Typography } from "./typography";
|
|
13
14
|
const DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024;
|
|
14
15
|
function formatFileSize(bytes) {
|
|
15
16
|
if (bytes === 0)
|
|
@@ -21,12 +22,12 @@ function formatFileSize(bytes) {
|
|
|
21
22
|
}
|
|
22
23
|
function getFileIcon(file) {
|
|
23
24
|
if (file.type.startsWith("image/")) {
|
|
24
|
-
return _jsx(ImageIcon, { className: "h-4 w-4 text-
|
|
25
|
+
return _jsx(ImageIcon, { className: "h-4 w-4 text-muted-foreground" });
|
|
25
26
|
}
|
|
26
27
|
if (file.type === "application/pdf") {
|
|
27
|
-
return _jsx(FileTextIcon, { className: "text-
|
|
28
|
+
return _jsx(FileTextIcon, { className: "text-muted-foreground", size: 16 });
|
|
28
29
|
}
|
|
29
|
-
return _jsx(
|
|
30
|
+
return _jsx(FileIcon, { className: "h-4 w-4 text-muted-foreground" });
|
|
30
31
|
}
|
|
31
32
|
export function FileUpload({ accept, maxSize = DEFAULT_MAX_FILE_SIZE, maxFiles = 10, onFilesChange, value = [], disabled = false, className, uploadProgress, }) {
|
|
32
33
|
const [isDragOver, setIsDragOver] = useState(false);
|
|
@@ -89,15 +90,15 @@ export function FileUpload({ accept, maxSize = DEFAULT_MAX_FILE_SIZE, maxFiles =
|
|
|
89
90
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
90
91
|
}, []);
|
|
91
92
|
const fileInput = (_jsx("input", { ref: inputRef, type: "file", accept: accept, multiple: maxFiles > 1, onChange: handleInputChange, disabled: disabled, className: "hidden" }));
|
|
92
|
-
return (_jsxs("div", { className: cn("space-y-
|
|
93
|
+
return (_jsxs("div", { className: cn("space-y-2", className), children: [fileInput, _jsxs("div", { onDrop: handleDrop, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onClick: openFilePicker, className: cn("relative flex cursor-pointer flex-col items-center justify-center gap-1.5 rounded-surface border border-dashed p-4 transition-colors", isDragOver && !disabled
|
|
93
94
|
? "border-primary bg-primary/5"
|
|
94
|
-
: "border-muted-foreground/25 hover:border-muted-foreground/50", disabled && "cursor-not-allowed opacity-50"), children: [_jsx(UploadIcon, { className: cn(isDragOver ? "text-primary" : "text-muted-foreground"), size:
|
|
95
|
+
: "border-muted-foreground/25 hover:border-muted-foreground/50", disabled && "cursor-not-allowed opacity-50"), children: [_jsx(UploadIcon, { className: cn(isDragOver ? "text-primary" : "text-muted-foreground"), size: 28 }), _jsxs("div", { className: "text-center", children: [_jsx(Typography, { as: "p", variant: "label", children: isDragOver ? "Drop files here" : "Drag & drop files here" }), _jsxs(Typography, { as: "p", variant: "caption", className: "mt-1", children: ["or click to browse (max ", formatFileSize(maxSize), " each)"] })] })] }), error ? (_jsx(Typography, { as: "p", variant: "bodySm", className: "text-destructive", children: error })) : null, value.length > 0 ? (_jsx("div", { className: "space-y-2", children: value.map((file, index) => {
|
|
95
96
|
var _a;
|
|
96
97
|
const progress = uploadProgress === null || uploadProgress === void 0 ? void 0 : uploadProgress.get(file.name);
|
|
97
98
|
const isUploading = (progress === null || progress === void 0 ? void 0 : progress.status) === "uploading";
|
|
98
99
|
const isComplete = (progress === null || progress === void 0 ? void 0 : progress.status) === "complete";
|
|
99
100
|
const isError = (progress === null || progress === void 0 ? void 0 : progress.status) === "error";
|
|
100
|
-
return (_jsxs("div", { className: "rounded-
|
|
101
|
+
return (_jsxs("div", { className: "rounded-control border bg-muted/30 px-2.5 py-1.5", children: [_jsxs("div", { className: "flex items-center gap-2", children: [getFileIcon(file), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx(Typography, { as: "p", variant: "label", className: "truncate", children: file.name }), _jsxs(Typography, { as: "p", variant: "caption", children: [formatFileSize(file.size), isUploading && ` • ${progress === null || progress === void 0 ? void 0 : progress.progress}%`, isComplete && " • Complete", isError && ` • ${(progress === null || progress === void 0 ? void 0 : progress.error) || "Error"}`] })] }), isComplete ? (_jsx("div", { className: "flex h-6 w-6 shrink-0 items-center justify-center text-[hsl(var(--status-success-foreground))]", children: _jsx(CheckIcon, { size: 16 }) })) : (_jsx(Button, { type: "button", variant: "ghost", size: "icon", className: "h-6 w-6 shrink-0", onClick: (e) => {
|
|
101
102
|
e.stopPropagation();
|
|
102
103
|
removeFile(index);
|
|
103
104
|
}, disabled: disabled || isUploading, "aria-label": `Remove ${file.name}`, children: _jsx(XIcon, { size: 16 }) }))] }), (isUploading ||
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type PopoverProps } from "./popover";
|
|
3
|
+
export interface FilterPopoverOption {
|
|
4
|
+
id: string;
|
|
5
|
+
label: React.ReactNode;
|
|
6
|
+
selected?: boolean;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
searchValue?: string;
|
|
9
|
+
ariaLabel?: string;
|
|
10
|
+
onSelect?: () => void;
|
|
11
|
+
}
|
|
12
|
+
export interface FilterPopoverGroup {
|
|
13
|
+
id: string;
|
|
14
|
+
label: React.ReactNode;
|
|
15
|
+
options: FilterPopoverOption[];
|
|
16
|
+
selectedCount?: number;
|
|
17
|
+
selectionLabel?: string;
|
|
18
|
+
searchable?: boolean;
|
|
19
|
+
searchPlaceholder?: string;
|
|
20
|
+
emptyLabel?: React.ReactNode;
|
|
21
|
+
ariaLabel?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface FilterPopoverProps extends Pick<PopoverProps, "align" | "defaultOpen" | "modal" | "onOpenChange" | "open" | "side"> {
|
|
24
|
+
groups: FilterPopoverGroup[];
|
|
25
|
+
selectedCount?: number;
|
|
26
|
+
trigger?: React.ReactElement;
|
|
27
|
+
triggerLabel?: React.ReactNode;
|
|
28
|
+
groupListLabel?: React.ReactNode;
|
|
29
|
+
resetLabel?: React.ReactNode;
|
|
30
|
+
emptyLabel?: React.ReactNode;
|
|
31
|
+
onReset?: () => void;
|
|
32
|
+
contentClassName?: string;
|
|
33
|
+
maxHeight?: string;
|
|
34
|
+
}
|
|
35
|
+
declare function getFilterSelectionLabel(count: number): string;
|
|
36
|
+
declare function FilterPopover({ align, contentClassName, defaultOpen, emptyLabel, groupListLabel, groups, maxHeight, modal, onOpenChange, onReset, open, resetLabel, selectedCount, side, trigger, triggerLabel, }: FilterPopoverProps): import("react/jsx-runtime").JSX.Element;
|
|
37
|
+
export { FilterPopover, getFilterSelectionLabel };
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { ChevronLeft, ChevronRight, SlidersHorizontal } from "lucide-react";
|
|
5
|
+
import { Button } from "./button";
|
|
6
|
+
import { CountBadge } from "./count-badge";
|
|
7
|
+
import { cn } from "./lib/utils";
|
|
8
|
+
import { Popover } from "./popover";
|
|
9
|
+
import { PopoverMenuFooter, PopoverMenuFooterAction, PopoverMenuGroup, PopoverMenuGroupLabel, PopoverMenuItem, PopoverMenuScrollArea, PopoverMenuSearch, PopoverMenuSection, PopoverMenuView, } from "./popover-menu";
|
|
10
|
+
import { Typography } from "./typography";
|
|
11
|
+
function getText(value) {
|
|
12
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
13
|
+
return String(value);
|
|
14
|
+
}
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
function getOptionSearchValue(option) {
|
|
18
|
+
var _a, _b, _c;
|
|
19
|
+
return (_c = (_b = (_a = option.searchValue) !== null && _a !== void 0 ? _a : option.ariaLabel) !== null && _b !== void 0 ? _b : getText(option.label)) !== null && _c !== void 0 ? _c : option.id;
|
|
20
|
+
}
|
|
21
|
+
function getGroupLabel(group) {
|
|
22
|
+
var _a, _b;
|
|
23
|
+
return (_b = (_a = group.ariaLabel) !== null && _a !== void 0 ? _a : getText(group.label)) !== null && _b !== void 0 ? _b : group.id;
|
|
24
|
+
}
|
|
25
|
+
function getGroupSelectedCount(group) {
|
|
26
|
+
var _a;
|
|
27
|
+
return ((_a = group.selectedCount) !== null && _a !== void 0 ? _a : group.options.filter((option) => option.selected).length);
|
|
28
|
+
}
|
|
29
|
+
function getFilterSelectionLabel(count) {
|
|
30
|
+
if (count === 0) {
|
|
31
|
+
return "Any";
|
|
32
|
+
}
|
|
33
|
+
return count === 1 ? "1 selected" : `${count} selected`;
|
|
34
|
+
}
|
|
35
|
+
function FilterPopover({ align = "start", contentClassName, defaultOpen, emptyLabel = "No options found.", groupListLabel = "Filter by", groups, maxHeight = "max-h-80", modal, onOpenChange, onReset, open, resetLabel = "Reset filters", selectedCount, side, trigger, triggerLabel = "Filters", }) {
|
|
36
|
+
var _a, _b, _c, _d, _e;
|
|
37
|
+
const [activeGroupId, setActiveGroupId] = React.useState(null);
|
|
38
|
+
const [transitionDirection, setTransitionDirection] = React.useState("forward");
|
|
39
|
+
const [query, setQuery] = React.useState("");
|
|
40
|
+
const activeGroup = (_a = groups.find((group) => group.id === activeGroupId)) !== null && _a !== void 0 ? _a : null;
|
|
41
|
+
const resolvedSelectedCount = selectedCount !== null && selectedCount !== void 0 ? selectedCount : groups.reduce((total, group) => total + getGroupSelectedCount(group), 0);
|
|
42
|
+
const normalizedQuery = query.trim().toLowerCase();
|
|
43
|
+
const filteredOptions = activeGroup && normalizedQuery
|
|
44
|
+
? activeGroup.options.filter((option) => getOptionSearchValue(option).toLowerCase().includes(normalizedQuery))
|
|
45
|
+
: (_b = activeGroup === null || activeGroup === void 0 ? void 0 : activeGroup.options) !== null && _b !== void 0 ? _b : [];
|
|
46
|
+
React.useEffect(() => {
|
|
47
|
+
setQuery("");
|
|
48
|
+
}, [activeGroupId]);
|
|
49
|
+
React.useEffect(() => {
|
|
50
|
+
if (!activeGroupId) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (!groups.some((group) => group.id === activeGroupId)) {
|
|
54
|
+
setActiveGroupId(null);
|
|
55
|
+
}
|
|
56
|
+
}, [activeGroupId, groups]);
|
|
57
|
+
const showGroup = (groupId) => {
|
|
58
|
+
setTransitionDirection("forward");
|
|
59
|
+
setActiveGroupId(groupId);
|
|
60
|
+
};
|
|
61
|
+
const showFilterGroups = () => {
|
|
62
|
+
setTransitionDirection("backward");
|
|
63
|
+
setActiveGroupId(null);
|
|
64
|
+
};
|
|
65
|
+
const defaultTrigger = (_jsxs(Button, { type: "button", variant: "outline", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), triggerLabel, resolvedSelectedCount > 0 ? (_jsx(CountBadge, { count: resolvedSelectedCount, size: "sm" })) : null] }));
|
|
66
|
+
return (_jsxs(Popover, { align: align, contentClassName: cn("w-[360px]", contentClassName), defaultOpen: defaultOpen, modal: modal, onOpenChange: onOpenChange, open: open, side: side, surface: "menu", trigger: trigger !== null && trigger !== void 0 ? trigger : defaultTrigger, children: [_jsx(PopoverMenuView, { className: "-mx-1 -mt-1 px-1 pt-1", direction: transitionDirection, viewKey: activeGroup ? `group-${activeGroup.id}` : "filter-groups", children: activeGroup ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "-mx-1 -mt-1 border-b p-1", children: _jsxs(Button, { type: "button", variant: "ghost", size: "sm", className: "w-full justify-start", onClick: showFilterGroups, children: [_jsx(ChevronLeft, { className: "h-4 w-4" }), activeGroup.label] }) }), activeGroup.searchable ? (_jsx(PopoverMenuSearch, { value: query, onChange: (event) => setQuery(event.target.value), placeholder: (_c = activeGroup.searchPlaceholder) !== null && _c !== void 0 ? _c : `Search ${getGroupLabel(activeGroup).toLowerCase()}...`, "aria-label": (_d = activeGroup.searchPlaceholder) !== null && _d !== void 0 ? _d : `Search ${getGroupLabel(activeGroup).toLowerCase()}` })) : null, _jsx(PopoverMenuScrollArea, { maxHeight: maxHeight, children: _jsx(PopoverMenuSection, { children: filteredOptions.length ? (filteredOptions.map((option) => (_jsx(PopoverMenuItem, { active: option.selected, "aria-label": option.ariaLabel, "aria-pressed": option.selected, disabled: option.disabled, onClick: option.onSelect, children: option.label }, option.id)))) : (_jsx(Typography, { as: "p", variant: "caption", className: "px-2 py-2", children: (_e = activeGroup.emptyLabel) !== null && _e !== void 0 ? _e : emptyLabel })) }) })] })) : (_jsx(PopoverMenuScrollArea, { maxHeight: maxHeight, children: _jsxs(PopoverMenuGroup, { children: [_jsx(PopoverMenuGroupLabel, { children: groupListLabel }), _jsx(PopoverMenuSection, { children: groups.map((group) => {
|
|
67
|
+
var _a;
|
|
68
|
+
const groupSelectedCount = getGroupSelectedCount(group);
|
|
69
|
+
const selectionLabel = (_a = group.selectionLabel) !== null && _a !== void 0 ? _a : getFilterSelectionLabel(groupSelectedCount);
|
|
70
|
+
return (_jsxs(PopoverMenuItem, { "aria-label": `${getGroupLabel(group)}, ${selectionLabel}`, onClick: () => showGroup(group.id), children: [_jsx(Typography, { as: "span", variant: "bodySm", className: "min-w-0 flex-1 truncate text-left", children: group.label }), groupSelectedCount > 0 ? (_jsx(CountBadge, { count: groupSelectedCount, size: "sm" })) : null, _jsx(ChevronRight, { className: "h-4 w-4 shrink-0 text-muted-foreground" })] }, group.id));
|
|
71
|
+
}) })] }) })) }), onReset ? (_jsx(PopoverMenuFooter, { children: _jsx(PopoverMenuFooterAction, { onClick: onReset, children: resetLabel }) })) : null] }));
|
|
72
|
+
}
|
|
73
|
+
export { FilterPopover, getFilterSelectionLabel };
|
package/dist/filter-toggle.js
CHANGED
|
@@ -2,7 +2,7 @@ import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { cva } from "class-variance-authority";
|
|
4
4
|
import { cn } from "./lib/utils";
|
|
5
|
-
const filterToggleVariants = cva("inline-flex cursor-pointer select-none items-center justify-center gap-1.5 rounded-
|
|
5
|
+
const filterToggleVariants = cva("inline-flex shrink-0 cursor-pointer select-none items-center justify-center gap-1.5 whitespace-nowrap rounded-control border px-2.5 py-1 text-xs font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background", {
|
|
6
6
|
variants: {
|
|
7
7
|
variant: {
|
|
8
8
|
default: "",
|
|
@@ -18,6 +18,6 @@ const filterToggleVariants = cva("inline-flex cursor-pointer select-none items-c
|
|
|
18
18
|
selected: false,
|
|
19
19
|
},
|
|
20
20
|
});
|
|
21
|
-
const FilterToggle = React.forwardRef(({ className, variant, selected = false, icon, children, ...props }, ref) => (_jsxs("button", { ref: ref, className: cn(filterToggleVariants({ variant, selected, className })), ...props, children: [icon, children] })));
|
|
21
|
+
const FilterToggle = React.forwardRef(({ className, variant, selected = false, icon, children, type = "button", ...props }, ref) => (_jsxs("button", { ref: ref, type: type, className: cn(filterToggleVariants({ variant, selected, className })), ...props, children: [icon, children] })));
|
|
22
22
|
FilterToggle.displayName = "FilterToggle";
|
|
23
23
|
export { FilterToggle, filterToggleVariants };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,25 +1,37 @@
|
|
|
1
1
|
export { Avatar, AvatarProfile, AvatarRoot, AvatarImage, } from "./avatar";
|
|
2
|
-
export type { AvatarProps, AvatarProfileProps, AvatarRootProps, } from "./avatar";
|
|
2
|
+
export type { AvatarProps, AvatarSize, AvatarProfileProps, AvatarRootProps, } from "./avatar";
|
|
3
3
|
export * from "./animated-icons";
|
|
4
|
-
export { Alert, alertVariants } from "./alert";
|
|
5
|
-
export type { AlertProps } from "./alert";
|
|
4
|
+
export { Alert, AlertAction, AlertConsent, alertVariants } from "./alert";
|
|
5
|
+
export type { AlertActionProps, AlertConsentProps, AlertProps } from "./alert";
|
|
6
6
|
export { Badge, badgeVariants } from "./badge";
|
|
7
|
-
export { Card } from "./card";
|
|
8
|
-
export type { CardProps } from "./card";
|
|
7
|
+
export { Card, CardGrid, CardSplitGrid, CardList, CardListItem, } from "./card";
|
|
8
|
+
export type { CardGridProps, CardListItemProps, CardListProps, CardProps, CardSplitGridProps, } from "./card";
|
|
9
9
|
export type { BadgeProps } from "./badge";
|
|
10
|
+
export { MessageAttachmentRow, MessageItem, MessageNewDivider, MessageThread, formatMessageDate, } from "./message-item";
|
|
11
|
+
export type { MessageAttachmentRowProps, MessageItemAttachment, MessageItemData, MessageItemProps, MessageNewDividerProps, MessageThreadProps, } from "./message-item";
|
|
12
|
+
export { NotificationItem, NotificationList, NotificationPopover, NotificationTrigger, } from "./notification";
|
|
13
|
+
export type { NotificationAction, NotificationFilter, NotificationIcon, NotificationItemData, NotificationItemProps, NotificationKind, NotificationListProps, NotificationPopoverProps, NotificationTriggerProps, NotificationTone, } from "./notification";
|
|
14
|
+
export { RoutingTimeline } from "./routing-timeline";
|
|
15
|
+
export type { RoutingTimelineItem, RoutingTimelineItemKind, RoutingTimelineProps, } from "./routing-timeline";
|
|
16
|
+
export { RichTextEditor, formatFileSize, replaceTemplateVariables, sanitizeRichTextHtml, } from "./rich-text-editor";
|
|
17
|
+
export type { AttachmentFile, RichTextEditorColor, RichTextEditorProps, RichTextEditorSendAction, RichTextEditorSendMetadata, RichTextEditorTemplate, TemplateContext, } from "./rich-text-editor";
|
|
10
18
|
export { Calendar, CalendarDayButton } from "./calendar";
|
|
11
19
|
export { Checkbox } from "./checkbox";
|
|
12
20
|
export type { CheckboxProps } from "./checkbox";
|
|
13
21
|
export { Switch } from "./switch";
|
|
14
22
|
export type { SwitchProps } from "./switch";
|
|
23
|
+
export { ThemeSwitcher } from "./theme-switcher";
|
|
24
|
+
export type { ThemeSwitcherProps } from "./theme-switcher";
|
|
15
25
|
export { DateInput } from "./date-input";
|
|
16
|
-
export type { DateInputProps } from "./date-input";
|
|
26
|
+
export type { DateInputProps, DateInputRangeProps, DateInputSingleProps, DateRangeInputValue, } from "./date-input";
|
|
17
27
|
export { CountBadge } from "./count-badge";
|
|
18
28
|
export type { CountBadgeProps } from "./count-badge";
|
|
19
29
|
export { EmptyState } from "./empty-state";
|
|
20
30
|
export type { EmptyStateProps } from "./empty-state";
|
|
21
31
|
export { EditableTable } from "./editable-table";
|
|
22
32
|
export type { EditableTableColumn, EditableTableProps, EditableTableRowActionContext, } from "./editable-table";
|
|
33
|
+
export { EditButton } from "./edit-button";
|
|
34
|
+
export type { EditButtonProps } from "./edit-button";
|
|
23
35
|
export { EmailInput } from "./email-input";
|
|
24
36
|
export type { EmailInputProps, EmailInputValidator, EmailInputValidatorHelpers, } from "./email-input";
|
|
25
37
|
export { Input } from "./input";
|
|
@@ -42,22 +54,36 @@ export { BackButton } from "./back-button";
|
|
|
42
54
|
export type { BackButtonProps } from "./back-button";
|
|
43
55
|
export { Button, buttonVariants } from "./button";
|
|
44
56
|
export type { ButtonProps } from "./button";
|
|
57
|
+
export { DropdownButton } from "./dropdown-button";
|
|
58
|
+
export type { DropdownButtonProps } from "./dropdown-button";
|
|
59
|
+
export { CloseButton } from "./close-button";
|
|
60
|
+
export type { CloseButtonProps } from "./close-button";
|
|
45
61
|
export { Link, linkVariants } from "./link";
|
|
46
62
|
export type { LinkProps } from "./link";
|
|
47
63
|
export { Dialog } from "./dialog";
|
|
48
64
|
export type { DialogAction, DialogProps } from "./dialog";
|
|
49
65
|
export { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandSeparator, CommandShortcut, } from "./command";
|
|
50
|
-
export { CommandSearch, type CommandSearchFilter, type CommandSearchItem, type CommandSearchProps, type CommandSearchSection, } from "./command-search";
|
|
66
|
+
export { CommandSearch, type CommandSearchFilter, type CommandSearchItem, type CommandSearchProps, type CommandSearchSection, type CommandSearchShowAllResultsLabel, } from "./command-search";
|
|
51
67
|
export { FileUpload } from "./file-upload";
|
|
52
68
|
export type { FileUploadProps } from "./file-upload";
|
|
69
|
+
export { FileUploadStatusToast, showFileUploadStatusToast, } from "./file-upload-status-toast";
|
|
70
|
+
export type { FileUploadStatusToastFile, FileUploadStatusToastProps, ShowFileUploadStatusToastOptions, } from "./file-upload-status-toast";
|
|
71
|
+
export { FilterPopover, getFilterSelectionLabel } from "./filter-popover";
|
|
72
|
+
export type { FilterPopoverGroup, FilterPopoverOption, FilterPopoverProps, } from "./filter-popover";
|
|
53
73
|
export { Progress } from "./progress";
|
|
54
74
|
export type { ProgressProps } from "./progress";
|
|
75
|
+
export { RadioGroup } from "./radio-group";
|
|
76
|
+
export type { RadioGroupOption, RadioGroupProps } from "./radio-group";
|
|
77
|
+
export { ScrollHint } from "./scroll-hint";
|
|
78
|
+
export type { ScrollHintProps } from "./scroll-hint";
|
|
79
|
+
export { TaskModeShell } from "./task-mode-shell";
|
|
80
|
+
export type { TaskModeShellProps } from "./task-mode-shell";
|
|
55
81
|
export { useFileUpload } from "./use-file-upload";
|
|
56
82
|
export type { FileUploadProgress, FileUploadResult, FileUploadStatus, UseFileUploadOptions, UseFileUploadReturn, } from "./use-file-upload";
|
|
57
83
|
export { Popover } from "./popover";
|
|
58
84
|
export type { PopoverProps } from "./popover";
|
|
59
|
-
export { PopoverMenuContent, PopoverMenuHeader, PopoverMenuSection, PopoverMenuItem, PopoverMenuDivider, PopoverMenuGroup, PopoverMenuGroupLabel, PopoverMenuSearch, PopoverMenuScrollArea, } from "./popover-menu";
|
|
60
|
-
export type { PopoverMenuContentProps, PopoverMenuHeaderProps, PopoverMenuSectionProps, PopoverMenuItemProps, PopoverMenuDividerProps, PopoverMenuGroupProps, PopoverMenuGroupLabelProps, PopoverMenuSearchProps, PopoverMenuScrollAreaProps, } from "./popover-menu";
|
|
85
|
+
export { PopoverMenuContent, PopoverMenuCheckboxItem, PopoverMenuHeader, PopoverMenuSection, PopoverMenuItem, PopoverMenuDivider, PopoverMenuFooter, PopoverMenuFooterAction, PopoverMenuFooterMeta, PopoverMenuGroup, PopoverMenuGroupLabel, PopoverMenuSearch, PopoverMenuScrollArea, PopoverMenuView, } from "./popover-menu";
|
|
86
|
+
export type { PopoverMenuContentProps, PopoverMenuCheckboxItemProps, PopoverMenuHeaderProps, PopoverMenuSectionProps, PopoverMenuItemProps, PopoverMenuDividerProps, PopoverMenuFooterActionProps, PopoverMenuFooterMetaProps, PopoverMenuFooterProps, PopoverMenuGroupProps, PopoverMenuGroupLabelProps, PopoverMenuSearchProps, PopoverMenuScrollAreaProps, PopoverMenuViewProps, } from "./popover-menu";
|
|
61
87
|
export { SearchInput } from "./search-input";
|
|
62
88
|
export type { SearchInputProps } from "./search-input";
|
|
63
89
|
export { SectionNav } from "./section-nav";
|
|
@@ -74,12 +100,14 @@ export { useViewportThreshold } from "./use-viewport-threshold";
|
|
|
74
100
|
export type { UseViewportThresholdOptions, UseViewportThresholdReturn, } from "./use-viewport-threshold";
|
|
75
101
|
export { Textarea } from "./textarea";
|
|
76
102
|
export type { TextareaProps } from "./textarea";
|
|
77
|
-
export { DraggableTabs, type DraggableTabItem, type DraggableTabsProps, } from "./draggable-tabs";
|
|
103
|
+
export { DraggableTabs, type DraggableTabBadge, type DraggableTabItem, type DraggableTabsProps, } from "./draggable-tabs";
|
|
78
104
|
export { Drawer, } from "./drawer";
|
|
79
105
|
export type { DrawerAction, DrawerProps, DrawerSide } from "./drawer";
|
|
80
|
-
export { DashboardLayout, DashboardSidebar, useSidebar, } from "./layout";
|
|
81
|
-
export type { DashboardLayoutProps, DashboardSidebarNavDropdownItem, DashboardSidebarNavGroup, DashboardSidebarNavItem, DashboardSidebarNavLinkItem, } from "./layout";
|
|
106
|
+
export { DashboardContent, DashboardLayout, DashboardRightPanel, DashboardRightPanelBody, DashboardRightPanelHeader, DashboardRightPanelSection, DashboardRightPanelTabs, DashboardSidebar, DashboardSidebarProfile, SidebarProvider, useSidebar, } from "./layout";
|
|
107
|
+
export type { DashboardContentProps, DashboardLayoutProps, DashboardRightPanelBodyProps, DashboardRightPanelHeaderProps, DashboardRightPanelMode, DashboardRightPanelProps, DashboardRightPanelSectionProps, DashboardRightPanelTabsProps, DashboardSidebarNavDropdownItem, DashboardSidebarNavGroup, DashboardSidebarNavItem, DashboardSidebarNavLinkItem, DashboardSidebarProfileProps, } from "./layout";
|
|
82
108
|
export { PageHeader } from "./page-header";
|
|
109
|
+
export { WorkspaceHeader } from "./workspace-header";
|
|
110
|
+
export type { WorkspaceHeaderProps } from "./workspace-header";
|
|
83
111
|
export { PageSection, PageSectionGroup } from "./page-section";
|
|
84
112
|
export type { PageSectionGroupProps, PageSectionProps } from "./page-section";
|
|
85
113
|
export { Typography, typographyVariants } from "./typography";
|
|
@@ -90,11 +118,13 @@ export { Pagination } from "./pagination";
|
|
|
90
118
|
export type { PaginationProps } from "./pagination";
|
|
91
119
|
export { TableToolbar } from "./table-toolbar";
|
|
92
120
|
export type { TableToolbarProps } from "./table-toolbar";
|
|
121
|
+
export { TableColumnVisibilityMenu } from "./table-column-visibility";
|
|
122
|
+
export type { TableColumnVisibilityMenuProps } from "./table-column-visibility";
|
|
93
123
|
export { useTableSort } from "./use-table-sort";
|
|
94
124
|
export type { UseTableSortOptions, UseTableSortReturn, } from "./use-table-sort";
|
|
95
125
|
export { Table, TableRoot, TableContainer, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, TableRowSkeleton, TABLE_SKELETON_PRESETS, } from "./table";
|
|
96
|
-
export type { TableColumn, TableProps, TableSortDirection, TableSortingProps, TableSkeletonConfig, TableRowSkeletonProps, } from "./table";
|
|
97
|
-
export { Tabs, TabsRoot, TabWithDropdown, type TabsItem, type TabsProps, TabsList, TabsTrigger, TabsContent, type TabWithDropdownProps, useTabsContext, type TabDropdownSection, } from "./tabs";
|
|
126
|
+
export type { TableColumn, TableProps, TableRowTone, TableSortDirection, TableSortingProps, TableSkeletonConfig, TableRowSkeletonProps, } from "./table";
|
|
127
|
+
export { Tabs, TabsRoot, TabWithDropdown, type TabsItem, type TabsItemLabel, type TabsItemLabelProps, type TabsProps, TabsList, TabsTrigger, TabsContent, type TabWithDropdownProps, useTabsContext, type TabDropdownSection, } from "./tabs";
|
|
98
128
|
export { Tooltip, TooltipRoot, TooltipTrigger, TooltipContent, TooltipProvider, type TooltipProps, } from "./tooltip";
|
|
99
129
|
export { Toaster, toast } from "./toaster";
|
|
100
130
|
export type { ToasterProps } from "./toaster";
|
|
@@ -110,3 +140,4 @@ export { Collapsible, CollapsibleSection } from "./collapsible";
|
|
|
110
140
|
export type { CollapsibleProps } from "./collapsible";
|
|
111
141
|
export { cn } from "./lib/utils";
|
|
112
142
|
export { parseDateTime, formatDateTime } from "./lib/date-utils";
|
|
143
|
+
export type { ParseDateTimeOptions } from "./lib/date-utils";
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
export { Avatar, AvatarProfile, AvatarRoot, AvatarImage, } from "./avatar";
|
|
2
2
|
export * from "./animated-icons";
|
|
3
|
-
export { Alert, alertVariants } from "./alert";
|
|
3
|
+
export { Alert, AlertAction, AlertConsent, alertVariants } from "./alert";
|
|
4
4
|
export { Badge, badgeVariants } from "./badge";
|
|
5
|
-
export { Card } from "./card";
|
|
5
|
+
export { Card, CardGrid, CardSplitGrid, CardList, CardListItem, } from "./card";
|
|
6
|
+
export { MessageAttachmentRow, MessageItem, MessageNewDivider, MessageThread, formatMessageDate, } from "./message-item";
|
|
7
|
+
export { NotificationItem, NotificationList, NotificationPopover, NotificationTrigger, } from "./notification";
|
|
8
|
+
export { RoutingTimeline } from "./routing-timeline";
|
|
9
|
+
export { RichTextEditor, formatFileSize, replaceTemplateVariables, sanitizeRichTextHtml, } from "./rich-text-editor";
|
|
6
10
|
export { Calendar, CalendarDayButton } from "./calendar";
|
|
7
11
|
export { Checkbox } from "./checkbox";
|
|
8
12
|
export { Switch } from "./switch";
|
|
13
|
+
export { ThemeSwitcher } from "./theme-switcher";
|
|
9
14
|
export { DateInput } from "./date-input";
|
|
10
15
|
export { CountBadge } from "./count-badge";
|
|
11
16
|
export { EmptyState } from "./empty-state";
|
|
12
17
|
export { EditableTable } from "./editable-table";
|
|
18
|
+
export { EditButton } from "./edit-button";
|
|
13
19
|
export { EmailInput } from "./email-input";
|
|
14
20
|
export { Input } from "./input";
|
|
15
21
|
export { Select } from "./select";
|
|
@@ -21,15 +27,22 @@ export { LabelValueGrid } from "./label-value-grid";
|
|
|
21
27
|
export { Breadcrumb, BreadcrumbNav, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis, } from "./breadcrumb";
|
|
22
28
|
export { BackButton } from "./back-button";
|
|
23
29
|
export { Button, buttonVariants } from "./button";
|
|
30
|
+
export { DropdownButton } from "./dropdown-button";
|
|
31
|
+
export { CloseButton } from "./close-button";
|
|
24
32
|
export { Link, linkVariants } from "./link";
|
|
25
33
|
export { Dialog } from "./dialog";
|
|
26
34
|
export { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandSeparator, CommandShortcut, } from "./command";
|
|
27
35
|
export { CommandSearch, } from "./command-search";
|
|
28
36
|
export { FileUpload } from "./file-upload";
|
|
37
|
+
export { FileUploadStatusToast, showFileUploadStatusToast, } from "./file-upload-status-toast";
|
|
38
|
+
export { FilterPopover, getFilterSelectionLabel } from "./filter-popover";
|
|
29
39
|
export { Progress } from "./progress";
|
|
40
|
+
export { RadioGroup } from "./radio-group";
|
|
41
|
+
export { ScrollHint } from "./scroll-hint";
|
|
42
|
+
export { TaskModeShell } from "./task-mode-shell";
|
|
30
43
|
export { useFileUpload } from "./use-file-upload";
|
|
31
44
|
export { Popover } from "./popover";
|
|
32
|
-
export { PopoverMenuContent, PopoverMenuHeader, PopoverMenuSection, PopoverMenuItem, PopoverMenuDivider, PopoverMenuGroup, PopoverMenuGroupLabel, PopoverMenuSearch, PopoverMenuScrollArea, } from "./popover-menu";
|
|
45
|
+
export { PopoverMenuContent, PopoverMenuCheckboxItem, PopoverMenuHeader, PopoverMenuSection, PopoverMenuItem, PopoverMenuDivider, PopoverMenuFooter, PopoverMenuFooterAction, PopoverMenuFooterMeta, PopoverMenuGroup, PopoverMenuGroupLabel, PopoverMenuSearch, PopoverMenuScrollArea, PopoverMenuView, } from "./popover-menu";
|
|
33
46
|
export { SearchInput } from "./search-input";
|
|
34
47
|
export { SectionNav } from "./section-nav";
|
|
35
48
|
export { GovtMasthead } from "./govt-masthead";
|
|
@@ -40,14 +53,16 @@ export { useViewportThreshold } from "./use-viewport-threshold";
|
|
|
40
53
|
export { Textarea } from "./textarea";
|
|
41
54
|
export { DraggableTabs, } from "./draggable-tabs";
|
|
42
55
|
export { Drawer, } from "./drawer";
|
|
43
|
-
export { DashboardLayout, DashboardSidebar, useSidebar, } from "./layout";
|
|
56
|
+
export { DashboardContent, DashboardLayout, DashboardRightPanel, DashboardRightPanelBody, DashboardRightPanelHeader, DashboardRightPanelSection, DashboardRightPanelTabs, DashboardSidebar, DashboardSidebarProfile, SidebarProvider, useSidebar, } from "./layout";
|
|
44
57
|
export { PageHeader } from "./page-header";
|
|
58
|
+
export { WorkspaceHeader } from "./workspace-header";
|
|
45
59
|
export { PageSection, PageSectionGroup } from "./page-section";
|
|
46
60
|
export { Typography, typographyVariants } from "./typography";
|
|
47
61
|
export { neaPalette, semanticColorTokens, typographyTokens, radiusTokens, spacingTokens, layoutTokens, } from "./theme";
|
|
48
62
|
export { neaDesignSystemContent, neaTailwindPreset, } from "./tailwind-preset";
|
|
49
63
|
export { Pagination } from "./pagination";
|
|
50
64
|
export { TableToolbar } from "./table-toolbar";
|
|
65
|
+
export { TableColumnVisibilityMenu } from "./table-column-visibility";
|
|
51
66
|
export { useTableSort } from "./use-table-sort";
|
|
52
67
|
export { Table, TableRoot, TableContainer, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, TableRowSkeleton, TABLE_SKELETON_PRESETS, } from "./table";
|
|
53
68
|
export { Tabs, TabsRoot, TabWithDropdown, TabsList, TabsTrigger, TabsContent, useTabsContext, } from "./tabs";
|
package/dist/input-control.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
declare const
|
|
2
|
+
declare const inputControlPaddingClassName = "px-3 py-2";
|
|
3
|
+
declare const inputControlClassName = "h-control w-full min-w-0 rounded-control border border-input bg-transparent px-3 py-2 text-sm transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-[invalid=true]:border-destructive aria-[invalid=true]:ring-destructive/20";
|
|
3
4
|
declare const InputControl: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref"> & React.RefAttributes<HTMLInputElement>>;
|
|
4
|
-
export { InputControl, inputControlClassName };
|
|
5
|
+
export { InputControl, inputControlClassName, inputControlPaddingClassName };
|
package/dist/input-control.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { cn } from "./lib/utils";
|
|
4
|
-
const
|
|
4
|
+
const inputControlPaddingClassName = "px-3 py-2";
|
|
5
|
+
const inputControlClassName = `h-control w-full min-w-0 rounded-control border border-input bg-transparent ${inputControlPaddingClassName} text-sm transition-[color,box-shadow] outline-none selection:bg-primary selection:text-primary-foreground file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-[invalid=true]:border-destructive aria-[invalid=true]:ring-destructive/20`;
|
|
5
6
|
const InputControl = React.forwardRef(({ className, type = "text", ...props }, ref) => (_jsx("input", { ref: ref, type: type, "data-slot": "input", className: cn(inputControlClassName, className), ...props })));
|
|
6
7
|
InputControl.displayName = "InputControl";
|
|
7
|
-
export { InputControl, inputControlClassName };
|
|
8
|
+
export { InputControl, inputControlClassName, inputControlPaddingClassName };
|
|
@@ -5,11 +5,13 @@ export interface LabelValueGridItem extends LabelValueProps {
|
|
|
5
5
|
}
|
|
6
6
|
export interface LabelValueGridProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
7
7
|
items: LabelValueGridItem[];
|
|
8
|
-
columns?: 1 | 2 | 3 | 4;
|
|
8
|
+
columns?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
9
|
+
density?: "default" | "compact";
|
|
9
10
|
itemClassName?: string;
|
|
10
11
|
minColumnWidth?: number;
|
|
12
|
+
hideIfEmpty?: boolean;
|
|
11
13
|
loading?: boolean;
|
|
12
14
|
loadingItems?: number;
|
|
13
15
|
}
|
|
14
|
-
declare function LabelValueGrid({ items, columns, className, itemClassName, minColumnWidth, loading, loadingItems, style, ...props }: LabelValueGridProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
declare function LabelValueGrid({ items, columns, density, className, itemClassName, minColumnWidth, hideIfEmpty, loading, loadingItems, style, ...props }: LabelValueGridProps): import("react/jsx-runtime").JSX.Element;
|
|
15
17
|
export { LabelValueGrid };
|
package/dist/label-value-grid.js
CHANGED
|
@@ -11,7 +11,8 @@ function getAvailableWidth(element) {
|
|
|
11
11
|
var _a, _b, _c, _d, _e, _f;
|
|
12
12
|
return Math.max(element.getBoundingClientRect().width, element.clientWidth, element.offsetWidth, (_b = (_a = element.parentElement) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().width) !== null && _b !== void 0 ? _b : 0, (_d = (_c = element.parentElement) === null || _c === void 0 ? void 0 : _c.clientWidth) !== null && _d !== void 0 ? _d : 0, (_f = (_e = element.parentElement) === null || _e === void 0 ? void 0 : _e.offsetWidth) !== null && _f !== void 0 ? _f : 0);
|
|
13
13
|
}
|
|
14
|
-
function LabelValueGrid({ items, columns = 4, className, itemClassName, minColumnWidth =
|
|
14
|
+
function LabelValueGrid({ items, columns = 4, density = "default", className, itemClassName, minColumnWidth, hideIfEmpty = false, loading = false, loadingItems = 4, style, ...props }) {
|
|
15
|
+
const resolvedMinColumnWidth = minColumnWidth !== null && minColumnWidth !== void 0 ? minColumnWidth : (density === "compact" ? 140 : 192);
|
|
15
16
|
const resolvedItems = React.useMemo(() => {
|
|
16
17
|
if (!loading)
|
|
17
18
|
return items;
|
|
@@ -38,7 +39,7 @@ function LabelValueGrid({ items, columns = 4, className, itemClassName, minColum
|
|
|
38
39
|
if (width <= 0) {
|
|
39
40
|
return;
|
|
40
41
|
}
|
|
41
|
-
setResolvedColumns(getResponsiveColumnCount(width, columns,
|
|
42
|
+
setResolvedColumns(getResponsiveColumnCount(width, columns, resolvedMinColumnWidth, GAP_PX));
|
|
42
43
|
};
|
|
43
44
|
const requestUpdate = () => {
|
|
44
45
|
if (frameId !== null) {
|
|
@@ -62,13 +63,13 @@ function LabelValueGrid({ items, columns = 4, className, itemClassName, minColum
|
|
|
62
63
|
window.removeEventListener("resize", requestUpdate);
|
|
63
64
|
observer.disconnect();
|
|
64
65
|
};
|
|
65
|
-
}, [columns,
|
|
66
|
-
return (_jsx("div", { ref: containerRef, className: cn("grid auto-rows-fr items-start gap-x-6 gap-y-
|
|
66
|
+
}, [columns, resolvedMinColumnWidth]);
|
|
67
|
+
return (_jsx("div", { ref: containerRef, className: cn("grid auto-rows-fr items-start gap-x-6 gap-y-6", className), style: {
|
|
67
68
|
...style,
|
|
68
69
|
gridTemplateColumns: `repeat(${resolvedColumns}, minmax(0, 1fr))`,
|
|
69
70
|
}, ...props, children: resolvedItems.map((item, index) => {
|
|
70
|
-
var _a;
|
|
71
|
-
return (_jsx(LabelValue, { ...item, className: cn("min-w-0", itemClassName, item.className) }, (
|
|
71
|
+
var _a, _b;
|
|
72
|
+
return (_jsx(LabelValue, { ...item, hideIfEmpty: (_a = item.hideIfEmpty) !== null && _a !== void 0 ? _a : hideIfEmpty, className: cn("min-w-0", itemClassName, item.className) }, (_b = item.id) !== null && _b !== void 0 ? _b : `${item.label}-${index}`));
|
|
72
73
|
}) }));
|
|
73
74
|
}
|
|
74
75
|
export { LabelValueGrid };
|