@celestia-island/hikari 0.55.108 → 0.55.109

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.108",
3
+ "version": "0.55.109",
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",
@@ -76,6 +76,17 @@ const setWidth = (w: number) => {
76
76
  window.dispatchEvent(new Event("resize"));
77
77
  };
78
78
 
79
+ function paddingInner(container: HTMLElement): HTMLElement | null | undefined {
80
+ const viewport = container.querySelector(".hk-scroll-container-viewport")
81
+ ?? container.querySelector(".hk-scroll-container");
82
+ return viewport?.firstElementChild as HTMLElement | null | undefined;
83
+ }
84
+
85
+ function mobileInnerPadding(container: HTMLElement): string {
86
+ return paddingInner(container)?.style.padding ?? "";
87
+ }
88
+
89
+
79
90
  function shellNode(
80
91
  props: Record<string, unknown>,
81
92
  slots: Record<string, unknown>,
@@ -234,4 +245,37 @@ describe("HkAdminShell", () => {
234
245
  expect(inner).toBeTruthy();
235
246
  expect(inner?.style.padding).toBe("2rem");
236
247
  });
248
+
249
+ it("drops the horizontal half of the content padding below the mobile breakpoint", async () => {
250
+ // Phone width: side gutters must vanish; vertical clearance survives.
251
+ // Asserted via longhands: happy-dom's shorthand parser collapses
252
+ // 3-value paddings, so style.padding cannot distinguish them here.
253
+ setWidth(390);
254
+ const mobileShell = mount(shellNode(
255
+ { navTitle: "Navigation", contentPadding: "2rem" },
256
+ { header: () => null, sidebar: NAV, content: CONTENT },
257
+ ));
258
+ const inner = paddingInner(mobileShell);
259
+ expect(inner?.style.paddingTop).toBe("2rem");
260
+ expect(inner?.style.paddingBottom).toBe("2rem");
261
+ expect(inner?.style.paddingLeft).toBe("0px");
262
+ expect(inner?.style.paddingRight).toBe("0px");
263
+
264
+ // Multi-value shorthand keeps per-side meaning: vertical survives,
265
+ // horizontal is zeroed (never the inverted "1rem 2rem 0").
266
+ const multi = mount(shellNode(
267
+ { navTitle: "Navigation", contentPadding: "1rem 2rem" },
268
+ { header: () => null, sidebar: NAV, content: CONTENT },
269
+ ));
270
+ const multiInner = paddingInner(multi);
271
+ expect(multiInner?.style.paddingTop).toBe("1rem");
272
+ expect(multiInner?.style.paddingBottom).toBe("1rem");
273
+ expect(multiInner?.style.paddingLeft).toBe("0px");
274
+ expect(multiInner?.style.paddingRight).toBe("0px");
275
+
276
+ // Crossing back to desktop restores the verbatim padding.
277
+ setWidth(1280);
278
+ await nextTick();
279
+ expect(mobileInnerPadding(mobileShell)).toBe("2rem");
280
+ });
237
281
  });
@@ -21,7 +21,11 @@ export const HkAdminShell = defineComponent({
21
21
  drawerPanelClass: { type: String, default: undefined },
22
22
  /** Content-area padding (inside the scroll viewport). Padding is
23
23
  * applied to an inner wrapper rather than the scroll container so
24
- * card box-shadows are never clipped at the viewport edges. */
24
+ * card box-shadows are never clipped at the viewport edges. Below
25
+ * the mobile breakpoint the horizontal half is dropped
26
+ * automatically (2026-10-03 user direction: on phones the content
27
+ * area must span the full width for 2D panels and the 3D scene —
28
+ * only the vertical clearance survives). */
25
29
  contentPadding: { type: String, default: "1.5rem" },
26
30
  },
27
31
  setup(props, { slots }) {
@@ -30,6 +34,22 @@ export const HkAdminShell = defineComponent({
30
34
  const isDesktop = computed(() => viewportWidth.value >= props.mobileBreakpoint);
31
35
  const sidebarOpen = ref(false);
32
36
 
37
+ // Content padding with the mobile side-gutter rule applied: desktop
38
+ // gets the value verbatim; below the breakpoint the horizontal
39
+ // tracks become zero while the vertical tracks survive. The CSS
40
+ // padding shorthand is parsed per side so multi-value values keep
41
+ // their meaning ("1rem 2rem" -> "1rem 0", not the invalid or
42
+ // inverted "1rem 2rem 0"). An empty value passes through untouched.
43
+ const mobileSideGutterFree = (value: string): string => {
44
+ const sides = value.trim().split(/\s+/).filter(Boolean);
45
+ if (sides.length === 0) return value;
46
+ const [top, , bottom] = sides;
47
+ return `${top} 0 ${bottom ?? top}`;
48
+ };
49
+ const contentStyle = computed(() => ({
50
+ padding: isDesktop.value ? props.contentPadding : mobileSideGutterFree(props.contentPadding),
51
+ }));
52
+
33
53
  const actionBar = provideActionBar();
34
54
 
35
55
  const toggleHamburger = () => {
@@ -80,7 +100,7 @@ export const HkAdminShell = defineComponent({
80
100
  {/* Padding lives INSIDE the scroll viewport (an inner
81
101
  wrapper) so card box-shadows are not clipped at the
82
102
  viewport edges. */}
83
- <div style={{ padding: props.contentPadding }}>{slots.content?.()}</div>
103
+ <div style={contentStyle.value}>{slots.content?.()}</div>
84
104
  </HScrollContainer>
85
105
  </main>
86
106
 
@@ -47,9 +47,11 @@
47
47
  target; sm keeps its compact --text-xs. xs (2026-10-02, connection
48
48
  popover action row) shrinks the footprint further for inline popover
49
49
  footers: same --text-xs, tighter padding, 1.375rem min-height, and a
50
- 13px glyph (HkButton.tsx scales icon/suffix with the size) inside a
51
- 0.8125rem fixed box so the square-glyph contract keeps its rhythm at
52
- the smaller scale. */
50
+ 13px glyph produced entirely by the CSS chain below (the glyph box
51
+ drops to 0.8125rem and the inner .hk-icon span scales to 100% of it,
52
+ so the svg that always renders at HIcon's size={16} lands at 13px)
53
+ while the square-glyph contract keeps its rhythm at the smaller
54
+ scale. HkButton.tsx itself renders every size's glyph identically. */
53
55
 
54
56
  .hk-btn-xs {
55
57
  padding: var(--space-4) var(--space-8);