mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-17 18:54:11 +08:00
fix(toggle): finish it
This commit is contained in:
1
packages/core/src/components.d.ts
vendored
1
packages/core/src/components.d.ts
vendored
@ -3102,6 +3102,7 @@ declare global {
|
|||||||
mode?: string,
|
mode?: string,
|
||||||
color?: string,
|
color?: string,
|
||||||
|
|
||||||
|
toggle?: any,
|
||||||
checked?: boolean,
|
checked?: boolean,
|
||||||
disabled?: boolean,
|
disabled?: boolean,
|
||||||
value?: string
|
value?: string
|
||||||
|
@ -63,7 +63,7 @@ export class Gesture {
|
|||||||
}
|
}
|
||||||
this.hasPress = (types.indexOf('press') > -1);
|
this.hasPress = (types.indexOf('press') > -1);
|
||||||
|
|
||||||
this.enabledChange(true);
|
this.enabledChange(this.enabled);
|
||||||
if (this.pan || this.hasPress) {
|
if (this.pan || this.hasPress) {
|
||||||
Context.dom.write(() => {
|
Context.dom.write(() => {
|
||||||
applyStyles(getElementReference(this.el, this.attachTo), GESTURE_INLINE_STYLES);
|
applyStyles(getElementReference(this.el, this.attachTo), GESTURE_INLINE_STYLES);
|
||||||
@ -78,9 +78,6 @@ export class Gesture {
|
|||||||
|
|
||||||
@PropDidChange('enabled')
|
@PropDidChange('enabled')
|
||||||
enabledChange(isEnabled: boolean) {
|
enabledChange(isEnabled: boolean) {
|
||||||
if (!this.gesture) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.pan || this.hasPress) {
|
if (this.pan || this.hasPress) {
|
||||||
Context.enableListener(this, 'touchstart', isEnabled, this.attachTo);
|
Context.enableListener(this, 'touchstart', isEnabled, this.attachTo);
|
||||||
Context.enableListener(this, 'mousedown', isEnabled, this.attachTo);
|
Context.enableListener(this, 'mousedown', isEnabled, this.attachTo);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, Event, EventEmitter, Listen, Prop, PropDidChange } from '@stencil/core';
|
import { Component, Event, EventEmitter, Listen, Method, Prop, PropDidChange, State } from '@stencil/core';
|
||||||
import { BooleanInputComponent, GestureDetail } from '../../index';
|
import { BooleanInputComponent, GestureDetail } from '../../index';
|
||||||
|
|
||||||
|
|
||||||
@ -14,42 +14,113 @@ import { BooleanInputComponent, GestureDetail } from '../../index';
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
export class Toggle implements BooleanInputComponent {
|
export class Toggle implements BooleanInputComponent {
|
||||||
|
|
||||||
private toggleId: string;
|
private toggleId: string;
|
||||||
private labelId: string;
|
private labelId: string;
|
||||||
private styleTmr: any;
|
private styleTmr: any;
|
||||||
|
private gestureConfig: any;
|
||||||
|
private startX: number;
|
||||||
|
|
||||||
activated: boolean = false;
|
|
||||||
hasFocus: boolean = false;
|
hasFocus: boolean = false;
|
||||||
startX: number;
|
|
||||||
|
|
||||||
@Event() ionChange: EventEmitter;
|
@State() activated: boolean = false;
|
||||||
@Event() ionStyle: EventEmitter;
|
|
||||||
@Event() ionFocus: EventEmitter;
|
|
||||||
@Event() ionBlur: EventEmitter;
|
|
||||||
|
|
||||||
@Prop() color: string;
|
@Prop() color: string;
|
||||||
@Prop() mode: string;
|
@Prop() mode: string;
|
||||||
|
|
||||||
@Prop({ mutable: true }) checked: boolean = false;
|
@Prop({ mutable: true }) checked: boolean = false;
|
||||||
@Prop({ mutable: true }) disabled: boolean = false;
|
|
||||||
@Prop({ mutable: true }) value: string;
|
|
||||||
|
|
||||||
|
|
||||||
protected ionViewWillLoad() {
|
|
||||||
this.emitStyle();
|
|
||||||
}
|
|
||||||
|
|
||||||
@PropDidChange('checked')
|
@PropDidChange('checked')
|
||||||
checkedChanged(val: boolean) {
|
checkedChanged(val: boolean) {
|
||||||
this.ionChange.emit({ checked: val });
|
this.ionChange.emit({ checked: val });
|
||||||
this.emitStyle();
|
this.emitStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Prop({ mutable: true }) disabled: boolean = false;
|
||||||
@PropDidChange('disabled')
|
@PropDidChange('disabled')
|
||||||
disabledChanged() {
|
disabledChanged() {
|
||||||
this.emitStyle();
|
this.emitStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: value is broken
|
||||||
|
@Prop({ mutable: true }) value: string;
|
||||||
|
|
||||||
|
@Event() ionChange: EventEmitter;
|
||||||
|
@Event() ionStyle: EventEmitter;
|
||||||
|
@Event() ionFocus: EventEmitter;
|
||||||
|
@Event() ionBlur: EventEmitter;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.gestureConfig = {
|
||||||
|
'onStart': this.onDragStart.bind(this),
|
||||||
|
'onMove': this.onDragMove.bind(this),
|
||||||
|
'onEnd': this.onDragEnd.bind(this),
|
||||||
|
'onPress': this.toggle.bind(this),
|
||||||
|
'gestureName': 'toggle',
|
||||||
|
'gesturePriority': 30,
|
||||||
|
'type': 'pan,press',
|
||||||
|
'direction': 'x',
|
||||||
|
'threshold': 0,
|
||||||
|
'attachTo': 'parent'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ionViewWillLoad() {
|
||||||
|
this.emitStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Listen('keydown.space')
|
||||||
|
onSpace(ev: KeyboardEvent) {
|
||||||
|
this.toggle();
|
||||||
|
ev.stopPropagation();
|
||||||
|
ev.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Method()
|
||||||
|
toggle() {
|
||||||
|
if (!this.disabled) {
|
||||||
|
this.checked = !this.checked;
|
||||||
|
this.fireFocus();
|
||||||
|
}
|
||||||
|
return this.checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private onDragStart(detail: GestureDetail) {
|
||||||
|
this.startX = detail.startX;
|
||||||
|
this.fireFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private onDragMove(detail: GestureDetail) {
|
||||||
|
const currentX = detail.currentX;
|
||||||
|
if (this.checked) {
|
||||||
|
if (currentX + 15 < this.startX) {
|
||||||
|
this.checked = false;
|
||||||
|
this.activated = true;
|
||||||
|
this.startX = currentX;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (currentX - 15 > this.startX) {
|
||||||
|
this.checked = true;
|
||||||
|
this.activated = (currentX < this.startX + 5);
|
||||||
|
this.startX = currentX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private onDragEnd(detail: GestureDetail) {
|
||||||
|
const delta = detail.deltaX;
|
||||||
|
if (this.checked) {
|
||||||
|
if (delta < -4) {
|
||||||
|
this.checked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (delta > 4) {
|
||||||
|
this.checked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.activated = false;
|
||||||
|
this.startX = null;
|
||||||
|
this.fireBlur();
|
||||||
|
}
|
||||||
|
|
||||||
private emitStyle() {
|
private emitStyle() {
|
||||||
clearTimeout(this.styleTmr);
|
clearTimeout(this.styleTmr);
|
||||||
|
|
||||||
@ -63,65 +134,6 @@ export class Toggle implements BooleanInputComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private canStart() {
|
|
||||||
return !this.disabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private onDragStart(detail: GestureDetail) {
|
|
||||||
this.startX = detail.startX;
|
|
||||||
this.fireFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private onDragMove(detail: GestureDetail) {
|
|
||||||
if (this.checked) {
|
|
||||||
if (detail.currentX + 15 < this.startX) {
|
|
||||||
this.checked = false;
|
|
||||||
this.activated = true;
|
|
||||||
this.startX = detail.currentX;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (detail.currentX - 15 > this.startX) {
|
|
||||||
this.checked = true;
|
|
||||||
this.activated = (detail.currentX < this.startX + 5);
|
|
||||||
this.startX = detail.currentX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private onDragEnd(detail: GestureDetail) {
|
|
||||||
if (this.checked) {
|
|
||||||
if (detail.startX + 4 > detail.currentX) {
|
|
||||||
this.checked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (detail.startX - 4 < detail.currentX) {
|
|
||||||
this.checked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.activated = false;
|
|
||||||
this.fireBlur();
|
|
||||||
this.startX = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Listen('keydown.space')
|
|
||||||
onSpace(ev: KeyboardEvent) {
|
|
||||||
this.toggle();
|
|
||||||
ev.stopPropagation();
|
|
||||||
ev.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
toggle() {
|
|
||||||
if (!this.disabled) {
|
|
||||||
this.checked = !this.checked;
|
|
||||||
this.fireFocus();
|
|
||||||
}
|
|
||||||
return this.checked;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fireFocus() {
|
fireFocus() {
|
||||||
if (!this.hasFocus) {
|
if (!this.hasFocus) {
|
||||||
this.hasFocus = true;
|
this.hasFocus = true;
|
||||||
@ -130,7 +142,6 @@ export class Toggle implements BooleanInputComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fireBlur() {
|
fireBlur() {
|
||||||
if (this.hasFocus) {
|
if (this.hasFocus) {
|
||||||
this.hasFocus = false;
|
this.hasFocus = false;
|
||||||
@ -139,7 +150,7 @@ export class Toggle implements BooleanInputComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hostData() {
|
protected hostData() {
|
||||||
return {
|
return {
|
||||||
class: {
|
class: {
|
||||||
'toggle-activated': this.activated,
|
'toggle-activated': this.activated,
|
||||||
@ -151,19 +162,9 @@ export class Toggle implements BooleanInputComponent {
|
|||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
return (
|
return (
|
||||||
<ion-gesture {...{
|
<ion-gesture {...this.gestureConfig}
|
||||||
'canStart': this.canStart.bind(this),
|
enabled={!this.disabled}
|
||||||
'onStart': this.onDragStart.bind(this),
|
>
|
||||||
'onMove': this.onDragMove.bind(this),
|
|
||||||
'onEnd': this.onDragEnd.bind(this),
|
|
||||||
'onPress': this.toggle.bind(this),
|
|
||||||
'gestureName': 'toggle',
|
|
||||||
'gesturePriority': 30,
|
|
||||||
'type': 'pan,press',
|
|
||||||
'direction': 'x',
|
|
||||||
'threshold': 0,
|
|
||||||
'attachTo': 'parent'
|
|
||||||
}}>
|
|
||||||
<div class='toggle-icon'>
|
<div class='toggle-icon'>
|
||||||
<div class='toggle-inner'></div>
|
<div class='toggle-inner'></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,7 +4,7 @@ exports.config = {
|
|||||||
generateWWW: false,
|
generateWWW: false,
|
||||||
bundles: [
|
bundles: [
|
||||||
{ components: ['ion-animation-controller'] },
|
{ components: ['ion-animation-controller'] },
|
||||||
{ components: ['ion-app', 'ion-content', 'ion-footer', 'ion-header', 'ion-navbar', 'ion-page', 'ion-title', 'ion-toolbar'] },
|
{ components: ['ion-app', 'ion-content', 'ion-scroll', 'ion-footer', 'ion-header', 'ion-navbar', 'ion-page', 'ion-title', 'ion-toolbar'] },
|
||||||
{ components: ['ion-action-sheet', 'ion-action-sheet-controller'] },
|
{ components: ['ion-action-sheet', 'ion-action-sheet-controller'] },
|
||||||
{ components: ['ion-alert', 'ion-alert-controller'] },
|
{ components: ['ion-alert', 'ion-alert-controller'] },
|
||||||
{ components: ['ion-avatar', 'ion-badge', 'ion-thumbnail'] },
|
{ components: ['ion-avatar', 'ion-badge', 'ion-thumbnail'] },
|
||||||
@ -15,7 +15,7 @@ exports.config = {
|
|||||||
{ components: ['ion-chip', 'ion-chip-button'] },
|
{ components: ['ion-chip', 'ion-chip-button'] },
|
||||||
{ components: ['ion-datetime', 'ion-picker', 'ion-picker-column', 'ion-picker-controller'] },
|
{ components: ['ion-datetime', 'ion-picker', 'ion-picker-column', 'ion-picker-controller'] },
|
||||||
{ components: ['ion-fab', 'ion-fab-button', 'ion-fab-list'] },
|
{ components: ['ion-fab', 'ion-fab-button', 'ion-fab-list'] },
|
||||||
{ components: ['ion-gesture', 'ion-scroll'], priority: 'low' },
|
{ components: ['ion-gesture'], priority: 'low' },
|
||||||
{ components: ['ion-grid', 'ion-row', 'ion-col'] },
|
{ components: ['ion-grid', 'ion-row', 'ion-col'] },
|
||||||
{ components: ['ion-item', 'ion-item-divider', 'ion-label', 'ion-list', 'ion-list-header', 'ion-skeleton-text'] },
|
{ components: ['ion-item', 'ion-item-divider', 'ion-label', 'ion-list', 'ion-list-header', 'ion-skeleton-text'] },
|
||||||
{ components: ['ion-item-sliding', 'ion-item-options', 'ion-item-option'] },
|
{ components: ['ion-item-sliding', 'ion-item-options', 'ion-item-option'] },
|
||||||
|
Reference in New Issue
Block a user