diff --git a/src/components/app/_globals.scss b/src/components/app/_globals.scss index 8a4d365c83..9f1996daa8 100644 --- a/src/components/app/_globals.scss +++ b/src/components/app/_globals.scss @@ -9,9 +9,6 @@ -ms-content-zooming: none; -webkit-tap-highlight-color: rgba(0,0,0,0); - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; -ms-touch-action: manipulation; touch-action: manipulation; diff --git a/src/components/app/_normalize.scss b/src/components/app/_normalize.scss index c85595a4c3..37a20fbd6b 100644 --- a/src/components/app/_normalize.scss +++ b/src/components/app/_normalize.scss @@ -193,16 +193,6 @@ input[type="number"]::-webkit-outer-spin-button { height: auto; } -// 1. Address `appearance` set to `searchfield` in Safari and Chrome. -// 2. Address `box-sizing` set to `border-box` in Safari and Chrome -// (include `-moz` to future-proof). -input[type="search"] { - -webkit-appearance: textfield; // 1 - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; // 2 - box-sizing: content-box; -} - // Remove inner padding and search cancel button in Safari and Chrome on OS X. // Safari (but not Chrome) clips the cancel button when the search input has // padding (and `textfield` appearance). diff --git a/src/components/app/ionic.scss b/src/components/app/ionic.scss index c1663776fe..50878bc7eb 100644 --- a/src/components/app/ionic.scss +++ b/src/components/app/ionic.scss @@ -5,7 +5,8 @@ @import "mixins/flex", "mixins/transform", - "mixins/transition"; + "mixins/transition", + "mixins/util"; // Globals @@ -32,6 +33,7 @@ "../list/list", "../modal/modal", "../radio/radio", + "../search-bar/search-bar", "../switch/switch", "../tabs/tabs", "../toolbar/toolbar"; @@ -51,6 +53,7 @@ "../list/extensions/ios", "../item/extensions/ios", "../radio/extensions/ios", + "../search-bar/extensions/ios", "../switch/extensions/ios", "../toolbar/extensions/ios"; diff --git a/src/components/app/mixins/_util.scss b/src/components/app/mixins/_util.scss new file mode 100644 index 0000000000..cd8eced5a0 --- /dev/null +++ b/src/components/app/mixins/_util.scss @@ -0,0 +1,66 @@ + +// Util Mixins/Functions + + + +// Appearance Mixin +// -------------------------------------------------- + +@mixin appearance($val) { + -webkit-appearance: $val; + -moz-appearance: $val; + -ms-appearance: $val; + appearance: $val; +} + + +// User Select Mixin +// -------------------------------------------------- + +@mixin user-select($select) { + -webkit-user-select: $select; + -moz-user-select: $select; + -ms-user-select: $select; + user-select: $select; +} + + +// Background Sizing Mixin +// -------------------------------------------------- + +@mixin background-size($size) { + -webkit-background-size: $size; + background-size: $size; +} + + +// String Replace Function +// -------------------------------------------------- + +@function str-replace($string, $search, $replace: '') { + $index: str-index($string, $search); + + @if $index { + @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); + } + + @return $string; +} + + +// URL Encode Function +// -------------------------------------------------- + +@function url-encode($val) { + $val: str-replace($val, ' ', '%20'); + @return $val; +} + + +// SVG Background Image Mixin +// -------------------------------------------------- + +@mixin svg-background-image($svg) { + $url: url-encode($svg); + background-image: url("data:image/svg+xml;charset=utf-8,#{$url}"); +} diff --git a/src/components/search-bar/extensions/ios.scss b/src/components/search-bar/extensions/ios.scss new file mode 100644 index 0000000000..53d2d61bdd --- /dev/null +++ b/src/components/search-bar/extensions/ios.scss @@ -0,0 +1,54 @@ + +// iOS Search Bar +// -------------------------------------------------- + +$search-bar-ios-background-color: #c9c9ce !default; +$search-bar-ios-border-color: $list-ios-border-color !default; +$search-bar-ios-padding: 0 8px !default; +$search-bar-ios-input-height: 28px !default; +$search-bar-ios-background-svg: "" !default; +$search-bar-ios-background-size: 13px 13px !default; + + +.search-bar-ios { + padding: $search-bar-ios-padding; + background: $search-bar-ios-background-color; + + + &:after { + position: absolute; + top: auto; + right: auto; + bottom: 0; + left: 0; + z-index: $z-index-list-border; + display: block; + + width: 100%; + height: 1px; + @include transform-origin(50%, 0); + + background-color: $list-ios-border-color; + + content: ''; + } + + .search-bar-input { + height: $search-bar-ios-input-height; + padding: 0 28px; + + font-size: 1.4rem; + font-weight: 400; + + border-radius: 5px; + color: #000; + background-color: #fff; + background-repeat: no-repeat; + background-position: 8px center; + + @include svg-background-image($search-bar-ios-background-svg); + @include background-size($search-bar-ios-background-size); + } + +} + diff --git a/src/components/search-bar/search-bar.js b/src/components/search-bar/search-bar.js index e69de29bb2..a279115770 100644 --- a/src/components/search-bar/search-bar.js +++ b/src/components/search-bar/search-bar.js @@ -0,0 +1,33 @@ +import {NgElement, Component, Template} from 'angular2/angular2' +import {ComponentConfig} from 'ionic2/config/component-config'; + +export let SearchBarConfig = new ComponentConfig('search-bar') + +@Component({ + selector: 'ion-search-bar', + bind: { + cancelText: 'cancel-text', + placeholderText: 'placeholder-text' + }, + services: [SearchBarConfig] +}) +@Template({ + inline: `
+ +
+ ` +}) +export class SearchBar { + constructor( + configFactory: SearchBarConfig, + ngElement: NgElement + ) { + this.domElement = ngElement.domElement; + configFactory.create(this); + + // Defaults + this.cancelText = this.cancelText || 'Cancel' + this.placeholderText = this.placeholderText || 'Search' + } +} + diff --git a/src/components/search-bar/search-bar.scss b/src/components/search-bar/search-bar.scss index e69de29bb2..e041978ddd 100644 --- a/src/components/search-bar/search-bar.scss +++ b/src/components/search-bar/search-bar.scss @@ -0,0 +1,35 @@ + +// Search Bar +// -------------------------------------------------- + +$search-bar-min-height: 44px !default; + + +.search-bar { + position: relative; + @include flex-display(); + @include flex-align-items(center); + width: 100%; + min-height: $search-bar-min-height; +} + +.search-bar-input-container { + position: relative; + display: block; + @include flex-shrink(1); + width: 100%; +} + +.search-bar-input { + display: block; + width: 100%; + height: 100%; + border: none; + font-family: inherit; + @include appearance(none); + outline: 0; +} + +.search-bar-cancel { + display: none; +} diff --git a/src/components/search-bar/test/basic/e2e.js b/src/components/search-bar/test/basic/e2e.js new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/src/components/search-bar/test/basic/e2e.js @@ -0,0 +1 @@ + diff --git a/src/components/search-bar/test/basic/main.html b/src/components/search-bar/test/basic/main.html new file mode 100644 index 0000000000..8fbeb4218d --- /dev/null +++ b/src/components/search-bar/test/basic/main.html @@ -0,0 +1,38 @@ + + + + + + + + + +
+
+
+ Item +
+
+
+ +
+
+
+ Item +
+
+
+ +
+
+
+ Item +
+
+
+ +
+ +
+ +
diff --git a/src/components/search-bar/test/basic/main.js b/src/components/search-bar/test/basic/main.js new file mode 100644 index 0000000000..16f08d7ad9 --- /dev/null +++ b/src/components/search-bar/test/basic/main.js @@ -0,0 +1,20 @@ +import {bootstrap} from 'angular2/core'; +import {Component, Template} from 'angular2/angular2'; +import {View} from 'ionic2/components/view/view'; +import {Content} from 'ionic2/components/content/content'; +import {List} from 'ionic2/components/list/list'; +import {SearchBar} from 'ionic2/components/search-bar/search-bar'; + + +@Component({ selector: '[ion-app]' }) +@Template({ + url: 'main.html', + directives: [View, Content, List, SearchBar] +}) +class IonicApp { + constructor() { + console.log('IonicApp Start') + } +} + +bootstrap(IonicApp) diff --git a/src/components/toolbar/toolbar.js b/src/components/toolbar/toolbar.js index d1b948b973..76d1b18a26 100644 --- a/src/components/toolbar/toolbar.js +++ b/src/components/toolbar/toolbar.js @@ -1,6 +1,7 @@ import {NgElement, Component, Template} from 'angular2/angular2' import {BackButton} from 'ionic2/components/toolbar/back-button' import {ComponentConfig} from 'ionic2/config/component-config' +import {raf} from 'ionic2/util/dom' export let ToolbarConfig = new ComponentConfig('toolbar') @@ -64,7 +65,7 @@ export class Toolbar { this.titleEle.style.margin = `0 ${centerMargin}px 0 0` - window.requestAnimationFrame(() => { + raf(() => { if (this.titleEle.offsetWidth < this.titleEle.scrollWidth) { this.titleEle.style.margin = '' this.titleEle.style.textAlign = 'left'