@timeax/form-palette
v0.1.27
Published
This package extracts and standardizes the **form + input + variant system** from an existing Laravel/Inertia/React project into a **reusable, framework-friendly** library
Maintainers
Readme
Index
- Form Palette
- Variant props + InputField usage
- Form Palette -
extraentrypoint (v2) - 1) Lister (runtime)
- 2)
useData()- deep dive (extremely important) - 3) JsonEditor (overview)
Form Palette
A small but powerful React form runtime built around three ideas:
- A single
<Form />shell that wires up state, submission and validation. <InputField />as the universal “field wrapper†that renders a registered variant (text, number, select, json-editor, etc.) and handles label / description / errors / layout.- Adapters that decide what “submit†means (
local,axios,inertia, or your own).
Quick start
Installation:
npm install @timeax/form-paletteimport * as React from "react";
import {
Form,
InputField,
registerCoreVariants,
registerAxiosAdapter,
registerInertiaAdapter,
} from "@timeax/form-palette";
// App boot (once)
registerCoreVariants();
registerAxiosAdapter();
await registerInertiaAdapter();If you only use one adapter, only register the one you need.
Form
Form is the main form component exported from the package entrypoint (it is CoreShell, re-exported as Form).
Minimal “local†form
Use adapter="local" when you want submission to be handled purely in JS.
function Example() {
return (
<Form
name="profile"
adapter="local"
onSubmit={(e) => {
// Current outbound snapshot
console.log(e.formData);
// You can also mutate outbound data via e.editData(...)
}}
>
<InputField
name="email"
variant="text"
label="Email"
required
/>
<InputField
name="age"
variant="number"
label="Age"
/>
<button type="submit">Save</button>
</Form>
);
}Axios adapter
<Form
name="profile"
adapter="axios"
url="/api/profile"
method="post"
onSubmitted={(form, payload) => {
console.log(payload);
}}
>
<InputField name="email" variant="text" label="Email" required />
<button type="submit">Save</button>
</Form>Inertia adapter
<Form
name="profile"
adapter="inertia"
url="/profile"
method="post"
onSubmitted={(form, payload) => {
// payload is the resolved inertia Page (or normalized error on failure)
console.log(payload);
}}
>
<InputField name="email" variant="text" label="Email" required />
<button type="submit">Save</button>
</Form>InputField
InputField is the form runtime’s “field wrapperâ€. It:
Pulls the chosen
variantfrom the variant registry and renders it.Connects to form state when used inside
<Form />(byname).Computes layout (label placement, helper slots, spacing, etc.) by combining:
- variant defaults
- host overrides
- optional
variant.resolveLayout(...)
Normalizes validation results into a consistent list of errors.
Basic usage
<InputField
name="username"
variant="text"
label="Username"
description="Public handle"
required
placeholder="@davy"
/>Helper slots
Most helper UI (description, help text, error text, tags, etc.) is rendered through a layout graph.
<InputField
name="bio"
variant="textarea"
label="Bio"
helpText="Keep it short"
errorText=""
/>Standalone mode
InputField can run without a surrounding <Form /> (it will fall back to a self-managed field state).
<InputField
variant="text"
label="Standalone"
defaultValue="Hello"
onChange={({ value }) => {
console.log(value);
}}
/>Adapters
Adapters define how the form submits.
Built-in adapter keys
local– no network; calls your callbacks.axios– HTTP submit via Axios.inertia– submit via Inertia.
Registering adapters
import { registerAdapter } from "@timeax/form-palette";
registerAdapter("my-adapter", (config) => {
return {
submit() {
// fire-and-forget
},
async send() {
// resolve a result shape that matches AdapterOk<"my-adapter">
return { data: config.data } as any;
},
run() {
this.submit();
},
};
});Adapter-specific props
Some adapters expose additional props on <Form /> (e.g. url, method, config).
Recommended boot order
- Register variants (so InputField can resolve
variant→ component). - Register the adapters you will use.
- Render forms.
registerCoreVariants();
registerAxiosAdapter();
await registerInertiaAdapter();Variant props + InputField usage
Below are the variant-specific props you can pass to <InputField /> for:
texttextareatoggle-groupnumberphonepasswordslidertoggletreeselectmulti-selectselectradiocheckboxchipscolordatekeyvalueeditorfileiconimage-iconjson-editorlistercustom
Note: Some props like
value,onValue,error,disabled,readOnly,size,densityare typically injected by the core runtime/InputField. The tables focus on the props you usually configure.
text
Variant props
| Prop | Description |
|--------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| trim?: boolean | boolean — If true, the value is trimmed before validation (visual input stays as typed). |
| minLength?: number | number — Minimum allowed length (after optional trimming). |
| maxLength?: number | number — Maximum allowed length (after optional trimming). |
| joinControls?: boolean | boolean — If true and there are controls, the input + controls share one box (border/radius/focus). |
| extendBoxToControls?: boolean | boolean — When joinControls is true, controls are either visually “inside†the same box (true) or separate (false). |
| inputClassName?: string | string — Extra classes for the inner <input> element (not the wrapper). |
| prefix?: string | string — Fixed prefix rendered as part of the visible input string (e.g. ₦, ID: ). |
| suffix?: string | string — Fixed suffix rendered as part of the visible input string (e.g. %, kg). |
| stripPrefix?: boolean | boolean — If true (default), the prefix is stripped from the emitted model value before calling onValue internally. |
| stripSuffix?: boolean | boolean — If true (default), the suffix is stripped from the emitted model value before calling onValue internally. |
| mask?: string | string — Mask pattern (PrimeReact style), e.g. "99/99/9999", "(999) 999-9999". |
| maskDefinitions?: Record<string, RegExp> | Record — Per-symbol slot definitions (kept for future custom engine; unused by current implementation). |
| slotChar?: string | string — Placeholder slot character (default _). |
| autoClear?: boolean | boolean — If true, “empty†masked values emit "" instead of a fully-masked placeholder string. |
| unmask?: "raw" \| "masked" \| boolean | union — Controls whether the model value is raw vs masked. ("raw"/true ⇒ emit unmasked; "masked"/false/undefined ⇒ emit masked). |
| maskInsertMode?: "stream" \| "caret" | union — Reserved for future caret-mode logic (currently unused; kept for API compatibility). |
| ...inputProps | All other standard React.InputHTMLAttributes<HTMLInputElement> (except value, defaultValue, onChange, size) are forwarded. |
Sample usage (InputField)
import { InputField } from "@timeax/form-palette";
export function ExampleText() {
return (
<InputField
variant="text"
name="phone"
label="Phone number"
description="We’ll use this for account recovery."
// semantic validation flags (core layer)
trim
minLength={11}
maxLength={11}
// mask + UI props (preset layer)
prefix="+234 "
mask="999 999 9999"
unmask="raw"
autoClear
// regular input attributes
type="tel"
inputMode="tel"
placeholder="803 123 4567"
/>
);
}textarea
Variant props
| Prop | Description |
|--------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ...textareaProps | The textarea variant primarily forwards props from the underlying UI Textarea component (UiTextareaProps), excluding value, defaultValue, and onChange because the variant emits changes via the form runtime. |
Sample usage (InputField)
import { InputField } from "@timeax/form-palette";
export function ExampleTextarea() {
return (
<InputField
variant="textarea"
name="bio"
label="About you"
helpText="Keep it short and clear."
// typical textarea attributes (usually supported via UiTextareaProps)
rows={4}
placeholder="Tell us a little about yourself..."
/>
);
}toggle-group
Variant props
| Prop | Description |
|------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| options: (ToggleOption \| string \| number \| boolean)[] | Options for the toggle group. You can pass full option objects or primitive shorthand (primitives are normalized to { value: String(x), label: String(x) }). |
| multiple?: boolean | boolean — If true, enables multi-select (value becomes an array of strings internally). |
| variant?: "default" \| "outline" | union — Visual style passed to the underlying ToggleGroup. |
| layout?: "horizontal" \| "vertical" \| "grid" | union — Layout mode. |
| gridCols?: number | number — Column count when layout="grid" (defaults to 2 in the component). |
| fillWidth?: boolean | boolean — If true, makes the group/items stretch to fill available width (adds w-full and related item sizing). |
| optionValue?: string | string — When options are custom objects, the property name to read value from (fallback: obj.value). |
| optionLabel?: string | string — When options are custom objects, the property name to read label from (fallback: obj.label or String(value)). |
| optionIcon?: string | string — When options are custom objects, the property name to read icon from (fallback: obj.icon). |
| optionDisabled?: string | string — When options are custom objects, the property name to read disabled flag from (fallback: obj.disabled). |
| optionTooltip?: string | string — When options are custom objects, the property name to read tooltip content from (fallback: obj.tooltip). |
| optionMeta?: string | string — When options are custom objects, the property name to read meta from (fallback: obj.meta). |
| renderOption?: (option, isSelected) => React.ReactNode | Custom renderer per option (receives normalized option + selected state). |
| className?: string | Class for the toggle group container. |
| itemClassName?: string | Base class applied to all toggle items. |
| activeClassName?: string | Class applied only to selected items (merged with default active styles). |
| autoCap?: boolean | If true, capitalizes the first letter of string labels. |
| gap?: number | Gap between buttons in pixels (applies to flex + grid layouts). |
ToggleOption shape (when not using primitive shorthand):
label: React.ReactNodevalue: stringicon?: React.ReactNodedisabled?: booleantooltip?: React.ReactNodemeta?: any
Sample usage (InputField)
import { InputField } from "@timeax/form-palette";
export function ExampleToggleGroup() {
return (
<InputField
variant="toggle-group"
name="plan"
label="Choose a plan"
required
options={[
{ value: "basic", label: "Basic" },
{ value: "pro", label: "Pro" },
{ value: "team", label: "Team", disabled: true, tooltip: "Coming soon" },
]}
layout="horizontal"
variant="outline"
fillWidth
gap={8}
activeClassName="ring-1 ring-primary"
/>
);
}number
| Prop | Description |
|----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| showButtons | When true, renders built-in step controls (±) alongside the number input. |
| buttonLayout | Layout for the step controls when showButtons is enabled. Supported layouts: "stacked" (vertical on the right) and "inline" (- left, + right). |
| step | Step amount used by the built-in controls and stepping logic (forwarded to the underlying number input). |
| min | Minimum numeric value constraint (used by the stepping logic and forwarded to the underlying number input). |
| max | Maximum numeric value constraint (used by the stepping logic and forwarded to the underlying number input). |
Also accepts the rest of the underlying
InputNumberProps(they’re forwarded to the number input).
Sample
<InputField
variant="number"
name="quantity"
label="Quantity"
description="How many items?"
min={1}
max={99}
step={1}
showButtons
buttonLayout="inline"
/>password
| Prop | Description |
|-------------------------|-----------------------------------------------------------|
| autoComplete | Sets the input autoComplete hint for password managers. |
| minLength | Minimum allowed length (HTML constraint). |
| maxLength | Maximum allowed length (HTML constraint). |
| revealToggle | Show / hide the reveal toggle button. |
| defaultRevealed | Initial revealed state (defaults to hidden). |
| onRevealChange | Called when revealed state changes. |
| renderToggleIcon | Custom renderer for the toggle icon. |
| toggleAriaLabel | ARIA label for the toggle button. |
| toggleButtonClassName | ClassName hook for the toggle button. |
| strengthMeter | Enable the strength meter UI. |
| ruleDefinitions | Custom rule definitions used by the strength meter. |
| ruleUses | Which rules should be considered when computing strength. |
| meterStyle | Visual style of the strength meter. |
| renderMeter | Custom renderer for the full meter block. |
| meterWrapperClassName | ClassName hook for the meter wrapper. |
Password inherits the visual props from the
textvariant (it reuses the text UI), but controlstype, value wiring, and trailing controls internally.
Sample
<InputField
variant="password"
name="password"
label="Password"
required
minLength={8}
autoComplete="new-password"
revealToggle
strengthMeter
ruleUses={["minLen", "upper", "lower", "number", "symbol"]}
/>phone
| Prop | Description |
|------------------------|---------------------------------------------------------------------------------|
| countries | List of allowed countries (and their dial codes) shown in the country selector. |
| defaultCountryCode | The default selected country code (e.g. "NG"). |
| allowCountrySearch | Enable searching in the country list. |
| allowCountryClear | Allow clearing the selected country. |
| countryPlaceholder | Placeholder text for the country selector. |
| showFlag | Show the flag in the country selector. |
| showCountryName | Show the country name in the selector / list. |
| showDialCode | Show dial codes in the country list. |
| showSelectedDialCode | Show the selected dial code next to the input. |
| dialCodeDelimiter | Delimiter between dial code and the input number (e.g. " ", "-"). |
| valueMode | Controls how the field value is emitted (e.g. E.164 vs local formats). |
| mask | Optional input mask (string or resolver function). |
| lazy | IMask “lazy†mode (placeholder chars hidden until typed). |
| keepCharPositions | IMask option to keep character positions stable. |
| unmask | How the underlying mask value is emitted (IMask option). |
Phone inherits the visual props from the
textvariant, but controls value parsing/formatting and the country selector internally.
Sample
<InputField
variant="phone"
name="phone"
label="Phone number"
defaultCountryCode="NG"
allowCountrySearch
showSelectedDialCode
dialCodeDelimiter=" "
valueMode="e164"
/>Slider (slider)
Value type: number | undefined
Props
| Prop | Description |
|----------------------------|--------------------------------------------------------|
| value | Current slider value (number). |
| onValue | Called when the value changes. |
| error | Validation/error message for the field. |
| disabled | Disables interaction. |
| readOnly | Prevents changes but still displays the value. |
| size | Sizing preset for the control. |
| density | Density preset for the control (spacing). |
| min | Minimum value (default 0). |
| max | Maximum value (default 100). |
| step | Step size (default 1). |
| showValue | Show the current numeric value next to the slider. |
| valuePlacement | Where to render the value when showValue is enabled. |
| formatValue | Format the displayed value. |
| className | Root wrapper className. |
| sliderClassName | Slider track/handle className. |
| valueClassName | Value label className. |
| leadingIcons | Icons rendered before the slider/value. |
| trailingIcons | Icons rendered after the slider/value. |
| icon | Single icon (shorthand). |
| iconGap | Gap between icon(s) and content. |
| leadingIconSpacing | Spacing between multiple leading icons. |
| trailingIconSpacing | Spacing between multiple trailing icons. |
| leadingControl | Optional control element rendered before the slider. |
| trailingControl | Optional control element rendered after the slider. |
| leadingControlClassName | Wrapper className for the leading control. |
| trailingControlClassName | Wrapper className for the trailing control. |
| joinControls | Join controls visually to the slider box. |
| extendBoxToControls | Extend slider “box†background behind controls. |
| controlVariant | Variant for the +/- controls (if shown). |
| controlStep | Step used by +/- controls (falls back to step). |
| controlDecrementIcon | Custom icon node for decrement control. |
| controlIncrementIcon | Custom icon node for increment control. |
Example
<InputField
name="rating"
label="Rating"
variant="slider"
min={0}
max={100}
step={5}
showValue
valuePlacement="right"
formatValue={(v) => `${v}%`}
controlVariant="ghost"
controlStep={5}
/>Toggle (toggle)
Value type: boolean | undefined
Props
| Prop | Description |
|------------------------|--------------------------------------------|
| value | Current toggle value (boolean). |
| onValue | Called when the value changes. |
| error | Validation/error message for the field. |
| size | Visual size of the switch. |
| density | Spacing density for the wrapper. |
| onText | Text shown when the value is true. |
| offText | Text shown when the value is false. |
| label | Optional label rendered beside the switch. |
| containerClassName | Wrapper className. |
| switchRootClassName | ClassName for the Switch root element. |
| switchThumbClassName | ClassName for the Switch thumb. |
Example
<InputField
name="enabled"
label="Enabled"
variant="toggle"
onText="On"
offText="Off"
density="sm"
/>TreeSelect (treeselect)
Value type: TreeKey | TreeKey[] | undefined (where TreeKey is string | number)
Base props
| Prop | Description |
|-------------------------|--------------------------------------------------------------------------------|
| value | Selected key(s). Single value is a key; multi is an array of keys. |
| onValue | Called when selection changes. |
| error | Validation/error message for the field. |
| disabled | Disables interaction. |
| readOnly | Prevents changes but still displays the selection. |
| size | Sizing preset for trigger/list rows. |
| density | Density preset for trigger/list rows. |
| options | Tree of options to render. |
| multiple | Allow selecting multiple keys (returns TreeKey[]). |
| autoCap | (Option mapping helper) Auto-capitalize generated labels when mapping options. |
| optionLabel | (Option mapping helper) Label accessor (key name or function). |
| optionValue | (Option mapping helper) Value accessor (key name or function). |
| optionDescription | (Option mapping helper) Description accessor. |
| optionDisabled | (Option mapping helper) Disabled accessor. |
| optionIcon | (Option mapping helper) Icon accessor. |
| optionKey | (Option mapping helper) Key accessor. |
| searchable | Enable search input in the dropdown. |
| searchPlaceholder | Placeholder text for the search input. |
| emptyLabel | Content shown when there are no options. |
| emptySearchText | Content shown when search returns no matches. |
| clearable | Show a clear/reset action. |
| placeholder | Text shown when nothing is selected. |
| className | Wrapper className for the whole field. |
| triggerClassName | ClassName for the trigger/button area. |
| contentClassName | ClassName for the dropdown content. |
| renderOption | Custom renderer for an option row. |
| renderValue | Custom renderer for the trigger's current value display. |
| expandAll | Expand all nodes by default. |
| defaultExpandedValues | Keys that should start expanded by default. |
| leafOnly | Restrict selection to leaf nodes only. |
Mode: default (mode omitted or "default")
| Prop | Description |
|----------------------------|-----------------------------------------------------------------|
| mode | Omit or set to 'default' to use the standard field trigger. |
| button | Optional custom trigger button renderer. |
| selectedBadge | Optional selected-count badge renderer. |
| icon | Single icon rendered near the trigger value. |
| iconGap | Gap between icon and content. |
| leadingIcons | One or more icons before the value. |
| trailingIcons | One or more icons after the value. |
| leadingControl | Custom control element before the trigger (e.g., clear button). |
| trailingControl | Custom control element after the trigger. |
| leadingControlClassName | ClassName for leading control wrapper. |
| trailingControlClassName | ClassName for trailing control wrapper. |
| joinControls | Visually join controls to the trigger box (shared border). |
| extendBoxToControls | Extend trigger background behind controls. |
| rootClassName | Wrapper className around controls + trigger. |
| triggerInnerClassName | ClassName for the trigger’s inner content. |
Mode: button (mode="button")
| Prop | Description |
|----------------------------|-----------------------------------------------------------------|
| mode | Set to 'button' to render a button-style trigger. |
| button | (mode='button') If provided, this is the trigger renderer. |
| selectedBadge | (mode='button') Selected-count badge renderer. |
| icon | Single icon rendered near the trigger value. |
| iconGap | Gap between icon and content. |
| leadingIcons | One or more icons before the value. |
| trailingIcons | One or more icons after the value. |
| leadingControl | Custom control element before the trigger (e.g., clear button). |
| trailingControl | Custom control element after the trigger. |
| leadingControlClassName | ClassName for leading control wrapper. |
| trailingControlClassName | ClassName for trailing control wrapper. |
| joinControls | Visually join controls to the trigger box (shared border). |
| extendBoxToControls | Extend trigger background behind controls. |
Example (default mode)
<InputField
name="category"
label="Category"
variant="treeselect"
options={[
{
key: "social",
label: "Social",
children: [
{ key: "twitter", label: "Twitter" },
{ key: "instagram", label: "Instagram" },
],
},
]}
searchable
placeholder="Pick one…"
/>Example (multiple + button mode)
<InputField
name="tags"
variant="treeselect"
mode="button"
multiple
options={[
{ key: 1, label: "Starter" },
{ key: 2, label: "Pro" },
{ key: 3, label: "Enterprise" },
]}
/>multi-select
Variant props
| Prop | Description |
|---------------------|---------------------------------------------------------------------------------------------------------------------------------|
| options | Options for the multi-select. Accepts primitives or objects. |
| autoCap | Capitalise the first letter of the label (when the resolved label is a string). |
| optionLabel | How to read the label from each option (string key or mapper function). If omitted: uses label, else String(value). |
| optionValue | How to read the value from each option (string key or mapper function). If omitted: primitives are used directly, else value. |
| optionDescription | How to read the description from each option (string key or mapper function). If omitted: uses description. |
| optionIcon | How to read the icon from each option (string key or mapper function). If omitted: uses icon. |
| optionDisabled | How to detect disabled options (string key or mapper function). If omitted: uses disabled. |
| optionKey | How to compute stable keys for items (string key or mapper function). If omitted: uses index. |
| searchable | Enable search field in the list. |
| searchPlaceholder | Placeholder for the search field. |
| emptySearchText | Text when there are no matches for the current search. |
| showSelectAll | Show a “Select all†row. |
| selectAllLabel | Label for the “Select all†row. |
| selectAllPosition | Where to render the “Select all†row. |
| clearable | Show a clear action when there is at least one selection. |
| placeholder | Placeholder when nothing is selected. |
| renderOption | Optional global renderer for an option row. (An option may also provide its own per-option render.) |
| renderCheckbox | Optional renderer for the checkbox element used by each option row. |
| renderValue | Custom renderer for the trigger summary (selected values). |
| maxListHeight | Max height for the list (px). |
| className | Wrapper class for the whole variant. |
| triggerClassName | Class for the trigger button. |
| contentClassName | Class for the popover content container. |
Options can be passed as:
- primitives:
['ng', 'gh', 'ke'] - objects:
[{ label, value, ...extra }]
Mode and trigger props
| Prop | Description |
|-------------------------------|------------------------------------------------------------------------------------------------------|
| mode | Choose trigger style: "default" (standard input-like trigger) or "button" (custom trigger node). |
| leadingIcons | Icons shown before the summary text inside the trigger (default mode). |
| trailingIcons | Icons shown after the summary / clear button inside the trigger. |
| icon | Single icon shorthand (falls into leadingIcons). |
| iconGap | Base gap (px) used between icon groups and text. |
| leadingIconSpacing | Override spacing (px) between leading icons and text. |
| trailingIconSpacing | Override spacing (px) between trailing icons and the right-side controls. |
| leadingControl | Custom node rendered on the far-left outside the trigger (e.g., a compact action button). |
| trailingControl | Custom node rendered on the far-right outside the trigger. |
| leadingControlClassName | ClassName for the leading control wrapper. |
| trailingControlClassName | ClassName for the trailing control wrapper. |
| joinControls | Visually joins leading/trailing controls with the trigger (no gaps). |
| extendBoxToControls | Extends the input box styling (border/background) around the joined controls. |
| button | Used when mode="button". If provided, this is the trigger. If not provided, children is used. |
| children | When mode="button" and button is not provided, children is used as the trigger content. |
| selectedBadge | Selected-count badge (mode="button" only). |
| selectedBadgeHiddenWhenZero | Hide the badge when selected count is 0 (mode="button"). |
| selectedBadgeClassName | ClassName for the selected-count badge. |
| selectedBadgePlacement | Where to place the badge relative to the trigger content (mode="button"). |
Sample usage
import { InputField } from "@timeax/form-palette"; // adjust import to your project
export function MultiSelectExample() {
return (
<InputField
variant="multi-select"
name="countries"
label="Countries"
description="Pick one or more countries."
options={[
{ label: "Nigeria", value: "ng" },
{ label: "Ghana", value: "gh" },
{ label: "Kenya", value: "ke" },
]}
searchable
searchPlaceholder="Search countries..."
showSelectAll
selectAllLabel="Select all"
clearable
placeholder="Select countries..."
/>
);
}radio
Variant props
| Prop | Description |
|------------------------|-----------------------------------------------------------------------------------------------------------------------|
| items | Alias of options (list of items to render). |
| options | Options to render. Supports RadioItem objects or custom items via mappers. |
| mappers | Mapping functions for TItem → value/label/description/disabled/key/render. Takes precedence over option* props. |
| optionValue | Shortcut mapping for value (used only if mappers is not provided). |
| optionLabel | Shortcut mapping for label (used only if mappers is not provided). |
| renderOption | Global option renderer (can be overridden per item via item.render). |
| layout | Layout mode: "stack" or "grid". |
| columns | Number of columns when layout="grid". |
| itemGapPx | Gap (px) between items. |
| size | Variant size override for the radio control. |
| density | Variant density override for spacing. |
| autoCap | Auto-capitalise labels when the resolved label is a string. |
| aria-label | ARIA label forwarded to the radio group wrapper. |
| aria-labelledby | ARIA aria-labelledby forwarded to the radio group wrapper. |
| aria-describedby | ARIA aria-describedby forwarded to the radio group wrapper. |
| groupClassName | ClassName for the group wrapper. |
| optionClassName | ClassName for each option container. |
| labelClassName | ClassName for the option label. |
| descriptionClassName | ClassName for the option description. |
| id | Optional id for the group wrapper. |
| name | HTML name attribute to group radio inputs. |
| className | Alias for groupClassName. |
Supported option shapes
RadioItem<TValue>:{ value, label, description?, disabled?, key?, render? }- Any
TItemshape, as long as you providemappers(oroptionLabel/optionValueshortcuts)
Sample usage
import { InputField } from "@timeax/form-palette"; // adjust import to your project
export function RadioExample() {
return (
<InputField
variant="radio"
name="plan"
label="Plan"
description="Choose a plan."
items={[
{ value: "free", label: "Free", description: "Basic features" },
{ value: "pro", label: "Pro", description: "Everything included" },
{ value: "team", label: "Team", description: "For small teams" },
]}
layout="grid"
columns={3}
autoCap
/>
);
}select
Variant props
| Prop | Description |
|----------------------------|---------------------------------------------------------------------------------------------------------------------------------|
| options | Options for the select. Accepts primitives or objects. |
| autoCap | Capitalise the first letter of the label (when the resolved label is a string). |
| optionLabel | How to read the label from each option (string key or mapper function). If omitted: uses label, else String(value). |
| optionValue | How to read the value from each option (string key or mapper function). If omitted: primitives are used directly, else value. |
| optionDescription | How to read the description from each option (string key or mapper function). If omitted: uses description. |
| optionIcon | How to read the icon from each option (string key or mapper function). If omitted: uses icon. |
| optionDisabled | How to detect disabled options (string key or mapper function). If omitted: uses disabled. |
| optionKey | How to compute stable keys for items (string key or mapper function). If omitted: uses index. |
| searchable | Enable search field in the list. |
| searchPlaceholder | Placeholder for the search field. |
| emptySearchText | Text shown when there are no matches for the current search. |
| clearable | Show a clear action (x) when a value is selected. |
| emptyLabel | Label to show when no value is selected (acts like “noneâ€). |
| placeholder | Placeholder when no value is selected (and emptyLabel not shown). |
| renderOption | Optional global renderer for a list option. (An option may also provide its own per-option render.) |
| renderValue | Custom renderer for the trigger display (selected option). |
| virtualScroll | Enable virtual scrolling for large option lists. |
| virtualScrollThreshold | Number of items after which virtual scroll is enabled (when virtualScroll=true). |
| virtualScrollPageSize | How many items to render per virtual page/chunk. |
| leadingControl | Custom node rendered on the far-left outside the trigger. |
| leadingControlClassName | ClassName for the leading control wrapper. |
| leadingIconSpacing | Override spacing (px) between leading icons and the selected value. |
| trailingIcons | Icons shown on the right side of the trigger. |
| trailingControl | Custom node rendered on the far-right outside the trigger. |
| trailingControlClassName | ClassName for the trailing control wrapper. |
| trailingIconSpacing | Override spacing (px) between selected value and trailing icons. |
| joinControls | Visually joins leading/trailing controls with the trigger (no gaps). |
| extendBoxToControls | Extends the input box styling (border/background) around the joined controls. |
| icon | Single icon shorthand (used in default mode). |
| iconGap | Base gap (px) used between icon and text. |
| className | Wrapper class for the whole variant. |
| triggerClassName | Class for the trigger button. |
| contentClassName | Class for the popover content container. |
| mode | Choose trigger style: "default" (normal select trigger) or "button" (custom trigger node). |
| leadingIcons | Icons shown before the selected value inside the trigger (default mode). |
| button | Used when mode="button". If provided, this is the trigger. If not provided, children is used. |
| children | When mode="button" and button is not provided, children is used as the trigger content. |
Options can be passed as:
- primitives:
['ng', 'gh', 'ke'] - objects:
[{ label, value, ...extra }]
Sample usage
import { InputField } from "@timeax/form-palette"; // adjust import to your project
export function SelectExample() {
return (
<InputField
variant="select"
name="country"
label="Country"
options={[
{ label: "Nigeria", value: "ng", description: "NG" },
{ label: "Ghana", value: "gh", description: "GH" },
{ label: "Kenya", value: "ke", description: "KE" },
]}
searchable
searchPlaceholder="Search..."
clearable
emptyLabel="No selection"
placeholder="Select a country..."
virtualScroll
virtualScrollThreshold={80}
virtualScrollPageSize={30}
/>
);
}checkbox
| Prop | Description | | |
|------------------------|------------------------------------------------------------------------------------------------------------------------------------|--------------------------------|------------------------|
| single | Render a single boolean checkbox instead of an option group. | | |
| singleLabel | Label text shown next to the checkbox in single mode. | | |
| singleDescription | Optional helper text shown under the single checkbox label. | | |
| options | Option list for group mode. Accepts primitives or objects (normalized to { value, label, description?, disabled?, key? }). | | |
| items | Alias for options (alternate naming). | | |
| mappers | Override normalization: { mapValue?, mapLabel?, mapDescription?, mapDisabled?, mapKey? }. | | |
| optionValue | Map item → option value (overrides mappers.mapValue). | | |
| optionLabel | Map item → option label (overrides mappers.mapLabel). | | |
| optionDescription | Map item → option description (overrides mappers.mapDescription). | | |
| optionDisabled | Map item → disabled boolean (overrides mappers.mapDisabled). | | |
| optionKey | Map item → stable React key (overrides mappers.mapKey). | | |
| renderOption | Custom option renderer (gets { item, index, state, effectiveTristate, disabled, size, density, checkboxId, click(), checkbox }). | | |
| tristate | Enable tri-state cycling for group options (none → true → false → none). | | |
| layout | Group layout: "list" or "grid". | | |
| columns | Grid columns when layout="grid" (default: 2). | | |
| itemGapPx | Gap between options in px (defaults vary by layout). | | |
| size | Checkbox size: "sm" | "md" | "lg"(default:"md"). |
| density | Spacing preset: "compact" | "normal"(default:"normal"). | |
| autoCap | Auto-capitalize option labels. | | |
| groupClassName | Class applied to the options wrapper. | | |
| className | Alias for groupClassName. | | |
| optionClassName | Class applied to each option container. | | |
| labelClassName | Class applied to label text (single + option labels). | | |
| optionLabelClassName | Extra class applied to each option label. | | |
| descriptionClassName | Extra class applied to option descriptions. | | |
| id | Wrapper id. | | |
| name | Base name used for hidden inputs in group mode. | | |
| aria-label | Accessibility label for the group wrapper. | | |
| aria-labelledby | Id of an element that labels the group wrapper. | | |
| aria-describedby | Id of an element that describes the group wrapper. | | |
Value shape notes
Single mode:
boolean | undefinedGroup mode:
CheckboxGroupEntry[] | undefined, where each entry is{ value, state }."none"is an internal state only (it never appears in the public value).
Sample usage
// single (boolean)
<InputField
name="agree_tos"
label="Terms"
variant="checkbox"
single
singleLabel="I agree to the Terms of Service"
/>
// group (with tri-state)
<InputField
name="notify_prefs"
label="Notify me"
variant="checkbox"
tristate
layout="grid"
columns={2}
options={[
{ label: "Email", value: "email", description: "Marketing + account alerts" },
{ label: "SMS", value: "sms" },
{ label: "Push", value: "push" },
]}
/>chips
| Prop | Description | |
|------------------------|--------------------------------------------------------------------------|-------------------------------|
| placeholder | Placeholde
