@choice-ui/react 1.6.7 → 1.6.9

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