Package Reference
In-call control bar
Overview
The bottom toolbar in the built-in call UI (mic, camera, screen share, record, raise hand, chat, participants, reactions, and Leave) is fully customizable. You can hide any button, restyle it, swap its icon or label, or replace it entirely — all through the same customization prop you already pass to the chat, no forking required.
This page covers the controls inside an active call. For the call buttons in the conversation header, see Phone & video calling.
Quick start
Pass a callControls object on the features prop of ChatMain. Each key targets one button.
import ChatMain from "@realtimexsco/live-chat";
import { chatConfig } from "@/configs/chat.config";
<ChatMain
{...chatConfig}
features={{
callControls: {
// Hide a button completely
record: { hidden: true },
raiseHand: { hidden: true },
// Restyle a button (classes are merged onto the default)
leave: { className: "bg-black hover:bg-neutral-800" },
// Change a tooltip / accessible label
chat: { label: "Open messages" },
},
}}
/>;That's it — the call bar re-renders with your changes and every other button keeps working as before.
Examples
Hide several buttons
callControls: {
record: { hidden: true },
raiseHand: { hidden: true },
reactions: { hidden: true },
}Swap an icon
import { PhoneMissed } from "lucide-react";
callControls: {
leave: { icon: <PhoneMissed size={18} />, label: "Hang up" },
}Fully custom button with render
render receives the live state and the built-in action, so your button does exactly what the default one does — you only control how it looks:
callControls: {
mic: {
render: ({ active, label, onClick, defaultIcon }) => (
<button
type="button"
onClick={onClick} // toggles the mic for you
aria-label={label}
className={active ? "my-btn my-btn--muted" : "my-btn"}
>
{defaultIcon} {/* or your own icon */}
</button>
),
},
}CallControlRenderContext fields
| Field | Type | Meaning |
|---|---|---|
| key | CallControlKey | Which control this is. |
| active | boolean | Whether it is in its "on" state (muted, hand raised, panel open…). |
| label | string | The resolved label (your label override, if any). |
| onClick | () => void | Runs the built-in action. Call it from your element. |
| defaultIcon | React.ReactNode | The icon the package would have drawn. |
TypeScript
All types are exported from the package:
import type {
CallControlsConfig,
CallControlButtonConfig,
CallControlRenderContext,
CallControlKey,
} from "@realtimexsco/live-chat";Notes
- Omitting
callControls(or any individual key) keeps the default button — you only describe what you want to change. renderandhiddentake precedence overicon/label/className(a hidden button renders nothing; arenderbutton ignores the shell props).- The built-in actions (mute, screen share, recording, leave, …) always stay wired to
onClick, so a custom-rendered button can't accidentally break call behavior.