Styles PPX (not recommended)
caution
The PPX is not recommended anymore for the following reasons:
- We don't use it in our codebase and cannot thoroughly test it.
- We will deprecate it as soon as it would take a significant amount of work hours to keep it alive.
- The ReScript team recommends to use as few PPXes as possible in your codebase.
Installation
First, add it to your dependencies using npm
or yarn
:
yarn add rescript-material-ui-ppx
# or
npm install rescript-material-ui-ppx
Second, add it to ppx-flags
in your bsconfig.json
:
{
"ppx-flags": ["rescript-material-ui-ppx/ppx"]
}
In some cases, depending on your project structure and build process, you might have to reference the path directly:
{
"ppx-flags": ["./node_modules/rescript-material-ui-ppx/ppx"]
}
What is a PPX?
PPX stands for Pre Processor eXtension. There is a fairly detailed article by @dylanirlbeck that I'd recommed if you're interested in the nuts and bolts of these extensions: Link to the article.
Why do we need one for rescript-material-ui?
When you create some
styles in MaterialUi,
you pass an object to the withStyles
function that returns another object with
the same keys that contains the class names as values.
While this is easily representable in Typescript for example, there is no
straight forward way to do this in ReScript
. This is where the PPX comes in.
You pass an object in and it automatically generates all needed types and function applications for you. This keeps the tedious and quite verbose work from you while staying completely type safe when accessing the generated class names.
Usage
The extension is used by defining a module and passing %makeStyles()
as the
module body. Think of %makeStyles()
as a function, that accepts either
- a record with all fields of type
ReactDOM.Style.t
- a function with a theme argument that returns above record
The resulting module contains a function called useStyles()
which you can use
as a hook inside of your React
component. That hook will return all record
keys with class names as their values.
Simple example
module Styles = %makeStyles({
root: ReactDOM.Style.make(~padding="20px", ()),
inner: ReactDOM.Style.make(~lineHeight="1.3em", ()),
})
@react.component
let make = () => {
let classes = Styles.useStyles()
<div className=classes.root>
<div className=classes.inner>
{"Content"->React.string}
</div>
</div>
}
Working with a theme
module Styles = %makeStyles(
theme => {
root: ReactDOM.Style.make(~padding=`${theme.spacing(3)->string_of_int}px`, ()),
inner: ReactDOM.Style.make(~color=theme.palette.primary.main, ()),
}
)
@react.component
let make = () => {
let classes = Styles.useStyles()
<div className=classes.root>
<div className=classes.inner>
{"Content"->React.string}
</div>
</div>
}