From 8b6b73627c61d1db1018d43081a2bf51e6bd0bc1 Mon Sep 17 00:00:00 2001 From: Till JS Date: Wed, 15 Apr 2026 20:37:19 +0200 Subject: [PATCH] feat(page-carousel): five-preset width picker replaces drag handle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PageShell drops the bottom-right drag handle and its pointer/touch tracking entirely, and adds a small header button (ArrowsOutLineHorizontal) that opens a menu with five discrete widths: XS 340 · S 440 · M 540 · L 720 · XL 960. Each entry shows its label and pixel value and highlights whichever one is currently closest to the persisted widthPx — so legacy freehand values (e.g. 823) still light up the nearest entry when the menu first opens. New module width-presets.ts holds the preset array and a nearestPresetIndex() helper so the same snapping logic isn't duplicated between PageShell and the store. Also drops the .page-shell.resizing style (and the `resizing` state, the shellEl ref, and the MIN/MAX width/height constants) that only existed to colour the shell while a drag was active. The five presets cover the useful width range without wasting space on tiny viewport-sized differences; anyone wanting an uncommon width can adjust widthPx directly in Dexie for now. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../components/page-carousel/PageShell.svelte | 215 +++++++++--------- .../components/page-carousel/width-presets.ts | 50 ++++ 2 files changed, 163 insertions(+), 102 deletions(-) create mode 100644 apps/mana/apps/web/src/lib/components/page-carousel/width-presets.ts diff --git a/apps/mana/apps/web/src/lib/components/page-carousel/PageShell.svelte b/apps/mana/apps/web/src/lib/components/page-carousel/PageShell.svelte index 7315a37b1..5910d511d 100644 --- a/apps/mana/apps/web/src/lib/components/page-carousel/PageShell.svelte +++ b/apps/mana/apps/web/src/lib/components/page-carousel/PageShell.svelte @@ -1,22 +1,29 @@ -
+
diff --git a/apps/mana/apps/web/src/lib/components/page-carousel/width-presets.ts b/apps/mana/apps/web/src/lib/components/page-carousel/width-presets.ts new file mode 100644 index 000000000..ffa08bf12 --- /dev/null +++ b/apps/mana/apps/web/src/lib/components/page-carousel/width-presets.ts @@ -0,0 +1,50 @@ +/** + * Five width presets for cards in a PageCarousel. + * + * The workbench used to offer free-form drag-to-resize on both axes. + * Height was near-universally ignored (pages scroll) and width-drag + * produced odd pixel values nobody cared to revisit. Replacing that + * with a small discrete set removes decision fatigue and guarantees + * cards fit the carousel gap + grid cleanly on every viewport. + */ + +export interface PageWidthPreset { + /** Stable identifier stored in the `widthPx` field of WorkbenchSceneApp. */ + widthPx: number; + /** Short label shown in the picker. */ + label: string; + /** Tooltip / aria-label. */ + description: string; +} + +export const PAGE_WIDTH_PRESETS: readonly PageWidthPreset[] = [ + { widthPx: 340, label: 'XS', description: 'Sehr schmal — für Info-Widgets' }, + { widthPx: 440, label: 'S', description: 'Schmal — für Listen' }, + { widthPx: 540, label: 'M', description: 'Normal' }, + { widthPx: 720, label: 'L', description: 'Breit — für Editoren' }, + { widthPx: 960, label: 'XL', description: 'Sehr breit — für Boards' }, +] as const; + +export const DEFAULT_PAGE_WIDTH = 540; + +/** + * Snap an arbitrary pixel value (from a legacy drag-resize row or a + * viewport default) to the nearest preset. Used by the picker to + * highlight the active entry, and as a safety clamp when old Dexie + * rows with `widthPx: 823` need to pick an "active" indicator. + */ +export function nearestPresetIndex(widthPx: number | undefined): number { + if (widthPx === undefined) { + return PAGE_WIDTH_PRESETS.findIndex((p) => p.widthPx === DEFAULT_PAGE_WIDTH); + } + let bestIdx = 0; + let bestDelta = Infinity; + PAGE_WIDTH_PRESETS.forEach((p, i) => { + const delta = Math.abs(p.widthPx - widthPx); + if (delta < bestDelta) { + bestDelta = delta; + bestIdx = i; + } + }); + return bestIdx; +}