storybook-router
storybook-router copied to clipboard
reach-router support
Feature Request:
Are you using storybook-router with a react based project or a vue one?
React (Gatsby)
Context for the request
I've been using storybook-router
with components that use gatsby-link because it previously wrapped react-router
's Link
component.
However, that switched to using Reach Router. I haven't used react router yet to give much insight into what might be different, but it would be great to be able to continue using storybook-router
the same way.
thanks for continued efforts with this package. it has been a great addition to storybook!
Hi @travi, thank you for the suggestion. I'll have a look but unfortunately I will not be able before September.
not a problem. mostly wanted to get it on your radar for when it makes sense
Would this thread be helpful? https://spectrum.chat/reach/questions/using-reach-router-in-storybook~d6ed6f77-dad7-4c5a-8ad3-c7784a594d7b?authed=true
In the thread @mikebarkmin suggested to @theinterned to use, for inspiration, his (MIT licensed) @reach/router proxy for react-cosmos as seen at this mirror: https://github.com/openpatch/ui-core/blob/master/src/proxies/ReachRouterProxy.js
Btw, sorry in advance if I don't notice my notification of this thread being updated... Guess I need to change the settings on a mobile app to make important GitHub notifications more obtrusive...
I was able to add memory source support in Reach Router and Storyboard with the following decorator:
import {
LocationProvider,
createMemorySource,
createHistory
} from "@reach/router";
import React from "react";
import { makeDecorator } from "@storybook/addons";
export const withRouter = makeDecorator({
name: "router",
parameterName: "router",
skipIfNoParametersOrOptions: true,
wrapper: (getStory, context, { parameters = "/" }) => {
const source = createMemorySource(parameters);
const history = createHistory(source);
history.listen(() => console.log('message arrived at router', source.location));
return <LocationProvider history={history}>{getStory(context)}</LocationProvider>;
}
});
which I then include in all stories (though you don't have to) with:
import { withRouter } from "./addons/router";
addDecorator(withRouter);
In a story that I want to add Reach Router component rendering, I add a router
param with the initial path:
storiesOf(storyName(base))
.add("default app state", () => {
return <App />
}, { router: "/" });
The url of your app won't update as you navigate around, but it does tie into Reach Router in what looks like the desired approach. This does not attempt to tie into Storybook's <Link>
s.
I ran into a snag having the router work properly after changing any context (ex: changing "knob" value) and the issue seemed to stem from calling createHistory
multiple times. If I kept a reference to the first history object I could make navigate
calls, but otherwise they would trigger my listener but do nothing in the router.
Here's my current iteration of the code that memoizes the history object, but resets the router location when a story with the router
parameter is encountered:
import {
LocationProvider,
createMemorySource,
createHistory as createRouterHistory
} from "@reach/router";
import React from "react";
import { makeDecorator } from "@storybook/addons";
let firstHistoryObject = null;
function createHistory(initialPath) {
if (firstHistoryObject) {
firstHistoryObject.navigate(initialPath);
return firstHistoryObject;
}
const source = createMemorySource(initialPath);
firstHistoryObject = createRouterHistory(source);
firstHistoryObject.listen(() =>
console.log("message arrived at router", source.location)
);
return firstHistoryObject;
}
export const withRouter = makeDecorator({
name: "router",
parameterName: "router",
skipIfNoParametersOrOptions: true,
wrapper: (getStory, context, { parameters = "/" }) => {
return (
<LocationProvider history={createHistory(parameters)}>
{getStory(context)}
</LocationProvider>
);
}
});