license import '@material/mwc-ripple/mwc-ripple' ; import { ariaProperty } from '@material/mwc-base/aria-property' ; import { FormElement } from '@material/mwc-base/form-element' ; import { Ripple } from '@material/mwc-ripple/mwc-ripple' ; import { RippleHandlers } from '@material/mwc-ripple/ripple-handlers' ; import { MDCSwitchAdapter , MDCSwitchState } from '@material/switch/adapter' ; import { MDCSwitchFoundation } from '@material/switch/foundation' ; import { html , TemplateResult } from 'lit' ; import { eventOptions , property , query , queryAsync , state } from 'lit/decorators.js' ; import { ClassInfo , classMap } from 'lit/directives/class-map.js' ; import { ifDefined } from 'lit/directives/if-defined.js' ; export class SwitchBase extends FormElement implements MDCSwitchState { @ property ( { type : Boolean } ) processing = false ; @ property ( { type : Boolean } ) selected = false ; soyPrefixAttribute @ ariaProperty @ property ( { type : String , attribute : 'aria-label' } ) override ariaLabel = '' ; soyPrefixAttribute @ ariaProperty @ property ( { type : String , attribute : 'aria-labelledby' } ) ariaLabelledBy = '' ; @ queryAsync ( 'mwc-ripple' ) override readonly ripple ! : Promise < Ripple | null > ; @ state ( ) protected shouldRenderRipple = false ; protected rippleHandlers = new RippleHandlers ( ( ) => { this . shouldRenderRipple = true ; return this . ripple ; } ) ; @ property ( { type : String , reflect : true } ) name = '' ; @ property ( { type : String } ) value = 'on' ; @ query ( 'input' ) protected readonly formElement ! : HTMLElement ; protected setFormData ( formData ) { if ( this . name && this . selected ) { formData . append ( this . name , this . value ) ; } } @ query ( '.mdc-switch' ) protected readonly mdcRoot ! : HTMLElement ; protected readonly mdcFoundationClass = MDCSwitchFoundation ; protected mdcFoundation ? : MDCSwitchFoundation ; override click ( ) { if ( this . disabled ) { return ; } this . mdcRoot ?. focus ( ) ; this . mdcRoot ?. click ( ) ; } soyTemplate protected override render ( ) { return html `
      <button
        type="button"
        class="mdc-switch ${ classMap ( this . getRenderClasses ( ) ) }"
        role="switch"
        aria-checked="${ this . selected }"
        aria-label="${ ifDefined ( this . ariaLabel || undefined ) }"
        aria-labelledby="${ ifDefined ( this . ariaLabelledBy || undefined ) }"
        .disabled=${ this . disabled }
        @click=${ this . handleClick }
        @focus="${ this . handleFocus }"
        @blur="${ this . handleBlur }"
        @pointerdown="${ this . handlePointerDown }"
        @pointerup="${ this . handlePointerUp }"
        @pointerenter="${ this . handlePointerEnter }"
        @pointerleave="${ this . handlePointerLeave }"
      >
        <div class="mdc-switch__track"></div>
        <div class="mdc-switch__handle-track">
          ${ this . renderHandle ( ) }
        </div>
      </button>

      <input
        type="checkbox"
        aria-hidden="true"
        name="${ this . name }"
        .checked=${ this . selected }
        .value=${ this . value }
      >
    ` ; } soyTemplate protected getRenderClasses ( ) { return { 'mdc-switch--processing' : this . processing , 'mdc-switch--selected' : this . selected , 'mdc-switch--unselected' : ! this . selected , } ; } soyTemplate protected renderHandle ( ) { return html `
      <div class="mdc-switch__handle">
        ${ this . renderShadow ( ) }
        ${ this . renderRipple ( ) }
        <div class="mdc-switch__icons">
          ${ this . renderOnIcon ( ) }
          ${ this . renderOffIcon ( ) }
        </div>
      </div>
    ` ; } soyTemplate protected renderShadow ( ) { return html `
      <div class="mdc-switch__shadow">
        <div class="mdc-elevation-overlay"></div>
      </div>
    ` ; } soyTemplate protected renderRipple ( ) { if ( this . shouldRenderRipple ) { return html `
        <div class="mdc-switch__ripple">
          <mwc-ripple
            internalUseStateLayerCustomProperties
            .disabled="${ this . disabled }"
            unbounded>
          </mwc-ripple>
        </div>
      ` ; } else { return html `` ; } } soyTemplate protected renderOnIcon ( ) { return html `
      <svg class="mdc-switch__icon mdc-switch__icon--on" viewBox="0 0 24 24">
        <path d="M19.69,5.23L8.96,15.96l-4.23-4.23L2.96,13.5l6,6L21.46,7L19.69,5.23z" />
      </svg>
    ` ; } soyTemplate protected renderOffIcon ( ) { return html `
      <svg class="mdc-switch__icon mdc-switch__icon--off" viewBox="0 0 24 24">
        <path d="M20 13H4v-2h16v2z" />
      </svg>
    ` ; } protected handleClick ( ) { this . mdcFoundation ?. handleClick ( ) ; } protected handleFocus ( ) { this . rippleHandlers . startFocus ( ) ; } protected handleBlur ( ) { this . rippleHandlers . endFocus ( ) ; } @ eventOptions ( { passive : true } ) protected handlePointerDown ( event ) { ( event . target as HTMLElement ) . setPointerCapture ( event . pointerId ) ; this . rippleHandlers . startPress ( event ) ; } protected handlePointerUp ( ) { this . rippleHandlers . endPress ( ) ; } protected handlePointerEnter ( ) { this . rippleHandlers . startHover ( ) ; } protected handlePointerLeave ( ) { this . rippleHandlers . endHover ( ) ; } protected createAdapter ( ) { return { state : this } ; } }