Advanced
API reference
Complete reference for all exports from @nestledjs/forms, @nestledjs/forms-native, and @nestledjs/forms-core.
Components
Form (web)
import { Form } from '@nestledjs/forms'
| Prop | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique form identifier |
fields | FormField[] | No | Declarative field definitions |
submit | (values: T) => void | Yes | Submit handler |
initialValues | Partial<T> | No | Pre-fill form values |
readOnly | boolean | No | Make all fields read-only |
theme | FormTheme | No | Custom theme object |
validateOnBlur | boolean | No | Validate on field blur |
validateOnChange | boolean | No | Validate on field change |
children | ReactNode | No | Submit buttons, imperative fields, etc. |
NativeForm (React Native)
import { NativeForm } from '@nestledjs/forms-native'
Same props as Form but rendered with React Native components.
RenderFormField
import { RenderFormField } from '@nestledjs/forms'
| Prop | Type | Required | Description |
|---|---|---|---|
field | FormField | Yes | Field definition from FormFieldClass |
ApolloSearchProvider
import { ApolloSearchProvider } from '@nestledjs/forms/apollo'
// or '@nestledjs/forms-native/apollo' / '@nestledjs/forms-core/apollo'
Enables searchSelectApollo and searchSelectMultiApollo fields. Place inside your existing <ApolloProvider>. Works with @apollo/client v3 and v4. The /apollo subpath is the only entry point that imports @apollo/client.
| Prop | Type | Required | Description |
|---|---|---|---|
children | ReactNode | Yes | Your app or form tree |
SearchQueryProvider
import { SearchQueryProvider } from '@nestledjs/forms-core'
Backs Apollo search select fields with a custom data layer (urql, TanStack Query, fetch) instead of Apollo Client.
| Prop | Type | Required | Description |
|---|---|---|---|
useSearchQuery | UseSearchQuery | Yes | Hook that executes the field's document |
children | ReactNode | Yes | Your app or form tree |
PhoneField
import { PhoneField } from '@nestledjs/forms/phone'
Direct import of the phone field component. It lives on its own subpath (no longer exported from @nestledjs/forms) to keep libphonenumber's ~150 KB metadata out of the main bundle; declarative usage via FormFieldClass.phone() lazy-loads it automatically.
FormFieldClass factory methods
import { FormFieldClass } from '@nestledjs/forms'
All methods follow the signature: FormFieldClass.method(key: string, options?: Options)
Text input fields
| Method | Description |
|---|---|
FormFieldClass.text(key, options?) | Single-line text input |
FormFieldClass.textArea(key, options?) | Multi-line text input |
FormFieldClass.email(key, options?) | Email input with validation |
FormFieldClass.password(key, options?) | Masked password input |
FormFieldClass.url(key, options?) | URL input with validation |
FormFieldClass.phone(key, options?) | Phone number with country code |
Numeric fields
| Method | Description |
|---|---|
FormFieldClass.number(key, options?) | Numeric input with min/max/step |
FormFieldClass.currency(key, options?) | Currency input with formatting |
Selection fields
| Method | Description |
|---|---|
FormFieldClass.select(key, options?) | Single-select dropdown |
FormFieldClass.multiSelect(key, options?) | Multi-select dropdown |
FormFieldClass.enumSelect(key, options?) | Select from TypeScript enum |
FormFieldClass.radio(key, options?) | Radio button group |
FormFieldClass.checkboxGroup(key, options?) | Checkbox group |
Search select fields
| Method | Description |
|---|---|
FormFieldClass.searchSelect(key, options?) | Searchable single-select |
FormFieldClass.searchSelectApollo(key, options?) | Apollo GraphQL single-select |
FormFieldClass.searchSelectMulti(key, options?) | Searchable multi-select |
FormFieldClass.searchSelectMultiApollo(key, options?) | Apollo GraphQL multi-select |
Boolean fields
| Method | Description |
|---|---|
FormFieldClass.checkbox(key, options?) | Standard checkbox |
FormFieldClass.switch(key, options?) | Toggle switch |
FormFieldClass.customCheckbox(key, options?) | Custom-styled checkbox |
Date & time fields
| Method | Description |
|---|---|
FormFieldClass.datePicker(key, options?) | Date picker |
FormFieldClass.dateTimePicker(key, options?) | Date and time picker |
FormFieldClass.timePicker(key, options?) | Time picker |
Utility fields
| Method | Description |
|---|---|
FormFieldClass.markdownEditor(key, options?) | Rich text markdown editor |
FormFieldClass.content(key, options?) | Display-only content |
FormFieldClass.custom(key, options?) | Custom component field |
FormFieldClass.button(key, options?) | Action button |
Shared field options
All field types accept these options:
interface BaseFieldOptions {
// Display
label?: string
placeholder?: string
helpText?: string
hidden?: boolean
// State
required?: boolean
disabled?: boolean
readOnly?: boolean
readOnlyStyle?: 'value' | 'disabled'
defaultValue?: any
// Conditional logic
showWhen?: (formValues: Record<string, any>) => boolean
requiredWhen?: (formValues: Record<string, any>) => boolean
disabledWhen?: (formValues: Record<string, any>) => boolean
validateWhen?: (formValues: Record<string, any>) => boolean
// Validation
validate?: (value: any) => true | string | Promise<true | string>
schema?: ZodTypeAny
validateWithForm?: (
value: any,
formValues: Record<string, any>,
) => true | string
validationDependencies?: string[]
validationGroup?: string
errorMessages?: { required?: string; [key: string]: string | undefined }
// Layout
wrapperClassName?: string
layout?: 'horizontal' | 'vertical'
customWrapper?: (children: React.ReactNode) => React.ReactElement
// Transform
submitTransform?: (value: any) => unknown
}
Hooks
useFormContext
import { useFormContext } from '@nestledjs/forms'
const {
formValues, // Record<string, any> — current form values
errors, // Record<string, string> — validation errors
isSubmitting, // boolean — whether form is submitting
setValue, // (key: string, value: any) => void
setError, // (key: string, error: string) => void
reset, // () => void — reset to initial values
validateGroup, // (group: string) => Promise<boolean>
} = useFormContext()
useFormValue
Reactively read a single field's value from any component inside <Form>.
import { useFormValue } from '@nestledjs/forms'
function Mirror() {
const answer = useFormValue<string>('answer')
return <p>You picked: {answer}</p>
}
Don't use form.watch() to read during render
form.watch(name) compiles, returns the right value on first render, and then silently never updates — no error, no warning, no type error. It re-renders only the component that owns useForm(), which is <Form> itself; <Form> passes children straight through, so React reuses that element reference and skips reconciling the subtree. Use useFormValue instead. The callback form, form.watch(cb), is fine.
useFormValues
The whole-form counterpart. Re-renders on any change, so prefer useFormValue when you only need one field.
import { useFormValues } from '@nestledjs/forms'
const values = useFormValues()
useWatch
react-hook-form's primitive, re-exported so you subscribe through the same instance <Form> uses. react-hook-form is a peer dependency — under pnpm's isolated node_modules an app that doesn't depend on it directly cannot resolve it, and adding it risks a second copy with a mismatched version.
import { useWatch, useFormContext } from '@nestledjs/forms'
const form = useFormContext()
const answer = useWatch({ control: form.control, name: 'answer' })
useFormConfig
import { useFormConfig } from '@nestledjs/forms'
const {
readOnly, // boolean
validateOnBlur, // boolean
validateOnChange, // boolean
} = useFormConfig()
useFormTheme
import { useFormTheme } from '@nestledjs/forms'
const theme = useFormTheme()
// theme.input, theme.label, theme.error, etc.
useNativeFormSubmit
import { useNativeFormSubmit } from '@nestledjs/forms-native'
const submitForm = useNativeFormSubmit()
// (() => Promise<void>) | null — null outside a NativeForm
<Pressable onPress={() => submitForm?.()} />
Returns NativeForm's submit trigger for custom submit buttons: runs validation, applies each field's submitTransform, then calls the form's submit prop.
useApolloSearchQuery
import { useApolloSearchQuery } from '@nestledjs/forms/apollo'
The Apollo implementation of UseSearchQuery used by ApolloSearchProvider. Useful as a reference when writing a custom adapter.
Theme utilities
tailwindTheme
import { tailwindTheme } from '@nestledjs/forms'
The default Tailwind CSS theme. Applied automatically unless you provide a custom theme.
createCustomTheme
import { createCustomTheme } from '@nestledjs/forms'
const theme = createCustomTheme({
input: 'custom-input-classes',
label: 'custom-label-classes',
})
// Merges with tailwindTheme — only override what you need
createFinalTheme
import { createFinalTheme } from '@nestledjs/forms'
const theme = createFinalTheme(baseTheme, overrides)
// Merges overrides into baseTheme at runtime
themeReference
import { themeReference } from '@nestledjs/forms'
// Object listing all theme property names and descriptions
generateThemeTemplate
import { generateThemeTemplate } from '@nestledjs/forms'
// Returns a theme object with all properties set to empty strings
Types
FormField
import type { FormField } from '@nestledjs/forms'
// Union type of all possible field definitions
FormFieldType
import { FormFieldType } from '@nestledjs/forms'
// Enum of all field type identifiers
FormTheme
import type { FormTheme } from '@nestledjs/forms'
// Interface for the complete theme object
FormProps
import type { FormProps } from '@nestledjs/forms'
// Props interface for the Form component
UseSearchQuery
import type { UseSearchQuery } from '@nestledjs/forms-core'
type UseSearchQuery = <TData = any>(
document: DocumentNode | TypedDocumentNode<TData>,
options?: { variables?: Record<string, unknown> },
) => {
data: TData | undefined
loading: boolean
refetch: (variables?: Record<string, unknown>) => Promise<{ data?: TData }>
}
The hook contract for custom search query adapters passed to SearchQueryProvider. The returned data must be referentially stable between renders unless the result changed.
Validation utilities
import {
createFieldValidation, // Create a validation function for a field
createFormResolver, // Create a form-level resolver
validateGroup, // Validate a specific validation group
} from '@nestledjs/forms'
Submit transform utilities
import {
singleSelectSubmitTransform, // Option object → ID string
multiSelectSubmitTransform, // Option objects → ID string array
resolveSubmitTransform, // Field's explicit transform, or its per-type default
} from '@nestledjs/forms-core'
Applied automatically at submit time for searchSelectApollo, searchSelectMultiApollo, multiSelect, and searchSelectMulti fields. An explicit submitTransform on the field always wins. Still re-exported from their previous locations.
Currency utilities
import {
currencies, // Array of all supported currency configurations
formatCurrency, // Format a number as currency string
getCurrencySymbol, // Get the symbol for a currency code
} from '@nestledjs/forms'
Date/time utilities
import {
formatDate, // Format a date value
formatDateTime, // Format a datetime value
formatTime, // Format a time value
} from '@nestledjs/forms'
Timezone-safe helpers for converting between Date objects and local date strings (used internally by the date pickers to avoid cross-timezone date corruption):
import {
parseLocalDate, // 'YYYY-MM-DD' string → Date in local time
formatLocalDate, // Date → 'YYYY-MM-DD' string in local time
parseLocalDateTime, // 'YYYY-MM-DDTHH:mm' string → Date in local time
formatLocalDateTime, // Date → 'YYYY-MM-DDTHH:mm' string in local time
} from '@nestledjs/forms-core'