add the contextual text for multiselectavatar and selectavatar (#14807)

necessary for the new design from @bonapara in Figma here
https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=70184-191735&t=s5CaYKWjRp64ECkN-11

Should look like this
<img width="397" height="416" alt="Screenshot 2025-10-01 at 11 25 00"
src="https://github.com/user-attachments/assets/fe585d34-f9b9-438a-91e2-8177722cc922"
/>

As you can see in the storybook, it looks like this :
<img width="681" height="414" alt="Screenshot 2025-10-01 at 11 25 25"
src="https://github.com/user-attachments/assets/8fa1b99c-9eb0-4f1e-a0a2-4ad136f977cc"
/>


Tech:
I took the same wording as "contextualText" as defined in the other
select component but decided to stay string only since I did not want to
overcomplicate the API for now. In that, it slightly differs from the
other components designed by @bosiraphael a week ago I think
This commit is contained in:
Guillim
2025-10-01 16:42:48 +02:00
committed by GitHub
parent 1b985ed5b1
commit bb0d37d79f
5 changed files with 53 additions and 6 deletions
@@ -6,6 +6,7 @@ import { Checkbox } from '@ui/input/components/Checkbox';
import {
StyledMenuItemBase,
StyledMenuItemLabel,
StyledMenuItemLabelLight,
StyledMenuItemLeftContent,
} from '../internals/components/StyledMenuItemBase';
@@ -17,11 +18,19 @@ const StyledLeftContentWithCheckboxContainer = styled.div`
width: 100%;
`;
const StyledTextContainer = styled.div`
display: flex;
align-items: center;
flex: 1 0 0;
gap: ${({ theme }) => theme.spacing(1)};
`;
type MenuItemMultiSelectAvatarProps = {
avatar?: ReactNode;
selected: boolean;
isKeySelected?: boolean;
text?: string;
contextualText?: string;
className?: string;
onSelectChange?: (selected: boolean) => void;
};
@@ -30,6 +39,7 @@ export const MenuItemMultiSelectAvatar = ({
avatar,
text,
selected,
contextualText,
className,
isKeySelected,
onSelectChange,
@@ -48,9 +58,19 @@ export const MenuItemMultiSelectAvatar = ({
<Checkbox checked={selected} />
<StyledMenuItemLeftContent>
{avatar}
<StyledMenuItemLabel>
<OverflowingTextWithTooltip text={text} />
</StyledMenuItemLabel>
<StyledTextContainer>
<StyledMenuItemLabel>
<OverflowingTextWithTooltip text={text} />
</StyledMenuItemLabel>
{contextualText && (
<>
<StyledMenuItemLabelLight>·</StyledMenuItemLabelLight>
<StyledMenuItemLabelLight>
<OverflowingTextWithTooltip text={contextualText} />
</StyledMenuItemLabelLight>
</>
)}
</StyledTextContainer>
</StyledMenuItemLeftContent>
</StyledLeftContentWithCheckboxContainer>
</StyledMenuItemBase>
@@ -4,9 +4,11 @@ import { type ReactNode } from 'react';
import {
StyledMenuItemIconCheck,
StyledMenuItemLabel,
StyledMenuItemLabelLight,
StyledMenuItemLeftContent,
} from '../internals/components/StyledMenuItemBase';
import styled from '@emotion/styled';
import { OverflowingTextWithTooltip } from '@ui/display';
import { StyledMenuItemSelect } from './MenuItemSelect';
@@ -14,6 +16,7 @@ type MenuItemSelectAvatarProps = {
avatar?: ReactNode;
selected: boolean;
text: string;
contextualText?: string;
className?: string;
onClick?: (event?: React.MouseEvent) => void;
disabled?: boolean;
@@ -21,9 +24,17 @@ type MenuItemSelectAvatarProps = {
testId?: string;
};
const StyledTextContainer = styled.div`
display: flex;
align-items: center;
flex: 1 0 0;
gap: ${({ theme }) => theme.spacing(1)};
`;
export const MenuItemSelectAvatar = ({
avatar,
text,
contextualText,
selected,
className,
onClick,
@@ -46,9 +57,19 @@ export const MenuItemSelectAvatar = ({
>
<StyledMenuItemLeftContent>
{avatar}
<StyledMenuItemLabel>
<OverflowingTextWithTooltip text={text} />
</StyledMenuItemLabel>
<StyledTextContainer>
<StyledMenuItemLabel>
<OverflowingTextWithTooltip text={text} />
</StyledMenuItemLabel>
{contextualText && (
<>
<StyledMenuItemLabelLight>·</StyledMenuItemLabelLight>
<StyledMenuItemLabelLight>
<OverflowingTextWithTooltip text={contextualText} />
</StyledMenuItemLabelLight>
</>
)}
</StyledTextContainer>
</StyledMenuItemLeftContent>
{selected && <StyledMenuItemIconCheck size={theme.icon.size.md} />}
</StyledMenuItemSelect>
@@ -24,6 +24,7 @@ type Story = StoryObj<typeof MenuItemMultiSelectAvatar>;
export const Default: Story = {
args: {
text: 'First option',
contextualText: 'Contextual text',
avatar: <Avatar avatarUrl={AVATAR_URL_MOCK} placeholder="L" />,
},
decorators: [ComponentDecorator, RecoilRootDecorator],
@@ -23,6 +23,7 @@ type Story = StoryObj<typeof MenuItemSelectAvatar>;
export const Default: Story = {
args: {
text: 'First option',
contextualText: 'Contextual text',
avatar: <Avatar avatarUrl={AVATAR_URL_MOCK} placeholder="L" />,
},
argTypes: {
@@ -96,6 +96,10 @@ export const StyledMenuItemLabel = styled.div`
white-space: nowrap;
`;
export const StyledMenuItemLabelLight = styled(StyledMenuItemLabel)`
color: ${({ theme }) => theme.font.color.light};
`;
export const StyledNoIconFiller = styled.div`
width: ${({ theme }) => theme.spacing(1)};
`;