diff --git a/apps/nextjs/src/components/board/layout/test/board-lanes.spec.ts b/apps/nextjs/src/components/board/layout/test/board-lanes.spec.ts index ecb537089..72a8bc3f4 100644 --- a/apps/nextjs/src/components/board/layout/test/board-lanes.spec.ts +++ b/apps/nextjs/src/components/board/layout/test/board-lanes.spec.ts @@ -38,6 +38,22 @@ describe("board lanes", () => { expect(getBoardLaneColumnCount(layout, "right")).toBe(0); }); + test("disables gutters for mobile layouts", () => { + const layout = { + id: "mobile", + name: "Mobile", + columnCount: 12, + leftGutterColumnCount: 2, + rightGutterColumnCount: 3, + breakpoint: 0, + role: "mobile", + } satisfies Board["layouts"][number]; + + expect(getBoardLaneColumnCount(layout, "left")).toBe(0); + expect(getBoardLaneColumnCount(layout, "main")).toBe(12); + expect(getBoardLaneColumnCount(layout, "right")).toBe(0); + }); + test("rejects ambiguous duplicate roots", () => { const board = new BoardMockBuilder() .addSection(new EmptySectionMockBuilder({ id: "main-a" }).build()) diff --git a/packages/definitions/src/section.ts b/packages/definitions/src/section.ts index ac820c840..1ea09ae2c 100644 --- a/packages/definitions/src/section.ts +++ b/packages/definitions/src/section.ts @@ -1,3 +1,5 @@ +import type { LayoutRole } from "./board"; + export const sectionKinds = ["empty", "container"] as const; export type SectionKind = (typeof sectionKinds)[number]; @@ -21,12 +23,17 @@ export const getBoardLaneColumnCount = ( columnCount: number; leftGutterColumnCount?: number | null; rightGutterColumnCount?: number | null; + role?: LayoutRole; }, lane: BoardLane, ) => { const total = Math.max(1, Math.floor(layout.columnCount)); - const left = Math.min(Math.max(0, Math.floor(layout.leftGutterColumnCount ?? 0)), total - 1); - const right = Math.min(Math.max(0, Math.floor(layout.rightGutterColumnCount ?? 0)), total - left - 1); + const left = + layout.role === "mobile" ? 0 : Math.min(Math.max(0, Math.floor(layout.leftGutterColumnCount ?? 0)), total - 1); + const right = + layout.role === "mobile" + ? 0 + : Math.min(Math.max(0, Math.floor(layout.rightGutterColumnCount ?? 0)), total - left - 1); if (lane === "left") return left; if (lane === "right") return right; return total - left - right; diff --git a/packages/validation/src/board-layout.spec.ts b/packages/validation/src/board-layout.spec.ts index 5f73132f9..a744c81a6 100644 --- a/packages/validation/src/board-layout.spec.ts +++ b/packages/validation/src/board-layout.spec.ts @@ -42,4 +42,17 @@ describe("board layout gutters", () => { }).success, ).toBe(false); }); + + test("rejects sidebars on mobile layouts", () => { + expect( + boardLayoutSchema.safeParse({ + id: "mobile", + name: "Mobile", + columnCount: 6, + leftGutterColumnCount: 1, + breakpoint: 0, + role: "mobile", + }).success, + ).toBe(false); + }); });