Skip to content

feat: remove dependency on o-utils from o3-form, require inputId#2365

Open
frshwtr wants to merge 3 commits intomainfrom
or-2108/remove-reliance-on-o-utils-from-o3
Open

feat: remove dependency on o-utils from o3-form, require inputId#2365
frshwtr wants to merge 3 commits intomainfrom
or-2108/remove-reliance-on-o-utils-from-o3

Conversation

@frshwtr
Copy link
Contributor

@frshwtr frshwtr commented Feb 13, 2026

No description provided.

feedback={feedback}
description={description}
inputId={id}
inputId={inputId}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this prop to be misleading. In most components, the prop is used to assign an ID to the HTMLElement. However in this case it is used as a reference for htmlFor

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant by good change is the value for the input is clearer even though it says inputId in there already 😂

Copy link
Member

@j-mes j-mes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates o3-form to remove its reliance on @financial-times/o-utils for ID generation by making inputId required and wiring all rendered id/htmlFor references directly to that value.

Changes:

  • Make inputId a required prop across o3-form input/fieldset types.
  • Remove uidBuilder usage in form components and derive related element IDs from inputId.
  • Drop @financial-times/o-utils from o3-form peer dependencies (and update the lockfile accordingly).

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
package-lock.json Removes o-utils peer dep entry for o3-form and bumps o-teaser version.
components/o3-form/package.json Removes @financial-times/o-utils from peerDependencies.
components/o3-form/src/types/index.ts Makes inputId required on base/select/fieldset-related props.
components/o3-form/src/tsx/fieldComponents/FormField.tsx Removes generated IDs; ties label/description IDs to inputId.
components/o3-form/src/tsx/TextInput.tsx Removes generated fallback ID; uses inputId directly.
components/o3-form/src/tsx/SelectInput.tsx Removes generated fallback ID; uses inputId directly.
components/o3-form/src/tsx/RadioButton.tsx Removes generated fallback ID for radio items.
components/o3-form/src/tsx/PasswordInput.tsx Removes generated fallback ID; uses inputId directly.
components/o3-form/src/tsx/FileInput.tsx Removes generated fallback ID; uses inputId directly.
components/o3-form/src/tsx/DateInputPicker.tsx Removes generated fallback ID; uses inputId directly.
components/o3-form/src/tsx/DateInput.tsx Removes generated fallback ID; uses inputId directly.
components/o3-form/src/tsx/CheckBox.tsx Removes generated fallback ID for checkbox items.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 1 to 4
// Base Input Props
export type BaseInputProps = {
inputId?: string;
inputId: string;
label?: string;
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inputId is now required on BaseInputProps, SelectInputProps, and FormFieldsetProps, but existing in-repo usages (e.g. Storybook stories and README TSX snippets) still omit inputId. This will cause TypeScript build/story/test failures unless those call sites are updated (or the components keep a fallback ID generation).

Copilot uses AI. Check for mistakes.
inputId is misleading on LabaledFormField as it does not provide an ID to that element. Instead, it is used as a ref in htmlFor.
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 16 out of 17 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (2)

components/o3-form/src/types/index.ts:9

  • BaseInputProps now requires label, which forces components like CheckBoxItem/RadioButtonItem (which use checkboxLabel/radioButtonLabel) to supply an unused label prop and breaks existing call sites. Consider splitting the shared props (e.g., inputId-only base) from “labeled field” props, or keep label optional on the base type and require it only for components that actually render it. Also note that making inputId required in TS doesn’t enforce it for JS consumers—consider a runtime invariant/throw when it’s missing/empty to avoid rendering id={undefined}.
export type BaseInputProps = {
	inputId: string;
	label: string;
	description?: string;
	optional?: boolean;
	error?: boolean;
	attributes?: JSX.IntrinsicElements['input'];
};

components/o3-form/src/tsx/fieldComponents/FormField.tsx:85

  • FormFieldset always sets aria-describedby to checkbox_${inputId}, even when description is not provided and the element with that id is never rendered. This produces an aria-describedby reference to a non-existent element; set aria-describedby only when description is present (or render the described element unconditionally).
	const descriptionId = `checkbox_${inputId}`;
	const labelClasses = ['o3-form-field__legend'];
	if (optional) {
		labelClasses.push('o3-form-field--optional');
	}
	return (
		<fieldset className="o3-form-field" aria-describedby={`${descriptionId}`}>
			<legend className={labelClasses.join(' ')}>
				{label}{' '}
				{description && (
					<span className="o3-form-input__description" id={descriptionId}>
						{description}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@j-mes
Copy link
Member

j-mes commented Feb 19, 2026

@joelcarr and I looked at this in the Murder of Devs meeting today and addressed quite a few concerns.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants