@sandlada/mdc
Version:
@sandlada/mdc is an open source component library that follows the Material Design 3 design specifications.
8 lines • 6.41 kB
JavaScript
import{customElement as e}from"../../node_modules/@lit/reactive-element/decorators/custom-element.js";import{property as t}from"../../node_modules/@lit/reactive-element/decorators/property.js";import{query as n}from"../../node_modules/@lit/reactive-element/decorators/query.js";import"../../node_modules/lit/decorators.js";import{html as r,nothing as i}from"../../node_modules/lit-html/lit-html.js";import{LitElement as a}from"../../node_modules/lit-element/lit-element.js";import"../../node_modules/lit/index.js";import{classMap as o}from"../../node_modules/lit-html/directives/class-map.js";import"../../node_modules/lit/directives/class-map.js";import{mixinElementInternals as s}from"../../utils/behaviors/element-internals.js";import{composeMixin as c}from"../../utils/compose-mixin/compose-mixin.js";import l from"../../_virtual/_@oxc-project_runtime@0.144.0/helpers/esm/decorate.js";import{dispatchActivationClick as u,isActivationClick as d}from"../../utils/event/form-label-activation.js";import{mixinFocusRingOptions as f}from"../focus-ring/focus-ring-options.mixin.js";import{mixinRippleOptions as p}from"../ripple/ripple-options.mixin.js";import{getFormState as m,getFormValue as h,mixinFormAssociated as g}from"../../utils/form/form-associated.js";import{createValidator as _,getValidityAnchor as v,mixinConstraintValidation as y}from"../../utils/behaviors/constraint-validation.js";import{CheckboxValidator as b}from"../../utils/behaviors/validators/checkbox-validator.js";import{redispatchEvent as x}from"../../utils/event/redispatch-event.js";import{SwitchStyles as S}from"./switch.style.js";
/**
* @license
* Copyright 2025 Kai-Orion & Sandlada
* SPDX-License-Identifier: MIT
*/
const C=new Set([`Tab`,` `,`Enter`]),w=new Set([` `,`Enter`]),T=[`pointerdown`,`mousedown`,`touchstart`];let E=!1,D=!1;function O(){if(!D){D=!0,document.addEventListener(`keydown`,e=>{e.altKey||e.ctrlKey||e.metaKey||(E=!0)},!0);for(let e of T)document.addEventListener(e,()=>{E=!1},!0)}}let k=class extends c(y,g,s,p,f)(a){static{this.styles=S}static{this.shadowRootOptions={mode:`open`,delegatesFocus:!0}}get focusRingControl(){return this.inputElement??null}focus(){this.inputElement?.focus()}blur(){this.inputElement?.blur()}constructor(){super(),this.selected=!1,this.required=!1,this.value=`on`,this.hideSelectedIcon=!1,this.showUnselectedIcon=!1,this.setAttribute(`role`,`switch`),this.addEventListener(`click`,this.handleClick.bind(this)),O(),this.addEventListener(`focusin`,this.handleFocusIn.bind(this)),this.addEventListener(`focusout`,this.handleFocusOut.bind(this)),this.addEventListener(`keydown`,this.handleVisualKeyDown.bind(this)),this.addEventListener(`pointerenter`,this.handlePointerEnter.bind(this)),this.addEventListener(`pointerleave`,this.handlePointerLeave.bind(this))}connectedCallback(){super.connectedCallback(),this.hasAttribute(`default-selected`)&&(this.selected=!0)}render(){let e=o({selected:this.selected,unselected:!this.selected,disabled:this.disabled,"show-unselected-icon":this.showUnselectedIcon});return r`<div class="${e} switch">${this.renderInput()} <span class="outline" aria-hidden="true"></span> <span class="handle-container">${this.renderRipple()} <span class="handle">${this.hideSelectedIcon?i:this.renderSelectedIcon()} ${this.showUnselectedIcon?this.renderUnselectedIcon():i} </span></span><span class="track" aria-hidden="true"></span> ${this.renderFocusRing()}</div>`}renderInput(){return r`<input id="input" class="touch input" .checked="${this.selected}" type="checkbox" .disabled="${this.disabled}" .required="${this.required}" tabindex="0" aria-hidden="true" ="${this.handleInput}" ="${this.handleChange}">`}renderSelectedIcon(){return r`<slot class="icon icon-selected" name="icon-selected"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9.55 18.2 3.65 12.3 5.275 10.675 9.55 14.95 18.725 5.775 20.35 7.4Z"/></svg></slot>`}renderUnselectedIcon(){return r`<slot class="icon icon-unselected" name="icon-unselected"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6.4 19.2 4.8 17.6 10.4 12 4.8 6.4 6.4 4.8 12 10.4 17.6 4.8 19.2 6.4 13.6 12 19.2 17.6 17.6 19.2 12 13.6Z"/></svg></slot>`}handlePointerEnter(){if(this.disabled)return;let e=this.rippleElement;e&&(e.hovered=!0)}handlePointerLeave(){let e=this.rippleElement;e&&(e.hovered=!1)}handleFocusIn(){this.shouldShowKeyboardVisuals()&&this.queueKeyboardVisualSync(!1)}handleFocusOut(){queueMicrotask(()=>{this.matches(`:focus`)||this.clearKeyboardVisuals()})}handleVisualKeyDown(e){this.disabled||!C.has(e.key)||(E=!0,this.queueKeyboardVisualSync(w.has(e.key)))}shouldShowKeyboardVisuals(){return E||(this.inputElement?.matches(`:focus-visible`)??!1)}queueKeyboardVisualSync(e){queueMicrotask(()=>{if(!this.isConnected||this.disabled||!this.shouldShowKeyboardVisuals())return;let t=this.focusRingElement;t&&!t.focused&&(t.focused=!0);let n=this.rippleElement;n&&!n.focused&&(n.focused=!0),e&&n&&!n.pressed&&n.action.handleClick()})}clearKeyboardVisuals(){let e=this.focusRingElement;e?.focused&&e.close();let t=this.rippleElement;t?.focused&&(t.focused=!1)}updated(e){super.updated(e),this.setAttribute(`aria-checked`,String(this.selected)),this.setAttribute(`aria-disabled`,String(this.disabled)),this.setAttribute(`aria-required`,String(this.required)),this.disabled&&(this.clearKeyboardVisuals(),this.rippleElement&&(this.rippleElement.hovered=!1,this.rippleElement.focused=!1,this.rippleElement.pressed=!1))}handleInput(e){let t=e.target;this.selected=t.checked}handleChange(e){x(this,e)}handleClick(e){!d(e)||!this.inputElement||(this.focus(),u(this.inputElement))}[h](){return this.selected?this.value:null}[m](){return String(this.selected)}formResetCallback(){this.selected=this.hasAttribute(`default-selected`)}formStateRestoreCallback(e){this.selected=e===`true`}[_](){return new b(()=>({checked:this.selected,required:this.required}))}[v](){return this.inputElement}};l([t({type:Boolean,reflect:!0})],k.prototype,`selected`,void 0),l([t({type:Boolean,reflect:!0})],k.prototype,`required`,void 0),l([t({type:String})],k.prototype,`value`,void 0),l([t({type:Boolean,attribute:`hide-selected-icon`})],k.prototype,`hideSelectedIcon`,void 0),l([t({type:Boolean,attribute:`show-unselected-icon`})],k.prototype,`showUnselectedIcon`,void 0),l([n(`#input`)],k.prototype,`inputElement`,void 0),k=l([e(`mdc-switch`)],k);export{k as MDCSwitch};
//# sourceMappingURL=switch.js.map