@apliteni/apliteni-ui 0.73.0 → 0.75.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.
@@ -6,13 +6,11 @@
6
6
 
7
7
  **Rule:** Give every pointer target at least 24x24 CSS px.
8
8
 
9
- **Why:** Larger targets are easier to activate accurately.
9
+ **Do:** The dashed square is the hit area the box declares, not a drawing of one.
10
10
 
11
- **Do:** Use a centred 24x24 `::before` hit area for a 19x19 checkbox.
11
+ **Don't:** The target stops where the 19x19 box stops.
12
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.
13
+ **Except:** WCAG 2.5.8 permits spacing, equivalent controls, inline text, user-agent sizes and essential presentation. An overlay must not reach its neighbours.
16
14
 
17
15
  ## Tap target on a phone
18
16
 
@@ -48,27 +46,23 @@
48
46
 
49
47
  **Rule:** Keep a focus indicator at least 3:1 against every ground it reaches.
50
48
 
51
- **Why:** A solid band remains visible where glow alone may disappear.
52
-
53
- **Do:** Use G2’s solid band with a surface-coloured gap around accent-filled controls.
49
+ **Do:** The solid band, with a surface-coloured gap around an accent-filled control.
54
50
 
55
- **Don't:** Use the halo alone as the focus indicator.
51
+ **Don't:** The halo on its own, with no solid band inside it to measure.
56
52
 
57
- **Except:** The band must reach 4.22:1 on flat ground and 3:1 against actual gap and halo pixels.
53
+ **Except:** The band must clear the bar against the gap and halo pixels too, not only against flat ground.
58
54
 
59
55
  ## Disabled control legibility
60
56
 
61
57
  <!-- rule: disabled-legibility -->
62
58
 
63
- **Rule:** Paint disabled controls with a different ink/surface pair from enabled controls.
59
+ **Rule:** Give a disabled control its own ink and surface pair, and take the accent off it.
64
60
 
65
- **Why:** Opaque colours keep disabled text and surfaces readable.
61
+ **Do:** Unavailable reads as unavailable with the pointer nowhere near it.
66
62
 
67
- **Do:** Use opaque `--disabled-ink`, `--disabled-surface` and `--disabled-border`.
63
+ **Don't:** Unavailable keeps the live paint, so only the cursor reports the state.
68
64
 
69
- **Don't:** Fade the label and box together.
70
-
71
- **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.
65
+ **Except:** A disabled label must stay legible, so the pair changes rather than fades. Only the label-free switch track may fade.
72
66
 
73
67
  ## Touch field text
74
68
 
@@ -76,58 +70,60 @@
76
70
 
77
71
  **Rule:** Set coarse-pointer field text to 16px without scaling it down.
78
72
 
79
- **Why:** iOS Safari zooms fields below 16px and does not zoom out.
73
+ **Why:** iOS Safari zooms into a field under 16px and does not zoom out. There is no specimen pair because the size answers to the pointer rather than the width, so both halves would draw the desktop size.
80
74
 
81
- **Do:** Apply real 16px text to `input`, `select` and `textarea`, including host fields.
75
+ **Do:** Real 16px text in the field itself.
82
76
 
83
- **Don't:** Scale 16px down with transforms or smaller computed text.
77
+ **Don't:** 16px scaled down, or a smaller computed size.
84
78
 
85
- **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.
79
+ **Except:** A host field above 16px keeps its size. Checkbox, radio, range, colour, file and button types do not zoom. Never take pinch-zoom away; the host owns the viewport tag.
86
80
 
87
81
  ## Body contrast
88
82
 
89
83
  <!-- rule: body-contrast -->
90
84
 
91
- **Rule:** Aim for body text contrast close to 7:1, not merely 4.5:1.
85
+ **Rule:** Keep body text close to 7:1 at every size, not merely at 4.5:1.
92
86
 
93
- **Why:** Stronger contrast supports comfortable reading at every size.
87
+ **Why:** Stronger contrast supports comfortable reading at every size. There is no specimen pair because a pale example would break this rule in front of the reader.
94
88
 
95
- **Do:** Use body ink at every size, then vary size, weight or spacing for hierarchy.
89
+ **Do:** Body ink at every size, with size, weight and spacing carrying the hierarchy.
96
90
 
97
- **Don't:** Use pale body ink and rely on larger text for hierarchy.
91
+ **Don't:** Pale ink propped up by larger text.
98
92
 
99
93
  ## Status labels
100
94
 
101
95
  <!-- rule: status-label -->
102
96
 
103
- **Rule:** Show every status with both a mark and a word.
97
+ **Rule:** Name every status in words, not by its colour.
104
98
 
105
99
  **Why:** Colour alone is not reliably distinguishable.
106
100
 
107
- **Do:** Pair a status icon with text such as “Paused.”
101
+ **Do:** The word carries the status; the tone fill agrees with it.
102
+
103
+ **Don't:** A tone fill with the word taken out of it.
108
104
 
109
- **Don't:** Show success using green colour alone.
105
+ **Except:** A status badge needs no glyph or dot. A callout or toast keeps its glyph, because its words sit in a sentence rather than in a fill.
110
106
 
111
107
  ## Measurable pairs
112
108
 
113
109
  <!-- rule: measurable-pair -->
114
110
 
115
- **Rule:** Prefer opaque grounds behind text so contrast can be measured.
111
+ **Rule:** Keep text on opaque grounds so its contrast can be measured.
116
112
 
117
- **Why:** Gradients, filters and translucent layers make contrast uncertain.
113
+ **Why:** A gradient, filter or translucent layer puts the ink on more than one ground, so no single pair can be read off it.
118
114
 
119
- **Do:** Place text on an opaque surface with a measurable ink pair.
115
+ **Do:** One opaque ground under the whole sentence.
120
116
 
121
- **Don't:** Place text over a gradient, filter or translucent layer.
117
+ **Don't:** The same sentence crossing a gradient, where each word sits on a different pair.
122
118
 
123
119
  ## Keyboard first
124
120
 
125
121
  <!-- rule: keyboard-first -->
126
122
 
127
- **Rule:** Implement keyboard behaviour before pointer behaviour and styling.
123
+ **Rule:** Build keyboard behaviour before pointer behaviour and styling.
128
124
 
129
- **Why:** Keyboard access defines the interaction before visual polish.
125
+ **Why:** Keyboard access defines the interaction before visual polish. There is no specimen pair because this is an order of work: both halves look the same once they are finished.
130
126
 
131
- **Do:** Make focus, order and keyboard actions work before styling controls.
127
+ **Do:** Focus, order and keyboard actions working before anything is styled.
132
128
 
133
- **Don't:** Style pointer interactions before implementing keyboard behaviour.
129
+ **Don't:** Pointer styling first and keyboard behaviour afterwards.
@@ -6,6 +6,8 @@
6
6
 
7
7
  **Rule:** Labels, buttons, badges and status text name the field, action or state in a few words.
8
8
 
9
+ **Why:** A control is read in the moment before acting, not studied.
10
+
9
11
  **Do:** “Save invoice.”
10
12
 
11
13
  **Don't:** “Click here to save your invoice.”
@@ -16,6 +18,8 @@
16
18
 
17
19
  **Rule:** Use one sentence for needed units, dates or limits.
18
20
 
21
+ **Why:** The figure above the caption cannot say its unit, its period or what it leaves out.
22
+
19
23
  **Do:** “March revenue in EUR, excluding refunds.”
20
24
 
21
25
  **Don't:** “An overview of your revenue.”
@@ -26,6 +30,8 @@
26
30
 
27
31
  **Rule:** Add a short introduction only for a purpose or step the title and controls leave unclear.
28
32
 
33
+ **Why:** An introduction that repeats the title costs the reader their place on the page.
34
+
29
35
  **Do:** “Upload a CSV with invoice numbers, dates and amounts.”
30
36
 
31
37
  **Don't:** “Manage your invoices here.”
@@ -36,6 +42,8 @@
36
42
 
37
43
  **Rule:** Explain a consequence or next step in one or two sentences.
38
44
 
45
+ **Why:** A callout earns its interruption by naming the consequence and what to do about it.
46
+
39
47
  **Do:** “Deleting this workspace deletes its reports. Export them first.”
40
48
 
41
49
  **Don't:** “Think carefully before proceeding.”
@@ -48,6 +56,8 @@
48
56
 
49
57
  **Rule:** Cut text readers can decide and finish without.
50
58
 
59
+ **Why:** Every spare word is read before it can be discarded.
60
+
51
61
  **Do:** “Exports include only filtered rows.”
52
62
 
53
63
  **Don't:** “Export quickly and easily.”
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apliteni/apliteni-ui",
3
- "version": "0.73.0",
3
+ "version": "0.75.0",
4
4
  "workspaces": [
5
5
  "react"
6
6
  ],
@@ -91,12 +91,21 @@
91
91
  .ui-snippet--reveal .ui-snippet__bar > span { color: var(--chip-success-ink); }
92
92
  .ui-snippet--reveal pre { color: var(--chip-success-ink); word-break: break-all; white-space: pre-wrap; }
93
93
 
94
- /* Inline code */
94
+ /* Inline code. The chip paints whichever reading surface its container is not on, so an
95
+ identifier keeps its chip on the page and inside a card, with no edge of its own. The
96
+ container hands the surface over in --code-bg; see src/tokens/tokens.css. #537
97
+
98
+ The chip READS --code-bg and never declares it, which is why its gap can match its paint
99
+ and its ring is composed here instead of in the shared recipe: a chip that re-pointed the
100
+ hand-off would hand the page to itself and paint the page everywhere. Backticks become a
101
+ chip wherever the kit renders prose (fmt() in site/changelog.mjs), so a link inside one is
102
+ ordinary markup and gets the gap of the surface it is actually on. */
95
103
  .ui-code {
96
104
  font-family: var(--font-mono);
97
105
  font-size: 0.9em;
98
- background: var(--surface); --ring-gap: var(--surface);
106
+ background: var(--code-bg); --ring-gap: var(--code-bg);
99
107
  padding: 2px 6px;
100
108
  border-radius: var(--radius-xs);
101
109
  color: var(--text);
110
+ --ring: 0 0 0 var(--ring-gap-width) var(--ring-gap), 0 0 0 calc(var(--ring-gap-width) + var(--ring-width)) var(--ring-color), 0 0 12px 2px color-mix(in srgb, var(--ring-color) 45%, transparent);
102
111
  }
@@ -123,8 +123,10 @@
123
123
  /* The empty state (.ui-empty) — shown when a table/list has no rows — now
124
124
  lives in styles/empty.css as a standalone component (illustration support). */
125
125
 
126
- /* Tables share their containing card’s reading surface, including pinned cells. */
127
- .ui-card { --table-bg: var(--surface); }
126
+ /* Tables share their containing card’s reading surface, including pinned cells. The code
127
+ chip's hand-off travels with it, so an identifier in a cell keeps the page rather than
128
+ the card the cell is now painted with. why: src/tokens/tokens.css */
129
+ .ui-card { --table-bg: var(--surface); --table-code-bg: var(--bg); }
128
130
 
129
131
  /* White in light, base canvas in dark; never a grey or tinted data surface. */
130
132
  .ui-table { background: var(--table-bg); --ring-gap: var(--table-bg); }
@@ -139,6 +139,16 @@
139
139
  --elev-drop under its inner line. why: docs/specification.md#elevation */
140
140
  --bg: #0e0d14;
141
141
  --table-bg: var(--bg);
142
+ /* A dark table is flush with the page, so the reading surface an inline code chip has
143
+ left inside one is the card. Light's table is white, so there it is the page. */
144
+ --table-code-bg: var(--surface);
145
+ /* A translucent wash paints BEHIND a chip, so it moves the ground and not the chip: the
146
+ pair has to be read against the wash composited over whatever opaque surface is under
147
+ it. Dark's washes lift a near-black ground away from the page, so the page is what the
148
+ chip has left; light's darken white toward the page, so the card is. Both directions
149
+ hold over EVERY opaque ground, which is why this is a token and not a context rule.
150
+ Measured in stories/code-chip.test.js. */
151
+ --wash-code-bg: var(--bg);
142
152
  --surface-2: #161520; /* non-text sunken marks and tracks */
143
153
  --surface: #211e2d; /* the card */
144
154
  --bg-elevated: #2a2639; /* FLOATING — menus, panels, drawer, modal, toasts */
@@ -319,6 +329,8 @@
319
329
  why: docs/specification.md#elevation */
320
330
  --bg: #f2f3f6;
321
331
  --table-bg: #ffffff;
332
+ --table-code-bg: var(--bg);
333
+ --wash-code-bg: var(--surface);
322
334
  --surface-2: #e9ecf3; /* non-text sunken marks and tracks */
323
335
  --surface: #ffffff; /* the card */
324
336
  --bg-elevated: #ffffff; /* FLOATING — menus, panels, drawer, modal, toasts */
@@ -472,9 +484,19 @@
472
484
  --prose-dense: 72ch;
473
485
  }
474
486
 
475
- /* Recompose only at painted containers; controls inherit the outside gap.
476
- * One recipe keeps surface propagation cheap and consistent.
477
- * why: docs/specification.md#the-focus-ring */
487
+ /* An inline code chip is text on a chip, so #455 leaves it two grounds and no grey: the
488
+ * page and the card. It cannot read the one it is on — a var() inside a custom property is
489
+ * substituted on the element that DECLARES it — so the painted container hands it the one
490
+ * it is not using itself, and the chip keeps a step wherever it is written. The page hands
491
+ * over the card below; every painted container hands over the page, in the recipe under it.
492
+ * Held by stories/code-chip.test.js. why: docs/specification.md#elevation */
493
+ :root { --code-bg: var(--surface); }
494
+
495
+ /* Recompose only at painted containers; controls inherit the outside gap, and each hands an
496
+ * inline code chip the page. One recipe keeps surface propagation cheap and consistent.
497
+ * .ui-code composes its own ring in src/styles/code.css instead of joining this list: a
498
+ * chip cannot both paint --code-bg and re-point it, and its gap has to be the surface it
499
+ * actually paints. why: docs/specification.md#the-focus-ring */
478
500
  .amenu,
479
501
  .dtsw,
480
502
  .rx-modal,
@@ -485,7 +507,6 @@
485
507
  .ui-card--accent,
486
508
  .ui-card--live,
487
509
  .ui-cmdk__panel,
488
- .ui-code,
489
510
  .ui-confirm__panel,
490
511
  .ui-drawer__footer,
491
512
  .ui-drawer__panel,
@@ -509,8 +530,38 @@
509
530
  .ui-toast--solid,
510
531
  .vsw__menu {
511
532
  --ring: 0 0 0 var(--ring-gap-width) var(--ring-gap), 0 0 0 calc(var(--ring-gap-width) + var(--ring-width)) var(--ring-color), 0 0 12px 2px color-mix(in srgb, var(--ring-color) 45%, transparent);
533
+ --code-bg: var(--bg);
512
534
  }
513
535
 
536
+ /* The two painted grounds that are not a plain card, and what each has left to hand over.
537
+ *
538
+ * A table paints the page in dark and white in light and follows its card when it is in
539
+ * one, so its hand-off travels with --table-bg as a token pair (src/styles/table.css
540
+ * re-points both). A TINTED surface mixes its colour INTO the card, so the card is the
541
+ * surface it still has: light mixes the tint down from white, which moves a tinted card
542
+ * toward the page and leaves the page 1.02 away, while the card it is a variant of stays
543
+ * 1.07-1.14 off in both themes. Measured in stories/code-chip.test.js. */
544
+ .ui-table,
545
+ .ui-table--sticky thead th,
546
+ .ui-table--pinned .ui-table__identity, .ui-table--pinned .ui-table__selection,
547
+ .ui-table--hover:not(.ui-table--zebra) tbody tr:hover td,
548
+ .ui-table--zebra tbody tr:nth-child(even) td,
549
+ .ui-table--zebra tbody tr:hover td,
550
+ .ui-table--zebra.ui-table--hover tbody tr:hover td { --code-bg: var(--table-code-bg); }
551
+ .ui-card--accent,
552
+ .ui-card--live,
553
+ .ui-snippet--reveal { --code-bg: var(--surface); }
554
+
555
+ /* A wash is not a rung: it is a layer the kit paints OVER one, and it paints behind a chip
556
+ * rather than under it, so the chip's ground moves and the chip does not. These five take
557
+ * caller markup — callout() and the success panel hand their body straight through — so a
558
+ * chip inside one is ordinary product markup rather than a shape anybody hand-places. */
559
+ .ui-callout--info,
560
+ .ui-callout--success,
561
+ .ui-callout--warn,
562
+ .ui-callout--danger,
563
+ .ui-success { --code-bg: var(--wash-code-bg); }
564
+
514
565
  /* A container focused itself paints outside its own surface; descendants only
515
566
  * inherit its inside gap again after focus moves to them. */
516
567
  .ui-card:focus-visible,