@universal-material/web
Version:
Material web components
155 lines • 5.08 kB
JavaScript
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} =${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}"
=${this.#handleInput}
=${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