Skip to content

Commit

Permalink
feat(tags): add mounted (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebkolind committed May 29, 2024
1 parent 94c7ece commit 8effe28
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 4 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- Add `mounted` to `tags` to run code after the tag has been mounted

## [0.0.32] - 2024-05-20

### Fixed
Expand Down
8 changes: 8 additions & 0 deletions src/__tests__/attributes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,12 @@ describe('attributes.ts', () => {

expect(el.value).toBe('test');
});

test("doesn't add `mounted` as an attribute", () => {
const el = document.createElement('div');

addAttribute(el, 'mounted', 'test');

expect(el.hasAttribute('mounted')).toBe(false);
});
});
8 changes: 8 additions & 0 deletions src/__tests__/tags.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,12 @@ describe('tags.ts', () => {
expect(el.$tent.attributes['data-bar']).toBe('baz');
expect(el.$tent.attributes['onclick']).toBe(fn);
});

test('mounted', () => {
const fn = jest.fn();
const el = createTag(['div', 'test', { mounted: fn }]);

expect(fn).toHaveBeenCalledTimes(1);
expect(fn).toHaveBeenCalledWith({ el });
});
});
8 changes: 6 additions & 2 deletions src/attributes.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { type TentNode, type Attrs } from './types';
import { type TentNode, type Attrs, type TagAttrsValues } from './types';

function addAttribute<A extends Attrs>(
el: TentNode<A> | HTMLElement,
key: string,
value: string | boolean | number,
value: TagAttrsValues,
) {
if (key === 'mounted') {
return;
}

if (typeof value === 'boolean') {
if (value) {
el.setAttribute(key, '');
Expand Down
2 changes: 2 additions & 0 deletions src/tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ function createTag(context: Context) {
el.append(typeof children === 'number' ? children.toString() : children);
}

attributes?.mounted?.({ el });

return el;
}

Expand Down
8 changes: 6 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@ export type TentNode<A extends Attrs = undefined> = Node &
};

export type Children = string | number | TentNode | (Node | string | Context)[];
export type Context = [string, Children, object | undefined];
export type Context = [string, Children, TagAttrs | undefined];

export type TagAttrsValues = string | boolean | number | Function;
type TagAttrs = Record<string, TagAttrsValues> & {
mounted?: ({ el }: { el: TentNode }) => void;
};
export type Tags = Record<
string,
(children: Children, attrs?: object) => TentNode
(children: Children, attrs?: TagAttrs) => TentNode
>;
6 changes: 6 additions & 0 deletions src/walker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ function walker<A extends Attrs>(oldNode: TentNode<A>, newNode: TentNode<A>) {
return;
}

if (oldNode.$tent == null || newNode.$tent == null) {
oldNode.replaceWith(newNode);

return;
}

// Remove attributes that are not present in the new node
for (const key in oldNode.$tent.attributes) {
if (newNode.$tent.attributes[key] == null) {
Expand Down

0 comments on commit 8effe28

Please sign in to comment.