# Migrar de Lite a Pro

> Pasa de super-scheduler-lite a super-scheduler: qué se mantiene, qué valores por defecto y callbacks cambian y cómo adoptar las funciones Pro paso a paso.

Source: https://superscheduler.org/es/docs/migrate-lite-to-pro/
Reviewed: 2026-10-07

Instala el tarball de Pro como `super-scheduler`, cambia los imports y la hoja de estilos de `super-scheduler-lite` a `super-scheduler` y escribe de forma explícita los valores por defecto de Lite, porque los de Pro son distintos (un día de celdas de una hora, edición activada, teclado desactivado). El nombre del componente, las cadenas de fecha ISO, los campos de recursos y eventos y las opciones básicas se mantienen. Sustituye `onTimeRangeClick` de Lite por `onTimeRangeSelected` y después activa las funciones Pro de una en una.

Lite y Pro comparten el nombre del componente, el modelo de fechas civiles y la forma básica de los datos, así que una vista de Lite pasa a Pro con un puñado de cambios. Las diferencias que importan son los valores por defecto, algunos callbacks y los tokens de estilo. Esta guía convierte primero una vista de Lite en una vista de Pro equivalente de solo lectura y después añade las funciones Pro una a una, para que cada paso se pueda probar por separado.

## Qué se mantiene
| Área | Común a Lite y Pro |
|---|---|
| Componente | `SuperSchedulerComponent`, con `ref.current.control` y `controlRef` |
| Fechas | Cadenas ISO civiles con segundos, intervalos semiabiertos, `SuperScheduler.Date` y `SchedulerDate` con los mismos métodos |
| Recursos | `{ id, name }`, con ids comparados de forma estricta (`1` y `'1'` son distintos) |
| Eventos | `id`, `resource`, `start`, `end`, `text`, `backColor`, `fontColor`, `cssClass`, `toolTip`, `tags` |
| Opciones | `startDate`, `days`, `scale: 'Day'`, `cellWidth`, `height`, `rowHeaderWidth`, `rowMinHeight`, `eventHeight`, `locale`, `emptyState` |
| Control | `update()`, `scrollTo()`, `scrollToResource()`, `visibleStart()`, `visibleEnd()`, `dispose()`, `disposed()` |
| Callback | `onEventClick({ e })` con `e.data` |

Todo lo que acepta Lite tiene un equivalente en Pro, salvo `ariaLabel` (ver más abajo). Las opciones de Pro como `treeEnabled` o `zoomLevels`, que Lite rechaza con «unsupported option», funcionan en cuanto cambias de paquete.

## Cambiar de paquete
Pro se instala desde un tarball HTTPS versionado con el nombre de paquete `super-scheduler`. Desinstala Lite salvo que otra parte de tu aplicación lo siga usando:

```sh
npm uninstall super-scheduler-lite
npm install https://npm.superscheduler.org/pro/YOUR_DOWNLOAD_KEY/0.1.0.tgz
```

Después, `package.json` incluye la URL y tu lockfile registra su integridad. La clave de esa URL es un secreto de descarga: aparece en `package.json` y en el lockfile, así que trátalos en consecuencia. [Instalar SuperScheduler Pro](https://superscheduler.org/es/docs/install-pro/) explica las claves, la CI y las actualizaciones. Pro declara React y React DOM (18.2 o posterior, o 19) como dependencias peer.

## Actualizar imports, estilos y valores por defecto
Esta es una vista de Lite:

```tsx
// src/Availability.tsx (Lite)
import { useState } from 'react'
import { SuperSchedulerComponent } from 'super-scheduler-lite'
import type { SuperScheduler } from 'super-scheduler-lite'
import 'super-scheduler-lite/styles.css'

const ROOMS: SuperScheduler.ResourceData[] = [
  { id: 'r101', name: 'Room 101' },
  { id: 'r102', name: 'Room 102' },
]
const EVENTS: SuperScheduler.EventData[] = [
  {
    id: 'b-1042',
    resource: 'r101',
    start: '2026-10-02T14:00:00',
    end: '2026-10-05T11:00:00',
    text: 'Ana Ruiz',
    backColor: '#dbeafe',
  },
  {
    id: 'b-1043',
    resource: 'r102',
    start: '2026-10-03T14:00:00',
    end: '2026-10-08T11:00:00',
    text: 'Tom Berg',
    backColor: '#dcfce7',
  },
]

/** Before: the read-only Lite view. */
export function Availability() {
  const [picked, setPicked] = useState('')
  return (
    <>
      <p aria-live="polite">{picked}</p>
      <SuperSchedulerComponent
        startDate="2026-10-01"
        resources={ROOMS}
        events={EVENTS}
        ariaLabel="Room availability"
        onEventClick={({ e }) => setPicked(`Booking ${String(e.data.id)}`)}
        onTimeRangeClick={({ start, resource }) =>
          setPicked(`Free: ${String(resource)} on ${start.toString('d MMM')}`)
        }
      />
    </>
  )
}
```
Y esta, la misma vista en Pro:

```tsx
// src/Availability.tsx (Pro)
import { useCallback, useState } from 'react'
import { SuperSchedulerComponent } from 'super-scheduler'
import type {
  SchedulerEventClickArgs,
  SchedulerTimeRangeSelectedArgs,
  SuperScheduler,
} from 'super-scheduler'
import 'super-scheduler/styles.css'

const ROOMS: SuperScheduler.ResourceData[] = [
  { id: 'r101', name: 'Room 101' },
  { id: 'r102', name: 'Room 102' },
]
const EVENTS: SuperScheduler.EventData[] = [
  {
    id: 'b-1042',
    resource: 'r101',
    start: '2026-10-02T14:00:00',
    end: '2026-10-05T11:00:00',
    text: 'Ana Ruiz',
    backColor: '#dbeafe',
  },
  {
    id: 'b-1043',
    resource: 'r102',
    start: '2026-10-03T14:00:00',
    end: '2026-10-08T11:00:00',
    text: 'Tom Berg',
    backColor: '#dcfce7',
  },
]
// Lite draws one header row with "d MMM" per day.
const TIME_HEADERS: SuperScheduler.TimeHeaderData[] = [{ groupBy: 'Day', format: 'd MMM' }]

/** After: the same view on Pro, still read-only. */
export function Availability() {
  const [picked, setPicked] = useState('')
  // Pro splices the events array it receives: give it its own copy.
  const [events] = useState(() => EVENTS.slice())

  const onEventClick = useCallback((args: SchedulerEventClickArgs) => {
    setPicked(`Booking ${String(args.e.id())}`)
  }, [])

  // Lite's onTimeRangeClick fires for any empty cell. In Pro, clicking an empty cell selects it;
  // Pro's own onTimeRangeClick fires only for a click on a range that is already selected.
  const onTimeRangeSelected = useCallback((args: SchedulerTimeRangeSelectedArgs) => {
    args.control.clearSelection()
    if (args.origin !== 'click' && args.origin !== 'keyboard') return
    setPicked(`Free: ${String(args.resource)} on ${args.start.toString('d MMM')}`)
  }, [])

  return (
    // Pro has no ariaLabel option: name the region around it.
    <section aria-label="Room availability">
      <p aria-live="polite">{picked}</p>
      <SuperSchedulerComponent
        // Lite's defaults, written out: Pro's defaults differ.
        startDate="2026-10-01"
        days={31}
        scale="Day"
        cellWidth={64}
        heightSpec="Fixed"
        height={400}
        rowHeaderWidth={160}
        rowHeaderWidthAutoFit={false}
        rowMinHeight={40}
        eventHeight={26}
        timeHeaders={TIME_HEADERS}
        emptyState="No resources"
        // Read-only, as in Lite: Pro enables dragging, resizing and zoom gestures by default.
        eventMoveHandling="Disabled"
        eventResizeHandling="Disabled"
        zoomGesture={false}
        // Keyboard navigation is built into Lite and opt-in in Pro.
        keyboardEnabled
        keyboardTarget="component"
        keyboardMode="Full"
        resources={ROOMS}
        events={events}
        onEventClick={onEventClick}
        onTimeRangeSelected={onTimeRangeSelected}
      />
    </section>
  )
}
```
Deberías ver las mismas habitaciones, reservas y colores, los mismos mensajes al hacer clic y ningún arrastre. La cuadrícula usa la fuente de tu página en lugar de la fuente del sistema de 13 px de Lite, y los colores del tema de Pro.

Los cambios, por orden:

1. Imports: `super-scheduler-lite` pasa a ser `super-scheduler`, y `super-scheduler-lite/styles.css` pasa a ser `super-scheduler/styles.css`.
2. Valores por defecto: escribe de forma explícita cada valor por defecto de Lite del que dependías (tabla de abajo).
3. Comportamiento: desactiva lo que Pro activa por defecto y activa el soporte de teclado.
4. Callbacks: pasa los clics en celdas a `onTimeRangeSelected`.
5. Datos: dale al control su propia copia del array de eventos, porque Pro modifica con splice el array que recibe cuando cambian los eventos. Lite trata sus arrays como de solo lectura.

| Opción | Por defecto en Lite | Por defecto en Pro |
|---|---|---|
| `days` | `31` | `1` |
| `scale` | `'Day'` (el único valor) | `'CellDuration'` con `cellDuration: 60`, celdas de una hora |
| `cellWidth` | `64` | `40` |
| `height` | `400`, fija | `600`, como máximo (`heightSpec: 'Max'`): la cuadrícula se ajusta a sus filas |
| `rowHeaderWidth` | `160` | `80`, y `rowHeaderWidthAutoFit: true` la ensancha hasta que caben los nombres |
| `rowMinHeight` | `40` | `0` |
| `eventHeight` | `26` | `35` |
| `emptyState` | `'No resources'` | ninguno |
| `ariaLabel` | `'Resource schedule'` | no disponible |
| Cabecera de tiempo | una fila, `d MMM` | `[{ groupBy: 'Default' }, { groupBy: 'Cell' }]` |

Pro no tiene la opción `ariaLabel`: su cuadrícula tiene un nombre accesible integrado. Pon la etiqueta en la región que la contiene, como hace el ejemplo con `<section aria-label>`.

### Estilos y selectores
Los nombres de clase y los tokens cambian de prefijo. La raíz de Lite es `.super-scheduler-lite`, con partes como `.super-scheduler-lite__event`; la raíz de Pro es `.super-scheduler`, con `.super-scheduler__event`, más los marcadores `[data-super-scheduler-part]`. Como punto de partida, traslada así los seis tokens de Lite:

| Token de Lite | Token de Pro |
|---|---|
| `--super-scheduler-background` | `--super-scheduler-surface` |
| `--super-scheduler-text` | `--super-scheduler-text` |
| `--super-scheduler-border` | `--super-scheduler-border` |
| `--super-scheduler-header` | sin un equivalente único; da estilo al slot `timeHeader` o a `.super-scheduler__header` |
| `--super-scheduler-event` | `--super-scheduler-event-bg` (o `backColor` en cada evento) |
| `--super-scheduler-focus` | `--super-scheduler-focus-color` y `--super-scheduler-focus-ring` |

Pro tiene un conjunto de tokens más completo, modo oscuro y presets de densidad; consulta [Temas](https://superscheduler.org/es/docs/theming/).

## Comportamiento que Pro activa
Lite es de solo lectura por diseño. Pro es un editor, así que de serie:

- mueve y redimensiona eventos arrastrando (`eventMoveHandling` y `eventResizeHandling` valen `'Update'` por defecto);
- selecciona rangos de tiempo con clic y arrastre (`timeRangeSelectedHandling: 'Enabled'`) y deja la sombra de la selección hasta la siguiente selección, un clic en otro sitio o `clearSelection()`;
- hace zoom con Ctrl o Cmd más la rueda y con el gesto de pellizco (`zoomGesture: true`);
- deja desactivado el soporte de teclado (`keyboardEnabled: false`), mientras que Lite siempre tiene navegación con las flechas. Con `keyboardEnabled`, Pro escucha en todo el documento salvo que `keyboardTarget` sea `'component'`.

El ejemplo de Pro de arriba fija todo esto al comportamiento de Lite. Quita esas líneas de una en una a medida que adoptes funciones.

## Callbacks con argumentos más completos
| Lite | Pro |
|---|---|
| `onEventClick({ control, e: { data }, originalEvent })` | `onEventClick({ e, div, control, originalEvent, ctrl, shift, meta, preventDefault })`, donde `e` es un `SuperScheduler.Event` con `data`, `id()`, `start()`, `end()`, `text()`, `resource()` y `duration()`; después, `onEventClicked` |
| `onTimeRangeClick({ control, start, end, resource, originalEvent })` en cualquier celda vacía | `onTimeRangeSelected({ start, end, resource, control, origin, multirange })`, con `origin` igual a `'click'`, `'drag'`, `'keyboard'` o `'api'` |

> **Behavior:**
> Pro también tiene un `onTimeRangeClick`, pero significa otra cosa: se dispara cuando el usuario hace clic en un rango de tiempo que ya está seleccionado. En Pro, un clic en una celda vacía es una selección de una celda que comunican `onTimeRangeSelect` (antes, cancelable) y `onTimeRangeSelected` (después). Filtra por `args.origin === 'click'` si los arrastres no deben contar.

Otras diferencias que conviene revisar en tus handlers:

- En Pro, los handlers se ejecutan con `this` apuntando al control, y la mayoría de los argumentos incluyen `control`.
- En Lite, `originalEvent` es un `KeyboardEvent` cuando una celda o un evento se activa con el teclado. En Pro, Intro sobre un evento genera un clic, así que `onEventClick` siempre recibe un `MouseEvent`, e Intro sobre una celda es una selección con `origin: 'keyboard'`.
- En Lite, los callbacks de `controlRef` se llaman con `null` al desmontar; Pro solo los llama con el control y vacía los objetos ref al desmontar.
- En Pro, `scrollTo(date)` acepta los argumentos opcionales `animated` y `position`.

## Cuando los dos paquetes están instalados
Algunos productos mantienen Lite en las páginas públicas y usan Pro en el backoffice. Funciona, con dos reglas:

- **Intercambia cadenas ISO, no objetos de fecha.** Cada edición tiene su propia clase de fecha, y Pro rechaza un objeto de fecha de Lite.
- **Mantén separado su CSS.** Cada paquete tiene su propia hoja de estilos. Algunos nombres de token existen en los dos (`--super-scheduler-text`, `--super-scheduler-border`), así que limita las sobrescrituras de Lite a `.super-scheduler-lite` en lugar de `:root`.

```ts
// src/dates.ts
import { type SuperScheduler as Lite } from 'super-scheduler-lite'
import { SuperScheduler as Pro } from 'super-scheduler'

// Each edition has its own date class. Passing a Lite date object to Pro throws
// ("expected a Date, a SchedulerDate, a number of ticks or an ISO 8601 string").
export function toProDate(date: Lite.Date): Pro.Date {
  return new Pro.Date(date.value)
}

// Shared state, URLs and storage hold civil ISO strings, which both editions accept.
export const selectedDay: string = Pro.Date.today().value
```
Cuando un mismo módulo necesite los dos componentes, impórtalos con nombres locales distintos, por ejemplo `import { SuperSchedulerComponent as LiteScheduler } from 'super-scheduler-lite'`.

## Adoptar las funciones Pro paso a paso
Cuando la vista de solo lectura coincida, añade una capacidad cada vez y pruébala:

1. **Teclado y accesibilidad.** Mantén `keyboardEnabled` y `keyboardMode="Full"`; consulta [Teclado, accesibilidad y táctil](https://superscheduler.org/es/docs/keyboard-accessibility-touch/).
2. **Edición.** Quita `eventMoveHandling="Disabled"` y `eventResizeHandling="Disabled"`, añade reglas con `onEventMoving` y `onEventMove`, y persiste los cambios desde `onEventsChange`; consulta [Reglas de arrastre y redimensionado](https://superscheduler.org/es/docs/drag-resize-rules/) y [Estado controlado](https://superscheduler.org/es/docs/controlled-state/).
3. **Creación de reservas.** Usa `onTimeRangeSelected` con `origin === 'drag'` para abrir un formulario.
4. **Horas y zoom.** Añade `zoomLevels` y quita `zoomGesture={false}`; consulta [Escalas de tiempo y zoom](https://superscheduler.org/es/docs/time-scales-zoom/).
5. **Filas.** Árboles, filas fijas, filas divididas y columnas en la cabecera de fila; consulta [Árboles, columnas y selección](https://superscheduler.org/es/docs/trees-columns-selection/).
6. **Módulos.** [Deshacer y rehacer](https://superscheduler.org/es/docs/undo-redo/), [Minimapa](https://superscheduler.org/es/docs/minimap-metrics/), [Vínculos](https://superscheduler.org/es/docs/links-dependencies/), [Paneles y vistas guardadas](https://superscheduler.org/es/docs/panes-saved-views/) y [Carga por rangos](https://superscheduler.org/es/docs/range-loading/).
7. **Contenido React.** Cambia el import a `super-scheduler/react-render` cuando necesites React dentro de eventos o cabeceras; consulta [Slots de renderizado React](https://superscheduler.org/es/docs/react-render-slots/).

→ https://superscheduler.org/es/examples/hotel-rooms/
Para preguntas comerciales sobre Pro, consulta la [página de precios](https://superscheduler.org/es/pricing/).
