@celestia-island/hikari 0.55.318 → 0.55.319

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": "@celestia-island/hikari",
3
- "version": "0.55.318",
3
+ "version": "0.55.319",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Hikari UI library, Vue 3 runtime — one design system for Vue 3 and Rust/WASM applications",
@@ -453,7 +453,13 @@ export default defineComponent({
453
453
  }
454
454
  const band = vp.getBoundingClientRect();
455
455
  const active = pickActiveProgressRoot(band);
456
- const rows = active ? active.root.querySelectorAll(props.scrollProgressSelector) : [];
456
+ // A list may own the row grammar (HkTable's section bands are body
457
+ // `<tr>`s that are not data rows); its `getRows` wins over the
458
+ // container selector. No `getRows` (or an undefined return) keeps the
459
+ // existing selector path byte-for-byte.
460
+ const rows = active
461
+ ? active.handle.getRows?.() ?? active.root.querySelectorAll(props.scrollProgressSelector)
462
+ : [];
457
463
  if (!active || rows.length === 0 || vp.scrollHeight <= vp.clientHeight + 1) {
458
464
  setProgressHidden();
459
465
  return;
@@ -11,6 +11,7 @@ import { createApp, defineComponent, h, inject, nextTick, onMounted, onUnmounted
11
11
 
12
12
  import HkScrollContainer from "./HkScrollContainer";
13
13
  import { HkAdminTablePage } from "./HkAdminTablePage";
14
+ import HTable from "./HkTable";
14
15
  import { HK_SCROLL_PROGRESS_REGISTRAR, type HkScrollProgressRegistrar } from "./HkScrollProgress";
15
16
 
16
17
  const mounts: Array<{ app: ReturnType<typeof createApp>; container: HTMLElement }> = [];
@@ -219,6 +220,24 @@ describe("HkScrollProgress", () => {
219
220
  expect(pill.textContent).toBe("11 / 340");
220
221
  });
221
222
 
223
+ it("counts only a sectioned HkTable's data rows, not its bands", async () => {
224
+ // The band is a `<tr>` in the section body but not a row. The table's
225
+ // handle `getRows` wins over the container's `tbody tr` selector, so
226
+ // the pill reports 2 sections x 2 rows = 4, not 6.
227
+ const sections = [
228
+ { key: "panel-a", label: "Panel A", rows: [{ name: "a0" }, { name: "a1" }] },
229
+ { key: "panel-b", label: "Panel B", rows: [{ name: "b0" }, { name: "b1" }] },
230
+ ];
231
+ const scroller = mountScroller(() =>
232
+ h(HTable, { columns: [{ key: "name", title: "Name" }], sections }),
233
+ );
234
+ stubRootRect(scroller.container, ".hk-table-host", -100, 1900);
235
+ stubRows(scroller.container, 6, 0);
236
+ scroller.refresh();
237
+ await nextTick();
238
+ expect(scroller.pill()!.textContent).toBe("1 / 4");
239
+ });
240
+
222
241
  it("falls back to the DOM row count when the total is absent", async () => {
223
242
  const List = makeList({ rows: ROWS });
224
243
  const scroller = mountScroller(() => h(List));
@@ -24,6 +24,12 @@ import "./HkScrollProgress.scss";
24
24
  export interface HkScrollProgressHandle {
25
25
  getRoot(): HTMLElement | null;
26
26
  getTotal(): number | undefined;
27
+ /** The list's own row elements in display order — wins over the
28
+ * container's `scrollProgressSelector` when present. This is for a
29
+ * list whose DOM rows are not all data rows (HkTable's section bands
30
+ * are `<tr>`s in the body, but they are not rows). Return `undefined`
31
+ * to fall back to the container's selector. */
32
+ getRows?(): readonly Element[] | undefined;
27
33
  }
28
34
 
29
35
  /** Provided by every HkScrollContainer instance whose `scrollProgress`
@@ -95,6 +95,26 @@
95
95
  background: var(--hi-color-bg-subtle, rgba(255, 255, 255, 0.03));
96
96
  }
97
97
 
98
+ /* A section's band is the first child of its body, so the base zebra rule
99
+ would shade each section's FIRST data row (child 2). Restart the phase
100
+ after the band: even data children are unshaded, odd ones carry the
101
+ stripe — the same first-row-unshaded phase an unsectioned body has. */
102
+ .hk-table-striped .hk-table-section-body .hk-table-row:nth-child(even) {
103
+ background: none;
104
+ }
105
+
106
+ .hk-table-striped .hk-table-section-body .hk-table-row:nth-child(odd) {
107
+ background: var(--hi-color-bg-subtle, rgba(255, 255, 255, 0.03));
108
+ }
109
+
110
+ /* The sectioned zebra pair above is (0,4,0) — it would out-specify the
111
+ shared `.hk-table-hover .hk-table-row:hover` rule (0,3,0) and kill hover
112
+ feedback on EVERY row of a striped sectioned table. Keep the pointer
113
+ feedback by re-stating it at a spec that beats the pair. */
114
+ .hk-table-striped.hk-table-hover .hk-table-section-body .hk-table-row:hover {
115
+ background: var(--hi-color-bg-subtle, rgba(255, 255, 255, 0.04));
116
+ }
117
+
98
118
  .hk-table-bordered {
99
119
  border: 1px solid var(--hi-color-border, rgba(100,100,100,0.1));
100
120
  border-radius: var(--radius-md, 8px);
@@ -153,6 +173,51 @@
153
173
  color: var(--hi-color-text-secondary, #666666);
154
174
  }
155
175
 
176
+ /* ── Section bands (grouped tables) ───────────────────────────────────
177
+ One `<tbody>` per section, each led by a band row. The band is a
178
+ rowgroup header, not a data row: it never carries `.hk-table-row`, so
179
+ the copy layer (which marks and cursor-styles cells via
180
+ `[data-copy-cell]`), the hover paint, the striped rule, the drag strip
181
+ and the selection/⋯ tracks all ignore it by construction. The band cell
182
+ carries no `data-copy-cell`, so it needs no copy-cursor override either.
183
+
184
+ The cell itself is TYPE-NEUTRAL for consumer markup: the `section` slot
185
+ carries arbitrary content (badges, panel names, status chips), so only
186
+ the track is styled here (padding / hairline / background / start
187
+ alignment). `font-weight: inherit` neutralizes the UA `th { font-weight:
188
+ bold }`; nothing here sets `white-space` (long panel names may wrap) or
189
+ `cursor` (selectable band text keeps its I-beam). Sizing is delivered by
190
+ the consumer's own classes; the plain `label` fallback gets its own span
191
+ below. The hk-table-sm/lg ladder steps ONLY the band's padding —
192
+ typography deliberately does not scale with the table size, because the
193
+ consumer's slot content owns its type. */
194
+ .hk-table-section-cell {
195
+ padding: var(--space-8, 8px) var(--space-12, 12px);
196
+ border-bottom: 1px solid var(--hi-color-border, rgba(100,100,100,0.08));
197
+ text-align: start;
198
+ background: var(--hi-color-bg-subtle, rgba(255, 255, 255, 0.03));
199
+ font-weight: inherit;
200
+ }
201
+
202
+ /* The default `label` branch only (the `section` slot bypasses this span
203
+ entirely): the previous text-sm / font-medium band look. */
204
+ .hk-table-section-label {
205
+ font-size: var(--text-sm, 0.875rem);
206
+ font-weight: 500;
207
+ }
208
+
209
+ .hk-table-sm .hk-table-section-cell {
210
+ padding: var(--space-4, 4px) var(--space-8, 8px);
211
+ }
212
+
213
+ .hk-table-lg .hk-table-section-cell {
214
+ padding: var(--space-16, 16px) var(--space-24, 24px);
215
+ }
216
+
217
+ .hk-table-bordered .hk-table-section-cell {
218
+ border: 1px solid var(--hi-color-border, rgba(100,100,100,0.06));
219
+ }
220
+
156
221
  /* ── Drag-to-reorder (draggable) ─────────────────────────────────────── */
157
222
 
158
223
  .hk-table-drag-handle {