Skip to content

Commit

Permalink
fix(Component): require state if S is defined (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebkolind committed Jun 2, 2024
1 parent 760c96b commit c4a32df
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 21 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]

### Fixed

- `Component<S>` now requires `state` if `S` is defined ([#43](https://github.com/tentjs/tent/issues/43))

## [0.0.33-0] - 2024-05-27

### Added
Expand Down
29 changes: 29 additions & 0 deletions src/__tests__/component.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { getByText, getByTestId, fireEvent } from '@testing-library/dom';

const { div, p, button } = tags;

beforeEach(() => {
document.body.innerHTML = '';
});

const Counter: Component<{ count: number }> = {
state: { count: 0 },
view: ({ state }) =>
Expand Down Expand Up @@ -47,4 +51,29 @@ describe('components', () => {

expect(mounted).toHaveBeenCalledTimes(1);
});

test('with state', () => {
const WithState: Component<{ count: number }> = {
state: { count: 0 },
view: ({ state }) => div(p(`Count: ${state.count}`)),
};

mount(document.body, WithState);

const el = getByText(document.body, /Count: 0/);

expect(el).toBeDefined();
});

test('without state', () => {
const WithoutState: Component = {
view: () => div(p(`No state`)),
};

mount(document.body, WithoutState);

const el = getByText(document.body, /No state/);

expect(el).toBeDefined();
});
});
21 changes: 8 additions & 13 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@ function mount<S extends {} = {}, A extends Attrs = {}>(
element: HTMLElement | Element | TentNode<A> | null,
component: Component<S, A>,
) {
if (element == null) {
return;
}
if (element == null) return;

let node: TentNode<A>;
const { state = {} as S, view, mounted } = component;
const { view, mounted } = component;
const state = 'state' in component ? component.state : ({} as S);
const el = element as TentNode<A>;

el.$tent = {
attributes: {},
};
el.$tent = { attributes: {} };

const handler = {
get(obj: S, key: string) {
Expand Down Expand Up @@ -45,21 +42,19 @@ function mount<S extends {} = {}, A extends Attrs = {}>(
const proxy = new Proxy<S>({ ...state }, handler);

node = view({ state: proxy, el });
node.$tent = {
attributes: {},
};
node.$tent = { attributes: {} };

el.append(node);

mounted?.({ state: proxy, el });
}

export {
mount,
tags,
mount,
createTag,
type Component,
type Children,
type Context,
type TentNode,
type Children,
type Component,
};
4 changes: 2 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ type ComponentContext<S, A extends Attrs> = {
export type Attrs = {} | undefined;
export type Component<S extends {} = {}, A extends Attrs = {}> = {
view: (context: ComponentContext<S, A>) => TentNode<A>;
state?: S;
mounted?: (context: ComponentContext<S, A>) => void;
};
} & State<S>;
type State<S> = {} extends S ? {} : { state: S };

export type TentNode<A extends Attrs = undefined> = Node &
Element &
Expand Down
8 changes: 2 additions & 6 deletions src/walker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@ function walker<A extends Attrs>(oldNode: TentNode<A>, newNode: TentNode<A>) {
addAttribute(oldNode, key, attrs[key]);
}

if (oc.length === 0 && nc.length === 0) {
return;
}
if (oc.length === 0 && nc.length === 0) return;

if (oc.length < nc.length) {
for (let i = 0; i < nc.length; i++) {
Expand All @@ -69,9 +67,7 @@ function walker<A extends Attrs>(oldNode: TentNode<A>, newNode: TentNode<A>) {
const oChild = oc[i];
const nChild = nc[i];

if (nChild == null) {
continue;
}
if (nChild == null) continue;

if (oChild.tagName !== nChild.tagName) {
oChild.replaceWith(nChild);
Expand Down

0 comments on commit c4a32df

Please sign in to comment.