Skip to content

Commit d03182e

Browse files
committed
perf(searchbar): searchbar animation is disabled by default
it can be reenabled by`<ion-searchbar animated="true">` fixes #6023
1 parent 2e1bb4b commit d03182e

File tree

5 files changed

+84
-52
lines changed

5 files changed

+84
-52
lines changed

src/components/searchbar/searchbar.ios.scss

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@ $searchbar-ios-toolbar-input-background: rgba(0, 0, 0, .08) !default;
6666

6767
background-repeat: no-repeat;
6868
background-size: $searchbar-ios-input-search-icon-size;
69-
70-
transition: $searchbar-ios-input-transition;
7169
}
7270

7371

@@ -87,8 +85,6 @@ $searchbar-ios-toolbar-input-background: rgba(0, 0, 0, .08) !default;
8785

8886
color: $searchbar-ios-input-text-color;
8987
background-color: $searchbar-ios-input-background-color;
90-
91-
transition: $searchbar-ios-input-transition;
9288
}
9389

9490

@@ -119,28 +115,15 @@ $searchbar-ios-toolbar-input-background: rgba(0, 0, 0, .08) !default;
119115

120116
flex-shrink: 0;
121117

122-
margin-right: -100%;
123118
margin-left: 0;
124119
padding: 0;
125120
padding-left: 8px;
126121

127122
height: 30px;
128123

129124
cursor: pointer;
130-
131-
opacity: 0;
132-
133-
transform: translate3d(0, 0, 0);
134-
transition: $searchbar-ios-cancel-transition;
135-
136-
pointer-events: none;
137125
}
138126

139-
.searchbar-ios.searchbar-show-cancel .searchbar-ios-cancel {
140-
display: block;
141-
}
142-
143-
144127
// Searchbar Left Aligned (iOS only)
145128
// -----------------------------------------
146129

@@ -156,10 +139,8 @@ $searchbar-ios-toolbar-input-background: rgba(0, 0, 0, .08) !default;
156139
// Searchbar Has Focus
157140
// -----------------------------------------
158141

159-
.searchbar-ios.searchbar-has-focus .searchbar-ios-cancel {
160-
opacity: 1;
161-
162-
pointer-events: auto;
142+
.searchbar-ios.searchbar-show-cancel.searchbar-has-focus .searchbar-ios-cancel {
143+
display: block;
163144
}
164145

165146

@@ -225,3 +206,29 @@ $searchbar-ios-toolbar-input-background: rgba(0, 0, 0, .08) !default;
225206
}
226207

227208
}
209+
210+
// Searchbar animation
211+
// -----------------------------------------
212+
213+
.searchbar-ios.searchbar-animated .searchbar-search-icon,
214+
.searchbar-ios.searchbar-animated .searchbar-input {
215+
transition: $searchbar-ios-input-transition;
216+
}
217+
218+
.searchbar-animated.searchbar-has-focus .searchbar-ios-cancel {
219+
opacity: 1;
220+
221+
pointer-events: auto;
222+
}
223+
224+
.searchbar-animated .searchbar-ios-cancel {
225+
display: block;
226+
227+
margin-right: -100%;
228+
229+
opacity: 0;
230+
transform: translate3d(0, 0, 0);
231+
transition: $searchbar-ios-cancel-transition;
232+
233+
pointer-events: none;
234+
}

src/components/searchbar/searchbar.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,4 @@ ion-searchbar {
4848
.searchbar-has-value.searchbar-has-focus .searchbar-clear-icon {
4949
display: block;
5050
}
51+

src/components/searchbar/searchbar.ts

Lines changed: 49 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { NgControl } from '@angular/forms';
33

44
import { Config } from '../../config/config';
55
import { Ion } from '../ion';
6-
import { isPresent } from '../../util/util';
6+
import { isPresent, isTrueProperty } from '../../util/util';
77
import { Debouncer } from '../../util/debouncer';
88

99

@@ -39,16 +39,19 @@ import { Debouncer } from '../../util/debouncer';
3939
'</div>' +
4040
'<button ion-button #cancelButton [tabindex]="_isActive ? 1 : -1" clear (click)="cancelSearchbar($event)" (mousedown)="cancelSearchbar($event)" class="searchbar-ios-cancel" type="button">{{cancelButtonText}}</button>',
4141
host: {
42+
'[class.searchbar-animated]': 'animated',
4243
'[class.searchbar-has-value]': '_value',
4344
'[class.searchbar-active]': '_isActive',
4445
'[class.searchbar-show-cancel]': 'showCancelButton',
45-
'[class.searchbar-left-aligned]': 'shouldAlignLeft()'
46+
'[class.searchbar-left-aligned]': '_shouldAlignLeft'
4647
},
4748
encapsulation: ViewEncapsulation.None
4849
})
4950
export class Searchbar extends Ion {
5051
_value: string|number = '';
5152
_shouldBlur: boolean = true;
53+
_shouldAlignLeft: boolean = true;
54+
_isCancelVisible: boolean = false;
5255
_isActive: boolean = false;
5356
_searchbarInput: ElementRef;
5457
_debouncer: Debouncer = new Debouncer(250);
@@ -115,6 +118,11 @@ export class Searchbar extends Ion {
115118
*/
116119
@Input() type: string = 'search';
117120

121+
/**
122+
* @input {string|boolean} Set the input's spellcheck property. Values: `true`, `false`. Default `false`.
123+
*/
124+
@Input() animated: string | boolean = false;
125+
118126
/**
119127
* @output {event} When the Searchbar input has changed including cleared.
120128
*/
@@ -217,7 +225,7 @@ export class Searchbar extends Ion {
217225
* @private
218226
* After View Checked position the elements
219227
*/
220-
ngAfterViewChecked() {
228+
ngAfterContentInit() {
221229
this.positionElements();
222230
}
223231

@@ -227,26 +235,31 @@ export class Searchbar extends Ion {
227235
* based on the input value and if it is focused. (ios only)
228236
*/
229237
positionElements() {
230-
if (this._config.get('mode') !== 'ios') return;
238+
let isAnimated = isTrueProperty(this.animated);
239+
let prevAlignLeft = this._shouldAlignLeft;
240+
let shouldAlignLeft = (!isAnimated || (this._value && this._value.toString().trim() !== '') || this._sbHasFocus === true);
241+
this._shouldAlignLeft = shouldAlignLeft;
231242

232-
// Position the input placeholder & search icon
233-
if (this._searchbarInput && this._searchbarIcon) {
234-
this.positionInputPlaceholder(this._searchbarInput.nativeElement, this._searchbarIcon.nativeElement);
243+
if (this._config.get('mode') !== 'ios') {
244+
return;
235245
}
236246

237-
// Position the cancel button
238-
if (this._cancelButton && this._cancelButton.nativeElement) {
239-
this.positionCancelButton(this._cancelButton.nativeElement);
247+
if (prevAlignLeft !== shouldAlignLeft) {
248+
this.positionPlaceholder();
249+
}
250+
if (isAnimated) {
251+
this.positionCancelButton();
240252
}
241253
}
242254

243-
/**
244-
* @private
245-
* Calculates the amount of padding/margin left for the elements
246-
* in order to center them based on the placeholder width
247-
*/
248-
positionInputPlaceholder(inputEle: HTMLElement, iconEle: HTMLElement) {
249-
if (this.shouldAlignLeft()) {
255+
positionPlaceholder() {
256+
if (!this._searchbarInput || !this._searchbarIcon) {
257+
return;
258+
}
259+
let inputEle = this._searchbarInput.nativeElement;
260+
let iconEle = this._searchbarIcon.nativeElement;
261+
262+
if (this._shouldAlignLeft) {
250263
inputEle.removeAttribute('style');
251264
iconEle.removeAttribute('style');
252265
} else {
@@ -273,23 +286,26 @@ export class Searchbar extends Ion {
273286
* @private
274287
* Show the iOS Cancel button on focus, hide it offscreen otherwise
275288
*/
276-
positionCancelButton(cancelButtonEle: HTMLElement) {
277-
if (cancelButtonEle.offsetWidth > 0) {
278-
if (this._sbHasFocus) {
279-
cancelButtonEle.style.marginRight = '0';
289+
positionCancelButton() {
290+
if (!this._cancelButton || !this._cancelButton.nativeElement) {
291+
return;
292+
}
293+
let showShowCancel = this._sbHasFocus;
294+
if (showShowCancel !== this._isCancelVisible) {
295+
let cancelStyleEle = this._cancelButton.nativeElement;
296+
let cancelStyle = cancelStyleEle.style;
297+
this._isCancelVisible = showShowCancel;
298+
if (showShowCancel) {
299+
cancelStyle.marginRight = '0';
280300
} else {
281-
cancelButtonEle.style.marginRight = -cancelButtonEle.offsetWidth + 'px';
301+
let offset = cancelStyleEle.offsetWidth;
302+
if (offset > 0) {
303+
cancelStyle.marginRight = -offset + 'px';
304+
}
282305
}
283306
}
284307
}
285308

286-
/**
287-
* @private
288-
* Align the input placeholder left on focus or if a value exists
289-
*/
290-
shouldAlignLeft() {
291-
return ( (this._value && this._value.toString().trim() !== '') || this._sbHasFocus === true );
292-
}
293309

294310
/**
295311
* @private
@@ -399,4 +415,8 @@ export class Searchbar extends Ion {
399415
registerOnTouched(fn: () => {}): void {
400416
this.onTouched = fn;
401417
}
418+
419+
focus() {
420+
this.getNativeElement().focus();
421+
}
402422
}

src/components/searchbar/test/basic/main.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
<h5 padding-left> Search - Default </h5>
33
<ion-searchbar [(ngModel)]="defaultSearch" showCancelButton debounce="500" (ionInput)="triggerInput($event)" (ionBlur)="inputBlurred($event)" (ionFocus)="inputFocused($event)" (ionCancel)="onCancelSearchbar($event)" (ionClear)="onClearSearchbar($event)"></ion-searchbar>
44

5+
<h5 padding-left> Search - Animated </h5>
6+
<ion-searchbar animated="true" showCancelButton debounce="500" (ionInput)="triggerInput($event)" (ionBlur)="inputBlurred($event)" (ionFocus)="inputFocused($event)" (ionCancel)="onCancelSearchbar($event)" (ionClear)="onClearSearchbar($event)"></ion-searchbar>
7+
58
<p padding-left>
69
defaultSearch: <b>{{ defaultSearch }}</b>
710
</p>

src/components/searchbar/test/nav/search.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414

1515
<ion-content>
1616

17-
<ion-searchbar (ionInput)="getItems($event)"></ion-searchbar>
18-
17+
<form>
18+
<ion-searchbar (ionInput)="getItems($event)"></ion-searchbar>
19+
</form>
1920
<ion-list>
2021
<button ion-item *ngFor="let item of items" (click)="showDetail(item)" class="e2eSearchbarNavItem">
2122
{{ item }}

0 commit comments

Comments
 (0)