Вызов фокуса после окончания анимации

This commit is contained in:
SleepWalker 2016-03-28 08:05:18 +03:00
parent 64d8388a73
commit 3d0f8aa9c0
9 changed files with 47 additions and 39 deletions

View File

@ -42,34 +42,11 @@ export default class BaseAuthBody extends Component {
};
}
/**
* Fixes some issues with scroll, when input beeing focused
*
* When an element is focused, by default browsers will scroll its parents to display
* focused item to user. This behavior may cause unexpected visual effects, when
* you animating apearing of an input (e.g. transform) and auto focusing it. In
* that case the browser will scroll the parent container so that input will be
* visible.
* This method will fix that issue by finding parent with overflow: hidden and
* reseting its scrollLeft value to 0.
*
* Usage:
* <input autoFocus onFocus={this.fixAutoFocus} />
*
* @param {Object} event
*/
fixAutoFocus = (event) => {
let el = event.target;
autoFocus() {
const fieldId = this.autoFocusField;
while (el.parentNode) {
el = el.parentNode;
if (getComputedStyle(el).overflow === 'hidden') {
el.scrollLeft = 0;
break;
}
}
};
fieldId && this.form[fieldId] && this.form[fieldId].focus();
}
serialize() {
return Object.keys(this.form).reduce((acc, key) => {

View File

@ -134,6 +134,8 @@ class PanelTransition extends Component {
height: forceHeight ? common.style.switchContextHeightSpring : 'auto'
};
this.tryToAutoFocus(panels.length);
const bodyHeight = {
position: 'relative',
height: `${canAnimateHeight ? common.style.heightSpring : formHeight}px`
@ -253,6 +255,26 @@ class PanelTransition extends Component {
authFlow.goBack();
};
/**
* Tries to auto focus form fields after transition end
*
* @param {number} length number of panels transitioned
*/
tryToAutoFocus(length) {
if (!this.body) {
return;
}
if (length === 1) {
if (!this.wasAutoFocused) {
this.body.autoFocus();
}
this.wasAutoFocused = true;
} else if (this.wasAutoFocused) {
this.wasAutoFocused = false;
}
}
getHeader({key, style, data}) {
const {Title, hasBackButton} = data;
const {transformSpring} = style;

View File

@ -14,6 +14,8 @@ class Body extends BaseAuthBody {
static displayName = 'ActivationBody';
static panelId = 'activation';
autoFocusField = 'key';
render() {
return (
<div>
@ -32,8 +34,6 @@ class Body extends BaseAuthBody {
<Input {...this.bindField('key')}
color="blue"
className={styles.activationCodeInput}
autoFocus
onFocus={this.fixAutoFocus}
required
placeholder={messages.enterTheCode}
/>

View File

@ -15,6 +15,8 @@ class Body extends BaseAuthBody {
static displayName = 'ChangePasswordBody';
static panelId = 'changePassword';
autoFocusField = 'password';
render() {
return (
<div>
@ -32,8 +34,6 @@ class Body extends BaseAuthBody {
icon="key"
color="darkBlue"
type="password"
autoFocus
onFocus={this.fixAutoFocus}
required
placeholder={messages.currentPassword}
/>

View File

@ -16,6 +16,8 @@ class Body extends BaseAuthBody {
static panelId = 'forgotPassword';
static hasGoBack = true;
autoFocusField = 'email';
// Если юзер вводил своё мыло во время попытки авторизации, то почему бы его сюда автоматически не подставить?
render() {
return (
@ -29,8 +31,6 @@ class Body extends BaseAuthBody {
<Input {...this.bindField('email')}
icon="envelope"
color="lightViolet"
autoFocus
onFocus={this.fixAutoFocus}
required
placeholder={messages.accountEmail}
/>

View File

@ -15,6 +15,8 @@ class Body extends BaseAuthBody {
static displayName = 'LoginBody';
static panelId = 'login';
autoFocusField = 'login';
render() {
return (
<div>
@ -22,8 +24,6 @@ class Body extends BaseAuthBody {
<Input {...this.bindField('login')}
icon="envelope"
autoFocus
onFocus={this.fixAutoFocus}
required
placeholder={messages.emailOrUsername}
/>

View File

@ -17,6 +17,8 @@ class Body extends BaseAuthBody {
static panelId = 'password';
static hasGoBack = true;
autoFocusField = 'password';
render() {
const {user} = this.context;
@ -38,8 +40,6 @@ class Body extends BaseAuthBody {
<Input {...this.bindField('password')}
icon="key"
type="password"
autoFocus
onFocus={this.fixAutoFocus}
required
placeholder={messages.accountPassword}
/>

View File

@ -16,6 +16,8 @@ class Body extends BaseAuthBody {
static displayName = 'RegisterBody';
static panelId = 'register';
autoFocusField = 'username';
render() {
return (
<div>
@ -25,8 +27,6 @@ class Body extends BaseAuthBody {
icon="user"
color="blue"
type="text"
autoFocus
onFocus={this.fixAutoFocus}
required
placeholder={messages.yourNickname}
/>

View File

@ -56,6 +56,11 @@ export class Input extends Component {
getValue() {
return this.el.value;
}
focus() {
this.el.focus();
setTimeout(this.el.focus.bind(this.el), 10);
}
}
export class Checkbox extends Component {
@ -86,6 +91,10 @@ export class Checkbox extends Component {
getValue() {
return this.el.checked ? 1 : 0;
}
focus() {
this.el.focus();
}
}
export class Form extends Component {