more perf impr
This commit is contained in:
@@ -22,6 +22,26 @@
|
|||||||
children: Snippet;
|
children: Snippet;
|
||||||
showCloseButton?: boolean;
|
showCloseButton?: boolean;
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
|
// Keep the (fixed, layout-viewport-centered) dialog centered within the
|
||||||
|
// VISUAL viewport, so the mobile keyboard shifts it up instead of covering it.
|
||||||
|
let kbShift = $state(0);
|
||||||
|
$effect(() => {
|
||||||
|
const vv = window.visualViewport;
|
||||||
|
if (!vv) return;
|
||||||
|
const update = () => {
|
||||||
|
const visualCenter = vv.offsetTop + vv.height / 2;
|
||||||
|
// negative when the keyboard eats the bottom → moves the dialog up
|
||||||
|
kbShift = Math.min(0, visualCenter - window.innerHeight / 2);
|
||||||
|
};
|
||||||
|
update();
|
||||||
|
vv.addEventListener('resize', update);
|
||||||
|
vv.addEventListener('scroll', update);
|
||||||
|
return () => {
|
||||||
|
vv.removeEventListener('resize', update);
|
||||||
|
vv.removeEventListener('scroll', update);
|
||||||
|
};
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<DialogPortal {...portalProps}>
|
<DialogPortal {...portalProps}>
|
||||||
@@ -33,6 +53,7 @@
|
|||||||
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',
|
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
|
style="margin-top:{kbShift}px;transition:margin-top 0.18s ease"
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
|
|||||||
@@ -262,18 +262,20 @@
|
|||||||
--pt: calc(var(--pt-min) + (var(--pt-full) - var(--pt-min)) * var(--k));
|
--pt: calc(var(--pt-min) + (var(--pt-full) - var(--pt-min)) * var(--k));
|
||||||
--rel: clamp(0, calc(1 - var(--p) * 2), 1);
|
--rel: clamp(0, calc(1 - var(--p) * 2), 1);
|
||||||
--detail: clamp(0, calc(1 - var(--p) * 1.6), 1);
|
--detail: clamp(0, calc(1 - var(--p) * 1.6), 1);
|
||||||
/* bar background/divider/shadow fade in once it starts collapsing */
|
/* bar background/divider fade in once it starts collapsing */
|
||||||
--chrome: clamp(0, calc(var(--p) / 0.35), 1);
|
--chrome: clamp(0, calc(var(--p) / 0.35), 1);
|
||||||
|
|
||||||
|
/* Opaque-background fade only — no backdrop-filter blur or animated
|
||||||
|
box-shadow (both are very expensive to repaint every scroll frame on
|
||||||
|
mobile). Promote to its own compositor layer so repaints stay isolated. */
|
||||||
background: color-mix(
|
background: color-mix(
|
||||||
in oklab,
|
in oklab,
|
||||||
var(--color-background) calc(var(--chrome) * 100%),
|
var(--color-background) calc(var(--chrome) * 100%),
|
||||||
transparent
|
transparent
|
||||||
);
|
);
|
||||||
backdrop-filter: blur(calc(var(--chrome) * 6px));
|
|
||||||
border-bottom: 1px solid
|
border-bottom: 1px solid
|
||||||
color-mix(in oklab, var(--color-border) calc(var(--chrome) * 100%), transparent);
|
color-mix(in oklab, var(--color-border) calc(var(--chrome) * 100%), transparent);
|
||||||
box-shadow: 0 6px 12px -8px rgba(0, 0, 0, calc(var(--chrome) * 0.35));
|
transform: translateZ(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.strip-cell,
|
.strip-cell,
|
||||||
|
|||||||
Reference in New Issue
Block a user