@comitor/ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +458 -0
- package/dist/chart/chart.d.ts +88 -0
- package/dist/chart/chart.js +199 -0
- package/dist/chart/chart.js.map +1 -0
- package/dist/chart/comitor-chart.d.ts +109 -0
- package/dist/chart/comitor-chart.js +189 -0
- package/dist/chart/comitor-chart.js.map +1 -0
- package/dist/chart/index.d.ts +4 -0
- package/dist/chart/index.js +3 -0
- package/dist/chart/index.js.map +1 -0
- package/dist/components/composite/avatar-group.d.ts +33 -0
- package/dist/components/composite/avatar-group.js +86 -0
- package/dist/components/composite/avatar-group.js.map +1 -0
- package/dist/components/composite/combobox.d.ts +70 -0
- package/dist/components/composite/combobox.js +291 -0
- package/dist/components/composite/combobox.js.map +1 -0
- package/dist/components/composite/command-palette.d.ts +56 -0
- package/dist/components/composite/command-palette.js +131 -0
- package/dist/components/composite/command-palette.js.map +1 -0
- package/dist/components/composite/confirm-dialog.d.ts +40 -0
- package/dist/components/composite/confirm-dialog.js +96 -0
- package/dist/components/composite/confirm-dialog.js.map +1 -0
- package/dist/components/composite/copy-button.d.ts +27 -0
- package/dist/components/composite/copy-button.js +80 -0
- package/dist/components/composite/copy-button.js.map +1 -0
- package/dist/components/composite/data-table.d.ts +136 -0
- package/dist/components/composite/data-table.js +300 -0
- package/dist/components/composite/data-table.js.map +1 -0
- package/dist/components/composite/date-picker.d.ts +77 -0
- package/dist/components/composite/date-picker.js +268 -0
- package/dist/components/composite/date-picker.js.map +1 -0
- package/dist/components/composite/empty-state.d.ts +38 -0
- package/dist/components/composite/empty-state.js +35 -0
- package/dist/components/composite/empty-state.js.map +1 -0
- package/dist/components/composite/filter-chips.d.ts +39 -0
- package/dist/components/composite/filter-chips.js +79 -0
- package/dist/components/composite/filter-chips.js.map +1 -0
- package/dist/components/composite/form-field.d.ts +58 -0
- package/dist/components/composite/form-field.js +81 -0
- package/dist/components/composite/form-field.js.map +1 -0
- package/dist/components/composite/form-section.d.ts +33 -0
- package/dist/components/composite/form-section.js +85 -0
- package/dist/components/composite/form-section.js.map +1 -0
- package/dist/components/composite/inline-edit.d.ts +38 -0
- package/dist/components/composite/inline-edit.js +165 -0
- package/dist/components/composite/inline-edit.js.map +1 -0
- package/dist/components/composite/keyboard-hint.d.ts +31 -0
- package/dist/components/composite/keyboard-hint.js +72 -0
- package/dist/components/composite/keyboard-hint.js.map +1 -0
- package/dist/components/composite/letter-avatar.d.ts +47 -0
- package/dist/components/composite/letter-avatar.js +66 -0
- package/dist/components/composite/letter-avatar.js.map +1 -0
- package/dist/components/composite/page-container.d.ts +25 -0
- package/dist/components/composite/page-container.js +23 -0
- package/dist/components/composite/page-container.js.map +1 -0
- package/dist/components/composite/page-header.d.ts +49 -0
- package/dist/components/composite/page-header.js +75 -0
- package/dist/components/composite/page-header.js.map +1 -0
- package/dist/components/composite/relative-time.d.ts +28 -0
- package/dist/components/composite/relative-time.js +44 -0
- package/dist/components/composite/relative-time.js.map +1 -0
- package/dist/components/composite/search-filter-bar.d.ts +38 -0
- package/dist/components/composite/search-filter-bar.js +135 -0
- package/dist/components/composite/search-filter-bar.js.map +1 -0
- package/dist/components/composite/stat-card.d.ts +48 -0
- package/dist/components/composite/stat-card.js +76 -0
- package/dist/components/composite/stat-card.js.map +1 -0
- package/dist/components/composite/status-config.d.ts +85 -0
- package/dist/components/composite/status-config.js +41 -0
- package/dist/components/composite/status-config.js.map +1 -0
- package/dist/components/composite/status-pill.d.ts +26 -0
- package/dist/components/composite/status-pill.js +59 -0
- package/dist/components/composite/status-pill.js.map +1 -0
- package/dist/components/composite/table-pagination.d.ts +31 -0
- package/dist/components/composite/table-pagination.js +103 -0
- package/dist/components/composite/table-pagination.js.map +1 -0
- package/dist/components/composite/text-utils.d.ts +38 -0
- package/dist/components/composite/text-utils.js +40 -0
- package/dist/components/composite/text-utils.js.map +1 -0
- package/dist/components/composite/toast.d.ts +56 -0
- package/dist/components/composite/toast.js +63 -0
- package/dist/components/composite/toast.js.map +1 -0
- package/dist/components/ui/accordion.d.ts +17 -0
- package/dist/components/ui/accordion.js +53 -0
- package/dist/components/ui/accordion.js.map +1 -0
- package/dist/components/ui/alert-dialog.d.ts +34 -0
- package/dist/components/ui/alert-dialog.js +103 -0
- package/dist/components/ui/alert-dialog.js.map +1 -0
- package/dist/components/ui/alert.d.ts +16 -0
- package/dist/components/ui/alert.js +50 -0
- package/dist/components/ui/alert.js.map +1 -0
- package/dist/components/ui/aspect-ratio.d.ts +7 -0
- package/dist/components/ui/aspect-ratio.js +10 -0
- package/dist/components/ui/aspect-ratio.js.map +1 -0
- package/dist/components/ui/avatar.d.ts +11 -0
- package/dist/components/ui/avatar.js +33 -0
- package/dist/components/ui/avatar.js.map +1 -0
- package/dist/components/ui/badge.d.ts +15 -0
- package/dist/components/ui/badge.js +37 -0
- package/dist/components/ui/badge.js.map +1 -0
- package/dist/components/ui/breadcrumb.d.ts +30 -0
- package/dist/components/ui/breadcrumb.js +89 -0
- package/dist/components/ui/breadcrumb.js.map +1 -0
- package/dist/components/ui/button-group.d.ts +21 -0
- package/dist/components/ui/button-group.js +62 -0
- package/dist/components/ui/button-group.js.map +1 -0
- package/dist/components/ui/button.d.ts +21 -0
- package/dist/components/ui/button.js +70 -0
- package/dist/components/ui/button.js.map +1 -0
- package/dist/components/ui/calendar.d.ts +26 -0
- package/dist/components/ui/calendar.js +148 -0
- package/dist/components/ui/calendar.js.map +1 -0
- package/dist/components/ui/card.d.ts +33 -0
- package/dist/components/ui/card.js +70 -0
- package/dist/components/ui/card.js.map +1 -0
- package/dist/components/ui/carousel.d.ts +46 -0
- package/dist/components/ui/carousel.js +173 -0
- package/dist/components/ui/carousel.js.map +1 -0
- package/dist/components/ui/checkbox.d.ts +17 -0
- package/dist/components/ui/checkbox.js +67 -0
- package/dist/components/ui/checkbox.js.map +1 -0
- package/dist/components/ui/collapsible.d.ts +17 -0
- package/dist/components/ui/collapsible.js +18 -0
- package/dist/components/ui/collapsible.js.map +1 -0
- package/dist/components/ui/command.d.ts +41 -0
- package/dist/components/ui/command.js +122 -0
- package/dist/components/ui/command.js.map +1 -0
- package/dist/components/ui/context-menu.d.ts +51 -0
- package/dist/components/ui/context-menu.js +166 -0
- package/dist/components/ui/context-menu.js.map +1 -0
- package/dist/components/ui/dialog.d.ts +48 -0
- package/dist/components/ui/dialog.js +131 -0
- package/dist/components/ui/dialog.js.map +1 -0
- package/dist/components/ui/drawer.d.ts +32 -0
- package/dist/components/ui/drawer.js +102 -0
- package/dist/components/ui/drawer.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +52 -0
- package/dist/components/ui/dropdown-menu.js +167 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/empty.d.ts +22 -0
- package/dist/components/ui/empty.js +87 -0
- package/dist/components/ui/empty.js.map +1 -0
- package/dist/components/ui/field.d.ts +46 -0
- package/dist/components/ui/field.js +197 -0
- package/dist/components/ui/field.js.map +1 -0
- package/dist/components/ui/form.d.ts +50 -0
- package/dist/components/ui/form.js +100 -0
- package/dist/components/ui/form.js.map +1 -0
- package/dist/components/ui/hover-card.d.ts +17 -0
- package/dist/components/ui/hover-card.js +31 -0
- package/dist/components/ui/hover-card.js.map +1 -0
- package/dist/components/ui/input-group.d.ts +26 -0
- package/dist/components/ui/input-group.js +148 -0
- package/dist/components/ui/input-group.js.map +1 -0
- package/dist/components/ui/input-otp.d.ts +23 -0
- package/dist/components/ui/input-otp.js +54 -0
- package/dist/components/ui/input-otp.js.map +1 -0
- package/dist/components/ui/input.d.ts +21 -0
- package/dist/components/ui/input.js +62 -0
- package/dist/components/ui/input.js.map +1 -0
- package/dist/components/ui/item.d.ts +39 -0
- package/dist/components/ui/item.js +142 -0
- package/dist/components/ui/item.js.map +1 -0
- package/dist/components/ui/kbd.d.ts +8 -0
- package/dist/components/ui/kbd.js +25 -0
- package/dist/components/ui/kbd.js.map +1 -0
- package/dist/components/ui/label.d.ts +7 -0
- package/dist/components/ui/label.js +21 -0
- package/dist/components/ui/label.js.map +1 -0
- package/dist/components/ui/menubar.d.ts +51 -0
- package/dist/components/ui/menubar.js +196 -0
- package/dist/components/ui/menubar.js.map +1 -0
- package/dist/components/ui/navigation-menu.d.ts +39 -0
- package/dist/components/ui/navigation-menu.js +123 -0
- package/dist/components/ui/navigation-menu.js.map +1 -0
- package/dist/components/ui/pagination.d.ts +40 -0
- package/dist/components/ui/pagination.js +95 -0
- package/dist/components/ui/pagination.js.map +1 -0
- package/dist/components/ui/popover.d.ts +19 -0
- package/dist/components/ui/popover.js +35 -0
- package/dist/components/ui/popover.js.map +1 -0
- package/dist/components/ui/progress.d.ts +12 -0
- package/dist/components/ui/progress.js +27 -0
- package/dist/components/ui/progress.js.map +1 -0
- package/dist/components/ui/radio-group.d.ts +9 -0
- package/dist/components/ui/radio-group.js +34 -0
- package/dist/components/ui/radio-group.js.map +1 -0
- package/dist/components/ui/resizable.d.ts +19 -0
- package/dist/components/ui/resizable.js +38 -0
- package/dist/components/ui/resizable.js.map +1 -0
- package/dist/components/ui/scroll-area.d.ts +13 -0
- package/dist/components/ui/scroll-area.js +46 -0
- package/dist/components/ui/scroll-area.js.map +1 -0
- package/dist/components/ui/select.d.ts +33 -0
- package/dist/components/ui/select.js +133 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/separator.d.ts +7 -0
- package/dist/components/ui/separator.js +23 -0
- package/dist/components/ui/separator.js.map +1 -0
- package/dist/components/ui/sheet.d.ts +38 -0
- package/dist/components/ui/sheet.js +96 -0
- package/dist/components/ui/sheet.js.map +1 -0
- package/dist/components/ui/skeleton.d.ts +6 -0
- package/dist/components/ui/skeleton.js +9 -0
- package/dist/components/ui/skeleton.js.map +1 -0
- package/dist/components/ui/slider.d.ts +12 -0
- package/dist/components/ui/slider.js +54 -0
- package/dist/components/ui/slider.js.map +1 -0
- package/dist/components/ui/sonner.d.ts +9 -0
- package/dist/components/ui/sonner.js +25 -0
- package/dist/components/ui/sonner.js.map +1 -0
- package/dist/components/ui/spinner.d.ts +6 -0
- package/dist/components/ui/spinner.js +10 -0
- package/dist/components/ui/spinner.js.map +1 -0
- package/dist/components/ui/switch.d.ts +14 -0
- package/dist/components/ui/switch.js +65 -0
- package/dist/components/ui/switch.js.map +1 -0
- package/dist/components/ui/table.d.ts +30 -0
- package/dist/components/ui/table.js +87 -0
- package/dist/components/ui/table.js.map +1 -0
- package/dist/components/ui/tabs.d.ts +35 -0
- package/dist/components/ui/tabs.js +54 -0
- package/dist/components/ui/tabs.js.map +1 -0
- package/dist/components/ui/textarea.d.ts +6 -0
- package/dist/components/ui/textarea.js +19 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/components/ui/toggle-group.d.ts +18 -0
- package/dist/components/ui/toggle-group.js +52 -0
- package/dist/components/ui/toggle-group.js.map +1 -0
- package/dist/components/ui/toggle.d.ts +15 -0
- package/dist/components/ui/toggle.js +33 -0
- package/dist/components/ui/toggle.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +21 -0
- package/dist/components/ui/tooltip.js +38 -0
- package/dist/components/ui/tooltip.js.map +1 -0
- package/dist/form.d.ts +5 -0
- package/dist/form.js +2 -0
- package/dist/form.js.map +1 -0
- package/dist/index.d.ts +111 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/cn.d.ts +16 -0
- package/dist/lib/cn.js +9 -0
- package/dist/lib/cn.js.map +1 -0
- package/dist/shell/app-header.d.ts +41 -0
- package/dist/shell/app-header.js +136 -0
- package/dist/shell/app-header.js.map +1 -0
- package/dist/shell/app-launcher.d.ts +33 -0
- package/dist/shell/app-launcher.js +189 -0
- package/dist/shell/app-launcher.js.map +1 -0
- package/dist/shell/app-shell.d.ts +44 -0
- package/dist/shell/app-shell.js +99 -0
- package/dist/shell/app-shell.js.map +1 -0
- package/dist/shell/comitor-lockup.d.ts +33 -0
- package/dist/shell/comitor-lockup.js +112 -0
- package/dist/shell/comitor-lockup.js.map +1 -0
- package/dist/shell/comitor-logo.d.ts +28 -0
- package/dist/shell/comitor-logo.js +92 -0
- package/dist/shell/comitor-logo.js.map +1 -0
- package/dist/shell/index.d.ts +24 -0
- package/dist/shell/index.js +23 -0
- package/dist/shell/index.js.map +1 -0
- package/dist/shell/mobile-menu.d.ts +26 -0
- package/dist/shell/mobile-menu.js +56 -0
- package/dist/shell/mobile-menu.js.map +1 -0
- package/dist/shell/notifications-button.d.ts +22 -0
- package/dist/shell/notifications-button.js +39 -0
- package/dist/shell/notifications-button.js.map +1 -0
- package/dist/shell/shell-context.d.ts +91 -0
- package/dist/shell/shell-context.js +233 -0
- package/dist/shell/shell-context.js.map +1 -0
- package/dist/shell/shell-link.d.ts +19 -0
- package/dist/shell/shell-link.js +18 -0
- package/dist/shell/shell-link.js.map +1 -0
- package/dist/shell/sidebar-group.d.ts +21 -0
- package/dist/shell/sidebar-group.js +43 -0
- package/dist/shell/sidebar-group.js.map +1 -0
- package/dist/shell/sidebar-menu-item.d.ts +27 -0
- package/dist/shell/sidebar-menu-item.js +152 -0
- package/dist/shell/sidebar-menu-item.js.map +1 -0
- package/dist/shell/sidebar.d.ts +26 -0
- package/dist/shell/sidebar.js +92 -0
- package/dist/shell/sidebar.js.map +1 -0
- package/dist/shell/theme-provider.d.ts +18 -0
- package/dist/shell/theme-provider.js +29 -0
- package/dist/shell/theme-provider.js.map +1 -0
- package/dist/shell/theme-toggle.d.ts +28 -0
- package/dist/shell/theme-toggle.js +67 -0
- package/dist/shell/theme-toggle.js.map +1 -0
- package/dist/shell/types.d.ts +168 -0
- package/dist/shell/types.js +38 -0
- package/dist/shell/types.js.map +1 -0
- package/dist/shell/user-menu.d.ts +42 -0
- package/dist/shell/user-menu.js +132 -0
- package/dist/shell/user-menu.js.map +1 -0
- package/dist/shell/utils.d.ts +62 -0
- package/dist/shell/utils.js +73 -0
- package/dist/shell/utils.js.map +1 -0
- package/dist/shell/workspace-switcher.d.ts +24 -0
- package/dist/shell/workspace-switcher.js +219 -0
- package/dist/shell/workspace-switcher.js.map +1 -0
- package/dist/tokens.d.ts +173 -0
- package/dist/tokens.js +161 -0
- package/dist/tokens.js.map +1 -0
- package/package.json +151 -0
- package/styles.css +357 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { AlertTriangle, CheckCircle2, Info, XCircle } from "lucide-react";
|
|
4
|
+
import { Toaster as SonnerToaster, toast as sonnerToast } from "sonner";
|
|
5
|
+
function Toaster({ theme = "system", position = "bottom-right", ...props }) {
|
|
6
|
+
return /* @__PURE__ */ jsx(
|
|
7
|
+
SonnerToaster,
|
|
8
|
+
{
|
|
9
|
+
theme,
|
|
10
|
+
position,
|
|
11
|
+
className: "toaster group",
|
|
12
|
+
icons: {
|
|
13
|
+
success: /* @__PURE__ */ jsx(CheckCircle2, { className: "size-4 text-success" }),
|
|
14
|
+
warning: /* @__PURE__ */ jsx(AlertTriangle, { className: "size-4 text-warning" }),
|
|
15
|
+
error: /* @__PURE__ */ jsx(XCircle, { className: "size-4 text-destructive" }),
|
|
16
|
+
info: /* @__PURE__ */ jsx(Info, { className: "size-4 text-info" })
|
|
17
|
+
},
|
|
18
|
+
toastOptions: {
|
|
19
|
+
classNames: {
|
|
20
|
+
toast: "group toast group-[.toaster]:bg-popover group-[.toaster]:text-popover-foreground group-[.toaster]:border-border group-[.toaster]:rounded-lg group-[.toaster]:shadow-card",
|
|
21
|
+
title: "group-[.toast]:text-sm group-[.toast]:font-medium",
|
|
22
|
+
description: "group-[.toast]:text-sm group-[.toast]:text-muted-foreground",
|
|
23
|
+
actionButton: "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
|
|
24
|
+
cancelButton: "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
...props
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
function toast(title, options = {}) {
|
|
32
|
+
const { variant = "default", description, duration, action, id } = options;
|
|
33
|
+
const config = { description, duration, action, id };
|
|
34
|
+
switch (variant) {
|
|
35
|
+
case "success":
|
|
36
|
+
return sonnerToast.success(title, config);
|
|
37
|
+
case "warning":
|
|
38
|
+
return sonnerToast.warning(title, config);
|
|
39
|
+
case "destructive":
|
|
40
|
+
return sonnerToast.error(title, config);
|
|
41
|
+
case "info":
|
|
42
|
+
return sonnerToast.info(title, config);
|
|
43
|
+
default:
|
|
44
|
+
return sonnerToast(title, config);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function dismissToast(id) {
|
|
48
|
+
sonnerToast.dismiss(id);
|
|
49
|
+
}
|
|
50
|
+
function toastPromise(promise, messages) {
|
|
51
|
+
return sonnerToast.promise(promise, {
|
|
52
|
+
loading: messages.loading ?? "\u0110ang x\u1EED l\xFD\u2026",
|
|
53
|
+
success: messages.success,
|
|
54
|
+
error: messages.error
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
Toaster,
|
|
59
|
+
dismissToast,
|
|
60
|
+
toast,
|
|
61
|
+
toastPromise
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=toast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/composite/toast.tsx"],"sourcesContent":["\"use client\";\n\nimport { AlertTriangle, CheckCircle2, Info, XCircle } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { Toaster as SonnerToaster, toast as sonnerToast } from \"sonner\";\n\nexport type ToasterProps = ComponentProps<typeof SonnerToaster>;\n\nexport type ToastVariant = \"default\" | \"success\" | \"warning\" | \"destructive\" | \"info\";\n\nexport interface ToastOptions {\n description?: ReactNode;\n variant?: ToastVariant;\n /** ms; mặc định theo sonner (4000). `Number.POSITIVE_INFINITY` = giữ đến khi người dùng đóng. */\n duration?: number;\n /** Nút hành động, vd { label: \"Hoàn tác\", onClick } */\n action?: { label: string; onClick: () => void };\n /** id để cập nhật/đóng đúng toast đó (dùng với luồng \"đang lưu…\" → \"đã lưu\") */\n id?: string | number;\n}\n\n/**\n * Vùng hiển thị toast — đặt MỘT LẦN ở gốc app.\n *\n * `theme` mặc định \"system\" và KHÔNG đọc `next-themes`: entry \".\" của package phải chạy được ở\n * app không có next-themes. App dùng next-themes hãy truyền xuống, nếu không toast sẽ theo\n * `prefers-color-scheme` của hệ điều hành và lệch với theme người dùng tự chọn:\n *\n * const { resolvedTheme } = useTheme();\n * <Toaster theme={resolvedTheme as \"light\" | \"dark\"} />\n */\nexport function Toaster({ theme = \"system\", position = \"bottom-right\", ...props }: ToasterProps) {\n return (\n <SonnerToaster\n theme={theme}\n position={position}\n className=\"toaster group\"\n icons={{\n success: <CheckCircle2 className=\"size-4 text-success\" />,\n warning: <AlertTriangle className=\"size-4 text-warning\" />,\n error: <XCircle className=\"size-4 text-destructive\" />,\n info: <Info className=\"size-4 text-info\" />\n }}\n toastOptions={{\n classNames: {\n toast:\n \"group toast group-[.toaster]:bg-popover group-[.toaster]:text-popover-foreground group-[.toaster]:border-border group-[.toaster]:rounded-lg group-[.toaster]:shadow-card\",\n title: \"group-[.toast]:text-sm group-[.toast]:font-medium\",\n description: \"group-[.toast]:text-sm group-[.toast]:text-muted-foreground\",\n actionButton: \"group-[.toast]:bg-primary group-[.toast]:text-primary-foreground\",\n cancelButton: \"group-[.toast]:bg-muted group-[.toast]:text-muted-foreground\"\n }\n }}\n {...props}\n />\n );\n}\n\n/**\n * Bắn toast theo biến thể của Comitor.\n *\n * Vì sao bọc `sonner` thay vì để app gọi thẳng: tên biến thể ở đây khớp với ngôn ngữ của design\n * system (`destructive`, không phải `error`), và khi cần đổi thư viện toast thì chỉ sửa một file.\n */\nexport function toast(title: ReactNode, options: ToastOptions = {}): string | number {\n const { variant = \"default\", description, duration, action, id } = options;\n const config = { description, duration, action, id };\n\n switch (variant) {\n case \"success\":\n return sonnerToast.success(title, config);\n case \"warning\":\n return sonnerToast.warning(title, config);\n case \"destructive\":\n return sonnerToast.error(title, config);\n case \"info\":\n return sonnerToast.info(title, config);\n default:\n return sonnerToast(title, config);\n }\n}\n\n/** Đóng một toast theo id, hoặc đóng tất cả khi không truyền id. */\nexport function dismissToast(id?: string | number): void {\n sonnerToast.dismiss(id);\n}\n\n/**\n * Toast bám theo một Promise: \"Đang lưu…\" → \"Đã lưu\" / \"Lưu thất bại\".\n * Chuỗi mặc định là tiếng Việt, app ghi đè được từng chuỗi.\n */\nexport function toastPromise<T>(\n promise: Promise<T>,\n messages: {\n loading?: ReactNode;\n success: ReactNode | ((data: T) => ReactNode);\n error: ReactNode | ((error: unknown) => ReactNode);\n }\n) {\n return sonnerToast.promise(promise, {\n loading: messages.loading ?? \"Đang xử lý…\",\n success: messages.success,\n error: messages.error\n });\n}\n"],"mappings":";AAsCiB;AApCjB,SAAS,eAAe,cAAc,MAAM,eAAe;AAE3D,SAAS,WAAW,eAAe,SAAS,mBAAmB;AA2BxD,SAAS,QAAQ,EAAE,QAAQ,UAAU,WAAW,gBAAgB,GAAG,MAAM,GAAiB;AAC/F,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,WAAU;AAAA,MACV,OAAO;AAAA,QACL,SAAS,oBAAC,gBAAa,WAAU,uBAAsB;AAAA,QACvD,SAAS,oBAAC,iBAAc,WAAU,uBAAsB;AAAA,QACxD,OAAO,oBAAC,WAAQ,WAAU,2BAA0B;AAAA,QACpD,MAAM,oBAAC,QAAK,WAAU,oBAAmB;AAAA,MAC3C;AAAA,MACA,cAAc;AAAA,QACZ,YAAY;AAAA,UACV,OACE;AAAA,UACF,OAAO;AAAA,UACP,aAAa;AAAA,UACb,cAAc;AAAA,UACd,cAAc;AAAA,QAChB;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAQO,SAAS,MAAM,OAAkB,UAAwB,CAAC,GAAoB;AACnF,QAAM,EAAE,UAAU,WAAW,aAAa,UAAU,QAAQ,GAAG,IAAI;AACnE,QAAM,SAAS,EAAE,aAAa,UAAU,QAAQ,GAAG;AAEnD,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO,YAAY,QAAQ,OAAO,MAAM;AAAA,IAC1C,KAAK;AACH,aAAO,YAAY,QAAQ,OAAO,MAAM;AAAA,IAC1C,KAAK;AACH,aAAO,YAAY,MAAM,OAAO,MAAM;AAAA,IACxC,KAAK;AACH,aAAO,YAAY,KAAK,OAAO,MAAM;AAAA,IACvC;AACE,aAAO,YAAY,OAAO,MAAM;AAAA,EACpC;AACF;AAGO,SAAS,aAAa,IAA4B;AACvD,cAAY,QAAQ,EAAE;AACxB;AAMO,SAAS,aACd,SACA,UAKA;AACA,SAAO,YAAY,QAAQ,SAAS;AAAA,IAClC,SAAS,SAAS,WAAW;AAAA,IAC7B,SAAS,SAAS;AAAA,IAClB,OAAO,SAAS;AAAA,EAClB,CAAC;AACH;","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as AccordionPrimitive from '@radix-ui/react-accordion';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Accordion (Radix). Animation `animate-accordion-down/up` do `tw-animate-css`
|
|
6
|
+
* cung cấp (đã @import trong styles.css) — không tự khai keyframes ở đây.
|
|
7
|
+
*/
|
|
8
|
+
type AccordionProps = React.ComponentProps<typeof AccordionPrimitive.Root>;
|
|
9
|
+
type AccordionItemProps = React.ComponentProps<typeof AccordionPrimitive.Item>;
|
|
10
|
+
type AccordionTriggerProps = React.ComponentProps<typeof AccordionPrimitive.Trigger>;
|
|
11
|
+
type AccordionContentProps = React.ComponentProps<typeof AccordionPrimitive.Content>;
|
|
12
|
+
declare function Accordion({ ...props }: AccordionProps): React.JSX.Element;
|
|
13
|
+
declare function AccordionItem({ className, ...props }: AccordionItemProps): React.JSX.Element;
|
|
14
|
+
declare function AccordionTrigger({ className, children, ...props }: AccordionTriggerProps): React.JSX.Element;
|
|
15
|
+
declare function AccordionContent({ className, children, ...props }: AccordionContentProps): React.JSX.Element;
|
|
16
|
+
|
|
17
|
+
export { Accordion, AccordionContent, type AccordionContentProps, AccordionItem, type AccordionItemProps, type AccordionProps, AccordionTrigger, type AccordionTriggerProps };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as AccordionPrimitive from "@radix-ui/react-accordion";
|
|
4
|
+
import { ChevronDownIcon } from "lucide-react";
|
|
5
|
+
import { cn } from "../../lib/cn.js";
|
|
6
|
+
function Accordion({ ...props }) {
|
|
7
|
+
return /* @__PURE__ */ jsx(AccordionPrimitive.Root, { "data-slot": "accordion", ...props });
|
|
8
|
+
}
|
|
9
|
+
function AccordionItem({ className, ...props }) {
|
|
10
|
+
return /* @__PURE__ */ jsx(
|
|
11
|
+
AccordionPrimitive.Item,
|
|
12
|
+
{
|
|
13
|
+
"data-slot": "accordion-item",
|
|
14
|
+
className: cn("border-b last:border-b-0", className),
|
|
15
|
+
...props
|
|
16
|
+
}
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
function AccordionTrigger({ className, children, ...props }) {
|
|
20
|
+
return /* @__PURE__ */ jsx(AccordionPrimitive.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
|
|
21
|
+
AccordionPrimitive.Trigger,
|
|
22
|
+
{
|
|
23
|
+
"data-slot": "accordion-trigger",
|
|
24
|
+
className: cn(
|
|
25
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-colors duration-150 ease-out outline-none hover:underline disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180",
|
|
26
|
+
className
|
|
27
|
+
),
|
|
28
|
+
...props,
|
|
29
|
+
children: [
|
|
30
|
+
children,
|
|
31
|
+
/* @__PURE__ */ jsx(ChevronDownIcon, { className: "text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200" })
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
) });
|
|
35
|
+
}
|
|
36
|
+
function AccordionContent({ className, children, ...props }) {
|
|
37
|
+
return /* @__PURE__ */ jsx(
|
|
38
|
+
AccordionPrimitive.Content,
|
|
39
|
+
{
|
|
40
|
+
"data-slot": "accordion-content",
|
|
41
|
+
className: "data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm",
|
|
42
|
+
...props,
|
|
43
|
+
children: /* @__PURE__ */ jsx("div", { className: cn("pt-0 pb-4", className), children })
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
Accordion,
|
|
49
|
+
AccordionContent,
|
|
50
|
+
AccordionItem,
|
|
51
|
+
AccordionTrigger
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=accordion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/accordion.tsx"],"sourcesContent":["\"use client\";\n\nimport * as AccordionPrimitive from \"@radix-ui/react-accordion\";\nimport { ChevronDownIcon } from \"lucide-react\";\nimport type * as React from \"react\";\nimport { cn } from \"../../lib/cn.js\";\n\n/**\n * Accordion (Radix). Animation `animate-accordion-down/up` do `tw-animate-css`\n * cung cấp (đã @import trong styles.css) — không tự khai keyframes ở đây.\n */\n\nexport type AccordionProps = React.ComponentProps<typeof AccordionPrimitive.Root>;\nexport type AccordionItemProps = React.ComponentProps<typeof AccordionPrimitive.Item>;\nexport type AccordionTriggerProps = React.ComponentProps<typeof AccordionPrimitive.Trigger>;\nexport type AccordionContentProps = React.ComponentProps<typeof AccordionPrimitive.Content>;\n\nfunction Accordion({ ...props }: AccordionProps) {\n return <AccordionPrimitive.Root data-slot=\"accordion\" {...props} />;\n}\n\nfunction AccordionItem({ className, ...props }: AccordionItemProps) {\n return (\n <AccordionPrimitive.Item\n data-slot=\"accordion-item\"\n className={cn(\"border-b last:border-b-0\", className)}\n {...props}\n />\n );\n}\n\nfunction AccordionTrigger({ className, children, ...props }: AccordionTriggerProps) {\n return (\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n data-slot=\"accordion-trigger\"\n className={cn(\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-colors duration-150 ease-out outline-none hover:underline disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronDownIcon className=\"text-muted-foreground pointer-events-none size-4 shrink-0 translate-y-0.5 transition-transform duration-200\" />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n}\n\nfunction AccordionContent({ className, children, ...props }: AccordionContentProps) {\n return (\n <AccordionPrimitive.Content\n data-slot=\"accordion-content\"\n className=\"data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm\"\n {...props}\n >\n <div className={cn(\"pt-0 pb-4\", className)}>{children}</div>\n </AccordionPrimitive.Content>\n );\n}\n\nexport { Accordion, AccordionContent, AccordionItem, AccordionTrigger };\n"],"mappings":";AAkBS,cAgBH,YAhBG;AAhBT,YAAY,wBAAwB;AACpC,SAAS,uBAAuB;AAEhC,SAAS,UAAU;AAYnB,SAAS,UAAU,EAAE,GAAG,MAAM,GAAmB;AAC/C,SAAO,oBAAC,mBAAmB,MAAnB,EAAwB,aAAU,aAAa,GAAG,OAAO;AACnE;AAEA,SAAS,cAAc,EAAE,WAAW,GAAG,MAAM,GAAuB;AAClE,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,4BAA4B,SAAS;AAAA,MAClD,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,iBAAiB,EAAE,WAAW,UAAU,GAAG,MAAM,GAA0B;AAClF,SACE,oBAAC,mBAAmB,QAAnB,EAA0B,WAAU,QACnC;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,QACD,oBAAC,mBAAgB,WAAU,+GAA8G;AAAA;AAAA;AAAA,EAC3I,GACF;AAEJ;AAEA,SAAS,iBAAiB,EAAE,WAAW,UAAU,GAAG,MAAM,GAA0B;AAClF,SACE;AAAA,IAAC,mBAAmB;AAAA,IAAnB;AAAA,MACC,aAAU;AAAA,MACV,WAAU;AAAA,MACT,GAAG;AAAA,MAEJ,8BAAC,SAAI,WAAW,GAAG,aAAa,SAAS,GAAI,UAAS;AAAA;AAAA,EACxD;AAEJ;","names":[]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* AlertDialog — hộp thoại xác nhận (Radix AlertDialog): chặn thao tác, buộc chọn
|
|
6
|
+
* Hủy/Đồng ý, không đóng được bằng click ra ngoài.
|
|
7
|
+
*
|
|
8
|
+
* Nút Action/Cancel mượn `buttonVariants` của Button để đồng bộ thị giác.
|
|
9
|
+
* Composite `ConfirmDialog` (Tier 2) sẽ bọc component này.
|
|
10
|
+
*/
|
|
11
|
+
type AlertDialogProps = React.ComponentProps<typeof AlertDialogPrimitive.Root>;
|
|
12
|
+
declare function AlertDialog({ ...props }: AlertDialogProps): React.JSX.Element;
|
|
13
|
+
type AlertDialogTriggerProps = React.ComponentProps<typeof AlertDialogPrimitive.Trigger>;
|
|
14
|
+
declare function AlertDialogTrigger({ ...props }: AlertDialogTriggerProps): React.JSX.Element;
|
|
15
|
+
type AlertDialogPortalProps = React.ComponentProps<typeof AlertDialogPrimitive.Portal>;
|
|
16
|
+
declare function AlertDialogPortal({ ...props }: AlertDialogPortalProps): React.JSX.Element;
|
|
17
|
+
type AlertDialogOverlayProps = React.ComponentProps<typeof AlertDialogPrimitive.Overlay>;
|
|
18
|
+
declare function AlertDialogOverlay({ className, ...props }: AlertDialogOverlayProps): React.JSX.Element;
|
|
19
|
+
type AlertDialogContentProps = React.ComponentProps<typeof AlertDialogPrimitive.Content>;
|
|
20
|
+
declare function AlertDialogContent({ className, ...props }: AlertDialogContentProps): React.JSX.Element;
|
|
21
|
+
type AlertDialogHeaderProps = React.ComponentProps<"div">;
|
|
22
|
+
declare function AlertDialogHeader({ className, ...props }: AlertDialogHeaderProps): React.JSX.Element;
|
|
23
|
+
type AlertDialogFooterProps = React.ComponentProps<"div">;
|
|
24
|
+
declare function AlertDialogFooter({ className, ...props }: AlertDialogFooterProps): React.JSX.Element;
|
|
25
|
+
type AlertDialogTitleProps = React.ComponentProps<typeof AlertDialogPrimitive.Title>;
|
|
26
|
+
declare function AlertDialogTitle({ className, ...props }: AlertDialogTitleProps): React.JSX.Element;
|
|
27
|
+
type AlertDialogDescriptionProps = React.ComponentProps<typeof AlertDialogPrimitive.Description>;
|
|
28
|
+
declare function AlertDialogDescription({ className, ...props }: AlertDialogDescriptionProps): React.JSX.Element;
|
|
29
|
+
type AlertDialogActionProps = React.ComponentProps<typeof AlertDialogPrimitive.Action>;
|
|
30
|
+
declare function AlertDialogAction({ className, ...props }: AlertDialogActionProps): React.JSX.Element;
|
|
31
|
+
type AlertDialogCancelProps = React.ComponentProps<typeof AlertDialogPrimitive.Cancel>;
|
|
32
|
+
declare function AlertDialogCancel({ className, ...props }: AlertDialogCancelProps): React.JSX.Element;
|
|
33
|
+
|
|
34
|
+
export { AlertDialog, AlertDialogAction, type AlertDialogActionProps, AlertDialogCancel, type AlertDialogCancelProps, AlertDialogContent, type AlertDialogContentProps, AlertDialogDescription, type AlertDialogDescriptionProps, AlertDialogFooter, type AlertDialogFooterProps, AlertDialogHeader, type AlertDialogHeaderProps, AlertDialogOverlay, type AlertDialogOverlayProps, AlertDialogPortal, type AlertDialogPortalProps, type AlertDialogProps, AlertDialogTitle, type AlertDialogTitleProps, AlertDialogTrigger, type AlertDialogTriggerProps };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
|
|
4
|
+
import { cn } from "../../lib/cn.js";
|
|
5
|
+
import { buttonVariants } from "./button.js";
|
|
6
|
+
function AlertDialog({ ...props }) {
|
|
7
|
+
return /* @__PURE__ */ jsx(AlertDialogPrimitive.Root, { "data-slot": "alert-dialog", ...props });
|
|
8
|
+
}
|
|
9
|
+
function AlertDialogTrigger({ ...props }) {
|
|
10
|
+
return /* @__PURE__ */ jsx(AlertDialogPrimitive.Trigger, { "data-slot": "alert-dialog-trigger", ...props });
|
|
11
|
+
}
|
|
12
|
+
function AlertDialogPortal({ ...props }) {
|
|
13
|
+
return /* @__PURE__ */ jsx(AlertDialogPrimitive.Portal, { "data-slot": "alert-dialog-portal", ...props });
|
|
14
|
+
}
|
|
15
|
+
function AlertDialogOverlay({ className, ...props }) {
|
|
16
|
+
return /* @__PURE__ */ jsx(
|
|
17
|
+
AlertDialogPrimitive.Overlay,
|
|
18
|
+
{
|
|
19
|
+
"data-slot": "alert-dialog-overlay",
|
|
20
|
+
className: cn(
|
|
21
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-ink/60 dark:bg-ink/80 backdrop-blur-sm",
|
|
22
|
+
className
|
|
23
|
+
),
|
|
24
|
+
...props
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
function AlertDialogContent({ className, ...props }) {
|
|
29
|
+
return /* @__PURE__ */ jsxs(AlertDialogPortal, { children: [
|
|
30
|
+
/* @__PURE__ */ jsx(AlertDialogOverlay, {}),
|
|
31
|
+
/* @__PURE__ */ jsx(
|
|
32
|
+
AlertDialogPrimitive.Content,
|
|
33
|
+
{
|
|
34
|
+
"data-slot": "alert-dialog-content",
|
|
35
|
+
className: cn(
|
|
36
|
+
"bg-card 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 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-xl border border-border p-6 shadow-overlay duration-200 sm:max-w-lg",
|
|
37
|
+
className
|
|
38
|
+
),
|
|
39
|
+
...props
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
] });
|
|
43
|
+
}
|
|
44
|
+
function AlertDialogHeader({ className, ...props }) {
|
|
45
|
+
return /* @__PURE__ */ jsx(
|
|
46
|
+
"div",
|
|
47
|
+
{
|
|
48
|
+
"data-slot": "alert-dialog-header",
|
|
49
|
+
className: cn("flex flex-col gap-2 text-center sm:text-left", className),
|
|
50
|
+
...props
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
function AlertDialogFooter({ className, ...props }) {
|
|
55
|
+
return /* @__PURE__ */ jsx(
|
|
56
|
+
"div",
|
|
57
|
+
{
|
|
58
|
+
"data-slot": "alert-dialog-footer",
|
|
59
|
+
className: cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className),
|
|
60
|
+
...props
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
function AlertDialogTitle({ className, ...props }) {
|
|
65
|
+
return /* @__PURE__ */ jsx(
|
|
66
|
+
AlertDialogPrimitive.Title,
|
|
67
|
+
{
|
|
68
|
+
"data-slot": "alert-dialog-title",
|
|
69
|
+
className: cn("text-lg font-semibold text-foreground", className),
|
|
70
|
+
...props
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
function AlertDialogDescription({ className, ...props }) {
|
|
75
|
+
return /* @__PURE__ */ jsx(
|
|
76
|
+
AlertDialogPrimitive.Description,
|
|
77
|
+
{
|
|
78
|
+
"data-slot": "alert-dialog-description",
|
|
79
|
+
className: cn("text-muted-foreground text-sm", className),
|
|
80
|
+
...props
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
function AlertDialogAction({ className, ...props }) {
|
|
85
|
+
return /* @__PURE__ */ jsx(AlertDialogPrimitive.Action, { className: cn(buttonVariants(), className), ...props });
|
|
86
|
+
}
|
|
87
|
+
function AlertDialogCancel({ className, ...props }) {
|
|
88
|
+
return /* @__PURE__ */ jsx(AlertDialogPrimitive.Cancel, { className: cn(buttonVariants({ variant: "outline" }), className), ...props });
|
|
89
|
+
}
|
|
90
|
+
export {
|
|
91
|
+
AlertDialog,
|
|
92
|
+
AlertDialogAction,
|
|
93
|
+
AlertDialogCancel,
|
|
94
|
+
AlertDialogContent,
|
|
95
|
+
AlertDialogDescription,
|
|
96
|
+
AlertDialogFooter,
|
|
97
|
+
AlertDialogHeader,
|
|
98
|
+
AlertDialogOverlay,
|
|
99
|
+
AlertDialogPortal,
|
|
100
|
+
AlertDialogTitle,
|
|
101
|
+
AlertDialogTrigger
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=alert-dialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/alert-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport * as AlertDialogPrimitive from \"@radix-ui/react-alert-dialog\";\nimport type * as React from \"react\";\nimport { cn } from \"../../lib/cn.js\";\nimport { buttonVariants } from \"./button.js\";\n\n/**\n * AlertDialog — hộp thoại xác nhận (Radix AlertDialog): chặn thao tác, buộc chọn\n * Hủy/Đồng ý, không đóng được bằng click ra ngoài.\n *\n * Nút Action/Cancel mượn `buttonVariants` của Button để đồng bộ thị giác.\n * Composite `ConfirmDialog` (Tier 2) sẽ bọc component này.\n */\n\nexport type AlertDialogProps = React.ComponentProps<typeof AlertDialogPrimitive.Root>;\n\nfunction AlertDialog({ ...props }: AlertDialogProps) {\n return <AlertDialogPrimitive.Root data-slot=\"alert-dialog\" {...props} />;\n}\n\nexport type AlertDialogTriggerProps = React.ComponentProps<typeof AlertDialogPrimitive.Trigger>;\n\nfunction AlertDialogTrigger({ ...props }: AlertDialogTriggerProps) {\n return <AlertDialogPrimitive.Trigger data-slot=\"alert-dialog-trigger\" {...props} />;\n}\n\nexport type AlertDialogPortalProps = React.ComponentProps<typeof AlertDialogPrimitive.Portal>;\n\nfunction AlertDialogPortal({ ...props }: AlertDialogPortalProps) {\n return <AlertDialogPrimitive.Portal data-slot=\"alert-dialog-portal\" {...props} />;\n}\n\nexport type AlertDialogOverlayProps = React.ComponentProps<typeof AlertDialogPrimitive.Overlay>;\n\nfunction AlertDialogOverlay({ className, ...props }: AlertDialogOverlayProps) {\n return (\n <AlertDialogPrimitive.Overlay\n data-slot=\"alert-dialog-overlay\"\n className={cn(\n \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-ink/60 dark:bg-ink/80 backdrop-blur-sm\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport type AlertDialogContentProps = React.ComponentProps<typeof AlertDialogPrimitive.Content>;\n\nfunction AlertDialogContent({ className, ...props }: AlertDialogContentProps) {\n return (\n <AlertDialogPortal>\n <AlertDialogOverlay />\n <AlertDialogPrimitive.Content\n data-slot=\"alert-dialog-content\"\n className={cn(\n \"bg-card 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 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-xl border border-border p-6 shadow-overlay duration-200 sm:max-w-lg\",\n className\n )}\n {...props}\n />\n </AlertDialogPortal>\n );\n}\n\nexport type AlertDialogHeaderProps = React.ComponentProps<\"div\">;\n\nfunction AlertDialogHeader({ className, ...props }: AlertDialogHeaderProps) {\n return (\n <div\n data-slot=\"alert-dialog-header\"\n className={cn(\"flex flex-col gap-2 text-center sm:text-left\", className)}\n {...props}\n />\n );\n}\n\nexport type AlertDialogFooterProps = React.ComponentProps<\"div\">;\n\nfunction AlertDialogFooter({ className, ...props }: AlertDialogFooterProps) {\n return (\n <div\n data-slot=\"alert-dialog-footer\"\n className={cn(\"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\", className)}\n {...props}\n />\n );\n}\n\nexport type AlertDialogTitleProps = React.ComponentProps<typeof AlertDialogPrimitive.Title>;\n\nfunction AlertDialogTitle({ className, ...props }: AlertDialogTitleProps) {\n return (\n <AlertDialogPrimitive.Title\n data-slot=\"alert-dialog-title\"\n className={cn(\"text-lg font-semibold text-foreground\", className)}\n {...props}\n />\n );\n}\n\nexport type AlertDialogDescriptionProps = React.ComponentProps<typeof AlertDialogPrimitive.Description>;\n\nfunction AlertDialogDescription({ className, ...props }: AlertDialogDescriptionProps) {\n return (\n <AlertDialogPrimitive.Description\n data-slot=\"alert-dialog-description\"\n className={cn(\"text-muted-foreground text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport type AlertDialogActionProps = React.ComponentProps<typeof AlertDialogPrimitive.Action>;\n\nfunction AlertDialogAction({ className, ...props }: AlertDialogActionProps) {\n return <AlertDialogPrimitive.Action className={cn(buttonVariants(), className)} {...props} />;\n}\n\nexport type AlertDialogCancelProps = React.ComponentProps<typeof AlertDialogPrimitive.Cancel>;\n\nfunction AlertDialogCancel({ className, ...props }: AlertDialogCancelProps) {\n return <AlertDialogPrimitive.Cancel className={cn(buttonVariants({ variant: \"outline\" }), className)} {...props} />;\n}\n\nexport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogOverlay,\n AlertDialogPortal,\n AlertDialogTitle,\n AlertDialogTrigger\n};\n"],"mappings":";AAkBS,cAkCL,YAlCK;AAhBT,YAAY,0BAA0B;AAEtC,SAAS,UAAU;AACnB,SAAS,sBAAsB;AAY/B,SAAS,YAAY,EAAE,GAAG,MAAM,GAAqB;AACnD,SAAO,oBAAC,qBAAqB,MAArB,EAA0B,aAAU,gBAAgB,GAAG,OAAO;AACxE;AAIA,SAAS,mBAAmB,EAAE,GAAG,MAAM,GAA4B;AACjE,SAAO,oBAAC,qBAAqB,SAArB,EAA6B,aAAU,wBAAwB,GAAG,OAAO;AACnF;AAIA,SAAS,kBAAkB,EAAE,GAAG,MAAM,GAA2B;AAC/D,SAAO,oBAAC,qBAAqB,QAArB,EAA4B,aAAU,uBAAuB,GAAG,OAAO;AACjF;AAIA,SAAS,mBAAmB,EAAE,WAAW,GAAG,MAAM,GAA4B;AAC5E,SACE;AAAA,IAAC,qBAAqB;AAAA,IAArB;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAIA,SAAS,mBAAmB,EAAE,WAAW,GAAG,MAAM,GAA4B;AAC5E,SACE,qBAAC,qBACC;AAAA,wBAAC,sBAAmB;AAAA,IACpB;AAAA,MAAC,qBAAqB;AAAA,MAArB;AAAA,QACC,aAAU;AAAA,QACV,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACC,GAAG;AAAA;AAAA,IACN;AAAA,KACF;AAEJ;AAIA,SAAS,kBAAkB,EAAE,WAAW,GAAG,MAAM,GAA2B;AAC1E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,gDAAgD,SAAS;AAAA,MACtE,GAAG;AAAA;AAAA,EACN;AAEJ;AAIA,SAAS,kBAAkB,EAAE,WAAW,GAAG,MAAM,GAA2B;AAC1E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,0DAA0D,SAAS;AAAA,MAChF,GAAG;AAAA;AAAA,EACN;AAEJ;AAIA,SAAS,iBAAiB,EAAE,WAAW,GAAG,MAAM,GAA0B;AACxE,SACE;AAAA,IAAC,qBAAqB;AAAA,IAArB;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,yCAAyC,SAAS;AAAA,MAC/D,GAAG;AAAA;AAAA,EACN;AAEJ;AAIA,SAAS,uBAAuB,EAAE,WAAW,GAAG,MAAM,GAAgC;AACpF,SACE;AAAA,IAAC,qBAAqB;AAAA,IAArB;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,iCAAiC,SAAS;AAAA,MACvD,GAAG;AAAA;AAAA,EACN;AAEJ;AAIA,SAAS,kBAAkB,EAAE,WAAW,GAAG,MAAM,GAA2B;AAC1E,SAAO,oBAAC,qBAAqB,QAArB,EAA4B,WAAW,GAAG,eAAe,GAAG,SAAS,GAAI,GAAG,OAAO;AAC7F;AAIA,SAAS,kBAAkB,EAAE,WAAW,GAAG,MAAM,GAA2B;AAC1E,SAAO,oBAAC,qBAAqB,QAArB,EAA4B,WAAW,GAAG,eAAe,EAAE,SAAS,UAAU,CAAC,GAAG,SAAS,GAAI,GAAG,OAAO;AACnH;","names":[]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
2
|
+
import { VariantProps } from 'class-variance-authority';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
|
|
5
|
+
declare const alertVariants: (props?: ({
|
|
6
|
+
variant?: "default" | "destructive" | null | undefined;
|
|
7
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
8
|
+
interface AlertProps extends React.ComponentProps<"div">, VariantProps<typeof alertVariants> {
|
|
9
|
+
}
|
|
10
|
+
type AlertTitleProps = React.ComponentProps<"div">;
|
|
11
|
+
type AlertDescriptionProps = React.ComponentProps<"div">;
|
|
12
|
+
declare function Alert({ className, variant, ...props }: AlertProps): React.JSX.Element;
|
|
13
|
+
declare function AlertTitle({ className, ...props }: AlertTitleProps): React.JSX.Element;
|
|
14
|
+
declare function AlertDescription({ className, ...props }: AlertDescriptionProps): React.JSX.Element;
|
|
15
|
+
|
|
16
|
+
export { Alert, AlertDescription, type AlertDescriptionProps, type AlertProps, AlertTitle, type AlertTitleProps, alertVariants };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cva } from "class-variance-authority";
|
|
3
|
+
import { cn } from "../../lib/cn.js";
|
|
4
|
+
const alertVariants = cva(
|
|
5
|
+
"relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
|
|
6
|
+
{
|
|
7
|
+
variants: {
|
|
8
|
+
variant: {
|
|
9
|
+
default: "bg-card text-card-foreground",
|
|
10
|
+
destructive: "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
defaultVariants: {
|
|
14
|
+
variant: "default"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
);
|
|
18
|
+
function Alert({ className, variant, ...props }) {
|
|
19
|
+
return /* @__PURE__ */ jsx("div", { "data-slot": "alert", role: "alert", className: cn(alertVariants({ variant }), className), ...props });
|
|
20
|
+
}
|
|
21
|
+
function AlertTitle({ className, ...props }) {
|
|
22
|
+
return /* @__PURE__ */ jsx(
|
|
23
|
+
"div",
|
|
24
|
+
{
|
|
25
|
+
"data-slot": "alert-title",
|
|
26
|
+
className: cn("col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight", className),
|
|
27
|
+
...props
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
function AlertDescription({ className, ...props }) {
|
|
32
|
+
return /* @__PURE__ */ jsx(
|
|
33
|
+
"div",
|
|
34
|
+
{
|
|
35
|
+
"data-slot": "alert-description",
|
|
36
|
+
className: cn(
|
|
37
|
+
"text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed",
|
|
38
|
+
className
|
|
39
|
+
),
|
|
40
|
+
...props
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
Alert,
|
|
46
|
+
AlertDescription,
|
|
47
|
+
AlertTitle,
|
|
48
|
+
alertVariants
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=alert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/alert.tsx"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\nimport type * as React from \"react\";\nimport { cn } from \"../../lib/cn.js\";\n\nconst alertVariants = cva(\n \"relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current\",\n {\n variants: {\n variant: {\n default: \"bg-card text-card-foreground\",\n destructive: \"text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90\"\n }\n },\n defaultVariants: {\n variant: \"default\"\n }\n }\n);\n\nexport interface AlertProps extends React.ComponentProps<\"div\">, VariantProps<typeof alertVariants> {}\nexport type AlertTitleProps = React.ComponentProps<\"div\">;\nexport type AlertDescriptionProps = React.ComponentProps<\"div\">;\n\nfunction Alert({ className, variant, ...props }: AlertProps) {\n return <div data-slot=\"alert\" role=\"alert\" className={cn(alertVariants({ variant }), className)} {...props} />;\n}\n\nfunction AlertTitle({ className, ...props }: AlertTitleProps) {\n return (\n <div\n data-slot=\"alert-title\"\n className={cn(\"col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight\", className)}\n {...props}\n />\n );\n}\n\nfunction AlertDescription({ className, ...props }: AlertDescriptionProps) {\n return (\n <div\n data-slot=\"alert-description\"\n className={cn(\n \"text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport { Alert, AlertDescription, AlertTitle, alertVariants };\n"],"mappings":"AAwBS;AAxBT,SAAS,WAA8B;AAEvC,SAAS,UAAU;AAEnB,MAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS;AAAA,QACT,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,IACX;AAAA,EACF;AACF;AAMA,SAAS,MAAM,EAAE,WAAW,SAAS,GAAG,MAAM,GAAe;AAC3D,SAAO,oBAAC,SAAI,aAAU,SAAQ,MAAK,SAAQ,WAAW,GAAG,cAAc,EAAE,QAAQ,CAAC,GAAG,SAAS,GAAI,GAAG,OAAO;AAC9G;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,MAAM,GAAoB;AAC5D,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,+DAA+D,SAAS;AAAA,MACrF,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,iBAAiB,EAAE,WAAW,GAAG,MAAM,GAA0B;AACxE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
type AspectRatioProps = React.ComponentProps<typeof AspectRatioPrimitive.Root>;
|
|
5
|
+
declare function AspectRatio({ ...props }: AspectRatioProps): React.JSX.Element;
|
|
6
|
+
|
|
7
|
+
export { AspectRatio, type AspectRatioProps };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio";
|
|
4
|
+
function AspectRatio({ ...props }) {
|
|
5
|
+
return /* @__PURE__ */ jsx(AspectRatioPrimitive.Root, { "data-slot": "aspect-ratio", ...props });
|
|
6
|
+
}
|
|
7
|
+
export {
|
|
8
|
+
AspectRatio
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=aspect-ratio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/aspect-ratio.tsx"],"sourcesContent":["\"use client\";\n\nimport * as AspectRatioPrimitive from \"@radix-ui/react-aspect-ratio\";\nimport type * as React from \"react\";\n\nexport type AspectRatioProps = React.ComponentProps<typeof AspectRatioPrimitive.Root>;\n\nfunction AspectRatio({ ...props }: AspectRatioProps) {\n return <AspectRatioPrimitive.Root data-slot=\"aspect-ratio\" {...props} />;\n}\n\nexport { AspectRatio };\n"],"mappings":";AAQS;AANT,YAAY,0BAA0B;AAKtC,SAAS,YAAY,EAAE,GAAG,MAAM,GAAqB;AACnD,SAAO,oBAAC,qBAAqB,MAArB,EAA0B,aAAU,gBAAgB,GAAG,OAAO;AACxE;","names":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
type AvatarProps = React.ComponentProps<typeof AvatarPrimitive.Root>;
|
|
5
|
+
type AvatarImageProps = React.ComponentProps<typeof AvatarPrimitive.Image>;
|
|
6
|
+
type AvatarFallbackProps = React.ComponentProps<typeof AvatarPrimitive.Fallback>;
|
|
7
|
+
declare function Avatar({ className, ...props }: AvatarProps): React.JSX.Element;
|
|
8
|
+
declare function AvatarImage({ className, ...props }: AvatarImageProps): React.JSX.Element;
|
|
9
|
+
declare function AvatarFallback({ className, ...props }: AvatarFallbackProps): React.JSX.Element;
|
|
10
|
+
|
|
11
|
+
export { Avatar, AvatarFallback, type AvatarFallbackProps, AvatarImage, type AvatarImageProps, type AvatarProps };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
4
|
+
import { cn } from "../../lib/cn.js";
|
|
5
|
+
function Avatar({ className, ...props }) {
|
|
6
|
+
return /* @__PURE__ */ jsx(
|
|
7
|
+
AvatarPrimitive.Root,
|
|
8
|
+
{
|
|
9
|
+
"data-slot": "avatar",
|
|
10
|
+
className: cn("relative flex size-8 shrink-0 overflow-hidden rounded-full", className),
|
|
11
|
+
...props
|
|
12
|
+
}
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
function AvatarImage({ className, ...props }) {
|
|
16
|
+
return /* @__PURE__ */ jsx(AvatarPrimitive.Image, { "data-slot": "avatar-image", className: cn("aspect-square size-full", className), ...props });
|
|
17
|
+
}
|
|
18
|
+
function AvatarFallback({ className, ...props }) {
|
|
19
|
+
return /* @__PURE__ */ jsx(
|
|
20
|
+
AvatarPrimitive.Fallback,
|
|
21
|
+
{
|
|
22
|
+
"data-slot": "avatar-fallback",
|
|
23
|
+
className: cn("bg-muted flex size-full items-center justify-center rounded-full", className),
|
|
24
|
+
...props
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
Avatar,
|
|
30
|
+
AvatarFallback,
|
|
31
|
+
AvatarImage
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=avatar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/avatar.tsx"],"sourcesContent":["\"use client\";\n\nimport * as AvatarPrimitive from \"@radix-ui/react-avatar\";\nimport type * as React from \"react\";\nimport { cn } from \"../../lib/cn.js\";\n\nexport type AvatarProps = React.ComponentProps<typeof AvatarPrimitive.Root>;\nexport type AvatarImageProps = React.ComponentProps<typeof AvatarPrimitive.Image>;\nexport type AvatarFallbackProps = React.ComponentProps<typeof AvatarPrimitive.Fallback>;\n\nfunction Avatar({ className, ...props }: AvatarProps) {\n return (\n <AvatarPrimitive.Root\n data-slot=\"avatar\"\n className={cn(\"relative flex size-8 shrink-0 overflow-hidden rounded-full\", className)}\n {...props}\n />\n );\n}\n\nfunction AvatarImage({ className, ...props }: AvatarImageProps) {\n return (\n <AvatarPrimitive.Image data-slot=\"avatar-image\" className={cn(\"aspect-square size-full\", className)} {...props} />\n );\n}\n\nfunction AvatarFallback({ className, ...props }: AvatarFallbackProps) {\n return (\n <AvatarPrimitive.Fallback\n data-slot=\"avatar-fallback\"\n className={cn(\"bg-muted flex size-full items-center justify-center rounded-full\", className)}\n {...props}\n />\n );\n}\n\nexport { Avatar, AvatarFallback, AvatarImage };\n"],"mappings":";AAYI;AAVJ,YAAY,qBAAqB;AAEjC,SAAS,UAAU;AAMnB,SAAS,OAAO,EAAE,WAAW,GAAG,MAAM,GAAgB;AACpD,SACE;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,8DAA8D,SAAS;AAAA,MACpF,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,MAAM,GAAqB;AAC9D,SACE,oBAAC,gBAAgB,OAAhB,EAAsB,aAAU,gBAAe,WAAW,GAAG,2BAA2B,SAAS,GAAI,GAAG,OAAO;AAEpH;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAAwB;AACpE,SACE;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,oEAAoE,SAAS;AAAA,MAC1F,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
2
|
+
import { VariantProps } from 'class-variance-authority';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
|
|
5
|
+
declare const badgeVariants: (props?: ({
|
|
6
|
+
variant?: "default" | "primary" | "secondary" | "outline" | "success" | "warning" | "destructive" | null | undefined;
|
|
7
|
+
size?: "sm" | "md" | null | undefined;
|
|
8
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
9
|
+
interface BadgeProps extends React.ComponentProps<"span">, VariantProps<typeof badgeVariants> {
|
|
10
|
+
/** Render ra chính phần tử con (Radix Slot) thay vì thẻ <span>. */
|
|
11
|
+
asChild?: boolean;
|
|
12
|
+
}
|
|
13
|
+
declare function Badge({ className, variant, size, asChild, ...props }: BadgeProps): React.JSX.Element;
|
|
14
|
+
|
|
15
|
+
export { Badge, type BadgeProps, badgeVariants };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
3
|
+
import { cva } from "class-variance-authority";
|
|
4
|
+
import { cn } from "../../lib/cn.js";
|
|
5
|
+
const badgeVariants = cva(
|
|
6
|
+
"inline-flex items-center font-medium rounded-md whitespace-nowrap gap-1 [&>svg]:size-3 [&>svg]:pointer-events-none",
|
|
7
|
+
{
|
|
8
|
+
variants: {
|
|
9
|
+
variant: {
|
|
10
|
+
default: "bg-gold-100 text-gold-600 dark:bg-gold-500/20 dark:text-gold-200",
|
|
11
|
+
primary: "bg-gold-100 text-gold-600 dark:bg-gold-500/20 dark:text-gold-200",
|
|
12
|
+
secondary: "bg-secondary text-secondary-foreground",
|
|
13
|
+
outline: "bg-transparent border border-border text-foreground",
|
|
14
|
+
success: "bg-success/15 text-[color:color-mix(in_srgb,var(--success),var(--ink)_40%)] dark:text-success",
|
|
15
|
+
warning: "bg-warning/20 text-[color:color-mix(in_srgb,var(--warning),var(--ink)_55%)] dark:text-warning",
|
|
16
|
+
destructive: "bg-destructive/15 text-[color:color-mix(in_srgb,var(--destructive),var(--ink)_30%)] dark:text-red"
|
|
17
|
+
},
|
|
18
|
+
size: {
|
|
19
|
+
sm: "px-1.5 py-0.5 text-[10px]",
|
|
20
|
+
md: "px-2 py-0.5 text-xs"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
defaultVariants: {
|
|
24
|
+
variant: "default",
|
|
25
|
+
size: "md"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
function Badge({ className, variant, size, asChild = false, ...props }) {
|
|
30
|
+
const Comp = asChild ? Slot : "span";
|
|
31
|
+
return /* @__PURE__ */ jsx(Comp, { "data-slot": "badge", className: cn(badgeVariants({ variant, size }), className), ...props });
|
|
32
|
+
}
|
|
33
|
+
export {
|
|
34
|
+
Badge,
|
|
35
|
+
badgeVariants
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=badge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/badge.tsx"],"sourcesContent":["import { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport type * as React from \"react\";\nimport { cn } from \"../../lib/cn.js\";\n\n/*\n * Style port từ comitor-ds (biến thể tonal + 2 cỡ sm/md).\n * API giữ tương thích shadcn (cva + asChild + data-slot).\n *\n * ─ VÌ SAO CHỮ CỦA BIẾN THỂ TONAL PHẢI TRỘN THÊM `--ink` Ở LIGHT MODE ─\n *\n * Badge in chữ 10–12px nên phải đạt WCAG AA 4.5:1. Bản port cũ dùng thẳng\n * `text-green / text-yellow / text-red` trên nền tint 10% và HỎNG ở light mode\n * (đo bằng công thức WCAG, nền trắng):\n *\n * success #2EA56A trên bg-green/10 = 2,82:1 ✗\n * warning #F2C94C trên bg-yellow/10 = 1,52:1 ✗ (gần như không đọc được)\n * destructive #D64545 trên bg-red/10 = 3,83:1 ✗\n *\n * Nguyên tắc sửa lấy từ chính repo này (`composite/status-config.ts`,\n * `composite/stat-card.tsx`): bậc màu TỐI cho light, bậc SÁNG cho dark. Khác ở chỗ\n * thang gold có sẵn bậc tối (`gold-500`) để mượn, còn --success/--warning/--destructive\n * KHÔNG có bậc nào — nên bậc tối được DẪN XUẤT tại chỗ bằng `color-mix` với `--ink`.\n * Cách này giữ đúng luật \"không hex trong component\" và vẫn đổi theo app nào tự set lại\n * token của mình (nếu styles.css bổ sung bậc tối --success-600/--warning-600/… thì thay\n * mấy chuỗi color-mix bên dưới bằng token đó là xong).\n *\n * Tỉ lệ trộn khác nhau theo từng màu vì độ sáng gốc khác nhau (vàng sáng hơn lục,\n * lục sáng hơn đỏ); chọn sao cho mọi biến thể ≥ 5:1, có biên an toàn khi app đổi token:\n *\n * success ink 40% → #216948 trên bg-success/15 = 5,59:1 ✓\n * warning ink 55% → #74632E trên bg-warning/20 = 5,31:1 ✓\n * destructive ink 30% → #993536 trên bg-destructive/15 = 5,82:1 ✓\n *\n * Dark mode giữ token sáng, không cần trộn: 7,47:1 / 7,20:1 / 5,17:1 trên nền --card.\n * Riêng destructive ở dark phải dùng `dark:text-red` chứ KHÔNG phải `dark:text-destructive`:\n * `--destructive` cố ý ghim #D64545 ở cả hai theme (để nút đặc + chữ trắng vẫn đủ tương phản),\n * dùng làm CHỮ trên nền tối chỉ được 3,58:1 ✗. `--red` là bậc đã nâng sáng cho dark (#F87171)\n * — đúng vai trò mà styles.css khai nó ra.\n *\n * Lưu ý: Tailwind sinh kèm fallback `color: var(--token)` cho trình duyệt không hỗ trợ\n * color-mix (trước 2023). Ở đó badge rơi về màu gốc — cùng mức hỏng như bản cũ, không tệ hơn;\n * và mọi tiện ích tint kiểu `bg-success/15` của Tailwind v4 cũng dựa trên color-mix nên đây là ràng buộc chung.\n */\nconst badgeVariants = cva(\n \"inline-flex items-center font-medium rounded-md whitespace-nowrap gap-1 [&>svg]:size-3 [&>svg]:pointer-events-none\",\n {\n variants: {\n variant: {\n default: \"bg-gold-100 text-gold-600 dark:bg-gold-500/20 dark:text-gold-200\",\n primary: \"bg-gold-100 text-gold-600 dark:bg-gold-500/20 dark:text-gold-200\",\n secondary: \"bg-secondary text-secondary-foreground\",\n outline: \"bg-transparent border border-border text-foreground\",\n success: \"bg-success/15 text-[color:color-mix(in_srgb,var(--success),var(--ink)_40%)] dark:text-success\",\n warning: \"bg-warning/20 text-[color:color-mix(in_srgb,var(--warning),var(--ink)_55%)] dark:text-warning\",\n destructive: \"bg-destructive/15 text-[color:color-mix(in_srgb,var(--destructive),var(--ink)_30%)] dark:text-red\"\n },\n size: {\n sm: \"px-1.5 py-0.5 text-[10px]\",\n md: \"px-2 py-0.5 text-xs\"\n }\n },\n defaultVariants: {\n variant: \"default\",\n size: \"md\"\n }\n }\n);\n\nexport interface BadgeProps extends React.ComponentProps<\"span\">, VariantProps<typeof badgeVariants> {\n /** Render ra chính phần tử con (Radix Slot) thay vì thẻ <span>. */\n asChild?: boolean;\n}\n\nfunction Badge({ className, variant, size, asChild = false, ...props }: BadgeProps) {\n const Comp = asChild ? Slot : \"span\";\n\n return <Comp data-slot=\"badge\" className={cn(badgeVariants({ variant, size }), className)} {...props} />;\n}\n\nexport { Badge, badgeVariants };\n"],"mappings":"AA6ES;AA7ET,SAAS,YAAY;AACrB,SAAS,WAA8B;AAEvC,SAAS,UAAU;AAyCnB,MAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS;AAAA,QACT,SAAS;AAAA,QACT,WAAW;AAAA,QACX,SAAS;AAAA,QACT,SAAS;AAAA,QACT,SAAS;AAAA,QACT,aAAa;AAAA,MACf;AAAA,MACA,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,MACN;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAOA,SAAS,MAAM,EAAE,WAAW,SAAS,MAAM,UAAU,OAAO,GAAG,MAAM,GAAe;AAClF,QAAM,OAAO,UAAU,OAAO;AAE9B,SAAO,oBAAC,QAAK,aAAU,SAAQ,WAAW,GAAG,cAAc,EAAE,SAAS,KAAK,CAAC,GAAG,SAAS,GAAI,GAAG,OAAO;AACxG;","names":[]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Breadcrumb — primitive tĩnh (không "use client", dùng được trong RSC).
|
|
5
|
+
* Chuỗi hiển thị mặc định là tiếng Việt và override được qua props tương ứng.
|
|
6
|
+
*
|
|
7
|
+
* Điều hướng: bọc `next/link` bằng `<BreadcrumbLink asChild><Link …/></BreadcrumbLink>`
|
|
8
|
+
* để primitive không phụ thuộc `next/*`.
|
|
9
|
+
*/
|
|
10
|
+
type BreadcrumbProps = React.ComponentProps<"nav">;
|
|
11
|
+
type BreadcrumbListProps = React.ComponentProps<"ol">;
|
|
12
|
+
type BreadcrumbItemProps = React.ComponentProps<"li">;
|
|
13
|
+
type BreadcrumbLinkProps = React.ComponentProps<"a"> & {
|
|
14
|
+
asChild?: boolean;
|
|
15
|
+
};
|
|
16
|
+
type BreadcrumbPageProps = React.ComponentProps<"span">;
|
|
17
|
+
type BreadcrumbSeparatorProps = React.ComponentProps<"li">;
|
|
18
|
+
type BreadcrumbEllipsisProps = React.ComponentProps<"span"> & {
|
|
19
|
+
/** Nhãn chỉ dành cho trình đọc màn hình. */
|
|
20
|
+
srLabel?: string;
|
|
21
|
+
};
|
|
22
|
+
declare function Breadcrumb({ ...props }: BreadcrumbProps): React.JSX.Element;
|
|
23
|
+
declare function BreadcrumbList({ className, ...props }: BreadcrumbListProps): React.JSX.Element;
|
|
24
|
+
declare function BreadcrumbItem({ className, ...props }: BreadcrumbItemProps): React.JSX.Element;
|
|
25
|
+
declare function BreadcrumbLink({ asChild, className, ...props }: BreadcrumbLinkProps): React.JSX.Element;
|
|
26
|
+
declare function BreadcrumbPage({ className, ...props }: BreadcrumbPageProps): React.JSX.Element;
|
|
27
|
+
declare function BreadcrumbSeparator({ children, className, ...props }: BreadcrumbSeparatorProps): React.JSX.Element;
|
|
28
|
+
declare function BreadcrumbEllipsis({ className, srLabel, ...props }: BreadcrumbEllipsisProps): React.JSX.Element;
|
|
29
|
+
|
|
30
|
+
export { Breadcrumb, BreadcrumbEllipsis, type BreadcrumbEllipsisProps, BreadcrumbItem, type BreadcrumbItemProps, BreadcrumbLink, type BreadcrumbLinkProps, BreadcrumbList, type BreadcrumbListProps, BreadcrumbPage, type BreadcrumbPageProps, type BreadcrumbProps, BreadcrumbSeparator, type BreadcrumbSeparatorProps };
|