your-toast 0.0.1 → 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.
package/README.md CHANGED
@@ -2,16 +2,24 @@
2
2
 
3
3
  Modern toast notification library for React apps.
4
4
 
5
- ✨ Clean API
6
- 🎨 Glass UI (coming soon)
5
+ ✨ Clean & intuitive API
6
+ 🍏 Glass-style UI
7
7
  ⚡ Lightweight & fast
8
+ 🔄 Promise support
9
+ 🎯 Fully controllable
8
10
 
9
11
  ---
10
12
 
11
- ## 🚧 Status
13
+ ## 🚀 Features
12
14
 
13
- This package is currently under development.
14
- First stable version will be released soon.
15
+ * 🔥 Minimal & powerful API (`toast()`)
16
+ * Promise-based toast (`toast.promise`)
17
+ * 🎨 Multiple variants (default, success, error, loading, action)
18
+ * 📦 Stack management (auto limit)
19
+ * 🔁 Update & dismiss control
20
+ * ⏱ Auto dismiss with duration
21
+ * 🍏 Glass UI (modern design)
22
+ * 🌙 Dark mode ready
15
23
 
16
24
  ---
17
25
 
@@ -26,6 +34,8 @@ npm install your-toast
26
34
  ## 🚀 Basic Usage
27
35
 
28
36
  ```jsx
37
+ "use client";
38
+
29
39
  import { YourToastProvider, toast } from "your-toast";
30
40
 
31
41
  export default function App() {
@@ -41,38 +51,87 @@ export default function App() {
41
51
 
42
52
  ---
43
53
 
44
- ## 🎯 Planned Features
45
-
46
- * 🍏 Apple-style glass UI toast
47
- * ⚡ Promise-based toast system
48
- * 📦 Stack management
49
- * 🎨 Multiple variants (minimal, glass, gradient)
50
- * 🔁 Update & dismiss controls
51
- * 🌙 Dark mode support
52
-
53
- ---
54
-
55
- ## 🧩 Example API (Upcoming)
54
+ ## 🎯 Variants
56
55
 
57
56
  ```js
57
+ toast("Default message");
58
+
58
59
  toast.success("Saved successfully");
59
60
 
60
61
  toast.error("Something went wrong");
61
62
 
63
+ toast.loading("Loading...");
64
+ ```
65
+
66
+ ---
67
+
68
+ ## ⚡ Promise Toast
69
+
70
+ ```js
62
71
  toast.promise(fetchData(), {
63
72
  loading: "Loading...",
64
- success: "Done!",
65
- error: "Error occurred"
73
+ success: "Data loaded!",
74
+ error: "Something went wrong",
75
+ });
76
+ ```
77
+
78
+ ---
79
+
80
+ ## 🔁 Update & Dismiss
81
+
82
+ ```js
83
+ const id = toast("Uploading...");
84
+
85
+ // update
86
+ toast.update(id, {
87
+ title: "Uploaded!",
88
+ type: "success",
89
+ });
90
+
91
+ // dismiss
92
+ toast.dismiss(id);
93
+ ```
94
+
95
+ ---
96
+
97
+ ## 🧩 Advanced Example
98
+
99
+ ```js
100
+ toast("File deleted", {
101
+ action: {
102
+ label: "Undo",
103
+ onClick: () => console.log("Undo clicked"),
104
+ },
66
105
  });
67
106
  ```
68
107
 
69
108
  ---
70
109
 
110
+ ## 🎨 Supported Types
111
+
112
+ * `default`
113
+ * `success`
114
+ * `error`
115
+ * `loading`
116
+ * `action`
117
+
118
+ ---
119
+
71
120
  ## 🛠 Developer Friendly
72
121
 
73
122
  * Simple and predictable API
74
- * Fully customizable
75
- * Built for modern React apps
123
+ * No extra setup required
124
+ * Works with modern React (18+)
125
+ * Lightweight and customizable
126
+
127
+ ---
128
+
129
+ ## 🚧 Roadmap
130
+
131
+ * 🍏 Advanced glass UI polish
132
+ * 🎞 Animation improvements
133
+ * 🎨 Theme system
134
+ * 📱 Mobile UX optimization
76
135
 
77
136
  ---
78
137
 
@@ -84,4 +143,4 @@ MIT
84
143
 
85
144
  ## 👨‍💻 Author
86
145
 
87
- Masaud Ahmod
146
+ Masaud Ahmod
package/dist/index.cjs ADDED
@@ -0,0 +1,233 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ YourToastProvider: () => YourToastProvider,
24
+ toast: () => toast
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/store/toastStore.ts
29
+ var toasts = [];
30
+ var listeners = [];
31
+ function notify() {
32
+ listeners.forEach((listener) => listener(toasts));
33
+ }
34
+ var toastStore = {
35
+ subscribe(listener) {
36
+ listeners.push(listener);
37
+ return () => {
38
+ listeners = listeners.filter((l) => l !== listener);
39
+ };
40
+ },
41
+ getToasts() {
42
+ return toasts;
43
+ },
44
+ add(toast2) {
45
+ toasts = [toast2, ...toasts].slice(0, 5);
46
+ notify();
47
+ },
48
+ remove(id) {
49
+ toasts = toasts.filter((t) => t.id !== id);
50
+ notify();
51
+ },
52
+ update(id, updated) {
53
+ toasts = toasts.map(
54
+ (t) => t.id === id ? { ...t, ...updated } : t
55
+ );
56
+ notify();
57
+ }
58
+ };
59
+
60
+ // src/core/toast.ts
61
+ function createToast(message, type = "default") {
62
+ const id = crypto.randomUUID();
63
+ const duration = 4e3;
64
+ toastStore.add({
65
+ id,
66
+ title: message,
67
+ type,
68
+ duration
69
+ });
70
+ setTimeout(() => {
71
+ toastStore.remove(id);
72
+ }, duration);
73
+ return id;
74
+ }
75
+ var toast = Object.assign(
76
+ (message) => createToast(message, "default"),
77
+ {
78
+ success: (message) => createToast(message, "success"),
79
+ error: (message) => createToast(message, "error"),
80
+ loading: (message) => createToast(message, "loading"),
81
+ action: (message) => createToast(message, "action"),
82
+ dismiss: (id) => {
83
+ toastStore.remove(id);
84
+ },
85
+ update: (id, data) => {
86
+ toastStore.update(id, data);
87
+ },
88
+ promise: async (promise, messages) => {
89
+ const id = createToast(messages.loading, "loading");
90
+ try {
91
+ const result = await promise;
92
+ toastStore.update(id, {
93
+ title: messages.success,
94
+ type: "success"
95
+ });
96
+ return result;
97
+ } catch (err) {
98
+ toastStore.update(id, {
99
+ title: messages.error,
100
+ type: "error"
101
+ });
102
+ throw err;
103
+ }
104
+ }
105
+ }
106
+ );
107
+
108
+ // src/hooks/useToast.ts
109
+ var import_react = require("react");
110
+ function useToast() {
111
+ const [toasts2, setToasts] = (0, import_react.useState)(
112
+ toastStore.getToasts()
113
+ );
114
+ (0, import_react.useEffect)(() => {
115
+ const unsubscribe = toastStore.subscribe(setToasts);
116
+ return unsubscribe;
117
+ }, []);
118
+ return { toasts: toasts2 };
119
+ }
120
+
121
+ // src/components/YourToastProvider.tsx
122
+ var import_jsx_runtime = require("react/jsx-runtime");
123
+ var YourToastProvider = ({
124
+ children
125
+ }) => {
126
+ const { toasts: toasts2 } = useToast();
127
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
128
+ children,
129
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: containerStyle, children: toasts2.map((toast2) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
130
+ "div",
131
+ {
132
+ style: {
133
+ ...toastStyle,
134
+ ...getVariantStyle(toast2.type)
135
+ },
136
+ children: [
137
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", flexDirection: "column" }, children: [
138
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontWeight: 600 }, children: toast2.title }),
139
+ toast2.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { opacity: 0.7, fontSize: "13px" }, children: toast2.description })
140
+ ] }),
141
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
142
+ "button",
143
+ {
144
+ onClick: () => toastStore.remove(toast2.id),
145
+ style: closeBtn,
146
+ children: "\u2715"
147
+ }
148
+ ),
149
+ toast2.action && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
150
+ "button",
151
+ {
152
+ onClick: toast2.action.onClick,
153
+ style: {
154
+ background: "rgba(255,255,255,0.1)",
155
+ border: "none",
156
+ padding: "6px 10px",
157
+ borderRadius: "8px",
158
+ color: "#fff",
159
+ cursor: "pointer",
160
+ fontSize: "12px"
161
+ },
162
+ children: toast2.action.label
163
+ }
164
+ )
165
+ ]
166
+ },
167
+ toast2.id
168
+ )) })
169
+ ] });
170
+ };
171
+ function getVariantStyle(type) {
172
+ switch (type) {
173
+ case "success":
174
+ return { background: "#16a34a" };
175
+ case "error":
176
+ return { background: "#dc2626" };
177
+ case "loading":
178
+ return { background: "#2563eb" };
179
+ case "action":
180
+ return { background: "#7c3aed" };
181
+ default:
182
+ return { background: "#111" };
183
+ }
184
+ }
185
+ var containerStyle = {
186
+ position: "fixed",
187
+ top: 20,
188
+ right: 20,
189
+ display: "flex",
190
+ flexDirection: "column",
191
+ gap: "10px",
192
+ zIndex: 9999
193
+ };
194
+ var toastStyle = {
195
+ backdropFilter: "blur(16px)",
196
+ background: "rgba(255, 255, 255, 0.08)",
197
+ color: "#fff",
198
+ padding: "14px 16px",
199
+ borderRadius: "14px",
200
+ display: "flex",
201
+ justifyContent: "space-between",
202
+ alignItems: "flex-start",
203
+ minWidth: "260px",
204
+ gap: "10px",
205
+ border: "1px solid rgba(255,255,255,0.1)",
206
+ boxShadow: "0 8px 30px rgba(0,0,0,0.3)",
207
+ animation: "yt-slide-in 0.3s ease"
208
+ };
209
+ var closeBtn = {
210
+ background: "transparent",
211
+ border: "none",
212
+ color: "#fff",
213
+ cursor: "pointer"
214
+ };
215
+ var style = document.createElement("style");
216
+ style.innerHTML = `
217
+ @keyframes yt-slide-in {
218
+ from {
219
+ opacity: 0;
220
+ transform: translateY(-10px) translateX(10px);
221
+ }
222
+ to {
223
+ opacity: 1;
224
+ transform: translateY(0) translateX(0);
225
+ }
226
+ }
227
+ `;
228
+ document.head.appendChild(style);
229
+ // Annotate the CommonJS export names for ESM import in node:
230
+ 0 && (module.exports = {
231
+ YourToastProvider,
232
+ toast
233
+ });
@@ -0,0 +1,22 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React from 'react';
3
+
4
+ declare const toast: ((message: string) => `${string}-${string}-${string}-${string}-${string}`) & {
5
+ success: (message: string) => `${string}-${string}-${string}-${string}-${string}`;
6
+ error: (message: string) => `${string}-${string}-${string}-${string}-${string}`;
7
+ loading: (message: string) => `${string}-${string}-${string}-${string}-${string}`;
8
+ action: (message: string) => `${string}-${string}-${string}-${string}-${string}`;
9
+ dismiss: (id: string) => void;
10
+ update: (id: string, data: Partial<any>) => void;
11
+ promise: <T>(promise: Promise<T>, messages: {
12
+ loading: string;
13
+ success: string;
14
+ error: string;
15
+ }) => Promise<T>;
16
+ };
17
+
18
+ declare const YourToastProvider: ({ children, }: {
19
+ children: React.ReactNode;
20
+ }) => react_jsx_runtime.JSX.Element;
21
+
22
+ export { YourToastProvider, toast };
@@ -0,0 +1,22 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React from 'react';
3
+
4
+ declare const toast: ((message: string) => `${string}-${string}-${string}-${string}-${string}`) & {
5
+ success: (message: string) => `${string}-${string}-${string}-${string}-${string}`;
6
+ error: (message: string) => `${string}-${string}-${string}-${string}-${string}`;
7
+ loading: (message: string) => `${string}-${string}-${string}-${string}-${string}`;
8
+ action: (message: string) => `${string}-${string}-${string}-${string}-${string}`;
9
+ dismiss: (id: string) => void;
10
+ update: (id: string, data: Partial<any>) => void;
11
+ promise: <T>(promise: Promise<T>, messages: {
12
+ loading: string;
13
+ success: string;
14
+ error: string;
15
+ }) => Promise<T>;
16
+ };
17
+
18
+ declare const YourToastProvider: ({ children, }: {
19
+ children: React.ReactNode;
20
+ }) => react_jsx_runtime.JSX.Element;
21
+
22
+ export { YourToastProvider, toast };
package/dist/index.js CHANGED
@@ -1,3 +1,205 @@
1
- export const toast = () => {
2
- console.log("your-toast coming soon 🚀");
3
- };
1
+ // src/store/toastStore.ts
2
+ var toasts = [];
3
+ var listeners = [];
4
+ function notify() {
5
+ listeners.forEach((listener) => listener(toasts));
6
+ }
7
+ var toastStore = {
8
+ subscribe(listener) {
9
+ listeners.push(listener);
10
+ return () => {
11
+ listeners = listeners.filter((l) => l !== listener);
12
+ };
13
+ },
14
+ getToasts() {
15
+ return toasts;
16
+ },
17
+ add(toast2) {
18
+ toasts = [toast2, ...toasts].slice(0, 5);
19
+ notify();
20
+ },
21
+ remove(id) {
22
+ toasts = toasts.filter((t) => t.id !== id);
23
+ notify();
24
+ },
25
+ update(id, updated) {
26
+ toasts = toasts.map(
27
+ (t) => t.id === id ? { ...t, ...updated } : t
28
+ );
29
+ notify();
30
+ }
31
+ };
32
+
33
+ // src/core/toast.ts
34
+ function createToast(message, type = "default") {
35
+ const id = crypto.randomUUID();
36
+ const duration = 4e3;
37
+ toastStore.add({
38
+ id,
39
+ title: message,
40
+ type,
41
+ duration
42
+ });
43
+ setTimeout(() => {
44
+ toastStore.remove(id);
45
+ }, duration);
46
+ return id;
47
+ }
48
+ var toast = Object.assign(
49
+ (message) => createToast(message, "default"),
50
+ {
51
+ success: (message) => createToast(message, "success"),
52
+ error: (message) => createToast(message, "error"),
53
+ loading: (message) => createToast(message, "loading"),
54
+ action: (message) => createToast(message, "action"),
55
+ dismiss: (id) => {
56
+ toastStore.remove(id);
57
+ },
58
+ update: (id, data) => {
59
+ toastStore.update(id, data);
60
+ },
61
+ promise: async (promise, messages) => {
62
+ const id = createToast(messages.loading, "loading");
63
+ try {
64
+ const result = await promise;
65
+ toastStore.update(id, {
66
+ title: messages.success,
67
+ type: "success"
68
+ });
69
+ return result;
70
+ } catch (err) {
71
+ toastStore.update(id, {
72
+ title: messages.error,
73
+ type: "error"
74
+ });
75
+ throw err;
76
+ }
77
+ }
78
+ }
79
+ );
80
+
81
+ // src/hooks/useToast.ts
82
+ import { useEffect, useState } from "react";
83
+ function useToast() {
84
+ const [toasts2, setToasts] = useState(
85
+ toastStore.getToasts()
86
+ );
87
+ useEffect(() => {
88
+ const unsubscribe = toastStore.subscribe(setToasts);
89
+ return unsubscribe;
90
+ }, []);
91
+ return { toasts: toasts2 };
92
+ }
93
+
94
+ // src/components/YourToastProvider.tsx
95
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
96
+ var YourToastProvider = ({
97
+ children
98
+ }) => {
99
+ const { toasts: toasts2 } = useToast();
100
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
101
+ children,
102
+ /* @__PURE__ */ jsx("div", { style: containerStyle, children: toasts2.map((toast2) => /* @__PURE__ */ jsxs(
103
+ "div",
104
+ {
105
+ style: {
106
+ ...toastStyle,
107
+ ...getVariantStyle(toast2.type)
108
+ },
109
+ children: [
110
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column" }, children: [
111
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600 }, children: toast2.title }),
112
+ toast2.description && /* @__PURE__ */ jsx("span", { style: { opacity: 0.7, fontSize: "13px" }, children: toast2.description })
113
+ ] }),
114
+ /* @__PURE__ */ jsx(
115
+ "button",
116
+ {
117
+ onClick: () => toastStore.remove(toast2.id),
118
+ style: closeBtn,
119
+ children: "\u2715"
120
+ }
121
+ ),
122
+ toast2.action && /* @__PURE__ */ jsx(
123
+ "button",
124
+ {
125
+ onClick: toast2.action.onClick,
126
+ style: {
127
+ background: "rgba(255,255,255,0.1)",
128
+ border: "none",
129
+ padding: "6px 10px",
130
+ borderRadius: "8px",
131
+ color: "#fff",
132
+ cursor: "pointer",
133
+ fontSize: "12px"
134
+ },
135
+ children: toast2.action.label
136
+ }
137
+ )
138
+ ]
139
+ },
140
+ toast2.id
141
+ )) })
142
+ ] });
143
+ };
144
+ function getVariantStyle(type) {
145
+ switch (type) {
146
+ case "success":
147
+ return { background: "#16a34a" };
148
+ case "error":
149
+ return { background: "#dc2626" };
150
+ case "loading":
151
+ return { background: "#2563eb" };
152
+ case "action":
153
+ return { background: "#7c3aed" };
154
+ default:
155
+ return { background: "#111" };
156
+ }
157
+ }
158
+ var containerStyle = {
159
+ position: "fixed",
160
+ top: 20,
161
+ right: 20,
162
+ display: "flex",
163
+ flexDirection: "column",
164
+ gap: "10px",
165
+ zIndex: 9999
166
+ };
167
+ var toastStyle = {
168
+ backdropFilter: "blur(16px)",
169
+ background: "rgba(255, 255, 255, 0.08)",
170
+ color: "#fff",
171
+ padding: "14px 16px",
172
+ borderRadius: "14px",
173
+ display: "flex",
174
+ justifyContent: "space-between",
175
+ alignItems: "flex-start",
176
+ minWidth: "260px",
177
+ gap: "10px",
178
+ border: "1px solid rgba(255,255,255,0.1)",
179
+ boxShadow: "0 8px 30px rgba(0,0,0,0.3)",
180
+ animation: "yt-slide-in 0.3s ease"
181
+ };
182
+ var closeBtn = {
183
+ background: "transparent",
184
+ border: "none",
185
+ color: "#fff",
186
+ cursor: "pointer"
187
+ };
188
+ var style = document.createElement("style");
189
+ style.innerHTML = `
190
+ @keyframes yt-slide-in {
191
+ from {
192
+ opacity: 0;
193
+ transform: translateY(-10px) translateX(10px);
194
+ }
195
+ to {
196
+ opacity: 1;
197
+ transform: translateY(0) translateX(0);
198
+ }
199
+ }
200
+ `;
201
+ document.head.appendChild(style);
202
+ export {
203
+ YourToastProvider,
204
+ toast
205
+ };
package/package.json CHANGED
@@ -1,12 +1,18 @@
1
1
  {
2
2
  "name": "your-toast",
3
- "version": "0.0.1",
3
+ "version": "0.1.0",
4
4
  "type": "module",
5
5
  "description": "Modern toast notification library for React (coming soon)",
6
- "main": "dist/index.js",
7
- "module": "dist/index.mjs",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.js",
8
8
  "types": "dist/index.d.ts",
9
- "files": ["dist"],
9
+ "scripts": {
10
+ "build": "tsup",
11
+ "dev": "tsup --watch"
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
10
16
  "sideEffects": false,
11
17
  "keywords": [
12
18
  "react",
@@ -15,6 +21,18 @@
15
21
  "ui",
16
22
  "toast-library"
17
23
  ],
24
+ "peerDependencies": {
25
+ "react": ">=18",
26
+ "react-dom": ">=18"
27
+ },
18
28
  "author": "Masaud Ahmod",
19
- "license": "MIT"
20
- }
29
+ "license": "MIT",
30
+ "devDependencies": {
31
+ "@types/react": "^19.2.14",
32
+ "@types/react-dom": "^19.2.3",
33
+ "react": "^19.2.5",
34
+ "react-dom": "^19.2.5",
35
+ "tsup": "^8.5.1",
36
+ "typescript": "^6.0.3"
37
+ }
38
+ }