Using Jeremy Ashkenas's guide on how to embed a notebook on React, I refactored the component as a function component.
- Make the embedable work on Framer X
- Map the controls as Framer X Control Props
Using Jeremy Ashkenas's guide on how to embed a notebook on React, I refactored the component as a function component.
| import * as React from 'react' | |
| import { useState, useEffect, useRef } from 'react' | |
| import { Frame, addPropertyControls, ControlType } from 'framer' | |
| import { Runtime, Inspector } from '@observablehq/runtime' | |
| import notebook from '@davo/bar-chart-race' | |
| export function Observable({ tick }) { | |
| const [tickDuration, setTickDuration] = useState(tick) | |
| const animationRef = useRef() | |
| useEffect(() => { | |
| const runtime = new Runtime() | |
| runtime.module(notebook, name => { | |
| if (name === 'chart') { | |
| return new Inspector(animationRef.current) | |
| } | |
| if (name === 'mutable tickDuration') { | |
| return { | |
| fulfilled: value => { | |
| this.tick = value | |
| } | |
| } | |
| } | |
| }) | |
| }, [tick]) | |
| useEffect(() => { | |
| setTickDuration(tick) | |
| }, [tick]) | |
| return ( | |
| <Frame size={'100%'} background={null}> | |
| <div ref={animationRef} /> | |
| </Frame> | |
| ) | |
| } | |
| Observable.defaultProps = { | |
| tick: 500 | |
| } | |
| addPropertyControls(Observable, { | |
| tick: { | |
| type: ControlType.Number, | |
| title: 'Duration', | |
| defaultValue: Observable.defaultProps.tick, | |
| min: 0, | |
| max: 5000, | |
| step: 1, | |
| displayStepper: false | |
| } | |
| }) |