Usage with ReasonML

The Reason bindings ship with some core Fela APIs, React hooks and all plugins, enhancers and presets.

Note: If you want to use older APIs such as

createComponent
or
connect
, we recommend using bs-react-fela(new tab) instead.

yarn add reason-fela
# you'll also need at least fela and react-fela
yarn add fela react-fela

In your

bsconfig.json
, include
"reason-fela"
in the
bs-dependencies
.

Creating a Fela renderer

First let's create our Fela Renderer instance. We can pass all the config options that the Fela renderer accepts.

FelaRenderer.re

open Fela;
/* you can also use all plugins and enhancers via Fela.Plugins and Fela.Enhancers
e.g. Fela.Plugins.prefixer, Fela.Enhancers.web */
let renderer = Renderer.make(
RendererConfig.make(
~plugins=Presets.web,
~selectorPrefix="reason-",
()
)
)

Passing the Renderer

Now that we have the renderer, we need to provide it to our app.
We can also optionally pass a theme down here, which is useful for dynamic theming.

Tip: If we just want to define some static theme properties, one can also leverage a

Theme.re
module and access it directly due to all files/modules being globally available.

App.re

open ReactFela;
let theme = {
"colors": {
"primary": "blue",
"secondary": "red"
}
};
[@react.component]
let make = (~children) =>
<RendererProvider renderer>
<ThemeProvider theme>
children
</ThemeProvider>
</RendererProvider>

Using the Hooks

Now that our app is aware of the renderer, we can use the provided hooks in any component. The hooks are similar to react-fela's useFela, but split into 3 different hooks for convenience.

RedText.re

open ReactFela;
[@react.component]
let make = (~children) => {
let css = useFela();
let theme = useTheme();
let renderer = useRenderer();
/* we can also do stuff we the renderer */
renderer##renderStatic(Fela.style({"backgroundColor": "red"}), "body");
<div
className={css([
Fela.style({"fontSize": "18pt", "color": theme##colors##primary}),
])}>
"I'm red"->React.string
</div>;
};

Convenience Hooks

ReactFela also includes two convenience hooks

useFela1
and
useFela2
that take just 1 or 2 parameters respectively instead of passing a list.

open ReactFela;
[@react.component]
let make = (~children) => {
let css1 = useFela1();
let css2 = useFela2();
<div className={css1(Fela.style({"color": "red"}))}>
<div
className={css2(
Fela.style({"color": "red"}),
Fela.style({"color": "red"}),
)}
/>
</div>;
};

Server-side Rendering

If we're running a universal app, we also want to make sure that styles are correctly rendered and rehydrated when doing server-side rendering.
Therefore, reason-fela also provides bindings to fela-dom.

Server.re

open Fela.Dom;
let htmlString = renderToMarkup(renderer);
let sheetList = renderToSheetList(renderer);
sheetList -> Belt.Array.forEach(({type_, css, media, support, rehydration}) => {
/* render your style nodes here */
});

Using bs-css-core

You can also opt-in bs-css-core(new tab) module which was forked from bs-css(new tab) for a more convenient, type-safe API.

yarn add @astrada/bs-css-core

In your

bsconfig.json
, include
"@astrada/bs-css-core"
in the
bs-dependencies
.

Now the only thing we need is a type converter which can be done using the

"%identity"
helper. You probably want to create a new utility mode e.g.
FelaUtils
that looks sth. like this:

FelaUtils.re

external fromBsCssCore: Css.style => Fela.style = "%identity";

Now we can use it in our components:

RedText.re

open ReactFela;
open FelaUtils;
open Css;
[@react.component]
let make = (~children) => {
let css = useFela();
let theme = useTheme();
let renderer = useRenderer();
/* we can also do stuff we the renderer */
renderer##renderStatic(
fromBsCssCore(style([backgroundColor(black)])),
"body",
);
<div
className={css([
fromBsCssCore(
style([fontSize(pt(18)), color(theme##colors##primary)]),
),
])}>
"I'm red"->React.string
</div>;
};