sonner 2.0.5 → 2.0.7

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/dist/index.d.mts CHANGED
@@ -47,6 +47,7 @@ interface Action {
47
47
  }
48
48
  interface ToastT {
49
49
  id: number | string;
50
+ toasterId?: string;
50
51
  title?: (() => React.ReactNode) | React.ReactNode;
51
52
  type?: ToastTypes;
52
53
  icon?: React.ReactNode;
@@ -71,6 +72,7 @@ interface ToastT {
71
72
  classNames?: ToastClassnames;
72
73
  descriptionClassName?: string;
73
74
  position?: Position;
75
+ testId?: string;
74
76
  }
75
77
  type Position = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'top-center' | 'bottom-center';
76
78
  interface ToastOptions {
@@ -84,6 +86,7 @@ interface ToastOptions {
84
86
  unstyled?: boolean;
85
87
  classNames?: ToastClassnames;
86
88
  closeButtonAriaLabel?: string;
89
+ toasterId?: string;
87
90
  }
88
91
  type Offset = {
89
92
  top?: string | number;
@@ -92,6 +95,7 @@ type Offset = {
92
95
  left?: string | number;
93
96
  } | string | number;
94
97
  interface ToasterProps {
98
+ id?: string;
95
99
  invert?: boolean;
96
100
  theme?: 'light' | 'dark' | 'system';
97
101
  position?: Position;
@@ -119,6 +123,7 @@ interface ToastToDismiss {
119
123
  }
120
124
  type ExternalToast = Omit<ToastT, 'id' | 'type' | 'title' | 'jsx' | 'delete' | 'promise'> & {
121
125
  id?: number | string;
126
+ toasterId?: string;
122
127
  };
123
128
 
124
129
  type titleT = (() => React.ReactNode) | React.ReactNode;
package/dist/index.d.ts CHANGED
@@ -47,6 +47,7 @@ interface Action {
47
47
  }
48
48
  interface ToastT {
49
49
  id: number | string;
50
+ toasterId?: string;
50
51
  title?: (() => React.ReactNode) | React.ReactNode;
51
52
  type?: ToastTypes;
52
53
  icon?: React.ReactNode;
@@ -71,6 +72,7 @@ interface ToastT {
71
72
  classNames?: ToastClassnames;
72
73
  descriptionClassName?: string;
73
74
  position?: Position;
75
+ testId?: string;
74
76
  }
75
77
  type Position = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'top-center' | 'bottom-center';
76
78
  interface ToastOptions {
@@ -84,6 +86,7 @@ interface ToastOptions {
84
86
  unstyled?: boolean;
85
87
  classNames?: ToastClassnames;
86
88
  closeButtonAriaLabel?: string;
89
+ toasterId?: string;
87
90
  }
88
91
  type Offset = {
89
92
  top?: string | number;
@@ -92,6 +95,7 @@ type Offset = {
92
95
  left?: string | number;
93
96
  } | string | number;
94
97
  interface ToasterProps {
98
+ id?: string;
95
99
  invert?: boolean;
96
100
  theme?: 'light' | 'dark' | 'system';
97
101
  position?: Position;
@@ -119,6 +123,7 @@ interface ToastToDismiss {
119
123
  }
120
124
  type ExternalToast = Omit<ToastT, 'id' | 'type' | 'title' | 'jsx' | 'delete' | 'promise'> & {
121
125
  id?: number | string;
126
+ toasterId?: string;
122
127
  };
123
128
 
124
129
  type titleT = (() => React.ReactNode) | React.ReactNode;
package/dist/index.js CHANGED
@@ -671,6 +671,7 @@ const Toast = (props)=>{
671
671
  "data-swipe-out": swipeOut,
672
672
  "data-swipe-direction": swipeOutDirection,
673
673
  "data-expanded": Boolean(expanded || expandByDefault && mounted),
674
+ "data-testid": toast.testId,
674
675
  style: {
675
676
  '--index': index,
676
677
  '--toasts-before': index,
@@ -686,6 +687,7 @@ const Toast = (props)=>{
686
687
  pointerStartRef.current = null;
687
688
  },
688
689
  onPointerDown: (event)=>{
690
+ if (event.button === 2) return; // Return early on right click
689
691
  if (disabled || !dismissible) return;
690
692
  dragStartTime.current = new Date();
691
693
  setOffsetBeforeRemove(offset.current);
@@ -919,17 +921,26 @@ function useSonner() {
919
921
  };
920
922
  }
921
923
  const Toaster = /*#__PURE__*/ React__default.default.forwardRef(function Toaster(props, ref) {
922
- const { invert, position = 'bottom-right', hotkey = [
924
+ const { id, invert, position = 'bottom-right', hotkey = [
923
925
  'altKey',
924
926
  'KeyT'
925
927
  ], expand, closeButton, className, offset, mobileOffset, theme = 'light', richColors, duration, style, visibleToasts = VISIBLE_TOASTS_AMOUNT, toastOptions, dir = getDocumentDirection(), gap = GAP, icons, containerAriaLabel = 'Notifications' } = props;
926
928
  const [toasts, setToasts] = React__default.default.useState([]);
929
+ const filteredToasts = React__default.default.useMemo(()=>{
930
+ if (id) {
931
+ return toasts.filter((toast)=>toast.toasterId === id);
932
+ }
933
+ return toasts.filter((toast)=>!toast.toasterId);
934
+ }, [
935
+ toasts,
936
+ id
937
+ ]);
927
938
  const possiblePositions = React__default.default.useMemo(()=>{
928
939
  return Array.from(new Set([
929
940
  position
930
- ].concat(toasts.filter((toast)=>toast.position).map((toast)=>toast.position))));
941
+ ].concat(filteredToasts.filter((toast)=>toast.position).map((toast)=>toast.position))));
931
942
  }, [
932
- toasts,
943
+ filteredToasts,
933
944
  position
934
945
  ]);
935
946
  const [heights, setHeights] = React__default.default.useState([]);
@@ -1084,7 +1095,7 @@ const Toaster = /*#__PURE__*/ React__default.default.forwardRef(function Toaster
1084
1095
  }, possiblePositions.map((position, index)=>{
1085
1096
  var _heights_;
1086
1097
  const [y, x] = position.split('-');
1087
- if (!toasts.length) return null;
1098
+ if (!filteredToasts.length) return null;
1088
1099
  return /*#__PURE__*/ React__default.default.createElement("ol", {
1089
1100
  key: position,
1090
1101
  dir: dir === 'auto' ? getDocumentDirection() : dir,
@@ -1136,7 +1147,7 @@ const Toaster = /*#__PURE__*/ React__default.default.forwardRef(function Toaster
1136
1147
  setInteracting(true);
1137
1148
  },
1138
1149
  onPointerUp: ()=>setInteracting(false)
1139
- }, toasts.filter((toast)=>!toast.position && index === 0 || toast.position === position).map((toast, index)=>{
1150
+ }, filteredToasts.filter((toast)=>!toast.position && index === 0 || toast.position === position).map((toast, index)=>{
1140
1151
  var _toastOptions_duration, _toastOptions_closeButton;
1141
1152
  return /*#__PURE__*/ React__default.default.createElement(Toast, {
1142
1153
  key: toast.id,
@@ -1159,7 +1170,7 @@ const Toaster = /*#__PURE__*/ React__default.default.forwardRef(function Toaster
1159
1170
  actionButtonStyle: toastOptions == null ? void 0 : toastOptions.actionButtonStyle,
1160
1171
  closeButtonAriaLabel: toastOptions == null ? void 0 : toastOptions.closeButtonAriaLabel,
1161
1172
  removeToast: removeToast,
1162
- toasts: toasts.filter((t)=>t.position == toast.position),
1173
+ toasts: filteredToasts.filter((t)=>t.position == toast.position),
1163
1174
  heights: heights.filter((h)=>h.position == toast.position),
1164
1175
  setHeights: setHeights,
1165
1176
  expandByDefault: expand,
package/dist/index.mjs CHANGED
@@ -664,6 +664,7 @@ const Toast = (props)=>{
664
664
  "data-swipe-out": swipeOut,
665
665
  "data-swipe-direction": swipeOutDirection,
666
666
  "data-expanded": Boolean(expanded || expandByDefault && mounted),
667
+ "data-testid": toast.testId,
667
668
  style: {
668
669
  '--index': index,
669
670
  '--toasts-before': index,
@@ -679,6 +680,7 @@ const Toast = (props)=>{
679
680
  pointerStartRef.current = null;
680
681
  },
681
682
  onPointerDown: (event)=>{
683
+ if (event.button === 2) return; // Return early on right click
682
684
  if (disabled || !dismissible) return;
683
685
  dragStartTime.current = new Date();
684
686
  setOffsetBeforeRemove(offset.current);
@@ -912,17 +914,26 @@ function useSonner() {
912
914
  };
913
915
  }
914
916
  const Toaster = /*#__PURE__*/ React.forwardRef(function Toaster(props, ref) {
915
- const { invert, position = 'bottom-right', hotkey = [
917
+ const { id, invert, position = 'bottom-right', hotkey = [
916
918
  'altKey',
917
919
  'KeyT'
918
920
  ], expand, closeButton, className, offset, mobileOffset, theme = 'light', richColors, duration, style, visibleToasts = VISIBLE_TOASTS_AMOUNT, toastOptions, dir = getDocumentDirection(), gap = GAP, icons, containerAriaLabel = 'Notifications' } = props;
919
921
  const [toasts, setToasts] = React.useState([]);
922
+ const filteredToasts = React.useMemo(()=>{
923
+ if (id) {
924
+ return toasts.filter((toast)=>toast.toasterId === id);
925
+ }
926
+ return toasts.filter((toast)=>!toast.toasterId);
927
+ }, [
928
+ toasts,
929
+ id
930
+ ]);
920
931
  const possiblePositions = React.useMemo(()=>{
921
932
  return Array.from(new Set([
922
933
  position
923
- ].concat(toasts.filter((toast)=>toast.position).map((toast)=>toast.position))));
934
+ ].concat(filteredToasts.filter((toast)=>toast.position).map((toast)=>toast.position))));
924
935
  }, [
925
- toasts,
936
+ filteredToasts,
926
937
  position
927
938
  ]);
928
939
  const [heights, setHeights] = React.useState([]);
@@ -1077,7 +1088,7 @@ const Toaster = /*#__PURE__*/ React.forwardRef(function Toaster(props, ref) {
1077
1088
  }, possiblePositions.map((position, index)=>{
1078
1089
  var _heights_;
1079
1090
  const [y, x] = position.split('-');
1080
- if (!toasts.length) return null;
1091
+ if (!filteredToasts.length) return null;
1081
1092
  return /*#__PURE__*/ React.createElement("ol", {
1082
1093
  key: position,
1083
1094
  dir: dir === 'auto' ? getDocumentDirection() : dir,
@@ -1129,7 +1140,7 @@ const Toaster = /*#__PURE__*/ React.forwardRef(function Toaster(props, ref) {
1129
1140
  setInteracting(true);
1130
1141
  },
1131
1142
  onPointerUp: ()=>setInteracting(false)
1132
- }, toasts.filter((toast)=>!toast.position && index === 0 || toast.position === position).map((toast, index)=>{
1143
+ }, filteredToasts.filter((toast)=>!toast.position && index === 0 || toast.position === position).map((toast, index)=>{
1133
1144
  var _toastOptions_duration, _toastOptions_closeButton;
1134
1145
  return /*#__PURE__*/ React.createElement(Toast, {
1135
1146
  key: toast.id,
@@ -1152,7 +1163,7 @@ const Toaster = /*#__PURE__*/ React.forwardRef(function Toaster(props, ref) {
1152
1163
  actionButtonStyle: toastOptions == null ? void 0 : toastOptions.actionButtonStyle,
1153
1164
  closeButtonAriaLabel: toastOptions == null ? void 0 : toastOptions.closeButtonAriaLabel,
1154
1165
  removeToast: removeToast,
1155
- toasts: toasts.filter((t)=>t.position == toast.position),
1166
+ toasts: filteredToasts.filter((t)=>t.position == toast.position),
1156
1167
  heights: heights.filter((h)=>h.position == toast.position),
1157
1168
  setHeights: setHeights,
1158
1169
  expandByDefault: expand,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sonner",
3
- "version": "2.0.5",
3
+ "version": "2.0.7",
4
4
  "description": "An opinionated toast component for React.",
5
5
  "exports": {
6
6
  ".": {
@@ -62,5 +62,5 @@
62
62
  "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc",
63
63
  "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc"
64
64
  },
65
- "packageManager": "pnpm@8.12.1"
65
+ "packageManager": "pnpm@9.15.9"
66
66
  }