feat(searchbar): add searchbar component

This commit is contained in:
Ionitron
2017-07-06 15:02:14 -04:00
parent 2df495b6e2
commit 59841ac7a8
6 changed files with 398 additions and 11 deletions

View File

@ -0,0 +1,269 @@
@import "../../themes/ionic.globals.ios";
@import "./searchbar";
// iOS Searchbar
// --------------------------------------------------
/// @prop - Padding top/bottom of the searchbar
$searchbar-ios-padding-vertical: 0 !default;
/// @prop - Padding start/end of the searchbar
$searchbar-ios-padding-horizontal: 8px !default;
/// @prop - Background of the searchbar
$searchbar-ios-background-color: rgba(0, 0, 0, .2) !default;
/// @prop - Border color of the searchbar
$searchbar-ios-border-color: rgba(0, 0, 0, .05) !default;
/// @prop - Minimum height of the searchbar
$searchbar-ios-min-height: 44px !default;
/// @prop - Color of the searchbar input search icon
$searchbar-ios-input-search-icon-color: rgba(0, 0, 0, .5) !default;
/// @prop - Svg for the searchbar input search icon
$searchbar-ios-input-search-icon-svg: "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 13 13'><path fill='fg-color' d='M5,1c2.2,0,4,1.8,4,4S7.2,9,5,9S1,7.2,1,5S2.8,1,5,1 M5,0C2.2,0,0,2.2,0,5s2.2,5,5,5s5-2.2,5-5S7.8,0,5,0 L5,0z'/><line stroke='fg-color' stroke-miterlimit='10' x1='12.6' y1='12.6' x2='8.2' y2='8.2'/></svg>" !default;
/// @prop - Size of the searchbar input search icon
$searchbar-ios-input-search-icon-size: 13px !default;
/// @prop - Height of the searchbar input
$searchbar-ios-input-height: 3rem !default;
/// @prop - Color of the searchbar input placeholder
$searchbar-ios-input-placeholder-color: rgba(0, 0, 0, .5) !default;
/// @prop - Color of the searchbar input text
$searchbar-ios-input-text-color: #000 !default;
/// @prop - Background of the searchbar input
$searchbar-ios-input-background-color: #fff !default;
/// @prop - Transition of the searchbar input
$searchbar-ios-input-transition: all 300ms ease !default;
/// @prop - Transition of the searchbar input cancel button
$searchbar-ios-cancel-transition: all 300ms ease !default;
/// @prop - Color of the searchbar input clear icon
$searchbar-ios-input-clear-icon-color: rgba(0, 0, 0, .5) !default;
/// @prop - Svg for the searchbar input clear icon
$searchbar-ios-input-clear-icon-svg: "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'><path fill='fg-color' d='M403.1,108.9c-81.2-81.2-212.9-81.2-294.2,0s-81.2,212.9,0,294.2c81.2,81.2,212.9,81.2,294.2,0S484.3,190.1,403.1,108.9z M352,340.2L340.2,352l-84.4-84.2l-84,83.8L160,339.8l84-83.8l-84-83.8l11.8-11.8l84,83.8l84.4-84.2l11.8,11.8L267.6,256L352,340.2z'/></svg>" !default;
/// @prop - Size of the searchbar input clear icon
$searchbar-ios-input-clear-icon-size: 18px !default;
/// @prop - Background of the searchbar input inside of a toolbar
$searchbar-ios-toolbar-input-background: rgba(0, 0, 0, .08) !default;
// Searchbar
// -----------------------------------------
.searchbar-ios {
@include padding($searchbar-ios-padding-vertical, $searchbar-ios-padding-horizontal);
min-height: $searchbar-ios-min-height;
border-top: $hairlines-width solid transparent;
border-bottom: $hairlines-width solid $searchbar-ios-border-color;
background: $searchbar-ios-background-color;
}
// Searchbar Mixin for Icons
// -----------------------------------------
@mixin ios-searchbar-icon($svg-icon, $fg-color) {
$svg: str-replace($svg-icon, 'fg-color', $fg-color);
@include svg-background-image($svg, true);
}
// Searchbar Search Icon
// -----------------------------------------
.searchbar-ios .searchbar-search-icon {
@include position(9px, null, null, 9px);
@include ios-searchbar-icon($searchbar-ios-input-search-icon-svg, $searchbar-ios-input-search-icon-color);
@include margin-horizontal(calc(50% - 60px), null);
position: absolute;
width: $searchbar-ios-input-search-icon-size + 1;
height: $searchbar-ios-input-search-icon-size + 1;
background-repeat: no-repeat;
background-size: $searchbar-ios-input-search-icon-size;
}
// Searchbar Input Field
// -----------------------------------------
.searchbar-ios .searchbar-input {
@include placeholder($searchbar-ios-input-placeholder-color);
@include padding(0, 28px);
@include border-radius(5px);
height: $searchbar-ios-input-height;
font-size: 1.4rem;
font-weight: 400;
color: $searchbar-ios-input-text-color;
background-color: $searchbar-ios-input-background-color;
}
// Searchbar Clear Input Icon
// -----------------------------------------
.searchbar-ios ion-button.searchbar-clear-icon {
@include position(0, 0, null, null);
@include ios-searchbar-icon($searchbar-ios-input-clear-icon-svg, $searchbar-ios-input-clear-icon-color);
@include background-position(center);
position: absolute;
width: 30px;
height: 100%;
background-repeat: no-repeat;
background-size: $searchbar-ios-input-clear-icon-size;
}
// Searchbar Cancel (iOS only)
// -----------------------------------------
.searchbar-ios .searchbar-ios-cancel {
@include margin-horizontal(0, null);
display: none;
flex-shrink: 0;
height: 30px;
cursor: pointer;
}
.searchbar-ios button.searchbar-ios-cancel {
@include padding(0, 0, 0, 8px);
@include margin(0);
}
// Searchbar Left Aligned (iOS only)
// -----------------------------------------
.searchbar-ios.searchbar-left-aligned .searchbar-search-icon {
@include margin-horizontal(0, null);
}
.searchbar-ios.searchbar-left-aligned .searchbar-input {
@include padding-horizontal(30px, null);
}
// Searchbar Has Focus
// -----------------------------------------
.searchbar-ios.searchbar-show-cancel.searchbar-has-focus .searchbar-ios-cancel {
display: block;
}
// Searchbar in Toolbar
// -----------------------------------------
.toolbar .searchbar-ios {
border-bottom-width: 0;
background: transparent;
}
.toolbar .searchbar-ios .searchbar-input {
background: $searchbar-ios-toolbar-input-background;
}
.toolbar .searchbar-ios .searchbar-ios-cancel {
@include padding(0);
}
.toolbar .searchbar-ios.searchbar-has-focus .searchbar-ios-cancel {
@include padding-horizontal(8px, null);
}
// Searchbar Cancel (MD only)
// -----------------------------------------
.searchbar-ios .searchbar-md-cancel {
display: none;
}
// Generate Default Search Bar Colors
// --------------------------------------------------
@each $color-name, $color-base, $color-contrast in get-colors($colors-ios) {
$fg-color: rgba($color-contrast, .5);
.searchbar-ios-#{$color-name} .searchbar-ios-cancel {
color: $color-base;
}
.searchbar-ios-#{$color-name} .searchbar-ios-cancel:hover:not(.disable-hover) {
color: color-shade($color-base);
}
.toolbar-ios-#{$color-name} .searchbar-ios .searchbar-search-icon {
@include ios-searchbar-icon($searchbar-ios-input-search-icon-svg, $fg-color);
}
.toolbar-ios-#{$color-name} .searchbar-ios .searchbar-input {
@include placeholder($fg-color);
color: $color-contrast;
background: rgba($color-contrast, .08);
}
.toolbar-ios-#{$color-name} .searchbar-ios .searchbar-clear-icon {
@include ios-searchbar-icon($searchbar-ios-input-clear-icon-svg, $fg-color);
}
.toolbar-ios-#{$color-name} .searchbar-ios .searchbar-ios-cancel {
color: color-contrast($colors-ios, $color-base, ios);
}
}
// Searchbar animation
// -----------------------------------------
.searchbar-ios.searchbar-animated.searchbar-show-cancel .searchbar-ios-cancel {
display: block;
}
.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 {
@include margin-horizontal(null, -100%);
@include transform(translate3d(0, 0, 0));
opacity: 0;
transition: $searchbar-ios-cancel-transition;
pointer-events: none;
}

View File

@ -0,0 +1,193 @@
@import "../../themes/ionic.globals.md";
@import "./searchbar";
// Material Design Searchbar
// --------------------------------------------------
// deprecated
$searchbar-md-padding: null !default;
/// @prop - Padding top of the searchbar
$searchbar-md-padding-top: 8px !default;
/// @prop - Padding end of the searchbar
$searchbar-md-padding-end: $searchbar-md-padding-top !default;
/// @prop - Padding bottom of the searchbar
$searchbar-md-padding-bottom: $searchbar-md-padding-top !default;
/// @prop - Padding start of the searchbar
$searchbar-md-padding-start: $searchbar-md-padding-end !default;
/// @prop - Background of the searchbar
$searchbar-md-background-color: inherit !default;
/// @prop - Color of the searchbar input search icon
$searchbar-md-input-search-icon-color: #5b5b5b !default;
/// @prop - Svg for the searchbar input search icon
$searchbar-md-input-search-icon-svg: "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'><path fill='" + $searchbar-md-input-search-icon-color + "' d='M337.509,305.372h-17.501l-6.571-5.486c20.791-25.232,33.922-57.054,33.922-93.257C347.358,127.632,283.896,64,205.135,64C127.452,64,64,127.632,64,206.629s63.452,142.628,142.225,142.628c35.011,0,67.831-13.167,92.991-34.008l6.561,5.487v17.551L415.18,448L448,415.086L337.509,305.372z M206.225,305.372c-54.702,0-98.463-43.887-98.463-98.743c0-54.858,43.761-98.742,98.463-98.742c54.7,0,98.462,43.884,98.462,98.742C304.687,261.485,260.925,305.372,206.225,305.372z'/></svg>" !default;
/// @prop - Size of the searchbar input search icon
$searchbar-md-input-search-icon-size: 20px !default;
/// @prop - Height of the searchbar input
$searchbar-md-input-height: auto !default;
/// @prop - Line height of the searchbar input
$searchbar-md-input-line-height: 3rem !default;
/// @prop - Box shadow of the searchbar input
$searchbar-md-input-box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12) !default;
/// @prop - Color of the searchbar input placeholder
$searchbar-md-input-placeholder-color: #aeaeae !default;
/// @prop - Color of the searchbar input text
$searchbar-md-input-text-color: #141414 !default;
/// @prop - Background of the searchbar input
$searchbar-md-input-background-color: #fff !default;
/// @prop - Border radius of the searchbar input
$searchbar-md-input-border-radius: 2px !default;
/// @prop - Color of the searchbar input clear icon
$searchbar-md-input-clear-icon-color: #5b5b5b !default;
/// @prop - Svg for the searchbar input clear icon
$searchbar-md-input-clear-icon-svg: "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'><polygon fill='" + $searchbar-md-input-clear-icon-color + "' points='405,136.798 375.202,107 256,226.202 136.798,107 107,136.798 226.202,256 107,375.202 136.798,405 256,285.798 375.202,405 405,375.202 285.798,256'/></svg>" !default;
/// @prop - Size of the searchbar input clear icon
$searchbar-md-input-clear-icon-size: 22px !default;
// Searchbar
// -----------------------------------------
.searchbar-md {
background: $searchbar-md-background-color;
@include deprecated-variable(padding, $searchbar-md-padding) {
@include padding($searchbar-md-padding-top, $searchbar-md-padding-end, $searchbar-md-padding-bottom, $searchbar-md-padding-start);
}
}
// Searchbar Search Icon
// -----------------------------------------
.searchbar-md .searchbar-search-icon {
@include position(11px, null, null, 16px);
@include svg-background-image($searchbar-md-input-search-icon-svg, true);
width: $searchbar-md-input-search-icon-size + 1;
height: $searchbar-md-input-search-icon-size + 1;
}
// Searchbar Cancel Icon (MD only)
// -----------------------------------------
.searchbar-md .searchbar-md-cancel {
@include position(0, null, null, 10px);
@include margin(0);
display: none;
width: $searchbar-md-input-search-icon-size + 1;
height: 100%;
}
// Searchbar Search & Cancel Icon
// -----------------------------------------
.searchbar-md .searchbar-search-icon,
.searchbar-md .searchbar-md-cancel {
position: absolute;
background-repeat: no-repeat;
background-size: $searchbar-md-input-search-icon-size;
}
.searchbar-md .searchbar-search-icon.activated,
.searchbar-md .searchbar-md-cancel.activated {
background-color: transparent;
}
// Searchbar Input Field
// -----------------------------------------
.searchbar-md .searchbar-input {
@include placeholder($searchbar-md-input-placeholder-color);
@include padding(6px, 55px);
@include border-radius($searchbar-md-input-border-radius);
@include background-position(start, 8px, center);
height: $searchbar-md-input-height;
font-size: 1.6rem;
font-weight: 400;
line-height: $searchbar-md-input-line-height;
color: $searchbar-md-input-text-color;
background-color: $searchbar-md-input-background-color;
box-shadow: $searchbar-md-input-box-shadow;
}
// Searchbar Clear Input Icon
// -----------------------------------------
.searchbar-md ion-button.searchbar-clear-icon {
@include position(0, 13px, null, null);
@include svg-background-image($searchbar-md-input-clear-icon-svg);
@include padding(0);
@include background-position(center);
position: absolute;
width: $searchbar-md-input-clear-icon-size;
height: 100%;
background-repeat: no-repeat;
background-size: $searchbar-md-input-clear-icon-size;
}
.searchbar-md ion-button.searchbar-clear-icon.activated {
background-color: transparent;
}
// Searchbar Focused
// -----------------------------------------
.searchbar-md.searchbar-has-focus.searchbar-show-cancel .searchbar-search-icon {
display: none;
}
.searchbar-md.searchbar-has-focus.searchbar-show-cancel .searchbar-md-cancel {
display: inline-flex;
}
// Searchbar in Toolbar
// -----------------------------------------
.toolbar .searchbar-md {
@include padding(3px);
}
.toolbar .searchbar-md .searchbar-md-cancel {
@include position-horizontal(14px, null);
}
// Searchbar Cancel Icon (iOS only)
// -----------------------------------------
.searchbar-md .searchbar-ios-cancel {
display: none;
}

View File

@ -0,0 +1,50 @@
@import "../../themes/ionic.globals";
// Searchbar
// --------------------------------------------------
ion-searchbar {
position: relative;
display: flex;
align-items: center;
width: 100%;
}
.searchbar-icon {
// Don't let them tap on the icon
pointer-events: none;
}
.searchbar-input-container {
position: relative;
display: block;
flex-shrink: 1;
width: 100%;
}
.searchbar-input {
@include appearance(none);
display: block;
width: 100%;
border: 0;
font-family: inherit;
}
.searchbar-clear-icon {
@include margin(0);
@include padding(0);
display: none;
min-height: 0;
}
.searchbar-has-value.searchbar-has-focus .searchbar-clear-icon {
display: block;
}

View File

@ -0,0 +1,379 @@
import { Component, h, Ionic, Prop, PropDidChange, State } from '@stencil/core';
import { VNodeData } from '../../utils/interfaces';
/**
* @name Searchbar
* @module ionic
* @description
* Manages the display of a Searchbar which can be used to search or filter items.
*
* @usage
* ```html
* <ion-searchbar
* [(ngModel)]="myInput"
* [showCancelButton]="shouldShowCancel"
* (ionInput)="onInput($event)"
* (ionCancel)="onCancel($event)">
* </ion-searchbar>
* ```
*
* @demo /docs/demos/src/searchbar/
* @see {@link /docs/components#searchbar Searchbar Component Docs}
*/
@Component({
tag: 'ion-searchbar',
styleUrls: {
ios: 'searchbar.ios.scss',
md: 'searchbar.md.scss',
wp: 'searchbar.wp.scss'
},
host: {
theme: 'searchbar'
}
})
export class Searchbar {
$el: HTMLElement;
_isCancelVisible: boolean = false;
_shouldBlur: boolean = true;
_shouldAlignLeft: boolean = true;
@Prop() mode: string;
@Prop() color: string;
@State() activated: boolean = false;
@State() focused: boolean = false;
// /**
// * @output {event} Emitted when the Searchbar input has changed, including when it's cleared.
// */
// @Output() ionInput: EventEmitter<UIEvent> = new EventEmitter<UIEvent>();
// /**
// * @output {event} Emitted when the cancel button is clicked.
// */
// @Output() ionCancel: EventEmitter<UIEvent> = new EventEmitter<UIEvent>();
// /**
// * @output {event} Emitted when the clear input button is clicked.
// */
// @Output() ionClear: EventEmitter<UIEvent> = new EventEmitter<UIEvent>();
/**
* @input {boolean} If true, enable searchbar animation. Default `false`.
*/
@Prop({ state: true }) animated: boolean = false;
/**
* @input {string} Set the input's autocomplete property. Values: `"on"`, `"off"`. Default `"off"`.
*/
@Prop({ state: true }) autocomplete: string = 'off';
/**
* @input {string} Set the input's autocorrect property. Values: `"on"`, `"off"`. Default `"off"`.
*/
@Prop({ state: true }) autocorrect: string = 'off';
/**
* @input {string} Set the the cancel button text. Default: `"Cancel"`.
*/
@Prop({ state: true }) cancelButtonText: string = 'Cancel';
// _inputDebouncer: TimeoutDebouncer = new TimeoutDebouncer(0);
// /**
// * @input {number} How long, in milliseconds, to wait to trigger the `ionInput` event after each keystroke. Default `250`.
// */
// @Input()
// get debounce(): number {
// return this._debouncer.wait;
// }
// set debounce(val: number) {
// this._debouncer.wait = val;
// this._inputDebouncer.wait = val;
// }
/**
* @input {number} Set the amount of time, in milliseconds, to wait to trigger the `ionInput` event after each keystroke. Default `250`.
*/
@Prop({ state: true }) debounce: number = 250;
/**
* @input {string} Set the input's placeholder. Default `"Search"`.
*/
@Prop({ state: true }) placeholder: string = 'Search';
/**
* @input {boolean} If true, show the cancel button. Default `false`.
*/
@Prop({ state: true }) showCancelButton: boolean = false;
/**
* @input {boolean} If true, enable spellcheck on the input. Default `false`.
*/
@Prop({ state: true }) spellcheck: boolean = false;
/**
* @input {string} Set the type of the input. Values: `"text"`, `"password"`, `"email"`, `"number"`, `"search"`, `"tel"`, `"url"`. Default `"search"`.
*/
@Prop({ state: true }) type: string = 'search';
/**
* @input {string} Set the value of the searchbar.
*/
@Prop({ state: true }) value: string;
ionViewDidLoad() {
this.positionElements();
}
/**
* @hidden
* Clears the input field and triggers the control change.
*/
clearInput(ev: UIEvent) {
Ionic.emit(this, 'ionClear', { detail: { event: ev } });
// setTimeout() fixes https://github.com/ionic-team/ionic/issues/7527
// wait for 4 frames
setTimeout(() => {
let value = this.value;
if (value !== undefined && value !== '') {
this.value = '';
Ionic.emit(this, 'ionInput', { detail: { event: ev } });
}
}, 16 * 4);
this._shouldBlur = false;
}
/**
* @hidden
* Clears the input field and tells the input to blur since
* the clearInput function doesn't want the input to blur
* then calls the custom cancel function if the user passed one in.
*/
cancelSearchbar(ev: UIEvent) {
Ionic.emit(this, 'ionCancel', { detail: { event: ev } });
this.clearInput(ev);
this._shouldBlur = true;
this.activated = false;
}
/**
* @hidden
* Update the Searchbar input value when the input changes
*/
inputChanged(ev: any) {
this.value = ev.target.value;
// this._inputDebouncer.debounce(() => {
// this.ionInput.emit(ev);
// });
}
/**
* @hidden
*/
inputUpdated() {
// const inputEle = this.$el.querySelector('.searchbar-input') as HTMLInputElement;
// 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 (inputEle && inputEle.value !== this.value) {
// // inputEle.value = this.value;
// this.value = inputEle.value;
// }
this.positionElements();
}
/**
* @hidden
* 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.
*/
inputBlurred() {
const inputEle = this.$el.querySelector('.searchbar-input') as HTMLElement;
// _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) {
inputEle.focus();
this._shouldBlur = true;
Ionic.emit(this, 'ionBlur', { detail: { this: this } });
this.inputUpdated();
return;
}
this.focused = false;
this.positionElements();
}
/**
* @hidden
* Sets the Searchbar to focused and active on input focus.
*/
inputFocused() {
this.activated = true;
this.focused = true;
Ionic.emit(this, 'ionFocus', { detail: { this: this } });
this.inputUpdated();
this.positionElements();
}
/**
* @hidden
* Positions the input search icon, placeholder, and the cancel button
* based on the input value and if it is focused. (ios only)
*/
positionElements() {
const prevAlignLeft = this._shouldAlignLeft;
const _shouldAlignLeft = (!this.animated || (this.value && this.value.toString().trim() !== '') || this.focused === true);
this._shouldAlignLeft = _shouldAlignLeft;
if (this.mode !== 'ios') {
return;
}
if (prevAlignLeft !== _shouldAlignLeft) {
this.positionPlaceholder();
}
if (this.animated) {
this.positionCancelButton();
}
}
/**
* @hidden
* Positions the input placeholder
*/
positionPlaceholder() {
const isRTL = document.documentElement.getAttribute('dir') === 'rtl';
const inputEle = this.$el.querySelector('.searchbar-input') as HTMLElement;
const iconEle = this.$el.querySelector('.searchbar-search-icon') as HTMLElement;
if (this._shouldAlignLeft) {
inputEle.removeAttribute('style');
iconEle.removeAttribute('style');
} else {
// Create a dummy span to get the placeholder width
var tempSpan = document.createElement('span');
tempSpan.innerHTML = this.placeholder;
document.body.appendChild(tempSpan);
// Get the width of the span then remove it
var textWidth = tempSpan.offsetWidth;
document.body.removeChild(tempSpan);
// Calculate the input padding
var inputLeft = 'calc(50% - ' + (textWidth / 2) + 'px)';
// Calculate the icon margin
var iconLeft = 'calc(50% - ' + ((textWidth / 2) + 30) + 'px)';
// Set the input padding start and icon margin start
if (isRTL) {
inputEle.style.paddingRight = inputLeft;
iconEle.style.marginRight = iconLeft;
} else {
inputEle.style.paddingLeft = inputLeft;
iconEle.style.marginLeft = iconLeft;
}
}
}
/**
* @hidden
* Show the iOS Cancel button on focus, hide it offscreen otherwise
*/
positionCancelButton() {
const isRTL = document.documentElement.getAttribute('dir') === 'rtl';
const cancelButton = this.$el.querySelector('.searchbar-ios-cancel') as HTMLElement;
const shouldShowCancel = this.focused;
if (shouldShowCancel !== this._isCancelVisible) {
var cancelStyle = cancelButton.style;
this._isCancelVisible = shouldShowCancel;
if (shouldShowCancel) {
if (isRTL) {
cancelStyle.marginLeft = '0';
} else {
cancelStyle.marginRight = '0';
}
} else {
var offset = cancelButton.offsetWidth;
if (offset > 0) {
if (isRTL) {
cancelStyle.marginLeft = -offset + 'px';
} else {
cancelStyle.marginRight = -offset + 'px';
}
}
}
}
}
hostData(): VNodeData {
return {
class: {
'searchbar-active': this.activated,
'searchbar-animated': this.animated,
'searchbar-has-value': (this.value !== undefined && this.value !== ''),
'searchbar-show-cancel': this.showCancelButton,
'searchbar-left-aligned': this._shouldAlignLeft,
'searchbar-has-focus': this.focused
}
};
}
render() {
return [
<div class='searchbar-input-container'>
<ion-button
mode="md"
onclick={this.cancelSearchbar.bind(this)}
onmousedown={this.cancelSearchbar.bind(this)}
clear
color="dark"
class="searchbar-md-cancel">
<ion-icon name="md-arrow-back"></ion-icon>
</ion-button>
<div class="searchbar-search-icon"></div>
<input
class="searchbar-input"
oninput={this.inputChanged.bind(this)}
onblur={this.inputBlurred.bind(this)}
onfocus={this.inputFocused.bind(this)}
placeholder={this.placeholder}
type={this.type}
value={this.value}
autocomplete={this.autocomplete}
autocorrect={this.autocorrect}
spellcheck={this.spellcheck}/>
<ion-button
clear
class="searchbar-clear-icon"
onclick={this.clearInput.bind(this)}
onmousedown={this.clearInput.bind(this)}>
</ion-button>
</div>,
<ion-button
tabindex={this.activated ? 1 : -1}
clear
onclick={this.cancelSearchbar.bind(this)}
onmousedown={this.cancelSearchbar.bind(this)}
class="searchbar-ios-cancel">
{this.cancelButtonText}
</ion-button>
];
}
}

View File

@ -0,0 +1,211 @@
@import "../../themes/ionic.globals.wp";
@import "./searchbar";
// Windows Searchbar
// --------------------------------------------------
// deprecated
$searchbar-wp-padding: null !default;
/// @prop - Padding top of the searchbar
$searchbar-wp-padding-top: 8px !default;
/// @prop - Padding end of the searchbar
$searchbar-wp-padding-end: $searchbar-wp-padding-top !default;
/// @prop - Padding bottom of the searchbar
$searchbar-wp-padding-bottom: $searchbar-wp-padding-top !default;
/// @prop - Padding start of the searchbar
$searchbar-wp-padding-start: $searchbar-wp-padding-end !default;
/// @prop - Background of the searchbar
$searchbar-wp-background-color: transparent !default;
/// @prop - Border width of the searchbar
$searchbar-wp-border-width: 2px !default;
/// @prop - Border color of the searchbar
$searchbar-wp-border-color: $input-wp-border-color !default;
/// @prop - Border color of the searchbar on focus
$searchbar-wp-border-color-focused: color($colors-wp, primary) !default;
/// @prop - Color of the searchbar input search icon
$searchbar-wp-input-search-icon-color: #858585 !default;
/// @prop - Svg for the searchbar input search icon
$searchbar-wp-input-search-icon-svg: "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'><path fill='" + $searchbar-wp-input-search-icon-color + "' d='M337.509,305.372h-17.501l-6.571-5.486c20.791-25.232,33.922-57.054,33.922-93.257C347.358,127.632,283.896,64,205.135,64C127.452,64,64,127.632,64,206.629s63.452,142.628,142.225,142.628c35.011,0,67.831-13.167,92.991-34.008l6.561,5.487v17.551L415.18,448L448,415.086L337.509,305.372z M206.225,305.372c-54.702,0-98.463-43.887-98.463-98.743c0-54.858,43.761-98.742,98.463-98.742c54.7,0,98.462,43.884,98.462,98.742C304.687,261.485,260.925,305.372,206.225,305.372z'/></svg>" !default;
/// @prop - Size of the searchbar input search icon
$searchbar-wp-input-search-icon-size: 20px !default;
/// @prop - Padding top/bottom of the searchbar input
$searchbar-wp-input-padding-vertical: 0 !default;
/// @prop - Padding start/end of the searchbar input
$searchbar-wp-input-padding-horizontal: 8px !default;
/// @prop - Height of the searchbar input
$searchbar-wp-input-height: auto !default;
/// @prop - Line height of the searchbar input
$searchbar-wp-input-line-height: 3rem !default;
/// @prop - Color of the searchbar input placeholder
$searchbar-wp-input-placeholder-color: #858585 !default;
/// @prop - Color of the searchbar input text
$searchbar-wp-input-text-color: #141414 !default;
/// @prop - Background of the searchbar input
$searchbar-wp-input-background-color: #fff !default;
/// @prop - Border radius of the searchbar input
$searchbar-wp-input-border-radius: 0 !default;
/// @prop - Font size of the searchbar input
$searchbar-wp-input-font-size: 1.4rem !default;
/// @prop - Font weight of the searchbar input
$searchbar-wp-input-font-weight: 400 !default;
/// @prop - Color of the searchbar input clear icon
$searchbar-wp-input-clear-icon-color: #858585 !default;
/// @prop - Svg for the searchbar input clear icon
$searchbar-wp-input-clear-icon-svg: "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'><polygon fill='" + $searchbar-wp-input-clear-icon-color + "' points='405,136.798 375.202,107 256,226.202 136.798,107 107,136.798 226.202,256 107,375.202 136.798,405 256,285.798 375.202,405 405,375.202 285.798,256'/></svg>" !default;
/// @prop - Size of the searchbar input clear icon
$searchbar-wp-input-clear-icon-size: 22px !default;
// Searchbar
// -----------------------------------------
.searchbar-wp {
background: $searchbar-wp-background-color;
@include deprecated-variable(padding, $searchbar-wp-padding) {
@include padding($searchbar-wp-padding-top, $searchbar-wp-padding-end, $searchbar-wp-padding-bottom, $searchbar-wp-padding-start);
}
}
.searchbar-wp .searchbar-input-container {
border: $searchbar-wp-border-width solid $searchbar-wp-border-color;
}
// Searchbar Search Icon
// -----------------------------------------
.searchbar-wp .searchbar-search-icon {
@include position(5px, $searchbar-wp-input-padding-horizontal, null, null);
@include svg-background-image($searchbar-wp-input-search-icon-svg, true);
position: absolute;
width: $searchbar-wp-input-search-icon-size + 1;
height: $searchbar-wp-input-search-icon-size + 1;
background-repeat: no-repeat;
background-size: $searchbar-wp-input-search-icon-size;
}
.searchbar-wp .searchbar-search-icon.activated {
background-color: transparent;
}
// Searchbar Input Field
// -----------------------------------------
.searchbar-wp .searchbar-input {
@include placeholder($searchbar-wp-input-placeholder-color);
@include padding($searchbar-wp-input-padding-vertical, $searchbar-wp-input-padding-horizontal);
@include border-radius($searchbar-wp-input-border-radius);
@include background-position(start, $searchbar-wp-input-padding-horizontal, center);
height: $searchbar-wp-input-height;
font-size: $searchbar-wp-input-font-size;
font-weight: $searchbar-wp-input-font-weight;
line-height: $searchbar-wp-input-line-height;
color: $searchbar-wp-input-text-color;
background-color: $searchbar-wp-input-background-color;
}
// Searchbar Clear Input Icon
// -----------------------------------------
.searchbar-wp ion-button.searchbar-clear-icon {
@include position(0, $searchbar-wp-input-padding-horizontal, null, null);
@include svg-background-image($searchbar-wp-input-clear-icon-svg);
@include padding(0);
@include background-position(center);
position: absolute;
width: $searchbar-wp-input-clear-icon-size;
height: 100%;
background-repeat: no-repeat;
background-size: $searchbar-wp-input-clear-icon-size;
}
.searchbar-wp ion-button.searchbar-clear-icon.activated {
background-color: transparent;
}
// Searchbar Focused
// -----------------------------------------
.searchbar-wp.searchbar-has-focus .searchbar-input-container {
border-color: $searchbar-wp-border-color-focused;
}
// Searchbar Left Aligned
// -----------------------------------------
.searchbar-wp.searchbar-has-value .searchbar-search-icon {
display: none;
}
// Searchbar Cancel Icon (iOS only)
// -----------------------------------------
.searchbar-wp .searchbar-ios-cancel {
display: none;
}
// Searchbar Cancel Icon (MD only)
// -----------------------------------------
.searchbar-wp .searchbar-md-cancel {
display: none;
}
// Searchbar in Toolbar
// -----------------------------------------
.toolbar .searchbar-wp {
@include padding(2px);
}
// Generate Default Windows Search Bar Colors
// --------------------------------------------------
@each $color-name, $color-base, $color-contrast in get-colors($colors-wp) {
.searchbar-wp-#{$color-name}.searchbar-has-focus .searchbar-input-container {
border-color: $color-base;
}
}

View File

@ -11,6 +11,7 @@ exports.config = {
{ components: ['ion-loading', 'ion-loading-controller'] },
{ components: ['ion-menu'], priority: 'low' },
{ components: ['ion-modal', 'ion-modal-controller'] },
{ components: ['ion-searchbar'] },
{ components: ['ion-segment', 'ion-segment-button'] },
{ components: ['ion-slides', 'ion-slide'] },
{ components: ['ion-spinner'] },