瀏覽代碼

feat(prejoin) Update design & refactor (#13089)

Update Dial Out Dialog design
Update Country Picker design
Convert some files to TS
Move styles from SCSS to JSS
Replace atlaskit InlineDialog with Popover in CountryPIcker and Prejoin components
factor2
Robert Pintilii 2 年之前
父節點
當前提交
d7cad9d560
沒有連結到貢獻者的電子郵件帳戶。

+ 0
- 75
css/_country-picker.scss 查看文件

1
-.cpick {
2
-    border: 1px solid #A4B8D1;
3
-    color: #fff;
4
-    display: flex;
5
-    font-size: 15px;
6
-    height: 38px;
7
-    line-height: 24px;
8
-
9
-    &-selector {
10
-        align-items: center;
11
-        background-color: #283447;
12
-        border-right: 1px solid #A4B8D1;
13
-        cursor: pointer;
14
-        display: flex;
15
-        padding: 8px 10px;
16
-        position: relative;
17
-        width: 88px;
18
-    }
19
-
20
-    &-icon {
21
-        margin-right: 8px;
22
-        position: absolute;
23
-        right: 0;
24
-        top: 12px;
25
-
26
-        & > svg {
27
-            fill: #fff;
28
-        }
29
-    }
30
-
31
-    &-input {
32
-        padding: 8px;
33
-        background: #1C2025;
34
-        border: 0;
35
-        margin: 0;
36
-        color: #fff;
37
-        caret-color: #0376DA;
38
-        flex-grow: 1;
39
-    }
40
-
41
-    &-dropdown {
42
-        height: 190px;
43
-        overflow-y: auto;
44
-        width: 343px;
45
-    }
46
-
47
-    &-dropdown-entry {
48
-        align-items: center;
49
-        cursor: pointer;
50
-        display: flex;
51
-        height: 40px;
52
-        padding: 0 10px;
53
-
54
-        &:hover {
55
-            background-color: #66768b;
56
-        }
57
-
58
-        &-text {
59
-            color: #fff;
60
-            flex-grow: 1;
61
-            font-size: 15px;
62
-            line-height: 24px;
63
-            overflow: hidden;
64
-            text-overflow: ellipsis;
65
-            white-space: nowrap;
66
-
67
-        }
68
-    }
69
-}
70
-
71
-// Override @Atlaskit/inline-dialog styles
72
-.cpick-container > div:nth-child(2) {
73
-    outline: none;
74
-    padding: 8px 0 0 0;
75
-}

+ 0
- 1
css/main.scss 查看文件

81
 @import 'audio-preview';
81
 @import 'audio-preview';
82
 @import 'video-preview';
82
 @import 'video-preview';
83
 @import 'premeeting/main';
83
 @import 'premeeting/main';
84
-@import 'country-picker';
85
 @import 'modals/invite/invite_more';
84
 @import 'modals/invite/invite_more';
86
 @import 'modals/security/security';
85
 @import 'modals/security/security';
87
 @import 'e2ee';
86
 @import 'e2ee';

+ 5
- 0
css/premeeting/_prejoin.scss 查看文件

40
 .prejoin-preview {
40
 .prejoin-preview {
41
     &-dropdown-btns {
41
     &-dropdown-btns {
42
         padding: 8px 0;
42
         padding: 8px 0;
43
+        width: 300px;
44
+        background-color: #E0E0E0;
45
+        border-radius: 3px;
46
+        position: relative;
47
+        top: -16px;
43
     }
48
     }
44
 
49
 
45
     &-dropdown-container {
50
     &-dropdown-container {

+ 7
- 12
react/features/base/ui/constants.web.ts 查看文件

111
         },
111
         },
112
 
112
 
113
         '.prejoin-dialog': {
113
         '.prejoin-dialog': {
114
-            background: '#1C2025',
114
+            backgroundColor: theme.palette.uiBackground,
115
             boxShadow: '0px 2px 20px rgba(0, 0, 0, 0.5)',
115
             boxShadow: '0px 2px 20px rgba(0, 0, 0, 0.5)',
116
-            borderRadius: '5px',
116
+            borderRadius: theme.shape.borderRadius,
117
             color: '#fff',
117
             color: '#fff',
118
             height: '400px',
118
             height: '400px',
119
             width: '375px',
119
             width: '375px',
165
             },
165
             },
166
 
166
 
167
             '.prejoin-dialog-icon': {
167
             '.prejoin-dialog-icon': {
168
-                cursor: 'pointer',
169
-
170
-                '& > svg': {
171
-                    fill: '#A4B8D1'
172
-                }
168
+                cursor: 'pointer'
173
             },
169
             },
174
 
170
 
175
             '.prejoin-dialog-btn': {
171
             '.prejoin-dialog-btn': {
176
-                width: '309px',
177
                 marginBottom: '8px'
172
                 marginBottom: '8px'
178
             },
173
             },
179
 
174
 
182
             },
177
             },
183
 
178
 
184
             '.prejoin-dialog-delimiter': {
179
             '.prejoin-dialog-delimiter': {
185
-                background: '#5f6266',
180
+                background: theme.palette.ui03,
186
                 border: '0',
181
                 border: '0',
187
                 height: '1px',
182
                 height: '1px',
188
                 margin: '0',
183
                 margin: '0',
191
             },
186
             },
192
 
187
 
193
             '.prejoin-dialog-delimiter-container': {
188
             '.prejoin-dialog-delimiter-container': {
194
-                margin: `${theme.spacing(3)} 0 ${theme.spacing(4)} 0`,
189
+                margin: `${theme.spacing(4)} 0`,
195
                 position: 'relative' as const
190
                 position: 'relative' as const
196
             },
191
             },
197
 
192
 
203
             },
198
             },
204
 
199
 
205
             '.prejoin-dialog-delimiter-txt': {
200
             '.prejoin-dialog-delimiter-txt': {
206
-                background: '#1C2025',
207
-                color: '#5f6266',
201
+                background: theme.palette.uiBackground,
202
+                color: theme.palette.text01,
208
                 fontSize: '11px',
203
                 fontSize: '11px',
209
                 textTransform: 'uppercase' as const,
204
                 textTransform: 'uppercase' as const,
210
                 padding: `0 ${theme.spacing(2)}`
205
                 padding: `0 ${theme.spacing(2)}`

+ 7
- 5
react/features/prejoin/components/web/Prejoin.tsx 查看文件

1
-import InlineDialog from '@atlaskit/inline-dialog';
2
 import React, { Component } from 'react';
1
 import React, { Component } from 'react';
3
 import { WithTranslation } from 'react-i18next';
2
 import { WithTranslation } from 'react-i18next';
4
 import { connect } from 'react-redux';
3
 import { connect } from 'react-redux';
10
 import { IconArrowDown, IconArrowUp, IconPhoneRinging, IconVolumeOff } from '../../../base/icons/svg';
9
 import { IconArrowDown, IconArrowUp, IconPhoneRinging, IconVolumeOff } from '../../../base/icons/svg';
11
 import { isVideoMutedByUser } from '../../../base/media/functions';
10
 import { isVideoMutedByUser } from '../../../base/media/functions';
12
 import { getLocalParticipant } from '../../../base/participants/functions';
11
 import { getLocalParticipant } from '../../../base/participants/functions';
12
+import Popover from '../../../base/popover/components/Popover.web';
13
 import ActionButton from '../../../base/premeeting/components/web/ActionButton';
13
 import ActionButton from '../../../base/premeeting/components/web/ActionButton';
14
 import PreMeetingScreen from '../../../base/premeeting/components/web/PreMeetingScreen';
14
 import PreMeetingScreen from '../../../base/premeeting/components/web/PreMeetingScreen';
15
 import { updateSettings } from '../../../base/settings/actions';
15
 import { updateSettings } from '../../../base/settings/actions';
373
                         data-testid = 'prejoin.errorMessage'>{t('prejoin.errorMissingName')}</div>}
373
                         data-testid = 'prejoin.errorMessage'>{t('prejoin.errorMissingName')}</div>}
374
 
374
 
375
                     <div className = 'prejoin-preview-dropdown-container'>
375
                     <div className = 'prejoin-preview-dropdown-container'>
376
-                        <InlineDialog
376
+                        <Popover
377
                             content = { hasExtraJoinButtons && <div className = 'prejoin-preview-dropdown-btns'>
377
                             content = { hasExtraJoinButtons && <div className = 'prejoin-preview-dropdown-btns'>
378
                                 {extraButtonsToRender.map(({ key, ...rest }) => (
378
                                 {extraButtonsToRender.map(({ key, ...rest }) => (
379
                                     <Button
379
                                     <Button
384
                                         { ...rest } />
384
                                         { ...rest } />
385
                                 ))}
385
                                 ))}
386
                             </div> }
386
                             </div> }
387
-                            isOpen = { showJoinByPhoneButtons }
388
-                            onClose = { _onDropdownClose }>
387
+                            onPopoverClose = { _onDropdownClose }
388
+                            position = 'bottom'
389
+                            trigger = 'click'
390
+                            visible = { showJoinByPhoneButtons }>
389
                             <ActionButton
391
                             <ActionButton
390
                                 OptionsIcon = { showJoinByPhoneButtons ? IconArrowUp : IconArrowDown }
392
                                 OptionsIcon = { showJoinByPhoneButtons ? IconArrowUp : IconArrowDown }
391
                                 ariaDropDownLabel = { t('prejoin.joinWithoutAudio') }
393
                                 ariaDropDownLabel = { t('prejoin.joinWithoutAudio') }
401
                                 type = 'primary'>
403
                                 type = 'primary'>
402
                                 { t('prejoin.joinMeeting') }
404
                                 { t('prejoin.joinMeeting') }
403
                             </ActionButton>
405
                             </ActionButton>
404
-                        </InlineDialog>
406
+                        </Popover>
405
                     </div>
407
                     </div>
406
                 </div>
408
                 </div>
407
                 { showDialog && (
409
                 { showDialog && (

react/features/prejoin/components/web/country-picker/CountryDropdown.js → react/features/prejoin/components/web/country-picker/CountryDropdown.tsx 查看文件

1
-// @flow
2
-
3
 import React from 'react';
1
 import React from 'react';
2
+import { makeStyles } from 'tss-react/mui';
4
 
3
 
5
 import { countries } from '../../../utils';
4
 import { countries } from '../../../utils';
6
 
5
 
7
 import CountryRow from './CountryRow';
6
 import CountryRow from './CountryRow';
8
 
7
 
9
-type Props = {
8
+interface IProps {
10
 
9
 
11
     /**
10
     /**
12
      * Click handler for a single entry.
11
      * Click handler for a single entry.
13
      */
12
      */
14
-    onEntryClick: Function,
15
-};
13
+    onEntryClick: Function;
14
+}
15
+
16
+const useStyles = makeStyles()(theme => {
17
+    return {
18
+        container: {
19
+            height: '190px',
20
+            width: '343px',
21
+            overflowY: 'auto',
22
+            backgroundColor: theme.palette.ui01
23
+        }
24
+    };
25
+});
16
 
26
 
17
 /**
27
 /**
18
  * This component displays the dropdown for the country picker.
28
  * This component displays the dropdown for the country picker.
19
  *
29
  *
20
  * @returns {ReactElement}
30
  * @returns {ReactElement}
21
  */
31
  */
22
-function CountryDropdown({ onEntryClick }: Props) {
32
+function CountryDropdown({ onEntryClick }: IProps) {
33
+    const { classes } = useStyles();
34
+
23
     return (
35
     return (
24
-        <div className = 'cpick-dropdown'>
36
+        <div className = { classes.container }>
25
             {countries.map(country => (
37
             {countries.map(country => (
26
                 <CountryRow
38
                 <CountryRow
27
                     country = { country }
39
                     country = { country }

+ 0
- 249
react/features/prejoin/components/web/country-picker/CountryPicker.js 查看文件

1
-// @flow
2
-
3
-import InlineDialog from '@atlaskit/inline-dialog';
4
-import React, { PureComponent } from 'react';
5
-import { connect } from 'react-redux';
6
-
7
-import { setDialOutCountry, setDialOutNumber } from '../../../actions.web';
8
-import { getDialOutCountry, getDialOutNumber } from '../../../functions';
9
-import { getCountryFromDialCodeText } from '../../../utils';
10
-
11
-import CountryDropDown from './CountryDropdown';
12
-import CountrySelector from './CountrySelector';
13
-
14
-const PREFIX_REG = /^(00)|\+/;
15
-
16
-type Props = {
17
-
18
-    /**
19
-     * The country to dial out to.
20
-     */
21
-    dialOutCountry: { name: string, dialCode: string, code: string },
22
-
23
-    /**
24
-     * The number to dial out to.
25
-     */
26
-    dialOutNumber: string,
27
-
28
-    /**
29
-     * Handler used when user presses 'Enter'.
30
-     */
31
-    onSubmit: Function,
32
-
33
-    /**
34
-     * Sets the dial out number.
35
-     */
36
-    setDialOutNumber: Function,
37
-
38
-    /**
39
-     * Sets the dial out country.
40
-     */
41
-    setDialOutCountry: Function,
42
-};
43
-
44
-type State = {
45
-
46
-    /**
47
-     * If the country picker is open or not.
48
-     */
49
-    isOpen: boolean,
50
-
51
-    /**
52
-     * The value of the input.
53
-     */
54
-    value: string
55
-}
56
-
57
-/**
58
- * This component displays a country picker with an input for the phone number.
59
- */
60
-class CountryPicker extends PureComponent<Props, State> {
61
-    /**
62
-     * A React ref to the HTML element containing the {@code input} instance.
63
-     */
64
-    inputRef: Object;
65
-
66
-    /**
67
-     * Initializes a new {@code CountryPicker} instance.
68
-     *
69
-     * @inheritdoc
70
-     */
71
-    constructor(props) {
72
-        super(props);
73
-
74
-        this.state = {
75
-            isOpen: false,
76
-            value: ''
77
-        };
78
-        this.inputRef = React.createRef();
79
-        this._onChange = this._onChange.bind(this);
80
-        this._onDropdownClose = this._onDropdownClose.bind(this);
81
-        this._onCountrySelectorClick = this._onCountrySelectorClick.bind(this);
82
-        this._onEntryClick = this._onEntryClick.bind(this);
83
-        this._onKeyPress = this._onKeyPress.bind(this);
84
-    }
85
-
86
-
87
-    /**
88
-     * Implements React's {@link Component#componentDidUnmount()}.
89
-     *
90
-     * @inheritdoc
91
-     */
92
-    componentDidMount() {
93
-        this.inputRef.current.focus();
94
-    }
95
-
96
-    /**
97
-     * Implements React's {@link Component#render()}.
98
-     *
99
-     * @inheritdoc
100
-     * @returns {ReactElement}
101
-     */
102
-    render() {
103
-        const { dialOutCountry, dialOutNumber } = this.props;
104
-        const { isOpen } = this.state;
105
-        const {
106
-            inputRef,
107
-            _onChange,
108
-            _onCountrySelectorClick,
109
-            _onDropdownClose,
110
-            _onKeyPress,
111
-            _onEntryClick
112
-        } = this;
113
-
114
-        return (
115
-            <div className = 'cpick-container'>
116
-                <InlineDialog
117
-                    content = { <CountryDropDown onEntryClick = { _onEntryClick } /> }
118
-                    isOpen = { isOpen }
119
-                    onClose = { _onDropdownClose }>
120
-                    <div className = 'cpick'>
121
-                        <CountrySelector
122
-                            country = { dialOutCountry }
123
-                            onClick = { _onCountrySelectorClick } />
124
-                        <input
125
-                            className = 'cpick-input'
126
-                            onChange = { _onChange }
127
-                            onKeyPress = { _onKeyPress }
128
-                            ref = { inputRef }
129
-                            value = { dialOutNumber } />
130
-                    </div>
131
-                </InlineDialog>
132
-            </div>
133
-        );
134
-    }
135
-
136
-    _onChange: (Object) => void;
137
-
138
-    /**
139
-     * Handles the input text change.
140
-     * Automatically updates the country from the 'CountrySelector' if a
141
-     * phone number prefix is entered (00 or +).
142
-     *
143
-     * @param {Object} e - The synthetic event.
144
-     * @returns {void}
145
-     */
146
-    _onChange({ target: { value } }) {
147
-        if (PREFIX_REG.test(value)) {
148
-            const textWithDialCode = value.replace(PREFIX_REG, '');
149
-
150
-            if (textWithDialCode.length >= 4) {
151
-                const country = getCountryFromDialCodeText(textWithDialCode);
152
-
153
-                if (country) {
154
-                    const rest = textWithDialCode.replace(country.dialCode, '');
155
-
156
-                    this.props.setDialOutCountry(country);
157
-                    this.props.setDialOutNumber(rest);
158
-
159
-                    return;
160
-                }
161
-            }
162
-        }
163
-
164
-        this.props.setDialOutNumber(value);
165
-    }
166
-
167
-    _onCountrySelectorClick: (Object) => void;
168
-
169
-    /**
170
-     * Click handler for country selector.
171
-     *
172
-     * @param {Object} e - The synthetic event.
173
-     * @returns {void}
174
-     */
175
-    _onCountrySelectorClick() {
176
-        this.setState({
177
-            isOpen: !this.setState.isOpen
178
-        });
179
-    }
180
-
181
-    _onDropdownClose: () => void;
182
-
183
-    /**
184
-     * Closes the dropdown.
185
-     *
186
-     * @returns {void}
187
-     */
188
-    _onDropdownClose() {
189
-        this.setState({
190
-            isOpen: false
191
-        });
192
-    }
193
-
194
-    _onEntryClick: (Object) => void;
195
-
196
-    /**
197
-     * Click handler for a single entry from the dropdown.
198
-     *
199
-     * @param {Object} country - The country used for dialing out.
200
-     * @returns {void}
201
-     */
202
-    _onEntryClick(country) {
203
-        this.props.setDialOutCountry(country);
204
-        this._onDropdownClose();
205
-    }
206
-
207
-    _onKeyPress: (Object) => void;
208
-
209
-    /**
210
-     * Handler for key presses.
211
-     *
212
-     * @param {Object} e - The synthetic event.
213
-     * @returns {void}
214
-     */
215
-    _onKeyPress(e) {
216
-        if (e.key === ' ' || e.key === 'Enter') {
217
-            e.preventDefault();
218
-            this.props.onSubmit();
219
-        }
220
-    }
221
-}
222
-
223
-/**
224
- * Maps (parts of) the redux state to the React {@code Component} props.
225
- *
226
- * @param {Object} state - The redux state.
227
- * @returns {Props}
228
- */
229
-function mapStateToProps(state) {
230
-    return {
231
-        dialOutCountry: getDialOutCountry(state),
232
-        dialOutNumber: getDialOutNumber(state)
233
-    };
234
-}
235
-
236
-/**
237
- * Maps redux actions to the props of the component.
238
- *
239
- * @type {{
240
- *     setDialOutCountry: Function,
241
- *     setDialOutNumber: Function
242
- * }}
243
- */
244
-const mapDispatchToProps = {
245
-    setDialOutCountry,
246
-    setDialOutNumber
247
-};
248
-
249
-export default connect(mapStateToProps, mapDispatchToProps)(CountryPicker);

+ 164
- 0
react/features/prejoin/components/web/country-picker/CountryPicker.tsx 查看文件

1
+import React, { useEffect, useRef, useState } from 'react';
2
+import { connect } from 'react-redux';
3
+import { makeStyles } from 'tss-react/mui';
4
+
5
+import { IReduxState } from '../../../../app/types';
6
+import Popover from '../../../../base/popover/components/Popover.web';
7
+import { withPixelLineHeight } from '../../../../base/styles/functions.web';
8
+import { setDialOutCountry, setDialOutNumber } from '../../../actions.web';
9
+import { getDialOutCountry, getDialOutNumber } from '../../../functions';
10
+import { getCountryFromDialCodeText } from '../../../utils';
11
+
12
+import CountryDropDown from './CountryDropdown';
13
+import CountrySelector from './CountrySelector';
14
+
15
+const PREFIX_REG = /^(00)|\+/;
16
+
17
+interface IProps {
18
+
19
+    /**
20
+     * The country to dial out to.
21
+     */
22
+    dialOutCountry: { code: string; dialCode: string; name: string; };
23
+
24
+    /**
25
+     * The number to dial out to.
26
+     */
27
+    dialOutNumber: string;
28
+
29
+    /**
30
+     * Handler used when user presses 'Enter'.
31
+     */
32
+    onSubmit: Function;
33
+
34
+    /**
35
+     * Sets the dial out country.
36
+     */
37
+    setDialOutCountry: Function;
38
+
39
+    /**
40
+     * Sets the dial out number.
41
+     */
42
+    setDialOutNumber: Function;
43
+}
44
+
45
+const useStyles = makeStyles()(theme => {
46
+    return {
47
+        container: {
48
+            border: 0,
49
+            borderRadius: theme.shape.borderRadius,
50
+            display: 'flex',
51
+            backgroundColor: theme.palette.ui03
52
+        },
53
+
54
+        input: {
55
+            padding: '0 4px',
56
+            margin: 0,
57
+            border: 0,
58
+            background: 'transparent',
59
+            color: theme.palette.text01,
60
+            flexGrow: 1,
61
+            ...withPixelLineHeight(theme.typography.bodyShortRegular)
62
+        }
63
+    };
64
+});
65
+
66
+const CountryPicker = (props: IProps) => {
67
+    const [ isOpen, setIsOpen ] = useState(false);
68
+    const inputRef = useRef<HTMLInputElement>(null);
69
+    const { classes } = useStyles();
70
+
71
+    useEffect(() => {
72
+        inputRef.current?.focus();
73
+    }, []);
74
+
75
+    const onChange = ({ target: { value: newValue } }: React.ChangeEvent<HTMLInputElement>) => {
76
+        if (PREFIX_REG.test(newValue)) {
77
+            const textWithDialCode = newValue.replace(PREFIX_REG, '');
78
+
79
+            if (textWithDialCode.length >= 4) {
80
+                const country = getCountryFromDialCodeText(textWithDialCode);
81
+
82
+                if (country) {
83
+                    const rest = textWithDialCode.replace(country.dialCode, '');
84
+
85
+                    props.setDialOutCountry(country);
86
+                    props.setDialOutNumber(rest);
87
+
88
+                    return;
89
+                }
90
+            }
91
+        }
92
+        props.setDialOutNumber(newValue);
93
+    };
94
+
95
+    const onCountrySelectorClick = () => {
96
+        setIsOpen(open => !open);
97
+    };
98
+
99
+    const onDropdownClose = () => {
100
+        setIsOpen(false);
101
+    };
102
+
103
+    const onEntryClick = (country: { code: string; dialCode: string; name: string; }) => {
104
+        props.setDialOutCountry(country);
105
+        onDropdownClose();
106
+    };
107
+
108
+    const onKeyPress = (e: React.KeyboardEvent) => {
109
+        if (e.key === ' ' || e.key === 'Enter') {
110
+            e.preventDefault();
111
+            props.onSubmit();
112
+        }
113
+    };
114
+
115
+    return (
116
+        /* eslint-disable react/jsx-no-bind */
117
+        <Popover
118
+            content = { <CountryDropDown onEntryClick = { onEntryClick } /> }
119
+            onPopoverClose = { onDropdownClose }
120
+            position = 'bottom'
121
+            trigger = 'click'
122
+            visible = { isOpen }>
123
+            <div className = { classes.container }>
124
+                <CountrySelector
125
+                    country = { props.dialOutCountry }
126
+                    onClick = { onCountrySelectorClick } />
127
+                <input
128
+                    className = { classes.input }
129
+                    onChange = { onChange }
130
+                    onKeyPress = { onKeyPress }
131
+                    ref = { inputRef }
132
+                    value = { props.dialOutNumber } />
133
+            </div>
134
+        </Popover>
135
+    );
136
+};
137
+
138
+/**
139
+ * Maps (parts of) the redux state to the React {@code Component} props.
140
+ *
141
+ * @param {Object} state - The redux state.
142
+ * @returns {IProps}
143
+ */
144
+function mapStateToProps(state: IReduxState) {
145
+    return {
146
+        dialOutCountry: getDialOutCountry(state),
147
+        dialOutNumber: getDialOutNumber(state)
148
+    };
149
+}
150
+
151
+/**
152
+ * Maps redux actions to the props of the component.
153
+ *
154
+ * @type {{
155
+ *     setDialOutCountry: Function,
156
+ *     setDialOutNumber: Function
157
+ * }}
158
+ */
159
+const mapDispatchToProps = {
160
+    setDialOutCountry,
161
+    setDialOutNumber
162
+};
163
+
164
+export default connect(mapStateToProps, mapDispatchToProps)(CountryPicker);

+ 0
- 68
react/features/prejoin/components/web/country-picker/CountryRow.js 查看文件

1
-// @flow
2
-
3
-import React, { PureComponent } from 'react';
4
-
5
-type Props = {
6
-
7
-    /**
8
-     * Country of the entry.
9
-     */
10
-    country: { name: string, dialCode: string, code: string },
11
-
12
-    /**
13
-     * Entry click handler.
14
-     */
15
-    onEntryClick: Function,
16
-};
17
-
18
-/**
19
- * This component displays a row from the country picker dropdown.
20
- */
21
-class CountryRow extends PureComponent<Props> {
22
-    /**
23
-     * Initializes a new {@code CountryRow} instance.
24
-     *
25
-     * @param {Props} props - The props of the component.
26
-     */
27
-    constructor(props: Props) {
28
-        super(props);
29
-
30
-        this._onClick = this._onClick.bind(this);
31
-    }
32
-
33
-    /**
34
-     * Implements React's {@link Component#render()}.
35
-     *
36
-     * @inheritdoc
37
-     * @returns {ReactElement}
38
-     */
39
-    render() {
40
-        const {
41
-            country: { code, dialCode, name }
42
-        } = this.props;
43
-
44
-        return (
45
-            <div
46
-                className = 'cpick-dropdown-entry'
47
-                onClick = { this._onClick }>
48
-                <div className = { `prejoin-dialog-flag iti-flag ${code}` } />
49
-                <div className = 'cpick-dropdown-entry-text'>
50
-                    {`${name} (+${dialCode})`}
51
-                </div>
52
-            </div>
53
-        );
54
-    }
55
-
56
-    _onClick: () => void;
57
-
58
-    /**
59
-     * Click handler.
60
-     *
61
-     * @returns {void}
62
-     */
63
-    _onClick() {
64
-        this.props.onEntryClick(this.props.country);
65
-    }
66
-}
67
-
68
-export default CountryRow;

+ 67
- 0
react/features/prejoin/components/web/country-picker/CountryRow.tsx 查看文件

1
+import React from 'react';
2
+import { makeStyles } from 'tss-react/mui';
3
+
4
+import { withPixelLineHeight } from '../../../../base/styles/functions.web';
5
+
6
+interface IProps {
7
+
8
+    /**
9
+     * Country of the entry.
10
+     */
11
+    country: { code: string; dialCode: string; name: string; };
12
+
13
+    /**
14
+     * Entry click handler.
15
+     */
16
+    onEntryClick: Function;
17
+}
18
+
19
+const useStyles = makeStyles()(theme => {
20
+    return {
21
+        container: {
22
+            display: 'flex',
23
+            padding: '10px',
24
+            alignItems: 'center',
25
+            backgroundColor: theme.palette.action03,
26
+
27
+            '&:hover': {
28
+                backgroundColor: theme.palette.action03Hover
29
+            }
30
+        },
31
+
32
+        flag: {
33
+            marginRight: theme.spacing(2)
34
+        },
35
+
36
+        text: {
37
+            color: theme.palette.text01,
38
+            ...withPixelLineHeight(theme.typography.bodyShortRegular),
39
+            flexGrow: 1,
40
+            overflow: 'hidden',
41
+            textOverflow: 'ellipsis',
42
+            whiteSpace: 'nowrap'
43
+        }
44
+    };
45
+});
46
+
47
+const CountryRow = ({ country, onEntryClick }: IProps) => {
48
+    const { classes, cx } = useStyles();
49
+
50
+    const _onClick = () => {
51
+        onEntryClick(country);
52
+    };
53
+
54
+    return (
55
+        <div
56
+            className = { classes.container }
57
+            // eslint-disable-next-line react/jsx-no-bind
58
+            onClick = { _onClick }>
59
+            <div className = { cx(classes.flag, 'iti-flag', country.code) } />
60
+            <div className = { classes.text }>
61
+                {`${country.name} (+${country.dialCode})`}
62
+            </div>
63
+        </div>
64
+    );
65
+};
66
+
67
+export default CountryRow;

+ 0
- 48
react/features/prejoin/components/web/country-picker/CountrySelector.js 查看文件

1
-// @flow
2
-
3
-import React, { useCallback } from 'react';
4
-
5
-import { Icon, IconArrowDown } from '../../../../base/icons';
6
-
7
-type Props = {
8
-
9
-    /**
10
-     * Country object of the entry.
11
-     */
12
-    country: { name: string, dialCode: string, code: string },
13
-
14
-    /**
15
-     * Click handler for the selector.
16
-     */
17
-    onClick: Function,
18
-};
19
-
20
-/**
21
- * This component displays the country selector with the flag.
22
- *
23
- * @returns {ReactElement}
24
- */
25
-function CountrySelector({ country: { code, dialCode }, onClick }: Props) {
26
-    const onKeyPressHandler = useCallback(e => {
27
-        if (onClick && (e.key === ' ' || e.key === 'Enter')) {
28
-            e.preventDefault();
29
-            onClick();
30
-        }
31
-    }, [ onClick ]);
32
-
33
-    return (
34
-        <div
35
-            className = 'cpick-selector'
36
-            onClick = { onClick }
37
-            onKeyPress = { onKeyPressHandler }>
38
-            <div className = { `prejoin-dialog-flag iti-flag ${code}` } />
39
-            <span>{`+${dialCode}`}</span>
40
-            <Icon
41
-                className = 'cpick-icon'
42
-                size = { 16 }
43
-                src = { IconArrowDown } />
44
-        </div>
45
-    );
46
-}
47
-
48
-export default CountrySelector;

+ 77
- 0
react/features/prejoin/components/web/country-picker/CountrySelector.tsx 查看文件

1
+import React, { useCallback } from 'react';
2
+import { makeStyles } from 'tss-react/mui';
3
+
4
+import Icon from '../../../../base/icons/components/Icon';
5
+import { IconArrowDown } from '../../../../base/icons/svg';
6
+import { withPixelLineHeight } from '../../../../base/styles/functions.web';
7
+
8
+interface IProps {
9
+
10
+    /**
11
+     * Country object of the entry.
12
+     */
13
+    country: { code: string; dialCode: string; name: string; };
14
+
15
+    /**
16
+     * Click handler for the selector.
17
+     */
18
+    onClick: () => void;
19
+}
20
+
21
+const useStyles = makeStyles()(theme => {
22
+    return {
23
+        container: {
24
+            padding: '8px 10px',
25
+            display: 'flex',
26
+            alignItems: 'center',
27
+            cursor: 'pointer',
28
+            backgroundColor: theme.palette.ui01,
29
+            borderRight: `1px solid ${theme.palette.ui03}`,
30
+            color: theme.palette.text01,
31
+            ...withPixelLineHeight(theme.typography.bodyShortRegular),
32
+            position: 'relative',
33
+            width: '88px',
34
+            borderTopLeftRadius: theme.shape.borderRadius,
35
+            borderBottomLeftRadius: theme.shape.borderRadius
36
+        },
37
+
38
+        text: {
39
+            flexGrow: 1
40
+        },
41
+
42
+        flag: {
43
+            marginRight: theme.spacing(2)
44
+        }
45
+    };
46
+});
47
+
48
+/**
49
+ * This component displays the country selector with the flag.
50
+ *
51
+ * @returns {ReactElement}
52
+ */
53
+function CountrySelector({ country: { code, dialCode }, onClick }: IProps) {
54
+    const { classes, cx } = useStyles();
55
+
56
+    const onKeyPressHandler = useCallback(e => {
57
+        if (onClick && (e.key === ' ' || e.key === 'Enter')) {
58
+            e.preventDefault();
59
+            onClick();
60
+        }
61
+    }, [ onClick ]);
62
+
63
+    return (
64
+        <div
65
+            className = { classes.container }
66
+            onClick = { onClick }
67
+            onKeyPress = { onKeyPressHandler }>
68
+            <div className = { cx(classes.flag, 'iti-flag', code) } />
69
+            <span className = { classes.text }>{`+${dialCode}`}</span>
70
+            <Icon
71
+                size = { 16 }
72
+                src = { IconArrowDown } />
73
+        </div>
74
+    );
75
+}
76
+
77
+export default CountrySelector;

+ 1
- 1
react/features/prejoin/utils.ts 查看文件

786
  * @param {string} text - The text containing the dial code.
786
  * @param {string} text - The text containing the dial code.
787
  * @returns {Object}
787
  * @returns {Object}
788
  */
788
  */
789
-export function getCountryFromDialCodeText(text: string): Object {
789
+export function getCountryFromDialCodeText(text: string) {
790
     return (
790
     return (
791
         countriesByCodeMap[text.slice(0, 4)]
791
         countriesByCodeMap[text.slice(0, 4)]
792
         || countriesByCodeMap[text.slice(0, 3)]
792
         || countriesByCodeMap[text.slice(0, 3)]

Loading…
取消
儲存