Summary
A horizontal menu bar widget (src/widgets/menu-bar.sh) with:
- Top-level labels rendered as a bar (Left/Right to navigate, Enter/Down to open)
- Dropdown panel rendered below the active top-level item (Up/Down to navigate, Enter to select, Esc to close)
- Nested submenus — items ending in
> open a second-level panel (Right/Enter to open, Left/Esc to close)
- Separator lines (
--- items) rendered as ────── and skipped during navigation
SHELLFRAME_MENU_RESULT set to the selected path on rc=2 (e.g. "File|Open Recent|file1.db")
Data model
Bash 3.2-compatible naming convention (no associative arrays):
SHELLFRAME_MENU_LABELS=("File" "Edit" "View")
SHELLFRAME_MENU_FILE=("New" "Open" "Open Recent>" "---" "Save" "Quit")
SHELLFRAME_MENU_FILE_OPEN_RECENT=("file1.db" "file2.db" "More...")
Label → variable name: uppercase, spaces to underscores, special chars stripped.
State globals
| Global |
Description |
SHELLFRAME_MENU_ACTIVE |
Top-level cursor index |
SHELLFRAME_MENU_OPEN |
0 = closed, 1 = dropdown open |
SHELLFRAME_MENU_DROPDOWN_IDX |
Cursor in open dropdown |
SHELLFRAME_MENU_SUBMENU_LABEL |
Open submenu label (empty = none) |
SHELLFRAME_MENU_SUBMENU_IDX |
Cursor in open submenu |
SHELLFRAME_MENU_RESULT |
Selected path on rc=2 |
API (v2 contract)
shellframe_menu_init
shellframe_menu_render top left width height
shellframe_menu_on_key key # returns 0 handled / 1 pass / 2 confirm
shellframe_menu_on_focus focused
shellframe_menu_size # preferred: 0×1; min: 10×1
Key bindings
| Context |
Key |
Action |
| Bar |
Left / Right |
Move active top-level item |
| Bar |
Enter / Down |
Open dropdown |
| Bar |
Esc |
Lose focus (rc=1) |
| Dropdown open |
Up / Down |
Move item cursor |
| Dropdown open |
Enter / Right (on > item) |
Open submenu |
| Dropdown open |
Enter (on leaf item) |
Confirm — set RESULT, rc=2 |
| Dropdown open |
Left / Esc |
Close dropdown |
| Submenu open |
Up / Down |
Move submenu cursor |
| Submenu open |
Enter |
Confirm — set RESULT, rc=2 |
| Submenu open |
Left / Esc |
Close submenu |
Deliverables
src/widgets/menu-bar.sh
tests/unit/test-menu-bar.sh
examples/menu-bar.sh
tests/integration/test-menu-bar.sh
- Entry in
docs/showcase.md
- Add to
shellframe.sh source list
Dependencies
#5 selection.sh, #7 clip.sh, #9 panel.sh, #4 input/keymap — all already shipped.
Effort
L (~1 day)
Summary
A horizontal menu bar widget (
src/widgets/menu-bar.sh) with:>open a second-level panel (Right/Enter to open, Left/Esc to close)---items) rendered as──────and skipped during navigationSHELLFRAME_MENU_RESULTset to the selected path on rc=2 (e.g."File|Open Recent|file1.db")Data model
Bash 3.2-compatible naming convention (no associative arrays):
Label → variable name: uppercase, spaces to underscores, special chars stripped.
State globals
SHELLFRAME_MENU_ACTIVESHELLFRAME_MENU_OPENSHELLFRAME_MENU_DROPDOWN_IDXSHELLFRAME_MENU_SUBMENU_LABELSHELLFRAME_MENU_SUBMENU_IDXSHELLFRAME_MENU_RESULTAPI (v2 contract)
Key bindings
>item)Deliverables
src/widgets/menu-bar.shtests/unit/test-menu-bar.shexamples/menu-bar.shtests/integration/test-menu-bar.shdocs/showcase.mdshellframe.shsource listDependencies
#5selection.sh,#7clip.sh,#9panel.sh,#4input/keymap — all already shipped.Effort
L (~1 day)