diff --git a/packages/app/src/components/Header/styles.ts b/packages/app/src/components/Header/styles.ts index 12f16e9753..9c529803e8 100644 --- a/packages/app/src/components/Header/styles.ts +++ b/packages/app/src/components/Header/styles.ts @@ -1,11 +1,9 @@ -import { styled } from '@/styles'; +import { displayFlex, styled } from '@/styles'; export const StyledHeader = styled('div')({ height: '60px', width: '100vw', - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', + ...displayFlex('space-between', 'center'), background: 'var(--affine-page-background)', transition: 'background-color 0.5s', position: 'fixed', @@ -24,9 +22,7 @@ export const StyledTitle = styled('div')({ top: 0, margin: 'auto', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', + ...displayFlex('center', 'center'), fontSize: '20px', }); @@ -74,9 +70,7 @@ export const IconButton = styled('div')(({ theme }) => { return { width: '32px', height: '32px', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', + ...displayFlex('center', 'center'), color: theme.colors.iconColor, borderRadius: '5px', ':hover': { diff --git a/packages/app/src/components/contact-modal/bg.png b/packages/app/src/components/contact-modal/bg.png index 4e2c39d356..737c8c17c0 100644 Binary files a/packages/app/src/components/contact-modal/bg.png and b/packages/app/src/components/contact-modal/bg.png differ diff --git a/packages/app/src/components/contact-modal/icons.tsx b/packages/app/src/components/contact-modal/icons.tsx index d267dbe9c3..aba676278d 100644 --- a/packages/app/src/components/contact-modal/icons.tsx +++ b/packages/app/src/components/contact-modal/icons.tsx @@ -1,55 +1,139 @@ -// export const CloseIcon = () => { -// return ( -// -// -// -// ); -// }; - export const LogoIcon = () => { return ( + + ); +}; +export const DocIcon = () => { + return ( + + ); }; -export const DiscordIcon = (props: any) => { +export const TwitterIcon = () => { return ( - + + + ); +}; + +export const GithubIcon = () => { + return ( + + - - + + ); }; +export const DiscordIcon = (props: any) => { + return ( + + + + + + + + + + + ); +}; + +export const TelegramIcon = () => { + return ( + + + + ); +}; + +export const RedditIcon = () => { + return ( + + + + ); +}; + +export const LinkIcon = () => { + return ( + + + + ); +}; diff --git a/packages/app/src/components/contact-modal/index.tsx b/packages/app/src/components/contact-modal/index.tsx index 78b9adbdff..0b45ec18ba 100644 --- a/packages/app/src/components/contact-modal/index.tsx +++ b/packages/app/src/components/contact-modal/index.tsx @@ -1,12 +1,16 @@ import { createPortal } from 'react-dom'; import Fade from '@mui/material/Fade'; -import GitHubIcon from '@mui/icons-material/GitHub'; -import RedditIcon from '@mui/icons-material/Reddit'; -import TelegramIcon from '@mui/icons-material/Telegram'; -import TwitterIcon from '@mui/icons-material/Twitter'; import CloseIcon from '@mui/icons-material/Close'; - -import { LogoIcon, DiscordIcon } from './icons'; +import { + LogoIcon, + DocIcon, + TwitterIcon, + GithubIcon, + DiscordIcon, + TelegramIcon, + RedditIcon, + LinkIcon, +} from './icons'; import logo from './affine-text-logo.png'; import { StyledModalContainer, @@ -27,7 +31,7 @@ import { const linkList = [ { - icon: , + icon: , title: 'Github', link: 'https://github.com/toeverything/AFFiNE', }, @@ -55,12 +59,14 @@ const linkList = [ const rightLinkList = [ { icon: , - title: 'Official Website AFFiNE.pro', + title: 'Official Website ', + subTitle: 'AFFiNE.pro', link: 'https://affine.pro', }, { - icon: , - title: 'Check Our Docs Open Source', + icon: , + title: 'Check Our Docs', + subTitle: 'Open Source', link: 'https://github.com/toeverything/AFFiNE', }, ]; @@ -80,24 +86,27 @@ export const ContactModal = ({ open, onClose }: TransitionsModalProps) => { Alpha - live demo { onClose(); }} > - + - {rightLinkList.map(({ icon, title, link }) => { + {rightLinkList.map(({ icon, title, subTitle, link }) => { return ( {icon} - {title} +

{title}

+

+ {subTitle} + +

); })} @@ -120,9 +129,7 @@ export const ContactModal = ({ open, onClose }: TransitionsModalProps) => {

- - What is the different from the affine 1.0? - + How is AFFiNE Alpha different?

Copyright © 2022 Toeverything

diff --git a/packages/app/src/components/contact-modal/style.ts b/packages/app/src/components/contact-modal/style.ts index b89be96e1e..32468d9734 100644 --- a/packages/app/src/components/contact-modal/style.ts +++ b/packages/app/src/components/contact-modal/style.ts @@ -1,4 +1,4 @@ -import { styled } from '@/styles'; +import { absoluteCenter, displayFlex, styled } from '@/styles'; import bg from './bg.png'; export const StyledModalContainer = styled('div')(({ theme }) => { return { @@ -13,11 +13,10 @@ export const StyledModalContainer = styled('div')(({ theme }) => { export const StyledModalWrapper = styled('div')(({ theme }) => { return { - width: '1000px', + width: '860px', height: '626px', backgroundColor: theme.colors.popoverBackground, backgroundImage: `url(${bg.src})`, - padding: '0 48px', borderRadius: '20px', position: 'absolute', left: 0, @@ -30,24 +29,24 @@ export const StyledModalWrapper = styled('div')(({ theme }) => { export const StyledBigLink = styled('a')(({ theme }) => { return { - width: '335px', - height: '110px', - marginBottom: '52px', - display: 'flex', - alignItems: 'center', + width: '320px', + height: '100px', + marginBottom: '48px', + paddingLeft: '114px', fontSize: '24px', lineHeight: '36px', - padding: '0 24px', fontWeight: '600', color: theme.colors.textColor, borderRadius: '10px', - + flexDirection: 'column', + ...displayFlex('center'), + position: 'relative', + transition: 'background .15s', ':visited': { color: theme.colors.textColor, }, ':hover': { - color: theme.colors.primaryColor, - background: theme.colors.hoverBackground, + background: 'rgba(68, 97, 242, 0.1)', }, ':last-of-type': { marginBottom: 0, @@ -57,10 +56,30 @@ export const StyledBigLink = styled('a')(({ theme }) => { height: '50px', marginRight: '40px', color: theme.colors.primaryColor, + ...absoluteCenter({ vertical: true, position: { left: '32px' } }), }, p: { - width: '197px', - height: '73px', + width: '100%', + height: '30px', + lineHeight: '30px', + ...displayFlex('flex-start', 'center'), + ':not(:last-of-type)': { + marginBottom: '4px', + }, + ':first-of-type': { + fontSize: '22px', + }, + ':last-of-type': { + fontSize: '20px', + color: theme.colors.primaryColor, + }, + svg: { + width: '15px', + height: '15px', + position: 'static', + transform: 'translate(0,0)', + marginLeft: '5px', + }, }, }; }); @@ -75,6 +94,8 @@ export const StyledSmallLink = styled('a')(({ theme }) => { paddingLeft: '24px', borderRadius: '5px', color: theme.colors.textColor, + transition: 'background .15s, color .15s', + ':visited': { color: theme.colors.textColor, }, @@ -100,25 +121,19 @@ export const StyledSubTitle = styled('div')(({ theme }) => { }); export const StyledLeftContainer = styled('div')({ - // height: '100%', - display: 'flex', flexDirection: 'column', - justifyContent: 'space-between', + ...displayFlex('space-between', 'center'), }); export const StyledRightContainer = styled('div')({ - display: 'flex', flexDirection: 'column', - justifyContent: 'center', - alignItems: 'flex-end', + ...displayFlex('center', 'flex-end'), }); export const StyledContent = styled('div')({ height: '276px', width: '100%', - padding: '0 160px', - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', + padding: '0 145px', + ...displayFlex('space-between', 'center'), color: '#3A4C5C', marginTop: '100px', }); @@ -127,7 +142,7 @@ export const StyledBackdrop = styled('div')(({ theme }) => { return { width: '100%', height: '100%', background: 'rgba(58, 76, 92, 0.2)' }; }); export const StyledLogo = styled('img')({ - height: '22px', + height: '18px', width: 'auto', }); @@ -136,45 +151,42 @@ export const StyledModalHeader = styled('div')(({ theme }) => { height: '30px', marginTop: '54px', padding: '0 48px', - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', + ...displayFlex('space-between', 'center'), }; }); export const StyledModalHeaderLeft = styled('div')(({ theme }) => { return { - display: 'flex', - alignItems: 'center', color: theme.colors.primaryColor, - - 'span:first-of-type': { - fontSize: '28px', - lineHeight: 1, - fontWeight: '600', - margin: '0 12px', - }, - 'span:last-of-type': { - height: '26px', + ...displayFlex('flex-end', 'flex-end'), + span: { + height: '20px', border: `1px solid ${theme.colors.primaryColor}`, borderRadius: '10px', - padding: '0 10px', + padding: '0 8px', lineHeight: '26px', - fontSize: '16px', + fontSize: '14px', + marginLeft: '12px', + ...displayFlex('center', 'center'), }, }; }); export const CloseButton = styled('div')(({ theme }) => { return { - width: '24px', - height: '24px', - borderRadius: '5px', + width: '30px', + height: '30px', + borderRadius: '6px', color: theme.colors.iconColor, cursor: 'pointer', + ...displayFlex('center', 'center'), ':hover': { background: theme.colors.hoverBackground, }, + svg: { + width: '20px', + height: '20px', + }, }; }); diff --git a/packages/app/src/components/edgeless-toolbar/icons.tsx b/packages/app/src/components/edgeless-toolbar/icons.tsx new file mode 100644 index 0000000000..aa04207aad --- /dev/null +++ b/packages/app/src/components/edgeless-toolbar/icons.tsx @@ -0,0 +1,151 @@ +export const SelectIcon = () => { + return ( + + + + + + + + + + + ); +}; + +export const TextIcon = () => { + return ( + + + + ); +}; + +export const ShapeIcon = () => { + return ( + + + + ); +}; + +export const PenIcon = () => { + return ( + + + + ); +}; + +export const StickerIcon = () => { + return ( + + + + ); +}; + +export const ConnectorIcon = () => { + return ( + + + + ); +}; + +export const UndoIcon = () => { + return ( + + + + ); +}; + +export const RedoIcon = () => { + return ( + + + + ); +}; diff --git a/packages/app/src/components/edgeless-toolbar/index.tsx b/packages/app/src/components/edgeless-toolbar/index.tsx new file mode 100644 index 0000000000..49762dde84 --- /dev/null +++ b/packages/app/src/components/edgeless-toolbar/index.tsx @@ -0,0 +1,110 @@ +import { + StyledEdgelessToolbar, + StyledToolbarWrapper, + StyledToolbarItem, +} from './style'; +import { + SelectIcon, + TextIcon, + ShapeIcon, + PenIcon, + StickerIcon, + ConnectorIcon, + UndoIcon, + RedoIcon, +} from './icons'; +import { Tooltip } from '@/components/tooltip'; +import Slide from '@mui/material/Slide'; +import { useEditor } from '@/components/editor-provider'; + +const toolbarList1 = [ + { + icon: , + toolTip: 'Select', + onClick: () => {}, + disable: false, + }, + { + icon: , + toolTip: 'Text(coming soon)', + onClick: () => {}, + disable: true, + }, + { + icon: , + toolTip: 'Shape(coming soon)', + onClick: () => {}, + disable: true, + }, + { + icon: , + toolTip: 'Sticker(coming soon)', + onClick: () => {}, + disable: true, + }, + { + icon: , + toolTip: 'Pen(coming soon)', + onClick: () => {}, + disable: true, + }, + + { + icon: , + toolTip: 'Connector(coming soon)', + onClick: () => {}, + disable: true, + }, +]; +const toolbarList2 = [ + { + icon: , + toolTip: 'Undo(coming soon)', + onClick: () => {}, + disable: true, + }, + { + icon: , + toolTip: 'Redo(coming soon)', + onClick: () => {}, + disable: true, + }, +]; +export const EdgelessToolbar = () => { + const { mode } = useEditor(); + return ( + + + + {toolbarList1.map(({ icon, toolTip, onClick, disable }, index) => { + return ( + + + {icon} + + + ); + })} + + + {toolbarList2.map(({ icon, toolTip, onClick, disable }, index) => { + return ( + + + {icon} + + + ); + })} + + + + ); +}; + +export default EdgelessToolbar; diff --git a/packages/app/src/components/edgeless-toolbar/reply.svg b/packages/app/src/components/edgeless-toolbar/reply.svg new file mode 100644 index 0000000000..bfe127a193 --- /dev/null +++ b/packages/app/src/components/edgeless-toolbar/reply.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/app/src/components/edgeless-toolbar/style.ts b/packages/app/src/components/edgeless-toolbar/style.ts new file mode 100644 index 0000000000..e57a370beb --- /dev/null +++ b/packages/app/src/components/edgeless-toolbar/style.ts @@ -0,0 +1,41 @@ +import { styled, displayFlex, fixedCenter } from '@/styles'; + +export const StyledEdgelessToolbar = styled.div(({ theme }) => ({ + height: '320px', + position: 'fixed', + left: '12px', + top: 0, + bottom: 0, + margin: 'auto', + zIndex: theme.zIndex.modal, +})); + +export const StyledToolbarWrapper = styled.div(({ theme }) => ({ + width: '44px', + borderRadius: '10px', + boxShadow: theme.shadow.modal, + padding: '4px', + background: theme.colors.popoverBackground, + transition: 'background .5s', + marginBottom: '12px', +})); + +export const StyledToolbarItem = styled.div<{ disable: boolean }>( + ({ theme, disable }) => ({ + width: '36px', + height: '36px', + ...displayFlex('center', 'center'), + color: disable ? '#C0C0C0' : theme.colors.iconColor, + cursor: 'pointer', + svg: { + width: '36px', + height: '36px', + }, + ':hover': disable + ? {} + : { + color: theme.colors.primaryColor, + background: theme.colors.hoverBackground, + }, + }) +); diff --git a/packages/app/src/components/editor-mode-switch/style.ts b/packages/app/src/components/editor-mode-switch/style.ts index d882a3a76d..72b0ab3340 100644 --- a/packages/app/src/components/editor-mode-switch/style.ts +++ b/packages/app/src/components/editor-mode-switch/style.ts @@ -1,4 +1,4 @@ -import { keyframes, styled } from '@/styles'; +import { displayFlex, keyframes, styled } from '@/styles'; // @ts-ignore import spring, { toString } from 'css-spring'; import type { ItemStatus } from './type'; @@ -128,9 +128,7 @@ export const StyledIcon = styled('div')<{ ? { width: '36px' } : { width: isLeft ? '44px' : '34px' }; return { - display: 'flex', - justifyContent: 'center', - alignItems: 'center', + ...displayFlex('center', 'center'), flexShrink: '0', ...dynamicStyle, }; diff --git a/packages/app/src/components/faq/style.ts b/packages/app/src/components/faq/style.ts index e6959906dc..e39e6280c5 100644 --- a/packages/app/src/components/faq/style.ts +++ b/packages/app/src/components/faq/style.ts @@ -1,4 +1,4 @@ -import { styled } from '@/styles'; +import { displayFlex, styled } from '@/styles'; export const StyledFAQ = styled('div')(({ theme }) => { return { @@ -23,9 +23,7 @@ export const StyledTransformIcon = styled.div<{ in: boolean }>( bottom: '0', top: '0', margin: 'auto', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', + ...displayFlex('center', 'center'), opacity: isIn ? 1 : 0, backgroundColor: isIn ? theme.colors.hoverBackground @@ -39,9 +37,7 @@ export const StyledIconWrapper = styled('div')<{ isEdgelessDark: boolean }>( ? theme.colors.popoverBackground : theme.colors.iconColor, marginBottom: '24px', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', + ...displayFlex('center', 'center'), cursor: 'pointer', backgroundColor: isEdgelessDark ? 'transparent' diff --git a/packages/app/src/components/shortcuts-modal/style.ts b/packages/app/src/components/shortcuts-modal/style.ts index cb12e1733e..e9a34cf679 100644 --- a/packages/app/src/components/shortcuts-modal/style.ts +++ b/packages/app/src/components/shortcuts-modal/style.ts @@ -1,4 +1,4 @@ -import { styled } from '@/styles'; +import { displayFlex, styled } from '@/styles'; export const StyledShortcutsModal = styled.div(({ theme }) => ({ width: '268px', @@ -19,9 +19,7 @@ export const StyledTitle = styled.div(({ theme }) => ({ color: theme.colors.textColor, fontWeight: '600', fontSize: theme.font.sm, - display: 'flex', - justifyContent: 'center', - alignItems: 'center', + ...displayFlex('center', 'center'), svg: { width: '20px', marginRight: '14px', @@ -38,9 +36,7 @@ export const StyledSubTitle = styled.div(({ theme }) => ({ padding: '0 16px', })); export const StyledModalHeader = styled.div(({ theme }) => ({ - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', + ...displayFlex('space-between', 'center'), height: '36px', width: '100%', padding: '8px 16px 0 16px', @@ -54,9 +50,7 @@ export const StyledModalHeader = styled.div(({ theme }) => ({ export const StyledListItem = styled.div(({ theme }) => ({ height: '32px', - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', + ...displayFlex('space-between', 'center'), fontSize: theme.font.xs, padding: '0 16px', })); @@ -68,6 +62,11 @@ export const CloseButton = styled('div')(({ theme }) => { borderRadius: '5px', color: theme.colors.iconColor, cursor: 'pointer', + ...displayFlex('center', 'center'), + svg: { + width: '15px', + height: '15px', + }, ':hover': { background: theme.colors.hoverBackground, }, diff --git a/packages/app/src/components/theme-mode-switch/style.ts b/packages/app/src/components/theme-mode-switch/style.ts index b40f7d3439..7f90930e67 100644 --- a/packages/app/src/components/theme-mode-switch/style.ts +++ b/packages/app/src/components/theme-mode-switch/style.ts @@ -1,4 +1,4 @@ -import { keyframes, styled } from '@/styles'; +import { displayFlex, keyframes, styled } from '@/styles'; import { CSSProperties } from 'react'; // @ts-ignore import spring, { toString } from 'css-spring'; @@ -56,11 +56,9 @@ export const StyledSwitchItem = styled('div')<{ return { width: '32px', height: '32px', - display: 'flex', position: 'absolute', left: '0', - justifyContent: 'center', - alignItems: 'center', + ...displayFlex('center', 'center'), cursor: 'pointer', ...activeStyle, }; diff --git a/packages/app/src/pages/affine.tsx b/packages/app/src/pages/affine.tsx index 2d5bbe9b30..5596e2778e 100644 --- a/packages/app/src/pages/affine.tsx +++ b/packages/app/src/pages/affine.tsx @@ -1,12 +1,10 @@ -import { styled } from '@/styles'; +import { displayFlex, styled } from '@/styles'; import { ThemeModeSwitch } from '@/components/theme-mode-switch'; export const StyledHeader = styled('div')({ height: '60px', width: '100vw', - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', + ...displayFlex('space-between', 'center'), position: 'relative', padding: '0 22px', borderBottom: '1px solid #e5e5e5', diff --git a/packages/app/src/pages/index.tsx b/packages/app/src/pages/index.tsx index 5fc28e0866..628b9f0334 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 EdgelessToolbar from '@/components/edgeless-toolbar'; import '@/components/simple-counter'; const StyledEditorContainer = styled('div')(({ theme }) => { @@ -33,6 +34,7 @@ const Home: NextPage = () => { + ); }; diff --git a/packages/app/src/styles/helper.ts b/packages/app/src/styles/helper.ts new file mode 100644 index 0000000000..50955a254b --- /dev/null +++ b/packages/app/src/styles/helper.ts @@ -0,0 +1,84 @@ +import type { CSSProperties } from 'react'; + +export const displayFlex = ( + justifyContent: CSSProperties['justifyContent'] = 'unset', + alignItems: CSSProperties['alignContent'] = 'unset', + alignContent: CSSProperties['alignContent'] = 'unset' +): { + display: CSSProperties['display']; + justifyContent: CSSProperties['justifyContent']; + alignItems: CSSProperties['alignContent']; + alignContent: CSSProperties['alignContent']; +} => { + return { + display: 'flex', + justifyContent, + alignItems, + alignContent, + }; +}; + +export const absoluteCenter = ({ + horizontal = false, + vertical = false, + position: { left, right, top, bottom } = {}, +}: { + horizontal?: boolean; + vertical?: boolean; + position?: { + left?: CSSProperties['left']; + right?: CSSProperties['right']; + top?: CSSProperties['top']; + bottom?: CSSProperties['bottom']; + }; +}): { + position: CSSProperties['position']; + left: CSSProperties['left']; + top: CSSProperties['top']; + right: CSSProperties['right']; + bottom: CSSProperties['bottom']; + transform: CSSProperties['transform']; +} => { + return { + position: 'absolute', + left: left ? left : horizontal ? '50%' : 'auto', + top: top ? top : vertical ? '50%' : 'auto', + right: right ? right : horizontal ? 'auto' : 'auto', + bottom: bottom ? bottom : vertical ? 'auto' : 'auto', + transform: `translate(${horizontal ? '-50%' : '0'}, ${ + vertical ? '-50%' : '0' + })`, + }; +}; +export const fixedCenter = ({ + horizontal = false, + vertical = false, + position: { left, right, top, bottom } = {}, +}: { + horizontal?: boolean; + vertical?: boolean; + position?: { + left?: CSSProperties['left']; + right?: CSSProperties['right']; + top?: CSSProperties['top']; + bottom?: CSSProperties['bottom']; + }; +}): { + position: CSSProperties['position']; + left: CSSProperties['left']; + top: CSSProperties['top']; + right: CSSProperties['right']; + bottom: CSSProperties['bottom']; + transform: CSSProperties['transform']; +} => { + return { + position: 'fixed', + left: left ? left : horizontal ? '50%' : 'auto', + top: top ? top : vertical ? '50%' : 'auto', + right: right ? right : horizontal ? 'auto' : 'auto', + bottom: bottom ? bottom : vertical ? 'auto' : 'auto', + transform: `translate(${horizontal ? '-50%' : '0'}, ${ + vertical ? '-50%' : '0' + })`, + }; +}; diff --git a/packages/app/src/styles/index.ts b/packages/app/src/styles/index.ts index e74c167d3c..7c6781815e 100644 --- a/packages/app/src/styles/index.ts +++ b/packages/app/src/styles/index.ts @@ -4,3 +4,4 @@ export * from './styled'; export { ThemeProvider } from './themeProvider'; export { lightTheme, darkTheme } from './theme'; export { useTheme } from './hooks'; +export * from './helper';