mirror of
https://github.com/twentyhq/twenty.git
synced 2024-11-28 17:25:10 +03:00
2294 feat(frontend): styling shortcut keys (#2336)
* 2294 feat(frontend): styling shortcut keys * 2294 fix(front): pr requested changes * Fix component interface --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
parent
aa09b5758c
commit
279630052f
@ -88,13 +88,9 @@ export const CommandMenu = () => {
|
||||
const activities = activityData?.searchResults ?? [];
|
||||
|
||||
const checkInShortcuts = (cmd: Command, search: string) => {
|
||||
if (cmd.shortcuts && cmd.shortcuts.length > 0) {
|
||||
return cmd.shortcuts
|
||||
.join('')
|
||||
.toLowerCase()
|
||||
.includes(search.toLowerCase());
|
||||
}
|
||||
return false;
|
||||
return (cmd.firstHotKey + (cmd.secondHotKey ?? ''))
|
||||
.toLowerCase()
|
||||
.includes(search.toLowerCase());
|
||||
};
|
||||
|
||||
const checkInLabels = (cmd: Command, search: string) => {
|
||||
@ -144,7 +140,8 @@ export const CommandMenu = () => {
|
||||
Icon={cmd.Icon}
|
||||
label={cmd.label}
|
||||
onClick={cmd.onCommandClick}
|
||||
shortcuts={cmd.shortcuts || []}
|
||||
firstHotKey={cmd.firstHotKey}
|
||||
secondHotKey={cmd.secondHotKey}
|
||||
/>
|
||||
))}
|
||||
</CommandGroup>
|
||||
@ -156,7 +153,8 @@ export const CommandMenu = () => {
|
||||
label={cmd.label}
|
||||
Icon={cmd.Icon}
|
||||
onClick={cmd.onCommandClick}
|
||||
shortcuts={cmd.shortcuts || []}
|
||||
firstHotKey={cmd.firstHotKey}
|
||||
secondHotKey={cmd.secondHotKey}
|
||||
/>
|
||||
))}
|
||||
</CommandGroup>
|
||||
|
@ -12,7 +12,8 @@ export type CommandMenuItemProps = {
|
||||
key: string;
|
||||
onClick?: () => void;
|
||||
Icon?: IconComponent;
|
||||
shortcuts?: Array<string>;
|
||||
firstHotKey?: string;
|
||||
secondHotKey?: string;
|
||||
};
|
||||
|
||||
export const CommandMenuItem = ({
|
||||
@ -20,7 +21,8 @@ export const CommandMenuItem = ({
|
||||
to,
|
||||
onClick,
|
||||
Icon,
|
||||
shortcuts,
|
||||
firstHotKey,
|
||||
secondHotKey,
|
||||
}: CommandMenuItemProps) => {
|
||||
const navigate = useNavigate();
|
||||
const { closeCommandMenu } = useCommandMenu();
|
||||
@ -46,7 +48,8 @@ export const CommandMenuItem = ({
|
||||
<MenuItemCommand
|
||||
LeftIcon={Icon}
|
||||
text={label}
|
||||
command={shortcuts ? shortcuts.join(' then ') : ''}
|
||||
firstHotKey={firstHotKey}
|
||||
secondHotKey={secondHotKey}
|
||||
onClick={onItemClick}
|
||||
/>
|
||||
);
|
||||
|
@ -13,35 +13,40 @@ export const commandMenuCommands: Command[] = [
|
||||
to: '/people',
|
||||
label: 'Go to People',
|
||||
type: CommandType.Navigate,
|
||||
shortcuts: ['G', 'P'],
|
||||
firstHotKey: 'G',
|
||||
secondHotKey: 'P',
|
||||
Icon: IconUser,
|
||||
},
|
||||
{
|
||||
to: '/companies',
|
||||
label: 'Go to Companies',
|
||||
type: CommandType.Navigate,
|
||||
shortcuts: ['G', 'C'],
|
||||
firstHotKey: 'G',
|
||||
secondHotKey: 'C',
|
||||
Icon: IconBuildingSkyscraper,
|
||||
},
|
||||
{
|
||||
to: '/opportunities',
|
||||
label: 'Go to Opportunities',
|
||||
type: CommandType.Navigate,
|
||||
shortcuts: ['G', 'O'],
|
||||
firstHotKey: 'G',
|
||||
secondHotKey: 'O',
|
||||
Icon: IconTargetArrow,
|
||||
},
|
||||
{
|
||||
to: '/settings/profile',
|
||||
label: 'Go to Settings',
|
||||
type: CommandType.Navigate,
|
||||
shortcuts: ['G', 'S'],
|
||||
firstHotKey: 'G',
|
||||
secondHotKey: 'S',
|
||||
Icon: IconSettings,
|
||||
},
|
||||
{
|
||||
to: '/tasks',
|
||||
label: 'Go to Tasks',
|
||||
type: CommandType.Navigate,
|
||||
shortcuts: ['G', 'T'],
|
||||
firstHotKey: 'G',
|
||||
secondHotKey: 'T',
|
||||
Icon: IconCheckbox,
|
||||
},
|
||||
];
|
||||
|
@ -10,6 +10,7 @@ export type Command = {
|
||||
label: string;
|
||||
type: CommandType.Navigate | CommandType.Create;
|
||||
Icon?: IconComponent;
|
||||
shortcuts?: string[];
|
||||
firstHotKey?: string;
|
||||
secondHotKey?: string;
|
||||
onCommandClick?: () => void;
|
||||
};
|
||||
|
@ -9,6 +9,8 @@ import {
|
||||
StyledMenuItemLeftContent,
|
||||
} from '../internals/components/StyledMenuItemBase';
|
||||
|
||||
import { MenuItemCommandHotKeys } from './MenuItemCommandHotKeys';
|
||||
|
||||
const StyledMenuItemLabelText = styled(StyledMenuItemLabel)`
|
||||
color: ${({ theme }) => theme.font.color.primary};
|
||||
`;
|
||||
@ -25,14 +27,6 @@ const StyledBigIconContainer = styled.div`
|
||||
padding: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
const StyledCommandText = styled.div`
|
||||
color: ${({ theme }) => theme.font.color.light};
|
||||
|
||||
padding-left: ${({ theme }) => theme.spacing(2)};
|
||||
padding-right: ${({ theme }) => theme.spacing(2)};
|
||||
white-space: nowrap;
|
||||
`;
|
||||
|
||||
const StyledMenuItemCommandContainer = styled(Command.Item)`
|
||||
--horizontal-padding: ${({ theme }) => theme.spacing(1)};
|
||||
--vertical-padding: ${({ theme }) => theme.spacing(2)};
|
||||
@ -58,17 +52,6 @@ const StyledMenuItemCommandContainer = styled(Command.Item)`
|
||||
}
|
||||
&[data-selected='true'] {
|
||||
background: ${({ theme }) => theme.background.tertiary};
|
||||
/* Could be nice to add a caret like this for better accessibility in the future
|
||||
But it needs to be consistend with other picker dropdown (e.g. company)
|
||||
&:after {
|
||||
background: ${({ theme }) => theme.background.quaternary};
|
||||
content: '';
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
width: 3px;
|
||||
z-index: ${({ theme }) => theme.lastLayerZIndex};
|
||||
} */
|
||||
}
|
||||
&[data-disabled='true'] {
|
||||
color: ${({ theme }) => theme.font.color.light};
|
||||
@ -83,7 +66,8 @@ const StyledMenuItemCommandContainer = styled(Command.Item)`
|
||||
export type MenuItemCommandProps = {
|
||||
LeftIcon?: IconComponent;
|
||||
text: string;
|
||||
command: string;
|
||||
firstHotKey?: string;
|
||||
secondHotKey?: string;
|
||||
className?: string;
|
||||
onClick?: () => void;
|
||||
};
|
||||
@ -91,7 +75,8 @@ export type MenuItemCommandProps = {
|
||||
export const MenuItemCommand = ({
|
||||
LeftIcon,
|
||||
text,
|
||||
command,
|
||||
firstHotKey,
|
||||
secondHotKey,
|
||||
className,
|
||||
onClick,
|
||||
}: MenuItemCommandProps) => {
|
||||
@ -109,7 +94,10 @@ export const MenuItemCommand = ({
|
||||
{text}
|
||||
</StyledMenuItemLabelText>
|
||||
</StyledMenuItemLeftContent>
|
||||
<StyledCommandText>{command}</StyledCommandText>
|
||||
<MenuItemCommandHotKeys
|
||||
firstHotKey={firstHotKey}
|
||||
secondHotKey={secondHotKey}
|
||||
/>
|
||||
</StyledMenuItemCommandContainer>
|
||||
);
|
||||
};
|
||||
|
@ -0,0 +1,62 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
const StyledCommandTextContainer = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
justify-content: center;
|
||||
`;
|
||||
|
||||
const StyledCommandText = styled.div`
|
||||
color: ${({ theme }) => theme.font.color.light};
|
||||
padding-bottom: ${({ theme }) => theme.spacing(1)};
|
||||
padding-left: ${({ theme }) => theme.spacing(2)};
|
||||
padding-right: ${({ theme }) => theme.spacing(2)};
|
||||
padding-top: ${({ theme }) => theme.spacing(1)};
|
||||
white-space: nowrap;
|
||||
`;
|
||||
|
||||
const StyledCommandKey = styled.div`
|
||||
align-items: center;
|
||||
background-color: ${({ theme }) => theme.background.secondary};
|
||||
border: 1px solid ${({ theme }) => theme.border.color.strong};
|
||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||
box-shadow: ${({ theme }) => theme.boxShadow.underline};
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
height: ${({ theme }) => theme.spacing(5)};
|
||||
height: 18px;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
width: ${({ theme }) => theme.spacing(4)};
|
||||
`;
|
||||
|
||||
export type MenuItemCommandHotKeysProps = {
|
||||
firstHotKey?: string;
|
||||
joinLabel?: string;
|
||||
secondHotKey?: string;
|
||||
};
|
||||
|
||||
export const MenuItemCommandHotKeys = ({
|
||||
firstHotKey,
|
||||
secondHotKey,
|
||||
joinLabel = 'then',
|
||||
}: MenuItemCommandHotKeysProps) => {
|
||||
return (
|
||||
<StyledCommandText>
|
||||
{firstHotKey && (
|
||||
<StyledCommandTextContainer>
|
||||
<StyledCommandKey>{firstHotKey}</StyledCommandKey>
|
||||
{secondHotKey && (
|
||||
<>
|
||||
{joinLabel}
|
||||
<StyledCommandKey>{secondHotKey}</StyledCommandKey>
|
||||
</>
|
||||
)}
|
||||
</StyledCommandTextContainer>
|
||||
)}
|
||||
</StyledCommandText>
|
||||
);
|
||||
};
|
@ -20,14 +20,16 @@ type Story = StoryObj<typeof MenuItemCommand>;
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
text: 'First option',
|
||||
command: '⌘ 1',
|
||||
firstHotKey: '⌘',
|
||||
secondHotKey: '1',
|
||||
},
|
||||
render: (props) => (
|
||||
<Command>
|
||||
<MenuItemCommand
|
||||
LeftIcon={props.LeftIcon}
|
||||
text={props.text}
|
||||
command={props.text}
|
||||
firstHotKey={props.firstHotKey}
|
||||
secondHotKey={props.secondHotKey}
|
||||
className={props.className}
|
||||
onClick={props.onClick}
|
||||
></MenuItemCommand>
|
||||
@ -37,12 +39,16 @@ export const Default: Story = {
|
||||
};
|
||||
|
||||
export const Catalog: CatalogStory<Story, typeof MenuItemCommand> = {
|
||||
args: { LeftIcon: IconBell, text: 'Menu item', command: '⌘1' },
|
||||
args: {
|
||||
text: 'Menu item',
|
||||
firstHotKey: '⌘',
|
||||
secondHotKey: '1',
|
||||
},
|
||||
argTypes: {
|
||||
className: { control: false },
|
||||
},
|
||||
parameters: {
|
||||
pseudo: { hover: ['.hover'], active: ['.pressed'], focus: ['.focus'] },
|
||||
pseudo: { hover: ['.hover'] },
|
||||
catalog: {
|
||||
dimensions: [
|
||||
{
|
||||
@ -54,13 +60,6 @@ export const Catalog: CatalogStory<Story, typeof MenuItemCommand> = {
|
||||
labels: (withIcon: boolean) =>
|
||||
withIcon ? 'With left icon' : 'Without left icon',
|
||||
},
|
||||
{
|
||||
name: 'selected',
|
||||
values: [true, false],
|
||||
props: () => ({}),
|
||||
labels: (selected: boolean) =>
|
||||
selected ? 'Selected' : 'Not selected',
|
||||
},
|
||||
{
|
||||
name: 'states',
|
||||
values: ['default', 'hover'],
|
||||
@ -88,7 +87,8 @@ export const Catalog: CatalogStory<Story, typeof MenuItemCommand> = {
|
||||
<MenuItemCommand
|
||||
LeftIcon={props.LeftIcon}
|
||||
text={props.text}
|
||||
command={props.text}
|
||||
firstHotKey={props.firstHotKey}
|
||||
secondHotKey={props.secondHotKey}
|
||||
className={props.className}
|
||||
onClick={props.onClick}
|
||||
></MenuItemCommand>
|
||||
|
@ -10,6 +10,7 @@ export const boxShadowLight = {
|
||||
grayScale.gray100,
|
||||
0.12,
|
||||
)}, 0px 2px 4px 0px ${rgba(grayScale.gray100, 0.04)}`,
|
||||
underline: `0px 1px 0px 0px ${rgba(grayScale.gray100, 0.32)}`,
|
||||
};
|
||||
|
||||
export const boxShadowDark = {
|
||||
@ -22,4 +23,5 @@ export const boxShadowDark = {
|
||||
grayScale.gray100,
|
||||
0.16,
|
||||
)}, 0px 2px 4px 0px ${rgba(grayScale.gray100, 0.08)}`,
|
||||
underline: `0px 1px 0px 0px ${rgba(grayScale.gray100, 0.32)}`,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user