mirror of
https://github.com/vector-im/element-web.git
synced 2024-11-16 05:04:57 +08:00
Improve country dropdown UX and expose +prefix
A prefix is now exposed through a change to the API for onOptionChange. This now returns the entire country object which includes iso2, prefix etc. This also shows the prefix in the Registration and Login screens as a prefix to the phone number field.
This commit is contained in:
parent
1347d9fa65
commit
336462366e
@ -37,6 +37,7 @@ export default class CountryDropdown extends React.Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this._onSearchChange = this._onSearchChange.bind(this);
|
this._onSearchChange = this._onSearchChange.bind(this);
|
||||||
|
this._onOptionChange = this._onOptionChange.bind(this);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
searchQuery: '',
|
searchQuery: '',
|
||||||
@ -48,7 +49,7 @@ export default class CountryDropdown extends React.Component {
|
|||||||
// If no value is given, we start with the first
|
// If no value is given, we start with the first
|
||||||
// country selected, but our parent component
|
// country selected, but our parent component
|
||||||
// doesn't know this, therefore we do this.
|
// doesn't know this, therefore we do this.
|
||||||
this.props.onOptionChange(COUNTRIES[0].iso2);
|
this.props.onOptionChange(COUNTRIES[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,6 +59,10 @@ export default class CountryDropdown extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onOptionChange(iso2) {
|
||||||
|
this.props.onOptionChange(COUNTRIES_BY_ISO2[iso2]);
|
||||||
|
}
|
||||||
|
|
||||||
_flagImgForIso2(iso2) {
|
_flagImgForIso2(iso2) {
|
||||||
// Unicode Regional Indicator Symbol letter 'A'
|
// Unicode Regional Indicator Symbol letter 'A'
|
||||||
const RIS_A = 0x1F1E6;
|
const RIS_A = 0x1F1E6;
|
||||||
@ -68,6 +73,10 @@ export default class CountryDropdown extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCountryPrefix(iso2) {
|
||||||
|
return COUNTRIES_BY_ISO2[iso2].prefix;
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const Dropdown = sdk.getComponent('elements.Dropdown');
|
const Dropdown = sdk.getComponent('elements.Dropdown');
|
||||||
|
|
||||||
@ -102,9 +111,11 @@ export default class CountryDropdown extends React.Component {
|
|||||||
// values between mounting and the initial value propgating
|
// values between mounting and the initial value propgating
|
||||||
const value = this.props.value || COUNTRIES[0].iso2;
|
const value = this.props.value || COUNTRIES[0].iso2;
|
||||||
|
|
||||||
|
const getShortOption = this.props.isSmall ? this._flagImgForIso2 : undefined;
|
||||||
|
|
||||||
return <Dropdown className={this.props.className}
|
return <Dropdown className={this.props.className}
|
||||||
onOptionChange={this.props.onOptionChange} onSearchChange={this._onSearchChange}
|
onOptionChange={this._onOptionChange} onSearchChange={this._onSearchChange}
|
||||||
menuWidth={298} getShortOption={this._flagImgForIso2}
|
menuWidth={298} getShortOption={getShortOption}
|
||||||
value={value} searchEnabled={true}
|
value={value} searchEnabled={true}
|
||||||
>
|
>
|
||||||
{options}
|
{options}
|
||||||
@ -114,6 +125,7 @@ export default class CountryDropdown extends React.Component {
|
|||||||
|
|
||||||
CountryDropdown.propTypes = {
|
CountryDropdown.propTypes = {
|
||||||
className: React.PropTypes.string,
|
className: React.PropTypes.string,
|
||||||
|
isSmall: React.PropTypes.bool,
|
||||||
onOptionChange: React.PropTypes.func.isRequired,
|
onOptionChange: React.PropTypes.func.isRequired,
|
||||||
value: React.PropTypes.string,
|
value: React.PropTypes.string,
|
||||||
};
|
};
|
||||||
|
@ -90,8 +90,11 @@ class PasswordLogin extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onPhoneCountryChanged(country) {
|
onPhoneCountryChanged(country) {
|
||||||
this.setState({phoneCountry: country});
|
this.setState({
|
||||||
this.props.onPhoneCountryChanged(country);
|
phoneCountry: country.iso2,
|
||||||
|
phonePrefix: country.prefix,
|
||||||
|
});
|
||||||
|
this.props.onPhoneCountryChanged(country.iso2);
|
||||||
}
|
}
|
||||||
|
|
||||||
onPhoneNumberChanged(ev) {
|
onPhoneNumberChanged(ev) {
|
||||||
@ -121,16 +124,17 @@ class PasswordLogin extends React.Component {
|
|||||||
const mxidInputClasses = classNames({
|
const mxidInputClasses = classNames({
|
||||||
"mx_Login_field": true,
|
"mx_Login_field": true,
|
||||||
"mx_Login_username": true,
|
"mx_Login_username": true,
|
||||||
|
"mx_Login_field_has_prefix": true,
|
||||||
"mx_Login_field_has_suffix": Boolean(this.props.hsDomain),
|
"mx_Login_field_has_suffix": Boolean(this.props.hsDomain),
|
||||||
});
|
});
|
||||||
let suffix = null;
|
let suffix = null;
|
||||||
if (this.props.hsDomain) {
|
if (this.props.hsDomain) {
|
||||||
suffix = <div className="mx_Login_username_suffix">
|
suffix = <div className="mx_Login_field_suffix">
|
||||||
:{this.props.hsDomain}
|
:{this.props.hsDomain}
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
return <div className="mx_Login_username_group">
|
return <div className="mx_Login_field_group">
|
||||||
<div className="mx_Login_username_prefix">@</div>
|
<div className="mx_Login_field_prefix">@</div>
|
||||||
<input
|
<input
|
||||||
className={mxidInputClasses}
|
className={mxidInputClasses}
|
||||||
key="username_input"
|
key="username_input"
|
||||||
@ -145,6 +149,7 @@ class PasswordLogin extends React.Component {
|
|||||||
</div>;
|
</div>;
|
||||||
case PasswordLogin.LOGIN_FIELD_PHONE:
|
case PasswordLogin.LOGIN_FIELD_PHONE:
|
||||||
const CountryDropdown = sdk.getComponent('views.login.CountryDropdown');
|
const CountryDropdown = sdk.getComponent('views.login.CountryDropdown');
|
||||||
|
const prefix = this.state.phonePrefix;
|
||||||
return <div className="mx_Login_phoneSection">
|
return <div className="mx_Login_phoneSection">
|
||||||
<CountryDropdown
|
<CountryDropdown
|
||||||
className="mx_Login_phoneCountry"
|
className="mx_Login_phoneCountry"
|
||||||
@ -152,17 +157,20 @@ class PasswordLogin extends React.Component {
|
|||||||
onOptionChange={this.onPhoneCountryChanged}
|
onOptionChange={this.onPhoneCountryChanged}
|
||||||
value={this.state.phoneCountry}
|
value={this.state.phoneCountry}
|
||||||
/>
|
/>
|
||||||
<input
|
<div className="mx_Login_field_group">
|
||||||
className="mx_Login_phoneNumberField mx_Login_field"
|
<div className="mx_Login_field_prefix">+{prefix}</div>
|
||||||
ref="phoneNumber"
|
<input
|
||||||
key="phone_input"
|
className="mx_Login_phoneNumberField mx_Login_field mx_Login_field_has_prefix"
|
||||||
type="text"
|
ref="phoneNumber"
|
||||||
name="phoneNumber"
|
key="phone_input"
|
||||||
onChange={this.onPhoneNumberChanged}
|
type="text"
|
||||||
placeholder="Mobile phone number"
|
name="phoneNumber"
|
||||||
value={this.state.phoneNumber}
|
onChange={this.onPhoneNumberChanged}
|
||||||
autoFocus
|
placeholder="Mobile phone number"
|
||||||
/>
|
value={this.state.phoneNumber}
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,8 @@ module.exports = React.createClass({
|
|||||||
|
|
||||||
_onPhoneCountryChange(newVal) {
|
_onPhoneCountryChange(newVal) {
|
||||||
this.setState({
|
this.setState({
|
||||||
phoneCountry: newVal,
|
phoneCountry: newVal.iso2,
|
||||||
|
phonePrefix: newVal.prefix,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -316,15 +317,22 @@ module.exports = React.createClass({
|
|||||||
className="mx_Login_phoneCountry"
|
className="mx_Login_phoneCountry"
|
||||||
value={this.state.phoneCountry}
|
value={this.state.phoneCountry}
|
||||||
/>
|
/>
|
||||||
<input type="text" ref="phoneNumber"
|
|
||||||
placeholder="Mobile phone number (optional)"
|
<div className="mx_Login_field_group">
|
||||||
defaultValue={this.props.defaultPhoneNumber}
|
<div className="mx_Login_field_prefix">+{this.state.phonePrefix}</div>
|
||||||
className={this._classForField(
|
<input type="text" ref="phoneNumber"
|
||||||
FIELD_PHONE_NUMBER, 'mx_Login_phoneNumberField', 'mx_Login_field'
|
placeholder="Mobile phone number (optional)"
|
||||||
)}
|
defaultValue={this.props.defaultPhoneNumber}
|
||||||
onBlur={function() {self.validateField(FIELD_PHONE_NUMBER);}}
|
className={this._classForField(
|
||||||
value={self.state.phoneNumber}
|
FIELD_PHONE_NUMBER,
|
||||||
/>
|
'mx_Login_phoneNumberField',
|
||||||
|
'mx_Login_field',
|
||||||
|
'mx_Login_field_has_prefix'
|
||||||
|
)}
|
||||||
|
onBlur={function() {self.validateField(FIELD_PHONE_NUMBER);}}
|
||||||
|
value={self.state.phoneNumber}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ export default WithMatrixClient(React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onPhoneCountryChange: function(phoneCountry) {
|
_onPhoneCountryChange: function(phoneCountry) {
|
||||||
this.setState({ phoneCountry: phoneCountry });
|
this.setState({ phoneCountry: phoneCountry.iso2 });
|
||||||
},
|
},
|
||||||
|
|
||||||
_onPhoneNumberChange: function(ev) {
|
_onPhoneNumberChange: function(ev) {
|
||||||
@ -149,10 +149,11 @@ export default WithMatrixClient(React.createClass({
|
|||||||
<div className="mx_UserSettings_profileLabelCell">
|
<div className="mx_UserSettings_profileLabelCell">
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_UserSettings_profileInputCell">
|
<div className="mx_UserSettings_profileInputCell">
|
||||||
<div className="mx_Login_phoneSection">
|
<div className="mx_UserSettings_phoneSection">
|
||||||
<CountryDropdown onOptionChange={this._onPhoneCountryChange}
|
<CountryDropdown onOptionChange={this._onPhoneCountryChange}
|
||||||
className="mx_Login_phoneCountry"
|
className="mx_UserSettings_phoneCountry"
|
||||||
value={this.state.phoneCountry}
|
value={this.state.phoneCountry}
|
||||||
|
isSmall={true}
|
||||||
/>
|
/>
|
||||||
<input type="text"
|
<input type="text"
|
||||||
ref={this._collectAddMsisdnInput}
|
ref={this._collectAddMsisdnInput}
|
||||||
|
Loading…
Reference in New Issue
Block a user