@xsolla/xui-toast 0.127.0 → 0.128.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 CHANGED
@@ -329,6 +329,7 @@ The root provider component that manages toast state and renders the toast conta
329
329
  | `children` | `ReactNode` | — | Application content. |
330
330
  | `position` | `"top" \| "bottom"` | `"top"` | Position of the toast container on screen. |
331
331
  | `defaultDuration` | `number` | `5000` | Default auto-dismiss duration in milliseconds. Set to `0` to disable auto-dismiss globally. |
332
+ | `maxWidth` | `number` | `100%` | Maximum width of the toast container in pixels. If not set, toasts stretch to full viewport width. |
332
333
 
333
334
  ### useToast
334
335
 
@@ -437,7 +438,7 @@ Toast dimensions come from `theme.sizing.toast()`:
437
438
  | `closeIconSize` | `20` | Close icon dimensions |
438
439
  | `fontSize` | `16` | Message text size |
439
440
  | `lineHeight` | `20` | Message line height |
440
- | `maxWidth` | `400` | Maximum toast width |
441
+ | `maxWidth` | `400` | Maximum toast width (theme default; overridden by `ToastProvider maxWidth` prop) |
441
442
  | `containerPadding` | `12` | Padding between toast container and screen edges |
442
443
  | `groupGap` | `4` | Vertical gap between stacked toasts |
443
444
 
@@ -15,6 +15,7 @@ interface ToastProps {
15
15
  variant?: ToastVariant;
16
16
  message: string;
17
17
  icon?: ReactNode;
18
+ duration?: number;
18
19
  onClose?: () => void;
19
20
  }
20
21
  interface ToastOptions {
@@ -26,6 +27,7 @@ interface ToastOptions {
26
27
  interface ToastGroupProps {
27
28
  toasts: ToastData[];
28
29
  position?: ToastPosition;
30
+ maxWidth?: number;
29
31
  onDismiss: (id: string) => void;
30
32
  }
31
33
  interface ToastContextType {
@@ -38,11 +40,12 @@ interface ToastProviderProps {
38
40
  children: ReactNode;
39
41
  position?: ToastPosition;
40
42
  defaultDuration?: number;
43
+ maxWidth?: number;
41
44
  }
42
45
 
43
46
  declare const Toast: React__default.FC<ToastProps>;
44
47
 
45
- declare const ToastGroup: React__default.MemoExoticComponent<({ toasts, position, onDismiss }: ToastGroupProps) => React__default.ReactPortal | null>;
48
+ declare const ToastGroup: React__default.MemoExoticComponent<({ toasts, position, maxWidth, onDismiss }: ToastGroupProps) => React__default.ReactPortal | null>;
46
49
 
47
50
  declare const ToastProvider: React__default.FC<ToastProviderProps>;
48
51
 
package/native/index.d.ts CHANGED
@@ -15,6 +15,7 @@ interface ToastProps {
15
15
  variant?: ToastVariant;
16
16
  message: string;
17
17
  icon?: ReactNode;
18
+ duration?: number;
18
19
  onClose?: () => void;
19
20
  }
20
21
  interface ToastOptions {
@@ -26,6 +27,7 @@ interface ToastOptions {
26
27
  interface ToastGroupProps {
27
28
  toasts: ToastData[];
28
29
  position?: ToastPosition;
30
+ maxWidth?: number;
29
31
  onDismiss: (id: string) => void;
30
32
  }
31
33
  interface ToastContextType {
@@ -38,11 +40,12 @@ interface ToastProviderProps {
38
40
  children: ReactNode;
39
41
  position?: ToastPosition;
40
42
  defaultDuration?: number;
43
+ maxWidth?: number;
41
44
  }
42
45
 
43
46
  declare const Toast: React__default.FC<ToastProps>;
44
47
 
45
- declare const ToastGroup: React__default.MemoExoticComponent<({ toasts, position, onDismiss }: ToastGroupProps) => React__default.ReactPortal | null>;
48
+ declare const ToastGroup: React__default.MemoExoticComponent<({ toasts, position, maxWidth, onDismiss }: ToastGroupProps) => React__default.ReactPortal | null>;
46
49
 
47
50
  declare const ToastProvider: React__default.FC<ToastProviderProps>;
48
51
 
package/native/index.js CHANGED
@@ -38,6 +38,9 @@ __export(index_exports, {
38
38
  });
39
39
  module.exports = __toCommonJS(index_exports);
40
40
 
41
+ // src/Toast.tsx
42
+ var import_react2 = require("react");
43
+
41
44
  // ../primitives-native/src/Box.tsx
42
45
  var import_react_native = require("react-native");
43
46
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -319,15 +322,33 @@ var getIconColor = (variant, colors) => {
319
322
  return colors.content.inverse;
320
323
  }
321
324
  };
325
+ var ANIMATION_DURATION = 200;
322
326
  var Toast = ({
323
327
  id,
324
328
  variant = "info",
325
329
  message,
326
330
  icon,
331
+ duration,
327
332
  onClose
328
333
  }) => {
329
334
  const { theme } = (0, import_xui_core.useDesignSystem)();
330
335
  const config = theme.sizing.toast();
336
+ const [visible, setVisible] = (0, import_react2.useState)(false);
337
+ const [dismissing, setDismissing] = (0, import_react2.useState)(false);
338
+ (0, import_react2.useEffect)(() => {
339
+ const frame = requestAnimationFrame(() => setVisible(true));
340
+ return () => cancelAnimationFrame(frame);
341
+ }, []);
342
+ const handleClose = () => {
343
+ if (dismissing) return;
344
+ setDismissing(true);
345
+ setTimeout(() => onClose?.(), ANIMATION_DURATION);
346
+ };
347
+ (0, import_react2.useEffect)(() => {
348
+ if (!duration || duration <= 0) return;
349
+ const timer = setTimeout(handleClose, duration);
350
+ return () => clearTimeout(timer);
351
+ }, [duration]);
331
352
  const iconColor = getIconColor(variant, theme.colors);
332
353
  const displayIcon = icon !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { size: config.iconSize, color: iconColor, children: icon }) : getDefaultIcon(variant, config.iconSize, iconColor);
333
354
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
@@ -345,6 +366,11 @@ var Toast = ({
345
366
  role: "alert",
346
367
  "aria-live": "polite",
347
368
  "data-toast-id": id,
369
+ style: {
370
+ opacity: visible && !dismissing ? 1 : 0,
371
+ transform: visible && !dismissing ? "translateY(0)" : "translateY(-8px)",
372
+ transition: `opacity ${ANIMATION_DURATION}ms ease-out, transform ${ANIMATION_DURATION}ms ease-out`
373
+ },
348
374
  children: [
349
375
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
350
376
  Box,
@@ -371,7 +397,7 @@ var Toast = ({
371
397
  onClose && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
372
398
  Box,
373
399
  {
374
- onPress: onClose,
400
+ onPress: handleClose,
375
401
  width: config.closeButtonSize,
376
402
  height: config.closeButtonSize,
377
403
  alignItems: "center",
@@ -389,11 +415,11 @@ var Toast = ({
389
415
  Toast.displayName = "Toast";
390
416
 
391
417
  // src/ToastGroup.native.tsx
392
- var import_react2 = require("react");
418
+ var import_react3 = require("react");
393
419
  var import_xui_core2 = require("@xsolla/xui-core");
394
420
  var import_jsx_runtime5 = require("react/jsx-runtime");
395
- var ToastGroup = (0, import_react2.memo)(
396
- ({ toasts, position = "top", onDismiss }) => {
421
+ var ToastGroup = (0, import_react3.memo)(
422
+ ({ toasts, position = "top", maxWidth, onDismiss }) => {
397
423
  const { theme } = (0, import_xui_core2.useDesignSystem)();
398
424
  const config = theme.sizing.toast();
399
425
  if (toasts.length === 0) {
@@ -415,7 +441,7 @@ var ToastGroup = (0, import_react2.memo)(
415
441
  Box,
416
442
  {
417
443
  width: "100%",
418
- maxWidth: config.maxWidth,
444
+ maxWidth,
419
445
  gap: config.groupGap,
420
446
  flexDirection: "column",
421
447
  children: toasts.map((toast) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
@@ -425,6 +451,7 @@ var ToastGroup = (0, import_react2.memo)(
425
451
  variant: toast.variant,
426
452
  message: toast.message,
427
453
  icon: toast.icon,
454
+ duration: toast.duration,
428
455
  onClose: () => onDismiss(toast.id)
429
456
  },
430
457
  toast.id
@@ -438,11 +465,11 @@ var ToastGroup = (0, import_react2.memo)(
438
465
  ToastGroup.displayName = "ToastGroup";
439
466
 
440
467
  // src/ToastProvider.tsx
441
- var import_react4 = require("react");
468
+ var import_react5 = require("react");
442
469
 
443
470
  // src/ToastContext.tsx
444
- var import_react3 = require("react");
445
- var ToastContext = (0, import_react3.createContext)(null);
471
+ var import_react4 = require("react");
472
+ var ToastContext = (0, import_react4.createContext)(null);
446
473
 
447
474
  // src/ToastProvider.tsx
448
475
  var import_jsx_runtime6 = require("react/jsx-runtime");
@@ -453,31 +480,17 @@ var generateToastId = () => {
453
480
  var ToastProvider = ({
454
481
  children,
455
482
  position = "top",
456
- defaultDuration = 5e3
483
+ defaultDuration = 5e3,
484
+ maxWidth
457
485
  }) => {
458
- const [toasts, setToasts] = (0, import_react4.useState)([]);
459
- const timersRef = (0, import_react4.useRef)(
460
- /* @__PURE__ */ new Map()
461
- );
462
- const clearTimer = (0, import_react4.useCallback)((id) => {
463
- const timer = timersRef.current.get(id);
464
- if (timer) {
465
- clearTimeout(timer);
466
- timersRef.current.delete(id);
467
- }
486
+ const [toasts, setToasts] = (0, import_react5.useState)([]);
487
+ const dismissToast = (0, import_react5.useCallback)((id) => {
488
+ setToasts((prev) => prev.filter((toast) => toast.id !== id));
468
489
  }, []);
469
- const dismissToast = (0, import_react4.useCallback)(
470
- (id) => {
471
- clearTimer(id);
472
- setToasts((prev) => prev.filter((toast) => toast.id !== id));
473
- },
474
- [clearTimer]
475
- );
476
- const dismissAllToasts = (0, import_react4.useCallback)(() => {
477
- timersRef.current.forEach((_, id) => clearTimer(id));
490
+ const dismissAllToasts = (0, import_react5.useCallback)(() => {
478
491
  setToasts([]);
479
- }, [clearTimer]);
480
- const addToast = (0, import_react4.useCallback)(
492
+ }, []);
493
+ const addToast = (0, import_react5.useCallback)(
481
494
  (options) => {
482
495
  const id = generateToastId();
483
496
  const duration = options.duration ?? defaultDuration;
@@ -489,23 +502,11 @@ var ToastProvider = ({
489
502
  duration
490
503
  };
491
504
  setToasts((prev) => [...prev, newToast]);
492
- if (duration > 0) {
493
- const timer = setTimeout(() => {
494
- dismissToast(id);
495
- }, duration);
496
- timersRef.current.set(id, timer);
497
- }
498
505
  return id;
499
506
  },
500
- [defaultDuration, dismissToast]
507
+ [defaultDuration]
501
508
  );
502
- (0, import_react4.useEffect)(() => {
503
- return () => {
504
- timersRef.current.forEach((timer) => clearTimeout(timer));
505
- timersRef.current.clear();
506
- };
507
- }, []);
508
- const contextValue = (0, import_react4.useMemo)(
509
+ const contextValue = (0, import_react5.useMemo)(
509
510
  () => ({
510
511
  toasts,
511
512
  addToast,
@@ -521,6 +522,7 @@ var ToastProvider = ({
521
522
  {
522
523
  toasts,
523
524
  position,
525
+ maxWidth,
524
526
  onDismiss: dismissToast
525
527
  }
526
528
  )
@@ -528,50 +530,50 @@ var ToastProvider = ({
528
530
  };
529
531
 
530
532
  // src/useToast.ts
531
- var import_react5 = require("react");
533
+ var import_react6 = require("react");
532
534
  var useToast = () => {
533
- const context = (0, import_react5.useContext)(ToastContext);
535
+ const context = (0, import_react6.useContext)(ToastContext);
534
536
  if (!context) {
535
537
  throw new Error("useToast must be used within a ToastProvider");
536
538
  }
537
539
  const { addToast, dismissToast, dismissAllToasts } = context;
538
- const toast = (0, import_react5.useCallback)(
540
+ const toast = (0, import_react6.useCallback)(
539
541
  (options) => {
540
542
  return addToast(options);
541
543
  },
542
544
  [addToast]
543
545
  );
544
- const success = (0, import_react5.useCallback)(
546
+ const success = (0, import_react6.useCallback)(
545
547
  (message, options) => {
546
548
  return addToast({ ...options, message, variant: "success" });
547
549
  },
548
550
  [addToast]
549
551
  );
550
- const info = (0, import_react5.useCallback)(
552
+ const info = (0, import_react6.useCallback)(
551
553
  (message, options) => {
552
554
  return addToast({ ...options, message, variant: "info" });
553
555
  },
554
556
  [addToast]
555
557
  );
556
- const warning = (0, import_react5.useCallback)(
558
+ const warning = (0, import_react6.useCallback)(
557
559
  (message, options) => {
558
560
  return addToast({ ...options, message, variant: "warning" });
559
561
  },
560
562
  [addToast]
561
563
  );
562
- const error = (0, import_react5.useCallback)(
564
+ const error = (0, import_react6.useCallback)(
563
565
  (message, options) => {
564
566
  return addToast({ ...options, message, variant: "error" });
565
567
  },
566
568
  [addToast]
567
569
  );
568
- const dismiss = (0, import_react5.useCallback)(
570
+ const dismiss = (0, import_react6.useCallback)(
569
571
  (id) => {
570
572
  dismissToast(id);
571
573
  },
572
574
  [dismissToast]
573
575
  );
574
- const dismissAll = (0, import_react5.useCallback)(() => {
576
+ const dismissAll = (0, import_react6.useCallback)(() => {
575
577
  dismissAllToasts();
576
578
  }, [dismissAllToasts]);
577
579
  return {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.tsx","../../../primitives-native/src/Box.tsx","../../../primitives-native/src/Text.tsx","../../../primitives-native/src/Icon.tsx","../../src/Toast.tsx","../../src/ToastGroup.native.tsx","../../src/ToastProvider.tsx","../../src/ToastContext.tsx","../../src/useToast.ts"],"sourcesContent":["export { Toast } from \"./Toast\";\nexport { ToastGroup } from \"./ToastGroup\";\nexport { ToastProvider } from \"./ToastProvider\";\nexport { ToastContext } from \"./ToastContext\";\nexport { useToast } from \"./useToast\";\nexport type { UseToastReturn } from \"./useToast\";\nexport * from \"./types\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({ children, color, size }) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return <View style={style}>{childrenWithProps}</View>;\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem } from \"@xsolla/xui-core\";\nimport { Check, AlertCircle, X } from \"@xsolla/xui-icons\";\nimport type { ToastProps, ToastVariant } from \"./types\";\n\nconst getDefaultIcon = (\n variant: ToastVariant,\n size: number,\n color: string\n): React.ReactNode => {\n switch (variant) {\n case \"success\":\n return <Check size={size} color={color} />;\n case \"info\":\n case \"warning\":\n case \"error\":\n default:\n return <AlertCircle size={size} color={color} />;\n }\n};\n\nconst getIconColor = (\n variant: ToastVariant,\n colors: ReturnType<typeof useDesignSystem>[\"theme\"][\"colors\"]\n): string => {\n switch (variant) {\n case \"success\":\n return colors.content.success.primary;\n case \"warning\":\n return colors.content.warning.primary;\n case \"error\":\n return colors.content.alert.primary;\n case \"info\":\n default:\n return colors.content.inverse;\n }\n};\n\nexport const Toast: React.FC<ToastProps> = ({\n id,\n variant = \"info\",\n message,\n icon,\n onClose,\n}) => {\n const { theme } = useDesignSystem();\n const config = theme.sizing.toast();\n\n const iconColor = getIconColor(variant, theme.colors);\n const displayIcon =\n icon !== undefined ? (\n <Icon size={config.iconSize} color={iconColor}>\n {icon}\n </Icon>\n ) : (\n getDefaultIcon(variant, config.iconSize, iconColor)\n );\n\n return (\n <Box\n backgroundColor={theme.colors.background.inverse}\n borderRadius={config.borderRadius}\n paddingHorizontal={config.paddingHorizontal}\n paddingVertical={config.paddingVertical}\n minHeight={config.minHeight}\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.gap}\n width=\"100%\"\n role=\"alert\"\n aria-live=\"polite\"\n data-toast-id={id}\n >\n <Box\n width={config.iconSize}\n height={config.iconSize}\n alignItems=\"center\"\n justifyContent=\"center\"\n flexShrink={0}\n >\n {displayIcon}\n </Box>\n\n <Box flex={1} minWidth={0}>\n <Text\n color={theme.colors.content.inverse}\n fontSize={config.fontSize}\n lineHeight={config.lineHeight}\n fontWeight=\"500\"\n numberOfLines={2}\n >\n {message}\n </Text>\n </Box>\n\n {onClose && (\n <Box\n onPress={onClose}\n width={config.closeButtonSize}\n height={config.closeButtonSize}\n alignItems=\"center\"\n justifyContent=\"center\"\n flexShrink={0}\n role=\"button\"\n aria-label=\"Dismiss toast\"\n >\n <X size={config.closeIconSize} color={theme.colors.content.inverse} />\n </Box>\n )}\n </Box>\n );\n};\n\nToast.displayName = \"Toast\";\n","import React, { memo } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem } from \"@xsolla/xui-core\";\nimport { Toast } from \"./Toast\";\nimport type { ToastGroupProps } from \"./types\";\n\nexport const ToastGroup = memo(\n ({ toasts, position = \"top\", onDismiss }: ToastGroupProps) => {\n const { theme } = useDesignSystem();\n const config = theme.sizing.toast();\n\n if (toasts.length === 0) {\n return null;\n }\n\n const positionStyles =\n position === \"top\"\n ? { top: config.containerPadding, bottom: undefined }\n : { top: undefined, bottom: config.containerPadding };\n\n return (\n <Box\n position=\"absolute\"\n left={0}\n right={0}\n zIndex={9999}\n alignItems=\"center\"\n paddingHorizontal={config.containerPadding}\n pointerEvents=\"box-none\"\n {...positionStyles}\n >\n <Box\n width=\"100%\"\n maxWidth={config.maxWidth}\n gap={config.groupGap}\n flexDirection=\"column\"\n >\n {toasts.map((toast) => (\n <Toast\n key={toast.id}\n id={toast.id}\n variant={toast.variant}\n message={toast.message}\n icon={toast.icon}\n onClose={() => onDismiss(toast.id)}\n />\n ))}\n </Box>\n </Box>\n );\n }\n);\n\nToastGroup.displayName = \"ToastGroup\";\n","import React, {\n useCallback,\n useMemo,\n useState,\n useEffect,\n useRef,\n} from \"react\";\nimport { ToastContext } from \"./ToastContext\";\nimport { ToastGroup } from \"./ToastGroup\";\nimport type { ToastProviderProps, ToastData, ToastOptions } from \"./types\";\n\nlet toastIdCounter = 0;\n\nconst generateToastId = (): string => {\n return `toast-${++toastIdCounter}-${Date.now()}`;\n};\n\nexport const ToastProvider: React.FC<ToastProviderProps> = ({\n children,\n position = \"top\",\n defaultDuration = 5000,\n}) => {\n const [toasts, setToasts] = useState<ToastData[]>([]);\n const timersRef = useRef<Map<string, ReturnType<typeof setTimeout>>>(\n new Map()\n );\n\n const clearTimer = useCallback((id: string) => {\n const timer = timersRef.current.get(id);\n if (timer) {\n clearTimeout(timer);\n timersRef.current.delete(id);\n }\n }, []);\n\n const dismissToast = useCallback(\n (id: string) => {\n clearTimer(id);\n setToasts((prev) => prev.filter((toast) => toast.id !== id));\n },\n [clearTimer]\n );\n\n const dismissAllToasts = useCallback(() => {\n timersRef.current.forEach((_, id) => clearTimer(id));\n setToasts([]);\n }, [clearTimer]);\n\n const addToast = useCallback(\n (options: ToastOptions): string => {\n const id = generateToastId();\n const duration = options.duration ?? defaultDuration;\n\n const newToast: ToastData = {\n id,\n variant: options.variant ?? \"info\",\n message: options.message,\n icon: options.icon,\n duration,\n };\n\n setToasts((prev) => [...prev, newToast]);\n\n // Set auto-dismiss timer if duration > 0\n if (duration > 0) {\n const timer = setTimeout(() => {\n dismissToast(id);\n }, duration);\n timersRef.current.set(id, timer);\n }\n\n return id;\n },\n [defaultDuration, dismissToast]\n );\n\n // Cleanup timers on unmount\n useEffect(() => {\n return () => {\n timersRef.current.forEach((timer) => clearTimeout(timer));\n timersRef.current.clear();\n };\n }, []);\n\n const contextValue = useMemo(\n () => ({\n toasts,\n addToast,\n dismissToast,\n dismissAllToasts,\n }),\n [toasts, addToast, dismissToast, dismissAllToasts]\n );\n\n return (\n <ToastContext.Provider value={contextValue}>\n {children}\n <ToastGroup\n toasts={toasts}\n position={position}\n onDismiss={dismissToast}\n />\n </ToastContext.Provider>\n );\n};\n","import { createContext } from \"react\";\nimport type { ToastContextType } from \"./types\";\n\nexport const ToastContext = createContext<ToastContextType | null>(null);\n","import { useContext, useCallback } from \"react\";\nimport { ToastContext } from \"./ToastContext\";\nimport type { ToastOptions } from \"./types\";\n\nexport interface UseToastReturn {\n /** Show a toast with custom options */\n toast: (options: ToastOptions) => string;\n /** Show a success toast */\n success: (\n message: string,\n options?: Omit<ToastOptions, \"message\" | \"variant\">\n ) => string;\n /** Show an info toast */\n info: (\n message: string,\n options?: Omit<ToastOptions, \"message\" | \"variant\">\n ) => string;\n /** Show a warning toast */\n warning: (\n message: string,\n options?: Omit<ToastOptions, \"message\" | \"variant\">\n ) => string;\n /** Show an error toast */\n error: (\n message: string,\n options?: Omit<ToastOptions, \"message\" | \"variant\">\n ) => string;\n /** Dismiss a specific toast by ID */\n dismiss: (id: string) => void;\n /** Dismiss all toasts */\n dismissAll: () => void;\n}\n\nexport const useToast = (): UseToastReturn => {\n const context = useContext(ToastContext);\n\n if (!context) {\n throw new Error(\"useToast must be used within a ToastProvider\");\n }\n\n const { addToast, dismissToast, dismissAllToasts } = context;\n\n const toast = useCallback(\n (options: ToastOptions): string => {\n return addToast(options);\n },\n [addToast]\n );\n\n const success = useCallback(\n (\n message: string,\n options?: Omit<ToastOptions, \"message\" | \"variant\">\n ): string => {\n return addToast({ ...options, message, variant: \"success\" });\n },\n [addToast]\n );\n\n const info = useCallback(\n (\n message: string,\n options?: Omit<ToastOptions, \"message\" | \"variant\">\n ): string => {\n return addToast({ ...options, message, variant: \"info\" });\n },\n [addToast]\n );\n\n const warning = useCallback(\n (\n message: string,\n options?: Omit<ToastOptions, \"message\" | \"variant\">\n ): string => {\n return addToast({ ...options, message, variant: \"warning\" });\n },\n [addToast]\n );\n\n const error = useCallback(\n (\n message: string,\n options?: Omit<ToastOptions, \"message\" | \"variant\">\n ): string => {\n return addToast({ ...options, message, variant: \"error\" });\n },\n [addToast]\n );\n\n const dismiss = useCallback(\n (id: string): void => {\n dismissToast(id);\n },\n [dismissToast]\n );\n\n const dismissAll = useCallback((): void => {\n dismissAllToasts();\n }, [dismissAllToasts]);\n\n return {\n toast,\n success,\n info,\n warning,\n error,\n dismiss,\n dismissAll,\n };\n};\n"],"mappings":"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","names":["import_react_native","import_jsx_runtime","RNText","import_react_native","import_jsx_runtime","React","import_jsx_runtime","import_react","import_xui_core","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_react"]}
1
+ {"version":3,"sources":["../../src/index.tsx","../../src/Toast.tsx","../../../primitives-native/src/Box.tsx","../../../primitives-native/src/Text.tsx","../../../primitives-native/src/Icon.tsx","../../src/ToastGroup.native.tsx","../../src/ToastProvider.tsx","../../src/ToastContext.tsx","../../src/useToast.ts"],"sourcesContent":["export { Toast } from \"./Toast\";\nexport { ToastGroup } from \"./ToastGroup\";\nexport { ToastProvider } from \"./ToastProvider\";\nexport { ToastContext } from \"./ToastContext\";\nexport { useToast } from \"./useToast\";\nexport type { UseToastReturn } from \"./useToast\";\nexport * from \"./types\";\n","import React, { useEffect, useState } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem } from \"@xsolla/xui-core\";\nimport { Check, AlertCircle, X } from \"@xsolla/xui-icons\";\nimport type { ToastProps, ToastVariant } from \"./types\";\n\nconst getDefaultIcon = (\n variant: ToastVariant,\n size: number,\n color: string\n): React.ReactNode => {\n switch (variant) {\n case \"success\":\n return <Check size={size} color={color} />;\n case \"info\":\n case \"warning\":\n case \"error\":\n default:\n return <AlertCircle size={size} color={color} />;\n }\n};\n\nconst getIconColor = (\n variant: ToastVariant,\n colors: ReturnType<typeof useDesignSystem>[\"theme\"][\"colors\"]\n): string => {\n switch (variant) {\n case \"success\":\n return colors.content.success.primary;\n case \"warning\":\n return colors.content.warning.primary;\n case \"error\":\n return colors.content.alert.primary;\n case \"info\":\n default:\n return colors.content.inverse;\n }\n};\n\nconst ANIMATION_DURATION = 200;\n\nexport const Toast: React.FC<ToastProps> = ({\n id,\n variant = \"info\",\n message,\n icon,\n duration,\n onClose,\n}) => {\n const { theme } = useDesignSystem();\n const config = theme.sizing.toast();\n const [visible, setVisible] = useState(false);\n const [dismissing, setDismissing] = useState(false);\n\n useEffect(() => {\n const frame = requestAnimationFrame(() => setVisible(true));\n return () => cancelAnimationFrame(frame);\n }, []);\n\n const handleClose = () => {\n if (dismissing) return;\n setDismissing(true);\n setTimeout(() => onClose?.(), ANIMATION_DURATION);\n };\n\n useEffect(() => {\n if (!duration || duration <= 0) return;\n const timer = setTimeout(handleClose, duration);\n return () => clearTimeout(timer);\n }, [duration]);\n\n const iconColor = getIconColor(variant, theme.colors);\n const displayIcon =\n icon !== undefined ? (\n <Icon size={config.iconSize} color={iconColor}>\n {icon}\n </Icon>\n ) : (\n getDefaultIcon(variant, config.iconSize, iconColor)\n );\n\n return (\n <Box\n backgroundColor={theme.colors.background.inverse}\n borderRadius={config.borderRadius}\n paddingHorizontal={config.paddingHorizontal}\n paddingVertical={config.paddingVertical}\n minHeight={config.minHeight}\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={config.gap}\n width=\"100%\"\n role=\"alert\"\n aria-live=\"polite\"\n data-toast-id={id}\n style={{\n opacity: visible && !dismissing ? 1 : 0,\n transform:\n visible && !dismissing ? \"translateY(0)\" : \"translateY(-8px)\",\n transition: `opacity ${ANIMATION_DURATION}ms ease-out, transform ${ANIMATION_DURATION}ms ease-out`,\n }}\n >\n <Box\n width={config.iconSize}\n height={config.iconSize}\n alignItems=\"center\"\n justifyContent=\"center\"\n flexShrink={0}\n >\n {displayIcon}\n </Box>\n\n <Box flex={1} minWidth={0}>\n <Text\n color={theme.colors.content.inverse}\n fontSize={config.fontSize}\n lineHeight={config.lineHeight}\n fontWeight=\"500\"\n numberOfLines={2}\n >\n {message}\n </Text>\n </Box>\n\n {onClose && (\n <Box\n onPress={handleClose}\n width={config.closeButtonSize}\n height={config.closeButtonSize}\n alignItems=\"center\"\n justifyContent=\"center\"\n flexShrink={0}\n role=\"button\"\n aria-label=\"Dismiss toast\"\n >\n <X size={config.closeIconSize} color={theme.colors.content.inverse} />\n </Box>\n )}\n </Box>\n );\n};\n\nToast.displayName = \"Toast\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n flexDirection,\n alignItems,\n justifyContent,\n position,\n top,\n bottom,\n left,\n right,\n width,\n flex,\n overflow,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n flexDirection,\n alignItems,\n justifyContent,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Destructure and drop web-only props from rest before passing to RN components\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": _ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": _ariaDisabled,\n \"aria-live\": _ariaLive,\n className,\n \"data-testid\": _dataTestId,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n if (onPress) {\n return (\n <Pressable\n onPress={onPress}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({ children, color, size }) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return <View style={style}>{childrenWithProps}</View>;\n};\n","import React, { memo } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box } from \"@xsolla/xui-primitives\";\nimport { useDesignSystem } from \"@xsolla/xui-core\";\nimport { Toast } from \"./Toast\";\nimport type { ToastGroupProps } from \"./types\";\n\nexport const ToastGroup = memo(\n ({ toasts, position = \"top\", maxWidth, onDismiss }: ToastGroupProps) => {\n const { theme } = useDesignSystem();\n const config = theme.sizing.toast();\n\n if (toasts.length === 0) {\n return null;\n }\n\n const positionStyles =\n position === \"top\"\n ? { top: config.containerPadding, bottom: undefined }\n : { top: undefined, bottom: config.containerPadding };\n\n return (\n <Box\n position=\"absolute\"\n left={0}\n right={0}\n zIndex={9999}\n alignItems=\"center\"\n paddingHorizontal={config.containerPadding}\n pointerEvents=\"box-none\"\n {...positionStyles}\n >\n <Box\n width=\"100%\"\n maxWidth={maxWidth}\n gap={config.groupGap}\n flexDirection=\"column\"\n >\n {toasts.map((toast) => (\n <Toast\n key={toast.id}\n id={toast.id}\n variant={toast.variant}\n message={toast.message}\n icon={toast.icon}\n duration={toast.duration}\n onClose={() => onDismiss(toast.id)}\n />\n ))}\n </Box>\n </Box>\n );\n }\n);\n\nToastGroup.displayName = \"ToastGroup\";\n","import React, { useCallback, useMemo, useState } from \"react\";\nimport { ToastContext } from \"./ToastContext\";\nimport { ToastGroup } from \"./ToastGroup\";\nimport type { ToastProviderProps, ToastData, ToastOptions } from \"./types\";\n\nlet toastIdCounter = 0;\n\nconst generateToastId = (): string => {\n return `toast-${++toastIdCounter}-${Date.now()}`;\n};\n\nexport const ToastProvider: React.FC<ToastProviderProps> = ({\n children,\n position = \"top\",\n defaultDuration = 5000,\n maxWidth,\n}) => {\n const [toasts, setToasts] = useState<ToastData[]>([]);\n\n const dismissToast = useCallback((id: string) => {\n setToasts((prev) => prev.filter((toast) => toast.id !== id));\n }, []);\n\n const dismissAllToasts = useCallback(() => {\n setToasts([]);\n }, []);\n\n const addToast = useCallback(\n (options: ToastOptions): string => {\n const id = generateToastId();\n const duration = options.duration ?? defaultDuration;\n\n const newToast: ToastData = {\n id,\n variant: options.variant ?? \"info\",\n message: options.message,\n icon: options.icon,\n duration,\n };\n\n setToasts((prev) => [...prev, newToast]);\n\n return id;\n },\n [defaultDuration]\n );\n\n const contextValue = useMemo(\n () => ({\n toasts,\n addToast,\n dismissToast,\n dismissAllToasts,\n }),\n [toasts, addToast, dismissToast, dismissAllToasts]\n );\n\n return (\n <ToastContext.Provider value={contextValue}>\n {children}\n <ToastGroup\n toasts={toasts}\n position={position}\n maxWidth={maxWidth}\n onDismiss={dismissToast}\n />\n </ToastContext.Provider>\n );\n};\n","import { createContext } from \"react\";\nimport type { ToastContextType } from \"./types\";\n\nexport const ToastContext = createContext<ToastContextType | null>(null);\n","import { useContext, useCallback } from \"react\";\nimport { ToastContext } from \"./ToastContext\";\nimport type { ToastOptions } from \"./types\";\n\nexport interface UseToastReturn {\n /** Show a toast with custom options */\n toast: (options: ToastOptions) => string;\n /** Show a success toast */\n success: (\n message: string,\n options?: Omit<ToastOptions, \"message\" | \"variant\">\n ) => string;\n /** Show an info toast */\n info: (\n message: string,\n options?: Omit<ToastOptions, \"message\" | \"variant\">\n ) => string;\n /** Show a warning toast */\n warning: (\n message: string,\n options?: Omit<ToastOptions, \"message\" | \"variant\">\n ) => string;\n /** Show an error toast */\n error: (\n message: string,\n options?: Omit<ToastOptions, \"message\" | \"variant\">\n ) => string;\n /** Dismiss a specific toast by ID */\n dismiss: (id: string) => void;\n /** Dismiss all toasts */\n dismissAll: () => void;\n}\n\nexport const useToast = (): UseToastReturn => {\n const context = useContext(ToastContext);\n\n if (!context) {\n throw new Error(\"useToast must be used within a ToastProvider\");\n }\n\n const { addToast, dismissToast, dismissAllToasts } = context;\n\n const toast = useCallback(\n (options: ToastOptions): string => {\n return addToast(options);\n },\n [addToast]\n );\n\n const success = useCallback(\n (\n message: string,\n options?: Omit<ToastOptions, \"message\" | \"variant\">\n ): string => {\n return addToast({ ...options, message, variant: \"success\" });\n },\n [addToast]\n );\n\n const info = useCallback(\n (\n message: string,\n options?: Omit<ToastOptions, \"message\" | \"variant\">\n ): string => {\n return addToast({ ...options, message, variant: \"info\" });\n },\n [addToast]\n );\n\n const warning = useCallback(\n (\n message: string,\n options?: Omit<ToastOptions, \"message\" | \"variant\">\n ): string => {\n return addToast({ ...options, message, variant: \"warning\" });\n },\n [addToast]\n );\n\n const error = useCallback(\n (\n message: string,\n options?: Omit<ToastOptions, \"message\" | \"variant\">\n ): string => {\n return addToast({ ...options, message, variant: \"error\" });\n },\n [addToast]\n );\n\n const dismiss = useCallback(\n (id: string): void => {\n dismissToast(id);\n },\n [dismissToast]\n );\n\n const dismissAll = useCallback((): void => {\n dismissAllToasts();\n }, [dismissAllToasts]);\n\n return {\n toast,\n success,\n info,\n warning,\n error,\n dismiss,\n dismissAll,\n };\n};\n"],"mappings":"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","names":["import_react","import_react_native","import_jsx_runtime","RNText","import_react_native","import_jsx_runtime","React","import_jsx_runtime","import_react","import_xui_core","import_jsx_runtime","import_react","import_react","import_jsx_runtime","import_react"]}
package/native/index.mjs CHANGED
@@ -1,3 +1,6 @@
1
+ // src/Toast.tsx
2
+ import { useEffect, useState } from "react";
3
+
1
4
  // ../primitives-native/src/Box.tsx
2
5
  import {
3
6
  View,
@@ -286,15 +289,33 @@ var getIconColor = (variant, colors) => {
286
289
  return colors.content.inverse;
287
290
  }
288
291
  };
292
+ var ANIMATION_DURATION = 200;
289
293
  var Toast = ({
290
294
  id,
291
295
  variant = "info",
292
296
  message,
293
297
  icon,
298
+ duration,
294
299
  onClose
295
300
  }) => {
296
301
  const { theme } = useDesignSystem();
297
302
  const config = theme.sizing.toast();
303
+ const [visible, setVisible] = useState(false);
304
+ const [dismissing, setDismissing] = useState(false);
305
+ useEffect(() => {
306
+ const frame = requestAnimationFrame(() => setVisible(true));
307
+ return () => cancelAnimationFrame(frame);
308
+ }, []);
309
+ const handleClose = () => {
310
+ if (dismissing) return;
311
+ setDismissing(true);
312
+ setTimeout(() => onClose?.(), ANIMATION_DURATION);
313
+ };
314
+ useEffect(() => {
315
+ if (!duration || duration <= 0) return;
316
+ const timer = setTimeout(handleClose, duration);
317
+ return () => clearTimeout(timer);
318
+ }, [duration]);
298
319
  const iconColor = getIconColor(variant, theme.colors);
299
320
  const displayIcon = icon !== void 0 ? /* @__PURE__ */ jsx4(Icon, { size: config.iconSize, color: iconColor, children: icon }) : getDefaultIcon(variant, config.iconSize, iconColor);
300
321
  return /* @__PURE__ */ jsxs(
@@ -312,6 +333,11 @@ var Toast = ({
312
333
  role: "alert",
313
334
  "aria-live": "polite",
314
335
  "data-toast-id": id,
336
+ style: {
337
+ opacity: visible && !dismissing ? 1 : 0,
338
+ transform: visible && !dismissing ? "translateY(0)" : "translateY(-8px)",
339
+ transition: `opacity ${ANIMATION_DURATION}ms ease-out, transform ${ANIMATION_DURATION}ms ease-out`
340
+ },
315
341
  children: [
316
342
  /* @__PURE__ */ jsx4(
317
343
  Box,
@@ -338,7 +364,7 @@ var Toast = ({
338
364
  onClose && /* @__PURE__ */ jsx4(
339
365
  Box,
340
366
  {
341
- onPress: onClose,
367
+ onPress: handleClose,
342
368
  width: config.closeButtonSize,
343
369
  height: config.closeButtonSize,
344
370
  alignItems: "center",
@@ -360,7 +386,7 @@ import { memo } from "react";
360
386
  import { useDesignSystem as useDesignSystem2 } from "@xsolla/xui-core";
361
387
  import { jsx as jsx5 } from "react/jsx-runtime";
362
388
  var ToastGroup = memo(
363
- ({ toasts, position = "top", onDismiss }) => {
389
+ ({ toasts, position = "top", maxWidth, onDismiss }) => {
364
390
  const { theme } = useDesignSystem2();
365
391
  const config = theme.sizing.toast();
366
392
  if (toasts.length === 0) {
@@ -382,7 +408,7 @@ var ToastGroup = memo(
382
408
  Box,
383
409
  {
384
410
  width: "100%",
385
- maxWidth: config.maxWidth,
411
+ maxWidth,
386
412
  gap: config.groupGap,
387
413
  flexDirection: "column",
388
414
  children: toasts.map((toast) => /* @__PURE__ */ jsx5(
@@ -392,6 +418,7 @@ var ToastGroup = memo(
392
418
  variant: toast.variant,
393
419
  message: toast.message,
394
420
  icon: toast.icon,
421
+ duration: toast.duration,
395
422
  onClose: () => onDismiss(toast.id)
396
423
  },
397
424
  toast.id
@@ -405,13 +432,7 @@ var ToastGroup = memo(
405
432
  ToastGroup.displayName = "ToastGroup";
406
433
 
407
434
  // src/ToastProvider.tsx
408
- import {
409
- useCallback,
410
- useMemo,
411
- useState,
412
- useEffect,
413
- useRef
414
- } from "react";
435
+ import { useCallback, useMemo, useState as useState2 } from "react";
415
436
 
416
437
  // src/ToastContext.tsx
417
438
  import { createContext } from "react";
@@ -426,30 +447,16 @@ var generateToastId = () => {
426
447
  var ToastProvider = ({
427
448
  children,
428
449
  position = "top",
429
- defaultDuration = 5e3
450
+ defaultDuration = 5e3,
451
+ maxWidth
430
452
  }) => {
431
- const [toasts, setToasts] = useState([]);
432
- const timersRef = useRef(
433
- /* @__PURE__ */ new Map()
434
- );
435
- const clearTimer = useCallback((id) => {
436
- const timer = timersRef.current.get(id);
437
- if (timer) {
438
- clearTimeout(timer);
439
- timersRef.current.delete(id);
440
- }
453
+ const [toasts, setToasts] = useState2([]);
454
+ const dismissToast = useCallback((id) => {
455
+ setToasts((prev) => prev.filter((toast) => toast.id !== id));
441
456
  }, []);
442
- const dismissToast = useCallback(
443
- (id) => {
444
- clearTimer(id);
445
- setToasts((prev) => prev.filter((toast) => toast.id !== id));
446
- },
447
- [clearTimer]
448
- );
449
457
  const dismissAllToasts = useCallback(() => {
450
- timersRef.current.forEach((_, id) => clearTimer(id));
451
458
  setToasts([]);
452
- }, [clearTimer]);
459
+ }, []);
453
460
  const addToast = useCallback(
454
461
  (options) => {
455
462
  const id = generateToastId();
@@ -462,22 +469,10 @@ var ToastProvider = ({
462
469
  duration
463
470
  };
464
471
  setToasts((prev) => [...prev, newToast]);
465
- if (duration > 0) {
466
- const timer = setTimeout(() => {
467
- dismissToast(id);
468
- }, duration);
469
- timersRef.current.set(id, timer);
470
- }
471
472
  return id;
472
473
  },
473
- [defaultDuration, dismissToast]
474
+ [defaultDuration]
474
475
  );
475
- useEffect(() => {
476
- return () => {
477
- timersRef.current.forEach((timer) => clearTimeout(timer));
478
- timersRef.current.clear();
479
- };
480
- }, []);
481
476
  const contextValue = useMemo(
482
477
  () => ({
483
478
  toasts,
@@ -494,6 +489,7 @@ var ToastProvider = ({
494
489
  {
495
490
  toasts,
496
491
  position,
492
+ maxWidth,
497
493
  onDismiss: dismissToast
498
494
  }
499
495
  )