Skip to content
weftGitHub

ControlBar

The controls along the bottom of a call: mute, camera, share, leave.

SourcePackage @weft-js/warp

Preview

tsx
import { state } from '@weft-js/core'import { ControlBar, Stack, Text } from '@weft-js/warp'export function Call() {  const c = useControls()  return (    <Stack gap="related" align="center">      <ControlBar mic={c.mic.value} camera={c.camera.value} sharing={c.sharing.value} hand={c.hand.value} side={c.side.value} onToggle={c.onToggle} onLeave={c.onLeave} />      <Text role="caption" subtle>{c.said.value}</Text>    </Stack>  )}function useControls() {  const mic = state(true), camera = state(true), sharing = state(false), hand = state(false)  const side = state<'people' | 'chat' | null>(null)  const said = state('Use the bar, or Tab to it and press the arrow keys.')  const onToggle = (c: string) => {    if (c === 'mic') mic.value = !mic.value    if (c === 'camera') camera.value = !camera.value    if (c === 'share') sharing.value = !sharing.value    if (c === 'hand') hand.value = !hand.value    if (c === 'chat' || c === 'people') side.value = side.value === c ? null : c    said.value = `Pressed ${c}`  }  return { mic, camera, sharing, hand, side, said, onToggle, onLeave: () => (said.value = 'Left the call') }}

Installation

npm install @weft-js/warp

Usage

tsx
import { ControlBar } from '@weft-js/warp'

Compact

Icons only, with Chat and People left for More.

tsx
import { state } from '@weft-js/core'import { ControlBar, Stack, Text } from '@weft-js/warp'export function Compact() {  const c = useControls()  return (    <Stack gap="related" align="center">      <ControlBar compact mic={c.mic.value} camera={c.camera.value} sharing={c.sharing.value} hand={c.hand.value} onToggle={c.onToggle} onLeave={c.onLeave} />      <Text role="caption" subtle>{c.said.value}</Text>    </Stack>  )}function useControls() {  const mic = state(true), camera = state(true), sharing = state(false), hand = state(false)  const side = state<'people' | 'chat' | null>(null)  const said = state('Use the bar, or Tab to it and press the arrow keys.')  const onToggle = (c: string) => {    if (c === 'mic') mic.value = !mic.value    if (c === 'camera') camera.value = !camera.value    if (c === 'share') sharing.value = !sharing.value    if (c === 'hand') hand.value = !hand.value    if (c === 'chat' || c === 'people') side.value = side.value === c ? null : c    said.value = `Pressed ${c}`  }  return { mic, camera, sharing, hand, side, said, onToggle, onLeave: () => (said.value = 'Left the call') }}

Accessibility

Tab
Moves into the bar, and out
LeftandRight
Move between controls
  • It is a toolbar with one tab stop. Leave is the only solid button.

API Reference

PropTypeDefaultDescription
micboolean—Whether the mic is on.
cameraboolean—Whether the camera is on.
sharingbooleanfalseWhether you are sharing.
handbooleanfalseWhether your hand is up.
side"chat" | "people" | null—The open side panel.
compactbooleanfalseIcons only, no Chat or People (they go in More), and Leave icon-only.
morestring'More options'The name of the More button.
EventTypeDefaultDescription
onToggle(control: "camera" | "chat" | "hand" | "mic" | "more" | "share" | "peopl…—Gets the name of the control pressed.
onLeave(() => void)—Leave was pressed.

Parts

Every element carries a stable name, so you can style it from your own CSS: [data-scope="call-controls"] [data-part="control"]

controlleavegroup

RelatedMeeting room