@azure/communication-react 1.5.1-alpha-202302250014 → 1.5.1-alpha-202303010017

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 (42) hide show
  1. package/dist/communication-react.d.ts +12 -0
  2. package/dist/dist-cjs/communication-react/index.js +521 -216
  3. package/dist/dist-cjs/communication-react/index.js.map +1 -1
  4. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
  5. package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
  6. package/dist/dist-esm/communication-react/src/index.d.ts +1 -0
  7. package/dist/dist-esm/communication-react/src/index.js.map +1 -1
  8. package/dist/dist-esm/react-components/src/components/ResponsiveVerticalGallery.d.ts +29 -0
  9. package/dist/dist-esm/react-components/src/components/ResponsiveVerticalGallery.js +77 -0
  10. package/dist/dist-esm/react-components/src/components/ResponsiveVerticalGallery.js.map +1 -0
  11. package/dist/dist-esm/react-components/src/components/VerticalGallery.d.ts +50 -0
  12. package/dist/dist-esm/react-components/src/components/VerticalGallery.js +85 -0
  13. package/dist/dist-esm/react-components/src/components/VerticalGallery.js.map +1 -0
  14. package/dist/dist-esm/react-components/src/components/VideoGallery/DefaultLayout.js +19 -13
  15. package/dist/dist-esm/react-components/src/components/VideoGallery/DefaultLayout.js.map +1 -1
  16. package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideo.d.ts +10 -3
  17. package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideo.js +6 -8
  18. package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideo.js.map +1 -1
  19. package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideoLayout.js +32 -16
  20. package/dist/dist-esm/react-components/src/components/VideoGallery/FloatingLocalVideoLayout.js.map +1 -1
  21. package/dist/dist-esm/react-components/src/components/VideoGallery/Layout.d.ts +6 -0
  22. package/dist/dist-esm/react-components/src/components/VideoGallery/Layout.js.map +1 -1
  23. package/dist/dist-esm/react-components/src/components/VideoGallery/{VideoGalleryResponsiveHorizontalGallery.d.ts → OverflowGallery.d.ts} +5 -3
  24. package/dist/dist-esm/react-components/src/components/VideoGallery/OverflowGallery.js +46 -0
  25. package/dist/dist-esm/react-components/src/components/VideoGallery/OverflowGallery.js.map +1 -0
  26. package/dist/dist-esm/react-components/src/components/VideoGallery/styles/FloatingLocalVideo.styles.d.ts +20 -3
  27. package/dist/dist-esm/react-components/src/components/VideoGallery/styles/FloatingLocalVideo.styles.js +11 -6
  28. package/dist/dist-esm/react-components/src/components/VideoGallery/styles/FloatingLocalVideo.styles.js.map +1 -1
  29. package/dist/dist-esm/react-components/src/components/VideoGallery/styles/VideoGalleryResponsiveVerticalGallery.styles.d.ts +38 -0
  30. package/dist/dist-esm/react-components/src/components/VideoGallery/styles/VideoGalleryResponsiveVerticalGallery.styles.js +44 -0
  31. package/dist/dist-esm/react-components/src/components/VideoGallery/styles/VideoGalleryResponsiveVerticalGallery.styles.js.map +1 -0
  32. package/dist/dist-esm/react-components/src/components/VideoGallery.d.ts +11 -0
  33. package/dist/dist-esm/react-components/src/components/VideoGallery.js +7 -3
  34. package/dist/dist-esm/react-components/src/components/VideoGallery.js.map +1 -1
  35. package/dist/dist-esm/react-components/src/components/index.d.ts +1 -0
  36. package/dist/dist-esm/react-components/src/components/index.js.map +1 -1
  37. package/dist/dist-esm/react-components/src/components/styles/VerticalGallery.styles.d.ts +32 -0
  38. package/dist/dist-esm/react-components/src/components/styles/VerticalGallery.styles.js +63 -0
  39. package/dist/dist-esm/react-components/src/components/styles/VerticalGallery.styles.js.map +1 -0
  40. package/package.json +8 -8
  41. package/dist/dist-esm/react-components/src/components/VideoGallery/VideoGalleryResponsiveHorizontalGallery.js +0 -19
  42. package/dist/dist-esm/react-components/src/components/VideoGallery/VideoGalleryResponsiveHorizontalGallery.js.map +0 -1
@@ -161,7 +161,7 @@ const _toCommunicationIdentifier = (id) => {
161
161
  // Copyright (c) Microsoft Corporation.
162
162
  // Licensed under the MIT license.
163
163
  // GENERATED FILE. DO NOT EDIT MANUALLY.
164
- var telemetryVersion = '1.5.1-alpha-202302250014';
164
+ var telemetryVersion = '1.5.1-alpha-202303010017';
165
165
 
166
166
  // Copyright (c) Microsoft Corporation.
167
167
  /**
@@ -9203,176 +9203,6 @@ const FloatingLocalCameraCycleButton = (props) => {
9203
9203
  (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 }))));
9204
9204
  };
9205
9205
 
9206
- // Copyright (c) Microsoft Corporation.
9207
- /**
9208
- * @private
9209
- */
9210
- react.mergeStyles({ position: 'relative', width: '100%', height: '100%' });
9211
- /**
9212
- * Small floating modal width and height in rem for small screen
9213
- */
9214
- const SMALL_FLOATING_MODAL_SIZE_PX = { width: 58, height: 104 };
9215
- /**
9216
- * Large floating modal width and height in rem for large screen
9217
- * Aspect ratio: 16:9
9218
- */
9219
- const LARGE_FLOATING_MODAL_SIZE_PX = { width: 215, height: 120 };
9220
- /**
9221
- * @private
9222
- * z-index to ensure that the local video tile is above the video gallery.
9223
- */
9224
- const LOCAL_VIDEO_TILE_ZINDEX = 2;
9225
- /**
9226
- * @private
9227
- */
9228
- const localVideoTileContainerStyle = (theme, isNarrow) => {
9229
- 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
9230
- ? { left: _pxToRem(localVideoTileOuterPaddingPX) }
9231
- : { right: _pxToRem(localVideoTileOuterPaddingPX) }));
9232
- };
9233
- /**
9234
- * @private
9235
- */
9236
- const localVideoTileWithControlsContainerStyle = (theme, isNarrow) => {
9237
- return react.concatStyleSets(localVideoTileContainerStyle(theme, isNarrow), {
9238
- root: { boxShadow: theme.effects.elevation8 }
9239
- });
9240
- };
9241
- /**
9242
- * @private
9243
- */
9244
- const floatingLocalVideoModalStyle = (theme, isNarrow) => {
9245
- return react.concatStyleSets({
9246
- main: localVideoTileContainerStyle(theme, isNarrow)
9247
- }, {
9248
- main: {
9249
- boxShadow: theme.effects.elevation8,
9250
- ':focus-within': {
9251
- boxShadow: theme.effects.elevation16,
9252
- border: `${_pxToRem(2)} solid ${theme.palette.neutralPrimary}`
9253
- }
9254
- }
9255
- }, localVideoModalStyles);
9256
- };
9257
- /**
9258
- * Padding equal to the amount the modal should stay inside the bounds of the container.
9259
- * i.e. if this is 8px, the modal should always be at least 8px inside the container at all times on all sides.
9260
- * @private
9261
- */
9262
- const localVideoTileOuterPaddingPX = 8;
9263
- /**
9264
- * @private
9265
- */
9266
- const floatingLocalVideoTileStyle = {
9267
- root: {
9268
- position: 'absolute',
9269
- zIndex: LOCAL_VIDEO_TILE_ZINDEX,
9270
- height: '100%',
9271
- width: '100%'
9272
- }
9273
- };
9274
- /**
9275
- * Styles for the local video tile modal when it is focused, will cause keyboard move icon to appear over video
9276
- * @private
9277
- */
9278
- const localVideoModalStyles = {
9279
- keyboardMoveIconContainer: {
9280
- zIndex: LOCAL_VIDEO_TILE_ZINDEX + 1 // zIndex to set the keyboard movement Icon above the other layers in the video tile.
9281
- }
9282
- };
9283
-
9284
- // Copyright (c) Microsoft Corporation.
9285
- /**
9286
- * @private
9287
- */
9288
- const horizontalGalleryContainerStyle = (shouldFloatLocalVideo, isNarrow) => {
9289
- return {
9290
- minHeight: isNarrow
9291
- ? `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`
9292
- : `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9293
- width: shouldFloatLocalVideo
9294
- ? isNarrow
9295
- ? `calc(100% - ${_pxToRem(SMALL_FLOATING_MODAL_SIZE_PX.width)})`
9296
- : `calc(100% - ${_pxToRem(LARGE_FLOATING_MODAL_SIZE_PX.width)})`
9297
- : '100%',
9298
- paddingRight: '0.5rem'
9299
- };
9300
- };
9301
- /**
9302
- * @private
9303
- */
9304
- const horizontalGalleryStyle = (isNarrow) => {
9305
- return {
9306
- children: isNarrow ? SMALL_HORIZONTAL_GALLERY_TILE_STYLE : LARGE_HORIZONTAL_GALLERY_TILE_STYLE
9307
- };
9308
- };
9309
- /**
9310
- * Small horizontal gallery tile size in rem
9311
- * @private
9312
- */
9313
- const SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM = { height: 6.5, width: 6.5 };
9314
- /**
9315
- * Large horizontal gallery tile size in rem
9316
- * @private
9317
- */
9318
- const LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM = { height: 7.5, width: 10 };
9319
- /**
9320
- * @private
9321
- */
9322
- const SMALL_HORIZONTAL_GALLERY_TILE_STYLE = {
9323
- minHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9324
- minWidth: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`,
9325
- maxHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9326
- maxWidth: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`
9327
- };
9328
- /**
9329
- * @private
9330
- */
9331
- const LARGE_HORIZONTAL_GALLERY_TILE_STYLE = {
9332
- minHeight: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9333
- minWidth: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`,
9334
- maxHeight: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9335
- maxWidth: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`
9336
- };
9337
-
9338
- // Copyright (c) Microsoft Corporation.
9339
- /**
9340
- * @private
9341
- */
9342
- const scrollableHorizontalGalleryStyles = {
9343
- root: {
9344
- width: '100%',
9345
- minHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9346
- paddingRight: '0.5rem',
9347
- '> *': SMALL_HORIZONTAL_GALLERY_TILE_STYLE
9348
- }
9349
- };
9350
- /**
9351
- * @private
9352
- */
9353
- const scrollableHorizontalGalleryContainerStyles = react.mergeStyles({
9354
- display: 'flex',
9355
- width: `calc(100% - ${SMALL_FLOATING_MODAL_SIZE_PX.width}px)`,
9356
- minHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9357
- overflow: 'scroll',
9358
- '-ms-overflow-style': 'none',
9359
- 'scrollbar-width': 'none',
9360
- '::-webkit-scrollbar': { display: 'none' }
9361
- });
9362
-
9363
- // Copyright (c) Microsoft Corporation.
9364
- /**
9365
- * Component to display elements horizontally in a scrollable container
9366
- * @private
9367
- */
9368
- const ScrollableHorizontalGallery = (props) => {
9369
- const { horizontalGalleryElements } = props;
9370
- const ref = React.useRef();
9371
- const { events: dragabbleEvents } = reactUseDraggableScroll.useDraggable(ref);
9372
- return (React__default['default'].createElement("div", Object.assign({ ref: ref }, dragabbleEvents, { className: scrollableHorizontalGalleryContainerStyles }),
9373
- React__default['default'].createElement(react.Stack, { "data-ui-id": "scrollable-horizontal-gallery", horizontal: true, styles: scrollableHorizontalGalleryStyles, tokens: { childrenGap: '0.5rem' } }, horizontalGalleryElements)));
9374
- };
9375
-
9376
9206
  // Copyright (c) Microsoft Corporation.
9377
9207
  // Licensed under the MIT license.
9378
9208
  /**
@@ -9562,7 +9392,7 @@ const HORIZONTAL_GALLERY_BUTTON_WIDTH = 1.75;
9562
9392
  /**
9563
9393
  * @private
9564
9394
  */
9565
- const leftRightButtonStyles = (theme) => {
9395
+ const leftRightButtonStyles$1 = (theme) => {
9566
9396
  return {
9567
9397
  background: 'none',
9568
9398
  padding: 0,
@@ -9580,7 +9410,7 @@ const HORIZONTAL_GALLERY_GAP = 0.5;
9580
9410
  /**
9581
9411
  * @private
9582
9412
  */
9583
- const rootStyle = {
9413
+ const rootStyle$1 = {
9584
9414
  height: '100%',
9585
9415
  width: '100%',
9586
9416
  gap: `${HORIZONTAL_GALLERY_GAP}rem`
@@ -9588,7 +9418,7 @@ const rootStyle = {
9588
9418
  /**
9589
9419
  * @private
9590
9420
  */
9591
- const childrenContainerStyle = {
9421
+ const childrenContainerStyle$1 = {
9592
9422
  height: '100%',
9593
9423
  gap: `${HORIZONTAL_GALLERY_GAP}rem`
9594
9424
  };
@@ -9645,14 +9475,14 @@ const HorizontalGallery = (props) => {
9645
9475
  const showButtons = numberOfChildren > childrenPerPage;
9646
9476
  const disablePreviousButton = page === 0;
9647
9477
  const disableNextButton = page === lastPage;
9648
- return (React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(rootStyle, (_a = props.styles) === null || _a === void 0 ? void 0 : _a.root) },
9478
+ return (React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(rootStyle$1, (_a = props.styles) === null || _a === void 0 ? void 0 : _a.root) },
9649
9479
  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 })),
9650
- React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(childrenContainerStyle, { '> *': (_b = props.styles) === null || _b === void 0 ? void 0 : _b.children }) }, childrenOnCurrentPage),
9480
+ React__default['default'].createElement(react.Stack, { horizontal: true, className: react.mergeStyles(childrenContainerStyle$1, { '> *': (_b = props.styles) === null || _b === void 0 ? void 0 : _b.children }) }, childrenOnCurrentPage),
9651
9481
  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 }))));
9652
9482
  };
9653
9483
  const HorizontalGalleryNavigationButton = (props) => {
9654
9484
  const theme = useTheme();
9655
- 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));
9485
+ return (React__default['default'].createElement(react.DefaultButton, { className: react.mergeStyles(leftRightButtonStyles$1(theme), props.styles), onClick: props.onClick, disabled: props.disabled, "data-ui-id": props.identifier }, props.icon));
9656
9486
  };
9657
9487
 
9658
9488
  // Copyright (c) Microsoft Corporation.
@@ -9666,7 +9496,7 @@ const ResponsiveHorizontalGallery = (props) => {
9666
9496
  const containerWidth = _useContainerWidth(containerRef);
9667
9497
  const leftPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingLeft) : 0;
9668
9498
  const rightPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingRight) : 0;
9669
- const childrenPerPage = calculateChildrenPerPage({
9499
+ const childrenPerPage = calculateChildrenPerPage$1({
9670
9500
  numberOfChildren: React__default['default'].Children.count(props.children),
9671
9501
  containerWidth: (containerWidth !== null && containerWidth !== void 0 ? containerWidth : 0) - leftPadding - rightPadding,
9672
9502
  childWidthRem,
@@ -9680,7 +9510,7 @@ const ResponsiveHorizontalGallery = (props) => {
9680
9510
  * Helper function to calculate children per page for HorizontalGallery based on width of container, child, buttons, and
9681
9511
  * gaps in between
9682
9512
  */
9683
- const calculateChildrenPerPage = (args) => {
9513
+ const calculateChildrenPerPage$1 = (args) => {
9684
9514
  const { numberOfChildren, containerWidth, buttonWidthRem, childWidthRem, gapWidthRem } = args;
9685
9515
  const childWidth = _convertRemToPx(childWidthRem);
9686
9516
  const gapWidth = _convertRemToPx(gapWidthRem);
@@ -9713,17 +9543,466 @@ const calculateChildrenPerPage = (args) => {
9713
9543
  return Math.floor((childrenSpace + gapWidth) / (childWidth + gapWidth));
9714
9544
  };
9715
9545
 
9546
+ // Copyright (c) Microsoft Corporation.
9547
+ // Licensed under the MIT license.
9548
+ /**
9549
+ * Vertical Gallery gap size in rem between tiles and buttons
9550
+ *
9551
+ * @private
9552
+ */
9553
+ const VERTICAL_GALLERY_GAP = 0.5;
9554
+ /**
9555
+ * @private
9556
+ */
9557
+ const childrenContainerStyle = {
9558
+ width: '100%',
9559
+ gap: `${VERTICAL_GALLERY_GAP}rem`
9560
+ };
9561
+ /**
9562
+ * @private
9563
+ */
9564
+ const rootStyle = {
9565
+ height: '100%',
9566
+ width: '100%',
9567
+ gap: `${VERTICAL_GALLERY_GAP}rem`,
9568
+ position: 'relative'
9569
+ };
9570
+ /**
9571
+ * @private
9572
+ */
9573
+ const pageNavigationControlBarContainerStyle = {
9574
+ height: '2rem',
9575
+ width: '100%',
9576
+ position: 'absolute',
9577
+ bottom: '0'
9578
+ };
9579
+ /**
9580
+ * @private
9581
+ */
9582
+ const leftRightButtonStyles = (theme) => {
9583
+ return {
9584
+ background: 'none',
9585
+ padding: 0,
9586
+ height: 'auto',
9587
+ borderRadius: theme.effects.roundedCorner4,
9588
+ border: 'none',
9589
+ minWidth: '2rem'
9590
+ };
9591
+ };
9592
+ /**
9593
+ * @private
9594
+ */
9595
+ const participantPageCounter = {
9596
+ lineHeight: '2rem',
9597
+ width: '100%',
9598
+ textAlign: 'center'
9599
+ };
9600
+ /**
9601
+ * @private
9602
+ */
9603
+ const navIconStyles = {
9604
+ root: {
9605
+ lineHeight: '0'
9606
+ }
9607
+ };
9608
+
9609
+ // Copyright (c) Microsoft Corporation.
9610
+ /**
9611
+ * VerticalGallery is a overflow gallery for participants in the {@link VideoGallery} component. Stacks
9612
+ * participants on the Y-axis of the VideoGallery for better use of horizontal space.
9613
+ *
9614
+ * @beta
9615
+ */
9616
+ const VerticalGallery = (props) => {
9617
+ const { children, styles, childrenPerPage } = props;
9618
+ const [page, setPage] = React.useState(0);
9619
+ const [buttonState, setButtonState] = React.useState({ previous: true, next: true });
9620
+ const numberOfChildren = React__default['default'].Children.count(children);
9621
+ const lastPage = Math.ceil(numberOfChildren / childrenPerPage) - 1;
9622
+ const paginatedChildren = React.useMemo(() => {
9623
+ return bucketize(React__default['default'].Children.toArray(children), childrenPerPage);
9624
+ }, [children, childrenPerPage]);
9625
+ const firstIndexOfCurrentPage = page * childrenPerPage;
9626
+ const clippedPage = firstIndexOfCurrentPage < numberOfChildren - 1 ? page : lastPage;
9627
+ const childrenOnCurrentPage = paginatedChildren[clippedPage];
9628
+ const showButtons = numberOfChildren > childrenPerPage;
9629
+ const onPreviousButtonClick = () => {
9630
+ setPage(page - 1);
9631
+ };
9632
+ const onNextButtonClick = () => {
9633
+ setPage(page + 1);
9634
+ };
9635
+ React.useEffect(() => {
9636
+ if (page > 0 && page < lastPage && showButtons) {
9637
+ // we are somewhere in between first and last pages.
9638
+ setButtonState({ previous: false, next: false });
9639
+ }
9640
+ else if (page === 0 && showButtons) {
9641
+ // we are on the first page.
9642
+ setButtonState({ previous: true, next: false });
9643
+ }
9644
+ else if (page === lastPage && showButtons) {
9645
+ // we are on the last page.
9646
+ setButtonState({ previous: false, next: true });
9647
+ }
9648
+ }, [page, numberOfChildren, lastPage, showButtons]);
9649
+ const childContainerStyle = React.useMemo(() => {
9650
+ return { root: childrenContainerStyle };
9651
+ }, []);
9652
+ const childrenStyles = React.useMemo(() => {
9653
+ return { root: styles === null || styles === void 0 ? void 0 : styles.children };
9654
+ }, [styles === null || styles === void 0 ? void 0 : styles.children]);
9655
+ if (childrenPerPage <= 0) {
9656
+ return React__default['default'].createElement(React__default['default'].Fragment, null);
9657
+ }
9658
+ return (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(rootStyle, styles === null || styles === void 0 ? void 0 : styles.root) },
9659
+ React__default['default'].createElement(react.Stack, { styles: childContainerStyle }, childrenOnCurrentPage.map((child, i) => {
9660
+ return (React__default['default'].createElement(react.Stack.Item, { key: i, styles: childrenStyles }, child));
9661
+ })),
9662
+ showButtons && (React__default['default'].createElement(VerticalGalleryControlBar, { buttonsDisabled: buttonState, onPreviousButtonClick: onPreviousButtonClick, onNextButtonClick: onNextButtonClick, totalPages: lastPage, currentPage: page }))));
9663
+ };
9664
+ const VerticalGalleryControlBar = (props) => {
9665
+ const { onNextButtonClick, onPreviousButtonClick, buttonsDisabled, currentPage, totalPages, styles } = props;
9666
+ const theme = useTheme();
9667
+ const pageCounterContainerStyles = React.useMemo(() => {
9668
+ return react.mergeStyles(pageNavigationControlBarContainerStyle, styles === null || styles === void 0 ? void 0 : styles.root);
9669
+ }, [styles === null || styles === void 0 ? void 0 : styles.root]);
9670
+ const previousButtonSyles = React.useMemo(() => {
9671
+ return react.mergeStyles(leftRightButtonStyles(theme), styles === null || styles === void 0 ? void 0 : styles.previousButton);
9672
+ }, [styles === null || styles === void 0 ? void 0 : styles.previousButton, theme]);
9673
+ const pageCounterStyles = React.useMemo(() => {
9674
+ return react.mergeStyles(participantPageCounter, styles === null || styles === void 0 ? void 0 : styles.counter);
9675
+ }, [styles === null || styles === void 0 ? void 0 : styles.counter]);
9676
+ const nextButtonsStyles = React.useMemo(() => {
9677
+ return react.mergeStyles(leftRightButtonStyles(theme), styles === null || styles === void 0 ? void 0 : styles.nextButton);
9678
+ }, [styles === null || styles === void 0 ? void 0 : styles.nextButton, theme]);
9679
+ const controlBarSpacing = { childrenGap: '0.5rem' };
9680
+ return (React__default['default'].createElement(react.Stack, { horizontalAlign: "center", tokens: controlBarSpacing, horizontal: true, className: pageCounterContainerStyles },
9681
+ React__default['default'].createElement(react.DefaultButton, { className: previousButtonSyles, onClick: onPreviousButtonClick, disabled: buttonsDisabled === null || buttonsDisabled === void 0 ? void 0 : buttonsDisabled.previous },
9682
+ React__default['default'].createElement(react.Icon, { iconName: "VerticalGalleryLeftButton", styles: navIconStyles })),
9683
+ React__default['default'].createElement(react.Text, { className: pageCounterStyles }, `${currentPage} / ${totalPages}`),
9684
+ React__default['default'].createElement(react.DefaultButton, { className: nextButtonsStyles, onClick: onNextButtonClick, disabled: buttonsDisabled === null || buttonsDisabled === void 0 ? void 0 : buttonsDisabled.next },
9685
+ React__default['default'].createElement(react.Icon, { iconName: "VerticalGalleryRightButton", styles: navIconStyles }))));
9686
+ };
9687
+
9688
+ // Copyright (c) Microsoft Corporation.
9689
+ /**
9690
+ * @private
9691
+ */
9692
+ react.mergeStyles({ position: 'relative', width: '100%', height: '100%' });
9693
+ /**
9694
+ * Small floating modal width and height in rem for small screen
9695
+ */
9696
+ const SMALL_FLOATING_MODAL_SIZE_PX = { width: 58, height: 104 };
9697
+ /**
9698
+ * Large floating modal width and height in rem for large screen
9699
+ * Aspect ratio: 16:9
9700
+ */
9701
+ const LARGE_FLOATING_MODAL_SIZE_PX = { width: 215, height: 120 };
9702
+ /**
9703
+ * Vertical gallery floating modal width and height in rem
9704
+ * Aspect ratio: 16:9
9705
+ */
9706
+ const VERTICAL_GALLERY_FLOATING_MODAL_SIZE_PX = { width: 144, height: 81 };
9707
+ /**
9708
+ * @private
9709
+ * z-index to ensure that the local video tile is above the video gallery.
9710
+ */
9711
+ const LOCAL_VIDEO_TILE_ZINDEX = 2;
9712
+ /**
9713
+ * @private
9714
+ */
9715
+ const localVideoTileContainerStyle = (theme, localVideoTileSize) => {
9716
+ return Object.assign({ minWidth: _pxToRem(localVideoTileSize.width), minHeight: _pxToRem(localVideoTileSize.height), position: 'absolute', bottom: _pxToRem(localVideoTileOuterPaddingPX), borderRadius: theme.effects.roundedCorner4, overflow: 'hidden' }, (theme.rtl
9717
+ ? { left: _pxToRem(localVideoTileOuterPaddingPX) }
9718
+ : { right: _pxToRem(localVideoTileOuterPaddingPX) }));
9719
+ };
9720
+ /**
9721
+ * @private
9722
+ */
9723
+ const localVideoTileWithControlsContainerStyle = (theme, localVideoTileSize) => {
9724
+ return react.concatStyleSets(localVideoTileContainerStyle(theme, localVideoTileSize), {
9725
+ root: { boxShadow: theme.effects.elevation8 }
9726
+ });
9727
+ };
9728
+ /**
9729
+ * @private
9730
+ */
9731
+ const floatingLocalVideoModalStyle = (theme, modalSize) => {
9732
+ return react.concatStyleSets({
9733
+ main: localVideoTileContainerStyle(theme, modalSize)
9734
+ }, {
9735
+ main: {
9736
+ boxShadow: theme.effects.elevation8,
9737
+ ':focus-within': {
9738
+ boxShadow: theme.effects.elevation16,
9739
+ border: `${_pxToRem(2)} solid ${theme.palette.neutralPrimary}`
9740
+ }
9741
+ }
9742
+ }, localVideoModalStyles);
9743
+ };
9744
+ /**
9745
+ * Padding equal to the amount the modal should stay inside the bounds of the container.
9746
+ * i.e. if this is 8px, the modal should always be at least 8px inside the container at all times on all sides.
9747
+ * @private
9748
+ */
9749
+ const localVideoTileOuterPaddingPX = 8;
9750
+ /**
9751
+ * @private
9752
+ */
9753
+ const floatingLocalVideoTileStyle = {
9754
+ root: {
9755
+ position: 'absolute',
9756
+ zIndex: LOCAL_VIDEO_TILE_ZINDEX,
9757
+ height: '100%',
9758
+ width: '100%'
9759
+ }
9760
+ };
9761
+ /**
9762
+ * Styles for the local video tile modal when it is focused, will cause keyboard move icon to appear over video
9763
+ * @private
9764
+ */
9765
+ const localVideoModalStyles = {
9766
+ keyboardMoveIconContainer: {
9767
+ zIndex: LOCAL_VIDEO_TILE_ZINDEX + 1 // zIndex to set the keyboard movement Icon above the other layers in the video tile.
9768
+ }
9769
+ };
9770
+
9771
+ // Copyright (c) Microsoft Corporation.
9772
+ /**
9773
+ * VerticalGallery tile size in rem:
9774
+ *
9775
+ * min - smallest possible size of the tile (90px)
9776
+ * max - Largest size we want the vertical tiles (144px)
9777
+ *
9778
+ * @private
9779
+ */
9780
+ const VERTICAL_GALLERY_TILE_SIZE_REM = { minHeight: 5.625, maxHeight: 9, width: 9 };
9781
+ /**
9782
+ * Styles for the VerticalGallery's container set in parent.
9783
+ *
9784
+ * width is being increased by 1rem to account for the gap width desired for the VerticalGallery.
9785
+ *
9786
+ * @param shouldFloatLocalVideo whether rendered in floating layout or not
9787
+ * @returns Style set for VerticalGallery container.
9788
+ */
9789
+ const verticalGalleryContainerStyle = (shouldFloatLocalVideo) => {
9790
+ return {
9791
+ width: `${VERTICAL_GALLERY_TILE_SIZE_REM.width}rem`,
9792
+ height: shouldFloatLocalVideo ? `calc(100% - ${_pxToRem(VERTICAL_GALLERY_FLOATING_MODAL_SIZE_PX.height)})` : '100%',
9793
+ paddingBottom: '0.5rem'
9794
+ };
9795
+ };
9796
+ /**
9797
+ * @private
9798
+ */
9799
+ const VERTICAL_GALLERY_TILE_STYLE = {
9800
+ minHeight: `${VERTICAL_GALLERY_TILE_SIZE_REM.minHeight}rem`,
9801
+ minWidth: `${VERTICAL_GALLERY_TILE_SIZE_REM.width}rem`,
9802
+ maxHeight: `${VERTICAL_GALLERY_TILE_SIZE_REM.maxHeight}rem`,
9803
+ maxWidth: `${VERTICAL_GALLERY_TILE_SIZE_REM.width}rem`
9804
+ };
9805
+ /**
9806
+ * @private
9807
+ */
9808
+ const verticalGalleryStyle = {
9809
+ children: VERTICAL_GALLERY_TILE_STYLE
9810
+ };
9811
+
9812
+ // Copyright (c) Microsoft Corporation.
9813
+ /**
9814
+ * Responsive container for the VerticalGallery Component. Performs calculations for number of children
9815
+ * for the VerticalGallery
9816
+ * @param props
9817
+ *
9818
+ * @beta
9819
+ */
9820
+ const ResponsiveVerticalGallery = (props) => {
9821
+ const { children, containerStyles, verticalGalleryStyles, gapHeightRem, controlBarHeightRem } = props;
9822
+ const containerRef = React.useRef(null);
9823
+ const containerHeight = _useContainerHeight(containerRef);
9824
+ const topPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingTop) : 0;
9825
+ const bottomPadding = containerRef.current ? parseFloat(getComputedStyle(containerRef.current).paddingBottom) : 0;
9826
+ const childrenPerPage = calculateChildrenPerPage({
9827
+ numberOfChildren: React__default['default'].Children.count(children),
9828
+ containerHeight: (containerHeight !== null && containerHeight !== void 0 ? containerHeight : 0) - topPadding - bottomPadding,
9829
+ gapHeightRem,
9830
+ controlBarHeight: controlBarHeightRem !== null && controlBarHeightRem !== void 0 ? controlBarHeightRem : 2
9831
+ });
9832
+ return (React__default['default'].createElement("div", { ref: containerRef, className: react.mergeStyles(containerStyles) },
9833
+ React__default['default'].createElement(VerticalGallery, { childrenPerPage: childrenPerPage, styles: verticalGalleryStyles }, children)));
9834
+ };
9835
+ /**
9836
+ * Helper function to find the number of children for the VerticalGallery on each page.
9837
+ */
9838
+ const calculateChildrenPerPage = (args) => {
9839
+ const { numberOfChildren, containerHeight, gapHeightRem, controlBarHeight } = args;
9840
+ const childMinHeightPx = _convertRemToPx(VERTICAL_GALLERY_TILE_SIZE_REM.minHeight);
9841
+ const gapHeightPx = _convertRemToPx(gapHeightRem);
9842
+ const controlBarHeightPx = _convertRemToPx(controlBarHeight);
9843
+ /** First check how many children can fit in containerHeight.
9844
+ *
9845
+ * _________________
9846
+ * | |
9847
+ * | |
9848
+ * |________________|
9849
+ * _________________
9850
+ * | |
9851
+ * | |
9852
+ * |________________|
9853
+ *
9854
+ * < n/m >
9855
+ *
9856
+ * number of children = container height - (2* gap height + button height) / childMinHeight
9857
+ *
9858
+ * we want to find the maximum number of children at the smallest size we can fit in the gallery and then resize them
9859
+ * to fill in the space as much as possible
9860
+ *
9861
+ * First we will find the max number of children without any controls we can fit.
9862
+ */
9863
+ const maxNumberOfChildrenInContainer = Math.floor((containerHeight + gapHeightPx) / (childMinHeightPx + gapHeightPx));
9864
+ // if all of the children fit in the container just return the number of children
9865
+ if (numberOfChildren <= maxNumberOfChildrenInContainer) {
9866
+ return maxNumberOfChildrenInContainer;
9867
+ }
9868
+ /**
9869
+ * For the pagination we know the container height, the height of the button bar and the 2 times the gap
9870
+ * height, top tile and bottom tile above control bar. So the child space is calculated as:
9871
+ *
9872
+ * space = height - controlbar - (2 * gap)
9873
+ */
9874
+ const childSpace = containerHeight - controlBarHeightPx - 2 * gapHeightPx;
9875
+ /**
9876
+ * Now that we have the childrenSpace height we can figure out how many Children can fir in the childrenSpace.
9877
+ * childrenSpace = n * childHeightMin + (n - 1) * gapHeight. isolate n and take the floor.
9878
+ */
9879
+ return Math.floor((childSpace + gapHeightPx) / (childMinHeightPx + gapHeightPx));
9880
+ };
9881
+
9882
+ // Copyright (c) Microsoft Corporation.
9883
+ /**
9884
+ * @private
9885
+ */
9886
+ const horizontalGalleryContainerStyle = (shouldFloatLocalVideo, isNarrow) => {
9887
+ return {
9888
+ minHeight: isNarrow
9889
+ ? `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`
9890
+ : `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9891
+ width: shouldFloatLocalVideo
9892
+ ? isNarrow
9893
+ ? `calc(100% - ${_pxToRem(SMALL_FLOATING_MODAL_SIZE_PX.width)})`
9894
+ : `calc(100% - ${_pxToRem(LARGE_FLOATING_MODAL_SIZE_PX.width)})`
9895
+ : '100%',
9896
+ paddingRight: '0.5rem'
9897
+ };
9898
+ };
9899
+ /**
9900
+ * @private
9901
+ */
9902
+ const horizontalGalleryStyle = (isNarrow) => {
9903
+ return {
9904
+ children: isNarrow ? SMALL_HORIZONTAL_GALLERY_TILE_STYLE : LARGE_HORIZONTAL_GALLERY_TILE_STYLE
9905
+ };
9906
+ };
9907
+ /**
9908
+ * Small horizontal gallery tile size in rem
9909
+ * @private
9910
+ */
9911
+ const SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM = { height: 6.5, width: 6.5 };
9912
+ /**
9913
+ * Large horizontal gallery tile size in rem
9914
+ * @private
9915
+ */
9916
+ const LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM = { height: 7.5, width: 10 };
9917
+ /**
9918
+ * @private
9919
+ */
9920
+ const SMALL_HORIZONTAL_GALLERY_TILE_STYLE = {
9921
+ minHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9922
+ minWidth: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`,
9923
+ maxHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9924
+ maxWidth: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`
9925
+ };
9926
+ /**
9927
+ * @private
9928
+ */
9929
+ const LARGE_HORIZONTAL_GALLERY_TILE_STYLE = {
9930
+ minHeight: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9931
+ minWidth: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`,
9932
+ maxHeight: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9933
+ maxWidth: `${LARGE_HORIZONTAL_GALLERY_TILE_SIZE_REM.width}rem`
9934
+ };
9935
+
9936
+ // Copyright (c) Microsoft Corporation.
9937
+ /**
9938
+ * @private
9939
+ */
9940
+ const scrollableHorizontalGalleryStyles = {
9941
+ root: {
9942
+ width: '100%',
9943
+ minHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9944
+ paddingRight: '0.5rem',
9945
+ '> *': SMALL_HORIZONTAL_GALLERY_TILE_STYLE
9946
+ }
9947
+ };
9948
+ /**
9949
+ * @private
9950
+ */
9951
+ const scrollableHorizontalGalleryContainerStyles = react.mergeStyles({
9952
+ display: 'flex',
9953
+ width: `calc(100% - ${SMALL_FLOATING_MODAL_SIZE_PX.width}px)`,
9954
+ minHeight: `${SMALL_HORIZONTAL_GALLERY_TILE_SIZE_REM.height}rem`,
9955
+ overflow: 'scroll',
9956
+ '-ms-overflow-style': 'none',
9957
+ 'scrollbar-width': 'none',
9958
+ '::-webkit-scrollbar': { display: 'none' }
9959
+ });
9960
+
9961
+ // Copyright (c) Microsoft Corporation.
9962
+ /**
9963
+ * Component to display elements horizontally in a scrollable container
9964
+ * @private
9965
+ */
9966
+ const ScrollableHorizontalGallery = (props) => {
9967
+ const { horizontalGalleryElements } = props;
9968
+ const ref = React.useRef();
9969
+ const { events: dragabbleEvents } = reactUseDraggableScroll.useDraggable(ref);
9970
+ return (React__default['default'].createElement("div", Object.assign({ ref: ref }, dragabbleEvents, { className: scrollableHorizontalGalleryContainerStyles }),
9971
+ React__default['default'].createElement(react.Stack, { "data-ui-id": "scrollable-horizontal-gallery", horizontal: true, styles: scrollableHorizontalGalleryStyles, tokens: { childrenGap: '0.5rem' } }, horizontalGalleryElements)));
9972
+ };
9973
+
9716
9974
  // Copyright (c) Microsoft Corporation.
9717
9975
  /**
9718
9976
  * A ResponsiveHorizontalGallery styled for the {@link VideoGallery}
9719
9977
  *
9720
9978
  * @private
9721
9979
  */
9722
- const VideoGalleryResponsiveHorizontalGallery = (props) => {
9723
- const { shouldFloatLocalVideo = false, isNarrow = false, horizontalGalleryElements, styles } = props;
9724
- const containerStyles = React.useMemo(() => horizontalGalleryContainerStyle(shouldFloatLocalVideo, isNarrow), [shouldFloatLocalVideo, isNarrow]);
9725
- const galleryStyles = React.useMemo(() => react.concatStyleSets(horizontalGalleryStyle(isNarrow), styles), [isNarrow, styles]);
9726
- return (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));
9980
+ const OverflowGallery = (props) => {
9981
+ const { shouldFloatLocalVideo = false, isNarrow = false, overflowGalleryElements, styles,
9982
+ /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout = 'HorizontalBottom' } = props;
9983
+ const containerStyles = React.useMemo(() => {
9984
+ /* @conditional-compile-remove(vertical-gallery) */
9985
+ if (overflowGalleryLayout === 'VerticalRight') {
9986
+ return verticalGalleryContainerStyle(shouldFloatLocalVideo);
9987
+ }
9988
+ return horizontalGalleryContainerStyle(shouldFloatLocalVideo, isNarrow);
9989
+ }, [shouldFloatLocalVideo, isNarrow, /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout]);
9990
+ const galleryStyles = React.useMemo(() => {
9991
+ /* @conditional-compile-remove(vertical-gallery) */
9992
+ if (overflowGalleryLayout === 'VerticalRight') {
9993
+ return react.concatStyleSets(verticalGalleryStyle, styles);
9994
+ }
9995
+ return react.concatStyleSets(horizontalGalleryStyle(isNarrow), styles);
9996
+ }, [isNarrow, styles, /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout]);
9997
+ /* @conditional-compile-remove(vertical-gallery) */
9998
+ if (overflowGalleryLayout === 'VerticalRight') {
9999
+ return (React__default['default'].createElement(ResponsiveVerticalGallery, { key: "responsive-vertical-gallery", containerStyles: containerStyles, verticalGalleryStyles: galleryStyles, controlBarHeightRem: HORIZONTAL_GALLERY_BUTTON_WIDTH, gapHeightRem: HORIZONTAL_GALLERY_GAP }, overflowGalleryElements));
10000
+ }
10001
+ /* @conditional-compile-remove(pinned-participants) */
10002
+ if (isNarrow) {
10003
+ return React__default['default'].createElement(ScrollableHorizontalGallery, { horizontalGalleryElements: overflowGalleryElements });
10004
+ }
10005
+ return (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 }, overflowGalleryElements));
9727
10006
  };
9728
10007
 
9729
10008
  // Copyright (c) Microsoft Corporation.
@@ -9735,7 +10014,8 @@ const VideoGalleryResponsiveHorizontalGallery = (props) => {
9735
10014
  */
9736
10015
  const DefaultLayout = (props) => {
9737
10016
  const { remoteParticipants = [], dominantSpeakers, localVideoComponent, screenShareComponent, onRenderRemoteParticipant, styles, maxRemoteVideoStreams, parentWidth,
9738
- /* @conditional-compile-remove(pinned-participants) */ pinnedParticipantUserIds } = props;
10017
+ /* @conditional-compile-remove(pinned-participants) */ pinnedParticipantUserIds,
10018
+ /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout = 'HorizontalBottom' } = props;
9739
10019
  const isNarrow = parentWidth ? isNarrowWidth(parentWidth) : false;
9740
10020
  const { gridParticipants, horizontalGalleryParticipants } = useOrganizedParticipants({
9741
10021
  remoteParticipants,
@@ -9760,19 +10040,26 @@ const DefaultLayout = (props) => {
9760
10040
  if (localVideoComponent) {
9761
10041
  gridTiles.push(localVideoComponent);
9762
10042
  }
9763
- const horizontalGallery = React.useMemo(() => {
10043
+ const overflowGallery = React.useMemo(() => {
9764
10044
  if (horizontalGalleryTiles.length === 0) {
9765
10045
  return null;
9766
10046
  }
9767
- /* @conditional-compile-remove(pinned-participants) */
9768
- if (isNarrow) {
9769
- return React__default['default'].createElement(ScrollableHorizontalGallery, { horizontalGalleryElements: horizontalGalleryTiles });
9770
- }
9771
- return (React__default['default'].createElement(VideoGalleryResponsiveHorizontalGallery, { isNarrow: isNarrow, shouldFloatLocalVideo: true, horizontalGalleryElements: horizontalGalleryTiles, styles: styles === null || styles === void 0 ? void 0 : styles.horizontalGallery }));
9772
- }, [isNarrow, horizontalGalleryTiles, styles === null || styles === void 0 ? void 0 : styles.horizontalGallery]);
9773
- return (React__default['default'].createElement(react.Stack, { horizontal: false, styles: rootLayoutStyle$1, tokens: videoGalleryLayoutGap },
10047
+ return (React__default['default'].createElement(OverflowGallery, { isNarrow: isNarrow, shouldFloatLocalVideo: false, overflowGalleryElements: horizontalGalleryTiles, styles: styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
10048
+ /* @conditional-compile-remove(pinned-participants) */
10049
+ overflowGalleryLayout: overflowGalleryLayout }));
10050
+ }, [
10051
+ isNarrow,
10052
+ horizontalGalleryTiles,
10053
+ styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
10054
+ /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout
10055
+ ]);
10056
+ return (React__default['default'].createElement(react.Stack
10057
+ /* @conditional-compile-remove(vertical-gallery) */
10058
+ , {
10059
+ /* @conditional-compile-remove(vertical-gallery) */
10060
+ horizontal: overflowGalleryLayout === 'VerticalRight', styles: rootLayoutStyle$1, tokens: videoGalleryLayoutGap },
9774
10061
  screenShareComponent ? (screenShareComponent) : (React__default['default'].createElement(GridLayout, { key: "grid-layout", styles: styles === null || styles === void 0 ? void 0 : styles.gridLayout }, gridTiles)),
9775
- horizontalGallery));
10062
+ overflowGallery));
9776
10063
  };
9777
10064
 
9778
10065
  // Copyright (c) Microsoft Corporation.
@@ -10463,21 +10750,19 @@ const modalMaxDragPosition = { x: localVideoTileOuterPaddingPX, y: localVideoTil
10463
10750
  * @private
10464
10751
  */
10465
10752
  const FloatingLocalVideo = (props) => {
10466
- const { localVideoComponent, layerHostId, isNarrow, parentWidth, parentHeight } = props;
10753
+ const { localVideoComponent, layerHostId, localVideoSize, parentWidth, parentHeight } = props;
10467
10754
  const theme = useTheme();
10468
- const modalWidth = isNarrow ? SMALL_FLOATING_MODAL_SIZE_PX.width : LARGE_FLOATING_MODAL_SIZE_PX.width;
10469
- const modalHeight = isNarrow ? SMALL_FLOATING_MODAL_SIZE_PX.height : LARGE_FLOATING_MODAL_SIZE_PX.height;
10470
10755
  // The minimum drag position is the top left of the video gallery. i.e. the modal (PiP) should not be able
10471
10756
  // to be dragged offscreen and these are the top and left bounds of that calculation.
10472
10757
  const modalMinDragPosition = React.useMemo(() => parentWidth && parentHeight
10473
10758
  ? {
10474
10759
  // We use -parentWidth/Height because our modal is positioned to start in the bottom right,
10475
10760
  // hence (0,0) is the bottom right of the video gallery.
10476
- x: -parentWidth + modalWidth + localVideoTileOuterPaddingPX,
10477
- y: -parentHeight + modalHeight + localVideoTileOuterPaddingPX
10761
+ x: -parentWidth + localVideoSize.width + localVideoTileOuterPaddingPX,
10762
+ y: -parentHeight + localVideoSize.height + localVideoTileOuterPaddingPX
10478
10763
  }
10479
- : undefined, [parentHeight, parentWidth, modalHeight, modalWidth]);
10480
- const modalStyles = React.useMemo(() => floatingLocalVideoModalStyle(theme, isNarrow), [theme, isNarrow]);
10764
+ : undefined, [parentHeight, parentWidth, localVideoSize.width, localVideoSize.height]);
10765
+ const modalStyles = React.useMemo(() => floatingLocalVideoModalStyle(theme, localVideoSize), [theme, localVideoSize]);
10481
10766
  const layerProps = React.useMemo(() => ({ hostId: layerHostId }), [layerHostId]);
10482
10767
  return (React__default['default'].createElement(_ModalClone, { isOpen: true, isModeless: true, dragOptions: DRAG_OPTIONS$1, styles: modalStyles, layerProps: layerProps, maxDragPosition: modalMaxDragPosition, minDragPosition: modalMinDragPosition }, localVideoComponent));
10483
10768
  };
@@ -10519,7 +10804,8 @@ const layerHostStyle = {
10519
10804
  */
10520
10805
  const FloatingLocalVideoLayout = (props) => {
10521
10806
  const { remoteParticipants = [], dominantSpeakers, localVideoComponent, screenShareComponent, onRenderRemoteParticipant, styles, maxRemoteVideoStreams, showCameraSwitcherInLocalPreview, parentWidth, parentHeight,
10522
- /* @conditional-compile-remove(pinned-participants) */ pinnedParticipantUserIds } = props;
10807
+ /* @conditional-compile-remove(pinned-participants) */ pinnedParticipantUserIds,
10808
+ /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout = 'HorizontalBottom' } = props;
10523
10809
  const theme = useTheme();
10524
10810
  const isNarrow = parentWidth ? isNarrowWidth(parentWidth) : false;
10525
10811
  const { gridParticipants, horizontalGalleryParticipants } = useOrganizedParticipants({
@@ -10547,28 +10833,43 @@ const FloatingLocalVideoLayout = (props) => {
10547
10833
  : (_b = p.videoStream) === null || _b === void 0 ? void 0 : _b.isAvailable);
10548
10834
  });
10549
10835
  const layerHostId = reactHooks.useId('layerhost');
10836
+ let localVideoSize = LARGE_FLOATING_MODAL_SIZE_PX;
10837
+ if (isNarrow) {
10838
+ localVideoSize = SMALL_FLOATING_MODAL_SIZE_PX;
10839
+ }
10840
+ /* @conditional-compile-remove(vertical-gallery) */
10841
+ if (overflowGalleryLayout === 'VerticalRight') {
10842
+ localVideoSize = VERTICAL_GALLERY_FLOATING_MODAL_SIZE_PX;
10843
+ }
10550
10844
  const wrappedLocalVideoComponent = localVideoComponent && shouldFloatLocalVideo ? (
10551
10845
  // When we use showCameraSwitcherInLocalPreview it disables dragging to allow keyboard navigation.
10552
- showCameraSwitcherInLocalPreview ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileWithControlsContainerStyle(theme, isNarrow), {
10846
+ showCameraSwitcherInLocalPreview ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileWithControlsContainerStyle(theme, localVideoSize), {
10553
10847
  boxShadow: theme.effects.elevation8,
10554
10848
  zIndex: LOCAL_VIDEO_TILE_ZINDEX
10555
- }) }, localVideoComponent)) : horizontalGalleryTiles.length > 0 ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileContainerStyle(theme, isNarrow)) }, localVideoComponent)) : (React__default['default'].createElement(FloatingLocalVideo, { localVideoComponent: localVideoComponent, layerHostId: layerHostId, isNarrow: isNarrow, parentWidth: parentWidth, parentHeight: parentHeight }))) : undefined;
10556
- const horizontalGallery = React.useMemo(() => {
10849
+ }) }, localVideoComponent)) : horizontalGalleryTiles.length > 0 ? (React__default['default'].createElement(react.Stack, { className: react.mergeStyles(localVideoTileContainerStyle(theme, localVideoSize)) }, localVideoComponent)) : (React__default['default'].createElement(FloatingLocalVideo, { localVideoComponent: localVideoComponent, layerHostId: layerHostId, localVideoSize: localVideoSize, parentWidth: parentWidth, parentHeight: parentHeight }))) : undefined;
10850
+ const overflowGallery = React.useMemo(() => {
10557
10851
  if (horizontalGalleryTiles.length === 0) {
10558
10852
  return null;
10559
10853
  }
10560
- /* @conditional-compile-remove(pinned-participants) */
10561
- if (isNarrow) {
10562
- return React__default['default'].createElement(ScrollableHorizontalGallery, { horizontalGalleryElements: horizontalGalleryTiles });
10563
- }
10564
- return (React__default['default'].createElement(VideoGalleryResponsiveHorizontalGallery, { isNarrow: isNarrow, shouldFloatLocalVideo: true, horizontalGalleryElements: horizontalGalleryTiles, styles: styles === null || styles === void 0 ? void 0 : styles.horizontalGallery }));
10565
- }, [isNarrow, horizontalGalleryTiles, styles === null || styles === void 0 ? void 0 : styles.horizontalGallery]);
10854
+ return (React__default['default'].createElement(OverflowGallery, { isNarrow: isNarrow, shouldFloatLocalVideo: true, overflowGalleryElements: horizontalGalleryTiles, styles: styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
10855
+ /* @conditional-compile-remove(vertical-gallery) */
10856
+ overflowGalleryLayout: overflowGalleryLayout }));
10857
+ }, [
10858
+ isNarrow,
10859
+ horizontalGalleryTiles,
10860
+ styles === null || styles === void 0 ? void 0 : styles.horizontalGallery,
10861
+ /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout
10862
+ ]);
10566
10863
  return (React__default['default'].createElement(react.Stack, { styles: rootLayoutStyle },
10567
10864
  wrappedLocalVideoComponent,
10568
10865
  React__default['default'].createElement(react.LayerHost, { id: layerHostId, className: react.mergeStyles(layerHostStyle) }),
10569
- React__default['default'].createElement(react.Stack, { horizontal: false, styles: innerLayoutStyle, tokens: videoGalleryLayoutGap },
10866
+ React__default['default'].createElement(react.Stack
10867
+ /* @conditional-compile-remove(vertical-gallery) */
10868
+ , {
10869
+ /* @conditional-compile-remove(vertical-gallery) */
10870
+ horizontal: overflowGalleryLayout === 'VerticalRight', styles: innerLayoutStyle, tokens: videoGalleryLayoutGap },
10570
10871
  screenShareComponent ? (screenShareComponent) : (React__default['default'].createElement(GridLayout, { key: "grid-layout", styles: styles === null || styles === void 0 ? void 0 : styles.gridLayout }, gridTiles)),
10571
- horizontalGallery)));
10872
+ overflowGallery)));
10572
10873
  };
10573
10874
 
10574
10875
  // Copyright (c) Microsoft Corporation.
@@ -10604,7 +10905,9 @@ const VideoGallery = (props) => {
10604
10905
  /* @conditional-compile-remove(pinned-participants) */
10605
10906
  onUnpinParticipant: onUnpinParticipantHandler,
10606
10907
  /* @conditional-compile-remove(pinned-participants) */
10607
- remoteVideoTileMenuOptions = DEFAULT_REMOTE_VIDEO_TILE_MENU_OPTIONS } = props;
10908
+ remoteVideoTileMenuOptions = DEFAULT_REMOTE_VIDEO_TILE_MENU_OPTIONS,
10909
+ /* @conditional-compile-remove(vertical-gallery) */
10910
+ overflowGalleryLayout = 'HorizontalBottom' } = props;
10608
10911
  const ids = useIdentifiers();
10609
10912
  const theme = useTheme();
10610
10913
  const localeStrings = useLocale$1().strings.videoGallery;
@@ -10764,7 +11067,8 @@ const VideoGallery = (props) => {
10764
11067
  localVideoComponent: localVideoTile,
10765
11068
  parentWidth: containerWidth,
10766
11069
  parentHeight: containerHeight,
10767
- /* @conditional-compile-remove(pinned-participants) */ pinnedParticipantUserIds: pinnedParticipants
11070
+ /* @conditional-compile-remove(pinned-participants) */ pinnedParticipantUserIds: pinnedParticipants,
11071
+ /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout
10768
11072
  }), [
10769
11073
  remoteParticipants,
10770
11074
  screenShareComponent,
@@ -10777,7 +11081,8 @@ const VideoGallery = (props) => {
10777
11081
  containerHeight,
10778
11082
  onRenderRemoteVideoTile,
10779
11083
  defaultOnRenderVideoTile,
10780
- /* @conditional-compile-remove(pinned-participants) */ pinnedParticipants
11084
+ /* @conditional-compile-remove(pinned-participants) */ pinnedParticipants,
11085
+ /* @conditional-compile-remove(vertical-gallery) */ overflowGalleryLayout
10781
11086
  ]);
10782
11087
  const videoGalleryLayout = React.useMemo(() => {
10783
11088
  if (layout === 'floatingLocalVideo') {