Browse Source
* updated sort order
* Update preview.tsx
* Create avatar.mdx
Added avatar documentation based on Figma docs
* Added badge docs
* fixed typos
* added breadcrumb docs
* Added callout docs
* added color password docs
* Added dialog docs
* fixed typo
* Updated Dialogs docs
Added a dialogs.mdx page for general docs that apply to both main Dialogs and Simple Dialogs.
Updated the sub-docs pages
* Update simple-dialog.mdx
* Added documentation from Figma to Forms docs
* Create icon-button.mdx
* added link docs
* Added menu docs
* Added progress indicator docs
* Updated table docs
* Added tab docs
* Added toggle group docs
* Revert "Update preview.tsx"
This reverts commit 4671d9726a.
* added docs for appA11yTitle
* Fixed typos
* Update libs/components/src/link/link.mdx
Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com>
* Update libs/components/src/menu/menu.mdx
Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com>
* Addressed feedback
* Addressed feedback on callout, menu, and progress
* moved stories mdx files to proper location
* Addressed feedback on dialogs.mdx
* Update libs/components/src/tabs/tabs.mdx
Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com>
* Addressed feedback on Tabs
* ran prettier
* Fixed title formatting
* ran prettier
* Update libs/components/src/dialog/dialogs.mdx
Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com>
* ran prettier
---------
Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com>
pull/5698/head
21 changed files with 936 additions and 79 deletions
@ -0,0 +1,67 @@
@@ -0,0 +1,67 @@
|
||||
import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; |
||||
|
||||
import * as stories from "./avatar.stories"; |
||||
|
||||
<Meta of={stories} /> |
||||
|
||||
# Avatar |
||||
|
||||
Avatars display a unique color that helps a user visually recognize their logged in account. |
||||
|
||||
A variance in color across the avatar component is important as it is used in Account Switching as a |
||||
visual indicator to recognize which of a personal or work account a user is logged into. |
||||
|
||||
<Primary /> |
||||
<Controls /> |
||||
|
||||
## Size |
||||
|
||||
### Large: 64px |
||||
|
||||
<Story of={stories.Large} /> |
||||
|
||||
### Default: 48px |
||||
|
||||
<Story of={stories.Default} /> |
||||
|
||||
### Small 28px |
||||
|
||||
<Story of={stories.Small} /> |
||||
|
||||
## Background color |
||||
|
||||
The Background color can be set 3 ways. The color is generated using the following order of |
||||
priority: |
||||
|
||||
- Color |
||||
- ID |
||||
- Text, usually set to the user's Name field |
||||
|
||||
<Story of={stories.ColorByText} /> |
||||
Use the user 'ID' field if `Name` is not defined. |
||||
<Story of={stories.ColorByID} /> |
||||
|
||||
## Outline |
||||
|
||||
If the avatar is displayed on one of the theme's `background` color variables or is interactive, |
||||
display the avatar with a 1 pixel `secondary-500` border to meet WCAG AA graphic contrast guidelines |
||||
for interactive elements. |
||||
|
||||
<Story of={stories.Border} /> |
||||
|
||||
## Avatar as a button |
||||
|
||||
The Avatar can be used as a button. |
||||
|
||||
Typically this is only in the navigation on client apps where account switching is used and in the |
||||
web app for the account menu indicator. |
||||
|
||||
When the avatar is used as a button, the following states should be used: |
||||
|
||||
`TODO:` [Jira add stories](https://bitwarden.atlassian.net/browse/CL-101) for button avatars. |
||||
[See Figma](https://www.figma.com/file/Zt3YSeb6E6lebAffrNLa0h/Tailwind-Component-Library?type=design&node-id=9730-31746&mode=design&t=IjDIHDb6FZl6bUQW-4) |
||||
|
||||
## Accessibility |
||||
|
||||
Avatar background color should have 3.1:1 contrast with it’s background; or include the |
||||
`secondary-500` border Avatar text should have 4.5:1 contrast with the avatar background color |
||||
@ -0,0 +1,67 @@
@@ -0,0 +1,67 @@
|
||||
import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; |
||||
|
||||
import * as stories from "./badge.stories"; |
||||
|
||||
<Meta of={stories} /> |
||||
|
||||
# Badge |
||||
|
||||
The Badge directive can be used on a `<span>` (non clickable events), or an `<a>` or `<button>` tag |
||||
for interactive events. The Focus and Hover states only apply to badges used for interactive events. |
||||
|
||||
Typically Badges are only used with text set to `text-xs`. If additional sizes are needed, the |
||||
component configurations may be reviewed and adjusted. |
||||
|
||||
<Primary /> |
||||
<Controls /> |
||||
|
||||
## Styles |
||||
|
||||
### Primary |
||||
|
||||
The primary badge is used to indicate an active status (example: device management page) or provide |
||||
additional information (example: type of emergency access granted). |
||||
|
||||
<Story of={stories.Primary} /> |
||||
|
||||
### Secondary |
||||
|
||||
The secondary badge style is typically is a default badge style. It is often used to indicate |
||||
neutral information. |
||||
|
||||
<Story of={stories.Secondary} /> |
||||
|
||||
### Success |
||||
|
||||
The success badge is used to indicate a positive status, OR to indicate a feature requires a Premium |
||||
subscription. See [Premium Badge](?path=/docs/web-premium-badge--docs) |
||||
|
||||
<Story of={stories.Success} /> |
||||
|
||||
### Danger |
||||
|
||||
The danger badge is used to indicate a negative status. |
||||
|
||||
<Story of={stories.Danger} /> |
||||
|
||||
### Warning |
||||
|
||||
The warning badge is used to indicate a status waiting on an additional action from the active user. |
||||
|
||||
<Story of={stories.Warning} /> |
||||
|
||||
### Info |
||||
|
||||
The info badge is used to indicate a low emphasis informative information. |
||||
|
||||
<Story of={stories.Info} /> |
||||
|
||||
## Badges as counters |
||||
|
||||
Badges can be used as part of links or buttons to provide a counter. See the |
||||
[Toggle Group](?path=/docs/component-library-toggle-group--docs) component. |
||||
|
||||
## Accessibility |
||||
|
||||
Be sure to use the correct html tag based on the purpose or function of the badge. Follow color WCAG |
||||
color contrast guidelines for small text. |
||||
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; |
||||
|
||||
import * as stories from "./breadcrumbs.stories"; |
||||
|
||||
<Meta of={stories} /> |
||||
|
||||
# Breadcrumbs |
||||
|
||||
Breadcrumbs are used to help users understand where they are in a products navigation. Typically |
||||
Bitwarden uses this component to indicate the user's current location in a set of data organized in |
||||
containers (Collections, Folders, or Projects). |
||||
|
||||
<Primary /> |
||||
<Controls /> |
||||
|
||||
## Display |
||||
|
||||
Breadcrumbs display above the page title. The current page should not appear as a breadcrumb link. |
||||
See [Header with Breadcrumbs](?path=/story/web-header--with-breadcrumbs). |
||||
|
||||
### Top Level |
||||
|
||||
When a user is 1 level deep into a tree, the top level is displayed as a single link above the page |
||||
title. |
||||
|
||||
<Story of={stories.TopLevel} /> |
||||
|
||||
### Second Level |
||||
|
||||
When a user is 2 or more levels deep into a tree, the top level is displayed followed by an |
||||
|
||||
<i class="bwi bwi-angle-right"></i> icon, and the following pages. |
||||
|
||||
<Story of={stories.SecondLevel} /> |
||||
|
||||
### Overflow |
||||
|
||||
When a user is several levels deep into a tree, the top level or 2 are displayed followed by an |
||||
|
||||
<i class="bwi bwi-ellipsis-h"> </i> icon button, and then the page directly above the current page. |
||||
|
||||
When the user selects the <i class="bwi bwi-ellipsis-h"></i> icon button, a menu opens displaying |
||||
the pages between the top level and the previous page. |
||||
|
||||
<Story of={stories.Overflow} /> |
||||
|
||||
### Small screens |
||||
|
||||
If a screen's width is not large enough to display the full breadcrumb path, display a link to the |
||||
previous page and an <i class="bwi bwi-angle-right"></i> icon to take the user back to the previous |
||||
page. |
||||
|
||||
`TODO:` [Jira add stories](https://bitwarden.atlassian.net/browse/CL-102) for responsive screen |
||||
width/small screens |
||||
@ -0,0 +1,66 @@
@@ -0,0 +1,66 @@
|
||||
import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; |
||||
|
||||
import * as stories from "./callout.stories"; |
||||
|
||||
<Meta of={stories} /> |
||||
|
||||
# Callouts |
||||
|
||||
Callouts are used to communicate important information to the user. Callouts should be used |
||||
sparingly, as they command a large amount of visual attention. Avoid using more than 1 callout in |
||||
the same location. |
||||
|
||||
## Styles |
||||
|
||||
Icons should remain consistent across these types. Do not change the icon without consulting a |
||||
designer. Use the following guidelines to help choose the correct type of callout. |
||||
|
||||
### Success |
||||
|
||||
Use the success callout to communicate a positive messaging to the user. |
||||
|
||||
**Example:** a positive report results shows a success callout. |
||||
|
||||
The success callout may also be used for the information related to a premium membership. In this |
||||
case, replace the icon with <i class="bwi bwi-star" title="bwi-star" aria-label="bwi-star"></i> |
||||
|
||||
<Story of={stories.Success} /> |
||||
|
||||
### Info |
||||
|
||||
Use an info callout to call attention to important information the user should be aware of, but has |
||||
low risk of the user receiving and unintended or irreversible results if they do not read the |
||||
information. |
||||
|
||||
**Example:** in the Domain Claiming modal, an info callout is used to tell the user the domain will |
||||
automatically be checked. |
||||
|
||||
<Story of={stories.Info} /> |
||||
|
||||
### Warning |
||||
|
||||
Use a warning callout if the user is about to perform an action that may have unintended or |
||||
irreversible results. |
||||
|
||||
**Example:** the warning callout is used before the change master password and encryption key form |
||||
to alert the user that they will be logged out. |
||||
|
||||
<Story of={stories.Warning} /> |
||||
|
||||
### Danger |
||||
|
||||
Use the danger callout to communicate an action the user is about to take is dangerous and typically |
||||
not reversible. |
||||
|
||||
The danger callout can also be used to alert the user of an error or errors, such as a server side |
||||
errors after form submit or failed communication request. |
||||
|
||||
<Story of={stories.Danger} /> |
||||
|
||||
## Accessibility |
||||
|
||||
Use the `role=”alert”` only if the callout is appearing on a page after the user takes an action. If |
||||
the content is static, do not use the alert role. This will cause a screen reader to announce the |
||||
callout content on page load. |
||||
|
||||
Ensure the title's color contrast remains WCAG compliant with the callout's background. |
||||
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; |
||||
|
||||
import * as stories from "./color-password.stories"; |
||||
|
||||
<Meta of={stories} /> |
||||
|
||||
# Color password |
||||
|
||||
The color password is used primarily in the Generator pages and in the Login type form. It includes |
||||
the logic for displaying letters as `text-main`, numbers as `primary`, and special symbols as |
||||
`danger`. |
||||
|
||||
<Primary /> |
||||
<Controls /> |
||||
|
||||
## Password Count |
||||
|
||||
The password count option is used in the Login type form. It is used to highlight each character's |
||||
position in the password string. |
||||
|
||||
<Story of={stories.ColorPasswordCount} /> |
||||
|
||||
## Wrapped Password |
||||
|
||||
When the password length is longer than the container's width, it should wrap as shown below. |
||||
|
||||
<Story of={stories.WrappedColorPassword} /> |
||||
|
||||
<Story of={stories.WrappedColorPasswordCount} /> |
||||
|
||||
## Accessibility |
||||
|
||||
The colors used in the colored password should maintain WCAG compliant contrast with theme |
||||
`background` and `background-alt` colors. |
||||
@ -0,0 +1,73 @@
@@ -0,0 +1,73 @@
|
||||
import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; |
||||
|
||||
import * as stories from "./dialog.stories"; |
||||
|
||||
<Meta of={stories} /> |
||||
|
||||
# Dialog |
||||
|
||||
Dialogs are used throughout the app to help the user focus on a specific action. Use this dialog |
||||
component when content exceeds 384px width or there are a high number of interactive elements |
||||
needed. **Example:** The web app's edit vault item form dialog |
||||
|
||||
For alerts or simple confirmation actions, like speedbumps, use the |
||||
[Simple Dialog](?path=/docs/component-library-dialogs-simple-dialog--docs). |
||||
|
||||
Dialogs's should be used sparingly as they do call extra attention to themselves and can be |
||||
interruptive if overused. |
||||
|
||||
<Primary /> |
||||
<Controls /> |
||||
|
||||
## Size |
||||
|
||||
There are 3 main dialog sizes: |
||||
|
||||
### Large |
||||
|
||||
Use the large size for dialogs that have many interactive elements or tabbed content. |
||||
|
||||
**Tailwind styling:** |
||||
|
||||
`max-w-3xl` 48rem |
||||
|
||||
<Story of={stories.Large} /> |
||||
|
||||
### Default |
||||
|
||||
Use the Default size for most dialogs that require some content and a few interactive elements. |
||||
**Example:** master password confirmation dialog |
||||
|
||||
**Tailwind styling:** |
||||
|
||||
`max-w-xl` 36rem |
||||
|
||||
<Story of={stories.Default} /> |
||||
|
||||
### Small |
||||
|
||||
**Tailwind styling:** |
||||
|
||||
`max-w-sm` 24rem |
||||
|
||||
<Story of={stories.Small} /> |
||||
|
||||
## Long Title |
||||
|
||||
If a dialog's title is too long to fully display. It should be truncated and on hover shown in a |
||||
tooltip. |
||||
|
||||
<Story of={stories.LongTitle} /> |
||||
|
||||
## Loading |
||||
|
||||
Similar to a page loading state, a Dialog that takes more than a few seconds to load should use a |
||||
loading state. |
||||
|
||||
<Story of={stories.Loading} /> |
||||
|
||||
## Tab Content |
||||
|
||||
Use tabs to separate related content within a dialog. |
||||
|
||||
<Story of={stories.TabContent} /> |
||||
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
import { Meta, Story, Source } from "@storybook/addon-docs"; |
||||
|
||||
<Meta title="Component Library/Dialogs" /> |
||||
|
||||
# Dialog |
||||
|
||||
Dialogs are used throughout the app to help the user focus on a specific action. |
||||
|
||||
Use the main [Dialog Component](?path=/docs/component-library-dialogs-dialog--docs). when content |
||||
exceeds 384px width or there are a high number of interactive elements needed. **Example:** The web |
||||
app's edit vault item form dialog |
||||
|
||||
For alerts or simple confirmation actions, like speedbumps, use the |
||||
[Simple Dialog](?path=/docs/component-library-dialogs-simple-dialog--docs). |
||||
|
||||
Dialogs's should be used sparingly as they do call extra attention to themselves and can be |
||||
interruptive if overused. |
||||
|
||||
## Placement |
||||
|
||||
Dialogs should be centered vertically and horizontally on screen. Dialogs height should expand to |
||||
fit its content until there are 2rems of margin on the top/bottom of the dialog; in this case, the |
||||
dialog should become scrollable. |
||||
|
||||
A backdrop should be used to hide the content below the dialog. Use `#000000` with `30% opacity`. |
||||
|
||||
<Story id="component-library-dialogs-service--default" /> |
||||
|
||||
## Accessibility |
||||
|
||||
### Component behavior |
||||
|
||||
- Dialog include `role="dialog"` |
||||
- The Dialog title is an `<h1>` |
||||
- A user should not be able to tab focus outside of the Dialog until it has been closed. |
||||
- Clicking outside the dialog or clicking escape should close the dialog (this prevents a keyboard |
||||
trap) |
||||
|
||||
### Required per implementation |
||||
|
||||
The triggering button should indicate to assistive technology that additional content will open or |
||||
appear when the trigger is selected. Consider using `aria-haspopup="true"` |
||||
|
||||
Dialog title should be announced by a screen reader when launched. Consider using `aria-labelledby` |
||||
or `aria-label` |
||||
|
||||
When opened, focus should follow the visual order of the popover’s focusable content. Typically |
||||
focus is moved to the close button, but it is acceptable to move focus to the first interactive |
||||
element after close since a user may not want to close the dialog immediately if there are |
||||
additional interactive elements. See |
||||
[WCAG Focus Order success criteria](https://www.w3.org/WAI/WCAG21/Understanding/focus-order.html) |
||||
|
||||
Once closed, focus should remain on the the element which triggered the Dialog. |
||||
|
||||
**Note:** If a Simple Dialog is triggered from a main Dialog, be sure to make sure focus is moved to |
||||
the Simple Dialog. |
||||
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; |
||||
|
||||
import * as stories from "./simple-dialog.stories"; |
||||
|
||||
<Meta of={stories} /> |
||||
|
||||
# Simple Dialogs |
||||
|
||||
Simple Dialogs are used throughout the app for simple alert or confirmation actions such as |
||||
speedbumps. |
||||
|
||||
For dialogs with a high number of interactive elements such as a form or content exceeding 384px, |
||||
use the [Dialog component](?path=/docs/component-library-dialogs-dialog--docs). |
||||
|
||||
<Primary /> |
||||
<Controls /> |
||||
|
||||
## Configurable Simple Dialog |
||||
|
||||
The Simple Dialog contains the following configuration points: |
||||
|
||||
- `title`: string |
||||
- `content`: string |
||||
- `type`: SimpleDialogType |
||||
- `icon`: string – if empty, infer from type |
||||
- `acceptButtonText`: string – if empty, default to "Yes" |
||||
- `cancelButtonText`: string – if empty, default to "No", unless acceptButtonText is overridden, in |
||||
which case default to "Cancel" |
||||
|
||||
To increase consistency, the simple dialog service supports some automation for setting the `icon` |
||||
and `color` based on the defined type. See the following for how properties will be configured when |
||||
the simple dialog's type is specified. |
||||
|
||||
| type | icon name | icon | color | |
||||
| ------- | ------------------------ | -------------------------------------------- | ----------- | |
||||
| primary | bwi-business | <i class="bwi bwi-business"></i> | primary-500 | |
||||
| success | bwi-star | <i class="bwi bwi-star"></i> | success-500 | |
||||
| info | bwi-info-circle | <i class="bwi bwi-info-circle"></i> | info-500 | |
||||
| warning | bwi-exclamation-triangle | <i class="bwi bwi-exclamation-triangle"></i> | warning-500 | |
||||
| danger | bwi-error | <i class="bwi bwi-error"></i> | danger-500 | |
||||
|
||||
## Scrolling Content |
||||
|
||||
Simple dialogs can support scrolling content if necessary, but typically with larger quantities of |
||||
content a [Dialog component](?path=/docs/component-library-dialogs-dialog--docs). |
||||
|
||||
<Story of={stories.ScrollingContent} /> |
||||
@ -0,0 +1,178 @@
@@ -0,0 +1,178 @@
|
||||
import { Meta, Story, Source } from "@storybook/addon-docs"; |
||||
|
||||
<Meta title="Component Library/Form" /> |
||||
|
||||
# Forms |
||||
|
||||
Component Library forms should always be built using [Angular Reactive Forms][reactive]. Please read |
||||
[ADR-0001][adr-0001] for a background to this decision. In practice this means that forms should |
||||
always use the native `form` element and bind a `formGroup`. |
||||
|
||||
<Story id="component-library-form--full-example" /> |
||||
|
||||
<Source id="component-library-form--full-example" /> |
||||
|
||||
## Form spacing and sections |
||||
|
||||
Forms consists of 1 or more inputs, and ends with 1 or 2 buttons. |
||||
|
||||
If there are many inputs in a form, they should should be organized into sections as content |
||||
relates. **Example:** Item type form |
||||
|
||||
Each input within a section should follow the following spacing guidelines (see |
||||
[Tailwind CSS spacing documentation](https://tailwindcss.com/docs/customizing-spacing)): |
||||
|
||||
- 1.5rem of vertical spacing between form elements: `mb-6` |
||||
- 1.5rem of horizontal spacing between form elements: `mr-6` |
||||
- 3rem of vertical spacing below a form section: `mb-12` |
||||
- 1rem of vertical spacing between a form group divider and the group's title; so title tag has: |
||||
`my-4` |
||||
- Form section titles should be styled using `text-lg` |
||||
- Each form sections may have a single column, double or triple column layout. No form should have |
||||
more than 3 columns. Do NOT use different column layouts within the same form section. Choose the |
||||
best layout based on the number of fields and type of fields included. |
||||
|
||||
## Input Types |
||||
|
||||
### Field |
||||
|
||||
A form field is the most common input in a form. It consists of a label, control and an optional |
||||
hint. |
||||
|
||||
The styling of form fields applies to all field types: `text`, `number`, `select`, `text-area`, |
||||
`date`, etc. |
||||
|
||||
Be sure to use an appropriate type attribute on fields when defining new field components (e.g. |
||||
`email` for email address or `number` for numerical information) to take advantage of newer input |
||||
controls like email verification, number selection, and more. |
||||
|
||||
#### Default with required attribute |
||||
|
||||
<Story id="component-library-form-field--default" /> |
||||
|
||||
#### Password Toggle |
||||
|
||||
<Story id="component-library-form-password-toggle--default" /> |
||||
|
||||
#### Search |
||||
|
||||
<Story id="component-library-form-search--default" /> |
||||
|
||||
### Selects |
||||
|
||||
#### Searchable single select (default) |
||||
|
||||
<Story id="component-library-form-select--default" /> |
||||
|
||||
#### Multi-select |
||||
|
||||
<Story id="component-library-form-multi-select--members" /> |
||||
|
||||
### Radio group |
||||
|
||||
Radio buttons should always be in radio groups. |
||||
|
||||
Radio groups are form fields that consists of a main label and multiple radio buttons. Each radio |
||||
button consists of a label and a radio input. |
||||
|
||||
The full form control + label should be selectable to allow the user a larger click target. |
||||
|
||||
Radio groups should always have a default selected value. |
||||
|
||||
Radio groups may optionally include extra helper text below each radio button. |
||||
|
||||
If a radio group has more than 4 options and the options do not need helper text, a |
||||
[select menu](?path=/docs/component-library-form-multi-select--docs) should be used instead. Avoid |
||||
using a radio group for more than 5 options even if the options require additional explanation text. |
||||
|
||||
`TODO: extend the select component to support a dropdown menu with descriptions below each option` |
||||
|
||||
#### Block |
||||
|
||||
<Story id="component-library-form-radio-button--block" /> |
||||
|
||||
#### Inline |
||||
|
||||
<Story id="component-library-form-radio-button--inline" /> |
||||
|
||||
[reactive]: https://angular.io/guide/reactive-forms |
||||
[adr-0001]: https://contributing.bitwarden.com/architecture/adr/reactive-forms |
||||
|
||||
### Checkbox |
||||
|
||||
The checkbox input is used to toggle an action on/off. |
||||
|
||||
Checkboxes can be displayed on their own or in a group (select multiple form question). When |
||||
displayed in a group, include an input Label and any associated required/validation logic for the |
||||
field. |
||||
|
||||
Unlike radio groups, checkbox groups are not required to have a default selected value. |
||||
|
||||
Checkbox groups can include extra explanation text below each radio button or just the checkbox |
||||
button itself. |
||||
|
||||
If a checkbox group has more than 4 options a |
||||
[multi-select components](?path=/docs/component-library-form-multi-select--docs) should be used. |
||||
|
||||
#### Single checkbox |
||||
|
||||
<Story id="component-library-form-checkbox--default" /> |
||||
|
||||
## Accessibility |
||||
|
||||
### Required Fields |
||||
|
||||
- Use "(required)" in the label of each required form field styled the same as the field's helper |
||||
text (`.muted-text`). |
||||
- If whether or not a form field is required depends on another field, add this to the field's |
||||
helper text. |
||||
- **Example:** "Billing Email is required if owned by a business". |
||||
|
||||
### Form Field Errors |
||||
|
||||
- When a resting field is filled out, validation is triggered when the user de-focuses the field |
||||
(`onblur`). If the control is invalid, assistive technology should announce the error (consider |
||||
using `role="alert"` or an `aria-live="assertive"`). |
||||
- Validation should not be triggered if the control is left untouched; this allows a user of |
||||
assistive technology to read the entire form if they wish without triggering validation that could |
||||
interrupt them. - **TODO:** research how we might implement this behavior; as previous research |
||||
has shown Angular may not allow both validation when `dirty` `onblur` AND validation on Submit |
||||
which is a requirement |
||||
- A form control with an error should change to the error UI and the error text should be displayed |
||||
below the element and be associated to their respective fields (consider using `aria-describedby`) |
||||
- When a field with an error is focused, assistive technology should announce the label and |
||||
elements' invalid state and then the error text. |
||||
- **Example:** "URL required, Error, URL format is not acceptable." |
||||
- Once the user has re-focused the field, and starts typing. The error will disappear. Validation |
||||
should not occur when typing in most cases. Once th user unfocuses the field, validation triggers |
||||
again. |
||||
|
||||
### Validation on Submit |
||||
|
||||
- Validation must also occur on submit. A user may select the submit button directly without |
||||
changing focus from a form input. Or a user may disable their browser's javascript which is what |
||||
supports the inline onblur validation. Finally, there may be a server side error that can only be |
||||
checked on submit. |
||||
- On submit, a summary error should appear near the submit button or at the top of the form alerting |
||||
the user of what errors need to be addressed. This summary should be read out by assistive |
||||
technology after submit regardless of whether or not it was already on screen. |
||||
- Any invalid form control will display an inline error following the field's helper text (or in |
||||
place of) |
||||
- If submit is successful, use a success toast to alert the user of the successful action. |
||||
- For any server side errors, the Danger toast may still be used. Be sure to adjust the toast's |
||||
timeout to follow the 6 second |
||||
|
||||
* 1 second for each additional 120 words rule. |
||||
|
||||
### Helper Text |
||||
|
||||
Similar to a field error, helper text should be associated to a field using `aria-describedby`. This |
||||
allows assistive technology to read out the instructional text and field requirements in addition to |
||||
the field’s label. |
||||
|
||||
### Visual style |
||||
|
||||
- All field inputs are interactive elements that must follow the WCAG graphic contrast guidelines. |
||||
Maintain a ratio of 3:1 with the form's background. |
||||
- Error styling should not rely only on using the `danger-500`color change. Use |
||||
<i class="bwi bwi-error"></i> as a prefix to highlight the text as error text versus helper |
||||
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; |
||||
|
||||
import * as stories from "./icon-button.stories"; |
||||
|
||||
<Meta of={stories} /> |
||||
|
||||
# Icon Button |
||||
|
||||
Icon buttons are used when no text accompanies the button. It consists of an icon that may be |
||||
updated to any icon in the `bwi-font`, a `title` attribute, and an `aria-label`. |
||||
|
||||
There are 3 common styles for button main, contrast, and danger. The main style is used on the |
||||
theme’s main `background`; and the contrast style is used on a theme’s colored or contrasting |
||||
backgrounds; danger is used for “trash” actions throughout the experience. The other styles are used |
||||
sparingly. |
||||
|
||||
The most common use of the icon button is in the banner, toast, and modal components as a close |
||||
button. It can also be found in tables as the 3 dot option menu, or on navigation list items when |
||||
there are options that need to be collapsed into a menu. |
||||
|
||||
Similar to the main button components, spacing between icon buttons should be .5rem. |
||||
|
||||
<Primary /> |
||||
<Controls /> |
||||
|
||||
**Note:** Main and contrast styles appear on backgrounds where using `primary-700` as a focus |
||||
indicator does not meet WCAG graphic contrast guidelines. |
||||
|
||||
## Sizes |
||||
|
||||
There are 2 sizes for the icon button: `small` and `default`. |
||||
|
||||
Default is typically used for most instances. Small is used if the implementation needs a variant |
||||
with less padding around the icon, such as in the navigation component. |
||||
|
||||
## Usage |
||||
|
||||
Icon buttons can be found in other components such as: the |
||||
[banner](?path=/docs/component-library-banner--docs) |
||||
[dialog](?path=/docs/component-library-dialogs--docs), and |
||||
[table](?path=/docs/component-library-table--docs). |
||||
|
||||
<Story id="component-library-banner--premium" /> |
||||
|
||||
## Accessibility |
||||
|
||||
Follow guidelines outlined in the [Button docs](?path=/docs/component-library-button--doc) |
||||
|
||||
Always use the `appA11yTitle` directive set to a string that describes the action of the |
||||
icon-button. This will auto assign the same string to the `title` and `aria-label` attributes. |
||||
|
||||
`aria-label` allows assistive technology to announce the action the button takes to the users. |
||||
|
||||
`title` attribute provides a user with the browser tool tip if they do not understand what the icon |
||||
is indicating. |
||||
@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
|
||||
import { Meta } from "@storybook/addon-docs"; |
||||
|
||||
<Meta title="Component Library/Form/Input" /> |
||||
<Meta title="Component Library/Form/Input Directive" /> |
||||
|
||||
# Input |
||||
|
||||
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; |
||||
|
||||
import * as stories from "./link.stories"; |
||||
|
||||
<Meta of={stories} /> |
||||
|
||||
# Link / Text button |
||||
|
||||
Text Links and Buttons use the `primary-500` color and can use either the `<a>` or `<button>` tags. |
||||
Choose which based on the action the button takes: |
||||
|
||||
- if navigating to a new page, use a `<a>` |
||||
- if taking an action on the current page use a `<button>` |
||||
|
||||
Text buttons or links are most commonly used in paragraphs of text or in forms to customize actions |
||||
or show/hide additional form options. |
||||
|
||||
<Primary /> |
||||
<Controls /> |
||||
|
||||
## Sizes |
||||
|
||||
There are 2 sizes for the component: default and small. |
||||
|
||||
Default uses `text-base` and small uses `text-xs` |
||||
|
||||
## With icons |
||||
|
||||
Text Links/buttons can have icons on left or the right. |
||||
|
||||
To indicate a new or add action, the <i class="bwi bwi-plus-circle"></i> icon on is used on the |
||||
left. |
||||
|
||||
An angle icon, <i class="bwi bwi-angle-right"></i>, is used on the left to indicate an expand to |
||||
show/hide additional content. |
||||
|
||||
## Accessibility |
||||
|
||||
Make sure to only use the Link on backgrounds that maintain the WCAG color contrast ratios. |
||||
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; |
||||
|
||||
import * as stories from "./menu.stories"; |
||||
|
||||
<Meta of={stories} /> |
||||
|
||||
# Menu |
||||
|
||||
Menus are used to help organize related options. Menus are most often used for item options in |
||||
tables. |
||||
|
||||
<Story of={stories.ClosedMenu} /> |
||||
<Controls /> |
||||
|
||||
## Accessibility |
||||
|
||||
Follow WCAG AA best practices. Example: Insure the triggering element has `aria-haspopup="true"` |
||||
prior to being clicked and `aria-expanded="true"` after the user clicks the element. |
||||
|
||||
User should be able to navigate the opened menu via the up and down arrow keys and close the menu |
||||
using the escape key or clicking out of the menu. |
||||
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; |
||||
|
||||
import * as stories from "./progress.stories"; |
||||
|
||||
<Meta of={stories} /> |
||||
|
||||
# Progress |
||||
|
||||
Progress indicators may be used to visually indicate progress or to visually measure some other |
||||
value, such as a password strength indicator. |
||||
|
||||
<Primary /> |
||||
<Controls /> |
||||
|
||||
## Labels |
||||
|
||||
Always display a label to provide a text based description of what the indicator is measuring. This |
||||
allows those who may not be familiar with the pattern to be able to read and digest the information. |
||||
It also allows assistive technology to accurately describe the indicator to those who may be unable |
||||
to see part or all of the indicator. |
||||
|
||||
<Story of={stories.Full} /> |
||||
|
||||
## Text label |
||||
|
||||
When measuring something other than progress, such as password strength, update the label to fit the |
||||
context of the implementation. |
||||
|
||||
<Story of={stories.CustomText} /> |
||||
|
||||
### Strength indicator styles |
||||
|
||||
For a strength indicator use the following styles for fill: |
||||
|
||||
- **Weak:** `danger-500` |
||||
- **Weak2:** `warning-500` |
||||
- **Good:** `primary-500` |
||||
- **Strong:** `success-500` |
||||
|
||||
## Accessibility |
||||
|
||||
Be sure to include the proper `aria-valuemin`, `aria-valuemax`, and `aria-valuenow` attributes. An |
||||
a`ria-valuetext` should also be configurable to include the text a screen reader should read to the |
||||
user. |
||||
|
||||
In the case of a password strength indicator; `aria-describedby` is used on the password field and |
||||
points to the `id` of the progress bar. This results in the screen reader reading the password |
||||
strength to the user after they finish typing. |
||||
@ -1,51 +0,0 @@
@@ -1,51 +0,0 @@
|
||||
import { Meta, Story, Source } from "@storybook/addon-docs"; |
||||
|
||||
<Meta title="Component Library/Form" /> |
||||
|
||||
# Forms |
||||
|
||||
Examples and usage guidelines for form control styles, layout options, and custom components for |
||||
creating a wide variety of forms. |
||||
|
||||
## Overview |
||||
|
||||
Component Library forms should always be built using [Angular Reactive Forms][reactive]. Please read |
||||
[ADR-0001][adr-0001] for a background to this decision. In practice this means that forms should |
||||
always use the native `form` element and bind a `formGroup`. |
||||
|
||||
Forms consists of one or multiple sections, and ends with one or multiple buttons. |
||||
|
||||
### Form Field |
||||
|
||||
A form field is the most common section in a form. It consists of a label, control and a optional |
||||
hint. |
||||
|
||||
<Story id="component-library-form-field--default" /> |
||||
|
||||
<Source id="component-library-form-field--default" /> |
||||
|
||||
### Radio group |
||||
|
||||
A radio group is a form field that consists of a main label and multiple radio groups. Each group |
||||
consists of a label and a radio input. |
||||
|
||||
#### Block |
||||
|
||||
<Story id="component-library-form-radio-button--block" /> |
||||
|
||||
<Source id="component-library-form-radio-button--block" /> |
||||
|
||||
#### Inline |
||||
|
||||
<Story id="component-library-form-radio-button--inline" /> |
||||
|
||||
<Source id="component-library-form-radio-button--inline" /> |
||||
|
||||
## Full Example |
||||
|
||||
<Story id="component-library-form--full-example" /> |
||||
|
||||
<Source id="component-library-form--full-example" /> |
||||
|
||||
[reactive]: https://angular.io/guide/reactive-forms |
||||
[adr-0001]: https://contributing.bitwarden.com/architecture/adr/reactive-forms |
||||
@ -0,0 +1,40 @@
@@ -0,0 +1,40 @@
|
||||
import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; |
||||
|
||||
import * as stories from "./tabs.stories"; |
||||
|
||||
<Meta of={stories} /> |
||||
|
||||
# Tabs |
||||
|
||||
The tab navigation and content tabs share the same styling. The tab navigation uses links to |
||||
navigate between pages, whereas the tab list uses `<buttons>` to toggle content on a single page. |
||||
|
||||
Tabs should be displayed on the `background-alt` color, with their content area set to background |
||||
and 1rem of padding on the left and right. |
||||
|
||||
<Primary /> |
||||
<Controls /> |
||||
|
||||
## Content Tabs |
||||
|
||||
<Story of={stories.ContentTabs} /> |
||||
|
||||
## Navigation Tabs |
||||
|
||||
<Story of={stories.NavigationTabs} /> |
||||
|
||||
## Content tabs in dialogs |
||||
|
||||
Tabs can be used in dialogs to separate related content. |
||||
|
||||
<Story id="component-library-dialogs-dialog--tab-content" /> |
||||
|
||||
## Accessibility |
||||
|
||||
**Navigation tabs** are implemented using the `<nav>` element and `<a>` for each tab. |
||||
|
||||
**Content tabs** should be implemented with the `tablist` role and: |
||||
|
||||
- Use `<button>` for the tab elements |
||||
- Set `aria-selected` for each tab; “true” for selected and “false” for unselected |
||||
- See WCAG for more: https://www.w3.org/TR/wai-aria-practices/examples/tabs/tabs-1/tabs.html |
||||
@ -0,0 +1,36 @@
@@ -0,0 +1,36 @@
|
||||
import { Meta, Story, Primary, Controls } from "@storybook/addon-docs"; |
||||
|
||||
import * as stories from "./toggle-group.stories"; |
||||
|
||||
<Meta of={stories} /> |
||||
|
||||
# Toggle Group |
||||
|
||||
Toggle groups are used for quick filters for a data set. **Example:** the Member’s page of the Admin |
||||
Console uses a toggle group to filter members by their organization status: all, invited, needs |
||||
confirmation, revoked. |
||||
|
||||
Toggle groups function as radio buttons and a radio group under the hood. |
||||
|
||||
A button in a toggle group can have a badge counter added to show the number of items existing |
||||
within that filter. |
||||
|
||||
For focus states, use `focus-visible`. |
||||
|
||||
<Primary /> |
||||
<Controls /> |
||||
|
||||
## Accessibility |
||||
|
||||
- Follow contrast rules for the main button styles. |
||||
- Focus: |
||||
- Implement as a radio group with button styling and a context label (context label can be screen |
||||
reader only depending on use case). |
||||
- Since only 1 button can be selected at a time to filter the toggle group acts similarly to a |
||||
radio group. |
||||
- When moving focus to a button group, the focus should always move to the selected button. The |
||||
screen reader should then announce the button group: example “[context label], [button content] |
||||
selected, of [# of buttons]”), the number of buttons and the currently selected button. The user |
||||
may navigate the options then via left/right arrow keys. |
||||
|
||||
See WCAG for more: https://www.w3.org/WAI/ARIA/apg/patterns/radio/ |
||||
Loading…
Reference in new issue