blob: 411efb23437d5bd33e6cb77704716685349de9b4 [file]
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import type * as Common from '../../../core/common/common.js';
import * as LitHtml from '../../lit-html/lit-html.js';
import * as VisualLogging from '../../visual_logging/visual_logging.js';
import * as IconButton from '../icon_button/icon_button.js';
import * as Input from '../input/input.js';
import settingCheckboxStyles from './settingCheckbox.css.js';
import {SettingDeprecationWarning} from './SettingDeprecationWarning.js';
export interface SettingCheckboxData {
setting: Common.Settings.Setting<boolean>;
}
/**
* A simple checkbox that is backed by a boolean setting.
*/
export class SettingCheckbox extends HTMLElement {
static readonly litTagName = LitHtml.literal`setting-checkbox`;
readonly #shadow = this.attachShadow({mode: 'open'});
#setting?: Common.Settings.Setting<boolean>;
#changeListenerDescriptor?: Common.EventTarget.EventDescriptor;
connectedCallback(): void {
this.#shadow.adoptedStyleSheets = [Input.checkboxStyles, settingCheckboxStyles];
}
set data(data: SettingCheckboxData) {
if (this.#changeListenerDescriptor && this.#setting) {
this.#setting.removeChangeListener(this.#changeListenerDescriptor.listener);
}
this.#setting = data.setting;
this.#changeListenerDescriptor = this.#setting.addChangeListener(() => {
this.#render();
});
this.#render();
}
#deprecationIcon(): LitHtml.TemplateResult|undefined {
if (!this.#setting?.deprecation) {
return undefined;
}
return LitHtml.html`<${SettingDeprecationWarning.litTagName} .data=${
this.#setting.deprecation as Common.Settings.Deprecation}></${SettingDeprecationWarning.litTagName}>`;
}
#render(): void {
if (!this.#setting) {
throw new Error('No "Setting" object provided for rendering');
}
const icon = this.#deprecationIcon();
const reason = this.#setting.disabledReason() ?
LitHtml.html`
<${IconButton.Icon.Icon.litTagName} class="disabled-reason" name="info" title=${
this.#setting.disabledReason()} @click=${onclick}></${IconButton.Icon.Icon.litTagName}>
` :
LitHtml.nothing;
LitHtml.render(
LitHtml.html`
<p>
<label>
<input
type="checkbox"
.checked=${this.#setting.disabledReason() ? false : this.#setting.get()}
?disabled=${this.#setting.disabled()}
@change=${this.#checkboxChanged}
jslog=${VisualLogging.toggle().track({click: true}).context(this.#setting.name)}
aria-label=${this.#setting.title()}
/>
${this.#setting.title()}${reason}${icon}
</label>
</p>`,
this.#shadow, {host: this});
}
#checkboxChanged(e: Event): void {
this.#setting?.set((e.target as HTMLInputElement).checked);
this.dispatchEvent(new CustomEvent('change', {
bubbles: true,
composed: false,
}));
}
}
customElements.define('setting-checkbox', SettingCheckbox);
declare global {
interface HTMLElementTagNameMap {
'setting-checkbox': SettingCheckbox;
}
}