---
title: Select
url: "https://native-sdk.dev/docs/components/select"
docs_index: /llms.txt
lastUpdated: 2026-10-16
---

> For an index of all documentation, see [/llms.txt](/llms.txt).

Use `select` as a trigger for a choice menu. Its content displays the current value; `placeholder` displays when it is empty. Handle `on-press` to open an anchored [dropdown-menu](/docs/components/dropdown-menu) containing `menu-item` options. Place the trigger and conditional menu in a `stack`. The model owns the open flag and clears it on selection or `on-dismiss`.

The selected option has a checkmark. Keyboard and pointer focus use a separate highlight, so moving through the menu does not change the committed value. For text entry with suggestions, see [combobox](/docs/components/combobox).

## Markup

Place the trigger and menu in a `stack`. Set `anchor="below"` and `anchor-alignment="stretch"` to align the menu below the trigger at the same width. Both `pick_env` and `close_env_picker` clear `env_picker_open` in `update`.

Enter, Space, or an arrow key activates the focused trigger. In the menu, Up/Down move through options from the selected item; Home/End move to the first or last. Enter or a click selects an option. Escape, Tab, or a click outside dispatches `on-dismiss` without changing the value. Focus returns to the trigger.

```html
<stack width="240">
  <select placeholder="Choose environment" on-press="toggle_env_picker">{envName}</select>
  <if test="{env_picker_open}">
    <dropdown-menu anchor="below" anchor-alignment="stretch" on-dismiss="close_env_picker">
      <for each="environments" key="id" as="e">
        <menu-item selected="{e.id == env_id}" on-press="pick_env:{e.id}">{e.name}</menu-item>
      </for>
    </dropdown-menu>
  </if>
</stack>
```

The core side is the open flag, the committed choice, and three arms:

```ts
// model: { readonly env_id: number; readonly env_picker_open: boolean }
case "toggle_env_picker":
  return { ...model, env_picker_open: !model.env_picker_open };
case "close_env_picker":
  return { ...model, env_picker_open: false };
case "pick_env":
  return { ...model, env_id: msg.id, env_picker_open: false };
```

```zig
.toggle_env_picker => model.env_picker_open = !model.env_picker_open,
.close_env_picker => model.env_picker_open = false,
.pick_env => |id| {
    model.env_id = id;
    model.env_picker_open = false;
},
```

## Programmatic construction (Zig)

In a Zig view, the `canvas.Ui` builder constructs the same tree programmatically:

```zig
ui.stack(.{ .width = 240 }, .{
    ui.el(.select, .{
        .text = model.envName(),
        .placeholder = "Choose environment",
        .on_press = .toggle_env_picker,
    }, .{}),
    if (model.env_picker_open) ui.el(.dropdown_menu, .{
        .anchor = .below,
        .anchor_alignment = .stretch,
        .on_dismiss = .close_env_picker,
    }, .{
        ui.el(.menu_item, .{ .text = "Production", .selected = model.env_id == 0, .on_press = .{ .pick_env = 0 } }, .{}),
        ui.el(.menu_item, .{ .text = "Staging", .selected = model.env_id == 1, .on_press = .{ .pick_env = 1 } }, .{}),
        ui.el(.menu_item, .{ .text = "Development", .selected = model.env_id == 2, .on_press = .{ .pick_env = 2 } }, .{}),
    }) else ui.spacer(0),
})
```

## Attributes

| Attribute     | Description                                                                                                                                                                                                                                                                                                   |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `text`        | Text value for text-bearing elements; a literal or one \{binding}.                                                                                                                                                                                                                                            |
| `placeholder` | Hint text shown while a text entry is empty.                                                                                                                                                                                                                                                                  |
| `disabled`    | Disables the control; true/false or a \{binding}.                                                                                                                                                                                                                                                             |
| `on-press`    | Dispatch a Msg on press: tag or tag:\{payload}. Legal on any element — a bound press handler makes it pressable, and presses on plain text/icons inside it fall through to it (dragging still selects text).                                                                                                  |
| `on-dismiss`  | Dismissible surfaces only (dialog, drawer, sheet, dropdown-menu): Msg dispatched when Escape or a click outside dismisses the surface, so the MODEL owns the close (clear the open flag in update). The engine hides the surface immediately as an optimistic echo; the source tree wins on the next rebuild. |

---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)