diff --git a/src/__tests__/attributes.test.ts b/src/__tests__/attributes.test.ts
index 3d66c0b..da93add 100644
--- a/src/__tests__/attributes.test.ts
+++ b/src/__tests__/attributes.test.ts
@@ -42,4 +42,12 @@ describe('attributes.ts', () => {
expect(el.hasAttribute('mounted')).toBe(false);
});
+
+ test("doesn't add `keep` as an attribute", () => {
+ const el = document.createElement('div');
+
+ addAttribute(el, 'keep', true);
+
+ expect(el.hasAttribute('keep')).toBe(false);
+ });
});
diff --git a/src/__tests__/component.test.ts b/src/__tests__/component.test.ts
index dfdd6ca..d78e6cf 100644
--- a/src/__tests__/component.test.ts
+++ b/src/__tests__/component.test.ts
@@ -1,7 +1,13 @@
import { mount } from '../mount';
import { tags } from '../tags';
import { type Component } from '../types';
-import { getByText, getByTestId, fireEvent } from '@testing-library/dom';
+import {
+ getByText,
+ getByTestId,
+ fireEvent,
+ getByRole,
+ queryByText,
+} from '@testing-library/dom';
const { div, p, button } = tags;
@@ -76,4 +82,34 @@ describe('components', () => {
expect(el).toBeDefined();
});
+
+ test('keep', () => {
+ const KeepComponent: Component<{ count: number }> = {
+ state: { count: 0 },
+ view({ state }) {
+ return div(
+ div(
+ [
+ `Don't change me ${state.count}`,
+ button('Increment', {
+ onclick: () => state.count++,
+ }),
+ ],
+ { keep: true },
+ ),
+ );
+ },
+ };
+
+ mount(document.body, KeepComponent);
+
+ const btn = getByRole(document.body, 'button');
+
+ expect(btn).toBeDefined();
+
+ fireEvent.click(btn);
+
+ expect(queryByText(document.body, /Don't change me 0/)).toBeTruthy();
+ expect(queryByText(document.body, /Don't change me 1/)).toBeNull();
+ });
});
diff --git a/src/attributes.ts b/src/attributes.ts
index db716eb..c8ada1c 100644
--- a/src/attributes.ts
+++ b/src/attributes.ts
@@ -5,7 +5,7 @@ function addAttribute(
key: string,
value: TagAttrsValues,
) {
- if (key === 'mounted') {
+ if (key === 'mounted' || key === 'keep') {
return;
}
diff --git a/src/types.ts b/src/types.ts
index 23f2b9d..ccdba0e 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -14,18 +14,27 @@ export type TentNode = Node &
Element &
HTMLElement & {
$tent: {
- attributes: object;
+ attributes: Record & {
+ mounted?: ({ el }: { el: TentNode }) => void;
+ keep?: boolean;
+ };
};
dataset: A & DOMStringMap;
children: TentNode[];
};
-export type Children = string | number | TentNode | (Node | string | Context)[];
+export type Children =
+ | string
+ | number
+ | TentNode
+ | Element
+ | (Node | string | Context)[];
export type Context = [string, Children, TagAttrs | undefined];
export type TagAttrsValues = string | boolean | number | Function;
type TagAttrs = Record & {
mounted?: ({ el }: { el: TentNode }) => void;
+ keep?: boolean;
};
export type Tags = Record<
string,
diff --git a/src/walker.ts b/src/walker.ts
index 07181ac..bed4b7b 100644
--- a/src/walker.ts
+++ b/src/walker.ts
@@ -46,6 +46,7 @@ function walker(oldNode: TentNode, newNode: TentNode) {
}
if (oc.length === 0 && nc.length === 0) return;
+ if (oldNode.$tent.attributes.keep) return;
if (oc.length < nc.length) {
for (let i = 0; i < nc.length; i++) {