Skip to content

Commit b7a43a1

Browse files
committed
stop array elements from rerendering on add and delete
1 parent da7b208 commit b7a43a1

File tree

5 files changed

+50
-73
lines changed

5 files changed

+50
-73
lines changed

packages/ecc-utils-design/demo/form/index.html

-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
<div class="p-10">
1313
<div id="demo"></div>
1414
</div>
15-
<!-- <button id="button">HTML Button</button> -->
1615

1716
<script type="module">
1817
import { html, render } from "lit";

packages/ecc-utils-design/src/components/form/form.ts

+4-8
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import "@shoelace-style/shoelace/dist/components/tooltip/tooltip.js";
1010
import "@shoelace-style/shoelace/dist/components/select/select.js";
1111
import "@shoelace-style/shoelace/dist/components/option/option.js";
1212
import * as _ from "lodash-es";
13-
import { repeat } from "lit/directives/repeat.js";
13+
import { unsafeHTML } from "lit/directives/unsafe-html.js";
1414
import { hostStyles } from "../../styles/host.styles.js";
1515
import formStyles from "./form.styles.js";
1616
import { primitiveStylesheet } from "../../styles/primitive.styles.js";
@@ -91,13 +91,13 @@ export default class EccUtilsDesignForm extends LitElement {
9191
@state() private errorMessage = "Something went wrong";
9292
@state() private successMessage = "Form submitted successfully";
9393
@state() private requiredButEmpty: string[] = [];
94-
@state() private items: Array<Element> = [];
94+
@state() private content = "";
9595

9696
declare setHTMLUnsafe: (htmlString: string) => void;
9797
protected firstUpdated(_changedProperties: PropertyValues): void {
9898
super.firstUpdated(_changedProperties);
9999

100-
this.items = Array.from(this.querySelectorAll(":scope > *"));
100+
this.content = this.innerHTML;
101101
this.setHTMLUnsafe("");
102102

103103
this.addEventListener("ecc-utils-change", (e) => {
@@ -219,11 +219,7 @@ export default class EccUtilsDesignForm extends LitElement {
219219

220220
return html`
221221
<form ecc-form @submit=${this.handleSubmit}>
222-
${repeat(
223-
this.items,
224-
() => _.uniqueId("ecc-form-item-"),
225-
(item) => html`${item}`
226-
)}
222+
${unsafeHTML(this.content)}
227223
228224
<sl-button
229225
type="submit"

packages/ecc-utils-design/src/components/form/formGroup.ts

+39-62
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { LitElement, html, TemplateResult } from "lit";
22
import { property, state } from "lit/decorators.js";
33
import { repeat } from "lit/directives/repeat.js";
4+
import { unsafeHTML } from "lit/directives/unsafe-html.js";
45
import * as _ from "lodash-es";
5-
import { noKeyWarning, renderInTooltip } from "./utils.js";
6+
import { noKeyWarning, renderInTooltip, generateUniqueKey } from "./utils.js";
67
import "@shoelace-style/shoelace/dist/components/details/details.js";
78
import "@shoelace-style/shoelace/dist/components/button/button.js";
89
import formStyles from "./form.styles.js";
@@ -29,27 +30,22 @@ export default class EccUtilsDesignFormGroup extends LitElement {
2930
@property({ type: Boolean, reflect: true }) collapsible = false;
3031

3132
@state() private arrayInstances: Array<{
32-
id: number;
33-
items: Element[];
33+
id: string;
34+
content: string;
3435
}> = [];
3536

36-
@state() private originalInstance: Element[] = [];
37-
@state() private items: Array<Element> = [];
37+
@state() private content = "";
3838
@state() private path = "";
3939

4040
declare setHTMLUnsafe: (htmlString: string) => void;
4141
protected firstUpdated(): void {
42+
this.content = this.innerHTML;
43+
4244
if (this.type === "array") {
43-
this.originalInstance = Array.from(this.querySelectorAll(":scope > *"));
44-
this.arrayInstances = Array.from(
45-
{ length: this.instances },
46-
(__, index) => ({
47-
id: index,
48-
items: this.originalInstance,
49-
})
50-
);
51-
} else {
52-
this.items = Array.from(this.querySelectorAll(":scope > *"));
45+
this.arrayInstances = Array.from({ length: this.instances }, () => ({
46+
id: generateUniqueKey(),
47+
content: this.content,
48+
}));
5349
}
5450

5551
this.setHTMLUnsafe("");
@@ -89,41 +85,33 @@ export default class EccUtilsDesignFormGroup extends LitElement {
8985
}
9086

9187
private renderGroupTemplate(): TemplateResult {
92-
return html`${this.collapsible
93-
? repeat(
94-
this.items,
95-
() => _.uniqueId("ecc-group-"),
96-
(item) => html`
97-
<sl-details
98-
data-testid="group-collapsible"
99-
summary=${`${this.label} ${this.required ? "*" : ""}`}
100-
>
101-
<div
102-
class="group-content"
103-
ecc-group
104-
ecc-group-key="${this.key}"
105-
path="${this.path}"
106-
>
107-
${item}
108-
</div>
109-
</sl-details>
110-
`
111-
)
112-
: repeat(
113-
this.items,
114-
() => _.uniqueId("ecc-group-"),
115-
(item) => html`
116-
<span>${this.label} ${this.required ? "*" : ""} </span>
88+
return this.collapsible
89+
? html`
90+
<sl-details
91+
data-testid="group-collapsible"
92+
summary=${`${this.label} ${this.required ? "*" : ""}`}
93+
>
11794
<div
11895
class="group-content"
11996
ecc-group
12097
ecc-group-key="${this.key}"
12198
path="${this.path}"
12299
>
123-
${item}
100+
${unsafeHTML(this.content)}
124101
</div>
125-
`
126-
)}`;
102+
</sl-details>
103+
`
104+
: html`
105+
<span>${this.label} ${this.required ? "*" : ""} </span>
106+
<div
107+
class="group-content"
108+
ecc-group
109+
ecc-group-key="${this.key}"
110+
path="${this.path}"
111+
>
112+
${unsafeHTML(this.content)}
113+
</div>
114+
`;
127115
}
128116

129117
private renderArrayTemplate(): TemplateResult {
@@ -143,12 +131,13 @@ export default class EccUtilsDesignFormGroup extends LitElement {
143131

144132
const addItem = () => {
145133
if (resolveAddButtonIsActive()) {
146-
this.arrayInstances.push({
147-
id: this.arrayInstances.length,
148-
items: this.originalInstance,
149-
});
134+
const newInstance = {
135+
id: generateUniqueKey(),
136+
content: this.content,
137+
};
138+
139+
this.arrayInstances = [...this.arrayInstances, newInstance];
150140

151-
this.requestUpdate();
152141
this.dispatchEvent(
153142
new CustomEvent("ecc-utils-array-add", {
154143
detail: {
@@ -168,7 +157,7 @@ export default class EccUtilsDesignFormGroup extends LitElement {
168157
newItems.splice(index, 1);
169158

170159
this.arrayInstances = newItems;
171-
this.requestUpdate();
160+
172161
this.dispatchEvent(
173162
new CustomEvent("ecc-utils-array-delete", {
174163
detail: {
@@ -182,14 +171,6 @@ export default class EccUtilsDesignFormGroup extends LitElement {
182171
}
183172
};
184173

185-
const arrayDiv = (item: Element, index: number) => {
186-
const div = document.createElement("div");
187-
div.setAttribute("ecc-array-key", `${this.key}[${index}]`);
188-
div.innerHTML = item.outerHTML;
189-
190-
return div;
191-
};
192-
193174
return html`
194175
<div
195176
class="array-container"
@@ -268,11 +249,7 @@ export default class EccUtilsDesignFormGroup extends LitElement {
268249
</svg>
269250
</sl-button>
270251
<div class="array-item-container">
271-
${repeat(
272-
instance.items,
273-
(item) => item.id,
274-
(item) => arrayDiv(item, index)
275-
)}
252+
${unsafeHTML(instance.content)}
276253
</div>
277254
</div>
278255
`

packages/ecc-utils-design/src/components/form/formInput.ts

+5
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,12 @@ export default class EccUtilsDesignFormInput extends LitElement {
6666
}
6767

6868
this.findNearestFormGroup();
69+
6970
if (this.value) {
7071
this.handleFireChangeEvent();
7172
}
73+
74+
// console.log("just connected");
7275
}
7376

7477
private findNearestFormGroup(element: HTMLElement | null = this): void {
@@ -137,6 +140,8 @@ export default class EccUtilsDesignFormInput extends LitElement {
137140
const target = e.target as HTMLInputElement;
138141
this.value = this.type === "switch" ? target.checked : target.value;
139142

143+
console.log("this.value", this.value, target);
144+
140145
this.handleFireChangeEvent();
141146
this.requestUpdate();
142147
}

packages/ecc-utils-design/src/components/form/utils.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ export function noKeyWarning(Element: string, label: string): void {
2727
);
2828
}
2929

30-
export function isShadowElement(element: Element): boolean {
31-
return element.getRootNode() instanceof ShadowRoot;
30+
export function generateUniqueKey() {
31+
return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
3232
}

0 commit comments

Comments
 (0)