Advanced step control
See original GitHub issueFollowing the discussion on #177, a feature I would love to have is an advanced form of Appear that would give great control on what happens at each step (i.e. not necessarily only making a component appear, but anything really).
My main use case is the control of D3.js updates, like filtering some data on a step, highlighting one particular bar, etc.
Original idea
My original idea was a Higher Order Component:
import withSteps from 'mdx-deck/with-steps'
withSteps(numberOfSteps, ({ step }) => {
// Render something using step.
return <span>Current step: {step}</span>
})
The above is just a functional component, but withSteps
would also allow relying on componentDidUpdate
to perform some low-level DOM operations, like updating a D3 chart:
import withSteps from 'mdx-deck/with-steps'
withSteps(numberOfSteps, class Chart extends React.Component {
constructor(props) {
super(props)
this.svgNode = React.createRef()
}
componentDidUpdate() {
const { step, data } = this.props
updateChart(this.svgNode.current, data, step)
}
render() {
return <svg ref={this.svgNode} />
}
})
However, as mentioned by @zcei, the issue with this approach is that it is not supported in mdx. As a result, it would require to create the component in a separate file (https://github.com/jxnblk/mdx-deck/issues/177#issuecomment-427588751).
step
and setStep
as properties
Instead, @zcei suggests a simple component that would provide step
and setStep
to its child (https://github.com/jxnblk/mdx-deck/issues/177#issuecomment-427579253):
<Steps>
{({ step, setSteps }) => {
// Do something with step and setSteps
}}
</Steps>
However, I believe passing setSteps
as a property is a bit weird. With functional components, it makes them intrinsically impure. Also, when should setSteps
be called? If the child is a functional component, that means it can only be called at render time 😵… And what happens if one calls setSteps
with a value lower than step
?
totalSteps
on the parent, and setStep
as a property
After some thoughts, an alternative could be:
<Steps totalSteps={4}>
{({ step }) => {
// Do something with step
}}
</Steps>
Note that I really wish <Steps>
would not only accept functional components but also class component. This is necessary to support low level DOM operations. Maybe:
<Steps totalSteps={4}>
{class SomeThing extends React.Component { /* */ }}
</Steps>
Issue Analytics
- State:
- Created 5 years ago
- Comments:5 (3 by maintainers)
Top GitHub Comments
V2 now has a
useSteps
hook that you can use in custom components. I’ll be adding docs soon, but peek at the source code forAppear
in the meantimeYes absolutely. The point is to make lifecycle hooks available.
I don’t think it is hard to do either. I don’t think a new dependency is required for this. I emphasized it just to make sure it does not get lost.