@gunjo/ui 0.0.1-alpha.0 → 0.0.1-alpha.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/LICENSE +21 -0
- package/README.ja.md +90 -0
- package/README.md +52 -91
- package/package.json +47 -6
- package/src/components/display/Accordion.tsx +185 -0
- package/src/components/display/AccordionGroup.tsx +155 -0
- package/src/components/display/ActionDataTable.tsx +413 -0
- package/src/components/display/ActivityTimelineCard.tsx +483 -0
- package/src/components/display/AnalyticsCard.tsx +167 -0
- package/src/components/display/AssetCard.tsx +242 -0
- package/src/components/display/AssetGrid.tsx +164 -0
- package/src/components/display/Avatar.tsx +127 -0
- package/src/components/display/AvatarGroup.tsx +131 -0
- package/src/components/{atoms → display}/Badge.tsx +3 -3
- package/src/components/display/BarChart.tsx +247 -0
- package/src/components/{molecules → display}/Card.tsx +1 -1
- package/src/components/display/Carousel.tsx +593 -0
- package/src/components/display/ChartLegend.tsx +124 -0
- package/src/components/display/ChatMessage.tsx +382 -0
- package/src/components/display/ChoroplethMap.tsx +613 -0
- package/src/components/display/Code.tsx +42 -0
- package/src/components/display/CodeBlock.tsx +338 -0
- package/src/components/display/ColorSwatch.tsx +71 -0
- package/src/components/display/ConcentricProgressCard.tsx +545 -0
- package/src/components/display/DataTable.tsx +522 -0
- package/src/components/display/DistributionBar.tsx +102 -0
- package/src/components/display/DocNote.tsx +36 -0
- package/src/components/display/DonutChart.tsx +257 -0
- package/src/components/display/EmptyState.tsx +44 -0
- package/src/components/display/FileTree.tsx +180 -0
- package/src/components/display/GaugeChart.tsx +219 -0
- package/src/components/display/HeatmapChart.tsx +266 -0
- package/src/components/display/Icon.tsx +66 -0
- package/src/components/display/ImagePreview.tsx +140 -0
- package/src/components/{atoms → display}/Img.tsx +46 -12
- package/src/components/display/LabeledDonutCard.tsx +475 -0
- package/src/components/display/LineChart.tsx +464 -0
- package/src/components/{molecules → display}/List.tsx +20 -13
- package/src/components/display/MarkdownRenderer.tsx +157 -0
- package/src/components/display/MetadataList.tsx +81 -0
- package/src/components/display/MiniDistributionBarCard.tsx +314 -0
- package/src/components/display/PieChart.tsx +234 -0
- package/src/components/display/QuadrantMatrix.tsx +330 -0
- package/src/components/display/RadarChart.tsx +335 -0
- package/src/components/display/RadialBarChart.tsx +264 -0
- package/src/components/display/RetentionCohortCard.tsx +350 -0
- package/src/components/display/RibbonChart.tsx +618 -0
- package/src/components/display/SearchableAccordion.tsx +270 -0
- package/src/components/display/SegmentTimelineCard.tsx +452 -0
- package/src/components/display/SegmentedGaugeCard.tsx +607 -0
- package/src/components/display/Spacer.tsx +51 -0
- package/src/components/display/SparklineChart.tsx +394 -0
- package/src/components/display/StackedBarChart.tsx +393 -0
- package/src/components/display/Statistic.tsx +70 -0
- package/src/components/{molecules → display}/Table.tsx +22 -7
- package/src/components/display/Tag.tsx +80 -0
- package/src/components/display/TagEditor.tsx +141 -0
- package/src/components/display/Timeline.tsx +121 -0
- package/src/components/{atoms → display}/ToolPill.tsx +42 -18
- package/src/components/display/TreeView.tsx +226 -0
- package/src/components/display/chart-tooltip.tsx +423 -0
- package/src/components/display/chart-utils.ts +71 -0
- package/src/components/display/circular-chart-utils.ts +147 -0
- package/src/components/display/generated/default-variant-keys.ts +90 -0
- package/src/components/display/generated/variant-keys.ts +169 -0
- package/src/components/{atoms → feedback}/Alert.tsx +12 -5
- package/src/components/feedback/Banner.tsx +90 -0
- package/src/components/{molecules → feedback}/NotificationCenter.tsx +64 -31
- package/src/components/feedback/ProgressWidget.tsx +44 -0
- package/src/components/{atoms → feedback}/Spinner.tsx +2 -2
- package/src/components/{molecules → feedback}/StatusBar.tsx +4 -4
- package/src/components/feedback/StatusScreen.tsx +148 -0
- package/src/components/{molecules → feedback}/Stepper.tsx +10 -5
- package/src/components/feedback/Toast.tsx +108 -0
- package/src/components/feedback/ToastProvider.tsx +78 -0
- package/src/components/feedback/generated/default-variant-keys.ts +16 -0
- package/src/components/feedback/generated/variant-keys.ts +21 -0
- package/src/components/generated/component-manifest.ts +1568 -454
- package/src/components/generated/component-style-hints.ts +1958 -718
- package/src/components/{atoms → inputs}/ButtonVariants.ts +13 -3
- package/src/components/inputs/Calendar.tsx +212 -0
- package/src/components/inputs/ChatComposer.tsx +75 -0
- package/src/components/inputs/ChatInput.tsx +528 -0
- package/src/components/{atoms → inputs}/Checkbox.tsx +2 -2
- package/src/components/inputs/Combobox.tsx +175 -0
- package/src/components/inputs/CopyButton.tsx +187 -0
- package/src/components/inputs/DatePicker.tsx +519 -0
- package/src/components/inputs/DateRangePicker.tsx +878 -0
- package/src/components/inputs/EditableField.tsx +182 -0
- package/src/components/{organisms → inputs}/FileUploader.tsx +24 -9
- package/src/components/inputs/FilterButton.tsx +163 -0
- package/src/components/{molecules → inputs}/Form.tsx +20 -3
- package/src/components/{atoms → inputs}/Input.tsx +2 -0
- package/src/components/inputs/InputOTP.tsx +75 -0
- package/src/components/inputs/Mention.tsx +279 -0
- package/src/components/inputs/NumberInput.tsx +109 -0
- package/src/components/inputs/PasswordGroup.tsx +138 -0
- package/src/components/inputs/PasswordInput.tsx +74 -0
- package/src/components/inputs/PasswordRequirementList.tsx +96 -0
- package/src/components/inputs/PasswordStrengthMeter.tsx +93 -0
- package/src/components/inputs/PhoneInput.tsx +99 -0
- package/src/components/inputs/PostalCodeInput.tsx +98 -0
- package/src/components/inputs/RangeSlider.tsx +129 -0
- package/src/components/inputs/SearchInput.tsx +76 -0
- package/src/components/inputs/Select.tsx +39 -0
- package/src/components/{atoms → inputs}/Slider.tsx +18 -5
- package/src/components/{molecules → inputs}/SortButton.tsx +5 -2
- package/src/components/{atoms → inputs}/Switch.tsx +15 -4
- package/src/components/inputs/TagInput.tsx +114 -0
- package/src/components/{atoms → inputs}/Textarea.tsx +1 -0
- package/src/components/inputs/TimePicker.tsx +150 -0
- package/src/components/inputs/Toggle.tsx +48 -0
- package/src/components/{atoms → inputs}/ToggleGroup.tsx +2 -2
- package/src/components/inputs/TooltipButton.tsx +148 -0
- package/src/components/inputs/VoiceInputButton.tsx +317 -0
- package/src/components/inputs/calendar-holidays.ts +56 -0
- package/src/components/inputs/generated/default-variant-keys.ts +32 -0
- package/src/components/{atoms → inputs}/generated/variant-keys.ts +19 -27
- package/src/components/layout/AspectRatio.tsx +12 -0
- package/src/components/layout/AssetInspectorPanel.tsx +416 -0
- package/src/components/layout/Cluster.tsx +56 -0
- package/src/components/layout/CollapsiblePanelToggle.tsx +94 -0
- package/src/components/layout/Container.tsx +43 -0
- package/src/components/layout/DeviceFrame.tsx +227 -0
- package/src/components/layout/Grid.tsx +65 -0
- package/src/components/layout/HStack.tsx +73 -0
- package/src/components/{organisms → layout}/InspectorPanel.tsx +6 -5
- package/src/components/layout/MarqueeFrame.tsx +158 -0
- package/src/components/layout/Resizable.tsx +94 -0
- package/src/components/layout/ScrollArea.tsx +71 -0
- package/src/components/{organisms → layout}/SpatialCanvas.tsx +12 -7
- package/src/components/layout/VStack.tsx +69 -0
- package/src/components/layout/generated/default-variant-keys.ts +16 -0
- package/src/components/layout/generated/variant-keys.ts +21 -0
- package/src/components/{molecules → navigation}/Breadcrumb.tsx +5 -4
- package/src/components/navigation/Command.tsx +266 -0
- package/src/components/navigation/CommandPalette.tsx +83 -0
- package/src/components/navigation/DocumentPager.tsx +171 -0
- package/src/components/navigation/Footer.tsx +88 -0
- package/src/components/navigation/Header.tsx +80 -0
- package/src/components/{molecules → navigation}/Menubar.tsx +45 -12
- package/src/components/navigation/NavigationMenu.tsx +128 -0
- package/src/components/navigation/PageAside.tsx +84 -0
- package/src/components/{molecules → navigation}/Pagination.tsx +60 -7
- package/src/components/{organisms → navigation}/RightRail.tsx +1 -1
- package/src/components/navigation/Sidebar.tsx +223 -0
- package/src/components/navigation/SidebarItem.tsx +160 -0
- package/src/components/{molecules → navigation}/Tabs.tsx +2 -2
- package/src/components/navigation/TextLink.tsx +71 -0
- package/src/components/navigation/generated/default-variant-keys.ts +12 -0
- package/src/components/navigation/generated/variant-keys.ts +13 -0
- package/src/components/overlay/AIChatInput.tsx +5 -0
- package/src/components/overlay/AIChatMessage.tsx +6 -0
- package/src/components/overlay/AlertDialog.tsx +145 -0
- package/src/components/overlay/ChatPanel.tsx +180 -0
- package/src/components/{molecules → overlay}/ContextMenu.tsx +65 -29
- package/src/components/{molecules → overlay}/Dialog.tsx +21 -13
- package/src/components/overlay/Drawer.tsx +131 -0
- package/src/components/{molecules → overlay}/DropdownMenu.tsx +52 -17
- package/src/components/overlay/FloatingPanel.tsx +90 -0
- package/src/components/overlay/HoverCard.tsx +36 -0
- package/src/components/overlay/MediaLightbox.tsx +403 -0
- package/src/components/overlay/MediaPickerDialog.tsx +198 -0
- package/src/components/overlay/Modal.tsx +103 -0
- package/src/components/overlay/OnboardingFlow.tsx +172 -0
- package/src/components/overlay/Popover.tsx +36 -0
- package/src/components/overlay/ShareModal.tsx +324 -0
- package/src/components/{molecules → overlay}/Sheet.tsx +76 -19
- package/src/components/overlay/Tooltip.tsx +130 -0
- package/src/components/overlay/generated/default-variant-keys.ts +14 -0
- package/src/components/overlay/generated/variant-keys.ts +17 -0
- package/src/components/patterns/BlogTemplate.tsx +46 -0
- package/src/components/{templates → patterns}/DashboardTemplate.tsx +2 -2
- package/src/components/patterns/DocsTemplate.tsx +41 -0
- package/src/components/{templates → patterns}/MediaLibraryTemplate.tsx +1 -1
- package/src/components/patterns/OnboardingTemplate.tsx +32 -0
- package/src/components/patterns/PricingTemplate.tsx +106 -0
- package/src/globals.css +173 -22
- package/src/index.ts +177 -76
- package/tailwind-theme-extend.cjs +48 -3
- package/design/atoms-metadata.json +0 -82
- package/design/molecules-metadata.json +0 -130
- package/design/organisms-metadata.json +0 -38
- package/design/templates-metadata.json +0 -38
- package/src/components/atoms/Avatar.tsx +0 -57
- package/src/components/atoms/Select.tsx +0 -28
- package/src/components/atoms/generated/default-variant-keys.ts +0 -36
- package/src/components/molecules/AIChatInput.tsx +0 -140
- package/src/components/molecules/AIChatMessage.tsx +0 -109
- package/src/components/molecules/Accordion.tsx +0 -99
- package/src/components/molecules/Calendar.tsx +0 -60
- package/src/components/molecules/Carousel.tsx +0 -261
- package/src/components/molecules/Command.tsx +0 -152
- package/src/components/molecules/FilterButton.tsx +0 -133
- package/src/components/molecules/HoverCard.tsx +0 -29
- package/src/components/molecules/Modal.tsx +0 -66
- package/src/components/molecules/Popover.tsx +0 -31
- package/src/components/molecules/ProgressWidget.tsx +0 -40
- package/src/components/molecules/Resizable.tsx +0 -47
- package/src/components/molecules/ScrollArea.tsx +0 -48
- package/src/components/molecules/SidebarItem.tsx +0 -134
- package/src/components/molecules/Toast.tsx +0 -57
- package/src/components/molecules/Tooltip.tsx +0 -30
- package/src/components/molecules/generated/default-variant-keys.ts +0 -22
- package/src/components/molecules/generated/variant-keys.ts +0 -33
- package/src/components/organisms/CommandPalette.tsx +0 -58
- package/src/components/organisms/FloatingPanel.tsx +0 -46
- package/src/components/organisms/ShareModal.tsx +0 -182
- package/src/components/organisms/ToastProvider.tsx +0 -49
- /package/src/components/{atoms → display}/Kbd.tsx +0 -0
- /package/src/components/{atoms → display}/Separator.tsx +0 -0
- /package/src/components/{atoms → display}/Skeleton.tsx +0 -0
- /package/src/components/{atoms → feedback}/Progress.tsx +0 -0
- /package/src/components/{atoms → inputs}/Button.tsx +0 -0
- /package/src/components/{atoms → inputs}/Label.tsx +0 -0
- /package/src/components/{atoms → inputs}/RadioGroup.tsx +0 -0
- /package/src/components/{organisms → navigation}/AppRail.tsx +0 -0
- /package/src/components/{templates → patterns}/AuthTemplate.tsx +0 -0
- /package/src/components/{templates → patterns}/BannalyzeTemplate.tsx +0 -0
- /package/src/components/{templates → patterns}/ChatTemplate.tsx +0 -0
- /package/src/components/{templates → patterns}/EditorTemplate.tsx +0 -0
- /package/src/components/{templates → patterns}/KanbanTemplate.tsx +0 -0
- /package/src/components/{templates → patterns}/LandingTemplate.tsx +0 -0
- /package/src/components/{templates → patterns}/SettingsTemplate.tsx +0 -0
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
import React, { useState, useEffect } from 'react';
|
|
3
|
-
import { createPortal } from 'react-dom';
|
|
4
|
-
import { X, Copy, Globe, Lock, Check, ExternalLink } from 'lucide-react';
|
|
5
|
-
import { cn } from '../../lib/utils';
|
|
6
|
-
|
|
7
|
-
export interface ShareData {
|
|
8
|
-
isPublic: boolean;
|
|
9
|
-
token?: string;
|
|
10
|
-
accessCount?: number;
|
|
11
|
-
createdAt?: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface ShareableItem {
|
|
15
|
-
id: string;
|
|
16
|
-
share?: ShareData;
|
|
17
|
-
[key: string]: any;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
interface ShareModalProps {
|
|
21
|
-
isOpen: boolean;
|
|
22
|
-
onClose: () => void;
|
|
23
|
-
item: ShareableItem;
|
|
24
|
-
onUpdate: (id: string, updates: Partial<ShareableItem>) => void;
|
|
25
|
-
apiEndpoint?: string; // Allow customizing API endpoint
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const ShareModal = ({ isOpen, onClose, item, onUpdate, apiEndpoint = '/api/share' }: ShareModalProps) => {
|
|
29
|
-
const [isPublic, setIsPublic] = useState(item.share?.isPublic || false);
|
|
30
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
31
|
-
const [copied, setCopied] = useState(false);
|
|
32
|
-
const [shareData, setShareData] = useState<ShareData | undefined>(item.share);
|
|
33
|
-
const [mounted, setMounted] = useState(false);
|
|
34
|
-
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
setMounted(true);
|
|
37
|
-
}, []);
|
|
38
|
-
|
|
39
|
-
useEffect(() => {
|
|
40
|
-
setIsPublic(item.share?.isPublic || false);
|
|
41
|
-
setShareData(item.share);
|
|
42
|
-
}, [item.id, item.share]);
|
|
43
|
-
|
|
44
|
-
if (!isOpen || !mounted) return null;
|
|
45
|
-
|
|
46
|
-
const handleToggleShare = async () => {
|
|
47
|
-
setIsLoading(true);
|
|
48
|
-
try {
|
|
49
|
-
const res = await fetch(apiEndpoint, {
|
|
50
|
-
method: 'POST',
|
|
51
|
-
headers: { 'Content-Type': 'application/json' },
|
|
52
|
-
body: JSON.stringify({
|
|
53
|
-
id: item.id,
|
|
54
|
-
enable: !isPublic
|
|
55
|
-
})
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
if (res.ok) {
|
|
59
|
-
const json = await res.json();
|
|
60
|
-
setIsPublic(!isPublic);
|
|
61
|
-
setShareData(json.share);
|
|
62
|
-
// Optimistic update for parent
|
|
63
|
-
onUpdate(item.id, { share: json.share });
|
|
64
|
-
}
|
|
65
|
-
} catch (error) {
|
|
66
|
-
console.error('Failed to toggle share', error);
|
|
67
|
-
} finally {
|
|
68
|
-
setIsLoading(false);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const shareUrl = shareData?.token
|
|
73
|
-
? `${window.location.origin}/share/${shareData.token}`
|
|
74
|
-
: '';
|
|
75
|
-
|
|
76
|
-
const handleCopy = () => {
|
|
77
|
-
if (shareUrl) {
|
|
78
|
-
navigator.clipboard.writeText(shareUrl);
|
|
79
|
-
setCopied(true);
|
|
80
|
-
setTimeout(() => setCopied(false), 2000);
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
return createPortal(
|
|
85
|
-
<div className="fixed inset-0 z-50 flex items-center justify-center bg-overlay/50 backdrop-blur-sm animate-in fade-in duration-200" onClick={(e) => { e.stopPropagation(); onClose(); }}>
|
|
86
|
-
<div className="bg-background border border-border rounded-xl shadow-2xl w-[448px] w-full max-w-md overflow-hidden animate-in zoom-in-95 duration-200" onClick={e => e.stopPropagation()}>
|
|
87
|
-
{/* Header */}
|
|
88
|
-
<div className="flex items-center justify-between px-4 py-3 border-b border-border bg-muted/50">
|
|
89
|
-
<h3 className="text-sm font-semibold text-foreground flex items-center gap-2">
|
|
90
|
-
<Globe size={16} className="text-primary" />
|
|
91
|
-
Share Image
|
|
92
|
-
</h3>
|
|
93
|
-
<button onClick={onClose} className="text-muted-foreground hover:text-foreground transition-colors">
|
|
94
|
-
<X size={18} />
|
|
95
|
-
</button>
|
|
96
|
-
</div>
|
|
97
|
-
|
|
98
|
-
{/* Content */}
|
|
99
|
-
<div className="p-6 space-y-6">
|
|
100
|
-
|
|
101
|
-
{/* Toggle Switch */}
|
|
102
|
-
<div className="flex items-center justify-between">
|
|
103
|
-
<div className="space-y-1">
|
|
104
|
-
<div className="text-sm font-medium text-foreground">Public Link</div>
|
|
105
|
-
<div className="text-xs text-muted-foreground">
|
|
106
|
-
{isPublic
|
|
107
|
-
? "Anyone with the link can view this image."
|
|
108
|
-
: "Only you can view this image."}
|
|
109
|
-
</div>
|
|
110
|
-
</div>
|
|
111
|
-
|
|
112
|
-
<button
|
|
113
|
-
onClick={handleToggleShare}
|
|
114
|
-
disabled={isLoading}
|
|
115
|
-
className={cn(
|
|
116
|
-
"relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:ring-offset-background",
|
|
117
|
-
isPublic ? "bg-primary" : "bg-muted",
|
|
118
|
-
isLoading && "opacity-50 cursor-not-allowed"
|
|
119
|
-
)}
|
|
120
|
-
>
|
|
121
|
-
<span
|
|
122
|
-
className={cn(
|
|
123
|
-
"inline-block h-4 w-4 transform rounded-full bg-background transition-transform",
|
|
124
|
-
isPublic ? "translate-x-6" : "translate-x-1"
|
|
125
|
-
)}
|
|
126
|
-
/>
|
|
127
|
-
</button>
|
|
128
|
-
</div>
|
|
129
|
-
|
|
130
|
-
{/* URL Display */}
|
|
131
|
-
{isPublic && shareData && (
|
|
132
|
-
<div className="space-y-2 animate-in slide-in-from-top-2 duration-200">
|
|
133
|
-
<label className="text-xs font-medium text-muted-foreground">Public URL</label>
|
|
134
|
-
<div className="flex items-center gap-2">
|
|
135
|
-
<div className="flex-1 bg-muted border border-border rounded-md px-3 py-2 text-xs text-muted-foreground font-mono truncate select-all">
|
|
136
|
-
{shareUrl}
|
|
137
|
-
</div>
|
|
138
|
-
<button
|
|
139
|
-
onClick={handleCopy}
|
|
140
|
-
className="p-2 bg-background hover:bg-muted text-muted-foreground rounded-md transition-colors border border-border"
|
|
141
|
-
title="Copy to clipboard"
|
|
142
|
-
>
|
|
143
|
-
{copied ? <Check size={16} className="text-primary" /> : <Copy size={16} />}
|
|
144
|
-
</button>
|
|
145
|
-
<a
|
|
146
|
-
href={shareUrl}
|
|
147
|
-
target="_blank"
|
|
148
|
-
rel="noopener noreferrer"
|
|
149
|
-
className="p-2 bg-background hover:bg-muted text-muted-foreground rounded-md transition-colors border border-border"
|
|
150
|
-
title="Open in new tab"
|
|
151
|
-
>
|
|
152
|
-
<ExternalLink size={16} />
|
|
153
|
-
</a>
|
|
154
|
-
</div>
|
|
155
|
-
|
|
156
|
-
{/* Stats */}
|
|
157
|
-
<div className="flex items-center gap-4 pt-2">
|
|
158
|
-
<div className="flex items-center gap-1.5 text-xs text-muted-foreground">
|
|
159
|
-
<Globe size={12} />
|
|
160
|
-
<span>Access Count: <span className="text-foreground font-mono">{shareData.accessCount || 0}</span></span>
|
|
161
|
-
</div>
|
|
162
|
-
<div className="flex items-center gap-1.5 text-xs text-muted-foreground">
|
|
163
|
-
<Lock size={12} />
|
|
164
|
-
<span>Token: <span className="text-foreground font-mono">{shareData.token?.slice(0, 8)}...</span></span>
|
|
165
|
-
</div>
|
|
166
|
-
</div>
|
|
167
|
-
</div>
|
|
168
|
-
)}
|
|
169
|
-
|
|
170
|
-
{!isPublic && (
|
|
171
|
-
<div className="flex flex-col items-center justify-center py-4 text-muted-foreground space-y-2 border-2 border-dashed border-border rounded-lg bg-muted/50">
|
|
172
|
-
<Lock size={24} />
|
|
173
|
-
<span className="text-xs">Sharing is disabled</span>
|
|
174
|
-
</div>
|
|
175
|
-
)}
|
|
176
|
-
|
|
177
|
-
</div>
|
|
178
|
-
</div>
|
|
179
|
-
</div>,
|
|
180
|
-
document.body
|
|
181
|
-
);
|
|
182
|
-
};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
"use client"
|
|
2
|
-
import React, { createContext, useContext, useState, useCallback } from 'react';
|
|
3
|
-
import { Toast, ToastType } from '../molecules/Toast';
|
|
4
|
-
|
|
5
|
-
interface ToastContextType {
|
|
6
|
-
showToast: (message: string, type: ToastType, duration?: number) => void;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const ToastContext = createContext<ToastContextType | undefined>(undefined);
|
|
10
|
-
|
|
11
|
-
export const ToastProvider = ({ children }: { children: React.ReactNode }) => {
|
|
12
|
-
const [toasts, setToasts] = useState<{ id: number, message: string, type: ToastType, duration: number, isVisible: boolean }[]>([]);
|
|
13
|
-
|
|
14
|
-
const showToast = useCallback((message: string, type: ToastType, duration = 3000) => {
|
|
15
|
-
const id = Date.now();
|
|
16
|
-
setToasts(prev => [...prev, { id, message, type, duration, isVisible: true }]);
|
|
17
|
-
}, []);
|
|
18
|
-
|
|
19
|
-
const closeToast = useCallback((id: number) => {
|
|
20
|
-
setToasts(prev => prev.map(t => t.id === id ? { ...t, isVisible: false } : t));
|
|
21
|
-
setTimeout(() => {
|
|
22
|
-
setToasts(prev => prev.filter(t => t.id !== id));
|
|
23
|
-
}, 300);
|
|
24
|
-
}, []);
|
|
25
|
-
|
|
26
|
-
return (
|
|
27
|
-
<ToastContext.Provider value={{ showToast }}>
|
|
28
|
-
{children}
|
|
29
|
-
<div className="fixed top-6 right-6 z-[100] flex flex-col items-center w-[320px] gap-2 pointer-events-none">
|
|
30
|
-
{toasts.map(toast => (
|
|
31
|
-
<Toast
|
|
32
|
-
key={toast.id}
|
|
33
|
-
message={toast.message}
|
|
34
|
-
type={toast.type}
|
|
35
|
-
isVisible={toast.isVisible}
|
|
36
|
-
onClose={() => closeToast(toast.id)}
|
|
37
|
-
duration={toast.duration}
|
|
38
|
-
/>
|
|
39
|
-
))}
|
|
40
|
-
</div>
|
|
41
|
-
</ToastContext.Provider>
|
|
42
|
-
);
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export const useToast = () => {
|
|
46
|
-
const context = useContext(ToastContext);
|
|
47
|
-
if (!context) throw new Error('useToast must be used within a ToastProvider');
|
|
48
|
-
return context;
|
|
49
|
-
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|