import { type PageLayoutBreakpoint } from '@/page-layout/constants/PageLayoutBreakpoints'; import { PAGE_LAYOUT_GRID_OVERLAY_Z_INDEX } from '@/page-layout/constants/PageLayoutGridOverlayZIndex'; import { useCreateWidgetFromClick } from '@/page-layout/hooks/useCreateWidgetFromClick'; import { pageLayoutCurrentBreakpointComponentState } from '@/page-layout/states/pageLayoutCurrentBreakpointComponentState'; import { pageLayoutCurrentLayoutsComponentState } from '@/page-layout/states/pageLayoutCurrentLayoutsComponentState'; import { pageLayoutSelectedCellsComponentState } from '@/page-layout/states/pageLayoutSelectedCellsComponentState'; import { calculateGridCellPosition } from '@/page-layout/utils/calculateGridCellPosition'; import { calculateTotalGridRows } from '@/page-layout/utils/calculateTotalGridRows'; import { generateCellId } from '@/page-layout/utils/generateCellId'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; import { styled } from '@linaria/react'; import { useMemo } from 'react'; import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledGridOverlay = styled.div<{ isDragSelecting?: boolean; breakpoint: PageLayoutBreakpoint; }>` position: absolute; top: ${themeCssVariables.spacing[2]}; left: ${themeCssVariables.spacing[2]}; right: ${themeCssVariables.spacing[2]}; bottom: ${themeCssVariables.spacing[2]}; display: grid; grid-template-columns: ${({ breakpoint }) => breakpoint === 'mobile' ? '1fr' : 'repeat(12, 1fr)'}; grid-auto-rows: 55px; gap: ${themeCssVariables.spacing[2]}; pointer-events: ${({ isDragSelecting }) => isDragSelecting ? 'auto' : 'none'}; z-index: ${PAGE_LAYOUT_GRID_OVERLAY_Z_INDEX}; `; const StyledGridCell = styled.div<{ isSelected?: boolean }>` background: ${({ isSelected }) => isSelected ? themeCssVariables.color.blue3 : 'transparent'}; border: 1px solid ${({ isSelected }) => isSelected ? themeCssVariables.color.blue7 : themeCssVariables.border.color.light}; border-radius: ${themeCssVariables.border.radius.md}; cursor: pointer; transition: background-color 0.3s ease; &:hover { background: ${themeCssVariables.background.transparent.lighter}; border-color: ${themeCssVariables.border.color.medium}; } `; export const PageLayoutGridOverlay = () => { const pageLayoutCurrentBreakpoint = useAtomComponentStateValue( pageLayoutCurrentBreakpointComponentState, ); const pageLayoutSelectedCells = useAtomComponentStateValue( pageLayoutSelectedCellsComponentState, ); const pageLayoutCurrentLayouts = useAtomComponentStateValue( pageLayoutCurrentLayoutsComponentState, ); const activeTabId = useAtomComponentStateValue(activeTabIdComponentState); const { createWidgetFromClick } = useCreateWidgetFromClick(); const numberOfRows = useMemo(() => { const currentTabLayouts = pageLayoutCurrentLayouts[activeTabId ?? ''] || { desktop: [], mobile: [], }; return calculateTotalGridRows(currentTabLayouts); }, [pageLayoutCurrentLayouts, activeTabId]); const isPageLayoutCurrentBreakpointMobile = pageLayoutCurrentBreakpoint === 'mobile'; const numberOfColumns = pageLayoutCurrentBreakpoint === 'mobile' ? 1 : 12; return ( {Array.from( { length: numberOfColumns * numberOfRows, }, (_, i) => { const { column, row } = calculateGridCellPosition({ index: i, numberOfColumns, }); const cellId = generateCellId(column, row); return ( createWidgetFromClick(cellId)} /> ); }, )} ); };