@cognite/aura 0.3.0 → 0.3.2
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/DESIGN.md +2243 -729
- package/README.md +133 -11
- package/dist/components/index.d.ts +3 -2
- package/dist/components/index.js +183 -176
- package/dist/components/ui/core/action-toolbar/action-toolbar.js +4 -4
- package/dist/components/ui/core/alert/alert.js +3 -3
- package/dist/components/ui/core/banner/banner.js +6 -6
- package/dist/components/ui/core/button/button.js +4 -4
- package/dist/components/ui/core/checkbox/checkbox.js +8 -8
- package/dist/components/ui/core/code-block/code-block.js +6 -6
- package/dist/components/ui/core/date-time-pickers/date-picker/date-picker.d.ts +15 -0
- package/dist/components/ui/core/date-time-pickers/date-picker/date-picker.js +73 -0
- package/dist/components/ui/core/date-time-pickers/date-picker/index.d.ts +3 -0
- package/dist/components/ui/core/date-time-pickers/date-picker/types.d.ts +17 -0
- package/dist/components/ui/core/date-time-pickers/date-picker/use-date-picker.d.ts +3 -0
- package/dist/components/ui/core/date-time-pickers/date-picker/use-date-picker.js +52 -0
- package/dist/components/ui/core/date-time-pickers/date-range-picker/date-range-picker.js +64 -75
- package/dist/components/ui/core/date-time-pickers/date-range-picker/types.d.ts +1 -2
- package/dist/components/ui/core/date-time-pickers/date-range-picker/use-date-range-picker.js +51 -64
- package/dist/components/ui/core/date-time-pickers/date-time-range-picker/date-time-range-picker.js +146 -161
- package/dist/components/ui/core/date-time-pickers/date-time-range-picker/types.d.ts +1 -2
- package/dist/components/ui/core/date-time-pickers/date-time-range-picker/use-date-time-range-picker.js +124 -137
- package/dist/components/ui/core/date-time-pickers/index.d.ts +4 -0
- package/dist/components/ui/core/date-time-pickers/index.js +10 -0
- package/dist/components/ui/core/date-time-pickers/shared/calendar/calendar.js +8 -8
- package/dist/components/ui/core/date-time-pickers/shared/date-time-input/date-time-input.d.ts +1 -1
- package/dist/components/ui/core/date-time-pickers/shared/date-time-input/date-time-input.js +1 -1
- package/dist/components/ui/core/date-time-pickers/shared/hooks/use-popover-state.d.ts +0 -2
- package/dist/components/ui/core/date-time-pickers/shared/hooks/use-popover-state.js +18 -34
- package/dist/components/ui/core/date-time-pickers/shared/hooks/use-single-date-state.d.ts +23 -0
- package/dist/components/ui/core/date-time-pickers/shared/hooks/use-single-date-state.js +32 -0
- package/dist/components/ui/core/date-time-pickers/shared/time-picker-panel/index.d.ts +2 -0
- package/dist/components/ui/core/date-time-pickers/shared/time-picker-panel/time-picker-panel.d.ts +19 -0
- package/dist/components/ui/core/date-time-pickers/shared/time-picker-panel/time-picker-panel.js +41 -0
- package/dist/components/ui/core/date-time-pickers/time-picker/index.d.ts +3 -0
- package/dist/components/ui/core/date-time-pickers/time-picker/time-picker.d.ts +16 -0
- package/dist/components/ui/core/date-time-pickers/time-picker/time-picker.js +100 -0
- package/dist/components/ui/core/date-time-pickers/time-picker/types.d.ts +23 -0
- package/dist/components/ui/core/date-time-pickers/time-picker/use-time-picker.d.ts +3 -0
- package/dist/components/ui/core/date-time-pickers/time-picker/use-time-picker.js +64 -0
- package/dist/components/ui/core/date-time-pickers/utils/calendar-utils.js +3 -3
- package/dist/components/ui/core/date-time-pickers/utils/time-utils.js +1 -1
- package/dist/components/ui/core/dropdown-menu/dropdown-menu.d.ts +17 -15
- package/dist/components/ui/core/dropdown-menu/dropdown-menu.js +83 -85
- package/dist/components/ui/core/hover-card/hover-card.js +3 -3
- package/dist/components/ui/core/input/input.js +1 -1
- package/dist/components/ui/core/message/message.js +387 -101
- package/dist/components/ui/core/pagination/pagination.js +9 -7
- package/dist/components/ui/core/prompt-input/prompt-input.js +16 -16
- package/dist/components/ui/core/radio-group/radio-group.js +7 -7
- package/dist/components/ui/core/reasoning/reasoning.js +1 -1
- package/dist/components/ui/core/segmented-control/segmented-control.js +3 -3
- package/dist/components/ui/core/select/select.d.ts +2 -1
- package/dist/components/ui/core/select/select.js +134 -110
- package/dist/components/ui/core/shimmer/shimmer.d.ts +3 -1
- package/dist/components/ui/core/shimmer/shimmer.js +89 -49
- package/dist/components/ui/core/tabs/tabs.js +3 -3
- package/dist/components/ui/core/textarea/textarea.js +1 -1
- package/dist/components/ui/core/toggle/toggle.d.ts +15 -0
- package/dist/components/ui/core/toggle/toggle.js +74 -0
- package/dist/components/ui/core/tool/tool.js +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/lib/portal-container-context.js +3 -3
- package/dist/lib/use-controllable-state.js +17 -17
- package/dist/lib/utils.d.ts +1 -1
- package/dist/lib/utils.js +7 -7
- package/dist/styles.css +1 -1
- package/dist/styles.source.css +3 -0
- package/package.json +200 -18
- package/dist/index.js +0 -308
package/DESIGN.md
CHANGED
|
@@ -1,852 +1,2072 @@
|
|
|
1
|
+
---
|
|
2
|
+
version: alpha
|
|
3
|
+
name: Aura
|
|
4
|
+
description: Cognite's design system for composable UI primitives in data-heavy industrial software.
|
|
5
|
+
colors:
|
|
6
|
+
primary: '#212426'
|
|
7
|
+
secondary: '#E4E6E8'
|
|
8
|
+
tertiary: '#486AED'
|
|
9
|
+
neutral: '#F1F2F3'
|
|
10
|
+
background: '#FFFFFF'
|
|
11
|
+
foreground: '#191B1D'
|
|
12
|
+
alternate-background: '#F9FAFA'
|
|
13
|
+
card-background: '#F9FAFA'
|
|
14
|
+
muted-background: '#F1F2F3'
|
|
15
|
+
muted-foreground: '#6D767E'
|
|
16
|
+
primary-background-hover: '#40464A'
|
|
17
|
+
secondary-background-hover: '#D4D7D9'
|
|
18
|
+
foreground-on-primary: '#F1F2F3'
|
|
19
|
+
secondary-foreground: '#40464A'
|
|
20
|
+
link-foreground: '#486AED'
|
|
21
|
+
border: '#E4E6E8'
|
|
22
|
+
border-emphasized: '#D4D7D9'
|
|
23
|
+
ring: '#7081C7'
|
|
24
|
+
ring-muted: '#B5BEE2'
|
|
25
|
+
info-background: '#D0D6ED'
|
|
26
|
+
info-foreground-on-info: '#32417F'
|
|
27
|
+
success-background: '#BBF3D0'
|
|
28
|
+
success-foreground-on-success: '#0F5026'
|
|
29
|
+
warning-background: '#FFE3A2'
|
|
30
|
+
warning-foreground-on-warning: '#755200'
|
|
31
|
+
destructive-background: '#FCCAD2'
|
|
32
|
+
destructive-foreground-on-critical: '#8D081F'
|
|
33
|
+
overlay-background: '#7C868E80'
|
|
34
|
+
typography:
|
|
35
|
+
display:
|
|
36
|
+
fontFamily: Space Grotesk
|
|
37
|
+
fontSize: 36px
|
|
38
|
+
fontWeight: 600
|
|
39
|
+
lineHeight: 44px
|
|
40
|
+
letterSpacing: -0.08px
|
|
41
|
+
h1:
|
|
42
|
+
fontFamily: Inter
|
|
43
|
+
fontSize: 32px
|
|
44
|
+
fontWeight: 600
|
|
45
|
+
lineHeight: 40px
|
|
46
|
+
letterSpacing: -0.08px
|
|
47
|
+
h2:
|
|
48
|
+
fontFamily: Inter
|
|
49
|
+
fontSize: 28px
|
|
50
|
+
fontWeight: 600
|
|
51
|
+
lineHeight: 32px
|
|
52
|
+
letterSpacing: -0.08px
|
|
53
|
+
h3:
|
|
54
|
+
fontFamily: Inter
|
|
55
|
+
fontSize: 24px
|
|
56
|
+
fontWeight: 600
|
|
57
|
+
lineHeight: 28px
|
|
58
|
+
letterSpacing: -0.04px
|
|
59
|
+
h4:
|
|
60
|
+
fontFamily: Inter
|
|
61
|
+
fontSize: 20px
|
|
62
|
+
fontWeight: 500
|
|
63
|
+
lineHeight: 24px
|
|
64
|
+
letterSpacing: -0.04px
|
|
65
|
+
body-md:
|
|
66
|
+
fontFamily: Inter
|
|
67
|
+
fontSize: 16px
|
|
68
|
+
fontWeight: 400
|
|
69
|
+
lineHeight: 20px
|
|
70
|
+
letterSpacing: -0.04px
|
|
71
|
+
body-sm:
|
|
72
|
+
fontFamily: Inter
|
|
73
|
+
fontSize: 14px
|
|
74
|
+
fontWeight: 400
|
|
75
|
+
lineHeight: 18px
|
|
76
|
+
letterSpacing: -0.04px
|
|
77
|
+
label:
|
|
78
|
+
fontFamily: Inter
|
|
79
|
+
fontSize: 12px
|
|
80
|
+
fontWeight: 500
|
|
81
|
+
lineHeight: 14px
|
|
82
|
+
letterSpacing: -0.04px
|
|
83
|
+
code:
|
|
84
|
+
fontFamily: Source Code Pro
|
|
85
|
+
fontSize: 14px
|
|
86
|
+
fontWeight: 400
|
|
87
|
+
lineHeight: 20px
|
|
88
|
+
rounded:
|
|
89
|
+
none: 0px
|
|
90
|
+
xs: 2px
|
|
91
|
+
sm: 4px
|
|
92
|
+
md: 6px
|
|
93
|
+
lg: 8px
|
|
94
|
+
xl: 12px
|
|
95
|
+
2xl: 16px
|
|
96
|
+
3xl: 24px
|
|
97
|
+
4xl: 32px
|
|
98
|
+
full: 9999px
|
|
99
|
+
spacing:
|
|
100
|
+
base: 4px
|
|
101
|
+
xs: 4px
|
|
102
|
+
sm: 8px
|
|
103
|
+
md: 12px
|
|
104
|
+
lg: 16px
|
|
105
|
+
xl: 20px
|
|
106
|
+
2xl: 24px
|
|
107
|
+
3xl: 32px
|
|
108
|
+
prose-max: 600px
|
|
109
|
+
container-2xl: 640px
|
|
110
|
+
container-8xl: 1536px
|
|
111
|
+
components:
|
|
112
|
+
button-primary:
|
|
113
|
+
backgroundColor: '{colors.primary}'
|
|
114
|
+
textColor: '{colors.foreground-on-primary}'
|
|
115
|
+
rounded: '{rounded.lg}'
|
|
116
|
+
padding: '{spacing.md}'
|
|
117
|
+
height: 36px
|
|
118
|
+
button-primary-hover:
|
|
119
|
+
backgroundColor: '{colors.primary-background-hover}'
|
|
120
|
+
button-secondary:
|
|
121
|
+
backgroundColor: '{colors.secondary}'
|
|
122
|
+
textColor: '{colors.foreground}'
|
|
123
|
+
rounded: '{rounded.lg}'
|
|
124
|
+
padding: '{spacing.md}'
|
|
125
|
+
height: 36px
|
|
126
|
+
button-destructive:
|
|
127
|
+
backgroundColor: '{colors.destructive-background}'
|
|
128
|
+
textColor: '{colors.destructive-foreground-on-critical}'
|
|
129
|
+
rounded: '{rounded.lg}'
|
|
130
|
+
height: 36px
|
|
131
|
+
button-sm:
|
|
132
|
+
height: 28px
|
|
133
|
+
rounded: '{rounded.lg}'
|
|
134
|
+
button-lg:
|
|
135
|
+
height: 40px
|
|
136
|
+
rounded: '{rounded.lg}'
|
|
137
|
+
button-secondary-hover:
|
|
138
|
+
backgroundColor: '{colors.secondary-background-hover}'
|
|
139
|
+
input-default:
|
|
140
|
+
backgroundColor: '{colors.background}'
|
|
141
|
+
textColor: '{colors.foreground}'
|
|
142
|
+
rounded: '{rounded.lg}'
|
|
143
|
+
height: 36px
|
|
144
|
+
input-muted:
|
|
145
|
+
backgroundColor: '{colors.muted-background}'
|
|
146
|
+
textColor: '{colors.muted-foreground}'
|
|
147
|
+
rounded: '{rounded.lg}'
|
|
148
|
+
height: 36px
|
|
149
|
+
dialog-overlay:
|
|
150
|
+
backgroundColor: '{colors.overlay-background}'
|
|
151
|
+
divider-default:
|
|
152
|
+
backgroundColor: '{colors.border}'
|
|
153
|
+
divider-emphasized:
|
|
154
|
+
backgroundColor: '{colors.border-emphasized}'
|
|
155
|
+
badge-neutral:
|
|
156
|
+
backgroundColor: '{colors.neutral}'
|
|
157
|
+
textColor: '{colors.secondary-foreground}'
|
|
158
|
+
rounded: '{rounded.sm}'
|
|
159
|
+
panel-alternate:
|
|
160
|
+
backgroundColor: '{colors.alternate-background}'
|
|
161
|
+
textColor: '{colors.foreground}'
|
|
162
|
+
card-default:
|
|
163
|
+
backgroundColor: '{colors.card-background}'
|
|
164
|
+
textColor: '{colors.foreground}'
|
|
165
|
+
rounded: '{rounded.xl}'
|
|
166
|
+
padding: '{spacing.lg}'
|
|
167
|
+
link-default:
|
|
168
|
+
textColor: '{colors.link-foreground}'
|
|
169
|
+
typography: '{typography.body-md}'
|
|
170
|
+
badge-xs:
|
|
171
|
+
height: 20px
|
|
172
|
+
rounded: '{rounded.sm}'
|
|
173
|
+
alert-info:
|
|
174
|
+
backgroundColor: '{colors.info-background}'
|
|
175
|
+
textColor: '{colors.info-foreground-on-info}'
|
|
176
|
+
rounded: '{rounded.lg}'
|
|
177
|
+
alert-success:
|
|
178
|
+
backgroundColor: '{colors.success-background}'
|
|
179
|
+
textColor: '{colors.success-foreground-on-success}'
|
|
180
|
+
rounded: '{rounded.lg}'
|
|
181
|
+
alert-warning:
|
|
182
|
+
backgroundColor: '{colors.warning-background}'
|
|
183
|
+
textColor: '{colors.warning-foreground-on-warning}'
|
|
184
|
+
rounded: '{rounded.lg}'
|
|
185
|
+
alert-destructive:
|
|
186
|
+
backgroundColor: '{colors.destructive-background}'
|
|
187
|
+
textColor: '{colors.destructive-foreground-on-critical}'
|
|
188
|
+
rounded: '{rounded.lg}'
|
|
189
|
+
---
|
|
190
|
+
|
|
1
191
|
## Overview
|
|
2
192
|
|
|
3
|
-
Aura is the design system for Cognite
|
|
193
|
+
Aura is the official design system for Cognite experiences: composable UI primitives for data-heavy industrial software.
|
|
4
194
|
|
|
5
|
-
|
|
195
|
+
Aura should feel like an **industrial control room**: quiet surfaces, stable hierarchy, immediate status signals, and controls that stay out of the operator's way until action is needed. The interface is engineered, not decorated. It gives dense operational data enough structure to scan quickly, reserves color for meaning, and makes interaction states predictable under pressure.
|
|
6
196
|
|
|
7
|
-
|
|
197
|
+
Light and dark themes share the same semantic roles; fixed tokens support persistent shell chrome.
|
|
8
198
|
|
|
9
|
-
|
|
199
|
+
**Tokens:** Reference values live in the YAML front matter at the top of this file. They provide context for agents and humans — the prose sections below carry design intent, constraints, and reasoning. Reference tokens in prose as `{colors.<name>}`, `{spacing.<name>}`, `{typography.<name>}`, `{rounded.<name>}`, and `{components.<name>}`.
|
|
10
200
|
|
|
11
|
-
**
|
|
201
|
+
**Implementation:** Package imports, component APIs, and host-shell integration live in the Aura [README](./README.md) — not in this file.
|
|
12
202
|
|
|
13
|
-
|
|
203
|
+
### For agents: how to read this file
|
|
14
204
|
|
|
15
|
-
|
|
205
|
+
Before editing or generating from this file, read Google's [DESIGN.md Philosophy](https://github.com/google-labs-code/design.md/blob/main/PHILOSOPHY.md). The philosophy applies directly to how Aura's spec should be used:
|
|
16
206
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
207
|
+
1. **Start with prose, not tokens.** The quality of generated UI depends more on understanding _intent_ than on copying hex values. Read **Overview**, **Do's and Don'ts**, **Heuristics**, **Interaction states**, and **Content** before implementing from the YAML block. Use **Heuristics** for detailed feedback, disclosure, error, layout, and accessibility decisions.
|
|
208
|
+
2. **Tokens are context, not rendering instructions.** YAML values anchor names and approximate light-theme references. Runtime styling comes from `@cognite/aura/colors.css`, `@cognite/aura/styles.css`, and component APIs — not from reimplementing token literals in product code.
|
|
209
|
+
3. **Prefer specific constraints over adjectives.** Aura targets data-heavy industrial software: flat hierarchy, semantic color only for status and feedback, predictable interaction states, and calm surfaces. When prose and a token disagree, follow the prose rationale.
|
|
210
|
+
4. **Negative constraints matter.** **Do's and Don'ts** and the **Avoid** / **Must not** rules in Heuristics define character as much as the palette.
|
|
211
|
+
5. **Extension sections are intentional.** Sections beyond the core design.md spec order — **Assets & Motion**, **Heuristics**, **Interaction states**, **Content** — extend the format for Aura. UX playbook guidance lives in this file.
|
|
212
|
+
|
|
213
|
+
### Alignment with Google design.md
|
|
214
|
+
|
|
215
|
+
| Philosophy principle | Aura approach |
|
|
216
|
+
| ------------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
217
|
+
| Prose carries design intent | Overview, colors, interaction states, content, and do's/don'ts are the primary identity guidance |
|
|
218
|
+
| Tokens referenced in prose | Key roles use `{colors.*}`, `{spacing.*}`, etc. inline; full ramps stay in tables and CSS |
|
|
219
|
+
| Specific reference > vague adjectives | Overview names data-heavy industrial UI; heuristic rules carry constraints |
|
|
220
|
+
| Do's and don'ts as guardrails | Dedicated **Do's and Don'ts** section plus compact severity-rated heuristics |
|
|
221
|
+
| Format extends beyond the spec | Motion, iconography, elevation, copy, accessibility, and extended UX guidance live in extension sections |
|
|
24
222
|
|
|
25
223
|
---
|
|
26
224
|
|
|
27
|
-
##
|
|
225
|
+
## Colors
|
|
28
226
|
|
|
29
|
-
|
|
227
|
+
Aura color behaves like instrumentation in a control room. Most of the interface is neutral structure; important changes appear as clear signals; decorative color is rare and never competes with status. A screen should still make sense when color is removed, but color should make state faster to recognize.
|
|
30
228
|
|
|
31
|
-
**
|
|
229
|
+
Use **Base** color for the operating surface: page backgrounds, cards, text, borders, focus, and persistent chrome. This is ~80–90% of the UI.
|
|
32
230
|
|
|
33
|
-
**
|
|
231
|
+
Use **Semantic** color only for status and feedback: info, success, warning, destructive, validation, and operational state. This is ~5–10% of the UI.
|
|
34
232
|
|
|
35
|
-
-
|
|
36
|
-
- **Fusion / app shell:** patterns such as global **Topbar**, **Sonner** toasts, **AlertDialog**, **Sheet** / **Drawer**, **Tabs**, **SegmentedControl**, **Checkbox** / **Radio** / **Switch**, **ContextMenu**, or **EmptyState** may live **outside** this package — **Must** still follow the same **Tokens**, **Interaction states**, and severity rules using your shell’s components or Radix-style primitives themed with Aura.
|
|
37
|
-
- **Minimal or standalone apps** (no Fusion shell): apply the **same tokens** and **interaction rules** with Aura primitives and your stack’s equivalents. **Must** rules that name shell-only components (**Topbar**, **Sonner**, **AlertDialog**, **Sheet**, …) apply **when that capability exists** — treat them as **Should** / **when available** and substitute with the closest Aura or Radix pattern; wire **TooltipProvider** (or your tooltip root) at app root wherever **Tooltip** is used. Do not invent a fake shell just to satisfy a checklist.
|
|
233
|
+
Use **Decorative** color only for non-status differentiation: accents, avatars, illustrations, and small visual markers that do not imply system health. This is ~5–10% of the UI.
|
|
38
234
|
|
|
39
|
-
|
|
235
|
+
Light-theme reference values for key roles are defined as `colors.*` tokens in the YAML front matter (referenced in tables as `{colors.<name>}`); full ramps and dark-theme values are in the tables below.
|
|
40
236
|
|
|
41
|
-
|
|
237
|
+
Do not hardcode hex, font sizes, or shadow strings in product UI when a token exists.
|
|
42
238
|
|
|
43
|
-
|
|
239
|
+
Aura supports **light** (`:root`) and **dark** (`.dark` / `prefers-color-scheme: dark` per library setup). Semantic and base tokens **resolve to different ramps** per theme. **`background-fixed-dark`**, **`background-fixed-light`**, **`foreground-fixed-*`**, and related **fixed** tokens keep the same appearance in both themes (persistent chrome such as sidebars). Always verify contrast in both themes before shipping.
|
|
44
240
|
|
|
45
|
-
|
|
241
|
+
Reference tokens by **full CSS name** or Tailwind token. Never use raw `hex` / `rgb` / `hsl` in product code. If no semantic token fits, use a documented **base** token; **step colors** on ramps (`mountain/*`, `fjord/*`, …) are only for custom, branding, or marketing surfaces where no semantic token exists yet.
|
|
46
242
|
|
|
47
|
-
|
|
243
|
+
### Common Tailwind mappings
|
|
48
244
|
|
|
49
|
-
**
|
|
245
|
+
Tables in this section use **CSS role names** (e.g. `link-foreground`, `card-background`). Each role maps to a `--color-{role}` custom property and Tailwind v4 utilities (`text-{role}`, `bg-{role}`, `border-{role}`, and `ring-{role}` where applicable). Prefer these utilities over raw `var(--…)` when the theme wire-up matches.
|
|
246
|
+
|
|
247
|
+
| Role (suffix after `text-` / `bg-` / `border-`) | Typical utilities | Notes |
|
|
248
|
+
| ----------------------------------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------- |
|
|
249
|
+
| `background` | `bg-background` | Page base |
|
|
250
|
+
| `foreground` | `text-foreground` | Primary text |
|
|
251
|
+
| `muted-foreground` | `text-muted-foreground` | Tertiary copy |
|
|
252
|
+
| `card-background` | `bg-card-background` | Cards (see **Card** component) |
|
|
253
|
+
| `muted-background` | `bg-muted-background` | Static fills, inputs, secondary chrome |
|
|
254
|
+
| `border` | `border-border` | Default strokes |
|
|
255
|
+
| `link-foreground` (`{colors.link-foreground}`) | `text-link-foreground` | Text links — same value as `{colors.tertiary}` |
|
|
256
|
+
| `primary-background` | `bg-primary-background`, `text-foreground-on-primary` | Default **Button** (`variant="default"`) pattern |
|
|
257
|
+
| `destructive-background` | `bg-destructive-background`, `text-destructive-foreground-on-critical` (on surface) | Destructive actions — pairings in **Semantic colors** |
|
|
258
|
+
| `info-background`, `success-background`, … | `bg-info-background`, `text-info-foreground`, … | Full names match **Semantic colors** token columns |
|
|
259
|
+
|
|
260
|
+
Semantic utilities use the **full token name** as the Tailwind segment (e.g. `bg-info-background`, not `bg-info`). For **charts**, utilities follow the **Chart tokens** names (`bg-chart-fjord-color-1`, `bg-chart-gridlines`, …).
|
|
261
|
+
|
|
262
|
+
Tables below list **light-theme** values as `{colors.<name>}` token references in the YAML front matter and **dark-theme** resolved values in the second column; the published `colors.css` is the runtime source of truth (some entries are `rgba()`).
|
|
263
|
+
|
|
264
|
+
### Base — Background
|
|
265
|
+
|
|
266
|
+
| Token | Light (reference) | Dark (reference) | Use |
|
|
267
|
+
| ------------------------------- | ------------------------------------- | ---------------- | ------------------------------------------------------------------ |
|
|
268
|
+
| `background` | `{colors.background}` | `#191B1D` | Primary surface — lowest layer |
|
|
269
|
+
| `alternate-background` | `{colors.alternate-background}` | `#111213` | Distinct layer or block separate from `background` |
|
|
270
|
+
| `card-background` | `{colors.card-background}` | `#212426` | Cards without drop shadow on `background` / `alternate-background` |
|
|
271
|
+
| `muted-background` | `{colors.muted-background}` | `#2D3134` | Static fills for controls, rows, segmented controls |
|
|
272
|
+
| `primary-background` | `{colors.primary}` | `#F9FAFA` | Primary actions (default button); use sparingly |
|
|
273
|
+
| `primary-background-hover` | `{colors.primary-background-hover}` | `#E4E6E8` | Hover on `primary-background` |
|
|
274
|
+
| `secondary-background` | `#E4E6E8` | `#40464A` | Secondary actions, switch track |
|
|
275
|
+
| `secondary-background-hover` | `{colors.secondary-background-hover}` | `#5E666D` | Hover on `secondary-background` |
|
|
276
|
+
| `accent-background` | `#F1F2F3` | `#2D3134` | Neutral hover on `background` / `card-background` (e.g. tabs) |
|
|
277
|
+
| `accent-background-strong` | `#E4E6E8` | `#40464A` | Neutral hover on `muted-background` / `active-muted-background` |
|
|
278
|
+
| `highlight-background` | `#F1F2F3` | `#2D3134` | Focused / active fields (inputs, selects, comboboxes) |
|
|
279
|
+
| `highlight-background-strong` | `#E4E6E8` | `#40464A` | Stronger focused / active field fill |
|
|
280
|
+
| `active-background` | `#191B1D` | `#F9FAFA` | High-contrast “on” (switch, checkbox, radio) |
|
|
281
|
+
| `active-background-hover` | `#2D3134` | `#F1F2F3` | Hover on `active-background` |
|
|
282
|
+
| `active-muted-background` | `#F1F2F3` | `#2D3134` | Lower-contrast selected (e.g. tabs) |
|
|
283
|
+
| `active-muted-background-hover` | `#E4E6E8` | `#40464A` | Hover on `active-muted-background` |
|
|
284
|
+
| `popover-background` | `#FFFFFF` | `#212426` | Top-layer surfaces with shadow (dialogs, popovers) |
|
|
285
|
+
| `raised-background` | `#2D3134` | `#40464A` | Tooltips, Sonner toasts — floats above page |
|
|
286
|
+
| `disabled-background` | `#F1F2F3` | `#2D3134` | Disabled inputs and controls |
|
|
287
|
+
| `overlay-background` | `{colors.overlay-background}` | `#7C868E80` | Scrim behind modals |
|
|
288
|
+
| `background-fixed-dark` | `#212426` | `#212426` | Must stay **dark** in both themes |
|
|
289
|
+
| `background-fixed-light` | `#FFFFFF` | `#FFFFFF` | Must stay **light** in both themes |
|
|
290
|
+
| `accent-background-fixed-dark` | `#2D3134` | `#2D3134` | Persistent dark accent chrome (e.g. sidebar) |
|
|
291
|
+
|
|
292
|
+
### Base — Foreground
|
|
293
|
+
|
|
294
|
+
| Token | Light (reference) | Dark (reference) | Use |
|
|
295
|
+
| ---------------------------------- | -------------------------------- | ---------------- | ------------------------------ |
|
|
296
|
+
| `foreground` | `{colors.foreground}` | `#F1F2F3` | Primary text and icons |
|
|
297
|
+
| `secondary-foreground` | `{colors.secondary-foreground}` | `#D4D7D9` | Supporting text and icons |
|
|
298
|
+
| `muted-foreground` | `{colors.muted-foreground}` | `#A5ABB1` | Tertiary / low emphasis |
|
|
299
|
+
| `disabled-foreground` | `#D4D7D9` | `#5E666D` | Disabled text and icons |
|
|
300
|
+
| `link-foreground` | `{colors.link-foreground}` | `#1742E7` | Text links |
|
|
301
|
+
| `foreground-on-primary` | `{colors.foreground-on-primary}` | `#191B1D` | On `primary-background` |
|
|
302
|
+
| `foreground-on-active` | `#F1F2F3` | `#191B1D` | On `active-background` |
|
|
303
|
+
| `active-foreground` | `#191B1D` | `#F1F2F3` | On `active-muted-background` |
|
|
304
|
+
| `foreground-fixed-dark` | `#191B1D` | `#191B1D` | Must stay dark in both themes |
|
|
305
|
+
| `foreground-fixed-light` | `#FFFFFF` | `#FFFFFF` | Must stay light in both themes |
|
|
306
|
+
| `foreground-secondary-fixed-dark` | `#40464A` | `#40464A` | Secondary copy, always dark |
|
|
307
|
+
| `secondary-foreground-fixed-light` | `#D4D7D9` | `#D4D7D9` | Secondary copy, always light |
|
|
308
|
+
| `muted-foreground-fixed-light` | `#BBC0C4` | `#BBC0C4` | Muted copy, always light |
|
|
309
|
+
|
|
310
|
+
### Base — Borders and focus
|
|
311
|
+
|
|
312
|
+
| Token | Light (reference) | Dark (reference) | Use |
|
|
313
|
+
| ------------------- | ---------------------------- | ---------------- | ------------------------------------------------ |
|
|
314
|
+
| `border` | `{colors.border}` | `#2D3134` | Default strokes |
|
|
315
|
+
| `border-emphasized` | `{colors.border-emphasized}` | `#40464A` | Stronger separation |
|
|
316
|
+
| `border-on-dark` | `#2D3134` | `#2D3134` | Strokes on dark chrome (both themes) |
|
|
317
|
+
| `border-active` | `#191B1D` | `#F9FAFA` | Active / toggled outlines |
|
|
318
|
+
| `ring` | `{colors.ring}` | `#7081C7` | Focus ring outer (maps to `--shadow-focus-ring`) |
|
|
319
|
+
| `ring-muted` | `{colors.ring-muted}` | `#B5BEE2` | Focus ring inner companion |
|
|
50
320
|
|
|
51
|
-
**
|
|
321
|
+
Also generated: `ring-destructive`, `ring-destructive-muted` for destructive / invalid focus (see **Effects — Focus rings**).
|
|
52
322
|
|
|
53
|
-
|
|
54
|
-
- **Must** use **Shimmer** when the layout of incoming content is known (list rows, cards, table skeleton).
|
|
55
|
-
- **Must** use **Loader** for compact inline waits (e.g. inside a **Button** or card header).
|
|
56
|
-
- **Must** use a **full-surface** pattern (centered **Loader**, **Skeleton** layout, or app **PageLoader**) for full-page or high-latency transitions including long AI operations.
|
|
57
|
-
- **Should** use **Progress** when completion is measurable (upload %, stepped flow).
|
|
58
|
-
- **Avoid** blank content areas with no indicator.
|
|
59
|
-
- **Avoid** using only a tiny spinner for large unknown layouts — prefer **Shimmer** / **Skeleton**.
|
|
323
|
+
### Semantic colors
|
|
60
324
|
|
|
61
|
-
|
|
325
|
+
Semantic tokens are **only** for status and system feedback (Alert, Banner, Sonner, badge status variants, validation). Do not use them as generic fills or decoration.
|
|
62
326
|
|
|
63
|
-
**
|
|
327
|
+
Each family has **default** pairings (theme-switching surfaces) and **muted** pairings (blocks on **persistent dark chrome**). On muted surfaces, use the same `*-foreground-on-*` token names with the muted background; verify contrast in context.
|
|
64
328
|
|
|
65
|
-
**
|
|
66
|
-
**App / shell:** Sonner (or equivalent toast), dedicated confirm **AlertDialog** where the shell provides it
|
|
329
|
+
**Info**
|
|
67
330
|
|
|
68
|
-
|
|
331
|
+
| Token | Light (reference) | Dark (reference) | Use |
|
|
332
|
+
| ------------------------- | ---------------------------------- | ---------------- | ----------------------------------------------------------------------------- |
|
|
333
|
+
| `info-background` | `{colors.info-background}` | `#B5BEE2` | Info surface |
|
|
334
|
+
| `info-background-hover` | `#B5BEE2` | `#D0D6ED` | Hover on `info-background` |
|
|
335
|
+
| `info-foreground` | `#4A5FB8` | `#9DA9D9` | Text near info context on standard surfaces |
|
|
336
|
+
| `info-foreground-on-info` | `{colors.info-foreground-on-info}` | `#1A2242` | Text **on** `info-background` |
|
|
337
|
+
| `info-muted-background` | `#F0F2F9` | `#2D3134` | Info tint on dark chrome |
|
|
338
|
+
| _(pairing)_ | — | — | On `info-muted-background`, use `info-foreground-on-info` for on-surface copy |
|
|
69
339
|
|
|
70
|
-
|
|
71
|
-
- **Must** use **transient toast** (e.g. Sonner, bottom-right, ~4s auto-dismiss) for low-stakes confirmations (“Saved”, “Copied”) — theme with Aura tokens.
|
|
72
|
-
- **Must** use **Dialog** (or shell **AlertDialog**) with explicit copy **before** irreversible actions — not only after the fact.
|
|
73
|
-
- **Should** offer **Undo** in the toast when the action is reversible and undo is cheap.
|
|
74
|
-
- **Should** use **Tooltip** (“Copied!”) for copy on small icon targets.
|
|
75
|
-
- **Avoid** `alert()` and other native blocking dialogs for product UX.
|
|
76
|
-
- **Avoid** stacking multiple toasts for a single user gesture.
|
|
340
|
+
**Success**
|
|
77
341
|
|
|
78
|
-
|
|
342
|
+
| Token | Light (reference) | Dark (reference) | Use |
|
|
343
|
+
| ------------------------------- | ---------------------------------------- | ---------------- | ------------------------------------------------------------------ |
|
|
344
|
+
| `success-background` | `{colors.success-background}` | `#8BDEAE` | Success surface |
|
|
345
|
+
| `success-background-hover` | `#8BDEAE` | `#BBF3D0` | Hover on `success-background` |
|
|
346
|
+
| `success-foreground` | `#1C984A` | `#24C45E` | Text near success on standard surfaces |
|
|
347
|
+
| `success-foreground-on-success` | `{colors.success-foreground-on-success}` | `#0A381C` | Text **on** `success-background` |
|
|
348
|
+
| `success-muted-background` | `#DDF9E7` | `#2D3134` | Success on dark chrome |
|
|
349
|
+
| _(pairing)_ | — | — | On `success-muted-background`, use `success-foreground-on-success` |
|
|
79
350
|
|
|
80
|
-
**
|
|
351
|
+
**Warning**
|
|
81
352
|
|
|
82
|
-
|
|
83
|
-
|
|
353
|
+
| Token | Light (reference) | Dark (reference) | Use |
|
|
354
|
+
| ------------------------------- | ---------------------------------------- | ---------------- | -------------------------------------- |
|
|
355
|
+
| `warning-background` | `{colors.warning-background}` | `#FFE3A2` | Warning surface |
|
|
356
|
+
| `warning-background-hover` | `#FFD062` | `#FFF1D0` | Hover on `warning-background` |
|
|
357
|
+
| `warning-foreground` | `#C18800` | `#D8BF00` | Text near warning on standard surfaces |
|
|
358
|
+
| `warning-foreground-on-warning` | `{colors.warning-foreground-on-warning}` | `#5B4000` | Text **on** `warning-background` |
|
|
359
|
+
| `warning-muted-background` | `#FFF1D0` | `#2D3134` | Warning on dark chrome |
|
|
84
360
|
|
|
85
|
-
**
|
|
361
|
+
**Destructive**
|
|
86
362
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
-
|
|
91
|
-
|
|
92
|
-
-
|
|
93
|
-
-
|
|
94
|
-
-
|
|
95
|
-
- **Avoid** treating routine “connecting / connected” or handshake flows as the default **Banner** channel — same rationale as **Avoid** using **Banner** for long onboarding when critical alerts need that channel (§5.3).
|
|
96
|
-
- **Avoid** stacking multiple Alerts inside one card or page section to enumerate line items; aggregate the message and push per-item state to badges or compact status rows.
|
|
363
|
+
| Token | Light (reference) | Dark (reference) | Use |
|
|
364
|
+
| ------------------------------------ | --------------------------------------------- | ---------------- | -------------------------------------------------- |
|
|
365
|
+
| `destructive-background` | `{colors.destructive-background}` | `#FAA9B7` | Error / destructive surface |
|
|
366
|
+
| `destructive-background-hover` | `#FAA9B7` | `#FCCAD2` | Hover on `destructive-background` |
|
|
367
|
+
| `destructive-foreground` | `#CB0B2C` | `#F65E78` | Text near destructive context on standard surfaces |
|
|
368
|
+
| `destructive-foreground-on-critical` | `{colors.destructive-foreground-on-critical}` | `#8D081F` | Text **on** `destructive-background` |
|
|
369
|
+
| `destructive-muted-background` | `#FDDEE4` | `#2D3134` | Destructive on dark chrome |
|
|
370
|
+
| `destructive-muted-background-hover` | `#FCCAD2` | `#40464A` | Hover on `destructive-muted-background` |
|
|
97
371
|
|
|
98
|
-
|
|
372
|
+
**Neutral** (status: draft, archived — not “semantic calm” in the same sense as info/success)
|
|
99
373
|
|
|
100
|
-
|
|
374
|
+
| Token | Light (reference) | Dark (reference) | Use |
|
|
375
|
+
| ------------------------------- | ----------------- | ---------------- | -------------------------------- |
|
|
376
|
+
| `neutral-background` | `#E4E6E8` | `#D4D7D9` | Neutral status surface |
|
|
377
|
+
| `neutral-background-hover` | `#D4D7D9` | `#E4E6E8` | Hover on `neutral-background` |
|
|
378
|
+
| `neutral-foreground` | `#52595F` | `#A5ABB1` | Text near neutral status |
|
|
379
|
+
| `neutral-foreground-on-neutral` | `#40464A` | `#2D3134` | Text **on** `neutral-background` |
|
|
380
|
+
| `neutral-muted-background` | `#F1F2F3` | `#2D3134` | Neutral on dark chrome |
|
|
101
381
|
|
|
102
|
-
|
|
103
|
-
| :--- | :--- | :--- | :--- |
|
|
104
|
-
| **Low** | Non-disruptive updates, minor status, validation hints | `Badge`, notification dot, inline `HelperText` | Does not interrupt the user. Badge for entity state; HelperText for field-level feedback. |
|
|
105
|
-
| **Medium** | Informative, occasionally actionable, not urgent | `Sonner` (toast), `Alert` | Sonner for transient confirmations (~4 s, bottom-right). Alert for inline, page-scoped status that needs awareness but not immediate action (typically one per page section/view). |
|
|
106
|
-
| **High** | Requires immediate attention or action; may interrupt task flow | `Banner` (system errors), `Dialog` / `AlertDialog`, full-page error state | Banner for persistent, region-scoped degraded states. Dialog for irreversible actions. Never use Sonner as the sole safety net for destructive work. |
|
|
382
|
+
**Naming:** CSS uses full role names (`info-foreground-on-info`, `neutral-foreground-on-neutral`, `destructive-foreground-on-critical`). There is no shortened alias in the theme.
|
|
107
383
|
|
|
108
|
-
|
|
384
|
+
### Decorative colors
|
|
109
385
|
|
|
110
|
-
|
|
111
|
-
- **Must not** use Sonner for errors that require user action — it auto-dismisses.
|
|
112
|
-
- **Must not** use repeated Alerts as a list visualization pattern; one Alert communicates the grouped situation, while item-level status belongs in Badge/status-card patterns.
|
|
113
|
-
- **Should** use `Badge` semantic variants (`warning`, `destructive`, `success`) on entities that carry that state, not as page-level alerts.
|
|
114
|
-
- **Avoid** stacking multiple Sonner toasts for a single user gesture.
|
|
386
|
+
For **small accents** (badges, avatars, empty states) where color differentiates but does **not** signal status — use **Chart tokens** for plot colors, not this ramp, unless a design explicitly maps a tile to a series color. Pattern: `decorative-background-{ramp}`, `decorative-background-{ramp}-hover`, `decorative-foreground-{ramp}`.
|
|
115
387
|
|
|
116
|
-
**
|
|
388
|
+
**Preference order for new work:**
|
|
117
389
|
|
|
118
|
-
|
|
390
|
+
| Priority | Ramp | Background | Foreground |
|
|
391
|
+
| -------- | -------- | -------------------------------- | -------------------------------- |
|
|
392
|
+
| 1 | Fjord | `decorative-background-fjord` | `decorative-foreground-fjord` |
|
|
393
|
+
| 2 | Nordic | `decorative-background-nordic` | `decorative-foreground-nordic` |
|
|
394
|
+
| 3 | Aurora | `decorative-background-aurora` | `decorative-foreground-aurora` |
|
|
395
|
+
| 4 | Dusk | `decorative-background-dusk` | `decorative-foreground-dusk` |
|
|
396
|
+
| 5 | Orange | `decorative-background-orange` | `decorative-foreground-orange` |
|
|
397
|
+
| 6 | Sky | `decorative-background-sky` | `decorative-foreground-sky` |
|
|
398
|
+
| 7 | Mountain | `decorative-background-mountain` | `decorative-foreground-mountain` |
|
|
399
|
+
|
|
400
|
+
Example (fjord ramp): light `decorative-background-fjord` → `#CCD5FA` (fjord-200), `decorative-foreground-fjord` → `#1234B6` (fjord-700); dark → `#AEBDF7` / `#0D2582` (fjord-300 / fjord-800).
|
|
401
|
+
|
|
402
|
+
### Chart tokens
|
|
403
|
+
|
|
404
|
+
**Priority rule:** use `chart-*` for any data plotted on axes or series; use `decorative-*` for non-data visual differentiation (tiles, avatars, accents); use semantic tokens (`info-*`, `success-*`, `warning-*`, `destructive-*`) for operational status and feedback only. Never swap between these groups.
|
|
405
|
+
|
|
406
|
+
| Token | Use |
|
|
407
|
+
| ----------------------------------------------- | ----------------------------------------------------------- |
|
|
408
|
+
| `chart-{ramp}-color-1` … `chart-{ramp}-color-6` | Alpha-based series / area-fill steps (strongest → lightest) |
|
|
409
|
+
| `chart-gridlines` | Grid lines |
|
|
410
|
+
|
|
411
|
+
Default series order: **fjord → nordic → aurora → dusk → orange**.
|
|
119
412
|
|
|
120
413
|
---
|
|
121
414
|
|
|
122
|
-
|
|
415
|
+
## Typography
|
|
123
416
|
|
|
124
|
-
|
|
417
|
+
Aura uses **Inter** for product UI, **Space Grotesk** for marketing display, and **Source Code Pro** for monospace. The type scale balances density for data interfaces with readable body copy at `{typography.body-md.fontSize}`.
|
|
125
418
|
|
|
126
|
-
|
|
419
|
+
| Token | Font | Use |
|
|
420
|
+
| ------------------------------ | --------------- | ----------------------------------- |
|
|
421
|
+
| `--font-sans` / `--font-inter` | Inter | Default UI — copy, labels, dense UI |
|
|
422
|
+
| `--font-marketing` | Space Grotesk | Marketing / display headings only |
|
|
423
|
+
| `--font-mono` | Source Code Pro | Code, technical strings |
|
|
127
424
|
|
|
128
|
-
**
|
|
425
|
+
**Type scale** — values live in the YAML `typography` tokens. Typical **semantic styles** map as follows:
|
|
129
426
|
|
|
130
|
-
|
|
427
|
+
| Style | Token | Tailwind class | Use |
|
|
428
|
+
| --------- | ---------------------- | -------------- | ------------------------ |
|
|
429
|
+
| `display` | `{typography.display}` | `text-5xl` | Hero / marketing display |
|
|
430
|
+
| `h1` | `{typography.h1}` | `text-4xl` | Page title |
|
|
431
|
+
| `h2` | `{typography.h2}` | `text-3xl` | Section title |
|
|
432
|
+
| `h3` | `{typography.h3}` | `text-2xl` | Subsection |
|
|
433
|
+
| `h4` | `{typography.h4}` | `text-xl` | Group label |
|
|
434
|
+
| `body-md` | `{typography.body-md}` | `text-base` | Default body |
|
|
435
|
+
| `body-sm` | `{typography.body-sm}` | `text-sm` | Secondary body |
|
|
436
|
+
| `label` | `{typography.label}` | `text-xs` | Form labels, compact UI |
|
|
437
|
+
| `code` | `{typography.code}` | `text-sm` | Monospace content |
|
|
131
438
|
|
|
132
|
-
|
|
439
|
+
---
|
|
133
440
|
|
|
134
|
-
|
|
135
|
-
- **Must** match **Button** `variant` to prominence: `default` = primary CTA, `secondary` / `outline` / `ghost` for supporting actions, `destructive` for irreversible commit.
|
|
136
|
-
- **Must** use a **chevron-down** (or equivalent) on controls that open menus or expandable regions, consistent with **DropdownMenu** / **Collapsible** / **Accordion** patterns.
|
|
137
|
-
- **Should** keep **`pointer`** cursor on interactive surfaces — Aura sets this; do not override without cause.
|
|
138
|
-
- **Avoid** custom “clickable text” that looks identical to body copy.
|
|
441
|
+
## Layout
|
|
139
442
|
|
|
140
|
-
|
|
443
|
+
### Dashboard quick start (agent checklist)
|
|
141
444
|
|
|
142
|
-
|
|
445
|
+
For pages with data-heavy layouts — cards, charts, metric tiles — work through these steps before writing component code.
|
|
143
446
|
|
|
144
|
-
**
|
|
447
|
+
- [ ] **Tokens** — confirm all colors use semantic or chart tokens, no raw hex. Metric tiles: `decorative-*`. Data series: `chart-*`. Status: `info-*`, `success-*`, `warning-*`, `destructive-*`. See [Colors](#colors).
|
|
448
|
+
- [ ] **Layout** — use a 12-column grid with `gap-4` or `gap-6`. Tile widths: `col-span-12 sm:col-span-6 lg:col-span-3`. Cap the page frame with `max-w-[min(100%,var(--container-8xl))]`.
|
|
449
|
+
- [ ] **Cards** — use the `Card` component with title, description, and a primary action. Do not stack unrelated actions in the same card. See [Layout and hierarchy](#6-layout-and-hierarchy).
|
|
450
|
+
- [ ] **Loading states** — every data region must show `Shimmer` (known layout) or `Loader` (unknown layout) while fetching. See [Feedback and system status](#1-feedback-and-system-status).
|
|
451
|
+
- [ ] **Status signals** — default to **Badge** or compact status cards for repeated states; keep **Alert** to one page-level inline instance unless multiple independent incidents each need separate action. See [Alert vs Banner vs Badge vs Sonner](#alert-vs-banner-vs-badge-vs-sonner).
|
|
452
|
+
- [ ] **Navigation** — one primary app chrome; avoid duplicating global navigation inside content. See [Layout and hierarchy](#6-layout-and-hierarchy).
|
|
453
|
+
- [ ] **Accessibility** — every chart must have a text summary of key insights. Icon-only controls must have `aria-label` and a `Tooltip`. See [Accessibility and inclusive design](#7-accessibility-and-inclusive-design).
|
|
145
454
|
|
|
146
|
-
|
|
455
|
+
### Layout and spacing
|
|
147
456
|
|
|
148
|
-
|
|
149
|
-
- **Must** use recognizable patterns (search field + magnifier icon, menu trigger + chevron).
|
|
150
|
-
- **Should** use **Card** + title/description + **Button** for first-use empty views — not a bare white panel.
|
|
151
|
-
- **Avoid** ambiguous icon-only controls without **Tooltip** + accessible name (see §2.3).
|
|
457
|
+
Width and spacing values in this subsection follow the **`{spacing.base}`-based** spacing scale in **[Layout → Size and dimensions](#size-and-dimensions)**.
|
|
152
458
|
|
|
153
|
-
|
|
459
|
+
**Body text reading width**
|
|
154
460
|
|
|
155
|
-
**
|
|
461
|
+
- **Must** cap **continuous body text** (paragraphs, descriptions, long labels) at a **maximum width of `{spacing.prose-max}`** for comfortable reading.
|
|
462
|
+
- **Must** apply that limit to the **text column only** — companion UI (icons, thumbnails, side metadata, charts, code blocks) **may** sit outside that `{spacing.prose-max}` band in the same row or card; do not shrink the text measure to absorb those elements.
|
|
463
|
+
- **Should** implement the cap with `max-w-[{spacing.prose-max}]` / `max-w-[37.5rem]` (or an equivalent layout wrapper) on the text block, not by stretching typography alone inside an arbitrarily wide container.
|
|
464
|
+
|
|
465
|
+
Standard layout primitives used across all patterns:
|
|
466
|
+
|
|
467
|
+
**Content max widths**
|
|
468
|
+
- max-w-7xl — dashboards, full-width layouts
|
|
469
|
+
- max-w-4xl — detail pages
|
|
470
|
+
- max-w-2xl — forms, wizard step content
|
|
471
|
+
- max-w-sm — search inputs, narrow controls
|
|
472
|
+
|
|
473
|
+
**Section spacing**
|
|
474
|
+
- space-y-8 — between major page sections (e.g. form groups)
|
|
475
|
+
- space-y-6 — between sections within a page
|
|
476
|
+
- space-y-4 — between items within a section
|
|
477
|
+
- space-y-2 — between label and field, tight groupings
|
|
478
|
+
|
|
479
|
+
**Grid gaps**
|
|
480
|
+
- gap-6 — dashboard grids, chart grids, panel gaps
|
|
481
|
+
- gap-4 — card grids, metric grids
|
|
482
|
+
- gap-3 — toolbar items, button groups
|
|
483
|
+
|
|
484
|
+
**Page padding**
|
|
485
|
+
- px-6 py-8 — standard content area (desktop)
|
|
486
|
+
- px-4 py-6 — mobile content area
|
|
487
|
+
- p-4 — card/panel internal padding
|
|
488
|
+
- p-6 — larger card internal padding
|
|
489
|
+
|
|
490
|
+
### Layout patterns
|
|
491
|
+
|
|
492
|
+
#### Sidebar content
|
|
493
|
+
3+ top-level sections. Persistent navigation needed.
|
|
494
|
+
Most common for multi-page apps.
|
|
495
|
+
|
|
496
|
+
**Structure**
|
|
497
|
+
|
|
498
|
+
```
|
|
499
|
+
┌──────────┬─────────────────────────────┐
|
|
500
|
+
│ │ Page Header / Breadcrumb │
|
|
501
|
+
│ Sidebar │─────────────────────────────│
|
|
502
|
+
│ Nav │ │
|
|
503
|
+
│ (dark) │ Main Content Area │
|
|
504
|
+
│ │ (bg-background) │
|
|
505
|
+
│ │ │
|
|
506
|
+
└──────────┴─────────────────────────────┘
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
**Responsive behavior**
|
|
510
|
+
Desktop (1440px+): Sidebar 240px, content fills rest.
|
|
511
|
+
Tablet (768px-1439px): Sidebar collapsible via hamburger.
|
|
512
|
+
Mobile (below 768px): Sidebar hidden. Hamburger menu.
|
|
513
|
+
Consider bottom nav for 3-5 primary sections.
|
|
514
|
+
|
|
515
|
+
#### Full-width dashboard
|
|
516
|
+
Data visualizations, metrics, monitoring. Maximum horizontal space needed.
|
|
517
|
+
|
|
518
|
+
**Structure**
|
|
519
|
+
|
|
520
|
+
```
|
|
521
|
+
┌─────────────────────────────────────────┐
|
|
522
|
+
│ Top Navigation Bar │
|
|
523
|
+
├─────────────────────────────────────────┤
|
|
524
|
+
│ Page Header + Filters │
|
|
525
|
+
├─────────────────────────────────────────┤
|
|
526
|
+
│ ┌───────┐ ┌───────┐ ┌───────┐ │
|
|
527
|
+
│ │Metric │ │Metric │ │Metric │ │
|
|
528
|
+
│ └───────┘ └───────┘ └───────┘ │
|
|
529
|
+
├─────────────────────────────────────────┤
|
|
530
|
+
│ Charts / Visualizations │
|
|
531
|
+
├─────────────────────────────────────────┤
|
|
532
|
+
│ Data Table │
|
|
533
|
+
└─────────────────────────────────────────┘
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
**Responsive behavior**
|
|
537
|
+
Desktop: Multi-column grid (grid-cols-3 or grid-cols-4).
|
|
538
|
+
Tablet: 2-column grid. Charts stack.
|
|
539
|
+
Mobile: Single column. Metrics as horizontal scroll.
|
|
540
|
+
|
|
541
|
+
#### Form page
|
|
542
|
+
Data entry, creation flows, configuration, settings with form fields.
|
|
543
|
+
|
|
544
|
+
**Structure**
|
|
545
|
+
|
|
546
|
+
```
|
|
547
|
+
┌─────────────────────────────────────────┐
|
|
548
|
+
│ Page Header + Back navigation │
|
|
549
|
+
├─────────────────────────────────────────┤
|
|
550
|
+
│ ┌───────────────────────────────┐ │
|
|
551
|
+
│ │ Form Section 1 (heading) │ │
|
|
552
|
+
│ │ [fields] │ │
|
|
553
|
+
│ ├───────────────────────────────┤ │
|
|
554
|
+
│ │ Form Section 2 (heading) │ │
|
|
555
|
+
│ │ [fields] │ │
|
|
556
|
+
│ └───────────────────────────────┘ │
|
|
557
|
+
├─────────────────────────────────────────┤
|
|
558
|
+
│ Sticky footer: [Cancel] [Save action] │
|
|
559
|
+
└─────────────────────────────────────────┘
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
**Responsive behavior**
|
|
563
|
+
Desktop: Form centered, max-w-2xl (672px) or max-w-3xl.
|
|
564
|
+
Tablet: Form fills width with px-6 padding.
|
|
565
|
+
Mobile: Full width. Sticky footer stays. Fields stack.
|
|
566
|
+
|
|
567
|
+
#### Detail page
|
|
568
|
+
|
|
569
|
+
Viewing a single record: report details, user profile, item information with related data.
|
|
570
|
+
|
|
571
|
+
**Structure**
|
|
572
|
+
|
|
573
|
+
```
|
|
574
|
+
┌─────────────────────────────────────────┐
|
|
575
|
+
│ Breadcrumb: Reports > Q2 Summary │
|
|
576
|
+
├─────────────────────────────────────────┤
|
|
577
|
+
│ Record Header [Title, status, actions] │
|
|
578
|
+
├─────────────────────────────────────────┤
|
|
579
|
+
│ ┌─────────────────┬───────────────┐ │
|
|
580
|
+
│ │ Main Content │ Sidebar │ │
|
|
581
|
+
│ │ (2/3 width) │ (1/3 width) │ │
|
|
582
|
+
│ └─────────────────┴───────────────┘ │
|
|
583
|
+
└─────────────────────────────────────────┘
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
**Responsive behavior**
|
|
587
|
+
Desktop: Two-column (grid-cols-3, main span-2, sidebar span-1).
|
|
588
|
+
Tablet: Sidebar below main content.
|
|
589
|
+
Mobile: Single column. Sidebar collapses.
|
|
590
|
+
|
|
591
|
+
|
|
592
|
+
#### Settings page
|
|
593
|
+
App preferences, account settings, notification config.
|
|
594
|
+
|
|
595
|
+
**Structure**
|
|
596
|
+
|
|
597
|
+
```
|
|
598
|
+
┌─────────────────────────────────────────┐
|
|
599
|
+
│ Page Header: Settings │
|
|
600
|
+
├───────────┬─────────────────────────────┤
|
|
601
|
+
│ Settings │ Section Content │
|
|
602
|
+
│ Nav │ [Form fields / toggles] │
|
|
603
|
+
└───────────┴─────────────────────────────┘
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
**Responsive behavior**
|
|
607
|
+
Desktop: Left nav + content area.
|
|
608
|
+
Tablet: Top tabs replacing left nav.
|
|
609
|
+
Mobile: Category list → tap opens section full-screen.
|
|
610
|
+
|
|
611
|
+
#### Split screen
|
|
612
|
+
Comparison views, editor + preview, master-detail with equal emphasis on both sides.
|
|
613
|
+
|
|
614
|
+
**Structure**
|
|
615
|
+
|
|
616
|
+
```
|
|
617
|
+
┌─────────────────────┬─────────────────────┐
|
|
618
|
+
│ │ │
|
|
619
|
+
│ Panel Left │ Panel Right │
|
|
620
|
+
│ (1/2 width) │ (1/2 width) │
|
|
621
|
+
│ │ │
|
|
622
|
+
└─────────────────────┴─────────────────────┘
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
**Responsive behavior**
|
|
626
|
+
Desktop: grid-cols-2, equal columns.
|
|
627
|
+
Tablet: grid-cols-2 with narrower gap.
|
|
628
|
+
Mobile: Stack vertically (grid-cols-1), or use Segmented Control to switch between panels.
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
#### Three panel
|
|
632
|
+
Navigation + content + properties panel. IDE-style layouts. Complex editing workflows with context panels.
|
|
633
|
+
|
|
634
|
+
**Structure**
|
|
635
|
+
|
|
636
|
+
```
|
|
637
|
+
┌──────────┬───────────────────┬──────────┐
|
|
638
|
+
│ │ │ │
|
|
639
|
+
│ Nav/ │ Main Content │ Props/ │
|
|
640
|
+
│ Tree │ (flexible) │ Detail │
|
|
641
|
+
│ (fixed) │ │ (fixed) │
|
|
642
|
+
│ │ │ │
|
|
643
|
+
└──────────┴───────────────────┴──────────┘
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
**Responsive behavior**
|
|
647
|
+
Desktop (1440px+): All 3 panels visible.
|
|
648
|
+
Tablet (768-1439px): Hide right panel, toggle via button.
|
|
649
|
+
Mobile (below 768px): Single panel with navigation as Drawer, right panel as bottom sheet or separate route.
|
|
650
|
+
|
|
651
|
+
#### List page
|
|
652
|
+
Browsing collections — reports, users, assets, items. The most common page type in data-heavy applications.
|
|
653
|
+
|
|
654
|
+
|
|
655
|
+
**Structure**
|
|
656
|
+
|
|
657
|
+
```
|
|
658
|
+
┌──────────────────────────────────────────┐
|
|
659
|
+
│ Page Header [Title] [Create button] │
|
|
660
|
+
├──────────────────────────────────────────┤
|
|
661
|
+
│ Filters toolbar [Search] [Filters] │
|
|
662
|
+
├──────────────────────────────────────────┤
|
|
663
|
+
│ Table / List │
|
|
664
|
+
│ (with empty state when no data) │
|
|
665
|
+
├──────────────────────────────────────────┤
|
|
666
|
+
│ Pagination │
|
|
667
|
+
└──────────────────────────────────────────┘
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
**Responsive behavior**
|
|
671
|
+
Desktop: Full table with all columns visible.
|
|
672
|
+
Tablet: Hide non-essential columns, allow horizontal scroll.
|
|
673
|
+
Mobile: Switch to card/list view with stackable filters.
|
|
674
|
+
|
|
675
|
+
#### Wizard
|
|
676
|
+
Multi-step creation flows, onboarding, configuration wizards, setup processes.
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
**Structure**
|
|
680
|
+
|
|
681
|
+
```
|
|
682
|
+
┌──────────────────────────────────────────┐
|
|
683
|
+
│ Step indicator (1 — 2 — 3 — 4) │
|
|
684
|
+
├──────────────────────────────────────────┤
|
|
685
|
+
│ │
|
|
686
|
+
│ Step Content Area │
|
|
687
|
+
│ (centered, max-w-2xl) │
|
|
688
|
+
│ │
|
|
689
|
+
├──────────────────────────────────────────┤
|
|
690
|
+
│ [Back] [Next/Submit] │
|
|
691
|
+
└──────────────────────────────────────────┘
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
**Responsive behavior**
|
|
695
|
+
Desktop: Centered content, horizontal numbered step indicator.
|
|
696
|
+
Tablet: Same layout with px-6 padding.
|
|
697
|
+
Mobile: Step indicator becomes compact ("Step 2 of 4"), content fills width.
|
|
156
698
|
|
|
157
|
-
|
|
699
|
+
### Size and dimensions
|
|
158
700
|
|
|
159
|
-
**
|
|
701
|
+
Aura aligns to a **`{spacing.base}` base grid**. Spacing in components follows **Tailwind spacing** (`p-*`, `gap-*`, `m-*`): one unit = **`{spacing.base}`** unless overridden. Common steps:
|
|
702
|
+
|
|
703
|
+
| Name | Token | Tailwind | Typical use |
|
|
704
|
+
| ---- | --------------- | -------- | -------------------------------- |
|
|
705
|
+
| xs | `{spacing.xs}` | `1` | Tight gaps, icon padding |
|
|
706
|
+
| sm | `{spacing.sm}` | `2` | Inline controls, compact padding |
|
|
707
|
+
| md | `{spacing.md}` | `3` | Card / popover internal padding |
|
|
708
|
+
| lg | `{spacing.lg}` | `4` | Related groups |
|
|
709
|
+
| xl | `{spacing.xl}` | `5` | Sections |
|
|
710
|
+
| 2xl | `{spacing.2xl}` | `6` | Page regions |
|
|
711
|
+
| 3xl | `{spacing.3xl}` | `8` | Large layout gaps |
|
|
712
|
+
|
|
713
|
+
Layout helpers in theme: `--container-2xl` (`{spacing.container-2xl}`), `--container-8xl` (`{spacing.container-8xl}`), `--message-content-max-width` (80% for chat content).
|
|
714
|
+
|
|
715
|
+
### Width and max content
|
|
716
|
+
|
|
717
|
+
Aura adjusts Tailwind **container** breakpoints where the default scale is too wide or too narrow for data-dense product surfaces:
|
|
718
|
+
|
|
719
|
+
| Token | Value | Role |
|
|
720
|
+
| ----------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
721
|
+
| `--container-2xl` | `{spacing.container-2xl}` | Narrower than Tailwind’s default `2xl` container — useful outer bound for regions; **body copy** inside can still follow the **`{spacing.prose-max}`** reading rule above |
|
|
722
|
+
| `--container-8xl` | `{spacing.container-8xl}` | Wide upper bound for dashboards and full-bleed marketing rows |
|
|
723
|
+
|
|
724
|
+
Prefer **`max-w-*`** (and other width utilities) tied to the theme over ad-hoc pixel `max-width` on wrappers. **Global frame** width (host chrome) is defined by the **host application**; **inside** the frame, combine these tokens with responsive utilities so regions reflow predictably.
|
|
725
|
+
|
|
726
|
+
### Specialized variables
|
|
727
|
+
|
|
728
|
+
| Variable | Value | Use |
|
|
729
|
+
| ----------------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------- |
|
|
730
|
+
| `--message-content-max-width` | `80%` | Primary column for chat / assistant **Message** content in wide threads |
|
|
731
|
+
| `--drawer-max-height` | `80vh` | Maximum height for top/bottom drawer-style panels when the host implements them |
|
|
732
|
+
| `--alert-icon-width` | `calc(var(--spacing) * 4)` (typically **16px**) | Fixed icon column in the **Alert** layout so titles and descriptions align |
|
|
733
|
+
|
|
734
|
+
### Regional spacing
|
|
735
|
+
|
|
736
|
+
- **Must** use the **spacing scale** for padding, margin, and `gap` between regions (`gap-*`, `p-*`, `m-*`) — see **Layout → Size and dimensions**.
|
|
737
|
+
- **Should** keep major block **padding** and **gap** on **`{spacing.base}`** multiples so control heights, radii, and typography line up visually.
|
|
738
|
+
- **Should** group related regions in **Card** (and **Separator** when two unrelated groups share a container) before mixing unrelated actions into the same band — see [Layout and hierarchy](#6-layout-and-hierarchy).
|
|
739
|
+
- **Avoid** one-off pixel gutters that ignore the scale unless matching a fixed graphic asset.
|
|
740
|
+
|
|
741
|
+
### Responsive behavior
|
|
742
|
+
|
|
743
|
+
- **Should** move secondary work into **Dialog** or a shell **Drawer** on narrow widths instead of compressing multi-column chrome.
|
|
744
|
+
- **Avoid** single-breakpoint layouts tuned only to a static design frame — use breakpoints, wrapping, and flexible sizing utilities where content must grow and shrink.
|
|
745
|
+
|
|
746
|
+
### Shell vs content
|
|
160
747
|
|
|
161
|
-
- **Must**
|
|
162
|
-
- **Must** use **HelperText** under fields for format and constraints **before** error.
|
|
163
|
-
- **Should** use **Popover** / **HoverCard** when help needs paragraphs or links.
|
|
164
|
-
- **Avoid** **Tooltip** as the **only** place for information users must have on touch-first flows.
|
|
748
|
+
**Global chrome** (workspace switcher, app-level navigation) is implemented by the **host application shell**, not the Aura component library. **Must** still theme that chrome with Aura **tokens** so shell and in-app surfaces feel continuous. **In-app content** should rely on Aura primitives (**Card**, **Banner**, **Dialog**, forms) plus the width and spacing rules above.
|
|
165
749
|
|
|
166
750
|
---
|
|
167
751
|
|
|
168
|
-
|
|
752
|
+
## Elevation & Depth
|
|
169
753
|
|
|
170
|
-
|
|
754
|
+
### Shadows
|
|
171
755
|
|
|
172
|
-
|
|
756
|
+
`--effect-shadow-sm` through `--effect-shadow-xl` are **alpha blacks** tuned per theme. Tailwind shadow utilities compose layered stacks from these tokens:
|
|
173
757
|
|
|
174
|
-
|
|
758
|
+
| Tailwind shadow | Built from `--effect-shadow-*` | Light (α) | Dark (α) | Use (per theme comments in CSS) |
|
|
759
|
+
| ---------------- | ------------------------------ | ----------- | ----------- | -------------------------------------------------- |
|
|
760
|
+
| `shadow-sm` | `--effect-shadow-sm` | 0.04 | 0.2 | Tooltips, small floating containers |
|
|
761
|
+
| `shadow-default` | md + sm layers | 0.05 + 0.04 | 0.302 + 0.2 | Menus, popovers, hover cards |
|
|
762
|
+
| `shadow-md` | lg + md layers | 0.06 + 0.05 | 0.4 + 0.302 | Sonner toasts, temporary elevated elements |
|
|
763
|
+
| `shadow-lg` | xl + lg layers | 0.10 + 0.06 | 0.6 + 0.4 | Modals / dialogs **without** full backdrop overlay |
|
|
764
|
+
| `shadow-xl` | xl + lg layers | 0.10 + 0.06 | 0.6 + 0.4 | Modals / dialogs **with** backdrop overlay |
|
|
175
765
|
|
|
176
|
-
|
|
177
|
-
**App:** `Sheet`, `Drawer` where the shell provides them — still use Aura tokens
|
|
766
|
+
Exact pixel stacks are defined in the theme CSS alongside `--shadow-sm` … `--shadow-xl`.
|
|
178
767
|
|
|
179
|
-
|
|
768
|
+
### Focus rings
|
|
769
|
+
|
|
770
|
+
Shadow-based (not `outline`) for consistent rendering:
|
|
180
771
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
-
|
|
184
|
-
-
|
|
185
|
-
- **Avoid** nesting **Accordion** more than one level.
|
|
772
|
+
| Token | Composition | Use |
|
|
773
|
+
| --------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------- |
|
|
774
|
+
| `--shadow-focus-ring` | `0 0 0 1px var(--ring)` (`{colors.ring}`), `0 0 0 3px var(--ring-muted)` (`{colors.ring-muted}`) | Default focus on interactive controls |
|
|
775
|
+
| `--shadow-focus-ring-destructive` | `0 0 0 1px var(--ring-destructive), 0 0 0 3px var(--ring-destructive-muted)` | Destructive / invalid focus |
|
|
186
776
|
|
|
187
|
-
|
|
777
|
+
### Opacity
|
|
188
778
|
|
|
189
|
-
|
|
779
|
+
| Token / concept | Value | Use |
|
|
780
|
+
| ------------------------------------------------ | ------------------------ | --------------------------------- |
|
|
781
|
+
| `--opacity-10` … `--opacity-80` (+ `*-inverted`) | rgba steps | Overlays, glass effects |
|
|
782
|
+
| Overlay scrim | via `overlay-background` | Modal backdrop (see color tables) |
|
|
783
|
+
| Chart fills | `chart-*-color-*` | See **Chart tokens** |
|
|
190
784
|
|
|
191
|
-
|
|
785
|
+
---
|
|
192
786
|
|
|
193
|
-
|
|
787
|
+
## Shapes
|
|
194
788
|
|
|
195
|
-
|
|
196
|
-
- **Must** let users return to earlier steps unless that causes data loss.
|
|
197
|
-
- **Avoid** multiple irreversible **primary** decisions in one step.
|
|
789
|
+
### Corner radius
|
|
198
790
|
|
|
199
|
-
|
|
791
|
+
Defined in the theme. Default interactive radius in components is often **`rounded-lg`** (`{rounded.lg}`) for buttons/inputs; cards and overlays use **`rounded-lg`**–**`rounded-xl`** (`{rounded.lg}`–`{rounded.xl}`).
|
|
200
792
|
|
|
201
|
-
|
|
793
|
+
| CSS variable | Token | Use |
|
|
794
|
+
| -------------------------- | ---------------- | -------------------------------------------------------------- |
|
|
795
|
+
| `--radius-none` | `{rounded.none}` | Dividers, full-bleed |
|
|
796
|
+
| `--radius-xs` | `{rounded.xs}` | Tight inner chrome |
|
|
797
|
+
| `--radius-sm` | `{rounded.sm}` | Small controls, badges |
|
|
798
|
+
| `--radius-md` / `--radius` | `{rounded.md}` | Maps to `rounded-md` — shared default in theme |
|
|
799
|
+
| `--radius-lg` | `{rounded.lg}` | **Default** for many controls (Button, Input) via `rounded-lg` |
|
|
800
|
+
| `--radius-xl` | `{rounded.xl}` | Dialogs, large cards, popovers |
|
|
801
|
+
| `--radius-2xl` | `{rounded.2xl}` | Extra-large surfaces |
|
|
802
|
+
| `--radius-3xl` | `{rounded.3xl}` | Marketing / hero panels |
|
|
803
|
+
| `--radius-4xl` | `{rounded.4xl}` | Largest marketing rounding |
|
|
804
|
+
| `--radius-full` | `{rounded.full}` | Pills, avatars |
|
|
202
805
|
|
|
203
|
-
|
|
204
|
-
|
|
806
|
+
### Borders
|
|
807
|
+
|
|
808
|
+
Aura is visually **flat**; surfaces, spacing, and typography do most structure. Add borders only when separation or affordance needs extra clarity.
|
|
205
809
|
|
|
206
810
|
**Rules**
|
|
207
811
|
|
|
208
|
-
- **Must**
|
|
209
|
-
- **
|
|
210
|
-
- **Should**
|
|
211
|
-
- **Avoid**
|
|
812
|
+
- **Must** treat borders/strokes as structural signals (inputs, table boundaries, critical separators), not decoration.
|
|
813
|
+
- **Should** distinguish line items inside cards with spacing, alignment, and type hierarchy before adding dividers.
|
|
814
|
+
- **Should** prefer one outer container boundary over many nested per-row outlines in the same card.
|
|
815
|
+
- **Avoid** drawing borders around every item in a list/card just to create visual rhythm.
|
|
816
|
+
- **Avoid** decorative outline stacks (`border` + `ring` + inset strokes) when no state or interaction meaning is conveyed.
|
|
817
|
+
|
|
818
|
+
| Concept | Value | Use |
|
|
819
|
+
| ---------------- | -------------------------------- | ---------------------------------------------------------------------- |
|
|
820
|
+
| Default width | **1px** | Tailwind `border` — tables, inputs, and occasional structural dividers |
|
|
821
|
+
| Emphasized width | **2px** | Stronger separation or invalid/critical state emphasis |
|
|
822
|
+
| Border color | `border`, `border-emphasized`, … | See **Base — Borders and focus** |
|
|
823
|
+
| Style | solid | Default |
|
|
212
824
|
|
|
213
825
|
---
|
|
214
826
|
|
|
215
|
-
|
|
827
|
+
## Primitive components
|
|
216
828
|
|
|
217
|
-
|
|
829
|
+
### Primitive component heights
|
|
218
830
|
|
|
219
|
-
|
|
831
|
+
Heights are **not** always single CSS variables; primitives use Tailwind height utilities. Representative values from core components:
|
|
220
832
|
|
|
221
|
-
|
|
833
|
+
| Size | Component token | Height | Aura usage |
|
|
834
|
+
| ----------- | ----------------------------- | -------------- | --------------------------------------------- |
|
|
835
|
+
| xs | `{components.badge-xs}` | 20px (`h-5`) | Badge (default) |
|
|
836
|
+
| sm | `{components.button-sm}` | 28px (`h-7`) | Button `sm`, compact rows |
|
|
837
|
+
| md | `{components.button-primary}` | 36px (`h-9`) | Button default, Input, Select, many menu rows |
|
|
838
|
+
| lg | `{components.button-lg}` | 40px (`h-10`) | Button `lg` |
|
|
839
|
+
| Icon button | sm / md / lg tokens | 28 / 36 / 40px | `icon-sm` / default / `icon-lg` |
|
|
222
840
|
|
|
223
|
-
**Aura
|
|
224
|
-
**App:** `AlertDialog` / confirm flow where supplied by shell
|
|
841
|
+
**Topbar** height is **application-defined** (not a single Aura token). **Table / list row** density varies by product; menu and command patterns often use **`{components.button-primary.height}`** (`h-9`) rows.
|
|
225
842
|
|
|
226
|
-
**Rules**
|
|
227
843
|
|
|
228
|
-
- **Must** confirm high-impact destructive actions in a **Dialog** (or **AlertDialog**) **before** execution.
|
|
229
|
-
- **Must** name what will be destroyed — not generic “Are you sure?”.
|
|
230
|
-
- **Must** label the confirm action with a **specific verb** (“Delete report”), not “OK”.
|
|
231
|
-
- **Should** use **Button** `variant="destructive"` for the confirming destructive action.
|
|
232
|
-
- **Avoid** toast as the **only** safety net for irreversible work.
|
|
233
844
|
|
|
234
|
-
|
|
845
|
+
### Global primitive rules
|
|
235
846
|
|
|
236
|
-
|
|
847
|
+
1. Prefer primitives over custom components.
|
|
848
|
+
2. Keep behavior accessible (keyboard activation, focus visibility, and clear state changes).
|
|
849
|
+
3. Do not hide critical information if users need fast comparison or repeated switching.
|
|
850
|
+
4. When selection is required before action, prefer contextual actions tied to that selection.
|
|
851
|
+
5. Use Storybook for exact variants, props, and implementation details.
|
|
237
852
|
|
|
238
|
-
|
|
853
|
+
### Primitive guidance
|
|
239
854
|
|
|
240
|
-
|
|
855
|
+
Sections are in alphabetical order. For each component, the Storybook link is the primary reference for variants and props; the docs link is the primary reference for usage and design guidance.
|
|
241
856
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
- **Must** gate “next step” until blocking errors are resolved.
|
|
245
|
-
- **Must** use component **`error`** / invalid props where **Input** / **Select** expose them — do not invent parallel red borders.
|
|
246
|
-
- **Should** validate on **blur** when the value is incomplete mid-typing.
|
|
247
|
-
- **Should** validate live when rules are cheap (length, pattern).
|
|
248
|
-
- **Avoid** revealing every error only on final submit with no prior field feedback.
|
|
857
|
+
#### Storybook reference
|
|
858
|
+
Anytime you need to reference a component in Storybook, use the following URL and replace the slug with the component's Storybook slug: https://master--695bb4b1b8041ae09768950a.chromatic.com/?path=/docs/primitives-{storybook-slug}--docs
|
|
249
859
|
|
|
250
|
-
####
|
|
860
|
+
#### Docs reference
|
|
861
|
+
Anytime you need to reference a component in docs, use the following URL and replace the slug with the component's doc slug: https://docs.cognite.com/aura-design-system/primitives/{docs-slug}
|
|
251
862
|
|
|
252
|
-
|
|
863
|
+
#### Accordion
|
|
253
864
|
|
|
254
|
-
**
|
|
255
|
-
**
|
|
865
|
+
**Storybook-slug:** accordion
|
|
866
|
+
**Docs-slug:** accordion
|
|
256
867
|
|
|
257
|
-
**
|
|
868
|
+
**Definition**
|
|
869
|
+
Accordion reveals and hides grouped content sections to reduce cognitive load and page density.
|
|
258
870
|
|
|
259
|
-
|
|
260
|
-
-
|
|
261
|
-
-
|
|
871
|
+
**Use when**
|
|
872
|
+
- Grouping settings in side/config panels.
|
|
873
|
+
- Breaking long forms into manageable sections.
|
|
874
|
+
- Organizing docs/FAQ/help content.
|
|
875
|
+
- Showing nested information hierarchies.
|
|
262
876
|
|
|
263
|
-
|
|
877
|
+
**Use something else when**
|
|
878
|
+
- All content must stay visible for comparison/scanning.
|
|
879
|
+
- Content is short and easy to read without progressive disclosure.
|
|
880
|
+
- Users are making high-stakes or multi-step decisions where hidden content can cause errors.
|
|
264
881
|
|
|
265
|
-
**
|
|
882
|
+
**Dos and don'ts**
|
|
883
|
+
- Do use clear, specific section titles.
|
|
884
|
+
- Do keep icon and heading behavior consistent.
|
|
885
|
+
- Do not use for very short/simple content.
|
|
886
|
+
- Do not nest accordions.
|
|
266
887
|
|
|
267
|
-
**
|
|
268
|
-
|
|
888
|
+
**Behavior**
|
|
889
|
+
- Header controls expand/collapse via click/tap/Enter/Space.
|
|
890
|
+
- Support multi-expand unless product pattern requires single-expand.
|
|
891
|
+
- Keep expanded content available to assistive tech.
|
|
269
892
|
|
|
270
|
-
**
|
|
893
|
+
**Often used with**
|
|
894
|
+
- `Separator`, section headings, and form controls inside panel content.
|
|
271
895
|
|
|
272
|
-
|
|
273
|
-
- **Must** keep undo inside the same session without deep navigation gymnastics.
|
|
274
|
-
- **Avoid** relying on undo alone for high-stakes actions — still confirm where appropriate (§4.1).
|
|
896
|
+
#### Action Toolbar
|
|
275
897
|
|
|
276
|
-
|
|
898
|
+
**Storybook-slug:** actiontoolbar
|
|
899
|
+
**Docs-slug:** action-toolbar
|
|
277
900
|
|
|
278
|
-
|
|
901
|
+
**Definition**
|
|
902
|
+
Action toolbar is a transient bottom-aligned action row that appears when users select items (for example in data-heavy views).
|
|
279
903
|
|
|
280
|
-
|
|
904
|
+
**Use when**
|
|
905
|
+
- Actions apply only to selected items.
|
|
906
|
+
- You need to reduce persistent toolbar clutter in tables/lists/cards.
|
|
907
|
+
- The workflow depends on selected state before next actions are valid.
|
|
281
908
|
|
|
282
|
-
|
|
909
|
+
**Use something else when**
|
|
910
|
+
- Actions are page-level and do not require selection first (use a standard toolbar/page actions).
|
|
283
911
|
|
|
284
|
-
**
|
|
912
|
+
**Dos and don'ts**
|
|
913
|
+
- Do keep actions contextual to the current selection.
|
|
914
|
+
- Do keep the set focused (use overflow when needed).
|
|
915
|
+
- Do center it in the container/page scope.
|
|
916
|
+
- Do not make it draggable.
|
|
285
917
|
|
|
286
|
-
**
|
|
918
|
+
**Behavior**
|
|
919
|
+
- Hidden by default; appears after selection.
|
|
920
|
+
- Anchored to bottom area; remains until selection clears, action completes, or user navigates away.
|
|
921
|
+
- If no reload occurs, it exits after action completion.
|
|
287
922
|
|
|
288
|
-
**
|
|
923
|
+
**Often used with**
|
|
924
|
+
- Selection patterns in data views, `Checkbox`, `Button`, `Menu`, and `Tooltip` for icon-only actions.
|
|
289
925
|
|
|
290
|
-
|
|
291
|
-
- **Must** render shortcut glyphs with **CommandShortcut** / **DropdownMenuShortcut** — not bespoke styled `<kbd>`.
|
|
292
|
-
- **Should** align with platform norms (e.g. ⌘/Ctrl+S, ⌘/Ctrl+K) where they do not fight the browser.
|
|
293
|
-
- **Avoid** stealing OS or browser reserved shortcuts.
|
|
926
|
+
#### Alert
|
|
294
927
|
|
|
295
|
-
|
|
928
|
+
**Storybook-slug:** alert
|
|
929
|
+
**Docs-slug:** alert
|
|
296
930
|
|
|
297
|
-
**
|
|
931
|
+
**Definition**
|
|
932
|
+
Alert communicates contextual, medium-emphasis information inside page/task flow. It is not a blocking modal.
|
|
298
933
|
|
|
299
|
-
**
|
|
300
|
-
|
|
934
|
+
**Use when**
|
|
935
|
+
- Providing inline guidance/recommendations in the current task.
|
|
936
|
+
- Calling attention to warnings/issues that need awareness but are not blocking.
|
|
937
|
+
- Offering direct actions that resolve the issue in context.
|
|
301
938
|
|
|
302
|
-
**
|
|
939
|
+
**Dos and don'ts**
|
|
940
|
+
- Do include action buttons only when actions are directly related to resolving/dismissing the alert.
|
|
941
|
+
- Do evaluate simpler feedback methods first (for example field-level validation).
|
|
942
|
+
- Do not attach unrelated actions.
|
|
303
943
|
|
|
304
|
-
|
|
305
|
-
-
|
|
306
|
-
-
|
|
307
|
-
-
|
|
944
|
+
**Placement**
|
|
945
|
+
- Align with surrounding content; do not pin flush against dividers.
|
|
946
|
+
- Use card style for wrapped content in constrained areas.
|
|
947
|
+
- Use strip style for short messages in wider areas.
|
|
308
948
|
|
|
309
|
-
|
|
949
|
+
**Behavior**
|
|
950
|
+
- Inline with page flow (not full-screen blocking).
|
|
951
|
+
- Dismissal removes/hides alert per variant.
|
|
952
|
+
- Action path should be clear and minimal.
|
|
310
953
|
|
|
311
|
-
**
|
|
954
|
+
**Often used with**
|
|
955
|
+
- `Button` for direct resolution actions.
|
|
312
956
|
|
|
313
|
-
|
|
957
|
+
#### Alert Dialog
|
|
314
958
|
|
|
315
|
-
**
|
|
959
|
+
**Docs-slug:** alert-dialog
|
|
316
960
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
- **Should** use **HelperText** / **Tooltip** for compact role- or context-specific hints.
|
|
320
|
-
- **Avoid** using **Banner** for long onboarding tours if **Banner** is already the channel for critical system alerts — mixed priority dilutes both.
|
|
961
|
+
**Definition**
|
|
962
|
+
Short, focused confirmation or acknowledgment that interrupts the user for a clear binary or limited choice.
|
|
321
963
|
|
|
322
|
-
|
|
964
|
+
**Use when**
|
|
965
|
+
- Confirming destructive or irreversible actions.
|
|
966
|
+
- Blocking until the user chooses from a small set of options.
|
|
323
967
|
|
|
324
|
-
|
|
968
|
+
**Use something else when**
|
|
969
|
+
- Inline persistence is enough (`Alert`).
|
|
970
|
+
- The flow requires a form or multi-field input (`Dialog`).
|
|
971
|
+
- A quick acknowledgment is sufficient (`Sonner Toast`).
|
|
325
972
|
|
|
326
|
-
|
|
973
|
+
**Often used with**
|
|
974
|
+
- `Button` (destructive variant) as the trigger.
|
|
327
975
|
|
|
328
|
-
####
|
|
976
|
+
#### Avatar
|
|
329
977
|
|
|
330
|
-
**
|
|
978
|
+
**Storybook-slug:** avatar
|
|
979
|
+
**Docs-slug:** avatar
|
|
331
980
|
|
|
332
|
-
**
|
|
981
|
+
**Definition**
|
|
982
|
+
Avatar visually represents a user, team, or concept and helps recognition in collaborative UI.
|
|
333
983
|
|
|
334
|
-
**
|
|
984
|
+
**Use when**
|
|
985
|
+
- Showing people in comments, chat, sharing, or collaborators.
|
|
986
|
+
- Representing accounts, teams, or organizations.
|
|
987
|
+
- Displaying AI/agent identities in conversational interfaces.
|
|
335
988
|
|
|
336
|
-
|
|
337
|
-
-
|
|
338
|
-
-
|
|
339
|
-
-
|
|
340
|
-
-
|
|
989
|
+
**Behavior**
|
|
990
|
+
- Choose size based on context density.
|
|
991
|
+
- Use overflow patterns for constrained spaces (for example +N with menu).
|
|
992
|
+
- Can be informational or interactive based on context.
|
|
993
|
+
- Can include status badges/dots.
|
|
341
994
|
|
|
342
|
-
|
|
995
|
+
**Often used with**
|
|
996
|
+
- `Badge`, `Tooltip`, `Menu`.
|
|
343
997
|
|
|
344
|
-
|
|
998
|
+
#### Badge
|
|
345
999
|
|
|
346
|
-
**
|
|
347
|
-
**
|
|
1000
|
+
**Storybook-slug:** badge
|
|
1001
|
+
**Docs-slug:** badge
|
|
348
1002
|
|
|
349
|
-
**
|
|
1003
|
+
**Definition**
|
|
1004
|
+
Compact label for status, category, or metadata.
|
|
350
1005
|
|
|
351
|
-
|
|
352
|
-
-
|
|
353
|
-
-
|
|
1006
|
+
**Use when**
|
|
1007
|
+
- Surfacing state at a glance (for example active, draft, error).
|
|
1008
|
+
- Tagging items without taking primary focus from the page.
|
|
354
1009
|
|
|
355
|
-
|
|
1010
|
+
**Use something else when**
|
|
1011
|
+
- The message needs explanation or recovery steps (consider `Alert` or inline text).
|
|
1012
|
+
- You need a primary action (use `Button`).
|
|
356
1013
|
|
|
357
|
-
**
|
|
1014
|
+
**Often used with**
|
|
1015
|
+
- `Avatar`, tables and lists, filter chips.
|
|
358
1016
|
|
|
359
|
-
|
|
1017
|
+
#### Banner
|
|
360
1018
|
|
|
361
|
-
**
|
|
1019
|
+
**Storybook-slug:** banner
|
|
1020
|
+
**Docs-slug:** banner-alert
|
|
362
1021
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
- **Must not** use **Button** `destructive` for non-destructive actions.
|
|
366
|
-
- **Should** use type scale, weight, and spacing (**Tokens** § Typography / spacing) to lead attention.
|
|
1022
|
+
**Definition**
|
|
1023
|
+
Persistent or dismissible message scoped at page or section level — stronger than inline helper text, broader than a single-field `Alert` in some layouts.
|
|
367
1024
|
|
|
368
|
-
|
|
1025
|
+
**Use when**
|
|
1026
|
+
- Announcing environment or product state (maintenance, trial, feature preview).
|
|
1027
|
+
- Page-wide outcomes that should stay visible while the user continues.
|
|
369
1028
|
|
|
370
|
-
**
|
|
1029
|
+
**Use something else when**
|
|
1030
|
+
- Task-specific guidance inside a flow (`Alert`).
|
|
1031
|
+
- Brief confirmation after an action (`Sonner Toast`).
|
|
371
1032
|
|
|
372
|
-
|
|
373
|
-
**Fusion shell:** `Topbar` overflow behavior
|
|
1033
|
+
#### Breadcrumb
|
|
374
1034
|
|
|
375
|
-
**
|
|
1035
|
+
**Storybook-slug:** breadcrumb
|
|
1036
|
+
**Docs-slug:** breadcrumbs
|
|
376
1037
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
- **Avoid** hard-coded pixel widths that bypass Tailwind and Aura layout tokens.
|
|
1038
|
+
**Definition**
|
|
1039
|
+
Hierarchical navigation aid that shows users their current location within the product's structure. Location-based, not path-based.
|
|
380
1040
|
|
|
381
|
-
|
|
1041
|
+
**Use when**
|
|
1042
|
+
- Users need to return to a parent page.
|
|
1043
|
+
- Users need clarity on their current position in the product hierarchy.
|
|
1044
|
+
- Quick access to ancestor pages is useful.
|
|
382
1045
|
|
|
383
|
-
|
|
1046
|
+
**Use something else when**
|
|
1047
|
+
- The page structure is flat — there is no hierarchy to show.
|
|
1048
|
+
- Users are switching between same-level content (use `Tabs` or `Segmented Control`).
|
|
384
1049
|
|
|
385
|
-
|
|
1050
|
+
**Dos and don'ts**
|
|
1051
|
+
- Do not make the current breadcrumb clickable.
|
|
1052
|
+
- Do not pair with a back button.
|
|
1053
|
+
- Do not wrap breadcrumb labels to multiple lines; truncate and use `Tooltip` for full text.
|
|
1054
|
+
- Show only one breadcrumb trail per page.
|
|
386
1055
|
|
|
387
|
-
|
|
1056
|
+
**Behavior**
|
|
1057
|
+
- All links except the current page are interactive (Tab, Shift+Tab, Enter).
|
|
1058
|
+
- When space is limited, condense middle items into an overflow menu showing the first and last two links.
|
|
1059
|
+
- The active page link always remains visible.
|
|
388
1060
|
|
|
389
|
-
**
|
|
1061
|
+
**Often used with**
|
|
1062
|
+
- `Tooltip` for truncated labels, `Menu` for overflow segments, `Topbar`.
|
|
390
1063
|
|
|
391
|
-
|
|
1064
|
+
#### Button
|
|
392
1065
|
|
|
393
|
-
-
|
|
394
|
-
|
|
395
|
-
- **Must** expose **DropdownMenu**, **Dialog**, and other overlays via keyboard, not pointer-only triggers.
|
|
396
|
-
- **Avoid** critical behavior on `onMouseEnter` / `onMouseLeave` without a keyboard-accessible path.
|
|
1066
|
+
**Storybook-slug:** button
|
|
1067
|
+
**Docs-slug:** button
|
|
397
1068
|
|
|
398
|
-
|
|
1069
|
+
**Definition**
|
|
1070
|
+
Primary control for discrete actions.
|
|
399
1071
|
|
|
400
|
-
**
|
|
1072
|
+
**Use when**
|
|
1073
|
+
- Committing, navigating a clear next step, or triggering destructive work (with confirmation pattern).
|
|
401
1074
|
|
|
402
|
-
**
|
|
1075
|
+
**Dos and don'ts**
|
|
1076
|
+
- One primary action per logical section when possible.
|
|
1077
|
+
- Match variant to risk: destructive actions use destructive variant and confirmation.
|
|
1078
|
+
- Label with verb + object (see Content guidelines in `./DESIGN.md`).
|
|
1079
|
+
- Icon-only actions need an accessible name (`aria-label`).
|
|
403
1080
|
|
|
404
|
-
|
|
405
|
-
-
|
|
406
|
-
- **Must not** encode meaning with **color alone** — pair with icon, **HelperText**, or label.
|
|
407
|
-
- **Avoid** `muted-foreground` for text the user must read to complete a task.
|
|
1081
|
+
**Often used with**
|
|
1082
|
+
- `Button Group`, `Dialog`, forms.
|
|
408
1083
|
|
|
409
|
-
####
|
|
1084
|
+
#### Button Group
|
|
410
1085
|
|
|
411
|
-
**
|
|
1086
|
+
**Storybook-slug:** button-group
|
|
412
1087
|
|
|
413
|
-
**
|
|
1088
|
+
**Definition**
|
|
1089
|
+
Visually joins related buttons into a connected row, clarifying that the actions belong to the same context.
|
|
414
1090
|
|
|
415
|
-
|
|
416
|
-
-
|
|
417
|
-
-
|
|
418
|
-
- **Avoid** stripping default ARIA from primitives without an equivalent.
|
|
1091
|
+
**Use when**
|
|
1092
|
+
- Two or more actions are closely related and operate on the same target (for example, a split-button or segmented action row).
|
|
1093
|
+
- Conserving horizontal space compared to individually spaced buttons.
|
|
419
1094
|
|
|
420
|
-
|
|
1095
|
+
**Use something else when**
|
|
1096
|
+
- Actions are unrelated and should not appear grouped.
|
|
1097
|
+
- You need more than a small set of actions (consider `Toolbar` or `Dropdown Menu`).
|
|
421
1098
|
|
|
422
|
-
**
|
|
1099
|
+
**Often used with**
|
|
1100
|
+
- `Button`, `Tooltip` for icon-only variants.
|
|
423
1101
|
|
|
424
|
-
|
|
1102
|
+
#### Card
|
|
425
1103
|
|
|
426
|
-
|
|
427
|
-
-
|
|
428
|
-
- **Avoid** sub-24px icon hit zones without expansion in dense tables.
|
|
1104
|
+
**Storybook-slug:** card
|
|
1105
|
+
**Docs-slug:** card
|
|
429
1106
|
|
|
430
|
-
|
|
1107
|
+
**Definition**
|
|
1108
|
+
A structural container with optional header, body, and footer slots for displaying data artifacts, widgets, or media. The Card with Count variant adds a numeric indicator to the header.
|
|
431
1109
|
|
|
432
|
-
|
|
1110
|
+
**Use when**
|
|
1111
|
+
- Presenting charts, visualizations, or data widgets.
|
|
1112
|
+
- Building grids of comparable items where list/grid view toggling is needed.
|
|
1113
|
+
- Displaying media content (images, videos).
|
|
433
1114
|
|
|
434
|
-
**
|
|
1115
|
+
**Use something else when**
|
|
1116
|
+
- You just need visual separation between sections — use `Separator` and spacing instead.
|
|
1117
|
+
- You are comparing dense metadata across rows — use `Table` or a data grid instead.
|
|
435
1118
|
|
|
436
|
-
|
|
1119
|
+
**Dos and don'ts**
|
|
1120
|
+
- Cards are structural containers only; interactive elements (`Button`, `Checkbox`) go inside the body or actions area.
|
|
1121
|
+
- Exception: the entire card can serve as a single focusable target when it acts as a link or selection item.
|
|
437
1122
|
|
|
438
|
-
**
|
|
1123
|
+
**Often used with**
|
|
1124
|
+
- `Button`, `Badge`, `Avatar`, `Separator`, charts, lists, or form fields in the body.
|
|
439
1125
|
|
|
440
|
-
|
|
1126
|
+
#### Checkbox
|
|
441
1127
|
|
|
442
|
-
**
|
|
1128
|
+
**Storybook-slug:** checkbox
|
|
1129
|
+
**Docs-slug:** checkbox
|
|
443
1130
|
|
|
444
|
-
|
|
1131
|
+
**Definition**
|
|
1132
|
+
Enables users to independently select one or multiple options. Can appear standalone or within menus, tree views, tables, or cards.
|
|
445
1133
|
|
|
446
|
-
**
|
|
1134
|
+
**Use when**
|
|
1135
|
+
- Multiple independent selections are required (for example, column visibility in a table).
|
|
1136
|
+
- Enabling or disabling settings where changes do not take immediate effect.
|
|
1137
|
+
- Confirming agreement before an action (for example, delete verification).
|
|
447
1138
|
|
|
448
|
-
|
|
1139
|
+
**Use something else when**
|
|
1140
|
+
- Only one option can be selected at a time (use `Radio`).
|
|
1141
|
+
- Options are not displayed simultaneously (use `Select`).
|
|
1142
|
+
- You need an immediate on/off toggle (use `Switch`).
|
|
449
1143
|
|
|
450
|
-
**
|
|
1144
|
+
**Dos and don'ts**
|
|
1145
|
+
- Do provide a label for every checkbox.
|
|
1146
|
+
- Do implement indeterminate states for partial group selection.
|
|
1147
|
+
- Do not pre-select checkboxes automatically.
|
|
1148
|
+
- Do not use a single checkbox unless it is confirming agreement.
|
|
1149
|
+
- Do not use card variants for long option lists.
|
|
451
1150
|
|
|
452
|
-
|
|
1151
|
+
**Behavior**
|
|
1152
|
+
- Space key toggles focused checkboxes.
|
|
1153
|
+
- Indeterminate state is set programmatically, not by user interaction.
|
|
1154
|
+
- Parent-child relationships follow selection cascading rules.
|
|
453
1155
|
|
|
454
|
-
**
|
|
1156
|
+
**Often used with**
|
|
1157
|
+
- `Label`, helper text for groups, `Card` variant for options needing descriptions.
|
|
455
1158
|
|
|
456
|
-
|
|
1159
|
+
#### Collapsible
|
|
457
1160
|
|
|
458
|
-
**
|
|
1161
|
+
**Storybook-slug:** collapsible
|
|
1162
|
+
**Docs-slug:** collapsible
|
|
459
1163
|
|
|
460
|
-
|
|
1164
|
+
**Definition**
|
|
1165
|
+
A single inline expandable block that toggles content visibility. Designed for one independent optional section, not multiple stacked areas.
|
|
461
1166
|
|
|
462
|
-
|
|
1167
|
+
**Use when**
|
|
1168
|
+
- Showing one optional or secondary block of content (for example, AI reasoning, advanced settings, a preview).
|
|
1169
|
+
- Content is useful but not essential to the primary task.
|
|
463
1170
|
|
|
464
|
-
|
|
1171
|
+
**Use something else when**
|
|
1172
|
+
- You have multiple expandable sections (use `Accordion`).
|
|
1173
|
+
- Content is essential — show it by default.
|
|
1174
|
+
- Users are navigating or filtering (use `Tabs` or filter controls).
|
|
465
1175
|
|
|
466
|
-
|
|
1176
|
+
**Dos and don'ts**
|
|
1177
|
+
- Do default to collapsed unless the collapsible content is the main purpose of the view.
|
|
1178
|
+
- Do keep the trigger label descriptive — it should communicate what's inside.
|
|
1179
|
+
- Do not nest collapsibles; use `Accordion` for layered disclosure.
|
|
1180
|
+
- Do not hide errors or required information.
|
|
467
1181
|
|
|
468
|
-
|
|
469
|
-
-
|
|
470
|
-
-
|
|
471
|
-
- Keep **Aura components:** lines aligned with [`src/components/index.ts`](./src/components/index.ts) exports (public entry for `@cognite/aura/components`); treat **App / Fusion shell** lines as integration responsibilities, not as Aura package exports.
|
|
472
|
-
- Preserve links: [Aura Storybook](https://storybook-aura-23638.fusion-preview.preview.cogniteapp.com); [Aura documentation](https://docs.cognite.com/aura-design-system/get-started) for published guides. Fetch current prop names from Storybook or source before codegen.
|
|
473
|
-
- If you split by section (§1–§7), repeat the **Severity** and **Scope** bullets at the top of each file so standalone chunks stay interpretable.
|
|
474
|
-
- Preserve **[Content](#content)** for action verbs, date/time rules, and tone; agents generating strings should follow it alongside **Heuristics**.
|
|
1182
|
+
**Behavior**
|
|
1183
|
+
- One trigger controls one associated region with optional animation.
|
|
1184
|
+
- State changes must be exposed to assistive technology.
|
|
475
1185
|
|
|
476
|
-
|
|
1186
|
+
**Often used with**
|
|
1187
|
+
- `Separator` when stacking multiple collapsible regions on a page.
|
|
477
1188
|
|
|
478
|
-
|
|
1189
|
+
#### Combobox
|
|
479
1190
|
|
|
480
|
-
**
|
|
1191
|
+
**Storybook-slug:** combobox
|
|
1192
|
+
**Docs-slug:** combobox
|
|
481
1193
|
|
|
482
|
-
**
|
|
1194
|
+
**Definition**
|
|
1195
|
+
A searchable select input that filters options as users type. Supports single and multi-select modes with optional ability to add new items.
|
|
483
1196
|
|
|
484
|
-
**
|
|
1197
|
+
**Use when**
|
|
1198
|
+
- More than approximately 12 options where search efficiency beats scrolling.
|
|
1199
|
+
- Users have a general sense of what they're looking for (country, asset name, tag).
|
|
1200
|
+
- Users need to add new options not in the predefined list.
|
|
485
1201
|
|
|
486
|
-
|
|
1202
|
+
**Use something else when**
|
|
1203
|
+
- Fewer than ~12 options: prefer `Select`, `Radio`, or `Checkbox`.
|
|
1204
|
+
- Users are unfamiliar with available options and need a visible list.
|
|
1205
|
+
- Very large datasets risk performance lag: use a data grid with filtering.
|
|
1206
|
+
- Pure text entry without selection (use `Input` or `Textarea`).
|
|
487
1207
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
| `foreground` | `text-foreground` | Primary text |
|
|
494
|
-
| `muted-foreground` | `text-muted-foreground` | Tertiary copy |
|
|
495
|
-
| `card-background` | `bg-card-background` | Cards (see **Card** component) |
|
|
496
|
-
| `muted-background` | `bg-muted-background` | Static fills, inputs, secondary chrome |
|
|
497
|
-
| `border` | `border-border` | Default strokes |
|
|
498
|
-
| `link-foreground` | `text-link-foreground` | Text links |
|
|
499
|
-
| `primary-background` | `bg-primary-background`, `text-foreground-on-primary` | Default **Button** (`variant="default"`) pattern |
|
|
500
|
-
| `destructive-background` | `bg-destructive-background`, `text-destructive-foreground-on-critical` (on surface) | Destructive actions — pairings in **Semantic colors** |
|
|
501
|
-
| `info-background`, `success-background`, … | `bg-info-background`, `text-info-foreground`, … | Full names match **Semantic colors** token columns |
|
|
502
|
-
|
|
503
|
-
Semantic utilities use the **full token name** as the Tailwind segment (e.g. `bg-info-background`, not `bg-info`). For **charts**, utilities follow the **Chart tokens** names (`bg-chart-fjord-color-1`, `bg-chart-gridlines`, …). For exhaustive coverage, use [`src/colors.css`](./src/colors.css) or your IDE on `@cognite/aura`.
|
|
504
|
-
|
|
505
|
-
Tables below list **approximate hex** resolved from [`src/colors.css`](./src/colors.css) at build time; the source of truth is the synced file (some entries are `rgba()`).
|
|
506
|
-
|
|
507
|
-
### Color
|
|
508
|
-
|
|
509
|
-
Aura groups color into **Base** (~80–90% of UI), **Semantic** (status and feedback, ~5–10%), and **Decorative** (accents and illustration, ~5–10%) so color carries **meaning** and stays calm.
|
|
510
|
-
|
|
511
|
-
#### Base — Background
|
|
512
|
-
|
|
513
|
-
| Token | Light (reference) | Dark (reference) | Use |
|
|
514
|
-
| :--- | :--- | :--- | :--- |
|
|
515
|
-
| `background` | `#FFFFFF` | `#191B1D` | Primary surface — lowest layer |
|
|
516
|
-
| `alternate-background` | `#F9FAFA` | `#111213` | Distinct layer or block separate from `background` |
|
|
517
|
-
| `card-background` | `#F9FAFA` | `#212426` | Cards without drop shadow on `background` / `alternate-background` |
|
|
518
|
-
| `muted-background` | `#F1F2F3` | `#2D3134` | Static fills for controls, rows, segmented controls |
|
|
519
|
-
| `primary-background` | `#212426` | `#F9FAFA` | Primary actions (default button); use sparingly |
|
|
520
|
-
| `primary-background-hover` | `#40464A` | `#E4E6E8` | Hover on `primary-background` |
|
|
521
|
-
| `secondary-background` | `#E4E6E8` | `#40464A` | Secondary actions, switch track |
|
|
522
|
-
| `secondary-background-hover` | `#D4D7D9` | `#5E666D` | Hover on `secondary-background` |
|
|
523
|
-
| `accent-background` | `#F1F2F3` | `#2D3134` | Neutral hover on `background` / `card-background` (e.g. tabs) |
|
|
524
|
-
| `accent-background-strong` | `#E4E6E8` | `#40464A` | Neutral hover on `muted-background` / `active-muted-background` |
|
|
525
|
-
| `highlight-background` | `#F1F2F3` | `#2D3134` | Focused / active fields (inputs, selects, comboboxes) |
|
|
526
|
-
| `highlight-background-strong` | `#E4E6E8` | `#40464A` | Stronger focused / active field fill |
|
|
527
|
-
| `active-background` | `#191B1D` | `#F9FAFA` | High-contrast “on” (switch, checkbox, radio) |
|
|
528
|
-
| `active-background-hover` | `#2D3134` | `#F1F2F3` | Hover on `active-background` |
|
|
529
|
-
| `active-muted-background` | `#F1F2F3` | `#2D3134` | Lower-contrast selected (e.g. tabs) |
|
|
530
|
-
| `active-muted-background-hover` | `#E4E6E8` | `#40464A` | Hover on `active-muted-background` |
|
|
531
|
-
| `popover-background` | `#FFFFFF` | `#212426` | Top-layer surfaces with shadow (dialogs, popovers) |
|
|
532
|
-
| `raised-background` | `#2D3134` | `#40464A` | Tooltips, Sonner toasts — floats above page |
|
|
533
|
-
| `disabled-background` | `#F1F2F3` | `#2D3134` | Disabled inputs and controls |
|
|
534
|
-
| `overlay-background` | `#7C868E80` | `#7C868E80` | Scrim behind modals |
|
|
535
|
-
| `background-fixed-dark` | `#212426` | `#212426` | Must stay **dark** in both themes |
|
|
536
|
-
| `background-fixed-light` | `#FFFFFF` | `#FFFFFF` | Must stay **light** in both themes |
|
|
537
|
-
| `accent-background-fixed-dark` | `#2D3134` | `#2D3134` | Persistent dark accent chrome (e.g. sidebar) |
|
|
538
|
-
|
|
539
|
-
#### Base — Foreground
|
|
540
|
-
|
|
541
|
-
| Token | Light (reference) | Dark (reference) | Use |
|
|
542
|
-
| :--- | :--- | :--- | :--- |
|
|
543
|
-
| `foreground` | `#191B1D` | `#F1F2F3` | Primary text and icons |
|
|
544
|
-
| `secondary-foreground` | `#40464A` | `#D4D7D9` | Supporting text and icons |
|
|
545
|
-
| `muted-foreground` | `#6D767E` | `#A5ABB1` | Tertiary / low emphasis |
|
|
546
|
-
| `disabled-foreground` | `#D4D7D9` | `#5E666D` | Disabled text and icons |
|
|
547
|
-
| `link-foreground` | `#486AED` | `#1742E7` | Text links |
|
|
548
|
-
| `foreground-on-primary` | `#F1F2F3` | `#191B1D` | On `primary-background` |
|
|
549
|
-
| `foreground-on-active` | `#F1F2F3` | `#191B1D` | On `active-background` |
|
|
550
|
-
| `active-foreground` | `#191B1D` | `#F1F2F3` | On `active-muted-background` |
|
|
551
|
-
| `foreground-fixed-dark` | `#191B1D` | `#191B1D` | Must stay dark in both themes |
|
|
552
|
-
| `foreground-fixed-light` | `#FFFFFF` | `#FFFFFF` | Must stay light in both themes |
|
|
553
|
-
| `foreground-secondary-fixed-dark` | `#40464A` | `#40464A` | Secondary copy, always dark |
|
|
554
|
-
| `secondary-foreground-fixed-light` | `#D4D7D9` | `#D4D7D9` | Secondary copy, always light |
|
|
555
|
-
| `muted-foreground-fixed-light` | `#BBC0C4` | `#BBC0C4` | Muted copy, always light |
|
|
556
|
-
|
|
557
|
-
#### Base — Borders and focus
|
|
558
|
-
|
|
559
|
-
| Token | Light (reference) | Dark (reference) | Use |
|
|
560
|
-
| :--- | :--- | :--- | :--- |
|
|
561
|
-
| `border` | `#E4E6E8` | `#2D3134` | Default strokes |
|
|
562
|
-
| `border-emphasized` | `#D4D7D9` | `#40464A` | Stronger separation |
|
|
563
|
-
| `border-on-dark` | `#2D3134` | `#2D3134` | Strokes on dark chrome (both themes) |
|
|
564
|
-
| `border-active` | `#191B1D` | `#F9FAFA` | Active / toggled outlines |
|
|
565
|
-
| `ring` | `#7081C7` | `#7081C7` | Focus ring outer (maps to `--shadow-focus-ring`) |
|
|
566
|
-
| `ring-muted` | `#B5BEE2` | `#B5BEE2` | Focus ring inner companion |
|
|
1208
|
+
**Dos and don'ts**
|
|
1209
|
+
- Do group related options into categories.
|
|
1210
|
+
- Do position checkmarks right-aligned in menus.
|
|
1211
|
+
- Do not use for simple binary choices or small option sets.
|
|
1212
|
+
- Do not place icons or badges on the left side of menu items.
|
|
567
1213
|
|
|
568
|
-
|
|
1214
|
+
**Behavior**
|
|
1215
|
+
- Single-select closes immediately on selection.
|
|
1216
|
+
- Multi-select stays open until the user clicks outside, presses Escape, or Enter.
|
|
569
1217
|
|
|
570
|
-
|
|
1218
|
+
**Often used with**
|
|
1219
|
+
- `Label`, helper text, `Badge`.
|
|
571
1220
|
|
|
572
|
-
|
|
1221
|
+
#### Command
|
|
573
1222
|
|
|
574
|
-
|
|
1223
|
+
**Storybook-slug:** command
|
|
1224
|
+
**Docs-slug:** command
|
|
575
1225
|
|
|
576
|
-
**
|
|
1226
|
+
**Definition**
|
|
1227
|
+
A keyboard-first search interface for discovering and executing actions, navigating pages, or looking up content application-wide. Typically activated via ⌘K / Ctrl+K and displayed inside a `Dialog` or `Popover`.
|
|
577
1228
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
| `info-foreground` | `#4A5FB8` | `#9DA9D9` | Text near info context on standard surfaces |
|
|
583
|
-
| `info-foreground-on-info` | `#32417F` | `#1A2242` | Text **on** `info-background` |
|
|
584
|
-
| `info-muted-background` | `#F0F2F9` | `#2D3134` | Info tint on dark chrome |
|
|
585
|
-
| *(pairing)* | — | — | On `info-muted-background`, use `info-foreground-on-info` for on-surface copy |
|
|
1229
|
+
**Use when**
|
|
1230
|
+
- Enabling keyboard-driven workflows across an entire application.
|
|
1231
|
+
- Providing power-user shortcuts to actions and destinations.
|
|
1232
|
+
- The application has too many actions or pages to surface in a standard nav.
|
|
586
1233
|
|
|
587
|
-
**
|
|
1234
|
+
**Use something else when**
|
|
1235
|
+
- Filtering a specific list or dataset (use `Search`).
|
|
1236
|
+
- Selecting from known form options (use `Combobox` or `Select`).
|
|
1237
|
+
- Navigating between a small number of pages (use `Tabs` or nav links).
|
|
588
1238
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
| *(pairing)* | — | — | On `success-muted-background`, use `success-foreground-on-success` |
|
|
1239
|
+
**Dos and don'ts**
|
|
1240
|
+
- Do organize results into logical categories.
|
|
1241
|
+
- Do use action-oriented labels ("Create asset," "Switch to dark mode").
|
|
1242
|
+
- Do display the keyboard shortcut on triggering elements.
|
|
1243
|
+
- Do surface frequently used items by default.
|
|
1244
|
+
- Do not use for general content search.
|
|
1245
|
+
- Do require confirmation steps for destructive actions.
|
|
597
1246
|
|
|
598
|
-
**
|
|
1247
|
+
**Behavior**
|
|
1248
|
+
- Keyboard-first interface presenting categorized, scannable action lists.
|
|
1249
|
+
- Shows loading indicators for async results and meaningful empty states.
|
|
599
1250
|
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
| `warning-background` | `#FFE3A2` | `#FFE3A2` | Warning surface |
|
|
603
|
-
| `warning-background-hover` | `#FFD062` | `#FFF1D0` | Hover on `warning-background` |
|
|
604
|
-
| `warning-foreground` | `#C18800` | `#D8BF00` | Text near warning on standard surfaces |
|
|
605
|
-
| `warning-foreground-on-warning` | `#755200` | `#5B4000` | Text **on** `warning-background` |
|
|
606
|
-
| `warning-muted-background` | `#FFF1D0` | `#2D3134` | Warning on dark chrome |
|
|
1251
|
+
**Often used with**
|
|
1252
|
+
- `Dialog`, `Popover`, `Search`, `Empty State`.
|
|
607
1253
|
|
|
608
|
-
|
|
1254
|
+
#### Count
|
|
609
1255
|
|
|
610
|
-
|
|
611
|
-
| :--- | :--- | :--- | :--- |
|
|
612
|
-
| `destructive-background` | `#FCCAD2` | `#FAA9B7` | Error / destructive surface |
|
|
613
|
-
| `destructive-background-hover` | `#FAA9B7` | `#FCCAD2` | Hover on `destructive-background` |
|
|
614
|
-
| `destructive-foreground` | `#CB0B2C` | `#F65E78` | Text near destructive context on standard surfaces |
|
|
615
|
-
| `destructive-foreground-on-critical` | `#8D081F` | `#8D081F` | Text **on** `destructive-background` |
|
|
616
|
-
| `destructive-muted-background` | `#FDDEE4` | `#2D3134` | Destructive on dark chrome |
|
|
617
|
-
| `destructive-muted-background-hover` | `#FCCAD2` | `#40464A` | Hover on `destructive-muted-background` |
|
|
1256
|
+
**Storybook-slug:** count
|
|
618
1257
|
|
|
619
|
-
**
|
|
1258
|
+
**Definition**
|
|
1259
|
+
A compact numeric indicator used to surface quantities inline — for example, unread messages, selected items, or totals attached to labels or tabs.
|
|
620
1260
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
| `neutral-background-hover` | `#D4D7D9` | `#E4E6E8` | Hover on `neutral-background` |
|
|
625
|
-
| `neutral-foreground` | `#52595F` | `#A5ABB1` | Text near neutral status |
|
|
626
|
-
| `neutral-foreground-on-neutral` | `#40464A` | `#2D3134` | Text **on** `neutral-background` |
|
|
627
|
-
| `neutral-muted-background` | `#F1F2F3` | `#2D3134` | Neutral on dark chrome |
|
|
1261
|
+
**Use when**
|
|
1262
|
+
- Showing a quantity associated with a label, tab, or list item.
|
|
1263
|
+
- Surfacing unread counts or selection totals without taking primary focus.
|
|
628
1264
|
|
|
629
|
-
**
|
|
1265
|
+
**Use something else when**
|
|
1266
|
+
- The value represents status or category rather than a quantity (use `Badge`).
|
|
630
1267
|
|
|
631
|
-
|
|
1268
|
+
**Often used with**
|
|
1269
|
+
- `Tabs`, `Badge`, `Label`, list items.
|
|
632
1270
|
|
|
633
|
-
|
|
1271
|
+
#### Date Picker
|
|
634
1272
|
|
|
635
|
-
**
|
|
1273
|
+
**Storybook-slug:** datepicker
|
|
1274
|
+
**Docs-slug:** date-and-time-picker
|
|
636
1275
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
| 1 | Fjord | `decorative-background-fjord` | `decorative-foreground-fjord` |
|
|
640
|
-
| 2 | Nordic | `decorative-background-nordic` | `decorative-foreground-nordic` |
|
|
641
|
-
| 3 | Aurora | `decorative-background-aurora` | `decorative-foreground-aurora` |
|
|
642
|
-
| 4 | Dusk | `decorative-background-dusk` | `decorative-foreground-dusk` |
|
|
643
|
-
| 5 | Orange | `decorative-background-orange` | `decorative-foreground-orange` |
|
|
644
|
-
| 6 | Sky | `decorative-background-sky` | `decorative-foreground-sky` |
|
|
645
|
-
| 7 | Mountain | `decorative-background-mountain` | `decorative-foreground-mountain` |
|
|
1276
|
+
**Definition**
|
|
1277
|
+
Allows users to select a single date through a calendar interface, ensuring proper formatting and avoiding input errors.
|
|
646
1278
|
|
|
647
|
-
|
|
1279
|
+
**Use when**
|
|
1280
|
+
- Users need to select an exact date.
|
|
1281
|
+
- Preventing manual date-formatting errors is important.
|
|
648
1282
|
|
|
649
|
-
|
|
1283
|
+
**Use something else when**
|
|
1284
|
+
- Relative dates are more appropriate ("Last week") — add shortcut options instead.
|
|
1285
|
+
- The date is fixed or recurring (consider a cron expression or plain `Input`).
|
|
1286
|
+
- Exact timing is not critical (use basic `Input`).
|
|
650
1287
|
|
|
651
|
-
**
|
|
1288
|
+
**Behavior**
|
|
1289
|
+
- Opens a calendar anchored to the input field.
|
|
1290
|
+
- Keyboard users can type valid values directly without using the picker.
|
|
1291
|
+
- Values commit in the configured locale format.
|
|
652
1292
|
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
| `chart-{ramp}-color-1` … `chart-{ramp}-color-6` | Alpha-based series / area-fill steps (strongest → lightest) |
|
|
656
|
-
| `chart-gridlines` | Grid lines |
|
|
1293
|
+
**Often used with**
|
|
1294
|
+
- `Label`, helper text, `Date Range Picker`.
|
|
657
1295
|
|
|
658
|
-
|
|
1296
|
+
#### Date Range Picker
|
|
659
1297
|
|
|
660
|
-
|
|
1298
|
+
**Storybook-slug:** daterangepicker
|
|
1299
|
+
**Docs-slug:** date-and-time-picker
|
|
661
1300
|
|
|
662
|
-
|
|
1301
|
+
**Definition**
|
|
1302
|
+
Allows users to select a start and end date from a calendar interface. Used for filtering by date ranges, comparing periods, or scheduling.
|
|
663
1303
|
|
|
664
|
-
|
|
1304
|
+
**Use when**
|
|
1305
|
+
- Users need to specify a date range for filtering or reporting.
|
|
1306
|
+
- Comparing data across a period.
|
|
665
1307
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
| `--font-marketing` | Space Grotesk | Marketing / display headings only |
|
|
670
|
-
| `--font-mono` | Source Code Pro | Code, technical strings |
|
|
1308
|
+
**Use something else when**
|
|
1309
|
+
- Only a single date is needed (use `Date Picker`).
|
|
1310
|
+
- Relative ranges like "Last 7 days" cover most use cases — add shortcut options.
|
|
671
1311
|
|
|
672
|
-
**
|
|
1312
|
+
**Behavior**
|
|
1313
|
+
- Enforces start/end ordering with validation messages.
|
|
1314
|
+
- Keyboard users can type valid values directly.
|
|
673
1315
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
| `display` | Space Grotesk | 36px (`text-5xl`) | 600 | 44px | -0.08px | Hero / marketing display |
|
|
677
|
-
| `h1` | Inter | 32px (`text-4xl`) | 600 | 40px | -0.08px | Page title |
|
|
678
|
-
| `h2` | Inter | 28px (`text-3xl`) | 600 | 32px | -0.08px | Section title |
|
|
679
|
-
| `h3` | Inter | 24px (`text-2xl`) | 600 | 28px | -0.04px | Subsection |
|
|
680
|
-
| `h4` | Inter | 20px (`text-xl`) | 500 | 24px | -0.04px | Group label |
|
|
681
|
-
| `body-md` | Inter | 16px (`text-base`) | 400 | 20px | -0.04px | Default body |
|
|
682
|
-
| `body-sm` | Inter | 14px (`text-sm`) | 400 | 18px | -0.04px | Secondary body |
|
|
683
|
-
| `label` | Inter | 12px (`text-xs`) | 500 | 14px | -0.04px | Form labels, compact UI |
|
|
684
|
-
| `code` | Source Code Pro | 14px (`text-sm`) | 400 | 20px | — | Monospace content |
|
|
1316
|
+
**Often used with**
|
|
1317
|
+
- `Label`, helper text, `Date Picker`.
|
|
685
1318
|
|
|
686
|
-
|
|
1319
|
+
#### Date Time Range Picker
|
|
687
1320
|
|
|
688
|
-
|
|
1321
|
+
**Storybook-slug:** datetimerangepicker
|
|
1322
|
+
**Docs-slug:** date-and-time-picker
|
|
689
1323
|
|
|
690
|
-
|
|
1324
|
+
**Definition**
|
|
1325
|
+
Allows users to select start and end date and time values. Used when precise time boundaries matter, for example scheduling or time-series filtering.
|
|
691
1326
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
| xs | 4px | `1` | Tight gaps, icon padding |
|
|
695
|
-
| sm | 8px | `2` | Inline controls, compact padding |
|
|
696
|
-
| md | 12px | `3` | Card / popover internal padding |
|
|
697
|
-
| lg | 16px | `4` | Related groups |
|
|
698
|
-
| xl | 20px | `5` | Sections |
|
|
699
|
-
| 2xl | 24px | `6` | Page regions |
|
|
700
|
-
| 3xl | 32px | `8` | Large layout gaps |
|
|
1327
|
+
**Use when**
|
|
1328
|
+
- Users must specify both a date and time for a range (scheduling, time-series queries).
|
|
701
1329
|
|
|
702
|
-
|
|
1330
|
+
**Use something else when**
|
|
1331
|
+
- Time precision is not required (use `Date Range Picker`).
|
|
1332
|
+
- Only a single point in time is needed (use `Date Picker` or `Time Picker`).
|
|
703
1333
|
|
|
704
|
-
|
|
1334
|
+
**Behavior**
|
|
1335
|
+
- Enforces start/end ordering; validates that end is after start.
|
|
1336
|
+
- Keyboard users can type valid values directly.
|
|
705
1337
|
|
|
706
|
-
|
|
1338
|
+
**Often used with**
|
|
1339
|
+
- `Label`, helper text, `Date Range Picker`.
|
|
707
1340
|
|
|
708
|
-
|
|
709
|
-
| :--- | :--- | :--- |
|
|
710
|
-
| xs | 20px (`h-5`) | Badge (default) |
|
|
711
|
-
| sm | 28px (`h-7`) | Button `sm`, compact rows |
|
|
712
|
-
| md | 36px (`h-9`) | Button default, Input, Select, many menu rows |
|
|
713
|
-
| lg | 40px (`h-10`) | Button `lg` |
|
|
714
|
-
| Icon button | 28 / 36 / 40px | `icon-sm` / default / `icon-lg` (`size-7`, `size-9`, `size-10`) |
|
|
1341
|
+
#### Dialog
|
|
715
1342
|
|
|
716
|
-
**
|
|
1343
|
+
**Storybook-slug:** dialog
|
|
1344
|
+
**Docs-slug:** dialog
|
|
717
1345
|
|
|
718
|
-
|
|
1346
|
+
**Definition**
|
|
1347
|
+
Richer content surface: forms, multi-field flows, or explanations that do not fit a strip or inline pattern.
|
|
719
1348
|
|
|
720
|
-
|
|
1349
|
+
**Use when**
|
|
1350
|
+
- Collecting input or showing structured content that needs focus without leaving the page.
|
|
721
1351
|
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
| `--radius-none` | 0px | Dividers, full-bleed |
|
|
727
|
-
| `--radius-xs` | 2px | Tight inner chrome |
|
|
728
|
-
| `--radius-sm` | 4px | Small controls, badges |
|
|
729
|
-
| `--radius-md` / `--radius` | 6px | Maps to `rounded-md` — shared default in theme |
|
|
730
|
-
| `--radius-lg` | 8px | **Default** for many controls (Button, Input) via `rounded-lg` |
|
|
731
|
-
| `--radius-xl` | 12px | Dialogs, large cards, popovers |
|
|
732
|
-
| `--radius-2xl` | 16px | Extra-large surfaces |
|
|
733
|
-
| `--radius-3xl` | 24px | Marketing / hero panels |
|
|
734
|
-
| `--radius-4xl` | 32px | Largest marketing rounding |
|
|
735
|
-
| `--radius-full` | 9999px | Pills, avatars |
|
|
1352
|
+
**Use something else when**
|
|
1353
|
+
- Inline persistence is enough (`Alert`).
|
|
1354
|
+
- Only a quick acknowledgement is needed (`Sonner Toast`).
|
|
1355
|
+
- The action is binary and destructive (use `Alert Dialog`).
|
|
736
1356
|
|
|
737
|
-
|
|
1357
|
+
**Often used with**
|
|
1358
|
+
- `Button`, `Form`, `Alert Dialog` for confirmation steps.
|
|
738
1359
|
|
|
739
|
-
|
|
1360
|
+
#### Drawer
|
|
740
1361
|
|
|
741
|
-
|
|
1362
|
+
**Storybook-slug:** drawer
|
|
742
1363
|
|
|
743
|
-
**
|
|
1364
|
+
**Definition**
|
|
1365
|
+
Secondary surface that slides in for filters, detail, or medium-length tasks without a full page change.
|
|
744
1366
|
|
|
745
|
-
|
|
746
|
-
-
|
|
747
|
-
- **Should** prefer one outer container boundary over many nested per-row outlines in the same card.
|
|
748
|
-
- **Avoid** drawing borders around every item in a list/card just to create visual rhythm.
|
|
749
|
-
- **Avoid** decorative outline stacks (`border` + `ring` + inset strokes) when no state or interaction meaning is conveyed.
|
|
1367
|
+
**Use when**
|
|
1368
|
+
- Supporting the main view (filters, record details, auxiliary forms).
|
|
750
1369
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
| Emphasized width | **2px** | Stronger separation or invalid/critical state emphasis |
|
|
755
|
-
| Border color | `border`, `border-emphasized`, … | See **Base — Borders and focus** |
|
|
756
|
-
| Style | solid | Default |
|
|
1370
|
+
**Use something else when**
|
|
1371
|
+
- The task needs full attention or multi-step wizard treatment (full page or `Dialog`).
|
|
1372
|
+
- Content is very short (consider `Popover` or inline).
|
|
757
1373
|
|
|
758
|
-
|
|
1374
|
+
#### Dropdown Menu
|
|
759
1375
|
|
|
760
|
-
|
|
1376
|
+
**Storybook-slug:** dropdown-menu
|
|
761
1377
|
|
|
762
|
-
|
|
1378
|
+
**Definition**
|
|
1379
|
+
A button-triggered overlay listing a set of related actions or options. One of the two menu variants (the other being a context menu, which is right-click triggered). See also: `Menu`.
|
|
763
1380
|
|
|
764
|
-
|
|
1381
|
+
**Use when**
|
|
1382
|
+
- A button needs to reveal secondary or overflow actions without persistent UI.
|
|
1383
|
+
- Grouping related actions behind a single trigger to reduce visual clutter.
|
|
765
1384
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
| `shadow-md` | lg + md layers | 0.06 + 0.05 | 0.4 + 0.302 | Sonner toasts, temporary elevated elements |
|
|
771
|
-
| `shadow-lg` | xl + lg layers | 0.10 + 0.06 | 0.6 + 0.4 | Modals / dialogs **without** full backdrop overlay |
|
|
772
|
-
| `shadow-xl` | xl + lg layers | 0.10 + 0.06 | 0.6 + 0.4 | Modals / dialogs **with** backdrop overlay |
|
|
1385
|
+
**Use something else when**
|
|
1386
|
+
- Options require complex selection or rich descriptions (use `Select Panel`).
|
|
1387
|
+
- Actions need user confirmation (use `Dialog` or `Alert Dialog`).
|
|
1388
|
+
- The action set is always visible and primary (use `Toolbar`).
|
|
773
1389
|
|
|
774
|
-
|
|
1390
|
+
**Behavior**
|
|
1391
|
+
- Closes after selection by default.
|
|
1392
|
+
- Positions above, below, or beside the trigger depending on viewport space.
|
|
1393
|
+
- Submenus open on hover.
|
|
775
1394
|
|
|
776
|
-
|
|
1395
|
+
**Often used with**
|
|
1396
|
+
- `Button`, `Separator`, `Badge`, checkbox toggles.
|
|
777
1397
|
|
|
778
|
-
|
|
1398
|
+
#### Empty State
|
|
779
1399
|
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
| `--shadow-focus-ring` | `0 0 0 1px var(--ring), 0 0 0 3px var(--ring-muted)` | Default focus on interactive controls |
|
|
783
|
-
| `--shadow-focus-ring-destructive` | `0 0 0 1px var(--ring-destructive), 0 0 0 3px var(--ring-destructive-muted)` | Destructive / invalid focus |
|
|
1400
|
+
**Storybook-slug:** empty
|
|
1401
|
+
**Docs-slug:** empty-state
|
|
784
1402
|
|
|
785
|
-
|
|
1403
|
+
**Definition**
|
|
1404
|
+
Placeholder when there is no data yet or results are empty.
|
|
786
1405
|
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
| `--opacity-10` … `--opacity-80` (+ `*-inverted`) | rgba steps | Overlays, glass effects |
|
|
790
|
-
| Overlay scrim | via `overlay-background` | Modal backdrop (see color tables) |
|
|
791
|
-
| Chart fills | `chart-*-color-*` | See **Chart tokens** |
|
|
1406
|
+
**Use when**
|
|
1407
|
+
- Lists, tables, charts, or artifacts have zero rows/points.
|
|
792
1408
|
|
|
793
|
-
|
|
1409
|
+
**Dos and don'ts**
|
|
1410
|
+
- Explain what will appear and how to get started.
|
|
1411
|
+
- Include a single clear CTA when creation/import applies.
|
|
794
1412
|
|
|
795
|
-
|
|
1413
|
+
#### Form
|
|
796
1414
|
|
|
797
|
-
|
|
1415
|
+
**Storybook-slug:** form
|
|
798
1416
|
|
|
799
|
-
|
|
1417
|
+
**Definition**
|
|
1418
|
+
A structural wrapper for form fields that manages layout, spacing, validation state propagation, and submission handling.
|
|
800
1419
|
|
|
801
|
-
|
|
1420
|
+
**Use when**
|
|
1421
|
+
- Collecting structured user input across one or more fields.
|
|
1422
|
+
- Grouping related fields with shared validation and submission logic.
|
|
802
1423
|
|
|
803
|
-
**
|
|
1424
|
+
**Dos and don'ts**
|
|
1425
|
+
- Do group semantically related fields together.
|
|
1426
|
+
- Do associate every field with a `Label`.
|
|
1427
|
+
- Do not use `Form` as a generic container when no submission or validation is needed.
|
|
804
1428
|
|
|
805
|
-
|
|
806
|
-
-
|
|
807
|
-
- **Should** implement the cap with `max-w-[600px]` / `max-w-[37.5rem]` (or an equivalent layout wrapper) on the text block, not by stretching typography alone inside an arbitrarily wide container.
|
|
1429
|
+
**Often used with**
|
|
1430
|
+
- `Input`, `Select`, `Combobox`, `Checkbox`, `Radio`, `Label`, `Button` (submit), `Dialog`.
|
|
808
1431
|
|
|
809
|
-
|
|
1432
|
+
#### Input
|
|
810
1433
|
|
|
811
|
-
|
|
1434
|
+
**Storybook-slug:** input
|
|
1435
|
+
**Docs-slug:** input
|
|
812
1436
|
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
| `--container-2xl` | 40rem (**640px**) | Narrower than Tailwind’s default `2xl` container — useful outer bound for regions; **body copy** inside can still follow the **600px** reading rule above |
|
|
816
|
-
| `--container-8xl` | 96rem (**1536px**) | Wide upper bound for dashboards and full-bleed marketing rows |
|
|
1437
|
+
**Definition**
|
|
1438
|
+
Single-line text field for capturing short text-based information in forms and toolbars.
|
|
817
1439
|
|
|
818
|
-
|
|
1440
|
+
**Use when**
|
|
1441
|
+
- Collecting specific text data (names, credentials, asset identifiers).
|
|
1442
|
+
- A form field requires free text that doesn't fit a structured picker.
|
|
819
1443
|
|
|
1444
|
+
**Use something else when**
|
|
1445
|
+
- Selecting from predefined options (use `Select`, `Combobox`, `Checkbox`, or `Radio`).
|
|
1446
|
+
- Suggestions as the user types are needed (use `Combobox`).
|
|
1447
|
+
- Selecting dates or times (use `Date Picker` / `Time Picker`).
|
|
1448
|
+
- Multi-line text is expected (use `Textarea`).
|
|
820
1449
|
|
|
821
|
-
|
|
1450
|
+
**Dos and don'ts**
|
|
1451
|
+
- Do not use long placeholder text that duplicates the label.
|
|
1452
|
+
- Do not mimic pre-filled content with placeholder text.
|
|
1453
|
+
- Do not wrap text in an input; truncate or switch to `Textarea`.
|
|
822
1454
|
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
| `--alert-icon-width` | `calc(var(--spacing) * 4)` (typically **16px**) | Fixed icon column in the **Alert** layout so titles and descriptions align |
|
|
1455
|
+
**Behavior**
|
|
1456
|
+
- Single-line only; updates as the user types.
|
|
1457
|
+
- Validation messages associate with the field for accessibility.
|
|
1458
|
+
- Supports leading (icon, prefix) and trailing (button, suffix, stepper) slots.
|
|
828
1459
|
|
|
829
|
-
|
|
1460
|
+
**Often used with**
|
|
1461
|
+
- `Label`, helper text, `Button`, `Tooltip`.
|
|
830
1462
|
|
|
831
|
-
|
|
832
|
-
- **Should** keep major block **padding** and **gap** on **4px** multiples so control heights, radii, and typography line up visually.
|
|
833
|
-
- **Should** group related regions in **Card** (and **Separator** when two unrelated groups share a container) before mixing unrelated actions into the same band — see **Heuristics §6**.
|
|
834
|
-
- **Avoid** one-off pixel gutters that ignore the scale unless matching a fixed graphic asset.
|
|
1463
|
+
#### Label
|
|
835
1464
|
|
|
836
|
-
|
|
1465
|
+
**Storybook-slug:** label
|
|
1466
|
+
**Docs-slug:** label
|
|
837
1467
|
|
|
838
|
-
|
|
839
|
-
|
|
1468
|
+
**Definition**
|
|
1469
|
+
A form label that identifies and is programmatically associated with an input field. Not intended as general-purpose text.
|
|
840
1470
|
|
|
841
|
-
|
|
1471
|
+
**Use when**
|
|
1472
|
+
- Every `Input`, `Select`, `Combobox`, `Textarea`, `Checkbox` group, `Radio` group, `Switch`, `Slider`, or `Date Picker` needs one.
|
|
1473
|
+
|
|
1474
|
+
**Use something else when**
|
|
1475
|
+
- You need a heading or section title (use appropriate heading levels).
|
|
1476
|
+
- You need descriptive text below a field (use helper text).
|
|
1477
|
+
- You are labeling a non-interactive element like a status indicator (use plain text or `Badge`).
|
|
1478
|
+
|
|
1479
|
+
**Dos and don'ts**
|
|
1480
|
+
- Do associate labels with fields via `htmlFor`/`id` for accessibility.
|
|
1481
|
+
- Do mark required fields consistently (asterisk or explicit text).
|
|
1482
|
+
- Do not replace labels with placeholder text — placeholders disappear and are inaccessible.
|
|
1483
|
+
- Do not hide labels for visual cleanliness; use `Tooltip` to supplement shortened labels.
|
|
1484
|
+
|
|
1485
|
+
**Often used with**
|
|
1486
|
+
- `Input`, `Select`, `Combobox`, `Checkbox`, `Radio`, `Switch`, `Slider`, `Textarea`, `Date Picker`.
|
|
1487
|
+
|
|
1488
|
+
#### Menu
|
|
1489
|
+
|
|
1490
|
+
**Storybook-slug:** menu
|
|
1491
|
+
**Docs-slug:** menu
|
|
1492
|
+
|
|
1493
|
+
**Definition**
|
|
1494
|
+
Presents a list of actions, options, or states for the current selection or context. Two variants: context menu (right-click/long-press trigger) and dropdown menu (button trigger). See also: `Dropdown Menu`.
|
|
1495
|
+
|
|
1496
|
+
**Use when**
|
|
1497
|
+
- Offering action choices from a button, select, or combobox when space is constrained.
|
|
1498
|
+
- Exposing contextual actions via right-click without dedicated trigger UI.
|
|
1499
|
+
|
|
1500
|
+
**Use something else when**
|
|
1501
|
+
- Options require reordering or rich descriptions (use `Select Panel`).
|
|
1502
|
+
- Actions need user confirmation before executing (use `Dialog`, `Alert Dialog`, or `Popover`).
|
|
1503
|
+
|
|
1504
|
+
**Dos and don'ts**
|
|
1505
|
+
- Do keep items left-aligned and styled consistently within sections.
|
|
1506
|
+
- Do separate actions into labeled sections using `Separator`.
|
|
1507
|
+
- Do not mix items with and without leading content (icons/toggles) in the same section.
|
|
1508
|
+
|
|
1509
|
+
**Behavior**
|
|
1510
|
+
- Closes after selection unless multi-select is enabled.
|
|
1511
|
+
- Positions above, below, left, or right of the trigger with a 4px gap, adapting to viewport space.
|
|
1512
|
+
- Submenus open on hover.
|
|
1513
|
+
|
|
1514
|
+
**Often used with**
|
|
1515
|
+
- `Button`, `Select`, `Combobox`, `Separator`, `Badge`, checkbox toggles.
|
|
1516
|
+
|
|
1517
|
+
#### Pagination
|
|
1518
|
+
|
|
1519
|
+
**Storybook-slug:** pagination
|
|
1520
|
+
**Docs-slug:** pagination
|
|
1521
|
+
|
|
1522
|
+
**Definition**
|
|
1523
|
+
Divides large datasets into pages, giving users control over navigation and improving load performance.
|
|
1524
|
+
|
|
1525
|
+
**Use when**
|
|
1526
|
+
- Datasets are large (tables, search results, galleries).
|
|
1527
|
+
- Performance concerns rule out infinite scroll.
|
|
1528
|
+
- Users need to bookmark or return to a specific page position.
|
|
1529
|
+
|
|
1530
|
+
**Use something else when**
|
|
1531
|
+
- The context is a discovery feed (use infinite scroll or "Load more").
|
|
1532
|
+
- Users are completing a sequential task (use a wizard/stepper).
|
|
1533
|
+
- You need to switch between unrelated modes (use `Segmented Control` or `Tabs`).
|
|
1534
|
+
|
|
1535
|
+
**Dos and don'ts**
|
|
1536
|
+
- Do place pagination below content, left-aligned.
|
|
1537
|
+
- Do provide "Next" and "Previous" buttons, disabled when irrelevant.
|
|
1538
|
+
- Do include "Results per page" options for large datasets.
|
|
1539
|
+
- Do not use pagination when fewer than ~20 items per page exist.
|
|
1540
|
+
|
|
1541
|
+
**Behavior**
|
|
1542
|
+
- Each page should have its own shareable URL.
|
|
1543
|
+
- Content loads without full page reloads; use loaders and skeletons while data fetches.
|
|
1544
|
+
- Teleport variant allows direct page number entry.
|
|
1545
|
+
- Filters, searches, and selections persist across pages.
|
|
1546
|
+
|
|
1547
|
+
**Often used with**
|
|
1548
|
+
- `Table`, data grids, `Search`, `Skeleton`.
|
|
1549
|
+
|
|
1550
|
+
#### Popover
|
|
1551
|
+
|
|
1552
|
+
**Storybook-slug:** popover
|
|
1553
|
+
**Docs-slug:** popover
|
|
1554
|
+
|
|
1555
|
+
**Definition**
|
|
1556
|
+
A click-triggered panel for interactive or structured supplemental content. Stays open until dismissed.
|
|
1557
|
+
|
|
1558
|
+
**Use when**
|
|
1559
|
+
- User needs to pick options, fill short fields, or read formatted content on demand without leaving the page.
|
|
1560
|
+
|
|
1561
|
+
**Use something else when**
|
|
1562
|
+
- Content is essential to the task — surface it inline or in `Dialog` / `Drawer`.
|
|
1563
|
+
- A brief, non-interactive hint is needed (use `Tooltip`).
|
|
1564
|
+
|
|
1565
|
+
**Often used with**
|
|
1566
|
+
- `Button` or icon as trigger, `Command`, form controls inside the panel.
|
|
1567
|
+
|
|
1568
|
+
#### Radio
|
|
1569
|
+
|
|
1570
|
+
**Storybook-slug:** radio
|
|
1571
|
+
**Docs-slug:** radio
|
|
1572
|
+
|
|
1573
|
+
**Definition**
|
|
1574
|
+
Allows users to select exactly one option from a small set of mutually exclusive choices.
|
|
1575
|
+
|
|
1576
|
+
**Use when**
|
|
1577
|
+
- Single selection from a small, visible set of predefined options.
|
|
1578
|
+
- All options should be visible side by side for comparison.
|
|
1579
|
+
|
|
1580
|
+
**Use something else when**
|
|
1581
|
+
- Multiple selections are needed (use `Checkbox`).
|
|
1582
|
+
- There are more than ~5 options or space is limited (use `Select` or `Combobox`).
|
|
1583
|
+
- The choice is binary and takes immediate effect (use `Switch`).
|
|
1584
|
+
|
|
1585
|
+
**Dos and don'ts**
|
|
1586
|
+
- Do pair each radio with a descriptive label.
|
|
1587
|
+
- Do not group unrelated options.
|
|
1588
|
+
- Do not exceed 5 options.
|
|
1589
|
+
|
|
1590
|
+
**Behavior**
|
|
1591
|
+
- Clicking or pressing Space selects the focused option and deselects others in the group.
|
|
1592
|
+
|
|
1593
|
+
**Often used with**
|
|
1594
|
+
- `Label`, helper text, `Card` variant for options needing supporting descriptions.
|
|
1595
|
+
|
|
1596
|
+
#### Search
|
|
1597
|
+
|
|
1598
|
+
**Storybook-slug:** search
|
|
1599
|
+
**Docs-slug:** search
|
|
1600
|
+
|
|
1601
|
+
**Definition**
|
|
1602
|
+
A specialized input for locating and filtering content, with built-in search and clear affordances.
|
|
1603
|
+
|
|
1604
|
+
**Use when**
|
|
1605
|
+
- Lists, tables, or datasets need quick item location.
|
|
1606
|
+
- Content-heavy pages where scrolling is impractical.
|
|
1607
|
+
- Application-wide search (in conjunction with `Command`).
|
|
1608
|
+
|
|
1609
|
+
**Use something else when**
|
|
1610
|
+
- Selecting from predefined options (use `Combobox` or `Select`).
|
|
1611
|
+
- Multi-attribute filtering requires dedicated filter controls.
|
|
1612
|
+
- General text input unrelated to content discovery (use `Input`).
|
|
1613
|
+
|
|
1614
|
+
**Dos and don'ts**
|
|
1615
|
+
- Do make it clear whether search covers the current list, the page, or the whole app.
|
|
1616
|
+
- Do display a no-results state when queries return nothing.
|
|
1617
|
+
- Do debounce live search to avoid excessive requests.
|
|
1618
|
+
- Do use descriptive placeholder text ("Search assets").
|
|
1619
|
+
- Do not leave empty results without explanation.
|
|
1620
|
+
|
|
1621
|
+
**Often used with**
|
|
1622
|
+
- `Table`, data grids, `Command`, adjacent filter controls (`Select`, `Combobox`).
|
|
1623
|
+
|
|
1624
|
+
#### Segmented Control
|
|
1625
|
+
|
|
1626
|
+
**Storybook-slug:** segmented
|
|
1627
|
+
**Docs-slug:** segmented-control
|
|
1628
|
+
|
|
1629
|
+
**Definition**
|
|
1630
|
+
Switches between a small number of peer views or modes on the same page.
|
|
1631
|
+
|
|
1632
|
+
**Use when**
|
|
1633
|
+
- Two to several comparable sections (for example overview vs details vs activity).
|
|
1634
|
+
|
|
1635
|
+
**Use something else when**
|
|
1636
|
+
- Content is hierarchical or lengthy and users must open multiple sections at once (consider `Accordion` or visible sections).
|
|
1637
|
+
- Navigating separate routes (tabs/sidebar patterns — see `building-pages.md`).
|
|
1638
|
+
|
|
1639
|
+
**Relationship to Accordion**
|
|
1640
|
+
- Segmented control swaps visibility of peer panels; accordion stacks expandable sections. Prefer segmented control when users switch modes frequently; accordion when progressive disclosure matters.
|
|
1641
|
+
|
|
1642
|
+
#### Select
|
|
1643
|
+
|
|
1644
|
+
**Storybook-slug:** select
|
|
1645
|
+
**Docs-slug:** select
|
|
1646
|
+
|
|
1647
|
+
**Definition**
|
|
1648
|
+
Enables users to choose one or more predefined options from a dropdown list. Used in forms and filtering when space is constrained.
|
|
1649
|
+
|
|
1650
|
+
**Use when**
|
|
1651
|
+
- Multiple predefined options exist and space prevents showing them all at once.
|
|
1652
|
+
- Options are familiar and don't require explanation.
|
|
1653
|
+
- A single or multi-select form input is needed.
|
|
1654
|
+
|
|
1655
|
+
**Use something else when**
|
|
1656
|
+
- 12+ options or search is needed (use `Combobox`).
|
|
1657
|
+
- Few options or a binary choice (use `Checkbox`, `Radio`, or `Switch`).
|
|
1658
|
+
- User-created values are needed (use `Combobox`).
|
|
1659
|
+
- Options need lengthy descriptions (use `Checkbox` or `Radio`).
|
|
1660
|
+
- Selection triggers immediate mode-switch (use `Segmented Control` or `Tabs`).
|
|
1661
|
+
|
|
1662
|
+
**Dos and don'ts**
|
|
1663
|
+
- Do provide a clear label and placeholder.
|
|
1664
|
+
- Do use helper text when clarification is needed.
|
|
1665
|
+
- Exercise caution with default selections — users may overlook them.
|
|
1666
|
+
|
|
1667
|
+
**Behavior**
|
|
1668
|
+
- Single-select closes after selection; multi-select may remain open.
|
|
1669
|
+
- Checkmarks appear right-aligned in the list.
|
|
1670
|
+
|
|
1671
|
+
**Often used with**
|
|
1672
|
+
- `Label`, helper text, `Button`.
|
|
1673
|
+
|
|
1674
|
+
#### Separator
|
|
1675
|
+
|
|
1676
|
+
**Storybook-slug:** separator
|
|
1677
|
+
**Docs-slug:** separator
|
|
1678
|
+
|
|
1679
|
+
**Definition**
|
|
1680
|
+
A 1px visual divider between distinct content sections. Improves readability while remaining visually subtle.
|
|
1681
|
+
|
|
1682
|
+
**Use when**
|
|
1683
|
+
- Creating visual relief between related groups of content.
|
|
1684
|
+
- Dividing sections within toolbars, menus, cards, or forms.
|
|
1685
|
+
|
|
1686
|
+
**Use something else when**
|
|
1687
|
+
- The layout is sparse — whitespace alone is sufficient.
|
|
1688
|
+
- Sections need semantic grouping (use headings, `Card`, or background regions instead).
|
|
1689
|
+
|
|
1690
|
+
**Dos and don'ts**
|
|
1691
|
+
- Do use 16px vertical separators for button or horizontal form element separation.
|
|
1692
|
+
- Do not place separators between every element.
|
|
1693
|
+
- Do not use bold or colorful separators — keep them subtle.
|
|
1694
|
+
- Do not replace semantic headings or landmarks with separators.
|
|
1695
|
+
|
|
1696
|
+
**Often used with**
|
|
1697
|
+
- `Toolbar`, `Card` headers/footers, `Accordion`, menus, dense form sections.
|
|
1698
|
+
|
|
1699
|
+
#### Skeleton
|
|
1700
|
+
|
|
1701
|
+
**Storybook-slug:** skeleton
|
|
842
1702
|
|
|
843
|
-
**
|
|
1703
|
+
**Definition**
|
|
1704
|
+
A loading placeholder that mimics the shape of incoming content, reducing perceived wait time and preventing layout shift.
|
|
1705
|
+
|
|
1706
|
+
**Use when**
|
|
1707
|
+
- Content is loading and the shape of the result is predictable (cards, lists, table rows).
|
|
1708
|
+
- Reducing layout shift while data fetches in the background.
|
|
1709
|
+
|
|
1710
|
+
**Use something else when**
|
|
1711
|
+
- The loading duration is very short (<300ms) — no loader is needed.
|
|
1712
|
+
- The content shape is unpredictable (use a spinner or progress indicator).
|
|
1713
|
+
|
|
1714
|
+
**Dos and don'ts**
|
|
1715
|
+
- Do match skeleton shapes to the actual content layout.
|
|
1716
|
+
- Do not animate excessively — subtle pulse is sufficient.
|
|
1717
|
+
|
|
1718
|
+
**Often used with**
|
|
1719
|
+
- `Card`, `Table`, `Pagination`, lists.
|
|
1720
|
+
|
|
1721
|
+
#### Slider
|
|
1722
|
+
|
|
1723
|
+
**Storybook-slug:** slider
|
|
1724
|
+
**Docs-slug:** slider
|
|
1725
|
+
|
|
1726
|
+
**Definition**
|
|
1727
|
+
An interactive control for selecting a single value or a range from a continuous scale. Provides visual feedback and quick approximate value selection.
|
|
1728
|
+
|
|
1729
|
+
**Use when**
|
|
1730
|
+
- Adjusting continuous values where precision is less important than visual feedback (volume, brightness, pricing filter).
|
|
1731
|
+
- Providing immediate visual feedback (media scrubbing, live previews).
|
|
1732
|
+
- Selecting a minimum and maximum range.
|
|
1733
|
+
|
|
1734
|
+
**Use something else when**
|
|
1735
|
+
- Precise numeric entry is required (use `Input` or `Select`).
|
|
1736
|
+
- The choice is categorical, not continuous (use `Radio` or `Select`).
|
|
1737
|
+
|
|
1738
|
+
**Behavior**
|
|
1739
|
+
- Supports immediate feedback (changes apply as the user drags) and deferred feedback (changes apply on submit).
|
|
1740
|
+
- Use deferred feedback when slider adjustments trigger screen reloads or visual disruptions; pair with helper text explaining that the user must submit to apply.
|
|
1741
|
+
|
|
1742
|
+
**Often used with**
|
|
1743
|
+
- `Label`, helper text, optional adjacent `Input` for precise numeric entry.
|
|
1744
|
+
|
|
1745
|
+
#### Sonner Toast
|
|
1746
|
+
|
|
1747
|
+
**Storybook-slug:** sonner
|
|
1748
|
+
**Docs-slug:** sonner
|
|
1749
|
+
|
|
1750
|
+
**Definition**
|
|
1751
|
+
Lightweight, auto-dismiss feedback for outcomes that do not need a blocking surface.
|
|
1752
|
+
|
|
1753
|
+
**Use when**
|
|
1754
|
+
- Confirming save, delete, or background completion.
|
|
1755
|
+
- Non-critical notices the user can miss without breaking a workflow.
|
|
1756
|
+
|
|
1757
|
+
**Use something else when**
|
|
1758
|
+
- User must read and act before continuing (`Alert Dialog`, `Dialog`, or persistent `Alert` / `Banner`).
|
|
1759
|
+
|
|
1760
|
+
#### Switch
|
|
1761
|
+
|
|
1762
|
+
**Storybook-slug:** switch
|
|
1763
|
+
**Docs-slug:** switch
|
|
1764
|
+
|
|
1765
|
+
**Definition**
|
|
1766
|
+
A binary toggle control that turns a setting on or off, with changes taking effect immediately.
|
|
1767
|
+
|
|
1768
|
+
**Use when**
|
|
1769
|
+
- Toggling a setting that takes immediate effect (for example, dark mode, notifications).
|
|
1770
|
+
|
|
1771
|
+
**Use something else when**
|
|
1772
|
+
- The change is form-dependent and deferred (use `Checkbox` or `Button`).
|
|
1773
|
+
- The action is one-time or destructive (use `Button`).
|
|
1774
|
+
- Multiple related toggles need grouping (use `Toggle Group`, `Checkbox`, or `Select`).
|
|
1775
|
+
|
|
1776
|
+
**Dos and don'ts**
|
|
1777
|
+
- Do apply a clear, descriptive label explaining the switch's function.
|
|
1778
|
+
- Do not embed switches inside `Menu` components — use menu checkmarks instead.
|
|
1779
|
+
- Do not use for destructive actions.
|
|
1780
|
+
|
|
1781
|
+
**Behavior**
|
|
1782
|
+
- Responds instantly to user interaction without requiring separate form submission.
|
|
1783
|
+
|
|
1784
|
+
**Often used with**
|
|
1785
|
+
- `Label`, helper text.
|
|
1786
|
+
|
|
1787
|
+
#### Table
|
|
1788
|
+
|
|
1789
|
+
**Storybook-slug:** table
|
|
1790
|
+
|
|
1791
|
+
**Definition**
|
|
1792
|
+
Dense, scannable display of rows and columns with optional selection and actions.
|
|
1793
|
+
|
|
1794
|
+
**Use when**
|
|
1795
|
+
- Comparing rows, scanning many attributes, or operating on multiple items.
|
|
1796
|
+
|
|
1797
|
+
**Use something else when**
|
|
1798
|
+
- A simple fixed list of links or single-column items (`List`).
|
|
1799
|
+
- A primary chart or narrative view (`Card`, charts — see Storybook).
|
|
1800
|
+
|
|
1801
|
+
**Often used with**
|
|
1802
|
+
- Selection + `Action Toolbar` (when selection-gated actions apply), `Pagination`, `Empty State`, row `Checkbox`, `Dropdown Menu` for row actions.
|
|
1803
|
+
|
|
1804
|
+
#### Tabs
|
|
1805
|
+
|
|
1806
|
+
**Storybook-slug:** tabs
|
|
1807
|
+
**Docs-slug:** tabs
|
|
1808
|
+
|
|
1809
|
+
**Definition**
|
|
1810
|
+
Organizes related content into switchable sections, allowing users to navigate between different views without leaving the page.
|
|
1811
|
+
|
|
1812
|
+
**Use when**
|
|
1813
|
+
- Organizing content into sections users switch between frequently.
|
|
1814
|
+
- Displaying related, mutually exclusive content.
|
|
1815
|
+
- Navigation within pages, dashboards, settings, or data views.
|
|
1816
|
+
|
|
1817
|
+
**Use something else when**
|
|
1818
|
+
- Filtering a list or dataset (use `Segmented Control`, `Button`, or `Menu`).
|
|
1819
|
+
- Multiple sections must be visible simultaneously (use `Accordion` or filters).
|
|
1820
|
+
- The choice is a binary toggle (use `Switch`).
|
|
1821
|
+
|
|
1822
|
+
**Dos and don'ts**
|
|
1823
|
+
- Do use a minimum of two tabs.
|
|
1824
|
+
- Do keep content above tabs stable across all tab states.
|
|
1825
|
+
- Do use leading icons consistently across all tabs or not at all.
|
|
1826
|
+
- Do not use tabs for basic filtering.
|
|
1827
|
+
- Do not apply to binary options.
|
|
1828
|
+
|
|
1829
|
+
**Behavior**
|
|
1830
|
+
- Exactly one tab panel is visible at a time.
|
|
1831
|
+
- Tab buttons manage selection state and keyboard focus.
|
|
1832
|
+
- Supports default, vertical, and full-width alignment options.
|
|
1833
|
+
|
|
1834
|
+
**Often used with**
|
|
1835
|
+
- `Table`, `Form`, `Card`, `Empty State`. Keep global page actions outside tab panels.
|
|
1836
|
+
|
|
1837
|
+
#### Textarea
|
|
1838
|
+
|
|
1839
|
+
**Storybook-slug:** textarea
|
|
1840
|
+
**Docs-slug:** textarea
|
|
1841
|
+
|
|
1842
|
+
**Definition**
|
|
1843
|
+
A multi-line text field for extended free-form input such as comments, feedback, messages, descriptions, or notes.
|
|
1844
|
+
|
|
1845
|
+
**Use when**
|
|
1846
|
+
- Multi-line text is expected (comments, notes, bios, explanations).
|
|
1847
|
+
- Editing large chunks of existing text.
|
|
1848
|
+
|
|
1849
|
+
**Use something else when**
|
|
1850
|
+
- A single line of text is all that is needed (use `Input`).
|
|
1851
|
+
- Structured data is expected (use masked `Input`, `Date Picker`, `Select`, or `Combobox`).
|
|
1852
|
+
- Rich formatting is needed (use a rich-text editor).
|
|
1853
|
+
|
|
1854
|
+
**Dos and don'ts**
|
|
1855
|
+
- Do use concise labels and placeholder text.
|
|
1856
|
+
- Do allow scroll when content exceeds the maximum height.
|
|
1857
|
+
- Do not set a small fixed height for expected lengthy input.
|
|
1858
|
+
- Do not pre-fill with default text users might overlook.
|
|
1859
|
+
|
|
1860
|
+
**Behavior**
|
|
1861
|
+
- Supports optional user resizing via a drag handle.
|
|
1862
|
+
- Restrict resizing when layout integrity is critical (forms in modals or sidebars) or when the textarea auto-expands programmatically.
|
|
1863
|
+
|
|
1864
|
+
**Often used with**
|
|
1865
|
+
- `Label`, helper text (optionally with character count).
|
|
1866
|
+
|
|
1867
|
+
#### Time Picker
|
|
1868
|
+
|
|
1869
|
+
**Storybook-slug:** timepicker
|
|
1870
|
+
**Docs-slug:** date-and-time-picker
|
|
1871
|
+
|
|
1872
|
+
**Definition**
|
|
1873
|
+
Allows users to select a time value through a clock interface.
|
|
1874
|
+
|
|
1875
|
+
**Use when**
|
|
1876
|
+
- Users need to select a precise time without a date.
|
|
1877
|
+
- Scheduling tasks, alarms, or time-of-day settings.
|
|
1878
|
+
|
|
1879
|
+
**Use something else when**
|
|
1880
|
+
- Both date and time are required (use `Date Picker` or `Date Time Range Picker`).
|
|
1881
|
+
- Exact timing is not important (use basic `Input`).
|
|
1882
|
+
|
|
1883
|
+
**Behavior**
|
|
1884
|
+
- Keyboard users can type valid values directly.
|
|
1885
|
+
- Values commit in the configured locale format.
|
|
1886
|
+
|
|
1887
|
+
**Often used with**
|
|
1888
|
+
- `Label`, helper text, `Date Picker`.
|
|
1889
|
+
|
|
1890
|
+
#### Toggle
|
|
1891
|
+
|
|
1892
|
+
**Storybook-slug:** toggle
|
|
1893
|
+
|
|
1894
|
+
**Definition**
|
|
1895
|
+
A single pressable button with active/inactive state, used to toggle one option or formatting command on or off.
|
|
1896
|
+
|
|
1897
|
+
**Use when**
|
|
1898
|
+
- A single binary option needs a visible pressed/unpressed state (for example, bold text, mute).
|
|
1899
|
+
|
|
1900
|
+
**Use something else when**
|
|
1901
|
+
- Two or more related toggles should be grouped (use `Toggle Group`).
|
|
1902
|
+
- The change takes immediate app-level effect (use `Switch`).
|
|
1903
|
+
- The action is a one-time command (use `Button`).
|
|
1904
|
+
|
|
1905
|
+
**Often used with**
|
|
1906
|
+
- `Toolbar`, `Tooltip` for icon-only variants, `Toggle Group`.
|
|
1907
|
+
|
|
1908
|
+
#### Toggle Group
|
|
1909
|
+
|
|
1910
|
+
**Docs-slug:** toggle-group
|
|
1911
|
+
|
|
1912
|
+
**Definition**
|
|
1913
|
+
A set of 2–4 related toggle options for mutually exclusive or multi-select settings that are always visible.
|
|
1914
|
+
|
|
1915
|
+
**Use when**
|
|
1916
|
+
- Toggling between 2–4 always-visible, mutually exclusive modes (for example, grid lines, text alignment, ruler visibility).
|
|
1917
|
+
- The current selection must always be immediately clear.
|
|
1918
|
+
|
|
1919
|
+
**Use something else when**
|
|
1920
|
+
- More than ~4–5 options exist (use `Select` or `Menu`).
|
|
1921
|
+
- Options execute one-time commands (use `Button`).
|
|
1922
|
+
- Multi-select filtering across a larger set (use `Checkbox` or filter chips).
|
|
1923
|
+
- Single-select filtering of a small dataset (use `Segmented Control`).
|
|
1924
|
+
- The context is page navigation (use `Tabs` or routing).
|
|
1925
|
+
|
|
1926
|
+
**Dos and don'ts**
|
|
1927
|
+
- Do keep labels concise — one or two words or icons only.
|
|
1928
|
+
- Do not mix icons and text labels within the same group.
|
|
1929
|
+
|
|
1930
|
+
**Behavior**
|
|
1931
|
+
- Selection updates instantly.
|
|
1932
|
+
- Supports single-select and multi-select configurations.
|
|
1933
|
+
|
|
1934
|
+
**Often used with**
|
|
1935
|
+
- `Toolbar`, `Tooltip` for icon-only variants.
|
|
1936
|
+
|
|
1937
|
+
#### Toolbar
|
|
1938
|
+
|
|
1939
|
+
**Docs-slug:** toolbar
|
|
1940
|
+
|
|
1941
|
+
**Definition**
|
|
1942
|
+
Persistent strip of primary tools or filters for a page or region — available without selecting rows first.
|
|
1943
|
+
|
|
1944
|
+
**Use when**
|
|
1945
|
+
- Page-level create/filter/export actions.
|
|
1946
|
+
- Tools that apply to the whole view or the current query.
|
|
1947
|
+
|
|
1948
|
+
**Use something else when**
|
|
1949
|
+
- Actions apply only after row/item selection (use `Action Toolbar`).
|
|
1950
|
+
|
|
1951
|
+
#### Topbar
|
|
1952
|
+
|
|
1953
|
+
**Storybook-slug:** topbar
|
|
1954
|
+
**Docs-slug:** topbar
|
|
1955
|
+
|
|
1956
|
+
**Definition**
|
|
1957
|
+
The single, persistent navigation bar at the top of every authenticated CDF and Flows custom app. Provides the primary orientation layer across three fixed regions: left (identity/breadcrumbs), middle (optional global navigation), and right (system controls).
|
|
1958
|
+
|
|
1959
|
+
**Use when**
|
|
1960
|
+
- Every authenticated screen in a CDF or Flows app — this component is mandatory.
|
|
1961
|
+
- The app has two or more top-level views requiring global switching.
|
|
1962
|
+
- Actions apply consistently across all app pages (for example, a persistent "Add data" button).
|
|
1963
|
+
|
|
1964
|
+
**Use something else when**
|
|
1965
|
+
- Login or authentication-only screens.
|
|
1966
|
+
- Full-screen flows or modals that intentionally hide global chrome.
|
|
1967
|
+
|
|
1968
|
+
**Dos and don'ts**
|
|
1969
|
+
- Do use the middle section for primary global app navigation.
|
|
1970
|
+
- Do use `Tabs` for distinct pages, `Segmented Control` for mode switching in the middle section.
|
|
1971
|
+
- Do not place page-specific actions in the action slot.
|
|
1972
|
+
- Do not reorder or restyle system controls.
|
|
1973
|
+
- Do not use multiple topbars per page.
|
|
1974
|
+
|
|
1975
|
+
**Behavior**
|
|
1976
|
+
- Left: app mark (small `Avatar`), breadcrumbs, optional inline metadata.
|
|
1977
|
+
- Middle: optional; omit for single-view apps.
|
|
1978
|
+
- Right (fixed order): Share → Notifications → Theme → Atlas.
|
|
1979
|
+
|
|
1980
|
+
**Often used with**
|
|
1981
|
+
- `Breadcrumb`, `Tabs`, `Segmented Control`, `Avatar`.
|
|
1982
|
+
|
|
1983
|
+
#### Tooltip
|
|
1984
|
+
|
|
1985
|
+
**Storybook-slug:** tooltip
|
|
1986
|
+
**Docs-slug:** tooltip
|
|
1987
|
+
|
|
1988
|
+
**Definition**
|
|
1989
|
+
A short hint that appears on hover or focus. No heavy interaction inside.
|
|
1990
|
+
|
|
1991
|
+
**Use when**
|
|
1992
|
+
- Clarifying a control or icon in one line or sentence.
|
|
1993
|
+
- Providing the full text of a truncated label (for example in `Breadcrumb`).
|
|
1994
|
+
|
|
1995
|
+
**Use something else when**
|
|
1996
|
+
- Content is essential to the task — surface it inline or in `Dialog` / `Drawer`.
|
|
1997
|
+
- Users need to interact with the content (use `Popover`).
|
|
1998
|
+
|
|
1999
|
+
**Often used with**
|
|
2000
|
+
- Icon-only `Button`, `Toggle`, `Breadcrumb`, `Label`.
|
|
2001
|
+
|
|
2002
|
+
#### Tree
|
|
2003
|
+
|
|
2004
|
+
**Storybook-slug:** tree
|
|
2005
|
+
**Docs-slug:** tree-view
|
|
2006
|
+
|
|
2007
|
+
**Definition**
|
|
2008
|
+
Displays hierarchical data in a nested structure with expandable/collapsible rows. Supports optional selection and drag-and-drop.
|
|
2009
|
+
|
|
2010
|
+
**Use when**
|
|
2011
|
+
- Presenting large structures with multiple nesting levels (folders, files, organizational hierarchies).
|
|
2012
|
+
- Progressive disclosure of complex hierarchical relationships.
|
|
2013
|
+
|
|
2014
|
+
**Use something else when**
|
|
2015
|
+
- Data is not hierarchical (use lists or `Table`).
|
|
2016
|
+
- A sortable, tabular layout with multiple columns is needed (use `Table`).
|
|
2017
|
+
- Non-hierarchical filtering is the goal (use `Tabs` or `Segmented Control`).
|
|
2018
|
+
- Showing location in site hierarchy (use `Breadcrumb`).
|
|
2019
|
+
|
|
2020
|
+
**Behavior**
|
|
2021
|
+
- Nodes expand and collapse independently.
|
|
2022
|
+
- Keyboard navigation follows tree semantics (arrow keys, Home/End).
|
|
2023
|
+
- Supports single and multi-selection.
|
|
2024
|
+
- Optional drag-and-drop reordering (must maintain accessibility).
|
|
2025
|
+
|
|
2026
|
+
**Often used with**
|
|
2027
|
+
- Row checkboxes, row menus, `Badge` for status, drag handles, selection highlights connecting to a side panel or `Table` in split-view layouts.
|
|
2028
|
+
|
|
2029
|
+
## Escalation guidance
|
|
2030
|
+
|
|
2031
|
+
If a primitive does not fit:
|
|
2032
|
+
1. Check Storybook variants/props first.
|
|
2033
|
+
2. Compose with existing primitives.
|
|
2034
|
+
3. If still blocked, note the gap and keep implementation consistent with Aura foundations.
|
|
2035
|
+
|
|
2036
|
+
---
|
|
2037
|
+
|
|
2038
|
+
## Do's and Don'ts
|
|
2039
|
+
|
|
2040
|
+
Practical guardrails for Aura-based UI. For full rationale, see [Heuristics](#heuristics), [Interaction states](#interaction-states), and [Content](#content).
|
|
2041
|
+
|
|
2042
|
+
### Do
|
|
2043
|
+
|
|
2044
|
+
- Use semantic or base **color tokens** — never raw hex, rgb, or hsl when a token exists.
|
|
2045
|
+
- Prefer Aura component **variants and APIs** over overriding styles with visual Tailwind utilities on primitives.
|
|
2046
|
+
- Show **loading feedback** (`Shimmer`, `Loader`, `Skeleton`) for any wait the user is expected to sit through.
|
|
2047
|
+
- Provide a **visible focus ring** on every interactive control (`shadow-focus-ring` / `shadow-focus-ring-destructive` on `:focus-visible`).
|
|
2048
|
+
- Cap continuous **body text** at `{spacing.prose-max}` width; keep companion UI outside that measure.
|
|
2049
|
+
- Use the **`{spacing.base}` spacing scale** for padding, margin, and gaps.
|
|
2050
|
+
- Pair **icon-only controls** with `aria-label` and a `Tooltip`.
|
|
2051
|
+
- Use **sentence case** for all UI copy; write action labels as verb + object ("Save changes", "Delete pipeline").
|
|
2052
|
+
- Verify **contrast in both light and dark themes** before shipping.
|
|
2053
|
+
|
|
2054
|
+
### Don't
|
|
2055
|
+
|
|
2056
|
+
- Don't use semantic status colors (`info-*`, `success-*`, `warning-*`, `destructive-*`) as generic decoration or toggled selection fills.
|
|
2057
|
+
- Don't remove focus styling or use `outline-none` / `ring-0` without an equivalent token-based focus ring.
|
|
2058
|
+
- Don't stack multiple **Alerts** or **toasts** for a single user gesture.
|
|
2059
|
+
- Don't use `alert()` or other native blocking dialogs for product UX.
|
|
2060
|
+
- Don't hardcode **font sizes, shadows, or border radii** when theme tokens exist.
|
|
2061
|
+
- Don't use icon-only targets without an accessible name and tooltip.
|
|
2062
|
+
- Don't mix **chart**, **decorative**, and **semantic** color groups interchangeably.
|
|
2063
|
+
- Don't override Aura primitive appearance with visual `className` utilities — use variants instead.
|
|
844
2064
|
|
|
845
2065
|
---
|
|
846
2066
|
|
|
847
|
-
## Assets
|
|
2067
|
+
## Assets & Motion
|
|
848
2068
|
|
|
849
|
-
**What this section is:** Rules for **illustrations**, **document icons**, **app icons**, and **system icons** in Aura-based products. Each type has a distinct job; mixing types or bending the rules adds noise and weakens trust. Visual execution (where files live, export pipelines) belongs in brand tooling and engineering skills, not here.
|
|
2069
|
+
**What this section is:** Rules for **illustrations**, **document icons**, **app icons**, and **system icons** in Aura-based products. It also includes rules and guidance for motion design. Each type has a distinct job; mixing types or bending the rules adds noise and weakens trust. Visual execution (where files live, export pipelines) belongs in brand tooling and engineering skills, not here.
|
|
850
2070
|
|
|
851
2071
|
### Illustrations
|
|
852
2072
|
|
|
@@ -940,18 +2160,243 @@ Rare exceptions (third-party or Cognite logos inside a cell) use **provided SVGs
|
|
|
940
2160
|
- **Must** give icon-only controls an accessible name (`aria-label` / `aria-labelledby`) **and** a **Tooltip** on hover/focus where the design hides the text label.
|
|
941
2161
|
- Icons that only repeat the meaning of adjacent visible text **should** be `aria-hidden="true"`.
|
|
942
2162
|
|
|
2163
|
+
### Motion (reference)
|
|
2164
|
+
|
|
2165
|
+
Short UI motion (e.g. accordion height) uses **~0.2s ease-out** in utilities; there is no separate “motion duration” token table in Aura today — follow component and `tw-animate-css` patterns.
|
|
2166
|
+
|
|
2167
|
+
---
|
|
2168
|
+
|
|
2169
|
+
## Heuristics
|
|
2170
|
+
|
|
2171
|
+
**What this section is:** The short interaction contract for Aura-based UIs. It keeps the design identity usable by agents and reviewers without turning this file into a full UX playbook.
|
|
2172
|
+
|
|
2173
|
+
This section contains Aura's decision rules, component selection guidance, and common failure modes. Severity terms carry specific meaning: **Must** / **must not** breaks usability, accessibility, or system conformance; **Should** is the strong default; **Avoid** is a known failure mode.
|
|
2174
|
+
|
|
2175
|
+
These rules apply to Aura primitives, host-shell components themed with Aura tokens, and standalone apps using Aura. Component props and enum names live in the component APIs, not in this spec.
|
|
2176
|
+
|
|
2177
|
+
### Aura vs. your responsibility
|
|
2178
|
+
|
|
2179
|
+
Aura components handle many accessibility concerns automatically. Composition, copy, focus management, and page structure remain the implementer's job.
|
|
2180
|
+
|
|
2181
|
+
| Concern | Aura handles | You verify |
|
|
2182
|
+
| --------------------- | --------------------------------------------------- | --------------------------------------------- |
|
|
2183
|
+
| Focus indicators | `shadow-focus-ring` on interactive elements | Not hidden by `overflow` or `z-index` |
|
|
2184
|
+
| Keyboard activation | Button: Enter/Space. Input: standard keys | Custom elements also respond |
|
|
2185
|
+
| ARIA roles | Correct roles on Dialog, SegmentedControl, etc. | Custom components declare correct roles |
|
|
2186
|
+
| Color contrast | Token pairs designed for AA compliance | Page backgrounds don't reduce contrast |
|
|
2187
|
+
| Dark mode | Semantic tokens adapt automatically | Custom colors also work in dark mode |
|
|
2188
|
+
| Disabled states | Communicated via `aria-disabled` | Reason for disabled is accessible |
|
|
2189
|
+
| Focus trapping | Dialog traps focus while open | Focus returns to the trigger element on close |
|
|
2190
|
+
|
|
2191
|
+
---
|
|
2192
|
+
|
|
2193
|
+
### 1. Feedback and system status
|
|
2194
|
+
|
|
2195
|
+
Users must always know whether the system is waiting, succeeded, failed, or needs action.
|
|
2196
|
+
|
|
2197
|
+
- **Must** show loading for any wait the user is expected to sit through. Use **Shimmer** or **Skeleton** when the incoming layout is known, **Loader** for compact waits, and **Progress** when completion is measurable.
|
|
2198
|
+
- **Must** acknowledge user-triggered mutations with visible feedback. Use a transient toast for low-stakes confirmations, inline feedback for scoped changes, and **Dialog** / shell **AlertDialog** before irreversible actions.
|
|
2199
|
+
- **Must** surface persistent workflow-impacting problems until dismissed or resolved. Use **Banner** for high-priority degraded states, **Alert** for page-scoped awareness, and **Badge** or compact status rows for repeated entity state.
|
|
2200
|
+
- **Avoid** blank loading areas, stacked toasts for one gesture, repeated Alert lists, and using **Banner** for routine connection handshakes.
|
|
2201
|
+
|
|
2202
|
+
### Alert vs Banner vs Badge vs Sonner
|
|
2203
|
+
|
|
2204
|
+
Use this matrix to pick the right feedback component. Priority is defined by whether the message requires immediate action and how long it needs to persist.
|
|
2205
|
+
|
|
2206
|
+
| Priority | When | Components | Notes |
|
|
2207
|
+
| ---------- | --------------------------------------------------------------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
2208
|
+
| **Low** | Non-disruptive updates, minor status, validation hints | `Badge`, notification dot, inline `HelperText` | Does not interrupt the user. Badge for entity state; HelperText for field-level feedback. |
|
|
2209
|
+
| **Medium** | Informative, occasionally actionable, not urgent | `Sonner` (toast), `Alert` | Sonner for transient confirmations (~4 s, bottom-right). Alert for inline, page-scoped status that needs awareness but not immediate action (typically one per page section/view). |
|
|
2210
|
+
| **High** | Requires immediate attention or action; may interrupt task flow | `Banner` (system errors), `Dialog` / `AlertDialog`, full-page error state | Banner for persistent, region-scoped degraded states. Dialog for irreversible actions. Never use Sonner as the sole safety net for destructive work. |
|
|
2211
|
+
|
|
2212
|
+
**Rules**
|
|
2213
|
+
|
|
2214
|
+
- **Must not** use Banner for low-priority or transient notices — it occupies persistent chrome and dilutes high-priority signals.
|
|
2215
|
+
- **Must not** use Sonner for errors that require user action — it auto-dismisses.
|
|
2216
|
+
- **Must not** use repeated Alerts as a list visualization pattern; one Alert communicates the grouped situation, while item-level status belongs in Badge/status-card patterns.
|
|
2217
|
+
- **Should** use `Badge` semantic variants (`warning`, `destructive`, `success`) on entities that carry that state, not as page-level alerts.
|
|
2218
|
+
- **Avoid** stacking multiple Sonner toasts for a single user gesture.
|
|
2219
|
+
|
|
2220
|
+
**Industrial / operational states**
|
|
2221
|
+
|
|
2222
|
+
The matrix above covers standard cases. For domain-specific states (e.g. sensor offline, process limit breach, control system degraded), apply the same priority logic: does the user need to act now? -> Banner or Dialog. Informational? -> Alert or Badge on the asset. Transient confirmation? -> Sonner. When many entities share similar state, summarize once (Alert/Banner) and show per-entity state with Badge or status cards.
|
|
2223
|
+
|
|
2224
|
+
---
|
|
2225
|
+
|
|
2226
|
+
### 2. Affordance and discoverability
|
|
2227
|
+
|
|
2228
|
+
Controls must read as interactive; users should not guess what is clickable, expandable, editable, or destructive.
|
|
2229
|
+
|
|
2230
|
+
- **Must** use semantic controls for actions, links, form fields, menus, and disclosure. Do not make generic elements behave like buttons.
|
|
2231
|
+
- **Must** match component variant to intent: primary for one main action, secondary or ghost for support, destructive only for irreversible work.
|
|
2232
|
+
- **Must** pair every field with a visible **Label**. Placeholder text is not a label.
|
|
2233
|
+
- **Must** give icon-only controls both an accessible name and a **Tooltip**.
|
|
2234
|
+
- **Should** use recognizable signifiers: chevrons for menus and disclosure, magnifier icons for search, helper text for constraints, and empty-state cards with an explanation plus a next action.
|
|
2235
|
+
- **Avoid** clickable text that looks identical to body copy or help that exists only in hover on touch-first flows.
|
|
2236
|
+
|
|
2237
|
+
---
|
|
2238
|
+
|
|
2239
|
+
### 3. Progressive disclosure
|
|
2240
|
+
|
|
2241
|
+
Introduce complexity only when needed; default views should stay scannable.
|
|
2242
|
+
|
|
2243
|
+
- **Must** use **Accordion** for stacked independent sections and **Collapsible** for one inline expandable block.
|
|
2244
|
+
- **Must** use **Dialog** for modal tasks and shell **Drawer** / **Sheet** for secondary edge panels where the host provides them.
|
|
2245
|
+
- **Must** split flows with 3 or more steps into discrete steps with visible progress.
|
|
2246
|
+
- **Must** scope menu items to the entity they affect. Do not mix row actions, page actions, and global actions in one menu.
|
|
2247
|
+
- **Should** keep advanced settings, rare metadata, and secondary actions behind disclosure when they are not needed for the main task.
|
|
2248
|
+
- **Avoid** deeply nested accordions, long flat menus, and multiple irreversible primary decisions in one step.
|
|
2249
|
+
|
|
2250
|
+
---
|
|
2251
|
+
|
|
2252
|
+
### 4. Error handling and prevention
|
|
2253
|
+
|
|
2254
|
+
Prevent errors where possible. When errors happen, users must understand what failed, why it matters, and how to recover.
|
|
2255
|
+
|
|
2256
|
+
- **Must** confirm high-impact destructive actions before execution. Name the object and consequence; do not ask only "Are you sure?".
|
|
2257
|
+
- **Must** label destructive confirmation with the specific action, such as "Delete report", not "OK" or "Confirm".
|
|
2258
|
+
- **Must** show form errors inline on the affected field and explain how to fix them.
|
|
2259
|
+
- **Must** protect unsaved work with auto-save where feasible, persistent unsaved state where not, and a discard warning before navigation.
|
|
2260
|
+
- **Should** offer **Undo** for reversible destructive actions when recovery is cheap and contained in the same session.
|
|
2261
|
+
- **Must** validate fields on blur, not on every keystroke.
|
|
2262
|
+
- **Must** preserve user input on a failed submission — never clear the form.
|
|
2263
|
+
- **Must** move focus to the first invalid field after a failed submission and announce the error via `aria-live`.
|
|
2264
|
+
- **Avoid** using toast as the only safety net for irreversible work or revealing every validation error only on final submit.
|
|
2265
|
+
|
|
2266
|
+
**Field validation states**
|
|
2267
|
+
|
|
2268
|
+
Not every field type needs every validation kind. Use this to scope what to implement:
|
|
2269
|
+
|
|
2270
|
+
| Field type | Required | Format | Length | Range | Uniqueness |
|
|
2271
|
+
| ------------- | -------- | ------ | -------- | ------------ | ---------- |
|
|
2272
|
+
| Text input | Yes | — | Optional | — | Optional |
|
|
2273
|
+
| Email input | Yes | Yes | — | — | Optional |
|
|
2274
|
+
| Password | Yes | Yes | Yes | — | — |
|
|
2275
|
+
| Number input | Yes | — | — | Yes | — |
|
|
2276
|
+
| Date picker | Yes | — | — | Yes | — |
|
|
2277
|
+
| Textarea | Yes | — | Yes | — | — |
|
|
2278
|
+
| Select | Yes | — | — | — | — |
|
|
2279
|
+
| Combobox | Yes | — | — | — | — |
|
|
2280
|
+
| Checkbox | — | — | — | — | — |
|
|
2281
|
+
| File upload | Yes | Yes | — | Yes (size) | — |
|
|
2282
|
+
|
|
2283
|
+
**Edge cases**
|
|
2284
|
+
|
|
2285
|
+
- Destructive action with undo? Still confirm — mention the undo window in the dialog body ("You can undo within 30 seconds").
|
|
2286
|
+
- Bulk delete? One confirmation naming the count ("Delete 12 reports?"), not one per item.
|
|
2287
|
+
- Auto-save? Use a subtle persistent "Saved" indicator, not a toast on every save.
|
|
2288
|
+
- Error partway through a multi-step flow? Don't lose progress — show the error on the current step and let the user retry from there.
|
|
2289
|
+
|
|
2290
|
+
---
|
|
2291
|
+
|
|
2292
|
+
### 5. Enabling power users
|
|
2293
|
+
|
|
2294
|
+
Experts should move faster without harming first-time clarity.
|
|
2295
|
+
|
|
2296
|
+
- **Should** provide shortcuts for the top few high-frequency actions and render them with Aura shortcut components.
|
|
2297
|
+
- **Should** align shortcuts with platform norms where they do not fight the browser or operating system.
|
|
2298
|
+
- **Must** support multi-select in list or table UIs that offer per-row destructive or batch actions.
|
|
2299
|
+
- **Must** show bulk action controls only when selection is non-empty, with selected count.
|
|
2300
|
+
- **Must** use structured empty states for first use or no data: title, explanation, and one clear next action.
|
|
2301
|
+
- **Avoid** bulk destructive work without confirmation, stealing reserved shortcuts, or using **Banner** for long onboarding tours.
|
|
2302
|
+
|
|
2303
|
+
---
|
|
2304
|
+
|
|
2305
|
+
### 6. Layout and hierarchy
|
|
2306
|
+
|
|
2307
|
+
Information must be scannable and oriented before action.
|
|
2308
|
+
|
|
2309
|
+
- **Must** group related fields and content in one **Card** or labeled section.
|
|
2310
|
+
- **Must** separate unrelated groups with spacing, section labels, or **Separator** before adding nested borders.
|
|
2311
|
+
- **Must** keep one clear primary CTA per view. Global actions belong in shell chrome; page actions belong in the page header or toolbar.
|
|
2312
|
+
- **Must** use shell **Tabs** / **SegmentedControl** for primary view switching where the product uses that pattern; do not duplicate global navigation in content.
|
|
2313
|
+
- **Should** use type scale, weight, and spacing to lead attention before using color or elevation.
|
|
2314
|
+
- **Avoid** unrelated actions in the same card, hard-coded pixel widths, duplicated navigation, and destructive styling for non-destructive actions.
|
|
2315
|
+
|
|
2316
|
+
---
|
|
2317
|
+
|
|
2318
|
+
### 7. Accessibility and inclusive design
|
|
2319
|
+
|
|
2320
|
+
Aura targets **WCAG AA** for primitives — usage must preserve that.
|
|
2321
|
+
|
|
2322
|
+
- **Must** complete every task path with keyboard alone.
|
|
2323
|
+
- **Must** keep visible focus treatment on every interactive control. Never use `outline-none` or `ring-0` without an equivalent Aura focus ring.
|
|
2324
|
+
- **Must** preserve primitive roles and ARIA behavior when composing or wrapping Aura components.
|
|
2325
|
+
- **Must** name icon-only controls and pair them with a **Tooltip**.
|
|
2326
|
+
- **Must not** encode meaning with color alone. Pair color with text, icon, helper text, or label.
|
|
2327
|
+
- **Must** meet contrast and target-size requirements for the shipped context.
|
|
2328
|
+
- **Must** follow visual/reading order for tab order, with no keyboard traps; add a skip-to-content link on pages with complex navigation.
|
|
2329
|
+
- **Must** use heading levels in strict sequential order: one `H1` per page, never skip a level, and never use a heading tag purely for visual sizing — use the Typography scale instead.
|
|
2330
|
+
- **Avoid** pointer-only behavior, unreadable `muted-foreground` copy for required tasks, and sub-24px icon hit zones without expansion.
|
|
2331
|
+
|
|
2332
|
+
**Alt text and icon naming**
|
|
2333
|
+
|
|
2334
|
+
| Type | Approach | Example |
|
|
2335
|
+
| ------------------------ | ---------------------------- | ------------------------------------- |
|
|
2336
|
+
| Informational image | Describe the content | `alt="Chart: output up 20%"` |
|
|
2337
|
+
| Decorative image | Empty | `alt=""` |
|
|
2338
|
+
| Icon-only control | `aria-label` on the control | `aria-label="Delete report"` |
|
|
2339
|
+
| Icon paired with a label | Hide the icon | `aria-hidden="true"` on the icon |
|
|
2340
|
+
|
|
2341
|
+
**Announcing dynamic content**
|
|
2342
|
+
|
|
2343
|
+
| Scenario | Method |
|
|
2344
|
+
| ---------------------- | --------------------------------------------- |
|
|
2345
|
+
| Search/list results update | `aria-live="polite"` |
|
|
2346
|
+
| Form error | `aria-live="assertive"` |
|
|
2347
|
+
| Toast | Handled by the toast component |
|
|
2348
|
+
| Dialog opens | Focus moves into the dialog (Aura handles) |
|
|
2349
|
+
| Dialog closes | Return focus to the trigger element |
|
|
2350
|
+
|
|
2351
|
+
### Common pitfalls (agent guidance)
|
|
2352
|
+
|
|
2353
|
+
These are the most frequent mistakes when generating or modifying Aura-based UI. Avoid all of them.
|
|
2354
|
+
|
|
2355
|
+
- Raw hex, `rgb(...)`, or arbitrary Tailwind colors in product UI.
|
|
2356
|
+
- Visual `className` overrides that bypass Aura variants, props, or tokens.
|
|
2357
|
+
- Duplicate shell navigation inside content.
|
|
2358
|
+
- Cards that mix unrelated actions, unrelated data, and dense nested borders.
|
|
2359
|
+
- Semantic, decorative, and chart colors used interchangeably.
|
|
2360
|
+
- Icon-only controls without accessible names and tooltips.
|
|
2361
|
+
- Disabled primary CTAs with no visible path to resolve the blocker.
|
|
2362
|
+
|
|
2363
|
+
### Verifying accessibility
|
|
2364
|
+
|
|
2365
|
+
**Self-check before shipping a page**
|
|
2366
|
+
|
|
2367
|
+
- [ ] Tab through all elements in logical order
|
|
2368
|
+
- [ ] Every button/link works with Enter/Space
|
|
2369
|
+
- [ ] Every dialog opens/closes with keyboard, and Escape closes dialogs, popovers, and dropdowns
|
|
2370
|
+
- [ ] Every image has appropriate alt text; every form field has a visible label
|
|
2371
|
+
- [ ] Non-color indicator present for every status
|
|
2372
|
+
- [ ] Headings follow H1 → H2 → H3 with no skipped levels
|
|
2373
|
+
- [ ] Dynamic updates are announced to screen readers
|
|
2374
|
+
- [ ] Focus ring (`shadow-focus-ring`) is visible on all interactive elements
|
|
2375
|
+
|
|
2376
|
+
**Tooling**
|
|
2377
|
+
|
|
2378
|
+
- Automated: WAVE, axe DevTools, or Lighthouse in Chrome DevTools.
|
|
2379
|
+
- Manual: unplug the mouse and complete primary tasks keyboard-only; spot-check critical flows with VoiceOver (Mac) or NVDA (Windows).
|
|
2380
|
+
|
|
2381
|
+
**Accessibility edge cases**
|
|
2382
|
+
|
|
2383
|
+
- Complex data visualization? Provide a text summary via `alt` or screen-reader-only text.
|
|
2384
|
+
- Drag-and-drop? Requires a keyboard alternative.
|
|
2385
|
+
- Real-time dashboard? Use `aria-live="polite"`, not `"assertive"` — frequent updates should not interrupt the user.
|
|
2386
|
+
- Third-party embed? Give the `iframe` a descriptive `title`.
|
|
2387
|
+
|
|
943
2388
|
---
|
|
944
2389
|
|
|
945
2390
|
## Interaction states
|
|
946
2391
|
|
|
947
|
-
**What this section is:** What each interaction state
|
|
2392
|
+
**What this section is:** What each interaction state _means_ for users, which **Tokens** and patterns Aura uses, and rules for custom controls built outside the library. **How** to wire `focus-visible`, CVA variants, or component props belongs in code and engineering skills.
|
|
948
2393
|
|
|
949
|
-
Every interactive control signals what is possible, what is happening, and what the system registered. **States are signifiers** — visual cues for affordances (what the element
|
|
2394
|
+
Every interactive control signals what is possible, what is happening, and what the system registered. **States are signifiers** — visual cues for affordances (what the element _can_ do). Using them consistently builds trust and keeps keyboard and assistive-tech use predictable.
|
|
950
2395
|
|
|
951
|
-
| Concept
|
|
952
|
-
|
|
|
953
|
-
| **Affordance** | A property that makes an action possible (e.g. a control can be activated).
|
|
954
|
-
| **Signifier**
|
|
2396
|
+
| Concept | Meaning |
|
|
2397
|
+
| -------------- | -------------------------------------------------------------------------------------- |
|
|
2398
|
+
| **Affordance** | A property that makes an action possible (e.g. a control can be activated). |
|
|
2399
|
+
| **Signifier** | A visible cue that communicates that affordance (shape, label, shadow, state styling). |
|
|
955
2400
|
|
|
956
2401
|
Aura primitives ship these states by default; the rules below describe the **design contract** and apply when extending Aura or building one-off interactives.
|
|
957
2402
|
|
|
@@ -989,7 +2434,7 @@ Keyboard or assistive tech has moved focus to the element. This is the main non-
|
|
|
989
2434
|
- **Must** use Aura’s **token-based focus ring** — `shadow-focus-ring` (CSS variable `--shadow-focus-ring`, composed from `ring` + `ring-muted` tokens) for default controls, and **`shadow-focus-ring-destructive`** / `--shadow-focus-ring-destructive` for invalid or destructive fields. Shared utilities in the library pair `outline-none` **with** these rings on `:focus-visible` — never `outline-none` or `ring-0` **alone**.
|
|
990
2435
|
- **Must** meet **WCAG AA** for the focus indicator against its immediate background.
|
|
991
2436
|
- **Should** use **`:focus-visible`** (or library equivalents) so pointers do not get a keyboard ring on every click, while keyboard users always see one.
|
|
992
|
-
- **Invalid inputs:** on focus, use the **destructive** focus ring token pair above (see **
|
|
2437
|
+
- **Invalid inputs:** on focus, use the **destructive** focus ring token pair above (see **Elevation & Depth → Focus rings**).
|
|
993
2438
|
|
|
994
2439
|
### Disabled
|
|
995
2440
|
|
|
@@ -1009,7 +2454,7 @@ Persistent **on/off**, **selected**, **active filter**, or **applied setting** u
|
|
|
1009
2454
|
|
|
1010
2455
|
**Guidance**
|
|
1011
2456
|
|
|
1012
|
-
- **Must** use **`active-background`** / **`active-background-hover`** or **`active-muted-background`** / **`active-muted-background-hover`** (and matching foreground tokens such as **`foreground-on-active`**, **`active-foreground`**) — **not** semantic status colors (`info
|
|
2457
|
+
- **Must** use **`active-background`** / **`active-background-hover`** or **`active-muted-background`** / **`active-muted-background-hover`** (and matching foreground tokens such as **`foreground-on-active`**, **`active-foreground`**) — **not** semantic status colors (`info-`*, `success-`*, …) for generic toggles.
|
|
1013
2458
|
- **Must not** rely on **color alone** — combine fill with icon, checkmark, label, or border treatment where the pattern is ambiguous.
|
|
1014
2459
|
- **Must** implement **hover**, **pressed**, and **focus** for the **selected** variant as well as the default variant when both exist.
|
|
1015
2460
|
- **Must not** show “selected” visuals for controls that are not actually in a selected state.
|
|
@@ -1028,184 +2473,253 @@ Work is **in progress**; the control or region may be temporarily inert or show
|
|
|
1028
2473
|
|
|
1029
2474
|
## Content
|
|
1030
2475
|
|
|
1031
|
-
**What this section is:** Conventions for **UI copy**
|
|
2476
|
+
**What this section is:** Conventions for **Fusion monorepo UI copy** in Aura-based surfaces: action labels, date and time presentation, grammar and style, localization, voice and tone, and writing that supports accessibility. Use it with **Heuristics** and **Interaction states** when designing or implementing strings.
|
|
1032
2477
|
|
|
1033
2478
|
**Who:** Designers, product writers, engineers, and agents generating microcopy.
|
|
1034
2479
|
|
|
1035
|
-
**Scope:** English
|
|
1036
|
-
|
|
1037
|
-
---
|
|
1038
|
-
|
|
1039
|
-
### Action labels
|
|
1040
|
-
|
|
1041
|
-
Users predict behavior from **consistent verbs**. Action labels use **sentence case** (e.g. “Edit model”).
|
|
1042
|
-
|
|
1043
|
-
**Must not** use **Confirm** as the primary action — name the outcome (**Delete**, **Save**, **Send**, …). **Must** use **Sign in** and **Sign out**; **must not** use “Log in” / “Log out” in UI.
|
|
1044
|
-
|
|
1045
|
-
**Avoid** a labeled **Close** action **alongside** **Cancel** or a **Confirm**-labeled button in the same surface — use **Cancel** to abandon without applying, the **outcome verb** for commit, and/or icon-only dismiss per pattern library.
|
|
1046
|
-
|
|
1047
|
-
| Label | Use |
|
|
1048
|
-
| :--- | :--- |
|
|
1049
|
-
| **Add** | Attach an existing object to a new context (e.g. add to canvas). |
|
|
1050
|
-
| **Apply** | Commit filters or settings so they drive subsequent behavior. |
|
|
1051
|
-
| **Approve** | User agrees; in workflows, usually advances the process. |
|
|
1052
|
-
| **Back** | Previous step in a sequence or hierarchy. |
|
|
1053
|
-
| **Browse** | Structured scanning (categories, menus, filters). |
|
|
1054
|
-
| **Cancel** | Stop the current action and dismiss the surface; warn if stopping risks data loss. |
|
|
1055
|
-
| **Clear (all)** | Clear fields or selections; restore default where a control always has a value (e.g. radio). |
|
|
1056
|
-
| **Close** | Close a page, pane, or window (often icon-only). |
|
|
1057
|
-
| **Collapse** / **Expand** | Hide or show a panel (often icon-only). |
|
|
1058
|
-
| **Copy** | Copy to clipboard for use elsewhere. |
|
|
1059
|
-
| **Create** | New object from nothing (vs **Add** / **Duplicate**). |
|
|
1060
|
-
| **Delete** | Permanently remove the object. |
|
|
1061
|
-
| **Discard** | Abandon unsaved draft or edits. |
|
|
1062
|
-
| **Download** / **Upload** | Transfer file remote → local / local → remote. |
|
|
1063
|
-
| **Duplicate** | Copy in the same location as the original. |
|
|
1064
|
-
| **Edit** | Change data or values. |
|
|
1065
|
-
| **Explore** | Open-ended discovery without a fixed goal. |
|
|
1066
|
-
| **Export** | Save in an external format (often via a secondary step for type and destination). |
|
|
1067
|
-
| **Finish** | Complete a multi-step flow (e.g. wizard). |
|
|
1068
|
-
| **Hide** / **Show** | Toggle visibility in the UI only (not delete). |
|
|
1069
|
-
| **Import** | Bring data in from an external source. |
|
|
1070
|
-
| **Insert** | Place at a position in an ordered structure (e.g. table row). |
|
|
1071
|
-
| **Next** | Advance one step in a sequence. |
|
|
1072
|
-
| **Open** | **Internal:** drawer, modal, or in-app route (support open-in-new-tab where appropriate). **External:** new tab/window for external URLs. |
|
|
1073
|
-
| **Publish** / **Unpublish** | Make content available to intended audiences / remove from public view without deleting. |
|
|
1074
|
-
| **Query** | Request specific data from a store or service. |
|
|
1075
|
-
| **Redo** / **Undo** | Redo reverses undo; undo steps back through user edits (not all actions are undoable). |
|
|
1076
|
-
| **Refresh** | Reload when the view may be stale. |
|
|
1077
|
-
| **Register** | Create an account or enroll a user (prefer over “Sign up” where it could be confused with **Sign in**). |
|
|
1078
|
-
| **Reject** | User does not approve; in workflows, usually blocks progression. |
|
|
1079
|
-
| **Remove** | Remove from current context without destroying the object. |
|
|
1080
|
-
| **Reset** | Revert to last saved or default values. |
|
|
1081
|
-
| **Restore** | Revert to last saved version. |
|
|
1082
|
-
| **Save** | Persist changes without closing the surface. |
|
|
1083
|
-
| **Search** | Goal-oriented lookup. |
|
|
1084
|
-
| **Select** | Pick from a set of options. |
|
|
1085
|
-
| **Sign in** / **Sign out** | Authenticate / end session. |
|
|
1086
|
-
| **View** | Show details or properties (read-heavy). |
|
|
1087
|
-
|
|
1088
|
-
---
|
|
1089
|
-
|
|
1090
|
-
### Date and time formatting
|
|
2480
|
+
**Scope:** English UI strings authored in the Fusion monorepo unless a feature explicitly ships localized strings. Numeric date order and clocks follow the host platform `dateTime` configuration. Product naming, white-labeling policy, and market-facing terminology are owned by product documentation and brand guidance; this section covers in-product microcopy patterns that Aura surfaces should follow.
|
|
1091
2481
|
|
|
1092
|
-
|
|
2482
|
+
### Role
|
|
1093
2483
|
|
|
1094
|
-
|
|
2484
|
+
You are writing interface copy for Fusion applications. Every string must be purposeful, concise, conversational, and clear. Identify the target audience persona before writing; the persona determines reading level, technical vocabulary, and tone.
|
|
1095
2485
|
|
|
1096
|
-
|
|
1097
|
-
| :--- | :--- |
|
|
1098
|
-
| **Read-only vs input** | Read-only is display-only; input uses pickers/fields — both should stay consistent within a feature. |
|
|
1099
|
-
| **Full vs abbreviated** | Full (“2 January 2023”, “6 hours 7 minutes”) vs short (“2 Jan 2023”, “6 hr 7 min”). Prefer abbreviated only when space is tight. |
|
|
1100
|
-
| **Absolute vs relative** | Absolute = calendar date/time of the event; relative = “32 min ago”. |
|
|
2486
|
+
For code-level accessibility (keyboard navigation, ARIA, focus, headings, live regions), see `handling-states.md`.
|
|
1101
2487
|
|
|
1102
|
-
|
|
2488
|
+
### Audience personas
|
|
1103
2489
|
|
|
1104
|
-
**
|
|
2490
|
+
Canonical persona definitions live in the cogdocs repository (`cogdocs/cogdocs-metadata.mdx`, **Audience** section). This summary covers what matters for microcopy decisions.
|
|
1105
2491
|
|
|
1106
|
-
|
|
1107
|
-
|
|
2492
|
+
| Persona | Technical level | UX copy implication |
|
|
2493
|
+
| ----------------------- | --------------- | ------------------------------------------------------------------------------- |
|
|
2494
|
+
| `businessUser` | Low | Plain language; outcomes over features; domain terms OK, avoid platform jargon |
|
|
2495
|
+
| `businessDecisionMaker` | Low | Plain language; ROI, business value, strategic impact; minimal technical detail |
|
|
2496
|
+
| `appMaker` | Mid | Configuration, automation, outcomes; avoid deep code/API detail |
|
|
2497
|
+
| `dataAnalyst` | Mid | Analytics, insights, dashboards; data terms OK, keep explanations clear |
|
|
2498
|
+
| `partner` | Mid–high | Precise; balance technical accuracy with clarity |
|
|
2499
|
+
| `administrator` | High | Technical terms OK; reliability, security, compliance, access; be precise |
|
|
2500
|
+
| `dataEngineer` | High | Technical terms OK; pipelines, ingestion, transformation |
|
|
2501
|
+
| `developer` | High | Technical terms OK; APIs, SDKs, integrations; precise and concise |
|
|
2502
|
+
| `aiEngineer` | High | Technical terms OK; ML/AI, models, automation |
|
|
2503
|
+
| `dataScientist` | High | Technical terms OK; experiments, models, analytics |
|
|
2504
|
+
| `securityEngineer` | High | Technical terms OK; IAM, threats, compliance |
|
|
2505
|
+
| `solutionArchitect` | High | Technical terms OK; integration, strategy, best practices |
|
|
2506
|
+
| `internal` | Varies | Can use Cognite-internal jargon; match internal conventions |
|
|
1108
2507
|
|
|
1109
|
-
**
|
|
2508
|
+
**Reading level:** Low = 7th–8th grade; Mid = 9th–10th grade; High = 10th–11th grade.
|
|
1110
2509
|
|
|
1111
|
-
|
|
1112
|
-
- **Must not** use **ordinal** day forms (“1st”, “23rd”) in UI dates.
|
|
1113
|
-
- If numeric dates are required, **should** use **`/`** separators, zero-pad single-digit days/months, and include the year; stay consistent across the feature.
|
|
1114
|
-
- For combined date + time in prose, **should** separate with **“at”** or an unambiguous pattern; **must** keep date and time ordering consistent.
|
|
2510
|
+
When the persona is unknown, default to plain language and outcomes.
|
|
1115
2511
|
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
- **Time range:** same style at start and end; on 12-hour clocks, repeat **AM**/**PM** only when needed for clarity (single meridiem can use one suffix; cross-midnight or long ranges may need both date and meridiem on each end).
|
|
1119
|
-
- **Date range:** consistent formatting; **avoid** dense numeric ranges that are hard to parse.
|
|
1120
|
-
- **Date-time range:** date first, then time; include year unless context suffices; for 12-hour + range, **must** label **AM**/**PM** clearly on both ends when ambiguity is likely.
|
|
1121
|
-
|
|
1122
|
-
**Duration** (elapsed length, not a clock range)
|
|
1123
|
-
|
|
1124
|
-
- **Should** express duration when elapsed length matters more than endpoints.
|
|
1125
|
-
- No “relative” phrasing for duration lists.
|
|
1126
|
-
- **Should** use a **space** between number and unit in body text and tables (`3 seconds`); compact controls may omit the space per component spec.
|
|
1127
|
-
- **Should** avoid commas between compound units (`10 minutes 3 seconds` not `10 minutes, 3 seconds`).
|
|
1128
|
-
- For sub-second precision, **should** use decimals (`2.5 seconds`) or round to a meaningful whole unit to reduce noise.
|
|
1129
|
-
|
|
1130
|
-
**Abbreviations** (lowercase units except proper nouns like **Jan**, **Mon**; no periods on abbreviations)
|
|
1131
|
-
|
|
1132
|
-
| Full (examples) | Abbreviated |
|
|
1133
|
-
| :--- | :--- |
|
|
1134
|
-
| millisecond(s), second(s), minute(s), hour(s) | ms, s, min, hr |
|
|
1135
|
-
| day(s), week(s), month(s), year(s) | d, wk, mo, yr |
|
|
1136
|
-
|
|
1137
|
-
Days and months: **Monday** → **Mon**, **January** → **Jan**, etc.; capitalize; allow width for **four-letter** abbreviations where internationalization may need it.
|
|
2512
|
+
### Voice and tone
|
|
1138
2513
|
|
|
1139
|
-
|
|
2514
|
+
Voice is consistent; tone adapts to the user's emotional state.
|
|
1140
2515
|
|
|
1141
|
-
|
|
2516
|
+
| Scenario | Tone | Example |
|
|
2517
|
+
| ----------------------- | ------------------------- | ------------------------------------------------------------------------------ |
|
|
2518
|
+
| First-time onboarding | Friendly, welcoming | "Let's get started. Your workspace is ready when you are." |
|
|
2519
|
+
| Technical documentation | Clear, direct, supportive | "Configure your endpoint and authenticate using your API key." |
|
|
2520
|
+
| Error messages | Empathetic, constructive | "Something went wrong. Try refreshing, or check your connection." |
|
|
2521
|
+
| Success states | Encouraging, concise | "Your data is now flowing." |
|
|
2522
|
+
| Product tours / help | Conversational, helpful | "Want a quick tour? We'll walk you through the essentials in under 2 minutes." |
|
|
2523
|
+
| High-stakes actions | Serious, transparent | "Delete pipeline? All history will be permanently removed." |
|
|
1142
2524
|
|
|
1143
2525
|
### Grammar and style
|
|
1144
2526
|
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
**Should** prefer **active voice**; use passive only for objectivity or legal emphasis.
|
|
1148
|
-
|
|
1149
|
-
**Numbers:** use **numerals** for all magnitudes in UI (`6 queries per second`, `50 Mbps`). **Should** use a **non-breaking space** between a number and its unit where line breaks would confuse.
|
|
1150
|
-
|
|
1151
|
-
**Abbreviations:** spell out when possible; **avoid** Latin shortcuts (“e.g.”, “etc.”) — use “for example”, “and more”, or recast the sentence.
|
|
2527
|
+
#### Language and capitalization
|
|
1152
2528
|
|
|
1153
|
-
**
|
|
2529
|
+
- **American English**: color, center, organization, modeling
|
|
2530
|
+
- **Sentence case everywhere**: "Create data model" — not "Create Data Model". No exceptions for UI text. Only proper nouns and product names are capitalized: Fusion, OPC-UA, Aura.
|
|
2531
|
+
- **No all-caps**
|
|
2532
|
+
- **No internal codenames** in customer-facing UI copy; use the feature or resource name users recognize.
|
|
1154
2533
|
|
|
1155
|
-
|
|
1156
|
-
- **Must** use periods for **multi-sentence** blocks and dense prose.
|
|
1157
|
-
- **Avoid** exclamation marks in default UI; use **ellipses** sparingly for in-progress or truncated text.
|
|
1158
|
-
- **Should** use the **Oxford comma** in lists.
|
|
1159
|
-
- **Avoid** ampersands (`&`) in translatable UI — use **and**.
|
|
2534
|
+
#### Numbers and units
|
|
1160
2535
|
|
|
1161
|
-
|
|
2536
|
+
- **Numerals for all numbers**, including those under 10: "6 queries", "3 items", "1 result"
|
|
2537
|
+
- Non-breaking space between number and unit: "50 Mbps"
|
|
2538
|
+
- Don't use "(s)" or "(es)" — choose singular or plural based on context
|
|
1162
2539
|
|
|
1163
|
-
|
|
2540
|
+
#### Abbreviations and punctuation
|
|
1164
2541
|
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
2542
|
+
- No Latin abbreviations: use "for example" not "e.g.", "and more" not "etc."
|
|
2543
|
+
- Define acronyms and technical terms when first used (unless writing for technical personas)
|
|
2544
|
+
- No ampersands (&): use "and" — including in headings
|
|
2545
|
+
- **Oxford comma**: "apples, oranges, and pears"
|
|
2546
|
+
- No exclamation marks in UI copy
|
|
2547
|
+
- No period after labels, tooltip text, or single-sentence bulleted list items; use periods for multiple/complex sentences
|
|
2548
|
+
- Ellipsis (…): only for ongoing processes or truncated text — use sparingly
|
|
1168
2549
|
|
|
1169
|
-
|
|
2550
|
+
#### Pronouns
|
|
1170
2551
|
|
|
1171
|
-
|
|
2552
|
+
- Don't mix "my" and "your" in the same context
|
|
2553
|
+
- **"My [resource]"** for app-owned items: "My data", "My assets"
|
|
2554
|
+
- Minimize "I" and "we" representing the application; focus on the user's perspective
|
|
2555
|
+
- Avoid ambiguous pronouns ("this", "that") without an explicit referent — name the thing
|
|
1172
2556
|
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
### Voice and tone
|
|
1176
|
-
|
|
1177
|
-
**Voice** stays consistent; **tone** shifts with context (onboarding vs error vs success).
|
|
1178
|
-
|
|
1179
|
-
**Should** lead with the user’s **intent** and **task**; use **plain**, customer vocabulary; stay **concise** and **scannable** (headings first, steps chunked; prefer visuals over long notes).
|
|
1180
|
-
|
|
1181
|
-
**Should** acknowledge friction honestly where UX is rough; keep disclaimers minimal.
|
|
1182
|
-
|
|
1183
|
-
| Scenario | Tone | Example |
|
|
1184
|
-
| :--- | :--- | :--- |
|
|
1185
|
-
| First-time onboarding | Friendly, welcoming | “Let’s get started — you’re ready when you are.” |
|
|
1186
|
-
| Technical flows | Clear, direct | “Configure your endpoint and authenticate with your API key.” |
|
|
1187
|
-
| Errors | Empathetic, constructive | “Something went wrong. Try refreshing or check your connection.” |
|
|
1188
|
-
| Success | Brief, positive | “Your data is now flowing.” |
|
|
1189
|
-
| Tours / help | Conversational | “Want a quick tour? We’ll cover the essentials in under two minutes.” |
|
|
1190
|
-
|
|
1191
|
-
Align microcopy with the same **product terminology** glossary referenced in **Grammar and style**.
|
|
2557
|
+
### Action labels
|
|
1192
2558
|
|
|
1193
|
-
|
|
2559
|
+
Use sentence case with an object: "Edit model", "Delete asset".
|
|
1194
2560
|
|
|
1195
|
-
|
|
2561
|
+
#### Approved labels
|
|
1196
2562
|
|
|
1197
|
-
|
|
2563
|
+
| Label | Use when |
|
|
2564
|
+
| ------------------ | --------------------------------------------------------------------------- |
|
|
2565
|
+
| Add | Taking an existing object into a new context ("Add to canvas") |
|
|
2566
|
+
| Apply | Setting filtered values that affect subsequent system behavior |
|
|
2567
|
+
| Approve | User agrees; initiates next step in a business process |
|
|
2568
|
+
| Back | Returning to the previous step in a sequence or hierarchy |
|
|
2569
|
+
| Cancel | Stopping the current action or closing a modal — warn of data loss |
|
|
2570
|
+
| Clear | Clearing all fields/selections; restores defaults |
|
|
2571
|
+
| Close | Closing a page, panel, or secondary window — often icon-only |
|
|
2572
|
+
| Copy | Copying an object to the clipboard |
|
|
2573
|
+
| Create | Making a new object from scratch |
|
|
2574
|
+
| Delete | Permanently destroying an object |
|
|
2575
|
+
| Discard | Discarding unsaved changes during create/edit |
|
|
2576
|
+
| Download | Transferring a file from remote to local |
|
|
2577
|
+
| Duplicate | Creating a copy in the same location as the original |
|
|
2578
|
+
| Edit | Changing data/values of an existing object |
|
|
2579
|
+
| Export | Saving data in an external format; typically opens a dialog |
|
|
2580
|
+
| Import | Bringing data from an external source; typically opens a dialog |
|
|
2581
|
+
| Next | Advancing to the next step in a wizard |
|
|
2582
|
+
| Finish | Completing a multi-step wizard |
|
|
2583
|
+
| Open | Opening a drawer, modal, or new page within current context |
|
|
2584
|
+
| Publish | Making content available to intended users |
|
|
2585
|
+
| Refresh | Reloading a view that is out of sync with the source |
|
|
2586
|
+
| Register | Creating a new user account |
|
|
2587
|
+
| Remove | Removing an object from the current context without destroying it |
|
|
2588
|
+
| Reset | Reverting to last saved or default state |
|
|
2589
|
+
| Save | Saving pending changes without closing the window/panel |
|
|
2590
|
+
| Search | Goal-oriented action to find precise information |
|
|
2591
|
+
| Select | Choosing one or more options from a list |
|
|
2592
|
+
| Show / Hide | Revealing or removing an element from view without deleting — use as a pair |
|
|
2593
|
+
| Sign in / Sign out | Entering or exiting the application |
|
|
2594
|
+
| Undo / Redo | Reversing or re-applying the most recent action |
|
|
2595
|
+
| Upload | Transferring a file from local to remote |
|
|
2596
|
+
| View | Presenting additional information or properties for an object |
|
|
2597
|
+
|
|
2598
|
+
#### Labels to avoid
|
|
2599
|
+
|
|
2600
|
+
| Avoid | Use instead | Reason |
|
|
2601
|
+
| --------------------- | ------------------------------------------- | -------------------------------- |
|
|
2602
|
+
| Confirm | The specific action verb ("Delete", "Send") | Too vague |
|
|
2603
|
+
| Log in / Log out | Sign in / Sign out | "Log" is technical jargon |
|
|
2604
|
+
| Sign up | Register | Avoids confusion with "Sign in" |
|
|
2605
|
+
| Submit, OK, Yes | The specific outcome verb | Generic; tell users what happens |
|
|
2606
|
+
| Click here, Read more | Descriptive link text | Inaccessible; not input-agnostic |
|
|
2607
|
+
|
|
2608
|
+
### UI text patterns
|
|
2609
|
+
|
|
2610
|
+
#### Titles
|
|
2611
|
+
|
|
2612
|
+
Noun phrases, sentence case. Examples: "Asset overview", "Pipeline runs", "Configure integration"
|
|
2613
|
+
|
|
2614
|
+
#### Buttons and CTAs
|
|
2615
|
+
|
|
2616
|
+
Active imperative verb + object. 2–4 words target, 6 max. Examples: "Save changes", "Delete pipeline", "View details"
|
|
2617
|
+
|
|
2618
|
+
#### Error messages
|
|
2619
|
+
|
|
2620
|
+
Pattern: `[What failed]. [Why/context if known]. [What to do].`
|
|
2621
|
+
Examples:
|
|
2622
|
+
|
|
2623
|
+
- "Ingestion failed. Check your extractor configuration and try again."
|
|
2624
|
+
- "Couldn't save changes. Connection lost. Reconnect and retry."
|
|
2625
|
+
Avoid: blame language, dead ends with no recovery path
|
|
2626
|
+
|
|
2627
|
+
#### Success messages
|
|
2628
|
+
|
|
2629
|
+
Past tense, specific, brief. Pattern: `[Action] [result]`
|
|
2630
|
+
Avoid "successfully"; that's implied in the pattern
|
|
2631
|
+
Examples: "Changes saved", "Pipeline started", "Integration configured"
|
|
2632
|
+
|
|
2633
|
+
#### Empty states
|
|
2634
|
+
|
|
2635
|
+
Explanation + CTA. Example: "No assets yet. Connect a data source to start exploring."
|
|
2636
|
+
|
|
2637
|
+
#### Tooltips
|
|
2638
|
+
|
|
2639
|
+
One to two sentences, present tense. Pattern: `[What it is]. [What it does or why it matters].`
|
|
2640
|
+
Examples:
|
|
2641
|
+
|
|
2642
|
+
- "Asset ID. The unique identifier for this asset."
|
|
2643
|
+
- "Time granularity. Controls how data points are aggregated in the chart."
|
|
2644
|
+
Never repeat the label. Never write more than 2 sentences.
|
|
2645
|
+
|
|
2646
|
+
#### Confirmation dialogs
|
|
2647
|
+
|
|
2648
|
+
State the consequence, not just the action. Pattern: `[What will be lost or affected]. [Reversibility]. [Specific action].`
|
|
2649
|
+
|
|
2650
|
+
- Primary CTA: match the specific action ("Delete pipeline", not "Confirm")
|
|
2651
|
+
- Secondary CTA: always provide a clear exit ("Cancel")
|
|
2652
|
+
Examples:
|
|
2653
|
+
- "Delete pipeline? All runs and history will be permanently removed. This can't be undone."
|
|
2654
|
+
- "Remove team member? They'll lose access to all shared resources immediately."
|
|
2655
|
+
Avoid: "Are you sure?", manipulative phrasing
|
|
2656
|
+
|
|
2657
|
+
#### Form fields
|
|
2658
|
+
|
|
2659
|
+
- **Labels**: Clear noun phrases ("Time series ID", "Email address")
|
|
2660
|
+
- **Placeholder text**: Use sparingly, only for standard formats like "[name@example.com](mailto:name@example.com)"
|
|
2661
|
+
- **Helper text**: Verb-first; explain why the information is needed
|
|
2662
|
+
|
|
2663
|
+
#### Notifications
|
|
2664
|
+
|
|
2665
|
+
Verb-first title + contextual description. 10–15 words total.
|
|
2666
|
+
Example: "Extractor disconnected. Check your network and reconnect."
|
|
2667
|
+
|
|
2668
|
+
### Accessibility
|
|
2669
|
+
|
|
2670
|
+
- Use **"Select"** not "Click" — input-agnostic: mouse, keyboard, touch, voice
|
|
2671
|
+
- Avoid ambiguous pronouns — screen readers lose surrounding context
|
|
2672
|
+
- Write descriptive link text: "Read pricing details" not "Click here"
|
|
2673
|
+
- Alt text by image type:
|
|
2674
|
+
- Icon → describes function: "Download PDF" not "download icon"
|
|
2675
|
+
- Link image → describes destination: "Contact support" not "question mark"
|
|
2676
|
+
- Chart/diagram → summarizes meaning: "Bar chart showing pipeline throughput declining 20% in Q3"
|
|
2677
|
+
- Decorative image → empty alt text (`alt=""`)
|
|
2678
|
+
- Never write "image of" or "photo of"
|
|
2679
|
+
- For charts and metrics, describe key trends or values in adjacent text — don't rely on visual encoding alone
|
|
2680
|
+
- Target 8–14 words per sentence (8 = 100% comprehension, 14 = 90%)
|
|
2681
|
+
- Pair visual indicators with text: "Error: field required" alongside a red icon
|
|
1198
2682
|
|
|
1199
|
-
|
|
2683
|
+
### Date and time formatting
|
|
1200
2684
|
|
|
1201
|
-
|
|
2685
|
+
- **Prefer written dates**: "2 January 2023" not "02/01/2023"
|
|
2686
|
+
- **Relative vs absolute**: ≤24 h from now → relative ("32 min ago"); >24 h → absolute ("2 Jan 2023")
|
|
2687
|
+
- Always include the year unless obvious from context
|
|
2688
|
+
- No ordinal numbers: "2 January" not "2nd January"
|
|
2689
|
+
- Separate date and time with "at": "2 Jan 2023 at 10:00 AM" — no comma
|
|
2690
|
+
- **12-hour time**: uppercase AM/PM, no periods, space before: "10:00 AM"
|
|
2691
|
+
- **Time zone**: UTC only; spell out "UTC" in text-only contexts
|
|
2692
|
+
- Never make the user convert time zones — handle in code
|
|
2693
|
+
- Ranges: consistent format across start and end; for ongoing processes use absolute start + "ongoing" until complete
|
|
2694
|
+
- Duration: no comma between units ("10 minutes 3 seconds"); space between number and unit in running text ("3 min"); no space in controls ("3min")
|
|
1202
2695
|
|
|
1203
|
-
**
|
|
2696
|
+
**Time unit abbreviations** (no periods; same form singular/plural):
|
|
2697
|
+
ms, s, min, hr, d, wk, mo, yr
|
|
1204
2698
|
|
|
1205
|
-
**
|
|
2699
|
+
**Day abbreviations** (3 chars for i18n):
|
|
2700
|
+
Mon, Tue, Wed, Thu, Fri, Sat, Sun
|
|
1206
2701
|
|
|
1207
|
-
**
|
|
2702
|
+
**Month abbreviations** (4 chars for i18n):
|
|
2703
|
+
Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
|
|
1208
2704
|
|
|
1209
|
-
|
|
2705
|
+
### Localization
|
|
1210
2706
|
|
|
1211
|
-
|
|
2707
|
+
- Keep sentences short with the subject near the start — compound clauses increase translation cost
|
|
2708
|
+
- Maintain consistent terminology and capitalization across strings (critical for translation memory)
|
|
2709
|
+
- No Latin abbreviations in translatable strings: "for example" not "e.g.", "and more" not "etc."
|
|
2710
|
+
- Avoid idioms and cultural references
|
|
2711
|
+
- No ampersands: use "and"
|
|
2712
|
+
- Small words (a, the, that, is): include in prose; may omit only in space-constrained labels and CTAs
|
|
2713
|
+
- Short sentences and simple grammar translate more reliably; plan for text expansion in localized UI (e.g. German often adds 30–40% length) with flexible button and title widths, not fixed ones
|
|
2714
|
+
|
|
2715
|
+
### Benchmarks
|
|
2716
|
+
|
|
2717
|
+
| Element | Target | Maximum |
|
|
2718
|
+
| -------------- | ------------------------ | ------------- |
|
|
2719
|
+
| Buttons / CTAs | 2–4 words | 6 words |
|
|
2720
|
+
| Titles | 3–6 words, 40 characters | — |
|
|
2721
|
+
| Tooltips | 10–20 words | 2 sentences |
|
|
2722
|
+
| Error messages | 12–18 words | — |
|
|
2723
|
+
| Instructions | 14 words | 20 words |
|
|
2724
|
+
| Notifications | 10–15 words total | — |
|
|
2725
|
+
| Line length | 40–60 characters | 70 characters |
|