@apliteni/apliteni-ui 0.93.0 → 0.94.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.
@@ -66,3 +66,5 @@
66
66
  **Do:** Draw inputs with an edge. Keep grey fills for non-text states, such as disabled tracks and dividers.
67
67
 
68
68
  **Don't:** Put text on grey fields, chips, headers or footers.
69
+
70
+ **Except:** The sidebar rail's current row. Its mark may be neither an accent nor an edge — an outline there means focus — and in the page shell the rail is the card surface already. It takes the quiet fill a rung off its rail, label and all. Artur, r34 of [#475](https://github.com/apliteni/apliteni-ui/issues/475).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apliteni/apliteni-ui",
3
- "version": "0.93.0",
3
+ "version": "0.94.0",
4
4
  "workspaces": [
5
5
  "react"
6
6
  ],
@@ -62,11 +62,13 @@
62
62
  .ui-app__rail > .ui-app__head,
63
63
  .ui-app__rail > .ui-app__user,
64
64
  .ui-app__rail > .ui-app__foot { width: var(--ui-nav-col); flex: none; }
65
- /* Hover keeps the reading surface and uses the edge declared in nav.css.
66
- The danger row and the current row are left out by name because this
67
- rule outranks the states nav.css writes for them.
68
- */
69
- .ui-app__rail .ui-nav__item:not(.is-danger):not(.is-active):hover { background: var(--surface); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */ }
65
+ /* The rail is itself --surface, so nav.css's plate has no step here: 1.000:1, with a
66
+ hairline as the whole resting mark. Both marks go a rung further — the current row
67
+ to the --surface-3 the folded rail already paints, a hovered row to half of it, so
68
+ the pointer stays quieter than the reader's own row in both themes (#475 r34). The
69
+ danger and current rows are named out: this rule outranks nav.css's states. */
70
+ .ui-app__rail .ui-nav__item:not(.is-danger):not(.is-active):hover { background: color-mix(in srgb, var(--surface-3) 50%, transparent); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ }
71
+ .ui-app__rail .ui-nav__item.is-active { background: var(--surface-3); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */ }
70
72
  .ui-app__brand {
71
73
  display: flex;
72
74
  align-items: center;
@@ -107,18 +109,18 @@
107
109
  anywhere — so the rail's foot is the account block alone. */
108
110
  .ui-app__rail .ui-nav--side { flex: 1 1 auto; }
109
111
 
110
- /* Which row is current is structural here, not chromatic: the resting glyphs
111
- step down so the current one is the brightest whatever --accent is doing, and
112
- the bar beside it carries the hue. A 3x17px bar on a 45x44 tile was the
113
- smallest of three weak signals doing the most work, so it grows with the row.
114
- The current glyph's own ink is nav.css's rule now, not a copy here: since #429
115
- EVERY rail reads it that way, so the rail's copy was the same sentence in a
116
- second file. What is left here is the rail's own resting step. */
112
+ /* Which row is current is structural here, not chromatic: the resting glyphs step
113
+ down so the current one is the brightest whatever --accent is doing, and the
114
+ plate nav.css draws around it carries no hue at all. #475 took the accent bar
115
+ that used to stand beside the glyph off every rail, so the line that grew it to
116
+ the taller tile here went with it. The current glyph's own ink is nav.css's rule
117
+ too, not a copy here: since #429 EVERY rail reads it that way, so the rail's copy
118
+ was the same sentence in a second file. What is left here is the rail's own
119
+ resting step. */
117
120
  /* Re-tuned at #295, which took the light rail down a step with the page. Below 720px
118
121
  the glyph is the whole row, so it is held at text grade rather than at 1.4.11's bar —
119
- stories/apps/shell-states.test.js:1491 `a resting glyph is dimmer but still legible`. */
122
+ stories/apps/shell-states.test.js:1595 `a resting glyph is dimmer but still legible`. */
120
123
  .ui-app__rail .ui-nav__ic svg { opacity: 0.66; }
121
- .ui-app__rail .ui-nav__item.is-active::before { width: 3px; height: 62%; }
122
124
 
123
125
  /* A destructive row of the rail is a navigation row and rests like one; the danger
124
126
  intent is the step nav.css writes for it. Both of nav.css's danger states are
@@ -277,16 +279,12 @@
277
279
  :where(.ui-app:not(.ui-app--topbar).is-collapsed) .ui-app__brand { opacity: 0; visibility: hidden; pointer-events: none; }
278
280
  :where(.ui-app.is-collapsed) .ui-app__rail .ui-nav__sub { margin-inline-start: 0; padding-inline-start: 0; border-inline-start-width: 0; }
279
281
  :where(.ui-app.is-collapsed) .ui-app__rail .ui-nav__item:not(:has(.ui-nav__ic))::after { opacity: 0.62; }
280
- /* The current row is ONE plate on the glyph column. Same rules as nav.css writes
281
- for a standalone folded rail, and for the same reasons: the bar stands in the
282
- row's own left padding, which on the strip is the rail's edge; the hairline is
283
- drawn on a row that keeps the open column, so its right edge is off the strip;
284
- and --ui-nav-strip is twice the glyph's centre, so a box that wide at the row's
285
- edge is centred on the glyph. why: docs/components.md#the-page-shell */
282
+ /* The current row's plate on the glyph column, and beside it the one thing a bare rail
283
+ does not do: an ordinary row drops its wash here, answered by the floating name below.
284
+ nav.css's folded rules, a rung further. why: docs/components.md#the-page-shell */
286
285
  :where(.ui-app.is-collapsed) .ui-app__rail .ui-nav__item.is-active { isolation: isolate; background: none; }
287
- :where(.ui-app.is-collapsed) .ui-app__rail .ui-nav__item.is-active:not(:focus-visible) { box-shadow: none; }
288
- :where(.ui-app.is-collapsed) .ui-app__rail .ui-nav__item.is-active::before { left: 0; width: var(--ui-nav-strip); height: 100%; border-radius: 10px; background: var(--surface-3); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ z-index: -1; }
289
- :where(.ui-app.is-collapsed) .ui-app__rail .ui-nav__item:hover:not(:focus-visible) { outline: none; }
286
+ :where(.ui-app.is-collapsed) .ui-app__rail .ui-nav__item.is-active::before { content: ""; position: absolute; left: 0; top: 50%; width: var(--ui-nav-strip); height: 100%; border-radius: 10px; transform: translateY(-50%); /* motion: still — a mark on the current row, whose own highlight already transitions; this centres it, it does not travel */ background: var(--surface-3); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ z-index: -1; }
287
+ :where(.ui-app.is-collapsed) .ui-app__rail .ui-nav__item:not(.is-danger):not(.is-active):hover { background: none; }
290
288
  /* The label IS the chip. `fixed` is the fallback placement, out of the rail's own
291
289
  clip; the @supports branch below pins it to the row and is the only one that
292
290
  survives a scroll. The toggle's selector is unscoped, because it is wordless at
@@ -490,9 +488,8 @@
490
488
  .ui-app__rail .ui-nav__sub { margin-inline-start: 0; padding-inline-start: 0; border-inline-start-width: 0; }
491
489
  .ui-app__rail .ui-nav__item:not(:has(.ui-nav__ic))::after { opacity: 0.62; }
492
490
  .ui-app__rail .ui-nav__item.is-active { isolation: isolate; background: none; }
493
- .ui-app__rail .ui-nav__item.is-active:not(:focus-visible) { box-shadow: none; }
494
- .ui-app__rail .ui-nav__item.is-active::before { left: 0; width: var(--ui-nav-strip); height: 100%; border-radius: 10px; background: var(--surface-3); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ z-index: -1; }
495
- .ui-app__rail .ui-nav__item:hover:not(:focus-visible) { outline: none; }
491
+ .ui-app__rail .ui-nav__item.is-active::before { content: ""; position: absolute; left: 0; top: 50%; width: var(--ui-nav-strip); height: 100%; border-radius: 10px; transform: translateY(-50%); /* motion: still — a mark on the current row, whose own highlight already transitions; this centres it, it does not travel */ background: var(--surface-3); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ z-index: -1; }
492
+ .ui-app__rail .ui-nav__item:not(.is-danger):not(.is-active):hover { background: none; }
496
493
  /* The one line of this block that is deliberately NOT the reader's fold: a finger
497
494
  is the only pointer this width has, so a row and the account block are held to
498
495
  44px. Neither floor can spread to the press, where growing the box is the one
@@ -75,34 +75,27 @@
75
75
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
76
76
  }
77
77
  .ui-nav .ui-nav__item { color: var(--text); } /* (0,2,0): a host sheet's a:link is (0,1,1) — why: docs/components.md#the-page-shell */
78
- .ui-nav__item:hover { outline: 1px solid var(--control-edge); outline-offset: -1px; background: var(--surface); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */ color: var(--strong); }
78
+ .ui-nav__item:hover { background: color-mix(in srgb, var(--surface) 50%, transparent); /* ring-gap: inherit — translucent wash retains the opaque containing gap. */ color: var(--strong); }
79
79
  .ui-nav__item.is-active {
80
80
  background: var(--surface); /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */
81
81
  color: var(--strong);
82
82
  font-weight: 500;
83
83
  }
84
- .ui-nav--side .ui-nav__item.is-active {
85
- box-shadow: inset 0 0 0 1px var(--border);
86
- }
87
- /* Accent rail marker on the active item */
88
- .ui-nav--side .ui-nav__item.is-active::before {
89
- content: "";
90
- position: absolute;
91
- left: 4px; top: 50%;
92
- width: 3px; height: 17px;
93
- border-radius: 3px;
94
- background: var(--accent);
95
- transform: translateY(-50%); /* motion: still — a mark on the current row, whose own highlight already transitions; this centres it, it does not travel */
96
- }
84
+ /* The current row's one mark is a plate, and nothing closes it: on a rail row an
85
+ outline means focus and only focus. The plate is the quiet fill a rung off the
86
+ ground the rail stands on, so layout.css takes it the next rung where the rail
87
+ is itself --surface. #475 r33/r34. why: docs/components.md#the-page-shell */
88
+
97
89
  .ui-nav__item:focus-visible { outline: 2px solid transparent; box-shadow: var(--ring); }
98
90
  .ui-nav__item.is-active:focus-visible { outline: 2px solid transparent; box-shadow: var(--ring); }
99
91
 
100
92
  .ui-nav__ic { display: inline-flex; flex: none; }
101
93
  .ui-nav__ic svg { width: 17px; height: 17px; stroke: currentColor; fill: none; stroke-width: 2.2; opacity: 0.72; }
102
- /* The glyph brightens with its row and takes the row's ink, not the accent. One
103
- accent signal per row: that is the marker above, which is the only thing on a
104
- rail that means "here". A glyph in --accent beside it is the same sentence
105
- said twice, and beside an accent counter it was said three times. See #429. */
94
+ /* The glyph brightens with its row and takes the row's ink, not the accent. A
95
+ rail row carries no accent at all since #475: the plate above is what means
96
+ "here", and the glyph's own step to full ink is the other half of that pair.
97
+ A glyph in --accent beside it was the same sentence said twice, and beside an
98
+ accent counter it was said three times. See #429 and #475. */
106
99
  .ui-nav__item.is-active .ui-nav__ic svg,
107
100
  .ui-nav__item.is-current .ui-nav__ic svg { opacity: 1; stroke: currentColor; } /* motion: still — the glyph brightens with its row, whose own highlight already transitions */
108
101
  .ui-nav__label {
@@ -127,12 +120,6 @@
127
120
  background and pull its label toward the rail behind it (#220). */
128
121
  .ui-nav__item.is-disabled { /* muted-ink: state — unavailable control */ color: var(--disabled-ink); cursor: default; pointer-events: none; }
129
122
 
130
- /* Hover adds an edge without changing the current row's reading surface.
131
- The danger row keeps its own state treatment. */
132
- .ui-nav__item.is-active:not(.is-danger):hover {
133
- background: var(--surface); outline: 1px solid var(--control-edge); outline-offset: -1px; /* ring-gap: inherit — control paint; its focus indicator uses the containing surface. */
134
- }
135
-
136
123
  /* Per-item badge / counter */
137
124
  .ui-nav__badge {
138
125
  flex: none;
@@ -160,8 +147,8 @@
160
147
  .ui-nav__item.is-active .ui-nav__badge.is-neutral { background: var(--surface); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */ color: var(--strong); }
161
148
  /* Same shape, one row up: on the current row the accent counter drops both the
162
149
  wash and the accent and reads as the neutral one beside it. The row already
163
- carries the one accent signal it is allowed — the marker — and the count is a
164
- number, not a second answer to "where am I". It also retires the pair #157
150
+ carries the one mark it is allowed — the plate — and the count is a number,
151
+ not a second answer to "where am I". It also retires the pair #157
165
152
  recorded: accent ink on --surface fell under WCAG AA in four of the eight
166
153
  theme x accent cells (4.08 in dark Nebula), and no alpha cleared it. Nothing
167
154
  now paints that pair. See #429 and docs/foundations.md#colour-and-contrast. */
@@ -195,12 +182,10 @@
195
182
  animation: m-slide-down var(--dur-fast) var(--ease-out) both;
196
183
  }
197
184
  .ui-nav__item--sub { font-size: calc(var(--text-base) - 0.5px); padding: 7px 12px; }
198
- /* No hairline on a nested current row — but only at rest. box-shadow carries
199
- both the hairline and the focus ring, so a rule about the resting look must
200
- say so, or it silently cancels the ring (WCAG 2.4.7). */
201
- .ui-nav--side .ui-nav__item--sub.is-active:not(:focus-visible) { box-shadow: none; }
202
- /* Hangs back onto the guide hairline the indent above draws. */
203
- .ui-nav--side .ui-nav__item--sub.is-active::before { left: calc(-1 * var(--space-3)); height: 15px; }
185
+ /* A nested current row takes the plate whole, like a top-level one. It used to
186
+ take neither half — the bar hung back onto the guide hairline and the plate's
187
+ own hairline was switched off so the two would not stack — and a fill with no
188
+ edge is not a mark the kit accepts. See #475. */
204
189
 
205
190
  /* Footer slot (divider + trailing links, e.g. sign-out) */
206
191
  .ui-nav__foot { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); }
@@ -272,27 +257,31 @@
272
257
  /* The current row on a folded rail: one plate on the glyph column, and nothing else.
273
258
  The open rail's 3px marker would stand in the rail's edge at this width, and a
274
259
  nested row would put it outside the rail; the hairline would be the same mark said
275
- twice. The plate is the strip, so it is centred on the glyph, and --surface-3 is the
276
- kit's quiet non-text fill — a step off the rail in both themes. The glyph's own step
277
- from 0.66 to full ink is the second half of that pair. `isolation` is what puts the
278
- plate behind the glyph: a positioned ::before paints over its row's content, and a
279
- negative z-index with no stacking context of its own would drop it behind the rail.
280
- why: #429 */
260
+ twice. The plate is the strip, so it is centred on the glyph, and its fill is the
261
+ rung the open row takes — one off the ground the rail stands on, which layout.css
262
+ takes one further in the shell — so a rail marks the same row with the same
263
+ material at both widths. The glyph's own step from 0.66 to full ink is the second
264
+ half of that pair. `isolation` is what puts the plate behind the glyph: a
265
+ positioned ::before paints over its row's content, and a negative z-index with no
266
+ stacking context of its own would drop it behind the rail.
267
+ why: #429 and #475 */
281
268
  .ui-nav--side.is-collapsed .ui-nav__item.is-active { isolation: isolate; background: none; }
282
- /* At rest only — box-shadow carries the hairline AND the focus ring (WCAG 2.4.7). */
283
- .ui-nav--side.is-collapsed .ui-nav__item.is-active:not(:focus-visible) { box-shadow: none; }
284
269
  .ui-nav--side.is-collapsed .ui-nav__item.is-active::before {
285
- left: 0;
270
+ content: "";
271
+ position: absolute;
272
+ left: 0; top: 50%;
286
273
  width: var(--ui-nav-strip);
287
274
  height: 100%;
288
275
  border-radius: 10px;
289
- background: var(--surface-3); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */
276
+ transform: translateY(-50%); /* motion: still — a mark on the current row, whose own highlight already transitions; this centres it, it does not travel */
277
+ background: var(--surface); /* ring-gap: inherit — decorative or text-only surface has no nested focus target. */
290
278
  z-index: -1;
291
279
  }
292
- /* A folded rail answers a pointer with the row's own ink and the name beside it,
293
- which is the whole readout at this width — the hover wash stands, the edge
294
- around it does not. At rest only, so the focus ring is left standing. */
295
- .ui-nav--side.is-collapsed .ui-nav__item:hover:not(:focus-visible) { outline: none; }
280
+ /* Nothing switches the hover wash off here: since #588 a folded row is only as wide
281
+ as the rail draws, so the wash is the box the plate paints, a rung quieter. It is
282
+ the whole answer a pointer gets outside the shell, where the floating name is
283
+ layout.css's. (The `outline: none` that stood here switched off an edge #475
284
+ removed.) #475 */
296
285
 
297
286
  /* -- Horizontal tabs ----------------------------------------------------- */
298
287
  .ui-nav--tabs {