# Subcomponents Subcomponents are low-level primitives for building custom form fields and inputs with consistent Nebula styling. Section: components Docs: https://nebula.kaluza.com/components/subcomponents --- ## When to use - When building a custom form field that has no Nebula field equivalent - When you need direct access to an input element for integration with a third-party form library that requires a ref - When a higher-level Nebula field component (such as [TextField](/components/text-field) or [SelectField](/components/select-field)) does not support the specific layout or behaviour your context requires ## When not to use - **When a full field component exists** - if [TextField](/components/text-field), [SelectField](/components/select-field), [TextareaField](/components/textarea-field), [CheckboxField](/components/checkbox), [RadioField](/components/radio), [DateField](/components/date-field), [DatepickerField](/components/datepicker-field), [CurrencyField](/components/currency-field), or [ComboboxField](/components/combobox-field) fits your use case, use it. The field components handle label association, hint text, error text, required/optional marking, and aria attributes automatically. - **To assemble a field without using Field** - if you are composing an input with a label, use the `Field` wrapper rather than assembling label and error elements manually. Manual assembly is likely to miss aria associations. ## Anatomy 1. **Field wrapper** (handles label, optional/required marking, hint, error text, and aria attribute injection) 2. **Input** (the focusable form control rendered inside the field wrapper) ## Basic usage Use `Field` to wrap any `*Input` component. `Field` injects `id`, `name`, `aria-invalid`, `aria-required`, and `aria-describedby` onto its direct child automatically. ```tsx ``` ## Variants and features ### Field `Field` is a layout and accessibility wrapper for form inputs. It renders a `label`, optional hint text, and error text, and injects the appropriate aria attributes onto its child input. Props: - `label`: the visible label text (required) - `id`: used to associate the label with the input (required) - `hint`: descriptive text shown below the label - `error`: validation message shown below the input; overrides any error supplied by a parent `Form` - `optional`: when `true`, appends "(optional)" to the label (or suppresses the required asterisk, depending on theme configuration) - `fullWidth`: controls how the input width responds to the viewport: `'small'` (full width on small screens, character-width on larger), `'always'`, or `'never'` - `characters`: approximate visible character count used to calculate the input width on larger viewports (default: 25) ```tsx ``` ### TextInput A standard single-line text input. Accepts `iconLeft` and `iconRight` props to place icons inside the input. ```tsx ``` ### NumberInput A text input configured for numeric entry. Sets `inputMode="numeric"`, `pattern="[0-9]*"`, and disables autocapitalise, autocorrect, and spellcheck. Use for whole numbers. For decimal amounts, use [CurrencyInput](#currencyinput) or set `inputMode="decimal"` via props. ```tsx ``` ### TextareaInput A multi-line text input. Defaults to 3 rows with vertical resizing disabled. Pass `resizable` to allow the user to resize. ```tsx ``` ### SelectInput A styled native `