diff --git a/src/assets/main.css b/src/assets/main.css index 79996a0..c889ddc 100644 --- a/src/assets/main.css +++ b/src/assets/main.css @@ -258,9 +258,10 @@ html.platform-macos #root { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); transition: + width 420ms cubic-bezier(0.2, 1.2, 0.26, 1), opacity 200ms ease, - transform 260ms cubic-bezier(0.22, 1, 0.36, 1); - will-change: opacity, transform; + transform 320ms cubic-bezier(0.2, 1.2, 0.26, 1); + will-change: width, opacity, transform; } .ss-immersive-toolbar.is-hidden { diff --git a/src/components/Home.tsx b/src/components/Home.tsx index be0c2fb..a6a1a99 100644 --- a/src/components/Home.tsx +++ b/src/components/Home.tsx @@ -118,6 +118,8 @@ export const Home: React.FC = ({ const groupRefs = useRef>({}) const searchAreaRef = useRef(null) const immersiveToolbarRef = useRef(null) + const immersiveToolbarContentRef = useRef(null) + const [immersiveToolbarWidth, setImmersiveToolbarWidth] = useState(null) const [selectedStudent, setSelectedStudent] = useState(null) const [batchMode, setBatchMode] = useState(false) @@ -321,6 +323,33 @@ export const Home: React.FC = ({ return () => document.removeEventListener("mousedown", onDocumentClick) }, []) + useEffect(() => { + if (!immersiveMode) return + const contentEl = immersiveToolbarContentRef.current + if (!contentEl) return + + let frameId: number | null = null + const updateToolbarWidth = () => { + if (frameId !== null) cancelAnimationFrame(frameId) + frameId = requestAnimationFrame(() => { + const contentWidth = Math.ceil(contentEl.getBoundingClientRect().width) + const nextWidth = contentWidth + 20 + setImmersiveToolbarWidth((prev) => (prev === nextWidth ? prev : nextWidth)) + }) + } + + updateToolbarWidth() + const observer = new ResizeObserver(updateToolbarWidth) + observer.observe(contentEl) + window.addEventListener("resize", updateToolbarWidth) + + return () => { + observer.disconnect() + window.removeEventListener("resize", updateToolbarWidth) + if (frameId !== null) cancelAnimationFrame(frameId) + } + }, [immersiveMode]) + useEffect(() => { return () => { if (longPressTimerRef.current !== null) { @@ -2481,9 +2510,8 @@ export const Home: React.FC = ({ position: "fixed", left: "50%", bottom: isPortraitMode ? "12px" : "16px", - transform: "translateX(-50%)", zIndex: 1100, - width: "max-content", + width: immersiveToolbarWidth ? `${immersiveToolbarWidth}px` : "max-content", maxWidth: "calc(100vw - 20px)", borderRadius: "999px", border: "1px solid color-mix(in srgb, var(--ss-border-color) 80%, transparent)", @@ -2497,7 +2525,10 @@ export const Home: React.FC = ({ }} >
{ + searchAreaRef.current = node + immersiveToolbarContentRef.current = node + }} style={{ display: "flex", alignItems: "center",