# Inicio rápido con Lite

> Instala super-scheduler-lite desde npm y pinta una línea de tiempo diaria de recursos en React: opciones y valores por defecto, clics, control imperativo y límites.

Source: https://superscheduler.org/es/docs/quick-start-lite/
Reviewed: 2026-10-07

Ejecuta npm install super-scheduler-lite, importa SuperSchedulerComponent y super-scheduler-lite/styles.css, y pasa startDate, days, resources y events. Lite pinta una línea de tiempo virtualizada y de solo lectura con una celda por día, comunica los clics mediante onEventClick y onTimeRangeClick, y lanza un error ante cualquier opción que no implemente.

SuperScheduler Lite es la edición pública y de solo lectura: una fila por recurso, una columna por día, los eventos como barras y los clics comunicados a tu código. Es la forma más rápida de poner un gráfico de ocupación o de disponibilidad en una aplicación React. Esta guía te lleva de un proyecto vacío a una línea de tiempo funcionando y después repasa todas las opciones, los callbacks, la API imperativa y lo que Lite rechaza a propósito.

Si necesitas arrastrar, redimensionar, horas y minutos, zoom o árboles de recursos, eso es cosa de Pro: consulta [Instalar SuperScheduler Pro](https://superscheduler.org/es/docs/install-pro/) y [Migrar de Lite a Pro](https://superscheduler.org/es/docs/migrate-lite-to-pro/).

## Requisitos
- React 18.2 o posterior, o React 19. React es una peer dependency, así que Lite usa la copia de tu aplicación.
- Un bundler o framework que entienda módulos ES o CommonJS (Vite, Next.js, webpack, Parcel y similares). El paquete incluye ambos formatos con sus declaraciones de TypeScript.
- Un entorno de navegador para pintar. El paquete se puede importar durante el renderizado en servidor; la línea de tiempo en sí se construye en el navegador cuando el componente se monta.

## Instalar el paquete
```sh
npm install super-scheduler-lite react react-dom
```

`react-dom` aparece porque es lo que usas para renderizar, no porque Lite lo importe.

## Pintar una primera línea de tiempo
```tsx
// src/Planning.tsx
import { SuperSchedulerComponent } from 'super-scheduler-lite'
import type { SuperScheduler } from 'super-scheduler-lite'
import 'super-scheduler-lite/styles.css'

// Module-level arrays keep the same identity on every render, so React never re-applies them.
const ROOMS: SuperScheduler.ResourceData[] = [
  { id: 'r101', name: 'Room 101' },
  { id: 'r102', name: 'Room 102' },
  { id: 'r103', name: 'Room 103' },
]

const BOOKINGS: SuperScheduler.EventData[] = [
  // Date-only values: the bar covers 2, 3 and 4 October (the end is exclusive).
  { id: 1, resource: 'r101', start: '2026-10-02', end: '2026-10-05', text: 'Booking 1042' },
  // Overlaps the first booking on the same row: Lite stacks it on a second line.
  {
    id: 2,
    resource: 'r101',
    start: '2026-10-04',
    end: '2026-10-07',
    text: 'Booking 1043',
    backColor: '#dbeafe',
  },
  // Times are kept: the bar starts at 14:00 and ends at 11:00, inside the day cells.
  {
    id: 3,
    resource: 'r103',
    start: '2026-10-06T14:00:00',
    end: '2026-10-09T11:00:00',
    text: 'Booking 1051',
  },
]

export function Planning() {
  return (
    <SuperSchedulerComponent startDate="2026-10-01" days={31} resources={ROOMS} events={BOOKINGS} />
  )
}
```
Deberías ver una cuadrícula de 400 píxeles de alto con una cabecera de etiquetas de día (`1 Oct`, `2 Oct`, …), tres filas de habitaciones y tres barras. La reserva 1042 ocupa el 2, el 3 y el 4 de octubre: la fecha de fin es exclusiva, así que una estancia que termina el `2026-10-05` desaparece a medianoche del día 5. La reserva 1043 se solapa con ella, así que Room 101 pasa a tener dos líneas y apila las dos barras. La reserva 1051 empieza a las 14:00 del día 6 y termina a las 11:00 del día 9: Lite coloca las barras en su hora exacta dentro de las celdas de día.

Haz scroll en cualquier dirección. Solo las filas, los días y los eventos visibles existen en el DOM, y el scroll nunca provoca un render de React, sea cual sea el tamaño de tus datos.

> **Tip:**
> Mantén `resources` y `events` estables entre renders: constantes de módulo, estado o `useMemo`. El componente compara las props por identidad y solo envía al control las que han cambiado, así que un array literal nuevo en cada render reconstruye la línea de tiempo cada vez.

## Importar los estilos
Importa `super-scheduler-lite/styles.css` una sola vez, normalmente en tu archivo de entrada o en el layout raíz. Las reglas viven en una capa de cascada CSS llamada `super-scheduler`, así que cualquier regla sin capa de tu propia hoja de estilos las sobrescribe sin `!important`.

El elemento raíz tiene la clase `super-scheduler-lite` y seis propiedades personalizadas. Sobrescríbelas en esa clase (no en un ancestro lejano, porque la raíz declara sus propios valores):

```css
.super-scheduler-lite {
  --super-scheduler-background: #ffffff;
  --super-scheduler-text: #18212f;
  --super-scheduler-border: #dce3ed;
  --super-scheduler-header: #f4f7fb;
  --super-scheduler-event: #d7e8fa;
  --super-scheduler-focus: #005cbf;
}

/* A dark theme driven by your own class on <html>. */
.dark .super-scheduler-lite {
  --super-scheduler-background: #121518;
  --super-scheduler-text: #f4f4f5;
  --super-scheduler-border: #2b3139;
  --super-scheduler-header: #1b1f24;
  --super-scheduler-event: #1f3a5c;
}
```

Lite define su propia fuente (system UI de 13 px) y ocupa todo el ancho de su contenedor. Los colores de cada evento salen de los datos (`backColor`, `fontColor`) o de una `cssClass` a la que das estilo tú.

## Opciones y valores por defecto
Todas las opciones que acepta Lite están en esta tabla. Cualquier otra lanza un error (consulta [Lo que Lite rechaza](#rejects)).

| Opción | Tipo | Por defecto | Notas |
|---|---|---|---|
| `startDate` | cadena ISO o `SuperScheduler.Date` | Hoy | El primer día; la hora se ignora |
| `days` | entero positivo | `31` | Número de columnas de día |
| `scale` | `'Day'` | `'Day'` | El único valor aceptado |
| `cellWidth` | número (px) | `64` | Ancho de un día |
| `height` | número (px) | `400` | Alto total de la caja con scroll, cabecera incluida |
| `rowHeaderWidth` | número (px) | `160` | Ancho de la columna con el nombre del recurso |
| `rowMinHeight` | número (px) | `40` | Las filas crecen cuando se apilan eventos solapados |
| `eventHeight` | número (px) | `26` | Alto de una línea de eventos |
| `resources` | `ResourceData[]` | `[]` | `{ id, name }`, plana |
| `events` | `EventData[]` | `[]` | Consulta [Campos de eventos](#event-fields) |
| `locale` | cadena | `'en-us'` | Etiquetas de día en la cabecera, como `es-es` o `de-de` |
| `ariaLabel` | cadena | `'Resource schedule'` | Nombre accesible de la cuadrícula, que también se muestra en la esquina superior izquierda |
| `emptyState` | cadena | `'No resources'` | Texto que se muestra cuando `resources` está vacío |
| `onEventClick` | función | ninguno | Consulta [Responder a los clics](#clicks) |
| `onTimeRangeClick` | función | ninguno | Consulta [Responder a los clics](#clicks) |

Las opciones numéricas deben ser positivas y finitas, y `days` debe ser un entero.

## Campos de eventos y recursos
Un recurso es `{ id, name }`. Un evento tiene cinco campos obligatorios y cinco opcionales:

| Campo | Obligatorio | Significado |
|---|---|---|
| `id` | sí | Cadena o número finito, único entre los eventos |
| `resource` | sí | El `id` de la fila a la que pertenece, con el mismo tipo |
| `start`, `end` | sí | Cadenas ISO (`2026-10-02` o `2026-10-02T14:00:00`, segundos incluidos) o `SuperScheduler.Date`; `end` es exclusivo |
| `text` | sí | La etiqueta, que se pinta como texto (nunca como HTML) |
| `backColor`, `fontColor` | no | Cualquier color CSS |
| `cssClass` | no | Nombres de clase adicionales en el botón del evento |
| `toolTip` | no | Tooltip nativo; por defecto, `text` |
| `tags` | no | Cualquier valor que quieras recuperar en `onEventClick` |

Los ids se comparan de forma estricta: `1` y `'1'` son ids distintos, así que un evento con `resource: '101'` no aparece en una fila con `id: 101`. Las fechas son valores civiles de reloj sin zona horaria; la [guía del modelo de datos](https://superscheduler.org/es/docs/resources-events-intervals/) explica las reglas, que son las mismas en ambas ediciones.

## Responder a los clics
Lite comunica dos interacciones. `onEventClick` recibe `{ control, e, originalEvent }`, donde `e.data` es tu objeto de evento. `onTimeRangeClick` recibe `{ control, start, end, resource, originalEvent }` cuando se pulsa una celda de día vacía; `start` es ese día a medianoche y `end` la medianoche siguiente, ambos como `SuperScheduler.Date`.

```tsx
// src/PlanningWithDetails.tsx
import { useCallback, useState } from 'react'
import { SuperSchedulerComponent } from 'super-scheduler-lite'
import type {
  SchedulerEventClickArgs,
  SchedulerTimeRangeClickArgs,
  SuperScheduler,
} from 'super-scheduler-lite'

interface PlanningProps {
  readonly rooms: SuperScheduler.ResourceData[]
  readonly bookings: SuperScheduler.EventData[]
}

export function PlanningWithDetails({ rooms, bookings }: PlanningProps) {
  const [detail, setDetail] = useState('Select a booking or a free day.')

  // Stable callbacks: a new function per render would be sent to the control on every render.
  const onEventClick = useCallback((args: SchedulerEventClickArgs) => {
    // Lite hands you the event's own data object, including `tags`.
    setDetail(`${args.e.data.text} (id ${String(args.e.data.id)})`)
  }, [])

  const onTimeRangeClick = useCallback((args: SchedulerTimeRangeClickArgs) => {
    // One day cell: `end` is the next midnight. Enter and Space on the active cell also land here.
    setDetail(`Free cell: ${String(args.resource)} on ${args.start.toString('d MMMM yyyy')}`)
  }, [])

  return (
    <>
      <p aria-live="polite">{detail}</p>
      <SuperSchedulerComponent
        startDate="2026-10-01"
        days={31}
        resources={rooms}
        events={bookings}
        onEventClick={onEventClick}
        onTimeRangeClick={onTimeRangeClick}
      />
    </>
  )
}
```
Deberías ver cómo cambia el párrafo al pulsar una reserva o una celda libre. Los mismos callbacks funcionan con el teclado: Tab pone el foco en la cuadrícula, las flechas mueven la celda activa e Intro o Espacio sobre ella llaman a `onTimeRangeClick`; los eventos son botones, así que Intro sobre un evento con foco llama a `onEventClick`. `originalEvent` es el evento DOM que hay detrás de la llamada: el `KeyboardEvent` cuando Intro o Espacio activaron una celda, y un evento de clic en los demás casos.

> **Behavior:**
> Los argumentos de los callbacks de Lite son más reducidos que los de Pro: `e` solo expone `data`. En Pro, `args.e` es un envoltorio `SuperScheduler.Event` con métodos como `id()` y `start()`. Si piensas migrar, basa la lógica de tus handlers en los campos de `e.data`.

## Controlar la línea de tiempo desde código
El componente React crea un control al montarse y lo libera al desmontarse. Accede a él mediante `ref.current.control` en el componente o con la prop `controlRef` (un objeto ref o un callback; Lite lo pone a `null` al desmontar).

```tsx
// src/NavigablePlanning.tsx
import { useRef } from 'react'
import { SuperScheduler, SuperSchedulerComponent } from 'super-scheduler-lite'

interface PlanningProps {
  readonly rooms: SuperScheduler.ResourceData[]
  readonly bookings: SuperScheduler.EventData[]
}

export function NavigablePlanning({ rooms, bookings }: PlanningProps) {
  // Lite sets `current` after mount and clears it on unmount.
  const controlRef = useRef<SuperScheduler.Scheduler | null>(null)

  const goToToday = () => controlRef.current?.scrollTo(SuperScheduler.Date.today())
  const findRoom = (id: SuperScheduler.ResourceData['id']) =>
    controlRef.current?.scrollToResource(id)
  const logRange = () => {
    const control = controlRef.current
    if (control !== null)
      console.info(`${control.visibleStart().value} to ${control.visibleEnd().value}`)
  }

  return (
    <>
      <div role="toolbar" aria-label="Planning navigation">
        <button type="button" onClick={goToToday}>
          Today
        </button>
        <button type="button" onClick={() => findRoom('r310')}>
          Room 310
        </button>
        <button type="button" onClick={logRange}>
          Visible range
        </button>
      </div>
      <SuperSchedulerComponent
        controlRef={controlRef}
        startDate="2026-10-01"
        days={92}
        height={520}
        resources={rooms}
        events={bookings}
      />
    </>
  )
}
```
El control de Lite tiene ocho miembros:

| Miembro | Qué hace |
|---|---|
| `update(options)` | Combina `options` con las opciones actuales y vuelve a dibujar. Un `undefined` explícito restaura el valor por defecto |
| `scrollTo(date)` | Hace scroll para que `date` quede en el borde izquierdo |
| `scrollToResource(id)` | Hace scroll para que esa fila quede arriba |
| `visibleStart()`, `visibleEnd()` | Las fechas en los bordes izquierdo y derecho de la vista desplazada |
| `disposed()` | Si `dispose()` ya se ha ejecutado |
| `dispose()` | Elimina el DOM, los listeners y los observers, y libera los datos |
| `init()` | Construye el DOM; el componente React lo llama por ti |

Sin React, crea el control sobre un elemento que sea tuyo:

```ts
// src/mount-planning.ts
import { SuperScheduler } from 'super-scheduler-lite'
import 'super-scheduler-lite/styles.css'

/** Mounts a read-only planning into `host` without React and returns its teardown. */
export function mountPlanning(host: HTMLElement): () => void {
  const control = new SuperScheduler.Scheduler(host, {
    startDate: '2026-10-01',
    days: 31,
    resources: [
      { id: 'r101', name: 'Room 101' },
      { id: 'r102', name: 'Room 102' },
    ],
    events: [
      { id: 1, resource: 'r101', start: '2026-10-02', end: '2026-10-05', text: 'Booking 1042' },
    ],
    onEventClick: ({ e }) => console.info('booking', e.data.id),
  })
  control.init()

  // update() merges with the current options; an explicit undefined restores a default.
  control.update({ days: 62, cellWidth: 48 })
  control.scrollTo('2026-10-15')

  return () => control.dispose()
}
```
## Actualizar los datos
El componente solo envía a `control.update()` las props que han cambiado, comparándolas por identidad. Para cambiar los datos, pasa un array nuevo: `setEvents([...events, next])` funciona, mientras que `events.push(next)` sobre el mismo array no llega a la línea de tiempo hasta que llamas tú a `control.update()`. Las actualizaciones que solo cambian `onEventClick` u `onTimeRangeClick` sustituyen los callbacks sin volver a dibujar.

## Lo que Lite rechaza
Lite valida su entrada y lanza un error en lugar de ignorar lo que no sabe hacer, así que un error de configuración aparece durante el desarrollo y no como una pantalla que funciona a medias:

- Una opción que no está en la tabla anterior, incluidas opciones de Pro como `allowEventOverlap` o `zoomLevels`, aunque se pasen desde JavaScript plano: `SuperScheduler Lite: unsupported option "zoomLevels"`.
- Un `scale` distinto de `'Day'`.
- Un recurso con `children`, `frozen`, `split` o `columns` (`resource children requires Pro`).
- Ids de recurso duplicados, ids que no son cadenas ni números finitos, y eventos cuyo `end` es anterior a su `start`.
- Tamaños no positivos o no finitos, y un `days` fraccionario.

Cuando `update()` lanza un error, la configuración anterior sigue en pantalla y utilizable. En React, el error se lanza mientras el componente aplica las props nuevas, así que un error boundary por encima lo captura.

> **Limitation:**
> Lite no tiene edición, celdas de horas o minutos, zoom, scroll infinito, árboles de recursos, filas fijas o divididas, vínculos, selección, resaltado de conflictos, minimapa, paneles, historial, vistas guardadas, carga por rangos ni slots de renderizado React. Su código no está en el paquete. Los campos adicionales de tus objetos de evento se conservan, pero no activan nada.

## Siguientes pasos
- Entiende las reglas de datos comunes a ambas ediciones: [Recursos, eventos e intervalos](https://superscheduler.org/es/docs/resources-events-intervals/).
- Integra el componente correctamente en una aplicación React más grande: [Integración con React](https://superscheduler.org/es/docs/react-integration/).
- Mira cómo es una planificación editable en los [ejemplos](https://superscheduler.org/es/examples/), todos construidos con Pro.
- Cuando necesites edición: [Migrar de Lite a Pro](https://superscheduler.org/es/docs/migrate-lite-to-pro/).
