cssinjs / theming

Unified CSSinJS theming solution for React
300 stars 39 forks source link

Unable to pass properties to component extending ThemeProviderProps #71

Closed janhartmann closed 5 years ago

janhartmann commented 5 years ago

I have a component like so:

import * as React from "react";
import { withTheme, ThemeProviderProps } from "theming";
import injectSheet, { StyledComponentProps, StyleCreator } from "react-jss";

import { ITheme } from "../../whitelabel/theme";

export interface ILogoProps
  extends StyledComponentProps,
    ThemeProviderProps<ITheme> {
  condensed?: boolean;
}

const Logo: React.SFC<ILogoProps> = ({ classes, condensed = true, theme }) => {
  const logo = condensed
    ? theme.branding.logo.sidebar.condensed
    : theme.branding.logo.sidebar.original;
  return <img src={logo} className={classes.root} />;
};

const styles: StyleCreator = (theme: ITheme) => ({
  root: {
    display: "block",
    height: 40
  }
});

export default injectSheet(styles)(withTheme(Logo));

When I use this component from another component, e.g.:

import * as React from "react";
import Logo from "./logo";

export default class Sidebar extends React.Component  {
  public render() {
    const { expanded } = this.state;
    return <Logo condensed={!expanded} />
  }
}

I get a TypeScript error saying:

[ts] Property 'condensed' does not exist on type 'IntrinsicAttributes & Pick<(Pick<{ theme: object; }, "theme"> & { theme?: object; innerRef?: (ref: StatelessComponent) => void; }) | (Pick<{ theme: object; }, "theme"> & { ...; } & { ...; }), never> & StyledComponentProps<...> & { ...; }'. [2339]

If I switch the withTheme(...) to wrap like export default withTheme(injectSheet(styles)(Logo)); the same error arrives on that line.

Am I doing something wrong?

HenriBeck commented 5 years ago

Why are you extending the your component props with ThemeProviderProps when it's using withTheme?

It could also be a problem of your react-jss typings.

janhartmann commented 5 years ago

Maybe I am misusing this.

I need to access my theme inside the component and in order to get typings, I need to make my component be aware of the Theme?

Do you recommend doing this instead:

export interface ILogoProps extends StyledComponentProps {
  condensed?: boolean;
  theme?: ITheme;
}
janhartmann commented 5 years ago

I am also using the @types/react-jss if that helps? :)

HenriBeck commented 5 years ago

Yes, though the theme doesn't need to be optional.

If you remove the injectSheet call and the StyledComponentProps, does the component then work properly?

janhartmann commented 5 years ago

I must have misused this libary, by not using imports from theming directly, and only rely on importing from react-jss all issues are going away.