Write a toolbar
// ==BundlewareToolbar==
// @id my-counter
// @name My Counter
// @version 1.0.0
// @description A small local counter.
// @match <all_urls>
// @api 2
// ==/BundlewareToolbar==
const { Toolbar, Action, Icon, store, useStore } = Bundleware;
const counter = store({ count: 0 });
function MyCounter() {
const [state, setState] = useStore(counter);
return (
<Toolbar icon={Icon.Palette} theme={{ brandColor: '#315b87' }}>
<Toolbar.Button title={`Count: ${state.count}`} icon={Icon.Sound} onAction={() => setState({ count: state.count + 1 })} />
<Toolbar.Button title="Details" action={<Action.OpenWindow title="Counter" target={<Details />} />} />
</Toolbar>
);
}
function Details(props) {
const [state] = useStore(counter);
return <><p>Clicked {state.count} times.</p><button onClick={props.close}>Done</button></>;
}
Bundleware.defineToolbar(<MyCounter />);examples/toolbar-script/ has more. The bundled
toolbars in src/toolbars/ are written the same way, in TypeScript, and checked with
strict by src/toolbars/tsconfig.json. For checking
and completion in any editor, put public/bundleware.d.ts
beside your script with a tsconfig.json like that one: "jsx": "react",
"jsxFactory": "Bundleware.h", "jsxFragmentFactory": "Bundleware.Fragment",
"moduleDetection": "force" and "types": []. The API's types are in the
BundlewareAPI namespace: function Details(props: BundlewareAPI.WindowProps & { id: string }), const theme: BundlewareAPI.ToolbarTheme = {…}, useRef<HTMLInputElement>(null).
A window body's close is given by the host, so openWindow(<Details id="a" />, …)
need not pass it. For a .jsx script, the example's jsconfig.json and
// @ts-check with JSDoc types do the same.