@iryanraushan/notchify 1.0.5 → 1.1.6

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
@@ -21,6 +21,8 @@ Dark & light mode ready. Fully themeable. Zero config to get started.
21
21
  ## Features
22
22
 
23
23
  - Dark & light mode out of the box
24
+ - Responsive — automatically adapts to mobile (≤768px) like Android native toasts
25
+ - Smooth enter/exit animations per position
24
26
  - Fully customizable colors, background, border, shadow, and duration
25
27
  - Lightweight — no extra dependencies beyond Radix UI
26
28
  - Works with React 17+ and Next.js (App & Pages router)
@@ -31,7 +33,7 @@ Dark & light mode ready. Fully themeable. Zero config to get started.
31
33
  ## Installation
32
34
 
33
35
  ```bash
34
- npm install notchify
36
+ npm i @iryanraushan/notchify
35
37
  ```
36
38
 
37
39
  > Peer dependencies — make sure these are installed in your project:
@@ -131,6 +133,45 @@ Pass `mode` to `ToastProvider`. Defaults to `dark`.
131
133
 
132
134
  ---
133
135
 
136
+ ## Positioning
137
+
138
+ Set the `position` prop on `ToastProvider` to control where toasts appear. All toasts use the same position.
139
+
140
+ ```tsx
141
+ <ToastProvider position="top-right">
142
+ {children}
143
+ </ToastProvider>
144
+ ```
145
+
146
+ **Supported positions:**
147
+
148
+ | Value | Description |
149
+ |---|---|
150
+ | `top-left` | Top-left corner |
151
+ | `top-center` | Top center |
152
+ | `top-right` | Top-right corner |
153
+ | `bottom-left` | Bottom-left corner |
154
+ | `bottom-center` | Bottom center |
155
+ | `bottom-right` | Bottom-right corner |
156
+
157
+ ### Default behavior
158
+
159
+ | Screen | Default position |
160
+ |---|---|
161
+ | Desktop (>768px) | `bottom-right` |
162
+ | Mobile (≤768px) | `bottom-center` |
163
+
164
+ ### Responsive behavior (mobile ≤768px)
165
+
166
+ On small screens, the `position` prop is automatically simplified for a native-app feel:
167
+
168
+ - Any `top-*` position → `top-center` (offset from top edge)
169
+ - Any `bottom-*` position → `bottom-center` (offset from bottom edge)
170
+
171
+ Toasts are horizontally centered and never pinned to the absolute edge.
172
+
173
+ ---
174
+
134
175
  ## Custom Theme
135
176
 
136
177
  Override any visual token globally via the `theme` prop on `ToastProvider`.
@@ -165,9 +206,12 @@ Any value you skip falls back to the default for the current mode.
165
206
  | Prop | Type | Default | Description |
166
207
  |---|---|---|---|
167
208
  | `mode` | `"dark" \| "light"` | `"dark"` | Color mode |
209
+ | `position` | `ToastPosition` | `"bottom-right"` | Toast position (desktop). See responsive behavior for mobile. |
168
210
  | `theme` | `ToastTheme` | `{}` | Theme overrides |
169
211
  | `children` | `ReactNode` | — | Your app |
170
212
 
213
+ **`ToastPosition`** — `"top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right"`
214
+
171
215
  ### `ToastTheme`
172
216
 
173
217
  | Key | Type | Description |
@@ -208,7 +252,7 @@ If you're using the App Router, mark your layout as a client component or extrac
208
252
  import { ToastProvider } from 'notchify';
209
253
 
210
254
  export function Providers({ children }: { children: React.ReactNode }) {
211
- return <ToastProvider mode="dark">{children}</ToastProvider>;
255
+ return <ToastProvider mode="dark" position="bottom-right">{children}</ToastProvider>;
212
256
  }
213
257
  ```
214
258
 
@@ -231,5 +275,4 @@ export default function RootLayout({ children }) {
231
275
 
232
276
  ## License
233
277
 
234
- MIT © [Raushan Kumar](https://github.com/iryanraushan)
235
- # notchify
278
+ MIT © [Raushan Kumar](https://github.com/iryanraushan)
package/dist/index.d.mts CHANGED
@@ -3,6 +3,7 @@ import * as ToastPrimitives from '@radix-ui/react-toast';
3
3
 
4
4
  type ToastVariant = "default" | "destructive" | "success";
5
5
  type ToastMode = "dark" | "light";
6
+ type ToastPosition = "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right";
6
7
  interface ToastTheme {
7
8
  background?: string;
8
9
  border?: string;
@@ -24,6 +25,7 @@ interface ToastContextValue {
24
25
  dismiss: (id: string) => void;
25
26
  theme: ToastTheme;
26
27
  mode: ToastMode;
28
+ position: ToastPosition;
27
29
  }
28
30
 
29
31
  declare const ToastViewport: React.ForwardRefExoticComponent<Omit<ToastPrimitives.ToastViewportProps & React.RefAttributes<HTMLOListElement>, "ref"> & React.RefAttributes<HTMLOListElement>>;
@@ -40,9 +42,10 @@ interface ToastProviderProps {
40
42
  children: React.ReactNode;
41
43
  theme?: ToastTheme;
42
44
  mode?: ToastMode;
45
+ position?: ToastPosition;
43
46
  }
44
- declare function ToastProvider({ children, theme, mode }: ToastProviderProps): React.JSX.Element;
47
+ declare function ToastProvider({ children, theme, mode, position }: ToastProviderProps): React.JSX.Element;
45
48
 
46
49
  declare function useToast(): ToastContextValue;
47
50
 
48
- export { Toast, type ToastContextValue, type ToastItem, type ToastMode, type ToastOptions, ToastProvider, type ToastTheme, type ToastVariant, ToastViewport, useToast };
51
+ export { Toast, type ToastContextValue, type ToastItem, type ToastMode, type ToastOptions, type ToastPosition, ToastProvider, type ToastTheme, type ToastVariant, ToastViewport, useToast };
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import * as ToastPrimitives from '@radix-ui/react-toast';
3
3
 
4
4
  type ToastVariant = "default" | "destructive" | "success";
5
5
  type ToastMode = "dark" | "light";
6
+ type ToastPosition = "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right";
6
7
  interface ToastTheme {
7
8
  background?: string;
8
9
  border?: string;
@@ -24,6 +25,7 @@ interface ToastContextValue {
24
25
  dismiss: (id: string) => void;
25
26
  theme: ToastTheme;
26
27
  mode: ToastMode;
28
+ position: ToastPosition;
27
29
  }
28
30
 
29
31
  declare const ToastViewport: React.ForwardRefExoticComponent<Omit<ToastPrimitives.ToastViewportProps & React.RefAttributes<HTMLOListElement>, "ref"> & React.RefAttributes<HTMLOListElement>>;
@@ -40,9 +42,10 @@ interface ToastProviderProps {
40
42
  children: React.ReactNode;
41
43
  theme?: ToastTheme;
42
44
  mode?: ToastMode;
45
+ position?: ToastPosition;
43
46
  }
44
- declare function ToastProvider({ children, theme, mode }: ToastProviderProps): React.JSX.Element;
47
+ declare function ToastProvider({ children, theme, mode, position }: ToastProviderProps): React.JSX.Element;
45
48
 
46
49
  declare function useToast(): ToastContextValue;
47
50
 
48
- export { Toast, type ToastContextValue, type ToastItem, type ToastMode, type ToastOptions, ToastProvider, type ToastTheme, type ToastVariant, ToastViewport, useToast };
51
+ export { Toast, type ToastContextValue, type ToastItem, type ToastMode, type ToastOptions, type ToastPosition, ToastProvider, type ToastTheme, type ToastVariant, ToastViewport, useToast };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React = require('react');
3
+ var React2 = require('react');
4
4
  var ToastPrimitives2 = require('@radix-ui/react-toast');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
 
@@ -22,7 +22,7 @@ function _interopNamespace(e) {
22
22
  return Object.freeze(n);
23
23
  }
24
24
 
25
- var React__namespace = /*#__PURE__*/_interopNamespace(React);
25
+ var React2__namespace = /*#__PURE__*/_interopNamespace(React2);
26
26
  var ToastPrimitives2__namespace = /*#__PURE__*/_interopNamespace(ToastPrimitives2);
27
27
 
28
28
  var __defProp = Object.defineProperty;
@@ -56,17 +56,17 @@ var __objRest = (source, exclude) => {
56
56
  }
57
57
  return target;
58
58
  };
59
- var ToastContext = React__namespace.createContext(null);
60
- function ToastProvider({ children, theme = {}, mode = "dark" }) {
61
- const [toasts, setToasts] = React__namespace.useState([]);
62
- const toast = React__namespace.useCallback((options) => {
59
+ var ToastContext = React2__namespace.createContext(null);
60
+ function ToastProvider({ children, theme = {}, mode = "dark", position = "bottom-right" }) {
61
+ const [toasts, setToasts] = React2__namespace.useState([]);
62
+ const toast = React2__namespace.useCallback((options) => {
63
63
  const id = Math.random().toString(36).slice(2);
64
64
  setToasts((prev) => [...prev, __spreadValues({ id }, options)]);
65
65
  }, []);
66
- const dismiss = React__namespace.useCallback((id) => {
66
+ const dismiss = React2__namespace.useCallback((id) => {
67
67
  setToasts((prev) => prev.filter((t) => t.id !== id));
68
68
  }, []);
69
- return /* @__PURE__ */ jsxRuntime.jsx(ToastContext.Provider, { value: { toast, dismiss, theme, mode }, children: /* @__PURE__ */ jsxRuntime.jsxs(ToastPrimitives2__namespace.Provider, { swipeDirection: "right", children: [
69
+ return /* @__PURE__ */ jsxRuntime.jsx(ToastContext.Provider, { value: { toast, dismiss, theme, mode, position }, children: /* @__PURE__ */ jsxRuntime.jsxs(ToastPrimitives2__namespace.Provider, { swipeDirection: "right", children: [
70
70
  children,
71
71
  toasts.map((t) => {
72
72
  var _a, _b;
@@ -100,52 +100,130 @@ var defaultLight = {
100
100
  border: "#e5e5e5",
101
101
  textColor: "#111111",
102
102
  boxShadow: "0 4px 24px rgba(0,0,0,0.08), 0 1px 4px rgba(0,0,0,0.06)"};
103
+ function useIsMobile() {
104
+ const [isMobile, setIsMobile] = React2__namespace.useState(
105
+ () => typeof window !== "undefined" ? window.innerWidth <= 768 : false
106
+ );
107
+ React2__namespace.useEffect(() => {
108
+ const mq = window.matchMedia("(max-width: 768px)");
109
+ const handler = (e) => setIsMobile(e.matches);
110
+ mq.addEventListener("change", handler);
111
+ return () => mq.removeEventListener("change", handler);
112
+ }, []);
113
+ return isMobile;
114
+ }
115
+ function getViewportStyle(position, isMobile) {
116
+ const isTop = position.startsWith("top");
117
+ if (isMobile) {
118
+ return __spreadProps(__spreadValues({
119
+ position: "fixed",
120
+ left: "50%",
121
+ transform: "translateX(-50%)"
122
+ }, isTop ? { top: 16 } : { bottom: 24 }), {
123
+ zIndex: 9999,
124
+ display: "flex",
125
+ flexDirection: "column",
126
+ gap: 8,
127
+ width: "calc(100vw - 32px)",
128
+ maxWidth: 420,
129
+ padding: 0,
130
+ pointerEvents: "none"
131
+ });
132
+ }
133
+ const base = {
134
+ position: "fixed",
135
+ zIndex: 9999,
136
+ display: "flex",
137
+ flexDirection: "column",
138
+ gap: 8,
139
+ maxWidth: 420,
140
+ width: "calc(100vw - 32px)",
141
+ padding: 0,
142
+ pointerEvents: "none"
143
+ };
144
+ switch (position) {
145
+ case "top-left":
146
+ return __spreadProps(__spreadValues({}, base), { top: 16, left: 16 });
147
+ case "top-center":
148
+ return __spreadProps(__spreadValues({}, base), { top: 16, left: "50%", transform: "translateX(-50%)" });
149
+ case "top-right":
150
+ return __spreadProps(__spreadValues({}, base), { top: 16, right: 16 });
151
+ case "bottom-left":
152
+ return __spreadProps(__spreadValues({}, base), { bottom: 16, left: 16 });
153
+ case "bottom-center":
154
+ return __spreadProps(__spreadValues({}, base), { bottom: 16, left: "50%", transform: "translateX(-50%)" });
155
+ case "bottom-right":
156
+ return __spreadProps(__spreadValues({}, base), { bottom: 16, right: 16 });
157
+ }
158
+ }
159
+ var animationStyle = `
160
+ @keyframes toast-slide-in-right { from { transform: translateX(calc(100% + 16px)); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
161
+ @keyframes toast-slide-in-left { from { transform: translateX(calc(-100% - 16px)); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
162
+ @keyframes toast-slide-in-up { from { transform: translateY(calc(100% + 8px)); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
163
+ @keyframes toast-slide-in-down { from { transform: translateY(calc(-100% - 8px)); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
164
+ @keyframes toast-fade-out { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0.95); } }
165
+ [data-state="open"][data-pos="top-left"] { animation: toast-slide-in-left 180ms ease-out; }
166
+ [data-state="open"][data-pos="top-center"] { animation: toast-slide-in-down 180ms ease-out; }
167
+ [data-state="open"][data-pos="top-right"] { animation: toast-slide-in-right 180ms ease-out; }
168
+ [data-state="open"][data-pos="bottom-left"] { animation: toast-slide-in-left 180ms ease-out; }
169
+ [data-state="open"][data-pos="bottom-center"]{ animation: toast-slide-in-up 180ms ease-out; }
170
+ [data-state="open"][data-pos="bottom-right"] { animation: toast-slide-in-right 180ms ease-out; }
171
+ [data-state="closed"] { animation: toast-fade-out 150ms ease-in forwards; }
172
+ `;
173
+ var styleInjected = false;
174
+ function injectAnimations() {
175
+ if (styleInjected || typeof document === "undefined") return;
176
+ const el = document.createElement("style");
177
+ el.textContent = animationStyle;
178
+ document.head.appendChild(el);
179
+ styleInjected = true;
180
+ }
103
181
  var CloseIcon = ({ color }) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "7", height: "7", viewBox: "0 0 10 10", fill: "none", "aria-hidden": "true", children: [
104
182
  /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "1", y1: "1", x2: "9", y2: "9", stroke: color, strokeWidth: "2", strokeLinecap: "round" }),
105
183
  /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "9", y1: "1", x2: "1", y2: "9", stroke: color, strokeWidth: "2", strokeLinecap: "round" })
106
184
  ] });
107
- var ToastViewport = React__namespace.forwardRef((_a, ref) => {
185
+ var ToastViewport = React2__namespace.forwardRef((_a, ref) => {
108
186
  var _b = _a, { style } = _b, props = __objRest(_b, ["style"]);
187
+ var _a2;
188
+ const ctx = React2__namespace.useContext(ToastContext);
189
+ const position = (_a2 = ctx == null ? void 0 : ctx.position) != null ? _a2 : "bottom-right";
190
+ const isMobile = useIsMobile();
191
+ const resolvedPosition = isMobile ? position.startsWith("top") ? "top-center" : "bottom-center" : position;
109
192
  return /* @__PURE__ */ jsxRuntime.jsx(
110
193
  ToastPrimitives2__namespace.Viewport,
111
194
  __spreadValues({
112
195
  ref,
113
- style: __spreadValues({
114
- position: "fixed",
115
- top: 16,
116
- right: 16,
117
- zIndex: 9999,
118
- display: "flex",
119
- flexDirection: "column",
120
- gap: 8,
121
- maxWidth: 420,
122
- width: "calc(100vw - 32px)",
123
- padding: 8,
124
- pointerEvents: "none"
125
- }, style)
196
+ style: __spreadValues(__spreadValues({}, getViewportStyle(resolvedPosition, isMobile)), style)
126
197
  }, props)
127
198
  );
128
199
  });
129
200
  ToastViewport.displayName = "ToastViewport";
130
- var Toast = React__namespace.forwardRef(
201
+ var Toast = React2__namespace.forwardRef(
131
202
  (_a, ref) => {
132
203
  var _b = _a, { variant = "default", duration = 3e3, message, onDismiss, style, theme, mode } = _b, props = __objRest(_b, ["variant", "duration", "message", "onDismiss", "style", "theme", "mode"]);
133
- var _a2, _b2, _c, _d, _e, _f, _g, _h;
134
- const ctx = React__namespace.useContext(ToastContext);
204
+ var _a2, _b2, _c, _d, _e, _f, _g, _h, _i;
205
+ const ctx = React2__namespace.useContext(ToastContext);
135
206
  const resolvedMode = (_a2 = mode != null ? mode : ctx == null ? void 0 : ctx.mode) != null ? _a2 : "dark";
136
207
  const resolvedTheme = (_b2 = theme != null ? theme : ctx == null ? void 0 : ctx.theme) != null ? _b2 : {};
208
+ const position = (_c = ctx == null ? void 0 : ctx.position) != null ? _c : "bottom-right";
209
+ const isMobile = useIsMobile();
210
+ const resolvedPosition = isMobile ? position.startsWith("top") ? "top-center" : "bottom-center" : position;
211
+ React2__namespace.useEffect(() => {
212
+ injectAnimations();
213
+ }, []);
137
214
  const base = resolvedMode === "light" ? defaultLight : defaultDark;
138
- const dotColor = (_d = (_c = resolvedTheme.dotColors) == null ? void 0 : _c[variant]) != null ? _d : defaultDotColors[variant];
139
- const bg = (_e = resolvedTheme.background) != null ? _e : base.background;
140
- const border = (_f = resolvedTheme.border) != null ? _f : base.border;
141
- const textColor = (_g = resolvedTheme.textColor) != null ? _g : base.textColor;
142
- const shadow = (_h = resolvedTheme.boxShadow) != null ? _h : base.boxShadow;
215
+ const dotColor = (_e = (_d = resolvedTheme.dotColors) == null ? void 0 : _d[variant]) != null ? _e : defaultDotColors[variant];
216
+ const bg = (_f = resolvedTheme.background) != null ? _f : base.background;
217
+ const border = (_g = resolvedTheme.border) != null ? _g : base.border;
218
+ const textColor = (_h = resolvedTheme.textColor) != null ? _h : base.textColor;
219
+ const shadow = (_i = resolvedTheme.boxShadow) != null ? _i : base.boxShadow;
143
220
  return /* @__PURE__ */ jsxRuntime.jsxs(
144
221
  ToastPrimitives2__namespace.Root,
145
222
  __spreadProps(__spreadValues({
146
223
  ref,
147
224
  duration,
148
225
  onOpenChange: (open) => !open && (onDismiss == null ? void 0 : onDismiss()),
226
+ "data-pos": resolvedPosition,
149
227
  style: __spreadValues({
150
228
  display: "flex",
151
229
  alignItems: "center",
@@ -190,7 +268,7 @@ var Toast = React__namespace.forwardRef(
190
268
  );
191
269
  Toast.displayName = "Toast";
192
270
  function useToast() {
193
- const ctx = React.useContext(ToastContext);
271
+ const ctx = React2.useContext(ToastContext);
194
272
  if (!ctx) throw new Error("useToast must be used within a ToastProvider");
195
273
  return ctx;
196
274
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ToastProvider.tsx","../src/components/Toast.tsx","../src/hooks/useToast.ts"],"names":["React","jsx","jsxs","ToastPrimitives","React2","ToastPrimitives2","_a","_b","useContext"],"mappings":"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","file":"index.js","sourcesContent":["import * as React from \"react\";\nimport * as ToastPrimitives from \"@radix-ui/react-toast\";\nimport { Toast, ToastViewport } from \"./Toast\";\nimport { ToastItem, ToastOptions, ToastContextValue, ToastTheme, ToastMode } from \"../types\";\n\nexport const ToastContext = React.createContext<ToastContextValue | null>(null);\n\ninterface ToastProviderProps {\n children: React.ReactNode;\n theme?: ToastTheme;\n mode?: ToastMode;\n}\n\nexport function ToastProvider({ children, theme = {}, mode = \"dark\" }: ToastProviderProps) {\n const [toasts, setToasts] = React.useState<ToastItem[]>([]);\n\n const toast = React.useCallback((options: ToastOptions) => {\n const id = Math.random().toString(36).slice(2);\n setToasts((prev) => [...prev, { id, ...options }]);\n }, []);\n\n const dismiss = React.useCallback((id: string) => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n return (\n <ToastContext.Provider value={{ toast, dismiss, theme, mode }}>\n <ToastPrimitives.Provider swipeDirection=\"right\">\n {children}\n {toasts.map((t) => (\n <Toast\n key={t.id}\n open\n variant={t.variant}\n duration={t.duration ?? theme.defaultDuration ?? 3000}\n message={t.message}\n onDismiss={() => dismiss(t.id)}\n />\n ))}\n <ToastViewport />\n </ToastPrimitives.Provider>\n </ToastContext.Provider>\n );\n}\n","import * as React from \"react\";\nimport * as ToastPrimitives from \"@radix-ui/react-toast\";\nimport { ToastVariant, ToastTheme, ToastMode } from \"../types\";\nimport { ToastContext } from \"./ToastProvider\";\n\nconst defaultDotColors: Record<ToastVariant, string> = {\n default: \"#3b82f6\",\n destructive: \"#ef4444\",\n success: \"#22c55e\",\n};\n\nconst defaultDark: Required<Omit<ToastTheme, \"dotColors\">> = {\n background: \"#0c0b0b\",\n border: \"#1a1a1a\",\n textColor: \"#f5f5f5\",\n boxShadow: \"0 4px 24px rgba(0,0,0,0.28), 0 1px 4px rgba(0,0,0,0.14)\",\n defaultDuration: 3000,\n};\n\nconst defaultLight: Required<Omit<ToastTheme, \"dotColors\">> = {\n background: \"#ffffff\",\n border: \"#e5e5e5\",\n textColor: \"#111111\",\n boxShadow: \"0 4px 24px rgba(0,0,0,0.08), 0 1px 4px rgba(0,0,0,0.06)\",\n defaultDuration: 3000,\n};\n\nconst CloseIcon = ({ color }: { color: string }) => (\n <svg width=\"7\" height=\"7\" viewBox=\"0 0 10 10\" fill=\"none\" aria-hidden=\"true\">\n <line x1=\"1\" y1=\"1\" x2=\"9\" y2=\"9\" stroke={color} strokeWidth=\"2\" strokeLinecap=\"round\" />\n <line x1=\"9\" y1=\"1\" x2=\"1\" y2=\"9\" stroke={color} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n);\n\nexport const ToastViewport = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Viewport>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>\n>(({ style, ...props }, ref) => (\n <ToastPrimitives.Viewport\n ref={ref}\n style={{\n position: \"fixed\",\n top: 16,\n right: 16,\n zIndex: 9999,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 8,\n maxWidth: 420,\n width: \"calc(100vw - 32px)\",\n padding: 8,\n pointerEvents: \"none\",\n ...style,\n }}\n {...props}\n />\n));\nToastViewport.displayName = \"ToastViewport\";\n\ninterface ToastRootProps extends React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> {\n variant?: ToastVariant;\n message: string;\n onDismiss?: () => void;\n theme?: ToastTheme;\n mode?: ToastMode;\n}\n\nexport const Toast = React.forwardRef<React.ElementRef<typeof ToastPrimitives.Root>, ToastRootProps>(\n ({ variant = \"default\", duration = 3000, message, onDismiss, style, theme, mode, ...props }, ref) => {\n const ctx = React.useContext(ToastContext);\n const resolvedMode = mode ?? ctx?.mode ?? \"dark\";\n const resolvedTheme = theme ?? ctx?.theme ?? {};\n\n const base = resolvedMode === \"light\" ? defaultLight : defaultDark;\n const dotColor = resolvedTheme.dotColors?.[variant] ?? defaultDotColors[variant];\n const bg = resolvedTheme.background ?? base.background;\n const border = resolvedTheme.border ?? base.border;\n const textColor = resolvedTheme.textColor ?? base.textColor;\n const shadow = resolvedTheme.boxShadow ?? base.boxShadow;\n\n return (\n <ToastPrimitives.Root\n ref={ref}\n duration={duration}\n onOpenChange={(open) => !open && onDismiss?.()}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 10,\n padding: \"10px 14px\",\n borderRadius: 12,\n border: `1px solid ${border}`,\n background: bg,\n boxShadow: shadow,\n pointerEvents: \"auto\",\n fontSize: 14,\n color: textColor,\n lineHeight: 1.5,\n ...style,\n }}\n {...props}\n >\n <ToastPrimitives.Close asChild>\n <button\n aria-label=\"Dismiss\"\n style={{\n width: 14,\n height: 14,\n borderRadius: \"50%\",\n background: dotColor,\n border: \"none\",\n cursor: \"pointer\",\n flexShrink: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 1,\n }}\n >\n <CloseIcon color={\"#ffffff\"} />\n </button>\n </ToastPrimitives.Close>\n\n <ToastPrimitives.Description style={{ flex: 1, color: textColor, fontSize: 14 }}>\n {message}\n </ToastPrimitives.Description>\n </ToastPrimitives.Root>\n );\n }\n);\nToast.displayName = \"Toast\";\n","import { useContext } from \"react\";\nimport { ToastContext } from \"../components/ToastProvider\";\n\nexport function useToast() {\n const ctx = useContext(ToastContext);\n if (!ctx) throw new Error(\"useToast must be used within a ToastProvider\");\n return ctx;\n}\n"]}
1
+ {"version":3,"sources":["../src/components/ToastProvider.tsx","../src/components/Toast.tsx","../src/hooks/useToast.ts"],"names":["React","jsxs","ToastPrimitives","jsx","React2","_a","ToastPrimitives2","_b","useContext"],"mappings":"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","file":"index.js","sourcesContent":["import * as React from \"react\";\nimport * as ToastPrimitives from \"@radix-ui/react-toast\";\nimport { Toast, ToastViewport } from \"./Toast\";\nimport { ToastItem, ToastOptions, ToastContextValue, ToastTheme, ToastMode, ToastPosition } from \"../types\";\n\nexport const ToastContext = React.createContext<ToastContextValue | null>(null);\n\ninterface ToastProviderProps {\n children: React.ReactNode;\n theme?: ToastTheme;\n mode?: ToastMode;\n position?: ToastPosition;\n}\n\nexport function ToastProvider({ children, theme = {}, mode = \"dark\", position = \"bottom-right\" }: ToastProviderProps) {\n const [toasts, setToasts] = React.useState<ToastItem[]>([]);\n\n const toast = React.useCallback((options: ToastOptions) => {\n const id = Math.random().toString(36).slice(2);\n setToasts((prev) => [...prev, { id, ...options }]);\n }, []);\n\n const dismiss = React.useCallback((id: string) => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n return (\n <ToastContext.Provider value={{ toast, dismiss, theme, mode, position }}>\n <ToastPrimitives.Provider swipeDirection=\"right\">\n {children}\n {toasts.map((t) => (\n <Toast\n key={t.id}\n open\n variant={t.variant}\n duration={t.duration ?? theme.defaultDuration ?? 3000}\n message={t.message}\n onDismiss={() => dismiss(t.id)}\n />\n ))}\n <ToastViewport />\n </ToastPrimitives.Provider>\n </ToastContext.Provider>\n );\n}\n","import * as React from \"react\";\nimport * as ToastPrimitives from \"@radix-ui/react-toast\";\nimport { ToastVariant, ToastTheme, ToastMode, ToastPosition } from \"../types\";\nimport { ToastContext } from \"./ToastProvider\";\n\nconst defaultDotColors: Record<ToastVariant, string> = {\n default: \"#3b82f6\",\n destructive: \"#ef4444\",\n success: \"#22c55e\",\n};\n\nconst defaultDark: Required<Omit<ToastTheme, \"dotColors\">> = {\n background: \"#0c0b0b\",\n border: \"#1a1a1a\",\n textColor: \"#f5f5f5\",\n boxShadow: \"0 4px 24px rgba(0,0,0,0.28), 0 1px 4px rgba(0,0,0,0.14)\",\n defaultDuration: 3000,\n};\n\nconst defaultLight: Required<Omit<ToastTheme, \"dotColors\">> = {\n background: \"#ffffff\",\n border: \"#e5e5e5\",\n textColor: \"#111111\",\n boxShadow: \"0 4px 24px rgba(0,0,0,0.08), 0 1px 4px rgba(0,0,0,0.06)\",\n defaultDuration: 3000,\n};\n\nfunction useIsMobile() {\n const [isMobile, setIsMobile] = React.useState(() =>\n typeof window !== \"undefined\" ? window.innerWidth <= 768 : false\n );\n React.useEffect(() => {\n const mq = window.matchMedia(\"(max-width: 768px)\");\n const handler = (e: MediaQueryListEvent) => setIsMobile(e.matches);\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, []);\n return isMobile;\n}\n\nfunction getViewportStyle(position: ToastPosition, isMobile: boolean): React.CSSProperties {\n const isTop = position.startsWith(\"top\");\n\n if (isMobile) {\n return {\n position: \"fixed\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n ...(isTop ? { top: 16 } : { bottom: 24 }),\n zIndex: 9999,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 8,\n width: \"calc(100vw - 32px)\",\n maxWidth: 420,\n padding: 0,\n pointerEvents: \"none\",\n };\n }\n\n const base: React.CSSProperties = {\n position: \"fixed\",\n zIndex: 9999,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 8,\n maxWidth: 420,\n width: \"calc(100vw - 32px)\",\n padding: 0,\n pointerEvents: \"none\",\n };\n\n switch (position) {\n case \"top-left\": return { ...base, top: 16, left: 16 };\n case \"top-center\": return { ...base, top: 16, left: \"50%\", transform: \"translateX(-50%)\" };\n case \"top-right\": return { ...base, top: 16, right: 16 };\n case \"bottom-left\": return { ...base, bottom: 16, left: 16 };\n case \"bottom-center\": return { ...base, bottom: 16, left: \"50%\", transform: \"translateX(-50%)\" };\n case \"bottom-right\": return { ...base, bottom: 16, right: 16 };\n }\n}\n\nconst animationStyle = `\n@keyframes toast-slide-in-right { from { transform: translateX(calc(100% + 16px)); opacity: 0; } to { transform: translateX(0); opacity: 1; } }\n@keyframes toast-slide-in-left { from { transform: translateX(calc(-100% - 16px)); opacity: 0; } to { transform: translateX(0); opacity: 1; } }\n@keyframes toast-slide-in-up { from { transform: translateY(calc(100% + 8px)); opacity: 0; } to { transform: translateY(0); opacity: 1; } }\n@keyframes toast-slide-in-down { from { transform: translateY(calc(-100% - 8px)); opacity: 0; } to { transform: translateY(0); opacity: 1; } }\n@keyframes toast-fade-out { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0.95); } }\n[data-state=\"open\"][data-pos=\"top-left\"] { animation: toast-slide-in-left 180ms ease-out; }\n[data-state=\"open\"][data-pos=\"top-center\"] { animation: toast-slide-in-down 180ms ease-out; }\n[data-state=\"open\"][data-pos=\"top-right\"] { animation: toast-slide-in-right 180ms ease-out; }\n[data-state=\"open\"][data-pos=\"bottom-left\"] { animation: toast-slide-in-left 180ms ease-out; }\n[data-state=\"open\"][data-pos=\"bottom-center\"]{ animation: toast-slide-in-up 180ms ease-out; }\n[data-state=\"open\"][data-pos=\"bottom-right\"] { animation: toast-slide-in-right 180ms ease-out; }\n[data-state=\"closed\"] { animation: toast-fade-out 150ms ease-in forwards; }\n`;\n\nlet styleInjected = false;\nfunction injectAnimations() {\n if (styleInjected || typeof document === \"undefined\") return;\n const el = document.createElement(\"style\");\n el.textContent = animationStyle;\n document.head.appendChild(el);\n styleInjected = true;\n}\n\nconst CloseIcon = ({ color }: { color: string }) => (\n <svg width=\"7\" height=\"7\" viewBox=\"0 0 10 10\" fill=\"none\" aria-hidden=\"true\">\n <line x1=\"1\" y1=\"1\" x2=\"9\" y2=\"9\" stroke={color} strokeWidth=\"2\" strokeLinecap=\"round\" />\n <line x1=\"9\" y1=\"1\" x2=\"1\" y2=\"9\" stroke={color} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n);\n\nexport const ToastViewport = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Viewport>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>\n>(({ style, ...props }, ref) => {\n const ctx = React.useContext(ToastContext);\n const position = ctx?.position ?? \"bottom-right\";\n const isMobile = useIsMobile();\n const resolvedPosition: ToastPosition = isMobile\n ? position.startsWith(\"top\") ? \"top-center\" : \"bottom-center\"\n : position;\n\n return (\n <ToastPrimitives.Viewport\n ref={ref}\n style={{ ...getViewportStyle(resolvedPosition, isMobile), ...style }}\n {...props}\n />\n );\n});\nToastViewport.displayName = \"ToastViewport\";\n\ninterface ToastRootProps extends React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> {\n variant?: ToastVariant;\n message: string;\n onDismiss?: () => void;\n theme?: ToastTheme;\n mode?: ToastMode;\n}\n\nexport const Toast = React.forwardRef<React.ElementRef<typeof ToastPrimitives.Root>, ToastRootProps>(\n ({ variant = \"default\", duration = 3000, message, onDismiss, style, theme, mode, ...props }, ref) => {\n const ctx = React.useContext(ToastContext);\n const resolvedMode = mode ?? ctx?.mode ?? \"dark\";\n const resolvedTheme = theme ?? ctx?.theme ?? {};\n const position = ctx?.position ?? \"bottom-right\";\n const isMobile = useIsMobile();\n const resolvedPosition: ToastPosition = isMobile\n ? position.startsWith(\"top\") ? \"top-center\" : \"bottom-center\"\n : position;\n\n React.useEffect(() => { injectAnimations(); }, []);\n\n const base = resolvedMode === \"light\" ? defaultLight : defaultDark;\n const dotColor = resolvedTheme.dotColors?.[variant] ?? defaultDotColors[variant];\n const bg = resolvedTheme.background ?? base.background;\n const border = resolvedTheme.border ?? base.border;\n const textColor = resolvedTheme.textColor ?? base.textColor;\n const shadow = resolvedTheme.boxShadow ?? base.boxShadow;\n\n return (\n <ToastPrimitives.Root\n ref={ref}\n duration={duration}\n onOpenChange={(open) => !open && onDismiss?.()}\n data-pos={resolvedPosition}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 10,\n padding: \"10px 14px\",\n borderRadius: 12,\n border: `1px solid ${border}`,\n background: bg,\n boxShadow: shadow,\n pointerEvents: \"auto\",\n fontSize: 14,\n color: textColor,\n lineHeight: 1.5,\n ...style,\n }}\n {...props}\n >\n <ToastPrimitives.Close asChild>\n <button\n aria-label=\"Dismiss\"\n style={{\n width: 14,\n height: 14,\n borderRadius: \"50%\",\n background: dotColor,\n border: \"none\",\n cursor: \"pointer\",\n flexShrink: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 1,\n }}\n >\n <CloseIcon color={\"#ffffff\"} />\n </button>\n </ToastPrimitives.Close>\n\n <ToastPrimitives.Description style={{ flex: 1, color: textColor, fontSize: 14 }}>\n {message}\n </ToastPrimitives.Description>\n </ToastPrimitives.Root>\n );\n }\n);\nToast.displayName = \"Toast\";\n","import { useContext } from \"react\";\nimport { ToastContext } from \"../components/ToastProvider\";\n\nexport function useToast() {\n const ctx = useContext(ToastContext);\n if (!ctx) throw new Error(\"useToast must be used within a ToastProvider\");\n return ctx;\n}\n"]}
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import * as React from 'react';
1
+ import * as React2 from 'react';
2
2
  import { useContext } from 'react';
3
3
  import * as ToastPrimitives2 from '@radix-ui/react-toast';
4
4
  import { jsx, jsxs } from 'react/jsx-runtime';
@@ -34,17 +34,17 @@ var __objRest = (source, exclude) => {
34
34
  }
35
35
  return target;
36
36
  };
37
- var ToastContext = React.createContext(null);
38
- function ToastProvider({ children, theme = {}, mode = "dark" }) {
39
- const [toasts, setToasts] = React.useState([]);
40
- const toast = React.useCallback((options) => {
37
+ var ToastContext = React2.createContext(null);
38
+ function ToastProvider({ children, theme = {}, mode = "dark", position = "bottom-right" }) {
39
+ const [toasts, setToasts] = React2.useState([]);
40
+ const toast = React2.useCallback((options) => {
41
41
  const id = Math.random().toString(36).slice(2);
42
42
  setToasts((prev) => [...prev, __spreadValues({ id }, options)]);
43
43
  }, []);
44
- const dismiss = React.useCallback((id) => {
44
+ const dismiss = React2.useCallback((id) => {
45
45
  setToasts((prev) => prev.filter((t) => t.id !== id));
46
46
  }, []);
47
- return /* @__PURE__ */ jsx(ToastContext.Provider, { value: { toast, dismiss, theme, mode }, children: /* @__PURE__ */ jsxs(ToastPrimitives2.Provider, { swipeDirection: "right", children: [
47
+ return /* @__PURE__ */ jsx(ToastContext.Provider, { value: { toast, dismiss, theme, mode, position }, children: /* @__PURE__ */ jsxs(ToastPrimitives2.Provider, { swipeDirection: "right", children: [
48
48
  children,
49
49
  toasts.map((t) => {
50
50
  var _a, _b;
@@ -78,52 +78,130 @@ var defaultLight = {
78
78
  border: "#e5e5e5",
79
79
  textColor: "#111111",
80
80
  boxShadow: "0 4px 24px rgba(0,0,0,0.08), 0 1px 4px rgba(0,0,0,0.06)"};
81
+ function useIsMobile() {
82
+ const [isMobile, setIsMobile] = React2.useState(
83
+ () => typeof window !== "undefined" ? window.innerWidth <= 768 : false
84
+ );
85
+ React2.useEffect(() => {
86
+ const mq = window.matchMedia("(max-width: 768px)");
87
+ const handler = (e) => setIsMobile(e.matches);
88
+ mq.addEventListener("change", handler);
89
+ return () => mq.removeEventListener("change", handler);
90
+ }, []);
91
+ return isMobile;
92
+ }
93
+ function getViewportStyle(position, isMobile) {
94
+ const isTop = position.startsWith("top");
95
+ if (isMobile) {
96
+ return __spreadProps(__spreadValues({
97
+ position: "fixed",
98
+ left: "50%",
99
+ transform: "translateX(-50%)"
100
+ }, isTop ? { top: 16 } : { bottom: 24 }), {
101
+ zIndex: 9999,
102
+ display: "flex",
103
+ flexDirection: "column",
104
+ gap: 8,
105
+ width: "calc(100vw - 32px)",
106
+ maxWidth: 420,
107
+ padding: 0,
108
+ pointerEvents: "none"
109
+ });
110
+ }
111
+ const base = {
112
+ position: "fixed",
113
+ zIndex: 9999,
114
+ display: "flex",
115
+ flexDirection: "column",
116
+ gap: 8,
117
+ maxWidth: 420,
118
+ width: "calc(100vw - 32px)",
119
+ padding: 0,
120
+ pointerEvents: "none"
121
+ };
122
+ switch (position) {
123
+ case "top-left":
124
+ return __spreadProps(__spreadValues({}, base), { top: 16, left: 16 });
125
+ case "top-center":
126
+ return __spreadProps(__spreadValues({}, base), { top: 16, left: "50%", transform: "translateX(-50%)" });
127
+ case "top-right":
128
+ return __spreadProps(__spreadValues({}, base), { top: 16, right: 16 });
129
+ case "bottom-left":
130
+ return __spreadProps(__spreadValues({}, base), { bottom: 16, left: 16 });
131
+ case "bottom-center":
132
+ return __spreadProps(__spreadValues({}, base), { bottom: 16, left: "50%", transform: "translateX(-50%)" });
133
+ case "bottom-right":
134
+ return __spreadProps(__spreadValues({}, base), { bottom: 16, right: 16 });
135
+ }
136
+ }
137
+ var animationStyle = `
138
+ @keyframes toast-slide-in-right { from { transform: translateX(calc(100% + 16px)); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
139
+ @keyframes toast-slide-in-left { from { transform: translateX(calc(-100% - 16px)); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
140
+ @keyframes toast-slide-in-up { from { transform: translateY(calc(100% + 8px)); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
141
+ @keyframes toast-slide-in-down { from { transform: translateY(calc(-100% - 8px)); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
142
+ @keyframes toast-fade-out { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0.95); } }
143
+ [data-state="open"][data-pos="top-left"] { animation: toast-slide-in-left 180ms ease-out; }
144
+ [data-state="open"][data-pos="top-center"] { animation: toast-slide-in-down 180ms ease-out; }
145
+ [data-state="open"][data-pos="top-right"] { animation: toast-slide-in-right 180ms ease-out; }
146
+ [data-state="open"][data-pos="bottom-left"] { animation: toast-slide-in-left 180ms ease-out; }
147
+ [data-state="open"][data-pos="bottom-center"]{ animation: toast-slide-in-up 180ms ease-out; }
148
+ [data-state="open"][data-pos="bottom-right"] { animation: toast-slide-in-right 180ms ease-out; }
149
+ [data-state="closed"] { animation: toast-fade-out 150ms ease-in forwards; }
150
+ `;
151
+ var styleInjected = false;
152
+ function injectAnimations() {
153
+ if (styleInjected || typeof document === "undefined") return;
154
+ const el = document.createElement("style");
155
+ el.textContent = animationStyle;
156
+ document.head.appendChild(el);
157
+ styleInjected = true;
158
+ }
81
159
  var CloseIcon = ({ color }) => /* @__PURE__ */ jsxs("svg", { width: "7", height: "7", viewBox: "0 0 10 10", fill: "none", "aria-hidden": "true", children: [
82
160
  /* @__PURE__ */ jsx("line", { x1: "1", y1: "1", x2: "9", y2: "9", stroke: color, strokeWidth: "2", strokeLinecap: "round" }),
83
161
  /* @__PURE__ */ jsx("line", { x1: "9", y1: "1", x2: "1", y2: "9", stroke: color, strokeWidth: "2", strokeLinecap: "round" })
84
162
  ] });
85
- var ToastViewport = React.forwardRef((_a, ref) => {
163
+ var ToastViewport = React2.forwardRef((_a, ref) => {
86
164
  var _b = _a, { style } = _b, props = __objRest(_b, ["style"]);
165
+ var _a2;
166
+ const ctx = React2.useContext(ToastContext);
167
+ const position = (_a2 = ctx == null ? void 0 : ctx.position) != null ? _a2 : "bottom-right";
168
+ const isMobile = useIsMobile();
169
+ const resolvedPosition = isMobile ? position.startsWith("top") ? "top-center" : "bottom-center" : position;
87
170
  return /* @__PURE__ */ jsx(
88
171
  ToastPrimitives2.Viewport,
89
172
  __spreadValues({
90
173
  ref,
91
- style: __spreadValues({
92
- position: "fixed",
93
- top: 16,
94
- right: 16,
95
- zIndex: 9999,
96
- display: "flex",
97
- flexDirection: "column",
98
- gap: 8,
99
- maxWidth: 420,
100
- width: "calc(100vw - 32px)",
101
- padding: 8,
102
- pointerEvents: "none"
103
- }, style)
174
+ style: __spreadValues(__spreadValues({}, getViewportStyle(resolvedPosition, isMobile)), style)
104
175
  }, props)
105
176
  );
106
177
  });
107
178
  ToastViewport.displayName = "ToastViewport";
108
- var Toast = React.forwardRef(
179
+ var Toast = React2.forwardRef(
109
180
  (_a, ref) => {
110
181
  var _b = _a, { variant = "default", duration = 3e3, message, onDismiss, style, theme, mode } = _b, props = __objRest(_b, ["variant", "duration", "message", "onDismiss", "style", "theme", "mode"]);
111
- var _a2, _b2, _c, _d, _e, _f, _g, _h;
112
- const ctx = React.useContext(ToastContext);
182
+ var _a2, _b2, _c, _d, _e, _f, _g, _h, _i;
183
+ const ctx = React2.useContext(ToastContext);
113
184
  const resolvedMode = (_a2 = mode != null ? mode : ctx == null ? void 0 : ctx.mode) != null ? _a2 : "dark";
114
185
  const resolvedTheme = (_b2 = theme != null ? theme : ctx == null ? void 0 : ctx.theme) != null ? _b2 : {};
186
+ const position = (_c = ctx == null ? void 0 : ctx.position) != null ? _c : "bottom-right";
187
+ const isMobile = useIsMobile();
188
+ const resolvedPosition = isMobile ? position.startsWith("top") ? "top-center" : "bottom-center" : position;
189
+ React2.useEffect(() => {
190
+ injectAnimations();
191
+ }, []);
115
192
  const base = resolvedMode === "light" ? defaultLight : defaultDark;
116
- const dotColor = (_d = (_c = resolvedTheme.dotColors) == null ? void 0 : _c[variant]) != null ? _d : defaultDotColors[variant];
117
- const bg = (_e = resolvedTheme.background) != null ? _e : base.background;
118
- const border = (_f = resolvedTheme.border) != null ? _f : base.border;
119
- const textColor = (_g = resolvedTheme.textColor) != null ? _g : base.textColor;
120
- const shadow = (_h = resolvedTheme.boxShadow) != null ? _h : base.boxShadow;
193
+ const dotColor = (_e = (_d = resolvedTheme.dotColors) == null ? void 0 : _d[variant]) != null ? _e : defaultDotColors[variant];
194
+ const bg = (_f = resolvedTheme.background) != null ? _f : base.background;
195
+ const border = (_g = resolvedTheme.border) != null ? _g : base.border;
196
+ const textColor = (_h = resolvedTheme.textColor) != null ? _h : base.textColor;
197
+ const shadow = (_i = resolvedTheme.boxShadow) != null ? _i : base.boxShadow;
121
198
  return /* @__PURE__ */ jsxs(
122
199
  ToastPrimitives2.Root,
123
200
  __spreadProps(__spreadValues({
124
201
  ref,
125
202
  duration,
126
203
  onOpenChange: (open) => !open && (onDismiss == null ? void 0 : onDismiss()),
204
+ "data-pos": resolvedPosition,
127
205
  style: __spreadValues({
128
206
  display: "flex",
129
207
  alignItems: "center",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ToastProvider.tsx","../src/components/Toast.tsx","../src/hooks/useToast.ts"],"names":["ToastPrimitives","jsxs","jsx","React2","_a","_b","useContext"],"mappings":"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","file":"index.mjs","sourcesContent":["import * as React from \"react\";\nimport * as ToastPrimitives from \"@radix-ui/react-toast\";\nimport { Toast, ToastViewport } from \"./Toast\";\nimport { ToastItem, ToastOptions, ToastContextValue, ToastTheme, ToastMode } from \"../types\";\n\nexport const ToastContext = React.createContext<ToastContextValue | null>(null);\n\ninterface ToastProviderProps {\n children: React.ReactNode;\n theme?: ToastTheme;\n mode?: ToastMode;\n}\n\nexport function ToastProvider({ children, theme = {}, mode = \"dark\" }: ToastProviderProps) {\n const [toasts, setToasts] = React.useState<ToastItem[]>([]);\n\n const toast = React.useCallback((options: ToastOptions) => {\n const id = Math.random().toString(36).slice(2);\n setToasts((prev) => [...prev, { id, ...options }]);\n }, []);\n\n const dismiss = React.useCallback((id: string) => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n return (\n <ToastContext.Provider value={{ toast, dismiss, theme, mode }}>\n <ToastPrimitives.Provider swipeDirection=\"right\">\n {children}\n {toasts.map((t) => (\n <Toast\n key={t.id}\n open\n variant={t.variant}\n duration={t.duration ?? theme.defaultDuration ?? 3000}\n message={t.message}\n onDismiss={() => dismiss(t.id)}\n />\n ))}\n <ToastViewport />\n </ToastPrimitives.Provider>\n </ToastContext.Provider>\n );\n}\n","import * as React from \"react\";\nimport * as ToastPrimitives from \"@radix-ui/react-toast\";\nimport { ToastVariant, ToastTheme, ToastMode } from \"../types\";\nimport { ToastContext } from \"./ToastProvider\";\n\nconst defaultDotColors: Record<ToastVariant, string> = {\n default: \"#3b82f6\",\n destructive: \"#ef4444\",\n success: \"#22c55e\",\n};\n\nconst defaultDark: Required<Omit<ToastTheme, \"dotColors\">> = {\n background: \"#0c0b0b\",\n border: \"#1a1a1a\",\n textColor: \"#f5f5f5\",\n boxShadow: \"0 4px 24px rgba(0,0,0,0.28), 0 1px 4px rgba(0,0,0,0.14)\",\n defaultDuration: 3000,\n};\n\nconst defaultLight: Required<Omit<ToastTheme, \"dotColors\">> = {\n background: \"#ffffff\",\n border: \"#e5e5e5\",\n textColor: \"#111111\",\n boxShadow: \"0 4px 24px rgba(0,0,0,0.08), 0 1px 4px rgba(0,0,0,0.06)\",\n defaultDuration: 3000,\n};\n\nconst CloseIcon = ({ color }: { color: string }) => (\n <svg width=\"7\" height=\"7\" viewBox=\"0 0 10 10\" fill=\"none\" aria-hidden=\"true\">\n <line x1=\"1\" y1=\"1\" x2=\"9\" y2=\"9\" stroke={color} strokeWidth=\"2\" strokeLinecap=\"round\" />\n <line x1=\"9\" y1=\"1\" x2=\"1\" y2=\"9\" stroke={color} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n);\n\nexport const ToastViewport = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Viewport>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>\n>(({ style, ...props }, ref) => (\n <ToastPrimitives.Viewport\n ref={ref}\n style={{\n position: \"fixed\",\n top: 16,\n right: 16,\n zIndex: 9999,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 8,\n maxWidth: 420,\n width: \"calc(100vw - 32px)\",\n padding: 8,\n pointerEvents: \"none\",\n ...style,\n }}\n {...props}\n />\n));\nToastViewport.displayName = \"ToastViewport\";\n\ninterface ToastRootProps extends React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> {\n variant?: ToastVariant;\n message: string;\n onDismiss?: () => void;\n theme?: ToastTheme;\n mode?: ToastMode;\n}\n\nexport const Toast = React.forwardRef<React.ElementRef<typeof ToastPrimitives.Root>, ToastRootProps>(\n ({ variant = \"default\", duration = 3000, message, onDismiss, style, theme, mode, ...props }, ref) => {\n const ctx = React.useContext(ToastContext);\n const resolvedMode = mode ?? ctx?.mode ?? \"dark\";\n const resolvedTheme = theme ?? ctx?.theme ?? {};\n\n const base = resolvedMode === \"light\" ? defaultLight : defaultDark;\n const dotColor = resolvedTheme.dotColors?.[variant] ?? defaultDotColors[variant];\n const bg = resolvedTheme.background ?? base.background;\n const border = resolvedTheme.border ?? base.border;\n const textColor = resolvedTheme.textColor ?? base.textColor;\n const shadow = resolvedTheme.boxShadow ?? base.boxShadow;\n\n return (\n <ToastPrimitives.Root\n ref={ref}\n duration={duration}\n onOpenChange={(open) => !open && onDismiss?.()}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 10,\n padding: \"10px 14px\",\n borderRadius: 12,\n border: `1px solid ${border}`,\n background: bg,\n boxShadow: shadow,\n pointerEvents: \"auto\",\n fontSize: 14,\n color: textColor,\n lineHeight: 1.5,\n ...style,\n }}\n {...props}\n >\n <ToastPrimitives.Close asChild>\n <button\n aria-label=\"Dismiss\"\n style={{\n width: 14,\n height: 14,\n borderRadius: \"50%\",\n background: dotColor,\n border: \"none\",\n cursor: \"pointer\",\n flexShrink: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 1,\n }}\n >\n <CloseIcon color={\"#ffffff\"} />\n </button>\n </ToastPrimitives.Close>\n\n <ToastPrimitives.Description style={{ flex: 1, color: textColor, fontSize: 14 }}>\n {message}\n </ToastPrimitives.Description>\n </ToastPrimitives.Root>\n );\n }\n);\nToast.displayName = \"Toast\";\n","import { useContext } from \"react\";\nimport { ToastContext } from \"../components/ToastProvider\";\n\nexport function useToast() {\n const ctx = useContext(ToastContext);\n if (!ctx) throw new Error(\"useToast must be used within a ToastProvider\");\n return ctx;\n}\n"]}
1
+ {"version":3,"sources":["../src/components/ToastProvider.tsx","../src/components/Toast.tsx","../src/hooks/useToast.ts"],"names":["React","ToastPrimitives","jsxs","jsx","_a","_b","useContext"],"mappings":"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","file":"index.mjs","sourcesContent":["import * as React from \"react\";\nimport * as ToastPrimitives from \"@radix-ui/react-toast\";\nimport { Toast, ToastViewport } from \"./Toast\";\nimport { ToastItem, ToastOptions, ToastContextValue, ToastTheme, ToastMode, ToastPosition } from \"../types\";\n\nexport const ToastContext = React.createContext<ToastContextValue | null>(null);\n\ninterface ToastProviderProps {\n children: React.ReactNode;\n theme?: ToastTheme;\n mode?: ToastMode;\n position?: ToastPosition;\n}\n\nexport function ToastProvider({ children, theme = {}, mode = \"dark\", position = \"bottom-right\" }: ToastProviderProps) {\n const [toasts, setToasts] = React.useState<ToastItem[]>([]);\n\n const toast = React.useCallback((options: ToastOptions) => {\n const id = Math.random().toString(36).slice(2);\n setToasts((prev) => [...prev, { id, ...options }]);\n }, []);\n\n const dismiss = React.useCallback((id: string) => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n return (\n <ToastContext.Provider value={{ toast, dismiss, theme, mode, position }}>\n <ToastPrimitives.Provider swipeDirection=\"right\">\n {children}\n {toasts.map((t) => (\n <Toast\n key={t.id}\n open\n variant={t.variant}\n duration={t.duration ?? theme.defaultDuration ?? 3000}\n message={t.message}\n onDismiss={() => dismiss(t.id)}\n />\n ))}\n <ToastViewport />\n </ToastPrimitives.Provider>\n </ToastContext.Provider>\n );\n}\n","import * as React from \"react\";\nimport * as ToastPrimitives from \"@radix-ui/react-toast\";\nimport { ToastVariant, ToastTheme, ToastMode, ToastPosition } from \"../types\";\nimport { ToastContext } from \"./ToastProvider\";\n\nconst defaultDotColors: Record<ToastVariant, string> = {\n default: \"#3b82f6\",\n destructive: \"#ef4444\",\n success: \"#22c55e\",\n};\n\nconst defaultDark: Required<Omit<ToastTheme, \"dotColors\">> = {\n background: \"#0c0b0b\",\n border: \"#1a1a1a\",\n textColor: \"#f5f5f5\",\n boxShadow: \"0 4px 24px rgba(0,0,0,0.28), 0 1px 4px rgba(0,0,0,0.14)\",\n defaultDuration: 3000,\n};\n\nconst defaultLight: Required<Omit<ToastTheme, \"dotColors\">> = {\n background: \"#ffffff\",\n border: \"#e5e5e5\",\n textColor: \"#111111\",\n boxShadow: \"0 4px 24px rgba(0,0,0,0.08), 0 1px 4px rgba(0,0,0,0.06)\",\n defaultDuration: 3000,\n};\n\nfunction useIsMobile() {\n const [isMobile, setIsMobile] = React.useState(() =>\n typeof window !== \"undefined\" ? window.innerWidth <= 768 : false\n );\n React.useEffect(() => {\n const mq = window.matchMedia(\"(max-width: 768px)\");\n const handler = (e: MediaQueryListEvent) => setIsMobile(e.matches);\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, []);\n return isMobile;\n}\n\nfunction getViewportStyle(position: ToastPosition, isMobile: boolean): React.CSSProperties {\n const isTop = position.startsWith(\"top\");\n\n if (isMobile) {\n return {\n position: \"fixed\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n ...(isTop ? { top: 16 } : { bottom: 24 }),\n zIndex: 9999,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 8,\n width: \"calc(100vw - 32px)\",\n maxWidth: 420,\n padding: 0,\n pointerEvents: \"none\",\n };\n }\n\n const base: React.CSSProperties = {\n position: \"fixed\",\n zIndex: 9999,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 8,\n maxWidth: 420,\n width: \"calc(100vw - 32px)\",\n padding: 0,\n pointerEvents: \"none\",\n };\n\n switch (position) {\n case \"top-left\": return { ...base, top: 16, left: 16 };\n case \"top-center\": return { ...base, top: 16, left: \"50%\", transform: \"translateX(-50%)\" };\n case \"top-right\": return { ...base, top: 16, right: 16 };\n case \"bottom-left\": return { ...base, bottom: 16, left: 16 };\n case \"bottom-center\": return { ...base, bottom: 16, left: \"50%\", transform: \"translateX(-50%)\" };\n case \"bottom-right\": return { ...base, bottom: 16, right: 16 };\n }\n}\n\nconst animationStyle = `\n@keyframes toast-slide-in-right { from { transform: translateX(calc(100% + 16px)); opacity: 0; } to { transform: translateX(0); opacity: 1; } }\n@keyframes toast-slide-in-left { from { transform: translateX(calc(-100% - 16px)); opacity: 0; } to { transform: translateX(0); opacity: 1; } }\n@keyframes toast-slide-in-up { from { transform: translateY(calc(100% + 8px)); opacity: 0; } to { transform: translateY(0); opacity: 1; } }\n@keyframes toast-slide-in-down { from { transform: translateY(calc(-100% - 8px)); opacity: 0; } to { transform: translateY(0); opacity: 1; } }\n@keyframes toast-fade-out { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0.95); } }\n[data-state=\"open\"][data-pos=\"top-left\"] { animation: toast-slide-in-left 180ms ease-out; }\n[data-state=\"open\"][data-pos=\"top-center\"] { animation: toast-slide-in-down 180ms ease-out; }\n[data-state=\"open\"][data-pos=\"top-right\"] { animation: toast-slide-in-right 180ms ease-out; }\n[data-state=\"open\"][data-pos=\"bottom-left\"] { animation: toast-slide-in-left 180ms ease-out; }\n[data-state=\"open\"][data-pos=\"bottom-center\"]{ animation: toast-slide-in-up 180ms ease-out; }\n[data-state=\"open\"][data-pos=\"bottom-right\"] { animation: toast-slide-in-right 180ms ease-out; }\n[data-state=\"closed\"] { animation: toast-fade-out 150ms ease-in forwards; }\n`;\n\nlet styleInjected = false;\nfunction injectAnimations() {\n if (styleInjected || typeof document === \"undefined\") return;\n const el = document.createElement(\"style\");\n el.textContent = animationStyle;\n document.head.appendChild(el);\n styleInjected = true;\n}\n\nconst CloseIcon = ({ color }: { color: string }) => (\n <svg width=\"7\" height=\"7\" viewBox=\"0 0 10 10\" fill=\"none\" aria-hidden=\"true\">\n <line x1=\"1\" y1=\"1\" x2=\"9\" y2=\"9\" stroke={color} strokeWidth=\"2\" strokeLinecap=\"round\" />\n <line x1=\"9\" y1=\"1\" x2=\"1\" y2=\"9\" stroke={color} strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n);\n\nexport const ToastViewport = React.forwardRef<\n React.ElementRef<typeof ToastPrimitives.Viewport>,\n React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>\n>(({ style, ...props }, ref) => {\n const ctx = React.useContext(ToastContext);\n const position = ctx?.position ?? \"bottom-right\";\n const isMobile = useIsMobile();\n const resolvedPosition: ToastPosition = isMobile\n ? position.startsWith(\"top\") ? \"top-center\" : \"bottom-center\"\n : position;\n\n return (\n <ToastPrimitives.Viewport\n ref={ref}\n style={{ ...getViewportStyle(resolvedPosition, isMobile), ...style }}\n {...props}\n />\n );\n});\nToastViewport.displayName = \"ToastViewport\";\n\ninterface ToastRootProps extends React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> {\n variant?: ToastVariant;\n message: string;\n onDismiss?: () => void;\n theme?: ToastTheme;\n mode?: ToastMode;\n}\n\nexport const Toast = React.forwardRef<React.ElementRef<typeof ToastPrimitives.Root>, ToastRootProps>(\n ({ variant = \"default\", duration = 3000, message, onDismiss, style, theme, mode, ...props }, ref) => {\n const ctx = React.useContext(ToastContext);\n const resolvedMode = mode ?? ctx?.mode ?? \"dark\";\n const resolvedTheme = theme ?? ctx?.theme ?? {};\n const position = ctx?.position ?? \"bottom-right\";\n const isMobile = useIsMobile();\n const resolvedPosition: ToastPosition = isMobile\n ? position.startsWith(\"top\") ? \"top-center\" : \"bottom-center\"\n : position;\n\n React.useEffect(() => { injectAnimations(); }, []);\n\n const base = resolvedMode === \"light\" ? defaultLight : defaultDark;\n const dotColor = resolvedTheme.dotColors?.[variant] ?? defaultDotColors[variant];\n const bg = resolvedTheme.background ?? base.background;\n const border = resolvedTheme.border ?? base.border;\n const textColor = resolvedTheme.textColor ?? base.textColor;\n const shadow = resolvedTheme.boxShadow ?? base.boxShadow;\n\n return (\n <ToastPrimitives.Root\n ref={ref}\n duration={duration}\n onOpenChange={(open) => !open && onDismiss?.()}\n data-pos={resolvedPosition}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 10,\n padding: \"10px 14px\",\n borderRadius: 12,\n border: `1px solid ${border}`,\n background: bg,\n boxShadow: shadow,\n pointerEvents: \"auto\",\n fontSize: 14,\n color: textColor,\n lineHeight: 1.5,\n ...style,\n }}\n {...props}\n >\n <ToastPrimitives.Close asChild>\n <button\n aria-label=\"Dismiss\"\n style={{\n width: 14,\n height: 14,\n borderRadius: \"50%\",\n background: dotColor,\n border: \"none\",\n cursor: \"pointer\",\n flexShrink: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: 1,\n }}\n >\n <CloseIcon color={\"#ffffff\"} />\n </button>\n </ToastPrimitives.Close>\n\n <ToastPrimitives.Description style={{ flex: 1, color: textColor, fontSize: 14 }}>\n {message}\n </ToastPrimitives.Description>\n </ToastPrimitives.Root>\n );\n }\n);\nToast.displayName = \"Toast\";\n","import { useContext } from \"react\";\nimport { ToastContext } from \"../components/ToastProvider\";\n\nexport function useToast() {\n const ctx = useContext(ToastContext);\n if (!ctx) throw new Error(\"useToast must be used within a ToastProvider\");\n return ctx;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iryanraushan/notchify",
3
- "version": "1.0.5",
3
+ "version": "1.1.6",
4
4
  "description": "A classic toast notification library for React and Next.js",
5
5
  "author": "Raushan Kumar",
6
6
  "license": "MIT",