Compare commits

...
Author SHA1 Message Date
Lucas Bordeau cd04b27a57 refactor: simplify z-index logic and enhance portal styling in record table
- Add static hoverPortal z-index to TABLE_Z_INDEX constant
- Remove scroll-dependent z-index sections (withGroups, withoutGroups scroll states, withoutGroupsCell0_0)
- Simplify RecordTableCellFocusedPortal to use static z-index value
- Simplify RecordTableCellFirstRowFirstColumn to use single static z-index
- Simplify RecordTableHeaderFirstScrollableCell to use static z-index
- Add outline-offset to hover and focus portals for proper cell boundaries
- Fix Linaria arithmetic interpolations for correct CSS unit spacing
2026-03-05 18:17:54 +01:00
12 changed files with 29 additions and 374 deletions
@@ -1,4 +1,6 @@
import { type RecordField } from '@/object-record/record-field/types/RecordField';
import { HorizontalScrollBoxShadowCSS } from '@/object-record/record-table/components/HorizontalScrollBoxShadowCSS';
import { VerticalScrollBoxShadowCSS } from '@/object-record/record-table/components/VerticalScrollBoxShadowCSS';
import { RECORD_TABLE_COLUMN_ADD_COLUMN_BUTTON_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnAddColumnButtonWidth';
import { RECORD_TABLE_COLUMN_ADD_COLUMN_BUTTON_WIDTH_CLASS_NAME } from '@/object-record/record-table/constants/RecordTableColumnAddColumnButtonWidthClassName';
import { RECORD_TABLE_COLUMN_CHECKBOX_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnCheckboxWidth';
@@ -10,8 +12,6 @@ import { RECORD_TABLE_COLUMN_LAST_EMPTY_COLUMN_WIDTH_VARIABLE_NAME } from '@/obj
import { RECORD_TABLE_COLUMN_WITH_GROUP_LAST_EMPTY_COLUMN_WIDTH_CLASS_NAME } from '@/object-record/record-table/constants/RecordTableColumnWithGroupLastEmptyColumnWidthClassName';
import { RECORD_TABLE_COLUMN_WITH_GROUP_LAST_EMPTY_COLUMN_WIDTH_VARIABLE_NAME } from '@/object-record/record-table/constants/RecordTableColumnWithGroupLastEmptyColumnWidthVariableName';
import { TABLE_Z_INDEX } from '@/object-record/record-table/constants/TableZIndex';
import { HorizontalScrollBoxShadowCSS } from '@/object-record/record-table/components/HorizontalScrollBoxShadowCSS';
import { VerticalScrollBoxShadowCSS } from '@/object-record/record-table/components/VerticalScrollBoxShadowCSS';
import { getRecordTableColumnFieldWidthClassName } from '@/object-record/record-table/utils/getRecordTableColumnFieldWidthClassName';
import { getRecordTableColumnFieldWidthCSSVariableName } from '@/object-record/record-table/utils/getRecordTableColumnFieldWidthCSSVariableName';
import { styled } from '@linaria/react';
@@ -95,8 +95,7 @@ const StyledTable = styled.div<{
}
div.header-cell:nth-of-type(3) {
left: ${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH +
RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px;
left: ${`${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH + RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px`};
right: 0;
background-color: ${themeCssVariables.background.primary};
@@ -129,16 +128,14 @@ const StyledTable = styled.div<{
div.table-cell-0-0 {
position: sticky;
left: ${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH +
RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px;
left: ${`${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH + RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px`};
${HorizontalScrollBoxShadowCSS}
}
div.table-cell:nth-of-type(3) {
position: sticky;
left: ${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH +
RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px;
left: ${`${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH + RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px`};
z-index: ${({ hasRecordGroups }) =>
hasRecordGroups
? TABLE_Z_INDEX.cell.withGroups.sticky
@@ -1,5 +1,6 @@
export const TABLE_Z_INDEX = {
base: 1,
hoverPortal: 4,
cell: {
withoutGroups: {
default: 3,
@@ -22,66 +23,10 @@ export const TABLE_Z_INDEX = {
headerColumnsNormal: 20,
},
},
withoutGroupsCell0_0: {
cell0_0HoveredWithoutScroll: 15,
cell0_0Normal: 12,
},
groupSection: {
stickyCell: 10,
normalCell: 8,
},
withGroups: {
noScrollAtAll: {
hoverPortalCellOnFirstScrollableColumn: 16,
hoverPortalCellOnNormalColumn: 14,
hoverPortalCellOnLabelIdentifierColumn: 14,
firstScrollableHeaderCell: 19,
},
scrolledBothVerticallyAndHorizontally: {
hoverPortalCellOnNormalColumn: 9,
hoverPortalCellOnFirstScrollableColumn: 9,
hoverPortalCellOnLabelIdentifierColumn: 9,
firstScrollableHeaderCell: 19,
},
scrolledHorizontallyOnly: {
hoverPortalCellOnLabelIdentifierColumn: 9,
hoverPortalCellOnNormalColumn: 9,
hoverPortalCellOnFirstScrollableColumn: 9,
firstScrollableHeaderCell: 19,
},
scrolledVerticallyOnly: {
hoverPortalCellOnNormalColumn: 9,
hoverPortalCellOnFirstScrollableColumn: 16,
hoverPortalCellOnLabelIdentifierColumn: 9,
firstScrollableHeaderCell: 19,
},
},
withoutGroups: {
noScrollAtAll: {
hoverPortalCellOnFirstScrollableColumn: 17,
hoverPortalCellOnNormalColumn: 17,
hoverPortalCellOnLabelIdentifierColumn: 17,
firstScrollableHeaderCell: 12,
},
scrolledBothVerticallyAndHorizontally: {
hoverPortalCellOnNormalColumn: 2,
hoverPortalCellOnFirstScrollableColumn: 2,
hoverPortalCellOnLabelIdentifierColumn: 2,
firstScrollableHeaderCell: 12,
},
scrolledHorizontallyOnly: {
hoverPortalCellOnLabelIdentifierColumn: 17,
hoverPortalCellOnNormalColumn: 11,
hoverPortalCellOnFirstScrollableColumn: 11,
firstScrollableHeaderCell: 10,
},
scrolledVerticallyOnly: {
hoverPortalCellOnNormalColumn: 9,
hoverPortalCellOnFirstScrollableColumn: 13,
hoverPortalCellOnLabelIdentifierColumn: 13,
firstScrollableHeaderCell: 14,
},
},
columnGrip: 30,
footer: {
tableWithGroups: {
@@ -1,5 +1,5 @@
import { getRecordTableColumnWidthInlineStyles } from '@/object-record/record-table/components/RecordTableStyleWrapper';
import { HorizontalScrollBoxShadowCSS } from '@/object-record/record-table/components/HorizontalScrollBoxShadowCSS';
import { getRecordTableColumnWidthInlineStyles } from '@/object-record/record-table/components/RecordTableStyleWrapper';
import { RECORD_TABLE_COLUMN_ADD_COLUMN_BUTTON_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnAddColumnButtonWidth';
import { RECORD_TABLE_COLUMN_ADD_COLUMN_BUTTON_WIDTH_CLASS_NAME } from '@/object-record/record-table/constants/RecordTableColumnAddColumnButtonWidthClassName';
import { RECORD_TABLE_COLUMN_CHECKBOX_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnCheckboxWidth';
@@ -26,12 +26,12 @@ import { useIsTableRowSecondaryDragged } from '@/object-record/record-table/reco
import { getRecordTableColumnFieldWidthClassName } from '@/object-record/record-table/utils/getRecordTableColumnFieldWidthClassName';
import { recordIdByRealIndexComponentFamilySelector } from '@/object-record/record-table/virtualization/states/recordIdByRealIndexComponentFamilySelector';
import { useAtomComponentFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilySelectorValue';
import { styled } from '@linaria/react';
import {
type DraggableProvided,
type DraggableRubric,
type DraggableStateSnapshot,
} from '@hello-pangea/dnd';
import { styled } from '@linaria/react';
import { useMemo } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants';
@@ -79,16 +79,14 @@ const StyledRowDraggableCloneCSSBridge = styled.div`
div.table-cell-0-0 {
position: sticky;
left: ${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH +
RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px;
left: ${`${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH + RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px`};
${HorizontalScrollBoxShadowCSS}
}
div.table-cell:nth-of-type(3) {
position: sticky;
left: ${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH +
RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px;
left: ${`${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH + RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px`};
z-index: ${TABLE_Z_INDEX.cell.withoutGroups.sticky};
${HorizontalScrollBoxShadowCSS}
@@ -1,14 +1,9 @@
import { TABLE_Z_INDEX } from '@/object-record/record-table/constants/TableZIndex';
import { StyledCell } from '@/object-record/record-table/record-table-cell/components/RecordTableCellStyleWrapper';
import { isRecordTableScrolledVerticallyComponentState } from '@/object-record/record-table/states/isRecordTableScrolledVerticallyComponentState';
import { recordTableFocusPositionComponentState } from '@/object-record/record-table/states/recordTableFocusPositionComponentState';
import { recordTableHoverPositionComponentState } from '@/object-record/record-table/states/recordTableHoverPositionComponentState';
import { getRecordTableColumnFieldWidthClassName } from '@/object-record/record-table/utils/getRecordTableColumnFieldWidthClassName';
import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { styled } from '@linaria/react';
import { type DraggableProvidedDragHandleProps } from '@hello-pangea/dnd';
import { cx } from '@linaria/core';
import { styled } from '@linaria/react';
import { useContext, type ReactNode } from 'react';
import { ThemeContext } from 'twenty-ui/theme-constants';
@@ -33,31 +28,7 @@ export const RecordTableCellFirstRowFirstColumn = ({
} & (Partial<DraggableProvidedDragHandleProps> | null)) => {
const { theme } = useContext(ThemeContext);
const recordTableHoverPosition = useAtomComponentStateValue(
recordTableHoverPositionComponentState,
);
const recordTableFocusPosition = useAtomComponentStateValue(
recordTableFocusPositionComponentState,
);
const isFocusPortalOnThisCell =
recordTableFocusPosition?.column === 0 &&
recordTableFocusPosition.row === 0;
const isHoveredPortalOnThisCell =
recordTableHoverPosition?.column === 0 &&
recordTableHoverPosition.row === 0;
const [isRecordTableScrolledVertically] = useAtomComponentState(
isRecordTableScrolledVerticallyComponentState,
);
const zIndex =
!isRecordTableScrolledVertically &&
(isHoveredPortalOnThisCell || isFocusPortalOnThisCell)
? TABLE_Z_INDEX.withoutGroupsCell0_0.cell0_0HoveredWithoutScroll
: TABLE_Z_INDEX.withoutGroupsCell0_0.cell0_0Normal;
const zIndex = TABLE_Z_INDEX.cell.withoutGroups.sticky;
const tdBackgroundColor = isSelected
? theme.accent.quaternary
@@ -1,15 +1,10 @@
import { RecordTableCellPortalWrapper } from '@/object-record/record-table/record-table-cell/components/RecordTableCellPortalWrapper';
import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { hasRecordGroupsComponentSelector } from '@/object-record/record-group/states/selectors/hasRecordGroupsComponentSelector';
import { TABLE_Z_INDEX } from '@/object-record/record-table/constants/TableZIndex';
import { RecordTableCellFocusedPortalContent } from '@/object-record/record-table/record-table-cell/components/RecordTableCellFocusedPortalContent';
import { RecordTableCellPortalRootContainer } from '@/object-record/record-table/record-table-cell/components/RecordTableCellPortalRootContainer';
import { isRecordTableScrolledHorizontallyComponentState } from '@/object-record/record-table/states/isRecordTableScrolledHorizontallyComponentState';
import { isRecordTableScrolledVerticallyComponentState } from '@/object-record/record-table/states/isRecordTableScrolledVerticallyComponentState';
import { RecordTableCellPortalWrapper } from '@/object-record/record-table/record-table-cell/components/RecordTableCellPortalWrapper';
import { recordTableFocusPositionComponentState } from '@/object-record/record-table/states/recordTableFocusPositionComponentState';
import { recordTableHoverPositionComponentState } from '@/object-record/record-table/states/recordTableHoverPositionComponentState';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { isDefined } from 'twenty-shared/utils';
export const RecordTableCellFocusedPortal = () => {
@@ -17,18 +12,6 @@ export const RecordTableCellFocusedPortal = () => {
recordTableFocusPositionComponentState,
);
const isRecordTableScrolledVertically = useAtomComponentStateValue(
isRecordTableScrolledVerticallyComponentState,
);
const isRecordTableScrolledHorizontally = useAtomComponentStateValue(
isRecordTableScrolledHorizontallyComponentState,
);
const hasRecordGroups = useAtomComponentSelectorValue(
hasRecordGroupsComponentSelector,
);
const recordTableHoverPosition = useAtomComponentStateValue(
recordTableHoverPositionComponentState,
);
@@ -43,106 +26,9 @@ export const RecordTableCellFocusedPortal = () => {
return null;
}
const isOnFirstScrollableColumn = recordTableFocusPosition.column === 1;
const isOnLabelIdentifierStickyColumn = recordTableFocusPosition.column === 0;
const zIndexForHoveredPortalOnFirstScrollableColumnWithoutGroups =
isRecordTableScrolledHorizontally && isRecordTableScrolledVertically
? TABLE_Z_INDEX.withoutGroups.scrolledBothVerticallyAndHorizontally
.hoverPortalCellOnFirstScrollableColumn
: isRecordTableScrolledHorizontally
? TABLE_Z_INDEX.withoutGroups.scrolledHorizontallyOnly
.hoverPortalCellOnFirstScrollableColumn
: isRecordTableScrolledVertically
? TABLE_Z_INDEX.withoutGroups.scrolledVerticallyOnly
.hoverPortalCellOnFirstScrollableColumn
: TABLE_Z_INDEX.withoutGroups.noScrollAtAll
.hoverPortalCellOnFirstScrollableColumn;
const zIndexForHoveredPortalOnLabelIdentifierStickyColumnWithoutGroups =
isRecordTableScrolledHorizontally && isRecordTableScrolledVertically
? TABLE_Z_INDEX.withoutGroups.scrolledBothVerticallyAndHorizontally
.hoverPortalCellOnLabelIdentifierColumn
: isRecordTableScrolledHorizontally
? TABLE_Z_INDEX.withoutGroups.scrolledHorizontallyOnly
.hoverPortalCellOnLabelIdentifierColumn
: isRecordTableScrolledVertically
? TABLE_Z_INDEX.withoutGroups.scrolledVerticallyOnly
.hoverPortalCellOnLabelIdentifierColumn
: TABLE_Z_INDEX.withoutGroups.noScrollAtAll
.hoverPortalCellOnLabelIdentifierColumn;
const zIndexForHoveredPortalOnNormalColumnWithoutGroups =
isRecordTableScrolledHorizontally && isRecordTableScrolledVertically
? TABLE_Z_INDEX.withoutGroups.scrolledBothVerticallyAndHorizontally
.hoverPortalCellOnNormalColumn
: isRecordTableScrolledHorizontally
? TABLE_Z_INDEX.withoutGroups.scrolledHorizontallyOnly
.hoverPortalCellOnNormalColumn
: isRecordTableScrolledVertically
? TABLE_Z_INDEX.withoutGroups.scrolledVerticallyOnly
.hoverPortalCellOnNormalColumn
: TABLE_Z_INDEX.withoutGroups.noScrollAtAll
.hoverPortalCellOnNormalColumn;
const zIndexForHoveredPortalWithoutGroups = isOnFirstScrollableColumn
? zIndexForHoveredPortalOnFirstScrollableColumnWithoutGroups
: isOnLabelIdentifierStickyColumn
? zIndexForHoveredPortalOnLabelIdentifierStickyColumnWithoutGroups
: zIndexForHoveredPortalOnNormalColumnWithoutGroups;
const zIndexForHoveredPortalOnFirstScrollableColumnWithGroups =
isRecordTableScrolledHorizontally && isRecordTableScrolledVertically
? TABLE_Z_INDEX.withGroups.scrolledBothVerticallyAndHorizontally
.hoverPortalCellOnFirstScrollableColumn
: isRecordTableScrolledHorizontally
? TABLE_Z_INDEX.withGroups.scrolledHorizontallyOnly
.hoverPortalCellOnFirstScrollableColumn
: isRecordTableScrolledVertically
? TABLE_Z_INDEX.withGroups.scrolledVerticallyOnly
.hoverPortalCellOnFirstScrollableColumn
: TABLE_Z_INDEX.withGroups.noScrollAtAll
.hoverPortalCellOnFirstScrollableColumn;
const zIndexForHoveredPortalOnLabelIdentifierStickyColumnWithGroups =
isRecordTableScrolledHorizontally && isRecordTableScrolledVertically
? TABLE_Z_INDEX.withGroups.scrolledBothVerticallyAndHorizontally
.hoverPortalCellOnLabelIdentifierColumn
: isRecordTableScrolledHorizontally
? TABLE_Z_INDEX.withGroups.scrolledHorizontallyOnly
.hoverPortalCellOnLabelIdentifierColumn
: isRecordTableScrolledVertically
? TABLE_Z_INDEX.withGroups.scrolledVerticallyOnly
.hoverPortalCellOnLabelIdentifierColumn
: TABLE_Z_INDEX.withGroups.noScrollAtAll
.hoverPortalCellOnLabelIdentifierColumn;
const zIndexForHoveredPortalOnNormalColumnWithGroups =
isRecordTableScrolledHorizontally && isRecordTableScrolledVertically
? TABLE_Z_INDEX.withGroups.scrolledBothVerticallyAndHorizontally
.hoverPortalCellOnNormalColumn
: isRecordTableScrolledHorizontally
? TABLE_Z_INDEX.withGroups.scrolledHorizontallyOnly
.hoverPortalCellOnNormalColumn
: isRecordTableScrolledVertically
? TABLE_Z_INDEX.withGroups.scrolledVerticallyOnly
.hoverPortalCellOnNormalColumn
: TABLE_Z_INDEX.withGroups.noScrollAtAll
.hoverPortalCellOnNormalColumn;
const zIndexForHoveredPortalWithGroups = isOnFirstScrollableColumn
? zIndexForHoveredPortalOnFirstScrollableColumnWithGroups
: isOnLabelIdentifierStickyColumn
? zIndexForHoveredPortalOnLabelIdentifierStickyColumnWithGroups
: zIndexForHoveredPortalOnNormalColumnWithGroups;
const zIndex = hasRecordGroups
? zIndexForHoveredPortalWithGroups
: zIndexForHoveredPortalWithoutGroups;
return (
<RecordTableCellPortalWrapper position={recordTableFocusPosition}>
<RecordTableCellPortalRootContainer zIndex={zIndex}>
<RecordTableCellPortalRootContainer zIndex={TABLE_Z_INDEX.hoverPortal}>
<RecordTableCellFocusedPortalContent />
</RecordTableCellPortalRootContainer>
</RecordTableCellPortalWrapper>
@@ -29,6 +29,7 @@ const StyledRecordTableCellFocusPortalContent = styled.div<{
height: ${RECORD_TABLE_ROW_HEIGHT}px;
outline: 1px solid ${themeCssVariables.color.blue8};
outline-offset: -1px;
user-select: none;
`;
@@ -1,14 +1,9 @@
import { RecordTableCellPortalWrapper } from '@/object-record/record-table/record-table-cell/components/RecordTableCellPortalWrapper';
import { recordTableHoverPositionComponentState } from '@/object-record/record-table/states/recordTableHoverPositionComponentState';
import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { hasRecordGroupsComponentSelector } from '@/object-record/record-group/states/selectors/hasRecordGroupsComponentSelector';
import { TABLE_Z_INDEX } from '@/object-record/record-table/constants/TableZIndex';
import { RecordTableCellHoveredPortalContent } from '@/object-record/record-table/record-table-cell/components/RecordTableCellHoveredPortalContent';
import { RecordTableCellPortalRootContainer } from '@/object-record/record-table/record-table-cell/components/RecordTableCellPortalRootContainer';
import { isRecordTableScrolledHorizontallyComponentState } from '@/object-record/record-table/states/isRecordTableScrolledHorizontallyComponentState';
import { isRecordTableScrolledVerticallyComponentState } from '@/object-record/record-table/states/isRecordTableScrolledVerticallyComponentState';
import { RecordTableCellPortalWrapper } from '@/object-record/record-table/record-table-cell/components/RecordTableCellPortalWrapper';
import { recordTableHoverPositionComponentState } from '@/object-record/record-table/states/recordTableHoverPositionComponentState';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { isDefined } from 'twenty-shared/utils';
export const RecordTableCellHoveredPortal = () => {
@@ -16,122 +11,13 @@ export const RecordTableCellHoveredPortal = () => {
recordTableHoverPositionComponentState,
);
const isRecordTableScrolledVertically = useAtomComponentStateValue(
isRecordTableScrolledVerticallyComponentState,
);
const isRecordTableScrolledHorizontally = useAtomComponentStateValue(
isRecordTableScrolledHorizontallyComponentState,
);
const hasRecordGroups = useAtomComponentSelectorValue(
hasRecordGroupsComponentSelector,
);
if (!isDefined(recordTableHoverPosition)) {
return null;
}
const isOnFirstScrollableColumn = recordTableHoverPosition.column === 1;
const isOnLabelIdentifierStickyColumn = recordTableHoverPosition.column === 0;
const zIndexForHoveredPortalOnFirstScrollableColumnWithoutGroups =
isRecordTableScrolledHorizontally && isRecordTableScrolledVertically
? TABLE_Z_INDEX.withoutGroups.scrolledBothVerticallyAndHorizontally
.hoverPortalCellOnFirstScrollableColumn
: isRecordTableScrolledHorizontally
? TABLE_Z_INDEX.withoutGroups.scrolledHorizontallyOnly
.hoverPortalCellOnFirstScrollableColumn
: isRecordTableScrolledVertically
? TABLE_Z_INDEX.withoutGroups.scrolledVerticallyOnly
.hoverPortalCellOnFirstScrollableColumn
: TABLE_Z_INDEX.withoutGroups.noScrollAtAll
.hoverPortalCellOnFirstScrollableColumn;
const zIndexForHoveredPortalOnLabelIdentifierStickyColumnWithoutGroups =
isRecordTableScrolledHorizontally && isRecordTableScrolledVertically
? TABLE_Z_INDEX.withoutGroups.scrolledBothVerticallyAndHorizontally
.hoverPortalCellOnLabelIdentifierColumn
: isRecordTableScrolledHorizontally
? TABLE_Z_INDEX.withoutGroups.scrolledHorizontallyOnly
.hoverPortalCellOnLabelIdentifierColumn
: isRecordTableScrolledVertically
? TABLE_Z_INDEX.withoutGroups.scrolledVerticallyOnly
.hoverPortalCellOnLabelIdentifierColumn
: TABLE_Z_INDEX.withoutGroups.noScrollAtAll
.hoverPortalCellOnLabelIdentifierColumn;
const zIndexForHoveredPortalOnNormalColumnWithoutGroups =
isRecordTableScrolledHorizontally && isRecordTableScrolledVertically
? TABLE_Z_INDEX.withoutGroups.scrolledBothVerticallyAndHorizontally
.hoverPortalCellOnNormalColumn
: isRecordTableScrolledHorizontally
? TABLE_Z_INDEX.withoutGroups.scrolledHorizontallyOnly
.hoverPortalCellOnNormalColumn
: isRecordTableScrolledVertically
? TABLE_Z_INDEX.withoutGroups.scrolledVerticallyOnly
.hoverPortalCellOnNormalColumn
: TABLE_Z_INDEX.withoutGroups.noScrollAtAll
.hoverPortalCellOnNormalColumn;
const zIndexForHoveredPortalWithoutGroups = isOnFirstScrollableColumn
? zIndexForHoveredPortalOnFirstScrollableColumnWithoutGroups
: isOnLabelIdentifierStickyColumn
? zIndexForHoveredPortalOnLabelIdentifierStickyColumnWithoutGroups
: zIndexForHoveredPortalOnNormalColumnWithoutGroups;
const zIndexForHoveredPortalOnFirstScrollableColumnWithGroups =
isRecordTableScrolledHorizontally && isRecordTableScrolledVertically
? TABLE_Z_INDEX.withGroups.scrolledBothVerticallyAndHorizontally
.hoverPortalCellOnFirstScrollableColumn
: isRecordTableScrolledHorizontally
? TABLE_Z_INDEX.withGroups.scrolledHorizontallyOnly
.hoverPortalCellOnFirstScrollableColumn
: isRecordTableScrolledVertically
? TABLE_Z_INDEX.withGroups.scrolledVerticallyOnly
.hoverPortalCellOnFirstScrollableColumn
: TABLE_Z_INDEX.withGroups.noScrollAtAll
.hoverPortalCellOnFirstScrollableColumn;
const zIndexForHoveredPortalOnLabelIdentifierStickyColumnWithGroups =
isRecordTableScrolledHorizontally && isRecordTableScrolledVertically
? TABLE_Z_INDEX.withGroups.scrolledBothVerticallyAndHorizontally
.hoverPortalCellOnLabelIdentifierColumn
: isRecordTableScrolledHorizontally
? TABLE_Z_INDEX.withGroups.scrolledHorizontallyOnly
.hoverPortalCellOnLabelIdentifierColumn
: isRecordTableScrolledVertically
? TABLE_Z_INDEX.withGroups.scrolledVerticallyOnly
.hoverPortalCellOnLabelIdentifierColumn
: TABLE_Z_INDEX.withGroups.noScrollAtAll
.hoverPortalCellOnLabelIdentifierColumn;
const zIndexForHoveredPortalOnNormalColumnWithGroups =
isRecordTableScrolledHorizontally && isRecordTableScrolledVertically
? TABLE_Z_INDEX.withGroups.scrolledBothVerticallyAndHorizontally
.hoverPortalCellOnNormalColumn
: isRecordTableScrolledHorizontally
? TABLE_Z_INDEX.withGroups.scrolledHorizontallyOnly
.hoverPortalCellOnNormalColumn
: isRecordTableScrolledVertically
? TABLE_Z_INDEX.withGroups.scrolledVerticallyOnly
.hoverPortalCellOnNormalColumn
: TABLE_Z_INDEX.withGroups.noScrollAtAll
.hoverPortalCellOnNormalColumn;
const zIndexForHoveredPortalWithGroups = isOnFirstScrollableColumn
? zIndexForHoveredPortalOnFirstScrollableColumnWithGroups
: isOnLabelIdentifierStickyColumn
? zIndexForHoveredPortalOnLabelIdentifierStickyColumnWithGroups
: zIndexForHoveredPortalOnNormalColumnWithGroups;
const zIndex = hasRecordGroups
? zIndexForHoveredPortalWithGroups
: zIndexForHoveredPortalWithoutGroups;
return (
<RecordTableCellPortalWrapper position={recordTableHoverPosition}>
<RecordTableCellPortalRootContainer zIndex={zIndex}>
<RecordTableCellPortalRootContainer zIndex={TABLE_Z_INDEX.hoverPortal}>
<RecordTableCellHoveredPortalContent />
</RecordTableCellPortalRootContainer>
</RecordTableCellPortalWrapper>
@@ -43,6 +43,7 @@ const StyledRecordTableCellHoveredPortalContent = styled.div<{
: showInteractiveStyle
? `1px solid ${themeCssVariables.font.color.extraLight}`
: `1px solid ${themeCssVariables.border.color.medium}`};
outline-offset: -1px;
user-select: none;
`;
@@ -1,7 +1,6 @@
import { styled } from '@linaria/react';
import { RECORD_TABLE_COLUMN_ADD_COLUMN_BUTTON_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnAddColumnButtonWidth';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { RECORD_TABLE_COLUMN_CHECKBOX_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnCheckboxWidth';
import { RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnDragAndDropWidth';
import { RECORD_TABLE_COLUMN_LAST_EMPTY_COLUMN_WIDTH_CLASS_NAME } from '@/object-record/record-table/constants/RecordTableColumnLastEmptyColumnWidthClassName';
@@ -10,13 +9,13 @@ import { useRecordTableContextOrThrow } from '@/object-record/record-table/conte
import { RecordTableAggregateFooterCell } from '@/object-record/record-table/record-table-footer/components/RecordTableAggregateFooterCell';
import { RecordTableColumnAggregateFooterCellContext } from '@/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterCellContext';
import { isDefined } from 'twenty-shared/utils';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledPlaceholderDragAndDropFooterCell = styled.div<{
isTableWithGroups: boolean;
}>`
background-color: ${themeCssVariables.background.primary};
width: ${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH +
RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px;
width: ${`${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH + RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px`};
position: sticky;
left: 0px;
bottom: 0;
@@ -11,7 +11,6 @@ import { hasRecordGroupsComponentSelector } from '@/object-record/record-group/s
import { isRecordTableRowActiveComponentFamilyState } from '@/object-record/record-table/states/isRecordTableRowActiveComponentFamilyState';
import { isRecordTableRowFocusActiveComponentState } from '@/object-record/record-table/states/isRecordTableRowFocusActiveComponentState';
import { isRecordTableRowFocusedComponentFamilyState } from '@/object-record/record-table/states/isRecordTableRowFocusedComponentFamilyState';
import { isRecordTableScrolledHorizontallyComponentState } from '@/object-record/record-table/states/isRecordTableScrolledHorizontallyComponentState';
import { isRecordTableScrolledVerticallyComponentState } from '@/object-record/record-table/states/isRecordTableScrolledVerticallyComponentState';
import { resizedFieldMetadataIdComponentState } from '@/object-record/record-table/states/resizedFieldMetadataIdComponentState';
import { getRecordTableColumnFieldWidthClassName } from '@/object-record/record-table/utils/getRecordTableColumnFieldWidthClassName';
@@ -56,39 +55,13 @@ export const RecordTableHeaderFirstScrollableCell = () => {
isRecordTableScrolledVerticallyComponentState,
);
const isRecordTableScrolledHorizontally = useAtomComponentStateValue(
isRecordTableScrolledHorizontallyComponentState,
);
const hasRecordGroups = useAtomComponentSelectorValue(
hasRecordGroupsComponentSelector,
);
const zIndexWithGroups =
isRecordTableScrolledHorizontally && isRecordTableScrolledVertically
? TABLE_Z_INDEX.withGroups.scrolledBothVerticallyAndHorizontally
.firstScrollableHeaderCell
: isRecordTableScrolledHorizontally
? TABLE_Z_INDEX.withGroups.scrolledHorizontallyOnly
.firstScrollableHeaderCell
: isRecordTableScrolledVertically
? TABLE_Z_INDEX.withGroups.scrolledVerticallyOnly
.firstScrollableHeaderCell
: TABLE_Z_INDEX.withGroups.noScrollAtAll.firstScrollableHeaderCell;
const zIndexWithoutGroups =
isRecordTableScrolledHorizontally && isRecordTableScrolledVertically
? TABLE_Z_INDEX.withoutGroups.scrolledBothVerticallyAndHorizontally
.firstScrollableHeaderCell
: isRecordTableScrolledHorizontally
? TABLE_Z_INDEX.withoutGroups.scrolledHorizontallyOnly
.firstScrollableHeaderCell
: isRecordTableScrolledVertically
? TABLE_Z_INDEX.withoutGroups.scrolledVerticallyOnly
.firstScrollableHeaderCell
: TABLE_Z_INDEX.withoutGroups.noScrollAtAll.firstScrollableHeaderCell;
const zIndex = hasRecordGroups ? zIndexWithGroups : zIndexWithoutGroups;
const zIndex = hasRecordGroups
? TABLE_Z_INDEX.headerColumns.withGroups.headerColumnsNormal
: TABLE_Z_INDEX.headerColumns.withoutGroups.headerColumnsNormal;
const shouldDisplayBorderBottom =
hasRecordGroups ||
@@ -1,7 +1,6 @@
import { styled } from '@linaria/react';
import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { RECORD_TABLE_COLUMN_CHECKBOX_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnCheckboxWidth';
import { RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnDragAndDropWidth';
import { RECORD_TABLE_COLUMN_MIN_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnMinWidth';
@@ -18,6 +17,7 @@ import {
sumByProperty,
} from 'twenty-shared/utils';
import { type IconComponent } from 'twenty-ui/display';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { useIsMobile } from 'twenty-ui/utilities';
const StyledDragDropPlaceholderCell = styled(
@@ -79,8 +79,7 @@ const StyledActionTextContainer = styled.div<{ width: number }>`
height: ${RECORD_TABLE_ROW_HEIGHT}px;
justify-content: start;
left: ${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH +
RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px;
left: ${`${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH + RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px`};
position: sticky;
width: ${({ width }) => width}px;
`;
@@ -82,8 +82,7 @@ const StyledRecordGroupSection = styled.div<{ width: number }>`
min-width: ${({ width }) => width}px;
position: sticky;
left: ${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH +
RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px;
left: ${`${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH + RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px`};
z-index: ${TABLE_Z_INDEX.groupSection.stickyCell};
`;