Material-ui: WithStyles peut-il transmettre des accessoires à l'objet styles ?

Créé le 17 oct. 2017  ·  54Commentaires  ·  Source: mui-org/material-ui

Actuellement, je développe un composant qui nécessite à la fois des objets props et des objets thèmes.

Au début, cela fonctionne très bien avec l'objet thème

const styles = theme => ({
  title: {
    ...theme.typography.headline,
    textAlign: 'center',
    padding: '8px 16px',
    margin: 0,
    color: theme.palette.common.white,
    backgroundColor: theme.palette.primary[500],
  },

withStyles(styles, { withTheme: true })(Component);
....

Mais j'ai aussi besoin d'accéder aux accessoires dans l'objet styles.

J'ai essayé l'exemple mais cela ne fonctionne pas.

{
 ....
display: (props) => props.display
}

Je finis par combiner react-jss et withTheme pour faire ça

import { withTheme } from 'material-ui/styles';
import injectSheet from 'react-jss';

function withStyles(styles, Component) {
  return withTheme()(injectSheet(styles)(Component));
}

export default withStyles;

....

const styles = {
  title: {
    display: (props) => props.display,
    textAlign: 'center',
    padding: '8px 16px',
    margin: 0,
    color: ({ theme }) => theme.palette.common.white,
    backgroundColor: ({ theme }) => theme.palette.primary[500],
  },

ça marche mais ça me manque vraiment

  title: {
    ...theme.typography.headline,
duplicate

Commentaire le plus utile

@oliviertassinari C'est très rassurant d'entendre que vous envisagerez de donner la priorité à cela ! Cela rendrait beaucoup plus facile la personnalisation des composants. Par exemple, j'aimerais avoir une case à cocher avec une taille configurable (c'est-à-dire largeur et hauteur en pixels) :

<CustomCheckbox size={16} />

Si nous pouvions accéder à props dans styles , ce serait très simple :

const styles = {
  root: {
    width: props => props.size,
    height: props => props.size
  }
}

ou

const styles = props => ({
  root: {
    width: props.size,
    height: props.size
  }
})

puis:

const CustomCheckbox = ({size, classes}) => <Checkbox className={classes.root} />;

export default withStyles(styles)(CustomCheckbox);

Pour l'instant, avez-vous des recommandations sur la façon dont nous devrions aborder ces types de cas d'utilisation ? Ou avez-vous une estimation du moment où vous pourriez ajouter la prise en charge de l'accès aux accessoires lors de l'utilisation de withStyles ?

Tous les 54 commentaires

Nous devrions probablement être en mesure de résoudre le problème en créant Material-UI en utilisant la même clé de contexte que react-jss : https://github.com/cssinjs/theming/blob/master/src/channel.js#L1.
Aussi, jetez un oeil à #7633

J'ai un PR prêt avec un exemple d'interopérabilité react-jss. Je vais l'ajouter dans la doc. cc @kof

@oliviertassinari est-ce que la résolution de cela signifie qu'il devrait être possible maintenant d'accéder aux accessoires dans la définition des styles ? Ce n'est pas clair pour moi comment...

@pelotom non, withStyles n'a pas accès aux propriétés. Mais étant donné combien les gens demandent cette fonctionnalité. C'est quelque chose que je peux prioriser, après les corrections de bugs. Vous pouvez utiliser le HOC injectSheet, mais cela ouvre la porte à plusieurs problèmes : fuite de mémoire, rechargement à chaud interrompu, pas classes composition

@oliviertassinari C'est très rassurant d'entendre que vous envisagerez de donner la priorité à cela ! Cela rendrait beaucoup plus facile la personnalisation des composants. Par exemple, j'aimerais avoir une case à cocher avec une taille configurable (c'est-à-dire largeur et hauteur en pixels) :

<CustomCheckbox size={16} />

Si nous pouvions accéder à props dans styles , ce serait très simple :

const styles = {
  root: {
    width: props => props.size,
    height: props => props.size
  }
}

ou

const styles = props => ({
  root: {
    width: props.size,
    height: props.size
  }
})

puis:

const CustomCheckbox = ({size, classes}) => <Checkbox className={classes.root} />;

export default withStyles(styles)(CustomCheckbox);

Pour l'instant, avez-vous des recommandations sur la façon dont nous devrions aborder ces types de cas d'utilisation ? Ou avez-vous une estimation du moment où vous pourriez ajouter la prise en charge de l'accès aux accessoires lors de l'utilisation de withStyles ?

@nmchaves Votre cas d'utilisation semble parfaitement correspondre à l'approche de style en ligne, vous pouvez en trouver un peu dans la documentation. FAQ
https://github.com/callemall/material-ui/blob/75a30061e76eae93c711ec202a2c7e4238a4f19a/docs/src/pages/style/SvgIcons.js#L38 -L44

Merci @oliviertassinari ! J'espérais pouvoir accomplir cela en utilisant withStyles , mais les styles en ligne fonctionneront très bien. Et le fait que vous le recommandiez ici + dans la doc me rend très confiant dans cette décision. Merci encore!

ce serait bien de pouvoir passer un accessoire (image src) au style pour un backgroundImage

J'envelopperais withStyle

const withStylesProps = styles =>
  Component =>
    props => {
      console.log(props);
      const Comp = withStyles(styles(props))(Component);
      // return <div>lol</div>;
      return <Comp {...props} />;
    };

const styles = props => ({
  foo: {
    height: `${props.y || 50}px`,
  }
});

export default withStylesProps(styles)(
  props => (
    <div className={props.classes.foo} style={{ ...props.style, background: 'yellow' }}>
      <h1>Hello!</h1>
    </div>
  )
);

démo : https://codesandbox.io/s/k2y01rj3w7

(Je suis surpris ^ fonctionne sans aucune configuration de ThemeProvider et JssProvider https://codesandbox.io/s/q6v7krx6, ah ça l'initialise)

@caub Cela fonctionne, mais vous devez être prudent avec ce modèle. Le CSS injecté augmentera avec le nombre d'instances du composant. C'est un doublon du #7633. Je n'ai pas creusé le sujet. Mais je crois que la version

@caub Merci pour le partage !

@oliviertassinari il y a ce https://github.com/cssinjs/react-jss/blob/master/readme.md#dynamic -values ​​dans react-jss, je me demande pourquoi il ne pourrait pas être utilisé dans material-ui ? De plus, je comprends votre point où vous dites que l'accessoire en ligne style est parfait pour les valeurs dynamiques, mais il est plus agréable d'avoir toutes les définitions de styles aux mêmes endroits. Il y a aussi https://github.com/airbnb/react-with-styles qui gérerait className et style pour des styles dynamiques plus efficaces

Je rencontre le même problème est ce que quelqu'un peut m'aider
`importer React depuis 'react';
importer les PropTypes de 'prop-types' ;
import { withStyles } de 'material-ui/styles';
importer le tiroir de 'material-ui/Drawer' ;
importer AppBar depuis 'material-ui/AppBar' ;
importer la barre d'outils de 'material-ui/Toolbar' ;
importer la liste de 'material-ui/List' ;
importer la typographie à partir de « material-ui/Typography » ;
importer IconButton de 'material-ui/IconButton';
importer Caché depuis 'material-ui/Hidden';
importer le diviseur de 'material-ui/Divider' ;
importer MenuIcon de 'material-ui-icons/Menu' ;
import { mailFolderListItems, otherMailFolderListItems } depuis './tileData' ;

const tiroirLargeur = 240 ;

const styles = thème => ({
racine: {
largeur : '100%',
hauteur : 430,
marginTop: theme.spacing.unit * 3,
zIndex : 1,
débordement caché',
},
appFrame : {
position : « parent »,
afficher : 'flex',
largeur : '100%',
hauteur : '100%',
},
appBar : {
position : 'absolue',
margeGauche : largeur du tiroir,
[theme.breakpoints.up('md')] : {
largeur : calc(100% - ${drawerWidth}px) ,
},
},
navIconHide : {
[theme.breakpoints.up('md')] : {
afficher : 'aucun',
},
},
En-tête de tiroir : theme.mixins.toolbar,
tiroirPapier : {
largeur : 250,
[theme.breakpoints.up('md')] : {
largeur: tiroirLargeur,
position : « parent »,
hauteur : '100%',
},
},
teneur: {
backgroundColor: theme.palette.background.default,
largeur : '100%',
remplissage : theme.spacing.unit * 3,
hauteur : 'calc(100% - 56px)',
margeHaut : 56,
[theme.breakpoints.up('sm')] : {
hauteur : 'calc(100% - 64px)',
margeHaut : 64,
},
},
});

la classe d'exportation ResponsiveDrawer étend React.Component {
état = {
mobileOpen : faux,
} ;

handleDrawerToggle = () => {
this.setState({ mobileOpen: !this.state.mobileOpen });
} ;

rendu() {
const { classes, thème } = this.props;

const drawer = (
  <div>
    <div className={classes.drawerHeader} />
    <Divider />
    <List>{mailFolderListItems}</List>
    <Divider />
    <List>{otherMailFolderListItems}</List>
  </div>
);

return (
  <div className={classes.root}>
    <div className={classes.appFrame}>
      <AppBar className={classes.appBar}>
        <Toolbar>
          <IconButton
            color="inherit"
            aria-label="open drawer"
            onClick={this.handleDrawerToggle}
            className={classes.navIconHide}
          >
            <MenuIcon />
          </IconButton>
          <Typography variant="title" color="inherit" noWrap>
            Responsive drawer
          </Typography>
        </Toolbar>
      </AppBar>
      <Hidden mdUp>
        <Drawer
          variant="temporary"
          anchor={theme.direction === 'rtl' ? 'right' : 'left'}
          open={this.state.mobileOpen}
          classes={{
            paper: classes.drawerPaper,
          }}
          onClose={this.handleDrawerToggle}
          ModalProps={{
            keepMounted: true, // Better open performance on mobile.
          }}
        >
          {drawer}
        </Drawer>
      </Hidden>
      <Hidden smDown implementation="css">
        <Drawer
          variant="permanent"
          open
          classes={{
            paper: classes.drawerPaper,
          }}
        >
          {drawer}
        </Drawer>
      </Hidden>
      <main className={classes.content}>
        <Typography noWrap>{'You think water moves fast? You should see ice.'}</Typography>
      </main>
    </div>
  </div>
);

}
}

ResponsiveDrawer.propTypes = {
classes : PropTypes.object.isRequired,
thème : PropTypes.object.isRequired,
} ;

exporter par défaut avecStyles(styles)(ResponsiveDrawer);
`

screen shot 2018-02-13 at 3 27 41 am

Le CSS injecté augmentera avec le nombre d'instances du composant.

Le CSS injecté par

J'ai aimé cela, bien qu'avec un composant sans état, il restituera le withStyle de render à render , nous pouvons éviter en utilisant un composant pur complet.

import React from 'react';
import {
  withStyles,
  Grid,
  CircularProgress
} from 'material-ui';

const PreloadComponent = props => {
  const { classes,size } = props;
  return (
    <Grid className={classes.container} container justify={'center'} alignItems={'center'}>
      <CircularProgress size={size}/>
    </Grid>
  )
};

const StyleWithThemeProps = (props) => {
  return withStyles(theme => ({
    container: {
      paddingTop: props.size*2 || 50,
      paddingBottom: props.size*2 || 50,
    }
  }),{withTheme: true})(PreloadComponent)
};

const Preload = props => {
  const { size } = props;
  const WithStylesPreloadComponent = StyleWithThemeProps(props);
  return (
    <WithStylesPreloadComponent {...props}/>
  )
};

Preload.defaultProps = {
  size: 20
};

export default Preload;

Nous pouvons utiliser un composant pur complet pour éviter la mise à jour

const PreloadComponent = props => {
  const { classes,size } = props;
  return (
    <Grid className={classes.container} container justify={'center'} alignItems={'center'}>
      <CircularProgress size={size}/>
    </Grid>
  )
};

const StyleWithThemeProps = (props) => {
  return withStyles(theme => ({
    container: {
      paddingTop: props.size*2 || 50,
      paddingBottom: props.size*2 || 50,
    }
  }),{withTheme: true})(PreloadComponent)
};

class PreloadFull extends React.PureComponent {

  constructor(props,context) {
    super(props);
  }

  componentWillMount() {
    this.StyledPreloadFull = StyleWithThemeProps(this.props);
  }

  componentWillUpdate(nextProps) {
    this.StyledPreloadFull = StyleWithThemeProps(nextProps);
  }

  render() {
    const { StyledPreloadFull,props } = this;
    return (
      <StyledPreloadFull {...props}/>
    );
  }
}

PreloadFull.defaultProps = {
  size: 20
};

export default PreloadFull;

@up209d Cela fonctionne, mais c'est assez pénible, je vais essayer de modifier withStyles , pour utiliser plus directement https://github.com/cssinjs/react-jss qui peut passer des props en valeurs

@SrikanthChebrolu pourriez-vous déplacer votre message vers un autre problème, car il n'est pas dans le sujet ?

Juste curieux de savoir quel est le statut à ce sujet ? J'ai lu ce numéro, les docs JSS, les docs material-ui, et je n'ai pas encore trouvé de solution pour Mui+Jss+TypeScript qui ne m'oblige pas à utiliser des styles en ligne. Mettre quelques styles en ligne est parfois inévitable, mais dans mon cas, il existe plusieurs styles qui ont de nombreux états différents, tous s'appuyant sur le thème et les accessoires :déçu:

@chazsolo Hé Chaz, vous pouvez en fait utiliser injectSheet partir de react-jss au lieu de withStyles partir de mui . De cette façon, vous pouvez avoir à la fois props et theme .

import injectSheet from 'react-jss';

const styles = theme => ({
  container: {
     color: props => theme.palette[props.color || 'primary'].main
  }
});

...

export default injectSheet(styles)(AnyComponent);
import { JssProvider, jss, createGenerateClassName } from 'react-jss/lib';
import { MuiThemeProvider } from 'material-ui';

const generateClassName = createGenerateClassName();

...

<JssProvider jss={jss} generateClassName={generateClassName}>
  <MuiThemeProvider theme={props.theme} sheetsManager={new Map()}>
    <App/>
  </MuiThemeProvider>
</JssProvider>

@chazsolo je pense que vous voulez suivre ce numéro https://github.com/cssinjs/jss/issues/682

Merci @kof et @up209d - abonné et donnant un coup à l'exemple de up209d.

@ up209d
Malheureusement, je ne pense pas que cela fonctionnera pour moi - j'ai implémenté ce que vous avez suggéré et je peux voir les accessoires dans l'appel de fonction à l'intérieur de l'objet styles , mais je continue à avoir des erreurs. IEst-ce que je manque juste des types ? J'étends WithStyles dans les props Interfaces afin d'avoir accès à l'objet classes dans les props (maintenant je me demande si c'est le problème référencé dans https://github.com/mui- org/material-ui/issues/8726#issuecomment-337482040)

TS2344: Type '(theme: ITheme) => { arc: { stroke: string; strokeWidth: (props: any) => string | number; }; arcM...' does not satisfy the constraint 'string | Record<string, CSSProperties> | StyleRulesCallback<string>'.
  Type '(theme: ITheme) => { arc: { stroke: string; strokeWidth: (props: any) => string | number; }; arcM...' is not assignable to type 'StyleRulesCallback<string>'.
    Type '{ arc: { stroke: string; strokeWidth: (props: any) => string | number; }; arcMovement: { strokeDa...' is not assignable to type 'Record<string, CSSProperties>'.
      Property 'arc' is incompatible with index signature.
        Type '{ stroke: string; strokeWidth: (props: any) => string | number; }' is not assignable to type 'CSSProperties'.
          Types of property 'strokeWidth' are incompatible.
            Type '(props: any) => string | number' is not assignable to type 'string | number | undefined'.
              Type '(props: any) => string | number' is not assignable to type 'number'.

Mon thème ressemble à :

import { ITheme } from '...';

export default (theme: ITheme) => ({
  arc: {
    // ...
    strokeWidth: (props: any): number | string => {
      // this logs the correct data I'm expecting
      console.log(props.data[0].properties.name)
      return 1.5
    }
  },
  arcMovement: {
    // ...
  },
})

Ce qui est intéressant, c'est que lorsque j'utilise l'objet classes dans mon composant, arc et arcMovement sont des propriétés valides :

// from Chrome console
{
  arc: "Arcs-arc-0-2-1 Arcs-arc-0-2-3",
  arcMovement: "Arcs-arcMovement-0-2-2"
}

Mettre à jour

J'ai réussi à faire fonctionner cela, mais comme indiqué dans le commentaire ci-dessus, j'ai dû supprimer toutes les références à WithStyles , withStyles , et je perds classes composition et thème nidification. Je vais me reposer maintenant et garder un œil sur les fils. Merci pour votre aide!

@chazsolo Hé Chaz, je ne suis pas sûr mais est-ce que vous voulez accéder à classes à l'intérieur du props de l'objet style . Si c'est le cas, je pense que c'est impossible puisque le classes n'est disponible qu'après jss traité l'objet style , comment pouvez-vous accéder à classes avant un processus de fabrication classes n'a même pas été déclenché ?

Je pense que @caub a déjà fourni une solution. Republiez simplement la solution avec peu de torsion. Pas besoin de bibliothèque supplémentaire.

Construisez votre propre wrapper withStylesProps .

import { withStyles } from 'material-ui/styles';

const styles = ( theme, props ) => ({
    exampleStyle: {
           color: 'red'  // <-- or try theme.palette.primary[600]
    }
})

const withStylesProps = ( styles ) =>
  Component =>
    props => {
      const Comp = withStyles(theme => styles(theme, props))(Component);
      return <Comp {...props} />;
    };

const YourComponent = ({  classes }) => 
      <Typography type="display4" className={classes.exampleStyle}>{type}</Typography>

export default withStylesProps(styles)(YourComponent);

Si vous n'aimez pas créer withStylesProps pour chaque composant, essayez de l'ajouter dans un fichier séparé et importez où vous le souhaitez.

@iamthuypham Merci pour le conseil. Cependant, lorsque j'encapsule mon composant avec withStylesProps , l'animation du composant de transition <Collapse j'utilise quelque part à l'intérieur du composant encapsulé cesse de fonctionner.

@jdolinski1 Pouvez-vous copier/coller votre exemple de code ?

@iamthuypham, votre solution a l'inconvénient de créer une nouvelle balise <style> chaque fois qu'un composant est créé. En outre, vous pouvez être prudent lorsque vous utilisez defaultProps et ajoutez-les à votre composant HOC et non aux composants de base.

image

Tout cela est supporté par react-jss , ne peut-il pas être supporté nativement par material-ui ?

De plus, je pense que le problème de children le composant encapsulé peut avoir.

@iamthuypham Je pense qu'il n'est pas recommandé de le faire, comme je le faisais dans le passé, et vous pourriez rencontrer de mauvaises performances tant que l'application se développera très bientôt. Créer une nouvelle instance de component avec un nouvel objet jss style n'est pas bon en termes de principe de codage car l'objet style doit être entièrement restitué, encore et encore, chaque temps par props changement. Utiliser injectSheet partir de react-jss est un meilleur choix. Si vous regardez dans le injectSheet vous verrez qu'il brise votre objet style en 2 morceaux ( static & dynamic ) donc seulement le dynamic est re-rendu lorsque props changent.

comment utiliser des plugins tels que jss-nested avec injectSheet ?.

avec injectSheet, je ne peux pas faire fonctionner les instructions '&:hover'.
avec withStyles, je ne peux pas accéder aux accessoires...

@koutsenko Voici un exemple :

import React from "react";
import { makeStyles } from "@material-ui/styles";
import Button from "@material-ui/core/Button";

const useStyles = makeStyles({
  root: {
    background: props => props.color,
    "&:hover": {
      background: props => props.hover
    },
    border: 0,
    borderRadius: 3,
    color: "white",
    height: 48,
    padding: "0 30px"
  }
});

export default function Hook() {
  const classes = useStyles({
    color: "red",
    hover: "blue"
  });
  return <Button className={classes.root}>Hook</Button>;
}

https://codesandbox.io/s/pw32vw2j3m

J'espère que ça aide.


Wow, c'est incroyable les progrès que nous avons réalisés en ~1 an 😍.

maintenant, comment tapez-vous cela?

@stunaz Bonne question. Je ne sais pas. Je ne l'ai pas examiné. @eps1lon a fait la définition TypeScript du module. Vous pouvez l'utiliser comme point de départ.
https://github.com/mui-org/material-ui/blob/f4281a77d15b0d6eec9d33cdc358cfb89844996d/packages/material-ui-styles/src/index.d.ts#L72

@koutsenko Voici un exemple :

Merci @oliviertassinari , avec " react@next " ça marche maintenant.

@koutsenko Si vous ne parvenez pas à faire fonctionner jss-nested , cela doit être un problème de configuration quelque part dans votre codage. Comme jss-nested est inclus dans jss-default-preset , cela fonctionne donc simplement oob

https://stackblitz.com/edit/react-py6w2v

@oliviertassinari

Pouvez-vous également définir l'ensemble de l'objet styles pour un sélecteur donné avec des accessoires ? À qui pouvez-vous appliquer conditionnellement une propriété?

Par exemple, comme ça

withStyles({
    root: {
        '& > path': (props) => {
            if(props.color)
                return {
                    fill: props.color
                };
           return {};
        }
    }
})

Ainsi, si l'accessoire n'existe pas, il utilise la valeur de remplissage précédente, plutôt que quelque chose d'autre sur lequel je dois le définir? Par exemple, il existe d'autres règles qui s'appliqueraient normalement au remplissage, mais je ne souhaite définir cette nouvelle propriété de remplissage que si la prop color est définie.

Merci!

@Guardiannw Pour une raison quelconque, votre variante ne fonctionne pas. Peut-être que @kof pourrait nous éclairer sur le pourquoi 💡. Vous pouvez effectuer l'une des opérations suivantes :

// 🏆
const useStyles = makeStyles({
  root: {
    "& > span": {
      backgroundColor: props => props.color || null,
    }
  }
});

// or 

const useStyles = makeStyles({
  root: props => ({
    "& > span": {
      backgroundColor: props.color || null
    }
  })
});

@oliviertassinari J'ai du mal à faire fonctionner votre deuxième option avec la fonction withStyles . Est-ce que cela ne fonctionne qu'avec makeStyles et les hooks ?

@Guardiannw Cela fonctionne avec l'une des API de @material-ui/styles .

@oliviertassinari ressemble à une syntaxe valide, les valeurs fn ont été ajoutées dans la v10, donc soit la v9 a été utilisée, soit j'ai besoin d'une reproduction de codesandbox

Ok, c'est avec ça que j'ai essayé. Il faudra peut-être réessayer.

@oliviertassinari J'ai une question sur l'utilisation de @materia-ui/styles, est-il disponible et à utiliser dans un environnement de production ?, dans la documentation indique que cela ne fonctionne pas avec la version stable, j'utilise le " 3.9.1", l'exemple https://github.com/mui-org/material-ui/issues/8726#issuecomment -452047345 que vous présentez a une fonctionnalité puissante et utile dont j'ai besoin. Dans ces numéros, j'ai vu de nombreux commentaires sous un angle différent et j'aime aussi la solution https://github.com/mui-org/material-ui/issues/8726#issuecomment -363546636 de @caub , mais votre commentaire sur son la solution est bonne.

@contrerasjf0 @material-ui/styles n'est disponible qu'en version alpha. Nous traitons les versions alpha comme la plupart des packages de l'écosystème React. Je vous recommanderais de ne jamais utiliser de packages alpha en production. Si vous le faites, vous devriez vous attendre à des bogues et à des changements de rupture entre chaque version, c'est-à-dire que vous devriez être capable de gérer l'ajout des versions alpha de désabonnement.

Ce que j'espère, c'est que les gens utilisent ces versions soit dans des projets de loisir, soit sur une branche distincte qui n'est pas déployée en production mais toujours testée, tout comme la branche de production. J'apprécie tous ceux qui utilisent ces versions alpha et nous font part de leurs commentaires.

@ up209d oui, votre solution fonctionne, mais avec
styles = { name: { cssprop: props => {} } notation, pas
styles = props => ({ name: { cssprop: {} })

De plus, JssProvider n'est pas nécessaire.

@koutsenko

// at value level:
styles = { name: { cssprop: props => value }
styles = theme => ({ name: { cssprop: props => value })

// at class name level
styles = { name: props => ({ cssprop: value })  }
styles = theme => ({ name: props => ({ cssprop: value })  })

Vous ne pouvez pas accéder à props au niveau supérieur, même en tant que deuxième argument après theme

j'ai trouvé un moyen

// MyComponent.tsx
import React, { PureComponent } from 'react';
import { myComponentWithStyles } from './myComponentWithStyles';

export interface MyComponentProps {
  copy: string;
  size?: number;
}

export class Twemoji extends PureComponent<myComponentWithStyles> {
  public render() {
    const { copy, classes } = this.props;

    return (
      <div className={classes.message}>
        {copy}
        <img src="https://via.placeholder.com/150" />
    </div>
    );
  }
}

// myComponentWithStyles.tsx
import React from 'react';
import { withStyles, WithStyles, Theme } from '@material-ui/core';
import { MyComponent, MyComponentProps } from './my-component';

const styles = (props: Theme & MyComponentProps) => ({
  message: {
    fontSize: props.typography.caption.fontSize,
    'box-sizing': 'content-box',
    '& img': {
      width: `${props.size || 24}px`,
      height: `${props.size || 24}px`,
      padding: '0 4px',
      verticalAlign: 'middle',
    },
  },
});

export type myComponentWithStyles = WithStyles<any>;

export const Component = (props: MyComponentProps) => {
  const StyledComponent = withStyles((theme: Theme) => styles({ ...props, ...theme }))(
    MyComponent
  );

  return <StyledComponent {...props} />;
};



md5-d0e1b51e375682cf2aad9c4d66b6c73a



<Component size={12} />

@ andreasonny83 Évitez ce modèle. Nous fournissons une API native en v4.

@oliviertassinari merci pour la mise à jour. Ce modèle est-il déjà disponible ? Une documentation disponible ?

Une dernière question @oliviertassinari . Puis-je utiliser makeStyles en combinaison avec withStyles ?

Je ne trouve pas de documentation pour cela. Ce que j'essaye de faire c'est ça :

const useStyles = makeStyles({
  message: {
    boxSizing: 'content-box'
  }
});

export const ComponentWithStyles = withStyles(useStyles())(MyComponent);

@andreasonny83

Utilisez l'un ou l'autre, dans votre exemple, supprimez simplement makeStyles :

const styles = { message: {boxSizing: 'content-box', background: props => props.bg} };
export const ComponentWithStyles = withStyles(styles)(MyComponent);

Les gens de Gday pensaient que je partageais ma solution actuelle en référence à la discussion ci-dessus, j'espère que cela aidera quelqu'un ou que quelqu'un pourrait offrir de meilleurs conseils sur ma solution actuelle. Pour ma page de connexion, l'identifiant ressemble à une image d'arrière-plan aléatoire, mais j'aime toujours conserver la puissance du matériel ui api. AuthPage n'est que la couche de présentation parente qui prend les composants d'authentification individuels (connexion, verrouillage, mot de passe oublié, réinitialisation du mot de passe, etc.) comme enfants. Peut confirmer avec chaque page actualiser un nouveau chargement d'arrière-plan ainsi qu'un joli accessoire fortement typé dans l'accessoire AuthPageContainer

//AuthPage.styles.tsx

import { Container } from "@material-ui/core";
import { ContainerProps } from "@material-ui/core/Container";
import { withStyles } from "@material-ui/core/styles";
import React from "react";

interface IAuthContainerProps extends ContainerProps {
  background: string;
}

export const AuthContainer = withStyles({
  root: props => ({
    alignItems: "center",
    backgroundImage: `url(${props.background})`,
    backgroundPosition: "50% 50%",
    backgroundRepeat: "no-repeat",
    backgroundSize: "cover",
    display: "flex",
    height: "100vh",
    justifyContent: "center",
    margin: 0,
    padding: 0,
    width: "100%"
  })
})((props: IAuthContainerProps) => <Container maxWidth={false} {...props} />);

// AuthPage.tsx

import React from "react";
import forest from "../../assets/backgrounds/forest.jpg";
import sky from "../../assets/backgrounds/sky.jpg";
import uluru from "../../assets/backgrounds/uluru.jpg";
import { AuthContainer } from "./AuthPage.styles";

const AuthPage = ({ children }) => {
  const generateBackground = () => {
    const backgrounds = [forest, sky, uluru];
    const index = Math.floor(Math.random() * backgrounds.length);
    return backgrounds[index];
  };

  return (
    <AuthContainer background={generateBackground()}>{children}</AuthContainer>
  );
};

export default AuthPage;

faites simplement quelque chose comme ceci :

// styles.js
export default theme => ({
    root: props => ({
        // some styles
    }),
    ...
});

//container.js
export default withStyles(styles)(MyComponent);

qu'en est-il de l'état de passage également ?

@luky1984
Vous ne pouvez pas. Au lieu de cela, vous pouvez faire :

// Component.js
<Button
    className={`
        ${classes.button} 
        ${this.state.isEnable
            ? classes.enable
            : classes.disable}
    `}
/>

Ou utilisez plutôt clsx https://www.npmjs.com/package/clsx

@caub Votre solution ruine l'ordre des noms de classe généré par jss.
Comme écrit ici : https://github.com/mui-org/material-ui/issues/8726#issuecomment-363546636
J'ai essayé d'utiliser votre solution, mais votre solution de composant HOC (withStylesProps) retarde l'appel de son withStyles, car il est enveloppé, donc l'appeler avec classNames ne remplace pas le css.
Comme : https://codesandbox.io/s/hocs-8uhw1?file=/index.js

le fond doit être #0000000 et la couleur : bleu

Cette page vous a été utile?
0 / 5 - 0 notes