I cannot find a way to get both a local rule reference (named '& $value'
in the code below) to fully work in conjunction with using functions for CSS definitions. Any CSS properties that are defined using a function accepting a StyleProperties
object and returning a CSS value are simply ignored when defined for rules that reference other local rules; please see code and comments:
import * as React from "react";
import { Theme, makeStyles, createStyles } from "@material-ui/core/styles";
import CssBaseline from "@material-ui/core/CssBaseline";
import clsx from "clsx";
type StyleProperties = {
scale: number;
};
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: (props: StyleProperties) => {
const size = `${2.0 * props.scale}rem`;
return {
position: "relative",
backgroundColor: theme.palette.background.paper,
border: `1px solid ${theme.palette.divider}`,
width: size,
height: size,
"& > div": {
position: "absolute"
}
};
},
value: {
color: theme.palette.text.primary,
width: "100%",
height: "100%",
textAlign: "center",
lineHeight: (props: StyleProperties) => `${2.0 * props.scale}rem`
},
static: {
"& $value": {
// Following are OK
color: theme.palette.action.disabled,
backgroundColor: theme.palette.action.disabledBackground,
// Ignored
border: (props: StyleProperties) =>
`${0.0625 * props.scale}rem solid red`
// Comment out above line and uncomment the following to see expected output
// if the value 2.0 was passed in through props.
//border: `${ 0.0625 * 2.0 }rem solid red`,
}
}
})
);
type ValueProperties = {
value: string;
scale: number;
};
function Value(props: ValueProperties) {
const classes = useStyles(props);
return <div className={clsx(classes.value)}>{props.value}</div>;
}
type CellProperties = {
static: boolean;
scale: number;
};
function Cell(props: CellProperties) {
const classes = useStyles(props);
return (
<div className={clsx(classes.root, { [classes.static]: props.static })}>
<Value value="value" scale={props.scale} />
</div>
);
}
export default function App() {
return (
<div className="App">
<CssBaseline />
<Cell static={false} scale={2.0} />
<Cell static={true} scale={2.0} />
</div>
);
}
I have also tried using a function accepting my StyleProperties
object at both static
and '& $value'
rule levels rather than at the CSS Property levels, but both approaches fully ignored all CSS definitions found within '& $value'
.
There are no error messages or warnings output when using the code above. After searching around through the documentation of both Material-UI and JSS I did not find any mention of known limitations relating to this scenario.
Ultimately, defining the CSS based on values provided by StyleProperties
and the Material-UI Theme
is a strict requirement for the interface of my application. So if you would like to suggest an alternate approach to declaring hierarchy based style rules, please keep that in mind.
EDIT: As requested I am providing a code sandbox to demonstrate the issue: https://codesandbox.io/s/relaxed-bird-sklgr -- see border
definition on line 43 and the fact it is not being applied.
The issue is that you are calling
useStyles
from bothCell
andValue
. This causes two different classes to be generated for thevalue
rule and two different classes to be generated for thestatic
rule. Thevalue
class generated forCell
is being referenced by"& $value"
in thestatic
class applied toCell
, but it is thevalue
class generated forValue
that is applied to theValue
element, so it isn't matched by the descendant selector in thestatic
class.You can fix this by only calling
useStyles
in one place and passing thevalue
class name down to theValue
element as in the example below: