Advanced Topics
Advanced Topics
Section titled “Advanced Topics”This chapter bundles together power-user techniques for building sophisticated, production-ready forms with @enlolab/forms. We cover dynamic field behaviour, conditional step navigation, theming with Tailwind, and internationalisation (i18n).
Prerequisite – You should be comfortable with the basics: configuration, steps, validation and submission.
1. Dynamic field behaviour
Section titled “1. Dynamic field behaviour”@enlolab/forms allows hidden, disabled, and readOnly props to be functions that receive the full form values object. This enables runtime logic without extra wiring.
1.1 Show / hide fields
Section titled “1.1 Show / hide fields”fields: { wantsNewsletter: { type: "checkbox", label: "Subscribe to newsletter", schema: z.boolean() }, emailFrequency: { type: "select", label: "Frequency", options: [ { label: "Daily", value: "daily" }, { label: "Weekly", value: "weekly" } ], hidden: (values) => !values.wantsNewsletter, schema: z.string().optional() }}1.2 Computed read-only fields
Section titled “1.2 Computed read-only fields”fields: { totalPrice: { type: "text", label: "Total (€)", readOnly: true, value: (values) => values.qty * values.unitPrice }}Internally FieldRenderer evaluates the function on every render via watch() from react-hook-form.
2. Conditional step navigation
Section titled “2. Conditional step navigation”Beyond per-field logic, you can route users through different steps with condition groups. Each StepCondition supports multiple conditions and combines them with AND / OR.
steps: { start: { id: "start", fields: ["age"], next: [ { conditions: [ { field: "age", operator: "lessThan", value: 18 } ], operator: "AND", target: "underage" } ], defaultNext: "adult" }, underage: {...}, adult: {...}}Evaluation happens inside evaluateStepCondition located in src/utils/stepUtils.ts.
3. Theming & design tokens
Section titled “3. Theming & design tokens”@enlolab/forms relies on Tailwind CSS and components built with Radix UI (similar to ShadCN UI patterns). You can therefore customise appearance via your Tailwind config.
- Override colours by extending the
theme.colorssection. - Inject design tokens (e.g. brand radius) using CSS variables and reference them in ShadCN components.
Example tailwind.config.js snippet:
module.exports = { theme: { extend: { colors: { primary: { DEFAULT: "#004aad", foreground: "#ffffff", }, }, borderRadius: { lg: "0.75rem", }, }, },};4. Internationalisation (i18n)
Section titled “4. Internationalisation (i18n)”While field labels are free strings (or HTML), some components have implicit locales:
- DateRenderers: uses locale
esby default viadate-fns. Passlocaleprop (roadmap) or wrap with your own renderer. - Validation messages: leverage Zod’s API to translate messages.
- Success / error messages: supply HTML with translated strings (e.g.,
successMessage: t('thanks')).
To fully localise a form, pair @enlolab/forms with a library like i18next or react-i18next and inject translations into field configs.
fields: { name: { label: t('name'), placeholder: t('name_placeholder'), schema: z.string().min(2, t('name_error')) }}5. Building custom fields
Section titled “5. Building custom fields”- Create a new React component (e.g.,
ColorPicker). - Add a case in
packages/enlolab-forms/src/factory/fieldRenderers.tsxmappingtype: 'color'to your component. - Extend TypeScript types in
packages/enlolab-forms/src/types/fields.ts. - Update the Fields Guide in the documentation.
The renderer receives disabled, readOnly and value/onChange props; integrate with them to maintain consistency.
6. Performance tips
Section titled “6. Performance tips”- Lazy load heavy inputs (e.g., map pickers) using React
lazy+Suspense. - Avoid large field arrays in a single step; split across steps for faster validation.
- Memoise icons or use Iconify string names instead of embedding SVG every render.
Related guides
Section titled “Related guides”- Steps Guide – Condition syntax reference.
- Layout Guide – Responsive grid configuration.
- Fields Guide – Complete field catalogue.