fix: refine mobile workbench sheets

This commit is contained in:
2026-07-27 12:56:03 +08:00
parent f0485ca86e
commit f8c79a2af3
12 changed files with 114 additions and 82 deletions
@@ -6,7 +6,6 @@ import {
type PointerEvent,
type ReactNode
} from "react";
import { X } from "lucide-react";
import { cn } from "@/shared/ui/cn";
import {
getMobileWorkbenchSheetHeight,
@@ -22,11 +21,9 @@ type MobileWorkbenchSheetProps = {
onClose: () => void;
children: ReactNode;
className?: string;
closing?: boolean;
onCloseComplete?: () => void;
};
const SNAP_ORDER: MobileWorkbenchSheetSnap[] = ["peek", "half", "full"];
const SNAP_ORDER: MobileWorkbenchSheetSnap[] = ["half", "full"];
export function MobileWorkbenchSheet({
label,
@@ -34,9 +31,7 @@ export function MobileWorkbenchSheet({
onSnapChange,
onClose,
children,
className,
closing = false,
onCloseComplete
className
}: MobileWorkbenchSheetProps) {
const pointerStartRef = useRef<{ y: number; height: number } | null>(null);
const draggedRef = useRef(false);
@@ -87,7 +82,7 @@ export function MobileWorkbenchSheet({
draggedRef.current = true;
}
const minHeight = getMobileWorkbenchSheetHeight("peek", window.innerHeight);
const minHeight = getMobileWorkbenchSheetHeight("half", window.innerHeight);
const maxHeight = getMobileWorkbenchSheetHeight("full", window.innerHeight);
setDragHeight(Math.min(maxHeight, Math.max(minHeight, start.height + delta)));
}
@@ -134,7 +129,7 @@ export function MobileWorkbenchSheet({
if (event.key === "Home") {
event.preventDefault();
onSnapChange("peek");
onSnapChange("half");
return;
}
@@ -150,17 +145,11 @@ export function MobileWorkbenchSheet({
data-snap={snap}
className={cn(
"mobile-workbench-sheet acrylic-panel pointer-events-auto absolute bottom-0 left-0 right-0 z-40 flex min-h-0 flex-col overflow-hidden rounded-t-[20px] border-x border-t transition-[height] duration-200 ease-[cubic-bezier(0.16,1,0.3,1)] motion-reduce:transition-none lg:hidden",
closing && "pointer-events-none",
className
)}
style={{ height: closing ? 0 : (dragHeight ?? restingHeight) }}
onTransitionEnd={(event) => {
if (closing && event.propertyName === "height" && event.target === event.currentTarget) {
onCloseComplete?.();
}
}}
style={{ height: dragHeight ?? restingHeight }}
>
<div className="relative flex h-7 shrink-0 items-center">
<div className="flex h-7 shrink-0 items-center">
<button
type="button"
aria-label={`${label}高度,当前${getSnapLabel(snap)}`}
@@ -173,14 +162,6 @@ export function MobileWorkbenchSheet({
>
<span className="h-1 w-10 rounded-full bg-slate-400/70 transition-[width,background-color] group-focus-visible:w-12 group-focus-visible:bg-blue-600" />
</button>
<button
type="button"
aria-label={`关闭${label}`}
className="absolute right-2 grid h-7 w-7 place-items-center rounded-lg text-slate-500 transition hover:bg-blue-50 hover:text-blue-700"
onClick={onClose}
>
<X size={15} aria-hidden="true" />
</button>
</div>
<div className="min-h-0 flex-1 overscroll-contain">{children}</div>
</section>
@@ -205,14 +186,10 @@ function getClosestSnap(height: number, viewportHeight: number): MobileWorkbench
getMobileWorkbenchSheetHeight(closest, viewportHeight) - height
);
return candidateDistance < closestDistance ? candidate : closest;
}, "peek");
}, "half");
}
function getSnapLabel(snap: MobileWorkbenchSheetSnap) {
if (snap === "peek") {
return "预览档";
}
if (snap === "half") {
return "半屏档";
}