npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@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-formMIT licensed

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.