Forms
Learn how to compose forms using IYK's design system components.
Form Structure
At IYK, we compose forms using a consistent pattern that combines several UI components to create accessible and user-friendly form fields. Each form field follows this structure:
- Label
-  Describes the purpose of the field using the UI.Labelcomponent
- Field
-  Wraps the input and provides context using the UI.Fieldcomponent with props likename,required, andvalidationMessage
- Input
-  The actual input component (e.g., UI.Textbox,UI.Select,UI.Choice)
- Validity
-  Shows validation messages using the UI.Validitycomponent
- Fieldset
-  Groups related form fields together, improving form organization and accessibility. 
Example
import * as UI from "@iyk/ui"
export default function Example() {
  return (
    <form className="w-full">
      <UI.Fieldset>
        <UI.Field name="email" required validationMessage="Please enter a valid email address">
          <UI.Label>Email</UI.Label>
          <UI.Textbox type="email" placeholder="Enter your email" />
          <UI.Validity />
        </UI.Field>
        <UI.Field name="country" required>
          <UI.Label>Country</UI.Label>
          <UI.Select>
            <option value="">Select a country</option>
            <option value="US">United States</option>
            <option value="CA">Canada</option>
            <option value="UK">United Kingdom</option>
          </UI.Select>
          <UI.Validity />
        </UI.Field>
        <UI.Field name="newsletter">
          <UI.Checkbox value="subscribe">Subscribe to our newsletter</UI.Checkbox>
          <UI.Validity />
        </UI.Field>
        <UI.ButtonGroup>
          <UI.Button type="submit" kind="solid" size="md">
            Submit
          </UI.Button>
        </UI.ButtonGroup>
      </UI.Fieldset>
    </form>
  )
}
Best Practices
Follow these best practices when composing forms:
- 
• Always use UI.Fieldto wrap form inputs. This ensures proper accessibility and validation handling.
- 
• Include UI.Validityafter each input to display validation messages consistently.
- 
• Use UI.Fieldsetto group related form fields together, improving form organization and accessibility.
- 
• Set appropriate input types (e.g., type="email",type="tel") to enable proper validation and mobile keyboard types.
- 
• Use requiredprop onUI.Fieldto indicate mandatory fields.
- 
• Provide clear validation messages using the validationMessageprop onUI.Field.
Validation Message Overrides
When using inputs, you can override the default browser validation message while keeping the built-in validation. This provides a consistent user experience across different browsers.
Here is an example of how to override the default browser validation message for an email input:
import * as UI from "@iyk/ui"
export default function Example() {
  return (
    <form className="w-full">
      <UI.Field name="email" required>
        <UI.Label>Email</UI.Label>
        <UI.Textbox
          type="email"
          required
          placeholder="Your email"
          validate={(control) => {
            if (
              control.validity.typeMismatch ||
              control.validity.badInput ||
              control.validity.valueMissing
            ) {
              return "Please enter a valid email address"
            }
          }}
        />
        <UI.Validity />
      </UI.Field>
    </form>
  )
}