Путешествия · Новый ресурс

Дизайн-система Kiwi Orbit.

Руководство по Orbit для путешествий: настоящие цвета и интервалы продукта, нативный выбор багажа, единообразная разбивка стоимости и полноценный локальный процесс проверки.

Руководство OpenDesign8 глав38 справочных записейАвторское руководство по приложению
01

Предварительный просмотр интерфейса дизайн-системы Kiwi Orbit

Измените число путешественников и выберите дополнительные опции. Просмотрите разбивку стоимости и измените выбор, чтобы сбросить устаревшее подтверждение.

Выберите багаж и посмотрите пример итоговой стоимостиОткрыть полный пример
Нативные компоненты Orbit React версии 27.7.0 с defaultTheme и скомпилированным Tailwind CSS; справочник токенов версии 11.0.0. · Справочник по реализации
02

Справочник по дизайн-системе Kiwi Orbit

Нативные компоненты Orbit React версии 27.7.0 с defaultTheme и скомпилированным Tailwind CSS; справочник токенов версии 11.0.0.

Цвета действий продукта

Источник
Название / правилоЗначение / конфигурацияПрименение
buttonPrimaryBackground#008F7B Справочник состояний основного действия. Различайте роли состояний при наведении, нажатии и фокусе.
buttonPrimaryBackgroundHover#007565 Справочник состояний основного действия. Различайте роли состояний при наведении, нажатии и фокусе.
buttonPrimaryBackgroundActive#006153 Справочник состояний основного действия. Различайте роли состояний при наведении, нажатии и фокусе.
buttonPrimaryForeground#FFFFFF Справочник состояний основного действия. Различайте роли состояний при наведении, нажатии и фокусе.
buttonPrimaryForegroundHover#FFFFFF Справочник состояний основного действия. Различайте роли состояний при наведении, нажатии и фокусе.
buttonPrimaryForegroundActive#FFFFFF Справочник состояний основного действия. Различайте роли состояний при наведении, нажатии и фокусе.
buttonPrimaryBorderColorFocusrgba(0, 143, 123, 0.5)Справочник состояний основного действия. Различайте роли состояний при наведении, нажатии и фокусе.

Интервалы компонентов

Источник
Название / правилоЗначение / конфигурацияПрименение
space502pxФактические значения шагов в пикселях из опубликованного пакета токенов.
space1004pxФактические значения шагов в пикселях из опубликованного пакета токенов.
space1506pxФактические значения шагов в пикселях из опубликованного пакета токенов.
space2008pxФактические значения шагов в пикселях из опубликованного пакета токенов.
space30012pxФактические значения шагов в пикселях из опубликованного пакета токенов.
space40016pxФактические значения шагов в пикселях из опубликованного пакета токенов.
space50020pxФактические значения шагов в пикселях из опубликованного пакета токенов.
space60024pxФактические значения шагов в пикселях из опубликованного пакета токенов.
space80032pxФактические значения шагов в пикселях из опубликованного пакета токенов.
space100040pxФактические значения шагов в пикселях из опубликованного пакета токенов.
space120048pxФактические значения шагов в пикселях из опубликованного пакета токенов.

Радиусы скругления

Источник
Название / правилоЗначение / конфигурацияПрименение
borderRadius502pxРазные радиусы подходят для элементов управления и более крупных поверхностей интерфейса путешествия.
borderRadius1004pxРазные радиусы подходят для элементов управления и более крупных поверхностей интерфейса путешествия.
borderRadius1506pxРазные радиусы подходят для элементов управления и более крупных поверхностей интерфейса путешествия.
borderRadius2008pxРазные радиусы подходят для элементов управления и более крупных поверхностей интерфейса путешествия.
borderRadius30012pxРазные радиусы подходят для элементов управления и более крупных поверхностей интерфейса путешествия.
borderRadius40016pxРазные радиусы подходят для элементов управления и более крупных поверхностей интерфейса путешествия.
borderRadiusNone0Разные радиусы подходят для элементов управления и более крупных поверхностей интерфейса путешествия.
borderRadiusFull9999pxРазные радиусы подходят для элементов управления и более крупных поверхностей интерфейса путешествия.

Основной текст

Источник
Название / правилоЗначение / конфигурацияПрименение
fontSizeTextSmall13pxОпубликованные роли основного текста; заголовки страниц задаются отдельно в приложении.
fontSizeTextNormal15pxОпубликованные роли основного текста; заголовки страниц задаются отдельно в приложении.
fontSizeTextLarge16pxОпубликованные роли основного текста; заголовки страниц задаются отдельно в приложении.
fontSizeTextExtraLarge18pxОпубликованные роли основного текста; заголовки страниц задаются отдельно в приложении.

Поверхности продукта и нейтральные поверхности

Источник
Название / правилоЗначение / конфигурацияПрименение
paletteCloudLight#F5F7F9 Используйте спокойные поверхности и хорошо читаемый текст в сочетании с цветом действий продукта.
paletteCloudNormal#E8EDF1 Используйте спокойные поверхности и хорошо читаемый текст в сочетании с цветом действий продукта.
paletteInkDark#252A31 Используйте спокойные поверхности и хорошо читаемый текст в сочетании с цветом действий продукта.
paletteInkLight#657890 Используйте спокойные поверхности и хорошо читаемый текст в сочетании с цветом действий продукта.
paletteInkNormal#4F5E71 Используйте спокойные поверхности и хорошо читаемый текст в сочетании с цветом действий продукта.
paletteProductLight#E1F4F3 Используйте спокойные поверхности и хорошо читаемый текст в сочетании с цветом действий продукта.
paletteProductNormal#008F7B Используйте спокойные поверхности и хорошо читаемый текст в сочетании с цветом действий продукта.
paletteProductDark#007061 Используйте спокойные поверхности и хорошо читаемый текст в сочетании с цветом действий продукта.
03

Полное руководство по дизайн-системе Kiwi Orbit

Практическое руководство по выбору, применению и оценке этой системы для реального интерфейса.

DESIGN-kiwi-orbit.md

Подробные рекомендации, отправная точка для реализации и ссылки на источники.

Скачать руководство

Макет выбора путешествия в дизайн-системе Kiwi Orbit

Сначала покажите маршрут, затем дополнительные опции

В сводке маршрута указаны коды двух аэропортов, названия городов и вымышленная продолжительность поездки. Она показывается до выбора багажа, чтобы контекст покупки оставался виден при сравнении дополнительных опций. Пунктирная линия — оригинальная иллюстрация CSS, а не схема маршрута перевозчика и не обещание реальной услуги.

Из этого руководства OpenDesign

Отделите выбор от итоговой стоимости

С одной стороны расположены параметры путешественников и багажа, с другой — разбивка стоимости. Одно и то же состояние определяет и выбранные элементы управления, и суммы. На телефоне сводка следует за вариантами выбора в порядке документа, поэтому понятно, какие параметры влияют на итоговую стоимость.

Цвета продукта и обратная связь в дизайн-системе Kiwi Orbit

Используйте цветовую палитру продукта для основного действия

В пакете токенов для действий продукта предусмотрен зелёный цвет с отдельными оттенками для состояний при наведении и нажатии. В справочнике приведены точные значения для роли кнопки — вместо предположительного фирменного зелёного. Нейтральные облачные поверхности обрамляют дополнительные варианты выбора и не отвлекают внимание от действия проверки.

Связывайте обратную связь с результатом

В нативном уведомлении об успехе говорится, что выбор проверен локально, а также указаны число путешественников и итоговая стоимость. Уведомление исчезает при изменении любого параметра. Поэтому прежнее зелёное подтверждение не останется на экране и не создаст впечатление, что оно относится к новому набору дополнительных опций.

Типографика и иерархия цен в дизайн-системе Kiwi Orbit

Используйте нативные текстовые стили для пояснений

В Orbit есть стандартные стили основного текста размером 13px и 15px, а также более крупные варианты. В примере используются нативные компоненты Text и Heading, а коды маршрута и итоговая стоимость выделены отдельно. Здесь браузер использует документированный запасной набор шрифтов; фирменный шрифт Kiwi.com не загружается незаметно для пользователя.

Указывайте единицы измерения рядом с ценами

Для каждой цены багажа указано, что она рассчитана на одного путешественника. В разбивке стоимость каждой выбранной дополнительной опции умножается на число путешественников, а итоговая сумма выделена сильнее, чем отдельные составляющие. Единица расчёта должна оставаться видимой и на мобильных устройствах: крупную привлекательную сумму без пояснения легко понять неправильно.

Шкалы радиусов и интервалов дизайн-системы Kiwi Orbit

Разграничивайте элементы управления и крупные поверхности

В текущую шкалу радиусов входят значения 2, 4, 6, 8, 12 и 16px, а также варианты без скругления и с полным скруглением. В созданных для примера панелях маршрута и сводки используются углы радиусом 12px, а для нативных элементов управления действуют собственные правила темы. Если применить наибольший радиус ко всем вложенным элементам, иерархия формы станет менее выраженной.

Сохраняйте целостность строки варианта при переносе

Флажок и список выбора в дизайн-системе Kiwi Orbit

Используйте подписи компонентов и информационные поля

Флажок получает видимую подпись и поясняющую информацию через публичные свойства. Для компонента Select задаются подпись и явные варианты числа путешественников — от одного до четырёх. Эти нативные компоненты сохраняют предусмотренное поведение взаимодействия и подписей, не подменяя элемент управления багажом кликабельным div.

Моделируйте каждую дополнительную опцию независимо

Ручная кладь и зарегистрированный багаж представлены отдельными логическими значениями. Приложение не предполагает, что выбор одного автоматически отменяет другой. Это намеренно упрощённое правило для примера: у реальной авиакомпании могут быть взаимоисключающие тарифные пакеты или нормы багажа для каждого пассажира, для которых понадобится другая модель.

Расчёт и проверка выбора в дизайн-системе Kiwi Orbit

Рассчитывайте итог по единой формуле

В примере число путешественников умножается на базовую стоимость и выбранные дополнительные услуги на человека. Итоговая сумма не хранится отдельно и не может разойтись с отображаемыми вариантами. Все цены и нормы багажа вымышлены и не являются актуальными предложениями Kiwi.com.

Сохраняйте снимок проверенного выбора

При проверке вместе сохраняются число путешественников, параметры багажа и итоговая стоимость. При изменении любого элемента управления этот снимок сбрасывается. Так пример показывает согласованность состояния, не выдавая локальное нажатие за бронирование, оплату, проверку доступности в реальном времени или окончательное ценовое предложение.

Доступная обратная связь при выборе в дизайн-системе Kiwi Orbit

Проверяйте работу подписей и пересчёта одновременно

С помощью нативных элементов управления пользователь может выбрать число путешественников и отметить любой из вариантов багажа с клавиатуры или указателем. Результат проверки отображается в области статуса. Проверка необязательного багажа не выдумывается: в рамках этого вымышленного тарифа допустимо не выбирать ни одну дополнительную опцию.

  1. Выберите двух путешественников и добавьте ручную кладь.
  2. Добавьте зарегистрированный багаж и проверьте все три суммы в разбивке.
  3. Локально проверьте выбор, измените один из параметров и убедитесь, что прежнее подтверждение исчезло.

Не допускайте скрытых последствий

Вымышленный характер примера поясняется над формой и рядом с итоговой стоимостью. Действие называется «Проверить выбор локально», а не «Купить» или «Забронировать». Все изменения остаются на странице; личные данные пассажиров, не нужные для демонстрации, не запрашиваются.

Провайдер и скомпилированные стили в дизайн-системе Kiwi Orbit

Используйте соответствующую стабильную версию

В этом примере зафиксированы версии компонентов React 27.7.0 и ссылок на токены 11.0.0. Подключаются OrbitProvider, defaultTheme пакета и скомпилированный файл lib/tailwind.css. Без этой таблицы стилей оформление компонентов, использующих утилитарные классы, будет неполным, даже если дерево React отобразится.

  • OrbitProvider и defaultTheme пакета.
  • Скомпилированный файл lib/tailwind.css из components 27.7.0.
  • Для среды сборки пакета требуется Node.js версии 22 или новее.

Явно указывайте требования к развёртыванию

Примеры компонентов дизайн-системы Kiwi Orbit

main.jsx — полный рабочий образец

Выберите багаж и посмотрите пример итоговой стоимости. Ниже приведён полный код точки входа React, включая всё состояние и проверки.

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 />);

Справочник по коду

  • Создайте проект React на Vite, сохраните <div id="root"></div> и загрузите этот код как src/main.jsx.

orbit.css — оригинальная адаптивная композиция

Слой компоновки приложения поверх нативных компонентов.

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;
  }
}

Справочник по коду

  • Сохраните рядом с main.jsx. Эти собственные правила композиции отделены от справочника токенов библиотеки.
04

Настройка агента дизайн-системы Kiwi Orbit

Отправная точка для реализации

Пример с закреплёнными версиями нативных компонентов собран и проверен в браузере локально. В образце используется только локальное состояние приложения.

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

Запрос для вашего проекта

Промпт для AI-агента
Создайте форму выбора дополнительных услуг для путешествия с помощью нативных компонентов Orbit и скомпилированных стилей. Поддерживайте согласованность сведений о маршруте, цен на человека, выбранных опций и итоговой стоимости. Ясно укажите, что цены вымышлены, а проверка выполняется локально; сбрасывайте устаревшее подтверждение при редактировании и не создавайте впечатление, что доступны бронирование или оплата.
05

Источники и область применения дизайн-системы Kiwi Orbit

Руководство по приложению OpenDesign. Маршрут, продолжительность поездки, цены и нормы багажа вымышлены. Нативные элементы управления Orbit работают локально; поиск рейсов, бронирование и оплата не выполняются.