UNPKG

communication-react-19

Version:

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

64 lines 4.24 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { DefaultButton, Icon, Stack, mergeStyles } from '@fluentui/react'; import React, { useEffect, useMemo, useState } from 'react'; import { useTheme } from '../theming'; import { rootStyle, childrenContainerStyle, leftRightButtonStyles } from './styles/HorizontalGallery.styles'; import { useIdentifiers } from '../identifiers'; import { bucketize } from './utils/overFlowGalleriesUtils'; /** * {@link HorizontalGallery} default children per page */ const DEFAULT_CHILDREN_PER_PAGE = 5; /** * Renders a horizontal gallery that parents children horizontally. Handles pagination based on the childrenPerPage prop. * @param props - HorizontalGalleryProps {@link @azure/communication-react#HorizontalGalleryProps} * @returns */ export const HorizontalGallery = (props) => { var _a; const { children, childrenPerPage = DEFAULT_CHILDREN_PER_PAGE, styles, onFetchTilesToRender } = props; const ids = useIdentifiers(); const [page, setPage] = useState(0); const numberOfChildren = React.Children.count(children); const lastPage = Math.ceil(numberOfChildren / childrenPerPage) - 1; const indexesArray = useMemo(() => { return bucketize([...Array(numberOfChildren).keys()], childrenPerPage); }, [numberOfChildren, childrenPerPage]); useEffect(() => { var _a; if (onFetchTilesToRender && indexesArray) { onFetchTilesToRender((_a = indexesArray[page]) !== null && _a !== void 0 ? _a : []); } }, [indexesArray, onFetchTilesToRender, page]); const firstIndexOfCurrentPage = page * childrenPerPage; const clippedPage = firstIndexOfCurrentPage < numberOfChildren - 1 ? page : lastPage; const childrenOnCurrentPage = useMemo(() => { const indexes = indexesArray === null || indexesArray === void 0 ? void 0 : indexesArray[clippedPage]; if (!indexes) { return []; } return indexes.map((index) => React.Children.toArray(children)[index]); }, [indexesArray, clippedPage, children]); const showButtons = numberOfChildren > childrenPerPage; const disablePreviousButton = page === 0; const disableNextButton = page === lastPage; const childrenStyles = useMemo(() => { return { root: styles === null || styles === void 0 ? void 0 : styles.children }; }, [styles === null || styles === void 0 ? void 0 : styles.children]); // If children per page is 0 or less return empty element if (childrenPerPage <= 0) { return React.createElement(React.Fragment, null); } return (React.createElement(Stack, { horizontal: true, className: mergeStyles(rootStyle, (_a = props.styles) === null || _a === void 0 ? void 0 : _a.root) }, showButtons && (React.createElement(HorizontalGalleryNavigationButton, { key: "previous-nav-button", icon: React.createElement(Icon, { iconName: "HorizontalGalleryLeftButton" }), styles: styles === null || styles === void 0 ? void 0 : styles.previousButton, onClick: () => setPage(Math.max(0, Math.min(lastPage, page - 1))), disabled: disablePreviousButton, identifier: ids.overflowGalleryLeftNavButton })), React.createElement(Stack, { horizontal: true, className: mergeStyles(childrenContainerStyle) }, childrenOnCurrentPage.map((child, i) => { return (React.createElement(Stack.Item, { styles: childrenStyles, key: i, "data-ui-id": ids.horizontalGalleryVideoTile }, child)); })), showButtons && (React.createElement(HorizontalGalleryNavigationButton, { key: "next-nav-button", icon: React.createElement(Icon, { iconName: "HorizontalGalleryRightButton" }), styles: styles === null || styles === void 0 ? void 0 : styles.nextButton, onClick: () => setPage(Math.min(lastPage, page + 1)), disabled: disableNextButton, identifier: ids.overflowGalleryRightNavButton })))); }; const HorizontalGalleryNavigationButton = (props) => { const theme = useTheme(); return (React.createElement(DefaultButton, { className: mergeStyles(leftRightButtonStyles(theme), props.styles), onClick: props.onClick, disabled: props.disabled, "data-ui-id": props.identifier }, props.icon)); }; //# sourceMappingURL=HorizontalGallery.js.map