ControlBar is the always-on chrome at the bottom of a meeting. Mic, camera, screen-share, record, and leave buttons in a single pill — slot-composable for custom button orders and app-specific actions.
Install
pnpm add @levelchat/react-components @levelchat/webBasic usage
Drop inside a provider and the bar auto-wires to the active room:
import { ControlBar } from '@levelchat/react-components';
export function MeetingChrome() {
return <ControlBar />;
}Toggle individual buttons via the show prop:
<ControlBar show={{ record: true, screen: false }} density="compact" />Headless hook
Use useControlBar when you need a fully bespoke render — the hook returns the same state machine the styled component consumes:
import { useControlBar } from '@levelchat/react-components';
function MyToolbar() {
const { mic, cam, screen, recording, leave } = useControlBar();
return (
<div>
<button onClick={mic.toggle}>{mic.on ? 'Mute' : 'Unmute'}</button>
<button onClick={cam.toggle}>{cam.on ? 'Stop video' : 'Start video'}</button>
<button onClick={leave}>Leave</button>
</div>
);
}Slot composition
Render slot children to control the layout exactly. Custom buttons live in <ControlBar.Custom>:
import { ControlBar } from '@levelchat/react-components';
import { Hand } from 'lucide-react';
<ControlBar>
<ControlBar.MicButton />
<ControlBar.CameraButton />
<ControlBar.Custom icon={Hand} label="Raise hand" onPress={raiseHand} />
<ControlBar.LeaveButton />
</ControlBar>Theming
--lc-tile-glass-bg— the bar background.--lc-brand-primary— accent for active buttons.--lc-danger-solid— leave + active record buttons.--lc-shadow-glass— drop shadow.
:root {
--lc-tile-glass-bg: rgba(20, 22, 30, .7);
--lc-brand-primary: #ff3366;
}Props
| Prop | Type | Default | Notes |
|---|---|---|---|
density | 'default' | 'compact' | default | Shrinks buttons for tight layouts. |
show | { mic?, cam?, screen?, record?, leave? } | all on except record | Toggle individual buttons. |
children | ReactNode | — | When set, replaces the default layout with composed slots. |