Here is yet another plugin RFC, what do you think?
More details and examples to come
// example-sidebar-plugin.tsx
import {
useSidebarPlugin,
useOpExecutionState,
useSetting,
useRegisterSetting,
Panel,
Toolbar,
PanelContent,
} from "@graphiql/react";
import NetworkIcon from "./icon.svg";
function formatIfJson(data) {
try {
const parsedJSON = JSON.parse(data);
return JSON.stringify(parsedJSON, null, 2);
} catch {
return data;
}
}
function MyCustomSidebar({ onClose }) {
// this would trigger a re-render on each operation execution
const { response } = useOpExecutionState();
// this might be almost impossible to provide easy type inference for but we will see
const formatJsonHeaders = useSetting("networkTab.formatJsonHeaders");
return (
<Panel>
<Toolbar title="Network" handleClose={onClose} expandable />
<PanelContent>
<h2>Headers</h2>
<table>
<thead>
<td>Name</td>
<td>Value</td>
</thead>
<tbody>
{Object.keys(response.headers).map((header) => (
<tr>
<td>{header}</td>
<td>
{formatJsonHeaders
? formatIfJson(response.headers[header])
: response.headers[header]}
</td>
</tr>
))}
</tbody>
</table>
</PanelContent>
</Panel>
);
}
export function PluginComponent() {
// this would be rendered on init,
// and push to a plugin registry state, for example in zustand or jotai
useSidebarPlugin({
title: "Network",
icon: NetworkIcon,
Component: (props) => <MyCustomSidebar {...props} />,
});
useRegisterSetting("networkTab.formatJsonHeaders", {
initialValue: true,
type: "boolean",
widget: "toggle",
});
return <></>;
}