@xyhp915/slack-base-ui 0.0.1 → 0.0.3
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 +220 -4
- package/agents/slack-base-ui/SKILL.md +137 -0
- package/agents/slack-base-ui/checklists/style-review.md +56 -0
- package/agents/slack-base-ui/templates/consumer-setup.md +109 -0
- package/agents/slack-base-ui/templates/slack-theme.css +152 -0
- package/libs/Dialog.d.ts +73 -0
- package/libs/Dialog.d.ts.map +1 -1
- package/libs/Popover.d.ts +69 -0
- package/libs/Popover.d.ts.map +1 -1
- package/libs/index.d.ts +4 -4
- package/libs/index.d.ts.map +1 -1
- package/libs/index.js +2885 -2718
- package/package.json +1 -1
- package/src/App.css +7 -0
- package/src/App.tsx +18 -0
- package/src/assets/react.svg +1 -0
- package/src/components/AlertDialog.tsx +185 -0
- package/src/components/AutoComplete.tsx +311 -0
- package/src/components/Avatar.tsx +70 -0
- package/src/components/Badge.tsx +48 -0
- package/src/components/Button.tsx +53 -0
- package/src/components/Checkbox.tsx +109 -0
- package/src/components/ContextMenu.tsx +393 -0
- package/src/components/Dialog.tsx +371 -0
- package/src/components/Form.tsx +409 -0
- package/src/components/IconButton.tsx +49 -0
- package/src/components/Input.tsx +56 -0
- package/src/components/Loading.tsx +123 -0
- package/src/components/Menu.tsx +368 -0
- package/src/components/Popover.tsx +367 -0
- package/src/components/Progress.tsx +89 -0
- package/src/components/Radio.tsx +137 -0
- package/src/components/Select.tsx +177 -0
- package/src/components/Switch.tsx +116 -0
- package/src/components/Tabs.tsx +128 -0
- package/src/components/Toast.tsx +149 -0
- package/src/components/Tooltip.tsx +46 -0
- package/src/components/index.ts +186 -0
- package/src/context/ThemeContext.tsx +53 -0
- package/src/context/useTheme.ts +11 -0
- package/src/examples/slack-clone/SlackApp.tsx +94 -0
- package/src/examples/slack-clone/components/ChannelHeader.tsx +34 -0
- package/src/examples/slack-clone/components/Composer.tsx +42 -0
- package/src/examples/slack-clone/components/Message.tsx +97 -0
- package/src/examples/slack-clone/components/UserProfile.tsx +78 -0
- package/src/examples/slack-clone/layout/Layout.tsx +27 -0
- package/src/examples/slack-clone/layout/Sidebar.tsx +67 -0
- package/src/examples/slack-clone/layout/SidebarItem.tsx +57 -0
- package/src/examples/slack-clone/layout/TopBar.tsx +30 -0
- package/src/index.css +240 -0
- package/src/main.tsx +22 -0
- package/src/pages/ComponentShowcase.tsx +1964 -0
- package/src/pages/Dashboard.tsx +87 -0
- package/src/pages/QuickStartDemo.tsx +262 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { SidebarItem } from './SidebarItem';
|
|
2
|
+
import { ChevronDown, Plus } from 'lucide-react';
|
|
3
|
+
|
|
4
|
+
export const Sidebar = () => {
|
|
5
|
+
return (
|
|
6
|
+
<aside className="w-[260px] bg-(--sidebar-bg) flex flex-col h-full text-(--sidebar-text) select-none">
|
|
7
|
+
{/* Workspace Header */}
|
|
8
|
+
<div className="h-12 px-4 flex items-center justify-between hover:bg-(--sidebar-item-hover) cursor-pointer border-b border-white/10 transition-colors">
|
|
9
|
+
<h1 className="font-bold text-white truncate text-[18px]">Acme Corp</h1>
|
|
10
|
+
<div className="bg-white/90 p-1 rounded-full text-(--slack-aubergine)">
|
|
11
|
+
<ChevronDown className="w-3 h-3 stroke-3" />
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
|
|
15
|
+
{/* Scrollable Content */}
|
|
16
|
+
<div className="flex-1 overflow-y-auto py-3 px-2 custom-scrollbar space-y-6">
|
|
17
|
+
|
|
18
|
+
{/* Section: Channels */}
|
|
19
|
+
<div className="space-y-0.5">
|
|
20
|
+
<div className="flex items-center justify-between group px-3 py-1 mb-1">
|
|
21
|
+
<div className="flex items-center gap-1 hover:bg-(--sidebar-item-hover) cursor-pointer rounded px-1 -ml-1">
|
|
22
|
+
<ChevronDown className="w-3 h-3" />
|
|
23
|
+
<span className="text-[15px] font-medium group-hover:text-white transition-colors">Channels</span>
|
|
24
|
+
</div>
|
|
25
|
+
<button className="opacity-0 group-hover:opacity-100 p-1 hover:bg-(--sidebar-item-hover) rounded text-white transition-opacity">
|
|
26
|
+
<Plus className="w-4 h-4" />
|
|
27
|
+
</button>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<SidebarItem label="general" active />
|
|
31
|
+
<SidebarItem label="random" />
|
|
32
|
+
<SidebarItem label="announcements" isPrivate />
|
|
33
|
+
<SidebarItem label="design-team" unreadCount={2} highlight />
|
|
34
|
+
<SidebarItem label="engineering" />
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
{/* Section: Direct Messages */}
|
|
38
|
+
<div className="space-y-0.5">
|
|
39
|
+
<div className="flex items-center justify-between group px-3 py-1 mb-1">
|
|
40
|
+
<div className="flex items-center gap-1 hover:bg-(--sidebar-item-hover) cursor-pointer rounded px-1 -ml-1">
|
|
41
|
+
<ChevronDown className="w-3 h-3" />
|
|
42
|
+
<span className="text-[15px] font-medium group-hover:text-white transition-colors">Direct messages</span>
|
|
43
|
+
</div>
|
|
44
|
+
<button className="opacity-0 group-hover:opacity-100 p-1 hover:bg-(--sidebar-item-hover) rounded text-white transition-opacity">
|
|
45
|
+
<Plus className="w-4 h-4" />
|
|
46
|
+
</button>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<SidebarItem itemType="dm" label="Alice Smith" status="online" />
|
|
50
|
+
<SidebarItem itemType="dm" label="Bob Jones" status="away" />
|
|
51
|
+
<SidebarItem itemType="dm" label="Charlie Day" status="offline" />
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
{/* Section: Apps */}
|
|
55
|
+
<div className="space-y-0.5">
|
|
56
|
+
<div className="flex items-center gap-1 px-3 py-1 mb-1 group cursor-pointer">
|
|
57
|
+
<ChevronDown className="w-3 h-3" />
|
|
58
|
+
<span className="text-[15px] font-medium group-hover:text-white transition-colors">Apps</span>
|
|
59
|
+
</div>
|
|
60
|
+
<SidebarItem label="Google Calendar" itemType="app" />
|
|
61
|
+
<SidebarItem label="Jira" itemType="app" />
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
</div>
|
|
65
|
+
</aside>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import clsx from 'clsx';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Hash, Lock } from 'lucide-react';
|
|
4
|
+
import { Badge } from '../../../components/Badge';
|
|
5
|
+
|
|
6
|
+
export type SidebarItemType = 'channel' | 'dm' | 'app' | 'section';
|
|
7
|
+
|
|
8
|
+
export interface SidebarItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
9
|
+
label: string;
|
|
10
|
+
itemType?: SidebarItemType;
|
|
11
|
+
active?: boolean;
|
|
12
|
+
unreadCount?: number;
|
|
13
|
+
highlight?: boolean; // White text for unreads/mentions
|
|
14
|
+
icon?: React.ElementType; // Override icon
|
|
15
|
+
isPrivate?: boolean;
|
|
16
|
+
status?: 'online' | 'away' | 'dnd' | 'offline';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const SidebarItem = React.forwardRef<HTMLButtonElement, SidebarItemProps>(
|
|
20
|
+
({ className, label, itemType = 'channel', active, unreadCount, highlight, icon: Icon, isPrivate, status, ...props }, ref) => {
|
|
21
|
+
|
|
22
|
+
// Determine default icon based on type
|
|
23
|
+
const DefaultIcon = isPrivate ? Lock : Hash;
|
|
24
|
+
const ItemIcon = Icon || (itemType === 'channel' ? DefaultIcon : undefined);
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<button
|
|
28
|
+
ref={ref}
|
|
29
|
+
className={clsx(
|
|
30
|
+
"w-full text-left flex items-center gap-2 px-3 py-1 rounded-md transition-colors text-[15px]",
|
|
31
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/50",
|
|
32
|
+
active
|
|
33
|
+
? "bg-(--sidebar-item-active) text-(--sidebar-text-active)"
|
|
34
|
+
: "text-(--sidebar-text) hover:bg-(--sidebar-item-hover)",
|
|
35
|
+
(highlight || unreadCount) && !active && "text-(--sidebar-text-active) font-bold",
|
|
36
|
+
className
|
|
37
|
+
)}
|
|
38
|
+
{...props}
|
|
39
|
+
>
|
|
40
|
+
<span className="opacity-70 flex items-center justify-center w-4">
|
|
41
|
+
{ItemIcon && <ItemIcon className="w-3.5 h-3.5" />}
|
|
42
|
+
{itemType === 'dm' && <div className={clsx("w-2.5 h-2.5 rounded text-[10px] bg-green-500", !active && "opacity-80")} />}
|
|
43
|
+
</span>
|
|
44
|
+
|
|
45
|
+
<span className="truncate flex-1">{label}</span>
|
|
46
|
+
|
|
47
|
+
{unreadCount ? (
|
|
48
|
+
<Badge
|
|
49
|
+
count={unreadCount}
|
|
50
|
+
variant={highlight ? "danger" : "neutral"}
|
|
51
|
+
className="ml-auto"
|
|
52
|
+
/>
|
|
53
|
+
) : null}
|
|
54
|
+
</button>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Search, Clock, HelpCircle } from 'lucide-react';
|
|
2
|
+
import { Avatar } from '../../../components/Avatar';
|
|
3
|
+
|
|
4
|
+
export const TopBar = () => {
|
|
5
|
+
return (
|
|
6
|
+
<header className="h-[44px] bg-(--slack-aubergine-dark) flex items-center justify-between px-4 shrink-0 shadow-sm z-10">
|
|
7
|
+
|
|
8
|
+
{/* Left Spacer / History Controls (often here) */}
|
|
9
|
+
<div className="w-[200px] flex items-center gap-4 text-white/70">
|
|
10
|
+
<Clock className="w-4 h-4 cursor-pointer hover:text-white" />
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
{/* Search Bar */}
|
|
14
|
+
<div className="flex-1 max-w-[600px]">
|
|
15
|
+
<button className="w-full h-[28px] bg-white/10 hover:bg-white/15 rounded-md flex items-center justify-center text-white/80 text-[13px] border border-white/10 shadow-inner px-2 transition-colors">
|
|
16
|
+
<Search className="w-3.5 h-3.5 mr-2 opacity-80" />
|
|
17
|
+
<span>Search Acme Corp</span>
|
|
18
|
+
</button>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
{/* Right Controls */}
|
|
22
|
+
<div className="w-[200px] flex items-center justify-end gap-3">
|
|
23
|
+
<HelpCircle className="w-4 h-4 text-white/70 cursor-pointer hover:text-white" />
|
|
24
|
+
<div className="relative cursor-pointer">
|
|
25
|
+
<Avatar size="xs" fallback="ME" status="online" rounded={false} className="rounded" />
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</header>
|
|
29
|
+
);
|
|
30
|
+
};
|
package/src/index.css
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
|
|
3
|
+
@theme {
|
|
4
|
+
--animate-in: fade-in 150ms ease-out;
|
|
5
|
+
--animate-out: fade-out 150ms ease-in;
|
|
6
|
+
|
|
7
|
+
/* 自定义圆角 - Slack 风格 */
|
|
8
|
+
--radius-sm: 3px;
|
|
9
|
+
--radius: 6px;
|
|
10
|
+
--radius-md: 8px;
|
|
11
|
+
--radius-lg: 10px;
|
|
12
|
+
--radius-xl: 14px;
|
|
13
|
+
--radius-2xl: 16px;
|
|
14
|
+
--radius-full: 9999px;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@keyframes fade-in {
|
|
18
|
+
0% {
|
|
19
|
+
opacity: 0;
|
|
20
|
+
}
|
|
21
|
+
100% {
|
|
22
|
+
opacity: 1;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@keyframes fade-out {
|
|
27
|
+
0% {
|
|
28
|
+
opacity: 1;
|
|
29
|
+
}
|
|
30
|
+
100% {
|
|
31
|
+
opacity: 0;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@keyframes zoom-in {
|
|
36
|
+
0% {
|
|
37
|
+
opacity: 0;
|
|
38
|
+
transform: scale(0.95);
|
|
39
|
+
}
|
|
40
|
+
100% {
|
|
41
|
+
opacity: 1;
|
|
42
|
+
transform: scale(1);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@keyframes zoom-out {
|
|
47
|
+
0% {
|
|
48
|
+
opacity: 1;
|
|
49
|
+
transform: scale(1);
|
|
50
|
+
}
|
|
51
|
+
100% {
|
|
52
|
+
opacity: 0;
|
|
53
|
+
transform: scale(0.95);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@keyframes progress-indeterminate {
|
|
58
|
+
0% {
|
|
59
|
+
transform: translateX(-100%);
|
|
60
|
+
}
|
|
61
|
+
100% {
|
|
62
|
+
transform: translateX(400%);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@keyframes loading-bar {
|
|
67
|
+
0% {
|
|
68
|
+
left: -33%;
|
|
69
|
+
}
|
|
70
|
+
50% {
|
|
71
|
+
left: 100%;
|
|
72
|
+
}
|
|
73
|
+
100% {
|
|
74
|
+
left: 100%;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
:root {
|
|
79
|
+
/* Colors - Slack Brand */
|
|
80
|
+
--slack-aubergine: #3F0E40;
|
|
81
|
+
--slack-aubergine-dark: #350d36;
|
|
82
|
+
--slack-blue: #1164A3;
|
|
83
|
+
--slack-green: #007a5a;
|
|
84
|
+
--slack-green-hover: #148567;
|
|
85
|
+
--slack-red: #E01E5A;
|
|
86
|
+
|
|
87
|
+
/* Theme Accent Tokens */
|
|
88
|
+
--accent: var(--slack-blue);
|
|
89
|
+
--accent-hover: #0b4c7a;
|
|
90
|
+
--accent-contrast: #ffffff;
|
|
91
|
+
--accent-action: var(--slack-green);
|
|
92
|
+
--accent-action-hover: var(--slack-green-hover);
|
|
93
|
+
--focus-ring: var(--accent);
|
|
94
|
+
--danger: var(--slack-red);
|
|
95
|
+
--danger-hover: #bd1546;
|
|
96
|
+
--badge-neutral: #616061;
|
|
97
|
+
|
|
98
|
+
/* Layout Colors */
|
|
99
|
+
--bg-primary: #ffffff;
|
|
100
|
+
--bg-secondary: #f8f8f8;
|
|
101
|
+
--bg-hover: #f2f2f2;
|
|
102
|
+
|
|
103
|
+
--text-primary: #1d1c1d;
|
|
104
|
+
--text-secondary: #616061;
|
|
105
|
+
--text-muted: #868686;
|
|
106
|
+
|
|
107
|
+
--border-light: #dddddd;
|
|
108
|
+
--border-gray: #767676;
|
|
109
|
+
--border-active: #dddddd;
|
|
110
|
+
--border-subtle: #e6e6e6;
|
|
111
|
+
|
|
112
|
+
/* Sidebar */
|
|
113
|
+
--sidebar-bg: var(--slack-aubergine);
|
|
114
|
+
--sidebar-text: #cfc3cf;
|
|
115
|
+
--sidebar-text-active: #ffffff;
|
|
116
|
+
--sidebar-item-hover: #350d36;
|
|
117
|
+
--sidebar-item-active: #1164A3;
|
|
118
|
+
|
|
119
|
+
/* Spacing */
|
|
120
|
+
--space-1: 4px;
|
|
121
|
+
--space-2: 8px;
|
|
122
|
+
--space-3: 12px;
|
|
123
|
+
--space-4: 16px;
|
|
124
|
+
--space-5: 20px;
|
|
125
|
+
--space-6: 24px;
|
|
126
|
+
--space-8: 32px;
|
|
127
|
+
|
|
128
|
+
/* Typography */
|
|
129
|
+
--font-family: 'Lato', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
|
130
|
+
--font-size-sm: 13px;
|
|
131
|
+
--font-size-md: 15px;
|
|
132
|
+
--font-size-lg: 18px;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
:root[data-theme-color="slack"] {
|
|
136
|
+
--accent: var(--slack-blue);
|
|
137
|
+
--accent-hover: #0b4c7a;
|
|
138
|
+
--accent-action: var(--slack-green);
|
|
139
|
+
--accent-action-hover: var(--slack-green-hover);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
:root[data-theme-color="blue"] {
|
|
143
|
+
--accent: #1164A3;
|
|
144
|
+
--accent-hover: #0b4c7a;
|
|
145
|
+
--accent-action: #1164A3;
|
|
146
|
+
--accent-action-hover: #0b4c7a;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
:root[data-theme-color="green"] {
|
|
150
|
+
--accent: #007a5a;
|
|
151
|
+
--accent-hover: #148567;
|
|
152
|
+
--accent-action: #007a5a;
|
|
153
|
+
--accent-action-hover: #148567;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
:root[data-theme-color="aubergine"] {
|
|
157
|
+
--accent: #3F0E40;
|
|
158
|
+
--accent-hover: #350d36;
|
|
159
|
+
--accent-action: #3F0E40;
|
|
160
|
+
--accent-action-hover: #350d36;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
:root.dark {
|
|
164
|
+
/* Colors - Slack Brand (Dark Mode Adjustments if needed) */
|
|
165
|
+
--slack-aubergine: #19171d;
|
|
166
|
+
/* Darker sidebar */
|
|
167
|
+
--slack-aubergine-dark: #121016;
|
|
168
|
+
|
|
169
|
+
/* Layout Colors */
|
|
170
|
+
--bg-primary: #1A1D21;
|
|
171
|
+
--bg-secondary: #222529;
|
|
172
|
+
--bg-hover: #2C3036;
|
|
173
|
+
|
|
174
|
+
--text-primary: #D1D2D3;
|
|
175
|
+
--text-secondary: #ABACAE;
|
|
176
|
+
--text-muted: #858688;
|
|
177
|
+
|
|
178
|
+
--border-light: #363a3e;
|
|
179
|
+
--border-active: transparent;
|
|
180
|
+
/* Slack buttons don't usually show high contrast borders on active in dark mode */
|
|
181
|
+
/* Darker border */
|
|
182
|
+
--border-subtle: #454545;
|
|
183
|
+
--border-gray: #404040;
|
|
184
|
+
|
|
185
|
+
/* Sidebar */
|
|
186
|
+
--sidebar-bg: #19171d;
|
|
187
|
+
--sidebar-text: #ABACAE;
|
|
188
|
+
--sidebar-text-active: #FFFFFF;
|
|
189
|
+
--sidebar-item-hover: #27242c;
|
|
190
|
+
--sidebar-item-active: #1164A3;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
* {
|
|
194
|
+
box-sizing: border-box;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
body {
|
|
198
|
+
margin: 0;
|
|
199
|
+
padding: 0;
|
|
200
|
+
font-family: var(--font-family), serif;
|
|
201
|
+
color: var(--text-primary);
|
|
202
|
+
background-color: var(--bg-primary);
|
|
203
|
+
-webkit-font-smoothing: subpixel-antialiased;
|
|
204
|
+
-moz-osx-font-smoothing: grayscale;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* Scrollbar styling */
|
|
208
|
+
::-webkit-scrollbar {
|
|
209
|
+
width: 8px;
|
|
210
|
+
height: 8px;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
::-webkit-scrollbar-track {
|
|
214
|
+
background: transparent;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
::-webkit-scrollbar-thumb {
|
|
218
|
+
background: rgba(0, 0, 0, 0.1);
|
|
219
|
+
border-radius: 4px;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
::-webkit-scrollbar-thumb:hover {
|
|
223
|
+
background: rgba(0, 0, 0, 0.2);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/* Dark mode scrollbar */
|
|
227
|
+
:root.dark ::-webkit-scrollbar-thumb {
|
|
228
|
+
background: rgba(255, 255, 255, 0.1);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
:root.dark ::-webkit-scrollbar-thumb:hover {
|
|
232
|
+
background: rgba(255, 255, 255, 0.2);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/* Focus Ring for Accessibility */
|
|
236
|
+
input:focus-visible, textarea:focus-visible {
|
|
237
|
+
outline: 3px solid color-mix(in srgb, var(--focus-ring) 35%, transparent);
|
|
238
|
+
outline-offset: 1px;
|
|
239
|
+
box-shadow: 0 0 0 1px color-mix(in srgb, var(--focus-ring) 40%, transparent);
|
|
240
|
+
}
|
package/src/main.tsx
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { StrictMode } from 'react'
|
|
2
|
+
import { createRoot } from 'react-dom/client'
|
|
3
|
+
import './index.css'
|
|
4
|
+
import App from './App.tsx'
|
|
5
|
+
import { ThemeProvider } from './context/ThemeContext'
|
|
6
|
+
import { ToastProvider } from './components'
|
|
7
|
+
import { DialogProvider } from './components'
|
|
8
|
+
import { ImperativePopoverProvider } from './components'
|
|
9
|
+
|
|
10
|
+
createRoot(document.getElementById('root')!).render(
|
|
11
|
+
<StrictMode>
|
|
12
|
+
<ThemeProvider>
|
|
13
|
+
<ToastProvider>
|
|
14
|
+
<DialogProvider>
|
|
15
|
+
<ImperativePopoverProvider>
|
|
16
|
+
<App />
|
|
17
|
+
</ImperativePopoverProvider>
|
|
18
|
+
</DialogProvider>
|
|
19
|
+
</ToastProvider>
|
|
20
|
+
</ThemeProvider>
|
|
21
|
+
</StrictMode>,
|
|
22
|
+
)
|