@t007/toast 0.0.5 → 0.0.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/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,236 @@
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
+
27
+ ---
28
+
29
+ ## Overview
30
+
31
+ **@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.
32
+
33
+ ### Why @t007/toast?
34
+
35
+ - ✅ **Physics-Driven Gestures:** Native-feeling "drag-to-close" utilizing Pointer Events (`x`, `y`, and directional configuration).
36
+ - ✅ **Intelligent Lifecycle:** Automatically pauses the auto-close timer and progress bar when hovered or when the browser tab loses focus.
37
+ - ✅ **Promise Integration:** Pass an async operation and the toast will automatically transition from "loading" to "success" or "error".
38
+ - ✅ **Haptic Feedback:** Optional built-in `navigator.vibrate` integration for physical feedback on mobile devices.
39
+ - ✅ **Zero Frameworks:** Pure vanilla JS, meaning it works flawlessly in React, Vue, Angular, or raw HTML.
40
+
41
+ ---
42
+
43
+ ## Demo & Screenshots
44
+
45
+ ### Standard Toast Notifications
46
+ Features built-in SVG icons, custom actions, and smooth hardware-accelerated animations.
47
+ <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" />
48
+
49
+ ---
50
+
51
+ ## Features
52
+
53
+ - **9 Positioning Zones**: Anchor toasts anywhere on the screen (e.g., `top-right`, `bottom-center`, `center-center`).
54
+ - **Dynamic Updating**: Update the text, icon, or type of an active toast without breaking its animation loop.
55
+ - **Queue Management**: Strict enforcement of `maxToasts` and `renotify` to keep the UI clean.
56
+ - **Custom Hardware Vibrations**: Unique vibration patterns for different alert types (`success`, `error`, `warning`).
57
+
58
+ ---
59
+
60
+ ## Tech Stack
61
+
62
+ ### Built with
63
+
64
+ - Vanilla JavaScript (ES6+)
65
+ - `requestAnimationFrame` Time Loops
66
+ - Pointer Events API
67
+ - Vibration API
68
+ - Bundled via `tsup` (ESM, CJS, IIFE outputs)
69
+
70
+ ---
71
+
72
+ ## Getting Started
73
+
74
+ ### Installation
75
+
76
+ Install via your preferred package manager:
77
+
78
+ ```bash
79
+ npm install @t007/toast @t007/utils
80
+ # or
81
+ yarn add @t007/toast @t007/utils
82
+ # or
83
+ pnpm add @t007/toast @t007/utils
84
+ ````
85
+
86
+ -----
87
+
88
+ ## Usage
89
+
90
+ ### Modern Bundlers (ESM)
91
+
92
+ ```javascript
93
+ import '@t007/toast/style.css';
94
+ import toast from '@t007/toast'; // also attached to window.t007
95
+
96
+ // 1. Simple success toast
97
+ toast.success("File uploaded successfully!");
98
+
99
+ // 2. Error toast with custom actions
100
+ toast.error("Connection failed", {
101
+ position: "bottom-right",
102
+ actions: {
103
+ "Retry": (e, instance) => {
104
+ console.log("Retrying...");
105
+ instance._remove();
106
+ }
107
+ }
108
+ });
109
+
110
+ // 3. Promise Handling
111
+ const myFetch = fetch('[https://api.example.com/data](https://api.example.com/data)');
112
+
113
+ toast.promise(myFetch, {
114
+ pending: "Loading data...",
115
+ success: "Data loaded successfully!",
116
+ error: "Failed to load data."
117
+ });
118
+ ```
119
+
120
+ ### CDN / Browser (Global)
121
+
122
+ If you are not using a bundler, the library automatically injects itself into the global `t007` object and provides the convenient `window.Toast` fallback.
123
+
124
+ ```html
125
+ <!DOCTYPE html>
126
+ <html>
127
+ <head>
128
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@t007/toast@latest/dist/index.min.css">
129
+ </head>
130
+ <body>
131
+
132
+ <button id="notifyBtn">Show Toast</button>
133
+
134
+ <script src="https://cdn.jsdelivr.net/npm/@t007/toast@latest"></script>
135
+
136
+ <script>
137
+ document.getElementById('notifyBtn').addEventListener('click', () => {
138
+ Toast.info("System running smoothly.", {
139
+ pauseOnHover: true,
140
+ dragToClose: true
141
+ }); // or use `t007.toast -> t007.toast.info()`
142
+ });
143
+ </script>
144
+ </body>
145
+ </html>
146
+ ```
147
+
148
+ -----
149
+
150
+ ## API Reference
151
+
152
+ ### Basic Toasts
153
+
154
+ Trigger toasts based on their severity. Returns the unique `id` of the generated toast.
155
+
156
+ - `toast(render, options)` (Default / Info)
157
+ - `toast.info(render, options)`
158
+ - `toast.success(render, options)`
159
+ - `toast.warn(render, options)`
160
+ - `toast.error(render, options)`
161
+
162
+ ### Toast Updating
163
+
164
+ You can dynamically update a toast that is currently on the screen.
165
+
166
+ ```javascript
167
+ const toastId = toast.loading("Processing...");
168
+
169
+ // Later in your code...
170
+ toast.update(toastId, {
171
+ render: "Processing complete!",
172
+ type: "success",
173
+ isLoading: false,
174
+ autoClose: 3000
175
+ });
176
+ ```
177
+
178
+ ### Promise Handling
179
+
180
+ Automatically maps a JavaScript Promise to the lifecycle of a toast.
181
+
182
+ ```javascript
183
+ toast.promise(promiseFunction, {
184
+ pending: { render: "Waiting...", type: "info" },
185
+ success: { render: (res) => `Success: ${res.data}`, type: "success" },
186
+ error: { render: (err) => `Failed: ${err.message}`, type: "error" }
187
+ });
188
+ ```
189
+
190
+ ### Configuration Options
191
+
192
+ The second argument of any toast call accepts a massive configuration object.
193
+
194
+ | Property | Type | Default | Description |
195
+ | ------------------ | -------------- | ------------- | --------------------------------------------------------- |
196
+ | `position` | String | `"top-right"` | The screen anchor point. |
197
+ | `autoClose` | Boolean/Number | `true` | MS to close, or false to disable. |
198
+ | `dragToClose` | Boolean/String | `true` | Allows swipe-to-dismiss via Pointer Events. |
199
+ | `dragToCloseDir` | String | `"x"` | Direction allowed for swiping (`x`, `y`, `x\|y`). |
200
+ | `pauseOnHover` | Boolean | `true` | Pauses timer when mouse enters toast. |
201
+ | `pauseOnFocusLoss` | Boolean | `true` | Pauses timer when window loses focus. |
202
+ | `vibrate` | Boolean/Array | `false` | Triggers device haptic feedback based on severity. |
203
+ | `actions` | Object | `null` | Key/Value object of button labels and callback functions. |
204
+
205
+ *(See source code for global configuration overrides via `t007.TOAST_DEFAULT_OPTIONS`).*
206
+
207
+ -----
208
+
209
+ ## Advanced Customization
210
+
211
+ ### The Global Config
212
+
213
+ You can override the default behavior for all toasts globally:
214
+
215
+ ```javascript
216
+ window.t007.TOAST_DEFAULT_OPTIONS.position = "bottom-center";
217
+ window.t007.TOAST_DEFAULT_OPTIONS.vibrate = true;
218
+
219
+ // Custom Durations
220
+ window.t007.TOAST_DURATIONS.error = 10000; // Leave errors up for 10 seconds
221
+ ```
222
+
223
+ ### CSS Variables
224
+
225
+ You can easily override the progress bar, animations, and container spacing by targeting `.t007-toast` in your stylesheet.
226
+
227
+ -----
228
+
229
+ ## Author
230
+
231
+ - Developer - [Oketade Oluwatobiloba (Tobi007-del)](https://github.com/Tobi007-del)
232
+ - Project - [t007-tools](https://github.com/Tobi007-del/t007-tools)
233
+
234
+ ## Acknowledgments
235
+
236
+ Designed to bring native mobile OS notification physics to the web. Part of the `@t007` utility ecosystem.
@@ -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.6",
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": "*"