@celestia-island/hikari 0.55.70 → 0.55.71
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
|
@@ -441,10 +441,9 @@
|
|
|
441
441
|
}
|
|
442
442
|
|
|
443
443
|
// ── Navigation motion (2026-09-23 user directive, round 16) ──────────
|
|
444
|
-
// The stepper never hard-cuts: status colors crossfade
|
|
445
|
-
//
|
|
446
|
-
//
|
|
447
|
-
// duration/ease and collapses under reduced motion.
|
|
444
|
+
// The stepper never hard-cuts: status colors crossfade and the window-mode
|
|
445
|
+
// cells wipe in from the navigation side. All of it rides the family's
|
|
446
|
+
// standard duration/ease and collapses under reduced motion.
|
|
448
447
|
|
|
449
448
|
.hk-timeline {
|
|
450
449
|
--hk-timeline-motion: 0.3s;
|
|
@@ -462,41 +461,17 @@
|
|
|
462
461
|
border-color var(--hk-timeline-motion) var(--hk-timeline-motion-ease);
|
|
463
462
|
}
|
|
464
463
|
|
|
465
|
-
//
|
|
466
|
-
//
|
|
467
|
-
//
|
|
468
|
-
//
|
|
464
|
+
// The full-mode active halo was removed here (2026-09-24 user directive):
|
|
465
|
+
// a measured pill behind the active step, sliding between nodes, which
|
|
466
|
+
// read as an unexplained primary blob in every wide multi-step flow and
|
|
467
|
+
// duplicated what the filled indicator and the label weight already say.
|
|
468
|
+
// Window mode never had one. The containing-block rule below stays — it is
|
|
469
|
+
// the timeline's anchor for any absolutely positioned consumer content, and
|
|
470
|
+
// the vertical rail anchors to the step rather than to this box.
|
|
469
471
|
.hk-timeline[data-mode="full"]:not(.hk-scroll-pin) {
|
|
470
472
|
position: relative;
|
|
471
473
|
}
|
|
472
474
|
|
|
473
|
-
.hk-timeline-halo {
|
|
474
|
-
position: absolute;
|
|
475
|
-
left: 0;
|
|
476
|
-
top: 50%;
|
|
477
|
-
translate: 0 -50%;
|
|
478
|
-
border-radius: 999px;
|
|
479
|
-
background: color-mix(in srgb, var(--hi-color-primary) 10%, transparent);
|
|
480
|
-
pointer-events: none;
|
|
481
|
-
height: 100%;
|
|
482
|
-
box-sizing: border-box;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
.hk-timeline[data-orientation="vertical"] .hk-timeline-halo {
|
|
486
|
-
top: 0;
|
|
487
|
-
left: 50%;
|
|
488
|
-
translate: -50% 0;
|
|
489
|
-
width: 100%;
|
|
490
|
-
height: auto;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
.hk-timeline-halo[data-placed] {
|
|
494
|
-
transition:
|
|
495
|
-
transform var(--hk-timeline-motion) var(--hk-timeline-motion-ease),
|
|
496
|
-
width var(--hk-timeline-motion) var(--hk-timeline-motion-ease),
|
|
497
|
-
height var(--hk-timeline-motion) var(--hk-timeline-motion-ease);
|
|
498
|
-
}
|
|
499
|
-
|
|
500
475
|
// Window mode: each cell's step content is keyed by its step key, so a
|
|
501
476
|
// navigation remounts it — wipe in from the navigation side. data-dir is
|
|
502
477
|
// absent on the very first render, so opening does not animate.
|
|
@@ -562,8 +537,4 @@ html[data-css-animations="0"] .hk-timeline[data-mode="window"][data-dir] .hk-tim
|
|
|
562
537
|
.hk-timeline[data-mode="window"][data-dir] .hk-timeline-step {
|
|
563
538
|
animation: none;
|
|
564
539
|
}
|
|
565
|
-
|
|
566
|
-
.hk-timeline-halo[data-placed] {
|
|
567
|
-
transition: none;
|
|
568
|
-
}
|
|
569
540
|
}
|
|
@@ -424,36 +424,20 @@ describe("HkTimeline navigation motion (round 16)", () => {
|
|
|
424
424
|
return { container, current };
|
|
425
425
|
}
|
|
426
426
|
|
|
427
|
-
it("
|
|
428
|
-
|
|
429
|
-
//
|
|
430
|
-
//
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
Object.defineProperty(step, "offsetLeft", {
|
|
435
|
-
configurable: true,
|
|
436
|
-
get: () => i * 100,
|
|
437
|
-
});
|
|
438
|
-
Object.defineProperty(step, "offsetWidth", {
|
|
439
|
-
configurable: true,
|
|
440
|
-
get: () => 80,
|
|
441
|
-
});
|
|
442
|
-
}
|
|
443
|
-
await nextTick();
|
|
444
|
-
await nextTick();
|
|
445
|
-
const halo = container.querySelector<HTMLElement>(".hk-timeline-halo");
|
|
446
|
-
expect(halo).not.toBeNull();
|
|
447
|
-
// Active = s1 (second node): translateX(100 - pad).
|
|
448
|
-
expect(halo!.style.transform).toBe("translateX(94px)");
|
|
449
|
-
expect(halo!.style.width).toBe("92px");
|
|
450
|
-
expect(halo!.hasAttribute("data-placed")).toBe(true);
|
|
451
|
-
|
|
452
|
-
current.value = "s3";
|
|
427
|
+
it("renders no full-mode halo behind the active step", async () => {
|
|
428
|
+
// The measured pill that used to slide behind the active step is gone
|
|
429
|
+
// (2026-09-24 user directive): in a wide multi-step flow it read as an
|
|
430
|
+
// unexplained primary blob, and the filled indicator plus the label
|
|
431
|
+
// weight already carry the active step. Pinned so a later "highlight"
|
|
432
|
+
// refactor cannot quietly reintroduce it.
|
|
433
|
+
const { container } = mountTimeline(4, "s1");
|
|
453
434
|
await nextTick();
|
|
454
435
|
await nextTick();
|
|
455
|
-
|
|
456
|
-
|
|
436
|
+
expect(container.querySelector(".hk-timeline-halo")).toBeNull();
|
|
437
|
+
// The overlay the window mode owns is a different element and stays a
|
|
438
|
+
// window-mode concern — full mode draws its connectors inline.
|
|
439
|
+
expect(container.querySelector(".hk-timeline[data-mode='full']")).not.toBeNull();
|
|
440
|
+
expect(container.querySelector(".hk-timeline-links")).toBeNull();
|
|
457
441
|
});
|
|
458
442
|
|
|
459
443
|
it("marks the navigation direction for the window-mode wipe", async () => {
|
|
@@ -178,9 +178,8 @@ export default defineComponent({
|
|
|
178
178
|
|
|
179
179
|
// ── Navigation motion (2026-09-23 user directive, round 16) ──────
|
|
180
180
|
// The stepper must not hard-cut between steps: the status colors
|
|
181
|
-
// crossfade (stylesheet)
|
|
182
|
-
// navigation side (keyed remount + data-dir)
|
|
183
|
-
// active halo slides between step nodes (measured transform).
|
|
181
|
+
// crossfade (stylesheet) and the window-mode cells wipe in from the
|
|
182
|
+
// navigation side (keyed remount + data-dir).
|
|
184
183
|
let prevIndex = currentIndex.value;
|
|
185
184
|
/** Set once the first navigation revealed a direction; drives the
|
|
186
185
|
* window-mode wipe's side via the host attribute. */
|
|
@@ -192,37 +191,11 @@ export default defineComponent({
|
|
|
192
191
|
prevIndex = idx;
|
|
193
192
|
});
|
|
194
193
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
if (!hostEl || !haloEl) return;
|
|
201
|
-
const step = hostEl.querySelector<HTMLElement>(
|
|
202
|
-
'.hk-timeline-step[data-status="active"]',
|
|
203
|
-
);
|
|
204
|
-
if (!step) return;
|
|
205
|
-
const vertical = props.orientation === "vertical";
|
|
206
|
-
const pad = 6;
|
|
207
|
-
if (vertical) {
|
|
208
|
-
haloEl.style.transform = `translateY(${Math.max(0, step.offsetTop - pad)}px)`;
|
|
209
|
-
haloEl.style.width = "";
|
|
210
|
-
haloEl.style.height = `${step.offsetHeight + pad * 2}px`;
|
|
211
|
-
} else {
|
|
212
|
-
haloEl.style.transform = `translateX(${Math.max(0, step.offsetLeft - pad)}px)`;
|
|
213
|
-
haloEl.style.height = "";
|
|
214
|
-
haloEl.style.width = `${step.offsetWidth + pad * 2}px`;
|
|
215
|
-
}
|
|
216
|
-
// The very first placement must not animate from nothing — only
|
|
217
|
-
// subsequent moves ride the CSS transition.
|
|
218
|
-
haloEl.setAttribute("data-placed", "");
|
|
219
|
-
}
|
|
220
|
-
watch(
|
|
221
|
-
() => [props.currentKey, props.orientation] as const,
|
|
222
|
-
() => {
|
|
223
|
-
void nextTick(positionHalo);
|
|
224
|
-
},
|
|
225
|
-
);
|
|
194
|
+
// The sliding full-mode highlight is gone (2026-09-24 user directive).
|
|
195
|
+
// It read as an unexplained primary blob behind the active step in every
|
|
196
|
+
// multi-step flow that is wide enough to show all of them, and the
|
|
197
|
+
// active step is already carried by its filled indicator plus the label
|
|
198
|
+
// weight. Window mode never had one, so nothing replaces it there.
|
|
226
199
|
|
|
227
200
|
function statusOf(idx: number): TimelineStepStatus {
|
|
228
201
|
return idx < currentIndex.value
|
|
@@ -262,13 +235,11 @@ export default defineComponent({
|
|
|
262
235
|
if (typeof ResizeObserver !== "undefined") {
|
|
263
236
|
observer = new ResizeObserver(() => {
|
|
264
237
|
measure();
|
|
265
|
-
positionHalo();
|
|
266
238
|
});
|
|
267
239
|
if (host.value) observer.observe(host.value);
|
|
268
240
|
}
|
|
269
241
|
void nextTick(() => {
|
|
270
242
|
measure();
|
|
271
|
-
positionHalo();
|
|
272
243
|
});
|
|
273
244
|
});
|
|
274
245
|
|
|
@@ -428,7 +399,6 @@ export default defineComponent({
|
|
|
428
399
|
data-mode="full"
|
|
429
400
|
data-dir={navDir.value ?? undefined}
|
|
430
401
|
>
|
|
431
|
-
<div ref={halo} class="hk-timeline-halo" aria-hidden="true" />
|
|
432
402
|
{props.steps.map((_step, idx) => {
|
|
433
403
|
const isLast = idx === props.steps.length - 1;
|
|
434
404
|
return renderStep(idx, { connector: !isLast, last: isLast });
|