Skip to content
Merged
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/src/app/docs/cli/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Write an owned `build.zig`/`build.zig.zon` into the app (once); the verbs then d
native eject component <name> [dir]
```

Write an owned copy of a library composite into `src/components/` (once, never overwriting — ejecting again errors with the file to delete first). Ejectable today: `stepper`, `timeline`, `timeline-item` — the library views that are honest compositions of primitives; engine controls are not on the menu (theme them through [tokens](/docs/theming) instead). `timeline` lands as a markup template (use it via `<use template="timeline" ...>`), the others as Zig view functions; each file opens with a header comment walking through the call-site migration, and each builds a widget tree identical to its library form at the moment of ejection. Unknown names get a did-you-mean plus the full ejectable list. See [Building Components](/docs/building-components#use-eject-or-build).
Write an owned copy of a library composite into `src/components/` (once, never overwriting — ejecting again errors with the file to delete first). Ejectable today: `stepper`, `timeline`, `timeline-item` — the library views that are compositions of primitives; engine controls are not on the menu (theme them through [tokens](/docs/theming) instead). All three eject as Native markup templates, so they work in TypeScript apps without an app-side Zig file; use them through `<import>` and `<use>`. Each file opens with a header comment walking through the call-site migration, and each builds a widget tree identical to its library form at the moment of ejection. Unknown names get a did-you-mean plus the full ejectable list. See [Building Components](/docs/building-components#use-eject-or-build).

### `native doctor`

Expand Down
2 changes: 1 addition & 1 deletion docs/src/app/docs/components/button/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Four sizes: `sm`, `default`, `lg`, and `icon` — the icon size renders a square

## Icons

`icon` names a built-in vector icon (see the [icon registry](/docs/components/icon)) drawn inline before the label — one hit target, one enabled/disabled tint.
`icon` names a built-in vector icon (see the [icon registry](/docs/components/icon)) drawn inline before the label — one hit target, one enabled/disabled tint. For an image-free icon button, use `size="icon"` with empty content and provide `label` for its accessible name. Registered-image button content remains a separate asset-lifecycle proposal.

<ComponentPreview name="button-icons" alt="Buttons with inline icons rendered by the engine" />

Expand Down
7 changes: 7 additions & 0 deletions docs/src/app/docs/components/segmented-control/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { pageMetadata } from "@/lib/page-metadata";

export const metadata = pageMetadata("components/segmented-control");

export default function SegmentedControlLayout({ children }: { children: React.ReactNode }) {
return children;
}
47 changes: 47 additions & 0 deletions docs/src/app/docs/components/segmented-control/page.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { ComponentPreview } from "@/components/component-preview";
import { AttrTable } from "@/components/attr-table";

# Segmented Control

A standalone exclusive-choice segment. Each `segmented-control` is one named, pressable item: bind `selected` from the model, dispatch `on-press`, and add a vector `icon` when the label benefits from one. Put several in a row for a compact choice control; use [tabs](/docs/components/tabs) when you also need the tab-strip container and conditional panel.

<ComponentPreview name="segmented-control" alt="Standalone segmented controls rendered by the engine" caption="Day, Week, and Month segments with Week selected" />

## Markup

```html
<row gap="6">
<segmented-control selected="{range == 'day'}" on-press="choose_day">Day</segmented-control>
<segmented-control selected="{range == 'week'}" icon="settings" on-press="choose_week">Week</segmented-control>
<segmented-control selected="{range == 'month'}" on-press="choose_month">Month</segmented-control>
</row>
```

`selected` is model-owned. Pressing a segment sends its message; the next view rebuild reflects the new selection. The segment itself is a text-bearing control, so it needs visible content or a `label` accessible name.

## Icons and sizes

The `icon` attribute uses the same closed vector-icon vocabulary as [button](/docs/components/button). It is drawn as part of the segment's own hit target and follows the segment's state tint. `size` selects the shared control register; `label` supplies an accessible name when the visible content is absent.

```html
<row gap="6">
<segmented-control size="sm" selected="{view == 'list'}" icon="file-text" label="List" on-press="show_list" />
<segmented-control size="sm" selected="{view == 'board'}" icon="settings" label="Board" on-press="show_board" />
</row>
```

## Programmatic construction (Zig)

In a Zig view, use the same retained widget kind directly with `canvas.Ui`:

```zig
ui.row(.{ .gap = 6 }, .{
ui.el(.segmented_control, .{ .text = "Day", .selected = model.range == .day, .on_press = .choose_day }, .{}),
ui.el(.segmented_control, .{ .text = "Week", .icon = "settings", .selected = model.range == .week, .on_press = .choose_week }, .{}),
ui.el(.segmented_control, .{ .text = "Month", .selected = model.range == .month, .on_press = .choose_month }, .{}),
})
```

## Attributes

<AttrTable attrs={["text", "selected", "disabled", "size", "icon", "icon-placement", "label", "key", "global-key", "on-press", "on-hold"]} />
2 changes: 1 addition & 1 deletion docs/src/app/docs/components/stepper/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ A stage stepper: `step` children joined by hairline connectors, with `active` na

## Markup

`active` is required — a number or one `{binding}`.
`active` is required — a number or one `{binding}`. The component is also ejectable as a markup template when you need to own its shape.

```html
<stepper active="{publish_step}">
Expand Down
4 changes: 2 additions & 2 deletions docs/src/app/docs/components/tabs/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { AttrTable } from "@/components/attr-table";

# Tabs

A tab strip: ONE muted rounded container (the house tab-strip treatment) whose triggers sit inside it — the active trigger lifts to the surface with a hairline, inactive triggers stay muted on the container's wash. The children are [buttons](/docs/components/button) whose `selected` state marks the active tab — usually an equality against a model field — and whose `on-press` switches it. The segmented-control foundation is what the engine renders tab triggers with: both markup engines lower `<button>` children of `<tabs>` to `segmented_control` widgets (the builder uses `segmented_control` children directly), so the strip renders identically however it is authored. The panel itself is ordinary conditional content: an `if` per tab under the strip.
A tab strip: ONE muted rounded container (the house tab-strip treatment) whose triggers sit inside it — the active trigger lifts to the surface with a hairline, inactive triggers stay muted on the container's wash. The children are [buttons](/docs/components/button) whose `selected` state marks the active tab — usually an equality against a model field — and whose `on-press` switches it. The segmented-control foundation is also available directly as `<segmented-control>` leaves: both markup engines lower `<button>` children of `<tabs>` to `segmented_control` widgets (the builder uses `segmented_control` children directly), so the strip renders identically however it is authored. The panel itself is ordinary conditional content: an `if` per tab under the strip.

<ComponentPreview name="tabs" alt="A tab strip rendered by the engine" caption="Account selected in a three-tab strip" />

Expand Down Expand Up @@ -33,7 +33,7 @@ A tab strip: ONE muted rounded container (the house tab-strip treatment) whose t

## Programmatic construction (Zig)

In a Zig view, the `canvas.Ui` builder constructs the same tree programmatically. In the builder the strip's children are `segmented_control` elementsthe widget kind the engine's tab strips are built on (segmented controls are a documented markup exclusion, so markup composes the strip from buttons instead).
In a Zig view, the `canvas.Ui` builder constructs the same tree programmatically. In the builder the strip's children are `segmented_control` elements, the same widget kind available as a standalone markup leaf.

```zig
ui.el(.tabs, .{}, .{
Expand Down
2 changes: 1 addition & 1 deletion docs/src/app/docs/components/timeline/page.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { EjectSection } from "@/components/eject-section";

# Timeline

A timeline/ledger list container: a vertical column of `timeline-item` children (`for` and `if` work inside it). Each item pairs a leading indicator badge — `indicator` text or a small dot, colored by `variant` — with a title/description/meta content column, joined by a connector rail; set `connector="false"` on the last item to end the rail. Binding `on-press` makes the whole item pressable with a trailing chevron. For a horizontal stage indicator, see [stepper](/docs/components/stepper).
A timeline/ledger list container: a vertical column of `timeline-item` children (`for` and `if` work inside it). Each item pairs a leading indicator badge — `indicator` text or a small dot, colored by `variant` — with a title/description/meta content column, joined by a connector rail; set `connector="false"` on the last item to end the rail. Binding `on-press` makes the whole item pressable with a trailing chevron. Both the container and item can be ejected as markup templates when you need to own their shape. For a horizontal stage indicator, see [stepper](/docs/components/stepper).

<ComponentPreview name="timeline" alt="A timeline rendered by the engine" caption="indicator badges, titles with descriptions and meta lines, and the connector rail" />

Expand Down
Loading
Loading