Skip to content

Commit 56f2d01

Browse files
authored
Capture sync async work for getBoundingRectAndElementFromPoint (#34)
Properly capturing layout work in steps ReduceWidthIn5Steps and IncreaseWidthIn5Steps.
1 parent 907f2b5 commit 56f2d01

10 files changed

Lines changed: 81 additions & 43 deletions

File tree

experimental/responsive-design/dist/app.js

Lines changed: 38 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

experimental/responsive-design/src/lib/components/app-ribbon.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { html } from "lit";
2+
import { when } from "lit/directives/when.js";
23
import { LightDOMLitElement } from "./base";
34
import { ribbonButtons } from "../../data/ribbon-buttons.js";
45
import "./ribbon-button.js";
56

6-
export class AppRibbon extends LightDOMLitElement {
7+
class AppRibbon extends LightDOMLitElement {
78
static properties = {
89
buttons: { type: Array },
910
visibleButtons: { type: Array },
@@ -65,7 +66,7 @@ export class AppRibbon extends LightDOMLitElement {
6566
return this.visibleButtons.map(
6667
(button, index) => html`
6768
<ribbon-button id="${button.id}" text="${button.text}" variant="${button.variant}" iconPosition="${button.iconPosition}"></ribbon-button>
68-
${index === 0 ? html`<div class="mx-0.5 h-6 border-l border-gray-300"></div>` : ""}
69+
${when(index === 0, () => html`<div class="mx-0.5 h-6 border-l border-gray-300"></div>`)}
6970
`
7071
);
7172
}

experimental/responsive-design/src/lib/components/chat-messages.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { html } from "lit";
2+
import { when } from "lit/directives/when.js";
23
import { ref, createRef } from "lit/directives/ref.js";
34
import { LightDOMLitElement } from "./base";
45

@@ -35,7 +36,7 @@ class ChatMessages extends LightDOMLitElement {
3536
${message.user
3637
? html` <div class="flex items-center space-x-2">
3738
<div class="text-pretty rounded-md bg-teal-600 px-3 py-2 text-xs text-white lg:text-base">
38-
${message.user} ${message.imageUrl ? html`<img src="${message.imageUrl}" alt="${message.imageAlt}" class="mt-2 h-32 w-full rounded-md" />` : ""}
39+
${message.user} ${when(message.imageUrl, () => html`<img src="${message.imageUrl}" alt="${message.imageAlt}" class="mt-2 h-32 w-full rounded-md" />`)}
3940
</div>
4041
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 flex-shrink-0 text-teal-600" fill="currentColor" viewBox="0 0 24 24">
4142
<circle cx="12" cy="8" r="4" />
@@ -51,7 +52,7 @@ class ChatMessages extends LightDOMLitElement {
5152
<path d="M8 16h8" />
5253
</svg>
5354
<div class="text-pretty rounded-md bg-gray-200 px-3 py-2 text-xs text-gray-900 lg:text-base">
54-
${message.bot} ${message.imageUrl ? html`<img src="${message.imageUrl}" alt="${message.imageAlt}" class="mt-2 h-32 w-full rounded-md" />` : ""}
55+
${message.bot} ${when(message.imageUrl, () => html`<img src="${message.imageUrl}" alt="${message.imageAlt}" class="mt-2 h-32 w-full rounded-md" />`)}
5556
</div>
5657
</div>
5758
`}

experimental/responsive-design/src/lib/components/chat-window.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { LitElement, adoptStyles, html } from "lit";
1+
import { LitElement, adoptStyles, html, nothing } from "lit";
22
import { messages as initialMessages } from "../../data/messages.js";
33
import "./chat-messages.js";
44
import "./chat-input.js";
@@ -76,7 +76,7 @@ class ChatWindow extends LitElement {
7676

7777
_getContentTemplate() {
7878
if (!this._isExpanded)
79-
return null;
79+
return nothing;
8080
return this._showOptions ? this._getOptionsTemplate() : this._getChatTemplate();
8181
}
8282

experimental/responsive-design/src/lib/components/recipe-card.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { html } from "lit";
2+
import { when } from "lit/directives/when.js";
23
import { LightDOMLitElement } from "./base";
34

45
class RecipeCard extends LightDOMLitElement {
@@ -152,7 +153,7 @@ class RecipeCard extends LightDOMLitElement {
152153
</div>
153154
<button class="show-more-btn flex-shrink-0 text-sm text-blue-500 hover:text-blue-700" @click="${this._toggleExpand}">${this.isExpanded ? "Less" : "More"}</button>
154155
</div>
155-
${this.isExpanded ? this._getExpandedTemplate() : ""}
156+
${when(this.isExpanded, () => this._getExpandedTemplate())}
156157
</div>
157158
`;
158159
}
@@ -173,7 +174,7 @@ class RecipeCard extends LightDOMLitElement {
173174
<div class="absolute -top-4 left-0 right-0 flex justify-center space-x-2 p-2">
174175
${this.recipe.tags.map((tag) => html`<span class="${this._getPillColor(tag)} inline-flex items-center rounded-full border p-1 text-xs font-medium">${tag}</span> `)}
175176
</div>
176-
${this.isExpanded ? this._getExpandedTemplate() : ""}
177+
${when(this.isExpanded, () => this._getExpandedTemplate())}
177178
<button @click="${this._toggleExpand}" class="show-more-btn w-28 justify-self-end border-none bg-transparent p-1 text-sm text-blue-400 hover:text-blue-900">${this.isExpanded ? "Show Less" : "Show More..."}</button>
178179
</div>
179180
`;

experimental/responsive-design/src/lib/components/recipe-grid.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,14 @@ class RecipeGrid extends LightDOMLitElement {
3434
this._compactQuery.removeEventListener("change", this._boundHandleLayoutChange);
3535
}
3636

37-
_handleLayoutChange(event) {
37+
async _handleLayoutChange(event) {
3838
this.isCompactLayout = event.matches;
39+
40+
await this.updateComplete;
41+
42+
// Dispatch to parent window (the benchmark runner's window)
43+
if (window.parent !== window)
44+
window.parent.dispatchEvent(new CustomEvent("resize-work-complete"));
3945
}
4046

4147
_handleToggleExpand(event) {

experimental/responsive-design/src/lib/components/ribbon-button.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { html } from "lit";
22
import { LightDOMLitElement } from "./base";
33

4-
export class RibbonButton extends LightDOMLitElement {
4+
class RibbonButton extends LightDOMLitElement {
55
static properties = {
66
text: { type: String },
77
variant: { type: String },

experimental/responsive-design/src/lib/components/section-heading.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { html } from "lit";
2+
import { when } from "lit/directives/when.js";
23
import { LightDOMLitElement } from "./base";
34

45
class SectionHeading extends LightDOMLitElement {
@@ -10,7 +11,7 @@ class SectionHeading extends LightDOMLitElement {
1011
render() {
1112
return html`
1213
<h2 class="has-[+p]:mb-1 text-left leading-9 tracking-tight">${this.title}</h2>
13-
${this.subtitle ? html`<p class="pl-1 text-sm text-gray-600">${this.subtitle}</p>` : ""}
14+
${when(this.subtitle, () => html`<p class="pl-1 text-sm text-gray-600">${this.subtitle}</p>`)}
1415
`;
1516
}
1617
}

resources/benchmark-runner.mjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ class Page {
121121
_wrapElement(element) {
122122
return new PageElement(element);
123123
}
124+
125+
addEventListener(name, listener, options) {
126+
this._frame.contentWindow.addEventListener(name, listener, options);
127+
}
124128
}
125129

126130
const NATIVE_OPTIONS = {

resources/tests.mjs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,10 +1131,19 @@ Suites.push({
11311131
const iframeElement = page.querySelector("#content-iframe");
11321132
const widths = [768, 704, 640, 560, 480];
11331133

1134+
// The matchMedia query is "(max-width: 640px)"
1135+
// Starting from a width > 640px, we'll only get 1 event when crossing to <= 640px
1136+
// This happens when the width changes from 704px to 640px
1137+
const resizeWorkPromise = new Promise((resolve) => {
1138+
page.addEventListener("resize-work-complete", resolve, { once: true });
1139+
});
1140+
11341141
for (const width of widths) {
11351142
iframeElement.setWidth(`${width}px`);
11361143
page.layout();
11371144
}
1145+
1146+
await resizeWorkPromise;
11381147
}),
11391148
new BenchmarkTestStep("ScrollToChatAndSendMessages", async (page) => {
11401149
const iframeElement = page.querySelector("#content-iframe", [], true);
@@ -1173,10 +1182,19 @@ Suites.push({
11731182
const iframeElement = page.querySelector("#content-iframe");
11741183
const widths = [560, 640, 704, 768, 800];
11751184

1185+
// The matchMedia query is "(max-width: 640px)"
1186+
// Starting from a width <= 640px, we'll get 1 event when crossing back to > 640px.
1187+
// This happens when the width changes from 640px to 704px.
1188+
const resizeWorkPromise = new Promise((resolve) => {
1189+
page.addEventListener("resize-work-complete", resolve, { once: true });
1190+
});
1191+
11761192
for (const width of widths) {
11771193
iframeElement.setWidth(`${width}px`);
11781194
page.layout();
11791195
}
1196+
1197+
await resizeWorkPromise;
11801198
}),
11811199
],
11821200
});

0 commit comments

Comments
 (0)