Compare commits
No commits in common. "cf1b7a792a5efbdfde041eacca75555a54db0662" and "fdb304505353a013dbd0a85627d5fd38c9445127" have entirely different histories.
cf1b7a792a
...
fdb3045053
@ -1021,18 +1021,7 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
|
|||||||
|
|
||||||
.farmcontrol-splitter.ant-splitter-horizontal.is-size-transitioning
|
.farmcontrol-splitter.ant-splitter-horizontal.is-size-transitioning
|
||||||
.ant-splitter-panel {
|
.ant-splitter-panel {
|
||||||
transition:
|
transition: flex-basis 0.15s ease-in-out;
|
||||||
--dashboard-splitter-sidebar-size 0.15s ease-in-out,
|
|
||||||
flex-basis 0.15s ease-in-out,
|
|
||||||
width 0.15s ease-in-out,
|
|
||||||
min-width 0.15s ease-in-out,
|
|
||||||
max-width 0.15s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
@property --dashboard-splitter-sidebar-size {
|
|
||||||
syntax: '<length>';
|
|
||||||
inherits: true;
|
|
||||||
initial-value: 80px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.farmcontrol-splitter
|
.farmcontrol-splitter
|
||||||
@ -1574,13 +1563,3 @@ span.ant-skeleton-input.ant-skeleton-input-sm.text-skeleton {
|
|||||||
.ant-splitter-panel.dashboard-splitter-content-panel {
|
.ant-splitter-panel.dashboard-splitter-content-panel {
|
||||||
flex-grow: 1 !important;
|
flex-grow: 1 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-splitter.farmcontrol-splitter
|
|
||||||
.ant-splitter-panel.dashboard-splitter-sidebar-panel.is-collapsed {
|
|
||||||
flex-grow: 0 !important;
|
|
||||||
flex-shrink: 0 !important;
|
|
||||||
flex-basis: var(--dashboard-splitter-sidebar-size) !important;
|
|
||||||
width: var(--dashboard-splitter-sidebar-size) !important;
|
|
||||||
min-width: var(--dashboard-splitter-sidebar-size) !important;
|
|
||||||
max-width: var(--dashboard-splitter-sidebar-size) !important;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import {
|
|||||||
useEffect,
|
useEffect,
|
||||||
useContext
|
useContext
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import { Layout, Menu, Flex, Button, Divider } from 'antd'
|
import { Layout, Menu, Flex, Button } from 'antd'
|
||||||
import { CaretDownFilled } from '@ant-design/icons'
|
import { CaretDownFilled } from '@ant-design/icons'
|
||||||
import CollapseSidebarIcon from '../../Icons/CollapseSidebarIcon'
|
import CollapseSidebarIcon from '../../Icons/CollapseSidebarIcon'
|
||||||
import ExpandSidebarIcon from '../../Icons/ExpandSidebarIcon'
|
import ExpandSidebarIcon from '../../Icons/ExpandSidebarIcon'
|
||||||
@ -152,18 +152,14 @@ const DashboardSidebar = ({
|
|||||||
_internalDisableMenuItemTitleTooltip
|
_internalDisableMenuItemTitleTooltip
|
||||||
/>
|
/>
|
||||||
</SimpleBar>
|
</SimpleBar>
|
||||||
|
<Flex style={{ padding: '4px', width: '100%' }}>
|
||||||
<Flex vertical style={{ width: '100%' }}>
|
<Button
|
||||||
<Divider style={{ margin: 0 }} />
|
size={isElectron ? 'middle' : 'large'}
|
||||||
<Flex style={{ padding: '4px', width: '100%' }}>
|
type='text'
|
||||||
<Button
|
icon={collapsed ? <ExpandSidebarIcon /> : <CollapseSidebarIcon />}
|
||||||
size={isElectron ? 'middle' : 'large'}
|
style={{ flexGrow: 1 }}
|
||||||
type='text'
|
onClick={() => handleCollapse(!collapsed)}
|
||||||
icon={collapsed ? <ExpandSidebarIcon /> : <CollapseSidebarIcon />}
|
/>
|
||||||
style={{ flexGrow: 1, width: '100%' }}
|
|
||||||
onClick={() => handleCollapse(!collapsed)}
|
|
||||||
/>
|
|
||||||
</Flex>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Sider>
|
</Sider>
|
||||||
|
|||||||
@ -17,8 +17,6 @@ const DEFAULT_SIDEBAR_PX = 300
|
|||||||
const MAX_SIDEBAR_PX = 400
|
const MAX_SIDEBAR_PX = 400
|
||||||
const COLLAPSED_WIDTH_PX = 80
|
const COLLAPSED_WIDTH_PX = 80
|
||||||
const ELECTRON_COLLAPSED_WIDTH_PX = 55
|
const ELECTRON_COLLAPSED_WIDTH_PX = 55
|
||||||
const EXPAND_DRAG_PX = 10
|
|
||||||
const SIZE_TRANSITION_MS = 150
|
|
||||||
const COLLAPSE_STORAGE_KEY = 'DashboardSidebar_collapseState'
|
const COLLAPSE_STORAGE_KEY = 'DashboardSidebar_collapseState'
|
||||||
const SIZE_STORAGE_KEY = 'DashboardSidebar_width'
|
const SIZE_STORAGE_KEY = 'DashboardSidebar_width'
|
||||||
|
|
||||||
@ -68,45 +66,8 @@ const DashboardSidebarSplitter = ({ sidebar, children }) => {
|
|||||||
const lastExpandedSizeRef = useRef(
|
const lastExpandedSizeRef = useRef(
|
||||||
clampExpandedSize(readStoredNumber(SIZE_STORAGE_KEY, DEFAULT_SIDEBAR_PX))
|
clampExpandedSize(readStoredNumber(SIZE_STORAGE_KEY, DEFAULT_SIDEBAR_PX))
|
||||||
)
|
)
|
||||||
const sidebarSizeRef = useRef(sidebarSize)
|
|
||||||
sidebarSizeRef.current = sidebarSize
|
|
||||||
const collapseSizeRafRef = useRef([])
|
|
||||||
const [sizeTransitioning, setSizeTransitioning] = useState(false)
|
const [sizeTransitioning, setSizeTransitioning] = useState(false)
|
||||||
const sizeTransitionTimeoutRef = useRef(null)
|
const sizeTransitionTimeoutRef = useRef(null)
|
||||||
const [resizeLocked, setResizeLocked] = useState(false)
|
|
||||||
const resizeLockedRef = useRef(false)
|
|
||||||
const suppressGestureRef = useRef(false)
|
|
||||||
const lockUntilPointerUpRef = useRef(false)
|
|
||||||
const lockTimeoutRef = useRef(null)
|
|
||||||
const pointerUnlockRef = useRef(null)
|
|
||||||
const ignoreResizeEndRef = useRef(false)
|
|
||||||
|
|
||||||
const setResizeLockedState = useCallback((locked) => {
|
|
||||||
resizeLockedRef.current = locked
|
|
||||||
setResizeLocked(locked)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const clearPointerUnlock = useCallback(() => {
|
|
||||||
if (!pointerUnlockRef.current) return
|
|
||||||
window.removeEventListener('pointerup', pointerUnlockRef.current)
|
|
||||||
window.removeEventListener('pointercancel', pointerUnlockRef.current)
|
|
||||||
pointerUnlockRef.current = null
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const attachPointerUnlock = useCallback(() => {
|
|
||||||
if (pointerUnlockRef.current) return
|
|
||||||
const handler = () => {
|
|
||||||
clearPointerUnlock()
|
|
||||||
suppressGestureRef.current = false
|
|
||||||
if (lockUntilPointerUpRef.current) {
|
|
||||||
lockUntilPointerUpRef.current = false
|
|
||||||
setResizeLockedState(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pointerUnlockRef.current = handler
|
|
||||||
window.addEventListener('pointerup', handler)
|
|
||||||
window.addEventListener('pointercancel', handler)
|
|
||||||
}, [clearPointerUnlock, setResizeLockedState])
|
|
||||||
|
|
||||||
const startSizeTransition = useCallback(() => {
|
const startSizeTransition = useCallback(() => {
|
||||||
setSizeTransitioning(true)
|
setSizeTransitioning(true)
|
||||||
@ -116,69 +77,16 @@ const DashboardSidebarSplitter = ({ sidebar, children }) => {
|
|||||||
sizeTransitionTimeoutRef.current = setTimeout(() => {
|
sizeTransitionTimeoutRef.current = setTimeout(() => {
|
||||||
setSizeTransitioning(false)
|
setSizeTransitioning(false)
|
||||||
sizeTransitionTimeoutRef.current = null
|
sizeTransitionTimeoutRef.current = null
|
||||||
}, SIZE_TRANSITION_MS)
|
}, 150)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const cancelCollapseSizeAnimation = useCallback(() => {
|
|
||||||
collapseSizeRafRef.current.forEach((id) => cancelAnimationFrame(id))
|
|
||||||
collapseSizeRafRef.current = []
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const animateCollapsedSize = useCallback(() => {
|
|
||||||
cancelCollapseSizeAnimation()
|
|
||||||
const ids = []
|
|
||||||
ids.push(
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
ids.push(
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
collapseSizeRafRef.current = []
|
|
||||||
setSidebarSize(collapsedWidth)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
)
|
|
||||||
collapseSizeRafRef.current = ids
|
|
||||||
}, [cancelCollapseSizeAnimation, collapsedWidth])
|
|
||||||
|
|
||||||
const lockResizeUntilPointerUp = useCallback(() => {
|
|
||||||
ignoreResizeEndRef.current = true
|
|
||||||
suppressGestureRef.current = true
|
|
||||||
lockUntilPointerUpRef.current = true
|
|
||||||
setResizeLockedState(true)
|
|
||||||
attachPointerUnlock()
|
|
||||||
}, [attachPointerUnlock, setResizeLockedState])
|
|
||||||
|
|
||||||
const lockResizeFor = useCallback(
|
|
||||||
(ms) => {
|
|
||||||
ignoreResizeEndRef.current = true
|
|
||||||
suppressGestureRef.current = true
|
|
||||||
setResizeLockedState(true)
|
|
||||||
attachPointerUnlock()
|
|
||||||
if (lockTimeoutRef.current) {
|
|
||||||
clearTimeout(lockTimeoutRef.current)
|
|
||||||
}
|
|
||||||
lockTimeoutRef.current = setTimeout(() => {
|
|
||||||
lockTimeoutRef.current = null
|
|
||||||
if (!lockUntilPointerUpRef.current) {
|
|
||||||
setResizeLockedState(false)
|
|
||||||
}
|
|
||||||
}, ms)
|
|
||||||
},
|
|
||||||
[attachPointerUnlock, setResizeLockedState]
|
|
||||||
)
|
|
||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
() => () => {
|
() => () => {
|
||||||
if (sizeTransitionTimeoutRef.current) {
|
if (sizeTransitionTimeoutRef.current) {
|
||||||
clearTimeout(sizeTransitionTimeoutRef.current)
|
clearTimeout(sizeTransitionTimeoutRef.current)
|
||||||
}
|
}
|
||||||
if (lockTimeoutRef.current) {
|
|
||||||
clearTimeout(lockTimeoutRef.current)
|
|
||||||
}
|
|
||||||
cancelCollapseSizeAnimation()
|
|
||||||
clearPointerUnlock()
|
|
||||||
},
|
},
|
||||||
[cancelCollapseSizeAnimation, clearPointerUnlock]
|
[]
|
||||||
)
|
)
|
||||||
|
|
||||||
const persistCollapsed = (nextCollapsed) => {
|
const persistCollapsed = (nextCollapsed) => {
|
||||||
@ -196,17 +104,15 @@ const DashboardSidebarSplitter = ({ sidebar, children }) => {
|
|||||||
persistSize(expandedSize)
|
persistSize(expandedSize)
|
||||||
}
|
}
|
||||||
collapsedRef.current = true
|
collapsedRef.current = true
|
||||||
|
setCollapsed(true)
|
||||||
persistCollapsed(true)
|
persistCollapsed(true)
|
||||||
startSizeTransition()
|
startSizeTransition()
|
||||||
setSidebarSize(sidebarSizeRef.current)
|
setSidebarSize(collapsedWidth)
|
||||||
setCollapsed(true)
|
|
||||||
animateCollapsedSize()
|
|
||||||
},
|
},
|
||||||
[animateCollapsedSize, startSizeTransition]
|
[collapsedWidth, startSizeTransition]
|
||||||
)
|
)
|
||||||
|
|
||||||
const expandSidebar = useCallback(() => {
|
const expandSidebar = useCallback(() => {
|
||||||
cancelCollapseSizeAnimation()
|
|
||||||
collapsedRef.current = false
|
collapsedRef.current = false
|
||||||
setCollapsed(false)
|
setCollapsed(false)
|
||||||
persistCollapsed(false)
|
persistCollapsed(false)
|
||||||
@ -214,7 +120,7 @@ const DashboardSidebarSplitter = ({ sidebar, children }) => {
|
|||||||
setSidebarSize(DEFAULT_SIDEBAR_PX)
|
setSidebarSize(DEFAULT_SIDEBAR_PX)
|
||||||
persistSize(DEFAULT_SIDEBAR_PX)
|
persistSize(DEFAULT_SIDEBAR_PX)
|
||||||
lastExpandedSizeRef.current = DEFAULT_SIDEBAR_PX
|
lastExpandedSizeRef.current = DEFAULT_SIDEBAR_PX
|
||||||
}, [cancelCollapseSizeAnimation, startSizeTransition])
|
}, [startSizeTransition])
|
||||||
|
|
||||||
const handleSidebarCollapse = useCallback(
|
const handleSidebarCollapse = useCallback(
|
||||||
(nextCollapsed) => {
|
(nextCollapsed) => {
|
||||||
@ -223,79 +129,33 @@ const DashboardSidebarSplitter = ({ sidebar, children }) => {
|
|||||||
} else {
|
} else {
|
||||||
expandSidebar()
|
expandSidebar()
|
||||||
}
|
}
|
||||||
lockResizeFor(SIZE_TRANSITION_MS)
|
|
||||||
},
|
},
|
||||||
[collapseSidebar, expandSidebar, lockResizeFor, sidebarSize]
|
[collapseSidebar, expandSidebar, sidebarSize]
|
||||||
)
|
)
|
||||||
|
|
||||||
const handleResizeStart = useCallback(() => {
|
|
||||||
if (!resizeLockedRef.current) {
|
|
||||||
ignoreResizeEndRef.current = false
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const handleResize = useCallback(
|
const handleResize = useCallback(
|
||||||
(sizes) => {
|
(sizes) => {
|
||||||
if (resizeLockedRef.current || suppressGestureRef.current) {
|
if (collapsedRef.current) {
|
||||||
if (collapsedRef.current) {
|
setSidebarSize(collapsedWidth)
|
||||||
setSidebarSize(collapsedWidth)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const size = sizes[0]
|
const size = sizes[0]
|
||||||
|
|
||||||
if (collapsedRef.current) {
|
|
||||||
if (size - collapsedWidth > EXPAND_DRAG_PX) {
|
|
||||||
expandSidebar()
|
|
||||||
lockResizeUntilPointerUp()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
setSidebarSize(Math.max(collapsedWidth, size))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size < COLLAPSE_BELOW_PX) {
|
if (size < COLLAPSE_BELOW_PX) {
|
||||||
collapseSidebar(lastExpandedSizeRef.current)
|
collapseSidebar(lastExpandedSizeRef.current)
|
||||||
lockResizeUntilPointerUp()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
setSidebarSize(size)
|
setSidebarSize(size)
|
||||||
lastExpandedSizeRef.current = clampExpandedSize(size)
|
lastExpandedSizeRef.current = clampExpandedSize(size)
|
||||||
},
|
},
|
||||||
[
|
[collapseSidebar, collapsedWidth]
|
||||||
collapseSidebar,
|
|
||||||
collapsedWidth,
|
|
||||||
expandSidebar,
|
|
||||||
lockResizeFor,
|
|
||||||
lockResizeUntilPointerUp
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const handleResizeEnd = useCallback(
|
const handleResizeEnd = useCallback(
|
||||||
(sizes) => {
|
(sizes) => {
|
||||||
if (
|
|
||||||
resizeLockedRef.current ||
|
|
||||||
suppressGestureRef.current ||
|
|
||||||
ignoreResizeEndRef.current
|
|
||||||
) {
|
|
||||||
ignoreResizeEndRef.current = false
|
|
||||||
if (collapsedRef.current) {
|
|
||||||
startSizeTransition()
|
|
||||||
setSidebarSize(collapsedWidth)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (collapsedRef.current) {
|
if (collapsedRef.current) {
|
||||||
if (sizes[0] - collapsedWidth > EXPAND_DRAG_PX) {
|
setSidebarSize(collapsedWidth)
|
||||||
expandSidebar()
|
|
||||||
lockResizeFor(SIZE_TRANSITION_MS)
|
|
||||||
} else {
|
|
||||||
startSizeTransition()
|
|
||||||
setSidebarSize(collapsedWidth)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,7 +164,7 @@ const DashboardSidebarSplitter = ({ sidebar, children }) => {
|
|||||||
setSidebarSize(next)
|
setSidebarSize(next)
|
||||||
persistSize(next)
|
persistSize(next)
|
||||||
},
|
},
|
||||||
[collapsedWidth, expandSidebar, lockResizeFor, startSizeTransition]
|
[collapsedWidth]
|
||||||
)
|
)
|
||||||
|
|
||||||
const sidebarNode = isValidElement(sidebar)
|
const sidebarNode = isValidElement(sidebar)
|
||||||
@ -329,27 +189,21 @@ const DashboardSidebarSplitter = ({ sidebar, children }) => {
|
|||||||
<Splitter
|
<Splitter
|
||||||
className={`farmcontrol-splitter dashboard-splitter${
|
className={`farmcontrol-splitter dashboard-splitter${
|
||||||
sizeTransitioning ? ' is-size-transitioning' : ''
|
sizeTransitioning ? ' is-size-transitioning' : ''
|
||||||
}${collapsed ? ' is-sidebar-collapsed' : ''}`}
|
}`}
|
||||||
style={{ height: '100%' }}
|
style={{ height: '100%' }}
|
||||||
onResizeStart={handleResizeStart}
|
|
||||||
onResize={handleResize}
|
onResize={handleResize}
|
||||||
onResizeEnd={handleResizeEnd}
|
onResizeEnd={handleResizeEnd}
|
||||||
>
|
>
|
||||||
<Splitter.Panel
|
<Splitter.Panel
|
||||||
className={`dashboard-splitter-sidebar-panel${
|
|
||||||
collapsed ? ' is-collapsed' : ''
|
|
||||||
}`}
|
|
||||||
size={sidebarSize}
|
size={sidebarSize}
|
||||||
min={collapsedWidth}
|
min={collapsedWidth}
|
||||||
max={
|
max={collapsed ? collapsedWidth : MAX_SIDEBAR_PX}
|
||||||
collapsed && resizeLocked && !sizeTransitioning
|
resizable={!collapsed}
|
||||||
? collapsedWidth
|
|
||||||
: MAX_SIDEBAR_PX
|
|
||||||
}
|
|
||||||
resizable={!resizeLocked}
|
|
||||||
style={{
|
style={{
|
||||||
overflow: 'visible',
|
overflow: 'visible',
|
||||||
'--dashboard-splitter-sidebar-size': `${sidebarSize}px`
|
minWidth: collapsedWidth,
|
||||||
|
maxWidth:
|
||||||
|
collapsed && !sizeTransitioning ? collapsedWidth : undefined
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{sidebarNode}
|
{sidebarNode}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user