mediasfu-reactjs
Version:
MediaSFU Prebuilt ReactJS SDK - Compatible with React 18 & 19, TypeScript & JavaScript
286 lines • 12.5 kB
TypeScript
import React from "react";
import type { FontAwesomeIconProps } from "@fortawesome/react-fontawesome";
import { Socket } from "socket.io-client";
export interface ConfirmHereModalOptions {
isConfirmHereModalVisible: boolean;
onConfirmHereClose: () => void;
backgroundColor?: string;
countdownDuration?: number;
socket: Socket;
localSocket?: Socket;
roomName: string;
member: string;
title?: React.ReactNode;
message?: React.ReactNode | ((context: {
counter: number;
countdownDuration: number;
}) => React.ReactNode);
countdownLabel?: React.ReactNode;
confirmButtonLabel?: React.ReactNode;
onTimeout?: () => void;
overlayProps?: React.HTMLAttributes<HTMLDivElement>;
contentProps?: React.HTMLAttributes<HTMLDivElement>;
containerProps?: React.HTMLAttributes<HTMLDivElement>;
spinnerWrapperProps?: React.HTMLAttributes<HTMLDivElement>;
spinnerIcon?: React.ReactNode;
spinnerIconProps?: Partial<FontAwesomeIconProps>;
titleProps?: React.HTMLAttributes<HTMLHeadingElement>;
messageProps?: React.HTMLAttributes<HTMLParagraphElement>;
countdownWrapperProps?: React.HTMLAttributes<HTMLParagraphElement>;
countdownValueProps?: React.HTMLAttributes<HTMLSpanElement>;
confirmButtonProps?: React.ButtonHTMLAttributes<HTMLButtonElement>;
renderSpinner?: (options: {
defaultSpinner: React.ReactNode;
}) => React.ReactNode;
renderTitle?: (options: {
defaultTitle: React.ReactNode;
}) => React.ReactNode;
renderMessage?: (options: {
defaultMessage: React.ReactNode;
counter: number;
countdownDuration: number;
}) => React.ReactNode;
renderCountdown?: (options: {
defaultCountdown: React.ReactNode;
counter: number;
countdownLabel: React.ReactNode;
}) => React.ReactNode;
renderConfirmButton?: (options: {
defaultButton: React.ReactNode;
}) => React.ReactNode;
renderBody?: (options: {
defaultBody: React.ReactNode;
spinner: React.ReactNode;
title: React.ReactNode;
message: React.ReactNode;
countdown: React.ReactNode;
confirmButton: React.ReactNode;
}) => React.ReactNode;
renderContent?: (options: {
defaultContent: React.ReactNode;
}) => React.ReactNode;
}
export type ConfirmHereModalType = (options: ConfirmHereModalOptions) => void;
/**
* ConfirmHereModal - A modal component for confirming user presence with countdown timer.
*
* This component displays an interactive modal that prompts users to confirm their presence in a session.
* It features a configurable countdown timer, socket-based presence confirmation, and comprehensive
* customization options for styling, content, and behavior.
*
* **Key Features:**
* - **Countdown Timer**: Configurable countdown duration (default 120 seconds) with real-time display
* - **Socket Communication**: Emits presence confirmation to both primary and local sockets
* - **Timeout Handling**: Custom callback support for timeout scenarios with automatic modal dismissal
* - **Custom Content**: Fully customizable title, message (with dynamic context), and labels
* - **Loading States**: Built-in spinner with customizable appearance during confirmation processing
* - **Flexible Messaging**: Message can be static node or dynamic function receiving countdown context
* - **HTML Attributes**: Granular control over all UI elements (overlay, content, buttons, text, etc.)
* - **Render Hooks**: Complete override capability for all visual elements (spinner, title, message, countdown, button, body, content)
* - **Responsive Design**: Automatic centering and z-index management for overlay positioning
* - **Accessibility**: Semantic HTML with proper button and heading elements
*
* @component
*
* @param {ConfirmHereModalOptions} props - Configuration options for ConfirmHereModal
* @param {boolean} props.isConfirmHereModalVisible - Controls modal visibility
* @param {() => void} props.onConfirmHereClose - Callback function invoked when modal is closed
* @param {string} [props.backgroundColor="#83c0e9"] - Background color for the modal content
* @param {number} [props.countdownDuration=120] - Countdown duration in seconds before automatic timeout
* @param {Socket} props.socket - Primary socket instance for emitting presence confirmation
* @param {Socket} [props.localSocket] - Optional local socket instance for local presence events
* @param {string} props.roomName - Room identifier for socket communication
* @param {string} props.member - Member identifier for presence confirmation
* @param {React.ReactNode} [props.title] - Custom title content (default: "Confirm Your Presence")
* @param {React.ReactNode | ((context: {counter: number; countdownDuration: number}) => React.ReactNode)} [props.message] - Message content or function receiving countdown context
* @param {React.ReactNode} [props.countdownLabel] - Label preceding countdown value (default: "Time remaining: ")
* @param {React.ReactNode} [props.confirmButtonLabel] - Button label for confirmation action (default: "I'm Here")
* @param {() => void} [props.onTimeout] - Callback invoked when countdown reaches zero
* @param {React.HTMLAttributes<HTMLDivElement>} [props.overlayProps] - HTML attributes for overlay container
* @param {React.HTMLAttributes<HTMLDivElement>} [props.contentProps] - HTML attributes for content wrapper
* @param {React.HTMLAttributes<HTMLDivElement>} [props.containerProps] - HTML attributes for main container
* @param {React.HTMLAttributes<HTMLDivElement>} [props.spinnerWrapperProps] - HTML attributes for spinner wrapper
* @param {React.ReactNode} [props.spinnerIcon] - Custom spinner icon component
* @param {Partial<FontAwesomeIconProps>} [props.spinnerIconProps] - FontAwesome icon props for spinner customization
* @param {React.HTMLAttributes<HTMLHeadingElement>} [props.titleProps] - HTML attributes for title element
* @param {React.HTMLAttributes<HTMLParagraphElement>} [props.messageProps] - HTML attributes for message element
* @param {React.HTMLAttributes<HTMLParagraphElement>} [props.countdownWrapperProps] - HTML attributes for countdown wrapper
* @param {React.HTMLAttributes<HTMLSpanElement>} [props.countdownValueProps] - HTML attributes for countdown value
* @param {React.ButtonHTMLAttributes<HTMLButtonElement>} [props.confirmButtonProps] - HTML attributes for confirm button
* @param {(options: {defaultSpinner: React.ReactNode}) => React.ReactNode} [props.renderSpinner] - Custom render function for spinner
* @param {(options: {defaultTitle: React.ReactNode}) => React.ReactNode} [props.renderTitle] - Custom render function for title
* @param {(options: {defaultMessage: React.ReactNode; counter: number; countdownDuration: number}) => React.ReactNode} [props.renderMessage] - Custom render function for message
* @param {(options: {defaultCountdown: React.ReactNode; counter: number; countdownLabel: React.ReactNode}) => React.ReactNode} [props.renderCountdown] - Custom render function for countdown
* @param {(options: {defaultButton: React.ReactNode}) => React.ReactNode} [props.renderConfirmButton] - Custom render function for confirm button
* @param {(options: {defaultBody: React.ReactNode; spinner: React.ReactNode; title: React.ReactNode; message: React.ReactNode; countdown: React.ReactNode; confirmButton: React.ReactNode}) => React.ReactNode} [props.renderBody] - Custom render function for modal body
* @param {(options: {defaultContent: React.ReactNode}) => React.ReactNode} [props.renderContent] - Custom render function for entire content
*
* @returns {React.JSX.Element} The rendered ConfirmHereModal component
*
* @example
* // Basic usage with default countdown
* ```tsx
* import React, { useState } from 'react';
* import { ConfirmHereModal } from 'mediasfu-reactjs';
* import { io } from 'socket.io-client';
*
* const BasicPresenceCheck = () => {
* const [showModal, setShowModal] = useState(true);
* const socket = io('https://mediasfu.com');
*
* return (
* <ConfirmHereModal
* isConfirmHereModalVisible={showModal}
* onConfirmHereClose={() => setShowModal(false)}
* socket={socket}
* roomName="meeting-room-123"
* member="user@example.com"
* countdownDuration={120}
* />
* );
* };
* ```
*
* @example
* // Custom styled with timeout warning
* ```tsx
* import React, { useState } from 'react';
* import { ConfirmHereModal } from 'mediasfu-reactjs';
* import { io } from 'socket.io-client';
*
* const CustomStyledPresence = () => {
* const [showModal, setShowModal] = useState(true);
* const socket = io('https://mediasfu.com');
*
* const handleTimeout = () => {
* console.warn('User failed to confirm presence');
* // Redirect to lobby or end session
* };
*
* return (
* <ConfirmHereModal
* isConfirmHereModalVisible={showModal}
* onConfirmHereClose={() => setShowModal(false)}
* socket={socket}
* roomName="meeting-room-123"
* member="user@example.com"
* backgroundColor="#ff6b6b"
* countdownDuration={60}
* onTimeout={handleTimeout}
* title={<h2 style={{ color: '#fff' }}>⚠️ Are You Still There?</h2>}
* message={({ counter }) => (
* <p style={{ color: counter < 10 ? '#fff' : '#333' }}>
* You will be removed from the meeting if you don't respond!
* </p>
* )}
* confirmButtonLabel="Yes, I'm Here!"
* confirmButtonProps={{
* style: {
* backgroundColor: '#2ecc71',
* color: '#fff',
* padding: '12px 24px',
* fontSize: '16px'
* }
* }}
* />
* );
* };
* ```
*
* @example
* // Analytics tracking for presence confirmations
* ```tsx
* import React, { useState } from 'react';
* import { ConfirmHereModal } from 'mediasfu-reactjs';
* import { io } from 'socket.io-client';
*
* const AnalyticsPresence = () => {
* const [showModal, setShowModal] = useState(true);
* const socket = io('https://mediasfu.com');
*
* const handleConfirm = () => {
* // Track confirmation
* analytics.track('Presence Confirmed', {
* roomName: 'meeting-room-123',
* timeRemaining: counter
* });
* setShowModal(false);
* };
*
* const handleTimeout = () => {
* analytics.track('Presence Timeout', {
* roomName: 'meeting-room-123'
* });
* };
*
* return (
* <ConfirmHereModal
* isConfirmHereModalVisible={showModal}
* onConfirmHereClose={handleConfirm}
* socket={socket}
* roomName="meeting-room-123"
* member="user@example.com"
* onTimeout={handleTimeout}
* renderCountdown={({ defaultCountdown, counter }) => (
* <div>
* {defaultCountdown}
* {counter < 30 && (
* <p style={{ color: 'red' }}>⏰ Less than 30 seconds remaining!</p>
* )}
* </div>
* )}
* />
* );
* };
* ```
*
* @example
* // Integration with MediasfuGeneric using uiOverrides
* ```tsx
* import React, { useState } from 'react';
* import { MediasfuGeneric, ConfirmHereModal } from 'mediasfu-reactjs';
*
* const CustomPresenceComponent = (props) => (
* <ConfirmHereModal
* {...props}
* title="Custom Presence Check"
* countdownDuration={90}
* message="Please confirm you're still attending this session."
* renderBody={({ spinner, title, message, countdown, confirmButton }) => (
* <div className="custom-presence">
* <div className="presence-header">
* {spinner}
* {title}
* </div>
* <div className="presence-content">
* {message}
* <div className="presence-countdown">{countdown}</div>
* </div>
* <div className="presence-footer">
* {confirmButton}
* </div>
* </div>
* )}
* />
* );
*
* const App = () => {
* const [credentials] = useState({
* apiUserName: 'user123',
* apiKey: 'your-api-key'
* });
*
* return (
* <MediasfuGeneric
* credentials={credentials}
* uiOverrides={{
* ConfirmHereModal: CustomPresenceComponent
* }}
* />
* );
* };
* ```
*/
declare const ConfirmHereModal: React.FC<ConfirmHereModalOptions>;
export default ConfirmHereModal;
//# sourceMappingURL=ConfirmHereModal.d.ts.map