communication-react-19
Version:
React library for building modern communication user experiences utilizing Azure Communication Services (React 19 compatible fork)
50 lines • 4.47 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { DefaultButton, Icon, IconButton, Modal, Stack, mergeStyles } from '@fluentui/react';
import React, { useMemo, useState } from 'react';
import { bodyContainer, brokenImageStyle, cancelIcon, closeButtonStyles, controlBarContainerStyle, downloadButtonStyle, downloadIcon, downloadIconStyle, focusTrapZoneStyle, headerStyle, normalImageStyle, overlayStyles, scrollableContentStyle, smallDownloadButtonContainerStyle, themeProviderRootStyle, titleBarContainerStyle, titleStyle } from './styles/ImageOverlay.style';
import { FluentThemeProvider } from '../theming/FluentThemeProvider';
import { useLocale } from '../localization';
/* @conditional-compile-remove(image-overlay-theme) */
import { imageOverlayTheme } from '../theming';
import { darkTheme } from '../theming';
import { Announcer } from './Announcer';
/**
* Component to render a fullscreen modal for a selected image.
*
* @public
*/
export const ImageOverlay = (props) => {
const { isOpen, imageSrc, title, titleIcon, altText, onDownloadButtonClicked, onDismiss } = props;
const localeStrings = useLocale().strings.imageOverlay;
const [isImageLoaded, setIsImageLoaded] = useState(true);
const overlayTheme = useMemo(() => {
/* @conditional-compile-remove(image-overlay-theme) */
return imageOverlayTheme;
return Object.assign(Object.assign({}, darkTheme), { semanticColors: Object.assign(Object.assign({}, darkTheme.semanticColors), { bodyBackground: 'rgba(0, 0, 0, 0.85)' }) });
}, []);
const imageStyle = isImageLoaded ? normalImageStyle : brokenImageStyle(overlayTheme);
const renderHeaderBar = () => {
return (React.createElement(Stack, { className: mergeStyles(headerStyle), role: "heading", "aria-label": title || 'Image', "aria-level": 2 },
React.createElement(Stack, { className: mergeStyles(titleBarContainerStyle) },
titleIcon,
React.createElement(Stack.Item, { className: mergeStyles(titleStyle(overlayTheme)) }, title)),
React.createElement(Stack, { className: mergeStyles(controlBarContainerStyle) },
onDownloadButtonClicked && (React.createElement(DefaultButton, { className: mergeStyles(downloadButtonStyle), text: localeStrings.downloadButtonLabel, onClick: () => onDownloadButtonClicked && onDownloadButtonClicked(imageSrc), onRenderIcon: () => React.createElement(Icon, { iconName: downloadIcon.iconName, className: mergeStyles(downloadIconStyle) }), "aria-live": 'polite', "aria-label": localeStrings.downloadButtonLabel, disabled: imageSrc === '' })),
onDownloadButtonClicked && (React.createElement(IconButton, { iconProps: downloadIcon, className: mergeStyles(smallDownloadButtonContainerStyle(overlayTheme)), onClick: () => onDownloadButtonClicked && onDownloadButtonClicked(imageSrc), "aria-label": localeStrings.downloadButtonLabel, "aria-live": 'polite', disabled: imageSrc === '' })),
React.createElement(IconButton, { iconProps: cancelIcon, className: mergeStyles(closeButtonStyles(overlayTheme)), onClick: onDismiss, "aria-label": localeStrings.dismissButtonAriaLabel, "aria-live": 'polite' }))));
};
const renderBodyWithLightDismiss = () => {
return (React.createElement(Stack, { className: mergeStyles(bodyContainer), onClick: () => props.onDismiss() }, imageSrc && (React.createElement("img", { src: imageSrc, className: mergeStyles(imageStyle), alt: altText || 'image', "aria-label": 'image-overlay-main-image', "data-ui-id": 'image-overlay-main-image', "aria-live": 'polite', onError: () => {
setIsImageLoaded(false);
}, onClick: (event) => event.stopPropagation(), onDoubleClick: (event) => {
event.persist();
} }))));
};
return (React.createElement(Modal, { titleAriaId: title, isOpen: isOpen, onDismiss: onDismiss, overlay: { styles: Object.assign({}, overlayStyles(overlayTheme)) }, styles: { main: focusTrapZoneStyle, scrollableContent: scrollableContentStyle }, isDarkOverlay: true },
React.createElement(Announcer, { ariaLive: 'polite', announcementString: localeStrings.overlayVisibleMessage }),
React.createElement(FluentThemeProvider, { fluentTheme: overlayTheme, rootStyle: themeProviderRootStyle },
renderHeaderBar(),
renderBodyWithLightDismiss())));
};
//# sourceMappingURL=ImageOverlay.js.map