@joewinke/jatui
v0.2.33
Published
Shared Svelte 5 component library for JAT projects
Readme
@joewinke/jatui
Shared Svelte 5 component library for JAT projects.
Installation
npm install @joewinke/jatuiRequires Svelte 5 and DaisyUI 5 as peer dependencies.
Dialog Utilities
ConfirmDialog and InputDialog are global, promise-based dialogs that replace the browser's native confirm() / prompt(). They're keyboard-accessible, animated, and theme-aware.
Setup — wire into root layout
Mount both components once at the app root so they're always available:
<!-- src/routes/+layout.svelte -->
<script>
import { ConfirmDialog, InputDialog } from '@joewinke/jatui';
</script>
<slot />
<ConfirmDialog />
<InputDialog />showConfirm(opts) → Promise<boolean>
Shows a modal confirmation dialog. Resolves true if the user confirms, false if they cancel or the timeout expires.
import { showConfirm } from '@joewinke/jatui';
const ok = await showConfirm({
title: 'Delete project?',
body: 'This cannot be undone.',
danger: true,
timeoutMs: 10000, // auto-cancel after 10 s; progress bar drains to zero
confirmLabel: 'Delete', // default: 'Confirm' (danger) / 'OK' (non-danger)
cancelLabel: 'Keep', // default: 'Cancel'
});
if (ok) {
await deleteProject(id);
}Options (ConfirmOptions):
| Option | Type | Default | Description |
|---|---|---|---|
| title | string | required | Dialog heading |
| body | string | — | Supporting detail text |
| danger | boolean | true | Red styling + terminal icon when true; info styling otherwise |
| timeoutMs | number | 8000 | Auto-cancel after this many ms; 0 disables the timer |
| confirmLabel | string | 'Confirm' / 'OK' | Confirm button label |
| cancelLabel | string | 'Cancel' | Cancel button label |
Keyboard: Enter confirms · Escape cancels · focus starts on Cancel (safe default for destructive actions).
showInput(opts) → Promise<string | null>
Shows a modal text-input dialog. Resolves with the typed string on confirm, null on cancel.
import { showInput } from '@joewinke/jatui';
const name = await showInput({
title: 'Rename project',
body: 'Enter a new name for this project.',
placeholder: 'My project',
maxLength: 60,
validate: (v) => v.trim().length < 2 ? 'Name must be at least 2 characters.' : null,
});
if (name !== null) {
await renameProject(id, name.trim());
}Options (InputOptions):
| Option | Type | Default | Description |
|---|---|---|---|
| title | string | required | Dialog heading |
| body | string | — | Supporting detail text |
| placeholder | string | — | Input placeholder text |
| maxLength | number | — | maxlength cap on the input field |
| validate | (value: string) => string \| null | — | Return an error message to block submission, null to allow it |
| confirmLabel | string | 'OK' | Confirm button label |
| cancelLabel | string | 'Cancel' | Cancel button label |
Keyboard: Enter submits (runs validate first) · Escape cancels · input is focused on open.
Migration guide — replacing native confirm() / prompt()
- if (!confirm('Are you sure you want to delete this?')) return;
+ if (!await showConfirm({ title: 'Delete this?', danger: true })) return;- const name = prompt('Enter a new name:', currentName);
- if (name === null) return;
+ const name = await showInput({ title: 'Rename', placeholder: currentName });
+ if (name === null) return;Both dialogs are non-blocking (await), keyboard-navigable, and respect the app's DaisyUI theme. Unlike native dialogs they don't pause the JavaScript event loop.
