UNPKG

mediasfu-reactnative-expo

Version:

mediasfu-reactnative-expo – Expo-managed React Native WebRTC SDK for video conferencing, webinars, live streaming, broadcast, screen sharing, whiteboard, chat, recording, live subtitles, translation, and AI agent rooms on iOS, Android, and web. Prebuilt r

254 lines (253 loc) 8.66 kB
import React from 'react'; import { StyleProp, ViewStyle } from 'react-native'; /** * Configuration for a single control button. * * @interface Button * * @property {string} [name] - Button label/name * @property {string} [icon] - Icon name (FontAwesome5) * @property {string} [alternateIcon] - Alternate icon name (shown when active) * @property {function} [onPress] - Click handler * @property {object} [backgroundColor] - Background colors with default and pressed states * @property {boolean} [active] - Whether button is in active state * @property {JSX.Element} [alternateIconComponent] - Custom alternate icon component * @property {JSX.Element} [iconComponent] - Custom icon component * @property {JSX.Element} [customComponent] - Completely custom button component * @property {string} [color] - Icon color * @property {string} [activeColor] - Icon color when active * @property {string} [inActiveColor] - Icon color when inactive * @property {boolean} [disabled] - Whether button is disabled * @property {boolean} [show] - Whether to show the button */ export interface Button { name?: string; icon?: string; alternateIcon?: string; accessibilityLabel?: string; onPress?: () => void; backgroundColor?: { default?: string; pressed?: string; }; active?: boolean; alternateIconComponent?: JSX.Element; iconComponent?: JSX.Element; customComponent?: JSX.Element; color?: string; activeColor?: string; inActiveColor?: string; disabled?: boolean; show?: boolean; } /** * Configuration options for the ControlButtonsComponent. * * @interface ControlButtonsComponentOptions * * **Button Configuration:** * @property {Button[]} buttons - Array of button configurations * * **Layout:** * @property {'flex-start' | 'center' | 'flex-end' | 'space-between' | 'space-around' | 'space-evenly'} [alignment='flex-start'] - Button alignment within container * @property {boolean} [vertical=false] - Whether to arrange buttons vertically (true) or horizontally (false) * * **Styling:** * @property {string} [buttonColor] - Default color for button icons * @property {object} [buttonBackgroundColor] - Background colors with default and pressed states * @property {StyleProp<ViewStyle>} [buttonsContainerStyle] - Custom styles for buttons container * @property {object} [style] - Additional custom styles for outer container * * **Custom Icons:** * @property {JSX.Element} [alternateIconComponent] - Global alternate icon component * @property {JSX.Element} [iconComponent] - Global icon component * * **Advanced Render Overrides:** * @property {function} [renderContent] - Optional custom renderer for button content (receives defaultContent and dimensions) * @property {function} [renderContainer] - Optional custom renderer for outer container (receives defaultContainer and dimensions) */ export interface ControlButtonsComponentOptions { buttons: Button[]; buttonColor?: string; buttonBackgroundColor?: { default?: string; pressed?: string; }; alignment?: 'flex-start' | 'center' | 'flex-end' | 'space-between' | 'space-around' | 'space-evenly'; vertical?: boolean; buttonsContainerStyle?: StyleProp<ViewStyle>; alternateIconComponent?: JSX.Element; iconComponent?: JSX.Element; style?: object; renderContent?: (options: { defaultContent: React.ReactNode; dimensions: { width: number; height: number; }; }) => React.ReactNode; renderContainer?: (options: { defaultContainer: React.ReactNode; dimensions: { width: number; height: number; }; }) => React.ReactNode; } export type ControlButtonsComponentType = (options: ControlButtonsComponentOptions) => JSX.Element; /** * ControlButtonsComponent - Flexible control button bar for meeting actions * * ControlButtonsComponent is a React Native component that renders a customizable * row or column of control buttons (mute, video, screen share, etc.). Each button * supports active/inactive states, custom icons, disabled states, and press feedback. * * **Key Features:** * - Horizontal or vertical button arrangement * - Active/inactive state visual feedback * - Custom icon support (FontAwesome5 or custom components) * - Pressed state animations * - Disabled button handling * - Flexible alignment options * - Show/hide individual buttons * * **UI Customization:** * This component can be replaced via `uiOverrides.controlButtonsComponent` to * provide a completely custom control button bar. * * @component * @param {ControlButtonsComponentOptions} props - Configuration options for the control buttons * * @returns {JSX.Element} Rendered control button bar * * @example * // Basic usage - Horizontal button bar * import React from 'react'; * import { ControlButtonsComponent, Button } from 'mediasfu-reactnative-expo'; * * function MeetingControls() { * const [isMuted, setIsMuted] = React.useState(false); * const [isVideoOff, setIsVideoOff] = React.useState(false); * * const buttons: Button[] = [ * { * name: 'Mic', * icon: 'microphone', * alternateIcon: 'microphone-slash', * active: isMuted, * onPress: () => setIsMuted(!isMuted), * activeColor: '#FF0000', * inActiveColor: '#FFFFFF', * }, * { * name: 'Video', * icon: 'video', * alternateIcon: 'video-slash', * active: isVideoOff, * onPress: () => setIsVideoOff(!isVideoOff), * activeColor: '#FF0000', * inActiveColor: '#FFFFFF', * }, * { * name: 'Leave', * icon: 'phone', * onPress: () => console.log('Leave meeting'), * backgroundColor: { default: '#FF0000', pressed: '#CC0000' }, * color: '#FFFFFF', * }, * ]; * * return ( * <ControlButtonsComponent * buttons={buttons} * alignment="center" * buttonBackgroundColor={{ default: '#333333', pressed: '#555555' }} * vertical={false} * /> * ); * } * * @example * // Vertical button bar with custom styling * <ControlButtonsComponent * buttons={controlButtons} * alignment="flex-start" * vertical={true} * buttonsContainerStyle={{ * gap: 10, * padding: 8, * backgroundColor: 'rgba(0,0,0,0.7)', * borderRadius: 8, * }} * /> * * @example * // With custom icon components * const customButtons: Button[] = [ * { * name: 'Custom', * customComponent: <MyCustomButtonComponent />, * onPress: () => console.log('Custom pressed'), * }, * { * name: 'Icon', * iconComponent: <CustomIcon name="custom" />, * alternateIconComponent: <CustomIcon name="custom-alt" />, * active: isActive, * onPress: toggleActive, * }, * ]; * * <ControlButtonsComponent * buttons={customButtons} * alignment="space-evenly" * /> * * @example * // Using uiOverrides for complete control bar replacement * import { MyCustomControlButtons } from './MyCustomControlButtons'; * * const sessionConfig = { * credentials: { apiKey: 'your-api-key' }, * uiOverrides: { * controlButtonsComponent: { * component: MyCustomControlButtons, * injectedProps: { * theme: 'modern', * showLabels: true, * }, * }, * }, * }; * * // MyCustomControlButtons.tsx * export const MyCustomControlButtons = (props: ControlButtonsComponentOptions & { theme: string; showLabels: boolean }) => { * return ( * <View style={{ flexDirection: props.vertical ? 'column' : 'row', gap: 12 }}> * {props.buttons.filter(btn => btn.show !== false).map((button, index) => ( * <Pressable * key={index} * onPress={button.onPress} * disabled={button.disabled} * style={{ * padding: 12, * borderRadius: props.theme === 'modern' ? 24 : 8, * backgroundColor: button.active ? '#007bff' : '#e0e0e0', * }} * > * {button.customComponent || ( * <FontAwesome5 * name={button.active ? button.alternateIcon : button.icon} * size={20} * color={button.active ? button.activeColor : button.inActiveColor} * /> * )} * {props.showLabels && <Text>{button.name}</Text>} * </Pressable> * ))} * </View> * ); * }; */ declare const ControlButtonsComponent: React.FC<ControlButtonsComponentOptions>; export default ControlButtonsComponent;