Skip to content
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

Interface guidelines for forms #261

Merged
merged 38 commits into from
Aug 5, 2022
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
5cc8cac
WIP
mperrotti Jan 24, 2022
4c7222d
WIP
mperrotti Feb 24, 2022
e8b570a
Merge branch 'main' of github.com:primer/design into mp/forms-docs
mperrotti Apr 26, 2022
2a62bd5
adds interface guidelines for forms
mperrotti Apr 27, 2022
0f1bc44
Update content/ui-patterns/forms.mdx
mperrotti May 4, 2022
e06b2c6
Update content/ui-patterns/forms.mdx
mperrotti May 4, 2022
3804436
Update content/ui-patterns/forms.mdx
mperrotti May 4, 2022
a202e05
Update content/ui-patterns/forms.mdx
mperrotti May 4, 2022
3c6e364
Update content/ui-patterns/forms.mdx
mperrotti May 4, 2022
a373809
Update content/ui-patterns/forms.mdx
mperrotti May 4, 2022
32f4e6e
Update content/ui-patterns/forms.mdx
mperrotti May 4, 2022
786bdcd
Update content/ui-patterns/forms.mdx
mperrotti May 4, 2022
3a858fe
Update content/ui-patterns/forms.mdx
mperrotti May 4, 2022
cee08d2
Update content/ui-patterns/forms.mdx
mperrotti May 4, 2022
67c15b3
Update content/ui-patterns/forms.mdx
mperrotti May 4, 2022
d6e29a4
Update content/ui-patterns/forms.mdx
mperrotti May 4, 2022
62492d4
Update content/ui-patterns/forms.mdx
mperrotti May 4, 2022
91498ae
Update content/ui-patterns/forms.mdx
mperrotti May 4, 2022
5a26f08
addresses feedback from design infrastructure teammates
mperrotti May 5, 2022
8664bde
removes unnecessary heading
mperrotti May 5, 2022
d5e2d4d
updates action menu example image
mperrotti May 12, 2022
d201897
updates focus styles in supporting graphics
mperrotti May 12, 2022
3cd148e
Update content/ui-patterns/forms.mdx
yaili May 13, 2022
1333064
updates guidance about placeholder text
mperrotti May 13, 2022
a607378
Merge branch 'mp/forms-docs' of github.com:primer/design into mp/form…
mperrotti May 13, 2022
0c55099
adds guidance on error summaries, removes checkbox group validation e…
mperrotti May 17, 2022
5758eba
addresses feedback about unclear guidelines
mperrotti May 17, 2022
b4ff765
Update content/ui-patterns/forms.mdx
mperrotti May 23, 2022
9b6b785
adds guidance about form control sizing
mperrotti May 24, 2022
e1b6e2c
Merge branch 'mp/forms-docs' of github.com:primer/design into mp/form…
mperrotti May 24, 2022
8a4ad2c
shortens intro paragraph, removes guidance about hiding labels
mperrotti May 24, 2022
0d0c6c5
updates example images
mperrotti May 25, 2022
265a168
renders gifs as HTML video elements
mperrotti May 25, 2022
90544e0
adds custom video player
mperrotti May 26, 2022
4e2265b
adds aria labels to icon buttons
mperrotti May 26, 2022
32e8aad
Merge branch 'main' of github.com:primer/design into mp/forms-docs
mperrotti Jun 1, 2022
fe1aa91
Merge branch 'main' of github.com:primer/design into mp/forms-docs
mperrotti Jun 2, 2022
585268e
addresses feedback about formcontrol anatomy diagrams
mperrotti Jun 2, 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
4 changes: 4 additions & 0 deletions content/components/textInputField.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: TextInputField
status: Alpha
---
387 changes: 387 additions & 0 deletions content/ui-patterns/forms.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,387 @@
---
title: Forms
mperrotti marked this conversation as resolved.
Show resolved Hide resolved
---

import {Box, Heading, Link} from '@primer/components'

<Box sx={{fontSize: 3}} class="lead" as="p">
Forms are used to complete tasks that require data input from the user. For example: creating a new repo, configuring settings, and logging in.
</Box>

<Box sx={{fontSize: 3}} class="lead" as="p">
Primer's form design guidelines aim to minimize the effort and cognitive load required to complete a task that involves a form.
</Box>
Copy link
Contributor

Choose a reason for hiding this comment

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

@mperrotti Can we simplify this leading description and make it into a single paragraph?

Forms are used to complete tasks that require data input from the user. For example: creating a new repo, configuring settings, and logging in.

Primer's form design guidelines aim to minimize the effort and cognitive load required to complete a task that involves a form.


## Form control anatomy

![diagrams labeling the anatomy of a text field and a checkbox field](https://user-images.githubusercontent.com/2313998/168928812-fa5c9ad7-4f92-4e9d-8e6e-62eb4413985c.png)
mperrotti marked this conversation as resolved.
Show resolved Hide resolved

### Label (required)
mperrotti marked this conversation as resolved.
Show resolved Hide resolved

Labels should be descriptive, and as short as possible: ideally no more than 3 words. Labels should be written in sentence case. For example: "Repository name".
mperrotti marked this conversation as resolved.
Show resolved Hide resolved

If you're having trouble keeping label text short, consider using a [caption](#caption) to provide more context.

In rare cases, a label may be hidden when the user has enough context to understand what the input does. When a label is visually hidden, label text must still be provided for assistive technology such as screen readers. For example: a search field with an icon that is placed in the spot a user would expect to find a search field may have a visually hidden label that says "Search".
Copy link
Contributor

Choose a reason for hiding this comment

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

In rare cases, a label may be hidden

For example: a search field with an icon that is placed in the spot a user would expect to find a search field may have a visually hidden label that says "Search".

Is a search field part of a forms pattern? Search fields appear throughout dotcom, and they're not rare =).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is a search field part of a forms pattern?

It could be, but usually it isn't. I was trying to think of the most common and obvious example.

Do you (or any other reviewers) have any better examples?

Copy link
Contributor

Choose a reason for hiding this comment

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

@mperrotti I'm not sure. It's confusing to see an example about a search field while this page is specifically about [long-form] forms pattern.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point about these guidelines being for long-form forms. I think it might be best to exclude this paragraph. Visually hidden labels can be addressed in form component guidelines.


Placeholder text is never an acceptable substitute for a label because:

- The placeholder text disappears as soon as the input has a value
- Placeholder text colors are typically too light to meet the minimum color contrast ratio required for accessibility
- Screen readers do not read placeholder text as a label

### Required field indicator

When a field is required to have a value, it should be visibly marked as required. An individual checkbox or radio button cannot be marked as required.

For more information, see the [required fields](#required-fields) section.

### Input (required)

The input is what the user interacts with to set the value of the form control. You may pre-fill inputs with smart default values, but be careful about making too many assumptions about what a user wants or needs.

### Caption

A caption may be used to provide additional context about the field to help users fill in the correct data or explain how the data will be used. Caption text should be as short as possible.

Caption text may be displayed alongside a validation message, or it may be hidden if it only provides redundant information.

Caption text may be used to augment the [label](#label), but should not be redundant with the label or any other parts of the form control. If the caption feels redundant, try removing it.

<DoDontContainer>
<Do>
<img role="presentation" src="https://user-images.githubusercontent.com/2313998/166832266-c34634ec-2ade-4bf6-8401-df0bdc02b324.png" />
Copy link
Contributor

Choose a reason for hiding this comment

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

image

@mperrotti This "do" example feels quite redundant 🤔

<Caption>Use caption text that shows new information and provides helpful context</Caption>
</Do>
<Dont>
<img role="presentation" src="https://user-images.githubusercontent.com/2313998/166832267-e00f88bb-6a81-42e2-a29d-63cc58a70550.png" />
<Caption>Don’t use caption text that is redundant</Caption>
</Dont>
</DoDontContainer>

### Validation message
Copy link
Contributor

Choose a reason for hiding this comment

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

The examples using checkbox groups have some weird application of bold. Do we really want to use bold labels for every checkbox or radio button item? Are the validation messages also meant to be bold? 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These are all meant to be bold. That's how the components are currently designed.

I'd be happy to change the checkbox and radio labels from bold to regular weight in separate PCSS and PRC PRs. What do you think @vdepizzol?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the intent with the semibold label is that the styles are consistent through all form elements (so input, select etc.) But I don't feel that the validation messages should also be semibold.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The semibold error messages are kind of new: primer/react#2013

@colebemis and I think it helps the text feel more balanced with the leading icon, but I'm open to changing it back to regular weight it if it's causing an issue.

Other reviewers - please chime in if you agree with @langermank that validation text should go back to regular weight.

Copy link
Contributor

Choose a reason for hiding this comment

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

@mperrotti I'd keep it at a regular weight. Validation messages can appear multiple times to the user in the same form. The bolded font feels too heavy.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I'll update the example images and submit a PR to PRC to change the weight back to normal.


A single validation message may be displayed to provide helpful information for a user to complete their task. For example: explain why a value is invalid so they can correct it and submit the form.

An individual checkbox or radio should not have its own validation message or style.

<DoDontContainer>
<Do>
<img role="presentation" src="https://user-images.githubusercontent.com/2313998/164065196-b0146ade-eccb-4a71-b1b6-f4a82b96c115.png" />
mperrotti marked this conversation as resolved.
Show resolved Hide resolved
<Caption>Show a validation message for the group of inputs</Caption>
Copy link
Contributor

Choose a reason for hiding this comment

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

Have we considered a validation pattern where if there are multiple errors, we render a single box above the form with a list of each error- which links to each input with the issue? Its my understanding that this is the preferred method for handling multiple form errors, but perhaps that case hasn't come up for accessibility testing?

This is from the book Form Design Patterns

image from Form Design Patterns book showing an error box above a group of fields, linking to each field that is invalid

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had considered this pattern, but I tried it on a settings page and it felt like too much error text was being shown at once.

However, this pattern is useful and I think it's worth further exploration. Do you think we could explore it in a separate issue? Or should I do it as part of this PR?

Copy link
Contributor

Choose a reason for hiding this comment

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

@mperrotti have you explored this?

Copy link
Contributor

Choose a reason for hiding this comment

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

image

@mperrotti additionally, is this "Pick your top two" and "Only two selections are allowed" a good recommendation for checkboxes? It feels out of place — I could see that pattern happening for a larger number ("Pick up to 10 items"?), but two...? Feels like a weird pattern...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought I removed this example. If it's still around somewhere, I'll change it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see this is still used used for a do/don't example.

Screen Shot 2022-05-23 at 5 59 28 PM

</Do>
<Dont>
<img role="presentation" src="https://user-images.githubusercontent.com/2313998/164065199-6cfa4893-55cb-4f81-a7d6-4b6ff66339eb.png" />
<Caption>Don’t show a validation message for each input</Caption>
</Dont>
</DoDontContainer>

Information from the caption should not be repeated in the error message. Show the validation message and remove the caption. A validation message makes the field easier to spot when a user is scanning for invalid fields.

<DoDontContainer>
<Do>
<img role="presentation" src="https://user-images.githubusercontent.com/2313998/166832268-519ebea3-e989-455c-b182-58e991d78a25.png" />
<Caption>Hide a caption that is redundant with the validation message</Caption>
</Do>
<Dont>
<img role="presentation" src="https://user-images.githubusercontent.com/2313998/166832269-4756f340-c24a-41bd-8fa9-db807607c874.png" />
<Caption>Don’t show a repetitive validation message</Caption>
mperrotti marked this conversation as resolved.
Show resolved Hide resolved
</Dont>
</DoDontContainer>

For more information about form validation, see the [validation guidelines](#invalid-input).

## Input methods
mperrotti marked this conversation as resolved.
Show resolved Hide resolved
mperrotti marked this conversation as resolved.
Show resolved Hide resolved

### Open-ended text

![Text input, open-ended autocomplete text input, plain text input, textarea](https://user-images.githubusercontent.com/2313998/168104196-e0400967-a455-4513-97b0-3005d7ee3d0c.png)

Use an open-ended text field when the field does not have a list of possible values. If the input is able to suggest values, use [autocomplete](#autocomplete) to allow users to pick a value or enter their own.

### A set of selectable options

![Action menu, autocomplete input with limited options, checkbox group, radio group, select](https://user-images.githubusercontent.com/2313998/168104199-2990e43c-6204-4ef5-970c-c9babaf1196c.png)
mperrotti marked this conversation as resolved.
Show resolved Hide resolved

Show a set of selectable options when there is a finite number of possible values.

## Structure

Forms should have a structure that makes it easy for users to scan. Forms that flow vertically are easier for sighted users to scan visually.

<DoDontContainer>
<Do>
<img role="presentation" src="https://user-images.githubusercontent.com/2313998/164065202-5c3aba0b-5cef-4ef4-9339-7192a3ebf23a.png" />
Copy link
Contributor

Choose a reason for hiding this comment

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

The radio button and checkbox groups seem to have inconsistent headings and unnecessary bold text. Could we revisit these design decisions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, let's revisit. I think the checkbox and radio labels should be the same weight as body text.

@vdepizzol - could you open an issue or discussion?

<Caption>Default to vertically stacked form controls</Caption>
</Do>
<Dont>
<img role="presentation" src="https://user-images.githubusercontent.com/2313998/164065205-4000430d-2216-4954-a367-86fbd0254cc3.png" />
<Caption>Don’t lay out forms that flow into columns just to reduce the vertical space used by the form</Caption>
</Dont>
</DoDontContainer>

### Order of form controls

Form fields should be in a predictable order that flows intuitively.

To achieve an intuitive flow:
- Order fields by their relative level of importance
- Keep related fields near each other
- When possible, keep inputs that require keyboard input near each other so that users who use a mouse don't have to switch back and forth between clicking and typing

### Grouping form controls

<Box mb={3} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<img
width="456"
alt="visually grouped of related inputs"
Copy link
Contributor

Choose a reason for hiding this comment

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

image

I'm not sure I understand what this image is telling here —

  • some headings are inside groups, some are not.
  • Is "grouping" specifically referring to horizontal placement?
  • Does Group 1.1 inside Group 1 specific which width it should follow?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

some headings are inside groups, some are not.

I think you're referring to the labels in the first three form controls as "headings". None of these are headings, they are input labels.


Is "grouping" specifically referring to horizontal placement?

Horizontal placement is just one of the ways you can visually group two or more inputs.


Does Group 1.1 inside Group 1 specific which width it should follow?

I'm not sure I understand this question.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I updated the image, but it's still a little "squished" because of the annotations.

src="https://user-images.githubusercontent.com/2313998/166850298-4117b815-ffa1-4f46-9ccd-dbecd1d0db71.png"
/>
<Box as="p" mt="0">When there is a collection of closely related fields, they should be labeled and visually grouped together. For example: putting form controls closer together.</Box>
</Box>

### Progressively disclosed form controls

<Box mb={3} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<img
mperrotti marked this conversation as resolved.
Show resolved Hide resolved
width="456"
alt="form section where controls are hidden until the feature is enabled"
src="https://user-images.githubusercontent.com/2313998/166850300-d3128b88-0ca4-4356-a687-04795e3103bb.png"
/>
<Box as="p" mt="0">To keep forms concise, you may choose to hide or show form controls based on selections the user has made.</Box>
</Box>

#### Nested form controls

Sometimes, progressively disclosed form controls can be visually nested under a parent form control. A common pattern is to use a checkbox or radio “checked” state to decide whether to show a related form control.

<Box mb={3} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<img
width="456"
alt="Primary discipline radio buttons, selected 'Other' option reveals a text input"
src="https://user-images.githubusercontent.com/2313998/164065214-0c0bc39f-52e5-4534-9c69-a1f6e4566fa9.png"
/>
<Box as="p" mt="0">If the parent form control provides sufficient visual context, you may visually hide the label. However, you must specify text for a visually hidden label that is accessible to screen readers.</Box>
</Box>

<Box mb={3} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<div>
<img
alt="Checkbox that progressively discloses a dropdown with an internal label"
Copy link

Choose a reason for hiding this comment

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

This is the first time I'm being introduced to the internal label concept, I wonder if this is something we should highlight above, on the Labels section?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is only something we'd do with an Action menu component, so that information will go in that component's guidelines.

src="https://user-images.githubusercontent.com/2313998/164065216-a2702413-5e84-4ec0-b990-b72261df0fb1.png"
/>
<img
alt="Checkbox that progressively discloses a labeled select input"
src="https://user-images.githubusercontent.com/2313998/166850721-7a5bf061-353d-4cdc-88b6-0d6d81087cb3.png"
/>
</div>
<Box as="p" mt="0">If the parent form control does not provide sufficient context, a visible label should be shown. Make sure the label of the nested form control doesn’t clash with the label of its parent form control.</Box>
</Box>

See [progressive disclosure](/ui-patterns/progressive-disclosure) for more information.

## Validation

Use Primer instead of browser-native validation UI. Browser-native validation messages are not accessible to screen readers, and they visually clash with Primer styles.

### Validation statuses

<Box mb={3} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<Box flexGrow={1} flexBasis="0">
<img
alt="input with forbidden characters"
src="https://user-images.githubusercontent.com/2313998/164065220-30c25ca4-827f-4327-95f4-9be888272813.png"
/>
<Box as="p" mt="0"><strong>Error messages:</strong> An invalid field should always have a message explaining why the value does not pass validation. The message should explain why the value is invalid, and unblock users from completing their task by guiding them to a valid value.</Box>
</Box>

<Box flexGrow={1} flexBasis="0">
<img
alt="valid repo name success"
src="https://user-images.githubusercontent.com/2313998/164065221-7e4f6a21-e9a7-465b-9a86-83c61533fdec.png"
/>
<Box as="p" mt="0"><strong>Success messages:</strong> A success message may be used when a user might need extra assurance that the field's value is valid. For example: when creating a repository name, it’s nice to be assured that the name is available and valid.</Box>
</Box>
</Box>

### Validation on submit

The default behavior of the web is to perform validation when the user attempts to submit the form. This lets the user flow quickly through the form without interruption.

When the form fails validation, guide the user to the invalid inputs:
- If the form has 3 or more errors, you may show an [interactive summary of errors](#interactive-summary-of-errors)
- If an interactive summary of errors is not shown, the first invalid input should be focused and scrolled into the viewport

After a form has been submitted and failed validation, you may switch to inline validation to provide quicker feedback.

#### Interactive summary of errors

<Box mb={3} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<img
width="456"
alt="a form for biographical information that has three invalid inputs"
src="https://user-images.githubusercontent.com/2313998/168926352-c30563ab-3782-4b86-8d21-1ad6dcfa09e3.png"
/>
<div>
<Box as="p" mt="0">In a <a href="/ui-patterns/messaging#flash-alerts">flash alert</a> at the top of the form, list the invalid inputs as anchor links. When the link is activated, place focus in it's corresponding input.</Box>
<Box as="p" mt="0">When the flash alert appears, it should be focused.</Box>
</div>
</Box>

### Inline validation
Copy link
Contributor

Choose a reason for hiding this comment

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

@mperrotti I'm finding it quite confusing to see these 3 gifs next to each other. There's a lot going on 😬 . I'm not sure I have any recommendations for now, but it's something we should pay more attention...

Screen.Recording.2022-05-23.at.10.49.45.mov

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right - all this motion is overwhelming. I'm going to try converting these to <video> elements that can be played or paused individually.


<Note variant="warning">
Inline validation offers immediate feedback, but be sure to consider the following drawbacks.

<ul>
<li>There is a negative impact on perceived performance when validating server-side.</li>
<li>When a screen reader user moves focus from the invalid input to the next form control, they will be interrupted by the validation message of the previous form control.</li>
</ul>
</Note>

<Box mb={3} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<img
width="456"
alt="screen recording of validation being performed after the user changes and blurs"
src="https://user-images.githubusercontent.com/2313998/164065853-fd7ef55a-7082-4b0d-aa6b-2b25af4c664b.gif"
/>
<Box as="p" mt="0">If the form control is in a valid state, validation should be performed until after the user has made a change to the input <strong>and has removed focus from the input</strong>.</Box>
</Box>

<Box mb={3} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<img
width="456"
alt="screen recording of validation being performed as the user tries to fix an invalid input"
src="https://user-images.githubusercontent.com/2313998/164065860-25e23fa0-e22a-435d-adbd-5666a9fd7890.gif"
/>
<Box as="p" mt="0">Don't attempt to validate an input before the user is done with it. Validation may be performed as the user is typing or making their selection, but only <strong>after the first time the input has been validated</strong> and the <strong>input is in an invalid state</strong>. This gives the user early positive feedback by removing the error if the user makes a change that fixes it.</Box>
</Box>

<Box mb={3} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<img
width="456"
alt="screen recording of valid repo name input showing loading indicator after blur"
src="https://user-images.githubusercontent.com/2313998/164065857-573ca6db-f2c7-49ac-a3cf-bf479a40973d.gif"
/>
<Box as="p" mt="0">If the form control’s validation is likely to take more than 1 second, show a loading indicator.</Box>
Copy link
Contributor

Choose a reason for hiding this comment

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

If the form control’s validation is likely to take more than 1 second

Is this the right metric to decide whether to display a loading indicator? What if the process is known as a quick one but the user is on a slow connection?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, if we're extending the height of the input control based on an async request that may take long to process, how do we avoid the content to reflow unexpectedly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this the right metric to decide whether to display a loading indicator? What if the process is known as a quick one but the user is on a slow connection?

It shouldn't matter what connection the user is on. This is a detail that would be handled in the implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also, if we're extending the height of the input control based on an async request that may take long to process, how do we avoid the content to reflow unexpectedly?

That's a great question, and I have no idea how we'd avoid reflow in that case.

Copy link
Contributor

Choose a reason for hiding this comment

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

Is this the right metric to decide whether to display a loading indicator? What if the process is known as a quick one but the user is on a slow connection?

It shouldn't matter what connection the user is on. This is a detail that would be handled in the implementation.

@mperrotti if there's a server request, wouldn't it make more sense to show the loading spinner regardless? I don't understand how that'd be handled in the implementation 🤔 .

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if there's a server request, wouldn't it make more sense to show the loading spinner regardless?

@vdepizzol - I was trying to avoid showing too many loading indicators because they could make the app feel slower. If we wait 1 second, we're still giving the user feedback that something is happening, but only if it's something that's making the user wait a noticeable amount of time.

Does that make sense?

</Box>

## Submission

Forms should follow consistent patterns for [submitting and saving data](/ui-patterns/saving).

## Related components

<Box mb={4} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<img
mperrotti marked this conversation as resolved.
Show resolved Hide resolved
width="456"
role="presentation"
src="https://user-images.githubusercontent.com/293280/123881067-cdbaea00-d8f8-11eb-98e4-e57c64489308.png"
/>
<div>
<Heading fontSize={3}>Action menu with selection</Heading>
<p>If the parent form control provides sufficient visual context, you may visually hide the label. However, you must specify text for a visually hidden label that is accessible to screen readers.</p>
<a href="https://primer.style/react/ActionMenu#with-selection">Primer React implementation</a>
</div>
</Box>

<Box mb={4} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<img
role="presentation"
width="456"
src="https://user-images.githubusercontent.com/2313998/168104391-d83bef5e-a628-4788-b1c2-6d72980fa508.png"
/>
<div>
<Heading fontSize={3}>Autocomplete</Heading>
<p>
An autocomplete input renders a text input that allows a user to quickly filter through a list of options to pick one or more values.
</p>
<a href="https://primer.style/react/Autocomplete">Primer React implementation</a>
</div>
</Box>

<Box mb={4} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<img
role="presentation"
width="456"
src="https://user-images.githubusercontent.com/2313998/166846801-91a03e2d-aedb-4ba3-b8ea-c7abcb7eadd6.png"
/>
<div>
<Heading fontSize={3}>Checkbox group</Heading>
<p>
A set of checkboxes to let users make one or more selections from a short list of options
</p>
<a href="https://primer.style/react/CheckboxGroup">Primer React implementation</a>
</div>
</Box>

<Box mb={4} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<img
role="presentation"
width="456"
src="https://user-images.githubusercontent.com/2313998/166846802-7d3a0563-d853-4d7b-b26f-0bb4e8c0d3ad.png"
/>
<div>
<Heading fontSize={3}>Form control</Heading>
<p>
A form control renders a labelled input and, optionally, associated validation text and/or hint text.
mperrotti marked this conversation as resolved.
Show resolved Hide resolved
</p>
<a href="https://primer.style/react/FormControl">Primer React implementation</a>
</div>
</Box>

<Box mb={4} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<img
role="presentation"
width="456"
src="https://user-images.githubusercontent.com/2313998/166846804-0b629054-9e56-42aa-b565-c7c82d63f52c.png"
/>
<div>
<Heading fontSize={3}>Radio group</Heading>
<p>
A set of radio inputs to let users make a single selection from a short list of options
</p>
<a href="https://primer.style/react/RadioGroup">Primer React implementation</a>
</div>
</Box>

<Box mb={4} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<img
role="presentation"
width="456"
src="https://user-images.githubusercontent.com/2313998/168104392-cc13297a-1b32-4a80-83aa-5dc569085ebc.png"
/>
<div>
<Heading fontSize={3}>Select dropdown</Heading>
<p>
A select input may be used when a user needs to select one option from a long list
</p>
<a href="https://primer.style/react/Select">Primer React implementation</a>
</div>
</Box>

<Box mb={4} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<img
role="presentation"
width="456"
src="https://user-images.githubusercontent.com/2313998/166833712-78f78a74-6d39-40d5-9cce-13e6e8ab691c.png"
/>
<div>
<Heading fontSize={3}>Textarea</Heading>
<p>
A text area is used to put multiple lines of text in an input
</p>
<a href="https://primer.style/react/Textarea">Primer React implementation</a>
</div>
</Box>

<Box mb={4} display="flex" alignItems="flex-start" flexDirection={["column", "column", "column", "column", "row"]} sx={{gap: 3}}>
<img role="presentation" width="456" src="https://user-images.githubusercontent.com/2313998/166846809-d05cddd2-54c3-41a5-801f-d4d186dfe903.png" />
<div>
<Heading fontSize={3}>Text input</Heading>
<p>
A text input is used to set a value that is a single line of text. See the list of <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types">types in the MDN docs</a>.
</p>
<a href="https://primer.style/react/Textarea">Primer React implementation</a>
</div>
</Box>
Loading