1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-14 06:11:16 +00:00

a11y] user settings: added support for 'keyboard access'

This commit is contained in:
llj
2021-09-30 17:22:59 +08:00
parent 1a4292d977
commit 62ec844ce9
6 changed files with 31 additions and 15 deletions

View File

@@ -35,7 +35,7 @@ class DeleteAccount extends React.Component {
<div className="setting-item" id="del-account"> <div className="setting-item" id="del-account">
<h3 className="setting-item-heading">{gettext('Delete Account')}</h3> <h3 className="setting-item-heading">{gettext('Delete Account')}</h3>
<p className="mb-2">{gettext('This operation will not be reverted. Please think twice!')}</p> <p className="mb-2">{gettext('This operation will not be reverted. Please think twice!')}</p>
<button className="btn btn-outline-primary" onClick={this.confirmDelete}>{gettext('Delete')}</button> <button type="button" className="btn btn-outline-primary" onClick={this.confirmDelete}>{gettext('Delete')}</button>
</div> </div>
{this.state.isConfirmDialogOpen && ( {this.state.isConfirmDialogOpen && (
<ModalPortal> <ModalPortal>

View File

@@ -19,8 +19,7 @@ class SocialLoginDintalk extends React.Component {
}; };
} }
confirmDisconnect = (e) => { confirmDisconnect = () => {
e.preventDefault();
this.setState({ this.setState({
isConfirmDialogOpen: true isConfirmDialogOpen: true
}); });
@@ -39,7 +38,7 @@ class SocialLoginDintalk extends React.Component {
<h3 className="setting-item-heading">{gettext('Social Login')}</h3> <h3 className="setting-item-heading">{gettext('Social Login')}</h3>
<p className="mb-2">{langCode == 'zh-cn' ? '钉钉': 'Dingtalk'}</p> <p className="mb-2">{langCode == 'zh-cn' ? '钉钉': 'Dingtalk'}</p>
{socialConnectedDingtalk ? {socialConnectedDingtalk ?
<a href="#" className="btn btn-outline-primary" onClick={this.confirmDisconnect}>{gettext('Disconnect')}</a> : <button className="btn btn-outline-primary" onClick={this.confirmDisconnect}>{gettext('Disconnect')}</button> :
<a href={`${siteRoot}dingtalk/connect/?next=${encodeURIComponent(socialNextPage)}`} className="btn btn-outline-primary">{gettext('Connect')}</a> <a href={`${siteRoot}dingtalk/connect/?next=${encodeURIComponent(socialNextPage)}`} className="btn btn-outline-primary">{gettext('Connect')}</a>
} }
</div> </div>

View File

@@ -19,8 +19,7 @@ class SocialLogin extends React.Component {
}; };
} }
confirmDisconnect = (e) => { confirmDisconnect = () => {
e.preventDefault();
this.setState({ this.setState({
isConfirmDialogOpen: true isConfirmDialogOpen: true
}); });
@@ -39,7 +38,7 @@ class SocialLogin extends React.Component {
<h3 className="setting-item-heading">{gettext('Social Login')}</h3> <h3 className="setting-item-heading">{gettext('Social Login')}</h3>
<p className="mb-2">{langCode == 'zh-cn' ? '企业微信': 'WeChat Work'}</p> <p className="mb-2">{langCode == 'zh-cn' ? '企业微信': 'WeChat Work'}</p>
{socialConnected ? {socialConnected ?
<a href="#" className="btn btn-outline-primary" onClick={this.confirmDisconnect}>{gettext('Disconnect')}</a> : <button className="btn btn-outline-primary" onClick={this.confirmDisconnect}>{gettext('Disconnect')}</button> :
<a href={`${siteRoot}work-weixin/oauth-connect/?next=${encodeURIComponent(socialNextPage)}`} className="btn btn-outline-primary">{gettext('Connect')}</a> <a href={`${siteRoot}work-weixin/oauth-connect/?next=${encodeURIComponent(socialNextPage)}`} className="btn btn-outline-primary">{gettext('Connect')}</a>
} }
</div> </div>

View File

@@ -80,15 +80,21 @@ class UserAvatarForm extends React.Component {
}); });
} }
onEditIconKeyDown = (e) => {
if (e.key == 'Enter' || e.key == 'Space') {
e.target.click();
}
}
render() { render() {
return ( return (
<form ref={this.form} className="form-group row" encType="multipart/form-data" method="post" action={`${siteRoot}avatar/add/`}> <form ref={this.form} className="form-group row" encType="multipart/form-data" method="post" action={`${siteRoot}avatar/add/`}>
<input type="hidden" name="csrfmiddlewaretoken" value={csrfToken} /> <input type="hidden" name="csrfmiddlewaretoken" value={csrfToken} />
<label className="col-sm-1 col-form-label">{gettext('Avatar:')}</label> <label className="col-sm-1 col-form-label">{gettext('Avatar:')}</label>
<div className="col-auto position-relative" onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut}> <div className="col-auto position-relative" onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut} onFocus={this.handleMouseOver} tabIndex="0">
<img src={this.state.avatarSrc} width="80" height="80" alt="" className="user-avatar" /> <img src={this.state.avatarSrc} width="80" height="80" alt="" className="user-avatar" />
<input type="file" name="avatar" className="d-none" onChange={this.fileInputChange} ref={this.fileInput} /> <input type="file" name="avatar" className="d-none" onChange={this.fileInputChange} ref={this.fileInput} />
<span className={`avatar-edit fas fa-edit ${!this.state.isEditShown && 'd-none'}`} onClick={this.openFileInput}></span> <span className={`avatar-edit fas fa-edit ${!this.state.isEditShown && 'd-none'}`} onClick={this.openFileInput} role="button" aria-label={gettext('Edit')} tabIndex="0" onKeyDown={this.onEditIconKeyDown}></span>
</div> </div>
</form> </form>
); );

View File

@@ -62,6 +62,12 @@ class WebAPIAuthToken extends React.Component {
}); });
} }
onIconKeyDown = (e) => {
if (e.key == 'Enter' || e.key == 'Space') {
e.target.click();
}
}
render() { render() {
const { authToken, isAuthTokenVisible } = this.state; const { authToken, isAuthTokenVisible } = this.state;
return ( return (
@@ -71,9 +77,9 @@ class WebAPIAuthToken extends React.Component {
{authToken ? ( {authToken ? (
<React.Fragment> <React.Fragment>
<div className="d-flex align-items-center"> <div className="d-flex align-items-center">
<label className="m-0 mr-2">{gettext('Token:')}</label> <label className="m-0 mr-2" htmlFor="token">{gettext('Token:')}</label>
<input className="border-0 mr-1" type="text" value={isAuthTokenVisible ? authToken : '****************************************'} readOnly={true} size={Math.max(authToken.length, 10)} /> <input id="token" className="border-0 mr-1" type="text" value={isAuthTokenVisible ? authToken : '****************************************'} readOnly={true} size={Math.max(authToken.length, 10)} />
<span onClick={this.toggleAuthTokenVisible} className={`eye-icon fas ${this.state.isAuthTokenVisible ? 'fa-eye': 'fa-eye-slash'}`}></span> <span tabIndex="0" role="button" aria-label={isAuthTokenVisible ? gettext('Hide') : gettext('Show')} onKeyDown={this.onIconKeyDown} onClick={this.toggleAuthTokenVisible} className={`eye-icon fas ${this.state.isAuthTokenVisible ? 'fa-eye': 'fa-eye-slash'}`}></span>
</div> </div>
<button className="btn btn-outline-primary mt-2" onClick={this.deleteAuthToken}>{gettext('Delete')}</button> <button className="btn btn-outline-primary mt-2" onClick={this.deleteAuthToken}>{gettext('Delete')}</button>
</React.Fragment> </React.Fragment>

View File

@@ -45,6 +45,12 @@ class WebdavPassword extends React.Component {
}); });
} }
onIconKeyDown = (e) => {
if (e.key == 'Enter' || e.key == 'Space') {
e.target.click();
}
}
render() { render() {
const { password, isPasswordVisible } = this.state; const { password, isPasswordVisible } = this.state;
return ( return (
@@ -54,9 +60,9 @@ class WebdavPassword extends React.Component {
{password ? ( {password ? (
<React.Fragment> <React.Fragment>
<div className="d-flex align-items-center"> <div className="d-flex align-items-center">
<label className="m-0 mr-2">{gettext('Password:')}</label> <label className="m-0 mr-2" htmlFor="passwd">{gettext('Password:')}</label>
<input className="border-0 mr-1" type="text" value={isPasswordVisible ? password : '**********'} readOnly={true} size={Math.max(password.length, 10)} /> <input id="passwd" className="border-0 mr-1" type="text" value={isPasswordVisible ? password : '**********'} readOnly={true} size={Math.max(password.length, 10)} />
<span onClick={this.togglePasswordVisible} className={`eye-icon fas ${this.state.isPasswordVisible ? 'fa-eye': 'fa-eye-slash'}`}></span> <span tabIndex="0" role="button" aria-label={isPasswordVisible? gettext('Hide') : gettext('Show')} onClick={this.togglePasswordVisible} onKeyDown={this.onIconKeyDown} className={`eye-icon fas ${this.state.isPasswordVisible ? 'fa-eye': 'fa-eye-slash'}`}></span>
</div> </div>
<button className="btn btn-outline-primary mt-2" onClick={this.toggleDialog}>{gettext('Update')}</button> <button className="btn btn-outline-primary mt-2" onClick={this.toggleDialog}>{gettext('Update')}</button>
</React.Fragment> </React.Fragment>