@omnifyjp/ui 0.1.1
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 +230 -0
- package/dist/chunk-23SALQ3G.js +219 -0
- package/dist/chunk-23SALQ3G.js.map +1 -0
- package/dist/chunk-3TGN2DFB.js +41 -0
- package/dist/chunk-3TGN2DFB.js.map +1 -0
- package/dist/chunk-3TV2IR7L.js +65 -0
- package/dist/chunk-3TV2IR7L.js.map +1 -0
- package/dist/chunk-4CT5SCAH.js +54 -0
- package/dist/chunk-4CT5SCAH.js.map +1 -0
- package/dist/chunk-4D6FDXCG.js +41 -0
- package/dist/chunk-4D6FDXCG.js.map +1 -0
- package/dist/chunk-4HCORCR2.js +114 -0
- package/dist/chunk-4HCORCR2.js.map +1 -0
- package/dist/chunk-4N357E44.js +119 -0
- package/dist/chunk-4N357E44.js.map +1 -0
- package/dist/chunk-4Q2FLTAW.js +23 -0
- package/dist/chunk-4Q2FLTAW.js.map +1 -0
- package/dist/chunk-5M67ZEPM.js +33 -0
- package/dist/chunk-5M67ZEPM.js.map +1 -0
- package/dist/chunk-5WCL47ZW.js +30 -0
- package/dist/chunk-5WCL47ZW.js.map +1 -0
- package/dist/chunk-5Y3SQ3EA.js +52 -0
- package/dist/chunk-5Y3SQ3EA.js.map +1 -0
- package/dist/chunk-6GCAG5FH.js +46 -0
- package/dist/chunk-6GCAG5FH.js.map +1 -0
- package/dist/chunk-6MVBERQJ.js +44 -0
- package/dist/chunk-6MVBERQJ.js.map +1 -0
- package/dist/chunk-725ICC47.js +44 -0
- package/dist/chunk-725ICC47.js.map +1 -0
- package/dist/chunk-7ALADSN3.js +56 -0
- package/dist/chunk-7ALADSN3.js.map +1 -0
- package/dist/chunk-7NMWBCF4.js +171 -0
- package/dist/chunk-7NMWBCF4.js.map +1 -0
- package/dist/chunk-7ZFYPC74.js +155 -0
- package/dist/chunk-7ZFYPC74.js.map +1 -0
- package/dist/chunk-ANTYNEUU.js +35 -0
- package/dist/chunk-ANTYNEUU.js.map +1 -0
- package/dist/chunk-AZARDPXB.js +43 -0
- package/dist/chunk-AZARDPXB.js.map +1 -0
- package/dist/chunk-BJO5JCFB.js +111 -0
- package/dist/chunk-BJO5JCFB.js.map +1 -0
- package/dist/chunk-BOYSXIM3.js +160 -0
- package/dist/chunk-BOYSXIM3.js.map +1 -0
- package/dist/chunk-CDARHMTL.js +25 -0
- package/dist/chunk-CDARHMTL.js.map +1 -0
- package/dist/chunk-CESZTYQQ.js +93 -0
- package/dist/chunk-CESZTYQQ.js.map +1 -0
- package/dist/chunk-D3GCOO74.js +90 -0
- package/dist/chunk-D3GCOO74.js.map +1 -0
- package/dist/chunk-DGPY4WP3.js +11 -0
- package/dist/chunk-DGPY4WP3.js.map +1 -0
- package/dist/chunk-DIS42JLG.js +13 -0
- package/dist/chunk-DIS42JLG.js.map +1 -0
- package/dist/chunk-DQGDQEXD.js +617 -0
- package/dist/chunk-DQGDQEXD.js.map +1 -0
- package/dist/chunk-DZENMCRL.js +63 -0
- package/dist/chunk-DZENMCRL.js.map +1 -0
- package/dist/chunk-EIF6WZAZ.js +38 -0
- package/dist/chunk-EIF6WZAZ.js.map +1 -0
- package/dist/chunk-F6VQCMYH.js +81 -0
- package/dist/chunk-F6VQCMYH.js.map +1 -0
- package/dist/chunk-FBNG2KGO.js +66 -0
- package/dist/chunk-FBNG2KGO.js.map +1 -0
- package/dist/chunk-FO7J3PYY.js +131 -0
- package/dist/chunk-FO7J3PYY.js.map +1 -0
- package/dist/chunk-FSFXDD6P.js +196 -0
- package/dist/chunk-FSFXDD6P.js.map +1 -0
- package/dist/chunk-IDRQ6BNQ.js +63 -0
- package/dist/chunk-IDRQ6BNQ.js.map +1 -0
- package/dist/chunk-IJIGJGL5.js +48 -0
- package/dist/chunk-IJIGJGL5.js.map +1 -0
- package/dist/chunk-JPTN62BV.js +128 -0
- package/dist/chunk-JPTN62BV.js.map +1 -0
- package/dist/chunk-KABLXGWK.js +66 -0
- package/dist/chunk-KABLXGWK.js.map +1 -0
- package/dist/chunk-KOGOYUEE.js +121 -0
- package/dist/chunk-KOGOYUEE.js.map +1 -0
- package/dist/chunk-KULHYNE2.js +138 -0
- package/dist/chunk-KULHYNE2.js.map +1 -0
- package/dist/chunk-KXT75MXF.js +164 -0
- package/dist/chunk-KXT75MXF.js.map +1 -0
- package/dist/chunk-KXZ7IND6.js +24 -0
- package/dist/chunk-KXZ7IND6.js.map +1 -0
- package/dist/chunk-L46XUK4O.js +33 -0
- package/dist/chunk-L46XUK4O.js.map +1 -0
- package/dist/chunk-LI7CKURD.js +65 -0
- package/dist/chunk-LI7CKURD.js.map +1 -0
- package/dist/chunk-LW5PTU7D.js +211 -0
- package/dist/chunk-LW5PTU7D.js.map +1 -0
- package/dist/chunk-MNAT3ZF6.js +106 -0
- package/dist/chunk-MNAT3ZF6.js.map +1 -0
- package/dist/chunk-NFAXCC73.js +239 -0
- package/dist/chunk-NFAXCC73.js.map +1 -0
- package/dist/chunk-OHBCYKNT.js +63 -0
- package/dist/chunk-OHBCYKNT.js.map +1 -0
- package/dist/chunk-ONAUEREV.js +28 -0
- package/dist/chunk-ONAUEREV.js.map +1 -0
- package/dist/chunk-OXQNDQJW.js +86 -0
- package/dist/chunk-OXQNDQJW.js.map +1 -0
- package/dist/chunk-PCQSHXOQ.js +104 -0
- package/dist/chunk-PCQSHXOQ.js.map +1 -0
- package/dist/chunk-PH6P53QX.js +48 -0
- package/dist/chunk-PH6P53QX.js.map +1 -0
- package/dist/chunk-PPZSGU2L.js +33 -0
- package/dist/chunk-PPZSGU2L.js.map +1 -0
- package/dist/chunk-QCGYYBDZ.js +25 -0
- package/dist/chunk-QCGYYBDZ.js.map +1 -0
- package/dist/chunk-QMAMDYRD.js +65 -0
- package/dist/chunk-QMAMDYRD.js.map +1 -0
- package/dist/chunk-RVJDDGQW.js +112 -0
- package/dist/chunk-RVJDDGQW.js.map +1 -0
- package/dist/chunk-SABAKV4J.js +238 -0
- package/dist/chunk-SABAKV4J.js.map +1 -0
- package/dist/chunk-TEYOLOZY.js +18 -0
- package/dist/chunk-TEYOLOZY.js.map +1 -0
- package/dist/chunk-TMFQJ7E3.js +61 -0
- package/dist/chunk-TMFQJ7E3.js.map +1 -0
- package/dist/chunk-UCEUTKTQ.js +116 -0
- package/dist/chunk-UCEUTKTQ.js.map +1 -0
- package/dist/chunk-UV6UVSCF.js +187 -0
- package/dist/chunk-UV6UVSCF.js.map +1 -0
- package/dist/chunk-VGQC333M.js +17 -0
- package/dist/chunk-VGQC333M.js.map +1 -0
- package/dist/chunk-WAPGZIAL.js +99 -0
- package/dist/chunk-WAPGZIAL.js.map +1 -0
- package/dist/chunk-WRCHR4AK.js +23 -0
- package/dist/chunk-WRCHR4AK.js.map +1 -0
- package/dist/chunk-XKVHX75G.js +51 -0
- package/dist/chunk-XKVHX75G.js.map +1 -0
- package/dist/chunk-YF6WRCTG.js +41 -0
- package/dist/chunk-YF6WRCTG.js.map +1 -0
- package/dist/chunk-YGBYH4EO.js +28 -0
- package/dist/chunk-YGBYH4EO.js.map +1 -0
- package/dist/chunk-YKJZV2JK.js +109 -0
- package/dist/chunk-YKJZV2JK.js.map +1 -0
- package/dist/chunk-YUYC6Y6E.js +143 -0
- package/dist/chunk-YUYC6Y6E.js.map +1 -0
- package/dist/chunk-Z47W426M.js +53 -0
- package/dist/chunk-Z47W426M.js.map +1 -0
- package/dist/components/accordion.d.ts +10 -0
- package/dist/components/accordion.js +4 -0
- package/dist/components/accordion.js.map +1 -0
- package/dist/components/alert-dialog.d.ts +17 -0
- package/dist/components/alert-dialog.js +5 -0
- package/dist/components/alert-dialog.js.map +1 -0
- package/dist/components/alert.d.ts +13 -0
- package/dist/components/alert.js +4 -0
- package/dist/components/alert.js.map +1 -0
- package/dist/components/aspect-ratio.d.ts +6 -0
- package/dist/components/aspect-ratio.js +3 -0
- package/dist/components/aspect-ratio.js.map +1 -0
- package/dist/components/avatar.d.ts +9 -0
- package/dist/components/avatar.js +4 -0
- package/dist/components/avatar.js.map +1 -0
- package/dist/components/badge.d.ts +13 -0
- package/dist/components/badge.js +4 -0
- package/dist/components/badge.js.map +1 -0
- package/dist/components/breadcrumb.d.ts +14 -0
- package/dist/components/breadcrumb.js +4 -0
- package/dist/components/breadcrumb.js.map +1 -0
- package/dist/components/button.d.ts +16 -0
- package/dist/components/button.js +4 -0
- package/dist/components/button.js.map +1 -0
- package/dist/components/calendar-category-badge.d.ts +10 -0
- package/dist/components/calendar-category-badge.js +5 -0
- package/dist/components/calendar-category-badge.js.map +1 -0
- package/dist/components/calendar-event-chip.d.ts +18 -0
- package/dist/components/calendar-event-chip.js +4 -0
- package/dist/components/calendar-event-chip.js.map +1 -0
- package/dist/components/calendar-event-sheet.d.ts +31 -0
- package/dist/components/calendar-event-sheet.js +9 -0
- package/dist/components/calendar-event-sheet.js.map +1 -0
- package/dist/components/calendar-mini.d.ts +29 -0
- package/dist/components/calendar-mini.js +6 -0
- package/dist/components/calendar-mini.js.map +1 -0
- package/dist/components/calendar-toolbar.d.ts +25 -0
- package/dist/components/calendar-toolbar.js +7 -0
- package/dist/components/calendar-toolbar.js.map +1 -0
- package/dist/components/calendar.d.ts +7 -0
- package/dist/components/calendar.js +5 -0
- package/dist/components/calendar.js.map +1 -0
- package/dist/components/card.d.ts +12 -0
- package/dist/components/card.js +4 -0
- package/dist/components/card.js.map +1 -0
- package/dist/components/carousel.d.ts +24 -0
- package/dist/components/carousel.js +5 -0
- package/dist/components/carousel.js.map +1 -0
- package/dist/components/chart.d.ts +43 -0
- package/dist/components/chart.js +4 -0
- package/dist/components/chart.js.map +1 -0
- package/dist/components/checkbox.d.ts +6 -0
- package/dist/components/checkbox.js +4 -0
- package/dist/components/checkbox.js.map +1 -0
- package/dist/components/collapsible.d.ts +8 -0
- package/dist/components/collapsible.js +3 -0
- package/dist/components/collapsible.js.map +1 -0
- package/dist/components/color-picker.d.ts +13 -0
- package/dist/components/color-picker.js +7 -0
- package/dist/components/color-picker.js.map +1 -0
- package/dist/components/combobox.d.ts +33 -0
- package/dist/components/combobox.js +8 -0
- package/dist/components/combobox.js.map +1 -0
- package/dist/components/command.d.ts +20 -0
- package/dist/components/command.js +5 -0
- package/dist/components/command.js.map +1 -0
- package/dist/components/context-menu.d.ts +28 -0
- package/dist/components/context-menu.js +4 -0
- package/dist/components/context-menu.js.map +1 -0
- package/dist/components/date-picker.d.ts +31 -0
- package/dist/components/date-picker.js +7 -0
- package/dist/components/date-picker.js.map +1 -0
- package/dist/components/dialog.d.ts +16 -0
- package/dist/components/dialog.js +4 -0
- package/dist/components/dialog.js.map +1 -0
- package/dist/components/drawer.d.ts +17 -0
- package/dist/components/drawer.js +4 -0
- package/dist/components/drawer.js.map +1 -0
- package/dist/components/dropdown-menu.d.ts +28 -0
- package/dist/components/dropdown-menu.js +4 -0
- package/dist/components/dropdown-menu.js.map +1 -0
- package/dist/components/file-upload.d.ts +17 -0
- package/dist/components/file-upload.js +5 -0
- package/dist/components/file-upload.js.map +1 -0
- package/dist/components/form.d.ts +28 -0
- package/dist/components/form.js +5 -0
- package/dist/components/form.js.map +1 -0
- package/dist/components/hover-card.d.ts +9 -0
- package/dist/components/hover-card.js +4 -0
- package/dist/components/hover-card.js.map +1 -0
- package/dist/components/input-otp.d.ts +14 -0
- package/dist/components/input-otp.js +4 -0
- package/dist/components/input-otp.js.map +1 -0
- package/dist/components/input.d.ts +5 -0
- package/dist/components/input.js +4 -0
- package/dist/components/input.js.map +1 -0
- package/dist/components/label.d.ts +6 -0
- package/dist/components/label.js +4 -0
- package/dist/components/label.js.map +1 -0
- package/dist/components/menubar.d.ts +29 -0
- package/dist/components/menubar.js +4 -0
- package/dist/components/menubar.js.map +1 -0
- package/dist/components/navigation-menu.d.ts +18 -0
- package/dist/components/navigation-menu.js +4 -0
- package/dist/components/navigation-menu.js.map +1 -0
- package/dist/components/pagination.d.ts +18 -0
- package/dist/components/pagination.js +5 -0
- package/dist/components/pagination.js.map +1 -0
- package/dist/components/permission-grid.d.ts +30 -0
- package/dist/components/permission-grid.js +5 -0
- package/dist/components/permission-grid.js.map +1 -0
- package/dist/components/popover.d.ts +10 -0
- package/dist/components/popover.js +4 -0
- package/dist/components/popover.js.map +1 -0
- package/dist/components/progress.d.ts +7 -0
- package/dist/components/progress.js +4 -0
- package/dist/components/progress.js.map +1 -0
- package/dist/components/radio-group.d.ts +8 -0
- package/dist/components/radio-group.js +4 -0
- package/dist/components/radio-group.js.map +1 -0
- package/dist/components/rating.d.ts +14 -0
- package/dist/components/rating.js +4 -0
- package/dist/components/rating.js.map +1 -0
- package/dist/components/resizable.d.ts +11 -0
- package/dist/components/resizable.js +4 -0
- package/dist/components/resizable.js.map +1 -0
- package/dist/components/scope-tree.d.ts +35 -0
- package/dist/components/scope-tree.js +5 -0
- package/dist/components/scope-tree.js.map +1 -0
- package/dist/components/scope-type-badge.d.ts +20 -0
- package/dist/components/scope-type-badge.js +5 -0
- package/dist/components/scope-type-badge.js.map +1 -0
- package/dist/components/scroll-area.d.ts +8 -0
- package/dist/components/scroll-area.js +4 -0
- package/dist/components/scroll-area.js.map +1 -0
- package/dist/components/select.d.ts +18 -0
- package/dist/components/select.js +4 -0
- package/dist/components/select.js.map +1 -0
- package/dist/components/separator.d.ts +7 -0
- package/dist/components/separator.js +4 -0
- package/dist/components/separator.js.map +1 -0
- package/dist/components/sheet.d.ts +16 -0
- package/dist/components/sheet.js +4 -0
- package/dist/components/sheet.js.map +1 -0
- package/dist/components/sidebar.d.ts +75 -0
- package/dist/components/sidebar.js +11 -0
- package/dist/components/sidebar.js.map +1 -0
- package/dist/components/skeleton.d.ts +5 -0
- package/dist/components/skeleton.js +4 -0
- package/dist/components/skeleton.js.map +1 -0
- package/dist/components/slider.d.ts +7 -0
- package/dist/components/slider.js +4 -0
- package/dist/components/slider.js.map +1 -0
- package/dist/components/slug-input.d.ts +22 -0
- package/dist/components/slug-input.js +6 -0
- package/dist/components/slug-input.js.map +1 -0
- package/dist/components/sonner.d.ts +6 -0
- package/dist/components/sonner.js +3 -0
- package/dist/components/sonner.js.map +1 -0
- package/dist/components/stage-type-badge.d.ts +24 -0
- package/dist/components/stage-type-badge.js +5 -0
- package/dist/components/stage-type-badge.js.map +1 -0
- package/dist/components/switch.d.ts +7 -0
- package/dist/components/switch.js +4 -0
- package/dist/components/switch.js.map +1 -0
- package/dist/components/table.d.ts +13 -0
- package/dist/components/table.js +4 -0
- package/dist/components/table.js.map +1 -0
- package/dist/components/tabs.d.ts +10 -0
- package/dist/components/tabs.js +4 -0
- package/dist/components/tabs.js.map +1 -0
- package/dist/components/tag-input.d.ts +15 -0
- package/dist/components/tag-input.js +5 -0
- package/dist/components/tag-input.js.map +1 -0
- package/dist/components/textarea.d.ts +5 -0
- package/dist/components/textarea.js +4 -0
- package/dist/components/textarea.js.map +1 -0
- package/dist/components/time-picker.d.ts +20 -0
- package/dist/components/time-picker.js +8 -0
- package/dist/components/time-picker.js.map +1 -0
- package/dist/components/toggle-group.d.ts +12 -0
- package/dist/components/toggle-group.js +5 -0
- package/dist/components/toggle-group.js.map +1 -0
- package/dist/components/toggle.d.ts +13 -0
- package/dist/components/toggle.js +4 -0
- package/dist/components/toggle.js.map +1 -0
- package/dist/components/tooltip.d.ts +10 -0
- package/dist/components/tooltip.js +4 -0
- package/dist/components/tooltip.js.map +1 -0
- package/dist/components/workflow-category-badge.d.ts +26 -0
- package/dist/components/workflow-category-badge.js +5 -0
- package/dist/components/workflow-category-badge.js.map +1 -0
- package/dist/components/workflow-diagram.d.ts +43 -0
- package/dist/components/workflow-diagram.js +5 -0
- package/dist/components/workflow-diagram.js.map +1 -0
- package/dist/components/workflow-status-badge.d.ts +24 -0
- package/dist/components/workflow-status-badge.js +5 -0
- package/dist/components/workflow-status-badge.js.map +1 -0
- package/dist/components/workflow-stepper.d.ts +34 -0
- package/dist/components/workflow-stepper.js +4 -0
- package/dist/components/workflow-stepper.js.map +1 -0
- package/dist/hooks/use-mobile.d.ts +3 -0
- package/dist/hooks/use-mobile.js +3 -0
- package/dist/hooks/use-mobile.js.map +1 -0
- package/dist/index.d.ts +111 -0
- package/dist/index.js +71 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/utils.d.ts +5 -0
- package/dist/lib/utils.js +3 -0
- package/dist/lib/utils.js.map +1 -0
- package/package.json +101 -0
- package/src/styles/fonts.css +0 -0
- package/src/styles/index.css +3 -0
- package/src/styles/tailwind.css +4 -0
- package/src/styles/theme.css +447 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { Button } from './chunk-PH6P53QX.js';
|
|
2
|
+
import { cn } from './chunk-DGPY4WP3.js';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Upload, X, FileImage, FileVideo, FileText, File } from 'lucide-react';
|
|
5
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
function FileUpload({
|
|
8
|
+
value = [],
|
|
9
|
+
onChange,
|
|
10
|
+
accept,
|
|
11
|
+
multiple = false,
|
|
12
|
+
maxSize = 10 * 1024 * 1024,
|
|
13
|
+
// 10MB default
|
|
14
|
+
maxFiles,
|
|
15
|
+
disabled,
|
|
16
|
+
className,
|
|
17
|
+
showPreview = true
|
|
18
|
+
}) {
|
|
19
|
+
const inputRef = React.useRef(null);
|
|
20
|
+
const [dragActive, setDragActive] = React.useState(false);
|
|
21
|
+
const [error, setError] = React.useState("");
|
|
22
|
+
const handleDrag = (e) => {
|
|
23
|
+
e.preventDefault();
|
|
24
|
+
e.stopPropagation();
|
|
25
|
+
if (e.type === "dragenter" || e.type === "dragover") {
|
|
26
|
+
setDragActive(true);
|
|
27
|
+
} else if (e.type === "dragleave") {
|
|
28
|
+
setDragActive(false);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
const validateFiles = (files) => {
|
|
32
|
+
setError("");
|
|
33
|
+
if (maxFiles && value.length + files.length > maxFiles) {
|
|
34
|
+
return {
|
|
35
|
+
valid: [],
|
|
36
|
+
error: `Ch\u1EC9 \u0111\u01B0\u1EE3c ch\u1ECDn t\u1ED1i \u0111a ${maxFiles} file`
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const oversizedFiles = files.filter((file) => file.size > maxSize);
|
|
40
|
+
if (oversizedFiles.length > 0) {
|
|
41
|
+
return {
|
|
42
|
+
valid: [],
|
|
43
|
+
error: `File v\u01B0\u1EE3t qu\xE1 dung l\u01B0\u1EE3ng cho ph\xE9p (${Math.round(maxSize / 1024 / 1024)}MB)`
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return { valid: files };
|
|
47
|
+
};
|
|
48
|
+
const handleDrop = (e) => {
|
|
49
|
+
e.preventDefault();
|
|
50
|
+
e.stopPropagation();
|
|
51
|
+
setDragActive(false);
|
|
52
|
+
if (disabled) return;
|
|
53
|
+
const droppedFiles = Array.from(e.dataTransfer.files);
|
|
54
|
+
const { valid, error: error2 } = validateFiles(droppedFiles);
|
|
55
|
+
if (error2) {
|
|
56
|
+
setError(error2);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
onChange?.([...value, ...valid]);
|
|
60
|
+
};
|
|
61
|
+
const handleChange = (e) => {
|
|
62
|
+
if (disabled) return;
|
|
63
|
+
const selectedFiles = Array.from(e.target.files || []);
|
|
64
|
+
const { valid, error: error2 } = validateFiles(selectedFiles);
|
|
65
|
+
if (error2) {
|
|
66
|
+
setError(error2);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
onChange?.([...value, ...valid]);
|
|
70
|
+
if (inputRef.current) {
|
|
71
|
+
inputRef.current.value = "";
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const handleRemove = (index) => {
|
|
75
|
+
onChange?.(value.filter((_, i) => i !== index));
|
|
76
|
+
};
|
|
77
|
+
const getFileIcon = (file) => {
|
|
78
|
+
if (file.type.startsWith("image/")) return FileImage;
|
|
79
|
+
if (file.type.startsWith("video/")) return FileVideo;
|
|
80
|
+
if (file.type.startsWith("text/")) return FileText;
|
|
81
|
+
return File;
|
|
82
|
+
};
|
|
83
|
+
const formatFileSize = (bytes) => {
|
|
84
|
+
if (bytes === 0) return "0 Bytes";
|
|
85
|
+
const k = 1024;
|
|
86
|
+
const sizes = ["Bytes", "KB", "MB", "GB"];
|
|
87
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
88
|
+
return Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
|
|
89
|
+
};
|
|
90
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("w-full", className), children: [
|
|
91
|
+
/* @__PURE__ */ jsx(
|
|
92
|
+
"input",
|
|
93
|
+
{
|
|
94
|
+
ref: inputRef,
|
|
95
|
+
type: "file",
|
|
96
|
+
accept,
|
|
97
|
+
multiple,
|
|
98
|
+
onChange: handleChange,
|
|
99
|
+
disabled,
|
|
100
|
+
className: "hidden"
|
|
101
|
+
}
|
|
102
|
+
),
|
|
103
|
+
/* @__PURE__ */ jsxs(
|
|
104
|
+
"div",
|
|
105
|
+
{
|
|
106
|
+
onDragEnter: handleDrag,
|
|
107
|
+
onDragLeave: handleDrag,
|
|
108
|
+
onDragOver: handleDrag,
|
|
109
|
+
onDrop: handleDrop,
|
|
110
|
+
onClick: () => !disabled && inputRef.current?.click(),
|
|
111
|
+
className: cn(
|
|
112
|
+
"relative border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors",
|
|
113
|
+
dragActive ? "border-blue-500 bg-blue-50" : "border-gray-300 hover:border-gray-400",
|
|
114
|
+
disabled && "opacity-50 cursor-not-allowed",
|
|
115
|
+
error && "border-red-500"
|
|
116
|
+
),
|
|
117
|
+
children: [
|
|
118
|
+
/* @__PURE__ */ jsx(Upload, { className: "mx-auto h-12 w-12 text-gray-400 mb-4" }),
|
|
119
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm text-gray-600 mb-2", children: [
|
|
120
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold text-blue-600", children: "Nh\u1EA5p \u0111\u1EC3 ch\u1ECDn file" }),
|
|
121
|
+
" ",
|
|
122
|
+
"ho\u1EB7c k\xE9o th\u1EA3 file v\xE0o \u0111\xE2y"
|
|
123
|
+
] }),
|
|
124
|
+
/* @__PURE__ */ jsxs("div", { className: "text-xs text-gray-500", children: [
|
|
125
|
+
accept && /* @__PURE__ */ jsxs("div", { children: [
|
|
126
|
+
"\u0110\u1ECBnh d\u1EA1ng: ",
|
|
127
|
+
accept
|
|
128
|
+
] }),
|
|
129
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
130
|
+
"Dung l\u01B0\u1EE3ng t\u1ED1i \u0111a: ",
|
|
131
|
+
Math.round(maxSize / 1024 / 1024),
|
|
132
|
+
"MB"
|
|
133
|
+
] }),
|
|
134
|
+
maxFiles && /* @__PURE__ */ jsxs("div", { children: [
|
|
135
|
+
"S\u1ED1 l\u01B0\u1EE3ng t\u1ED1i \u0111a: ",
|
|
136
|
+
maxFiles,
|
|
137
|
+
" file"
|
|
138
|
+
] })
|
|
139
|
+
] })
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
),
|
|
143
|
+
error && /* @__PURE__ */ jsx("div", { className: "mt-2 text-sm text-red-600", children: error }),
|
|
144
|
+
showPreview && value.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-4 space-y-2", children: value.map((file, index) => {
|
|
145
|
+
const FileIcon = getFileIcon(file);
|
|
146
|
+
const isImage = file.type.startsWith("image/");
|
|
147
|
+
const previewUrl = isImage ? URL.createObjectURL(file) : null;
|
|
148
|
+
return /* @__PURE__ */ jsxs(
|
|
149
|
+
"div",
|
|
150
|
+
{
|
|
151
|
+
className: "flex items-center gap-3 p-3 border rounded-lg bg-gray-50",
|
|
152
|
+
children: [
|
|
153
|
+
previewUrl ? /* @__PURE__ */ jsx(
|
|
154
|
+
"img",
|
|
155
|
+
{
|
|
156
|
+
src: previewUrl,
|
|
157
|
+
alt: file.name,
|
|
158
|
+
className: "w-10 h-10 rounded object-cover"
|
|
159
|
+
}
|
|
160
|
+
) : /* @__PURE__ */ jsx("div", { className: "w-10 h-10 rounded bg-gray-200 flex items-center justify-center", children: /* @__PURE__ */ jsx(FileIcon, { className: "w-5 h-5 text-gray-600" }) }),
|
|
161
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
162
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm font-medium truncate", children: file.name }),
|
|
163
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: formatFileSize(file.size) })
|
|
164
|
+
] }),
|
|
165
|
+
/* @__PURE__ */ jsx(
|
|
166
|
+
Button,
|
|
167
|
+
{
|
|
168
|
+
type: "button",
|
|
169
|
+
variant: "ghost",
|
|
170
|
+
size: "sm",
|
|
171
|
+
onClick: () => handleRemove(index),
|
|
172
|
+
disabled,
|
|
173
|
+
className: "flex-shrink-0",
|
|
174
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
|
|
175
|
+
}
|
|
176
|
+
)
|
|
177
|
+
]
|
|
178
|
+
},
|
|
179
|
+
`${file.name}-${index}`
|
|
180
|
+
);
|
|
181
|
+
}) })
|
|
182
|
+
] });
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export { FileUpload };
|
|
186
|
+
//# sourceMappingURL=chunk-UV6UVSCF.js.map
|
|
187
|
+
//# sourceMappingURL=chunk-UV6UVSCF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/file-upload.tsx"],"names":["error"],"mappings":"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","file":"chunk-UV6UVSCF.js","sourcesContent":["import * as React from \"react\";\nimport { Upload, X, File, FileImage, FileText, FileVideo } from \"lucide-react\";\nimport { cn } from \"../lib/utils\";\nimport { Button } from \"./button\";\n\ninterface FileUploadProps {\n value?: File[];\n onChange?: (files: File[]) => void;\n accept?: string;\n multiple?: boolean;\n maxSize?: number; // in bytes\n maxFiles?: number;\n disabled?: boolean;\n className?: string;\n showPreview?: boolean;\n}\n\nexport function FileUpload({\n value = [],\n onChange,\n accept,\n multiple = false,\n maxSize = 10 * 1024 * 1024, // 10MB default\n maxFiles,\n disabled,\n className,\n showPreview = true,\n}: FileUploadProps) {\n const inputRef = React.useRef<HTMLInputElement>(null);\n const [dragActive, setDragActive] = React.useState(false);\n const [error, setError] = React.useState<string>(\"\");\n\n const handleDrag = (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (e.type === \"dragenter\" || e.type === \"dragover\") {\n setDragActive(true);\n } else if (e.type === \"dragleave\") {\n setDragActive(false);\n }\n };\n\n const validateFiles = (files: File[]): { valid: File[]; error?: string } => {\n setError(\"\");\n\n // Check max files\n if (maxFiles && value.length + files.length > maxFiles) {\n return {\n valid: [],\n error: `Chỉ được chọn tối đa ${maxFiles} file`,\n };\n }\n\n // Check file size\n const oversizedFiles = files.filter((file) => file.size > maxSize);\n if (oversizedFiles.length > 0) {\n return {\n valid: [],\n error: `File vượt quá dung lượng cho phép (${Math.round(maxSize / 1024 / 1024)}MB)`,\n };\n }\n\n return { valid: files };\n };\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setDragActive(false);\n\n if (disabled) return;\n\n const droppedFiles = Array.from(e.dataTransfer.files);\n const { valid, error } = validateFiles(droppedFiles);\n\n if (error) {\n setError(error);\n return;\n }\n\n onChange?.([...value, ...valid]);\n };\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled) return;\n\n const selectedFiles = Array.from(e.target.files || []);\n const { valid, error } = validateFiles(selectedFiles);\n\n if (error) {\n setError(error);\n return;\n }\n\n onChange?.([...value, ...valid]);\n\n // Reset input\n if (inputRef.current) {\n inputRef.current.value = \"\";\n }\n };\n\n const handleRemove = (index: number) => {\n onChange?.(value.filter((_, i) => i !== index));\n };\n\n const getFileIcon = (file: File) => {\n if (file.type.startsWith(\"image/\")) return FileImage;\n if (file.type.startsWith(\"video/\")) return FileVideo;\n if (file.type.startsWith(\"text/\")) return FileText;\n return File;\n };\n\n const formatFileSize = (bytes: number) => {\n if (bytes === 0) return \"0 Bytes\";\n const k = 1024;\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return Math.round(bytes / Math.pow(k, i) * 100) / 100 + \" \" + sizes[i];\n };\n\n return (\n <div className={cn(\"w-full\", className)}>\n <input\n ref={inputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={handleChange}\n disabled={disabled}\n className=\"hidden\"\n />\n\n {/* Upload Area */}\n <div\n onDragEnter={handleDrag}\n onDragLeave={handleDrag}\n onDragOver={handleDrag}\n onDrop={handleDrop}\n onClick={() => !disabled && inputRef.current?.click()}\n className={cn(\n \"relative border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors\",\n dragActive\n ? \"border-blue-500 bg-blue-50\"\n : \"border-gray-300 hover:border-gray-400\",\n disabled && \"opacity-50 cursor-not-allowed\",\n error && \"border-red-500\"\n )}\n >\n <Upload className=\"mx-auto h-12 w-12 text-gray-400 mb-4\" />\n <div className=\"text-sm text-gray-600 mb-2\">\n <span className=\"font-semibold text-blue-600\">Nhấp để chọn file</span>\n {\" \"}hoặc kéo thả file vào đây\n </div>\n <div className=\"text-xs text-gray-500\">\n {accept && <div>Định dạng: {accept}</div>}\n <div>Dung lượng tối đa: {Math.round(maxSize / 1024 / 1024)}MB</div>\n {maxFiles && <div>Số lượng tối đa: {maxFiles} file</div>}\n </div>\n </div>\n\n {/* Error Message */}\n {error && (\n <div className=\"mt-2 text-sm text-red-600\">{error}</div>\n )}\n\n {/* File List */}\n {showPreview && value.length > 0 && (\n <div className=\"mt-4 space-y-2\">\n {value.map((file, index) => {\n const FileIcon = getFileIcon(file);\n const isImage = file.type.startsWith(\"image/\");\n const previewUrl = isImage ? URL.createObjectURL(file) : null;\n\n return (\n <div\n key={`${file.name}-${index}`}\n className=\"flex items-center gap-3 p-3 border rounded-lg bg-gray-50\"\n >\n {previewUrl ? (\n <img\n src={previewUrl}\n alt={file.name}\n className=\"w-10 h-10 rounded object-cover\"\n />\n ) : (\n <div className=\"w-10 h-10 rounded bg-gray-200 flex items-center justify-center\">\n <FileIcon className=\"w-5 h-5 text-gray-600\" />\n </div>\n )}\n\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium truncate\">{file.name}</div>\n <div className=\"text-xs text-gray-500\">\n {formatFileSize(file.size)}\n </div>\n </div>\n\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => handleRemove(index)}\n disabled={disabled}\n className=\"flex-shrink-0\"\n >\n <X className=\"h-4 w-4\" />\n </Button>\n </div>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { cn } from './chunk-DGPY4WP3.js';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
function Skeleton({ className, ...props }) {
|
|
5
|
+
return /* @__PURE__ */ jsx(
|
|
6
|
+
"div",
|
|
7
|
+
{
|
|
8
|
+
"data-slot": "skeleton",
|
|
9
|
+
className: cn("bg-accent animate-pulse rounded-md", className),
|
|
10
|
+
...props
|
|
11
|
+
}
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { Skeleton };
|
|
16
|
+
//# sourceMappingURL=chunk-VGQC333M.js.map
|
|
17
|
+
//# sourceMappingURL=chunk-VGQC333M.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/skeleton.tsx"],"names":[],"mappings":";;;AAEA,SAAS,QAAA,CAAS,EAAE,SAAA,EAAW,GAAG,OAAM,EAAgC;AACtE,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,UAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,oCAAA,EAAsC,SAAS,CAAA;AAAA,MAC5D,GAAG;AAAA;AAAA,GACN;AAEJ","file":"chunk-VGQC333M.js","sourcesContent":["import { cn } from \"../lib/utils\";\n\nfunction Skeleton({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"skeleton\"\n className={cn(\"bg-accent animate-pulse rounded-md\", className)}\n {...props}\n />\n );\n}\n\nexport { Skeleton };\n"]}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { cn } from './chunk-DGPY4WP3.js';
|
|
2
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
3
|
+
import { ChevronRight, MoreHorizontal } from 'lucide-react';
|
|
4
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
function Breadcrumb({ ...props }) {
|
|
7
|
+
return /* @__PURE__ */ jsx("nav", { "aria-label": "breadcrumb", "data-slot": "breadcrumb", ...props });
|
|
8
|
+
}
|
|
9
|
+
function BreadcrumbList({ className, ...props }) {
|
|
10
|
+
return /* @__PURE__ */ jsx(
|
|
11
|
+
"ol",
|
|
12
|
+
{
|
|
13
|
+
"data-slot": "breadcrumb-list",
|
|
14
|
+
className: cn(
|
|
15
|
+
"text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5",
|
|
16
|
+
className
|
|
17
|
+
),
|
|
18
|
+
...props
|
|
19
|
+
}
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
function BreadcrumbItem({ className, ...props }) {
|
|
23
|
+
return /* @__PURE__ */ jsx(
|
|
24
|
+
"li",
|
|
25
|
+
{
|
|
26
|
+
"data-slot": "breadcrumb-item",
|
|
27
|
+
className: cn("inline-flex items-center gap-1.5", className),
|
|
28
|
+
...props
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
function BreadcrumbLink({
|
|
33
|
+
asChild,
|
|
34
|
+
className,
|
|
35
|
+
...props
|
|
36
|
+
}) {
|
|
37
|
+
const Comp = asChild ? Slot : "a";
|
|
38
|
+
return /* @__PURE__ */ jsx(
|
|
39
|
+
Comp,
|
|
40
|
+
{
|
|
41
|
+
"data-slot": "breadcrumb-link",
|
|
42
|
+
className: cn("hover:text-foreground transition-colors", className),
|
|
43
|
+
...props
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
function BreadcrumbPage({ className, ...props }) {
|
|
48
|
+
return /* @__PURE__ */ jsx(
|
|
49
|
+
"span",
|
|
50
|
+
{
|
|
51
|
+
"data-slot": "breadcrumb-page",
|
|
52
|
+
role: "link",
|
|
53
|
+
"aria-disabled": "true",
|
|
54
|
+
"aria-current": "page",
|
|
55
|
+
className: cn("text-foreground font-normal", className),
|
|
56
|
+
...props
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
function BreadcrumbSeparator({
|
|
61
|
+
children,
|
|
62
|
+
className,
|
|
63
|
+
...props
|
|
64
|
+
}) {
|
|
65
|
+
return /* @__PURE__ */ jsx(
|
|
66
|
+
"li",
|
|
67
|
+
{
|
|
68
|
+
"data-slot": "breadcrumb-separator",
|
|
69
|
+
role: "presentation",
|
|
70
|
+
"aria-hidden": "true",
|
|
71
|
+
className: cn("[&>svg]:size-3.5", className),
|
|
72
|
+
...props,
|
|
73
|
+
children: children ?? /* @__PURE__ */ jsx(ChevronRight, {})
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
function BreadcrumbEllipsis({
|
|
78
|
+
className,
|
|
79
|
+
...props
|
|
80
|
+
}) {
|
|
81
|
+
return /* @__PURE__ */ jsxs(
|
|
82
|
+
"span",
|
|
83
|
+
{
|
|
84
|
+
"data-slot": "breadcrumb-ellipsis",
|
|
85
|
+
role: "presentation",
|
|
86
|
+
"aria-hidden": "true",
|
|
87
|
+
className: cn("flex size-9 items-center justify-center", className),
|
|
88
|
+
...props,
|
|
89
|
+
children: [
|
|
90
|
+
/* @__PURE__ */ jsx(MoreHorizontal, { className: "size-4" }),
|
|
91
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "More" })
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export { Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator };
|
|
98
|
+
//# sourceMappingURL=chunk-WAPGZIAL.js.map
|
|
99
|
+
//# sourceMappingURL=chunk-WAPGZIAL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/breadcrumb.tsx"],"names":[],"mappings":";;;;;AAMA,SAAS,UAAA,CAAW,EAAE,GAAG,KAAA,EAAM,EAAgC;AAC7D,EAAA,2BAAQ,KAAA,EAAA,EAAI,YAAA,EAAW,cAAa,WAAA,EAAU,YAAA,EAAc,GAAG,KAAA,EAAO,CAAA;AACxE;AAEA,SAAS,cAAA,CAAe,EAAE,SAAA,EAAW,GAAG,OAAM,EAA+B;AAC3E,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,iBAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,0FAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,cAAA,CAAe,EAAE,SAAA,EAAW,GAAG,OAAM,EAA+B;AAC3E,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,iBAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,kCAAA,EAAoC,SAAS,CAAA;AAAA,MAC1D,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,cAAA,CAAe;AAAA,EACtB,OAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAEG;AACD,EAAA,MAAM,IAAA,GAAO,UAAU,IAAA,GAAO,GAAA;AAE9B,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,iBAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,yCAAA,EAA2C,SAAS,CAAA;AAAA,MACjE,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,cAAA,CAAe,EAAE,SAAA,EAAW,GAAG,OAAM,EAAiC;AAC7E,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,iBAAA;AAAA,MACV,IAAA,EAAK,MAAA;AAAA,MACL,eAAA,EAAc,MAAA;AAAA,MACd,cAAA,EAAa,MAAA;AAAA,MACb,SAAA,EAAW,EAAA,CAAG,6BAAA,EAA+B,SAAS,CAAA;AAAA,MACrD,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,mBAAA,CAAoB;AAAA,EAC3B,QAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA+B;AAC7B,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,sBAAA;AAAA,MACV,IAAA,EAAK,cAAA;AAAA,MACL,aAAA,EAAY,MAAA;AAAA,MACZ,SAAA,EAAW,EAAA,CAAG,kBAAA,EAAoB,SAAS,CAAA;AAAA,MAC1C,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA,QAAA,wBAAa,YAAA,EAAA,EAAa;AAAA;AAAA,GAC7B;AAEJ;AAEA,SAAS,kBAAA,CAAmB;AAAA,EAC1B,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAiC;AAC/B,EAAA,uBACE,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,qBAAA;AAAA,MACV,IAAA,EAAK,cAAA;AAAA,MACL,aAAA,EAAY,MAAA;AAAA,MACZ,SAAA,EAAW,EAAA,CAAG,yCAAA,EAA2C,SAAS,CAAA;AAAA,MACjE,GAAG,KAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,cAAA,EAAA,EAAe,WAAU,QAAA,EAAS,CAAA;AAAA,wBACnC,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EAAU,QAAA,EAAA,MAAA,EAAI;AAAA;AAAA;AAAA,GAChC;AAEJ","file":"chunk-WAPGZIAL.js","sourcesContent":["import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { ChevronRight, MoreHorizontal } from \"lucide-react\";\n\nimport { cn } from \"../lib/utils\";\n\nfunction Breadcrumb({ ...props }: React.ComponentProps<\"nav\">) {\n return <nav aria-label=\"breadcrumb\" data-slot=\"breadcrumb\" {...props} />;\n}\n\nfunction BreadcrumbList({ className, ...props }: React.ComponentProps<\"ol\">) {\n return (\n <ol\n data-slot=\"breadcrumb-list\"\n className={cn(\n \"text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbItem({ className, ...props }: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"breadcrumb-item\"\n className={cn(\"inline-flex items-center gap-1.5\", className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbLink({\n asChild,\n className,\n ...props\n}: React.ComponentProps<\"a\"> & {\n asChild?: boolean;\n}) {\n const Comp = asChild ? Slot : \"a\";\n\n return (\n <Comp\n data-slot=\"breadcrumb-link\"\n className={cn(\"hover:text-foreground transition-colors\", className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbPage({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"breadcrumb-page\"\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn(\"text-foreground font-normal\", className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"breadcrumb-separator\"\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\"[&>svg]:size-3.5\", className)}\n {...props}\n >\n {children ?? <ChevronRight />}\n </li>\n );\n}\n\nfunction BreadcrumbEllipsis({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"breadcrumb-ellipsis\"\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\"flex size-9 items-center justify-center\", className)}\n {...props}\n >\n <MoreHorizontal className=\"size-4\" />\n <span className=\"sr-only\">More</span>\n </span>\n );\n}\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n};\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
// src/hooks/use-mobile.ts
|
|
4
|
+
var MOBILE_BREAKPOINT = 768;
|
|
5
|
+
function useIsMobile() {
|
|
6
|
+
const [isMobile, setIsMobile] = React.useState(
|
|
7
|
+
void 0
|
|
8
|
+
);
|
|
9
|
+
React.useEffect(() => {
|
|
10
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
11
|
+
const onChange = () => {
|
|
12
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
13
|
+
};
|
|
14
|
+
mql.addEventListener("change", onChange);
|
|
15
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
16
|
+
return () => mql.removeEventListener("change", onChange);
|
|
17
|
+
}, []);
|
|
18
|
+
return !!isMobile;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { useIsMobile };
|
|
22
|
+
//# sourceMappingURL=chunk-WRCHR4AK.js.map
|
|
23
|
+
//# sourceMappingURL=chunk-WRCHR4AK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/use-mobile.ts"],"names":[],"mappings":";;;AAEA,IAAM,iBAAA,GAAoB,GAAA;AAEnB,SAAS,WAAA,GAAc;AAC5B,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAU,KAAA,CAAA,QAAA;AAAA,IACpC;AAAA,GACF;AAEA,EAAM,gBAAU,MAAM;AACpB,IAAA,MAAM,MAAM,MAAA,CAAO,UAAA,CAAW,CAAA,YAAA,EAAe,iBAAA,GAAoB,CAAC,CAAA,GAAA,CAAK,CAAA;AACvE,IAAA,MAAM,WAAW,MAAM;AACrB,MAAA,WAAA,CAAY,MAAA,CAAO,aAAa,iBAAiB,CAAA;AAAA,IACnD,CAAA;AACA,IAAA,GAAA,CAAI,gBAAA,CAAiB,UAAU,QAAQ,CAAA;AACvC,IAAA,WAAA,CAAY,MAAA,CAAO,aAAa,iBAAiB,CAAA;AACjD,IAAA,OAAO,MAAM,GAAA,CAAI,mBAAA,CAAoB,QAAA,EAAU,QAAQ,CAAA;AAAA,EACzD,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO,CAAC,CAAC,QAAA;AACX","file":"chunk-WRCHR4AK.js","sourcesContent":["import * as React from \"react\";\n\nconst MOBILE_BREAKPOINT = 768;\n\nexport function useIsMobile() {\n const [isMobile, setIsMobile] = React.useState<boolean | undefined>(\n undefined,\n );\n\n React.useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);\n const onChange = () => {\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n };\n mql.addEventListener(\"change\", onChange);\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\n return () => mql.removeEventListener(\"change\", onChange);\n }, []);\n\n return !!isMobile;\n}\n"]}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Badge } from './chunk-3TGN2DFB.js';
|
|
2
|
+
import { cn } from './chunk-DGPY4WP3.js';
|
|
3
|
+
import { MoreHorizontal, FileText, FileSignature, ShoppingCart, Receipt, Calendar } from 'lucide-react';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var categoryConfig = {
|
|
7
|
+
leave: {
|
|
8
|
+
icon: Calendar,
|
|
9
|
+
style: "bg-blue-50 dark:bg-blue-500/15 text-blue-600 dark:text-blue-400 border-blue-200 dark:border-blue-500/30"
|
|
10
|
+
},
|
|
11
|
+
expense: {
|
|
12
|
+
icon: Receipt,
|
|
13
|
+
style: "bg-green-50 dark:bg-green-500/15 text-green-600 dark:text-green-400 border-green-200 dark:border-green-500/30"
|
|
14
|
+
},
|
|
15
|
+
purchase: {
|
|
16
|
+
icon: ShoppingCart,
|
|
17
|
+
style: "bg-amber-50 dark:bg-amber-500/15 text-amber-600 dark:text-amber-400 border-amber-200 dark:border-amber-500/30"
|
|
18
|
+
},
|
|
19
|
+
contract: {
|
|
20
|
+
icon: FileSignature,
|
|
21
|
+
style: "bg-purple-50 dark:bg-purple-500/15 text-purple-600 dark:text-purple-400 border-purple-200 dark:border-purple-500/30"
|
|
22
|
+
},
|
|
23
|
+
document: {
|
|
24
|
+
icon: FileText,
|
|
25
|
+
style: "bg-cyan-50 dark:bg-cyan-500/15 text-cyan-600 dark:text-cyan-400 border-cyan-200 dark:border-cyan-500/30"
|
|
26
|
+
},
|
|
27
|
+
other: {
|
|
28
|
+
icon: MoreHorizontal,
|
|
29
|
+
style: "bg-muted text-muted-foreground"
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var defaultLabels = {
|
|
33
|
+
leave: "Leave",
|
|
34
|
+
expense: "Expense",
|
|
35
|
+
purchase: "Purchase",
|
|
36
|
+
contract: "Contract",
|
|
37
|
+
document: "Document",
|
|
38
|
+
other: "Other"
|
|
39
|
+
};
|
|
40
|
+
function WorkflowCategoryBadge({ category, label, className }) {
|
|
41
|
+
const config = categoryConfig[category];
|
|
42
|
+
const Icon = config.icon;
|
|
43
|
+
return /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: cn(config.style, className), children: [
|
|
44
|
+
/* @__PURE__ */ jsx(Icon, { className: "w-3 h-3 mr-1" }),
|
|
45
|
+
label ?? defaultLabels[category]
|
|
46
|
+
] });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export { WorkflowCategoryBadge };
|
|
50
|
+
//# sourceMappingURL=chunk-XKVHX75G.js.map
|
|
51
|
+
//# sourceMappingURL=chunk-XKVHX75G.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/workflow-category-badge.tsx"],"names":[],"mappings":";;;;;AA6BA,IAAM,cAAA,GAAqF;AAAA,EACzF,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,YAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,aAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,cAAA;AAAA,IACN,KAAA,EAAO;AAAA;AAEX,CAAA;AAEA,IAAM,aAAA,GAAkD;AAAA,EACtD,KAAA,EAAO,OAAA;AAAA,EACP,OAAA,EAAS,SAAA;AAAA,EACT,QAAA,EAAU,UAAA;AAAA,EACV,QAAA,EAAU,UAAA;AAAA,EACV,QAAA,EAAU,UAAA;AAAA,EACV,KAAA,EAAO;AACT,CAAA;AAaO,SAAS,qBAAA,CAAsB,EAAE,QAAA,EAAU,KAAA,EAAO,WAAU,EAA+B;AAChG,EAAA,MAAM,MAAA,GAAS,eAAe,QAAQ,CAAA;AACtC,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AAEpB,EAAA,uBACE,IAAA,CAAC,SAAM,OAAA,EAAQ,SAAA,EAAU,WAAW,EAAA,CAAG,MAAA,CAAO,KAAA,EAAO,SAAS,CAAA,EAC5D,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,WAAU,cAAA,EAAe,CAAA;AAAA,IAC9B,KAAA,IAAS,cAAc,QAAQ;AAAA,GAAA,EAClC,CAAA;AAEJ","file":"chunk-XKVHX75G.js","sourcesContent":["import {\n Calendar,\n Receipt,\n ShoppingCart,\n FileSignature,\n FileText,\n MoreHorizontal,\n} from 'lucide-react';\nimport { cn } from '../lib/utils';\nimport { Badge } from './badge';\n\n/** Supported workflow categories with built-in icon and color mappings. */\nexport type WorkflowCategory =\n | 'leave'\n | 'expense'\n | 'purchase'\n | 'contract'\n | 'document'\n | 'other';\n\nexport interface WorkflowCategoryBadgeProps {\n /** The category key. Determines the icon and color. */\n category: WorkflowCategory;\n /** The displayed label text. Defaults to a capitalized version of the category. */\n label?: string;\n /** Optional additional className. */\n className?: string;\n}\n\nconst categoryConfig: Record<WorkflowCategory, { icon: typeof Calendar; style: string }> = {\n leave: {\n icon: Calendar,\n style:\n 'bg-blue-50 dark:bg-blue-500/15 text-blue-600 dark:text-blue-400 border-blue-200 dark:border-blue-500/30',\n },\n expense: {\n icon: Receipt,\n style:\n 'bg-green-50 dark:bg-green-500/15 text-green-600 dark:text-green-400 border-green-200 dark:border-green-500/30',\n },\n purchase: {\n icon: ShoppingCart,\n style:\n 'bg-amber-50 dark:bg-amber-500/15 text-amber-600 dark:text-amber-400 border-amber-200 dark:border-amber-500/30',\n },\n contract: {\n icon: FileSignature,\n style:\n 'bg-purple-50 dark:bg-purple-500/15 text-purple-600 dark:text-purple-400 border-purple-200 dark:border-purple-500/30',\n },\n document: {\n icon: FileText,\n style:\n 'bg-cyan-50 dark:bg-cyan-500/15 text-cyan-600 dark:text-cyan-400 border-cyan-200 dark:border-cyan-500/30',\n },\n other: {\n icon: MoreHorizontal,\n style: 'bg-muted text-muted-foreground',\n },\n};\n\nconst defaultLabels: Record<WorkflowCategory, string> = {\n leave: 'Leave',\n expense: 'Expense',\n purchase: 'Purchase',\n contract: 'Contract',\n document: 'Document',\n other: 'Other',\n};\n\n/**\n * WorkflowCategoryBadge renders a badge with an icon and color for a workflow category.\n *\n * Each category has a dedicated icon and color scheme:\n * - leave: Calendar (blue)\n * - expense: Receipt (green)\n * - purchase: ShoppingCart (amber)\n * - contract: FileSignature (purple)\n * - document: FileText (cyan)\n * - other: MoreHorizontal (muted)\n */\nexport function WorkflowCategoryBadge({ category, label, className }: WorkflowCategoryBadgeProps) {\n const config = categoryConfig[category];\n const Icon = config.icon;\n\n return (\n <Badge variant=\"outline\" className={cn(config.style, className)}>\n <Icon className=\"w-3 h-3 mr-1\" />\n {label ?? defaultLabels[category]}\n </Badge>\n );\n}\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Badge } from './chunk-3TGN2DFB.js';
|
|
2
|
+
import { cn } from './chunk-DGPY4WP3.js';
|
|
3
|
+
import { GitBranch, Bell, Eye, CheckCircle } from 'lucide-react';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var stageConfig = {
|
|
7
|
+
approval: {
|
|
8
|
+
icon: CheckCircle,
|
|
9
|
+
style: "bg-green-50 dark:bg-green-500/15 text-green-600 dark:text-green-400 border-green-200 dark:border-green-500/30"
|
|
10
|
+
},
|
|
11
|
+
review: {
|
|
12
|
+
icon: Eye,
|
|
13
|
+
style: "bg-blue-50 dark:bg-blue-500/15 text-blue-600 dark:text-blue-400 border-blue-200 dark:border-blue-500/30"
|
|
14
|
+
},
|
|
15
|
+
notification: {
|
|
16
|
+
icon: Bell,
|
|
17
|
+
style: "bg-amber-50 dark:bg-amber-500/15 text-amber-600 dark:text-amber-400 border-amber-200 dark:border-amber-500/30"
|
|
18
|
+
},
|
|
19
|
+
conditional: {
|
|
20
|
+
icon: GitBranch,
|
|
21
|
+
style: "bg-purple-50 dark:bg-purple-500/15 text-purple-600 dark:text-purple-400 border-purple-200 dark:border-purple-500/30"
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
var defaultLabels = {
|
|
25
|
+
approval: "Approval",
|
|
26
|
+
review: "Review",
|
|
27
|
+
notification: "Notification",
|
|
28
|
+
conditional: "Conditional"
|
|
29
|
+
};
|
|
30
|
+
function StageTypeBadge({ type, label, className }) {
|
|
31
|
+
const config = stageConfig[type];
|
|
32
|
+
const Icon = config.icon;
|
|
33
|
+
return /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: cn(config.style, className), children: [
|
|
34
|
+
/* @__PURE__ */ jsx(Icon, { className: "w-3 h-3 mr-1" }),
|
|
35
|
+
label ?? defaultLabels[type]
|
|
36
|
+
] });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { StageTypeBadge };
|
|
40
|
+
//# sourceMappingURL=chunk-YF6WRCTG.js.map
|
|
41
|
+
//# sourceMappingURL=chunk-YF6WRCTG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/stage-type-badge.tsx"],"names":[],"mappings":";;;;;AAgBA,IAAM,WAAA,GAA8E;AAAA,EAClF,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,WAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,GAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,IAAA,EAAM,IAAA;AAAA,IACN,KAAA,EACE;AAAA,GACJ;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EACE;AAAA;AAEN,CAAA;AAEA,IAAM,aAAA,GAA2C;AAAA,EAC/C,QAAA,EAAU,UAAA;AAAA,EACV,MAAA,EAAQ,QAAA;AAAA,EACR,YAAA,EAAc,cAAA;AAAA,EACd,WAAA,EAAa;AACf,CAAA;AAWO,SAAS,cAAA,CAAe,EAAE,IAAA,EAAM,KAAA,EAAO,WAAU,EAAwB;AAC9E,EAAA,MAAM,MAAA,GAAS,YAAY,IAAI,CAAA;AAC/B,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA;AAEpB,EAAA,uBACE,IAAA,CAAC,SAAM,OAAA,EAAQ,SAAA,EAAU,WAAW,EAAA,CAAG,MAAA,CAAO,KAAA,EAAO,SAAS,CAAA,EAC5D,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,WAAU,cAAA,EAAe,CAAA;AAAA,IAC9B,KAAA,IAAS,cAAc,IAAI;AAAA,GAAA,EAC9B,CAAA;AAEJ","file":"chunk-YF6WRCTG.js","sourcesContent":["import { CheckCircle, Eye, Bell, GitBranch } from 'lucide-react';\nimport { cn } from '../lib/utils';\nimport { Badge } from './badge';\n\n/** Supported stage types with built-in icon and color mappings. */\nexport type StageType = 'approval' | 'review' | 'notification' | 'conditional';\n\nexport interface StageTypeBadgeProps {\n /** The stage type key. Determines the icon and color. */\n type: StageType;\n /** The displayed label text. Defaults to a capitalized version of the type. */\n label?: string;\n /** Optional additional className. */\n className?: string;\n}\n\nconst stageConfig: Record<StageType, { icon: typeof CheckCircle; style: string }> = {\n approval: {\n icon: CheckCircle,\n style:\n 'bg-green-50 dark:bg-green-500/15 text-green-600 dark:text-green-400 border-green-200 dark:border-green-500/30',\n },\n review: {\n icon: Eye,\n style:\n 'bg-blue-50 dark:bg-blue-500/15 text-blue-600 dark:text-blue-400 border-blue-200 dark:border-blue-500/30',\n },\n notification: {\n icon: Bell,\n style:\n 'bg-amber-50 dark:bg-amber-500/15 text-amber-600 dark:text-amber-400 border-amber-200 dark:border-amber-500/30',\n },\n conditional: {\n icon: GitBranch,\n style:\n 'bg-purple-50 dark:bg-purple-500/15 text-purple-600 dark:text-purple-400 border-purple-200 dark:border-purple-500/30',\n },\n};\n\nconst defaultLabels: Record<StageType, string> = {\n approval: 'Approval',\n review: 'Review',\n notification: 'Notification',\n conditional: 'Conditional',\n};\n\n/**\n * StageTypeBadge renders a badge with an icon and color for a workflow stage type.\n *\n * Each type has a dedicated icon and color scheme:\n * - approval: CheckCircle (green)\n * - review: Eye (blue)\n * - notification: Bell (amber)\n * - conditional: GitBranch (purple)\n */\nexport function StageTypeBadge({ type, label, className }: StageTypeBadgeProps) {\n const config = stageConfig[type];\n const Icon = config.icon;\n\n return (\n <Badge variant=\"outline\" className={cn(config.style, className)}>\n <Icon className=\"w-3 h-3 mr-1\" />\n {label ?? defaultLabels[type]}\n </Badge>\n );\n}\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { cn } from './chunk-DGPY4WP3.js';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
var Input = React.forwardRef(
|
|
6
|
+
({ className, type, ...props }, ref) => {
|
|
7
|
+
return /* @__PURE__ */ jsx(
|
|
8
|
+
"input",
|
|
9
|
+
{
|
|
10
|
+
type,
|
|
11
|
+
ref,
|
|
12
|
+
"data-slot": "input",
|
|
13
|
+
className: cn(
|
|
14
|
+
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-element w-full min-w-0 rounded-md border px-3 py-1 text-base bg-input-background transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
15
|
+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
16
|
+
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
17
|
+
className
|
|
18
|
+
),
|
|
19
|
+
...props
|
|
20
|
+
}
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
Input.displayName = "Input";
|
|
25
|
+
|
|
26
|
+
export { Input };
|
|
27
|
+
//# sourceMappingURL=chunk-YGBYH4EO.js.map
|
|
28
|
+
//# sourceMappingURL=chunk-YGBYH4EO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/input.tsx"],"names":[],"mappings":";;;;AAIA,IAAM,KAAA,GAAc,KAAA,CAAA,UAAA;AAAA,EAClB,CAAC,EAAE,SAAA,EAAW,MAAM,GAAG,KAAA,IAAS,GAAA,KAAQ;AACtC,IAAA,uBACE,GAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,GAAA;AAAA,QACA,WAAA,EAAU,OAAA;AAAA,QACV,SAAA,EAAW,EAAA;AAAA,UACT,kcAAA;AAAA,UACA,+EAAA;AAAA,UACA,wGAAA;AAAA,UACA;AAAA,SACF;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-YGBYH4EO.js","sourcesContent":["import * as React from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\nconst Input = React.forwardRef<HTMLInputElement, React.ComponentProps<\"input\">>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n ref={ref}\n data-slot=\"input\"\n className={cn(\n \"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-element w-full min-w-0 rounded-md border px-3 py-1 text-base bg-input-background transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm\",\n \"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]\",\n \"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n className,\n )}\n {...props}\n />\n );\n }\n);\nInput.displayName = \"Input\";\n\nexport { Input };"]}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { cn } from './chunk-DGPY4WP3.js';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
function Table({ className, ...props }) {
|
|
5
|
+
return /* @__PURE__ */ jsx(
|
|
6
|
+
"div",
|
|
7
|
+
{
|
|
8
|
+
"data-slot": "table-container",
|
|
9
|
+
className: "relative w-full overflow-x-auto",
|
|
10
|
+
children: /* @__PURE__ */ jsx(
|
|
11
|
+
"table",
|
|
12
|
+
{
|
|
13
|
+
"data-slot": "table",
|
|
14
|
+
className: cn("w-full caption-bottom text-sm", className),
|
|
15
|
+
...props
|
|
16
|
+
}
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
function TableHeader({ className, ...props }) {
|
|
22
|
+
return /* @__PURE__ */ jsx(
|
|
23
|
+
"thead",
|
|
24
|
+
{
|
|
25
|
+
"data-slot": "table-header",
|
|
26
|
+
className: cn("[&_tr]:border-b", className),
|
|
27
|
+
...props
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
function TableBody({ className, ...props }) {
|
|
32
|
+
return /* @__PURE__ */ jsx(
|
|
33
|
+
"tbody",
|
|
34
|
+
{
|
|
35
|
+
"data-slot": "table-body",
|
|
36
|
+
className: cn("[&_tr:last-child]:border-0", className),
|
|
37
|
+
...props
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
function TableFooter({ className, ...props }) {
|
|
42
|
+
return /* @__PURE__ */ jsx(
|
|
43
|
+
"tfoot",
|
|
44
|
+
{
|
|
45
|
+
"data-slot": "table-footer",
|
|
46
|
+
className: cn(
|
|
47
|
+
"bg-muted/50 border-t font-medium [&>tr]:last:border-b-0",
|
|
48
|
+
className
|
|
49
|
+
),
|
|
50
|
+
...props
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
function TableRow({ className, ...props }) {
|
|
55
|
+
return /* @__PURE__ */ jsx(
|
|
56
|
+
"tr",
|
|
57
|
+
{
|
|
58
|
+
"data-slot": "table-row",
|
|
59
|
+
className: cn(
|
|
60
|
+
"hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors",
|
|
61
|
+
className
|
|
62
|
+
),
|
|
63
|
+
...props
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
function TableHead({ className, ...props }) {
|
|
68
|
+
return /* @__PURE__ */ jsx(
|
|
69
|
+
"th",
|
|
70
|
+
{
|
|
71
|
+
"data-slot": "table-head",
|
|
72
|
+
className: cn(
|
|
73
|
+
"text-foreground h-table-head px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
|
|
74
|
+
className
|
|
75
|
+
),
|
|
76
|
+
...props
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
function TableCell({ className, ...props }) {
|
|
81
|
+
return /* @__PURE__ */ jsx(
|
|
82
|
+
"td",
|
|
83
|
+
{
|
|
84
|
+
"data-slot": "table-cell",
|
|
85
|
+
className: cn(
|
|
86
|
+
"p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
|
|
87
|
+
className
|
|
88
|
+
),
|
|
89
|
+
...props
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
function TableCaption({
|
|
94
|
+
className,
|
|
95
|
+
...props
|
|
96
|
+
}) {
|
|
97
|
+
return /* @__PURE__ */ jsx(
|
|
98
|
+
"caption",
|
|
99
|
+
{
|
|
100
|
+
"data-slot": "table-caption",
|
|
101
|
+
className: cn("text-muted-foreground mt-4 text-sm", className),
|
|
102
|
+
...props
|
|
103
|
+
}
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };
|
|
108
|
+
//# sourceMappingURL=chunk-YKJZV2JK.js.map
|
|
109
|
+
//# sourceMappingURL=chunk-YKJZV2JK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/table.tsx"],"names":[],"mappings":";;;AAIA,SAAS,KAAA,CAAM,EAAE,SAAA,EAAW,GAAG,OAAM,EAAkC;AACrE,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,iBAAA;AAAA,MACV,SAAA,EAAU,iCAAA;AAAA,MAEV,QAAA,kBAAA,GAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,WAAA,EAAU,OAAA;AAAA,UACV,SAAA,EAAW,EAAA,CAAG,+BAAA,EAAiC,SAAS,CAAA;AAAA,UACvD,GAAG;AAAA;AAAA;AACN;AAAA,GACF;AAEJ;AAEA,SAAS,WAAA,CAAY,EAAE,SAAA,EAAW,GAAG,OAAM,EAAkC;AAC3E,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,cAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,iBAAA,EAAmB,SAAS,CAAA;AAAA,MACzC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,SAAA,CAAU,EAAE,SAAA,EAAW,GAAG,OAAM,EAAkC;AACzE,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,YAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,4BAAA,EAA8B,SAAS,CAAA;AAAA,MACpD,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,WAAA,CAAY,EAAE,SAAA,EAAW,GAAG,OAAM,EAAkC;AAC3E,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,cAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,yDAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,QAAA,CAAS,EAAE,SAAA,EAAW,GAAG,OAAM,EAA+B;AACrE,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,WAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,6EAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,SAAA,CAAU,EAAE,SAAA,EAAW,GAAG,OAAM,EAA+B;AACtE,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,YAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,4JAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,SAAA,CAAU,EAAE,SAAA,EAAW,GAAG,OAAM,EAA+B;AACtE,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,YAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,wGAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,YAAA,CAAa;AAAA,EACpB,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAoC;AAClC,EAAA,uBACE,GAAA;AAAA,IAAC,SAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,eAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,oCAAA,EAAsC,SAAS,CAAA;AAAA,MAC5D,GAAG;AAAA;AAAA,GACN;AAEJ","file":"chunk-YKJZV2JK.js","sourcesContent":["import * as React from \"react\";\n\nimport { cn } from \"../lib/utils\";\n\nfunction Table({ className, ...props }: React.ComponentProps<\"table\">) {\n return (\n <div\n data-slot=\"table-container\"\n className=\"relative w-full overflow-x-auto\"\n >\n <table\n data-slot=\"table\"\n className={cn(\"w-full caption-bottom text-sm\", className)}\n {...props}\n />\n </div>\n );\n}\n\nfunction TableHeader({ className, ...props }: React.ComponentProps<\"thead\">) {\n return (\n <thead\n data-slot=\"table-header\"\n className={cn(\"[&_tr]:border-b\", className)}\n {...props}\n />\n );\n}\n\nfunction TableBody({ className, ...props }: React.ComponentProps<\"tbody\">) {\n return (\n <tbody\n data-slot=\"table-body\"\n className={cn(\"[&_tr:last-child]:border-0\", className)}\n {...props}\n />\n );\n}\n\nfunction TableFooter({ className, ...props }: React.ComponentProps<\"tfoot\">) {\n return (\n <tfoot\n data-slot=\"table-footer\"\n className={cn(\n \"bg-muted/50 border-t font-medium [&>tr]:last:border-b-0\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TableRow({ className, ...props }: React.ComponentProps<\"tr\">) {\n return (\n <tr\n data-slot=\"table-row\"\n className={cn(\n \"hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TableHead({ className, ...props }: React.ComponentProps<\"th\">) {\n return (\n <th\n data-slot=\"table-head\"\n className={cn(\n \"text-foreground h-table-head px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TableCell({ className, ...props }: React.ComponentProps<\"td\">) {\n return (\n <td\n data-slot=\"table-cell\"\n className={cn(\n \"p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction TableCaption({\n className,\n ...props\n}: React.ComponentProps<\"caption\">) {\n return (\n <caption\n data-slot=\"table-caption\"\n className={cn(\"text-muted-foreground mt-4 text-sm\", className)}\n {...props}\n />\n );\n}\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n};"]}
|