diff --git a/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptedPost.tsx b/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptedPost.tsx index b7c881d3988f..44cb328fa1af 100644 --- a/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptedPost.tsx +++ b/packages/mask/src/components/InjectedComponents/DecryptedPost/DecryptedPost.tsx @@ -6,7 +6,6 @@ import { TypedMessageTuple, } from '@masknet/typed-message' import type { ProfileIdentifier } from '@masknet/shared-base' -import { or } from '@masknet/theme' import { ServicesWithProgress } from '../../../extension/service' import type { Profile } from '../../../database' @@ -69,7 +68,7 @@ export function DecryptPost(props: DecryptPostProps) { const authorInPayload = usePostClaimedAuthor() const current = usePostInfo()! const currentPostBy = usePostInfoDetails.author() - const postBy = or(authorInPayload, currentPostBy) + const postBy = authorInPayload || currentPostBy const postMetadataImages = usePostInfoDetails.postMetadataImages() const mentionedLinks = usePostInfoDetails.mentionedLinks() const Success = props.successComponent || DecryptPostSuccess diff --git a/packages/mask/src/plugins/PoolTogether/UI/Account.tsx b/packages/mask/src/plugins/PoolTogether/UI/Account.tsx index a70ba0eb5b2f..e6fdde3a26fa 100644 --- a/packages/mask/src/plugins/PoolTogether/UI/Account.tsx +++ b/packages/mask/src/plugins/PoolTogether/UI/Account.tsx @@ -1,5 +1,5 @@ import { RefreshIcon } from '@masknet/icons' -import { DarkColor } from '@masknet/theme/constants' +import { DarkColor } from '@masknet/theme/base' import { formatBalance } from '@masknet/web3-shared-evm' import { CircularProgress, Grid, Link, Typography } from '@mui/material' import { makeStyles } from '@masknet/theme' diff --git a/packages/mask/src/plugins/PoolTogether/UI/AccountPool.tsx b/packages/mask/src/plugins/PoolTogether/UI/AccountPool.tsx index f436c932aeff..d77942778965 100644 --- a/packages/mask/src/plugins/PoolTogether/UI/AccountPool.tsx +++ b/packages/mask/src/plugins/PoolTogether/UI/AccountPool.tsx @@ -1,5 +1,5 @@ import { TokenIcon } from '@masknet/shared' -import { DarkColor } from '@masknet/theme/constants' +import { DarkColor } from '@masknet/theme/base' import { formatBalance, useChainId } from '@masknet/web3-shared-evm' import { Grid, Link, Typography } from '@mui/material' import { makeStyles } from '@masknet/theme' diff --git a/packages/mask/src/plugins/PoolTogether/UI/CountdownView.tsx b/packages/mask/src/plugins/PoolTogether/UI/CountdownView.tsx index 2e2f09695089..29ac40f0c873 100644 --- a/packages/mask/src/plugins/PoolTogether/UI/CountdownView.tsx +++ b/packages/mask/src/plugins/PoolTogether/UI/CountdownView.tsx @@ -3,7 +3,7 @@ import { Box, Grid, Typography } from '@mui/material' import { makeStyles, useStylesExtends } from '@masknet/theme' import { useInterval } from 'react-use' import { ONE_SECOND } from '../constants' -import { DarkColor } from '@masknet/theme/constants' +import { DarkColor } from '@masknet/theme/base' import intervalToDuration from 'date-fns/intervalToDuration' const useStyles = makeStyles()((theme) => ({ diff --git a/packages/mask/src/plugins/PoolTogether/UI/PoolTogetherView.tsx b/packages/mask/src/plugins/PoolTogether/UI/PoolTogetherView.tsx index 270adbb042bb..192076f9db5d 100644 --- a/packages/mask/src/plugins/PoolTogether/UI/PoolTogetherView.tsx +++ b/packages/mask/src/plugins/PoolTogether/UI/PoolTogetherView.tsx @@ -1,5 +1,5 @@ import { RefreshIcon } from '@masknet/icons' -import { DarkColor } from '@masknet/theme/constants' +import { DarkColor } from '@masknet/theme/base' import { usePoolTogetherConstants } from '@masknet/web3-shared-evm' import { Card, CardContent, CircularProgress, Paper, Tab, Tabs, Typography } from '@mui/material' import { makeStyles } from '@masknet/theme' diff --git a/packages/shared/src/contexts/base/types.ts b/packages/shared/src/contexts/base/types.ts index 04c1876e526a..d786d5465496 100644 --- a/packages/shared/src/contexts/base/types.ts +++ b/packages/shared/src/contexts/base/types.ts @@ -1,6 +1,12 @@ -import type { ComponentOverwriteConfig } from '@masknet/theme' import type { InjectedDialogClassKey, InjectedDialogProps } from '../components' +type ClassNameMap = { [P in ClassKey]: string } + +interface ComponentOverwriteConfig { + classes?: () => { classes: Partial> } + props?: (props: Props) => Props +} + export interface SharedComponentOverwrite { InjectedDialog?: ComponentOverwriteConfig } diff --git a/packages/theme/.storybook/preview.js b/packages/theme/.storybook/preview.js index 2840f3da7421..26bb809ab09c 100644 --- a/packages/theme/.storybook/preview.js +++ b/packages/theme/.storybook/preview.js @@ -1,6 +1,6 @@ import React, { useEffect, useState } from 'react' import { ThemeProvider, StyledEngineProvider, Box } from '@mui/material' -import { MaskDarkTheme, MaskLightTheme, applyMaskColorVars, DisableShadowRootContext } from '../src/index' +import { MaskDarkTheme, MaskLightTheme, applyMaskColorVars, DisableShadowRootContext } from '@masknet/theme' // Not compatible? // import { withMatrix } from 'storybook-addon-matrix' import { I18nextProvider, initReactI18next } from 'react-i18next' diff --git a/packages/theme/package.json b/packages/theme/package.json index a37c5ca733e4..a37d582a702e 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -5,22 +5,24 @@ "type": "module", "exports": { ".": { - "webpack": "./src/index.ts", - "default": "./dist/src/index.js" + "types": "./dist/src/entry.d.ts", + "webpack": "./src/entry.ts", + "default": "./dist/src/entry.d.ts" }, - "./constants": { - "webpack": "./src/constants.ts", - "default": "./dist/src/constants.js" + "./base": { + "types": "./dist/src/entry-base.d.ts", + "webpack": "./src/entry-base.ts", + "default": "./dist/src/entry-base.js" } }, "typesVersions": { "*": { - "constants": [ - "./dist/src/constants.d.ts" + "base": [ + "./dist/src/entry-base.d.ts" ] } }, - "types": "./dist/src/index.d.ts", + "types": "./dist/src/entry.d.ts", "scripts": { "build-storybook": "build -- build-storybook", "start": "dev -- start-storybook -p 6006" diff --git a/packages/theme/src/CSSVariableInjector.tsx b/packages/theme/src/CSSVariables/Injector.tsx similarity index 88% rename from packages/theme/src/CSSVariableInjector.tsx rename to packages/theme/src/CSSVariables/Injector.tsx index feee253efdd5..8715c49ba1c0 100644 --- a/packages/theme/src/CSSVariableInjector.tsx +++ b/packages/theme/src/CSSVariables/Injector.tsx @@ -1,6 +1,6 @@ import { GlobalStyles, Theme, useTheme } from '@mui/material' import { useRef } from 'react' -import { CSSVariableInjectorCSS } from './constants' +import { CSSVariableInjectorCSS } from './applyToDOM' export function CSSVariableInjector(props: React.PropsWithChildren<{ useTheme?: () => Theme }>) { const { current: useConsistentTheme } = useRef(props.useTheme || useTheme) diff --git a/packages/theme/src/CSSVariables/applyToDOM.ts b/packages/theme/src/CSSVariables/applyToDOM.ts new file mode 100644 index 000000000000..b1887eeab3ea --- /dev/null +++ b/packages/theme/src/CSSVariables/applyToDOM.ts @@ -0,0 +1,48 @@ +import type { PaletteMode } from '@mui/material' +import { kebabCase } from 'lodash-unified' +import { LightColor, DarkColor } from './constants' +import tinyColor from 'tinycolor2' + +// Fragment are in the form of "1, 2, 3" +// which is used for rgba(var(--x), alpha) +function getRGBFragment(x: Record, key: string) { + const { r, g, b } = tinyColor(x[key]).toRgb() + return [r, g, b].join(', ') +} +export function CSSVariableInjectorCSS(scheme: PaletteMode) { + const ns: Record = scheme === 'light' ? LightColor : DarkColor + const result: Record = {} + for (const key in ns) { + // --mask-name: val; + result[`--mask-${kebabCase(key)}`] = ns[key] + result[`--mask-${kebabCase(key)}-fragment`] = getRGBFragment(ns, key) + } + return { ':root, :host': result } +} + +export function applyMaskColorVars(node: HTMLElement, scheme: PaletteMode) { + const ns: Record = scheme === 'light' ? LightColor : DarkColor + if (node === document.body) { + const id = '#mask-style-var' + if (!document.getElementById(id)) { + const style = document.createElement('style') + style.id = id + document.head.appendChild(style) + } + applyMaskColorVars(document.getElementById(id)!, scheme) + return + } else if (node instanceof HTMLStyleElement) { + let rule = ':root, :host {\n' + for (const key in ns) { + // --mask-name: val; + rule += ` --mask-${kebabCase(key)}: ${ns[key]};\n` + rule += ` --mask-${kebabCase(key)}-fragment: ${getRGBFragment(ns, key)};\n` + } + node.textContent = rule + '}' + } else { + for (const key in ns) { + node.style.setProperty('--mask-' + kebabCase(key), ns[key]) + node.style.setProperty('--mask-' + kebabCase(key) + '-fragment', getRGBFragment(ns, key)) + } + } +} diff --git a/packages/theme/src/constants.ts b/packages/theme/src/CSSVariables/constants.ts similarity index 56% rename from packages/theme/src/constants.ts rename to packages/theme/src/CSSVariables/constants.ts index 8d876c5645bc..8c6025ff1db5 100644 --- a/packages/theme/src/constants.ts +++ b/packages/theme/src/CSSVariables/constants.ts @@ -1,6 +1,3 @@ -import { PaletteMode, Theme, useTheme } from '@mui/material' -import { kebabCase } from 'lodash-unified' -import parseColor from 'tinycolor2' export const LightColor = { primary: '#1c68f3', primaryContrastText: '#ffffff', @@ -149,81 +146,4 @@ export const DarkColor: typeof LightColor = { warningBackground: 'rgba(255, 185, 21, 0.1)', cyberconnectPrimary: '#ffffff', } - export type Color = typeof LightColor - -export function getMaskColor(theme: Theme) { - if (theme.palette.mode === 'dark') return DarkColor - return LightColor -} -export function useMaskColor() { - return getMaskColor(useTheme()) -} - -export function CSSVariableInjectorCSS(scheme: PaletteMode) { - const ns: Record = scheme === 'light' ? LightColor : DarkColor - const result: Record = {} - for (const key in ns) { - // --mask-name: val; - result[`--mask-${kebabCase(key)}`] = ns[key] - result[`--mask-${kebabCase(key)}-fragment`] = getRGBFragment(ns, key) - } - return { ':root, :host': result } -} -export function applyMaskColorVars(node: HTMLElement, scheme: PaletteMode) { - const ns: Record = scheme === 'light' ? LightColor : DarkColor - if (node === document.body) { - const id = '#mask-style-var' - if (!document.getElementById(id)) { - const style = document.createElement('style') - style.id = id - document.head.appendChild(style) - } - applyMaskColorVars(document.getElementById(id)!, scheme) - return - } else if (node instanceof HTMLStyleElement) { - let rule = ':root, :host {\n' - for (const key in ns) { - // --mask-name: val; - rule += ` --mask-${kebabCase(key)}: ${ns[key]};\n` - rule += ` --mask-${kebabCase(key)}-fragment: ${getRGBFragment(ns, key)};\n` - } - node.textContent = rule + '}' - } else { - for (const key in ns) { - node.style.setProperty('--mask-' + kebabCase(key), ns[key]) - node.style.setProperty('--mask-' + kebabCase(key) + '-fragment', getRGBFragment(ns, key)) - } - } -} -// Fragment are in the form of "1, 2, 3" -// which is used for rgba(var(--x), alpha) -function getRGBFragment(x: Record, key: string) { - const { r, g, b } = parseColor(x[key]).toRgb() - return [r, g, b].join(', ') -} - -export type MaskCSSVariableColor = string & { - /** Append alpha channel to the original color */ - alpha(alpha: number): string -} & ((defaultValue?: string) => string) - -export const MaskColorVar: Record = new Proxy( - { __proto__: null } as any, - { - get(target, key) { - if (target[key]) return target[key] - if (typeof key !== 'string') throw new TypeError() - const cssVar = kebabCase(key) - target[key] = (defaultValue?: string) => { - // it might be an object when used in styled components. - if (typeof defaultValue !== 'string') defaultValue = undefined - const x = `var(--mask-${cssVar}${defaultValue ? ', ' + defaultValue : ''})` - return x - } - target[key][Symbol.toPrimitive] = () => `var(--mask-${cssVar})` - target[key].alpha = (alpha: number) => `rgba(var(--mask-${cssVar}-fragment), ${alpha})` - return target[key] - }, - }, -) diff --git a/packages/theme/src/CSSVariables/createVars.ts b/packages/theme/src/CSSVariables/createVars.ts new file mode 100644 index 000000000000..00f17e4be0aa --- /dev/null +++ b/packages/theme/src/CSSVariables/createVars.ts @@ -0,0 +1,16 @@ +/** @internal */ +export function css_var>( + unique_name: string, + keys: T, +): { [key in keyof T]: string & ((defaultValue?: string) => string) } { + for (const k in keys) keys[k] = createVar(k) as any + return keys as any + function createVar(name: string) { + const val = '--' + unique_name + '-' + name + function use(defaultValue?: string): string { + return `var(${val}${typeof defaultValue === 'undefined' ? '' : ', ' + defaultValue})` + } + use.toString = () => val + return use + } +} diff --git a/packages/theme/src/CSSVariables/index.ts b/packages/theme/src/CSSVariables/index.ts new file mode 100644 index 000000000000..e5ee367cdc7a --- /dev/null +++ b/packages/theme/src/CSSVariables/index.ts @@ -0,0 +1,4 @@ +export * from './applyToDOM' +export * from './Injector' +export * from './constants' +export * from './vars' diff --git a/packages/theme/src/CSSVariables/vars.ts b/packages/theme/src/CSSVariables/vars.ts new file mode 100644 index 000000000000..a2ea63692f7d --- /dev/null +++ b/packages/theme/src/CSSVariables/vars.ts @@ -0,0 +1,32 @@ +import type { Theme } from '@mui/material' +import { kebabCase } from 'lodash-unified' +import { LightColor, DarkColor } from './constants' + +export function getMaskColor(theme: Theme) { + if (theme.palette.mode === 'dark') return DarkColor + return LightColor +} +export type MaskCSSVariableColor = string & { + /** Append alpha channel to the original color */ + alpha(alpha: number): string +} & ((defaultValue?: string) => string) + +export const MaskColorVar: Record = new Proxy( + { __proto__: null } as any, + { + get(target, key) { + if (target[key]) return target[key] + if (typeof key !== 'string') throw new TypeError() + const cssVar = kebabCase(key) + target[key] = (defaultValue?: string) => { + // it might be an object when used in styled components. + if (typeof defaultValue !== 'string') defaultValue = undefined + const x = `var(--mask-${cssVar}${defaultValue ? ', ' + defaultValue : ''})` + return x + } + target[key][Symbol.toPrimitive] = () => `var(--mask-${cssVar})` + target[key].alpha = (alpha: number) => `rgba(var(--mask-${cssVar}-fragment), ${alpha})` + return target[key] + }, + }, +) diff --git a/packages/theme/src/Components/FolderTabs/index.tsx b/packages/theme/src/Components/FolderTabs/index.tsx index 103709a35c26..ccff3564622b 100644 --- a/packages/theme/src/Components/FolderTabs/index.tsx +++ b/packages/theme/src/Components/FolderTabs/index.tsx @@ -1,7 +1,7 @@ import { Children, FC, useState, HTMLProps, ReactElement } from 'react' import classnames from 'classnames' -import { makeStyles } from '../../makeStyles' -import { MaskColorVar } from '../../constants' +import { makeStyles } from '../../UIHelper/makeStyles' +import { MaskColorVar } from '../../CSSVariables' const useStyles = makeStyles()((theme, _, refs) => { const { palette } = theme diff --git a/packages/theme/src/Components/PhoneNumberField/index.tsx b/packages/theme/src/Components/PhoneNumberField/index.tsx index 0a8b9bf686df..3bb112be3f6e 100644 --- a/packages/theme/src/Components/PhoneNumberField/index.tsx +++ b/packages/theme/src/Components/PhoneNumberField/index.tsx @@ -1,5 +1,5 @@ import { Box, InputBaseProps } from '@mui/material' -import { makeStyles } from '../../makeStyles' +import { makeStyles } from '../../UIHelper/makeStyles' import { MaskTextField } from '../TextField' import { ChangeEvent, ReactNode, useState } from 'react' diff --git a/packages/theme/src/Components/SearchableList/SearchableList.tsx b/packages/theme/src/Components/SearchableList/SearchableList.tsx index 4bc8abaa134b..d7de747acee8 100644 --- a/packages/theme/src/Components/SearchableList/SearchableList.tsx +++ b/packages/theme/src/Components/SearchableList/SearchableList.tsx @@ -3,7 +3,7 @@ import { FixedSizeList, FixedSizeListProps } from 'react-window' import Fuse from 'fuse.js' import { uniqBy } from 'lodash-unified' import { Box, InputAdornment } from '@mui/material' -import { makeStyles } from '../../makeStyles' +import { makeStyles } from '../../UIHelper/makeStyles' import { MaskSearchableItemInList } from './MaskSearchableItemInList' import { MaskTextField, MaskTextFieldProps } from '../TextField' import { SearchIcon } from '@masknet/icons' diff --git a/packages/theme/src/Components/Snackbar/index.tsx b/packages/theme/src/Components/Snackbar/index.tsx index 3c584ca25992..f901a146d717 100644 --- a/packages/theme/src/Components/Snackbar/index.tsx +++ b/packages/theme/src/Components/Snackbar/index.tsx @@ -18,9 +18,9 @@ import WarningIcon from '@mui/icons-material/Warning' import InfoIcon from '@mui/icons-material/Info' import DoneIcon from '@mui/icons-material/Done' import { LoadingIcon, RiskIcon } from '@masknet/icons' -import { makeStyles } from '../../makeStyles' +import { makeStyles } from '../../UIHelper/makeStyles' import { useStylesExtends } from '../../UIHelper/custom-ui-helper' -import { MaskColorVar } from '../../constants' +import { MaskColorVar } from '../../CSSVariables' export { SnackbarProvider, useSnackbar } from 'notistack' export type { VariantType, OptionsObject, SnackbarKey, SnackbarMessage } from 'notistack' diff --git a/packages/theme/src/Components/TextField/index.tsx b/packages/theme/src/Components/TextField/index.tsx index c3dc10b5f592..045c0989932f 100644 --- a/packages/theme/src/Components/TextField/index.tsx +++ b/packages/theme/src/Components/TextField/index.tsx @@ -1,7 +1,7 @@ import { ForwardedRef, forwardRef } from 'react' import { Box, formHelperTextClasses, TextField, StandardTextFieldProps, InputProps, Typography } from '@mui/material' -import { makeStyles } from '../../makeStyles' -import { getMaskColor, MaskColorVar } from '../../constants' +import { makeStyles } from '../../UIHelper/makeStyles' +import { getMaskColor, MaskColorVar } from '../../CSSVariables/vars' const useStyles = makeStyles()((theme) => ({ label: { diff --git a/packages/theme/src/ShadowRoot/index.ts b/packages/theme/src/ShadowRoot/index.ts index 61a44ac90262..67be14f6fb91 100644 --- a/packages/theme/src/ShadowRoot/index.ts +++ b/packages/theme/src/ShadowRoot/index.ts @@ -10,6 +10,5 @@ export { createShadowRootForwardedComponent, createShadowRootForwardedPopperComponent, } from './Portal' -export { ShadowRootMenu, ShadowRootPopper, ShadowRootTooltip } from './Wrapped' export { ShadowRootIsolation } from './ShadowRootIsolation' export { DisableShadowRootContext } from './Contexts' diff --git a/packages/theme/src/ThemeProvider.tsx b/packages/theme/src/Theme/Provider.tsx similarity index 95% rename from packages/theme/src/ThemeProvider.tsx rename to packages/theme/src/Theme/Provider.tsx index ef7664dd5744..13a47ed2575a 100644 --- a/packages/theme/src/ThemeProvider.tsx +++ b/packages/theme/src/Theme/Provider.tsx @@ -1,6 +1,6 @@ import { CssBaseline, Theme, ThemeProvider } from '@mui/material' import { MaskIconPalette, MaskIconPaletteContext } from '@masknet/icons' -import { CustomSnackbarProvider } from './Components/Snackbar' +import { CustomSnackbarProvider } from '../Components/Snackbar' function compose(init: React.ReactNode, ...f: ((children: React.ReactNode) => JSX.Element)[]) { return f.reduceRight((prev, curr) => curr(prev), <>{init}) diff --git a/packages/theme/src/changes.ts b/packages/theme/src/Theme/changes.ts similarity index 100% rename from packages/theme/src/changes.ts rename to packages/theme/src/Theme/changes.ts diff --git a/packages/theme/src/component-changes.ts b/packages/theme/src/Theme/component-changes.ts similarity index 95% rename from packages/theme/src/component-changes.ts rename to packages/theme/src/Theme/component-changes.ts index 9e98120ba1c9..0d7f4bf33797 100644 --- a/packages/theme/src/component-changes.ts +++ b/packages/theme/src/Theme/component-changes.ts @@ -1,21 +1,7 @@ import type { PaletteMode, ThemeOptions } from '@mui/material' -import type { Color } from './constants' +import type { Color } from '../CSSVariables' +import { css_var } from '../CSSVariables/createVars' -function css_var>( - unique_name: string, - keys: T, -): { [key in keyof T]: string & ((defaultValue?: string) => string) } { - for (const k in keys) keys[k] = createVar(k) as any - return keys as any - function createVar(name: string) { - const val = '--' + unique_name + '-' + name - function use(defaultValue?: string): string { - return `var(${val}${typeof defaultValue === 'undefined' ? '' : ', ' + defaultValue})` - } - use.toString = () => val - return use - } -} type Theme = ThemeOptions | ((mode: PaletteMode, colors: Color) => ThemeOptions) export const BaseLine: Theme = (mode, colors): ThemeOptions => ({ diff --git a/packages/theme/src/Theme/index.ts b/packages/theme/src/Theme/index.ts new file mode 100644 index 000000000000..a1c2c81a2eb0 --- /dev/null +++ b/packages/theme/src/Theme/index.ts @@ -0,0 +1,3 @@ +export * from './types' +export { MaskThemeProvider } from './Provider' +export { MaskDarkTheme, MaskLightTheme } from './theme' diff --git a/packages/theme/src/Theme/theme.ts b/packages/theme/src/Theme/theme.ts new file mode 100644 index 000000000000..421cc05625d0 --- /dev/null +++ b/packages/theme/src/Theme/theme.ts @@ -0,0 +1,34 @@ +import { createTheme, PaletteMode, ThemeOptions } from '@mui/material' +import * as Changes from './changes' +import * as Components from './component-changes' +import { merge } from 'lodash-unified' +import type { PaletteOptions } from '@mui/material/styles/createPalette' +import { DarkColor, LightColor, Color } from '../CSSVariables' + +const color = (mode: PaletteMode, color: Color): PaletteOptions => ({ + mode, + primary: { main: color.primary, contrastText: color.primaryContrastText }, + secondary: { main: color.primary, contrastText: color.primaryContrastText }, // Yes, not a typo, it's primary + background: { paper: color.primaryBackground, default: color.secondaryBackground }, + error: { main: color.redMain, contrastText: color.redContrastText }, + success: { main: color.greenMain }, + warning: { main: color.orangeMain }, + divider: color.divider, + text: { primary: color.textPrimary, secondary: color.textSecondary }, +}) + +function MaskTheme(mode: PaletteMode) { + const colors = mode === 'dark' ? DarkColor : LightColor + const theme = merge( + { palette: color(mode, colors) } as ThemeOptions, + ...Object.values(Changes).map(applyColors), + ...Object.values(Components).map(applyColors), + ) + return createTheme(theme) + function applyColors(x: any) { + if (typeof x === 'function') return x(mode, colors) + return x + } +} +export const MaskLightTheme = MaskTheme('light') +export const MaskDarkTheme = MaskTheme('dark') diff --git a/packages/theme/src/Theme/types.ts b/packages/theme/src/Theme/types.ts new file mode 100644 index 000000000000..512c392f0ecf --- /dev/null +++ b/packages/theme/src/Theme/types.ts @@ -0,0 +1,5 @@ +export enum Appearance { + default = 'default', + light = 'light', + dark = 'dark', +} diff --git a/packages/theme/src/UIHelper/custom-ui-helper.tsx b/packages/theme/src/UIHelper/custom-ui-helper.tsx index dfdc4679ba79..a7b6b10555e7 100644 --- a/packages/theme/src/UIHelper/custom-ui-helper.tsx +++ b/packages/theme/src/UIHelper/custom-ui-helper.tsx @@ -1,5 +1,5 @@ /// -type ClassNameMap = { [P in ClassKey]: string } +export type ClassNameMap = { [P in ClassKey]: string } // Priority: classes from props > configHooks > defaultStyles export function useStylesExtends( defaultStyles: { classes?: ClassNameMap }, @@ -25,10 +25,3 @@ export function mergeClasses(...args: (Partial> | undefined } return result } - -/** - * In case of y is a react hooks call, we should always call the hooks. So we can't use x ?? y directly. - */ -export function or(x: T | undefined, y: T) { - return x ?? y -} diff --git a/packages/theme/src/UIHelper/index.ts b/packages/theme/src/UIHelper/index.ts new file mode 100644 index 000000000000..26dc45eee1cf --- /dev/null +++ b/packages/theme/src/UIHelper/index.ts @@ -0,0 +1,3 @@ +export * from './makeStyles' +export * from './custom-ui-helper' +export * from './useUserPrefersColorScheme' diff --git a/packages/theme/src/makeStyles.ts b/packages/theme/src/UIHelper/makeStyles.ts similarity index 65% rename from packages/theme/src/makeStyles.ts rename to packages/theme/src/UIHelper/makeStyles.ts index 96af1a8acbbc..a689dfae0801 100644 --- a/packages/theme/src/makeStyles.ts +++ b/packages/theme/src/UIHelper/makeStyles.ts @@ -1,5 +1,3 @@ import { createMakeStyles } from 'tss-react' import { useTheme } from '@mui/material' export const { makeStyles } = createMakeStyles({ useTheme }) -export type { Css, Cx } from 'tss-react' -export { keyframes } from 'tss-react' diff --git a/packages/theme/src/UIHelper/useUserPrefersColorScheme.ts b/packages/theme/src/UIHelper/useUserPrefersColorScheme.ts new file mode 100644 index 000000000000..114c0614e3c9 --- /dev/null +++ b/packages/theme/src/UIHelper/useUserPrefersColorScheme.ts @@ -0,0 +1,5 @@ +import { type PaletteMode, useMediaQuery } from '@mui/material' + +export function useSystemPreferencePalette(): PaletteMode { + return useMediaQuery('(prefers-color-scheme: dark)') ? 'dark' : 'light' +} diff --git a/packages/theme/src/customization/index.ts b/packages/theme/src/customization/index.ts deleted file mode 100644 index c9f6f047dc00..000000000000 --- a/packages/theme/src/customization/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './types' diff --git a/packages/theme/src/customization/types.ts b/packages/theme/src/customization/types.ts deleted file mode 100644 index 82b7ebeaf57e..000000000000 --- a/packages/theme/src/customization/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -type ClassNameMap = { [P in ClassKey]: string } - -export interface ComponentOverwriteConfig { - classes?: () => { classes: Partial> } - props?: (props: Props) => Props -} diff --git a/packages/theme/src/entry-base.ts b/packages/theme/src/entry-base.ts new file mode 100644 index 000000000000..ff8ceeeae059 --- /dev/null +++ b/packages/theme/src/entry-base.ts @@ -0,0 +1,12 @@ +/// + +// Some re-exports +import tinyColor from 'tinycolor2' +export const parseColor = tinyColor +export { keyframes, type Css, type Cx, TssCacheProvider } from 'tss-react' + +// +export * from './UIHelper' +export * from './CSSVariables' +export * from './Theme' +export * from './ShadowRoot' diff --git a/packages/theme/src/ShadowRoot/Wrapped.tsx b/packages/theme/src/entry.ts similarity index 70% rename from packages/theme/src/ShadowRoot/Wrapped.tsx rename to packages/theme/src/entry.ts index ddc4e9d75ad9..c44953a76c39 100644 --- a/packages/theme/src/ShadowRoot/Wrapped.tsx +++ b/packages/theme/src/entry.ts @@ -1,6 +1,11 @@ +/// import { Menu, Popper, Tooltip } from '@mui/material' -import { createShadowRootForwardedComponent, createShadowRootForwardedPopperComponent } from './Portal' +import { createShadowRootForwardedComponent, createShadowRootForwardedPopperComponent } from './ShadowRoot/Portal' export const ShadowRootTooltip: typeof Tooltip = createShadowRootForwardedPopperComponent(Tooltip) as any export const ShadowRootMenu: typeof Menu = createShadowRootForwardedComponent(Menu) as any export const ShadowRootPopper: typeof Popper = createShadowRootForwardedComponent(Popper) as any + +export * from './entry-base' +export * from './Components' +export * from './hooks' diff --git a/packages/theme/src/index.ts b/packages/theme/src/index.ts index 2764905d6304..c89fee5242ba 100644 --- a/packages/theme/src/index.ts +++ b/packages/theme/src/index.ts @@ -1,65 +1 @@ -/// -// see https://github.com/import-js/eslint-plugin-import/issues/2288 -import { createTheme, PaletteMode, ThemeOptions, useMediaQuery } from '@mui/material' -import * as Changes from './changes' -import * as Components from './component-changes' -import { merge } from 'lodash-unified' -import type { PaletteOptions } from '@mui/material/styles/createPalette' -import { DarkColor, LightColor, Color } from './constants' -import tinyColor from 'tinycolor2' - -export const parseColor = tinyColor - -const color = (mode: PaletteMode, color: Color): PaletteOptions => ({ - mode, - primary: { main: color.primary, contrastText: color.primaryContrastText }, - secondary: { main: color.primary, contrastText: color.primaryContrastText }, // Yes, not a typo, it's primary - background: { paper: color.primaryBackground, default: color.secondaryBackground }, - error: { main: color.redMain, contrastText: color.redContrastText }, - success: { main: color.greenMain }, - warning: { main: color.orangeMain }, - divider: color.divider, - text: { primary: color.textPrimary, secondary: color.textSecondary }, -}) - -function MaskTheme(mode: PaletteMode) { - const colors = mode === 'dark' ? DarkColor : LightColor - const theme = merge( - { palette: color(mode, colors) } as ThemeOptions, - ...Object.values(Changes).map(applyColors), - ...Object.values(Components).map(applyColors), - ) - return createTheme(theme) - function applyColors(x: any) { - if (typeof x === 'function') return x(mode, colors) - return x - } -} -export const MaskLightTheme = MaskTheme('light') -export const MaskDarkTheme = MaskTheme('dark') -export * from './ThemeProvider' -export * from './makeStyles' -export * from './Components' -export * from './hooks' -export * from './customization' -export * from './ShadowRoot' -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 { - // see https://github.com/import-js/eslint-plugin-import/issues/2288 - return useMediaQuery(query) ? 'dark' : 'light' -} -export function currentSystemPreferencePalette(): PaletteMode { - return matchMedia(query).matches ? 'dark' : 'light' -} - -export enum Appearance { - default = 'default', - light = 'light', - dark = 'dark', -} +export * from './entry'