feat: add resizable desktop panes
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { clampDesktopPaneWidth, getDesktopPaneMax, readDesktopPaneWidth, writeDesktopPaneWidth } from './desktop-shell-resize'
|
||||
|
||||
describe('desktop shell resize', () => {
|
||||
it('clamps the sidebar while preserving the center and detail panes', () => {
|
||||
expect(clampDesktopPaneWidth('sidebar', 120, 1440, 350)).toBe(190)
|
||||
expect(clampDesktopPaneWidth('sidebar', 500, 1440, 350)).toBe(360)
|
||||
expect(clampDesktopPaneWidth('sidebar', 360, 931, 350)).toBe(251)
|
||||
})
|
||||
|
||||
it('clamps the detail pane while preserving the center and sidebar panes', () => {
|
||||
expect(clampDesktopPaneWidth('detail', 240, 1440, 236)).toBe(300)
|
||||
expect(clampDesktopPaneWidth('detail', 600, 1440, 236)).toBe(520)
|
||||
expect(clampDesktopPaneWidth('detail', 520, 931, 236)).toBe(365)
|
||||
})
|
||||
|
||||
it('reports the effective maximum at narrow desktop widths', () => {
|
||||
expect(getDesktopPaneMax('sidebar', 931, 350)).toBe(251)
|
||||
expect(getDesktopPaneMax('detail', 931, 236)).toBe(365)
|
||||
expect(getDesktopPaneMax('detail', 1440, 236)).toBe(520)
|
||||
})
|
||||
|
||||
it('restores only finite persisted widths', () => {
|
||||
const storage = { getItem: (key: string) => key.endsWith('sidebar') ? '288' : 'oops' }
|
||||
expect(readDesktopPaneWidth(storage, 'dodo.desktop.sidebar', 236)).toBe(288)
|
||||
expect(readDesktopPaneWidth(storage, 'dodo.desktop.detail', 350)).toBe(350)
|
||||
expect(readDesktopPaneWidth({ getItem: () => { throw new Error('blocked') } }, 'key', 236)).toBe(236)
|
||||
})
|
||||
|
||||
it('ignores storage write failures', () => {
|
||||
expect(() => writeDesktopPaneWidth({ setItem: () => { throw new Error('blocked') } }, 'key', 300)).not.toThrow()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,31 @@
|
||||
export type DesktopPane = 'sidebar' | 'detail'
|
||||
|
||||
const SIDEBAR_MIN = 190
|
||||
const SIDEBAR_MAX = 360
|
||||
const DETAIL_MIN = 300
|
||||
const DETAIL_MAX = 520
|
||||
const CENTER_MIN = 330
|
||||
|
||||
export function getDesktopPaneMax(pane: DesktopPane, viewportWidth: number, otherPaneWidth: number) {
|
||||
const lower = pane === 'sidebar' ? SIDEBAR_MIN : DETAIL_MIN
|
||||
const upper = pane === 'sidebar' ? SIDEBAR_MAX : DETAIL_MAX
|
||||
return Math.round(Math.min(upper, Math.max(lower, viewportWidth - otherPaneWidth - CENTER_MIN)))
|
||||
}
|
||||
|
||||
export function clampDesktopPaneWidth(pane: DesktopPane, width: number, viewportWidth: number, otherPaneWidth: number) {
|
||||
const lower = pane === 'sidebar' ? SIDEBAR_MIN : DETAIL_MIN
|
||||
return Math.round(Math.min(Math.max(width, lower), getDesktopPaneMax(pane, viewportWidth, otherPaneWidth)))
|
||||
}
|
||||
|
||||
export function readDesktopPaneWidth(storage: Pick<Storage, 'getItem'>, key: string, fallback: number) {
|
||||
try {
|
||||
const value = Number(storage.getItem(key))
|
||||
return Number.isFinite(value) && value > 0 ? value : fallback
|
||||
} catch {
|
||||
return fallback
|
||||
}
|
||||
}
|
||||
|
||||
export function writeDesktopPaneWidth(storage: Pick<Storage, 'setItem'>, key: string, width: number) {
|
||||
try { storage.setItem(key, String(width)) } catch { /* storage can be unavailable */ }
|
||||
}
|
||||
Reference in New Issue
Block a user