storybook-addon-recoil-flow
Version:
Shows a graph of the current recoil state
50 lines (49 loc) • 2.48 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
import { useEffect } from "react";
import { makeDecorator, useChannel, useCallback } from "@storybook/preview-api";
import { useRecoilNodesAndEdges } from "../hooks/useRecoilNodesAndEdges";
import { RecoilRoot } from "recoil";
const RecoilSnooper = ({ emit, allowedKeys, showConnected, }) => {
const { edges, nodes } = useRecoilNodesAndEdges();
let filteredNodes = [...nodes];
if (allowedKeys.length > 0)
filteredNodes = nodes.filter(({ id }) => allowedKeys.some((k) => id.startsWith(k)));
if (allowedKeys && showConnected) {
const connectedNodes = new Set();
do {
filteredNodes.push(...Array.from(connectedNodes));
const filteredNodeKeys = filteredNodes.map(({ id }) => id);
connectedNodes.clear();
edges.forEach(({ source, target }) => {
const sourceKnown = filteredNodeKeys.includes(source);
const targetKnown = filteredNodeKeys.includes(target);
if (sourceKnown !== targetKnown) {
const targetNode = nodes.find(({ id }) => id === target);
const sourceNode = nodes.find(({ id }) => id === source);
if (sourceKnown && targetNode)
connectedNodes.add(targetNode);
if (targetKnown && sourceNode)
connectedNodes.add(sourceNode);
}
});
} while (connectedNodes.size > 0);
}
useEffect(() => {
emit("recoil-flow-changed", { nodes: filteredNodes, edges });
}, [edges, nodes]);
return null;
};
export const withRecoilFlow = makeDecorator({
name: "withRecoilFlow",
parameterName: "recoilFlow",
wrapper: (storyFn, {}, { parameters = {} }) => {
var _a, _b, _c;
const emit = useChannel({}, []);
const emitCallback = useCallback((eventName, data) => {
emit(eventName, data);
}, []);
const allowedKeys = ((_a = parameters.filter) === null || _a === void 0 ? void 0 : _a.keys) || [];
const showConnected = (_c = (_b = parameters.filter) === null || _b === void 0 ? void 0 : _b.showConnected) !== null && _c !== void 0 ? _c : true;
return (_jsxs(RecoilRoot, { override: false, children: [_jsx(RecoilSnooper, { emit: emitCallback, allowedKeys: allowedKeys, showConnected: showConnected }), storyFn()] }));
},
});