Skip to content

Commit eaee366

Browse files
Connor ClarkDevtools-frontend LUCI CQ
authored andcommitted
[UI] Migrate Checklist to UI eng vision
Fixed: 407941156 Change-Id: I0c63538178e4b235b91f9812a772578b3da433ad Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/7218150 Auto-Submit: Connor Clark <[email protected]> Reviewed-by: Danil Somsikov <[email protected]> Commit-Queue: Connor Clark <[email protected]>
1 parent a1eb656 commit eaee366

File tree

3 files changed

+66
-49
lines changed

3 files changed

+66
-49
lines changed

front_end/panels/timeline/components/insights/Checklist.ts

Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright 2024 The Chromium Authors
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
4-
/* eslint-disable @devtools/no-lit-render-outside-of-view */
54

65
/**
76
* @file A list of pass/fail conditions for an insight.
@@ -11,11 +10,13 @@ import '../../../../ui/kit/kit.js';
1110

1211
import * as i18n from '../../../../core/i18n/i18n.js';
1312
import type * as Trace from '../../../../models/trace/trace.js';
14-
import * as ComponentHelpers from '../../../../ui/components/helpers/helpers.js';
13+
import * as UI from '../../../../ui/legacy/legacy.js';
1514
import * as Lit from '../../../../ui/lit/lit.js';
1615

1716
import checklistStyles from './checklist.css.js';
1817

18+
const {html} = Lit;
19+
1920
const UIStrings = {
2021
/**
2122
* @description Text for a screen-reader label to tell the user that the icon represents a successful insight check
@@ -32,7 +33,43 @@ const UIStrings = {
3233
const str_ = i18n.i18n.registerUIStrings('panels/timeline/components/insights/Checklist.ts', UIStrings);
3334
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
3435

35-
const {html} = Lit;
36+
interface ViewInput {
37+
checklist: GenericChecklist;
38+
}
39+
40+
type View = (input: ViewInput, output: undefined, target: HTMLElement) => void;
41+
42+
export const DEFAULT_VIEW: View = (input, output, target) => {
43+
const {
44+
checklist,
45+
} = input;
46+
47+
function getIcon(check: GenericChecklist['']): Lit.TemplateResult {
48+
const icon = check.value ? 'check-circle' : 'clear';
49+
50+
const ariaLabel = check.value ? i18nString(UIStrings.successAriaLabel, {PH1: check.label}) :
51+
i18nString(UIStrings.failedAriaLabel, {PH1: check.label});
52+
return html`
53+
<devtools-icon
54+
aria-label=${ariaLabel}
55+
name=${icon}
56+
class=${check.value ? 'check-passed' : 'check-failed'}
57+
></devtools-icon>
58+
`;
59+
}
60+
61+
// clang-format off
62+
Lit.render(html`
63+
<style>${checklistStyles}</style>
64+
<ul>
65+
${Object.values(checklist).map(check => html`<li>
66+
${getIcon(check)}
67+
<span data-checklist-label>${check.label}</span>
68+
</li>`)}
69+
</ul>
70+
`, target);
71+
// clang-format on
72+
};
3673

3774
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3875
type GenericChecklist = Trace.Insights.Types.Checklist<any>;
@@ -46,55 +83,28 @@ export interface TableDataRow {
4683
overlays?: Trace.Types.Overlays.Overlay[];
4784
}
4885

49-
export class Checklist extends HTMLElement {
50-
readonly #shadow = this.attachShadow({mode: 'open'});
86+
export class Checklist extends UI.Widget.Widget {
87+
#view: View;
5188
#checklist?: GenericChecklist;
5289

53-
set checklist(checklist: GenericChecklist) {
54-
this.#checklist = checklist;
55-
void ComponentHelpers.ScheduledRender.scheduleRender(this, this.#render);
56-
}
57-
58-
connectedCallback(): void {
59-
void ComponentHelpers.ScheduledRender.scheduleRender(this, this.#render);
90+
constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
91+
super(element, {useShadowDom: true});
92+
this.#view = view;
6093
}
6194

62-
#getIcon(check: GenericChecklist['']): Lit.TemplateResult {
63-
const icon = check.value ? 'check-circle' : 'clear';
64-
65-
const ariaLabel = check.value ? i18nString(UIStrings.successAriaLabel, {PH1: check.label}) :
66-
i18nString(UIStrings.failedAriaLabel, {PH1: check.label});
67-
return html`
68-
<devtools-icon
69-
aria-label=${ariaLabel}
70-
name=${icon}
71-
class=${check.value ? 'check-passed' : 'check-failed'}
72-
></devtools-icon>
73-
`;
95+
set checklist(checklist: GenericChecklist) {
96+
this.#checklist = checklist;
97+
this.requestUpdate();
7498
}
7599

76-
async #render(): Promise<void> {
100+
override performUpdate(): void {
77101
if (!this.#checklist) {
78102
return;
79103
}
80104

81-
Lit.render(
82-
html`
83-
<style>${checklistStyles}</style>
84-
<ul>
85-
${Object.values(this.#checklist).map(check => html`<li>
86-
${this.#getIcon(check)}
87-
<span data-checklist-label>${check.label}</span>
88-
</li>`)}
89-
</ul>`,
90-
this.#shadow, {host: this});
105+
const input: ViewInput = {
106+
checklist: this.#checklist,
107+
};
108+
this.#view(input, undefined, this.contentElement);
91109
}
92110
}
93-
94-
declare global {
95-
interface HTMLElementTagNameMap {
96-
'devtools-performance-checklist': Checklist;
97-
}
98-
}
99-
100-
customElements.define('devtools-performance-checklist', Checklist);

front_end/panels/timeline/components/insights/DocumentLatency.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import './Checklist.js';
6-
75
import type {DocumentLatencyInsightModel} from '../../../../models/trace/insights/DocumentLatency.js';
86
import type * as Trace from '../../../../models/trace/trace.js';
7+
import * as UI from '../../../../ui/legacy/legacy.js';
98
import * as Lit from '../../../../ui/lit/lit.js';
109

1110
import {BaseInsightComponent} from './BaseInsightComponent.js';
11+
import {Checklist} from './Checklist.js';
1212

1313
const {html} = Lit;
14+
const {widgetConfig} = UI.Widget;
1415

1516
export class DocumentLatency extends BaseInsightComponent<DocumentLatencyInsightModel> {
1617
override internalName = 'document-latency';
@@ -29,7 +30,9 @@ export class DocumentLatency extends BaseInsightComponent<DocumentLatencyInsight
2930
}
3031

3132
// clang-format off
32-
return html`<devtools-performance-checklist .checklist=${this.model.data.checklist}></devtools-performance-checklist>`;
33+
return html`<devtools-widget .widgetConfig=${widgetConfig(Checklist, {
34+
checklist: this.model.data.checklist,
35+
})}></devtools-widget>`;
3336
// clang-format on
3437
}
3538
}

front_end/panels/timeline/components/insights/LCPDiscovery.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
import './Checklist.js';
6-
75
import * as i18n from '../../../../core/i18n/i18n.js';
86
import type {LCPDiscoveryInsightModel} from '../../../../models/trace/insights/LCPDiscovery.js';
97
import * as Trace from '../../../../models/trace/trace.js';
108
import * as uiI18n from '../../../../ui/i18n/i18n.js';
9+
import * as UI from '../../../../ui/legacy/legacy.js';
1110
import * as Lit from '../../../../ui/lit/lit.js';
1211

1312
import {BaseInsightComponent} from './BaseInsightComponent.js';
13+
import {Checklist} from './Checklist.js';
1414
import {imageRef} from './ImageRef.js';
1515

16+
const {widgetConfig} = UI.Widget;
17+
1618
const {UIStrings, i18nString, getImageData} = Trace.Insights.Models.LCPDiscovery;
1719

1820
const {html} = Lit;
@@ -89,7 +91,9 @@ export class LCPDiscovery extends BaseInsightComponent<LCPDiscoveryInsightModel>
8991
// clang-format off
9092
return html`
9193
<div class="insight-section">
92-
<devtools-performance-checklist class="insight-section" .checklist=${imageData.checklist}></devtools-performance-checklist>
94+
<devtools-widget .widgetConfig=${widgetConfig(Checklist, {
95+
checklist: imageData.checklist,
96+
})}></devtools-widget>
9397
<div class="insight-section">${imageRef(imageData.request)}${delayEl}</div>
9498
</div>`;
9599
// clang-format on

0 commit comments

Comments
 (0)