cerner / terra-core

Terra offers a set of configurable React components designed to help build scalable and modular application UIs. This UI library was created to solve real-world issues in projects we work on day to day.
http://terra-ui.com
Apache License 2.0
182 stars 167 forks source link

terra-icon UX Audit #3123

Open ryanthemanuel opened 3 years ago

ryanthemanuel commented 3 years ago

terra-icon

Known Aliases

Document any known aliases of the component, decide if another name makes more sense.

Design Standard Doc

Any documentation needed to be added to terra-ui describing the make up and usage of the component Any doc examples that need to be updated?

Guides

Any guides needed to be added to terra-ui describing the usage of this component when used with other components.

Accessibility Guides

Behaviours

Accessibility

Deprecation

Related Issues

Other Considerations

Possibly some general clean up of the OCS icon repository. Need to evaluate icons to make sure they are low lighting correctly. Look into exporting at 16 rather than 64. Need to evaluate styling for stand-alone use (without extra styling for text alignment)

neilpfeiffer commented 3 years ago

Additional Consideration: Need to evaluate further if icons need the ability to be provided as isIconOnly or isStandalone with the additional vertical positioning styles removed that make icons look correctly aligned with text, for use in locations where vertical and horizontal centering is critical and icons are all by themselves (e.g. terra-button which is isIconOnly).

Concerns: One of the largest concerns from a UX perspective is not all icons are going to be approved for standalone use (no text or labels beside them) based on Humans Factors recommendations and Design Standards, only certain icons that have wide/broad understanding can be used by themselves, so having a universal prop that indicates all can be used as standalone might violate Design Standards. We'll need to evaluate further how best to approach it.

sdadn commented 2 years ago

Tech Design 1

Overview

According to https://a11y-101.com/development/svg , the simplest way to make svgs accessible is to use them in an img tag if they are meaningful. An img tag supports the alt property for screenreaders.

Currently, terra-icon works as follows:

attributes = {
    "viewBox":"0 0 48 48",
    "xmlns":"http://www.w3.org/2000/svg",
    "data-name":"Layer 1"
};

<IconBase {...attributes}>
    <path d="M48 21H27V0h-6v21H0v6h21v21h6V27h21z" ></path>
</IconBase>

Which returns the following html:

<svg 
    viewBox="0 0 48 48"
    xmlns="http://www.w3.org/2000/svg" 
    data-name="Layer 1" 
    >
    <path d="M48 21H27V0h-6v21H0v6h21v21h6V27h21z" ></path>
</svg>

In order to meet accessibility standards, the resulting html should be a img tag. Since img and svg have different attributes (e.g. img does not support child nodes), this will change the props for IconBase, resulting in an active change for this story.

Current Props

Prop Type Required Default Description
ariaLabel string optional null String that labels the current element. If aria-label is present, role is site to img and aria-hidden is removed
children node optional null Child nodes
isBidi bool optional false Should the svg mirror when dir=”rtl”
isSpin bool optional false Should the svg spin
height string optional 1em Height of SVG
width string optional 1em Width of SVG
focusable string optional false Focusable attribute

Proposed Props

Prop Type Required Default Description
alt string required "" String that labels the current element. If aria-label is present, role is site to img and aria-hidden is removed
svgSource string required null Svg input for the icon. Can be inline svg or a file
imageType enum optional “informative” Type of icon. Currently supports "decorative" and "infomative"
encoding enum optional "none" “none”: svg file , “utf8”: inline svg as Unicode, “base64": inline svg as base64
isBidi bool optional false Should the svg mirror when dir=”rtl”
isSpin bool optional false Should the svg spin
height string optional 1em Height of SVG
width string optional 1em Width of SVG
focusable string optional false Focusable attribute

This is an active change resulting in a major version bump. children and ariaLabel will be removed in the next major version.

Examples uses

const attributes = {
    isBidi: false,
    iconType: "informative",
    alt: "plus icon",
    encoding: "none" //default value,
    svgSource: "path/to/file.svg"
};

return ( <img src={svgSource} {... other attributes} ></img> );
const attributes = {
    isBidi: false,
    iconType: "informative",
    alt: "plus icon",
    encoding: "utf8"
    svgSource: `<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path d="M48 21H27V0h-6v21H0v6h21v21h6V27h21z"/></svg>`,
};
const generatedSVGSource = `data:image/svg+xml;${encoding},${svgSource}`;

return ( <img  src={generatedSVGSource} {...other attributes}></img> );
const attributes = {
    isBidi: false,
    iconType: "informative",
    alt: "plus icon",
    encoding: "base64"
    svgSource: `PHN2ZyBkYXRhLW5hbWU9IkxheWVyIDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDQ4IDQ4Ij48cGF0aCBkPSJNNDggMjFIMjdWMGgtNnYyMUgwdjZoMjF2MjFoNlYyN2gyMXoiLz48L3N2Zz4=`,
};

const generatedSVGSource = `data:image/svg+xml;${encoding},${svgSource}`;

return ( <img  src={generatedSVGSource} {...other attributes}></img> );

Accessibility

In order to meet accessibility standards, the imageType prop will be used to set the type of the icon as "informative" or "decorative"which will set the attributes of the img so that it will be read/ignored by screenreaders.

if imageType="decorative":

attributes.role = presentation

otherwise

attributes.role = undefined

To Do

sdadn commented 2 years ago

As Tech Design 1 is causing complications with the existing icon coloring logic, it is being dropped for Tech Design 2.

sdadn commented 2 years ago

Tech Design 2

Overview

According to https://www.deque.com/blog/creating-accessible-svgs/ , the simplest and reccommended way to make svgs accessible is to use them in an img tag if they are meaningful. An img tag supports the alt property for screenreaders. However, terra-icon is deigned so that consumers can change the color of non-static icons by simply using the font-color. In order to maintain this feature, deque's alternative recommendation which is to add a title tag to a svg will be used.

Currently, terra-icon works as follows:

attributes = {
    "viewBox":"0 0 48 48",
    "xmlns":"http://www.w3.org/2000/svg",
    "data-name":"Layer 1"
};

<IconBase {...attributes}>
    <path d="M48 21H27V0h-6v21H0v6h21v21h6V27h21z" ></path>
</IconBase>

Which returns the following html:

<svg 
    viewBox="0 0 48 48"
    xmlns="http://www.w3.org/2000/svg" 
    data-name="Layer 1" 
    >
    <path d="M48 21H27V0h-6v21H0v6h21v21h6V27h21z" ></path>
</svg>

In order to meet accessibility standards, the resulting svg should have a title tag like the following:

<svg 
    viewBox="0 0 48 48"
    xmlns="http://www.w3.org/2000/svg" 
    data-name="Layer 1" 
    >
    <title>icon title</title>
    <path d="M48 21H27V0h-6v21H0v6h21v21h6V27h21z" ></path>
</svg>

Solution

The default component will be updated to be meaningful. This is so that consumers will adher to accessibility standards by default. A sub-component IconDecorative will be added for consumers to utilize decorative icons.

Default Meaningful Component

The props for the component will be updated as follows:

Current Props
Prop Type Required Default Description
ariaLabel string optional null String that labels the current element; If aria-label is present, role is site to img and aria-hidden is removed
children node optional null Child nodes
isBidi bool optional false Should the svg mirror when dir=”rtl”
isSpin bool optional false Should the svg spin
height string optional 1em Height of SVG
width string optional 1em Width of SVG
focusable string optional false Focusable attribute
Proposed Props
Prop Type Required Default Description
a11yLabel string required - String that labels the current element
children node optional null Child nodes
isBidi bool optional false Should the svg mirror when dir=”rtl”
isSpin bool optional false Should the svg spin
height string optional 1em Height of SVG
width string optional 1em Width of SVG
focusable string optional false Focusable attribute

This is an active change resulting in a major version bump. children and ariaLabel will be removed in the next major version.

Resulting html

the default iconBase will return the following html

<svg 
    viewBox="0 0 48 48"
    xmlns="http://www.w3.org/2000/svg" 
    data-name="Layer 1" 
    >
    <title>icon title</title>
    <path d="M48 21H27V0h-6v21H0v6h21v21h6V27h21z" ></path>
</svg>

Decorative icon

For a decorative icon, the role is set to presentation with no title prop.

Proposed Props
Prop Type Required Default Description
children node optional null Child nodes
isBidi bool optional false Should the svg mirror when dir=”rtl”
isSpin bool optional false Should the svg spin
height string optional 1em Height of SVG
width string optional 1em Width of SVG
focusable string optional false Focusable attribute
Resulting html
<svg 
    viewBox="0 0 48 48"
    xmlns="http://www.w3.org/2000/svg" 
    data-name="Layer 1" 
    role="presentation"
    >
    <path d="M48 21H27V0h-6v21H0v6h21v21h6V27h21z" ></path>
</svg>