@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
|
@@ -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={
|
|
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
|
|
51
|
-
0.8125rem
|
|
52
|
-
the
|
|
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);
|