@financial-times/o3-form
v0.9.0
Published
Provides a viewport-aware tooltip for annotating or or highlighting other aspects of a product's UI
Readme
o3-form
Provides components to construct forms.
Overview
o3-form provides UI form elements with consistent labelling, descriptions, and error styles and interfaces.
Components
Form
Form is the top-level component that wraps all form elements. It can be used as plain HTML:
<form class="o3-form">
<!-- form elements go here -->
</form>Or users can also import JSX components:
import {Form} from '@financial-times/o3-form/cjs'; // or esm
<Form>
<!-- form elements go here -->
</Form>;| Prop | Description | required | Type | Default |
|------------|----------------------------------|----------|------|---------|
| children | The form elements to be rendered | true | any | - |
Form Field, Form Fieldset and Feedback
Form Field components can be complex and contain multiple elements. Form Field and Form Fieldset are containers for form elements. Shared anatomy of Form Field and Form Fieldset looks like composition of the following elements:
<form>
<form-field-element>
<title-label-element>
Title/Label
</title-label-element>
<description-element>
Description
</description-element>
<!-- form elements go here -->
<feedback-element>
Feedback
</feedback-element>
</form-field>
</form>We are using Title and Label interchangeably. But we export two JSX components from o3-form package: TitledFormField
and LabeledFormField. Both components are similar but TitledFormField is used with checkboxes, radio buttons and
use-cases when <label> element needs to be part of form element or more flexibility is require. LabeledFormField is
used with other text inputs.
The main difference between them is HTML they output. TitledFormField outputs:
<div className="o3-form-field">
<span className="o3-form-field__title" id="{labelId}"> Title </span>
<!--- Description -->
{children}
<!--- Feedback --->
</div>And LabeledFormField outputs:
<div className="o3-form-field">
<label className="o3-form-field__label" htmlFor="{id}"> label </label>
<!--- Description -->
{children}
<!--- Feedback --->
</div>TitleFormField expects children to contain both <input> and <label> elements, which helps us a lot with checkboxes
and radio buttons. LabeledFormField expects children to contain only <input> element. Two components in JSX can be
used as follows:
import {
Form,
TitledFormField,
LabeledFormField,
CheckBoxItem,
} from '@financial-times/o3-form/cjs'; // or esm
<Form>
<TitledFormField label="Title for checkbox" description="Description">
<input type="checkbox" id={inputId} />
<label htmlFor={inputId}>Checkbox Label</label>
</TitledFormField>
<LabeledFormField
label="Label for text input"
description="Description"
inputId={inputId}>
<input type="text" id={inputId} />
</LabeledFormField>
</Form>;Form Field and Form Fieldset components have same props:
| Prop | Description | required | Type | Default |
|---------------|----------------------------------------------------------------------------------------------------|----------|--------|---------|
| label | The label for the form fieldset | true | string | - |
| inputId | The id of the form input element | false | string | - |
| description | A description of the form fieldset | false | string | - |
| children | The form elements to be rendered | true | any | - |
| feedback | The feedback object for the form fieldset that contains message and type of message properties | false | string | - |
Form Fieldset is used to group related form elements together such as checkboxes. They can be used as plain HTML:
<form class="o3-form">
<div class="o3-form-field">
<fieldset className="o3-form-field" aria-describedby="descriptionId">
<legend className="o3-form-field__legend ">
Field group label/title
</legend>
<span className="o3-form-input__description" id="descriptionId">
description of the field group
</span>
<!-- form elements go here -->
</fieldset>
</div>
</form>Or users can also import JSX components:
import {Form, FormFieldset} from '@financial-times/o3-form/cjs'; // or esm
<Form>
<FormFieldset label="Field group label/title" description="description of the field group">
<!-- form elements go here -->
</FormFieldset>
</Form>;| Prop | Description | required | Type | Default |
|---------------|----------------------------------------------------------------------------------------------------|----------|--------|---------|
| label | The label for the form fieldset | true | string | - |
| description | A description of the form fieldset | false | string | - |
| children | The form elements to be rendered | true | any | - |
| feedback | The feedback object for the form fieldset that contains message and type of message properties | false | string | - |
Text Input
A standard text input for collecting text values. label: 'Full name', description: 'Your full name as printed on your driving license',
HTML
<div data-o3-brand="whitelabel">
<div class="o3-form-field">
<label for="my-input-field">Full name</label>
<span
class="o3-form-input-description"
>
Your full name as printed on your driving license
</span>
<input id="my-input-field" class="o3-form o3-form-text-input" type="text" />
</div>
</div>JSX
import {TextInput} from '@financial-times/o3-form/cjs'; // or esm
<TextInput
label="Full name"
disabled="{false}"
description="Your full name as printed on your driving license"
/>Short text input
The size and max length of the text input can be limited with the length property.
HTML
<div class="o3-form-field">
<label for="my-input-field">Security Code</label>
<span class="o3-form-input-description">
3 digit security code as printed on the back of your credit card.
</span>
<input
id="my-input-field"
class="o3-form o3-form-text-input o3-form-text-input--short-3"
maxlength="3"
type="text"
/>
</div>JSX
import {TextInput} from '@financial-times/o3-form/cjs'; // or esm
<TextInput
label="Security code"
description="3 digit security code as printed on the back of your credit card."
length="{3}"
/>;This will provide a text box 3 characters wide and only allow 3 characters to be typed.
If you prefer to limit the length without styling, use the maxLength attribute instead.
HTML
<div class="o3-form-field">
<label for="my-input-field">Security Code</label>
<span class="o3-form-input-description">
3 digit security code as printed on the back of your credit card.
</span>
<input
id="my-input-field"
class="o3-form o3-form-text-input"
maxlength="3"
type="text"
/>
</div>JSX
import {TextInput} from '@financial-times/o3-form/cjs'; // or esm
<TextInput
label="Security code"
description="3 digit security code as printed on the back of your credit card."
feedback={args.feedback}
attributes={{
maxLength: 3,
}}
/>Password Input
A password input for collecting password values. Features a show/hide password toggle and a forgot password link.
HTML
<div class="o3-form-field">
<label
class="o3-form-field__label"
for="o3-form-password-input-_5538262633951523"
>
Password
</label>
<span
class="o3-form-input__description"
id="o3-form-description_5812824517374977"
>
Your password must be at least 8 characters.
</span>
<div class="o3-password-input__container">
<input
id="o3-form-password-input-_5538262633951523"
class="o3-form o3-form-text-input o3-form-text-input--password"
required=""
type="password"
aria-required="true"
/>
<button
id="o3-form-password-toggle"
class="o3-password-input__show-password-toggle o3-password-input__show-password-toggle--show"
aria-label="Show password"
title="Show password"
aria-pressed="false"
></button>
</div>
<div class="o3-form-feedback o3-form-feedback__undefined">
<span class="o3-form-feedback__undefined-message"></span>
</div>
</div>
<div class="o3-password-input__controls">
<a class="o3-typography-link" href="#">Forgot password?</a>
</div>Be sure to include Javascript to enable the password toggle feature.
import PasswordInput from '@financial-times/o3-form/cjs/PasswordInput';
document.addEventListener('DOMContentLoaded', function() {
const passwordInput = new PasswordInput(
document.getElementById('o3-form-password-toggle')
);
});import {PasswordInput} from '@financial-times/o3-form';
<Form>
<PasswordInput
label="Password"
description="Your password must be at least 8 characters."
forgotPasswordLink="#" />
</Form>Checkbox
A customizable and accessible checkbox input for selecting one or more items from a list, or turning an item on or off.
Checkbox can also have a state of indeterminate and o3-form provides styling, for indeterminate state but this
state can only be set using javaScript. Read more
about indeterminate state.
Checkboxes can be used as plain HTML:
<form class="o3-form">
<div class="o3-form-field">
<span class="o3-form-field__title" id="o3-form-label_Demo_ID">
Check this box
</span>
<span class="o3-form-input__description" id="o3-form-description_DEMO_ID">
Please check the box to continue
</span>
<div class="o3-form-input__checkbox">
<input
type="checkbox"
id="checkbox_1"
class="o3-form-input__checkbox-input o3-visually-hidden"
required=""
aria-required="true"
/>
<label for="checkbox_1" class="o3-form-input__checkbox-label">
I agree to the terms and conditions
</label>
</div>
</div>
</form>Or users can also import JSX components:
import {CheckBox, TitledFormField} from '@financial-times/o3-form/cjs'; // or esm
<TitledFormField>
<CheckBox
inputId="terms"
checkboxLabel="I agree to the terms and conditions"
optional={false}
/>
;
</TitledFormField>;| Prop | Description | required | Type | Default |
|-----------------|-----------------------------------------------------------------------------------------------|----------|---------|---------|
| inputId | The id of the checkbox input | true | string | - |
| checkboxLabel | The label for the checkbox | true | string | - |
| feedback | The feedback object for the checkbox that contains message and type of message properties | false | string | - |
| optional | Whether the checkbox is optional | false | boolean | - |
| label | The title for the checkbox | false | string | - |
| description | A description of the checkbox | false | string | - |
Checkbox Group
For multiple related checkboxes, use the CheckBoxGroup component:
<form class="o3-form">
<fieldset
class="o3-form-field"
aria-describedby="o3-form-Interest-description"
>
<legend class="o3-form-field__legend">Select your interests</legend>
<span class="o3-form-input__description" id="o3-form-Interest-description2">
Choose all interests that apply
</span>
<div class="o3-form-input__checkbox">
<input
type="checkbox"
id="interest-tech"
class="o3-form-input__checkbox-input o3-visually-hidden"
/>
<label for="interest-tech" class="o3-form-input__checkbox-label">
Technology
</label>
</div>
<div class="o3-form-input__checkbox">
<input
type="checkbox"
id="interest-finance"
class="o3-form-input__checkbox-input o3-visually-hidden"
/>
<label for="interest-finance" class="o3-form-input__checkbox-label">
Finance
</label>
</div>
<div class="o3-form-input__checkbox">
<input
type="checkbox"
id="interest-sports"
class="o3-form-input__checkbox-input o3-visually-hidden"
/>
<label for="interest-sports" class="o3-form-input__checkbox-label">
Sports
</label>
</div>
</fieldset>
</form>import {CheckBoxGroup, CheckBoxItem} from '@financial-times/o3-form/cjs'; // or esm
<CheckBoxGroup
label="Select your interests"
description="Choose all that apply">
<CheckBoxItem inputId="interest-tech" checkboxLabel="Technology" />
<CheckBoxItem inputId="interest-finance" checkboxLabel="Finance" />
<CheckBoxItem inputId="interest-sports" checkboxLabel="Sports" />
</CheckBoxGroup>;| Attribute | Description | Type | Default |
|---------------|------------------------------------------|------------|---------|
| label | The label for the group of checkboxes | string | |
| description | A description of the group of checkboxes | string | |
| children | The checkboxes to be rendered | CheckBox[] | |
Select Input
A dropdown select input for choosing one option from a list.
HTML
<div class="o3-form-field">
<label
class="o3-form-field__label"
for="o3-form-select-input-_3564083419195512"
>
Card type
</label>
<span
class="o3-form-input__description"
id="o3-form-description_14471165011746046"
>
Printed on the front side of your payment card.
</span>
<div class="o3-form-select-input__container">
<select
id="o3-form-select-input-_3564083419195512"
class="o3-form o3-form-select-input"
required=""
aria-required="true"
maxlength="0"
type="select"
>
<option value="American Express">American Express</option>
<option value="Visa Debit">Visa Debit</option>
<option value="Visa Credit">Visa Credit</option>
<option value="Mastercard Debit">Mastercard Debit</option>
<option value="Mastercard Credit">Mastercard Credit</option>
</select>
</div>
<div class="o3-form-feedback o3-form-feedback__undefined">
<span class="o3-form-feedback__undefined-message"></span>
</div>
</div>TSX
import {SelectInput} from '@financial-times/o3-form';
<SelectInput
label="Card type"
description="Printed on the front side of your payment card."
>
<option value="American Express">American Express</option>
<option value="Visa Debit">Visa Debit</option>
<option value="Visa Credit">Visa Credit</option>
<option value="Mastercard Debit">Mastercard Debit</option>
<option value="Mastercard Credit">Mastercard Credit</option>
</SelectInput>Short Text Input
Select input supports width control for shorter inputs:
<div class="o3-form-field">
<label
class="o3-form-field__label"
for="o3-form-select-input-_3564083419195512"
>
Title
</label>
<div class="o3-form-select-input__container o3-form-select-input--short-3">
<select
id="o3-form-select-input-_3564083419195512"
class="o3-form o3-form-select-input"
required=""
aria-required="true"
maxlength="0"
type="select"
>
<option value="American Express">American Express</option>
<option value="Visa Debit">Visa Debit</option>
<option value="Visa Credit">Visa Credit</option>
<option value="Mastercard Debit">Mastercard Debit</option>
<option value="Mastercard Credit">Mastercard Credit</option>
</select>
</div>
<div class="o3-form-feedback o3-form-feedback__undefined">
<span class="o3-form-feedback__undefined-message"></span>
</div>
</div>TSX
import {SelectInput} from '@financial-times/o3-form';
<SelectInput
label="Title"
length="3"
>
<option value="Mr">Mr</option>
<option value="Mrs">Mrs</option>
<option value="Mx>">Mx</option>
</SelectInput>Date Input
Used for collecting date values, Origami provides two options for date input.
Date Picker
Makes use of the browser's native date picker. We recommend using this if you need to support core experiences.
TSX
import {DateInputPicker} from '@financial-times/o3-form';
const MyForm = () => {
<Form>
<DateInputPicker
label="Date of birth"
description="The year you were born"
/>
</Form>;
};HTML
<div class="o3-form">
<div class="o3-form-field">
<label
class="o3-form-field__label"
for="o3-form-date-input"
>
Date of Birth
</label>
<span
class="o3-form-input__description"
id="o3-form-description"
>
The date you were born
</span>
<input
id="o3-form-date-input"
class="o3-form o3-form-text-input"
required=""
type="date"
aria-required="true"
pattern="[0-9]{2}/[0-9]{2}/[0-9]{4}"
/>
<div class="o3-form-feedback o3-form-feedback__undefined">
<span class="o3-form-feedback__undefined-message"></span>
</div>
</div>
</div>Date Text Input
An input allowing users to input a date via text input only. We recommend using Date Picker if you need to support core experiences.
import {DateInputPicker} from '@financial-times/o3-form';
const MyForm = () => {
<Form>
<DateInput
label="Date of birth"
description="The year you were born"
/>
</Form>;
};<script>
import DateInput from '@financial-times/o3-form/cjs/DateInput';
document.addEventListener('DOMContentLoaded', function() {
const dateInput = new DateInput(
document.getElementById('o3-form-date-input)
);
});
</script>
<div
class="o3-form"
style="grid-column: content-start / content-end; font-family: var(--o3-font-family-metric);"
>
<div class="o3-form-field">
<label
class="o3-form-field__label"
for="o3-form-date-input"
>
Date of Birth
</label>
<span
class="o3-form-input__description"
id="o3-form-description"
>
The date you were born
</span>
<input
id="o3-form-date-input"
class="o3-form o3-form-text-input"
required=""
type="text"
aria-required="true"
pattern="[0-9]{2}/[0-9]{2}/[0-9]{4}"
/>
<div class="o3-form-feedback o3-form-feedback__undefined">
<span class="o3-form-feedback__undefined-message"></span>
</div>
</div>
</div>
</div>Contact
If you have any questions or comments about this component, or need help using it, please either raise an issue, visit #origami-support or email Origami Support.
Licence
This software is published by the Financial Times under the MIT licence.
