@ailuracode/alpine-toast 0.1.1
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 +21 -0
- package/README.md +67 -0
- package/dist/global.d.ts +266 -0
- package/dist/index.d.ts +225 -0
- package/dist/index.js +540 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) ailuracode
|
|
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,67 @@
|
|
|
1
|
+
# @ailuracode/alpine-toast
|
|
2
|
+
|
|
3
|
+
Headless in-app toast queue for Alpine.js via the `$toast` magic.
|
|
4
|
+
|
|
5
|
+
**CSS-framework agnostic** — no markup, no styles. Only `default`, `bottom-right`, and `promise` are built into the API; you declare variants and positions your UI needs.
|
|
6
|
+
|
|
7
|
+
**[Full documentation →](../../docs/toast.md)**
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @ailuracode/alpine-toast alpinejs
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick example
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
import Alpine from "alpinejs";
|
|
19
|
+
import toast, { toastPositions, toastVariants } from "@ailuracode/alpine-toast";
|
|
20
|
+
|
|
21
|
+
Alpine.plugin(
|
|
22
|
+
toast({
|
|
23
|
+
variants: toastVariants(["success", "error", "loading"] as const),
|
|
24
|
+
positions: toastPositions(["top-center", "bottom-right"] as const),
|
|
25
|
+
defaultPosition: "bottom-right",
|
|
26
|
+
promise: {
|
|
27
|
+
loadingVariant: "loading",
|
|
28
|
+
successVariant: "success",
|
|
29
|
+
errorVariant: "error",
|
|
30
|
+
},
|
|
31
|
+
})
|
|
32
|
+
);
|
|
33
|
+
Alpine.start();
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```html
|
|
37
|
+
<button @click="$toast('Hello')">Default</button>
|
|
38
|
+
<button @click="$toast.success('Saved')">Success</button>
|
|
39
|
+
<button @click="$toast('Notice', { position: 'top-center' })">Top</button>
|
|
40
|
+
<button @click="() => $toast.promise(save, { loading: 'Saving...', success: 'Saved!' })">
|
|
41
|
+
Save
|
|
42
|
+
</button>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```html
|
|
46
|
+
<button @click="$toast.dismiss(toast.id)" aria-label="Close">✕</button>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Also available on the store: `$store.toast.dismiss(id)`.
|
|
50
|
+
|
|
51
|
+
## API summary
|
|
52
|
+
|
|
53
|
+
| | |
|
|
54
|
+
|-|-|
|
|
55
|
+
| **Content** | `content` on each toast — any type your UI renders |
|
|
56
|
+
| **Magic** | `$toast(title, options?)` → toast id (`default` variant, `bottom-right` position) |
|
|
57
|
+
| **Close** | `$toast.dismiss(id)`, `$toast.dismissAt(position)`, `$toast.dismissAll()` |
|
|
58
|
+
| **Dedupe** | `$toast.pushUnique(key, payload)` — one active toast per key (undo flows) |
|
|
59
|
+
| **Promise** | `$toast.promise(factoryOrPromise, messages?)` |
|
|
60
|
+
| **Variants** | `variants: toastVariants([...])` → `$toast.<name>()` |
|
|
61
|
+
| **Positions** | `positions: toastPositions([...])` → one stack per position |
|
|
62
|
+
| **Queue** | `maxToasts` / `maxVisible` per timed or persistent stack |
|
|
63
|
+
| **UI** | Bring your own markup and CSS |
|
|
64
|
+
|
|
65
|
+
## License
|
|
66
|
+
|
|
67
|
+
MIT
|
package/dist/global.d.ts
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/// <reference types="@types/alpinejs" />
|
|
2
|
+
|
|
3
|
+
export declare const TOAST_STORE_KEY: "toast";
|
|
4
|
+
|
|
5
|
+
export type ToastStoreKey = typeof TOAST_STORE_KEY;
|
|
6
|
+
|
|
7
|
+
export type DefaultToastPosition = "bottom-right";
|
|
8
|
+
|
|
9
|
+
export type ToastPosition<TPositions extends readonly string[] = readonly []> =
|
|
10
|
+
| DefaultToastPosition
|
|
11
|
+
| TPositions[number];
|
|
12
|
+
|
|
13
|
+
export type DefaultToastVariant = "default";
|
|
14
|
+
|
|
15
|
+
/** Milliseconds before auto-dismiss, or `false` / `0` to keep the toast open. */
|
|
16
|
+
export type ToastDuration = number | false;
|
|
17
|
+
|
|
18
|
+
export type ToastVariant<TVariants extends readonly string[] = readonly []> =
|
|
19
|
+
| DefaultToastVariant
|
|
20
|
+
| TVariants[number];
|
|
21
|
+
|
|
22
|
+
export interface ToastAction {
|
|
23
|
+
label: string;
|
|
24
|
+
onClick?: () => void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ToastPayload<
|
|
28
|
+
TVariants extends readonly string[] = readonly [],
|
|
29
|
+
TPositions extends readonly string[] = readonly [],
|
|
30
|
+
TContent = unknown,
|
|
31
|
+
> {
|
|
32
|
+
content?: TContent | null;
|
|
33
|
+
title?: string | null;
|
|
34
|
+
description?: string | null;
|
|
35
|
+
variant?: ToastVariant<TVariants>;
|
|
36
|
+
position?: ToastPosition<TPositions>;
|
|
37
|
+
duration?: ToastDuration;
|
|
38
|
+
action?: ToastAction | null;
|
|
39
|
+
key?: string | null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface ToastItem<
|
|
43
|
+
TVariants extends readonly string[] = readonly [],
|
|
44
|
+
TPositions extends readonly string[] = readonly [],
|
|
45
|
+
TContent = unknown,
|
|
46
|
+
> {
|
|
47
|
+
id: string;
|
|
48
|
+
key: string | null;
|
|
49
|
+
content: TContent | null;
|
|
50
|
+
title: string | null;
|
|
51
|
+
description: string | null;
|
|
52
|
+
variant: ToastVariant<TVariants>;
|
|
53
|
+
position: ToastPosition<TPositions>;
|
|
54
|
+
duration: ToastDuration;
|
|
55
|
+
action: ToastAction | null;
|
|
56
|
+
removed: boolean;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export type ToastPayloadWithoutVariant<
|
|
60
|
+
TVariants extends readonly string[] = readonly [],
|
|
61
|
+
TPositions extends readonly string[] = readonly [],
|
|
62
|
+
TContent = unknown,
|
|
63
|
+
> = Omit<ToastPayload<TVariants, TPositions, TContent>, "variant">;
|
|
64
|
+
|
|
65
|
+
export interface ToastPromiseOptions<TVariants extends readonly string[] = readonly []> {
|
|
66
|
+
loading?: string;
|
|
67
|
+
error?: string;
|
|
68
|
+
duration?: ToastDuration;
|
|
69
|
+
loadingVariant?: ToastVariant<TVariants>;
|
|
70
|
+
successVariant?: ToastVariant<TVariants>;
|
|
71
|
+
errorVariant?: ToastVariant<TVariants>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface ToastPluginOptions<
|
|
75
|
+
TVariants extends readonly string[] = readonly [],
|
|
76
|
+
TPositions extends readonly string[] = readonly [],
|
|
77
|
+
_TContent = unknown,
|
|
78
|
+
> {
|
|
79
|
+
variants?: TVariants;
|
|
80
|
+
positions?: TPositions;
|
|
81
|
+
defaultPosition?: ToastPosition<TPositions>;
|
|
82
|
+
defaultDuration?: number;
|
|
83
|
+
promise?: ToastPromiseOptions<TVariants>;
|
|
84
|
+
maxToasts?: number;
|
|
85
|
+
maxVisible?: number;
|
|
86
|
+
listenToWindowEvents?: boolean;
|
|
87
|
+
storeKey?: ToastStoreKey;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface ToastPromiseMessages<
|
|
91
|
+
T = unknown,
|
|
92
|
+
TVariant extends string = string,
|
|
93
|
+
TContent = unknown,
|
|
94
|
+
> {
|
|
95
|
+
loading?: string;
|
|
96
|
+
success?: string | ((data: T) => string);
|
|
97
|
+
error?: string;
|
|
98
|
+
loadingContent?: TContent;
|
|
99
|
+
successContent?: TContent | ((data: T) => TContent);
|
|
100
|
+
errorContent?: TContent;
|
|
101
|
+
loadingVariant?: TVariant;
|
|
102
|
+
successVariant?: TVariant;
|
|
103
|
+
errorVariant?: TVariant;
|
|
104
|
+
duration?: ToastDuration;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export type ToastPromiseInput<T> = (() => Promise<T> | T) | Promise<T>;
|
|
108
|
+
|
|
109
|
+
export type ToastEventPayload<
|
|
110
|
+
TVariants extends readonly string[] = readonly [],
|
|
111
|
+
TPositions extends readonly string[] = readonly [],
|
|
112
|
+
TContent = unknown,
|
|
113
|
+
> = ToastPayload<TVariants, TPositions, TContent>;
|
|
114
|
+
|
|
115
|
+
export interface ToastStore<
|
|
116
|
+
TVariants extends readonly string[] = readonly [],
|
|
117
|
+
TPositions extends readonly string[] = readonly [],
|
|
118
|
+
TContent = unknown,
|
|
119
|
+
> {
|
|
120
|
+
defaultPosition: ToastPosition<TPositions>;
|
|
121
|
+
stackPositions: readonly ToastPosition<TPositions>[];
|
|
122
|
+
maxToasts: number;
|
|
123
|
+
maxVisible: number;
|
|
124
|
+
items: ToastItem<TVariants, TPositions, TContent>[];
|
|
125
|
+
push(payload?: ToastPayload<TVariants, TPositions, TContent>): string;
|
|
126
|
+
pushUnique(key: string, payload?: ToastPayload<TVariants, TPositions, TContent>): string;
|
|
127
|
+
update(id: string, payload?: Partial<ToastPayload<TVariants, TPositions, TContent>>): void;
|
|
128
|
+
dismiss(id: string): void;
|
|
129
|
+
dismissAt(position: ToastPosition<TPositions>): void;
|
|
130
|
+
dismissAll(): void;
|
|
131
|
+
destroy(): void;
|
|
132
|
+
itemsAt(position: ToastPosition<TPositions>): ToastItem<TVariants, TPositions, TContent>[];
|
|
133
|
+
timedItemsAt(position: ToastPosition<TPositions>): ToastItem<TVariants, TPositions, TContent>[];
|
|
134
|
+
persistentItemsAt(
|
|
135
|
+
position: ToastPosition<TPositions>
|
|
136
|
+
): ToastItem<TVariants, TPositions, TContent>[];
|
|
137
|
+
activeTimedItemsAt(
|
|
138
|
+
position: ToastPosition<TPositions>
|
|
139
|
+
): ToastItem<TVariants, TPositions, TContent>[];
|
|
140
|
+
activePersistentItemsAt(
|
|
141
|
+
position: ToastPosition<TPositions>
|
|
142
|
+
): ToastItem<TVariants, TPositions, TContent>[];
|
|
143
|
+
isVisibleAt(position: ToastPosition<TPositions>, index: number): boolean;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export type ToastVariantMethods<
|
|
147
|
+
TVariants extends readonly string[],
|
|
148
|
+
TPositions extends readonly string[] = readonly [],
|
|
149
|
+
TContent = unknown,
|
|
150
|
+
> = {
|
|
151
|
+
[K in TVariants[number]]: (
|
|
152
|
+
titleOrPayload: string | ToastPayloadWithoutVariant<TVariants, TPositions, TContent>,
|
|
153
|
+
options?: Omit<ToastPayloadWithoutVariant<TVariants, TPositions, TContent>, "title" | "content">
|
|
154
|
+
) => string;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export type ToastMagic<
|
|
158
|
+
TVariants extends readonly string[] = readonly [],
|
|
159
|
+
TPositions extends readonly string[] = readonly [],
|
|
160
|
+
TContent = unknown,
|
|
161
|
+
> = {
|
|
162
|
+
(title: string, options?: Omit<ToastPayload<TVariants, TPositions, TContent>, "title">): string;
|
|
163
|
+
(payload: ToastPayload<TVariants, TPositions, TContent>): string;
|
|
164
|
+
promise<T>(
|
|
165
|
+
factoryOrPromise: ToastPromiseInput<T>,
|
|
166
|
+
messages?: ToastPromiseMessages<T, ToastVariant<TVariants>, TContent>
|
|
167
|
+
): Promise<T>;
|
|
168
|
+
dismiss(id: string): void;
|
|
169
|
+
update(id: string, payload?: Partial<ToastPayload<TVariants, TPositions, TContent>>): void;
|
|
170
|
+
dismissAt(position: ToastPosition<TPositions>): void;
|
|
171
|
+
dismissAll(): void;
|
|
172
|
+
pushUnique(key: string, payload?: ToastPayload<TVariants, TPositions, TContent>): string;
|
|
173
|
+
fromPayload(payload?: ToastEventPayload<TVariants, TPositions, TContent>): string;
|
|
174
|
+
} & ToastVariantMethods<TVariants, TPositions, TContent>;
|
|
175
|
+
|
|
176
|
+
export type ResolvedPromiseConfig<TVariants extends readonly string[] = readonly []> = {
|
|
177
|
+
loading: string;
|
|
178
|
+
error: string;
|
|
179
|
+
duration: ToastDuration;
|
|
180
|
+
loadingVariant: ToastVariant<TVariants>;
|
|
181
|
+
successVariant: ToastVariant<TVariants>;
|
|
182
|
+
errorVariant: ToastVariant<TVariants>;
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
export type ResolvedToastPluginConfig<
|
|
186
|
+
TVariants extends readonly string[] = readonly [],
|
|
187
|
+
TPositions extends readonly string[] = readonly [],
|
|
188
|
+
> = {
|
|
189
|
+
defaultPosition: ToastPosition<TPositions>;
|
|
190
|
+
defaultDuration: number;
|
|
191
|
+
maxToasts: number;
|
|
192
|
+
maxVisible: number;
|
|
193
|
+
listenToWindowEvents: boolean;
|
|
194
|
+
storeKey: ToastStoreKey;
|
|
195
|
+
variants: TVariants;
|
|
196
|
+
positions: TPositions;
|
|
197
|
+
promise: ResolvedPromiseConfig<TVariants>;
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
export declare function resolveToastPluginConfig<
|
|
201
|
+
const TVariants extends readonly string[] = readonly [],
|
|
202
|
+
const TPositions extends readonly string[] = readonly [],
|
|
203
|
+
>(
|
|
204
|
+
options?: ToastPluginOptions<TVariants, TPositions>
|
|
205
|
+
): ResolvedToastPluginConfig<TVariants, TPositions>;
|
|
206
|
+
|
|
207
|
+
export declare function toastOptions<
|
|
208
|
+
const TVariants extends readonly string[] = readonly [],
|
|
209
|
+
const TPositions extends readonly string[] = readonly [],
|
|
210
|
+
TContent = unknown,
|
|
211
|
+
>(
|
|
212
|
+
options: ToastPluginOptions<TVariants, TPositions, TContent>
|
|
213
|
+
): ToastPluginOptions<TVariants, TPositions, TContent>;
|
|
214
|
+
|
|
215
|
+
export declare function toastVariants<const T extends readonly string[]>(variants: T): T;
|
|
216
|
+
|
|
217
|
+
export declare function toastPositions<const T extends readonly string[]>(positions: T): T;
|
|
218
|
+
|
|
219
|
+
export interface CreateToastStoreOptions<TPositions extends readonly string[] = readonly []> {
|
|
220
|
+
defaultPosition?: ToastPosition<TPositions>;
|
|
221
|
+
positions?: TPositions;
|
|
222
|
+
defaultDuration?: number;
|
|
223
|
+
maxToasts?: number;
|
|
224
|
+
maxVisible?: number;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export declare function resolveStackPositions<TPositions extends readonly string[]>(
|
|
228
|
+
defaultPosition: ToastPosition<TPositions>,
|
|
229
|
+
positions?: TPositions
|
|
230
|
+
): readonly ToastPosition<TPositions>[];
|
|
231
|
+
|
|
232
|
+
export declare function createToastStore<
|
|
233
|
+
const TPositions extends readonly string[] = readonly [],
|
|
234
|
+
TContent = unknown,
|
|
235
|
+
>(options?: CreateToastStoreOptions<TPositions>): ToastStore<readonly [], TPositions, TContent>;
|
|
236
|
+
|
|
237
|
+
export declare function createToastMagic<
|
|
238
|
+
const TVariants extends readonly string[],
|
|
239
|
+
const TPositions extends readonly string[] = readonly [],
|
|
240
|
+
TContent = unknown,
|
|
241
|
+
>(
|
|
242
|
+
config: ResolvedToastPluginConfig<TVariants, TPositions>,
|
|
243
|
+
getStore: () => ToastStore<TVariants, TPositions, TContent>
|
|
244
|
+
): ToastMagic<TVariants, TPositions, TContent>;
|
|
245
|
+
|
|
246
|
+
declare function toastPlugin<
|
|
247
|
+
const TVariants extends readonly string[] = readonly [],
|
|
248
|
+
const TPositions extends readonly string[] = readonly [],
|
|
249
|
+
TContent = unknown,
|
|
250
|
+
>(
|
|
251
|
+
options?: ToastPluginOptions<TVariants, TPositions, TContent>
|
|
252
|
+
): (Alpine: import("alpinejs").Alpine) => void;
|
|
253
|
+
declare function toastPlugin(Alpine: import("alpinejs").Alpine): void;
|
|
254
|
+
|
|
255
|
+
export default toastPlugin;
|
|
256
|
+
|
|
257
|
+
declare global {
|
|
258
|
+
namespace Alpine {
|
|
259
|
+
interface Stores {
|
|
260
|
+
toast: ToastStore;
|
|
261
|
+
}
|
|
262
|
+
interface Magics<T> {
|
|
263
|
+
$toast: ToastMagic;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import AlpineType from 'alpinejs';
|
|
2
|
+
|
|
3
|
+
/** Built-in Alpine store key for the toast queue. */
|
|
4
|
+
declare const TOAST_STORE_KEY: "toast";
|
|
5
|
+
type ToastStoreKey = typeof TOAST_STORE_KEY;
|
|
6
|
+
/** Built-in position used when none is provided. Map to CSS in your UI layer. */
|
|
7
|
+
type DefaultToastPosition = "bottom-right";
|
|
8
|
+
/** Union of `bottom-right` plus developer-defined positions from plugin options. */
|
|
9
|
+
type ToastPosition<TPositions extends readonly string[] = readonly []> = DefaultToastPosition | TPositions[number];
|
|
10
|
+
/** Built-in variant used when none is provided. */
|
|
11
|
+
type DefaultToastVariant = "default";
|
|
12
|
+
/** Milliseconds before auto-dismiss, or `false` / `0` to keep the toast open. */
|
|
13
|
+
type ToastDuration = number | false;
|
|
14
|
+
/** Union of `default` plus developer-defined variants from plugin options. */
|
|
15
|
+
type ToastVariant<TVariants extends readonly string[] = readonly []> = DefaultToastVariant | TVariants[number];
|
|
16
|
+
interface ToastAction {
|
|
17
|
+
label: string;
|
|
18
|
+
onClick?: () => void;
|
|
19
|
+
}
|
|
20
|
+
interface ToastPayload<TVariants extends readonly string[] = readonly [], TPositions extends readonly string[] = readonly [], TContent = unknown> {
|
|
21
|
+
/** Arbitrary payload for your renderer — objects, arrays, DOM refs, etc. */
|
|
22
|
+
content?: TContent | null;
|
|
23
|
+
/** Optional string shorthand; omit when using `content` only. */
|
|
24
|
+
title?: string | null;
|
|
25
|
+
description?: string | null;
|
|
26
|
+
variant?: ToastVariant<TVariants>;
|
|
27
|
+
position?: ToastPosition<TPositions>;
|
|
28
|
+
duration?: ToastDuration;
|
|
29
|
+
action?: ToastAction | null;
|
|
30
|
+
/**
|
|
31
|
+
* Optional dedupe key — use with `pushUnique` so only one active toast keeps this key.
|
|
32
|
+
* Useful for undo flows and single-slot notices.
|
|
33
|
+
*/
|
|
34
|
+
key?: string | null;
|
|
35
|
+
}
|
|
36
|
+
interface ToastItem<TVariants extends readonly string[] = readonly [], TPositions extends readonly string[] = readonly [], TContent = unknown> {
|
|
37
|
+
id: string;
|
|
38
|
+
key: string | null;
|
|
39
|
+
content: TContent | null;
|
|
40
|
+
title: string | null;
|
|
41
|
+
description: string | null;
|
|
42
|
+
variant: ToastVariant<TVariants>;
|
|
43
|
+
position: ToastPosition<TPositions>;
|
|
44
|
+
duration: ToastDuration;
|
|
45
|
+
action: ToastAction | null;
|
|
46
|
+
removed: boolean;
|
|
47
|
+
}
|
|
48
|
+
type ToastPayloadWithoutVariant<TVariants extends readonly string[] = readonly [], TPositions extends readonly string[] = readonly [], TContent = unknown> = Omit<ToastPayload<TVariants, TPositions, TContent>, "variant">;
|
|
49
|
+
interface ToastPromiseOptions<TVariants extends readonly string[] = readonly []> {
|
|
50
|
+
/** Loading toast title. Default: `"Loading..."`. */
|
|
51
|
+
loading?: string;
|
|
52
|
+
/** Error toast title. Default: `"Error"`. */
|
|
53
|
+
error?: string;
|
|
54
|
+
/** Auto-dismiss duration after success/error. Default: `4000`. */
|
|
55
|
+
duration?: ToastDuration;
|
|
56
|
+
loadingVariant?: ToastVariant<TVariants>;
|
|
57
|
+
successVariant?: ToastVariant<TVariants>;
|
|
58
|
+
errorVariant?: ToastVariant<TVariants>;
|
|
59
|
+
}
|
|
60
|
+
interface ToastPluginOptions<TVariants extends readonly string[] = readonly [], TPositions extends readonly string[] = readonly [], _TContent = unknown> {
|
|
61
|
+
/** Optional variant names — each registers a `$toast.<variant>()` shortcut. */
|
|
62
|
+
variants?: TVariants;
|
|
63
|
+
/** Optional position names — stored on each toast; style via your own CSS. */
|
|
64
|
+
positions?: TPositions;
|
|
65
|
+
/** Default toast position when omitted from a payload. */
|
|
66
|
+
defaultPosition?: ToastPosition<TPositions>;
|
|
67
|
+
/** Default auto-dismiss duration in milliseconds. */
|
|
68
|
+
defaultDuration?: number;
|
|
69
|
+
/** Promise flow defaults (`loading` → `success` / `error` variants and copy). */
|
|
70
|
+
promise?: ToastPromiseOptions<TVariants>;
|
|
71
|
+
/** Maximum toasts in the queue. `0` = unlimited. Default: `5`. */
|
|
72
|
+
maxToasts?: number;
|
|
73
|
+
/** Maximum toasts shown at once. Defaults to `maxToasts`. */
|
|
74
|
+
maxVisible?: number;
|
|
75
|
+
/** Listen for `toast` window events. Default: `true`. */
|
|
76
|
+
listenToWindowEvents?: boolean;
|
|
77
|
+
/** Internal store key. Default: `"toast"`. */
|
|
78
|
+
storeKey?: ToastStoreKey;
|
|
79
|
+
}
|
|
80
|
+
interface ToastPromiseMessages<T = unknown, TVariant extends string = string, TContent = unknown> {
|
|
81
|
+
loading?: string;
|
|
82
|
+
success?: string | ((data: T) => string);
|
|
83
|
+
error?: string;
|
|
84
|
+
loadingContent?: TContent;
|
|
85
|
+
successContent?: TContent | ((data: T) => TContent);
|
|
86
|
+
errorContent?: TContent;
|
|
87
|
+
loadingVariant?: TVariant;
|
|
88
|
+
successVariant?: TVariant;
|
|
89
|
+
errorVariant?: TVariant;
|
|
90
|
+
duration?: ToastDuration;
|
|
91
|
+
}
|
|
92
|
+
/** Async factory or an existing `Promise` / thenable passed to `$toast.promise`. */
|
|
93
|
+
type ToastPromiseInput<T> = (() => Promise<T> | T) | Promise<T>;
|
|
94
|
+
type ToastEventPayload<TVariants extends readonly string[] = readonly [], TPositions extends readonly string[] = readonly [], TContent = unknown> = ToastPayload<TVariants, TPositions, TContent>;
|
|
95
|
+
interface ToastStore<TVariants extends readonly string[] = readonly [], TPositions extends readonly string[] = readonly [], TContent = unknown> {
|
|
96
|
+
defaultPosition: ToastPosition<TPositions>;
|
|
97
|
+
/** Positions with an independent toast stack each. */
|
|
98
|
+
stackPositions: readonly ToastPosition<TPositions>[];
|
|
99
|
+
maxToasts: number;
|
|
100
|
+
maxVisible: number;
|
|
101
|
+
items: ToastItem<TVariants, TPositions, TContent>[];
|
|
102
|
+
push(payload?: ToastPayload<TVariants, TPositions, TContent>): string;
|
|
103
|
+
/** Dismiss active toasts with the same `key`, then push. */
|
|
104
|
+
pushUnique(key: string, payload?: ToastPayload<TVariants, TPositions, TContent>): string;
|
|
105
|
+
update(id: string, payload?: Partial<ToastPayload<TVariants, TPositions, TContent>>): void;
|
|
106
|
+
dismiss(id: string): void;
|
|
107
|
+
/** Dismiss every toast in a position stack. */
|
|
108
|
+
dismissAt(position: ToastPosition<TPositions>): void;
|
|
109
|
+
/** Dismiss all toasts in every stack. */
|
|
110
|
+
dismissAll(): void;
|
|
111
|
+
/** Clear pending timers — call when tearing down the plugin or store. */
|
|
112
|
+
destroy(): void;
|
|
113
|
+
/** Toasts at `position`, newest first (includes exiting `removed` items). */
|
|
114
|
+
itemsAt(position: ToastPosition<TPositions>): ToastItem<TVariants, TPositions, TContent>[];
|
|
115
|
+
/** Timed stack at `position` (includes exiting `removed` items). */
|
|
116
|
+
timedItemsAt(position: ToastPosition<TPositions>): ToastItem<TVariants, TPositions, TContent>[];
|
|
117
|
+
/** Persistent stack at `position` (includes exiting `removed` items). */
|
|
118
|
+
persistentItemsAt(position: ToastPosition<TPositions>): ToastItem<TVariants, TPositions, TContent>[];
|
|
119
|
+
/** Active timed toasts only — preferred for `x-for` render lists. */
|
|
120
|
+
activeTimedItemsAt(position: ToastPosition<TPositions>): ToastItem<TVariants, TPositions, TContent>[];
|
|
121
|
+
/** Active persistent toasts only — preferred for `x-for` render lists. */
|
|
122
|
+
activePersistentItemsAt(position: ToastPosition<TPositions>): ToastItem<TVariants, TPositions, TContent>[];
|
|
123
|
+
/** Whether the timed toast at `index` (within `timedItemsAt`) should render. */
|
|
124
|
+
isVisibleAt(position: ToastPosition<TPositions>, index: number): boolean;
|
|
125
|
+
}
|
|
126
|
+
type ToastVariantMethods<TVariants extends readonly string[], TPositions extends readonly string[] = readonly [], TContent = unknown> = {
|
|
127
|
+
[K in TVariants[number]]: (titleOrPayload: string | ToastPayloadWithoutVariant<TVariants, TPositions, TContent>, options?: Omit<ToastPayloadWithoutVariant<TVariants, TPositions, TContent>, "title" | "content">) => string;
|
|
128
|
+
};
|
|
129
|
+
type ToastMagic<TVariants extends readonly string[] = readonly [], TPositions extends readonly string[] = readonly [], TContent = unknown> = {
|
|
130
|
+
(title: string, options?: Omit<ToastPayload<TVariants, TPositions, TContent>, "title">): string;
|
|
131
|
+
(payload: ToastPayload<TVariants, TPositions, TContent>): string;
|
|
132
|
+
promise<T>(factoryOrPromise: ToastPromiseInput<T>, messages?: ToastPromiseMessages<T, ToastVariant<TVariants>, TContent>): Promise<T>;
|
|
133
|
+
dismiss(id: string): void;
|
|
134
|
+
update(id: string, payload?: Partial<ToastPayload<TVariants, TPositions, TContent>>): void;
|
|
135
|
+
/** Dismiss every toast in a position stack. */
|
|
136
|
+
dismissAt(position: ToastPosition<TPositions>): void;
|
|
137
|
+
/** Dismiss all toasts in every stack. */
|
|
138
|
+
dismissAll(): void;
|
|
139
|
+
/** Push after dismissing any active toast with the same `key`. */
|
|
140
|
+
pushUnique(key: string, payload?: ToastPayload<TVariants, TPositions, TContent>): string;
|
|
141
|
+
fromPayload(payload?: ToastEventPayload<TVariants, TPositions, TContent>): string;
|
|
142
|
+
} & ToastVariantMethods<TVariants, TPositions, TContent>;
|
|
143
|
+
type ResolvedPromiseConfig<TVariants extends readonly string[] = readonly []> = {
|
|
144
|
+
loading: string;
|
|
145
|
+
error: string;
|
|
146
|
+
duration: ToastDuration;
|
|
147
|
+
loadingVariant: ToastVariant<TVariants>;
|
|
148
|
+
successVariant: ToastVariant<TVariants>;
|
|
149
|
+
errorVariant: ToastVariant<TVariants>;
|
|
150
|
+
};
|
|
151
|
+
type ResolvedToastPluginConfig<TVariants extends readonly string[] = readonly [], TPositions extends readonly string[] = readonly []> = {
|
|
152
|
+
defaultPosition: ToastPosition<TPositions>;
|
|
153
|
+
defaultDuration: number;
|
|
154
|
+
maxToasts: number;
|
|
155
|
+
maxVisible: number;
|
|
156
|
+
listenToWindowEvents: boolean;
|
|
157
|
+
storeKey: ToastStoreKey;
|
|
158
|
+
variants: TVariants;
|
|
159
|
+
positions: TPositions;
|
|
160
|
+
promise: ResolvedPromiseConfig<TVariants>;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/** Resolves plugin options with defaults and queue limit rules. */
|
|
164
|
+
declare function resolveToastPluginConfig<const TVariants extends readonly string[] = readonly [], const TPositions extends readonly string[] = readonly []>(options?: ToastPluginOptions<TVariants, TPositions>): ResolvedToastPluginConfig<TVariants, TPositions>;
|
|
165
|
+
/** Builds typed toast plugin options with inferred variant and position literals. */
|
|
166
|
+
declare function toastOptions<const TVariants extends readonly string[] = readonly [], const TPositions extends readonly string[] = readonly [], TContent = unknown>(options: ToastPluginOptions<TVariants, TPositions, TContent>): ToastPluginOptions<TVariants, TPositions, TContent>;
|
|
167
|
+
/** Declares toast variant names with full literal inference. */
|
|
168
|
+
declare function toastVariants<const T extends readonly string[]>(variants: T): T;
|
|
169
|
+
/** Declares toast position names with full literal inference. */
|
|
170
|
+
declare function toastPositions<const T extends readonly string[]>(positions: T): T;
|
|
171
|
+
|
|
172
|
+
/** Variant names that cannot override core `$toast` methods. */
|
|
173
|
+
declare const RESERVED_TOAST_MAGIC_KEYS: Set<string>;
|
|
174
|
+
/** Builds the callable `$toast` magic API backed by the internal toast store. */
|
|
175
|
+
declare function createToastMagic<const TVariants extends readonly string[], const TPositions extends readonly string[] = readonly [], TContent = unknown>(config: ResolvedToastPluginConfig<TVariants, TPositions>, getStore: () => ToastStore<TVariants, TPositions, TContent>): ToastMagic<TVariants, TPositions, TContent>;
|
|
176
|
+
|
|
177
|
+
interface CreateToastStoreOptions<TPositions extends readonly string[] = readonly []> {
|
|
178
|
+
defaultPosition?: ToastPosition<TPositions>;
|
|
179
|
+
/** Declared positions — each gets its own stack. */
|
|
180
|
+
positions?: TPositions;
|
|
181
|
+
defaultDuration?: number;
|
|
182
|
+
maxToasts?: number;
|
|
183
|
+
maxVisible?: number;
|
|
184
|
+
/** Reactive store accessor — required for Alpine auto-dismiss timers. */
|
|
185
|
+
getStore?: () => ToastStore<readonly [], TPositions, unknown>;
|
|
186
|
+
}
|
|
187
|
+
declare function resolveToastLimits(options?: {
|
|
188
|
+
maxToasts?: number;
|
|
189
|
+
maxVisible?: number;
|
|
190
|
+
}): {
|
|
191
|
+
maxToasts: number;
|
|
192
|
+
maxVisible: number;
|
|
193
|
+
};
|
|
194
|
+
/** Unique stack keys: built-in default plus configured positions. */
|
|
195
|
+
declare function resolveStackPositions<TPositions extends readonly string[]>(defaultPosition: ToastPosition<TPositions>, positions?: TPositions): readonly ToastPosition<TPositions>[];
|
|
196
|
+
/** Canonical persistent value — `0` is normalized to `false`. */
|
|
197
|
+
declare function normalizeToastDuration(duration: ToastDuration): ToastDuration;
|
|
198
|
+
/** Resolves payload duration — `false` / `0` persist; `undefined` uses the default. */
|
|
199
|
+
declare function resolveToastDuration(duration: ToastDuration | undefined, defaultDuration: number): ToastDuration;
|
|
200
|
+
/** Whether the toast should schedule an auto-dismiss timer. */
|
|
201
|
+
declare function shouldAutoDismiss(duration: ToastDuration): duration is number;
|
|
202
|
+
/** Persistent toasts (`duration: false` / `0`) use a separate UI stack from timed toasts. */
|
|
203
|
+
declare function isPersistentDuration(duration: ToastDuration): boolean;
|
|
204
|
+
/**
|
|
205
|
+
* Timed duration for `$toast.promise` loading state.
|
|
206
|
+
* Stays in the timed stack; the timer is replaced when the promise settles.
|
|
207
|
+
*/
|
|
208
|
+
declare const PROMISE_LOADING_DURATION = 3600000;
|
|
209
|
+
/** Creates the internal reactive toast queue consumed by `$toast` and UI integrators. */
|
|
210
|
+
declare function createToastStore<const TPositions extends readonly string[] = readonly [], TContent = unknown>(options?: CreateToastStoreOptions<TPositions>): ToastStore<readonly [], TPositions, TContent>;
|
|
211
|
+
|
|
212
|
+
/** Alpine.js toast plugin. Registers magic `$toast` with an internal reactive queue. CSS-framework agnostic — no markup or styles. */
|
|
213
|
+
declare function toastPlugin<const TVariants extends readonly string[] = readonly [], const TPositions extends readonly string[] = readonly [], TContent = unknown>(optionsOrAlpine?: ToastPluginOptions<TVariants, TPositions, TContent> | AlpineType.Alpine): undefined | ((Alpine: AlpineType.Alpine) => void);
|
|
214
|
+
declare global {
|
|
215
|
+
namespace Alpine {
|
|
216
|
+
interface Stores {
|
|
217
|
+
toast: ToastStore;
|
|
218
|
+
}
|
|
219
|
+
interface Magics<T> {
|
|
220
|
+
$toast: ToastMagic;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export { type DefaultToastPosition, type DefaultToastVariant, PROMISE_LOADING_DURATION, RESERVED_TOAST_MAGIC_KEYS, type ResolvedPromiseConfig, type ResolvedToastPluginConfig, TOAST_STORE_KEY, type ToastAction, type ToastDuration, type ToastEventPayload, type ToastItem, type ToastMagic, type ToastPayload, type ToastPayloadWithoutVariant, type ToastPluginOptions, type ToastPosition, type ToastPromiseInput, type ToastPromiseMessages, type ToastPromiseOptions, type ToastStore, type ToastStoreKey, type ToastVariant, type ToastVariantMethods, createToastMagic, createToastStore, toastPlugin as default, isPersistentDuration, normalizeToastDuration, resolveStackPositions, resolveToastDuration, resolveToastLimits, resolveToastPluginConfig, shouldAutoDismiss, toastOptions, toastPositions, toastVariants };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
// src/types.ts
|
|
2
|
+
var TOAST_STORE_KEY = "toast";
|
|
3
|
+
|
|
4
|
+
// src/config.ts
|
|
5
|
+
var DEFAULT_PLUGIN_OPTIONS = {
|
|
6
|
+
defaultPosition: "bottom-right",
|
|
7
|
+
defaultDuration: 4e3,
|
|
8
|
+
maxToasts: 5,
|
|
9
|
+
listenToWindowEvents: true
|
|
10
|
+
};
|
|
11
|
+
function variantFromList(variants, preferred) {
|
|
12
|
+
if (variants.includes(preferred)) {
|
|
13
|
+
return preferred;
|
|
14
|
+
}
|
|
15
|
+
return "default";
|
|
16
|
+
}
|
|
17
|
+
function resolvePromiseConfig(variants, promise = {}) {
|
|
18
|
+
return {
|
|
19
|
+
loading: promise.loading ?? "Loading...",
|
|
20
|
+
error: promise.error ?? "Error",
|
|
21
|
+
duration: promise.duration ?? 4e3,
|
|
22
|
+
loadingVariant: promise.loadingVariant ?? variantFromList(variants, "loading"),
|
|
23
|
+
successVariant: promise.successVariant ?? variantFromList(variants, "success"),
|
|
24
|
+
errorVariant: promise.errorVariant ?? variantFromList(variants, "error")
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function resolveToastPluginConfig(options = {}) {
|
|
28
|
+
const variants = options.variants ?? [];
|
|
29
|
+
const positions = options.positions ?? [];
|
|
30
|
+
const maxToasts = options.maxToasts ?? DEFAULT_PLUGIN_OPTIONS.maxToasts;
|
|
31
|
+
let maxVisible = options.maxVisible ?? maxToasts;
|
|
32
|
+
if (maxToasts > 0 && maxVisible > maxToasts) {
|
|
33
|
+
maxVisible = maxToasts;
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
defaultPosition: options.defaultPosition ?? DEFAULT_PLUGIN_OPTIONS.defaultPosition,
|
|
37
|
+
defaultDuration: options.defaultDuration ?? DEFAULT_PLUGIN_OPTIONS.defaultDuration,
|
|
38
|
+
maxToasts,
|
|
39
|
+
maxVisible,
|
|
40
|
+
listenToWindowEvents: options.listenToWindowEvents ?? DEFAULT_PLUGIN_OPTIONS.listenToWindowEvents,
|
|
41
|
+
storeKey: options.storeKey ?? TOAST_STORE_KEY,
|
|
42
|
+
variants,
|
|
43
|
+
positions,
|
|
44
|
+
promise: resolvePromiseConfig(variants, options.promise)
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function toastOptions(options) {
|
|
48
|
+
return options;
|
|
49
|
+
}
|
|
50
|
+
function toastVariants(variants) {
|
|
51
|
+
return variants;
|
|
52
|
+
}
|
|
53
|
+
function toastPositions(positions) {
|
|
54
|
+
return positions;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/store.ts
|
|
58
|
+
function resolveToastLimits(options = {}) {
|
|
59
|
+
const maxToasts = options.maxToasts ?? 5;
|
|
60
|
+
let maxVisible = options.maxVisible ?? maxToasts;
|
|
61
|
+
if (maxToasts > 0 && maxVisible > maxToasts) {
|
|
62
|
+
maxVisible = maxToasts;
|
|
63
|
+
}
|
|
64
|
+
return { maxToasts, maxVisible };
|
|
65
|
+
}
|
|
66
|
+
function resolveStackPositions(defaultPosition, positions) {
|
|
67
|
+
const stacks = [defaultPosition];
|
|
68
|
+
for (const position of positions ?? []) {
|
|
69
|
+
if (!stacks.includes(position)) {
|
|
70
|
+
stacks.push(position);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return stacks;
|
|
74
|
+
}
|
|
75
|
+
function createToastId() {
|
|
76
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
77
|
+
return crypto.randomUUID();
|
|
78
|
+
}
|
|
79
|
+
return `toast-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
80
|
+
}
|
|
81
|
+
function normalizeToastDuration(duration) {
|
|
82
|
+
if (duration === 0) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
return duration;
|
|
86
|
+
}
|
|
87
|
+
function resolveToastDuration(duration, defaultDuration) {
|
|
88
|
+
if (duration === void 0) {
|
|
89
|
+
return normalizeToastDuration(defaultDuration);
|
|
90
|
+
}
|
|
91
|
+
return normalizeToastDuration(duration);
|
|
92
|
+
}
|
|
93
|
+
function shouldAutoDismiss(duration) {
|
|
94
|
+
return typeof duration === "number" && duration > 0 && Number.isFinite(duration);
|
|
95
|
+
}
|
|
96
|
+
function isPersistentDuration(duration) {
|
|
97
|
+
return !shouldAutoDismiss(duration);
|
|
98
|
+
}
|
|
99
|
+
var PROMISE_LOADING_DURATION = 36e5;
|
|
100
|
+
function itemsAtPosition(items, position) {
|
|
101
|
+
return items.filter((item) => item.position === position);
|
|
102
|
+
}
|
|
103
|
+
function timedStackAt(items, position) {
|
|
104
|
+
return itemsAtPosition(items, position).filter((item) => shouldAutoDismiss(item.duration));
|
|
105
|
+
}
|
|
106
|
+
function persistentStackAt(items, position) {
|
|
107
|
+
return itemsAtPosition(items, position).filter((item) => isPersistentDuration(item.duration));
|
|
108
|
+
}
|
|
109
|
+
function enforcePositionLimit(items, position, maxToasts, dismissMany, stack) {
|
|
110
|
+
if (maxToasts <= 0) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const stackAtPosition = stack === "persistent" ? persistentStackAt(items, position) : timedStackAt(items, position);
|
|
114
|
+
const activeAtPosition = stackAtPosition.filter((item) => !item.removed);
|
|
115
|
+
const overflowIds = activeAtPosition.slice(maxToasts).map((item) => item.id);
|
|
116
|
+
dismissMany(overflowIds);
|
|
117
|
+
}
|
|
118
|
+
function applyToastPatch(item, payload) {
|
|
119
|
+
const next = { ...item };
|
|
120
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
121
|
+
if (value !== void 0) {
|
|
122
|
+
if (key === "duration") {
|
|
123
|
+
Object.assign(next, { duration: normalizeToastDuration(value) });
|
|
124
|
+
} else {
|
|
125
|
+
Object.assign(next, { [key]: value });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return next;
|
|
130
|
+
}
|
|
131
|
+
function createToastStore(options = {}) {
|
|
132
|
+
const defaultPosition = options.defaultPosition ?? "bottom-right";
|
|
133
|
+
const stackPositions = resolveStackPositions(defaultPosition, options.positions);
|
|
134
|
+
const defaultDuration = options.defaultDuration ?? 4e3;
|
|
135
|
+
const { maxToasts, maxVisible } = resolveToastLimits(options);
|
|
136
|
+
const dismissDelayMs = 400;
|
|
137
|
+
const dismissTimers = /* @__PURE__ */ new Map();
|
|
138
|
+
const purgeTimers = /* @__PURE__ */ new Map();
|
|
139
|
+
const getStore = options.getStore;
|
|
140
|
+
const store = {
|
|
141
|
+
defaultPosition,
|
|
142
|
+
stackPositions,
|
|
143
|
+
maxToasts,
|
|
144
|
+
maxVisible,
|
|
145
|
+
items: [],
|
|
146
|
+
itemsAt(position) {
|
|
147
|
+
return itemsAtPosition(this.items, position);
|
|
148
|
+
},
|
|
149
|
+
timedItemsAt(position) {
|
|
150
|
+
return timedStackAt(this.items, position);
|
|
151
|
+
},
|
|
152
|
+
persistentItemsAt(position) {
|
|
153
|
+
return persistentStackAt(this.items, position);
|
|
154
|
+
},
|
|
155
|
+
activeTimedItemsAt(position) {
|
|
156
|
+
return this.timedItemsAt(position).filter((item) => !item.removed);
|
|
157
|
+
},
|
|
158
|
+
activePersistentItemsAt(position) {
|
|
159
|
+
return this.persistentItemsAt(position).filter((item) => !item.removed);
|
|
160
|
+
},
|
|
161
|
+
isVisibleAt(position, index) {
|
|
162
|
+
const stack = this.timedItemsAt(position);
|
|
163
|
+
const item = stack[index];
|
|
164
|
+
if (!item || item.removed) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
if (this.maxVisible <= 0) {
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
let rank = 0;
|
|
171
|
+
for (let i = 0; i <= index; i++) {
|
|
172
|
+
if (stack[i] && !stack[i].removed) {
|
|
173
|
+
rank++;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return rank <= this.maxVisible;
|
|
177
|
+
},
|
|
178
|
+
push(payload = {}) {
|
|
179
|
+
const position = payload.position ?? this.defaultPosition;
|
|
180
|
+
const id = createToastId();
|
|
181
|
+
const toast = {
|
|
182
|
+
id,
|
|
183
|
+
key: payload.key ?? null,
|
|
184
|
+
content: payload.content ?? null,
|
|
185
|
+
title: payload.title ?? null,
|
|
186
|
+
description: payload.description ?? null,
|
|
187
|
+
variant: payload.variant ?? "default",
|
|
188
|
+
position,
|
|
189
|
+
duration: resolveToastDuration(payload.duration, defaultDuration),
|
|
190
|
+
action: payload.action ?? null,
|
|
191
|
+
removed: false
|
|
192
|
+
};
|
|
193
|
+
this.items = [toast, ...this.items];
|
|
194
|
+
enforcePositionLimit(
|
|
195
|
+
this.items,
|
|
196
|
+
position,
|
|
197
|
+
this.maxToasts,
|
|
198
|
+
(ids) => markRemoved(ids),
|
|
199
|
+
shouldAutoDismiss(toast.duration) ? "timed" : "persistent"
|
|
200
|
+
);
|
|
201
|
+
scheduleDismiss(id, toast.duration);
|
|
202
|
+
return id;
|
|
203
|
+
},
|
|
204
|
+
pushUnique(key, payload = {}) {
|
|
205
|
+
const activeIds = this.items.filter((item) => !item.removed && item.key === key).map((item) => item.id);
|
|
206
|
+
markRemoved(activeIds);
|
|
207
|
+
return this.push({ ...payload, key });
|
|
208
|
+
},
|
|
209
|
+
update(id, payload = {}) {
|
|
210
|
+
const current = this.items.find((toast) => toast.id === id);
|
|
211
|
+
if (!current) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const previousPosition = current.position;
|
|
215
|
+
const wasPersistent = isPersistentDuration(current.duration);
|
|
216
|
+
this.items = this.items.map(
|
|
217
|
+
(item) => item.id === id ? applyToastPatch(item, payload) : item
|
|
218
|
+
);
|
|
219
|
+
const updated = this.items.find((toast) => toast.id === id);
|
|
220
|
+
if (!updated) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
const nextPosition = updated.position;
|
|
224
|
+
const isNowPersistent = isPersistentDuration(updated.duration);
|
|
225
|
+
const durationStackChanged = payload.duration !== void 0 && wasPersistent !== isNowPersistent;
|
|
226
|
+
const positionChanged = nextPosition !== previousPosition;
|
|
227
|
+
if (positionChanged) {
|
|
228
|
+
enforcePositionLimit(
|
|
229
|
+
this.items,
|
|
230
|
+
previousPosition,
|
|
231
|
+
this.maxToasts,
|
|
232
|
+
(ids) => markRemoved(ids),
|
|
233
|
+
"timed"
|
|
234
|
+
);
|
|
235
|
+
enforcePositionLimit(
|
|
236
|
+
this.items,
|
|
237
|
+
previousPosition,
|
|
238
|
+
this.maxToasts,
|
|
239
|
+
(ids) => markRemoved(ids),
|
|
240
|
+
"persistent"
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
if (positionChanged || durationStackChanged) {
|
|
244
|
+
enforcePositionLimit(
|
|
245
|
+
this.items,
|
|
246
|
+
nextPosition,
|
|
247
|
+
this.maxToasts,
|
|
248
|
+
(ids) => markRemoved(ids),
|
|
249
|
+
"timed"
|
|
250
|
+
);
|
|
251
|
+
enforcePositionLimit(
|
|
252
|
+
this.items,
|
|
253
|
+
nextPosition,
|
|
254
|
+
this.maxToasts,
|
|
255
|
+
(ids) => markRemoved(ids),
|
|
256
|
+
"persistent"
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
if (payload.duration !== void 0) {
|
|
260
|
+
scheduleDismiss(id, updated.duration);
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
dismiss(id) {
|
|
264
|
+
markRemoved([id]);
|
|
265
|
+
},
|
|
266
|
+
dismissAt(position) {
|
|
267
|
+
const ids = this.itemsAt(position).filter((item) => !item.removed).map((item) => item.id);
|
|
268
|
+
markRemoved(ids);
|
|
269
|
+
},
|
|
270
|
+
dismissAll() {
|
|
271
|
+
const ids = this.items.filter((item) => !item.removed).map((item) => item.id);
|
|
272
|
+
markRemoved(ids);
|
|
273
|
+
},
|
|
274
|
+
destroy() {
|
|
275
|
+
for (const timer of dismissTimers.values()) {
|
|
276
|
+
clearTimeout(timer);
|
|
277
|
+
}
|
|
278
|
+
dismissTimers.clear();
|
|
279
|
+
for (const timer of purgeTimers.values()) {
|
|
280
|
+
clearTimeout(timer);
|
|
281
|
+
}
|
|
282
|
+
purgeTimers.clear();
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
function clearDismissTimer(id) {
|
|
286
|
+
const timer = dismissTimers.get(id);
|
|
287
|
+
if (timer !== void 0) {
|
|
288
|
+
clearTimeout(timer);
|
|
289
|
+
dismissTimers.delete(id);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function markRemoved(ids) {
|
|
293
|
+
if (ids.length === 0) {
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
const activeStore = getStore?.() ?? store;
|
|
297
|
+
const idsToRemove = [];
|
|
298
|
+
for (const id of ids) {
|
|
299
|
+
const toast = activeStore.items.find((item) => item.id === id);
|
|
300
|
+
if (!toast || toast.removed) {
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
clearDismissTimer(id);
|
|
304
|
+
idsToRemove.push(id);
|
|
305
|
+
}
|
|
306
|
+
if (idsToRemove.length === 0) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const removeSet = new Set(idsToRemove);
|
|
310
|
+
activeStore.items = activeStore.items.map(
|
|
311
|
+
(item) => removeSet.has(item.id) ? { ...item, removed: true } : item
|
|
312
|
+
);
|
|
313
|
+
const batchId = createToastId();
|
|
314
|
+
const timer = setTimeout(() => {
|
|
315
|
+
purgeTimers.delete(batchId);
|
|
316
|
+
const storeForFilter = getStore?.() ?? store;
|
|
317
|
+
storeForFilter.items = storeForFilter.items.filter((item) => !removeSet.has(item.id));
|
|
318
|
+
}, dismissDelayMs);
|
|
319
|
+
purgeTimers.set(batchId, timer);
|
|
320
|
+
}
|
|
321
|
+
function scheduleDismiss(id, duration) {
|
|
322
|
+
clearDismissTimer(id);
|
|
323
|
+
if (duration === PROMISE_LOADING_DURATION) {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
if (shouldAutoDismiss(duration)) {
|
|
327
|
+
const timer = setTimeout(() => {
|
|
328
|
+
dismissTimers.delete(id);
|
|
329
|
+
(getStore?.() ?? store).dismiss(id);
|
|
330
|
+
}, duration);
|
|
331
|
+
dismissTimers.set(id, timer);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return store;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// src/magic.ts
|
|
338
|
+
var RESERVED_TOAST_MAGIC_KEYS = /* @__PURE__ */ new Set([
|
|
339
|
+
"dismiss",
|
|
340
|
+
"update",
|
|
341
|
+
"dismissAt",
|
|
342
|
+
"dismissAll",
|
|
343
|
+
"pushUnique",
|
|
344
|
+
"fromPayload",
|
|
345
|
+
"promise"
|
|
346
|
+
]);
|
|
347
|
+
function pushToast(store, titleOrPayload, options = {}) {
|
|
348
|
+
if (typeof titleOrPayload === "string") {
|
|
349
|
+
return store.push({
|
|
350
|
+
title: titleOrPayload,
|
|
351
|
+
...options
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
return store.push(titleOrPayload);
|
|
355
|
+
}
|
|
356
|
+
function pushVariantToast(store, variant, titleOrPayload, options = {}) {
|
|
357
|
+
if (typeof titleOrPayload === "string") {
|
|
358
|
+
return store.push({
|
|
359
|
+
title: titleOrPayload,
|
|
360
|
+
...options,
|
|
361
|
+
variant
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
return store.push({
|
|
365
|
+
...titleOrPayload,
|
|
366
|
+
...options,
|
|
367
|
+
variant
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
function resolveSuccessTitle(data, messages) {
|
|
371
|
+
if (typeof messages.success === "function") {
|
|
372
|
+
return messages.success(data);
|
|
373
|
+
}
|
|
374
|
+
return messages.success;
|
|
375
|
+
}
|
|
376
|
+
function resolveSuccessContent(data, messages) {
|
|
377
|
+
const { successContent } = messages;
|
|
378
|
+
if (typeof successContent === "function") {
|
|
379
|
+
return successContent(data);
|
|
380
|
+
}
|
|
381
|
+
return successContent;
|
|
382
|
+
}
|
|
383
|
+
function resolveErrorTitle(messages, fallbackError) {
|
|
384
|
+
return messages.error ?? fallbackError;
|
|
385
|
+
}
|
|
386
|
+
function resolveToastPromise(factoryOrPromise) {
|
|
387
|
+
if (typeof factoryOrPromise === "function") {
|
|
388
|
+
return Promise.resolve(factoryOrPromise());
|
|
389
|
+
}
|
|
390
|
+
return Promise.resolve(factoryOrPromise);
|
|
391
|
+
}
|
|
392
|
+
function buildPromiseSuccessPatch(data, messages, successVariant, settledDuration) {
|
|
393
|
+
const successTitle = resolveSuccessTitle(data, messages);
|
|
394
|
+
const successContent = resolveSuccessContent(data, messages);
|
|
395
|
+
return {
|
|
396
|
+
...successTitle !== void 0 ? { title: successTitle } : {},
|
|
397
|
+
...successContent !== void 0 ? { content: successContent } : {},
|
|
398
|
+
variant: successVariant,
|
|
399
|
+
duration: settledDuration
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
function buildPromiseErrorPatch(messages, promiseConfig, errorVariant, settledDuration) {
|
|
403
|
+
return {
|
|
404
|
+
title: resolveErrorTitle(messages, promiseConfig.error),
|
|
405
|
+
...messages.errorContent !== void 0 ? { content: messages.errorContent } : {},
|
|
406
|
+
variant: errorVariant,
|
|
407
|
+
duration: settledDuration
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
function createToastMagic(config, getStore) {
|
|
411
|
+
const magic = ((titleOrPayload, options) => pushToast(getStore(), titleOrPayload, options ?? {}));
|
|
412
|
+
magic.dismiss = (id) => getStore().dismiss(id);
|
|
413
|
+
magic.update = (id, payload) => getStore().update(id, payload);
|
|
414
|
+
magic.dismissAt = (position) => getStore().dismissAt(position);
|
|
415
|
+
magic.dismissAll = () => getStore().dismissAll();
|
|
416
|
+
magic.pushUnique = (key, payload) => getStore().pushUnique(key, payload ?? {});
|
|
417
|
+
magic.fromPayload = (payload = {}) => {
|
|
418
|
+
const { title = null, content = null, variant = "default", ...options } = payload;
|
|
419
|
+
return pushToast(getStore(), {
|
|
420
|
+
title,
|
|
421
|
+
content,
|
|
422
|
+
variant,
|
|
423
|
+
...options
|
|
424
|
+
});
|
|
425
|
+
};
|
|
426
|
+
magic.promise = async (factoryOrPromise, messages = {}) => {
|
|
427
|
+
const promiseConfig = config.promise;
|
|
428
|
+
const loadingVariant = messages.loadingVariant ?? promiseConfig.loadingVariant;
|
|
429
|
+
const successVariant = messages.successVariant ?? promiseConfig.successVariant;
|
|
430
|
+
const errorVariant = messages.errorVariant ?? promiseConfig.errorVariant;
|
|
431
|
+
const settledDuration = messages.duration ?? promiseConfig.duration;
|
|
432
|
+
const id = getStore().push({
|
|
433
|
+
title: messages.loading ?? promiseConfig.loading,
|
|
434
|
+
content: messages.loadingContent ?? null,
|
|
435
|
+
variant: loadingVariant,
|
|
436
|
+
duration: PROMISE_LOADING_DURATION
|
|
437
|
+
});
|
|
438
|
+
try {
|
|
439
|
+
const data = await resolveToastPromise(factoryOrPromise);
|
|
440
|
+
getStore().update(
|
|
441
|
+
id,
|
|
442
|
+
buildPromiseSuccessPatch(data, messages, successVariant, settledDuration)
|
|
443
|
+
);
|
|
444
|
+
return data;
|
|
445
|
+
} catch (error) {
|
|
446
|
+
getStore().update(
|
|
447
|
+
id,
|
|
448
|
+
buildPromiseErrorPatch(messages, promiseConfig, errorVariant, settledDuration)
|
|
449
|
+
);
|
|
450
|
+
throw error;
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
for (const variant of config.variants) {
|
|
454
|
+
if (RESERVED_TOAST_MAGIC_KEYS.has(variant)) {
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
Object.assign(magic, {
|
|
458
|
+
[variant]: (titleOrPayload, options = {}) => pushVariantToast(getStore(), variant, titleOrPayload, options)
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
return magic;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// src/index.ts
|
|
465
|
+
function registerAlpineToastStore(Alpine, storeKey, store) {
|
|
466
|
+
const registerStore = Alpine.store;
|
|
467
|
+
registerStore(storeKey, store);
|
|
468
|
+
}
|
|
469
|
+
function getToastStore(Alpine, storeKey) {
|
|
470
|
+
return Alpine.store(storeKey);
|
|
471
|
+
}
|
|
472
|
+
function registerToastPlugin(Alpine, options = {}) {
|
|
473
|
+
const config = resolveToastPluginConfig(options);
|
|
474
|
+
let reactiveStore;
|
|
475
|
+
let windowEventsAbort;
|
|
476
|
+
const store = createToastStore({
|
|
477
|
+
defaultPosition: config.defaultPosition,
|
|
478
|
+
positions: config.positions,
|
|
479
|
+
defaultDuration: config.defaultDuration,
|
|
480
|
+
maxToasts: config.maxToasts,
|
|
481
|
+
maxVisible: config.maxVisible,
|
|
482
|
+
getStore: () => reactiveStore ?? store
|
|
483
|
+
});
|
|
484
|
+
const baseDestroy = store.destroy.bind(store);
|
|
485
|
+
store.destroy = () => {
|
|
486
|
+
windowEventsAbort?.abort();
|
|
487
|
+
windowEventsAbort = void 0;
|
|
488
|
+
baseDestroy();
|
|
489
|
+
};
|
|
490
|
+
registerAlpineToastStore(Alpine, config.storeKey, store);
|
|
491
|
+
reactiveStore = getToastStore(Alpine, config.storeKey);
|
|
492
|
+
const toast = createToastMagic(
|
|
493
|
+
config,
|
|
494
|
+
() => getToastStore(Alpine, config.storeKey)
|
|
495
|
+
);
|
|
496
|
+
Alpine.magic("toast", () => toast);
|
|
497
|
+
if (config.listenToWindowEvents && typeof window !== "undefined") {
|
|
498
|
+
windowEventsAbort = new AbortController();
|
|
499
|
+
window.addEventListener(
|
|
500
|
+
"toast",
|
|
501
|
+
(event) => {
|
|
502
|
+
if (event instanceof CustomEvent) {
|
|
503
|
+
toast.fromPayload(
|
|
504
|
+
event.detail ?? {}
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
},
|
|
508
|
+
{ signal: windowEventsAbort.signal }
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
function toastPlugin(optionsOrAlpine) {
|
|
513
|
+
if (optionsOrAlpine && typeof optionsOrAlpine.magic === "function") {
|
|
514
|
+
registerToastPlugin(optionsOrAlpine, {});
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
const options = optionsOrAlpine ?? {};
|
|
518
|
+
return (Alpine) => {
|
|
519
|
+
registerToastPlugin(Alpine, options);
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
export {
|
|
523
|
+
PROMISE_LOADING_DURATION,
|
|
524
|
+
RESERVED_TOAST_MAGIC_KEYS,
|
|
525
|
+
TOAST_STORE_KEY,
|
|
526
|
+
createToastMagic,
|
|
527
|
+
createToastStore,
|
|
528
|
+
toastPlugin as default,
|
|
529
|
+
isPersistentDuration,
|
|
530
|
+
normalizeToastDuration,
|
|
531
|
+
resolveStackPositions,
|
|
532
|
+
resolveToastDuration,
|
|
533
|
+
resolveToastLimits,
|
|
534
|
+
resolveToastPluginConfig,
|
|
535
|
+
shouldAutoDismiss,
|
|
536
|
+
toastOptions,
|
|
537
|
+
toastPositions,
|
|
538
|
+
toastVariants
|
|
539
|
+
};
|
|
540
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/config.ts","../src/store.ts","../src/magic.ts","../src/index.ts"],"sourcesContent":["/** Built-in Alpine store key for the toast queue. */\nexport const TOAST_STORE_KEY = \"toast\" as const;\n\nexport type ToastStoreKey = typeof TOAST_STORE_KEY;\n\n/** Built-in position used when none is provided. Map to CSS in your UI layer. */\nexport type DefaultToastPosition = \"bottom-right\";\n\n/** Union of `bottom-right` plus developer-defined positions from plugin options. */\nexport type ToastPosition<TPositions extends readonly string[] = readonly []> =\n | DefaultToastPosition\n | TPositions[number];\n\n/** Built-in variant used when none is provided. */\nexport type DefaultToastVariant = \"default\";\n\n/** Milliseconds before auto-dismiss, or `false` / `0` to keep the toast open. */\nexport type ToastDuration = number | false;\n\n/** Union of `default` plus developer-defined variants from plugin options. */\nexport type ToastVariant<TVariants extends readonly string[] = readonly []> =\n | DefaultToastVariant\n | TVariants[number];\n\nexport interface ToastAction {\n label: string;\n onClick?: () => void;\n}\n\nexport interface ToastPayload<\n TVariants extends readonly string[] = readonly [],\n TPositions extends readonly string[] = readonly [],\n TContent = unknown,\n> {\n /** Arbitrary payload for your renderer — objects, arrays, DOM refs, etc. */\n content?: TContent | null;\n /** Optional string shorthand; omit when using `content` only. */\n title?: string | null;\n description?: string | null;\n variant?: ToastVariant<TVariants>;\n position?: ToastPosition<TPositions>;\n duration?: ToastDuration;\n action?: ToastAction | null;\n /**\n * Optional dedupe key — use with `pushUnique` so only one active toast keeps this key.\n * Useful for undo flows and single-slot notices.\n */\n key?: string | null;\n}\n\nexport interface ToastItem<\n TVariants extends readonly string[] = readonly [],\n TPositions extends readonly string[] = readonly [],\n TContent = unknown,\n> {\n id: string;\n key: string | null;\n content: TContent | null;\n title: string | null;\n description: string | null;\n variant: ToastVariant<TVariants>;\n position: ToastPosition<TPositions>;\n duration: ToastDuration;\n action: ToastAction | null;\n removed: boolean;\n}\n\nexport type ToastPayloadWithoutVariant<\n TVariants extends readonly string[] = readonly [],\n TPositions extends readonly string[] = readonly [],\n TContent = unknown,\n> = Omit<ToastPayload<TVariants, TPositions, TContent>, \"variant\">;\n\nexport interface ToastPromiseOptions<TVariants extends readonly string[] = readonly []> {\n /** Loading toast title. Default: `\"Loading...\"`. */\n loading?: string;\n /** Error toast title. Default: `\"Error\"`. */\n error?: string;\n /** Auto-dismiss duration after success/error. Default: `4000`. */\n duration?: ToastDuration;\n loadingVariant?: ToastVariant<TVariants>;\n successVariant?: ToastVariant<TVariants>;\n errorVariant?: ToastVariant<TVariants>;\n}\n\nexport interface ToastPluginOptions<\n TVariants extends readonly string[] = readonly [],\n TPositions extends readonly string[] = readonly [],\n _TContent = unknown,\n> {\n /** Optional variant names — each registers a `$toast.<variant>()` shortcut. */\n variants?: TVariants;\n /** Optional position names — stored on each toast; style via your own CSS. */\n positions?: TPositions;\n /** Default toast position when omitted from a payload. */\n defaultPosition?: ToastPosition<TPositions>;\n /** Default auto-dismiss duration in milliseconds. */\n defaultDuration?: number;\n /** Promise flow defaults (`loading` → `success` / `error` variants and copy). */\n promise?: ToastPromiseOptions<TVariants>;\n /** Maximum toasts in the queue. `0` = unlimited. Default: `5`. */\n maxToasts?: number;\n /** Maximum toasts shown at once. Defaults to `maxToasts`. */\n maxVisible?: number;\n /** Listen for `toast` window events. Default: `true`. */\n listenToWindowEvents?: boolean;\n /** Internal store key. Default: `\"toast\"`. */\n storeKey?: ToastStoreKey;\n}\n\nexport interface ToastPromiseMessages<\n T = unknown,\n TVariant extends string = string,\n TContent = unknown,\n> {\n loading?: string;\n success?: string | ((data: T) => string);\n error?: string;\n loadingContent?: TContent;\n successContent?: TContent | ((data: T) => TContent);\n errorContent?: TContent;\n loadingVariant?: TVariant;\n successVariant?: TVariant;\n errorVariant?: TVariant;\n duration?: ToastDuration;\n}\n\n/** Async factory or an existing `Promise` / thenable passed to `$toast.promise`. */\nexport type ToastPromiseInput<T> = (() => Promise<T> | T) | Promise<T>;\n\nexport type ToastEventPayload<\n TVariants extends readonly string[] = readonly [],\n TPositions extends readonly string[] = readonly [],\n TContent = unknown,\n> = ToastPayload<TVariants, TPositions, TContent>;\n\nexport interface ToastStore<\n TVariants extends readonly string[] = readonly [],\n TPositions extends readonly string[] = readonly [],\n TContent = unknown,\n> {\n defaultPosition: ToastPosition<TPositions>;\n /** Positions with an independent toast stack each. */\n stackPositions: readonly ToastPosition<TPositions>[];\n maxToasts: number;\n maxVisible: number;\n items: ToastItem<TVariants, TPositions, TContent>[];\n push(payload?: ToastPayload<TVariants, TPositions, TContent>): string;\n /** Dismiss active toasts with the same `key`, then push. */\n pushUnique(key: string, payload?: ToastPayload<TVariants, TPositions, TContent>): string;\n update(id: string, payload?: Partial<ToastPayload<TVariants, TPositions, TContent>>): void;\n dismiss(id: string): void;\n /** Dismiss every toast in a position stack. */\n dismissAt(position: ToastPosition<TPositions>): void;\n /** Dismiss all toasts in every stack. */\n dismissAll(): void;\n /** Clear pending timers — call when tearing down the plugin or store. */\n destroy(): void;\n /** Toasts at `position`, newest first (includes exiting `removed` items). */\n itemsAt(position: ToastPosition<TPositions>): ToastItem<TVariants, TPositions, TContent>[];\n /** Timed stack at `position` (includes exiting `removed` items). */\n timedItemsAt(position: ToastPosition<TPositions>): ToastItem<TVariants, TPositions, TContent>[];\n /** Persistent stack at `position` (includes exiting `removed` items). */\n persistentItemsAt(\n position: ToastPosition<TPositions>\n ): ToastItem<TVariants, TPositions, TContent>[];\n /** Active timed toasts only — preferred for `x-for` render lists. */\n activeTimedItemsAt(\n position: ToastPosition<TPositions>\n ): ToastItem<TVariants, TPositions, TContent>[];\n /** Active persistent toasts only — preferred for `x-for` render lists. */\n activePersistentItemsAt(\n position: ToastPosition<TPositions>\n ): ToastItem<TVariants, TPositions, TContent>[];\n /** Whether the timed toast at `index` (within `timedItemsAt`) should render. */\n isVisibleAt(position: ToastPosition<TPositions>, index: number): boolean;\n}\n\nexport type ToastVariantMethods<\n TVariants extends readonly string[],\n TPositions extends readonly string[] = readonly [],\n TContent = unknown,\n> = {\n [K in TVariants[number]]: (\n titleOrPayload: string | ToastPayloadWithoutVariant<TVariants, TPositions, TContent>,\n options?: Omit<ToastPayloadWithoutVariant<TVariants, TPositions, TContent>, \"title\" | \"content\">\n ) => string;\n};\n\nexport type ToastMagic<\n TVariants extends readonly string[] = readonly [],\n TPositions extends readonly string[] = readonly [],\n TContent = unknown,\n> = {\n (title: string, options?: Omit<ToastPayload<TVariants, TPositions, TContent>, \"title\">): string;\n (payload: ToastPayload<TVariants, TPositions, TContent>): string;\n promise<T>(\n factoryOrPromise: ToastPromiseInput<T>,\n messages?: ToastPromiseMessages<T, ToastVariant<TVariants>, TContent>\n ): Promise<T>;\n dismiss(id: string): void;\n update(id: string, payload?: Partial<ToastPayload<TVariants, TPositions, TContent>>): void;\n /** Dismiss every toast in a position stack. */\n dismissAt(position: ToastPosition<TPositions>): void;\n /** Dismiss all toasts in every stack. */\n dismissAll(): void;\n /** Push after dismissing any active toast with the same `key`. */\n pushUnique(key: string, payload?: ToastPayload<TVariants, TPositions, TContent>): string;\n fromPayload(payload?: ToastEventPayload<TVariants, TPositions, TContent>): string;\n} & ToastVariantMethods<TVariants, TPositions, TContent>;\n\nexport type ResolvedPromiseConfig<TVariants extends readonly string[] = readonly []> = {\n loading: string;\n error: string;\n duration: ToastDuration;\n loadingVariant: ToastVariant<TVariants>;\n successVariant: ToastVariant<TVariants>;\n errorVariant: ToastVariant<TVariants>;\n};\n\nexport type ResolvedToastPluginConfig<\n TVariants extends readonly string[] = readonly [],\n TPositions extends readonly string[] = readonly [],\n> = {\n defaultPosition: ToastPosition<TPositions>;\n defaultDuration: number;\n maxToasts: number;\n maxVisible: number;\n listenToWindowEvents: boolean;\n storeKey: ToastStoreKey;\n variants: TVariants;\n positions: TPositions;\n promise: ResolvedPromiseConfig<TVariants>;\n};\n","import type {\n ResolvedPromiseConfig,\n ResolvedToastPluginConfig,\n ToastPluginOptions,\n ToastVariant,\n} from \"./types.js\";\nimport { TOAST_STORE_KEY } from \"./types.js\";\n\nconst DEFAULT_PLUGIN_OPTIONS = {\n defaultPosition: \"bottom-right\",\n defaultDuration: 4000,\n maxToasts: 5,\n listenToWindowEvents: true,\n} as const;\n\nfunction variantFromList<TVariants extends readonly string[]>(\n variants: TVariants,\n preferred: string\n): ToastVariant<TVariants> {\n if (variants.includes(preferred)) {\n return preferred as ToastVariant<TVariants>;\n }\n\n return \"default\";\n}\n\nfunction resolvePromiseConfig<TVariants extends readonly string[]>(\n variants: TVariants,\n promise: ToastPluginOptions<TVariants>[\"promise\"] = {}\n): ResolvedPromiseConfig<TVariants> {\n return {\n loading: promise.loading ?? \"Loading...\",\n error: promise.error ?? \"Error\",\n duration: promise.duration ?? 4000,\n loadingVariant: promise.loadingVariant ?? variantFromList(variants, \"loading\"),\n successVariant: promise.successVariant ?? variantFromList(variants, \"success\"),\n errorVariant: promise.errorVariant ?? variantFromList(variants, \"error\"),\n };\n}\n\n/** Resolves plugin options with defaults and queue limit rules. */\nexport function resolveToastPluginConfig<\n const TVariants extends readonly string[] = readonly [],\n const TPositions extends readonly string[] = readonly [],\n>(\n options: ToastPluginOptions<TVariants, TPositions> = {} as ToastPluginOptions<\n TVariants,\n TPositions\n >\n): ResolvedToastPluginConfig<TVariants, TPositions> {\n const variants = (options.variants ?? []) as TVariants;\n const positions = (options.positions ?? []) as TPositions;\n const maxToasts = options.maxToasts ?? DEFAULT_PLUGIN_OPTIONS.maxToasts;\n let maxVisible = options.maxVisible ?? maxToasts;\n\n if (maxToasts > 0 && maxVisible > maxToasts) {\n maxVisible = maxToasts;\n }\n\n return {\n defaultPosition: options.defaultPosition ?? DEFAULT_PLUGIN_OPTIONS.defaultPosition,\n defaultDuration: options.defaultDuration ?? DEFAULT_PLUGIN_OPTIONS.defaultDuration,\n maxToasts,\n maxVisible,\n listenToWindowEvents:\n options.listenToWindowEvents ?? DEFAULT_PLUGIN_OPTIONS.listenToWindowEvents,\n storeKey: options.storeKey ?? TOAST_STORE_KEY,\n variants,\n positions,\n promise: resolvePromiseConfig(variants, options.promise),\n };\n}\n\n/** Builds typed toast plugin options with inferred variant and position literals. */\nexport function toastOptions<\n const TVariants extends readonly string[] = readonly [],\n const TPositions extends readonly string[] = readonly [],\n TContent = unknown,\n>(\n options: ToastPluginOptions<TVariants, TPositions, TContent>\n): ToastPluginOptions<TVariants, TPositions, TContent> {\n return options;\n}\n\n/** Declares toast variant names with full literal inference. */\nexport function toastVariants<const T extends readonly string[]>(variants: T): T {\n return variants;\n}\n\n/** Declares toast position names with full literal inference. */\nexport function toastPositions<const T extends readonly string[]>(positions: T): T {\n return positions;\n}\n","import type { ToastDuration, ToastItem, ToastPayload, ToastPosition, ToastStore } from \"./types.js\";\n\nexport interface CreateToastStoreOptions<TPositions extends readonly string[] = readonly []> {\n defaultPosition?: ToastPosition<TPositions>;\n /** Declared positions — each gets its own stack. */\n positions?: TPositions;\n defaultDuration?: number;\n maxToasts?: number;\n maxVisible?: number;\n /** Reactive store accessor — required for Alpine auto-dismiss timers. */\n getStore?: () => ToastStore<readonly [], TPositions, unknown>;\n}\n\nexport function resolveToastLimits(options: { maxToasts?: number; maxVisible?: number } = {}): {\n maxToasts: number;\n maxVisible: number;\n} {\n const maxToasts = options.maxToasts ?? 5;\n let maxVisible = options.maxVisible ?? maxToasts;\n\n if (maxToasts > 0 && maxVisible > maxToasts) {\n maxVisible = maxToasts;\n }\n\n return { maxToasts, maxVisible };\n}\n\n/** Unique stack keys: built-in default plus configured positions. */\nexport function resolveStackPositions<TPositions extends readonly string[]>(\n defaultPosition: ToastPosition<TPositions>,\n positions?: TPositions\n): readonly ToastPosition<TPositions>[] {\n const stacks: ToastPosition<TPositions>[] = [defaultPosition];\n\n for (const position of positions ?? []) {\n if (!stacks.includes(position as ToastPosition<TPositions>)) {\n stacks.push(position as ToastPosition<TPositions>);\n }\n }\n\n return stacks;\n}\n\nfunction createToastId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n\n return `toast-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n}\n\n/** Canonical persistent value — `0` is normalized to `false`. */\nexport function normalizeToastDuration(duration: ToastDuration): ToastDuration {\n if (duration === 0) {\n return false;\n }\n\n return duration;\n}\n\n/** Resolves payload duration — `false` / `0` persist; `undefined` uses the default. */\nexport function resolveToastDuration(\n duration: ToastDuration | undefined,\n defaultDuration: number\n): ToastDuration {\n if (duration === undefined) {\n return normalizeToastDuration(defaultDuration);\n }\n\n return normalizeToastDuration(duration);\n}\n\n/** Whether the toast should schedule an auto-dismiss timer. */\nexport function shouldAutoDismiss(duration: ToastDuration): duration is number {\n return typeof duration === \"number\" && duration > 0 && Number.isFinite(duration);\n}\n\n/** Persistent toasts (`duration: false` / `0`) use a separate UI stack from timed toasts. */\nexport function isPersistentDuration(duration: ToastDuration): boolean {\n return !shouldAutoDismiss(duration);\n}\n\n/**\n * Timed duration for `$toast.promise` loading state.\n * Stays in the timed stack; the timer is replaced when the promise settles.\n */\nexport const PROMISE_LOADING_DURATION = 3_600_000;\n\nfunction itemsAtPosition<\n TVariants extends readonly string[],\n TPositions extends readonly string[],\n TContent = unknown,\n>(\n items: ToastItem<TVariants, TPositions, TContent>[],\n position: ToastPosition<TPositions>\n): ToastItem<TVariants, TPositions, TContent>[] {\n return items.filter((item) => item.position === position);\n}\n\nfunction timedStackAt<\n TVariants extends readonly string[],\n TPositions extends readonly string[],\n TContent = unknown,\n>(\n items: ToastItem<TVariants, TPositions, TContent>[],\n position: ToastPosition<TPositions>\n): ToastItem<TVariants, TPositions, TContent>[] {\n return itemsAtPosition(items, position).filter((item) => shouldAutoDismiss(item.duration));\n}\n\nfunction persistentStackAt<\n TVariants extends readonly string[],\n TPositions extends readonly string[],\n TContent = unknown,\n>(\n items: ToastItem<TVariants, TPositions, TContent>[],\n position: ToastPosition<TPositions>\n): ToastItem<TVariants, TPositions, TContent>[] {\n return itemsAtPosition(items, position).filter((item) => isPersistentDuration(item.duration));\n}\n\nfunction enforcePositionLimit<\n TVariants extends readonly string[],\n TPositions extends readonly string[],\n TContent = unknown,\n>(\n items: ToastItem<TVariants, TPositions, TContent>[],\n position: ToastPosition<TPositions>,\n maxToasts: number,\n dismissMany: (ids: string[]) => void,\n stack: \"timed\" | \"persistent\"\n): void {\n if (maxToasts <= 0) {\n return;\n }\n\n const stackAtPosition =\n stack === \"persistent\" ? persistentStackAt(items, position) : timedStackAt(items, position);\n const activeAtPosition = stackAtPosition.filter((item) => !item.removed);\n const overflowIds = activeAtPosition.slice(maxToasts).map((item) => item.id);\n\n dismissMany(overflowIds);\n}\n\nfunction applyToastPatch<TPositions extends readonly string[], TContent = unknown>(\n item: ToastItem<readonly [], TPositions, TContent>,\n payload: Partial<ToastPayload<readonly [], TPositions, TContent>>\n): ToastItem<readonly [], TPositions, TContent> {\n const next = { ...item };\n\n for (const [key, value] of Object.entries(payload) as [\n keyof ToastPayload<readonly [], TPositions, TContent>,\n ToastPayload<readonly [], TPositions, TContent>[keyof ToastPayload<\n readonly [],\n TPositions,\n TContent\n >],\n ][]) {\n if (value !== undefined) {\n if (key === \"duration\") {\n Object.assign(next, { duration: normalizeToastDuration(value as ToastDuration) });\n } else {\n Object.assign(next, { [key]: value });\n }\n }\n }\n\n return next;\n}\n\n/** Creates the internal reactive toast queue consumed by `$toast` and UI integrators. */\nexport function createToastStore<\n const TPositions extends readonly string[] = readonly [],\n TContent = unknown,\n>(\n options: CreateToastStoreOptions<TPositions> = {}\n): ToastStore<readonly [], TPositions, TContent> {\n const defaultPosition = options.defaultPosition ?? \"bottom-right\";\n const stackPositions = resolveStackPositions(defaultPosition, options.positions);\n const defaultDuration = options.defaultDuration ?? 4000;\n const { maxToasts, maxVisible } = resolveToastLimits(options);\n const dismissDelayMs = 400;\n const dismissTimers = new Map<string, ReturnType<typeof setTimeout>>();\n const purgeTimers = new Map<string, ReturnType<typeof setTimeout>>();\n const getStore = options.getStore;\n\n const store: ToastStore<readonly [], TPositions, TContent> = {\n defaultPosition,\n stackPositions,\n maxToasts,\n maxVisible,\n items: [],\n\n itemsAt(position) {\n return itemsAtPosition(this.items, position);\n },\n\n timedItemsAt(position) {\n return timedStackAt(this.items, position);\n },\n\n persistentItemsAt(position) {\n return persistentStackAt(this.items, position);\n },\n\n activeTimedItemsAt(position) {\n return this.timedItemsAt(position).filter((item) => !item.removed);\n },\n\n activePersistentItemsAt(position) {\n return this.persistentItemsAt(position).filter((item) => !item.removed);\n },\n\n isVisibleAt(position, index) {\n const stack = this.timedItemsAt(position);\n const item = stack[index];\n\n if (!item || item.removed) {\n return false;\n }\n\n if (this.maxVisible <= 0) {\n return true;\n }\n\n let rank = 0;\n\n for (let i = 0; i <= index; i++) {\n if (stack[i] && !stack[i].removed) {\n rank++;\n }\n }\n\n return rank <= this.maxVisible;\n },\n\n push(payload: ToastPayload<readonly [], TPositions, TContent> = {}) {\n const position = payload.position ?? this.defaultPosition;\n const id = createToastId();\n const toast: ToastItem<readonly [], TPositions, TContent> = {\n id,\n key: payload.key ?? null,\n content: payload.content ?? null,\n title: payload.title ?? null,\n description: payload.description ?? null,\n variant: payload.variant ?? \"default\",\n position,\n duration: resolveToastDuration(payload.duration, defaultDuration),\n action: payload.action ?? null,\n removed: false,\n };\n\n this.items = [toast, ...this.items];\n enforcePositionLimit(\n this.items,\n position,\n this.maxToasts,\n (ids) => markRemoved(ids),\n shouldAutoDismiss(toast.duration) ? \"timed\" : \"persistent\"\n );\n scheduleDismiss(id, toast.duration);\n\n return id;\n },\n\n pushUnique(key, payload: ToastPayload<readonly [], TPositions, TContent> = {}) {\n const activeIds = this.items\n .filter((item) => !item.removed && item.key === key)\n .map((item) => item.id);\n\n markRemoved(activeIds);\n\n return this.push({ ...payload, key });\n },\n\n update(id, payload: Partial<ToastPayload<readonly [], TPositions, TContent>> = {}) {\n const current = this.items.find((toast) => toast.id === id);\n if (!current) {\n return;\n }\n\n const previousPosition = current.position;\n const wasPersistent = isPersistentDuration(current.duration);\n\n this.items = this.items.map((item) =>\n item.id === id ? applyToastPatch(item, payload) : item\n );\n\n const updated = this.items.find((toast) => toast.id === id);\n if (!updated) {\n return;\n }\n\n const nextPosition = updated.position;\n const isNowPersistent = isPersistentDuration(updated.duration);\n const durationStackChanged =\n payload.duration !== undefined && wasPersistent !== isNowPersistent;\n const positionChanged = nextPosition !== previousPosition;\n\n if (positionChanged) {\n enforcePositionLimit(\n this.items,\n previousPosition,\n this.maxToasts,\n (ids) => markRemoved(ids),\n \"timed\"\n );\n enforcePositionLimit(\n this.items,\n previousPosition,\n this.maxToasts,\n (ids) => markRemoved(ids),\n \"persistent\"\n );\n }\n\n if (positionChanged || durationStackChanged) {\n enforcePositionLimit(\n this.items,\n nextPosition,\n this.maxToasts,\n (ids) => markRemoved(ids),\n \"timed\"\n );\n enforcePositionLimit(\n this.items,\n nextPosition,\n this.maxToasts,\n (ids) => markRemoved(ids),\n \"persistent\"\n );\n }\n\n if (payload.duration !== undefined) {\n scheduleDismiss(id, updated.duration);\n }\n },\n\n dismiss(id) {\n markRemoved([id]);\n },\n\n dismissAt(position) {\n const ids = this.itemsAt(position)\n .filter((item) => !item.removed)\n .map((item) => item.id);\n\n markRemoved(ids);\n },\n\n dismissAll() {\n const ids = this.items.filter((item) => !item.removed).map((item) => item.id);\n\n markRemoved(ids);\n },\n\n destroy() {\n for (const timer of dismissTimers.values()) {\n clearTimeout(timer);\n }\n\n dismissTimers.clear();\n\n for (const timer of purgeTimers.values()) {\n clearTimeout(timer);\n }\n\n purgeTimers.clear();\n },\n };\n\n function clearDismissTimer(id: string): void {\n const timer = dismissTimers.get(id);\n\n if (timer !== undefined) {\n clearTimeout(timer);\n dismissTimers.delete(id);\n }\n }\n\n function markRemoved(ids: string[]): void {\n if (ids.length === 0) {\n return;\n }\n\n const activeStore = getStore?.() ?? store;\n const idsToRemove: string[] = [];\n\n for (const id of ids) {\n const toast = activeStore.items.find((item) => item.id === id);\n\n if (!toast || toast.removed) {\n continue;\n }\n\n clearDismissTimer(id);\n idsToRemove.push(id);\n }\n\n if (idsToRemove.length === 0) {\n return;\n }\n\n const removeSet = new Set(idsToRemove);\n\n activeStore.items = activeStore.items.map((item) =>\n removeSet.has(item.id) ? { ...item, removed: true } : item\n );\n\n const batchId = createToastId();\n\n const timer = setTimeout(() => {\n purgeTimers.delete(batchId);\n const storeForFilter = getStore?.() ?? store;\n storeForFilter.items = storeForFilter.items.filter((item) => !removeSet.has(item.id));\n }, dismissDelayMs);\n\n purgeTimers.set(batchId, timer);\n }\n\n function scheduleDismiss(id: string, duration: ToastDuration): void {\n clearDismissTimer(id);\n\n // Promise loading uses a sentinel duration — settled via `update`, not a timer.\n if (duration === PROMISE_LOADING_DURATION) {\n return;\n }\n\n if (shouldAutoDismiss(duration)) {\n const timer = setTimeout(() => {\n dismissTimers.delete(id);\n (getStore?.() ?? store).dismiss(id);\n }, duration);\n dismissTimers.set(id, timer);\n }\n }\n\n return store;\n}\n","import { PROMISE_LOADING_DURATION } from \"./store.js\";\nimport type {\n ResolvedToastPluginConfig,\n ToastDuration,\n ToastEventPayload,\n ToastMagic,\n ToastPayload,\n ToastPayloadWithoutVariant,\n ToastPromiseInput,\n ToastPromiseMessages,\n ToastStore,\n ToastVariant,\n} from \"./types.js\";\n\n/** Variant names that cannot override core `$toast` methods. */\nexport const RESERVED_TOAST_MAGIC_KEYS = new Set([\n \"dismiss\",\n \"update\",\n \"dismissAt\",\n \"dismissAll\",\n \"pushUnique\",\n \"fromPayload\",\n \"promise\",\n]);\n\nfunction pushToast<\n TVariants extends readonly string[],\n TPositions extends readonly string[] = readonly [],\n TContent = unknown,\n>(\n store: ToastStore<TVariants, TPositions, TContent>,\n titleOrPayload: string | ToastPayload<TVariants, TPositions, TContent>,\n options: Omit<ToastPayload<TVariants, TPositions, TContent>, \"title\"> = {}\n): string {\n if (typeof titleOrPayload === \"string\") {\n return store.push({\n title: titleOrPayload,\n ...options,\n });\n }\n\n return store.push(titleOrPayload);\n}\n\nfunction pushVariantToast<\n TVariants extends readonly string[],\n TPositions extends readonly string[] = readonly [],\n TContent = unknown,\n>(\n store: ToastStore<TVariants, TPositions, TContent>,\n variant: ToastVariant<TVariants>,\n titleOrPayload: string | ToastPayloadWithoutVariant<TVariants, TPositions, TContent>,\n options: Omit<\n ToastPayloadWithoutVariant<TVariants, TPositions, TContent>,\n \"title\" | \"content\"\n > = {}\n): string {\n if (typeof titleOrPayload === \"string\") {\n return store.push({\n title: titleOrPayload,\n ...options,\n variant,\n });\n }\n\n return store.push({\n ...titleOrPayload,\n ...options,\n variant,\n });\n}\n\nfunction resolveSuccessTitle<T>(data: T, messages: ToastPromiseMessages<T>): string | undefined {\n if (typeof messages.success === \"function\") {\n return messages.success(data);\n }\n\n return messages.success;\n}\n\nfunction resolveSuccessContent<T, TContent>(\n data: T,\n messages: ToastPromiseMessages<T, string, TContent>\n): TContent | undefined {\n const { successContent } = messages;\n\n if (typeof successContent === \"function\") {\n return (successContent as (value: T) => TContent)(data);\n }\n\n return successContent;\n}\n\nfunction resolveErrorTitle<T, V extends string = string>(\n messages: ToastPromiseMessages<T, V>,\n fallbackError: string\n): string {\n return messages.error ?? fallbackError;\n}\n\nfunction resolveToastPromise<T>(factoryOrPromise: ToastPromiseInput<T>): Promise<T> {\n if (typeof factoryOrPromise === \"function\") {\n return Promise.resolve(factoryOrPromise());\n }\n\n return Promise.resolve(factoryOrPromise);\n}\n\nfunction buildPromiseSuccessPatch<T, TContent, TVariants extends readonly string[]>(\n data: T,\n messages: ToastPromiseMessages<T, ToastVariant<TVariants>, TContent>,\n successVariant: ToastVariant<TVariants>,\n settledDuration: ToastDuration\n): Partial<ToastPayload<TVariants, readonly [], TContent>> {\n const successTitle = resolveSuccessTitle(data, messages);\n const successContent = resolveSuccessContent(data, messages);\n\n return {\n ...(successTitle !== undefined ? { title: successTitle } : {}),\n ...(successContent !== undefined ? { content: successContent } : {}),\n variant: successVariant,\n duration: settledDuration,\n };\n}\n\nfunction buildPromiseErrorPatch<T, TContent, TVariants extends readonly string[]>(\n messages: ToastPromiseMessages<T, ToastVariant<TVariants>, TContent>,\n promiseConfig: ResolvedToastPluginConfig<TVariants>[\"promise\"],\n errorVariant: ToastVariant<TVariants>,\n settledDuration: ToastDuration\n): Partial<ToastPayload<TVariants, readonly [], TContent>> {\n return {\n title: resolveErrorTitle(messages, promiseConfig.error),\n ...(messages.errorContent !== undefined ? { content: messages.errorContent } : {}),\n variant: errorVariant,\n duration: settledDuration,\n };\n}\n\n/** Builds the callable `$toast` magic API backed by the internal toast store. */\nexport function createToastMagic<\n const TVariants extends readonly string[],\n const TPositions extends readonly string[] = readonly [],\n TContent = unknown,\n>(\n config: ResolvedToastPluginConfig<TVariants, TPositions>,\n getStore: () => ToastStore<TVariants, TPositions, TContent>\n): ToastMagic<TVariants, TPositions, TContent> {\n const magic = ((\n titleOrPayload: string | ToastPayload<TVariants, TPositions, TContent>,\n options?: Omit<ToastPayload<TVariants, TPositions, TContent>, \"title\">\n ) => pushToast(getStore(), titleOrPayload, options ?? {})) as ToastMagic<\n TVariants,\n TPositions,\n TContent\n >;\n\n magic.dismiss = (id) => getStore().dismiss(id);\n magic.update = (id, payload) => getStore().update(id, payload);\n magic.dismissAt = (position) => getStore().dismissAt(position);\n magic.dismissAll = () => getStore().dismissAll();\n magic.pushUnique = (key, payload) => getStore().pushUnique(key, payload ?? {});\n\n magic.fromPayload = (payload: ToastEventPayload<TVariants, TPositions, TContent> = {}) => {\n const { title = null, content = null, variant = \"default\", ...options } = payload;\n\n return pushToast(getStore(), {\n title,\n content,\n variant,\n ...options,\n });\n };\n\n magic.promise = async <T>(\n factoryOrPromise: ToastPromiseInput<T>,\n messages: ToastPromiseMessages<T, ToastVariant<TVariants>, TContent> = {}\n ): Promise<T> => {\n const promiseConfig = config.promise;\n const loadingVariant = messages.loadingVariant ?? promiseConfig.loadingVariant;\n const successVariant = messages.successVariant ?? promiseConfig.successVariant;\n const errorVariant = messages.errorVariant ?? promiseConfig.errorVariant;\n const settledDuration = messages.duration ?? promiseConfig.duration;\n\n const id = getStore().push({\n title: messages.loading ?? promiseConfig.loading,\n content: messages.loadingContent ?? null,\n variant: loadingVariant,\n duration: PROMISE_LOADING_DURATION,\n });\n\n try {\n const data = await resolveToastPromise(factoryOrPromise);\n\n getStore().update(\n id,\n buildPromiseSuccessPatch(data, messages, successVariant, settledDuration)\n );\n\n return data;\n } catch (error) {\n getStore().update(\n id,\n buildPromiseErrorPatch(messages, promiseConfig, errorVariant, settledDuration)\n );\n\n throw error;\n }\n };\n\n for (const variant of config.variants) {\n if (RESERVED_TOAST_MAGIC_KEYS.has(variant)) {\n continue;\n }\n\n Object.assign(magic, {\n [variant]: (\n titleOrPayload: string | ToastPayloadWithoutVariant<TVariants, TPositions, TContent>,\n options: Omit<\n ToastPayloadWithoutVariant<TVariants, TPositions, TContent>,\n \"title\" | \"content\"\n > = {}\n ) =>\n pushVariantToast(getStore(), variant as ToastVariant<TVariants>, titleOrPayload, options),\n });\n }\n\n return magic;\n}\n","import type AlpineType from \"alpinejs\";\nimport { resolveToastPluginConfig } from \"./config.js\";\nimport { createToastMagic } from \"./magic.js\";\nimport { createToastStore } from \"./store.js\";\nimport type { ToastEventPayload, ToastPluginOptions, ToastStore, ToastStoreKey } from \"./types.js\";\n\nexport {\n resolveToastPluginConfig,\n toastOptions,\n toastPositions,\n toastVariants,\n} from \"./config.js\";\nexport { createToastMagic, RESERVED_TOAST_MAGIC_KEYS } from \"./magic.js\";\nexport {\n createToastStore,\n isPersistentDuration,\n normalizeToastDuration,\n PROMISE_LOADING_DURATION,\n resolveStackPositions,\n resolveToastDuration,\n resolveToastLimits,\n shouldAutoDismiss,\n} from \"./store.js\";\nexport type {\n DefaultToastPosition,\n DefaultToastVariant,\n ResolvedPromiseConfig,\n ResolvedToastPluginConfig,\n ToastAction,\n ToastDuration,\n ToastEventPayload,\n ToastItem,\n ToastMagic,\n ToastPayload,\n ToastPayloadWithoutVariant,\n ToastPluginOptions,\n ToastPosition,\n ToastPromiseInput,\n ToastPromiseMessages,\n ToastPromiseOptions,\n ToastStore,\n ToastStoreKey,\n ToastVariant,\n ToastVariantMethods,\n} from \"./types.js\";\n\nexport { TOAST_STORE_KEY } from \"./types.js\";\n\nfunction registerAlpineToastStore<TPositions extends readonly string[], TContent>(\n Alpine: AlpineType.Alpine,\n storeKey: ToastStoreKey,\n store: ToastStore<readonly [], TPositions, TContent>\n): void {\n const registerStore = Alpine.store as (name: ToastStoreKey, value: unknown) => void;\n registerStore(storeKey, store);\n}\n\nfunction getToastStore<\n TVariants extends readonly string[],\n TPositions extends readonly string[],\n TContent,\n>(Alpine: AlpineType.Alpine, storeKey: ToastStoreKey): ToastStore<TVariants, TPositions, TContent> {\n return Alpine.store(storeKey) as unknown as ToastStore<TVariants, TPositions, TContent>;\n}\n\nfunction registerToastPlugin<\n TVariants extends readonly string[],\n TPositions extends readonly string[] = readonly [],\n TContent = unknown,\n>(\n Alpine: AlpineType.Alpine,\n options: ToastPluginOptions<TVariants, TPositions, TContent> = {} as ToastPluginOptions<\n TVariants,\n TPositions,\n TContent\n >\n): void {\n const config = resolveToastPluginConfig(options);\n let reactiveStore: ToastStore<TVariants, TPositions, TContent> | undefined;\n let windowEventsAbort: AbortController | undefined;\n\n const store = createToastStore<TPositions, TContent>({\n defaultPosition: config.defaultPosition,\n positions: config.positions,\n defaultDuration: config.defaultDuration,\n maxToasts: config.maxToasts,\n maxVisible: config.maxVisible,\n getStore: (): ToastStore<readonly [], TPositions, TContent> =>\n (reactiveStore ?? store) as ToastStore<readonly [], TPositions, TContent>,\n });\n\n const baseDestroy = store.destroy.bind(store);\n\n store.destroy = () => {\n windowEventsAbort?.abort();\n windowEventsAbort = undefined;\n baseDestroy();\n };\n\n registerAlpineToastStore<TPositions, TContent>(Alpine, config.storeKey, store);\n reactiveStore = getToastStore<TVariants, TPositions, TContent>(Alpine, config.storeKey);\n const toast = createToastMagic(config, () =>\n getToastStore<TVariants, TPositions, TContent>(Alpine, config.storeKey)\n );\n Alpine.magic(\"toast\", () => toast);\n\n if (config.listenToWindowEvents && typeof window !== \"undefined\") {\n windowEventsAbort = new AbortController();\n\n window.addEventListener(\n \"toast\",\n (event) => {\n if (event instanceof CustomEvent) {\n toast.fromPayload(\n (event.detail ?? {}) as ToastEventPayload<TVariants, TPositions, TContent>\n );\n }\n },\n { signal: windowEventsAbort.signal }\n );\n }\n}\n\n/** Alpine.js toast plugin. Registers magic `$toast` with an internal reactive queue. CSS-framework agnostic — no markup or styles. */\nexport default function toastPlugin<\n const TVariants extends readonly string[] = readonly [],\n const TPositions extends readonly string[] = readonly [],\n TContent = unknown,\n>(\n optionsOrAlpine?: ToastPluginOptions<TVariants, TPositions, TContent> | AlpineType.Alpine\n): undefined | ((Alpine: AlpineType.Alpine) => void) {\n if (optionsOrAlpine && typeof (optionsOrAlpine as AlpineType.Alpine).magic === \"function\") {\n registerToastPlugin(optionsOrAlpine as AlpineType.Alpine, {});\n return;\n }\n\n const options =\n (optionsOrAlpine as ToastPluginOptions<TVariants, TPositions, TContent> | undefined) ?? {};\n\n return (Alpine: AlpineType.Alpine) => {\n registerToastPlugin(Alpine, options);\n };\n}\n\ndeclare global {\n namespace Alpine {\n interface Stores {\n toast: import(\"./types.js\").ToastStore;\n }\n interface Magics<T> {\n $toast: import(\"./types.js\").ToastMagic;\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ailuracode/alpine-toast",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Alpine.js in-app toast queue magic",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "ailuracode",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/ailuracode/alpine.git",
|
|
14
|
+
"directory": "packages/toast"
|
|
15
|
+
},
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/ailuracode/alpine/issues"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/ailuracode/alpine/tree/master/packages/toast#readme",
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"README.md"
|
|
23
|
+
],
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"default": "./dist/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./global": {
|
|
30
|
+
"types": "./dist/global.d.ts"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"types": "./dist/global.d.ts",
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"alpinejs": "^3.0.0",
|
|
36
|
+
"@types/alpinejs": "^3.13.11"
|
|
37
|
+
},
|
|
38
|
+
"peerDependenciesMeta": {
|
|
39
|
+
"@types/alpinejs": {
|
|
40
|
+
"optional": true
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"keywords": [
|
|
44
|
+
"alpinejs",
|
|
45
|
+
"alpine",
|
|
46
|
+
"plugin",
|
|
47
|
+
"toast",
|
|
48
|
+
"sonner",
|
|
49
|
+
"notifications"
|
|
50
|
+
],
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsup src/index.ts --format esm --dts --clean --sourcemap --out-dir dist && cp src/global.d.ts dist/global.d.ts",
|
|
53
|
+
"test": "vitest run --config ../../vitest.config.ts test"
|
|
54
|
+
}
|
|
55
|
+
}
|