feat(design-system): add Field and Label, migrate webapp form fields#6657
Merged
macko911 merged 6 commits intoJun 26, 2026
Conversation
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.
Contributor
Preview Deploy
|
Contributor
There was a problem hiding this comment.
3 issues found across 42 files
Confidence score: 3/5
packages/design-system/src/components/ui/field.stories.tsxdefinesFieldSetCompositionwith 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.tsxhas disabled selectors that don’t match the current Field composition (group-data-[disabled=true]vs named group, andpeer-disabledorder mismatch), so disabled labels may render as enabled and confuse users—align the selectors withgroup/field(or restructure the markup) and verify the disabled state visually.packages/design-system/src/components/ui/field.tsxdrops ref forwarding inFieldLabel, which is an API regression for consumers relying on label refs for focus/measurement hooks—wrapFieldLabelinReact.forwardRefand pass the ref through to de-risk downstream breakage.
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
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.
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
pfreixes
approved these changes
Jun 26, 2026
macko911
deleted the
matej/nan-6079-replace-webapp-form-field-components-label-form-with-design
branch
June 26, 2026 11:16
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The webapp shipped its own form-field primitives —
Labeland theFormset (Form/FormField/FormItem/FormLabel/FormControl/FormMessage/FormDescription/useFormField). These pair with theInput/InputGroupmoved in NAN-6060 and belong in@nangohq/design-systemalongside the other form building blocks, matching the Figma "Field" components.Solution
Fieldfamily to the design system (Field,FieldLabel,FieldDescription,FieldError,FieldGroup,FieldSet,FieldLegend,FieldSeparator) plus theLabelprimitive — token-exact to Figma and built on the DSInput.Fieldfamily is dependency-free and react-hook-form integration uses RHF'sControllerdirectly, so the design system takes no RHF dependency.Form.tsxas a thin RHF adapter over theFieldfamily — same public API, so the existing RHF forms keep their imports while all presentation/tokens now come from the design system.Label: the Figma DS models the label only as part of Field, soFieldLabelis the design system's label (it inlines the radix label). Repoint the webapp call sites toFieldLabel; delete the webappLabel.tsxand drop@radix-ui/react-labelfrom the webapp.text-secondary(wastext-muted), matching Figma.Fixes NAN-6079. Adopting the
Fieldcomposition 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, andnpm run format:checkpass; Storybook production build passes.REMOTE_API=dev) in light and dark: Signin, the Create Environment dialog (FormControlaria +FormMessageerror), and Environment/User settings labels — no visual or behavioral regressions.