Skip to content

Commit cf3682a

Browse files
committed
refactor: update form and virtual list components for improved template measurement and styling
1 parent 95ffa80 commit cf3682a

File tree

7 files changed

+74
-23
lines changed

7 files changed

+74
-23
lines changed

app/form/form.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,10 @@
88
padding: var(--padding);
99
width: 100%;
1010
height: 100%;
11+
}
12+
13+
.list-item {
14+
display: block;
15+
height: 2rem;
16+
background: red;
1117
}

app/form/form.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<template id="list-item">
2-
<div class="list-item">
2+
<li class="list-item">
33
<span>__name__</span>
44
<span>__age__</span>
55
<span>__email__</span>
6-
</div>
6+
</li>
77
</template>
88

99
<app-header><h2>Form</h2></app-header>

app/form/form.js

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import "./../../components/toast-notification/toast-notification.js";
22
import { FormModule } from "./../../src/modules/form.js";
33
import "./../../components/dynamic-columns/dynamic-columns.js";
44
import "./../../components/virtual-list/virtual-list.js";
5+
import { ComponentModule } from "../../src/modules/component.js";
56

67
export default class FormView extends HTMLElement {
78
static tag = "form-view";
@@ -24,7 +25,14 @@ export default class FormView extends HTMLElement {
2425
const data = loadData();
2526

2627
const virtualList = this.shadowRoot.querySelector("virtual-list");
27-
virtualList.load(data, template, this.#inflate.bind(this));
28+
29+
ComponentModule.on_ready({
30+
element: virtualList,
31+
callback: () => {
32+
virtualList.load(data, template, 32, this.#inflate.bind(this));
33+
}
34+
})
35+
2836
}
2937

3038
async disconnectedCallback() {
@@ -36,9 +44,6 @@ export default class FormView extends HTMLElement {
3644

3745
}
3846

39-
load(data) {
40-
}
41-
4247
async #click(event) {
4348
const target = event.target;
4449

@@ -96,4 +101,18 @@ function loadData() {
96101
return data;
97102
}
98103

104+
// Ensure the template is properly styled before measuring
105+
function measureListItem(template) {
106+
const div = document.createElement("div");
107+
div.style.position = "absolute";
108+
div.style.visibility = "hidden";
109+
div.style.height = "auto";
110+
div.style.width = "auto";
111+
div.appendChild(template.cloneNode(true));
112+
document.body.appendChild(div);
113+
const height = div.clientHeight;
114+
document.body.removeChild(div);
115+
return height;
116+
}
117+
99118
customElements.define(FormView.tag, FormView);

components/virtual-list/virtual-list.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { HTML } from "./virtual-list.html.js";
22
import { SizesManager } from "../../src/modules/virtualization/sizes-manager.js";
3+
import { ComponentModule } from "../../src/modules/component.js";
4+
import { IdleModule } from "../../src/modules/idle.js";
35

46
/**
57
* The VirtualList web component handles creating and displaying a virtual list.
@@ -27,6 +29,7 @@ export class VirtualList extends HTMLElement {
2729
*/
2830
async connectedCallback() {
2931
// Initialize the virtual list here
32+
await ComponentModule.ready({element: this});
3033
}
3134

3235
/**
@@ -39,18 +42,23 @@ export class VirtualList extends HTMLElement {
3942
this.#template = null;
4043
this.#inflateFn = null;
4144
}
45+
46+
#loadElements() {
47+
const height = this.offsetHeight;
48+
}
4249

4350
/**
4451
* Method to update the list items.
4552
* @param {Array} items - The list items to display.
4653
*/
47-
load(items, template, inflateFn) {
54+
async load(items, template, height, inflateFn) {
4855
this.#template = template;
4956
this.#inflateFn = inflateFn;
5057

5158
// Update the virtual list with new items
5259
this.#data.push(...items);
53-
this.#sizeManager = new SizesManager(this.#data.length, 32);
60+
this.#sizeManager = new SizesManager(this.#data.length, height);
61+
IdleModule.perform({ tasks: [this.#loadElements.bind(this)] });
5462
}
5563
}
5664

src/modules/component.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,16 @@ class ComponentModule {
6666
* await ComponentModule.ready({ element: document.querySelector("my-component") });
6767
* @returns {Promise<void>}
6868
*/
69-
static async ready(args){
69+
static ready(args){
7070
const { element } = args;
7171

72-
element.dataset.ready = "true";
73-
element.dispatchEvent(new CustomEvent("ready"));
72+
return new Promise(resolve => {
73+
requestAnimationFrame(() => {
74+
element.dataset.ready = "true";
75+
element.dispatchEvent(new CustomEvent("ready"));
76+
resolve();
77+
})
78+
});
7479
}
7580

7681
/**

src/modules/dom.js

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
11
class DomModule {
22
static name = Object.freeze("dom");
33

4-
static async measure_template(template) {
5-
const div = document.createElement("div");
6-
div.style.display = "none";
7-
div.appendChild(template.cloneNode(true));
8-
9-
document.body.appendChild(div);
10-
const height = div.clientHeight;
11-
document.body.removeChild(div);
12-
return height;
4+
static measure_template(template, parentElement) {
5+
return new Promise(resolve => {
6+
const div = document.createElement("div");
7+
div.id = "measure";
8+
div.style.position = "fixed";
9+
div.style.top = 0;
10+
div.style.left = 0;
11+
div.style.height = "auto";
12+
div.style.width = "auto";
13+
div.appendChild(template.content.cloneNode(true));
14+
15+
parentElement.appendChild(div);
16+
17+
requestAnimationFrame(() => {
18+
const width = div.clientWidth;
19+
const height = div.clientHeight;
20+
parentElement.removeChild(div);
21+
resolve({width, height});
22+
});
23+
})
1324
}
1425
}
1526

tests/src/modules/dom.test.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ globalThis.document = {
1515
getBoundingClientRect: () => ({ height: 100 })
1616
}),
1717
getBoundingClientRect: () => ({ height: 100 }),
18-
clientHeight: 100
18+
clientHeight: 100,
19+
clientWidth: 50
1920
};
2021
},
2122
body: {
@@ -28,6 +29,7 @@ Deno.test("DomModule.measure_template should return the height of a template", a
2829
const template = document.createElement("template");
2930
template.innerHTML = "<div style='height: 100px'></div>";
3031

31-
const height = await DomModule.measure_template(template);
32-
assertEquals(height, 100);
32+
const size = await DomModule.measure_template(template);
33+
assertEquals(size.width, 50);
34+
assertEquals(size.height, 100);
3335
});

0 commit comments

Comments
 (0)