@levelchat/react-components
v0.1.2
Published
LevelChat React component kit — SDK-wired video, meeting, and pre-call primitives. Headless hooks + styled components + slot composition.
Readme
@levelchat/react-components
Production-grade React UI kit for LevelChat. Headless hooks + styled
components + slot composition, all reading from @levelchat/brand design
tokens so theming is one stylesheet override away.
This is the kit you reach for when you want a complete, working
video-meeting UI in one import. Pair it with @levelchat/web-react's
<LevelChatProvider> to get auto-wired components.
For marketing / docs chrome (Button, Nav, PricingCard, CodeBlock, etc.)
see @levelchat/marketing-ui.
Install
pnpm add @levelchat/react-components @levelchat/webQuick start
import { LevelChatProvider } from '@levelchat/web-react';
import {
VideoTile,
ControlBar,
PreJoin,
} from '@levelchat/react-components';
import '@levelchat/brand/tokens.css';
import '@levelchat/react-components/styles.css';
export function MeetingRoom({ token, participantId }) {
return (
<LevelChatProvider autoJoin={{ token }}>
<VideoTile participantId={participantId} />
<ControlBar />
</LevelChatProvider>
);
}Components
This release ships three production-grade components plus two supporting indicators:
| Component | Default props | Hook |
| ----------------- | ------------------------------ | --------------------- |
| <VideoTile> | participantId, source | useVideoTrack |
| <ControlBar> | density, show | useControlBar |
| <PreJoin> | onJoin, initialDisplayName | usePreJoin |
| <MicIndicator> | muted, surface | useMicState |
| <NetworkIndicator> | quality, asDot | useConnectionQuality|
Each styled component supports two modes:
- Hook-driven — pass
participantIdand the component subscribes to the activeRoomautomatically. - Prop-driven — pass explicit visual props (
name,muted,mediaStream, etc.) and the component renders without touching the SDK. Used by marketing tiles, Storybook, and tests.
Slot composition
Every styled component also exposes a slot map for Radix-style headless composition. The default styled output equals the default composition; reach for slots when you need a custom layout.
<VideoTile.Container aspect="16:9">
<VideoTile.Video stream={stream} mirror />
<VideoTile.Overlay>
<YourCaptions />
</VideoTile.Overlay>
<VideoTile.Name name="Mira Saito" />
<VideoTile.MicIndicator muted={false} />
<VideoTile.NetworkIndicator quality="good" asDot />
</VideoTile.Container><ControlBar>
<ControlBar.MicButton />
<ControlBar.CameraButton />
<ControlBar.Custom icon={Hand} label="Raise hand" onPress={raise} />
<ControlBar.LeaveButton />
</ControlBar><PreJoin onJoin={join}>
<PreJoin.Preview />
<PreJoin.NameInput />
<PreJoin.DeviceMenu kind="mic" />
<PreJoin.MicLevel />
<PreJoin.JoinButton />
</PreJoin>Theming
All colors, radii, shadows, and motion timings read from CSS variables
defined in @levelchat/brand/tokens.css. Override any variable in your
own stylesheet to retheme the kit without changing component code:
:root {
--lc-brand-primary: #ff3366; /* accent color used by ControlBar */
--lc-radius-tile: 20px; /* VideoTile corner radius */
--lc-shadow-tile: 0 4px 12px rgba(0,0,0,.1);
--lc-danger-solid: #d33; /* MicIndicator muted bg */
}The Tailwind preset from @levelchat/brand/tailwind.preset.js exposes
the same tokens under the lc-* namespace if you prefer utility classes.
License
MIT. See LICENSE.
