MeetingRoom
A whole video call: tiles, layouts, people, chat and controls.
SourcePackage @kerf-js/veneer
Preview
tsx
import { state } from '@kerf-js/core'import { Button, Card, Inset, MeetingRoom, Text} from '@kerf-js/veneer'import type { Participant } from '@kerf-js/veneer'import type { Invite } from '@kerf-js/veneer'export function Incident() { const left = state(false) return ( <div style="block-size:560px"> {left.value ? ( <Card title="You left the incident review" sweep={false} > <Button onClick={() => (left.value = false)}> Rejoin </Button> </Card> ) : ( <MeetingRoom title="Incident review" timer="12:48" recording participants={CALL} self={CALL_SELF} presenter="Sam" shareTitle="Incident timeline" share={SLIDE} chat={CHAT} invite={INVITE} onLeave={() => (left.value = true)} /> )} </div> )}const CALL: Participant[] = [ { id: 'sam', name: 'Sam Okafor', role: 'host', isSpeaking: true, }, { id: 'jun', name: 'Jun Tanaka', isMuted: true }, { id: 'ines', name: 'Inés Vidal' }, { id: 'mara', name: 'Mara Lindqvist', handRaised: true, }, { id: 'lena', name: 'Lena Fischer', isMuted: true, network: 'poor', }, { id: 'tomas', name: 'Tomás Oliveira', isCamOn: false },]const CALL_SELF: Participant = { id: 'priya', name: 'Priya Raman',}const CHAT = () => ( <Inset pad="group"> <Text subtle> Sam: the rollback finished at 15:41. </Text> </Inset>)const SLIDE = () => ( <Inset pad="section"> <Text role="heading">mobile-bff timeline</Text> </Inset>)const INVITE = () => ( <Button emphasis="outline" tone="neutral" size="sm" full > Invite people </Button>)Installation
npm install @kerf-js/veneerUsage
tsx
import { MeetingRoom } from '@kerf-js/veneer'On a phone
compact shows the speaker, and icons only.
tsx
import { Inset, MeetingRoom, Text } from '@kerf-js/veneer'import type { Participant } from '@kerf-js/veneer'export function Phone() { return ( <div style="block-size:620px"> <MeetingRoom compact title="Incident review" timer="12:48" participants={CALL} self={CALL_SELF} chat={CHAT} /> </div> )}const CALL: Participant[] = [ { id: 'sam', name: 'Sam Okafor', role: 'host', isSpeaking: true, }, { id: 'jun', name: 'Jun Tanaka', isMuted: true }, { id: 'ines', name: 'Inés Vidal' }, { id: 'mara', name: 'Mara Lindqvist', handRaised: true, }, { id: 'lena', name: 'Lena Fischer', isMuted: true, network: 'poor', }, { id: 'tomas', name: 'Tomás Oliveira', isCamOn: false },]const CALL_SELF: Participant = { id: 'priya', name: 'Priya Raman',}const CHAT = () => ( <Inset pad="group"> <Text subtle> Sam: the rollback finished at 15:41. </Text> </Inset>)Accessibility
- Raised hands are announced. Who is speaking is not, or it would never stop.
- Veneer never touches the camera or microphone: media is yours.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | — | The heading. |
participants | Participant[] | { value: Participant[]; } | (() => Participant[]) | — | Everyone but you. |
self | Participant | — | You. |
layout | MeetingLayout | State<MeetingLayout> | — | gallery, speaker, presentation or board. |
timer | unknown | — | Elapsed time, already formatted. |
recording | boolean | false | Shows a Rec badge in the header. |
live | string | (() => string) | — | The room's connection. |
compact | boolean | false | For a phone. Unset, it follows the room's width. |
theme | "dark" | "light" | — | Dark unless you say otherwise. |
video | Video | — | Return the <video> for a participant. |
share | (() => unknown) | — | The shared screen. |
presenter | string | — | Who is sharing. |
shareTitle | string | — | What is being shared, in the presentation header. Default "Shared screen". |
board | (() => unknown) | — | The whiteboard. |
chat | (() => unknown) | — | The Chat panel. |
invite | (() => unknown) | — | Below People. |
mic | boolean | State<boolean> | — | Whether your mic is on: a state the room writes, or a value with onMic. |
camera | boolean | State<boolean> | — | Whether your camera is on: a state the room writes, or a value with onCamera. |
hand | boolean | State<boolean> | — | Whether your hand is raised: a state the room writes, or a value with onHand. |
sharing | boolean | State<boolean> | — | Whether you are sharing your screen: a state the room writes, or a value with onShare. |
sidebar | "chat" | "people" | State<"chat" | "people" | null> | null | — | The open side panel, people or chat, or null for none. |
reaction | string | — | The emoji the React button sends. Default 🎉. |
| Event | Type | Default | Description |
|---|---|---|---|
onLayoutChange | ((l: MeetingLayout) => void) | — | Called with the layout picked in the switcher. |
onMic | ((on: boolean) => void) | — | Called with the mic's new state. Start or stop the track here. |
onCamera | ((on: boolean) => void) | — | Called with the camera's new state. Start or stop the track here. |
onHand | ((on: boolean) => void) | — | Called with true when you raise your hand and false when you lower it. |
onShare | ((on: boolean) => void) | — | Called with true to start sharing your screen and false to stop. |
onReact | ((emoji: string) => void) | — | Called with the emoji when you react. |
onLeave | (() => void) | — | Called when Leave is pressed. |
onMore | (() => void) | — | More: replaces the phone's default, which opens the People and Chat panel. |
RelatedTileControl barPrejoin