UNPKG

communication-react-19

Version:

React library for building modern communication user experiences utilizing Azure Communication Services (React 19 compatible fork)

85 lines 4.04 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { Customizer, LayerHost, mergeStyles, registerIcons, Stack, useTheme } from '@fluentui/react'; import { FluentThemeProvider } from "../../../../react-components/src"; import React, { createContext, useContext } from 'react'; import { LocalizationProvider } from '../localization'; import { DEFAULT_COMPOSITE_ICONS } from './icons'; import { globalLayerHostStyle } from './styles/GlobalHostLayer.styles'; import { useId } from '@fluentui/react-hooks'; import { ACSAudioProvider } from './AudioProvider'; /** * A base provider {@link React.Context} to wrap components with other required providers * (e.g. icons, FluentThemeProvider, LocalizationProvider). * * Required providers are only wrapped once, with all other instances only passing children. * * @private */ export const BaseProvider = (props) => { const { fluentTheme, rtl, locale } = props; const globalLayerHostId = useId('composite-global-hostId'); /** * Pass only the children if we previously registered icons, and have previously wrapped the children in * FluentThemeProvider and LocalizationProvider */ const alreadyWrapped = useBase(); if (alreadyWrapped) { return React.createElement(React.Fragment, null, props.children); } /** * Before registering fluent icons, we should check DEFAULT_COMPOSITE_ICONS and strip out the key value pairs where value is undefined */ const iconsToRegister = {}; Object.entries(DEFAULT_COMPOSITE_ICONS).forEach(([key, value]) => { if (value) { iconsToRegister[key] = value; } }); /** * We register the default icon mappings merged with custom icons provided through props * to ensure all icons render correctly. */ registerIcons({ icons: Object.assign(Object.assign({}, iconsToRegister), props.icons) }); /** * We need to create one context for the AudioProvider to ensure that we only have one instance of the AudioContext. */ const compositeAudioContext = new AudioContext(); // we use Customizer to override default LayerHost injected to <body /> // which stop polluting global dom tree and increase compatibility with react-full-screen const CompositeElement = (React.createElement(FluentThemeProvider, { fluentTheme: fluentTheme, rtl: rtl }, // On mobile we expect the composite to fill the device screen, hence we set a meta property to have better OOBE. props.formFactor === 'mobile' && React.createElement("meta", { name: "viewport", content: "width=device-width" }), React.createElement(Customizer, { scopedSettings: { Layer: { hostId: globalLayerHostId } } }, React.createElement(ACSAudioProvider, { audioContext: compositeAudioContext }, React.createElement(WithBackgroundColor, null, props.children))), React.createElement(LayerHost, { id: globalLayerHostId, className: mergeStyles(globalLayerHostStyle) }))); const localizedElement = locale ? LocalizationProvider({ locale, children: CompositeElement }) : CompositeElement; return React.createElement(BaseContext.Provider, { value: true }, localizedElement); }; /** * @private */ const BaseContext = createContext(false); /** * @private */ const useBase = () => useContext(BaseContext); /** * @private * Provides a wrapper with a background color to ensure that composites always have a background color. * This is necessary to ensure that composites are not transparent, * and the background color of it's parent elements doesn't show through the composite. */ const WithBackgroundColor = (props) => { const { children } = props; const theme = useTheme(); const className = mergeStyles({ background: theme.semanticColors.bodyBackground, height: '100%', width: '100%', position: 'relative' }); return React.createElement(Stack, { className: className }, children); }; //# sourceMappingURL=BaseComposite.js.map