MenuItem & MenuDivider

Classes for building the right-click context menu on the status bar icon. MenuItem represents a clickable entry with optional icons, shortcuts, submenus, and custom view content. MenuDivider inserts a horizontal separator line between items.

menu

import nib


def main(app: nib.App):
    app.title = "Menu"
    app.icon = nib.SFSymbol("contextualmenu.and.cursorarrow")
    app.width = 300
    app.height = 150

    app.menu = [
        nib.MenuItem("Preferences", icon="gear", shortcut="cmd+,"),
        nib.MenuItem(
            "More Options",
            menu=[
                nib.MenuItem("Option A", badge="3"),
                nib.MenuItem("Option B", shortcut="cmd+R"),
            ],
        ),
        nib.MenuDivider(),
        nib.MenuItem(
            "Quit",
            icon="power",
            shortcut="cmd+Q",
            action=app.quit,
        ),
    ]

    app.build(
        nib.VStack(
            controls=[
                nib.Text("Right-click the status bar icon", font=nib.Font.HEADLINE),
                nib.Text(
                    "to see the context menu.",
                    font=nib.Font.CAPTION,
                    foreground_color=nib.Color.SECONDARY,
                ),
            ],
            spacing=4,
            padding=20,
        )
    )


nib.run(main)

Constructor

nib.MenuItem(
    title=None,
    action=None,
    icon=None,
    content=None,
    menu=None,
    shortcut=None,
    state=None,
    badge=None,
    enabled=True,
    height=None,
)

Parameters

Parameter Type Default Description
title str | None None The menu item text. Optional if content is provided
action Callable[[], None] | None None Callback invoked when the item is clicked
icon str | SFSymbol | None None SF Symbol name as a string (e.g. "gear") or an SFSymbol instance with full configuration
content View | None None Custom view for rich menu item content. Replaces title and icon when provided
menu list[MenuItem] | None None Child items to create a submenu
shortcut str | None None Keyboard shortcut displayed next to the item, e.g. "cmd+q", "cmd+shift+n", "opt+x"
state str | None None Checkmark state indicator. "on" shows a checkmark, "off" shows nothing, "mixed" shows a dash
badge str | None None Badge text shown on the right side of the item (macOS 14+)
enabled bool True Whether the item is clickable. Disabled items appear grayed out
height float | None None Custom height in points for content-based items. Default is auto-sized

Properties

All constructor parameters are stored as public instance attributes and can be read directly:

Property Type Description
title str | None The menu item text
action Callable | None Click callback
icon str | SFSymbol | None Icon configuration
content View | None Custom view content
menu list[MenuItem] Submenu items (empty list if none)
shortcut str | None Keyboard shortcut string
state str | None Checkmark state
badge str | None Badge text
enabled bool Whether the item is enabled
height float | None Custom height

A horizontal separator line between menu items. Takes no parameters.

Constructor

nib.MenuDivider()

Examples

Basic context menu

import nib

def main(app: nib.App):
    app.title = "My App"
    app.icon = nib.SFSymbol("star.fill")
    app.width = 300
    app.height = 200

    def open_settings():
        print("Opening settings")

    app.menu = [
        nib.MenuItem("Settings", action=open_settings, icon="gear", shortcut="cmd+,"),
        nib.MenuDivider(),
        nib.MenuItem("Quit", action=app.quit, shortcut="cmd+q"),
    ]

    app.build(nib.Text("Right-click the menu bar icon", padding=20))

nib.run(main)
import nib

def main(app: nib.App):
    app.title = "Editor"
    app.icon = nib.SFSymbol("doc.text")
    app.width = 300
    app.height = 200

    current_theme = "light"

    def set_theme(name):
        nonlocal current_theme
        current_theme = name
        print(f"Theme set to {name}")

    app.menu = [
        nib.MenuItem(
            "Theme",
            icon="paintbrush",
            menu=[
                nib.MenuItem(
                    "Light",
                    action=lambda: set_theme("light"),
                    state="on" if current_theme == "light" else "off",
                ),
                nib.MenuItem(
                    "Dark",
                    action=lambda: set_theme("dark"),
                    state="on" if current_theme == "dark" else "off",
                ),
            ],
        ),
        nib.MenuItem("Export", icon="square.and.arrow.up", badge="New"),
        nib.MenuItem("Disabled Item", enabled=False),
        nib.MenuDivider(),
        nib.MenuItem("Quit", action=app.quit),
    ]

    app.build(nib.Text("Right-click for menu", padding=20))

nib.run(main)