@hjmds/design-contracts 1.12.0 → 1.13.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 (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 +25 -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 +17 -0
  16. package/dist/component-recipes.d.ts.map +1 -1
  17. package/dist/component-recipes.js +5 -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 +376 -0
  67. package/docs/sheet.md +12 -0
  68. package/docs/splitter.md +8 -2
  69. package/docs/theming.md +36 -29
  70. package/docs/toggle-group.md +7 -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 +104 -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 +215 -0
  169. package/docs/usage/components/section.md +111 -0
  170. package/docs/usage/components/segmented-control.md +138 -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 +151 -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 +274 -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,74 @@
1
+ # 크기
2
+
3
+ - 단계: 토큰
4
+ - 상태: 배포
5
+ - 지원: Web · Native
6
+ - 적용: 1.12.1
7
+ - 검토일: 2026-10-06
8
+ - 근거: `src/foundations.ts`(`glyph`·`control`), `src/component-recipes.ts`(`iconRecipe`·`spinnerRecipe`·`chipRecipe`·`avatarRecipe`·`skeletonRecipe`), `src/base-recipes.ts`(`buttonRecipe`), `src/design-system-provider.ts`(`visibleControlHeight`), `packages/react/src/theme.ts`
9
+ - 스토리북: `배포/토큰/공간과 크기/크기`
10
+
11
+ ## 언제 쓰나
12
+
13
+ 아이콘·작은 그림(glyph)의 크기와 누를 수 있는 컨트롤의 높이·최소 터치 영역을 정할 때 쓴다. 모든 버튼의 폭이나 화면 요소의
14
+ 크기를 뜻하지 않는다. 화면 폭·행 높이는 [화면 여백과 너비](layout.md)에 있다.
15
+
16
+ ## 값
17
+
18
+ ### glyph(아이콘·작은 그림)
19
+
20
+ | 토큰 | 값 | Web CSS 변수 | Native 경로 | 용도 |
21
+ | --- | --- | --- | --- | --- |
22
+ | `glyph.xs` | 14 | — | `glyph.xs` | Spinner `small` |
23
+ | `glyph.sm` | 20 | — | `glyph.sm` | Spinner `medium`(기본), 작은 아이콘 |
24
+ | `glyph.md` | 24 | — | `glyph.md` | Icon 기본 크기, Steps 표지 |
25
+ | `glyph.lg` | 28 | — | `glyph.lg` | Spinner `large`, EmptyState 아이콘 |
26
+ | `glyph.xl` | 32 | — | `glyph.xl` | 큰 아이콘 |
27
+ | `glyph.xxl` | 44 | — | `glyph.xxl` | Skeleton 원 기본 지름, Calendar `large` 날짜 칸 지름 |
28
+ | `glyph.xxxl` | 48 | — | `glyph.xxxl` | 가장 큰 아이콘 |
29
+
30
+ Icon의 `size` prop은 이 이름(`"md"`)을 받는다. Avatar는 glyph가 아니라 자기 크기(`small` 32 · `medium` 40 · `large` 48 · `xlarge` 64)를 쓴다.
31
+
32
+ ### control(컨트롤 높이·터치 영역)
33
+
34
+ | 토큰 | 값 | Web CSS 변수 | Native 경로 | 용도 |
35
+ | --- | --- | --- | --- | --- |
36
+ | `control.minTouchTarget` | 44 | `--hjm-control-min-touch-target` | `control.minTouchTarget` | 누를 수 있는 모든 것의 최소 터치 영역(가로·세로). ListRow `compact` 한 줄, Calendar `medium` 칸 |
37
+ | `control.buttonHeight.small` | 36 | `--hjm-control-button-small` | `control.buttonHeight.small` | Button `size="small"`. `control.buttonHitSlop.small` 4를 더해 터치 영역 44 |
38
+ | `control.buttonHeight.medium` | 44 | `--hjm-control-button-medium` | `control.buttonHeight.medium` | Button `size="medium"`(기본) |
39
+ | `control.buttonHeight.large` | 52 | `--hjm-control-button-large` | `control.buttonHeight.large` | Button `size="large"`, 화면 하단 주 행동 |
40
+ | `control.fieldHeight` | 44 | `--hjm-control-field-height` | `control.fieldHeight` | 한 줄 입력 필드 높이 |
41
+ | `control.chipHeight.small` | 36 | — | `control.chipHeight.small` | Chip `size="small"` |
42
+ | `control.chipHeight.medium` | 44 | — | `control.chipHeight.medium` | Chip `size="medium"` |
43
+ | `control.selectionIndicator` | 24 | — | `control.selectionIndicator` | Checkbox·Radio 표지 상자 |
44
+
45
+ Provider의 `minimumVisualTarget`을 켜면 보이는 버튼 높이가 44보다 작아지지 않는다(`small`도 44). Web은 `--hjm-control-button-*`에 반영된다.
46
+ Native 경로의 `glyph`·`control`은 `@hjmds/design-contracts/foundations` import다.
47
+
48
+ ## 쓰는 법
49
+
50
+ ```tsx
51
+ // Web
52
+ import { Icon } from "@hjmds/react/display";
53
+
54
+ <Icon name="search" size="sm" />
55
+ // 제품 고유 누름 영역: .product-tile { min-block-size: var(--hjm-control-min-touch-target); }
56
+ ```
57
+
58
+ ```tsx
59
+ // Native
60
+ import { Pressable } from "react-native";
61
+ import { control, glyph } from "@hjmds/design-contracts/foundations";
62
+
63
+ <Pressable style={{ minHeight: control.minTouchTarget, minWidth: control.minTouchTarget }} onPress={open}>
64
+ <ProductMark width={glyph.md} height={glyph.md} />
65
+ </Pressable>
66
+ ```
67
+
68
+ 아이콘 사용법은 [Icon](../components/icon.md), 버튼 크기 선택은 [Button 배치](../components/button.md#배치)를 본다.
69
+
70
+ ## 하지 말 것
71
+
72
+ - 누를 수 있는 영역을 44보다 작게 만들지 않는다. 그림이 작으면 hitSlop·padding으로 터치 영역을 44로 맞춘다.
73
+ - Button·필드 높이를 `style`로 바꾸지 않는다. `size` prop으로만 고른다.
74
+ - 아이콘 크기에 18, 22 같은 새 숫자를 쓰지 않는다.
@@ -0,0 +1,73 @@
1
+ # 간격
2
+
3
+ - 단계: 토큰
4
+ - 상태: 배포
5
+ - 지원: Web · Native
6
+ - 적용: 1.12.1
7
+ - 검토일: 2026-10-06
8
+ - 근거: `src/foundations.ts`(`spacing`·`layout`), `src/grid.ts`(`gridGaps`), `src/base-recipes.ts`(`buttonRecipe`·`fieldRecipe`), `src/auth-screen.ts`, `packages/react/src/theme.ts`, `packages/react/src/styles.css`
9
+ - 스토리북: `배포/토큰/공간과 크기/간격`
10
+
11
+ ## 언제 쓰나
12
+
13
+ 요소 사이 간격(gap)과 영역 안쪽 여백(padding)을 정할 때 쓴다. 숫자는 Web에서 CSS px, Native에서 dp(pt)다.
14
+ 화면 좌우 여백·최대 폭은 이 값을 묶어 이름을 붙인 [화면 여백과 너비](layout.md)를 먼저 본다.
15
+
16
+ ## 값
17
+
18
+ | 토큰 | 값 | Web CSS 변수 | Native 경로 | 용도 |
19
+ | --- | --- | --- | --- | --- |
20
+ | `spacing.xxs` | 4 | `--hjm-space-xxs` | `spacing.xxs` · `theme.tokens.spacing.xxs` | 목록 팝업 안쪽 여백(Select·Menubar) |
21
+ | `spacing.xs` | 8 | `--hjm-space-xs` | `spacing.xs` · `theme.tokens.spacing.xs` | 필드 라벨과 입력 사이, DatePicker 팝업과 입력 사이, EmptyState 안 요소 사이 |
22
+ | `spacing.sm` | 12 | `--hjm-space-sm` | `spacing.sm` · `theme.tokens.spacing.sm` | 나란한 버튼 사이, Toast 사이, small 버튼 좌우·필드 위아래 안쪽 여백 |
23
+ | `spacing.md` | 16 | `--hjm-space-md` | `spacing.md` · `theme.tokens.spacing.md` | Stack·Grid 기본 gap, medium 버튼·필드 좌우 안쪽 여백, `layout.contentGap`, `layout.pagePadding.compact` |
24
+ | `spacing.lg` | 20 | `--hjm-space-lg` | `spacing.lg` · `theme.tokens.spacing.lg` | large 버튼 좌우 안쪽 여백, `layout.pagePadding.regular`, Dialog 하단 여백 |
25
+ | `spacing.xl` | 24 | `--hjm-space-xl` | `spacing.xl` · `theme.tokens.spacing.xl` | `layout.sectionGap`, `layout.pagePadding.spacious`, EmptyState·Result 좌우 여백 |
26
+ | `spacing.xxl` | 32 | `--hjm-space-xxl` | `spacing.xxl` · `theme.tokens.spacing.xxl` | EmptyState 위아래 여백 |
27
+ | `spacing.xxxl` | 40 | `--hjm-space-xxxl` | `spacing.xxxl` · `theme.tokens.spacing.xxxl` | Result 위아래 여백, AuthScreen regular 위아래 여백 |
28
+
29
+ - Native 경로의 `spacing`은 `@hjmds/design-contracts/foundations` import, `theme`은 `useHjmNativeTheme()` 결과다.
30
+ - Stack·Grid·Surface의 `gap`·`padding` prop은 이 토큰 이름(`"md"`)을 받는다. Grid는 `none`(0)을 하나 더 받는다.
31
+ - 두 단계 사이에서 애매하면 작은 쪽을 고른다. 새 숫자(10, 18 등)를 만들지 않는다.
32
+
33
+ ## 쓰는 법
34
+
35
+ ```tsx
36
+ // Web
37
+ import { Stack, Surface } from "@hjmds/react/layout";
38
+
39
+ <Surface padding="lg">
40
+ <Stack gap="sm">{children}</Stack>
41
+ </Surface>
42
+
43
+ // 제품 CSS가 꼭 필요하면 변수로: .product-toolbar { gap: var(--hjm-space-xs); padding-inline: var(--hjm-space-md); }
44
+ ```
45
+
46
+ ```tsx
47
+ // Native
48
+ import { StyleSheet } from "react-native";
49
+ import { spacing } from "@hjmds/design-contracts/foundations";
50
+ import { Stack, Surface } from "@hjmds/react-native/primitives";
51
+
52
+ <Surface padding="lg">
53
+ <Stack gap="sm">{children}</Stack>
54
+ </Surface>
55
+
56
+ const styles = StyleSheet.create({ toolbar: { gap: spacing.xs, paddingHorizontal: spacing.md } });
57
+ ```
58
+
59
+ 간격 배치 규칙은 [Stack](../components/stack.md)·[Grid](../components/grid.md)·[Container](../components/container.md) 지침에 있다.
60
+
61
+ ## 하지 말 것
62
+
63
+ - `margin: 13px`, `padding: 10` 같은 숫자를 직접 쓰지 않는다. 토큰에 없는 리듬은 계약 공백이므로 이슈로 올린다.
64
+ - 자식마다 margin을 붙여 간격을 만들지 않는다. 감싸는 Stack·Grid의 `gap`으로 정한다.
65
+ - `--hjm-space-*` 변수를 제품 CSS에서 재정의하지 않는다([브랜드 경계 §3](../../brand-boundary.md)).
66
+ - 화면 좌우 여백을 화면마다 `spacing.lg`로 적지 않는다. [Container](../components/container.md)의 `gutter`를 쓴다.
67
+
68
+ ## 플랫폼 차이
69
+
70
+ | 항목 | Web | Native |
71
+ | --- | --- | --- |
72
+ | 단위 | CSS px(`--hjm-space-*`는 `px` 문자열) | dp(pt) 숫자 |
73
+ | Stack `gap` 타입 | 토큰 이름만 | 토큰 이름 또는 숫자 |
@@ -0,0 +1,50 @@
1
+ # 테두리
2
+
3
+ - 단계: 토큰
4
+ - 상태: 배포
5
+ - 지원: Web · Native
6
+ - 적용: 1.12.1
7
+ - 검토일: 2026-10-06
8
+ - 근거: `src/foundations.ts`(`stroke`), `src/component-contracts.ts`(`focusIndicatorContract`), `src/base-recipes.ts`(`fieldRecipe`), `src/component-recipes.ts`(`segmentedControlRecipe`·`tabsRecipe`), `packages/react/src/theme.ts`
9
+ - 스토리북: `배포/토큰/표면과 움직임/테두리`
10
+
11
+ ## 언제 쓰나
12
+
13
+ 테두리·구분선·포커스 링의 두께를 정할 때 쓴다. 색은 [색상](color.md)의 테두리 역할(`border`·`borderControl`·`border.focus`)에서 고른다.
14
+
15
+ ## 값
16
+
17
+ | 토큰 | 값 | Web CSS 변수 | Native 경로 | 용도 |
18
+ | --- | --- | --- | --- | --- |
19
+ | `stroke.subtle` | 1 | `--hjm-stroke-subtle` | `stroke.subtle` | 약한 경계(`border.subtle` 색과 함께) |
20
+ | `stroke.default` | 1 | `--hjm-stroke-default` | `stroke.default` | 영역 경계·구분선·필드 테두리(`fieldRecipe.borderWidth` 1) |
21
+ | `stroke.strong` | 2 | `--hjm-stroke-strong` | `stroke.strong` | 선택 표시: SegmentedControl 선택 칸 테두리, Tabs 현재 탭 밑줄 높이 |
22
+ | `stroke.focus` | 2 | `--hjm-stroke-focus` · `--hjm-focus-width` | `stroke.focus` | 키보드 포커스 링. 바깥 간격 2(`--hjm-focus-offset`), 색 `contentBrand`(`--hjm-color-focus`) |
23
+
24
+ Native 경로의 `stroke`는 `@hjmds/design-contracts/foundations` import다.
25
+
26
+ ## 쓰는 법
27
+
28
+ ```tsx
29
+ // Web
30
+ // 제품 고유 영역: .product-panel { border: var(--hjm-stroke-default) solid var(--hjm-color-border); }
31
+ import { Surface } from "@hjmds/react/layout";
32
+
33
+ <Surface bordered>{children}</Surface>
34
+ ```
35
+
36
+ ```tsx
37
+ // Native
38
+ import { View } from "react-native";
39
+ import { stroke } from "@hjmds/design-contracts/foundations";
40
+ import { useHjmNativeTheme } from "@hjmds/react-native/provider";
41
+
42
+ const theme = useHjmNativeTheme();
43
+ <View style={{ borderWidth: stroke.default, borderColor: theme.colors.border }} />;
44
+ ```
45
+
46
+ ## 하지 말 것
47
+
48
+ - 0.5·1.5 같은 두께를 만들지 않는다. hairline이 필요하면 `stroke.subtle`과 `border.subtle` 색을 쓴다.
49
+ - HJM 컴포넌트의 포커스 링을 지우거나(`outline: none`) 다시 그리지 않는다. 제품 고유 컨트롤만 같은 값(`stroke.focus` 2, 간격 2)으로 그린다.
50
+ - 테두리 두께로 선택 상태를 알리는 경우 색도 함께 바꾼다. 두께만으로는 구분이 약하다.
@@ -0,0 +1,70 @@
1
+ # 테마 편집
2
+
3
+ - 단계: 토큰
4
+ - 상태: 배포
5
+ - 지원: Web · Native
6
+ - 적용: 1.12.1
7
+ - 검토일: 2026-10-06
8
+ - 근거: [테마 작업실](../../theme-studio.md), [브랜드 경계](../../brand-boundary.md), `src/theme-studio.ts`, `src/palette-contrast.ts`, `showcase/web/src/foundations/ThemeStudio.stories.tsx`, `showcase/native/src/ThemeStudio.stories.tsx`
9
+ - 스토리북: `배포/토큰/편집 도구/테마 편집`
10
+
11
+ ## 언제 쓰나
12
+
13
+ 제품 브랜드 색을 정할 때, 바꿀 색을 light·dark 양쪽에서 실제 컴포넌트에 입혀 보고 대비를 확인한 뒤
14
+ Provider에 넣을 `brandPalette` 설정을 얻는 작업 도구다. 새 테마 엔진이나 자동 색 생성기가 아니다.
15
+
16
+ 도구 흐름(Storybook 화면, Web·Native 같음):
17
+
18
+ 1. light·dark 각각 세 역할(주요 버튼 배경 `primary`, 주요 버튼 글자 `onPrimary`, 브랜드 강조 글자 `contentBrand`)에 `#rrggbb`를 넣고 적용한다.
19
+ 2. 같은 화면 아래 샘플(버튼·입력·비활성·오류·아이콘·알림·기록 목록)이 그 팔레트로 다시 그려진다.
20
+ 3. "색 대비 확인"에서 각 쌍의 대비·기준·통과 여부를 본다. 미달이 하나라도 있으면 색을 고친다.
21
+ 4. "설정 내보내기"로 `{ "brandPalette": … }` JSON을 받는다(Web 파일 다운로드, Native OS 공유). 아래 코드 블록에서 복사해도 된다.
22
+
23
+ ## 값
24
+
25
+ | 토큰 | 값 | Web CSS 변수 | Native 경로 | 용도 |
26
+ | --- | --- | --- | --- | --- |
27
+ | `StudioColorRole` | `primary` · `onPrimary` · `contentBrand` | `--hjm-color-primary` · `--hjm-color-on-primary` · `--hjm-color-content-brand` | `theme.colors.primary` 등 | 도구에서 바꿀 수 있는 세 역할 |
28
+ | `applyStudioColor(palette, theme, role, color)` | 여섯 자리 HEX만 허용(아니면 `TypeError`), 소문자로 저장, 입력 객체 불변 | — | `@hjmds/design-contracts/theme-studio` | 역할 하나의 색 바꾸기 |
29
+ | `studioReport(palette, theme)` | 각 규칙의 `foreground`·`background`·`ratio`·`minimum`·`pass` | — | `@hjmds/design-contracts/theme-studio` | HJM 기본 팔레트에 바꾼 값을 합쳐 대비 검사. 통과 판정은 반올림 전 값 |
30
+ | `exportStudioPalette(palette)` | `{ "brandPalette": { "light": {…}, "dark": {…} } }` JSON 문자열 | — | `@hjmds/design-contracts/theme-studio` | 산출물. 바꾼 key만 담는다 |
31
+ | 대비 기준 | 글자 4.5 · 형태(`primary`·`borderControl`)와 `textWeak` 3 | — | `paletteContrastRules` | [색상](color.md)의 쌍 표와 같다 |
32
+
33
+ ## 쓰는 법
34
+
35
+ 산출물은 Provider의 `brandPalette` prop에 그대로 넣고, 같은 값을 제품 테스트에서 `checkBrandPaletteContrast`로 검사한다.
36
+
37
+ ```tsx
38
+ // Web
39
+ import { HjmProvider } from "@hjmds/react/provider";
40
+ import { brandPalette } from "./brand-palette"; // 테마 편집에서 내보낸 JSON의 brandPalette
41
+
42
+ <HjmProvider brandPalette={brandPalette}>{app}</HjmProvider>
43
+ ```
44
+
45
+ ```tsx
46
+ // Native
47
+ import { HjmNativeProvider } from "@hjmds/react-native/provider";
48
+ import { checkBrandPaletteContrast } from "@hjmds/design-contracts/palette-contrast";
49
+ import { brandPalette } from "./brand-palette";
50
+
51
+ <HjmNativeProvider brandPalette={brandPalette} safeAreaInsets={insets}>{app}</HjmNativeProvider>
52
+
53
+ // 제품 테스트
54
+ expect(checkBrandPaletteContrast(brandPalette)).toEqual([]);
55
+ ```
56
+
57
+ ## 하지 말 것
58
+
59
+ - 통과 표시를 전체 접근성 인증으로 보고하지 않는다. 지정된 색 쌍의 대비일 뿐이고 hover·focus·실제 배경은 따로 확인한다.
60
+ - 내보낸 JSON을 HJM 중앙 토큰이나 다른 제품 기본값으로 쓰지 않는다. 그 제품의 `brandPalette`에만 쓴다.
61
+ - 도구 밖에서 `--hjm-color-*`를 재정의해 같은 효과를 내지 않는다([브랜드 경계 §3](../../brand-boundary.md)).
62
+ - Showcase 샘플 문구·예시 색을 제품에 복사하지 않는다. 도구의 라벨·오류 문구는 showcase 소유다.
63
+
64
+ ## 플랫폼 차이
65
+
66
+ | 항목 | Web | Native |
67
+ | --- | --- | --- |
68
+ | 내보내기 | `hjm-brand-palette.json` 파일 다운로드 | OS 공유 시트(`Share.share`) |
69
+ | 기록 샘플 | DataTable | List |
70
+ | 키보드 | — | 입력이 키보드에 가리지 않게 스크롤이 키보드 높이를 따른다 |
@@ -0,0 +1,70 @@
1
+ # 글꼴 편집
2
+
3
+ - 단계: 토큰
4
+ - 상태: 배포
5
+ - 지원: Web · Native
6
+ - 적용: 1.12.1
7
+ - 검토일: 2026-10-06
8
+ - 근거: [테마 작업실](../../theme-studio.md), `src/foundations.ts`(`fontFamily`), `showcase/web/src/foundations/TypographyStudio.stories.tsx`, `showcase/native/src/TypographyStudio.stories.tsx`, `showcase/shared/typography-studio.ts`
9
+ - 스토리북: `배포/토큰/편집 도구/글꼴 편집`
10
+
11
+ ## 언제 쓰나
12
+
13
+ 제품 서체 후보를 정할 때, 후보 폰트를 기본 서체와 나란히 같은 크기로 그려 한글·영문·숫자·긴 문장을 비교하고
14
+ 출처·라이선스를 함께 기록하는 작업 도구다. 공개 API가 없는 Storybook 도구이며 HJM 토큰을 바꾸지 않는다.
15
+
16
+ 도구 흐름:
17
+
18
+ 1. 후보 폰트를 넣는다. Web은 `.woff`·`.woff2`·`.ttf`·`.otf` 파일 선택, Native는 사용 권한이 있는 OTF·TTF 주소(`https://` 또는 `file://`)를 넣고 "서체 불러오기".
19
+ 2. 상태 문구가 비어 있음 → 불러오는 중 → 불러옴 / 실패로 바뀐다. 실패하면 기본 서체로 표시한다.
20
+ 3. "기본 서체"와 "비교할 서체" 두 카드에서 `heading` 크기 제목, 본문, 굵은 본문을 비교한다. 한글 글리프가 없는 부분은 기본 서체로 대체될 수 있다.
21
+ 4. 서체 출처·라이선스 문서 주소를 적고, 아래 "서체 후보 설정" 코드 블록을 기록으로 가져간다.
22
+
23
+ ## 값
24
+
25
+ | 토큰 | 값 | Web CSS 변수 | Native 경로 | 용도 |
26
+ | --- | --- | --- | --- | --- |
27
+ | 비교 기준 서체 | Web `system-ui, sans-serif`, Native OS 기본 | `--hjm-font-family-ui`(HJM 기본 목록은 [타이포그래피](typography.md)) | — | "기본 서체" 카드 |
28
+ | 비교 글자 크기 | `typography.heading` 24 · `typography.body` 14 · body bold | `--hjm-type-heading-*` · `--hjm-type-body-*` | `theme.tokens.typography` | 두 카드가 같은 단계로 그린다 |
29
+ | 산출물(Web) | `{ fileName, source, license, status, fallback: "system-ui, sans-serif" }` JSON | — | — | 후보 기록. 폰트 파일은 포함하지 않는다 |
30
+ | 산출물(Native) | `{ family, status, source, license }` JSON | — | — | 후보 기록 |
31
+ | `status` | `empty` · `loading` · `ready` · `error` | — | — | 불러오기 상태 |
32
+
33
+ ## 쓰는 법
34
+
35
+ 후보가 정해지면 제품이 폰트 파일과 라이선스를 소유하고 제품 앱에서 등록한다. HJM 컴포넌트는 Web에서 Provider 루트의 서체를,
36
+ `host="contents"`일 때는 제품 루트의 서체를 상속한다.
37
+
38
+ ```tsx
39
+ // Web
40
+ import { HjmProvider } from "@hjmds/react/provider";
41
+
42
+ // 제품 CSS: @font-face { font-family: "ProductSans"; src: url("/fonts/product-sans.woff2") format("woff2"); }
43
+ // 제품 CSS: .product-root { font-family: "ProductSans", system-ui, sans-serif; }
44
+ <div className="product-root">
45
+ <HjmProvider host="contents">{app}</HjmProvider>
46
+ </div>
47
+ ```
48
+
49
+ ```tsx
50
+ // Native
51
+ import { useFonts } from "expo-font";
52
+
53
+ const [loaded] = useFonts({ ProductSans: require("./assets/fonts/ProductSans.otf") });
54
+ // HJM Native 컴포넌트는 fontFamily를 지정하지 않는다. 제품 서체 적용 범위는 제품 Text 래퍼가 정한다.
55
+ ```
56
+
57
+ ## 하지 말 것
58
+
59
+ - 라이선스가 확인되지 않은 폰트를 제품에 넣지 않는다. 도구에 적은 출처·라이선스 주소를 제품 문서에 남긴다.
60
+ - 도구에서 불러온 폰트를 저장·배포 경로로 쓰지 않는다. Web 파일은 현재 미리보기에서만 쓰고, Native 등록은 앱 종료까지만 남는다.
61
+ - `--hjm-font-family-ui`를 제품 CSS에서 재정의하지 않는다([브랜드 경계 §3](../../brand-boundary.md)).
62
+ - 서체를 바꾸면서 글자 크기·줄 높이 토큰을 함께 바꾸지 않는다. 같은 크기에서 비교한 결과로 고른다.
63
+
64
+ ## 플랫폼 차이
65
+
66
+ | 항목 | Web | Native |
67
+ | --- | --- | --- |
68
+ | 폰트 입력 | 파일 선택, `FontFace`로 메모리에서 등록(업로드 없음) | 주소 입력, `expo-font` `loadAsync` |
69
+ | 초기화 | 등록한 폰트를 문서에서 제거 | 기본 서체로 돌아가지만 등록은 앱 종료까지 유지 |
70
+ | 서체 적용 | 스타일 `fontFamily: "<family>", system-ui, sans-serif` | 등록이 끝난 뒤에만 `fontFamily` 적용 |
@@ -0,0 +1,89 @@
1
+ # 타이포그래피
2
+
3
+ - 단계: 토큰
4
+ - 상태: 배포
5
+ - 지원: Web · Native
6
+ - 적용: 1.12.1
7
+ - 검토일: 2026-10-06
8
+ - 근거: `src/foundations.ts`(`typography`·`heading`·`fontFamily`·`fontWeight`·`letterSpacing`·`numeric`·`largeTextThreshold`), `src/component-recipes.ts`(`textRecipe`), `packages/react/src/theme.ts`, `packages/react/src/provider.tsx`, `packages/react-native/src/provider.tsx`
9
+ - 스토리북: `배포/토큰/색과 글자/타이포그래피`
10
+
11
+ ## 언제 쓰나
12
+
13
+ 글자 크기·줄 높이·굵기를 정할 때 쓴다. 대부분은 [Text](../components/text.md)의 `variant`·`emphasis`와
14
+ [Heading](../components/heading.md)의 `level`로 고르고, 토큰을 직접 읽는 것은 제품 고유 그림(차트 라벨 등)일 때다.
15
+
16
+ ## 값
17
+
18
+ ### 글자 단계(`typography`, Text `variant`)
19
+
20
+ | 토큰 | 값 | Web CSS 변수 | Native 경로 | 용도 |
21
+ | --- | --- | --- | --- | --- |
22
+ | `typography.caption` | 11 / 줄 16 / 400 | `--hjm-type-caption-size` · `-line-height` · `-weight` | `theme.tokens.typography.caption` | 가장 작은 보조 표기, AuthScreen 정책 링크 |
23
+ | `typography.label` | 12 / 줄 18 / 600 | `--hjm-type-label-*` | `theme.tokens.typography.label` | 라벨·도움말·small 버튼 글자 |
24
+ | `typography.body` | 14 / 줄 20 / 400 | `--hjm-type-body-*` | `theme.tokens.typography.body` | 기본 본문·medium 버튼·필드 글자 |
25
+ | `typography.bodyLarge` | 16 / 줄 24 / 400 | `--hjm-type-body-large-*` | `theme.tokens.typography.bodyLarge` | 읽기용 긴 본문·large 버튼 글자 |
26
+ | `typography.title` | 18 / 줄 26 / 700 | `--hjm-type-title-*` | `theme.tokens.typography.title` | 카드 제목(`heading.level5`) |
27
+ | `typography.titleLarge` | 20 / 줄 28 / 800 | `--hjm-type-title-large-*` | `theme.tokens.typography.titleLarge` | 큰 구획 제목(`heading.level4`) |
28
+ | `typography.heading` | 24 / 줄 32 / 800 | `--hjm-type-heading-*` | `theme.tokens.typography.heading` | 화면의 가장 큰 제목 |
29
+
30
+ ### 문서 제목 단계(`heading`, Heading `level`)
31
+
32
+ | 토큰 | 값 | Web CSS 변수 | Native 경로 | 용도 |
33
+ | --- | --- | --- | --- | --- |
34
+ | `heading.level1` | 40 / 줄 48 / 800 | — | `heading.level1` | 랜딩·문서의 대표 제목 |
35
+ | `heading.level2` | 32 / 줄 40 / 800 | — | `heading.level2` | 긴 페이지의 큰 구획 제목 |
36
+ | `heading.level3` | = `typography.heading` 24 | `--hjm-type-heading-*` | `heading.level3` | 화면 제목 |
37
+ | `heading.level4` | = `typography.titleLarge` 20 | `--hjm-type-title-large-*` | `heading.level4` | 구획 제목 |
38
+ | `heading.level5` | = `typography.title` 18 | `--hjm-type-title-*` | `heading.level5` | 카드 제목 |
39
+
40
+ ### 서체·굵기·자간·숫자
41
+
42
+ | 토큰 | 값 | Web CSS 변수 | Native 경로 | 용도 |
43
+ | --- | --- | --- | --- | --- |
44
+ | `fontFamily.ui` | Inter, Pretendard, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif | `--hjm-font-family-ui` | `fontFamily.ui` | 화면 글자. Native는 HJM이 서체를 지정하지 않아 OS 기본 서체로 그린다 |
45
+ | `fontFamily.code` | ui-monospace, SFMono-Regular, Consolas, Liberation Mono, monospace | — (`--hjm-font-family-code` fallback) | `fontFamily.code` | 코드 |
46
+ | `fontWeight.regular` · `medium` · `semibold` · `bold` · `heavy` | 400 · 500 · 600 · 700 · 800 | `--hjm-font-weight-<이름>` | `fontWeight.<이름>` | Text `emphasis`: `regular` 400 · `medium` 600 · `strong` 700 |
47
+ | `letterSpacing.tight` · `normal` · `wide` | -0.2 · 0 · 0.2 | — | `letterSpacing.<이름>` | 자간 조정이 필요한 제품 고유 글자. HJM 컴포넌트는 자간을 지정하지 않는다 |
48
+ | `numeric.tabular` · `proportional` | `tabular-nums` · `proportional-nums` | — | `numeric.<이름>` | 바뀌는 숫자(카운터·통계·날짜 칸)는 `tabular`로 폭을 고정 |
49
+ | `largeTextThreshold` | 1.6 | 루트 `data-large-text="true"` | `largeTextThreshold` | 글자 배율이 이 값 이상이면 큰 글자 배치로 바꾼다 |
50
+
51
+ Native 경로의 `theme`은 `useHjmNativeTheme()`, 나머지 이름은 `@hjmds/design-contracts/foundations` import다.
52
+ Web 크기 변수는 `rem × --hjm-text-scale`이라 Provider의 `textScale`을 따른다.
53
+
54
+ ## 쓰는 법
55
+
56
+ ```tsx
57
+ // Web
58
+ import { Text } from "@hjmds/react/layout";
59
+ import { Heading } from "@hjmds/react/heading";
60
+
61
+ <Heading level="level3">{t("orders.title")}</Heading>
62
+ <Text as="p" variant="body" tone="muted">{t("orders.hint")}</Text>
63
+ // 제품 고유 그림: .product-axis-label { font-size: var(--hjm-type-caption-size); line-height: var(--hjm-type-caption-line-height); }
64
+ ```
65
+
66
+ ```tsx
67
+ // Native
68
+ import { Text } from "@hjmds/react-native/primitives";
69
+ import { Heading } from "@hjmds/react-native/heading";
70
+
71
+ <Heading level="level3">{t("orders.title")}</Heading>
72
+ <Text variant="body" tone="muted">{t("orders.hint")}</Text>
73
+ ```
74
+
75
+ ## 하지 말 것
76
+
77
+ - `font-size: 15px`, `fontWeight: "900"`처럼 단계 밖 값을 쓰지 않는다.
78
+ - 크기를 맞추려고 Heading의 `semanticLevel`을 바꾸지 않는다. 시각 크기는 `level`, 문서 구조는 `semanticLevel`이다.
79
+ - 글자 크기를 고정해 OS 글자 크기 설정을 막지 않는다(`allowFontScaling={false}`, px 고정 `font-size`).
80
+ - 줄 높이를 지워 글자를 겹치게 하지 않는다. 한국어 본문은 토큰 줄 높이를 그대로 쓴다.
81
+ - 제품 서체는 [글꼴 편집](typography-studio.md)으로 비교·라이선스를 확인한 뒤 제품이 소유한다. `--hjm-font-family-ui`를 재정의하지 않는다.
82
+
83
+ ## 플랫폼 차이
84
+
85
+ | 항목 | Web | Native |
86
+ | --- | --- | --- |
87
+ | 단위 | rem(16px 기준) × `--hjm-text-scale` | dp. OS 글자 크기를 따르고, Provider `textScale`을 주면 HJM이 한 번만 곱한다 |
88
+ | 서체 | `--hjm-font-family-ui` 목록 | OS 기본 서체(HJM이 `fontFamily`를 지정하지 않음) |
89
+ | 큰 글자 판정 | 루트 `data-large-text` | `isLargeTextScale(environment.textScale)` |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hjmds/design-contracts",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "description": "Renderer-neutral design contracts, tokens, recipes, and behaviors shared by HJM products.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -660,6 +660,12 @@
660
660
  "react-native": "./dist/action-session.js",
661
661
  "import": "./dist/action-session.js",
662
662
  "default": "./dist/action-session.js"
663
+ },
664
+ "./screen-patterns": {
665
+ "types": "./dist/screen-patterns.d.ts",
666
+ "react-native": "./dist/screen-patterns.js",
667
+ "import": "./dist/screen-patterns.js",
668
+ "default": "./dist/screen-patterns.js"
663
669
  }
664
670
  },
665
671
  "files": [