kerfjs 4.4.0 → 5.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/LICENSE +1 -1
  3. package/README.md +34 -35
  4. package/ai/cursorrules +46 -1
  5. package/ai/manifest.json +62 -5
  6. package/ai/skill.md +53 -2
  7. package/dist/actions.d.ts +1 -1
  8. package/dist/actions.js +4 -4
  9. package/dist/actions.js.map +1 -1
  10. package/dist/array-signal.js +5 -5
  11. package/dist/async.js +17 -10
  12. package/dist/async.js.map +1 -1
  13. package/dist/attach.d.ts +11 -8
  14. package/dist/attach.js +52 -4
  15. package/dist/attach.js.map +1 -1
  16. package/dist/chunk-GY4XV2UV.js +1 -1
  17. package/dist/{chunk-VVDJLWMP.js → chunk-HW7KSM2Y.js} +2 -2
  18. package/dist/chunk-HW7KSM2Y.js.map +1 -0
  19. package/dist/{chunk-KEZTD6H4.js → chunk-KPXIOG2C.js} +3 -3
  20. package/dist/{chunk-KEZTD6H4.js.map → chunk-KPXIOG2C.js.map} +1 -1
  21. package/dist/{chunk-SAYPJ6XR.js → chunk-KZJXHFIB.js} +10 -6
  22. package/dist/chunk-KZJXHFIB.js.map +1 -0
  23. package/dist/{chunk-MRYM3O3V.js → chunk-LVH3GC6B.js} +11 -8
  24. package/dist/chunk-LVH3GC6B.js.map +1 -0
  25. package/dist/chunk-QIP723L4.js +1 -1
  26. package/dist/{chunk-SRWQKB33.js → chunk-SVATPF5R.js} +97 -74
  27. package/dist/chunk-SVATPF5R.js.map +1 -0
  28. package/dist/{chunk-3APBEVHF.js → chunk-U6FK33SG.js} +3 -3
  29. package/dist/{chunk-3APBEVHF.js.map → chunk-U6FK33SG.js.map} +1 -1
  30. package/dist/{chunk-U32TFTGZ.js → chunk-UZJ6I4T6.js} +3 -3
  31. package/dist/chunk-UZJ6I4T6.js.map +1 -0
  32. package/dist/{chunk-YHH7OUFA.js → chunk-V46JKE44.js} +3 -3
  33. package/dist/chunk-V46JKE44.js.map +1 -0
  34. package/dist/{chunk-SUPUPSBE.js → chunk-ZDCJZCNO.js} +9 -8
  35. package/dist/chunk-ZDCJZCNO.js.map +1 -0
  36. package/dist/dev.d.ts +9 -6
  37. package/dist/dev.js +5 -5
  38. package/dist/dev.js.map +1 -1
  39. package/dist/html.d.ts +1 -1
  40. package/dist/html.js +5 -5
  41. package/dist/html.js.map +1 -1
  42. package/dist/index.d.ts +1 -1
  43. package/dist/index.js +11 -11
  44. package/dist/jsx-runtime.js +5 -5
  45. package/dist/list.d.ts +1 -1
  46. package/dist/list.js +273 -211
  47. package/dist/list.js.map +1 -1
  48. package/dist/overlay.d.ts +190 -280
  49. package/dist/overlay.js +401 -361
  50. package/dist/overlay.js.map +1 -1
  51. package/dist/remount.d.ts +5 -3
  52. package/dist/remount.js +29 -10
  53. package/dist/remount.js.map +1 -1
  54. package/dist/router.d.ts +1 -1
  55. package/dist/router.js +44 -22
  56. package/dist/router.js.map +1 -1
  57. package/dist/scope.d.ts +4 -3
  58. package/dist/scope.js +10 -10
  59. package/dist/scope.js.map +1 -1
  60. package/dist/testing.js +4 -4
  61. package/dist/timing.d.ts +3 -2
  62. package/dist/timing.js +5 -5
  63. package/dist/timing.js.map +1 -1
  64. package/llms.txt +7 -4
  65. package/package.json +12 -10
  66. package/dist/chunk-MRYM3O3V.js.map +0 -1
  67. package/dist/chunk-SAYPJ6XR.js.map +0 -1
  68. package/dist/chunk-SRWQKB33.js.map +0 -1
  69. package/dist/chunk-SUPUPSBE.js.map +0 -1
  70. package/dist/chunk-U32TFTGZ.js.map +0 -1
  71. package/dist/chunk-VVDJLWMP.js.map +0 -1
  72. package/dist/chunk-YHH7OUFA.js.map +0 -1
  73. /package/dist/{attrSelector-Cmu2ZoGO.d.ts → attr-Cmu2ZoGO.d.ts} +0 -0
package/dist/overlay.d.ts CHANGED
@@ -40,285 +40,7 @@ declare function positionAnchored(el: HTMLElement, anchor: Element, options?: An
40
40
  declare function autoReposition(el: HTMLElement, anchor: Element, options?: AnchorPositionOptions): () => void;
41
41
 
42
42
  /**
43
- * Wiring slots passed to a {@link ConfirmOptions.render} — spread `ok` / `cancel`
44
- * onto your own clickable elements so `confirm()` still resolves them (they are
45
- * `data-confirm` attribute bags). `message` is the raw message (escape it by
46
- * interpolating through JSX).
47
- */
48
- interface ConfirmRenderSlots {
49
- message: string;
50
- /** Spread onto the confirm control. */
51
- ok: Record<string, string>;
52
- /** Spread onto the cancel control. */
53
- cancel: Record<string, string>;
54
- }
55
- /** Options for {@link confirm}. */
56
- interface ConfirmOptions {
57
- /** Where to append the overlay. Default `document.body`. */
58
- container?: Element;
59
- /** Wrapper class. Default `'kerf-overlay'`. */
60
- className?: string;
61
- /** Optional heading above the message. */
62
- title?: string;
63
- /** Confirm button label. Default `'OK'`. */
64
- okText?: string;
65
- /** Cancel button label. Default `'Cancel'`. */
66
- cancelText?: string;
67
- /** Add a `kerf-confirm--danger` class to the wrapper for destructive actions. */
68
- danger?: boolean;
69
- /** Host the dialog in the browser top layer (`<dialog>.showModal()`) where supported. See {@link OverlayOptions.native}. */
70
- native?: boolean;
71
- /**
72
- * Bring your own markup (design-system dialogs): return the full dialog body,
73
- * spreading the provided `ok`/`cancel` wiring onto your buttons. Overrides the
74
- * default two-button markup; `confirm()` keeps owning dismiss / focus-trap /
75
- * focus-restore and still resolves `true`/`false` for OK/Cancel/dismissal.
76
- */
77
- render?: (slots: ConfirmRenderSlots) => OverlayContent;
78
- }
79
- /**
80
- * A promise-based `window.confirm` replacement (that global is a no-op in Tauri
81
- * webviews). Renders a two-button dialog and resolves `true` for OK, `false`
82
- * for Cancel or any dismissal (Escape / backdrop). Message + labels are
83
- * auto-escaped (rendered through the JSX runtime). Pass `render` for your own markup.
84
- */
85
- declare function confirm(message: string, options?: ConfirmOptions): Promise<boolean>;
86
- /**
87
- * Validate a single field's value. Return a non-empty error string to BLOCK
88
- * submission (shown inline next to the field); return `undefined`/`null`/`''` to
89
- * allow it.
90
- */
91
- type FieldValidator = (value: string) => string | null | undefined | void;
92
- /** Options for {@link prompt}. */
93
- interface PromptOptions {
94
- /** Where to append the overlay. Default `document.body`. */
95
- container?: Element;
96
- /** Wrapper class. Default `'kerf-overlay'`. */
97
- className?: string;
98
- /** Optional heading above the message. */
99
- title?: string;
100
- /** Pre-filled input value. Default `''`. */
101
- defaultValue?: string;
102
- /** Input placeholder. */
103
- placeholder?: string;
104
- /** `type` attribute of the input (`'text'`, `'email'`, `'password'`, …). Default `'text'`. */
105
- inputType?: string;
106
- /** Confirm button label. Default `'OK'`. */
107
- okText?: string;
108
- /** Cancel button label. Default `'Cancel'`. */
109
- cancelText?: string;
110
- /** Block OK while this returns an error string; the message shows inline. */
111
- validate?: FieldValidator;
112
- /** Host the dialog in the browser top layer (`<dialog>.showModal()`) where supported. See {@link OverlayOptions.native}. */
113
- native?: boolean;
114
- /**
115
- * Bring your own markup: return the full dialog body, spreading the provided
116
- * `input` (the text field), `ok`/`cancel` (buttons), and optional `error` (the
117
- * inline-error slot) wiring. `prompt()` still reads the input, runs `validate`,
118
- * submits on Enter, and owns dismiss / focus. If you omit the `error` slot,
119
- * `validate` simply re-focuses the input without an inline message.
120
- */
121
- render?: (slots: PromptRenderSlots) => OverlayContent;
122
- }
123
- /** Wiring slots for a {@link PromptOptions.render} — spread each onto your own markup. */
124
- interface PromptRenderSlots {
125
- message: string;
126
- /** Spread onto your `<input>` — carries the marker, `type`, `value`, and `placeholder`. */
127
- input: Record<string, string>;
128
- /** Spread onto your inline-error element (optional). */
129
- error: Record<string, string>;
130
- /** Spread onto the confirm control. */
131
- ok: Record<string, string>;
132
- /** Spread onto the cancel control. */
133
- cancel: Record<string, string>;
134
- }
135
- /**
136
- * A promise-based `window.prompt` replacement (that global is a no-op in Tauri
137
- * webviews). Renders a one-field dialog and resolves the entered **string** on OK
138
- * (an empty string is a valid result) or `null` on Cancel / dismissal. Enter in
139
- * the input submits. `message`, the default value, and labels are auto-escaped
140
- * (rendered through the JSX runtime). Optional `validate` blocks OK inline. Pass
141
- * `render` for your own markup.
142
- */
143
- declare function prompt(message: string, options?: PromptOptions): Promise<string | null>;
144
- /** A single field in a {@link form}. */
145
- interface FormField {
146
- /** Field name — the key in the resolved record (and the input's `name`). */
147
- name: string;
148
- /** Label shown above the input. Defaults to `name`. */
149
- label?: string;
150
- /** Pre-filled value. Default `''`. */
151
- defaultValue?: string;
152
- /** Input placeholder. */
153
- placeholder?: string;
154
- /** `type` attribute of the input. Default `'text'`. */
155
- type?: string;
156
- /** Block OK while this returns an error string; the message shows inline for this field. */
157
- validate?: FieldValidator;
158
- }
159
- /** One field's wiring in a {@link FormRenderSlots} — spread `input`/`error` onto your markup. */
160
- interface FormRenderField {
161
- name: string;
162
- label: string;
163
- /** Spread onto your `<input>` — carries the marker, `name`, `type`, `value`, `placeholder`. */
164
- input: Record<string, string>;
165
- /** Spread onto your inline-error element (optional). */
166
- error: Record<string, string>;
167
- }
168
- /** Wiring slots for a {@link FormOptions.render}. */
169
- interface FormRenderSlots {
170
- fields: FormRenderField[];
171
- /** Spread onto the confirm control. */
172
- ok: Record<string, string>;
173
- /** Spread onto the cancel control. */
174
- cancel: Record<string, string>;
175
- }
176
- /** Options for {@link form}. */
177
- interface FormOptions {
178
- /** Where to append the overlay. Default `document.body`. */
179
- container?: Element;
180
- /** Wrapper class. Default `'kerf-overlay'`. */
181
- className?: string;
182
- /** Optional heading above the fields. */
183
- title?: string;
184
- /** Confirm button label. Default `'OK'`. */
185
- okText?: string;
186
- /** Cancel button label. Default `'Cancel'`. */
187
- cancelText?: string;
188
- /** Host the dialog in the browser top layer (`<dialog>.showModal()`) where supported. See {@link OverlayOptions.native}. */
189
- native?: boolean;
190
- /**
191
- * Bring your own markup: return the full form body, laying out `slots.fields`
192
- * (each with `input`/`error` wiring to spread) and the `ok`/`cancel` buttons.
193
- * `form()` still reads each input, runs per-field `validate`, focuses the first
194
- * invalid field, submits on Enter, and owns dismiss / focus. Omit a field's
195
- * `error` slot to skip its inline message.
196
- */
197
- render?: (slots: FormRenderSlots) => OverlayContent;
198
- }
199
- /**
200
- * A promise-based multi-field dialog — the two-or-three-input sibling of
201
- * {@link prompt}. Renders one labeled input per {@link FormField} and resolves a
202
- * `Record<name, value>` on OK (after every field's `validate` passes) or `null`
203
- * on Cancel / dismissal. Enter in any field submits. All labels, defaults, and
204
- * the title are auto-escaped through the JSX runtime.
205
- */
206
- declare function form(fields: readonly FormField[], options?: FormOptions): Promise<Record<string, string> | null>;
207
- /** One choosable action in a {@link choice} dialog. */
208
- interface ChoiceAction<R> {
209
- /** The value this action resolves. */
210
- value: R;
211
- /** Button label (auto-escaped). */
212
- label: string;
213
- /** Extra class on this action's button. */
214
- className?: string;
215
- }
216
- /** Wiring slots for a {@link ChoiceOptions.render} — spread `actions[i]` onto your i-th button. */
217
- interface ChoiceRenderSlots {
218
- message: string;
219
- /** One attribute bag per action (in order) — spread onto that action's control. */
220
- actions: Array<Record<string, string>>;
221
- }
222
- /** Options for {@link choice}. */
223
- interface ChoiceOptions<R> {
224
- /** Where to append the overlay. Default `document.body`. */
225
- container?: Element;
226
- /** Wrapper class. Default `'kerf-overlay'`. */
227
- className?: string;
228
- /** Optional heading above the message. */
229
- title?: string;
230
- /** The value resolved when **Enter** is pressed anywhere in the dialog (the default action). */
231
- defaultValue?: R;
232
- /** Host the dialog in the browser top layer (`<dialog>.showModal()`) where supported. See {@link OverlayOptions.native}. */
233
- native?: boolean;
234
- /** Bring your own markup: return the full body, spreading each `slots.actions[i]` onto your buttons. */
235
- render?: (slots: ChoiceRenderSlots) => OverlayContent;
236
- }
237
- /**
238
- * The **N-way** sibling of {@link confirm}: renders one button per {@link ChoiceAction}
239
- * and resolves that action's `value` on click, or `null` on Cancel / dismissal.
240
- * Pass `defaultValue` to make **Enter** (anywhere in the dialog) resolve a default
241
- * action — the "global Enter-to-confirm" model — without you having to hold the
242
- * overlay handle. `message` + labels are auto-escaped; pass `render` for your own
243
- * markup. kerf owns dismiss / focus-trap / focus-restore. For fully bespoke
244
- * keyboard/close control, drive {@link overlay} directly.
245
- */
246
- declare function choice<R>(message: string, actions: ReadonlyArray<ChoiceAction<R>>, options?: ChoiceOptions<R>): Promise<R | null>;
247
-
248
- /**
249
- * `toast()` for `kerfjs/overlay` — a non-modal, auto-dismissing notification that
250
- * stacks in a shared body-level region. Split out of `overlay.ts` (KF-513) since
251
- * it's a distinct transient-UI concern from the modal dialogs; re-exported from
252
- * `overlay.ts` so the public `kerfjs/overlay` surface is unchanged. Structural
253
- * only — kerf ships no CSS; you style the region / toast / animations.
254
- */
255
-
256
- /** Content for a {@link toast}: text, `SafeHtml`, or a render function. */
257
- type ToastContent = string | SafeHtml | (() => MountResult);
258
- /** Accent variant for a {@link toast} — mapped to a `${className}--${variant}` class. */
259
- type ToastVariant = 'info' | 'success' | 'warning';
260
- /** Options for {@link toast}. */
261
- interface ToastOptions {
262
- /** Where toasts stack. Default: a lazily-created `<div class="kerf-toasts">` on `document.body`. */
263
- container?: Element;
264
- /** Class on the toast element. Default `'kerf-toast'`. */
265
- className?: string;
266
- /** Auto-dismiss after this many ms. `0` keeps it until dismissed by hand. Default `4000`. */
267
- duration?: number;
268
- /** ARIA role. Default `'status'`. */
269
- role?: string;
270
- /**
271
- * `'stack'` (default) shows toasts stacked in the region; `'replace'` dismisses
272
- * the region's current toast(s) first (collapse-to-latest for a rapid sequence).
273
- */
274
- mode?: 'stack' | 'replace';
275
- /**
276
- * How `mode: 'replace'` drops the prior toast(s): `'fade'` (default) runs their
277
- * full exit transition (nice for a STACKING region), or `'instant'` removes them
278
- * synchronously with no exit — what a single, exactly-centered toast slot wants,
279
- * so the outgoing and incoming messages never cross-fade in the same spot.
280
- */
281
- collapse?: 'fade' | 'instant';
282
- /** Accent variant — adds a `${className}--${variant}` class (kerf ships no CSS; you style it). */
283
- variant?: ToastVariant;
284
- /** Class added on the next animation frame after mount, so a CSS **entrance** transition can run. */
285
- enterClass?: string;
286
- /**
287
- * Class added when dismissing, so CSS owns the **exit**. On dismiss the
288
- * `enterClass` (if any) is also REMOVED, so `exitClass` doesn't have to
289
- * out-specify it — and a symmetric single-class fade (entrance = add
290
- * `enterClass`, exit = remove it) works by setting only `enterClass` +
291
- * `exitDuration`. The node is removed `exitDuration` ms later.
292
- */
293
- exitClass?: string;
294
- /** ms to wait before removing the node on dismiss — applies when `exitClass` is set OR when it's > 0 (to let a removed `enterClass` transition out). Default `0`. */
295
- exitDuration?: number;
296
- }
297
- /** Handle returned by {@link toast}. */
298
- interface ToastHandle {
299
- /** The toast element — inspect it, or run your own entrance/exit transitions. */
300
- el: HTMLElement;
301
- /**
302
- * Dismiss it early. Default runs the `exitClass` transition (removed after
303
- * `exitDuration`); pass `{ instant: true }` to remove it **synchronously** with
304
- * no exit — for an action button that immediately shows a replacement toast in a
305
- * single centered slot (no cross-fade). Idempotent.
306
- */
307
- dismiss(options?: {
308
- instant?: boolean;
309
- }): void;
310
- }
311
- /**
312
- * Show a non-modal, auto-dismissing notification. Stacks in a shared body-level
313
- * region (or your `container`). Returns a {@link ToastHandle} (`{ el, dismiss }`)
314
- * so you can run entrance/exit transitions, wire an action button, or inspect the
315
- * node. `mode: 'replace'` collapses a rapid sequence to the latest; `variant`
316
- * adds an accent class; `enterClass`/`exitClass` let CSS own the animation.
317
- */
318
- declare function toast(content: ToastContent, options?: ToastOptions): ToastHandle;
319
-
320
- /**
321
- * `kerfjs/overlay` — the modal / overlay + dismiss manager.
43
+ * Internal overlay / popover / tooltip lifecycle implementation.
322
44
  *
323
45
  * Every real kerf app hand-rolls this: `toElement → body.appendChild → mount →
324
46
  * wire dismissal → remove`, plus the fiddly parts (Escape, backdrop / outside
@@ -403,7 +125,8 @@ interface OverlayHandle {
403
125
  /**
404
126
  * Open an overlay: append a wrapper to `container`, `mount()` `content` inside
405
127
  * it, wire the requested dismissals + (optionally) a focus trap, and return a
406
- * handle. See {@link OverlayOptions}.
128
+ * handle. Concurrent fallback overlays dismiss from the top down. See
129
+ * {@link OverlayOptions}.
407
130
  */
408
131
  declare function overlay(content: OverlayContent, options?: OverlayOptions): OverlayHandle;
409
132
 
@@ -476,4 +199,191 @@ interface TooltipOptions extends AnchorPositionOptions {
476
199
  */
477
200
  declare function tooltip(anchor: Element, content: TooltipContent, options?: TooltipOptions): () => void;
478
201
 
202
+ /** One choosable action in a {@link choice} dialog. */
203
+ interface ChoiceAction<R> {
204
+ value: R;
205
+ label: string;
206
+ className?: string;
207
+ }
208
+ /** Wiring slots for a {@link ChoiceOptions.render}. */
209
+ interface ChoiceRenderSlots {
210
+ message: string;
211
+ actions: Array<Record<string, string>>;
212
+ }
213
+ /** Options for {@link choice}. */
214
+ interface ChoiceOptions<R> {
215
+ container?: Element;
216
+ className?: string;
217
+ title?: string;
218
+ defaultValue?: R;
219
+ native?: boolean;
220
+ render?: (slots: ChoiceRenderSlots) => OverlayContent;
221
+ }
222
+ /** The N-way sibling of {@link confirm}. */
223
+ declare function choice<R>(message: string, actions: ReadonlyArray<ChoiceAction<R>>, options?: ChoiceOptions<R>): Promise<R | null>;
224
+
225
+ /** Wiring slots passed to a {@link ConfirmOptions.render}. */
226
+ interface ConfirmRenderSlots {
227
+ message: string;
228
+ /** Spread onto the confirm control. */
229
+ ok: Record<string, string>;
230
+ /** Spread onto the cancel control. */
231
+ cancel: Record<string, string>;
232
+ }
233
+ /** Options for {@link confirm}. */
234
+ interface ConfirmOptions {
235
+ /** Where to append the overlay. Default `document.body`. */
236
+ container?: Element;
237
+ /** Wrapper class. Default `'kerf-overlay'`. */
238
+ className?: string;
239
+ /** Optional heading above the message. */
240
+ title?: string;
241
+ /** Confirm button label. Default `'OK'`. */
242
+ okText?: string;
243
+ /** Cancel button label. Default `'Cancel'`. */
244
+ cancelText?: string;
245
+ /** Add a `kerf-confirm--danger` class to the wrapper for destructive actions. */
246
+ danger?: boolean;
247
+ /** Host the dialog in the browser top layer where supported. */
248
+ native?: boolean;
249
+ /** Bring your own body while retaining kerf's dialog wiring. */
250
+ render?: (slots: ConfirmRenderSlots) => OverlayContent;
251
+ }
252
+ /** A promise-based `window.confirm` replacement. */
253
+ declare function confirm(message: string, options?: ConfirmOptions): Promise<boolean>;
254
+
255
+ /** Validate a single field's value. */
256
+ type FieldValidator = (value: string) => string | null | undefined | void;
257
+ /** Options for {@link prompt}. */
258
+ interface PromptOptions {
259
+ container?: Element;
260
+ className?: string;
261
+ title?: string;
262
+ defaultValue?: string;
263
+ placeholder?: string;
264
+ inputType?: string;
265
+ okText?: string;
266
+ cancelText?: string;
267
+ validate?: FieldValidator;
268
+ native?: boolean;
269
+ render?: (slots: PromptRenderSlots) => OverlayContent;
270
+ }
271
+ /** Wiring slots for a {@link PromptOptions.render}. */
272
+ interface PromptRenderSlots {
273
+ message: string;
274
+ input: Record<string, string>;
275
+ error: Record<string, string>;
276
+ ok: Record<string, string>;
277
+ cancel: Record<string, string>;
278
+ }
279
+ /** A promise-based `window.prompt` replacement. */
280
+ declare function prompt(message: string, options?: PromptOptions): Promise<string | null>;
281
+
282
+ /** A single field in a {@link form}. */
283
+ interface FormField {
284
+ name: string;
285
+ label?: string;
286
+ defaultValue?: string;
287
+ placeholder?: string;
288
+ type?: string;
289
+ validate?: FieldValidator;
290
+ }
291
+ /** One field's wiring in a {@link FormRenderSlots}. */
292
+ interface FormRenderField {
293
+ name: string;
294
+ label: string;
295
+ input: Record<string, string>;
296
+ error: Record<string, string>;
297
+ }
298
+ /** Wiring slots for a {@link FormOptions.render}. */
299
+ interface FormRenderSlots {
300
+ fields: FormRenderField[];
301
+ ok: Record<string, string>;
302
+ cancel: Record<string, string>;
303
+ }
304
+ /** Options for {@link form}. */
305
+ interface FormOptions {
306
+ container?: Element;
307
+ className?: string;
308
+ title?: string;
309
+ okText?: string;
310
+ cancelText?: string;
311
+ native?: boolean;
312
+ render?: (slots: FormRenderSlots) => OverlayContent;
313
+ }
314
+ /** A promise-based multi-field dialog. */
315
+ declare function form(fields: readonly FormField[], options?: FormOptions): Promise<Record<string, string> | null>;
316
+
317
+ /**
318
+ * `toast()` for `kerfjs/overlay` — a non-modal, auto-dismissing notification that
319
+ * stacks in a shared body-level region. Split out of `overlay.ts` (KF-513) since
320
+ * it's a distinct transient-UI concern from the modal dialogs; re-exported from
321
+ * `overlay.ts` so the public `kerfjs/overlay` surface is unchanged. Structural
322
+ * only — kerf ships no CSS; you style the region / toast / animations.
323
+ */
324
+
325
+ /** Content for a {@link toast}: an escaped text string, trusted `SafeHtml`, or a render function. */
326
+ type ToastContent = string | SafeHtml | (() => MountResult);
327
+ /** Accent variant for a {@link toast} — mapped to a `${className}--${variant}` class. */
328
+ type ToastVariant = 'info' | 'success' | 'warning';
329
+ /** Options for {@link toast}. */
330
+ interface ToastOptions {
331
+ /** Where toasts stack. Default: a lazily-created `<div class="kerf-toasts">` on `document.body`. */
332
+ container?: Element;
333
+ /** Class on the toast element. Default `'kerf-toast'`. */
334
+ className?: string;
335
+ /** Auto-dismiss after this many ms. `0` keeps it until dismissed by hand. Default `4000`. */
336
+ duration?: number;
337
+ /** ARIA role. Default `'status'`. */
338
+ role?: string;
339
+ /**
340
+ * `'stack'` (default) shows toasts stacked in the region; `'replace'` dismisses
341
+ * the region's current toast(s) first (collapse-to-latest for a rapid sequence).
342
+ */
343
+ mode?: 'stack' | 'replace';
344
+ /**
345
+ * How `mode: 'replace'` drops the prior toast(s): `'fade'` (default) runs their
346
+ * full exit transition (nice for a STACKING region), or `'instant'` removes them
347
+ * synchronously with no exit — what a single, exactly-centered toast slot wants,
348
+ * so the outgoing and incoming messages never cross-fade in the same spot.
349
+ */
350
+ collapse?: 'fade' | 'instant';
351
+ /** Accent variant — adds a `${className}--${variant}` class (kerf ships no CSS; you style it). */
352
+ variant?: ToastVariant;
353
+ /** Class added on the next animation frame after mount, so a CSS **entrance** transition can run. */
354
+ enterClass?: string;
355
+ /**
356
+ * Class added when dismissing, so CSS owns the **exit**. On dismiss the
357
+ * `enterClass` (if any) is also REMOVED, so `exitClass` doesn't have to
358
+ * out-specify it — and a symmetric single-class fade (entrance = add
359
+ * `enterClass`, exit = remove it) works by setting only `enterClass` +
360
+ * `exitDuration`. The node is removed `exitDuration` ms later.
361
+ */
362
+ exitClass?: string;
363
+ /** ms to wait before removing the node on dismiss — applies when `exitClass` is set OR when it's > 0 (to let a removed `enterClass` transition out). Default `0`. */
364
+ exitDuration?: number;
365
+ }
366
+ /** Handle returned by {@link toast}. */
367
+ interface ToastHandle {
368
+ /** The toast element — inspect it, or run your own entrance/exit transitions. */
369
+ el: HTMLElement;
370
+ /**
371
+ * Dismiss it early. Default runs the `exitClass` transition (removed after
372
+ * `exitDuration`); pass `{ instant: true }` to remove it **synchronously** with
373
+ * no exit — for an action button that immediately shows a replacement toast in a
374
+ * single centered slot (no cross-fade). Idempotent.
375
+ */
376
+ dismiss(options?: {
377
+ instant?: boolean;
378
+ }): void;
379
+ }
380
+ /**
381
+ * Show a non-modal, auto-dismissing notification. Stacks in a shared body-level
382
+ * region (or your `container`). Returns a {@link ToastHandle} (`{ el, dismiss }`)
383
+ * so you can run entrance/exit transitions, wire an action button, or inspect the
384
+ * node. `mode: 'replace'` collapses a rapid sequence to the latest; `variant`
385
+ * adds an accent class; `enterClass`/`exitClass` let CSS own the animation.
386
+ */
387
+ declare function toast(content: ToastContent, options?: ToastOptions): ToastHandle;
388
+
479
389
  export { type AnchorPositionOptions, type ChoiceAction, type ChoiceOptions, type ChoiceRenderSlots, type ConfirmOptions, type ConfirmRenderSlots, type DismissTrigger, type FieldValidator, type FormField, type FormOptions, type FormRenderField, type FormRenderSlots, type OverlayContent, type OverlayHandle, type OverlayOptions, type PopoverOptions, type PopoverPlacement, type PromptOptions, type PromptRenderSlots, type ToastContent, type ToastHandle, type ToastOptions, type ToastVariant, type TooltipContent, type TooltipOptions, autoReposition, choice, confirm, form, overlay, popover, positionAnchored, prompt, toast, tooltip };