Skip to content

Correct and improve Storybook and docs for form controls #2143

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
Jul 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
30433df
updates checkbox props tables, storybook stories, and storybook controls
mperrotti Jun 18, 2022
97ed7dc
updates Radio props table, Storybook stories, and Storybook controls
mperrotti Jun 20, 2022
c7651e3
updates FormControl Storybook stories, and Storybook controls
mperrotti Jun 20, 2022
37a0af4
Merge branch 'main' of github.com:primer/react into mp/fix-form-docs-…
mperrotti Jun 21, 2022
62aa753
updates TextInput and TextInputWithWrapper props tables, Storybook st…
mperrotti Jun 21, 2022
b1b6b9e
updates Select stories
mperrotti Jun 21, 2022
44c7233
fixes more issues with Select stories and prop docs
mperrotti Jun 21, 2022
5721897
updates Textarea prop tables, Storybook stories, and Storybook controls
mperrotti Jun 21, 2022
7bebbda
updates CheckboxGroup and RadioGroup Storybook stories, and Storybook…
mperrotti Jun 22, 2022
d2faf40
updates Autocomplete Storybook stories, and Storybook controls
mperrotti Jun 22, 2022
f34efe0
fixes 'size' control in TextInput stories
mperrotti Jun 22, 2022
d71d421
fixes a11y issues with Autocomplete examples
mperrotti Jun 23, 2022
a41637b
updates input stories to use the FormControl component and controls, …
mperrotti Jun 23, 2022
9de5485
Merge branch 'main' of github.com:primer/react into mp/fix-form-docs-…
mperrotti Jun 23, 2022
4eac20c
updates tests
mperrotti Jun 23, 2022
7d11bf0
adds changeset
mperrotti Jun 23, 2022
4ec08e9
fix linting issue
mperrotti Jun 23, 2022
99e0775
updates after merging from main
mperrotti Jun 23, 2022
ce43782
Merge branch 'main' into mp/fix-form-docs-storybook-and-mdx
mperrotti Jun 24, 2022
78c71f9
Merge branch 'main' of github.com:primer/react into mp/fix-form-docs-…
mperrotti Jun 24, 2022
2cc71f5
Merge branch 'mp/fix-form-docs-storybook-and-mdx' of github.com:prime…
mperrotti Jun 29, 2022
635ea7e
Merge branch 'main' of github.com:primer/react into mp/fix-form-docs-…
mperrotti Jun 29, 2022
f40050d
Merge branch 'main' into mp/fix-form-docs-storybook-and-mdx
mperrotti Jul 18, 2022
dc0e139
Merge branch 'main' of github.com:primer/react into mp/fix-form-docs-…
mperrotti Jul 20, 2022
2c034c9
excludes story-helpers.tsx from build
mperrotti Jul 20, 2022
76eded2
fixes regression in CheckboxGroup and RadioGroup fixture stories
mperrotti Jul 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tough-coats-allow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@primer/react': patch
---

Fixes bugs in form components discovered while fixing/improving Storybook and docs.
Copy link
Member

Choose a reason for hiding this comment

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

Are there any details which we should surface in the changelog?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nothing major - it was mostly minor visual tweaks.

However, I should mention that FormControl.Label can now accept an id prop.

41 changes: 23 additions & 18 deletions docs/content/Autocomplete.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: Autocomplete
status: Alpha
description: Used to render a text input that allows a user to quickly filter through a list of options to pick one or more values.
source: https://github.com/primer/react/tree/main/src/Autocomplete
storybook: '/react/storybook?path=/story/forms-autocomplete--single-select'
storybook: '/react/storybook?path=/story/form-controls-autocomplete--default'
---

import {Autocomplete} from '@primer/react'
Expand Down Expand Up @@ -56,7 +56,7 @@ A function may be passed to the `filterFn` prop if this default filtering behavi

```jsx live
<FormControl>
<FormControl.Label>Pick a branch</FormControl.Label>
<FormControl.Label id="autocompleteLabel-basic">Pick a branch</FormControl.Label>
<Autocomplete>
<Autocomplete.Input />
<Autocomplete.Overlay>
Expand All @@ -72,6 +72,7 @@ A function may be passed to the `filterFn` prop if this default filtering behavi
{text: 'visual-design-tweaks', id: 7}
]}
selectedItemIds={[]}
aria-labelledby="autocompleteLabel-basic"
/>
</Autocomplete.Overlay>
</Autocomplete>
Expand Down Expand Up @@ -114,7 +115,7 @@ const CustomTextInputExample = () => {

return (
<FormControl>
<FormControl.Label>Pick options</FormControl.Label>
<FormControl.Label id="autocompleteLabel-customInput">Pick options</FormControl.Label>
<Autocomplete>
<Autocomplete.Input as={TextInputWithTokens} tokens={tokens} onTokenRemove={onTokenRemove} />
<Autocomplete.Overlay>
Expand All @@ -132,6 +133,7 @@ const CustomTextInputExample = () => {
selectedItemIds={selectedItemIds}
onSelectedChange={onSelectedChange}
selectionVariant="multiple"
aria-labelledby="autocompleteLabel-customInput"
/>
</Autocomplete.Overlay>
</Autocomplete>
Expand All @@ -146,7 +148,7 @@ render(<CustomTextInputExample />)

```jsx live
<FormControl>
<FormControl.Label>Pick a branch</FormControl.Label>
<FormControl.Label id="autocompleteLabel-withoutOverlay">Pick a branch</FormControl.Label>
<Autocomplete>
<Autocomplete.Input />
<Autocomplete.Menu
Expand All @@ -161,6 +163,7 @@ render(<CustomTextInputExample />)
{text: 'visual-design-tweaks', id: 7}
]}
selectedItemIds={[]}
aria-labelledby="autocompleteLabel-withoutOverlay"
/>
</Autocomplete>
</FormControl>
Expand Down Expand Up @@ -221,7 +224,7 @@ const CustomRenderedItemExample = () => {

return (
<FormControl>
<FormControl.Label>Pick labels</FormControl.Label>
<FormControl.Label id="autocompleteLabel-customRenderedItem">Pick labels</FormControl.Label>
<Autocomplete>
<Autocomplete.Input
as={TextInputWithTokens}
Expand All @@ -248,7 +251,7 @@ const CustomRenderedItemExample = () => {
selectedItemIds={selectedItemIds}
onSelectedChange={onSelectedChange}
selectionVariant="multiple"
aria-labelledby="autocompleteLabel-issueLabels"
aria-labelledby="autocompleteLabel-customRenderedItem"
/>
</Autocomplete.Overlay>
</Autocomplete>
Expand Down Expand Up @@ -279,9 +282,9 @@ const CustomSortAfterMenuClose = () => {

return (
<FormControl>
<FormControl.Label>Pick branches</FormControl.Label>
<FormControl.Label id="autocompleteLabel-sortAfterClose">Pick branches</FormControl.Label>
<Autocomplete>
<Autocomplete.Input id="autocompleteInput-sortAfterClose" />
<Autocomplete.Input />
<Autocomplete.Overlay>
<Autocomplete.Menu
items={[
Expand Down Expand Up @@ -323,9 +326,9 @@ const CustomSearchFilter = () => {

return (
<FormControl>
<FormControl.Label>Pick a branch</FormControl.Label>
<FormControl.Label id="autocompleteLabel-customFilter">Pick a branch</FormControl.Label>
<Autocomplete>
<Autocomplete.Input id="autocompleteInput-customFilter" onChange={handleChange} />
<Autocomplete.Input onChange={handleChange} />
<Autocomplete.Overlay>
<Autocomplete.Menu
items={[
Expand Down Expand Up @@ -382,7 +385,9 @@ const InOverlayWithCustomScrollContainerRef = () => {
)}
>
<FormControl>
<FormControl.Label visuallyHidden>Pick branches</FormControl.Label>
<FormControl.Label visuallyHidden id="autocompleteLabel-withCustomScrollRef">
Pick branches
</FormControl.Label>
<Autocomplete>
<Box display="flex" flexDirection="column" height="100%">
<Box
Expand Down Expand Up @@ -424,7 +429,7 @@ const InOverlayWithCustomScrollContainerRef = () => {
]}
selectedItemIds={[]}
customScrollContainerRef={scrollContainerRef}
aria-labelledby="autocompleteLabel"
aria-labelledby="autocompleteLabel-withCustomScrollRef"
/>
</Box>
</Box>
Expand Down Expand Up @@ -465,14 +470,14 @@ const MultiSelect = () => {
return (
<Box display="flex" flexDirection="column" sx={{gap: '1em'}}>
<FormControl>
<FormControl.Label>Pick branches</FormControl.Label>
<FormControl.Label id="autocompleteLabel-multiselect">Pick branches</FormControl.Label>
<Autocomplete>
<Autocomplete.Input id="autocompleteInput" />
<Autocomplete.Input />
<Autocomplete.Overlay>
<Autocomplete.Menu
items={items}
selectedItemIds={selectedItemIds}
aria-labelledby="autocompleteLabel"
aria-labelledby="autocompleteLabel-multiselect"
onSelectedChange={onSelectedChange}
selectionVariant="multiple"
/>
Expand Down Expand Up @@ -535,9 +540,9 @@ const MultiSelectAddNewItem = () => {
return (
<Box display="flex" flexDirection="column" sx={{gap: '1em'}}>
<FormControl>
<FormControl.Label>Pick or add branches</FormControl.Label>
<FormControl.Label id="autocompleteLabel-addItem">Pick or add branches</FormControl.Label>
<Autocomplete>
<Autocomplete.Input onChange={handleChange} id="autocompleteInput" />
<Autocomplete.Input onChange={handleChange} />
<Autocomplete.Overlay>
<Autocomplete.Menu
addNewItem={
Expand All @@ -559,7 +564,7 @@ const MultiSelectAddNewItem = () => {
selectedItemIds={selectedItemIds}
onSelectedChange={onSelectedChange}
selectionVariant="multiple"
aria-labelledby="autocompleteLabel"
aria-labelledby="autocompleteLabel-addItem"
/>
</Autocomplete.Overlay>
</Autocomplete>
Expand Down
34 changes: 27 additions & 7 deletions docs/content/Checkbox.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Checkbox
description: Use checkboxes to toggle between checked and unchecked states in a list or as a standalone form field
status: Alpha
source: https://github.com/primer/react/blob/main/src/Checkbox.tsx
storybook: '/react/storybook?path=/story/forms-checkbox--default'
storybook: '/react/storybook?path=/story/form-controls-checkbox--default'
componentId: checkbox
---

Expand Down Expand Up @@ -87,15 +87,10 @@ An `indeterminate` checkbox state should be used if the input value is neither t
type="boolean"
description="Checks the input by default in uncontrolled mode"
/>
<PropsTableRow
name="onChange"
type="(event: React.ChangeEvent) => void"
description="A callback function that is triggered when the checked state has been changed"
/>
<PropsTableRow
name="disabled"
type="boolean"
description="Modifies the native disabled state of the native checkbox"
description="Modifies the native disabled state of the native checkbox"
/>
<PropsTableRow
name="indeterminate"
Expand All @@ -111,6 +106,31 @@ An `indeterminate` checkbox state should be used if the input value is neither t
</>
}
/>
<PropsTableRow
name="onChange"
type="(event: React.ChangeEvent) => void"
description="A callback function that is triggered when the checked state has been changed"
/>
<PropsTableRow
name="validationStatus"
type="'error' | 'success' | 'warning'"
description={
<>
Only used to inform ARIA attributes.<br />
Individual checkboxes do not have validation styles.
</>
}
/>
<PropsTableRow
name="value"
type="string"
description={
<>
A unique value that is never shown to the user.<br />
Used during form submission and to identify which checkbox inputs are selected.
</>
}
/>
<PropsTableBasePropRows
elementType="input"
refType="HTMLInputElement"
Expand Down
2 changes: 1 addition & 1 deletion docs/content/FormControl.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: FormControl
status: Alpha
description: Renders a labelled input and, optionally, associated validation text and/or hint text.
source: https://github.com/primer/react/blob/main/src/FormControl/FormControl.tsx
storybook: '/react/storybook?path=/story/forms-inputfield--text-input-field'
storybook: '/react/storybook?path=/story/forms-form-controls-text-input--default'
---

import {
Expand Down
4 changes: 2 additions & 2 deletions docs/content/Radio.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: Radio
description: Use radios when a user needs to select one option from a list
status: Alpha
source: https://github.com/primer/react/blob/main/src/Radio.tsx
storybook: '/react/storybook?path=/story/forms-radio-button--default'
storybook: '/react/storybook?path=/story/forms-form-controls-radio--default'
---

## Examples
Expand Down Expand Up @@ -62,7 +62,7 @@ If you're not building something custom, you should use the [ChoiceFieldset](/Ch

<PropsTable>
<PropsTableRow name="value" type="string" required description="A unique value that is never shown to the user" />
<PropsTableRow name="name" type="string" required description="Required for grouping multiple radios" />
<PropsTableRow name="name" type="string" description="Required for grouping multiple radios" />
<PropsTableRow name="checked" type="boolean" description="Modifies true/false value of the native radio" />
<PropsTableRow name="defaultChecked" type="boolean" description="Selects the radio by default in uncontrolled mode" />
<PropsTableRow
Expand Down
14 changes: 11 additions & 3 deletions docs/content/Select.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: Select
description: Use a select input when a user needs to select one option from a long list
status: Alpha
source: https://github.com/primer/react/blob/main/src/Select.tsx
storybook: '/react/storybook?path=/story/forms-select--default'
storybook: '/react/storybook?path=/story/forms-form-controls-select--default'
---

import {Select, Text} from '@primer/react'
Expand Down Expand Up @@ -66,20 +66,28 @@ import {Select, Text} from '@primer/react'
name="block"
type="boolean"
defaultValue="false"
description={<>Creates a full width input element</>}
description="Creates a full width input element"
/>
<PropsTableRow
name="contrast"
type="boolean"
defaultValue="false"
description="Changes background color to a higher contrast color"
/>
<PropsTableRow
name="placeholder"
type="string"
description={<>
Placeholder text to show when no option is selected. <br />
This option is hidden from the dropdown menu when the 'required' prop is set
</>}
/>
<PropsTableRow
name="size"
type="'small' | 'medium' | 'large'"
description="Creates a smaller or larger input than the default."
/>
<PropsTableRow name="validationStatus" type="'warning' | 'error'" description="Style the input to match the status" />
<PropsTableRow name="validationStatus" type="'error' | 'success' | 'warning'" description="Style the input to match the status" />
<PropsTablePassthroughPropsRow
elementName="select"
passthroughPropsLink={
Expand Down
1 change: 1 addition & 0 deletions docs/content/TextInput.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ componentId: text_input
title: TextInput
status: Alpha
source: https://github.com/primer/react/blob/main/src/TextInput.tsx
storybook: '/react/storybook?path=/story/forms-form-controls-text-input--default'
---

TextInput is a form component to add default styling to the native text input.
Expand Down
8 changes: 7 additions & 1 deletion docs/content/TextInputWithTokens.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: TextInputWithTokens
status: Alpha
description: Used to show multiple values in one field
source: https://github.com/primer/react/tree/main/src/TextInputWithTokens.tsx
storybook: '/react/storybook?path=/story/forms-text-input-with-tokens--default'
storybook: '/react/storybook?path=/story/forms-form-controls-text-input-with-tokens--default'
---

import {TextInputWithTokens} from '@primer/react'
Expand Down Expand Up @@ -439,6 +439,11 @@ render(<WithIconAndLoadingIndicator />)
type="number"
description="The number of tokens to display before truncating"
/>
<PropsTablePassthroughPropsRow
elementName="TextInput"
isPolymorphic
passthroughPropsLink={<Link href="/react/TextInput">TextInput docs</Link>}
/>
</PropsTable>

### Adding and removing tokens
Expand All @@ -464,6 +469,7 @@ There is no function that gets called to "add" a token, so the user needs to be
fullTestCoverage: true,
usedInProduction: false,
usageExamplesDocumented: true,
hasStorybookStories: true,
designReviewed: false,
a11yReviewed: false,
stableApi: false,
Expand Down
11 changes: 7 additions & 4 deletions docs/content/Textarea.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: Textarea
description: Use Textarea for multi-line text input form fields
status: Alpha
source: https://github.com/primer/react/blob/main/src/Textarea.tsx
storybook: /react/storybook?path=/story/forms-textarea--default
storybook: '/react/storybook?path=/story/forms-form-controls--textarea-story'
---

import {Textarea} from '@primer/react'
Expand Down Expand Up @@ -158,10 +158,13 @@ By default, `Textarea` can be resized by the user vertically and horizontally. R
elementType="textarea"
refType="HTMLTextAreaElement"
/>
<PropsTablePassthroughPropsRow
elementName="textarea"
<PropsTableBasePropRows
elementType="input"
refType="HTMLTextareaElement"
passthroughPropsLink={
<Link href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#attributes">MDN</Link>
<Link href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea#attributes">
MDN
</Link>
}
/>

Expand Down
3 changes: 1 addition & 2 deletions src/Autocomplete/AutocompleteMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,12 @@ function getItemById<T extends AutocompleteMenuItem>(itemId: string | number, it
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type AutocompleteItemProps<T = Record<string, any>> = AutocompleteMenuItem & {metadata?: T}

// TODO: we should make `aria-labelledby` required for a11y
export type AutocompleteMenuInternalProps<T extends AutocompleteItemProps> = {
/**
* A menu item that is used to allow users make a selection that is not available in the array passed to the `items` prop.
* This menu item gets appended to the end of the list of options.
*/
// TODO: rethink this part of the component API. this is kind of weird and confusing to use
// TODO: rethink `addNewItem` prop name
addNewItem?: Omit<T, 'onAction' | 'leadingVisual' | 'id'> & {
handleAddItem: (item: Omit<T, 'onAction' | 'leadingVisual'>) => void
}
Expand Down
2 changes: 1 addition & 1 deletion src/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export type CheckboxProps = {
*/
required?: boolean
/**
* Indicates whether the checkbox validation state
* Only used to inform ARIA attributes. Individual checkboxes do not have validation styles.
*/
validationStatus?: FormValidationStatus
/**
Expand Down
Loading