@celestia-island/hikari 0.55.328 → 0.55.329

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.328",
3
+ "version": "0.55.329",
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,15 +1,23 @@
1
1
  // Use theme variables with namespace to avoid conflicts
2
2
  @use "./hikari-vars" as vars;
3
3
 
4
+ /* The terminal is a solid dark canvas by convention (like a code block):
5
+ the surface IS its own frame — no border, one radius tier. The canvas
6
+ stays dark in every app theme (a light-mode terminal reads as a web
7
+ pane, not a terminal); hosts may retune it via --color-terminal-bg /
8
+ --color-terminal-fg without touching the component. Nested hosts must
9
+ NOT wrap it in their own framed box — that stacking is what produced
10
+ the round-outer/square-inner double frame reported 2026-11-09. */
4
11
  .hk-terminal {
5
12
  position: relative;
6
13
  display: block;
7
14
  width: 100%;
8
15
  height: 100%;
9
16
  min-height: 8rem;
10
- padding: 0.35rem 0.45rem;
11
- background: rgb(var(--color-background, 20 22 26));
12
- border: 1px solid rgb(var(--color-border, 128 128 128) / 15%);
17
+ padding: 0.6rem 0.75rem;
18
+ /* Terminal channels seed as r g b TRIPLETS (a hex seed passes the TSX
19
+ layer but invalidates rgb(var()) here — computed value drops out). */
20
+ background: rgb(var(--color-terminal-bg, 20 22 26));
13
21
  border-radius: vars.$hikari-radius-fine-md;
14
22
  box-sizing: border-box;
15
23
  overflow: hidden;
@@ -159,6 +159,46 @@ afterEach(() => {
159
159
  });
160
160
 
161
161
  describe("HkTerminal", () => {
162
+ it("derives the canvas from the TERMINAL channels, not the app theme", async () => {
163
+ // The canvas is a terminal and stays dark in every app theme: the
164
+ // 2026-11-09 double-frame report was a light theme-background panel
165
+ // inside chest's black rounded host. The palette must read
166
+ // --color-terminal-bg/-fg (fixed dark defaults) and must NOT read
167
+ // --color-background/--color-text.
168
+ const theme = __testables.deriveXtermTheme(document.createElement("div")) as Record<
169
+ string,
170
+ string
171
+ >;
172
+ expect(theme.background).toBe("#14161a");
173
+ expect(theme.foreground).toBe("#d6dde6");
174
+ expect(theme.cursorAccent).toBe("#14161a");
175
+ expect(theme.cursor).toBe("#7aa2f7");
176
+ expect(theme.selectionBackground).toBe("#3b435688");
177
+ // Host-side retune wins over the defaults (happy-dom's computed
178
+ // style doesn't resolve inline custom properties, so the retune arm
179
+ // is exercised through a stubbed window computed-style).
180
+ const fakeHost = { tag: "stub" } as unknown as HTMLElement;
181
+ const resolver = (el: Element) =>
182
+ el === fakeHost
183
+ ? ({
184
+ getPropertyValue: (name: string) =>
185
+ name === "--color-terminal-bg"
186
+ ? "10 12 16"
187
+ : name === "--color-terminal-fg"
188
+ ? "#c0c8d4"
189
+ : name === "--color-terminal-selection"
190
+ ? "#2e3a4e"
191
+ : "",
192
+ } as CSSStyleDeclaration)
193
+ : window.getComputedStyle(el);
194
+ const spy = vi.spyOn(window, "getComputedStyle").mockImplementation(resolver);
195
+ const tuned = __testables.deriveXtermTheme(fakeHost) as Record<string, string>;
196
+ spy.mockRestore();
197
+ expect(tuned.background).toBe("#0a0c10");
198
+ expect(tuned.foreground).toBe("#c0c8d4");
199
+ expect(tuned.selectionBackground).toBe("#2e3a4e88");
200
+ });
201
+
162
202
  it("passes the typography props into the Terminal options", async () => {
163
203
  mountTerminal({ fontSize: 15, fontFamily: "MyMono", scrollback: 500, cursorBlink: false });
164
204
  await nextTick();
@@ -47,10 +47,16 @@ import "./HkTerminal.scss";
47
47
  * - `write(data: string | Uint8Array)` — binary-safe feed.
48
48
  * - `writeln`, `clear`, `reset`, `fit`, `focus`, `dimensions`.
49
49
  *
50
- * Theming: the xterm theme is derived from the hikari color channels
51
- * (`--color-background` / `--color-text` / `--color-primary` / …) at
52
- * mount, and re-derived when the document element's class or style
53
- * changes (the light/dark switch mechanism consumers use).
50
+ * Theming: the canvas is a terminal and stays DARK in every app theme —
51
+ * background/foreground default to the fixed terminal palette and may be
52
+ * retuned per host via `--color-terminal-bg` / `--color-terminal-fg` /
53
+ * `--color-terminal-selection`; the cursor accent still derives from the
54
+ * hikari channel (`--color-primary`). The palette re-derives
55
+ * when the document element's class or style changes (the light/dark
56
+ * switch mechanism consumers use). Surface grammar: the component owns
57
+ * border+radius+background (borderless dark canvas, one radius tier) —
58
+ * consumers size the host box and must not wrap it in their own framed
59
+ * surface.
54
60
  */
55
61
 
56
62
  /** Resolve an `r g b` triplet channel (with fallback) to `#rrggbb`. */
@@ -72,11 +78,18 @@ function channelToHex(host: HTMLElement, name: string, fallback: string): string
72
78
 
73
79
  function deriveXtermTheme(host: HTMLElement): ITheme {
74
80
  return {
75
- background: channelToHex(host, "--color-background", "#14161a"),
76
- foreground: channelToHex(host, "--color-text", "#e6e6e6"),
81
+ // The canvas is a terminal: fixed dark defaults, NOT the app theme's
82
+ // background/text (those flip with light/dark and would render a
83
+ // light terminal). Selection too — a theme-coupled pale wash on the
84
+ // dark canvas collapses selected-text contrast to ~3:1 in light
85
+ // themes (R2 of the 2026-11-09 chain). Hosts retune via
86
+ // --color-terminal-bg/-fg/-selection.
87
+ background: channelToHex(host, "--color-terminal-bg", "#14161a"),
88
+ foreground: channelToHex(host, "--color-terminal-fg", "#d6dde6"),
77
89
  cursor: channelToHex(host, "--color-primary", "#7aa2f7"),
78
- cursorAccent: channelToHex(host, "--color-background", "#14161a"),
79
- selectionBackground: channelToHex(host, "--color-selected-bg", "#3b4356") + "88",
90
+ cursorAccent: channelToHex(host, "--color-terminal-bg", "#14161a"),
91
+ selectionBackground:
92
+ channelToHex(host, "--color-terminal-selection", "#3b4356") + "88",
80
93
  };
81
94
  }
82
95
 
@@ -238,4 +251,4 @@ export default defineComponent({
238
251
  });
239
252
 
240
253
  /** Test seam: pure helpers (no DOM dependency beyond getComputedStyle). */
241
- export const __testables = { channelToHex };
254
+ export const __testables = { channelToHex, deriveXtermTheme };