@hjmds/design-contracts 1.46.1 → 1.48.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 (107) hide show
  1. package/dist/behaviors.d.ts +2 -1
  2. package/dist/behaviors.d.ts.map +1 -1
  3. package/dist/bottom-navigation.d.ts +4 -0
  4. package/dist/bottom-navigation.d.ts.map +1 -1
  5. package/dist/bottom-navigation.js +12 -0
  6. package/dist/bottom-navigation.js.map +1 -1
  7. package/dist/card.d.ts +2 -2
  8. package/dist/card.d.ts.map +1 -1
  9. package/dist/card.js +3 -2
  10. package/dist/card.js.map +1 -1
  11. package/dist/carousel.d.ts +1 -0
  12. package/dist/carousel.d.ts.map +1 -1
  13. package/dist/carousel.js +1 -0
  14. package/dist/carousel.js.map +1 -1
  15. package/dist/catalog.d.ts +151 -31
  16. package/dist/catalog.d.ts.map +1 -1
  17. package/dist/catalog.js +14 -13
  18. package/dist/catalog.js.map +1 -1
  19. package/dist/color-picker.d.ts +51 -1
  20. package/dist/color-picker.d.ts.map +1 -1
  21. package/dist/color-picker.js +56 -2
  22. package/dist/color-picker.js.map +1 -1
  23. package/dist/component-recipes.d.ts +28 -10
  24. package/dist/component-recipes.d.ts.map +1 -1
  25. package/dist/component-recipes.js +28 -20
  26. package/dist/component-recipes.js.map +1 -1
  27. package/dist/conversation-row.d.ts +1 -1
  28. package/dist/conversation-row.d.ts.map +1 -1
  29. package/dist/conversation-row.js +2 -1
  30. package/dist/conversation-row.js.map +1 -1
  31. package/dist/data-table.d.ts +12 -0
  32. package/dist/data-table.d.ts.map +1 -1
  33. package/dist/data-table.js +2 -0
  34. package/dist/data-table.js.map +1 -1
  35. package/dist/date-range.d.ts +122 -3
  36. package/dist/date-range.d.ts.map +1 -1
  37. package/dist/date-range.js +139 -5
  38. package/dist/date-range.js.map +1 -1
  39. package/dist/icon.d.ts +2 -1
  40. package/dist/icon.d.ts.map +1 -1
  41. package/dist/icon.js +2 -0
  42. package/dist/icon.js.map +1 -1
  43. package/dist/recipes.d.ts +1 -0
  44. package/dist/recipes.d.ts.map +1 -1
  45. package/dist/recipes.js +1 -0
  46. package/dist/recipes.js.map +1 -1
  47. package/dist/screen-patterns.d.ts +33 -2
  48. package/dist/screen-patterns.d.ts.map +1 -1
  49. package/dist/screen-patterns.js +27 -2
  50. package/dist/screen-patterns.js.map +1 -1
  51. package/dist/share-sheet.d.ts +115 -0
  52. package/dist/share-sheet.d.ts.map +1 -0
  53. package/dist/share-sheet.js +62 -0
  54. package/dist/share-sheet.js.map +1 -0
  55. package/dist/version.d.ts +1 -1
  56. package/dist/version.js +1 -1
  57. package/dist/version.js.map +1 -1
  58. package/docs/bottom-navigation.md +16 -0
  59. package/docs/color-picker.md +24 -19
  60. package/docs/dialog.md +2 -3
  61. package/docs/generated/component-maturity.md +12 -12
  62. package/docs/generated/renderer-evidence.json +71 -19
  63. package/docs/generated/renderer-evidence.md +15 -14
  64. package/docs/generated/showcase-manifest.json +35 -21
  65. package/docs/optional-adapters.md +21 -5
  66. package/docs/stable-core.md +37 -0
  67. package/docs/usage/README.md +14 -10
  68. package/docs/usage/SELECTION.md +109 -0
  69. package/docs/usage/components/avatar.md +31 -6
  70. package/docs/usage/components/badge.md +10 -1
  71. package/docs/usage/components/bottom-navigation.md +16 -0
  72. package/docs/usage/components/button.md +11 -0
  73. package/docs/usage/components/card.md +6 -0
  74. package/docs/usage/components/chat-message.md +9 -1
  75. package/docs/usage/components/chat-room-members.md +4 -0
  76. package/docs/usage/components/chat-screen.md +10 -1
  77. package/docs/usage/components/color-picker.md +65 -28
  78. package/docs/usage/components/comment-thread-screen.md +16 -1
  79. package/docs/usage/components/conversation-list-screen.md +81 -0
  80. package/docs/usage/components/conversation-row.md +5 -1
  81. package/docs/usage/components/data-table.md +2 -0
  82. package/docs/usage/components/date-range-picker.md +15 -5
  83. package/docs/usage/components/dialog.md +3 -3
  84. package/docs/usage/components/event-attendance-card.md +4 -0
  85. package/docs/usage/components/follow-list-screen.md +109 -0
  86. package/docs/usage/components/follow-profile-card.md +4 -0
  87. package/docs/usage/components/list-row.md +6 -0
  88. package/docs/usage/components/menu.md +12 -0
  89. package/docs/usage/components/notice.md +8 -3
  90. package/docs/usage/components/notification-inbox-screen.md +10 -0
  91. package/docs/usage/components/notification-row.md +4 -0
  92. package/docs/usage/components/page-indicator.md +1 -0
  93. package/docs/usage/components/profile-summary.md +32 -3
  94. package/docs/usage/components/section.md +2 -2
  95. package/docs/usage/components/settings-screen.md +1 -1
  96. package/docs/usage/components/share-sheet.md +139 -0
  97. package/docs/usage/components/shared-transition-element.md +1 -1
  98. package/docs/usage/components/sheet.md +1 -0
  99. package/docs/usage/components/statistic.md +1 -1
  100. package/docs/usage/compositions/interaction-adapters.md +2 -2
  101. package/docs/usage/compositions/optional-adapters.md +2 -2
  102. package/docs/usage/compositions/web-additions.md +5 -5
  103. package/docs/usage/screens/common-comments.md +1 -0
  104. package/docs/usage/screens/common-conversation-list.md +22 -1
  105. package/docs/usage/screens/common-follow-list.md +87 -0
  106. package/docs/usage/screens/common-settings.md +23 -0
  107. package/package.json +7 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
- "designSystemVersion": "1.46.1",
3
+ "designSystemVersion": "1.48.0",
4
4
  "packageName": "@hjmds/design-contracts",
5
5
  "components": [
6
6
  {
@@ -1717,10 +1717,10 @@
1717
1717
  "extensions": [],
1718
1718
  "category": "input",
1719
1719
  "platform": "shared",
1720
- "contractStatus": "beta",
1720
+ "contractStatus": "stable",
1721
1721
  "surfaces": {
1722
- "web": "beta",
1723
- "native": "beta"
1722
+ "web": "stable",
1723
+ "native": "stable"
1724
1724
  },
1725
1725
  "requirements": [
1726
1726
  {
@@ -2294,14 +2294,16 @@
2294
2294
  "storyId": "input/color-picker",
2295
2295
  "name": "ColorPicker",
2296
2296
  "label": "색상 선택기",
2297
- "companions": [],
2297
+ "companions": [
2298
+ "ColorSwatchPicker"
2299
+ ],
2298
2300
  "extensions": [],
2299
2301
  "category": "input",
2300
- "platform": "web",
2302
+ "platform": "adaptive",
2301
2303
  "contractStatus": "stable",
2302
2304
  "surfaces": {
2303
2305
  "web": "stable",
2304
- "native": "unsupported"
2306
+ "native": "stable"
2305
2307
  },
2306
2308
  "requirements": [
2307
2309
  {
@@ -2322,6 +2324,18 @@
2322
2324
  "accessibility",
2323
2325
  "keyboard"
2324
2326
  ]
2327
+ },
2328
+ {
2329
+ "surface": "native",
2330
+ "scenarios": [
2331
+ "default",
2332
+ "dark",
2333
+ "long-copy",
2334
+ "large-text",
2335
+ "rtl",
2336
+ "reduced-motion",
2337
+ "accessibility"
2338
+ ]
2325
2339
  }
2326
2340
  ],
2327
2341
  "documentation": {
@@ -2898,10 +2912,10 @@
2898
2912
  "extensions": [],
2899
2913
  "category": "navigation",
2900
2914
  "platform": "shared",
2901
- "contractStatus": "beta",
2915
+ "contractStatus": "stable",
2902
2916
  "surfaces": {
2903
- "web": "beta",
2904
- "native": "beta"
2917
+ "web": "stable",
2918
+ "native": "stable"
2905
2919
  },
2906
2920
  "requirements": [
2907
2921
  {
@@ -2950,7 +2964,7 @@
2950
2964
  "contractStatus": "stable",
2951
2965
  "surfaces": {
2952
2966
  "web": "stable",
2953
- "native": "beta"
2967
+ "native": "stable"
2954
2968
  },
2955
2969
  "requirements": [
2956
2970
  {
@@ -3922,7 +3936,7 @@
3922
3936
  "contractStatus": "stable",
3923
3937
  "surfaces": {
3924
3938
  "web": "stable",
3925
- "native": "beta"
3939
+ "native": "stable"
3926
3940
  },
3927
3941
  "requirements": [
3928
3942
  {
@@ -3980,10 +3994,10 @@
3980
3994
  "extensions": [],
3981
3995
  "category": "data-display",
3982
3996
  "platform": "shared",
3983
- "contractStatus": "beta",
3997
+ "contractStatus": "stable",
3984
3998
  "surfaces": {
3985
- "web": "beta",
3986
- "native": "beta"
3999
+ "web": "stable",
4000
+ "native": "stable"
3987
4001
  },
3988
4002
  "requirements": [
3989
4003
  {
@@ -6196,10 +6210,10 @@
6196
6210
  "extensions": [],
6197
6211
  "category": "feedback",
6198
6212
  "platform": "adaptive",
6199
- "contractStatus": "beta",
6213
+ "contractStatus": "stable",
6200
6214
  "surfaces": {
6201
- "web": "beta",
6202
- "native": "beta"
6215
+ "web": "stable",
6216
+ "native": "stable"
6203
6217
  },
6204
6218
  "requirements": [
6205
6219
  {
@@ -6245,10 +6259,10 @@
6245
6259
  "extensions": [],
6246
6260
  "category": "data-display",
6247
6261
  "platform": "adaptive",
6248
- "contractStatus": "beta",
6262
+ "contractStatus": "stable",
6249
6263
  "surfaces": {
6250
- "web": "beta",
6251
- "native": "beta"
6264
+ "web": "stable",
6265
+ "native": "stable"
6252
6266
  },
6253
6267
  "requirements": [
6254
6268
  {
@@ -1,6 +1,22 @@
1
1
  # Optional presentation adapters
2
2
 
3
- ## Image host extension — 2026-10-07 (unpublished)
3
+ ## Current support — 2026-10-26
4
+
5
+ The four Native entries `image-viewer`, `keyboard-controller`, `sheet-gesture` and
6
+ `context-menu-native` are **stable for the documented optional-peer/host contract**.
7
+ The Web image viewer counterpart is stable as well. This is API support, not a claim
8
+ that every OS, physical device or consuming product has been certified.
9
+
10
+ The promotion reuses the installed iOS/Android engine observations linked below and
11
+ reruns the affected host/browser behavior tests. The current iPhone 17 Pro / iOS 26.5
12
+ Showcase additionally confirmed image loading and dismissal, keyboard entry with the
13
+ dock above the IME and retained text after Done, and sheet input/open/close state.
14
+ The existing iOS system-menu Save and Android engine checks remain historical evidence;
15
+ Android was not connected for a new run. Spoken VoiceOver/TalkBack, release binaries
16
+ and per-product peer/linking validation remain consumer QA as for other stable APIs.
17
+ See [Stable Core](stable-core.md#2026-10-26-잔여-실험과-beta-승격).
18
+
19
+ ## Image host extension — 2026-10-07 implementation record
4
20
 
5
21
  Native ImageViewer accepts `renderImage` with the item, measured viewport width/height and
6
22
  `onReady`/`onError`. This lets a product retain Expo display events and cache policy without
@@ -18,7 +34,7 @@ previous/next buttons, not swipe paging. Mode, viewport, item and retry changes
18
34
  retire callbacks and reset readiness/position. Output-size means layout units, not physical device pixels.
19
35
  Host width/height are the computed image dimensions in inspection mode (possibly larger than the viewport).
20
36
  The [image usage guide](usage/components/image.md) defines labels, placement and review invalidation.
21
- This is unpublished and is not proof of Expo onDisplay validation or Utilverse adoption.
37
+ These host props are present in the 1.47.0 source/package train; their presence is not proof of Expo onDisplay validation or Utilverse adoption.
22
38
  The Native Modal accepts supportedOrientations in fullScreen presentation. Optional left/right
23
39
  safe-area insets protect controls and feedback in landscape while the gallery remains full width.
24
40
  Products must supply updated insets and permit rotation in their manifests; OS rotation lock still applies.
@@ -123,9 +139,9 @@ Expo Go cannot verify these linked native modules.
123
139
 
124
140
  Web stories: `배포/구성/직접 조작과 모션/숫자 변화와 메뉴 변형`. Native stories: `배포/구성/직접 조작과 모션/이미지·시트·키보드 조작` (the earlier 갤러리/모션 연동 and 실험실/선택적 연동 menus; moved by the 2026-10-06 user-approved Storybook promotion, which is not an API promotion).
125
141
  Tests cover adaptation logic and web browser behavior; native mocks cannot prove OS gestures,
126
- keyboard animation, accessibility focus, native linking or installed-device health. Keep native
127
- adapters experimental until iOS/Android device evidence exists. No consumer migration or publication
128
- is implied by adding these entries. The prior Motion Primitives candidate remains reference-only.
142
+ keyboard animation, accessibility focus, native linking or installed-device health. The current
143
+ stable decision also uses the installed-engine observations and scoped follow-up above. No consumer
144
+ migration or publication is implied by changing support status. The prior Motion Primitives candidate remains reference-only.
129
145
 
130
146
  A removal replaces the optional imports with canonical Statistic/Menu/Sheet/KeyboardAvoiding or
131
147
  product image/menu behavior and removes the matching peers. There is no persisted-state migration.
@@ -1,5 +1,42 @@
1
1
  # Stable Core
2
2
 
3
+ ## 2026-10-26 잔여 실험과 beta 승격
4
+
5
+ 사용자의 “다 올려” 지시에 따라 남아 있던 카탈로그 beta와 실험 화면을 승격했다.
6
+ 카탈로그의 계약/Web은 stable131·beta0, Native는 stable114·beta0·unsupported17이다.
7
+ 지원하지 않는 플랫폼을 새로 구현하거나 지원된다고 표시하지 않았다.
8
+
9
+ - 계약·Web·Native: ImageChoiceGroup, PageIndicator, Chart, TypingIndicator, ChatDateSeparator.
10
+ - Native surface: ColorPicker, Pagination, DataTable(Web/계약은 이미 stable).
11
+ - Storybook Web·Native: FollowListScreen의 `팔로워와 팔로잉`을 배포로 이동. Web id `common-follow-list` 유지.
12
+ - 선택형 image-viewer(Web·Native), Native keyboard-controller·sheet-gesture·context-menu-native 및
13
+ screen-transition은 문서화한 peer/host 범위의 API를 stable로 지원한다. optional import, native linking,
14
+ React Navigation7.4.1 host와 기존 package patch 전제는 유지한다. expo-router 통합을 새로 제공하지 않는다.
15
+ - Dialog의 optional motionOrigin도 문서화한 상태·초안 보존·종료/재열기 계약을 stable로 지원한다.
16
+ 모든 기기에서 같은 frame time이나 제품별 조합 검증을 보장한다는 뜻은 아니다.
17
+
18
+ 검사에서 ColorPicker의 누락된 default/environment fixture를 발견해 실제 공개 API fixture를 보완했다.
19
+ 새 fixture가 드러낸 RTL 문제는 색상 막대의 좌표 소유 위치인 Slider에서 고쳤다. painted track이 물리
20
+ 색상 축을 명시하고 드래그 계산·thumb·layout이 같은 방향을 쓰며, 일반 Slider는 제품 읽기 방향을 따른다.
21
+ 환경 proof는 명시적으로 고정한 하위 좌표계를 상속해 검사하고 고정 좌표가 그대로인지 단언한다.
22
+ 단순 catalog 이름/숫자를 복제하던 회귀 단언은 제거하고 per-surface 불변식과 독립 legacy/custom 검사를 유지했다.
23
+
24
+ 변경 범위 결과: Native 관련14파일69건, Web 관련9파일30건, 색상/일반 Slider 회귀15건(새 RTL 회귀 포함),
25
+ 승격 대상 환경 matrix Web35건·Native35건 통과. 최대 글자 조건은 실행하지 않았다. contracts의
26
+ component-references13건과 세 package build/typecheck를 확인했다. 두 Showcase typecheck도 통과했다.
27
+ 현재 iPhone17 Pro/iOS26.5의 기존 SDK58 개발 클라이언트와8084 Metro에서 이미지 실제 로딩/닫기,
28
+ 키보드 입력321→완료(값 유지·IME 위 dock), 시트 입력789→닫힘, 공유 카드→상세→목록, Dialog의
29
+ 실패 후 초안 유지→닫기/재열기→성공 저장과 팔로워 화면의 맞팔로우→회원 프로필→목록 복귀를 Device Hub로 확인했다. NativeContextMenu의 시스템 메뉴
30
+ Save 및 Android16 네 엔진 확인은 기존9월29일 증거를 재사용했다. 이번에 Android 연결 기기는 없었으며
31
+ 새 Android UI·물리 기기·VoiceOver/TalkBack·Release binary·성능 전수 결과로 확대하지 않는다.
32
+
33
+ 전체 Showcase 검사는 별개 기존 실패를 재현했다: 전체 스토리 규격74건 및 Native foundation token 문서
34
+ 2개 누락, Web Affix recipe fixture의 추가 sticky 값, 전체 usage의 Card/QuoteCard 문서3건이다.
35
+ 승격 대상 FollowList의 상태 표시 이름·스토리 순서는 고쳤으며 해당 두 스토리의 남은 규격 오류는0건이다.
36
+ 이번 FollowList 승격과 관계없는 항목을 수정하거나 전체 통과로 보고하지 않는다. 변경한 지침7개는
37
+ 선택 검사·색인 생성을 통과했다. 공개 source의 승격과 npm 게시·공개 Storybook 게시·제품 채택은
38
+ 별개이며, 이번 작업은1.47.0 버전을 유지하고 다음 train용 minor Changeset을 남긴다.
39
+
3
40
  ## 2026-10-19 TimePicker 개발 소스 승격
4
41
 
5
42
  사용자가 승인한 통합 시·분 열 디자인으로 `TimePicker`를 canonical catalog에 등록하고 계약·Web·Native
@@ -7,7 +7,7 @@
7
7
  [선택 기준](SELECTION.md)으로 그대로 사용·공개 슬롯 확장·공통 API 보완·제품 고유 기능 연결을 고른다. 설치 버전의 지침을 본다: `node_modules/@hjmds/design-contracts/docs/usage/`.
8
8
  이름을 모르면 [쉬운 말로 찾고 비교하기](FINDING.md)에서 일상 표현과 선택 기준·요청 예시로 시작한다.
9
9
  제공 기준은 확인한 기본 API 버전이며 최초 출시 버전이 아니다. 구성·화면은 각 API 지침의 제공 버전을 확인한다.
10
- API 안정성은 1.46.0의 생성 manifest에서 읽은 정규(canonical) API 기준이다. 동반·선택형 확장은 개별 계약을 확인한다.
10
+ API 안정성은 1.47.0의 생성 manifest에서 읽은 정규(canonical) API 기준이다. 동반·선택형 확장은 개별 계약을 확인한다.
11
11
  Storybook 배포/실험은 예제 분류이며 npm 게시·기기 검증·제품 반영을 의미하지 않는다.
12
12
  `분류`는 Storybook 제목 `<배포|실험>/<단계>/<분류>/<항목>`의 셋째 마디이고, 토큰·구성·화면은 Storybook 메뉴와 같은 순서다.
13
13
 
@@ -54,11 +54,11 @@ Storybook 배포/실험은 예제 분류이며 npm 게시·기기 검증·제품
54
54
  | [Breadcrumb](components/breadcrumb.md) | 탐색 | Web의 깊은 계층 화면에서 현재 위치까지의 경로를 보여 주고 상위 계층으로 바로 돌아가게 할 때 쓴다. | 1.12.1 | Web | Web stable / Native unsupported | 배포 |
55
55
  | [Button](components/button.md) | 동작 | 사용자가 누르면 무언가가 일어나는 텍스트 행동에 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
56
56
  | [Calendar](components/calendar.md) | 데이터 표시 | 화면에 항상 펼쳐진 한 달 격자에서 날짜 하나를 고를 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
57
- | [Card](components/card.md) | 데이터 표시 | 인용문과 출처를 묶으면 미게시 동반 API `QuoteCard`를 사용한다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
57
+ | [Card](components/card.md) | — | 인용문과 출처를 묶으면 미게시 동반 API `QuoteCard`를 사용한다. | | | Web stable / Native stable | |
58
58
  | [Carousel](components/carousel.md) | 데이터 표시 | 한 번에 카드 하나만 보이고 사용자가 순서대로 넘겨 보는 유한한 묶음에 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
59
59
  | [Celebration](components/celebration.md) | 구성/직접 조작과 모션 | 목표 달성, 첫 완료처럼 드물게 일어나는 성공 순간에 한 번 터지는 색종이 효과에 쓴다. | 1.12.1 | Web · Native | 개별 API 계약 참조 | 배포 |
60
- | [Chart](components/chart.md) | 데이터 표시 | 수치의 흐름·비교·몫·모양·관계를 그림으로 읽게 할 때 쓴다. | 1.21.0 | Web · Native | Web beta / Native beta | 배포 |
61
- | [ChatDateSeparator](components/chat-date-separator.md) | 데이터 표시 | 대화 타임라인에서 날짜(또는 오래 쉰 뒤의 시각)가 바뀌는 자리에 가운데 정렬 구분 줄을 둘 때 쓴다. | 1.31.0 | Web · Native | Web beta / Native beta | 배포 |
60
+ | [Chart](components/chart.md) | 데이터 표시 | 수치의 흐름·비교·몫·모양·관계를 그림으로 읽게 할 때 쓴다. | 1.21.0 | Web · Native | Web stable / Native stable | 배포 |
61
+ | [ChatDateSeparator](components/chat-date-separator.md) | 데이터 표시 | 대화 타임라인에서 날짜(또는 오래 쉰 뒤의 시각)가 바뀌는 자리에 가운데 정렬 구분 줄을 둘 때 쓴다. | 1.31.0 | Web · Native | Web stable / Native stable | 배포 |
62
62
  | [ChatMessage](components/chat-message.md) | 데이터 표시 | DM·대화 타임라인의 메시지 한 개에 쓴다. | 1.17.1 | Web · Native | Web stable / Native stable | 배포 |
63
63
  | [ChatRoomActions](components/chat-room-actions.md) | 구성/입력과 작성 | 나가기·내 기록 삭제·방 삭제를 구분해 확인한다. | 1.45.0 | Web · Native | 개별 API 계약 참조 | 배포 |
64
64
  | [ChatRoomCreate](components/chat-room-create.md) | 구성/입력과 작성 | 참여자를 검색·선택하고 사진·이름을 정해 방을 개설한다. | 1.45.0 | Web · Native | 개별 API 계약 참조 | 배포 |
@@ -74,7 +74,7 @@ Storybook 배포/실험은 예제 분류이며 npm 게시·기기 검증·제품
74
74
  | [CodeBlock](components/code-block.md) | 데이터 표시 | 코드·명령·설정 조각을 읽기 전용으로 보여 주고 사용자가 선택·복사하게 할 때 쓴다. | 1.12.1 | Web · Native | 개별 API 계약 참조 | 배포 |
75
75
  | [CohortRetentionTable](components/cohort-retention-table.md) | 구성/정보 표시 | 가입 시점(코호트)별로 기간마다 남은 인원 비율을 직사각형 표와 heat 색으로 비교할 때 쓴다. | 1.21.0 | Web · Native | 개별 API 계약 참조 | 배포 |
76
76
  | [Collapsible](components/collapsible.md) | 데이터 표시 | 이웃 없이 혼자 접었다 펴는 한 덩어리에 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
77
- | [ColorPicker](components/color-picker.md) | 입력 | 사용자가 콘텐츠 색(라벨 색, 태그 색, 테마 편집기의 사용자 값 등)을 sRGB HEX로 고르는 폼 입력에 쓴다. | 1.12.1 | Web | Web stable / Native unsupported | 배포 |
77
+ | [ColorPicker](components/color-picker.md) | 입력 | 사용자가 콘텐츠 색(라벨 색, 태그 색, 손그림 펜 색, 테마 편집기의 사용자 값 등)을 sRGB HEX로 고를 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
78
78
  | [Combobox](components/combobox.md) | 입력 | 주어진 목록에서 하나를 고르는데 목록이 길어 입력으로 좁혀야 할 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
79
79
  | [CommandPalette](components/command-palette.md) | 오버레이 | ⌘K 스타일로 앱 전체의 **행동**을 검색해 실행하는 모달에 쓴다. | 1.12.1 | Web | Web stable / Native unsupported | 배포 |
80
80
  | [CommentThreadRow](components/comment-thread-row.md) | 데이터 표시 | 가상화 목록(FlatList·가상 스크롤러)처럼 제품이 댓글 목록을 직접 그려야 할 때 댓글 한 행을 그린다. | 1.23.0 | Web · Native | Web stable / Native stable | 배포 |
@@ -83,11 +83,12 @@ Storybook 배포/실험은 예제 분류이며 npm 게시·기기 검증·제품
83
83
  | [Container](components/container.md) | 레이아웃 | 화면 본문의 최대 폭과 좌우(논리 방향) 여백을 맞출 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
84
84
  | [ContentTransition](components/content-transition.md) | 시각 효과 | 같은 자리의 내용이 상태에 따라 바뀔 때(필터 결과 패널, 단계별 본문) 새 내용이 짧게 나타나도록 감싼다. | 1.12.1 | Web · Native | 개별 API 계약 참조 | 배포 |
85
85
  | [ContextMenu](components/context-menu.md) | 탐색 | Web에서 제품이 소유한 영역(카드·목록 행·캔버스)의 우클릭·길게 누르기·Shift+F10에 명령 목록을 띄울 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native unsupported | 배포 |
86
+ | [ConversationListScreen](components/conversation-list-screen.md) | 화면/소통 | DM·단체방 대화 목록의 공통 화면이다. | 미게시(1.46.1 이후) | Web · Native | 개별 API 계약 참조 | 배포 |
86
87
  | [ConversationRow](components/conversation-row.md) | 화면/소통 | 대화 목록에서 상대, 마지막 메시지, 상대 시각, 안 읽음 점을 표시한다. | 1.24.0 | Web · Native | 개별 API 계약 참조 | 배포 |
87
88
  | [ConversionFunnel](components/conversion-funnel.md) | 구성/정보 표시 | 순차 단계(열기 → 작성 → 저장 등)의 인원을 가로 막대로 보여 주고, 단계를 골라 전체 대비·직전 대비 전환율과 이탈 수를 문구로 읽을 때 쓴다. | 1.21.0 | Web · Native | 개별 API 계약 참조 | 배포 |
88
89
  | [CorrelationMatrix](components/correlation-matrix.md) | 구성/정보 표시 | 여러 지표 사이의 상관계수(-1~1)를 정사각 대칭 표와 양·음 두 방향 heat 색으로 보여 줄 때 쓴다. | 1.21.0 | Web · Native | 개별 API 계약 참조 | 배포 |
89
90
  | [CounterBadge](components/counter-badge.md) | 데이터 표시 | 읽지 않은 알림·메시지·장바구니 수처럼 **셀 수 있는 개수**를 아이콘·행 옆에 작게 보일 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
90
- | [DataTable](components/data-table.md) | 데이터 표시 | 여러 행의 데이터를 열로 맞춰 훑고, 열 기준으로 정렬하거나 행을 골라 일괄 작업할 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native beta | 배포 |
91
+ | [DataTable](components/data-table.md) | 데이터 표시 | 여러 행의 데이터를 열로 맞춰 훑고, 열 기준으로 정렬하거나 행을 골라 일괄 작업할 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
91
92
  | [DatePicker](components/date-picker.md) | 입력 | 폼·필터 자리에서 날짜 **하나**를 고를 때 쓴다(생년월일, 방문일, 시작일 필터). 평소에는 필드 트리거만 보이고, 누르면 Web은 필드에 붙은 팝오버, Native는 Sheet 안에 같은 달력 격자를 연다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
92
93
  | [DateRangePicker](components/date-range-picker.md) | 입력 | 시작~끝 날짜 **구간**을 고를 때 쓴다(통계 기간, 예약, 검색 필터). 필드 트리거나 오버레이 없이 달력 격자를 그 자리에 펼쳐 둔다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
93
94
  | [DescriptionList](components/description-list.md) | 데이터 표시 | 라벨-값 쌍의 묶음을 보여 줄 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
@@ -103,6 +104,7 @@ Storybook 배포/실험은 예제 분류이며 npm 게시·기기 검증·제품
103
104
  | [FilePicker](components/file-picker.md) | 입력 | 사용자가 업로드할 로컬 파일을 고르게 할 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
104
105
  | [FilterRecovery](components/filter-recovery.md) | 구성/피드백과 복구 | 검색·필터 결과가 비었을 때 실제로 결과가 생기는 필터 완화 제안을 보여 주고, 사용자가 고른 하나를 명시적으로 적용할 때 쓴다. | 1.21.0 | Web · Native | 개별 API 계약 참조 | 배포 |
105
106
  | [FloatingActionButton](components/floating-action-button.md) | 동작 | 목록·피드처럼 스크롤되는 콘텐츠 위에 떠 있는 **단일 생성 행동**(새 기록 추가, 새 글 작성)에 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
107
+ | [FollowListScreen](components/follow-list-screen.md) | 화면/소통 | 팔로워/팔로잉을 전환하고 사람을 검색하며 각 행에서 팔로우할 때 사용한다. | 1.47.0 | Web · Native | 개별 API 계약 참조 | 배포 |
106
108
  | [FollowProfileCard](components/follow-profile-card.md) | 구성/정보 표시 | 프로필 카드에서 팔로우·팔로잉 전환과 팔로워 수를 실제 mutation 결과와 함께 보여 줄 때 쓴다. | 1.21.0 | Web · Native | 개별 API 계약 참조 | 배포 |
107
109
  | [Form](components/form.md) | 입력 | 여러 Field를 한 화면에 쌓고 한 번에 제출할 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
108
110
  | [Grid](components/grid.md) | 레이아웃 | 카드·타일처럼 같은 모양의 자식을 창 크기에 따라 열 수를 바꿔 배치할 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
@@ -112,7 +114,7 @@ Storybook 배포/실험은 예제 분류이며 npm 게시·기기 검증·제품
112
114
  | [IconButton](components/icon-button.md) | 동작 | 보이는 글자 없이 아이콘만으로 표시하는 행동에 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
113
115
  | [IconTile](components/icon-tile.md) | 데이터 표시 | 프로필·런처 격자의 아이콘 위/제목 아래 항목에 쓴다. | 1.26.0 | Web · Native | Web stable / Native stable | 배포 |
114
116
  | [Image](components/image.md) | 데이터 표시 | 원본 크기를 아는 사진·차트 이미지를 로드 전에 자리를 잡아 두고, 실패해도 의미를 잃지 않게 보여 줄 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
115
- | [ImageChoiceGroup](components/image-choice-group.md) | 입력 | 아바타 얼굴, 프로필 사진, 모음에 넣을 사진처럼 **그림을 보고 고르는** 단일·다중 선택에 쓴다. | 미게시(1.26.1 이후) | Web · Native | Web beta / Native beta | 배포 |
117
+ | [ImageChoiceGroup](components/image-choice-group.md) | 입력 | 아바타 얼굴, 프로필 사진, 모음에 넣을 사진처럼 **그림을 보고 고르는** 단일·다중 선택에 쓴다. | 미게시(1.26.1 이후) | Web · Native | Web stable / Native stable | 배포 |
116
118
  | [ImageComparison](components/image-comparison.md) | 데이터 표시 | 같은 좌표와 비율의 두 이미지를 겹쳐 변화량을 비교할 때 쓴다. | 1.14.0 | Web · Native | 개별 API 계약 참조 | 배포 |
117
119
  | [ImportFieldMapping](components/import-field-mapping.md) | 구성/입력과 작성 | CSV 등 원본 열을 제품의 대상 필드에 연결하고, 검증을 통과한 연결만 가져오기로 넘길 때 쓴다. | 1.21.0 | Web · Native | 개별 API 계약 참조 | 배포 |
118
120
  | [InlineEdit](components/inline-edit.md) | 구성/입력과 작성 | 목록·상세의 제목처럼 이미 확정된 짧은 값 하나를 그 자리에서 명시적으로 편집·저장·취소할 때 쓴다. | 1.21.0 | Web · Native | 개별 API 계약 참조 | 배포 |
@@ -143,8 +145,8 @@ Storybook 배포/실험은 예제 분류이며 npm 게시·기기 검증·제품
143
145
  | [OnboardingScreen](components/onboarding-screen.md) | 레이아웃 | 첫 실행 소개·초기 설정처럼 **몇 단계를 차례로 넘기는 화면**에 쓴다. | 1.14.0 | Web · Native | Web stable / Native stable | 배포 |
144
146
  | [OtpField](components/otp-field.md) | 입력 | 문자·메일로 받은 **숫자 인증번호**를 칸 모양으로 입력받을 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
145
147
  | [OverviewScreen](components/overview-screen.md) | 레이아웃 | 같은 데이터와 기능을 유지하면서 테마별 행·카드·격자와 도구 배치를 선택하는 목록 화면에 쓴다. | 1.15.0 | Web · Native | 개별 API 계약 참조 | 배포 |
146
- | [PageIndicator](components/page-indicator.md) | 탐색 | 제품이 직접 만든 가로 페이저(Native 페이징 `FlatList`, Web scroll-snap 줄) 아래에 지금 몇 번째 페이지인지 점으로 보여 주고, 점을 눌러 그 페이지로 옮길 때 쓴다. | 1.31.0 | Web · Native | Web beta / Native beta | 배포 |
147
- | [Pagination](components/pagination.md) | 탐색 | 총 개수(또는 총 페이지 수)가 정해진 결과 집합에서 사용자가 **임의의 페이지로 바로 이동**해야 할 때 Web·Native에서 쓴다. | 1.12.1 | Web · Native | Web stable / Native beta | 배포 |
148
+ | [PageIndicator](components/page-indicator.md) | 탐색 | 제품이 직접 만든 가로 페이저(Native 페이징 `FlatList`, Web scroll-snap 줄) 아래에 지금 몇 번째 페이지인지 점으로 보여 주고, 점을 눌러 그 페이지로 옮길 때 쓴다. | 1.31.0 | Web · Native | Web stable / Native stable | 배포 |
149
+ | [Pagination](components/pagination.md) | 탐색 | 총 개수(또는 총 페이지 수)가 정해진 결과 집합에서 사용자가 **임의의 페이지로 바로 이동**해야 할 때 Web·Native에서 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
148
150
  | [PasswordField](components/password-field.md) | 입력 | 비밀번호를 입력받고, 필요할 때만 값을 눈으로 확인하게 할 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
149
151
  | [PasswordRulesField](components/password-rules-field.md) | 구성/입력과 작성 | 새 비밀번호 입력 아래에 제품이 정한 규칙의 충족 개수와 규칙별 상태를 함께 보여 줄 때 쓴다. | 1.21.0 | Web · Native | 개별 API 계약 참조 | 배포 |
150
152
  | [PermissionScreen](components/permission-screen.md) | 레이아웃 | 카메라·위치·알림 같은 권한이 **왜 필요한지 설명하고 다음 행동을 고르게 하는** 화면에 쓴다. | 1.17.1 | Web · Native | Web stable / Native stable | 배포 |
@@ -174,6 +176,7 @@ Storybook 배포/실험은 예제 분류이며 npm 게시·기기 검증·제품
174
176
  | [SettingsScreen](components/settings-screen.md) | 레이아웃 | 앱의 설정 화면 전체에 쓴다. | 1.17.1 | Web · Native | Web stable / Native stable | 배포 |
175
177
  | [SharedTransitionElement](components/shared-transition-element.md) | 구성/직접 조작과 모션 | 목록의 카드(사진·썸네일)를 눌러 상세 화면으로 갈 때, 같은 요소가 두 화면 사이에서 확대·축소되어 이어지는 공유 요소 전환에 쓴다. | 1.12.1 | Native | 개별 API 계약 참조 | 배포 |
176
178
  | [SharedTransitionScreen](components/shared-transition-screen.md) | 구성/직접 조작과 모션 | `createHjmTransitionStack()`으로 만든 stack에서 공유 요소 전환을 쓸 때, **각 라우트 본문**을 감싼다. | 1.12.1 | Native | 개별 API 계약 참조 | 배포 |
179
+ | [ShareSheet](components/share-sheet.md) | 오버레이 | 링크 하나를 **앱 안의 받는 사람에게 보내거나(선택), 링크를 복사하거나, 기기 공유 시트로 내보내는** 공유 시트에 쓴다. | 미게시(1.47.0 이후) | Web · Native | 개별 API 계약 참조 | 실험 |
177
180
  | [Sheet](components/sheet.md) | 오버레이 | 현재 화면 위에 모달로 띄우는 보조 작업 패널에 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
178
181
  | [ShortcutRecorder](components/shortcut-recorder.md) | 구성/직접 조작과 모션 | Web 앱에서 사용자가 수정키+키 조합을 눌러 기록하고, 확인 뒤 실제 단축키로 등록하게 할 때 쓴다. | 1.21.0 | Web | 개별 API 계약 참조 | 배포 |
179
182
  | [Sidebar](components/sidebar.md) | 탐색 | 데스크톱 Web의 세로 내비게이션에 쓴다. | 1.12.1 | Web | Web stable / Native unsupported | 배포 |
@@ -214,7 +217,7 @@ Storybook 배포/실험은 예제 분류이며 npm 게시·기기 검증·제품
214
217
  | [TransferList](components/transfer-list.md) | 입력 | 한 항목 집합을 두 목록으로 나누고 사용자가 항목을 오가게 할 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
215
218
  | [TransferTask](components/transfer-task.md) | 구성/피드백과 복구 | 업로드·다운로드·동기화처럼 실제 전송 계층이 진행량을 알려 주는 작업에 시작·취소·진행률·결과를 한 묶음으로 붙인다. | 1.21.0 | Web · Native | 개별 API 계약 참조 | 배포 |
216
219
  | [Tree](components/tree.md) | 데이터 표시 | 깊이가 정해지지 않은 계층 데이터를 펼치고 접으며 탐색하고, 그 안에서 하나 또는 여럿을 고를 때 쓴다. | 1.12.1 | Web | Web stable / Native unsupported | 배포 |
217
- | [TypingIndicator](components/typing-indicator.md) | 상태와 알림 | 대화 타임라인에서 상대가 지금 입력 중임을 보여 줄 때 쓴다. | 1.31.0 | Web · Native | Web beta / Native beta | 배포 |
220
+ | [TypingIndicator](components/typing-indicator.md) | 상태와 알림 | 대화 타임라인에서 상대가 지금 입력 중임을 보여 줄 때 쓴다. | 1.31.0 | Web · Native | Web stable / Native stable | 배포 |
218
221
  | [UploadItem](components/upload-item.md) | 데이터 표시 | 사용자가 고른 파일 **한 개**의 업로드 상태(대기·전송 중·완료·실패)를 한 행으로 보여 줄 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
219
222
  | [VirtualList](components/virtual-list.md) | 데이터 표시 | 행 높이가 **모두 같은** 긴 목록(수백~수천 행)을 정해진 높이 안에서 스크롤할 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
220
223
  | [VisuallyHidden](components/visually-hidden.md) | 기반 기능 | Web에서 화면에는 보이지 않지만 스크린 리더는 읽어야 하는 **문맥 문구**를 덧붙일 때 쓴다. | 1.12.1 | Web | Web stable / Native unsupported | 배포 |
@@ -322,6 +325,7 @@ Storybook 배포/실험은 예제 분류이며 npm 게시·기기 검증·제품
322
325
  | [신고와 차단](screens/flow-moderation.md) | 소통 | ModerationScreen을 사용해 신고와 차단 흐름을 구성한다. | 구성 API 지침 참조 | Web · Native | 구성 API별 | 배포 |
323
326
  | [알림함](screens/common-inbox.md) | 소통 | NotificationInboxScreen을 사용해 알림함 흐름을 구성한다. | 구성 API 지침 참조 | Web · Native | 구성 API별 | 배포 |
324
327
  | [채팅](screens/common-chat.md) | 소통 | ChatScreen을 사용해 채팅 흐름을 구성한다. | 구성 API 지침 참조 | Web · Native | 구성 API별 | 배포 |
328
+ | [팔로워와 팔로잉](screens/common-follow-list.md) | 소통 | 두 관계 목록을 검색하고 프로필로 이동하며 팔로우한다. | 1.47.0 | Web · Native | 구성 API별 | 배포 |
325
329
  | [기록 표현 비교](screens/reference-comparison.md) | 화면 틀과 도구 | ScreenLayout을 사용해 같은 기록의 세 가지 구성 흐름을 구성한다. | 구성 API 지침 참조 | Web · Native | 구성 API별 | 배포 |
326
330
  | [목업 편집](screens/mockup-studio.md) | 화면 틀과 도구 | 제품 화면 캡처를 휴대폰·브라우저 프레임에 넣어 스토어·소개용 이미지(PNG)와 짧은 장면 영상을 만드는 Web 전용 작업 도구 화면이다. | 1.12.1 | Web | 구성 API별 | 배포 |
327
331
  | [화면 골격과 상태](screens/common-shell.md) | 화면 틀과 도구 | ScreenLayout을 사용해 화면 골격 흐름을 구성한다. | 구성 API 지침 참조 | Web · Native | 구성 API별 | 배포 |
@@ -150,3 +150,112 @@ HJM 공통 구성이 선택을 소유하고 제품 adapter는 `presentation`을
150
150
  [Menu 전사 개발 선택](components/menu.md#전사-개발-적용-선택--2026-10-20)을 따른다.
151
151
 
152
152
  2026-10-23 사용자 지시: 익숙한 아이콘 하나로 의미를 전달할 수 있는 보조 행동은 본문·오류 안내에서도 `IconButton`을 사용한다. 접근성 `label`과 Web 설명(title/Tooltip), pending·disabled·포커스 복구를 보존한다. 재전송은 refresh, 이전 상태로 돌아가기는 되돌리기 아이콘으로 구분한다. 메뉴 행의 이름과 삭제 확인·결제·동의 같은 최종 의사 확인 문구는 유지한다.
153
+
154
+
155
+ ### 목록 이관의 확인 단위 (2026-10-25)
156
+
157
+ 번뚝에서 행 컴포넌트만 공통으로 바꾸고 부모의 카드·여백·구분선을 남겨 화면이 달라졌다.
158
+ 목록은 실제 route/scroll host → 공통 화면/구성 → 목록 → 행까지 함께 확인한다.
159
+ 대화는 ConversationListScreen, 알림은 NotificationInboxScreen의 행 종류 계약,
160
+ 검색은 SearchScreen과 List/ListRow를 먼저 선택한다. 일반 목록의 묶음 표면은 List appearance를
161
+ 사용하며 단순 행을 Card로 다시 감싸지 않는다. 지도 위 정보판·선택 가능한 복합 카드처럼
162
+ 고유 역할이 있는 표면까지 없애는 규칙은 아니다.
163
+
164
+ 변경한 배치 확인에서는 실제 HJM 구현과 데이터가 있는 목록을 사용한다.
165
+ 링크로 대체한 mock·빈 상태·타입 검사만으로 목록의 시각 일치를 보고하지 않는다.
166
+ 이는 기존 변경 범위 검사의 대상 선택이며 새 CI 게이트나 전수 회귀 의무가 아니다.
167
+
168
+ ### 소비 화면 조합 검사 (2026-10-25)
169
+
170
+ 같은 공통 행을 쓰면서 바깥 카드·여백이 남고, 본문 Stack 간격이 행동 묶음에 적용됐으며,
171
+ 제품 팔레트까지 공통 기본값으로 교체된 사고를 보완한다. 공통 레이아웃을 먼저 선택하고
172
+ 제품의 데이터·문구·테마는 보존한다. 검사 통과는 실제 화면 일치의 증명이 아니다.
173
+
174
+ 기존 `scripts/audit-consumer-ui.mjs`는 제품의 `app.contract.json`에 등록된 mobile/web 소스를
175
+ 검사한다. 포트폴리오 루트를 주면 `portfolio.json`의 모든 제품을 순회한다. 폐기되어
176
+ checkout이 없는 제품은 제외 사유를 표시하고, 그 외 누락·분석 실패는 unavailable로 남긴다.
177
+
178
+ HJM 저장소에서 실행:
179
+
180
+ ```sh
181
+ node scripts/audit-consumer-ui.mjs ../../apps/diairy /tmp/diairy-ui.json --check
182
+ node scripts/audit-consumer-ui.mjs ../.. /tmp/portfolio-ui.json --check
183
+ node --test scripts/audit-consumer-ui.test.mjs
184
+ ```
185
+
186
+ - 간격 값은 authored `foundations.ts`·`component-recipes.ts`에서 읽는다. 별도 숫자 규격표를 복제하지 않는다.
187
+ - 확정 위반: 직접 HJM Button·standalone Link 행동의 인접 배치를 소유한 Stack의 정적 gap이 actionGroupRecipe와 다름.
188
+ - 검토 후보: 행을 감싼 카드/여백, 반복 행의 Stack 간격, 중첩 스크롤, 제품 탭 역할, 자체 상태 UI,
189
+ 공통 컴포넌트 style 덮어쓰기, HEAD 대비 테마 주입 제거/기본 팔레트 교체. 후보를 자동 수정하거나 예외 목록으로 숨기지 않는다.
190
+ - 별칭·namespace·fragment·조건부 분기를 해석한다. 상호 배타적인 버튼을 동시에 놓인 것으로 세지 않는다.
191
+ 단순 로컬 Button 어댑터는 import 경로로 추적하되 실제 geometry는 확정하지 않는다.
192
+ - CSS, 복잡한 어댑터·동적 스타일·portal·실행 상태·전체 route 도달성은 정적 검사만으로 보장하지 않는다.
193
+ 보고서의 raw control/local component 목록과 화면 실측으로 확인한다. 후보 0개도 준수 완료가 아니다.
194
+ - `--check`는 확정 위반에 1, 범위 누락에 2를 반환한다. 후보는 보고서에서 별도로 검토한다.
195
+ 배포 CI에는 새 게이트를 붙이지 않는다. 작은 수정은 대상 제품과 관련 테스트를 선택하고 전사 순회는 명시 요청 때 실행한다.
196
+ - 공통 화면의 실제 폭·여백·상태·안전 영역·행동 영역은 기존 Web browser/Native screen 테스트가 검사한다.
197
+ 제품 테마는 실제 Provider 입력 팔레트와 제품 팔레트의 연결을 제품 테스트에서 확인한다.
198
+ 다에리 Web/Native와 스핀트 Native는 2026-10-25 테마 소실 회귀를 추가했다.
199
+
200
+ 2026-10-25 후보 후속 검토: 조건부 분기의 전체 조합을 열거하던 64개 한도는 제거했다.
201
+ 첫/끝 요소와 가능한 인접 쌍을 합성해 조건부 영역이 많은 화면에서도 행동 간격 검사를 수행한다.
202
+ 일반 텍스트 Link를 행동 묶음으로 오인하지 않으며 standalone Link만 버튼과 함께 검사한다.
203
+ 검토 기록은 원래 파일 hash와 검토한 현재 hash, 판단 근거를 보존한다.
204
+ 제품별 사용자 결정이나 지원되는 style 입력은 검토 사유이지 자동 검사 면제 목록이 아니다.
205
+
206
+ ### Native 헤더와 상단 안전 영역 검사
207
+
208
+ 2026-10-25 번뚝 팔로워 화면은 네이티브 헤더를 숨긴 뒤 FollowListScreen만 연결해 상태 표시줄과
209
+ 제목이 겹쳤다. Provider가 inset을 알고 있다는 사실만으로 화면에 여백이 적용되지는 않는다.
210
+ 네이티브 헤더가 없는 전체 화면은 `ScreenHost`가 상단·좌우 inset을 맡고 화면은 하단을 맡는다.
211
+ 이미 navigator/상위 ScreenHost/SafeAreaView가 상단을 확보하면 다시 더하지 않는다.
212
+ `ScreenLayout.safeAreaTop`은 헤더 없는 본문용이며 표시되는 헤더 위 여백의 대체재가 아니다.
213
+
214
+ 기존 소비 검사기는 Native 화면의 JSX 조상에 상단 ScreenHost 또는 SafeAreaView가 확인되지 않으면
215
+ `safe-area-top-owner` 검토 후보로 남긴다. 다른 파일의 navigator·SafeAreaView·Provider 연결을
216
+ 추적해야 하므로 이 후보를 곧바로 위반으로 확정하거나 일괄 wrapper 추가하지 않는다.
217
+ 정적으로 확인되는 상단 host 안의 ScreenHost 중첩은 `safe-area-top-duplicate` 위반이다.
218
+ 동적 edges/spread는 소유자가 확인된 것으로 처리하지 않는다. 실제 기기에서는 상태 표시줄 아래
219
+ 헤더 위치를 별도로 확인한다. Native host 테스트는 기기 좌표 측정의 대체 증거가 아니다.
220
+
221
+ ### 예방 검사 범위와 판정 갱신 (2026-10-25)
222
+
223
+ 목록·간격만 확인하면 행동 역할·상단 도구·입력 포커스가 빠진다는 사용자 지적을 반영했다.
224
+ 기존 검사기에 역할/포커스 검토와 판정 근거 갱신을 추가하며 별도 배포 게이트는 만들지 않는다.
225
+
226
+ | 지침 경계 | 현재 자동 확인 | 반드시 별도로 판단할 범위 |
227
+ | --- | --- | --- |
228
+ | 행동 묶음 간격 | `action-group-gap`, authored recipe 값 | CSS/View/복잡한 wrapper의 최종 간격 |
229
+ | 주·보조 행동/같은 크기 | `competing-primary-actions`, `action-size-mismatch` 후보 | 독립 행동인지, 조건이 동시에 참인지, 실제 폭·높이 |
230
+ | 선택/설정 제어 | `selection-control` 후보 | 실행 결과 상태와 단일/다중 선택·설정의 구분 |
231
+ | 상단 도구 | `header-text-action`, `header-tool-size`, `header-tool-gap` 후보 | 제품 헤더 adapter, 아이콘 의미·개수, 탐색/제목 중복 |
232
+ | 목록·본문 여백 | `row-rhythm`, `list-wrapper`, `screen-gutter` 후보 | 카드의 도메인 의미, 최종 좌우·상하 대칭 |
233
+ | 상단 안전 영역 | `safe-area-top-owner`, `safe-area-top-duplicate` | route/navigator/Sheet의 상단 소유권, 실제 상태 표시줄 좌표 |
234
+ | 스크롤·상태 | `scroll-owner`, `state-owner` 후보, 기존 composition-state-height 테스트 | 가상화·overflow·키보드·footer·정중앙·경계 배경 |
235
+ | 입력 포커스 | `input-focus-owner`, `imperative-focus` 후보, 기존 initial-focus 테스트 | 제출 오류/명시적 편집/복귀와 진입·단계 자동 포커스의 구분 |
236
+ | 테마/표현 | HEAD 대비 팔레트 제거 탐지, 공개 style override 후보 | 제품별 승인·라이트/다크·장면 artwork·색 대비 |
237
+ | 전체 화면 기하 | 기존 screen-chrome/screen-insets browser 테스트 | 소비 앱의 실제 화면·긴 문구·좁은 폭·오버레이/스크롤 상태 |
238
+ | 키보드/접근성 | 기존 keyboard-field-visibility·focus 테스트 | 소비 앱 이름/읽기 순서/동작, 실제 플랫폼 키보드 |
239
+ | 사용 계약/버전 | 소스 inventory와 앱 contract 표면 목록 | 공개 export/설치 버전, 실제 실행 bundle, route 도달성 |
240
+
241
+ 단순 named import와 barrel 재수출, React `forwardRef`/`memo` Button·IconButton 어댑터를 추적한다.
242
+ 어댑터의 prop 기본값·동적 값까지 증명하는 것은 아니므로 해당 결과는 검토 후보다.
243
+ 조건 요약은 JSX 분기를 보존하지만 서로 다른 boolean 식의 논리적 상호 배타성까지 증명하지 않는다.
244
+ 후보가 없어도 위 표의 수동/실측 범위는 통과로 바꾸지 않는다. 최대 글자 설정은 포트폴리오 지침대로 제외한다.
245
+
246
+ 포트폴리오 루트와 기존 판정 보고서를 함께 주면 근거 변경을 확인한다:
247
+
248
+ ```sh
249
+ node scripts/audit-consumer-ui.mjs ../.. /tmp/portfolio-ui.json --reviews ../../docs/design/audits/2026-10-25-ui-composition.json --check
250
+ ```
251
+
252
+ `candidateReview`·`headerSafetyAudit`·`extendedReview`의 현재 소스 해시와 `evidence` 경로/해시를
253
+ 대조한다. 바뀌거나 삭제되면 `stale`, 의존 근거가 없으면 `dependencies-unrecorded`, 모두 같으면
254
+ `source-unchanged`다. **마지막 값도 화면 합격을 뜻하지 않는다.** 후보를 숨기지 않고 다시 보여주며,
255
+ 변경된 소유 구현/조건을 재검토한 뒤에만 판정·근거를 갱신한다. 파일을 다시 읽지 않고 해시만 덮어쓰지 않는다.
256
+
257
+ ### 회원 사진의 기본 동작 (2026-10-25)
258
+
259
+ 댓글·공용 채팅까지 모든 회원 아바타는 해당 회원 프로필로 연결한다. [Avatar의 회원 프로필 이동](components/avatar.md#회원-프로필-이동-2026-10-25)을 따른다.
260
+ 상위 구성의 avatarAction/leadingAction/memberProfile을 우선 연결하고 회원 ID·route는 제품이 소유한다.
261
+ 사진 확대만 연결하거나, 본문 링크 안에 프로필 버튼을 중첩하거나, 장식 접근성 wrapper 안에 버튼을 넣지 않는다.
@@ -70,9 +70,9 @@ import { Avatar } from "@hjmds/react-native/data-display";
70
70
  | `name` | `string` | 의미 있는 아바타는 필수 | 이니셜과 기본 접근성 이름의 원천. 공백뿐이면 `TypeError`. `decorative`이면 생략할 수 있다(이니셜 없이 액자·대체 그림만) |
71
71
  | `decorative` | `boolean` | `false` | 옆에 이름이 보이는 작성자 표시나 사람 없는 장식. Web은 루트 `aria-hidden`·`img alt=""`이고 `alt`를 함께 줄 수 없다. Native는 `accessibilityLabel`을 함께 줄 수 없다 |
72
72
  | Web `src` · Native `source` | `string` · `ImageSourcePropType` | — | 사진이 없으면 prop을 뺀다. 주소(Native는 source 내용)가 바뀌면 실패 상태를 지우고 다시 시도한다 |
73
- | `size` | `xxsmall`(22) · `xsmall`(28) · `small`(32) · `medium`(40) · `touch`(44) · `large`(48) · `xlarge`(64). Native는 기존 숫자(pt)도 받는다 | Web `medium` · Native 44(`touch`) | `avatarRecipe.sizes`. Native 숫자가 22 미만이면 `RangeError`(2026-10-23 전에는 24). 새 코드는 단계 이름을 쓴다 |
73
+ | `size` | `xxsmall`(22) · `xsmall`(28) · `small`(32) · `medium`(40) · `touch`(44) · `large`(48) · `xlarge`(64). Native는 기존 숫자(pt)도 받는다 | Web·Native `large`(48) | `avatarRecipe.sizes`. Native 숫자가 22 미만이면 `RangeError`(2026-10-23 전에는 24). 새 코드는 단계 이름을 쓴다 |
74
74
  | `shape` | `circle` · `rounded` | `circle` | `rounded`는 `radius.md`(가장 가까운 디자인 프로필) |
75
- | `frame` | `outlined` · `surface` · `none` | `outlined` | `avatarRecipe.frames`. `outlined`=canvas 바탕+1px 테두리(기존), `surface`=바탕만, `none`=바탕·테두리 없음(제품 그림이 액자를 채울 때) |
75
+ | `frame` | `outlined` · `surface` · `none` | `outlined` | `avatarRecipe.frames`. `outlined`=canvas 바탕+borderControl 50% alpha의 1px 테두리, `surface`=바탕만, `none`=바탕·테두리 없음(제품 그림이 액자를 채울 때) |
76
76
  | `accessory` · `accessoryPlacement` | `ReactNode` · `bottom-end` · `top-end` | — · `bottom-end` | 팀 배지·상태 점 같은 모서리 표식. 아바타 상자 모서리(`avatarRecipe.accessory.offset` 0, Asset·IconTile처럼 바깥으로 나가는 거리)에 붙고 액자에 잘리지 않는다. 누르는 요소를 넣지 않는다 |
77
77
  | `renderFallback` | `(context: { size: number; decorative: true }) => ReactNode` | — | 사진이 없거나 실패했을 때만 불린다. `size`는 px/pt 값. null·undefined를 돌려주면 기본 대체 표시(Web `fallback`→이니셜, Native 이니셜)를 쓴다 |
78
78
  | Web `alt` | `string` | `name` | `""`이면 보조기기에서 숨긴다 |
@@ -82,13 +82,13 @@ import { Avatar } from "@hjmds/react-native/data-display";
82
82
  | Native `renderImage` | `(context: AvatarImageRenderProps) => ReactNode` | 기본 Native Image | 제품의 이미지 캐시·표시 호스트를 연결한다(1.14.0 추가). `source`, `size`, HJM `fallback`, 세대가 보호된 `onError` 제공 |
83
83
  | Native `initials` | `string` | 이름에서 계산 | 앞뒤 공백을 지우고 최대 3자, 대문자 |
84
84
  | `layoutStyle` | margin·width·flex·`alignSelf` | — | 배치 전용. Native `style`·`imageStyle`은 제거된 속성 — layoutStyle 또는 `size`/`renderFallback` |
85
- | `AvatarGroup`(Web) `label` · `size` · `overflow` | `string` · Avatar 크기 · `ReactNode` | `label` 필수 · `size` `medium` | 빈 `label`은 `TypeError`. `overflow`는 제품이 만든 "+3" 같은 문구이며 `aria-hidden`이다(남은 인원은 `label`에 담는다). 겹침은 크기의 30%다 |
85
+ | `AvatarGroup`(Web) `label` · `size` · `overflow` | `string` · Avatar 크기 · `ReactNode` | `label` 필수 · `size` `large` | 빈 `label`은 `TypeError`. `overflow`는 제품이 만든 "+3" 같은 문구이며 `aria-hidden`이다(남은 인원은 `label`에 담는다). 겹침은 크기의 30%다 |
86
86
 
87
87
  ## 배치
88
88
 
89
89
  | 항목 | 값 | 근거 |
90
90
  | --- | --- | --- |
91
- | 크기 | `xxsmall` 22 · `xsmall` 28 · `small` 32 · `medium` 40 · `touch` 44 · `large` 48 · `xlarge` 64. 댓글·칩 안 작은 작성자 표시는 `xxsmall`/`xsmall`, 목록 행에는 Web `medium`/Native 기본, 프로필 머리에는 `xlarge`. 감싼 요소 크기(`h-8` 등)로 맞추지 말고 단계를 고른다. Avatar 자체는 터치 대상이 아니므로 누르는 프로필은 감싸는 행·버튼이 최소 44를 확보한다 | `.hjm-avatar[data-size]`, `react-native/src/data-display.tsx` |
91
+ | 크기 | `xxsmall` 22 · `xsmall` 28 · `small` 32 · `medium` 40 · `touch` 44 · `large` 48 · `xlarge` 64. 댓글·칩 안 작은 작성자 표시는 `xxsmall`/`xsmall`, 일반 회원 목록과 프로필 머리에는 `large`(48). 감싼 요소 크기(`h-8` 등)로 맞추지 말고 단계를 고른다. 표시 전용 Avatar는 터치 대상이 아니다. 프로필 이동은 상위 구성의 전용 행동 또는 Avatar.action을 연결해 최소 44를 확보한다 | `.hjm-avatar[data-size]`, `react-native/src/data-display.tsx` |
92
92
  | 간격 | 자체 바깥 여백이 없다. `AvatarGroup`은 크기의 30%만큼 겹치고 각 아바타에 `bg` 색 2px 테두리를 둘러 경계를 만든다 | `.hjm-avatar-group` |
93
93
  | 순서·정렬 | 행·카드·댓글 머리의 시작 쪽에 두고 이름·본문이 끝 쪽으로 이어진다. `AvatarGroup`의 넘친 수 표시는 맨 끝에 온다 | `.hjm-avatar-group__overflow` |
94
94
  | 고정·스크롤 | 고정 영역이 없다 | — |
@@ -163,7 +163,32 @@ Avatar를 쓰지 못한 이유(이름 필수, Web 이미지 호스트 없음, 4
163
163
  // Web: 작성자 이름 옆의 장식 아바타, 제품 SVG가 액자를 채운다
164
164
  <Avatar decorative size="xsmall" frame="none" {...(svgUrl ? { src: svgUrl } : {})} fallback={emoji} />
165
165
 
166
- // Native: 둥근 사각형 선수 사진 + 모서리 팀 배지
167
- <Avatar name={player.name} accessibilityLabel={player.name} size="large" shape="rounded"
166
+ // Native: 원형 선수 사진 + 모서리 팀 배지
167
+ <Avatar name={player.name} accessibilityLabel={player.name} size="large" shape="circle"
168
168
  {...(uri ? { source: { uri } } : {})} accessory={<TeamBadge team={team} />} />
169
169
  ```
170
+
171
+ ### 회원 프로필 이동 (2026-10-25)
172
+
173
+ 회원 사진을 표시만 하거나 확대 보기만 연결한 사용처가 남아 사용자 요청으로 기본 행동을 통일했다.
174
+ `Avatar`는 Web·Native 모두 `action={{label: t("profile.open"), onPress: () => openMember(member.id)}}`를 받는다.
175
+ 이름 있는 버튼이 장식 사진을 감싸며 사진이 실패하거나 이니셜만 있어도 이동은 유지된다.
176
+ 라우트·회원 ID·권한은 제품이 공급하고, HJM은 최소 44px/pt 영역과 접근성 이름을 소유한다.
177
+ 별도 프로필 행동이 있는 사진 자식은 항상 장식이다. 프로필 버튼 자체를 `aria-hidden`/`no-hide-descendants`로 숨기지 않는다.
178
+
179
+ 상위 구성의 전용 API를 먼저 사용한다. 댓글은 `avatarAction`, 채팅은 `avatarAction`, 알림은 `NotificationRow.avatarAction`,
180
+ 일반 목록은 `ListRow.leadingAction`, 카드 작성자는 `Card.leadingAction`, 대화 목록은 `ConversationRow.avatarAction` + `renderBody`, 참여자는 `ChatRoomMembers.memberProfile`이다.
181
+ 같은 사진에 `Avatar.action`과 상위 `avatarAction`을 함께 넣지 않는다. 본문 링크/버튼과 독립 프로필 버튼은 형제다.
182
+
183
+ 회원 식별자가 없는 장식·방 사진을 회원 프로필로 연결하지 않는다. 명시적인 사진 편집·공유 대상 선택은 원래 작업을 유지한다.
184
+
185
+ 내 프로필 화면의 내 사진은 예외로 그 자체가 사진 변경 버튼이다(2026-10-25 사용자 지시). `action={{label: t("photo.change"), onPress: openPhotoPicker}}`를 연결하고 사진 고르기·자르기·업로드는 제품이 소유한다. 같은 화면에 중복 "사진 바꾸기" 버튼을 두지 않는다.
186
+ 제품의 실제 회원 화면이 없으면 실제 공개 데이터의 화면부터 제공한다. 이미 그 회원 화면이면 중복 이동하지 않는다.
187
+
188
+ 프로필 행동의 `disabled`는 전송·삭제 등 현재 작업이 경로 이탈을 막는 동안 사용한다. 버튼을 없애거나 활성 버튼에서 오류를 무시하는 대신 동일한 이름과 비활성 의미를 유지한다.
189
+
190
+ ## 일반 회원 크기 (2026-10-25)
191
+
192
+ 사용자 요청으로 Web·Native 기본값은 `size="large"`(48), `shape="circle"`이다. 프로필과 일반 회원 목록에도 48을 쓰고 댓글·채팅 등 촘촘한 목록의 명시적인 작은 단계는 유지한다. 제품별 사진·이니셜·이모지·동물 그림도 같은 회원 프레임을 따른다. 콘텐츠 썸네일·앱 아이콘의 모양이나 크기에는 적용하지 않는다.
193
+
194
+ 기본 `frame="outlined"`는 `border.control` 50% alpha, 1px의 원형 윤곽이다. 2026-10-25 번뚝 이모지 아바타에서 기존 선은 흐리고 2px 불투명 선은 진하다는 피드백을 거쳐 1px·50%로 조정했으며, 사용자가 이 값을 디자인 시스템 기본값으로 지정했다. 지름은 테두리 포함이고 Web·Native에 동일하다. 미게시 개발 중 추가했던 `strong` 옵션은 기본값과 합쳐 제거했다. 제품에서 별도 frame을 지정할 필요가 없다.
@@ -70,7 +70,7 @@ const seriesColor = { light: "#216BA8", dark: "#216BA8" } as const; // 제품
70
70
  | --- | --- | --- | --- |
71
71
  | `tone` | `neutral` · `strong` · `brand` · `info` · `success` · `warning` · `attention` · `danger` | `neutral` | 단색 배경과 흰색 굵은 글자를 사용한다. `neutral`은 회색, `strong`은 더 진한 회색, 나머지는 각 의미의 solid fill이다. `outline`은 투명 배경과 의미색 글자다 |
72
72
  | `categoryColor` | `{ light: string; dark: string }`(6자리 hex) | — | `tone` 대신 쓰는 제품 분류 색. 글자색은 HJM이 고르고 AA를 검사한다(위 절). 개발 소스, 미게시 |
73
- | `variant` | `filled` · `outline` | `filled` | — |
73
+ | `variant` | `filled` · `outline` · `plain` | `filled` | — |
74
74
  | `size` | `small` · `medium` | `medium` | — |
75
75
  | `leading` · `trailing` | `ReactNode \| (context: BadgeAdornmentContext) => ReactNode` | — | 라벨 왼쪽·오른쪽 아이콘. 양쪽 동시 사용 가능하며 보조기기에서 숨겨진다 |
76
76
  | Web `children` · Native `label` | `ReactNode` · `string \| number`(필수) | — | 표시 라벨 |
@@ -108,3 +108,12 @@ Web·Native 모두 `radius.sm`(8)의 둥근 사각형을 사용한다. 2026-10-1
108
108
  | 배치 | `layoutStyle` | `layoutStyle`(`style`은 제거된 속성) |
109
109
  | 라벨 스타일 훅 | 없음 | `labelStyle` 제거된 속성 — tone/토큰 |
110
110
  | 기본 폭 | inline | `alignSelf: "flex-start"` |
111
+
112
+ ### 테두리 없는 상태 — 개발 소스, 미게시
113
+
114
+ 2026-10-26 오늘야구 라이브 표시 요청에 따라 `variant="plain"`을 추가했다.
115
+ outline과 같은 의미색 글자를 유지하고 배경·테두리를 없앤다. 점은 `leading`에 장식 노드로 전달한다.
116
+
117
+ ```tsx
118
+ <Badge label="진행 중" tone="danger" variant="plain" size="small" />
119
+ ```
@@ -279,3 +279,19 @@ Tab은 탐색 막대에 한 번 진입하고, 방향키·Home·End는 포커스
279
279
 
280
280
  `presentation: "capsule"`의 선택 항목은 `selectionCapsule`의 neutral 선택 배경과 글자를 쓴다.
281
281
  기본 아이콘·글자 탐색의 위치 강조와 명시적 `selection: "tile"`의 브랜드 면은 기존 계약을 따른다.
282
+
283
+
284
+ ## 타일 바탕과 선택 강조 분리 (2026-10-25)
285
+
286
+ 오늘야구에서 선택된 파란 타일은 유지하면서 바탕을 흰색으로 사용하려는 요청으로
287
+ `configuration.tone: "brand" | "neutral"`을 추가했다. 기본 `brand`는 기존 surfaceAccent 바탕을 유지한다.
288
+ `neutral`은 `semanticColors.surface.default`(테마의 surface)를 사용한다. 라이트 기본 테마에서는 흰색,
289
+ 다크에서는 어두운 공통 표면이며 선택 타일의 primary/onPrimary와 모양·간격·동작은 유지한다.
290
+ flat tile 전용이며 raised 표면과 함께 지정하면 오류다. 앱에서 팔레트나 style을 덮어쓰지 않는다.
291
+
292
+ ```tsx
293
+ configuration={{ presentation: "floating", selection: "tile", tone: "neutral" }}
294
+ ```
295
+
296
+ Web·Native의 `NeutralTiles`와 `NeutralTilesDark` Storybook 예제가 같은 공개 API를 사용한다.
297
+ 로컬 개발 API이며 게시된 패키지 지원은 해당 릴리스에 포함된 뒤 확인한다.
@@ -108,6 +108,17 @@ import { Button } from "@hjmds/react-native/actions";
108
108
  └──────────────────────────────┘ └──────────────────────┘
109
109
  ```
110
110
 
111
+ ## 연속 버튼의 색상 구분 (2026-10-25)
112
+
113
+ 번뚝의 ‘내 버전 만들기’와 ‘그대로 가져가기’가 같은 파란색으로 연속 표시되어 행동의 우선순위가
114
+ 구분되지 않았다는 사용자 지적을 반영한다. **가로·세로로 연속되는 서로 다른 행동 버튼에는 다른 색을 쓴다.**
115
+ 주 행동은 `tone="primary"`, 보조 행동은 `tone="secondary"` 또는 `ghost`로 배경·글자색을 구분한다.
116
+ 단순히 tone 이름만 다르게 지정하지 말고 제품 테마의 실제 색도 구분되는지 확인한다.
117
+ 색은 HJM tone·semantic token으로 연결하며 버튼별 임의 색상 하드코딩이나 의미 없는 무지개색 배치는 하지 않는다.
118
+ 세 개 이상이면 주 행동 하나를 강조하고 나머지 보조 행동은 같은 중립색 계열을 공유할 수 있다.
119
+ 선택지·탭·토글의 같은 역할 항목은 각 선택 컴포넌트의 상태 색상 계약을 따른다.
120
+ Web·Native와 라이트·다크 테마에 동일하게 적용한다.
121
+
111
122
  ## 꼭 지킬 것
112
123
 
113
124
  - Button은 callback의 Promise를 자동으로
@@ -1,5 +1,7 @@
1
1
  # Card
2
2
 
3
+ 2026-10-25 번뚝 글자 크기 리뷰 반영(개발 소스·미게시): 카드 제목은 `bodyLarge` 16/24, `medium` 굵기를 사용한다. 반복 카드가 페이지 제목과 경쟁하지 않도록 양 renderer에 동일하게 적용한다.
4
+
3
5
  - 단계: 컴포넌트
4
6
  - 상태: 배포
5
7
  - 지원: Web · Native
@@ -293,3 +295,7 @@ QuoteCard가 자동으로 원문을 자르거나 열지 않는다. 이 API의
293
295
  다에리 편지·장소 기록은 새 탭·가운데 클릭·링크 미리보기를 보존해야 하므로 버튼 callback으로 바꾸지 않는다. `href`는 공통 카드의 media·본문을 덮는 별도 이름 있는 anchor를 만들고, `actions`는 그 위의 독립 대상으로 남긴다. 본문/그림은 링크 이름에 모두 합치지 않고 `aria-label`에 제품이 고른 짧은 이름을 준다. 프레임워크 링크·소리·초안 정리는 `renderLink`가 받은 href/className/접근성 props를 그대로 전달하면서 연결한다. 카드·배지 위치·표면·누름 피드백을 제품 CSS로 다시 조립하지 않는다. Native 목적지 이동은 기존 `onActivate` 콜백으로 연결한다.
294
296
 
295
297
  <!-- usage-example: Web ../../../../../showcase/web/src/components/Card.stories.tsx -->
298
+
299
+ ### 회원 프로필 이동 (2026-10-25)
300
+
301
+ `leadingAction={label,onPress}`로 leading의 작성자 사진을 해당 회원 프로필에 연결한다. 카드 전체 `onActivate`/`href`와 독립된 형제 컨트롤이며 Native의 접근성 카드 안에 프로필 버튼을 중첩하지 않는다. 사진에는 별도 Avatar.action을 함께 넣지 않는다.