차트
차트는 숫자를 읽게 돕는 그림만 둡니다. 의존성 없는 SVG 에 색은 한 색(--uyoo-progress)입니다.
좋음 · 주의 · 한도는 색이 아니라 상태 아이콘과 글자가 말합니다. 축 · 격자 · 범례는 최소로 두고 값은 늘 글자로도 읽힙니다(요약 문장 · 표로 보기). 재질은 진행 막대와 같아 파인 홈 위에 채움을 얹습니다. 여러 계열 · 이중 축은 이 부품들의 범위 밖입니다(요청이 생기면 visx 로 ADR).
- import
- import { Sparkline, SparklineInteractive, BarList, Meter } from "@uyoolabs/ui/ui";
- 고르는 법
- 지금 값 하나 + 흐름 → Stat + Sparkline. 순위 · 무엇이 많은가 → BarList(긴 쪽 위, 길이로 견줌). 한도 대비 얼마나 썼나 → Meter(role=meter). 일이 얼마나 끝났나 → Progress · ProgressRing(진행 페이지).
- 쓰지 않는 경우
- 파이 · 도넛(각도는 길이보다 부정확합니다) · 조각 둘짜리 파이 · 막대 하나짜리 차트를 쓰지 않습니다. 무지개 색 · 그라데이션 채움 · 3D · 그늘진 막대를 쓰지 않습니다. 값을 그림으로만 말하지 않습니다. 상태를 채움 색으로 바꾸지 않습니다(결정 #45).
- 시각 · 숫자
- dates 는 앱이 UTC 시각을 보는 사람의 시간대로 바꾼 달력 날짜(YYYY-MM-DD)입니다. 숫자 서식은 lib/format 의 formatNumber(lang)입니다.
Sparkline
sm 64×20 · md 120×32 · 막대형. 끝 점에는 놓인 면 색의 2px 고리를 두릅니다. 포커스를 받지 않습니다.
| 키 | 동작 |
|---|---|
| Tab | 그림에 들어오면 마지막 점의 값 판을 띄운다(Tab 정지점 하나) |
| ←·→ | 이전 · 다음 점. 끝에서 멈춘다 |
| Home·End | 처음 · 마지막 점 |
| Esc | 값 판을 닫는다. 포커스는 그림에 남는다 |
| 포인터를 움직임 | 안내선이 가장 가까운 X 에 붙는다(누르는 자리는 그림 전체 폭) |
| BarList 링크 행 | Tab 으로 행 사이를 옮기고 Enter 로 그 주소로 간다. 링크 없는 행은 포커스를 받지 않는다 |
BarList
행마다 이름 · 파인 홈 8px 위 한 색 막대 · 값 + 비율. 그림이 아니라 글이 읽히고 막대는 aria-hidden 입니다.
비율은 행마다 반올림해 합이 100 이 안 될 수 있습니다. 고치지 않습니다.
Meter
한도 대비 사용량입니다. 채움은 늘 한 색이고, 한도에 가까움(warn) · 막힘(bad)은 아이콘 + 문장 + 글자색이 말합니다.
저장 공간62GB / 100GB
38GB 남았습니다.
멤버 좌석46석 / 50석
곧 한도에 닿습니다. 좌석을 늘리거나 멤버를 정리합니다.
props
소스의 타입과 JSDoc 에서 생성한 표입니다. 컴포넌트를 고치면 pnpm gen 으로 다시 만듭니다.
Sparkline
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| data필수 | readonly number[] | — | 2개 이상. 하나면 점 하나(한 점), 0개면 빈 상태 |
| size | "sm" | "md" | "sm" | sm 64×20(줄 안 · Stat 안) · md 120×32(카드 안) |
| variant | "line" | "bar" | "line" | line · bar(날마다 세는 값) |
| label필수 | string | — | 그림의 이름(무엇을 그렸나) — ‘최근 20일 메시지 수’. 요약 문장의 머리가 된다 |
| summary | string | — | 요약 문장을 앱이 직접 줄 때. 없으면 labels.summary 로 만든다 |
| formatValue | (v: number) => string | — | 요약 문장의 숫자 서식. 기본은 lib/format 의 formatNumber(lang) |
| dates | readonly string[] | — | 요약의 ‘가장 많은 날’ 에 쓰는 달력 날짜(YYYY-MM-DD). data 와 같은 순서 |
| loading | boolean | — | 뼈대 블록(크기 그대로). 300ms 지연은 감싼 SkeletonRegion 이 맡는다 |
| dot | boolean | true | 끝 점. 기본 true(line) |
| decorative | boolean | — | 장식으로 둔다(aria-hidden). 곁의 숫자가 이미 같은 것을 말할 때(Stat 안)만 쓴다. 이때도 label 은 준다 |
| lang | "ko" | "en" | "ja" | "ko" | |
| labels | Partial<SparklineLabels> | — | |
| className | string | — |
SparklineInteractive
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| data필수 | readonly number[] | — | 2개 이상. 하나면 점 하나(한 점), 0개면 빈 상태 |
| variant | "line" | "bar" | — | line · bar(날마다 세는 값) |
| label필수 | string | — | 그림의 이름(무엇을 그렸나) — ‘최근 20일 메시지 수’. 요약 문장의 머리가 된다 |
| summary | string | — | 요약 문장을 앱이 직접 줄 때. 없으면 labels.summary 로 만든다 |
| formatValue | (v: number) => string | — | 요약 문장의 숫자 서식. 기본은 lib/format 의 formatNumber(lang) |
| dates | readonly string[] | — | 요약의 ‘가장 많은 날’ 에 쓰는 달력 날짜(YYYY-MM-DD). data 와 같은 순서 |
| loading | boolean | — | 뼈대 블록(크기 그대로). 300ms 지연은 감싼 SkeletonRegion 이 맡는다 |
| dot | boolean | true | 끝 점. 기본 true(line) |
| lang | "ko" | "en" | "ja" | "ko" | |
| labels | Partial<SparklineLabels> | — | |
| className | string | — | |
| width | number | — | 그림 폭(px). 없으면 놓인 자리의 폭을 잰다(처음에는 260) |
| height | number | — | 그림 높이. 기본 64, 축을 켜면 170 |
| axis | boolean | false | y 눈금(0 · 1,000 · 2,000 처럼 깔끔한 값) · x 처음 · 가운데 · 끝 날짜 · 1px 격자 |
| endLabel | boolean | axis | 끝 값 하나를 직접 단다. 기본은 axis 와 같다 |
| activeIndex | number | null | — | 제어 — 값 판이 가리키는 점. null 이면 판이 닫힌다 |
| defaultActiveIndex | number | null | null | 비제어 첫 값 |
| onActiveIndexChange | (index: number | null) => void | — | 포인터 · 키보드 모두에서 불린다 |
| tableHref | string | — | ‘표로 보기’ 링크. 값 판이 유일한 통로가 되지 않게 같은 값을 표로 준다 |
| onShowTable | () => void | — | 링크 대신 표를 여는 동작 |
| refreshing | boolean | — | 다시 불러오는 동안 앞 그림을 그대로 두고 오른쪽 위 스피너 + aria-busy. 흐리게 하지 않는다 |
| heading | ReactNode | — | 머리 줄의 보이는 제목(카드 안 선 차트). 없으면 머리 줄은 ‘표로 보기’ 만 둔다 |
BarList
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| items필수 | readonly BarListItem[] | — | 받은 순서대로 그린다. 정렬은 앱이 한다(보통 큰 값이 위) |
| max | number | — | 막대 100% 의 기준. 기본은 가장 큰 값(비율이 아니라 길이 견주기) |
| limit | number | 8 | 이 개수를 넘으면 뒤를 ‘나머지 n개’ 한 행(합계)으로 합친다. 기본 8 |
| restHref | string | — | 나머지 행의 링크(전체 목록) |
| showShare | boolean | true | 비율 글자(12 muted). 기본 true — 합계 대비 % |
| total | number | — | 비율의 분모. 기본은 items 의 합 |
| formatValue | (v: number) => string | — | 기본 lib/format 의 formatNumber(lang) |
| current | string | — | 거르기에 쓰인 행의 key — 체크 + 600(막대 색은 그대로) |
| label필수 | string | — | 목록 이름(‘채널별 메시지 수’) → ul aria-label |
| loading | boolean | — | 뼈대 행 limit 개 |
| refreshing | boolean | — | 다시 불러오는 동안 앞 목록을 그대로 두고 aria-busy |
| lang | "ko" | "en" | "ja" | "ko" | |
| labels | Partial<BarListLabels> | — | |
| className | string | — |
Meter
| prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
| label필수 | ReactNode | — | ‘저장 공간’ — 미터의 이름이 된다 |
| value필수 | number | — | |
| max필수 | number | — | 0 이면 채움 0, 값 글자만 |
| valueLabel | ReactNode | — | 머리 줄 오른쪽 글자. 기본은 ‘62GB / 100GB’ |
| unit | string | — | ‘GB’ · ‘석’ · ‘건’ |
| valueText | string | — | aria-valuetext. 기본 labels.valueText(value, max, status) |
| status | "ok" | "warn" | "bad" | — | 기본은 thresholds 로 계산한다. bad 는 동작이 막혔을 때만 앱이 준다 |
| thresholds | { warn?: number } | — | status 를 고르는 기준. 기본 { warn: 0.9 } — bad 는 자동으로 고르지 않는다(막혔는지는 앱만 안다) |
| marks | readonly { value: number; label: string }[] | — | 홈을 가로지르는 기준선(무료 한도 등). 값은 value 와 같은 단위. 뜻은 valueLabel · 문장이 말한다 |
| message | ReactNode | — | 바닥 문장. warn · bad 면 앞에 아이콘이 붙는다. 무엇을 하면 되는지는 제품마다 달라 앱이 준다 |
| loading | boolean | — | |
| lang | "ko" | "en" | "ja" | "ko" | |
| labels | Partial<MeterLabels> | — | |
| className | string | — |