@hjmds/design-contracts 1.15.0 → 1.16.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.
- package/dist/collection-rail.d.ts +42 -0
- package/dist/collection-rail.d.ts.map +1 -0
- package/dist/collection-rail.js +88 -0
- package/dist/collection-rail.js.map +1 -0
- package/dist/design-profile.d.ts +2 -5
- package/dist/design-profile.d.ts.map +1 -1
- package/dist/design-profile.js +16 -3
- package/dist/design-profile.js.map +1 -1
- package/dist/effect-surface.d.ts +7 -1
- package/dist/effect-surface.d.ts.map +1 -1
- package/dist/effect-surface.js +7 -1
- package/dist/effect-surface.js.map +1 -1
- package/dist/foundations.d.ts +13 -2
- package/dist/foundations.d.ts.map +1 -1
- package/dist/foundations.js +22 -2
- package/dist/foundations.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/docs/auth-screen.md +6 -1
- package/docs/collection-rail.md +48 -0
- package/docs/design-profile.md +40 -3
- package/docs/effect-surface.md +27 -1
- package/docs/file-picker.md +6 -0
- package/docs/floating-action-button.md +9 -0
- package/docs/font-roles.md +50 -0
- package/docs/generated/component-maturity.md +1 -1
- package/docs/generated/renderer-evidence.json +3 -3
- package/docs/generated/renderer-evidence.md +1 -1
- package/docs/generated/showcase-manifest.json +1 -1
- package/docs/menubar.md +6 -0
- package/docs/screen-patterns.md +4 -0
- package/docs/sidebar.md +6 -0
- package/docs/skip-nav.md +6 -0
- package/docs/toast.md +9 -0
- package/docs/toggle-group.md +5 -0
- package/docs/top.md +6 -0
- package/docs/transfer-list.md +6 -0
- package/docs/upload-item.md +6 -0
- package/docs/usage/README.md +8 -5
- package/docs/usage/components/auth-screen-layout.md +6 -2
- package/docs/usage/components/comment-thread-screen.md +12 -5
- package/docs/usage/components/design-system-provider.md +10 -1
- package/docs/usage/components/effect-surface.md +5 -1
- package/docs/usage/components/file-picker.md +7 -1
- package/docs/usage/components/floating-action-button.md +11 -1
- package/docs/usage/components/heading.md +3 -0
- package/docs/usage/components/list.md +77 -0
- package/docs/usage/components/menubar.md +6 -0
- package/docs/usage/components/overview-screen.md +6 -4
- package/docs/usage/components/sidebar.md +7 -1
- package/docs/usage/components/skip-nav.md +7 -1
- package/docs/usage/components/surface.md +9 -0
- package/docs/usage/components/text.md +2 -1
- package/docs/usage/components/toast.md +9 -0
- package/docs/usage/components/toggle-group.md +9 -1
- package/docs/usage/components/top.md +7 -1
- package/docs/usage/components/transfer-list.md +7 -1
- package/docs/usage/components/upload-item.md +6 -0
- package/docs/usage/compositions/collection-detail.md +91 -0
- package/docs/usage/compositions/command-records.md +4 -4
- package/docs/usage/compositions/content-transition-comparison.md +11 -5
- package/docs/usage/compositions/date-time-selection.md +4 -4
- package/docs/usage/compositions/design-profile-comparison.md +15 -4
- package/docs/usage/compositions/paper-surface.md +101 -0
- package/docs/usage/screens/common-comments.md +6 -2
- package/docs/usage/tokens/font-roles.md +87 -0
- package/docs/usage/tokens/typography.md +3 -0
- package/package.json +7 -1
package/docs/usage/README.md
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
| --- | --- | --- | --- | --- |
|
|
14
14
|
| [색상](tokens/color.md) | 색과 글자 | 색은 팔레트 이름(파랑·회색)이 아니라 배경·글자·브랜드·피드백·테두리 **역할**로 고른다. | 배포 | Web · Native |
|
|
15
15
|
| [타이포그래피](tokens/typography.md) | 색과 글자 | 글자 크기·줄 높이·굵기를 정할 때 쓴다. | 배포 | Web · Native |
|
|
16
|
+
| [표시·읽기·기술 글자](tokens/font-roles.md) | 색과 글자 | 앱의 제목·읽기용 본문·입력/조작 문구·기술값을 서로 다른 서체로 표시할 때 쓴다. | 배포 | Web · Native |
|
|
16
17
|
| [간격](tokens/spacing.md) | 공간과 크기 | 요소 사이 간격(gap)과 영역 안쪽 여백(padding)을 정할 때 쓴다. | 배포 | Web · Native |
|
|
17
18
|
| [크기](tokens/size.md) | 공간과 크기 | 아이콘·작은 그림(glyph)의 크기와 누를 수 있는 컨트롤의 높이·최소 터치 영역을 정할 때 쓴다. | 배포 | Web · Native |
|
|
18
19
|
| [화면 여백과 너비](tokens/layout.md) | 공간과 크기 | 화면 좌우 여백·본문 최대 폭·구획 간격·행 높이·breakpoint를 정하는 화면 배치의 기준값이다. | 배포 | Web · Native |
|
|
@@ -107,7 +108,7 @@
|
|
|
107
108
|
| [NumberField](components/number-field.md) | 입력 | 범위가 정해진 **정확한 수 하나**를 입력받을 때 쓴다. | 배포 | Web · Native |
|
|
108
109
|
| [OnboardingScreen](components/onboarding-screen.md) | 화면/소개 | 첫 실행 소개·초기 설정처럼 **몇 단계를 차례로 넘기는 화면**에 쓴다. | 배포 | Web · Native |
|
|
109
110
|
| [OtpField](components/otp-field.md) | 입력 | 문자·메일로 받은 **숫자 인증번호**를 칸 모양으로 입력받을 때 쓴다. | 배포 | Web · Native |
|
|
110
|
-
| [OverviewScreen](components/overview-screen.md) | 레이아웃 | 같은 데이터와 기능을 유지하면서 테마별 행·카드·격자와 도구 배치를 선택하는 목록 화면에 쓴다. |
|
|
111
|
+
| [OverviewScreen](components/overview-screen.md) | 레이아웃 | 같은 데이터와 기능을 유지하면서 테마별 행·카드·격자와 도구 배치를 선택하는 목록 화면에 쓴다. | 배포 | Web · Native |
|
|
111
112
|
| [Pagination](components/pagination.md) | 탐색 | 총 개수(또는 총 페이지 수)가 정해진 결과 집합에서 사용자가 **임의의 페이지로 바로 이동**해야 할 때 Web에서 쓴다. | 배포 | Web |
|
|
112
113
|
| [PasswordField](components/password-field.md) | 입력 | 비밀번호를 입력받고, 필요할 때만 값을 눈으로 확인하게 할 때 쓴다. | 배포 | Web · Native |
|
|
113
114
|
| [PermissionScreen](components/permission-screen.md) | 화면/소개 | 카메라·위치·알림 같은 권한이 **왜 필요한지 설명하고 다음 행동을 고르게 하는** 화면에 쓴다. | 배포 | Web · Native |
|
|
@@ -187,7 +188,7 @@
|
|
|
187
188
|
| [입력을 유지하는 도구](compositions/context-toolbar.md) | 입력과 작성 | 작성 중인 입력을 보존한 채 선택적 도구를 펼쳐야 할 때 쓴다. | 배포 | Web · Native |
|
|
188
189
|
| [첫 작업을 만들고 이어하기](compositions/reference-first.md) | 입력과 작성 | 첫 기록을 단계별 작성하고 중단한 초안 이어가기 흐름이 필요할 때 쓴다. | 배포 | Web · Native |
|
|
189
190
|
| [날짜 선택과 예정 목록](compositions/stea-schedule-card.md) | 선택과 필터 | 한 주처럼 짧은 날짜 범위에서 날짜 하나를 고르면 같은 카드 안의 일정 목록이 그 날짜로 바뀌는 요약 카드에 쓴다. | 배포 | Web · Native |
|
|
190
|
-
| [날짜와 시각 선택](compositions/date-time-selection.md) | 선택과 필터 | 기록·알림의 날짜 하나와 하루 안의 시각을 함께 고를 때 쓴다. |
|
|
191
|
+
| [날짜와 시각 선택](compositions/date-time-selection.md) | 선택과 필터 | 기록·알림의 날짜 하나와 하루 안의 시각을 함께 고를 때 쓴다. | 배포 | Web · Native |
|
|
191
192
|
| [대표 항목과 묶음 전체 선택](compositions/selection-scope.md) | 선택과 필터 | 사진 묶음·스레드처럼 대표 항목 하나와 묶음 전체가 같은 모양으로 보일 때, 공유·삭제·이동 전에 대상 범위와 개수를 고르고 문구로 확인한 뒤 적용하게 할 때 쓴다. | 배포 | Web · Native |
|
|
192
193
|
| [사진 촬영과 앨범 선택](compositions/photo-source.md) | 선택과 필터 | 명시적으로 선택 후 플랫폼 picker 실행 흐름이 필요할 때 쓴다. | 배포 | Web · Native |
|
|
193
194
|
| [선택 후 적용·취소](compositions/interaction-flow-apply.md) | 선택과 필터 | 표시 방식·정렬·필터처럼 시트에서 여러 번 바꿔 본 뒤 적용을 눌러야 화면에 반영되고, 취소하거나 닫으면 기존 선택을 유지해야 할 때 쓴다. | 배포 | Web · Native |
|
|
@@ -195,7 +196,7 @@
|
|
|
195
196
|
| [보관함과 페이지 이동](compositions/web-navigation.md) | 탐색과 이동 | Web에서 상위 보관함 → 하위 모음으로 들어가고, 그 모음의 긴 목록을 페이지 단위로 넘겨 보는 탐색에 쓴다. | 배포 | Web |
|
|
196
197
|
| [펼침과 메뉴](compositions/disclosure.md) | 탐색과 이동 | Web에서 내용을 숨겼다 펼치거나(Collapsible), 대상에 붙은 작업 메뉴를 우클릭·키보드로 열거나(ContextMenu), 데스크톱 앱처럼 상단 메뉴 막대를 두는(Menubar) 세 방식을 각각 보여 주는 모음이다. | 배포 | Web |
|
|
197
198
|
| [대화 메시지](compositions/common-message.md) | 정보 표시 | 말풍선 하나하나에 반응·답장·원문 이동·전송 실패 후 다시 보내기를 붙일 때 쓴다. | 배포 | Web · Native |
|
|
198
|
-
| [명령 기록 표시](compositions/command-records.md) | 정보 표시 | 명령 원문과 출력 기록을 선택·읽기·복사할 때 쓴다. |
|
|
199
|
+
| [명령 기록 표시](compositions/command-records.md) | 정보 표시 | 명령 원문과 출력 기록을 선택·읽기·복사할 때 쓴다. | 배포 | Web · Native |
|
|
199
200
|
| [문서와 파일](compositions/document-resource.md) | 정보 표시 | 이름·형식·크기와 미리보기·내보내기·별도 메뉴를 함께 제공하는 문서에 쓴다. | 배포 | Web · Native |
|
|
200
201
|
| [수치와 이전 대비 변화](compositions/stea-stat-summary.md) | 정보 표시 | 매출·주문·반품처럼 몇 개의 핵심 수치를 비교 기간과 함께 보이고, 증감의 방향과 좋고 나쁨을 색 없이도 읽히게 할 때 쓴다. | 배포 | Web · Native |
|
|
201
202
|
| [알림 항목](compositions/common-notification.md) | 정보 표시 | 알림 한 행을 누르면 바로 읽음으로 바꾸고, 서버가 실패하면 읽지 않음으로 되돌릴 때 쓴다. | 배포 | Web · Native |
|
|
@@ -220,13 +221,15 @@
|
|
|
220
221
|
| [선택 배경 이동](compositions/selection-motion.md) | 직접 조작과 모션 | 짧은 단일 선택의 현재 항목을 이어지는 배경으로 보여 줄 때 쓴다. | 배포 | Web · Native |
|
|
221
222
|
| [숫자 변화와 메뉴 변형](compositions/optional-motion.md) | 직접 조작과 모션 | 선택 설치 모션(숫자 자리 단위 변화, 메뉴 형태 변환)을 기존 컴포넌트 자리에 끼워 넣을 때 쓴다. | 배포 | Web |
|
|
222
223
|
| [이미지·시트·키보드 조작](compositions/optional-adapters.md) | 직접 조작과 모션 | Native 앱 한 화면에서 이미지 확대 보기, 끌어서 높이를 바꾸는 시트, OS 길게 누르기 메뉴, 키보드를 따라 올라가는 하단 행동을 함께 쓸 때 provider 중첩 순서와 각 요소의 자리를 확인하는 구성이다. | 배포 | Native |
|
|
224
|
+
| [카드 탐색과 상세 연결](compositions/collection-detail.md) | 직접 조작과 모션 | 유한 카드 여러 장의 독립 입력을 보존하면서 탐색하고 별도 상세 모달을 열 때 쓴다. | 배포 | Web · Native |
|
|
223
225
|
| [내비게이션 바 비교](compositions/navigation-bar-collection.md) | 비교와 검증 | 하단 탭에 목적지 이동과 별개의 행동(작성·전원·기록 추가)을 함께 둘지, 선택한 목적지를 어떻게 보여 줄지 고를 때 이 비교를 본다. | 배포 | Web · Native |
|
|
224
|
-
| [내용 전환 비교](compositions/content-transition-comparison.md) | 비교와 검증 | 동일 내용의 전환 표현을 테마와 비교하거나 단계별 입력·완료·복구를 검토할 때 쓴다. |
|
|
226
|
+
| [내용 전환 비교](compositions/content-transition-comparison.md) | 비교와 검증 | 동일 내용의 전환 표현을 테마와 비교하거나 단계별 입력·완료·복구를 검토할 때 쓴다. | 배포 | Web · Native |
|
|
225
227
|
| [네이티브 컴포넌트 기기 확인](compositions/native-renderers.md) | 비교와 검증 | Native 공개 컴포넌트가 실제 기기·시뮬레이터에서 그려지고 눌리는지 범주별로 한 화면에서 확인할 때 쓴다. | 배포 | Native |
|
|
226
228
|
| [복합 입력 모음](compositions/compound-controls.md) | 비교와 검증 | 기존 컨트롤을 묶은 네 가지 복합 입력(소요 시간, 버튼 자리 확인, 이모지 반응, 알림 종)을 화면 안 한 블록으로 둘 때 쓴다. | 배포 | Web · Native |
|
|
227
229
|
| [시각 효과 모음](compositions/visual-foundations.md) | 비교와 검증 | 배경 질감, 의미 이름 아이콘, 사진 없는 프로필 얼굴, 문장 전환처럼 화면의 분위기를 더하는 선택 표현을 고를 때 이 모음을 본다. | 배포 | Web · Native |
|
|
228
230
|
| [웹 전용 보조 컴포넌트](compositions/web-additions.md) | 비교와 검증 | Web에만 있는 보조 컴포넌트 세 개(색 고르기, 문서 워터마크, 스크롤 중 고정되는 실행 영역)를 실제 쓰임 하나씩과 함께 보여 주는 모음이다. | 배포 | Web |
|
|
229
|
-
| [
|
|
231
|
+
| [종이 줄무늬 비교](compositions/paper-surface.md) | 비교와 검증 | 같은 입력·기록에서 종이 preset의 grain+ruled 상속과 앱이 지정한 평면/줄무늬 표현을 비교한다. | 배포 | Web · Native |
|
|
232
|
+
| [테마 조합](compositions/design-profile-comparison.md) | 비교와 검증 | 같은 기능에 10가지 표현을 적용하고, 앱 소유 테마 설정을 넣었을 때 네 단계의 전파와 상태 유지를 검토할 때 쓴다. | 배포 | Web · Native |
|
|
230
233
|
| [토스트 배치 비교](compositions/toast-layout.md) | 비교와 검증 | Toast 카드 한 장의 내부 배치(톤 배지·제목·설명·닫기·실행 버튼)와 화면 위 위치를 좁은 폭·큰 글자·긴 문구·톤별로 확인하는 비교 스토리다. | 배포 | Web |
|
|
231
234
|
| [환경 조합 검증](compositions/environment-matrix.md) | 비교와 검증 | 제품 화면이 테마·쓰기 방향·글자 크기·모션 설정이 달라져도 같은 의미를 유지하는지 확인할 때, 어떤 환경 조합과 검증 항목을 골라 볼지 정하는 기준표로 쓴다. | 배포 | Web |
|
|
232
235
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
6
|
- 적용: 1.12.1
|
|
7
|
-
- 검토일: 2026-10-
|
|
7
|
+
- 검토일: 2026-10-07
|
|
8
8
|
- 근거: [로그인 화면 골격](../../auth-screen.md), [1.4 제품 채택 가이드](../../product-adoption-1.4.md), recipe `authScreenRecipe`(`src/auth-screen.ts`), 포트폴리오 상위 기준 루트 `docs/LOGIN_SCREEN_STANDARD.md`(LS)
|
|
9
9
|
- 스토리북: `배포/컴포넌트/레이아웃/로그인 화면`
|
|
10
10
|
|
|
@@ -74,7 +74,7 @@ import { AuthScreenLayout } from "@hjmds/react-native/auth-screen";
|
|
|
74
74
|
|
|
75
75
|
| 항목 | 값 | 근거 |
|
|
76
76
|
| --- | --- | --- |
|
|
77
|
-
| 크기 | 화면 전체(Web `min-block-size: 100dvh`, Native `ScrollView flex: 1`). 위 블록과 footer는 최대 폭 416, 마크 72(`markSize`, `radius.lg`), 정책 링크 최소 44(`footerMinTouchTarget`), mainCard 모서리 `radius.lg` 16 | `authScreenRecipe`, `.hjm-auth-screen*` |
|
|
77
|
+
| 크기 | 화면 전체(Web `min-block-size: 100dvh`, Native `ScrollView flex: 1`). 위 블록과 footer는 최대 폭 416, 마크 72(`markSize`, `radius.lg`), 정책 링크 최소 44(`footerMinTouchTarget`), mainCard 모서리 profile의 `radius.lg`(neutral/미지정 16) | `authScreenRecipe`, `.hjm-auth-screen*` |
|
|
78
78
|
| 간격 | `regular` / `compact`: 바깥 좌우 `layout.pagePadding.regular` 20 / `.compact` 16, 바깥 위아래 `spacing.xxxl` 40 / `spacing.lg` 20, hero 안 `spacing.md` 16 / `spacing.xs` 8, hero↔main `spacing.xl` 24 / `spacing.md` 16, 위 블록↔footer 최소 `spacing.xl` 24 / `spacing.md` 16. mainCard 안쪽 `spacing.md` 16 | `authScreenRecipe.densities`·`mainCard` |
|
|
79
79
|
| 순서·정렬 | 위→아래 hero(가운데 정렬 문구) → main(폭 꽉 채움) → footer(동의 고지·정책 링크). 위 블록은 남는 세로 공간에서 가운데, footer는 바닥에 붙는다. 진행 중 로딩은 main 카드 가운데에 겹친다 | `.hjm-auth-screen__block`(`justify-content: center`), `.hjm-auth-screen__pending` |
|
|
80
80
|
| 고정·스크롤 | 고정 영역이 없다. 넘치면 화면 전체가 스크롤한다. 안전 영역은 Native `contentInsetAdjustmentBehavior="automatic"`과 키보드 inset 자동 조정이 처리하고, Web은 safe-area inset을 더하지 않는다 | `react-native/src/auth-screen.tsx`, `.hjm-auth-screen` |
|
|
@@ -127,3 +127,7 @@ import { AuthScreenLayout } from "@hjmds/react-native/auth-screen";
|
|
|
127
127
|
- 앱 셸이 이미 `<main>`을 가진 Web 화면에서 기본값을 쓰면 main landmark가 중첩된다. `as="section"`을 쓴다.
|
|
128
128
|
- 기존 제품 카드 wrapper 안에서 `mainCard`를 켜면 카드가 이중이 된다. wrapper를 걷어내고 `mainCard`로 옮긴다.
|
|
129
129
|
- 현재 Web `style`은 recipe 크기 변수(`--hjm-auth-screen-*`) 뒤에 펼쳐져 최대 폭·간격 변수를 덮을 수 있다. 배치는 `layoutStyle`로만 준다.
|
|
130
|
+
|
|
131
|
+
### 테마 카드 모서리
|
|
132
|
+
|
|
133
|
+
`mainCard`는 가장 가까운 Provider의 `designProfile.tokens.radius.lg`를 양 플랫폼에서 소비한다. 테마가 없으면 기존 recipe의 16을 유지한다. 제공자 버튼은 제공자 브랜드 규격을 유지하며, 처리 중에도 카드와 입력을 제거하지 않는다. 카드 표면과 제공자 브랜드를 같은 radius로 강제하면 제품 테마가 제공자 규격을 덮기 때문에 역할을 나눈다.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
6
|
- 적용: 미게시(1.12.1 이후)
|
|
7
|
-
- 검토일: 2026-10-
|
|
7
|
+
- 검토일: 2026-10-07
|
|
8
8
|
- 근거: [반복 화면 조합](../../screen-patterns.md), Web·Native `src/screens.tsx`·`src/screen-flows.tsx`; 기존 개별 지침을 새 규격으로 통합. 예제 스토리는 2026-10-06 사용자 승인으로 스토리북 배포([승인 기록](../../../../../docs/STORYBOOK_NAVIGATION.md#21-2026-10-06-전체-승격과-규격-확정)). 스토리북 배포는 API 게시가 아니다(`적용` 참고)
|
|
9
9
|
- 스토리북: `배포/화면/소통/댓글`
|
|
10
10
|
|
|
@@ -88,15 +88,15 @@ import { MessageComposer } from "@hjmds/react-native/screens";
|
|
|
88
88
|
|
|
89
89
|
`CommentThreadItem`: `id`, `parentId`(`null`이면 최상위), `author`, `body`(노드), `timeLabel`, `likeCountLabel`,
|
|
90
90
|
`likeIcon`, `likeLabel`은 필수. 선택은 `bodyText`(작성자와 본문을 한 줄 흐름으로), `avatar`, `likeAction`(기본
|
|
91
|
-
좋아요 버튼 교체, `null`이면 생략), `actions`(
|
|
91
|
+
좋아요 버튼 교체, `null`이면 생략), `actions`(하트 바로 옆의 더보기 메뉴 등), `canReply`(기본: 최상위만 true), `replyDisabled`.
|
|
92
92
|
|
|
93
93
|
## 배치
|
|
94
94
|
|
|
95
95
|
| 항목 | 값 | 근거 |
|
|
96
96
|
| --- | --- | --- |
|
|
97
|
-
| 크기 | ScreenLayout 폭(최대 720); 본문 열이 남은 폭을 채우고(`flex: 1`, 최소 폭 0) 오른쪽 끝에
|
|
98
|
-
| 간격 | 화면 padding `spacing.md` 16; 최상위 댓글 묶음 사이 `spacing.lg` 20; 댓글 행–답글 묶음 `spacing.xs` 8; 답글 묶음 들여쓰기 `sectionGap`(`spacing.xl`) 24, 펼침 버튼·답글 사이 `spacing.md` 16; 행 안 아바타–본문–좋아요 `spacing.sm` 12, 본문 줄 사이 `spacing.xxs` 4, 시각·좋아요 수·답글 버튼 사이 `spacing.sm` 12 | `screen-flows.tsx` `Stack gap`, `screenPatternRecipe.sectionGap` |
|
|
99
|
-
| 순서·정렬 | 최상위 댓글(아바타 → 작성자·본문 → 시각·좋아요 수·답글 → `actions` →
|
|
97
|
+
| 크기 | ScreenLayout 폭(최대 720); 본문 열이 남은 폭을 채우고(`flex: 1`, 최소 폭 0) 오른쪽 끝에 좋아요와 `actions`를 같은 가로 행으로; 답글·펼침 버튼은 `Button size="small"` ghost | Web·Native `CommentThreadScreen` |
|
|
98
|
+
| 간격 | 화면 padding `spacing.md` 16; 최상위 댓글 묶음 사이 `spacing.lg` 20; 댓글 행–답글 묶음 `spacing.xs` 8; 답글 묶음 들여쓰기 `sectionGap`(`spacing.xl`) 24, 펼침 버튼·답글 사이 `spacing.md` 16; 행 안 아바타–본문–좋아요 `spacing.sm` 12, 본문 줄 사이 `spacing.xxs` 4, 좋아요–actions 사이 `spacing.xxs` 4, 시각·좋아요 수·답글 버튼 사이 `spacing.sm` 12 | `screen-flows.tsx` `Stack gap`, `screenPatternRecipe.sectionGap` |
|
|
99
|
+
| 순서·정렬 | 최상위 댓글(아바타 → 작성자·본문 → 시각·좋아요 수·답글) + 행 오른쪽 좋아요 → `actions` → 답글 펼침 버튼 → 펼친 답글 → … → `threadFooter` → composer(footer) | 렌더 순서 |
|
|
100
100
|
| 고정·스크롤 | 헤더·composer 고정, 댓글은 본문 화면 스크롤(`scroll` 기본 `"screen"`); composer는 `ready`·`empty`에서만 | `ScreenLayout`, `screen-flows.tsx` |
|
|
101
101
|
| 좁은 폭·큰 글자 | 시각·좋아요 수·답글 버튼 줄과 작성자 줄은 줄바꿈(`flexWrap: "wrap"`); 답글은 한 단계만 들여써 좁은 폭에서도 본문 폭을 지킨다 | `screen-flows.tsx` |
|
|
102
102
|
|
|
@@ -123,3 +123,10 @@ import { MessageComposer } from "@hjmds/react-native/screens";
|
|
|
123
123
|
|
|
124
124
|
- 작성창 노출 조건이 ChatScreen과 다르다. ChatScreen은 `ready`에서만, CommentThreadScreen은 `ready`·`empty`에서 보인다.
|
|
125
125
|
`loading`·`error`·`restricted`에서는 둘 다 숨는다.
|
|
126
|
+
|
|
127
|
+
2026-10-07 사용자 요청으로 댓글의 추가 행동을 본문 아래에서 하트 바로 옆으로 옮겼다.
|
|
128
|
+
기존 위치는 답글 행동과 섞였고 세로로 쌓으면 하트와 더보기의 관계가 떨어져 보였다.
|
|
129
|
+
두 버튼은 같은 가로 행이며 더보기 glyph는 세로 점3개(`MoreVertical`)를 제품이 Menu
|
|
130
|
+
trigger로 공급한다. `actions`는 자유 노드 슬롯을 유지하고 메뉴 권한/항목/전송은 제품 소유다.
|
|
131
|
+
순서는 좋아요 → 더보기이며 RTL에서는 논리 방향을 따른다. `likeAction=null`도 그대로 지원한다.
|
|
132
|
+
이 배치 수정은 1.14.0 이후 미게시 변경이며 npm/제품 배포와 별개다.
|
|
@@ -31,6 +31,15 @@ Provider 없이 렌더하면 예외가 난다. 화면 일부의 밀도·테마
|
|
|
31
31
|
|
|
32
32
|
테마 값은 Web `useHjmTheme()`, Native `useHjmNativeTheme()`로 읽는다(둘 다 Provider 밖에서는 예외).
|
|
33
33
|
|
|
34
|
+
### React Server Components에서 설정 주입
|
|
35
|
+
|
|
36
|
+
2026-10-07 공개 guide의 profile context 오류를 같은 원인인 Provider entry에서도 보완했다.
|
|
37
|
+
현재 main의 Web `/provider`는 client entry이다. 서버는 contracts의 `defineHjmDesignProfile`로 만든
|
|
38
|
+
직렬화 가능한 제품 설정과 서버 JSX children을 넘기며, hook·브라우저 관찰은 Provider 경계 안에서
|
|
39
|
+
실행된다.1.15.0 게시본에는 이 client directive 보완이 없으므로 제품의 client wrapper를 유지한다.
|
|
40
|
+
다른 Web entry와 루트 barrel의 RSC 지원은 이 변경으로 보장하지 않는다.
|
|
41
|
+
[실제 Next 재현·검증](../../../../../docs/qa/2026-10-07-rsc-profile-boundary.md)을 참고한다.
|
|
42
|
+
|
|
34
43
|
## 최소 사용 예
|
|
35
44
|
|
|
36
45
|
```tsx
|
|
@@ -77,7 +86,7 @@ expect(checkBrandPaletteContrast(PRODUCT_BRAND_PALETTE)).toEqual({ light: [], da
|
|
|
77
86
|
| `reducedMotion` | `true` · `false` | `false` | — |
|
|
78
87
|
| `minimumVisualTarget` | `true` · `false` | `false` | — |
|
|
79
88
|
| `brandPalette` | `{ light?, dark? }` | — | 각각 `ThemeColors` 17개 key 중 필요한 것만 넘긴다(부분 병합). 상태 강조색은 덮을 수 없다. 중첩 Provider는 가장 가까운 상위의 값을 물려받는다 |
|
|
80
|
-
| `designProfile` | `HjmDesignProfile` | 가장 가까운 상위 프로필 또는 없음 |
|
|
89
|
+
| `designProfile` | `HjmDesignProfile` | 가장 가까운 상위 프로필 또는 없음 | 기본 프로필은1.15.0 게시. `hjmDesignPresets` 또는 `defineHjmDesignProfile` 결과만 넣는다. 후속 글자 역할·질감/구성 개선은 아직 미게시다. [프로필 계약](../../design-profile.md)의 토큰·질감·전환·구성·화면 기본값을 상속한다 |
|
|
81
90
|
| `value` | `DesignSystemProviderValue`(`resolveDesignSystemProviderValue` 결과) | — | 테스트·스토리·임베딩용. 환경 prop·`brandPalette`·`designProfile`과 함께 쓸 수 없고(타입이 막는다), 주면 OS theme·모션 관찰과 상위 `brandPalette` 상속이 멈춘다 |
|
|
82
91
|
| `surfaceEffects`(Native) | `{ renderBackdrop?, insetShadows? }` | 상위 host 또는 없음 | 미게시 실험. 실제 blur host·inset capability를 한 번 등록하며 `{}`로 하위 영역을 해제. [Surface 질감 계약](../../design-profile.md#surfacecard의-유리클레이-질감) |
|
|
83
92
|
| `safeAreaInsets`(Native) | `{ top?, right?, bottom?, left? }`(pt) | `{}` | 보통 `useSafeAreaInsets()` 결과. 중첩 Provider는 가장 가까운 상위 값을 물려받는다 |
|
|
@@ -62,7 +62,8 @@ import { EffectSurface } from "@hjmds/react-native/effect-surface";
|
|
|
62
62
|
|
|
63
63
|
| prop | 값 | 기본값 | 설명 |
|
|
64
64
|
| --- | --- | --- | --- |
|
|
65
|
-
| `descriptor.layers` | `mesh` · `glow` · `grain` · `noise` | `["mesh"]` | 서로 다른 1~4개.
|
|
65
|
+
| `descriptor.layers` | `mesh` · `glow` · `grain` · `noise` · `ruled` | `["mesh"]` | 서로 다른 1~4개. ruled는 1.15.0 이후 미게시 실험 |
|
|
66
|
+
| `descriptor.ruledSpacing` | 유한한 8~128 host units | `24` | ruled의 1unit 선 간격. 텍스트 baseline과 독립적이며 모션 밖 정적 레이어 |
|
|
66
67
|
| `descriptor.intensity` | 0~1 | `0.22` | — |
|
|
67
68
|
| `descriptor.period` | 2~120초 | `12` | — |
|
|
68
69
|
| `descriptor.seed` | 문자열 | `"hjm"` | 빈 문자열 금지 |
|
|
@@ -120,3 +121,6 @@ import { EffectSurface } from "@hjmds/react-native/effect-surface";
|
|
|
120
121
|
- descriptor 검증 오류는 대비 밖에 있어 그대로 던져진다. 값 범위를 지킨다.
|
|
121
122
|
|
|
122
123
|
`noise`의 구현 차이·실험 조건은 [질감 비교](../compositions/texture-comparison.md)를 따른다. 기존 grain을 교체하지 않는다.
|
|
124
|
+
|
|
125
|
+
`ruled`의 profile 상속/override와 입력 보존은 [종이 줄무늬 비교](../compositions/paper-surface.md)를 따른다.
|
|
126
|
+
ruled-only descriptor는 active=true여도 애니메이션을 시작하지 않는다. 테이프·찢어진 경계·본문 회전은 제공하지 않는다.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
6
|
- 적용: 1.12.1
|
|
7
|
-
- 검토일: 2026-10-
|
|
7
|
+
- 검토일: 2026-10-07
|
|
8
8
|
- 근거: [FilePicker](../../file-picker.md), 판정 `resolveFilePickerSelection`(`@hjmds/design-contracts/components/file-picker`)
|
|
9
9
|
- 스토리북: `배포/컴포넌트/입력/파일 선택`
|
|
10
10
|
|
|
@@ -112,3 +112,9 @@ import { FilePicker } from "@hjmds/react-native/file-picker";
|
|
|
112
112
|
|
|
113
113
|
- Native `onPick`이 reject하면 `onSelect`는 불리지 않고 `onPickError`로만 전달된다. 빈 함수로 두면 피커 실패가 화면에 남지 않는다.
|
|
114
114
|
- 브라우저 `accept`와 OS 피커 필터는 힌트일 뿐이다. 거부 판정은 반드시 `onSelect` 결과로 처리한다.
|
|
115
|
+
|
|
116
|
+
### 프로필 모서리·제목 소비
|
|
117
|
+
|
|
118
|
+
2026-10-07 소비 감사에서 Native 선택 버튼의 모서리 12가 프로필을 우회했다. Web 버튼의 기존 `radius.md`와 같은 역할을 Native도 가까운 프로필에서 읽으며, 프로필이 없으면 기존 12를 유지한다. 선택 어댑터·비활성/진행 상태·파일 검증은 바꾸지 않는다.
|
|
119
|
+
|
|
120
|
+
프로필 연결은 1.15.0 이후 미게시 변경이며, 기본 배포 계약과 실제 Native 기기 검증은 구분한다.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
6
|
- 적용: 1.12.1
|
|
7
|
-
- 검토일: 2026-10-
|
|
7
|
+
- 검토일: 2026-10-07
|
|
8
8
|
- 근거: [FloatingActionButton](../../floating-action-button.md), recipe `floatingActionButtonRecipe`(`src/floating-action-button.ts`)
|
|
9
9
|
- 스토리북: `배포/컴포넌트/동작/플로팅 실행 버튼`
|
|
10
10
|
|
|
@@ -136,3 +136,13 @@ const [clearance, setClearance] = useState(0);
|
|
|
136
136
|
|
|
137
137
|
- 모드마다 Button과 IconButton을 바꿔 끼우면 focus와 ref를 잃는다. 이 컴포넌트 하나로 접고 편다.
|
|
138
138
|
- Native `safeAreaBottomInset`은 OS 하단 inset만이다. 화면 안 도구막대 높이는 제품이 따로 더한다.
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
### 테마의 깊이 상속
|
|
142
|
+
|
|
143
|
+
2026-10-07 테마 소비 감사에서 FAB만 recipe의 고정 그림자를 읽어 같은 화면의
|
|
144
|
+
카드·오버레이·하단 행동과 깊이가 달랐다. 가까운 Provider의 designProfile이 있으면
|
|
145
|
+
`tokens.shadow.floating`을 읽는다. 모양은 기존 원·pill을 유지하고 프로필 모서리로 바꾸지 않는다.
|
|
146
|
+
프로필 없는 기존 소비자는 같은 recipe 그림자/elevation을 유지한다.
|
|
147
|
+
Native에서 opacity0은 Android elevation도0으로 해석한다. 제품은 각 FAB에 그림자 prop을
|
|
148
|
+
넣지 않고 루트 프로필을 한 번 주입한다. 클릭·접힘·접근성 이름·safe area·clearance는 그대로다.
|
|
@@ -91,3 +91,6 @@ import { Heading } from "@hjmds/react-native/heading";
|
|
|
91
91
|
- Web `style`은 이제 버려지지 않고 합쳐진다. 다만 크기·줄 높이·굵기 변수(`--hjm-heading-*`)는 recipe가 마지막에 덮으므로
|
|
92
92
|
`style`로 크기를 바꿀 수 없다. 배치는 `layoutStyle`로 준다.
|
|
93
93
|
- Native `style`(deprecated)은 아직 마지막에 합쳐져 색·크기까지 바뀐다. 쓰지 말고 `layoutStyle`·`level`로 옮긴다.
|
|
94
|
+
|
|
95
|
+
2026-10-07 추가: 제목은 프로필의 optional `tokens.fontFamily.display`를 사용하고 생략 시 현재 ui를 따른다.
|
|
96
|
+
문서 semanticLevel·크기·굵기는 유지한다. [서체 역할](../tokens/font-roles.md), 1.15.0 이후 미게시.
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
| 화면 형태 | 쓸 것 |
|
|
20
20
|
| --- | --- |
|
|
21
21
|
| 수십 개 이하의 행을 한 번에 그림(설정, 계정 메뉴, 검색 결과 한 페이지) | `List` + `ListRow` |
|
|
22
|
+
| 유한 카드 여러 장의 독립 입력/행동을 함께 보여주는 가로 탐색 | `CollectionRail` (미게시 실험, 아래 가로 배치 지침) |
|
|
22
23
|
| 행 한 줄의 제목·설명·앞뒤 슬롯 | [ListRow](list-row.md) |
|
|
23
24
|
| 높이가 고정된 행 수백~수천 개를 창 안에서 스크롤 | [VirtualList](virtual-list.md) |
|
|
24
25
|
| 이어지는 목록의 다음 페이지 요청 footer | [LoadMore](load-more.md) (List·VirtualList 아래에 둔다) |
|
|
@@ -107,6 +108,82 @@ Native `grouped` 프레임은 Provider의 `tokens.radius.lg`를 읽는다. plain
|
|
|
107
108
|
[ LoadMore ]
|
|
108
109
|
```
|
|
109
110
|
|
|
111
|
+
### CollectionRail 가로 배치
|
|
112
|
+
|
|
113
|
+
새 `CollectionRail`은 미게시(1.15.0 이후) 실험 companion이다. 기존 List의 배포/호환 계약은 유지한다.
|
|
114
|
+
|
|
115
|
+
#### 언제 쓰나
|
|
116
|
+
|
|
117
|
+
이미 불러온 유한 카드/자료를 여러 개 함께 읽고 가로로 탐색할 때 쓴다. 독립 입력·버튼·링크는 계속 접근 가능하며
|
|
118
|
+
스크롤 anchor는 선택 값과 다르다. 모든 항목을 그리는 List의 companion이며 큰 데이터의 가상화는 제공하지 않는다.
|
|
119
|
+
|
|
120
|
+
#### 쓰지 않을 때
|
|
121
|
+
|
|
122
|
+
| 상황 | 대신 쓸 것 |
|
|
123
|
+
| --- | --- |
|
|
124
|
+
| 한 패널만 선택·표시하고 다른 패널은 숨김 | [Carousel](carousel.md) |
|
|
125
|
+
| 세로 행과 구분선 | [List](list.md)·[ListRow](list-row.md) |
|
|
126
|
+
| 수백~수천 데이터 | [VirtualList](virtual-list.md) 또는 별도 가상화 계약 |
|
|
127
|
+
| 드래그로 순서를 확정 | [SortableCollection](sortable-collection.md) |
|
|
128
|
+
|
|
129
|
+
#### 공개 이름과 import
|
|
130
|
+
|
|
131
|
+
| 이름 | 역할 | Web | Native |
|
|
132
|
+
| --- | --- | --- | --- |
|
|
133
|
+
| `CollectionRail` | List companion — 유한 가로 배치/탐색 | `@hjmds/react/collection-rail` | `@hjmds/react-native/collection-rail` |
|
|
134
|
+
|
|
135
|
+
`CollectionRailItem`·geometry/resolver는 `@hjmds/design-contracts/collection-rail`. 신규 granular entry만 사용하고 추가 peer/root import는 없다.
|
|
136
|
+
|
|
137
|
+
#### 최소 사용 예
|
|
138
|
+
|
|
139
|
+
```tsx
|
|
140
|
+
import { CollectionRail } from "@hjmds/react/collection-rail";
|
|
141
|
+
// Native: @hjmds/react-native/collection-rail
|
|
142
|
+
<CollectionRail label={t("records.title")} items={records}
|
|
143
|
+
labels={{ previous: t("records.previous"), next: t("records.next"), navigation: t("records.navigation") }}
|
|
144
|
+
renderItem={item => <RecordCard item={item} />} emptyContent={<EmptyRecords />} />
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
#### 축과 기본값
|
|
148
|
+
|
|
149
|
+
| prop | 값 | 기본값 | 설명 |
|
|
150
|
+
| --- | --- | --- | --- |
|
|
151
|
+
| `label` | string | 필수 | 현지화된 목록 이름 |
|
|
152
|
+
| `items` | `{id,label}[]` | 필수 | 안정·고유·빈 값 아닌 ID/label, empty 허용 |
|
|
153
|
+
| `renderItem` | `(item) => ReactNode` | 필수 | 버튼·입력·카드는 기존 공개 API 사용 |
|
|
154
|
+
| `labels` | previous/next/navigation string | 필수 | 스크롤 행동 이름, empty 금지 |
|
|
155
|
+
| `density` | compact/comfortable | comfortable | 최대 폭240/360, 실제 폭에서 clamp |
|
|
156
|
+
| `defaultStartKey` | item ID | 첫 항목 | 초기 위치만. 선택/상세 값 아님 |
|
|
157
|
+
| `onStartKeyChange` | `(key: string|null) => void` | 생략 | 앞쪽 항목 변화 관찰; 선택 확정 callback 아님 |
|
|
158
|
+
| `emptyContent` | ReactNode | 생략 | 제품의 빈 목록 내용 |
|
|
159
|
+
| `layoutStyle` | 공개 배치 key | 생략 | 루트 배치. 카드 시각 표현은 Card/Provider |
|
|
160
|
+
|
|
161
|
+
#### 배치
|
|
162
|
+
|
|
163
|
+
| 항목 | 값 | 근거 |
|
|
164
|
+
| --- | --- | --- |
|
|
165
|
+
| 크기 | 가용 viewport 폭, item 최대240/360. viewport358일 때 item334·다음 item8px 일부 | `collectionRailRecipe.itemMaxWidth/edgeHint`, `layout.readingMaxWidth`720/`spacing.xl`24 |
|
|
166
|
+
| 간격 | item 간16, controls 위/사이12, track 상하8 | `spacing.md`16, `spacing.sm`12, `spacing.xs`8 |
|
|
167
|
+
| 순서·정렬 | items 데이터 순서와 stable key 유지; controls 끝쪽. RTL은 논리 방향 번역 | resolver 및 renderer의 명시적 direction |
|
|
168
|
+
| 고정·스크롤 | viewport만 실제 가로 scroll, controls는 밖. 끝에서 멈추고 자동 이동 없음 | 공통 maxOffset·target resolver |
|
|
169
|
+
| 좁은 폭·큰 글자 | 기본 글자의 좁은 폭에서 실제 측정으로 카드 폭을 줄임. 최대 글자 조건은 제외 | 2026-10-07 사용자 범위, root AGENTS.md |
|
|
170
|
+
|
|
171
|
+
#### 꼭 지킬 것
|
|
172
|
+
|
|
173
|
+
같은 항목에 안정 ID를 쓰고 테마/폭을 subtree key로 두지 않는다. 카드 전체를 버튼으로 만들어 입력/상세 버튼을 중첩하지 않는다.
|
|
174
|
+
초점 카드 노출은 선택을 확정하지 않는다. 서버 조회·선택·권한·초안·상세 콘텐츠는 제품이 소유한다.
|
|
175
|
+
앱은 Showcase를 import하지 않는다. 설치한 게시 버전의 entry가 있는지 확인한 뒤 사용한다.
|
|
176
|
+
|
|
177
|
+
#### 플랫폼 차이
|
|
178
|
+
|
|
179
|
+
| 항목 | Web | Native |
|
|
180
|
+
| --- | --- | --- |
|
|
181
|
+
| 스크롤 | clientWidth·ResizeObserver·negative RTL scrollLeft | onLayout·LTR ScrollView 물리 offset·RTL row placement |
|
|
182
|
+
| 키보드 | viewport/controls의 방향·Home/End, input 키 유지 | 플랫폼 ScrollView·자식 입력·명시적 previous/next; 실제 OS 검수 필요 |
|
|
183
|
+
| 부분 노출 | 모든 listitem mounted·inert 아님, 초점 시 최소 노출 | removeClippedSubviews=false, 자식 접근성 유지, focus 노출 |
|
|
184
|
+
| 끝 행동 | aria-disabled로 끝에서도 호출 행동 초점 유지 | 기존 Button disabled 상태 |
|
|
185
|
+
|
|
186
|
+
|
|
110
187
|
## 꼭 지킬 것
|
|
111
188
|
|
|
112
189
|
- 자식 하나가 행 하나다. 자식마다 안정된 `key`를 준다(없으면 순서 index로 key를 만든다).
|
|
@@ -97,3 +97,9 @@ Native 예는 없다(renderer 없음).
|
|
|
97
97
|
맞춰 활성 항목을 바꾼다. 메뉴 막대 라벨의 hover 전환·클릭·비활성 건너뛰기는 유지한다.
|
|
98
98
|
고정 지연이나 키보드 검사 재시도로 가리는 대신 입력 의도를 구분했다.
|
|
99
99
|
[검증 기록](../../../../../docs/qa/2026-10-07-command-records.md).
|
|
100
|
+
|
|
101
|
+
### 프로필 모서리·제목 소비
|
|
102
|
+
|
|
103
|
+
2026-10-07 소비 감사에서 Web 라벨의 숫자 recipe 모서리가 프로필을 우회했다. 기존 `radius.sm` 역할을 가까운 Provider의 CSS 변수로 읽고 변수 없는 독립 사용은 recipe 8을 유지한다. 열린 메뉴·roving focus·비활성 건너뛰기·행동과 Web 전용 범위는 바꾸지 않는다.
|
|
104
|
+
|
|
105
|
+
프로필 연결은 1.15.0 이후 미게시 변경이며, 기본 배포 계약과 실제 Native 기기 검증은 구분한다.
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
# OverviewScreen
|
|
2
2
|
|
|
3
3
|
- 단계: 컴포넌트
|
|
4
|
-
- 상태:
|
|
4
|
+
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
|
-
- 적용:
|
|
7
|
-
- 검토일: 2026-10-
|
|
6
|
+
- 적용: 1.15.0
|
|
7
|
+
- 검토일: 2026-10-08
|
|
8
8
|
- 근거: [디자인 프로필](../../design-profile.md), 양 renderer `src/design-profile.tsx`; 기존 ScreenLayout·Grid·Collapsible의 상태 엔진을 재사용한다.
|
|
9
|
-
- 스토리북:
|
|
9
|
+
- 스토리북: `배포/컴포넌트/레이아웃/목록 화면 골격`
|
|
10
10
|
|
|
11
11
|
## 언제 쓰나
|
|
12
12
|
|
|
13
13
|
같은 데이터와 기능을 유지하면서 테마별 행·카드·격자와 도구 배치를 선택하는 목록 화면에 쓴다.
|
|
14
14
|
|
|
15
|
+
기본 공개 API는 npm 1.15.0에 있다. 후속 글자 역할·종이 줄 간격·토큰 소비 개선의 main 구현은 별도 미게시이며, 이 적용 버전으로 후속 개선까지 게시됐다고 해석하지 않는다.
|
|
16
|
+
|
|
15
17
|
## 쓰지 않을 때
|
|
16
18
|
|
|
17
19
|
| 상황 | 대신 쓸 것 |
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web
|
|
6
6
|
- 적용: 1.12.1
|
|
7
|
-
- 검토일: 2026-10-
|
|
7
|
+
- 검토일: 2026-10-07
|
|
8
8
|
- 근거: [Sidebar](../../sidebar.md), `src/sidebar.ts`(`sidebarRecipe`, `validateSidebarDescriptor`)
|
|
9
9
|
- 스토리북: `배포/컴포넌트/탐색/사이드바`, `배포/컴포넌트/탐색/사이드바 전환`
|
|
10
10
|
|
|
@@ -105,3 +105,9 @@ Native: 없음. 폰은 BottomNavigation, 태블릿 split view는 navigator가
|
|
|
105
105
|
- 항목은 `href`가 있는 일반 `<a>`이고 클릭 시 기본 이동을 막지 않는다. `onNavigate`는 알림 콜백이지
|
|
106
106
|
이동을 대신하지 않는다. client router 전환(Next.js 등)이 필요하면 제품 셸에서 동작을 확인한다.
|
|
107
107
|
- `destination`을 빼면 `href` 없는 `<a>`가 되어 키보드 초점을 받지 못한다. 이동 항목에는 `destination`을 둔다.
|
|
108
|
+
|
|
109
|
+
### 프로필 모서리·제목 소비
|
|
110
|
+
|
|
111
|
+
2026-10-07 소비 감사에서 Web 항목의 숫자 recipe 모서리가 프로필을 우회했다. 기존 `radius.md` 역할을 가까운 Provider의 CSS 변수로 읽고 변수 없는 독립 사용은 recipe 12를 유지한다. 레일 폭·링크·현재 위치·접기·초점과 Web 전용 범위는 바꾸지 않는다.
|
|
112
|
+
|
|
113
|
+
프로필 연결은 1.15.0 이후 미게시 변경이며, 기본 배포 계약과 실제 Native 기기 검증은 구분한다.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web
|
|
6
6
|
- 적용: 1.12.1
|
|
7
|
-
- 검토일: 2026-10-
|
|
7
|
+
- 검토일: 2026-10-07
|
|
8
8
|
- 근거: [SkipNav](../../skip-nav.md), `src/skip-nav.ts`(`skipNavRecipe`)
|
|
9
9
|
- 스토리북: `배포/컴포넌트/기반 기능/본문 바로가기`
|
|
10
10
|
|
|
@@ -74,3 +74,9 @@ Native: 없음.
|
|
|
74
74
|
- 클릭 시 대상에 `tabindex`가 없으면 `tabindex="-1"`을 붙이고 `focus()`한다. 대상 요소에 생긴 이 속성을 지우지 않는다.
|
|
75
75
|
- `onClick`에서 `event.preventDefault()`를 부르면 초점 이동이 일어나지 않는다.
|
|
76
76
|
- 현재 `style`은 타입상 받지만 HJM이 recipe 변수 style로 덮어써 조용히 버려진다. 위치는 recipe offset이 고정한다.
|
|
77
|
+
|
|
78
|
+
### 프로필 모서리·제목 소비
|
|
79
|
+
|
|
80
|
+
2026-10-07 소비 감사에서 Web 링크의 숫자 recipe 모서리가 프로필을 우회했다. 기존 `radius.md` 역할을 가까운 Provider의 CSS 변수로 읽고 변수 없는 독립 사용은 recipe 12를 유지한다. 숨김·고정 위치·표시·본문 초점 이동과 Web 전용 범위는 바꾸지 않는다.
|
|
81
|
+
|
|
82
|
+
프로필 연결은 1.15.0 이후 미게시 변경이며, 기본 배포 계약과 실제 Native 기기 검증은 구분한다.
|
|
@@ -30,6 +30,15 @@
|
|
|
30
30
|
| --- | --- | --- | --- |
|
|
31
31
|
| `Surface` | 기본 | `@hjmds/react`, `/layout` | `@hjmds/react-native`, `/primitives` |
|
|
32
32
|
|
|
33
|
+
### React Server Components의 import 경계
|
|
34
|
+
|
|
35
|
+
공개 guide가 HJM profile context를 서버 module에서 평가해 실패한 사례(2026-10-07)를 보완했다.
|
|
36
|
+
현재 main의 Web `/layout`은 client entry이므로 서버가 작성한 JSX children과 직렬화 가능한 props를
|
|
37
|
+
Surface로 넘길 수 있다. 서버 page 전체를 client로 바꿀 필요는 없다. 이 보완은1.15.0 이후 미게시이므로
|
|
38
|
+
설치1.15.0에서는 제품의 작은 `"use client"` 재수출 경계를 유지한다. callback/ref 등 client 실행이
|
|
39
|
+
필요한 props는 소비 Client Component에서 만든다. 루트 barrel/다른 entry를 서버에 직접 import해도
|
|
40
|
+
된다는 보장은 아니다. [재현·검증](../../../../../docs/qa/2026-10-07-rsc-profile-boundary.md)을 따른다.
|
|
41
|
+
|
|
33
42
|
## 최소 사용 예
|
|
34
43
|
|
|
35
44
|
```tsx
|
|
@@ -58,6 +58,7 @@ import { Text } from "@hjmds/react-native/primitives";
|
|
|
58
58
|
| prop | 값 | 기본값 | 설명 |
|
|
59
59
|
| --- | --- | --- | --- |
|
|
60
60
|
| `variant` | `caption`(11) · `label`(12) · `body`(14) · `bodyLarge`(16) · `title`(18) · `titleLarge`(20) · `heading`(24) | `body` | 화면·섹션 제목은 모양이 아니라 [Heading](heading.md)으로 쓴다 |
|
|
61
|
+
| `fontRole` | `ui` · `display` · `reading` · `code` | 제목 variant는 display, 본문은 reading, caption/label은 ui | 명시값이 기본을 덮는다. [역할 지침](../tokens/font-roles.md), 1.15.0 이후 미게시 |
|
|
61
62
|
| `emphasis` | `regular` · `medium`(semibold) · `strong`(bold) | `regular` | — |
|
|
62
63
|
| `tone` | `primary` · `body` · `muted` · `subtle` · `weak` · `brand` · `danger` · `inverse` | `primary` | — |
|
|
63
64
|
| `as` | `span` · `p` · `div` · `strong` · `small` | `span` | Web만. 문단은 `as="p"` |
|
|
@@ -68,7 +69,7 @@ import { Text } from "@hjmds/react-native/primitives";
|
|
|
68
69
|
|
|
69
70
|
## 배치
|
|
70
71
|
|
|
71
|
-
Native는 제품 프로필의 `tokens.fontFamily.ui
|
|
72
|
+
Native는 Text의 역할을 해당 stack에, 입력/조작 host는 제품 프로필의 `tokens.fontFamily.ui`에 연결한다. 기본 UI stack은 OS 서체를 유지하고, 제품이 지정한 첫 named font의 등록·글리프 확인은 제품이 맡는다.
|
|
72
73
|
|
|
73
74
|
| 항목 | 값 | 근거 |
|
|
74
75
|
| --- | --- | --- |
|
|
@@ -165,3 +165,12 @@ Native의 선택형 `/toast-liquid`도 가장 가까운 프로필의 `radius.lg`
|
|
|
165
165
|
### 고정 아이콘과 큰 글자
|
|
166
166
|
|
|
167
167
|
2026-10-06 최근 검색 삭제 기호가 큰 글자에서 잘린 재현에 따라 Native 내장 삭제·메뉴 기호는 고정 아이콘 틀의 크기를 유지한다. 주변 제목·라벨은 계속 확대한다. Chip의 체크와 Toast 닫기는 기존 비확대 경로를 유지하며 회귀 검사에 포함한다. 제품이 전달한 아이콘 슬롯은 제품이 같은 조건을 검증한다.
|
|
168
|
+
|
|
169
|
+
### 프로필 행간 소비 — 미게시
|
|
170
|
+
|
|
171
|
+
2026-10-07 소비 감사에서 Web 제목/설명의 1.35/1.45 고정 행간이 `typography.body.lineHeight`를
|
|
172
|
+
우회하는 것을 확인했다. 두 slot은 기존 body 역할이므로 선택된 프로필의 `--hjm-type-body-line-height`를
|
|
173
|
+
기존 Provider/portal 토큰 경로로 읽는다. 프로필 없는 Provider와 독립 사용은 기존 1.35/1.45를 유지한다.
|
|
174
|
+
일괄 기본 행간 변경은 기존 알림 레이아웃까지 바꾸므로 채택하지 않았다. Native 본문 행간은 이미 body
|
|
175
|
+
토큰을 소비하며, 이번 Native 변경은 action 라벨의 ui 서체 역할만 명시한다. 알림 문구·큐·시간·닫기·
|
|
176
|
+
행동·초점 계약은 바꾸지 않는다.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
6
|
- 적용: 1.12.1
|
|
7
|
-
- 검토일: 2026-10-
|
|
7
|
+
- 검토일: 2026-10-07
|
|
8
8
|
- 근거: [ToggleGroup](../../toggle-group.md), `src/toggle-group.ts`(`toggleGroupRecipe`)
|
|
9
9
|
- 스토리북: `배포/컴포넌트/입력/토글 그룹`
|
|
10
10
|
|
|
@@ -93,3 +93,11 @@ import { ToggleGroup } from "@hjmds/react-native/toggle-group";
|
|
|
93
93
|
| 배치 | CSS(`hjm-toggle-group`) | 가로 `flexWrap: "wrap"` |
|
|
94
94
|
| 외부 꾸밈 | `className`, `ref`, `layoutStyle` | `layoutStyle`(`style`은 deprecated) |
|
|
95
95
|
| 키보드 | 항목마다 tab stop(roving 없음) | 해당 없음 |
|
|
96
|
+
|
|
97
|
+
### 제품 테마의 모서리
|
|
98
|
+
|
|
99
|
+
2026-10-07 테마 소비 점검에서 양 renderer가 숫자로 확정된 recipe 모서리를 읽어
|
|
100
|
+
제품 profile을 무시했다. profile이 있으면 가장 가까운 Provider의 `tokens.radius.md`를
|
|
101
|
+
사용하고 없으면 기존 `toggleGroupRecipe.radius` 12를 유지한다. 새 style prop이나
|
|
102
|
+
별도 토글 엔진을 추가하지 않는다. 중첩 Provider에서 별도 profile을 생략하면 상속하며,
|
|
103
|
+
명시적인 neutral profile은 중립 모서리로 돌아간다. 테마 변경은 눌린 항목·비활성·초점을 초기화하지 않는다.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
6
|
- 적용: 1.12.1
|
|
7
|
-
- 검토일: 2026-10-
|
|
7
|
+
- 검토일: 2026-10-07
|
|
8
8
|
- 근거: [Top](../../top.md), `src/top.ts`(`topRecipe`)
|
|
9
9
|
- 스토리북: `배포/컴포넌트/레이아웃/화면 제목과 설명`
|
|
10
10
|
|
|
@@ -87,3 +87,9 @@ import { Top } from "@hjmds/react-native/top";
|
|
|
87
87
|
| 제목 요소 | 실제 `h1`~`h3`(`headingLevel`) | `accessibilityRole="header"`(단계 없음, `headingLevel` 미사용) |
|
|
88
88
|
| `trailing` 내림 기준 | CSS 줄바꿈 | 글자 배율 1.6 이상이면 세로로 쌓음 |
|
|
89
89
|
| ref | `forwardRef`(`header` 요소) | 없음 |
|
|
90
|
+
|
|
91
|
+
### 프로필 모서리·제목 소비
|
|
92
|
+
|
|
93
|
+
2026-10-07 소비 감사에서 두 renderer의 제목 크기·행간·굵기가 foundation으로 확정된 recipe를 직접 읽어 프로필을 우회했다. `large`는 가까운 프로필의 `heading.level2`, `medium`은 `typography.titleLarge`를 읽고 프로필이 없으면 기존 recipe를 유지한다. 시각 역할은 `headingLevel`과 독립이며 display 서체·제목 의미·보조 행동·초점은 바꾸지 않는다.
|
|
94
|
+
|
|
95
|
+
프로필 연결은 1.15.0 이후 미게시 변경이며, 기본 배포 계약과 실제 Native 기기 검증은 구분한다.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
6
|
- 적용: 1.12.1
|
|
7
|
-
- 검토일: 2026-10-
|
|
7
|
+
- 검토일: 2026-10-07
|
|
8
8
|
- 근거: [TransferList](../../transfer-list.md), `src/transfer-list.ts`(`transferListRecipe`)
|
|
9
9
|
- 스토리북: `배포/컴포넌트/입력/목록 간 항목 이동`
|
|
10
10
|
|
|
@@ -113,3 +113,9 @@ Web ≥ 480 Web < 480 · Native
|
|
|
113
113
|
| 이동 후 포커스 | 빈 자리로 올라온 행, 비면 빈 상태 문구 | 옮기지 않음 |
|
|
114
114
|
| 패널 비었을 때 전체 선택 | 활성 | `disabled` |
|
|
115
115
|
| 외부 꾸밈 | `className`, `ref`, `layoutStyle` | `layoutStyle`(`style`은 deprecated) |
|
|
116
|
+
|
|
117
|
+
### 프로필 모서리·제목 소비
|
|
118
|
+
|
|
119
|
+
2026-10-07 소비 감사에서 Native 패널의 모서리 12가 프로필을 우회했다. Web 패널의 기존 `radius.md`와 같은 역할을 Native도 가까운 프로필에서 읽으며, 프로필이 없으면 기존 12를 유지한다. 선택 집합·이동·비활성 항목·초점 계약은 바꾸지 않는다.
|
|
120
|
+
|
|
121
|
+
프로필 연결은 1.15.0 이후 미게시 변경이며, 기본 배포 계약과 실제 Native 기기 검증은 구분한다.
|
|
@@ -99,3 +99,9 @@ import { UploadItem } from "@hjmds/react-native/upload-item";
|
|
|
99
99
|
| 루트 | `role="group"`, `aria-label`=파일명, `HTMLAttributes`·`ref`·`layoutStyle` 전달 | 일반 `View`, `layoutStyle`(`style`은 deprecated) |
|
|
100
100
|
| 상태 낭독 | 상태 문장 live region | 파일 정보 묶음이 한 요소(`busy` state, value=상태 문장), 액션은 별도 버튼 |
|
|
101
101
|
| `leading` | `aria-hidden` | 접근성 트리에서 숨김 |
|
|
102
|
+
|
|
103
|
+
### 프로필 모서리·제목 소비
|
|
104
|
+
|
|
105
|
+
2026-10-07 소비 감사에서 Native 행의 모서리 12가 프로필을 우회했다. Web의 기존 `radius.md`와 같은 역할을 Native도 가까운 프로필에서 읽으며, 프로필이 없으면 기존 12를 유지한다. 업로드 상태·취소/재시도·진행 알림은 바꾸지 않는다.
|
|
106
|
+
|
|
107
|
+
프로필 연결은 1.15.0 이후 미게시 변경이며, 기본 배포 계약과 실제 Native 기기 검증은 구분한다.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# 카드 탐색과 상세 연결
|
|
2
|
+
|
|
3
|
+
- 단계: 구성
|
|
4
|
+
- 상태: 배포
|
|
5
|
+
- 지원: Web · Native
|
|
6
|
+
- 적용: 1.16.0
|
|
7
|
+
- 검토일: 2026-10-08
|
|
8
|
+
- 근거: [원제품과 기존 API 대조](../../../../../docs/plans/aceternity-interaction-adoption-2026-10-07.md), 양 Showcase `collection-detail-preview.tsx`
|
|
9
|
+
- 스토리북: `배포/구성/직접 조작과 모션/카드 상세 연결`
|
|
10
|
+
|
|
11
|
+
## 언제 쓰나
|
|
12
|
+
|
|
13
|
+
유한 카드 여러 장의 독립 입력을 보존하면서 탐색하고 별도 상세 모달을 열 때 쓴다. 후기/상품/자료는
|
|
14
|
+
제품 데이터·콘텐츠 변형이며 가로 목록 또는 모달 엔진을 각각 복제하지 않는다. 예제는 합성 기록이며 서버 저장이 아니다.
|
|
15
|
+
|
|
16
|
+
## 구성 요소
|
|
17
|
+
|
|
18
|
+
| 컴포넌트 | 역할 | 지침 |
|
|
19
|
+
| --- | --- | --- |
|
|
20
|
+
| Container·Section·Stack | 제목/설명/폭·문서 흐름 | [Container](../components/container.md)·[Section](../components/section.md)·[Stack](../components/stack.md) |
|
|
21
|
+
| CollectionRail | 여러 항목과 유한 가로 탐색 | [가로 배치](../components/list.md#collectionrail-가로-배치) |
|
|
22
|
+
| Card | 제목·설명·본문 입력·별도 actions | [Card](../components/card.md) |
|
|
23
|
+
| TextField | 카드/상세의 독립 초안 | [입력](../components/field.md) |
|
|
24
|
+
| Dialog·Button | actions의 상세 열기·닫기·초점 복귀 | [Dialog](../components/dialog.md)·[Button](../components/button.md) |
|
|
25
|
+
|
|
26
|
+
## 배치
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
제목/설명 → 현재 테마 → 다음 테마
|
|
30
|
+
가로 목록: [제목/설명 → 기록 메모 → 상세 보기] × 안정 ID
|
|
31
|
+
목록 밖 끝쪽: 이전 기록 / 다음 기록
|
|
32
|
+
상세: 제목/닫기 → 상세 메모 → 다음 테마
|
|
33
|
+
합성 예제 안내
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
| 영역 | 컴포넌트 | 위치 | 크기·간격 |
|
|
37
|
+
| --- | --- | --- | --- |
|
|
38
|
+
| 바깥 틀 | Container·Section·Stack | 세로 | gutter compact16, Stack spacing.md16 |
|
|
39
|
+
| 목록 | CollectionRail | 테마 아래 | comfortable 최대360, 간격16·edgeHint24, 실제 viewport 측정 |
|
|
40
|
+
| 카드 | Card·TextField | 각각 listitem | Card recipe padding/표면과 Provider 테마 상속 |
|
|
41
|
+
| 상세 열기 | Button in Card.actions | 카드 본문 아래 | tone secondary, 카드 전체를 button으로 감싸지 않음 |
|
|
42
|
+
| 상세 | Dialog·Stack | 기존 modal portal/Native Modal | Dialog size/keyboard/safe-area contract, Stack gap16 |
|
|
43
|
+
|
|
44
|
+
## 흐름과 상태
|
|
45
|
+
|
|
46
|
+
1. 카드 메모를 작성하고 이전/다음·touch·Web 키보드로 탐색한다. 모든 카드의 ID/초안은 남는다.
|
|
47
|
+
2. 일부 보이는 카드의 입력에 초점을 주면 필요한 만큼 노출한다. 입력의 방향/Home/End 키를 목록이 가로채지 않는다.
|
|
48
|
+
3. 상세 보기를 열어 별도 메모를 작성한다. Dialog가 배경 잠금/닫기/초점 복귀를 소유한다.
|
|
49
|
+
4. 본문 또는 상세 안에서 다음 테마를 누른다. 원문·초안·열린 대상이 유지된다. 닫고 다시 열어도 상세 초안이 남는다.
|
|
50
|
+
|
|
51
|
+
| 상태 | 모습 | 포커스·알림 |
|
|
52
|
+
| --- | --- | --- |
|
|
53
|
+
| 기본 | 여러 카드와 끝 controls | 목록/행동 이름, 선택값 없이 scroll anchor |
|
|
54
|
+
| 진행 중 | host scroll 또는 상세 편집 | reduced-motion 즉시 탐색, 편집 키/초안 유지 |
|
|
55
|
+
| 실패 | 이 fixture는 서버 요청을 실행하지 않음 | 제품 조회/저장 실패는 기존 Notice·복구 계약 합성; 가짜 서버 성공/실패 없음 |
|
|
56
|
+
| 빈 목록 | 제품 emptyContent | 양 끝 controls 잠김, stale 선택/모달 생성 없음 |
|
|
57
|
+
|
|
58
|
+
## 코드 골격
|
|
59
|
+
|
|
60
|
+
```tsx
|
|
61
|
+
// Web
|
|
62
|
+
import { CollectionRail } from "@hjmds/react/collection-rail";
|
|
63
|
+
import { Card } from "@hjmds/react/display";
|
|
64
|
+
import { Dialog } from "@hjmds/react/overlays";
|
|
65
|
+
<CollectionRail label={title} items={records} labels={labels}
|
|
66
|
+
renderItem={item => <Card title={item.label} actions={<Dialog title={item.label}
|
|
67
|
+
closeLabel={closeLabel} trigger={<OpenDetailButton item={item} />}><Detail item={item} /></Dialog>}>
|
|
68
|
+
<RecordFields item={item} />
|
|
69
|
+
</Card>} />
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
// Native
|
|
74
|
+
import { CollectionRail } from "@hjmds/react-native/collection-rail";
|
|
75
|
+
import { Card } from "@hjmds/react-native/data-display";
|
|
76
|
+
import { Dialog } from "@hjmds/react-native/overlays";
|
|
77
|
+
<CollectionRail label={title} items={records} labels={labels}
|
|
78
|
+
renderItem={item => <RecordCard item={item} />} />
|
|
79
|
+
// RecordCard owns open/close, stable drafts, Card.actions Button and Dialog.returnFocusRef.
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Native는 controlled Dialog open/onOpenChange를 쓴다.
|
|
83
|
+
테마·초안·상세 open owner를 rail 밖 stable card에 두고 key는 item.id만 사용한다.
|
|
84
|
+
|
|
85
|
+
## 플랫폼 차이
|
|
86
|
+
|
|
87
|
+
| 항목 | Web | Native |
|
|
88
|
+
| --- | --- | --- |
|
|
89
|
+
| 상세 호출 | Dialog의 canonical trigger in Card.actions | Card.actions Button과 controlled Dialog, 실제 OS 복귀 검수 별도 |
|
|
90
|
+
| 보기 변경 | ResizeObserver와 input focus 노출 | ScrollView layout/content-size와 focus 노출, OS touch/VoiceOver 별도 |
|
|
91
|
+
| 테마 | 같은 Provider 경로의 10 profiles | 같은 profiles/데이터, 플랫폼 표현 |
|