fix(searchbar): fix input bluring

fixes #14916
This commit is contained in:
Manu Mtz.-Almeida
2018-07-29 14:19:51 +02:00
parent a62759c3cc
commit d65174bcf3
2 changed files with 18 additions and 45 deletions

View File

@ -14,17 +14,15 @@ import { createColorClasses } from '../../utils/theme';
scoped: true
})
export class Searchbar {
private nativeInput!: HTMLInputElement;
private isCancelVisible = false;
private shouldBlur = true;
private shouldAlignLeft = true;
@Element() el!: HTMLElement;
@Prop({ context: 'document' }) doc!: Document;
@State() activated = false;
@State() focused = false;
/**
@ -158,9 +156,14 @@ export class Searchbar {
/**
* Clears the input field and triggers the control change.
*/
private clearInput() {
private clearInput(ev?: Event) {
this.ionClear.emit();
if (ev) {
ev.preventDefault();
ev.stopPropagation();
}
// setTimeout() fixes https://github.com/ionic-team/ionic/issues/7527
// wait for 4 frames
setTimeout(() => {
@ -170,7 +173,6 @@ export class Searchbar {
this.ionInput.emit();
}
}, 16 * 4);
this.shouldBlur = false;
}
/**
@ -180,10 +182,7 @@ export class Searchbar {
*/
private cancelSearchbar() {
this.ionCancel.emit();
this.clearInput();
this.shouldBlur = true;
this.activated = false;
}
/**
@ -197,36 +196,13 @@ export class Searchbar {
this.ionInput.emit(ev);
}
private inputUpdated() {
// const inputEl = (this.el.shadowRoot || this.el).querySelector('.searchbar-input') as HTMLInputElment;
// It is important not to re-assign the value if it is the same, because,
// otherwise, the caret is moved to the end of the input
// if (inputEl && inputEl.value !== this.value) {
// // inputEl.value = this.value;
// this.value = inputEl.value;
// }
this.positionElements();
}
/**
* Sets the Searchbar to not focused and checks if it should align left
* based on whether there is a value in the searchbar or not.
*/
private onBlur() {
const inputEl = (this.el.shadowRoot || this.el).querySelector('.searchbar-input') as HTMLInputElement;
// shouldBlur determines if it should blur
// if we are clearing the input we still want to stay focused in the input
if (this.shouldBlur === false) {
inputEl.focus();
this.shouldBlur = true;
this.ionBlur.emit();
this.inputUpdated();
return;
}
this.focused = false;
this.ionBlur.emit();
this.positionElements();
}
@ -234,12 +210,8 @@ export class Searchbar {
* Sets the Searchbar to focused and active on input focus.
*/
private onFocus() {
this.activated = true;
this.focused = true;
this.ionFocus.emit();
this.inputUpdated();
this.positionElements();
}
@ -270,7 +242,7 @@ export class Searchbar {
*/
private positionPlaceholder() {
const isRTL = this.doc.dir === 'rtl';
const inputEl = (this.el.shadowRoot || this.el).querySelector('.searchbar-input') as HTMLInputElement;
const inputEl = this.nativeInput;
const iconEl = (this.el.shadowRoot || this.el).querySelector('.searchbar-search-icon') as HTMLElement;
if (this.shouldAlignLeft) {
@ -339,7 +311,6 @@ export class Searchbar {
return {
class: {
...createColorClasses(this.color),
'searchbar-active': this.activated,
'searchbar-animated': this.animated,
'searchbar-has-value': (this.value !== ''),
'searchbar-show-cancel': this.showCancelButton,
@ -356,9 +327,8 @@ export class Searchbar {
const cancelButton = (this.showCancelButton)
? <button
type="button"
tabIndex={this.mode === 'ios' && !this.activated ? -1 : undefined}
tabIndex={this.mode === 'ios' && !this.focused ? -1 : undefined}
onClick={this.cancelSearchbar.bind(this)}
onMouseDown={this.cancelSearchbar.bind(this)}
class="searchbar-cancel-button">
{ this.mode === 'md'
? <ion-icon mode={this.mode} icon={this.cancelButtonIcon}></ion-icon>
@ -385,9 +355,11 @@ export class Searchbar {
<button
type="button"
no-blur={true}
class="searchbar-clear-button"
onClick={this.clearInput.bind(this)}
onMouseDown={this.clearInput.bind(this)}>
onMouseDown={this.clearInput.bind(this)}
onTouchStart={this.clearInput.bind(this)}>
<ion-icon mode={this.mode} icon={clearIcon} class="searchbar-clear-icon"></ion-icon>
</button>
</div>,

View File

@ -1,5 +1,5 @@
const SKIP_BLURRING = ['INPUT', 'TEXTAREA', 'ION-INPUT', 'ION-TEXTAREA'];
const SKIP_SELECTOR = 'input, textarea, [no-blur]';
export function enableInputBlurring(doc: Document) {
console.debug('Input: enableInputBlurring');
@ -25,17 +25,18 @@ export function enableInputBlurring(doc: Document) {
if (!active) {
return;
}
// only blur if the active element is a text-input or a textarea
if (SKIP_BLURRING.indexOf(active.tagName) === -1) {
if (active.matches(SKIP_SELECTOR)) {
return;
}
// if the selected target is the active element, do not blur
const tapped = ev.target;
const tapped = ev.target as HTMLElement;
if (tapped === active) {
return;
}
if (SKIP_BLURRING.indexOf(tapped.tagName) >= 0) {
if (tapped.matches(SKIP_SELECTOR) || tapped.closest(SKIP_SELECTOR)) {
return;
}