@ionic/core
Version:
Base components for Ionic
197 lines (196 loc) • 5.97 kB
JavaScript
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;