feat(web): user-selectable density mode (compact/comfortable) #48
Reference in New Issue
Block a user
Delete Branch "ui-density-mode"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #17, closes #18, closes #19, closes #20, closes #21
Summary
Adds a density toggle to the AppShell header that switches the entire UI between comfortable (default) and compact modes. The preference is persisted in localStorage.
Architecture
CSS custom properties (
--d-*variables) defined intheme.cssunder[data-density="comfortable"]and[data-density="compact"]selectors. Components reference these viavar(--d-*)in inline styles — toggling thedata-densityattribute on<html>flips everything instantly with zero React re-renders.Changes
New files
web/src/hooks/useDensity.ts— hook wrappinguseLocalStorage+ DOM attribute syncweb/src/components/PageFooter.tsx— shared fixed footer with stats (left) and pagination (right)Deleted
web/src/components/items/FooterStats.tsx— replaced by PageFooterModified
theme.css— 24 density CSS custom properties (comfortable + compact blocks)main.tsx— FOUC prevention: sync density from localStorage before first paintAppShell.tsx— flex-column layout (eliminatescalc(100vh - 64px)hack), all spacing usesvar(--d-*), density toggle button (COM/CMP)ItemsPage.tsx— inline pagination replaced by PageFooter, height: 100%AuditPage.tsx— sameItemTable.tsx— th/td padding and font use density varsAuditTable.tsx— sameItemsToolbar.tsx— container gap/padding, input/select/button sizes use density varsAuditToolbar.tsx— sameWhat changed visually
Even in comfortable mode, the UI is tighter than before (e.g., header padding 16px -> 10px, toolbar gap 12px -> 8px). Compact mode reduces further (header 5.6px, toolbar 5.6px, table cell padding halved).