kerfjs 4.2.0-beta.2 → 4.2.0-beta.4

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/overlay.d.ts CHANGED
@@ -53,6 +53,19 @@ interface OverlayHandle {
53
53
  * handle. See {@link OverlayOptions}.
54
54
  */
55
55
  declare function overlay(content: OverlayContent, options?: OverlayOptions): OverlayHandle;
56
+ /**
57
+ * Wiring slots passed to a {@link ConfirmOptions.render} — spread `ok` / `cancel`
58
+ * onto your own clickable elements so `confirm()` still resolves them (they are
59
+ * `data-confirm` attribute bags). `message` is the raw message (escape it by
60
+ * interpolating through JSX).
61
+ */
62
+ interface ConfirmRenderSlots {
63
+ message: string;
64
+ /** Spread onto the confirm control. */
65
+ ok: Record<string, string>;
66
+ /** Spread onto the cancel control. */
67
+ cancel: Record<string, string>;
68
+ }
56
69
  /** Options for {@link confirm}. */
57
70
  interface ConfirmOptions {
58
71
  /** Where to append the overlay. Default `document.body`. */
@@ -67,12 +80,19 @@ interface ConfirmOptions {
67
80
  cancelText?: string;
68
81
  /** Add a `kerf-confirm--danger` class to the wrapper for destructive actions. */
69
82
  danger?: boolean;
83
+ /**
84
+ * Bring your own markup (design-system dialogs): return the full dialog body,
85
+ * spreading the provided `ok`/`cancel` wiring onto your buttons. Overrides the
86
+ * default two-button markup; `confirm()` keeps owning dismiss / focus-trap /
87
+ * focus-restore and still resolves `true`/`false` for OK/Cancel/dismissal.
88
+ */
89
+ render?: (slots: ConfirmRenderSlots) => OverlayContent;
70
90
  }
71
91
  /**
72
92
  * A promise-based `window.confirm` replacement (that global is a no-op in Tauri
73
93
  * webviews). Renders a two-button dialog and resolves `true` for OK, `false`
74
94
  * for Cancel or any dismissal (Escape / backdrop). Message + labels are
75
- * auto-escaped (rendered through the JSX runtime).
95
+ * auto-escaped (rendered through the JSX runtime). Pass `render` for your own markup.
76
96
  */
77
97
  declare function confirm(message: string, options?: ConfirmOptions): Promise<boolean>;
78
98
  /**
@@ -101,13 +121,34 @@ interface PromptOptions {
101
121
  cancelText?: string;
102
122
  /** Block OK while this returns an error string; the message shows inline. */
103
123
  validate?: FieldValidator;
124
+ /**
125
+ * Bring your own markup: return the full dialog body, spreading the provided
126
+ * `input` (the text field), `ok`/`cancel` (buttons), and optional `error` (the
127
+ * inline-error slot) wiring. `prompt()` still reads the input, runs `validate`,
128
+ * submits on Enter, and owns dismiss / focus. If you omit the `error` slot,
129
+ * `validate` simply re-focuses the input without an inline message.
130
+ */
131
+ render?: (slots: PromptRenderSlots) => OverlayContent;
132
+ }
133
+ /** Wiring slots for a {@link PromptOptions.render} — spread each onto your own markup. */
134
+ interface PromptRenderSlots {
135
+ message: string;
136
+ /** Spread onto your `<input>` — carries the marker, `type`, `value`, and `placeholder`. */
137
+ input: Record<string, string>;
138
+ /** Spread onto your inline-error element (optional). */
139
+ error: Record<string, string>;
140
+ /** Spread onto the confirm control. */
141
+ ok: Record<string, string>;
142
+ /** Spread onto the cancel control. */
143
+ cancel: Record<string, string>;
104
144
  }
105
145
  /**
106
146
  * A promise-based `window.prompt` replacement (that global is a no-op in Tauri
107
147
  * webviews). Renders a one-field dialog and resolves the entered **string** on OK
108
148
  * (an empty string is a valid result) or `null` on Cancel / dismissal. Enter in
109
149
  * the input submits. `message`, the default value, and labels are auto-escaped
110
- * (rendered through the JSX runtime). Optional `validate` blocks OK inline.
150
+ * (rendered through the JSX runtime). Optional `validate` blocks OK inline. Pass
151
+ * `render` for your own markup.
111
152
  */
112
153
  declare function prompt(message: string, options?: PromptOptions): Promise<string | null>;
113
154
  /** A single field in a {@link form}. */
@@ -125,6 +166,23 @@ interface FormField {
125
166
  /** Block OK while this returns an error string; the message shows inline for this field. */
126
167
  validate?: FieldValidator;
127
168
  }
169
+ /** One field's wiring in a {@link FormRenderSlots} — spread `input`/`error` onto your markup. */
170
+ interface FormRenderField {
171
+ name: string;
172
+ label: string;
173
+ /** Spread onto your `<input>` — carries the marker, `name`, `type`, `value`, `placeholder`. */
174
+ input: Record<string, string>;
175
+ /** Spread onto your inline-error element (optional). */
176
+ error: Record<string, string>;
177
+ }
178
+ /** Wiring slots for a {@link FormOptions.render}. */
179
+ interface FormRenderSlots {
180
+ fields: FormRenderField[];
181
+ /** Spread onto the confirm control. */
182
+ ok: Record<string, string>;
183
+ /** Spread onto the cancel control. */
184
+ cancel: Record<string, string>;
185
+ }
128
186
  /** Options for {@link form}. */
129
187
  interface FormOptions {
130
188
  /** Where to append the overlay. Default `document.body`. */
@@ -137,6 +195,14 @@ interface FormOptions {
137
195
  okText?: string;
138
196
  /** Cancel button label. Default `'Cancel'`. */
139
197
  cancelText?: string;
198
+ /**
199
+ * Bring your own markup: return the full form body, laying out `slots.fields`
200
+ * (each with `input`/`error` wiring to spread) and the `ok`/`cancel` buttons.
201
+ * `form()` still reads each input, runs per-field `validate`, focuses the first
202
+ * invalid field, submits on Enter, and owns dismiss / focus. Omit a field's
203
+ * `error` slot to skip its inline message.
204
+ */
205
+ render?: (slots: FormRenderSlots) => OverlayContent;
140
206
  }
141
207
  /**
142
208
  * A promise-based multi-field dialog — the two-or-three-input sibling of
@@ -146,8 +212,71 @@ interface FormOptions {
146
212
  * the title are auto-escaped through the JSX runtime.
147
213
  */
148
214
  declare function form(fields: readonly FormField[], options?: FormOptions): Promise<Record<string, string> | null>;
149
- /** Vertical placement of a {@link popover} relative to its anchor. */
215
+ /** One choosable action in a {@link choice} dialog. */
216
+ interface ChoiceAction<R> {
217
+ /** The value this action resolves. */
218
+ value: R;
219
+ /** Button label (auto-escaped). */
220
+ label: string;
221
+ /** Extra class on this action's button. */
222
+ className?: string;
223
+ }
224
+ /** Wiring slots for a {@link ChoiceOptions.render} — spread `actions[i]` onto your i-th button. */
225
+ interface ChoiceRenderSlots {
226
+ message: string;
227
+ /** One attribute bag per action (in order) — spread onto that action's control. */
228
+ actions: Array<Record<string, string>>;
229
+ }
230
+ /** Options for {@link choice}. */
231
+ interface ChoiceOptions<R> {
232
+ /** Where to append the overlay. Default `document.body`. */
233
+ container?: Element;
234
+ /** Wrapper class. Default `'kerf-overlay'`. */
235
+ className?: string;
236
+ /** Optional heading above the message. */
237
+ title?: string;
238
+ /** The value resolved when **Enter** is pressed anywhere in the dialog (the default action). */
239
+ defaultValue?: R;
240
+ /** Bring your own markup: return the full body, spreading each `slots.actions[i]` onto your buttons. */
241
+ render?: (slots: ChoiceRenderSlots) => OverlayContent;
242
+ }
243
+ /**
244
+ * The **N-way** sibling of {@link confirm}: renders one button per {@link ChoiceAction}
245
+ * and resolves that action's `value` on click, or `null` on Cancel / dismissal.
246
+ * Pass `defaultValue` to make **Enter** (anywhere in the dialog) resolve a default
247
+ * action — the "global Enter-to-confirm" model — without you having to hold the
248
+ * overlay handle. `message` + labels are auto-escaped; pass `render` for your own
249
+ * markup. kerf owns dismiss / focus-trap / focus-restore. For fully bespoke
250
+ * keyboard/close control, drive {@link overlay} directly.
251
+ */
252
+ declare function choice<R>(message: string, actions: ReadonlyArray<ChoiceAction<R>>, options?: ChoiceOptions<R>): Promise<R | null>;
253
+ /** Vertical placement relative to an anchor (used by {@link popover}, {@link positionAnchored}, {@link tooltip}). */
150
254
  type PopoverPlacement = 'bottom' | 'top';
255
+ /** Placement options for {@link positionAnchored} / {@link autoReposition}. */
256
+ interface AnchorPositionOptions {
257
+ /** Preferred side of the anchor; flips to the other side if it would overflow the viewport. Default `'bottom'`. */
258
+ placement?: PopoverPlacement;
259
+ /** Horizontal edge to line up with the anchor: `'start'` (left edges) or `'end'` (right edges). Default `'start'`. */
260
+ align?: 'start' | 'end';
261
+ /** Gap in px between the anchor and the element. Default `4`. */
262
+ gap?: number;
263
+ }
264
+ /**
265
+ * One-shot: position `el` relative to `anchor` — below by default, flipping above
266
+ * if it would overflow the viewport, aligned to a horizontal edge and clamped into
267
+ * view. Sets `el.style` `position: fixed`, `margin: 0`, `left`, and `top` (fixed so
268
+ * `left`/`top` are viewport coordinates, matching `getBoundingClientRect`). This is
269
+ * `popover()`'s placement core, usable on any element (an inline hint, a tooltip) —
270
+ * no overlay lifecycle. Pair with {@link autoReposition} to keep it glued while open.
271
+ */
272
+ declare function positionAnchored(el: HTMLElement, anchor: Element, options?: AnchorPositionOptions): void;
273
+ /**
274
+ * Keep `el` positioned against `anchor` (via {@link positionAnchored}) as the page
275
+ * scrolls or resizes. Positions once immediately, then re-runs on `scroll`
276
+ * (capture phase — catches scrolls in any inner container, not just `window`) and
277
+ * `resize`. Returns a disposer that removes the listeners.
278
+ */
279
+ declare function autoReposition(el: HTMLElement, anchor: Element, options?: AnchorPositionOptions): () => void;
151
280
  /** Options for {@link popover}. */
152
281
  interface PopoverOptions {
153
282
  /** Where to append the popover wrapper. Default `document.body`. */
@@ -182,8 +311,34 @@ interface PopoverOptions {
182
311
  * listeners. `position: fixed` is set inline (you style everything else).
183
312
  */
184
313
  declare function popover(anchor: Element, content: OverlayContent, options?: PopoverOptions): OverlayHandle;
314
+ /** Content for a {@link tooltip}: text (auto-escaped), `SafeHtml`, or a render function. */
315
+ type TooltipContent = string | SafeHtml | (() => MountResult);
316
+ /** Options for {@link tooltip}. */
317
+ interface TooltipOptions extends AnchorPositionOptions {
318
+ /** Where to append the tooltip wrapper. Default `document.body`. */
319
+ container?: Element;
320
+ /** Class on the wrapper. Default `'kerf-tooltip'`. */
321
+ className?: string;
322
+ /** Delay in ms before showing after hover/focus enters. Default `400`. */
323
+ delay?: number;
324
+ /** Delay in ms before hiding after hover/focus leaves. Default `100`. */
325
+ hideDelay?: number;
326
+ /** ARIA role on the wrapper. Default `'tooltip'`. */
327
+ role?: string;
328
+ }
329
+ /**
330
+ * A hover/focus-triggered, non-modal, auto-hiding tooltip anchored to `anchor`.
331
+ * Shows after `delay` on `pointerenter`/`focus`, hides after `hideDelay` on
332
+ * `pointerleave`/`blur`, and positions itself with {@link autoReposition} (above
333
+ * the anchor by default). Unlike {@link popover} there is no click-dismiss model —
334
+ * it follows the pointer/focus. Returns a disposer that removes the anchor
335
+ * listeners and hides any shown tooltip. Structural only (kerf ships no CSS).
336
+ */
337
+ declare function tooltip(anchor: Element, content: TooltipContent, options?: TooltipOptions): () => void;
185
338
  /** Content for a {@link toast}: text, `SafeHtml`, or a render function. */
186
339
  type ToastContent = string | SafeHtml | (() => MountResult);
340
+ /** Accent variant for a {@link toast} — mapped to a `${className}--${variant}` class. */
341
+ type ToastVariant = 'info' | 'success' | 'warning';
187
342
  /** Options for {@link toast}. */
188
343
  interface ToastOptions {
189
344
  /** Where toasts stack. Default: a lazily-created `<div class="kerf-toasts">` on `document.body`. */
@@ -194,11 +349,47 @@ interface ToastOptions {
194
349
  duration?: number;
195
350
  /** ARIA role. Default `'status'`. */
196
351
  role?: string;
352
+ /**
353
+ * `'stack'` (default) shows toasts stacked in the region; `'replace'` dismisses
354
+ * the region's current toast(s) first (collapse-to-latest for a rapid sequence).
355
+ */
356
+ mode?: 'stack' | 'replace';
357
+ /**
358
+ * How `mode: 'replace'` drops the prior toast(s): `'fade'` (default) runs their
359
+ * full exit transition (nice for a STACKING region), or `'instant'` removes them
360
+ * synchronously with no exit — what a single, exactly-centered toast slot wants,
361
+ * so the outgoing and incoming messages never cross-fade in the same spot.
362
+ */
363
+ collapse?: 'fade' | 'instant';
364
+ /** Accent variant — adds a `${className}--${variant}` class (kerf ships no CSS; you style it). */
365
+ variant?: ToastVariant;
366
+ /** Class added on the next animation frame after mount, so a CSS **entrance** transition can run. */
367
+ enterClass?: string;
368
+ /**
369
+ * Class added when dismissing, so CSS owns the **exit**. On dismiss the
370
+ * `enterClass` (if any) is also REMOVED, so `exitClass` doesn't have to
371
+ * out-specify it — and a symmetric single-class fade (entrance = add
372
+ * `enterClass`, exit = remove it) works by setting only `enterClass` +
373
+ * `exitDuration`. The node is removed `exitDuration` ms later.
374
+ */
375
+ exitClass?: string;
376
+ /** 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`. */
377
+ exitDuration?: number;
378
+ }
379
+ /** Handle returned by {@link toast}. */
380
+ interface ToastHandle {
381
+ /** The toast element — inspect it, or run your own entrance/exit transitions. */
382
+ el: HTMLElement;
383
+ /** Dismiss it early (running the `exitClass` transition if set). Idempotent. */
384
+ dismiss(): void;
197
385
  }
198
386
  /**
199
387
  * Show a non-modal, auto-dismissing notification. Stacks in a shared body-level
200
- * region (or your `container`). Returns a `() => void` that dismisses it early.
388
+ * region (or your `container`). Returns a {@link ToastHandle} (`{ el, dismiss }`)
389
+ * so you can run entrance/exit transitions, wire an action button, or inspect the
390
+ * node. `mode: 'replace'` collapses a rapid sequence to the latest; `variant`
391
+ * adds an accent class; `enterClass`/`exitClass` let CSS own the animation.
201
392
  */
202
- declare function toast(content: ToastContent, options?: ToastOptions): () => void;
393
+ declare function toast(content: ToastContent, options?: ToastOptions): ToastHandle;
203
394
 
204
- export { type ConfirmOptions, type DismissTrigger, type FieldValidator, type FormField, type FormOptions, type OverlayContent, type OverlayHandle, type OverlayOptions, type PopoverOptions, type PopoverPlacement, type PromptOptions, type ToastContent, type ToastOptions, confirm, form, overlay, popover, prompt, toast };
395
+ 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 };