1

To learn and , I'm working on a simple “Things 2 Do” app (see source code on GitHub).

I have a TodoItem component that should be rendered with strike-through style when the item has been completed.

I try to solve this by creating a record with various styles, similar to CSS classes, one root style and one for completed items.

type style = {
  root: ReactDOMRe.style,
  completed: ReactDOMRe.style
};

let styles = {
  root: ReactDOMRe.Style.make(), /* add root styles here */
  completed: ReactDOMRe.Style.make(~opacity="0.666", ~textDecoration="line-through", ())
};

If the prop completed is true, I combine the root style with the completed style, otherwise I just use the root, like this:

let style = styles.root;
let style = item.completed ? ReactDOMRe.Style.combine(style, styles.completed) : style;

This works, but it seems clunky, so I'm wondering: Is there a more elegant solution, e.g. using a variant and a switch statement?

What is the idiomatic way to create styles for a Reason-React component that depend on props?

Here is the full code of my component:

type item = {
  id: int,
  title: string,
  completed: bool
};

type style = {
  root: ReactDOMRe.style,
  completed: ReactDOMRe.style
};

let str = ReasonReact.stringToElement;

let component = ReasonReact.statelessComponent("TodoItem");

let styles = {
  root: ReactDOMRe.Style.make(), /* add root styles here */
  completed: ReactDOMRe.Style.make(~opacity="0.666", ~textDecoration="line-through", ())
};

let make = (~item: item, ~onToggle, _) => {
  ...component,
  render: (_) => {
    let style = styles.root;
    let style = item.completed ? ReactDOMRe.Style.combine(style, styles.completed) : style;
    <div style>
      <input
        _type="checkbox"
        onChange=((_) => onToggle())
        checked=(Js.Boolean.to_js_boolean(item.completed))
      />
      <label> (str(item.title)) </label>
    </div>
  }
};
Patrick Hund
  • 19,163
  • 11
  • 66
  • 95

2 Answers2

3

I don't think there's anything that can be called idiomatic yet. The area is quickly changing, and even I have some ideas of my own on how to improve it, but this is more or less how I do it now using bs-css:

module Styles = {
  open Css;

  let root = completed => style([
    color(white),
    opacity(completed ? 0.666 : 1.),
    textDecoration(completed ? LineThrough : None)
  ]);
}

...

  render: _self =>
    <div className=Styles.root(item.completed)>
      ...
    </div>
glennsl
  • 28,186
  • 12
  • 57
  • 75
0

For now, the way I'm styling my component is OK. There is not really an idiomatic way for styling React components in Reason yet.

The Reason documentation has this to say:

Since CSS-in-JS is all the rage right now, we'll recommend our official pick soon. In the meantime, for inline styles, there's the ReactDOMRe.Style.make API

Patrick Hund
  • 19,163
  • 11
  • 66
  • 95