From 9ce0b49054938e684f853260f8c5b8f917ebadb5 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Thu, 9 Jul 2026 21:19:40 -0700 Subject: [PATCH] FN-7752: tighten mobile Settings modal layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Squashes FN-7752, improving the mobile Settings modal layout to reduce chrome and simplify section navigation on small screens. - Replace the mobile section-picker button row with a compact dropdown-only selector, keeping an accessible aria-label - Slim down the header and footer, collapsing footer actions to a single row on mobile - Tighten SettingsModal.css breakpoint rules (≤768px) for header/footer sizing and spacing - Update settings-mobile tests to cover the new dropdown-only picker and single-row footer behavior - Add changeset documenting the mobile layout fix Files changed: .changeset/fn-7752-mobile-settings-layout.md | 7 +++ .../dashboard/app/components/SettingsModal.css | 62 ++++++++++++++++------ .../dashboard/app/components/SettingsModal.tsx | 19 +++++-- .../components/__tests__/settings-mobile.test.tsx | 26 +++++++-- 4 files changed, 90 insertions(+), 24 deletions(-) Fusion-Task-Id: FN-7752 Fusion-Task-Lineage: 5dea597c-19f7-49c4-979a-7528d84fa6c5 Co-authored-by: Fusion (runfusion.ai) --- .changeset/fn-7752-mobile-settings-layout.md | 7 +++ .../app/components/SettingsModal.css | 62 ++++++++++++++----- .../app/components/SettingsModal.tsx | 19 ++++-- .../__tests__/settings-mobile.test.tsx | 26 ++++++-- 4 files changed, 90 insertions(+), 24 deletions(-) create mode 100644 .changeset/fn-7752-mobile-settings-layout.md diff --git a/.changeset/fn-7752-mobile-settings-layout.md b/.changeset/fn-7752-mobile-settings-layout.md new file mode 100644 index 0000000000..d97e92fd98 --- /dev/null +++ b/.changeset/fn-7752-mobile-settings-layout.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Tighten the mobile Settings layout — dropdown-only section picker, single-row footer, and slimmer header/footer. +category: fix +dev: SettingsModal mobile (≤768px) CSS/JSX only; section-picker label removed, aria-label preserves accessible name. diff --git a/packages/dashboard/app/components/SettingsModal.css b/packages/dashboard/app/components/SettingsModal.css index 134d9753f5..57161eec41 100644 --- a/packages/dashboard/app/components/SettingsModal.css +++ b/packages/dashboard/app/components/SettingsModal.css @@ -243,6 +243,20 @@ The embedded title reads like other embedded-view titles (Planning modal-header- edge, after the Star/Discord actions, without displacing them. Desktop/tablet embedded and the standalone modal presentation are untouched by this rule (scoped to .settings-modal--embedded .modal-header--embedded). */ + /* + FNXC:Settings 2026-07-09-00:00: + FN-7752 makes the mobile Settings header and footer shorter at ≤768px only. Keep the FN-4375 one-line header invariant while trimming vertical padding in both standalone modal and embedded SettingsView presentations. + */ + .settings-modal .modal-header, + .settings-modal .modal-actions { + padding-block: var(--space-sm); + padding-inline: var(--space-md); + } + + .settings-modal--embedded .modal-header--embedded { + min-height: 0; + } + .settings-modal--embedded .modal-header--embedded .settings-embedded-mobile-close { --settings-embedded-mobile-close-touch-target: calc(var(--space-lg) + var(--space-lg) + var(--space-xs)); @@ -287,21 +301,41 @@ The embedded title reads like other embedded-view titles (Planning modal-header- } @media (max-width: 768px) { + /* + FNXC:Settings 2026-07-09-00:00: + FN-7752 requires the mobile Settings footer to remain a single horizontal row in both standalone and embedded presentations. Keep Version/Help, Export/Import/Reset, and Cancel/Save on one nowrap rail that can scroll horizontally instead of stacking into multiple rows. + */ + .settings-modal .modal-actions { + flex-wrap: nowrap; + align-items: center; + gap: var(--space-xs); + overflow-x: auto; + overflow-y: hidden; + } + + .settings-modal .modal-actions-left, + .settings-modal .modal-actions-right { + flex-shrink: 0; + gap: var(--space-xs); + } + .settings-modal-footer-version { - flex: 1 1 100%; + flex: 0 1 auto; margin-right: 0; } .settings-update-check { - flex-wrap: wrap; - row-gap: var(--space-xs); + flex-wrap: nowrap; + row-gap: 0; } .settings-update-result { - flex: 1 1 100%; + flex: 0 1 auto; + white-space: nowrap; } - .settings-footer-help-btn { + .settings-footer-help-btn, + .settings-version-check-btn { flex-shrink: 0; } } @@ -2214,21 +2248,19 @@ The header row wraps so the badge drops below the heading on narrow widths inste font-size: 16px; } + /* + FNXC:Settings 2026-07-09-00:00: + FN-7752 trims mobile-only Settings section chrome: after removing the visible picker label, use smaller horizontal padding for the picker and internal section text so narrow viewports devote more width to controls without changing desktop/tablet rules. + */ .settings-mobile-section-picker { display: flex; flex-direction: column; gap: var(--space-xs); - padding: var(--space-sm) var(--space-lg) var(--space-md); + padding: var(--space-sm) var(--space-md) var(--space-md); border-bottom: none; background: var(--surface); } - .settings-mobile-section-picker label { - color: var(--text-muted); - font-weight: 600; - text-transform: uppercase; - } - .settings-mobile-section-picker-control-row { display: flex; align-items: center; @@ -2320,7 +2352,7 @@ The header row wraps so the badge drops below the heading on narrow widths inste } .settings-section-heading { - padding: var(--space-lg) var(--space-lg) var(--space-md); + padding: var(--space-lg) var(--space-md) var(--space-md); margin: 0 0 var(--space-md); } @@ -2345,7 +2377,7 @@ The header row wraps so the badge drops below the heading on narrow widths inste } .settings-scope-banner { - padding: var(--space-sm) var(--space-lg); + padding: var(--space-sm) var(--space-md); } .memory-editor-frame { @@ -2371,7 +2403,7 @@ The header row wraps so the badge drops below the heading on narrow widths inste } .settings-description { - padding: 0 var(--space-lg); + padding: 0 var(--space-md); } .settings-model-lane-actions { diff --git a/packages/dashboard/app/components/SettingsModal.tsx b/packages/dashboard/app/components/SettingsModal.tsx index 55f018554b..3c8f437413 100644 --- a/packages/dashboard/app/components/SettingsModal.tsx +++ b/packages/dashboard/app/components/SettingsModal.tsx @@ -967,10 +967,15 @@ export function SettingsModal({ const [activePluginsSubsection, setActivePluginsSubsection] = useState(() => initialSection === "pi-extensions" ? "pi-extensions" : "fusion-plugins", ); + /* + FNXC:Settings 2026-07-09-00:00: + Mobile Settings navigation is controlled by both the viewport hook and the CSS media query because tests and embedded shells can mock one surface independently. Treat either mobile signal as sufficient so the compact picker/search-toggle path stays available whenever Settings is in mobile mode. + */ const [showMobileSectionPicker, setShowMobileSectionPicker] = useState(() => - typeof window !== "undefined" && typeof window.matchMedia === "function" + viewportMode === "mobile" || + (typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia(MOBILE_SETTINGS_MEDIA_QUERY)?.matches === true - : false, + : false), ); const [settingsSearchQuery, setSettingsSearchQuery] = useState(""); /* @@ -1210,13 +1215,13 @@ export function SettingsModal({ return; } const updateMobilePicker = (event?: MediaQueryListEvent) => { - setShowMobileSectionPicker(event ? event.matches : mediaQuery.matches); + setShowMobileSectionPicker(viewportMode === "mobile" || (event ? event.matches : mediaQuery.matches)); }; updateMobilePicker(); mediaQuery.addEventListener("change", updateMobilePicker); return () => mediaQuery.removeEventListener("change", updateMobilePicker); - }, []); + }, [viewportMode]); /* FNXC:SettingsReset 2026-07-04-00:15: @@ -3653,11 +3658,15 @@ export function SettingsModal({