UNPKG

@universal-material/web

Version:
155 lines 5.08 kB
import { __decorate } from "tslib"; import { html, LitElement, nothing } from 'lit'; import { property, query } from 'lit/decorators.js'; import { styles as baseStyles } from '../base.styles.js'; import { redispatchEvent } from '../events/redispatch-event.js'; import { styles } from './selection-control.styles.js'; import '../../ripple/ripple.js'; export const isActivationClick = (event) => { // Event must start at the event target. if (event.currentTarget !== event.target) { return false; } // Event must not be retargeted from shadowRoot. if (event.composedPath()[0] !== event.target) { return false; } // Target must not be disabled; this should only occur for a synthetically // dispatched click. if (event.target.disabled) { return false; } // This is an activation if the event should not be squelched. return !squelchEvent(event); }; // TODO(https://bugzilla.mozilla.org/show_bug.cgi?id=1804576) // Remove when Firefox bug is addressed. const squelchEvent = (event) => { const squelched = isSquelchingEvents; if (squelched) { event.preventDefault(); event.stopImmediatePropagation(); } squelchEventsForMicrotask(); return squelched; }; // Ignore events for one microtask only. let isSquelchingEvents = false; const squelchEventsForMicrotask = async () => { isSquelchingEvents = true; // Need to pause for just one microtask. /* eslint-disable @typescript-eslint/await-thenable */ await null; isSquelchingEvents = false; }; export class UmSelectionControl extends LitElement { static { this.styles = [baseStyles, styles]; } static { this.formAssociated = true; } static { this.shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true, }; } get form() { return this.elementInternals.form; } focus(options) { this.input.focus(options); } #checked; get checked() { return this.input ? this.input.checked : this.#checked; } set checked(checked) { this.#checked = checked; if (this.input) { this.input.checked = checked; } this.elementInternals.setFormValue(checked ? this.value : null); } constructor() { super(); this.name = ''; this.disabled = false; this.#checked = false; this.inputType = 'checkbox'; this.renderRipple = true; this.inputDescribedById = undefined; this.inputLabelledById = undefined; /** * The element value to use in form submission when checked. */ this.value = 'on'; this._checkedAttribute = false; this.elementInternals = this.attachInternals(); } firstUpdated(changedProperties) { super.firstUpdated(changedProperties); this.input.checked = this.#checked; } connectedCallback() { super.connectedCallback(); this.addEventListener('click', this._handleClick); } disconnectedCallback() { super.disconnectedCallback(); this.removeEventListener('click', this._handleClick); } render() { const ripple = html ` <u-ripple ?disabled=${this.disabled} @click=${this.#handleRippleClick}></u-ripple> `; return html ` <div class="container"> ${this.renderRipple ? ripple : nothing} <input id="input" type=${this.inputType} class="focus-ring" .checked=${this._checkedAttribute} .disabled=${this.disabled} aria-labelledby="${this.inputLabelledById || nothing}" aria-describedby="${this.inputDescribedById || nothing}" @input=${this.#handleInput} @change=${this.#handleChange} /> <div class="indicator-container">${this.renderIndicator()}</div> </div> `; } #handleInput(event) { const target = event.target; this.checked = target.checked; // <input> 'input' event bubbles and is composed, don't re-dispatch it. } #handleChange(event) { // <input> 'change' event is not composed, re-dispatch it. redispatchEvent(this, event); } #handleRippleClick(e) { e.preventDefault(); this.input.click(); } _handleClick(e) { if (isActivationClick(e)) { this.input.click(); } } } __decorate([ property({ reflect: true }) ], UmSelectionControl.prototype, "name", void 0); __decorate([ property({ type: Boolean, reflect: true }) ], UmSelectionControl.prototype, "disabled", void 0); __decorate([ query('input') ], UmSelectionControl.prototype, "input", void 0); __decorate([ property() ], UmSelectionControl.prototype, "value", void 0); __decorate([ property({ type: Boolean }) ], UmSelectionControl.prototype, "checked", null); __decorate([ property({ type: Boolean, attribute: 'checked' }) ], UmSelectionControl.prototype, "_checkedAttribute", void 0); //# sourceMappingURL=selection-control.js.map