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 useWindowon, 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
}