ga-toasts 2.0.0 → 2.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/dist/index.d.cts CHANGED
@@ -3,15 +3,18 @@
3
3
  *
4
4
  * Design goals of the 2.x rewrite:
5
5
  * - Every toast owns its state (element, timer, listeners) in a registry, so
6
- * closing/updating never leaves dangling timers or crashes (v1 bug: closing
7
- * a toast before its auto-close timer fired threw on `parentNode`).
6
+ * closing/updating never leaves dangling timers or crashes.
8
7
  * - Listeners are attached through a per-toast AbortController and torn down in
9
8
  * one call — no `cloneNode` tricks.
10
- * - Messages are rendered as text by default (`html: true` to opt into markup),
11
- * closing the v1 XSS hole.
9
+ * - Messages are rendered as text by default (`html: true` to opt into markup).
12
10
  * - Screen readers are notified through a persistent `aria-live` region.
13
- * - The stacked layout is computed in JS (a single transform per toast) so the
14
- * enter/leave, swipe, stack-offset and expand-on-hover transforms never fight.
11
+ * - The stacked layout is computed in JS (a single transform per toast).
12
+ *
13
+ * Configurability (2.1): every instance is minted by `makeToaster(config)`.
14
+ * The default export `toast` is one such instance; `createToaster(config)`
15
+ * spins up isolated, independently-themed toasters (own registry, containers,
16
+ * theme, icons, defaults, mount root). Theming writes `--gat-*` custom
17
+ * properties through a per-instance scoped <style> so dark-mode rules still win.
15
18
  */
16
19
  type ToastType = 'success' | 'error' | 'warning' | 'info' | 'primary' | 'secondary' | 'loading';
17
20
  type ToastPosition = 'top-start' | 'top-center' | 'top-end' | 'middle-start' | 'middle-center' | 'middle-end' | 'bottom-start' | 'bottom-center' | 'bottom-end';
@@ -125,50 +128,120 @@ interface ToastHandle {
125
128
  update(options: Partial<ToastOptions>): ToastHandle;
126
129
  close(): void;
127
130
  }
128
- declare function injectStyles(): void;
129
- declare function show(options?: ToastOptions): ToastHandle;
130
- declare function close(target: string | HTMLElement | null | undefined): void;
131
- declare function closeAll(): void;
132
- declare function clear(type?: ToastType): void;
133
- declare function getCount(type?: ToastType): number;
134
- declare function exists(id: string): boolean;
135
- declare function get(id: string): HTMLElement | null;
136
- declare const success: (message: string, options?: ToastOptions) => ToastHandle;
137
- declare const error: (message: string, options?: ToastOptions) => ToastHandle;
138
- declare const warning: (message: string, options?: ToastOptions) => ToastHandle;
139
- declare const info: (message: string, options?: ToastOptions) => ToastHandle;
140
- declare function loading(message?: string, options?: ToastOptions): ToastHandle;
141
- declare function confirm(message: string, options?: ConfirmOptions): ToastHandle;
142
- declare function promise<T>(input: Promise<T> | (() => Promise<T>), messages: PromiseMessages<T>, options?: ToastOptions): Promise<T>;
143
- declare function setDefaults(defaults: ToastOptions): void;
144
- declare function setLogger(fn: ((event: string, payload: unknown) => void) | null): void;
145
- /** Render arbitrary content (HTML string, element, or a factory) as a toast. */
146
- declare function custom(content: NonNullable<ToastOptions['content']>, options?: ToastOptions): ToastHandle;
131
+ type PresetName = 'soft' | 'solid' | 'minimal' | 'sharp' | 'material';
132
+ /** Design tokens. Any omitted key keeps its default. Numbers → px where sensible. */
133
+ interface ThemeTokens {
134
+ /** Start from a named preset, then override with the tokens below. */
135
+ preset?: PresetName;
136
+ width?: number | string;
137
+ radius?: number | string;
138
+ gap?: number | string;
139
+ edge?: number | string;
140
+ font?: string;
141
+ /** Padding + font-size scale. */
142
+ density?: 'compact' | 'comfortable' | 'spacious';
143
+ /** Shadow depth preset. */
144
+ elevation?: 'flat' | 'raised' | 'floating';
145
+ /** Card background style. */
146
+ surface?: 'glass' | 'solid' | 'outline';
147
+ /** Width of the colored leading accent bar (0 = none). */
148
+ accentEdge?: number | string;
149
+ /** Countdown indicator style. */
150
+ progress?: 'bar' | 'ring' | 'none';
151
+ /** Primary accent (maps to the `primary` type + generic accents). */
152
+ accent?: string;
153
+ /** Per-type accent colors. */
154
+ colors?: Partial<Record<ToastType, string>>;
155
+ text?: string;
156
+ textSoft?: string;
157
+ textMuted?: string;
158
+ /** Card surface color (sets both frosted + solid tokens). */
159
+ surfaceColor?: string;
160
+ border?: string;
161
+ shadow?: string;
162
+ chip?: string;
163
+ ease?: string;
164
+ /** Token overrides applied only under the dark theme. */
165
+ dark?: Partial<ThemeTokens>;
166
+ }
167
+ interface StackConfig {
168
+ /** px each stacked card peeks out when collapsed. */
169
+ peek?: number;
170
+ /** px gap between cards when expanded. */
171
+ gap?: number;
172
+ /** per-index scale reduction when collapsed (default 0.05). */
173
+ scaleStep?: number;
174
+ /** When the stack fans out. `hover` (default), `always`, or `never`. */
175
+ expand?: 'hover' | 'always' | 'never';
176
+ /** Reverse stacking so the newest sits at the back. */
177
+ newestOnTop?: boolean;
178
+ }
179
+ interface RenderContext {
180
+ id: string;
181
+ close: () => void;
182
+ }
183
+ interface ToasterConfig {
184
+ /** Options merged into every toast (per-toast options still win). */
185
+ defaults?: ToastOptions;
186
+ /** Per-type default auto-close duration in ms. */
187
+ durations?: Partial<Record<ToastType, number>>;
188
+ /** Theme tokens or a named preset. */
189
+ theme?: ThemeTokens | PresetName;
190
+ /** Replace built-in icons (per type, `null` to hide) and/or the close icon. */
191
+ icons?: Partial<Record<ToastType, string | null>> & {
192
+ close?: string;
193
+ };
194
+ /** How many stacked toasts stay visible per position (default 3). */
195
+ maxVisible?: number;
196
+ /** Stacking geometry + behavior. */
197
+ stack?: StackConfig;
198
+ /** Replace the default toast body with your own element. */
199
+ render?: (opts: ToastOptions, ctx: RenderContext) => HTMLElement | void;
200
+ /** `false` → don't auto-inject CSS (ship your own / headless). Default true. */
201
+ injectStyles?: boolean;
202
+ /** Nonce set on the injected <style> for strict-CSP apps. */
203
+ styleNonce?: string;
204
+ /** Mount containers/live-regions/backdrop here (portals / shadow DOM). */
205
+ root?: HTMLElement | ShadowRoot;
206
+ /** Lifecycle/debug event sink. */
207
+ logger?: (event: string, payload: unknown) => void;
208
+ }
147
209
  interface ToastFn {
148
210
  (message: string, options?: ToastOptions): ToastHandle;
149
- show: typeof show;
150
- success: typeof success;
151
- error: typeof error;
152
- warning: typeof warning;
153
- info: typeof info;
154
- loading: typeof loading;
155
- confirm: typeof confirm;
156
- promise: typeof promise;
157
- custom: typeof custom;
158
- close: typeof close;
159
- closeAll: typeof closeAll;
160
- clear: typeof clear;
211
+ show: (options?: ToastOptions) => ToastHandle;
212
+ success: (message: string, options?: ToastOptions) => ToastHandle;
213
+ error: (message: string, options?: ToastOptions) => ToastHandle;
214
+ warning: (message: string, options?: ToastOptions) => ToastHandle;
215
+ info: (message: string, options?: ToastOptions) => ToastHandle;
216
+ loading: (message?: string, options?: ToastOptions) => ToastHandle;
217
+ confirm: (message: string, options?: ConfirmOptions) => ToastHandle;
218
+ promise: <T>(input: Promise<T> | (() => Promise<T>), messages: PromiseMessages<T>, options?: ToastOptions) => Promise<T>;
219
+ custom: (content: NonNullable<ToastOptions['content']>, options?: ToastOptions) => ToastHandle;
220
+ close: (target: string | HTMLElement | null | undefined) => void;
221
+ closeAll: () => void;
222
+ /** Alias of `close` — dismiss one toast by id. */
223
+ dismiss: (target: string | HTMLElement | null | undefined) => void;
224
+ /** Alias of `closeAll` — dismiss every toast. */
225
+ dismissAll: () => void;
226
+ clear: (type?: ToastType) => void;
161
227
  update: (id: string, options: Partial<ToastOptions>) => ToastHandle | null;
162
- get: typeof get;
163
- exists: typeof exists;
164
- getCount: typeof getCount;
165
- setDefaults: typeof setDefaults;
166
- setLogger: typeof setLogger;
167
- injectStyles: typeof injectStyles;
228
+ get: (id: string) => HTMLElement | null;
229
+ exists: (id: string) => boolean;
230
+ getCount: (type?: ToastType) => number;
231
+ setDefaults: (defaults: ToastOptions) => void;
232
+ setMaxVisible: (count: number) => void;
233
+ setLogger: (fn: ((event: string, payload: unknown) => void) | null) => void;
234
+ /** Configure this toaster (defaults, theme, icons, stack, headless, …). */
235
+ configure: (cfg: ToasterConfig) => ToastFn;
236
+ /** Set theme tokens or a named preset. */
237
+ theme: (tokens: ThemeTokens | PresetName) => ToastFn;
238
+ injectStyles: () => void;
168
239
  }
169
- /** Callable shorthand: `toast('Saved')`, plus `toast.success(...)` etc. */
240
+ /** Create an isolated toaster with its own theme, defaults, icons and root. */
241
+ declare function createToaster(config?: ToasterConfig): ToastFn;
242
+ /** The default, globally-shared toaster. */
170
243
  declare const toast: ToastFn;
171
244
  /** Named object API, backwards-compatible with GA Toasts 1.x. */
172
245
  declare const GaToasts: ToastFn;
173
246
 
174
- export { type ConfirmOptions, GaToasts, type PromiseMessages, type ToastAction, type ToastAnimation, type ToastFn, type ToastHandle, type ToastOptions, type ToastPosition, type ToastProgressPosition, type ToastSize, type ToastType, type ToastVariant, toast as default, toast };
247
+ export { type ConfirmOptions, GaToasts, type PresetName, type PromiseMessages, type RenderContext, type StackConfig, type ThemeTokens, type ToastAction, type ToastAnimation, type ToastFn, type ToastHandle, type ToastOptions, type ToastPosition, type ToastProgressPosition, type ToastSize, type ToastType, type ToastVariant, type ToasterConfig, createToaster, toast as default, toast };
package/dist/index.d.ts CHANGED
@@ -3,15 +3,18 @@
3
3
  *
4
4
  * Design goals of the 2.x rewrite:
5
5
  * - Every toast owns its state (element, timer, listeners) in a registry, so
6
- * closing/updating never leaves dangling timers or crashes (v1 bug: closing
7
- * a toast before its auto-close timer fired threw on `parentNode`).
6
+ * closing/updating never leaves dangling timers or crashes.
8
7
  * - Listeners are attached through a per-toast AbortController and torn down in
9
8
  * one call — no `cloneNode` tricks.
10
- * - Messages are rendered as text by default (`html: true` to opt into markup),
11
- * closing the v1 XSS hole.
9
+ * - Messages are rendered as text by default (`html: true` to opt into markup).
12
10
  * - Screen readers are notified through a persistent `aria-live` region.
13
- * - The stacked layout is computed in JS (a single transform per toast) so the
14
- * enter/leave, swipe, stack-offset and expand-on-hover transforms never fight.
11
+ * - The stacked layout is computed in JS (a single transform per toast).
12
+ *
13
+ * Configurability (2.1): every instance is minted by `makeToaster(config)`.
14
+ * The default export `toast` is one such instance; `createToaster(config)`
15
+ * spins up isolated, independently-themed toasters (own registry, containers,
16
+ * theme, icons, defaults, mount root). Theming writes `--gat-*` custom
17
+ * properties through a per-instance scoped <style> so dark-mode rules still win.
15
18
  */
16
19
  type ToastType = 'success' | 'error' | 'warning' | 'info' | 'primary' | 'secondary' | 'loading';
17
20
  type ToastPosition = 'top-start' | 'top-center' | 'top-end' | 'middle-start' | 'middle-center' | 'middle-end' | 'bottom-start' | 'bottom-center' | 'bottom-end';
@@ -125,50 +128,120 @@ interface ToastHandle {
125
128
  update(options: Partial<ToastOptions>): ToastHandle;
126
129
  close(): void;
127
130
  }
128
- declare function injectStyles(): void;
129
- declare function show(options?: ToastOptions): ToastHandle;
130
- declare function close(target: string | HTMLElement | null | undefined): void;
131
- declare function closeAll(): void;
132
- declare function clear(type?: ToastType): void;
133
- declare function getCount(type?: ToastType): number;
134
- declare function exists(id: string): boolean;
135
- declare function get(id: string): HTMLElement | null;
136
- declare const success: (message: string, options?: ToastOptions) => ToastHandle;
137
- declare const error: (message: string, options?: ToastOptions) => ToastHandle;
138
- declare const warning: (message: string, options?: ToastOptions) => ToastHandle;
139
- declare const info: (message: string, options?: ToastOptions) => ToastHandle;
140
- declare function loading(message?: string, options?: ToastOptions): ToastHandle;
141
- declare function confirm(message: string, options?: ConfirmOptions): ToastHandle;
142
- declare function promise<T>(input: Promise<T> | (() => Promise<T>), messages: PromiseMessages<T>, options?: ToastOptions): Promise<T>;
143
- declare function setDefaults(defaults: ToastOptions): void;
144
- declare function setLogger(fn: ((event: string, payload: unknown) => void) | null): void;
145
- /** Render arbitrary content (HTML string, element, or a factory) as a toast. */
146
- declare function custom(content: NonNullable<ToastOptions['content']>, options?: ToastOptions): ToastHandle;
131
+ type PresetName = 'soft' | 'solid' | 'minimal' | 'sharp' | 'material';
132
+ /** Design tokens. Any omitted key keeps its default. Numbers → px where sensible. */
133
+ interface ThemeTokens {
134
+ /** Start from a named preset, then override with the tokens below. */
135
+ preset?: PresetName;
136
+ width?: number | string;
137
+ radius?: number | string;
138
+ gap?: number | string;
139
+ edge?: number | string;
140
+ font?: string;
141
+ /** Padding + font-size scale. */
142
+ density?: 'compact' | 'comfortable' | 'spacious';
143
+ /** Shadow depth preset. */
144
+ elevation?: 'flat' | 'raised' | 'floating';
145
+ /** Card background style. */
146
+ surface?: 'glass' | 'solid' | 'outline';
147
+ /** Width of the colored leading accent bar (0 = none). */
148
+ accentEdge?: number | string;
149
+ /** Countdown indicator style. */
150
+ progress?: 'bar' | 'ring' | 'none';
151
+ /** Primary accent (maps to the `primary` type + generic accents). */
152
+ accent?: string;
153
+ /** Per-type accent colors. */
154
+ colors?: Partial<Record<ToastType, string>>;
155
+ text?: string;
156
+ textSoft?: string;
157
+ textMuted?: string;
158
+ /** Card surface color (sets both frosted + solid tokens). */
159
+ surfaceColor?: string;
160
+ border?: string;
161
+ shadow?: string;
162
+ chip?: string;
163
+ ease?: string;
164
+ /** Token overrides applied only under the dark theme. */
165
+ dark?: Partial<ThemeTokens>;
166
+ }
167
+ interface StackConfig {
168
+ /** px each stacked card peeks out when collapsed. */
169
+ peek?: number;
170
+ /** px gap between cards when expanded. */
171
+ gap?: number;
172
+ /** per-index scale reduction when collapsed (default 0.05). */
173
+ scaleStep?: number;
174
+ /** When the stack fans out. `hover` (default), `always`, or `never`. */
175
+ expand?: 'hover' | 'always' | 'never';
176
+ /** Reverse stacking so the newest sits at the back. */
177
+ newestOnTop?: boolean;
178
+ }
179
+ interface RenderContext {
180
+ id: string;
181
+ close: () => void;
182
+ }
183
+ interface ToasterConfig {
184
+ /** Options merged into every toast (per-toast options still win). */
185
+ defaults?: ToastOptions;
186
+ /** Per-type default auto-close duration in ms. */
187
+ durations?: Partial<Record<ToastType, number>>;
188
+ /** Theme tokens or a named preset. */
189
+ theme?: ThemeTokens | PresetName;
190
+ /** Replace built-in icons (per type, `null` to hide) and/or the close icon. */
191
+ icons?: Partial<Record<ToastType, string | null>> & {
192
+ close?: string;
193
+ };
194
+ /** How many stacked toasts stay visible per position (default 3). */
195
+ maxVisible?: number;
196
+ /** Stacking geometry + behavior. */
197
+ stack?: StackConfig;
198
+ /** Replace the default toast body with your own element. */
199
+ render?: (opts: ToastOptions, ctx: RenderContext) => HTMLElement | void;
200
+ /** `false` → don't auto-inject CSS (ship your own / headless). Default true. */
201
+ injectStyles?: boolean;
202
+ /** Nonce set on the injected <style> for strict-CSP apps. */
203
+ styleNonce?: string;
204
+ /** Mount containers/live-regions/backdrop here (portals / shadow DOM). */
205
+ root?: HTMLElement | ShadowRoot;
206
+ /** Lifecycle/debug event sink. */
207
+ logger?: (event: string, payload: unknown) => void;
208
+ }
147
209
  interface ToastFn {
148
210
  (message: string, options?: ToastOptions): ToastHandle;
149
- show: typeof show;
150
- success: typeof success;
151
- error: typeof error;
152
- warning: typeof warning;
153
- info: typeof info;
154
- loading: typeof loading;
155
- confirm: typeof confirm;
156
- promise: typeof promise;
157
- custom: typeof custom;
158
- close: typeof close;
159
- closeAll: typeof closeAll;
160
- clear: typeof clear;
211
+ show: (options?: ToastOptions) => ToastHandle;
212
+ success: (message: string, options?: ToastOptions) => ToastHandle;
213
+ error: (message: string, options?: ToastOptions) => ToastHandle;
214
+ warning: (message: string, options?: ToastOptions) => ToastHandle;
215
+ info: (message: string, options?: ToastOptions) => ToastHandle;
216
+ loading: (message?: string, options?: ToastOptions) => ToastHandle;
217
+ confirm: (message: string, options?: ConfirmOptions) => ToastHandle;
218
+ promise: <T>(input: Promise<T> | (() => Promise<T>), messages: PromiseMessages<T>, options?: ToastOptions) => Promise<T>;
219
+ custom: (content: NonNullable<ToastOptions['content']>, options?: ToastOptions) => ToastHandle;
220
+ close: (target: string | HTMLElement | null | undefined) => void;
221
+ closeAll: () => void;
222
+ /** Alias of `close` — dismiss one toast by id. */
223
+ dismiss: (target: string | HTMLElement | null | undefined) => void;
224
+ /** Alias of `closeAll` — dismiss every toast. */
225
+ dismissAll: () => void;
226
+ clear: (type?: ToastType) => void;
161
227
  update: (id: string, options: Partial<ToastOptions>) => ToastHandle | null;
162
- get: typeof get;
163
- exists: typeof exists;
164
- getCount: typeof getCount;
165
- setDefaults: typeof setDefaults;
166
- setLogger: typeof setLogger;
167
- injectStyles: typeof injectStyles;
228
+ get: (id: string) => HTMLElement | null;
229
+ exists: (id: string) => boolean;
230
+ getCount: (type?: ToastType) => number;
231
+ setDefaults: (defaults: ToastOptions) => void;
232
+ setMaxVisible: (count: number) => void;
233
+ setLogger: (fn: ((event: string, payload: unknown) => void) | null) => void;
234
+ /** Configure this toaster (defaults, theme, icons, stack, headless, …). */
235
+ configure: (cfg: ToasterConfig) => ToastFn;
236
+ /** Set theme tokens or a named preset. */
237
+ theme: (tokens: ThemeTokens | PresetName) => ToastFn;
238
+ injectStyles: () => void;
168
239
  }
169
- /** Callable shorthand: `toast('Saved')`, plus `toast.success(...)` etc. */
240
+ /** Create an isolated toaster with its own theme, defaults, icons and root. */
241
+ declare function createToaster(config?: ToasterConfig): ToastFn;
242
+ /** The default, globally-shared toaster. */
170
243
  declare const toast: ToastFn;
171
244
  /** Named object API, backwards-compatible with GA Toasts 1.x. */
172
245
  declare const GaToasts: ToastFn;
173
246
 
174
- export { type ConfirmOptions, GaToasts, type PromiseMessages, type ToastAction, type ToastAnimation, type ToastFn, type ToastHandle, type ToastOptions, type ToastPosition, type ToastProgressPosition, type ToastSize, type ToastType, type ToastVariant, toast as default, toast };
247
+ export { type ConfirmOptions, GaToasts, type PresetName, type PromiseMessages, type RenderContext, type StackConfig, type ThemeTokens, type ToastAction, type ToastAnimation, type ToastFn, type ToastHandle, type ToastOptions, type ToastPosition, type ToastProgressPosition, type ToastSize, type ToastType, type ToastVariant, type ToasterConfig, createToaster, toast as default, toast };