['onMouseLeave']
+ sizeVariableMountPoint?: HTMLElement
}
const MINIMAL_CONTENT_VIEWPORT_WIDTH = 100
const MINIMAL_WIDTH = 240
+function getSafeSize(size: number, width: number) {
+ if (size > width - MINIMAL_CONTENT_VIEWPORT_WIDTH) return width - MINIMAL_CONTENT_VIEWPORT_WIDTH
+ if (size < MINIMAL_WIDTH) return MINIMAL_WIDTH
+ return size
+}
+
export function SideBarBodyWrapper({
baseSize,
className,
children,
onLeave,
+ sizeVariableMountPoint,
}: React.PropsWithChildren
) {
const [size, setSize] = React.useState(baseSize)
const configContext = useConfigs()
@@ -34,27 +41,50 @@ export function SideBarBodyWrapper({
const { width } = useWindowSize()
React.useEffect(() => {
- if (size > width - MINIMAL_CONTENT_VIEWPORT_WIDTH)
- setSize(width - MINIMAL_CONTENT_VIEWPORT_WIDTH)
- else if (size < MINIMAL_WIDTH) setSize(MINIMAL_WIDTH)
+ const safeSize = getSafeSize(size, width)
+ if (safeSize !== size) setSize(safeSize)
}, [width, size])
-
- React.useEffect(() => {
- setResizingState(true)
- const timer = setTimeout(() => setResizingState(false), 100)
- return () => clearTimeout(timer)
- }, [width, size])
-
- useCSSVariable('--gitako-width', `${size}px`)
+ const bodyWrapperRef = React.useRef(null)
useDebounce(() => configContext.onChange({ sideBarWidth: size }), 100, [size])
- const onResize = React.useCallback((size: number) => {
- // do NOT merge this with the above similar effect, side bar will jump otherwise
- if (size > width - MINIMAL_CONTENT_VIEWPORT_WIDTH)
- setSize(width - MINIMAL_CONTENT_VIEWPORT_WIDTH)
- else if (size < MINIMAL_WIDTH) setSize(MINIMAL_WIDTH)
- else setSize(size)
- }, [])
+ function apply(sizeVariableMountPoint: HTMLElement | undefined, size: number) {
+ if (sizeVariableMountPoint)
+ setCSSVariable(
+ '--gitako-width',
+ sizeVariableMountPoint ? `${size}px` : undefined,
+ sizeVariableMountPoint,
+ )
+
+ if (bodyWrapperRef.current)
+ setCSSVariable(
+ '--gitako-width',
+ sizeVariableMountPoint ? undefined : `${size}px`,
+ bodyWrapperRef.current,
+ )
+ }
+
+ // Update size using useEffect would cause delay
+ const onResize = React.useMemo(() => {
+ let sizeToApply: number,
+ applied = true
+ return (size: number) => {
+ // do NOT merge this with the above similar effect, side bar will jump otherwise
+ sizeToApply = getSafeSize(size, width)
+ setSize(sizeToApply)
+
+ if (applied) {
+ applied = false
+ requestAnimationFrame(() => {
+ applied = true
+ apply(sizeVariableMountPoint, sizeToApply)
+ })
+ }
+ }
+ }, [width, sizeVariableMountPoint])
+
+ React.useEffect(() => {
+ apply(sizeVariableMountPoint, size)
+ }, [sizeVariableMountPoint])
const onMouseLeave = React.useCallback(
e => {
@@ -65,7 +95,11 @@ export function SideBarBodyWrapper({
)
return (
-
+
{children}
{features.resize && (