From 25dc4077813183ecba6174556f6cbb7b97fe528e Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Wed, 19 Oct 2022 15:35:59 +0800 Subject: [PATCH] feat: add shortcuts modal --- packages/app/public/globals.css | 8 ++ .../app/src/components/contact-modal/style.ts | 16 ++-- packages/app/src/components/faq/icons.tsx | 14 +++ packages/app/src/components/faq/index.tsx | 52 ++++++++--- packages/app/src/components/faq/style.ts | 28 +++++- packages/app/src/components/modal/index.tsx | 41 --------- packages/app/src/components/popover/index.tsx | 2 +- .../src/components/shortcuts-modal/config.ts | 66 ++++++++++++++ .../src/components/shortcuts-modal/icons.tsx | 14 +++ .../src/components/shortcuts-modal/index.tsx | 87 ++++++++++++++++--- .../src/components/shortcuts-modal/style.ts | 65 ++++++++++++++ packages/app/src/styles/theme.ts | 19 ++-- packages/app/src/styles/types.ts | 9 +- 13 files changed, 334 insertions(+), 87 deletions(-) delete mode 100644 packages/app/src/components/modal/index.tsx create mode 100644 packages/app/src/components/shortcuts-modal/config.ts diff --git a/packages/app/public/globals.css b/packages/app/public/globals.css index 35d63bd2e7..7388399c01 100644 --- a/packages/app/public/globals.css +++ b/packages/app/public/globals.css @@ -181,3 +181,11 @@ input[type='number']::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } + +* { + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE 10+ */ +} +::-webkit-scrollbar { + display: none; /* Chrome Safari */ +} diff --git a/packages/app/src/components/contact-modal/style.ts b/packages/app/src/components/contact-modal/style.ts index a8476f70be..f3ef289bc8 100644 --- a/packages/app/src/components/contact-modal/style.ts +++ b/packages/app/src/components/contact-modal/style.ts @@ -15,7 +15,7 @@ export const StyledModalWrapper = styled('div')(({ theme }) => { return { width: '1000px', height: '626px', - background: ' #FFFFFF', + background: theme.colors.popoverBackground, padding: '0 48px', borderRadius: '20px', position: 'absolute', @@ -111,12 +111,14 @@ export const StyledSmallLink = styled('a')(({ theme }) => { }, }; }); -export const StyledSubTitle = styled('div')({ - width: '189px', - fontSize: '18px', - fontWeight: '600', - color: '#3A4C5C', - marginBottom: '24px', +export const StyledSubTitle = styled('div')(({theme}) => { + return ({ + width: '189px', + fontSize: '18px', + fontWeight: '600', + color: theme.colors.textColor, + marginBottom: '24px', + }) }); export const StyledLeftContainer = styled('div')({ diff --git a/packages/app/src/components/faq/icons.tsx b/packages/app/src/components/faq/icons.tsx index 9a4eba69ae..7c8797265d 100644 --- a/packages/app/src/components/faq/icons.tsx +++ b/packages/app/src/components/faq/icons.tsx @@ -43,3 +43,17 @@ export const KeyboardIcon = () => { ); }; + +export const CloseIcon = () => { + return ( + + + + ); +}; diff --git a/packages/app/src/components/faq/index.tsx b/packages/app/src/components/faq/index.tsx index 3beab8d438..af9d84a2d0 100644 --- a/packages/app/src/components/faq/index.tsx +++ b/packages/app/src/components/faq/index.tsx @@ -1,9 +1,15 @@ import { useState } from 'react'; -import { StyledFAQ, StyledIconWrapper, StyledFAQWrapper } from './style'; -import { ContactIcon, HelpIcon, KeyboardIcon } from './icons'; +import { + StyledFAQ, + StyledIconWrapper, + StyledFAQWrapper, + StyledTransformIcon, +} from './style'; +import { CloseIcon, ContactIcon, HelpIcon, KeyboardIcon } from './icons'; import Grow from '@mui/material/Grow'; import { Tooltip } from '../tooltip'; import ContactModal from '@/components/contact-modal'; +import ShortcutsModal from '@/components/shortcuts-modal'; const Contact = () => { const [openModal, setOpenModal] = useState(false); return ( @@ -21,9 +27,32 @@ const Contact = () => { ); }; + +const Shortcuts = () => { + const [openModal, setOpenModal] = useState(false); + return ( + <> + { + setOpenModal(false); + }} + /> + + + { + setOpenModal(true); + }} + > + + + + + ); +}; export const FAQ = () => { const [showContent, setShowContent] = useState(false); - return ( <> { - - - - - + - - - +
+ + + + + + +
); diff --git a/packages/app/src/components/faq/style.ts b/packages/app/src/components/faq/style.ts index b1744d90c4..f82ed8ccba 100644 --- a/packages/app/src/components/faq/style.ts +++ b/packages/app/src/components/faq/style.ts @@ -4,20 +4,38 @@ export const StyledFAQ = styled('div')(({ theme }) => { return { width: '32px', height: '32px', - backgroundColor: '#fff', color: theme.colors.iconColor, position: 'fixed', right: '30px', bottom: '30px', borderRadius: '50%', - zIndex: 1000, + zIndex: theme.zIndex.popover, ':hover': { backgroundColor: theme.colors.popoverBackground, color: theme.colors.primaryColor, }, }; }); - +export const StyledTransformIcon = styled.div<{ in: boolean }>( + ({ in: isIn, theme }) => ({ + height: '32px', + width: '32px', + borderRadius: '50%', + position: 'absolute', + left: '0', + right: '0', + bottom: '0', + top: '0', + margin: 'auto', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + opacity: isIn ? 1 : 0, + backgroundColor: isIn + ? theme.colors.hoverBackground + : theme.colors.pageBackground, + }) +); export const StyledIconWrapper = styled('div')(({ theme }) => { return { color: theme.colors.iconColor, @@ -26,10 +44,12 @@ export const StyledIconWrapper = styled('div')(({ theme }) => { justifyContent: 'center', alignItems: 'center', cursor: 'pointer', - backgroundColor: 'transparent', + backgroundColor: theme.colors.pageBackground, borderRadius: '50%', width: '32px', height: '32px', + transition: 'background-color 0.3s', + position: 'relative', ':hover': { color: theme.colors.primaryColor, backgroundColor: theme.colors.hoverBackground, diff --git a/packages/app/src/components/modal/index.tsx b/packages/app/src/components/modal/index.tsx deleted file mode 100644 index b734727f30..0000000000 --- a/packages/app/src/components/modal/index.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import ModalUnstyled from '@mui/base/ModalUnstyled'; -import { styled } from '@/styles'; -import Fade from '@mui/material/Fade'; - -import { ClickAwayListener } from '@mui/material'; - -const StyledModal = styled(ModalUnstyled)` - position: fixed; - z-index: 1300; - right: 0; - bottom: 0; - top: 0; - left: 0; - display: flex; - align-items: center; - justify-content: center; -`; - -type TransitionsModalProps = { - open: boolean; - onClose: () => void; - children: JSX.Element; -}; - -export const Modal = (props: TransitionsModalProps) => { - return ( - - - - {props.children} - - - - ); -}; diff --git a/packages/app/src/components/popover/index.tsx b/packages/app/src/components/popover/index.tsx index 9f47d1a956..0d0f790984 100644 --- a/packages/app/src/components/popover/index.tsx +++ b/packages/app/src/components/popover/index.tsx @@ -25,7 +25,7 @@ const StyledPopover = styled('div')(({ theme }) => { return { width: '248px', background: theme.colors.popoverBackground, - boxShadow: theme.colors.boxShadow, + boxShadow: theme.shadow.popover, color: theme.colors.popoverColor, borderRadius: '10px 0px 10px 10px', padding: '8px 4px', diff --git a/packages/app/src/components/shortcuts-modal/config.ts b/packages/app/src/components/shortcuts-modal/config.ts new file mode 100644 index 0000000000..707ff48a20 --- /dev/null +++ b/packages/app/src/components/shortcuts-modal/config.ts @@ -0,0 +1,66 @@ +export const macKeyboardShortcuts = { + Undo: 'cmd + Z', + Redo: 'cmd + shift + Z', + Bold: 'cmd + B', + Italic: 'cmd + I', + Underline: 'cmd + U', + Strikethrough: 'cmd + Shit + S', + 'Inline code': ' cmd + E', + Link: 'cmd + K', + 'Body text': 'cmd + Option + 0', + 'Heading 1': 'cmd + Option + 1', + 'Heading 2': 'cmd + Option + 2', + 'Heading 3': 'cmd + Option + 3', + 'Heading 4': 'cmd + Option + 4', + 'Heading 5': 'cmd + Option + 5', + 'Heading 6': 'cmd + Option + 6', + 'Increase indent': 'Tab', + 'Reduce indent': 'Shift + Tab', +}; + +export const macMarkdownShortcuts = { + Bold: '**Text**', + Italic: '*Text*', + Underline: '~Text~', + Strikethrough: '~~Text~~', + 'Inline code': '`Code`', + 'Heading 1': '# + Space', + 'Heading 2': '## + Space', + 'Heading 3': '### + Space', + 'Heading 4': '#### + Space', + 'Heading 5': '##### + Space', + 'Heading 6': '###### + Space', +}; + +export const windowsKeyboardShortcuts = { + Undo: 'Ctrl + Z', + Redo: 'Ctrl + Y', + Bold: 'Ctrl + B', + Italic: 'Ctrl + I', + Underline: 'Ctrl + U', + Strikethrough: 'Ctrl + Shit + S', + 'Inline code': ' Ctrl + E', + Link: 'Ctrl + K', + 'Body text': 'Ctrl + Shift + 0', + 'Heading 1': 'Ctrl + Shift + 1', + 'Heading 2': 'Ctrl + Shift + 2', + 'Heading 3': 'Ctrl + Shift + 3', + 'Heading 4': 'Ctrl + Shift + 4', + 'Heading 5': 'Ctrl + Shift + 5', + 'Heading 6': 'Ctrl + Shift + 6', + 'Increase indent': 'Tab', + 'Reduce indent': 'Shift + Tab', +}; +export const winMarkdownShortcuts = { + Bold: '**Text** + Space', + Italic: '*Text* + Space', + Underline: '~Text~ + Space', + Strikethrough: '~~Text~~ + Space', + 'Inline code': '`Code` + Space', + 'Heading 1': '# + Space', + 'Heading 2': '## + Space', + 'Heading 3': '### + Space', + 'Heading 4': '#### + Space', + 'Heading 5': '##### + Space', + 'Heading 6': '###### + Space', +}; diff --git a/packages/app/src/components/shortcuts-modal/icons.tsx b/packages/app/src/components/shortcuts-modal/icons.tsx index a920d445ee..13eb2d3cea 100644 --- a/packages/app/src/components/shortcuts-modal/icons.tsx +++ b/packages/app/src/components/shortcuts-modal/icons.tsx @@ -11,3 +11,17 @@ export const CloseIcon = () => { ); }; + +export const KeyboardIcon = () => { + return ( + + + + ); +}; diff --git a/packages/app/src/components/shortcuts-modal/index.tsx b/packages/app/src/components/shortcuts-modal/index.tsx index dd6007fa12..2d079525f7 100644 --- a/packages/app/src/components/shortcuts-modal/index.tsx +++ b/packages/app/src/components/shortcuts-modal/index.tsx @@ -1,19 +1,78 @@ -import { styled } from '@/styles'; -import Fade from '@mui/material/Fade'; - - -const StyledModal = styled('div')(({ theme }) => { - return { - color: theme.colors.textColor, - }; -}); - -type TransitionsModalProps = { +import { createPortal } from 'react-dom'; +import { KeyboardIcon } from './icons'; +import { + StyledListItem, + StyledModalHeader, + StyledShortcutsModal, + StyledSubTitle, + StyledTitle, + CloseButton, +} from './style'; +import { + macKeyboardShortcuts, + macMarkdownShortcuts, + windowsKeyboardShortcuts, + winMarkdownShortcuts, +} from '@/components/shortcuts-modal/config'; +import CloseIcon from '@mui/icons-material/Close'; +import Slide from '@mui/material/Slide'; +type ModalProps = { open: boolean; onClose: () => void; - children: JSX.Element; }; -export const ShortcutsModal = (props: TransitionsModalProps) => { - return
111
; +const isMac = () => { + return /macintosh|mac os x/i.test(navigator.userAgent); }; + +export const ShortcutsModal = ({ open, onClose }: ModalProps) => { + const markdownShortcuts = isMac() + ? macMarkdownShortcuts + : winMarkdownShortcuts; + const keyboardShortcuts = isMac() + ? macKeyboardShortcuts + : windowsKeyboardShortcuts; + return createPortal( + + + <> + + + + Shortcuts + + + { + onClose(); + }} + > + + + + Keyboard shortcuts + {Object.entries(keyboardShortcuts).map(([title, shortcuts]) => { + return ( + + {title} + {shortcuts} + + ); + })} + Markdown shortcuts + {Object.entries(markdownShortcuts).map(([title, shortcuts]) => { + return ( + + {title} + {shortcuts} + + ); + })} + + + , + document.body + ); +}; + +export default ShortcutsModal; diff --git a/packages/app/src/components/shortcuts-modal/style.ts b/packages/app/src/components/shortcuts-modal/style.ts index e69de29bb2..e1924b513f 100644 --- a/packages/app/src/components/shortcuts-modal/style.ts +++ b/packages/app/src/components/shortcuts-modal/style.ts @@ -0,0 +1,65 @@ +import { styled } from '@/styles'; + +export const StyledShortcutsModal = styled.div(({ theme }) => ({ + width: '268px', + height: '66vh', + backgroundColor: theme.colors.popoverBackground, + boxShadow: theme.shadow.popover, + color: theme.colors.popoverColor, + padding: '8px 16px', + overflow: 'auto', + boxRadius: '10px', + position: 'fixed', + right: '12px', + top: '0', + bottom: '0', + margin: 'auto', + zIndex: theme.zIndex.modal, +})); +export const StyledTitle = styled.div(({ theme }) => ({ + color: theme.colors.textColor, + fontWeight: '600', + fontSize: theme.font.sm, + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + svg: { + width: '20px', + marginRight: '14px', + color: theme.colors.primaryColor, + }, +})); +export const StyledSubTitle = styled.div(({ theme }) => ({ + color: theme.colors.textColor, + fontWeight: '500', + fontSize: '12px', + height: '36px', + lineHeight: '36px', +})); +export const StyledModalHeader = styled.div(({ theme }) => ({ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + height: '36px', +})); + +export const StyledListItem = styled.div(({ theme }) => ({ + height: '32px', + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + fontSize: theme.font.xs, +})); + +export const CloseButton = styled('div')(({ theme }) => { + return { + width: '24px', + height: '24px', + borderRadius: '5px', + color: theme.colors.iconColor, + cursor: 'pointer', + ':hover': { + background: theme.colors.hoverBackground, + }, + }; +}); diff --git a/packages/app/src/styles/theme.ts b/packages/app/src/styles/theme.ts index b3d393ea4c..fb011861c3 100644 --- a/packages/app/src/styles/theme.ts +++ b/packages/app/src/styles/theme.ts @@ -23,9 +23,6 @@ export const lightTheme: AffineTheme = { quoteColor: '#4C6275', placeHolderColor: '#C7C7C7', selectedColor: 'rgba(104, 128, 255, 0.1)', - - boxShadow: - ' 0px 1px 10px -6px rgba(24, 39, 75, 0.08), 0px 3px 16px -6px rgba(24, 39, 75, 0.04);', }, font: { xs: '12px', @@ -38,6 +35,12 @@ export const lightTheme: AffineTheme = { modal: 1000, popover: 100, }, + shadow: { + popover: + '4px 4px 7px rgba(58, 76, 92, 0.04), -4px -4px 13px rgba(58, 76, 92, 0.02), 6px 6px 36px rgba(58, 76, 92, 0.06);', + modal: + '4px 4px 7px rgba(58, 76, 92, 0.04), -4px -4px 13px rgba(58, 76, 92, 0.02), 6px 6px 36px rgba(58, 76, 92, 0.06);', + }, }; export const darkTheme: AffineTheme = { @@ -60,8 +63,11 @@ export const darkTheme: AffineTheme = { quoteColor: '#A9B1C6', placeHolderColor: '#C7C7C7', selectedColor: 'rgba(240, 242, 255, 0.8)', - - boxShadow: + }, + shadow: { + popover: + '0px 1px 10px -6px rgba(24, 39, 75, 0.08), 0px 3px 16px -6px rgba(24, 39, 75, 0.04)', + modal: '0px 1px 10px -6px rgba(24, 39, 75, 0.08), 0px 3px 16px -6px rgba(24, 39, 75, 0.04)', }, }; @@ -90,7 +96,8 @@ export const globalThemeVariables: ( '--affine-selected-color': theme.colors.selectedColor, '--affine-placeholder-color': theme.colors.placeHolderColor, - '--affine-box-shadow': theme.colors.boxShadow, + '--affine-modal-shadow': theme.shadow.modal, + '--affine-popover-shadow': theme.shadow.popover, '--affine-font-xs': theme.font.xs, // tiny '--affine-font-sm': theme.font.sm, // small diff --git a/packages/app/src/styles/types.ts b/packages/app/src/styles/types.ts index d4df343e95..da54956d91 100644 --- a/packages/app/src/styles/types.ts +++ b/packages/app/src/styles/types.ts @@ -31,8 +31,6 @@ export interface AffineTheme { quoteColor: string; placeHolderColor: string; selectedColor: string; - - boxShadow: string; }; font: { xs: string; // tiny @@ -46,6 +44,10 @@ export interface AffineTheme { modal: number; popover: number; }; + shadow: { + modal: string; + popover: string; + }; } export interface AffineThemeCSSVariables { @@ -67,7 +69,8 @@ export interface AffineThemeCSSVariables { '--affine-placeholder-color': AffineTheme['colors']['placeHolderColor']; '--affine-selected-color': AffineTheme['colors']['selectedColor']; - '--affine-box-shadow': AffineTheme['colors']['boxShadow']; + '--affine-modal-shadow': AffineTheme['shadow']['popover']; + '--affine-popover-shadow': AffineTheme['shadow']['modal']; '--affine-font-xs': AffineTheme['font']['xs']; // tiny '--affine-font-sm': AffineTheme['font']['sm']; // small