UNPKG

alouette

Version:

A modern, customizable design system built on top of NativeWind v5 with configurable defaults

209 lines (161 loc) • 8.41 kB
--- name: alouette-inputs description: > The controls that take a value from the user. InputText is the text field, whose mode sets the keyboard, autocomplete and secure entry together; TextArea is its multiline twin, InputPassword adds the show/hide toggle, and InputCode is a one-time code (never a row of InputTexts). Switch applies a setting at once; a standalone Checkbox is a form opt-in. Select picks one value from a known list and InputTextAutocomplete narrows that list by typing. Single-select groups compose their children, never an options array: RadioGroup (a list), RadioButtonGroup (a segmented pill, behind the light/dark ColorModePicker) and RadioCardGroup (cards); multi-select CheckboxGroup and CheckboxCardGroup. A choice that moves between routes is navigation, not a radio group. Binding these to a validated form is alouette-forms. Load when adding a text field, a password or code field, a dropdown, a toggle, checkboxes, radio buttons, a segmented choice, or a light/dark switch. sources: - packages/alouette/src/ui/inputs/InputText.tsx - packages/alouette/src/ui/inputs/InputPassword.tsx - packages/alouette/src/ui/inputs/InputCode.tsx - packages/alouette/src/ui/inputs/InputCode.stories.tsx - packages/alouette/src/ui/inputs/Select.shared.tsx - packages/alouette/src/ui/inputs/Select.tsx - packages/alouette/src/ui/inputs/Select.web.tsx - packages/alouette/src/ui/inputs/InputTextAutocomplete.shared.tsx - packages/alouette/src/ui/inputs/InputTextAutocomplete.tsx - packages/alouette/src/ui/inputs/InputTextAutocomplete.web.tsx - packages/alouette/src/ui/inputs/InputTextAutocomplete.stories.tsx - packages/alouette/src/ui/inputs/TextArea.tsx - packages/alouette/src/ui/inputs/Switch.tsx - packages/alouette/src/ui/inputs/Switch.web.tsx - packages/alouette/src/ui/inputs/RadioGroup.tsx - packages/alouette/src/ui/inputs/Radio.tsx - packages/alouette/src/ui/inputs/RadioButtonGroup.tsx - packages/alouette/src/ui/inputs/RadioButton.tsx - packages/alouette/src/ui/inputs/RadioCardGroup.tsx - packages/alouette/src/ui/inputs/RadioCard.tsx - packages/alouette/src/ui/inputs/RadioCardGroup.stories.tsx - packages/alouette/src/ui/inputs/CheckboxGroup.tsx - packages/alouette/src/ui/inputs/Checkbox.tsx - packages/alouette/src/ui/inputs/CheckboxCardGroup.tsx - packages/alouette/src/ui/inputs/CheckboxCard.tsx - packages/alouette/src/ui/inputs/ColorModePicker.tsx - packages/alouette/src/ui/inputs/ColorModePicker.stories.tsx --- This skill builds on alouette-theming (token model). Read it first. # alouette — Inputs The raw controls. Each one works on its own, controlled (`value` + `onChangeText` / `onValueChange`) or not; inside a validated form the same control is rendered from a `FormField`'s `render`, which hands it the field bindings and the label/error wiring (alouette-forms/SKILL.md). ## Core Patterns ```tsx import { InputText } from "alouette"; <InputText mode="email" value={email} onChangeText={setEmail} placeholder="you@example.com" />; ``` ### Input modes `mode` bundles the right keyboard, input mode, autocomplete and secure entry: `"password" | "email" | "number" | "tel" | "url" | "search" | "webSearch"`. A one-time code (SMS, e-mail, authenticator) is `InputCode`, never a row of `InputText`s: one input holds the code behind its cells, so paste, OS autofill, Backspace and the screen reader see a single field. Modes, `onComplete` and the form wiring: [references/input-code.md](references/input-code.md). A password is `InputPassword`, not `mode="password"`: that mode plus an eye toggle in the field (`aria-pressed` while the password shows, named by `toggleLabel`, default "Show password"), controlled through `visible` / `defaultVisible` / `onVisibleChange`. Pass `autoComplete="new-password"` on a sign-up form. ### Slots: a glyph or an icon button in the field `startSlot` / `endSlot` overlay the field's leading / trailing square (`control-md`), the text padded past them: an `Icon` carrying its own ink (`text-muted`, or `text-form-disabled-text` on a disabled field) or a `soft` `sm` `IconButton`. Fixed-width content only, never a prefix text. With a slot, `className` lands on the frame around the input, the box the parent lays out. ```tsx <InputPassword autoComplete="new-password" toggleLabel="Afficher le mot de passe" /> <InputText placeholder="Search" startSlot={<Icon icon={<MagnifyingGlassRegularIcon />} className="text-muted" />} /> <InputText endSlot={<IconButton variant="soft" size="sm" icon={<CalendarBlankRegularIcon />} aria-label="Pick a date" onPress={openPicker} />} /> ``` ### TextArea, Switch, disabled ```tsx <TextArea value={notes} onChangeText={setNotes} placeholder="Notes" /> <Switch checked={on} onValueChange={setOn} /> {/* controlled */} <Switch onValueChange={(v) => log(v)} /> {/* uncontrolled */} <InputText disabled value={value} /> <Switch disabled checked={on} /> ``` ### Select, autocomplete and single-select groups `Select` picks one value from a list without typing; `InputTextAutocomplete` is a text field backed by a filtered listbox, for narrowing that list by typing. Three single-select families share one group-owns-the-value API and compose their children rather than take an options array: `RadioGroup` + `Radio` (circle-dot list), `RadioButtonGroup` + `RadioButton` (segmented pill bar) and `RadioCardGroup` + `RadioCard` (icon/label/description cards). Multi-select: `CheckboxGroup`, `CheckboxCardGroup` (`values: string[]`) and a standalone boolean `Checkbox` for form opt-ins (an immediate setting stays a `Switch`). `RadioButtonGroup` also takes `variant="icon"` — a pill of square icon-only chips, each option's `label` staying its accessible name. `ColorModePicker` is the light/dark control built on it: it reports a `ColorModePreference` and the app applies it by passing it to a `ScopedTheme` (alouette-theming/SKILL.md). Props, platform behavior and examples: [references/choice-inputs.md](references/choice-inputs.md). ## Common Mistakes ### MEDIUM Disabling an input with editable={false} Wrong: ```tsx <InputText editable={false} /> ``` Correct: ```tsx <InputText disabled /> ``` `InputText` exposes a `disabled` prop that sets `editable`, `aria-disabled` and the disabled styling together; passing `editable` directly skips the disabled visual state and a11y. Source: packages/alouette/src/ui/inputs/InputText.tsx ### MEDIUM Setting keyboardType / secureTextEntry by hand Wrong: ```tsx <InputText secureTextEntry autoComplete="current-password" /> <InputText keyboardType="email-address" inputMode="email" /> ``` Correct: ```tsx <InputPassword /> <InputText mode="email" /> ``` The `mode` prop bundles `inputMode` + `keyboardType` + `autoComplete` + `secureTextEntry` consistently across platforms; setting them piecemeal is error-prone. A password also gets its show/hide toggle from `InputPassword`. Source: packages/alouette/src/ui/inputs/InputText.tsx (MODE_PROPS); ui/inputs/InputPassword.tsx ### MEDIUM Wiring Switch like a web checkbox Wrong: ```tsx <Switch value={on} onChange={(e) => setOn(e.target.checked)} /> ``` Correct: ```tsx <Switch checked={on} onValueChange={setOn} /> ``` `Switch` is controlled via `checked` and reports through `onValueChange(value: boolean)`. `value`/`onChange` with `e.target` do nothing in React Native. Source: packages/alouette/src/ui/inputs/Switch.tsx ### MEDIUM Picking the wrong single-select family `RadioGroup` + `Radio`: vertical circle-dot list (longer option lists, labeled form fields). `RadioButtonGroup` + `RadioButton`: horizontal segmented pill bar (2–4 compact, equal-weight choices like view mode or time range). `RadioCardGroup` + `RadioCard`: cards, for a few options that each need an icon and a line of explanation. None of the three replaces the two components for long lists: `Select` when the value is picked from the list, `InputTextAutocomplete` when the user types to narrow it. The three share one context, so a child must sit inside its own group: a `RadioCard` under a `RadioGroup` renders, but a `Radio` outside any of the three throws "Radio, RadioButton and RadioCard must be rendered inside a RadioGroup, RadioButtonGroup or RadioCardGroup." Source: packages/alouette/src/ui/inputs/RadioGroup.tsx; ui/inputs/RadioButtonGroup.tsx; ui/inputs/RadioCardGroup.tsx