feat: default split pane to 20%, persist position in cookie
Replaced localStorage with document.cookie (1-year expiry, samesite=lax). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
34848588a8
commit
e6e6c96261
1 changed files with 19 additions and 10 deletions
|
|
@ -3,11 +3,26 @@
|
|||
import { useRef, useState, useEffect, useCallback } from 'react'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const COOKIE_PREFIX = 'split-pane:'
|
||||
const COOKIE_MAX_AGE = 60 * 60 * 24 * 365
|
||||
|
||||
function readSplitCookie(key: string): number | null {
|
||||
if (typeof document === 'undefined') return null
|
||||
const match = document.cookie.match(new RegExp(`(?:^|; )${COOKIE_PREFIX}${key}=([^;]+)`))
|
||||
if (!match) return null
|
||||
const val = parseFloat(decodeURIComponent(match[1]))
|
||||
return !isNaN(val) && val > 0 && val < 100 ? val : null
|
||||
}
|
||||
|
||||
function writeSplitCookie(key: string, value: number) {
|
||||
document.cookie = `${COOKIE_PREFIX}${key}=${value}; max-age=${COOKIE_MAX_AGE}; path=/; samesite=lax`
|
||||
}
|
||||
|
||||
interface SplitPaneProps {
|
||||
left: React.ReactNode
|
||||
right: React.ReactNode
|
||||
storageKey: string
|
||||
defaultSplit?: number // percentage for left pane, default 40
|
||||
defaultSplit?: number // percentage for left pane
|
||||
minSize?: number // minimum px per pane, default 200
|
||||
}
|
||||
|
||||
|
|
@ -15,18 +30,12 @@ export function SplitPane({
|
|||
left,
|
||||
right,
|
||||
storageKey,
|
||||
defaultSplit = 40,
|
||||
defaultSplit = 20,
|
||||
minSize = 200,
|
||||
}: SplitPaneProps) {
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
const [split, setSplit] = useState<number>(() => {
|
||||
if (typeof window === 'undefined') return defaultSplit
|
||||
const stored = localStorage.getItem(`split-pane:${storageKey}`)
|
||||
if (stored) {
|
||||
const val = parseFloat(stored)
|
||||
if (!isNaN(val) && val > 0 && val < 100) return val
|
||||
}
|
||||
return defaultSplit
|
||||
return readSplitCookie(storageKey) ?? defaultSplit
|
||||
})
|
||||
const [isDragging, setIsDragging] = useState(false)
|
||||
const [isMobile, setIsMobile] = useState(false)
|
||||
|
|
@ -49,7 +58,7 @@ export function SplitPane({
|
|||
const maxPct = 100 - minPct
|
||||
const newSplit = Math.min(maxPct, Math.max(minPct, (offsetX / containerWidth) * 100))
|
||||
setSplit(newSplit)
|
||||
localStorage.setItem(`split-pane:${storageKey}`, String(newSplit))
|
||||
writeSplitCookie(storageKey, newSplit)
|
||||
}, [isDragging, minSize, storageKey])
|
||||
|
||||
const onMouseUp = useCallback(() => setIsDragging(false), [])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue