@apliteni/apliteni-ui 0.37.1 → 0.39.0
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/README.md +5 -2
- package/guidelines/accessibility-floor.md +105 -0
- package/guidelines/colour-and-theming.md +56 -0
- package/guidelines/command-palette.md +79 -0
- package/guidelines/component-choice.md +71 -0
- package/guidelines/dense-tables.md +87 -0
- package/guidelines/destructive-actions.md +43 -0
- package/guidelines/drawer.md +53 -0
- package/guidelines/going-back.md +77 -0
- package/guidelines/hover-readouts.md +67 -0
- package/guidelines/iconography.md +57 -0
- package/guidelines/labels-and-titles.md +79 -0
- package/guidelines/layout-and-density.md +68 -0
- package/guidelines/microcopy.md +29 -0
- package/guidelines/motion.md +53 -0
- package/guidelines/overview.md +1 -0
- package/guidelines/pagination.md +89 -0
- package/guidelines/stat-bands.md +39 -0
- package/guidelines/state-set.md +57 -0
- package/guidelines/the-page.md +123 -0
- package/package.json +3 -1
- package/react/dist/index.d.ts +64 -2
- package/react/dist/index.js +160 -47
- package/src/components/filter-bar.js +56 -0
- package/src/components/index.js +4 -4
- package/src/components/segmented.js +40 -0
- package/src/components/table-values.js +32 -0
- package/src/index.css +1 -0
- package/src/index.js +4 -0
- package/src/inline.js +2 -0
- package/src/styles/filter-bar.css +10 -0
- package/src/styles/segmented.css +7 -0
- package/src/styles/table.css +45 -3
- package/src/tokens/tokens.css +5 -0
package/README.md
CHANGED
|
@@ -31,8 +31,11 @@ factories below. Yes → the [React components](#react-components-stateful-surfa
|
|
|
31
31
|
Either layer follows the same UI rules — what one page may hold, which component to reach
|
|
32
32
|
for, the states it owes, how colour and wording work. They live in the **Guidelines** section
|
|
33
33
|
of Storybook, which opens on
|
|
34
|
-
[
|
|
35
|
-
|
|
34
|
+
[links to every guideline page](https://ui.apli.tech/storybook/?path=/story/guidelines-overview--overview).
|
|
35
|
+
The same guidance ships as plain Markdown in
|
|
36
|
+
`node_modules/@apliteni/apliteni-ui/guidelines/`. Start with
|
|
37
|
+
[guidelines/overview.md](guidelines/overview.md); Storybook reads these documents too.
|
|
38
|
+
|
|
36
39
|
[The page](https://ui.apli.tech/storybook/?path=/story/guidelines-the-page--the-page) is the one
|
|
37
40
|
to read before you design a screen: the limits one page keeps, whatever it is about.
|
|
38
41
|
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Accessibility minimums
|
|
2
|
+
|
|
3
|
+
## Minimum target size
|
|
4
|
+
|
|
5
|
+
<!-- rule: target-size -->
|
|
6
|
+
|
|
7
|
+
**Rule:** Give every pointer target at least 24x24 CSS px.
|
|
8
|
+
|
|
9
|
+
**Why:** Larger targets are easier to activate accurately.
|
|
10
|
+
|
|
11
|
+
**Do:** Use a centred 24x24 `::before` hit area for a 19x19 checkbox.
|
|
12
|
+
|
|
13
|
+
**Don't:** Leave a 19x19 target unchanged.
|
|
14
|
+
|
|
15
|
+
**Except:** WCAG 2.5.8 permits spacing, equivalent controls, inline text, user-agent sizes and essential presentation. Overlays must not reach neighbours.
|
|
16
|
+
|
|
17
|
+
## Focus ring contrast
|
|
18
|
+
|
|
19
|
+
<!-- rule: ring-contrast -->
|
|
20
|
+
|
|
21
|
+
**Rule:** Keep a focus indicator at least 3:1 against every ground it reaches.
|
|
22
|
+
|
|
23
|
+
**Why:** A solid band remains visible where glow alone may disappear.
|
|
24
|
+
|
|
25
|
+
**Do:** Use G2’s solid band with a surface-coloured gap around accent-filled controls.
|
|
26
|
+
|
|
27
|
+
**Don't:** Use the halo alone as the focus indicator.
|
|
28
|
+
|
|
29
|
+
**Except:** The band must reach 4.22:1 on flat ground and 3:1 against actual gap and halo pixels.
|
|
30
|
+
|
|
31
|
+
## Disabled control legibility
|
|
32
|
+
|
|
33
|
+
<!-- rule: disabled-legibility -->
|
|
34
|
+
|
|
35
|
+
**Rule:** Paint disabled controls with a different ink/surface pair from enabled controls.
|
|
36
|
+
|
|
37
|
+
**Why:** Opaque colours keep disabled text and surfaces readable.
|
|
38
|
+
|
|
39
|
+
**Do:** Use opaque `--disabled-ink`, `--disabled-surface` and `--disabled-border`.
|
|
40
|
+
|
|
41
|
+
**Don't:** Fade the label and box together.
|
|
42
|
+
|
|
43
|
+
**Except:** Labels must reach 3:1. Boxless ghosts use `--disabled-ink-bare`, floored at 4.89:1. Disabled controls must look weaker by changing the pair and removing accent. Only the label-free switch track may fade.
|
|
44
|
+
|
|
45
|
+
## Touch field text
|
|
46
|
+
|
|
47
|
+
<!-- rule: touch-field-size -->
|
|
48
|
+
|
|
49
|
+
**Rule:** Set coarse-pointer field text to 16px without scaling it down.
|
|
50
|
+
|
|
51
|
+
**Why:** iOS Safari zooms fields below 16px and does not zoom out.
|
|
52
|
+
|
|
53
|
+
**Do:** Apply real 16px text to `input`, `select` and `textarea`, including host fields.
|
|
54
|
+
|
|
55
|
+
**Don't:** Scale 16px down with transforms or smaller computed text.
|
|
56
|
+
|
|
57
|
+
**Except:** Preserve host fields above 16px with `!important` on a more specific selector. Checkbox, radio, range, colour, file and button types do not zoom. Do not remove pinch-zoom with `user-scalable=no` or `maximum-scale=1`. The host owns the viewport tag.
|
|
58
|
+
|
|
59
|
+
## Body contrast
|
|
60
|
+
|
|
61
|
+
<!-- rule: body-contrast -->
|
|
62
|
+
|
|
63
|
+
**Rule:** Aim for body text contrast close to 7:1, not merely 4.5:1.
|
|
64
|
+
|
|
65
|
+
**Why:** Stronger contrast supports comfortable reading at every size.
|
|
66
|
+
|
|
67
|
+
**Do:** Use body ink at every size, then vary size, weight or spacing for hierarchy.
|
|
68
|
+
|
|
69
|
+
**Don't:** Use pale body ink and rely on larger text for hierarchy.
|
|
70
|
+
|
|
71
|
+
## Status labels
|
|
72
|
+
|
|
73
|
+
<!-- rule: status-label -->
|
|
74
|
+
|
|
75
|
+
**Rule:** Show every status with both a mark and a word.
|
|
76
|
+
|
|
77
|
+
**Why:** Colour alone is not reliably distinguishable.
|
|
78
|
+
|
|
79
|
+
**Do:** Pair a status icon with text such as “Paused.”
|
|
80
|
+
|
|
81
|
+
**Don't:** Show success using green colour alone.
|
|
82
|
+
|
|
83
|
+
## Measurable pairs
|
|
84
|
+
|
|
85
|
+
<!-- rule: measurable-pair -->
|
|
86
|
+
|
|
87
|
+
**Rule:** Prefer opaque grounds behind text so contrast can be measured.
|
|
88
|
+
|
|
89
|
+
**Why:** Gradients, filters and translucent layers make contrast uncertain.
|
|
90
|
+
|
|
91
|
+
**Do:** Place text on an opaque surface with a measurable ink pair.
|
|
92
|
+
|
|
93
|
+
**Don't:** Place text over a gradient, filter or translucent layer.
|
|
94
|
+
|
|
95
|
+
## Keyboard first
|
|
96
|
+
|
|
97
|
+
<!-- rule: keyboard-first -->
|
|
98
|
+
|
|
99
|
+
**Rule:** Implement keyboard behaviour before pointer behaviour and styling.
|
|
100
|
+
|
|
101
|
+
**Why:** Keyboard access defines the interaction before visual polish.
|
|
102
|
+
|
|
103
|
+
**Do:** Make focus, order and keyboard actions work before styling controls.
|
|
104
|
+
|
|
105
|
+
**Don't:** Style pointer interactions before implementing keyboard behaviour.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Colour and theming
|
|
2
|
+
|
|
3
|
+
## Semantic tokens
|
|
4
|
+
|
|
5
|
+
**Rule:** Add and use a semantic colour token before writing a literal.
|
|
6
|
+
|
|
7
|
+
**Why:** Literals cannot follow the theme or accent.
|
|
8
|
+
|
|
9
|
+
**Do:** Use tokens for ground and ink.
|
|
10
|
+
|
|
11
|
+
**Don't:** Freeze colours at dark-theme values.
|
|
12
|
+
|
|
13
|
+
**Except:** Token definitions set the colours; `#000` inside a mask controls alpha, not colour.
|
|
14
|
+
|
|
15
|
+
<!-- rule: tokens -->
|
|
16
|
+
|
|
17
|
+
## Stable signals
|
|
18
|
+
|
|
19
|
+
**Rule:** Let the accent change with a sub-theme, but keep `--pink` and `--green` unchanged.
|
|
20
|
+
|
|
21
|
+
**Why:** If danger followed the accent, revoke and go would look identical.
|
|
22
|
+
|
|
23
|
+
**Do:** Keep error as `--pink` under every accent.
|
|
24
|
+
|
|
25
|
+
**Don't:** Point `--pink` at the accent.
|
|
26
|
+
|
|
27
|
+
**Except:** Across `data-theme`, signals change: light deepens `--pink` from `#e97ca5` to `#b63361` so it reads as ink on white.
|
|
28
|
+
|
|
29
|
+
<!-- rule: signals -->
|
|
30
|
+
|
|
31
|
+
## Accent contrast
|
|
32
|
+
|
|
33
|
+
**Rule:** Use `--accent-strong` for an accent ground and `--accent` for accent ink.
|
|
34
|
+
|
|
35
|
+
**Why:** `--accent` is text on the canvas; its darker sibling, `--accent-strong`, lets white clear AA.
|
|
36
|
+
|
|
37
|
+
**Do:** Use `--accent-strong` behind white text.
|
|
38
|
+
|
|
39
|
+
**Don't:** Use `--accent` as that ground.
|
|
40
|
+
|
|
41
|
+
**Except:** In Phoenix, Ocean and Emerald, both are one token; the difference matters only in Nebula.
|
|
42
|
+
|
|
43
|
+
<!-- rule: accent-strong -->
|
|
44
|
+
|
|
45
|
+
## Theme checks
|
|
46
|
+
|
|
47
|
+
**Rule:** Check dark and light themes and at least two accents before opening a PR.
|
|
48
|
+
|
|
49
|
+
**Why:** A pair that clears AA in dark can fail in light over a card’s wash.
|
|
50
|
+
|
|
51
|
+
**Do:** Test both themes and two accents.
|
|
52
|
+
|
|
53
|
+
**Don't:** Check only dark mode and one accent.
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
<!-- rule: both-themes -->
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# The command palette
|
|
2
|
+
|
|
3
|
+
## Named things
|
|
4
|
+
|
|
5
|
+
<!-- rule: named-things -->
|
|
6
|
+
|
|
7
|
+
**Rule:** Put something in the palette only if a reader can name it.
|
|
8
|
+
|
|
9
|
+
**Why:** Named items are easier to find and understand.
|
|
10
|
+
|
|
11
|
+
**Do:** Include recognisable commands and numbered records that readers can also reach by clicking through the product.
|
|
12
|
+
|
|
13
|
+
**Don't:** Include “Advanced…”, “More”, a frequency option, or a row that opens the current page.
|
|
14
|
+
|
|
15
|
+
**Except:** One-step settings are commands, such as “Switch to the light theme”; settings needing a choice open a named page.
|
|
16
|
+
|
|
17
|
+
## Product-owned groups
|
|
18
|
+
|
|
19
|
+
<!-- rule: groups -->
|
|
20
|
+
|
|
21
|
+
**Rule:** Group results by what they are, using the product’s own word for each group.
|
|
22
|
+
|
|
23
|
+
**Why:** Groups tell readers whether a result opens a record, changes location or runs a command.
|
|
24
|
+
|
|
25
|
+
**Do:** Use three sentence-case headings at the 13px label rank for actions, destinations and recent items.
|
|
26
|
+
|
|
27
|
+
**Don't:** Show nine ungrouped rows that hide whether Enter runs a command, opens an invoice or goes to a page.
|
|
28
|
+
|
|
29
|
+
## Query-based ranking
|
|
30
|
+
|
|
31
|
+
<!-- rule: ranking -->
|
|
32
|
+
|
|
33
|
+
**Rule:** Rank results by how the query matches the name, and let the caller break every tie.
|
|
34
|
+
|
|
35
|
+
**Why:** Caller order keeps preferred commands first, and the kit stores no usage history.
|
|
36
|
+
|
|
37
|
+
**Do:** For “inv”, rank whole-word matches above fragments and names above notes; put the best row’s group first.
|
|
38
|
+
|
|
39
|
+
**Don't:** Put INV-4809 first because of its digits while leaving the matching name “New invoice” last.
|
|
40
|
+
|
|
41
|
+
**Except:** For server results, pass `rank: false` and answer `ui-command-query`; the server ranks the full result, and the kit keeps that order.
|
|
42
|
+
|
|
43
|
+
## Six keyboard keys
|
|
44
|
+
|
|
45
|
+
<!-- rule: keyboard -->
|
|
46
|
+
|
|
47
|
+
**Rule:** Handle Cmd/Ctrl+K, Up, Down, Enter, Escape and Tab, and leave every other key to the text box.
|
|
48
|
+
|
|
49
|
+
**Why:** These keys open, navigate, run, close and contain the palette without changing text-box behavior.
|
|
50
|
+
|
|
51
|
+
**Do:** Wrap arrow navigation, run the active row with Enter, close the top overlay with Escape, and keep focus inside with Tab.
|
|
52
|
+
|
|
53
|
+
**Don't:** Handle Home, End, Ctrl+N/P/J/K or Alt+Arrow; Home and End belong to the caret under ARIA’s combobox pattern.
|
|
54
|
+
|
|
55
|
+
**Except:** Leave Ctrl+K alone inside another text box, where it means kill-to-end-of-line.
|
|
56
|
+
|
|
57
|
+
## Focus and announcements
|
|
58
|
+
|
|
59
|
+
<!-- rule: say-it -->
|
|
60
|
+
|
|
61
|
+
**Rule:** Focus the text box, announce the result count, and return focus afterward.
|
|
62
|
+
|
|
63
|
+
**Why:** `aria-activedescendant` identifies the active row while letters and arrows stay in the text box.
|
|
64
|
+
|
|
65
|
+
**Do:** Announce only the count in a polite live region and restore focus on close, even if the command removed the opener.
|
|
66
|
+
|
|
67
|
+
**Don't:** Move focus to each row or reread every row after each keystroke.
|
|
68
|
+
|
|
69
|
+
## Confirm destructive actions
|
|
70
|
+
|
|
71
|
+
<!-- rule: ask-first -->
|
|
72
|
+
|
|
73
|
+
**Rule:** Never let the palette run a delete by itself.
|
|
74
|
+
|
|
75
|
+
**Why:** A destructive row must be confirmed because readers watch the text box on this fast surface.
|
|
76
|
+
|
|
77
|
+
**Do:** Show an ellipsis and danger ink, and let Enter open a confirm above the palette that answers the first Escape.
|
|
78
|
+
|
|
79
|
+
**Don't:** Omit confirmation; the row becomes disabled and arrow navigation skips it.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Component choice
|
|
2
|
+
|
|
3
|
+
## Interrupt with a question
|
|
4
|
+
|
|
5
|
+
<!-- rule: interrupt -->
|
|
6
|
+
|
|
7
|
+
**Rule:** Stop the page for a question; leave a statement on the page.
|
|
8
|
+
|
|
9
|
+
**Why:** A confirm keeps keyboard focus until answered; a callout does not interrupt.
|
|
10
|
+
|
|
11
|
+
**Except:** Use a drawer when the answer needs a form instead of two buttons.
|
|
12
|
+
|
|
13
|
+
**Do:** The question stops the page.
|
|
14
|
+
|
|
15
|
+
**Don't:** Show the same question with nothing to answer.
|
|
16
|
+
|
|
17
|
+
## Show lasting conditions
|
|
18
|
+
|
|
19
|
+
<!-- rule: transient -->
|
|
20
|
+
|
|
21
|
+
**Rule:** Use a toast for what happened and a callout for what is still true.
|
|
22
|
+
|
|
23
|
+
**Why:** A toast dismisses itself, so an active condition disappears too soon.
|
|
24
|
+
|
|
25
|
+
**Except:** A toast with an action may remain because something happened and can still be answered.
|
|
26
|
+
|
|
27
|
+
**Do:** Keep a standing warning on the page.
|
|
28
|
+
|
|
29
|
+
**Don't:** Let the same warning dismiss itself.
|
|
30
|
+
|
|
31
|
+
## Match controls to panels
|
|
32
|
+
|
|
33
|
+
<!-- rule: panels -->
|
|
34
|
+
|
|
35
|
+
**Rule:** Use tabs() when the control owns a panel and segmented() when it owns nothing.
|
|
36
|
+
|
|
37
|
+
**Why:** A tablist promises a panel and arrow-key support; a strip without either fails the reader.
|
|
38
|
+
|
|
39
|
+
**Except:** Links between locations are neither; the kit’s nav uses aria-current, not a tablist.
|
|
40
|
+
|
|
41
|
+
**Do:** Use a filter strip that owns no panel.
|
|
42
|
+
|
|
43
|
+
**Don't:** Use a tablist that owns no panels.
|
|
44
|
+
|
|
45
|
+
## Match confirmation scale
|
|
46
|
+
|
|
47
|
+
<!-- rule: scale -->
|
|
48
|
+
|
|
49
|
+
**Rule:** Choose the confirmation by how much of the screen it owns.
|
|
50
|
+
|
|
51
|
+
**Why:** successPanel() is a page block; success() is the page and tells the reader where to go next.
|
|
52
|
+
|
|
53
|
+
**Except:** A block that needs somewhere to go next still uses success(); successPanel() takes two strings.
|
|
54
|
+
|
|
55
|
+
**Do:** Use a block confirmation inside the page.
|
|
56
|
+
|
|
57
|
+
**Don't:** Force a page-sized confirmation into a card.
|
|
58
|
+
|
|
59
|
+
## Add dropdown search
|
|
60
|
+
|
|
61
|
+
<!-- rule: dropdown-search -->
|
|
62
|
+
|
|
63
|
+
**Rule:** Give a dropdown a search field at ten options, or whenever its options come from data.
|
|
64
|
+
|
|
65
|
+
**Why:** Ten options require scrolling, and data-fed lists need search at any count; matching anywhere in a label also finds later words.
|
|
66
|
+
|
|
67
|
+
**Except:** Below six options, search adds an unnecessary stop; at six to nine, the author decides, adding search for described rows that scroll from the sixth.
|
|
68
|
+
|
|
69
|
+
**Do:** For twenty-nine currencies, type “dollar” instead of scrolling.
|
|
70
|
+
|
|
71
|
+
**Don't:** Show only seven of twenty-nine currencies without search when dollars are scattered through the list.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Dense tables
|
|
2
|
+
|
|
3
|
+
Keep numbers comparable when the dataset needs many rows and columns.
|
|
4
|
+
|
|
5
|
+
## Use the right surface
|
|
6
|
+
|
|
7
|
+
<!-- rule: surface -->
|
|
8
|
+
|
|
9
|
+
**Why:** Grey or tinted table backgrounds make dense rows harder to separate from the surrounding interface.
|
|
10
|
+
|
|
11
|
+
**Rule:** Put tables on a white surface in light mode and the base canvas in dark mode.
|
|
12
|
+
|
|
13
|
+
**Do:** Use a white surface in light mode and the base canvas in dark mode; let the row edge mark hover.
|
|
14
|
+
|
|
15
|
+
**Don't:** Add a grey zebra or hover fill.
|
|
16
|
+
|
|
17
|
+
## Choose density without shrinking type
|
|
18
|
+
|
|
19
|
+
<!-- rule: density -->
|
|
20
|
+
|
|
21
|
+
**Why:** Compact rows save space without making values harder to read.
|
|
22
|
+
|
|
23
|
+
**Rule:** Choose compact spacing without changing the type size.
|
|
24
|
+
|
|
25
|
+
**Do:** Keep readable values at the small text rank and use compact vertical spacing only when needed.
|
|
26
|
+
|
|
27
|
+
**Don't:** Shrink the type to fit more rows.
|
|
28
|
+
|
|
29
|
+
## Align numeric values
|
|
30
|
+
|
|
31
|
+
<!-- rule: numbers -->
|
|
32
|
+
|
|
33
|
+
**Why:** A shared edge lets readers compare magnitudes quickly.
|
|
34
|
+
|
|
35
|
+
**Rule:** Right-align numeric headers and values.
|
|
36
|
+
|
|
37
|
+
**Do:** Right-align numeric headers and values, use tabular numerals, and keep text left-aligned.
|
|
38
|
+
|
|
39
|
+
**Don't:** Align numbers to their labels or sort formatted strings.
|
|
40
|
+
|
|
41
|
+
## Name the comparison
|
|
42
|
+
|
|
43
|
+
<!-- rule: delta -->
|
|
44
|
+
|
|
45
|
+
**Why:** A sign carries direction without making colour do all the work.
|
|
46
|
+
|
|
47
|
+
**Rule:** Print the sign and name the comparison.
|
|
48
|
+
|
|
49
|
+
**Do:** Print the sign, name the comparison, and let the caller choose whether the change is good or bad.
|
|
50
|
+
|
|
51
|
+
**Don't:** Use colour alone or treat a missing comparison as zero.
|
|
52
|
+
|
|
53
|
+
## Keep units readable
|
|
54
|
+
|
|
55
|
+
<!-- rule: units -->
|
|
56
|
+
|
|
57
|
+
**Why:** Units carry information even when they are secondary to the value.
|
|
58
|
+
|
|
59
|
+
**Rule:** Keep units smaller and in body ink.
|
|
60
|
+
|
|
61
|
+
**Do:** Keep units smaller and in body ink, and explain abbreviations in reachable text.
|
|
62
|
+
|
|
63
|
+
**Don't:** Hide units in muted text or make readers guess what an abbreviation means.
|
|
64
|
+
|
|
65
|
+
## Scroll instead of squeezing
|
|
66
|
+
|
|
67
|
+
<!-- rule: overflow -->
|
|
68
|
+
|
|
69
|
+
**Why:** There is no universal column limit that keeps every dataset readable.
|
|
70
|
+
|
|
71
|
+
**Rule:** Scroll columns instead of squeezing them.
|
|
72
|
+
|
|
73
|
+
**Do:** Use a named keyboard-focusable scroll region with a sticky header and pinned identity column.
|
|
74
|
+
|
|
75
|
+
**Don't:** Squeeze columns until values are unreadable or silently remove data.
|
|
76
|
+
|
|
77
|
+
## Keep updates stable
|
|
78
|
+
|
|
79
|
+
<!-- rule: states -->
|
|
80
|
+
|
|
81
|
+
**Why:** Stable rows and clear states help readers keep their place while results change.
|
|
82
|
+
|
|
83
|
+
**Rule:** Keep the table stable while results update.
|
|
84
|
+
|
|
85
|
+
**Do:** Retain rows while refreshing, report busy state, distinguish no data from no matches and errors, and preserve focus when filters change.
|
|
86
|
+
|
|
87
|
+
**Don't:** Replace the table with a blank state or move focus without telling the reader why.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Destructive actions
|
|
2
|
+
|
|
3
|
+
## Quiet destructive controls
|
|
4
|
+
|
|
5
|
+
<!-- rule: colour -->
|
|
6
|
+
|
|
7
|
+
**Rule:** Keep destructive controls quiet at rest and turn them `--pink` on hover.
|
|
8
|
+
|
|
9
|
+
**Why:** `--accent` makes a destructive control look ordinary.
|
|
10
|
+
|
|
11
|
+
**Except:** `--pink` also marks a seen error, not an impending action.
|
|
12
|
+
|
|
13
|
+
**Do:** Hover makes the danger row `--pink`.
|
|
14
|
+
|
|
15
|
+
**Don't:** Hover repaints the row `--accent`.
|
|
16
|
+
|
|
17
|
+
## Name both actions
|
|
18
|
+
|
|
19
|
+
<!-- rule: wording -->
|
|
20
|
+
|
|
21
|
+
**Rule:** Name the action that destroys and the action that does not.
|
|
22
|
+
|
|
23
|
+
**Why:** “OK” explains nothing; “Revoke access” names the cost.
|
|
24
|
+
|
|
25
|
+
**Except:** Use “Cancel” when there is nothing to keep yet, such as a new form or upload.
|
|
26
|
+
|
|
27
|
+
**Do:** Each label makes sense alone.
|
|
28
|
+
|
|
29
|
+
**Don't:** Use “Are you sure?” without saying what will happen.
|
|
30
|
+
|
|
31
|
+
## Choose confirmation or undo
|
|
32
|
+
|
|
33
|
+
<!-- rule: undo -->
|
|
34
|
+
|
|
35
|
+
**Rule:** Choose confirmation or undo based on reversibility; never use both.
|
|
36
|
+
|
|
37
|
+
**Why:** Confirmation adds a click to undoable actions, while undo is an empty promise for actions that cannot be restored.
|
|
38
|
+
|
|
39
|
+
**Except:** Confirm actions affecting many items: one row is undoable with one click, but a whole selection is not.
|
|
40
|
+
|
|
41
|
+
**Do:** Ask first when nothing can be restored.
|
|
42
|
+
|
|
43
|
+
**Don't:** Offer undo for an already-gone workspace.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Drawers
|
|
2
|
+
|
|
3
|
+
## One-record drawer
|
|
4
|
+
|
|
5
|
+
<!-- rule: one-record -->
|
|
6
|
+
|
|
7
|
+
**Rule:** Open a drawer to view or change one record without leaving its list.
|
|
8
|
+
|
|
9
|
+
**Why:** Closing the drawer returns the user to the opened row.
|
|
10
|
+
|
|
11
|
+
**Do:** Use a drawer for a short filter, a new key, or a reclassification.
|
|
12
|
+
|
|
13
|
+
**Don't:** Use it for work needing an address, multiple screens, or steps; use a page instead.
|
|
14
|
+
|
|
15
|
+
**Except:** Two-answer questions use confirm. Short forms fit; forms needing steps or more than one screen use a page.
|
|
16
|
+
|
|
17
|
+
## Grouped content
|
|
18
|
+
|
|
19
|
+
<!-- rule: no-cards -->
|
|
20
|
+
|
|
21
|
+
**Rule:** Group drawer content under headings and never put a card inside it.
|
|
22
|
+
|
|
23
|
+
**Why:** The drawer already provides the edge and raised surface, so cards add unnecessary boxes.
|
|
24
|
+
|
|
25
|
+
**Do:** Use three groups, with a heading over each group’s rows and one line between groups.
|
|
26
|
+
|
|
27
|
+
**Don't:** Put each group in a card inside the drawer.
|
|
28
|
+
|
|
29
|
+
## Three divider lines
|
|
30
|
+
|
|
31
|
+
<!-- rule: three-lines -->
|
|
32
|
+
|
|
33
|
+
**Rule:** Draw lines under the header, over the footer, and between each group; draw no other lines.
|
|
34
|
+
|
|
35
|
+
**Why:** These lines mark scrolling boundaries and separate groups, not rows.
|
|
36
|
+
|
|
37
|
+
**Do:** Separate header, footer and groups.
|
|
38
|
+
|
|
39
|
+
**Don't:** Add dividers between every row.
|
|
40
|
+
|
|
41
|
+
## Spaced label rows
|
|
42
|
+
|
|
43
|
+
<!-- rule: rows -->
|
|
44
|
+
|
|
45
|
+
**Rule:** Put each value beside its label and separate rows with space.
|
|
46
|
+
|
|
47
|
+
**Why:** In a drawer up to 560px wide, labels and values stay together at any zoom without row lines.
|
|
48
|
+
|
|
49
|
+
**Do:** Place a short value beside its label, such as `Status — Active`.
|
|
50
|
+
|
|
51
|
+
**Don't:** Put the value at the far edge and use row lines to guide the eye back.
|
|
52
|
+
|
|
53
|
+
**Except:** Put figures readers compare down the panel, such as amounts, in a table using `table()` and right-align them.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Going back
|
|
2
|
+
|
|
3
|
+
## Link only for child pages
|
|
4
|
+
|
|
5
|
+
<!-- rule: below-a-list -->
|
|
6
|
+
|
|
7
|
+
**Rule:** Add a back link only when the page is under another page.
|
|
8
|
+
|
|
9
|
+
**Why:** It provides the missing move from a record to its parent list.
|
|
10
|
+
|
|
11
|
+
**Do:** From an invoice record, link to the invoice list.
|
|
12
|
+
|
|
13
|
+
**Don't:** Add one to the Invoices sidebar section; it is not a child page.
|
|
14
|
+
|
|
15
|
+
## Name the destination
|
|
16
|
+
|
|
17
|
+
<!-- rule: name-it -->
|
|
18
|
+
|
|
19
|
+
**Rule:** Name the destination instead of using only “Back”.
|
|
20
|
+
|
|
21
|
+
**Why:** The arrow shows direction, so the words should identify the destination.
|
|
22
|
+
|
|
23
|
+
**Do:** Say “Back to Invoices”, matching the sidebar spelling; hide the arrow from screen readers.
|
|
24
|
+
|
|
25
|
+
**Don't:** Use “Back”, which does not identify the destination in a screen reader’s links list.
|
|
26
|
+
|
|
27
|
+
**Except:** A multi-screen form may use “Back” for the previous step; that is a form button, not this link.
|
|
28
|
+
|
|
29
|
+
## Link to the parent address
|
|
30
|
+
|
|
31
|
+
<!-- rule: address-not-history -->
|
|
32
|
+
|
|
33
|
+
**Rule:** Link to the parent’s address, preserving filters, sort and page; never use history or `javascript:`.
|
|
34
|
+
|
|
35
|
+
**Why:** Addresses work with new tabs, bookmarks and sharing, while browser Back handles history.
|
|
36
|
+
|
|
37
|
+
**Do:** Use `backLink()` with the parent list address and its current state.
|
|
38
|
+
|
|
39
|
+
**Don't:** Use a history link that fails in a new tab or shared address.
|
|
40
|
+
|
|
41
|
+
**Except:** After search or another record, still link to the parent; browser Back returns to the previous location.
|
|
42
|
+
|
|
43
|
+
## Choose one navigation method
|
|
44
|
+
|
|
45
|
+
<!-- rule: one-or-the-other -->
|
|
46
|
+
|
|
47
|
+
**Rule:** Put one back link or trail above the title, never both.
|
|
48
|
+
|
|
49
|
+
**Why:** A trail shows several levels; a back link shows one step, and `appShell()` draws only the link when both are provided.
|
|
50
|
+
|
|
51
|
+
**Do:** Align the single line above the title.
|
|
52
|
+
|
|
53
|
+
**Don't:** Repeat the hierarchy with both; the current page is then named three times.
|
|
54
|
+
|
|
55
|
+
## Keep the section active
|
|
56
|
+
|
|
57
|
+
<!-- rule: section-lit -->
|
|
58
|
+
|
|
59
|
+
**Rule:** Keep the parent section active with `aria-current="true"`, not `"page"`, and use its name in the link.
|
|
60
|
+
|
|
61
|
+
**Why:** The record remains in its list’s section without making the list seem like the current page; `appShell()` does this when given a back link.
|
|
62
|
+
|
|
63
|
+
**Do:** Keep the sidebar row active and say “Back to Invoices”.
|
|
64
|
+
|
|
65
|
+
**Don't:** Leave the section inactive or give it another name.
|
|
66
|
+
|
|
67
|
+
## Keep the link quiet
|
|
68
|
+
|
|
69
|
+
<!-- rule: quiet -->
|
|
70
|
+
|
|
71
|
+
**Rule:** Style the back link as secondary navigation, using `--text` despite host link colours.
|
|
72
|
+
|
|
73
|
+
**Why:** It appears on every record page and must not compete with the title or main action.
|
|
74
|
+
|
|
75
|
+
**Do:** Use body ink, no box until pointer hover, and a size smaller than the title.
|
|
76
|
+
|
|
77
|
+
**Don't:** Use two filled buttons or make leaving the record more prominent than its main action.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Hover readouts
|
|
2
|
+
|
|
3
|
+
## Keep readouts over the page
|
|
4
|
+
|
|
5
|
+
<!-- rule: overlay -->
|
|
6
|
+
|
|
7
|
+
**Rule:** Show hover values beside their marks, never inside page layout.
|
|
8
|
+
|
|
9
|
+
**Why:** A changing readout must not move the page.
|
|
10
|
+
|
|
11
|
+
**Do:** Float the value beside a chart point, sparkline, heatmap cell, or truncated cell.
|
|
12
|
+
|
|
13
|
+
**Don't:** Add a value line that grows the card and pushes content down.
|
|
14
|
+
|
|
15
|
+
## Prefer above the mark
|
|
16
|
+
|
|
17
|
+
<!-- rule: above-the-mark -->
|
|
18
|
+
|
|
19
|
+
**Rule:** Open the readout above the mark; place it below only when space above is clipped and below has more room.
|
|
20
|
+
|
|
21
|
+
**Why:** This keeps the mark and pointer approach clear while keeping the readout on-screen.
|
|
22
|
+
|
|
23
|
+
**Do:** Open a readout below a tall bar near the top of a clipping region.
|
|
24
|
+
|
|
25
|
+
**Don't:** Force it above until the month and value are clipped.
|
|
26
|
+
|
|
27
|
+
## Give one useful comparison
|
|
28
|
+
|
|
29
|
+
<!-- rule: contents -->
|
|
30
|
+
|
|
31
|
+
**Rule:** Name the point, show its value, and include no more than one comparison.
|
|
32
|
+
|
|
33
|
+
**Why:** Short readouts stay readable and do not cover nearby marks.
|
|
34
|
+
|
|
35
|
+
**Do:** Use three short lines: point, value, one comparison.
|
|
36
|
+
|
|
37
|
+
**Don't:** Wrap long text or place controls in the readout.
|
|
38
|
+
|
|
39
|
+
**Except:** Match the page’s currency and precision.
|
|
40
|
+
|
|
41
|
+
## Tap to open or close
|
|
42
|
+
|
|
43
|
+
<!-- rule: on-touch -->
|
|
44
|
+
|
|
45
|
+
**Rule:** On touch screens, tap a mark to open the readout and tap again to move or close it.
|
|
46
|
+
|
|
47
|
+
**Why:** Hover is not readable under a finger.
|
|
48
|
+
|
|
49
|
+
**Do:** Tap another mark to move the readout, or tap the same mark or anywhere else to close it.
|
|
50
|
+
|
|
51
|
+
**Don't:** Require a hover gesture on a touch screen.
|
|
52
|
+
|
|
53
|
+
**Except:** The opening tap blocks the mark’s click but still reaches page listeners; the tap that closes the readout may also drill down.
|
|
54
|
+
|
|
55
|
+
## Provide another access method
|
|
56
|
+
|
|
57
|
+
<!-- rule: not-only-hover -->
|
|
58
|
+
|
|
59
|
+
**Rule:** Never make hover the only way to reach a value.
|
|
60
|
+
|
|
61
|
+
**Why:** Pointer, focus, and tap must all support access, and Escape must dismiss the readout.
|
|
62
|
+
|
|
63
|
+
**Do:** Let focus or tap open the readout, and provide the leading figure plus a table or labelled series summary.
|
|
64
|
+
|
|
65
|
+
**Don't:** Require pointing at one of 365 daily points to find its value.
|
|
66
|
+
|
|
67
|
+
**Except:** Touch-screen focus without a tap must support screen-reader arrival; pointer detection must support laptop mouse hover, finger or pen tap, and keyboard focus restoration. Whether chart marks should be tab stops remains undecided; the kit adds none.
|