components/formcompose
Inputs · 11 / 64

Form Composition

Input · Select · Button

Input, Select and Button mixed at one size: a filter toolbar and a business form.

BEHAVIOR CONTRACT

All three share ControlSize (box height XS 20 / SM 24 / MD 32 / LG 40), so height, radius, type, icons and spacing line up at each size.

RECORDED INTERACTION

The harness filters by status and owner and types a search in the toolbar, then fills in the customer, region and amount in the form.

examples/storybook/form_composition.zig:185
pub fn build(scope: *ui.Scope, cx: *ui.Cx) anyerror!*ui.Node {
    const a = cx.allocator;
    const root = try ui.box(cx, .{ .direction = .column, .gap = 16 }, .{});
    tag(root, "story.formcompose.root");

    try root.appendChild(a, try heading(cx, "Filter toolbar · same size"));
    try root.appendChild(a, try caption(cx, "Input / Select / Button share ControlSize: XS 20 · SM 24 · MD 32 · LG 40 px"));
    inline for (sizes) |spec| {
        try root.appendChild(a, try filterToolbar(spec, scope, cx));
    }

    try root.appendChild(a, try heading(cx, "Business form · MD"));
    try root.appendChild(a, try orderForm(scope, cx));
    return root;
}
View source on GitHubexamples/storybook/form_composition.zig:185

The story's verbatim source from the Storybook (zenit 4c50245 2026-10-01). W is ui.widgets; col / row / label are small Storybook layout helpers.

zenit · Dual-licensedFree for open-source projects under GPL-3.0-only; closed-source or commercial products need a commercial license.Contact the author: zongyi.xzy#gmail.com (replace # with @)zenit 4c50245 2026-10-01