diff --git a/packages/app/package.json b/packages/app/package.json index 1c2e3dd608..cf8e1db0f6 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -17,9 +17,10 @@ "@emotion/react": "^11.10.4", "@emotion/server": "^11.10.0", "@emotion/styled": "^11.10.4", + "@fontsource/space-mono": "^4.5.10", "@mui/base": "^5.0.0-alpha.87", - "@mui/material": "^5.8.6", "@mui/icons-material": "^5.10.9", + "@mui/material": "^5.8.6", "@toeverything/pathfinder-logger": "workspace:@pathfinder/logger@*", "css-spring": "^4.1.0", "lit": "^2.3.1", diff --git a/packages/app/public/globals.css b/packages/app/public/globals.css index 5a33ec99f6..c3f50fd465 100644 --- a/packages/app/public/globals.css +++ b/packages/app/public/globals.css @@ -125,7 +125,6 @@ h3, h4, h5, h6, -em, strong, b { font-weight: bold; diff --git a/packages/app/src/components/Header/index.tsx b/packages/app/src/components/Header/index.tsx index 405cd9006a..fb4df965db 100644 --- a/packages/app/src/components/Header/index.tsx +++ b/packages/app/src/components/Header/index.tsx @@ -66,29 +66,31 @@ export const Header = () => { return ( <> - - { - contactModalHandler(true); - }} - /> - - { - setIsHover(true); - }} - onMouseLeave={() => { - setIsHover(false); + { + contactModalHandler(true); }} > - + + {title ? ( + { + setIsHover(true); }} - /> - {title} - + onMouseLeave={() => { + setIsHover(false); + }} + > + + {title} + + ) : null} diff --git a/packages/app/src/components/Header/styles.ts b/packages/app/src/components/Header/styles.ts index 9c529803e8..b69e0d4dae 100644 --- a/packages/app/src/components/Header/styles.ts +++ b/packages/app/src/components/Header/styles.ts @@ -36,7 +36,11 @@ export const StyledTitleWrapper = styled('div')({ export const StyledLogo = styled('div')(({ theme }) => ({ color: theme.colors.primaryColor, + width: '60px', + height: '60px', cursor: 'pointer', + marginLeft: '-22px', + ...displayFlex('center', 'center'), })); export const StyledHeaderRightSide = styled('div')({ diff --git a/packages/app/src/components/contact-modal/style.ts b/packages/app/src/components/contact-modal/style.ts index 32468d9734..e1bb82d2fe 100644 --- a/packages/app/src/components/contact-modal/style.ts +++ b/packages/app/src/components/contact-modal/style.ts @@ -14,7 +14,7 @@ export const StyledModalContainer = styled('div')(({ theme }) => { export const StyledModalWrapper = styled('div')(({ theme }) => { return { width: '860px', - height: '626px', + height: '540px', backgroundColor: theme.colors.popoverBackground, backgroundImage: `url(${bg.src})`, borderRadius: '20px', @@ -112,7 +112,6 @@ export const StyledSmallLink = styled('a')(({ theme }) => { }); export const StyledSubTitle = styled('div')(({ theme }) => { return { - width: '189px', fontSize: '18px', fontWeight: '600', color: theme.colors.textColor, @@ -121,10 +120,13 @@ export const StyledSubTitle = styled('div')(({ theme }) => { }); export const StyledLeftContainer = styled('div')({ + width: '320px', flexDirection: 'column', ...displayFlex('space-between', 'center'), }); export const StyledRightContainer = styled('div')({ + width: '214px', + flexShrink: '0', flexDirection: 'column', ...displayFlex('center', 'flex-end'), }); @@ -132,10 +134,11 @@ export const StyledRightContainer = styled('div')({ export const StyledContent = styled('div')({ height: '276px', width: '100%', - padding: '0 145px', + padding: '0 140px', ...displayFlex('space-between', 'center'), color: '#3A4C5C', - marginTop: '100px', + marginTop: '58px', + letterSpacing: '0.06em', }); export const StyledBackdrop = styled('div')(({ theme }) => { @@ -148,8 +151,8 @@ export const StyledLogo = styled('img')({ export const StyledModalHeader = styled('div')(({ theme }) => { return { - height: '30px', - marginTop: '54px', + height: '20px', + marginTop: '36px', padding: '0 48px', ...displayFlex('space-between', 'center'), }; @@ -197,10 +200,16 @@ export const StyledModalFooter = styled('div')(({ theme }) => { textAlign: 'center', color: theme.colors.textColor, - marginTop: '75px', + marginTop: '40px', 'p:first-of-type': { color: theme.colors.primaryColor, - marginBottom: '10px', + letterSpacing: '0.06em', + marginBottom: '25px', + a: { + ':visited': { + color: theme.colors.linkColor, + }, + }, }, }; }); diff --git a/packages/app/src/components/editor-mode-switch/style.ts b/packages/app/src/components/editor-mode-switch/style.ts index 72b0ab3340..ac7050e94e 100644 --- a/packages/app/src/components/editor-mode-switch/style.ts +++ b/packages/app/src/components/editor-mode-switch/style.ts @@ -30,8 +30,13 @@ export const StyledAnimateRadioContainer = styled('div')<{ shrink: boolean }>( background: theme.colors.hoverBackground, position: 'relative', display: 'flex', - transition: `background ${ANIMATE_DURATION}ms`, + transition: `background ${ANIMATE_DURATION}ms, border ${ANIMATE_DURATION}ms`, + border: '1px solid transparent', + ...shrinkStyle, + ':hover': { + border: `1px solid ${theme.colors.primaryColor}`, + }, }; } ); diff --git a/packages/app/src/components/loading/index.tsx b/packages/app/src/components/loading/index.tsx new file mode 100644 index 0000000000..a04cffefb5 --- /dev/null +++ b/packages/app/src/components/loading/index.tsx @@ -0,0 +1,14 @@ +import { StyledLoading, StyledLoadingItem } from './styled'; + +export const Loading = () => { + return ( + + + + + + + ); +}; + +export default Loading; diff --git a/packages/app/src/components/loading/styled.ts b/packages/app/src/components/loading/styled.ts new file mode 100644 index 0000000000..43c7254d22 --- /dev/null +++ b/packages/app/src/components/loading/styled.ts @@ -0,0 +1,93 @@ +import { styled } from '@/styles'; + +const loadingItemSize = '40px'; +export const StyledLoading = styled.div` + position: relative; + left: 50%; + transform: rotateX(55deg) rotateZ(-45deg) + translate(calc(${loadingItemSize} * -2), 0); + margin-bottom: calc(3 * ${loadingItemSize}); + + @keyframes slide { + 0% { + transform: translate(var(--sx), var(--sy)); + } + 65% { + transform: translate(var(--ex), var(--sy)); + } + 95%, + 100% { + transform: translate(var(--ex), var(--ey)); + } + } + @keyframes load { + 20% { + content: '.'; + } + 40% { + content: '..'; + } + 80%, + 100% { + content: '...'; + } + } +`; + +export const StyledLoadingItem = styled.div` + position: absolute; + width: ${loadingItemSize}; + height: ${loadingItemSize}; + background: #9dacf9; + animation: slide 0.9s cubic-bezier(0.65, 0.53, 0.59, 0.93) infinite; + + &::before, + &::after { + content: ''; + position: absolute; + width: 100%; + height: 100%; + } + + &::before { + background: #5260b9; + transform: skew(0deg, -45deg); + right: 100%; + top: 50%; + } + + &::after { + background: #6880ff; + transform: skew(-45deg, 0deg); + top: 100%; + right: 50%; + } + + &:nth-child(1) { + --sx: 50%; + --sy: -50%; + --ex: 150%; + --ey: 50%; + } + + &:nth-child(2) { + --sx: -50%; + --sy: -50%; + --ex: 50%; + --ey: -50%; + } + + &:nth-child(3) { + --sx: 150%; + --sy: 50%; + --ex: 50%; + --ey: 50%; + } + + &:nth-child(4) { + --sx: 50%; + --sy: 50%; + --ex: -50%; + --ey: -50%; + } +`; diff --git a/packages/app/src/components/shortcuts-modal/config.ts b/packages/app/src/components/shortcuts-modal/config.ts index 7a868e3d75..948a8a54f3 100644 --- a/packages/app/src/components/shortcuts-modal/config.ts +++ b/packages/app/src/components/shortcuts-modal/config.ts @@ -19,11 +19,11 @@ export const macKeyboardShortcuts = { }; export const macMarkdownShortcuts = { - Bold: '**Text**', - Italic: '*Text*', - Underline: '~Text~', - Strikethrough: '~~Text~~', - 'Inline code': '`Code`', + 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', @@ -38,7 +38,7 @@ export const windowsKeyboardShortcuts = { Bold: 'Ctrl + B', Italic: 'Ctrl + I', Underline: 'Ctrl + U', - Strikethrough: 'Ctrl + ⇧ + S', + Strikethrough: 'Ctrl + Shift + S', 'Inline code': ' Ctrl + E', Link: 'Ctrl + K', 'Body text': 'Ctrl + Shift + 0', diff --git a/packages/app/src/pages/_app.tsx b/packages/app/src/pages/_app.tsx index 747669cad0..7b009515ce 100644 --- a/packages/app/src/pages/_app.tsx +++ b/packages/app/src/pages/_app.tsx @@ -7,6 +7,8 @@ import { EditorProvider } from '@/components/editor-provider'; import { ModalProvider } from '@/components/global-modal-provider'; import { Logger } from '@toeverything/pathfinder-logger'; +import '@fontsource/space-mono'; + const ThemeProvider = dynamic(() => import('@/styles/themeProvider'), { ssr: false, }); diff --git a/packages/app/src/pages/_document.tsx b/packages/app/src/pages/_document.tsx index d84f7f8604..7bc23a3892 100644 --- a/packages/app/src/pages/_document.tsx +++ b/packages/app/src/pages/_document.tsx @@ -42,12 +42,7 @@ export default class AppDocument extends Document { render() { return ( - - - +
diff --git a/packages/app/src/pages/affine.tsx b/packages/app/src/pages/affine.tsx index 5596e2778e..b822906d2a 100644 --- a/packages/app/src/pages/affine.tsx +++ b/packages/app/src/pages/affine.tsx @@ -1,5 +1,6 @@ import { displayFlex, styled } from '@/styles'; import { ThemeModeSwitch } from '@/components/theme-mode-switch'; +import { Loading } from '@/components/loading'; export const StyledHeader = styled('div')({ height: '60px', @@ -12,9 +13,12 @@ export const StyledHeader = styled('div')({ const Affine = () => { return ( - - - + <> + + + + + ); }; diff --git a/packages/app/src/pages/index.tsx b/packages/app/src/pages/index.tsx index 628b9f0334..741282b51a 100644 --- a/packages/app/src/pages/index.tsx +++ b/packages/app/src/pages/index.tsx @@ -3,6 +3,7 @@ import dynamic from 'next/dynamic'; import { styled } from '@/styles'; import { Header } from '@/components/Header'; import { FAQ } from '@/components/faq'; +import Loading from '@/components/loading'; import EdgelessToolbar from '@/components/edgeless-toolbar'; import '@/components/simple-counter'; @@ -21,8 +22,30 @@ const StyledPage = styled('div')(({ theme }) => { }; }); +const StyledLoadingContainer = styled('div')(({ theme }) => { + return { + height: '100vh', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + color: theme.colors.primaryColor, + h1: { + fontSize: '2em', + marginTop: '150px', + fontWeight: '600', + }, + }; +}); + const DynamicEditor = dynamic(() => import('../components/editor'), { - loading: () =>
Loading...
, + loading: () => ( + +
+ +

Loading...

+
+
+ ), ssr: false, }); diff --git a/packages/app/src/styles/theme.ts b/packages/app/src/styles/theme.ts index acf8685e34..c24b835891 100644 --- a/packages/app/src/styles/theme.ts +++ b/packages/app/src/styles/theme.ts @@ -23,13 +23,15 @@ export const lightTheme: AffineTheme = { quoteColor: '#4C6275', placeHolderColor: '#C7C7C7', selectedColor: 'rgba(104, 128, 255, 0.1)', + borderColor: '#D0D7E3', }, font: { xs: '12px', sm: '16px', base: '18px', family: `Avenir Next, ${basicFontFamily}`, - family2: `Roboto, ${basicFontFamily}`, + family2: `Space Mono, ${basicFontFamily}`, + lineHeightBase: '26px', }, zIndex: { modal: 1000, @@ -41,6 +43,9 @@ export const lightTheme: AffineTheme = { 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);', }, + space: { + paragraph: '8px', + }, }; export const darkTheme: AffineTheme = { @@ -63,6 +68,7 @@ export const darkTheme: AffineTheme = { quoteColor: '#A9B1C6', placeHolderColor: '#C7C7C7', selectedColor: 'rgba(240, 242, 255, 0.8)', + borderColor: '#4D4C53', }, shadow: { popover: @@ -95,6 +101,7 @@ export const globalThemeVariables: ( '--affine-quote-color': theme.colors.quoteColor, '--affine-selected-color': theme.colors.selectedColor, '--affine-placeholder-color': theme.colors.placeHolderColor, + '--affine-border-color': theme.colors.borderColor, '--affine-modal-shadow': theme.shadow.modal, '--affine-popover-shadow': theme.shadow.popover, @@ -102,11 +109,14 @@ export const globalThemeVariables: ( '--affine-font-xs': theme.font.xs, // tiny '--affine-font-sm': theme.font.sm, // small '--affine-font-base': theme.font.base, + '--affine-line-height-base': theme.font.lineHeightBase, '--affine-z-index-modal': theme.zIndex.modal, '--affine-z-index-popover': theme.zIndex.popover, '--affine-font-family': theme.font.family, '--affine-font-family2': theme.font.family2, + + '--affine-paragraph-space': theme.space.paragraph, }; }; diff --git a/packages/app/src/styles/themeProvider.tsx b/packages/app/src/styles/themeProvider.tsx index 307d71eba8..097e0d5c72 100644 --- a/packages/app/src/styles/themeProvider.tsx +++ b/packages/app/src/styles/themeProvider.tsx @@ -34,33 +34,49 @@ export const ThemeProvider = ({ localStorageThemeHelper.set(themeMode); }; + // ===================== A temporary solution, just use system theme and not remember the user selected ==================== useEffect(() => { - setMode(localStorageThemeHelper.get() || 'auto'); + const systemThemeHelper = new SystemThemeHelper(); + const systemTheme = systemThemeHelper.get(); + setMode(systemTheme); + + systemThemeHelper.onChange(() => { + setMode(systemThemeHelper.get()); + }); }, []); useEffect(() => { - const systemThemeHelper = new SystemThemeHelper(); - const selectedThemeMode = localStorageThemeHelper.get(); + setTheme(mode === 'auto' ? theme : mode); + }, [mode, setTheme, theme]); + // ===================== ==================== - const themeMode = selectedThemeMode || mode; - if (themeMode === 'auto') { - setTheme(systemThemeHelper.get()); - } else { - setTheme(themeMode); - } - - // When system theme changed, change the theme mode - systemThemeHelper.onChange(() => { - // TODO: There may be should be provided a way to let user choose whether to - if (mode === 'auto') { - setTheme(systemThemeHelper.get()); - } - }); - - return () => { - systemThemeHelper.dispose(); - }; - }, [mode]); + // useEffect(() => { + // setMode(localStorageThemeHelper.get() || 'auto'); + // }, []); + // + // useEffect(() => { + // const systemThemeHelper = new SystemThemeHelper(); + // const selectedThemeMode = localStorageThemeHelper.get(); + // + // const themeMode = selectedThemeMode || mode; + // if (themeMode === 'auto') { + // setTheme(systemThemeHelper.get()); + // } else { + // setTheme(themeMode); + // } + // + // // When system theme changed, change the theme mode + // systemThemeHelper.onChange(() => { + // // TODO: There may be should be provided a way to let user choose whether to + // if (mode === 'auto') { + // setTheme(systemThemeHelper.get()); + // } + // }); + // + // return () => { + // systemThemeHelper.dispose(); + // }; + // }, [mode]); return ( diff --git a/packages/app/src/styles/types.ts b/packages/app/src/styles/types.ts index 3e70ffc340..b95dd38fcd 100644 --- a/packages/app/src/styles/types.ts +++ b/packages/app/src/styles/types.ts @@ -31,6 +31,7 @@ export interface AffineTheme { quoteColor: string; placeHolderColor: string; selectedColor: string; + borderColor: string; }; font: { xs: string; // tiny @@ -39,6 +40,8 @@ export interface AffineTheme { family: string; family2: string; + + lineHeightBase: string | number; }; zIndex: { modal: number; @@ -48,6 +51,9 @@ export interface AffineTheme { modal: string; popover: string; }; + space: { + paragraph: string; + }; } export interface AffineThemeCSSVariables { @@ -68,6 +74,7 @@ export interface AffineThemeCSSVariables { '--affine-quote-color': AffineTheme['colors']['quoteColor']; '--affine-placeholder-color': AffineTheme['colors']['placeHolderColor']; '--affine-selected-color': AffineTheme['colors']['selectedColor']; + '--affine-border-color': AffineTheme['colors']['borderColor']; '--affine-modal-shadow': AffineTheme['shadow']['popover']; '--affine-popover-shadow': AffineTheme['shadow']['modal']; @@ -75,12 +82,15 @@ export interface AffineThemeCSSVariables { '--affine-font-xs': AffineTheme['font']['xs']; // tiny '--affine-font-sm': AffineTheme['font']['sm']; // small '--affine-font-base': AffineTheme['font']['base']; + '--affine-line-height-base': AffineTheme['font']['lineHeightBase']; '--affine-z-index-modal': AffineTheme['zIndex']['modal']; '--affine-z-index-popover': AffineTheme['zIndex']['popover']; '--affine-font-family': AffineTheme['font']['family']; '--affine-font-family2': AffineTheme['font']['family2']; + + '--affine-paragraph-space': AffineTheme['space']['paragraph']; } declare module '@emotion/react' { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 88b0d3103d..5cb9ba8b13 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,6 +25,7 @@ importers: '@emotion/react': ^11.10.4 '@emotion/server': ^11.10.0 '@emotion/styled': ^11.10.4 + '@fontsource/space-mono': ^4.5.10 '@mui/base': ^5.0.0-alpha.87 '@mui/icons-material': ^5.10.9 '@mui/material': ^5.8.6 @@ -54,6 +55,7 @@ importers: '@emotion/react': 11.10.4_w5j4k42lgipnm43s3brx6h3c34 '@emotion/server': 11.10.0_@emotion+css@11.10.0 '@emotion/styled': 11.10.4_yiaqs725o7pcd7rteavrnhgj4y + '@fontsource/space-mono': 4.5.10 '@mui/base': 5.0.0-alpha.101_7ey2zzynotv32rpkwno45fsx4e '@mui/icons-material': 5.10.9_5fncb4nagb4cvvcnwamw2rozfa '@mui/material': 5.10.9_af5ln35zuaotaffazii6n6bke4 @@ -377,6 +379,10 @@ packages: - supports-color dev: true + /@fontsource/space-mono/4.5.10: + resolution: {integrity: sha512-OTrWNdcPp01bZjEbSu52vMu9PaReUFylHAMI4lctKVbYUnm+e7a4eG6YcnRvDrJEMYHBDtEWLAsqGVldV5r1EQ==} + dev: false + /@humanwhocodes/config-array/0.10.4: resolution: {integrity: sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==} engines: {node: '>=10.10.0'}