@iamfiro/design 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/AGENTS.md +81 -0
  2. package/README.md +15 -2
  3. package/agents/INDEX.md +156 -0
  4. package/agents/accordion/AGENTS.md +279 -0
  5. package/agents/action-bar/AGENTS.md +90 -0
  6. package/agents/alert/AGENTS.md +212 -0
  7. package/agents/alert-dialog/AGENTS.md +193 -0
  8. package/agents/app-shell/AGENTS.md +409 -0
  9. package/agents/area-chart/AGENTS.md +183 -0
  10. package/agents/aspect-ratio/AGENTS.md +143 -0
  11. package/agents/avatar/AGENTS.md +130 -0
  12. package/agents/badge/AGENTS.md +217 -0
  13. package/agents/bar-chart/AGENTS.md +386 -0
  14. package/agents/bar-list/AGENTS.md +223 -0
  15. package/agents/brand-icon/AGENTS.md +82 -0
  16. package/agents/breadcrumb/AGENTS.md +133 -0
  17. package/agents/button/AGENTS.md +195 -0
  18. package/agents/card/AGENTS.md +141 -0
  19. package/agents/card-frame/AGENTS.md +227 -0
  20. package/agents/chat-bubble/AGENTS.md +266 -0
  21. package/agents/chat-composer/AGENTS.md +251 -0
  22. package/agents/checkbox/AGENTS.md +113 -0
  23. package/agents/code-block/AGENTS.md +144 -0
  24. package/agents/color-dot/AGENTS.md +120 -0
  25. package/agents/color-picker/AGENTS.md +224 -0
  26. package/agents/colors/AGENTS.md +168 -0
  27. package/agents/combobox/AGENTS.md +218 -0
  28. package/agents/command-menu/AGENTS.md +169 -0
  29. package/agents/comment/AGENTS.md +206 -0
  30. package/agents/context-menu/AGENTS.md +303 -0
  31. package/agents/copy-button/AGENTS.md +84 -0
  32. package/agents/count-badge/AGENTS.md +115 -0
  33. package/agents/countdown/AGENTS.md +101 -0
  34. package/agents/data-grid/AGENTS.md +460 -0
  35. package/agents/date-picker/AGENTS.md +197 -0
  36. package/agents/delta/AGENTS.md +114 -0
  37. package/agents/description-list/AGENTS.md +251 -0
  38. package/agents/dialog/AGENTS.md +391 -0
  39. package/agents/drawer/AGENTS.md +471 -0
  40. package/agents/dropdown-menu/AGENTS.md +322 -0
  41. package/agents/dropzone/AGENTS.md +116 -0
  42. package/agents/elapsed/AGENTS.md +160 -0
  43. package/agents/empty-state/AGENTS.md +203 -0
  44. package/agents/file-chip/AGENTS.md +79 -0
  45. package/agents/file-icon/AGENTS.md +66 -0
  46. package/agents/file-upload/AGENTS.md +168 -0
  47. package/agents/filter-chips/AGENTS.md +167 -0
  48. package/agents/flag/AGENTS.md +67 -0
  49. package/agents/funnel-chart/AGENTS.md +131 -0
  50. package/agents/highlight/AGENTS.md +119 -0
  51. package/agents/hover-card/AGENTS.md +271 -0
  52. package/agents/icon-stack/AGENTS.md +120 -0
  53. package/agents/icon-tile/AGENTS.md +94 -0
  54. package/agents/inline-diff/AGENTS.md +211 -0
  55. package/agents/input/AGENTS.md +261 -0
  56. package/agents/kanban/AGENTS.md +352 -0
  57. package/agents/kbd/AGENTS.md +160 -0
  58. package/agents/layout/AGENTS.md +351 -0
  59. package/agents/line-chart/AGENTS.md +393 -0
  60. package/agents/link/AGENTS.md +53 -0
  61. package/agents/list/AGENTS.md +392 -0
  62. package/agents/marker/AGENTS.md +142 -0
  63. package/agents/masked-text/AGENTS.md +127 -0
  64. package/agents/menubar/AGENTS.md +276 -0
  65. package/agents/multi-select/AGENTS.md +159 -0
  66. package/agents/navigation-menu/AGENTS.md +315 -0
  67. package/agents/notice-stack/AGENTS.md +101 -0
  68. package/agents/number-stepper/AGENTS.md +96 -0
  69. package/agents/otp-input/AGENTS.md +162 -0
  70. package/agents/pagination/AGENTS.md +189 -0
  71. package/agents/phone-input/AGENTS.md +131 -0
  72. package/agents/pie-chart/AGENTS.md +243 -0
  73. package/agents/popover/AGENTS.md +190 -0
  74. package/agents/progress/AGENTS.md +273 -0
  75. package/agents/progress-tracker/AGENTS.md +305 -0
  76. package/agents/rating/AGENTS.md +165 -0
  77. package/agents/relative-time/AGENTS.md +103 -0
  78. package/agents/resizable/AGENTS.md +390 -0
  79. package/agents/scaled-preview/AGENTS.md +111 -0
  80. package/agents/scatter-chart/AGENTS.md +160 -0
  81. package/agents/scroll-area/AGENTS.md +271 -0
  82. package/agents/search-input/AGENTS.md +105 -0
  83. package/agents/segmented-control/AGENTS.md +153 -0
  84. package/agents/select/AGENTS.md +159 -0
  85. package/agents/selector-button/AGENTS.md +122 -0
  86. package/agents/sidebar/AGENTS.md +201 -0
  87. package/agents/skeleton/AGENTS.md +166 -0
  88. package/agents/slider/AGENTS.md +181 -0
  89. package/agents/spark-chart/AGENTS.md +257 -0
  90. package/agents/sparkbar/AGENTS.md +92 -0
  91. package/agents/spinner/AGENTS.md +123 -0
  92. package/agents/split-view/AGENTS.md +290 -0
  93. package/agents/stat/AGENTS.md +138 -0
  94. package/agents/status-icon/AGENTS.md +243 -0
  95. package/agents/step-list/AGENTS.md +313 -0
  96. package/agents/table/AGENTS.md +286 -0
  97. package/agents/tabs/AGENTS.md +305 -0
  98. package/agents/tag-input/AGENTS.md +246 -0
  99. package/agents/time-picker/AGENTS.md +228 -0
  100. package/agents/timeline/AGENTS.md +1018 -0
  101. package/agents/toast/AGENTS.md +266 -0
  102. package/agents/toggle-group/AGENTS.md +216 -0
  103. package/agents/toolbar/AGENTS.md +277 -0
  104. package/agents/tooltip/AGENTS.md +154 -0
  105. package/agents/tracker/AGENTS.md +158 -0
  106. package/agents/tree-diagram/AGENTS.md +260 -0
  107. package/agents/tree-view/AGENTS.md +329 -0
  108. package/agents/typography/AGENTS.md +396 -0
  109. package/lib/index.js +17914 -0
  110. package/lib/style.css +2 -0
  111. package/lib/types/components/Accordion/Accordion.d.ts +57 -0
  112. package/lib/types/components/ActionBar/ActionBar.d.ts +24 -0
  113. package/lib/types/components/Alert/Alert.d.ts +36 -0
  114. package/lib/types/components/AppShell/AppShell.d.ts +38 -0
  115. package/lib/types/components/AreaChart/AreaChart.d.ts +17 -0
  116. package/lib/types/components/BarChart/BarChart.d.ts +57 -0
  117. package/lib/types/components/BarList/BarList.d.ts +56 -0
  118. package/lib/types/components/Breadcrumb/Breadcrumb.d.ts +15 -0
  119. package/lib/types/components/Calendar/Calendar.d.ts +34 -0
  120. package/lib/types/components/Calendar/DatePicker.d.ts +45 -0
  121. package/lib/types/components/Calendar/date.d.ts +32 -0
  122. package/lib/types/components/Card/Card.d.ts +64 -0
  123. package/lib/types/components/CardFrame/CardFrame.d.ts +15 -0
  124. package/lib/types/components/Chart/ChartParts.d.ts +38 -0
  125. package/lib/types/components/Chart/chart.d.ts +46 -0
  126. package/lib/types/components/Chart/useChartInteraction.d.ts +39 -0
  127. package/lib/types/components/ChatBubble/ChatBubble.d.ts +61 -0
  128. package/lib/types/components/ChatBubble/formatChatTime.d.ts +2 -0
  129. package/lib/types/components/ChatComposer/ChatComposer.d.ts +42 -0
  130. package/lib/types/components/CodeBlock/CodeBlock.d.ts +18 -0
  131. package/lib/types/components/CodeBlock/highlight.d.ts +10 -0
  132. package/lib/types/components/ColorPicker/ColorPicker.d.ts +61 -0
  133. package/lib/types/components/ColorPicker/color.d.ts +48 -0
  134. package/lib/types/components/ColorPicker/presets.d.ts +7 -0
  135. package/lib/types/components/Combobox/Combobox.d.ts +48 -0
  136. package/lib/types/components/CommandMenu/CommandMenu.d.ts +51 -0
  137. package/lib/types/components/Comment/Comment.d.ts +45 -0
  138. package/lib/types/components/ContextMenu/ContextMenu.d.ts +40 -0
  139. package/lib/types/components/DataGrid/DataGrid.d.ts +43 -0
  140. package/lib/types/components/DataGrid/GridPopover.d.ts +43 -0
  141. package/lib/types/components/DataGrid/anchor.d.ts +5 -0
  142. package/lib/types/components/DataGrid/model.d.ts +61 -0
  143. package/lib/types/components/DataGrid/panels.d.ts +63 -0
  144. package/lib/types/components/DataGrid/typeMeta.d.ts +6 -0
  145. package/lib/types/components/DataGrid/types.d.ts +77 -0
  146. package/lib/types/components/DescriptionList/DescriptionList.d.ts +77 -0
  147. package/lib/types/components/Dialog/AlertDialog.d.ts +26 -0
  148. package/lib/types/components/Dialog/Dialog.d.ts +42 -0
  149. package/lib/types/components/Dialog/modal.d.ts +38 -0
  150. package/lib/types/components/Drawer/Drawer.d.ts +62 -0
  151. package/lib/types/components/DropdownMenu/DropdownMenu.d.ts +97 -0
  152. package/lib/types/components/DropdownMenu/menuCore.d.ts +23 -0
  153. package/lib/types/components/Dropzone/Dropzone.d.ts +30 -0
  154. package/lib/types/components/EmptyState/EmptyState.d.ts +26 -0
  155. package/lib/types/components/FileChip/FileChip.d.ts +32 -0
  156. package/lib/types/components/FileUpload/FileUpload.d.ts +52 -0
  157. package/lib/types/components/FilterChips/FilterChips.d.ts +37 -0
  158. package/lib/types/components/FunnelChart/FunnelChart.d.ts +38 -0
  159. package/lib/types/components/FunnelChart/funnel.d.ts +25 -0
  160. package/lib/types/components/Highlight/Highlight.d.ts +35 -0
  161. package/lib/types/components/HoverCard/HoverCard.d.ts +47 -0
  162. package/lib/types/components/InlineDiff/InlineDiff.d.ts +36 -0
  163. package/lib/types/components/InlineDiff/diff.d.ts +42 -0
  164. package/lib/types/components/InlineDiff/useDiffReview.d.ts +57 -0
  165. package/lib/types/components/Kanban/Kanban.d.ts +64 -0
  166. package/lib/types/components/Kanban/KanbanCard.d.ts +35 -0
  167. package/lib/types/components/Kanban/move.d.ts +25 -0
  168. package/lib/types/components/LineChart/LineChart.d.ts +85 -0
  169. package/lib/types/components/List/List.d.ts +62 -0
  170. package/lib/types/components/Listbox/Listbox.d.ts +60 -0
  171. package/lib/types/components/Marker/Marker.d.ts +28 -0
  172. package/lib/types/components/Menubar/Menubar.d.ts +50 -0
  173. package/lib/types/components/MultiSelect/MultiSelect.d.ts +38 -0
  174. package/lib/types/components/NavigationMenu/NavigationMenu.d.ts +101 -0
  175. package/lib/types/components/NoticeStack/NoticeStack.d.ts +41 -0
  176. package/lib/types/components/NumberStepper/NumberStepper.d.ts +32 -0
  177. package/lib/types/components/OtpInput/OtpInput.d.ts +31 -0
  178. package/lib/types/components/Pagination/Pagination.d.ts +54 -0
  179. package/lib/types/components/Pagination/paginationRange.d.ts +7 -0
  180. package/lib/types/components/PhoneInput/PhoneInput.d.ts +47 -0
  181. package/lib/types/components/PieChart/PieChart.d.ts +67 -0
  182. package/lib/types/components/PieChart/arc.d.ts +26 -0
  183. package/lib/types/components/PieChart/useArcTween.d.ts +15 -0
  184. package/lib/types/components/Popover/Popover.d.ts +28 -0
  185. package/lib/types/components/ProgressTracker/ProgressTracker.d.ts +64 -0
  186. package/lib/types/components/Rating/Rating.d.ts +42 -0
  187. package/lib/types/components/Resizable/Resizable.d.ts +50 -0
  188. package/lib/types/components/Resizable/layout.d.ts +31 -0
  189. package/lib/types/components/ScaledPreview/ScaledPreview.d.ts +38 -0
  190. package/lib/types/components/ScatterChart/ScatterChart.d.ts +81 -0
  191. package/lib/types/components/ScatterChart/scatter.d.ts +14 -0
  192. package/lib/types/components/ScrollArea/ScrollArea.d.ts +34 -0
  193. package/lib/types/components/Select/Select.d.ts +39 -0
  194. package/lib/types/components/Sidebar/Sidebar.d.ts +39 -0
  195. package/lib/types/components/Skeleton/Skeleton.d.ts +47 -0
  196. package/lib/types/components/Slider/Slider.d.ts +36 -0
  197. package/lib/types/components/SparkChart/SparkChart.d.ts +55 -0
  198. package/lib/types/components/SparkChart/spark.d.ts +16 -0
  199. package/lib/types/components/Sparkbar/Sparkbar.d.ts +39 -0
  200. package/lib/types/components/SplitView/SplitView.d.ts +31 -0
  201. package/lib/types/components/Stat/Stat.d.ts +58 -0
  202. package/lib/types/components/StepList/StepList.d.ts +61 -0
  203. package/lib/types/components/Table/Table.d.ts +39 -0
  204. package/lib/types/components/Tabs/Tabs.d.ts +47 -0
  205. package/lib/types/components/TagInput/TagInput.d.ts +46 -0
  206. package/lib/types/components/TimePicker/TimePicker.d.ts +43 -0
  207. package/lib/types/components/TimePicker/time.d.ts +15 -0
  208. package/lib/types/components/Timeline/Timeline.d.ts +154 -0
  209. package/lib/types/components/Timeline/scale.d.ts +22 -0
  210. package/lib/types/components/Toast/Toaster.d.ts +19 -0
  211. package/lib/types/components/Toast/index.d.ts +4 -0
  212. package/lib/types/components/Toast/store.d.ts +75 -0
  213. package/lib/types/components/ToggleGroup/ToggleGroup.d.ts +28 -0
  214. package/lib/types/components/Toolbar/Toolbar.d.ts +70 -0
  215. package/lib/types/components/Tracker/Tracker.d.ts +43 -0
  216. package/lib/types/components/TreeDiagram/TreeDiagram.d.ts +68 -0
  217. package/lib/types/components/TreeView/TreeView.d.ts +107 -0
  218. package/lib/types/components/index.d.ts +186 -0
  219. package/lib/types/hooks/index.d.ts +17 -0
  220. package/lib/types/hooks/timing.d.ts +29 -0
  221. package/lib/types/hooks/useControllableState.d.ts +5 -0
  222. package/lib/types/hooks/useCountdown.d.ts +19 -0
  223. package/lib/types/hooks/useDigitInput.d.ts +24 -0
  224. package/lib/types/hooks/useDismiss.d.ts +3 -0
  225. package/lib/types/hooks/useElapsed.d.ts +28 -0
  226. package/lib/types/hooks/useFloating.d.ts +21 -0
  227. package/lib/types/hooks/useFocusTrap.d.ts +7 -0
  228. package/lib/types/hooks/usePresence.d.ts +8 -0
  229. package/lib/types/hooks/usePressToOpen.d.ts +20 -0
  230. package/lib/types/hooks/useScrollLock.d.ts +2 -0
  231. package/lib/types/hooks/useSelection.d.ts +29 -0
  232. package/lib/types/index.d.ts +5 -0
  233. package/lib/types/primitives/AspectRatio.d.ts +14 -0
  234. package/lib/types/primitives/BrandIcon.d.ts +12 -0
  235. package/lib/types/primitives/ColorDot.d.ts +20 -0
  236. package/lib/types/primitives/CopyButton.d.ts +12 -0
  237. package/lib/types/primitives/CountBadge.d.ts +28 -0
  238. package/lib/types/primitives/Countdown.d.ts +21 -0
  239. package/lib/types/primitives/Delta.d.ts +33 -0
  240. package/lib/types/primitives/Elapsed.d.ts +23 -0
  241. package/lib/types/primitives/FileIcon.d.ts +17 -0
  242. package/lib/types/primitives/Flag.d.ts +15 -0
  243. package/lib/types/primitives/IconStack.d.ts +27 -0
  244. package/lib/types/primitives/IconTile.d.ts +24 -0
  245. package/lib/types/primitives/Kbd.d.ts +19 -0
  246. package/lib/types/primitives/Layout.d.ts +64 -0
  247. package/lib/types/primitives/Link.d.ts +12 -0
  248. package/lib/types/primitives/MaskedText.d.ts +28 -0
  249. package/lib/types/primitives/Progress.d.ts +52 -0
  250. package/lib/types/primitives/RelativeTime.d.ts +22 -0
  251. package/lib/types/primitives/SearchInput.d.ts +8 -0
  252. package/lib/types/primitives/SelectorButton.d.ts +23 -0
  253. package/lib/types/primitives/Spinner.d.ts +15 -0
  254. package/lib/types/primitives/StatusIcon.d.ts +40 -0
  255. package/lib/types/primitives/Swatch.d.ts +11 -0
  256. package/lib/types/primitives/Tooltip.d.ts +17 -0
  257. package/lib/types/primitives/Typography.d.ts +48 -0
  258. package/lib/types/primitives/formatCountdown.d.ts +2 -0
  259. package/lib/types/primitives/formatElapsed.d.ts +8 -0
  260. package/lib/types/primitives/formatRelativeTime.d.ts +16 -0
  261. package/lib/types/primitives/hotkey.d.ts +10 -0
  262. package/lib/types/primitives/index.d.ts +188 -0
  263. package/lib/types/primitives/maskValue.d.ts +24 -0
  264. package/package.json +54 -4
@@ -0,0 +1,114 @@
1
+ # Delta
2
+
3
+ > 데이터 표시 · `@iamfiro/design` · 직접 만들지 말고 이 컴포넌트를 쓴다.
4
+
5
+ 이전 · 목표와 비교한 증감을 부호와 함께 보여 줘요. 더 큰 값이 좋은지 나쁜지(higherIs)에 따라 초록 · 주황이 정해지고, 0은 회색이에요. 빼기는 하이픈이 아닌 진짜 마이너스(−)를 쓰고 숫자는 tabular라 세로로 줄이 맞아요.
6
+
7
+ ```tsx
8
+ import { Delta } from '@iamfiro/design'
9
+ ```
10
+
11
+ ## 디자인 규칙
12
+
13
+ - 표 칸 · KPI 카드의 작은 추이는 `SparkLine` · `SparkArea` · `Sparkbar`(같은 props, 하나로 고르면 `SparkChart type`). 축 없음, 실제 픽셀 크기로 그려 24–40px에서도 또렷하게, 값 범위는 0이 아니라 최솟값–최댓값. 색은 `tone="trend"` + `higherIs`(Delta와 같은 규칙), 마지막 값은 `endDot`. 긴 표에선 `tooltip={false}`로 이벤트 없는 정적 그림(`role="img"`). KPI 카드는 Card 안 `Stat` + `Delta` + `SparkArea`.
14
+ - 증감은 `Delta`: 진짜 마이너스(−), tabular 숫자, 좋고 나쁨은 부호가 아니라 `higherIs`로 정한다(시간 · 비용 · 오류는 `worse`). 0은 회색.
15
+
16
+ ## API
17
+
18
+ ### Delta
19
+
20
+ | prop | 타입 | 기본값 | 설명 |
21
+ | --- | --- | --- | --- |
22
+ | `value` (필수) | `number` | | 부호가 있는 증감 값. 0은 중립(회색, 부호 없음). |
23
+ | `format` | `(absolute: number) => ReactNode` | `ko-KR 숫자` | 절댓값을 보여 줄 형식. 부호는 자동으로 붙어요. |
24
+ | `suffix` | `ReactNode` | | 숫자 뒤 글자("늦음", "지난주 대비"). |
25
+ | `higherIs` | `'better' \| 'worse' \| 'neutral'` | `'better'` | 값이 커지는 것의 의미. neutral이면 늘 회색. |
26
+ | `worseTone` | `'warning' \| 'danger'` | `'warning'` | 나빠졌을 때 색. 위험한 지표는 danger. |
27
+ | `arrow` | `boolean` | | 숫자 앞 위/아래 화살표. |
28
+ | `variant` | `'soft' \| 'text'` | `'soft'` | soft: 연한 배지 · text: 색 글자만. |
29
+ | `size` | `'sm' \| 'md'` | `'md'` | 크기. |
30
+ | `aria-label` | `string` | | 보이는 글자 대신 읽을 문장. |
31
+
32
+ ## 예제
33
+
34
+ 예제를 감싼 `style={{ ... }}` div는 미리보기 배치용이다. 실제 화면 배치는 `Stack` · `Inline` · `Grid`로 한다.
35
+
36
+ ### 좋아짐 · 나빠짐
37
+
38
+ 매출처럼 클수록 좋은 값은 higherIs="better"(기본), 소요 시간 · 비용처럼 작을수록 좋은 값은 "worse".
39
+
40
+ ```tsx
41
+ import { Fragment } from 'react'
42
+ import { Delta, Grid, Text } from '@iamfiro/design'
43
+
44
+ const ROWS = [
45
+ { label: '주간 가입자', value: 128, higherIs: 'better' as const },
46
+ { label: '주간 가입자', value: -36, higherIs: 'better' as const },
47
+ { label: '평균 빌드 시간', value: 12, higherIs: 'worse' as const },
48
+ { label: '평균 빌드 시간', value: -4, higherIs: 'worse' as const },
49
+ { label: '열린 이슈', value: 0, higherIs: 'worse' as const },
50
+ ]
51
+
52
+ export default function Example() {
53
+ return (
54
+ <Grid columns="auto auto auto" gap={6} rowGap={3} align="center" style={{ justifyContent: 'start' }}>
55
+ {ROWS.map((r, i) => (
56
+ <Fragment key={i}>
57
+ <Text variant="label-sm" tone="secondary">
58
+ {r.label}
59
+ </Text>
60
+ <Text variant="code">{`higherIs="${r.higherIs}"`}</Text>
61
+ <Delta value={r.value} higherIs={r.higherIs} />
62
+ </Fragment>
63
+ ))}
64
+ </Grid>
65
+ )
66
+ }
67
+ ```
68
+
69
+ ### 형식 · 화살표
70
+
71
+ format은 부호를 뺀 절댓값을 받아요. 단위 · 소수점 · 통화는 여기서, 부호는 Delta가 붙여요.
72
+
73
+ ```tsx
74
+ import { Delta, Inline } from '@iamfiro/design'
75
+
76
+ const won = new Intl.NumberFormat('ko-KR', { style: 'currency', currency: 'KRW' })
77
+
78
+ export default function Example() {
79
+ return (
80
+ <Inline gap={3}>
81
+ <Delta value={12} higherIs="worse" format={(n) => `${n}초`} />
82
+ <Delta value={-4} higherIs="worse" format={(n) => `${n}초`} />
83
+ <Delta value={0.042} format={(n) => `${(n * 100).toFixed(1)}%`} arrow />
84
+ <Delta value={-0.018} format={(n) => `${(n * 100).toFixed(1)}%`} arrow />
85
+ <Delta value={2300} higherIs="worse" format={(n) => won.format(n)} worseTone="danger" arrow />
86
+ <Delta value={3} higherIs="worse" format={(n) => `${n}건`} size="sm" />
87
+ </Inline>
88
+ )
89
+ }
90
+ ```
91
+
92
+ ### 글자형
93
+
94
+ variant="text"는 배경 없이 색 글자만. 제목줄 · 문장 안에 넣을 때 써요.
95
+
96
+ ```tsx
97
+ import { Delta, Heading, Inline, Stack, Text } from '@iamfiro/design'
98
+
99
+ export default function Example() {
100
+ return (
101
+ <Stack gap={4}>
102
+ <Inline gap={3} align="baseline">
103
+ <Heading level={3}>10월 정기 배포</Heading>
104
+ <Delta variant="text" value={23} higherIs="worse" format={(n) => `${n}초`} suffix="늦음" />
105
+ </Inline>
106
+ <Text variant="body-sm" tone="secondary">
107
+ 이번 주 응답 시간은 평균 182ms로{' '}
108
+ <Delta variant="text" value={-14} higherIs="worse" format={(n) => `${n}ms`} arrow /> 줄었고, 오류율은{' '}
109
+ <Delta variant="text" value={0} format={(n) => `${n}%p`} /> 그대로예요.
110
+ </Text>
111
+ </Stack>
112
+ )
113
+ }
114
+ ```
@@ -0,0 +1,251 @@
1
+ # DescriptionList
2
+
3
+ > 데이터 표시 · `@iamfiro/design` · 직접 만들지 말고 이 컴포넌트를 쓴다.
4
+
5
+ 라벨 · 값 쌍을 진짜 <dl>로 보여 줘요. 라벨(오버라인 또는 옅은 캡션) 아래 값을 columns 칸 격자로 놓거나, 한 줄에 라벨 왼쪽 · 값 오른쪽으로 놓아요. soft는 상세 팝오버 안의 옅은 회색 패널(모서리 12, 촘촘한 여백)이에요. DescriptionSection은 격자 아래 "입력 / 결과" 같은 오버라인 제목 + 본문 블록이에요. 모두 Box · Grid · Stack · Text 조립이고, 값 크기는 Stat과 같은 숫자 역할을 써요.
6
+
7
+ ```tsx
8
+ import { DescriptionItem, DescriptionList, DescriptionSection } from '@iamfiro/design'
9
+ ```
10
+
11
+ ## 디자인 규칙
12
+
13
+ - 라벨 · 값 쌍(상세 팝오버, 결제 정보)은 `DescriptionList`(`<dl>`, `columns` 격자 또는 `layout="inline"` 행, `variant="soft"` 회색 패널, `labelStyle="overline" | "muted"`). "입력 / 결과" 같은 제목 + 본문은 `DescriptionSection`.
14
+
15
+ ## API
16
+
17
+ ### DescriptionList
18
+
19
+ | prop | 타입 | 기본값 | 설명 |
20
+ | --- | --- | --- | --- |
21
+ | `items` | `DescriptionListItem[]` | | { id?, label, value, icon?, tone?, span? } 목록. 또는 children. |
22
+ | `children` | `ReactNode` | | <DescriptionItem>들. |
23
+ | `layout` | `'stacked' \| 'inline'` | `'stacked'` | 라벨 위 값 격자 / 한 줄 행(라벨 왼쪽, 값 오른쪽). |
24
+ | `columns` | `number \| string` | `stacked 3 · inline 1` | 칸 수 또는 grid-template-columns 문자열. |
25
+ | `minItemWidth` | `number` | | 반응형: 이 폭(px) 이상인 칸을 들어가는 만큼. columns보다 우선. |
26
+ | `variant` | `'plain' \| 'soft'` | `'plain'` | soft: 회색 패널(--surface-active, 모서리 12, 여백 12). |
27
+ | `labelStyle` | `'overline' \| 'muted'` | `'overline'` | 오버라인 라벨 / 옅은 캡션 라벨. |
28
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 값 크기. stacked는 number-sm · md · lg, inline은 label-sm · md · lg. |
29
+ | `align` | `'end' \| 'start'` | `'end'` | inline 행만. end: 값을 행 오른쪽 끝에 · start: 값을 가장 긴 라벨 뒤 한 열에 맞춰 왼쪽 정렬(받는 사람 / 제목 / 첨부). |
30
+ | `gap` | `Space` | `stacked 4 · inline 6` | 칸 사이 간격. |
31
+ | `rowGap` | `Space` | `stacked 4 · inline 2` | 줄 사이 간격. |
32
+ | `aria-label` | `string` | | 목록 이름("배포 정보"). |
33
+
34
+ ### DescriptionItem
35
+
36
+ | prop | 타입 | 기본값 | 설명 |
37
+ | --- | --- | --- | --- |
38
+ | `label` (필수) | `ReactNode` | | 라벨(<dt>). |
39
+ | `icon` | `ReactNode` | | 라벨 앞 아이콘. 라벨과 같은 옅은 색, inline 16px · stacked 14px. |
40
+ | `children` (필수) | `ReactNode` | | 값(<dd>). |
41
+ | `tone` | `TextTone` | `'default'` | 값 색. 오류는 danger. |
42
+ | `span` | `number` | | 차지할 칸 수. |
43
+
44
+ ### DescriptionSection
45
+
46
+ | prop | 타입 | 기본값 | 설명 |
47
+ | --- | --- | --- | --- |
48
+ | `title` (필수) | `ReactNode` | | 오버라인 제목("입력"). |
49
+ | `children` (필수) | `ReactNode` | | 본문(body-sm, secondary). |
50
+
51
+ ## 예제
52
+
53
+ 예제를 감싼 `style={{ ... }}` div는 미리보기 배치용이다. 실제 화면 배치는 `Stack` · `Inline` · `Grid`로 한다.
54
+
55
+ ### 배포 상세 (soft + 섹션)
56
+
57
+ variant="soft"는 회색 패널 안의 3칸 격자. 아래 DescriptionSection으로 입력 · 결과를 붙여요. tone="danger"로 "1 오류"처럼 값 색을 바꿔요.
58
+
59
+ ```tsx
60
+ import { Badge, Stack, Card, CardBody, CardHeader, DescriptionList, DescriptionSection } from '@iamfiro/design'
61
+
62
+ export default function Example() {
63
+ return (
64
+ <Card variant="raised" style={{ width: '100%', maxWidth: 400 }}>
65
+ <CardHeader title="결제 페이지 배포" description="프로덕션 · 이도현" actions={<Badge tone="success">완료</Badge>} />
66
+ <CardBody>
67
+ <Stack gap={4}>
68
+ <DescriptionList
69
+ variant="soft"
70
+ columns={3}
71
+ aria-label="배포 지표"
72
+ items={[
73
+ { label: '소요 시간', value: '37초' },
74
+ { label: '시작', value: '+11초' },
75
+ { label: '비용', value: '₩1,200' },
76
+ { label: '변경 줄', value: '9.8k' },
77
+ { label: '테스트', value: '412' },
78
+ { label: '오류', value: '1', tone: 'danger' },
79
+ ]}
80
+ />
81
+ <DescriptionSection title="입력">요금제 세 가지의 결제 문구를 새로 반영</DescriptionSection>
82
+ <DescriptionSection title="결과">무료 · 프로 · 팀 문구 반영, 쿠폰 처리 테스트 1건 재시도</DescriptionSection>
83
+ </Stack>
84
+ </CardBody>
85
+ </Card>
86
+ )
87
+ }
88
+ ```
89
+
90
+ ### 결제 정보 (옅은 라벨)
91
+
92
+ labelStyle="muted"는 대문자 느낌 없이 조용한 캡션 라벨, size="sm"은 14px 값이에요. 값 자리에는 MaskedText · Highlight 같은 어떤 요소든 넣을 수 있어요.
93
+
94
+ ```tsx
95
+ import { MaskedText, DescriptionList } from '@iamfiro/design'
96
+
97
+ export default function Example() {
98
+ return (
99
+ <DescriptionList
100
+ labelStyle="muted"
101
+ size="sm"
102
+ columns="repeat(3, max-content)"
103
+ gap={8}
104
+ aria-label="송금 정보"
105
+ items={[
106
+ { label: '금액', value: '₩12,480,000' },
107
+ { label: '지급일', value: '10월 24일' },
108
+ { label: '계좌', value: <MaskedText label="계좌" value="110-482-301193" visibleEnd={4} visibleStart={3} /> },
109
+ ]}
110
+ />
111
+ )
112
+ }
113
+ ```
114
+
115
+ ### 상세 정보 (앞 아이콘)
116
+
117
+ item마다 icon을 주면 라벨 앞에 옅은 16px 아이콘이 붙어요(라벨과 같은 색, 라벨이 길어져도 찌그러지지 않음). 값은 행 오른쪽 끝에 맞춰요.
118
+
119
+ ```tsx
120
+ import { Banknote, Hash, User, Users } from 'lucide-react'
121
+ import { Avatar, Inline, Card, CardBody, CardHeader, DescriptionList } from '@iamfiro/design'
122
+
123
+ export default function Example() {
124
+ return (
125
+ <Card padding="sm" style={{ width: '100%', maxWidth: 340 }}>
126
+ <CardHeader title="상세 정보" />
127
+ <CardBody>
128
+ <DescriptionList
129
+ layout="inline"
130
+ labelStyle="muted"
131
+ aria-label="상세 정보"
132
+ items={[
133
+ {
134
+ label: '요청자',
135
+ icon: <User />,
136
+ value: (
137
+ <Inline gap={2} justify="end" wrap={false}>
138
+ <Avatar name="김민지" size={20} />
139
+ 김민지
140
+ </Inline>
141
+ ),
142
+ },
143
+ { label: '담당 팀', icon: <Users />, value: '재무기획팀' },
144
+ { label: '처리 건수', icon: <Hash />, value: '12건' },
145
+ { label: '비용', icon: <Banknote />, value: '₩42,000' },
146
+ ]}
147
+ />
148
+ </CardBody>
149
+ </Card>
150
+ )
151
+ }
152
+ ```
153
+
154
+ ### 승인 카드 (회색 패널 + 왼쪽 정렬)
155
+
156
+ align="start"면 값이 가장 긴 라벨 바로 뒤 한 열에 줄지어 서요. variant="soft"와 함께 카드 안의 옅은 회색 패널로 받는 사람 · 제목 · 첨부를 보여 줘요.
157
+
158
+ ```tsx
159
+ import { Mail } from 'lucide-react'
160
+ import { Button, IconTile, Card, CardBody, CardFooter, CardHeader, DescriptionItem, DescriptionList, FileChip, toast } from '@iamfiro/design'
161
+
162
+ export default function Example() {
163
+ return (
164
+ <Card padding="sm" style={{ width: '100%', maxWidth: 400 }}>
165
+ <CardHeader
166
+ icon={
167
+ <IconTile>
168
+ <Mail />
169
+ </IconTile>
170
+ }
171
+ title="메일 발송 승인"
172
+ description="계약 변경 안내를 보내기 전에 확인해 주세요."
173
+ />
174
+ <CardBody>
175
+ <DescriptionList layout="inline" align="start" variant="soft" labelStyle="muted" size="sm" aria-label="보낼 메일">
176
+ <DescriptionItem label="받는 사람">박서준 (한빛물류)</DescriptionItem>
177
+ <DescriptionItem label="제목">공급 계약 제3조 변경 안내</DescriptionItem>
178
+ <DescriptionItem label="첨부">
179
+ <FileChip name="공급계약_변경안_v2.pdf" size={182_000} icon="clip" variant="ghost" onClick={() => toast('공급계약_변경안_v2.pdf 미리보기를 열었어요')} />
180
+ </DescriptionItem>
181
+ </DescriptionList>
182
+ </CardBody>
183
+ <CardFooter>
184
+ <Button size="sm" variant="secondary" onClick={() => toast('발송을 거절했어요')}>
185
+ 거절
186
+ </Button>
187
+ <Button size="sm" variant="primary" onClick={() => toast.success('메일을 보냈어요')}>
188
+ 보내기
189
+ </Button>
190
+ </CardFooter>
191
+ </Card>
192
+ )
193
+ }
194
+ ```
195
+
196
+ ### 한 줄 행
197
+
198
+ layout="inline": 라벨 왼쪽 · 값 오른쪽. 영수증 · 요약 카드처럼 좁은 곳에 써요. 행 사이는 선 없이 간격이에요.
199
+
200
+ ```tsx
201
+ import { Card, CardBody, DescriptionList } from '@iamfiro/design'
202
+
203
+ export default function Example() {
204
+ return (
205
+ <Card style={{ width: '100%', maxWidth: 320 }}>
206
+ <CardBody>
207
+ <DescriptionList
208
+ layout="inline"
209
+ labelStyle="muted"
210
+ aria-label="청구서 INV-2207"
211
+ items={[
212
+ { label: '청구서', value: 'INV-2207' },
213
+ { label: '거래처', value: '한빛물류' },
214
+ { label: '공급가액', value: '₩11,345,455' },
215
+ { label: '부가세', value: '₩1,134,545' },
216
+ { label: '미납', value: '1건', tone: 'danger' },
217
+ ]}
218
+ />
219
+ </CardBody>
220
+ </Card>
221
+ )
222
+ }
223
+ ```
224
+
225
+ ### children으로
226
+
227
+ items 대신 <DescriptionItem>을 직접 넣어요. span으로 여러 칸을 차지하고, minItemWidth면 폭에 맞춰 칸 수가 바뀌어요.
228
+
229
+ ```tsx
230
+ import { Avatar, Inline, Text, DescriptionItem, DescriptionList } from '@iamfiro/design'
231
+
232
+ export default function Example() {
233
+ return (
234
+ <DescriptionList minItemWidth={140} size="sm" aria-label="계정 정보" style={{ width: '100%' }}>
235
+ <DescriptionItem label="담당자">
236
+ <Inline gap={2} wrap={false}>
237
+ <Avatar name="김민지" size={20} />
238
+ 김민지
239
+ </Inline>
240
+ </DescriptionItem>
241
+ <DescriptionItem label="요금제">팀 · 연간</DescriptionItem>
242
+ <DescriptionItem label="다음 결제">11월 1일</DescriptionItem>
243
+ <DescriptionItem label="메모" span={2}>
244
+ <Text variant="body-sm" tone="secondary">
245
+ 이도현 님이 10월 25일에 좌석 3개를 추가했어요.
246
+ </Text>
247
+ </DescriptionItem>
248
+ </DescriptionList>
249
+ )
250
+ }
251
+ ```