docs(components): add Forms guidelines page to Storybook - #1961
Draft
cmwinters wants to merge 3 commits into
Draft
docs(components): add Forms guidelines page to Storybook#1961cmwinters wants to merge 3 commits into
cmwinters wants to merge 3 commits into
Conversation
Adds the first page under the Guidelines section, which was already reserved in storySort.order but had no content. The page documents what the code actually enforces. Its main job is the composition rule: no form component accepts label, description, errorMessage or placeholder as a prop, because React Aria omits them in favour of slot composition. Those are React Spectrum props, and the confusion is easy to hit since AGENTS.md mentions the names as a convention to mirror rather than as a description of the current API. It also records three gaps rather than papering over them: required fields render no visible marker, FieldError has no icon or live region, and helper text fails contrast inside picker items. All three regressed from the deprecated form package or are suppressed in axe config. Content guidelines are left as an explicitly-owned scaffold. The repo has no written copy standards to point at, so wording rules are marked as needing a content designer instead of being invented here. Examples live in a companion story file tagged ['!dev', '!autodocs'] so they stay out of the sidebar, following the recipes/composition pattern. Writing them as real stories rather than fenced code blocks means they are type-checked and cannot drift from the component APIs.
|
commit: |
Retitles the page from Guidelines/Forms to Components/Forms so it sits at the root of the group it describes: clicking "Forms" in the sidebar opens the overview, and expanding it lists the individual components. A docs entry whose title matches a folder path coexists with that folder's children without conflict. Files move alongside the component stories they document, so Forms.mdx and Forms.stories.tsx now sit next to Form.stories.tsx rather than in a separate guidelines directory. Their header comment calls out that these are cross-cutting form examples and not the Form component's own stories, since the singular and plural filenames are otherwise easy to confuse. The intro now frames Select, ComboBox, DateField and TimeField as the field types living elsewhere in the sidebar, rather than listing the components this page already nests.
MDX implements CommonMark, not GitHub Flavored Markdown, so table syntax in docs pages compiled to literal text — visible pipes and dashes rather than a table. Strikethrough, task lists and bare-URL autolinks fail the same way. Adds remark-gfm and passes it through addon-docs' mdxPluginOptions so GFM markdown renders as authored. Storybook styles no prose tables of its own; only the props argstable is themed. Without styling a GFM table renders with browser defaults, meaning no borders or padding, so this also adds table styles for docs prose. Those rules are scoped to direct children of the docs content container, which keeps them off tables rendered inside a Canvas by the Table component's own stories. They use --lp-* tokens rather than this file's hardcoded-hex convention because .sbdocs only exists in the preview frame, where the token CSS is loaded and [data-theme] flips the values. The compound class selector keeps specificity level with the argstable rules so the file stays free of new descending-specificity lint warnings.
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.
Summary
Adds a Forms overview page at the root of the
Components/Formsgroup — a home for written guidance, which the design system didn't have. Storybook carried API references (autodocs) and live examples (stories, recipes), but nowhere to say "here is how to compose a form."Clicking Forms in the sidebar now opens this overview; expanding it still lists the ten form components. A docs entry whose title matches a folder path coexists with that folder's children without conflict, so this needed zero config change.
Files sit alongside the stories they document —
Forms.mdxandForms.stories.tsxnext toForm.stories.tsx. Their header comment flags that these are cross-cutting form examples rather than theFormcomponent's own stories, since the singular/plural filenames are easy to confuse.The main thing this page fixes
No form component accepts
label,description,errorMessageorplaceholderas a prop. React Aria deliberatelyOmits them — they're React Spectrum props. The real pattern is slot composition:This is easy to get wrong because
AGENTS.md:59mentionsdescription/errorMessageas the naming convention to mirror if you ever add such a prop — not as a description of today's API. The page quotes the.d.tsOmitdirectly so it can't drift.Three gaps recorded rather than papered over
isRequiredsetsaria-requiredand nativerequired, butLabelhas noisRequiredawareness. The deprecated@launchpad-ui/formhadRequiredAsteriskand an(optional)suffix — neither has a modern equivalent.FieldErrorhas no icon and no live region. Styled text only; the deprecated package had an alert icon witharia-live="polite".Select/ComboBoxstories suppress the axecolor-contrastrule for[slot="description"]rather than fixing the token.These are arguably the strongest argument for the page: they're invisible today. Each deserves its own ticket.
Content guidelines are a scaffold with a named gap
Per the agreed approach, wording rules are not invented here. I searched exhaustively — the repo has no written copy standards: zero hits for "copy standard", "sentence case", "title case", "content guideline", "microcopy", "voice", "tone", "capitalization" across all markdown, MDX and code. Commit
157f6971("follow our copy standards") is a one-line story edit ("Secondary action"→"Cancel").So that section lists the questions a content designer needs to answer, plus the de facto conventions observable in our stories as raw material. It needs an owner — either someone supplies a canonical LD content-standard URL to link, or this page becomes the first written version.
Screenshots (if appropriate)
<Canvas>renders live rather than an error placeholder. Please eyeball those, or the Chromatic snapshots will.Testing approaches
Verified against the built Storybook output rather than by eye:
pnpm storybook:buildexits 0 — the MDX compilesindex.jsonshowscomponents-forms--docswithtitle: 'Components/Forms', typedocs, tagunattached-mdxComponents/Forms/*child entries with no duplicate-title conflict — verified by rebuilding after the retitle['test']withdevandautodocsstripped, exactly matching howrecipes/composition.stories.tsxindexesforms.storiesand all five story symbols, so the<Canvas of={...}>imports bundle correctlytoc:!0present in the chunk — thedocs.tocparameter does take effect on an unattached MDX page (this was the uncertain bit; nothing else in the repo sets it)pnpm typecheckandpnpm checkcleanCheckboxGroup/RadioGroupstories, since a slot mismatch throws at render (see DSYS-157)Examples are written as real stories, not fenced code blocks, so they're type-checked and can't drift from the component APIs. Given the
label/descriptionconfusion above, a wrong sample would be worse than no page.Follow-ups worth filing
Found while auditing, all out of scope here:
RadioButton.tsx:19-23has Radio's JSDoc copy-pasted ("A radio represents an individual option…") — it renders as a button.TextArea.tsx:23-27typo "mult-line".ComboBoxClearButton,CheckboxIcon,RadioIconexported with no JSDoc. Autodocs is global, so these are public today.TextArea,Radio,RadioButton,Input,FieldError.Label.module.css:13-18keys on a bareorientationattribute butForm.tsx:38emitsdata-orientation.Form's horizontaldiv[data-rac]selector also can't matchCheckbox/Radio/Switch(root<label>).ComboBox.stories.tsx:172-178uses'*not([aria-hidden]...)'— missing the:beforenot(, so it likely isn't applying.axeimport in any test. Real coverage is the addon-a11y panel plus Chromatic.Legacy/Form/*stories are untagged, so deprecated form components look like live docs — actively confusing next to a new Forms guidelines page.