59029a0035
Fixes #15327 The issue occurred because the drag clone's visual state was previously tied strictly to hovering over the `VISIBLE_TABS` boundaries. When a tab was dragged outside this area (such as the last tab naturally crossing into the `MORE_BUTTON` hover zone), the drag clone incorrectly fell back to the dropdown menu item style. We fixed this by making the `isHoveringTabList` logic more robust. Instead of enforcing the tab style only within the `VISIBLE_TABS` boundary, the dropdown style is now strictly restricted to the `OVERFLOW_TABS` boundary. With this change: - Visible tabs successfully maintain their appearance when dragged anywhere outside the dropdown. - Dropdown tabs correctly transition to the normal tab style when dragged out of the dropdown area, improving UX. https://github.com/user-attachments/assets/9474e4c1-26a8-46e3-b9ee-4c6dbd8a4ea6 --------- Co-authored-by: Arun kumar <arunkumar@Aruns-MacBook-Air.local> Co-authored-by: ehconitin <nitinkoche03@gmail.com> Co-authored-by: nitin <142569587+ehconitin@users.noreply.github.com> Co-authored-by: Charles Bochet <charles@twenty.com>
102 lines
3.3 KiB
TypeScript
102 lines
3.3 KiB
TypeScript
import { isDefined } from 'twenty-shared/utils';
|
|
import { PAGE_LAYOUT_TAB_LIST_DROPPABLE_IDS } from '@/page-layout/components/PageLayoutTabListDroppableIds';
|
|
import { pageLayoutTabListCurrentDragDroppableIdComponentState } from '@/page-layout/states/pageLayoutTabListCurrentDragDroppableIdComponentState';
|
|
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
|
|
import { TabAvatar } from '@/ui/layout/tab-list/components/TabAvatar';
|
|
import { type SingleTabProps } from '@/ui/layout/tab-list/types/SingleTabProps';
|
|
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
|
|
import { type DraggableProvided } from '@hello-pangea/dnd';
|
|
import { styled } from '@linaria/react';
|
|
import { useContext } from 'react';
|
|
import { StyledTabContainer, TabContent } from 'twenty-ui/input';
|
|
import { MenuItemSelectAvatar } from 'twenty-ui/navigation';
|
|
import { ThemeContext } from 'twenty-ui/theme-constants';
|
|
const StyledDraggableWrapper = styled.div`
|
|
cursor: grab;
|
|
display: flex;
|
|
|
|
&:active {
|
|
cursor: grabbing;
|
|
}
|
|
`;
|
|
|
|
export const PageLayoutTabRenderClone = ({
|
|
tab,
|
|
provided,
|
|
activeTabId,
|
|
}: {
|
|
tab: SingleTabProps;
|
|
provided: DraggableProvided;
|
|
activeTabId: string | null;
|
|
}) => {
|
|
const { theme } = useContext(ThemeContext);
|
|
const pageLayoutTabListCurrentDragDroppableId = useAtomComponentStateValue(
|
|
pageLayoutTabListCurrentDragDroppableIdComponentState,
|
|
);
|
|
|
|
const isHoveringTabList =
|
|
pageLayoutTabListCurrentDragDroppableId !==
|
|
PAGE_LAYOUT_TAB_LIST_DROPPABLE_IDS.OVERFLOW_TABS;
|
|
|
|
if (!isDefined(tab)) return null;
|
|
|
|
if (isHoveringTabList) {
|
|
return (
|
|
<StyledDraggableWrapper
|
|
ref={provided.innerRef}
|
|
// oxlint-disable-next-line react/jsx-props-no-spreading
|
|
{...provided.draggableProps}
|
|
// oxlint-disable-next-line react/jsx-props-no-spreading
|
|
{...provided.dragHandleProps}
|
|
style={{
|
|
...provided.draggableProps.style,
|
|
cursor: 'grabbing',
|
|
}}
|
|
>
|
|
<StyledTabContainer active={tab.id === activeTabId} disabled={false}>
|
|
<TabContent
|
|
id={tab.id}
|
|
active={false}
|
|
disabled={false}
|
|
LeftIcon={tab.Icon}
|
|
title={tab.title}
|
|
logo={tab.logo}
|
|
pill={tab.pill}
|
|
/>
|
|
</StyledTabContainer>
|
|
</StyledDraggableWrapper>
|
|
);
|
|
} else {
|
|
return (
|
|
<StyledDraggableWrapper
|
|
id={'clone-drag-wrapper'}
|
|
ref={provided.innerRef}
|
|
// oxlint-disable-next-line react/jsx-props-no-spreading
|
|
{...provided.draggableProps}
|
|
// oxlint-disable-next-line react/jsx-props-no-spreading
|
|
{...provided.dragHandleProps}
|
|
style={{
|
|
...provided.draggableProps.style,
|
|
cursor: 'grabbing',
|
|
}}
|
|
>
|
|
<div
|
|
style={{
|
|
minWidth:
|
|
GenericDropdownContentWidth.Medium -
|
|
theme.spacingMultiplicator * 2,
|
|
}}
|
|
>
|
|
<MenuItemSelectAvatar
|
|
text={tab.title}
|
|
avatar={<TabAvatar tab={tab} />}
|
|
selected={tab.id === activeTabId}
|
|
onClick={undefined}
|
|
disabled
|
|
/>
|
|
</div>
|
|
</StyledDraggableWrapper>
|
|
);
|
|
}
|
|
};
|