@laravel-inertia-toast/react 0.1.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.
@@ -0,0 +1,8 @@
1
+ import type { ToastItem as ToastItemType, ToastConfig } from '../types';
2
+ interface ToastItemProps {
3
+ toast: ToastItemType;
4
+ config: ToastConfig;
5
+ onRemove: (id: string) => void;
6
+ }
7
+ export declare function ToastItem({ toast, config, onRemove }: ToastItemProps): import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1 @@
1
+ export declare function Toasts(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import type { ToastConfig, ToastItem } from './types';
3
+ export interface ToastContextValue {
4
+ items: ToastItem[];
5
+ config: ToastConfig;
6
+ success: (message: string, duration?: number) => void;
7
+ error: (message: string, duration?: number) => void;
8
+ info: (message: string, duration?: number) => void;
9
+ warning: (message: string, duration?: number) => void;
10
+ remove: (id: string) => void;
11
+ clear: () => void;
12
+ }
13
+ export declare const ToastContext: React.Context<ToastContextValue | null>;
14
+ export interface ToastProviderProps {
15
+ children: React.ReactNode;
16
+ config?: Partial<ToastConfig>;
17
+ }
18
+ export declare function ToastProvider({ children, config: configOverrides }: ToastProviderProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,2 @@
1
+ import { type ToastContextValue } from '../context';
2
+ export declare function useToast(): ToastContextValue;
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),r=require("react"),x=require("@inertiajs/react");let j=0;function C(){return`toast-${++j}-${Date.now()}`}const y={duration:5e3,position:"top-right",maxVisible:5,propKey:"toasts"};function k(t,i){switch(i.type){case"ADD":{const a=[{...i.payload,id:C()},...t.items].slice(0,t.config.maxVisible);return{...t,items:a}}case"REMOVE":return{...t,items:t.items.filter(n=>n.id!==i.payload)};case"CLEAR":return{...t,items:[]};default:return t}}const v=r.createContext(null);function R({children:t,config:i}){const n={...y,...i},[a,l]=r.useReducer(k,{items:[],config:n}),f=x.usePage(),m=r.useRef(n);m.current=n,r.useEffect(()=>x.router.on("finish",()=>{const s=f.props[m.current.propKey];s&&Array.isArray(s)&&s.forEach(d=>{l({type:"ADD",payload:d})})}),[f.props]);const c=r.useCallback((o,s,d)=>{l({type:"ADD",payload:{message:o,level:s,duration:d??null}})},[]),w={items:a.items,config:a.config,success:r.useCallback((o,s)=>c(o,"success",s),[c]),error:r.useCallback((o,s)=>c(o,"error",s),[c]),info:r.useCallback((o,s)=>c(o,"info",s),[c]),warning:r.useCallback((o,s)=>c(o,"warning",s),[c]),remove:r.useCallback(o=>l({type:"REMOVE",payload:o}),[]),clear:r.useCallback(()=>l({type:"CLEAR"}),[])};return e.jsx(v.Provider,{value:w,children:t})}function h(){const t=r.useContext(v);if(!t)throw new Error("useToast must be used within a <ToastProvider>");return t}const g={success:"bg-green-50 text-green-800 dark:bg-green-900/30 dark:text-green-300",error:"bg-red-50 text-red-800 dark:bg-red-900/30 dark:text-red-300",warning:"bg-yellow-50 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-300",info:"bg-blue-50 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300"},u={success:"text-green-500 dark:text-green-400",error:"text-red-500 dark:text-red-400",warning:"text-yellow-500 dark:text-yellow-400",info:"text-blue-500 dark:text-blue-400"};function N(){return e.jsx("svg",{className:"h-5 w-5",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z",clipRule:"evenodd"})})}function L(){return e.jsx("svg",{className:"h-5 w-5",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z",clipRule:"evenodd"})})}function T(){return e.jsx("svg",{className:"h-5 w-5",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z",clipRule:"evenodd"})})}function z(){return e.jsx("svg",{className:"h-5 w-5",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{fillRule:"evenodd",d:"M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z",clipRule:"evenodd"})})}function M({level:t}){switch(t){case"success":return e.jsx(N,{});case"error":return e.jsx(L,{});case"warning":return e.jsx(T,{});default:return e.jsx(z,{})}}function b({toast:t,config:i,onRemove:n}){const a=r.useRef(null),l=t.duration??i.duration;return r.useEffect(()=>(l>0&&(a.current=setTimeout(()=>{n(t.id)},l)),()=>{a.current&&clearTimeout(a.current)}),[l,t.id,n]),e.jsx("div",{className:`pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg shadow-lg ring-1 ring-black/5 ${g[t.level]??g.info}`,role:"alert",children:e.jsx("div",{className:"p-4",children:e.jsxs("div",{className:"flex items-start",children:[e.jsx("div",{className:`shrink-0 ${u[t.level]??u.info}`,children:e.jsx(M,{level:t.level})}),e.jsx("div",{className:"ml-3 w-0 flex-1",children:e.jsx("p",{className:"text-sm font-medium",children:t.message})}),e.jsx("div",{className:"ml-4 flex shrink-0",children:e.jsxs("button",{type:"button",className:`inline-flex rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 ${u[t.level]??u.info}`,onClick:()=>n(t.id),children:[e.jsx("span",{className:"sr-only",children:"Close"}),e.jsx("svg",{className:"h-5 w-5",viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{d:"M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z"})})]})})]})})})}const p={"top-right":"top-4 right-4 items-end","top-left":"top-4 left-4 items-start","top-center":"top-4 left-1/2 -translate-x-1/2 items-center","bottom-right":"bottom-4 right-4 items-end","bottom-left":"bottom-4 left-4 items-start","bottom-center":"bottom-4 left-1/2 -translate-x-1/2 items-center"};function E(){const{items:t,config:i,remove:n}=h(),a=p[i.position]??p["top-right"];return e.jsx("div",{className:`pointer-events-none fixed z-50 flex w-full max-w-sm flex-col gap-3 ${a}`,"aria-live":"polite",children:t.map(l=>e.jsx(b,{toast:l,config:i,onRemove:n},l.id))})}exports.ToastItem=b;exports.ToastProvider=R;exports.Toasts=E;exports.useToast=h;
@@ -0,0 +1,6 @@
1
+ export { ToastProvider } from './context';
2
+ export type { ToastProviderProps, ToastContextValue } from './context';
3
+ export { useToast } from './hooks/useToast';
4
+ export { Toasts } from './components/Toasts';
5
+ export { ToastItem } from './components/ToastItem';
6
+ export type { ToastLevel, ToastMessage, ToastItem as ToastItemType, ToastConfig } from './types';
package/dist/index.js ADDED
@@ -0,0 +1,186 @@
1
+ import { jsx as t, jsxs as p } from "react/jsx-runtime";
2
+ import { createContext as y, useReducer as C, useRef as h, useEffect as x, useCallback as c, useContext as k } from "react";
3
+ import { usePage as R, router as N } from "@inertiajs/react";
4
+ let L = 0;
5
+ function z() {
6
+ return `toast-${++L}-${Date.now()}`;
7
+ }
8
+ const M = {
9
+ duration: 5e3,
10
+ position: "top-right",
11
+ maxVisible: 5,
12
+ propKey: "toasts"
13
+ };
14
+ function A(e, i) {
15
+ switch (i.type) {
16
+ case "ADD": {
17
+ const s = [{
18
+ ...i.payload,
19
+ id: z()
20
+ }, ...e.items].slice(0, e.config.maxVisible);
21
+ return { ...e, items: s };
22
+ }
23
+ case "REMOVE":
24
+ return {
25
+ ...e,
26
+ items: e.items.filter((n) => n.id !== i.payload)
27
+ };
28
+ case "CLEAR":
29
+ return { ...e, items: [] };
30
+ default:
31
+ return e;
32
+ }
33
+ }
34
+ const w = y(null);
35
+ function K({ children: e, config: i }) {
36
+ const n = { ...M, ...i }, [s, l] = C(A, {
37
+ items: [],
38
+ config: n
39
+ }), f = R(), m = h(n);
40
+ m.current = n, x(() => N.on("finish", () => {
41
+ const r = f.props[m.current.propKey];
42
+ r && Array.isArray(r) && r.forEach((u) => {
43
+ l({ type: "ADD", payload: u });
44
+ });
45
+ }), [f.props]);
46
+ const a = c((o, r, u) => {
47
+ l({
48
+ type: "ADD",
49
+ payload: { message: o, level: r, duration: u ?? null }
50
+ });
51
+ }, []), b = {
52
+ items: s.items,
53
+ config: s.config,
54
+ success: c((o, r) => a(o, "success", r), [a]),
55
+ error: c((o, r) => a(o, "error", r), [a]),
56
+ info: c((o, r) => a(o, "info", r), [a]),
57
+ warning: c((o, r) => a(o, "warning", r), [a]),
58
+ remove: c((o) => l({ type: "REMOVE", payload: o }), []),
59
+ clear: c(() => l({ type: "CLEAR" }), [])
60
+ };
61
+ return /* @__PURE__ */ t(w.Provider, { value: b, children: e });
62
+ }
63
+ function E() {
64
+ const e = k(w);
65
+ if (!e)
66
+ throw new Error("useToast must be used within a <ToastProvider>");
67
+ return e;
68
+ }
69
+ const g = {
70
+ success: "bg-green-50 text-green-800 dark:bg-green-900/30 dark:text-green-300",
71
+ error: "bg-red-50 text-red-800 dark:bg-red-900/30 dark:text-red-300",
72
+ warning: "bg-yellow-50 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-300",
73
+ info: "bg-blue-50 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300"
74
+ }, d = {
75
+ success: "text-green-500 dark:text-green-400",
76
+ error: "text-red-500 dark:text-red-400",
77
+ warning: "text-yellow-500 dark:text-yellow-400",
78
+ info: "text-blue-500 dark:text-blue-400"
79
+ };
80
+ function T() {
81
+ return /* @__PURE__ */ t("svg", { className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ t(
82
+ "path",
83
+ {
84
+ fillRule: "evenodd",
85
+ d: "M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z",
86
+ clipRule: "evenodd"
87
+ }
88
+ ) });
89
+ }
90
+ function I() {
91
+ return /* @__PURE__ */ t("svg", { className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ t(
92
+ "path",
93
+ {
94
+ fillRule: "evenodd",
95
+ d: "M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z",
96
+ clipRule: "evenodd"
97
+ }
98
+ ) });
99
+ }
100
+ function D() {
101
+ return /* @__PURE__ */ t("svg", { className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ t(
102
+ "path",
103
+ {
104
+ fillRule: "evenodd",
105
+ d: "M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z",
106
+ clipRule: "evenodd"
107
+ }
108
+ ) });
109
+ }
110
+ function $() {
111
+ return /* @__PURE__ */ t("svg", { className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ t(
112
+ "path",
113
+ {
114
+ fillRule: "evenodd",
115
+ d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a.75.75 0 000 1.5h.253a.25.25 0 01.244.304l-.459 2.066A1.75 1.75 0 0010.747 15H11a.75.75 0 000-1.5h-.253a.25.25 0 01-.244-.304l.459-2.066A1.75 1.75 0 009.253 9H9z",
116
+ clipRule: "evenodd"
117
+ }
118
+ ) });
119
+ }
120
+ function B({ level: e }) {
121
+ switch (e) {
122
+ case "success":
123
+ return /* @__PURE__ */ t(T, {});
124
+ case "error":
125
+ return /* @__PURE__ */ t(I, {});
126
+ case "warning":
127
+ return /* @__PURE__ */ t(D, {});
128
+ default:
129
+ return /* @__PURE__ */ t($, {});
130
+ }
131
+ }
132
+ function P({ toast: e, config: i, onRemove: n }) {
133
+ const s = h(null), l = e.duration ?? i.duration;
134
+ return x(() => (l > 0 && (s.current = setTimeout(() => {
135
+ n(e.id);
136
+ }, l)), () => {
137
+ s.current && clearTimeout(s.current);
138
+ }), [l, e.id, n]), /* @__PURE__ */ t(
139
+ "div",
140
+ {
141
+ className: `pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg shadow-lg ring-1 ring-black/5 ${g[e.level] ?? g.info}`,
142
+ role: "alert",
143
+ children: /* @__PURE__ */ t("div", { className: "p-4", children: /* @__PURE__ */ p("div", { className: "flex items-start", children: [
144
+ /* @__PURE__ */ t("div", { className: `shrink-0 ${d[e.level] ?? d.info}`, children: /* @__PURE__ */ t(B, { level: e.level }) }),
145
+ /* @__PURE__ */ t("div", { className: "ml-3 w-0 flex-1", children: /* @__PURE__ */ t("p", { className: "text-sm font-medium", children: e.message }) }),
146
+ /* @__PURE__ */ t("div", { className: "ml-4 flex shrink-0", children: /* @__PURE__ */ p(
147
+ "button",
148
+ {
149
+ type: "button",
150
+ className: `inline-flex rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 ${d[e.level] ?? d.info}`,
151
+ onClick: () => n(e.id),
152
+ children: [
153
+ /* @__PURE__ */ t("span", { className: "sr-only", children: "Close" }),
154
+ /* @__PURE__ */ t("svg", { className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ t("path", { d: "M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" }) })
155
+ ]
156
+ }
157
+ ) })
158
+ ] }) })
159
+ }
160
+ );
161
+ }
162
+ const v = {
163
+ "top-right": "top-4 right-4 items-end",
164
+ "top-left": "top-4 left-4 items-start",
165
+ "top-center": "top-4 left-1/2 -translate-x-1/2 items-center",
166
+ "bottom-right": "bottom-4 right-4 items-end",
167
+ "bottom-left": "bottom-4 left-4 items-start",
168
+ "bottom-center": "bottom-4 left-1/2 -translate-x-1/2 items-center"
169
+ };
170
+ function O() {
171
+ const { items: e, config: i, remove: n } = E(), s = v[i.position] ?? v["top-right"];
172
+ return /* @__PURE__ */ t(
173
+ "div",
174
+ {
175
+ className: `pointer-events-none fixed z-50 flex w-full max-w-sm flex-col gap-3 ${s}`,
176
+ "aria-live": "polite",
177
+ children: e.map((l) => /* @__PURE__ */ t(P, { toast: l, config: i, onRemove: n }, l.id))
178
+ }
179
+ );
180
+ }
181
+ export {
182
+ P as ToastItem,
183
+ K as ToastProvider,
184
+ O as Toasts,
185
+ E as useToast
186
+ };
@@ -0,0 +1,15 @@
1
+ export type ToastLevel = 'success' | 'error' | 'info' | 'warning';
2
+ export interface ToastMessage {
3
+ message: string;
4
+ level: ToastLevel;
5
+ duration: number | null;
6
+ }
7
+ export interface ToastItem extends ToastMessage {
8
+ id: string;
9
+ }
10
+ export interface ToastConfig {
11
+ duration: number;
12
+ position: string;
13
+ maxVisible: number;
14
+ propKey: string;
15
+ }
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@laravel-inertia-toast/react",
3
+ "version": "0.1.0",
4
+ "description": "React toast components for Laravel Inertia Toast",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.cjs",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "scripts": {
21
+ "build": "vite build && tsc --emitDeclarationOnly",
22
+ "dev": "vite build --watch"
23
+ },
24
+ "peerDependencies": {
25
+ "@inertiajs/react": "^1.0.0 || ^2.0.0",
26
+ "react": "^18.0.0 || ^19.0.0",
27
+ "react-dom": "^18.0.0 || ^19.0.0"
28
+ },
29
+ "devDependencies": {
30
+ "@inertiajs/react": "^2.0.0",
31
+ "@types/react": "^19.0.0",
32
+ "@types/react-dom": "^19.0.0",
33
+ "react": "^19.0.0",
34
+ "react-dom": "^19.0.0",
35
+ "typescript": "^5.4.0",
36
+ "vite": "^6.0.0"
37
+ },
38
+ "keywords": [
39
+ "laravel",
40
+ "inertia",
41
+ "toast",
42
+ "react",
43
+ "notifications"
44
+ ]
45
+ }