@choice-ui/react 1.6.8 → 1.7.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.
Files changed (81) hide show
  1. package/dist/components/description/dist/index.d.ts +8 -0
  2. package/dist/components/description/dist/index.js +29 -0
  3. package/dist/components/description/src/description.d.ts +6 -0
  4. package/dist/components/description/src/description.js +18 -0
  5. package/dist/components/description/src/index.d.ts +2 -0
  6. package/dist/components/description/src/tv.d.ts +13 -0
  7. package/dist/components/description/src/tv.js +15 -0
  8. package/dist/components/description/tsup.config.d.ts +2 -0
  9. package/dist/components/emoji-picker/dist/index.d.ts +1 -0
  10. package/dist/components/emoji-picker/dist/index.js +4 -2
  11. package/dist/components/emoji-picker/src/emoji-picker.d.ts +1 -0
  12. package/dist/components/emoji-picker/src/emoji-picker.js +4 -2
  13. package/dist/components/error-message/dist/index.d.ts +8 -0
  14. package/dist/components/error-message/dist/index.js +30 -0
  15. package/dist/components/error-message/src/error-message.d.ts +6 -0
  16. package/dist/components/error-message/src/error-message.js +19 -0
  17. package/dist/components/error-message/src/index.d.ts +2 -0
  18. package/dist/components/error-message/src/tv.d.ts +13 -0
  19. package/dist/components/error-message/src/tv.js +15 -0
  20. package/dist/components/error-message/tsup.config.d.ts +2 -0
  21. package/dist/components/form/src/adapters/base-adapter.js +4 -2
  22. package/dist/components/form/src/tv.d.ts +0 -12
  23. package/dist/components/form/src/tv.js +1 -13
  24. package/dist/components/index.d.ts +3 -0
  25. package/dist/components/md-render/dist/index.d.ts +2 -1
  26. package/dist/components/md-render/dist/index.js +3 -1
  27. package/dist/components/md-render/src/md-render.js +3 -1
  28. package/dist/components/md-render/src/types.d.ts +2 -1
  29. package/dist/components/notifications/dist/index.d.ts +1 -5
  30. package/dist/components/notifications/src/notifications.d.ts +0 -1
  31. package/dist/components/notifications/src/notifications.js +0 -1
  32. package/dist/components/numeric-input/dist/index.d.ts +23 -9
  33. package/dist/components/numeric-input/dist/index.js +26 -3
  34. package/dist/components/numeric-input/src/components/numeric-input-menu-trigger.js +4 -1
  35. package/dist/components/numeric-input/src/hooks/index.d.ts +1 -0
  36. package/dist/components/numeric-input/src/hooks/use-numeric-long-press.d.ts +13 -0
  37. package/dist/components/numeric-input/src/hooks/use-numeric-long-press.js +27 -0
  38. package/dist/components/numeric-input/src/index.d.ts +1 -0
  39. package/dist/components/numeric-input/src/tv.js +22 -2
  40. package/dist/components/picture-preview/dist/index.d.ts +5 -0
  41. package/dist/components/picture-preview/dist/index.js +287 -140
  42. package/dist/components/picture-preview/src/hooks/useWheelHandler.d.ts +6 -1
  43. package/dist/components/picture-preview/src/hooks/useWheelHandler.js +25 -7
  44. package/dist/components/picture-preview/src/picture-preview.d.ts +5 -0
  45. package/dist/components/picture-preview/src/picture-preview.js +214 -123
  46. package/dist/components/picture-preview/src/tv.d.ts +93 -3
  47. package/dist/components/picture-preview/src/tv.js +48 -10
  48. package/dist/components/separator/dist/index.d.ts +1 -8
  49. package/dist/components/separator/src/separator.d.ts +1 -8
  50. package/dist/components/separator/src/separator.js +33 -5
  51. package/dist/components/separator/src/tv.d.ts +39 -18
  52. package/dist/components/separator/src/tv.js +37 -7
  53. package/dist/components/text-field/dist/index.d.ts +2 -3
  54. package/dist/components/text-field/dist/index.js +4 -19
  55. package/dist/components/text-field/src/components/index.d.ts +0 -1
  56. package/dist/components/text-field/src/text-field.d.ts +3 -2
  57. package/dist/components/text-field/src/text-field.js +2 -2
  58. package/dist/components/text-field/src/tv.d.ts +3 -3
  59. package/dist/components/text-field/src/tv.js +1 -6
  60. package/dist/components/toast/dist/index.d.ts +260 -0
  61. package/dist/components/toast/src/components/index.d.ts +3 -0
  62. package/dist/components/toast/src/components/toast-progress-bar.d.ts +7 -0
  63. package/dist/components/toast/src/components/toast-progress-bar.js +53 -0
  64. package/dist/components/toast/src/components/toaster-item.d.ts +26 -0
  65. package/dist/components/toast/src/components/toaster-item.js +412 -0
  66. package/dist/components/toast/src/components/toaster-slots.d.ts +87 -0
  67. package/dist/components/toast/src/components/toaster-slots.js +38 -0
  68. package/dist/components/toast/src/index.d.ts +5 -0
  69. package/dist/components/toast/src/store.d.ts +113 -0
  70. package/dist/components/toast/src/store.js +204 -0
  71. package/dist/components/toast/src/toaster.d.ts +87 -0
  72. package/dist/components/toast/src/toaster.js +271 -0
  73. package/dist/components/toast/src/tv.d.ts +365 -0
  74. package/dist/components/toast/src/tv.js +412 -0
  75. package/dist/components/toast/src/types.d.ts +79 -0
  76. package/dist/components/toast/tsup.config.d.ts +2 -0
  77. package/dist/index.js +11 -2
  78. package/dist/styles/components.css +2 -0
  79. package/package.json +1 -1
  80. package/dist/components/text-field/src/components/field-description.d.ts +0 -2
  81. package/dist/components/text-field/src/components/field-description.js +0 -16
@@ -0,0 +1,412 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { RemoveSmall, LoaderCircle, CircleInfoLargeSolid, CircleWarningLargeSolid, CircleErrorSolid, CircleCheckLargeSolid } from "@choiceform/icons-react";
3
+ import { motion } from "framer-motion";
4
+ import { memo, forwardRef, useId, useRef, useState, useMemo, useEffect } from "react";
5
+ import { useEventCallback } from "usehooks-ts";
6
+ import { dismiss, updateHeight } from "../store.js";
7
+ import { toastRootTv } from "../tv.js";
8
+ import { ToastProgressBar } from "./toast-progress-bar.js";
9
+ import { tcx } from "../../../../shared/utils/tcx/tcx.js";
10
+ import { mergeRefs } from "../../../../shared/utils/merge-refs/merge-refs.js";
11
+ const GAP = 12;
12
+ const DEFAULT_HEIGHT = 56;
13
+ const SWIPE_THRESHOLD = 56;
14
+ const ANIMATION_CONFIG = {
15
+ default: {
16
+ type: "spring",
17
+ stiffness: 150,
18
+ damping: 20,
19
+ mass: 1
20
+ },
21
+ opacity: {
22
+ type: "tween",
23
+ duration: 0.35,
24
+ ease: "easeOut"
25
+ }
26
+ };
27
+ const SuccessIcon = memo(() => /* @__PURE__ */ jsx(CircleCheckLargeSolid, {}));
28
+ SuccessIcon.displayName = "SuccessIcon";
29
+ const ErrorIcon = memo(() => /* @__PURE__ */ jsx(CircleErrorSolid, {}));
30
+ ErrorIcon.displayName = "ErrorIcon";
31
+ const WarningIcon = memo(() => /* @__PURE__ */ jsx(CircleWarningLargeSolid, {}));
32
+ WarningIcon.displayName = "WarningIcon";
33
+ const InfoIcon = memo(() => /* @__PURE__ */ jsx(CircleInfoLargeSolid, {}));
34
+ InfoIcon.displayName = "InfoIcon";
35
+ const LoadingIcon = memo(() => /* @__PURE__ */ jsx(LoaderCircle, { className: "animate-spin" }));
36
+ LoadingIcon.displayName = "LoadingIcon";
37
+ const TOAST_ICONS = {
38
+ success: /* @__PURE__ */ jsx(SuccessIcon, {}),
39
+ error: /* @__PURE__ */ jsx(ErrorIcon, {}),
40
+ warning: /* @__PURE__ */ jsx(WarningIcon, {}),
41
+ info: /* @__PURE__ */ jsx(InfoIcon, {}),
42
+ loading: /* @__PURE__ */ jsx(LoadingIcon, {}),
43
+ default: null
44
+ };
45
+ function getToastIcon(type) {
46
+ return TOAST_ICONS[type] ?? null;
47
+ }
48
+ const HTML_TAG_REGEX = /<[a-z][\s\S]*>/i;
49
+ function isHtmlString(content) {
50
+ return typeof content === "string" && HTML_TAG_REGEX.test(content);
51
+ }
52
+ const ToasterItem = memo(
53
+ forwardRef(function ToasterItem2({
54
+ toast,
55
+ index,
56
+ total,
57
+ expanded,
58
+ position,
59
+ toasterId,
60
+ toastHeights,
61
+ slotProps,
62
+ showProgress = false,
63
+ defaultDuration = 5e3,
64
+ isPaused = false,
65
+ layout = "default"
66
+ }, ref) {
67
+ const titleId = useId();
68
+ const descriptionId = useId();
69
+ const rootRef = useRef(null);
70
+ const [isSwiping, setIsSwiping] = useState(false);
71
+ const [swipeOffset, setSwipeOffset] = useState({ x: 0, y: 0 });
72
+ const [swipeDirection, setSwipeDirection] = useState(null);
73
+ const swipeStartRef = useRef(null);
74
+ const toastDuration = toast.duration ?? defaultDuration;
75
+ const shouldShowProgress = showProgress && toastDuration > 0 && toast.type !== "loading";
76
+ const offsetY = useMemo(() => {
77
+ if (expanded) {
78
+ let offset = 0;
79
+ for (let i = 0; i < index; i++) {
80
+ offset += (toastHeights[i] ?? DEFAULT_HEIGHT) + GAP;
81
+ }
82
+ return offset;
83
+ }
84
+ return index * 8;
85
+ }, [expanded, index, toastHeights]);
86
+ useEffect(() => {
87
+ const node = rootRef.current;
88
+ if (!node) return;
89
+ let rafId = null;
90
+ let lastHeight = 0;
91
+ const measureHeight = () => {
92
+ if (rafId !== null) {
93
+ cancelAnimationFrame(rafId);
94
+ }
95
+ rafId = requestAnimationFrame(() => {
96
+ const height = node.offsetHeight;
97
+ if (height > 0 && height !== lastHeight) {
98
+ lastHeight = height;
99
+ updateHeight(toast.id, height, toasterId);
100
+ }
101
+ rafId = null;
102
+ });
103
+ };
104
+ measureHeight();
105
+ const resizeObserver = new ResizeObserver(measureHeight);
106
+ resizeObserver.observe(node);
107
+ return () => {
108
+ resizeObserver.disconnect();
109
+ if (rafId !== null) {
110
+ cancelAnimationFrame(rafId);
111
+ }
112
+ };
113
+ }, [toast.id, toasterId]);
114
+ const close = useEventCallback((_direction) => {
115
+ dismiss(toast.id, toasterId);
116
+ });
117
+ const handleKeyDown = useEventCallback((e) => {
118
+ if (e.key === "Escape") {
119
+ e.preventDefault();
120
+ close();
121
+ }
122
+ });
123
+ const handlePointerDown = useEventCallback((e) => {
124
+ const target = e.target;
125
+ if (target.closest("button, a, input, [role='button']")) {
126
+ return;
127
+ }
128
+ swipeStartRef.current = { x: e.clientX, y: e.clientY };
129
+ setSwipeDirection(null);
130
+ target.setPointerCapture(e.pointerId);
131
+ });
132
+ const handlePointerMove = useEventCallback((e) => {
133
+ if (!swipeStartRef.current) return;
134
+ const deltaX = e.clientX - swipeStartRef.current.x;
135
+ const deltaY = e.clientY - swipeStartRef.current.y;
136
+ const isVerticalPosition = position === "top-center" || position === "bottom-center";
137
+ if (isVerticalPosition) {
138
+ const absDeltaY = Math.abs(deltaY);
139
+ if (!isSwiping && absDeltaY > 10) {
140
+ setIsSwiping(true);
141
+ }
142
+ if (isSwiping) {
143
+ setSwipeDirection(deltaY > 0 ? "down" : "up");
144
+ setSwipeOffset({ x: 0, y: deltaY });
145
+ }
146
+ } else {
147
+ const absDeltaX = Math.abs(deltaX);
148
+ if (!isSwiping && absDeltaX > 10) {
149
+ setIsSwiping(true);
150
+ }
151
+ if (isSwiping) {
152
+ setSwipeDirection(deltaX > 0 ? "right" : "left");
153
+ setSwipeOffset({ x: deltaX, y: 0 });
154
+ }
155
+ }
156
+ });
157
+ const handlePointerUp = useEventCallback((e) => {
158
+ if (!swipeStartRef.current) return;
159
+ const target = e.target;
160
+ target.releasePointerCapture(e.pointerId);
161
+ const isVerticalPosition = position === "top-center" || position === "bottom-center";
162
+ const swipeDistance = isVerticalPosition ? Math.abs(swipeOffset.y) : Math.abs(swipeOffset.x);
163
+ if (swipeDistance > SWIPE_THRESHOLD && swipeDirection) {
164
+ close(swipeDirection);
165
+ } else {
166
+ setSwipeOffset({ x: 0, y: 0 });
167
+ }
168
+ swipeStartRef.current = null;
169
+ setIsSwiping(false);
170
+ });
171
+ const handlePointerCancel = useEventCallback((e) => {
172
+ const target = e.target;
173
+ target.releasePointerCapture(e.pointerId);
174
+ swipeStartRef.current = null;
175
+ setIsSwiping(false);
176
+ setSwipeOffset({ x: 0, y: 0 });
177
+ setSwipeDirection(null);
178
+ });
179
+ const displayIcon = getToastIcon(toast.type);
180
+ const isBehind = index > 0 && !expanded;
181
+ const isTop = position.startsWith("top");
182
+ const scale = expanded ? 1 : Math.max(0, 1 - index * 0.05);
183
+ const yPosition = useMemo(() => {
184
+ const swipeY = swipeOffset.y;
185
+ if (expanded) {
186
+ return isTop ? offsetY + swipeY : -offsetY + swipeY;
187
+ }
188
+ const peek = 8;
189
+ const shrink = 1 - scale;
190
+ const height = toast.height || 0;
191
+ const peekOffset = index * peek;
192
+ const shrinkOffset = shrink * height;
193
+ return isTop ? peekOffset + shrinkOffset + swipeY : -(peekOffset + shrinkOffset) + swipeY;
194
+ }, [expanded, isTop, offsetY, swipeOffset.y, scale, toast.height, index]);
195
+ const stackOpacity = useMemo(() => {
196
+ if (expanded) return 1;
197
+ return Math.max(0, 1 - index * 0.2);
198
+ }, [expanded, index]);
199
+ const enterExitY = isTop ? -100 : 100;
200
+ const exitAnimation = useMemo(() => {
201
+ const dir = swipeDirection || toast.swipeDirection;
202
+ const exitBase = { opacity: 0, zIndex: -1, filter: "blur(4px)" };
203
+ if (dir === "right") return { ...exitBase, x: "100%" };
204
+ if (dir === "left") return { ...exitBase, x: "-100%" };
205
+ if (dir === "up") return { ...exitBase, y: "-100%" };
206
+ if (dir === "down") return { ...exitBase, y: "100%" };
207
+ return exitBase;
208
+ }, [swipeDirection, toast.swipeDirection]);
209
+ const tv = useMemo(
210
+ () => toastRootTv({
211
+ layout,
212
+ type: toast.type,
213
+ position,
214
+ hasActions: !!toast.action || !!toast.cancel,
215
+ hasDescription: !!toast.description,
216
+ hasIcon: !!displayIcon,
217
+ behind: isBehind,
218
+ expanded,
219
+ variant: toast.variant
220
+ }),
221
+ [
222
+ layout,
223
+ toast.type,
224
+ position,
225
+ toast.action,
226
+ toast.cancel,
227
+ toast.description,
228
+ displayIcon,
229
+ isBehind,
230
+ expanded,
231
+ toast.variant
232
+ ]
233
+ );
234
+ const zIndex = total - index;
235
+ const compactProgress = layout === "compact" && shouldShowProgress;
236
+ const combinedStyle = useMemo(() => {
237
+ const backgroundColorMap = compactProgress ? {
238
+ default: "var(--color-gray-800)",
239
+ accent: "var(--color-accent-hover-background)",
240
+ success: "var(--color-success-hover-background)",
241
+ warning: "var(--color-warning-hover-background)",
242
+ error: "var(--color-danger-hover-background)",
243
+ assistive: "var(--color-assistive-hover-background)"
244
+ } : {
245
+ default: "var(--color-menu-background)",
246
+ accent: "var(--color-accent-background)",
247
+ success: "var(--color-success-background)",
248
+ warning: "var(--color-warning-background)",
249
+ error: "var(--color-danger-background)",
250
+ assistive: "var(--color-assistive-background)"
251
+ };
252
+ const bgColor = backgroundColorMap[toast.variant ?? "default"] ?? "var(--color-menu-background)";
253
+ return {
254
+ "--toast-index": index,
255
+ "--toast-opacity": `${stackOpacity * 100}%`,
256
+ "--toast-background-color": `color-mix(in srgb, ${bgColor} var(--toast-opacity), var(--color-default-background))`,
257
+ "--toast-gap": `${GAP}px`,
258
+ zIndex
259
+ };
260
+ }, [index, stackOpacity, zIndex, compactProgress, toast.variant]);
261
+ const handleActionClick = useEventCallback(() => {
262
+ var _a;
263
+ (_a = toast.action) == null ? void 0 : _a.onClick();
264
+ close();
265
+ });
266
+ const handleDismissClick = useEventCallback(() => {
267
+ close();
268
+ });
269
+ const { renderIcon, renderActions } = slotProps;
270
+ const iconContent = useMemo(() => {
271
+ if (renderIcon) {
272
+ return renderIcon(toast.type, displayIcon);
273
+ }
274
+ return displayIcon;
275
+ }, [renderIcon, toast.type, displayIcon]);
276
+ const titleContent = useMemo(() => {
277
+ if (!toast.title) return null;
278
+ return /* @__PURE__ */ jsx(
279
+ "div",
280
+ {
281
+ id: titleId,
282
+ className: tcx(tv.title(), slotProps.titleClassName),
283
+ style: slotProps.titleStyle,
284
+ ...isHtmlString(toast.title) ? { dangerouslySetInnerHTML: { __html: toast.title } } : { children: toast.title }
285
+ }
286
+ );
287
+ }, [toast.title, titleId, tv, slotProps.titleClassName, slotProps.titleStyle]);
288
+ const descriptionContent = useMemo(() => {
289
+ if (!toast.description) return null;
290
+ return /* @__PURE__ */ jsx(
291
+ "div",
292
+ {
293
+ id: descriptionId,
294
+ className: tcx(tv.description(), slotProps.descriptionClassName),
295
+ style: slotProps.descriptionStyle,
296
+ ...isHtmlString(toast.description) ? { dangerouslySetInnerHTML: { __html: toast.description } } : { children: toast.description }
297
+ }
298
+ );
299
+ }, [toast.description, descriptionId, tv, slotProps.descriptionClassName, slotProps.descriptionStyle]);
300
+ const actionsContent = useMemo(() => {
301
+ var _a;
302
+ if (!toast.action && !toast.cancel) return null;
303
+ if (renderActions) {
304
+ return renderActions(toast.action, toast.cancel, close);
305
+ }
306
+ return /* @__PURE__ */ jsxs(
307
+ "div",
308
+ {
309
+ className: tcx(tv.actions(), slotProps.actionsClassName),
310
+ style: slotProps.actionsStyle,
311
+ children: [
312
+ toast.action && /* @__PURE__ */ jsx(
313
+ "button",
314
+ {
315
+ type: "button",
316
+ className: tv.button({ buttonVariant: "action" }),
317
+ onClick: handleActionClick,
318
+ children: toast.action.label
319
+ }
320
+ ),
321
+ toast.cancel && /* @__PURE__ */ jsx(
322
+ "button",
323
+ {
324
+ type: "button",
325
+ className: tcx(tv.button({ buttonVariant: "cancel" })),
326
+ onClick: handleDismissClick,
327
+ children: layout === "default" ? (_a = toast.cancel) == null ? void 0 : _a.label : /* @__PURE__ */ jsx(RemoveSmall, {})
328
+ }
329
+ )
330
+ ]
331
+ }
332
+ );
333
+ }, [
334
+ renderActions,
335
+ toast.action,
336
+ toast.cancel,
337
+ close,
338
+ tv,
339
+ handleActionClick,
340
+ handleDismissClick,
341
+ slotProps.actionsClassName,
342
+ slotProps.actionsStyle
343
+ ]);
344
+ const mergedClassName = tcx(tv.root(), slotProps.itemClassName);
345
+ const mergedStyle = useMemo(() => {
346
+ if (slotProps.itemStyle) {
347
+ return { ...combinedStyle, ...slotProps.itemStyle };
348
+ }
349
+ return combinedStyle;
350
+ }, [combinedStyle, slotProps.itemStyle]);
351
+ return /* @__PURE__ */ jsxs(
352
+ motion.div,
353
+ {
354
+ ref: mergeRefs(rootRef, ref),
355
+ initial: { y: enterExitY },
356
+ animate: {
357
+ x: swipeOffset.x,
358
+ y: yPosition,
359
+ scale,
360
+ opacity: 1,
361
+ filter: "blur(0px)"
362
+ },
363
+ exit: exitAnimation,
364
+ transition: isSwiping ? { duration: 0 } : ANIMATION_CONFIG,
365
+ role: toast.type === "error" || toast.type === "warning" ? "alertdialog" : "status",
366
+ "aria-modal": "false",
367
+ "aria-labelledby": toast.title ? titleId : void 0,
368
+ "aria-describedby": toast.description ? descriptionId : void 0,
369
+ "aria-live": toast.type === "error" ? "assertive" : "polite",
370
+ tabIndex: 0,
371
+ "data-toast-root": true,
372
+ "data-type": toast.type,
373
+ className: mergedClassName,
374
+ style: mergedStyle,
375
+ onKeyDown: handleKeyDown,
376
+ onPointerDown: handlePointerDown,
377
+ onPointerMove: handlePointerMove,
378
+ onPointerUp: handlePointerUp,
379
+ onPointerCancel: handlePointerCancel,
380
+ children: [
381
+ /* @__PURE__ */ jsxs("div", { className: tv.content(), children: [
382
+ iconContent && /* @__PURE__ */ jsx(
383
+ "div",
384
+ {
385
+ className: tcx(tv.icon(), slotProps.iconClassName),
386
+ style: slotProps.iconStyle,
387
+ children: iconContent
388
+ }
389
+ ),
390
+ titleContent,
391
+ layout === "default" && descriptionContent,
392
+ shouldShowProgress && /* @__PURE__ */ jsx(
393
+ ToastProgressBar,
394
+ {
395
+ duration: toastDuration,
396
+ isPaused,
397
+ tv
398
+ }
399
+ )
400
+ ] }),
401
+ actionsContent
402
+ ]
403
+ }
404
+ );
405
+ })
406
+ );
407
+ ToasterItem.displayName = "ToasterItem";
408
+ export {
409
+ DEFAULT_HEIGHT,
410
+ GAP,
411
+ ToasterItem
412
+ };
@@ -0,0 +1,87 @@
1
+ import { ReactNode } from 'react';
2
+ import { ToastType } from '../types';
3
+ export interface ToastAction {
4
+ label: ReactNode;
5
+ onClick: () => void;
6
+ }
7
+ export interface ToastCancel {
8
+ label: ReactNode;
9
+ onClick?: () => void;
10
+ }
11
+ /**
12
+ * Props for Toaster.Item slot component
13
+ */
14
+ export interface ToasterItemSlotProps {
15
+ className?: string;
16
+ style?: React.CSSProperties;
17
+ children?: ReactNode;
18
+ }
19
+ /**
20
+ * Slot component for customizing toast item container
21
+ */
22
+ export declare const ToasterItemSlot: import('react').ForwardRefExoticComponent<ToasterItemSlotProps & import('react').RefAttributes<HTMLDivElement>>;
23
+ /**
24
+ * Props for Toaster.Icon slot component
25
+ */
26
+ export interface ToasterIconSlotProps {
27
+ className?: string;
28
+ style?: React.CSSProperties;
29
+ /** Custom render function - receives type and default icon */
30
+ children?: (type: ToastType, defaultIcon: ReactNode) => ReactNode;
31
+ }
32
+ /**
33
+ * Slot component for customizing toast icon
34
+ */
35
+ export declare const ToasterIconSlot: import('react').ForwardRefExoticComponent<ToasterIconSlotProps & import('react').RefAttributes<HTMLDivElement>>;
36
+ /**
37
+ * Props for Toaster.Title slot component
38
+ */
39
+ export interface ToasterTitleSlotProps {
40
+ className?: string;
41
+ style?: React.CSSProperties;
42
+ }
43
+ /**
44
+ * Slot component for customizing toast title
45
+ */
46
+ export declare const ToasterTitleSlot: import('react').ForwardRefExoticComponent<ToasterTitleSlotProps & import('react').RefAttributes<HTMLDivElement>>;
47
+ /**
48
+ * Props for Toaster.Description slot component
49
+ */
50
+ export interface ToasterDescriptionSlotProps {
51
+ className?: string;
52
+ style?: React.CSSProperties;
53
+ }
54
+ /**
55
+ * Slot component for customizing toast description
56
+ */
57
+ export declare const ToasterDescriptionSlot: import('react').ForwardRefExoticComponent<ToasterDescriptionSlotProps & import('react').RefAttributes<HTMLDivElement>>;
58
+ /**
59
+ * Props for Toaster.Actions slot component
60
+ */
61
+ export interface ToasterActionsSlotProps {
62
+ className?: string;
63
+ style?: React.CSSProperties;
64
+ /** Custom render function for actions */
65
+ children?: (action: ToastAction | undefined, cancel: ToastCancel | undefined, close: () => void) => ReactNode;
66
+ }
67
+ /**
68
+ * Slot component for customizing toast actions
69
+ */
70
+ export declare const ToasterActionsSlot: import('react').ForwardRefExoticComponent<ToasterActionsSlotProps & import('react').RefAttributes<HTMLDivElement>>;
71
+ /**
72
+ * Collected slot props from Toaster.Item children
73
+ */
74
+ export interface CollectedSlotProps {
75
+ itemClassName?: string;
76
+ itemStyle?: React.CSSProperties;
77
+ iconClassName?: string;
78
+ iconStyle?: React.CSSProperties;
79
+ renderIcon?: (type: ToastType, defaultIcon: ReactNode) => ReactNode;
80
+ titleClassName?: string;
81
+ titleStyle?: React.CSSProperties;
82
+ descriptionClassName?: string;
83
+ descriptionStyle?: React.CSSProperties;
84
+ actionsClassName?: string;
85
+ actionsStyle?: React.CSSProperties;
86
+ renderActions?: (action: ToastAction | undefined, cancel: ToastCancel | undefined, close: () => void) => ReactNode;
87
+ }
@@ -0,0 +1,38 @@
1
+ import { forwardRef } from "react";
2
+ const ToasterItemSlot = forwardRef(
3
+ function ToasterItemSlot2(_props, _ref) {
4
+ return null;
5
+ }
6
+ );
7
+ ToasterItemSlot.displayName = "Toaster.Item";
8
+ const ToasterIconSlot = forwardRef(
9
+ function ToasterIconSlot2(_props, _ref) {
10
+ return null;
11
+ }
12
+ );
13
+ ToasterIconSlot.displayName = "Toaster.Icon";
14
+ const ToasterTitleSlot = forwardRef(
15
+ function ToasterTitleSlot2(_props, _ref) {
16
+ return null;
17
+ }
18
+ );
19
+ ToasterTitleSlot.displayName = "Toaster.Title";
20
+ const ToasterDescriptionSlot = forwardRef(
21
+ function ToasterDescriptionSlot2(_props, _ref) {
22
+ return null;
23
+ }
24
+ );
25
+ ToasterDescriptionSlot.displayName = "Toaster.Description";
26
+ const ToasterActionsSlot = forwardRef(
27
+ function ToasterActionsSlot2(_props, _ref) {
28
+ return null;
29
+ }
30
+ );
31
+ ToasterActionsSlot.displayName = "Toaster.Actions";
32
+ export {
33
+ ToasterActionsSlot,
34
+ ToasterDescriptionSlot,
35
+ ToasterIconSlot,
36
+ ToasterItemSlot,
37
+ ToasterTitleSlot
38
+ };
@@ -0,0 +1,5 @@
1
+ export { Toaster } from './toaster';
2
+ export type { ToasterProps } from './toaster';
3
+ export { toast } from './store';
4
+ export type { ToastOptions, ToastData } from './store';
5
+ export type { ToastType, ToastVariant, ToastPosition } from './types';
@@ -0,0 +1,113 @@
1
+ import { ToastPosition, ToastType, ToastVariant } from './types';
2
+ export interface ToastData {
3
+ id: string;
4
+ type: ToastType;
5
+ variant?: ToastVariant;
6
+ /**
7
+ * Title content. Supports:
8
+ * - Plain string: rendered as text
9
+ * - HTML string (containing tags like `<b>`, `<strong>`, etc.): rendered as HTML
10
+ * - ReactNode: rendered as React component
11
+ */
12
+ title?: React.ReactNode;
13
+ /**
14
+ * Description content. Supports:
15
+ * - Plain string: rendered as text
16
+ * - HTML string (containing tags like `<b>`, `<strong>`, etc.): rendered as HTML
17
+ * - ReactNode: rendered as React component
18
+ */
19
+ description?: React.ReactNode;
20
+ duration?: number;
21
+ icon?: React.ReactNode;
22
+ action?: {
23
+ label: React.ReactNode;
24
+ onClick: () => void;
25
+ };
26
+ cancel?: {
27
+ label: React.ReactNode;
28
+ onClick?: () => void;
29
+ };
30
+ onClose?: () => void;
31
+ onAutoClose?: () => void;
32
+ dismissible?: boolean;
33
+ createdAt: number;
34
+ height?: number;
35
+ removing?: boolean;
36
+ swipeDirection?: "left" | "right" | "up" | "down";
37
+ }
38
+ export interface ToastOptions {
39
+ id?: string;
40
+ variant?: ToastVariant;
41
+ /**
42
+ * Description content. Supports:
43
+ * - Plain string: rendered as text
44
+ * - HTML string (containing tags like `<b>`, `<strong>`, etc.): rendered as HTML
45
+ * - ReactNode: rendered as React component
46
+ */
47
+ description?: React.ReactNode;
48
+ duration?: number;
49
+ icon?: React.ReactNode;
50
+ action?: {
51
+ label: React.ReactNode;
52
+ onClick: () => void;
53
+ };
54
+ cancel?: {
55
+ label: React.ReactNode;
56
+ onClick?: () => void;
57
+ };
58
+ onClose?: () => void;
59
+ onAutoClose?: () => void;
60
+ dismissible?: boolean;
61
+ }
62
+ export interface ToasterState {
63
+ toasts: ToastData[];
64
+ expanded: boolean;
65
+ position: ToastPosition;
66
+ }
67
+ type Subscriber = (state?: ToasterState) => void;
68
+ export declare function subscribe(callback: Subscriber, toasterId?: string): () => void;
69
+ export declare function getSnapshot(toasterId?: string): ToasterState;
70
+ export declare function setToasterConfig(config: Partial<Pick<ToasterState, "position" | "expanded">>, toasterId?: string): void;
71
+ export declare function dismiss(id: string, toasterId?: string): void;
72
+ export declare function dismissAll(toasterId?: string): void;
73
+ export declare function updateHeight(id: string, height: number, toasterId?: string): void;
74
+ export declare function setExpanded(expanded: boolean, toasterId?: string): void;
75
+ interface PromiseOptions<T> {
76
+ loading: string | (ToastOptions & {
77
+ title: string;
78
+ });
79
+ success: string | (ToastOptions & {
80
+ title: string;
81
+ }) | ((data: T) => string | (ToastOptions & {
82
+ title: string;
83
+ }));
84
+ error: string | (ToastOptions & {
85
+ title: string;
86
+ }) | ((err: unknown) => string | (ToastOptions & {
87
+ title: string;
88
+ }));
89
+ }
90
+ type ToastFunction = {
91
+ (title: string, options?: ToastOptions): string;
92
+ success: (title: string, options?: ToastOptions) => string;
93
+ error: (title: string, options?: ToastOptions) => string;
94
+ warning: (title: string, options?: ToastOptions) => string;
95
+ info: (title: string, options?: ToastOptions) => string;
96
+ loading: (title: string, options?: ToastOptions) => string;
97
+ promise: <T>(promise: Promise<T>, options: PromiseOptions<T>) => Promise<T>;
98
+ dismiss: (id: string) => void;
99
+ dismissAll: () => void;
100
+ use: (toasterId: string) => {
101
+ (title: string, options?: ToastOptions): string;
102
+ success: (title: string, options?: ToastOptions) => string;
103
+ error: (title: string, options?: ToastOptions) => string;
104
+ warning: (title: string, options?: ToastOptions) => string;
105
+ info: (title: string, options?: ToastOptions) => string;
106
+ loading: (title: string, options?: ToastOptions) => string;
107
+ promise: <T>(promise: Promise<T>, options: PromiseOptions<T>) => Promise<T>;
108
+ dismiss: (id: string) => void;
109
+ dismissAll: () => void;
110
+ };
111
+ };
112
+ export declare const toast: ToastFunction;
113
+ export {};