Chart legend and key icon
Chart legend names a data series next to its colour, for reading charts. Key icon puts an icon in a circle; use it to draw attention to a metric, feature or list item.
Beta until design confirms the legend Blue colour (C24) and the key icon colour bindings (C25, FC-12), decides on the colours below 3:1 (C23), and adds a local shadow style for the dots (FC-16).
Preview
Pick a component, then change its props. The preview renders the real component and the code updates with it.
import { ChartLegend } from '@nuton/ui'
<ChartLegend color="blue">Lessons completed</ChartLegend>Installation
Availability
@nuton/ui and @nuton/tokens are private workspace packages. They aren't published to a registry yet (D4: registry deferred; D12: distribution waits on the provenance review). Inside the Nuton monorepo, add them as workspace dependencies. The commands below apply once the packages are published.
1. Add the packages
pnpm add @nuton/ui @nuton/tokens @remixicon/reactnpm install @nuton/ui @nuton/tokens @remixicon/reactyarn add @nuton/ui @nuton/tokens @remixicon/reactPeer dependencies: react and react-dom 18 or later. @remixicon/react supplies the icons you pass to KeyIcon (Remix Icon is Nuton's icon set, D1).
2. Load tokens and component styles once
// app/layout.tsx (or your app's entry file)
import '@nuton/tokens/tokens.css' // --nu-* design tokens
import '@nuton/ui/styles.css' // component styles (uses the tokens)The legend label uses the Label/X Small type tokens, which read --nu-font-body. Map it to Inter as described in the Button font setup. No provider or other setup is needed.
Usage
import { ChartLegend, KeyIcon } from '@nuton/ui'
import { RiBookOpenLine } from '@remixicon/react'
export function ActivityLegend() {
return (
<ul className="legend">
<li><ChartLegend color="blue">Lessons completed</ChartLegend></li>
<li><ChartLegend color="orange">Quizzes taken</ChartLegend></li>
</ul>
)
}
export function LessonCount() {
return <p><KeyIcon color="blue" icon={<RiBookOpenLine />} /> 12 lessons</p>
}- Defaults:
ChartLegendandChartLegendDotare gray (the dot is md);KeyIconis stroke, gray, 40. - Give every series a
ChartLegendwith the series name. UseChartLegendDoton its own only where text sits next to it, such as a tooltip row. - Put two or more legends in a list (
<ul>of<li>), so screen readers announce how many series there are. - Pass a Remix icon through
icon. Leavelabeloff when text next to the key icon says the same thing.
Variants and sizes
The family has three parts. ChartLegendDot is the coloured mark; ChartLegend is a small dot plus the series name; KeyIcon is an icon in a circle with its own palette and five sizes.
Chart legend colours
- Gray
- Light gray
- Blue
- Orange
- Red
- Green
- Yellow
- Purple
- Sky
- Pink
- Teal
- Disabled
<ul>
<li><ChartLegend color="gray">Gray</ChartLegend></li>
<li><ChartLegend color="light-gray">Light gray</ChartLegend></li>
<li><ChartLegend color="blue">Blue</ChartLegend></li>
<li><ChartLegend color="orange">Orange</ChartLegend></li>
<li><ChartLegend color="red">Red</ChartLegend></li>
<li><ChartLegend color="green">Green</ChartLegend></li>
<li><ChartLegend color="yellow">Yellow</ChartLegend></li>
<li><ChartLegend color="purple">Purple</ChartLegend></li>
<li><ChartLegend color="sky">Sky</ChartLegend></li>
<li><ChartLegend color="pink">Pink</ChartLegend></li>
<li><ChartLegend color="teal">Teal</ChartLegend></li>
<li><ChartLegend color="teal" disabled>Disabled</ChartLegend></li>
</ul>Figma discrepancy: legend Blue (C24, FC-13)
In Figma, the Chart Legends “Blue” instance overrides its dot to State/Success/Base (green), and “Disabled” is a Teal dot with overrides. Code builds the legend from the dot component, so legend Blue is Primary blue. Awaiting design confirmation.
Legend dots: colour × size
All 11 colours at both sizes. The dot is 12px in both; size sets the frame around it.
mdsmmd · 20px framesm · 16px frame<ChartLegendDot color="blue" size="md" />
<ChartLegendDot color="blue" size="sm" />| Part | Frame | Inset | Mark | Details |
|---|---|---|---|---|
ChartLegendDot size="md" | 20 × 20 | 4 | 12px circle | 2px inside Stroke/White, shadow regular-shadow/small (interim token, FC-16) |
ChartLegendDot size="sm" | 16 × 16 | 2 | ||
ChartLegend | 16 tall | — | Small dot | 4px gap, Label/X Small (12px, 500) with a 16px line box, Text/Sub-600 |
Measured in the browser (legend 16 tall). Figma binds the legend text to a remote Label/X Small style (Satoshi); code uses the local Nuton Label/X Small (C22).
Key icon appearance
<KeyIcon appearance="stroke" color="blue" icon={<RiBookOpenLine />} />
<KeyIcon appearance="lighter" color="blue" icon={<RiBookOpenLine />} />Stroke: Bg/White, 1px inside Stroke/Soft-200, regular-shadow/x-small. Lighter: State/<colour>/Lighter fill, no border. The icon is State/<colour>/Base (gray: Icon/Sub-600).
Key icon sizes
6456484032<KeyIcon size={64} icon={<RiUser6Line />} />
<KeyIcon size={56} icon={<RiUser6Line />} />
<KeyIcon size={48} icon={<RiUser6Line />} />
<KeyIcon size={40} icon={<RiUser6Line />} />
<KeyIcon size={32} icon={<RiUser6Line />} />| Size | Figma name | Circle | Inset | Icon |
|---|---|---|---|---|
64 | 2X-Large | 64 × 64 | 16 | 32 |
56 | X-Large | 56 × 56 | 14 | 28 |
48 | Large | 48 × 48 | 12 | 24 |
40 | Medium (default) | 40 × 40 | 10 | 20 |
32 | Small | 32 × 32 | 6 | 20 |
Verified in the browser against Figma geometry.
Key icons: appearance × colour × size
Every Figma variant: 2 appearances × 9 colours × 5 sizes.
Stroke
6456484032Lighter
6456484032Figma discrepancy: key icon colours (C25, FC-12)
Code follows the Figma bindings, including three oddities: Blue Lighter uses State/Purple/Lighter for its fill; Purple Lighter binds a remote feature/lighter token (code uses local State/Purple/Lighter, C22); and “Teal” uses State/Verified (sky) values, not State/Teal. Design to confirm whether Blue should use Primary/Lighter and Teal should use State/Teal.
Colour tokens
| Colour | Dot (--nu-chart-color) | Key icon (--nu-key-icon-fg / --nu-key-icon-tint) |
|---|---|---|
| Gray | State/Faded/Base | Icon/Sub-600 / State/Faded/Lighter |
| Light gray | Icon/Disabled-300 | Not available |
| Blue | State/Primary/Base | State/Primary/Base / State/Purple/Lighter (C25) |
| Orange | State/Warning/Base | State/Warning/Base / Lighter |
| Red | State/Error/Base | State/Error/Base / Lighter |
| Green | State/Success/Base | State/Success/Base / Lighter |
| Yellow | State/Pending/Base | State/Pending/Base / Lighter |
| Purple | State/Purple/Base | State/Purple/Base / Lighter |
| Sky | State/Verified/Base | Not available |
| Pink | State/Feature/Base | State/Feature/Base / Lighter |
| Teal | State/Teal/Base | State/Verified/Base / Lighter (C25) |
States
None of these components is interactive, so there are no hover, focus or pressed states. The legend has a disabled state; the key icon is either decorative or labelled.
disabled on the dot alone swaps its colour to Icon/Disabled-300.label. Hidden from assistive tech; the text beside it carries the meaning.label, it's an img named “Reading lesson”. Use it when the icon alone carries meaning.State tokens
These custom properties are set by the component from its props, on the element itself. Use the props; the properties are listed for reference.
| Token | Element | Default | Disabled |
|---|---|---|---|
--nu-chart-color | .nu-chart-dot | The colour's base token (see Colour tokens) | Icon/Disabled-300 |
| Legend text colour | .nu-chart-legend | Text/Sub-600 | Text/Disabled-500 |
--nu-key-icon-size, --nu-key-icon-glyph | .nu-key-icon | 40 / 20 (by size) | — |
--nu-key-icon-fg, --nu-key-icon-tint | .nu-key-icon | By color (see Colour tokens) | — |
Composition examples
Series toggle
Click a legend to hide or show its series. Each legend sits inside a real Button with aria-pressed; a hidden series shows the disabled legend. The chart has a text summary for screen readers.
The disabled legend text is 1.52:1 (C23). The button's pressed state, not the grey text, tells assistive tech the series is hidden.
Chart legend
Key icons in a space summary
Next to text, the key icon is decorative: leave label off.
Labelled key icons
When the icon is the only cue, such as a lesson type in a list, pass label so it's announced.
Use only colours at 3:1 or higher for meaningful key icons: not green, yellow or teal lighter (C23).
API reference
ChartLegend props
| Prop | Type | Default | Description |
|---|---|---|---|
childrenrequired | ReactNode | — | The series name. |
color | ChartColor | 'gray' | The dot colour: 'gray' | 'light-gray' | 'blue' | 'orange' | 'red' | 'green' | 'yellow' | 'purple' | 'sky' | 'pink' | 'teal'. Always renders a small dot. |
disabled | boolean | false | A series that is hidden or not available (Figma Disabled). Greys the dot and the text. Purely visual. |
ref | Ref<HTMLSpanElement> | — | Forwarded to the outer span. |
…rest | Omit<HTMLAttributes<HTMLSpanElement>, 'color'> | — | Any other span attribute (className, id, aria-*…), applied to the outer span. |
ChartLegendDot props
| Prop | Type | Default | Description |
|---|---|---|---|
color | ChartColor | 'gray' | One of the 11 chart colours. |
size | 'sm' | 'md' | 'md' | Frame 16 / 20px. The dot is 12px in both. |
disabled | boolean | false | Swaps the colour to Icon/Disabled-300. |
ref | Ref<HTMLSpanElement> | — | Forwarded to the span. |
…rest | Omit<HTMLAttributes<HTMLSpanElement>, 'color'> | — | Any other span attribute. The dot always renders aria-hidden="true". |
KeyIcon props
| Prop | Type | Default | Description |
|---|---|---|---|
iconrequired | ReactNode | — | A Remix icon (D1), for example <RiUser6Line />. |
appearance | 'stroke' | 'lighter' | 'stroke' | Stroke: white with a 1px border and shadow. Lighter: tinted fill (Figma Style). |
color | KeyIconColor | 'gray' | 'gray' | 'blue' | 'orange' | 'red' | 'green' | 'yellow' | 'purple' | 'pink' | 'teal'. |
size | KeyIconSize | 40 | 32 | 40 | 48 | 56 | 64, the circle in pixels. |
label | string | — | Accessible name. With it the key icon is role="img"; without it, aria-hidden. |
ref | Ref<HTMLSpanElement> | — | Forwarded to the span. |
…rest | Omit<HTMLAttributes<HTMLSpanElement>, 'color'> | — | Any other span attribute. |
Styling hooks
ChartLegendDot renders .nu-chart-dot with data-color, data-size and data-disabled. ChartLegend renders .nu-chart-legend (with data-disabled) around a small dot and .nu-chart-legend__label. KeyIcon renders .nu-key-icon with data-appearance, data-color and data-size. Use props rather than styling these attributes.
Accessibility
Keyboard
| Key | Behaviour |
|---|---|
| Tab | Skips legends, dots and key icons: they aren’t focusable. In a series toggle, focus moves to each wrapping button. |
| Enter / Space | Nothing on the components themselves. On a wrapping button, toggles the series. |
Screen readers
The legend reads as its text; the dot is always hidden. Several legends in a list announce the count. A key icon is hidden unless label is set; then it's an img with that name. The disabled state isn't announced, so say it in text or with aria-pressed.
Focus
None of the components takes focus. When you wrap a legend in a Button, the button's focus ring applies.
Contrast and colour
Dots as chart marks on white: Light Gray 1.53, Yellow 2.10 and Green 2.85 are below 3:1; Sky 3.27, Orange 3.44 and the rest pass. Key icons: Gray, Blue, Purple, Red, Pink, Orange and Teal Stroke (3.27) are 3:1 or higher; Green (2.85 / 2.59), Yellow (2.10 / 2.02) and Teal Lighter (2.78) are below, so use them only decoratively. Disabled legend text is 1.52 (C23, as C8). The legend text names the series, so colour is never the only cue.
Touch and pointer
Not targets. A series toggle's size="sm" button is 36px tall, above the 24 × 24 minimum (WCAG 2.5.8).
You must: give every series a text legend; put several legends in a list; pair low-contrast series with patterns or direct labels in the chart itself; pass label only when the key icon alone carries meaning.
Figma mapping
| Figma | Variants | Code |
|---|---|---|
| Chart Legend Dots [1.1] (57:15737) | 11 colours × Medium (20) · Small (16) | ChartLegendDot color size="md" | "sm" |
| Chart Legends [1.1] (57:15695) | 11 colours + Disabled | ChartLegend color disabled |
| Key Icons [1.1] (57:15783) | Stroke · Lighter × 9 colours × 2X-Large (64) · X-Large (56) · Large (48) · Medium (40) · Small (32) | KeyIcon appearance color size icon label |
Figma's description says “9 distinct colour options”; the dot and legend components have 11 (FC-13). Payment Icons (57:15965) sit on the same Figma page. They aren't part of this family and are already on the D9 clean-up list.
Guidelines and related components
Use these for
ChartLegend: naming each series of a chart, such as lessons completed and quizzes taken.ChartLegendDot: a colour key next to existing text, such as a tooltip row.KeyIcon: highlighting a metric, feature or list item, such as a space's lesson count.
Do and don't
- Lessons completed
- Quizzes taken
Common mistakes
- Putting an
onClickon a legend. It isn't focusable or announced as a control; wrap it in aButton. - Relying on the greyed disabled legend to say a series is hidden. Pair it with
aria-pressedor text. - Matching chart colours to dots by eye. Use the same State tokens the dot uses (see Colour tokens).
- Setting the dot
sizeon a legend.ChartLegendalways uses the small dot.