Saltar al contenido
Índice de Kit UI
Kit UI Componentes

Reproducción temporal.

Patrón canónico de reproducción temporal para cochid-mapas, cables, transporte y mapa de santiago.

Verlo por niveles

Primero el componente, después la variación de marca y finalmente su uso dentro de una página.

Nivel 1Componente canónico
Fuente: cortes de DTPM · intervalo 5 min
Nivel 2Compañía de Innovación de Santiago · variación
Fuente: cortes de DTPM · intervalo 5 min
Nivel 3Dentro de una página
Sitio · sección
Fuente: cortes de DTPM · intervalo 5 min
Ver y copiar el código de este render
HTML del nivel canónico
<section class="ui-sample ui-map" data-map-playback="true"><div class="ui-actions" role="toolbar" aria-label="Reproducción temporal"><button class="btn btn--primary" type="button">Reproducir</button><button class="btn btn--secondary" type="button">Anterior</button><button class="btn btn--secondary" type="button">Siguiente</button><label>Velocidad <select class="input"><option>1×</option><option selected="">2×</option></select></label></div><time dateTime="2026-08-25T18:24:00-04:00">18:24 CLT</time><small>Fuente: cortes de DTPM · intervalo 5 min</small></section>

Variaciones por marca y sitio

Cada cambio visible declara su autoridad; lo que permanece canónico no se vuelve a inventar en el producto.

cochid.cl

COCHID

Autoridad: core-style/DECISIONES.md M15 y LOGOS-CANONICOS.md
Fuente: cortes de DTPM · intervalo 5 min

Cambia en esta marca

  • Cuadrado azul y namebrand de tres líneas
  • Azul COCHID en selección, capas y series

Permanece canónico

  • Estructura y semántica comunes
  • Fuentes, unidades y alternativa tabular
innovacionsantiago.cl

Compañía de Innovación de Santiago

Autoridad: CONSTITUTION.md + LOGOS-CANONICOS.md
Fuente: cortes de DTPM · intervalo 5 min

Cambia en esta marca

  • Navegación y contenido propios del servicio
  • Acento reservado para acciones y datos

Permanece canónico

  • Mark CIS y namebrand de tres líneas
  • IBM Plex Sans, foco, espaciado y anatomía

Comparación histórica recuperable

Compara la propuesta con cortes reales del repositorio. La ausencia de una muestra se declara y nunca se reconstruye de memoria.

Estado actual
Reproducción temporal no tiene una implementación vigente demostrada; sus ejemplos son material candidato.
Cambio propuesto
Publicar en r19 el contrato de Reproducción temporal para Patrón canónico de reproducción temporal para cochid-mapas, cables, transporte y mapa de santiago.
Qué ocurre si respondes No
Reproducción temporal queda fuera de r19 y sus ejemplos siguen sólo como evidencia pendiente de reformulación.

Preparando comparación histórica…

Antes / r19

La comparación convierte una regla abstracta en una diferencia visible y verificable.

r19 · correctoContrato canónico renderizado
Fuente: cortes de DTPM · intervalo 5 min
  • Incluye leyenda, atribución, período y alternativa textual.
  • Conserva controles operables por teclado y estados de cobertura.
Antes · problema observadoAnti-ejemplo no interactivo
Mapa de resultadosColores sin leyenda, fuente, período ni alternativa
  • No uses color como única codificación.
  • No ocultes qué capa, fuente o geometría está fallando.

Responsive

La misma anatomía debe conservar lectura, foco y acciones sin cortar contenido ni crear scroll horizontal en la página.

320 pxMóvil y zoom
Fuente: cortes de DTPM · intervalo 5 min
1280 pxEscritorio
Fuente: cortes de DTPM · intervalo 5 min

Cobertura

DimensiónContrato
Propietario canónicoSistema de diseño CIS y COCHID Mapas · core/core-style
Consumidorescochid-mapas, Cables, Transporte y Mapa de Santiago
Dependenciasrenderer cartográfico, fuente y atribución
Estadocandidato

Evidencia de adopción

Patrón propuesto. 0 implementaciones observadas en 0 repositorios.

La observación demuestra uso existente; la aceptación canónica sigue dependiendo de esta ficha y de su propietario.

DatoResultado
ClasificaciónPatrón propuesto
Implementaciones0 implementaciones observadas
RepositoriosNingún repositorio observado
Snapshotkit/componentes/componentes-observados.json

Consumidores observados

El inventario conserva repositorio, archivo fuente y criterio de asociación. Observar una implementación no la convierte automáticamente en canónica.

Estados

Estado requerido
base
selección
cargando
sin cobertura
error

Accesibilidad

  • Conserva nombre accesible, orden de lectura y foco visible.
  • Funciona a 320 px, con zoom de 200% y texto largo.
  • El color nunca es la única señal de estado o acción.
  • El contenido esencial permanece disponible sin JavaScript.

Código HTML

Copia el bloque completo; después cambia contenido y destinos, no su anatomía.

Código de referencia
<section class="ui-sample ui-map" data-map-playback="true"><div class="ui-actions" role="toolbar" aria-label="Reproducción temporal"><button class="btn btn--primary" type="button">Reproducir</button><button class="btn btn--secondary" type="button">Anterior</button><button class="btn btn--secondary" type="button">Siguiente</button><label>Velocidad <select class="input"><option>1×</option><option selected="">2×</option></select></label></div><time dateTime="2026-08-25T18:24:00-04:00">18:24 CLT</time><small>Fuente: cortes de DTPM · intervalo 5 min</small></section>

Código TAILWIND

Copia el bloque completo; después cambia contenido y destinos, no su anatomía.

Código de referencia
<section class="ui-sample ui-map border border-slate-300 bg-white p-4 text-slate-950 grid gap-3" data-map-playback="true"><div class="ui-actions" role="toolbar" aria-label="Reproducción temporal"><button class="btn btn--primary border border-slate-950 px-3 py-2 focus-visible:outline-2 focus-visible:outline-offset-2 disabled:cursor-not-allowed" type="button">Reproducir</button><button class="btn btn--secondary border border-slate-950 px-3 py-2 focus-visible:outline-2 focus-visible:outline-offset-2 disabled:cursor-not-allowed" type="button">Anterior</button><button class="btn btn--secondary border border-slate-950 px-3 py-2 focus-visible:outline-2 focus-visible:outline-offset-2 disabled:cursor-not-allowed" type="button">Siguiente</button><label>Velocidad <select class="input border border-slate-400 bg-white px-3 py-2 focus-visible:outline-2 focus-visible:outline-offset-2"><option>1×</option><option selected="">2×</option></select></label></div><time dateTime="2026-08-25T18:24:00-04:00">18:24 CLT</time><small class="text-sm text-slate-600">Fuente: cortes de DTPM · intervalo 5 min</small></section>

Código REACT

Copia el bloque completo; después cambia contenido y destinos, no su anatomía.

Código de referencia
import type { ChangeEventHandler, MouseEventHandler } from "react";

export interface MapPlaybackSpeed {
  /** Texto de la opción («2×»). */
  label: string;
  /** Valor de la opción si difiere del texto; sin él se usa `label`. */
  value?: string;
}

export interface MapPlaybackProps {
  /** Nombre accesible de la barra de controles. */
  toolbarLabel?: string;
  /** La animación está corriendo: el primer botón pasa a decir `pauseLabel`. */
  playing?: boolean;
  playLabel?: string;
  pauseLabel?: string;
  onPlay?: MouseEventHandler<HTMLButtonElement>;
  onPause?: MouseEventHandler<HTMLButtonElement>;
  /** Texto del botón que retrocede un cuadro; vacío lo oculta. */
  previousLabel?: string;
  onPrevious?: MouseEventHandler<HTMLButtonElement>;
  /** Texto del botón que avanza un cuadro; vacío lo oculta. */
  nextLabel?: string;
  onNext?: MouseEventHandler<HTMLButtonElement>;
  /** Rótulo del selector de velocidad. */
  speedLabel?: string;
  /** Velocidades disponibles; sin elementos no se muestra el selector. */
  speeds?: MapPlaybackSpeed[];
  /** Velocidad inicial de un selector no controlado (valor u opción). */
  defaultSpeed?: string;
  /** Velocidad de un selector controlado; va junto con `onSpeedChange`. */
  speed?: string;
  /** Se llama al cambiar la velocidad, esté controlado o no el selector. */
  onSpeedChange?: ChangeEventHandler<HTMLSelectElement>;
  /** Instante del cuadro visible en ISO 8601, con zona horaria. */
  dateTime?: string;
  /** Texto visible del instante del cuadro dentro de `<time>` («18:24 CLT»); vacío lo omite. */
  time?: string;
  /** Fuente de los datos, con su prefijo («Fuente: …»); vacía la omite. */
  source?: string;
  /** Nota tras la fuente (intervalo entre cuadros, fecha de corte); vacía la omite. */
  note?: string;
  className?: string;
}

const VELOCIDADES: MapPlaybackSpeed[] = [{ label: "1×" }, { label: "2×" }];

/**
 * Barra de reproducción de un mapa animado en el tiempo, con reproducir o pausar, cuadro anterior y siguiente, velocidad y la hora del cuadro visible.
 *
 * Sin estado interno: `playing` decide si el primer botón reproduce o pausa, y la página avanza los cuadros con `onNext` y `onPrevious`.
 *
 * @example <MapPlayback playing={corriendo} onPlay={reproducir} onPause={pausar} onNext={avanzar} onPrevious={retroceder} dateTime="2026-08-25T18:29:00-04:00" time="18:29 CLT" />
 */
export function MapPlayback({
  toolbarLabel = "Reproducción temporal",
  playing = false,
  playLabel = "Reproducir",
  pauseLabel = "Pausar",
  onPlay,
  onPause,
  previousLabel = "Anterior",
  onPrevious,
  nextLabel = "Siguiente",
  onNext,
  speedLabel = "Velocidad",
  speeds = VELOCIDADES,
  defaultSpeed = "2×",
  speed,
  onSpeedChange,
  dateTime = "2026-08-25T18:24:00-04:00",
  time = "18:24 CLT",
  source = "Fuente: cortes de DTPM",
  note = "intervalo 5 min",
  className,
}: MapPlaybackProps) {
  const controlado = speed !== undefined && onSpeedChange !== undefined;
  const pie = [source, note].filter(Boolean).join(" · ");
  return (
    <section className={["ui-map", className].filter(Boolean).join(" ")} data-map-playback>
      <div className="ui-actions" role="toolbar" aria-label={toolbarLabel}>
        <button className="btn btn--primary" type="button" onClick={playing ? onPause : onPlay}>{playing ? pauseLabel : playLabel}</button>
        {previousLabel ? <button className="btn btn--secondary" type="button" onClick={onPrevious}>{previousLabel}</button> : null}
        {nextLabel ? <button className="btn btn--secondary" type="button" onClick={onNext}>{nextLabel}</button> : null}
        {speeds.length ? (
          <label>
            {speedLabel ? `${speedLabel} ` : null}
            <select className="input" onChange={onSpeedChange} {...(controlado ? { value: speed } : { defaultValue: speed ?? defaultSpeed })}>
              {speeds.map((opcion, i) => (
                <option key={i} value={opcion.value}>{opcion.label}</option>
              ))}
            </select>
          </label>
        ) : null}
      </div>
      {time ? <time dateTime={dateTime}>{time}</time> : null}
      {pie ? <small>{pie}</small> : null}
    </section>
  );
}