@celestia-island/hikari 0.55.260 → 0.55.261

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.260",
3
+ "version": "0.55.261",
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",
@@ -1,5 +1,5 @@
1
1
  import { afterEach, describe, expect, it } from "vitest";
2
- import { createApp, h } from "vue";
2
+ import { createApp, h, nextTick, ref } from "vue";
3
3
 
4
4
  import HkDonutChart from "./HkDonutChart";
5
5
  import type { HkDonutEntry } from "./donutGeometry";
@@ -80,6 +80,24 @@ describe("HkDonutChart", () => {
80
80
  expect(empty.querySelector(".hk-donut--empty")).toBeTruthy();
81
81
  });
82
82
 
83
+ it("clears a dead hover key when the entries swap under a held pointer", async () => {
84
+ // The wowsp lesson: the hovered element can unmount without firing
85
+ // mouseleave; without the reset every surviving slice would stay
86
+ // stuck at is-dim under the dead key.
87
+ const entriesRef = ref(ENTRIES);
88
+ const el = mount(h(() => <HkDonutChart entries={entriesRef.value} />));
89
+ const slices = [...el.querySelectorAll(".hk-donut__slice")];
90
+ slices[0]!.dispatchEvent(new MouseEvent("mouseenter"));
91
+ await nextTick();
92
+ expect(slices[1]!.className).toContain("is-dim");
93
+ entriesRef.value = ENTRIES.slice(0, 1);
94
+ await nextTick();
95
+ const after = [...el.querySelectorAll(".hk-donut__slice")];
96
+ expect(after).toHaveLength(1);
97
+ expect(after[0]!.className).not.toContain("is-dim");
98
+ expect(after[0]!.className).not.toContain("is-hot");
99
+ });
100
+
83
101
  it("renders the legendIcon slot's glyph in place of the text label", () => {
84
102
  const el = mount(
85
103
  <HkDonutChart
@@ -1,4 +1,4 @@
1
- import { computed, defineComponent, ref, type PropType } from "vue";
1
+ import { computed, defineComponent, ref, watch, type PropType } from "vue";
2
2
 
3
3
  import {
4
4
  chunkLegendItems,
@@ -67,6 +67,20 @@ export default defineComponent({
67
67
  },
68
68
  setup(props, { emit, slots }) {
69
69
  const hovered = ref<string | null>(null);
70
+ // A hover key lives on a DOM element; when the entries swap under a
71
+ // held pointer, the hovered element can unmount WITHOUT firing
72
+ // mouseleave (browsers skip removed nodes) — a dead key would dim
73
+ // the whole block until the pointer deliberately re-entered it.
74
+ // Resetting on every entries repaint costs nothing (a resting
75
+ // pointer only ever clears nulls) and can never stick. Lesson
76
+ // upstreamed from wowsp's ShipDistCharts, whose own test pins it.
77
+ watch(
78
+ () => props.entries,
79
+ () => {
80
+ hovered.value = null;
81
+ },
82
+ { deep: true },
83
+ );
70
84
 
71
85
  const slices = computed<HkDonutSlice[]>(() =>
72
86
  donutSlices(