pejay-ui 1.3.4 → 1.4.0
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 +59 -1
- package/bin/cli.js +294 -22
- package/package.json +2 -2
- package/registry/buttons.json +9 -0
- package/registry/dropdowns.json +28 -0
- package/registry/forms.json +322 -0
- package/registry/layouts.json +18 -0
- package/registry/overlays.json +8 -0
- package/registry/scaffolds.json +83 -0
- package/registry/toast.json +10 -0
- package/templates/overlays/index.ts +1 -0
- package/templates/overlays/portal.tsx +26 -0
- package/templates/toast/README.md +183 -0
- package/templates/toast/container.tsx +320 -0
- package/templates/toast/index.ts +4 -0
- package/templates/toast/store.ts +35 -0
- package/templates/toast/toast.ts +54 -0
- package/templates/toast/types.ts +15 -0
- package/registry.json +0 -256
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
{
|
|
2
|
+
"form/input": {
|
|
3
|
+
"name": "Input",
|
|
4
|
+
"category": "form",
|
|
5
|
+
"files": [
|
|
6
|
+
"templates/form/input.tsx"
|
|
7
|
+
],
|
|
8
|
+
"utils": [
|
|
9
|
+
"cn.ts"
|
|
10
|
+
],
|
|
11
|
+
"peerDependencies": [
|
|
12
|
+
"clsx",
|
|
13
|
+
"tailwind-merge",
|
|
14
|
+
"lucide-react"
|
|
15
|
+
],
|
|
16
|
+
"supportsCategory": true
|
|
17
|
+
},
|
|
18
|
+
"form/amount-input": {
|
|
19
|
+
"name": "AmountInput",
|
|
20
|
+
"category": "form",
|
|
21
|
+
"files": [
|
|
22
|
+
"templates/form/amount-input.tsx"
|
|
23
|
+
],
|
|
24
|
+
"utils": [
|
|
25
|
+
"cn.ts"
|
|
26
|
+
],
|
|
27
|
+
"peerDependencies": [
|
|
28
|
+
"clsx",
|
|
29
|
+
"tailwind-merge",
|
|
30
|
+
"lucide-react"
|
|
31
|
+
],
|
|
32
|
+
"supportsCategory": true
|
|
33
|
+
},
|
|
34
|
+
"form/checkbox": {
|
|
35
|
+
"name": "Checkbox",
|
|
36
|
+
"category": "form",
|
|
37
|
+
"files": [
|
|
38
|
+
"templates/form/checkbox.tsx"
|
|
39
|
+
],
|
|
40
|
+
"utils": [
|
|
41
|
+
"cn.ts"
|
|
42
|
+
],
|
|
43
|
+
"peerDependencies": [
|
|
44
|
+
"clsx",
|
|
45
|
+
"tailwind-merge",
|
|
46
|
+
"lucide-react"
|
|
47
|
+
],
|
|
48
|
+
"supportsCategory": true
|
|
49
|
+
},
|
|
50
|
+
"form/checkbox-group": {
|
|
51
|
+
"name": "CheckboxGroup",
|
|
52
|
+
"category": "form",
|
|
53
|
+
"files": [
|
|
54
|
+
"templates/form/checkbox-group.tsx"
|
|
55
|
+
],
|
|
56
|
+
"utils": [
|
|
57
|
+
"cn.ts"
|
|
58
|
+
],
|
|
59
|
+
"peerDependencies": [
|
|
60
|
+
"clsx",
|
|
61
|
+
"tailwind-merge"
|
|
62
|
+
],
|
|
63
|
+
"dependencies": [
|
|
64
|
+
"form/checkbox"
|
|
65
|
+
],
|
|
66
|
+
"supportsCategory": true
|
|
67
|
+
},
|
|
68
|
+
"form/date-picker": {
|
|
69
|
+
"name": "DatePicker",
|
|
70
|
+
"category": "form",
|
|
71
|
+
"files": [
|
|
72
|
+
"templates/form/date-picker.tsx"
|
|
73
|
+
],
|
|
74
|
+
"utils": [
|
|
75
|
+
"cn.ts"
|
|
76
|
+
],
|
|
77
|
+
"peerDependencies": [
|
|
78
|
+
"clsx",
|
|
79
|
+
"tailwind-merge",
|
|
80
|
+
"lucide-react",
|
|
81
|
+
"@floating-ui/react"
|
|
82
|
+
],
|
|
83
|
+
"dependencies": [
|
|
84
|
+
"dropdown/select-input"
|
|
85
|
+
],
|
|
86
|
+
"supportsCategory": true
|
|
87
|
+
},
|
|
88
|
+
"form/date-range-picker": {
|
|
89
|
+
"name": "DateRangePicker",
|
|
90
|
+
"category": "form",
|
|
91
|
+
"files": [
|
|
92
|
+
"templates/form/date-range-picker.tsx"
|
|
93
|
+
],
|
|
94
|
+
"utils": [
|
|
95
|
+
"cn.ts"
|
|
96
|
+
],
|
|
97
|
+
"peerDependencies": [
|
|
98
|
+
"clsx",
|
|
99
|
+
"tailwind-merge",
|
|
100
|
+
"lucide-react",
|
|
101
|
+
"@floating-ui/react"
|
|
102
|
+
],
|
|
103
|
+
"dependencies": [
|
|
104
|
+
"dropdown/select-input"
|
|
105
|
+
],
|
|
106
|
+
"supportsCategory": true
|
|
107
|
+
},
|
|
108
|
+
"form/email-input": {
|
|
109
|
+
"name": "EmailInput",
|
|
110
|
+
"category": "form",
|
|
111
|
+
"files": [
|
|
112
|
+
"templates/form/email-input.tsx"
|
|
113
|
+
],
|
|
114
|
+
"utils": [
|
|
115
|
+
"cn.ts"
|
|
116
|
+
],
|
|
117
|
+
"peerDependencies": [
|
|
118
|
+
"clsx",
|
|
119
|
+
"tailwind-merge",
|
|
120
|
+
"lucide-react"
|
|
121
|
+
],
|
|
122
|
+
"supportsCategory": true
|
|
123
|
+
},
|
|
124
|
+
"form/file-input": {
|
|
125
|
+
"name": "FileInput",
|
|
126
|
+
"category": "form",
|
|
127
|
+
"files": [
|
|
128
|
+
"templates/form/file-input.tsx"
|
|
129
|
+
],
|
|
130
|
+
"utils": [
|
|
131
|
+
"cn.ts"
|
|
132
|
+
],
|
|
133
|
+
"peerDependencies": [
|
|
134
|
+
"clsx",
|
|
135
|
+
"tailwind-merge",
|
|
136
|
+
"lucide-react"
|
|
137
|
+
],
|
|
138
|
+
"supportsCategory": true
|
|
139
|
+
},
|
|
140
|
+
"form/number-input": {
|
|
141
|
+
"name": "NumberInput",
|
|
142
|
+
"category": "form",
|
|
143
|
+
"files": [
|
|
144
|
+
"templates/form/number-input.tsx"
|
|
145
|
+
],
|
|
146
|
+
"utils": [
|
|
147
|
+
"cn.ts"
|
|
148
|
+
],
|
|
149
|
+
"peerDependencies": [
|
|
150
|
+
"clsx",
|
|
151
|
+
"tailwind-merge",
|
|
152
|
+
"lucide-react"
|
|
153
|
+
],
|
|
154
|
+
"supportsCategory": true
|
|
155
|
+
},
|
|
156
|
+
"form/password-input": {
|
|
157
|
+
"name": "PasswordInput",
|
|
158
|
+
"category": "form",
|
|
159
|
+
"files": [
|
|
160
|
+
"templates/form/password-input.tsx"
|
|
161
|
+
],
|
|
162
|
+
"utils": [
|
|
163
|
+
"cn.ts"
|
|
164
|
+
],
|
|
165
|
+
"peerDependencies": [
|
|
166
|
+
"clsx",
|
|
167
|
+
"tailwind-merge",
|
|
168
|
+
"lucide-react"
|
|
169
|
+
],
|
|
170
|
+
"supportsCategory": true
|
|
171
|
+
},
|
|
172
|
+
"form/phone-input": {
|
|
173
|
+
"name": "PhoneInput",
|
|
174
|
+
"category": "form",
|
|
175
|
+
"files": [
|
|
176
|
+
"templates/form/phone-input.tsx"
|
|
177
|
+
],
|
|
178
|
+
"utils": [
|
|
179
|
+
"cn.ts"
|
|
180
|
+
],
|
|
181
|
+
"peerDependencies": [
|
|
182
|
+
"clsx",
|
|
183
|
+
"tailwind-merge",
|
|
184
|
+
"lucide-react"
|
|
185
|
+
],
|
|
186
|
+
"supportsCategory": true
|
|
187
|
+
},
|
|
188
|
+
"form/radio": {
|
|
189
|
+
"name": "Radio",
|
|
190
|
+
"category": "form",
|
|
191
|
+
"files": [
|
|
192
|
+
"templates/form/radio.tsx"
|
|
193
|
+
],
|
|
194
|
+
"utils": [
|
|
195
|
+
"cn.ts"
|
|
196
|
+
],
|
|
197
|
+
"peerDependencies": [
|
|
198
|
+
"clsx",
|
|
199
|
+
"tailwind-merge"
|
|
200
|
+
],
|
|
201
|
+
"supportsCategory": true
|
|
202
|
+
},
|
|
203
|
+
"form/radio-group": {
|
|
204
|
+
"name": "RadioGroup",
|
|
205
|
+
"category": "form",
|
|
206
|
+
"files": [
|
|
207
|
+
"templates/form/radio-group.tsx"
|
|
208
|
+
],
|
|
209
|
+
"utils": [
|
|
210
|
+
"cn.ts"
|
|
211
|
+
],
|
|
212
|
+
"peerDependencies": [
|
|
213
|
+
"clsx",
|
|
214
|
+
"tailwind-merge"
|
|
215
|
+
],
|
|
216
|
+
"dependencies": [
|
|
217
|
+
"form/radio"
|
|
218
|
+
],
|
|
219
|
+
"supportsCategory": true
|
|
220
|
+
},
|
|
221
|
+
"form/range-slider": {
|
|
222
|
+
"name": "RangeSlider",
|
|
223
|
+
"category": "form",
|
|
224
|
+
"files": [
|
|
225
|
+
"templates/form/range-slider.tsx"
|
|
226
|
+
],
|
|
227
|
+
"utils": [
|
|
228
|
+
"cn.ts"
|
|
229
|
+
],
|
|
230
|
+
"peerDependencies": [
|
|
231
|
+
"clsx",
|
|
232
|
+
"tailwind-merge"
|
|
233
|
+
],
|
|
234
|
+
"supportsCategory": true
|
|
235
|
+
},
|
|
236
|
+
"form/switch": {
|
|
237
|
+
"name": "Switch",
|
|
238
|
+
"category": "form",
|
|
239
|
+
"files": [
|
|
240
|
+
"templates/form/switch.tsx"
|
|
241
|
+
],
|
|
242
|
+
"utils": [
|
|
243
|
+
"cn.ts"
|
|
244
|
+
],
|
|
245
|
+
"peerDependencies": [
|
|
246
|
+
"clsx",
|
|
247
|
+
"tailwind-merge"
|
|
248
|
+
],
|
|
249
|
+
"supportsCategory": true
|
|
250
|
+
},
|
|
251
|
+
"form/textarea": {
|
|
252
|
+
"name": "Textarea",
|
|
253
|
+
"category": "form",
|
|
254
|
+
"files": [
|
|
255
|
+
"templates/form/textarea.tsx"
|
|
256
|
+
],
|
|
257
|
+
"utils": [
|
|
258
|
+
"cn.ts"
|
|
259
|
+
],
|
|
260
|
+
"peerDependencies": [
|
|
261
|
+
"clsx",
|
|
262
|
+
"tailwind-merge"
|
|
263
|
+
],
|
|
264
|
+
"supportsCategory": true
|
|
265
|
+
},
|
|
266
|
+
"form/time-picker": {
|
|
267
|
+
"name": "TimePicker",
|
|
268
|
+
"category": "form",
|
|
269
|
+
"files": [
|
|
270
|
+
"templates/form/time-picker.tsx"
|
|
271
|
+
],
|
|
272
|
+
"utils": [
|
|
273
|
+
"cn.ts"
|
|
274
|
+
],
|
|
275
|
+
"peerDependencies": [
|
|
276
|
+
"clsx",
|
|
277
|
+
"tailwind-merge",
|
|
278
|
+
"lucide-react",
|
|
279
|
+
"@floating-ui/react"
|
|
280
|
+
],
|
|
281
|
+
"dependencies": [
|
|
282
|
+
"dropdown/select-input"
|
|
283
|
+
],
|
|
284
|
+
"supportsCategory": true
|
|
285
|
+
},
|
|
286
|
+
"form/time-range-picker": {
|
|
287
|
+
"name": "TimeRangePicker",
|
|
288
|
+
"category": "form",
|
|
289
|
+
"files": [
|
|
290
|
+
"templates/form/time-range-picker.tsx"
|
|
291
|
+
],
|
|
292
|
+
"utils": [
|
|
293
|
+
"cn.ts"
|
|
294
|
+
],
|
|
295
|
+
"peerDependencies": [
|
|
296
|
+
"clsx",
|
|
297
|
+
"tailwind-merge",
|
|
298
|
+
"lucide-react",
|
|
299
|
+
"@floating-ui/react"
|
|
300
|
+
],
|
|
301
|
+
"dependencies": [
|
|
302
|
+
"dropdown/select-input"
|
|
303
|
+
],
|
|
304
|
+
"supportsCategory": true
|
|
305
|
+
},
|
|
306
|
+
"form/url-input": {
|
|
307
|
+
"name": "UrlInput",
|
|
308
|
+
"category": "form",
|
|
309
|
+
"files": [
|
|
310
|
+
"templates/form/url-input.tsx"
|
|
311
|
+
],
|
|
312
|
+
"utils": [
|
|
313
|
+
"cn.ts"
|
|
314
|
+
],
|
|
315
|
+
"peerDependencies": [
|
|
316
|
+
"clsx",
|
|
317
|
+
"tailwind-merge",
|
|
318
|
+
"lucide-react"
|
|
319
|
+
],
|
|
320
|
+
"supportsCategory": true
|
|
321
|
+
}
|
|
322
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"layouts/lv1": {
|
|
3
|
+
"name": "AppLayout",
|
|
4
|
+
"category": "layouts",
|
|
5
|
+
"files": [
|
|
6
|
+
"templates/layouts/lv1/app-layout.tsx",
|
|
7
|
+
"templates/layouts/lv1/sidebar-menu.tsx",
|
|
8
|
+
"templates/layouts/lv1/index.ts"
|
|
9
|
+
],
|
|
10
|
+
"utils": ["cn.ts"],
|
|
11
|
+
"peerDependencies": [
|
|
12
|
+
"clsx",
|
|
13
|
+
"tailwind-merge",
|
|
14
|
+
"lucide-react"
|
|
15
|
+
],
|
|
16
|
+
"supportsCategory": true
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tanstack-query-client": {
|
|
3
|
+
"name": "TanstackQueryClient",
|
|
4
|
+
"category": "scaffold",
|
|
5
|
+
"subcategory": "tanstack-query",
|
|
6
|
+
"targetDirName": "tanstack-query",
|
|
7
|
+
"files": [
|
|
8
|
+
"templates/scaffolds/tanstack-query"
|
|
9
|
+
],
|
|
10
|
+
"peerDependencies": [
|
|
11
|
+
"@tanstack/react-query"
|
|
12
|
+
],
|
|
13
|
+
"supportsCategory": true
|
|
14
|
+
},
|
|
15
|
+
"react-router-client": {
|
|
16
|
+
"name": "ReactRouterClient",
|
|
17
|
+
"category": "scaffold",
|
|
18
|
+
"subcategory": "react-router",
|
|
19
|
+
"targetDirName": "react-router",
|
|
20
|
+
"files": [
|
|
21
|
+
"templates/scaffolds/react-router"
|
|
22
|
+
],
|
|
23
|
+
"peerDependencies": [
|
|
24
|
+
"react-router-dom"
|
|
25
|
+
],
|
|
26
|
+
"supportsCategory": true
|
|
27
|
+
},
|
|
28
|
+
"tanstack-router-client": {
|
|
29
|
+
"name": "TanstackRouterClient",
|
|
30
|
+
"category": "scaffold",
|
|
31
|
+
"subcategory": "tanstack-router",
|
|
32
|
+
"targetDirName": "tanstack-router",
|
|
33
|
+
"files": [
|
|
34
|
+
"templates/scaffolds/tanstack-router"
|
|
35
|
+
],
|
|
36
|
+
"peerDependencies": [
|
|
37
|
+
"@tanstack/react-router"
|
|
38
|
+
],
|
|
39
|
+
"supportsCategory": true
|
|
40
|
+
},
|
|
41
|
+
"axios-client": {
|
|
42
|
+
"name": "AxiosClient",
|
|
43
|
+
"category": "scaffold",
|
|
44
|
+
"subcategory": "axios",
|
|
45
|
+
"targetDirName": "axios",
|
|
46
|
+
"files": [
|
|
47
|
+
"templates/scaffolds/axios"
|
|
48
|
+
],
|
|
49
|
+
"peerDependencies": [
|
|
50
|
+
"axios"
|
|
51
|
+
],
|
|
52
|
+
"supportsCategory": true
|
|
53
|
+
},
|
|
54
|
+
"redux-store-client": {
|
|
55
|
+
"name": "ReduxStoreClient",
|
|
56
|
+
"category": "scaffold",
|
|
57
|
+
"subcategory": "redux-store",
|
|
58
|
+
"targetDirName": "redux-store",
|
|
59
|
+
"files": [
|
|
60
|
+
"templates/scaffolds/redux-store"
|
|
61
|
+
],
|
|
62
|
+
"peerDependencies": [
|
|
63
|
+
"@reduxjs/toolkit",
|
|
64
|
+
"react-redux",
|
|
65
|
+
"redux-persist"
|
|
66
|
+
],
|
|
67
|
+
"supportsCategory": true
|
|
68
|
+
},
|
|
69
|
+
"rtk-query-client": {
|
|
70
|
+
"name": "RtkQueryClient",
|
|
71
|
+
"category": "scaffold",
|
|
72
|
+
"subcategory": "rtk-query",
|
|
73
|
+
"targetDirName": "rtk-query",
|
|
74
|
+
"files": [
|
|
75
|
+
"templates/scaffolds/rtk-query"
|
|
76
|
+
],
|
|
77
|
+
"peerDependencies": [
|
|
78
|
+
"@reduxjs/toolkit",
|
|
79
|
+
"react-redux"
|
|
80
|
+
],
|
|
81
|
+
"supportsCategory": true
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./portal";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createPortal } from "react-dom";
|
|
2
|
+
import { useEffect, useState, type ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
interface PortalProps {
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export function Portal({ children }: PortalProps) {
|
|
8
|
+
const [container, setContainer] = useState<HTMLDivElement | null>(null);
|
|
9
|
+
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const div = document.createElement("div");
|
|
12
|
+
div.id = "dynamic-portal";
|
|
13
|
+
document.body.appendChild(div);
|
|
14
|
+
setContainer(div);
|
|
15
|
+
|
|
16
|
+
return () => {
|
|
17
|
+
if (div.parentNode) {
|
|
18
|
+
document.body.removeChild(div);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}, []);
|
|
22
|
+
|
|
23
|
+
if (!container) return null;
|
|
24
|
+
|
|
25
|
+
return createPortal(children, container);
|
|
26
|
+
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# Toast Notification Component
|
|
2
|
+
|
|
3
|
+
A toast notification system featuring:
|
|
4
|
+
- **Fully Customizable Styling**: Complete visual control over status designs.
|
|
5
|
+
- **Interactive Gestures**: Swipe-to-dismiss drag support for touch and pointer events.
|
|
6
|
+
- **Built-in Theme Presets**: Ready-to-use themes for Success, Error, Warning, and Info alerts.
|
|
7
|
+
- **Smart Timers**: Auto-dismiss timers that pause when the user hovers over a toast.
|
|
8
|
+
- **Custom Rendering**: Bypasses the default style to render custom React components and functions.
|
|
9
|
+
- **Transitions**: Smooth entry/exit animations (slide and fade transitions).
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. Setup
|
|
14
|
+
|
|
15
|
+
To use the toast notification system, place the `<ToastContainer />` at the root of your application (typically in `App.tsx` or `main.tsx`).
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { ToastContainer } from "@/pejay-ui/components/toast";
|
|
19
|
+
|
|
20
|
+
export default function App() {
|
|
21
|
+
return (
|
|
22
|
+
<>
|
|
23
|
+
{/* Your App Routing/Content */}
|
|
24
|
+
<ToastContainer placement="top-right" animationType="fade" />
|
|
25
|
+
</>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### `<ToastContainer />` Props
|
|
31
|
+
|
|
32
|
+
| Prop | Type | Default | Description |
|
|
33
|
+
| :--- | :--- | :--- | :--- |
|
|
34
|
+
| `placement` | `"top-right" \| "top-left" \| "bottom-right" \| "bottom-left"` | `"top-right"` | The screen corner where notifications will stack. |
|
|
35
|
+
| `animationType` | `"fade" \| "slide"` | `"fade"` | The entrance and exit transition animation style. Can also be passed as `animation-type`. |
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 2. Usage & API
|
|
40
|
+
|
|
41
|
+
Import the `toast` function from the module:
|
|
42
|
+
```ts
|
|
43
|
+
import { toast } from "@/pejay-ui/components/toast";
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Call Signatures
|
|
47
|
+
|
|
48
|
+
The status methods (`success`, `error`, `warning`, `info`) support two call signatures:
|
|
49
|
+
|
|
50
|
+
#### 1. Quick Message (String Only)
|
|
51
|
+
For displaying a single-line text message with default settings:
|
|
52
|
+
```ts
|
|
53
|
+
toast.success("All changes saved!");
|
|
54
|
+
```
|
|
55
|
+
You can also pass an optional configuration object as the second argument:
|
|
56
|
+
```ts
|
|
57
|
+
toast.error("An error occurred", { duration: 5000, showClose: false });
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
#### 2. Detailed Object Configuration
|
|
61
|
+
For full title and description control:
|
|
62
|
+
```ts
|
|
63
|
+
toast.warning({
|
|
64
|
+
title: "Low Disk Space",
|
|
65
|
+
description: "You have less than 10% space remaining.",
|
|
66
|
+
duration: 6000
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
### Shared Configuration Options (`ToastOptions`)
|
|
73
|
+
All toast methods accept an options object:
|
|
74
|
+
|
|
75
|
+
| Option | Type | Default | Description |
|
|
76
|
+
| :--- | :--- | :--- | :--- |
|
|
77
|
+
| `title` | `string` | — | Bold title text displayed in the toast. |
|
|
78
|
+
| `description` | `string` | — | Smaller detail text under the title. |
|
|
79
|
+
| `duration` | `number` | `4000` | Lifetime in milliseconds. Pass `Infinity` to disable auto-closing. |
|
|
80
|
+
| `showClose` | `boolean` | `true` | Whether to show the close cross button. |
|
|
81
|
+
| `dismiss` | `string` | — | An existing toast ID to dismiss before showing the new one. |
|
|
82
|
+
| `icon` | `React.ReactNode` | — | Custom React element to override the default status icon. |
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 3. Presets & Examples
|
|
87
|
+
|
|
88
|
+
### A. Success Toast
|
|
89
|
+
Use for successful operations (submitting forms, saves, payments).
|
|
90
|
+
```ts
|
|
91
|
+
toast.success({
|
|
92
|
+
title: "Payment Received",
|
|
93
|
+
description: "Your invoice #2093 has been paid successfully.",
|
|
94
|
+
duration: 4000,
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### B. Error Toast
|
|
99
|
+
Use for failed requests, validation errors, or application crashes.
|
|
100
|
+
```ts
|
|
101
|
+
toast.error({
|
|
102
|
+
title: "Upload Failed",
|
|
103
|
+
description: "The connection was lost. Please check your network and try again.",
|
|
104
|
+
duration: 6000,
|
|
105
|
+
showClose: true,
|
|
106
|
+
});
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### C. Warning Toast
|
|
110
|
+
Use for alerts, soft errors, or actions requiring user attention.
|
|
111
|
+
```ts
|
|
112
|
+
toast.warning({
|
|
113
|
+
title: "Unsaved Changes",
|
|
114
|
+
description: "Your work will be lost if you navigate away.",
|
|
115
|
+
duration: 5000,
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### D. Info Toast
|
|
120
|
+
Use for general system notices or status updates.
|
|
121
|
+
```ts
|
|
122
|
+
toast.info({
|
|
123
|
+
title: "System Maintenance",
|
|
124
|
+
description: "Scheduled maintenance will begin tonight at 12:00 AM EST.",
|
|
125
|
+
duration: Infinity, // Stays visible until manually closed
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## 4. Custom Toasts
|
|
132
|
+
|
|
133
|
+
For completely custom designs, use `toast.custom()`. This method bypasses default styling and allows you to render any React component.
|
|
134
|
+
|
|
135
|
+
### Custom Example with Manual Dismissal
|
|
136
|
+
You can pass a function to the `content` property. It receives the unique `id` of the toast, allowing you to trigger a manual dismiss from inside your custom UI:
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
toast.custom({
|
|
140
|
+
id: "my-custom-toast", // Optional custom string ID
|
|
141
|
+
duration: 10000, // 10 seconds
|
|
142
|
+
content: (id) => (
|
|
143
|
+
<div className="flex flex-col gap-3 p-4 w-full bg-slate-900 border border-violet-500/30 rounded-xl shadow-lg">
|
|
144
|
+
<div className="flex flex-col gap-1">
|
|
145
|
+
<h4 className="text-sm font-semibold text-white">Importing Contacts</h4>
|
|
146
|
+
<p className="text-xs text-slate-400">Please wait while we process your file.</p>
|
|
147
|
+
</div>
|
|
148
|
+
<div className="flex gap-2 justify-end">
|
|
149
|
+
<button
|
|
150
|
+
onClick={() => toast.dismiss(id)}
|
|
151
|
+
className="px-3 py-1 bg-violet-600 hover:bg-violet-700 text-xs font-semibold text-white rounded-md transition-colors"
|
|
152
|
+
>
|
|
153
|
+
Cancel Import
|
|
154
|
+
</button>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
)
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## 5. Dismissing Toasts
|
|
162
|
+
|
|
163
|
+
Toasts can be dismissed programmatically in two ways:
|
|
164
|
+
|
|
165
|
+
### 1. By ID via `toast.dismiss()`
|
|
166
|
+
You can manually trigger the removal of a toast at any time by calling `toast.dismiss(id)` with the ID returned when the toast was created:
|
|
167
|
+
```ts
|
|
168
|
+
// Trigger the toast and capture its generated ID
|
|
169
|
+
const toastId = toast.info("Uploading file...", { duration: Infinity });
|
|
170
|
+
|
|
171
|
+
// Dismiss it later (e.g. once the file upload succeeds)
|
|
172
|
+
toast.dismiss(toastId);
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### 2. Auto-Dismissing when Triggering a New Toast (via `dismiss` option)
|
|
176
|
+
You can automatically dismiss an active toast by passing its ID in the `dismiss` option of a new toast. This is useful for transitioning states (e.g., from a loading state to a success/error state):
|
|
177
|
+
```ts
|
|
178
|
+
// 1. Show loading toast with a fixed ID
|
|
179
|
+
toast.info("Saving changes...", { id: "saving-progress" });
|
|
180
|
+
|
|
181
|
+
// 2. Trigger success toast, which dismisses "saving-progress" before rendering
|
|
182
|
+
toast.success("All changes saved!", { dismiss: "saving-progress" });
|
|
183
|
+
```
|