UNPKG

@ionic/core

Version:
202 lines (198 loc) • 10.3 kB
import { h } from '../ionic.core.js'; import { c as createColorClasses, d as hostContext } from './chunk-7c632336.js'; import { d as findItemLabel, e as renderHiddenInput } from './chunk-6d7d2f8c.js'; import { d as hapticSelection } from './chunk-81780b86.js'; 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('./chunk-f56eaea8.js')).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 ":host{-webkit-box-sizing:content-box!important;box-sizing:content-box!important;display:inline-block;outline:none;contain:content;cursor:pointer;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:2}:host(.ion-focused) input{border:2px solid #5e9ed6}:host(.toggle-disabled){pointer-events:none}button{left:0;top:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;position:absolute;width:100%;height:100%;border:0;background:transparent;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;outline:none}:host-context([dir=rtl]) button{right:0}button::-moz-focus-inner{border:0}:host{--background:var(--ion-item-background,var(--ion-background-color,#fff));--background-checked:var(--ion-color-primary,#3880ff);--handle-background:var(--ion-item-background,var(--ion-background-color,#fff));--handle-background-checked:var(--ion-item-background,var(--ion-background-color,#fff));-webkit-box-sizing:content-box;box-sizing:content-box;position:relative;width:51px;height:32px;contain:strict}:host(.ion-color.toggle-checked) .toggle-icon{background:var(--ion-color-base)}:host(.ion-color.toggle-checked) .toggle-inner{background:var(--ion-color-contrast)}.toggle-icon{border-radius:16px;display:block;position:relative;width:100%;height:100%;-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-transition:background-color .3s;transition:background-color .3s;background-color:var(--ion-color-step-50,#f2f2f2);overflow:hidden;pointer-events:none}.toggle-icon:before{right:2px;bottom:2px;border-radius:16px;-webkit-transform:scaleX(1);transform:scaleX(1);-webkit-transition:-webkit-transform .3s;transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;background:var(--background);content:\"\"}.toggle-icon:before,.toggle-inner{left:2px;top:2px;position:absolute}.toggle-inner{border-radius:14px;width:28px;height:28px;-webkit-transition:width .12s ease-in-out 80ms,left .11s ease-in-out 80ms,right .11s ease-in-out 80ms,-webkit-transform .3s;transition:width .12s ease-in-out 80ms,left .11s ease-in-out 80ms,right .11s ease-in-out 80ms,-webkit-transform .3s;transition:transform .3s,width .12s ease-in-out 80ms,left .11s ease-in-out 80ms,right .11s ease-in-out 80ms;transition:transform .3s,width .12s ease-in-out 80ms,left .11s ease-in-out 80ms,right .11s ease-in-out 80ms,-webkit-transform .3s;background:var(--handle-background);-webkit-box-shadow:0 3px 12px rgba(0,0,0,.16),0 3px 1px rgba(0,0,0,.1);box-shadow:0 3px 12px rgba(0,0,0,.16),0 3px 1px rgba(0,0,0,.1);will-change:transform;contain:strict}:host-context([dir=rtl]) .toggle-inner{right:2px}:host(.toggle-checked) .toggle-icon{background:var(--background-checked)}:host(.toggle-activated) .toggle-icon:before,:host(.toggle-checked) .toggle-icon:before{-webkit-transform:scale3d(0,0,0);transform:scale3d(0,0,0)}:host(.toggle-checked) .toggle-inner{-webkit-transform:translate3d(19px,0,0);transform:translate3d(19px,0,0);background:var(--handle-background-checked)}:host([dir=rtl].toggle-checked) .toggle-inner{-webkit-transform:translate3d(calc(-1 * 19px),0,0);transform:translate3d(calc(-1 * 19px),0,0)}:host(.toggle-activated.toggle-checked) .toggle-inner:before{-webkit-transform:scale3d(0,0,0);transform:scale3d(0,0,0)}:host(.toggle-activated) .toggle-inner{width:34px}:host(.toggle-activated.toggle-checked) .toggle-inner{left:-4px}:host([dir=rtl].toggle-activated.toggle-checked) .toggle-inner{right:-4px}:host(.toggle-disabled){opacity:.3}:host(.in-item[slot]){margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:16px;padding-right:8px;padding-top:6px;padding-bottom:5px}\@supports ((-webkit-margin-start:0) or (margin-inline-start:0)) or (-webkit-margin-start:0){:host(.in-item[slot]){padding-left:unset;padding-right:unset;-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:8px;padding-inline-end:8px}}:host(.in-item[slot=start]){padding-left:0;padding-right:16px;padding-top:6px;padding-bottom:5px}\@supports ((-webkit-margin-start:0) or (margin-inline-start:0)) or (-webkit-margin-start:0){:host(.in-item[slot=start]){padding-left:unset;padding-right:unset;-webkit-padding-start:0;padding-inline-start:0;-webkit-padding-end:16px;padding-inline-end:16px}}"; } static get styleMode() { return "ios"; } } 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; export { Toggle as IonToggle };