mirror of
https://github.com/SECTL/SecScore.git
synced 2026-07-21 13:59:03 +08:00
feat: 增加沉浸模式切换过渡动画
This commit is contained in:
+38
-1
@@ -7,6 +7,8 @@ import { ContentArea } from "./components/ContentArea"
|
|||||||
import { OOBE } from "./components/OOBE/OOBE"
|
import { OOBE } from "./components/OOBE/OOBE"
|
||||||
import { ThemeProvider, useTheme } from "./contexts/ThemeContext"
|
import { ThemeProvider, useTheme } from "./contexts/ThemeContext"
|
||||||
|
|
||||||
|
const IMMERSIVE_TRANSITION_MS = 260
|
||||||
|
|
||||||
function MainContent(): React.JSX.Element {
|
function MainContent(): React.JSX.Element {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
@@ -15,6 +17,8 @@ function MainContent(): React.JSX.Element {
|
|||||||
const [messageApi, contextHolder] = message.useMessage()
|
const [messageApi, contextHolder] = message.useMessage()
|
||||||
const { isIosDevice, isAndroidDevice, defaultPortraitMode } = useMemo(getMobileDeviceInfo, [])
|
const { isIosDevice, isAndroidDevice, defaultPortraitMode } = useMemo(getMobileDeviceInfo, [])
|
||||||
const [immersiveMode, setImmersiveMode] = useState(false)
|
const [immersiveMode, setImmersiveMode] = useState(false)
|
||||||
|
const [sidebarVisible, setSidebarVisible] = useState(true)
|
||||||
|
const sidebarTransitionTimerRef = useRef<number | null>(null)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const api = (window as any).api
|
const api = (window as any).api
|
||||||
@@ -350,6 +354,30 @@ function MainContent(): React.JSX.Element {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (sidebarTransitionTimerRef.current) {
|
||||||
|
window.clearTimeout(sidebarTransitionTimerRef.current)
|
||||||
|
sidebarTransitionTimerRef.current = null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!immersiveMode) {
|
||||||
|
setSidebarVisible(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sidebarTransitionTimerRef.current = window.setTimeout(() => {
|
||||||
|
setSidebarVisible(false)
|
||||||
|
sidebarTransitionTimerRef.current = null
|
||||||
|
}, IMMERSIVE_TRANSITION_MS)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if (sidebarTransitionTimerRef.current) {
|
||||||
|
window.clearTimeout(sidebarTransitionTimerRef.current)
|
||||||
|
sidebarTransitionTimerRef.current = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [immersiveMode])
|
||||||
|
|
||||||
const isDark = currentTheme?.mode === "dark"
|
const isDark = currentTheme?.mode === "dark"
|
||||||
const brandColor = currentTheme?.config?.tdesign?.brandColor || "#0052D9"
|
const brandColor = currentTheme?.config?.tdesign?.brandColor || "#0052D9"
|
||||||
|
|
||||||
@@ -366,7 +394,15 @@ function MainContent(): React.JSX.Element {
|
|||||||
>
|
>
|
||||||
{contextHolder}
|
{contextHolder}
|
||||||
<Layout style={{ height: "100%", flexDirection: "row", overflow: "hidden" }}>
|
<Layout style={{ height: "100%", flexDirection: "row", overflow: "hidden" }}>
|
||||||
{!immersiveMode && (
|
{sidebarVisible && (
|
||||||
|
<div
|
||||||
|
className={`ss-immersive-sidebar ${immersiveMode ? "is-hidden" : "is-visible"}`}
|
||||||
|
style={
|
||||||
|
{
|
||||||
|
"--ss-sidebar-width": `${sidebarCollapsed ? 64 : 200}px`,
|
||||||
|
} as React.CSSProperties
|
||||||
|
}
|
||||||
|
>
|
||||||
<Sidebar
|
<Sidebar
|
||||||
activeMenu={activeMenu}
|
activeMenu={activeMenu}
|
||||||
permission={permission}
|
permission={permission}
|
||||||
@@ -376,6 +412,7 @@ function MainContent(): React.JSX.Element {
|
|||||||
floatingExpanded={floatingSidebarExpanded}
|
floatingExpanded={floatingSidebarExpanded}
|
||||||
onFloatingExpandedChange={setFloatingSidebarExpanded}
|
onFloatingExpandedChange={setFloatingSidebarExpanded}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
<ContentArea
|
<ContentArea
|
||||||
permission={permission}
|
permission={permission}
|
||||||
|
|||||||
@@ -225,3 +225,45 @@ html.platform-macos #root {
|
|||||||
.ss-group-board-modal .ant-modal-body {
|
.ss-group-board-modal .ant-modal-body {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ss-immersive-sidebar {
|
||||||
|
--ss-sidebar-width: 200px;
|
||||||
|
width: var(--ss-sidebar-width);
|
||||||
|
overflow: hidden;
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(0);
|
||||||
|
transition:
|
||||||
|
width 260ms cubic-bezier(0.22, 1, 0.36, 1),
|
||||||
|
opacity 220ms ease,
|
||||||
|
transform 260ms cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
|
will-change: width, opacity, transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ss-immersive-sidebar.is-hidden {
|
||||||
|
width: 0;
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-10px);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ss-immersive-toolbar {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateX(-50%) translateY(0) scale(1);
|
||||||
|
transition:
|
||||||
|
opacity 200ms ease,
|
||||||
|
transform 260ms cubic-bezier(0.22, 1, 0.36, 1);
|
||||||
|
will-change: opacity, transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ss-immersive-toolbar.is-hidden {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateX(-50%) translateY(16px) scale(0.98);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.ss-immersive-sidebar,
|
||||||
|
.ss-immersive-toolbar {
|
||||||
|
transition: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2472,10 +2472,11 @@ export const Home: React.FC<HomeProps> = ({
|
|||||||
)}
|
)}
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
{immersiveMode && (
|
|
||||||
<div
|
<div
|
||||||
ref={immersiveToolbarRef}
|
ref={immersiveToolbarRef}
|
||||||
data-immersive-toolbar="true"
|
data-immersive-toolbar="true"
|
||||||
|
className={`ss-immersive-toolbar ${immersiveMode ? "is-visible" : "is-hidden"}`}
|
||||||
|
aria-hidden={!immersiveMode}
|
||||||
style={{
|
style={{
|
||||||
position: "fixed",
|
position: "fixed",
|
||||||
left: "50%",
|
left: "50%",
|
||||||
@@ -2635,7 +2636,6 @@ export const Home: React.FC<HomeProps> = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
|
|
||||||
{isPortraitMode ? (
|
{isPortraitMode ? (
|
||||||
<Drawer
|
<Drawer
|
||||||
|
|||||||
Reference in New Issue
Block a user