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

Дизайн-система Elastic UI.

Создайте исследовательский интерфейс журналов Elastic UI с проверенными шкалами Borealis, нативными элементами управления таблицей и поиском, фильтрацией по уровню серьёзности, локально сохраняемыми событиями и полным исходным кодом React.

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

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

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

Поиск и сохранение примеров записей журналаОткрыть полный пример
Нативная Elastic UI 123.0.0 / Borealis 8.1.0 с React 18.3.1. Локальные данные журнала и состояние приложения созданы специально для примера. · Справочник по реализации
02

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

Elastic UI 123.0.0 с темой Borealis 8.1.0 и React 18.3.1. В таблицах используются имена из опубликованного JSON темы; это ключи экспорта, а не буквальные пути в объекте useEuiTheme. В самом предварительном просмотре используется нативная тема React API.

Семантические цвета Borealis

Источник
Название / правилоЗначение / конфигурацияПрименение
euiColorPrimarylight: #0B64DD; dark: #61A2FFИмена из опубликованного экспорта темы. В React используйте соответствующую семантическую роль через useEuiTheme, а не задавайте эти значения напрямую.
euiColorSuccesslight: #008A5E; dark: #24C292Имена из опубликованного экспорта темы. В React используйте соответствующую семантическую роль через useEuiTheme, а не задавайте эти значения напрямую.
euiColorWarninglight: #FACB3D; dark: #FACB3DИмена из опубликованного экспорта темы. В React используйте соответствующую семантическую роль через useEuiTheme, а не задавайте эти значения напрямую.
euiColorDangerlight: #C61E25; dark: #F6726AИмена из опубликованного экспорта темы. В React используйте соответствующую семантическую роль через useEuiTheme, а не задавайте эти значения напрямую.
euiColorEmptyShadelight: #FFFFFF; dark: #111C2CИмена из опубликованного экспорта темы. В React используйте соответствующую семантическую роль через useEuiTheme, а не задавайте эти значения напрямую.
euiColorFullShadelight: #07101F; dark: #FFFFFFИмена из опубликованного экспорта темы. В React используйте соответствующую семантическую роль через useEuiTheme, а не задавайте эти значения напрямую.
euiPageBackgroundColorlight: #ECF1F9; dark: #07101FИмена из опубликованного экспорта темы. В React используйте соответствующую семантическую роль через useEuiTheme, а не задавайте эти значения напрямую.
euiTextColorlight: #384861; dark: #B4C1D5Имена из опубликованного экспорта темы. В React используйте соответствующую семантическую роль через useEuiTheme, а не задавайте эти значения напрямую.
euiTextSubduedColorlight: #516381; dark: #98A8C3Имена из опубликованного экспорта темы. В React используйте соответствующую семантическую роль через useEuiTheme, а не задавайте эти значения напрямую.

Шкала интервалов

Источник
Название / правилоЗначение / конфигурацияПрименение
euiSizeXS4pxДля ритма макета используйте соответствующие размеры EuiSpacer/FlexGroup; согласно экспорту этой темы, базовый интервал составляет 16px.
euiSizeS8pxДля ритма макета используйте соответствующие размеры EuiSpacer/FlexGroup; согласно экспорту этой темы, базовый интервал составляет 16px.
euiSizeM12pxДля ритма макета используйте соответствующие размеры EuiSpacer/FlexGroup; согласно экспорту этой темы, базовый интервал составляет 16px.
euiSize16pxДля ритма макета используйте соответствующие размеры EuiSpacer/FlexGroup; согласно экспорту этой темы, базовый интервал составляет 16px.
euiSizeL24pxДля ритма макета используйте соответствующие размеры EuiSpacer/FlexGroup; согласно экспорту этой темы, базовый интервал составляет 16px.
euiSizeXL32pxДля ритма макета используйте соответствующие размеры EuiSpacer/FlexGroup; согласно экспорту этой темы, базовый интервал составляет 16px.
euiSizeXXL40pxДля ритма макета используйте соответствующие размеры EuiSpacer/FlexGroup; согласно экспорту этой темы, базовый интервал составляет 16px.

Типографика

Источник
Название / правилоЗначение / конфигурацияПрименение
euiFontSizeXS12pxОпубликованный справочник типографики. Для иерархии компонентов используйте варианты EuiText/EuiTitle.
euiFontSizeS14pxОпубликованный справочник типографики. Для иерархии компонентов используйте варианты EuiText/EuiTitle.
euiFontSize14pxОпубликованный справочник типографики. Для иерархии компонентов используйте варианты EuiText/EuiTitle.
euiFontSizeM16pxОпубликованный справочник типографики. Для иерархии компонентов используйте варианты EuiText/EuiTitle.
euiFontSizeL20pxОпубликованный справочник типографики. Для иерархии компонентов используйте варианты EuiText/EuiTitle.
euiFontSizeXL24pxОпубликованный справочник типографики. Для иерархии компонентов используйте варианты EuiText/EuiTitle.
euiFontSizeXXL30pxОпубликованный справочник типографики. Для иерархии компонентов используйте варианты EuiText/EuiTitle.
euiLineHeight1.5Опубликованный справочник типографики. Для иерархии компонентов используйте варианты EuiText/EuiTitle.

Границы и формы

Источник
Название / правилоЗначение / конфигурацияПрименение
euiBorderWidthThin1pxРазличайте форму встроенных элементов, элементов управления, панелей и рамок; единый радиус скругления для всего интерфейса уничтожил бы эту иерархию.
euiBorderWidthThick2pxРазличайте форму встроенных элементов, элементов управления, панелей и рамок; единый радиус скругления для всего интерфейса уничтожил бы эту иерархию.
euiBorderColor#E3E8F2 Различайте форму встроенных элементов, элементов управления, панелей и рамок; единый радиус скругления для всего интерфейса уничтожил бы эту иерархию.
euiBorderRadiusInline4pxРазличайте форму встроенных элементов, элементов управления, панелей и рамок; единый радиус скругления для всего интерфейса уничтожил бы эту иерархию.
euiBorderRadiusControl8pxРазличайте форму встроенных элементов, элементов управления, панелей и рамок; единый радиус скругления для всего интерфейса уничтожил бы эту иерархию.
euiBorderRadiusPanel12pxРазличайте форму встроенных элементов, элементов управления, панелей и рамок; единый радиус скругления для всего интерфейса уничтожил бы эту иерархию.
euiBorderRadiusFrame16pxРазличайте форму встроенных элементов, элементов управления, панелей и рамок; единый радиус скругления для всего интерфейса уничтожил бы эту иерархию.

Фокус и анимация

Источник
Название / правилоЗначение / конфигурацияПрименение
euiFocusRingSize2pxСохраняйте нативное поведение фокуса и анимации, не переопределяя внутренние селекторы .eui.
euiFocusBackgroundColor#ECF1F9 Сохраняйте нативное поведение фокуса и анимации, не переопределяя внутренние селекторы .eui.
euiAnimSpeedExtraFast90msСохраняйте нативное поведение фокуса и анимации, не переопределяя внутренние селекторы .eui.
euiAnimSpeedFast150msСохраняйте нативное поведение фокуса и анимации, не переопределяя внутренние селекторы .eui.
euiAnimSpeedNormal250msСохраняйте нативное поведение фокуса и анимации, не переопределяя внутренние селекторы .eui.
euiAnimSpeedSlow350msСохраняйте нативное поведение фокуса и анимации, не переопределяя внутренние селекторы .eui.

Контракт нативной API в этом обозревателе

Источник
Название / правилоЗначение / конфигурацияПрименение
EuiProvidercolorMode="light" | "dark"Предоставляет контекст темы и стили Emotion.
useEuiTheme{ euiTheme }Определяет семантические цвета для пользовательских элементов и EuiHealth.
EuiBasicTableitems · itemId · columnsОтображает управляемую видимую коллекцию со стабильными идентификаторами.
EuiFieldSearchvalue · onChange · incrementalПриложение фильтрует локальную коллекцию из шести событий.
EuiButtonGroupoptions · idSelected · onChangeУправляемый фильтр уровня важности с видимой легендой.
EuiHealthcolor + readable child labelЦветная точка дополняет обозначение уровня важности, но не заменяет его.
03

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

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

DESIGN-elastic-ui.md

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

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

Структура обозревателя дизайн-системы Elastic UI

Рабочее пространство для расследований, а не универсальная панель мониторинга

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

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

Используйте актуальную границу темы

В этом примере EUI 123.0.0 сочетается с Borealis 8.1.0. Справочные значения взяты из этой опубликованной темы, а не из старого снимка экрана Amsterdam. EuiProvider управляет режимом оформления и контекстом стилей. Состояние приложения не зависит от вычислений темы, поэтому при смене оформления сохранённые события и текущий поисковый запрос не сбрасываются.

Семантические цветовые роли дизайн-системы Elastic UI

Свяжите уровень важности с его значением

В этом приложении для уровня Info используется основная роль, для Warning — роль предупреждения, а для Error — роль опасности. EuiHealth показывает рядом с точкой текстовое обозначение уровня важности. Это соответствие — правило приложения; оно не означает, что любой элемент основного цвета обозначает информационный уровень. Для ошибок и событий по-прежнему нужны понятные текстовые подписи.

Получайте цвета из активной темы

Экран вызывает useEuiTheme и использует полученные цвета для фона, основного текста и индикаторов состояния. В таблицах экспорта приведены пары значений для светлой и тёмной тем, чтобы различие было заметно. Не копируйте одно значение hex для обоих режимов и не используйте сгенерированные классы Emotion, чтобы принудительно задать соответствие.

Типографика и числовая иерархия дизайн-системы Elastic UI

Сначала задайте контекст показателей, затем выделите числа

EuiStat сопоставляет 6 примерам событий, 1 событию с ошибкой и количеству сохранённых событий описания. Без них числа были бы неоднозначны. EuiTitle обозначает начало расследования, а EuiText указывает временной интервал и уточняет, что данные приведены для примера. Заголовок потока — заголовок меньшего уровня, а не второй заголовок страницы.

Сохраняйте читаемость текста журнала при высокой плотности данных

В экспорте Borealis используется базовый размер 14px и рекомендованная высота строки 1.5; шкала типографики включает размеры 12/16/20/24/30px. Для временных меток и названий сервисов предусмотрены колонки фиксированной ширины, а сообщению события отводится гибкая ширина. В примере используются доступные системные шрифты из нативного стека — удалённый шрифт Inter не загружается.

Базовая таблица и управляемые фильтры дизайн-системы Elastic UI

Отделяйте отображение от фильтрации

EuiBasicTable получает уже отфильтрованные элементы. Для столбцов задаётся поле или пользовательский рендерер, а itemId использует стабильный идентификатор события. EuiFieldSearch обновляет состояние запроса, а EuiButtonGroup — идентификатор выбранного уровня важности. Приложение объединяет оба условия фильтрации, прежде чем передать таблице видимую коллекцию.

  1. Введите название сервиса или фрагмент сообщения.
  2. Выберите Error или Warning, чтобы добавить условие по уровню важности.
  3. Сохраните подходящее событие с помощью действия в его строке.
  4. Сбросьте фильтры и проверьте, что сохранённое событие по-прежнему отмечено.

Сохраняйте события по их идентификаторам, а не по позиции строки

Интервалы дизайн-системы Elastic UI и адаптивные данные

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

Опубликованные размеры: 4, 8, 12, 16, 24, 32 и 40px. EuiSpacer и EuiFlexGroup задают интервалы между сводными показателями, фильтрами и таблицей событий. EuiPanel формирует контейнер; в теме радиус панели 12px отличается от радиуса элементов управления 8px и рамок 16px.

Удерживайте страницу в пределах мобильной области просмотра

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

Дизайн-система Elastic UI: поиск, пустые результаты и сохранённые данные

Для поиска без результатов предусмотрено простое действие для восстановления

При запросе без результатов отображается сообщение «Нет событий, соответствующих текущим фильтрам» и действие «Сбросить фильтры». Сброс запроса и уровня серьёзности восстанавливает все шесть примеров событий, не изменяя сохранённые идентификаторы. Количество совпавших событий над таблицей объявляется через вежливую область динамического обновления.

Локальное сохранение — это не рабочий процесс реагирования на инцидент

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

Дизайн-система Elastic UI: доступные действия в таблице

Не полагайтесь только на подсказки для обозначения фильтров

У поля поиска есть доступное имя, а группа кнопок служит легендой уровней серьёзности. У столбцов таблицы есть понятные заголовки; действие в каждой строке представлено стандартной EuiButtonEmpty. EuiHealth содержит текст, поэтому цвет статуса никогда не является единственным источником информации. Сохраняйте эти требования при замене примеров данных.

  • Для обозначения уровня серьёзности используйте видимые подписи.
  • Сохраните подпись таблицы и названия столбцов.
  • Связывайте сохранённое состояние со стабильным идентификатором события.

Сохраняйте согласованность клавиатурного и визуального состояния

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

Дизайн-система Elastic UI: настройка и интеграция темы

Установите документированные зависимые пакеты

В официальном руководстве по настройке используются Yarn и перечислены Borealis, Emotion, datemath и moment наряду с EUI. В этом примере используется React 18, а дерево компонентов не обёрнуто в StrictMode. Эти ограничения явно указаны ниже, чтобы приложение не наследовало незаметно React 19 из только что созданного шаблона.

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

Дизайн-система Elastic UI: примеры компонентов

main.jsx — полноценный обозреватель журналов на нативных компонентах

EuiProvider и Borealis позволяют создать контролируемую таблицу событий с фильтрацией по уровню серьёзности и поиску, а также локальным состоянием сохранённых событий.

jsx
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import {
  EuiProvider,
  EuiPanel,
  EuiTitle,
  EuiText,
  EuiSpacer,
  EuiFlexGroup,
  EuiFlexItem,
  EuiFieldSearch,
  EuiButtonGroup,
  EuiButtonEmpty,
  EuiBasicTable,
  EuiHealth,
  EuiStat,
  EuiSwitch,
  EuiCallOut,
  useEuiTheme,
} from "@elastic/eui";
const logs = [
  {
    id: 1,
    time: "09:42:18",
    service: "gateway",
    message: "Request completed",
    level: "Info",
    duration: 42,
  },
  {
    id: 2,
    time: "09:42:21",
    service: "worker",
    message: "Retry queued after timeout",
    level: "Warning",
    duration: 1200,
  },
  {
    id: 3,
    time: "09:42:24",
    service: "gateway",
    message: "Upstream connection refused",
    level: "Error",
    duration: 800,
  },
  {
    id: 4,
    time: "09:42:29",
    service: "indexer",
    message: "Batch indexed",
    level: "Info",
    duration: 180,
  },
  {
    id: 5,
    time: "09:42:32",
    service: "worker",
    message: "Job completed",
    level: "Info",
    duration: 94,
  },
  {
    id: 6,
    time: "09:42:36",
    service: "gateway",
    message: "Upstream connection restored",
    level: "Info",
    duration: 51,
  },
];
function Screen({ dark, setDark }) {
  const { euiTheme } = useEuiTheme();
  const [query, setQuery] = useState(""),
    [level, setLevel] = useState("all"),
    [saved, setSaved] = useState([]);
  const visible = logs.filter(
    (x) =>
      (level === "all" || x.level === level) &&
      (x.service + " " + x.message).toLowerCase().includes(query.toLowerCase()),
  );
  const colors = {
    Info: euiTheme.colors.primary,
    Warning: euiTheme.colors.warning,
    Error: euiTheme.colors.danger,
  };
  const columns = [
    { field: "time", name: "Time", width: "105px" },
    { field: "service", name: "Service", width: "105px" },
    {
      field: "message",
      name: "Event",
      render: (value, item) => (
        <span>
          {value}
          {saved.includes(item.id) ? " · Saved locally" : ""}
        </span>
      ),
    },
    {
      field: "level",
      name: "Level",
      width: "110px",
      render: (value) => <EuiHealth color={colors[value]}>{value}</EuiHealth>,
    },
    {
      name: "Action",
      width: "110px",
      render: (item) => (
        <EuiButtonEmpty
          size="xs"
          onClick={() =>
            setSaved((v) =>
              v.includes(item.id)
                ? v.filter((id) => id !== item.id)
                : [...v, item.id],
            )
          }
        >
          {saved.includes(item.id) ? "Unsave" : "Save event"}
        </EuiButtonEmpty>
      ),
    },
  ];
  return (
    <main
      style={{
        padding: 24,
        background: euiTheme.colors.backgroundBasePlain,
        color: euiTheme.colors.textParagraph,
      }}
    >
      <EuiFlexGroup justifyContent="spaceBetween" alignItems="center">
        <EuiFlexItem>
          <EuiText size="xs">
            <p>ELASTIC UI · LOG EXPLORER</p>
          </EuiText>
          <EuiTitle size="m">
            <h1>Investigate gateway events</h1>
          </EuiTitle>
        </EuiFlexItem>
        <EuiFlexItem grow={false}>
          <EuiSwitch
            label="Dark mode"
            checked={dark}
            onChange={(e) => setDark(e.target.checked)}
          />
        </EuiFlexItem>
      </EuiFlexGroup>
      <EuiSpacer size="l" />
      <EuiFlexGroup>
        <EuiFlexItem>
          <EuiPanel>
            <EuiStat title="6" description="Sample events" titleSize="m" />
          </EuiPanel>
        </EuiFlexItem>
        <EuiFlexItem>
          <EuiPanel>
            <EuiStat
              title="1"
              description="Error event"
              titleSize="m"
              titleColor="danger"
            />
          </EuiPanel>
        </EuiFlexItem>
        <EuiFlexItem>
          <EuiPanel>
            <EuiStat
              title={String(saved.length)}
              description="Saved in this preview"
              titleSize="m"
            />
          </EuiPanel>
        </EuiFlexItem>
      </EuiFlexGroup>
      <EuiSpacer size="l" />
      <EuiPanel>
        <EuiTitle size="xs">
          <h2>Event stream</h2>
        </EuiTitle>
        <EuiText size="s">
          <p>09:42:18–09:42:36 · fictional data · no live telemetry</p>
        </EuiText>
        <EuiSpacer size="m" />
        <EuiFlexGroup alignItems="center">
          <EuiFlexItem>
            <EuiFieldSearch
              fullWidth
              aria-label="Search log events"
              placeholder="Search service or message"
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              incremental
            />
          </EuiFlexItem>
          <EuiFlexItem grow={false}>
            <EuiButtonGroup
              legend="Filter severity"
              options={[
                { id: "all", label: "All" },
                { id: "Warning", label: "Warning" },
                { id: "Error", label: "Error" },
              ]}
              idSelected={level}
              onChange={(id) => setLevel(id)}
            />
          </EuiFlexItem>
        </EuiFlexGroup>
        <EuiSpacer size="m" />
        <EuiText size="xs">
          <p aria-live="polite">{visible.length} matching events</p>
        </EuiText>
        <div style={{ overflowX: "auto", maxWidth: "100%" }}>
          <div style={{ minWidth: 640 }}>
            <EuiBasicTable
                  responsiveBreakpoint={false}
              items={visible}
              itemId="id"
              columns={columns}
              tableCaption="Fictional application events"
              noItemsMessage="No events match the current filters."
            />
          </div>
        </div>
        {!visible.length && (
          <EuiButtonEmpty
            onClick={() => {
              setLevel("all");
              setQuery("");
            }}
          >
            Clear filters
          </EuiButtonEmpty>
        )}
      </EuiPanel>
      <EuiSpacer size="l" />
      <EuiCallOut size="s" title="Local investigation workspace">
        Saving an event only changes this preview. No query is sent to
        Elasticsearch and no incident is created.
      </EuiCallOut>
      <EuiSpacer size="m" />
      <EuiText size="xs">
        <p>
          Native Elastic UI 123.0.0 · Borealis 8.1.0 theme · controlled filters
          and table actions.
        </p>
      </EuiText>
    </main>
  );
}
function App() {
  const [dark, setDark] = useState(false);
  return (
    <EuiProvider colorMode={dark ? "dark" : "light"}>
      <Screen dark={dark} setDark={setDark} />
    </EuiProvider>
  );
}
createRoot(document.getElementById("root")).render(<App />);

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

  • Сохраните файл как src/main.jsx в шаблоне React. Эта точка входа намеренно не включает StrictMode.
  • Ограниченная ширина таблицы 640px — решение приложения CSS; все визуальные элементы компонентов предоставляются EUI.

Примечание о пользовательском оформлении с учётом темы

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

jsx
import React from 'react';
import { useEuiTheme } from '@elastic/eui';
export function InvestigationNote({ children }) {
  const { euiTheme } = useEuiTheme();
  return <aside style={{ padding: euiTheme.size.m, color: euiTheme.colors.textParagraph, borderLeft: `2px solid ${euiTheme.colors.primary}` }}>{children}</aside>;
}

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

  • Разместите InvestigationNote внутри EuiProvider. Примечание унаследует выбранный режим оформления.
04

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

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

В официальном руководстве EUI описана установка с помощью Yarn и поддержка React 18. Для сборщиков, отличных от Webpack, задокументированы особенности; этот конкретный пример на нативных компонентах собран с помощью esbuild и проверен в браузере. Используйте версию Node.js, поддерживаемую вашим шаблоном.

sh
yarn create vite elastic-investigation --template react
cd elastic-investigation
yarn add [email protected] [email protected] @elastic/[email protected] @elastic/[email protected] @elastic/datemath @emotion/react @emotion/css moment
# Replace src/main.jsx with the complete example above.
yarn dev

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

Промпт для AI-агента
Создайте экран расследования журналов с помощью Elastic UI 123.0.0, Borealis 8.1.0 и React 18. Изучите предоставленные экспорт темы и исходный код на нативных компонентах. Используйте EuiProvider, контролируемый EuiBasicTable, доступный поиск и фильтры по уровню серьёзности. Сохраняйте данные по стабильному идентификатору события, оставляйте закладки при фильтрации и отличайте локальное состояние интерфейса от настоящего запроса к Elasticsearch или ответа на запрос сохранения. На мобильных устройствах удерживайте таблицу в пределах отведённой ей области.
05

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

Руководство, подготовленное OpenDesign, и вымышленный локальный обозреватель журналов на нативных компонентах с Elastic UI 123.0.0 и Borealis 8.1.0. Примеры событий не являются данными телеметрии в реальном времени, а действие сохранения хранит данные только в памяти. Для EUI предусмотрены варианты лицензирования Elastic/SSPL; сведения о распространении см. в официальной лицензии пакета.