LevelChatLevelChatDocs
ControlBar

Components

ControlBar

The floating glass bar at the bottom of every meeting.

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/web

Requirements

  • Reactreact and react-dom ^18 || ^19 (peer dependency).
  • LevelChat Web SDK@levelchat/web ^0.2.4 (peer dependency, wires hook-driven mode to the live Room).
  • Provider — wrap the tree in <LevelChatProvider> from @levelchat/web-react so hook-driven mode can subscribe to room events. Prop-driven demos work without it.
  • Styles — import the brand tokens + kit stylesheet exactly once at the app entry, before any kit component renders.

In Next.js (App Router), import the stylesheets at the top of your root layout:

TypeScript (TSX)
// app/layout.tsx
import '@levelchat/brand/tokens.css';
import '@levelchat/react-components/styles.css';

In Vite (or any plain React app), import them at the top of your entry module:

TypeScript (TSX)
// src/main.tsx
import '@levelchat/brand/tokens.css';
import '@levelchat/react-components/styles.css';

Basic usage

Drop inside a provider and the bar auto-wires to the active room:

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

PropTypeDefaultNotes
density'default' | 'compact'defaultShrinks buttons for tight layouts.
show{ mic?, cam?, screen?, record?, leave? }all on except recordToggle individual buttons.
childrenReactNodeWhen set, replaces the default layout with composed slots.
ControlBar — LevelChat Docs