Saltar al contenido
Índice de Kit UI
Kit UI Componentes

Timeline cartográfico.

Patrón canónico de timeline cartográfico 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
  1. 1 ago · inicio
  2. 15 ago · cambio de red
  3. 25 ago · último corte
Fuente: cortes diarios de DTPM
Nivel 2Compañía de Innovación de Santiago · variación
  1. 1 ago · inicio
  2. 15 ago · cambio de red
  3. 25 ago · último corte
Fuente: cortes diarios de DTPM
Nivel 3Dentro de una página
Sitio · sección
  1. 1 ago · inicio
  2. 15 ago · cambio de red
  3. 25 ago · último corte
Fuente: cortes diarios de DTPM
Ver y copiar el código de este render
HTML del nivel canónico
<section class="ui-sample ui-map" data-map-timeline="true"><label for="map-time-0">Fecha visible: <output for="map-time-0">1 ago 2026</output></label><input id="map-time-0" type="range" min="1" max="25" value="1"><svg width="100%" height="34" aria-hidden="true"><g><line x1="0%" x2="0%" y1="0" y2="6" stroke="currentColor"></line><text x="0%" y="18" text-anchor="start" fill="currentColor">1 ago</text><text x="0%" y="31" text-anchor="start" fill="currentColor">inicio</text></g><g><line x1="58.33%" x2="58.33%" y1="0" y2="6" stroke="currentColor"></line><text x="58.33%" y="18" text-anchor="middle" fill="currentColor">15 ago</text><text x="58.33%" y="31" text-anchor="middle" fill="currentColor">cambio de red</text></g><g><line x1="100%" x2="100%" y1="0" y2="6" stroke="currentColor"></line><text x="100%" y="18" text-anchor="end" fill="currentColor">25 ago</text><text x="100%" y="31" text-anchor="end" fill="currentColor">último corte</text></g></svg><ol class="sr-only"><li>1 ago · inicio</li><li>15 ago · cambio de red</li><li>25 ago · último corte</li></ol><small>Fuente: cortes diarios de DTPM</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
  1. 1 ago · inicio
  2. 15 ago · cambio de red
  3. 25 ago · último corte
Fuente: cortes diarios de DTPM

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
  1. 1 ago · inicio
  2. 15 ago · cambio de red
  3. 25 ago · último corte
Fuente: cortes diarios de DTPM

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
Timeline cartográfico no tiene una implementación vigente demostrada; sus ejemplos son material candidato.
Cambio propuesto
Publicar en r19 el contrato de Timeline cartográfico para Patrón canónico de timeline cartográfico para cochid-mapas, cables, transporte y mapa de santiago.
Qué ocurre si respondes No
Timeline cartográfico 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
  1. 1 ago · inicio
  2. 15 ago · cambio de red
  3. 25 ago · último corte
Fuente: cortes diarios de DTPM
  • 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
  1. 1 ago · inicio
  2. 15 ago · cambio de red
  3. 25 ago · último corte
Fuente: cortes diarios de DTPM
1280 pxEscritorio
  1. 1 ago · inicio
  2. 15 ago · cambio de red
  3. 25 ago · último corte
Fuente: cortes diarios de DTPM

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-timeline="true"><label for="map-time-0">Fecha visible: <output for="map-time-0">1 ago 2026</output></label><input id="map-time-0" type="range" min="1" max="25" value="1"><svg width="100%" height="34" aria-hidden="true"><g><line x1="0%" x2="0%" y1="0" y2="6" stroke="currentColor"></line><text x="0%" y="18" text-anchor="start" fill="currentColor">1 ago</text><text x="0%" y="31" text-anchor="start" fill="currentColor">inicio</text></g><g><line x1="58.33%" x2="58.33%" y1="0" y2="6" stroke="currentColor"></line><text x="58.33%" y="18" text-anchor="middle" fill="currentColor">15 ago</text><text x="58.33%" y="31" text-anchor="middle" fill="currentColor">cambio de red</text></g><g><line x1="100%" x2="100%" y1="0" y2="6" stroke="currentColor"></line><text x="100%" y="18" text-anchor="end" fill="currentColor">25 ago</text><text x="100%" y="31" text-anchor="end" fill="currentColor">último corte</text></g></svg><ol class="sr-only"><li>1 ago · inicio</li><li>15 ago · cambio de red</li><li>25 ago · último corte</li></ol><small>Fuente: cortes diarios de DTPM</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-timeline="true"><label for="map-time-0">Fecha visible: <output for="map-time-0">1 ago 2026</output></label><input class="border border-slate-400 bg-white px-3 py-2 focus-visible:outline-2 focus-visible:outline-offset-2" id="map-time-0" type="range" min="1" max="25" value="1"><svg class="h-auto w-full" width="100%" height="34" aria-hidden="true"><g><line x1="0%" x2="0%" y1="0" y2="6" stroke="currentColor"></line><text x="0%" y="18" text-anchor="start" fill="currentColor">1 ago</text><text x="0%" y="31" text-anchor="start" fill="currentColor">inicio</text></g><g><line x1="58.33%" x2="58.33%" y1="0" y2="6" stroke="currentColor"></line><text x="58.33%" y="18" text-anchor="middle" fill="currentColor">15 ago</text><text x="58.33%" y="31" text-anchor="middle" fill="currentColor">cambio de red</text></g><g><line x1="100%" x2="100%" y1="0" y2="6" stroke="currentColor"></line><text x="100%" y="18" text-anchor="end" fill="currentColor">25 ago</text><text x="100%" y="31" text-anchor="end" fill="currentColor">último corte</text></g></svg><ol class="sr-only grid gap-2"><li>1 ago · inicio</li><li>15 ago · cambio de red</li><li>25 ago · último corte</li></ol><small class="text-sm text-slate-600">Fuente: cortes diarios de DTPM</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 } from "react";

export interface MapTimelineEvent {
  /** Fecha del hito, en formato corto («15 ago»). */
  date: string;
  /** Qué ocurre en esa fecha («cambio de red»); vacío deja sólo la fecha. */
  label?: string;
  /** Posición del hito en la escala del deslizador, entre `min` y `max` (15 para el 15 de agosto en un rango de 1 a 25); sin valor, los hitos se reparten a lo ancho en el orden de la lista. */
  value?: number;
}

export interface MapTimelineProps {
  /** Rótulo del deslizador, antes de la fecha visible. */
  label?: string;
  /** Id del deslizador; la etiqueta y la salida apuntan a él. Usa uno distinto por mapa en la página. */
  id?: string;
  name?: string;
  /** Primer corte disponible. */
  min?: number;
  /** Último corte disponible. */
  max?: number;
  /** Distancia entre cortes; sin valor, el navegador usa 1. */
  step?: number;
  /** Posición inicial de un deslizador no controlado. */
  defaultValue?: number;
  /** Posición de un deslizador controlado; va junto con `onChange`. */
  value?: number;
  /** Se llama al mover el deslizador, esté controlado o no. */
  onChange?: ChangeEventHandler<HTMLInputElement>;
  /** Fecha que corresponde a la posición actual, tal como se muestra («1 ago 2026»). */
  valueText?: string;
  /** Hitos de la serie, en orden; cada uno se ubica sobre la escala según su `value`. Sin elementos no se muestra la lista. */
  events?: MapTimelineEvent[];
  /** Fuente de los datos, con su prefijo («Fuente: …»); vacía la omite. */
  source?: string;
  className?: string;
}

const HITOS: MapTimelineEvent[] = [
  { date: "1 ago", label: "inicio", value: 1 },
  { date: "15 ago", label: "cambio de red", value: 15 },
  { date: "25 ago", label: "último corte", value: 25 },
];

/** Porcentaje del ancho de la escala que corresponde al hito `i`. */
function mapTimelinePosicion(hito: MapTimelineEvent, i: number, total: number, min: number, max: number) {
  const fraccion = hito.value !== undefined && max > min
    ? (hito.value - min) / (max - min)
    : total > 1 ? i / (total - 1) : 0;
  return Math.round(Math.min(1, Math.max(0, fraccion)) * 10000) / 100;
}

/** Ancla del texto: los hitos cerca de un extremo se alinean hacia adentro para no salirse de la escala. */
function mapTimelineAncla(posicion: number) {
  if (posicion < 12) return "start";
  if (posicion > 88) return "end";
  return "middle";
}

/**
 * Control de fecha para un mapa con datos en varios cortes: un deslizador con la fecha visible, la lista de hitos y la fuente.
 *
 * La fecha visible va en un `<output>` asociado al deslizador; actualiza `valueText` junto con la posición. Los hitos se dibujan en una escala SVG, cada uno en la posición que le da su `value` entre `min` y `max`; la misma lista va en un `<ol>` para lectores de pantalla.
 *
 * @example <MapTimeline id="corte-dtpm" min={1} max={25} value={dia} onChange={cambiarDia} valueText="25 ago 2026" />
 * @example <MapTimeline min={1} max={31} events={[{ date: "1 ago", label: "inicio", value: 1 }, { date: "10 ago", label: "cambio de red", value: 10 }, { date: "31 ago", label: "último corte", value: 31 }]} />
 */
export function MapTimeline({
  label = "Fecha visible:",
  id = "map-time-0",
  name,
  min = 1,
  max = 25,
  step,
  defaultValue = 1,
  value,
  onChange,
  valueText = "1 ago 2026",
  events = HITOS,
  source = "Fuente: cortes diarios de DTPM",
  className,
}: MapTimelineProps) {
  const controlado = value !== undefined && onChange !== undefined;
  return (
    <section className={["ui-map", className].filter(Boolean).join(" ")} data-map-timeline>
      {label || valueText ? (
        <label htmlFor={id}>{label}{label && valueText ? " " : null}{valueText ? <output htmlFor={id}>{valueText}</output> : null}</label>
      ) : null}
      <input
        id={id}
        name={name}
        type="range"
        min={min}
        max={max}
        step={step}
        onChange={onChange}
        {...(controlado ? { value } : { defaultValue: value ?? defaultValue })}
      />
      {events.length ? (
        <svg width="100%" height="34" aria-hidden="true">
          {events.map((hito, i) => {
            const posicion = mapTimelinePosicion(hito, i, events.length, min, max);
            const x = `${posicion}%`;
            const ancla = mapTimelineAncla(posicion);
            return (
              <g key={i}>
                <line x1={x} x2={x} y1="0" y2="6" stroke="currentColor"></line>
                <text x={x} y="18" textAnchor={ancla} fill="currentColor">{hito.date}</text>
                {hito.label ? <text x={x} y="31" textAnchor={ancla} fill="currentColor">{hito.label}</text> : null}
              </g>
            );
          })}
        </svg>
      ) : null}
      {events.length ? (
        <ol className="sr-only">
          {events.map((hito, i) => (
            <li key={i}>{hito.label ? `${hito.date} · ${hito.label}` : hito.date}</li>
          ))}
        </ol>
      ) : null}
      {source ? <small>{source}</small> : null}
    </section>
  );
}