diff --git a/resources/views/docs/mobile/4/digging-deeper/accessibility.md b/resources/views/docs/mobile/4/digging-deeper/accessibility.md
index 101fca66..1c4e698f 100644
--- a/resources/views/docs/mobile/4/digging-deeper/accessibility.md
+++ b/resources/views/docs/mobile/4/digging-deeper/accessibility.md
@@ -20,7 +20,7 @@ Every element accepts two attributes:
- `a11y-hint` - Supplementary usage guidance, announced after the label (e.g. "Double-tap to open settings").
@verbatim
-```blade
+```blade static
```
@@ -48,7 +48,7 @@ isn't descriptive enough on its own.
mystery to screen reader users.
@verbatim
-```blade
+```blade static
{{-- Bad: VoiceOver has nothing meaningful to announce --}}
@@ -63,7 +63,7 @@ Standalone `` elements are **decorative by default** — they are
unless you give them an `a11y-label`. If an icon conveys meaning on its own (or is tappable), label it:
@verbatim
-```blade
+```blade static
```
@endverbatim
@@ -72,7 +72,7 @@ Images take an `alt` attribute, mirroring the web. With `alt`, the image is anno
is treated as decorative and skipped:
@verbatim
-```blade
+```blade static
```
@endverbatim
@@ -82,7 +82,7 @@ is treated as decorative and skipped:
The tappable trailing icon button on a [list item](../edge-components/list) takes its own label via `trailing-a11y-label`:
@verbatim
-```blade
+```blade static
```
@endverbatim
@@ -52,7 +52,7 @@ useful for text inputs where syncing on every character is wasteful:
| `native:model.debounce.300ms` | After the user stops changing it for the given delay. |
@verbatim
-```blade
+```blade static
{{-- Sync only when the user leaves the field --}}
@@ -87,7 +87,7 @@ properties, derive the rest with computed methods, and let the UI re-render itse
something other than a public property — set the value and change handler directly:
@verbatim
-```blade
+```blade static
```
@endverbatim
diff --git a/resources/views/docs/mobile/4/digging-deeper/gestures.md b/resources/views/docs/mobile/4/digging-deeper/gestures.md
index 1e559dce..6bf8fc3c 100644
--- a/resources/views/docs/mobile/4/digging-deeper/gestures.md
+++ b/resources/views/docs/mobile/4/digging-deeper/gestures.md
@@ -17,7 +17,7 @@ If you've used Reanimated in React Native, this is the same idea.
Create one in PHP with `SharedValue::make($initial)`, bind it to a gesture, and read it from any animatable prop:
@verbatim
-```blade
+```blade static
@php $drag = \Native\Mobile\Edge\SharedValue::make(); @endphp
@@ -68,7 +68,7 @@ change in `animate-duration` (milliseconds) and the element eases from its old v
render. The animatable props are `translate-x`, `translate-y`, `scale`, `rotate`, and `opacity`:
@verbatim
-```blade
+```blade static
{{-- A panel slides up from below when $shown flips to true --}}
@@ -113,7 +113,7 @@ back on release:
- `press-translate-y` — nudge down while pressed (e.g. `3`)
@verbatim
-```blade
+```blade static
Press me
diff --git a/resources/views/docs/mobile/4/digging-deeper/lifecycle-hooks.md b/resources/views/docs/mobile/4/digging-deeper/lifecycle-hooks.md
index b5c2807b..981cdfa3 100644
--- a/resources/views/docs/mobile/4/digging-deeper/lifecycle-hooks.md
+++ b/resources/views/docs/mobile/4/digging-deeper/lifecycle-hooks.md
@@ -103,7 +103,7 @@ Livewire's updated hooks. The hook name is `updated` + the studly-cased property
value.
@verbatim
-```blade
+```blade static
```
@endverbatim
diff --git a/resources/views/docs/mobile/4/digging-deeper/reactivity.md b/resources/views/docs/mobile/4/digging-deeper/reactivity.md
index a1e1a690..fa5faa09 100644
--- a/resources/views/docs/mobile/4/digging-deeper/reactivity.md
+++ b/resources/views/docs/mobile/4/digging-deeper/reactivity.md
@@ -32,7 +32,7 @@ class CartScreen extends NativeComponent
Access it as `$this->total` (no parentheses) in PHP, or `@{{ $this->total }}` in the view:
@verbatim
-```blade
+```blade static
Total: {{ $this->total }}
```
@endverbatim
@@ -82,7 +82,7 @@ You can also drive a re-render from the view with `native:poll` — useful for a
without wiring a method:
@verbatim
-```blade
+```blade static
{{ now()->format('g:i:s A') }}
```
@endverbatim
diff --git a/resources/views/docs/mobile/4/digging-deeper/theming.md b/resources/views/docs/mobile/4/digging-deeper/theming.md
index 5d16cd83..88450495 100644
--- a/resources/views/docs/mobile/4/digging-deeper/theming.md
+++ b/resources/views/docs/mobile/4/digging-deeper/theming.md
@@ -77,7 +77,7 @@ preserves the alpha byte.
Reference any token from Blade with the `theme-{token}` class suffix, on background, text, and border utilities:
@verbatim
-```blade
+```blade static
BalanceUpdated just now
diff --git a/resources/views/docs/mobile/4/edge-components/activity-indicator.md b/resources/views/docs/mobile/4/edge-components/activity-indicator.md
index 3b418fd4..da264840 100644
--- a/resources/views/docs/mobile/4/edge-components/activity-indicator.md
+++ b/resources/views/docs/mobile/4/edge-components/activity-indicator.md
@@ -39,18 +39,21 @@ a non-theme-styled container (e.g. a light spinner over a dark image overlay).
@verbatim
```blade
-
+Loading...
```
@endverbatim
+On a real loading screen, use `` at the page root instead — the fixed `h-[200]` here just
+gives the example a bounded area to center in.
+
### Inline loading
@verbatim
```blade
-
+Refreshing
diff --git a/resources/views/docs/mobile/4/edge-components/badge.md b/resources/views/docs/mobile/4/edge-components/badge.md
index 993b5e62..37c569f4 100644
--- a/resources/views/docs/mobile/4/edge-components/badge.md
+++ b/resources/views/docs/mobile/4/edge-components/badge.md
@@ -8,8 +8,8 @@ order: 110
A small count or text marker, typically used as an overlay on nav items, list rows, or buttons. Renders as a capsule
pill.
-Colors come from the theme via the semantic `variant` prop by default. To override them per instance, apply `bg-*`
-classes for the fill and `rounded-*` classes to adjust the capsule radius.
+Colors come from the theme via the semantic `variant` prop — `destructive` (the default), `primary`, or `accent`.
+Prefer `variant` for badge colors: it keeps the label legible on both platforms and in both light and dark themes.
@verbatim
```blade
@@ -41,7 +41,7 @@ icon, see the `badge` and `news` props on [``](bottom-na
@verbatim
```blade
-
+
@@ -58,19 +58,40 @@ icon, see the `badge` and `news` props on [``](bottom-na
### Anchored to an icon
-Use a [``](stack) to layer the badge over its target:
+Use a [``](stack) to layer the badge over its target. Size the stack a little larger than the
+icon so the badge has a corner to sit in, and position it with positive `top-*` / `right-*` insets — the
+renderer anchors an absolute child to whichever edges you set (negative insets are not supported):
@verbatim
```blade
-
+
```
@endverbatim
+### Custom background (iOS only)
+
+On iOS you can override the capsule fill with a `bg-*` class and the radius with a `rounded-*` class:
+
+@verbatim
+```blade static
+
+```
+@endverbatim
+
+
+
## Element
```php
diff --git a/resources/views/docs/mobile/4/edge-components/bottom-nav.md b/resources/views/docs/mobile/4/edge-components/bottom-nav.md
index fdf258bd..9836bf46 100644
--- a/resources/views/docs/mobile/4/edge-components/bottom-nav.md
+++ b/resources/views/docs/mobile/4/edge-components/bottom-nav.md
@@ -20,8 +20,10 @@ order: 120
A bottom navigation bar with up to 5 items. Used for your app's primary navigation.
+One bar demonstrates the whole item API — an `active` tab, a `news` dot, and a `badge`:
+
@verbatim
-```blade
+```blade static
+ ` can contain up to 5 `` elements.
### Props
- `id` - Unique identifier (required)
-- `icon` - A named [icon](icons) (required)
+- `icon` - A named [icon](icon#icon-name-reference) (required)
- `label` - Accessibility label (required)
- `url` - A URL to navigate to in the web view (required)
- `active` - Highlight this item as active (optional, default: `false`)
@@ -84,7 +95,7 @@ Any `url` that doesn't match a registered native route will exit to the web view
-### `badge` example
+Here's `badge` on a tab item:
@@ -95,23 +106,23 @@ Any `url` that doesn't match a registered native route will exit to the web view
## Builder API
When a `` is supplied by a [layout](../the-basics/layouts), you build it fluently with the `TabBar`
-and `Tab` builders rather than writing it in Blade.
+and `Tab` builders rather than writing it in Blade. This is the same bar as the [Overview](#overview) example:
```php
use Native\Mobile\Edge\Layouts\Builders\Tab;
use Native\Mobile\Edge\Layouts\Builders\TabBar;
TabBar::make()
- ->dark()
- ->activeColor('#0891b2')
->labelVisibility('labeled')
- ->backgroundColor('#0F172A')
- ->textColor('#94A3B8')
- ->add(Tab::link('Chats', '/syncup', icon: 'chat_bubble')->badge('2'))
- ->add(Tab::link('Friends', '/syncup/friends', icon: 'person.3.fill')->news())
- ->add(Tab::link('Profile', '/syncup/profile', icon: 'person')->active());
+ ->activeColor('#0891b2')
+ ->add(Tab::link('Home', '/home', icon: 'home')->active())
+ ->add(Tab::link('Friends', '/friends', icon: 'person.3.fill')->news())
+ ->add(Tab::link('Profile', '/profile', icon: 'person')->badge('3'));
```
+To force a dark bar regardless of the system theme, chain `->dark()` — or take full control with
+`->backgroundColor('#0F172A')->textColor('#94A3B8')`, which wins over `dark()`'s default.
+
### `TabBar` methods
- `make()` - Create a new builder
@@ -126,7 +137,7 @@ TabBar::make()
- `link(string $label, string $url, ?string $icon = null)` - Build a tab. The id defaults to the label slugified
- `id(string $id)` - Override the auto-generated id
-- `icon(string $icon)` - A named [icon](icons)
+- `icon(string $icon)` - A named [icon](icon#icon-name-reference)
- `badge(string $badge, ?string $color = null)` - Show a numeric/text badge
- `news(bool $news = true)` - Show a red dot indicator
- `active(bool $active = true)` - Mark this tab as active
diff --git a/resources/views/docs/mobile/4/edge-components/bottom-sheet.md b/resources/views/docs/mobile/4/edge-components/bottom-sheet.md
index 0ff6faa3..a8b875b6 100644
--- a/resources/views/docs/mobile/4/edge-components/bottom-sheet.md
+++ b/resources/views/docs/mobile/4/edge-components/bottom-sheet.md
@@ -9,7 +9,7 @@ A modal panel that slides up from the bottom of the screen. Use it for contextua
that overlay the main content. Renders as SwiftUI's `.sheet` with `presentationDetents` on iOS and a Material3
`ModalBottomSheet` on Android.
-Per Model 3, the container color resolves from `theme.surface`. For a custom surface wrap content in a
+Per Material 3, the container color resolves from `theme.surface`. For a custom surface wrap content in a
``.
@verbatim
@@ -64,21 +64,21 @@ Accepts any EDGE elements as children. The children are rendered inside the shee
-
+ Edit
-
+ Share
-
+ Delete
@@ -107,7 +107,7 @@ Accepts any EDGE elements as children. The children are rendered inside the shee
Add Item
-
+
diff --git a/resources/views/docs/mobile/4/edge-components/button-group.md b/resources/views/docs/mobile/4/edge-components/button-group.md
index dbe8253c..f71a5d32 100644
--- a/resources/views/docs/mobile/4/edge-components/button-group.md
+++ b/resources/views/docs/mobile/4/edge-components/button-group.md
@@ -13,10 +13,16 @@ Use this for short, mutually-exclusive choices that fit on one row. For more opt
@verbatim
```blade
+@php $period = 0; @endphp
+
+
+Showing {{ ['Daily', 'Weekly', 'Monthly'][$period] }} stats
```
@endverbatim
+`period` is a public int property on your component — the `@php` line stands in for `public int $period = 0;`. Tapping a segment syncs the new index back automatically, so anything echoing `$period` re-renders.
+
## Props
- `options` - Array of option labels (required, array of strings)
@@ -32,11 +38,16 @@ Use this for short, mutually-exclusive choices that fit on one row. For more opt
## Two-way Binding
-`native:model` binds the selected index to an integer property on your component:
+`native:model` binds the selected index to an integer property on your component — declare it as
+`public int $planTier = 1;` and the group keeps it in sync:
@verbatim
```blade
+@php $planTier = 1; @endphp
+
+
+Selected plan: {{ $tiers[$planTier] }}
```
@endverbatim
@@ -44,24 +55,38 @@ Use this for short, mutually-exclusive choices that fit on one row. For more opt
### Period picker
+`reportRange` is a public int property on your component (`public int $reportRange = 2;`):
+
@verbatim
```blade
+@php $reportRange = 2; @endphp
+
+
+Report range: {{ ['Day', 'Week', 'Month', 'Year'][$reportRange] }}
```
@endverbatim
### With manual change handler
+Instead of `native:model`, pass the current index with `:value` and handle changes yourself.
+`$difficulty` is a public int property on your component, and `setDifficulty(int $index)` is the
+method that receives the new index — assign it to `$difficulty` there:
+
@verbatim
```blade
+@php $difficulty = 1; @endphp
+
+
+Difficulty: {{ ['Easy', 'Medium', 'Hard'][$difficulty] }}
```
@endverbatim
diff --git a/resources/views/docs/mobile/4/edge-components/button.md b/resources/views/docs/mobile/4/edge-components/button.md
index 1bf0478a..ffc1c318 100644
--- a/resources/views/docs/mobile/4/edge-components/button.md
+++ b/resources/views/docs/mobile/4/edge-components/button.md
@@ -17,6 +17,8 @@ control drop to a [``](pressable) wrapping your own content.
```
@endverbatim
+`@press` names a public method on your component — tapping this button calls `handleStart()`.
+
## Props
The label can be passed as the `label` attribute or as slot content between the tags. If both are set, `label` wins.
@@ -28,8 +30,8 @@ Slot content is treated as plain text — nested tags are stripped and whitespac
token solid; for a softer tonal fill, set opacity on the token itself (e.g. `'secondary' => 'fuchsia-500/70'`
in `config/native-ui.php`) — see [Theming](../digging-deeper/theming)
- `size` - `sm`, `md` (default), `lg`
-- `icon` - A leading [icon](icons) name (optional)
-- `icon-trailing` - A trailing [icon](icons) name (optional)
+- `icon` - A leading [icon](icon#icon-name-reference) name (optional)
+- `icon-trailing` - A trailing [icon](icon#icon-name-reference) name (optional)
- `font` - Custom font for the label from `resources/fonts/`, by filename without extension (optional, string) — see [Text › Custom fonts](text#custom-fonts)
- `line-height` - Label line height as a multiplier of the font size (optional, float)
- `line-height-px` - Label line height as an absolute value in pixels (optional, float)
@@ -73,7 +75,7 @@ attributes are intentionally dropped before reaching the renderer.
@verbatim
```blade
-
+
diff --git a/resources/views/docs/mobile/4/edge-components/canvas.md b/resources/views/docs/mobile/4/edge-components/canvas.md
index 63c56d63..bae76506 100644
--- a/resources/views/docs/mobile/4/edge-components/canvas.md
+++ b/resources/views/docs/mobile/4/edge-components/canvas.md
@@ -10,13 +10,16 @@ children stack vertically by default. Use it as a semantic wrapper when grouping
@verbatim
```blade
-
-
+
+
```
@endverbatim
+Shapes take their fill from a `bg` attribute or any `bg-*` class (including `bg-theme-*` tokens), and corner
+rounding from `rounded-*` classes.
+
## Props
All [shared layout and style attributes](layout) are supported. There are no canvas-specific props.
@@ -29,6 +32,66 @@ Accepts any EDGE elements as children. Typically used with [shape primitives](sh
For overlay-style layering of shapes use a [``](stack) instead — `` arranges children
along the column main axis, which is rarely what you want for free-form drawing.
+## Examples
+
+### Mini bar chart
+
+Shapes plus flex layout are enough for lightweight data graphics. A bottom-aligned row of rects with varying
+heights makes a bar chart — vary the `opacity-*` class to get a tonal ramp from a single theme color:
+
+@verbatim
+```blade
+
+
+
+
+
+
+
+
+```
+@endverbatim
+
+In a real app you'd generate the rects with `@foreach` over a public array property on your component and
+compute each `:height` from the data point.
+
+### Pulsing beacon
+
+Transform attributes (`:scale`, `:rotate`, `:translate-x`, `:translate-y`) combine with `animate-loop` and
+`:animate-duration` to produce continuous, auto-reversing animations. Layer an animated circle behind a static
+one in a stack to get a pulsing status beacon:
+
+@verbatim
+```blade
+
+
+
+
+
+
+```
+@endverbatim
+
+The loop oscillates the outer circle between its resting state and the declared `:scale` (and `opacity-*`),
+reversing each cycle. `:animate-duration` is in milliseconds; add `animate-easing` to change the curve.
+
+### Concentric rings
+
+Layering same-center circles of decreasing size in a stack gives a bullseye — again using opacity steps of one
+theme color so it works in both light and dark mode:
+
+@verbatim
+```blade
+
+
+
+
+
+
+
+```
+@endverbatim
+
## Element
```php
diff --git a/resources/views/docs/mobile/4/edge-components/carousel.md b/resources/views/docs/mobile/4/edge-components/carousel.md
index 21eb6e5d..16f6eb60 100644
--- a/resources/views/docs/mobile/4/edge-components/carousel.md
+++ b/resources/views/docs/mobile/4/edge-components/carousel.md
@@ -12,8 +12,8 @@ stack with `item-spacing` between items.
```blade
@foreach($posts as $post)
-
- {{ $post->title }}
+
+ {{ $post->title }}{{ $post->excerpt }}
@endforeach
@@ -66,14 +66,23 @@ wrapping a [``](row).
@foreach($contacts as $contact)
-
- {{ $contact->name }}
+
+
+ {{ $contact->initials }}
+
+
+
+ {{ $contact->name }}
@endforeach
```
@endverbatim
+Use `rounded-full` (a class) to make the avatar circular — the `border-radius` *attribute* is not
+read on images. The initials layer underneath the image acts as a fallback: it shows while the
+avatar is loading, or whenever `$contact->avatar` is empty.
+
## Element
```php
diff --git a/resources/views/docs/mobile/4/edge-components/checkbox.md b/resources/views/docs/mobile/4/edge-components/checkbox.md
index e0a57516..12e8423e 100644
--- a/resources/views/docs/mobile/4/edge-components/checkbox.md
+++ b/resources/views/docs/mobile/4/edge-components/checkbox.md
@@ -9,14 +9,21 @@ A binary tick/untick control with an optional inline label. On iOS, renders as a
(`checkmark.square.fill` / `square`) — SwiftUI has no native checkbox primitive. On Android, renders as a Material3
`Checkbox`.
-Per Model 3, check/border/label colors come from the theme — no per-instance overrides.
+Per Material 3, check/border/label colors come from the theme — no per-instance overrides.
@verbatim
```blade
+@php $agreed = false; @endphp
+
+
+{{ $agreed ? 'Thanks for agreeing!' : 'Tap the box to agree' }}
```
@endverbatim
+Here `agreed` is a public boolean property on your component — the `@php` line stands in for
+`public bool $agreed = false;`. Toggling the box syncs the new state back automatically.
+
## Props
- `value` - Current checked state (optional, boolean, default: `false`)
@@ -39,30 +46,48 @@ Margin classes position the checkbox; the check, border, and label colors come f
## Two-way Binding
-Use `native:model` for automatic two-way binding with a boolean property on your component. The `live`, `blur`,
-and `debounce` modifiers set `sync-mode` (and `debounce-ms`) for you, though for a discrete tap every toggle is a
-single event.
+Use `native:model` for automatic two-way binding with a public boolean property on your component. The `live`,
+`blur`, and `debounce` modifiers set `sync-mode` (and `debounce-ms`) for you, though for a discrete tap every
+toggle is a single event.
@verbatim
```blade
-
+@php $subscribed = true; @endphp
+
+
+
+{{ $subscribed ? 'You are subscribed' : 'Not subscribed' }}
```
@endverbatim
+`subscribed` is a public boolean property on your component (the `@php` line stands in for
+`public bool $subscribed = true;`). Every toggle syncs the new value back, so the `{{ $subscribed }}` echo
+updates as soon as you tap.
+
## Examples
### Multiple options
@verbatim
```blade
+@php
+ $emailNotifications = true;
+ $smsNotifications = false;
+ $pushNotifications = true;
+@endphp
+
+
+ Enabled: {{ ($emailNotifications ? 1 : 0) + ($smsNotifications ? 1 : 0) + ($pushNotifications ? 1 : 0) }} of 3
```
@endverbatim
+Each checkbox binds its own public boolean property; the summary line re-renders on every toggle.
+
### Disabled
@verbatim
diff --git a/resources/views/docs/mobile/4/edge-components/chip.md b/resources/views/docs/mobile/4/edge-components/chip.md
index 354e608e..d21c5b52 100644
--- a/resources/views/docs/mobile/4/edge-components/chip.md
+++ b/resources/views/docs/mobile/4/edge-components/chip.md
@@ -13,15 +13,20 @@ fully rounded and can be adjusted with `rounded-*` classes.
@verbatim
```blade
+@php $filterVerified = false; @endphp
+
```
@endverbatim
+`filterVerified` is a public boolean property on your component — the `@php` line stands in for
+`public bool $filterVerified = false;`.
+
## Props
- `label` - Chip text (optional, string). Can also be passed as the first argument to `make()`
- `selected` / `value` - Whether the chip is active (optional, boolean, default: `false`)
-- `icon` - Leading [icon](icons) name (optional, string)
+- `icon` - Leading [icon](icon#icon-name-reference) name (optional, string)
- `disabled` - Disable the chip (optional, boolean, default: `false`)
- `a11y-label` - Accessibility label (optional)
- `a11y-hint` - Accessibility hint (optional)
@@ -36,17 +41,28 @@ fully rounded and can be adjusted with `rounded-*` classes.
@verbatim
```blade
+@php $filterOnSale = false; @endphp
+
+
+
+ {{ $filterOnSale ? 'Showing sale items only' : 'Showing everything' }}
+
```
@endverbatim
+Toggling the chip syncs the new boolean back to `filterOnSale` automatically, and anything that reads the
+property — like the `{{ $filterOnSale ? ... }}` echo above — re-renders with the new value.
+
## Examples
### Filter chip row
@verbatim
```blade
-
+@php $filter = 'all'; @endphp
+
+
@@ -54,10 +70,15 @@ fully rounded and can be adjusted with `rounded-*` classes.
```
@endverbatim
+Here `$filter` is a public string property and `setFilter()` is a public method on your component that assigns it —
+driving `selected` from one property keeps the row single-select.
+
### With icon
@verbatim
```blade
+@php $onlyVerified = false; @endphp
+
```
@endverbatim
diff --git a/resources/views/docs/mobile/4/edge-components/column.md b/resources/views/docs/mobile/4/edge-components/column.md
index 67ad083d..23773244 100644
--- a/resources/views/docs/mobile/4/edge-components/column.md
+++ b/resources/views/docs/mobile/4/edge-components/column.md
@@ -42,8 +42,23 @@ Everything else from the shared list applies the same as on any element (`w-*`,
### Full-screen layout with safe area
+A column at the page root typically fills the screen and pushes actions to the bottom with a spacer:
+
@verbatim
```blade
+
+ My App
+
+
+
+```
+@endverbatim
+
+The full-screen version below adds `safe-area` at the page root so content clears the notch and home
+indicator — run it in your app to see it edge-to-edge:
+
+@verbatim
+```blade static
My App
@@ -80,16 +95,21 @@ Everything else from the shared list applies the same as on any element (`w-*`,
### Space-between distribution
+`justify-between` spreads children across the column's height, placing the leftover space between them:
+
@verbatim
```blade
-
- Top
- Middle
- Bottom
+
+ Top
+ Middle
+ Bottom
```
@endverbatim
+Distribution needs a bounded height to work with — on a real screen you would typically use `h-full` at the
+page root; the fixed `h-[220]` here just gives the preview a bounded height to distribute.
+
## Element
```php
diff --git a/resources/views/docs/mobile/4/edge-components/gesture-area.md b/resources/views/docs/mobile/4/edge-components/gesture-area.md
index 7e29ddbf..63da331e 100644
--- a/resources/views/docs/mobile/4/edge-components/gesture-area.md
+++ b/resources/views/docs/mobile/4/edge-components/gesture-area.md
@@ -10,7 +10,7 @@ Captures a vertical pan/drag gesture over its content and writes the translation
Children render normally — gesture detection wraps the whole content frame.
@verbatim
-```blade
+```blade static
@php $drag = \Native\Mobile\Edge\SharedValue::make(); @endphp
@@ -21,6 +21,10 @@ Children render normally — gesture detection wraps the whole content frame.
```
@endverbatim
+This example needs a real app to try out: the drag runs entirely on the UI thread against a live
+`SharedValue` bound from your component, so there's no inline preview here — drop the snippet into a
+screen in your app and drag the card.
+
## Props
- `pan-y` - A [`SharedValue`](../digging-deeper/gestures) that receives the vertical drag translation (required for
diff --git a/resources/views/docs/mobile/4/edge-components/icon.md b/resources/views/docs/mobile/4/edge-components/icon.md
index fef4c425..03fd6547 100644
--- a/resources/views/docs/mobile/4/edge-components/icon.md
+++ b/resources/views/docs/mobile/4/edge-components/icon.md
@@ -5,12 +5,14 @@ order: 230
## Overview
-Displays a platform-native icon. On iOS, icons render as SF Symbols. On Android, icons render as Material Icons.
-A smart mapping system translates common icon names across platforms automatically.
+Displays a platform-native icon. On iOS, icons render as [SF Symbols](https://developer.apple.com/sf-symbols/);
+on Android, as [Material Icons](https://fonts.google.com/icons?icon.set=Material+Icons). You don't need to worry about
+the differences — use one consistent icon name and EDGE's smart mapping system translates it to the right platform
+symbol automatically.
@verbatim
```blade
-
+
```
@endverbatim
@@ -18,11 +20,11 @@ A smart mapping system translates common icon names across platforms automatical
All [shared layout and style attributes](layout) are supported, plus:
-- `name` - Icon name (required unless `ios`/`android` are given, string). See the [Icons](icons) reference
-- `ios` / `android` - Per-platform overrides: an [SF Symbol](icons) name for iOS and a [Material Icon](icons) name
+- `name` - Icon name (required unless `ios`/`android` are given, string). See the [Icon name reference](#icon-name-reference)
+- `ios` / `android` - Per-platform overrides: an [SF Symbol](#ios-sf-symbols) name for iOS and a [Material Icon](#android-material-icons) name
for Android, so one tag renders the right symbol on each platform. Use in place of `name` when the platforms
need different icons (``). When bound with `:ios` / `:android`,
- these also accept enum cases directly — `:ios="Ios::Gearshape"`, `:android="Android::Settings"`
+ these also accept enum cases directly — see [Typed icon enums](#typed-icon-enums)
- `size` - Icon size in dp (optional, float, default: `24`)
- `color` - Icon color as hex string (optional, default: platform default)
- `dark-color` - Icon color when the device is in dark mode, as a hex string (optional). Overrides `color` in dark mode
@@ -31,8 +33,8 @@ All [shared layout and style attributes](layout) are supported, plus:
@@ -43,10 +45,10 @@ and platform-specific usage, see the [Icons](icons) reference page.
@verbatim
```blade
-
-
-
-
+
+
+
+
```
@endverbatim
@@ -67,13 +69,13 @@ and platform-specific usage, see the [Icons](icons) reference page.
@verbatim
```blade
-
+ No messages
```
@endverbatim
-### Platform-specific icon
+### Platform-specific icons
Give each platform its own symbol with the `ios` / `android` attributes — resolution happens per platform, so one
tag renders the right icon on each:
@@ -84,18 +86,51 @@ tag renders the right icon on each:
```
@endverbatim
-Or bind enum cases directly with `:ios` / `:android`:
+### Typed icon enums
+
+Bind `:ios` / `:android` to pass enum cases instead of strings for typed, autocompletable symbol names. Import
+the enums into your Blade view with `@@use` first — compiled views have no namespace, so a bare `Ios::Gearshape`
+won't resolve:
@verbatim
```blade
+@use('App\Icons\Ios')
+@use('App\Icons\Android')
+
```
@endverbatim
+The `AndroidOutlined` enum renders the outlined Material style instead of the filled one:
+
+@verbatim
+```blade
+@use('App\Icons\Ios')
+@use('App\Icons\AndroidOutlined')
+
+
+```
+@endverbatim
+
+You can also combine a shared `name` with a per-platform enum override:
+
+@verbatim
+```blade
+@use('App\Icons\Ios')
+
+
+```
+@endverbatim
+
+If you'd rather skip the `@@use` import, fully-qualified cases work anywhere:
+`:ios="\App\Icons\Ios::Gearshape"`.
+
+## How names resolve
+
+Every icon name — whether passed to `` or to the `icon` attribute of any other EDGE component — goes
+through a four-tier resolution strategy:
+
+1. **Direct platform icons** - On iOS, if the name contains a `.` it's used as a direct SF Symbol path (e.g., `car.side.fill`). On Android, any Material Icon ligature name works directly (e.g., `shopping_cart`)
+2. **Manual mapping** - Explicit mappings for common icons and aliases (e.g., `home`, `settings`, `user`)
+3. **Smart fallback** - Normalizes unmapped icon names to a platform equivalent
+4. **Default fallback** - Uses a circle icon if no match is found
+
+This approach means you can use intuitive icon names for common cases, leverage direct platform icons for advanced use
+cases, and get consistent results across iOS and Android.
+
+### iOS (SF Symbols)
+
+On iOS, icons render as SF Symbols. Manual mappings convert common icon names to their SF Symbol equivalents.
+For example:
+
+- `home` → `house.fill`
+- `settings` → `gearshape.fill`
+- `check` → `checkmark.circle.fill`
+
+Any name containing a `.` bypasses the mapping and is used as a direct SF Symbol path. Dotted paths are iOS-only,
+so pair them with an `android` override:
+
+@verbatim
+```blade
+
+```
+@endverbatim
+
+If a name isn't manually mapped and isn't a dotted path, the smart fallback lower-cases it and strips dashes and
+underscores (`archive-box` → `archivebox`). It deliberately does **not** guess filled or circled variations — many
+SF Symbols ship their plain glyph at the bare name, so when you want the filled variant, ask for it explicitly
+(`archivebox.fill`, or the `Ios::ArchiveboxFill` enum case).
+
+### Android (Material Icons)
+
+On Android, icons render using a lightweight font-based approach that supports the entire Material Icons library. You
+can use any Material Icon by its ligature name directly (e.g., `shopping_cart`, `qr_code_2`) — no mapping required.
+
+Manual mappings provide convenient aliases for common icon names. For example:
+
+- `home` → `home`
+- `settings` → `settings`
+- `check` → `check`
+- `cart` → `shopping_cart`
+
+## Icons in other components
+
+Every EDGE component with an `icon` attribute resolves names through this same system — pass it the same names you
+would give ``:
+
+@verbatim
+```blade
+
+```
+@endverbatim
+
+The PHP Element builders take per-platform overrides everywhere too: any builder with an icon accepts
+`icon(?string $name = null, IosSymbol|string|null $ios = null, AndroidSymbol|string|null $android = null)`, so you can
+pass a shared name, `ios:` / `android:` named arguments, or both.
+
+For Blade components whose tag only takes a single `icon` string, pick the platform variant with the `System` facade:
+
+@verbatim
+```blade
+
+```
+@endverbatim
+
+## Icon name reference
+
+All icons listed here are manually mapped and guaranteed to work consistently across iOS and Android.
+
+### Navigation
+
+| Icon | Description |
+|------|-------------|
+| `dashboard` | Grid-style dashboard view |
+| `home` | House/home screen |
+| `menu` | Three-line hamburger menu |
+| `settings` | Gear/settings |
+| `account`, `profile`, `user` | User account or profile |
+| `person` | Single person |
+| `people`, `connections`, `contacts` | Multiple people |
+| `group`, `groups` | Group of people |
+
+### Business & Commerce
+
+| Icon | Description |
+|------|-------------|
+| `orders`, `receipt` | Receipt or order |
+| `cart`, `shopping` | Shopping cart |
+| `shop`, `store` | Store or storefront |
+| `products`, `inventory` | Products or inventory |
+
+### Charts & Data
+
+| Icon | Description |
+|------|-------------|
+| `chart`, `barchart` | Bar chart |
+| `analytics` | Analytics/analysis |
+| `summary`, `report`, `assessment` | Summary or report |
+
+### Time & Scheduling
+
+| Icon | Description |
+|------|-------------|
+| `clock`, `schedule`, `time` | Clock or time |
+| `calendar` | Calendar |
+| `history` | History or recent |
+
+### Actions
+
+| Icon | Description |
+|------|-------------|
+| `add`, `plus` | Add or create new |
+| `edit` | Edit or modify |
+| `delete` | Delete or remove |
+| `save` | Save |
+| `search` | Search |
+| `filter` | Filter |
+| `refresh` | Refresh or reload |
+| `share` | Share |
+| `download` | Download |
+| `upload` | Upload |
+
+### Communication
+
+| Icon | Description |
+|------|-------------|
+| `notifications` | Notifications or alerts |
+| `message` | Message or SMS |
+| `email`, `mail` | Email |
+| `chat` | Chat or conversation |
+| `phone` | Phone or call |
+
+### Navigation Arrows
+
+| Icon | Description |
+|------|-------------|
+| `back` | Back or previous |
+| `forward` | Forward or next |
+| `up` | Up arrow |
+| `down` | Down arrow |
+
+### Status
+
+| Icon | Description |
+|------|-------------|
+| `check`, `done` | Check or complete |
+| `close` | Close or dismiss |
+| `warning` | Warning |
+| `error` | Error |
+| `info` | Information |
+
+### Authentication
+
+| Icon | Description |
+|------|-------------|
+| `login` | Login |
+| `logout`, `exit` | Logout or exit |
+| `lock` | Locked |
+| `unlock` | Unlocked |
+
+### Content
+
+| Icon | Description |
+|------|-------------|
+| `favorite`, `heart` | Favorite or like |
+| `star` | Star or rating |
+| `bookmark` | Bookmark |
+| `image`, `photo` | Image or photo |
+| `image-plus` | Add photo |
+| `video` | Video |
+| `folder` | Folder |
+| `folder-lock` | Locked folder |
+| `file`, `description` | Document or file |
+| `book-open` | Book |
+| `newspaper`, `news`, `article` | News or article |
+
+### Device & Hardware
+
+| Icon | Description |
+|------|-------------|
+| `camera` | Camera |
+| `qr`, `qrcode`, `qr-code` | QR code scanner |
+| `device-phone-mobile`, `smartphone` | Mobile phone |
+| `vibrate` | Vibration |
+| `bell` | Bell or notification |
+| `finger-print`, `fingerprint` | Fingerprint or biometric |
+| `light-bulb`, `lightbulb`, `flashlight` | Light bulb or flashlight |
+| `map`, `location` | Map or location |
+| `globe-alt`, `globe`, `web` | Globe or web |
+| `bolt`, `flash` | Lightning bolt or flash |
+
+### Audio & Volume
+
+| Icon | Description |
+|------|-------------|
+| `speaker`, `speaker-wave` | Speaker with sound |
+| `volume-up` | Volume up |
+| `volume-down` | Volume down |
+| `volume-mute`, `mute` | Muted |
+| `volume-off` | Volume off |
+| `music`, `audio`, `music-note` | Music or audio |
+| `microphone`, `mic` | Microphone |
+
+### Miscellaneous
+
+| Icon | Description |
+|------|-------------|
+| `help` | Help or question |
+| `about`, `information-circle` | Information or about |
+| `more` | More options |
+| `list` | List view |
+| `visibility` | Visible |
+| `visibility_off` | Hidden |
+
+## Finding icons
+
+Browse the complete Material Icons library at [Google Fonts Icons](https://fonts.google.com/icons). Use the icon name
+exactly as shown (with underscores, e.g., `shopping_cart`, `qr_code_2`).
+
+For the complete SF Symbols library, download the [SF Symbols app](https://developer.apple.com/sf-symbols/) for macOS.
+This [community Figma file](https://www.figma.com/community/file/1549047589273604548) is another great starting point,
+though not comprehensive.
+
+
+
+Icons carry meaning that users recognize across apps, so stay consistent: use the same icon name for the same action
+throughout your app. And if you rely on auto-converted names, test that they appear correctly on both platforms.
+
## Element
```php
diff --git a/resources/views/docs/mobile/4/edge-components/icons.md b/resources/views/docs/mobile/4/edge-components/icons.md
deleted file mode 100644
index 6b8fe876..00000000
--- a/resources/views/docs/mobile/4/edge-components/icons.md
+++ /dev/null
@@ -1,312 +0,0 @@
----
-title: Icons
-order: 240
----
-
-## Overview
-
-NativePHP EDGE components use a smart icon mapping system that automatically converts icon names to platform-specific
-icons. On iOS, icons render as [SF Symbols](https://developer.apple.com/sf-symbols/), while Android uses
-[Material Icons](https://fonts.google.com/icons?icon.set=Material+Icons).
-
-You don't need to worry about the differences! Just use a single, consistent icon name in your components, and the EDGE
-handles the platform translation automatically.
-
-## How It Works
-
-The icon system uses a four-tier resolution strategy:
-
-1. **Direct Platform Icons** - On iOS, if the name contains a `.` it's used as a direct SF Symbol path (e.g., `car.side.fill`). On Android, any Material Icon ligature name works directly (e.g., `shopping_cart`).
-2. **Manual Mapping** - Explicit mappings for common icons and aliases (e.g., `home`, `settings`, `user`)
-3. **Smart Fallback** - Attempts to auto-convert unmapped icon names to platform equivalents
-4. **Default Fallback** - Uses a circle icon if no match is found
-
-This approach means you can use intuitive icon names for common cases, leverage direct platform icons for advanced use
-cases, and get consistent results across iOS and Android.
-
-## Platform Differences
-
-### iOS (SF Symbols)
-
-On iOS, icons render as SF Symbols. Manual mappings convert common icon names to their SF Symbol equivalents.
-For example:
-
-- `home` → `house.fill`
-- `settings` → `gearshape.fill`
-- `check` → `checkmark.circle.fill`
-
-If an icon name isn't manually mapped, the system attempts to find a matching SF Symbol by trying variations like
-`.fill`, `.circle.fill`, and `.square.fill`.
-
-### Android (Material Icons)
-
-On Android, icons render using a lightweight font-based approach that supports the entire Material Icons library. You
-can use any Material Icon by its ligature name directly (e.g., `shopping_cart`, `qr_code_2`).
-
-Manual mappings provide convenient aliases for common icon names. For example:
-
-- `home` → `home`
-- `settings` → `settings`
-- `check` → `check`
-- `cart` → `shopping_cart`
-
-## Direct Platform Icons
-
-For advanced use cases, you can use platform-specific icon names directly.
-
-### iOS SF Symbols
-
-On iOS, include a `.` in the icon name to use an SF Symbol path directly:
-
-@verbatim
-```blade
-
-
-
-```
-@endverbatim
-
-### Android Material Icons
-
-On Android, use any Material Icon ligature name (with underscores):
-
-@verbatim
-```blade
-
-
-
-```
-@endverbatim
-
-## Platform-Specific Icons
-
-When a single mapped name won't do, give each platform its own symbol. The [``](icon) component accepts
-`ios` and `android` attributes that resolve per platform, so one tag renders the right icon on each:
-
-@verbatim
-```blade
-
-```
-@endverbatim
-
-Bind with `:ios` / `:android` to pass enum cases directly for typed, autocompletable symbol names:
-
-@verbatim
-```blade
-
-```
-@endverbatim
-
-The `App\Icons\Ios` and `App\Icons\Android` enums are generated into your app by the
-[native-ui](https://github.com/nativephp/native-ui) plugin. Run this once to create them:
-
-```shell
-php artisan native-ui:generate-icons
-```
-
-For components that take a single `icon` attribute, pick the platform variant with the `System` facade:
-
-@verbatim
-```blade
-
-```
-@endverbatim
-
-See the [Icon](icon) reference for the full per-platform API.
-
-## Basic Usage
-
-Use the `icon` attribute in any EDGE component that supports icons, simply passing the name of the icon you wish to use:
-
-@verbatim
-```blade
-
-```
-@endverbatim
-
-## Icon Reference
-
-All icons listed here are manually mapped and guaranteed to work consistently across iOS and Android.
-
-### Navigation
-
-| Icon | Description |
-|------|-------------|
-| `dashboard` | Grid-style dashboard view |
-| `home` | House/home screen |
-| `menu` | Three-line hamburger menu |
-| `settings` | Gear/settings |
-| `account`, `profile`, `user` | User account or profile |
-| `person` | Single person |
-| `people`, `connections`, `contacts` | Multiple people |
-| `group`, `groups` | Group of people |
-
-### Business & Commerce
-
-| Icon | Description |
-|------|-------------|
-| `orders`, `receipt` | Receipt or order |
-| `cart`, `shopping` | Shopping cart |
-| `shop`, `store` | Store or storefront |
-| `products`, `inventory` | Products or inventory |
-
-### Charts & Data
-
-| Icon | Description |
-|------|-------------|
-| `chart`, `barchart` | Bar chart |
-| `analytics` | Analytics/analysis |
-| `summary`, `report`, `assessment` | Summary or report |
-
-### Time & Scheduling
-
-| Icon | Description |
-|------|-------------|
-| `clock`, `schedule`, `time` | Clock or time |
-| `calendar` | Calendar |
-| `history` | History or recent |
-
-### Actions
-
-| Icon | Description |
-|------|-------------|
-| `add`, `plus` | Add or create new |
-| `edit` | Edit or modify |
-| `delete` | Delete or remove |
-| `save` | Save |
-| `search` | Search |
-| `filter` | Filter |
-| `refresh` | Refresh or reload |
-| `share` | Share |
-| `download` | Download |
-| `upload` | Upload |
-
-### Communication
-
-| Icon | Description |
-|------|-------------|
-| `notifications` | Notifications or alerts |
-| `message` | Message or SMS |
-| `email`, `mail` | Email |
-| `chat` | Chat or conversation |
-| `phone` | Phone or call |
-
-### Navigation Arrows
-
-| Icon | Description |
-|------|-------------|
-| `back` | Back or previous |
-| `forward` | Forward or next |
-| `up` | Up arrow |
-| `down` | Down arrow |
-
-### Status
-
-| Icon | Description |
-|------|-------------|
-| `check`, `done` | Check or complete |
-| `close` | Close or dismiss |
-| `warning` | Warning |
-| `error` | Error |
-| `info` | Information |
-
-### Authentication
-
-| Icon | Description |
-|------|-------------|
-| `login` | Login |
-| `logout`, `exit` | Logout or exit |
-| `lock` | Locked |
-| `unlock` | Unlocked |
-
-### Content
-
-| Icon | Description |
-|------|-------------|
-| `favorite`, `heart` | Favorite or like |
-| `star` | Star or rating |
-| `bookmark` | Bookmark |
-| `image`, `photo` | Image or photo |
-| `image-plus` | Add photo |
-| `video` | Video |
-| `folder` | Folder |
-| `folder-lock` | Locked folder |
-| `file`, `description` | Document or file |
-| `book-open` | Book |
-| `newspaper`, `news`, `article` | News or article |
-
-### Device & Hardware
-
-| Icon | Description |
-|------|-------------|
-| `camera` | Camera |
-| `qr`, `qrcode`, `qr-code` | QR code scanner |
-| `device-phone-mobile`, `smartphone` | Mobile phone |
-| `vibrate` | Vibration |
-| `bell` | Bell or notification |
-| `finger-print`, `fingerprint` | Fingerprint or biometric |
-| `light-bulb`, `lightbulb`, `flashlight` | Light bulb or flashlight |
-| `map`, `location` | Map or location |
-| `globe-alt`, `globe`, `web` | Globe or web |
-| `bolt`, `flash` | Lightning bolt or flash |
-
-### Audio & Volume
-
-| Icon | Description |
-|------|-------------|
-| `speaker`, `speaker-wave` | Speaker with sound |
-| `volume-up` | Volume up |
-| `volume-down` | Volume down |
-| `volume-mute`, `mute` | Muted |
-| `volume-off` | Volume off |
-| `music`, `audio`, `music-note` | Music or audio |
-| `microphone`, `mic` | Microphone |
-
-### Miscellaneous
-
-| Icon | Description |
-|------|-------------|
-| `help` | Help or question |
-| `about`, `information-circle` | Information or about |
-| `more` | More options |
-| `list` | List view |
-| `visibility` | Visible |
-| `visibility_off` | Hidden |
-
-## Best Practices
-
-Icons have meaning and most users will associate the visual cues of icons and the underlying behavior or section of an
-application across apps. So try to maintain consistent use of icons to help guide users through your app.
-
-- **Stay consistent** - Use the same icon name throughout your app for the same action
-- **Test on both platforms** - If you use auto-converted icons, verify they appear correctly on iOS and Android
-
-## Finding Icons
-
-### Android Material Icons
-
-Browse the complete Material Icons library at [Google Fonts Icons](https://fonts.google.com/icons). Use the icon name
-exactly as shown (with underscores, e.g., `shopping_cart`, `qr_code_2`).
-
-### iOS SF Symbols
-
-Browse SF Symbols using this [community Figma file](https://www.figma.com/community/file/1549047589273604548). While not
-comprehensive, it's a great starting point for discovering available symbols.
-
-For the complete library, download the [SF Symbols app](https://developer.apple.com/sf-symbols/) for macOS.
-
-
diff --git a/resources/views/docs/mobile/4/edge-components/image.md b/resources/views/docs/mobile/4/edge-components/image.md
index 7f1484cc..86271d97 100644
--- a/resources/views/docs/mobile/4/edge-components/image.md
+++ b/resources/views/docs/mobile/4/edge-components/image.md
@@ -9,7 +9,13 @@ Displays an image from a URL. Loaded asynchronously by the native platform — `
@verbatim
```blade
-
+
```
@endverbatim
@@ -40,7 +46,7 @@ The renderer collapses fit modes to two effective behaviors: `fit` and `fill`. M
@verbatim
```blade
-
+
```
@endverbatim
@@ -49,11 +55,11 @@ The renderer collapses fit modes to two effective behaviors: `fit` and `fill`. M
@verbatim
```blade
```
@endverbatim
@@ -61,24 +67,33 @@ The renderer collapses fit modes to two effective behaviors: `fit` and `fill`. M
### Tinted icon image
@verbatim
-```blade
+```blade static
```
@endverbatim
+
+
### Image in a card
@verbatim
```blade
-
-
-
- Article Title
+
+
+
+ Article TitleA brief description of the article.
@@ -90,7 +105,7 @@ The renderer collapses fit modes to two effective behaviors: `fit` and `fill`. M
```php
use Native\Mobile\Edge\Elements\Image;
-Image::make('https://example.com/photo.jpg')
+Image::make('https://picsum.photos/seed/nativephp/400/300')
->fit(2)
->tintColor('#7C3AED');
```
diff --git a/resources/views/docs/mobile/4/edge-components/introduction.md b/resources/views/docs/mobile/4/edge-components/introduction.md
index f1aadcbf..154c7722 100644
--- a/resources/views/docs/mobile/4/edge-components/introduction.md
+++ b/resources/views/docs/mobile/4/edge-components/introduction.md
@@ -82,7 +82,7 @@ interactive forms and navigation chrome.
## How It Works
@verbatim
-```blade
+```blade static
diff --git a/resources/views/docs/mobile/4/edge-components/layout.md b/resources/views/docs/mobile/4/edge-components/layout.md
index 9c93019d..2c22151d 100644
--- a/resources/views/docs/mobile/4/edge-components/layout.md
+++ b/resources/views/docs/mobile/4/edge-components/layout.md
@@ -15,7 +15,7 @@ This page documents the shared attribute system that powers the layout engine ac
Control element dimensions with width, height, and fill attributes.
@verbatim
-```blade
+```blade static
{{-- Fixed dimensions (in dp) --}}
...
@@ -55,7 +55,7 @@ Padding and margin follow CSS shorthand conventions. Pass a single value for uni
per-side control.
@verbatim
-```blade
+```blade static
{{-- Uniform padding --}}
...
@@ -93,7 +93,7 @@ The layout engine uses a Flexbox-based system. Containers (column, row) arrange
properties control how children grow, shrink, and align.
@verbatim
-```blade
+```blade static
{{-- Grow to fill remaining space --}}
...
@@ -130,7 +130,7 @@ Alignment values are integers that map to standard flex alignment:
| `4` | baseline |
@verbatim
-```blade
+```blade static
{{-- Center children on both axes --}}
...
@@ -166,7 +166,7 @@ A child with `w-full` (or `h-full`) overrides its parent's `items-center` along
Visual styling attributes that apply to any element.
@verbatim
-```blade
+```blade static
Tap, double tap, or long press me
@@ -210,7 +210,7 @@ Respect the device's safe area insets (notch, home indicator, status bar) by add
typically applied to your outermost column.
@verbatim
-```blade
+```blade static
{{-- Content will not overlap the notch or home indicator --}}
@@ -229,7 +229,7 @@ chrome already handles safe-area insets for you.
Hide elements without removing them from the tree.
@verbatim
-```blade
+```blade static
{{-- This element is not displayed --}}
@@ -243,7 +243,7 @@ Hide elements without removing them from the tree.
Override styles for dark mode using the `dark:` prefix with Tailwind classes, or pass a `dark` attribute array.
@verbatim
-```blade
+```blade static
{{-- Tailwind dark mode --}}
@@ -261,7 +261,7 @@ EDGE includes a built-in Tailwind CSS parser that converts familiar utility clas
the `class` attribute on any element.
@verbatim
-```blade
+```blade static
Styled with Tailwind
diff --git a/resources/views/docs/mobile/4/edge-components/lazy-grid.md b/resources/views/docs/mobile/4/edge-components/lazy-grid.md
index 560d61a4..9d923af4 100644
--- a/resources/views/docs/mobile/4/edge-components/lazy-grid.md
+++ b/resources/views/docs/mobile/4/edge-components/lazy-grid.md
@@ -15,9 +15,9 @@ of thumb is around 50 or more cells.
@verbatim
```blade
-
- @foreach($icons as $icon)
-
+
+ @foreach (['star', 'heart', 'bell', 'bookmark', 'camera', 'paperplane', 'flag', 'gearshape'] as $icon)
+
@endforeach
@@ -25,6 +25,8 @@ of thumb is around 50 or more cells.
```
@endverbatim
+In a real app you would typically loop a collection property on your component (`$icons`) rather than a literal list.
+
## Props
- `columns` - Number of equal-width tracks the cells flow across. When `horizontal` is set, this becomes the number
@@ -55,24 +57,26 @@ it be the screen's scroll container) to keep lazy composition.
@verbatim
```blade
-
- @foreach($photos as $photo)
+
+ @foreach (range(1, 9) as $i)
-
+
@endforeach
```
@endverbatim
+Swap `range(1, 9)` for your own `$photos` collection and bind `src` from each item (e.g. `$photo->url`).
+
### Horizontal category shelves
@verbatim
-```blade
+```blade static
@foreach($products as $product)
-
+ {{ $product->name }}
@endforeach
diff --git a/resources/views/docs/mobile/4/edge-components/list.md b/resources/views/docs/mobile/4/edge-components/list.md
index 16e58934..1c3a59c2 100644
--- a/resources/views/docs/mobile/4/edge-components/list.md
+++ b/resources/views/docs/mobile/4/edge-components/list.md
@@ -72,18 +72,19 @@ content slots.
- `leadingMonogram` - 1-2 character monogram (combine with `leadingMonogramColor`)
- `leadingMonogramColor` - Hex color for monogram background
- `leadingImage` - URL of a square image with a small radius
-- `leadingCheckbox` - Boolean value for a leading checkbox. Toggling is interactive on [Android]; iOS renders a
- static glyph
-- `leadingRadio` - Boolean value for a leading radio button. Toggling is interactive on [Android]; iOS renders a
- static glyph
+- `leadingCheckbox` - Boolean value for a leading checkbox. Interactive when `on-leading-change` is set —
+ tapping the box fires your handler with the new value (the row's own `@press` still handles taps elsewhere
+ on the row); without a handler it renders as a static state glyph
+- `leadingRadio` - Boolean value for a leading radio button. Interactive when `on-leading-change` is set;
+ static glyph otherwise
### Trailing slot (mutually exclusive)
- `trailingIcon` - Icon name rendered as a trailing icon. Pair with `trailingIconIos` / `trailingIconAndroid` to
override the [icon](icon) per platform
- `trailingText` - Trailing text label
-- `trailingCheckbox` - Boolean value for a trailing checkbox. Toggling is interactive on [Android]; iOS renders a
- static glyph
+- `trailingCheckbox` - Boolean value for a trailing checkbox. Interactive when `on-trailing-change` is set;
+ static glyph otherwise
- `trailingSwitch` - Boolean value for a trailing switch [Android]
- `trailingIconButton` - Icon name for a tappable trailing button
- `trailing-a11y-label` - Accessibility label for the trailing icon button (recommended whenever
@@ -120,9 +121,11 @@ All color props accept the full [color grammar](../digging-deeper/theming#color-
- `on-swipe-delete` - Shortcut for a single destructive trailing swipe. For anything richer, use
`trailing-actions` below.
-Toggle changes and trailing icon-button taps are wired through the [Element](#element) callbacks rather than Blade
-events. `onTrailingPress()` fires on both platforms when the trailing icon button is tapped. `onLeadingChange()`
-and `onTrailingChange()` fire on [Android], where the checkbox / radio / switch controls are interactive.
+- `on-leading-change` / `on-trailing-change` - Component method called when the leading/trailing checkbox or
+ radio is toggled, receiving the new value. Without a handler the control renders as a static state glyph.
+
+`onTrailingPress()` fires on both platforms when the trailing icon button is tapped. The trailing switch is
+interactive on [Android] only.
### Swipe actions
@@ -135,18 +138,25 @@ definitions the user reveals by swiping the row. Each action is an array:
- `tint` - Background color as a hex string
- `role` - Set to `destructive` to render in the platform's delete style (trailing only)
+Swipe actions only work on rows that are direct children of `` (or a ``) —
+they are attached by the list renderer, so a standalone `` silently ignores them.
+
@verbatim
```blade
-
+
+ @foreach ($emails as $email)
+
+ @endforeach
+
```
@endverbatim
@@ -204,6 +214,9 @@ ListSection::make('Fruits', ListItem::make('Apple'))->footer('1 item');
### Swipe-to-delete with pull-to-refresh
+The checkbox, swipe, and row press are three independent targets on one row: tapping the box fires
+`on-leading-change`, swiping left fires `on-swipe-delete`, tapping anywhere else fires `@press`.
+
@verbatim
```blade
@@ -212,6 +225,7 @@ ListSection::make('Fruits', ListItem::make('Apple'))->footer('1 item');
headline="{{ $task->title }}"
supporting="{{ $task->due }}"
leadingCheckbox="{{ $task->done }}"
+ on-leading-change="toggleTask({{ $task->id }})"
trailingIcon="forward"
on-swipe-delete="deleteTask({{ $task->id }})"
@press="openTask({{ $task->id }})"
@@ -221,13 +235,22 @@ ListSection::make('Fruits', ListItem::make('Apple'))->footer('1 item');
```
@endverbatim
+> [!NOTE]
+> Pull-to-refresh needs to own the pull gesture, so it only fires when the list is the screen's scrolling
+> container — inside another scroll view (like this docs page) the outer container wins the pull. Swipe and
+> checkbox work inline; run the refresh on a dedicated screen.
+
### Infinite scroll
+`loadMore()` is a method on your component that fetches the next page and appends it to the collection the loop
+renders — in a real app the loop is `@foreach ($posts as $post)` over your paginated results. The fixed `range()`
+here just gives the demo enough rows to scroll before the end-reached trigger fires.
+
@verbatim
```blade
- @foreach($posts as $post)
-
+ @foreach (range(1, 15) as $i)
+
@endforeach
```
diff --git a/resources/views/docs/mobile/4/edge-components/menus.md b/resources/views/docs/mobile/4/edge-components/menus.md
index f5f3bf5c..86df571f 100644
--- a/resources/views/docs/mobile/4/edge-components/menus.md
+++ b/resources/views/docs/mobile/4/edge-components/menus.md
@@ -10,9 +10,10 @@ standalone element — you build a list of actions and attach it with an attribu
- `:menu` on a [button](button) or [pressable](pressable) — tapping opens the menu instead of firing `@press`.
- `:trailing-menu` on a [list item](list) — opens from the row's trailing edge.
+- `items()` on a nav-bar action — see [Menus in the nav bar](#menus-in-the-nav-bar) below.
-All three share one item model: an array of `NavAction`, the same builder used for
-[nav-bar menus](../the-basics/layouts#builder-reference).
+All of them share one item model: an array of `NavAction`, the same builder used
+[throughout layouts](../the-basics/layouts#builder-reference).
## Building the items
@@ -64,6 +65,53 @@ Use `:trailing-menu` to open a menu from a row's trailing edge — a common patt
```
@endverbatim
+## Menus in the nav bar
+
+The same `NavAction` builder powers pull-down menus on nav-bar (top bar) actions. Give an action sub-items
+with `items()` and it renders as a menu that drops from the bar button instead of firing a plain press:
+
+```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('share')
+ ->icon('share')
+ ->a11yLabel('Share')
+ ->press('share')
+ )
+ ->action(
+ NavAction::make('more')
+ ->icon('ellipsis')
+ ->a11yLabel('More options')
+ ->items([
+ NavAction::make('mute')
+ ->label('Mute')
+ ->icon(ios: 'bell.slash', android: 'notifications_off')
+ ->press('mute'),
+ NavAction::make('pin')->label('Pin')->icon('pin')->press('pin'),
+ NavAction::divider(),
+ NavAction::make('delete')
+ ->label('Delete')
+ ->icon('trash')
+ ->press('delete')
+ ->destructive(),
+ ])
+ );
+}
+```
+
+Here `share` stays a plain press, while `more` opens a native pull-down (SwiftUI `Menu` / Compose `DropdownMenu`)
+with dividers and destructive tinting, exactly like the inline menus above. This works in both stack and tab
+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.
+
## Item reference
The menu-relevant `NavAction` methods:
@@ -73,6 +121,8 @@ The menu-relevant `NavAction` methods:
- `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
diff --git a/resources/views/docs/mobile/4/edge-components/modal.md b/resources/views/docs/mobile/4/edge-components/modal.md
index af9cfefc..80d900b3 100644
--- a/resources/views/docs/mobile/4/edge-components/modal.md
+++ b/resources/views/docs/mobile/4/edge-components/modal.md
@@ -9,7 +9,7 @@ A full-screen modal overlay. Visibility is driven by the `visible` prop. Use a [
contextual actions; reach for `` when you want the entire screen covered (e.g. an onboarding flow,
image preview, or detail view).
-Per Model 3, backdrop and surface colors come from `theme.background`. The close icon uses `theme.onSurfaceVariant`.
+Per Material 3, backdrop and surface colors come from `theme.background`. The close icon uses `theme.onSurfaceVariant`.
@verbatim
```blade
@@ -23,8 +23,8 @@ Per Model 3, backdrop and surface colors come from `theme.background`. The close
- Details
- {{ $description }}
+ Details
+ {{ $description }}
@@ -90,7 +90,7 @@ Programmatically setting `visible` to `false` from PHP does not fire the callbac
- Processing...
+ Processing...
{{-- A real app closes this from PHP when the work finishes;
the button stands in for that here since the modal can't
be dismissed by the user. --}}
diff --git a/resources/views/docs/mobile/4/edge-components/pressable.md b/resources/views/docs/mobile/4/edge-components/pressable.md
index c7245432..5183bf03 100644
--- a/resources/views/docs/mobile/4/edge-components/pressable.md
+++ b/resources/views/docs/mobile/4/edge-components/pressable.md
@@ -13,13 +13,16 @@ provides a clear tap target that wraps multiple children.
@verbatim
```blade
-id }})" class="w-full p-4 rounded-xl" bg="#FFFFFF">
- {{ $item->name }}
- {{ $item->description }}
+
+ Account
+ Signed in as {{ $name }} — tap anywhere on the card
```
@endverbatim
+`@press` names a method on your component — declare `public function openAccount(): void` and it runs when any
+part of the card is tapped.
+
## Props
All [shared layout and style attributes](layout) are supported, plus:
@@ -48,10 +51,10 @@ Accepts any EDGE elements as children. Children are arranged vertically (like a
@press="selectItem({{ $item->id }})"
class="w-full px-4 py-3"
>
-
+
-
- {{ $item->name }}
+
+ {{ $item->name }}{{ $item->subtitle }}
@@ -64,30 +67,38 @@ Accepts any EDGE elements as children. Children are arranged vertically (like a
```
@endverbatim
+Interpolate arguments straight into the handler — each row calls `selectItem()` on your component with its own id.
+
### Card with tap and long press
@verbatim
```blade
-id }})"
- @longPress="showOptions({{ $post->id }})"
- class="w-full p-4 rounded-2xl gap-2"
- bg="#FFFFFF"
- :elevation="2"
->
- {{ $post->title }}
- {{ $post->excerpt }}
-
+@foreach ($posts as $post)
+ id }})"
+ @longPress="showOptions({{ $post->id }})"
+ class="w-full p-4 mb-3 rounded-2xl gap-2 bg-theme-surface"
+ :elevation="2"
+ >
+ {{ $post->title }}
+ {{ $post->excerpt }}
+
+@endforeach
```
@endverbatim
+A tap calls `openDetail()`; holding the card calls `showOptions()` instead — one pressable can route each gesture to
+a different component method.
+
### Navigation with @navigate
@verbatim
```blade
-id }}" class="w-full p-4">
- {{ $item->name }}
-
+@foreach ($items as $item)
+ id }}" class="w-full px-4 py-3">
+ {{ $item->name }}
+
+@endforeach
```
@endverbatim
@@ -103,13 +114,14 @@ the animation stays smooth even while a handler is dispatching:
@verbatim
```blade
id }})"
+ @press="openDetail"
:press-scale="0.92"
:press-opacity="0.85"
:press-translate-y="3"
- class="w-full p-4 rounded-2xl"
+ class="w-full p-4 rounded-2xl gap-1 bg-theme-surface-variant"
>
- {{ $post->title }}
+ Press and hold
+ The card scales down, dims, and nudges while pressed.
```
@endverbatim
diff --git a/resources/views/docs/mobile/4/edge-components/progress-bar.md b/resources/views/docs/mobile/4/edge-components/progress-bar.md
index 9186674d..7867373d 100644
--- a/resources/views/docs/mobile/4/edge-components/progress-bar.md
+++ b/resources/views/docs/mobile/4/edge-components/progress-bar.md
@@ -10,7 +10,7 @@ value (or with `indeterminate`), renders an animated wave.
For a circular spinner use [``](activity-indicator) instead.
-Per Model 3, the progress fill uses `theme.primary` and the track uses `theme.surfaceVariant`. The optional `color`
+Per Material 3, the progress fill uses `theme.primary` and the track uses `theme.surfaceVariant`. The optional `color`
prop is an escape hatch for non-theme containers.
@verbatim
@@ -40,16 +40,20 @@ prop is an escape hatch for non-theme containers.
@verbatim
```blade
+@php $progress = 0.65; @endphp
+
-
- Uploading
- {{ round($progress * 100) }}%
+
+ Uploading
+ {{ round($progress * 100) }}%
```
@endverbatim
+Here `$progress` stands in for a public property on your component — declare `public float $progress = 0.65;` and update it as the work advances; the bar and the percentage label track it automatically.
+
### Indeterminate
@verbatim
@@ -66,6 +70,12 @@ prop is an escape hatch for non-theme containers.
```
@endverbatim
+
+
## Element
```php
diff --git a/resources/views/docs/mobile/4/edge-components/radio-group.md b/resources/views/docs/mobile/4/edge-components/radio-group.md
index 28c60984..989f8fcf 100644
--- a/resources/views/docs/mobile/4/edge-components/radio-group.md
+++ b/resources/views/docs/mobile/4/edge-components/radio-group.md
@@ -8,10 +8,12 @@ order: 310
A single-choice container holding `` children. The group owns the selection; each child declares its
own `value` and label.
-Per Model 3, all colors come from theme tokens.
+Per Material 3, all colors come from theme tokens.
@verbatim
```blade
+@php $plan = 'pro'; @endphp
+
@@ -20,6 +22,9 @@ Per Model 3, all colors come from theme tokens.
```
@endverbatim
+Here `plan` is a public string property on your component — the `@php` line stands in for
+`public string $plan = 'pro';`.
+
## Props (Group)
- `value` - Currently selected `value` string (optional). Use `native:model` for two-way binding
@@ -34,17 +39,25 @@ Per Model 3, all colors come from theme tokens.
## Two-way Binding
-`native:model` binds the group's selected value to a string property on your component:
+`native:model` binds the group's selected value to a public string property on your component:
@verbatim
```blade
-
-
-
+@php $billing = 'monthly'; @endphp
+
+
+
+
+
+Billed: {{ $billing }}
```
@endverbatim
+`billing` is a public string property on your component (the `@php` line stands in for
+`public string $billing = 'monthly';`). Picking an option syncs the new value back automatically,
+so the `{{ $billing }}` echo updates as soon as you tap a different option.
+
## Children
`` declares a single option:
@@ -61,17 +74,25 @@ Per Model 3, all colors come from theme tokens.
@verbatim
```blade
-
+@php $selectedPlan = 'free'; @endphp
+
+
+
+Current plan: {{ $selectedPlan }}
```
@endverbatim
### Manual handler
+When you need side effects beyond a simple property write, bind `:value` yourself and handle
+`@change` — `$shippingMethod` is a public string property and `setShipping()` a public method on
+your component, receiving the new value as its parameter:
+
@verbatim
```blade
diff --git a/resources/views/docs/mobile/4/edge-components/refreshable.md b/resources/views/docs/mobile/4/edge-components/refreshable.md
index 8811e657..f78ee07a 100644
--- a/resources/views/docs/mobile/4/edge-components/refreshable.md
+++ b/resources/views/docs/mobile/4/edge-components/refreshable.md
@@ -11,17 +11,19 @@ component method, and the platform handles the gesture, spinner, and physics for
their native pull-to-refresh spinner, with system haptics on iOS.
@verbatim
-```blade
+```blade static
@foreach($items as $item)
- {{ $item->title }}
+ {{ $item->name }}
@endforeach
```
@endverbatim
+The refreshable container wants the full height of the screen — run it in your app to feel the pull gesture.
+
## Events
- `@refresh` - Component method called when the user pulls down past the release threshold (optional, string)
@@ -50,7 +52,7 @@ content — cards, a [``](column), a dashboard — rather than a
### Refreshable feed
@verbatim
-```blade
+```blade static
@foreach($posts as $post)
diff --git a/resources/views/docs/mobile/4/edge-components/row.md b/resources/views/docs/mobile/4/edge-components/row.md
index a957e7de..b3311954 100644
--- a/resources/views/docs/mobile/4/edge-components/row.md
+++ b/resources/views/docs/mobile/4/edge-components/row.md
@@ -12,7 +12,7 @@ and inline groupings.
```blade
- 4.8 Rating
+ 4.8 Rating
```
@endverbatim
@@ -43,9 +43,9 @@ Everything else from the shared list applies the same as on any element (`w-*`,
@verbatim
```blade
- Title
+ Title
-
+
```
@endverbatim
@@ -55,9 +55,9 @@ Everything else from the shared list applies the same as on any element (`w-*`,
@verbatim
```blade
- One
- Two
- Three
+ One
+ Two
+ Three
```
@endverbatim
diff --git a/resources/views/docs/mobile/4/edge-components/scroll-view.md b/resources/views/docs/mobile/4/edge-components/scroll-view.md
index 2a47811e..60dba1cb 100644
--- a/resources/views/docs/mobile/4/edge-components/scroll-view.md
+++ b/resources/views/docs/mobile/4/edge-components/scroll-view.md
@@ -11,6 +11,21 @@ Android and `ScrollView` on iOS for efficient rendering.
@verbatim
```blade
+
+
+ @foreach (range(1, 20) as $i)
+ Scrollable row {{ $i }}
+ @endforeach
+
+
+```
+@endverbatim
+
+The fixed `h-[240]` here just gives the preview a bounded viewport so the content overflows and scrolls. On a real
+screen you'd typically let the scroll view fill the page instead:
+
+@verbatim
+```blade static
@foreach($items as $item)
@@ -50,12 +65,15 @@ scrollable content.
### Vertical list
+A full-screen list of posts. `safe-area` keeps the content clear of the notch and home indicator, so this one is
+meant for a real page root — run it in your app to see it edge-to-edge:
+
@verbatim
-```blade
-
-
+```blade static
+
+
@foreach($posts as $post)
-
+ {{ $post->title }}{{ $post->excerpt }}
@@ -76,8 +94,7 @@ scrollable content.
:width="120"
:height="80"
center
- bg="#F1F5F9"
- :border-radius="12"
+ class="bg-theme-surface-variant rounded-xl"
>
{{ $category->name }}
@@ -89,9 +106,12 @@ scrollable content.
### Full-page scrollable layout
+Another page-root pattern — `h-full` and `safe-area` only make sense against a real screen, so try this one in your
+app:
+
@verbatim
-```blade
-
+```blade static
+Welcome
@@ -105,9 +125,12 @@ scrollable content.
### Chat-style stick-to-bottom
+The view opens at the latest message and stays pinned to the bottom as new content arrives. The fixed `h-[200]`
+bounds the preview so there's something to scroll — in a real chat screen you'd use `fill` instead:
+
@verbatim
```blade
-
+
@foreach($messages as $message)
{{ $message->body }}
diff --git a/resources/views/docs/mobile/4/edge-components/select.md b/resources/views/docs/mobile/4/edge-components/select.md
index cff5942c..ae31ec2b 100644
--- a/resources/views/docs/mobile/4/edge-components/select.md
+++ b/resources/views/docs/mobile/4/edge-components/select.md
@@ -8,19 +8,24 @@ order: 350
A single-choice dropdown picker over a flat list of strings. On iOS, renders as a SwiftUI `Menu` (popover); on
Android, as an M3 `ExposedDropdownMenuBox` with an outlined trigger.
-Per Model 3, colors and borders come from theme tokens.
+Per Material 3, colors and borders come from theme tokens.
@verbatim
```blade
+@php $shippingCountry = null; @endphp
+
```
@endverbatim
+Here `shippingCountry` is a public string property on your component (the `@php` line stands in for
+`public ?string $shippingCountry = null;`) — while it is `null`, the placeholder shows.
+
Options are a flat list of display strings — pass the strings you want shown, and the selected string is the
value bound back to your component. An associative `value => label` array is flattened to its labels, so the
displayed text is what you get.
@@ -51,21 +56,36 @@ Margin classes position the picker; its colors and borders come from the theme.
@verbatim
```blade
-
+@php $country = 'Canada'; @endphp
+
+
+
+Shipping to: {{ $country }}
```
@endverbatim
+`country` is a public string property on your component (the `@php` line stands in for
+`public string $country = 'Canada';`), and `$countries` is an array of option strings. Picking an option
+syncs the selected string back automatically — no `@change` handler needed — so the echoed text updates
+with the selection.
+
## Examples
### Country picker
@verbatim
```blade
+@php $destination = 'Japan'; @endphp
+
```
@endverbatim
diff --git a/resources/views/docs/mobile/4/edge-components/shapes.md b/resources/views/docs/mobile/4/edge-components/shapes.md
index 71e57ed2..8aa3d94a 100644
--- a/resources/views/docs/mobile/4/edge-components/shapes.md
+++ b/resources/views/docs/mobile/4/edge-components/shapes.md
@@ -15,19 +15,21 @@ These are typically placed inside a [``](canvas) or used standalo
## Rect
-A rectangle filled with `bg`. All [shared layout and style attributes](layout) apply, so border, radius, opacity,
-and elevation behave as on any other element.
+A rectangle filled with `bg`. All [shared layout and style attributes](layout) apply — use Tailwind-style classes
+(`rounded-*`, `border-*`, `opacity-*`, `shadow-*`) for radius, borders, opacity, and elevation, just as on any
+other element.
@verbatim
```blade
-
+
```
@endverbatim
### Props
-- `left` - X position offset in dp (optional, float). Used inside an absolutely-positioned parent
-- `top` - Y position offset in dp (optional, float)
+The `left` / `top` position props are accepted by the PHP element but are not currently read by the iOS or Android
+renderers. To offset a rect inside a parent, use absolute-positioning classes instead — e.g.
+`class="absolute top-[8] left-[8]"`.
`` is a self-closing element, so it doesn't accept tag children. To layer content on top of the fill,
overlay the rect and your content inside a [``](stack). In PHP, the `Rect` element accepts children via
@@ -46,33 +48,35 @@ perfect circle use equal `width` and `height`.
### Props
-- `left` - X position offset in dp (optional, float)
-- `top` - Y position offset in dp (optional, float)
+As with ``, the `left` / `top` position props exist on the PHP element but the renderers don't read
+them — position circles with absolute-positioning classes (`class="absolute top-[8] left-[8]"`) or by centering
+them in a [``](stack).
`` is a self-closing element. It does not accept children.
## Line
-A 1pt horizontal rule across the available width.
+A horizontal rule. Style it with `border-*` classes:
@verbatim
-```blade
-
+```blade static
+
```
@endverbatim
### Props
-All [shared layout and style attributes](layout) are supported. The most useful:
+All [shared layout and style attributes](layout) are supported. Set the stroke through classes:
-- `border-color` - Line color as hex string (optional, default: platform separator color)
-- `border-width` - Stroke thickness in dp (optional, float, default: `1`)
+- `border-theme-outline` / `border-[#94A3B8]` - Line color (default: platform separator color)
+- `border` / `border-2` / `border-4` - Stroke thickness in dp (default: `1`)
@@ -93,7 +97,7 @@ Overlay the label on a filled rect with a ``. Give the rect an exp
@verbatim
```blade
-
+ New
```
@@ -101,9 +105,17 @@ Overlay the label on a filled rect with a ``. Give the rect an exp
### Decorative separator
+@verbatim
+```blade static
+
+```
+@endverbatim
+
+For a full-width rule that renders consistently on both platforms today, use a divider instead:
+
@verbatim
```blade
-
+
```
@endverbatim
diff --git a/resources/views/docs/mobile/4/edge-components/side-nav.md b/resources/views/docs/mobile/4/edge-components/side-nav.md
index 7462227b..4e81ab28 100644
--- a/resources/views/docs/mobile/4/edge-components/side-nav.md
+++ b/resources/views/docs/mobile/4/edge-components/side-nav.md
@@ -21,7 +21,7 @@ order: 370
A slide-out navigation drawer with support for groups, headers, and dividers.
@verbatim
-```blade
+```blade static
+@php $brightness = 60; @endphp
+
+
```
@endverbatim
+`brightness` is a public property on your component — the `@php` line stands in for
+`public int $brightness = 60;`.
+
## Props
- `value` - Current value (optional, float)
@@ -41,19 +46,26 @@ Margin classes position the slider; the active track and thumb colors come from
@verbatim
```blade
+@php $intensity = 50; @endphp
+
{{-- Every drag tick fires --}}
-
+
{{-- Only fires on drag release --}}
-
+
{{-- Coalesce ticks into one event after 300ms idle --}}
-
+
+
+Intensity: {{ $intensity }}
```
@endverbatim
-`live` is the default and stress-tests the runtime's round-trip; `blur` is the most efficient for unsteady hands;
-`debounce` is the middle ground. Omit the interval (`native:model.debounce`) and it defaults to 300ms.
+`intensity` is a public property on your component (`public int $intensity = 50;`). All three sliders bind
+the same property, so dragging any one of them syncs the others and the echo — notice *when* each modifier
+pushes its update. `live` is the default and stress-tests the runtime's round-trip; `blur` is the most
+efficient for unsteady hands; `debounce` is the middle ground. Omit the interval (`native:model.debounce`)
+and it defaults to 300ms.
## Examples
@@ -61,21 +73,30 @@ Margin classes position the slider; the active track and thumb colors come from
@verbatim
```blade
+@php $volume = 40; @endphp
+
-
- Volume
- {{ $volume }}%
+
+ Volume
+ {{ $volume }}%
```
@endverbatim
+Declare `volume` as a public property on your component (`public int $volume = 40;`) and the label
+tracks the thumb as it settles.
+
### Stepped picker
@verbatim
```blade
+@php $rating = 3; @endphp
+
+
+Rating: {{ $rating }} / 5
```
@endverbatim
diff --git a/resources/views/docs/mobile/4/edge-components/spacer.md b/resources/views/docs/mobile/4/edge-components/spacer.md
index 384d87ab..1c127c1d 100644
--- a/resources/views/docs/mobile/4/edge-components/spacer.md
+++ b/resources/views/docs/mobile/4/edge-components/spacer.md
@@ -9,7 +9,7 @@ A flexible space element that expands to fill remaining space within a column or
push elements apart without calculating explicit sizes.
@verbatim
-```blade
+```blade static
```
@endverbatim
@@ -48,7 +48,7 @@ See the full shared list at [Layout & Styling](layout#supported-tailwind-classes
@verbatim
```blade
-
+WelcomeGet started with your app.
@@ -57,6 +57,10 @@ See the full shared list at [Layout & Styling](layout#supported-tailwind-classes
```
@endverbatim
+In a real app this column is usually the page root with `h-full`, so the spacer pushes the button to the bottom of the
+screen. The fixed `h-[220]` here just gives the preview a bounded height — a spacer can only grow when its parent's
+main axis is constrained.
+
### Toolbar with right-aligned trailing icon
@verbatim
@@ -75,7 +79,7 @@ See the full shared list at [Layout & Styling](layout#supported-tailwind-classes
```blade
Section One
-
+ Section Two
```
@@ -83,8 +87,9 @@ See the full shared list at [Layout & Styling](layout#supported-tailwind-classes
@@ -93,6 +98,6 @@ often more readable.
```php
use Native\Mobile\Edge\Elements\Spacer;
-Spacer::make(); // flex-grow: 1
-Spacer::make()->height(8); // fixed 8dp vertical
+Spacer::make(); // flex-grow: 1
+Spacer::make()->height(8)->flexGrow(0); // fixed 8dp vertical
```
diff --git a/resources/views/docs/mobile/4/edge-components/stack.md b/resources/views/docs/mobile/4/edge-components/stack.md
index 7f21d368..f4a89d75 100644
--- a/resources/views/docs/mobile/4/edge-components/stack.md
+++ b/resources/views/docs/mobile/4/edge-components/stack.md
@@ -12,10 +12,10 @@ Useful for badges, image overlays, floating labels, and layered UI effects.
@verbatim
```blade
-
-
+
+
- Overlay Text
+ Overlay Text
```
@@ -51,12 +51,15 @@ Everything else from the shared list applies as on any element (`p-*`, `m-*`, `b
@verbatim
```blade
-
+
```
@endverbatim
+In a real app the base layer would typically be a `` avatar (e.g.
+``).
+
### Badge on an icon
@verbatim
@@ -75,8 +78,8 @@ Everything else from the shared list applies as on any element (`p-*`, `m-*`, `b
@verbatim
```blade
-
-
+
+ Featured ArticleRead more about this topic
@@ -100,7 +103,7 @@ use Native\Mobile\Edge\Elements\Image;
use Native\Mobile\Edge\Elements\Text;
Stack::make(
- Image::make('https://example.com/photo.jpg'),
+ Image::make('https://picsum.photos/seed/nativephp/400/300'),
Text::make('Overlay'),
)->width(200)->height(200);
```
diff --git a/resources/views/docs/mobile/4/edge-components/tab-row.md b/resources/views/docs/mobile/4/edge-components/tab-row.md
index 0f35125c..310c1d06 100644
--- a/resources/views/docs/mobile/4/edge-components/tab-row.md
+++ b/resources/views/docs/mobile/4/edge-components/tab-row.md
@@ -12,19 +12,24 @@ Distinct from [``](bottom-nav) — bottom nav is your app's p
URL routing, while `` is an in-screen sectioning control whose tabs swap content within the same
screen.
-Per Model 3, the active tab uses `theme.primary` and the underline is `theme.primary`. Inactive tabs use
+Per Material 3, the active tab uses `theme.primary` and the underline is `theme.primary`. Inactive tabs use
`theme.onSurfaceVariant`.
@verbatim
```blade
+@php $activeTab = 0; @endphp
+
-
+
```
@endverbatim
+`activeTab` is a public int property on your component — the `@php` line stands in for
+`public int $activeTab = 0;`.
+
## Props (Row)
- `value` / `selected-index` - Currently selected tab index (optional, int, default: `0`)
@@ -38,24 +43,31 @@ Per Model 3, the active tab uses `theme.primary` and the underline is `theme.pri
## Two-way Binding
-`native:model` binds the selected index to an integer property on your component:
+`native:model` binds the selected index to an integer property on your component. Tapping a tab syncs the new
+index back automatically:
@verbatim
```blade
-
+@php $currentTab = 0; @endphp
+
+
+
+Selected: {{ ['One', 'Two', 'Three'][$currentTab] }}
```
@endverbatim
+Here `currentTab` stands in for `public int $currentTab = 0;` on your component.
+
## Children
`` declares a single tab. Each accepts:
- `label` - Tab label (required, string). Can also be passed as the first argument to `make()`
-- `icon` - Optional [icon](icons) name rendered above the label
+- `icon` - Optional [icon](icon#icon-name-reference) name rendered above the label
- `a11y-label` - Accessibility label override (optional)
## Examples
@@ -64,7 +76,9 @@ Per Model 3, the active tab uses `theme.primary` and the underline is `theme.pri
@verbatim
```blade
-
+@php $section = 0; @endphp
+
+
@@ -72,30 +86,35 @@ Per Model 3, the active tab uses `theme.primary` and the underline is `theme.pri
@if($section === 0)
-
- Overview content
+
+ Overview content
@elseif($section === 1)
-
- Activity content
+
+ Activity content
@else
-
- Members content
+
+ Members content
@endif
```
@endverbatim
+`section` is a public int property on your component (`public int $section = 0;`). On a real screen you would
+typically add `fill` to the outer column and the content panes so they occupy the remaining screen height.
+
### Tabs with icons
@verbatim
```blade
+@php $filter = 0; @endphp
+
-
+
```
@endverbatim
@@ -109,7 +128,7 @@ use Nativephp\NativeUi\Elements\Tab;
TabRow::make(
Tab::make('Recent')->icon('history'),
Tab::make('Starred')->icon('star'),
- Tab::make('Archived')->icon('archive'),
+ Tab::make('Archived')->icon('archive-box'),
)
->selectedIndex($activeTab)
->onChange('setActiveTab');
@@ -126,4 +145,4 @@ TabRow::make(
### `Tab` methods
- `make(string $label = '')` - Create a tab with a label
-- `icon(?string $name = null, IosSymbol|string|null $ios = null, AndroidSymbol|string|null $android = null)` - Tab icon. Pass a shared [icon](icons) name, or override per platform with the `ios:` / `android:` named arguments
+- `icon(?string $name = null, IosSymbol|string|null $ios = null, AndroidSymbol|string|null $android = null)` - Tab icon. Pass a shared [icon](icon#icon-name-reference) name, or override per platform with the `ios:` / `android:` named arguments
diff --git a/resources/views/docs/mobile/4/edge-components/text-input.md b/resources/views/docs/mobile/4/edge-components/text-input.md
index c4f7b4c0..de76304b 100644
--- a/resources/views/docs/mobile/4/edge-components/text-input.md
+++ b/resources/views/docs/mobile/4/edge-components/text-input.md
@@ -16,12 +16,14 @@ All three share the same prop set and event API. Choose the outlined / filled pa
reach for bare when you want to style the input yourself.
On iOS the outlined and filled variants render as SwiftUI `TextField` / `SecureField` with Material3-style chrome; on
-Android they map to `OutlinedTextField` / `TextField` (filled). Per Model 3 these two have no per-instance color or
+Android they map to `OutlinedTextField` / `TextField` (filled). Per Material 3 these two have no per-instance color or
border overrides — all chrome resolves from the theme. For fully custom input visuals reach for the bare variant, or
drop to [``](pressable) wrapping your own drawing.
@verbatim
```blade
+@php $email = ''; @endphp
+
`](pressable) wrapping your own drawing.
```
@endverbatim
+`email` is a public string property on your component — the `@php` line stands in for
+`public string $email = '';` and seeds the inline preview.
+
## Props
All three variants accept the same shared prop set. The bare variant adds a `color` attribute on top — see
@@ -111,12 +116,19 @@ Use the `native:model` directive for automatic two-way binding with a component
@verbatim
```blade
-
-
-
+@php $name = 'Ada'; $email = ''; $search = ''; @endphp
+
+
+
+
+
+Hello, {{ $name }}!
```
@endverbatim
+`name`, `email`, and `search` are public string properties on your component — typing syncs them back
+automatically, so the `{{ $name }}` echo updates as you type.
+
`sync-mode` semantics:
- `live` (default) — every keystroke fires `@change`
@@ -142,6 +154,8 @@ Two things set it apart:
@verbatim
```blade
+@php $draft = ''; @endphp
+
```
@@ -173,6 +189,8 @@ The `color` attribute can be set explicitly or picked up from a `text-*` class o
@verbatim
```blade
+@php $email = ''; $password = ''; @endphp
+
+
Hello, world!
```
@@ -58,7 +58,7 @@ into your app's `resources/fonts/` directory, then reference one by its filename
@verbatim
```blade
-
+
Custom heading
```
@@ -128,7 +128,7 @@ Arbitrary values are supported too: `leading-[1.4]` (multiplier) or `leading-[24
@verbatim
```blade
-
+
A comfortably spaced paragraph that wraps across several lines with a little
extra breathing room between them.
@@ -160,7 +160,7 @@ Style text with Tailwind classes — these compose with `text-*` size and `font-
@verbatim
```blade
-
+
Styled with Tailwind
```
@@ -193,8 +193,8 @@ whole region selectable. Use `select-none` to opt a nested subtree back out:
@verbatim
```blade
- Selectable heading
- This body copy can be selected and copied.
+ Selectable heading
+ This body copy can be selected and copied.Not selectable
@@ -226,13 +226,13 @@ Use the `dark:` prefix with Tailwind classes or pass a dark-mode color override.
@verbatim
```blade
-Thin (1)
-Light (2)
-Regular (3)
-Medium (4)
-SemiBold (5)
-Bold (6)
-Heavy (7)
+Thin (1)
+Light (2)
+Regular (3)
+Medium (4)
+SemiBold (5)
+Bold (6)
+Heavy (7)
```
@endverbatim
@@ -240,7 +240,7 @@ Use the `dark:` prefix with Tailwind classes or pass a dark-mode color override.
@verbatim
```blade
-
+
This text will be truncated with an ellipsis after two lines if it overflows
the available space in its container.
@@ -251,7 +251,7 @@ Use the `dark:` prefix with Tailwind classes or pass a dark-mode color override.
@verbatim
```blade
-
+
Welcome Back
```
@@ -261,7 +261,7 @@ Use the `dark:` prefix with Tailwind classes or pass a dark-mode color override.
@verbatim
```blade
-
+
Learn more
```
@@ -271,12 +271,16 @@ Use the `dark:` prefix with Tailwind classes or pass a dark-mode color override.
@verbatim
```blade
-
+@php $score = 1250; @endphp
+
+
Score: {{ $score }}
```
@endverbatim
+Here `$score` stands in for a public property on your component — `public int $score = 1250;`.
+