blob: 9b1ec531512e41c9859fe3ff9d3f482d22d8f7bd [file] [log] [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.js';
import type {CrToggleElement} from 'chrome://resources/cr_elements/cr_toggle/cr_toggle.js';
import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js';
import {getCss} from './toggle_row.css.js';
import {getHtml} from './toggle_row.html.js';
/**
* An extensions-toggle-row provides a way of having a clickable row that can
* modify a cr-toggle, by leveraging the native <label> functionality. It uses
* a hidden native <input type="checkbox"> to achieve this.
*/
export interface ExtensionsToggleRowElement {
$: {
crToggle: CrToggleElement,
label: HTMLLabelElement,
native: HTMLInputElement,
};
}
export class ExtensionsToggleRowElement extends CrLitElement {
static get is() {
return 'extensions-toggle-row';
}
static override get styles() {
return getCss();
}
override render() {
return getHtml.bind(this)();
}
static override get properties() {
return {
checked: {
type: Boolean,
reflect: true,
},
disabled: {
type: Boolean,
reflect: true,
},
};
}
accessor checked: boolean = false;
accessor disabled: boolean = false;
/**
* Exposing the clickable part of extensions-toggle-row for testing
* purposes.
*/
getLabel(): HTMLElement {
return this.$.label;
}
protected onNativeClick_(e: Event) {
// Even though the native checkbox is hidden and can't be actually
// clicked/tapped by the user, because it resides within the <label> the
// browser emits an extraneous event when the label is clicked. Stop
// propagation so that it does not interfere with |onLabelClick_| listener.
e.stopPropagation();
}
private async updateChecked_(value: boolean) {
this.checked = value;
// Sync value of native checkbox and cr-toggle and |checked|.
await this.updateComplete;
this.fire('change', this.checked);
}
/**
* Fires when the native checkbox changes value. This happens when the user
* clicks directly on the <label>.
*/
protected onNativeChange_(e: Event) {
e.stopPropagation();
this.updateChecked_(this.$.native.checked);
}
protected onCrToggleChange_(e: CustomEvent<boolean>) {
e.stopPropagation();
this.updateChecked_(e.detail);
}
}
declare global {
interface HTMLElementTagNameMap {
'extensions-toggle-row': ExtensionsToggleRowElement;
}
}
customElements.define(
ExtensionsToggleRowElement.is, ExtensionsToggleRowElement);