@100mslive/roomkit-react 0.2.8-alpha.6 → 0.2.8-alpha.8

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 (51) hide show
  1. package/dist/{HLSView-53PDKIS2.js → HLSView-6KPQ2KD6.js} +176 -174
  2. package/dist/HLSView-6KPQ2KD6.js.map +7 -0
  3. package/dist/Prebuilt/components/HMSVideo/HLSQualitySelector.d.ts +3 -2
  4. package/dist/Prebuilt/components/HMSVideo/utils.d.ts +0 -1
  5. package/dist/Prebuilt/components/Leave/DesktopLeaveRoom.d.ts +2 -1
  6. package/dist/Prebuilt/components/Leave/LeaveRoom.d.ts +2 -1
  7. package/dist/Prebuilt/components/Leave/MwebLeaveRoom.d.ts +2 -1
  8. package/dist/Prebuilt/components/RaiseHand.d.ts +4 -1
  9. package/dist/Sheet/Sheet.d.ts +1 -0
  10. package/dist/{chunk-2ZFAT7KY.js → chunk-JQCSGJIR.js} +742 -639
  11. package/dist/chunk-JQCSGJIR.js.map +7 -0
  12. package/dist/index.cjs.js +1253 -1144
  13. package/dist/index.cjs.js.map +4 -4
  14. package/dist/index.js +1 -1
  15. package/dist/meta.cjs.json +256 -201
  16. package/dist/meta.esbuild.json +263 -206
  17. package/package.json +6 -6
  18. package/src/Button/Button.tsx +4 -4
  19. package/src/Fieldset/Fieldset.tsx +1 -1
  20. package/src/Input/PasswordInput.stories.tsx +1 -1
  21. package/src/Pagination/StyledPagination.stories.tsx +2 -2
  22. package/src/Prebuilt/IconButton.tsx +1 -1
  23. package/src/Prebuilt/components/AppData/useSidepane.js +22 -10
  24. package/src/Prebuilt/components/Chat/Chat.tsx +41 -1
  25. package/src/Prebuilt/components/Chat/ChatFooter.tsx +19 -15
  26. package/src/Prebuilt/components/EmojiReaction.jsx +32 -22
  27. package/src/Prebuilt/components/HMSVideo/HLSQualitySelector.tsx +85 -78
  28. package/src/Prebuilt/components/HMSVideo/HMSVideo.jsx +3 -4
  29. package/src/Prebuilt/components/HMSVideo/MwebHLSViewTitle.tsx +49 -56
  30. package/src/Prebuilt/components/HMSVideo/VideoTime.tsx +2 -1
  31. package/src/Prebuilt/components/HMSVideo/utils.ts +0 -8
  32. package/src/Prebuilt/components/IconButtonWithOptions/IconButtonWithOptions.tsx +1 -1
  33. package/src/Prebuilt/components/Leave/DesktopLeaveRoom.tsx +50 -46
  34. package/src/Prebuilt/components/Leave/LeaveRoom.tsx +10 -5
  35. package/src/Prebuilt/components/Leave/MwebLeaveRoom.tsx +12 -6
  36. package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +7 -3
  37. package/src/Prebuilt/components/Notifications/HandRaisedNotifications.tsx +4 -1
  38. package/src/Prebuilt/components/Polls/Voting/Voting.tsx +3 -2
  39. package/src/Prebuilt/components/Polls/common/OptionInputWithDelete.tsx +1 -1
  40. package/src/Prebuilt/components/Polls/common/utils.ts +2 -2
  41. package/src/Prebuilt/components/RaiseHand.tsx +8 -2
  42. package/src/Prebuilt/components/RoomDetails/RoomDetailsPane.tsx +41 -14
  43. package/src/Prebuilt/components/pdfAnnotator/shareScreenOptions.jsx +2 -2
  44. package/src/Prebuilt/components/pdfAnnotator/uploadedFile.jsx +1 -1
  45. package/src/Prebuilt/layouts/HLSView.jsx +27 -24
  46. package/src/Prebuilt/layouts/SidePane.tsx +1 -2
  47. package/src/Prebuilt/layouts/VideoStreamingSection.tsx +3 -2
  48. package/src/Prebuilt/primitives/DialogContent.jsx +1 -1
  49. package/src/Sheet/Sheet.tsx +3 -3
  50. package/dist/HLSView-53PDKIS2.js.map +0 -7
  51. package/dist/chunk-2ZFAT7KY.js.map +0 -7
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "prebuilt",
11
11
  "roomkit"
12
12
  ],
13
- "version": "0.2.8-alpha.6",
13
+ "version": "0.2.8-alpha.8",
14
14
  "author": "100ms",
15
15
  "license": "MIT",
16
16
  "repository": {
@@ -82,11 +82,11 @@
82
82
  "react": ">=17.0.2 <19.0.0"
83
83
  },
84
84
  "dependencies": {
85
- "@100mslive/hls-player": "0.2.8-alpha.6",
85
+ "@100mslive/hls-player": "0.2.8-alpha.8",
86
86
  "@100mslive/hms-noise-cancellation": "0.0.0-alpha.1",
87
- "@100mslive/hms-virtual-background": "1.12.8-alpha.6",
88
- "@100mslive/react-icons": "0.9.8-alpha.6",
89
- "@100mslive/react-sdk": "0.9.8-alpha.6",
87
+ "@100mslive/hms-virtual-background": "1.12.8-alpha.8",
88
+ "@100mslive/react-icons": "0.9.8-alpha.8",
89
+ "@100mslive/react-sdk": "0.9.8-alpha.8",
90
90
  "@100mslive/types-prebuilt": "0.12.7",
91
91
  "@emoji-mart/data": "^1.0.6",
92
92
  "@emoji-mart/react": "^1.0.1",
@@ -122,5 +122,5 @@
122
122
  "uuid": "^8.3.2",
123
123
  "worker-timers": "^7.0.40"
124
124
  },
125
- "gitHead": "666634daeed360298e28b87d08d82b96639e0f70"
125
+ "gitHead": "cddbc3f6a55bc8612229e7cfa865eb8946b564b2"
126
126
  }
@@ -20,22 +20,22 @@ const getOutlinedVariants = (
20
20
  textDisabled: string,
21
21
  ) => {
22
22
  return {
23
- bg: '$transparent',
23
+ bg: 'transparent',
24
24
  border: `solid $space$px $colors${base}`,
25
25
  c: text,
26
26
  '&[disabled]': {
27
27
  c: textDisabled,
28
- bg: '$transparent',
28
+ bg: 'transparent',
29
29
  border: `solid $space$px $colors${disabled}`,
30
30
  cursor: 'not-allowed',
31
31
  },
32
32
  '&:not([disabled]):hover': {
33
33
  border: `solid $space$px $colors${hover}`,
34
- bg: '$transparent',
34
+ bg: 'transparent',
35
35
  },
36
36
  '&:not([disabled]):active': {
37
37
  border: `solid $space$px $colors${active}`,
38
- bg: '$transparent',
38
+ bg: 'transparent',
39
39
  },
40
40
  '&:not([disabled]):focus-visible': {
41
41
  boxShadow: `0 0 0 3px $colors${base}`,
@@ -5,7 +5,7 @@ const StyledFieldset = styled('fieldset', {
5
5
  alignItems: 'center',
6
6
  justifyContent: 'space-between',
7
7
  border: 'none',
8
- backgroundColor: '$transparent',
8
+ backgroundColor: 'transparent',
9
9
  });
10
10
 
11
11
  export const Fieldset = StyledFieldset;
@@ -25,7 +25,7 @@ const Template: ComponentStory<typeof PasswordInput.Root> = args => {
25
25
  showPassword={showPassword}
26
26
  onChange={e => setText(e.target.value)}
27
27
  />
28
- <PasswordInput.Icons ref={ref} css={{ bg: '$transparent' }}>
28
+ <PasswordInput.Icons ref={ref} css={{ bg: 'transparent' }}>
29
29
  <PasswordInput.ShowIcon
30
30
  showPassword={showPassword}
31
31
  onClick={() => {
@@ -41,7 +41,7 @@ const PaginationComponent = ({ page: propsPage, setPage: propsSetPage, numPages
41
41
  disabled={disableLeft}
42
42
  onClick={prevPage}
43
43
  type="button"
44
- css={{ padding: 0, border: 'none', backgroundColor: '$transparent' }}
44
+ css={{ padding: 0, border: 'none', backgroundColor: 'transparent' }}
45
45
  >
46
46
  <ChevronLeftIcon width={16} height={16} style={{ cursor: disableLeft ? 'not-allowed' : 'pointer' }} />
47
47
  </StyledPagination.Chevron>
@@ -54,7 +54,7 @@ const PaginationComponent = ({ page: propsPage, setPage: propsSetPage, numPages
54
54
  disabled={disableRight}
55
55
  onClick={nextPage}
56
56
  type="button"
57
- css={{ padding: 0, border: 'none', backgroundColor: '$transparent' }}
57
+ css={{ padding: 0, border: 'none', backgroundColor: 'transparent' }}
58
58
  >
59
59
  <ChevronRightIcon width={16} height={16} style={{ cursor: disableRight ? 'not-allowed' : 'pointer' }} />
60
60
  </StyledPagination.Chevron>
@@ -11,7 +11,7 @@ const IconButton = styled(BaseIconButton, {
11
11
  active: {
12
12
  true: {
13
13
  color: '$on_surface_high',
14
- backgroundColor: '$transparent',
14
+ backgroundColor: 'transparent',
15
15
  },
16
16
  false: {
17
17
  border: '1px solid transparent',
@@ -46,27 +46,39 @@ export const usePollViewToggle = () => {
46
46
 
47
47
  const togglePollView = useCallback(
48
48
  id => {
49
- const newView = match({ id, isOpen, view })
49
+ match({ id, isOpen, view })
50
50
  .with(
51
51
  {
52
52
  id: P.string,
53
53
  },
54
- () => POLL_VIEWS.VOTE,
54
+ () => {
55
+ setPollState({
56
+ [POLL_STATE.pollInView]: id,
57
+ [POLL_STATE.view]: POLL_VIEWS.VOTE,
58
+ });
59
+ hmsActions.setAppData(APP_DATA.sidePane, SIDE_PANE_OPTIONS.POLLS);
60
+ },
55
61
  )
56
62
  .with(
57
63
  {
58
64
  isOpen: true,
59
65
  view: P.when(view => !!view),
60
66
  },
61
- () => null,
67
+ () => {
68
+ setPollState({
69
+ [POLL_STATE.pollInView]: undefined,
70
+ [POLL_STATE.view]: null,
71
+ });
72
+ hmsActions.setAppData(APP_DATA.sidePane, '');
73
+ },
62
74
  )
63
- .otherwise(() => POLL_VIEWS.CREATE_POLL_QUIZ);
64
-
65
- setPollState({
66
- [POLL_STATE.pollInView]: id,
67
- [POLL_STATE.view]: newView,
68
- });
69
- hmsActions.setAppData(APP_DATA.sidePane, newView ? SIDE_PANE_OPTIONS.POLLS : '');
75
+ .otherwise(() => {
76
+ setPollState({
77
+ [POLL_STATE.pollInView]: undefined,
78
+ [POLL_STATE.view]: POLL_VIEWS.CREATE_POLL_QUIZ,
79
+ });
80
+ hmsActions.setAppData(APP_DATA.sidePane, SIDE_PANE_OPTIONS.POLLS);
81
+ });
70
82
  },
71
83
  [hmsActions, view, setPollState, isOpen],
72
84
  );
@@ -2,16 +2,20 @@ import React, { MutableRefObject, useCallback, useRef } from 'react';
2
2
  import { useMedia } from 'react-use';
3
3
  import { VariableSizeList } from 'react-window';
4
4
  import { selectSessionStore, selectUnreadHMSMessagesCount } from '@100mslive/hms-video-store';
5
+ import { match } from 'ts-pattern';
5
6
  import { selectHMSMessagesCount, useHMSActions, useHMSStore, useHMSVanillaStore } from '@100mslive/react-sdk';
6
7
  import { ChevronDownIcon } from '@100mslive/react-icons';
7
8
  import { Button } from '../../../Button';
8
- import { Flex } from '../../../Layout';
9
+ import { Box, Flex } from '../../../Layout';
9
10
  import { config as cssConfig } from '../../../Theme';
11
+ // @ts-ignore: No implicit any
12
+ import { EmojiReaction } from '../EmojiReaction';
10
13
  import { ChatBody } from './ChatBody';
11
14
  import { ChatFooter } from './ChatFooter';
12
15
  import { ChatBlocked, ChatPaused } from './ChatStates';
13
16
  import { PinnedMessage } from './PinnedMessage';
14
17
  import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
18
+ import { useLandscapeHLSStream, useMobileHLSStream } from '../../common/hooks';
15
19
  import { SESSION_STORE_KEY } from '../../common/constants';
16
20
 
17
21
  export const Chat = () => {
@@ -21,6 +25,9 @@ export const Chat = () => {
21
25
  const vanillaStore = useHMSVanillaStore();
22
26
  const { enabled: isChatEnabled = true } = useHMSStore(selectSessionStore(SESSION_STORE_KEY.CHAT_STATE)) || {};
23
27
  const isMobile = useMedia(cssConfig.media.md);
28
+ const isMobileHLSStream = useMobileHLSStream();
29
+ const isLandscapeStream = useLandscapeHLSStream();
30
+
24
31
  const scrollToBottom = useCallback(
25
32
  (unreadCount = 0) => {
26
33
  if (listRef.current && listRef.current.scrollToItem && unreadCount > 0) {
@@ -46,6 +53,7 @@ export const Chat = () => {
46
53
  >
47
54
  {isMobile && elements?.chat?.is_overlay ? null : <PinnedMessage />}
48
55
  <ChatBody ref={listRef} scrollToBottom={scrollToBottom} />
56
+
49
57
  <ChatPaused />
50
58
  <ChatBlocked />
51
59
  {isMobile && elements?.chat?.is_overlay ? <PinnedMessage /> : null}
@@ -54,6 +62,38 @@ export const Chat = () => {
54
62
  <NewMessageIndicator scrollToBottom={scrollToBottom} listRef={listRef} />
55
63
  </ChatFooter>
56
64
  ) : null}
65
+ {(isMobileHLSStream || isLandscapeStream) && (
66
+ <Box
67
+ css={{
68
+ position: 'absolute',
69
+ ...match({ isLandscapeStream, isChatEnabled })
70
+ .with(
71
+ {
72
+ isLandscapeStream: true,
73
+ isChatEnabled: true,
74
+ },
75
+ () => ({ bottom: '$19', right: '$10' }),
76
+ )
77
+ .with(
78
+ {
79
+ isLandscapeStream: true,
80
+ isChatEnabled: false,
81
+ },
82
+ () => ({ bottom: '$20', right: '$10' }),
83
+ )
84
+ .with(
85
+ {
86
+ isLandscapeStream: false,
87
+ isChatEnabled: true,
88
+ },
89
+ () => ({ bottom: '$19', right: '$8' }),
90
+ )
91
+ .otherwise(() => ({})),
92
+ }}
93
+ >
94
+ <EmojiReaction />
95
+ </Box>
96
+ )}
57
97
  </Flex>
58
98
  );
59
99
  };
@@ -8,16 +8,16 @@ import { Box, config as cssConfig, Flex, IconButton as BaseIconButton, Popover,
8
8
  import { IconButton } from '../../../IconButton';
9
9
  import { MoreSettings } from '../MoreSettings/MoreSettings';
10
10
  import { RaiseHand } from '../RaiseHand';
11
- // @ts-ignore
11
+ // @ts-ignore: No implicit any
12
12
  import { ToastManager } from '../Toast/ToastManager';
13
13
  import { ChatSelectorContainer } from './ChatSelectorContainer';
14
14
  import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
15
- // @ts-ignore
15
+ // @ts-ignore: No implicit any
16
16
  import { useChatDraftMessage } from '../AppData/useChatState';
17
- // @ts-ignore
17
+ // @ts-ignore: No implicit any
18
18
  import { useSetSubscribedChatSelector, useSubscribeChatSelector } from '../AppData/useUISettings';
19
19
  import { useIsPeerBlacklisted } from '../hooks/useChatBlacklist';
20
- // @ts-ignore
20
+ // @ts-ignore: No implicit any
21
21
  import { useEmojiPickerStyles } from './useEmojiPickerStyles';
22
22
  import { useDefaultChatSelection, useLandscapeHLSStream, useMobileHLSStream } from '../../common/hooks';
23
23
  import { CHAT_SELECTOR, SESSION_STORE_KEY } from '../../common/constants';
@@ -148,7 +148,7 @@ export const ChatFooter = ({ onSend, children }: { onSend: (count: number) => vo
148
148
  }
149
149
 
150
150
  return (
151
- <Box>
151
+ <Box css={{ position: 'relative' }}>
152
152
  <Flex>
153
153
  <ChatSelectorContainer />
154
154
  {canDisableChat && isMobile && isOverlayChat ? (
@@ -202,10 +202,12 @@ export const ChatFooter = ({ onSend, children }: { onSend: (count: number) => vo
202
202
  align="center"
203
203
  css={{
204
204
  bg: isOverlayChat && isMobile ? '$surface_dim' : '$surface_default',
205
+ minHeight: '$16',
205
206
  maxHeight: '$24',
206
207
  position: 'relative',
208
+ py: '$6',
207
209
  pl: '$8',
208
- flexGrow: '1',
210
+ flexGrow: 1,
209
211
  r: '$1',
210
212
  '@md': {
211
213
  minHeight: 'unset',
@@ -266,15 +268,17 @@ export const ChatFooter = ({ onSend, children }: { onSend: (count: number) => vo
266
268
  </BaseIconButton>
267
269
  </Flex>
268
270
  {(isMwebHLSStream || isLandscapeHLSStream) && (
269
- <Flex
270
- css={{
271
- alignItems: 'center',
272
- }}
273
- gap="1"
274
- >
275
- {noAVPermissions ? <RaiseHand /> : null}
276
- <MoreSettings elements={elements} screenType={screenType} />
277
- </Flex>
271
+ <>
272
+ <Flex
273
+ css={{
274
+ alignItems: 'center',
275
+ }}
276
+ gap="1"
277
+ >
278
+ {noAVPermissions ? <RaiseHand css={{ bg: '$surface_default' }} /> : null}
279
+ <MoreSettings elements={elements} screenType={screenType} />
280
+ </Flex>
281
+ </>
278
282
  )}
279
283
  </Flex>
280
284
  )}
@@ -1,4 +1,4 @@
1
- import React, { Fragment, useState } from 'react';
1
+ import React, { useState } from 'react';
2
2
  import { useMedia } from 'react-use';
3
3
  import data from '@emoji-mart/data/sets/14/apple.json';
4
4
  import { init } from 'emoji-mart';
@@ -7,9 +7,7 @@ import {
7
7
  selectIsConnectedToRoom,
8
8
  selectLocalPeerID,
9
9
  useCustomEvent,
10
- // useHMSActions,
11
10
  useHMSStore,
12
- // useRecordingStreaming,
13
11
  } from '@100mslive/react-sdk';
14
12
  import { EmojiIcon } from '@100mslive/react-icons';
15
13
  import { EmojiCard } from './Footer/EmojiCard';
@@ -20,6 +18,7 @@ import { config as cssConfig } from '../../Theme';
20
18
  import { Tooltip } from '../../Tooltip';
21
19
  import IconButton from '../IconButton';
22
20
  import { useDropdownList } from './hooks/useDropdownList';
21
+ import { useLandscapeHLSStream, useMobileHLSStream } from '../common/hooks';
23
22
  import { EMOJI_REACTION_TYPE } from '../common/constants';
24
23
 
25
24
  init({ data });
@@ -33,6 +32,9 @@ export const EmojiReaction = () => {
33
32
  const localPeerId = useHMSStore(selectLocalPeerID);
34
33
  // const { isStreamingOn } = useRecordingStreaming();
35
34
  const isMobile = useMedia(cssConfig.media.md);
35
+ const isLandscape = useMedia(cssConfig.media.ls);
36
+ const isMobileHLSStream = useMobileHLSStream();
37
+ const isLandscapeStream = useLandscapeHLSStream();
36
38
 
37
39
  const { sendEvent } = useCustomEvent({
38
40
  type: EMOJI_REACTION_TYPE,
@@ -65,24 +67,32 @@ export const EmojiReaction = () => {
65
67
  if (!isConnected) {
66
68
  return null;
67
69
  }
68
- return isMobile ? (
69
- <EmojiCard sendReaction={sendReaction} />
70
- ) : (
71
- <Fragment>
72
- <Dropdown.Root open={open} onOpenChange={setOpen}>
73
- <Dropdown.Trigger asChild data-testid="emoji_reaction_btn">
74
- <IconButton>
75
- <Tooltip title="Emoji reaction">
76
- <Box>
77
- <EmojiIcon />
78
- </Box>
79
- </Tooltip>
80
- </IconButton>
81
- </Dropdown.Trigger>
82
- <Dropdown.Content sideOffset={5} align="center" css={{ p: '$8', bg: '$surface_default' }}>
83
- <EmojiCard sendReaction={sendReaction} />
84
- </Dropdown.Content>
85
- </Dropdown.Root>
86
- </Fragment>
70
+
71
+ if ((isMobile || isLandscape) && !(isLandscapeStream || isMobileHLSStream)) {
72
+ return <EmojiCard sendReaction={sendReaction} />;
73
+ }
74
+ return (
75
+ <Dropdown.Root open={open} onOpenChange={setOpen}>
76
+ <Dropdown.Trigger asChild data-testid="emoji_reaction_btn">
77
+ <IconButton
78
+ css={
79
+ isMobile || isLandscape ? { bg: '$surface_default', r: '$round', border: '1px solid $border_bright' } : {}
80
+ }
81
+ >
82
+ <Tooltip title="Emoji reaction">
83
+ <Box>
84
+ <EmojiIcon />
85
+ </Box>
86
+ </Tooltip>
87
+ </IconButton>
88
+ </Dropdown.Trigger>
89
+ <Dropdown.Content
90
+ sideOffset={5}
91
+ align={isMobileHLSStream || isLandscapeStream ? 'end' : 'center'}
92
+ css={{ p: '$8', bg: '$surface_default' }}
93
+ >
94
+ <EmojiCard sendReaction={sendReaction} />
95
+ </Dropdown.Content>
96
+ </Dropdown.Root>
87
97
  );
88
98
  };
@@ -14,6 +14,7 @@ export function HLSQualitySelector({
14
14
  onQualityChange,
15
15
  selection,
16
16
  isAuto,
17
+ containerRef,
17
18
  }: {
18
19
  open: boolean;
19
20
  onOpenChange: (value: boolean) => void;
@@ -21,9 +22,14 @@ export function HLSQualitySelector({
21
22
  onQualityChange: (quality: { [key: string]: string | number } | HMSHLSLayer) => void;
22
23
  selection: HMSHLSLayer;
23
24
  isAuto: boolean;
25
+ containerRef?: HTMLDivElement;
24
26
  }) {
25
27
  const isMobile = useMedia(config.media.md);
26
28
  const isLandscape = useIsLandscape();
29
+
30
+ if (layers.length === 0) {
31
+ return null;
32
+ }
27
33
  if (isMobile || isLandscape) {
28
34
  return (
29
35
  <Sheet.Root open={open} onOpenChange={onOpenChange}>
@@ -39,86 +45,87 @@ export function HLSQualitySelector({
39
45
  <SettingsIcon />
40
46
  </Flex>
41
47
  </Sheet.Trigger>
42
-
43
- {layers.length > 0 && (
44
- <Sheet.Content css={{ bg: '$surface_default', pb: '$1' }} onClick={() => onOpenChange(false)}>
45
- <Sheet.Title
46
- css={{
47
- display: 'flex',
48
- color: '$on_surface_high',
49
- w: '100%',
50
- justifyContent: 'space-between',
51
- mt: '$8',
52
- fontSize: '$md',
53
- px: '$10',
54
- pb: '$8',
55
- borderBottom: '1px solid $border_bright',
56
- alignItems: 'center',
57
- }}
58
- >
59
- Quality
60
- <Sheet.Close css={{ color: '$on_surface_high' }} onClick={() => onOpenChange(false)}>
61
- <CrossIcon />
62
- </Sheet.Close>
63
- </Sheet.Title>
64
- {layers.map(layer => {
65
- return (
66
- <Flex
67
- align="center"
68
- css={{
69
- w: '100%',
70
- bg: '$surface_default',
71
- '&:hover': {
72
- bg: '$surface_brighter',
73
- },
74
- cursor: 'pointer',
75
- gap: '$4',
76
- py: '$8',
77
- px: '$10',
78
- }}
79
- key={layer.width}
80
- onClick={() => onQualityChange(layer)}
81
- >
82
- <Text variant="caption" css={{ fontWeight: '$semiBold' }}>
83
- {getQualityText(layer)}
84
- </Text>
85
- <Text variant="caption" css={{ flex: '1 1 0', c: '$on_surface_low', pl: '$2' }}>
86
- {getBitrateText(layer)}
87
- </Text>
88
- {!isAuto && layer.width === selection?.width && layer.height === selection?.height && (
89
- <CheckIcon width="16px" height="16px" />
90
- )}
91
- </Flex>
92
- );
93
- })}
94
- <Flex
95
- align="center"
96
- css={{
97
- w: '100%',
98
- bg: '$surface_default',
99
- '&:hover': {
100
- bg: '$surface_brighter',
101
- },
102
- cursor: 'pointer',
103
- gap: '$4',
104
- py: '$8',
105
- px: '$10',
106
- }}
107
- key="auto"
108
- onClick={() => onQualityChange({ height: 'auto' })}
109
- >
110
- <Text variant="caption" css={{ fontWeight: '$semiBold', flex: '1 1 0' }}>
111
- Auto
112
- </Text>
113
- {isAuto && <CheckIcon width="16px" height="16px" />}
114
- </Flex>
115
- </Sheet.Content>
116
- )}
48
+ <Sheet.Content
49
+ container={containerRef}
50
+ css={{ bg: '$surface_default', pb: '$1' }}
51
+ onClick={() => onOpenChange(false)}
52
+ >
53
+ <Sheet.Title
54
+ css={{
55
+ display: 'flex',
56
+ color: '$on_surface_high',
57
+ w: '100%',
58
+ justifyContent: 'space-between',
59
+ mt: '$8',
60
+ fontSize: '$md',
61
+ px: '$10',
62
+ pb: '$8',
63
+ borderBottom: '1px solid $border_bright',
64
+ alignItems: 'center',
65
+ }}
66
+ >
67
+ Quality
68
+ <Sheet.Close css={{ color: '$on_surface_high' }} onClick={() => onOpenChange(false)}>
69
+ <CrossIcon />
70
+ </Sheet.Close>
71
+ </Sheet.Title>
72
+ {layers.map(layer => {
73
+ return (
74
+ <Flex
75
+ align="center"
76
+ css={{
77
+ w: '100%',
78
+ bg: '$surface_default',
79
+ '&:hover': {
80
+ bg: '$surface_brighter',
81
+ },
82
+ cursor: 'pointer',
83
+ gap: '$4',
84
+ py: '$8',
85
+ px: '$10',
86
+ }}
87
+ key={layer.width}
88
+ onClick={() => onQualityChange(layer)}
89
+ >
90
+ <Text variant="caption" css={{ fontWeight: '$semiBold' }}>
91
+ {getQualityText(layer)}
92
+ </Text>
93
+ <Text variant="caption" css={{ flex: '1 1 0', c: '$on_surface_low', pl: '$2' }}>
94
+ {getBitrateText(layer)}
95
+ </Text>
96
+ {!isAuto && layer.width === selection?.width && layer.height === selection?.height && (
97
+ <CheckIcon width="16px" height="16px" />
98
+ )}
99
+ </Flex>
100
+ );
101
+ })}
102
+ <Flex
103
+ align="center"
104
+ css={{
105
+ w: '100%',
106
+ bg: '$surface_default',
107
+ '&:hover': {
108
+ bg: '$surface_brighter',
109
+ },
110
+ cursor: 'pointer',
111
+ gap: '$4',
112
+ py: '$8',
113
+ px: '$10',
114
+ }}
115
+ key="auto"
116
+ onClick={() => onQualityChange({ height: 'auto' })}
117
+ >
118
+ <Text variant="caption" css={{ fontWeight: '$semiBold', flex: '1 1 0' }}>
119
+ Auto
120
+ </Text>
121
+ {isAuto && <CheckIcon width="16px" height="16px" />}
122
+ </Flex>
123
+ </Sheet.Content>
117
124
  </Sheet.Root>
118
125
  );
119
126
  }
120
127
  return (
121
- <Dropdown.Root open={open} onOpenChange={value => onOpenChange(value)}>
128
+ <Dropdown.Root open={open} onOpenChange={value => onOpenChange(value)} modal={false}>
122
129
  <Dropdown.Trigger asChild data-testid="quality_selector">
123
130
  <Flex
124
131
  css={{
@@ -169,7 +176,7 @@ export function HLSQualitySelector({
169
176
  </Tooltip>
170
177
  </Flex>
171
178
  </Dropdown.Trigger>
172
- {layers.length > 0 && (
179
+ <Dropdown.Portal container={containerRef}>
173
180
  <Dropdown.Content
174
181
  sideOffset={5}
175
182
  align="end"
@@ -232,7 +239,7 @@ export function HLSQualitySelector({
232
239
  {isAuto && <CheckIcon width="16px" height="16px" />}
233
240
  </Dropdown.Item>
234
241
  </Dropdown.Content>
235
- )}
242
+ </Dropdown.Portal>
236
243
  </Dropdown.Root>
237
244
  );
238
245
  }
@@ -14,13 +14,12 @@ export const HMSVideo = forwardRef(({ children, ...props }, videoRef) => {
14
14
  position: 'relative',
15
15
  '& video::cue': {
16
16
  color: 'white',
17
- // textShadow: '0px 0px 4px #000',
18
17
  whiteSpace: 'pre-line',
19
- fontSize: '$lg',
18
+ fontSize: '$sm',
20
19
  fontStyle: 'normal',
21
- fontWeight: '$semiBold',
20
+ fontWeight: '$regular',
22
21
  lineHeight: '$sm',
23
- letterSpacing: '0.5px',
22
+ letterSpacing: '0.25px',
24
23
  },
25
24
  '& video::-webkit-media-text-track-display': {
26
25
  padding: '0 $4',