zenity-wrapper
v1.0.4
Published
Bun-powered Zenity dialog wrapper for macOS/Linux
Maintainers
Readme
Bun Zenity Wrapper
A fully-typed TypeScript wrapper for Zenity dialogs, providing an easy-to-use API for creating native desktop dialogs in your Bun applications.
Prerequisites
Install Zenity on your system:
# macOS
brew install zenity
# Ubuntu/Debian
sudo apt-get install zenity
# Fedora
sudo dnf install zenitymacOS Note: This wrapper automatically configures Zenity to prevent GTK4-related crashes on macOS by setting the
GSETTINGS_BACKEND=memoryenvironment variable. No additional setup required!
Installation
Install from npm once published:
# With Bun
bun add zenity-wrapper
# With npm
npm install zenity-wrapper
# With pnpm
pnpm add zenity-wrapperUsage
import Zenity from 'zenity-wrapper';
const zenity = new Zenity();
// Show an info dialog
await zenity.info("Hello, World!", { title: "Greeting" });
// Ask a question
const confirm = await zenity.question("Continue?");
if (confirm) {
console.log("User confirmed!");
}
// Get user input
const name = await zenity.entry("Enter your name:");
console.log(`Hello, ${name}!`);
// Forms with button differentiation (NEW!)
const result = await zenity.forms(
[
{ type: 'entry', label: 'Name' },
{ type: 'entry', label: 'Email' }
],
{
title: 'Contact Info',
extraButton: 'Skip' // Optional third button
}
);
// Now you can distinguish which button was clicked
if (result.button === 'ok') {
console.log('Submitted:', result.values);
} else if (result.button === 'extra') {
console.log('User clicked Skip button');
} else {
console.log('User cancelled');
}Breaking Change in Forms API
⚠️ Important: The forms() method now returns a FormsResult object instead of string[] | null.
Before:
const values = await zenity.forms([...], options);
if (values) {
console.log(values);
}After:
const result = await zenity.forms([...], options);
if (result.button === 'ok' && result.values) {
console.log(result.values);
}This change allows you to distinguish between Cancel and Extra button clicks, which was previously impossible.
Demos
The demos directory contains TypeScript ports of the Python Zenity Wrapper demos. You can run any demo using bun:
bun demos/info_dialog.ts
bun demos/simple_form.tsAvailable Demos
Message Dialogs
info_dialog.ts- Information messagewarning_dialog.ts- Warning messageerror_dialog.ts- Error messagequestion_dialog.ts- Yes/No question
Input Dialogs
entry_dialog.ts- Text inputpassword_dialog.ts- Password inputscale_dialog.ts- Slider/Scalecalendar_dialog.ts- Date picker
Selection Dialogs
list_dialog.ts- Simple list selectionchecklist_dialog.ts- Multiple selection checklistradiolist_dialog.ts- Single selection radio listfile_selection_dialog.ts- File/Directory picker
Progress Dialogs
progress_dialog.ts- Progress bars
Text Dialogs
text_dialog.ts- Text viewer/editor
Form Dialogs
simple_form.ts- Basic form with entry fieldspassword_form.ts- Login/Registration formmultiline_form.ts- Form with multiline text areacalendar_form.ts- Form with date pickercombo_form.ts- Form with dropdownslist_form.ts- Form with list selectioncomprehensive_form.ts- Form showcasing all field types
Screenshots
Message Dialogs
Input Dialogs
Selection Dialogs
Form Dialogs
Controlling Multiline Input Height
When using forms with multiline text fields, you can control the height by setting the height option on the dialog. Zenity automatically distributes the available space among form fields, with multiline fields receiving proportionally more vertical space.
How it works:
- Single-line fields (entry, password, combo) have a fixed height
- Multiline fields expand to use the remaining available vertical space
- The
heightparameter controls the overall dialog height, not individual fields
Example:
const zenity = new Zenity();
// Small multiline area (default height)
const result1 = await zenity.forms(
[
{ type: 'entry', label: 'Title' },
{ type: 'multiline', label: 'Description' },
{ type: 'entry', label: 'Tags' }
],
{
text: "Create a Post",
separator: "||"
}
);
// Large multiline area (increased height)
const result2 = await zenity.forms(
[
{ type: 'entry', label: 'Title' },
{ type: 'multiline', label: 'Description' },
{ type: 'entry', label: 'Tags' }
],
{
text: "Create a Post",
separator: "||",
width: 600,
height: 800 // More dialog height = more space for multiline field
}
);Note: Zenity doesn't provide command-line options to control individual field heights. The layout is handled automatically based on the overall dialog dimensions.
API Documentation
See ZENITY_API.md for complete API documentation with examples for all dialog types.
Forms Collection
The FormCollection class (demos/forms_collection.ts) provides pre-built, developer-focused forms for common workflows. These forms combine multiple input types to collect structured data for various tasks.
Running the Forms Collection Demo
bun demos/forms_collection.tsAvailable Forms
The collection includes 24+ ready-to-use forms organized by category:
Project Setup
- Package Initialization (npm/Bun packages)
- TypeScript Configuration
- Python Project Setup
- Web Project Setup (React, Vue, etc.)
Git & Version Control
- Conventional Git Commits
- Pull Requests
- Release Versioning
- .gitignore Generator
Configuration Files
- Environment Variables
- ESLint/Prettier Config
- VS Code Workspace Settings
- Package.json Scripts
Deployment & DevOps
- Docker Container Config
- GitHub Actions Workflows
- SSH Configuration
Database & Services
- Database Connection Setup
- API Configuration
Documentation
- README Generator
- Changelog Entries
- Blog Post Metadata
Issue Tracking
- Bug Reports
- Feature Requests
Usage Example
import { FormCollection } from './demos/forms_collection';
const forms = new FormCollection();
// Collect package initialization data
const pkgData = await forms.packageInit();
console.log(pkgData);
// {
// packageName: 'my-app',
// version: '0.1.0',
// description: 'My awesome app',
// author: 'Developer Name',
// license: 'MIT',
// runtime: 'Bun'
// }
// Collect git commit data
const commit = await forms.gitCommit();
console.log(commit);
// {
// type: 'feat',
// scope: 'api',
// summary: 'Add user authentication',
// description: 'Implemented JWT-based auth',
// breaking: 'No'
// }All forms return structured objects with named fields, making it easy to integrate into scripts and automation workflows.
Running the Demo
bun run demo.tsThe demo showcases all available dialog types including:
- Message dialogs (info, warning, error, question)
- Input dialogs (entry, password, scale, calendar)
- Selection dialogs (list, color picker)
- File dialogs (open, save, directory)
- Progress dialogs
- Advanced dialogs (forms, text editor)
Building
You can build your TypeScript files with Bun:
# Build a single file
bun build ./demo.ts --outdir ./dist
# Build with minification
bun build ./demo.ts --outdir ./dist --minify
# Build as a standalone executable
bun build ./demo.ts --compile --outfile zenity-demoFor more build options, see the Bun build documentation.
TypeScript Support
This library is written in TypeScript and includes full type definitions. All dialog options are properly typed for an excellent development experience.
import Zenity, { QuestionOptions, ListOptions } from './zenity-wrapper';
const options: QuestionOptions = {
title: "Confirm",
okLabel: "Yes",
cancelLabel: "No"
};Project Info
This project was created using bun init in bun v1.3.2. Bun is a fast all-in-one JavaScript runtime.
Publishing
To publish the package to npm:
# Build the package
bun run build
# Login to npm if needed
npm login
# Publish
npm publish --access public
# Alternatively, using Bun
bun publishIf the name zenity-wrapper is taken on npm, update the name field in package.json before publishing.
