RealTimeX
Start For Free

RealTimeX

Package Documentation

IntroductionPrerequisitesInstallationProject setupQuick start
Package structureConfigurationComponentsHooksAPI integrationSocket events
OverviewReplace entire UIReplace componentsStyle with classNamesThemes & localePhone & video callingIn-call control barFeatures
TroubleshootingFAQVersion historyBest practicesSupport & contact

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.

tsx
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" },
    },
  }}
/>;

Note

Using the composable Chat provider instead of ChatMain? Pass it as uiConfig={{ features: { callControls: { … } } }}.

That's it — the call bar re-renders with your changes and every other button keeps working as before.

The button keys

KeyButton
micMute / unmute microphone
cameraCamera on/off (or "Switch to video call")
screenShareShare / stop sharing screen
recordStart / stop recording
raiseHandRaise / lower hand
chatOpen / close the in-call chat panel
participantsShow / hide the participants panel
reactionsEmoji reactions popover
leaveLeave / end the call

Note

Some buttons only appear in the right context — e.g. screenShare and camerashow once the call is a video call. Hiding a button that isn't currently shown is a no-op.

What you can set per button

Every key accepts a CallControlButtonConfig:

FieldTypeEffect
hiddenbooleanRemove the button entirely.
classNamestringExtra classes merged onto the default button.
labelstringOverride the tooltip / accessible label.
iconReact.ReactNodeReplace just the icon, keeping the default button shell.
render(ctx: CallControlRenderContext) => ReactNodeReplace the whole button. You render it; the action stays wired.

There's also a top-level className on callControls for the bar container:

tsx
callControls: {
  className: "bg-black/40 backdrop-blur", // the row wrapping all the buttons
}

Examples

Hide several buttons

tsx
callControls: {
  record: { hidden: true },
  raiseHand: { hidden: true },
  reactions: { hidden: true },
}

Swap an icon

tsx
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:

tsx
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

FieldTypeMeaning
keyCallControlKeyWhich control this is.
activebooleanWhether it is in its "on" state (muted, hand raised, panel open…).
labelstringThe resolved label (your label override, if any).
onClick() => voidRuns the built-in action. Call it from your element.
defaultIconReact.ReactNodeThe icon the package would have drawn.

TypeScript

All types are exported from the package:

typescript
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.
  • render and hidden take precedence over icon / label / className (a hidden button renders nothing; a render button 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.
PreviousPhone & video callingNextFeatures

On this page

OverviewQuick startThe button keysWhat you can set per buttonExamplesTypeScriptNotes