@azure/communication-react 1.4.3-alpha-202212060013.0 → 1.4.3-alpha-202212070014.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. package/dist/dist-cjs/communication-react/index.js +356 -220
  2. package/dist/dist-cjs/communication-react/index.js.map +1 -1
  3. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
  4. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
  5. package/dist/dist-esm/react-components/src/components/VideoGallery/DefaultLayout.d.ts +41 -0
  6. package/dist/dist-esm/react-components/src/components/VideoGallery/DefaultLayout.js +45 -0
  7. package/dist/dist-esm/react-components/src/components/VideoGallery/DefaultLayout.js.map +1 -0
  8. package/dist/dist-esm/react-components/src/components/VideoGallery/VideoGalleryResponsiveHorizontalGallery.d.ts +12 -0
  9. package/dist/dist-esm/react-components/src/components/VideoGallery/VideoGalleryResponsiveHorizontalGallery.js +18 -0
  10. package/dist/dist-esm/react-components/src/components/VideoGallery/VideoGalleryResponsiveHorizontalGallery.js.map +1 -0
  11. package/dist/dist-esm/react-components/src/components/VideoGallery/styles/DefaultLayout.styles.d.ts +6 -0
  12. package/dist/dist-esm/react-components/src/components/VideoGallery/styles/DefaultLayout.styles.js +9 -0
  13. package/dist/dist-esm/react-components/src/components/VideoGallery/styles/DefaultLayout.styles.js.map +1 -0
  14. package/dist/dist-esm/react-components/src/components/VideoGallery/styles/VideoGalleryResponsiveHorizontalGallery.styles.d.ts +59 -0
  15. package/dist/dist-esm/react-components/src/components/VideoGallery/styles/VideoGalleryResponsiveHorizontalGallery.styles.js +64 -0
  16. package/dist/dist-esm/react-components/src/components/VideoGallery/styles/VideoGalleryResponsiveHorizontalGallery.styles.js.map +1 -0
  17. package/dist/dist-esm/react-components/src/components/VideoGallery/videoGalleryUtils.d.ts +17 -0
  18. package/dist/dist-esm/react-components/src/components/VideoGallery/videoGalleryUtils.js +68 -0
  19. package/dist/dist-esm/react-components/src/components/VideoGallery/videoGalleryUtils.js.map +1 -0
  20. package/dist/dist-esm/react-components/src/components/VideoGallery.js +25 -17
  21. package/dist/dist-esm/react-components/src/components/VideoGallery.js.map +1 -1
  22. package/package.json +8 -8
@@ -202,7 +202,7 @@ const _toCommunicationIdentifier = (id) => {
202
202
  // Copyright (c) Microsoft Corporation.
203
203
  // Licensed under the MIT license.
204
204
  // GENERATED FILE. DO NOT EDIT MANUALLY.
205
- var telemetryVersion = '1.4.3-alpha-202212060013.0';
205
+ var telemetryVersion = '1.4.3-alpha-202212070014.0';
206
206
 
207
207
  // Copyright (c) Microsoft Corporation.
208
208
  /**
@@ -8386,154 +8386,6 @@ const _RemoteVideoTile = React__default['default'].memo((props) => {
8386
8386
  participantState: props.participantState }));
8387
8387
  });
8388
8388
 
8389
- // Copyright (c) Microsoft Corporation.
8390
- // Licensed under the MIT license.
8391
- /**
8392
- * Horizontal Gallery button width in rem
8393
- */
8394
- const HORIZONTAL_GALLERY_BUTTON_WIDTH = 1.75;
8395
- /**
8396
- * @private
8397
- */
8398
- const leftRightButtonStyles = (theme) => {
8399
- return {
8400
- background: 'none',
8401
- padding: 0,
8402
- height: 'auto',
8403
- minWidth: `${HORIZONTAL_GALLERY_BUTTON_WIDTH}rem`,
8404
- maxWidth: `${HORIZONTAL_GALLERY_BUTTON_WIDTH}rem`,
8405
- border: `1px solid ${theme.palette.neutralLight}`,
8406
- borderRadius: theme.effects.roundedCorner4
8407
- };
8408
- };
8409
- /**
8410
- * Horizontal Gallery gap size in rem between tiles and buttons
8411
- */
8412
- const HORIZONTAL_GALLERY_GAP = 0.5;
8413
- /**
8414
- * @private
8415
- */
8416
- const rootStyle = {
8417
- height: '100%',
8418
- width: '100%',
8419
- gap: `${HORIZONTAL_GALLERY_GAP}rem`
8420
- };
8421
- /**
8422
- * @private
8423
- */
8424
- const childrenContainerStyle = {
8425
- height: '100%',
8426
- gap: `${HORIZONTAL_GALLERY_GAP}rem`
8427
- };
8428
-
8429
- // Copyright (c) Microsoft Corporation.
8430
- /**
8431
- * {@link HorizontalGallery} default children per page
8432
- */
8433
- const DEFAULT_CHILDREN_PER_PAGE = 5;
8434
- /**
8435
- * Renders a horizontal gallery that parents children horizontally. Handles pagination based on the childrenPerPage prop.
8436
- * @param props - HorizontalGalleryProps {@link @azure/communication-react#HorizontalGalleryProps}
8437
- * @returns
8438
- */
8439
- const HorizontalGallery = (props) => {
8440
- var _a, _b;
8441
- const { children, childrenPerPage = DEFAULT_CHILDREN_PER_PAGE, styles } = props;
8442
- const ids = useIdentifiers();
8443
- const [page, setPage] = React.useState(0);
8444
- const numberOfChildren = React__default['default'].Children.count(children);
8445
- const lastPage = Math.ceil(numberOfChildren / childrenPerPage) - 1;
8446
- const paginatedChildren = React.useMemo(() => {
8447
- return bucketize(React__default['default'].Children.toArray(children), childrenPerPage);
8448
- }, [children, childrenPerPage]);
8449
- // If children per page is 0 or less return empty element
8450
- if (childrenPerPage <= 0) {
8451
- return React__default['default'].createElement(React__default['default'].Fragment, null);
8452
- }
8453
- const firstIndexOfCurrentPage = page * childrenPerPage;
8454
- const clippedPage = firstIndexOfCurrentPage < numberOfChildren - 1 ? page : lastPage;
8455
- const childrenOnCurrentPage = paginatedChildren[clippedPage];
8456
- const showButtons = numberOfChildren > childrenPerPage;
8457
- const disablePreviousButton = page === 0;
8458
- const disableNextButton = page === lastPage;
8459
- return (React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(rootStyle, (_a = props.styles) === null || _a === void 0 ? void 0 : _a.root) },
8460
- showButtons && (React__default['default'].createElement(HorizontalGalleryNavigationButton, { key: "previous-nav-button", icon: React__default['default'].createElement(react.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.horizontalGalleryLeftNavButton })),
8461
- React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(childrenContainerStyle, { '> *': (_b = props.styles) === null || _b === void 0 ? void 0 : _b.children }) }, childrenOnCurrentPage),
8462
- showButtons && (React__default['default'].createElement(HorizontalGalleryNavigationButton, { key: "next-nav-button", icon: React__default['default'].createElement(react.Icon, { iconName: "HorizontalGalleryRightButton" }), styles: styles === null || styles === void 0 ? void 0 : styles.nextButton, onClick: () => setPage(Math.min(lastPage, page + 1)), disabled: disableNextButton, identifier: ids.horizontalGalleryRightNavButton }))));
8463
- };
8464
- const HorizontalGalleryNavigationButton = (props) => {
8465
- const theme = useTheme();
8466
- return (React__default['default'].createElement(react.DefaultButton, { className: react.mergeStyles(leftRightButtonStyles(theme), props.styles), onClick: props.onClick, disabled: props.disabled, "data-ui-id": props.identifier }, props.icon));
8467
- };
8468
- function bucketize(arr, bucketSize) {
8469
- const bucketArray = [];
8470
- if (bucketSize <= 0) {
8471
- return bucketArray;
8472
- }
8473
- for (let i = 0; i < arr.length; i += bucketSize) {
8474
- bucketArray.push(arr.slice(i, i + bucketSize));
8475
- }
8476
- return bucketArray;
8477
- }
8478
-
8479
- // Copyright (c) Microsoft Corporation.
8480
- /**
8481
- * Wrapped HorizontalGallery that adjusts the number of items per page based on the
8482
- * available width obtained from a ResizeObserver, width per child, gap width, and button width
8483
- */
8484
- const ResponsiveHorizontalGallery = (props) => {
8485
- const { childWidthRem, gapWidthRem, buttonWidthRem = 0 } = props;
8486
- const containerRef = React.useRef(null);
8487
- const containerWidth = _useContainerWidth(containerRef);
8488
- const leftPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingLeft) : 0;
8489
- const rightPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingRight) : 0;
8490
- const childrenPerPage = calculateChildrenPerPage({
8491
- numberOfChildren: React__default['default'].Children.count(props.children),
8492
- containerWidth: (containerWidth !== null && containerWidth !== void 0 ? containerWidth : 0) - leftPadding - rightPadding,
8493
- childWidthRem,
8494
- gapWidthRem,
8495
- buttonWidthRem
8496
- });
8497
- return (React__default['default'].createElement("div", { ref: containerRef, className: react.mergeStyles(props.containerStyles) },
8498
- React__default['default'].createElement(HorizontalGallery, { childrenPerPage: childrenPerPage, styles: props.horizontalGalleryStyles }, props.children)));
8499
- };
8500
- /**
8501
- * Helper function to calculate children per page for HorizontalGallery based on width of container, child, buttons, and
8502
- * gaps in between
8503
- */
8504
- const calculateChildrenPerPage = (args) => {
8505
- const { numberOfChildren, containerWidth, buttonWidthRem, childWidthRem, gapWidthRem } = args;
8506
- const childWidth = _convertRemToPx(childWidthRem);
8507
- const gapWidth = _convertRemToPx(gapWidthRem);
8508
- /** First check how many children can fit in containerWidth.
8509
- * __________________________________
8510
- * | || |
8511
- * | || |
8512
- * |________________||________________|
8513
- * <-----------containerWidth--------->
8514
- * containerWidth = n * childWidth + (n - 1) * gapWidth. Isolate n and take the floor.
8515
- */
8516
- const numberOfChildrenInContainer = Math.floor((containerWidth + gapWidth) / (childWidth + gapWidth));
8517
- // If all children fit then return numberOfChildrenInContainer
8518
- if (numberOfChildren <= numberOfChildrenInContainer) {
8519
- return numberOfChildrenInContainer;
8520
- }
8521
- const buttonWidth = _convertRemToPx(buttonWidthRem);
8522
- /** We know we need to paginate. So we need to subtract the buttonWidth twice and gapWidth twice from
8523
- * containerWidth to compute childrenSpace
8524
- * <-----------containerWidth--------->
8525
- * __________________________________
8526
- * | || || || |
8527
- * |<|| || ||>|
8528
- * |_||_____________||_____________||_|
8529
- * <-------childrenSpace------>
8530
- */
8531
- const childrenSpace = containerWidth - 2 * buttonWidth - 2 * gapWidth;
8532
- // Now that we have childrenSpace width we can figure out how many children can fit in childrenSpace.
8533
- // childrenSpace = n * childWidth + (n - 1) * gapWidth. Isolate n and take the floor.
8534
- return Math.floor((childrenSpace + gapWidth) / (childWidth + gapWidth));
8535
- };
8536
-
8537
8389
  // Copyright (c) Microsoft Corporation.
8538
8390
  /**
8539
8391
  * @private
@@ -8548,11 +8400,11 @@ const videoGalleryContainerStyle = {
8548
8400
  /**
8549
8401
  * Small floating modal width and height in rem for small screen
8550
8402
  */
8551
- const SMALL_FLOATING_MODAL_SIZE_PX = { width: 64, height: 88 };
8403
+ const SMALL_FLOATING_MODAL_SIZE_PX$1 = { width: 64, height: 88 };
8552
8404
  /**
8553
8405
  * Large floating modal width and height in rem for large screen
8554
8406
  */
8555
- const LARGE_FLOATING_MODAL_SIZE_PX = { width: 160, height: 120 };
8407
+ const LARGE_FLOATING_MODAL_SIZE_PX$1 = { width: 160, height: 120 };
8556
8408
  /**
8557
8409
  * @private
8558
8410
  * z-index to ensure that the local video tile is above the video gallery.
@@ -8584,7 +8436,7 @@ const localVideoTileOuterPaddingPX = 8;
8584
8436
  * @private
8585
8437
  */
8586
8438
  const localVideoTileContainerStyle = (theme, isNarrow) => {
8587
- return Object.assign({ minWidth: isNarrow ? _pxToRem(SMALL_FLOATING_MODAL_SIZE_PX.width) : _pxToRem(LARGE_FLOATING_MODAL_SIZE_PX.width), minHeight: isNarrow ? _pxToRem(SMALL_FLOATING_MODAL_SIZE_PX.height) : _pxToRem(LARGE_FLOATING_MODAL_SIZE_PX.height), position: 'absolute', bottom: _pxToRem(localVideoTileOuterPaddingPX), borderRadius: theme.effects.roundedCorner4, overflow: 'hidden' }, (theme.rtl
8439
+ return Object.assign({ minWidth: isNarrow ? _pxToRem(SMALL_FLOATING_MODAL_SIZE_PX$1.width) : _pxToRem(LARGE_FLOATING_MODAL_SIZE_PX$1.width), minHeight: isNarrow ? _pxToRem(SMALL_FLOATING_MODAL_SIZE_PX$1.height) : _pxToRem(LARGE_FLOATING_MODAL_SIZE_PX$1.height), position: 'absolute', bottom: _pxToRem(localVideoTileOuterPaddingPX), borderRadius: theme.effects.roundedCorner4, overflow: 'hidden' }, (theme.rtl
8588
8440
  ? { left: _pxToRem(localVideoTileOuterPaddingPX) }
8589
8441
  : { right: _pxToRem(localVideoTileOuterPaddingPX) }));
8590
8442
  };
@@ -8607,58 +8459,6 @@ const floatingLocalVideoTileStyle = {
8607
8459
  width: '100%'
8608
8460
  }
8609
8461
  };
8610
- /**
8611
- * @private
8612
- */
8613
- const horizontalGalleryContainerStyle = (shouldFloatLocalVideo, isNarrow) => {
8614
- return {
8615
- minHeight: isNarrow
8616
- ? `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`
8617
- : `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
8618
- width: shouldFloatLocalVideo
8619
- ? isNarrow
8620
- ? `calc(100% - ${_pxToRem(SMALL_FLOATING_MODAL_SIZE_PX.width)})`
8621
- : `calc(100% - ${_pxToRem(LARGE_FLOATING_MODAL_SIZE_PX.width)})`
8622
- : '100%',
8623
- paddingRight: '0.5rem'
8624
- };
8625
- };
8626
- /**
8627
- * @private
8628
- */
8629
- const horizontalGalleryStyle = (isNarrow) => {
8630
- return {
8631
- children: isNarrow ? SMALL_HORIZONTAL_GALLERY_TILE_STYLE : LARGE_HORIZONTAL_GALLERY_TILE_STYLE
8632
- };
8633
- };
8634
- /**
8635
- * Small horizontal gallery tile size in rem
8636
- * @private
8637
- */
8638
- const SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM = { height: 5.5, width: 5.5 };
8639
- /**
8640
- * Large horizontal gallery tile size in rem
8641
- * @private
8642
- */
8643
- const LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM = { height: 7.5, width: 10 };
8644
- /**
8645
- * @private
8646
- */
8647
- const SMALL_HORIZONTAL_GALLERY_TILE_STYLE = {
8648
- minHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
8649
- minWidth: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`,
8650
- maxHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
8651
- maxWidth: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`
8652
- };
8653
- /**
8654
- * @private
8655
- */
8656
- const LARGE_HORIZONTAL_GALLERY_TILE_STYLE = {
8657
- minHeight: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
8658
- minWidth: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`,
8659
- maxHeight: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
8660
- maxWidth: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`
8661
- };
8662
8462
  /**
8663
8463
  * @private
8664
8464
  */
@@ -9566,6 +9366,334 @@ const FloatingLocalCameraCycleButton = (props) => {
9566
9366
  (localVideoCameraCycleButtonProps === null || localVideoCameraCycleButtonProps === void 0 ? void 0 : localVideoCameraCycleButtonProps.onSelectCamera) !== undefined && (React__default['default'].createElement(LocalVideoCameraCycleButton, { cameras: localVideoCameraCycleButtonProps.cameras, selectedCamera: localVideoCameraCycleButtonProps.selectedCamera, onSelectCamera: localVideoCameraCycleButtonProps.onSelectCamera, label: localVideoCameraSwitcherLabel, ariaDescription: ariaDescription }))));
9567
9367
  };
9568
9368
 
9369
+ // Copyright (c) Microsoft Corporation.
9370
+ // Licensed under the MIT license.
9371
+ /**
9372
+ * @private
9373
+ */
9374
+ const rootLayoutStyle = {
9375
+ root: { position: 'relative', height: '100%', width: '100%', padding: '0.5rem' }
9376
+ };
9377
+
9378
+ // Copyright (c) Microsoft Corporation.
9379
+ // Licensed under the MIT license.
9380
+ /**
9381
+ * Horizontal Gallery button width in rem
9382
+ */
9383
+ const HORIZONTAL_GALLERY_BUTTON_WIDTH = 1.75;
9384
+ /**
9385
+ * @private
9386
+ */
9387
+ const leftRightButtonStyles = (theme) => {
9388
+ return {
9389
+ background: 'none',
9390
+ padding: 0,
9391
+ height: 'auto',
9392
+ minWidth: `${HORIZONTAL_GALLERY_BUTTON_WIDTH}rem`,
9393
+ maxWidth: `${HORIZONTAL_GALLERY_BUTTON_WIDTH}rem`,
9394
+ border: `1px solid ${theme.palette.neutralLight}`,
9395
+ borderRadius: theme.effects.roundedCorner4
9396
+ };
9397
+ };
9398
+ /**
9399
+ * Horizontal Gallery gap size in rem between tiles and buttons
9400
+ */
9401
+ const HORIZONTAL_GALLERY_GAP = 0.5;
9402
+ /**
9403
+ * @private
9404
+ */
9405
+ const rootStyle = {
9406
+ height: '100%',
9407
+ width: '100%',
9408
+ gap: `${HORIZONTAL_GALLERY_GAP}rem`
9409
+ };
9410
+ /**
9411
+ * @private
9412
+ */
9413
+ const childrenContainerStyle = {
9414
+ height: '100%',
9415
+ gap: `${HORIZONTAL_GALLERY_GAP}rem`
9416
+ };
9417
+
9418
+ // Copyright (c) Microsoft Corporation.
9419
+ /**
9420
+ * {@link HorizontalGallery} default children per page
9421
+ */
9422
+ const DEFAULT_CHILDREN_PER_PAGE = 5;
9423
+ /**
9424
+ * Renders a horizontal gallery that parents children horizontally. Handles pagination based on the childrenPerPage prop.
9425
+ * @param props - HorizontalGalleryProps {@link @azure/communication-react#HorizontalGalleryProps}
9426
+ * @returns
9427
+ */
9428
+ const HorizontalGallery = (props) => {
9429
+ var _a, _b;
9430
+ const { children, childrenPerPage = DEFAULT_CHILDREN_PER_PAGE, styles } = props;
9431
+ const ids = useIdentifiers();
9432
+ const [page, setPage] = React.useState(0);
9433
+ const numberOfChildren = React__default['default'].Children.count(children);
9434
+ const lastPage = Math.ceil(numberOfChildren / childrenPerPage) - 1;
9435
+ const paginatedChildren = React.useMemo(() => {
9436
+ return bucketize(React__default['default'].Children.toArray(children), childrenPerPage);
9437
+ }, [children, childrenPerPage]);
9438
+ // If children per page is 0 or less return empty element
9439
+ if (childrenPerPage <= 0) {
9440
+ return React__default['default'].createElement(React__default['default'].Fragment, null);
9441
+ }
9442
+ const firstIndexOfCurrentPage = page * childrenPerPage;
9443
+ const clippedPage = firstIndexOfCurrentPage < numberOfChildren - 1 ? page : lastPage;
9444
+ const childrenOnCurrentPage = paginatedChildren[clippedPage];
9445
+ const showButtons = numberOfChildren > childrenPerPage;
9446
+ const disablePreviousButton = page === 0;
9447
+ const disableNextButton = page === lastPage;
9448
+ return (React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(rootStyle, (_a = props.styles) === null || _a === void 0 ? void 0 : _a.root) },
9449
+ showButtons && (React__default['default'].createElement(HorizontalGalleryNavigationButton, { key: "previous-nav-button", icon: React__default['default'].createElement(react.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.horizontalGalleryLeftNavButton })),
9450
+ React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(childrenContainerStyle, { '> *': (_b = props.styles) === null || _b === void 0 ? void 0 : _b.children }) }, childrenOnCurrentPage),
9451
+ showButtons && (React__default['default'].createElement(HorizontalGalleryNavigationButton, { key: "next-nav-button", icon: React__default['default'].createElement(react.Icon, { iconName: "HorizontalGalleryRightButton" }), styles: styles === null || styles === void 0 ? void 0 : styles.nextButton, onClick: () => setPage(Math.min(lastPage, page + 1)), disabled: disableNextButton, identifier: ids.horizontalGalleryRightNavButton }))));
9452
+ };
9453
+ const HorizontalGalleryNavigationButton = (props) => {
9454
+ const theme = useTheme();
9455
+ return (React__default['default'].createElement(react.DefaultButton, { className: react.mergeStyles(leftRightButtonStyles(theme), props.styles), onClick: props.onClick, disabled: props.disabled, "data-ui-id": props.identifier }, props.icon));
9456
+ };
9457
+ function bucketize(arr, bucketSize) {
9458
+ const bucketArray = [];
9459
+ if (bucketSize <= 0) {
9460
+ return bucketArray;
9461
+ }
9462
+ for (let i = 0; i < arr.length; i += bucketSize) {
9463
+ bucketArray.push(arr.slice(i, i + bucketSize));
9464
+ }
9465
+ return bucketArray;
9466
+ }
9467
+
9468
+ // Copyright (c) Microsoft Corporation.
9469
+ /**
9470
+ * Wrapped HorizontalGallery that adjusts the number of items per page based on the
9471
+ * available width obtained from a ResizeObserver, width per child, gap width, and button width
9472
+ */
9473
+ const ResponsiveHorizontalGallery = (props) => {
9474
+ const { childWidthRem, gapWidthRem, buttonWidthRem = 0 } = props;
9475
+ const containerRef = React.useRef(null);
9476
+ const containerWidth = _useContainerWidth(containerRef);
9477
+ const leftPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingLeft) : 0;
9478
+ const rightPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingRight) : 0;
9479
+ const childrenPerPage = calculateChildrenPerPage({
9480
+ numberOfChildren: React__default['default'].Children.count(props.children),
9481
+ containerWidth: (containerWidth !== null && containerWidth !== void 0 ? containerWidth : 0) - leftPadding - rightPadding,
9482
+ childWidthRem,
9483
+ gapWidthRem,
9484
+ buttonWidthRem
9485
+ });
9486
+ return (React__default['default'].createElement("div", { ref: containerRef, className: react.mergeStyles(props.containerStyles) },
9487
+ React__default['default'].createElement(HorizontalGallery, { childrenPerPage: childrenPerPage, styles: props.horizontalGalleryStyles }, props.children)));
9488
+ };
9489
+ /**
9490
+ * Helper function to calculate children per page for HorizontalGallery based on width of container, child, buttons, and
9491
+ * gaps in between
9492
+ */
9493
+ const calculateChildrenPerPage = (args) => {
9494
+ const { numberOfChildren, containerWidth, buttonWidthRem, childWidthRem, gapWidthRem } = args;
9495
+ const childWidth = _convertRemToPx(childWidthRem);
9496
+ const gapWidth = _convertRemToPx(gapWidthRem);
9497
+ /** First check how many children can fit in containerWidth.
9498
+ * __________________________________
9499
+ * | || |
9500
+ * | || |
9501
+ * |________________||________________|
9502
+ * <-----------containerWidth--------->
9503
+ * containerWidth = n * childWidth + (n - 1) * gapWidth. Isolate n and take the floor.
9504
+ */
9505
+ const numberOfChildrenInContainer = Math.floor((containerWidth + gapWidth) / (childWidth + gapWidth));
9506
+ // If all children fit then return numberOfChildrenInContainer
9507
+ if (numberOfChildren <= numberOfChildrenInContainer) {
9508
+ return numberOfChildrenInContainer;
9509
+ }
9510
+ const buttonWidth = _convertRemToPx(buttonWidthRem);
9511
+ /** We know we need to paginate. So we need to subtract the buttonWidth twice and gapWidth twice from
9512
+ * containerWidth to compute childrenSpace
9513
+ * <-----------containerWidth--------->
9514
+ * __________________________________
9515
+ * | || || || |
9516
+ * |<|| || ||>|
9517
+ * |_||_____________||_____________||_|
9518
+ * <-------childrenSpace------>
9519
+ */
9520
+ const childrenSpace = containerWidth - 2 * buttonWidth - 2 * gapWidth;
9521
+ // Now that we have childrenSpace width we can figure out how many children can fit in childrenSpace.
9522
+ // childrenSpace = n * childWidth + (n - 1) * gapWidth. Isolate n and take the floor.
9523
+ return Math.floor((childrenSpace + gapWidth) / (childWidth + gapWidth));
9524
+ };
9525
+
9526
+ // Copyright (c) Microsoft Corporation.
9527
+ /**
9528
+ * Small floating modal width and height in rem for small screen
9529
+ */
9530
+ const SMALL_FLOATING_MODAL_SIZE_PX = { width: 64, height: 88 };
9531
+ /**
9532
+ * Large floating modal width and height in rem for large screen
9533
+ */
9534
+ const LARGE_FLOATING_MODAL_SIZE_PX = { width: 160, height: 120 };
9535
+ /**
9536
+ * @private
9537
+ */
9538
+ const horizontalGalleryContainerStyle = (shouldFloatLocalVideo, isNarrow) => {
9539
+ return {
9540
+ minHeight: isNarrow
9541
+ ? `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`
9542
+ : `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9543
+ width: shouldFloatLocalVideo
9544
+ ? isNarrow
9545
+ ? `calc(100% - ${_pxToRem(SMALL_FLOATING_MODAL_SIZE_PX.width)})`
9546
+ : `calc(100% - ${_pxToRem(LARGE_FLOATING_MODAL_SIZE_PX.width)})`
9547
+ : '100%',
9548
+ paddingRight: '0.5rem'
9549
+ };
9550
+ };
9551
+ /**
9552
+ * @private
9553
+ */
9554
+ const horizontalGalleryStyle = (isNarrow) => {
9555
+ return {
9556
+ children: isNarrow ? SMALL_HORIZONTAL_GALLERY_TILE_STYLE : LARGE_HORIZONTAL_GALLERY_TILE_STYLE
9557
+ };
9558
+ };
9559
+ /**
9560
+ * Small horizontal gallery tile size in rem
9561
+ * @private
9562
+ */
9563
+ const SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM = { height: 5.5, width: 5.5 };
9564
+ /**
9565
+ * Large horizontal gallery tile size in rem
9566
+ * @private
9567
+ */
9568
+ const LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM = { height: 7.5, width: 10 };
9569
+ /**
9570
+ * @private
9571
+ */
9572
+ const SMALL_HORIZONTAL_GALLERY_TILE_STYLE = {
9573
+ minHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9574
+ minWidth: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`,
9575
+ maxHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9576
+ maxWidth: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`
9577
+ };
9578
+ /**
9579
+ * @private
9580
+ */
9581
+ const LARGE_HORIZONTAL_GALLERY_TILE_STYLE = {
9582
+ minHeight: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9583
+ minWidth: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`,
9584
+ maxHeight: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9585
+ maxWidth: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`
9586
+ };
9587
+
9588
+ // Copyright (c) Microsoft Corporation.
9589
+ /**
9590
+ * A ResponsiveHorizontalGallery styled for the @link{VideoGallery}
9591
+ */
9592
+ const VideoGalleryResponsiveHorizontalGallery = (props) => {
9593
+ const { shouldFloatLocalVideo = false, isNarrow = false, horizontalGalleryElements, styles } = props;
9594
+ const containerStyles = React.useMemo(() => horizontalGalleryContainerStyle(shouldFloatLocalVideo, isNarrow), [shouldFloatLocalVideo, isNarrow]);
9595
+ const galleryStyles = React.useMemo(() => react.concatStyleSets(horizontalGalleryStyle(isNarrow), styles), [isNarrow, styles]);
9596
+ return (React__default['default'].createElement(react.Stack, { styles: { root: { paddingTop: '0.5rem' } } },
9597
+ React__default['default'].createElement(ResponsiveHorizontalGallery, { key: "responsive-horizontal-gallery", containerStyles: containerStyles, horizontalGalleryStyles: galleryStyles, childWidthRem: isNarrow ? SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width : LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width, buttonWidthRem: HORIZONTAL_GALLERY_BUTTON_WIDTH, gapWidthRem: HORIZONTAL_GALLERY_GAP }, horizontalGalleryElements)));
9598
+ };
9599
+
9600
+ // Copyright (c) Microsoft Corporation.
9601
+ const DEFAULT_MAX_REMOTE_VIDEOSTREAMS = 4;
9602
+ const DEFAULT_MAX_AUDIO_DOMINANT_SPEAKERS = 6;
9603
+ /**
9604
+ * @private
9605
+ */
9606
+ const useFloatingLocalVideoLayout = (props) => {
9607
+ var _a, _b;
9608
+ const visibleVideoParticipants = React.useRef([]);
9609
+ const visibleAudioParticipants = React.useRef([]);
9610
+ const { remoteParticipants, dominantSpeakers, maxRemoteVideoStreams = DEFAULT_MAX_REMOTE_VIDEOSTREAMS, maxAudioDominantSpeakers = DEFAULT_MAX_AUDIO_DOMINANT_SPEAKERS, isScreenShareActive = false } = props;
9611
+ visibleVideoParticipants.current = smartDominantSpeakerParticipants({
9612
+ participants: (_a = remoteParticipants === null || remoteParticipants === void 0 ? void 0 : remoteParticipants.filter((p) => { var _a; return (_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable; })) !== null && _a !== void 0 ? _a : [],
9613
+ dominantSpeakers,
9614
+ lastVisibleParticipants: visibleVideoParticipants.current,
9615
+ maxDominantSpeakers: maxRemoteVideoStreams
9616
+ }).slice(0, maxRemoteVideoStreams);
9617
+ const visibleVideoParticipantsSet = new Set(visibleVideoParticipants.current.map((p) => p.userId));
9618
+ /* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
9619
+ const callingParticipants = remoteParticipants.filter((p) => p.state === ('Connecting' ));
9620
+ /* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
9621
+ const callingParticipantsSet = new Set(callingParticipants.map((p) => p.userId));
9622
+ visibleAudioParticipants.current = smartDominantSpeakerParticipants({
9623
+ participants: (_b = remoteParticipants === null || remoteParticipants === void 0 ? void 0 : remoteParticipants.filter((p) => !visibleVideoParticipantsSet.has(p.userId) &&
9624
+ /* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */ !callingParticipantsSet.has(p.userId))) !== null && _b !== void 0 ? _b : [],
9625
+ dominantSpeakers,
9626
+ lastVisibleParticipants: visibleAudioParticipants.current,
9627
+ maxDominantSpeakers: maxAudioDominantSpeakers
9628
+ });
9629
+ const getGridParticipants = React.useCallback(() => {
9630
+ /* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
9631
+ return visibleVideoParticipants.current.length > 0
9632
+ ? visibleVideoParticipants.current
9633
+ : visibleAudioParticipants.current.concat(callingParticipants);
9634
+ }, [
9635
+ /* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */ callingParticipants
9636
+ ]);
9637
+ const gridParticipants = getGridParticipants();
9638
+ const getHorizontalGalleryRemoteParticipants = React.useCallback(() => {
9639
+ if (isScreenShareActive) {
9640
+ // If screen sharing is active, assign video and audio participants as horizontal gallery participants
9641
+ /* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
9642
+ return visibleVideoParticipants.current.concat(visibleAudioParticipants.current.concat(callingParticipants));
9643
+ }
9644
+ else {
9645
+ // If screen sharing is not active, then assign all video tiles as grid tiles.
9646
+ // If there are no video tiles, then assign audio tiles as grid tiles.
9647
+ /* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
9648
+ return visibleVideoParticipants.current.length > 0
9649
+ ? visibleAudioParticipants.current.concat(callingParticipants)
9650
+ : [];
9651
+ }
9652
+ }, [
9653
+ /* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */ callingParticipants,
9654
+ isScreenShareActive
9655
+ ]);
9656
+ const horizontalGalleryParticipants = getHorizontalGalleryRemoteParticipants();
9657
+ return { gridParticipants, horizontalGalleryParticipants };
9658
+ };
9659
+
9660
+ // Copyright (c) Microsoft Corporation.
9661
+ /**
9662
+ * DefaultLayout displays remote participants, local video component, and screen sharing component in
9663
+ * a grid and horizontal gallery.
9664
+ *
9665
+ * @private
9666
+ */
9667
+ const DefaultLayout = (props) => {
9668
+ const { remoteParticipants = [], dominantSpeakers, localVideoComponent, screenShareComponent, onRenderRemoteParticipant, styles, maxRemoteVideoStreams, parentWidth } = props;
9669
+ const isNarrow = parentWidth ? isNarrowWidth(parentWidth) : false;
9670
+ const floatingLocalVideoLayout = useFloatingLocalVideoLayout({
9671
+ remoteParticipants,
9672
+ dominantSpeakers,
9673
+ maxRemoteVideoStreams,
9674
+ isScreenShareActive: !!screenShareComponent
9675
+ });
9676
+ let activeVideoStreams = 0;
9677
+ const gridTiles = floatingLocalVideoLayout.gridParticipants.map((p) => {
9678
+ var _a, _b;
9679
+ return onRenderRemoteParticipant(p, maxRemoteVideoStreams && maxRemoteVideoStreams >= 0
9680
+ ? ((_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable) && activeVideoStreams++ < maxRemoteVideoStreams
9681
+ : (_b = p.videoStream) === null || _b === void 0 ? void 0 : _b.isAvailable);
9682
+ });
9683
+ const horizontalGalleryTiles = floatingLocalVideoLayout.horizontalGalleryParticipants.map((p) => {
9684
+ var _a, _b;
9685
+ return onRenderRemoteParticipant(p, maxRemoteVideoStreams && maxRemoteVideoStreams >= 0
9686
+ ? ((_a = p.videoStream) === null || _a === void 0 ? void 0 : _a.isAvailable) && activeVideoStreams++ < maxRemoteVideoStreams
9687
+ : (_b = p.videoStream) === null || _b === void 0 ? void 0 : _b.isAvailable);
9688
+ });
9689
+ if (localVideoComponent) {
9690
+ gridTiles.push(localVideoComponent);
9691
+ }
9692
+ return (React__default['default'].createElement(react.Stack, { horizontal: false, styles: rootLayoutStyle },
9693
+ screenShareComponent ? (screenShareComponent) : (React__default['default'].createElement(GridLayout, { key: "grid-layout", styles: styles === null || styles === void 0 ? void 0 : styles.gridLayout }, gridTiles)),
9694
+ horizontalGalleryTiles.length > 0 && (React__default['default'].createElement(VideoGalleryResponsiveHorizontalGallery, { isNarrow: isNarrow, horizontalGalleryElements: horizontalGalleryTiles, styles: styles === null || styles === void 0 ? void 0 : styles.horizontalGallery }))));
9695
+ };
9696
+
9569
9697
  // Copyright (c) Microsoft Corporation.
9570
9698
  /**
9571
9699
  * @private
@@ -9611,8 +9739,8 @@ const VideoGallery = (props) => {
9611
9739
  const visibleAudioParticipants = React.useRef([]);
9612
9740
  /* @conditional-compile-remove(PSTN-calls) */ /* @conditional-compile-remove(one-to-n-calling) */
9613
9741
  const visibleCallingParticipants = React.useRef([]);
9614
- const modalWidth = isNarrow ? SMALL_FLOATING_MODAL_SIZE_PX.width : LARGE_FLOATING_MODAL_SIZE_PX.width;
9615
- const modalHeight = isNarrow ? SMALL_FLOATING_MODAL_SIZE_PX.height : LARGE_FLOATING_MODAL_SIZE_PX.height;
9742
+ const modalWidth = isNarrow ? SMALL_FLOATING_MODAL_SIZE_PX$1.width : LARGE_FLOATING_MODAL_SIZE_PX$1.width;
9743
+ const modalHeight = isNarrow ? SMALL_FLOATING_MODAL_SIZE_PX$1.height : LARGE_FLOATING_MODAL_SIZE_PX$1.height;
9616
9744
  // The minimum drag position is the top left of the video gallery. i.e. the modal (PiP) should not be able
9617
9745
  // to be dragged offscreen and these are the top and left bounds of that calculation.
9618
9746
  const modalMinDragPosition = React.useMemo(() => containerWidth && containerHeight
@@ -9733,21 +9861,29 @@ const VideoGallery = (props) => {
9733
9861
  const remoteScreenShareComponent = screenShareParticipant && (React__default['default'].createElement(RemoteScreenShare, Object.assign({}, screenShareParticipant, { renderElement: (_d = screenShareParticipant.screenShareStream) === null || _d === void 0 ? void 0 : _d.renderElement, onCreateRemoteStreamView: onCreateRemoteStreamView, onDisposeRemoteStreamView: onDisposeRemoteStreamView, isReceiving: (_e = screenShareParticipant.screenShareStream) === null || _e === void 0 ? void 0 : _e.isReceiving })));
9734
9862
  const horizontalGalleryPresent = horizontalGalleryTiles && horizontalGalleryTiles.length > 0;
9735
9863
  const layerHostId = reactHooks.useId('layerhost');
9864
+ if (layout === 'floatingLocalVideo') {
9865
+ return (React__default['default'].createElement("div", { "data-ui-id": ids.videoGallery, ref: containerRef, className: react.mergeStyles(videoGalleryOuterDivStyle, styles === null || styles === void 0 ? void 0 : styles.root) },
9866
+ shouldFloatLocalVideo &&
9867
+ !shouldFloatNonDraggableLocalVideo &&
9868
+ localVideoTile &&
9869
+ (horizontalGalleryPresent ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileContainerStyle(theme, isNarrow)) }, localVideoTile)) : (React__default['default'].createElement(_ModalClone, { isOpen: true, isModeless: true, dragOptions: DRAG_OPTIONS$1, styles: floatingLocalVideoModalStyle(theme, isNarrow), layerProps: { hostId: layerHostId }, maxDragPosition: modalMaxDragPosition, minDragPosition: modalMinDragPosition }, localVideoTile))),
9870
+ // When we use showCameraSwitcherInLocalPreview it disables dragging to allow keyboard navigation.
9871
+ shouldFloatNonDraggableLocalVideo && localVideoTile && remoteParticipants.length > 0 && (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileWithControlsContainerStyle(theme, isNarrow), {
9872
+ boxShadow: theme.effects.elevation8,
9873
+ zIndex: LOCAL_VIDEO_TILE_ZINDEX
9874
+ }) }, localVideoTile)),
9875
+ React__default['default'].createElement(react.Stack, { horizontal: false, styles: videoGalleryContainerStyle },
9876
+ screenShareParticipant ? (remoteScreenShareComponent) : (localParticipant === null || localParticipant === void 0 ? void 0 : localParticipant.isScreenSharingOn) ? (localScreenShareStreamComponent) : (React__default['default'].createElement(GridLayout, { key: "grid-layout", styles: styles === null || styles === void 0 ? void 0 : styles.gridLayout }, gridTiles)),
9877
+ horizontalGalleryPresent && (React__default['default'].createElement(VideoGalleryResponsiveHorizontalGallery, { shouldFloatLocalVideo: true, isNarrow: isNarrow, horizontalGalleryElements: horizontalGalleryTiles, styles: styles === null || styles === void 0 ? void 0 : styles.horizontalGallery })),
9878
+ React__default['default'].createElement(react.LayerHost, { id: layerHostId, className: react.mergeStyles(layerHostStyle) }))));
9879
+ }
9880
+ const screenShareComponent = remoteScreenShareComponent
9881
+ ? remoteScreenShareComponent
9882
+ : localParticipant.isScreenSharingOn
9883
+ ? localScreenShareStreamComponent
9884
+ : undefined;
9736
9885
  return (React__default['default'].createElement("div", { "data-ui-id": ids.videoGallery, ref: containerRef, className: react.mergeStyles(videoGalleryOuterDivStyle, styles === null || styles === void 0 ? void 0 : styles.root) },
9737
- shouldFloatLocalVideo &&
9738
- !shouldFloatNonDraggableLocalVideo &&
9739
- localVideoTile &&
9740
- (horizontalGalleryPresent ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileContainerStyle(theme, isNarrow)) }, localVideoTile)) : (React__default['default'].createElement(_ModalClone, { isOpen: true, isModeless: true, dragOptions: DRAG_OPTIONS$1, styles: floatingLocalVideoModalStyle(theme, isNarrow), layerProps: { hostId: layerHostId }, maxDragPosition: modalMaxDragPosition, minDragPosition: modalMinDragPosition }, localVideoTile))),
9741
- // When we use showCameraSwitcherInLocalPreview it disables dragging to allow keyboard navigation.
9742
- shouldFloatNonDraggableLocalVideo && localVideoTile && remoteParticipants.length > 0 && (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileWithControlsContainerStyle(theme, isNarrow), {
9743
- boxShadow: theme.effects.elevation8,
9744
- zIndex: LOCAL_VIDEO_TILE_ZINDEX
9745
- }) }, localVideoTile)),
9746
- React__default['default'].createElement(react.Stack, { horizontal: false, styles: videoGalleryContainerStyle },
9747
- screenShareParticipant ? (remoteScreenShareComponent) : (localParticipant === null || localParticipant === void 0 ? void 0 : localParticipant.isScreenSharingOn) ? (localScreenShareStreamComponent) : (React__default['default'].createElement(GridLayout, { key: "grid-layout", styles: styles === null || styles === void 0 ? void 0 : styles.gridLayout }, gridTiles)),
9748
- horizontalGalleryPresent && (React__default['default'].createElement("div", { style: { paddingTop: '0.5rem' } },
9749
- React__default['default'].createElement(ResponsiveHorizontalGallery, { key: "responsive-horizontal-gallery", containerStyles: horizontalGalleryContainerStyle(shouldFloatLocalVideo, isNarrow), horizontalGalleryStyles: react.concatStyleSets(horizontalGalleryStyle(isNarrow), styles === null || styles === void 0 ? void 0 : styles.horizontalGallery), childWidthRem: isNarrow ? SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width : LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width, buttonWidthRem: HORIZONTAL_GALLERY_BUTTON_WIDTH, gapWidthRem: HORIZONTAL_GALLERY_GAP }, horizontalGalleryTiles))),
9750
- React__default['default'].createElement(react.LayerHost, { id: layerHostId, className: react.mergeStyles(layerHostStyle) }))));
9886
+ React__default['default'].createElement(DefaultLayout, { remoteParticipants: remoteParticipants, onRenderRemoteParticipant: onRenderRemoteVideoTile !== null && onRenderRemoteVideoTile !== void 0 ? onRenderRemoteVideoTile : defaultOnRenderVideoTile, localVideoComponent: localVideoTile, screenShareComponent: screenShareComponent, maxRemoteVideoStreams: maxRemoteVideoStreams, dominantSpeakers: dominantSpeakers, parentWidth: containerWidth, styles: styles })));
9751
9887
  };
9752
9888
 
9753
9889
  // Copyright (c) Microsoft Corporation.