diff --git a/packages/mask/src/UIRoot.tsx b/packages/mask/src/UIRoot.tsx
index aa9a5f12c085..caa45b96d77f 100644
--- a/packages/mask/src/UIRoot.tsx
+++ b/packages/mask/src/UIRoot.tsx
@@ -1,6 +1,6 @@
import { Suspense } from 'react'
import { Web3Provider } from '@masknet/web3-shared-evm'
-import { CssBaseline, StyledEngineProvider, Theme } from '@mui/material'
+import { StyledEngineProvider, Theme } from '@mui/material'
import { NetworkPluginID, PluginsWeb3ContextProvider, useAllPluginsWeb3State } from '@masknet/plugin-infra'
import { I18NextProviderHMR, SharedContextProvider } from '@masknet/shared'
import { ErrorBoundary, ErrorBoundaryBuildInfoContext, useValueRef } from '@masknet/shared-base-ui'
@@ -57,10 +57,8 @@ export function MaskUIRoot({ children, kind, useTheme }: MaskUIRootProps) {
useMaskIconPalette={useMaskIconPalette}
CustomSnackbarOffsetY={isFacebook(activatedSocialNetworkUI) ? 80 : undefined}
useTheme={useTheme}
- baseline={kind === 'page'}>
-
- {jsx}
-
+ children={jsx}
+ />
),
(jsx) => {jsx},
)
diff --git a/packages/mask/src/extension/options-page/DashboardDialogs/Base.tsx b/packages/mask/src/extension/options-page/DashboardDialogs/Base.tsx
index 94633995c73a..57b1986d4599 100644
--- a/packages/mask/src/extension/options-page/DashboardDialogs/Base.tsx
+++ b/packages/mask/src/extension/options-page/DashboardDialogs/Base.tsx
@@ -10,9 +10,13 @@ import {
IconButtonProps,
} from '@mui/material'
import { makeStyles } from '@masknet/theme'
-import { ThemeProvider } from '@mui/material/styles'
+import { Theme, ThemeOptions, ThemeProvider } from '@mui/material/styles'
import CloseIcon from '@mui/icons-material/Close'
-import { extendsTheme, useClassicMaskFullPageTheme, useMatchXS } from '../../../utils'
+import { useMatchXS } from '../../../utils'
+import { useClassicMaskFullPageTheme } from '../../../utils/theme/useClassicMaskFullPageTheme'
+import { appearanceSettings, languageSettings } from '../../../settings/settings'
+import { useValueRef } from '@masknet/shared-base-ui'
+import { cloneDeep, merge } from 'lodash-unified'
const useStyles = makeStyles()((theme) => ({
root: {
@@ -101,7 +105,7 @@ export function useModal
@@ -160,6 +164,9 @@ const useDashboardDialogWrapperStyles = makeStyles(
},
}))
+function extendsTheme(extend: (theme: Theme) => ThemeOptions) {
+ return (theme: Theme) => merge(cloneDeep(theme), extend(theme))
+}
const dialogTheme = extendsTheme((theme) => ({
components: {
MuiOutlinedInput: {
diff --git a/packages/mask/src/extension/popups/UI.tsx b/packages/mask/src/extension/popups/UI.tsx
index c50ed7a8e8ef..9e5993fe12c9 100644
--- a/packages/mask/src/extension/popups/UI.tsx
+++ b/packages/mask/src/extension/popups/UI.tsx
@@ -2,16 +2,17 @@ import { lazy } from 'react'
import { Navigate, Route, Routes, HashRouter } from 'react-router-dom'
import { createInjectHooksRenderer, useActivatedPluginsDashboard } from '@masknet/plugin-infra'
import { PopupRoutes } from '@masknet/shared-base'
-import { useClassicMaskFullPageTheme } from '../../utils'
+import { usePopupFullPageTheme } from '../../utils/theme/useClassicMaskFullPageTheme'
import '../../social-network-adaptor/browser-action'
import { Web3Provider } from '@masknet/web3-shared-evm'
import { PopupWeb3Context } from '../../web3/context'
import { PopupFrame } from './components/PopupFrame'
-import { Appearance } from '@masknet/theme'
import { MaskUIRoot } from '../../UIRoot'
+import { useValueRef } from '@masknet/shared-base-ui'
+import { languageSettings } from '../../settings/settings'
-function useAlwaysLightTheme() {
- return useClassicMaskFullPageTheme({ forcePalette: Appearance.light })
+function usePopupTheme() {
+ return usePopupFullPageTheme(useValueRef(languageSettings))
}
const Wallet = lazy(() => import('./pages/Wallet'))
const Personas = lazy(() => import('./pages/Personas'))
@@ -24,7 +25,7 @@ const PluginRender = createInjectHooksRenderer(useActivatedPluginsDashboard, (x)
export default function Popups() {
return (
-
+
diff --git a/packages/mask/src/extension/popups/components/PopupFrame/index.tsx b/packages/mask/src/extension/popups/components/PopupFrame/index.tsx
index 21881ee4d917..b33b6f700f59 100644
--- a/packages/mask/src/extension/popups/components/PopupFrame/index.tsx
+++ b/packages/mask/src/extension/popups/components/PopupFrame/index.tsx
@@ -17,7 +17,7 @@ function GlobalCss() {
overflowX: 'hidden',
margin: '0 auto !important',
maxWidth: '100%',
- '-webkit-font-smoothing': 'subpixel-antialiased',
+ WebkitFontSmoothing: 'subpixel-antialiased',
'&::-webkit-scrollbar': {
display: 'none',
},
diff --git a/packages/mask/src/extension/popups/pages/Swap/index.tsx b/packages/mask/src/extension/popups/pages/Swap/index.tsx
index 4adb25540b66..a4475eba395b 100644
--- a/packages/mask/src/extension/popups/pages/Swap/index.tsx
+++ b/packages/mask/src/extension/popups/pages/Swap/index.tsx
@@ -9,7 +9,8 @@ import { WalletStateBarUI } from '../../components/WalletStateBar'
import { SwapBox } from './SwapBox'
import { SwapWeb3Context } from '../../../../web3/context'
import { PopupRoutes } from '@masknet/shared-base'
-import { useI18N, usePopupsMaskFullPageTheme } from '../../../../utils'
+import { useI18N } from '../../../../utils'
+import { useSwapPageTheme } from '../../../../utils/theme/useSwapPageTheme'
import { NetworkPluginID, useReverseAddress } from '@masknet/plugin-infra'
import { TargetChainIdContext } from '../../../../plugins/Trader/trader/useTargetChainIdContext'
import { AllProviderTradeContext } from '../../../../plugins/Trader/trader/useAllProviderTradeContext'
@@ -68,7 +69,7 @@ export default function SwapPage() {
const { t } = useI18N()
const { classes } = useStyles()
const chainId = useChainId()
- const theme = usePopupsMaskFullPageTheme()
+ const theme = useSwapPageTheme()
const { value: pendingTransactions = [] } = useRecentTransactions({
status: TransactionStatusType.NOT_DEPEND,
})
diff --git a/packages/mask/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx b/packages/mask/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx
index d58a66ae9710..6beab8740f0e 100644
--- a/packages/mask/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx
+++ b/packages/mask/src/plugins/ITO/SNSAdaptor/ClaimAllDialog.tsx
@@ -95,7 +95,7 @@ const useStyles = makeStyles()((theme, props) => {
width: '100%',
alignItems: 'center',
justifyContent: 'space-between',
- '-webkit-font-smoothing': 'antialiased',
+ WebkitFontSmoothing: 'antialiased',
fontSize: 14,
},
cardHeaderLocked: {
diff --git a/packages/mask/src/plugins/VCent/SNSAdaptor/TweetDialog.tsx b/packages/mask/src/plugins/VCent/SNSAdaptor/TweetDialog.tsx
index e67ab12d39da..e5d41cb662e7 100644
--- a/packages/mask/src/plugins/VCent/SNSAdaptor/TweetDialog.tsx
+++ b/packages/mask/src/plugins/VCent/SNSAdaptor/TweetDialog.tsx
@@ -1,7 +1,7 @@
import { first } from 'lodash-unified'
import { Button } from '@mui/material'
import { makeStyles } from '@masknet/theme'
-import { isDarkTheme } from '../../../utils/theme-tools'
+import { isDarkTheme } from '../../../utils/theme'
import { ETHIcon } from '../icons/ETH'
import { VCentIconLight, VCentIconDark } from '../icons/VCent'
import { VALUABLES_VCENT_URL } from '../constants'
diff --git a/packages/mask/src/plugins/Wallet/SNSAdaptor/RiskWarningDialog/index.tsx b/packages/mask/src/plugins/Wallet/SNSAdaptor/RiskWarningDialog/index.tsx
index 0c01a034f884..19b6b54280de 100644
--- a/packages/mask/src/plugins/Wallet/SNSAdaptor/RiskWarningDialog/index.tsx
+++ b/packages/mask/src/plugins/Wallet/SNSAdaptor/RiskWarningDialog/index.tsx
@@ -50,9 +50,9 @@ const useStyles = makeStyles()((theme) => ({
marginTop: theme.spacing(2),
padding: theme.spacing(2),
borderRadius: theme.spacing(1),
- '&> :first-child': {
- paddingBottom: theme.spacing(1),
- },
+ },
+ texts: {
+ paddingBottom: theme.spacing(1),
},
}))
@@ -104,10 +104,10 @@ export function WalletRiskWarningDialog() {
children={{t('wallet_risk_warning_content')}}
/>
-
+
{t('nft_wallet_label')}
-
+
{isMobile ? formatEthereumAddress(account, 5) : account}
diff --git a/packages/mask/src/social-network-adaptor/facebook.com/customization/custom.ts b/packages/mask/src/social-network-adaptor/facebook.com/customization/custom.ts
index 2d163de13460..2042d879c223 100644
--- a/packages/mask/src/social-network-adaptor/facebook.com/customization/custom.ts
+++ b/packages/mask/src/social-network-adaptor/facebook.com/customization/custom.ts
@@ -5,7 +5,7 @@ import { useMemo } from 'react'
import { useValueRef } from '@masknet/shared-base-ui'
import { SubscriptionFromValueRef } from '@masknet/shared-base'
import type { SocialNetworkUI } from '../../../social-network'
-import { fromRGB, isDark, shade, toRGB } from '../../../utils/theme-tools'
+import { fromRGB, isDark, shade, toRGB } from '../../../utils/theme'
const primaryColorRef = new ValueRef(toRGB([29, 161, 242]))
const primaryColorContrastColorRef = new ValueRef(toRGB([255, 255, 255]))
diff --git a/packages/mask/src/social-network-adaptor/minds.com/customization/custom.ts b/packages/mask/src/social-network-adaptor/minds.com/customization/custom.ts
index 71f388a0f0d7..18b2086f0e34 100644
--- a/packages/mask/src/social-network-adaptor/minds.com/customization/custom.ts
+++ b/packages/mask/src/social-network-adaptor/minds.com/customization/custom.ts
@@ -5,7 +5,7 @@ import { useMemo } from 'react'
import { useValueRef } from '@masknet/shared-base-ui'
import { SubscriptionFromValueRef } from '@masknet/shared-base'
import type { SocialNetworkUI } from '../../../social-network'
-import { fromRGB, getBackgroundColor, getForegroundColor, shade, toRGB } from '../../../utils/theme-tools'
+import { fromRGB, getBackgroundColor, getForegroundColor, shade, toRGB } from '../../../utils/theme'
import { themeListItemSelector } from '../utils/selector'
// TODO: get this from DOM. But currently Minds has a single primary color
diff --git a/packages/mask/src/social-network-adaptor/twitter.com/customization/custom.ts b/packages/mask/src/social-network-adaptor/twitter.com/customization/custom.ts
index 9377d76923ad..e6cff6cc609a 100644
--- a/packages/mask/src/social-network-adaptor/twitter.com/customization/custom.ts
+++ b/packages/mask/src/social-network-adaptor/twitter.com/customization/custom.ts
@@ -5,7 +5,7 @@ import { PaletteMode, Theme, unstable_createMuiStrictModeTheme } from '@mui/mate
import produce, { setAutoFreeze } from 'immer'
import { useMemo } from 'react'
import type { SocialNetworkUI } from '../../../social-network'
-import { fromRGB, getBackgroundColor, getForegroundColor, isDark, shade, toRGB } from '../../../utils/theme-tools'
+import { fromRGB, getBackgroundColor, getForegroundColor, isDark, shade, toRGB } from '../../../utils/theme'
import { isMobileTwitter } from '../utils/isMobile'
import { composeAnchorSelector, composeAnchorTextSelector, headingTextSelector } from '../utils/selector'
import twitterColorSchema from './twitter-color-schema.json'
diff --git a/packages/mask/src/utils/index.ts b/packages/mask/src/utils/index.ts
index c6a009552f39..eba2a666feb7 100644
--- a/packages/mask/src/utils/index.ts
+++ b/packages/mask/src/utils/index.ts
@@ -11,7 +11,6 @@ export * from './i18n-next-ui'
export * from './messages'
export * from './permissions'
export * from './createNormalReactRoot'
-export * from './theme-tools'
export * from './theme'
export * from './utils'
export * from './watcher'
diff --git a/packages/mask/src/utils/theme/MaskTheme.ts b/packages/mask/src/utils/theme/MaskTheme.ts
new file mode 100644
index 000000000000..3aad54159e25
--- /dev/null
+++ b/packages/mask/src/utils/theme/MaskTheme.ts
@@ -0,0 +1,96 @@
+// ! This file is used during SSR. DO NOT import new files that does not work in SSR
+
+import { unstable_createMuiStrictModeTheme, type ThemeOptions } from '@mui/material'
+import { grey, orange } from '@mui/material/colors'
+import { cloneDeep, merge } from 'lodash-unified'
+
+function getFontFamily(monospace?: boolean) {
+ // We want to look native.
+ // Windows has no CJK sans monospace. Accommodate that.
+ // We only use it for fingerprints anyway so CJK coverage ain't a problem... yet.
+ const monofont = navigator.platform.startsWith('Win') ? 'Consolas, monospace' : 'monospace'
+ // https://caniuse.com/font-family-system-ui
+ // Firefox does NOT support yet it in any form on Windows, but tests indicate that it agrees with Edge in using the UI font for sans-serif:
+ // Microsoft YaHei on zh-Hans-CN.
+ return !monospace ? '-apple-system, system-ui, sans-serif' : monofont
+}
+const base: ThemeOptions = {
+ palette: {
+ primary: { main: '#1c68f3' },
+ secondary: orange,
+ text: { hint: 'rgba(0, 0, 0, 0.38)' },
+ },
+ typography: {
+ fontFamily: getFontFamily(),
+ },
+ breakpoints: {
+ values: {
+ xs: 0,
+ sm: 600,
+ md: 1112,
+ lg: 1280,
+ xl: 1920,
+ },
+ },
+ components: {
+ MuiLink: { defaultProps: { underline: 'hover' } },
+ MuiButton: {
+ styleOverrides: {
+ root: {
+ textTransform: 'unset',
+ minWidth: '100px',
+ },
+ },
+ defaultProps: {
+ size: 'small',
+ disableElevation: true,
+ },
+ },
+ MuiTab: {
+ styleOverrides: {
+ root: {
+ textTransform: 'unset',
+ padding: '0',
+ // up-sm
+ '@media screen and (min-width: 600px)': {
+ minWidth: 160,
+ },
+ },
+ },
+ },
+ MuiDialog: {
+ styleOverrides: {
+ paper: {
+ borderRadius: '12px',
+ },
+ },
+ },
+ },
+}
+const lightThemePatch: Partial = {
+ palette: {
+ mode: 'light',
+ },
+}
+const darkThemePatch: Partial = {
+ palette: {
+ mode: 'dark',
+ background: {
+ paper: grey[900],
+ },
+ },
+ components: {
+ MuiPaper: {
+ // https://github.com/mui-org/material-ui/pull/25522
+ styleOverrides: { root: { backgroundImage: 'unset' } },
+ },
+ },
+}
+const baseTheme = (theme: 'dark' | 'light') => {
+ if (theme === 'light') return merge(cloneDeep(base), lightThemePatch)
+ return merge(cloneDeep(base), darkThemePatch)
+}
+/** @deprecated Only use it from useClassicMaskSNSTheme */
+export const MaskLightTheme = unstable_createMuiStrictModeTheme(baseTheme('light'))
+/** @deprecated Only use it from useClassicMaskSNSTheme */
+export const MaskDarkTheme = unstable_createMuiStrictModeTheme(baseTheme('dark'))
diff --git a/packages/mask/src/utils/theme-tools.ts b/packages/mask/src/utils/theme/color-tools.ts
similarity index 94%
rename from packages/mask/src/utils/theme-tools.ts
rename to packages/mask/src/utils/theme/color-tools.ts
index 197f11140ba4..68c7c239196c 100644
--- a/packages/mask/src/utils/theme-tools.ts
+++ b/packages/mask/src/utils/theme/color-tools.ts
@@ -1,3 +1,5 @@
+import { clamp } from 'lodash-unified'
+
type RGB = [number, number, number]
type RGBA = [number, number, number, number]
@@ -19,12 +21,6 @@ export function fromRGB(rgb: string): RGB | undefined {
return
}
-export function clamp(num: number, min: number, max: number) {
- if (num < min) return min
- if (num > max) return max
- return num
-}
-
export function shade(channels: RGB, percentage: number): RGB {
return channels.map((c) => clamp(Math.floor((c * (100 + percentage)) / 100), 0, 255)) as RGB
}
diff --git a/packages/mask/src/utils/theme/index.ts b/packages/mask/src/utils/theme/index.ts
new file mode 100644
index 000000000000..76a6527c393c
--- /dev/null
+++ b/packages/mask/src/utils/theme/index.ts
@@ -0,0 +1,9 @@
+import './theme-global.d'
+
+// Do not export more files. Those files are deprecated.
+export * from './color-tools'
+export * from './MaskTheme'
+export * from './useColorStyles'
+export * from './useErrorStyles'
+export * from './useThemeLanguage'
+export * from './useClassicMaskSNSTheme'
diff --git a/packages/mask/src/utils/theme-global.d.ts b/packages/mask/src/utils/theme/theme-global.d.ts
similarity index 100%
rename from packages/mask/src/utils/theme-global.d.ts
rename to packages/mask/src/utils/theme/theme-global.d.ts
diff --git a/packages/mask/src/utils/theme/useClassicMaskFullPageTheme.ts b/packages/mask/src/utils/theme/useClassicMaskFullPageTheme.ts
new file mode 100644
index 000000000000..8a0da1724299
--- /dev/null
+++ b/packages/mask/src/utils/theme/useClassicMaskFullPageTheme.ts
@@ -0,0 +1,26 @@
+// ! This file is used during SSR. DO NOT import new files that does not work in SSR
+
+import type { LanguageOptions } from '@masknet/public-api'
+import { Appearance } from '@masknet/theme'
+import { PaletteMode, unstable_createMuiStrictModeTheme } from '@mui/material'
+import { MaskDarkTheme, MaskLightTheme } from './MaskTheme'
+import { useThemeLanguage } from './useThemeLanguage'
+
+/**
+ * @deprecated Should migrate to \@masknet/theme
+ */
+export function useClassicMaskFullPageTheme(userPreference: Appearance, language: LanguageOptions) {
+ const systemPreference: PaletteMode =
+ 'matchMedia' in globalThis ? (matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : 'light'
+ const finalPalette: PaletteMode = userPreference === Appearance.default ? systemPreference : userPreference
+
+ const baseTheme = finalPalette === 'dark' ? MaskDarkTheme : MaskLightTheme
+ return unstable_createMuiStrictModeTheme(baseTheme, useThemeLanguage(language))
+}
+
+/**
+ * @deprecated Should migrate to \@masknet/theme
+ */
+export function usePopupFullPageTheme(language: LanguageOptions) {
+ return useClassicMaskFullPageTheme(Appearance.light, language)
+}
diff --git a/packages/mask/src/utils/theme/useClassicMaskSNSTheme.ts b/packages/mask/src/utils/theme/useClassicMaskSNSTheme.ts
new file mode 100644
index 000000000000..e8f23320ff84
--- /dev/null
+++ b/packages/mask/src/utils/theme/useClassicMaskSNSTheme.ts
@@ -0,0 +1,28 @@
+import { unstable_createMuiStrictModeTheme } from '@mui/material'
+import type { Theme } from '@mui/material/styles/createTheme'
+import { useRef } from 'react'
+import { activatedSocialNetworkUI } from '../../social-network'
+import { useSubscription } from 'use-subscription'
+import { MaskDarkTheme, MaskLightTheme } from './MaskTheme'
+import { useThemeLanguage } from './useThemeLanguage'
+import { SubscriptionFromValueRef } from '@masknet/shared-base'
+import { ValueRef } from '@dimensiondev/holoflows-kit'
+import { useValueRef } from '@masknet/shared-base-ui'
+import { languageSettings } from '../../settings/settings'
+
+const staticRef = SubscriptionFromValueRef(new ValueRef('light'))
+const defaultUseTheme = (t: Theme) => t
+/**
+ * @deprecated Should migrate to \@masknet/theme
+ */
+export function useClassicMaskSNSTheme() {
+ const provider = useRef(activatedSocialNetworkUI.customization.paletteMode?.current || staticRef).current
+ const usePostTheme = useRef(activatedSocialNetworkUI.customization.useTheme || defaultUseTheme).current
+ const palette = useSubscription(provider)
+ const baseTheme = palette === 'dark' ? MaskDarkTheme : MaskLightTheme
+
+ // TODO: support RTL?
+ const [localization, isRTL] = useThemeLanguage(useValueRef(languageSettings))
+ const theme = unstable_createMuiStrictModeTheme(baseTheme, localization)
+ return usePostTheme(theme)
+}
diff --git a/packages/mask/src/utils/theme/useColorStyles.ts b/packages/mask/src/utils/theme/useColorStyles.ts
new file mode 100644
index 000000000000..1d0d1e1ea458
--- /dev/null
+++ b/packages/mask/src/utils/theme/useColorStyles.ts
@@ -0,0 +1,18 @@
+import { makeStyles } from '@masknet/theme'
+import { blue, green, red } from '@mui/material/colors'
+import type { MaskDarkTheme } from './MaskTheme'
+
+export const useColorStyles = makeStyles()((theme: typeof MaskDarkTheme) => {
+ const dark = theme.palette.mode === 'dark'
+ return {
+ error: {
+ color: dark ? red[500] : red[900],
+ },
+ success: {
+ color: dark ? green[500] : green[800],
+ },
+ info: {
+ color: dark ? blue[500] : blue[800],
+ },
+ }
+})
diff --git a/packages/mask/src/utils/theme/useErrorStyles.ts b/packages/mask/src/utils/theme/useErrorStyles.ts
new file mode 100644
index 000000000000..23734f2110af
--- /dev/null
+++ b/packages/mask/src/utils/theme/useErrorStyles.ts
@@ -0,0 +1,21 @@
+import { makeStyles } from '@masknet/theme'
+import { red } from '@mui/material/colors'
+
+export const useErrorStyles = makeStyles()((theme) => {
+ const dark = theme.palette.mode === 'dark'
+ return {
+ containedPrimary: {
+ backgroundColor: dark ? red[500] : red[900],
+ '&:hover': {
+ backgroundColor: dark ? red[900] : red[700],
+ },
+ },
+ outlinedPrimary: {
+ borderColor: dark ? red[500] : red[900],
+ color: dark ? red[500] : red[900],
+ '&:hover': {
+ borderColor: dark ? red[900] : red[700],
+ },
+ },
+ }
+})
diff --git a/packages/mask/src/utils/theme.ts b/packages/mask/src/utils/theme/useSwapPageTheme.ts
similarity index 52%
rename from packages/mask/src/utils/theme.ts
rename to packages/mask/src/utils/theme/useSwapPageTheme.ts
index 3baa14bdc2ab..f03e10a0f54a 100644
--- a/packages/mask/src/utils/theme.ts
+++ b/packages/mask/src/utils/theme/useSwapPageTheme.ts
@@ -1,149 +1,13 @@
-import { ValueRef } from '@dimensiondev/holoflows-kit'
-import { useValueRef } from '@masknet/shared-base-ui'
-import { SubscriptionFromValueRef } from '@masknet/shared-base'
-import { Appearance, or, makeStyles, parseColor } from '@masknet/theme'
-import { LanguageOptions, SupportedLanguages } from '@masknet/public-api'
-import { PaletteMode, unstable_createMuiStrictModeTheme } from '@mui/material'
-import { blue, green, grey, orange, red } from '@mui/material/colors'
-import { jaJP, koKR, zhTW, zhCN, enUS, Localization } from '@mui/material/locale/index'
-import type { Theme, ThemeOptions } from '@mui/material/styles/createTheme'
-import { cloneDeep, merge } from 'lodash-unified'
-import { useRef } from 'react'
-import { appearanceSettings, languageSettings } from '../settings/settings'
-import { activatedSocialNetworkUI } from '../social-network'
-import './theme-global.d'
-import { Subscription, useSubscription } from 'use-subscription'
+import { parseColor } from '@masknet/theme'
+import { unstable_createMuiStrictModeTheme } from '@mui/material'
import produce, { setAutoFreeze } from 'immer'
-import twitterColorSchema from '../social-network-adaptor/twitter.com/customization/twitter-color-schema.json'
-
-function getFontFamily(monospace?: boolean) {
- // We want to look native.
-
- // Windows has no CJK sans monospace. Accommodate that.
- // We only use it for fingerprints anyway so CJK coverage ain't a problem... yet.
- const monofont = navigator.platform.startsWith('Win') ? 'Consolas, monospace' : 'monospace'
- // https://caniuse.com/font-family-system-ui
- // Firefox does NOT support yet it in any form on Windows, but tests indicate that it agrees with Edge in using the UI font for sans-serif:
- // Microsoft YaHei on zh-Hans-CN.
- return !monospace ? '-apple-system, system-ui, sans-serif' : monofont
-}
-
-const base: ThemeOptions = {
- palette: {
- primary: { main: '#1c68f3' }, // blue,
- secondary: orange,
- text: { hint: 'rgba(0, 0, 0, 0.38)' },
- },
- typography: {
- fontFamily: getFontFamily(),
- },
- breakpoints: {
- values: {
- xs: 0,
- sm: 600,
- md: 1112,
- lg: 1280,
- xl: 1920,
- },
- },
- components: {
- MuiLink: { defaultProps: { underline: 'hover' } },
- MuiButton: {
- styleOverrides: {
- root: {
- textTransform: 'unset',
- minWidth: '100px',
- },
- },
- defaultProps: {
- size: 'small',
- disableElevation: true,
- },
- },
- MuiTab: {
- styleOverrides: {
- root: {
- textTransform: 'unset',
- padding: '0',
- // up-sm
- '@media screen and (min-width: 600px)': {
- minWidth: 160,
- },
- },
- },
- },
- MuiDialog: {
- styleOverrides: {
- paper: {
- borderRadius: '12px',
- },
- },
- },
- },
-}
-
-const lightThemePatch: Partial = {
- palette: {
- mode: 'light',
- },
-}
-
-const darkThemePatch: Partial = {
- palette: {
- mode: 'dark',
- background: {
- paper: grey[900],
- },
- },
- components: {
- MuiPaper: {
- // https://github.com/mui-org/material-ui/pull/25522
- styleOverrides: { root: { backgroundImage: 'unset' } },
- },
- },
-}
-
-const baseTheme = (theme: 'dark' | 'light') => {
- if (theme === 'light') return merge(cloneDeep(base), lightThemePatch)
- return merge(cloneDeep(base), darkThemePatch)
-}
-
-// Theme
-const MaskLightTheme = unstable_createMuiStrictModeTheme(baseTheme('light'))
-const MaskDarkTheme = unstable_createMuiStrictModeTheme(baseTheme('dark'))
-const staticSubscription: Subscription = SubscriptionFromValueRef(new ValueRef('light'))
-export function useClassicMaskSNSTheme() {
- const { current: provider } = useRef(
- activatedSocialNetworkUI.customization.paletteMode?.current || staticSubscription,
- )
- const { current: usePostTheme = (t: Theme) => t } = useRef(activatedSocialNetworkUI.customization.useTheme)
- const palette = useSubscription(provider)
- const baseTheme = palette === 'dark' ? MaskDarkTheme : MaskLightTheme
-
- // TODO: support RTL?
- const [localization, isRTL] = useThemeLanguage()
- const theme = unstable_createMuiStrictModeTheme(baseTheme, localization)
- return usePostTheme(theme)
-}
-/**
- * @deprecated
- * - Popups: migrate to \@masknet/theme package
- */
-export function useClassicMaskFullPageTheme(overwrite?: ClassicMaskFullPageThemeOptions) {
- const userPreference = or(overwrite?.forcePalette, useValueRef(appearanceSettings))
- const systemPreference: PaletteMode = matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
- const finalPalette: PaletteMode = userPreference === Appearance.default ? systemPreference : userPreference
-
- const baseTheme = finalPalette === 'dark' ? MaskDarkTheme : MaskLightTheme
- const [localization, isRTL] = useThemeLanguage()
- // TODO: support RTL
- return unstable_createMuiStrictModeTheme(baseTheme, localization)
-}
+import twitterColorSchema from '../../social-network-adaptor/twitter.com/customization/twitter-color-schema.json'
+import { MaskLightTheme } from './MaskTheme'
/**
- * Only used in swap pages under popups, will replace it in the future
+ * @deprecated Should migrate to \@masknet/theme
*/
-export function usePopupsMaskFullPageTheme() {
+export function useSwapPageTheme() {
const baseTheme = MaskLightTheme
setAutoFreeze(false)
@@ -348,60 +212,3 @@ export function usePopupsMaskFullPageTheme() {
})
return unstable_createMuiStrictModeTheme(PopupTheme)
}
-
-function useThemeLanguage(): [loc: Localization, RTL: boolean] {
- let language = useValueRef(languageSettings)
- // TODO: support auto language
- if (language === LanguageOptions.__auto__) language = LanguageOptions.enUS
-
- const displayLanguage = language as any as SupportedLanguages
-
- const langs: Record = {
- [SupportedLanguages.enUS]: enUS,
- [SupportedLanguages.jaJP]: jaJP,
- [SupportedLanguages.koKR]: koKR,
- [SupportedLanguages.zhTW]: zhTW,
- [SupportedLanguages.zhCN]: zhCN,
- }
- return [langs[displayLanguage] || enUS, false]
-}
-
-export interface ClassicMaskFullPageThemeOptions {
- forcePalette?: Appearance
-}
-
-export const useColorStyles = makeStyles()((theme: typeof MaskDarkTheme) => {
- const dark = theme.palette.mode === 'dark'
- return {
- error: {
- color: dark ? red[500] : red[900],
- },
- success: {
- color: dark ? green[500] : green[800],
- },
- info: {
- color: dark ? blue[500] : blue[800],
- },
- }
-})
-export const useErrorStyles = makeStyles()((theme) => {
- const dark = theme.palette.mode === 'dark'
- return {
- containedPrimary: {
- backgroundColor: dark ? red[500] : red[900],
- '&:hover': {
- backgroundColor: dark ? red[900] : red[700],
- },
- },
- outlinedPrimary: {
- borderColor: dark ? red[500] : red[900],
- color: dark ? red[500] : red[900],
- '&:hover': {
- borderColor: dark ? red[900] : red[700],
- },
- },
- }
-})
-export function extendsTheme(extend: (theme: Theme) => ThemeOptions) {
- return (theme: Theme) => merge(cloneDeep(theme), extend(theme))
-}
diff --git a/packages/mask/src/utils/theme/useThemeLanguage.ts b/packages/mask/src/utils/theme/useThemeLanguage.ts
new file mode 100644
index 000000000000..841c44fbcf6e
--- /dev/null
+++ b/packages/mask/src/utils/theme/useThemeLanguage.ts
@@ -0,0 +1,28 @@
+// ! This file is used during SSR. DO NOT import new files that does not work in SSR
+
+import { LanguageOptions, SupportedLanguages } from '@masknet/public-api'
+import { jaJP, koKR, zhTW, zhCN, enUS, Localization } from '@mui/material/locale/index'
+import { updateLanguage } from '@masknet/shared-base'
+import { startTransition, useEffect } from 'react'
+
+const langs: Record = {
+ [SupportedLanguages.enUS]: enUS,
+ [SupportedLanguages.jaJP]: jaJP,
+ [SupportedLanguages.koKR]: koKR,
+ [SupportedLanguages.zhTW]: zhTW,
+ [SupportedLanguages.zhCN]: zhCN,
+}
+export function useThemeLanguage(language: LanguageOptions): [loc: Localization, RTL: boolean] {
+ useEffect(() => {
+ if (language !== LanguageOptions.__auto__) return
+ startTransition(() => updateLanguage(language))
+ }, [language])
+
+ if (language === LanguageOptions.__auto__) {
+ // we've scheduled an update above.
+ language = LanguageOptions.enUS
+ }
+
+ const displayLanguage = language as any as SupportedLanguages
+ return [langs[displayLanguage] || enUS, false]
+}
diff --git a/packages/theme/src/ThemeProvider.tsx b/packages/theme/src/ThemeProvider.tsx
index ad93110993a8..ef7664dd5744 100644
--- a/packages/theme/src/ThemeProvider.tsx
+++ b/packages/theme/src/ThemeProvider.tsx
@@ -5,16 +5,14 @@ import { CustomSnackbarProvider } from './Components/Snackbar'
function compose(init: React.ReactNode, ...f: ((children: React.ReactNode) => JSX.Element)[]) {
return f.reduceRight((prev, curr) => curr(prev), <>{init}>)
}
-const identity = (jsx: React.ReactNode) => jsx as JSX.Element
export interface MaskThemeProvider extends React.PropsWithChildren<{}> {
- baseline: boolean
useTheme(): Theme
useMaskIconPalette(theme: Theme): MaskIconPalette
CustomSnackbarOffsetY?: number
}
export function MaskThemeProvider(props: MaskThemeProvider) {
- const { children, baseline, useTheme, useMaskIconPalette, CustomSnackbarOffsetY } = props
+ const { children, useTheme, useMaskIconPalette, CustomSnackbarOffsetY } = props
const theme = useTheme()
const MaskIconPalette = useMaskIconPalette(theme)
@@ -30,13 +28,11 @@ export function MaskThemeProvider(props: MaskThemeProvider) {
offsetY={CustomSnackbarOffsetY}
/>
),
- baseline
- ? (jsx) => (
- <>
-
- {jsx}
- >
- )
- : identity,
+ (jsx) => (
+ <>
+
+ {jsx}
+ >
+ ),
)
}
diff --git a/packages/theme/src/index.ts b/packages/theme/src/index.ts
index 3af80710f206..2764905d6304 100644
--- a/packages/theme/src/index.ts
+++ b/packages/theme/src/index.ts
@@ -47,6 +47,7 @@ export * from './UIHelper/custom-ui-helper'
export * from './CSSVariableInjector'
export { getMaskColor, useMaskColor, MaskColorVar, applyMaskColorVars } from './constants'
export type { MaskCSSVariableColor } from './constants'
+export { TssCacheProvider } from 'tss-react'
const query = '(prefers-color-scheme: dark)'
export function useSystemPreferencePalette(): PaletteMode {