@hogoshi/ui 0.1.5 → 0.1.6
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": "@hogoshi/ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@base-ui/react": "^1.8.0",
|
|
41
|
-
"@hogoshi/tokens": "^0.1.
|
|
41
|
+
"@hogoshi/tokens": "^0.1.2",
|
|
42
42
|
"@hugeicons-pro/core-duotone-rounded": "^4.2.2",
|
|
43
43
|
"@hugeicons-pro/core-solid-rounded": "^4.2.2",
|
|
44
44
|
"@hugeicons-pro/core-stroke-rounded": "^4.2.2",
|
|
@@ -21,7 +21,7 @@ export function TopBar({ contained = false, children, className }: { contained?:
|
|
|
21
21
|
const root = document.querySelector("[data-scroll-root]");
|
|
22
22
|
const read = () => {
|
|
23
23
|
const top = root instanceof HTMLElement ? root.scrollTop : window.scrollY;
|
|
24
|
-
setCompact(top > 24);
|
|
24
|
+
setCompact((current) => (current ? top > 8 : top > 24));
|
|
25
25
|
};
|
|
26
26
|
read();
|
|
27
27
|
const target: EventTarget = root instanceof HTMLElement ? root : window;
|
|
@@ -30,13 +30,13 @@ export function TopBar({ contained = false, children, className }: { contained?:
|
|
|
30
30
|
}, []);
|
|
31
31
|
|
|
32
32
|
return (
|
|
33
|
-
<header className={cn("pointer-events-none inset-x-0 top-0 z-[var(--z-sticky)]
|
|
33
|
+
<header className={cn("pointer-events-none inset-x-0 top-0 z-[var(--z-sticky)]", contained ? "absolute" : "fixed", className)}>
|
|
34
34
|
<div
|
|
35
35
|
className={cn(
|
|
36
|
-
"pointer-events-auto flex items-center transition-[width,
|
|
36
|
+
"pointer-events-auto relative mx-auto flex h-12 items-center border transition-[width,translate,border-radius,background-color,border-color,box-shadow] duration-[calc(var(--motion-duration)*4)] ease-[var(--motion-ease)]",
|
|
37
37
|
compact
|
|
38
|
-
? "border-border bg-bg-elevated
|
|
39
|
-
: "
|
|
38
|
+
? "border-border bg-bg-elevated w-[min(40rem,calc(100%-max(0.75rem,var(--safe-left))-max(0.75rem,var(--safe-right))))] translate-y-[calc(var(--safe-top)+0.75rem)] rounded-full px-2 shadow-[var(--shadow-md)]"
|
|
39
|
+
: "before:pointer-events-auto w-full translate-y-[var(--safe-top)] border-transparent bg-transparent pl-[max(0.75rem,var(--safe-left))] pr-[max(0.75rem,var(--safe-right))] before:absolute before:inset-x-0 before:bottom-full before:h-[var(--safe-top)] before:content-['']",
|
|
40
40
|
)}
|
|
41
41
|
>
|
|
42
42
|
<Navbar className="relative h-full w-full bg-transparent px-1 shadow-none backdrop-blur-none">{children}</Navbar>
|
|
@@ -154,7 +154,7 @@ export function BottomBar({ className, children, ...props }: ComponentProps<"nav
|
|
|
154
154
|
return (
|
|
155
155
|
<nav
|
|
156
156
|
className={cn(
|
|
157
|
-
"bg-bg-elevated/70 border-border fixed right-[max(0.75rem,var(--safe-right))] bottom-
|
|
157
|
+
"bg-bg-elevated/70 border-border fixed right-[max(0.75rem,var(--safe-right))] bottom-[max(0.5rem,var(--safe-bottom))] left-[max(0.75rem,var(--safe-left))] z-[var(--z-sticky)] rounded-[var(--radius-lg)] border p-1 shadow-[var(--shadow-md)] backdrop-blur-xl md:hidden",
|
|
158
158
|
className,
|
|
159
159
|
)}
|
|
160
160
|
{...props}
|
|
@@ -33,8 +33,7 @@ function markScrolling(element: Element) {
|
|
|
33
33
|
|
|
34
34
|
function motionAllowed() {
|
|
35
35
|
const motion = document.documentElement.getAttribute("data-motion");
|
|
36
|
-
|
|
37
|
-
return !window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
36
|
+
return motion !== "off" && motion !== "reduced";
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
function stop(element: Element) {
|
|
@@ -38,6 +38,41 @@ function freeze(media: HTMLVideoElement | HTMLCanvasElement, copy: Element) {
|
|
|
38
38
|
copy.replaceWith(canvas);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
function lockScroll() {
|
|
42
|
+
const root = document.querySelector("[data-scroll-root]");
|
|
43
|
+
if (root instanceof HTMLElement) {
|
|
44
|
+
const top = root.scrollTop;
|
|
45
|
+
const left = root.scrollLeft;
|
|
46
|
+
return () => {
|
|
47
|
+
root.scrollTop = top;
|
|
48
|
+
root.scrollLeft = left;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const top = window.scrollY;
|
|
52
|
+
const left = window.scrollX;
|
|
53
|
+
const body = document.body;
|
|
54
|
+
const prev = {
|
|
55
|
+
position: body.style.position,
|
|
56
|
+
top: body.style.top,
|
|
57
|
+
left: body.style.left,
|
|
58
|
+
right: body.style.right,
|
|
59
|
+
width: body.style.width,
|
|
60
|
+
};
|
|
61
|
+
body.style.position = "fixed";
|
|
62
|
+
body.style.top = `-${top}px`;
|
|
63
|
+
body.style.left = "0";
|
|
64
|
+
body.style.right = "0";
|
|
65
|
+
body.style.width = "100%";
|
|
66
|
+
return () => {
|
|
67
|
+
body.style.position = prev.position;
|
|
68
|
+
body.style.top = prev.top;
|
|
69
|
+
body.style.left = prev.left;
|
|
70
|
+
body.style.right = prev.right;
|
|
71
|
+
body.style.width = prev.width;
|
|
72
|
+
window.scrollTo(left, top);
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
41
76
|
function holdPage() {
|
|
42
77
|
const root = document.documentElement;
|
|
43
78
|
root.setAttribute("data-theme-switching", "");
|
|
@@ -160,9 +195,7 @@ export function ThemeToggle({
|
|
|
160
195
|
if (switching) return;
|
|
161
196
|
const root = document.documentElement;
|
|
162
197
|
const next = root.getAttribute("data-mode") === "dark" ? "light" : "dark";
|
|
163
|
-
|
|
164
|
-
window.matchMedia("(prefers-reduced-motion: reduce)").matches || root.getAttribute("data-motion") === "off";
|
|
165
|
-
if (reduce) {
|
|
198
|
+
if (root.getAttribute("data-motion") === "off") {
|
|
166
199
|
swap(next);
|
|
167
200
|
return;
|
|
168
201
|
}
|
|
@@ -172,8 +205,10 @@ export function ThemeToggle({
|
|
|
172
205
|
const current = next === "dark" ? "light" : "dark";
|
|
173
206
|
const inward = next === "dark";
|
|
174
207
|
const layer = snapshot(inward ? current : next);
|
|
208
|
+
const unlock = lockScroll();
|
|
175
209
|
const finish = () => {
|
|
176
210
|
layer.remove();
|
|
211
|
+
unlock();
|
|
177
212
|
requestAnimationFrame(() => {
|
|
178
213
|
requestAnimationFrame(() => {
|
|
179
214
|
release();
|
package/src/styles.css
CHANGED
|
@@ -61,6 +61,8 @@ body {
|
|
|
61
61
|
color: var(--fg);
|
|
62
62
|
font-family: var(--font-sans);
|
|
63
63
|
font-size: var(--text-base);
|
|
64
|
+
min-height: 100%;
|
|
65
|
+
min-height: 100dvh;
|
|
64
66
|
-webkit-font-smoothing: antialiased;
|
|
65
67
|
text-rendering: optimizeLegibility;
|
|
66
68
|
}
|
|
@@ -328,11 +330,6 @@ nav,
|
|
|
328
330
|
to { opacity: 1; transform: scale(1); }
|
|
329
331
|
}
|
|
330
332
|
|
|
331
|
-
html[data-theme-switching],
|
|
332
|
-
html[data-theme-switching] body {
|
|
333
|
-
overflow: hidden !important;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
333
|
html[data-theme-switching] body {
|
|
337
334
|
pointer-events: none !important;
|
|
338
335
|
}
|
|
@@ -432,12 +429,3 @@ button.hogoshi-grab:disabled {
|
|
|
432
429
|
z-index: 0;
|
|
433
430
|
}
|
|
434
431
|
|
|
435
|
-
@media (prefers-reduced-motion: reduce) {
|
|
436
|
-
*,
|
|
437
|
-
*::before,
|
|
438
|
-
*::after {
|
|
439
|
-
animation-duration: 1ms !important;
|
|
440
|
-
animation-iteration-count: 1 !important;
|
|
441
|
-
transition-duration: 1ms !important;
|
|
442
|
-
}
|
|
443
|
-
}
|