@r01al/simple-toast 1.0.1 → 1.0.3

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.
@@ -4,237 +4,82 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.SimpleToast = {}));
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
+ function _defineProperty(e, r, t) {
8
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
9
+ value: t,
10
+ enumerable: true,
11
+ configurable: true,
12
+ writable: true
13
+ }) : e[r] = t, e;
14
+ }
15
+ function ownKeys(e, r) {
16
+ var t = Object.keys(e);
17
+ if (Object.getOwnPropertySymbols) {
18
+ var o = Object.getOwnPropertySymbols(e);
19
+ r && (o = o.filter(function (r) {
20
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
21
+ })), t.push.apply(t, o);
22
+ }
23
+ return t;
24
+ }
25
+ function _objectSpread2(e) {
26
+ for (var r = 1; r < arguments.length; r++) {
27
+ var t = null != arguments[r] ? arguments[r] : {};
28
+ r % 2 ? ownKeys(Object(t), true).forEach(function (r) {
29
+ _defineProperty(e, r, t[r]);
30
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
31
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
32
+ });
33
+ }
34
+ return e;
35
+ }
36
+ function _toPrimitive(t, r) {
37
+ if ("object" != typeof t || !t) return t;
38
+ var e = t[Symbol.toPrimitive];
39
+ if (void 0 !== e) {
40
+ var i = e.call(t, r);
41
+ if ("object" != typeof i) return i;
42
+ throw new TypeError("@@toPrimitive must return a primitive value.");
43
+ }
44
+ return ("string" === r ? String : Number)(t);
45
+ }
46
+ function _toPropertyKey(t) {
47
+ var i = _toPrimitive(t, "string");
48
+ return "symbol" == typeof i ? i : i + "";
49
+ }
50
+
7
51
  const defaultConfig = {
8
- position: 'tr',
52
+ position: 'bc',
9
53
  duration: 3000,
10
54
  theme: 'l',
11
55
  dismissible: true,
12
56
  maxToasts: 10
13
57
  };
14
-
15
- let globalConfig = { ...defaultConfig };
16
-
58
+ let globalConfig = _objectSpread2({}, defaultConfig);
17
59
  function configure(config) {
18
- globalConfig = { ...globalConfig, ...config };
60
+ globalConfig = _objectSpread2(_objectSpread2({}, globalConfig), config);
19
61
  }
20
-
21
62
  function getConfig() {
22
63
  return globalConfig;
23
64
  }
24
65
 
25
66
  let stylesInjected = false;
26
-
27
67
  function injectStyles() {
28
68
  if (stylesInjected) return;
29
-
30
69
  const style = document.createElement('style');
31
70
  style.setAttribute('data-r01st', '');
32
- style.textContent = `
33
- .r01st-container {
34
- position: fixed;
35
- z-index: 9999;
36
- pointer-events: none;
37
- padding: 16px;
38
- }
39
- .r01st-container[data-position="tl"] {
40
- top: 0;
41
- left: 0;
42
- }
43
-
44
- .r01st-container[data-position="tc"] {
45
- top: 0;
46
- left: 50%;
47
- margin-left: -210px;
48
- }
49
-
50
- .r01st-container[data-position="tr"] {
51
- top: 0;
52
- right: 0;
53
- }
54
- .r01st-container[data-position="ml"] {
55
- top: 50%;
56
- left: 0;
57
- margin-top: -50px;
58
- }
59
-
60
- .r01st-container[data-position="mc"] {
61
- top: 50%;
62
- left: 50%;
63
- margin-left: -210px;
64
- margin-top: -50px;
65
- }
66
-
67
- .r01st-container[data-position="mr"] {
68
- top: 50%;
69
- right: 0;
70
- margin-top: -50px;
71
- }
72
- .r01st-container[data-position="bl"] {
73
- bottom: 0;
74
- left: 0;
75
- }
76
-
77
- .r01st-container[data-position="bc"] {
78
- bottom: 0;
79
- left: 50%;
80
- margin-left: -210px;
81
- }
82
-
83
- .r01st-container[data-position="br"] {
84
- bottom: 0;
85
- right: 0;
86
- }
87
- .r01st {
88
- pointer-events: auto;
89
- position: relative;
90
- min-width: 280px;
91
- max-width: 420px;
92
- padding: 16px;
93
- margin-bottom: 16px;
94
- border-radius: 8px;
95
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
96
- font-size: 14px;
97
- line-height: 1.5;
98
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
99
- color: #ffffff;
100
- opacity: 0;
101
- transition: opacity 0.3s ease, margin-top 0.3s ease;
102
- margin-top: -20px;
103
- }
104
- .r01st-show {
105
- opacity: 1;
106
- margin-top: 0;
107
- }
108
- .r01st-container[data-theme="l"] .r01st-success {
109
- background-color: #10b981;
110
- }
111
-
112
- .r01st-container[data-theme="l"] .r01st-error {
113
- background-color: #ef4444;
114
- }
115
-
116
- .r01st-container[data-theme="l"] .r01st-info {
117
- background-color: #3b82f6;
118
- }
119
-
120
- .r01st-container[data-theme="l"] .r01st-warning {
121
- background-color: #f59e0b;
122
- }
123
- .r01st-container[data-theme="d"] .r01st-success {
124
- background-color: #059669;
125
- }
126
-
127
- .r01st-container[data-theme="d"] .r01st-error {
128
- background-color: #dc2626;
129
- }
130
-
131
- .r01st-container[data-theme="d"] .r01st-info {
132
- background-color: #2563eb;
133
- }
134
-
135
- .r01st-container[data-theme="d"] .r01st-warning {
136
- background-color: #d97706;
137
- }
138
- .r01st-content {
139
- display: inline-block;
140
- width: 100%;
141
- vertical-align: top;
142
- padding-right: 30px;
143
- }
144
- .r01st-icon {
145
- display: inline-block;
146
- width: 20px;
147
- height: 20px;
148
- vertical-align: middle;
149
- margin-right: 12px;
150
- }
151
-
152
- .r01st-icon svg {
153
- width: 100%;
154
- height: 100%;
155
- display: block;
156
- }
157
- .r01st-message {
158
- display: inline-block;
159
- vertical-align: middle;
160
- word-wrap: break-word;
161
- max-width: calc(100% - 32px);
162
- }
163
- .r01st-close {
164
- position: absolute;
165
- top: 16px;
166
- right: 16px;
167
- background: transparent;
168
- border: none;
169
- color: #ffffff;
170
- font-size: 24px;
171
- line-height: 1;
172
- cursor: pointer;
173
- padding: 0;
174
- width: 24px;
175
- height: 24px;
176
- text-align: center;
177
- border-radius: 4px;
178
- opacity: 0.8;
179
- }
180
-
181
- .r01st-close:hover {
182
- background-color: rgba(255, 255, 255, 0.2);
183
- opacity: 1;
184
- }
185
-
186
- .r01st-close:focus {
187
- outline: 2px solid #ffffff;
188
- outline-offset: 2px;
189
- }
190
- .r01st-container[data-position^="b"] .r01st {
191
- margin-top: 0;
192
- margin-bottom: -20px;
193
- }
194
-
195
- .r01st-container[data-position^="b"] .r01st-show {
196
- margin-bottom: 16px;
197
- }
198
- @media (max-width: 480px) {
199
- .r01st-container {
200
- left: 0 !important;
201
- right: 0 !important;
202
- margin-left: 0 !important;
203
- padding: 8px;
204
- }
205
-
206
- .r01st {
207
- min-width: auto;
208
- max-width: none;
209
- }
210
- }
211
- @media (prefers-reduced-motion: reduce) {
212
- .r01st {
213
- transition: opacity 0.2s;
214
- margin-top: 0;
215
- }
216
- }
217
- @media print {
218
- .r01st-container {
219
- display: none;
220
- }
221
- }
222
- `;
223
-
71
+ style.textContent = "\n.r01st-container {\n position: fixed;\n z-index: 9999;\n pointer-events: none;\n padding: 16px;\n}\n.r01st-container[data-position=\"tl\"] {\n top: 0;\n left: 0;\n}\n\n.r01st-container[data-position=\"tc\"] {\n top: 0;\n left: 50%;\n margin-left: -210px;\n}\n\n.r01st-container[data-position=\"tr\"] {\n top: 0;\n right: 0;\n}\n.r01st-container[data-position=\"ml\"] {\n top: 50%;\n left: 0;\n margin-top: -50px;\n}\n\n.r01st-container[data-position=\"mc\"] {\n top: 50%;\n left: 50%;\n margin-left: -210px;\n margin-top: -50px;\n}\n\n.r01st-container[data-position=\"mr\"] {\n top: 50%;\n right: 0;\n margin-top: -50px;\n}\n.r01st-container[data-position=\"bl\"] {\n bottom: 0;\n left: 0;\n}\n\n.r01st-container[data-position=\"bc\"] {\n bottom: 0;\n left: 50%;\n margin-left: -210px;\n}\n\n.r01st-container[data-position=\"br\"] {\n bottom: 0;\n right: 0;\n}\n.r01st {\n pointer-events: auto;\n position: relative;\n min-width: 280px;\n max-width: 420px;\n padding: 16px;\n margin-bottom: 16px;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n font-size: 14px;\n line-height: 1.5;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;\n color: #ffffff;\n opacity: 0;\n transition: opacity 0.3s ease, margin-top 0.3s ease;\n margin-top: -20px;\n}\n.r01st-show {\n opacity: 1;\n margin-top: 0;\n}\n.r01st-container[data-theme=\"l\"] .r01st-success {\n background-color: #10b981;\n}\n\n.r01st-container[data-theme=\"l\"] .r01st-error {\n background-color: #ef4444;\n}\n\n.r01st-container[data-theme=\"l\"] .r01st-info {\n background-color: #3b82f6;\n}\n\n.r01st-container[data-theme=\"l\"] .r01st-warning {\n background-color: #f59e0b;\n}\n.r01st-container[data-theme=\"d\"] .r01st-success {\n background-color: #059669;\n}\n\n.r01st-container[data-theme=\"d\"] .r01st-error {\n background-color: #dc2626;\n}\n\n.r01st-container[data-theme=\"d\"] .r01st-info {\n background-color: #2563eb;\n}\n\n.r01st-container[data-theme=\"d\"] .r01st-warning {\n background-color: #d97706;\n}\n.r01st-content {\n display: inline-block;\n width: 100%;\n vertical-align: top;\n}\n.r01st-table {\n width: 100%;\n border-collapse: collapse;\n}\n.r01st-cell {\n vertical-align: middle;\n}\n.r01st-message-cell {\n width: 100%;\n}\n.r01st-close-cell {\n width: 1%;\n padding-left: 8px;\n}\n.r01st-icon {\n display: inline-block;\n width: 20px;\n height: 20px;\n vertical-align: middle;\n margin-right: 12px;\n}\n\n.r01st-icon svg {\n width: 100%;\n height: 100%;\n display: block;\n}\n.r01st-message {\n display: inline-block;\n vertical-align: middle;\n word-wrap: break-word;\n max-width: calc(100% - 32px);\n}\n.r01st-close {\n background: transparent;\n border: none;\n color: #ffffff;\n font-size: 24px;\n line-height: 1;\n cursor: pointer;\n padding: 0;\n width: 24px;\n height: 24px;\n text-align: center;\n border-radius: 4px;\n opacity: 0.8;\n}\n\n.r01st-close:hover {\n background-color: rgba(255, 255, 255, 0.2);\n opacity: 1;\n}\n\n.r01st-close:focus {\n outline: 2px solid #ffffff;\n outline-offset: 2px;\n}\n.r01st-container[data-position^=\"b\"] .r01st {\n margin-top: 0;\n margin-bottom: -20px;\n}\n\n.r01st-container[data-position^=\"b\"] .r01st-show {\n margin-bottom: 16px;\n}\n@media (max-width: 480px) {\n .r01st-container {\n left: 0 !important;\n right: 0 !important;\n margin-left: 0 !important;\n padding: 8px;\n }\n\n .r01st {\n min-width: auto;\n max-width: none;\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .r01st {\n transition: opacity 0.2s;\n margin-top: 0;\n }\n}\n@media print {\n .r01st-container {\n display: none;\n }\n}\n";
224
72
  document.head.appendChild(style);
225
73
  stylesInjected = true;
226
74
  }
227
75
 
228
76
  let container = null;
229
-
230
77
  function getContainer(position, theme) {
231
78
  injectStyles();
232
-
233
79
  if (container && (container.getAttribute('data-position') !== position || container.getAttribute('data-theme') !== theme)) {
234
80
  container.parentNode.removeChild(container);
235
81
  container = null;
236
82
  }
237
-
238
83
  if (!container) {
239
84
  container = document.createElement('div');
240
85
  container.className = 'r01st-container';
@@ -245,10 +90,8 @@
245
90
  container.setAttribute('data-theme', theme);
246
91
  document.body.appendChild(container);
247
92
  }
248
-
249
93
  return container;
250
94
  }
251
-
252
95
  function cleanupContainer(activeCount) {
253
96
  if (container && activeCount === 0) {
254
97
  container.parentNode.removeChild(container);
@@ -271,32 +114,39 @@
271
114
  toastEl.className = 'r01st r01st-' + type + (className ? ' ' + className : '');
272
115
  toastEl.setAttribute('role', 'alert');
273
116
  toastEl.setAttribute('data-toast-id', id);
274
-
275
117
  const content = document.createElement('div');
276
118
  content.className = 'r01st-content';
277
-
278
119
  const icon = document.createElement('span');
279
120
  icon.className = 'r01st-icon';
280
121
  icon.innerHTML = getIcon(type);
281
122
  icon.setAttribute('aria-hidden', 'true');
282
123
  content.appendChild(icon);
283
-
284
124
  const messageEl = document.createElement('span');
285
125
  messageEl.className = 'r01st-message';
286
126
  messageEl.textContent = message;
287
127
  content.appendChild(messageEl);
288
-
289
- toastEl.appendChild(content);
290
-
291
128
  if (dismissible) {
129
+ const layoutTable = document.createElement('table');
130
+ layoutTable.className = 'r01st-table';
131
+ const layoutRow = document.createElement('tr');
132
+ const messageCell = document.createElement('td');
133
+ messageCell.className = 'r01st-cell r01st-message-cell';
134
+ messageCell.appendChild(content);
135
+ const closeCell = document.createElement('td');
136
+ closeCell.className = 'r01st-cell r01st-close-cell';
292
137
  const closeBtn = document.createElement('button');
293
138
  closeBtn.className = 'r01st-close';
294
139
  closeBtn.innerHTML = '&times;';
295
140
  closeBtn.setAttribute('aria-label', 'Close notification');
296
141
  closeBtn.onclick = onClose;
297
- toastEl.appendChild(closeBtn);
142
+ closeCell.appendChild(closeBtn);
143
+ layoutRow.appendChild(messageCell);
144
+ layoutRow.appendChild(closeCell);
145
+ layoutTable.appendChild(layoutRow);
146
+ toastEl.appendChild(layoutTable);
147
+ } else {
148
+ toastEl.appendChild(content);
298
149
  }
299
-
300
150
  return toastEl;
301
151
  }
302
152
 
@@ -305,10 +155,8 @@
305
155
  element.className = element.className + ' r01st-show';
306
156
  });
307
157
  }
308
-
309
158
  function hideToast(element, callback) {
310
159
  element.className = element.className.replace(' r01st-show', '');
311
-
312
160
  setTimeout(() => {
313
161
  if (element.parentNode) {
314
162
  element.parentNode.removeChild(element);
@@ -319,59 +167,52 @@
319
167
 
320
168
  let toastCounter = 0;
321
169
  const activeToasts = new Map();
322
-
323
- function createToast(message, options = {}) {
324
- const config = { ...getConfig(), ...options };
325
- const { position, duration, dismissible, theme, className, type = 'info' } = config;
326
-
170
+ function createToast(message) {
171
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
172
+ const config = _objectSpread2(_objectSpread2({}, getConfig()), options);
173
+ const {
174
+ position,
175
+ duration,
176
+ dismissible,
177
+ theme,
178
+ className,
179
+ type = 'info'
180
+ } = config;
327
181
  const id = ++toastCounter;
328
-
329
182
  if (activeToasts.size >= getConfig().maxToasts) {
330
183
  const firstToast = activeToasts.keys().next().value;
331
184
  dismissToast(firstToast);
332
185
  }
333
-
334
186
  const container = getContainer(position, theme);
335
-
336
187
  const handleClose = () => dismissToast(id);
337
-
338
188
  const toastEl = createToastElement(message, type, dismissible, className, id, handleClose);
339
-
340
189
  container.appendChild(toastEl);
341
-
342
190
  showToast(toastEl);
343
-
344
191
  const toastData = {
345
192
  element: toastEl,
346
193
  timeoutId: null
347
194
  };
348
-
349
195
  if (duration > 0) {
350
196
  toastData.timeoutId = setTimeout(() => dismissToast(id), duration);
351
197
  }
352
-
353
198
  activeToasts.set(id, toastData);
354
-
355
199
  return id;
356
200
  }
357
-
358
201
  function dismissToast(id) {
359
202
  const toastData = activeToasts.get(id);
360
203
  if (!toastData) return;
361
-
362
- const { element, timeoutId } = toastData;
363
-
204
+ const {
205
+ element,
206
+ timeoutId
207
+ } = toastData;
364
208
  if (timeoutId) {
365
209
  clearTimeout(timeoutId);
366
210
  }
367
-
368
211
  activeToasts.delete(id);
369
-
370
212
  hideToast(element, () => {
371
213
  cleanupContainer(activeToasts.size);
372
214
  });
373
215
  }
374
-
375
216
  function dismissAllToasts() {
376
217
  const ids = Array.from(activeToasts.keys());
377
218
  ids.forEach(id => dismissToast(id));
@@ -383,15 +224,36 @@
383
224
  * @param {Object} options - Toast options
384
225
  * @returns {number} Toast ID
385
226
  */
386
- function toast(message, options = {}) {
227
+ function toast(message) {
228
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
387
229
  return createToast(message, options);
388
230
  }
389
231
 
390
232
  // Shorthand methods
391
- toast.success = (message, options = {}) => toast(message, { ...options, type: 'success' });
392
- toast.error = (message, options = {}) => toast(message, { ...options, type: 'error' });
393
- toast.info = (message, options = {}) => toast(message, { ...options, type: 'info' });
394
- toast.warning = (message, options = {}) => toast(message, { ...options, type: 'warning' });
233
+ toast.success = function (message) {
234
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
235
+ return toast(message, _objectSpread2(_objectSpread2({}, options), {}, {
236
+ type: 'success'
237
+ }));
238
+ };
239
+ toast.error = function (message) {
240
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
241
+ return toast(message, _objectSpread2(_objectSpread2({}, options), {}, {
242
+ type: 'error'
243
+ }));
244
+ };
245
+ toast.info = function (message) {
246
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
247
+ return toast(message, _objectSpread2(_objectSpread2({}, options), {}, {
248
+ type: 'info'
249
+ }));
250
+ };
251
+ toast.warning = function (message) {
252
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
253
+ return toast(message, _objectSpread2(_objectSpread2({}, options), {}, {
254
+ type: 'warning'
255
+ }));
256
+ };
395
257
 
396
258
  // Export dismiss methods
397
259
  toast.dismiss = dismissToast;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@r01al/simple-toast",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Lightweight, framework-agnostic toast notification library with zero dependencies",
5
5
  "keywords": [
6
6
  "toast",