diff --git a/apps/web/src/components/affine/pinboard/pinboard-render/OperationButton.tsx b/apps/web/src/components/affine/pinboard/pinboard-render/OperationButton.tsx index 38e5f7fc66..abe926b62b 100644 --- a/apps/web/src/components/affine/pinboard/pinboard-render/OperationButton.tsx +++ b/apps/web/src/components/affine/pinboard/pinboard-render/OperationButton.tsx @@ -1,4 +1,9 @@ -import { MenuItem, MuiClickAwayListener, PureMenu } from '@affine/component'; +import { + baseTheme, + MenuItem, + MuiClickAwayListener, + PureMenu, +} from '@affine/component'; import { useTranslation } from '@affine/i18n'; import { MoreVerticalIcon, @@ -7,7 +12,6 @@ import { PlusIcon, } from '@blocksuite/icons'; import type { PageMeta } from '@blocksuite/store'; -import { useTheme } from '@mui/material'; import { useMemo, useRef, useState } from 'react'; import { useBlockSuiteMetaHelper } from '../../../../hooks/affine/use-block-suite-meta-helper'; @@ -39,9 +43,6 @@ export const OperationButton = ({ onMenuClose, onRename, }: OperationButtonProps) => { - const { - zIndex: { modal: modalIndex }, - } = useTheme(); const { t } = useTranslation(); const timer = useRef>(); @@ -49,7 +50,7 @@ export const OperationButton = ({ const [operationMenuOpen, setOperationMenuOpen] = useState(false); const [pinboardMenuOpen, setPinboardMenuOpen] = useState(false); const [confirmModalOpen, setConfirmModalOpen] = useState(false); - const menuIndex = useMemo(() => modalIndex + 1, [modalIndex]); + const menuIndex = useMemo(() => parseInt(baseTheme.zIndexModal) + 1, []); const { removeToTrash } = useBlockSuiteMetaHelper(blockSuiteWorkspace); return ( diff --git a/apps/web/src/components/pure/footer/styles.ts b/apps/web/src/components/pure/footer/styles.ts index 5c68b642f3..222d649547 100644 --- a/apps/web/src/components/pure/footer/styles.ts +++ b/apps/web/src/components/pure/footer/styles.ts @@ -62,7 +62,7 @@ export const StyledCard = styled('div')<{ ...displayFlex('flex-start', 'flex-start'), marginBottom: '24px', transition: 'background .2s', - background: theme.palette.mode === 'light' ? '#FFF' : '#2C2C2C', + background: 'var(--affine-background-primary-color)', ':hover': { background: 'var(--affine-hover-color)', '.add-icon': { diff --git a/apps/web/src/components/pure/workspace-list-modal/styles.ts b/apps/web/src/components/pure/workspace-list-modal/styles.ts index 2d15e2b1e5..dd1ff2aac7 100644 --- a/apps/web/src/components/pure/workspace-list-modal/styles.ts +++ b/apps/web/src/components/pure/workspace-list-modal/styles.ts @@ -41,28 +41,6 @@ export const StyleWorkspaceTitle = styled('div')(({ theme }) => { }; }); -export const StyledCard = styled('div')<{ - active?: boolean; -}>(({ theme, active }) => { - const borderColor = active ? 'var(--affine-primary-color)' : 'transparent'; - return { - width: '310px', - height: '124px', - cursor: 'pointer', - padding: '16px', - boxShadow: '0px 0px 8px rgba(0, 0, 0, 0.1)', - borderRadius: '12px', - border: `1px solid ${borderColor}`, - ...displayFlex('flex-start', 'flex-start'), - marginBottom: '24px', - transition: 'background .2s', - background: theme.palette.mode === 'light' ? '#FFF' : '#2C2C2C', - ':hover': { - background: 'var(--affine-hover-color)', - }, - }; -}); - export const StyledCreateWorkspaceCard = styled('div')(({ theme }) => { return { width: '310px', diff --git a/apps/web/src/pages/_app.tsx b/apps/web/src/pages/_app.tsx index 67c934772f..7dcc150e34 100644 --- a/apps/web/src/pages/_app.tsx +++ b/apps/web/src/pages/_app.tsx @@ -1,4 +1,5 @@ import '@affine/component/theme/global.css'; +import '@affine/component/theme/theme.css'; import { config, setupGlobal } from '@affine/env'; import { createI18n, I18nextProvider } from '@affine/i18n'; diff --git a/apps/web/src/providers/ThemeProvider.tsx b/apps/web/src/providers/ThemeProvider.tsx index ffc430316e..cf0e10d41c 100644 --- a/apps/web/src/providers/ThemeProvider.tsx +++ b/apps/web/src/providers/ThemeProvider.tsx @@ -1,72 +1,7 @@ -import type { - AffineCssVariables, - AffineTheme, - ThemeProviderProps, -} from '@affine/component'; -import { AffineMuiThemeProvider, getTheme, muiThemes } from '@affine/component'; -import { GlobalStyles } from '@mui/material'; -import kebabCase from 'kebab-case'; -import { ThemeProvider as NextThemeProvider, useTheme } from 'next-themes'; +import type { ThemeProviderProps } from '@affine/component'; +import { ThemeProvider as NextThemeProvider } from 'next-themes'; import type { PropsWithChildren } from 'react'; import type React from 'react'; -import { memo, useEffect, useMemo, useState } from 'react'; - -import { useCurrentMode } from '../hooks/current/use-current-mode'; - -const CssVariablesInjector = memo<{ - theme: AffineTheme; -}>(function ThemeInjector({ theme }) { - return ( - { - variables[ - `--affine-${kebabCase(key)}` as keyof AffineCssVariables - ] = value; - return variables; - }, {} as AffineCssVariables), - }, - body: { - color: 'var(--affine-text-primary-colorr)', - }, - html: { - fontFamily: theme.fontFamily, - fontSize: theme.fontBase, - lineHeight: theme.lineHeight, - }, - }} - /> - ); -}); - -const ThemeProviderInner = memo( - function ThemeProviderInner({ children }) { - const { resolvedTheme: theme } = useTheme(); - const editorMode = useCurrentMode(); - // SSR will always render the light theme, so we need to defer the theme if user selected dark mode - const [deferTheme, setDeferTheme] = useState<'light' | 'dark'>('light'); - - const themeStyle = useMemo( - () => getTheme(deferTheme, editorMode), - [deferTheme, editorMode] - ); - - useEffect(() => { - window.apis?.onThemeChange(theme === 'dark' ? 'dark' : 'light'); - setDeferTheme(theme === 'dark' ? 'dark' : 'light'); - }, [theme]); - return ( - - - {children} - - ); - } -); const themes = ['dark', 'light']; @@ -76,7 +11,7 @@ export const ThemeProvider = ({ }: PropsWithChildren) => { return ( - {children} + {children} ); }; diff --git a/packages/component/.storybook/preview.tsx b/packages/component/.storybook/preview.tsx index d5654e7a3b..ef1a0a8f8d 100644 --- a/packages/component/.storybook/preview.tsx +++ b/packages/component/.storybook/preview.tsx @@ -1,16 +1,10 @@ -import React, { useMemo } from 'react'; +import { useEffect, ComponentType } from 'react'; +import { ThemeProvider, useTheme } from 'next-themes'; import '@blocksuite/editor/themes/affine.css'; -import '../src/theme/global.css'; - -import { - AffineCssVariables, - AffineMuiThemeProvider, - getTheme, - muiThemes, -} from '@affine/component'; +import '@affine/component/theme/global.css'; +import '@affine/component/theme/theme.css'; import { useDarkMode } from 'storybook-dark-mode'; -import { GlobalStyles } from '@mui/material'; -import kebabCase from 'kebab-case'; + export const parameters = { actions: { argTypesRegex: '^on[A-Z].*' }, controls: { @@ -21,35 +15,22 @@ export const parameters = { }, }; -export const decorators = [ - (Story: React.ComponentType) => { - const isDark = useDarkMode(); +const Component = () => { + const isDark = useDarkMode(); + const theme = useTheme(); + useEffect(() => { + theme.setTheme(isDark ? 'dark' : 'light'); + }, [isDark]); + return null; +}; - const theme = useMemo( - () => getTheme(isDark ? 'dark' : 'light', 'page'), - [isDark] - ); +export const decorators = [ + (Story: ComponentType) => { return ( - - { - variables[ - `--affine-${kebabCase(key)}` as keyof AffineCssVariables - ] = value; - return variables; - }, {} as AffineCssVariables), - }, - html: { - fontFamily: theme.fontFamily, - fontSize: theme.fontBase, - lineHeight: theme.lineHeight, - }, - }} - /> + + - + ); }, ]; diff --git a/packages/component/src/components/affine-loading/index.tsx b/packages/component/src/components/affine-loading/index.tsx index e7ccf61e23..d482e2a4b0 100644 --- a/packages/component/src/components/affine-loading/index.tsx +++ b/packages/component/src/components/affine-loading/index.tsx @@ -1,4 +1,4 @@ -import { useTheme } from '@mui/material'; +import { useTheme } from 'next-themes'; import type { FC } from 'react'; import { InternalLottie } from '../internal-lottie'; @@ -16,8 +16,8 @@ export const AffineLoading: FC = ({ autoplay = false, autoReverse = false, }) => { - const theme = useTheme(); - const isDark = theme.palette.mode === 'dark'; + const { theme } = useTheme(); + const isDark = theme === 'dark'; return ( { + variables[`--affine-${kebabCase(key)}` as keyof AffineCssVariables] = + value; + return variables; + }, {} as AffineCssVariables), + }, +}); + +globalStyle('html[data-theme="dark"]', { + vars: { + ...Object.entries(darkTheme).reduce((variables, [key, value]) => { + variables[`--affine-${kebabCase(key)}` as keyof AffineCssVariables] = + value; + return variables; + }, {} as AffineCssVariables), + }, +});