Data Analytics · New Resource

Elastic UI Design System.

Build an Elastic UI log explorer with verified Borealis scales, native table and search controls, severity filtering, local saved events, and complete React source.

OpenDesign Guide8 Chapters43 Reference EntriesOriginal Application Guide
01

Elastic UI Design System Interface Preview

Filter the event stream by message or severity, save individual events, clear an empty result, and switch between light and dark appearance.

Search and save sample log eventsOpen Full Example
Native Elastic UI 123.0.0 / Borealis 8.1.0 with React 18.3.1. Original local log data and application state. · Implementation reference
02

Elastic UI Design System Design Reference

Elastic UI 123.0.0 with Borealis theme 8.1.0 and React 18.3.1. Tables use names from the published theme JSON; these are export keys, not literal useEuiTheme object paths. The actual preview uses the native React theme API.

Borealis semantic colors

Source
Name / RuleValue / ConfigurationUse
euiColorPrimarylight: #0B64DD; dark: #61A2FFPublished theme-export names. In React, consume the corresponding semantic role through useEuiTheme rather than hardcoding these values.
euiColorSuccesslight: #008A5E; dark: #24C292Published theme-export names. In React, consume the corresponding semantic role through useEuiTheme rather than hardcoding these values.
euiColorWarninglight: #FACB3D; dark: #FACB3DPublished theme-export names. In React, consume the corresponding semantic role through useEuiTheme rather than hardcoding these values.
euiColorDangerlight: #C61E25; dark: #F6726APublished theme-export names. In React, consume the corresponding semantic role through useEuiTheme rather than hardcoding these values.
euiColorEmptyShadelight: #FFFFFF; dark: #111C2CPublished theme-export names. In React, consume the corresponding semantic role through useEuiTheme rather than hardcoding these values.
euiColorFullShadelight: #07101F; dark: #FFFFFFPublished theme-export names. In React, consume the corresponding semantic role through useEuiTheme rather than hardcoding these values.
euiPageBackgroundColorlight: #ECF1F9; dark: #07101FPublished theme-export names. In React, consume the corresponding semantic role through useEuiTheme rather than hardcoding these values.
euiTextColorlight: #384861; dark: #B4C1D5Published theme-export names. In React, consume the corresponding semantic role through useEuiTheme rather than hardcoding these values.
euiTextSubduedColorlight: #516381; dark: #98A8C3Published theme-export names. In React, consume the corresponding semantic role through useEuiTheme rather than hardcoding these values.

Spacing scale

Source
Name / RuleValue / ConfigurationUse
euiSizeXS4pxUse matching EuiSpacer/FlexGroup sizes for layout rhythm; base is 16px in this theme export.
euiSizeS8pxUse matching EuiSpacer/FlexGroup sizes for layout rhythm; base is 16px in this theme export.
euiSizeM12pxUse matching EuiSpacer/FlexGroup sizes for layout rhythm; base is 16px in this theme export.
euiSize16pxUse matching EuiSpacer/FlexGroup sizes for layout rhythm; base is 16px in this theme export.
euiSizeL24pxUse matching EuiSpacer/FlexGroup sizes for layout rhythm; base is 16px in this theme export.
euiSizeXL32pxUse matching EuiSpacer/FlexGroup sizes for layout rhythm; base is 16px in this theme export.
euiSizeXXL40pxUse matching EuiSpacer/FlexGroup sizes for layout rhythm; base is 16px in this theme export.

Typography

Source
Name / RuleValue / ConfigurationUse
euiFontSizeXS12pxPublished type reference. Use EuiText/EuiTitle variants for the component hierarchy.
euiFontSizeS14pxPublished type reference. Use EuiText/EuiTitle variants for the component hierarchy.
euiFontSize14pxPublished type reference. Use EuiText/EuiTitle variants for the component hierarchy.
euiFontSizeM16pxPublished type reference. Use EuiText/EuiTitle variants for the component hierarchy.
euiFontSizeL20pxPublished type reference. Use EuiText/EuiTitle variants for the component hierarchy.
euiFontSizeXL24pxPublished type reference. Use EuiText/EuiTitle variants for the component hierarchy.
euiFontSizeXXL30pxPublished type reference. Use EuiText/EuiTitle variants for the component hierarchy.
euiLineHeight1.5Published type reference. Use EuiText/EuiTitle variants for the component hierarchy.

Borders and shape

Source
Name / RuleValue / ConfigurationUse
euiBorderWidthThin1pxDistinguish inline, control, panel and frame shape; a single universal corner radius would erase the hierarchy.
euiBorderWidthThick2pxDistinguish inline, control, panel and frame shape; a single universal corner radius would erase the hierarchy.
euiBorderColor#E3E8F2 Distinguish inline, control, panel and frame shape; a single universal corner radius would erase the hierarchy.
euiBorderRadiusInline4pxDistinguish inline, control, panel and frame shape; a single universal corner radius would erase the hierarchy.
euiBorderRadiusControl8pxDistinguish inline, control, panel and frame shape; a single universal corner radius would erase the hierarchy.
euiBorderRadiusPanel12pxDistinguish inline, control, panel and frame shape; a single universal corner radius would erase the hierarchy.
euiBorderRadiusFrame16pxDistinguish inline, control, panel and frame shape; a single universal corner radius would erase the hierarchy.

Focus and motion

Source
Name / RuleValue / ConfigurationUse
euiFocusRingSize2pxKeep native focus and motion behavior instead of overriding internal .eui selectors.
euiFocusBackgroundColor#ECF1F9 Keep native focus and motion behavior instead of overriding internal .eui selectors.
euiAnimSpeedExtraFast90msKeep native focus and motion behavior instead of overriding internal .eui selectors.
euiAnimSpeedFast150msKeep native focus and motion behavior instead of overriding internal .eui selectors.
euiAnimSpeedNormal250msKeep native focus and motion behavior instead of overriding internal .eui selectors.
euiAnimSpeedSlow350msKeep native focus and motion behavior instead of overriding internal .eui selectors.

Native API contract in this explorer

Source
Name / RuleValue / ConfigurationUse
EuiProvidercolorMode="light" | "dark"Supplies theme context and Emotion styles.
useEuiTheme{ euiTheme }Resolve semantic colors for custom elements and EuiHealth.
EuiBasicTableitems · itemId · columnsRender the controlled visible collection using stable IDs.
EuiFieldSearchvalue · onChange · incrementalApplication filters a six-event local collection.
EuiButtonGroupoptions · idSelected · onChangeControlled severity filter with a visible legend.
EuiHealthcolor + readable child labelA status dot supplements, rather than replaces, the severity word.
03

Elastic UI Design System Complete Guide

A practical guide to choosing, applying, and reviewing this system for a real interface.

DESIGN-elastic-ui.md

Complete guidance, an implementation starting point, and source links.

Download Guide

Elastic UI Design System Explorer Structure

An investigation workspace rather than a generic dashboard

The specimen has three compact summary statistics and a single event stream. A search field and severity group narrow that stream; each row exposes an independent save action. Keeping the action next to its event lets a reader collect evidence without leaving the filtered context. The summary explicitly counts sample events rather than claiming live traffic.

From this OpenDesign guide

Use the current theme boundary

This example pairs EUI 123.0.0 with Borealis 8.1.0. The reference values come from that published theme, not an older Amsterdam screenshot. EuiProvider owns the visual mode and style context. Application state remains outside any theme calculation, so changing appearance does not reset saved events or the current query.

Elastic UI Design System Semantic Color Roles

Apply severity as a meaningful relationship

Info uses the primary role, Warning the warning role, and Error the danger role in this application. EuiHealth displays the severity word alongside the dot. The mapping is application policy; it does not imply that every primary-colored element represents informational severity. Error counts and event labels still need readable text.

Resolve colors from the active theme

Screen calls useEuiTheme and uses the resolved colors for its canvas, body text and health indicators. The export tables include paired light/dark values so the difference is visible. Do not copy one hex value into both modes or target generated Emotion class names to force a match.

Elastic UI Design System Type and Numerical Hierarchy

Give statistics context before emphasizing the number

EuiStat pairs the 6 sample events, 1 error event and saved count with descriptions. The number alone would be ambiguous. EuiTitle introduces the investigation, while EuiText supplies the time window and sample-data qualification. The stream header is a smaller heading rather than a second page title.

Keep log text readable at compact density

Borealis uses a 14px base export with a 1.5 line-height reference, plus 12/16/20/24/30px type steps. Timestamps and service names have predictable columns, while the event message receives flexible width. The example uses available system fonts through the native stack and does not claim a remotely loaded Inter asset.

Elastic UI Design System Basic Table and Controlled Filters

Separate presentation from filtering

EuiBasicTable receives the already-filtered items. Columns define a field or custom renderer, and itemId uses the stable event ID. EuiFieldSearch updates query state; EuiButtonGroup updates the selected severity ID. The application combines both predicates before handing the visible collection to the table.

  1. Type a service name or message fragment.
  2. Choose Error or Warning to combine a severity predicate.
  3. Save a matching event using its row action.
  4. Clear the filters and verify the saved event remains marked.

Save by event identity, not row position

Elastic UI Design System Spacing and Responsive Data

Use the native spacing scale across groups

The published sizes are 4, 8, 12, 16, 24, 32 and 40px. EuiSpacer and EuiFlexGroup provide the space between summary statistics, filters and the event table. EuiPanel supplies the container shape; the theme distinguishes its 12px panel radius from the 8px control and 16px frame radii.

Keep the page inside the mobile viewport

The summary and filter groups reflow through native FlexGroup behavior. The table sits in a bounded horizontal scrolling region with a 640px application minimum, preserving the timestamp, message and action relationships instead of letting the entire page overflow. A production table can choose the documented responsive-table options for its actual column set.

Elastic UI Design System Search, Empty and Saved States

A zero-result search has a direct recovery action

An impossible query displays No events match the current filters and a Clear filters action. Resetting query and severity restores all six sample events without altering saved IDs. The count above the table announces the matching-event total through a polite live region.

A local save is not an incident workflow

Saving an event changes the visible row label and the saved statistic. It does not contact Elasticsearch, create an incident or persist across refresh. A real investigation product should add a documented persistence endpoint and report pending or failed responses before claiming that the saved collection is durable.

Elastic UI Design System Accessible Table Actions

Name filters independently of placeholders

The search has an accessible name, and the button group supplies a severity legend. Table columns have descriptive headers; each row action is a native EuiButtonEmpty. EuiHealth includes text, so the status color is never the only information. Preserve these contracts when replacing sample data.

  • Use visible words for severity.
  • Retain the table caption and column names.
  • Keep saved state associated with the stable event ID.

Keep keyboard and visual state together

Users can focus search, select a severity filter, reach row actions and toggle the appearance setting. The 2px focus ring is part of the theme reference. Test a filtered set after saving a row and after clearing the filter; the action label and saved statistic should continue to agree.

Elastic UI Design System Setup and Theme Integration

Install the documented peer dependencies

The official setup guide uses Yarn and lists Borealis, Emotion, datemath and moment alongside EUI. This specimen runs React 18 and does not wrap the tree in StrictMode. The setup below keeps those constraints explicit rather than silently inheriting React 19 from a newly generated application.

Treat the full entry file as the implementation

Elastic UI Design System Component Examples

main.jsx — complete native log explorer

EuiProvider and Borealis support a controlled event table with severity/search filtering and local saved-event state.

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

Code reference

  • Save as src/main.jsx in the React scaffold. This entry deliberately does not enable StrictMode.
  • The 640px bounded table width is application CSS; all component visuals come from EUI.

Custom theme-aware note

Use the active theme inside a provider instead of coupling custom markup to generated component classes.

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

Code reference

  • Render InvestigationNote under EuiProvider. The note inherits the selected visual mode.
04

Elastic UI Design System Agent Setup

Implementation Starting Point

The official EUI guide documents Yarn installation and React 18 support. Non-Webpack bundlers have documented caveats; this specific native example was bundled with esbuild and browser-tested. Use a Node.js version supported by your scaffold.

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

A Prompt for Your Project

Agent Prompt
Build a log investigation screen with Elastic UI 123.0.0, Borealis 8.1.0 and React 18. Read the supplied theme export and native source. Use EuiProvider, a controlled EuiBasicTable, accessible search and severity filters. Save by stable event ID, preserve bookmarks across filtering, and distinguish local UI state from a real Elasticsearch query or persistence response. Keep the table contained on mobile.
05

Elastic UI Design System Sources and Scope

OpenDesign-authored guide and fictional local log explorer running native Elastic UI 123.0.0 with Borealis 8.1.0. Sample events are not live telemetry and the save action is in-memory only. EUI carries its own Elastic/SSPL licensing choices; consult the official package license for your distribution.