Pārlūkot izejas kodu

ref(invite): use AtlasKit for invite modal buttons and inputs (#1868)

* ref(invite): use AtlasKit for invite modal buttons and inputs

- Convert button to AK Button.
- Convert inputs to AK FieldText.

* remove noop, replace with custom empty func
master
virtuacoplenny 8 gadus atpakaļ
vecāks
revīzija
1b7973a28e

+ 17
- 1
css/modals/invite/_invite.scss Parādīt failu

32
 
32
 
33
             .dial-in-numbers-trigger-icon {
33
             .dial-in-numbers-trigger-icon {
34
                 position: absolute;
34
                 position: absolute;
35
-                right: 0;
35
+                right: 10px;
36
                 top: 4px;
36
                 top: 4px;
37
             }
37
             }
38
         }
38
         }
47
 
47
 
48
     .form-control {
48
     .form-control {
49
         padding: 0;
49
         padding: 0;
50
+
51
+        &__container {
52
+            /**
53
+             * Ensure contents display in a line and vertically centered.
54
+             */
55
+            align-items: center;
56
+
57
+            button {
58
+                font-size: $modalButtonFontSize;
59
+            }
60
+        }
61
+
62
+        &__input-container {
63
+            flex: 1;
64
+            margin-right: 10px;
65
+        }
50
     }
66
     }
51
 
67
 
52
     .inviteLink {
68
     .inviteLink {

+ 15
- 2
react/features/dial-out/components/DialOutNumbersForm.web.js Parādīt failu

1
 import { StatelessDropdownMenu } from '@atlaskit/dropdown-menu';
1
 import { StatelessDropdownMenu } from '@atlaskit/dropdown-menu';
2
 import AKFieldText, { FieldText } from '@atlaskit/field-text';
2
 import AKFieldText, { FieldText } from '@atlaskit/field-text';
3
 import ExpandIcon from '@atlaskit/icon/glyph/expand';
3
 import ExpandIcon from '@atlaskit/icon/glyph/expand';
4
-import { noop as _onNoop } from 'lodash';
5
 import React, { Component } from 'react';
4
 import React, { Component } from 'react';
6
 import { connect } from 'react-redux';
5
 import { connect } from 'react-redux';
7
 
6
 
96
         this._dialInputElem = null;
95
         this._dialInputElem = null;
97
 
96
 
98
         // Bind event handlers so they are only bound once for every instance.
97
         // Bind event handlers so they are only bound once for every instance.
98
+        this._onDropdownTriggerInputChange
99
+            = this._onDropdownTriggerInputChange.bind(this);
99
         this._onInputChange = this._onInputChange.bind(this);
100
         this._onInputChange = this._onInputChange.bind(this);
100
         this._onOpenChange = this._onOpenChange.bind(this);
101
         this._onOpenChange = this._onOpenChange.bind(this);
101
         this._onSelect = this._onSelect.bind(this);
102
         this._onSelect = this._onSelect.bind(this);
209
                     isLabelHidden = { true }
210
                     isLabelHidden = { true }
210
                     isReadOnly = { true }
211
                     isReadOnly = { true }
211
                     label = 'dial-out-code'
212
                     label = 'dial-out-code'
212
-                    onChange = { _onNoop }
213
+                    onChange = { this._onDropdownTriggerInputChange }
213
                     type = 'text'
214
                     type = 'text'
214
                     value = { dialCode || '' } />
215
                     value = { dialCode || '' } />
215
                 <span className = 'dropdown-trigger-icon'>
216
                 <span className = 'dropdown-trigger-icon'>
256
         this.props.onChange(dialCode, this.state.dialInput);
257
         this.props.onChange(dialCode, this.state.dialInput);
257
     }
258
     }
258
 
259
 
260
+    /**
261
+     * This is a no-op function used to stub out FieldText's onChange in order
262
+     * to prevent FieldText from printing prop type validation errors. FieldText
263
+     * is used as a trigger for the dropdown in {@code DialOutNumbersForm} to
264
+     * get the desired AtlasKit input look for the UI.
265
+     *
266
+     * @returns {void}
267
+     */
268
+    _onDropdownTriggerInputChange() {
269
+        // Intentionally left empty.
270
+    }
271
+
259
     /**
272
     /**
260
      * Updates the dialInput state when the input changes.
273
      * Updates the dialInput state when the input changes.
261
      *
274
      *

+ 65
- 12
react/features/invite/components/AddPasswordForm.js Parādīt failu

1
+import Button from '@atlaskit/button';
2
+import { FieldText } from '@atlaskit/field-text';
1
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
2
 import { connect } from 'react-redux';
4
 import { connect } from 'react-redux';
3
 
5
 
52
             password: ''
54
             password: ''
53
         };
55
         };
54
 
56
 
57
+        /**
58
+         * The internal reference to the React {@code component} for entering a
59
+         * password.
60
+         *
61
+         * @private
62
+         * @type {ReactComponent}
63
+         */
64
+        this._inputComponent = null;
65
+
55
         // Bind event handlers so they are only bound once for every instance.
66
         // Bind event handlers so they are only bound once for every instance.
56
         this._onKeyDown = this._onKeyDown.bind(this);
67
         this._onKeyDown = this._onKeyDown.bind(this);
57
         this._onPasswordChange = this._onPasswordChange.bind(this);
68
         this._onPasswordChange = this._onPasswordChange.bind(this);
58
         this._onSubmit = this._onSubmit.bind(this);
69
         this._onSubmit = this._onSubmit.bind(this);
70
+        this._setInput = this._setInput.bind(this);
71
+    }
72
+
73
+    /**
74
+     * Directly bind a handler to the input element. This is done in order to
75
+     * intercept enter presses so any outer forms do not become submitted.
76
+     * Atlaskit Button does not expose a way to hook onto keydown events.
77
+     *
78
+     * @inheritdoc
79
+     */
80
+    componentDidMount() {
81
+        this._inputComponent.input.onkeydown = this._onKeyDown;
82
+    }
83
+
84
+    /**
85
+     * Remove any handlers set directly on DOM elements.
86
+     *
87
+     * @inheritdoc
88
+     */
89
+    componentWillUnmount() {
90
+        this._inputComponent.input.onkeydown = null;
59
     }
91
     }
60
 
92
 
61
     /**
93
     /**
72
                 className = 'form-control'
104
                 className = 'form-control'
73
                 onSubmit = { this._onSubmit } >
105
                 onSubmit = { this._onSubmit } >
74
                 <div className = 'form-control__container'>
106
                 <div className = 'form-control__container'>
75
-                    <input
76
-                        autoFocus = { true }
77
-                        className = 'input-control'
78
-                        id = 'newPasswordInput'
79
-                        onChange = { this._onPasswordChange }
80
-                        onKeyDown = { this._onKeyDown }
81
-                        placeholder = { t('dialog.createPassword') }
82
-                        type = 'text' />
83
-                    <button
84
-                        className = 'button-control button-control_light'
85
-                        disabled = { !this.state.password }
107
+                    <div className = 'form-control__input-container'>
108
+                        <FieldText
109
+                            autoFocus = { true }
110
+                            compact = { true }
111
+                            id = 'newPasswordInput'
112
+                            isLabelHidden = { true }
113
+                            label = 'Enter Password'
114
+                            onChange = { this._onPasswordChange }
115
+                            onKeyDown = { this._onKeyDown }
116
+                            placeholder = { t('dialog.createPassword') }
117
+                            ref = { this._setInput }
118
+                            shouldFitContainer = { true }
119
+                            type = 'text' />
120
+                    </div>
121
+                    <Button
86
                         id = 'addPasswordBtn'
122
                         id = 'addPasswordBtn'
123
+                        isDisabled = { !this.state.password }
87
                         onClick = { this._onSubmit }
124
                         onClick = { this._onSubmit }
125
+                        shouldFitContainer = { true }
88
                         type = 'button'>
126
                         type = 'button'>
89
                         { t('dialog.add') }
127
                         { t('dialog.add') }
90
-                    </button>
128
+                    </Button>
91
                 </div>
129
                 </div>
92
             </div>
130
             </div>
93
         );
131
         );
141
 
179
 
142
         this.setState({ password: '' });
180
         this.setState({ password: '' });
143
     }
181
     }
182
+
183
+    /**
184
+     * Sets the instance variable for the React Component used for entering a
185
+     * password.
186
+     *
187
+     * @param {Object} inputComponent - The React Component for the input
188
+     * field.
189
+     * @private
190
+     * @returns {void}
191
+     */
192
+    _setInput(inputComponent) {
193
+        if (inputComponent !== this._inputComponent) {
194
+            this._inputComponent = inputComponent;
195
+        }
196
+    }
144
 }
197
 }
145
 
198
 
146
 export default translate(connect()(AddPasswordForm));
199
 export default translate(connect()(AddPasswordForm));

+ 33
- 9
react/features/invite/components/DialInNumbersForm.js Parādīt failu

1
+import Button from '@atlaskit/button';
1
 import { StatelessDropdownMenu } from '@atlaskit/dropdown-menu';
2
 import { StatelessDropdownMenu } from '@atlaskit/dropdown-menu';
3
+import { FieldText } from '@atlaskit/field-text';
2
 import ExpandIcon from '@atlaskit/icon/glyph/expand';
4
 import ExpandIcon from '@atlaskit/icon/glyph/expand';
3
 import React, { Component } from 'react';
5
 import React, { Component } from 'react';
4
 import { connect } from 'react-redux';
6
 import { connect } from 'react-redux';
92
 
94
 
93
         // Bind event handlers so they are only bound once for every instance.
95
         // Bind event handlers so they are only bound once for every instance.
94
         this._onCopyClick = this._onCopyClick.bind(this);
96
         this._onCopyClick = this._onCopyClick.bind(this);
97
+        this._onDropdownTriggerInputChange
98
+            = this._onDropdownTriggerInputChange.bind(this);
95
         this._onOpenChange = this._onOpenChange.bind(this);
99
         this._onOpenChange = this._onOpenChange.bind(this);
96
         this._onSelect = this._onSelect.bind(this);
100
         this._onSelect = this._onSelect.bind(this);
97
         this._setCopyElement = this._setCopyElement.bind(this);
101
         this._setCopyElement = this._setCopyElement.bind(this);
154
                 </label>
158
                 </label>
155
                 <div className = 'form-control__container'>
159
                 <div className = 'form-control__container'>
156
                     { this._createDropdownMenu(items, selectedNumber.content) }
160
                     { this._createDropdownMenu(items, selectedNumber.content) }
157
-                    <button
158
-                        className = 'button-control button-control_light'
161
+                    <Button
162
+                        appearance = 'default'
159
                         onClick = { this._onCopyClick }
163
                         onClick = { this._onCopyClick }
164
+                        shouldFitContainer = { true }
160
                         type = 'button'>
165
                         type = 'button'>
161
-                        Copy
162
-                    </button>
166
+                        { t('dialog.copy') }
167
+                    </Button>
163
                 </div>
168
                 </div>
164
                 <textarea
169
                 <textarea
165
                     className = 'dial-in-numbers-copy'
170
                     className = 'dial-in-numbers-copy'
204
     _createDropdownTrigger(triggerText) {
209
     _createDropdownTrigger(triggerText) {
205
         return (
210
         return (
206
             <div className = 'dial-in-numbers-trigger'>
211
             <div className = 'dial-in-numbers-trigger'>
207
-                <input
208
-                    className = 'input-control'
209
-                    readOnly = { true }
210
-                    type = 'text'
211
-                    value = { triggerText || '' } />
212
+                <div className = 'form-control__input-container'>
213
+                    <FieldText
214
+                        compact = { true }
215
+                        isLabelHidden = { true }
216
+                        isReadOnly = { true }
217
+                        label = 'Select Dial-In Number'
218
+                        onChange = { this._onDropdownTriggerInputChange }
219
+                        ref = { this._setInput }
220
+                        shouldFitContainer = { true }
221
+                        type = 'text'
222
+                        value = { triggerText || '' } />
223
+                </div>
212
                 <span className = 'dial-in-numbers-trigger-icon'>
224
                 <span className = 'dial-in-numbers-trigger-icon'>
213
                     <ExpandIcon
225
                     <ExpandIcon
214
                         label = 'expand'
226
                         label = 'expand'
330
         }
342
         }
331
     }
343
     }
332
 
344
 
345
+    /**
346
+     * This is a no-op function used to stub out FieldText's onChange in order
347
+     * to prevent FieldText from printing prop type validation errors. FieldText
348
+     * is used as a trigger for the dropdown in {@code DialInNumbersForm} to
349
+     * get the desired AtlasKit input look for the UI.
350
+     *
351
+     * @returns {void}
352
+     */
353
+    _onDropdownTriggerInputChange() {
354
+        // Intentionally left empty.
355
+    }
356
+
333
     /**
357
     /**
334
      * Sets the internal state to either open or close the dropdown. If the
358
      * Sets the internal state to either open or close the dropdown. If the
335
      * dropdown is disabled, the state will always be set to false.
359
      * dropdown is disabled, the state will always be set to false.

+ 47
- 26
react/features/invite/components/ShareLinkForm.js Parādīt failu

1
+import Button from '@atlaskit/button';
2
+import { FieldText } from '@atlaskit/field-text';
1
 import React, { Component } from 'react';
3
 import React, { Component } from 'react';
2
 
4
 
3
 import { translate } from '../../base/i18n';
5
 import { translate } from '../../base/i18n';
36
         super(props);
38
         super(props);
37
 
39
 
38
         /**
40
         /**
39
-         * The internal reference to the DOM/HTML element backing the React
40
-         * {@code Component} input with id {@code inviteLinkRef}. It is
41
-         * necessary for the implementation of copying to the clipboard.
41
+         * The internal reference to the React {@code component} for display
42
+         * the meeting link in an input element.
42
          *
43
          *
43
          * @private
44
          * @private
44
-         * @type {HTMLInputElement}
45
+         * @type {ReactComponent}
45
          */
46
          */
46
-        this._inputElement = null;
47
+        this._inputComponent = null;
47
 
48
 
48
         // Bind event handlers so they are only bound once for every instance.
49
         // Bind event handlers so they are only bound once for every instance.
49
         this._onClick = this._onClick.bind(this);
50
         this._onClick = this._onClick.bind(this);
51
+        this._onDropdownTriggerInputChange
52
+            = this._onDropdownTriggerInputChange.bind(this);
50
         this._setInput = this._setInput.bind(this);
53
         this._setInput = this._setInput.bind(this);
51
     }
54
     }
52
 
55
 
60
         const { t } = this.props;
63
         const { t } = this.props;
61
         const inputValue = this.props.toCopy || t('inviteUrlDefaultMsg');
64
         const inputValue = this.props.toCopy || t('inviteUrlDefaultMsg');
62
 
65
 
63
-        // FIXME An input HTML element is used here instead of atlaskit's
64
-        // field-text because the latter does not currently support readOnly.
65
         return (
66
         return (
66
             <div className = 'form-control'>
67
             <div className = 'form-control'>
67
                 <label className = 'form-control__label'>
68
                 <label className = 'form-control__label'>
68
                     { t('dialog.shareLink') }
69
                     { t('dialog.shareLink') }
69
                 </label>
70
                 </label>
70
                 <div className = 'form-control__container'>
71
                 <div className = 'form-control__container'>
71
-                    <input
72
-                        className = 'input-control inviteLink'
73
-                        id = 'inviteLinkRef'
74
-                        readOnly = { true }
75
-                        ref = { this._setInput }
76
-                        type = 'text'
77
-                        value = { inputValue } />
78
-                    <button
79
-                        className =
80
-                            'button-control button-control_light copyInviteLink'
72
+                    <div className = 'form-control__input-container'>
73
+                        <FieldText
74
+                            compact = { true }
75
+                            id = 'inviteLinkRef'
76
+                            isLabelHidden = { true }
77
+                            isReadOnly = { true }
78
+                            label = 'invite link'
79
+                            onChange = { this._onDropdownTriggerInputChange }
80
+                            ref = { this._setInput }
81
+                            shouldFitContainer = { true }
82
+                            type = 'text'
83
+                            value = { inputValue } />
84
+                    </div>
85
+                    <Button
86
+                        appearance = 'default'
81
                         onClick = { this._onClick }
87
                         onClick = { this._onClick }
88
+                        shouldFitContainer = { true }
82
                         type = 'button'>
89
                         type = 'button'>
83
                         { t('dialog.copy') }
90
                         { t('dialog.copy') }
84
-                    </button>
91
+                    </Button>
85
                 </div>
92
                 </div>
86
             </div>
93
             </div>
87
         );
94
         );
95
      */
102
      */
96
     _onClick() {
103
     _onClick() {
97
         try {
104
         try {
98
-            this._inputElement.select();
105
+            const { input } = this._inputComponent;
106
+
107
+            input.select();
99
             document.execCommand('copy');
108
             document.execCommand('copy');
100
-            this._inputElement.blur();
109
+            input.blur();
101
         } catch (err) {
110
         } catch (err) {
102
             logger.error('error when copying the text', err);
111
             logger.error('error when copying the text', err);
103
         }
112
         }
104
     }
113
     }
105
 
114
 
106
     /**
115
     /**
107
-     * Sets the internal reference to the DOM/HTML element backing the React
108
-     * {@code Component} input with id {@code inviteLinkRef}.
116
+     * This is a no-op function used to stub out FieldText's onChange in order
117
+     * to prevent FieldText from printing prop type validation errors. FieldText
118
+     * is used as a trigger for the dropdown in {@code ShareLinkForm} to get the
119
+     * desired AtlasKit input look for the UI.
120
+     *
121
+     * @returns {void}
122
+     */
123
+    _onDropdownTriggerInputChange() {
124
+        // Intentionally left empty.
125
+    }
126
+
127
+    /**
128
+     * Sets the internal reference to the React Component wrapping the input
129
+     * with id {@code inviteLinkRef}.
109
      *
130
      *
110
-     * @param {HTMLInputElement} element - The DOM/HTML element for this
111
-     * {@code Component}'s input.
131
+     * @param {ReactComponent} inputComponent - React Component for displaying
132
+     * an input for displaying the meeting link.
112
      * @private
133
      * @private
113
      * @returns {void}
134
      * @returns {void}
114
      */
135
      */
115
-    _setInput(element) {
116
-        this._inputElement = element;
136
+    _setInput(inputComponent) {
137
+        this._inputComponent = inputComponent;
117
     }
138
     }
118
 }
139
 }
119
 
140
 

Notiek ielāde…
Atcelt
Saglabāt