Skip to content
oks-ui

Building with oks-ui

Compose a form

Form collects values and fires onSubmit. FormFieldSet is one component that renders every field type. That's the whole model.

The shape

import { Form, FormFieldSet } from "oks-ui/form-field-set";
import { Button } from "oks-ui/button";

function ProfileForm() {
  return (
    <Form onSubmit={(data) => saveProfile(data)}>
      <FormFieldSet type="text" name="name" label="Name" />
      <FormFieldSet
        type="email"
        name="email"
        label="Email"
        validation={{ rules: { required: true, email: true } }}
      />
      <FormFieldSet
        type="select"
        name="role"
        label="Role"
        options={[
          { label: "Admin", value: "admin" },
          { label: "Editor", value: "editor" },
        ]}
      />
      <FormFieldSet type="switch" name="notify" label="Email me updates" defaultChecked />
      <Button type="submit" color="primary">Save</Button>
    </Form>
  );
}

Every field type is the same call

Change type and the right control renders — with the right label placement, the right keyboard behaviour, and the right ARIA. The types: text, textarea, select, password, otp, phone, range, file, switch, radio, checkbox, datepicker (and text also covers number / url / search / color).

Validation

Pass validation.rules. Errors render inline and set aria-invalid; the message is wired to the input with aria-describedby. Nothing else to do.

<FormFieldSet
  type="password"
  name="password"
  label="Password"
  validation={{
    rules: { required: true, minLength: 8 },
    messages: { minLength: "Use at least 8 characters." },
  }}
/>

Multi-step flows

For a wizard, reach for SteppedForm — it's built on FormFieldSet, tracks progress, and validates per step.