Wenn Sie createStyleSheet
, gibt es keine Möglichkeit (zumindest die mir bekannt ist), auf die Requisiten der Komponente zuzugreifen. Ich denke, dies ist wichtig, da manchmal Größen, URL-Bilder und andere Stile als Requisiten an die Komponente übergeben werden sollen.
Heute ist die einzige Lösung dafür, diese Dinge in Inline-Stile zu unterteilen, aber soweit ich weiß, verwendet material-ui v1 jss
und react-jss
, und diese beiden bieten Ihnen bereits die Möglichkeit Zugriff auf die Requisiten über Funktionen, die die Requisiten empfangen und dann den gewünschten Stil zurückgeben, wie folgt:
const styles = {
button: {
background: props => props.color
},
root: {
backgroundImage: props => `url(${props.backgroundImage})`
}
}
// Reference: https://github.com/cssinjs/react-jss#example
Was halten Sie davon, so etwas auch auf material-ui zu implementieren?
React-jss implementiert diese Funktion. Sie können es immer über unserer Styling-Lösung verwenden. Die eigentliche Motivation für die Implementierung dieses Features hier sollte eine einfachere/bessere interne Implementierung der Komponenten sein.
response-jss injectStyles() tut dies auch, aber es scheint, dass es besser wäre, Requisiten zu StyleRuleCallback
hinzuzufügen.
const styles = (props, theme) => ({})
Auf diese Weise sind Sie nicht nur auf Werte beschränkt, die von Requisiten abhängen.
Das Feedback von color
anstelle des vordefinierten bereitzustellen. Die Auswirkung auf die CSS-Größe ist unklar, aber es würde das Überschreiben der Komponentenfarbe noch einfacher machen. Dies ist etwas zu untersuchen. Sobald die Browserunterstützung für CSS-Variablen hoch genug ist (in 2 Jahren?), können wir uns darauf verlassen.
@oliviertassinari würde die CSS-Größe in einigen Fällen nicht tatsächlich abnehmen?
Wie ich es verstehe, definieren wir derzeit alle Klassen für ...Primary
und ...Accent
- würde diese Änderung nicht bedeuten, dass wir nur Klassen für ...Colorized
pflegen müssten? Oder machen Sie sich Sorgen um das generierte CSS?
So oder so denke ich, dass dies dx enorm verbessern würde, da wir im Grunde komplexe Klassen wie https://github.com/callemall/material-ui/blob/v1-beta/src/Button/Button.js#L11 neu implementieren müssen, wenn wir möchten Nicht-Palette-Farben verwenden.
Würde die CSS-Größe in einigen Fällen nicht tatsächlich abnehmen?
@sakulstra Schwer zu sagen. Es wird von der Umsetzung abhängen. Vielleicht :).
Aus Sicht der TypeScript-Typisierung wäre es schön, wenn auf _both_ props
und theme
innerhalb einer Stilspezifikation props
diese Weise zugegriffen werden könnte:
const styles = {
button: {
background: ({ theme }) => theme.palette.primary[200]
},
root: {
backgroundImage: ({ props }) => `url(${props.backgroundImage})`
}
};
Der Grund dafür ist, dass TypeScript häufig nicht den richtigen Typ für withStyles
wenn ihm ein Funktionsobjekt übergeben wird, sodass Sie zusätzliche Typannotationen bereitstellen müssen, damit es funktioniert, z
withStyles<'button' | 'root'>(theme => ...)
Wenn auch Requisiten übergeben werden, wird dies zu
withStyles<'button' | 'root', Props>((theme, props) => ...)
Wie ist der aktuelle Stand dazu? Es wäre wirklich schön, diese Funktion zu haben
@lucasmafra Ich habe diese Funktion zum Meilenstein nach der Veröffentlichung nach v1 hinzugefügt. Je früher wir v1 veröffentlichen können, desto besser.
Diese Funktionalität ist der Schlüssel zum Schreiben ausdrucksstarker Stilregeln, die Requisiten, Medienabfragen und interaktive Zustände kombinieren. Sie können diese Funktionalität nicht durch Inline-Stile ersetzen. Leider ist withStyles
in keinem meiner Projekte verwendbar, bis dies hinzugefügt wird.
Sie können jederzeit ein benutzerdefiniertes Design einrichten und diese Konvention verwenden: Uns gefällt, wie gestylte Komponenten Ihnen sofort Zugriff auf das props.theme geben, indem Sie ThemeProvider in MuiThemeProvider verschachteln, wenn beide theme={theme} aufgerufen werden. Es erweitert das Standardthema, das mui verfügbar macht
//inline with HOC Method
h1 style= {{ 'color: this.props.theme.palette.primary[500]' }}
//styled components ( no method necessary )
const Heading = styled.h1`
color: ${p => p.theme.palette.primary['500']};
`
Ich musste nur Funktionswerte verwenden, also habe ich die injectSheet()
Funktion von response-jss verwendet. Ich bin es gewohnt, die withStyles()
Funktion von Mui zu verwenden. Gibt es also einen Nachteil, wenn ich injectSheet anstelle von withStyles verwende?
@damien-monni Sie erhalten keinen Zugriff auf Ihr MUI-Theme.
Hallo zusammen, wollte nur meine Version der komponentenähnlichen API im Material-UI-
props
und theme
hochgezogen, um die Funktion zu stylen.props
an umschlossene KomponenteReact.forwardRef
function
oder object
akzeptieren Verwandte Probleme: #10825, #7633
styled.js
import React, { Component } from 'react';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
function styled(WrappedComponent, customProps) {
return (style, options) => {
class StyledComponent extends Component {
render() {
let {
forwardRef,
classes,
className,
...passThroughProps
} = this.props;
return (
<WrappedComponent
ref={forwardRef}
className={classNames(classes.root, className)}
{...passThroughProps}
{...customProps}
/>
);
}
}
StyledComponent.propTypes = {
classes: PropTypes.object.isRequired,
className: PropTypes.string,
};
let hoistedProps = {};
const styles =
typeof style === 'function'
? theme => {
return { root: style({ ...theme, theme, props: hoistedProps }) };
}
: { root: style };
const WithRef = withStyles(styles, options)(StyledComponent);
return React.forwardRef((props, ref) => {
hoistedProps = props;
return <WithRef {...props} forwardRef={ref} />;
});
};
}
export default styled;
Anwendungsbeispiel
const MobileNav = styled('nav')(({ theme, props }) => ({
'&.pos-fixed': {
top: 0,
position: props.fixed ? 'fixed' : 'absolute',
zIndex: 99,
animation: 'fadeInDown 0.3s ease-out forwards',
backgroundColor: theme.palette.common.white,
},
}));
Mit benutzerdefinierten Requisiten
const StyledButton = styled(Button, { component: Link })(
({ theme, props }) => ({
color: props.disabled ? 'gray' : 'blue',
[theme.breakpoints.down('sm')]: {
color: 'red',
},
})
);
@oliviertassinari Um dieses Problem zu lösen, verwende ich die folgende Lösung:
componentWillMount() {
const {color} = this.props;
jss.setup(jssPreset());
const stylesheet = jss.createStyleSheet({
underline: {
"&:after": {
backgroundColor: `${color} !important`
}
}
}).attach();
this.underlineClass = stylesheet.classes.underline;
}
Es funktioniert großartig, aber gibt es einige potenzielle Probleme, die ich nicht sehe? Ich mag es nicht, dass ich zum Beispiel jss.setup zweimal aufrufen muss 😅. Ich bin mir nicht sicher, ob ich den Lebenszyklus von jss
verstehe. Ich war überrascht, dass ich hier setup()
aufrufen musste.
Es funktioniert großartig, aber gibt es einige potenzielle Probleme, die ich nicht sehe?
@wcandillon Einige potenzielle
Ich habe diese Bibliothek entwickelt, um Requisiten mit Stil zu haben:
https://github.com/JacquesBonet/jss-material-ui
Erfolgreich in einem Projekt getestet.
Zuerst verwende ich die Danielmahon-Lösung, bekomme aber ein Stilvererbungsproblem.
@oliviertassinari Haben wir
@HunderlineK Some alternatives: https://material-ui.com/customization/overrides/#2-dynamic-variation-for-a-one-time-situation.
@danielmahon Ihr Ansatz ist genau das, wonach ich gerade suche, um mein Problem zu lösen, obwohl die "Styled Component" nicht neu gerendert wird, wenn sie neue Requisiten erhält. Hast du noch was probiert?
Ich werde mir etwas anderes einfallen lassen und wenn mir etwas einfällt, lasse ich es dich wissen
💰 Daran hängt gerade ein Kopfgeld von 50 $ :)
Wie @lewisdiamond sagte, const styles = (props, theme) => ({})
wäre wirklich ordentlich.
Oder const styles = (theme, props) => ({})
, um vielleicht nicht zu brechen.
Ich füge dieses Problem im
@oliviertassinari dies hat wahrscheinlich erhebliche Auswirkungen auf die Eingabe von withStyles
, lass es mich wissen, wenn ich dabei helfen kann
@pelotom Danke, ich lasse es dich wissen. Ich hoffe, ich kann diesen Monat anfangen, mich mit dem Thema zu befassen.
Gibt es diesbezüglich Arbeiten? Es ist ein wichtiges Feature IMO, vielleicht kann ich dabei helfen.
EDIT: Ich habe angefangen, daran zu arbeiten. Es ist gelungen, Requisiten an die styles
Funktion zu übergeben, die withStyles
akzeptiert. Das einzige Problem ist, dass Stile nicht aktualisiert werden, wenn sich Requisiten ändern. Werde eine PR erstellen, wenn das gelöst ist.
Hallo, ich bin gerade auf einen Anwendungsfall gestoßen, bei dem ich dies benötigte, um die Farben der Avatar-Komponente anzupassen, und es gibt keine andere Möglichkeit, den Stil für alle Varianten der Komponente anders als diese zu steuern.
const styles = theme => ({
chip:{
},
separator: {
marginRight: theme.spacing.unit,
},
fright: {
float: 'right',
},
fleft: {
float: 'left',
},
outlinedPrimary:{
color: props => stringToColor( props.username),
border: props => `1px solid ${fade(stringToColor(props.username), 0.5)}`,
'$clickable&:hover, $clickable&:focus, $deletable&:focus': props => ({
backgroundColor: fade(stringToColor(props.username), theme.palette.action.hoverOpacity),
border: `1px solid ${stringToColor(props.username)}`,
}),
},
outlined: {
backgroundColor: 'transparent',
border: props => `1px solid ${
theme.palette.type === 'light' ? stringToColor(props.username) : fade(stringToColor(props.username))
}`,
'$clickable&:hover, $clickable&:focus, $deletable&:focus': props => ({
backgroundColor: fade(stringToColor(props.username), theme.palette.action.hoverOpacity),
}),
},
});
Sie können meine Lösung Japrogramer überprüfen: https://github.com/JacquesBonet/jss-material-ui
danke, ich werde es mir anschauen.
Ich brauchte dieses Feature heute früher, also habe ich ein HOC geschrieben. withStyles
macht selbst etwas Caching, daher kann ich nicht wirklich sagen, wie sehr sich das auswirkt, aber ich werde mir die Caching-Implementierung von withStyles
in meiner Freizeit ansehen, für jetzt alle, die nach einem Schneller Weg, um Requisiten und Themen zu erhalten, um dort gut zu spielen
Diese Komponente führt eine vollständige Neumontage durch, wenn sich die Requisiten etwas ändern, was mit der Änderung der Indexnummer der Stylesheet-Klasse oder etwas im withStyles-HOC zu tun hat
import React from 'react';
import { withStyles } from '@material-ui/core/styles';
const { createElement, forwardRef } = React
const withPropsStyles = ( style ) => {
const withPropsStyles = ( component ) => {
return forwardRef( (props, ref) => {
const proxy = (theme) => style(props, theme)
const hoc = withStyles(proxy)(component)
return props.children ?
createElement(hoc, { ...props, ref}, props.children) :
createElement(hoc, {...props, ref})
})
}
return withPropsStyles
}
export default withPropsStyles
const styles = (props, theme) => ({
root:{
backgroundColor: props.light ? theme.palette.primary.light : theme.palette.primary.main
},
})
const SomeComponent = ({classes}) => <div className={classes.root}/>
export default withPropsStyles(styles)(SomeComponent)
Einfach und funktioniert (aber auch die vollen Remount-Kosten)
Können wir mit dieser Änderung die Verwendung von Inline-Stilen aus der Bibliothek zugunsten von 100 % JSS entfernen? Meine App funktioniert nicht mit Inline-Stilen und als ich den Ripple-Effekt durch JSS ersetzen wollte, wurde mir klar, dass ich diese Funktion brauche. Vielleicht ein kleiner Performance-Hit, scheint aber sauberer zu sein.
@koshea lässt den Inline-Stil withStyles
als Dekorateur oder wie im Beispiel funktionieren.
Ich wollte auch erwähnen, dass die Verwendung von Inline-Stilen keine strenge Inhaltssicherheitsrichtlinie ermöglicht.
Es erfordert das Hinzufügen des unsafe-inline
Flags zu den Style-Direktiven, was nicht sicher ist.
Dynamische Stile mit Unterstützung für Requisiten sollten dieses Problem lösen
Hallo Leute, sorry, dass ich mich in die Diskussion "einfach so" einklinken muss. Ich habe vor kurzem angefangen, Mui (mit Typescript) zu verwenden, und obwohl ich es für eine äußerst leistungsstarke Bibliothek halte, hat sie sicherlich ihre Komplexität.
Ich habe in einigen Kommentaren oben bemerkt, dass es eine Diskussion darüber gibt, ob diese Funktion (props, theme) => {}
oder (theme, props) => {}
. Ich möchte in seinem Kommentar unterstreichen , was Erstellen von props
und theme
gesagt hat. Wenn wir das so machen, wird es uns wahrscheinlich leichter fallen, die Stildefinitionen zu überarbeiten, sobald diese Änderung eintrifft (auf die ich mich wirklich freue). Prost 🙂
Vielen Dank an alle für die Geduld! Dieses Problem wird in #13503 behandelt. Dies ist eine Voraussetzung für die Komponentenhelfer, die wir implementieren möchten. Wir haben auch begonnen, mit der Hook-API zu experimentieren: https://twitter.com/olivtassinari/status/1058805751404261376.
Hat es das in 4.0 geschafft? Es sieht so aus, als hätte der makeStyles
Callback keinen props
Parameter.
@city41 const classes = useStyles(props);
Ich verstehe. So sieht es aus
const useStyles = makeStyles(theme => {
return {
foo: {
color: theme.props.danger ? '#ff0000' : '#00ff00'
}
};
});
function MyComponent(props) {
const classes = useStyles(props);
return <div className={classes.foo}>...</div>;
}
Ich sehe dies nicht im Abschnitt Stile-API auf der Website dokumentiert. Mal sehen, ob ich eine PR schicken kann.
@city41 Es gibt einen Beginn einer Dokumentation in https://material-ui.com/styles/basics/#adapting -based-on-props.
cool, froh zu sehen, dass die docs aktualisiert werden. Für alle anderen, die zu diesem Thema kommen, hier ist, wie ich Thema und Requisiten kombiniert habe, um eine Komponente zu stylen
import React from 'react';
import { Button, Theme, makeStyles } from '@material-ui/core';
interface ButtonProps {
destructive: boolean;
}
const useButtonStyles = makeStyles<Theme, ButtonProps>(theme => {
return {
root: props => ({
backgroundColor: props.destructive ? theme.palette.error.main : theme.palette.primary.main
})
};
});
export const PrimaryButton: React.FunctionComponent<ButtonProps> = props => {
const classes = useButtonStyles(props);
return <Button {...props} className={classes.root} variant="contained" />;
};
Wie kann ich prop in einer Json-Datei mit externen Stilen verwenden?
zum Beispiel ist dies eine externe Datei
const typographyStyle = {
title2: {
fontFamily:"Montserrat",
fontStyle:"normal",
fontWeight:"800",
fontSize:"72px",
lineHeight:"88px",
letterSpacing:"-0.02em",
// color:"#304C82"
color : props => {
console.log(props,'c1');
return props.color
}
}
};
export default typographyStyle;
Ich importiere diese Datei und verbreite das Objekt
import typographyStyle from "../assets/jss/material-kit-pro-react/views/componentsSections/typographyStyle";
const styles = theme => ({
...typographyStyle,
homeSearch:{
width: '100%',
'& div':{
'& input':{
"color":"#304C82",
height: 65,
fontFamily: 'Open Sans',
fontStyle: 'normal',
fontWeight: 800,
fontSize: '48px',
lineHeight: '65px',
letterSpacing: '-0.03em',
'&::placeholder':{
fontFamily: 'Open Sans',
fontStyle: 'normal',
fontWeight: 800,
fontSize: '48px',
lineHeight: '65px',
letterSpacing: '-0.03em',
color: '#EAEAEA'
}
}
}
},
});
Jetzt bekomme ich bei der Farbfunktion props = {} .
kann mir diesbezüglich jemand helfen?
AKTUALISIEREN:
Es scheint, als ob ich etwas falsch mache, weil ich sogar in meiner Hauptdatei "styles.js" ein leeres Objekt erhalte
homeSearch: props => {
console.log(props);
return {
width: '100%',
border: `1px solid ${props.color}`
,
'& div':{
'& input':{
"color":"#304C82",
height: 65,
fontFamily: 'Open Sans',
fontStyle: 'normal',
fontWeight: 800,
fontSize: '48px',
lineHeight: '65px',
letterSpacing: '-0.03em',
'&::placeholder':{
fontFamily: 'Open Sans',
fontStyle: 'normal',
fontWeight: 800,
fontSize: '48px',
lineHeight: '65px',
letterSpacing: '-0.03em',
color: '#EAEAEA'
}
}
}
}
},
Hilfreichster Kommentar
Ich füge dieses Problem im