Skip to content

Commit

Permalink
stop array elements from rerendering on add and delete
Browse files Browse the repository at this point in the history
  • Loading branch information
SalihuDickson committed Jan 28, 2025
1 parent da7b208 commit b7a43a1
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 73 deletions.
1 change: 0 additions & 1 deletion packages/ecc-utils-design/demo/form/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
<div class="p-10">
<div id="demo"></div>
</div>
<!-- <button id="button">HTML Button</button> -->

<script type="module">
import { html, render } from "lit";
Expand Down
12 changes: 4 additions & 8 deletions packages/ecc-utils-design/src/components/form/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import "@shoelace-style/shoelace/dist/components/tooltip/tooltip.js";
import "@shoelace-style/shoelace/dist/components/select/select.js";
import "@shoelace-style/shoelace/dist/components/option/option.js";
import * as _ from "lodash-es";
import { repeat } from "lit/directives/repeat.js";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
import { hostStyles } from "../../styles/host.styles.js";
import formStyles from "./form.styles.js";
import { primitiveStylesheet } from "../../styles/primitive.styles.js";
Expand Down Expand Up @@ -91,13 +91,13 @@ export default class EccUtilsDesignForm extends LitElement {
@state() private errorMessage = "Something went wrong";
@state() private successMessage = "Form submitted successfully";
@state() private requiredButEmpty: string[] = [];
@state() private items: Array<Element> = [];
@state() private content = "";

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

this.items = Array.from(this.querySelectorAll(":scope > *"));
this.content = this.innerHTML;
this.setHTMLUnsafe("");

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

return html`
<form ecc-form @submit=${this.handleSubmit}>
${repeat(
this.items,
() => _.uniqueId("ecc-form-item-"),
(item) => html`${item}`
)}
${unsafeHTML(this.content)}
<sl-button
type="submit"
Expand Down
101 changes: 39 additions & 62 deletions packages/ecc-utils-design/src/components/form/formGroup.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { LitElement, html, TemplateResult } from "lit";
import { property, state } from "lit/decorators.js";
import { repeat } from "lit/directives/repeat.js";
import { unsafeHTML } from "lit/directives/unsafe-html.js";
import * as _ from "lodash-es";
import { noKeyWarning, renderInTooltip } from "./utils.js";
import { noKeyWarning, renderInTooltip, generateUniqueKey } from "./utils.js";
import "@shoelace-style/shoelace/dist/components/details/details.js";
import "@shoelace-style/shoelace/dist/components/button/button.js";
import formStyles from "./form.styles.js";
Expand All @@ -29,27 +30,22 @@ export default class EccUtilsDesignFormGroup extends LitElement {
@property({ type: Boolean, reflect: true }) collapsible = false;

@state() private arrayInstances: Array<{
id: number;
items: Element[];
id: string;
content: string;
}> = [];

@state() private originalInstance: Element[] = [];
@state() private items: Array<Element> = [];
@state() private content = "";
@state() private path = "";

declare setHTMLUnsafe: (htmlString: string) => void;
protected firstUpdated(): void {
this.content = this.innerHTML;

if (this.type === "array") {
this.originalInstance = Array.from(this.querySelectorAll(":scope > *"));
this.arrayInstances = Array.from(
{ length: this.instances },
(__, index) => ({
id: index,
items: this.originalInstance,
})
);
} else {
this.items = Array.from(this.querySelectorAll(":scope > *"));
this.arrayInstances = Array.from({ length: this.instances }, () => ({
id: generateUniqueKey(),
content: this.content,
}));
}

this.setHTMLUnsafe("");
Expand Down Expand Up @@ -89,41 +85,33 @@ export default class EccUtilsDesignFormGroup extends LitElement {
}

private renderGroupTemplate(): TemplateResult {
return html`${this.collapsible
? repeat(
this.items,
() => _.uniqueId("ecc-group-"),
(item) => html`
<sl-details
data-testid="group-collapsible"
summary=${`${this.label} ${this.required ? "*" : ""}`}
>
<div
class="group-content"
ecc-group
ecc-group-key="${this.key}"
path="${this.path}"
>
${item}
</div>
</sl-details>
`
)
: repeat(
this.items,
() => _.uniqueId("ecc-group-"),
(item) => html`
<span>${this.label} ${this.required ? "*" : ""} </span>
return this.collapsible
? html`
<sl-details
data-testid="group-collapsible"
summary=${`${this.label} ${this.required ? "*" : ""}`}
>
<div
class="group-content"
ecc-group
ecc-group-key="${this.key}"
path="${this.path}"
>
${item}
${unsafeHTML(this.content)}
</div>
`
)}`;
</sl-details>
`
: html`
<span>${this.label} ${this.required ? "*" : ""} </span>
<div
class="group-content"
ecc-group
ecc-group-key="${this.key}"
path="${this.path}"
>
${unsafeHTML(this.content)}
</div>
`;
}

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

const addItem = () => {
if (resolveAddButtonIsActive()) {
this.arrayInstances.push({
id: this.arrayInstances.length,
items: this.originalInstance,
});
const newInstance = {
id: generateUniqueKey(),
content: this.content,
};

this.arrayInstances = [...this.arrayInstances, newInstance];

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

this.arrayInstances = newItems;
this.requestUpdate();

this.dispatchEvent(
new CustomEvent("ecc-utils-array-delete", {
detail: {
Expand All @@ -182,14 +171,6 @@ export default class EccUtilsDesignFormGroup extends LitElement {
}
};

const arrayDiv = (item: Element, index: number) => {
const div = document.createElement("div");
div.setAttribute("ecc-array-key", `${this.key}[${index}]`);
div.innerHTML = item.outerHTML;

return div;
};

return html`
<div
class="array-container"
Expand Down Expand Up @@ -268,11 +249,7 @@ export default class EccUtilsDesignFormGroup extends LitElement {
</svg>
</sl-button>
<div class="array-item-container">
${repeat(
instance.items,
(item) => item.id,
(item) => arrayDiv(item, index)
)}
${unsafeHTML(instance.content)}
</div>
</div>
`
Expand Down
5 changes: 5 additions & 0 deletions packages/ecc-utils-design/src/components/form/formInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,12 @@ export default class EccUtilsDesignFormInput extends LitElement {
}

this.findNearestFormGroup();

if (this.value) {
this.handleFireChangeEvent();
}

// console.log("just connected");
}

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

console.log("this.value", this.value, target);

this.handleFireChangeEvent();
this.requestUpdate();
}
Expand Down
4 changes: 2 additions & 2 deletions packages/ecc-utils-design/src/components/form/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ export function noKeyWarning(Element: string, label: string): void {
);
}

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

0 comments on commit b7a43a1

Please sign in to comment.