From 6f4cd7522f5b689b532902618f0a41e0a5be2a99 Mon Sep 17 00:00:00 2001 From: ajnart Date: Thu, 23 Jul 2026 02:19:26 +0200 Subject: [PATCH] fix: align mobile root section ordering --- .../components/board/mobile/mobile-board.tsx | 9 ++------- .../board/mobile/mobile-layout.spec.ts | 13 ++++++++++++- .../components/board/mobile/mobile-layout.ts | 17 ++++++++++++++--- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/apps/nextjs/src/components/board/mobile/mobile-board.tsx b/apps/nextjs/src/components/board/mobile/mobile-board.tsx index 5e7a1029f..aa06a521f 100644 --- a/apps/nextjs/src/components/board/mobile/mobile-board.tsx +++ b/apps/nextjs/src/components/board/mobile/mobile-board.tsx @@ -11,18 +11,13 @@ import type { GridItemHTMLElement, GridStack as GridStackInstance } from "@homar import { BoardItemContent } from "../items/item-content"; import { SectionProvider } from "../sections/section-context"; import classes from "./mobile-board.module.css"; -import { createMobileBoardItems, mobileColumnCount } from "./mobile-layout"; +import { createMobileBoardItems, getMobileRootSection, mobileColumnCount } from "./mobile-layout"; export const MobileBoard = () => { const board = useRequiredBoard(); const desktopLayout = getDesktopLayout(board); const items = useMemo(() => createMobileBoardItems(board, desktopLayout.id), [board, desktopLayout.id]); - const rootSection = board.sections.find((section) => section.kind !== "dynamic") ?? { - id: "mobile", - kind: "empty" as const, - xOffset: 0, - yOffset: 0, - }; + const rootSection = getMobileRootSection(board); const wrapperRef = useRef(null); const itemRefs = useRef>>({}); const gridstackRef = useRef(null); diff --git a/apps/nextjs/src/components/board/mobile/mobile-layout.spec.ts b/apps/nextjs/src/components/board/mobile/mobile-layout.spec.ts index 73979b6bb..3e06594d0 100644 --- a/apps/nextjs/src/components/board/mobile/mobile-layout.spec.ts +++ b/apps/nextjs/src/components/board/mobile/mobile-layout.spec.ts @@ -5,9 +5,20 @@ import { BoardMockBuilder } from "../items/actions/test/mocks/board-mock"; import { DynamicSectionMockBuilder } from "../items/actions/test/mocks/dynamic-section-mock"; import { EmptySectionMockBuilder } from "../items/actions/test/mocks/empty-section-mock"; import { ItemMockBuilder } from "../items/actions/test/mocks/item-mock"; -import { createMobileBoardItems } from "./mobile-layout"; +import { createMobileBoardItems, getMobileRootSection } from "./mobile-layout"; describe("createMobileBoardItems", () => { + test("selects the first root section in visual order", () => { + const board = new BoardMockBuilder().build(); + board.sections.push( + new EmptySectionMockBuilder({ id: "stored-first", xOffset: 0, yOffset: 1 }).build(), + new EmptySectionMockBuilder({ id: "visually-first", xOffset: 1, yOffset: 0 }).build(), + new EmptySectionMockBuilder({ id: "visually-second", xOffset: 2, yOffset: 0 }).build(), + ); + + expect(getMobileRootSection(board).id).toBe("visually-first"); + }); + test("flattens categories and dynamic sections in visual order", () => { const board = new BoardMockBuilder().build(); const desktopLayoutId = board.layouts.at(0)?.id; diff --git a/apps/nextjs/src/components/board/mobile/mobile-layout.ts b/apps/nextjs/src/components/board/mobile/mobile-layout.ts index 0a66e5e28..ab8bd4d65 100644 --- a/apps/nextjs/src/components/board/mobile/mobile-layout.ts +++ b/apps/nextjs/src/components/board/mobile/mobile-layout.ts @@ -15,6 +15,19 @@ type PositionedLayout = { const comparePosition = (elementA: PositionedElement, elementB: PositionedElement) => elementA.yOffset - elementB.yOffset || elementA.xOffset - elementB.xOffset; +const getMobileRootSections = (board: Board) => + board.sections + .filter((section) => section.kind !== "dynamic") + .toSorted((sectionA, sectionB) => sectionA.yOffset - sectionB.yOffset || sectionA.xOffset - sectionB.xOffset); + +export const getMobileRootSection = (board: Board) => + getMobileRootSections(board)[0] ?? { + id: "mobile", + kind: "empty" as const, + xOffset: 0, + yOffset: 0, + }; + const getLayout = ( layouts: TLayout[], desktopLayoutId: string, @@ -26,9 +39,7 @@ const getLayout = ( )[0]; export const createMobileBoardItems = (board: Board, desktopLayoutId: string): SectionItem[] => { - const rootSections = board.sections - .filter((section) => section.kind !== "dynamic") - .toSorted((sectionA, sectionB) => sectionA.yOffset - sectionB.yOffset || sectionA.xOffset - sectionB.xOffset); + const rootSections = getMobileRootSections(board); const defaultSectionId = rootSections[0]?.id ?? "mobile"; const layoutPriority = new Map( board.layouts