Skip to content
This repository has been archived by the owner on Mar 4, 2020. It is now read-only.

Commit

Permalink
docs(Accessibility): improve acc descriptions for components (#1371)
Browse files Browse the repository at this point in the history
improve acc descriptions for components
  • Loading branch information
jurokapsiar committed May 25, 2019
1 parent 9a34737 commit 37ebb61
Show file tree
Hide file tree
Showing 22 changed files with 283 additions and 44 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

### Documentation
- Accessibility: improve introduction section @jurokapsiar ([#1368](https://github.com/stardust-ui/react/pull/1368))
- Accessibility: improve accessibility descriptions for components @jurokapsiar ([#1371](https://github.com/stardust-ui/react/pull/1371))

<!--------------------------------[ v0.31.0 ]------------------------------- -->
## [v0.31.0](https://github.com/stardust-ui/react/tree/v0.31.0) (2019-05-21)
Expand Down
8 changes: 8 additions & 0 deletions docs/src/components/ComponentDoc/AccessibilityDescription.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as React from 'react'
import * as ReactMarkdown from 'react-markdown'

const AccessibilityDescription: React.FunctionComponent<{ value: string }> = ({ value }) => (
<ReactMarkdown source={value} />
)

export default AccessibilityDescription
55 changes: 37 additions & 18 deletions docs/src/components/ComponentDoc/ComponentDocAccessibility.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as React from 'react'
import * as _ from 'lodash'
import { Flex, Text, Accordion } from '@stardust-ui/react'
import { Flex, Loader, Text, Accordion } from '@stardust-ui/react'

const AccessibilityDescription = React.lazy(() => import('./AccessibilityDescription'))

const behaviorMenu = require('docs/src/behaviorMenu')

Expand All @@ -19,35 +21,52 @@ const ComponentDocAccessibility = ({ info }) => {

const accessibilityDetails = (
<>
{description && <Text style={{ whiteSpace: 'pre-line' }}>{description}</Text>}
{description && (
<Text style={{ whiteSpace: 'pre-line' }}>
<React.Suspense fallback={<Loader />}>
<AccessibilityDescription value={description} />
</React.Suspense>
</Text>
)}

{behaviorName && (
<Text>
Default behavior:{' '}
<a href={`behaviors/${behaviorName}#${_.kebabCase(stem)}`}>{behaviorName}</a>
</Text>
<>
<Text>
Default behavior:{' '}
<a href={`behaviors/${behaviorName}#${_.kebabCase(stem)}`}>{behaviorName}</a>
</Text>
<br />
</>
)}

{info.behaviors && (
<Text>
Available behaviors:{' '}
{info.behaviors.map(behavior => (
<React.Fragment key={`${behavior.category}-${behavior.name}`}>
<a href={`behaviors/${behavior.category}#${_.kebabCase(behavior.name)}`}>
{behavior.displayName}
</a>{' '}
</React.Fragment>
))}
</Text>
<>
<Text>
Available behaviors:{' '}
{info.behaviors.map(behavior => (
<React.Fragment key={`${behavior.category}-${behavior.name}`}>
<a href={`behaviors/${behavior.category}#${_.kebabCase(behavior.name)}`}>
{behavior.displayName}
</a>{' '}
</React.Fragment>
))}
</Text>
<br />
</>
)}
</>
)

const accessPanels = [
{
key: 'accessibility',
content: { content: accessibilityDetails },
title: { content: 'Accessibility', as: 'h2' },
content: { content: accessibilityDetails, styles: { paddingLeft: '14px' } },
title: {
content: <Text content="Accessibility" />,
as: 'span',
'aria-level': '2',
styles: { paddingBottom: '0', paddingTop: '0' },
},
},
]

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
"react-dom": "^16.8.6",
"react-element-to-jsx-string": "^14.0.2",
"react-hot-loader": "^4.8.2",
"react-markdown": "^4.0.8",
"react-router": "^4.1.2",
"react-router-dom": "^4.1.2",
"react-source-render": "2.0.0-beta.6",
Expand Down
6 changes: 5 additions & 1 deletion packages/internal-tooling/babel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ module.exports = {
'@babel/preset-react',
'@babel/preset-typescript',
],
plugins: ['@babel/plugin-proposal-class-properties', '@babel/plugin-transform-runtime'],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-transform-runtime',
],
env: {
delelopment: {
plugins: ['react-hot-loader/babel'],
Expand Down
1 change: 1 addition & 0 deletions packages/internal-tooling/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"dependencies": {
"@babel/core": "^7.3.4",
"@babel/plugin-proposal-class-properties": "^7.3.4",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-transform-runtime": "^7.3.4",
"@babel/preset-env": "^7.3.4",
"@babel/preset-react": "^7.0.0",
Expand Down
5 changes: 3 additions & 2 deletions packages/react/src/components/Accordion/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,8 @@ class Accordion extends AutoControlledComponent<WithAsProp<AccordionProps>, Acco
/**
* An accordion allows users to toggle the display of sections of content.
* @accessibility
* Implements ARIA Accordion design pattern (keyboard navigation not yet supported).
* Consider using Tree if you intend to wrap Lists in an Accordion.
* Implements [ARIA Accordion](https://www.w3.org/TR/wai-aria-practices-1.1/#accordion) design pattern (keyboard navigation not yet supported).
* Do use Accordion for grouping parts of the UI (multipart forms, articales...).
* Do use Tree component to display a hierarchical structure that allows user to select one item.
*/
export default withSafeTypeForAs<typeof Accordion, AccordionProps>(Accordion)
6 changes: 3 additions & 3 deletions packages/react/src/components/Alert/Alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ class Alert extends UIComponent<WithAsProp<AlertProps>, AlertState> {
/**
* A Alert displays information that explains nearby content.
* @accessibility
* Other considerations:
* - by default, content from warning and danger variants is announced by the screen reader. To announce the content of other variants, a mechanism similar to react-aria-live can be used
* - if Alert contains action slot, textual representation needs to be provided by using 'title', 'aria-label' or 'aria-labelledby' attributes
* Do use warning and danger variants to announce the alert by the screen reader.
* Do use other libraries (for example react-aria-live) if the content of default or success variant needs to be announced.
* Do add textual representation to action slot if they only contain an icon (using title, aria-label or aria-labelledby props on the slot).
*/
export default withSafeTypeForAs<typeof Alert, AlertProps>(Alert)
4 changes: 1 addition & 3 deletions packages/react/src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,6 @@ Button.create = createShorthandFactory({ Component: Button, mappedProp: 'content
/**
* A button indicates a possible user action.
* @accessibility
* Other considerations:
* - for disabled buttons, add 'disabled' attribute so that the state is properly recognized by the screen reader
* - if button includes icon only, textual representation needs to be provided by using 'title', 'aria-label' or 'aria-labelledby' attributes
* Do add textual representation if the component only contains an icon (using title, aria-label or aria-labelledby props).
*/
export default withSafeTypeForAs<typeof Button, ButtonProps, 'button'>(Button)
4 changes: 3 additions & 1 deletion packages/react/src/components/Dialog/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ Dialog.slotClassNames = {
}

/**
* A Dialog indicates a possible user action.
* A Dialog displays important information on top of a page which usually requires user's attention, confirmation or interaction.
* @accessibility
* Implements [ARIA Dialog (Modal)](https://www.w3.org/TR/wai-aria-practices-1.1/#dialog_modal) design pattern.
*/
export default withSafeTypeForAs<typeof Dialog, DialogProps>(Dialog)
4 changes: 3 additions & 1 deletion packages/react/src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1291,6 +1291,8 @@ Dropdown.slotClassNames = {
* Dropdown allows user to select one or more values from a list of items.
* Can also be created with search capability.
* @accessibility
* Implements ARIA collapsible Listbox design pattern, uses aria-live to announce state changes.
* Implements [ARIA Combo Box](https://www.w3.org/TR/wai-aria-practices-1.1/#combobox) design pattern, uses aria-live to announce state changes.
* Do provide getA11ySelectionMessage, getA11yStatusMessage, noResultsMessage and loadingMessage props to announce state changes correctly.
* Do provide aria-label to triggerButton slot for non-searchable variants if the placeholder prop is not used.
*/
export default withSafeTypeForAs<typeof Dropdown, DropdownProps>(Dropdown)
2 changes: 1 addition & 1 deletion packages/react/src/components/Embed/Embed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ class Embed extends AutoControlledComponent<WithAsProp<EmbedProps>, EmbedState>
Embed.create = createShorthandFactory({ Component: Embed })

/**
* A GIF is a muted segment of a video
* A GIF is a muted segment of a video.
* @accessibility
* If GIF should be visible to screen readers, textual representation needs to be provided in 'alt' or 'title' property.
*
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/components/Form/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,6 @@ class Form extends UIComponent<WithAsProp<FormProps>, any> {
/**
* A Form displays a set of related user input fields in a structured way.
* @accessibility
* Label needs to be provided by using 'aria-label', or 'aria-labelledby' attributes on the <form> element.
* Do provide label by using 'aria-label', or 'aria-labelledby' prop.
*/
export default withSafeTypeForAs<typeof Form, FormProps, 'form'>(Form)
5 changes: 3 additions & 2 deletions packages/react/src/components/Grid/Grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ class Grid extends UIComponent<WithAsProp<GridProps>, any> {

/**
* A grid is used to harmonize negative space in a layout.
* @accessibility This is example usage of the accessibility tag.
* This should be replaced with the actual description after the PR is merged
* @accessibility
* Do use Grid behavior for bidirectional keyboard navigation. Use appropriate ARIA role for the grid and actionable components inside of it.
* Don't use grid component as a replacement for table.
*/
export default withSafeTypeForAs<typeof Grid, GridProps>(Grid)
3 changes: 1 addition & 2 deletions packages/react/src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ Header.create = createShorthandFactory({ Component: Header, mappedProp: 'content
* Nest headings by their rank (or level). The most important heading has the rank 1 (<h1>), the least important heading rank 6 (<h6>). Headings with an equal or higher rank start a new section, headings with a lower rank start new subsections that are part of the higher ranked section.
*
* Other considerations:
* - when the description property is used in header, readers will narrate both header content and description within the element.
* In addition to that, both will be displayed in the list of headings.
* - when the description property is used in header, readers will narrate both header content and description within the element. In addition to that, both will be displayed in the list of headings.
*/
export default withSafeTypeForAs<typeof Header, HeaderProps, 'h1'>(Header)
2 changes: 2 additions & 0 deletions packages/react/src/components/Icon/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,7 @@ Icon.create = createShorthandFactory({ Component: Icon, mappedProp: 'name' })

/**
* An icon is a glyph used to represent something else.
* @accessibility
* Don't use as a replacement for actionable component - use Button text variant with an icon instead.
*/
export default withSafeTypeForAs<typeof Icon, IconProps, 'span'>(Icon)
4 changes: 2 additions & 2 deletions packages/react/src/components/Image/Image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ Image.create = createShorthandFactory({ Component: Image, mappedProp: 'src' })
* If image should be visible to screen readers, textual representation needs to be provided in 'alt' property.
*
* Other considerations:
* - when alt property is empty, then Narrator in scan mode navigates to image and narrates it as empty paragraph
* - when image has role='presentation' then screen readers navigate to the element in scan/virtual mode. To avoid this, the attribute "aria-hidden='true'" is applied by the default image behavior
* - when alt property is empty, then Narrator in scan mode navigates to image and narrates it as empty paragraph.
* - when image has role='presentation' then screen readers navigate to the element in scan/virtual mode. To avoid this, the attribute "aria-hidden='true'" is applied by the default image behavior.
* - when alt property is used in combination with aria-label, arialabbeledby or title, additional screen readers verification is needed as each screen reader handles this combination differently.
*/
export default withSafeTypeForAs<typeof Image, ImageProps, 'img'>(Image)
4 changes: 3 additions & 1 deletion packages/react/src/components/Menu/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ Menu.create = createShorthandFactory({ Component: Menu, mappedArrayProp: 'items'
/**
* A menu displays grouped navigation actions.
* @accessibility
* Implements ARIA Menu, Toolbar or Tabs design pattern, depending on the behavior used.
* Implements ARIA [Menu](https://www.w3.org/TR/wai-aria-practices-1.1/#menu), [Toolbar](https://www.w3.org/TR/wai-aria-practices-1.1/#toolbar) or [Tabs](https://www.w3.org/TR/wai-aria-practices-1.1/#tabpanel) design pattern, depending on the behavior used.
* Do choose desired accessibility behavior depending on the use case.
* Do provide label to the Menu component using aria-label or aria-labelledby prop.
*/
export default withSafeTypeForAs<typeof Menu, MenuProps, 'ul'>(Menu)
4 changes: 2 additions & 2 deletions packages/react/src/components/Popup/Popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ export interface PopupState {

/**
* A Popup displays additional information on top of a page.
* @accessibility This is example usage of the accessibility tag.
* This should be replaced with the actual description after the PR is merged
* @accessibility
* Do use popupFocusTrapBehavior if the focus needs to be trapped inside of the Popup.
*/
export default class Popup extends AutoControlledComponent<PopupProps, PopupState> {
static displayName = 'Popup'
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/components/RadioGroup/RadioGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,6 @@ class RadioGroup extends AutoControlledComponent<WithAsProp<RadioGroupProps>, an
/**
* A radio group allows a user to select a value from a small set of options.
* @accessibility
* Implements ARIA Radio Group design pattern.
* Implements [ARIA Radio Group](https://www.w3.org/TR/wai-aria-practices-1.1/#radiobutton) design pattern.
*/
export default withSafeTypeForAs<typeof RadioGroup, RadioGroupProps>(RadioGroup)
3 changes: 3 additions & 0 deletions packages/react/src/components/Reaction/Reaction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,8 @@ Reaction.slotClassNames = {

/**
* A reaction is used to indicate user's reaction.
* @accessibility
* Do use actionable components (for example Button) if the reactions need to be actionable.
* Do add textual representation to the icon slot if it only contains an icon (using title, aria-label or aria-labelledby props on the slot).
*/
export default withSafeTypeForAs<typeof Reaction, ReactionProps, 'span'>(Reaction)

0 comments on commit 37ebb61

Please sign in to comment.