From 3850374f32d9726a2f51e89704f6855d2ee9583c Mon Sep 17 00:00:00 2001 From: Topher Hindman Date: Wed, 11 Feb 2026 09:09:26 -0800 Subject: [PATCH 1/8] feat(core,react): add showParticipants to WidgetState and reducer Add participants panel state management to the widget system. The WidgetState type and default state now include showParticipants. The chatReducer handles toggle_participants with mutual exclusivity - opening participants closes chat and vice versa. --- packages/core/src/types.ts | 2 ++ packages/react/src/context/chat-context.ts | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index cdbf36aa4..31474a764 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -12,11 +12,13 @@ export type WidgetState = { showChat: boolean; unreadMessages: number; showSettings?: boolean; + showParticipants?: boolean; }; export const WIDGET_DEFAULT_STATE: WidgetState = { showChat: false, unreadMessages: 0, showSettings: false, + showParticipants: false, }; // ## Track Source Types diff --git a/packages/react/src/context/chat-context.ts b/packages/react/src/context/chat-context.ts index 8499063b6..6134420aa 100644 --- a/packages/react/src/context/chat-context.ts +++ b/packages/react/src/context/chat-context.ts @@ -7,7 +7,8 @@ export type ChatContextAction = | { msg: 'hide_chat' } | { msg: 'toggle_chat' } | { msg: 'unread_msg'; count: number } - | { msg: 'toggle_settings' }; + | { msg: 'toggle_settings' } + | { msg: 'toggle_participants' }; /** @internal */ export type WidgetContextType = { @@ -18,19 +19,26 @@ export type WidgetContextType = { /** @internal */ export function chatReducer(state: WidgetState, action: ChatContextAction): WidgetState { if (action.msg === 'show_chat') { - return { ...state, showChat: true, unreadMessages: 0 }; + return { ...state, showChat: true, unreadMessages: 0, showParticipants: false }; } else if (action.msg === 'hide_chat') { return { ...state, showChat: false }; } else if (action.msg === 'toggle_chat') { const newState = { ...state, showChat: !state.showChat }; if (newState.showChat === true) { newState.unreadMessages = 0; + newState.showParticipants = false; } return newState; } else if (action.msg === 'unread_msg') { return { ...state, unreadMessages: action.count }; } else if (action.msg === 'toggle_settings') { return { ...state, showSettings: !state.showSettings }; + } else if (action.msg === 'toggle_participants') { + const newState = { ...state, showParticipants: !state.showParticipants }; + if (newState.showParticipants === true) { + newState.showChat = false; + } + return newState; } else { return { ...state }; } From 5d761196f8ea3336470f59da44dc295b543b25a7 Mon Sep 17 00:00:00 2001 From: Topher Hindman Date: Wed, 11 Feb 2026 09:18:26 -0800 Subject: [PATCH 2/8] feat(core,styles,react): add participants toggle setup, icon, and styles Add setupParticipantsToggle core function, participants-icon.svg with auto-generated ParticipantsIcon.tsx, and SCSS styles for both the toggle button (with count badge) and the participants sidebar panel. --- .../core/src/components/participantsToggle.ts | 6 ++ packages/core/src/index.ts | 1 + .../src/assets/icons/ParticipantsIcon.tsx | 25 +++++++ packages/react/src/assets/icons/index.ts | 1 + .../styles/assets/icons/participants-icon.svg | 6 ++ .../controls/_participants-toggle.scss | 20 ++++++ .../scss/components/controls/index.scss | 1 + packages/styles/scss/prefabs/index.scss | 1 + .../styles/scss/prefabs/participants.scss | 65 +++++++++++++++++++ 9 files changed, 126 insertions(+) create mode 100644 packages/core/src/components/participantsToggle.ts create mode 100644 packages/react/src/assets/icons/ParticipantsIcon.tsx create mode 100644 packages/styles/assets/icons/participants-icon.svg create mode 100644 packages/styles/scss/components/controls/_participants-toggle.scss create mode 100644 packages/styles/scss/prefabs/participants.scss diff --git a/packages/core/src/components/participantsToggle.ts b/packages/core/src/components/participantsToggle.ts new file mode 100644 index 000000000..a7cfbcfa7 --- /dev/null +++ b/packages/core/src/components/participantsToggle.ts @@ -0,0 +1,6 @@ +import { prefixClass } from '../styles-interface'; + +export function setupParticipantsToggle() { + const className: string = [prefixClass('button'), prefixClass('participants-toggle')].join(' '); + return { className }; +} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 432c8a028..ef4d51c17 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -19,6 +19,7 @@ export * from './components/chat'; export * from './components/startAudio'; export * from './components/startVideo'; export * from './components/chatToggle'; +export * from './components/participantsToggle'; export * from './components/focusToggle'; export * from './components/clearPinButton'; export * from './components/room'; diff --git a/packages/react/src/assets/icons/ParticipantsIcon.tsx b/packages/react/src/assets/icons/ParticipantsIcon.tsx new file mode 100644 index 000000000..592602473 --- /dev/null +++ b/packages/react/src/assets/icons/ParticipantsIcon.tsx @@ -0,0 +1,25 @@ +/** + * WARNING: This file was auto-generated by svgr. Do not edit. + */ +import * as React from 'react'; +import type { SVGProps } from 'react'; +/** + * @internal + */ +const SvgParticipantsIcon = (props: SVGProps) => ( + + + + +); +export default SvgParticipantsIcon; diff --git a/packages/react/src/assets/icons/index.ts b/packages/react/src/assets/icons/index.ts index 7425b1e9a..4d74a860b 100644 --- a/packages/react/src/assets/icons/index.ts +++ b/packages/react/src/assets/icons/index.ts @@ -9,6 +9,7 @@ export { default as LeaveIcon } from './LeaveIcon'; export { default as LockLockedIcon } from './LockLockedIcon'; export { default as MicDisabledIcon } from './MicDisabledIcon'; export { default as MicIcon } from './MicIcon'; +export { default as ParticipantsIcon } from './ParticipantsIcon'; export { default as QualityExcellentIcon } from './QualityExcellentIcon'; export { default as QualityGoodIcon } from './QualityGoodIcon'; export { default as QualityPoorIcon } from './QualityPoorIcon'; diff --git a/packages/styles/assets/icons/participants-icon.svg b/packages/styles/assets/icons/participants-icon.svg new file mode 100644 index 000000000..3a6995fcd --- /dev/null +++ b/packages/styles/assets/icons/participants-icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/packages/styles/scss/components/controls/_participants-toggle.scss b/packages/styles/scss/components/controls/_participants-toggle.scss new file mode 100644 index 000000000..e90a7516c --- /dev/null +++ b/packages/styles/scss/components/controls/_participants-toggle.scss @@ -0,0 +1,20 @@ +@use 'button'; + +.participants-toggle { + @extend .button; + position: relative; +} + +.participants-toggle[data-lk-participant-count]::after { + content: attr(data-lk-participant-count); + position: absolute; + top: 0; + left: 0; + padding: 0.25rem; + margin-left: 0.25rem; + margin-top: 0.25rem; + border-radius: 50%; + font-size: 0.5rem; + line-height: 0.75; + background: var(--accent-bg); +} diff --git a/packages/styles/scss/components/controls/index.scss b/packages/styles/scss/components/controls/index.scss index c92102698..bc8d0f24b 100644 --- a/packages/styles/scss/components/controls/index.scss +++ b/packages/styles/scss/components/controls/index.scss @@ -2,6 +2,7 @@ @use 'disconnect-button'; @use 'focus-toggle'; @use 'chat-toggle'; +@use 'participants-toggle'; @use 'media-device-select'; @use 'start-audio'; @use 'pagination-control'; diff --git a/packages/styles/scss/prefabs/index.scss b/packages/styles/scss/prefabs/index.scss index 5d8f5057c..4722d6700 100644 --- a/packages/styles/scss/prefabs/index.scss +++ b/packages/styles/scss/prefabs/index.scss @@ -2,5 +2,6 @@ @use 'audio-conference'; @use 'chat'; @use 'control-bar'; +@use 'participants'; @use 'prejoin'; @use 'video-conference'; diff --git a/packages/styles/scss/prefabs/participants.scss b/packages/styles/scss/prefabs/participants.scss new file mode 100644 index 000000000..d186dde26 --- /dev/null +++ b/packages/styles/scss/prefabs/participants.scss @@ -0,0 +1,65 @@ +.participants { + display: grid; + grid-template-rows: var(--chat-header-height) 1fr; + width: clamp(200px, 55ch, 60ch); + background-color: var(--bg2); + border-left: 1px solid var(--border-color); +} + +.participants-header { + height: var(--chat-header-height); + padding: 0.75rem; + position: relative; + display: flex; + align-items: center; + justify-content: center; + .close-button { + position: absolute; + right: 0; + transform: translateX(-50%); + background-color: transparent; + &:hover { + background-color: var(--lk-control-active-hover-bg); + } + } +} + +.participants-list { + display: flex; + width: 100%; + max-height: 100%; + flex-direction: column; + gap: 0.25rem; + overflow: auto; + padding: 0.25rem; +} + +.participant-entry { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 0.75rem; + border-radius: var(--border-radius); + + .participant-name { + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .track-muted-indicator-camera, + .track-muted-indicator-microphone { + flex-shrink: 0; + } +} + +@media (max-width: 600px) { + .participants { + position: fixed; + top: 0; + right: 0; + max-width: 100%; + bottom: var(--control-bar-height); + } +} From b267d6cdf5bdf685481fef7956d1f80ab7417d15 Mon Sep 17 00:00:00 2001 From: Topher Hindman Date: Wed, 11 Feb 2026 09:19:26 -0800 Subject: [PATCH 3/8] feat(react): add useParticipantsToggle hook and ParticipantsToggle component Add the toggle hook that dispatches toggle_participants to the widget reducer and displays the participant count badge. Add the ParticipantsToggle button component following the ChatToggle pattern with forwardRef. --- .../controls/ParticipantsToggle.tsx | 32 +++++++++++++++++ packages/react/src/components/index.ts | 1 + packages/react/src/hooks/index.ts | 4 +++ .../react/src/hooks/useParticipantsToggle.ts | 35 +++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 packages/react/src/components/controls/ParticipantsToggle.tsx create mode 100644 packages/react/src/hooks/useParticipantsToggle.ts diff --git a/packages/react/src/components/controls/ParticipantsToggle.tsx b/packages/react/src/components/controls/ParticipantsToggle.tsx new file mode 100644 index 000000000..e9109a7dc --- /dev/null +++ b/packages/react/src/components/controls/ParticipantsToggle.tsx @@ -0,0 +1,32 @@ +import * as React from 'react'; +import { useParticipantsToggle } from '../../hooks'; + +/** @public */ +export interface ParticipantsToggleProps extends React.ButtonHTMLAttributes {} + +/** + * The `ParticipantsToggle` component is a button that toggles the visibility of the participants panel. + * @remarks + * For the component to have any effect it has to live inside a `LayoutContext` context. + * + * @example + * ```tsx + * + * + * + * ``` + * @public + */ +export const ParticipantsToggle: ( + props: ParticipantsToggleProps & React.RefAttributes, +) => React.ReactNode = /* @__PURE__ */ React.forwardRef( + function ParticipantsToggle(props: ParticipantsToggleProps, ref) { + const { mergedProps } = useParticipantsToggle({ props }); + + return ( + + ); + }, +); diff --git a/packages/react/src/components/index.ts b/packages/react/src/components/index.ts index 235d6c878..d5c0e3277 100644 --- a/packages/react/src/components/index.ts +++ b/packages/react/src/components/index.ts @@ -1,6 +1,7 @@ export * from './controls/ClearPinButton'; export * from './ConnectionState'; export * from './controls/ChatToggle'; +export * from './controls/ParticipantsToggle'; export * from './controls/DisconnectButton'; export * from './controls/FocusToggle'; export * from './controls/MediaDeviceSelect'; diff --git a/packages/react/src/hooks/index.ts b/packages/react/src/hooks/index.ts index c47c201af..2faf38319 100644 --- a/packages/react/src/hooks/index.ts +++ b/packages/react/src/hooks/index.ts @@ -38,6 +38,10 @@ export { type UseStartAudioProps, useStartAudio } from './useStartAudio'; export { type UseStartVideoProps, useStartVideo } from './useStartVideo'; export { type UseSwipeOptions, useSwipe } from './useSwipe'; export { type UseChatToggleProps, useChatToggle } from './useChatToggle'; +export { + type UseParticipantsToggleProps, + useParticipantsToggle, +} from './useParticipantsToggle'; export { type UseTokenOptions, type UserInfo, useToken } from './useToken'; export { useTrackMutedIndicator } from './useTrackMutedIndicator'; export { type UseTrackToggleProps, useTrackToggle } from './useTrackToggle'; diff --git a/packages/react/src/hooks/useParticipantsToggle.ts b/packages/react/src/hooks/useParticipantsToggle.ts new file mode 100644 index 000000000..f1087e6a4 --- /dev/null +++ b/packages/react/src/hooks/useParticipantsToggle.ts @@ -0,0 +1,35 @@ +import { setupParticipantsToggle } from '@livekit/components-core'; +import { useLayoutContext } from '../context'; +import { mergeProps } from '../mergeProps'; +import * as React from 'react'; +import { useParticipants } from './useParticipants'; + +/** @public */ +export interface UseParticipantsToggleProps { + props: React.ButtonHTMLAttributes; +} + +/** + * The `useParticipantsToggle` hook provides state and functions for toggling the participants panel. + * @remarks + * Depends on the `LayoutContext` to work properly. + * @public + */ +export function useParticipantsToggle({ props }: UseParticipantsToggleProps) { + const { dispatch, state } = useLayoutContext().widget; + const { className } = React.useMemo(() => setupParticipantsToggle(), []); + const participants = useParticipants(); + + const mergedProps = React.useMemo(() => { + return mergeProps(props, { + className, + onClick: () => { + if (dispatch) dispatch({ msg: 'toggle_participants' }); + }, + 'aria-pressed': state?.showParticipants ? 'true' : 'false', + 'data-lk-participant-count': participants.length.toFixed(0), + }); + }, [props, className, dispatch, state, participants.length]); + + return { mergedProps }; +} From 56ff9eeae25632cef3cab455bd8f84a927535e90 Mon Sep 17 00:00:00 2001 From: Topher Hindman Date: Wed, 11 Feb 2026 09:20:34 -0800 Subject: [PATCH 4/8] feat(react): add Participants prefab panel Add the Participants sidebar panel that displays a sorted list of all room participants with their name and mic/camera mute indicators. Uses existing useParticipants, useSortedParticipants, ParticipantName, and TrackMutedIndicator components. Includes a close button in the header following the same pattern as the Chat panel. --- packages/react/src/prefabs/Participants.tsx | 59 +++++++++++++++++++++ packages/react/src/prefabs/index.ts | 1 + 2 files changed, 60 insertions(+) create mode 100644 packages/react/src/prefabs/Participants.tsx diff --git a/packages/react/src/prefabs/Participants.tsx b/packages/react/src/prefabs/Participants.tsx new file mode 100644 index 000000000..a2f5a3f41 --- /dev/null +++ b/packages/react/src/prefabs/Participants.tsx @@ -0,0 +1,59 @@ +import { Track } from 'livekit-client'; +import * as React from 'react'; +import { useMaybeLayoutContext } from '../context'; +import { ParticipantsToggle } from '../components'; +import { ParticipantName } from '../components/participant/ParticipantName'; +import { TrackMutedIndicator } from '../components/participant/TrackMutedIndicator'; +import { useParticipants } from '../hooks/useParticipants'; +import { useSortedParticipants } from '../hooks/useSortedParticipants'; +import { ParticipantContext } from '../context'; +import ChatCloseIcon from '../assets/icons/ChatCloseIcon'; + +/** @public */ +export interface ParticipantsProps extends React.HTMLAttributes {} + +/** + * The `Participants` component displays a list of all participants in the room + * with their name and audio/video muted indicators. + * + * @example + * ```tsx + * + * + * + * ``` + * @public + */ +export function Participants({ ...props }: ParticipantsProps) { + const participants = useParticipants(); + const sortedParticipants = useSortedParticipants(participants); + const layoutContext = useMaybeLayoutContext(); + + return ( +
+
+ Participants ({participants.length}) + {layoutContext && ( + + + + )} +
+
    + {sortedParticipants.map((participant) => ( +
  • + + + + + +
  • + ))} +
+
+ ); +} diff --git a/packages/react/src/prefabs/index.ts b/packages/react/src/prefabs/index.ts index 252496bae..977a29abc 100644 --- a/packages/react/src/prefabs/index.ts +++ b/packages/react/src/prefabs/index.ts @@ -1,4 +1,5 @@ export { Chat, type ChatProps } from './Chat'; +export { Participants, type ParticipantsProps } from './Participants'; export { PreJoin, type PreJoinProps, usePreviewDevice, usePreviewTracks } from './PreJoin'; export { VideoConference, type VideoConferenceProps } from './VideoConference'; export { ControlBar, type ControlBarProps, type ControlBarControls } from './ControlBar'; From be73c865a21f0bbea19c56749d60225e0d76289f Mon Sep 17 00:00:00 2001 From: Topher Hindman Date: Wed, 11 Feb 2026 09:22:04 -0800 Subject: [PATCH 5/8] feat(react): integrate Participants into VideoConference and ControlBar Add Participants toggle button to the ControlBar between screen share and chat. Wire up the Participants sidebar panel in VideoConference alongside the Chat panel. Update responsive layout to account for either sidebar being open. --- packages/react/src/prefabs/ControlBar.tsx | 22 +++++++++++++------ .../react/src/prefabs/VideoConference.tsx | 7 +++++- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/packages/react/src/prefabs/ControlBar.tsx b/packages/react/src/prefabs/ControlBar.tsx index 2b004834e..fdf68efee 100644 --- a/packages/react/src/prefabs/ControlBar.tsx +++ b/packages/react/src/prefabs/ControlBar.tsx @@ -3,8 +3,9 @@ import * as React from 'react'; import { MediaDeviceMenu } from './MediaDeviceMenu'; import { DisconnectButton } from '../components/controls/DisconnectButton'; import { TrackToggle } from '../components/controls/TrackToggle'; -import { ChatIcon, GearIcon, LeaveIcon } from '../assets/icons'; +import { ChatIcon, GearIcon, LeaveIcon, ParticipantsIcon } from '../assets/icons'; import { ChatToggle } from '../components/controls/ChatToggle'; +import { ParticipantsToggle } from '../components/controls/ParticipantsToggle'; import { useLocalParticipantPermissions, usePersistentUserChoices } from '../hooks'; import { useMediaQuery } from '../hooks/internal'; import { useMaybeLayoutContext } from '../context'; @@ -21,6 +22,7 @@ export type ControlBarControls = { screenShare?: boolean; leave?: boolean; settings?: boolean; + participants?: boolean; }; const trackSourceToProtocol = (source: Track.Source) => { @@ -74,14 +76,14 @@ export function ControlBar({ onDeviceError, ...props }: ControlBarProps) { - const [isChatOpen, setIsChatOpen] = React.useState(false); + const [isSidebarOpen, setIsSidebarOpen] = React.useState(false); const layoutContext = useMaybeLayoutContext(); React.useEffect(() => { - if (layoutContext?.widget.state?.showChat !== undefined) { - setIsChatOpen(layoutContext?.widget.state?.showChat); - } - }, [layoutContext?.widget.state?.showChat]); - const isTooLittleSpace = useMediaQuery(`(max-width: ${isChatOpen ? 1000 : 760}px)`); + const showChat = layoutContext?.widget.state?.showChat ?? false; + const showParticipants = layoutContext?.widget.state?.showParticipants ?? false; + setIsSidebarOpen(showChat || showParticipants); + }, [layoutContext?.widget.state?.showChat, layoutContext?.widget.state?.showParticipants]); + const isTooLittleSpace = useMediaQuery(`(max-width: ${isSidebarOpen ? 1000 : 760}px)`); const defaultVariation = isTooLittleSpace ? 'minimal' : 'verbose'; variation ??= defaultVariation; @@ -203,6 +205,12 @@ export function ControlBar({ {showText && (isScreenShareEnabled ? 'Stop screen share' : 'Share screen')} )} + {visibleControls.participants && ( + + {showIcon && } + {showText && 'Participants'} + + )} {visibleControls.chat && ( {showIcon && } diff --git a/packages/react/src/prefabs/VideoConference.tsx b/packages/react/src/prefabs/VideoConference.tsx index 62af5d61f..803b34f53 100644 --- a/packages/react/src/prefabs/VideoConference.tsx +++ b/packages/react/src/prefabs/VideoConference.tsx @@ -22,6 +22,7 @@ import { useCreateLayoutContext } from '../context'; import { usePinnedTracks, useTracks } from '../hooks'; import { Chat } from './Chat'; import { ControlBar } from './ControlBar'; +import { Participants } from './Participants'; import { useWarnAboutMissingStyles } from '../hooks/useWarnAboutMissingStyles'; /** @@ -64,6 +65,7 @@ export function VideoConference({ showChat: false, unreadMessages: 0, showSettings: false, + showParticipants: false, }); const lastAutoFocusedScreenShareTrack = React.useRef(null); @@ -155,7 +157,7 @@ export function VideoConference({ )} - + + {SettingsComponent && (
Date: Wed, 11 Feb 2026 09:32:42 -0800 Subject: [PATCH 6/8] fix(styles): hide participant count badge on panel close button Add :not(.close-button) to the participants-toggle badge selector so the count badge only appears on the control bar button, not on the close button inside the participants panel header. --- .../styles/scss/components/controls/_participants-toggle.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/styles/scss/components/controls/_participants-toggle.scss b/packages/styles/scss/components/controls/_participants-toggle.scss index e90a7516c..83ed7b02c 100644 --- a/packages/styles/scss/components/controls/_participants-toggle.scss +++ b/packages/styles/scss/components/controls/_participants-toggle.scss @@ -5,7 +5,7 @@ position: relative; } -.participants-toggle[data-lk-participant-count]::after { +.participants-toggle[data-lk-participant-count]:not(.close-button)::after { content: attr(data-lk-participant-count); position: absolute; top: 0; From cfcda29e2e47e54859aa15585af20e4aa776581e Mon Sep 17 00:00:00 2001 From: Topher Hindman Date: Wed, 11 Feb 2026 09:50:08 -0800 Subject: [PATCH 7/8] style(react): fix prettier formatting in participants feature Inline short JSX props and exports to satisfy prettier line length rules. --- packages/react/src/hooks/index.ts | 5 +---- packages/react/src/prefabs/Participants.tsx | 8 ++------ packages/react/src/prefabs/VideoConference.tsx | 8 ++++---- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/packages/react/src/hooks/index.ts b/packages/react/src/hooks/index.ts index 2faf38319..cd9cc1adf 100644 --- a/packages/react/src/hooks/index.ts +++ b/packages/react/src/hooks/index.ts @@ -38,10 +38,7 @@ export { type UseStartAudioProps, useStartAudio } from './useStartAudio'; export { type UseStartVideoProps, useStartVideo } from './useStartVideo'; export { type UseSwipeOptions, useSwipe } from './useSwipe'; export { type UseChatToggleProps, useChatToggle } from './useChatToggle'; -export { - type UseParticipantsToggleProps, - useParticipantsToggle, -} from './useParticipantsToggle'; +export { type UseParticipantsToggleProps, useParticipantsToggle } from './useParticipantsToggle'; export { type UseTokenOptions, type UserInfo, useToken } from './useToken'; export { useTrackMutedIndicator } from './useTrackMutedIndicator'; export { type UseTrackToggleProps, useTrackToggle } from './useTrackToggle'; diff --git a/packages/react/src/prefabs/Participants.tsx b/packages/react/src/prefabs/Participants.tsx index a2f5a3f41..a96579050 100644 --- a/packages/react/src/prefabs/Participants.tsx +++ b/packages/react/src/prefabs/Participants.tsx @@ -44,12 +44,8 @@ export function Participants({ ...props }: ParticipantsProps) {
  • - - + +
  • ))} diff --git a/packages/react/src/prefabs/VideoConference.tsx b/packages/react/src/prefabs/VideoConference.tsx index 803b34f53..e89087702 100644 --- a/packages/react/src/prefabs/VideoConference.tsx +++ b/packages/react/src/prefabs/VideoConference.tsx @@ -157,7 +157,9 @@ export function VideoConference({
    )} - + - + {SettingsComponent && (
    Date: Wed, 11 Feb 2026 10:01:34 -0800 Subject: [PATCH 8/8] chore(react): update API signature for participants feature Regenerate api-extractor output to include the new Participants, ParticipantsToggle, useParticipantsToggle, and ControlBarControls public API additions. --- packages/react/etc/components-react.api.md | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/packages/react/etc/components-react.api.md b/packages/react/etc/components-react.api.md index b62d1c754..98d19e56d 100644 --- a/packages/react/etc/components-react.api.md +++ b/packages/react/etc/components-react.api.md @@ -283,6 +283,7 @@ export type ControlBarControls = { screenShare?: boolean; leave?: boolean; settings?: boolean; + participants?: boolean; }; // @public (undocumented) @@ -553,6 +554,25 @@ export interface ParticipantNameProps extends React_2.HTMLAttributes) => React_2.JSX.Element; +// @public +export function Participants({ ...props }: ParticipantsProps): React_2.JSX.Element; + +// Warning: (ae-internal-missing-underscore) The name "ParticipantsIcon" should be prefixed with an underscore because the declaration is marked as @internal +// +// @internal (undocumented) +export const ParticipantsIcon: (props: SVGProps) => React_2.JSX.Element; + +// @public (undocumented) +export interface ParticipantsProps extends React_2.HTMLAttributes { +} + +// @public +export const ParticipantsToggle: (props: ParticipantsToggleProps & React_2.RefAttributes) => React_2.ReactNode; + +// @public (undocumented) +export interface ParticipantsToggleProps extends React_2.ButtonHTMLAttributes { +} + // @public export const ParticipantTile: (props: ParticipantTileProps & React_2.RefAttributes) => React_2.ReactNode; @@ -1107,6 +1127,22 @@ export interface UseParticipantsOptions { updateOnlyOn?: RoomEvent[]; } +// @public +export function useParticipantsToggle({ props }: UseParticipantsToggleProps): { + mergedProps: React_2.ButtonHTMLAttributes & { + className: string; + onClick: () => void; + 'aria-pressed': string; + 'data-lk-participant-count': string; + }; +}; + +// @public (undocumented) +export interface UseParticipantsToggleProps { + // (undocumented) + props: React_2.ButtonHTMLAttributes; +} + // @public export function useParticipantTile({ trackRef, onParticipantClick, disableSpeakingIndicator, htmlProps, }: UseParticipantTileProps): { elementProps: React_2.HTMLAttributes;