@esmalley/ts-utils 5.0.0 → 6.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 +615 -1
- package/dist/cjs/index.js +10 -10
- package/dist/cjs/index.js.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/esm/index.js +10 -10
- package/dist/esm/index.js.map +3 -3
- package/dist/types/Arrayifier.d.ts +3 -3
- package/dist/types/Arrayifier.d.ts.map +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,2 +1,616 @@
|
|
|
1
1
|
# ts-utils
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
A modular collection of TypeScript utilities for modern web development.
|
|
4
|
+
|
|
5
|
+
* Data transformation & CSV generation
|
|
6
|
+
* CSS-in-JS styling & Material Design shadows
|
|
7
|
+
* Comprehensive color manipulation
|
|
8
|
+
* Robust date parsing and formatting
|
|
9
|
+
* Object deep cloning and merging
|
|
10
|
+
* Event handling systems
|
|
11
|
+
* Array shuffling and combinations
|
|
12
|
+
|
|
13
|
+
# Table of Contents
|
|
14
|
+
|
|
15
|
+
* [Installation](#installation)
|
|
16
|
+
* [Modules](#modules)
|
|
17
|
+
* [Arithmetic](#arithmetic)
|
|
18
|
+
* [Arrayifier](#arrayifier)
|
|
19
|
+
* [Color](#color)
|
|
20
|
+
* [CSV](#csv)
|
|
21
|
+
* [Dates](#dates)
|
|
22
|
+
* [Kontororu (Events)](#kontororu-events)
|
|
23
|
+
* [Objector](#objector)
|
|
24
|
+
* [Sorter](#sorter)
|
|
25
|
+
* [Style](#style)
|
|
26
|
+
* [Textor](#textor)
|
|
27
|
+
* [Theme](#theme)
|
|
28
|
+
* [Toaster](#toaster)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
* [Testing](#testing)
|
|
32
|
+
* [License](#license)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
# Installation
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install @esmalley/ts-utils
|
|
40
|
+
# or
|
|
41
|
+
yarn add @esmalley/ts-utils
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
# Modules
|
|
48
|
+
|
|
49
|
+
## Arithmetic
|
|
50
|
+
|
|
51
|
+
Math helpers for bounding and calculation.
|
|
52
|
+
|
|
53
|
+
### `clamp(number, min, max)`
|
|
54
|
+
|
|
55
|
+
Restricts a given number to be within the specified minimum and maximum range.
|
|
56
|
+
|
|
57
|
+
* **Example 1: Restricting UI Scroll**
|
|
58
|
+
Ensure a scroll position never goes out of bounds.
|
|
59
|
+
```ts
|
|
60
|
+
import { Arithmetic } from '@esmalley/ts-utils';
|
|
61
|
+
|
|
62
|
+
const rawScroll = -50;
|
|
63
|
+
const boundedScroll = Arithmetic.clamp(rawScroll, 0, 500);
|
|
64
|
+
console.log(boundedScroll); // Output: 0
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
* **Example 2: Normalizing Health Points**
|
|
70
|
+
Prevent health from exceeding maximum or falling below zero.
|
|
71
|
+
```ts
|
|
72
|
+
const currentHealth = 120;
|
|
73
|
+
const actualHealth = Arithmetic.clamp(currentHealth, 0, 100);
|
|
74
|
+
console.log(actualHealth); // Output: 100
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Arrayifier
|
|
83
|
+
|
|
84
|
+
Utilities for manipulating arrays and generating sets.
|
|
85
|
+
|
|
86
|
+
### `shuffle(array)`
|
|
87
|
+
|
|
88
|
+
Randomizes the order of elements in an array in-place using the Fisher-Yates algorithm.
|
|
89
|
+
|
|
90
|
+
* **Example 1: Shuffling a Deck**
|
|
91
|
+
```ts
|
|
92
|
+
import { Arrayifier } from '@esmalley/ts-utils';
|
|
93
|
+
|
|
94
|
+
const deck = ['Ace', 'King', 'Queen', 'Jack'];
|
|
95
|
+
Arrayifier.shuffle(deck);
|
|
96
|
+
console.log(deck); // e.g., ['Queen', 'Ace', 'Jack', 'King']
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
### `getCombinations(arr, r)`
|
|
103
|
+
|
|
104
|
+
Returns all possible combinations of a specific size `r` from an array.
|
|
105
|
+
|
|
106
|
+
* **Example 1: Tournament Matchups**
|
|
107
|
+
Get all unique pairs from a list of players.
|
|
108
|
+
```ts
|
|
109
|
+
const players = [1, 2, 3, 4];
|
|
110
|
+
const matchups = Arrayifier.getCombinations(players, 2);
|
|
111
|
+
// Output: [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Color
|
|
120
|
+
|
|
121
|
+
Comprehensive suite for hex, RGB, and HSL manipulation.
|
|
122
|
+
|
|
123
|
+
### `lerpColor(a, b, amount)`
|
|
124
|
+
|
|
125
|
+
Linearly interpolates between two hexadecimal colors.
|
|
126
|
+
|
|
127
|
+
* **Example 1: Health Bar Gradient**
|
|
128
|
+
Get the color at the 50% mark between Red and Green.
|
|
129
|
+
```ts
|
|
130
|
+
import { Color } from '@esmalley/ts-utils';
|
|
131
|
+
const midPoint = Color.lerpColor('#ff0000', '#00ff00', 0.5);
|
|
132
|
+
console.log(midPoint); // Output: #7f7f00
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
### `getTextColor(color, backgroundColor)`
|
|
139
|
+
|
|
140
|
+
Determines a high-contrast text color based on the background color to ensure accessibility (WCAG compliance).
|
|
141
|
+
|
|
142
|
+
* **Example 1: Dynamic Label Styling**
|
|
143
|
+
```ts
|
|
144
|
+
const bg = '#000000'; // Black background
|
|
145
|
+
const text = Color.getTextColor('#333333', bg);
|
|
146
|
+
console.log(text); // Output: #FFFFFF (returns white for better contrast)
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
### `darken(hex, amount)`
|
|
153
|
+
|
|
154
|
+
Darkens a hex color by a specified percentage (0 to 1).
|
|
155
|
+
|
|
156
|
+
* **Example 1: Button Hover State**
|
|
157
|
+
```ts
|
|
158
|
+
const primary = '#3498db';
|
|
159
|
+
const hover = Color.darken(primary, 0.2); // 20% darker
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
### `alphaColor(hex, alpha)`
|
|
166
|
+
|
|
167
|
+
Converts a hex color to an `rgba()` string with the provided transparency.
|
|
168
|
+
|
|
169
|
+
* **Example 1: Transparent Overlay**
|
|
170
|
+
```ts
|
|
171
|
+
const overlay = Color.alphaColor('#000000', 0.5);
|
|
172
|
+
console.log(overlay); // Output: rgba(0, 0, 0, 0.5)
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## CSV
|
|
181
|
+
|
|
182
|
+
Utilities for data exportation.
|
|
183
|
+
|
|
184
|
+
### `download(data)`
|
|
185
|
+
|
|
186
|
+
Takes a nested object and triggers a browser download of a generated `.csv` file.
|
|
187
|
+
|
|
188
|
+
* **Example 1: Exporting User Lists**
|
|
189
|
+
```ts
|
|
190
|
+
import { CSV } from '@esmalley/ts-utils';
|
|
191
|
+
|
|
192
|
+
const userData = {
|
|
193
|
+
user_1: { name: 'Alice', email: 'alice@example.com' },
|
|
194
|
+
user_2: { name: 'Bob', email: 'bob@example.com' }
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
CSV.download(userData); // Triggers download of 'srating-data.csv'
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Dates
|
|
206
|
+
|
|
207
|
+
Powerful date parsing, formatting, and arithmetic.
|
|
208
|
+
|
|
209
|
+
### `parse(input, utc?)`
|
|
210
|
+
|
|
211
|
+
A robust parser that handles ISO strings, US formats, timestamps, and mixed time strings (e.g., "5:00pm").
|
|
212
|
+
|
|
213
|
+
* **Example 1: Parsing US Format**
|
|
214
|
+
```ts
|
|
215
|
+
import { Dates } from '@esmalley/ts-utils';
|
|
216
|
+
const date = Dates.parse('01/25/2026 5:30 pm');
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
### `format(date, formatString)`
|
|
223
|
+
|
|
224
|
+
Formats a date using a variety of tokens (Y, y, m, n, F, M, d, j, D, l, H, h, G, g, i, s, a, A).
|
|
225
|
+
|
|
226
|
+
* **Example 1: Friendly Date String**
|
|
227
|
+
```ts
|
|
228
|
+
const now = new Date();
|
|
229
|
+
console.log(Dates.format(now, 'l, F jS, Y')); // Output: "Sunday, January 25th, 2026"
|
|
230
|
+
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
### `add(date, amount, unit)`
|
|
236
|
+
|
|
237
|
+
Adds a specific amount of time to a date (years, months, days, hours, minutes).
|
|
238
|
+
|
|
239
|
+
* **Example 1: Expiration Calculation**
|
|
240
|
+
```ts
|
|
241
|
+
const today = new Date();
|
|
242
|
+
const nextYear = Dates.add(today, 1, 'years');
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
### `isSameDay(date1, date2)`
|
|
249
|
+
|
|
250
|
+
Checks if two dates refer to the same calendar day, ignoring time.
|
|
251
|
+
|
|
252
|
+
* **Example 1: Calendar Highlighting**
|
|
253
|
+
```ts
|
|
254
|
+
const d1 = '2026-01-25 10:00';
|
|
255
|
+
const d2 = '2026-01-25 18:00';
|
|
256
|
+
console.log(Dates.isSameDay(d1, d2)); // true
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## Objector
|
|
264
|
+
|
|
265
|
+
Utilities for deep object manipulation.
|
|
266
|
+
|
|
267
|
+
### `deepClone(obj)`
|
|
268
|
+
|
|
269
|
+
Creates a full, recursive copy of an object, including Maps, Sets, Dates, and RegEx.
|
|
270
|
+
|
|
271
|
+
* **Example 1: State Immutability**
|
|
272
|
+
```ts
|
|
273
|
+
import { Objector } from '@esmalley/ts-utils';
|
|
274
|
+
const state = { user: { id: 1 } };
|
|
275
|
+
const newState = Objector.deepClone(state);
|
|
276
|
+
newState.user.id = 2;
|
|
277
|
+
console.log(state.user.id); // 1 (unchanged)
|
|
278
|
+
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
### `extender(target, ...sources)`
|
|
284
|
+
|
|
285
|
+
Deeply merges multiple source objects into a target object.
|
|
286
|
+
|
|
287
|
+
* **Example 1: Configuration Merging**
|
|
288
|
+
```ts
|
|
289
|
+
const defaults = { theme: 'light', flags: { debug: false } };
|
|
290
|
+
const userConfig = { flags: { debug: true } };
|
|
291
|
+
Objector.extender(defaults, userConfig);
|
|
292
|
+
// defaults is now { theme: 'light', flags: { debug: true } }
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Sorter
|
|
301
|
+
|
|
302
|
+
Table and collection sorting helpers.
|
|
303
|
+
|
|
304
|
+
### `getComparator(order, orderBy)`
|
|
305
|
+
|
|
306
|
+
Returns a comparison function for use with `Array.sort()`.
|
|
307
|
+
|
|
308
|
+
* **Example 1: Sorting Table Data**
|
|
309
|
+
```ts
|
|
310
|
+
import { Sorter } from '@esmalley/ts-utils';
|
|
311
|
+
const rows = [{ val: 10 }, { val: 5 }, { val: 20 }];
|
|
312
|
+
const comparator = Sorter.getComparator('desc', 'val');
|
|
313
|
+
rows.sort(comparator); // [{ val: 20 }, { val: 10 }, { val: 5 }]
|
|
314
|
+
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## Style
|
|
322
|
+
|
|
323
|
+
Utilities for dynamic CSS injection and style management.
|
|
324
|
+
|
|
325
|
+
### `getStyleClassName(css, debug?)`
|
|
326
|
+
|
|
327
|
+
Hashes a CSS object/string, generates a unique class name, and injects the style into the document head.
|
|
328
|
+
|
|
329
|
+
* **Example 1: Scoped Dynamic Styling**
|
|
330
|
+
```ts
|
|
331
|
+
import { Style } from '@esmalley/ts-utils';
|
|
332
|
+
|
|
333
|
+
const className = Style.getStyleClassName({
|
|
334
|
+
backgroundColor: 'red',
|
|
335
|
+
'&:hover': {
|
|
336
|
+
backgroundColor: 'blue'
|
|
337
|
+
},
|
|
338
|
+
'@media (max-width: 600px)': {
|
|
339
|
+
fontSize: 12
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
// Returns a unique hash like 'css-1a2b3c' and injects the CSS.
|
|
344
|
+
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
### `getShadow(depth)`
|
|
350
|
+
|
|
351
|
+
Returns a Material Design elevation shadow string (0-24).
|
|
352
|
+
|
|
353
|
+
* **Example 1: Component Elevation**
|
|
354
|
+
```ts
|
|
355
|
+
const shadow = Style.getShadow(4);
|
|
356
|
+
// Returns: "0px 2px 4px -1px rgba(0,0,0,0.2),0px 4px 5px 0px rgba(0,0,0,0.14)..."
|
|
357
|
+
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
## Textor
|
|
362
|
+
|
|
363
|
+
String manipulation and linguistic utility functions.
|
|
364
|
+
|
|
365
|
+
### `levenshtein(a, b)`
|
|
366
|
+
|
|
367
|
+
Calculates the Levenshtein distance between two strings. This is a string metric for measuring the difference between two sequences (the minimum number of single-character edits required to change one word into the other).
|
|
368
|
+
|
|
369
|
+
* **Example 1: Search Suggestions / "Did you mean?"**
|
|
370
|
+
Determine how close a user's typo is to a correct keyword.
|
|
371
|
+
```ts
|
|
372
|
+
import { Textor } from '@esmalley/ts-utils';
|
|
373
|
+
|
|
374
|
+
const input = 'Gogle';
|
|
375
|
+
const target = 'Google';
|
|
376
|
+
const distance = Textor.levenshtein(input, target);
|
|
377
|
+
|
|
378
|
+
console.log(distance); // Output: 1
|
|
379
|
+
if (distance <= 2) {
|
|
380
|
+
console.log(`Did you mean ${target}?`);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
* **Example 2: Deduplicating Data**
|
|
387
|
+
Check if two strings are likely the same record with minor variations.
|
|
388
|
+
```ts
|
|
389
|
+
const user1 = "Johnathan Doe";
|
|
390
|
+
const user2 = "Jonathan Doe";
|
|
391
|
+
const diff = Textor.levenshtein(user1, user2);
|
|
392
|
+
|
|
393
|
+
// A distance of 1 suggests a very high similarity
|
|
394
|
+
const isLikelySame = diff < 3;
|
|
395
|
+
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
### `toSentenceCase(str)`
|
|
401
|
+
|
|
402
|
+
Converts a string to sentence case by capitalizing the first letter of the first word and making the rest of the string lowercase. It also handles trimming whitespace.
|
|
403
|
+
|
|
404
|
+
* **Example 1: Formatting User-Generated Content**
|
|
405
|
+
Clean up a messy title submitted via a form.
|
|
406
|
+
```ts
|
|
407
|
+
const rawTitle = " WELCOME TO THE DASHBOARD ";
|
|
408
|
+
const cleanTitle = Textor.toSentenceCase(rawTitle);
|
|
409
|
+
|
|
410
|
+
console.log(cleanTitle); // Output: "Welcome to the dashboard"
|
|
411
|
+
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
* **Example 2: Normalizing Table Headers**
|
|
416
|
+
```ts
|
|
417
|
+
const keys = ["USER_NAME", "EMAIL_ADDRESS"];
|
|
418
|
+
const labels = keys.map(k => Textor.toSentenceCase(k.replace('_', ' ')));
|
|
419
|
+
|
|
420
|
+
console.log(labels); // Output: ["User name", "Email address"]
|
|
421
|
+
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
## Theme
|
|
429
|
+
|
|
430
|
+
A comprehensive Material Design-inspired theming engine providing light and dark modes with a full 50-900 color palette.
|
|
431
|
+
|
|
432
|
+
### `constructor(mode)`
|
|
433
|
+
|
|
434
|
+
Initializes the theme engine with either `'light'` or `'dark'`. Throws an error if an invalid mode is provided.
|
|
435
|
+
|
|
436
|
+
* **Example 1: Dynamic Theme Initialization**
|
|
437
|
+
```ts
|
|
438
|
+
import { Theme } from '@esmalley/ts-utils';
|
|
439
|
+
|
|
440
|
+
const userPreference = localStorage.getItem('theme') || 'light';
|
|
441
|
+
const themeEngine = new Theme(userPreference);
|
|
442
|
+
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
### `getTheme()`
|
|
448
|
+
|
|
449
|
+
Returns the full theme object (background, primary, secondary, warning, success, error, and text palettes) based on the mode selected in the constructor.
|
|
450
|
+
|
|
451
|
+
* **Example 1: Consuming Theme in a Style Object**
|
|
452
|
+
```ts
|
|
453
|
+
const myTheme = new Theme('dark').getTheme();
|
|
454
|
+
|
|
455
|
+
const headerStyle = {
|
|
456
|
+
backgroundColor: myTheme.header.main,
|
|
457
|
+
color: myTheme.text.primary,
|
|
458
|
+
borderBottom: `1px solid ${myTheme.primary.main}`
|
|
459
|
+
};
|
|
460
|
+
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
### `getDarkTheme()` / `getLightTheme()`
|
|
466
|
+
|
|
467
|
+
Explicitly retrieves the configuration for a specific mode, regardless of the current instance state.
|
|
468
|
+
|
|
469
|
+
* **Example 1: Comparing Modes**
|
|
470
|
+
```ts
|
|
471
|
+
const theme = new Theme('light');
|
|
472
|
+
const dark = theme.getDarkTheme();
|
|
473
|
+
const light = theme.getLightTheme();
|
|
474
|
+
|
|
475
|
+
console.log(dark.background.main); // #121212
|
|
476
|
+
console.log(light.background.main); // #ffffff
|
|
477
|
+
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
### Palette Accessors (e.g., `getGrey()`, `getAmber()`, etc.)
|
|
483
|
+
|
|
484
|
+
The class provides access to the standard Material Design color ramps.
|
|
485
|
+
|
|
486
|
+
* **Example 1: Using Specific Color Weights**
|
|
487
|
+
```ts
|
|
488
|
+
const theme = new Theme('light');
|
|
489
|
+
const greys = theme.getGrey();
|
|
490
|
+
|
|
491
|
+
const dividerStyle = {
|
|
492
|
+
backgroundColor: greys[300] // Light grey for dividers
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
const secondaryText = {
|
|
496
|
+
color: greys[600] // Medium grey for subtext
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
---
|
|
504
|
+
|
|
505
|
+
## Toaster
|
|
506
|
+
|
|
507
|
+
A global state manager for UI notifications (Toasts). It supports subscriptions, auto-dismissal, and exit animations.
|
|
508
|
+
|
|
509
|
+
### `subscribe(listener)`
|
|
510
|
+
|
|
511
|
+
Allows a UI component (like a React or Vue component) to listen for changes to the toast list. Returns an unsubscribe function.
|
|
512
|
+
|
|
513
|
+
* **Example 1: Integrating with a Framework (React-like)**
|
|
514
|
+
```ts
|
|
515
|
+
import { toaster } from '@esmalley/ts-utils';
|
|
516
|
+
|
|
517
|
+
const unsubscribe = toaster.subscribe((newList) => {
|
|
518
|
+
console.log("Toasts updated:", newList);
|
|
519
|
+
this.setState({ toasts: newList });
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
// Later, clean up the listener
|
|
523
|
+
// unsubscribe();
|
|
524
|
+
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
### `add(message, type)`
|
|
530
|
+
|
|
531
|
+
Adds a new notification to the stack. Defaults to `'info'` type. Automatically triggers a close request after 4 seconds.
|
|
532
|
+
|
|
533
|
+
* **Example 1: Error Handling**
|
|
534
|
+
```ts
|
|
535
|
+
try {
|
|
536
|
+
await api.save();
|
|
537
|
+
toaster.add("Changes saved successfully!", "success");
|
|
538
|
+
} catch (e) {
|
|
539
|
+
toaster.add("Failed to save changes. Please try again.", "error");
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
* **Example 2: Basic Notification**
|
|
546
|
+
```ts
|
|
547
|
+
toaster.add("You have a new message."); // Defaults to 'info'
|
|
548
|
+
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
### `requestClose(id)`
|
|
554
|
+
|
|
555
|
+
Starts the "exit" phase for a toast. It marks the toast as `exiting: true`, allowing the UI to play a fade-out animation before the toast is fully removed 500ms later.
|
|
556
|
+
|
|
557
|
+
* **Example 1: Manual Dismiss Button**
|
|
558
|
+
```ts
|
|
559
|
+
// Inside your UI component's "X" button click handler
|
|
560
|
+
const handleClose = (toastId) => {
|
|
561
|
+
toaster.requestClose(toastId);
|
|
562
|
+
};
|
|
563
|
+
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
|
|
568
|
+
### `remove(id)`
|
|
569
|
+
|
|
570
|
+
Immediately removes a toast from the list without waiting for an animation or timeout.
|
|
571
|
+
|
|
572
|
+
* **Example 1: Force Clearing a specific alert**
|
|
573
|
+
```ts
|
|
574
|
+
toaster.remove(currentToastId);
|
|
575
|
+
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
### `getToasts()`
|
|
581
|
+
|
|
582
|
+
Returns the current array of active `ToastItem` objects.
|
|
583
|
+
|
|
584
|
+
* **Example 1: Checking Toast Count**
|
|
585
|
+
```ts
|
|
586
|
+
const activeToasts = toaster.getToasts();
|
|
587
|
+
if (activeToasts.length > 5) {
|
|
588
|
+
console.log("The user is being flooded with notifications!");
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
---
|
|
596
|
+
|
|
597
|
+
## Kontororu (Events)
|
|
598
|
+
|
|
599
|
+
An EventTarget wrapper for managing custom listeners.
|
|
600
|
+
|
|
601
|
+
### `addEventListener(type, listener)`
|
|
602
|
+
|
|
603
|
+
Registers an event handler.
|
|
604
|
+
|
|
605
|
+
* **Example 1: Custom Socket Events**
|
|
606
|
+
```ts
|
|
607
|
+
import { Kontororu } from '@esmalley/ts-utils';
|
|
608
|
+
const bus = new Kontororu();
|
|
609
|
+
bus.addEventListener('data', (payload) => console.log(payload));
|
|
610
|
+
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
|