From cda9c684c3e62379b68e60624f6571c16c4320e5 Mon Sep 17 00:00:00 2001 From: Mike Cao Date: Fri, 13 Feb 2026 01:53:53 -0800 Subject: [PATCH] Migrate board layout UI to react-zen and preserve empty component titles --- .../boards/[boardId]/BoardColumn.module.css | 17 --- .../boards/[boardId]/BoardComponentSelect.tsx | 8 +- .../(main)/boards/[boardId]/BoardEditBody.tsx | 114 ++++++++++-------- .../boards/[boardId]/BoardEditColumn.tsx | 37 +++--- .../[boardId]/BoardEditLayout.module.css | 46 ------- .../(main)/boards/[boardId]/BoardEditRow.tsx | 99 ++++++++++----- .../(main)/boards/[boardId]/BoardViewBody.tsx | 5 +- .../boards/[boardId]/BoardViewColumn.tsx | 2 +- .../(main)/boards/[boardId]/BoardViewRow.tsx | 17 +-- 9 files changed, 168 insertions(+), 177 deletions(-) delete mode 100644 src/app/(main)/boards/[boardId]/BoardColumn.module.css delete mode 100644 src/app/(main)/boards/[boardId]/BoardEditLayout.module.css diff --git a/src/app/(main)/boards/[boardId]/BoardColumn.module.css b/src/app/(main)/boards/[boardId]/BoardColumn.module.css deleted file mode 100644 index 895e62058..000000000 --- a/src/app/(main)/boards/[boardId]/BoardColumn.module.css +++ /dev/null @@ -1,17 +0,0 @@ -.column { - position: relative; -} - -.columnAction { - opacity: 0; - visibility: hidden; - pointer-events: none; - transition: opacity 120ms ease; -} - -.column:hover .columnAction, -.column:focus-within .columnAction { - opacity: 1; - visibility: visible; - pointer-events: auto; -} diff --git a/src/app/(main)/boards/[boardId]/BoardComponentSelect.tsx b/src/app/(main)/boards/[boardId]/BoardComponentSelect.tsx index 5619a8e06..d36b9014f 100644 --- a/src/app/(main)/boards/[boardId]/BoardComponentSelect.tsx +++ b/src/app/(main)/boards/[boardId]/BoardComponentSelect.tsx @@ -73,14 +73,14 @@ export function BoardComponentSelect({ setSelectedDef(definition); setConfigValues(getDefaultConfigValues(definition, initialConfig)); - setTitle(initialConfig.title || definition.name); + setTitle(initialConfig.title ?? ''); setDescription(initialConfig.description || ''); }, [initialConfig, allDefinitions]); const handleSelectComponent = (def: ComponentDefinition) => { setSelectedDef(def); setConfigValues(getDefaultConfigValues(def)); - setTitle(def.name); + setTitle(''); setDescription(''); }; @@ -107,7 +107,7 @@ export function BoardComponentSelect({ const config: BoardComponentConfig = { type: selectedDef.type, - title: title || selectedDef.name, + title, description, }; @@ -248,7 +248,7 @@ export function BoardComponentSelect({ {t(labels.cancel)} diff --git a/src/app/(main)/boards/[boardId]/BoardEditBody.tsx b/src/app/(main)/boards/[boardId]/BoardEditBody.tsx index 6b7c2ecfd..d9c366fb0 100644 --- a/src/app/(main)/boards/[boardId]/BoardEditBody.tsx +++ b/src/app/(main)/boards/[boardId]/BoardEditBody.tsx @@ -1,11 +1,10 @@ -import { Button, Icon, Row, Tooltip, TooltipTrigger } from '@umami/react-zen'; +import { Box, Button, Icon, Row, Tooltip, TooltipTrigger } from '@umami/react-zen'; import { produce } from 'immer'; import { Fragment, useEffect, useRef } from 'react'; import { Group, type GroupImperativeHandle, Panel, Separator } from 'react-resizable-panels'; import { v4 as uuid } from 'uuid'; import { useBoard } from '@/components/hooks'; import { GripHorizontal, Plus } from '@/components/icons'; -import styles from './BoardEditLayout.module.css'; import { BoardEditRow } from './BoardEditRow'; import { BUTTON_ROW_HEIGHT, MAX_ROW_HEIGHT, MIN_ROW_HEIGHT } from './boardConstants'; @@ -108,52 +107,71 @@ export function BoardEditBody() { const minHeight = (rows.length || 1) * MAX_ROW_HEIGHT + BUTTON_ROW_HEIGHT; return ( - - {rows.map((row, index) => ( - - - + + + {rows.map((row, index) => ( + + + + + {index < rows.length - 1 && ( + + + + + + + + )} + + ))} + {!!websiteId && ( + + + + + Add row + + - {index < rows.length - 1 && ( - - - - - - - - )} - - ))} - {!!websiteId && ( - - - - - Add row - - - - )} - + )} + + ); } diff --git a/src/app/(main)/boards/[boardId]/BoardEditColumn.tsx b/src/app/(main)/boards/[boardId]/BoardEditColumn.tsx index 0d65381cc..1fddee66d 100644 --- a/src/app/(main)/boards/[boardId]/BoardEditColumn.tsx +++ b/src/app/(main)/boards/[boardId]/BoardEditColumn.tsx @@ -1,11 +1,20 @@ -import { Box, Button, Dialog, Icon, Modal, Row, Tooltip, TooltipTrigger } from '@umami/react-zen'; +import { + Box, + Button, + Column, + Dialog, + Icon, + Modal, + Row, + Tooltip, + TooltipTrigger, +} from '@umami/react-zen'; import { useMemo, useState } from 'react'; import { Panel } from '@/components/common/Panel'; import { useBoard, useMessages } from '@/components/hooks'; import { Pencil, Plus, X } from '@/components/icons'; import type { BoardComponentConfig } from '@/lib/types'; import { getComponentDefinition } from '../boardComponentRegistry'; -import styles from './BoardColumn.module.css'; import { BoardComponentRenderer } from './BoardComponentRenderer'; import { BoardComponentSelect } from './BoardComponentSelect'; @@ -25,6 +34,7 @@ export function BoardEditColumn({ canRemove?: boolean; }) { const [showSelect, setShowSelect] = useState(false); + const [showActions, setShowActions] = useState(false); const { board } = useBoard(); const { t, labels } = useMessages(); const websiteId = board?.parameters?.websiteId; @@ -44,7 +54,7 @@ export function BoardEditColumn({ const hasComponent = !!component; const canRemoveAction = hasComponent || canRemove; const defaultTitle = component ? getComponentDefinition(component.type)?.name : undefined; - const title = component?.title || defaultTitle; + const title = component?.title ?? defaultTitle; const description = component?.description; const handleRemove = () => { @@ -62,16 +72,11 @@ export function BoardEditColumn({ width="100%" height="100%" position="relative" - className={styles.column} + onMouseEnter={() => setShowActions(true)} + onMouseLeave={() => setShowActions(false)} > - {canEdit && canRemoveAction && ( - + {canEdit && canRemoveAction && showActions && ( + {hasComponent && ( @@ -100,17 +105,13 @@ export function BoardEditColumn({ ) : ( canEdit && ( - + - + ) )} diff --git a/src/app/(main)/boards/[boardId]/BoardEditLayout.module.css b/src/app/(main)/boards/[boardId]/BoardEditLayout.module.css deleted file mode 100644 index 4d540f00d..000000000 --- a/src/app/(main)/boards/[boardId]/BoardEditLayout.module.css +++ /dev/null @@ -1,46 +0,0 @@ -.columnSeparator { - width: 12px; - display: flex; - align-items: center; - justify-content: center; - cursor: col-resize; -} - -.rowSeparator { - height: 12px; - display: flex; - align-items: center; - justify-content: center; - cursor: row-resize; -} - -.separatorHandle { - display: flex; - align-items: center; - justify-content: center; - color: var(--gray-9); -} - -.rowGroup { - position: relative; - height: 100%; -} - -.rowActions { - position: absolute; - top: 50%; - right: 12px; - transform: translateY(-50%); - z-index: 20; - opacity: 0; - visibility: hidden; - pointer-events: none; - transition: opacity 120ms ease; -} - -.rowGroup:hover .rowActions, -.rowGroup:focus-within .rowActions { - opacity: 1; - visibility: visible; - pointer-events: auto; -} diff --git a/src/app/(main)/boards/[boardId]/BoardEditRow.tsx b/src/app/(main)/boards/[boardId]/BoardEditRow.tsx index 2a9dca753..39b47f7a3 100644 --- a/src/app/(main)/boards/[boardId]/BoardEditRow.tsx +++ b/src/app/(main)/boards/[boardId]/BoardEditRow.tsx @@ -1,6 +1,6 @@ -import { Button, Column, Icon, Tooltip, TooltipTrigger } from '@umami/react-zen'; +import { Box, Button, Column, Icon, Row, Tooltip, TooltipTrigger } from '@umami/react-zen'; import { produce } from 'immer'; -import { Fragment } from 'react'; +import { Fragment, useState } from 'react'; import { Group, type GroupImperativeHandle, @@ -12,7 +12,6 @@ import { useBoard } from '@/components/hooks'; import { ChevronDown, GripVertical, Minus, Plus } from '@/components/icons'; import type { BoardColumn as BoardColumnType, BoardComponentConfig } from '@/lib/types'; import { BoardEditColumn } from './BoardEditColumn'; -import styles from './BoardEditLayout.module.css'; import { MAX_COLUMNS, MIN_COLUMN_WIDTH } from './boardConstants'; export function BoardEditRow({ @@ -37,6 +36,7 @@ export function BoardEditRow({ onRegisterRef: (rowId: string, ref: GroupImperativeHandle | null) => void; }) { const { board, updateBoard } = useBoard(); + const [showActions, setShowActions] = useState(false); const handleGroupRef = (ref: GroupImperativeHandle | null) => { onRegisterRef(rowId, ref); @@ -82,35 +82,68 @@ export function BoardEditRow({ }; return ( - - {columns?.map((column, index) => ( - - - 1} - /> - - {index < columns.length - 1 && ( - - - - - - - - )} - - ))} - {canEdit && ( - + setShowActions(true)} + onMouseLeave={() => setShowActions(false)} + > + + {columns?.map((column, index) => ( + + + 1} + /> + + {index < columns.length - 1 && ( + + + + + + + + )} + + ))} + + {canEdit && showActions && ( +