d9-toast 1.0.10 → 1.0.12

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
@@ -1,15 +1,17 @@
1
1
  # D9-Toast
2
2
 
3
- Customizable toast notifications for React with TailwindCSS support.
3
+ Customizable toast notifications for React.
4
+
4
5
 
5
6
  **Features:**
6
7
 
7
- * Lightweight and fully customizable toast notifications.
8
- * Built with React.
9
- * Tailwind CSS included—no setup required.
10
- * Easy to import and use in any React project.
11
- * Supports multiple types: success, error, info, warning.
12
- * Fully responsive and modern UI.
8
+ * Lightweight and fully customizable toast notifications.
9
+ * Built with React.
10
+ * Pure CSS included no additional setup required.
11
+ * Easy to import and use in any React project.
12
+ * Supports multiple types: success, error, info, warning, loading, submit.
13
+ * Fully responsive and modern UI.
14
+ * Users can optionally add Tailwind CSS classes via `className` for custom styling.
13
15
 
14
16
  ---
15
17
 
@@ -64,6 +66,7 @@ function App() {
64
66
  actions: [
65
67
  { text: "Undo", callback: () => console.log("Undo clicked") },
66
68
  ],
69
+ className: "bg-green-500 text-white shadow-lg", // optional Tailwind/custom styling
67
70
  });
68
71
  };
69
72
 
@@ -92,6 +95,7 @@ export default App;
92
95
  | `actions` | array | [] | Array of action objects `{ text: string, callback: function }` |
93
96
  | `closable` | boolean | true | Show close button |
94
97
  | `progress` | boolean | true | Show progress bar |
98
+ | `className` | string| " " | Optional extra CSS/Tailwind classes to customize the toast bar |
95
99
 
96
100
  ---
97
101
 
@@ -103,17 +107,18 @@ export default App;
103
107
  npm run build
104
108
  ```
105
109
 
106
- * Generates CSS in `dist/toast.css` using TailwindCSS
107
- * Generates JS in `dist/` using Babel
110
+ * Copies JS to `dist/`
111
+ * Copies CSS `(toast.css)` to `dist/`
108
112
 
109
- ### Tailwind Support
113
+ ### Styling
110
114
 
111
- Make sure your project has Tailwind installed. If not, include the `toast.css` from `dist/` in your project:
115
+ * Default styling is included in dist/toast.css
116
+ * Users can optionally override or extend styles using className
112
117
 
113
118
  ```jsx
114
- import 'd9-toast/dist/toast.css';
119
+ import "d9-toast/dist/toast.css";
115
120
  ```
116
-
121
+ * Tailwind CSS is optional — you can pass Tailwind classes via className.
117
122
  ---
118
123
 
119
124
  ## License
package/dist/Toast.js CHANGED
@@ -5,6 +5,7 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
5
5
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
6
6
  function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
7
7
  import React, { useEffect, useRef, useState } from "react";
8
+ import "./toast.css";
8
9
  import Icons from "./Icons";
9
10
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
10
11
  var Toast = function Toast(_ref) {
@@ -14,6 +15,8 @@ var Toast = function Toast(_ref) {
14
15
  type = _ref$type === void 0 ? "info" : _ref$type,
15
16
  _ref$theme = _ref.theme,
16
17
  theme = _ref$theme === void 0 ? "light" : _ref$theme,
18
+ _ref$className = _ref.className,
19
+ className = _ref$className === void 0 ? "" : _ref$className,
17
20
  _ref$duration = _ref.duration,
18
21
  duration = _ref$duration === void 0 ? 5000 : _ref$duration,
19
22
  _ref$actions = _ref.actions,
@@ -75,21 +78,21 @@ var Toast = function Toast(_ref) {
75
78
  // time to left...
76
79
  var timeToLeft = remaining.current - elapsed;
77
80
  // set shrink bar...
78
- setProgressWidth(Math.max(timeToLeft / duration * 100, 0));
81
+ setProgressWidth(timeToLeft / duration * 100);
79
82
  if (timeToLeft <= 0) {
80
83
  // stop timer...
81
84
  clearInterval(intervalRef.current);
82
85
  // remove toast.
83
86
  remove();
84
87
  }
85
- }, 50);
88
+ }, 100);
86
89
  };
87
90
 
88
91
  // for pause
89
92
  var pauseTimer = function pauseTimer() {
90
93
  if (isPaused) return;
91
94
  clearInterval(intervalRef.current);
92
- remaining.current -= Date.now() - start.current;
95
+ remaining.current = remaining.current - (Date.now() - start.current);
93
96
  setPaused(true);
94
97
  };
95
98
 
@@ -102,45 +105,34 @@ var Toast = function Toast(_ref) {
102
105
  };
103
106
 
104
107
  // Styles
105
- var colors = {
106
- success: "bg-green-600/20 text-green-600",
107
- error: "bg-red-600/20 text-red-600",
108
- info: "bg-blue-600/20 text-blue-600",
109
- warning: "bg-yellow-600/20 text-yellow-600",
110
- loading: theme === "light" ? "bg-gray-950/20 text-gray-950" : "bg-gray-50/20 text-gray-50",
111
- submit: theme === "light" ? "bg-gray-600/20 text-gray-600" : "bg-gray-600/50 text-gray-200"
112
- };
113
- var keyframes = "\n @keyframes downToUp{ from {transform: translateY(100%); opacity:0} to {transform:translateY(0); opacity:1} }\n @keyframes upToDown{ from {transform: translateY(-100%); opacity:0} to {transform:translateY(0); opacity:1} }\n ";
114
- var animation = "".concat(position.includes("top") ? "upToDown" : "downToUp", " 0.3s ease-in");
115
- return /*#__PURE__*/_jsxs(_Fragment, {
116
- children: [/*#__PURE__*/_jsx("style", {
117
- children: keyframes
118
- }), /*#__PURE__*/_jsxs("div", {
108
+ var animation = "".concat(position.startsWith("top") && "upToDown" || position.startsWith("bottom") && "downToUp" || position.endsWith("top") && "upToDown" || position.endsWith("bottom") && "downToUp", " 0.3s ease-in");
109
+ return /*#__PURE__*/_jsx(_Fragment, {
110
+ children: /*#__PURE__*/_jsxs("div", {
119
111
  style: {
120
112
  animation: animation
121
113
  },
122
- className: "w-80 ".concat(theme === "light" ? "bg-gray-50 text-gray-950" : "bg-gray-950 text-gray-50", " shadow-lg rounded-lg p-1.5 flex flex-col gap-2 relative"),
114
+ className: "toast ".concat(theme, " ").concat(className),
123
115
  onMouseEnter: pauseOnHover ? pauseTimer : undefined,
124
116
  onMouseLeave: pauseOnHover ? resumeTimer : undefined,
125
117
  children: [/*#__PURE__*/_jsxs("div", {
126
- className: "flex justify-between items-center px-1 py-0.5 rounded-md inset-shadow-2xs ".concat(colors[type]),
118
+ className: "toastHeader ".concat(type),
127
119
  children: [/*#__PURE__*/_jsxs("span", {
128
- className: "flex items-center gap-2 font-medium text-base",
129
120
  children: [/*#__PURE__*/_jsx(Icons, {
130
121
  name: type
131
122
  }), " ", type.toUpperCase()]
132
123
  }), closable && /*#__PURE__*/_jsx("button", {
133
- className: " hover:text-red-600 cursor-pointer",
134
124
  onClick: remove,
135
125
  children: /*#__PURE__*/_jsx(Icons, {
136
126
  name: "X"
137
127
  })
138
128
  })]
139
129
  }), /*#__PURE__*/_jsx("p", {
140
- className: "p-1",
130
+ style: {
131
+ padding: "4px"
132
+ },
141
133
  children: message
142
134
  }), actions.length > 0 && /*#__PURE__*/_jsx("div", {
143
- className: "flex justify-end gap-2 mb-2",
135
+ className: "toastActions",
144
136
  children: actions.map(function (a, idx) {
145
137
  return /*#__PURE__*/_jsx("button", {
146
138
  onClick: function onClick() {
@@ -149,20 +141,20 @@ var Toast = function Toast(_ref) {
149
141
  id: id
150
142
  });
151
143
  },
152
- className: "px-3 py-1 text-sm rounded ".concat(idx === 1 ? "".concat(colors[type], " bg-transparent") : colors[type], " ").concat(theme === "dark" ? "text-gray-50" : "text-gray-900", " ring cursor-pointer"),
144
+ style: {
145
+ borderColor: "".concat(theme === "dark" ? "#f9fafb33" : "#161d2333")
146
+ },
153
147
  children: a.text
154
148
  }, idx);
155
149
  })
156
150
  }), progress && duration !== 0 && /*#__PURE__*/_jsx("div", {
157
- className: "h-1 w-full bg-gray-200 rounded overflow-hidden absolute bottom-0 left-0",
158
- children: /*#__PURE__*/_jsx("div", {
159
- className: "h-1 ".concat(colors[type], " transition-all"),
160
- style: {
161
- width: "".concat(progressWidth, "%")
162
- }
163
- })
151
+ className: "toast-progress ",
152
+ style: {
153
+ width: "".concat(progressWidth, "%"),
154
+ backgroundColor: "".concat(theme === "dark" ? "#536175" : "#161d2333")
155
+ }
164
156
  })]
165
- })]
157
+ })
166
158
  });
167
159
  };
168
160
  export default Toast;
@@ -16,6 +16,7 @@ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" !=
16
16
  function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
17
17
  import React, { createContext, useCallback, useContext, useState } from "react";
18
18
  import Toast from "./Toast";
19
+ import "./toast.css";
19
20
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
21
  var ToastContext = /*#__PURE__*/createContext();
21
22
  export var useToast = function useToast() {
@@ -35,19 +36,6 @@ export var ToastProvider = function ToastProvider(_ref) {
35
36
  return Date.now() + Math.random();
36
37
  };
37
38
 
38
- // Position classes
39
- var getPositionClasses = function getPositionClasses(position) {
40
- var classes = "fixed z-50 flex gap-3 ";
41
- if (position.includes("top")) classes += "top-4 flex-col ";
42
- if (position.includes("bottom")) classes += "bottom-4 flex-col-reverse ";
43
- if (position.includes("right")) classes += "right-4 ";
44
- if (position.includes("left")) classes += "left-4 ";
45
- if (position === "center") classes += "top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex-col ";
46
- if (position === "center-top") classes += "top-4 left-1/2 -translate-x-1/2 flex-col ";
47
- if (position === "center-bottom") classes += "bottom-4 left-1/2 -translate-x-1/2 flex-col-reverse ";
48
- return classes.trim();
49
- };
50
-
51
39
  // Show toast
52
40
  var showToast = useCallback(function (toast) {
53
41
  var newToast = _objectSpread({
@@ -77,7 +65,7 @@ export var ToastProvider = function ToastProvider(_ref) {
77
65
  removeToast: removeToast
78
66
  },
79
67
  children: [children, /*#__PURE__*/_jsx("div", {
80
- className: getPositionClasses(position),
68
+ className: "toastContainer ".concat(position),
81
69
  children: toasts.map(function (toast) {
82
70
  return /*#__PURE__*/_jsx(Toast, _objectSpread(_objectSpread({}, toast), {}, {
83
71
  position: position,
@@ -1,20 +1,48 @@
1
1
  declare module "d9-toast" {
2
2
  import React from "react";
3
3
 
4
- export type ToastType = "success" | "error" | "info" | "warning" | "loading" | "submit";
4
+ export type ToastType =
5
+ | "success"
6
+ | "error"
7
+ | "info"
8
+ | "warning"
9
+ | "loading"
10
+ | "submit";
11
+
12
+ export interface ToastAction {
13
+ text: string;
14
+ callback?: (toast: { id: number }) => void;
15
+ }
5
16
 
6
17
  export interface ToastOptions {
7
18
  message: string;
8
19
  type?: ToastType;
9
20
  duration?: number;
10
- actions?: { text: string; callback?: (toast: { id: number }) => void }[];
21
+ actions?: ToastAction[];
11
22
  theme?: "light" | "dark";
12
23
  progress?: boolean;
13
24
  closable?: boolean;
14
25
  pauseOnHover?: boolean;
15
26
  pauseOnFocusLoss?: boolean;
27
+ className?: string;
16
28
  }
17
29
 
18
- export const ToastProvider: React.FC<{ children: React.ReactNode; position?: string }>;
19
- export const useToast: () => { showToast: (toast: ToastOptions) => void; removeToast: (id: number) => void };
30
+ export interface ToastProviderProps {
31
+ children: React.ReactNode;
32
+ position?:
33
+ | "top-right"
34
+ | "top-left"
35
+ | "bottom-right"
36
+ | "bottom-left"
37
+ | "center"
38
+ | "center-top"
39
+ | "center-bottom";
40
+ }
41
+
42
+ export const ToastProvider: React.FC<ToastProviderProps>;
43
+
44
+ export const useToast: () => {
45
+ showToast: (toast: ToastOptions) => void;
46
+ removeToast: (id: number) => void;
47
+ };
20
48
  }
package/dist/index.js CHANGED
@@ -1,4 +1,2 @@
1
- import React from "react";
2
- import { ToastProvider, useToast } from "./ToastContext";
3
- import "./toast.css";
4
- export { ToastProvider, useToast };
1
+ import "./toast.css"; // default styles
2
+ export { ToastProvider, useToast } from "./ToastContext";
package/dist/toast.css CHANGED
@@ -1,9 +1,164 @@
1
- .d9-toast {
2
- @tailwind base;
3
- @tailwind components;
4
- @tailwind utilities;
1
+ .toastContainer {
2
+ position: fixed;
3
+ z-index: 999;
4
+ display: flex;
5
+ gap: 12px;
6
+ }
7
+ .toastContainer.top-right {
8
+ flex-direction: column;
9
+ top: 16px;
10
+ right: 16px;
11
+ }
12
+ .toastContainer.top-left {
13
+ flex-direction: column;
14
+ top: 16px;
15
+ left: 16px;
16
+ }
17
+ .toastContainer.bottom-right {
18
+ flex-direction: column-reverse;
19
+ bottom: 16px;
20
+ right: 16px;
21
+ }
22
+ .toastContainer.bottom-left {
23
+ flex-direction: column-reverse;
24
+ bottom: 16px;
25
+ left: 16px;
26
+ }
27
+ .toastContainer.center {
28
+ flex-direction: column;
29
+ top: 50%;
30
+ left: 50%;
31
+ transform: translate(-50%, -50%);
32
+ }
33
+ .toastContainer.center-top {
34
+ top: 16px;
35
+ left: 50%;
36
+ transform: translateX(-50%);
37
+ }
38
+ .toastContainer.center-bottom {
39
+ bottom: 16px;
40
+ left: 50%;
41
+ transform: translateX(-50%);
42
+ }
43
+
44
+ .toast {
45
+ position: relative;
46
+ width: 320px;
47
+ display: flex;
48
+ flex-direction: column;
49
+ gap: 8px;
50
+ padding: 6px;
51
+ border-radius: 8px;
52
+ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
53
+ font-family: system-ui, sans-serif;
54
+ transition: all 0.3s ease-in-out;
55
+ }
56
+ .toast.light {
57
+ background-color: #f9fafb;
58
+ color: #030712;
59
+ }
60
+
61
+ .toast.dark {
62
+ background-color: #030712;
63
+ color: #f9fafb;
64
+ }
65
+
66
+
67
+ .toastHeader {
68
+ display: flex;
69
+ justify-content: space-between;
70
+ align-items: center;
71
+ padding: 2px 4px;
72
+ border-radius: 6px;
73
+ box-shadow: inset 0 1px rgb(0 0 0 / 0.05);
74
+ }
75
+ .toastHeader span {
76
+ display: flex;
77
+ align-items: center;
78
+ gap: 8px;
79
+ font-size: 1rem;
80
+ font-weight: 500;
81
+ }
82
+ .toastHeader button:hover {
83
+ cursor: pointer;
84
+ color: oklch(57.7% 0.245 27.325);
85
+ }
86
+
87
+ .toastHeader.success {
88
+ color: oklch(62.7% 0.194 149.214);
89
+ background-color: oklch(63.187% 0.18673 147.227 / 0.2);
90
+ }
91
+ .toastHeader.error {
92
+ color: oklch(57.7% 0.245 27.325);
93
+ background-color: oklch(58.305% 0.23863 28.392 / 0.2);
94
+ }
95
+ .toastHeader.info {
96
+ color: oklch(54.6% 0.245 262.881);
97
+ background-color: oklch(54.6% 0.245 262.881 / 0.1);
98
+ }
99
+ .toastHeader.warning {
100
+ color: oklch(68.1% 0.162 75.834);
101
+ background-color: oklch(68.1% 0.162 75.834 / 0.1);
102
+ }
103
+ .toastHeader.loading,
104
+ .toastHeader.submit {
105
+ color: oklch(48.847% 0.03665 257.306);
106
+ background-color: oklch(44.6% 0.03 256.802 / 0.2);
107
+ }
108
+ .toastActions {
109
+ display: flex;
110
+ justify-content: flex-end;
111
+ gap: 15px;
112
+ margin-right: 5px;
113
+ margin-bottom: 8px;
114
+ }
115
+ .toastActions button {
116
+ padding: 4px 12px;
117
+ font-size: 14px;
118
+ border-radius: 6px;
119
+ border: 1px solid;
120
+ cursor: pointer;
121
+ }
122
+
123
+ .toast-progress {
124
+ position: absolute;
125
+ bottom: 0;
126
+ left: 0;
127
+ height: 0.25rem;
128
+ transition: width 0.1s linear;
129
+ border-radius: 0 0 0.25rem 0.25rem;
130
+ overflow: hidden;
131
+ }
132
+
133
+ @keyframes downToUp {
134
+ from {
135
+ transform: translateY(100%);
136
+ opacity: 0;
137
+ }
138
+ to {
139
+ transform: translateY(0);
140
+ opacity: 1;
141
+ }
142
+ }
143
+
144
+ @keyframes upToDown {
145
+ from {
146
+ transform: translateY(-100%);
147
+ opacity: 0;
148
+ }
149
+ to {
150
+ transform: translateY(0);
151
+ opacity: 1;
152
+ }
5
153
  }
6
154
 
7
- .d9-toast .toast {
8
- /* toast-specific styles */
155
+ @media screen and (max-width: 325px) {
156
+ .toastContainer.top-right,
157
+ .toastContainer.bottom-right {
158
+ right: 0px;
159
+ }
160
+ .toastContainer.top-left,
161
+ .toastContainer.bottom-left {
162
+ left: 0px;
163
+ }
9
164
  }
package/package.json CHANGED
@@ -1,16 +1,18 @@
1
1
  {
2
2
  "name": "d9-toast",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "Customizable toast notifications for React",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
7
7
  "files": [
8
8
  "dist"
9
9
  ],
10
+ "sideEffects": [
11
+ "./dist/toast.css"
12
+ ],
10
13
  "scripts": {
11
- "build:css": "tailwindcss -i ./src/toast.css -o ./dist/toast.css --minify",
12
14
  "build:js": "npx babel src --out-dir dist --copy-files",
13
- "build": "npm run build:css && npm run build:js"
15
+ "build": "npm run build:js"
14
16
  },
15
17
  "peerDependencies": {
16
18
  "react": ">=17",
@@ -20,8 +22,7 @@
20
22
  "react",
21
23
  "toast",
22
24
  "notifications",
23
- "ui",
24
- "tailwind"
25
+ "ui"
25
26
  ],
26
27
  "license": "MIT",
27
28
  "author": "Athul PS",
@@ -29,12 +30,6 @@
29
30
  "@babel/cli": "^7.28.3",
30
31
  "@babel/core": "^7.28.4",
31
32
  "@babel/preset-env": "^7.28.3",
32
- "@babel/preset-react": "^7.27.1",
33
- "autoprefixer": "^10.4.21",
34
- "postcss": "^8.5.6",
35
- "tailwindcss": "^4.1.14"
36
- },
37
- "dependencies": {
38
- "@tailwindcss/cli": "^4.1.14"
33
+ "@babel/preset-react": "^7.27.1"
39
34
  }
40
35
  }