io.select.singleNative

One choice in the browser's own drop-down.

io.select.singleNative asks to pick one option from the browser's own <select>. The list that opens is drawn by the browser and the operating system. It suits short lists, such as a role or a plan. The handler gets the chosen option itself, not a string.

The simplest one

The whole action file, and roughly what your team sees when it runs.

src/actions/accounts/changePlanAction.ts
import { app } from '../../app';
export const changePlanAction = app.defineAction({
name: 'Change plan',
handler: async ({ io }) => {
const plan = await io.select.singleNative('Plan', {
options: ['Free', 'Team', 'Business'],
defaultValue: 'Team',
});
},
});
The code. One call in an action, the whole file.
tools.example.com/actions/accounts/change_plan

Change plan

PlanTeam⇅
Free✓TeamBusiness
Continue
In the browser. Roughly what your team sees. Your theme decides the details.

What you can set

The settings you will reach for most, each with the line of code that turns it on.

io.select.singleNative('Plan', { options })

The browser's own select. A plain <select>, nothing drawn on top. The menu that opens is the one the system draws.

options: ['Free', 'Team', 'Business']

Made for short lists. No search as you type and no × to clear. For a long list, use io.select.single.

label: (account) => account.name

Records from your database. Name rows with key and label. The handler gets the record back, relations and dates included.

defaultValue: user.accountId

A starting choice by id. defaultValue takes the option or just its key. The id stored on a record is enough.

io.select.singleNative(…).optional()

Optional when you say so. The field is required by default. Chain .optional() and an empty field gives undefined.

.validate((plan) => message)

Checked on the server. A value that was not offered is sent back. .validate() adds a check of your own after that.

Write your first tool today.

An async function, a few await calls, and the form is in the browser.

AwaitIO is free for small teams, made possible by companies and people who sponsor it.