데이터 분석 · 새 리소스

Elastic UI 디자인 시스템.

검증된 Borealis 스케일, 기본 테이블과 검색 컨트롤, 심각도 필터링, 로컬 저장 이벤트, 완전한 React 소스를 갖춘 Elastic UI 로그 탐색기를 만드세요.

OpenDesign 가이드8개 챕터참조 항목 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제어된 표시 컬렉션을 안정적인 ID로 렌더링합니다.
EuiFieldSearchvalue · onChange · incremental애플리케이션이 로컬 이벤트 6개의 컬렉션을 필터링합니다.
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을 호출하고 확인된 색상을 캔버스, 본문 텍스트, 상태 표시기에 사용합니다. 내보내기 표에는 라이트 모드와 다크 모드의 값이 함께 있어 차이를 확인할 수 있습니다. 두 모드에 같은 헥스 값을 복사하거나 생성된 Emotion 클래스 이름을 대상으로 강제로 색상을 맞추지 마세요.

Elastic UI 디자인 시스템 타이포그래피와 수치 계층 구조

숫자를 강조하기 전에 통계를 설명하세요

EuiStat은 샘플 이벤트 6개, 오류 이벤트 1개, 저장된 이벤트 수에 설명을 덧붙입니다. 숫자만으로는 의미가 모호할 수 있습니다. EuiTitle은 조사 제목을 표시하고, EuiText는 시간 범위와 샘플 데이터라는 점을 설명합니다. 스트림 제목은 두 번째 페이지 제목이 아니라 더 작은 제목으로 표시합니다.

촘촘한 레이아웃에서도 로그 텍스트를 읽기 쉽게 유지하세요

Borealis는 1.5의 줄 높이 레퍼런스와 함께 기본 내보내기 글꼴 크기 14px 및 12/16/20/24/30px 크기 단계를 사용합니다. 타임스탬프와 서비스 이름은 예측 가능한 열에 배치하고, 이벤트 메시지에는 유연한 너비를 제공합니다. 이 예제는 네이티브 글꼴 스택을 통해 사용할 수 있는 시스템 글꼴을 사용하며, 원격으로 불러오는 Inter 에셋이 있다고 주장하지 않습니다.

Elastic UI 디자인 시스템 기본 테이블과 제어형 필터

표시와 필터링을 분리하세요

EuiBasicTable에는 필터링이 완료된 항목을 전달합니다. 열은 필드 또는 커스텀 렌더러를 정의하고, itemId에는 안정적인 이벤트 ID를 사용합니다. EuiFieldSearch는 검색어 상태를 업데이트하고, EuiButtonGroup은 선택된 심각도 ID를 업데이트합니다. 애플리케이션은 표시할 컬렉션을 테이블에 전달하기 전에 두 조건을 모두 적용합니다.

  1. 서비스 이름이나 메시지 일부를 입력하세요.
  2. Error 또는 Warning을 선택해 심각도 조건을 추가하세요.
  3. 행 작업을 사용해 조건에 맞는 이벤트를 저장하세요.
  4. 필터를 지우고 저장된 이벤트가 계속 표시되는지 확인하세요.

행 위치가 아니라 이벤트 ID로 저장하세요

Elastic UI 디자인 시스템 간격과 반응형 데이터

그룹 전체에 네이티브 간격 스케일을 사용하세요

게시된 간격 크기는 4, 8, 12, 16, 24, 32, 40px입니다. EuiSpacer와 EuiFlexGroup를 사용해 요약 통계, 필터, 이벤트 테이블 사이에 간격을 둡니다. EuiPanel은 컨테이너 형태를 제공하며, 테마는 패널의 모서리 반경 12px을 컨트롤의 8px 및 프레임의 16px과 구분합니다.

페이지가 모바일 뷰포트 안에 들어오도록 유지하세요

요약 및 필터 그룹은 네이티브 FlexGroup 동작에 따라 재배치됩니다. 테이블은 가로 스크롤이 가능한 제한된 영역에 두고 애플리케이션의 최소 너비를 640px로 유지합니다. 이렇게 하면 페이지 전체가 넘치는 대신 타임스탬프, 메시지, 작업 간의 관계를 유지할 수 있습니다. 프로덕션 테이블에서는 실제 열 구성에 맞춰 문서화된 반응형 테이블 옵션을 선택할 수 있습니다.

Elastic UI 디자인 시스템 검색, 빈 상태, 저장 상태

검색 결과가 없을 때 바로 복구할 수 있는 동작 제공

결과가 없는 검색어를 입력하면 ‘현재 필터와 일치하는 이벤트가 없습니다’라는 메시지와 필터 지우기 동작이 표시됩니다. 검색어와 심각도 필터를 초기화하면 저장된 ID는 그대로 유지하면서 샘플 이벤트 6개가 모두 다시 표시됩니다. 표 위의 개수는 일치하는 이벤트 수를 정중한 라이브 영역을 통해 알립니다.

로컬 저장은 인시던트 워크플로가 아닙니다

이벤트를 저장하면 행에 표시되는 라벨과 저장된 항목 통계가 바뀝니다. 하지만 Elasticsearch에 연결하거나 인시던트를 만들지는 않으며 새로고침 후에도 상태가 유지되지 않습니다. 실제 조사 제품에서 저장된 항목이 유지된다고 설명하려면, 문서화된 영속성 엔드포인트를 추가하고 응답이 대기 중이거나 실패한 상태도 표시해야 합니다.

Elastic UI 디자인 시스템의 접근성 있는 표 동작

플레이스홀더와 별도로 필터에 이름 지정

검색 필드에는 접근성 이름이 있고, 버튼 그룹은 심각도 범례를 제공합니다. 표 열에는 설명이 포함된 헤더가 있고 각 행의 동작에는 기본 EuiButtonEmpty를 사용합니다. EuiHealth에는 텍스트가 포함되어 있어 상태를 색상만으로 전달하지 않습니다. 샘플 데이터를 교체할 때도 이러한 규칙을 유지하세요.

  • 심각도는 눈에 보이는 단어로 표시하세요.
  • 표 캡션과 열 이름을 유지하세요.
  • 저장 상태를 안정적인 이벤트 ID와 연결하세요.

키보드 상태와 시각적 상태를 일치시키세요

사용자는 검색 필드에 포커스를 두고, 심각도 필터를 선택하고, 행 동작으로 이동하고, 모양 설정을 전환할 수 있습니다. 2px 포커스 링은 테마 참조의 일부입니다. 행을 저장한 뒤 필터링된 목록을 확인하고, 필터를 지운 뒤에도 확인하세요. 동작 라벨과 저장된 항목 통계가 계속 일치해야 합니다.

Elastic UI 디자인 시스템 설정 및 테마 통합

문서에 명시된 피어 종속성을 설치하세요

공식 설정 가이드에서는 Yarn을 사용하며 EUI와 함께 Borealis, Emotion, datemath, moment를 나열합니다. 이 예제는 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 />);

코드 참조

  • React 스캐폴드의 src/main.jsx로 저장하세요. 이 진입점에서는 의도적으로 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>;
}

코드 참조

  • EuiProvider 아래에서 InvestigationNote를 렌더링하세요. 메모는 선택한 시각 모드를 따릅니다.
04

Elastic UI 디자인 시스템 AI 에이전트 설정

구현 시작점

공식 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

프로젝트를 위한 프롬프트

에이전트 프롬프트
Elastic UI 123.0.0, Borealis 8.1.0, React 18을 사용해 로그 조사 화면을 구축하세요. 제공된 테마 내보내기 파일과 네이티브 소스를 살펴보세요. EuiProvider, 제어형 EuiBasicTable, 접근성 있는 검색 및 심각도 필터를 사용하세요. 안정적인 이벤트 ID로 항목을 저장하고 필터링 중에도 북마크를 유지하세요. 로컬 UI 상태와 실제 Elasticsearch 쿼리 또는 영속성 응답을 구분하세요. 모바일에서는 표가 화면을 벗어나지 않도록 하세요.
05

Elastic UI 디자인 시스템 출처 및 범위

OpenDesign에서 작성한 가이드와 Borealis 8.1.0을 사용하는 가상의 로컬 로그 탐색기입니다. 네이티브 Elastic UI 123.0.0에서 실행됩니다. 샘플 이벤트는 실시간 원격 측정 데이터가 아니며 저장 동작은 메모리에서만 작동합니다. EUI에는 자체 Elastic/SSPL 라이선스 선택 사항이 있으므로 배포 시 공식 패키지 라이선스를 확인하세요.