useWindow hook
The useWindow hook exposes the Window API to any component.
Wrap the tree in a WindowProvider
useWindow reads the API from the nearest WindowProvider. Render the provider
above every component that needs the API — including the one that renders the
Window itself.
import { Window, WindowProvider, useWindow } from 'react-bwin';
import 'react-bwin/react-bwin.css';
export default function App() {
return (
<WindowProvider>
<Toolbar />
<Window />
</WindowProvider>
);
}
The Window registers its API with the provider when it mounts, so any sibling
or descendant of the provider can reach it through useWindow — they don't need
to be related to the Window component directly.
Call the API
Call useWindow inside a component and destructure the methods you need. They
forward to the live Window, so call them from event handlers, effects, or
anywhere else.
function Toolbar() {
const { addPane, removePane, setTheme } = useWindow();
return (
<>
<button
onClick={() =>
addPane('pane-2', {
position: 'bottom',
size: 120,
title: 'Pane 3',
content: <em>Pane 3</em>,
})
}
>
Add pane
</button>
<button onClick={() => removePane('pane-2')}>Remove pane</button>
<button onClick={() => setTheme('dark')}>Dark</button>
<button onClick={() => setTheme('')}>Light</button>
</>
);
}
See Add a pane, Update a pane, Remove a pane, Customize actions, Detached glass, Windowless glass, and Theme for live examples.
Subscribe to events
The hook also exposes on/off for events.
Subscribe in an effect and unsubscribe in its cleanup so the listener is removed
when the component unmounts. Pass the same function reference to both on and
off.
function PaneLogger() {
const { on, off } = useWindow();
useEffect(() => {
const handleAdd = (sash) => console.log('pane added', sash.id);
on('pane-add', handleAdd);
return () => off('pane-add', handleAdd);
}, [on, off]);
return null;
}
Listeners fire outside React's render cycle, so set React state yourself if a listener should update the UI.
Render a Window before calling the API
The API is only available once a Window has mounted inside the provider.
Calling a method before then throws an error. Trigger calls from user
interactions or effects that run after mount, not during the first render.
Stable references
Every method returned by useWindow — on, off, setTheme, and the rest —
keeps a stable identity for the lifetime of the component. It's therefore safe
to list them in an effect's dependency array (as with [on, off] and
[setTheme] above) without the effect re-running on every render.
function DarkOnMount() {
const { setTheme } = useWindow();
useEffect(() => {
setTheme('dark');
}, [setTheme]); // setTheme is stable, so this runs only once
}