🙌

[Typescript]Material UIテーマのパレットで任意のキーワードを追加する

2020/10/14に公開

Material UIのpaletteを拡張する

Material UIではcreateMuiThemeでpaletteが作成できます。
便利ではあるのですが、デフォルト設定以外のキーワードでも色指定したい場面は多いかと思います。
Material UIのテーマカラーを拡張してデフォルトのprimary|secondary|error|warning|info|success以外のキーワードをパレットオプションに追加する方法、ついでにグラデーションも扱うときのちょっとしたテクもお伝えします。

拡張用のd.tsファイルの追加

デフォルト以外のワードで登録するとエラーが出るので、PaletteOptionsを拡張します。

PaletteOptionsを拡張する

src/types/createPalette.d.ts

import * as createPalette from '@material-ui/core/styles/createPalette';
declare module '@material-ui/core/styles/createPalette' {
    interface PaletteOptions {    
        customColor1?: PaletteColorOptions;
        customColor2?: PaletteColorOptions;
    }
    interface Palette {    
        customColor1: PaletteColor;
        customColor2: PaletteColor;
    }
}

PaletteOptionsを追加するだけならこれだけでOKです。

src/components/theme.ts

const theme = createMuiTheme({
  palette: {
    primary: {
      main: '#556cd6',
    },
    secondary: {
      main: '#19857b',
    },
    success: {
      main: '#69A06F',
    },
    error: {
      main: red.A400,
    },
    customColor1:{
      main: '#69cc6F',
    },
    customColor2:{
      main: '#356cd6',
    }
  },
})

オリジナルのPaletteColorを追加してPaletteColorOptionsを拡張する

追加したパレットオプションでデフォルトのPaletteColorOptionsを利用するのであれば上記で終了です。しかし例えばmainlightでなくここも任意のワードを使いたいのであればさらに追加が必要です。

import * as createPalette from '@material-ui/core/styles/createPalette';
declare module '@material-ui/core/styles/createPalette' {
    interface PaletteOptions {    
      customColor1?: PaletteColorOptions;
      customColor2?: PaletteColorOptions;
      primaryGradation?: GradationPaletteColorOptions
    }
    interface Palette {    
      customColor1: PaletteColor;
      customColor2: PaletteColor;
    }
    interface GradationPaletteColorOptions {
      toRight?: string
      toBottom?: string
      toRightBottom?: string
    }
    interface GradationPaletteColor {
      toRight: string
      toBottom: string
      toRightBottom?: string
    }
  }

こうすればパレットオプション内に任意のワードを追加することができます

const theme = createMuiTheme({
 palette: {
   primary: {
     main: '#556cd6',
   },
   secondary: {
     main: '#19857b',
   },
   success: {
     main: '#69A06F',
   },
   error: {
     main: red.A400,
   },
   customColor1:{
     main: '#69cc6F',
   },
   customColor2:{
     main: '#356cd6',
   },
   primaryGradation: {
     toRight: 'linear-gradient(90deg, #FF0000, #FFBA00)',
     toBottom: 'linear-gradient(180deg, #FF0000, #FFBA00)',
     toRightBottom: 'linear-gradient(135deg, #FF0000, #FFBA00)',
   },
 },
})

[おまけ]透過なグラデーションを扱う時

上記のようにlinear-gradient(90deg, #FF0000, #FFBA00)を登録しておけば、UI側でtheme.pallete.primaryGradation.toRightという具合に使うことができます。Hex(#xxxxx) だと透過は使えないのでRGB(rgba(xxx,xxx,xxx,0.7) という具合に登録しておくと透過も可能です。

const theme = createMuiTheme({
 palette: {
   primary: {
     main: '#556cd6',
   },
   //省略
   primaryGradation: {
     toRight: 'linear-gradient(90deg, rgba(255,0,0,0.7), rgba(255,186,0,0.7))',//opacity:0.7で透過!!
     toBottom: 'linear-gradient(180deg, #FF0000, #FFBA00)',
     toRightBottom: 'linear-gradient(135deg, #FF0000, #FFBA00)',
   },
 },
})
const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    root: {
      background: theme.palette.primaryGradation.toRight,
    },
  })
)

ただ透過度が固定でなくcss側で数値を入れたいときもあります。

色だけパレットから拾ってきたい場合はパレットの色登録をRGBにしておくとグラデーションの時の使い勝手は上がります。

const theme = createMuiTheme({
 palette: {
   primary: {
     main: '#556cd6',
   },
   //省略
   primaryGradation: {
     red: '255,0,0',//RGBで設定
     orange: '255,186,0',//RGBで設定
     toRight: 'linear-gradient(90deg, rgba(255,0,0,0.7), rgba(255,186,0,0.7))',
     toBottom: 'linear-gradient(180deg, #FF0000, #FFBA00)',
     toRightBottom: 'linear-gradient(135deg, #FF0000, #FFBA00)',
   },
 },
})
const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    root: {
      background:
        'linear-gradient(0deg, rgba(' + theme.palette.primaryGradation.red + ',0.7), rgba(' + theme.palette.primaryGradation.orange + ',0.7))',
    },
  })
)

こちらからは以上です!なにか参考になれば幸いです!!


参考

Discussion