Przeglądaj źródła

feat(tooltip) Create and move to our component (#13061)

Create Tooltip component
Fix Popover positioning calculations
Add margins to popover
Remove @atlaskit/tooltip
Update all components to use the new Tooltip component

Added tooltip actions and reducers for the following functionality: when a user hovers over an element is sees the tooltip for that element and then hovers another element that has a tooltip, instead of using the delay and animations we just unmount the current tooltip and mount the next one immediately
factor2
Robert Pintilii 2 lat temu
rodzic
commit
00780929e5
No account linked to committer's email address
46 zmienionych plików z 351 dodań i 538 usunięć
  1. 19
    41
      css/_popover.scss
  2. 1
    5
      css/_reactions-menu.scss
  3. 4
    4
      css/_settings-button.scss
  4. 0
    56
      package-lock.json
  5. 0
    1
      package.json
  6. 1
    2
      react/features/app/reducers.web.ts
  7. 2
    0
      react/features/app/types.ts
  8. 15
    13
      react/features/base/popover/components/Popover.web.tsx
  9. 9
    12
      react/features/base/popover/functions.web.ts
  10. 2
    4
      react/features/base/react/components/web/BaseIndicator.tsx
  11. 1
    1
      react/features/base/toolbox/components/ToolboxItem.web.js
  12. 0
    168
      react/features/base/toolbox/components/web/OverflowMenuItem.js
  13. 5
    3
      react/features/base/toolbox/components/web/ToolboxButtonWithIcon.js
  14. 0
    111
      react/features/base/toolbox/components/web/ToolboxItem.js
  15. 0
    1
      react/features/base/toolbox/components/web/index.js
  16. 19
    0
      react/features/base/tooltip/actionTypes.tsx
  17. 29
    0
      react/features/base/tooltip/actions.tsx
  18. 150
    0
      react/features/base/tooltip/components/Tooltip.tsx
  19. 0
    50
      react/features/base/tooltip/components/TooltipWrapper.js
  20. 0
    3
      react/features/base/tooltip/components/index.js
  21. 0
    3
      react/features/base/tooltip/index.js
  22. 50
    0
      react/features/base/tooltip/reducer.ts
  23. 1
    1
      react/features/calendar-sync/components/AddMeetingUrlButton.web.js
  24. 1
    1
      react/features/calendar-sync/components/JoinButton.web.js
  25. 1
    1
      react/features/conference/components/web/InsecureRoomNameLabel.tsx
  26. 1
    3
      react/features/conference/components/web/RaisedHandsCountLabel.tsx
  27. 7
    9
      react/features/conference/components/web/SubjectText.tsx
  28. 1
    3
      react/features/conference/components/web/ToggleTopPanelLabel.tsx
  29. 2
    5
      react/features/connection-stats/components/ConnectionStatsTable.tsx
  30. 1
    3
      react/features/display-name/components/web/DisplayName.tsx
  31. 1
    3
      react/features/e2ee/components/E2EELabel.tsx
  32. 1
    1
      react/features/filmstrip/components/web/PinnedIndicator.tsx
  33. 1
    1
      react/features/filmstrip/components/web/RaisedHandIndicator.tsx
  34. 1
    2
      react/features/filmstrip/components/web/Thumbnail.tsx
  35. 3
    1
      react/features/filmstrip/constants.ts
  36. 1
    3
      react/features/invite/components/add-people-dialog/web/InviteByEmailSection.tsx
  37. 1
    1
      react/features/reactions/components/web/ReactionButton.js
  38. 1
    3
      react/features/recording/components/Recording/web/HighlightButton.tsx
  39. 1
    3
      react/features/recording/components/web/RecordingLabel.tsx
  40. 1
    3
      react/features/speaker-stats/components/web/SpeakerStats.tsx
  41. 11
    3
      react/features/toolbox/components/web/DialogPortal.ts
  42. 1
    3
      react/features/transcribing/components/TranscribingLabel.web.tsx
  43. 1
    1
      react/features/video-quality/components/VideoQualityLabel.web.js
  44. 2
    3
      react/features/virtual-background/components/VirtualBackgrounds.tsx
  45. 1
    3
      react/features/visitors/components/web/VisitorsCountLabel.tsx
  46. 1
    0
      tsconfig.native.json

+ 19
- 41
css/_popover.scss Wyświetl plik

@@ -1,49 +1,27 @@
1
-/**
2
- * Mousemove padding styles are used to add invisible elements to the popover
3
- * to allow mouse movement from the popover trigger to the popover itself
4
- * without triggering a mouseleave event.
5
- */
6
-%vertical-popover-padding {
7
-    height: 100%;
8
-    position: absolute;
9
-    top: 0;
10
-    width: 20px;
11
-    padding: 20px 0;
12
-    top: -20px;
13
-}
1
+.popover {
2
+    margin: -16px -24px;
3
+    z-index: $popoverZ;
14 4
 
15
-%horizontal-popover-padding {
16
-    height: 25px;
17
-    position: absolute;
18
-    right: 0;
19
-    width: 100%;
20
-    padding: 0 35px;
21
-    left: -35px;
22
-}
5
+    .popover-content {
6
+        margin: 16px 24px;
7
+        position: relative;
23 8
 
24
-.popover-mousemove-padding-left {
25
-    @extend %vertical-popover-padding;
26
-    left: -35px;
27
-}
9
+        &.top {
10
+            bottom: 8px;
11
+        }
28 12
 
29
-.popover-mousemove-padding-right {
30
-    @extend %vertical-popover-padding;
31
-    right: -35px;
32
-}
13
+        &.bottom {
14
+            top: 8px;
15
+        }
33 16
 
34
-.popover-mousemove-padding-bottom {
35
-    @extend %horizontal-popover-padding;
36
-    bottom: -40px;
37
-}
38
-
39
-.popover-mousemove-padding-top {
40
-    @extend %horizontal-popover-padding;
41
-    top: -40px;
42
-}
17
+        &.left {
18
+            right: 8px;
19
+        }
43 20
 
44
-.popover {
45
-    margin: -16px -24px;
46
-    z-index: $popoverZ;
21
+        &.right {
22
+            left: 8px;
23
+        }
24
+    }
47 25
 }
48 26
 
49 27
 .excalidraw .popover {

+ 1
- 5
css/_reactions-menu.scss Wyświetl plik

@@ -4,7 +4,7 @@
4 4
 	width: 280px;
5 5
 	background: $menuBG;
6 6
 	box-shadow: 0px 3px 16px rgba(0, 0, 0, 0.6), 0px 0px 4px 1px rgba(0, 0, 0, 0.25);
7
-	border-radius: 3px;
7
+	border-radius: 6px;
8 8
 	padding: 16px;
9 9
 
10 10
 	&.with-gif {
@@ -104,10 +104,6 @@
104 104
 	}
105 105
 }
106 106
 
107
-.reactions-menu-container {
108
-	padding-bottom: 6px;
109
-}
110
-
111 107
 .reactions-animations-container {
112 108
 	position: absolute;
113 109
 	width: 20%;

+ 4
- 4
css/_settings-button.scss Wyświetl plik

@@ -34,20 +34,20 @@
34 34
         background: #F2F3F4;
35 35
         box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25), 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
36 36
 
37
-        & > svg {
37
+        & svg {
38 38
             fill: #040404;
39 39
         }
40 40
 
41 41
         &.settings-button-small-icon--disabled {
42 42
             background: #36383C;
43 43
 
44
-            &> svg {
44
+            & svg {
45 45
                 fill: #929292;
46 46
             }
47 47
         }
48 48
     }
49 49
 
50
-    & > svg {
50
+    & svg {
51 51
         fill: #fff;
52 52
     }
53 53
 
@@ -55,7 +55,7 @@
55 55
         background-color: #36383c;
56 56
         cursor: default;
57 57
 
58
-        &> svg {
58
+        & svg {
59 59
             fill: #929292;
60 60
         }
61 61
     }

+ 0
- 56
package-lock.json Wyświetl plik

@@ -15,7 +15,6 @@
15 15
         "@atlaskit/inline-message": "11.0.8",
16 16
         "@atlaskit/multi-select": "15.0.5",
17 17
         "@atlaskit/theme": "11.0.2",
18
-        "@atlaskit/tooltip": "17.1.2",
19 18
         "@emotion/react": "11.10.0",
20 19
         "@emotion/styled": "11.10.0",
21 20
         "@giphy/js-fetch-api": "4.7.1",
@@ -599,18 +598,6 @@
599 598
         "styled-components": "^3.2.6"
600 599
       }
601 600
     },
602
-    "node_modules/@atlaskit/motion": {
603
-      "version": "0.4.8",
604
-      "resolved": "https://registry.npmjs.org/@atlaskit/motion/-/motion-0.4.8.tgz",
605
-      "integrity": "sha512-+5hABjUNUgl66zNya+EmNXLrbJQ7EgXA+fNQih7qzu7MkIuzJjT5vEtpXrzckLKBu1v1HsbMQW90Wnd8MJugdw==",
606
-      "dependencies": {
607
-        "@babel/runtime": "^7.0.0",
608
-        "@emotion/core": "^10.0.9"
609
-      },
610
-      "peerDependencies": {
611
-        "react": "^16.8.0"
612
-      }
613
-    },
614 601
     "node_modules/@atlaskit/multi-select": {
615 602
       "version": "15.0.5",
616 603
       "resolved": "https://registry.npmjs.org/@atlaskit/multi-select/-/multi-select-15.0.5.tgz",
@@ -789,25 +776,6 @@
789 776
         "@babel/types": "^7.15.0"
790 777
       }
791 778
     },
792
-    "node_modules/@atlaskit/tooltip": {
793
-      "version": "17.1.2",
794
-      "resolved": "https://registry.npmjs.org/@atlaskit/tooltip/-/tooltip-17.1.2.tgz",
795
-      "integrity": "sha512-0N63l18ZuyL2pjNXwY3pwnNos3HjOsFhSmnj2TLASC+RLz/6/Nk1k9gXuydfMjU2ntsr7xrVY5U7ING0mxAzQQ==",
796
-      "dependencies": {
797
-        "@atlaskit/analytics-next": "^8.1.0",
798
-        "@atlaskit/motion": "^0.4.0",
799
-        "@atlaskit/popper": "^5.0.0",
800
-        "@atlaskit/portal": "^4.0.0",
801
-        "@atlaskit/theme": "^11.0.0",
802
-        "@babel/runtime": "^7.0.0",
803
-        "@emotion/core": "^10.0.9",
804
-        "bind-event-listener": "^1.0.2"
805
-      },
806
-      "peerDependencies": {
807
-        "react": "^16.8.0",
808
-        "react-dom": "^16.8.0"
809
-      }
810
-    },
811 779
     "node_modules/@babel/code-frame": {
812 780
       "version": "7.18.6",
813 781
       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
@@ -20705,15 +20673,6 @@
20705 20673
         "react-scrolllock": "^5.0.1"
20706 20674
       }
20707 20675
     },
20708
-    "@atlaskit/motion": {
20709
-      "version": "0.4.8",
20710
-      "resolved": "https://registry.npmjs.org/@atlaskit/motion/-/motion-0.4.8.tgz",
20711
-      "integrity": "sha512-+5hABjUNUgl66zNya+EmNXLrbJQ7EgXA+fNQih7qzu7MkIuzJjT5vEtpXrzckLKBu1v1HsbMQW90Wnd8MJugdw==",
20712
-      "requires": {
20713
-        "@babel/runtime": "^7.0.0",
20714
-        "@emotion/core": "^10.0.9"
20715
-      }
20716
-    },
20717 20676
     "@atlaskit/multi-select": {
20718 20677
       "version": "15.0.5",
20719 20678
       "resolved": "https://registry.npmjs.org/@atlaskit/multi-select/-/multi-select-15.0.5.tgz",
@@ -20857,21 +20816,6 @@
20857 20816
         "@babel/types": "^7.15.0"
20858 20817
       }
20859 20818
     },
20860
-    "@atlaskit/tooltip": {
20861
-      "version": "17.1.2",
20862
-      "resolved": "https://registry.npmjs.org/@atlaskit/tooltip/-/tooltip-17.1.2.tgz",
20863
-      "integrity": "sha512-0N63l18ZuyL2pjNXwY3pwnNos3HjOsFhSmnj2TLASC+RLz/6/Nk1k9gXuydfMjU2ntsr7xrVY5U7ING0mxAzQQ==",
20864
-      "requires": {
20865
-        "@atlaskit/analytics-next": "^8.1.0",
20866
-        "@atlaskit/motion": "^0.4.0",
20867
-        "@atlaskit/popper": "^5.0.0",
20868
-        "@atlaskit/portal": "^4.0.0",
20869
-        "@atlaskit/theme": "^11.0.0",
20870
-        "@babel/runtime": "^7.0.0",
20871
-        "@emotion/core": "^10.0.9",
20872
-        "bind-event-listener": "^1.0.2"
20873
-      }
20874
-    },
20875 20819
     "@babel/code-frame": {
20876 20820
       "version": "7.18.6",
20877 20821
       "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",

+ 0
- 1
package.json Wyświetl plik

@@ -20,7 +20,6 @@
20 20
     "@atlaskit/inline-message": "11.0.8",
21 21
     "@atlaskit/multi-select": "15.0.5",
22 22
     "@atlaskit/theme": "11.0.2",
23
-    "@atlaskit/tooltip": "17.1.2",
24 23
     "@emotion/react": "11.10.0",
25 24
     "@emotion/styled": "11.10.0",
26 25
     "@giphy/js-fetch-api": "4.7.1",

+ 1
- 2
react/features/app/reducers.web.ts Wyświetl plik

@@ -1,6 +1,5 @@
1
-// @flow
2
-
3 1
 import '../base/devices/reducer';
2
+import '../base/tooltip/reducer';
4 3
 import '../e2ee/reducer';
5 4
 import '../face-landmarks/reducer';
6 5
 import '../feedback/reducer';

+ 2
- 0
react/features/app/types.ts Wyświetl plik

@@ -24,6 +24,7 @@ import { IResponsiveUIState } from '../base/responsive-ui/reducer';
24 24
 import { ISettingsState } from '../base/settings/reducer';
25 25
 import { ISoundsState } from '../base/sounds/reducer';
26 26
 import { ITestingState } from '../base/testing/reducer';
27
+import { ITooltipState } from '../base/tooltip/reducer';
27 28
 import { INoSrcDataState, ITracksState } from '../base/tracks/reducer';
28 29
 import { IUserInteractionState } from '../base/user-interaction/reducer';
29 30
 import { IBreakoutRoomsState } from '../breakout-rooms/reducer';
@@ -111,6 +112,7 @@ export interface IReduxState {
111 112
     'features/base/responsive-ui': IResponsiveUIState;
112 113
     'features/base/settings': ISettingsState;
113 114
     'features/base/sounds': ISoundsState;
115
+    'features/base/tooltip': ITooltipState;
114 116
     'features/base/tracks': ITracksState;
115 117
     'features/base/user-interaction': IUserInteractionState;
116 118
     'features/breakout-rooms': IBreakoutRoomsState;

+ 15
- 13
react/features/base/popover/components/Popover.web.tsx Wyświetl plik

@@ -5,7 +5,6 @@ import { IReduxState } from '../../../app/types';
5 5
 import DialogPortal from '../../../toolbox/components/web/DialogPortal';
6 6
 import Drawer from '../../../toolbox/components/web/Drawer';
7 7
 import JitsiPortal from '../../../toolbox/components/web/JitsiPortal';
8
-import { isMobileBrowser } from '../../environment/utils';
9 8
 import { connect } from '../../redux/functions';
10 9
 import { getContextMenuStyle } from '../functions.web';
11 10
 
@@ -14,6 +13,11 @@ import { getContextMenuStyle } from '../functions.web';
14 13
  */
15 14
 interface IProps {
16 15
 
16
+    /**
17
+     * Whether the child element can be clicked on.
18
+     */
19
+    allowClick?: boolean;
20
+
17 21
     /**
18 22
      * A child React Element to use as the trigger for showing the dialog.
19 23
      */
@@ -245,7 +249,8 @@ class Popover extends Component<IProps, IState> {
245 249
                     <DialogPortal
246 250
                         getRef = { this._setContextMenuRef }
247 251
                         setSize = { this._setContextMenuStyle }
248
-                        style = { this.state.contextMenuStyle }>
252
+                        style = { this.state.contextMenuStyle }
253
+                        targetSelector = '.popover-content'>
249 254
                         <ReactFocusLock
250 255
                             lockProps = {{
251 256
                                 role: 'dialog',
@@ -345,9 +350,11 @@ class Popover extends Component<IProps, IState> {
345 350
      * @returns {void}
346 351
      */
347 352
     _onClick(event: React.MouseEvent) {
348
-        const { trigger, visible } = this.props;
353
+        const { allowClick, trigger, visible } = this.props;
349 354
 
350
-        event.stopPropagation();
355
+        if (!allowClick) {
356
+            event.stopPropagation();
357
+        }
351 358
         if (trigger === 'click') {
352 359
             if (visible) {
353 360
                 this._onHideDialog();
@@ -417,20 +424,15 @@ class Popover extends Component<IProps, IState> {
417 424
      * @returns {ReactElement}
418 425
      */
419 426
     _renderContent() {
420
-        const { content } = this.props;
427
+        const { content, position } = this.props;
421 428
 
422 429
         return (
423 430
             <div
424 431
                 className = 'popover'
425 432
                 onKeyDown = { this._onEscKey }>
426
-                { content }
427
-                {!isMobileBrowser() && (
428
-                    <>
429
-                        <div className = 'popover-mousemove-padding-top' />
430
-                        <div className = 'popover-mousemove-padding-right' />
431
-                        <div className = 'popover-mousemove-padding-left' />
432
-                        <div className = 'popover-mousemove-padding-bottom' />
433
-                    </>)}
433
+                <div className = { `popover-content ${position.split('-')[0]}` }>
434
+                    { content }
435
+                </div>
434 436
             </div>
435 437
         );
436 438
     }

+ 9
- 12
react/features/base/popover/functions.web.ts Wyświetl plik

@@ -1,43 +1,40 @@
1
-const LEFT_RIGHT_OFFSET = 25;
2
-const TOP_BOTTOM_OFFSET = 20;
3
-
4 1
 const getLeftAlignedStyle = (bounds: DOMRect) => {
5 2
     return {
6 3
         position: 'fixed',
7
-        right: `${window.innerWidth - bounds.x + LEFT_RIGHT_OFFSET}px`
4
+        right: `${window.innerWidth - bounds.x}px`
8 5
     };
9 6
 };
10 7
 
11 8
 const getRightAlignedStyle = (bounds: DOMRect) => {
12 9
     return {
13 10
         position: 'fixed',
14
-        left: `${bounds.x + bounds.width + LEFT_RIGHT_OFFSET}px`
11
+        left: `${bounds.x + bounds.width}px`
15 12
     };
16 13
 };
17 14
 
18 15
 const getTopAlignedStyle = (bounds: DOMRect) => {
19 16
     return {
20 17
         position: 'fixed',
21
-        bottom: `${window.innerHeight - bounds.y + TOP_BOTTOM_OFFSET}px`
18
+        bottom: `${window.innerHeight - bounds.y}px`
22 19
     };
23 20
 };
24 21
 
25 22
 const getBottomAlignedStyle = (bounds: DOMRect) => {
26 23
     return {
27 24
         position: 'fixed',
28
-        top: `${bounds.y + bounds.height + TOP_BOTTOM_OFFSET}px`
25
+        top: `${bounds.y + bounds.height}px`
29 26
     };
30 27
 };
31 28
 
32 29
 const getLeftRightStartAlign = (bounds: DOMRect, size: DOMRectReadOnly) => {
33 30
     return {
34
-        top: `${Math.min(bounds.y + 15, window.innerHeight - size.height - 20)}px`
31
+        top: `${Math.min(bounds.y, window.innerHeight - size.height - 20)}px`
35 32
     };
36 33
 };
37 34
 
38 35
 const getLeftRightMidAlign = (bounds: DOMRect, size: DOMRectReadOnly) => {
39 36
     return {
40
-        bottom: `${window.innerHeight - bounds.y - bounds.height - (size.height / 2)}px`
37
+        bottom: `${window.innerHeight - bounds.y - (bounds.height / 2) - (size.height / 2)}px`
41 38
     };
42 39
 };
43 40
 
@@ -49,19 +46,19 @@ const getLeftRightEndAlign = (bounds: DOMRect, size: DOMRectReadOnly) => {
49 46
 
50 47
 const getTopBotStartAlign = (bounds: DOMRect) => {
51 48
     return {
52
-        right: `${window.innerWidth - bounds.x + 10}px`
49
+        right: `${window.innerWidth - bounds.x - 6}px`
53 50
     };
54 51
 };
55 52
 
56 53
 const getTopBotMidAlign = (bounds: DOMRect, size: DOMRectReadOnly) => {
57 54
     return {
58
-        right: `${window.innerWidth - bounds.x - (size.width / 2)}px`
55
+        right: `${window.innerWidth - bounds.x - (bounds.width / 2) - (size.width / 2)}px`
59 56
     };
60 57
 };
61 58
 
62 59
 const getTopBotEndAlign = (bounds: DOMRect) => {
63 60
     return {
64
-        left: `${bounds.x + bounds.width + 10}px`
61
+        left: `${bounds.x + bounds.width - 6}px`
65 62
     };
66 63
 };
67 64
 

+ 2
- 4
react/features/base/react/components/web/BaseIndicator.tsx Wyświetl plik

@@ -4,9 +4,7 @@ import { makeStyles } from 'tss-react/mui';
4 4
 
5 5
 import { translate } from '../../../i18n/functions';
6 6
 import Icon from '../../../icons/components/Icon';
7
-// eslint-disable-next-line lines-around-comment
8
-// @ts-ignore
9
-import { Tooltip } from '../../../tooltip';
7
+import Tooltip from '../../../tooltip/components/Tooltip';
10 8
 
11 9
 /**
12 10
  * The type of the React {@code Component} props of {@link BaseIndicator}.
@@ -58,7 +56,7 @@ interface IProps extends WithTranslation {
58 56
      * From which side of the indicator the tooltip should appear from,
59 57
      * defaulting to "top".
60 58
      */
61
-    tooltipPosition: string;
59
+    tooltipPosition: 'top' | 'bottom' | 'left' | 'right';
62 60
 }
63 61
 
64 62
 const useStyles = makeStyles()(() => {

+ 1
- 1
react/features/base/toolbox/components/ToolboxItem.web.js Wyświetl plik

@@ -3,7 +3,7 @@
3 3
 import React, { Fragment } from 'react';
4 4
 
5 5
 import { Icon } from '../../icons';
6
-import { Tooltip } from '../../tooltip';
6
+import Tooltip from '../../tooltip/components/Tooltip';
7 7
 import ContextMenuItem from '../../ui/components/web/ContextMenuItem';
8 8
 
9 9
 import AbstractToolboxItem from './AbstractToolboxItem';

+ 0
- 168
react/features/base/toolbox/components/web/OverflowMenuItem.js Wyświetl plik

@@ -1,168 +0,0 @@
1
-// @flow
2
-
3
-import React, { Component } from 'react';
4
-
5
-import { Icon } from '../../../icons';
6
-import { Tooltip } from '../../../tooltip';
7
-
8
-/**
9
- * The type of the React {@code Component} props of {@link OverflowMenuItem}.
10
- */
11
-type Props = {
12
-
13
-    /**
14
-     * A succinct description of what the item does. Used by accessibility tools
15
-     * and torture tests.
16
-     */
17
-    accessibilityLabel: string,
18
-
19
-    /**
20
-     * Whether menu item is disabled or not.
21
-     */
22
-    disabled: boolean,
23
-
24
-    /**
25
-     * A React Element to display at the end of {@code OverflowMenuItem}.
26
-     */
27
-    elementAfter?: React$Node,
28
-
29
-    /**
30
-     * The icon class to use for displaying an icon before the link text.
31
-     */
32
-    icon: Object,
33
-
34
-    /**
35
-     * Id of the icon to be rendered.
36
-     */
37
-    iconId?: string,
38
-
39
-    /**
40
-     * The callback to invoke when {@code OverflowMenuItem} is clicked.
41
-     */
42
-    onClick: Function,
43
-
44
-    /**
45
-     * The text to display in the {@code OverflowMenuItem}.
46
-     */
47
-    text: string,
48
-
49
-    /**
50
-     * The text to display in the tooltip.
51
-     */
52
-    tooltip?: string,
53
-
54
-    /**
55
-     * From which direction the tooltip should appear, relative to the button.
56
-     */
57
-    tooltipPosition: string
58
-};
59
-
60
-/**
61
- * A React {@code Component} for displaying a link to interact with other
62
- * features of the application.
63
- *
64
- * @augments Component
65
- */
66
-class OverflowMenuItem extends Component<Props> {
67
-    /**
68
-     * Default values for {@code OverflowMenuItem} component's properties.
69
-     *
70
-     * @static
71
-     */
72
-    static defaultProps = {
73
-        tooltipPosition: 'left',
74
-        disabled: false
75
-    };
76
-
77
-    /**
78
-     * Initializes a new {@code OverflowMenuItem} instance.
79
-     *
80
-     * @param {*} props - The read-only properties with which the new instance
81
-     * is to be initialized.
82
-     */
83
-    constructor(props: Props) {
84
-        super(props);
85
-
86
-        // Bind event handler so it is only bound once for every instance.
87
-        this._onKeyPress = this._onKeyPress.bind(this);
88
-    }
89
-
90
-    _onKeyPress: (Object) => void;
91
-
92
-    /**
93
-     * KeyPress handler for accessibility.
94
-     *
95
-     * @param {Object} e - The key event to handle.
96
-     *
97
-     * @returns {void}
98
-     */
99
-    _onKeyPress(e) {
100
-        if (!this.props.disabled && this.props.onClick && (e.key === ' ' || e.key === 'Enter')) {
101
-            e.preventDefault();
102
-            this.props.onClick();
103
-        }
104
-    }
105
-
106
-    /**
107
-     * Implements React's {@link Component#render()}.
108
-     *
109
-     * @inheritdoc
110
-     * @returns {ReactElement}
111
-     */
112
-    render() {
113
-        const { accessibilityLabel, disabled, elementAfter, icon, iconId, onClick } = this.props;
114
-
115
-        let className = 'overflow-menu-item';
116
-
117
-        className += this.props.disabled ? ' disabled' : '';
118
-
119
-        return (
120
-            <li
121
-                aria-disabled = { disabled }
122
-                aria-label = { accessibilityLabel }
123
-                className = { className }
124
-                onClick = { disabled ? null : onClick }
125
-                onKeyPress = { this._onKeyPress }
126
-                role = 'button'
127
-                tabIndex = { 0 }>
128
-                <span className = 'overflow-menu-item-icon'>
129
-                    <Icon
130
-                        id = { iconId }
131
-                        src = { icon } />
132
-                </span>
133
-                { this._renderText() }
134
-                {
135
-                    elementAfter || null
136
-                }
137
-            </li>
138
-        );
139
-    }
140
-
141
-    /**
142
-     * Renders the text label to display in the {@code OverflowMenuItem}.
143
-     *
144
-     * @private
145
-     * @returns {ReactElement}
146
-     */
147
-    _renderText() {
148
-        const textElement = (
149
-            <span className = 'overflow-menu-item-text'>
150
-                { this.props.text }
151
-            </span>
152
-        );
153
-
154
-        if (this.props.tooltip) {
155
-            return (
156
-                <Tooltip
157
-                    content = { this.props.tooltip }
158
-                    position = { this.props.tooltipPosition }>
159
-                    { textElement }
160
-                </Tooltip>
161
-            );
162
-        }
163
-
164
-        return textElement;
165
-    }
166
-}
167
-
168
-export default OverflowMenuItem;

+ 5
- 3
react/features/base/toolbox/components/web/ToolboxButtonWithIcon.js Wyświetl plik

@@ -4,7 +4,7 @@ import React from 'react';
4 4
 
5 5
 import { NOTIFY_CLICK_MODE } from '../../../../toolbox/constants';
6 6
 import { Icon } from '../../../icons';
7
-import { Tooltip } from '../../../tooltip';
7
+import Tooltip from '../../../tooltip/components/Tooltip';
8 8
 
9 9
 type Props = {
10 10
 
@@ -107,12 +107,13 @@ export default function ToolboxButtonWithIcon(props: Props) {
107 107
     } = props;
108 108
 
109 109
     const iconProps = {};
110
+    let className = '';
110 111
 
111 112
     if (iconDisabled) {
112
-        iconProps.className
113
+        className
113 114
             = 'settings-button-small-icon settings-button-small-icon--disabled';
114 115
     } else {
115
-        iconProps.className = 'settings-button-small-icon';
116
+        className = 'settings-button-small-icon';
116 117
         iconProps.onClick = () => {
117 118
             if (typeof APP !== 'undefined' && notifyMode) {
118 119
                 APP.API.notifyToolbarButtonClicked(
@@ -141,6 +142,7 @@ export default function ToolboxButtonWithIcon(props: Props) {
141 142
 
142 143
             <div>
143 144
                 <Tooltip
145
+                    containerClassName = { className }
144 146
                     content = { iconTooltip }
145 147
                     position = 'top'>
146 148
                     <Icon

+ 0
- 111
react/features/base/toolbox/components/web/ToolboxItem.js Wyświetl plik

@@ -1,111 +0,0 @@
1
-// @flow
2
-
3
-import React, { Fragment } from 'react';
4
-
5
-import { Icon } from '../../../icons';
6
-import { Tooltip } from '../../../tooltip';
7
-import AbstractToolboxItem from '../AbstractToolboxItem';
8
-import type { Props } from '../AbstractToolboxItem';
9
-
10
-/**
11
- * Web implementation of {@code AbstractToolboxItem}.
12
- */
13
-export default class ToolboxItem extends AbstractToolboxItem<Props> {
14
-    /**
15
-     * Initializes a new {@code ToolboxItem} instance.
16
-     *
17
-     * @inheritdoc
18
-     */
19
-    constructor(props: Props) {
20
-        super(props);
21
-
22
-        this._onKeyPress = this._onKeyPress.bind(this);
23
-    }
24
-
25
-    _onKeyPress: (Object) => void;
26
-
27
-    /**
28
-     * Handles 'Enter' and Space key on the button to trigger onClick for accessibility.
29
-     *
30
-     * @param {Object} event - The key event.
31
-     * @private
32
-     * @returns {void}
33
-     */
34
-    _onKeyPress(event) {
35
-        if (event.key === 'Enter' || event.key === ' ') {
36
-            event.preventDefault();
37
-            this.props.onClick();
38
-        }
39
-    }
40
-
41
-    /**
42
-     * Handles rendering of the actual item. If the label is being shown, which
43
-     * is controlled with the `showLabel` prop, the item is rendered for its
44
-     * display in an overflow menu, otherwise it will only have an icon, which
45
-     * can be displayed on any toolbar.
46
-     *
47
-     * @protected
48
-     * @returns {ReactElement}
49
-     */
50
-    _renderItem() {
51
-        const {
52
-            disabled,
53
-            elementAfter,
54
-            onClick,
55
-            showLabel,
56
-            tooltipPosition,
57
-            toggled
58
-        } = this.props;
59
-        const className = showLabel ? 'overflow-menu-item' : 'toolbox-button';
60
-        const props = {
61
-            'aria-pressed': toggled,
62
-            'aria-disabled': disabled,
63
-            'aria-label': this.accessibilityLabel,
64
-            className: className + (disabled ? ' disabled' : ''),
65
-            onClick: disabled ? undefined : onClick,
66
-            onKeyPress: this._onKeyPress,
67
-            tabIndex: 0,
68
-            role: 'button'
69
-        };
70
-
71
-        const elementType = showLabel ? 'li' : 'div';
72
-        const useTooltip = this.tooltip && this.tooltip.length > 0;
73
-        let children = (
74
-            <Fragment>
75
-                { this._renderIcon() }
76
-                { showLabel && <span>
77
-                    { this.label }
78
-                </span> }
79
-                { elementAfter }
80
-            </Fragment>
81
-        );
82
-
83
-        if (useTooltip) {
84
-            children = (
85
-                <Tooltip
86
-                    content = { this.tooltip }
87
-                    position = { tooltipPosition }>
88
-                    { children }
89
-                </Tooltip>
90
-            );
91
-        }
92
-
93
-        return React.createElement(elementType, props, children);
94
-    }
95
-
96
-    /**
97
-     * Helper function to render the item's icon.
98
-     *
99
-     * @private
100
-     * @returns {ReactElement}
101
-     */
102
-    _renderIcon() {
103
-        const { customClass, disabled, icon, showLabel, toggled } = this.props;
104
-        const iconComponent = <Icon src = { icon } />;
105
-        const elementType = showLabel ? 'span' : 'div';
106
-        const className = `${showLabel ? 'overflow-menu-item-icon' : 'toolbox-icon'} ${
107
-            toggled ? 'toggled' : ''} ${disabled ? 'disabled' : ''} ${customClass ?? ''}`;
108
-
109
-        return React.createElement(elementType, { className }, iconComponent);
110
-    }
111
-}

+ 0
- 1
react/features/base/toolbox/components/web/index.js Wyświetl plik

@@ -1,4 +1,3 @@
1 1
 // @flow
2 2
 
3
-export { default as OverflowMenuItem } from './OverflowMenuItem';
4 3
 export { default as ToolboxButtonWithIcon } from './ToolboxButtonWithIcon';

+ 19
- 0
react/features/base/tooltip/actionTypes.tsx Wyświetl plik

@@ -0,0 +1,19 @@
1
+/**
2
+ * The type of the action which signals a tooltip is being displayed.
3
+ *
4
+ * {
5
+ *     type: SHOW_TOOLTIP,
6
+ *     content: string
7
+ * }.
8
+ */
9
+export const SHOW_TOOLTIP = 'SHOW_TOOLTIP';
10
+
11
+/**
12
+ * The type of the action which signals a tooltip should be hidden.
13
+ *
14
+ * {
15
+ *     type: SHOW_TOOLTIP,
16
+ *     content: string
17
+ * }.
18
+ */
19
+export const HIDE_TOOLTIP = 'HIDE_TOOLTIP';

+ 29
- 0
react/features/base/tooltip/actions.tsx Wyświetl plik

@@ -0,0 +1,29 @@
1
+import { HIDE_TOOLTIP, SHOW_TOOLTIP } from './actionTypes';
2
+
3
+/**
4
+ * Set tooltip state to visible.
5
+ *
6
+ * @param {string} content - The content of the tooltip.
7
+ * Used as unique identifier for tooltip.
8
+ * @returns {Object}
9
+ */
10
+export function showTooltip(content: string) {
11
+    return {
12
+        type: SHOW_TOOLTIP,
13
+        content
14
+    };
15
+}
16
+
17
+/**
18
+ * Set tooltip state to hidden.
19
+ *
20
+ * @param {string} content - The content of the tooltip.
21
+ * Used as unique identifier for tooltip.
22
+ * @returns {Object}
23
+ */
24
+export function hideTooltip(content: string) {
25
+    return {
26
+        type: HIDE_TOOLTIP,
27
+        content
28
+    };
29
+}

+ 150
- 0
react/features/base/tooltip/components/Tooltip.tsx Wyświetl plik

@@ -0,0 +1,150 @@
1
+import React, { ReactElement, useCallback, useEffect, useRef, useState } from 'react';
2
+import { useDispatch, useSelector } from 'react-redux';
3
+import { keyframes } from 'tss-react';
4
+import { makeStyles } from 'tss-react/mui';
5
+
6
+import { IReduxState } from '../../../app/types';
7
+import { isMobileBrowser } from '../../environment/utils';
8
+import Popover from '../../popover/components/Popover.web';
9
+import { withPixelLineHeight } from '../../styles/functions.web';
10
+import { hideTooltip, showTooltip } from '../actions';
11
+
12
+const TOOLTIP_DELAY = 300;
13
+const ANIMATION_DURATION = 0.2;
14
+
15
+interface IProps {
16
+    children: ReactElement;
17
+    containerClassName?: string;
18
+    content: string;
19
+    position?: 'top' | 'bottom' | 'left' | 'right';
20
+}
21
+
22
+const useStyles = makeStyles()(theme => {
23
+    return {
24
+        container: {
25
+            backgroundColor: theme.palette.uiBackground,
26
+            borderRadius: '3px',
27
+            padding: theme.spacing(2),
28
+            ...withPixelLineHeight(theme.typography.labelRegular),
29
+            color: theme.palette.text01,
30
+            position: 'relative',
31
+
32
+            '&.mounting-animation': {
33
+                animation: `${keyframes`
34
+                    0% {
35
+                        opacity: 0;
36
+                    }
37
+                    100% {
38
+                        opacity: 1;
39
+                    }
40
+                `} ${ANIMATION_DURATION}s forwards ease-in`
41
+            },
42
+
43
+            '&.unmounting': {
44
+                animation: `${keyframes`
45
+                    0% {
46
+                        opacity: 1;
47
+                    }
48
+                    100% {
49
+                        opacity: 0;
50
+                    }
51
+                `} ${ANIMATION_DURATION}s forwards ease-out`
52
+            }
53
+        }
54
+    };
55
+});
56
+
57
+const Tooltip = ({ containerClassName, content, children, position = 'top' }: IProps) => {
58
+    const dispatch = useDispatch();
59
+    const [ visible, setVisible ] = useState(false);
60
+    const [ isUnmounting, setIsUnmounting ] = useState(false);
61
+    const { classes, cx } = useStyles();
62
+    const timeoutID = useRef({
63
+        open: 0,
64
+        close: 0
65
+    });
66
+    const {
67
+        content: storeContent,
68
+        previousContent,
69
+        visible: isVisible
70
+    } = useSelector((state: IReduxState) => state['features/base/tooltip']);
71
+
72
+    if (isMobileBrowser()) {
73
+        return children;
74
+    }
75
+
76
+    const contentComponent = (
77
+        <div
78
+            className = { cx(classes.container, previousContent === '' && 'mounting-animation',
79
+                isUnmounting && 'unmounting') }>
80
+            {content}
81
+        </div>
82
+    );
83
+
84
+    const openPopover = () => {
85
+        setVisible(true);
86
+        dispatch(showTooltip(content));
87
+    };
88
+
89
+    const closePopover = () => {
90
+        setVisible(false);
91
+        dispatch(hideTooltip(content));
92
+        setIsUnmounting(false);
93
+    };
94
+
95
+    const onPopoverOpen = useCallback(() => {
96
+        clearTimeout(timeoutID.current.close);
97
+        timeoutID.current.close = 0;
98
+        if (!visible) {
99
+            if (isVisible) {
100
+                openPopover();
101
+            } else {
102
+                timeoutID.current.open = window.setTimeout(() => {
103
+                    openPopover();
104
+                }, TOOLTIP_DELAY);
105
+            }
106
+        }
107
+    }, [ visible, isVisible ]);
108
+
109
+    const onPopoverClose = useCallback(() => {
110
+        clearTimeout(timeoutID.current.open);
111
+        if (visible) {
112
+            timeoutID.current.close = window.setTimeout(() => {
113
+                setIsUnmounting(true);
114
+            }, TOOLTIP_DELAY);
115
+        }
116
+    }, [ visible ]);
117
+
118
+    useEffect(() => {
119
+        if (isUnmounting) {
120
+            setTimeout(() => {
121
+                if (timeoutID.current.close !== 0) {
122
+                    closePopover();
123
+                }
124
+            }, (ANIMATION_DURATION * 1000) + 10);
125
+        }
126
+    }, [ isUnmounting ]);
127
+
128
+    useEffect(() => {
129
+        if (storeContent !== content) {
130
+            closePopover();
131
+            clearTimeout(timeoutID.current.close);
132
+            timeoutID.current.close = 0;
133
+        }
134
+    }, [ storeContent ]);
135
+
136
+    return (
137
+        <Popover
138
+            allowClick = { true }
139
+            className = { containerClassName }
140
+            content = { contentComponent }
141
+            onPopoverClose = { onPopoverClose }
142
+            onPopoverOpen = { onPopoverOpen }
143
+            position = { position }
144
+            visible = { visible }>
145
+            {children}
146
+        </Popover>
147
+    );
148
+};
149
+
150
+export default Tooltip;

+ 0
- 50
react/features/base/tooltip/components/TooltipWrapper.js Wyświetl plik

@@ -1,50 +0,0 @@
1
-// @flow
2
-
3
-import Tooltip from '@atlaskit/tooltip';
4
-import React from 'react';
5
-
6
-import { isMobileBrowser } from '../../environment/utils';
7
-
8
-type Props = {
9
-
10
-    /**
11
-     * Children of the component.
12
-     */
13
-    children: React$Node,
14
-
15
-    /**
16
-     * The text to be displayed in the tooltip.
17
-     */
18
-    content?: string | null,
19
-
20
-    /**
21
-     * The position of the tooltip relative to the element it contains.
22
-     */
23
-    position?: string
24
-
25
-}
26
-
27
-/**
28
- * Wrapper of AtlasKit Tooltip that doesn't render the actual tooltip in mobile browsers.
29
- *
30
- * @returns {ReactElement}
31
- */
32
-function TooltipWrapper({
33
-    children,
34
-    content,
35
-    position
36
-}: Props) {
37
-    if (isMobileBrowser()) {
38
-        return children;
39
-    }
40
-
41
-    return (
42
-        <Tooltip
43
-            content = { content }
44
-            position = { position }>
45
-            {children}
46
-        </Tooltip>
47
-    );
48
-}
49
-
50
-export default TooltipWrapper;

+ 0
- 3
react/features/base/tooltip/components/index.js Wyświetl plik

@@ -1,3 +0,0 @@
1
-// @flow
2
-
3
-export { default as Tooltip } from './TooltipWrapper';

+ 0
- 3
react/features/base/tooltip/index.js Wyświetl plik

@@ -1,3 +0,0 @@
1
-// @flow
2
-
3
-export * from './components';

+ 50
- 0
react/features/base/tooltip/reducer.ts Wyświetl plik

@@ -0,0 +1,50 @@
1
+import ReducerRegistry from '../redux/ReducerRegistry';
2
+
3
+import { HIDE_TOOLTIP, SHOW_TOOLTIP } from './actionTypes';
4
+
5
+export interface ITooltipState {
6
+    content: string;
7
+    previousContent: string;
8
+    visible: boolean;
9
+}
10
+
11
+const DEFAULT_STATE = {
12
+    content: '',
13
+    previousContent: '',
14
+    visible: false
15
+};
16
+
17
+/**
18
+ * Reduces redux actions which mark the tooltip as displayed or hidden.
19
+ *
20
+ * @param {IDialogState} state - The current redux state.
21
+ * @param {Action} action - The redux action to reduce.
22
+ * @param {string} action.type - The type of the redux action to reduce..
23
+ * @returns {State} The next redux state that is the result of reducing the
24
+ * specified action.
25
+ */
26
+ReducerRegistry.register<ITooltipState>('features/base/tooltip', (state = DEFAULT_STATE, action): ITooltipState => {
27
+    switch (action.type) {
28
+    case SHOW_TOOLTIP:
29
+        return {
30
+            content: action.content,
31
+            previousContent: state.content,
32
+            visible: true
33
+        };
34
+    case HIDE_TOOLTIP: {
35
+        // The tooltip can be marked as hidden only if the hide action
36
+        // is dispatched by the tooltip that is displayed.
37
+        if (action.content === state.content) {
38
+            return {
39
+                content: '',
40
+                previousContent: '',
41
+                visible: false
42
+            };
43
+        }
44
+
45
+        return state;
46
+    }
47
+    }
48
+
49
+    return state;
50
+});

+ 1
- 1
react/features/calendar-sync/components/AddMeetingUrlButton.web.js Wyświetl plik

@@ -10,7 +10,7 @@ import {
10 10
 import { translate } from '../../base/i18n';
11 11
 import { Icon, IconPlus } from '../../base/icons';
12 12
 import { connect } from '../../base/redux';
13
-import { Tooltip } from '../../base/tooltip';
13
+import Tooltip from '../../base/tooltip/components/Tooltip';
14 14
 import { updateCalendarEvent } from '../actions';
15 15
 
16 16
 /**

+ 1
- 1
react/features/calendar-sync/components/JoinButton.web.js Wyświetl plik

@@ -4,7 +4,7 @@ import React, { Component } from 'react';
4 4
 
5 5
 import { translate } from '../../base/i18n';
6 6
 import { Icon, IconPlus } from '../../base/icons';
7
-import { Tooltip } from '../../base/tooltip';
7
+import Tooltip from '../../base/tooltip/components/Tooltip';
8 8
 
9 9
 /**
10 10
  * The type of the React {@code Component} props of {@link JoinButton}.

+ 1
- 1
react/features/conference/components/web/InsecureRoomNameLabel.tsx Wyświetl plik

@@ -1,4 +1,3 @@
1
-import Tooltip from '@atlaskit/tooltip';
2 1
 import React from 'react';
3 2
 import { connect } from 'react-redux';
4 3
 
@@ -6,6 +5,7 @@ import { translate } from '../../../base/i18n/functions';
6 5
 import { IconExclamationTriangle } from '../../../base/icons/svg';
7 6
 import Label from '../../../base/label/components/web/Label';
8 7
 import { COLORS } from '../../../base/label/constants';
8
+import Tooltip from '../../../base/tooltip/components/Tooltip';
9 9
 import AbstractInsecureRoomNameLabel, { _mapStateToProps } from '../AbstractInsecureRoomNameLabel';
10 10
 
11 11
 /**

+ 1
- 3
react/features/conference/components/web/RaisedHandsCountLabel.tsx Wyświetl plik

@@ -6,9 +6,7 @@ import { makeStyles } from 'tss-react/mui';
6 6
 import { IReduxState } from '../../../app/types';
7 7
 import { IconRaiseHand } from '../../../base/icons/svg';
8 8
 import Label from '../../../base/label/components/web/Label';
9
-// eslint-disable-next-line lines-around-comment
10
-// @ts-ignore
11
-import { Tooltip } from '../../../base/tooltip';
9
+import Tooltip from '../../../base/tooltip/components/Tooltip';
12 10
 import { open as openParticipantsPane } from '../../../participants-pane/actions.web';
13 11
 
14 12
 const useStyles = makeStyles()(theme => {

+ 7
- 9
react/features/conference/components/web/SubjectText.tsx Wyświetl plik

@@ -5,9 +5,7 @@ import { makeStyles } from 'tss-react/mui';
5 5
 
6 6
 import { getConferenceName } from '../../../base/conference/functions';
7 7
 import { withPixelLineHeight } from '../../../base/styles/functions.web';
8
-// eslint-disable-next-line lines-around-comment
9
-// @ts-ignore
10
-import { Tooltip } from '../../../base/tooltip';
8
+import Tooltip from '../../../base/tooltip/components/Tooltip';
11 9
 
12 10
 const useStyles = makeStyles()(theme => {
13 11
     return {
@@ -44,13 +42,13 @@ const SubjectText = () => {
44 42
     const { classes } = useStyles();
45 43
 
46 44
     return (
47
-        <div className = { classes.container }>
48
-            <Tooltip
49
-                content = { subject }
50
-                position = 'bottom'>
45
+        <Tooltip
46
+            content = { subject }
47
+            position = 'bottom'>
48
+            <div className = { classes.container }>
51 49
                 <div className = { clsx('subject-text--content', classes.content) }>{subject}</div>
52
-            </Tooltip>
53
-        </div>
50
+            </div>
51
+        </Tooltip>
54 52
     );
55 53
 };
56 54
 

+ 1
- 3
react/features/conference/components/web/ToggleTopPanelLabel.tsx Wyświetl plik

@@ -5,9 +5,7 @@ import { useDispatch, useSelector } from 'react-redux';
5 5
 import { IReduxState } from '../../../app/types';
6 6
 import { IconArrowDown } from '../../../base/icons/svg/index';
7 7
 import Label from '../../../base/label/components/web/Label';
8
-// eslint-disable-next-line lines-around-comment
9
-// @ts-ignore
10
-import { Tooltip } from '../../../base/tooltip';
8
+import Tooltip from '../../../base/tooltip/components/Tooltip';
11 9
 import { setTopPanelVisible } from '../../../filmstrip/actions.web';
12 10
 
13 11
 const ToggleTopPanelLabel = () => {

+ 2
- 5
react/features/connection-stats/components/ConnectionStatsTable.tsx Wyświetl plik

@@ -230,12 +230,9 @@ const styles = (theme: Theme) => {
230 230
         },
231 231
         contextMenu: {
232 232
             position: 'relative' as const,
233
-            marginTop: 0,
233
+            margin: 0,
234 234
             right: 'auto',
235
-            padding: `${theme.spacing(2)} ${theme.spacing(1)}`,
236
-            marginLeft: theme.spacing(1),
237
-            marginRight: theme.spacing(1),
238
-            marginBottom: theme.spacing(1)
235
+            padding: `${theme.spacing(2)} ${theme.spacing(1)}`
239 236
         },
240 237
         download: {},
241 238
         mobile: {

+ 1
- 3
react/features/display-name/components/web/DisplayName.tsx Wyświetl plik

@@ -10,9 +10,7 @@ import {
10 10
 } from '../../../base/participants/functions';
11 11
 import { updateSettings } from '../../../base/settings/actions';
12 12
 import { withPixelLineHeight } from '../../../base/styles/functions.web';
13
-// eslint-disable-next-line lines-around-comment
14
-// @ts-ignore
15
-import { Tooltip } from '../../../base/tooltip';
13
+import Tooltip from '../../../base/tooltip/components/Tooltip';
16 14
 import { getIndicatorsTooltipPosition } from '../../../filmstrip/functions.web';
17 15
 import { appendSuffix } from '../../functions';
18 16
 

+ 1
- 3
react/features/e2ee/components/E2EELabel.tsx Wyświetl plik

@@ -5,9 +5,7 @@ import { translate } from '../../base/i18n/functions';
5 5
 import { IconE2EE } from '../../base/icons/svg';
6 6
 import Label from '../../base/label/components/web/Label';
7 7
 import { COLORS } from '../../base/label/constants';
8
-// eslint-disable-next-line lines-around-comment
9
-// @ts-ignore
10
-import { Tooltip } from '../../base/tooltip';
8
+import Tooltip from '../../base/tooltip/components/Tooltip';
11 9
 
12 10
 import { IProps, _mapStateToProps } from './AbstractE2EELabel';
13 11
 

+ 1
- 1
react/features/filmstrip/components/web/PinnedIndicator.tsx Wyświetl plik

@@ -27,7 +27,7 @@ interface IProps {
27 27
     /**
28 28
      * From which side of the indicator the tooltip should appear from.
29 29
      */
30
-    tooltipPosition: string;
30
+    tooltipPosition: 'top' | 'bottom' | 'left' | 'right';
31 31
 }
32 32
 
33 33
 const useStyles = makeStyles()(() => {

+ 1
- 1
react/features/filmstrip/components/web/RaisedHandIndicator.tsx Wyświetl plik

@@ -27,7 +27,7 @@ interface IProps {
27 27
     /**
28 28
      * From which side of the indicator the tooltip should appear from.
29 29
      */
30
-    tooltipPosition: string;
30
+    tooltipPosition: 'top' | 'bottom' | 'left' | 'right';
31 31
 }
32 32
 
33 33
 const useStyles = makeStyles()(theme => {

+ 1
- 2
react/features/filmstrip/components/web/Thumbnail.tsx Wyświetl plik

@@ -30,8 +30,7 @@ import {
30 30
 } from '../../../base/participants/functions';
31 31
 import { IParticipant } from '../../../base/participants/types';
32 32
 import { ASPECT_RATIO_NARROW } from '../../../base/responsive-ui/constants';
33
-// @ts-ignore
34
-import { Tooltip } from '../../../base/tooltip';
33
+import Tooltip from '../../../base/tooltip/components/Tooltip';
35 34
 import { trackStreamingStatusChanged } from '../../../base/tracks/actions';
36 35
 import {
37 36
     getLocalAudioTrack,

+ 3
- 1
react/features/filmstrip/constants.ts Wyświetl plik

@@ -222,7 +222,9 @@ export const STATS_POPOVER_POSITION = {
222 222
 /**
223 223
  * The tooltip position for the indicators on the thumbnail.
224 224
  */
225
-export const INDICATORS_TOOLTIP_POSITION = {
225
+export const INDICATORS_TOOLTIP_POSITION: {
226
+    [x: string]: 'right' | 'left' | 'top';
227
+} = {
226 228
     [THUMBNAIL_TYPE.TILE]: 'right',
227 229
     [THUMBNAIL_TYPE.VERTICAL]: 'left',
228 230
     [THUMBNAIL_TYPE.HORIZONTAL]: 'top'

+ 1
- 3
react/features/invite/components/add-people-dialog/web/InviteByEmailSection.tsx Wyświetl plik

@@ -11,9 +11,7 @@ import {
11 11
     IconOffice365,
12 12
     IconYahoo
13 13
 } from '../../../../base/icons/svg';
14
-// eslint-disable-next-line lines-around-comment
15
-// @ts-ignore
16
-import { Tooltip } from '../../../../base/tooltip';
14
+import Tooltip from '../../../../base/tooltip/components/Tooltip';
17 15
 import { copyText } from '../../../../base/util/copyText.web';
18 16
 
19 17
 interface IProps {

+ 1
- 1
react/features/reactions/components/web/ReactionButton.js Wyświetl plik

@@ -2,7 +2,7 @@
2 2
 
3 3
 import React from 'react';
4 4
 
5
-import { Tooltip } from '../../../base/tooltip';
5
+import Tooltip from '../../../base/tooltip/components/Tooltip';
6 6
 import AbstractToolbarButton from '../../../toolbox/components/AbstractToolbarButton';
7 7
 import type { Props as AbstractToolbarButtonProps } from '../../../toolbox/components/AbstractToolbarButton';
8 8
 

+ 1
- 3
react/features/recording/components/Recording/web/HighlightButton.tsx Wyświetl plik

@@ -10,9 +10,7 @@ import { IconHighlight } from '../../../../base/icons/svg';
10 10
 import { MEET_FEATURES } from '../../../../base/jwt/constants';
11 11
 import Label from '../../../../base/label/components/web/Label';
12 12
 import { connect } from '../../../../base/redux/functions';
13
-// eslint-disable-next-line lines-around-comment
14
-// @ts-ignore
15
-import { Tooltip } from '../../../../base/tooltip';
13
+import Tooltip from '../../../../base/tooltip/components/Tooltip';
16 14
 import BaseTheme from '../../../../base/ui/components/BaseTheme.web';
17 15
 import { maybeShowPremiumFeatureDialog } from '../../../../jaas/actions';
18 16
 import AbstractHighlightButton, {

+ 1
- 3
react/features/recording/components/web/RecordingLabel.tsx Wyświetl plik

@@ -7,9 +7,7 @@ import { IconRecord, IconSites } from '../../../base/icons/svg';
7 7
 import Label from '../../../base/label/components/web/Label';
8 8
 import { JitsiRecordingConstants } from '../../../base/lib-jitsi-meet';
9 9
 import { connect } from '../../../base/redux/functions';
10
-// eslint-disable-next-line lines-around-comment
11
-// @ts-ignore
12
-import { Tooltip } from '../../../base/tooltip';
10
+import Tooltip from '../../../base/tooltip/components/Tooltip';
13 11
 import AbstractRecordingLabel, {
14 12
     _mapStateToProps
15 13
 

+ 1
- 3
react/features/speaker-stats/components/web/SpeakerStats.tsx Wyświetl plik

@@ -14,9 +14,7 @@ import {
14 14
     IconEmotionsSad,
15 15
     IconEmotionsSurprised
16 16
 } from '../../../base/icons/svg';
17
-// eslint-disable-next-line lines-around-comment
18
-// @ts-ignore
19
-import { Tooltip } from '../../../base/tooltip';
17
+import Tooltip from '../../../base/tooltip/components/Tooltip';
20 18
 import Dialog from '../../../base/ui/components/web/Dialog';
21 19
 import { escapeRegexp } from '../../../base/util/helpers';
22 20
 import { initSearch, resetSearchCriteria, toggleFaceExpressions } from '../../actions.any';

+ 11
- 3
react/features/toolbox/components/web/DialogPortal.ts Wyświetl plik

@@ -31,6 +31,12 @@ type Props = {
31 31
      * Custom style to apply to the container div.
32 32
      */
33 33
     style?: any;
34
+
35
+    /**
36
+     * The selector for the element we consider the content container.
37
+     * This is used to determine the correct size of the portal content.
38
+     */
39
+    targetSelector?: string;
34 40
 };
35 41
 
36 42
 /**
@@ -39,7 +45,7 @@ type Props = {
39 45
  *
40 46
  * @returns {ReactElement}
41 47
  */
42
-function DialogPortal({ children, className, style, getRef, setSize }: Props) {
48
+function DialogPortal({ children, className, style, getRef, setSize, targetSelector }: Props) {
43 49
     const clientWidth = useSelector((state: IReduxState) => state['features/base/responsive-ui'].clientWidth);
44 50
     const [ portalTarget ] = useState(() => {
45 51
         const portalDiv = document.createElement('div');
@@ -87,13 +93,15 @@ function DialogPortal({ children, className, style, getRef, setSize }: Props) {
87 93
             }
88 94
         });
89 95
 
96
+        const target = targetSelector ? portalTarget.querySelector(targetSelector) : portalTarget;
97
+
90 98
         if (document.body) {
91 99
             document.body.appendChild(portalTarget);
92
-            observer.observe(portalTarget);
100
+            observer.observe(target ?? portalTarget);
93 101
         }
94 102
 
95 103
         return () => {
96
-            observer.unobserve(portalTarget);
104
+            observer.unobserve(target ?? portalTarget);
97 105
             if (document.body) {
98 106
                 document.body.removeChild(portalTarget);
99 107
             }

+ 1
- 3
react/features/transcribing/components/TranscribingLabel.web.tsx Wyświetl plik

@@ -3,9 +3,7 @@ import { connect } from 'react-redux';
3 3
 
4 4
 import { translate } from '../../base/i18n/functions';
5 5
 import Label from '../../base/label/components/web/Label';
6
-// eslint-disable-next-line lines-around-comment
7
-// @ts-ignore
8
-import { Tooltip } from '../../base/tooltip';
6
+import Tooltip from '../../base/tooltip/components/Tooltip';
9 7
 
10 8
 import { Props, _mapStateToProps } from './AbstractTranscribingLabel';
11 9
 

+ 1
- 1
react/features/video-quality/components/VideoQualityLabel.web.js Wyświetl plik

@@ -8,7 +8,7 @@ import { IconPerformance } from '../../base/icons';
8 8
 import { Label } from '../../base/label';
9 9
 import { COLORS } from '../../base/label/constants';
10 10
 import { connect } from '../../base/redux';
11
-import { Tooltip } from '../../base/tooltip';
11
+import Tooltip from '../../base/tooltip/components/Tooltip';
12 12
 import { shouldDisplayTileView } from '../../video-layout';
13 13
 
14 14
 import AbstractVideoQualityLabel, {

+ 2
- 3
react/features/virtual-background/components/VirtualBackgrounds.tsx Wyświetl plik

@@ -14,8 +14,7 @@ import { translate } from '../../base/i18n/functions';
14 14
 import Icon from '../../base/icons/components/Icon';
15 15
 import { IconCloseLarge } from '../../base/icons/svg';
16 16
 import { withPixelLineHeight } from '../../base/styles/functions.web';
17
-// @ts-ignore
18
-import { Tooltip } from '../../base/tooltip';
17
+import Tooltip from '../../base/tooltip/components/Tooltip';
19 18
 import Spinner from '../../base/ui/components/web/Spinner';
20 19
 import { BACKGROUNDS_LIMIT, IMAGES, type Image, VIRTUAL_BACKGROUND_TYPE } from '../constants';
21 20
 import { toDataURL } from '../functions';
@@ -430,7 +429,7 @@ function VirtualBackgrounds({
430 429
                         </Tooltip>
431 430
                         {_images.map(image => (
432 431
                             <Tooltip
433
-                                content = { image.tooltip && t(`virtualBackground.${image.tooltip}`) }
432
+                                content = { (image.tooltip && t(`virtualBackground.${image.tooltip}`)) ?? '' }
434 433
                                 key = { image.id }
435 434
                                 position = { 'top' }>
436 435
                                 <img

+ 1
- 3
react/features/visitors/components/web/VisitorsCountLabel.tsx Wyświetl plik

@@ -6,9 +6,7 @@ import { makeStyles } from 'tss-react/mui';
6 6
 import { IReduxState } from '../../../app/types';
7 7
 import { IconUsers } from '../../../base/icons/svg';
8 8
 import Label from '../../../base/label/components/web/Label';
9
-// eslint-disable-next-line lines-around-comment
10
-// @ts-ignore
11
-import { Tooltip } from '../../../base/tooltip';
9
+import Tooltip from '../../../base/tooltip/components/Tooltip';
12 10
 import { getVisitorsShortText, iAmVisitor } from '../../functions';
13 11
 
14 12
 const useStyles = makeStyles()(theme => {

+ 1
- 0
tsconfig.native.json Wyświetl plik

@@ -18,6 +18,7 @@
18 18
         "node_modules",
19 19
         "react/features/analytics/handlers/GoogleAnalyticsHandler.ts",
20 20
         "react/features/base/components/participants-pane-list",
21
+        "react/features/base/tooltip",
21 22
         "react/features/connection-stats",
22 23
         "react/features/desktop-picker",
23 24
         "react/features/e2ee",

Ładowanie…
Anuluj
Zapisz