@pixpilot/formily-shadcn
v1.11.27
Published
Formily integration for shadcn/ui components
Downloads
2,938
Readme
@pixpilot/formily-shadcn
Formily integration for shadcn/ui components. Build powerful, schema-driven forms with shadcn/ui's beautiful components and Formily's reactive form management.
Features
- 🎨 Shadcn/ui Integration - Uses shadcn/ui components for consistent design
- 📝 JSON Schema Support - Define forms using JSON Schema
- ⚡ Reactive State Management - Built on @formily/reactive for optimal performance
- 🔄 Dynamic Forms - Support for dynamic arrays, conditional fields, and complex layouts
- 📐 Grid Layout - Built-in responsive grid layout with
FormGrid - ✅ Validation - Comprehensive validation with error display
- 🎯 Type Safe - Full TypeScript support
Installation
pnpm add @pixpilot/formily-shadcn @formily/core @formily/reactQuick Start
Basic Form
import { createForm, Form, SchemaField } from '@pixpilot/formily-shadcn';
const form = createForm();
const schema = {
type: 'object',
properties: {
username: {
type: 'string',
title: 'Username',
required: true,
'x-decorator': 'FormItem',
'x-component': 'Input',
'x-component-props': {
placeholder: 'Enter your username',
},
},
email: {
type: 'string',
title: 'Email',
required: true,
'x-decorator': 'FormItem',
'x-component': 'Input',
'x-component-props': {
type: 'email',
placeholder: 'Enter your email',
},
},
},
};
function MyForm() {
return (
<Form
form={form}
layout={{ density: 'comfortable' }}
onSubmit={(values) => console.log(values)}
>
<SchemaField schema={schema} />
<button type="submit">Submit</button>
</Form>
);
}Grid Layout
const schema = {
type: 'void',
'x-component': 'FormGrid',
properties: {
field1: {
type: 'string',
title: 'Field 1 (Span 2)',
'x-decorator': 'FormItem',
'x-decorator-props': { className: 'col-span-2' },
'x-component': 'Input',
},
field2: {
type: 'string',
title: 'Field 2',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
},
};Array Fields
import {
Field,
ArrayField as FormilyArrayField,
FormItem,
Input,
} from '@pixpilot/formily-shadcn';
<FormilyArrayField name="contacts">
{(field) => (
<div>
{field.value?.map((_, index) => (
// eslint-disable-next-line react/no-array-index-key
<div key={index}>
<Field
name={`contacts.${index}.name`}
title="Name"
decorator={[FormItem]}
component={[Input]}
/>
<button onClick={() => field.remove(index)}>Remove</button>
</div>
))}
<button onClick={() => field.push({})}>Add Contact</button>
</div>
)}
</FormilyArrayField>;Available Components
Form Components
Form- Main form wrapper with FormProviderFormItem- Field decorator with label, error messagesFormGrid- Responsive grid layout
Input Components
Input- Text inputTextarea- Multi-line text inputNumberInput- Number inputCheckbox- Checkbox inputRadio- Radio groupSelect- Select dropdown
Field Components
SchemaField- Renders forms from JSON Schema
Schema Properties
Common x-properties
x-component: Component to render (e.g., 'Input', 'Select')x-decorator: Wrapper component (typically 'FormItem')x-component-props: Props passed to the componentx-decorator-props: Props passed to the decorator
Documentation
Form Layout Options
Learn how to configure form layout and visual settings using the FormLayoutOptions interface:
- Density - Control spacing between form elements (compact, normal, comfortable, responsive)
- Description Placement - Configure where field descriptions appear (top, bottom, popover)
- Label Placement - Set label position relative to inputs (top, bottom, start, end)
- Custom Classes - Apply custom CSS classes to form elements
JSON Schema Form: Headless vs Default Pattern
Learn about the difference between JsonSchemaFormRenderer (headless) and JsonSchemaForm (batteries-included) components:
JsonSchemaFormRenderer- Pure, headless component that requires you to provide all components explicitly. Ideal for custom component registries and bundle size optimization.JsonSchemaForm- Convenience wrapper that comes pre-loaded with all standard components (Slider, Combobox, TagsInput, etc.). Perfect for getting started quickly.
API Reference
createForm
Creates a form instance with reactive state management.
const form = createForm({
initialValues: {},
effects: () => {},
});Form Configuration
useFieldNameAsLabel
The useFieldNameAsLabel option controls whether field names are automatically converted to labels when no explicit label is provided.
Default Behavior:
JsonSchemaFormRenderer- SetsuseFieldNameAsLabel: trueby default. Field names are automatically capitalized and used as labels if notitleis provided in the schema.Formcomponent - Must be explicitly configured. Users need to setuseFieldNameAsLabel: truein theconfigprop to enable this behavior.
Example with JsonSchemaFormRenderer (enabled by default):
import { JsonSchemaFormRenderer } from '@pixpilot/formily-shadcn';
const schema = {
type: 'object',
properties: {
userName: {
type: 'string',
'x-decorator': 'FormItem',
'x-component': 'Input',
// No title provided - will use "User Name" as label
},
},
};
export function MyForm() {
return <JsonSchemaFormRenderer schema={schema} />;
}Example with Form component (requires explicit configuration):
import { createForm, Form, SchemaField } from '@pixpilot/formily-shadcn';
const form = createForm();
const schema = {
type: 'object',
properties: {
userName: {
type: 'string',
'x-decorator': 'FormItem',
'x-component': 'Input',
// No title provided - will use "User Name" as label only if config is set
},
},
};
export function MyForm() {
return (
<Form
form={form}
config={{
label: {
useFieldNameAsLabel: true, // Must be explicitly set
},
}}
>
<SchemaField schema={schema} />
</Form>
);
}The label resolution priority is:
- Explicit
labelprop (if provided and notfalse) - Schema
titlefield - Field
namecapitalized (only ifuseFieldNameAsLabel: true) - No label
