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