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-felayarn add fela react-felaIn 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-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: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>;};