@apliteni/apliteni-ui 0.126.0 → 0.127.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apliteni/apliteni-ui",
3
- "version": "0.126.0",
3
+ "version": "0.127.0",
4
4
  "workspaces": [
5
5
  "react"
6
6
  ],
@@ -49,6 +49,7 @@
49
49
  height: min(max(100%, var(--tap-min)), calc(100% + var(--tap-clear-y)));
50
50
  }
51
51
  .ui-check input::before,
52
+ .ui-table__selection input[type=checkbox]::before,
52
53
  .ui-toast__close::before {
53
54
  width: max(var(--tap-aa), min(max(100%, var(--tap-min)), calc(100% + var(--tap-clear-x))));
54
55
  height: max(var(--tap-aa), min(max(100%, var(--tap-min)), calc(100% + var(--tap-clear-y))));
@@ -102,6 +103,14 @@
102
103
  --tap-clear-x: var(--tap-gap);
103
104
  --tap-clear-y: 0px;
104
105
  }
106
+ .ui-table__selection {
107
+ --tap-clear-x: var(--tap-min);
108
+ --tap-clear-y: var(--tap-min);
109
+ }
110
+ .ui-table--dense .ui-table__selection,
111
+ .ui-table--compact .ui-table__selection {
112
+ --tap-clear-y: 0px;
113
+ }
105
114
  .ui-toast {
106
115
  row-gap: var(--tap-gap) !important;
107
116
  --tap-clear-y: var(--tap-gap);
@@ -1420,6 +1420,7 @@ function DataTable({
1420
1420
  }
1421
1421
  );
1422
1422
  const pageAllOn = selectable && slice.length > 0 && slice.every((r) => selected.has(r.name));
1423
+ const pageSomeOn = selectable && !pageAllOn && slice.some((r) => selected.has(r.name));
1423
1424
  return /* @__PURE__ */ jsxs13(Fragment4, { children: [
1424
1425
  /* @__PURE__ */ jsx17(
1425
1426
  "div",
@@ -1442,6 +1443,9 @@ function DataTable({
1442
1443
  type: "checkbox",
1443
1444
  checked: pageAllOn,
1444
1445
  "aria-label": "Select all rows on this page",
1446
+ ref: (input) => {
1447
+ if (input) input.indeterminate = pageSomeOn;
1448
+ },
1445
1449
  onChange: () => onTogglePage(slice.map((r) => r.name))
1446
1450
  }
1447
1451
  ) }) : null,
@@ -123,7 +123,9 @@
123
123
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%235c6270' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
124
124
  }
125
125
 
126
- /* Checkbox / radio — custom, token-driven */
126
+ /* Checkbox / radio — custom, token-driven. DataTable's selection boxes are bare
127
+ inputs in a cell with no label, and take the same box so a partial page reads in
128
+ the kit's paint rather than the browser's. #619 */
127
129
  .ui-check {
128
130
  display: inline-flex;
129
131
  align-items: flex-start;
@@ -133,7 +135,8 @@
133
135
  color: var(--text);
134
136
  line-height: 1.5;
135
137
  }
136
- .ui-check input {
138
+ .ui-check input,
139
+ .ui-table__selection input[type="checkbox"] {
137
140
  appearance: none;
138
141
  width: 19px;
139
142
  height: 19px;
@@ -146,6 +149,9 @@
146
149
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
147
150
  position: relative;
148
151
  }
152
+ /* In a cell there is no label line to sit beside, so the box centres on the row's
153
+ text instead of dropping 1px to meet a label's first line. */
154
+ .ui-table__selection input[type="checkbox"] { margin-top: 0; vertical-align: middle; }
149
155
  /* The target, not the ink. The box above is drawn at 19x19 because that is what
150
156
  sits beside a 15px label without shouting; WCAG 2.5.8 wants 24 CSS px of
151
157
  pointer target, which is a different question. This overlay answers it and
@@ -155,7 +161,8 @@
155
161
  inside the same <label> (which toggles the same input, so an overlap there
156
162
  would cost nothing) and 14px between stacked rows in the specimen. Measured
157
163
  in stories/guidelines/accessibility-floor.test.js. #219 */
158
- .ui-check input::before {
164
+ .ui-check input::before,
165
+ .ui-table__selection input[type="checkbox"]::before {
159
166
  content: '';
160
167
  position: absolute;
161
168
  left: 50%;
@@ -171,9 +178,12 @@
171
178
  accent band is the second band #578 round r34 took off the focus rules, and a
172
179
  pointer resting on a focused control would put it back. One indicator, which is
173
180
  what the kit's rows already chose. why: docs/foundations.md#the-focus-ring */
174
- .ui-check input:enabled:hover:not(:focus-visible) { border-color: var(--accent); }
175
- .ui-check input:checked { background: var(--accent); border-color: var(--accent); }
176
- .ui-check input[type="checkbox"]:checked::after {
181
+ .ui-check input:enabled:hover:not(:focus-visible),
182
+ .ui-table__selection input[type="checkbox"]:enabled:hover:not(:focus-visible) { border-color: var(--accent); }
183
+ .ui-check input:checked,
184
+ .ui-table__selection input[type="checkbox"]:checked { background: var(--accent); border-color: var(--accent); }
185
+ .ui-check input[type="checkbox"]:checked::after,
186
+ .ui-table__selection input[type="checkbox"]:checked::after {
177
187
  content: "";
178
188
  position: absolute;
179
189
  left: 5px; top: 1.5px;
@@ -199,14 +209,59 @@
199
209
  ground together. A checked box drops the accent for the reason a disabled primary
200
210
  button does: the accent IS the "press me". Its mark inverts to --disabled-surface,
201
211
  so the tick and the dot keep the measured --disabled-ink pair in both themes. */
202
- .ui-check input:disabled {
212
+ .ui-check input:disabled,
213
+ .ui-table__selection input[type="checkbox"]:disabled {
203
214
  background: var(--disabled-surface); /* code-bg: inherit — control paint; the containing surface is the ground, for a chip and for a band alike. */
204
215
  border-color: var(--disabled-border);
205
216
  cursor: not-allowed;
206
217
  }
207
- .ui-check input:disabled:checked { background: var(--disabled-ink); border-color: var(--disabled-ink); }
208
- .ui-check input[type="checkbox"]:disabled:checked::after { border-color: var(--disabled-surface); }
218
+ .ui-check input:disabled:checked,
219
+ .ui-table__selection input[type="checkbox"]:disabled:checked { background: var(--disabled-ink); border-color: var(--disabled-ink); }
220
+ .ui-check input[type="checkbox"]:disabled:checked::after,
221
+ .ui-table__selection input[type="checkbox"]:disabled:checked::after { border-color: var(--disabled-surface); }
209
222
  .ui-check input[type="radio"]:disabled:checked::after { background: var(--disabled-surface); /* code-bg: inherit — the mark inside the box; the box carries the focus indicator. */ }
223
+ /* Partial: some of a group is on, not all. The checked box's fill with a level
224
+ dash where the tick would be, so the box still reads as "on" from across a table
225
+ and the dash alone says "not all". It wins over a tick when both are set, as the
226
+ browser's own box does. Drawn with a border, not a background, so forced colours
227
+ keeps the dash. #619 */
228
+ .ui-check input[type="checkbox"]:indeterminate,
229
+ .ui-table__selection input[type="checkbox"]:indeterminate { background: var(--accent); border-color: var(--accent); }
230
+ .ui-check input[type="checkbox"]:indeterminate::after,
231
+ .ui-table__selection input[type="checkbox"]:indeterminate::after {
232
+ content: "";
233
+ position: absolute;
234
+ inset: 0;
235
+ margin: auto;
236
+ width: 11px; height: 0; /* odd, so the 17px padding box splits into equal gaps */
237
+ border: solid var(--accent-contrast);
238
+ border-width: 2px 0 0;
239
+ transform: none;
240
+ }
241
+ /* White ink falls below 3:1 on the lighter dark-theme accents, so the tick, the dash and
242
+ the radio's dot take the ink a selected Segmented pill takes there. */
243
+ :where(:root[data-theme="dark"]) .ui-check input[type="checkbox"]:enabled:is(:checked, :indeterminate)::after,
244
+ :where(:root[data-theme="dark"]) .ui-table__selection input[type="checkbox"]:enabled:is(:checked, :indeterminate)::after { border-color: var(--signal-contrast); }
245
+ :where(:root[data-theme="dark"]) .ui-check input[type="radio"]:enabled:checked::after { background: var(--signal-contrast); }
246
+ .ui-check input[type="checkbox"]:disabled:indeterminate,
247
+ .ui-table__selection input[type="checkbox"]:disabled:indeterminate { background: var(--disabled-ink); border-color: var(--disabled-ink); }
248
+ .ui-check input[type="checkbox"]:disabled:indeterminate::after,
249
+ .ui-table__selection input[type="checkbox"]:disabled:indeterminate::after { border-color: var(--disabled-surface); }
250
+ /* Forced colours replace every fill, so a disabled box that painted only a fill and
251
+ a --disabled-* edge drew the same edge and mark as an enabled one, and a radio's dot
252
+ vanished. GrayText is the system colour for an unavailable control. The tick and the
253
+ dash are borders, so they keep it; the dot is a fill, so it names a system colour. */
254
+ @media (forced-colors: active) {
255
+ .ui-check input:disabled,
256
+ .ui-check input:disabled:is(:checked, :indeterminate),
257
+ .ui-check input[type="checkbox"]:disabled:is(:checked, :indeterminate),
258
+ .ui-table__selection input[type="checkbox"]:disabled,
259
+ .ui-table__selection input[type="checkbox"]:disabled:is(:checked, :indeterminate) { border-color: GrayText; }
260
+ .ui-check input[type="checkbox"]:disabled:is(:checked, :indeterminate)::after,
261
+ .ui-table__selection input[type="checkbox"]:disabled:is(:checked, :indeterminate)::after { border-color: GrayText; }
262
+ .ui-check input[type="radio"]:enabled:checked::after { background: CanvasText; }
263
+ .ui-check input[type="radio"]:disabled:checked::after { background: GrayText; }
264
+ }
210
265
  /* The label is the click target, so the cursor belongs on it, and the words it
211
266
  holds go quiet with the box beside them. */
212
267
  .ui-check:has(input:disabled) { /* muted-ink: state — unavailable control */ color: var(--disabled-ink); cursor: not-allowed; }
@@ -467,6 +467,9 @@ a.ui-identity:hover { text-decoration: underline; }
467
467
  .ui-table--pinned .ui-identity__name { min-width: 0; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
468
468
  }
469
469
 
470
+ /* Automatic layout hands every column a share of the free width, and a box is not worth one: the selection column takes the width of its box and the gap after it. The pinned table below fixes it instead. */
471
+ .ui-table .ui-table__selection { width: 1%; }
472
+
470
473
  /* One width reserves the selection track and offsets the adjacent identity. */
471
474
  .ui-table--pinned { --ui-table-selection-width: var(--space-12); --ui-table-identity-max: min(var(--panel-sm), 50vw); }
472
475
  .ui-table--pinned .ui-table__selection { box-sizing: border-box; width: var(--ui-table-selection-width); min-width: var(--ui-table-selection-width); max-width: var(--ui-table-selection-width); padding-inline: 0; text-align: center; }
@@ -96,6 +96,7 @@
96
96
  with a 1.5px border, so without it the clamp takes this layer DOWN to 22
97
97
  and under the kit's own minimum. */
98
98
  .ui-check input::before,
99
+ .ui-table__selection input[type="checkbox"]::before,
99
100
  .ui-toast__close::before {
100
101
  width: max(var(--tap-aa), min(max(100%, var(--tap-min)), calc(100% + var(--tap-clear-x))));
101
102
  height: max(var(--tap-aa), min(max(100%, var(--tap-min)), calc(100% + var(--tap-clear-y))));
@@ -168,6 +169,12 @@
168
169
  }
169
170
  .ui-table__act { --tap-clear-x: var(--tap-gap); --tap-clear-y: 0px; }
170
171
 
172
+ /* The selection box is 19px in a 58px row and a 34px header: the layer has room to reach the floor both ways. */
173
+ .ui-table__selection { --tap-clear-x: var(--tap-min); --tap-clear-y: var(--tap-min); }
174
+ /* A dense or compact table's rows are 33px to 40px apart and share an edge, so a layer that grows down takes the pixels nearest the next row's box. Those rows keep the 24px floor. */
175
+ .ui-table--dense .ui-table__selection,
176
+ .ui-table--compact .ui-table__selection { --tap-clear-y: 0px; }
177
+
171
178
  /* Down only, like the nine rows below: a toast is a full row at this width,
172
179
  and opening it across took 24px out of the message for no reach at all —
173
180
  its action already clears the floor on the vertical half. The box does not