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
createComponentorconnect, we recommend using bs-react-fela instead.
yarn add reason-fela
# you'll also need at least fela and react-fela
yarn add fela react-felaIn your bsconfig.json, include "reason-fela" in the bs-dependencies.
First let's create our Fela renderer. We can pass all the configs that the Fela renderer accepts.
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-",
()
)
)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.remodule and access it directly due to all files/modules being globally available.
open ReactFela;
let theme = {
"colors": {
"primary": Css.blue,
"secondary": Css.red
}
};
[@react.component]
let make = (~children) =>
<RendererProvider renderer>
<ThemeProvider theme>
children
</ThemeProvider>
</RendererProvider>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.
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>;
};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>;
};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.
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 */
});You can also opt-in bs-css-core module which was forked from bs-css for a more convenient, type-safe API.
yarn add @astrada/bs-css-coreIn 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:
external fromBsCssCore: Css.style => Fela.style = "%identity";Now we can use it in our components:
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>;
};