Skip to content

feat(design-system): add Field and Label, migrate webapp form fields#6657

Merged
macko911 merged 6 commits into
masterfrom
matej/nan-6079-replace-webapp-form-field-components-label-form-with-design
Jun 26, 2026
Merged

feat(design-system): add Field and Label, migrate webapp form fields#6657
macko911 merged 6 commits into
masterfrom
matej/nan-6079-replace-webapp-form-field-components-label-form-with-design

Conversation

@macko911

@macko911 macko911 commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Problem

The webapp shipped its own form-field primitives — Label and the Form set (Form/FormField/FormItem/FormLabel/FormControl/FormMessage/FormDescription/useFormField). These pair with the Input/InputGroup moved in NAN-6060 and belong in @nangohq/design-system alongside the other form building blocks, matching the Figma "Field" components.

Solution

  • Add the Field family to the design system (Field, FieldLabel, FieldDescription, FieldError, FieldGroup, FieldSet, FieldLegend, FieldSeparator) plus the Label primitive — token-exact to Figma and built on the DS Input.
  • Mirror shadcn: the Field family is dependency-free and react-hook-form integration uses RHF's Controller directly, so the design system takes no RHF dependency.
  • Rewrite the webapp Form.tsx as a thin RHF adapter over the Field family — same public API, so the existing RHF forms keep their imports while all presentation/tokens now come from the design system.
  • No standalone Label: the Figma DS models the label only as part of Field, so FieldLabel is the design system's label (it inlines the radix label). Repoint the webapp call sites to FieldLabel; delete the webapp Label.tsx and drop @radix-ui/react-label from the webapp.
  • Reconcile webapp typography utilities to DS tokens — notably the field description now uses text-secondary (was text-muted), matching Figma.

Fixes NAN-6079. Adopting the Field composition at the remaining call sites is tracked in NAN-6102 and NAN-6103.

Storybook

New stories under Design System/Components (deployed to https://storybook.nango.dev):

Testing

  • npm run ts-build, npm run lint, and npm run format:check pass; Storybook production build passes.
  • Verified live (REMOTE_API=dev) in light and dark: Signin, the Create Environment dialog (FormControl aria + FormMessage error), and Environment/User settings labels — no visual or behavioral regressions.
image

macko911 added 4 commits June 25, 2026 11:23
Follow-up to the NAN-6060 Input migration. Add the Label primitive and the dependency-free Field family (Field, FieldLabel, FieldDescription, FieldError, FieldGroup), mirroring shadcn and matching the Figma Field spec. The webapp typography utilities are reconciled to DS tokens (notably description -> text-secondary). Colocate stories under Design System/Components and drop the legacy webapp-backed showcase stories; react-hook-form is a devDependency only, for the Controller composition story.
Rewrite Form.tsx as a thin react-hook-form adapter over the DS Field family (same public API, presentation now sourced from the design system) and swap the standalone Label call sites to the DS Label. Delete the webapp Label.tsx and drop the now-unused @radix-ui/react-label dependency.
Round out the Field family from the Figma spec: FieldSet (semantic <fieldset> grouping), FieldLegend (legend/label variants with optional description) and FieldSeparator (rule with optional centered text). No webapp consumer yet — added so the family is complete and ready. Split the Field stories into focused per-component stories under the one Field title.
The webapp Label was deleted in this migration, but two legacy stories still imported it via the @ alias. The dev server is lazy so it never surfaced; the production build-storybook transforms every story and failed. Point them at the design-system Label.
@linear-code

linear-code Bot commented Jun 25, 2026

Copy link
Copy Markdown

NAN-6079

@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Preview Deploy

Status URL Deploy Logs Last Updated
✅ Ready Preview URL Deploy Logs 26 Jun 2026, 07:22 UTC

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

3 issues found across 42 files

Confidence score: 3/5

  • packages/design-system/src/components/ui/field.stories.tsx defines FieldSetComposition with two <FieldLegend> elements in one <fieldset>, which is invalid structure and can cause incorrect screen-reader announcements in the canonical example—update the story to a single first-child legend before merging.
  • packages/design-system/src/components/ui/label.tsx has disabled selectors that don’t match the current Field composition (group-data-[disabled=true] vs named group, and peer-disabled order mismatch), so disabled labels may render as enabled and confuse users—align the selectors with group/field (or restructure the markup) and verify the disabled state visually.
  • packages/design-system/src/components/ui/field.tsx drops ref forwarding in FieldLabel, which is an API regression for consumers relying on label refs for focus/measurement hooks—wrap FieldLabel in React.forwardRef and pass the ref through to de-risk downstream breakage.

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread packages/design-system/src/components/ui/field.stories.tsx Outdated
Comment thread packages/design-system/src/components/ui/field.tsx Outdated
Comment thread packages/design-system/src/components/ui/label.tsx Outdated
The Figma design system models the label only as part of Field, so don't ship a standalone Label. FieldLabel now inlines the radix label directly; label.tsx and its story are removed and the Label export is dropped. Repoint the webapp call sites and the Checkbox/Switch stories to FieldLabel. Rendering is unchanged.
The Field Set story nested two FieldLegends (each a <legend>) in one <fieldset>, which is invalid HTML. Wrap the Billing address sub-group in its own nested FieldSet so each fieldset has a single legend as its first child.
@macko911
macko911 marked this pull request as ready for review June 26, 2026 08:19
@macko911
macko911 requested a review from gabrielle-svg June 26, 2026 08:19
@superagent-security

Copy link
Copy Markdown

Superagent didn't find any vulnerabilities or security issues in this PR.

@macko911
macko911 added this pull request to the merge queue Jun 26, 2026
Merged via the queue into master with commit b875e86 Jun 26, 2026
35 checks passed
@macko911
macko911 deleted the matej/nan-6079-replace-webapp-form-field-components-label-form-with-design branch June 26, 2026 11:16
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.

2 participants