UNPKG

@ionic/core

Version:
197 lines (196 loc) • 5.97 kB
import { hapticSelection } from '../../utils/haptic'; import { findItemLabel, renderHiddenInput } from '../../utils/helpers'; import { createColorClasses, hostContext } from '../../utils/theme'; export class Toggle { constructor() { this.inputId = `ion-tg-${toggleIds++}`; this.lastDrag = 0; this.activated = false; this.name = this.inputId; this.checked = false; this.disabled = false; this.value = 'on'; this.onFocus = () => { this.ionFocus.emit(); }; this.onBlur = () => { this.ionBlur.emit(); }; } checkedChanged(isChecked) { this.ionChange.emit({ checked: isChecked, value: this.value }); } disabledChanged() { this.emitStyle(); if (this.gesture) { this.gesture.setDisabled(this.disabled); } } componentWillLoad() { this.emitStyle(); } async componentDidLoad() { this.gesture = (await import('../../utils/gesture')).createGesture({ el: this.el, queue: this.queue, gestureName: 'toggle', gesturePriority: 100, threshold: 5, passive: false, onStart: () => this.onStart(), onMove: ev => this.onMove(ev), onEnd: ev => this.onEnd(ev), }); this.disabledChanged(); } componentDidUnload() { if (this.gesture) { this.gesture.destroy(); this.gesture = undefined; } } onClick() { if (this.lastDrag + 300 < Date.now()) { this.checked = !this.checked; } } emitStyle() { this.ionStyle.emit({ 'interactive-disabled': this.disabled, }); } onStart() { this.activated = true; this.setFocus(); } onMove(detail) { if (shouldToggle(this.checked, detail.deltaX, -10)) { this.checked = !this.checked; hapticSelection(); } } onEnd(ev) { this.activated = false; this.lastDrag = Date.now(); ev.event.preventDefault(); ev.event.stopImmediatePropagation(); } getValue() { return this.value || ''; } setFocus() { if (this.buttonEl) { this.buttonEl.focus(); } } hostData() { const { inputId, disabled, checked, activated, color, el } = this; const labelId = inputId + '-lbl'; const label = findItemLabel(el); if (label) { label.id = labelId; } return { 'role': 'checkbox', 'aria-disabled': disabled ? 'true' : null, 'aria-checked': `${checked}`, 'aria-labelledby': labelId, class: Object.assign({}, createColorClasses(color), { 'in-item': hostContext('ion-item', el), 'toggle-activated': activated, 'toggle-checked': checked, 'toggle-disabled': disabled, 'interactive': true }) }; } render() { const value = this.getValue(); renderHiddenInput(true, this.el, this.name, (this.checked ? value : ''), this.disabled); return [ h("div", { class: "toggle-icon" }, h("div", { class: "toggle-inner" })), h("button", { type: "button", onFocus: this.onFocus, onBlur: this.onBlur, disabled: this.disabled, ref: el => this.buttonEl = el }) ]; } static get is() { return "ion-toggle"; } static get encapsulation() { return "shadow"; } static get properties() { return { "activated": { "state": true }, "checked": { "type": Boolean, "attr": "checked", "mutable": true, "watchCallbacks": ["checkedChanged"] }, "color": { "type": String, "attr": "color" }, "disabled": { "type": Boolean, "attr": "disabled", "watchCallbacks": ["disabledChanged"] }, "el": { "elementRef": true }, "mode": { "type": String, "attr": "mode" }, "name": { "type": String, "attr": "name" }, "queue": { "context": "queue" }, "value": { "type": String, "attr": "value" } }; } static get events() { return [{ "name": "ionChange", "method": "ionChange", "bubbles": true, "cancelable": true, "composed": true }, { "name": "ionFocus", "method": "ionFocus", "bubbles": true, "cancelable": true, "composed": true }, { "name": "ionBlur", "method": "ionBlur", "bubbles": true, "cancelable": true, "composed": true }, { "name": "ionStyle", "method": "ionStyle", "bubbles": true, "cancelable": true, "composed": true }]; } static get listeners() { return [{ "name": "click", "method": "onClick" }]; } static get style() { return "/**style-placeholder:ion-toggle:**/"; } static get styleMode() { return "/**style-id-placeholder:ion-toggle:**/"; } } function shouldToggle(checked, deltaX, margin) { const isRTL = document.dir === 'rtl'; if (checked) { return (!isRTL && (margin > deltaX)) || (isRTL && (-margin < deltaX)); } else { return (!isRTL && (-margin < deltaX)) || (isRTL && (margin > deltaX)); } } let toggleIds = 0;