PipelineTable
먼저 보고, 그다음 계약을 읽습니다
run/job/agent 상태 행에 특화된 표 — 행 좌측 status dot + drill-down 클릭.
Component intent의도와 경계 읽기
운영자 대시보드의 상태 테이블. getStatus(row) 를 주면 각 행 좌측에 StatusLight dot 이 자동으로 붙고(4-state: pending=muted·running=running·success=ok·error=danger 와 StatusLight variant 동일), 미지정 시 dot 컬럼 자체가 사라진다. running/blue 상태에서는 pulse 로 "살아있음"을 표시한다(pulseOnRunning). onRowClick 으로 drill-down, loading 시 skeleton, 빈 rows 시 emptyState 를 렌더. 정렬/페이징이 필요하면 DataTable, 스트리밍 커서가 필요하면 StreamingTable 을 쓴다.
예제
SSOT에 등록된 실제 API 기준 snippet입니다. standalone 배지만 독립 실행 단위이며, fragment는 주변 state·handler 문맥을 생략합니다.
import { PipelineTable } from "@axe/ui";import type { PipelineColumn, StatusVariant } from "@axe/ui";type Run = { id: string; job: string; started: string; state: StatusVariant };const columns: PipelineColumn<Run>[] = [ { key: "job", header: "작업", width: "40%" }, { key: "started", header: "시작", align: "right" },];<PipelineTable columns={columns} rows={runs} getStatus={(r) => r.state} getRowKey={(r) => r.id} onRowClick={(r) => expandRun(r)}/>import { PipelineTable } from "@axe/ui";<PipelineTable columns={columns} rows={[]} getStatus={(r) => r.state} loading loadingRows={6} emptyState="실행 이력이 없습니다"/><div class="axe-pipeline-table"> <div class="axe-pipeline-table__scroll"> <table class="axe-pipeline-table__table"> <thead class="axe-pipeline-table__thead"> <tr> <th class="axe-pipeline-table__th axe-pipeline-table__th--status"></th> <th class="axe-pipeline-table__th" scope="col">작업</th> </tr> </thead> <tbody> <tr class="axe-pipeline-table__tr"> <td class="axe-pipeline-table__td axe-pipeline-table__td--status"> <span class="axe-status-light axe-status-light--running axe-status-light--size-sm"> <span class="axe-status-light__dot" aria-hidden="true"></span> </span> </td> <td class="axe-pipeline-table__td">공시 수집</td> </tr> </tbody> </table> </div></div>Props
TSX 소스가 진실입니다. 주요 export 컴포넌트의 public API만 노출합니다.
| 이름 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
columns | PipelineColumn<Row>[] | 필수 | — | 열 정의 배열. 각 항목: key(식별자) · header(ReactNode) · align?("left"|"right"|"center") · width?(CSS 폭, 미지정 시 auto) · render?(셀 커스텀, 미지정 시 row[key] 를 string/number 로 출력). |
rows | Row[] | 필수 | — | 표시할 상태 행. Row 는 제네릭. |
getStatus | (row: Row) => StatusVariant | — | — | 행별 상태 → 좌측 dot(StatusLight). 미지정 시 status 컬럼 자체가 생략된다. StatusVariant = ok|green|warning|amber|danger|red|muted|gray|running|blue. |
pulseOnRunning | boolean | — | true | status 가 running 또는 blue 일 때 dot 을 pulse. reduced-motion 시 자동으로 정적. |
getRowKey | (row: Row, index: number) => string | — | — | React key + onRowClick 대상 식별. 미지정 시 배열 index. |
onRowClick | (row: Row) => void | — | — | 행 클릭(drill-down) 콜백. 지정하면 행이 role=button+tabIndex 위젯이 되고 Enter/Space 로도 실행된다(DataTable 과 달리 별도 rowClickable 플래그 없음). |
loading | boolean | — | — | true 면 tbody 자리에 skeleton 행(dot + bar)을 렌더. |
loadingRows | number | — | 5 | loading skeleton 행 수. |
emptyState | React.ReactNode | — | — | rows 가 비었을 때 placeholder. 미지정 시 "데이터 없음". |
...rest | Omit<React.HTMLAttributes<HTMLDivElement>, "onClick"> | — | — | className 병합 후 나머지는 루트 div 로 전파. onClick 은 행 단위 onRowClick 과 혼동을 막으려 제외. forwardRef 는 루트 div 를 가리킨다. |
.axe-* 클래스 계약
React 밖에서도 같은 표면을 그리는 공개 계약입니다. stable은 minor 버전 안에서 이름을 바꾸지 않습니다.
| 클래스 | 안정성 | 용도 |
|---|---|---|
.axe-pipeline-table | stable | 루트 div — elevated 배경·border·radius-lg·overflow hidden(radius clip). |
.axe-pipeline-table__scroll | stable | 가로 스크롤 컨테이너(iOS 모멘텀). |
.axe-pipeline-table__table | stable | `<table>` — width 100%·min-width 600px·border-collapse. |
.axe-pipeline-table__thead | stable | thead — subtle 배경. |
.axe-pipeline-table__th | stable | 헤더 셀 — xs·uppercase·secondary. `--right/--center` 로 정렬. |
.axe-pipeline-table__th--status | stable | status dot 열의 헤더 — 32px 고정 폭(라벨 없는 빈 셀). |
.axe-pipeline-table__td | stable | 본문 셀 — tabular-nums·middle 정렬. `--right/--center` 로 정렬. |
.axe-pipeline-table__td--status | stable | status dot 셀 — 32px·중앙 정렬. |
.axe-pipeline-table__tr | stable | 본문 행 — 하단 border·hover 시 accent 4% 배경. |
.axe-pipeline-table__tr--clickable | stable | onRowClick 이 있을 때 — cursor pointer·focus-visible outline. |
.axe-pipeline-table__empty | stable | 빈 상태 셀 — 중앙 muted 텍스트(colSpan 전폭). |
.axe-pipeline-table__tr--empty | internal | 빈 상태 행 마커 — hover 무효화. |
.axe-pipeline-table__tr--skeleton | internal | loading skeleton 행. |
.axe-pipeline-table__skel | internal | shimmer 플레이스홀더(indicators.css 의 axe-shimmer 공유). |
.axe-pipeline-table__skel--dot | internal | skeleton status dot(8px 원형). |
.axe-pipeline-table__skel--bar | internal | skeleton 텍스트 바(70%·12px). |
접근성
키보드, ARIA, 구현 노트를 함께 검토합니다.
- onRowClick 이 있는 행은 Enter/Space 로 실행(preventDefault 로 스크롤 방지)
onRowClick 이 있을 때만 행이 role="button"+tabIndex=0 를 받는다(없으면 순수 table 시맨틱). status dot 은 StatusLight — 내부 dot span 이 aria-hidden 이라 상태는 순수 시각 신호다.
PipelineTable 은 StatusLight 를 label 없이 dot-only 로 렌더하므로 스크린리더는 상태를 읽지 못한다 — SR 사용자에게 상태가 필요하면 별도 텍스트/뱃지 컬럼(render 로)이나 행 aria-label 로 보강한다. onRowClick 을 쓸 때는 셀 안에 링크/버튼을 넣지 않는다(nested interactive 충돌).