diff --git a/res/css/views/dialogs/_InviteDialog.scss b/res/css/views/dialogs/_InviteDialog.scss
index b9063f46b9..a6871f7547 100644
--- a/res/css/views/dialogs/_InviteDialog.scss
+++ b/res/css/views/dialogs/_InviteDialog.scss
@@ -27,37 +27,29 @@ limitations under the License.
padding-left: 8px;
overflow-x: hidden;
overflow-y: auto;
+ display: flex;
+ flex-wrap: wrap;
.mx_InviteDialog_userTile {
+ margin: 6px 6px 0 0;
display: inline-block;
- float: left;
- position: relative;
- top: 7px;
+ min-width: max-content; // prevent manipulation by flexbox
}
- // Using a textarea for this element, to circumvent autofill
- // Mostly copied from AddressPickerDialog
- textarea,
- textarea:focus {
- height: 34px;
- line-height: $font-34px;
+ // Mostly copied from AddressPickerDialog; overrides bunch of our default text input styles
+ input, input:focus {
+ margin: 6px 0 !important;
+ height: 24px;
+ line-height: $font-24px;
font-size: $font-14px;
padding-left: 12px;
- margin: 0 !important;
border: 0 !important;
outline: 0 !important;
resize: none;
- overflow: hidden;
box-sizing: border-box;
- word-wrap: nowrap;
-
- // Roughly fill about 2/5ths of the available space. This is to try and 'fill' the
- // remaining space after a bunch of pills, but is a bit hacky. Ideally we'd have
- // support for "fill remaining width", but traditional tricks don't work with what
- // we're pushing into this "field". Flexbox just makes things worse. The theory is
- // that users won't need more than about 2/5ths of the input to find the person
- // they're looking for.
- width: 40%;
+ min-width: 40%;
+ flex: 1 !important;
+ color: $primary-fg-color !important;
}
}
diff --git a/src/components/views/dialogs/InviteDialog.js b/src/components/views/dialogs/InviteDialog.js
index 108fa4d8c7..5e97e94403 100644
--- a/src/components/views/dialogs/InviteDialog.js
+++ b/src/components/views/dialogs/InviteDialog.js
@@ -663,12 +663,21 @@ export default class InviteDialog extends React.PureComponent {
};
_onKeyDown = (e) => {
- // when the field is empty and the user hits backspace remove the right-most target
- if (!e.target.value && !this.state.busy && this.state.targets.length > 0 && e.key === Key.BACKSPACE &&
- !e.ctrlKey && !e.shiftKey && !e.metaKey
- ) {
+ if (this.state.busy) return;
+ const value = e.target.value.trim();
+ const hasModifiers = e.ctrlKey || e.shiftKey || e.metaKey;
+ if (!value && this.state.targets.length > 0 && e.key === Key.BACKSPACE && !hasModifiers) {
+ // when the field is empty and the user hits backspace remove the right-most target
e.preventDefault();
this._removeMember(this.state.targets[this.state.targets.length - 1]);
+ } else if (value && e.key === Key.ENTER && !hasModifiers) {
+ // when the user hits enter with something in their field try to convert it
+ e.preventDefault();
+ this._convertFilter();
+ } else if (value && e.key === Key.SPACE && !hasModifiers && value.includes("@") && !value.includes(" ")) {
+ // when the user hits space and their input looks like an e-mail/MXID then try to convert it
+ e.preventDefault();
+ this._convertFilter();
}
};
@@ -811,6 +820,10 @@ export default class InviteDialog extends React.PureComponent {
filterText = ""; // clear the filter when the user accepts a suggestion
}
this.setState({targets, filterText});
+
+ if (this._editorRef && this._editorRef.current) {
+ this._editorRef.current.focus();
+ }
};
_removeMember = (member: Member) => {
@@ -820,6 +833,10 @@ export default class InviteDialog extends React.PureComponent {
targets.splice(idx, 1);
this.setState({targets});
}
+
+ if (this._editorRef && this._editorRef.current) {
+ this._editorRef.current.focus();
+ }
};
_onPaste = async (e) => {
@@ -829,7 +846,7 @@ export default class InviteDialog extends React.PureComponent {
return;
}
- // Prevent the text being pasted into the textarea
+ // Prevent the text being pasted into the input
e.preventDefault();
// Process it as a list of addresses to add instead
@@ -1024,8 +1041,8 @@ export default class InviteDialog extends React.PureComponent {
));
const input = (
-
);
return (