Storybook docs (#5552)

* 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>
This commit is contained in:
Danielle Flinn 2023-06-27 12:46:44 -07:00 committed by GitHub
parent 683b7fea77
commit 6ef6140b29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 936 additions and 79 deletions

View File

@ -101,6 +101,7 @@ const preview: Preview = {
},
options: {
storySort: {
method: "alphabetical",
order: ["Documentation", ["Introduction", "Colors", "Icons"], "Component Library"],
},
},

View File

@ -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 its background; or include the
`secondary-500` border Avatar text should have 4.5:1 contrast with the avatar background color

View File

@ -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.

View File

@ -10,7 +10,7 @@ Banners are used for important communication with the user that needs to be seen
little effect on the experience. Banners appear at the top of the user's screen on page load and
persist across all pages a user navigates to.
- They should always be dismissable and never use a timeout. If a user dismisses a banner, it should
- They should always be dismissible and never use a timeout. If a user dismisses a banner, it should
not reappear during that same active session.
- Use banners sparingly, as they can feel intrusive to the user if they appear unexpectedly. Their
effectiveness may decrease if too many are used.

View File

@ -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

View File

@ -33,31 +33,6 @@ Groups within page content, dialog footers or forms should have the `primary` ca
to left. Groups in headers and navigational areas should have the `primary` call to action on the
right.
## Accessibility
Please follow these guidelines to ensure that buttons are accessible to all users.
### Color contrast
All button styles are WCAG compliant when displayed on `background` and `background-alt` colors. To
use a button on a different background, double check that the color contrast is sufficient in both
the light and dark themes.
### Loading Buttons
Include an `aria-label` attribute that defaults to “loading” but can be configurable per
implementation. On click, the screen reader should announce the `aria-label`. Once the action is
compelted, use another messaging pattern to alert the user that the action is complete (example:
success toast).
### Submit and async actions
Both submit and async action buttons use a loading button state while an action is taken. If your
button is preforming a long running task in the background like a server API call, be sure to review
the [Async Actions Directive](?path=/story/component-library-async-actions-overview--page).
<Story of={stories.Loading} />
## Styles
There are 3 main styles for the button: Primary, Secondary, and Danger.
@ -96,3 +71,39 @@ Typically button widths expand with their text. In some causes though buttons ma
where the width is fixed and the text wraps to 2 lines if exceeding the buttons width.
<Story of={stories.Block} />
## Accessibility
Please follow these guidelines to ensure that buttons are accessible to all users.
### Color contrast
All button styles are WCAG compliant when displayed on `background` and `background-alt` colors. To
use a button on a different background, double check that the color contrast is sufficient in both
the light and dark themes.
### Loading Buttons
Include an `aria-label` attribute that defaults to "loading" but can be configurable per
implementation. On click, the screen reader should announce the `aria-label`. Once the action is
completed, use another messaging pattern to alert the user that the action is complete (example:
success toast).
### Submit and async actions
Both submit and async action buttons use a loading button state while an action is taken. If your
button is preforming a long running task in the background like a server API call, be sure to review
the [Async Actions Directive](?path=/story/component-library-async-actions-overview--page).
<Story of={stories.Loading} />
### appA11yTitle
`appA11yTitle` is a directive that auto assigns the same string to the `title` and `aria-label`
attributes.
When a button uses accessible content (e.i. actual text), DO NOT include this as it adds redundant
content for someone using assistive technology.
`appA11yTitle` should only be used if the element it applies to does not include accessible text,
e.i. an icon.

View File

@ -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.

View File

@ -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.

View File

@ -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} />

View File

@ -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 popovers 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.

View File

@ -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} />

View File

@ -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 fields 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

View File

@ -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
themes main `background`; and the contrast style is used on a themes 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.

View File

@ -1,6 +1,6 @@
import { Meta } from "@storybook/addon-docs";
<Meta title="Component Library/Form/Input" />
<Meta title="Component Library/Form/Input Directive" />
# Input

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -26,12 +26,18 @@ The UI component consists of a couple of elements.
### Guidelines
- Always include a row or column header with your table; this allows screen readers to better
contextualize the data
contextualize the data.
- Avoid spanning data across cells.
- Be sure to make repeating actions unique by associating them with the object they relate to.
Example: if there are multiple “Edit” buttons on a table, a screen reader should read “Edit,
Netflix” for an edit option for a Netflix item.
- Use [Virtual Scrolling](#virtual-scrolling) for large data sets.
- For bulk menu options, display a 3 dot menu in the header. When multiple items are selected, the
bulk menu will contain actions that can be completed in bulk for the selected items.
- Note, this may result in some menu actions being hidden at times if they are not applicable to
the selected item
- Clicking on a rows 3 dot menu will continue to result in actions specific to just that row's
item
### Usage
@ -147,3 +153,12 @@ specify a `itemSize`, set `scrollWindow` to `true` and replace `*ngFor` with `*c
</bit-table>
</cdk-virtual-scroll-viewport>
```
## Accessibility
- Always include a row or column header with your table; this allows assistive technology to better
contextualize the data
- Avoid spanning data across cells
- Be sure to make repeating actions unique by associating them with the object they relate to
- **Example:** if there are multiple “Edit” buttons on a table, a screen reader should read “Edit,
Netflix” for an edit option for a Netflix item.

View File

@ -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

View File

@ -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 Members 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/