@celestia-island/hikari 0.55.69 → 0.55.70

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.69",
3
+ "version": "0.55.70",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Hikari Vue 3 component library — production-grade UI components based on shittim-chest design system",
@@ -32,7 +32,22 @@
32
32
  --hk-stepflow-sticky-bg,
33
33
  color-mix(in srgb, var(--hi-color-surface, #f0f4f8) 95%, transparent)
34
34
  );
35
- top: var(--hk-stepflow-sticky-top, 0px);
35
+ // The HOST's declared gutter owns the resting offset, not this rule. The
36
+ // pin contract's offset rule is (0,3,0) and parks a top pin at
37
+ // var(--hk-scroll-pad-top, 0px); this rule is (0,4,0), so a bare `0px`
38
+ // default silently out-specified it and parked the stuck pin flush
39
+ // against the scrollport edge instead of at the gutter line. The
40
+ // window-mode bonds sit 11-13px below the pin's top, so they landed
41
+ // INSIDE the host's own gutter cover (HkModal paints
42
+ // `.hk-modal-body::before` there at z-index 3), leaving their visibility
43
+ // resting entirely on the pin's z-index 10 staying inside that cover's
44
+ // stacking context. Any promoted wrapper between the scroll host and the
45
+ // pin collapses that: the bond measures 0 % under an opaque cover and
46
+ // exactly 5.0 % under a 95 % one — the round-24 phone signature
47
+ // (左中右三段式的步骤左右没有横线). Deferring to the gutter moves the
48
+ // bond to pad+11, clear of the cover band, and keeps a consumer's own
49
+ // override working through --hk-stepflow-sticky-top.
50
+ top: var(--hk-stepflow-sticky-top, var(--hk-scroll-pad-top, 0px));
36
51
  margin-bottom: 0;
37
52
  padding-bottom: var(--hk-stepflow-header-gap, var(--space-16, 1rem));
38
53
  }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Source contract for the window-mode bond's visibility.
3
+ *
4
+ * Round-24 chest report: 左中右三段式的步骤左右没有横线 — the provider wizard's
5
+ * step indicator rendered its three cells but neither the completed bond,
6
+ * the pending bond, nor the edge continuations read as lines. Two
7
+ * independent causes, both measured on a real engine, both pinned here:
8
+ *
9
+ * 1. The stuck pin ignored the host's declared gutter. The step-flow's
10
+ * sticky rule is (0,4,0) and the pin contract's offset rule is
11
+ * (0,3,0), so a bare `0px` default out-specified the contract and
12
+ * parked the pin flush against the scrollport edge. The window-mode
13
+ * bonds sit 11-13px below the pin's top and therefore landed inside
14
+ * HkModal's own gutter cover (`.hk-modal-body::before`, z-index 3),
15
+ * which left their visibility resting entirely on the pin's z-index
16
+ * beating that cover. One promoted wrapper between the scroll host
17
+ * and the pin collapses it: the bond then measures 0 % under an
18
+ * opaque cover and exactly 5.0 % under a 95 % one.
19
+ * 2. The pending bond derived its colour from `--hi-color-border`, which
20
+ * the shipped schemes define WITH alpha (rgb(128 128 128 / 15%)), so
21
+ * the bond computed to 15 % × 30 % = 4.5 % — and a 2px line at 4.5 %
22
+ * is not a line.
23
+ *
24
+ * Both are pure stylesheet facts, which is why they are asserted against
25
+ * the source: jsdom runs no cascade, and the failure only shows up as
26
+ * pixels. The geometry half of the same investigation (the containing
27
+ * block is correct — the overlay anchors to the sticky timeline) needs no
28
+ * assertion; it was never wrong.
29
+ */
30
+ import { describe, expect, it } from "vitest";
31
+ import { readFileSync } from "node:fs";
32
+ import { dirname, join } from "node:path";
33
+ import { fileURLToPath } from "node:url";
34
+
35
+ const here = dirname(fileURLToPath(import.meta.url));
36
+ const read = (name: string): string => readFileSync(join(here, name), "utf-8");
37
+
38
+ const stepflow = read("HkStepFlow.scss");
39
+ const timeline = read("HkTimeline.scss");
40
+ const scrollpin = read("HkScrollPin.scss");
41
+
42
+ /** The declaration block of the first rule whose selector starts at `from`. */
43
+ function blockAfter(source: string, from: number): string {
44
+ const end = source.indexOf("}", from);
45
+ return end < 0 ? source.slice(from) : source.slice(from, end);
46
+ }
47
+
48
+ describe("window-mode bond visibility contract", () => {
49
+ it("keeps the pin contract's gutter as the sticky step-flow header's default offset", () => {
50
+ // The pin contract still declares the gutter for an offset top pin...
51
+ expect(scrollpin).toContain("top: var(--hk-scroll-pad-top, 0px)");
52
+
53
+ // ...and the step-flow override DEFERS to it instead of replacing it
54
+ // with 0. Losing this is silent: the pin still pins, the cells still
55
+ // render, only the bonds fall under the host's gutter cover.
56
+ const at = stepflow.indexOf(
57
+ ".hk-step-flow[data-sticky-header] > .hk-timeline.hk-scroll-pin",
58
+ );
59
+ expect(at).toBeGreaterThan(-1);
60
+ const block = blockAfter(stepflow, at);
61
+ expect(block).toContain(
62
+ "top: var(--hk-stepflow-sticky-top, var(--hk-scroll-pad-top, 0px));",
63
+ );
64
+ // The old bare default must not come back.
65
+ expect(block).not.toContain("top: var(--hk-stepflow-sticky-top, 0px);");
66
+ });
67
+
68
+ it("derives the pending bond from an opaque tone so its alpha is not multiplied", () => {
69
+ const at = timeline.indexOf('&[data-status="pending"]');
70
+ expect(at).toBeGreaterThan(-1);
71
+ const block = blockAfter(timeline, at);
72
+ expect(block).toContain("--_link-color:");
73
+ expect(block).toContain("var(--hi-color-muted");
74
+ // Deriving from the border token multiplied its own alpha.
75
+ expect(block).not.toContain("var(--hi-color-border)");
76
+ });
77
+
78
+ it("carries both bonds as real boxes on the shared node geometry", () => {
79
+ // The segments are positioned off the shared tokens, so a bond can only
80
+ // be invisible through colour or occlusion — never through zero size.
81
+ expect(timeline).toContain("--hk-timeline-link-thickness: 2px");
82
+ expect(timeline).toContain("--hk-timeline-link-clearance: 20px");
83
+ expect(timeline).toContain('&[data-segment="before-current"]');
84
+ expect(timeline).toContain('&[data-segment="current-after"]');
85
+ });
86
+ });
@@ -137,7 +137,16 @@
137
137
  // the current step is never a link endpoint (HkTimeline.tsx statusOf),
138
138
  // so no "active" key here.
139
139
  &[data-status="pending"] {
140
- --_link-color: color-mix(in srgb, var(--hi-color-border) 30%, transparent);
140
+ // 30 % of a SOLID muted tone. Deriving from --hi-color-border multiplied
141
+ // that token's own alpha: the shipped schemes define it as
142
+ // `rgb(128 128 128 / 15%)`, so the bond computed to 15 % × 30 % = 4.5 %
143
+ // — a 2px line at 4.5 % reads as no line at all, which is what the
144
+ // round-24 report saw on the right bond and on both edge continuations
145
+ // (左中右三段式的步骤左右没有横线). --hi-color-muted is an opaque text
146
+ // tone in the family's schemes, so the 30 % below is the strength it
147
+ // looks like; the intent ("a third as loud as the completed bond")
148
+ // survives whatever alpha a theme gives its border token.
149
+ --_link-color: color-mix(in srgb, var(--hi-color-muted, #6c6c6c) 30%, transparent);
141
150
  }
142
151
 
143
152
  background-color: var(--_link-color);