UNPKG

libreria-renderizado-npm

Version:

Una librería básica para gestionar el estado y JSX

93 lines (74 loc) 2.82 kB
type Listener = () => void; export function createState<T>(initialValue: T) { let value = initialValue; const listeners = new Set<Listener>(); function setState(newValue: T): void { if (newValue !== value) { value = newValue; listeners.forEach(listener => listener()); } } function getState(): T { return value; } function subscribe(listener: Listener): () => void { if (typeof listener !== 'function') { throw new Error('El listener debe ser una función'); } listeners.add(listener); // Devuelve una función que permitirá desuscribirse return () => listeners.delete(listener); } return [getState, setState, subscribe] as const; } // Función para crear un elemento con JSX export function jsx(type: string, props: { [key: string]: any }, ...children: any[]): HTMLElement { if (typeof type !== 'string') { throw new Error('El tipo del elemento debe ser una cadena'); } const el = document.createElement(type); if (props) { Object.keys(props).forEach((key) => { if (key.startsWith('on')) { const event = key.substring(2).toLowerCase(); if (typeof props[key] === 'function') { el.addEventListener(event, props[key]); } else { console.warn(`El manejador del evento ${event} no es una función.`); } } else if (key === 'className') { el.classList.add(props[key]); } else { el.setAttribute(key, props[key]); } }); } children.forEach((child) => { if (typeof child === 'string') { el.appendChild(document.createTextNode(child)); } else if (child instanceof HTMLElement) { el.appendChild(child); } }); return el; } // Función para renderizar un componente en un contenedor // Función para renderizar un componente en un contenedor // Función para renderizar un componente en un contenedor export function render(component: () => { element: HTMLElement, subscribe: (listener: () => void) => () => void }, container: HTMLElement): () => void { if (!container || !(container instanceof HTMLElement)) { throw new Error('El contenedor debe ser un elemento DOM válido'); } function update(): void { const { element } = component(); // Obtener el componente renderizado container.innerHTML = ''; // Limpiar el contenedor container.appendChild(element); // Añadir el componente al contenedor } update(); // Primer renderizado // La función subscribe devuelve una función para desuscribirse const unsubscribe = component().subscribe(update); // Suscribirse al estado return () => { update(); unsubscribe(); // Desuscribirse cuando sea necesario }; }