# whiptail-js
> `whiptail-js` is a lightweight terminal-style dialog library for the web, inspired by the classic Linux `whiptail` tool, featuring keyboard navigation and touch support for mobile devices.
## Getting Started
### Installation
```bash
npm install jquery
npm install whiptail-js
```
Or use a CDN:
```html
```
### Usage
First, add a container element where your UI will render:
```html
```
Then create a new instance of `WhiptailJS`:
```js
const whiptail = new WhiptailJS({
title: "Raspberry Pi Software Configuration Tool (raspi-config)",
items: [
{ label: "1 System Options Configure system settings", focus: true },
{ label: "2 Display Options Configure display settings" },
{ label: "3 Interface Options Configure connections to peripherals" },
{ label: "4 Performance Options Configure performance settings" },
{ label: "5 Localisation Options Configure language and regional settings" },
{ label: "6 Advanced Options Configure advanced settings" },
{ label: "7 Update Update this tool to the latest version" },
{ label: "8 About raspi-config Information about this configuration tool" }
],
footer: [{ label: "<Select>", id: 'select' }, { label: "<Finish>", id: 'close' }],
selector: "#whiptail-container",
focus: true,
onSelect: (item, btn) => {
if(btn.id === 'close') {
whiptail.destroy(); // destroy the instance
} else if (btn.id === 'select') {
alert(`You selected: ${item.textContent}`);
}
}
});
```
### Output
### Configuration Options
- **`title`** | *(string, optional)* The dialog's header text.
- **`selector`** | *(string)* The CSS selector of the container element where the dialog will render.
- **`height`** | *(string, optional)* The height of the dialog. Accepts values in pixels (e.g., `"400px"`) or percentages (e.g., `"60%"`).
- **`width`** | *(string, optional)* The width of the dialog. Accepts values in pixels (e.g., `"600px"`) or percentages (e.g., `"80%"`).
- **`focus`** | *(boolean, optional)* Whether the dialog should automatically receive focus when created.
- **`text`** | *(string, optional)* Additional text content to display in the dialog.
- **`items`** | *(array of objects, optional)* List of menu items, each with the following:
- `label` *(string)* | The text content of the item.
- `id` *(string, optional)* | The HTML id attribute for the item.
- `class` *(string, optional)* | The HTML class attribute for the item.
- `focus` *(boolean, optional)* | Whether this item is initially focused.
- `active` *(boolean, optional)* | Whether this item is initially active (selected).
- **`footer`** | *(array of objects)* List of footer buttons, each with the same properties as `items`.
- **`onSelect`** | *(function)* Callback called when a user selects an item or footer button. Receives two arguments:
- The selected item DOM element.
- The selected footer button DOM element.
- **`onClose`** | *(function, optional)* Callback called when a user closes the dialog via the Escape key.
### API Methods
- **`constructor(config)`** | Creates a new whiptail dialog instance with the provided configuration options.
- **`get()`** | Returns the DOM element of the dialog container.
- **`focus()`** | Sets focus to the dialog, used to ensure keyboard navigation works properly.
- **`status()`** | Returns an object with `item` and `footer` properties containing the currently focused menu item and footer button element.
- **`destroy()`** | Destroys the dialog from the DOM and cleans up all event listeners.
- **`return()`** | Calls the `onClose` callback, equivalent to pressing Escape key.
- **`onSelect(item, footerButton)`** | Callback triggered when a user makes a selection. Receives the selected item and footer button elements.
- **`onClose()`** | Callback triggered when a user closes the dialog (via Escape key).
### Default Options
`whiptail-js` provides a selection of convenience methods that mimic the Linux whiptail commands, allowing you to create standard dialogs quickly.
#### Methods:
`WhiptailJS.msgbox(selector, text, [height], [width], [callback], [config])`
Displays a simple message box with an OK button.
```js
WhiptailJS.msgbox('#whiptail-container', 'Hello world!', 200, 400, () => {
console.log('OK pressed');
});
```
`WhiptailJS.yesno(selector, text, [height], [width], [callback], [config])`
Displays a [Yes / No] confirmation dialog.
```js
WhiptailJS.yesno('#whiptail-container', 'Do you want to continue?', 200, 400, (item, btn) => {
console.log(`${btn.id} pressed`);
});
```
`WhiptailJS.infobox(selector, text, [height], [width], [callback], [config])`
Displays a message box without any buttons; automatically calls the callback.
```js
WhiptailJS.infobox('#whiptail-container', 'Processing...', 200, 400, () => {
// do whatever before destroying
});
```
`WhiptailJS.textbox(selector, fileUrl, [height], [width], [callback], [config])`
Displays a file's content in a message box.
```js
WhiptailJS.msgbox('#whiptail-container', '/path/to/file.txt', 200, 400, () => {
console.log('OK pressed');
});
```
**Tip:** This method also supports external URLs.
`WhiptailJS.menu(selector, text, [height], [width], items, [callback], [config])`
Displays a menu list with selectable items.
```js
WhiptailJS.menu('#whiptail-container', 'Choose an option:', 500, 800, [
{ label: 'Option 1' },
{ label: 'Option 2', focus: true },
{ label: 'Option 3' }
], (item, btn) => {
console.log(`Selected: ${item.textContent}`);
});
```