Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Dialogs

Perry provides native dialog functions for file selection, alerts, and sheets.

File Open Dialog

import { openFileDialog } from "perry/ui";

const filePath = openFileDialog();
if (filePath) {
  console.log(`Selected: ${filePath}`);
}

Returns the selected file path, or null if cancelled.

Folder Selection Dialog

import { openFolderDialog } from "perry/ui";

const folderPath = openFolderDialog();
if (folderPath) {
  console.log(`Selected folder: ${folderPath}`);
}

Save File Dialog

import { saveFileDialog } from "perry/ui";

const savePath = saveFileDialog();
if (savePath) {
  // Write file to savePath
}

Alert

Display a native alert dialog:

import { alert } from "perry/ui";

alert("Operation Complete", "Your file has been saved successfully.");

alert(title, message) shows a modal alert with an OK button.

Sheets

Sheets are modal panels attached to a window:

import { Sheet, Text, Button, VStack } from "perry/ui";

const sheet = Sheet(() =>
  VStack([
    Text("Sheet Content"),
    Button("Close", () => {
      sheet.dismiss();
    }),
  ])
);

// Show the sheet
sheet.present();

Platform Notes

DialogmacOSiOSWindowsLinuxWeb
File OpenNSOpenPanelUIDocumentPickerIFileOpenDialogGtkFileChooserDialog<input type="file">
File SaveNSSavePanelIFileSaveDialogGtkFileChooserDialogDownload link
FolderNSOpenPanelIFileOpenDialogGtkFileChooserDialog
AlertNSAlertUIAlertControllerMessageBoxWMessageDialogalert()
SheetNSSheetModal VCModal DialogModal WindowModal div

Complete Example

import { App, Text, Button, VStack, HStack, State, openFileDialog, saveFileDialog, alert } from "perry/ui";
import { readFileSync, writeFileSync } from "perry/fs";

const content = State("");
const filePath = State("");

App("Text Editor", () =>
  VStack([
    HStack([
      Button("Open", () => {
        const path = openFileDialog();
        if (path) {
          filePath.set(path);
          content.set(readFileSync(path));
        }
      }),
      Button("Save As", () => {
        const path = saveFileDialog();
        if (path) {
          writeFileSync(path, content.get());
          filePath.set(path);
          alert("Saved", `File saved to ${path}`);
        }
      }),
    ]),
    Text(`File: ${filePath.get() || "No file open"}`),
    TextField(content, "Start typing..."),
  ])
);

Next Steps