Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/docs.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'],
],
],

Expand Down
170 changes: 158 additions & 12 deletions resources/views/docs/mobile/4/edge-components/menus.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
> `<native:top-bar>` 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) `<native:top-bar>` render their actions as plain buttons, so `items()` is ignored
> there. An inline `<native:top-bar>` without `custom` takes a menu as nested `<native:top-bar-action>` elements; see
> [Menus in Blade](#menus-in-blade).

## Sections, rows and submenus

<x-docs.version-badge since="4.9" />

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 [`<native:top-bar>`](top-bar) builds the same menu from nested `<native:top-bar-action>` 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
<native:top-bar title="Note">
<native:top-bar-action id="more" icon="ellipsis" a11y-label="More">
<native:top-bar-action row>
<native:top-bar-action id="scan" label="Scan" icon="document_scanner" ios-icon="doc.viewfinder" @tap="scan" />
<native:top-bar-action id="pin" :label="$pinned ? 'Unpin' : 'Pin'" icon="pin" @tap="togglePin" />
<native:top-bar-action id="lock" label="Lock" icon="lock" @tap="lock" />
</native:top-bar-action>

<native:top-bar-action section label="View">
<native:top-bar-action id="paper" label="Lines & Grids" icon="grid_on" ios-icon="squareshape.split.3x3">
<native:top-bar-action id="paper_none" label="None" :checked="$paper === 'none'" @tap="setPaper('none')" />
<native:top-bar-action id="paper_lines" label="Lines" :checked="$paper === 'lines'" @tap="setPaper('lines')" />
<native:top-bar-action id="paper_grid" label="Grid" :checked="$paper === 'grid'" @tap="setPaper('grid')" />
</native:top-bar-action>
</native:top-bar-action>

<native:top-bar-action section>
<native:top-bar-action id="delete" label="Delete" icon="trash" destructive @tap="delete" />
</native:top-bar-action>
</native:top-bar-action>
</native:top-bar>
```
@endverbatim

<aside>

Sections, rows, submenus, subtitles and checkmarks are drawn in nav-bar menus. Menus attached with `:menu` or
`:trailing-menu` still draw a flat list, so keep those to plain items and `NavAction::divider()`.

</aside>

## 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.
31 changes: 30 additions & 1 deletion resources/views/docs/mobile/4/edge-components/top-bar.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,17 @@ On iOS, if more than 5 actions are provided, they collapse into an overflow menu

### `<native:top-bar-action>` 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)

<aside>

Expand All @@ -111,6 +115,31 @@ method on your screen instead of navigating, use `@tap="methodName"`.

</aside>

### Menus

Nest `<native:top-bar-action>` 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
<native:top-bar title="Inbox">
<native:top-bar-action id="more" icon="ellipsis" a11y-label="More">
<native:top-bar-action section label="Sort by">
<native:top-bar-action id="sort_date" label="Date" :checked="$sort === 'date'" @tap="sortBy('date')" />
<native:top-bar-action id="sort_sender" label="Sender" :checked="$sort === 'sender'" @tap="sortBy('sender')" />
</native:top-bar-action>
<native:top-bar-action section>
<native:top-bar-action id="archive_all" label="Archive All" icon="archive" @tap="archiveAll" />
</native:top-bar-action>
</native:top-bar-action>
</native:top-bar>
```
@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

`<native:top-bar-action>` resolves icons through the same contract as [`<native:icon>`](icon#typed-icon-enums): a
Expand Down
5 changes: 4 additions & 1 deletion resources/views/docs/mobile/4/the-basics/layouts.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,10 @@ Any icon you pass to these builders can also be one of your own
- `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

Expand Down
Loading