Skip to content

Commit

Permalink
docs(future/Icon): update usage guidelines
Browse files Browse the repository at this point in the history
  • Loading branch information
HeartSquared committed Sep 16, 2024
1 parent 8bd2ecd commit 199b4eb
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Icons should be easily distinguishable and clearly visible against their backgro
Where suitable, color can be used to highlight an icon or reinforce its meaning, such as using green for success or red for errors.

<DosAndDonts>
<DoOrDont story={IconStories.ColorReinforceDo} />
<DoOrDont story={IconStories.ColorPurposefulDo} />
</DosAndDonts>

#### Don't rely on color alone
Expand All @@ -110,7 +110,6 @@ Ensure that icons are distinguishable by varying the icon, fill, or labels. Rely
Overusing icons can create visual clutter and overwhelm users. Use them sparingly to highlight important actions or information.

<DosAndDonts>
<DoOrDont story={IconStories.InterfaceDo} />
<DoOrDont story={IconStories.InterfaceDont} isDont />
</DosAndDonts>

Expand All @@ -119,6 +118,7 @@ Overusing icons can create visual clutter and overwhelm users. Use them sparingl
Icons should support, not replace, text labels, especially for accessibility. Screen readers and other assistive technologies may not always interpret icons correctly.

<DosAndDonts>
<DoOrDont story={IconStories.ImportantInformationDo} />
<DoOrDont story={IconStories.ImportantInformationDont} isDont />
</DosAndDonts>

Expand All @@ -130,6 +130,14 @@ If the icon is interactive, it should have a base, hover, and focus state.
<DoOrDont story={IconStories.InteractiveStatesDo} />
</DosAndDonts>

#### Don't rely on tooltips to covey icon meaning

Important information can be hidden if it's only explained in tooltips, leading to poor user experience. Whenever possible, include a text label or other contextual information alongside the icon to clearly convey its meaning.

<DosAndDonts>
<DoOrDont story={IconStories.TooltipDont} isDont />
</DosAndDonts>

## Default icon set

Whilst you have access to all Material Symbols, the following icons match the default set we have in Figma.
Expand Down
17 changes: 17 additions & 0 deletions packages/components/src/__future__/Icon/_docs/Icon.docs.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.interactiveIcon {
position: relative;
background: none;
padding: 0;
color: var(--color-blue-500);

&:hover {
color: var(--color-blue-400);
}
}

.interactiveIcon:focus::after {
position: absolute;
content: "";
border: var(--border-focus-ring-border-width) solid var(--color-blue-500);
inset: -2px;
}
120 changes: 73 additions & 47 deletions packages/components/src/__future__/Icon/_docs/Icon.docs.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ import { Tag } from "~components/__future__/Tag"
import { StickerSheet } from "~storybook/components/StickerSheet"
import { iconDefaultSet } from "../constants"
import { Icon } from "../index"
import imgInterfaceDo from "./assets/interface-do.png"
import imgInterfaceDont from "./assets/interface-dont.png"
import imgTooltipDont from "./assets/tooltip-dont.png"
import styles from "./Icon.docs.module.css"

const meta = {
title: "Illustrations/Icon/Icon (Future)",
Expand Down Expand Up @@ -216,10 +217,9 @@ export const DefaultIconSet: Story = {

export const ConsistentDo: Story = {
render: () => (
<div>
<Icon name="star" isPresentational />
<Icon name="star" isPresentational isFilled />
</div>
<Text variant="body">
Edit <Icon name="edit" isPresentational />
</Text>
),
}

Expand Down Expand Up @@ -352,12 +352,12 @@ export const ContrastDont: Story = {
),
}

export const ColorReinforceDo: Story = {
export const ColorPurposefulDo: Story = {
render: () => (
<>
<InlineNotification variant="success">Success!</InlineNotification>
<InlineNotification variant="success">Success</InlineNotification>
<InlineNotification variant="warning" noBottomMargin>
Error!
Error
</InlineNotification>
</>
),
Expand All @@ -372,12 +372,7 @@ export const DistinguishDo: Story = {
</div>
<div className="flex items-center gap-4">
<Text variant="body">Selected</Text>
<Icon
name="thumb_up"
isPresentational
isFilled
className="text-blue-500"
/>
<Icon name="thumb_up" isPresentational isFilled />
</div>
</div>
),
Expand All @@ -398,23 +393,54 @@ export const DistinguishDont: Story = {
),
}

export const InterfaceDo: Story = {
export const InterfaceDont: Story = {
render: () => (
<img
src={imgInterfaceDo}
alt="Example of a good interface"
className="w-full"
src={imgInterfaceDont}
alt="Example of a bad interface"
className="block m-auto max-w-[600px]"
/>
),
}

export const InterfaceDont: Story = {
export const ImportantInformationDo: Story = {
render: () => (
<img
src={imgInterfaceDont}
alt="Example of a good interface"
className="w-full"
/>
<TableContainer>
<TableHeader>
<TableRow>
<TableHeaderRowCell
labelText="Flag for review"
sorting="ascending"
width={4 / 12}
/>
<TableHeaderRowCell labelText="Employee" sorting="ascending" />
</TableRow>
</TableHeader>
<TableCard>
<TableRow>
<TableRowCell width={4 / 12}>
<Icon name="flag" alt="Flag" />
</TableRowCell>
<TableRowCell>
<Text tag="div" variant="body">
John Johnson
</Text>
</TableRowCell>
</TableRow>
</TableCard>
<TableCard>
<TableRow>
<TableRowCell width={4 / 12}>
<Icon name="flag" alt="Flag" />
</TableRowCell>
<TableRowCell>
<Text tag="div" variant="body">
Michelle Summer
</Text>
</TableRowCell>
</TableRow>
</TableCard>
</TableContainer>
),
}

Expand Down Expand Up @@ -458,34 +484,24 @@ export const ImportantInformationDont: Story = {
},
}

const MockLink = ({
children,
...props
}: {
children: React.ReactNode
}): JSX.Element => (
// eslint-disable-next-line jsx-a11y/anchor-is-valid
<a
href="#"
className="text-black hover:text-blue-500 focus:text-blue-500 focus:border-1 focus:border-solid focus:border-blue-500 [--icon-vertical-align:text-bottom]"
{...props}
>
{children}
</a>
const InteractiveIcon = (props: Record<string, any>): JSX.Element => (
<button type="button" className={styles.interactiveIcon} {...props}>
<Icon name="info" isPresentational isFilled />
</button>
)

export const InteractiveStatesDo: Story = {
render: () => (
<div className="flex gap-16">
<MockLink>
Base <Icon name="auto_awesome" isPresentational isFilled />
</MockLink>
<MockLink data-sb-pseudo-styles="hover">
Hover <Icon name="auto_awesome" isPresentational isFilled />
</MockLink>
<MockLink data-sb-pseudo-styles="focus">
Focus <Icon name="auto_awesome" isPresentational isFilled />
</MockLink>
<Text variant="body">
Base <InteractiveIcon />
</Text>
<Text variant="body">
Hover <InteractiveIcon data-sb-pseudo-styles="hover" />
</Text>
<Text variant="body">
Focus <InteractiveIcon data-sb-pseudo-styles="focus" />
</Text>
</div>
),
parameters: {
Expand All @@ -496,3 +512,13 @@ export const InteractiveStatesDo: Story = {
},
},
}

export const TooltipDont: Story = {
render: () => (
<img
src={imgTooltipDont}
alt="Example of a bad use of a tooltip on an icon"
className="block m-auto max-w-[600px]"
/>
),
}
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 199b4eb

Please sign in to comment.