Skip to content

Form

Form wrapper with validation, layout options, and field management.

import { Form } from 'asterui'

Basic Form

Simple login form with username and password fields.

 

 

import { Form, Input, Button } from 'asterui'

function App() {
  return (
      <Form onFinish={(values) => alert(JSON.stringify(values, null, 2))}>
        <Form.Item name="username" label="Username">
          <Input placeholder="Enter username" />
        </Form.Item>
        <Form.Item name="password" label="Password">
          <Input type="password" placeholder="Enter password" />
        </Form.Item>
        <Form.Item>
          <Button color="primary" htmlType="submit">
            Login
          </Button>
        </Form.Item>
      </Form>
    )
}

export default App

Form Validation

Form with validation rules for required fields and email pattern.

 

 

import { Form, Input, Button } from 'asterui'

function App() {
  return (
      <Form onFinish={(values) => alert(JSON.stringify(values, null, 2))}>
        <Form.Item
          name="email"
          label="Email"
          rules={[
            { required: true, message: 'Please enter your email' },
            { type: 'email', message: 'Please enter a valid email' }
          ]}
        >
          <Input placeholder="name@example.com" />
        </Form.Item>
        <Form.Item
          name="password"
          label="Password"
          rules={[
            { required: true, message: 'Please enter your password' },
            { min: 6, message: 'Password must be at least 6 characters' }
          ]}
        >
          <Input type="password" placeholder="Enter password" />
        </Form.Item>
        <Form.Item>
          <Button color="primary" htmlType="submit">
            Submit
          </Button>
        </Form.Item>
      </Form>
    )
}

export default App

Tooltip & Extra

Labels with tooltip help icons and extra helper text below fields.

 

Username must be 3-20 characters
import { Form, Input, Button } from 'asterui'

function App() {
  return (
      <Form onFinish={(values) => alert(JSON.stringify(values, null, 2))}>
        <Form.Item
          name="username"
          label="Username"
          tooltip="Your unique identifier on the platform"
          extra="Username must be 3-20 characters"
          rules={[{ required: true }, { min: 3 }, { max: 20 }]}
        >
          <Input placeholder="Choose a username" />
        </Form.Item>
        <Form.Item>
          <Button color="primary" htmlType="submit">Save</Button>
        </Form.Item>
      </Form>
    )
}

export default App

Validation Feedback

Show validation icons inside inputs with hasFeedback prop.

 

 

import { Form, Input, Button } from 'asterui'

function App() {
  return (
      <Form onFinish={(values) => alert(JSON.stringify(values, null, 2))}>
        <Form.Item
          name="email"
          label="Email"
          hasFeedback
          rules={[{ required: true }, { type: 'email' }]}
        >
          <Input placeholder="you@example.com" />
        </Form.Item>
        <Form.Item
          name="password"
          label="Password"
          hasFeedback
          rules={[
            { required: true },
            { min: 8, message: 'At least 8 characters' },
          ]}
        >
          <Input type="password" placeholder="Enter password" />
        </Form.Item>
        <Form.Item>
          <Button color="primary" htmlType="submit">Register</Button>
        </Form.Item>
      </Form>
    )
}

export default App

Form Layouts

Different form layouts: horizontal, vertical, and inline.

 

 

import { Form, Input, Button, Radio, Space } from 'asterui'
import { useState } from 'react'

function App() {
  const [layout, setLayout] = useState<'horizontal' | 'vertical' | 'inline'>('vertical')
  
  return (
      <Space direction="vertical" size="lg" className="w-full">
        <Radio.Group
          value={layout}
          onChange={(e) => setLayout(e.target.value as typeof layout)}
        >
          <Radio value="vertical">Vertical</Radio>
          <Radio value="horizontal">Horizontal</Radio>
          <Radio value="inline">Inline</Radio>
        </Radio.Group>
  
        <Form layout={layout} onFinish={(values) => alert(JSON.stringify(values, null, 2))}>
          <Form.Item name="name" label="Name" required>
            <Input placeholder="Enter name" />
          </Form.Item>
          <Form.Item name="email" label="Email" required>
            <Input placeholder="Enter email" />
          </Form.Item>
          <Form.Item>
            <Button color="primary" htmlType="submit">
              Submit
            </Button>
          </Form.Item>
        </Form>
      </Space>
    )
}

export default App

Initial Values

Form with pre-populated initial values.

 

 

 

import { Form, Input, Button, Textarea } from 'asterui'

function App() {
  const initialValues = {
    username: 'john_doe',
    email: 'john@example.com',
    bio: 'Software developer'
  }
  
  return (
      <Form initialValues={initialValues} onFinish={(values) => alert(JSON.stringify(values, null, 2))}>
        <Form.Item name="username" label="Username">
          <Input />
        </Form.Item>
        <Form.Item name="email" label="Email">
          <Input />
        </Form.Item>
        <Form.Item name="bio" label="Bio">
          <Textarea rows={3} />
        </Form.Item>
        <Form.Item>
          <Button color="primary" htmlType="submit">
            Update Profile
          </Button>
        </Form.Item>
      </Form>
    )
}

export default App

Form.useForm

Create a form instance to set values and reset fields programmatically.

 

 

import { Form, Input, Button, Space, Modal } from 'asterui'

function App() {
  const form = Form.useForm<{ name: string; email: string }>()
  
  const fillSample = () => {
    form.setFieldsValue({
      name: 'Aster UI',
      email: 'hello@asterui.com',
    })
  }
  
  const reset = () => form.resetFields()
  
  const handleFinish = (values: { name: string; email: string }) => {
    Modal.info({
      title: 'Form Submitted',
      content: <pre className="text-left">{JSON.stringify(values, null, 2)}</pre>,
    })
  }
  
  return (
      <Form form={form} onFinish={handleFinish}>
        <Form.Item name="name" label="Name" rules={[{ required: true }]}>
          <Input className="w-full" placeholder="Jane Doe" />
        </Form.Item>
        <Form.Item name="email" label="Email" rules={[{ required: true }, { type: 'email' }]}>
          <Input className="w-full" placeholder="jane@example.com" />
        </Form.Item>
        <Form.Item>
          <Space>
            <Button type="button" variant="outline" onClick={fillSample}>
              Fill Sample
            </Button>
            <Button type="button" variant="ghost" onClick={reset}>
              Reset
            </Button>
            <Button color="primary" htmlType="submit">
              Submit
            </Button>
          </Space>
        </Form.Item>
      </Form>
    )
}

export default App

Floating Labels

Form.Item with floating labels that animate when focused.

 

 

 

import { Form, Input, Button } from 'asterui'

function App() {
  return (
      <Form onFinish={(values) => alert(JSON.stringify(values, null, 2))}>
        <Form.Item name="fullName" floatingLabel="Full Name" required>
          <Input />
        </Form.Item>
        <Form.Item name="email" floatingLabel="Email Address" required>
          <Input type="email" />
        </Form.Item>
        <Form.Item name="password" floatingLabel="Password" required>
          <Input type="password" />
        </Form.Item>
        <Form.Item>
          <Button color="primary" htmlType="submit">
            Sign Up
          </Button>
        </Form.Item>
      </Form>
    )
}

export default App

Form Addons

Form.Item with text/elements before or after inputs.

 

 

 

import { Form, Input, Button } from 'asterui'

function App() {
  return (
      <Form onFinish={(values) => alert(JSON.stringify(values, null, 2))}>
        <Form.Item name="website" label="Website" addonBefore="https://">
          <Input placeholder="your-site.com" />
        </Form.Item>
        <Form.Item name="price" label="Price" addonBefore="$" addonAfter=".00">
          <Input type="number" placeholder="0" />
        </Form.Item>
        <Form.Item name="email" label="Email" addonAfter="@company.com">
          <Input placeholder="username" />
        </Form.Item>
        <Form.Item>
          <Button color="primary" htmlType="submit">
            Submit
          </Button>
        </Form.Item>
      </Form>
    )
}

export default App

Dynamic Fields (Form.List)

Add and remove form fields dynamically with Form.List.

 

 

import { Form, Input, Button, Space, Modal } from 'asterui'

function App() {
  return (
      <Form
        initialValues={{ guests: [{ name: '', email: '' }] }}
        onFinish={(values) => Modal.info({ title: 'Form Data', content: JSON.stringify(values, null, 2) })}
      >
        <Form.List name="guests">
          {(fields, { add, remove }) => (
            <Space direction="vertical" className="w-full">
              {fields.map((field, index) => (
                <Space key={field.id} className="w-full items-end">
                  <Form.Item
                    name={[field.name, 'name']}
                    label={index === 0 ? 'Name' : undefined}
                    rules={[{ required: true, message: 'Name required' }]}
                  >
                    <Input placeholder="Guest name" />
                  </Form.Item>
                  <Form.Item
                    name={[field.name, 'email']}
                    label={index === 0 ? 'Email' : undefined}
                    rules={[{ required: true }, { type: 'email' }]}
                  >
                    <Input placeholder="Email" />
                  </Form.Item>
                  <Form.Item>
                    <Button
                      type="button"
                      color="error"
                      variant="ghost"
                      size="sm"
                      onClick={() => remove(index)}
                      disabled={fields.length === 1}
                    >
                      Remove
                    </Button>
                  </Form.Item>
                </Space>
              ))}
              <Button type="button" variant="outline" onClick={() => add({ name: '', email: '' })}>
                + Add Guest
              </Button>
            </Space>
          )}
        </Form.List>
        <Form.Item>
          <Button color="primary" htmlType="submit" className="mt-4">
            Submit
          </Button>
        </Form.Item>
      </Form>
    )
}

export default App
PropertyDescriptionTypeDefault
onFinishSuccess handler (called when validation passes)(values: any) => void-
onFinishFailedFailed handler (called when validation fails)(errorInfo: any) => void-
initialValuesInitial form field valuesRecord<string, any>-
layoutForm layout orientation'horizontal' | 'vertical' | 'inline''vertical'
labelWidthLabel width in pixels for horizontal layoutnumber60
sizeSize of form controls'xs' | 'sm' | 'md' | 'lg' | 'xl''md'
disabledDisable all form fieldsbooleanfalse
childrenForm content (Form.Item elements)React.ReactNode-
classNameAdditional CSS classesstring-
PropertyDescriptionTypeDefault
nameField name (required for validation)string-
labelField label textstring-
floatingLabelFloating label text (alternative to label)string-
addonBeforeText/element before input (outside)React.ReactNode-
addonAfterText/element after input (outside)React.ReactNode-
rulesValidation rulesValidationRule[]-
requiredMark field as required (shorthand)booleanfalse
valuePropNameProp name for value (e.g., “checked” for checkboxes)string'value'
inlineRender with auto width instead of full widthbooleanfalse
tooltipTooltip text to show next to labelstring-
extraAdditional content below the form controlReact.ReactNode-
hasFeedbackShow validation feedback iconbooleanfalse
dependenciesField names that trigger re-validation when changedstring[]-
validateTriggerWhen to validate'onChange' | 'onBlur' | 'onSubmit' | array'onChange'
initialValueInitial value for this fieldany-
hiddenHide field but still validate and submitbooleanfalse
childrenForm control element (Input, Select, etc.)React.ReactNode-
classNameAdditional CSS classesstring-
PropertyDescriptionTypeDefault
fieldsSpecific field names to show errors for (shows all if not specified)string[]-
classNameAdditional CSS classesstring-

Manages dynamic arrays of form fields.

PropertyDescriptionTypeDefault
nameName of the array fieldstring-
childrenRender function(fields, operations) => ReactNode-

Fields array item:

  • id - Unique identifier for the field
  • name - Index of the field (use in Form.Item name as [field.name, 'fieldKey'])

Operations:

  • add(value?) - Add a new field with optional initial value
  • remove(index) - Remove field at index
  • move(from, to) - Move field from one index to another

The rules prop accepts an array of validation rules:

  • required: boolean - Field is required
  • message: string - Error message to display
  • type: 'email' | 'url' | 'number' - Built-in type validation
  • min: number - Minimum length for strings or minimum value for numbers
  • max: number - Maximum length for strings or maximum value for numbers
  • pattern: RegExp - Custom regex pattern validation
  • validate: (value) => boolean | string | Promise - Custom validation function