// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/* eslint-disable @devtools/enforce-custom-element-definitions-location */
import './ButtonDialog.js';
/* eslint-disable @devtools/no-lit-render-outside-of-view */
import * as i18n from '../../../core/i18n/i18n.js';
import type * as Platform from '../../../core/platform/platform.js';
import * as Buttons from '../../../ui/components/buttons/buttons.js';
import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
import {html, nothing, render, type TemplateResult} from '../../../ui/lit/lit.js';
import type {ButtonDialogData} from './ButtonDialog.js';
import shortcutDialogStyles from './shortcutDialog.css.js';
const UIStrings = {
/**
* @description Title of question mark button for the shortcuts dialog.
*/
showShortcutTitle: 'Show shortcuts',
/**
* @description Title of the keyboard shortcuts help menu.
*/
dialogTitle: 'Keyboard shortcuts',
} as const;
const str_ = i18n.i18n.registerUIStrings('ui/components/dialogs/ShortcutDialog.ts', UIStrings);
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
declare global {
interface HTMLElementTagNameMap {
'devtools-shortcut-dialog': ShortcutDialog;
}
}
export type ShortcutPart = {
key: string,
}|{joinText: string};
export type ShortcutRow = ShortcutPart[]|{footnote: string};
export interface Shortcut {
title: string|Platform.UIString.LocalizedString;
rows: readonly ShortcutRow[];
}
export interface ShortcutDialogData {
shortcuts: Shortcut[];
open?: boolean;
customTitle?: Platform.UIString.LocalizedString;
}
export class ShortcutDialog extends HTMLElement {
readonly #shadow = this.attachShadow({mode: 'open'});
#shortcuts: Shortcut[] = [];
#openOnRender = false;
#customTitle?: Platform.UIString.LocalizedString;
#prependedElement: HTMLElement|null = null;
get data(): ShortcutDialogData {
return {
shortcuts: this.#shortcuts,
open: this.#openOnRender,
customTitle: this.#customTitle,
};
}
set data(data: ShortcutDialogData) {
this.#shortcuts = data.shortcuts;
if (data.open) {
this.#openOnRender = data.open;
}
if (data.customTitle) {
this.#customTitle = data.customTitle;
}
void ComponentHelpers.ScheduledRender.scheduleRender(this, this.#render);
}
prependElement(element: HTMLElement): void {
this.#prependedElement = element;
}
#renderRow(row: ShortcutRow): TemplateResult {
if (!Array.isArray(row)) {
// If it's not an array it's a footnote, which is the easier case, so
// render that and return.
return html`${row.footnote}`;
}
return html`${row.map(part => {
if ('key' in part) {
return html`${part.key}`;
}
return html`${part.joinText}`;
})}
`;
}
#render(): void {
if (!ComponentHelpers.ScheduledRender.isScheduledRender(this)) {
throw new Error('Shortcut dialog render was not scheduled');
}
// clang-format off
render(
html`