본문으로 건너뛰기
데이터 / timeline

Timeline

날짜로 묶은 활동 피드 — 좌측 dot + 수직 레일, 한국어 상대 날짜 헤더.
데이터timelineStatic specimentimeline타임라인activity활동
01 · Specimen

먼저 보고, 그다음 계약을 읽습니다

날짜로 묶은 활동 피드 — 좌측 dot + 수직 레일, 한국어 상대 날짜 헤더.

Workbench 불러오는 중…
Component intent의도와 경계 읽기

items 를 groupBy(day/week/month/커스텀 함수) 로 묶어 최신→과거 순으로 그리는 활동 타임라인. 좌측 dot 과 이를 잇는 수직선은 CSS ::before 로만 그린다. 그룹 헤더는 relativeLabels 가 켜지면 ko-KR 상대 표기('오늘'/'어제'/'N일 전'/'이번 주'/'지난 달')로, 꺼지면 절대 날짜로 나온다. stickyHeaders 로 스크롤 중 날짜 헤더를 상단 고정하고, loadMore/hasMore/loading 으로 무한 스크롤 '더 보기'를 붙인다. item.variant 가 dot 색(success/warning/danger/info)을 정한다.

02 · Use

예제

SSOT에 등록된 실제 API 기준 snippet입니다. standalone 배지만 독립 실행 단위이며, fragment는 주변 state·handler 문맥을 생략합니다.

01일 단위 그룹 + 더 보기tsxfragment
일 단위 그룹 + 더 보기
import { Timeline } from "@axe/ui";<Timeline  items={[    { id: "a", date: new Date(), title: "회고 작성", content: "주간 회고 초안 완료" },    { id: "b", date: "2026-05-20", title: "Frame 배포", content: "v0.4.2 blue/green 전환", variant: "success" },  ]}  groupBy="day"  stickyHeaders  hasMore  loadMore={() => fetchMore()}/>
02CSS-only 정적 스냅샷 (비-React)htmlfragment
CSS-only 정적 스냅샷 (비-React)
<ol class="axe-timeline axe-timeline--sticky">  <li class="axe-timeline__group">    <time class="axe-timeline__date-header" datetime="2026-05-21">오늘</time>    <ol class="axe-timeline__items">      <li class="axe-timeline__item axe-timeline__item--success">        <span class="axe-timeline__rail" aria-hidden="true">          <span class="axe-timeline__dot"></span>        </span>        <div class="axe-timeline__body">          <div class="axe-timeline__title-row">            <span class="axe-timeline__title">Frame 배포</span>            <time class="axe-timeline__time" datetime="2026-05-21T09:14">09:14</time>          </div>          <div class="axe-timeline__content">v0.4.2 blue/green 전환</div>        </div>      </li>    </ol>  </li></ol>
03 · React

Props

TSX 소스가 진실입니다. 주요 export 컴포넌트의 public API만 노출합니다.

이름타입필수기본값설명
itemsTimelineItem[]필수타임라인 항목들. `{ id; date: Date | string; title?; content; icon?; variant? }`. date 문자열은 new Date() 로 파싱. content 만 필수, title 없으면 시각만 단독 표시.
groupBy"day" | "week" | "month" | ((d: Date) => string)"day"그룹 기준. 함수를 주면 반환 문자열이 그룹 키가 되고 헤더는 절대 날짜로 표기.
relativeLabelsbooleantrue그룹 헤더를 '오늘'/'어제'/'이번 주' 등 ko-KR 상대 표기로. false 면 절대 날짜.
stickyHeadersbooleantrue스크롤 컨테이너 안에서 날짜 헤더를 상단 고정(position: sticky).
compactbooleanfalse간격을 좁히고 dot 을 축소한 dense 모드. compact 에선 item.icon 을 그리지 않는다.
loadMore() => void'더 보기' 버튼 클릭 핸들러. hasMore 와 함께 쓴다.
hasMorebooleanfalsetrue 면 목록 하단에 '더 보기' 버튼을 렌더.
loadingbooleanfalsetrue 면 '더 보기' 대신 '불러오는 중...'(aria-live) 표시.
...restOmit<React.HTMLAttributes<HTMLOListElement>, "onChange">className 병합, 나머지는 루트 <ol> 로 전파. ref 는 루트 ol 로 forward.
04 · Any stack

.axe-* 클래스 계약

React 밖에서도 같은 표면을 그리는 공개 계약입니다. stable은 minor 버전 안에서 이름을 바꾸지 않습니다.

클래스안정성용도
.axe-timelinestable루트 <ol> — 세로 그룹 스택.
.axe-timeline--stickystable날짜 헤더 sticky-top 활성.
.axe-timeline--compactstabledense 모드 — 간격/ dot 축소.
.axe-timeline__groupstable한 날짜 묶음 <li>(헤더 + 항목 목록).
.axe-timeline__date-headerstable그룹 날짜 헤더 <time>.
.axe-timeline__itemsstable그룹 안 항목들의 중첩 <ol>.
.axe-timeline__itemstable항목 <li> — 레일 + 본문 2열.
.axe-timeline__item--successstabledot success 색.
.axe-timeline__item--warningstabledot warning 색.
.axe-timeline__item--dangerstabledot danger 색.
.axe-timeline__item--infostabledot info 색.
.axe-timeline__railstable좌측 dot+수직선 열(선은 ::before). aria-hidden.
.axe-timeline__dotstable항목 원형 마커(아이콘 담김).
.axe-timeline__bodystable제목/시각/본문을 담는 우측 본문.
.axe-timeline__title-rowstable제목 + 시각을 좌우로 놓는 줄.
.axe-timeline__titlestable항목 제목 텍스트.
.axe-timeline__timestable항목 시각 <time>(HH:MM).
.axe-timeline__time--solostable제목 없을 때 시각 단독 표기.
.axe-timeline__contentstable항목 본문 영역.
.axe-timeline__loadmorestable'더 보기'/로딩 줄 <li>.
.axe-timeline__loadmore-btnstable'더 보기' 버튼.
.axe-timeline__loadingstable'불러오는 중...' 텍스트(aria-live).
.axe-timeline__emptystable항목 0개일 때 '기록이 없습니다' <li>.
비-React 소비 노트
레일 수직선·dot·sticky 는 순수 CSS 라 서버가 같은 중첩 마크업(ol.axe-timeline > li.__group > time.__date-header + ol.__items > li.__item ...)을 그리면 CSS-only 로 동일 재현된다. 단 그룹핑·정렬·상대 날짜 라벨은 컴포넌트가 계산하는 것이라 서버(maud/jinja)가 직접 산출해 넣어야 하고, '더 보기' 인터랙션은 JS 몫이다.
05 · Inclusive

접근성

키보드, ARIA, 구현 노트를 함께 검토합니다.

ARIA

시맨틱 <ol>/<li> 중첩(그룹 ol > li > time + 항목 ol > li)으로 구조를 표현. 그룹 헤더와 항목 시각은 <time datetime> 으로 머신 리더블. 좌측 rail/dot 은 aria-hidden — 장식.

Notes

'더 보기'는 진짜 <button>(loadMore 호출). 로딩 문구는 aria-live="polite" 로 알림. 항목 순서는 항상 날짜 desc(최신 먼저) 로 컴포넌트가 정렬한다. 상대 라벨은 ko-KR 고정(new Date() 기준이라 클라이언트 렌더 필요 — 그래서 "use client").

06 · Judgment

권장 · 지양

권장
  • groupBy 는 데이터 밀도에 맞춰 — 하루 수십 건이면 day, 장기 이력이면 month.
  • stickyHeaders 를 살리려면 스크롤 되는 컨테이너 안에 둘 것.
  • variant 는 상태가 있는 이벤트(배포 성공/실패 등)에만 — 무의미한 색 남발 금지.
지양
  • loadMore 없이 hasMore 만 켜지 말 것(버튼이 아무 것도 안 함).
  • 정적 prerender 에서 상대 라벨을 기대하지 말 것 — 빌드 시각으로 동결된다.
검색창을 열면 컴포넌트 인덱스를 불러옵니다.