# Select

> Dropdown single-select input for choosing from predefined options.

**URL:** https://inference.sh/docs/agents/widgets/select
**Last updated:** 2026-09-18

---

Dropdown single-select input for choosing from predefined options.

## Preview

```
[Select an option... ▼]
```

## Usage

```go
node := models.WidgetNode{
    Type:        models.WidgetNodeTypeSelect,
    Name:        "role",
    Placeholder: "Select role",
    Options: []models.WidgetSelectOption{
        {Label: "Admin", Value: "admin"},
        {Label: "Editor", Value: "editor"},
        {Label: "Viewer", Value: "viewer"},
    },
}
```

## Props

| Name | Type | Description | Default |
|------|------|-------------|---------|
| `type` | `"select"` | Node type | required |
| `name` | `string` | Form field name (key in form data) | required |
| `placeholder` | `string` | Placeholder text when no selection | `"Select..."` |
| `options` | `WidgetSelectOption[]` | Available options | required |
| `required` | `boolean` | Whether selection is required | `false` |
| `onChangeAction` | `WidgetAction` | Action triggered when selection changes | - |

### WidgetSelectOption

| Name | Type | Description |
|------|------|-------------|
| `label` | `string` | Display text |
| `value` | `string` | Value submitted in form data |

## Examples

### Basic Select

```go
{
    Type:        models.WidgetNodeTypeSelect,
    Name:        "priority",
    Placeholder: "Select priority",
    Options: []models.WidgetSelectOption{
        {Label: "Low", Value: "low"},
        {Label: "Medium", Value: "medium"},
        {Label: "High", Value: "high"},
    },
}
```

### Select with Change Action

Trigger an action immediately when the selection changes:

```go
{
    Type:        models.WidgetNodeTypeSelect,
    Name:        "country",
    Placeholder: "Select country",
    Options: []models.WidgetSelectOption{
        {Label: "United States", Value: "us"},
        {Label: "United Kingdom", Value: "uk"},
        {Label: "Canada", Value: "ca"},
    },
    OnChangeAction: &models.WidgetAction{
        Type:    "country_changed",
        Handler: "client",
    },
}
```

### With Form Layout

```go
widget := &models.Widget{
    Type:  models.WidgetTypeUI,
    Title: "Assign Task",
    Children: []models.WidgetNode{
        {
            Type: models.WidgetNodeTypeCol,
            Gap:  3,
            Children: []models.WidgetNode{
                {Type: models.WidgetNodeTypeLabel, Value: "Assignee", FieldName: "assignee"},
                {
                    Type:        models.WidgetNodeTypeSelect,
                    Name:        "assignee",
                    Placeholder: "Select team member",
                    Options: []models.WidgetSelectOption{
                        {Label: "Alice", Value: "alice"},
                        {Label: "Bob", Value: "bob"},
                        {Label: "Charlie", Value: "charlie"},
                    },
                },
                {Type: models.WidgetNodeTypeLabel, Value: "Priority", FieldName: "priority"},
                {
                    Type:        models.WidgetNodeTypeSelect,
                    Name:        "priority",
                    Placeholder: "Select priority",
                    Options: []models.WidgetSelectOption{
                        {Label: "Low", Value: "low"},
                        {Label: "Medium", Value: "medium"},
                        {Label: "High", Value: "high"},
                    },
                },
                {
                    Type:    models.WidgetNodeTypeRow,
                    Gap:     2,
                    Justify: "end",
                    Children: []models.WidgetNode{
                        {
                            Type:    models.WidgetNodeTypeButton,
                            Label:   "Assign",
                            Variant: "default",
                            OnClickAction: &models.WidgetAction{
                                Type:            "assign_task",
                                LoadingBehavior: "self",
                            },
                        },
                    },
                },
            },
        },
    },
}
```

### Dynamic Options

Build options from data:

```go
func buildUserSelectOptions(users []User) []models.WidgetSelectOption {
    options := make([]models.WidgetSelectOption, len(users))
    for i, user := range users {
        options[i] = models.WidgetSelectOption{
            Label: user.Name,
            Value: user.ID,
        }
    }
    return options
}

node := models.WidgetNode{
    Type:        models.WidgetNodeTypeSelect,
    Name:        "user_id",
    Placeholder: "Select user",
    Options:     buildUserSelectOptions(users),
}
```

## Form Data

When the widget is submitted, the selected value is included:

```json
{
  "priority": "high",
  "assignee": "alice"
}
```

## TypeScript

```typescript
const node: WidgetNode = {
  type: "select",
  name: "role",
  placeholder: "Select role",
  options: [
    { label: "Admin", value: "admin" },
    { label: "User", value: "user" },
  ],
  onChangeAction: {
    type: "role_changed",
    handler: "client",
  },
}
```

## Best Practices

1. **Use descriptive labels** - Make options clear and unambiguous
2. **Order logically** - Alphabetical, by frequency, or by importance
3. **Limit options** - For 2-3 options, consider radio buttons instead
4. **Include placeholder** - Help users understand what to select
5. **Use onChangeAction for dependent fields** - Update other fields based on selection
