@hua-labs/ui 1.0.0 → 1.1.0-alpha.0.2
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 +897 -210
- package/dist/ComponentLayout-BxCenSAm.d.mts +73 -0
- package/dist/advanced/dashboard.d.ts +7 -0
- package/dist/advanced/dashboard.d.ts.map +1 -0
- package/dist/advanced/motion.d.ts +2 -0
- package/dist/advanced/motion.d.ts.map +1 -0
- package/dist/advanced-dashboard.d.mts +4 -0
- package/dist/advanced-dashboard.js +2 -0
- package/dist/advanced-dashboard.js.map +1 -0
- package/dist/advanced-dashboard.mjs +2 -0
- package/dist/advanced-dashboard.mjs.map +1 -0
- package/dist/advanced-motion.d.mts +93 -0
- package/dist/advanced-motion.js +2 -0
- package/dist/advanced-motion.js.map +1 -0
- package/dist/advanced-motion.mjs +2 -0
- package/dist/advanced-motion.mjs.map +1 -0
- package/dist/advanced.d.mts +734 -0
- package/dist/advanced.d.ts +17 -0
- package/dist/advanced.d.ts.map +1 -0
- package/dist/advanced.js +2 -0
- package/dist/advanced.js.map +1 -0
- package/dist/advanced.mjs +2 -0
- package/dist/advanced.mjs.map +1 -0
- package/dist/chunk-627HOIRV.mjs +2 -0
- package/dist/chunk-627HOIRV.mjs.map +1 -0
- package/dist/chunk-ACEKLG37.mjs +2 -0
- package/dist/chunk-ACEKLG37.mjs.map +1 -0
- package/dist/chunk-E5PN4LUS.mjs +2 -0
- package/dist/chunk-E5PN4LUS.mjs.map +1 -0
- package/dist/chunk-KHEJZ3U4.mjs +2 -0
- package/dist/chunk-KHEJZ3U4.mjs.map +1 -0
- package/dist/chunk-MXGXBG63.mjs +2 -0
- package/dist/chunk-MXGXBG63.mjs.map +1 -0
- package/dist/chunk-R5KCFRYV.mjs +2 -0
- package/dist/chunk-R5KCFRYV.mjs.map +1 -0
- package/dist/chunk-UGSYQDR4.mjs +2 -0
- package/dist/chunk-UGSYQDR4.mjs.map +1 -0
- package/dist/chunk-UUHAXGMO.mjs +2 -0
- package/dist/chunk-UUHAXGMO.mjs.map +1 -0
- package/dist/chunk-VU264VFN.mjs +2 -0
- package/dist/chunk-VU264VFN.mjs.map +1 -0
- package/dist/chunk-ZFS4B5QT.mjs +2 -0
- package/dist/chunk-ZFS4B5QT.mjs.map +1 -0
- package/dist/components/Accordion.d.ts +109 -1
- package/dist/components/Accordion.d.ts.map +1 -1
- package/dist/components/Action.d.ts +68 -0
- package/dist/components/Action.d.ts.map +1 -0
- package/dist/components/ActionToolbar.d.ts +65 -0
- package/dist/components/ActionToolbar.d.ts.map +1 -0
- package/dist/components/Alert.d.ts +49 -0
- package/dist/components/Alert.d.ts.map +1 -1
- package/dist/components/Autocomplete.d.ts +88 -0
- package/dist/components/Autocomplete.d.ts.map +1 -0
- package/dist/components/Avatar.d.ts +71 -1
- package/dist/components/Avatar.d.ts.map +1 -1
- package/dist/components/Badge.d.ts +32 -2
- package/dist/components/Badge.d.ts.map +1 -1
- package/dist/components/Bookmark.d.ts +49 -0
- package/dist/components/Bookmark.d.ts.map +1 -0
- package/dist/components/BottomSheet.d.ts +91 -1
- package/dist/components/BottomSheet.d.ts.map +1 -1
- package/dist/components/Breadcrumb.d.ts +73 -14
- package/dist/components/Breadcrumb.d.ts.map +1 -1
- package/dist/components/Button.d.ts +82 -7
- package/dist/components/Button.d.ts.map +1 -1
- package/dist/components/Card.d.ts +122 -5
- package/dist/components/Card.d.ts.map +1 -1
- package/dist/components/ChatMessage.d.ts +67 -1
- package/dist/components/ChatMessage.d.ts.map +1 -1
- package/dist/components/Checkbox.d.ts +48 -2
- package/dist/components/Checkbox.d.ts.map +1 -1
- package/dist/components/Command.d.ts +82 -1
- package/dist/components/Command.d.ts.map +1 -1
- package/dist/components/ComponentLayout.d.ts +72 -0
- package/dist/components/ComponentLayout.d.ts.map +1 -0
- package/dist/components/ConfirmModal.d.ts +66 -1
- package/dist/components/ConfirmModal.d.ts.map +1 -1
- package/dist/components/Container.d.ts +39 -0
- package/dist/components/Container.d.ts.map +1 -1
- package/dist/components/ContextMenu.d.ts +51 -1
- package/dist/components/ContextMenu.d.ts.map +1 -1
- package/dist/components/DatePicker.d.ts +62 -0
- package/dist/components/DatePicker.d.ts.map +1 -0
- package/dist/components/Divider.d.ts +13 -3
- package/dist/components/Divider.d.ts.map +1 -1
- package/dist/components/Drawer.d.ts +103 -1
- package/dist/components/Drawer.d.ts.map +1 -1
- package/dist/components/Dropdown.d.ts +51 -1
- package/dist/components/Dropdown.d.ts.map +1 -1
- package/dist/components/EmotionAnalysis.d.ts +59 -1
- package/dist/components/EmotionAnalysis.d.ts.map +1 -1
- package/dist/components/EmotionButton.d.ts +35 -1
- package/dist/components/EmotionButton.d.ts.map +1 -1
- package/dist/components/EmotionMeter.d.ts +38 -2
- package/dist/components/EmotionMeter.d.ts.map +1 -1
- package/dist/components/EmotionSelector.d.ts +51 -1
- package/dist/components/EmotionSelector.d.ts.map +1 -1
- package/dist/components/FeatureCard.d.ts +61 -0
- package/dist/components/FeatureCard.d.ts.map +1 -0
- package/dist/components/Form.d.ts +114 -0
- package/dist/components/Form.d.ts.map +1 -0
- package/dist/components/Grid.d.ts +42 -1
- package/dist/components/Grid.d.ts.map +1 -1
- package/dist/components/HeroSection.d.ts +77 -0
- package/dist/components/HeroSection.d.ts.map +1 -0
- package/dist/components/Icon/Icon.d.ts +159 -0
- package/dist/components/Icon/Icon.d.ts.map +1 -0
- package/dist/components/Icon/IconProvider.d.ts +94 -0
- package/dist/components/Icon/IconProvider.d.ts.map +1 -0
- package/dist/components/Icon/icon-store.d.ts +21 -0
- package/dist/components/Icon/icon-store.d.ts.map +1 -0
- package/dist/components/Icon/index.d.ts +10 -0
- package/dist/components/Icon/index.d.ts.map +1 -0
- package/dist/components/InfoCard.d.ts +48 -0
- package/dist/components/InfoCard.d.ts.map +1 -0
- package/dist/components/Input.d.ts +40 -8
- package/dist/components/Input.d.ts.map +1 -1
- package/dist/components/Label.d.ts +50 -0
- package/dist/components/Label.d.ts.map +1 -0
- package/dist/components/LanguageToggle.d.ts +41 -1
- package/dist/components/LanguageToggle.d.ts.map +1 -1
- package/dist/components/Link.d.ts +52 -0
- package/dist/components/Link.d.ts.map +1 -0
- package/dist/components/LoadingSpinner.d.ts +44 -5
- package/dist/components/LoadingSpinner.d.ts.map +1 -1
- package/dist/components/Menu.d.ts +92 -1
- package/dist/components/Menu.d.ts.map +1 -1
- package/dist/components/Modal.d.ts +67 -5
- package/dist/components/Modal.d.ts.map +1 -1
- package/dist/components/Navigation.d.ts +72 -0
- package/dist/components/Navigation.d.ts.map +1 -0
- package/dist/components/PageNavigation.d.ts +48 -0
- package/dist/components/PageNavigation.d.ts.map +1 -0
- package/dist/components/PageTransition.d.ts +44 -1
- package/dist/components/PageTransition.d.ts.map +1 -1
- package/dist/components/Pagination.d.ts +52 -1
- package/dist/components/Pagination.d.ts.map +1 -1
- package/dist/components/Panel.d.ts +99 -0
- package/dist/components/Panel.d.ts.map +1 -0
- package/dist/components/Popover.d.ts +46 -1
- package/dist/components/Popover.d.ts.map +1 -1
- package/dist/components/Progress.d.ts +52 -3
- package/dist/components/Progress.d.ts.map +1 -1
- package/dist/components/Radio.d.ts +44 -2
- package/dist/components/Radio.d.ts.map +1 -1
- package/dist/components/ScrollArea.d.ts +53 -1
- package/dist/components/ScrollArea.d.ts.map +1 -1
- package/dist/components/ScrollIndicator.d.ts +43 -1
- package/dist/components/ScrollIndicator.d.ts.map +1 -1
- package/dist/components/ScrollProgress.d.ts +37 -0
- package/dist/components/ScrollProgress.d.ts.map +1 -1
- package/dist/components/ScrollToTop.d.ts +48 -11
- package/dist/components/ScrollToTop.d.ts.map +1 -1
- package/dist/components/SectionHeader.d.ts +42 -0
- package/dist/components/SectionHeader.d.ts.map +1 -0
- package/dist/components/Select.d.ts +59 -2
- package/dist/components/Select.d.ts.map +1 -1
- package/dist/components/Skeleton.d.ts +44 -1
- package/dist/components/Skeleton.d.ts.map +1 -1
- package/dist/components/Slider.d.ts +75 -0
- package/dist/components/Slider.d.ts.map +1 -0
- package/dist/components/Stack.d.ts +42 -1
- package/dist/components/Stack.d.ts.map +1 -1
- package/dist/components/StatsPanel.d.ts +72 -0
- package/dist/components/StatsPanel.d.ts.map +1 -0
- package/dist/components/Switch.d.ts +48 -2
- package/dist/components/Switch.d.ts.map +1 -1
- package/dist/components/Table.d.ts +206 -0
- package/dist/components/Table.d.ts.map +1 -0
- package/dist/components/Tabs.d.ts +123 -10
- package/dist/components/Tabs.d.ts.map +1 -1
- package/dist/components/Textarea.d.ts +48 -2
- package/dist/components/Textarea.d.ts.map +1 -1
- package/dist/components/ThemeProvider.d.ts +67 -2
- package/dist/components/ThemeProvider.d.ts.map +1 -1
- package/dist/components/ThemeToggle.d.ts +44 -0
- package/dist/components/ThemeToggle.d.ts.map +1 -1
- package/dist/components/Toast.d.ts +75 -1
- package/dist/components/Toast.d.ts.map +1 -1
- package/dist/components/Toggle.d.ts +62 -0
- package/dist/components/Toggle.d.ts.map +1 -0
- package/dist/components/Tooltip.d.ts +48 -1
- package/dist/components/Tooltip.d.ts.map +1 -1
- package/dist/components/Upload.d.ts +87 -0
- package/dist/components/Upload.d.ts.map +1 -0
- package/dist/components/advanced/AdvancedPageTransition.d.ts +25 -0
- package/dist/components/advanced/AdvancedPageTransition.d.ts.map +1 -0
- package/dist/components/advanced/index.d.ts +4 -0
- package/dist/components/advanced/index.d.ts.map +1 -0
- package/dist/components/advanced/usePageTransition.d.ts +33 -0
- package/dist/components/advanced/usePageTransition.d.ts.map +1 -0
- package/dist/components/advanced/usePageTransitionManager.d.ts +44 -0
- package/dist/components/advanced/usePageTransitionManager.d.ts.map +1 -0
- package/dist/components/dashboard/ActivityFeed.d.ts +87 -0
- package/dist/components/dashboard/ActivityFeed.d.ts.map +1 -0
- package/dist/components/dashboard/BarChart.d.ts +82 -0
- package/dist/components/dashboard/BarChart.d.ts.map +1 -0
- package/dist/components/dashboard/DashboardGrid.d.ts +44 -0
- package/dist/components/dashboard/DashboardGrid.d.ts.map +1 -0
- package/dist/components/dashboard/DashboardSidebar.d.ts +105 -0
- package/dist/components/dashboard/DashboardSidebar.d.ts.map +1 -0
- package/dist/components/dashboard/DashboardToolbar.d.ts +120 -0
- package/dist/components/dashboard/DashboardToolbar.d.ts.map +1 -0
- package/dist/components/dashboard/EmptyState.d.ts +61 -0
- package/dist/components/dashboard/EmptyState.d.ts.map +1 -0
- package/dist/components/dashboard/MembershipBadge.d.ts +45 -0
- package/dist/components/dashboard/MembershipBadge.d.ts.map +1 -0
- package/dist/components/dashboard/MerchantList.d.ts +98 -0
- package/dist/components/dashboard/MerchantList.d.ts.map +1 -0
- package/dist/components/dashboard/MetricCard.d.ts +75 -0
- package/dist/components/dashboard/MetricCard.d.ts.map +1 -0
- package/dist/components/dashboard/MiniBarChart.d.ts +60 -0
- package/dist/components/dashboard/MiniBarChart.d.ts.map +1 -0
- package/dist/components/dashboard/NotificationCard.d.ts +89 -0
- package/dist/components/dashboard/NotificationCard.d.ts.map +1 -0
- package/dist/components/dashboard/ProfileCard.d.ts +82 -0
- package/dist/components/dashboard/ProfileCard.d.ts.map +1 -0
- package/dist/components/dashboard/ProgressCard.d.ts +71 -0
- package/dist/components/dashboard/ProgressCard.d.ts.map +1 -0
- package/dist/components/dashboard/QuickActionCard.d.ts +63 -0
- package/dist/components/dashboard/QuickActionCard.d.ts.map +1 -0
- package/dist/components/dashboard/RoutingBreakdownCard.d.ts +88 -0
- package/dist/components/dashboard/RoutingBreakdownCard.d.ts.map +1 -0
- package/dist/components/dashboard/SettlementTimeline.d.ts +90 -0
- package/dist/components/dashboard/SettlementTimeline.d.ts.map +1 -0
- package/dist/components/dashboard/StatCard.d.ts +70 -0
- package/dist/components/dashboard/StatCard.d.ts.map +1 -0
- package/dist/components/dashboard/SummaryCard.d.ts +73 -0
- package/dist/components/dashboard/SummaryCard.d.ts.map +1 -0
- package/dist/components/dashboard/TransactionDetailDrawer.d.ts +183 -0
- package/dist/components/dashboard/TransactionDetailDrawer.d.ts.map +1 -0
- package/dist/components/dashboard/TransactionsTable.d.ts +137 -0
- package/dist/components/dashboard/TransactionsTable.d.ts.map +1 -0
- package/dist/components/dashboard/TrendChart.d.ts +75 -0
- package/dist/components/dashboard/TrendChart.d.ts.map +1 -0
- package/dist/components/dashboard/index.d.ts +41 -0
- package/dist/components/dashboard/index.d.ts.map +1 -0
- package/dist/components/scrollbar/scrollbar.d.ts +12 -0
- package/dist/components/scrollbar/scrollbar.d.ts.map +1 -0
- package/dist/dashboard-QMssHf5j.d.mts +1801 -0
- package/dist/feedback.d.mts +103 -0
- package/dist/feedback.d.ts +21 -0
- package/dist/feedback.d.ts.map +1 -0
- package/dist/feedback.js +2 -0
- package/dist/feedback.js.map +1 -0
- package/dist/feedback.mjs +2 -0
- package/dist/feedback.mjs.map +1 -0
- package/dist/form.d.mts +803 -0
- package/dist/form.d.ts +42 -0
- package/dist/form.d.ts.map +1 -0
- package/dist/form.js +2 -0
- package/dist/form.js.map +1 -0
- package/dist/form.mjs +2 -0
- package/dist/form.mjs.map +1 -0
- package/dist/hooks/useScrollToggle.d.ts +12 -0
- package/dist/hooks/useScrollToggle.d.ts.map +1 -0
- package/dist/icons-DoSGIez_.d.mts +135 -0
- package/dist/index.d.mts +3770 -0
- package/dist/index.d.ts +76 -38
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -49
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +37 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lib/icon-aliases.d.ts +24 -0
- package/dist/lib/icon-aliases.d.ts.map +1 -0
- package/dist/lib/icon-names.d.ts +47 -0
- package/dist/lib/icon-names.d.ts.map +1 -0
- package/dist/lib/icon-providers.d.ts +559 -0
- package/dist/lib/icon-providers.d.ts.map +1 -0
- package/dist/lib/icons.d.ts +113 -24
- package/dist/lib/icons.d.ts.map +1 -1
- package/dist/lib/phosphor-icons.d.ts +6 -0
- package/dist/lib/phosphor-icons.d.ts.map +1 -0
- package/dist/lib/styles/colors.d.ts +131 -0
- package/dist/lib/styles/colors.d.ts.map +1 -0
- package/dist/lib/styles/index.d.ts +8 -0
- package/dist/lib/styles/index.d.ts.map +1 -0
- package/dist/lib/styles/utils.d.ts +87 -0
- package/dist/lib/styles/utils.d.ts.map +1 -0
- package/dist/lib/styles/variants.d.ts +79 -0
- package/dist/lib/styles/variants.d.ts.map +1 -0
- package/dist/lib/types/common.d.ts +80 -0
- package/dist/lib/types/common.d.ts.map +1 -0
- package/dist/lib/types/index.d.ts +6 -0
- package/dist/lib/types/index.d.ts.map +1 -0
- package/dist/lib/utils.d.ts +73 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/navigation.d.mts +105 -0
- package/dist/navigation.d.ts +22 -0
- package/dist/navigation.d.ts.map +1 -0
- package/dist/navigation.js +2 -0
- package/dist/navigation.js.map +1 -0
- package/dist/navigation.mjs +2 -0
- package/dist/navigation.mjs.map +1 -0
- package/package.json +92 -25
- package/src/styles/toast.css +23 -0
- package/dist/components/Accordion.js +0 -84
- package/dist/components/Alert.js +0 -61
- package/dist/components/Avatar.js +0 -18
- package/dist/components/Badge.js +0 -15
- package/dist/components/BottomSheet.js +0 -96
- package/dist/components/Breadcrumb.js +0 -47
- package/dist/components/Button.js +0 -23
- package/dist/components/Card.js +0 -18
- package/dist/components/ChatMessage.js +0 -59
- package/dist/components/Checkbox.js +0 -30
- package/dist/components/Command.js +0 -119
- package/dist/components/ConfirmModal.js +0 -53
- package/dist/components/Container.js +0 -23
- package/dist/components/ContextMenu.js +0 -110
- package/dist/components/Divider.js +0 -39
- package/dist/components/Drawer.js +0 -79
- package/dist/components/Dropdown.js +0 -174
- package/dist/components/EmotionAnalysis.js +0 -40
- package/dist/components/EmotionButton.js +0 -16
- package/dist/components/EmotionMeter.js +0 -21
- package/dist/components/EmotionSelector.js +0 -46
- package/dist/components/Grid.js +0 -44
- package/dist/components/Icon.d.ts +0 -26
- package/dist/components/Icon.d.ts.map +0 -1
- package/dist/components/Icon.js +0 -48
- package/dist/components/Input.js +0 -25
- package/dist/components/LanguageToggle.js +0 -61
- package/dist/components/LoadingSpinner.js +0 -37
- package/dist/components/Menu.js +0 -122
- package/dist/components/Modal.js +0 -62
- package/dist/components/PageTransition.js +0 -39
- package/dist/components/Pagination.js +0 -87
- package/dist/components/Popover.js +0 -159
- package/dist/components/Progress.js +0 -51
- package/dist/components/Radio.js +0 -29
- package/dist/components/ScrollArea.js +0 -42
- package/dist/components/ScrollIndicator.js +0 -60
- package/dist/components/ScrollProgress.js +0 -39
- package/dist/components/ScrollToTop.js +0 -46
- package/dist/components/Select.js +0 -29
- package/dist/components/Skeleton.js +0 -71
- package/dist/components/Stack.js +0 -34
- package/dist/components/Switch.js +0 -29
- package/dist/components/Tabs.js +0 -117
- package/dist/components/Textarea.js +0 -31
- package/dist/components/ThemeProvider.js +0 -76
- package/dist/components/ThemeToggle.js +0 -49
- package/dist/components/Toast.js +0 -138
- package/dist/components/Tooltip.js +0 -102
- package/dist/lib/icons.js +0 -321
- package/dist/lib/utils.js +0 -5
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import { cn } from "../lib/utils";
|
|
5
|
-
import { Icon } from "./Icon";
|
|
6
|
-
const Checkbox = React.forwardRef(({ className, variant = "default", size = "md", error = false, success = false, label, description, ...props }, ref) => {
|
|
7
|
-
const sizeClasses = {
|
|
8
|
-
sm: "w-4 h-4",
|
|
9
|
-
md: "w-5 h-5",
|
|
10
|
-
lg: "w-6 h-6"
|
|
11
|
-
};
|
|
12
|
-
const iconSizes = {
|
|
13
|
-
sm: 12,
|
|
14
|
-
md: 14,
|
|
15
|
-
lg: 16
|
|
16
|
-
};
|
|
17
|
-
const variantClasses = {
|
|
18
|
-
default: "border-gray-300 bg-white text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-800 dark:focus:ring-blue-400",
|
|
19
|
-
outline: "border-2 border-gray-200 bg-transparent text-blue-600 focus:ring-blue-500 dark:border-gray-700 dark:focus:ring-blue-400",
|
|
20
|
-
filled: "border-transparent bg-gray-50 text-blue-600 focus:bg-white focus:ring-blue-500 dark:bg-gray-700 dark:focus:bg-gray-800 dark:focus:ring-blue-400"
|
|
21
|
-
};
|
|
22
|
-
const stateClasses = error
|
|
23
|
-
? "border-red-500 focus:ring-red-500 dark:border-red-400 dark:focus:ring-red-400"
|
|
24
|
-
: success
|
|
25
|
-
? "border-green-500 focus:ring-green-500 dark:border-green-400 dark:focus:ring-green-400"
|
|
26
|
-
: "";
|
|
27
|
-
return (_jsxs("div", { className: "flex items-start space-x-3", children: [_jsxs("div", { className: "relative", children: [_jsx("input", { type: "checkbox", className: cn("peer sr-only", className), ref: ref, ...props }), _jsx("div", { className: cn("flex items-center justify-center rounded border transition-all duration-200 cursor-pointer", "peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-offset-2", "peer-disabled:cursor-not-allowed peer-disabled:opacity-50", sizeClasses[size], variantClasses[variant], stateClasses, "peer-checked:bg-blue-600 peer-checked:border-blue-600 dark:peer-checked:bg-blue-500 dark:peer-checked:border-blue-500"), children: _jsx(Icon, { name: "check", size: iconSizes[size], className: "text-white opacity-0 peer-checked:opacity-100 transition-opacity duration-200" }) })] }), (label || description) && (_jsxs("div", { className: "flex flex-col", children: [label && (_jsx("label", { className: "text-sm font-medium text-gray-900 dark:text-white cursor-pointer", children: label })), description && (_jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: description }))] }))] }));
|
|
28
|
-
});
|
|
29
|
-
Checkbox.displayName = "Checkbox";
|
|
30
|
-
export { Checkbox };
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import { cn } from "../lib/utils";
|
|
5
|
-
const Command = React.forwardRef(({ className, children, open: controlledOpen, onOpenChange, placeholder = "명령어를 검색하세요...", searchValue: controlledSearchValue, onSearchChange, disabled = false, ...props }, ref) => {
|
|
6
|
-
const [internalOpen, setInternalOpen] = React.useState(false);
|
|
7
|
-
const [internalSearchValue, setInternalSearchValue] = React.useState("");
|
|
8
|
-
const [selectedIndex, setSelectedIndex] = React.useState(0);
|
|
9
|
-
const commandRef = React.useRef(null);
|
|
10
|
-
const inputRef = React.useRef(null);
|
|
11
|
-
const listRef = React.useRef(null);
|
|
12
|
-
const isControlled = controlledOpen !== undefined;
|
|
13
|
-
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
14
|
-
const searchValue = controlledSearchValue !== undefined ? controlledSearchValue : internalSearchValue;
|
|
15
|
-
const handleOpenChange = (newOpen) => {
|
|
16
|
-
if (disabled)
|
|
17
|
-
return;
|
|
18
|
-
if (!isControlled) {
|
|
19
|
-
setInternalOpen(newOpen);
|
|
20
|
-
}
|
|
21
|
-
onOpenChange?.(newOpen);
|
|
22
|
-
};
|
|
23
|
-
const handleSearchChange = (value) => {
|
|
24
|
-
if (!isControlled) {
|
|
25
|
-
setInternalSearchValue(value);
|
|
26
|
-
}
|
|
27
|
-
onSearchChange?.(value);
|
|
28
|
-
setSelectedIndex(0);
|
|
29
|
-
};
|
|
30
|
-
const handleKeyDown = (event) => {
|
|
31
|
-
if (disabled)
|
|
32
|
-
return;
|
|
33
|
-
const items = listRef.current?.querySelectorAll('[data-command-item]');
|
|
34
|
-
const itemCount = items?.length || 0;
|
|
35
|
-
switch (event.key) {
|
|
36
|
-
case 'ArrowDown':
|
|
37
|
-
event.preventDefault();
|
|
38
|
-
setSelectedIndex((prev) => (prev + 1) % itemCount);
|
|
39
|
-
break;
|
|
40
|
-
case 'ArrowUp':
|
|
41
|
-
event.preventDefault();
|
|
42
|
-
setSelectedIndex((prev) => (prev - 1 + itemCount) % itemCount);
|
|
43
|
-
break;
|
|
44
|
-
case 'Enter':
|
|
45
|
-
event.preventDefault();
|
|
46
|
-
const selectedItem = items?.[selectedIndex];
|
|
47
|
-
selectedItem?.click();
|
|
48
|
-
break;
|
|
49
|
-
case 'Escape':
|
|
50
|
-
event.preventDefault();
|
|
51
|
-
handleOpenChange(false);
|
|
52
|
-
break;
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
React.useEffect(() => {
|
|
56
|
-
if (isOpen) {
|
|
57
|
-
inputRef.current?.focus();
|
|
58
|
-
setSelectedIndex(0);
|
|
59
|
-
}
|
|
60
|
-
}, [isOpen]);
|
|
61
|
-
React.useEffect(() => {
|
|
62
|
-
const handleKeyDown = (event) => {
|
|
63
|
-
if (event.key === 'k' && (event.metaKey || event.ctrlKey)) {
|
|
64
|
-
event.preventDefault();
|
|
65
|
-
handleOpenChange(!isOpen);
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
document.addEventListener('keydown', handleKeyDown);
|
|
69
|
-
return () => {
|
|
70
|
-
document.removeEventListener('keydown', handleKeyDown);
|
|
71
|
-
};
|
|
72
|
-
}, [isOpen]);
|
|
73
|
-
React.useEffect(() => {
|
|
74
|
-
const selectedItem = listRef.current?.querySelector(`[data-command-item]:nth-child(${selectedIndex + 1})`);
|
|
75
|
-
selectedItem?.scrollIntoView({ block: 'nearest' });
|
|
76
|
-
}, [selectedIndex]);
|
|
77
|
-
return (_jsx("div", { ref: ref, className: cn("relative", className), ...props, children: isOpen && (_jsx("div", { ref: commandRef, className: cn("fixed inset-0 z-50 bg-black/50 backdrop-blur-sm", // 50% 투명도
|
|
78
|
-
"flex items-start justify-center pt-16" // 64px 상단 여백
|
|
79
|
-
), onClick: () => handleOpenChange(false), children: _jsxs("div", { className: cn("w-full max-w-2xl mx-4 bg-white dark:bg-gray-800 rounded-lg shadow-2xl", // 보더 대신 섀도우
|
|
80
|
-
"border-0 overflow-hidden" // 보더 제거
|
|
81
|
-
), onClick: (e) => e.stopPropagation(), style: {
|
|
82
|
-
boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)"
|
|
83
|
-
}, children: [_jsxs("div", { className: "p-4 border-b border-gray-200 dark:border-gray-700", children: [" ", _jsx("input", { ref: inputRef, type: "text", placeholder: placeholder, value: searchValue, onChange: (e) => handleSearchChange(e.target.value), onKeyDown: handleKeyDown, className: cn("w-full bg-transparent text-lg font-medium outline-none", // 18px 텍스트
|
|
84
|
-
"placeholder:text-gray-500 dark:placeholder:text-gray-400", "text-gray-900 dark:text-gray-100") })] }), _jsx("div", { ref: listRef, className: "max-h-96 overflow-y-auto py-2" // 384px 최대 높이, 8px 패딩
|
|
85
|
-
, children: React.Children.map(children, (child, index) => {
|
|
86
|
-
if (React.isValidElement(child)) {
|
|
87
|
-
return React.cloneElement(child, {
|
|
88
|
-
selected: index === selectedIndex,
|
|
89
|
-
onSelect: () => {
|
|
90
|
-
child.props?.onSelect?.();
|
|
91
|
-
handleOpenChange(false);
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
return child;
|
|
96
|
-
}) })] }) })) }));
|
|
97
|
-
});
|
|
98
|
-
Command.displayName = "Command";
|
|
99
|
-
const CommandInput = React.forwardRef(({ className, ...props }, ref) => (_jsx("input", { ref: ref, className: cn("flex h-10 w-full rounded-md bg-transparent px-3 py-2 text-sm outline-none", // 40px 높이, 12px, 8px 패딩
|
|
100
|
-
"placeholder:text-gray-500 dark:placeholder:text-gray-400", "disabled:cursor-not-allowed disabled:opacity-50", className), ...props })));
|
|
101
|
-
CommandInput.displayName = "CommandInput";
|
|
102
|
-
const CommandList = React.forwardRef(({ className, ...props }, ref) => (_jsx("div", { ref: ref, className: cn("max-h-96 overflow-y-auto py-2", className), ...props })));
|
|
103
|
-
CommandList.displayName = "CommandList";
|
|
104
|
-
const CommandItem = React.forwardRef(({ className, icon, selected = false, onSelect, children, ...props }, ref) => {
|
|
105
|
-
return (_jsxs("button", { ref: ref, "data-command-item": true, className: cn("relative flex w-full items-center gap-3 rounded-sm px-4 py-3 text-sm", // 16px, 12px 패딩
|
|
106
|
-
"text-gray-700 dark:text-gray-300", "hover:bg-gray-100 dark:hover:bg-gray-700", "focus:bg-gray-100 dark:focus:bg-gray-700", "focus:outline-none", selected && "bg-gray-100 dark:bg-gray-700", "transition-colors", className), onClick: onSelect, ...props, children: [icon && (_jsx("div", { className: "flex-shrink-0 w-4 h-4 text-gray-500 dark:text-gray-400", children: icon })), _jsx("span", { className: "flex-1 text-left", children: children })] }));
|
|
107
|
-
});
|
|
108
|
-
CommandItem.displayName = "CommandItem";
|
|
109
|
-
const CommandGroup = React.forwardRef(({ className, heading, children, ...props }, ref) => (_jsxs("div", { ref: ref, className: cn("py-2", className), ...props, children: [" ", heading && (_jsxs("div", { className: "px-4 py-2 text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide", children: [" ", heading] })), _jsxs("div", { className: "space-y-1", children: [" ", children] })] })));
|
|
110
|
-
CommandGroup.displayName = "CommandGroup";
|
|
111
|
-
const CommandSeparator = React.forwardRef(({ className, ...props }, ref) => (_jsx("div", { ref: ref, className: cn("h-px bg-gray-200 dark:bg-gray-700 my-2", className), ...props })));
|
|
112
|
-
CommandSeparator.displayName = "CommandSeparator";
|
|
113
|
-
const CommandEmpty = React.forwardRef(({ className, children = "결과가 없습니다.", ...props }, ref) => (_jsx("div", { ref: ref, className: cn("py-8 text-center text-sm text-gray-500 dark:text-gray-400", // 32px 패딩
|
|
114
|
-
className), ...props, children: children })));
|
|
115
|
-
CommandEmpty.displayName = "CommandEmpty";
|
|
116
|
-
// 편의 컴포넌트들
|
|
117
|
-
export const CommandDialog = React.forwardRef(({ className, ...props }, ref) => (_jsx(Command, { ref: ref, className: className, ...props })));
|
|
118
|
-
CommandDialog.displayName = "CommandDialog";
|
|
119
|
-
export { Command, CommandInput, CommandList, CommandItem, CommandGroup, CommandSeparator, CommandEmpty };
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import { cn } from "../lib/utils";
|
|
5
|
-
import { Modal } from "./Modal";
|
|
6
|
-
import { Button } from "./Button";
|
|
7
|
-
const ConfirmModal = React.forwardRef(({ isOpen, onClose, onConfirm, title, message, warning, confirmText = "확인", cancelText = "취소", confirmButtonText, type = "danger", loading = false, disabled = false, showInput = false, inputValue = "", onInputChange, inputPlaceholder, inputLabel, requiredInputValue, showCancel = true, size = "md" }, ref) => {
|
|
8
|
-
// 타입별 아이콘과 색상
|
|
9
|
-
const typeConfig = {
|
|
10
|
-
danger: {
|
|
11
|
-
icon: (_jsx("svg", { className: "h-6 w-6 text-red-600 dark:text-red-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" }) })),
|
|
12
|
-
bgColor: "bg-red-100 dark:bg-red-900/20",
|
|
13
|
-
buttonColor: "bg-red-600 hover:bg-red-700 focus:ring-red-500",
|
|
14
|
-
textColor: "text-red-600 dark:text-red-400"
|
|
15
|
-
},
|
|
16
|
-
warning: {
|
|
17
|
-
icon: (_jsx("svg", { className: "h-6 w-6 text-yellow-600 dark:text-yellow-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" }) })),
|
|
18
|
-
bgColor: "bg-yellow-100 dark:bg-yellow-900/20",
|
|
19
|
-
buttonColor: "bg-yellow-600 hover:bg-yellow-700 focus:ring-yellow-500",
|
|
20
|
-
textColor: "text-yellow-600 dark:text-yellow-400"
|
|
21
|
-
},
|
|
22
|
-
info: {
|
|
23
|
-
icon: (_jsx("svg", { className: "h-6 w-6 text-blue-600 dark:text-blue-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) })),
|
|
24
|
-
bgColor: "bg-blue-100 dark:bg-blue-900/20",
|
|
25
|
-
buttonColor: "bg-blue-600 hover:bg-blue-700 focus:ring-blue-500",
|
|
26
|
-
textColor: "text-blue-600 dark:text-blue-400"
|
|
27
|
-
},
|
|
28
|
-
success: {
|
|
29
|
-
icon: (_jsx("svg", { className: "h-6 w-6 text-green-600 dark:text-green-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) })),
|
|
30
|
-
bgColor: "bg-green-100 dark:bg-green-900/20",
|
|
31
|
-
buttonColor: "bg-green-600 hover:bg-green-700 focus:ring-green-500",
|
|
32
|
-
textColor: "text-green-600 dark:text-green-400"
|
|
33
|
-
},
|
|
34
|
-
error: {
|
|
35
|
-
icon: (_jsx("svg", { className: "h-6 w-6 text-red-600 dark:text-red-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })),
|
|
36
|
-
bgColor: "bg-red-100 dark:bg-red-900/20",
|
|
37
|
-
buttonColor: "bg-red-600 hover:bg-red-700 focus:ring-red-500",
|
|
38
|
-
textColor: "text-red-600 dark:text-red-400"
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
const config = typeConfig[type];
|
|
42
|
-
const isInputValid = !showInput || !requiredInputValue || inputValue === requiredInputValue;
|
|
43
|
-
const isDisabled = disabled || loading || !isInputValid;
|
|
44
|
-
return (_jsx(Modal, { ref: ref, isOpen: isOpen, onClose: onClose, showCloseButton: false, size: size, children: _jsxs("div", { className: "text-center", children: [_jsx("div", { className: cn("mx-auto flex items-center justify-center h-16 w-16 rounded-full mb-6", // 64px 아이콘, 24px 여백
|
|
45
|
-
config.bgColor), children: config.icon }), _jsxs("h3", { className: "text-xl font-semibold text-gray-900 dark:text-white mb-4", children: [" ", title] }), _jsxs("div", { className: "mb-6", children: [" ", _jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: message }), warning && (_jsx("p", { className: cn("text-sm mt-3 font-medium", // 12px 여백
|
|
46
|
-
config.textColor), children: warning }))] }), showInput && (_jsxs("div", { className: "mb-6", children: [" ", _jsxs("label", { htmlFor: "confirmInput", className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-3 text-left", children: [" ", inputLabel] }), _jsx("input", { type: "text", id: "confirmInput", value: inputValue, onChange: (e) => onInputChange?.(e.target.value), placeholder: inputPlaceholder, className: "w-full px-4 py-3 border border-gray-300 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-2 focus:ring-red-500 focus:border-transparent dark:bg-gray-700 dark:text-white transition-colors" // 16px, 12px 패딩
|
|
47
|
-
})] })), _jsxs("div", { className: cn("flex gap-3", // 12px 간격
|
|
48
|
-
showCancel ? "justify-center" : "justify-center"), children: [showCancel && (_jsx(Button, { variant: "outline", onClick: onClose, disabled: loading, className: "px-6 py-3" // 24px, 12px 패딩
|
|
49
|
-
, children: cancelText })), _jsx(Button, { variant: "default", onClick: onConfirm, disabled: isDisabled, className: cn("px-6 py-3", // 24px, 12px 패딩
|
|
50
|
-
config.buttonColor), children: loading ? (_jsxs("div", { className: "flex items-center", children: [_jsxs("svg", { className: "animate-spin -ml-1 mr-2 h-4 w-4 text-white", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })] }), "\uCC98\uB9AC \uC911..."] })) : (confirmButtonText || confirmText) })] })] }) }));
|
|
51
|
-
});
|
|
52
|
-
ConfirmModal.displayName = "ConfirmModal";
|
|
53
|
-
export { ConfirmModal };
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import React from "react";
|
|
4
|
-
import { cn } from "../lib/utils";
|
|
5
|
-
const Container = React.forwardRef(({ className, size = "lg", padding = "md", centered = true, fluid = false, ...props }, ref) => {
|
|
6
|
-
const sizeClasses = {
|
|
7
|
-
sm: "max-w-2xl", // 672px
|
|
8
|
-
md: "max-w-4xl", // 896px
|
|
9
|
-
lg: "max-w-6xl", // 1152px
|
|
10
|
-
xl: "max-w-7xl", // 1280px
|
|
11
|
-
full: "max-w-full"
|
|
12
|
-
};
|
|
13
|
-
const paddingClasses = {
|
|
14
|
-
none: "",
|
|
15
|
-
sm: "px-4 py-8", // 16px 좌우, 32px 상하
|
|
16
|
-
md: "px-6 py-12", // 24px 좌우, 48px 상하
|
|
17
|
-
lg: "px-8 py-16", // 32px 좌우, 64px 상하
|
|
18
|
-
xl: "px-12 py-20" // 48px 좌우, 80px 상하
|
|
19
|
-
};
|
|
20
|
-
return (_jsx("div", { ref: ref, className: cn("w-full", !fluid && sizeClasses[size], paddingClasses[padding], centered && "mx-auto", className), ...props }));
|
|
21
|
-
});
|
|
22
|
-
Container.displayName = "Container";
|
|
23
|
-
export { Container };
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import { cn } from "../lib/utils";
|
|
5
|
-
const ContextMenu = React.forwardRef(({ className, children, open: controlledOpen, onOpenChange, trigger, placement = "bottom", align = "start", offset = 8, disabled = false, ...props }, ref) => {
|
|
6
|
-
const [internalOpen, setInternalOpen] = React.useState(false);
|
|
7
|
-
const [coords, setCoords] = React.useState({ x: 0, y: 0 });
|
|
8
|
-
const triggerRef = React.useRef(null);
|
|
9
|
-
const menuRef = React.useRef(null);
|
|
10
|
-
const isControlled = controlledOpen !== undefined;
|
|
11
|
-
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
12
|
-
const handleOpenChange = (newOpen) => {
|
|
13
|
-
if (disabled)
|
|
14
|
-
return;
|
|
15
|
-
if (!isControlled) {
|
|
16
|
-
setInternalOpen(newOpen);
|
|
17
|
-
}
|
|
18
|
-
onOpenChange?.(newOpen);
|
|
19
|
-
};
|
|
20
|
-
const handleContextMenu = (event) => {
|
|
21
|
-
event.preventDefault();
|
|
22
|
-
if (disabled)
|
|
23
|
-
return;
|
|
24
|
-
const rect = event.currentTarget.getBoundingClientRect();
|
|
25
|
-
const x = event.clientX;
|
|
26
|
-
const y = event.clientY;
|
|
27
|
-
setCoords({ x, y });
|
|
28
|
-
handleOpenChange(true);
|
|
29
|
-
};
|
|
30
|
-
const updatePosition = React.useCallback(() => {
|
|
31
|
-
if (!menuRef.current)
|
|
32
|
-
return;
|
|
33
|
-
const menuRect = menuRef.current.getBoundingClientRect();
|
|
34
|
-
const viewportWidth = window.innerWidth;
|
|
35
|
-
const viewportHeight = window.innerHeight;
|
|
36
|
-
let x = coords.x;
|
|
37
|
-
let y = coords.y;
|
|
38
|
-
// 뷰포트 경계 확인 및 조정
|
|
39
|
-
if (x + menuRect.width > viewportWidth - 8) {
|
|
40
|
-
x = viewportWidth - menuRect.width - 8; // 8px 여백
|
|
41
|
-
}
|
|
42
|
-
if (y + menuRect.height > viewportHeight - 8) {
|
|
43
|
-
y = viewportHeight - menuRect.height - 8; // 8px 여백
|
|
44
|
-
}
|
|
45
|
-
if (x < 8)
|
|
46
|
-
x = 8; // 8px 여백
|
|
47
|
-
if (y < 8)
|
|
48
|
-
y = 8; // 8px 여백
|
|
49
|
-
setCoords({ x, y });
|
|
50
|
-
}, [coords.x, coords.y]);
|
|
51
|
-
React.useEffect(() => {
|
|
52
|
-
if (isOpen) {
|
|
53
|
-
updatePosition();
|
|
54
|
-
window.addEventListener('resize', updatePosition);
|
|
55
|
-
window.addEventListener('scroll', updatePosition);
|
|
56
|
-
return () => {
|
|
57
|
-
window.removeEventListener('resize', updatePosition);
|
|
58
|
-
window.removeEventListener('scroll', updatePosition);
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
}, [isOpen, updatePosition]);
|
|
62
|
-
React.useEffect(() => {
|
|
63
|
-
const handleClickOutside = (event) => {
|
|
64
|
-
if (triggerRef.current &&
|
|
65
|
-
menuRef.current &&
|
|
66
|
-
!triggerRef.current.contains(event.target) &&
|
|
67
|
-
!menuRef.current.contains(event.target)) {
|
|
68
|
-
handleOpenChange(false);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
if (isOpen) {
|
|
72
|
-
document.addEventListener('mousedown', handleClickOutside);
|
|
73
|
-
return () => {
|
|
74
|
-
document.removeEventListener('mousedown', handleClickOutside);
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
}, [isOpen]);
|
|
78
|
-
return (_jsxs("div", { ref: ref, className: cn("relative", className), ...props, children: [trigger && (_jsx("div", { ref: triggerRef, onContextMenu: handleContextMenu, className: "inline-block", children: trigger })), isOpen && (_jsx("div", { ref: menuRef, className: cn("fixed z-50 bg-white dark:bg-gray-800 rounded-lg shadow-xl backdrop-blur-sm", // 보더 대신 섀도우 사용
|
|
79
|
-
"min-w-[200px] py-2", // 16px 패딩
|
|
80
|
-
"border-0" // 보더 제거
|
|
81
|
-
), style: {
|
|
82
|
-
left: coords.x,
|
|
83
|
-
top: coords.y,
|
|
84
|
-
boxShadow: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)"
|
|
85
|
-
}, children: children }))] }));
|
|
86
|
-
});
|
|
87
|
-
ContextMenu.displayName = "ContextMenu";
|
|
88
|
-
const ContextMenuItem = React.forwardRef(({ className, icon, variant = "default", children, disabled, ...props }, ref) => {
|
|
89
|
-
const getVariantClasses = () => {
|
|
90
|
-
switch (variant) {
|
|
91
|
-
case "destructive":
|
|
92
|
-
return "text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20";
|
|
93
|
-
case "disabled":
|
|
94
|
-
return "text-gray-400 dark:text-gray-500 cursor-not-allowed";
|
|
95
|
-
default:
|
|
96
|
-
return "text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700";
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
return (_jsxs("button", { ref: ref, className: cn("w-full flex items-center gap-3 px-4 py-3 text-sm font-medium transition-colors focus:outline-none focus:bg-gray-100 dark:focus:bg-gray-700", // 16px, 12px 패딩
|
|
100
|
-
getVariantClasses(), className), disabled: disabled || variant === "disabled", ...props, children: [icon && (_jsx("div", { className: "flex-shrink-0 w-4 h-4", children: icon })), _jsx("span", { className: "flex-1 text-left", children: children })] }));
|
|
101
|
-
});
|
|
102
|
-
ContextMenuItem.displayName = "ContextMenuItem";
|
|
103
|
-
const ContextMenuSeparator = React.forwardRef(({ className, ...props }, ref) => (_jsx("div", { ref: ref, className: cn("h-px bg-gray-200 dark:bg-gray-700 my-2", className), ...props })));
|
|
104
|
-
ContextMenuSeparator.displayName = "ContextMenuSeparator";
|
|
105
|
-
const ContextMenuLabel = React.forwardRef(({ className, children, ...props }, ref) => (_jsx("div", { ref: ref, className: cn("px-4 py-2 text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide", className), ...props, children: children })));
|
|
106
|
-
ContextMenuLabel.displayName = "ContextMenuLabel";
|
|
107
|
-
// 편의 컴포넌트들
|
|
108
|
-
const ContextMenuGroup = React.forwardRef(({ className, children, ...props }, ref) => (_jsx("div", { ref: ref, className: cn("py-1", className), ...props, children: children })));
|
|
109
|
-
ContextMenuGroup.displayName = "ContextMenuGroup";
|
|
110
|
-
export { ContextMenu, ContextMenuItem, ContextMenuSeparator, ContextMenuLabel, ContextMenuGroup };
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import { cn } from "../lib/utils";
|
|
5
|
-
const Divider = React.forwardRef(({ className, orientation = "horizontal", variant = "solid", size = "md", spacing = "md", color = "default", ...props }, ref) => {
|
|
6
|
-
const orientationClasses = {
|
|
7
|
-
horizontal: "w-full",
|
|
8
|
-
vertical: "h-full w-px"
|
|
9
|
-
};
|
|
10
|
-
const sizeClasses = {
|
|
11
|
-
sm: orientation === "horizontal" ? "h-px" : "w-px",
|
|
12
|
-
md: orientation === "horizontal" ? "h-0.5" : "w-0.5", // 2px
|
|
13
|
-
lg: orientation === "horizontal" ? "h-1" : "w-1" // 4px
|
|
14
|
-
};
|
|
15
|
-
const variantClasses = {
|
|
16
|
-
solid: "",
|
|
17
|
-
dashed: "border-dashed",
|
|
18
|
-
dotted: "border-dotted",
|
|
19
|
-
gradient: orientation === "horizontal"
|
|
20
|
-
? "bg-gradient-to-r from-transparent via-gray-300 to-transparent dark:via-gray-600"
|
|
21
|
-
: "bg-gradient-to-b from-transparent via-gray-300 to-transparent dark:via-gray-600"
|
|
22
|
-
};
|
|
23
|
-
const colorClasses = {
|
|
24
|
-
default: "bg-gray-200 dark:bg-gray-700",
|
|
25
|
-
muted: "bg-gray-100 dark:bg-gray-800",
|
|
26
|
-
primary: "bg-blue-200 dark:bg-blue-700",
|
|
27
|
-
secondary: "bg-gray-300 dark:bg-gray-600"
|
|
28
|
-
};
|
|
29
|
-
const spacingClasses = {
|
|
30
|
-
none: "",
|
|
31
|
-
sm: orientation === "horizontal" ? "my-4" : "mx-4", // 16px
|
|
32
|
-
md: orientation === "horizontal" ? "my-6" : "mx-6", // 24px
|
|
33
|
-
lg: orientation === "horizontal" ? "my-8" : "mx-8", // 32px
|
|
34
|
-
xl: orientation === "horizontal" ? "my-12" : "mx-12" // 48px
|
|
35
|
-
};
|
|
36
|
-
return (_jsx("div", { ref: ref, className: cn("flex-shrink-0", orientationClasses[orientation], sizeClasses[size], variant === "gradient" ? variantClasses[variant] : colorClasses[color], variant !== "gradient" && variantClasses[variant], spacingClasses[spacing], className), ...props }));
|
|
37
|
-
});
|
|
38
|
-
Divider.displayName = "Divider";
|
|
39
|
-
export { Divider };
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import { cn } from "../lib/utils";
|
|
5
|
-
import { Icon } from "./Icon";
|
|
6
|
-
const Drawer = React.forwardRef(({ open, onOpenChange, children, className, side = "right", size = "md", showBackdrop = true, closeOnBackdropClick = true, closeOnEscape = true, ...props }, ref) => {
|
|
7
|
-
const [isVisible, setIsVisible] = React.useState(false);
|
|
8
|
-
const [isAnimating, setIsAnimating] = React.useState(false);
|
|
9
|
-
React.useEffect(() => {
|
|
10
|
-
if (open) {
|
|
11
|
-
setIsVisible(true);
|
|
12
|
-
setIsAnimating(true);
|
|
13
|
-
// 애니메이션 시작을 위한 지연
|
|
14
|
-
const timer = setTimeout(() => setIsAnimating(false), 50);
|
|
15
|
-
return () => clearTimeout(timer);
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
setIsAnimating(true);
|
|
19
|
-
const timer = setTimeout(() => {
|
|
20
|
-
setIsVisible(false);
|
|
21
|
-
setIsAnimating(false);
|
|
22
|
-
}, 300); // 애니메이션 완료 후 숨김
|
|
23
|
-
return () => clearTimeout(timer);
|
|
24
|
-
}
|
|
25
|
-
}, [open]);
|
|
26
|
-
React.useEffect(() => {
|
|
27
|
-
if (!closeOnEscape)
|
|
28
|
-
return;
|
|
29
|
-
const handleEscape = (e) => {
|
|
30
|
-
if (e.key === "Escape" && open) {
|
|
31
|
-
onOpenChange(false);
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
if (open) {
|
|
35
|
-
document.addEventListener("keydown", handleEscape);
|
|
36
|
-
document.body.style.overflow = "hidden";
|
|
37
|
-
}
|
|
38
|
-
return () => {
|
|
39
|
-
document.removeEventListener("keydown", handleEscape);
|
|
40
|
-
document.body.style.overflow = "";
|
|
41
|
-
};
|
|
42
|
-
}, [open, closeOnEscape, onOpenChange]);
|
|
43
|
-
if (!isVisible)
|
|
44
|
-
return null;
|
|
45
|
-
const sizeClasses = {
|
|
46
|
-
sm: side === "left" || side === "right" ? "w-80" : "h-64",
|
|
47
|
-
md: side === "left" || side === "right" ? "w-96" : "h-96",
|
|
48
|
-
lg: side === "left" || side === "right" ? "w-[28rem]" : "h-[32rem]",
|
|
49
|
-
xl: side === "left" || side === "right" ? "w-[32rem]" : "h-[40rem]",
|
|
50
|
-
full: side === "left" || side === "right" ? "w-full" : "h-full"
|
|
51
|
-
};
|
|
52
|
-
const sideClasses = {
|
|
53
|
-
left: "left-0 top-0 h-full translate-x-0",
|
|
54
|
-
right: "right-0 top-0 h-full translate-x-0",
|
|
55
|
-
top: "top-0 left-0 w-full translate-y-0",
|
|
56
|
-
bottom: "bottom-0 left-0 w-full translate-y-0"
|
|
57
|
-
};
|
|
58
|
-
const transformClasses = {
|
|
59
|
-
left: isAnimating ? (open ? "translate-x-0" : "-translate-x-full") : "",
|
|
60
|
-
right: isAnimating ? (open ? "translate-x-0" : "translate-x-full") : "",
|
|
61
|
-
top: isAnimating ? (open ? "translate-y-0" : "-translate-y-full") : "",
|
|
62
|
-
bottom: isAnimating ? (open ? "translate-y-0" : "translate-y-full") : ""
|
|
63
|
-
};
|
|
64
|
-
return (_jsxs("div", { className: "fixed inset-0 z-50", children: [showBackdrop && (_jsx("div", { className: cn("absolute inset-0 bg-black/50 backdrop-blur-sm transition-opacity duration-300", isAnimating ? (open ? "opacity-100" : "opacity-0") : ""), onClick: closeOnBackdropClick ? () => onOpenChange(false) : undefined })), _jsx("div", { ref: ref, className: cn("absolute bg-white/95 dark:!bg-gray-800/95 backdrop-blur-xl border border-gray-200/50 dark:!border-gray-600/50 shadow-2xl transition-transform duration-300 ease-out", sizeClasses[size], sideClasses[side], transformClasses[side], className), ...props, children: children })] }));
|
|
65
|
-
});
|
|
66
|
-
Drawer.displayName = "Drawer";
|
|
67
|
-
const DrawerHeader = React.forwardRef(({ children, className, showCloseButton = true, onClose, ...props }, ref) => {
|
|
68
|
-
return (_jsxs("div", { ref: ref, className: cn("flex items-center justify-between p-6 border-b border-gray-200/50 dark:border-gray-700/50", className), ...props, children: [_jsx("div", { className: "flex-1", children: children }), showCloseButton && (_jsx("button", { onClick: onClose, className: "p-2 rounded-lg hover:bg-gray-100/80 dark:hover:bg-gray-800/80 transition-colors", children: _jsx(Icon, { name: "x", size: 20 }) }))] }));
|
|
69
|
-
});
|
|
70
|
-
DrawerHeader.displayName = "DrawerHeader";
|
|
71
|
-
const DrawerContent = React.forwardRef(({ children, className, ...props }, ref) => {
|
|
72
|
-
return (_jsx("div", { ref: ref, className: cn("flex-1 p-6 overflow-y-auto", className), ...props, children: children }));
|
|
73
|
-
});
|
|
74
|
-
DrawerContent.displayName = "DrawerContent";
|
|
75
|
-
const DrawerFooter = React.forwardRef(({ children, className, ...props }, ref) => {
|
|
76
|
-
return (_jsx("div", { ref: ref, className: cn("flex items-center justify-end gap-3 p-6 border-t border-gray-200/50 dark:border-gray-700/50", className), ...props, children: children }));
|
|
77
|
-
});
|
|
78
|
-
DrawerFooter.displayName = "DrawerFooter";
|
|
79
|
-
export { Drawer, DrawerHeader, DrawerContent, DrawerFooter };
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import { cn } from "../lib/utils";
|
|
5
|
-
const Dropdown = React.forwardRef(({ className, trigger, children, open: controlledOpen, onOpenChange, placement = "bottom", align = "start", offset = 8, disabled = false, showArrow = true, ...props }, ref) => {
|
|
6
|
-
const [internalOpen, setInternalOpen] = React.useState(false);
|
|
7
|
-
const [coords, setCoords] = React.useState({ x: 0, y: 0 });
|
|
8
|
-
const triggerRef = React.useRef(null);
|
|
9
|
-
const dropdownRef = React.useRef(null);
|
|
10
|
-
const isControlled = controlledOpen !== undefined;
|
|
11
|
-
const isOpen = isControlled ? controlledOpen : internalOpen;
|
|
12
|
-
const handleOpenChange = (newOpen) => {
|
|
13
|
-
if (disabled)
|
|
14
|
-
return;
|
|
15
|
-
if (!isControlled) {
|
|
16
|
-
setInternalOpen(newOpen);
|
|
17
|
-
}
|
|
18
|
-
onOpenChange?.(newOpen);
|
|
19
|
-
};
|
|
20
|
-
const handleTriggerClick = () => {
|
|
21
|
-
handleOpenChange(!isOpen);
|
|
22
|
-
};
|
|
23
|
-
const updatePosition = React.useCallback(() => {
|
|
24
|
-
if (!triggerRef.current || !dropdownRef.current)
|
|
25
|
-
return;
|
|
26
|
-
const triggerRect = triggerRef.current.getBoundingClientRect();
|
|
27
|
-
const dropdownRect = dropdownRef.current.getBoundingClientRect();
|
|
28
|
-
const viewportWidth = window.innerWidth;
|
|
29
|
-
const viewportHeight = window.innerHeight;
|
|
30
|
-
let x = 0;
|
|
31
|
-
let y = 0;
|
|
32
|
-
// 기본 위치 계산
|
|
33
|
-
switch (placement) {
|
|
34
|
-
case "top":
|
|
35
|
-
x = triggerRect.left;
|
|
36
|
-
y = triggerRect.top - offset;
|
|
37
|
-
break;
|
|
38
|
-
case "bottom":
|
|
39
|
-
x = triggerRect.left;
|
|
40
|
-
y = triggerRect.bottom + offset;
|
|
41
|
-
break;
|
|
42
|
-
case "left":
|
|
43
|
-
x = triggerRect.left - offset;
|
|
44
|
-
y = triggerRect.top;
|
|
45
|
-
break;
|
|
46
|
-
case "right":
|
|
47
|
-
x = triggerRect.right + offset;
|
|
48
|
-
y = triggerRect.top;
|
|
49
|
-
break;
|
|
50
|
-
}
|
|
51
|
-
// 정렬 조정
|
|
52
|
-
switch (align) {
|
|
53
|
-
case "center":
|
|
54
|
-
if (placement === "top" || placement === "bottom") {
|
|
55
|
-
x = triggerRect.left + triggerRect.width / 2 - dropdownRect.width / 2;
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
y = triggerRect.top + triggerRect.height / 2 - dropdownRect.height / 2;
|
|
59
|
-
}
|
|
60
|
-
break;
|
|
61
|
-
case "end":
|
|
62
|
-
if (placement === "top" || placement === "bottom") {
|
|
63
|
-
x = triggerRect.right - dropdownRect.width;
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
y = triggerRect.bottom - dropdownRect.height;
|
|
67
|
-
}
|
|
68
|
-
break;
|
|
69
|
-
case "start":
|
|
70
|
-
default:
|
|
71
|
-
// 기본값은 이미 start 정렬
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
// 뷰포트 경계 확인 및 조정
|
|
75
|
-
if (x < 8)
|
|
76
|
-
x = 8; // 8px 여백
|
|
77
|
-
if (x + dropdownRect.width > viewportWidth - 8) {
|
|
78
|
-
x = viewportWidth - dropdownRect.width - 8; // 8px 여백
|
|
79
|
-
}
|
|
80
|
-
if (y < 8)
|
|
81
|
-
y = 8; // 8px 여백
|
|
82
|
-
if (y + dropdownRect.height > viewportHeight - 8) {
|
|
83
|
-
y = viewportHeight - dropdownRect.height - 8; // 8px 여백
|
|
84
|
-
}
|
|
85
|
-
setCoords({ x, y });
|
|
86
|
-
}, [placement, align, offset]);
|
|
87
|
-
React.useEffect(() => {
|
|
88
|
-
if (isOpen) {
|
|
89
|
-
updatePosition();
|
|
90
|
-
window.addEventListener('resize', updatePosition);
|
|
91
|
-
window.addEventListener('scroll', updatePosition);
|
|
92
|
-
return () => {
|
|
93
|
-
window.removeEventListener('resize', updatePosition);
|
|
94
|
-
window.removeEventListener('scroll', updatePosition);
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
}, [isOpen, updatePosition]);
|
|
98
|
-
React.useEffect(() => {
|
|
99
|
-
const handleClickOutside = (event) => {
|
|
100
|
-
if (triggerRef.current &&
|
|
101
|
-
dropdownRef.current &&
|
|
102
|
-
!triggerRef.current.contains(event.target) &&
|
|
103
|
-
!dropdownRef.current.contains(event.target)) {
|
|
104
|
-
handleOpenChange(false);
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
if (isOpen) {
|
|
108
|
-
document.addEventListener('mousedown', handleClickOutside);
|
|
109
|
-
return () => {
|
|
110
|
-
document.removeEventListener('mousedown', handleClickOutside);
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
}, [isOpen]);
|
|
114
|
-
const getPlacementClasses = () => {
|
|
115
|
-
switch (placement) {
|
|
116
|
-
case "top":
|
|
117
|
-
return "bottom-full left-0 mb-2"; // 8px 간격
|
|
118
|
-
case "bottom":
|
|
119
|
-
return "top-full left-0 mt-2"; // 8px 간격
|
|
120
|
-
case "left":
|
|
121
|
-
return "right-full top-0 mr-2"; // 8px 간격
|
|
122
|
-
case "right":
|
|
123
|
-
return "left-full top-0 ml-2"; // 8px 간격
|
|
124
|
-
default:
|
|
125
|
-
return "top-full left-0 mt-2";
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
const getArrowClasses = () => {
|
|
129
|
-
switch (placement) {
|
|
130
|
-
case "top":
|
|
131
|
-
return "top-full left-4 -translate-x-1/2 border-t-gray-100 dark:border-t-gray-800";
|
|
132
|
-
case "bottom":
|
|
133
|
-
return "bottom-full left-4 -translate-x-1/2 border-b-gray-100 dark:border-b-gray-800";
|
|
134
|
-
case "left":
|
|
135
|
-
return "left-full top-4 -translate-y-1/2 border-l-gray-100 dark:border-l-gray-800";
|
|
136
|
-
case "right":
|
|
137
|
-
return "right-full top-4 -translate-y-1/2 border-r-gray-100 dark:border-r-gray-800";
|
|
138
|
-
default:
|
|
139
|
-
return "bottom-full left-4 -translate-x-1/2 border-b-gray-100 dark:border-b-gray-800";
|
|
140
|
-
}
|
|
141
|
-
};
|
|
142
|
-
return (_jsxs("div", { ref: ref, className: cn("relative", className), ...props, children: [_jsx("div", { ref: triggerRef, onClick: handleTriggerClick, className: "inline-block cursor-pointer", children: trigger }), isOpen && (_jsxs("div", { ref: dropdownRef, className: cn("absolute z-50 bg-white dark:bg-gray-800 rounded-lg shadow-xl backdrop-blur-sm", // 보더 대신 섀도우 사용
|
|
143
|
-
"min-w-[200px] py-2", // 16px 패딩
|
|
144
|
-
getPlacementClasses()), style: {
|
|
145
|
-
transform: `translate(${coords.x}px, ${coords.y}px)`,
|
|
146
|
-
boxShadow: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)"
|
|
147
|
-
}, children: [showArrow && (_jsx("div", { className: cn("absolute w-0 h-0 border-4 border-transparent", getArrowClasses()) })), _jsx("div", { className: "relative z-10", children: children })] }))] }));
|
|
148
|
-
});
|
|
149
|
-
Dropdown.displayName = "Dropdown";
|
|
150
|
-
const DropdownItem = React.forwardRef(({ className, icon, variant = "default", children, disabled, ...props }, ref) => {
|
|
151
|
-
const getVariantClasses = () => {
|
|
152
|
-
switch (variant) {
|
|
153
|
-
case "destructive":
|
|
154
|
-
return "text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20";
|
|
155
|
-
case "disabled":
|
|
156
|
-
return "text-gray-400 dark:text-gray-500 cursor-not-allowed";
|
|
157
|
-
default:
|
|
158
|
-
return "text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700";
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
return (_jsxs("button", { ref: ref, className: cn("w-full flex items-center gap-3 px-4 py-3 text-sm font-medium transition-colors focus:outline-none focus:bg-gray-100 dark:focus:bg-gray-700", // 16px, 12px 패딩
|
|
162
|
-
getVariantClasses(), className), disabled: disabled || variant === "disabled", ...props, children: [icon && (_jsx("div", { className: "flex-shrink-0 w-4 h-4", children: icon })), _jsx("span", { className: "flex-1 text-left", children: children })] }));
|
|
163
|
-
});
|
|
164
|
-
DropdownItem.displayName = "DropdownItem";
|
|
165
|
-
const DropdownSeparator = React.forwardRef(({ className, ...props }, ref) => (_jsx("div", { ref: ref, className: cn("h-px bg-gray-200 dark:bg-gray-700 my-2", className), ...props })));
|
|
166
|
-
DropdownSeparator.displayName = "DropdownSeparator";
|
|
167
|
-
const DropdownLabel = React.forwardRef(({ className, children, ...props }, ref) => (_jsx("div", { ref: ref, className: cn("px-4 py-2 text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide", className), ...props, children: children })));
|
|
168
|
-
DropdownLabel.displayName = "DropdownLabel";
|
|
169
|
-
// 편의 컴포넌트들
|
|
170
|
-
const DropdownMenu = React.forwardRef(({ className, children, ...props }, ref) => (_jsx("div", { ref: ref, className: cn("py-1", className), ...props, children: children })));
|
|
171
|
-
DropdownMenu.displayName = "DropdownMenu";
|
|
172
|
-
const DropdownGroup = React.forwardRef(({ className, children, ...props }, ref) => (_jsx("div", { ref: ref, className: cn("space-y-1", className), ...props, children: children })));
|
|
173
|
-
DropdownGroup.displayName = "DropdownGroup";
|
|
174
|
-
export { Dropdown, DropdownItem, DropdownSeparator, DropdownLabel, DropdownMenu, DropdownGroup };
|