hyperstack

How do you convert this JSX to Hyperstack?


How would you convert this JSX into a Hyperstack Component?

const Stopwatch = () => (
  <ReactStopwatch
    seconds={0}
    minutes={0}
    hours={0}
    limit="00:00:10"
    onChange={({ hours, minutes, seconds }) => {
      // do something
    }}
    onCallback={() => console.log('Finish')}
    render={({ formatted, hours, minutes, seconds }) => {
      return (
        <div>
          <p>
            Formatted: { formatted }
          </p>
          <p>
            Hours: { hours }
          </p>
          <p>
            Minutes: { minutes }
          </p>
          <p>
            Seconds: { seconds }
          </p>
        </div>
      );
    }}
   />
);

This syntax render={({ formatted, hours, minutes, seconds }) is new to me. Are these props?

I am trying to use this NPM module:

https://www.npmjs.com/package/react-stopwatch


Solution

  • The render prop renders a functional component. A functional component is a function, such that the arguments are props, and the return value is the component to be rendered.

    Therefor, we need to convert your render prop to opal.

        DIV do
          P { "Formatted: #{native_props.formatted}" }
          P { "Hours: #{native_props.hours}" }
          P { "Minutes: #{native_props.minutes}" }
          P { "Seconds: #{native_props.seconds}" }
        end.to_n
    

    There's one gotcha here. The first is that props is being passed as a javascript object. We need that to be ruby, so we wrap it in Native.

    Step two is exposing the stopwatch class to Hyperstack.

    Under app/javascript/packs, edit hyperstack.js to include react-stopwatch.

    import ReactStopwatch from 'react-stopwatch';
    global.ReactStopwatch = ReactStopwatch;
    

    Now you can use Stopwatch in your code.

    Putting this together, you get:

    class Stopwatch < HyperComponent
      render do
        ReactStopwatch(seconds: 0, minutes: 0, hours: 0, limit: "00:00:10").on("<render>") do |props|
          DIV do
            P { "Formatted: #{props.formatted}" }
            P { "Hours: #{props.hours}" }
            P { "Minutes: #{props.minutes}" }
            P { "Seconds: #{props.seconds}" }
          end.to_n
        end
      end
    end