perf(searchbar): searchbar animation is disabled by default

it can be reenabled by`<ion-searchbar animated="true">`

fixes #6023
This commit is contained in:
Manu Mtz.-Almeida
2016-09-22 16:15:24 +02:00
parent 2e1bb4bbde
commit d03182e34e
5 changed files with 84 additions and 52 deletions

View File

@ -66,8 +66,6 @@ $searchbar-ios-toolbar-input-background: rgba(0, 0, 0, .08) !default;
background-repeat: no-repeat; background-repeat: no-repeat;
background-size: $searchbar-ios-input-search-icon-size; background-size: $searchbar-ios-input-search-icon-size;
transition: $searchbar-ios-input-transition;
} }
@ -87,8 +85,6 @@ $searchbar-ios-toolbar-input-background: rgba(0, 0, 0, .08) !default;
color: $searchbar-ios-input-text-color; color: $searchbar-ios-input-text-color;
background-color: $searchbar-ios-input-background-color; background-color: $searchbar-ios-input-background-color;
transition: $searchbar-ios-input-transition;
} }
@ -119,7 +115,6 @@ $searchbar-ios-toolbar-input-background: rgba(0, 0, 0, .08) !default;
flex-shrink: 0; flex-shrink: 0;
margin-right: -100%;
margin-left: 0; margin-left: 0;
padding: 0; padding: 0;
padding-left: 8px; padding-left: 8px;
@ -127,20 +122,8 @@ $searchbar-ios-toolbar-input-background: rgba(0, 0, 0, .08) !default;
height: 30px; height: 30px;
cursor: pointer; cursor: pointer;
opacity: 0;
transform: translate3d(0, 0, 0);
transition: $searchbar-ios-cancel-transition;
pointer-events: none;
} }
.searchbar-ios.searchbar-show-cancel .searchbar-ios-cancel {
display: block;
}
// Searchbar Left Aligned (iOS only) // Searchbar Left Aligned (iOS only)
// ----------------------------------------- // -----------------------------------------
@ -156,10 +139,8 @@ $searchbar-ios-toolbar-input-background: rgba(0, 0, 0, .08) !default;
// Searchbar Has Focus // Searchbar Has Focus
// ----------------------------------------- // -----------------------------------------
.searchbar-ios.searchbar-has-focus .searchbar-ios-cancel { .searchbar-ios.searchbar-show-cancel.searchbar-has-focus .searchbar-ios-cancel {
opacity: 1; display: block;
pointer-events: auto;
} }
@ -225,3 +206,29 @@ $searchbar-ios-toolbar-input-background: rgba(0, 0, 0, .08) !default;
} }
} }
// Searchbar animation
// -----------------------------------------
.searchbar-ios.searchbar-animated .searchbar-search-icon,
.searchbar-ios.searchbar-animated .searchbar-input {
transition: $searchbar-ios-input-transition;
}
.searchbar-animated.searchbar-has-focus .searchbar-ios-cancel {
opacity: 1;
pointer-events: auto;
}
.searchbar-animated .searchbar-ios-cancel {
display: block;
margin-right: -100%;
opacity: 0;
transform: translate3d(0, 0, 0);
transition: $searchbar-ios-cancel-transition;
pointer-events: none;
}

View File

@ -48,3 +48,4 @@ ion-searchbar {
.searchbar-has-value.searchbar-has-focus .searchbar-clear-icon { .searchbar-has-value.searchbar-has-focus .searchbar-clear-icon {
display: block; display: block;
} }

View File

@ -3,7 +3,7 @@ import { NgControl } from '@angular/forms';
import { Config } from '../../config/config'; import { Config } from '../../config/config';
import { Ion } from '../ion'; import { Ion } from '../ion';
import { isPresent } from '../../util/util'; import { isPresent, isTrueProperty } from '../../util/util';
import { Debouncer } from '../../util/debouncer'; import { Debouncer } from '../../util/debouncer';
@ -39,16 +39,19 @@ import { Debouncer } from '../../util/debouncer';
'</div>' + '</div>' +
'<button ion-button #cancelButton [tabindex]="_isActive ? 1 : -1" clear (click)="cancelSearchbar($event)" (mousedown)="cancelSearchbar($event)" class="searchbar-ios-cancel" type="button">{{cancelButtonText}}</button>', '<button ion-button #cancelButton [tabindex]="_isActive ? 1 : -1" clear (click)="cancelSearchbar($event)" (mousedown)="cancelSearchbar($event)" class="searchbar-ios-cancel" type="button">{{cancelButtonText}}</button>',
host: { host: {
'[class.searchbar-animated]': 'animated',
'[class.searchbar-has-value]': '_value', '[class.searchbar-has-value]': '_value',
'[class.searchbar-active]': '_isActive', '[class.searchbar-active]': '_isActive',
'[class.searchbar-show-cancel]': 'showCancelButton', '[class.searchbar-show-cancel]': 'showCancelButton',
'[class.searchbar-left-aligned]': 'shouldAlignLeft()' '[class.searchbar-left-aligned]': '_shouldAlignLeft'
}, },
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class Searchbar extends Ion { export class Searchbar extends Ion {
_value: string|number = ''; _value: string|number = '';
_shouldBlur: boolean = true; _shouldBlur: boolean = true;
_shouldAlignLeft: boolean = true;
_isCancelVisible: boolean = false;
_isActive: boolean = false; _isActive: boolean = false;
_searchbarInput: ElementRef; _searchbarInput: ElementRef;
_debouncer: Debouncer = new Debouncer(250); _debouncer: Debouncer = new Debouncer(250);
@ -115,6 +118,11 @@ export class Searchbar extends Ion {
*/ */
@Input() type: string = 'search'; @Input() type: string = 'search';
/**
* @input {string|boolean} Set the input's spellcheck property. Values: `true`, `false`. Default `false`.
*/
@Input() animated: string | boolean = false;
/** /**
* @output {event} When the Searchbar input has changed including cleared. * @output {event} When the Searchbar input has changed including cleared.
*/ */
@ -217,7 +225,7 @@ export class Searchbar extends Ion {
* @private * @private
* After View Checked position the elements * After View Checked position the elements
*/ */
ngAfterViewChecked() { ngAfterContentInit() {
this.positionElements(); this.positionElements();
} }
@ -227,26 +235,31 @@ export class Searchbar extends Ion {
* based on the input value and if it is focused. (ios only) * based on the input value and if it is focused. (ios only)
*/ */
positionElements() { positionElements() {
if (this._config.get('mode') !== 'ios') return; let isAnimated = isTrueProperty(this.animated);
let prevAlignLeft = this._shouldAlignLeft;
let shouldAlignLeft = (!isAnimated || (this._value && this._value.toString().trim() !== '') || this._sbHasFocus === true);
this._shouldAlignLeft = shouldAlignLeft;
// Position the input placeholder & search icon if (this._config.get('mode') !== 'ios') {
if (this._searchbarInput && this._searchbarIcon) { return;
this.positionInputPlaceholder(this._searchbarInput.nativeElement, this._searchbarIcon.nativeElement);
} }
// Position the cancel button if (prevAlignLeft !== shouldAlignLeft) {
if (this._cancelButton && this._cancelButton.nativeElement) { this.positionPlaceholder();
this.positionCancelButton(this._cancelButton.nativeElement); }
if (isAnimated) {
this.positionCancelButton();
} }
} }
/** positionPlaceholder() {
* @private if (!this._searchbarInput || !this._searchbarIcon) {
* Calculates the amount of padding/margin left for the elements return;
* in order to center them based on the placeholder width }
*/ let inputEle = this._searchbarInput.nativeElement;
positionInputPlaceholder(inputEle: HTMLElement, iconEle: HTMLElement) { let iconEle = this._searchbarIcon.nativeElement;
if (this.shouldAlignLeft()) {
if (this._shouldAlignLeft) {
inputEle.removeAttribute('style'); inputEle.removeAttribute('style');
iconEle.removeAttribute('style'); iconEle.removeAttribute('style');
} else { } else {
@ -273,23 +286,26 @@ export class Searchbar extends Ion {
* @private * @private
* Show the iOS Cancel button on focus, hide it offscreen otherwise * Show the iOS Cancel button on focus, hide it offscreen otherwise
*/ */
positionCancelButton(cancelButtonEle: HTMLElement) { positionCancelButton() {
if (cancelButtonEle.offsetWidth > 0) { if (!this._cancelButton || !this._cancelButton.nativeElement) {
if (this._sbHasFocus) { return;
cancelButtonEle.style.marginRight = '0'; }
let showShowCancel = this._sbHasFocus;
if (showShowCancel !== this._isCancelVisible) {
let cancelStyleEle = this._cancelButton.nativeElement;
let cancelStyle = cancelStyleEle.style;
this._isCancelVisible = showShowCancel;
if (showShowCancel) {
cancelStyle.marginRight = '0';
} else { } else {
cancelButtonEle.style.marginRight = -cancelButtonEle.offsetWidth + 'px'; let offset = cancelStyleEle.offsetWidth;
if (offset > 0) {
cancelStyle.marginRight = -offset + 'px';
}
} }
} }
} }
/**
* @private
* Align the input placeholder left on focus or if a value exists
*/
shouldAlignLeft() {
return ( (this._value && this._value.toString().trim() !== '') || this._sbHasFocus === true );
}
/** /**
* @private * @private
@ -399,4 +415,8 @@ export class Searchbar extends Ion {
registerOnTouched(fn: () => {}): void { registerOnTouched(fn: () => {}): void {
this.onTouched = fn; this.onTouched = fn;
} }
focus() {
this.getNativeElement().focus();
}
} }

View File

@ -2,6 +2,9 @@
<h5 padding-left> Search - Default </h5> <h5 padding-left> Search - Default </h5>
<ion-searchbar [(ngModel)]="defaultSearch" showCancelButton debounce="500" (ionInput)="triggerInput($event)" (ionBlur)="inputBlurred($event)" (ionFocus)="inputFocused($event)" (ionCancel)="onCancelSearchbar($event)" (ionClear)="onClearSearchbar($event)"></ion-searchbar> <ion-searchbar [(ngModel)]="defaultSearch" showCancelButton debounce="500" (ionInput)="triggerInput($event)" (ionBlur)="inputBlurred($event)" (ionFocus)="inputFocused($event)" (ionCancel)="onCancelSearchbar($event)" (ionClear)="onClearSearchbar($event)"></ion-searchbar>
<h5 padding-left> Search - Animated </h5>
<ion-searchbar animated="true" showCancelButton debounce="500" (ionInput)="triggerInput($event)" (ionBlur)="inputBlurred($event)" (ionFocus)="inputFocused($event)" (ionCancel)="onCancelSearchbar($event)" (ionClear)="onClearSearchbar($event)"></ion-searchbar>
<p padding-left> <p padding-left>
defaultSearch: <b>{{ defaultSearch }}</b> defaultSearch: <b>{{ defaultSearch }}</b>
</p> </p>

View File

@ -14,8 +14,9 @@
<ion-content> <ion-content>
<ion-searchbar (ionInput)="getItems($event)"></ion-searchbar> <form>
<ion-searchbar (ionInput)="getItems($event)"></ion-searchbar>
</form>
<ion-list> <ion-list>
<button ion-item *ngFor="let item of items" (click)="showDetail(item)" class="e2eSearchbarNavItem"> <button ion-item *ngFor="let item of items" (click)="showDetail(item)" class="e2eSearchbarNavItem">
{{ item }} {{ item }}