Browse the docs

Show a panel

Shows a small window you describe in JSON: text, pictures, buttons, fields, sliders, tables and charts, drawn natively.

Show panel title

Details #

Describe a window as a tree of views and Switchboard draws it with real controls in the same glass panel as a prompt: keyboard, VoiceOver, light and dark all work. The panel appears without taking the keyboard from the app you are in until it needs it (a field to type in, or a default button to press).

With wait on (the default) the step behaves like Ask for input: it shows the panel, waits, and answers with the button pressed and everything entered. Escape, ⌘. or Cancel fails the step with "cancelled by you". With wait off the step shows the panel and the macro carries on; the panel stays until a button closes it, you press Escape, or Close a panel closes it. Give it an id and later steps can change it with Update a panel or read it with Read a panel.

The answer is {id, button, values}. button is the pressed button's value (its title when it has none). values has one entry per node with an id that holds something: the text of a field or the choice of a picker, a toggle's true or false, a slider's number, a table's chosen row or rows. Every value is also a variable of its own name, panelButton holds the button, and into receives the whole answer.

The views #

A view is {"type": …} plus its properties. id names a view so a value or an update can find it; ids are unique in a panel. Fields, toggles, sliders, pickers and tables you choose rows from must have one.

typepropertiesits value
stackdir (v or h), gap, align (start, center, end), children, scrollnone
texttext, style (title, body, caption, mono)none
imagesymbol (an SF Symbol) or file or url (https, up to 2 MB), size, tint, labelnone
buttontitle, role (default, cancel, destructive, plain), value, run, close, symbolnone
fieldlabel, kind (text, multiline, secure), placeholder, valuetext
togglelabel, valuetrue or false
sliderlabel, min, max, step, valuea number
pickerlabel, options (text or {title, value}), style (menu, segmented, radio), valuethe option's value
progressvalue from 0 to 1 (leave it out for a bar that just moves), labelnone
tablecolumns ({title, key}), rows (objects), select (none, one, many)the chosen row, or the list of them
chartkind (line, bar), data ({x, y} points), titlenone
divider, spacernone

Text in any property can use {{ }}; it is filled in when the panel appears. A panel holds at most 200 views, 8 levels deep, 500 table rows and 1000 chart points. Anything outside this list is refused with where it is and what it probably meant: unknown type "chek" at body.children[1]; did you mean "toggle"?.

An image with no label is hidden from VoiceOver, so give a meaningful picture a label.

Buttons #

Put button views in the body, or give the buttons list and the panel adds them along the bottom, with Cancel. Return presses the default button: the first in the list, or the body's button with role: "default". Inside a multi-line field Return adds a line and ⌘Return presses it. ⌘1 to ⌘9 press the first nine buttons in the list.

A button's run starts a macro in the same library, either by name ("run": "Archive") or with inputs ("run": {"macro": "Archive", "inputs": {"keep": 3}}). The macro also gets panel.values and panel.button, so it sees what was entered. The panel closes when the macro has started, unless the button has close: false: then the panel stays, the button waits while the macro runs, and a failure shows as a red line under the title. The run appears in Activity as "Panel button". A button without run answers with its value; with close: false it only records the press, and Read a panel returns it as button.

Parameters #

ParameterTypeRequiredValuesWhat it does
aiyes / notrue adds the AI badge: a model made this panel.
bodyrecordThe views. Usually a stack.
buttonslist of textThe footer buttons when the body has no button view. The first is the default. A waiting panel with neither gets an OK button.
idtextNames the panel for the steps that touch it. Left out, it is named after the step, so running the macro again replaces the old panel.
intotextThe variable that receives {id, button, values}.
keepOpenyes / noLeave the panel up after the answer, so later steps can update or close it.
positionone ofcenter cursor topcenter (default, in the upper third of the pointer's screen), cursor or top.
titletextThe window title. Defaults to the macro's name.
waityes / noOn (default): wait for the answer. Off: show and carry on; the answer is just {id}.
widthnumberIn points, from 280 to 900. Default 420. The height fits the content, up to 80% of the screen, then it scrolls.

Every step also accepts label, onFailure, timeout and dryRunSafe.

Examples #

Confirm with details
Do
  1. Show panel “Move 14 files?” and wait
  2. Show “{{ panelButton }}, trash duplicates: {{ trash }}”
Open in Switchboard to try it
A settings form
Do
  1. Show panel “Export settings” and wait
  2. Show “Exporting {{ name }}.{{ format }} at {{ quality…”
Open in Switchboard to try it
A live download (a bar, a note, a Stop button)
Do
  1. Show panel “Download” and carry on
  2. Repeat 20 times
  3. Update panel “dl” (2 things)
  4. Read panel “dl” into now
  5. If {{ now.button }} is “stop”
  6. Break out of the repeat
  7. Wait 0.5 s
  8. Close panel “dl”
Open in Switchboard to try it
A results table with a Use this button
Do
  1. Show panel “Pick a reply” and wait
  2. Show “{{ choice.reply }}”
Open in Switchboard to try it

Gotchas #

  • Updates to a showing panel are checked against the same vocabulary and limits, and a bad one fails its step with where it is. A field you are typing in keeps your text unless the update says force.

  • A dry run shows the panel for real, unless a button runs a macro: then it answers with every view's starting value and the first button, and shows nothing.

  • A secure field's text reaches the macro but is kept out of the trace.

  • {{ }} is filled in once, when the panel appears. To change what a panel shows later, use Update a panel.

  • It waits for you, so a waiting panel has no 10 s default limit. The macro's own timeout still ends it.

  • A panel cannot run script or load a web page. Web content in a panel is not available.

See also #

Update a panel, Read a panel, Close a panel, Ask for input, Show message