mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
switch
This commit is contained in:
@@ -45,7 +45,8 @@
|
||||
@import
|
||||
"../checkbox/extensions/ios",
|
||||
"../list/extensions/ios",
|
||||
"../item/extensions/ios";
|
||||
"../item/extensions/ios",
|
||||
"../switch/extensions/ios";
|
||||
|
||||
|
||||
// Icons
|
||||
|
||||
38
src/components/switch/extensions/ios.scss
Normal file
38
src/components/switch/extensions/ios.scss
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
// iOS Switch
|
||||
// --------------------------------------------------
|
||||
|
||||
$switch-ios-width: 52px !default;
|
||||
$switch-ios-height: 32px !default;
|
||||
$switch-ios-slider-off-background: #fff !default;
|
||||
$switch-ios-slider-on-background: #4cd964 !default;
|
||||
$switch-ios-toggle-on-background: #fff !default;
|
||||
|
||||
|
||||
.switch-ios {
|
||||
|
||||
.switch-toggle {
|
||||
width: $switch-ios-width;
|
||||
height: $switch-ios-height;
|
||||
border-radius: $switch-ios-height / 2;
|
||||
|
||||
background: #e5e5e5;
|
||||
}
|
||||
|
||||
.switch-toggle:before {
|
||||
background: $switch-ios-slider-off-background;
|
||||
}
|
||||
|
||||
.switch-toggle:after {
|
||||
box-shadow: 0 2px 5px rgba(0,0,0,.4);
|
||||
}
|
||||
|
||||
&[aria-checked=true] .switch-toggle {
|
||||
background: $switch-ios-slider-on-background;
|
||||
}
|
||||
|
||||
&[aria-checked=true] .switch-toggle:before {
|
||||
@include scale(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,71 +1,64 @@
|
||||
import {NgElement, Component, Template} from 'angular2/angular2';
|
||||
import {Component, Template, NgElement, PropertySetter} from 'angular2/angular2'
|
||||
import {ComponentConfig} from 'ionic2/config/component-config'
|
||||
|
||||
export let SwitchConfig = new ComponentConfig('switch')
|
||||
|
||||
@Component({
|
||||
selector: 'ion-switch',
|
||||
bind: {
|
||||
checked: 'checked'
|
||||
}
|
||||
},
|
||||
events: {
|
||||
'click': 'onClick()'
|
||||
},
|
||||
services: [SwitchConfig]
|
||||
})
|
||||
@Template({
|
||||
inline: `
|
||||
<div class="item item-switch">
|
||||
<div ng-transclude></div>
|
||||
<label class="switch">
|
||||
<input type="checkbox" (click)="onClick(input)" #input>
|
||||
<div class="track">
|
||||
<div class="handle"></div>
|
||||
<div class="item-content">
|
||||
|
||||
<div class="item-title">
|
||||
<content></content>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
`
|
||||
|
||||
<div class="item-media media-switch">
|
||||
<div class="switch-toggle"></div>
|
||||
</div>
|
||||
|
||||
</div>`
|
||||
})
|
||||
export class Switch {
|
||||
constructor(
|
||||
@NgElement() el : NgElement,
|
||||
@EventEmitter('change') emitChange: Function
|
||||
configFactory: SwitchConfig,
|
||||
element: NgElement,
|
||||
@PropertySetter('attr.role') setAriaRole: Function,
|
||||
@PropertySetter('attr.aria-checked') setAriaChecked: Function,
|
||||
@PropertySetter('attr.aria-invalid') setAriaInvalid: Function,
|
||||
@PropertySetter('attr.aria-disabled') setAriaDisabled: Function
|
||||
) {
|
||||
this.ngElement = el;
|
||||
this.emitChange = emitChange;
|
||||
this.domElement = element.domElement
|
||||
this.domElement.classList.add('item')
|
||||
this.config = configFactory.create(this)
|
||||
|
||||
setAriaRole('checkbox')
|
||||
setAriaInvalid('false')
|
||||
setAriaDisabled('false')
|
||||
|
||||
this.setAriaRole = setAriaRole
|
||||
this.setAriaChecked = setAriaChecked
|
||||
this.setAriaInvalid = setAriaInvalid
|
||||
this.setAriaDisabled = setAriaDisabled
|
||||
}
|
||||
|
||||
set checked(checked) {
|
||||
this._checked = checked
|
||||
this.setAriaChecked(checked)
|
||||
}
|
||||
get checked() {
|
||||
return this._checked
|
||||
}
|
||||
onClick() {
|
||||
this.emitChange(this.checked);
|
||||
this.checked = !this.checked;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
<ion-view>
|
||||
|
||||
<aside/>
|
||||
|
||||
<tabs>
|
||||
<my-page-3 title="My Page 3" />
|
||||
<tab>
|
||||
static content
|
||||
</tab>
|
||||
</tabs>
|
||||
|
||||
</ion-view>
|
||||
|
||||
@Component({
|
||||
selector: 'my-page-3',
|
||||
defaults: {
|
||||
title: 'My Page 3',
|
||||
icon: 'Super icon'
|
||||
},
|
||||
})
|
||||
@Template( {
|
||||
url: 'my-page-3.html'
|
||||
})
|
||||
@Route({
|
||||
name: 'my-page-3'
|
||||
})
|
||||
class MyPage3 extends TabComponent {
|
||||
|
||||
}
|
||||
|
||||
|
||||
1) Sign in page, 1 view
|
||||
2) Navigate to a tabs view, 3 tabs, all have the same side menu
|
||||
3) Tab 2, page 2 navigates to nested tabs with it's own side menu
|
||||
|
||||
*/
|
||||
|
||||
@@ -1,214 +1,74 @@
|
||||
/**
|
||||
* Switch
|
||||
* --------------------------------------------------
|
||||
*/
|
||||
|
||||
.item-switch{
|
||||
// Switch
|
||||
// --------------------------------------------------
|
||||
|
||||
}
|
||||
.switch{
|
||||
input{
|
||||
display:none;
|
||||
}
|
||||
.track{
|
||||
width:50px;
|
||||
height:50px;
|
||||
background:black;
|
||||
}
|
||||
input:checked+.track{
|
||||
background:blue;
|
||||
}
|
||||
$switch-padding-right: 15px !default;
|
||||
$switch-width: 52px !default;
|
||||
$switch-height: 32px !default;
|
||||
$switch-border-width: 2px !default;
|
||||
$switch-slider-off-background: #ccc !default;
|
||||
$switch-slider-on-background: #387ef5 !default;
|
||||
$switch-toggle-on-background: #fff !default;
|
||||
|
||||
|
||||
.switch .item-media {
|
||||
padding-right: $switch-padding-right;
|
||||
}
|
||||
|
||||
//.item-toggle {
|
||||
// pointer-events: none;
|
||||
//}
|
||||
//
|
||||
//.toggle {
|
||||
// // set the color defaults
|
||||
// @include toggle-style($toggle-on-default-border, $toggle-on-default-bg);
|
||||
//
|
||||
// position: relative;
|
||||
// display: inline-block;
|
||||
// pointer-events: auto;
|
||||
// margin: -$toggle-hit-area-expansion;
|
||||
// padding: $toggle-hit-area-expansion;
|
||||
//
|
||||
// &.dragging {
|
||||
// .handle {
|
||||
// background-color: $toggle-handle-dragging-bg-color !important;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
//
|
||||
//.toggle {
|
||||
// &.toggle-light {
|
||||
// @include toggle-style($toggle-on-light-border, $toggle-on-light-bg);
|
||||
// }
|
||||
// &.toggle-stable {
|
||||
// @include toggle-style($toggle-on-stable-border, $toggle-on-stable-bg);
|
||||
// }
|
||||
// &.toggle-positive {
|
||||
// @include toggle-style($toggle-on-positive-border, $toggle-on-positive-bg);
|
||||
// }
|
||||
// &.toggle-calm {
|
||||
// @include toggle-style($toggle-on-calm-border, $toggle-on-calm-bg);
|
||||
// }
|
||||
// &.toggle-assertive {
|
||||
// @include toggle-style($toggle-on-assertive-border, $toggle-on-assertive-bg);
|
||||
// }
|
||||
// &.toggle-balanced {
|
||||
// @include toggle-style($toggle-on-balanced-border, $toggle-on-balanced-bg);
|
||||
// }
|
||||
// &.toggle-energized {
|
||||
// @include toggle-style($toggle-on-energized-border, $toggle-on-energized-bg);
|
||||
// }
|
||||
// &.toggle-royal {
|
||||
// @include toggle-style($toggle-on-royal-border, $toggle-on-royal-bg);
|
||||
// }
|
||||
// &.toggle-dark {
|
||||
// @include toggle-style($toggle-on-dark-border, $toggle-on-dark-bg);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//.toggle input {
|
||||
// // hide the actual input checkbox
|
||||
// display: none;
|
||||
//}
|
||||
//
|
||||
///* the track appearance when the toggle is "off" */
|
||||
//.toggle .track {
|
||||
// @include transition-timing-function(ease-in-out);
|
||||
// @include transition-duration($toggle-transition-duration);
|
||||
// @include transition-property((background-color, border));
|
||||
//
|
||||
// display: inline-block;
|
||||
// box-sizing: border-box;
|
||||
// width: $toggle-width;
|
||||
// height: $toggle-height;
|
||||
// border: solid $toggle-border-width $toggle-off-border-color;
|
||||
// border-radius: $toggle-border-radius;
|
||||
// background-color: $toggle-off-bg-color;
|
||||
// content: ' ';
|
||||
// cursor: pointer;
|
||||
// pointer-events: none;
|
||||
//}
|
||||
//
|
||||
///* Fix to avoid background color bleeding */
|
||||
///* (occured on (at least) Android 4.2, Asus MeMO Pad HD7 ME173X) */
|
||||
//.platform-android4_2 .toggle .track {
|
||||
// -webkit-background-clip: padding-box;
|
||||
//}
|
||||
//
|
||||
///* the handle (circle) thats inside the toggle's track area */
|
||||
///* also the handle's appearance when it is "off" */
|
||||
//.toggle .handle {
|
||||
// @include transition($toggle-transition-duration cubic-bezier(0, 1.1, 1, 1.1));
|
||||
// @include transition-property((background-color, transform));
|
||||
// position: absolute;
|
||||
// display: block;
|
||||
// width: $toggle-handle-width;
|
||||
// height: $toggle-handle-height;
|
||||
// border-radius: $toggle-handle-radius;
|
||||
// background-color: $toggle-handle-off-bg-color;
|
||||
// top: $toggle-border-width + $toggle-hit-area-expansion;
|
||||
// left: $toggle-border-width + $toggle-hit-area-expansion;
|
||||
// box-shadow: 0 2px 7px rgba(0,0,0,.35), 0 1px 1px rgba(0,0,0,.15);
|
||||
//
|
||||
// &:before {
|
||||
// // used to create a larger (but hidden) hit area to slide the handle
|
||||
// position: absolute;
|
||||
// top: -4px;
|
||||
// left: ( ($toggle-handle-width / 2) * -1) - 8;
|
||||
// padding: ($toggle-handle-height / 2) + 5 ($toggle-handle-width + 7);
|
||||
// content: " ";
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//.toggle input:checked + .track .handle {
|
||||
// // the handle when the toggle is "on"
|
||||
// @include translate3d($toggle-width - $toggle-handle-width - ($toggle-border-width * 2), 0, 0);
|
||||
// background-color: $toggle-handle-on-bg-color;
|
||||
//}
|
||||
//
|
||||
//.item-toggle.active {
|
||||
// box-shadow: none;
|
||||
//}
|
||||
//
|
||||
//.item-toggle,
|
||||
//.item-toggle.item-complex .item-content {
|
||||
// // make sure list item content have enough padding on right to fit the toggle
|
||||
// padding-right: ($item-padding * 3) + $toggle-width;
|
||||
//}
|
||||
//
|
||||
//.item-toggle.item-complex {
|
||||
// padding-right: 0;
|
||||
//}
|
||||
//
|
||||
//.item-toggle .toggle {
|
||||
// // position the toggle to the right within a list item
|
||||
// position: absolute;
|
||||
// top: ($item-padding / 2) + 2;
|
||||
// right: $item-padding;
|
||||
// z-index: $z-index-item-toggle;
|
||||
//}
|
||||
//
|
||||
//.toggle input:disabled + .track {
|
||||
// opacity: .6;
|
||||
//}
|
||||
//
|
||||
//.toggle-small {
|
||||
//
|
||||
// .track {
|
||||
// border: 0;
|
||||
// width: 34px;
|
||||
// height: 15px;
|
||||
// background: #9e9e9e;
|
||||
// }
|
||||
// input:checked + .track {
|
||||
// background: rgba(0,150,137,.5);
|
||||
// }
|
||||
// .handle {
|
||||
// top: 2px;
|
||||
// left: 4px;
|
||||
// width: 21px;
|
||||
// height: 21px;
|
||||
// box-shadow: 0 2px 5px rgba(0,0,0,.25);
|
||||
// }
|
||||
// input:checked + .track .handle {
|
||||
// @include translate3d(16px, 0, 0);
|
||||
// background: rgb(0,150,137);
|
||||
// }
|
||||
// &.item-toggle .toggle {
|
||||
// top: 19px;
|
||||
// }
|
||||
//
|
||||
// .toggle-light {
|
||||
// @include toggle-small-style($toggle-on-light-bg);
|
||||
// }
|
||||
// .toggle-stable {
|
||||
// @include toggle-small-style($toggle-on-stable-bg);
|
||||
// }
|
||||
// .toggle-positive {
|
||||
// @include toggle-small-style($toggle-on-positive-bg);
|
||||
// }
|
||||
// .toggle-calm {
|
||||
// @include toggle-small-style($toggle-on-calm-bg);
|
||||
// }
|
||||
// .toggle-assertive {
|
||||
// @include toggle-small-style($toggle-on-assertive-bg);
|
||||
// }
|
||||
// .toggle-balanced {
|
||||
// @include toggle-small-style($toggle-on-balanced-bg);
|
||||
// }
|
||||
// .toggle-energized {
|
||||
// @include toggle-small-style($toggle-on-energized-bg);
|
||||
// }
|
||||
// .toggle-royal {
|
||||
// @include toggle-small-style($toggle-on-royal-bg);
|
||||
// }
|
||||
// .toggle-dark {
|
||||
// @include toggle-small-style($toggle-on-dark-bg);
|
||||
// }
|
||||
//}
|
||||
.switch-toggle {
|
||||
position: relative;
|
||||
|
||||
width: $switch-width;
|
||||
height: $switch-height;
|
||||
border-radius: $switch-height / 2;
|
||||
|
||||
background: $switch-slider-off-background;
|
||||
}
|
||||
|
||||
.switch-toggle:before {
|
||||
position: absolute;
|
||||
left: $switch-border-width;
|
||||
top: $switch-border-width;
|
||||
|
||||
width: $switch-width - ($switch-border-width * 2);
|
||||
height: $switch-height - ($switch-border-width * 2);
|
||||
border-radius: $switch-height / 2;
|
||||
|
||||
@include transition-duration(300ms);
|
||||
content: ' ';
|
||||
}
|
||||
|
||||
.switch[aria-checked=true] .switch-toggle {
|
||||
background: $switch-slider-on-background;
|
||||
}
|
||||
|
||||
.switch .switch-toggle:after {
|
||||
position: absolute;
|
||||
left: $switch-border-width;
|
||||
top: $switch-border-width;
|
||||
|
||||
width: $switch-height - ($switch-border-width * 2);
|
||||
height: $switch-height - ($switch-border-width * 2);
|
||||
|
||||
border-radius: $switch-height - ($switch-border-width * 2);
|
||||
background: $switch-toggle-on-background;
|
||||
|
||||
@include transition-duration(300ms);
|
||||
|
||||
content: ' ';
|
||||
}
|
||||
|
||||
.switch[aria-checked=true] .switch-toggle:after {
|
||||
@include translate3d(20px,0,0);
|
||||
}
|
||||
|
||||
.switch[aria-disabled=true] {
|
||||
pointer-events: none;
|
||||
opacity: 0.5;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.switch .item-media,
|
||||
.switch .item-content {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,28 @@
|
||||
|
||||
<div class="item switch"
|
||||
role="checkbox"
|
||||
aria-label="Airplane Mode"
|
||||
aria-checked="true"
|
||||
aria-invalid="false">
|
||||
<div class="pane">
|
||||
|
||||
<div class="item-container">
|
||||
<div class="pane-container">
|
||||
|
||||
<div class="item-media"></div>
|
||||
<div class="content" style="background: #efeff4">
|
||||
|
||||
<ion-list>
|
||||
|
||||
<ion-list-header>Some Switches</ion-list-header>
|
||||
|
||||
<ion-switch [checked]="true">
|
||||
Apples
|
||||
</ion-switch>
|
||||
|
||||
<ion-switch>
|
||||
Bananas
|
||||
</ion-switch>
|
||||
|
||||
<ion-switch [disabled]="true">
|
||||
Oranges
|
||||
</ion-switch>
|
||||
|
||||
</ion-list>
|
||||
|
||||
<div class="item-content">
|
||||
Airplane Mode
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
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 {Switch} from 'ionic2/components/switch/switch';
|
||||
import {List} from 'ionic2/components/list/list';
|
||||
|
||||
@Component({ selector: '[ion-app]' })
|
||||
@Template({
|
||||
url: 'main.html',
|
||||
directives: [View, Content, Switch, List]
|
||||
})
|
||||
class IonicApp {
|
||||
constructor() {
|
||||
console.log('IonicApp Start')
|
||||
}
|
||||
}
|
||||
|
||||
bootstrap(IonicApp)
|
||||
|
||||
Reference in New Issue
Block a user