@cdx-ui/components 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +24 -0
- package/README.md +2 -0
- package/coverage.svg +1 -1
- package/docs/components/accordion/content.md +538 -0
- package/docs/components/alert/content.md +203 -0
- package/docs/components/alert-dialog/content.md +319 -0
- package/docs/components/avatar/content.md +368 -0
- package/docs/components/avatar/design.md +202 -0
- package/docs/components/badge/content.md +235 -0
- package/docs/components/bottom-sheet/content.md +351 -0
- package/docs/components/bottom-sheet/design.md +249 -0
- package/docs/components/breadcrumbs/content.md +169 -0
- package/docs/components/button/content.md +398 -0
- package/docs/components/button/design.md +258 -0
- package/docs/components/calendar/content.md +137 -0
- package/docs/components/card/content.md +283 -0
- package/docs/components/carousel/content.md +416 -0
- package/docs/components/checkbox/content.md +236 -0
- package/docs/components/checkbox/design.md +214 -0
- package/docs/components/chip/content.md +439 -0
- package/docs/components/chip/design.md +418 -0
- package/docs/components/color-area/content.md +86 -0
- package/docs/components/color-field/content.md +134 -0
- package/docs/components/color-picker/content.md +208 -0
- package/docs/components/color-slider/content.md +120 -0
- package/docs/components/color-swatch/content.md +64 -0
- package/docs/components/color-swatch-picker/content.md +126 -0
- package/docs/components/content.md +97 -0
- package/docs/components/currency-input/content.md +205 -0
- package/docs/components/data-grid/content.md +522 -0
- package/docs/components/date-field/content.md +147 -0
- package/docs/components/date-picker/content.md +360 -0
- package/docs/components/date-range-picker/content.md +301 -0
- package/docs/components/date-time-field/content.md +157 -0
- package/docs/components/date-time-list/content.md +105 -0
- package/docs/components/date-time-picker/content.md +272 -0
- package/docs/components/dialog/content.md +436 -0
- package/docs/components/dialog/design.md +192 -0
- package/docs/components/divider/content.md +112 -0
- package/docs/components/drawer/content.md +436 -0
- package/docs/components/field/content.md +277 -0
- package/docs/components/form/content.md +62 -0
- package/docs/components/full-screen-dialog/content.md +881 -0
- package/docs/components/heading/content.md +55 -0
- package/docs/components/icon/content.md +190 -0
- package/docs/components/icon-button/content.md +200 -0
- package/docs/components/icon-button/design.md +165 -0
- package/docs/components/image/content.md +104 -0
- package/docs/components/input/content.md +281 -0
- package/docs/components/input/design.md +389 -0
- package/docs/components/insurance-disclosure/content.md +103 -0
- package/docs/components/link/content.md +180 -0
- package/docs/components/link/design.md +160 -0
- package/docs/components/list-item/content.md +695 -0
- package/docs/components/menu/content.md +1247 -0
- package/docs/components/month-calendar/content.md +84 -0
- package/docs/components/month-picker/content.md +273 -0
- package/docs/components/otp-input/content.md +327 -0
- package/docs/components/progress-bar/content.md +87 -0
- package/docs/components/progress-circle/content.md +176 -0
- package/docs/components/progress-segmented/content.md +119 -0
- package/docs/components/quick-action-button/content.md +154 -0
- package/docs/components/quick-action-button/design.md +170 -0
- package/docs/components/radio/content.md +224 -0
- package/docs/components/range-calendar/content.md +123 -0
- package/docs/components/reorderable-list/content.md +309 -0
- package/docs/components/scoped-theme/content.md +47 -0
- package/docs/components/scroll-shadow/content.md +686 -0
- package/docs/components/select/content.md +400 -0
- package/docs/components/select/design.md +301 -0
- package/docs/components/skeleton/content.md +103 -0
- package/docs/components/slider/content.md +423 -0
- package/docs/components/stack/content.md +161 -0
- package/docs/components/switch/content.md +150 -0
- package/docs/components/switch/design.md +208 -0
- package/docs/components/table/content.md +548 -0
- package/docs/components/table-pagination/content.md +177 -0
- package/docs/components/tabs/content.md +292 -0
- package/docs/components/text/content.md +142 -0
- package/docs/components/textarea/content.md +222 -0
- package/docs/components/tile/content.md +703 -0
- package/docs/components/toast/content.md +456 -0
- package/docs/components/toggle-button/content.md +505 -0
- package/docs/components/tooltip/content.md +350 -0
- package/docs/components/virtualized-list/content.md +250 -0
- package/docs/foundations/content.md +9 -0
- package/docs/foundations/expressions/icons/content.md +19 -0
- package/docs/foundations/styles/tokens/all-tokens/content.md +192 -0
- package/docs/foundations/styles/tokens/what-are-tokens/content.md +33 -0
- package/docs/foundations/styles/tokens/what-are-tokens/design.md +33 -0
- package/docs/getting-started/content.md +4 -0
- package/docs/getting-started/designers/content.md +13 -0
- package/docs/getting-started/designers/design.md +13 -0
- package/docs/getting-started/developers/accessibility/content.md +31 -0
- package/docs/getting-started/developers/content.md +612 -0
- package/docs/getting-started/developers/styling/content.md +193 -0
- package/docs/llms.txt +193 -0
- package/docs/patterns/account-management/content.md +75 -0
- package/docs/patterns/authentication/content.md +52 -0
- package/docs/patterns/content.md +10 -0
- package/docs/patterns/dashboard/content.md +39 -0
- package/docs/patterns/empty-states/content.md +31 -0
- package/docs/patterns/forms/content.md +109 -0
- package/docs/patterns/onboarding/content.md +69 -0
- package/docs/patterns/payments/content.md +35 -0
- package/docs/patterns/settings/content.md +72 -0
- package/docs/resources/content.md +9 -0
- package/docs/resources/figma-libraries/content.md +42 -0
- package/docs/resources/release-notes/0.0.1-beta.118/content.md +27 -0
- package/docs/resources/release-notes/0.0.1-beta.122/content.md +21 -0
- package/docs/resources/release-notes/0.0.1-beta.124/content.md +16 -0
- package/docs/resources/release-notes/0.0.1-beta.126/content.md +10 -0
- package/docs/resources/release-notes/0.0.1-beta.127/content.md +14 -0
- package/docs/resources/release-notes/0.0.1-beta.128/content.md +9 -0
- package/docs/resources/release-notes/0.0.1-beta.129/content.md +18 -0
- package/docs/resources/release-notes/0.0.1-beta.130/content.md +18 -0
- package/docs/resources/release-notes/0.0.1-beta.133/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.134/content.md +17 -0
- package/docs/resources/release-notes/0.0.1-beta.136/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.137/content.md +10 -0
- package/docs/resources/release-notes/0.0.1-beta.138/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.139/content.md +13 -0
- package/docs/resources/release-notes/0.0.1-beta.140/content.md +26 -0
- package/docs/resources/release-notes/0.0.1-beta.141/content.md +63 -0
- package/docs/resources/release-notes/0.0.1-beta.142/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.143/content.md +12 -0
- package/docs/resources/release-notes/0.0.1-beta.144/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.145/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.147/content.md +10 -0
- package/docs/resources/release-notes/0.0.1-beta.149/content.md +10 -0
- package/docs/resources/release-notes/0.0.1-beta.150/content.md +13 -0
- package/docs/resources/release-notes/0.0.1-beta.152/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.154/content.md +15 -0
- package/docs/resources/release-notes/0.0.1-beta.156/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.158/content.md +9 -0
- package/docs/resources/release-notes/0.0.1-beta.159/content.md +11 -0
- package/docs/resources/release-notes/0.0.1-beta.160/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.161/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.163/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.164/content.md +9 -0
- package/docs/resources/release-notes/0.0.1-beta.166/content.md +17 -0
- package/docs/resources/release-notes/0.0.1-beta.167/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.168/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.169/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.171/content.md +16 -0
- package/docs/resources/release-notes/0.0.1-beta.172/content.md +24 -0
- package/docs/resources/release-notes/0.0.1-beta.173/content.md +15 -0
- package/docs/resources/release-notes/0.0.1-beta.174/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.176/content.md +32 -0
- package/docs/resources/release-notes/0.0.1-beta.179/content.md +11 -0
- package/docs/resources/release-notes/0.0.1-beta.182/content.md +13 -0
- package/docs/resources/release-notes/0.0.1-beta.185/content.md +7 -0
- package/docs/resources/release-notes/0.0.1-beta.187/content.md +27 -0
- package/docs/resources/release-notes/0.1.1/content.md +23 -0
- package/docs/resources/release-notes/0.1.2/content.md +7 -0
- package/docs/resources/release-notes/0.1.4/content.md +19 -0
- package/docs/resources/release-notes/0.1.5/content.md +7 -0
- package/docs/resources/release-notes/0.1.6/content.md +7 -0
- package/docs/resources/release-notes/0.2.0/content.md +31 -0
- package/docs/resources/release-notes/0.2.1/content.md +17 -0
- package/docs/resources/release-notes/0.2.2/content.md +11 -0
- package/docs/resources/release-notes/0.2.3/content.md +15 -0
- package/docs/resources/release-notes/content.md +64 -0
- package/lib/commonjs/components/DateTimeList/index.js +11 -26
- package/lib/commonjs/components/DateTimeList/index.js.map +1 -1
- package/lib/commonjs/components/DateTimeList/styles.js +2 -12
- package/lib/commonjs/components/DateTimeList/styles.js.map +1 -1
- package/lib/commonjs/components/ListItem/index.js.map +1 -1
- package/lib/commonjs/components/ListItem/styles.js +2 -1
- package/lib/commonjs/components/ListItem/styles.js.map +1 -1
- package/lib/commonjs/components/Menu/index.js +11 -5
- package/lib/commonjs/components/Menu/index.js.map +1 -1
- package/lib/commonjs/components/ScrollShadow/gradient.js +29 -0
- package/lib/commonjs/components/ScrollShadow/gradient.js.map +1 -0
- package/lib/commonjs/components/ScrollShadow/index.js +171 -44
- package/lib/commonjs/components/ScrollShadow/index.js.map +1 -1
- package/lib/commonjs/components/ScrollShadow/styles.js +58 -14
- package/lib/commonjs/components/ScrollShadow/styles.js.map +1 -1
- package/lib/commonjs/components/ScrollShadow/useComposedScrollHandler.js +63 -0
- package/lib/commonjs/components/ScrollShadow/useComposedScrollHandler.js.map +1 -0
- package/lib/commonjs/components/ScrollShadow/useScrollShadow.js +48 -8
- package/lib/commonjs/components/ScrollShadow/useScrollShadow.js.map +1 -1
- package/lib/commonjs/components/Tabs/index.js +16 -23
- package/lib/commonjs/components/Tabs/index.js.map +1 -1
- package/lib/commonjs/components/Tabs/styles.js +1 -10
- package/lib/commonjs/components/Tabs/styles.js.map +1 -1
- package/lib/commonjs/figma/ListItem.SectionHeader.figma.js +20 -5
- package/lib/commonjs/figma/ListItem.SectionHeader.figma.js.map +1 -1
- package/lib/module/components/DateTimeList/index.js +12 -27
- package/lib/module/components/DateTimeList/index.js.map +1 -1
- package/lib/module/components/DateTimeList/styles.js +1 -11
- package/lib/module/components/DateTimeList/styles.js.map +1 -1
- package/lib/module/components/ListItem/index.js.map +1 -1
- package/lib/module/components/ListItem/styles.js +2 -1
- package/lib/module/components/ListItem/styles.js.map +1 -1
- package/lib/module/components/Menu/index.js +11 -5
- package/lib/module/components/Menu/index.js.map +1 -1
- package/lib/module/components/ScrollShadow/gradient.js +24 -0
- package/lib/module/components/ScrollShadow/gradient.js.map +1 -0
- package/lib/module/components/ScrollShadow/index.js +170 -48
- package/lib/module/components/ScrollShadow/index.js.map +1 -1
- package/lib/module/components/ScrollShadow/styles.js +57 -13
- package/lib/module/components/ScrollShadow/styles.js.map +1 -1
- package/lib/module/components/ScrollShadow/useComposedScrollHandler.js +57 -0
- package/lib/module/components/ScrollShadow/useComposedScrollHandler.js.map +1 -0
- package/lib/module/components/ScrollShadow/useScrollShadow.js +46 -8
- package/lib/module/components/ScrollShadow/useScrollShadow.js.map +1 -1
- package/lib/module/components/Tabs/index.js +17 -24
- package/lib/module/components/Tabs/index.js.map +1 -1
- package/lib/module/components/Tabs/styles.js +0 -9
- package/lib/module/components/Tabs/styles.js.map +1 -1
- package/lib/module/figma/ListItem.SectionHeader.figma.js +20 -5
- package/lib/module/figma/ListItem.SectionHeader.figma.js.map +1 -1
- package/lib/typescript/components/DateTimeList/index.d.ts.map +1 -1
- package/lib/typescript/components/DateTimeList/styles.d.ts +1 -4
- package/lib/typescript/components/DateTimeList/styles.d.ts.map +1 -1
- package/lib/typescript/components/ListItem/index.d.ts +5 -4
- package/lib/typescript/components/ListItem/index.d.ts.map +1 -1
- package/lib/typescript/components/ListItem/styles.d.ts +1 -1
- package/lib/typescript/components/ListItem/styles.d.ts.map +1 -1
- package/lib/typescript/components/Menu/index.d.ts.map +1 -1
- package/lib/typescript/components/ScrollShadow/gradient.d.ts +7 -0
- package/lib/typescript/components/ScrollShadow/gradient.d.ts.map +1 -0
- package/lib/typescript/components/ScrollShadow/index.d.ts +57 -15
- package/lib/typescript/components/ScrollShadow/index.d.ts.map +1 -1
- package/lib/typescript/components/ScrollShadow/styles.d.ts +8 -2
- package/lib/typescript/components/ScrollShadow/styles.d.ts.map +1 -1
- package/lib/typescript/components/ScrollShadow/useComposedScrollHandler.d.ts +13 -0
- package/lib/typescript/components/ScrollShadow/useComposedScrollHandler.d.ts.map +1 -0
- package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts +15 -2
- package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts.map +1 -1
- package/lib/typescript/components/Tabs/index.d.ts.map +1 -1
- package/lib/typescript/components/Tabs/styles.d.ts +0 -7
- package/lib/typescript/components/Tabs/styles.d.ts.map +1 -1
- package/lib/typescript/figma/ListItem.SectionHeader.figma.d.ts.map +1 -1
- package/package.json +8 -6
- package/src/components/DateTimeList/index.tsx +13 -26
- package/src/components/DateTimeList/styles.ts +1 -10
- package/src/components/ListItem/index.tsx +5 -4
- package/src/components/ListItem/styles.ts +1 -0
- package/src/components/Menu/index.tsx +11 -8
- package/src/components/ScrollShadow/gradient.ts +48 -0
- package/src/components/ScrollShadow/index.tsx +300 -69
- package/src/components/ScrollShadow/styles.ts +45 -28
- package/src/components/ScrollShadow/useComposedScrollHandler.ts +58 -0
- package/src/components/ScrollShadow/useScrollShadow.ts +72 -10
- package/src/components/Tabs/index.tsx +25 -35
- package/src/components/Tabs/styles.ts +0 -9
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Heading (https://design.candescent.com/docs/components/heading)
|
|
2
|
+
|
|
3
|
+
Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--React-Native-Components?node-id=399-3385), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/content-heading--default)
|
|
4
|
+
|
|
5
|
+
`Heading` pairs Forge UI heading styles with the corresponding accessible heading level.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Heading } from '@cdx-ui/components';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Basic
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { Heading } from '@cdx-ui/components';
|
|
15
|
+
|
|
16
|
+
export default function HeadingBasicDemo() {
|
|
17
|
+
return <Heading>Account overview</Heading>;
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Sizes
|
|
22
|
+
|
|
23
|
+
Each `size` maps to a heading level: `xl` to level 1, `lg` to level 2, through `xs` at level 5.
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import { Box, Heading, type HeadingProps } from '@cdx-ui/components';
|
|
27
|
+
|
|
28
|
+
const SIZES = ['xs', 'sm', 'md', 'lg', 'xl'] as const satisfies readonly NonNullable<
|
|
29
|
+
HeadingProps['size']
|
|
30
|
+
>[];
|
|
31
|
+
|
|
32
|
+
export default function HeadingSizesDemo() {
|
|
33
|
+
return (
|
|
34
|
+
<Box className="gap-4">
|
|
35
|
+
{SIZES.map((size) => (
|
|
36
|
+
<Heading key={size} size={size}>
|
|
37
|
+
{size} heading
|
|
38
|
+
</Heading>
|
|
39
|
+
))}
|
|
40
|
+
</Box>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## API
|
|
46
|
+
|
|
47
|
+
### Heading
|
|
48
|
+
|
|
49
|
+
| Prop | Type | Default | Description |
|
|
50
|
+
| --- | --- | --- | --- |
|
|
51
|
+
| `className?` | `string` | — | Additional Uniwind/Tailwind classes, merged after the heading's own styles. |
|
|
52
|
+
| `children?` | `React.ReactNode` | — | Heading text. |
|
|
53
|
+
| `size?` | `'xl' \| 'lg' \| 'md' \| 'sm' \| 'xs' \| null` | `'lg'` | Heading typography style. Also sets the accessibility heading level: `xl` is level 1 through `xs` at level 5. |
|
|
54
|
+
|
|
55
|
+
Inherits all [`TextProps`](https://reactnative.dev/docs/text#props). The default `size` is `lg`, which uses heading level 2.
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Icon (https://design.candescent.com/docs/components/icon)
|
|
2
|
+
|
|
3
|
+
Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--React-Native-Components?node-id=397-33), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/content-icon--default)
|
|
4
|
+
|
|
5
|
+
A wrapper around Forge UI icons that adds Uniwind `className` support and themed defaults.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Icon } from '@cdx-ui/components';
|
|
9
|
+
import { Home } from '@cdx-ui/icons';
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Browse the complete set of available glyphs in the [icon explorer](https://design.candescent.com/docs/foundations/expressions/icons/content.md).
|
|
13
|
+
|
|
14
|
+
## Basic
|
|
15
|
+
|
|
16
|
+
Pass an icon component from `@cdx-ui/icons` to the required `as` prop.
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
import { Icon } from '@cdx-ui/components';
|
|
20
|
+
import { Home } from '@cdx-ui/icons';
|
|
21
|
+
|
|
22
|
+
export default function IconBasicDemo() {
|
|
23
|
+
return <Icon as={Home} className="size-6" accessibilityLabel="Home" />;
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Sizes
|
|
28
|
+
|
|
29
|
+
Use `size-*` utilities to set both SVG dimensions. The default `size-5` renders at 20 pixels.
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
import { Box, Icon, Text } from '@cdx-ui/components';
|
|
33
|
+
import { Home } from '@cdx-ui/icons';
|
|
34
|
+
|
|
35
|
+
export default function IconSizesDemo() {
|
|
36
|
+
return (
|
|
37
|
+
<Box className="flex-row items-end gap-5">
|
|
38
|
+
<Box className="items-center gap-2">
|
|
39
|
+
<Icon as={Home} className="size-4" />
|
|
40
|
+
<Text size="sm" color="secondary">
|
|
41
|
+
16
|
|
42
|
+
</Text>
|
|
43
|
+
</Box>
|
|
44
|
+
<Box className="items-center gap-2">
|
|
45
|
+
<Icon as={Home} className="size-5" />
|
|
46
|
+
<Text size="sm" color="secondary">
|
|
47
|
+
20
|
|
48
|
+
</Text>
|
|
49
|
+
</Box>
|
|
50
|
+
<Box className="items-center gap-2">
|
|
51
|
+
<Icon as={Home} className="size-6" />
|
|
52
|
+
<Text size="sm" color="secondary">
|
|
53
|
+
24
|
|
54
|
+
</Text>
|
|
55
|
+
</Box>
|
|
56
|
+
<Box className="items-center gap-2">
|
|
57
|
+
<Icon as={Home} className="size-8" />
|
|
58
|
+
<Text size="sm" color="secondary">
|
|
59
|
+
32
|
|
60
|
+
</Text>
|
|
61
|
+
</Box>
|
|
62
|
+
<Box className="items-center gap-2">
|
|
63
|
+
<Icon as={Home} className="size-10" />
|
|
64
|
+
<Text size="sm" color="secondary">
|
|
65
|
+
40
|
|
66
|
+
</Text>
|
|
67
|
+
</Box>
|
|
68
|
+
</Box>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Colors
|
|
74
|
+
|
|
75
|
+
Use `color` to select a semantic content color. It maps to the matching theme-aware `text-content-*` token, so prefer it over a color class.
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
import { Box, Icon, Text, type IconProps } from '@cdx-ui/components';
|
|
79
|
+
import { Favorite } from '@cdx-ui/icons';
|
|
80
|
+
|
|
81
|
+
const COLORS = [
|
|
82
|
+
'primary',
|
|
83
|
+
'secondary',
|
|
84
|
+
'tertiary',
|
|
85
|
+
'action',
|
|
86
|
+
'danger',
|
|
87
|
+
'warning',
|
|
88
|
+
'success',
|
|
89
|
+
'info',
|
|
90
|
+
] as const satisfies readonly NonNullable<IconProps['color']>[];
|
|
91
|
+
|
|
92
|
+
export default function IconColorsDemo() {
|
|
93
|
+
return (
|
|
94
|
+
<Box className="flex-row flex-wrap gap-5">
|
|
95
|
+
{COLORS.map((color) => (
|
|
96
|
+
<Box key={color} className="items-center gap-2">
|
|
97
|
+
<Icon as={Favorite} color={color} className="size-6" />
|
|
98
|
+
<Text size="sm" color="secondary">
|
|
99
|
+
{color}
|
|
100
|
+
</Text>
|
|
101
|
+
</Box>
|
|
102
|
+
))}
|
|
103
|
+
</Box>
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Outlined and filled
|
|
109
|
+
|
|
110
|
+
Icons render their outlined variant by default. Set `filled` when the selected icon provides filled path data; icons without a filled variant fall back to their outline.
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
import { Box, Icon, Text } from '@cdx-ui/components';
|
|
114
|
+
import { Favorite } from '@cdx-ui/icons';
|
|
115
|
+
|
|
116
|
+
export default function IconFilledDemo() {
|
|
117
|
+
return (
|
|
118
|
+
<Box className="flex-row gap-8">
|
|
119
|
+
<Box className="items-center gap-2">
|
|
120
|
+
<Icon as={Favorite} color="action" className="size-8" />
|
|
121
|
+
<Text size="sm" color="secondary">
|
|
122
|
+
Outlined
|
|
123
|
+
</Text>
|
|
124
|
+
</Box>
|
|
125
|
+
<Box className="items-center gap-2">
|
|
126
|
+
<Icon as={Favorite} filled color="action" className="size-8" />
|
|
127
|
+
<Text size="sm" color="secondary">
|
|
128
|
+
Filled
|
|
129
|
+
</Text>
|
|
130
|
+
</Box>
|
|
131
|
+
</Box>
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Accessibility
|
|
137
|
+
|
|
138
|
+
Omit `accessibilityLabel` when an icon is decorative or repeats adjacent text. Provide a concise label when the icon conveys information that is not available elsewhere.
|
|
139
|
+
|
|
140
|
+
```tsx
|
|
141
|
+
import { Box, Icon, Text } from '@cdx-ui/components';
|
|
142
|
+
import { ArrowForward, Lock } from '@cdx-ui/icons';
|
|
143
|
+
|
|
144
|
+
export default function IconAccessibilityDemo() {
|
|
145
|
+
return (
|
|
146
|
+
<Box className="gap-5">
|
|
147
|
+
<Box className="flex-row items-center gap-3">
|
|
148
|
+
<Icon as={Lock} color="success" className="size-6" accessibilityLabel="Account protected" />
|
|
149
|
+
<Text>Informative icon with a screen reader label</Text>
|
|
150
|
+
</Box>
|
|
151
|
+
<Box className="flex-row items-center gap-3">
|
|
152
|
+
<Icon as={ArrowForward} color="secondary" className="size-6" />
|
|
153
|
+
<Text>Decorative icon next to visible text</Text>
|
|
154
|
+
</Box>
|
|
155
|
+
</Box>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## API
|
|
161
|
+
|
|
162
|
+
### Icon
|
|
163
|
+
|
|
164
|
+
Renders the Forge icon supplied through `as`. `className` supports Uniwind utilities for dimensions, spacing, and positioning.
|
|
165
|
+
|
|
166
|
+
| Prop | Type | Default | Description |
|
|
167
|
+
| --- | --- | --- | --- |
|
|
168
|
+
| `className?` | `string` | — | Utility classes for size (`size-*`) and placement, merged after the defaults. |
|
|
169
|
+
| `children?` | `React.ReactNode` | — | — |
|
|
170
|
+
| `filled?` | `boolean` | — | When `true`, renders the filled variant of the icon (if available). Defaults to `false` (outlined). |
|
|
171
|
+
| `size?` | `string \| number` | — | Width and height of the icon, in pixels or any SVG length. The bare icon renders at 24 when omitted. |
|
|
172
|
+
| `data-testid?` | `string` | — | Test identifier forwarded to the rendered SVG. |
|
|
173
|
+
| `as` | `ForgeIcon` | — | The `@cdx-ui/icons` component to render. |
|
|
174
|
+
|
|
175
|
+
Inherits all `ForgeIconProps` except the SVG `color`: [`SvgProps`](https://github.com/software-mansion/react-native-svg#common-props) plus `filled`, `size`, and `accessibilityLabel`.
|
|
176
|
+
|
|
177
|
+
## Defaults and styling
|
|
178
|
+
|
|
179
|
+
- `color` defaults to `primary`.
|
|
180
|
+
- A raw `color` value, such as a hex string, is deprecated. It is passed to the SVG unchanged and logs a one-time warning in development. Use a semantic color instead.
|
|
181
|
+
- `className` defaults to `size-5 shrink-0`, so an icon keeps its size in a row of text on web.
|
|
182
|
+
- Consumer classes are merged after the defaults, so `size-*` and `shrink` utilities override them.
|
|
183
|
+
- The inherited `size` prop can set the SVG dimensions directly when a `size-*` class is not appropriate.
|
|
184
|
+
- `filled` defaults to `false`.
|
|
185
|
+
|
|
186
|
+
## Accessibility
|
|
187
|
+
|
|
188
|
+
- Without `accessibilityLabel`, the underlying SVG is decorative and hidden from assistive technology.
|
|
189
|
+
- With `accessibilityLabel`, the SVG is exposed with the image role and announced using that label.
|
|
190
|
+
- `Icon` is not interactive. Use `IconButton` for an icon-only action, or place a decorative icon inside another control that already has an accessible name.
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# Icon Button (https://design.candescent.com/docs/components/icon-button)
|
|
2
|
+
|
|
3
|
+
Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--React-Native-Components?node-id=427-5235), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/actions-iconbutton--default)
|
|
4
|
+
|
|
5
|
+
A single-icon button for compact actions in toolbars, table rows, and inline controls.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { IconButton } from '@cdx-ui/components';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Variants
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { IconButton, Box } from '@cdx-ui/components';
|
|
15
|
+
import { ArrowCircleUp } from '@cdx-ui/icons';
|
|
16
|
+
|
|
17
|
+
export default function IconButtonVariantsDemo() {
|
|
18
|
+
return (
|
|
19
|
+
<Box className="flex-row gap-4">
|
|
20
|
+
<IconButton as={ArrowCircleUp} variant="solid" accessibilityLabel="Solid" />
|
|
21
|
+
<IconButton as={ArrowCircleUp} variant="subtle" accessibilityLabel="Subtle" />
|
|
22
|
+
<IconButton as={ArrowCircleUp} variant="ghost" accessibilityLabel="Ghost" />
|
|
23
|
+
</Box>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Solid
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import { IconButton, Box } from '@cdx-ui/components';
|
|
32
|
+
import { ArrowCircleUp } from '@cdx-ui/icons';
|
|
33
|
+
|
|
34
|
+
export default function IconButtonSolidDemo() {
|
|
35
|
+
return (
|
|
36
|
+
<Box className="flex-row gap-4">
|
|
37
|
+
<IconButton as={ArrowCircleUp} variant="solid" color="neutral" accessibilityLabel="Neutral" />
|
|
38
|
+
<IconButton as={ArrowCircleUp} variant="solid" color="action" accessibilityLabel="Action" />
|
|
39
|
+
<IconButton as={ArrowCircleUp} variant="solid" color="danger" accessibilityLabel="Danger" />
|
|
40
|
+
</Box>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Subtle
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { IconButton, Box } from '@cdx-ui/components';
|
|
49
|
+
import { ArrowCircleUp } from '@cdx-ui/icons';
|
|
50
|
+
|
|
51
|
+
export default function IconButtonSubtleDemo() {
|
|
52
|
+
return (
|
|
53
|
+
<Box className="flex-row gap-4">
|
|
54
|
+
<IconButton
|
|
55
|
+
as={ArrowCircleUp}
|
|
56
|
+
variant="subtle"
|
|
57
|
+
color="neutral"
|
|
58
|
+
accessibilityLabel="Neutral"
|
|
59
|
+
/>
|
|
60
|
+
<IconButton as={ArrowCircleUp} variant="subtle" color="action" accessibilityLabel="Action" />
|
|
61
|
+
<IconButton as={ArrowCircleUp} variant="subtle" color="danger" accessibilityLabel="Danger" />
|
|
62
|
+
</Box>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Ghost
|
|
68
|
+
|
|
69
|
+
```tsx
|
|
70
|
+
import { IconButton, Box } from '@cdx-ui/components';
|
|
71
|
+
import { ArrowCircleUp } from '@cdx-ui/icons';
|
|
72
|
+
|
|
73
|
+
export default function IconButtonGhostDemo() {
|
|
74
|
+
return (
|
|
75
|
+
<Box className="flex-row gap-4">
|
|
76
|
+
<IconButton as={ArrowCircleUp} variant="ghost" color="neutral" accessibilityLabel="Neutral" />
|
|
77
|
+
<IconButton as={ArrowCircleUp} variant="ghost" color="action" accessibilityLabel="Action" />
|
|
78
|
+
<IconButton as={ArrowCircleUp} variant="ghost" color="danger" accessibilityLabel="Danger" />
|
|
79
|
+
</Box>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Colors
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import { IconButton, Box } from '@cdx-ui/components';
|
|
88
|
+
import { ArrowCircleUp } from '@cdx-ui/icons';
|
|
89
|
+
|
|
90
|
+
export default function IconButtonColorsDemo() {
|
|
91
|
+
return (
|
|
92
|
+
<Box className="flex-row gap-4">
|
|
93
|
+
<IconButton as={ArrowCircleUp} color="neutral" accessibilityLabel="Neutral" />
|
|
94
|
+
<IconButton as={ArrowCircleUp} color="action" accessibilityLabel="Action" />
|
|
95
|
+
<IconButton as={ArrowCircleUp} color="danger" accessibilityLabel="Danger" />
|
|
96
|
+
</Box>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Sizes
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
import { IconButton, Box } from '@cdx-ui/components';
|
|
105
|
+
import { ArrowCircleUp } from '@cdx-ui/icons';
|
|
106
|
+
|
|
107
|
+
export default function IconButtonSizesDemo() {
|
|
108
|
+
return (
|
|
109
|
+
<Box className="flex-row items-center gap-4">
|
|
110
|
+
<IconButton as={ArrowCircleUp} size="default" accessibilityLabel="Default size" />
|
|
111
|
+
<IconButton as={ArrowCircleUp} size="small" accessibilityLabel="Small size" />
|
|
112
|
+
</Box>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Disabled
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
import { IconButton, Box } from '@cdx-ui/components';
|
|
121
|
+
import { ArrowCircleUp } from '@cdx-ui/icons';
|
|
122
|
+
|
|
123
|
+
export default function IconButtonDisabledDemo() {
|
|
124
|
+
return (
|
|
125
|
+
<Box className="flex-row gap-4">
|
|
126
|
+
<IconButton
|
|
127
|
+
as={ArrowCircleUp}
|
|
128
|
+
variant="solid"
|
|
129
|
+
color="action"
|
|
130
|
+
isDisabled
|
|
131
|
+
accessibilityLabel="Disabled solid"
|
|
132
|
+
/>
|
|
133
|
+
<IconButton
|
|
134
|
+
as={ArrowCircleUp}
|
|
135
|
+
variant="subtle"
|
|
136
|
+
color="action"
|
|
137
|
+
isDisabled
|
|
138
|
+
accessibilityLabel="Disabled subtle"
|
|
139
|
+
/>
|
|
140
|
+
<IconButton
|
|
141
|
+
as={ArrowCircleUp}
|
|
142
|
+
variant="ghost"
|
|
143
|
+
color="action"
|
|
144
|
+
isDisabled
|
|
145
|
+
accessibilityLabel="Disabled ghost"
|
|
146
|
+
/>
|
|
147
|
+
</Box>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## As link
|
|
153
|
+
|
|
154
|
+
Use `Link` with `asChild` to merge navigation behavior onto the icon button.
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
import { IconButton, Link } from '@cdx-ui/components';
|
|
158
|
+
import { ArrowCircleUp } from '@cdx-ui/icons';
|
|
159
|
+
|
|
160
|
+
export default function IconButtonAsLinkDemo() {
|
|
161
|
+
return (
|
|
162
|
+
<Link href="https://example.com" asChild webProps={{ target: '_blank', rel: 'noopener' }}>
|
|
163
|
+
<IconButton as={ArrowCircleUp} accessibilityLabel="Open link" />
|
|
164
|
+
</Link>
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## API
|
|
170
|
+
|
|
171
|
+
### IconButton
|
|
172
|
+
|
|
173
|
+
| Prop | Type | Default | Description |
|
|
174
|
+
| --- | --- | --- | --- |
|
|
175
|
+
| `className?` | `string` | — | — |
|
|
176
|
+
| `children?` | `React.ReactNode \| ((state: PressableStateCallbackType) => React.ReactNode)` | — | Either children or a render prop that receives a boolean reflecting whether the component is currently pressed. |
|
|
177
|
+
| `size?` | `'default' \| 'small' \| null` | — | — |
|
|
178
|
+
| `variant?` | `'solid' \| 'subtle' \| 'ghost' \| 'tint'` | `'solid'` | Visual style variant. |
|
|
179
|
+
| `color?` | `'neutral' \| 'action' \| 'danger' \| null` | — | — |
|
|
180
|
+
| `as` | `ForgeIcon` | — | Forge icon component to render (icon-only control). |
|
|
181
|
+
| `iconClassName?` | `string` | — | Passed through to the underlying `Icon`. |
|
|
182
|
+
| `isDisabled?` | `boolean` | — | If true, the button will be disabled. |
|
|
183
|
+
|
|
184
|
+
Inherits all [`PressableProps`](https://reactnative.dev/docs/pressable#props) (including `onPress`).
|
|
185
|
+
|
|
186
|
+
## Accessibility
|
|
187
|
+
|
|
188
|
+
Because there is no visible text label, every `IconButton` **must** have an explicit `accessibilityLabel` for screen readers.
|
|
189
|
+
|
|
190
|
+
| Attribute | Value |
|
|
191
|
+
| -------------------- | ------------------------------------------------------------- |
|
|
192
|
+
| `accessibilityRole` | `button` (default) |
|
|
193
|
+
| `accessibilityLabel` | **Required** — describes the action (e.g., "Close", "Delete") |
|
|
194
|
+
|
|
195
|
+
## When to use
|
|
196
|
+
|
|
197
|
+
| Use `Button` when… | Use `IconButton` when… |
|
|
198
|
+
| ---------------------------------------------------- | ------------------------------------------------------------------ |
|
|
199
|
+
| The action needs a visible text label | The icon alone communicates the action |
|
|
200
|
+
| An icon should sit beside that label (`Button.Icon`) | The control stands alone, such as a toolbar action or close button |
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Icon Button — Design (https://design.candescent.com/docs/components/icon-button)
|
|
2
|
+
|
|
3
|
+
## Usage
|
|
4
|
+
|
|
5
|
+
**Common alternative names**: Icon-only button
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## **Anatomy**
|
|
10
|
+
|
|
11
|
+
**Anatomy\_icon-button**
|
|
12
|
+
|
|
13
|
+
1. **Icon**: A single graphic that represents the icon button’s action. Follow the icon affordance guidelines below.
|
|
14
|
+
2. **Outline (optional):** A visible border that defines the icon button’s shape and boundary, helping it stand out against the background while maintaining a lightweight visual presence.
|
|
15
|
+
3. **State layer**: A translucent background color that appears when the icon button is hovered over or focused on.
|
|
16
|
+
|
|
17
|
+
### Variant
|
|
18
|
+
|
|
19
|
+
Icon buttons are available in 2 variants: **solid** and **ghost**.
|
|
20
|
+
|
|
21
|
+
- **Outline**
|
|
22
|
+
|
|
23
|
+
Medium‑emphasis icon buttons used for actions that are important but not the primary action. The outline provides clear affordance while keeping visual weight lower than primary controls.
|
|
24
|
+
- **Ghost**
|
|
25
|
+
|
|
26
|
+
Low‑emphasis icon buttons used for secondary or supporting actions. With no outline, this variant relies on placement and state feedback.
|
|
27
|
+
|
|
28
|
+
### **Size**
|
|
29
|
+
|
|
30
|
+
Icon Buttons are available in 2 sizes: **Default** and **Small**. Size should be considered for visual balance and user focus; larger buttons will draw greater attention.
|
|
31
|
+
|
|
32
|
+
- **size: default**
|
|
33
|
+
|
|
34
|
+
Default icon buttons have a icon size of 24x24 px, plus 10 px of padding, resulting in a 44x44 px icon button.
|
|
35
|
+
- **size: small**
|
|
36
|
+
|
|
37
|
+
Small icon buttons have a default icon size of 20x20 px, plus 6 px of padding, resulting in a 32x32 px icon button.
|
|
38
|
+
|
|
39
|
+
### **Color**
|
|
40
|
+
|
|
41
|
+
Icon Buttons are currently only available in a neutral color. Other colors will be added in future versions.
|
|
42
|
+
|
|
43
|
+
- **color: neutral**
|
|
44
|
+
|
|
45
|
+
Neutral, most common, less visual prominence
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
Usage
|
|
50
|
+
|
|
51
|
+
### When to use
|
|
52
|
+
|
|
53
|
+
> [!TIP]
|
|
54
|
+
>
|
|
55
|
+
> **Provide a small, clickable icon that represents an action or a link**
|
|
56
|
+
>
|
|
57
|
+
> - ex. Search, refresh, print
|
|
58
|
+
|
|
59
|
+
> [!TIP]
|
|
60
|
+
>
|
|
61
|
+
> **For secondary or less important actions that may not require a lot of emphasis**
|
|
62
|
+
>
|
|
63
|
+
> - ex. Settings, more options
|
|
64
|
+
|
|
65
|
+
> [!TIP]
|
|
66
|
+
>
|
|
67
|
+
> **For actions that users frequently use**
|
|
68
|
+
>
|
|
69
|
+
> - ex. Add, delete, hide
|
|
70
|
+
|
|
71
|
+
### When not to use
|
|
72
|
+
|
|
73
|
+
> [!CAUTION]
|
|
74
|
+
>
|
|
75
|
+
> **As the primary call-to-action on a page**
|
|
76
|
+
>
|
|
77
|
+
> - ex: The submit button on a form
|
|
78
|
+
> - ex: The confirm button on a modal
|
|
79
|
+
|
|
80
|
+
### Layout and placement
|
|
81
|
+
|
|
82
|
+
Icon buttons are typically placed in areas of the interface where users expect to find actions, such as in toolbars or near form fields.
|
|
83
|
+
|
|
84
|
+
When using icon buttons in a toolbar, consider grouping related buttons together to improve the user's ability to quickly scan and identify them.
|
|
85
|
+
|
|
86
|
+
_usage\_layout\_01-ex_
|
|
87
|
+
|
|
88
|
+
### **Consistency**
|
|
89
|
+
|
|
90
|
+
Icon buttons should look and feel consistent with other buttons on the page, especially ones that are directly next to each other. That includes standard buttons, button groups, toggle buttons, etc.
|
|
91
|
+
|
|
92
|
+
- **Do:** When using buttons and icon buttons in the same row, use the same value for the size property so that the button heights align.
|
|
93
|
+
- **Don't:** Don’t mix and match button sizes.
|
|
94
|
+
- **Do:** Icon buttons in a row should generally be the same color.
|
|
95
|
+
- **Do:** Make an exception for icon buttons that represent destructive actions.
|
|
96
|
+
- **Don't:** Don’t mix and match colors without a good reason.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## **Behavior**
|
|
101
|
+
|
|
102
|
+
### **Interaction states**
|
|
103
|
+
|
|
104
|
+
The default state of an icon button is clickable. The appearance of the button will respond as the user interacts with it.
|
|
105
|
+
|
|
106
|
+
- **Resting (default)**
|
|
107
|
+
|
|
108
|
+
Default state. The user is not interacting with the icon button.
|
|
109
|
+
- **isHovered**
|
|
110
|
+
|
|
111
|
+
When the user’s cursor is hovering over the icon button.
|
|
112
|
+
- **isFocused**
|
|
113
|
+
|
|
114
|
+
When the user focuses on the icon button using tab navigation controls on their keyboard.
|
|
115
|
+
|
|
116
|
+
### **Disabled**
|
|
117
|
+
|
|
118
|
+
Icon buttons can be disabled, which prevents the user from clicking on or interacting with the button.
|
|
119
|
+
|
|
120
|
+
Using disabled buttons can cause accessibility issues so try and avoid them, as they often create more problems than they solve. Keep buttons active and use clear error messaging to guide users whenever possible. Use disabled buttons only in rare edge cases.
|
|
121
|
+
|
|
122
|
+
- **isDisabled**
|
|
123
|
+
|
|
124
|
+
The user cannot interact with the icon button in this state.
|
|
125
|
+
|
|
126
|
+
### **Click**
|
|
127
|
+
|
|
128
|
+
When a user clicks an icon button, it should perform the intended action and provide feedback to the user to indicate that the action has been taken. Do not leave the user to guess if the action was successful or not.
|
|
129
|
+
|
|
130
|
+
For more information about providing feedback, see our Notifications pattern.
|
|
131
|
+
|
|
132
|
+
### **Destructive actions**
|
|
133
|
+
|
|
134
|
+
Just like standard buttons, icon buttons can be used for destructive actions. Destructive actions are **actions that cause permanent data loss**, such as discarding a draft email, deleting a user account, or closing a credit card. In most cases, these actions can’t be undone.
|
|
135
|
+
|
|
136
|
+
#### **Preventing user error**
|
|
137
|
+
|
|
138
|
+
In flows that contain destructive actions, **users should be prompted before the action is executed**, as it is possible they pressed the button by mistake. This is especially important when using an icon button, since there is no visible label to help the user.
|
|
139
|
+
|
|
140
|
+
- **Do:** Use a destructive icon button to open the confirmation prompt, and then a high-emphasis destructive button in the prompt to complete the action.
|
|
141
|
+
- **Don't:** Don’t complete a destructive action without prompting the user. The user must confirm their intent in order to avoid mistakes.
|
|
142
|
+
|
|
143
|
+
## Content
|
|
144
|
+
|
|
145
|
+
## Recognition over recall
|
|
146
|
+
|
|
147
|
+
When using an icon button, make sure that the icon is **highly recognizable** and has a clear **affordance**. In other words, the meaning of the symbol should be easily understood even without a visible label. If there is no unambiguous icon available, use a standard button instead.
|
|
148
|
+
|
|
149
|
+
- **Do:** Use icon buttons for actions with icons that are highly recognizable.
|
|
150
|
+
- **Don't:** Don’t use icon buttons with icons that are not highly recognizable to most users.
|
|
151
|
+
|
|
152
|
+
## Context and meaning
|
|
153
|
+
|
|
154
|
+
Sometimes, the context of an icon button makes the meaning of its icon more recognizable to the user. The same icon may have a very obvious meaning in one context, and be completely unclear in another. When choosing an icon for an icon button, consider the context of the current page, the current flow, the type of application, and/or the device type.
|
|
155
|
+
|
|
156
|
+
- **Do:** In the context of a timer app, the ⏹︎ stop and ⏸︎ pause icons will have very obvious meanings to the user.
|
|
157
|
+
- **Don't:** In the context of a table containing employee names & roles, the ⏹︎ stop and ⏸︎ pause icons will have no obvious meaning to the user.
|
|
158
|
+
|
|
159
|
+
## **Represent the action**
|
|
160
|
+
|
|
161
|
+
The icon inside of an icon button can dynamically change. However, the **icon should always represent the button’s action**, not the state of another element.
|
|
162
|
+
|
|
163
|
+
As an example, think about the play/pause button on a music player. When the user wants to pause the music, they will look for the **⏸ pause icon**, because the want to take the **pause action**. They would interpret the **▶ play icon** as the **play action**, the opposite of what they want.
|
|
164
|
+
|
|
165
|
+
- **Do:** Use an icon that represents the button’s action, not the current state of the parent component.
|