@t007/toast 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 OLUWATOBILOBA OKETADE
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,243 @@
1
+ # @t007/toast
2
+
3
+ > A high-performance, physics-driven vanilla JavaScript toast notification system. Features multi-touch drag-to-close gestures, hardware-accelerated animations, and a seamless Promise-resolution API.
4
+
5
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
6
+ [![NPM Version](https://img.shields.io/npm/v/@t007/toast.svg)](https://www.npmjs.com/package/@t007/toast)
7
+
8
+ [Live Demo](https://tobi007-del.github.io/t007-tools/packages/toast/src/index.html) | [Report Bug](https://github.com/Tobi007-del/t007-tools/issues)
9
+
10
+ ---
11
+
12
+ ## Table of contents
13
+
14
+ - [@t007/toast](#t007toast)
15
+ - [Table of contents](#table-of-contents)
16
+ - [Overview](#overview)
17
+ - [Demo \& Screenshots](#demo--screenshots)
18
+ - [Features](#features)
19
+ - [Tech Stack](#tech-stack)
20
+ - [Getting Started](#getting-started)
21
+ - [Usage](#usage)
22
+ - [API Reference](#api-reference)
23
+ - [Advanced Customization](#advanced-customization)
24
+ - [Author](#author)
25
+ - [Acknowledgments](#acknowledgments)
26
+ - [Star History](#star-history)
27
+
28
+ ---
29
+
30
+ ## Overview
31
+
32
+ **@t007/toast** is not just another notification library. It is a highly optimized, requestAnimationFrame-driven notification engine that mimics native mobile OS behaviors. It handles complex pointer gestures, pauses on window blur/hover, and manages a dynamic queue to prevent screen flooding.
33
+
34
+ ### Why @t007/toast?
35
+
36
+ - ✅ **Physics-Driven Gestures:** Native-feeling "drag-to-close" utilizing Pointer Events (`x`, `y`, and directional configuration).
37
+ - ✅ **Intelligent Lifecycle:** Automatically pauses the auto-close timer and progress bar when hovered or when the browser tab loses focus.
38
+ - ✅ **Promise Integration:** Pass an async operation and the toast will automatically transition from "loading" to "success" or "error".
39
+ - ✅ **Haptic Feedback:** Optional built-in `navigator.vibrate` integration for physical feedback on mobile devices.
40
+ - ✅ **Zero Frameworks:** Pure vanilla JS, meaning it works flawlessly in React, Vue, Angular, or raw HTML.
41
+
42
+ ---
43
+
44
+ ## Demo & Screenshots
45
+
46
+ ### Standard Toast Notifications
47
+ Features built-in SVG icons, custom actions, and smooth hardware-accelerated animations.
48
+ <img src="https://raw.githubusercontent.com/Tobi007-del/t007-tools/refs/heads/main/assets/images/toast_library_toast_preview.png" alt="Toast Preview" width="600" />
49
+
50
+ ---
51
+
52
+ ## Features
53
+
54
+ - **9 Positioning Zones**: Anchor toasts anywhere on the screen (e.g., `top-right`, `bottom-center`, `center-center`).
55
+ - **Dynamic Updating**: Update the text, icon, or type of an active toast without breaking its animation loop.
56
+ - **Queue Management**: Strict enforcement of `maxToasts` and `renotify` to keep the UI clean.
57
+ - **Custom Hardware Vibrations**: Unique vibration patterns for different alert types (`success`, `error`, `warning`).
58
+
59
+ ---
60
+
61
+ ## Tech Stack
62
+
63
+ ### Built with
64
+
65
+ - Vanilla JavaScript (ES6+)
66
+ - `requestAnimationFrame` Time Loops
67
+ - Pointer Events API
68
+ - Vibration API
69
+ - Bundled via `tsup` (ESM, CJS, IIFE outputs)
70
+
71
+ ---
72
+
73
+ ## Getting Started
74
+
75
+ ### Installation
76
+
77
+ Install via your preferred package manager:
78
+
79
+ ```bash
80
+ npm install @t007/toast @t007/utils
81
+ # or
82
+ yarn add @t007/toast @t007/utils
83
+ # or
84
+ pnpm add @t007/toast @t007/utils
85
+ ````
86
+
87
+ -----
88
+
89
+ ## Usage
90
+
91
+ ### Modern Bundlers (ESM)
92
+
93
+ ```javascript
94
+ import '@t007/toast/style.css';
95
+ import toast from '@t007/toast'; // also attached to window.t007
96
+
97
+ // 1. Simple success toast
98
+ toast.success("File uploaded successfully!");
99
+
100
+ // 2. Error toast with custom actions
101
+ toast.error("Connection failed", {
102
+ position: "bottom-right",
103
+ actions: {
104
+ "Retry": (e, instance) => {
105
+ console.log("Retrying...");
106
+ instance._remove();
107
+ }
108
+ }
109
+ });
110
+
111
+ // 3. Promise Handling
112
+ const myFetch = fetch('[https://api.example.com/data](https://api.example.com/data)');
113
+
114
+ toast.promise(myFetch, {
115
+ pending: "Loading data...",
116
+ success: "Data loaded successfully!",
117
+ error: "Failed to load data."
118
+ });
119
+ ```
120
+
121
+ ### CDN / Browser (Global)
122
+
123
+ If you are not using a bundler, the library automatically injects itself into the global `t007` object and provides the convenient `window.Toast` fallback.
124
+
125
+ ```html
126
+ <!DOCTYPE html>
127
+ <html>
128
+ <head>
129
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@t007/toast@latest/dist/index.min.css">
130
+ </head>
131
+ <body>
132
+
133
+ <button id="notifyBtn">Show Toast</button>
134
+
135
+ <script src="https://cdn.jsdelivr.net/npm/@t007/toast@latest"></script>
136
+
137
+ <script>
138
+ document.getElementById('notifyBtn').addEventListener('click', () => {
139
+ Toast.info("System running smoothly.", {
140
+ pauseOnHover: true,
141
+ dragToClose: true
142
+ }); // or use `t007.toast -> t007.toast.info()`
143
+ });
144
+ </script>
145
+ </body>
146
+ </html>
147
+ ```
148
+
149
+ -----
150
+
151
+ ## API Reference
152
+
153
+ ### Basic Toasts
154
+
155
+ Trigger toasts based on their severity. Returns the unique `id` of the generated toast.
156
+
157
+ - `toast(render, options)` (Default / Info)
158
+ - `toast.info(render, options)`
159
+ - `toast.success(render, options)`
160
+ - `toast.warn(render, options)`
161
+ - `toast.error(render, options)`
162
+
163
+ ### Toast Updating
164
+
165
+ You can dynamically update a toast that is currently on the screen.
166
+
167
+ ```javascript
168
+ const toastId = toast.loading("Processing...");
169
+
170
+ // Later in your code...
171
+ toast.update(toastId, {
172
+ render: "Processing complete!",
173
+ type: "success",
174
+ isLoading: false,
175
+ autoClose: 3000
176
+ });
177
+ ```
178
+
179
+ ### Promise Handling
180
+
181
+ Automatically maps a JavaScript Promise to the lifecycle of a toast.
182
+
183
+ ```javascript
184
+ toast.promise(promiseFunction, {
185
+ pending: { render: "Waiting...", type: "info" },
186
+ success: { render: (res) => `Success: ${res.data}`, type: "success" },
187
+ error: { render: (err) => `Failed: ${err.message}`, type: "error" }
188
+ });
189
+ ```
190
+
191
+ ### Configuration Options
192
+
193
+ The second argument of any toast call accepts a massive configuration object.
194
+
195
+ | Property | Type | Default | Description |
196
+ | ------------------ | -------------- | ------------- | --------------------------------------------------------- |
197
+ | `position` | String | `"top-right"` | The screen anchor point. |
198
+ | `autoClose` | Boolean/Number | `true` | MS to close, or false to disable. |
199
+ | `dragToClose` | Boolean/String | `true` | Allows swipe-to-dismiss via Pointer Events. |
200
+ | `dragToCloseDir` | String | `"x"` | Direction allowed for swiping (`x`, `y`, `x\|y`). |
201
+ | `pauseOnHover` | Boolean | `true` | Pauses timer when mouse enters toast. |
202
+ | `pauseOnFocusLoss` | Boolean | `true` | Pauses timer when window loses focus. |
203
+ | `vibrate` | Boolean/Array | `false` | Triggers device haptic feedback based on severity. |
204
+ | `actions` | Object | `null` | Key/Value object of button labels and callback functions. |
205
+
206
+ *(See source code for global configuration overrides via `t007.TOAST_DEFAULT_OPTIONS`).*
207
+
208
+ -----
209
+
210
+ ## Advanced Customization
211
+
212
+ ### The Global Config
213
+
214
+ You can override the default behavior for all toasts globally:
215
+
216
+ ```javascript
217
+ window.t007.TOAST_DEFAULT_OPTIONS.position = "bottom-center";
218
+ window.t007.TOAST_DEFAULT_OPTIONS.vibrate = true;
219
+
220
+ // Custom Durations
221
+ window.t007.TOAST_DURATIONS.error = 10000; // Leave errors up for 10 seconds
222
+ ```
223
+
224
+ ### CSS Variables
225
+
226
+ You can easily override the progress bar, animations, and container spacing by targeting `.t007-toast` in your stylesheet.
227
+
228
+ -----
229
+
230
+ ## Author
231
+
232
+ - Developer - [Oketade Oluwatobiloba (Tobi007-del)](https://github.com/Tobi007-del)
233
+ - Project - [t007-tools](https://github.com/Tobi007-del/t007-tools)
234
+
235
+ ## Acknowledgments
236
+
237
+ Designed to bring native mobile OS notification physics to the web. Part of the `@t007` utility ecosystem.
238
+
239
+ ## Star History
240
+
241
+ If you find this project useful, please consider giving it a star! ⭐
242
+
243
+ [![Star History Chart](https://api.star-history.com/svg?repos=Tobi007-del/t007-tools&type=Date)](https://github.com/Tobi007-del/t007-tools)
@@ -1,9 +1,6 @@
1
1
  "use strict";
2
2
  (() => {
3
3
  // ../utils/dist/index.js
4
- function clamp(min = 0, val, max = Infinity) {
5
- return Math.min(Math.max(val, min), max);
6
- }
7
4
  function uid(prefix = "") {
8
5
  return prefix + Date.now().toString(36) + "_" + performance.now().toString(36).replace(".", "") + "_" + Math.random().toString(36).slice(2);
9
6
  }
@@ -31,8 +28,11 @@
31
28
  for (const k of Object.keys(styles)) if (styles[k] !== void 0) el.style[k] = styles[k];
32
29
  }
33
30
  }
34
- function loadResource(src, type = "style", { module, media, crossOrigin, integrity, referrerPolicy, nonce, fetchPriority, attempts = 3, retryKey = false } = {}, w = window) {
31
+ var VIRTUAL_RESOURCE = /* @__PURE__ */ Symbol.for("T007_VIRTUAL_RESOURCE");
32
+ function loadResource(req, type = "style", { module, media, crossOrigin, integrity, referrerPolicy, nonce, fetchPriority, attempts = 3, retryKey = false } = {}, w = window) {
35
33
  w.t007._resourceCache ??= {};
34
+ if (req === VIRTUAL_RESOURCE || "symbol" === typeof req) return Promise.resolve();
35
+ const src = req;
36
36
  if (w.t007._resourceCache[src]) return w.t007._resourceCache[src];
37
37
  const existing = type === "script" ? Array.prototype.find.call(w.document.scripts, (s) => isSameURL(s.src, src)) : type === "style" ? Array.prototype.find.call(w.document.styleSheets, (s) => isSameURL(s.href, src)) : null;
38
38
  if (existing) return w.t007._resourceCache[src] = Promise.resolve(existing);
@@ -56,6 +56,9 @@
56
56
  });
57
57
  return w.t007._resourceCache[src];
58
58
  }
59
+ function clamp(min = 0, val, max = Infinity) {
60
+ return Math.min(Math.max(val, min), max);
61
+ }
59
62
  function onAllMethods(owner, callback) {
60
63
  let proto = owner;
61
64
  while (proto && proto !== Object.prototype) {
@@ -74,12 +77,13 @@
74
77
  }
75
78
  if (typeof window !== "undefined") {
76
79
  window.t007 ??= {};
80
+ t007.VIRTUAL_RESOURCE = VIRTUAL_RESOURCE;
77
81
  window.T007_TOAST_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest`;
78
82
  window.T007_INPUT_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest`;
79
83
  window.T007_DIALOG_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest`;
80
- window.T007_TOAST_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest/dist/index.css`;
81
- window.T007_INPUT_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest/dist/index.css`;
82
- window.T007_DIALOG_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest/dist/index.css`;
84
+ window.T007_TOAST_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest/dist/index.min.css`;
85
+ window.T007_INPUT_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest/dist/index.min.css`;
86
+ window.T007_DIALOG_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest/dist/index.min.css`;
83
87
  }
84
88
 
85
89
  // src/index.js
@@ -1,7 +1,4 @@
1
1
  // ../utils/dist/index.js
2
- function clamp(min = 0, val, max = Infinity) {
3
- return Math.min(Math.max(val, min), max);
4
- }
5
2
  function uid(prefix = "") {
6
3
  return prefix + Date.now().toString(36) + "_" + performance.now().toString(36).replace(".", "") + "_" + Math.random().toString(36).slice(2);
7
4
  }
@@ -29,8 +26,11 @@ function assignEl(el, props, dataset, styles) {
29
26
  for (const k of Object.keys(styles)) if (styles[k] !== void 0) el.style[k] = styles[k];
30
27
  }
31
28
  }
32
- function loadResource(src, type = "style", { module, media, crossOrigin, integrity, referrerPolicy, nonce, fetchPriority, attempts = 3, retryKey = false } = {}, w = window) {
29
+ var VIRTUAL_RESOURCE = /* @__PURE__ */ Symbol.for("T007_VIRTUAL_RESOURCE");
30
+ function loadResource(req, type = "style", { module, media, crossOrigin, integrity, referrerPolicy, nonce, fetchPriority, attempts = 3, retryKey = false } = {}, w = window) {
33
31
  w.t007._resourceCache ??= {};
32
+ if (req === VIRTUAL_RESOURCE || "symbol" === typeof req) return Promise.resolve();
33
+ const src = req;
34
34
  if (w.t007._resourceCache[src]) return w.t007._resourceCache[src];
35
35
  const existing = type === "script" ? Array.prototype.find.call(w.document.scripts, (s) => isSameURL(s.src, src)) : type === "style" ? Array.prototype.find.call(w.document.styleSheets, (s) => isSameURL(s.href, src)) : null;
36
36
  if (existing) return w.t007._resourceCache[src] = Promise.resolve(existing);
@@ -54,6 +54,9 @@ function loadResource(src, type = "style", { module, media, crossOrigin, integri
54
54
  });
55
55
  return w.t007._resourceCache[src];
56
56
  }
57
+ function clamp(min = 0, val, max = Infinity) {
58
+ return Math.min(Math.max(val, min), max);
59
+ }
57
60
  function onAllMethods(owner, callback) {
58
61
  let proto = owner;
59
62
  while (proto && proto !== Object.prototype) {
@@ -72,12 +75,13 @@ function bindAllMethods(owner) {
72
75
  }
73
76
  if (typeof window !== "undefined") {
74
77
  window.t007 ??= {};
78
+ t007.VIRTUAL_RESOURCE = VIRTUAL_RESOURCE;
75
79
  window.T007_TOAST_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest`;
76
80
  window.T007_INPUT_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest`;
77
81
  window.T007_DIALOG_JS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest`;
78
- window.T007_TOAST_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest/dist/index.css`;
79
- window.T007_INPUT_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest/dist/index.css`;
80
- window.T007_DIALOG_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest/dist/index.css`;
82
+ window.T007_TOAST_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/toast@latest/dist/index.min.css`;
83
+ window.T007_INPUT_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/input@latest/dist/index.min.css`;
84
+ window.T007_DIALOG_CSS_SRC ??= `https://cdn.jsdelivr.net/npm/@t007/dialog@latest/dist/index.min.css`;
81
85
  }
82
86
 
83
87
  // src/index.js
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@t007/toast",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "A lightweight, pure JS toast system.",
5
5
  "author": "Oketade Oluwatobiloba <tobioketade007@gmail.com>",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "git+https://github.com/tobi007-del/t007-tools.git",
9
+ "url": "git+https://github.com/Tobi007-del/t007-tools.git",
10
10
  "directory": "packages/toast"
11
11
  },
12
- "homepage": "https://github.com/tobi007-del/t007-tools/tree/main/packages/toast#readme",
12
+ "homepage": "https://github.com/Tobi007-del/t007-tools/blob/main/packages/toast#readme",
13
13
  "bugs": {
14
- "url": "https://github.com/tobi007-del/t007-tools/issues"
14
+ "url": "https://github.com/Tobi007-del/t007-tools/issues"
15
15
  },
16
16
  "type": "module",
17
17
  "main": "./dist/index.js",
@@ -33,24 +33,26 @@
33
33
  "./global": "./dist/index.global.js",
34
34
  "./style.css": "./dist/index.css"
35
35
  },
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
36
39
  "scripts": {
37
- "build": "tsup --config ../../tsup.config.ts"
40
+ "build": "tsup --config ../../tsup.config.ts",
41
+ "prepublishOnly": "shx cp ../../LICENSE ."
38
42
  },
39
43
  "files": [
40
- "dist",
41
- "./dist/index.d.ts",
42
- "./dist/index.css"
44
+ "dist"
43
45
  ],
44
46
  "keywords": [
45
47
  "t007",
48
+ "ecosystem",
49
+ "ui",
50
+ "vanilla-js",
46
51
  "toast",
47
52
  "snackbar",
48
53
  "notification",
49
54
  "alert",
50
- "promise",
51
- "ui",
52
- "vanilla-js",
53
- "zero-dependency"
55
+ "promise"
54
56
  ],
55
57
  "dependencies": {
56
58
  "@t007/utils": "*"