@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
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Toast 메시지 타입 / Toast message type
|
|
6
|
+
* @typedef {Object} Toast
|
|
7
|
+
* @property {string} id - Toast 고유 ID / Toast unique ID
|
|
8
|
+
* @property {"success" | "error" | "warning" | "info"} type - Toast 타입 / Toast type
|
|
9
|
+
* @property {string} [title] - Toast 제목 / Toast title
|
|
10
|
+
* @property {string} message - Toast 메시지 / Toast message
|
|
11
|
+
* @property {number} [duration] - 표시 시간(ms), 0이면 자동 제거 안 함 / Display duration (ms), 0 means no auto-remove
|
|
12
|
+
* @property {Object} [action] - 액션 버튼 / Action button
|
|
13
|
+
* @property {string} action.label - 액션 버튼 레이블 / Action button label
|
|
14
|
+
* @property {() => void} action.onClick - 액션 버튼 클릭 핸들러 / Action button click handler
|
|
15
|
+
*/
|
|
16
|
+
interface Toast {
|
|
17
|
+
id: string;
|
|
18
|
+
type: "success" | "error" | "warning" | "info";
|
|
19
|
+
title?: string;
|
|
20
|
+
message: string;
|
|
21
|
+
duration?: number;
|
|
22
|
+
action?: {
|
|
23
|
+
label: string;
|
|
24
|
+
onClick: () => void;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
interface ToastContextType {
|
|
28
|
+
toasts: Toast[];
|
|
29
|
+
addToast: (toast: Omit<Toast, "id">) => void;
|
|
30
|
+
removeToast: (id: string) => void;
|
|
31
|
+
clearToasts: () => void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* useToast Hook
|
|
35
|
+
*
|
|
36
|
+
* Toast를 추가, 제거, 초기화하는 훅입니다.
|
|
37
|
+
* ToastProvider 내부에서만 사용 가능합니다.
|
|
38
|
+
*
|
|
39
|
+
* Hook for adding, removing, and clearing toasts.
|
|
40
|
+
* Can only be used within ToastProvider.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* const { addToast, removeToast, clearToasts } = useToast()
|
|
44
|
+
*
|
|
45
|
+
* addToast({
|
|
46
|
+
* type: "success",
|
|
47
|
+
* message: "저장되었습니다",
|
|
48
|
+
* duration: 3000
|
|
49
|
+
* })
|
|
50
|
+
*
|
|
51
|
+
* @returns {ToastContextType} Toast 컨텍스트 값 / Toast context value
|
|
52
|
+
* @throws {Error} ToastProvider 외부에서 사용 시 에러 발생 / Error when used outside ToastProvider
|
|
53
|
+
*/
|
|
54
|
+
declare function useToast(): ToastContextType;
|
|
55
|
+
/**
|
|
56
|
+
* ToastProvider 컴포넌트의 props / ToastProvider component props
|
|
57
|
+
* @typedef {Object} ToastProviderProps
|
|
58
|
+
* @property {React.ReactNode} children - 자식 컴포넌트 / Child components
|
|
59
|
+
* @property {number} [maxToasts=5] - 최대 Toast 개수 / Maximum number of toasts
|
|
60
|
+
* @property {"top-right" | "top-left" | "bottom-right" | "bottom-left" | "top-center" | "bottom-center"} [position="top-right"] - Toast 표시 위치 / Toast display position
|
|
61
|
+
*/
|
|
62
|
+
interface ToastProviderProps {
|
|
63
|
+
children: React.ReactNode;
|
|
64
|
+
maxToasts?: number;
|
|
65
|
+
position?: "top-right" | "top-left" | "bottom-right" | "bottom-left" | "top-center" | "bottom-center";
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* ToastProvider 컴포넌트 / ToastProvider component
|
|
69
|
+
*
|
|
70
|
+
* Toast 시스템의 컨텍스트를 제공하는 Provider 컴포넌트입니다.
|
|
71
|
+
* 앱의 루트 레벨에서 사용하여 전역 Toast 기능을 활성화합니다.
|
|
72
|
+
*
|
|
73
|
+
* Provider component that provides context for the Toast system.
|
|
74
|
+
* Use at the root level of your app to enable global Toast functionality.
|
|
75
|
+
*
|
|
76
|
+
* @component
|
|
77
|
+
* @example
|
|
78
|
+
* // App.tsx
|
|
79
|
+
* <ToastProvider position="top-center" maxToasts={3}>
|
|
80
|
+
* <App />
|
|
81
|
+
* </ToastProvider>
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* // 컴포넌트에서 사용 / Usage in component
|
|
85
|
+
* const { addToast } = useToast()
|
|
86
|
+
*
|
|
87
|
+
* const handleSave = () => {
|
|
88
|
+
* addToast({
|
|
89
|
+
* type: "success",
|
|
90
|
+
* message: "저장되었습니다",
|
|
91
|
+
* title: "성공"
|
|
92
|
+
* })
|
|
93
|
+
* }
|
|
94
|
+
*
|
|
95
|
+
* @param {ToastProviderProps} props - ToastProvider 컴포넌트의 props / ToastProvider component props
|
|
96
|
+
* @returns {JSX.Element} ToastProvider 컴포넌트 / ToastProvider component
|
|
97
|
+
*
|
|
98
|
+
* @todo 접근성 개선: ToastItem에 role="alert" 또는 role="status" 추가 필요 / Accessibility: Add role="alert" or role="status" to ToastItem
|
|
99
|
+
* @todo 접근성 개선: aria-live="polite" 또는 aria-live="assertive" 추가 필요 / Accessibility: Add aria-live="polite" or aria-live="assertive"
|
|
100
|
+
*/
|
|
101
|
+
declare function ToastProvider({ children, maxToasts, position }: ToastProviderProps): react_jsx_runtime.JSX.Element;
|
|
102
|
+
|
|
103
|
+
export { type Toast, ToastProvider, useToast };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feedback Components Entrypoint
|
|
3
|
+
*
|
|
4
|
+
* 피드백 관련 컴포넌트들을 모아서 export하는 엔트리 포인트입니다.
|
|
5
|
+
* 글로벌 상태 관리가 필요한 Toast 컴포넌트만 포함합니다.
|
|
6
|
+
*
|
|
7
|
+
* Entry point that aggregates feedback-related components.
|
|
8
|
+
* Includes Toast component that requires global state management.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* // Toast 컴포넌트만 import / Import only Toast components
|
|
12
|
+
* import { ToastProvider, useToast } from '@hua-labs/ui/feedback';
|
|
13
|
+
* import '@hua-labs/ui/styles/toast.css';
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // Core에서도 여전히 사용 가능 (하위 호환성) / Still available from core (backward compatibility)
|
|
17
|
+
* import { ToastProvider, useToast } from '@hua-labs/ui';
|
|
18
|
+
*/
|
|
19
|
+
export { ToastProvider, useToast } from './components/Toast';
|
|
20
|
+
export type { Toast } from './components/Toast';
|
|
21
|
+
//# sourceMappingURL=feedback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC7D,YAAY,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/feedback.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var k=require('react'),clsx=require('clsx'),tailwindMerge=require('tailwind-merge'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var k__default=/*#__PURE__*/_interopDefault(k);function d(...t){return tailwindMerge.twMerge(clsx.clsx(t))}var b=k.createContext(void 0);function y(){let t=k.useContext(b);if(!t)throw new Error("useToast must be used within a ToastProvider");return t}function C({children:t,maxToasts:n=5,position:a="top-right"}){let[s,r]=k.useState([]),i=k.useCallback(o=>{r(u=>u.filter(g=>g.id!==o));},[]),c=k.useCallback(o=>{let u=Math.random().toString(36).substr(2,9),g={...o,id:u};r(x=>[...x,g].slice(-n)),o.duration!==0&&setTimeout(()=>{i(u);},o.duration||5e3);},[n,i]),m=k.useCallback(()=>{r([]);},[]);return jsxRuntime.jsxs(b.Provider,{value:{toasts:s,addToast:c,removeToast:i,clearToasts:m},children:[t,jsxRuntime.jsx(L,{toasts:s,removeToast:i,position:a})]})}function L({toasts:t,removeToast:n,position:a}){let s={"top-right":"top-4 right-4","top-left":"top-4 left-4","bottom-right":"bottom-4 right-4","bottom-left":"bottom-4 left-4","top-center":"top-4 left-1/2 transform -translate-x-1/2","bottom-center":"bottom-4 left-1/2 transform -translate-x-1/2"};return t.length===0?null:jsxRuntime.jsx("div",{className:d("fixed z-50 space-y-3 max-w-sm",s[a]),children:t.map(r=>jsxRuntime.jsx(N,{toast:r,onRemove:n},r.id))})}function N({toast:t,onRemove:n}){let[a,s]=k.useState(false);k__default.default.useEffect(()=>{s(true);},[]);let r=()=>{s(false),setTimeout(()=>n(t.id),300);},i=o=>{switch(o){case "success":return "bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800 text-green-800 dark:text-green-200";case "error":return "bg-red-50 dark:bg-red-900/20 border-red-200 dark:border-red-800 text-red-800 dark:text-red-200";case "warning":return "bg-yellow-50 dark:bg-yellow-900/20 border-yellow-200 dark:border-yellow-800 text-yellow-800 dark:text-yellow-200";case "info":return "bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800 text-blue-800 dark:text-blue-200"}},c=o=>{switch(o){case "success":return "text-green-500 dark:text-green-400";case "error":return "text-red-500 dark:text-red-400";case "warning":return "text-yellow-500 dark:text-yellow-400";case "info":return "text-blue-500 dark:text-blue-400"}},m=o=>{switch(o){case "success":return jsxRuntime.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsxRuntime.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M5 13l4 4L19 7"})});case "error":return jsxRuntime.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsxRuntime.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})});case "warning":return jsxRuntime.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsxRuntime.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"})});case "info":return jsxRuntime.jsx("svg",{className:"w-5 h-5",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsxRuntime.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"})})}};return jsxRuntime.jsxs("div",{className:d("flex items-start p-4 rounded-xl border shadow-lg backdrop-blur-sm transition-all duration-300 transform",i(t.type),a?"translate-x-0 opacity-100 scale-100":"translate-x-full opacity-0 scale-95"),style:{animation:a?"slideInRight 0.3s cubic-bezier(0.16, 1, 0.3, 1)":void 0},children:[jsxRuntime.jsxs("div",{className:d("flex-shrink-0 mr-3",c(t.type)),children:[" ",m(t.type)]}),jsxRuntime.jsxs("div",{className:"flex-1 min-w-0",children:[t.title&&jsxRuntime.jsxs("h4",{className:"text-sm font-semibold mb-1",children:[" ",t.title]}),jsxRuntime.jsx("p",{className:"text-sm leading-relaxed",children:t.message}),t.action&&jsxRuntime.jsx("button",{onClick:t.action.onClick,className:"mt-3 text-sm font-medium underline hover:no-underline transition-all duration-200",children:t.action.label})]}),jsxRuntime.jsxs("div",{className:"flex-shrink-0 ml-4",children:[" ",jsxRuntime.jsx("button",{onClick:r,className:d("inline-flex rounded-md p-1.5 focus:outline-none focus:ring-2 focus:ring-offset-2 transition-all duration-200 hover:bg-black/5 dark:hover:bg-white/5",c(t.type)),"aria-label":"\uB2EB\uAE30",children:jsxRuntime.jsx("svg",{className:"w-4 h-4",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:jsxRuntime.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]})]})}exports.ToastProvider=C;exports.useToast=y;//# sourceMappingURL=feedback.js.map
|
|
2
|
+
//# sourceMappingURL=feedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/components/Toast.tsx"],"names":["merge","inputs","twMerge","clsx","ToastContext","createContext","useToast","context","useContext","ToastProvider","children","maxToasts","position","toasts","setToasts","useState","removeToast","useCallback","id","prev","toast","addToast","newToast","clearToasts","jsxs","jsx","ToastContainer","positionClasses","ToastItem","onRemove","isVisible","setIsVisible","React","handleRemove","getToastStyles","type","getIconStyles","getToastIcon"],"mappings":"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","file":"feedback.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\n/**\n * HUA UI의 스마트 클래스 병합 유틸리티\n * clsx와 tailwind-merge를 결합하여 중복 클래스를 자동으로 해결합니다.\n * \n * @param inputs - 병합할 클래스 값들\n * @returns 병합된 클래스 문자열\n * \n * @example\n * ```tsx\n * merge(\"px-2 py-1\", \"px-4\") // \"py-1 px-4\"\n * merge(\"text-red-500\", \"text-blue-500\") // \"text-blue-500\"\n * merge(\"bg-white\", \"dark:bg-slate-900\") // \"bg-white dark:bg-slate-900\"\n * ```\n */\nexport function merge(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n\n/**\n * 조건부 클래스 병합 유틸리티\n * 조건에 따라 클래스를 선택적으로 병합합니다.\n * \n * @param condition - 클래스를 적용할 조건\n * @param trueClass - 조건이 true일 때 적용할 클래스\n * @param falseClass - 조건이 false일 때 적용할 클래스 (선택사항)\n * @returns 병합된 클래스 문자열\n * \n * @example\n * ```tsx\n * mergeIf(isActive, \"bg-blue-500\", \"bg-gray-200\")\n * mergeIf(isLoading, \"opacity-50 cursor-not-allowed\")\n * ```\n */\nexport function mergeIf(\n condition: boolean,\n trueClass: ClassValue,\n falseClass?: ClassValue\n) {\n return merge(condition ? trueClass : falseClass || \"\")\n}\n\n/**\n * 상대 시간 포맷팅 유틸리티\n * \n * 날짜를 상대 시간 형식으로 포맷팅합니다 (예: \"방금 전\", \"5분 전\", \"2시간 전\", \"3일 전\").\n * 7일 이상 경과한 경우 절대 날짜를 반환합니다.\n * \n * Formats a date as relative time (e.g., \"방금 전\", \"5분 전\", \"2시간 전\", \"3일 전\").\n * Returns absolute date for dates older than 7 days.\n * \n * @param timestamp - 포맷팅할 날짜 (Date 객체 또는 ISO 문자열) / Date to format (Date object or ISO string)\n * @param locale - 로케일 (기본값: \"ko-KR\") / Locale (default: \"ko-KR\")\n * @returns 포맷팅된 상대 시간 문자열 / Formatted relative time string\n * \n * @example\n * ```tsx\n * formatRelativeTime(new Date()) // \"방금 전\"\n * formatRelativeTime(new Date(Date.now() - 5 * 60000)) // \"5분 전\"\n * formatRelativeTime(new Date(Date.now() - 2 * 3600000)) // \"2시간 전\"\n * formatRelativeTime(new Date(Date.now() - 3 * 86400000)) // \"3일 전\"\n * formatRelativeTime(new Date(\"2024-01-01\")) // \"2024. 1. 1.\" (7일 이상 경과)\n * ```\n */\nexport function formatRelativeTime(timestamp: Date | string, locale = \"ko-KR\"): string {\n const date = typeof timestamp === \"string\" ? new Date(timestamp) : timestamp;\n const now = new Date();\n const diff = now.getTime() - date.getTime();\n const minutes = Math.floor(diff / 60000);\n const hours = Math.floor(diff / 3600000);\n const days = Math.floor(diff / 86400000);\n\n if (minutes < 1) return locale === \"ko-KR\" ? \"방금 전\" : \"just now\";\n if (minutes < 60) return locale === \"ko-KR\" ? `${minutes}분 전` : `${minutes}m ago`;\n if (hours < 24) return locale === \"ko-KR\" ? `${hours}시간 전` : `${hours}h ago`;\n if (days < 7) return locale === \"ko-KR\" ? `${days}일 전` : `${days}d ago`;\n return date.toLocaleDateString(locale);\n}\n\n/**\n * 객체 기반 클래스 병합 유틸리티\n * 객체의 키-값 쌍을 기반으로 조건부 클래스를 병합합니다.\n * \n * @param classMap - 클래스 맵 객체\n * @returns 병합된 클래스 문자열\n * \n * @example\n * ```tsx\n * mergeMap({\n * \"bg-blue-500\": isPrimary,\n * \"bg-gray-500\": !isPrimary,\n * \"text-white\": true,\n * \"opacity-50\": isDisabled\n * })\n * ```\n */\nexport function mergeMap(classMap: Record<string, boolean | undefined | null>) {\n const classes = Object.entries(classMap)\n .filter(([, condition]) => condition)\n .map(([className]) => className)\n \n return merge(...classes)\n}\n\n// 하위 호환성을 위해 cn도 export (점진적 마이그레이션 지원)\nexport const cn = merge ","\"use client\"\n\nimport React from \"react\"\nimport { createContext, useContext, useState, useCallback } from \"react\"\nimport { merge } from \"../lib/utils\"\n\n/**\n * Toast 메시지 타입 / Toast message type\n * @typedef {Object} Toast\n * @property {string} id - Toast 고유 ID / Toast unique ID\n * @property {\"success\" | \"error\" | \"warning\" | \"info\"} type - Toast 타입 / Toast type\n * @property {string} [title] - Toast 제목 / Toast title\n * @property {string} message - Toast 메시지 / Toast message\n * @property {number} [duration] - 표시 시간(ms), 0이면 자동 제거 안 함 / Display duration (ms), 0 means no auto-remove\n * @property {Object} [action] - 액션 버튼 / Action button\n * @property {string} action.label - 액션 버튼 레이블 / Action button label\n * @property {() => void} action.onClick - 액션 버튼 클릭 핸들러 / Action button click handler\n */\nexport interface Toast {\n id: string\n type: \"success\" | \"error\" | \"warning\" | \"info\"\n title?: string\n message: string\n duration?: number\n action?: {\n label: string\n onClick: () => void\n }\n}\n\n// Toast Context 타입\ninterface ToastContextType {\n toasts: Toast[]\n addToast: (toast: Omit<Toast, \"id\">) => void\n removeToast: (id: string) => void\n clearToasts: () => void\n}\n\n// Toast Context 생성\nconst ToastContext = createContext<ToastContextType | undefined>(undefined)\n\n/**\n * useToast Hook\n * \n * Toast를 추가, 제거, 초기화하는 훅입니다.\n * ToastProvider 내부에서만 사용 가능합니다.\n * \n * Hook for adding, removing, and clearing toasts.\n * Can only be used within ToastProvider.\n * \n * @example\n * const { addToast, removeToast, clearToasts } = useToast()\n * \n * addToast({\n * type: \"success\",\n * message: \"저장되었습니다\",\n * duration: 3000\n * })\n * \n * @returns {ToastContextType} Toast 컨텍스트 값 / Toast context value\n * @throws {Error} ToastProvider 외부에서 사용 시 에러 발생 / Error when used outside ToastProvider\n */\nexport function useToast(): ToastContextType {\n const context = useContext(ToastContext)\n if (!context) {\n throw new Error(\"useToast must be used within a ToastProvider\")\n }\n return context\n}\n\n/**\n * ToastProvider 컴포넌트의 props / ToastProvider component props\n * @typedef {Object} ToastProviderProps\n * @property {React.ReactNode} children - 자식 컴포넌트 / Child components\n * @property {number} [maxToasts=5] - 최대 Toast 개수 / Maximum number of toasts\n * @property {\"top-right\" | \"top-left\" | \"bottom-right\" | \"bottom-left\" | \"top-center\" | \"bottom-center\"} [position=\"top-right\"] - Toast 표시 위치 / Toast display position\n */\ninterface ToastProviderProps {\n children: React.ReactNode\n maxToasts?: number\n position?: \"top-right\" | \"top-left\" | \"bottom-right\" | \"bottom-left\" | \"top-center\" | \"bottom-center\"\n}\n\n/**\n * ToastProvider 컴포넌트 / ToastProvider component\n * \n * Toast 시스템의 컨텍스트를 제공하는 Provider 컴포넌트입니다.\n * 앱의 루트 레벨에서 사용하여 전역 Toast 기능을 활성화합니다.\n * \n * Provider component that provides context for the Toast system.\n * Use at the root level of your app to enable global Toast functionality.\n * \n * @component\n * @example\n * // App.tsx\n * <ToastProvider position=\"top-center\" maxToasts={3}>\n * <App />\n * </ToastProvider>\n * \n * @example\n * // 컴포넌트에서 사용 / Usage in component\n * const { addToast } = useToast()\n * \n * const handleSave = () => {\n * addToast({\n * type: \"success\",\n * message: \"저장되었습니다\",\n * title: \"성공\"\n * })\n * }\n * \n * @param {ToastProviderProps} props - ToastProvider 컴포넌트의 props / ToastProvider component props\n * @returns {JSX.Element} ToastProvider 컴포넌트 / ToastProvider component\n * \n * @todo 접근성 개선: ToastItem에 role=\"alert\" 또는 role=\"status\" 추가 필요 / Accessibility: Add role=\"alert\" or role=\"status\" to ToastItem\n * @todo 접근성 개선: aria-live=\"polite\" 또는 aria-live=\"assertive\" 추가 필요 / Accessibility: Add aria-live=\"polite\" or aria-live=\"assertive\"\n */\nexport function ToastProvider({\n children,\n maxToasts = 5,\n position = \"top-right\"\n}: ToastProviderProps) {\n const [toasts, setToasts] = useState<Toast[]>([])\n\n const removeToast = useCallback((id: string) => {\n setToasts(prev => prev.filter(toast => toast.id !== id))\n }, [])\n\n const addToast = useCallback((toast: Omit<Toast, \"id\">) => {\n const id = Math.random().toString(36).substr(2, 9)\n const newToast: Toast = { ...toast, id }\n\n setToasts(prev => {\n const updatedToasts = [...prev, newToast]\n return updatedToasts.slice(-maxToasts) // 최대 개수 제한\n })\n\n // 자동 제거\n if (toast.duration !== 0) {\n setTimeout(() => {\n removeToast(id)\n }, toast.duration || 5000)\n }\n }, [maxToasts, removeToast])\n\n const clearToasts = useCallback(() => {\n setToasts([])\n }, [])\n\n return (\n <ToastContext.Provider value={{ toasts, addToast, removeToast, clearToasts }}>\n {children}\n <ToastContainer toasts={toasts} removeToast={removeToast} position={position} />\n </ToastContext.Provider>\n )\n}\n\n// Toast Container Props\ninterface ToastContainerProps {\n toasts: Toast[]\n removeToast: (id: string) => void\n position: string\n}\n\n// Toast Container\nfunction ToastContainer({ toasts, removeToast, position }: ToastContainerProps) {\n const positionClasses = {\n \"top-right\": \"top-4 right-4\",\n \"top-left\": \"top-4 left-4\",\n \"bottom-right\": \"bottom-4 right-4\",\n \"bottom-left\": \"bottom-4 left-4\",\n \"top-center\": \"top-4 left-1/2 transform -translate-x-1/2\",\n \"bottom-center\": \"bottom-4 left-1/2 transform -translate-x-1/2\"\n }\n\n if (toasts.length === 0) return null\n\n return (\n <div className={merge(\n \"fixed z-50 space-y-3 max-w-sm\", // 12px 간격\n positionClasses[position as keyof typeof positionClasses]\n )}>\n {toasts.map((toast) => (\n <ToastItem key={toast.id} toast={toast} onRemove={removeToast} />\n ))}\n </div>\n )\n}\n\n// Toast Item Props\ninterface ToastItemProps {\n toast: Toast\n onRemove: (id: string) => void\n}\n\n// Toast Item\nfunction ToastItem({ toast, onRemove }: ToastItemProps) {\n const [isVisible, setIsVisible] = useState(false)\n\n React.useEffect(() => {\n setIsVisible(true)\n }, [])\n\n const handleRemove = () => {\n setIsVisible(false)\n setTimeout(() => onRemove(toast.id), 300)\n }\n\n const getToastStyles = (type: Toast[\"type\"]) => {\n switch (type) {\n case \"success\":\n return \"bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800 text-green-800 dark:text-green-200\"\n case \"error\":\n return \"bg-red-50 dark:bg-red-900/20 border-red-200 dark:border-red-800 text-red-800 dark:text-red-200\"\n case \"warning\":\n return \"bg-yellow-50 dark:bg-yellow-900/20 border-yellow-200 dark:border-yellow-800 text-yellow-800 dark:text-yellow-200\"\n case \"info\":\n return \"bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800 text-blue-800 dark:text-blue-200\"\n }\n }\n\n const getIconStyles = (type: Toast[\"type\"]) => {\n switch (type) {\n case \"success\":\n return \"text-green-500 dark:text-green-400\"\n case \"error\":\n return \"text-red-500 dark:text-red-400\"\n case \"warning\":\n return \"text-yellow-500 dark:text-yellow-400\"\n case \"info\":\n return \"text-blue-500 dark:text-blue-400\"\n }\n }\n\n const getToastIcon = (type: Toast[\"type\"]) => {\n switch (type) {\n case \"success\":\n return (\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n </svg>\n )\n case \"error\":\n return (\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n )\n case \"warning\":\n return (\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n )\n case \"info\":\n return (\n <svg className=\"w-5 h-5\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <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\" />\n </svg>\n )\n }\n }\n\n return (\n <div\n className={merge(\n \"flex items-start p-4 rounded-xl border shadow-lg backdrop-blur-sm transition-all duration-300 transform\",\n getToastStyles(toast.type),\n isVisible\n ? \"translate-x-0 opacity-100 scale-100\"\n : \"translate-x-full opacity-0 scale-95\"\n )}\n style={{\n animation: isVisible ? \"slideInRight 0.3s cubic-bezier(0.16, 1, 0.3, 1)\" : undefined\n }}\n >\n {/* 아이콘 */}\n <div className={merge(\"flex-shrink-0 mr-3\", getIconStyles(toast.type))}> {/* 12px 여백 */}\n {getToastIcon(toast.type)}\n </div>\n\n {/* 내용 */}\n <div className=\"flex-1 min-w-0\">\n {toast.title && (\n <h4 className=\"text-sm font-semibold mb-1\"> {/* 4px 여백 */}\n {toast.title}\n </h4>\n )}\n <p className=\"text-sm leading-relaxed\">\n {toast.message}\n </p>\n\n {/* 액션 버튼 */}\n {toast.action && (\n <button\n onClick={toast.action.onClick}\n className=\"mt-3 text-sm font-medium underline hover:no-underline transition-all duration-200\" // 12px 여백\n >\n {toast.action.label}\n </button>\n )}\n </div>\n\n {/* 닫기 버튼 */}\n <div className=\"flex-shrink-0 ml-4\"> {/* 16px 여백 */}\n <button\n onClick={handleRemove}\n className={merge(\n \"inline-flex rounded-md p-1.5 focus:outline-none focus:ring-2 focus:ring-offset-2 transition-all duration-200 hover:bg-black/5 dark:hover:bg-white/5\",\n getIconStyles(toast.type)\n )}\n aria-label=\"닫기\"\n >\n <svg className=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n </div>\n )\n}\n\n// 편의 함수들\nexport const showToast = (toast: Omit<Toast, \"id\">) => {\n // 이 함수는 ToastProvider 내부에서만 사용 가능\n\n}\n\nexport const showSuccessToast = (message: string, title?: string, duration?: number) => {\n\n}\n\nexport const showErrorToast = (message: string, title?: string, duration?: number) => {\n\n}\n\nexport const showWarningToast = (message: string, title?: string, duration?: number) => {\n\n}\n\nexport const showInfoToast = (message: string, title?: string, duration?: number) => {\n\n} "]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"feedback.mjs"}
|