From eea9041efc0eedd019ade68deef25a8de6746674 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 3 Nov 2026 20:42:06 +0000 Subject: [PATCH 1/2] Document menu sections, rows, submenus, subtitles and checkmarks Covers NavAction::section(), NavAction::row(), ->subtitle(), ->checked() and submenus from nested items(), with a Notes-style example, how each looks on iOS and Android, and the matching Blade props on . Pressable and list-item menus still draw a flat list, which the menus page now says. Co-Authored-By: Claude Opus 5.5 --- .../docs/mobile/4/edge-components/menus.md | 170 ++++++++++++++++-- .../docs/mobile/4/edge-components/top-bar.md | 31 +++- .../views/docs/mobile/4/the-basics/layouts.md | 5 +- 3 files changed, 192 insertions(+), 14 deletions(-) diff --git a/resources/views/docs/mobile/4/edge-components/menus.md b/resources/views/docs/mobile/4/edge-components/menus.md index 86df571fd..c3a418c4d 100644 --- a/resources/views/docs/mobile/4/edge-components/menus.md +++ b/resources/views/docs/mobile/4/edge-components/menus.md @@ -13,7 +13,8 @@ standalone element — you build a list of actions and attach it with an attribu - `items()` on a nav-bar action — see [Menus in the nav bar](#menus-in-the-nav-bar) below. All of them share one item model: an array of `NavAction`, the same builder used -[throughout layouts](../the-basics/layouts#builder-reference). +[throughout layouts](../the-basics/layouts#builder-reference). Nav-bar menus can also be grouped into +[sections, rows and submenus](#sections-rows-and-submenus). ## Building the items @@ -109,21 +110,166 @@ with dividers and destructive tinting, exactly like the inline menus above. This layouts — you can also attach it directly in a layout definition via `NavBar::make()->action(...)` in your layout's `navBar()`. -> **Note** Menus are only supported on nav-bar actions. Bottom-nav / tab-bar items and the inline -> `` element render their actions as plain buttons — `items()` is ignored there. +> **Note** Menus are only supported on nav-bar actions. Bottom-nav / tab-bar items and a +> [`custom`](top-bar#custom-bars) `` render their actions as plain buttons, so `items()` is ignored +> there. An inline `` without `custom` takes a menu as nested `` elements; see +> [Menus in Blade](#menus-in-blade). + +## Sections, rows and submenus + + + +A nav-bar menu doesn't have to be a flat list. You can group items into titled sections, put a compact row of +buttons across the top, nest a submenu, and give any item a subtitle or a checkmark. This menu is laid out like the +one behind the ⋯ button in Apple's Notes app: + +```php +use Native\Mobile\Edge\Layouts\Builders\NavAction; +use Native\Mobile\Edge\Layouts\Builders\NavBarOptions; + +public function navigationOptions(): ?NavBarOptions +{ + return NavBarOptions::make()->action( + NavAction::make('more') + ->icon('ellipsis') + ->a11yLabel('More') + ->items([ + NavAction::row([ + NavAction::make('scan') + ->label('Scan') + ->icon(ios: 'doc.viewfinder', android: 'document_scanner') + ->press('scan'), + NavAction::make('pin') + ->label($this->pinned ? 'Unpin' : 'Pin') + ->icon('pin') + ->press('togglePin'), + NavAction::make('lock')->label('Lock')->icon('lock')->press('lock'), + ]), + NavAction::section(items: [ + NavAction::make('find')->label('Find in Note')->icon('search')->press('find'), + NavAction::make('move') + ->label('Move Note') + ->subtitle($this->folder) + ->icon('folder') + ->press('move'), + ]), + NavAction::section('View', [ + NavAction::make('paper') + ->label('Lines & Grids') + ->icon(ios: 'squareshape.split.3x3', android: 'grid_on') + ->items([ + NavAction::make('paper_none') + ->label('None') + ->checked($this->paper === 'none') + ->press("setPaper('none')"), + NavAction::make('paper_lines') + ->label('Lines') + ->checked($this->paper === 'lines') + ->press("setPaper('lines')"), + NavAction::make('paper_grid') + ->label('Grid') + ->checked($this->paper === 'grid') + ->press("setPaper('grid')"), + ]), + NavAction::make('attachments') + ->label('Show Attachments') + ->icon(ios: 'paperclip', android: 'attach_file') + ->checked($this->showAttachments) + ->press('toggleAttachments'), + ]), + NavAction::section(items: [ + NavAction::make('delete')->label('Delete')->icon('trash')->press('delete')->destructive(), + ]), + ]) + ); +} +``` + +Here's what each piece does: + +- `NavAction::row([...])` puts its items side by side across the top of the menu, each with its icon above a short + label. A row fits a few items, so keep the labels short. +- `NavAction::section('View', [...])` groups its items under a heading. Use `NavAction::section(items: [...])` for a + group with no heading. It still gets separated from the items around it. +- An item with its own `items()` is a submenu. `Lines & Grids` above opens a submenu of paper styles. +- `subtitle()` adds a second, smaller line under an item's label. Here it shows the folder the note is in. +- `checked()` puts a checkmark on an item. Pass it a boolean from your screen's state, like the paper styles do, and + the checkmark moves when the state changes. + +Rows and sections are containers, not tappable items. Their ids are fixed placeholders (`row` and `section`, like +`divider` for a divider), and they ignore `icon()`, `press()` and the other item methods. Give each item inside them +its own unique id. + +### How they look on each platform + +On iOS, the menu is a native `UIMenu`. Sections are drawn inline, with the title as a small heading above the group +and a separator line between groups. The row uses UIKit's medium element size: each item is a small button with its +icon above its label, the same as the Scan, Pin and Lock buttons in Notes. A submenu shows a chevron and opens in +place over the menu it came from. Checked items get the system checkmark, and destructive items are red. + +On Android, the menu is a Material dropdown. A divider separates each section from the items around it, and the +section's title shows as a small heading. The row is a line of buttons, each with an icon and a label. Tapping a +submenu replaces the dropdown's items with the submenu's, with a back row at the top to return to the previous +level. Checked items show a check mark at the end of the item, and a subtitle sits under the label in a smaller, +quieter style. + +### Menus in Blade + +An inline [``](top-bar) builds the same menu from nested `` elements. Add +`section` (with an optional `label` for its heading) or `row` to an action to make it a container, and nest actions +inside an item to make a submenu. `subtitle` and `checked` are attributes like any other: + +@verbatim +```blade + + + + + + + + + + + + + + + + + + + + + +``` +@endverbatim + + ## Item reference The menu-relevant `NavAction` methods: -- `make(string $id)` — create an item with a unique id -- `icon(?string $name = null, ios:, android:)` — a leading [icon](icon) -- `label(string)` — the row text -- `press(string $method)` — the component method to call when chosen -- `url(string)` — navigate to a URL instead of calling a method -- `items(array $items)` — sub-items that turn a nav-bar action into a pull-down menu (nav-bar actions only) -- `a11yLabel(string)` — screen-reader label for icon-only actions -- `destructive(bool = true)` — tint the item as destructive -- `NavAction::divider()` — a separator row +- `make(string $id)` - create an item with a unique id +- `icon(?string $name = null, ios:, android:)` - a leading [icon](icon) +- `label(string)` - the item's text +- `subtitle(string)` - a second, smaller line under the label (nav-bar menus) +- `press(string $method)` - the component method to call when chosen +- `url(string)` - navigate to a URL instead of calling a method +- `items(array $items)` - sub-items that turn a nav-bar action into a pull-down menu, or an item inside one into a + submenu (nav-bar actions only) +- `a11yLabel(string)` - screen-reader label for icon-only actions +- `destructive(bool = true)` - tint the item as destructive +- `checked(bool = true)` - show a checkmark on the item (nav-bar menus) +- `NavAction::divider()` - a separator row +- `NavAction::section(?string $title = null, array $items = [])` - an inline group of items under an optional heading + (nav-bar menus) +- `NavAction::row(array $items)` - a compact row of icon-over-label buttons (nav-bar menus) See the [`NavAction` builder](../the-basics/layouts#builder-reference) for the full list. diff --git a/resources/views/docs/mobile/4/edge-components/top-bar.md b/resources/views/docs/mobile/4/edge-components/top-bar.md index f798080cf..45d92e436 100644 --- a/resources/views/docs/mobile/4/edge-components/top-bar.md +++ b/resources/views/docs/mobile/4/edge-components/top-bar.md @@ -96,13 +96,17 @@ On iOS, if more than 5 actions are provided, they collapse into an overflow menu ### `` Props -- `id` - Unique identifier (required) +- `id` - Unique identifier (required, except on a `section` or `row`) - `icon` - A named [icon](icon#icon-name-reference) — the cross-platform fallback (optional if a platform icon is given) - `ios-icon` / `android-icon` - Per-platform icon overrides: an enum case (`App\Icons\Ios`, `App\Icons\Android`, `App\Icons\AndroidOutlined`) or a raw symbol string. `ios` / `android` are accepted as shorthand (optional). See [Platform icons](#platform-icons) - `material-variant` - Material style hint for Android, e.g. `outlined` (optional). Set automatically when you use an `AndroidOutlined` enum case - `label` - Text label. Used for accessibility and displayed in overflow menus (optional but recommended) - `url` - A URL to navigate to when tapped (optional) - `destructive` - Render in the destructive (red) tint (optional, boolean) +- `subtitle` - A second, smaller line under the label, for an action inside a menu (optional, string) +- `checked` - Show a checkmark, for an action inside a menu (optional, boolean) +- `section` - Group the actions nested inside this one, with `label` as the heading (optional, boolean). See [Menus](#menus) +- `row` - Show the actions nested inside this one as a compact row of icon-over-label buttons (optional, boolean). See [Menus](#menus) +### Menus + +Nest `` elements inside an action and it opens a pull-down menu of them instead of firing a +press. Inside a menu, an action with its own nested actions is a submenu, and the `section` and `row` attributes +group items the way [`NavAction::section()` and `NavAction::row()`](menus#sections-rows-and-submenus) do: + +@verbatim +```blade static + + + + + + + + + + + +``` +@endverbatim + +See [Menus](menus#menus-in-blade) for a full example and how menus look on each platform. A `custom` bar draws its +actions as plain buttons and ignores nested actions. + ### Platform icons `` resolves icons through the same contract as [``](icon#typed-icon-enums): a diff --git a/resources/views/docs/mobile/4/the-basics/layouts.md b/resources/views/docs/mobile/4/the-basics/layouts.md index 517dd4271..0590389ff 100644 --- a/resources/views/docs/mobile/4/the-basics/layouts.md +++ b/resources/views/docs/mobile/4/the-basics/layouts.md @@ -143,7 +143,10 @@ in a screen's Blade. - `press(string $method)` — screen method to call when tapped - `url(string)` — navigate to a URL when tapped; `event(string)` — dispatch a native event (advanced) - `destructive(bool = true)` — render in the destructive tint -- `items(array $actions)` — nest `NavAction`s to render a pull-down menu; `NavAction::divider()` adds a separator +- `items(array $actions)` — nest `NavAction`s to render a pull-down menu; `NavAction::divider()` adds a separator, + `NavAction::section($title, $items)` groups items under a heading, `NavAction::row($items)` adds a compact row of + buttons, and an item with its own `items()` opens a submenu. See [Sections, rows and submenus](../edge-components/menus#sections-rows-and-submenus) +- `subtitle(string)` and `checked(bool = true)` add a second line and a checkmark to an item inside a menu #### Custom title view / logo From f514499f8dc6a22bd46b68f7187edb11b5bd8524 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Sat, 14 Nov 2026 16:51:18 +0000 Subject: [PATCH 2/2] Label menu sections for Mobile 4.9 and list 4.8 and 4.9 as released 4.8.0 shipped without the menu work, so the section's badge moves to the release it lands in. Lists 4.8 (out now) and 4.9 so the badge passes the version test, the way earlier release docs did. Co-Authored-By: Claude Opus 5.5 --- config/docs.php | 2 +- resources/views/docs/mobile/4/edge-components/menus.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/docs.php b/config/docs.php index c1e7695dd..788c1388e 100644 --- a/config/docs.php +++ b/config/docs.php @@ -59,7 +59,7 @@ 1 => ['1.0', '1.1'], 2 => ['2.0'], 3 => ['3.0', '3.1', '3.2', '3.3'], - 4 => ['4.0', '4.1', '4.2', '4.3', '4.4', '4.5', '4.6', '4.7'], + 4 => ['4.0', '4.1', '4.2', '4.3', '4.4', '4.5', '4.6', '4.7', '4.8', '4.9'], ], ], diff --git a/resources/views/docs/mobile/4/edge-components/menus.md b/resources/views/docs/mobile/4/edge-components/menus.md index c3a418c4d..5d6162b39 100644 --- a/resources/views/docs/mobile/4/edge-components/menus.md +++ b/resources/views/docs/mobile/4/edge-components/menus.md @@ -117,7 +117,7 @@ layout's `navBar()`. ## Sections, rows and submenus - + A nav-bar menu doesn't have to be a flat list. You can group items into titled sections, put a compact row of buttons across the top, nest a submenu, and give any item a subtitle or a checkmark. This menu is laid out like the