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
JavaScript
// 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