設定値を深堀りしていく
{ cssVariables: { colorSchemeSelector: 'data-mui-color-scheme', cssVarPrefix: 'template', }, colorSchemes, typography, shadows, shape, components: { ...inputsCustomizations, ...dataDisplayCustomizations, ...feedbackCustomizations, ...navigationCustomizations, ...surfacesCustomizations, ...themeComponents, }, }
cssVariables
cssVariables
は、見ての通り、2つのパラメータが設定されています。shared-theme/AppTheme.tsx#L30-L33
{ cssVariables: { colorSchemeSelector: 'data-mui-color-scheme', cssVarPrefix: 'template', } }
実際に設定してみます
createTheme({ + cssVariables: {+ cssVarPrefix: 'zako',+ }, })
cssVarPrefix
は CSS Variable を生成してくれる際の Prefix になる値のようです。(デフォルト:--mui
)colorSchemeSelector
は Dark Mode を手動で切り替える際に役立つようです。
colorSchemeSelector を colorSchemes と一緒に使ってみる
createTheme({ cssVariables: { + colorSchemeSelector: 'class', cssVarPrefix: 'zako', }, + colorSchemes: { light: true, dark: true }, })
テンプレートの colorSchemes
に比べて簡易的な設定ですが、こうすると Light Mode と Dark Mode が切り替えられるようです。colorSchemes
の設定については後述で試しますので、ここでは boolean 値を指定して終わりです。
cssVariables の型定義
cssVariables?: boolean | Pick<CssVarsThemeOptions, 'colorSchemeSelector' | 'rootSelector' | 'disableCssColorScheme' | 'cssVarPrefix' | 'shouldSkipGeneratingVar'>;
このようになっているようです。
boolean | object |
---|---|
true | false | { "CssVarsThemeOptions": ?, "colorSchemeSelector": ?, "rootSelector": ?, "disableCssColorScheme": ?, "cssVarPrefix": ?, "shouldSkipGeneratingVar": ? } |
colorSchemes
colorSchemes
は非常にたくさんの設定がされています。shared-theme/themePrimitives.ts#L241-L341
テンプレートテーマの colorSchems の設定 (長いので折りたたみ)
export const colorSchemes = { light: { palette: { primary: { light: brand[200], main: brand[400], dark: brand[700], contrastText: brand[50], }, info: { light: brand[100], main: brand[300], dark: brand[600], contrastText: gray[50], }, warning: { light: orange[300], main: orange[400], dark: orange[800], }, error: { light: red[300], main: red[400], dark: red[800], }, success: { light: green[300], main: green[400], dark: green[800], }, grey: { ...gray, }, divider: alpha(gray[300], 0.4), background: { default: 'hsl(0, 0%, 99%)', paper: 'hsl(220, 35%, 97%)', }, text: { primary: gray[800], secondary: gray[600], warning: orange[400], }, action: { hover: alpha(gray[200], 0.2), selected: `${alpha(gray[200], 0.3)}`, }, baseShadow: 'hsla(220, 30%, 5%, 0.07) 0px 4px 16px 0px, hsla(220, 25%, 10%, 0.07) 0px 8px 16px -5px', }, }, dark: { palette: { primary: { contrastText: brand[50], light: brand[300], main: brand[400], dark: brand[700], }, info: { contrastText: brand[300], light: brand[500], main: brand[700], dark: brand[900], }, warning: { light: orange[400], main: orange[500], dark: orange[700], }, error: { light: red[400], main: red[500], dark: red[700], }, success: { light: green[400], main: green[500], dark: green[700], }, grey: { ...gray, }, divider: alpha(gray[700], 0.6), background: { default: gray[900], paper: 'hsl(220, 30%, 7%)', }, text: { primary: 'hsl(0, 0%, 100%)', secondary: gray[400], }, action: { hover: alpha(gray[600], 0.2), selected: alpha(gray[600], 0.3), }, baseShadow: 'hsla(220, 30%, 5%, 0.7) 0px 4px 16px 0px, hsla(220, 25%, 10%, 0.8) 0px 8px 16px -5px', }, }, };
具体的な型定義
colorSchemes?: Partial<Record<DefaultColorScheme, boolean | ColorSystemOptions>> & (ExtendedColorScheme extends string ? Record<ExtendedColorScheme, ColorSystemOptions> : {});
type DefaultColorScheme = 'light' | 'dark'; interface ColorSystemOptions { palette?: PaletteOptions & { background?: Partial<PaletteBackgroundChannel>; common?: Partial<PaletteCommonChannel>; primary?: Partial<PaletteColorChannel>; secondary?: Partial<PaletteColorChannel>; error?: Partial<PaletteColorChannel>; info?: Partial<PaletteColorChannel>; success?: Partial<PaletteColorChannel>; text?: Partial<PaletteTextChannel>; dividerChannel?: Partial<string>; action?: Partial<PaletteActionChannel>; Alert?: Partial<PaletteAlert>; AppBar?: Partial<PaletteAppBar>; Avatar?: Partial<PaletteAvatar>; Button?: Partial<PaletteButton>; Chip?: Partial<PaletteChip>; FilledInput?: Partial<PaletteFilledInput>; LinearProgress?: Partial<PaletteLinearProgress>; Skeleton?: Partial<PaletteSkeleton>; Slider?: Partial<PaletteSlider>; SnackbarContent?: Partial<PaletteSnackbarContent>; SpeedDialAction?: Partial<PaletteSpeedDialAction>; StepConnector?: Partial<PaletteStepConnector>; StepContent?: Partial<PaletteStepContent>; Switch?: Partial<PaletteSwitch>; TableCell?: Partial<PaletteTableCell>; Tooltip?: Partial<PaletteTooltip>; }; opacity?: Partial<Opacity>; overlays?: Overlays; }
という定義のようなので、噛み砕くとだいたい以下のような感じみたいですね。
{ "light"?: boolean | ColorSystemOptions, "dark"?: boolean | ColorSystemOptions, }
とりあえず設定して使ってみる
未設定なものはデフォルト値が使われるようになっているようです。
background.default | background.paper | |
---|---|---|
light | ほぼ白 | 明るい赤 |
dark | ほぼ黒 | 暗い赤 |
const theme = createTheme({ cssVariables: { colorSchemeSelector: 'class', cssVarPrefix: 'zako', }, colorSchemes: { + light: {+ palette: {+ background: {+ default: '#eee',+ paper: '#fdd',+ },+ },+ },+ dark: {+ palette: {+ background: {+ default: '#111',+ paper: '#322',+ },+ },+ }, }, })
typography
shared-theme/themePrimitives.ts#L343-L391
テンプレートテーマの typography の設定 (長いので折りたたみ)
export const typography = { fontFamily: ['"Inter", "sans-serif"'].join(','), h1: { fontSize: defaultTheme.typography.pxToRem(48), fontWeight: 600, lineHeight: 1.2, letterSpacing: -0.5, }, h2: { fontSize: defaultTheme.typography.pxToRem(36), fontWeight: 600, lineHeight: 1.2, }, h3: { fontSize: defaultTheme.typography.pxToRem(30), lineHeight: 1.2, }, h4: { fontSize: defaultTheme.typography.pxToRem(24), fontWeight: 600, lineHeight: 1.5, }, h5: { fontSize: defaultTheme.typography.pxToRem(20), fontWeight: 600, }, h6: { fontSize: defaultTheme.typography.pxToRem(18), fontWeight: 600, }, subtitle1: { fontSize: defaultTheme.typography.pxToRem(18), }, subtitle2: { fontSize: defaultTheme.typography.pxToRem(14), fontWeight: 500, }, body1: { fontSize: defaultTheme.typography.pxToRem(14), }, body2: { fontSize: defaultTheme.typography.pxToRem(14), fontWeight: 400, }, caption: { fontSize: defaultTheme.typography.pxToRem(12), fontWeight: 400, }, };
具体的な型定義
export interface TypographyOptions extends Partial<Record<Variant, TypographyStyleOptions> & FontStyleOptions> {}
colorSchemes よりは複雑ではないですね。追ってみると以下のようになっているみたいですね。
export type Variant = | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'subtitle1' | 'subtitle2' | 'body1' | 'body2' | 'caption' | 'button' | 'overline'; export type TypographyStyle = CSSProperties; export interface TypographyStyleOptions extends TypographyStyle {}
つまり Partial<Record<Variant, TypographyStyleOptions>>
は以下のようになるはずです
{ 'h1'?: CSSProperties, 'h2'?: CSSProperties, 'h3'?: CSSProperties, 'h4'?: CSSProperties, 'h5'?: CSSProperties, 'h6'?: CSSProperties, 'subtitle1'?: CSSProperties, 'subtitle2'?: CSSProperties, 'body1'?: CSSProperties, 'body2'?: CSSProperties, 'caption'?: CSSProperties, 'button'?: CSSProperties, 'overline'?: CSSProperties, }
更に font-family
の設定ができるはずです
shadows
shared-theme/themePrimitives.ts#L398-L399
const defaultShadows: Shadows = ['var(--mui-palette-baseShadow)', ...defaultTheme.shadows.slice(1)]; export const shadows = defaultShadows;
具体的な型定義
export type Shadows = [ 'none', string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, ];
shape
shared-theme/themePrimitives.ts#L393-L395
export const shape = { borderRadius: 8, };
具体的な型定義
export interface Shape { borderRadius: number; }
前回の記事で、細かい違いとして 角丸の強さが異なるなぁという感想がありましたが、原因はここですね。
components
Material UI の Component に対して、共通の定義を行える場所です。
例えば、上記で「ほぼ黒」と「暗い赤」を設定しましたが、テーブルの部分だけ「暗い赤」になっていません。
今回は、そこを「暗い赤」にすることを目標に、components の設定をしてみます。
実際に設定してみる
export const CustomTheme: React.FC<CustomThemeProps> = ({ children }) => { const theme = createTheme({ cssVariables: { colorSchemeSelector: 'class', cssVarPrefix: 'zako', }, colorSchemes: { light: { palette: { background: { default: '#eee', paper: '#fdd', }, }, }, dark: { palette: { background: { default: '#111', paper: '#322', }, }, }, }, + components: {+ MuiDataGrid: {+ styleOverrides: {+ root: ({ theme }) => ({+ backgroundColor: theme.palette.background.paper,+ [`& .${gridClasses.columnHeader}`]: {+ backgroundColor: theme.palette.background.paper,+ },+ }),+ },+ },+ }, })