Merge custom option test fix into mobile boards

This commit is contained in:
Thomas Camlong committed 2026-08-09 18:08:39 +02:00
commit 2c97eec1d0
32 files changed
+798 -238

No files matched your search

@@ -18,7 +18,7 @@ export const BoardEmptySection = ({ section, columnCount, requestedRowCount, rai
const [isEditMode] = useEditMode();
const t = useScopedI18n("board.landmark");
if (totalLength === 0 && !isEditMode && requestedRowCount === 0) return null;
if (totalLength === 0 && !isEditMode && requestedRowCount === 0 && railPlacement !== "main") return null;
return (
<SectionGrid
@@ -86,6 +86,10 @@ body[data-board-grid-interacting="drag"] .board-grid-placeholder {
overflow: visible;
}
body[data-board-grid-interacting="resize"] .board-grid-entry[data-dnd-active="true"] > .board-grid-content-mount {
overflow: clip;
}
.board-grid-placeholder {
z-index: 0;
background: color-mix(in srgb, var(--mantine-primary-color-filled) 16%, transparent);
@@ -178,7 +182,7 @@ body[data-board-grid-interacting="drag"] .board-grid-placeholder {
.board-grid-resize-handle[data-grid-resize-handle="s"] {
right: 44px;
left: 44px;
height: 32px;
height: max(32px, calc(25px * var(--board-canvas-inverse-scale, 1)));
cursor: ns-resize;
}
@@ -194,7 +198,7 @@ body[data-board-grid-interacting="drag"] .board-grid-placeholder {
.board-grid-resize-handle[data-grid-resize-handle="w"] {
top: 44px;
bottom: 44px;
width: 32px;
width: max(32px, calc(25px * var(--board-canvas-inverse-scale, 1)));
cursor: ew-resize;
}
@@ -217,8 +221,8 @@ body[data-board-grid-interacting="drag"] .board-grid-placeholder {
.board-grid-resize-handle[data-grid-resize-handle="sw"],
.board-grid-resize-handle[data-grid-resize-handle="nw"] {
z-index: 9;
width: 44px;
height: 44px;
width: max(44px, calc(25px * var(--board-canvas-inverse-scale, 1)));
height: max(44px, calc(25px * var(--board-canvas-inverse-scale, 1)));
}
.board-grid-resize-handle[data-grid-resize-handle="ne"] {
@@ -10,6 +10,7 @@ import { CollisionPriority } from "@dnd-kit/abstract";
import { pointerIntersection } from "@dnd-kit/collision";
import type { DragDropManager, Draggable as DomDraggable } from "@dnd-kit/dom";
import { Accessibility, AutoScroller, Feedback, PointerActivationConstraints, PointerSensor } from "@dnd-kit/dom";
import { RestrictToElement } from "@dnd-kit/dom/modifiers";
import { getEventCoordinates, getFrameTransform, isPointerEvent } from "@dnd-kit/dom/utilities";
import type {
BeforeDragStartEvent,
@@ -720,6 +721,7 @@ export default function GridEditor({ sectionId, columnCount, rowCount, placement
if (!previewGrid || !interaction) return placements;
if (interaction.sourceGridId === sectionId) {
if (interaction.mode === "resize") return previewGrid.placements;
const original = controlledById.get(interaction.activeId);
if (!original) return previewGrid.placements;
return previewGrid.placements.some((placement) => placement.id === interaction.activeId)
@@ -734,9 +736,16 @@ export default function GridEditor({ sectionId, columnCount, rowCount, placement
);
const targetPlacement =
interaction?.valid && interaction.targetGridId === sectionId ? interaction.targetPlacement : null;
const growsDuringDrag =
interaction?.mode === "drag" &&
(interaction.targetGridId === sectionId ||
(interaction.targetGridId === null && interaction.sourceGridId === sectionId));
const participatesInInteraction =
interaction && (interaction.sourceGridId === sectionId || interaction.targetGridId === sectionId);
const previewRowCount = getLayoutRowCount(previewGrid?.placements ?? renderPlacements);
const renderedRowCount =
section.kind !== "container" && interaction?.mode === "resize"
? Math.max(rowCount, getLayoutRowCount(renderPlacements))
section.kind !== "container" && participatesInInteraction
? Math.max(rowCount, previewRowCount) + (growsDuringDrag ? 1 : 0)
: rowCount;
const { ref: droppableRef, isDropTarget } = useDroppable<GridTargetData>({
@@ -876,6 +885,14 @@ const DndGridEntry = ({ sectionId, placement, label, columnCount, maxRowCount }:
],
[],
);
const modifiers = useMemo(
() => [
RestrictToElement.configure({
element: () => shellRef.current?.closest('[data-testid="board-canvas"]') ?? null,
}),
],
[],
);
const {
ref: draggableRef,
handleRef,
@@ -886,6 +903,7 @@ const DndGridEntry = ({ sectionId, placement, label, columnCount, maxRowCount }:
type: GRID_ENTRY_TYPE,
data: sourceData,
sensors,
modifiers,
});
const setShellRef = useCallback(
(element: HTMLDivElement | null) => {
@@ -1,6 +1,6 @@
"use client";
import { useMemo } from "react";
import { useEffect, useMemo, useState } from "react";
import dynamic from "next/dynamic";
import { Box, LoadingOverlay } from "@mantine/core";
import combineClasses from "clsx";
@@ -13,12 +13,14 @@ import type { ContainerSectionItem, Section } from "~/app/[locale]/boards/_types
import {
getCollapsedDisplayLayout,
getEditableCanvasAttributes,
getGridRowCountForVisualHeight,
getLayoutRowCount,
getLogicalItemStyle,
getLogicalTrackSize,
getReadonlyCanvasAttributes,
normalizeGridPlacement,
} from "~/components/board/layout";
import { useBoardCanvasScale } from "~/components/board/layout/scaled-board-canvas";
import { loadGridEditorAsync } from "./grid-editor-loader";
import { useGridEditorRuntimeStatus } from "./grid-editor-runtime";
import type { SectionGridPlacement } from "./use-grid-layout-actions";
@@ -81,6 +83,7 @@ export const SectionGrid = ({
className,
}: SectionGridProps) => {
const [isEditMode] = useEditMode();
const canvasScale = useBoardCanvasScale();
const editorRuntimeStatus = useGridEditorRuntimeStatus();
const board = useRequiredBoard();
const currentLayoutId = useCurrentLayout();
@@ -144,8 +147,9 @@ export const SectionGrid = ({
);
const displayedItems = items.map((item) => withPlacement(item, placementById.get(item.id)));
const displayedInnerSections = innerSections.map((item) => withPlacement(item, placementById.get(item.id)));
const minimumViewportRowCount = useMinimumViewportRowCount(section.kind === "empty", canvasScale);
const contentRowCount = Math.max(1, getLayoutRowCount(displayPlacements));
const rowCount = Math.max(contentRowCount, requestedRowCount);
const rowCount = Math.max(contentRowCount, requestedRowCount, minimumViewportRowCount);
const logicalWidth = getLogicalTrackSize(columnCount);
const logicalHeight = getLogicalTrackSize(rowCount);
const canvasAttributes = isEditMode
@@ -199,6 +203,24 @@ export const SectionGrid = ({
);
};
const useMinimumViewportRowCount = (enabled: boolean, canvasScale: number) => {
const [visualHeight, setVisualHeight] = useState(0);
useEffect(() => {
if (!enabled) return;
const update = () => setVisualHeight(window.visualViewport?.height ?? window.innerHeight);
update();
window.addEventListener("resize", update, { passive: true });
window.visualViewport?.addEventListener("resize", update, { passive: true });
return () => {
window.removeEventListener("resize", update);
window.visualViewport?.removeEventListener("resize", update);
};
}, [enabled]);
return enabled ? getGridRowCountForVisualHeight(visualHeight, canvasScale) : 0;
};
const getContainerMinimumSize = (
board: ReturnType<typeof useRequiredBoard>,
layoutId: string,
@@ -27,6 +27,7 @@ describe("board grid import boundary", () => {
{ file: "components/board/sections/grid/grid-editor.tsx", kind: "static", specifier: "@dnd-kit/abstract" },
{ file: "components/board/sections/grid/grid-editor.tsx", kind: "static", specifier: "@dnd-kit/collision" },
{ file: "components/board/sections/grid/grid-editor.tsx", kind: "static", specifier: "@dnd-kit/dom" },
{ file: "components/board/sections/grid/grid-editor.tsx", kind: "static", specifier: "@dnd-kit/dom/modifiers" },
{ file: "components/board/sections/grid/grid-editor.tsx", kind: "static", specifier: "@dnd-kit/dom/utilities" },
{ file: "components/board/sections/grid/grid-editor.tsx", kind: "static", specifier: "@dnd-kit/react" },
]);