Dialogs
sw.dialog offers two kinds of dialog:
- Themed dialogs — drawn by ScriptWeaver in your app's theme, async: they return a Promise and your app keeps running while they're open.
- Native dialogs — the operating system's own message boxes and file pickers, blocking: the call pauses your script until the user responds.
Themed dialogs (async)
Live preview. In the Player's built-in docs viewer (
scriptweaver --help), this rendersDialogsas a live, theme-aware widget you can interact with.
const choice = await sw.dialog.message('Save your changes?', {
title: 'Confirm',
icon: 'question',
buttons: ['Save', 'Discard', 'Cancel'],
default: 'Save',
cancelValue: 'Cancel',
});
if (choice === 'Save') save();
message(text, options?) → Promise<label | cancelValue>
Shows a modal message box styled by the current theme and resolves with the label of the button the user clicked.
| option | meaning |
|---|---|
title |
window title (default 'Message') |
icon |
'info' (default), 'question', 'warning', 'danger', 'success' — a themed icon |
buttons |
array of button labels (default ['OK']) |
default |
the label Return activates; drawn solid and focused (defaults to the first button) |
cancelValue |
what Escape or closing the window resolves with (default null) |
prompt(text, options?) → Promise<string | null>
Asks for one line of text. Resolves with the entered string (OK / Return) or
null (Cancel / Escape / window close).
const name = await sw.dialog.prompt('Project name:', { value: 'my-app' });
if (name !== null) create(name);
Options: title, value (prefill), ok / cancel (button labels).
chooseFont(current?, options?) → Promise<string | null>
A themed font picker — choose a family, size and style (bold / italic /
underline / strike), with a live preview. Resolves with a Tk font string
(OK) or null (Cancel / Escape / window close).
const font = await sw.dialog.chooseFont('Helvetica 12');
if (font !== null) label.font = font; // e.g. '{DejaVu Sans} 14 bold italic'
The first argument is the starting font in any Tk font form — a string like
'Helvetica 12' or '{DejaVu Sans} 14 bold', or a named font; omit it to open
on the default font. You may instead pass an options object whose initial is
the starting font.
The resolved value is a plain string you can assign straight to a widget's
font option, store in JSON, or emit into generated code — it round-trips
unchanged (a family containing spaces comes back brace-quoted, e.g.
{DejaVu Sans} 14 bold). Store it as-is; there is no object to unpack.
Options: title, ok / cancel (button labels), sample (preview text),
initial (starting font).
Why async?
The themed dialogs take a Tk grab — the user can't interact with the rest
of the window — but your JavaScript never stops. Timers keep firing,
events keep arriving, animations keep moving. The result simply arrives
later, through the Promise:
sw.dialog.message('Working…').then((r) => console.log('closed with', r));
// code here runs immediately, with the dialog still up
Use await when you want the prompt-like flow, or .then() when the dialog
should not hold up other work. Dialogs may be stacked — opening a dialog from
a dialog works, and closing the inner one returns modality to the outer one.
Keyboard: Tab moves between buttons, Return activates the default
button (prompt submits the entry), Escape cancels. The dialog is
announced to assistive technology, and when it closes, focus returns to the
widget that had it.
Native message boxes
sw.dialog.alert('File saved.');
if (sw.dialog.confirm('Delete this item?')) {
// the user clicked Yes
}
alert(message, options?)— an OK box.confirm(message, options?)— a Yes / No box; returnstruefor Yes.
Both accept an options object: title, icon ('info', 'question',
'warning', 'error'), and detail (secondary text).
sw.dialog.alert('Could not open the file.', {
title: 'Error',
icon: 'error',
detail: String(err),
});
These use the OS-native message box, which on some platforms looks different
from your themed app. For dialogs that match your theme — and don't block —
prefer sw.dialog.message.
File and directory pickers
Each returns the chosen path as a string, or an empty string if the user cancels.
const path = sw.dialog.openFile({ title: 'Open note' });
if (path) text.setText(sw.fs.readFile(path));
const dest = sw.dialog.saveFile({ initialFile: 'untitled.txt' });
const dir = sw.dialog.chooseDirectory();
openFile(options?)— pick an existing file.saveFile(options?)— choose a path to save to.chooseDirectory(options?)— pick a folder.
Common options: title, initialDir, initialFile (open / save), and
defaultExtension (save).
Colour picker
const colour = sw.dialog.chooseColor({ initial: '#3366ff' });
if (colour) shape.fill = colour; // '#rrggbb', or '' if cancelled
A note on blocking
The native dialogs are synchronous: the call waits for the user and your
code resumes on the next line with the result in hand — usually exactly what
you want for a file picker. But be aware that everything in your script
waits: while a native dialog is open, timers don't fire and event handlers
queue up until it closes. If something must keep running — a progress
update, a clock, an animation — use the async sw.dialog.message /
sw.dialog.prompt instead, or open the picker at a moment when pausing is
fine.
Next
- System & files —
sw.fs,sw.sys,sw.app - Events & binding
- Widget reference