This commit is contained in:
2026-03-15 15:09:36 +09:00
parent a457a80bfe
commit f4df35b344
18 changed files with 149 additions and 430 deletions

View File

@@ -1,4 +1,5 @@
import { State, type ValuesOfStateArray } from "./State";
import type { PropsBase, PropStates, StatesBase } from "../types.js";
import { State, type ValuesOfStateArray } from "./State.js";
export abstract class ComponentBase<Props extends PropsBase, States extends StatesBase> {
static propsToPropStates<Props extends PropsBase>(props: Props | PropStates<Props>) {
@@ -14,7 +15,7 @@ export abstract class ComponentBase<Props extends PropsBase, States extends Stat
return propsState as PropStates<Props>;
}
states: States = {} as States;
states: PropStates<States> = {} as PropStates<States>;
propStates: PropStates<Props>;
children: ComponentBase<any, any>[] = [];
mounted: boolean = false;
@@ -29,21 +30,8 @@ export abstract class ComponentBase<Props extends PropsBase, States extends Stat
init(): void { }
protected abstract createNode(): Node;
mount(target: Node) {
if (this.mounted) {
throw new Error("This component is already mounted");
}
target.appendChild(this.node);
this.mounted = true;
this.onMount?.();
}
destroy() {
this.children.forEach((child) => child.destroy());
this.subscriberSymbols.forEach(({ state, symbol }) => {
state.unsubscribe(symbol);
});
this.onDestoy?.();
};
abstract mount(target: Node): any;
abstract destroy(): any;
onMount(): void { };
onDestoy(): void { };
@@ -77,28 +65,4 @@ export abstract class ComponentBase<Props extends PropsBase, States extends Stat
}
propState.set(value);
}
}
export type StatesBase = Record<string, State<any>>;
export type PropsBase = Record<string, any>;
export type PropStates<Props extends PropsBase> = {
[K in keyof Props]: State<Props[K]>
}
export type ComponentBlueprint<Props extends PropsBase, States extends StatesBase> = {
type: 'component',
component: new (props: Props, children?: Blueprint[]) => ComponentBase<Props, States>,
props: Props,
children: Blueprint[]
}
export type HTMLBlueprint = {
type: 'html',
tag: string;
props: Record<string, any>;
children: Blueprint[]
}
export type TextBlueprint = {
type: 'text',
props: { content: State<any> | any }
}
export type Blueprint = ComponentBlueprint<any, any> | HTMLBlueprint | TextBlueprint;
}