Skip to content
kerfjsGitHub

ControlBar

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

SourcePackage @kerf-js/veneer

Preview

tsx
import { state } from '@kerf-js/core'import { ControlBar, Stack, Text } from '@kerf-js/veneer'export function Call() {  const {    mic,    camera,    sharing,    hand,    side,    onToggle,    onLeave,    said,  } = useControls()  return (    <Stack      gap="related"      align="center"    >      <ControlBar        mic={mic.value}        camera={camera.value}        sharing={sharing.value}        hand={hand.value}        side={side.value}        onToggle={onToggle}        onLeave={onLeave}      />      <Text        role="caption"        subtle      >        {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 @kerf-js/veneer

Usage

tsx
import { ControlBar } from '@kerf-js/veneer'

Compact

Icons only, with Chat and People left for More.

tsx
import { state } from '@kerf-js/core'import { ControlBar, Stack, Text } from '@kerf-js/veneer'export function Compact() {  const {    mic,    camera,    sharing,    hand,    onToggle,    onLeave,    said,  } = useControls()  return (    <Stack      gap="related"      align="center"    >      <ControlBar        compact        mic={mic.value}        camera={camera.value}        sharing={sharing.value}        hand={hand.value}        onToggle={onToggle}        onLeave={onLeave}      />      <Text        role="caption"        subtle      >        {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"]

controlleave

RelatedMeeting room