Add resizable panes with drag handles, min widths, and persistence

This commit is contained in:
2026-06-05 10:46:07 +03:00
parent 411bfbc6c2
commit c50f141d57
11 changed files with 482 additions and 25 deletions
+35
View File
@@ -0,0 +1,35 @@
/**
* Pane-layout orchestration — bridges the (browser-free) PanesStore to the
* ux-prefs adapter. Same store↔adapter pattern as theme/preferences.
*
* `initPanes` hydrates persisted widths into the store before render. `wirePanes`
* persists changes, **debounced**, because a drag emits a width update on every
* pointer move — writing localStorage on each would thrash. The debounce settles
* the write to the final resting widths (the same approach as snippet auto-save).
*/
import { loadPanelLayout, savePanelLayout } from '../infrastructure/ux-prefs';
import { usePanesStore } from '../stores/PanesStore';
/** Delay before a settled resize is persisted. */
export const PANES_PERSIST_DEBOUNCE_MS = 300;
/** Hydrate persisted pane widths into the store. Call before render. */
export function initPanes(): void {
usePanesStore.getState().hydrate(loadPanelLayout());
}
/** Persist width changes (debounced). Returns a teardown that detaches the subscriber. */
export function wirePanes(): () => void {
let timer: ReturnType<typeof setTimeout> | undefined;
return usePanesStore.subscribe((state, prev) => {
if (state.libraryWidth === prev.libraryWidth && state.previewWidth === prev.previewWidth) {
return;
}
clearTimeout(timer);
timer = setTimeout(() => {
const { libraryWidth, previewWidth } = usePanesStore.getState();
savePanelLayout({ libraryWidth, previewWidth });
}, PANES_PERSIST_DEBOUNCE_MS);
});
}