From daab4433c2c94c21989b3a95e607da849c459e4a Mon Sep 17 00:00:00 2001 From: SandObserver <260779319+SandObserver@users.noreply.github.com> Date: Wed, 14 Oct 2026 21:51:05 -0400 Subject: [PATCH] Make large and extra large widgets fill the desktop rows they span --- ui/css/dashboard.css | 1 + ui/index.html | 4 ++-- ui/js/dashboard.js | 9 ++++++--- ui/js/ui.js | 2 +- ui/js/widget-types.js | 2 +- ui/test/widget-types.test.mjs | 8 ++++++++ 6 files changed, 19 insertions(+), 7 deletions(-) diff --git a/ui/css/dashboard.css b/ui/css/dashboard.css index 77507708..abe272f4 100644 --- a/ui/css/dashboard.css +++ b/ui/css/dashboard.css @@ -138,6 +138,7 @@ literally in the source and a scan for one will not find it. */ .c1 { grid-column:span 1 } .c2 { grid-column:span 2 } + .r2, .r3 { align-self:stretch } .r2 { grid-row:span 2 } .r3 { grid-row:span 3 } diff --git a/ui/index.html b/ui/index.html index 99c0749c..9dc92657 100644 --- a/ui/index.html +++ b/ui/index.html @@ -26,7 +26,7 @@ Stackyard - + @@ -56,5 +56,5 @@ - + diff --git a/ui/js/dashboard.js b/ui/js/dashboard.js index b15a94c1..81280db6 100644 --- a/ui/js/dashboard.js +++ b/ui/js/dashboard.js @@ -8,7 +8,7 @@ import { cardPreset, fixedAppearance, uniqueTitle, -} from '/js/widget-types.js?v=9264dee5'; +} from '/js/widget-types.js?v=b0e8f76d'; import { el, ICON_R, @@ -46,7 +46,7 @@ import { buildMobile, resetMobileChrome, mkFolderGlyph, -} from '/js/ui.js?v=3c85d5d7'; +} from '/js/ui.js?v=d648c39b'; import { badgeMinimum, badgeSignature, computeBadgeVisual, readBadgeUpdate } from '/js/badge-logic.js?v=9e6d9d4b'; import { formatNumber } from '/js/format-number.js?v=349a741d'; import { closeBadgePopover, wireBadgePopover } from '/js/badge-popover.js?v=1e0ab5d1'; @@ -343,7 +343,10 @@ function mkWidget(item) { if (preset) card.dataset.card = preset; if (fixedAppearance(item, widgetReg)) card.dataset.appearance = 'dark'; const design = WIDGET_DESIGN[sz] || WIDGET_DESIGN.medium; - card.style.height = WH.d[sz] + 'px'; + if (wRows.d[sz] >= 2) { + card.style.minHeight = WH.d[sz] + 'px'; + card.style.height = '100%'; + } else card.style.height = WH.d[sz] + 'px'; card.style.borderRadius = WIDGET_R + 'px'; mountScaledWidget(card, { src: widgetSrc(item, widgetReg, { lang: currentLang() }), diff --git a/ui/js/ui.js b/ui/js/ui.js index f6983414..12f98b03 100644 --- a/ui/js/ui.js +++ b/ui/js/ui.js @@ -1,5 +1,5 @@ import { iconChain } from '/js/icons.js?v=9c7b5111'; -import { widgetSrc, cardPreset, fixedAppearance, uniqueTitle, WIDGET_DESIGN } from '/js/widget-types.js?v=9264dee5'; +import { widgetSrc, cardPreset, fixedAppearance, uniqueTitle, WIDGET_DESIGN } from '/js/widget-types.js?v=b0e8f76d'; import { mk, clr, diff --git a/ui/js/widget-types.js b/ui/js/widget-types.js index bd66c0e4..b00d1ca0 100644 --- a/ui/js/widget-types.js +++ b/ui/js/widget-types.js @@ -1,7 +1,7 @@ // @ts-check /* Layout geometry, keyed by widget family size, never by widget. */ -export const WIDGET_HEIGHTS = { small: 150, medium: 150, large: 304, xlarge: 456 }; +export const WIDGET_HEIGHTS = { small: 150, medium: 150, large: 330, xlarge: 510 }; /* The fixed design canvas per family, in px. Widgets render at these dimensions and are scaled to fit the card. */ export const WIDGET_DESIGN = { small: [170, 170], medium: [360, 170], large: [360, 360], xlarge: [360, 540] }; diff --git a/ui/test/widget-types.test.mjs b/ui/test/widget-types.test.mjs index b9b209dc..a883fdf4 100644 --- a/ui/test/widget-types.test.mjs +++ b/ui/test/widget-types.test.mjs @@ -164,3 +164,11 @@ test('cardPreset ignores an unknown name and an unknown widget', () => { assert.equal(cardPreset({ widgetType: 'nope' }, CARD_REG), ''); assert.equal(cardPreset({}, CARD_REG), ''); }); + +test('a widget over several desktop rows is as tall as those rows and the gaps between them', () => { + const ROW_GAP = 30; + for (const sz of Object.keys(WIDGET_HEIGHTS)) { + const rows = WIDGET_ROWS.desktop[sz] || 1; + assert.equal(WIDGET_HEIGHTS[sz], rows * WIDGET_HEIGHTS.small + (rows - 1) * ROW_GAP, sz); + } +});