v5.0.0-alpha.7
Pre-releaseBreaking Changes
Replaced individual component props with a unified components prop
The 15 individual component props on SchemaForm (inputComponent, labelComponent, multilineComponent, selectComponent, checkboxComponent, radioComponent, checkboxWrapperComponent, radioWrapperComponent, radioGroupComponent, fieldErrorsComponent, fieldComponent, fieldsComponent, globalErrorsComponent, buttonComponent, and component) have been replaced by a single components prop that accepts a partial ComponentMap.
Before:
<SchemaForm
schema={schema}
component={StyledForm}
inputComponent={MyInput}
buttonComponent={MyButton}
labelComponent={MyLabel}
fieldsComponent={MyFieldsWrapper}
globalErrorsComponent={MyErrors}
/>After:
<SchemaForm
schema={schema}
components={{
form: StyledForm,
input: MyInput,
button: MyButton,
label: MyLabel,
fields: MyFieldsWrapper,
globalErrors: MyErrors,
}}
/>Every slot in ComponentMap is now constrained to a component that accepts the minimum props the library passes at runtime. Components with incompatible props fail at compile time instead of silently breaking at runtime.
The full set of slots is: form, field, label, input, multiline, select, checkbox, radio, checkboxWrapper, radioWrapper, radioGroup, fieldErrors, error, fields, globalErrors, button.
New makeSchemaForm factory
makeSchemaForm sets base components once for your entire app. The factory captures concrete types so that custom component props flow through to Field children with full type safety:
import { makeSchemaForm } from 'remix-forms'
const SchemaForm = makeSchemaForm({
form: StyledForm,
input: ChakraInput,
multiline: ChakraTextarea,
button: ChakraButton,
})The returned component still accepts a components prop for per-form overrides. Components resolve in a 3-level cascade: per-form override > base (from makeSchemaForm) > built-in defaults.
Type-safe SmartInput
SmartInput now automatically knows which component it will render — derived from three sources — and accepts only that component's props:
- Schema type —
boolean→ Checkbox, enum → Select - SchemaForm config —
multiline={['bio']},radio={['role']}(usesconsttype params for literal tuple inference) - Field-level props —
<Field multiline>,<Field radio>
<SchemaForm schema={schema} multiline={['bio']} radio={['role']}>
{({ Field }) => (
<>
{/* SmartInput infers Input slot → accepts ChakraInput's size/variant */}
<Field name="email">
{({ SmartInput }) => <SmartInput variant="filled" />}
</Field>
{/* 'bio' is in multiline config → SmartInput infers Multiline slot */}
<Field name="bio">
{({ SmartInput }) => <SmartInput resize="none" />}
</Field>
</>
)}
</SchemaForm>Bug fix
Fixed a pre-existing bug where the radio prop wasn't passed to Field via cloneElement when using custom children layouts, causing radio fields to never render as radio buttons in that scenario.
New Exports
makeSchemaForm— factory function for creating pre-configuredSchemaFormcomponentsComponentMap(type) — describes all 16 component slots available for customisationMergeComponents(type) — utility type for the 3-level component cascade
What's Changed
- BREAKING: Replace individual component props with generic components prop by @danielweinmann in #402
Full Changelog: v5.0.0-alpha.6...v5.0.0-alpha.7