mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.89k stars 32.26k forks source link

Theme overrides : width does not exist on type CSSProperties #21650

Open RobelTekle opened 4 years ago

RobelTekle commented 4 years ago

Using createMuiTheme I override the MuiCard, setting a custom width and height, in this way.

const theme = createMuiTheme({
  palette: {
    type: 'light',
    primary: {
      main: primaryColor,
    },
    secondary: {
      main: secondaryColor,
    },
    fallback: {
      main: fallback,
    },
    fog: {
      main: fog,
    },
  },
  overrides: {
    MuiCard: {
      root: {
        width: 300,
        height: 276,
        margin: 15,
        [breakpoints.down('sm')]: {
          margin: 5,
        },
      },
    },
  },
  props: {
    MuiSkeleton: {
      animation: 'pulse',
    },
    MuiAvatar: {
      variant: 'rounded',
    },
  },
})

The component take the good dimensions. The problem comes when I try to access these values in the style of other components.

export const useStyle = makeStyles((theme: Theme) =>
  createStyles({
    cardSkeleton: {
      width: theme.overrides?.MuiCard?.root?.width ?? 300,
      height: theme.overrides?.MuiCard?.root?.height ?? 276,
      margin: 15,
      [theme.breakpoints.down('sm')]: {
        margin: 5,
      },
    },
  }),
)

I have this error for width and height : Property 'width' does not exist on type 'CSSProperties | CreateCSSProperties<{}> | PropsFunc<{}, CreateCSSProperties<{}>>'. Property 'width' does not exist on type 'PropsFunc<{}, CreateCSSProperties<{}>>'.

Your Environment 🌎

Tech Version
Material-UI v4.10.2
React 16.11.0
Browser Chrome
TypeScript 3.8.3
oliviertassinari commented 4 years ago

I believe we cover this in https://material-ui.com/guides/typescript/#customization-of-theme, you need to tell TypeScript the theme has changed.

RobelTekle commented 4 years ago

Hi @oliviertassinari thanks for your answer. Following you recommendation I modified the theme type. I'm using cra, so all declaration are in the react-app-env.d.ts file. This is my theme type declaration, but I still have the error message from typescript.

// / <reference types="react-scripts" />
import { Palette } from '@material-ui/core/styles/createPalette'
import { Theme } from '@material-ui/core/styles/createMuiTheme'
import React from 'react'

declare module '@material-ui/core/styles/createPalette' {
  interface Palette {
    fallback: Palette['primary']
    fog: Palette['primary']
  }
  interface PaletteOptions {
    fallback: PaletteOptions['primary']
    fog: PaletteOptions['primary']
  }
}

declare module '@material-ui/core/styles/createMuiTheme' {
  interface Theme {
    overrides: {
      MuiCard: {
        root: {
          width: React.CSSProperties['width']
          height: React.CSSProperties['height']
          margin: React.CSSProperties['margin']
        }
      }
    }
  }

  interface ThemeOptions {
    overrides: {
      MuiCard: {
        root: {
          width: React.CSSProperties['width']
          height: React.CSSProperties['height']
          margin: React.CSSProperties['margin']
        }
      }
    }
  }
}
eps1lon commented 4 years ago

@RobelTekle Could you share a complete repro? This would help a lot identifying the issue.

RobelTekle commented 4 years ago

Hi @eps1lon, the project is in a private repo. I tried to create an example in codesandbox https://codesandbox.io/s/serverless-monad-xfup0?file=/src/index.tsx But in codesandbox the module augmentation does not work at all.

ukris commented 4 years ago

Same here. Typescript material UI with custom theme worked in 4.9.11. Broke after upgrading. The issue is that theme's custom properties are empty - even if the type is defined. The issue also persists in "5.0.0-alpha.1"

RobelTekle commented 4 years ago

Tried to downgrade to 4.9.10 I still have the error

ukris commented 4 years ago

I've created a Github repo based on your code sandbox. https://github.com/ukris/material-ui-theme-overrides

master corresponds to material-UI - 4.9.11 and branches 4.11.0 and 5.0.0.alpha2 respectively.

for some reason in your case, all version works with the changes

There is one caveat: // @ts-ignore const root:CSSProperties = theme.overrides?.MuiCard?.root

if // @ts-ignore is unacceptable, then I guess u can do a conditional check, and return two different objects. or have theme: any as some solutions seemed to allude - which I think is not an acceptable solution. Below is conditional check without @ts-ignore


 const rt = theme.overrides?.MuiCard?.root
  if (!rt) {
    return createStyles({
      constainer: {
        position: 'relative',
        backgroundColor: theme.palette.fog.main,
      },
    })
  }
  const root =  rt as CSSProperties
  return createStyles({
    constainer: {
      position: 'relative',
      width: root?.width,
      height: root?.height, 
      margin : root?.margin,
      backgroundColor: theme.palette.fog.main,
    },
  })```