From 21d1201de15d7d61f463cd1ed15929ef7b2b0e86 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Thu, 9 Jul 2026 10:35:05 -0700 Subject: [PATCH] FN-7713: collapse mobile Settings search row behind an expand/hide toggle Mobile Settings modal now hides the search row by default and exposes a toggle icon to expand/hide it, keeping desktop layout unchanged. - Add mobile-only searchRowExpanded state and toggle affordance in SettingsModal.tsx - Add toggle icon styling in SettingsModal.css - Update dashboard-guide.md docs to describe the new mobile behavior - Add/extend tests covering the collapsed-by-default state and toggle interaction - Add changeset (feature, no release wording) for @runfusion/fusion Files changed: .../fn-7713-mobile-settings-search-toggle.md | 7 ++ docs/dashboard-guide.md | 3 + .../dashboard/app/components/SettingsModal.css | 31 ++++++ .../dashboard/app/components/SettingsModal.tsx | 112 ++++++++++++++------- .../__tests__/SettingsModal.general.test.tsx | 7 ++ .../components/__tests__/settings-mobile.test.tsx | 69 +++++++++++++ 6 files changed, 192 insertions(+), 37 deletions(-) Fusion-Task-Id: FN-7713 Fusion-Task-Lineage: 4ce90317-28ce-45b4-a1d7-8fd662a922ae Co-authored-by: Fusion (runfusion.ai) --- .../fn-7713-mobile-settings-search-toggle.md | 7 ++ docs/dashboard-guide.md | 3 + .../app/components/SettingsModal.css | 31 +++++ .../app/components/SettingsModal.tsx | 112 ++++++++++++------ .../__tests__/SettingsModal.general.test.tsx | 7 ++ .../__tests__/settings-mobile.test.tsx | 69 +++++++++++ 6 files changed, 192 insertions(+), 37 deletions(-) create mode 100644 .changeset/fn-7713-mobile-settings-search-toggle.md diff --git a/.changeset/fn-7713-mobile-settings-search-toggle.md b/.changeset/fn-7713-mobile-settings-search-toggle.md new file mode 100644 index 0000000000..647917d7f3 --- /dev/null +++ b/.changeset/fn-7713-mobile-settings-search-toggle.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": minor +--- + +summary: Mobile Settings search row now collapses by default with a show/hide toggle. +category: feature +dev: SettingsModal mobile-only searchRowExpanded state + toggle icon; desktop unchanged. diff --git a/docs/dashboard-guide.md b/docs/dashboard-guide.md index ce3f737d5b..0775e7c91f 100644 --- a/docs/dashboard-guide.md +++ b/docs/dashboard-guide.md @@ -13,6 +13,9 @@ When Fusion detects a newer `@runfusion/fusion` release, the Settings modal foot Use **Search settings** at the top of Settings to find the section that contains a setting by name or keyword. The same search works in the Settings modal and embedded Settings page, filters both the desktop section list and mobile section picker, and only searches sections currently visible for enabled feature flags. + +On mobile, the search row starts collapsed behind a compact toggle icon (top of the Settings navigation) to save vertical space; tap it to reveal the search input and tap again to hide it. An in-progress search query is preserved across collapse/expand. Desktop and tablet always show the search row with no toggle. + Every user-editable setting's help text (the `.settings-description`/`` hint under a field) states its own default value — for example “Default: 3.”, “Default: enabled.”, or “No default — unset (inherits the global setting).” for values that fall back to another scope. Canonical default values come from `DEFAULT_GLOBAL_SETTINGS` / `DEFAULT_PROJECT_SETTINGS` in `packages/core/src/settings-schema.ts`; the dashboard copy never invents a number. A guard test (`settings-default-descriptions.test.tsx`) enforces that every surfaced setting states its default and that every `DEFAULT_SETTINGS` key is either documented or explicitly allowlisted as not surfaced in the Settings UI. diff --git a/packages/dashboard/app/components/SettingsModal.css b/packages/dashboard/app/components/SettingsModal.css index 403836b1ba..8e4668a199 100644 --- a/packages/dashboard/app/components/SettingsModal.css +++ b/packages/dashboard/app/components/SettingsModal.css @@ -558,6 +558,20 @@ The embedded title reads like other embedded-view titles (Planning modal-header- border-bottom: var(--btn-border-width) solid var(--border); } +/* FNXC:Settings 2026-07-09-00:00: the row wraps label + input + results; on desktop it always + renders (see .settings-search-toggle below, hidden here). On mobile the toggle in SettingsModal.tsx + controls whether this wrapper mounts at all. */ +.settings-search-row { + display: flex; + flex-direction: column; + gap: var(--space-xs); +} + +/* Desktop/tablet: search row is always visible, so the toggle icon never renders here. */ +.settings-search-toggle { + display: none; +} + .settings-search-label { color: var(--text-muted); font-size: 0.75rem; @@ -2179,6 +2193,23 @@ The header row wraps so the badge drops below the heading on narrow widths inste padding: var(--space-md) var(--space-lg) var(--space-sm); } + /* FNXC:Settings 2026-07-09-00:00: mobile-only collapse-by-default toggle. The row starts + collapsed (only the icon button renders) and expands to the full search row on tap. */ + .settings-search-toggle { + --settings-search-toggle-touch-target: calc(var(--space-lg) + var(--space-lg) + var(--space-xs)); + display: inline-flex; + align-items: center; + justify-content: center; + align-self: flex-start; + width: var(--settings-search-toggle-touch-target); + height: var(--settings-search-toggle-touch-target); + flex-shrink: 0; + } + + .settings-search-row { + margin-top: var(--space-xs); + } + .settings-search-input-wrap { align-items: stretch; } diff --git a/packages/dashboard/app/components/SettingsModal.tsx b/packages/dashboard/app/components/SettingsModal.tsx index da08553fea..76ddfa9f18 100644 --- a/packages/dashboard/app/components/SettingsModal.tsx +++ b/packages/dashboard/app/components/SettingsModal.tsx @@ -1,5 +1,5 @@ import { useState, useEffect, useCallback, useMemo, useRef, type CSSProperties, type MouseEvent } from "react"; -import { Globe, Folder, RefreshCw, Star, HelpCircle, Settings as SettingsIcon } from "lucide-react"; +import { Globe, Folder, RefreshCw, Star, HelpCircle, Settings as SettingsIcon, Search, X as SearchToggleCloseIcon } from "lucide-react"; import { getErrorMessage, resolveGitlabConfig, @@ -973,6 +973,18 @@ export function SettingsModal({ : false, ); const [settingsSearchQuery, setSettingsSearchQuery] = useState(""); + /* + * FNXC:Settings 2026-07-09-00:00: + * Mobile Settings previously always rendered the `.settings-search` row (label + input + result + * count) above the section picker, eating vertical space even when the user was not searching. + * On mobile only, the row now starts COLLAPSED behind a compact icon toggle; tapping it reveals + * the input, tapping again hides it. Desktop/tablet is untouched — the row is always visible + * there and the toggle never renders (see `isMobileSettingsSearch` below). Decision on the + * active-query edge case: `settingsSearchQuery` state is never cleared by collapsing, so + * re-expanding always restores the exact query and result count the user had before collapsing + * (no forced auto-expand — the toggle stays user-controlled). + */ + const [mobileSearchRowExpanded, setMobileSearchRowExpanded] = useState(false); const [appVersion, setAppVersion] = useState(null); const [updateCheckLoading, setUpdateCheckLoading] = useState(false); const [updateCheckResult, setUpdateCheckResult] = useState(null); @@ -1053,6 +1065,10 @@ export function SettingsModal({ const searchableSectionOptions = searchMatchedSections.filter((section) => !section.isGroupHeader); const hasSettingsSearchQuery = normalizedSettingsSearchQuery.length > 0; const hasSettingsSearchResults = searchableSectionOptions.length > 0; + // FNXC:Settings 2026-07-09-00:00: desktop/tablet always show the search row and never render the + // toggle; mobile starts collapsed (`mobileSearchRowExpanded === false`) until the user taps it. + const isMobileSettingsSearch = viewportMode === "mobile"; + const settingsSearchRowVisible = !isMobileSettingsSearch || mobileSearchRowExpanded; const firstSearchMatchedSectionId = resolveFirstSelectableSettingsSection(searchMatchedSections, firstVisibleSectionId); /** Get the scope of the currently active section */ @@ -3636,42 +3652,64 @@ export function SettingsModal({