mirror of
https://github.com/element-hq/element-web.git
synced 2024-12-15 20:41:30 +03:00
Applied aria-describedby to all other dialogs that are using BaseDialog.
Also added initial focus where it has not been set.
This commit is contained in:
parent
4f83f6cf25
commit
a31af39ca8
9 changed files with 57 additions and 36 deletions
|
@ -127,7 +127,7 @@ export default class ChatCreateOrReuseDialog extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
<div className={labelClasses}><i>{ _t("Start new chat") }</i></div>
|
<div className={labelClasses}><i>{ _t("Start new chat") }</i></div>
|
||||||
</AccessibleButton>;
|
</AccessibleButton>;
|
||||||
content = <div className="mx_Dialog_content">
|
content = <div className="mx_Dialog_content" id='mx_Dialog_content'>
|
||||||
{ _t('You already have existing direct chats with this user:') }
|
{ _t('You already have existing direct chats with this user:') }
|
||||||
<div className="mx_ChatCreateOrReuseDialog_tiles">
|
<div className="mx_ChatCreateOrReuseDialog_tiles">
|
||||||
{ this.state.tiles }
|
{ this.state.tiles }
|
||||||
|
@ -144,7 +144,7 @@ export default class ChatCreateOrReuseDialog extends React.Component {
|
||||||
if (this.state.busyProfile) {
|
if (this.state.busyProfile) {
|
||||||
profile = <Spinner />;
|
profile = <Spinner />;
|
||||||
} else if (this.state.profileError) {
|
} else if (this.state.profileError) {
|
||||||
profile = <div className="error">
|
profile = <div className="error" role="alert">
|
||||||
Unable to load profile information for { this.props.userId }
|
Unable to load profile information for { this.props.userId }
|
||||||
</div>;
|
</div>;
|
||||||
} else {
|
} else {
|
||||||
|
@ -160,14 +160,14 @@ export default class ChatCreateOrReuseDialog extends React.Component {
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
content = <div>
|
content = <div>
|
||||||
<div className="mx_Dialog_content">
|
<div className="mx_Dialog_content" id='mx_Dialog_content'>
|
||||||
<p>
|
<p>
|
||||||
{ _t('Click on the button below to start chatting!') }
|
{ _t('Click on the button below to start chatting!') }
|
||||||
</p>
|
</p>
|
||||||
{ profile }
|
{ profile }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
<button className="mx_Dialog_primary" onClick={this.props.onNewDMClick}>
|
<button className="mx_Dialog_primary" onClick={this.props.onNewDMClick} autoFocus="true">
|
||||||
{ _t('Start Chatting') }
|
{ _t('Start Chatting') }
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -179,6 +179,7 @@ export default class ChatCreateOrReuseDialog extends React.Component {
|
||||||
<BaseDialog className='mx_ChatCreateOrReuseDialog'
|
<BaseDialog className='mx_ChatCreateOrReuseDialog'
|
||||||
onFinished={this.props.onFinished.bind(false)}
|
onFinished={this.props.onFinished.bind(false)}
|
||||||
title={title}
|
title={title}
|
||||||
|
contentId='mx_Dialog_content'
|
||||||
>
|
>
|
||||||
{ content }
|
{ content }
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
|
@ -186,7 +187,7 @@ export default class ChatCreateOrReuseDialog extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatCreateOrReuseDialog.propTyps = {
|
ChatCreateOrReuseDialog.propTypes = {
|
||||||
userId: React.PropTypes.string.isRequired,
|
userId: React.PropTypes.string.isRequired,
|
||||||
// Called when clicking outside of the dialog
|
// Called when clicking outside of the dialog
|
||||||
onFinished: React.PropTypes.func.isRequired,
|
onFinished: React.PropTypes.func.isRequired,
|
||||||
|
|
|
@ -51,22 +51,18 @@ export default React.createClass({
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function() {
|
|
||||||
if (this.props.focus) {
|
|
||||||
this.refs.button.focus();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||||
return (
|
return (
|
||||||
<BaseDialog className="mx_ErrorDialog" onFinished={this.props.onFinished}
|
<BaseDialog className="mx_ErrorDialog" onFinished={this.props.onFinished}
|
||||||
title={this.props.title || _t('Error')}>
|
title={this.props.title || _t('Error')}
|
||||||
<div className="mx_Dialog_content">
|
contentId='mx_Dialog_content'
|
||||||
|
>
|
||||||
|
<div className="mx_Dialog_content" id='mx_Dialog_content'>
|
||||||
{ this.props.description || _t('An error has occurred.') }
|
{ this.props.description || _t('An error has occurred.') }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
<button ref="button" className="mx_Dialog_primary" onClick={this.props.onFinished}>
|
<button className="mx_Dialog_primary" onClick={this.props.onFinished} autoFocus={this.props.focus}>
|
||||||
{ this.props.button || _t('OK') }
|
{ this.props.button || _t('OK') }
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -72,11 +72,12 @@ export default React.createClass({
|
||||||
let content;
|
let content;
|
||||||
if (this.state.authError) {
|
if (this.state.authError) {
|
||||||
content = (
|
content = (
|
||||||
<div>
|
<div id='mx_Dialog_content'>
|
||||||
<div>{ this.state.authError.message || this.state.authError.toString() }</div>
|
<div role={(this.state.authError.message || this.state.authError.toString()) ? "alert" : ""}>{ this.state.authError.message || this.state.authError.toString() }</div>
|
||||||
<br />
|
<br />
|
||||||
<AccessibleButton onClick={this._onDismissClick}
|
<AccessibleButton onClick={this._onDismissClick}
|
||||||
className="mx_UserSettings_button"
|
className="mx_UserSettings_button"
|
||||||
|
autoFocus="true"
|
||||||
>
|
>
|
||||||
{ _t("Dismiss") }
|
{ _t("Dismiss") }
|
||||||
</AccessibleButton>
|
</AccessibleButton>
|
||||||
|
@ -84,7 +85,7 @@ export default React.createClass({
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
content = (
|
content = (
|
||||||
<div>
|
<div id='mx_Dialog_content'>
|
||||||
<InteractiveAuth ref={this._collectInteractiveAuth}
|
<InteractiveAuth ref={this._collectInteractiveAuth}
|
||||||
matrixClient={this.props.matrixClient}
|
matrixClient={this.props.matrixClient}
|
||||||
authData={this.props.authData}
|
authData={this.props.authData}
|
||||||
|
@ -99,6 +100,7 @@ export default React.createClass({
|
||||||
<BaseDialog className="mx_InteractiveAuthDialog"
|
<BaseDialog className="mx_InteractiveAuthDialog"
|
||||||
onFinished={this.props.onFinished}
|
onFinished={this.props.onFinished}
|
||||||
title={this.state.authError ? 'Error' : (this.props.title || _t('Authentication'))}
|
title={this.state.authError ? 'Error' : (this.props.title || _t('Authentication'))}
|
||||||
|
contentId='mx_Dialog_content'
|
||||||
>
|
>
|
||||||
{ content }
|
{ content }
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
|
|
|
@ -125,11 +125,11 @@ export default React.createClass({
|
||||||
text = _t(text, {displayName: displayName});
|
text = _t(text, {displayName: displayName});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div id='mx_Dialog_content'>
|
||||||
<p>{ text }</p>
|
<p>{ text }</p>
|
||||||
|
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
<button onClick={this._onVerifyClicked}>
|
<button onClick={this._onVerifyClicked} autoFocus="true">
|
||||||
{ _t('Start verification') }
|
{ _t('Start verification') }
|
||||||
</button>
|
</button>
|
||||||
<button onClick={this._onShareClicked}>
|
<button onClick={this._onShareClicked}>
|
||||||
|
@ -153,7 +153,7 @@ export default React.createClass({
|
||||||
content = this._renderContent();
|
content = this._renderContent();
|
||||||
} else {
|
} else {
|
||||||
content = (
|
content = (
|
||||||
<div>
|
<div id='mx_Dialog_content'>
|
||||||
<p>{ _t('Loading device info...') }</p>
|
<p>{ _t('Loading device info...') }</p>
|
||||||
<Spinner />
|
<Spinner />
|
||||||
</div>
|
</div>
|
||||||
|
@ -164,6 +164,7 @@ export default React.createClass({
|
||||||
<BaseDialog className='mx_KeyShareRequestDialog'
|
<BaseDialog className='mx_KeyShareRequestDialog'
|
||||||
onFinished={this.props.onFinished}
|
onFinished={this.props.onFinished}
|
||||||
title={_t('Encryption key request')}
|
title={_t('Encryption key request')}
|
||||||
|
contentId='mx_Dialog_content'
|
||||||
>
|
>
|
||||||
{ content }
|
{ content }
|
||||||
</BaseDialog>
|
</BaseDialog>
|
||||||
|
|
|
@ -29,6 +29,12 @@ export default React.createClass({
|
||||||
onFinished: React.PropTypes.func.isRequired,
|
onFinished: React.PropTypes.func.isRequired,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
componentDidMount: function() {
|
||||||
|
if (this.refs.bugreportLink) {
|
||||||
|
this.refs.bugreportLink.focus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_sendBugReport: function() {
|
_sendBugReport: function() {
|
||||||
const BugReportDialog = sdk.getComponent("dialogs.BugReportDialog");
|
const BugReportDialog = sdk.getComponent("dialogs.BugReportDialog");
|
||||||
Modal.createTrackedDialog('Session Restore Error', 'Send Bug Report Dialog', BugReportDialog, {});
|
Modal.createTrackedDialog('Session Restore Error', 'Send Bug Report Dialog', BugReportDialog, {});
|
||||||
|
@ -48,7 +54,7 @@ export default React.createClass({
|
||||||
{ _t(
|
{ _t(
|
||||||
"Otherwise, <a>click here</a> to send a bug report.",
|
"Otherwise, <a>click here</a> to send a bug report.",
|
||||||
{},
|
{},
|
||||||
{ 'a': (sub) => <a onClick={this._sendBugReport} key="bugreport" href='#'>{ sub }</a> },
|
{ 'a': (sub) => <a ref="bugreportLink" onClick={this._sendBugReport} key="bugreport" href='#'>{ sub }</a> },
|
||||||
) }
|
) }
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
|
@ -56,8 +62,10 @@ export default React.createClass({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BaseDialog className="mx_ErrorDialog" onFinished={this.props.onFinished}
|
<BaseDialog className="mx_ErrorDialog" onFinished={this.props.onFinished}
|
||||||
title={_t('Unable to restore session')}>
|
title={_t('Unable to restore session')}
|
||||||
<div className="mx_Dialog_content">
|
contentId='mx_Dialog_content'
|
||||||
|
>
|
||||||
|
<div className="mx_Dialog_content" id='mx_Dialog_content'>
|
||||||
<p>{ _t("We encountered an error trying to restore your previous session. If " +
|
<p>{ _t("We encountered an error trying to restore your previous session. If " +
|
||||||
"you continue, you will need to log in again, and encrypted chat " +
|
"you continue, you will need to log in again, and encrypted chat " +
|
||||||
"history will be unreadable.") }</p>
|
"history will be unreadable.") }</p>
|
||||||
|
@ -68,7 +76,7 @@ export default React.createClass({
|
||||||
|
|
||||||
{ bugreport }
|
{ bugreport }
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons" autoFocus={SdkConfig.get().bug_report_endpoint_url ? false : true}>
|
||||||
<button className="mx_Dialog_primary" onClick={this._continueClicked}>
|
<button className="mx_Dialog_primary" onClick={this._continueClicked}>
|
||||||
{ _t("Continue anyway") }
|
{ _t("Continue anyway") }
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -41,6 +41,7 @@ export default React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
|
this.refs.emailInputField.focus();
|
||||||
},
|
},
|
||||||
|
|
||||||
onEmailAddressChanged: function(value) {
|
onEmailAddressChanged: function(value) {
|
||||||
|
@ -130,6 +131,7 @@ export default React.createClass({
|
||||||
|
|
||||||
const emailInput = this.state.emailBusy ? <Spinner /> : <EditableText
|
const emailInput = this.state.emailBusy ? <Spinner /> : <EditableText
|
||||||
className="mx_SetEmailDialog_email_input"
|
className="mx_SetEmailDialog_email_input"
|
||||||
|
ref="emailInputField"
|
||||||
placeholder={_t("Email address")}
|
placeholder={_t("Email address")}
|
||||||
placeholderClassName="mx_SetEmailDialog_email_input_placeholder"
|
placeholderClassName="mx_SetEmailDialog_email_input_placeholder"
|
||||||
blurToCancel={false}
|
blurToCancel={false}
|
||||||
|
@ -139,9 +141,10 @@ export default React.createClass({
|
||||||
<BaseDialog className="mx_SetEmailDialog"
|
<BaseDialog className="mx_SetEmailDialog"
|
||||||
onFinished={this.onCancelled}
|
onFinished={this.onCancelled}
|
||||||
title={this.props.title}
|
title={this.props.title}
|
||||||
|
contentId='mx_Dialog_content'
|
||||||
>
|
>
|
||||||
<div className="mx_Dialog_content">
|
<div className="mx_Dialog_content">
|
||||||
<p>
|
<p id='mx_Dialog_content'>
|
||||||
{ _t('This will allow you to reset your password and receive notifications.') }
|
{ _t('This will allow you to reset your password and receive notifications.') }
|
||||||
</p>
|
</p>
|
||||||
{ emailInput }
|
{ emailInput }
|
||||||
|
|
|
@ -234,14 +234,14 @@ export default React.createClass({
|
||||||
"error": Boolean(this.state.usernameError),
|
"error": Boolean(this.state.usernameError),
|
||||||
"success": usernameAvailable,
|
"success": usernameAvailable,
|
||||||
});
|
});
|
||||||
usernameIndicator = <div className={usernameIndicatorClasses}>
|
usernameIndicator = <div className={usernameIndicatorClasses} role="alert">
|
||||||
{ usernameAvailable ? _t('Username available') : this.state.usernameError }
|
{ usernameAvailable ? _t('Username available') : this.state.usernameError }
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
let authErrorIndicator = null;
|
let authErrorIndicator = null;
|
||||||
if (this.state.authError) {
|
if (this.state.authError) {
|
||||||
authErrorIndicator = <div className="error">
|
authErrorIndicator = <div className="error" role="alert">
|
||||||
{ this.state.authError }
|
{ this.state.authError }
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
|
@ -253,8 +253,9 @@ export default React.createClass({
|
||||||
<BaseDialog className="mx_SetMxIdDialog"
|
<BaseDialog className="mx_SetMxIdDialog"
|
||||||
onFinished={this.props.onFinished}
|
onFinished={this.props.onFinished}
|
||||||
title={_t('To get started, please pick a username!')}
|
title={_t('To get started, please pick a username!')}
|
||||||
|
contentId='mx_Dialog_content'
|
||||||
>
|
>
|
||||||
<div className="mx_Dialog_content">
|
<div className="mx_Dialog_content" id='mx_Dialog_content'>
|
||||||
<div className="mx_SetMxIdDialog_input_group">
|
<div className="mx_SetMxIdDialog_input_group">
|
||||||
<input type="text" ref="input_value" value={this.state.username}
|
<input type="text" ref="input_value" value={this.state.username}
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
|
|
|
@ -143,8 +143,9 @@ export default React.createClass({
|
||||||
this.props.onFinished();
|
this.props.onFinished();
|
||||||
}}
|
}}
|
||||||
title={_t('Room contains unknown devices')}
|
title={_t('Room contains unknown devices')}
|
||||||
|
contentId='mx_Dialog_content'
|
||||||
>
|
>
|
||||||
<GeminiScrollbar autoshow={false} className="mx_Dialog_content">
|
<GeminiScrollbar autoshow={false} className="mx_Dialog_content" id='mx_Dialog_content'>
|
||||||
<h4>
|
<h4>
|
||||||
{ _t('"%(RoomName)s" contains devices that you haven\'t seen before.', {RoomName: this.props.room.name}) }
|
{ _t('"%(RoomName)s" contains devices that you haven\'t seen before.', {RoomName: this.props.room.name}) }
|
||||||
</h4>
|
</h4>
|
||||||
|
@ -161,7 +162,7 @@ export default React.createClass({
|
||||||
}}>
|
}}>
|
||||||
{ _t("Send anyway") }
|
{ _t("Send anyway") }
|
||||||
</button>
|
</button>
|
||||||
<button className="mx_Dialog_primary" autoFocus={true}
|
<button className="mx_Dialog_primary"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
// XXX: temporary logging to try to diagnose
|
// XXX: temporary logging to try to diagnose
|
||||||
// https://github.com/vector-im/riot-web/issues/3148
|
// https://github.com/vector-im/riot-web/issues/3148
|
||||||
|
|
|
@ -130,9 +130,10 @@ export const PasswordAuthEntry = React.createClass({
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p>{ _t("To continue, please enter your password.") }</p>
|
<p>{ _t("To continue, please enter your password.") }</p>
|
||||||
<p>{ _t("Password:") }</p>
|
|
||||||
<form onSubmit={this._onSubmit}>
|
<form onSubmit={this._onSubmit}>
|
||||||
|
<label htmlFor="passwordField">{ _t("Password:") }</label>
|
||||||
<input
|
<input
|
||||||
|
name="passwordField"
|
||||||
ref="passwordField"
|
ref="passwordField"
|
||||||
className={passwordBoxClass}
|
className={passwordBoxClass}
|
||||||
onChange={this._onPasswordFieldChange}
|
onChange={this._onPasswordFieldChange}
|
||||||
|
@ -142,7 +143,7 @@ export const PasswordAuthEntry = React.createClass({
|
||||||
{ submitButtonOrSpinner }
|
{ submitButtonOrSpinner }
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<div className="error">
|
<div className="error" role={ this.props.errorText ? "alert" : ""}>
|
||||||
{ this.props.errorText }
|
{ this.props.errorText }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -184,7 +185,7 @@ export const RecaptchaAuthEntry = React.createClass({
|
||||||
<CaptchaForm sitePublicKey={sitePublicKey}
|
<CaptchaForm sitePublicKey={sitePublicKey}
|
||||||
onCaptchaResponse={this._onCaptchaResponse}
|
onCaptchaResponse={this._onCaptchaResponse}
|
||||||
/>
|
/>
|
||||||
<div className="error">
|
<div className="error" role={ this.props.errorText ? "alert" : ""}>
|
||||||
{ this.props.errorText }
|
{ this.props.errorText }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -384,6 +385,7 @@ export const MsisdnAuthEntry = React.createClass({
|
||||||
className="mx_InteractiveAuthEntryComponents_msisdnEntry"
|
className="mx_InteractiveAuthEntryComponents_msisdnEntry"
|
||||||
value={this.state.token}
|
value={this.state.token}
|
||||||
onChange={this._onTokenChange}
|
onChange={this._onTokenChange}
|
||||||
|
aria-label={ _t("Code")}
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
<input type="submit" value={_t("Submit")}
|
<input type="submit" value={_t("Submit")}
|
||||||
|
@ -391,7 +393,7 @@ export const MsisdnAuthEntry = React.createClass({
|
||||||
disabled={!enableSubmit}
|
disabled={!enableSubmit}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
<div className="error">
|
<div className="error" role={this.state.errorText ? "alert" : ""}>
|
||||||
{ this.state.errorText }
|
{ this.state.errorText }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -426,6 +428,12 @@ export const FallbackAuthEntry = React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
focus: function() {
|
||||||
|
if (this.refs.fallbackButton) {
|
||||||
|
this.refs.fallbackButton.focus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_onShowFallbackClick: function() {
|
_onShowFallbackClick: function() {
|
||||||
const url = this.props.matrixClient.getFallbackAuthUrl(
|
const url = this.props.matrixClient.getFallbackAuthUrl(
|
||||||
this.props.loginType,
|
this.props.loginType,
|
||||||
|
@ -446,8 +454,8 @@ export const FallbackAuthEntry = React.createClass({
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<a onClick={this._onShowFallbackClick}>{ _t("Start authentication") }</a>
|
<a ref="fallbackButton" onClick={this._onShowFallbackClick}>{ _t("Start authentication") }</a>
|
||||||
<div className="error">
|
<div className="error" role={ this.props.errorText ? "alert" : ""}>
|
||||||
{ this.props.errorText }
|
{ this.props.errorText }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue