Selaa lähdekoodia

feat(ui-components) Add clickable icon component (#11976)

factor2
Robert Pintilii 3 vuotta sitten
vanhempi
commit
0f57c37d6a
No account linked to committer's email address

+ 1
- 1
react/features/base/conference/reducer.ts Näytä tiedosto

@@ -50,7 +50,7 @@ export interface IConferenceState {
50 50
     authEnabled?: boolean|undefined;
51 51
     authLogin?: string|undefined;
52 52
     authRequired?: Object;
53
-    conference: Object|undefined;
53
+    conference: any|undefined;
54 54
     conferenceTimestamp?: number;
55 55
     e2eeSupported: boolean|undefined;
56 56
     followMeEnabled?: boolean;

+ 53
- 0
react/features/base/ui/components/web/ClickableIcon.tsx Näytä tiedosto

@@ -0,0 +1,53 @@
1
+import { makeStyles } from '@material-ui/core';
2
+import clsx from 'clsx';
3
+import React from 'react';
4
+
5
+import { isMobileBrowser } from '../../../environment/utils';
6
+import Icon from '../../../icons/components/Icon';
7
+import { Theme } from '../../types';
8
+
9
+interface IProps {
10
+    accessibilityLabel: string;
11
+    icon: Function;
12
+    onClick: () => void;
13
+}
14
+
15
+const useStyles = makeStyles((theme: Theme) => {
16
+    return {
17
+        button: {
18
+            padding: '2px',
19
+            backgroundColor: theme.palette.action03,
20
+            border: 0,
21
+            outline: 0,
22
+            borderRadius: `${theme.shape.borderRadius}px`,
23
+
24
+            '&:hover': {
25
+                backgroundColor: theme.palette.ui02
26
+            },
27
+
28
+            '&:active': {
29
+                backgroundColor: theme.palette.ui03
30
+            },
31
+
32
+            '&.is-mobile': {
33
+                padding: '10px'
34
+            }
35
+        }
36
+    };
37
+});
38
+
39
+const ClickableIcon = ({ accessibilityLabel, icon, onClick }: IProps) => {
40
+    const styles = useStyles();
41
+    const isMobile = isMobileBrowser();
42
+
43
+    return (<button
44
+        aria-label = { accessibilityLabel }
45
+        className = { clsx(styles.button, isMobile && 'is-mobile') }
46
+        onClick = { onClick }>
47
+        <Icon
48
+            size = { 24 }
49
+            src = { icon } />
50
+    </button>);
51
+};
52
+
53
+export default ClickableIcon;

react/features/participants-pane/components/web/ParticipantsPane.js → react/features/participants-pane/components/web/ParticipantsPane.tsx Näytä tiedosto

@@ -1,36 +1,50 @@
1
-// @flow
2
-
1
+/* eslint-disable lines-around-comment */
3 2
 import { withStyles } from '@material-ui/core';
4 3
 import React, { Component } from 'react';
4
+import { WithTranslation } from 'react-i18next';
5 5
 
6
+import { IState } from '../../../app/types';
6 7
 import participantsPaneTheme from '../../../base/components/themes/participantsPaneTheme.json';
8
+// @ts-ignore
7 9
 import { openDialog } from '../../../base/dialog';
8
-import { translate } from '../../../base/i18n';
9
-import { Icon, IconClose, IconHorizontalPoints } from '../../../base/icons';
10
+import { translate } from '../../../base/i18n/functions';
11
+import { IconClose, IconHorizontalPoints } from '../../../base/icons/svg/index';
12
+// @ts-ignore
10 13
 import { isLocalParticipantModerator } from '../../../base/participants/functions';
11
-import { connect } from '../../../base/redux';
14
+import { connect } from '../../../base/redux/functions';
12 15
 import Button from '../../../base/ui/components/web/Button';
16
+import ClickableIcon from '../../../base/ui/components/web/ClickableIcon';
13 17
 import { BUTTON_TYPES } from '../../../base/ui/constants';
18
+import { Theme } from '../../../base/ui/types';
19
+// @ts-ignore
14 20
 import { isAddBreakoutRoomButtonVisible } from '../../../breakout-rooms/functions';
21
+// @ts-ignore
15 22
 import { MuteEveryoneDialog } from '../../../video-menu/components/';
23
+// @ts-ignore
16 24
 import { close } from '../../actions';
17 25
 import {
18 26
     findAncestorByClass,
19 27
     getParticipantsPaneOpen,
20 28
     isMoreActionsVisible,
21 29
     isMuteAllVisible
30
+    // @ts-ignore
22 31
 } from '../../functions';
32
+// @ts-ignore
23 33
 import { AddBreakoutRoomButton } from '../breakout-rooms/components/web/AddBreakoutRoomButton';
34
+// @ts-ignore
24 35
 import { RoomList } from '../breakout-rooms/components/web/RoomList';
25 36
 
37
+// @ts-ignore
26 38
 import { FooterContextMenu } from './FooterContextMenu';
39
+// @ts-ignore
27 40
 import LobbyParticipants from './LobbyParticipants';
41
+// @ts-ignore
28 42
 import MeetingParticipants from './MeetingParticipants';
29 43
 
30 44
 /**
31 45
  * The type of the React {@code Component} props of {@link ParticipantsPane}.
32 46
  */
33
-type Props = {
47
+interface Props extends WithTranslation {
34 48
 
35 49
     /**
36 50
      * Whether there is backend support for Breakout Rooms.
@@ -52,6 +66,11 @@ type Props = {
52 66
      */
53 67
     _showAddRoomButton: boolean,
54 68
 
69
+    /**
70
+     * Whether to show the footer menu.
71
+     */
72
+    _showFooter: boolean,
73
+
55 74
     /**
56 75
      * Whether to show the more actions button.
57 76
      */
@@ -62,26 +81,16 @@ type Props = {
62 81
      */
63 82
     _showMuteAllButton: boolean,
64 83
 
65
-    /**
66
-     * Whether to show the footer menu.
67
-     */
68
-    _showFooter: boolean,
69
-
70
-    /**
71
-     * The Redux dispatch function.
72
-     */
73
-    dispatch: Function,
74
-
75 84
     /**
76 85
      * An object containing the CSS classes.
77 86
      */
78
-    classes: Object,
87
+    classes: any,
79 88
 
80 89
     /**
81
-     * The i18n translate function.
90
+     * The Redux dispatch function.
82 91
      */
83
-    t: Function
84
-};
92
+    dispatch: Function
93
+}
85 94
 
86 95
 /**
87 96
  * The type of the React {@code Component} state of {@link ParticipantsPane}.
@@ -99,7 +108,7 @@ type State = {
99 108
     searchString: string
100 109
 };
101 110
 
102
-const styles = theme => {
111
+const styles = (theme: Theme) => {
103 112
     return {
104 113
         container: {
105 114
             boxSizing: 'border-box',
@@ -170,7 +179,7 @@ class ParticipantsPane extends Component<Props, State> {
170 179
      *
171 180
      * @inheritdoc
172 181
      */
173
-    constructor(props) {
182
+    constructor(props: Props) {
174 183
         super(props);
175 184
 
176 185
         this.state = {
@@ -181,7 +190,6 @@ class ParticipantsPane extends Component<Props, State> {
181 190
         // Bind event handlers so they are only bound once per instance.
182 191
         this._onClosePane = this._onClosePane.bind(this);
183 192
         this._onDrawerClose = this._onDrawerClose.bind(this);
184
-        this._onKeyPress = this._onKeyPress.bind(this);
185 193
         this._onMuteAll = this._onMuteAll.bind(this);
186 194
         this._onToggleContext = this._onToggleContext.bind(this);
187 195
         this._onWindowClickListener = this._onWindowClickListener.bind(this);
@@ -235,17 +243,10 @@ class ParticipantsPane extends Component<Props, State> {
235 243
             <div className = 'participants_pane'>
236 244
                 <div className = 'participants_pane-content'>
237 245
                     <div className = { classes.header }>
238
-                        <div
239
-                            aria-label = { t('participantsPane.close', 'Close') }
240
-                            className = { classes.closeButton }
241
-                            onClick = { this._onClosePane }
242
-                            onKeyPress = { this._onKeyPress }
243
-                            role = 'button'
244
-                            tabIndex = { 0 }>
245
-                            <Icon
246
-                                size = { 24 }
247
-                                src = { IconClose } />
248
-                        </div>
246
+                        <ClickableIcon
247
+                            accessibilityLabel = { t('participantsPane.close', 'Close') }
248
+                            icon = { IconClose }
249
+                            onClick = { this._onClosePane } />
249 250
                     </div>
250 251
                     <div className = { classes.container }>
251 252
                         <LobbyParticipants />
@@ -286,22 +287,18 @@ class ParticipantsPane extends Component<Props, State> {
286 287
         );
287 288
     }
288 289
 
289
-    setSearchString: (string) => void;
290
-
291 290
     /**
292 291
      * Sets the search string.
293 292
      *
294 293
      * @param {string} newSearchString - The new search string.
295 294
      * @returns {void}
296 295
      */
297
-    setSearchString(newSearchString) {
296
+    setSearchString(newSearchString: string) {
298 297
         this.setState({
299 298
             searchString: newSearchString
300 299
         });
301 300
     }
302 301
 
303
-    _onClosePane: () => void;
304
-
305 302
     /**
306 303
      * Callback for closing the participant pane.
307 304
      *
@@ -312,8 +309,6 @@ class ParticipantsPane extends Component<Props, State> {
312 309
         this.props.dispatch(close());
313 310
     }
314 311
 
315
-    _onDrawerClose: () => void;
316
-
317 312
     /**
318 313
      * Callback for closing the drawer.
319 314
      *
@@ -326,24 +321,6 @@ class ParticipantsPane extends Component<Props, State> {
326 321
         });
327 322
     }
328 323
 
329
-    _onKeyPress: (Object) => void;
330
-
331
-    /**
332
-     * KeyPress handler for accessibility for closing the participants pane.
333
-     *
334
-     * @param {Object} e - The key event to handle.
335
-     *
336
-     * @returns {void}
337
-     */
338
-    _onKeyPress(e) {
339
-        if (e.key === ' ' || e.key === 'Enter') {
340
-            e.preventDefault();
341
-            this._onClosePane();
342
-        }
343
-    }
344
-
345
-    _onMuteAll: () => void;
346
-
347 324
     /**
348 325
      * The handler for clicking mute all button.
349 326
      *
@@ -353,8 +330,6 @@ class ParticipantsPane extends Component<Props, State> {
353 330
         this.props.dispatch(openDialog(MuteEveryoneDialog));
354 331
     }
355 332
 
356
-    _onToggleContext: () => void;
357
-
358 333
     /**
359 334
      * Handler for toggling open/close of the footer context menu.
360 335
      *
@@ -366,15 +341,13 @@ class ParticipantsPane extends Component<Props, State> {
366 341
         });
367 342
     }
368 343
 
369
-    _onWindowClickListener: (event: Object) => void;
370
-
371 344
     /**
372 345
      * Window click event listener.
373 346
      *
374 347
      * @param {Event} e - The click event.
375 348
      * @returns {void}
376 349
      */
377
-    _onWindowClickListener(e) {
350
+    _onWindowClickListener(e: any) {
378 351
         if (this.state.contextOpen && !findAncestorByClass(e.target, this.props.classes.footerMoreContainer)) {
379 352
             this.setState({
380 353
                 contextOpen: false
@@ -393,7 +366,7 @@ class ParticipantsPane extends Component<Props, State> {
393 366
  * @protected
394 367
  * @returns {Props}
395 368
  */
396
-function _mapStateToProps(state: Object) {
369
+function _mapStateToProps(state: IState) {
397 370
     const isPaneOpen = getParticipantsPaneOpen(state);
398 371
     const { conference } = state['features/base/conference'];
399 372
     const _isBreakoutRoomsSupported = conference?.getBreakoutRooms()?.isSupported();
@@ -408,4 +381,5 @@ function _mapStateToProps(state: Object) {
408 381
     };
409 382
 }
410 383
 
384
+// @ts-ignore
411 385
 export default translate(connect(_mapStateToProps)(withStyles(styles)(ParticipantsPane)));

Loading…
Peruuta
Tallenna