UNPKG

@weareconceptstudio/cs-admin

Version:

A comprehensive React-based admin panel system with dynamic actions, form components, and design system

1,133 lines (966 loc) 34.8 kB
# Form Components Documentation This document provides comprehensive documentation for all form components available in CS Admin UI. ## Table of Contents - [FormContainer](#formcontainer) - [InputField](#inputfield) - [SelectField](#selectfield) - [Editor](#editor) - [MediaPicker](#mediapicker) - [DateTimePicker](#datetimepicker) - [ArrayField](#arrayfield) - [ColorField](#colorfield) - [ColorPicker](#colorpicker) - [SlugField](#slugfield) - [TreeSelectField](#treeselectfield) - [MetaInputs](#metainputs) --- ## FormContainer The main form wrapper component that provides layout, validation, and form management. ### Props | Prop | Type | Default | Description | | -------------------- | ---------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------ | | `className` | string | `''` | Additional CSS classes | | `layoutClassName` | string | `''` | Layout CSS classes | | `initialValues` | object | `{}` | Form initial values | | `onFinish` | function | `null` | Form submission handler | | `onChange` | function | `null` | Form values change handler | | `hasLayout` | boolean | `false` | Enable form layout with header and sidebar | | `title` | string | `''` | Form title | | `subtitle` | string/component | `null` | Form subtitle | | `trans` | boolean | `true` | Enable translation support | | `rightBar` | array | `[]` | Right sidebar components | | `preview` | component | `undefined` | Preview component | | `hasMeta` | boolean | `true` | Enable SEO meta fields | | `hasInformation` | object | `{createdAt: true, published: false, lastModified: true, orderDate: false, sendingDate: false}` | Information panel configuration | | `draftStatusKey` | string | `'status'` | Draft status field name | | `hasStatusSelection` | boolean | `false` | Enable status selection | | `statusSelection` | array/object | `null` | Status selection options | | `buttons` | object | `{save: true, draft: false, cancel: false, delete: false}` | Button configuration | | `additionalButtons` | component | `false` | Additional custom buttons | | `tabs` | component | `null` | Tab navigation component | | `hasBackButton` | boolean | `true` | Show back button | ### Usage ```jsx import { FormContainer, InputField } from '@weareconceptstudio/cs-admin'; const MyForm = ({ action, current, onFinish }) => { return ( <FormContainer title='Create Post' subtitle='Fill in the details below' hasLayout={true} onFinish={onFinish} initialValues={current} buttons={{ save: true, draft: true, cancel: true, delete: false, }} hasInformation={{ createdAt: true, lastModified: true, published: true, orderDate: false, sendingDate: false, }} hasBackButton={true} hasStatusSelection={true} statusSelection={[ { value: 'draft', label: 'Draft' }, { value: 'published', label: 'Published' }, { value: 'archived', label: 'Archived' }, ]}> <InputField name='title' label='Title' required={true} /> </FormContainer> ); }; ``` ### Advanced Configuration ```jsx const AdvancedForm = ({ action, current, onFinish }) => { return ( <FormContainer title='Advanced Post Editor' subtitle={ <div> <p>Create and manage your content</p> <Badge status='processing' text='Auto-save enabled' /> </div> } hasLayout={true} layoutClassName='full-width' onFinish={onFinish} onChange={(changedValues, allValues, form) => { // Handle form changes console.log('Form changed:', changedValues); }} initialValues={current} trans={true} hasBackButton={true} buttons={{ save: { title: 'Save Changes' }, draft: true, cancel: true, delete: action === 'edit', }} additionalButtons={ <Button type='mini' iconName='preview'> Preview </Button> } hasInformation={{ createdAt: true, published: true, lastModified: true, orderDate: false, sendingDate: true, }} hasStatusSelection={true} statusSelection={[ { value: 'draft', label: 'Draft' }, { value: 'review', label: 'Under Review' }, { value: 'published', label: 'Published' }, { value: 'archived', label: 'Archived' }, ]} draftStatusKey='status' hasMeta={true} rightBar={[<CustomSidebarComponent key='custom' />]} tabs={ <Tabs defaultActiveKey='content' items={[ { key: 'content', label: 'Content', children: <ContentTab /> }, { key: 'settings', label: 'Settings', children: <SettingsTab /> }, { key: 'seo', label: 'SEO', children: <SEOTab /> }, ]} /> }> {/* Form content */} </FormContainer> ); }; ``` ### Props Details #### Layout Props - **`hasLayout`**: Enables the full form layout with header, sidebar, and structured content area - **`layoutClassName`**: Additional CSS classes for the layout container - **`hasBackButton`**: Shows a back button in the layout header (uses context navigation) #### Form Behavior Props - **`onChange`**: Callback function triggered when form values change ```jsx onChange={(changedValues, allValues, form) => { // Handle form changes console.log('Changed:', changedValues); console.log('All values:', allValues); }} ``` #### Information Panel Props - **`hasInformation`**: Object controlling which information fields to show ```jsx hasInformation={{ createdAt: true, // Show creation date published: true, // Show published date with edit capability lastModified: true, // Show last modified date orderDate: false, // Show order date sendingDate: false, // Show sending date }} ``` #### Status Management Props - **`hasStatusSelection`**: Enable status selection in the information panel - **`statusSelection`**: Array or object defining status options ```jsx // Array format statusSelection={[ { value: 'draft', label: 'Draft' }, { value: 'published', label: 'Published' }, ]} // Object format statusSelection={{ draft: 'Draft', published: 'Published', archived: 'Archived' }} ``` - **`draftStatusKey`**: Field name for draft status (default: 'status') #### Button Configuration - **`buttons`**: Object controlling form buttons ```jsx buttons={{ save: true, // Show save button save: { title: 'Custom Save' }, // Custom save button text draft: true, // Show draft/publish buttons cancel: true, // Show cancel button delete: true, // Show delete button (edit mode) }} ``` #### Additional UI Props - **`additionalButtons`**: Custom buttons to add to the button area - **`tabs`**: Tab navigation component for organizing form content - **`rightBar`**: Array of components to display in the right sidebar - **`trans`**: Enable translation support and language switcher --- ## InputField A versatile input component that supports multiple input types. ### Props | Prop | Type | Default | Description | | -------------- | ---------------- | --------- | ------------------------------------------------------------------------- | | `type` | string | `'input'` | Input type: 'input', 'textarea', 'number', 'search', 'checkbox', 'switch' | | `label` | string | `''` | Field label | | `name` | string | `''` | Field name | | `className` | string | `''` | Additional CSS classes | | `required` | boolean | `true` | Whether field is required | | `rules` | array | `[]` | Validation rules | | `labelOptions` | object | `{}` | Ant Design Form.Item label props | | `inputOptions` | object | `{}` | Input component props | | `maxLength` | string/number | `null` | Maximum character length | | `allowClear` | boolean | `false` | Show clear button | | `errorKey` | string | - | Custom error message key | | `placeholder` | string | - | Input placeholder | | `addonBefore` | string/component | - | Input prefix | | `extra` | string/component | - | Extra information below field | | `tooltip` | string/component | - | Tooltip content | | `checkboxText` | string | - | Checkbox label text | | `inputConfig` | object | - | Input configuration (from context) | ### Usage ```jsx // Basic text input <InputField name="title" label="Title" placeholder="Enter title" required={true} maxLength={100} /> // Textarea <InputField type="textarea" name="description" label="Description" maxLength="p1" // Uses config character count autoSize={{ minRows: 4, maxRows: 10 }} /> // Number input <InputField type="number" name="price" label="Price" addonBefore="$" inputOptions={{ min: 0, step: 0.01 }} /> // Search input <InputField type="search" name="search" label="Search" onSearch={(value) => console.log(value)} /> // Checkbox <InputField type="checkbox" name="published" checkboxText="Published" required={false} /> // Switch <InputField type="switch" name="active" label="Active" required={false} /> ``` --- ## SelectField A dropdown selection component with support for single and multiple selection. ### Props | Prop | Type | Default | Description | | --------------- | --------- | ------- | ----------------------------------------- | | `label` | string | `''` | Field label | | `name` | string | `''` | Field name | | `mode` | string | `null` | Selection mode: 'multiple', 'tags' | | `labelOptions` | object | `{}` | Ant Design Form.Item label props | | `inputOptions` | object | `{}` | Select component props | | `optGroup` | boolean | `false` | Enable option grouping | | `optionKey` | string | `null` | Key for option label (defaults to 'name') | | `optionValue` | string | `null` | Key for option value (defaults to 'id') | | `list` | array | `[]` | Options array | | `required` | boolean | `true` | Whether field is required | | `rules` | array | `[]` | Validation rules | | `placeholder` | string | `''` | Placeholder text | | `suffixIcon` | component | - | Custom suffix icon | | `hasBorder` | boolean | `false` | Show border | | `className` | string | `''` | Additional CSS classes | | `showSearch` | boolean | `false` | Enable search functionality | | `onSelect` | function | - | Selection handler | | `errorKey` | string | - | Custom error message key | | `dropdownAlign` | object | - | Dropdown alignment | ### Usage ```jsx // Basic select <SelectField name="category" label="Category" list={categories} placeholder="Select category" required={true} /> // Multiple selection <SelectField name="tags" label="Tags" mode="multiple" list={tags} placeholder="Select tags" showSearch={true} /> // With custom option keys <SelectField name="status" label="Status" list={statuses} optionKey="label" optionValue="value" required={true} /> // With option groups <SelectField name="location" label="Location" optGroup={true} list={{ "North America": [ { id: 1, name: "United States" }, { id: 2, name: "Canada" } ], "Europe": [ { id: 3, name: "United Kingdom" }, { id: 4, name: "Germany" } ] }} /> ``` --- ## Editor A rich text editor component based on CKEditor 5. ### Props | Prop | Type | Default | Description | | ---------------- | ------- | ------- | -------------------------------- | | `label` | string | `''` | Field label | | `name` | string | `''` | Field name | | `required` | boolean | `true` | Whether field is required | | `rules` | array | `[]` | Validation rules | | `labelOptions` | object | `{}` | Ant Design Form.Item label props | | `toolbar` | array | `null` | Custom toolbar configuration | | `dynamic` | boolean | `false` | Enable dynamic naming | | `dynamicName` | string | `''` | Dynamic field name | | `errorKey` | string | - | Custom error message key | | `hasImageUpload` | boolean | `false` | Enable image upload | ### Usage ```jsx // Basic editor <Editor name="content" label="Content" required={true} /> // With custom toolbar <Editor name="description" label="Description" toolbar={[ 'heading', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote' ]} /> // With image upload <Editor name="article" label="Article" hasImageUpload={true} toolbar={[ 'heading', 'bold', 'italic', 'link', 'uploadImage', 'insertTable' ]} /> ``` --- ## MediaPicker A file upload and media selection component. ### Props | Prop | Type | Default | Description | | ---------------- | ------- | ----------------- | ----------------------------------------------------- | | `label` | string | `''` | Field label | | `name` | string | `''` | Field name | | `rules` | array | `[]` | Validation rules | | `required` | boolean | `true` | Whether field is required | | `acceptTypes` | array | `defaultAllTypes` | Accepted file types | | `multiple` | boolean | `false` | Allow multiple file selection | | `labelOptions` | object | `{}` | Ant Design Form.Item label props | | `dynamic` | boolean | `false` | Enable dynamic naming | | `dynamicName` | string | `''` | Dynamic field name | | `errorKey` | string | - | Custom error message key | | `allowDimension` | object | - | Required dimensions `{width: number, height: number}` | ### Usage ```jsx // Single image upload <MediaPicker name="featured_image" label="Featured Image" acceptTypes={['image/*']} required={true} /> // Multiple files <MediaPicker name="gallery" label="Gallery" acceptTypes={['image/*', 'video/*']} multiple={true} required={false} /> // With dimension requirements <MediaPicker name="banner" label="Banner Image" acceptTypes={['image/*']} allowDimension={{ width: 1200, height: 630 }} required={true} /> // Document upload <MediaPicker name="document" label="Document" acceptTypes={['application/pdf', 'application/msword']} required={true} /> ``` --- ## DateTimePicker A date and time selection component with multiple picker types. ### Props | Prop | Type | Default | Description | | --------------- | --------- | --------------- | ------------------------------------------------------- | | `label` | string | `''` | Field label | | `name` | string | `''` | Field name | | `labelOptions` | object | `{}` | Ant Design Form.Item label props | | `inputOptions` | object | `{}` | Picker component props | | `required` | boolean | `true` | Whether field is required | | `rules` | array | `[]` | Validation rules | | `type` | string | `'date'` | Picker type: 'date', 'time', 'date-range', 'time-range' | | `format` | string | `'DD/MM/YYYY'` | Display format | | `outputFormat` | string | `''` | Output format (uses format if empty) | | `className` | string | `'date-picker'` | Additional CSS classes | | `suffixIcon` | component | `null` | Custom suffix icon | | `multiple` | boolean | `false` | Allow multiple date selection | | `errorKey` | string | - | Custom error message key | | `inputReadOnly` | boolean | `false` | Make input read-only | ### Usage ```jsx // Date picker <DateTimePicker name="publish_date" label="Publish Date" type="date" format="DD/MM/YYYY" required={true} /> // Time picker <DateTimePicker name="event_time" label="Event Time" type="time" format="HH:mm" required={true} /> // Date range picker <DateTimePicker name="date_range" label="Date Range" type="date-range" format="DD/MM/YYYY" required={true} /> // Time range picker <DateTimePicker name="time_range" label="Time Range" type="time-range" format="HH:mm" required={true} /> // With custom format <DateTimePicker name="created_at" label="Created At" type="date" format="YYYY-MM-DD" outputFormat="YYYY-MM-DD HH:mm:ss" required={true} /> ``` --- ## ArrayField A dynamic array field component for managing lists of data. ### Props | Prop | Type | Default | Description | | ------------- | -------- | -------- | ---------------------------------- | | `fullPrefix` | array | - | Full field path prefix | | `prefix` | string | - | Field prefix | | `isRequired` | boolean | `true` | Whether field is required | | `renderItem` | function | - | Function to render each array item | | `btnText` | string | `'item'` | Add button text | | `btnProps` | object | `{}` | Add button props | | `hideButton` | boolean | `false` | Hide add button | | `addOptions` | object | `{}` | Default values for new items | | `draggable` | boolean | `false` | Enable drag-and-drop reordering | | `collapsable` | boolean | `true` | Enable collapsible items | | `max` | number | - | Maximum number of items | ### Usage ```jsx // Basic array field <ArrayField prefix="features" isRequired={true} btnText="Add Feature" renderItem={(field, index, remove) => ( <div key={field.key}> <InputField {...field} name={[field.name, 'title']} label="Feature Title" /> <InputField {...field} name={[field.name, 'description']} label="Description" type="textarea" /> <Button onClick={() => remove(field.name)}>Remove</Button> </div> )} /> // Draggable array field <ArrayField prefix="steps" draggable={true} btnText="Add Step" renderItem={(field, index, remove) => ( <div key={field.key}> <InputField {...field} name={[field.name, 'step']} label={`Step ${index + 1}`} /> </div> )} /> // With maximum items <ArrayField prefix="tags" max={5} btnText="Add Tag" renderItem={(field, index, remove) => ( <InputField {...field} name={[field.name, 'name']} label="Tag Name" /> )} /> ``` --- ## ColorField A color selection component with predefined color options. ### Props | Prop | Type | Default | Description | | -------------- | -------- | --------- | ---------------------------------- | | `label` | string | `''` | Field label | | `name` | string | `''` | Field name | | `mode` | string | `null` | Selection mode: 'multiple', 'tags' | | `required` | boolean | `true` | Whether field is required | | `rules` | array | `[]` | Validation rules | | `labelOptions` | object | `{}` | Ant Design Form.Item label props | | `inputOptions` | object | `{}` | Select component props | | `optionKey` | string | `'id'` | Key for option value | | `optionValue` | string | `'value'` | Key for color value | | `optionTitle` | string | `'name'` | Key for option label | | `list` | array | `[]` | Color options array | | `placeholder` | string | `''` | Placeholder text | | `errorKey` | string | - | Custom error message key | | `onSelect` | function | - | Selection handler | ### Usage ```jsx // Basic color field <ColorField name="primary_color" label="Primary Color" list={[ { id: 1, name: 'Red', value: '#ff0000' }, { id: 2, name: 'Blue', value: '#0000ff' }, { id: 3, name: 'Green', value: '#00ff00' } ]} required={true} /> // Multiple color selection <ColorField name="theme_colors" label="Theme Colors" mode="multiple" list={colorPalette} required={false} /> ``` --- ## ColorPicker A color picker component with visual color selection. ### Props | Prop | Type | Default | Description | | -------------- | ------- | ------- | -------------------------------- | | `label` | string | `''` | Field label | | `name` | string | `''` | Field name | | `rules` | array | `[]` | Validation rules | | `required` | boolean | `true` | Whether field is required | | `labelOptions` | object | `{}` | Ant Design Form.Item label props | | `dynamic` | boolean | `false` | Enable dynamic naming | | `dynamicName` | string | `''` | Dynamic field name | | `errorKey` | string | - | Custom error message key | ### Usage ```jsx // Basic color picker <ColorPicker name="background_color" label="Background Color" required={true} /> // Optional color picker <ColorPicker name="accent_color" label="Accent Color" required={false} /> ``` --- ## SlugField A slug generation field that automatically creates URL-friendly slugs from another field. ### Props | Prop | Type | Default | Description | | ----------------- | ------ | ------- | ---------------------------------------------------------- | | `listener` | string | - | **Required** - Field name to listen to for slug generation | | `table` | string | - | **Required** - Table name for slug validation | | `defaultLanguage` | string | - | Default language (from context) | | `languages` | array | - | Available languages (from context) | ### Usage ```jsx // Basic slug field <SlugField listener="title" table="posts" /> // With translation support <SlugField listener="title" table="articles" /> ``` --- ## TreeSelectField A hierarchical selection component for tree-structured data. ### Props | Prop | Type | Default | Description | | -------------- | ------- | ---------------------------------------------------- | -------------------------------- | | `label` | string | - | Field label | | `name` | string | - | Field name | | `labelOptions` | object | `{}` | Ant Design Form.Item label props | | `fieldNames` | object | `{label: 'name', value: 'id', children: 'children'}` | Field name mapping | | `list` | array | `[]` | Tree data array | | `inputOptions` | object | `{}` | TreeSelect component props | | `required` | boolean | `true` | Whether field is required | | `rules` | array | `[]` | Validation rules | ### Usage ```jsx // Basic tree select <TreeSelectField name="category" label="Category" list={categoryTree} required={true} /> // With custom field names <TreeSelectField name="department" label="Department" list={departmentTree} fieldNames={{ label: 'title', value: 'code', children: 'subdepartments' }} required={true} /> ``` --- ## MetaInputs A predefined component for SEO meta fields (title, description, image). ### Props This component has no props as it provides a standard set of SEO fields. ### Usage ```jsx // Basic meta inputs <MetaInputs /> // The component automatically provides: // - Meta Title (max 60 characters) // - Meta Description (max 160 characters) // - Meta Image (1200x630px recommended) ``` --- ## Form Validation All form components support Ant Design's validation system. Here are common validation patterns: ### Basic Validation ```jsx <InputField name='email' label='Email' rules={[ { required: true, message: 'Email is required' }, { type: 'email', message: 'Please enter a valid email' }, ]} /> ``` ### Custom Validation ```jsx <InputField name='password' label='Password' rules={[ { required: true, message: 'Password is required' }, { min: 8, message: 'Password must be at least 8 characters' }, { validator: (_, value) => { if (!/(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/.test(value)) { return Promise.reject(new Error('Password must contain uppercase, lowercase, and number')); } return Promise.resolve(); }, }, ]} /> ``` ### Conditional Validation ```jsx <InputField name='phone' label='Phone' rules={[ { validator: (_, value) => { if (form.getFieldValue('contact_method') === 'phone' && !value) { return Promise.reject(new Error('Phone is required when contact method is phone')); } return Promise.resolve(); }, }, ]} /> ``` --- ## Form Layout ### Basic Layout ```jsx <FormContainer title='Create Post' hasLayout={true} onFinish={handleSubmit}> <InputField name='title' label='Title' /> <Editor name='content' label='Content' /> <MediaPicker name='image' label='Featured Image' /> </FormContainer> ``` ### With Sidebar ```jsx <FormContainer title='Edit Post' hasLayout={true} rightBar={[<CustomComponent key='custom' />]} hasInformation={{ createdAt: true, lastModified: true, }}> {/* Form fields */} </FormContainer> ``` ### With Tabs ```jsx <FormContainer title='Product' hasLayout={true} tabs={ <Tabs items={[ { key: 'general', label: 'General', children: <GeneralTab /> }, { key: 'seo', label: 'SEO', children: <SEOTab /> }, ]} /> }> {/* Form content */} </FormContainer> ``` --- ## Best Practices 1. **Always provide meaningful labels** for accessibility 2. **Use appropriate validation rules** for data integrity 3. **Group related fields** using containers or collapsible sections 4. **Provide helpful placeholder text** for better UX 5. **Use required fields sparingly** - only mark truly essential fields 6. **Test form validation** with various input scenarios 7. **Consider mobile responsiveness** when designing forms 8. **Use consistent field naming** conventions 9. **Provide clear error messages** that help users fix issues 10. **Consider form performance** with large datasets --- ## Examples ### Complete Form Example ```jsx import { FormContainer, InputField, SelectField, Editor, MediaPicker, DateTimePicker, ArrayField, ColorPicker, MetaInputs, } from '@weareconceptstudio/cs-admin'; const PostForm = ({ action, current, onFinish }) => { return ( <FormContainer title={action === 'create' ? 'Create Post' : 'Edit Post'} hasLayout={true} onFinish={onFinish} initialValues={current} buttons={{ save: true, draft: true, cancel: true, }} hasInformation={{ createdAt: true, lastModified: true, }}> {/* Basic Information */} <InputField name='title' label='Title' placeholder='Enter post title' required={true} maxLength={100} /> <InputField type='textarea' name='excerpt' label='Excerpt' maxLength='p1' placeholder='Brief description of the post' /> <Editor name='content' label='Content' hasImageUpload={true} required={true} /> {/* Media */} <MediaPicker name='featured_image' label='Featured Image' acceptTypes={['image/*']} allowDimension={{ width: 1200, height: 630 }} required={true} /> <MediaPicker name='gallery' label='Gallery' acceptTypes={['image/*']} multiple={true} required={false} /> {/* Categorization */} <SelectField name='category' label='Category' list={categories} placeholder='Select category' required={true} /> <SelectField name='tags' label='Tags' mode='multiple' list={tags} placeholder='Select tags' showSearch={true} /> {/* Publishing */} <DateTimePicker name='publish_date' label='Publish Date' type='date' format='DD/MM/YYYY' required={true} /> <InputField type='switch' name='featured' label='Featured Post' required={false} /> {/* Custom Fields */} <ArrayField prefix='custom_fields' btnText='Add Custom Field' renderItem={(field, index, remove) => ( <div key={field.key} style={{ display: 'flex', gap: '10px', marginBottom: '10px' }}> <InputField {...field} name={[field.name, 'key']} label='Field Key' placeholder='e.g., price' /> <InputField {...field} name={[field.name, 'value']} label='Field Value' placeholder='e.g., $29.99' /> <Button onClick={() => remove(field.name)}>Remove</Button> </div> )} /> {/* SEO */} <MetaInputs /> </FormContainer> ); }; ``` This documentation covers all the form components available in CS Admin UI. Each component is designed to be flexible and integrate seamlessly with the overall admin system.