structu-rex
Version:
Framework agnostic UI design system builder (Atomic Design, containers/UI, hooks, presenters)
101 lines (98 loc) • 3.91 kB
text/typescript
/**
* Structurex – base configuration layer
* -------------------------------------
* This file lets a host application declare – at **compile time** – the
* concrete type that every `render()` method of a Structurex component
* will return. The mechanism relies exclusively on TypeScript’s type
* system; no runtime state is kept and the generated JavaScript is just
* an empty stub.
*
* Usage in the consuming project:
* ```ts
* import { setRenderOutput } from 'structurex';
*
* // Suppose your render methods always return an `HTMLElement`.
* setRenderOutput<HTMLElement>();
*
* // (Optional but recommended) tell the compiler globally:
* declare module 'structurex' {
* interface StructurexConfig {
* renderOutput: HTMLElement;
* }
* }
* ```
*/
/**
* Internal configuration contract – **do not** implement this interface
* directly; instead augment it from the host application as shown above.
*/
interface StructurexConfig {
/** Placeholder for the type produced by `render()`. */
renderOutput: unknown;
}
/**
* Convenience alias with the selected render-output type.
*/
type RenderOutput = StructurexConfig['renderOutput'];
/**
* Registers the render-output type for the current project.
*
* The generic parameter `T` is **erased** during compilation, therefore
* this function is a no-op at runtime – its sole purpose is to give the
* compiler a point where `T` can be captured and validated.
*/
declare function setRenderOutput<T = unknown>(): void;
/**
* **For internal use only.** Allows base classes to refer to the chosen
* render-output type without exposing the implementation details. The
* function must never run; it merely provides a typed value in the type
* space.
*/
declare function getRenderOutput(): RenderOutput;
declare abstract class AtomicComponent<TProps = unknown> {
protected readonly props: Readonly<TProps>;
/**
* Components receive their data through a strongly-typed, immutable `props` object.
*/
protected constructor(props: Readonly<TProps>);
/**
* Every concrete component must implement `render()` and return the host-defined
* `RenderOutput` type (HTMLElement, string, virtual vnode, etc.).
*/
abstract render(): RenderOutput;
}
declare abstract class UIComponent<TProps = unknown> extends AtomicComponent<TProps> {
}
declare abstract class Atom<TProps = unknown> extends UIComponent<TProps> {
}
declare abstract class Molecule<TProps = unknown> extends UIComponent<TProps> {
}
declare abstract class Organism<TProps = unknown> extends UIComponent<TProps> {
}
declare abstract class Template<TProps = unknown> extends UIComponent<TProps> {
}
declare abstract class Page<TProps = unknown> extends UIComponent<TProps> {
}
declare abstract class ContainerComponent<TState = unknown, TProps = unknown> extends AtomicComponent<TProps> {
/** Internal, immutable snapshot of the component state */
protected state: Readonly<TState>;
constructor(props: Readonly<TProps>);
/**
* Provide the initial state for this container. Called once in the ctor.
*/
protected abstract getInitialState(): TState;
/**
* Imperative setter for derived classes. A specific renderer/runtime can
* replace this with a reactive alternative.
*/
protected setState(partial: Partial<TState>): void;
}
declare abstract class Hook<TOutput = unknown> {
/** Execute the hook and return its outcome */
abstract execute(): TOutput;
}
declare abstract class Presenter<TDto = unknown, TViewModel = unknown> {
/** Transform a data-transfer object into something that a UI can consume */
abstract map(dto: TDto): TViewModel;
}
export { Atom, AtomicComponent, ContainerComponent, Hook, Molecule, Organism, Page, Presenter, type RenderOutput, type StructurexConfig, Template, UIComponent, getRenderOutput, setRenderOutput };