How the Multi-Panel Layout System Manages State and Rendering in Lifetrace
The multi-panel layout system in Lifetrace uses a centralized Zustand store (useUiStore) to track panel visibility, widths, and feature mappings, while the PanelRegion component handles responsive rendering calculations and conditional panel display based on window dimensions.
The Lifetrace UI implements a dynamic three-panel layout capable of displaying one, two, or three panels depending on window width, user interactions, and feature configuration. All state management is centralized in a persisted Zustand store, with rendering logic encapsulated in the PanelRegion component to ensure reactive updates and layout consistency.
Centralized State Management with Zustand
All layout state lives in useUiStore, defined in free-todo-frontend/lib/store/ui-store/store.ts. The store maintains a single source of truth for panel geometry, content assignment, and interaction constraints.
Core State Fields
The store tracks several categories of layout state:
- Panel visibility:
isPanelAOpen,isPanelBOpen, andisPanelCOpencontrol whether each slot (panelA,panelB,panelC) is rendered. - Panel dimensions:
panelAWidthandpanelCWidthstore relative widths for the left and right panels (the middle panel width is derived mathematically). These values are constrained byMIN_PANEL_WIDTH(0.2) andMAX_PANEL_WIDTH(0.8) as defined infree-todo-frontend/lib/store/ui-store/utils.ts【utils.ts†L15-L20】. - Feature mapping:
panelFeatureMapdetermines which feature (e.g.,todos,chat) occupies each slot【store.ts†L23-L25】. - Pinning and disabling:
panelPinMap,disabledFeatures, andbackendDisabledFeaturesprevent unwanted swaps or hide specific features【store.ts†L25-L31】. - Auto-close tracking:
autoClosedPanelsmaintains a stack of panels automatically hidden (e.g., when a modal opens) so they can be restored later【store.ts†L29-L33】.
Store Actions and Persistence
The store exposes specific methods for layout manipulation:
togglePanelA(),togglePanelB(),togglePanelC()– Flip the open state of individual panels.setPanelAWidth()/setPanelCWidth()– Update panel widths with automatic clamping to the safe range.setPanelFeature()– Assign a feature to a slot while respecting pinning and disabling rules.swapPanelPositions()– Exchange features and open-state between two slots, aborting if either slot is pinned【store.ts†L97-L55】.setAutoClosePanel()/restoreAutoClosedPanel()– Push and pop panels on the auto-close stack【store.ts†L57-L84】.
The store is persisted using Zustand's persist middleware with the storage key "ui-panel-config", ensuring layout preferences survive page reloads.
Rendering Logic in PanelRegion
The PanelRegion component in free-todo-frontend/components/layout/PanelRegion.tsx serves as the top-level layout container, translating store state into visible UI.
Responsive Width Calculations
PanelRegion pulls state from the store and determines visibility based on window dimensions:
const { isPanelAOpen, isPanelBOpen, isPanelCOpen, panelAWidth, panelCWidth } = useUiStore();
const shouldShowPanelB = mounted ? width >= 800 : false;
const shouldShowPanelC = mounted ? width >= 1200 : false;
These width thresholds (800px for the middle panel, 1200px for the right panel) define how many slots are allowed by the current viewport. A slot renders only when both the store flag (isPanelXOpen) and the responsive rule (shouldShowPanelX) are true.
Layout State Computation
The component derives a layoutState object using useMemo to calculate exact widths for every visible panel combination:
const layoutState = useMemo(() => {
if (!showPanelA && !showPanelB && !showPanelC) {
return { panelAWidth: 0, panelBWidth: 1, panelCWidth: 0 };
}
// Algorithm handles single, double, and triple panel configurations
// with clamping to [0.1, 0.9] safe band
}, [showPanelA, showPanelB, showPanelC, panelAWidth]);
This computation handles all panel combinations (single, double, or triple) and ensures widths remain within safe boundaries.
Panel Rendering and Resize Handles
The component conditionally renders PanelContainer elements for visible slots, passing calculated widths and drag states:
{showPanelA && (
<PanelContainer width={layoutState.panelAWidth} position="panelA">
<PanelContent position="panelA" />
</PanelContainer>
)}
{showPanelA && showPanelB && <ResizeHandle position="betweenAAndB" />}
ResizeHandle components appear only when adjacent panel pairs exist. The actual feature UI is rendered by PanelContent, which looks up the assigned feature via getFeatureByPosition using the panelFeatureMap state.
Layout Stability Measures
To prevent visual jitter, PanelRegion uses useLayoutEffect with double requestAnimationFrame to apply !important height styles to the Panels container and BottomDock after React finishes painting【PanelRegion.tsx†L14-L30, 33-L49】.
Feature-to-Panel Mapping
The PanelContent component in free-todo-frontend/components/layout/PanelContent.tsx receives a position prop ("panelA", "panelB", or "panelC") and resolves the feature to render:
const { getFeatureByPosition, panelFeatureMap } = useUiStore();
const assignedFeature = mounted ? panelFeatureMap[position] : null;
If a feature is assigned and not disabled, the component renders the feature-specific UI (e.g., Todo list, Chat view). The mapping between feature names and icons is declared in free-todo-frontend/lib/config/panel-config.ts within the FEATURE_ICON_MAP constant.
State Persistence and Layout Survival
Because the store uses Zustand's persist middleware with the configuration { name: "ui-panel-config", storage: createJSONStorage(() => localStorage) }, all layout state—including open/close flags, custom widths, and feature assignments—survives browser refreshes. When the application reloads, useUiStore rehydrates from storage, and PanelRegion immediately renders the restored layout without additional API calls.
Summary
- Centralized state: All multi-panel layout state lives in the persisted Zustand store
useUiStore, including visibility flags, width ratios, and feature mappings. - Responsive constraints:
PanelRegionenforces viewport-based limits (800px and 1200px breakpoints) to determine how many panels can display simultaneously. - Immutable calculations: Layout widths are computed via
useMemoinPanelRegion, handling all panel combinations while clamping to safe ranges defined inutils.ts. - Feature abstraction:
PanelContentresolves which UI component to render based on thepanelFeatureMapstate, keeping layout logic separate from feature implementation. - Auto-close stack: The system tracks automatically closed panels in
autoClosedPanels, enabling restoration when modal overlays or temporary states conclude.
Frequently Asked Questions
How does the layout handle window resizing?
The PanelRegion component receives width and height props from the parent page. It calculates shouldShowPanelB and shouldShowPanelC based on hardcoded breakpoints (800px and 1200px). These boolean values combine with the store's open flags (isPanelAOpen, etc.) to determine final visibility. When the window shrinks below a threshold, panels automatically hide without modifying the store state, preserving user preferences for when the window expands again.
What prevents panels from becoming too narrow or too wide?
The store uses the clampWidth utility defined in free-todo-frontend/lib/store/ui-store/utils.ts to constrain all width values between MIN_PANEL_WIDTH (0.2 or 20%) and MAX_PANEL_WIDTH (0.8 or 80%). When users resize panels via drag handles or when setPanelAWidth is called programmatically, the value is clamped before storage. Additionally, PanelRegion enforces a secondary [0.1, 0.9] safe band during layout calculations to prevent edge-case rendering issues.
How does panel swapping work when features are pinned?
The swapPanelPositions action in free-todo-frontend/lib/store/ui-store/store.ts exchanges features and open-state between two slots. Before executing the swap, it checks panelPinMap to verify that neither source nor target position is pinned. If either slot is pinned, the operation aborts silently. This ensures critical panels (like persistent navigation or active tools) remain locked in their assigned positions regardless of user interactions with other panels.
What happens to panel state when a modal opens?
When a modal or overlay requires additional screen real estate, the system calls setAutoClosePanel() with the panel identifier (e.g., 'panelC'). This pushes the panel onto the autoClosedPanels stack and sets its open flag to false, hiding it immediately. When the modal closes, restoreAutoClosedPanel() pops the stack and reopens the panels in reverse order of closing. This stack-based approach handles nested modals correctly, ensuring the UI returns to its exact previous state.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →