Componentes

Los componentes de EmberKit son funciones simples que devuelven elementos JSX. Siguen el mismo modelo mental que React, pero con cero overhead de runtime por defecto.

Definir un componente

function Button({ children, variant = 'primary' }: { children: unknown; variant?: string }) {
  return (
    <button className={`btn btn-${variant}`}>
      {children}
    </button>
  );
}

Los componentes reciben un único objeto de props y devuelven JSX. No hay componentes de clase, métodos de ciclo de vida ni enlace de this.

Usar componentes

function App() {
  return (
    <div>
      <Button>Click me</Button>
      <Button variant="secondary">Cancel</Button>
    </div>
  );
}

Children

Los componentes pueden aceptar children para actuar como contenedores:

function Card({ children, title }: { children: unknown; title: string }) {
  return (
    <div className="card">
      <h3 className="card-title">{title}</h3>
      <div className="card-body">{children}</div>
    </div>
  );
}

Renderizado condicional

Usa expresiones de JavaScript para la salida condicional:

function Status({ online }: { online: boolean }) {
  return (
    <div>
      {online ? <span className="badge-green">Online</span> : <span className="badge-red">Offline</span>}
    </div>
  );
}

Listas

Usa map para renderizar listas con props key:

function TodoList({ items }: { items: string[] }) {
  return (
    <ul>
      {items.map((item) => (
        <li key={item}>{item}</li>
      ))}
    </ul>
  );
}

Estático vs interactivo

function Title() {
  return <h1>Hello</h1>;
}

function Counter() {
  const [count, setCount] = createSignal(0);
  return (
    <div>
      <button type="button" onClick={() => setCount((c) => c + 1)}>+</button>
      <span data-ek-bind={count}>{count()}</span>
    </div>
  );
}

Detalles: Hidratación. Props signal en componentes: Signals.

Interfaz de props

Define los tipos de props con interfaces de TypeScript:

interface ButtonProps {
  children: unknown;
  variant?: 'primary' | 'secondary' | 'ghost';
  size?: 'sm' | 'md' | 'lg';
  disabled?: boolean;
  onClick?: () => void;
}

function Button({ children, variant = 'primary', size = 'md', disabled, onClick }: ButtonProps) {
  return (
    <button
      className={`btn btn-${variant} btn-${size}`}
      disabled={disabled}
      onClick={onClick}
    >
      {children}
    </button>
  );
}

Próximos pasos