menuBarItems
Adds a section to Switchboard's menu bar menu that your extension fills and updates.
Details #
Switchboard lives in the menu bar. The menuBarItems point adds a section to the menu that opens from its icon. Each section has a title, an optional symbol and a list of rows. Rows can be commands, ticked choices, separators or submenus.
The section is yours to describe, and the engine draws it. When the menu opens, the engine asks your handler what to show. When the person chooses a row, the engine tells your handler which one.
Declare it in switchboard.json under adds.menuBarItems:
{
"adds": {
"menuBarItems": [
{ "id": "water", "title": "Water", "icon": "drop", "refreshSeconds": 300 }
]
}
}
And implement it:
import { defineExtension, menuBarItem } from '@switchboard/sdk';
export default defineExtension({
menuBarItems: [
menuBarItem('water', {
build: async (ctx) => ({ title: 'Water: 3', items: [{ id: 'add', title: 'Add a glass' }] }),
click: async (entryId, ctx) => { /* entryId is 'add' */ },
}),
],
});
Gotchas #
buildmust answer within 3 seconds, or the section shows its last answer greyed out.clickhas 10 seconds.ctx.menu.updateonly works for an item this extension declared.Rows with an empty
idor notitleare dropped. Keep ids stable so ticks and clicks stay with the right row.The menu is read as it opens. Do not do slow work in
build; keep the number somewhere cheap (ctx.storage) and read it.No permission is needed to define a section. The handler needs permissions only for what it does itself.
Unknown keys in an entry are refused.
A complete extension using this point can be downloaded from the Full example section and edited: a daily water tally with commands, a ticked submenu and a live title.
Manifest fields #
| Field | Required | What it is |
|---|---|---|
id | yes | Lowercase letters, digits and . _ -, up to 64 characters, starting with a letter. Unique in the list. |
title | yes | 1 to 80 characters. Shown until your handler answers, and greyed if it stops answering. |
description | no | Up to 1000 characters. |
icon | no | 1 to 200 characters. The name of a symbol, used when the handler gives none. |
refreshSeconds | no | A whole number from 1 to 3600. How often the engine asks build again. Without it, only when the menu opens. |
What the handler gets and returns #
build(ctx) returns the section's state:
title: the section's title (up to 120 characters).icon: a symbol name.items: up to 50 rows. A row has anidand atitle, and optionallyenabled: falseto grey it,checked: trueto tick it,childrenfor a submenu (up to three levels), orseparator: trueto draw a line.
With no items, the title is a single clickable row, and a click arrives with the item's own id.
click(entryId, ctx) runs when a row is chosen. It returns nothing. The engine asks build again afterwards. To show the change at once from inside click, or from a timer, call ctx.menu.update(itemId, state) with the same shape build returns.