@celestia-island/hikari 0.55.181 → 0.55.183

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.181",
3
+ "version": "0.55.183",
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",
@@ -58,7 +58,7 @@
58
58
  "vue": "^*"
59
59
  },
60
60
  "dependencies": {
61
- "@celestia-island/tairitsu-transport": "^0.1",
61
+ "@celestia-island/tairitsu-transport": "^0.2.0",
62
62
  "@xterm/addon-fit": "^0.*",
63
63
  "@xterm/addon-image": "^0.10.0-beta.301",
64
64
  "@xterm/xterm": "^6.1.0-beta.304",
@@ -69,18 +69,18 @@
69
69
  "marked": "^*"
70
70
  },
71
71
  "devDependencies": {
72
+ "@types/node": "^*",
72
73
  "@types/three": "^*",
73
- "three": "^0.185",
74
74
  "@vitejs/plugin-vue": "^*",
75
75
  "@vitejs/plugin-vue-jsx": "^*",
76
76
  "@vue/server-renderer": "^*",
77
77
  "happy-dom": "^*",
78
78
  "sass": "^*",
79
+ "three": "^0.185",
79
80
  "typescript": "^*",
80
81
  "vite": "^*",
81
- "vue-tsc": "^*",
82
82
  "vitest": "^*",
83
- "@types/node": "^*"
83
+ "vue-tsc": "^*"
84
84
  },
85
85
  "sideEffects": [
86
86
  "**/*.scss",
@@ -89,6 +89,23 @@
89
89
  display: flex;
90
90
  align-items: center;
91
91
  gap: var(--space-8, 0.5rem);
92
+
93
+ /* A vertical list's row content owns the lane's width: when the host
94
+ renders ONE root element per row (the card shapes — wowsp's install
95
+ and account cards), stretch it across the lane so every row fills
96
+ the list instead of hugging its own text (wowsp report 2026-10-18:
97
+ the settings card lists shrank to content width after adopting this
98
+ component — the retired SortableList rows were plain blocks that
99
+ filled). min-width: 0 keeps ellipsis chains inside the card working.
100
+ Fragment rows — several sibling elements sharing the lane (chest's
101
+ tab/subview manager rows) — keep host-owned layout: the selector
102
+ deliberately does not match them. The drag ghost reuses the row
103
+ markup, so a single-root ghost fills its frame exactly like its
104
+ live row. */
105
+ > :only-child {
106
+ flex: 1;
107
+ min-width: 0;
108
+ }
92
109
  }
93
110
 
94
111
  .hk-draggable-list-ghost {
@@ -62,3 +62,22 @@ describe("HkDraggableList handle-lane sheet", () => {
62
62
  expect(body).toContain("display: none");
63
63
  });
64
64
  });
65
+
66
+ describe("HkDraggableList content-lane fill sheet", () => {
67
+ const css = listCss();
68
+
69
+ it("stretches a single-root row across the lane", () => {
70
+ const body = ruleBody(css, ".hk-draggable-list-content > :only-child");
71
+ expect(body, "the :only-child fill rule must exist").not.toBeNull();
72
+ expect(body).toContain("flex: 1");
73
+ expect(body).toContain("min-width: 0");
74
+ });
75
+
76
+ // The fill must stay keyed on :only-child: fragment rows (several
77
+ // siblings sharing the lane) are host-owned layout and must not match.
78
+ it("never stretches fragment rows — the rule keys on :only-child alone", () => {
79
+ const fillRules = css.match(/\.hk-draggable-list-content\s*>\s*[^{]+\{/g) ?? [];
80
+ expect(fillRules.length).toBe(1);
81
+ expect(fillRules[0]).toContain(":only-child");
82
+ });
83
+ });
@@ -223,6 +223,54 @@ describe("HkDraggableList list semantics", () => {
223
223
  });
224
224
  });
225
225
 
226
+ describe("HkDraggableList content-lane shape", () => {
227
+ /** The lane hands the slot content through verbatim, and the sheet
228
+ * stretches a lane's ONLY element child across the row (the
229
+ * `:only-child` fill — sheet twin:
230
+ * HkDraggableList.styles.test.ts). That selector's semantics hinge on
231
+ * this shape: a single-root slot must land as exactly one element
232
+ * child, and a fragment slot as several siblings (which the fill
233
+ * deliberately does not match). */
234
+
235
+ function mountWithSlot(slot: () => unknown): HTMLElement {
236
+ const container = document.createElement("div");
237
+ document.body.appendChild(container);
238
+ const app = createApp({
239
+ render: () =>
240
+ h(
241
+ HDraggableList,
242
+ { items: [{ key: "a" }] },
243
+ { item: () => slot() },
244
+ ),
245
+ });
246
+ app.mount(container);
247
+ mounts.push({ app, container });
248
+ return container.querySelector(".hk-draggable-list") as HTMLElement;
249
+ }
250
+
251
+ function laneOf(root: HTMLElement): HTMLElement {
252
+ return root.querySelector(".hk-draggable-list-content") as HTMLElement;
253
+ }
254
+
255
+ it("lands a single-root slot as the lane's only element child", () => {
256
+ const root = mountWithSlot(() => h("div", { class: "row-card" }, "body"));
257
+ const children = Array.from(laneOf(root).children);
258
+ expect(children).toHaveLength(1);
259
+ expect(children[0]!.classList.contains("row-card")).toBe(true);
260
+ });
261
+
262
+ it("lands a fragment slot as several lane siblings the fill ignores", () => {
263
+ const root = mountWithSlot(() => [
264
+ h("span", { class: "row-lead" }, "lead"),
265
+ h("span", { class: "row-tail" }, "tail"),
266
+ ]);
267
+ const children = Array.from(laneOf(root).children);
268
+ expect(children).toHaveLength(2);
269
+ expect(children[0]!.classList.contains("row-lead")).toBe(true);
270
+ expect(children[1]!.classList.contains("row-tail")).toBe(true);
271
+ });
272
+ });
273
+
226
274
  describe("HkDraggableList press ergonomics (clickable rows)", () => {
227
275
  /** Two guards make a clickable row safe inside the list (ported from
228
276
  * wowsp's SortableList twin, which ran them in production):