Improve command menu chip design (#9915)
Before: <img width="236" alt="Capture d’écran 2025-01-29 à 17 07 13" src="https://github.com/user-attachments/assets/edc277f3-3e50-405a-9981-3ac63e270f3f" /> <img width="259" alt="Capture d’écran 2025-01-29 à 17 07 23" src="https://github.com/user-attachments/assets/81863c50-5b96-4cbf-bc15-ab437d839fa1" /> <img width="224" alt="Capture d’écran 2025-01-29 à 17 07 41" src="https://github.com/user-attachments/assets/c0783544-6928-4b05-bf86-66d37ddca5e5" /> After: <img width="230" alt="Capture d’écran 2025-01-29 à 17 03 49" src="https://github.com/user-attachments/assets/c47be446-32fa-40d1-af25-207ed91c0ea2" /> <img width="254" alt="Capture d’écran 2025-01-29 à 17 04 15" src="https://github.com/user-attachments/assets/99b9ab30-c77d-4392-8ef6-2a1a5fb00047" /> <img width="218" alt="Capture d’écran 2025-01-29 à 17 04 37" src="https://github.com/user-attachments/assets/6e214a42-438d-495f-9855-fd5397fcc6d3" />
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
import { Fragment } from 'react/jsx-runtime';
|
||||||
|
|
||||||
const StyledChip = styled.div<{ variant?: 'default' | 'small' }>`
|
const StyledChip = styled.div`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background: ${({ theme }) => theme.background.transparent.light};
|
background: ${({ theme }) => theme.background.transparent.light};
|
||||||
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
||||||
@ -8,8 +9,7 @@ const StyledChip = styled.div<{ variant?: 'default' | 'small' }>`
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: ${({ theme }) => theme.spacing(1)};
|
gap: ${({ theme }) => theme.spacing(1)};
|
||||||
height: ${({ theme, variant }) =>
|
height: ${({ theme }) => theme.spacing(6)};
|
||||||
variant === 'small' ? theme.spacing(6) : theme.spacing(8)};
|
|
||||||
padding: 0 ${({ theme }) => theme.spacing(2)};
|
padding: 0 ${({ theme }) => theme.spacing(2)};
|
||||||
font-size: ${({ theme }) => theme.font.size.sm};
|
font-size: ${({ theme }) => theme.font.size.sm};
|
||||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||||
@ -21,43 +21,18 @@ const StyledIconsContainer = styled.div`
|
|||||||
display: flex;
|
display: flex;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledIconWrapper = styled.div<{ withIconBackground?: boolean }>`
|
|
||||||
background: ${({ theme, withIconBackground }) =>
|
|
||||||
withIconBackground ? theme.background.primary : 'unset'};
|
|
||||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
|
||||||
padding: ${({ theme }) => theme.spacing(0.5)};
|
|
||||||
border: 1px solid
|
|
||||||
${({ theme, withIconBackground }) =>
|
|
||||||
withIconBackground ? theme.border.color.medium : 'transparent'};
|
|
||||||
&:not(:first-of-type) {
|
|
||||||
margin-left: -${({ theme }) => theme.spacing(1)};
|
|
||||||
}
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const CommandMenuContextChip = ({
|
export const CommandMenuContextChip = ({
|
||||||
Icons,
|
Icons,
|
||||||
text,
|
text,
|
||||||
withIconBackground,
|
|
||||||
variant = 'default',
|
|
||||||
}: {
|
}: {
|
||||||
Icons: React.ReactNode[];
|
Icons: React.ReactNode[];
|
||||||
text?: string;
|
text?: string;
|
||||||
withIconBackground?: boolean;
|
|
||||||
variant?: 'default' | 'small';
|
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<StyledChip variant={variant}>
|
<StyledChip>
|
||||||
<StyledIconsContainer>
|
<StyledIconsContainer>
|
||||||
{Icons.map((Icon, index) => (
|
{Icons.map((Icon, index) => (
|
||||||
<StyledIconWrapper
|
<Fragment key={index}>{Icon}</Fragment>
|
||||||
key={index}
|
|
||||||
withIconBackground={withIconBackground}
|
|
||||||
>
|
|
||||||
{Icon}
|
|
||||||
</StyledIconWrapper>
|
|
||||||
))}
|
))}
|
||||||
</StyledIconsContainer>
|
</StyledIconsContainer>
|
||||||
<span>{text}</span>
|
<span>{text}</span>
|
||||||
|
|||||||
@ -7,11 +7,9 @@ import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMeta
|
|||||||
export const CommandMenuContextRecordChip = ({
|
export const CommandMenuContextRecordChip = ({
|
||||||
objectMetadataItemId,
|
objectMetadataItemId,
|
||||||
instanceId,
|
instanceId,
|
||||||
variant = 'default',
|
|
||||||
}: {
|
}: {
|
||||||
objectMetadataItemId: string;
|
objectMetadataItemId: string;
|
||||||
instanceId?: string;
|
instanceId?: string;
|
||||||
variant?: 'default' | 'small';
|
|
||||||
}) => {
|
}) => {
|
||||||
const { objectMetadataItem } = useObjectMetadataItemById({
|
const { objectMetadataItem } = useObjectMetadataItemById({
|
||||||
objectId: objectMetadataItemId,
|
objectId: objectMetadataItemId,
|
||||||
@ -43,8 +41,6 @@ export const CommandMenuContextRecordChip = ({
|
|||||||
totalCount,
|
totalCount,
|
||||||
)}
|
)}
|
||||||
Icons={Avatars}
|
Icons={Avatars}
|
||||||
withIconBackground={true}
|
|
||||||
variant={variant}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,8 +3,24 @@ import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
|||||||
import { useRecordChipData } from '@/object-record/hooks/useRecordChipData';
|
import { useRecordChipData } from '@/object-record/hooks/useRecordChipData';
|
||||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
import { useTheme } from '@emotion/react';
|
import { useTheme } from '@emotion/react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
import { Avatar } from 'twenty-ui';
|
import { Avatar } from 'twenty-ui';
|
||||||
|
|
||||||
|
const StyledIconWrapper = styled.div<{ withIconBackground?: boolean }>`
|
||||||
|
background: ${({ theme, withIconBackground }) =>
|
||||||
|
withIconBackground ? theme.background.primary : 'unset'};
|
||||||
|
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||||
|
border: 1px solid
|
||||||
|
${({ theme, withIconBackground }) =>
|
||||||
|
withIconBackground ? theme.border.color.medium : 'transparent'};
|
||||||
|
&:not(:first-of-type) {
|
||||||
|
margin-left: -${({ theme }) => theme.spacing(1)};
|
||||||
|
}
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
`;
|
||||||
|
|
||||||
export const CommandMenuContextRecordChipAvatars = ({
|
export const CommandMenuContextRecordChipAvatars = ({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
record,
|
record,
|
||||||
@ -24,7 +40,9 @@ export const CommandMenuContextRecordChipAvatars = ({
|
|||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<StyledIconWrapper
|
||||||
|
withIconBackground={recordChipData.avatarType !== 'rounded'}
|
||||||
|
>
|
||||||
{Icon ? (
|
{Icon ? (
|
||||||
<Icon color={IconColor} size={theme.icon.size.sm} />
|
<Icon color={IconColor} size={theme.icon.size.sm} />
|
||||||
) : (
|
) : (
|
||||||
@ -36,6 +54,6 @@ export const CommandMenuContextRecordChipAvatars = ({
|
|||||||
size="sm"
|
size="sm"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</StyledIconWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -47,7 +47,6 @@ export const ResetContextToSelectionCommandButton = () => {
|
|||||||
<CommandMenuContextRecordChip
|
<CommandMenuContextRecordChip
|
||||||
objectMetadataItemId={objectMetadataItem.id}
|
objectMetadataItemId={objectMetadataItem.id}
|
||||||
instanceId="command-menu-previous"
|
instanceId="command-menu-previous"
|
||||||
variant="small"
|
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
onClick={resetPreviousCommandMenuContext}
|
onClick={resetPreviousCommandMenuContext}
|
||||||
|
|||||||
@ -30,22 +30,6 @@ export const MultipleIcons: Story = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const WithIconBackground: Story = {
|
|
||||||
args: {
|
|
||||||
Icons: [<IconUser size={16} />],
|
|
||||||
text: 'Person',
|
|
||||||
withIconBackground: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const MultipleIconsWithIconBackground: Story = {
|
|
||||||
args: {
|
|
||||||
Icons: [<IconUser size={16} />, <IconBuildingSkyscraper size={16} />],
|
|
||||||
text: 'Person & Company',
|
|
||||||
withIconBackground: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export const IconsOnly: Story = {
|
export const IconsOnly: Story = {
|
||||||
args: {
|
args: {
|
||||||
Icons: [<IconUser size={16} />, <IconBuildingSkyscraper size={16} />],
|
Icons: [<IconUser size={16} />, <IconBuildingSkyscraper size={16} />],
|
||||||
|
|||||||
@ -9,5 +9,12 @@ export const getAvatarType = (objectNameSingular: string) => {
|
|||||||
return 'squared';
|
return 'squared';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
objectNameSingular === CoreObjectNameSingular.Task ||
|
||||||
|
objectNameSingular === CoreObjectNameSingular.Note
|
||||||
|
) {
|
||||||
|
return 'icon';
|
||||||
|
}
|
||||||
|
|
||||||
return 'rounded';
|
return 'rounded';
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user