Fix missing form-control color tokens in the ESM build - #1417
Conversation
The `--brand-control-*` color tokens only reached CSS through a shared side-effect import in the forms barrel (`src/forms/index.ts`), which the ESM build's tree-shaking dropped. As a result, consumers importing from `@primer/react-brand/esm` without the global `lib/css/main.css` lost all form-control borders and boxes (checkboxes and radios rendered invisible). Co-locate the control `colors-with-modes.css` import in each form component (TextInput, Textarea, Select, Checkbox, Radio, FormControl), matching the established Button pattern, so the tokens ride along in the component modules that are unavoidably included when the components are used. Remove the now-redundant barrel import. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: afd2ea59-8442-4214-bd4b-ecc92d8987a5
🦋 Changeset detectedLatest commit: 5ebb629 The changes in this PR will be included in the next version bump. This PR includes changesets to release 9 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
🟢 No design token changes found |
🟢 Unit test coverage changes foundUnit test coverage has been updated through this PR. Changes: 0 new tests, 0 removed tests, 2 improved, 0 decreased
|
🟢 Bundle size report
|
🟢 No visual differences foundOur visual comparison tests did not find any differences in the UI. |
There was a problem hiding this comment.
Pull request overview
Fixes a packaging gap in @primer/react-brand/esm where the shared --brand-control-* color token CSS was not being emitted for ESM consumers (causing form controls to render without borders/boxes when lib/css/main.css is not loaded). The change aligns forms with the existing per-component “co-located token import” pattern used elsewhere in the library (e.g. Button).
Changes:
- Co-locate the
functional/components/control/colors-with-modes.cssside-effect import into each of:TextInput,Textarea,Select,Checkbox,Radio, andFormControl. - Remove the now-ineffective shared side-effect import from
packages/react/src/forms/index.ts(which the ESM build does not reliably emit as a preserved module). - Add a changeset documenting the ESM-only fix and impacted released versions.
Show a summary per file
| File | Description |
|---|---|
| packages/react/src/forms/TextInput/TextInput.tsx | Adds co-located control color token CSS import so ESM TextInput carries required tokens. |
| packages/react/src/forms/Textarea/Textarea.tsx | Adds co-located control color token CSS import for ESM Textarea token availability. |
| packages/react/src/forms/Select/Select.tsx | Adds co-located control color token CSS import for ESM Select token availability. |
| packages/react/src/forms/Checkbox/Checkbox.tsx | Adds co-located control color token CSS import for ESM Checkbox token availability. |
| packages/react/src/forms/Radio/Radio.tsx | Adds co-located control color token CSS import for ESM Radio token availability. |
| packages/react/src/forms/FormControl/FormControl.tsx | Adds co-located control color token CSS import for ESM FormControl token availability. |
| packages/react/src/forms/index.ts | Removes barrel-level side-effect import that didn’t survive ESM output. |
| .changeset/fix-esm-control-color-tokens.md | Documents the patch release and the ESM-only consumer impact/upgrade note. |
Review details
- Files reviewed: 8/8 changed files
- Comments generated: 0
- Review effort level: Low
rezrah
left a comment
There was a problem hiding this comment.
LGTM. One change request for the changelog. Thanks for fixing this 🙇.
Co-authored-by: Rez <13340707+rezrah@users.noreply.github.com>
Summary
The
@primer/react-brand/esmbuild never shipped the--brand-control-*color token family, so pure-ESM consumers that drop the globallib/css/main.csslose every form-control border and box:TextInput/Select/Textareaborders disappear andCheckbox/Radiorender invisible (this is what broke the ContactSales form on github.com/enterprise/contact).The control color tokens reached CSS only through a single side-effect import in the
forms/index.tsre-export barrel. The ESM build (Vite + rolldown,preserveModules) rewrites the package entry to import the leaf component modules directly and never emitsesm/forms/index.js, so that barrel's CSS side-effect — and the tokens with it — silently vanished from the ESM output. Every other component (Button, Card, Label, …) already co-locates its owncolors-with-modes.cssimport inside the component, so its tokens ride along with the component module; the forms family was the lone exception relying on the barrel.This moves the control-token import into each of the six form components to match that established per-component pattern, and drops the now-redundant barrel import.
lib/css/main.css(the monolithic CSS-class build) is unaffected.Both released
0.70.0and0.71.0ship the ESM build without these tokens — no released version has ever shipped working ESM control tokens — so consumers on the ESM entry will need to upgrade to the release containing this fix.List of notable changes:
functional/components/control/colors-with-modes.cssimport toTextInput,Textarea,Select,Checkbox,RadioandFormControl, so the--brand-control-*color tokens ship with the components in the ESM build (mirrors the existingButtonpattern)forms/index.ts, since the ESM build drops that re-export barrel and it therefore never delivered the tokens to ESM consumersWhat should reviewers focus on?
Button.tsx), rather than the barrel-level import it replaces.lib/css/main.cssis unchanged in content — the fix only changes what the ESM build emits (the CSS-class build was already self-contained).--brand-control-large-*,--brand-control-medium-*,--brand-control-animation-*), which already shipped in ESM, are not regressed.Steps to test:
npm run build:lib.packages/react/esm/: each of the six form component.jsfiles now side-effect-imports afunctional/components/control/colors-with-modes-*.css, and that token CSS is emitted intoesm/(previously it was absent entirely).esm/**/*.css: 0--brand-control-*tokens are now used without a definition (was 32).FormControl/TextInput/Select/Checkbox/Radiofrom@primer/react-brand/esmin a bundler without importingmain.css. Controls now render with borders/boxes; before this fix the borders collapsed and checkboxes/radios were invisible.Reference-vs-definition check (run from
packages/react, prints 0 after the fix)Supporting resources (related issues, external links, etc):
@primer/react-brand@0.70.0and@0.71.0— both ship the ESM build without the--brand-control-*color tokens. Consumers using the ESM entry should upgrade once this ships.Contributor checklist:
tsc, ESLint with 0 warnings, Prettier,jest src/forms— 82 tests)esm/output (reference check + an ESM-only consumer harness)main.cssis unchangedReviewer checklist:
Screenshots: