mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
search bar
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
66
src/components/app/mixins/_util.scss
Normal file
66
src/components/app/mixins/_util.scss
Normal file
@@ -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}");
|
||||
}
|
||||
54
src/components/search-bar/extensions/ios.scss
Normal file
54
src/components/search-bar/extensions/ios.scss
Normal file
@@ -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: "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 13 13'><path fill='#939398' 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='#939398' stroke-miterlimit='10' x1='12.6' y1='12.6' x2='8.2' y2='8.2'/></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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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: `<div class="search-bar-input-container">
|
||||
<input class="search-bar-input" type="search" [placeholder]="placeholderText">
|
||||
</div>
|
||||
<button class="button search-bar-cancel">{{ cancelText }}</button>`
|
||||
})
|
||||
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'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
1
src/components/search-bar/test/basic/e2e.js
Normal file
1
src/components/search-bar/test/basic/e2e.js
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
38
src/components/search-bar/test/basic/main.html
Normal file
38
src/components/search-bar/test/basic/main.html
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
<ion-view view-title="Search Bar">
|
||||
|
||||
<ion-content>
|
||||
|
||||
<ion-search-bar></ion-search-bar>
|
||||
|
||||
<ion-list>
|
||||
|
||||
<div class="item">
|
||||
<div class="item-content">
|
||||
<div class="item-title">
|
||||
Item
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item">
|
||||
<div class="item-content">
|
||||
<div class="item-title">
|
||||
Item
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item">
|
||||
<div class="item-content">
|
||||
<div class="item-title">
|
||||
Item
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</ion-list>
|
||||
|
||||
</ion-content>
|
||||
|
||||
</ion-view>
|
||||
20
src/components/search-bar/test/basic/main.js
Normal file
20
src/components/search-bar/test/basic/main.js
Normal file
@@ -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)
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user