Form Field API
Imports
Standalone imports
import { TngError, TngFormFieldComponent, TngFormFieldPrefix, TngFormFieldSuffix, TngHint, TngInputComponent, TngLabelComponent } from '@tailng-ui/components';
<tng-form-field>
labelPosition | 'outline' | 'above' | 'left' | Places the label on the top border, above the border, or left of the border. Defaults to above. |
size | 'sm' | 'md' | 'lg' | Label and message density. |
appearance | 'outlined' | 'plain' | 'none' | Visual chrome around the control. outlined paints the standard text-field border (default for inputs). plain strips the border / padding for controls that draw their own chrome (switch, slider, listbox, …). none strips the message container chrome as well. Auto-detected from the projected control; explicit value wins. |
controlType | 'auto' | 'text' | 'inline' | 'group' | 'composite' | Layout hint. inline puts the label to the right of the control on the same row — the default for switch/toggle/single-checkbox. auto derives the value from the projected control's tag. |
requiredMarker | boolean | Shows the marker when the control is required. |
hideHintWhenError | boolean | Hides hints when visible errors are present. |
inlineWidth | boolean | When true, the field uses intrinsic width instead of stretching to the container. Defaults to false (full width). |
disabled | boolean | null | Overrides derived disabled state. |
invalid | boolean | null | Overrides derived invalid state. |
slot | Partial<Record<TngFormFieldSlot, string>> | Micro styling classes for field slots. |
Messages
Use tngHint and tngError on projected message elements. Each message receives an id automatically unless one is provided.
Adornments
Use tngFormFieldPrefix and tngFormFieldSuffix for content that belongs to the whole field row. Use tngInputFieldPrefix and tngInputFieldSuffix inside <tng-input-field> when the adornment belongs inside the input shell.
tngFormFieldPrefix | Directive | Projects content before the control slot. |
tngFormFieldSuffix | Directive | Projects content after the control slot. |
Supported controls
The form-field projects any control via a default <ng-content> slot — you don't need to register a selector. Out of the box, the following TailNG controls register themselves through TNG_FORM_FIELD_CONTROL so the form-field can route label, aria-describedby, and state correctly:
tng-input/tng-textarea/tng-input-field/tng-select/tng-multiselect/tng-autocomplete/tng-multi-autocomplete/tng-datepicker— text-shaped, outlined frame.tng-switch/tng-toggle/tng-checkbox— inline-trailing label, plain frame.tng-radio/tng-slider/tng-toggle-group/tng-listbox/tng-input-otp/tng-month-daypicker/tng-yearpicker— plain frame, label above.
Anything else projected as a child works too: the form-field falls back to the default content slot and visual styling. Use appearance and controlType to pin the layout when auto-detection isn't what you want.
Custom Control Contract
Native input[tngInput], textarea[tngInput], and textarea[tngTextarea] work directly. Custom controls can provide TNG_FORM_FIELD_CONTROL. Add a static tngFormFieldControl marker attribute when the custom host is not one of the built-in projected control selectors.
Control provider
import { TNG_FORM_FIELD_CONTROL, type TngFormFieldControl } from '@tailng-ui/components';
providers: [{ provide: TNG_FORM_FIELD_CONTROL, useExisting: MyControl }]