From 2b13a63848ffe27ba3efc2fe9986b4bbb83aaac1 Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Tue, 18 Oct 2022 11:55:10 +0800 Subject: [PATCH 1/5] feat: modify theme mode switch style --- packages/app/src/components/Header/icons.tsx | 40 ----------- packages/app/src/components/Header/index.tsx | 30 +-------- .../components/editor-mode-switch/style.ts | 2 +- .../components/theme-mode-switch/icons.tsx | 44 ++++++++++++ .../components/theme-mode-switch/index.tsx | 46 +++++++++++++ .../src/components/theme-mode-switch/style.ts | 67 +++++++++++++++++++ packages/app/src/pages/affine.tsx | 20 +++++- packages/app/src/styles/theme.ts | 2 + packages/app/src/styles/types.ts | 1 + 9 files changed, 183 insertions(+), 69 deletions(-) create mode 100644 packages/app/src/components/theme-mode-switch/icons.tsx create mode 100644 packages/app/src/components/theme-mode-switch/index.tsx create mode 100644 packages/app/src/components/theme-mode-switch/style.ts diff --git a/packages/app/src/components/Header/icons.tsx b/packages/app/src/components/Header/icons.tsx index 9e27fc7875..6f9d5ebee1 100644 --- a/packages/app/src/components/Header/icons.tsx +++ b/packages/app/src/components/Header/icons.tsx @@ -22,46 +22,6 @@ export const LogoIcon = ({ style = {}, ...props }: IconProps) => { ); }; -export const MoonIcon = ({ style = {}, ...props }: IconProps) => { - return ( - - - - ); -}; - -export const SunIcon = ({ style = {}, ...props }: IconProps) => { - return ( - - - - ); -}; - export const MoreIcon = ({ style = {}, ...props }: IconProps) => { return ( { - const { changeMode, mode } = useTheme(); - - return ( - <> - {mode === 'dark' ? ( - { - changeMode('light'); - }} - > - ) : ( - { - changeMode('dark'); - }} - > - )} - - ); -}; +import ThemeModeSwitch from '@/components/theme-mode-switch'; const PopoverContent = () => { const { editor, mode, setMode } = useEditor(); @@ -109,7 +85,7 @@ export const Header = () => { - + } style={{ marginLeft: '20px' }} diff --git a/packages/app/src/components/editor-mode-switch/style.ts b/packages/app/src/components/editor-mode-switch/style.ts index aea2af5738..f12dd45763 100644 --- a/packages/app/src/components/editor-mode-switch/style.ts +++ b/packages/app/src/components/editor-mode-switch/style.ts @@ -3,7 +3,7 @@ import { keyframes, styled } from '@/styles'; import spring, { toString } from 'css-spring'; import type { ItemStatus } from './type'; -const ANIMATE_DURATION = 300; +const ANIMATE_DURATION = 400; export const StyledAnimateRadioContainer = styled('div')<{ shrink: boolean }>( ({ shrink }) => { diff --git a/packages/app/src/components/theme-mode-switch/icons.tsx b/packages/app/src/components/theme-mode-switch/icons.tsx new file mode 100644 index 0000000000..43d9688d08 --- /dev/null +++ b/packages/app/src/components/theme-mode-switch/icons.tsx @@ -0,0 +1,44 @@ +import type { DOMAttributes, CSSProperties } from 'react'; +type IconProps = { + style?: CSSProperties; +} & DOMAttributes; + +export const MoonIcon = ({ style = {}, ...props }: IconProps) => { + return ( + + + + ); +}; + +export const SunIcon = ({ style = {}, ...props }: IconProps) => { + return ( + + + + ); +}; diff --git a/packages/app/src/components/theme-mode-switch/index.tsx b/packages/app/src/components/theme-mode-switch/index.tsx new file mode 100644 index 0000000000..324a3cfdae --- /dev/null +++ b/packages/app/src/components/theme-mode-switch/index.tsx @@ -0,0 +1,46 @@ +import { useState } from 'react'; +import { useTheme } from '@/styles'; +import { MoonIcon, SunIcon } from './icons'; +import { StyledThemeModeSwitch, StyledSwitchItem } from './style'; + +export const ThemeModeSwitch = () => { + const { mode, changeMode } = useTheme(); + const [isHover, setIsHover] = useState(false); + const [firstTrigger, setFirstTrigger] = useState(false); + return ( + { + setIsHover(true); + if (!firstTrigger) { + setFirstTrigger(true); + } + }} + onMouseLeave={() => { + setIsHover(false); + }} + > + { + changeMode('light'); + }} + > + + + { + changeMode('dark'); + }} + > + + + + ); +}; + +export default ThemeModeSwitch; diff --git a/packages/app/src/components/theme-mode-switch/style.ts b/packages/app/src/components/theme-mode-switch/style.ts new file mode 100644 index 0000000000..605fd304e2 --- /dev/null +++ b/packages/app/src/components/theme-mode-switch/style.ts @@ -0,0 +1,67 @@ +import { keyframes, styled } from '@/styles'; +import { CSSProperties } from 'react'; +// @ts-ignore +import spring, { toString } from 'css-spring'; + +const ANIMATE_DURATION = 400; + +export const StyledThemeModeSwitch = styled('div')({ + width: '32px', + height: '32px', + borderRadius: '5px', + overflow: 'hidden', + backgroundColor: 'transparent', + position: 'relative', +}); +export const StyledSwitchItem = styled('div')<{ + active: boolean; + isHover: boolean; + firstTrigger: boolean; +}>(({ active, isHover, firstTrigger, theme }) => { + const activeRaiseAnimate = keyframes`${toString( + spring({ top: '0' }, { top: '-100%' }, { preset: 'gentle' }) + )}`; + const raiseAnimate = keyframes`${toString( + spring({ top: '100%' }, { top: '0' }, { preset: 'gentle' }) + )}`; + const activeDeclineAnimate = keyframes`${toString( + spring({ top: '-100%' }, { top: '0' }, { preset: 'gentle' }) + )}`; + const declineAnimate = keyframes`${toString( + spring({ top: '0' }, { top: '100%' }, { preset: 'gentle' }) + )}`; + const activeStyle = active + ? { + color: theme.colors.disabled, + top: '0', + animation: firstTrigger + ? `${ + isHover ? activeRaiseAnimate : activeDeclineAnimate + } ${ANIMATE_DURATION}ms forwards` + : 'unset', + animationDirection: isHover ? 'normal' : 'alternate', + } + : ({ + top: '100%', + color: theme.colors.highlight, + backgroundColor: theme.colors.hoverBackground, + animation: firstTrigger + ? `${ + isHover ? raiseAnimate : declineAnimate + } ${ANIMATE_DURATION}ms forwards` + : 'unset', + animationDirection: isHover ? 'normal' : 'alternate', + } as CSSProperties); + + return { + width: '32px', + height: '32px', + display: 'flex', + position: 'absolute', + left: '0', + justifyContent: 'center', + alignItems: 'center', + cursor: 'pointer', + ...activeStyle, + }; +}); diff --git a/packages/app/src/pages/affine.tsx b/packages/app/src/pages/affine.tsx index 73b35a6689..2d5bbe9b30 100644 --- a/packages/app/src/pages/affine.tsx +++ b/packages/app/src/pages/affine.tsx @@ -1,5 +1,23 @@ +import { 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', + position: 'relative', + padding: '0 22px', + borderBottom: '1px solid #e5e5e5', +}); + const Affine = () => { - return
affine page
; + return ( + + + + ); }; export default Affine; diff --git a/packages/app/src/styles/theme.ts b/packages/app/src/styles/theme.ts index 5b00dd2583..464403c3c1 100644 --- a/packages/app/src/styles/theme.ts +++ b/packages/app/src/styles/theme.ts @@ -7,6 +7,7 @@ export const lightTheme: AffineTheme = { highlight: '#7389FD', disabled: '#9096A5', background: '#fff', + hoverBackground: '#F1F3FF', }, font: { xs: '12px', @@ -22,6 +23,7 @@ export const darkTheme: AffineTheme = { highlight: '#7389FD', disabled: '#9096A5', background: '#3d3c3f', + hoverBackground: '#F1F3FF', }, }; diff --git a/packages/app/src/styles/types.ts b/packages/app/src/styles/types.ts index 7c042957c5..9eec4c335c 100644 --- a/packages/app/src/styles/types.ts +++ b/packages/app/src/styles/types.ts @@ -17,6 +17,7 @@ export interface AffineTheme { highlight: string; disabled: string; background: string; + hoverBackground: string; }; font: { xs: string; // tiny From 90dba82a59736ee2d0864e1ce50d9c907bad0d15 Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Tue, 18 Oct 2022 17:08:42 +0800 Subject: [PATCH 2/5] feat: modify style variables --- packages/app/public/globals.css | 4 +- packages/app/src/components/Header/index.tsx | 2 +- packages/app/src/components/Header/styles.ts | 55 +++++------ .../components/editor-mode-switch/index.tsx | 26 ++--- .../components/editor-mode-switch/style.ts | 34 +++---- packages/app/src/components/faq/style.ts | 19 ++-- packages/app/src/components/popover/index.tsx | 8 +- .../src/components/simple-counter/index.ts | 2 +- .../src/components/theme-mode-switch/style.ts | 4 +- .../app/src/components/tooltip/Tooltip.tsx | 2 +- packages/app/src/pages/index.tsx | 14 +-- packages/app/src/pages/temporary.css | 74 +++++++------- packages/app/src/styles/theme.ts | 97 ++++++++++++++----- packages/app/src/styles/themeProvider.tsx | 4 +- packages/app/src/styles/types.ts | 55 ++++++++++- 15 files changed, 232 insertions(+), 168 deletions(-) diff --git a/packages/app/public/globals.css b/packages/app/public/globals.css index 62b1feadfd..35d63bd2e7 100644 --- a/packages/app/public/globals.css +++ b/packages/app/public/globals.css @@ -145,7 +145,7 @@ button, select, keygen, legend { - color: var(--page-text-color); + color: var(--affine-text-color); outline: 0; font-size: 18px; line-height: 1.5; @@ -156,7 +156,7 @@ body { } a, a:hover { - color: var(--page-text-color); + color: var(--affine-link-color); } input { diff --git a/packages/app/src/components/Header/index.tsx b/packages/app/src/components/Header/index.tsx index 4a982b4366..504ec1c184 100644 --- a/packages/app/src/components/Header/index.tsx +++ b/packages/app/src/components/Header/index.tsx @@ -65,7 +65,7 @@ export const Header = () => { return ( - {}} /> + {}} /> { diff --git a/packages/app/src/components/Header/styles.ts b/packages/app/src/components/Header/styles.ts index 8162ca2eaa..16ac015e7a 100644 --- a/packages/app/src/components/Header/styles.ts +++ b/packages/app/src/components/Header/styles.ts @@ -33,14 +33,10 @@ export const StyledTitleWrapper = styled('div')({ position: 'relative', }); -export const StyledLogo = styled('div')({}); - -export const StyledModeSwitch = styled('div')({ - height: '100%', - display: 'flex', - alignItems: 'center', - marginRight: '12px', -}); +export const StyledLogo = styled('div')(({ theme }) => ({ + color: theme.colors.primaryColor, + cursor: 'pointer', +})); export const StyledHeaderRightSide = styled('div')({ height: '100%', @@ -48,27 +44,25 @@ export const StyledHeaderRightSide = styled('div')({ alignItems: 'center', }); -export const StyledMoreMenuItem = styled('div')({ - height: '32px', - display: 'flex', - alignItems: 'center', - borderRadius: '5px', - fontSize: '14px', - color: '#4C6275', - padding: '0 14px', - svg: { - fill: '#4C6275', - width: '16px', - height: '16px', - marginRight: '14px', - }, - ':hover': { - color: 'var(--affine-highlight-color)', - background: '#F1F3FF', +export const StyledMoreMenuItem = styled('div')(({ theme }) => { + return { + height: '32px', + display: 'flex', + alignItems: 'center', + borderRadius: '5px', + fontSize: '14px', + color: theme.colors.popoverColor, + padding: '0 14px', svg: { - fill: 'var(--affine-highlight-color)', + width: '16px', + height: '16px', + marginRight: '14px', }, - }, + ':hover': { + color: theme.colors.primaryColor, + background: theme.colors.hoverBackground, + }, + }; }); export const IconButton = styled('div')(({ theme }) => { @@ -78,12 +72,11 @@ export const IconButton = styled('div')(({ theme }) => { display: 'flex', justifyContent: 'center', alignItems: 'center', - color: theme.colors.disabled, - background: 'transparent', + color: theme.colors.iconColor, borderRadius: '5px', ':hover': { - color: theme.colors.highlight, - background: '#F1F3FF', + color: theme.colors.primaryColor, + background: theme.colors.hoverBackground, }, }; }); diff --git a/packages/app/src/components/editor-mode-switch/index.tsx b/packages/app/src/components/editor-mode-switch/index.tsx index 9558abc756..94bc5c5204 100644 --- a/packages/app/src/components/editor-mode-switch/index.tsx +++ b/packages/app/src/components/editor-mode-switch/index.tsx @@ -1,7 +1,6 @@ import React, { useState, useEffect, cloneElement } from 'react'; import { StyledAnimateRadioContainer, - StyledRadioMiddle, StyledMiddleLine, StyledRadioItem, StyledLabel, @@ -19,21 +18,21 @@ import { useEditor } from '@/components/editor-provider'; const PaperItem = ({ active }: { active?: boolean }) => { const { theme: { - colors: { highlight, disabled }, + colors: { iconColor, primaryColor }, }, } = useTheme(); - return ; + return ; }; const EdgelessItem = ({ active }: { active?: boolean }) => { const { theme: { - colors: { highlight, disabled }, + colors: { iconColor, primaryColor }, }, } = useTheme(); - return ; + return ; }; const AnimateRadioItem = ({ @@ -57,24 +56,11 @@ const AnimateRadioItem = ({ ); }; -const RadioMiddle = ({ - isHover, - direction, -}: { - isHover: boolean; - direction: 'left' | 'right' | 'middle'; -}) => { - return ( - - ); -}; - export const EditorModeSwitch = ({ isHover, style = {}, }: AnimateRadioProps) => { + const { mode: themeMode } = useTheme(); const { mode, setMode } = useEditor(); const modifyRadioItemStatus = (): RadioItemStatus => { return { @@ -124,7 +110,7 @@ export const EditorModeSwitch = ({ setRadioItemStatus(modifyRadioItemStatus()); }} /> -