@hjmds/design-contracts 1.12.1 โ†’ 1.13.1

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 (288) hide show
  1. package/dist/avatar-fallback.d.ts +11 -0
  2. package/dist/avatar-fallback.d.ts.map +1 -1
  3. package/dist/avatar-fallback.js +21 -0
  4. package/dist/avatar-fallback.js.map +1 -1
  5. package/dist/base-recipes.d.ts +17 -0
  6. package/dist/base-recipes.d.ts.map +1 -1
  7. package/dist/base-recipes.js +17 -0
  8. package/dist/base-recipes.js.map +1 -1
  9. package/dist/catalog.d.ts +26 -0
  10. package/dist/catalog.d.ts.map +1 -1
  11. package/dist/command-palette.d.ts +14 -9
  12. package/dist/command-palette.d.ts.map +1 -1
  13. package/dist/command-palette.js +8 -9
  14. package/dist/command-palette.js.map +1 -1
  15. package/dist/component-recipes.d.ts +31 -0
  16. package/dist/component-recipes.d.ts.map +1 -1
  17. package/dist/component-recipes.js +20 -0
  18. package/dist/component-recipes.js.map +1 -1
  19. package/dist/provider-button.d.ts.map +1 -1
  20. package/dist/provider-button.js +3 -0
  21. package/dist/provider-button.js.map +1 -1
  22. package/dist/reactions.d.ts +10 -0
  23. package/dist/reactions.d.ts.map +1 -1
  24. package/dist/reactions.js +7 -0
  25. package/dist/reactions.js.map +1 -1
  26. package/dist/screen-patterns.d.ts +147 -0
  27. package/dist/screen-patterns.d.ts.map +1 -0
  28. package/dist/screen-patterns.js +149 -0
  29. package/dist/screen-patterns.js.map +1 -0
  30. package/dist/slider.d.ts +8 -0
  31. package/dist/slider.d.ts.map +1 -1
  32. package/dist/slider.js +6 -1
  33. package/dist/slider.js.map +1 -1
  34. package/dist/upload-item.d.ts +5 -0
  35. package/dist/upload-item.d.ts.map +1 -1
  36. package/dist/upload-item.js +5 -0
  37. package/dist/upload-item.js.map +1 -1
  38. package/dist/version.d.ts +1 -1
  39. package/dist/version.js +1 -1
  40. package/dist/version.js.map +1 -1
  41. package/docs/action-session.md +3 -3
  42. package/docs/agreement.md +5 -0
  43. package/docs/avatar-fallback.md +7 -0
  44. package/docs/bottom-navigation.md +6 -0
  45. package/docs/brand-boundary.md +1 -1
  46. package/docs/button-label.md +6 -0
  47. package/docs/clipboard.md +3 -0
  48. package/docs/command-palette.md +45 -2
  49. package/docs/consumer-policy.md +5 -1
  50. package/docs/data-table.md +6 -4
  51. package/docs/dialog.md +8 -2
  52. package/docs/form.md +51 -0
  53. package/docs/generated/component-maturity.md +1 -1
  54. package/docs/generated/renderer-evidence.json +3 -3
  55. package/docs/generated/renderer-evidence.md +1 -1
  56. package/docs/generated/showcase-manifest.json +1 -1
  57. package/docs/link.md +8 -0
  58. package/docs/migration-native-legacy-removal.md +45 -1
  59. package/docs/optional-adapters.md +1 -1
  60. package/docs/password-field.md +5 -0
  61. package/docs/product-composition-adoption.md +40 -0
  62. package/docs/progress.md +19 -1
  63. package/docs/provider-button.md +13 -0
  64. package/docs/result.md +3 -0
  65. package/docs/screen-chrome.md +10 -0
  66. package/docs/screen-patterns.md +378 -0
  67. package/docs/sheet.md +21 -0
  68. package/docs/splitter.md +8 -2
  69. package/docs/theming.md +36 -29
  70. package/docs/toggle-group.md +13 -0
  71. package/docs/tour.md +7 -1
  72. package/docs/tree.md +5 -2
  73. package/docs/upload-item.md +7 -0
  74. package/docs/usage/README.md +236 -0
  75. package/docs/usage/STANDARD.md +108 -0
  76. package/docs/usage/components/accordion.md +107 -0
  77. package/docs/usage/components/activity-heatmap.md +104 -0
  78. package/docs/usage/components/affix.md +86 -0
  79. package/docs/usage/components/agreement.md +129 -0
  80. package/docs/usage/components/alert-dialog.md +130 -0
  81. package/docs/usage/components/anchor.md +96 -0
  82. package/docs/usage/components/aspect-ratio.md +89 -0
  83. package/docs/usage/components/asset.md +126 -0
  84. package/docs/usage/components/auth-provider-button.md +116 -0
  85. package/docs/usage/components/auth-screen-layout.md +129 -0
  86. package/docs/usage/components/avatar.md +114 -0
  87. package/docs/usage/components/badge.md +84 -0
  88. package/docs/usage/components/bottom-cta.md +125 -0
  89. package/docs/usage/components/bottom-info.md +99 -0
  90. package/docs/usage/components/bottom-navigation.md +136 -0
  91. package/docs/usage/components/breadcrumb.md +81 -0
  92. package/docs/usage/components/button.md +118 -0
  93. package/docs/usage/components/calendar.md +122 -0
  94. package/docs/usage/components/card.md +110 -0
  95. package/docs/usage/components/carousel.md +113 -0
  96. package/docs/usage/components/celebration.md +96 -0
  97. package/docs/usage/components/chat-message.md +122 -0
  98. package/docs/usage/components/chat-screen.md +112 -0
  99. package/docs/usage/components/checkbox-group.md +104 -0
  100. package/docs/usage/components/checkbox.md +103 -0
  101. package/docs/usage/components/chip.md +107 -0
  102. package/docs/usage/components/code-block.md +111 -0
  103. package/docs/usage/components/collapsible.md +112 -0
  104. package/docs/usage/components/color-picker.md +86 -0
  105. package/docs/usage/components/combobox.md +137 -0
  106. package/docs/usage/components/command-palette.md +125 -0
  107. package/docs/usage/components/comment-thread-screen.md +125 -0
  108. package/docs/usage/components/container.md +98 -0
  109. package/docs/usage/components/content-transition.md +101 -0
  110. package/docs/usage/components/context-menu.md +136 -0
  111. package/docs/usage/components/counter-badge.md +107 -0
  112. package/docs/usage/components/data-table.md +122 -0
  113. package/docs/usage/components/date-picker.md +142 -0
  114. package/docs/usage/components/date-range-picker.md +111 -0
  115. package/docs/usage/components/description-list.md +103 -0
  116. package/docs/usage/components/design-system-provider.md +124 -0
  117. package/docs/usage/components/dialog.md +176 -0
  118. package/docs/usage/components/divider.md +89 -0
  119. package/docs/usage/components/editor-screen.md +126 -0
  120. package/docs/usage/components/effect-surface.md +120 -0
  121. package/docs/usage/components/empty-state.md +114 -0
  122. package/docs/usage/components/field.md +129 -0
  123. package/docs/usage/components/file-picker.md +114 -0
  124. package/docs/usage/components/floating-action-button.md +138 -0
  125. package/docs/usage/components/form.md +162 -0
  126. package/docs/usage/components/grid.md +99 -0
  127. package/docs/usage/components/heading.md +87 -0
  128. package/docs/usage/components/icon-button.md +126 -0
  129. package/docs/usage/components/icon.md +105 -0
  130. package/docs/usage/components/image.md +122 -0
  131. package/docs/usage/components/keyboard-avoiding.md +93 -0
  132. package/docs/usage/components/keyboard-dock.md +110 -0
  133. package/docs/usage/components/keyboard-form-scroll-view.md +95 -0
  134. package/docs/usage/components/keyboard-motion-provider.md +86 -0
  135. package/docs/usage/components/layout.md +117 -0
  136. package/docs/usage/components/link.md +121 -0
  137. package/docs/usage/components/list-detail-screen.md +103 -0
  138. package/docs/usage/components/list-row.md +124 -0
  139. package/docs/usage/components/list.md +119 -0
  140. package/docs/usage/components/load-more.md +115 -0
  141. package/docs/usage/components/masonry.md +109 -0
  142. package/docs/usage/components/media-selection-screen.md +119 -0
  143. package/docs/usage/components/mentions.md +119 -0
  144. package/docs/usage/components/menu.md +129 -0
  145. package/docs/usage/components/menubar.md +93 -0
  146. package/docs/usage/components/message-composer.md +124 -0
  147. package/docs/usage/components/moderation-screen.md +113 -0
  148. package/docs/usage/components/notice.md +106 -0
  149. package/docs/usage/components/notification-inbox-screen.md +97 -0
  150. package/docs/usage/components/notification-item.md +98 -0
  151. package/docs/usage/components/number-field.md +131 -0
  152. package/docs/usage/components/onboarding-screen.md +106 -0
  153. package/docs/usage/components/otp-field.md +101 -0
  154. package/docs/usage/components/pagination.md +82 -0
  155. package/docs/usage/components/password-field.md +137 -0
  156. package/docs/usage/components/permission-screen.md +107 -0
  157. package/docs/usage/components/photo-source-sheet.md +119 -0
  158. package/docs/usage/components/popover.md +108 -0
  159. package/docs/usage/components/profile-screen.md +89 -0
  160. package/docs/usage/components/progress.md +122 -0
  161. package/docs/usage/components/qr-code.md +122 -0
  162. package/docs/usage/components/radio-group.md +124 -0
  163. package/docs/usage/components/radio.md +104 -0
  164. package/docs/usage/components/result.md +116 -0
  165. package/docs/usage/components/saved-items-screen.md +126 -0
  166. package/docs/usage/components/screen-layout.md +119 -0
  167. package/docs/usage/components/search-field.md +120 -0
  168. package/docs/usage/components/search-screen.md +221 -0
  169. package/docs/usage/components/section.md +111 -0
  170. package/docs/usage/components/segmented-control.md +146 -0
  171. package/docs/usage/components/select.md +142 -0
  172. package/docs/usage/components/settings-screen.md +126 -0
  173. package/docs/usage/components/shared-transition-element.md +111 -0
  174. package/docs/usage/components/shared-transition-screen.md +86 -0
  175. package/docs/usage/components/sheet.md +157 -0
  176. package/docs/usage/components/side-panel.md +104 -0
  177. package/docs/usage/components/sidebar.md +107 -0
  178. package/docs/usage/components/skeleton.md +105 -0
  179. package/docs/usage/components/skip-nav.md +76 -0
  180. package/docs/usage/components/slider.md +121 -0
  181. package/docs/usage/components/sortable-collection.md +127 -0
  182. package/docs/usage/components/spinner.md +86 -0
  183. package/docs/usage/components/splitter.md +103 -0
  184. package/docs/usage/components/stack.md +93 -0
  185. package/docs/usage/components/statistic.md +123 -0
  186. package/docs/usage/components/steps.md +110 -0
  187. package/docs/usage/components/surface.md +91 -0
  188. package/docs/usage/components/swipe-actions.md +124 -0
  189. package/docs/usage/components/switch.md +120 -0
  190. package/docs/usage/components/tabs.md +134 -0
  191. package/docs/usage/components/tag.md +84 -0
  192. package/docs/usage/components/tags-input.md +111 -0
  193. package/docs/usage/components/text-area.md +112 -0
  194. package/docs/usage/components/text-format.md +75 -0
  195. package/docs/usage/components/text-transition.md +104 -0
  196. package/docs/usage/components/text.md +101 -0
  197. package/docs/usage/components/thinking-orb.md +105 -0
  198. package/docs/usage/components/timeline.md +105 -0
  199. package/docs/usage/components/toast.md +145 -0
  200. package/docs/usage/components/toggle-group.md +95 -0
  201. package/docs/usage/components/tooltip.md +103 -0
  202. package/docs/usage/components/top-bar.md +124 -0
  203. package/docs/usage/components/top.md +89 -0
  204. package/docs/usage/components/tour.md +118 -0
  205. package/docs/usage/components/transfer-list.md +115 -0
  206. package/docs/usage/components/tree.md +91 -0
  207. package/docs/usage/components/upload-item.md +99 -0
  208. package/docs/usage/components/virtual-list.md +105 -0
  209. package/docs/usage/components/visually-hidden.md +72 -0
  210. package/docs/usage/components/watermark.md +78 -0
  211. package/docs/usage/compositions/action-recovery-optimistic.md +180 -0
  212. package/docs/usage/compositions/action-recovery-save.md +235 -0
  213. package/docs/usage/compositions/action-recovery-undo.md +193 -0
  214. package/docs/usage/compositions/common-message.md +132 -0
  215. package/docs/usage/compositions/common-notification.md +101 -0
  216. package/docs/usage/compositions/compound-controls.md +186 -0
  217. package/docs/usage/compositions/data-layouts.md +157 -0
  218. package/docs/usage/compositions/disclosure.md +144 -0
  219. package/docs/usage/compositions/environment-matrix.md +139 -0
  220. package/docs/usage/compositions/expo-interactions.md +149 -0
  221. package/docs/usage/compositions/family-drawer.md +201 -0
  222. package/docs/usage/compositions/floating-action-button.md +197 -0
  223. package/docs/usage/compositions/input-sheet.md +148 -0
  224. package/docs/usage/compositions/interaction-adapters.md +190 -0
  225. package/docs/usage/compositions/interaction-flow-apply.md +205 -0
  226. package/docs/usage/compositions/interaction-flow-draft.md +188 -0
  227. package/docs/usage/compositions/interaction-flow-search.md +171 -0
  228. package/docs/usage/compositions/native-renderers.md +106 -0
  229. package/docs/usage/compositions/navigation-bar-collection.md +164 -0
  230. package/docs/usage/compositions/optional-adapters.md +169 -0
  231. package/docs/usage/compositions/optional-motion.md +109 -0
  232. package/docs/usage/compositions/photo-source.md +104 -0
  233. package/docs/usage/compositions/purpose-input-comment.md +110 -0
  234. package/docs/usage/compositions/purpose-input-message.md +119 -0
  235. package/docs/usage/compositions/reference-first.md +96 -0
  236. package/docs/usage/compositions/reference-review.md +107 -0
  237. package/docs/usage/compositions/reference-settings.md +107 -0
  238. package/docs/usage/compositions/selection-scope.md +174 -0
  239. package/docs/usage/compositions/stea-event-ticket.md +166 -0
  240. package/docs/usage/compositions/stea-flip-card.md +162 -0
  241. package/docs/usage/compositions/stea-order-progress.md +184 -0
  242. package/docs/usage/compositions/stea-otp-verify.md +215 -0
  243. package/docs/usage/compositions/stea-pixel-empty.md +140 -0
  244. package/docs/usage/compositions/stea-schedule-card.md +169 -0
  245. package/docs/usage/compositions/stea-stat-summary.md +154 -0
  246. package/docs/usage/compositions/time-selection.md +174 -0
  247. package/docs/usage/compositions/toast-layout.md +128 -0
  248. package/docs/usage/compositions/visual-foundations.md +185 -0
  249. package/docs/usage/compositions/web-additions.md +146 -0
  250. package/docs/usage/compositions/web-navigation.md +143 -0
  251. package/docs/usage/screens/common-chat.md +127 -0
  252. package/docs/usage/screens/common-comments.md +108 -0
  253. package/docs/usage/screens/common-inbox.md +110 -0
  254. package/docs/usage/screens/common-login.md +98 -0
  255. package/docs/usage/screens/common-profile.md +221 -0
  256. package/docs/usage/screens/common-saved.md +127 -0
  257. package/docs/usage/screens/common-search.md +279 -0
  258. package/docs/usage/screens/common-settings.md +126 -0
  259. package/docs/usage/screens/common-shell.md +108 -0
  260. package/docs/usage/screens/dashboard.md +245 -0
  261. package/docs/usage/screens/discovery-gallery.md +306 -0
  262. package/docs/usage/screens/flow-collection.md +96 -0
  263. package/docs/usage/screens/flow-editor.md +120 -0
  264. package/docs/usage/screens/flow-media.md +111 -0
  265. package/docs/usage/screens/flow-moderation.md +120 -0
  266. package/docs/usage/screens/flow-onboarding.md +193 -0
  267. package/docs/usage/screens/flow-permission.md +103 -0
  268. package/docs/usage/screens/landing.md +347 -0
  269. package/docs/usage/screens/mockup-studio.md +190 -0
  270. package/docs/usage/screens/notification-settings.md +206 -0
  271. package/docs/usage/screens/reference-comparison.md +159 -0
  272. package/docs/usage/templates/component.md +61 -0
  273. package/docs/usage/templates/composition.md +47 -0
  274. package/docs/usage/templates/screen.md +56 -0
  275. package/docs/usage/templates/token.md +32 -0
  276. package/docs/usage/tokens/color.md +142 -0
  277. package/docs/usage/tokens/elevation-opacity.md +86 -0
  278. package/docs/usage/tokens/layers.md +98 -0
  279. package/docs/usage/tokens/layout.md +114 -0
  280. package/docs/usage/tokens/motion.md +88 -0
  281. package/docs/usage/tokens/radius.md +53 -0
  282. package/docs/usage/tokens/size.md +74 -0
  283. package/docs/usage/tokens/spacing.md +73 -0
  284. package/docs/usage/tokens/stroke.md +50 -0
  285. package/docs/usage/tokens/theme-studio.md +70 -0
  286. package/docs/usage/tokens/typography-studio.md +70 -0
  287. package/docs/usage/tokens/typography.md +89 -0
  288. package/package.json +7 -1
@@ -0,0 +1,112 @@
1
+ # TextArea
2
+
3
+ - ๋‹จ๊ณ„: ์ปดํฌ๋„ŒํŠธ
4
+ - ์ƒํƒœ: ๋ฐฐํฌ
5
+ - ์ง€์›: Web ยท Native
6
+ - ์ ์šฉ: 1.12.1
7
+ - ๊ฒ€ํ† ์ผ: 2026-10-06
8
+ - ๊ทผ๊ฑฐ: `src/base-recipes.ts`(`fieldRecipe`)
9
+ - ์Šคํ† ๋ฆฌ๋ถ: `๋ฐฐํฌ/์ปดํฌ๋„ŒํŠธ/์ž…๋ ฅ/์—ฌ๋Ÿฌ ์ค„ ์ž…๋ ฅ`
10
+
11
+ ## ์–ธ์ œ ์“ฐ๋‚˜
12
+
13
+ ์—ฌ๋Ÿฌ ์ค„ ์ž์œ  ๊ธ€์„ ๋ฐ›๋Š” ์ž…๋ ฅ์— ์“ด๋‹ค. ์ž๊ธฐ์†Œ๊ฐœ, ํ›„๊ธฐ, ๋ฌธ์˜ ๋ณธ๋ฌธ์ฒ˜๋Ÿผ ์ค„๋ฐ”๊ฟˆ์ด ๊ฐ’์˜ ์ผ๋ถ€์ธ ๊ฒฝ์šฐ๋‹ค.
14
+ ๋ผ๋ฒจยท์„ค๋ช…ยท์˜ค๋ฅ˜ ๋ฌธ๊ตฌ ํ‹€์€ [Field](field.md)์™€ ๊ฐ™๋‹ค.
15
+
16
+ ## ์“ฐ์ง€ ์•Š์„ ๋•Œ
17
+
18
+ | ์ƒํ™ฉ | ๋Œ€์‹  ์“ธ ๊ฒƒ |
19
+ | --- | --- |
20
+ | ํ•œ ์ค„ ๊ฐ’(์ด๋ฆ„, ์ด๋ฉ”์ผ) | [Field](field.md)์˜ `TextField` |
21
+ | `@์‚ฌ๋žŒ` ์–ธ๊ธ‰์ด ์žˆ๋Š” ๋ณธ๋ฌธ | [Mentions](mentions.md) |
22
+ | ๋น„๋ฐ€๋ฒˆํ˜ธยท์ˆซ์žยท์ธ์ฆ ์ฝ”๋“œ | [PasswordField](password-field.md), [NumberField](number-field.md), [OTPField](otp-field.md) |
23
+ | ๊ฒ€์ƒ‰์–ด | [SearchField](search-field.md) |
24
+
25
+ ## ๊ณต๊ฐœ ์ด๋ฆ„๊ณผ import
26
+
27
+ | ์ด๋ฆ„ | ์—ญํ•  | Web | Native |
28
+ | --- | --- | --- | --- |
29
+ | `TextArea` | ๊ธฐ๋ณธ | `@hjmds/react`, `/forms` | `@hjmds/react-native`, `/inputs` |
30
+
31
+ ## ์ตœ์†Œ ์‚ฌ์šฉ ์˜ˆ
32
+
33
+ ```tsx
34
+ // Web
35
+ import { TextArea } from "@hjmds/react/forms";
36
+
37
+ <TextArea
38
+ label={t("review.body")}
39
+ description={t("review.bodyHint")}
40
+ error={bodyError ? t(bodyError) : undefined}
41
+ value={body}
42
+ onChange={(event) => setBody(event.currentTarget.value)}
43
+ minVisibleLines={3}
44
+ maxVisibleLines={8}
45
+ />
46
+ ```
47
+
48
+ ```tsx
49
+ // Native
50
+ import { TextArea } from "@hjmds/react-native/inputs";
51
+
52
+ <TextArea
53
+ label={t("review.body")}
54
+ value={body}
55
+ onValueChange={setBody}
56
+ maxVisibleLines={8}
57
+ layoutStyle={{ marginTop: 16 }}
58
+ />
59
+ ```
60
+
61
+ ## ์ถ•๊ณผ ๊ธฐ๋ณธ๊ฐ’
62
+
63
+ | prop | ๊ฐ’ | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… |
64
+ | --- | --- | --- | --- |
65
+ | `variant` | `surface` ยท `inset` | `surface` | โ€” |
66
+ | `shape` | `medium` ยท `large` ยท `full` | `medium` | โ€” |
67
+ | `align` | `start` ยท `center` | `start` | โ€” |
68
+ | `value`/`defaultValue` | `string` | โ€” | โ€” |
69
+ | `onChange`(Web) | `(event: ChangeEvent<HTMLTextAreaElement>) => void` | โ€” | DOM ์ด๋ฒคํŠธ. ๊ฐ’์€ `event.currentTarget.value` |
70
+ | `onValueChange`(Native) | `(value: string) => void` | โ€” | ๋‹ค์Œ ๋ฌธ์ž์—ด |
71
+ | `minVisibleLines` ยท `maxVisibleLines` | ์ค„ ์ˆ˜ | ์ตœ์†Œ ๋†’์ด 80, ์ƒํ•œ ์—†์Œ | ๋†’์ด๋Š” ์ค„ ์ˆ˜๋กœ๋งŒ ์ •ํ•œ๋‹ค. ์ตœ์†Œ ๋†’์ด๋Š” `max(80, ์ค„ ์ˆ˜ ร— typography.body ์ค„ ๋†’์ด 20 + spacing.sm 12 ร— 2)`๋ผ `minVisibleLines`๊ฐ€ 1ยท2์—ฌ๋„ 80(`fieldRecipe.multilineMinHeight`) ์•„๋ž˜๋กœ ๋‚ด๋ ค๊ฐ€์ง€ ์•Š๊ณ  3๋ถ€ํ„ฐ ์ปค์ง„๋‹ค(3์ค„ 84). WebยทNative ๊ฐ™๋‹ค |
72
+ | `leadingAction` | `ReactNode` | โ€” | ํ‹€ ์•ˆ ๊ธ€์ž ์•ž ํ–‰๋™ ๋ฒ„ํŠผ. ์ž๋ผ๋Š” ๊ธ€์ž์˜ ์„ธ๋กœ ๊ฐ€์šด๋ฐ์— ๋งž์ถ”๊ณ  ํ๋ฆฐ affix ์ƒ‰์„ ์“ฐ์ง€ ์•Š๋Š”๋‹ค. ๋ฏธ๊ฒŒ์‹œ(1.12.1 ์ดํ›„) |
73
+ | `trailing` | `ReactNode` | โ€” | ํ‹€ ์•ˆ ๊ธ€์ž ๋’ค ์Šฌ๋กฏ |
74
+ | `description` ยท `error` ยท `required` ยท `disabled` | Web `ReactNode`, Native `string` ยท `boolean` | โ€” | Field์™€ ๊ฐ™์€ ํ‹€๋กœ ๊ทธ๋ ค์ง€๊ณ  ๋ณด์กฐ๊ธฐ๊ธฐ ์„ค๋ช…์— ์—ฐ๊ฒฐ๋œ๋‹ค |
75
+ | `busy`(Native) | `boolean` | `false` | โ€” |
76
+ | `layoutStyle` | `HjmCompositionStyleProp` | โ€” | ํ•„๋“œ ์ „์ฒด(๋ผ๋ฒจยทํ‹€ยท์„ค๋ช…) ๋ฐฐ์น˜. WebยทNative ๋ชจ๋‘ |
77
+
78
+ `leading`(ํ๋ฆฐ ์žฅ์‹ affix)์€ TextArea์— ์—†๋‹ค(TextField ์ „์šฉ). ํ–‰๋™์€ `leadingAction`ยท`trailing`์— ๋‘๊ณ , ๊ธ€์ž ์ˆ˜ ๊ฐ™์€ ๋ณด์กฐ ํ‘œ์‹œ๋Š” `description`์œผ๋กœ ๋‘”๋‹ค.
79
+
80
+ ## ๋ฐฐ์น˜
81
+
82
+ | ํ•ญ๋ชฉ | ๊ฐ’ | ๊ทผ๊ฑฐ |
83
+ | --- | --- | --- |
84
+ | ํฌ๊ธฐ | ์ตœ์†Œ ๋†’์ด 80(`fieldRecipe.multilineMinHeight`)์—์„œ ์‹œ์ž‘ํ•ด ์ž…๋ ฅ์— ๋”ฐ๋ผ ์ž๋ž€๋‹ค. ์ขŒ์šฐ ์•ˆ์ชฝ ์—ฌ๋ฐฑ `spacing.md` 16, ๋ชจ์„œ๋ฆฌ ๊ธฐ๋ณธ `radius.md` 12 | `fieldRecipe`, `.hjm-field__control--multiline` |
85
+ | ๊ฐ„๊ฒฉ | ๋ผ๋ฒจ๊ณผ ํ‹€ ์‚ฌ์ด `spacing.xs` 8. ์ด์›ƒ ํ•„๋“œ์™€์˜ ๊ฐ„๊ฒฉ์€ ํผ์ด ์ •ํ•˜๊ณ  TextArea๋Š” ๋ฐ”๊นฅ ์—ฌ๋ฐฑ์ด ์—†๋‹ค(ํ•„์š”ํ•˜๋ฉด `layoutStyle`๋กœ ์ค€๋‹ค) | `fieldRecipe.label.gap`, `.hjm-field` |
86
+ | ์ˆœ์„œยท์ •๋ ฌ | ๋ผ๋ฒจ โ†’ ์ž…๋ ฅ ํ‹€ โ†’ ์„ค๋ช…/์˜ค๋ฅ˜. ํผ์˜ ์„ธ๋กœ ์ค„์—์„œ ํญ์„ ๊ฝ‰ ์ฑ„์šด๋‹ค | `react-native/src/inputs.tsx`(`TextArea`) |
87
+ | ๊ณ ์ •ยท์Šคํฌ๋กค | `maxVisibleLines`์— ๋‹ฟ์œผ๋ฉด ํ‹€ ์•ˆ์—์„œ ์Šคํฌ๋กคํ•œ๋‹ค. Web์€ ์‚ฌ์šฉ์ž๊ฐ€ ์„ธ๋กœ๋กœ๋งŒ ํฌ๊ธฐ๋ฅผ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค(`resize: vertical`) | `.hjm-field__control--multiline textarea` |
88
+ | ์ข์€ ํญยทํฐ ๊ธ€์ž | ํฐ ๊ธ€์ž์—์„œ๋Š” ์ค„ ๋†’์ด๊ฐ€ ์ปค์ ธ `minVisibleLines`ยท`maxVisibleLines`์˜ ์‹ค์ œ ๋†’์ด๋„ ์ปค์ง„๋‹ค. ํ”ฝ์…€ ๋†’์ด๋กœ ๊ณ ์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค | `.hjm-field__control--multiline textarea` |
89
+
90
+ ## ๊ผญ ์ง€ํ‚ฌ ๊ฒƒ
91
+
92
+ - `label` ๋˜๋Š” ์ ‘๊ทผ ์ด๋ฆ„(Web `aria-label`, Native `accessibilityLabel`)์ด ๋ฐ˜๋“œ์‹œ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๋‘˜ ๋‹ค ์—†์œผ๋ฉด `TypeError`.
93
+ - ๋ผ๋ฒจยท์„ค๋ช…ยท์˜ค๋ฅ˜ยทplaceholder๋Š” i18n ํ‚ค๋กœ ๋„ฃ๋Š”๋‹ค. placeholder๋ฅผ ๋ผ๋ฒจ ๋Œ€์‹  ์“ฐ์ง€ ์•Š๋Š”๋‹ค.
94
+ - ๋†’์ด๋ฅผ `style`์˜ `minHeight`/`maxHeight`๋กœ ๋ฐ”๊พธ์ง€ ์•Š๋Š”๋‹ค. `minVisibleLines`/`maxVisibleLines`๋ฅผ ์“ด๋‹ค.
95
+ - ํ•œ ์ค„ ๋†’์ด(44)์—์„œ ์‹œ์ž‘ํ•ด ์ž๋ผ๋Š” ์ž…๋ ฅ์ด ํ•„์š”ํ•˜๋ฉด TextArea๊ฐ€ ์•„๋‹ˆ๋ผ [MessageComposer](message-composer.md)๋ฅผ ์“ด๋‹ค. ํ•œ ์ค„ ์‹œ์ž‘์€ composer ๋‚ด๋ถ€ ์ „์šฉ์ด๋ฉฐ ๊ณต๊ฐœ `minVisibleLines`๋กœ๋Š” 80 ์•„๋ž˜๋กœ ๋‚ด๋ ค๊ฐ€์ง€ ์•Š๋Š”๋‹ค. 2026-10-06 ๋ฆฌ๋ทฐ์—์„œ ํ•˜ํ•œ์„ 44๋กœ ๋‚ฎ์ถ˜ ๋ฏธ๊ฒŒ์‹œ ๋ณ€๊ฒฝ์ด ๊ธฐ์กด `minVisibleLines={2}` ํ•„๋“œ๋ฅผ 80์—์„œ 64๋กœ ์ค„์—ฌ ๋˜๋Œ๋ ธ๋‹ค.
96
+ - ์˜ค๋ฅ˜๋Š” `error`๋กœ ๋„˜๊ธด๋‹ค. ํ…Œ๋‘๋ฆฌ ์ƒ‰์„ ์ง์ ‘ ๋ฐ”๊พธ์ง€ ์•Š๋Š”๋‹ค.
97
+
98
+ ## ํ”Œ๋žซํผ ์ฐจ์ด
99
+
100
+ | ํ•ญ๋ชฉ | Web | Native |
101
+ | --- | --- | --- |
102
+ | ๊ฐ’ ๋ณ€๊ฒฝ | DOM `onChange`(`onValueChange` ์—†์Œ) | `onValueChange(value)` |
103
+ | ๋ฐฐ์น˜ | `layoutStyle`(ํ•„๋“œ ์ „์ฒด), ๋ฐ”๊นฅ ํ‹€ class๋Š” `fieldClassName` | `layoutStyle`(ํ•„๋“œ ์ „์ฒด) |
104
+ | `style` | `textarea`์— ์ „๋‹ฌ | ํƒ€์ž…์—์„œ ์ œ์™ธ |
105
+ | ์ง„ํ–‰ ํ‘œ์‹œ | ์—†์Œ | `busy` |
106
+ | ๋ผ๋ฒจยท๋ฌธ๊ตฌ ํƒ€์ž… | `ReactNode` | `string` |
107
+ | import ๊ฒฝ๋กœ | `/forms` | `/inputs` |
108
+
109
+ ## ํ•จ์ •
110
+
111
+ - ํ˜„์žฌ Web `TextField`์˜ `onValueChange` ์ฃผ์„์€ "Web TextArea์™€ ๊ฐ™์€ ์ฝœ๋ฐฑ"์ด๋ผ๊ณ  ์ ์ง€๋งŒ Web `TextAreaProps`์—๋Š”
112
+ `onValueChange`๊ฐ€ ์—†๋‹ค(`react/src/forms.tsx`). ๊ณต์œ  ํผ ์ฝ”๋“œ๋Š” Web TextArea๋งŒ `onChange`๋กœ ๋ถ„๊ธฐํ•œ๋‹ค.
@@ -0,0 +1,75 @@
1
+ # TextFormat
2
+
3
+ - ๋‹จ๊ณ„: ์ปดํฌ๋„ŒํŠธ
4
+ - ์ƒํƒœ: ๋ฐฐํฌ
5
+ - ์ง€์›: Web
6
+ - ์ ์šฉ: 1.12.1
7
+ - ๊ฒ€ํ† ์ผ: 2026-10-06
8
+ - ๊ทผ๊ฑฐ: [TextFormat](../../text-formats.md), `src/text-formats.ts`(`textFormatRecipe`)
9
+ - ์Šคํ† ๋ฆฌ๋ถ: `๋ฐฐํฌ/์ปดํฌ๋„ŒํŠธ/๊ธ€์ž์™€ ์•„์ด์ฝ˜/๊ธ€์ž ์„œ์‹`
10
+
11
+ ## ์–ธ์ œ ์“ฐ๋‚˜
12
+
13
+ ๋„์›€๋งยท๊ฐœ๋ฐœ์ž ์•ˆ๋‚ดยท์•ฝ๊ด€ ๋ณธ๋ฌธ ์•ˆ์—์„œ ๋‹จ์ถ•ํ‚ค(`โŒ˜S`), ์งง์€ ์ฝ”๋“œ ์กฐ๊ฐ(`pnpm add โ€ฆ`), ์ธ์šฉ๋ฌธ์„
14
+ ํ‘œ์‹œํ•  ๋•Œ ์“ด๋‹ค. `kind`๋งˆ๋‹ค `<kbd>`ยท`<code>`ยท`<blockquote>`๋ผ๋Š” ๋‹ค๋ฅธ HTML ์š”์†Œ๋ฅผ ๊ทธ๋ ค
15
+ ๋ณด์กฐ๊ธฐ๊ธฐ๊ฐ€ ๊ทธ ์˜๋ฏธ๋Œ€๋กœ ์ฝ๊ฒŒ ํ•œ๋‹ค.
16
+
17
+ ## ์“ฐ์ง€ ์•Š์„ ๋•Œ
18
+
19
+ | ์ƒํ™ฉ | ๋Œ€์‹  ์“ธ ๊ฒƒ |
20
+ | --- | --- |
21
+ | ์—ฌ๋Ÿฌ ์ค„ ์ฝ”๋“œ, ๋ณต์‚ฌ ๋ฒ„ํŠผ์ด ๋ถ™์€ ์ฝ”๋“œ | [CodeBlock](code-block.md) |
22
+ | ๋‹จ์ˆœํžˆ ๊ธ€์ž ํฌ๊ธฐยท๊ตต๊ธฐ๋งŒ ๋‹ค๋ฆ„ | [Text](text.md) |
23
+ | Native ํ™”๋ฉด | ์—†์Œ. RN์—๋Š” ๋Œ€์‘ ์˜๋ฏธ ์š”์†Œ๊ฐ€ ์—†์–ด renderer๋ฅผ ๋‘์ง€ ์•Š๋Š”๋‹ค([๊ณ„์•ฝ](../../text-formats.md)) |
24
+
25
+ ## ๊ณต๊ฐœ ์ด๋ฆ„๊ณผ import
26
+
27
+ | ์ด๋ฆ„ | ์—ญํ•  | Web | Native |
28
+ | --- | --- | --- | --- |
29
+ | `TextFormat` | ๊ธฐ๋ณธ | `@hjmds/react`, `/text-formats` | โ€” |
30
+
31
+ ## ์ตœ์†Œ ์‚ฌ์šฉ ์˜ˆ
32
+
33
+ ```tsx
34
+ // Web
35
+ import { Text } from "@hjmds/react/layout";
36
+ import { TextFormat } from "@hjmds/react/text-formats";
37
+
38
+ <>
39
+ <Text>
40
+ {t("help.saveShortcut.prefix")}{" "}
41
+ <TextFormat kind="kbd">{t("help.saveShortcut.key")}</TextFormat>
42
+ </Text>
43
+ <TextFormat kind="code">pnpm add @hjmds/react</TextFormat>
44
+ </>
45
+ ```
46
+
47
+ Native: ์—†์Œ.
48
+
49
+ ## ์ถ•๊ณผ ๊ธฐ๋ณธ๊ฐ’
50
+
51
+ | prop | ๊ฐ’ | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… |
52
+ | --- | --- | --- | --- |
53
+ | `kind`(ํ•„์ˆ˜) | `kbd` โ†’ `<kbd>` ยท `code` โ†’ `<code>` ยท `quote` โ†’ `<blockquote>` | ์—†์Œ | ๋ชฉ๋ก ๋ฐ– ๊ฐ’์€ ์‹คํ–‰ ์ค‘ `TypeError` |
54
+ | `children` | `ReactNode` | โ€” (ํ•„์ˆ˜) | โ€” |
55
+ | `layoutStyle` | `HjmCompositionStyleProp` | โ€” | ๋ฐฐ์น˜(์ฃผ๋กœ `quote` ๋ธ”๋ก์˜ ๋ฐ”๊นฅ ์—ฌ๋ฐฑยทํญ) |
56
+ | ๋‚˜๋จธ์ง€ | `HTMLAttributes<HTMLElement>` | โ€” | ํ•ด๋‹น HTML ์š”์†Œ๋กœ ์ „๋‹ฌ๋˜๊ณ  ref๋„ ๊ทธ ์š”์†Œ๋กœ ๊ฐ„๋‹ค |
57
+
58
+ ## ๋ฐฐ์น˜
59
+
60
+ | ํ•ญ๋ชฉ | ๊ฐ’ | ๊ทผ๊ฑฐ |
61
+ | --- | --- | --- |
62
+ | ํฌ๊ธฐ | `kbd`ยท`code` ์•ˆ์ชฝ ์ขŒ์šฐ ์—ฌ๋ฐฑ `spacing.xxs` 4, ๋ชจ์„œ๋ฆฌ `radius.sm` 8. `quote` ์‹œ์ž‘ ์ชฝ 2px ์„ธ๋กœ ์„ ๊ณผ ์•ˆ์ชฝ ์—ฌ๋ฐฑ `spacing.md` 16 | `.hjm-text-format[data-kind]` |
63
+ | ๊ฐ„๊ฒฉ | ๋ฐ”๊นฅ ์—ฌ๋ฐฑ์ด ์—†๋‹ค(`margin: 0`). `quote` ์•ž๋’ค ๋ฌธ๋‹จ๊ณผ์˜ ๊ฐ„๊ฒฉ์€ ๋ถ€๋ชจ๊ฐ€ ์ค€๋‹ค | `.hjm-text-format` |
64
+ | ์ˆœ์„œยท์ •๋ ฌ | `kbd`ยท`code`๋Š” ๋ฌธ์žฅ ์•ˆ์— ์ธ๋ผ์ธ์œผ๋กœ, `quote`๋Š” ๋ธ”๋ก์œผ๋กœ ๋†“๋Š”๋‹ค | `.hjm-text-format` |
65
+ | ๊ณ ์ •ยท์Šคํฌ๋กค | โ€” | โ€” |
66
+ | ์ข์€ ํญยทํฐ ๊ธ€์ž | ๊ธด ์ฝ”๋“œ ์กฐ๊ฐ์€ ์ค„๋ฐ”๊ฟˆ๋œ๋‹ค(`overflow-wrap: anywhere`). ์ค„๋ฐ”๊ฟˆ ์—†์ด ๊ฐ€๋กœ ์Šคํฌ๋กค์ด ํ•„์š”ํ•˜๋ฉด [CodeBlock](code-block.md) | `.hjm-text-format` |
67
+
68
+ ## ๊ผญ ์ง€ํ‚ฌ ๊ฒƒ
69
+
70
+ - ํ‚ค ์ด๋ฆ„(โŒ˜ / Ctrl ๋“ฑ)์€ ์ œํ’ˆ ๋ฌธ๊ตฌ๋‹ค. ํ”Œ๋žซํผ๋ณ„๋กœ ๋‹ค๋ฅด๊ฒŒ ๋ถ€๋ฅด๋ฏ€๋กœ i18n ํ‚ค๋กœ ๋„ฃ๊ณ  HJM์ด ์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค.
71
+ - `quote`๋Š” ๋ธ”๋ก ์š”์†Œ(`<blockquote>`)๋ฅผ ๋งŒ๋“ ๋‹ค. ๋ฌธ๋‹จ ์•ˆ ์ธ๋ผ์ธ ๊ฐ•์กฐ์šฉ์œผ๋กœ ์“ฐ์ง€ ์•Š๋Š”๋‹ค.
72
+ - ๋ฐฐ์น˜๋Š” `layoutStyle`๋กœ ํ•œ๋‹ค. `className`์€ ๋ถ™์ผ ์ˆ˜ ์žˆ์ง€๋งŒ(`hjm-text-format`์— ํ•ฉ์ณ์ง„๋‹ค) ๊ธ€๊ผดยท์ƒ‰ยทํ…Œ๋‘๋ฆฌ๋ฅผ ๋ฎ์ง€ ์•Š๋Š”๋‹ค.
73
+ ๋ฐฐ์น˜ ์™ธ ์‹œ๊ฐ override๋Š” [์†Œ๋น„ ์ •์ฑ…](../../consumer-policy.md) ์œ„๋ฐ˜์ด๋‹ค.
74
+ - ๋ชจ์–‘์€ `@hjmds/react/styles.css`์˜ `.hjm-text-format` ๊ทœ์น™์ด ๊ทธ๋ฆฐ๋‹ค. stylesheet๋ฅผ ๋ถˆ๋Ÿฌ์˜ค์ง€
75
+ ์•Š์€ ํ™”๋ฉด์—์„œ๋Š” ์˜๋ฏธ ์š”์†Œ๋งŒ ๋‚จ๊ณ  HJM ๋ชจ์–‘์€ ์—†๋‹ค.
@@ -0,0 +1,104 @@
1
+ # TextTransition
2
+
3
+ - ๋‹จ๊ณ„: ์ปดํฌ๋„ŒํŠธ
4
+ - ์ƒํƒœ: ๋ฐฐํฌ
5
+ - ์ง€์›: Web ยท Native
6
+ - ์ ์šฉ: 1.12.1
7
+ - ๊ฒ€ํ† ์ผ: 2026-10-06
8
+ - ๊ทผ๊ฑฐ: `src/content-transition.ts`(`resolveContentTransition`). ๋…๋ฆฝ ๊ณ„์•ฝ ๋ฌธ์„œ ์—†์Œ(supplemental)
9
+ - ์Šคํ† ๋ฆฌ๋ถ: `๋ฐฐํฌ/์ปดํฌ๋„ŒํŠธ/์‹œ๊ฐ ํšจ๊ณผ/๋‚ด์šฉ ์ „ํ™˜`, `๋ฐฐํฌ/๊ตฌ์„ฑ/์ง์ ‘ ์กฐ์ž‘๊ณผ ๋ชจ์…˜/๋Œ๊ธฐยท๋ฐ€๊ธฐยทํ™”๋ฉด ์ „ํ™˜`
10
+
11
+ ## ์–ธ์ œ ์“ฐ๋‚˜
12
+
13
+ ๊ฐ™์€ ์ž๋ฆฌ์˜ ์งง์€ ๋ฌธ์ž์—ด์ด ๋ฐ”๋€” ๋•Œ(์ƒํƒœ ๋ฌธ๊ตฌ, ๋ฒ„ํŠผ ์˜† ์•ˆ๋‚ด, ๋‹จ๊ณ„ ์ด๋ฆ„) ๋ฐ”๋€ ์ˆœ๊ฐ„์„ ์งง์€
14
+ ๋“ฑ์žฅ ๋ชจ์…˜์œผ๋กœ ์•Œ๋ฆฐ๋‹ค. ๊ธ€์ž ๋‹จ์œ„๋กœ ์ชผ๊ฐœ์ง€ ์•Š๊ณ  ๋ฌธ์ž์—ด ์ „์ฒด๋ฅผ ํ•œ ๋ฒˆ์— ๋ฐ”๊ฟ”, ์ค„๋ฐ”๊ฟˆยท์„ ํƒยท
15
+ ์Šคํฌ๋ฆฐ๋ฆฌ๋” ๋‚ญ๋…์ด ํ•œ ๊ฐ’์œผ๋กœ ์œ ์ง€๋œ๋‹ค.
16
+
17
+ ## ์“ฐ์ง€ ์•Š์„ ๋•Œ
18
+
19
+ | ์ƒํ™ฉ | ๋Œ€์‹  ์“ธ ๊ฒƒ |
20
+ | --- | --- |
21
+ | ๋ฌธ์ž์—ด์ด ์•„๋‹ˆ๋ผ ํŒจ๋„ยท์˜์—ญ ์ „์ฒด๊ฐ€ ๋ฐ”๋€œ | `ContentTransition`(๊ฐ™์€ subpath, ์•„๋ž˜ ํ‘œ) โ€” [ContentTransition](content-transition.md) |
22
+ | ์ˆซ์ž ๊ฐ’์ด ๋ฐ”๋€Œ๋Š” ํ†ต๊ณ„ | [Statistic](statistic.md) |
23
+ | ์ฝ์–ด ์ค˜์•ผ ํ•˜๋Š” ๊ฒฐ๊ณผ ์•Œ๋ฆผ | [Toast](toast.md), [Notice](notice.md) |
24
+
25
+ ## ๊ณต๊ฐœ ์ด๋ฆ„๊ณผ import
26
+
27
+ | ์ด๋ฆ„ | ์—ญํ•  | Web | Native |
28
+ | --- | --- | --- | --- |
29
+ | `TextTransition` | ๊ธฐ๋ณธ(๋ฌธ์ž์—ด ์ „ํ™˜) | `/content-transition` | `/content-transition` |
30
+ | `ContentTransition` | ๋™๋ฐ˜(ํ•˜์œ„ ํŠธ๋ฆฌ ์ „ํ™˜, TextTransition์˜ ๊ธฐ๋ฐ˜) | `/content-transition` | `/content-transition` |
31
+
32
+ root์—์„œ๋Š” ๋‚ด๋ณด๋‚ด์ง€ ์•Š๋Š”๋‹ค. granular subpath๋กœ๋งŒ ๊ฐ€์ ธ์˜จ๋‹ค.
33
+
34
+ | renderer | ํ•„์š”ํ•œ peer(`peerDependenciesMeta` optional) |
35
+ | --- | --- |
36
+ | Web | `framer-motion` 13.4.4 (subpath๊ฐ€ ์ง์ ‘ import ํ•œ๋‹ค) |
37
+ | Native | ์—†์Œ. RN `Animated`๋งŒ ์“ด๋‹ค |
38
+
39
+ ## ์ตœ์†Œ ์‚ฌ์šฉ ์˜ˆ
40
+
41
+ ```tsx
42
+ // Web
43
+ import { TextTransition } from "@hjmds/react/content-transition";
44
+
45
+ // ์ƒํƒœ โ†’ i18n ํ‚ค ์ƒ์ˆ˜ ํ‘œ. ํ‚ค๋ฅผ ํ…œํ”Œ๋ฆฟ ๋ฌธ์ž์—ด๋กœ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค.
46
+ const uploadStatusKey = {
47
+ uploading: "upload.status.uploading",
48
+ processing: "upload.status.processing",
49
+ done: "upload.status.done",
50
+ } as const;
51
+
52
+ <TextTransition text={t(uploadStatusKey[phase])} preset="rise" />
53
+ ```
54
+
55
+ ```tsx
56
+ // Native
57
+ import { TextTransition } from "@hjmds/react-native/content-transition";
58
+
59
+ const uploadStatusKey = {
60
+ uploading: "upload.status.uploading",
61
+ processing: "upload.status.processing",
62
+ done: "upload.status.done",
63
+ } as const;
64
+
65
+ <TextTransition text={t(uploadStatusKey[phase])} preset="rise" />
66
+ ```
67
+
68
+ ## ์ถ•๊ณผ ๊ธฐ๋ณธ๊ฐ’
69
+
70
+ | prop | ๊ฐ’ | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… |
71
+ | --- | --- | --- | --- |
72
+ | `text`(ํ•„์ˆ˜) | ๋ฌธ์ž์—ด | โ€” | ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ์ „ํ™˜ํ•œ๋‹ค. ๊ฐ™์€ ๋ฌธ์ž์—ด์ด๋ฉด ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š๋Š”๋‹ค |
73
+ | `preset` | `fade` ยท `rise`(์•„๋ž˜ 12์—์„œ) ยท `slide`(๊ฐ€๋กœ 16, RTL์ด๋ฉด ๋ฐ˜๋Œ€) ยท `scale`(0.96์—์„œ) | `fade` | โ€” |
74
+ | `motion` | `system` ยท `none` | `system` | `system`์ด์–ด๋„ provider์˜ reduced motion์ด๋ฉด ์ฆ‰์‹œ ๋ฐ”๋€๋‹ค |
75
+ | `layoutStyle`(Web) | `HjmCompositionStyleProp` | โ€” | ๋ฐ”๊นฅ `<div>` ๋ฐฐ์น˜. Native์—๋Š” ์—†๋‹ค |
76
+ | `ContentTransition` `stateKey`ยท`children` | `string`ยท`ReactNode` | โ€” (ํ•„์ˆ˜) | `stateKey`๊ฐ€ ๋ฐ”๋€” ๋•Œ ํ•˜์œ„ ํŠธ๋ฆฌ๋ฅผ ์ „ํ™˜ํ•œ๋‹ค |
77
+ | `ContentTransition` `focusTarget`(Web) | `RefObject<HTMLElement \| null>` | โ€” | ์ „ํ™˜ ์ „ ํฌ์ปค์Šค๊ฐ€ ๋ฐ”๋€Œ๋Š” ํ•˜์œ„ ํŠธ๋ฆฌ ์•ˆ์— ์žˆ์—ˆ์œผ๋ฉด ์ „ํ™˜ ๋’ค ์ด ์š”์†Œ๋กœ ํฌ์ปค์Šค๋ฅผ ์˜ฎ๊ธด๋‹ค |
78
+
79
+ ์ฒซ ๋ Œ๋”์—๋Š” ๋ชจ์…˜์ด ์—†๋‹ค. ๊ธธ์ด๋Š” `motion.normal`, ๊ณก์„ ์€ `easing.enter`(foundations).
80
+
81
+ ## ๋ฐฐ์น˜
82
+
83
+ | ํ•ญ๋ชฉ | ๊ฐ’ | ๊ทผ๊ฑฐ |
84
+ | --- | --- | --- |
85
+ | ํฌ๊ธฐ | ๋ฐ”๊นฅ ์—ฌ๋ฐฑยทํฌ๊ธฐ prop์ด ์—†๋‹ค. ๋†’์ด๋Š” ์ƒˆ ๋ฌธ์ž์—ด์— ๋งž์ถฐ ์ฆ‰์‹œ ๋ฐ”๋€๋‹ค(๋†’์ด ๋ณด๊ฐ„ ์—†์Œ). ์ž๋ฆฌ๋ฅผ ๊ณ ์ •ํ•˜๋ ค๋ฉด ๋ถ€๋ชจ์— ์ตœ์†Œ ๋†’์ด๋ฅผ ์ค€๋‹ค | `react/src/content-transition.tsx`, `react-native/src/content-transition.tsx` |
86
+ | ๊ฐ„๊ฒฉ | ์œ„์น˜์™€ ์ด์›ƒ ๊ฐ„๊ฒฉ์€ ๊ฐ์‹ธ๋Š” [Stack](stack.md) ๋“ฑ์˜ `gap`์œผ๋กœ ์ค€๋‹ค | โ€” |
87
+ | ์ˆœ์„œยท์ •๋ ฌ | ๋ธ”๋ก ์š”์†Œ๋‹ค(Web `<div>` ๋‘ ๊ฒน, Native `Animated.View`). ๋ฌธ์žฅ ์ค‘๊ฐ„์— ์ธ๋ผ์ธ์œผ๋กœ ๋ผ์šฐ์ง€ ์•Š๊ณ  ํ•œ ์ค„(๋˜๋Š” ํ•œ ๋ฉ์–ด๋ฆฌ)๋กœ ๋‘”๋‹ค | `react/src/content-transition.tsx`, `react-native/src/content-transition.tsx` |
88
+ | ๊ณ ์ •ยท์Šคํฌ๋กค | ์ด๋™๋Ÿ‰์€ `rise` ์„ธ๋กœ 12, `slide` ๊ฐ€๋กœ 16์ด๋‹ค. ๋ถ€๋ชจ๊ฐ€ `overflow: hidden`์ด๋ฉด ์‹œ์ž‘ ์œ„์น˜๊ฐ€ ์ž˜๋ ค ๋ณด์ผ ์ˆ˜ ์žˆ๋‹ค | `design-contracts/src/content-transition.ts` |
89
+ | ์ข์€ ํญยทํฐ ๊ธ€์ž | ์ข์€ ํญ์—์„œ ๋ฌธ๊ตฌ ๊ธธ์ด ์ฐจ์ด๋กœ ์ค„ ์ˆ˜๊ฐ€ ๋ฐ”๋€Œ๋ฉด ์•„๋ž˜ ์š”์†Œ๊ฐ€ ํŠ„๋‹ค(ํฌ๊ธฐ ํ–‰ ์ฐธ๊ณ ) | `react/src/content-transition.tsx` |
90
+
91
+ ## ๊ผญ ์ง€ํ‚ฌ ๊ฒƒ
92
+
93
+ - ๋ฌธ์ž์—ด์€ i18n ํ‚ค๋กœ ๋งŒ๋“  ์ตœ์ข… ๋ฌธ๊ตฌ๋ฅผ ๋„˜๊ธด๋‹ค. ๊ธ€์ž ์ˆ˜ ๋ณ€ํ™”๋ฅผ ๋…ธ๋ฆฐ ์—ฐ์ถœ์šฉ์œผ๋กœ ์“ฐ์ง€ ์•Š๋Š”๋‹ค.
94
+ - ๊ธ€์ž ๋ชจ์–‘ prop์€ ์—†๋‹ค. ๊ธ€์ž ๋ชจ์–‘์€ ๊ฐ์‹ธ๋Š” ์ชฝ์ด ์ •ํ•œ๋‹ค(์•„๋ž˜ ํ”Œ๋žซํผ ์ฐจ์ด). Web์€ `layoutStyle`๋กœ ๋ฐฐ์น˜๋งŒ ํ•˜๊ณ , Native๋Š” ๋ฐฐ์น˜ prop์ด ์—†์–ด ๊ฐ์‹ธ๋Š” ์ชฝ์ด ๋ฐฐ์น˜ํ•œ๋‹ค.
95
+ - Web์—์„œ ์ด subpath๋ฅผ ์“ฐ๋ ค๋ฉด ์•ฑ์— `framer-motion`์„ ์„ค์น˜ํ•œ๋‹ค. ์—†์œผ๋ฉด import ์‹œ์ ์— ์‹คํŒจํ•œ๋‹ค.
96
+
97
+ ## ํ”Œ๋žซํผ ์ฐจ์ด
98
+
99
+ | ํ•ญ๋ชฉ | Web | Native |
100
+ | --- | --- | --- |
101
+ | ๊ธ€์ž ๋ Œ๋” | `<div>` ์•ˆ์˜ ๋งจ ํ…์ŠคํŠธ(๋ถ€๋ชจ ๊ธ€๊ผด ์ƒ์†) | HJM `Text`๋กœ ๊ฐ์‹ผ๋‹ค |
102
+ | ์ „ํ™˜ ๋ฐฉ์‹ | `stateKey`๋กœ ํ‚ค๋ฅผ ๋ฐ”๊ฟ” ์ƒˆ ๋…ธ๋“œ๋ฅผ ๋งˆ์šดํŠธ | ๊ฐ™์€ ๋…ธ๋“œ์˜ opacityยทtransform ๋ณด๊ฐ„ |
103
+ | ๋ฐฑ๊ทธ๋ผ์šด๋“œ | ํ•ด๋‹น ์—†์Œ | ์•ฑ์ด active๊ฐ€ ์•„๋‹ˆ๋ฉด ์ „ํ™˜ ์—†์ด ์ฆ‰์‹œ ํ‘œ์‹œ |
104
+ | `layoutStyle` | ์žˆ์Œ | ์—†์Œ |
@@ -0,0 +1,101 @@
1
+ # Text
2
+
3
+ - ๋‹จ๊ณ„: ์ปดํฌ๋„ŒํŠธ
4
+ - ์ƒํƒœ: ๋ฐฐํฌ
5
+ - ์ง€์›: Web ยท Native
6
+ - ์ ์šฉ: 1.12.1
7
+ - ๊ฒ€ํ† ์ผ: 2026-10-06
8
+ - ๊ทผ๊ฑฐ: `src/component-recipes.ts`(`textRecipe`), [Gravity Letters](../../gravity-letters.md)
9
+ - ์Šคํ† ๋ฆฌ๋ถ: `๋ฐฐํฌ/์ปดํฌ๋„ŒํŠธ/๊ธ€์ž์™€ ์•„์ด์ฝ˜/๋ณธ๋ฌธ ๊ธ€์ž`, `๋ฐฐํฌ/์ปดํฌ๋„ŒํŠธ/์‹œ๊ฐ ํšจ๊ณผ/์ค‘๋ ฅ ๊ธ€์ž`
10
+
11
+ ## ์–ธ์ œ ์“ฐ๋‚˜
12
+
13
+ ํ™”๋ฉด์˜ ๋ชจ๋“  ์ผ๋ฐ˜ ๊ธ€์ž์— ์“ด๋‹ค. ๋ณธ๋ฌธยท๋ณด์กฐ ์„ค๋ช…ยท์บก์…˜ยท๋ผ๋ฒจยท์นด๋“œ ์•ˆ์˜ ์ž‘์€ ์ œ๋ชฉ(24px ์ดํ•˜)์ด ์—ฌ๊ธฐ์—
14
+ ์†ํ•œ๋‹ค. ์ œํ’ˆ CSS๋กœ ํฐํŠธ ํฌ๊ธฐยท๊ตต๊ธฐยท์ƒ‰์„ ์ง์ ‘ ์“ฐ๋Š” ๋Œ€์‹  `variant`ยท`emphasis`ยท`tone`์œผ๋กœ ๊ณ ๋ฅธ๋‹ค.
15
+
16
+ ## ์“ฐ์ง€ ์•Š์„ ๋•Œ
17
+
18
+ | ์ƒํ™ฉ | ๋Œ€์‹  ์“ธ ๊ฒƒ |
19
+ | --- | --- |
20
+ | ๋ฌธ์„œ ์ œ๋ชฉ ๋‹จ๊ณ„(`h1`~)๊ฐ€ ํ•„์š”ํ•˜๊ฑฐ๋‚˜ 24px๋ณด๋‹ค ํฐ ์ œ๋ชฉ | [Heading](heading.md) |
21
+ | ํ™”๋ฉด ์ฒซ ์ž๋ฆฌ์˜ ์ œ๋ชฉ ๋ธ”๋ก(๋ณด์กฐ ๋ฌธ์žฅยทํ–‰๋™ ํฌํ•จ) | [Top](top.md) |
22
+ | ๋ณธ๋ฌธ ๋ฌถ์Œ์˜ ํ—ค๋” ํ–‰ | [Section](section.md) |
23
+ | ์ˆซ์ž ์ง€ํ‘œ์™€ ๊ทธ ๋ผ๋ฒจ | [Statistic](statistic.md) |
24
+ | ๋‹ค๋ฅธ ํ™”๋ฉดยทURL๋กœ ๊ฐ€๋Š” ๊ธ€์ž | [Link](link.md) |
25
+ | ์ˆซ์žยท๋‚ ์งœยท์ฝ”๋“œ ๊ฐ™์€ ํ˜•์‹ ๊ธ€์ž | [TextFormat](text-format.md) |
26
+ | ํ™”๋ฉด์—๋Š” ์ˆจ๊ธฐ๊ณ  ๋ณด์กฐ๊ธฐ๊ธฐ์—๋งŒ ์ฝํž ๊ธ€์ž(Web) | [VisuallyHidden](visually-hidden.md) |
27
+
28
+ Text์™€ Heading์˜ ๊ฒฝ๊ณ„: Text์˜ `variant="heading"`(24px)์€ **๋ชจ์–‘๋งŒ** ์ œ๋ชฉ์ด๊ณ  ์ œ๋ชฉ role์ด ์—†๋‹ค.
29
+ ๋ณด์กฐ๊ธฐ๊ธฐ์˜ ์ œ๋ชฉ ํƒ์ƒ‰์— ์žกํ˜€์•ผ ํ•˜๊ฑฐ๋‚˜ ๋” ํฐ ํฌ๊ธฐ๊ฐ€ ํ•„์š”ํ•˜๋ฉด Heading์„ ์“ด๋‹ค. Heading์€ ์—ฌ๋ฐฑ์„ ๊ฐ–์ง€ ์•Š๋Š”๋‹ค.
30
+
31
+ ## ๊ณต๊ฐœ ์ด๋ฆ„๊ณผ import
32
+
33
+ | ์ด๋ฆ„ | ์—ญํ•  | Web | Native |
34
+ | --- | --- | --- | --- |
35
+ | `Text` | ๊ธฐ๋ณธ | `@hjmds/react`, `/layout` | `@hjmds/react-native`, `/primitives` |
36
+ | `GravityLetters` | ํ™•์žฅ(ํ™๋ณด์šฉ ๊ธ€์ž ๋‚™ํ•˜ ์žฅ์‹, optional-extension) | `/gravity-letters` | `/gravity-letters` |
37
+
38
+ `GravityLetters`๋Š” granular subpath๋กœ๋งŒ import ๋œ๋‹ค. ์ถ”๊ฐ€ peer ์˜์กด์„ฑ์€ ์—†๋‹ค(Web์€ WAAPI, Native๋Š” RN `Animated`).
39
+
40
+ ## ์ตœ์†Œ ์‚ฌ์šฉ ์˜ˆ
41
+
42
+ ```tsx
43
+ // Web
44
+ import { Text } from "@hjmds/react/layout";
45
+
46
+ <Text as="p" variant="body" tone="muted">{t("profile.bioHint")}</Text>
47
+ ```
48
+
49
+ ```tsx
50
+ // Native
51
+ import { Text } from "@hjmds/react-native/primitives";
52
+
53
+ <Text variant="body" tone="muted" numberOfLines={2}>{t("profile.bioHint")}</Text>
54
+ ```
55
+
56
+ ## ์ถ•๊ณผ ๊ธฐ๋ณธ๊ฐ’
57
+
58
+ | prop | ๊ฐ’ | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… |
59
+ | --- | --- | --- | --- |
60
+ | `variant` | `caption`(11) ยท `label`(12) ยท `body`(14) ยท `bodyLarge`(16) ยท `title`(18) ยท `titleLarge`(20) ยท `heading`(24) | `body` | ํ™”๋ฉดยท์„น์…˜ ์ œ๋ชฉ์€ ๋ชจ์–‘์ด ์•„๋‹ˆ๋ผ [Heading](heading.md)์œผ๋กœ ์“ด๋‹ค |
61
+ | `emphasis` | `regular` ยท `medium`(semibold) ยท `strong`(bold) | `regular` | โ€” |
62
+ | `tone` | `primary` ยท `body` ยท `muted` ยท `subtle` ยท `weak` ยท `brand` ยท `danger` ยท `inverse` | `primary` | โ€” |
63
+ | `as` | `span` ยท `p` ยท `div` ยท `strong` ยท `small` | `span` | Web๋งŒ. ๋ฌธ๋‹จ์€ `as="p"` |
64
+ | `align` | `TextStyle["textAlign"]` | ์“ฐ๊ธฐ ๋ฐฉํ–ฅ์˜ ์‹œ์ž‘ ์ชฝ | Native๋งŒ |
65
+ | `layoutStyle` | `HjmCompositionStyleProp` | โ€” | ๋ฐฐ์น˜. WebยทNative ๋ชจ๋‘ |
66
+ | `GravityLetters` `glyphs` | `readonly string[]`(1~32๊ฐœ) | โ€” (ํ•„์ˆ˜) | โ€” |
67
+ | `GravityLetters` `active`ยท`replayKey` | `boolean`ยท`string \| number` | `false`ยท`0` | `replayKey`๊ฐ€ ๋ฐ”๋€Œ๋ฉด ๋‹ค์‹œ ๋–จ์–ด์ง„๋‹ค. Web๋งŒ `layoutStyle`๋„ ๋ฐ›๋Š”๋‹ค |
68
+
69
+ ## ๋ฐฐ์น˜
70
+
71
+ | ํ•ญ๋ชฉ | ๊ฐ’ | ๊ทผ๊ฑฐ |
72
+ | --- | --- | --- |
73
+ | ํฌ๊ธฐ | ํญ์€ ๋ถ€๋ชจ๋ฅผ ๋”ฐ๋ฅธ๋‹ค. ๊ธด ์ฝ๊ธฐ ๊ธ€์€ ๋ถ€๋ชจ ํญ์„ `layout.readingMaxWidth` 720 ์ดํ•˜๋กœ ๋‘”๋‹ค | `foundations.ts`(`layout`) |
74
+ | ๊ฐ„๊ฒฉ | ๋ฐ”๊นฅ ์—ฌ๋ฐฑ์ด ์—†๋‹ค(Web `margin: 0`). ๋ฌธ๋‹จ ์‚ฌ์ดยท๋ผ๋ฒจ๊ณผ ๊ฐ’ ์‚ฌ์ด ๊ฐ„๊ฒฉ์€ ๋ถ€๋ชจ [Stack](stack.md)์˜ `gap`์ด๋‚˜ `layoutStyle`๋กœ ์ค€๋‹ค. ๋ณธ๋ฌธ ๋ฌธ๋‹จ ๋ฌถ์Œ์€ ๋ณดํ†ต `spacing.xs` 8~`spacing.sm` 12, ์„น์…˜ ์‚ฌ์ด๋Š” `layout.sectionGap`(`spacing.xl` 24) | `.hjm-text`, `foundations.ts`(`layout`, `spacing`) |
75
+ | ์ˆœ์„œยท์ •๋ ฌ | Web์€ ๋ถ€๋ชจ๊ฐ€ ์ •ํ•˜๊ณ , Native๋Š” `align`(์ƒ๋žต ์‹œ ์“ฐ๊ธฐ ๋ฐฉํ–ฅ์˜ ์‹œ์ž‘ ์ชฝ)์œผ๋กœ ์ •ํ•œ๋‹ค | `react-native/src/primitives.tsx` |
76
+ | ๊ณ ์ •ยท์Šคํฌ๋กค | โ€” | โ€” |
77
+ | ์ข์€ ํญยทํฐ ๊ธ€์ž | ์ค„์ด ๋Š˜์–ด๋‚˜ ๋†’์ด๊ฐ€ ์ž๋ž€๋‹ค. ์ž๋ฅด๋ ค๋ฉด Native `numberOfLines`๋ฅผ ์“ฐ๊ณ , ํ•ต์‹ฌ ๋ฌธ๊ตฌ๋Š” ์ž๋ฅด์ง€ ์•Š๋Š”๋‹ค | `.hjm-text`(`overflow-wrap: anywhere`) |
78
+
79
+ ## ๊ผญ ์ง€ํ‚ฌ ๊ฒƒ
80
+
81
+ - ๊ธ€์ž๋Š” i18n ํ‚ค๋กœ ๋„ฃ๋Š”๋‹ค. ์ œํ’ˆ ์ด๋ฆ„ยท๋„๋ฉ”์ธ ๋ฌธ๊ตฌ๋Š” ์ œํ’ˆ ์†Œ์œ , ํฌ๊ธฐยท์ƒ‰ ์ฒด๊ณ„๋Š” HJM ์†Œ์œ ๋‹ค.
82
+ - ๋ฐฐ์น˜(์—ฌ๋ฐฑยทํญยทflex)๋Š” `layoutStyle`๋กœ๋งŒ ํ•œ๋‹ค. ์ƒ‰ยทํฌ๊ธฐยท๊ตต๊ธฐ๋Š” `style`/`className`์œผ๋กœ ๋ฎ์ง€ ์•Š๋Š”๋‹ค.
83
+ (Native Text์˜ `style`์€ layout primitive๋ผ deprecated ๊ฒฝ๊ณ  ๋Œ€์ƒ์—์„œ ๋น ์ ธ ์žˆ์„ ๋ฟ ๊ถŒ์žฅ ๊ฒฝ๋กœ๊ฐ€ ์•„๋‹ˆ๋‹ค.)
84
+ - ์ƒ‰์œผ๋กœ ์˜๋ฏธ๋ฅผ ๋ฐ”๊ฟ€ ๋•Œ๋Š” `tone`๋งŒ ์“ด๋‹ค(์˜ค๋ฅ˜ ๋ฌธ๊ตฌ `danger`, ์–ด๋‘์šด ๋ฐฐ๊ฒฝ ์œ„ `inverse`).
85
+ - `GravityLetters`๋Š” ์žฅ์‹์ด๋ฉฐ ์ ‘๊ทผ์„ฑ ํŠธ๋ฆฌ์—์„œ ์ˆจ๋Š”๋‹ค. ๊ฐ™์€ ๋ฌธ๊ตฌ์˜ ์ •์  TextยทHeading์„ ๋ฐ”๊นฅ์— ํ•จ๊ป˜ ๋‘”๋‹ค.
86
+ `glyphs`๋Š” 32๊ฐœ ์ดํ•˜, ๋นˆ ๋ฌธ์ž์—ดยท์ค„๋ฐ”๊ฟˆ ์—†์ด ๋„˜๊ธด๋‹ค(์–ด๊ธฐ๋ฉด `RangeError`). `active` ๊ธฐ๋ณธ์€ `false`๋‹ค.
87
+
88
+ ## ํ”Œ๋žซํผ ์ฐจ์ด
89
+
90
+ | ํ•ญ๋ชฉ | Web | Native |
91
+ | --- | --- | --- |
92
+ | ์š”์†Œ ์„ ํƒ | `as` | ์—†์Œ(ํ•ญ์ƒ RN `Text`) |
93
+ | ์ •๋ ฌ | ์—†์Œ(๋ฐฐ์น˜๋Š” ๋ถ€๋ชจ) | `align`(์ƒ๋žต ์‹œ ๋ฐฉํ–ฅ์— ๋งž์ถ˜ ๋…ผ๋ฆฌ ์ •๋ ฌ) |
94
+ | ๊ธ€์ž ํฌ๊ธฐ ์กฐ์ • | ๋ธŒ๋ผ์šฐ์ € | provider `textScaling`์ด `allowFontScaling`์„ ์ •ํ•จ |
95
+ | ๊ธด ๋‹จ์–ด ์ค„๋ฐ”๊ฟˆ | `overflow-wrap: anywhere` | RN ๊ธฐ๋ณธ |
96
+ | import ๊ฒฝ๋กœ | `/layout` | `/primitives` |
97
+
98
+ ## ํ•จ์ •
99
+
100
+ - `emphasis`๊ฐ€ `variant`์˜ ๊ตต๊ธฐ๋ฅผ ๋ฎ๋Š”๋‹ค. `variant="title"`๋„ ๊ธฐ๋ณธ `emphasis="regular"`๋ฉด ๋ณดํ†ต ๊ตต๊ธฐ๋กœ
101
+ ๊ทธ๋ ค์ง„๋‹ค. ๊ตต์€ ์ œ๋ชฉ์ด ํ•„์š”ํ•˜๋ฉด `emphasis="strong"`์„ ๋ช…์‹œํ•œ๋‹ค(๋‘ renderer ๋™์ผ).
@@ -0,0 +1,105 @@
1
+ # ThinkingOrb
2
+
3
+ - ๋‹จ๊ณ„: ์ปดํฌ๋„ŒํŠธ
4
+ - ์ƒํƒœ: ๋ฐฐํฌ
5
+ - ์ง€์›: Web ยท Native
6
+ - ์ ์šฉ: 1.12.1
7
+ - ๊ฒ€ํ† ์ผ: 2026-10-06
8
+ - ๊ทผ๊ฑฐ: [ThinkingOrb](../../thinking-orb.md), `src/thinking-orb-recipe.ts`(`thinkingOrbRecipe`)
9
+ - ์Šคํ† ๋ฆฌ๋ถ: `๋ฐฐํฌ/์ปดํฌ๋„ŒํŠธ/์ƒํƒœ์™€ ์•Œ๋ฆผ/์ƒ๊ฐ ์ค‘ ํ‘œ์‹œ`
10
+
11
+ ## ์–ธ์ œ ์“ฐ๋‚˜
12
+
13
+ AI ์—์ด์ „ํŠธ๊ฐ€ ์‹ค์ œ๋กœ ๊ฒ€์ƒ‰ยท์ƒ์„ฑยท๋“ฃ๊ธฐ ๊ฐ™์€ ์ž‘์—…์„ ํ•˜๋Š” ๋™์•ˆ ๊ทธ ๋‹จ๊ณ„๋ฅผ ๋ณด์—ฌ ์ค„ ๋•Œ๋งŒ ์“ด๋‹ค.
14
+ ์ƒํƒœ(`state`)๋Š” ์•ฑ์ด ์‹ค์ œ ์ž‘์—… ๋‹จ๊ณ„์—์„œ ๋„˜๊ธด๋‹ค. orb๊ฐ€ ์ง„ํ–‰๋ฅ ์„ ํ‰๋‚ด ๋‚ด์ง€ ์•Š๋Š”๋‹ค.
15
+
16
+ ## ์“ฐ์ง€ ์•Š์„ ๋•Œ
17
+
18
+ | ์ƒํ™ฉ | ๋Œ€์‹  ์“ธ ๊ฒƒ |
19
+ | --- | --- |
20
+ | ์ผ๋ฐ˜ ๋กœ๋”ฉยท๋Œ€๊ธฐ | [Spinner](spinner.md) |
21
+ | ์ง„ํ–‰๋ฅ ์„ ์•„๋Š” ์ž‘์—… | [Progress](progress.md) |
22
+ | ์ฝ˜ํ…์ธ  ์ž๋ฆฌ ํ‘œ์‹œ | [Skeleton](skeleton.md) |
23
+ | ์™„๋ฃŒยท์˜ค๋ฅ˜ ๊ฒฐ๊ณผ | [Result](result.md), [Toast](toast.md) โ€” orb๋ฅผ ๊ฒฐ๊ณผ UI๋กœ ๊ต์ฒดํ•œ๋‹ค |
24
+
25
+ ## ๊ณต๊ฐœ ์ด๋ฆ„๊ณผ import
26
+
27
+ | ์ด๋ฆ„ | ์—ญํ•  | Web | Native |
28
+ | --- | --- | --- | --- |
29
+ | `ThinkingOrb` | ๊ธฐ๋ณธ(root์—์„œ๋Š” ๋‚ด๋ณด๋‚ด์ง€ ์•Š๋Š”๋‹ค) | `/thinking-orb` | `/thinking-orb` |
30
+
31
+ granular subpath๋กœ๋งŒ ๊ฐ€์ ธ์˜จ๋‹ค. Native subpath๋Š” optional native peer๋ฅผ ์ง์ ‘ import ํ•œ๋‹ค.
32
+
33
+ | renderer | ํ•„์š”ํ•œ peer(`peerDependenciesMeta` optional) |
34
+ | --- | --- |
35
+ | Web | ์—†์Œ(Canvas 2D) |
36
+ | Native | `@shopify/react-native-skia` ^2.6.2, `react-native-reanimated` ^4.5.1์™€ ๊ทธ ์ „์ œ `react-native-worklets` ^0.10.1. ๋ชจ๋‘ native ๋ชจ๋“ˆ์ด๋ผ ์„ค์น˜ ํ›„ dev client๋ฅผ ๋‹ค์‹œ ๋นŒ๋“œํ•œ๋‹ค |
37
+
38
+ ๊ณ„์•ฝ ๋ฌธ์„œ๊ฐ€ ๊ฒ€์ฆ ๋Œ€์ƒ์œผ๋กœ ์ ์€ ์กฐํ•ฉ์€ Expo 57 / RN 0.86.2๋‹ค. ๊ธฐ๋ณธ ํŒจํ‚ค์ง€์˜ `react-native >=0.81`
39
+ ๋ฒ”์œ„๊ฐ€ ์ด subpath์˜ ์ง€์›์„ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.
40
+
41
+ ## ์ตœ์†Œ ์‚ฌ์šฉ ์˜ˆ
42
+
43
+ ```tsx
44
+ // Web
45
+ import { ThinkingOrb } from "@hjmds/react/thinking-orb";
46
+
47
+ <ThinkingOrb state="searching" label={t("agent.searching")} />
48
+ ```
49
+
50
+ ```tsx
51
+ // Native
52
+ import { ThinkingOrb } from "@hjmds/react-native/thinking-orb";
53
+
54
+ <ThinkingOrb state="searching" size={20} label={t("agent.searching")} active={isFocused} />
55
+ ```
56
+
57
+ ## ์ถ•๊ณผ ๊ธฐ๋ณธ๊ฐ’
58
+
59
+ | prop | ๊ฐ’ | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… |
60
+ | --- | --- | --- | --- |
61
+ | `state` | `working` ยท `searching` ยท `solving` ยท `listening` ยท `connecting` ยท `weaving` ยท `composing` ยท `breathing` ยท `shaping` | `working` | `listening`์€ ์Œ์„ฑ ํฌ๊ธฐ ์‹œ๊ฐํ™”๊ฐ€ ์•„๋‹ˆ๋‹ค |
62
+ | `appearance` | `state`(์ƒํƒœ๋ณ„ ๊ธฐํ•˜) ยท `fluid` ยท `matrix` | `state` | โ€” |
63
+ | `size` | `64` ยท `20` | `64` | ๋‹ค๋ฅธ ๊ฐ’์€ `RangeError` |
64
+ | `label`(ํ•„์ˆ˜) | ๋ฒˆ์—ญ๋œ ํ˜„์žฌ ์ž‘์—… ์„ค๋ช… | โ€” | ๋น„๊ฑฐ๋‚˜ ๊ณต๋ฐฑ์ด๋ฉด `TypeError` |
65
+ | `speed` | 0 ์ดˆ๊ณผ 4 ์ดํ•˜ | `1` | โ€” |
66
+ | `paused` | `boolean` | `false` | โ€” |
67
+ | `active` | `boolean` | `true` | โ€” |
68
+ | `layoutStyle`(Web) | `HjmCompositionStyleProp` | โ€” | ๋ฐ”๊นฅ ์š”์†Œ ๋ฐฐ์น˜. `style`๊ณผ ๊ฒน์น˜๋ฉด `layoutStyle`์ด ์ด๊ธด๋‹ค |
69
+ | `style` | Web `CSSProperties`, Native `StyleProp<ViewStyle>` | โ€” | Native๋Š” `layoutStyle`์ด ์—†์–ด `style`์ด ๋ฐฐ์น˜ ํ†ต๋กœ๋‹ค(optional motion host frame์ด๋ผ deprecated ๋Œ€์ƒ์—์„œ ๋น ์กŒ๋‹ค). ๋ฐฐ์น˜ key๋งŒ ๋„ฃ๋Š”๋‹ค |
70
+
71
+ ์ƒ‰์€ provider์˜ `text` ์ƒ‰์„ ๊นŠ์ด๋ณ„ opacity๋กœ ์“ด๋‹ค. ์ƒ‰ prop์€ ์—†๋‹ค.
72
+
73
+ ## ๋ฐฐ์น˜
74
+
75
+ | ํ•ญ๋ชฉ | ๊ฐ’ | ๊ทผ๊ฑฐ |
76
+ | --- | --- | --- |
77
+ | ํฌ๊ธฐ | ์ •์‚ฌ๊ฐํ˜• ๊ณ ์ • ํฌ๊ธฐ `size` 20 ๋˜๋Š” 64. ์•ˆ์ชฝยท๋ฐ”๊นฅ ์—ฌ๋ฐฑ์ด ์—†๋‹ค. ๋ˆ„๋ฅผ ์ˆ˜ ์—†๋Š” ํ‘œ์‹œ๋ผ ํ„ฐ์น˜ ์˜์—ญ ์š”๊ตฌ๊ฐ€ ์—†๋‹ค | `thinkingOrbRecipe`(`sizes: [20, 64]`) |
78
+ | ๊ฐ„๊ฒฉ | ๋ฌธ๊ตฌ์™€ ๋‚˜๋ž€ํžˆ ๋‘˜ ๋•Œ ๊ฐ„๊ฒฉ์€ ๊ฐ์‹ธ๋Š” [Stack](stack.md)์˜ `gap`(์˜ˆ: `spacing.xs` 8)์œผ๋กœ ์ค€๋‹ค | โ€” |
79
+ | ์ˆœ์„œยท์ •๋ ฌ | 20์€ ์ž‘์—… ๋ฌธ๊ตฌ ํ•œ ์ค„๊ณผ ๋‚˜๋ž€ํžˆ, 64๋Š” ์˜์—ญ ๊ฐ€์šด๋ฐ ๋‹จ๋…์œผ๋กœ ๋‘”๋‹ค. Web ๋ฐ”๊นฅ ์š”์†Œ๋Š” `inline-flex`๋ผ ๊ธ€์ค„ ์•ˆ์—๋„ ๋†“์ธ๋‹ค. ๋ฒ„ํŠผ ์•ˆ ๋กœ๋”ฉ ํ‘œ์‹œ๋กœ ์“ฐ์ง€ ์•Š๋Š”๋‹ค(๋ฒ„ํŠผ์€ `loading`). ์ž‘์—…์ด ๋๋‚˜๋ฉด ๊ฐ™์€ ์ž๋ฆฌ๋ฅผ ๊ฒฐ๊ณผ UI๋กœ ๋ฐ”๊พธ๊ณ  orb์™€ ๊ฒฐ๊ณผ๋ฅผ ํ•จ๊ป˜ ๋‘์ง€ ์•Š๋Š”๋‹ค | `react/src/thinking-orb.tsx` |
80
+ | ๊ณ ์ •ยท์Šคํฌ๋กค | โ€” | โ€” |
81
+ | ์ข์€ ํญยทํฐ ๊ธ€์ž | ํฐ ๊ธ€์ž ์„ค์ •์—๋„ ํฌ๊ธฐ๊ฐ€ ๋ณ€ํ•˜์ง€ ์•Š๋Š”๋‹ค | `react/src/thinking-orb.tsx`, `react-native/src/thinking-orb.tsx` |
82
+
83
+ ## ๊ผญ ์ง€ํ‚ฌ ๊ฒƒ
84
+
85
+ - Native์—์„œ๋Š” ํƒญยท๋‚ด๋น„๊ฒŒ์ด์…˜ยท๊ฐ€์ƒ ๋ชฉ๋ก์—์„œ ํ™”๋ฉด์ด ๊ฐ€๋ ค์ง€๋ฉด `active={false}`๋ฅผ ๋„˜๊ธด๋‹ค.
86
+ mounted ์ƒํƒœ๋กœ ์ˆจ์€ ํ™”๋ฉด์€ AppState๋กœ ์•Œ ์ˆ˜ ์—†์–ด ๊ณ„์† ๊ทธ๋ฆฐ๋‹ค.
87
+ - orb๊ฐ€ live region(Web `role="status"`, Native progressbar + `accessibilityLiveRegion`)์ด๋‹ค.
88
+ ๊ฐ™์€ ๋ฌธ๊ตฌ๋ฅผ ์˜†์— ๋˜ ๋ณด์—ฌ ์ค„ ๋•Œ ๊ทธ ๋ฌธ๊ตฌ์— live region์„ ์ค‘๋ณต์œผ๋กœ ๋‘์ง€ ์•Š๋Š”๋‹ค.
89
+ - ํฌ๊ธฐ๋Š” `size`๋กœ๋งŒ ๋ฐ”๊พผ๋‹ค. CSSยทtransform์œผ๋กœ ํ™•๋Œ€ํ•˜์ง€ ์•Š๋Š”๋‹ค.
90
+ - ๋ฐฐ์น˜๋Š” Web `layoutStyle`, Native `style`๋กœ ํ•˜๊ณ  ๋ฐฐ์น˜ key(marginยท`alignSelf` ๋“ฑ)๋งŒ ๋„ฃ๋Š”๋‹ค. Web `className`ยท`style`๋กœ ํฌ๊ธฐยท์ƒ‰์„ ๋ฐ”๊พธ์ง€ ์•Š๋Š”๋‹ค.
91
+
92
+ ## ํ”Œ๋žซํผ ์ฐจ์ด
93
+
94
+ | ํ•ญ๋ชฉ | Web | Native |
95
+ | --- | --- | --- |
96
+ | ๊ทธ๋ฆฌ๊ธฐ | Canvas 2D, ๋ณด์ด์ง€ ์•Š์œผ๋ฉด(IntersectionObserverยท๋ฌธ์„œ ์ˆจ๊น€) ์ •์ง€ | Skia Picture, ๋ฐฑ๊ทธ๋ผ์šด๋“œยท`active=false`๋ฉด ์ •์ง€ |
97
+ | ๋ชจ์…˜ ์ค„์ด๊ธฐ | provider `reducedMotion` | provider ๊ฐ’ ๋˜๋Š” OS ์„ค์ •. OS ๊ฐ’์„ ์ฝ๊ธฐ ์ „์—๋Š” ์ •์ง€ ํ”„๋ ˆ์ž„์œผ๋กœ ์‹œ์ž‘ |
98
+ | ์ ‘๊ทผ์„ฑ | `role="status"` + ์ˆจ๊ธด ํ…์ŠคํŠธ | `accessibilityRole="progressbar"`, `busy: true` |
99
+ | ์ถ”๊ฐ€ prop | `className`, `layoutStyle` | `testID`(`layoutStyle` ์—†์Œ) |
100
+
101
+ ## ํ•จ์ •
102
+
103
+ - 2026-10 ์†Œ๋น„ ์•ฑ์—์„œ ์ด subpath๋ฅผ ์“ฐ๋ฉด์„œ SkiaยทReanimated ๊ฐ™์€ optional native peer๋ฅผ
104
+ ์„ค์น˜ํ•˜์ง€ ์•Š์•„ tscยทํ…Œ์ŠคํŠธ๋Š” ํ†ต๊ณผํ–ˆ๋Š”๋ฐ ๊ธฐ๊ธฐ Metro์—์„œ ํฌ๋ž˜์‹œ๊ฐ€ ๋‚ฌ๋‹ค. ํƒ€์ž… ๊ฒ€์‚ฌ๋Š” peer ์„ค์น˜๋ฅผ
105
+ ์ฆ๋ช…ํ•˜์ง€ ์•Š๋Š”๋‹ค. Native ์ฑ„ํƒ ์ „์— ์œ„ peer๋ฅผ ์•ฑ `package.json`์— ๋„ฃ๊ณ  ์„ค์น˜ ์•ฑ์—์„œ ์‹ค์ œ๋กœ ๊ทธ๋ ค์ง€๋Š”์ง€ ํ™•์ธํ•œ๋‹ค.
@@ -0,0 +1,105 @@
1
+ # Timeline
2
+
3
+ - ๋‹จ๊ณ„: ์ปดํฌ๋„ŒํŠธ
4
+ - ์ƒํƒœ: ๋ฐฐํฌ
5
+ - ์ง€์›: Web ยท Native
6
+ - ์ ์šฉ: 1.12.1
7
+ - ๊ฒ€ํ† ์ผ: 2026-10-06
8
+ - ๊ทผ๊ฑฐ: [Timeline](../../timeline.md), `src/timeline.ts`(`timelineRecipe`)
9
+ - ์Šคํ† ๋ฆฌ๋ถ: `๋ฐฐํฌ/์ปดํฌ๋„ŒํŠธ/๋ฐ์ดํ„ฐ ํ‘œ์‹œ/ํƒ€์ž„๋ผ์ธ`
10
+
11
+ ## ์–ธ์ œ ์“ฐ๋‚˜
12
+
13
+ ์ด๋ฏธ ์ผ์–ด๋‚œ ์ผ์„ ์‹œ๊ฐ„ ์ˆœ์„œ๋Œ€๋กœ ๋ณด์—ฌ ์ค„ ๋•Œ ์“ด๋‹ค. ๊ฒฝ๊ธฐ ํ”Œ๋ ˆ์ด ๊ธฐ๋ก, ์ด์ ยท๋ณ€๊ฒฝ ์ด๋ ฅ, ์ฃผ๋ฌธ ์ฒ˜๋ฆฌ
14
+ ๊ธฐ๋ก์ฒ˜๋Ÿผ "๋ฌด์Šจ ์ผ์ด ์–ธ์ œ ์žˆ์—ˆ๋‚˜"๋ฅผ ์œ„โ†’์•„๋ž˜ ํ•œ ๋ฐฉํ–ฅ์œผ๋กœ ๋‚˜์—ดํ•œ๋‹ค. ํ˜„์žฌ ์œ„์น˜(์ปค์„œ)๋Š” ์—†๋‹ค.
15
+
16
+ ## ์“ฐ์ง€ ์•Š์„ ๋•Œ
17
+
18
+ | ์ƒํ™ฉ | ๋Œ€์‹  ์“ธ ๊ฒƒ |
19
+ | --- | --- |
20
+ | ํ๋ฆ„์—์„œ ์ง€๊ธˆ ์–ด๋””์— ์žˆ๋Š”์ง€(ํ˜„์žฌ ๋‹จ๊ณ„) | [Steps](steps.md) |
21
+ | ํ•ญ๋ชฉ์„ ๋ˆŒ๋Ÿฌ ์ด๋™ยท์„ ํƒ | [List](list.md), [ListRow](list-row.md) |
22
+ | ํ•ญ๋ชฉ์ด ํ•˜๋‚˜๋„ ์—†์Œ | Timeline์„ ๋งˆ์šดํŠธํ•˜์ง€ ์•Š๊ณ  [EmptyState](empty-state.md) |
23
+ | ๊ณผ๊ฑฐ ๊ธฐ๋ก์„ ๋” ๋ถˆ๋Ÿฌ์˜ด | Timeline ์•„๋ž˜์— [LoadMore](load-more.md)๋ฅผ ํ•ฉ์„ฑ |
24
+ | ํ•ญ๋ชฉ๋ณ„ ์งง์€ ๋ฐฐ์ง€ | ์ƒˆ ํ•„๋“œ ์—†์Œ. ์ œํ’ˆ ํ™”๋ฉด์—์„œ [Tag](tag.md)๋กœ ์กฐํ•ฉ |
25
+
26
+ ## ๊ณต๊ฐœ ์ด๋ฆ„๊ณผ import
27
+
28
+ | ์ด๋ฆ„ | ์—ญํ•  | Web | Native |
29
+ | --- | --- | --- | --- |
30
+ | `Timeline` | ๊ธฐ๋ณธ | `@hjmds/react`, `/display` | `@hjmds/react-native`, `/data-display` |
31
+
32
+ ํ•ญ๋ชฉ ํƒ€์ž… `TimelineItemDescriptor`๋Š” `@hjmds/design-contracts/components/timeline`์— ์žˆ๋‹ค.
33
+
34
+ ## ์ตœ์†Œ ์‚ฌ์šฉ ์˜ˆ
35
+
36
+ ```tsx
37
+ // Web
38
+ import { Timeline } from "@hjmds/react/display";
39
+
40
+ // ์ƒํƒœ โ†’ i18n ํ‚ค ์ƒ์ˆ˜ ํ‘œ. ํ‚ค๋ฅผ ํ…œํ”Œ๋ฆฟ ๋ฌธ์ž์—ด๋กœ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค.
41
+ const playEventKey = {
42
+ hit: "pbp.event.hit",
43
+ out: "pbp.event.out",
44
+ run: "pbp.event.run",
45
+ } as const;
46
+
47
+ <Timeline
48
+ items={plays.map((play) => ({
49
+ id: play.id,
50
+ label: t(playEventKey[play.kind]),
51
+ timestamp: formatInning(play.inning), // ์ œํ’ˆ์ด ํฌ๋งทํ•œ ๋ฌธ์ž์—ด
52
+ tone: play.scored ? "success" : "neutral",
53
+ }))}
54
+ composeAccessibleName={({ position, total, label }) =>
55
+ t("pbp.itemA11y", { position, total, label })}
56
+ />
57
+ ```
58
+
59
+ ```tsx
60
+ // Native
61
+ import { Timeline } from "@hjmds/react-native/data-display";
62
+
63
+ <Timeline
64
+ items={items}
65
+ composeAccessibleName={({ position, total, label }) =>
66
+ t("pbp.itemA11y", { position, total, label })}
67
+ />
68
+ ```
69
+
70
+ ## ์ถ•๊ณผ ๊ธฐ๋ณธ๊ฐ’
71
+
72
+ | prop | ๊ฐ’ | ๊ธฐ๋ณธ๊ฐ’ | ์„ค๋ช… |
73
+ | --- | --- | --- | --- |
74
+ | `items`(ํ•„์ˆ˜) | `id`ยท`label` ํ•„์ˆ˜, `timestamp`ยท`description`ยท`tone` ์„ ํƒ | โ€” | ๋ฐฐ์—ด ์ˆœ์„œ๊ฐ€ ๊ณง ํ‘œ์‹œ ์ˆœ์„œ |
75
+ | `items[].tone` | `neutral` ยท `info` ยท `success` ยท `attention` | `neutral` | `warning`ยท`danger`๋Š” ์—†๋‹ค |
76
+ | `composeAccessibleName`(ํ•„์ˆ˜) | `(info: { position: number, total: number, label: string }) => string` | โ€” | position์€ 1๋ถ€ํ„ฐ |
77
+ | `layoutStyle` | `HjmCompositionStyleProp` | โ€” | ๋ฃจํŠธ ๋ฐฐ์น˜. WebยทNative ๋ชจ๋‘ |
78
+ | `style`(Native) | `StyleProp<ViewStyle>` | โ€” | deprecated โ€” `layoutStyle`. ๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ ํ•œ ๋ฒˆ ๊ฒฝ๊ณ ํ•˜๊ณ  ๋‹ค์Œ major์—์„œ ์ œ๊ฑฐ๋œ๋‹ค |
79
+ | ๋‚˜๋จธ์ง€ | Web `<ol>` ์†์„ฑ, Native `ViewProps`(`style` ์ œ์™ธ) | โ€” | โ€” |
80
+
81
+ ## ๋ฐฐ์น˜
82
+
83
+ | ํ•ญ๋ชฉ | ๊ฐ’ | ๊ทผ๊ฑฐ |
84
+ | --- | --- | --- |
85
+ | ํฌ๊ธฐ | ๊ฐ ํ•ญ๋ชฉ์€ [๋ ˆ์ผ 16][๋ณธ๋ฌธ] ๋‘ ์—ด. ๋ ˆ์ผ์€ ์ง€๋ฆ„ 10์˜ dot๊ณผ ๋‹ค์Œ ํ•ญ๋ชฉ๊นŒ์ง€ ์ด์–ด์ง€๋Š” 1px connector. ํ•ญ๋ชฉ์€ ๋ˆ„๋ฅผ ์ˆ˜ ์—†์–ด ํ„ฐ์น˜ ์˜์—ญ ์š”๊ตฌ๊ฐ€ ์—†๊ณ  ํ–‰ ์•ˆ์— ๋ฒ„ํŠผ์„ ๋„ฃ์ง€ ์•Š๋Š”๋‹ค | `timelineRecipe`, `.hjm-timeline__item`ยท`__dot`ยท`__connector` |
86
+ | ๊ฐ„๊ฒฉ | ํ•ญ๋ชฉ ์‚ฌ์ด `spacing.md` 16, ๋ ˆ์ผ๊ณผ ๋ณธ๋ฌธ ์—ด ๊ฐ„๊ฒฉ `spacing.sm` 12, ๋ณธ๋ฌธ ์ค„ ๊ฐ„๊ฒฉ `spacing.xxs` 4 | `timelineRecipe.gap`, `.hjm-timeline*` |
87
+ | ์ˆœ์„œยท์ •๋ ฌ | ๋ณธ๋ฌธ์€ labelยทtimestamp ์ค„ โ†’ description. Web์€ label๊ณผ timestamp๋ฅผ ํ•œ ์ค„ ์–‘ ๋์— ๋‘”๋‹ค | `.hjm-timeline__heading` |
88
+ | ๊ณ ์ •ยท์Šคํฌ๋กค | ๋ณธ๋ฌธ ์Šคํฌ๋กค ์˜์—ญ ์•ˆ์˜ ํ•œ ์„น์…˜์œผ๋กœ ํญ์„ ๊ฝ‰ ์ฑ„์šด๋‹ค. ๋” ๋ถˆ๋Ÿฌ์˜ค๊ธฐ๋Š” Timeline ์•„๋ž˜์— [LoadMore](load-more.md) | โ€” |
89
+ | ์ข์€ ํญยทํฐ ๊ธ€์ž | Web์€ ์ข์œผ๋ฉด timestamp๊ฐ€ ๋‹ค์Œ ์ค„๋กœ ๋‚ด๋ ค๊ฐ„๋‹ค(`flex-wrap`). ํฐ ๊ธ€์ž์—์„œ๋„ ๊ธ€์„ ์ž๋ฅด์ง€ ์•Š๋Š”๋‹ค | `.hjm-timeline__heading`ยท`__label` |
90
+
91
+ ## ๊ผญ ์ง€ํ‚ฌ ๊ฒƒ
92
+
93
+ - `timestamp`ยท`description`์€ ์ œํ’ˆ์ด ๋‚ ์งœยท์ด๋‹์„ ์ด๋ฏธ ํฌ๋งทํ•œ ๋ฌธ์ž์—ด์ด๋‹ค. Timeline์€ ์‹œ๊ฐ„ ๊ณ„์‚ฐ์„ ํ•˜์ง€ ์•Š๋Š”๋‹ค.
94
+ - ๋นˆ ๋ฐฐ์—ด, ์ค‘๋ณต `id`, ์•ž๋’ค ๊ณต๋ฐฑ์ด ์žˆ๋Š” `id`, ๋นˆ ๋ฌธ์ž์—ด ํ•„๋“œ, ๋ชฉ๋ก ๋ฐ– tone์€ ์‹คํ–‰ ์ค‘ ์˜ค๋ฅ˜๋ฅผ ๋˜์ง„๋‹ค.
95
+ - ์ ‘๊ทผ ์ด๋ฆ„์˜ ์–ด์ˆœ์€ ์–ธ์–ด๋งˆ๋‹ค ๋‹ค๋ฅด๋ฏ€๋กœ `composeAccessibleName`์€ i18n ํ‚ค๋กœ ๋งŒ๋“ ๋‹ค.
96
+ - ์ œํ’ˆ ๊ณ ์œ  ์ƒ‰(๊ตฌ๋‹จ ์ƒ‰ ๋“ฑ)์€ adapter์—์„œ ๋„ค tone ์ค‘ ํ•˜๋‚˜๋กœ ๋จผ์ € ๋งคํ•‘ํ•œ๋‹ค. dot ์ƒ‰์„ ์ง์ ‘ ์น ํ•˜์ง€ ์•Š๋Š”๋‹ค.
97
+ - ๋ฐฐ์น˜๋Š” `layoutStyle`๋กœ ํ•œ๋‹ค. Web `className`/`style`๊ณผ Native์˜ deprecated `style`๋กœ dotยทconnectorยท๊ธ€์ž ์ƒ‰์„ ๋ฎ์ง€ ์•Š๋Š”๋‹ค.
98
+
99
+ ## ํ”Œ๋žซํผ ์ฐจ์ด
100
+
101
+ | ํ•ญ๋ชฉ | Web | Native |
102
+ | --- | --- | --- |
103
+ | ๊ตฌ์กฐ | `<ol>` / `<li>`, dotยทconnector `aria-hidden` | `View` ํ–‰, railยท๋ณธ๋ฌธ์€ ์ ‘๊ทผ์„ฑ ํŠธ๋ฆฌ์—์„œ ์ˆจ๊น€ |
104
+ | ํ•ญ๋ชฉ ์ ‘๊ทผ ์ด๋ฆ„ | `<li aria-label={accessibleName}>` | `accessibleName, timestamp, description`์„ ์ด์–ด ๋ถ™์ธ `accessibilityLabel` |
105
+ | ref | `HTMLOListElement`๋กœ ์ „๋‹ฌ | ์—†์Œ(ํ•จ์ˆ˜ ์ปดํฌ๋„ŒํŠธ) |