Viajes · Nuevo recurso

Sistema de diseño Kiwi Orbit.

Una guía de Orbit centrada en viajes, con colores y espaciado reales del producto, opciones nativas de equipaje, un desglose de precios coherente y un flujo local completo de revisión.

Guía de OpenDesign8 capítulos38 entradas de referenciaGuía de aplicación original
01

Vista previa de la interfaz del sistema de diseño Kiwi Orbit

Cambia el número de viajeros y los extras; consulta el desglose y elimina una revisión obsoleta al modificar una opción.

Elige el equipaje y consulta un total de ejemploAbrir ejemplo completo
Componentes nativos de Orbit React 27.7.0 con defaultTheme y CSS de Tailwind compilado; referencia de tokens 11.0.0. · Referencia de implementación
02

Referencia de diseño del sistema de diseño Kiwi Orbit

Componentes nativos de Orbit React 27.7.0 con defaultTheme y CSS de Tailwind compilado; referencia de tokens 11.0.0.

Colores de acción del producto

Fuente
Nombre / ReglaValor / ConfiguraciónUso
buttonPrimaryBackground#008F7B Referencia de los estados de la acción principal. Mantén diferenciadas las funciones de hover, active y focus.
buttonPrimaryBackgroundHover#007565 Referencia de los estados de la acción principal. Mantén diferenciadas las funciones de hover, active y focus.
buttonPrimaryBackgroundActive#006153 Referencia de los estados de la acción principal. Mantén diferenciadas las funciones de hover, active y focus.
buttonPrimaryForeground#FFFFFF Referencia de los estados de la acción principal. Mantén diferenciadas las funciones de hover, active y focus.
buttonPrimaryForegroundHover#FFFFFF Referencia de los estados de la acción principal. Mantén diferenciadas las funciones de hover, active y focus.
buttonPrimaryForegroundActive#FFFFFF Referencia de los estados de la acción principal. Mantén diferenciadas las funciones de hover, active y focus.
buttonPrimaryBorderColorFocusrgba(0, 143, 123, 0.5)Referencia de los estados de la acción principal. Mantén diferenciadas las funciones de hover, active y focus.

Espaciado de los componentes

Fuente
Nombre / ReglaValor / ConfiguraciónUso
space502pxValores reales en píxeles de los intervalos de espaciado del paquete de tokens publicado.
space1004pxValores reales en píxeles de los intervalos de espaciado del paquete de tokens publicado.
space1506pxValores reales en píxeles de los intervalos de espaciado del paquete de tokens publicado.
space2008pxValores reales en píxeles de los intervalos de espaciado del paquete de tokens publicado.
space30012pxValores reales en píxeles de los intervalos de espaciado del paquete de tokens publicado.
space40016pxValores reales en píxeles de los intervalos de espaciado del paquete de tokens publicado.
space50020pxValores reales en píxeles de los intervalos de espaciado del paquete de tokens publicado.
space60024pxValores reales en píxeles de los intervalos de espaciado del paquete de tokens publicado.
space80032pxValores reales en píxeles de los intervalos de espaciado del paquete de tokens publicado.
space100040pxValores reales en píxeles de los intervalos de espaciado del paquete de tokens publicado.
space120048pxValores reales en píxeles de los intervalos de espaciado del paquete de tokens publicado.

Radios de esquina

Fuente
Nombre / ReglaValor / ConfiguraciónUso
borderRadius502pxLos distintos radios se adaptan a los controles y a superficies de viaje más amplias.
borderRadius1004pxLos distintos radios se adaptan a los controles y a superficies de viaje más amplias.
borderRadius1506pxLos distintos radios se adaptan a los controles y a superficies de viaje más amplias.
borderRadius2008pxLos distintos radios se adaptan a los controles y a superficies de viaje más amplias.
borderRadius30012pxLos distintos radios se adaptan a los controles y a superficies de viaje más amplias.
borderRadius40016pxLos distintos radios se adaptan a los controles y a superficies de viaje más amplias.
borderRadiusNone0Los distintos radios se adaptan a los controles y a superficies de viaje más amplias.
borderRadiusFull9999pxLos distintos radios se adaptan a los controles y a superficies de viaje más amplias.

Tipografía del cuerpo

Fuente
Nombre / ReglaValor / ConfiguraciónUso
fontSizeTextSmall13pxEstilos publicados para el cuerpo; los encabezados personalizados de la página forman parte de la composición de la aplicación.
fontSizeTextNormal15pxEstilos publicados para el cuerpo; los encabezados personalizados de la página forman parte de la composición de la aplicación.
fontSizeTextLarge16pxEstilos publicados para el cuerpo; los encabezados personalizados de la página forman parte de la composición de la aplicación.
fontSizeTextExtraLarge18pxEstilos publicados para el cuerpo; los encabezados personalizados de la página forman parte de la composición de la aplicación.

Superficies del producto y neutras

Fuente
Nombre / ReglaValor / ConfiguraciónUso
paletteCloudLight#F5F7F9 Usa superficies sobrias y texto legible en torno al color de acción del producto.
paletteCloudNormal#E8EDF1 Usa superficies sobrias y texto legible en torno al color de acción del producto.
paletteInkDark#252A31 Usa superficies sobrias y texto legible en torno al color de acción del producto.
paletteInkLight#657890 Usa superficies sobrias y texto legible en torno al color de acción del producto.
paletteInkNormal#4F5E71 Usa superficies sobrias y texto legible en torno al color de acción del producto.
paletteProductLight#E1F4F3 Usa superficies sobrias y texto legible en torno al color de acción del producto.
paletteProductNormal#008F7B Usa superficies sobrias y texto legible en torno al color de acción del producto.
paletteProductDark#007061 Usa superficies sobrias y texto legible en torno al color de acción del producto.
03

Guía completa del sistema de diseño Kiwi Orbit

Una guía práctica para elegir, aplicar y revisar este sistema en una interfaz real.

DESIGN-kiwi-orbit.md

Orientación completa, un punto de partida para la implementación y enlaces al código fuente.

Descargar la guía

Diseño de selección de viajes del sistema de diseño Kiwi Orbit

Presenta la ruta antes de los extras

El resumen de la ruta muestra los códigos de los dos aeropuertos, los nombres de las ciudades y una duración ficticia antes de las opciones de equipaje. Así, el contexto de compra permanece visible mientras el usuario compara los extras. La línea discontinua es una ilustración original de CSS, no un gráfico de rutas de una aerolínea ni una promesa sobre un servicio real.

De esta guía de OpenDesign

Separa las opciones del total

Los viajeros y el equipaje aparecen a un lado, y el desglose del precio se muestra junto a ellos. El mismo estado determina tanto los controles seleccionados como los importes. En el móvil, el resumen aparece después de las opciones en el orden del documento, para que quede claro qué datos explican el total.

Color del producto y comentarios del sistema de diseño Kiwi Orbit

Usa la familia del producto para la acción principal

El paquete de tokens proporciona una acción de producto verde con tonos diferenciados para hover y active. La referencia muestra los valores exactos de la función del botón, en lugar de depender de un tono de verde de marca supuesto. Las superficies neutras en tonos nube enmarcan los extras seleccionables sin hacer que todos los paneles compitan con la acción de revisión.

Haz que los comentarios sean específicos para el resultado

La alerta de éxito nativa indica «Selección revisada localmente» y muestra la cantidad de viajeros y el total. Se borra cada vez que cambia una opción. Así, una confirmación verde anterior no puede seguir visible como si validara un conjunto de extras recién editado.

Tipografía y jerarquía de precios del sistema de diseño Kiwi Orbit

Usa los estilos de texto nativos para el contenido explicativo

Orbit ofrece estilos de texto de cuerpo pequeño de 13 px y normal de 15 px, además de opciones de mayor tamaño. El ejemplo usa los componentes Text y Heading nativos, mientras que los códigos de ruta y el total tienen un énfasis propio. El navegador usa aquí una pila de fuentes alternativas documentada; no se carga ninguna fuente de marca de Kiwi.com de forma silenciosa.

Mantén las unidades junto a los importes

Cada precio del equipaje indica que es por viajero. El desglose multiplica cada extra seleccionado por la cantidad de viajeros, y el total destaca visualmente más que sus partidas. La unidad no debe desaparecer en móviles, porque una cifra grande y llamativa sin especificar su alcance puede interpretarse fácilmente de forma incorrecta.

Escalas de radios y espaciado del sistema de diseño Kiwi Orbit

Diferencia los controles de las superficies más amplias

La escala de radios actual incluye valores de 2, 4, 6, 8, 12 y 16 px, además de las opciones sin radio y completo. Los paneles de ruta y resumen usan esquinas de 12 px, mientras que los controles nativos conservan sus propias reglas de tema. Aplicar el radio más grande a cada elemento anidado haría que el formulario perdiera jerarquía.

Mantén intacta la fila de opciones cuando se ajuste en varias líneas

Casillas y selectores controlados del sistema de diseño Kiwi Orbit

Usa las etiquetas de los componentes y los campos de información

Checkbox recibe la etiqueta visible y la información complementaria mediante propiedades públicas. Select recibe una etiqueta y opciones explícitas para elegir entre uno y cuatro viajeros. Estas composiciones nativas conservan su comportamiento de interacción y etiquetado, sin recurrir a un div con apariencia de control de equipaje en el que se pueda hacer clic.

Modela cada extra de forma independiente

El equipaje de cabina y el equipaje facturado son booleanos independientes. La aplicación no da a entender que seleccionar uno deseleccione automáticamente el otro. Esta es una política de ejemplo deliberadamente sencilla; una aerolínea real podría ofrecer paquetes mutuamente excluyentes o franquicias específicas para cada pasajero, que requerirían un modelo distinto.

Cálculo y revisión de la selección del sistema de diseño Kiwi Orbit

Calcula el total con una sola fórmula

El ejemplo calcula el número de viajeros multiplicado por la tarifa base más los extras seleccionados por persona. No guarda un total editable por separado que pueda dejar de coincidir con las opciones visibles. Todos los precios y las franquicias son expresamente ficticios y no corresponden a ofertas actuales de Kiwi.com.

Guarda una instantánea de la revisión

La revisión guarda juntos el número de viajeros, las opciones de equipaje y el total. Al cambiar cualquier control, se borra esa instantánea. Así, el ejemplo demuestra la coherencia del estado sin presentar un clic local como una reserva, un pago, una comprobación de disponibilidad en tiempo real o una cotización definitiva.

Comentarios accesibles sobre la selección del sistema de diseño Kiwi Orbit

Comprueba conjuntamente las etiquetas y el recálculo

Con el teclado o el puntero, se puede elegir el número de viajeros y activar cualquiera de las dos opciones de equipaje mediante los controles nativos. El resultado de la revisión aparece en una región de estado. No se inventa ninguna validación para el equipaje opcional: dejar sin seleccionar ambos extras es un estado válido para esta tarifa ficticia.

  1. Selecciona dos viajeros y añade equipaje de cabina.
  2. Añade equipaje facturado y comprueba los tres importes del desglose.
  3. Revisa la selección localmente, cambia una opción y confirma que desaparezca el mensaje de éxito anterior.

Evita consecuencias ocultas

La página explica el alcance ficticio encima del formulario y junto al total. La acción es «Revisar selección local», no «Comprar» ni «Reservar». Todos los cambios permanecen en la página y no se solicitan datos personales de los pasajeros, ya que no son necesarios para una demostración.

Proveedor y estilos compilados del sistema de diseño Kiwi Orbit

Usa la versión estable correspondiente

Este ejemplo fija la versión de los componentes React en 27.7.0 y la de las referencias a tokens en 11.0.0. Importa OrbitProvider, el paquete defaultTheme y el archivo compilado lib/tailwind.css. Si se omite esa hoja de estilos, los estilos de los componentes basados en utilidades quedan incompletos, aunque se renderice el árbol de React.

  • OrbitProvider y el paquete defaultTheme.
  • Archivo compilado lib/tailwind.css de components 27.7.0.
  • Node.js 22 o posterior para el entorno de compilación del paquete.

Especifica claramente los requisitos de despliegue

Ejemplos de componentes del sistema de diseño Kiwi Orbit

main.jsx — ejemplo completo y funcional

Elige el equipaje y revisa un total de ejemplo. El código fuente siguiente es la entrada completa de React, incluidos todos los estados y la validación.

jsx
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import {
  OrbitProvider,
  Button,
  Checkbox,
  Select,
  Alert,
  Heading,
  Text,
} from "@kiwicom/orbit-components";
import defaultTheme from "@kiwicom/orbit-components/lib/defaultTheme";
import "@kiwicom/orbit-components/lib/tailwind.css";
import "./orbit.css";
function App() {
  const [travellers, setTravellers] = useState("1"),
    [cabin, setCabin] = useState(false),
    [checked, setChecked] = useState(false),
    [saved, setSaved] = useState(null);
  const count = Number(travellers),
    extras = (cabin ? 18 : 0) + (checked ? 32 : 0),
    total = count * (96 + extras);
  function update(fn) {
    fn();
    setSaved(null);
  }
  return (
    <OrbitProvider theme={defaultTheme}>
      <main className="trip">
        <header>
          <Text size="small">ORIGINAL TRAVEL SPECIMEN</Text>
          <Heading as="h1" type="title1">Choose what travels with you</Heading>
          <Text>
            Fictional one-way fare. Prices illustrate the interface, not a
            bookable flight.
          </Text>
        </header>
        <div className="trip-grid">
          <section>
            <div className="route">
              <div>
                <strong>PRG</strong>
                <span>Prague</span>
              </div>
              <div className="route-line">
                <span>1h 45m · direct</span>
                <i></i>
              </div>
              <div>
                <strong>AMS</strong>
                <span>Amsterdam</span>
              </div>
            </div>
            <div className="options">
              <Heading as="h2" type="title3">Travellers and baggage</Heading>
              <Select
                label="Travellers"
                ariaLabel="Travellers"
                value={travellers}
                options={[1, 2, 3, 4].map((n) => ({
                  value: String(n),
                  label: n + " adult" + (n === 1 ? "" : "s"),
                }))}
                onChange={(e) => update(() => setTravellers(e.target.value))}
              />
              <div className="bag-option">
                <div>
                  <Heading as="h3" type="title4">Personal item</Heading>
                  <Text size="small">
                    Fits under the seat · included in this example fare
                  </Text>
                </div>
                <strong>Included</strong>
              </div>
              <div className="bag-option">
                <Checkbox
                  label="Add cabin baggage"
                  info="One 10 kg bag per traveller · fictional allowance"
                  checked={cabin}
                  onChange={(e) => update(() => setCabin(e.target.checked))}
                />
                <strong>
                  €18<span>/ traveller</span>
                </strong>
              </div>
              <div className="bag-option">
                <Checkbox
                  label="Add checked baggage"
                  info="One 20 kg bag per traveller · fictional allowance"
                  checked={checked}
                  onChange={(e) => update(() => setChecked(e.target.checked))}
                />
                <strong>
                  €32<span>/ traveller</span>
                </strong>
              </div>
            </div>
          </section>
          <aside>
            <Heading as="h2" type="title3">Your example selection</Heading>
            <dl>
              <dt>Base fare × {count}</dt>
              <dd>€{96 * count}</dd>
              {cabin && (
                <>
                  <dt>Cabin baggage × {count}</dt>
                  <dd>€{18 * count}</dd>
                </>
              )}
              {checked && (
                <>
                  <dt>Checked baggage × {count}</dt>
                  <dd>€{32 * count}</dd>
                </>
              )}
            </dl>
            <div className="trip-total">
              <span>Total</span>
              <strong>€{total}</strong>
            </div>
            <Text size="small">
              All amounts are illustrative. No payment or reservation will be
              created.
            </Text>
            <Button
              fullWidth
              onClick={() => setSaved({ count, cabin, checked, total })}
            >
              Review local selection
            </Button>
            {saved && (
              <div role="status" className="trip-confirm">
                <Alert type="success" title="Selection reviewed locally">
                  {saved.count} traveller{saved.count === 1 ? "" : "s"} · €
                  {saved.total}. No booking created.
                </Alert>
              </div>
            )}
          </aside>
        </div>
        <footer>
          Native Orbit 27.7.0 components and compiled package styles. Original
          layout and fictional pricing logic by OpenDesign.
        </footer>
      </main>
    </OrbitProvider>
  );
}
createRoot(document.getElementById("root")).render(<App />);

Referencia de código

  • Crea un proyecto Vite React, conserva <div id="root"></div> y cárgalo como src/main.jsx.

orbit.css — composición adaptable original

Diseño de la aplicación con capas alrededor de los componentes nativos.

css
* {
  box-sizing: border-box;
}
body {
  margin: 0;
  background: #f5f7f9;
  color: #252a31;
  font:
    16px/1.5 Arial,
    sans-serif;
}
.trip {
  padding: 32px;
}
.trip header {
  max-width: 760px;
  margin-bottom: 28px;
}
.trip header h1 {
  margin: 8px 0 12px;
}
.trip-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(280px, 1fr);
  gap: 24px;
}
.route,
.options,
.trip aside {
  background: #fff;
  border-radius: 12px;
  border: 1px solid #e8edf1;
  padding: 24px;
}
.route {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 20px;
}
.route strong {
  font-size: 32px;
  display: block;
}
.route span {
  font-size: 14px;
  display: block;
  color: #4f5e71;
}
.route-line {
  flex: 1;
  text-align: center;
}
.route-line i {
  display: block;
  border-top: 2px dashed #bac7d5;
  margin-top: 12px;
}
.options > h3 {
  margin-bottom: 20px;
}
.options > div:first-of-type {
  margin-bottom: 12px;
}
.bag-option {
  display: flex;
  gap: 20px;
  align-items: center;
  justify-content: space-between;
  padding: 24px 0;
  border-top: 1px solid #e8edf1;
}
.bag-option:last-child {
  padding-bottom: 0;
}
.bag-option > strong {
  white-space: nowrap;
  font-size: 18px;
}
.bag-option > strong span {
  display: block;
  font-size: 12px;
  font-weight: 400;
  color: #657890;
}
.trip aside {
  align-self: start;
}
.trip dl {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 16px;
  margin: 24px 0;
}
.trip dd {
  margin: 0;
  text-align: right;
  font-weight: 600;
}
.trip-total {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-top: 1px solid #bac7d5;
  padding: 20px 0;
}
.trip-total strong {
  font-size: 32px;
}
.trip aside > button {
  margin-top: 24px;
}
.trip-confirm {
  margin-top: 20px;
}
.trip footer {
  font-size: 12px;
  color: #657890;
  margin-top: 24px;
}
@media (max-width: 900px) {
  .trip-grid {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 550px) {
  .trip {
    padding: 16px;
  }
  .route,
  .options,
  .trip aside {
    padding: 20px;
  }
  .route {
    gap: 12px;
  }
  .route strong {
    font-size: 28px;
  }
  .route-line span {
    font-size: 12px;
  }
  .bag-option {
    align-items: flex-start;
    gap: 12px;
  }
}

Referencia de código

  • Guárdalo junto a main.jsx. Estas reglas de composición personalizadas se distinguen de la referencia de tokens de la biblioteca.
04

Configuración del agente del sistema de diseño Kiwi Orbit

Punto de partida para la implementación

El ejemplo nativo fijado se empaquetó y se comprobó localmente en el navegador. El ejemplo utiliza únicamente el estado local de la aplicación.

sh
npm create vite@latest orbit-trip -- --template react
cd orbit-trip
npm install
npm install [email protected] [email protected] @kiwicom/[email protected]
# Use Node.js >=22. Replace src/main.jsx and add src/orbit.css.
npm run dev

Una instrucción para tu proyecto

Instrucción para el agente
Crea un selector de extras de viaje con componentes nativos de Orbit y estilos compilados. Mantén coherentes el contexto de la ruta, los precios por viajero, los extras seleccionados y el total. Indica claramente que los precios son ficticios y que la revisión es local, borra la revisión anterior cuando se edite y no des a entender que hay funciones de reserva o pago.
05

Fuentes y alcance del sistema de diseño Kiwi Orbit

Guía de aplicación de OpenDesign. La ruta, la duración, los precios y las franquicias de equipaje son ficticios. Los controles nativos de Orbit funcionan localmente; no se realiza ninguna búsqueda de vuelos, reserva ni pago.