@celestia-island/hikari 0.40.19 → 0.40.22

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.40.19",
3
+ "version": "0.40.22",
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",
@@ -10,6 +10,20 @@
10
10
  .hk-popover-panel {
11
11
  min-width: 0;
12
12
  max-height: min(70vh, calc(100vh - 2 * 8px));
13
+ /* Width MUST be position-independent (max-content, viewport-capped).
14
+ * The anchored panel is fixed-positioned with shrink-to-fit sizing,
15
+ * and computePosition places it as `left = anchorEnd - panelWidth`
16
+ * (bottom-end). With shrink-to-fit the width itself derives from the
17
+ * available space (`viewport - left`) — so any elastically-wide
18
+ * content (percentage-width rows) creates a geometric feedback: every
19
+ * ResizeObserver → rAF reposition adds (viewport - anchorEnd) px of
20
+ * width until the clamp saturates, and the menu visibly ratchets
21
+ * wider frame by frame (demo.dev field report 2026-09-07). Pinning
22
+ * the width to max-content breaks the loop: the panel sizes to its
23
+ * content wherever it sits, and positioning converges in one pass.
24
+ * VIEWPORT_PAD is 8 (script side). */
25
+ width: max-content;
26
+ max-width: calc(100vw - 2 * 8px);
13
27
  }
14
28
 
15
29
  /* Pop motion family tokens (--hk-pop-* in theme.scss) — the reference
@@ -91,6 +105,10 @@
91
105
  }
92
106
 
93
107
  .hk-popover-panel.hk-is-sheet {
108
+ /* The sheet spans the viewport via inline left/right — the anchored
109
+ * rule's max-content width would over-constrain it (left+right+width
110
+ * drops `right` in LTR) and dock it at content width instead. */
111
+ width: auto;
94
112
  border-radius: var(--hk-modal-radius, var(--hi-radius-lg, 12px))
95
113
  var(--hk-modal-radius, var(--hi-radius-lg, 12px))
96
114
  0 0;
@@ -17,4 +17,18 @@ describe("HkPopover glass layer surface hooks", () => {
17
17
  expect(block).toContain("var(--hk-popover-bg, rgb(var(--color-surface)))");
18
18
  expect(block).toContain("var(--hk-popover-blur,");
19
19
  });
20
+
21
+ // Width must stay position-independent: computePosition places the
22
+ // anchored panel at `left = anchorEnd - panelWidth` (bottom-end), so
23
+ // a shrink-to-fit (position-dependent) width creates a ResizeObserver
24
+ // feedback that ratchets the menu wider every frame with elastically-
25
+ // wide content (demo.dev field report 2026-09-07). The sheet branch
26
+ // must keep spanning via its inline left/right (width: auto).
27
+ it("pins the anchored panel width to max-content and resets the sheet", () => {
28
+ const base = src.match(/\.hk-popover-panel\s*{[^}]*}/)![0];
29
+ expect(base).toContain("width: max-content");
30
+ expect(base).toContain("max-width: calc(100vw - 2 * 8px)");
31
+ const sheet = src.match(/\.hk-popover-panel\.hk-is-sheet\s*{[^}]*}/)![0];
32
+ expect(sheet).toContain("width: auto");
33
+ });
20
34
  });
@@ -47,9 +47,24 @@
47
47
  flex-direction: column;
48
48
  gap: var(--space-4, 0.25rem);
49
49
  min-width: 13rem;
50
+ max-width: 22rem;
50
51
  padding: var(--space-8, 0.5rem);
51
52
  }
52
53
 
54
+ /*
55
+ * The anchored popover panel is shrink-to-fit (width: max-content, #421),
56
+ * so any long-form prose in a host slot (mode-extra hint paragraphs) would
57
+ * otherwise set the panel's PREFERRED width — the menu once opened at the
58
+ * hint's single-line ideal width (~870px), stretching the segmented mode
59
+ * group full-bleed and leaving a wide void right of every row. The cap
60
+ * above clamps the menu's max-content contribution instead. The sheet
61
+ * branch is excluded: it stretches to the viewport by design, and its
62
+ * width never derives from content.
63
+ */
64
+ .hk-popover-panel.hk-is-sheet .s-theme-menu {
65
+ max-width: none;
66
+ }
67
+
53
68
  .s-theme-menu-label {
54
69
  font-size: var(--text-xs, 0.75rem);
55
70
  font-weight: 600;
@@ -1,5 +1,5 @@
1
1
  import { computed, defineComponent, onUnmounted, ref, watch, type PropType } from "vue";
2
- import { Check, ChevronDown, Monitor, Moon, Palette, Sun, Trash as Trash2 } from "lucide-vue-next";
2
+ import { Check, ChevronDown, Monitor, MoonStar, Palette, Sun, Trash as Trash2 } from "lucide-vue-next";
3
3
  import {
4
4
  HDivider,
5
5
  HPopover,
@@ -159,9 +159,9 @@ export const HkThemeToggle = defineComponent({
159
159
  function modeOptions(): TabItem[] {
160
160
  const auto = isAutoMode.value;
161
161
  return [
162
- { key: "system", label: t("hikari::theme.modeAuto"), icon: <Monitor size={14} /> },
163
- { key: "light", label: t("hikari::theme.modeLight"), icon: <Sun size={14} />, disabled: auto },
164
- { key: "dark", label: t("hikari::theme.modeDark"), icon: <Moon size={14} />, disabled: auto },
162
+ { key: "system", label: t("hikari::theme.modeAuto"), icon: <Monitor size={16} /> },
163
+ { key: "light", label: t("hikari::theme.modeLight"), icon: <Sun size={16} />, disabled: auto },
164
+ { key: "dark", label: t("hikari::theme.modeDark"), icon: <MoonStar size={16} />, disabled: auto },
165
165
  ];
166
166
  }
167
167
 
@@ -205,11 +205,11 @@ export const HkThemeToggle = defineComponent({
205
205
  aria-label={t("hikari::theme.mode")}
206
206
  >
207
207
  {currentMode.value === "system" ? (
208
- <Monitor size={14} />
208
+ <Monitor size={16} />
209
209
  ) : effectiveMode.value === "dark" ? (
210
- <Moon size={14} />
210
+ <MoonStar size={16} />
211
211
  ) : (
212
- <Sun size={14} />
212
+ <Sun size={16} />
213
213
  )}
214
214
  </button>
215
215
  <button
@@ -252,7 +252,7 @@ export const HkThemeToggle = defineComponent({
252
252
  aria-label={t("hikari::theme.autoAltitudeTip")}
253
253
  onClick={resolveAutoToManual}
254
254
  >
255
- {altitudeNight.value ? <Moon size={14} /> : <Sun size={14} />}
255
+ {altitudeNight.value ? <MoonStar size={16} /> : <Sun size={16} />}
256
256
  <span class="s-theme-mode-autoalt-value">{altitudeText.value}</span>
257
257
  </button>
258
258
  ),