Files
twenty/packages/twenty-front/src/modules/ui/layout/dropdown/components/DropdownMenuHeader.tsx
T
Raphaël Bosi f44e2935df Fix filter multi select (#8682)
- Created a dropdown inside a dropdown for the
`ObjectFilterDropdownOperandDropdown` so the operand can be opened over
the selection with an offset
- Refactored dropdown component and introduced `DropdownUnmountEffect`
to close the dropdown when the component unmounts
- Removed old logic

Before:
<img width="216" alt="Capture d’écran 2024-11-22 à 14 03 58"
src="https://github.com/user-attachments/assets/3c1bba03-af03-4993-a070-f009b8dc876f">

After:
<img width="222" alt="Capture d’écran 2024-11-22 à 14 03 40"
src="https://github.com/user-attachments/assets/a8a784b4-8672-4b02-bb21-e4a749682f2e">
2024-11-22 14:08:29 +00:00

93 lines
2.5 KiB
TypeScript

import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { ComponentProps, MouseEvent } from 'react';
import { IconComponent, LightIconButton } from 'twenty-ui';
const StyledHeader = styled.li`
align-items: center;
color: ${({ theme }) => theme.font.color.primary};
cursor: ${({ onClick }) => (onClick ? 'pointer' : 'default')};
display: flex;
font-size: ${({ theme, onClick }) =>
onClick ? theme.font.size.sm : theme.font.size.md};
font-weight: ${({ theme }) => theme.font.weight.medium};
border-top-left-radius: ${({ theme }) => theme.border.radius.sm};
border-top-right-radius: ${({ theme }) => theme.border.radius.sm};
border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
padding: ${({ theme }) => theme.spacing(1)};
user-select: none;
width: inherit;
&:hover {
background: ${({ theme, onClick }) =>
onClick ? theme.background.transparent.light : 'none'};
}
`;
const StyledEndIcon = styled.div`
display: inline-flex;
color: ${({ theme }) => theme.font.color.tertiary};
padding: ${({ theme }) => theme.spacing(1)};
margin-left: auto;
margin-right: 0;
& > svg {
height: ${({ theme }) => theme.icon.size.md}px;
width: ${({ theme }) => theme.icon.size.md}px;
}
`;
const StyledChildrenWrapper = styled.span`
overflow: hidden;
padding: 0 ${({ theme }) => theme.spacing(1)};
`;
type DropdownMenuHeaderProps = ComponentProps<'li'> & {
StartIcon?: IconComponent;
EndIcon?: IconComponent;
onClick?: (event: MouseEvent<HTMLButtonElement>) => void;
testId?: string;
className?: string;
};
export const DropdownMenuHeader = ({
children,
StartIcon,
EndIcon,
onClick,
testId,
className,
}: DropdownMenuHeaderProps) => {
const theme = useTheme();
return (
<>
{EndIcon && (
<StyledHeader
data-testid={testId}
onClick={onClick}
className={className}
>
<StyledChildrenWrapper>{children}</StyledChildrenWrapper>
<StyledEndIcon>
<EndIcon size={theme.icon.size.md} />
</StyledEndIcon>
</StyledHeader>
)}
{StartIcon && (
<StyledHeader data-testid={testId} className={className}>
<LightIconButton
testId="dropdown-menu-header-end-icon"
Icon={StartIcon}
accent="tertiary"
size="small"
onClick={onClick}
/>
<StyledChildrenWrapper>{children}</StyledChildrenWrapper>
</StyledHeader>
)}
</>
);
};