@hjmds/design-contracts 1.31.0 → 1.32.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/behaviors.d.ts +2 -0
- package/dist/behaviors.d.ts.map +1 -1
- package/dist/bottom-navigation.d.ts +19 -0
- package/dist/bottom-navigation.d.ts.map +1 -1
- package/dist/bottom-navigation.js +21 -0
- package/dist/bottom-navigation.js.map +1 -1
- package/dist/catalog.d.ts +37 -0
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +2 -1
- package/dist/catalog.js.map +1 -1
- package/dist/component-recipes.d.ts +39 -0
- package/dist/component-recipes.d.ts.map +1 -1
- package/dist/component-recipes.js +27 -1
- package/dist/component-recipes.js.map +1 -1
- package/dist/image-choice.d.ts +40 -0
- package/dist/image-choice.d.ts.map +1 -1
- package/dist/image-choice.js +49 -0
- package/dist/image-choice.js.map +1 -1
- package/dist/pagination.d.ts +53 -0
- package/dist/pagination.d.ts.map +1 -1
- package/dist/pagination.js +48 -0
- package/dist/pagination.js.map +1 -1
- package/dist/screen-patterns.d.ts +52 -2
- package/dist/screen-patterns.d.ts.map +1 -1
- package/dist/screen-patterns.js +34 -1
- package/dist/screen-patterns.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/authoring-tools.md +1 -0
- package/docs/bottom-navigation.md +18 -0
- package/docs/data-workflows.md +1 -0
- package/docs/generated/component-maturity.md +1 -1
- package/docs/generated/renderer-evidence.json +7 -5
- package/docs/generated/renderer-evidence.md +1 -1
- package/docs/generated/showcase-manifest.json +4 -2
- package/docs/pagination.md +17 -0
- package/docs/screen-patterns.md +37 -1
- package/docs/toast.md +10 -0
- package/docs/usage/README.md +6 -6
- package/docs/usage/components/bottom-cta.md +11 -0
- package/docs/usage/components/bottom-navigation.md +36 -2
- package/docs/usage/components/chat-date-separator.md +3 -3
- package/docs/usage/components/chat-message.md +5 -2
- package/docs/usage/components/chat-screen.md +1 -1
- package/docs/usage/components/comment-thread-row.md +1 -1
- package/docs/usage/components/conversation-row.md +3 -3
- package/docs/usage/components/icon-tile.md +9 -2
- package/docs/usage/components/image-choice-group.md +33 -4
- package/docs/usage/components/media-selection-screen.md +5 -3
- package/docs/usage/components/moderation-screen.md +20 -1
- package/docs/usage/components/page-indicator.md +3 -3
- package/docs/usage/components/pagination.md +28 -4
- package/docs/usage/components/screen-layout.md +6 -3
- package/docs/usage/components/search-screen.md +5 -3
- package/docs/usage/components/toast.md +5 -0
- package/docs/usage/components/typing-indicator.md +3 -3
- package/docs/usage/screens/common-conversation-list.md +2 -2
- package/package.json +1 -1
|
@@ -84,7 +84,7 @@ import { ScreenLayout } from "@hjmds/react-native/screens";
|
|
|
84
84
|
| `scroll` | `"screen"` · `"content"` | `"screen"` | `content`는 본문 자식(가상화 목록)이 스크롤을 소유한다. 상태 교체 중에는 `screen`으로 돌아간다 |
|
|
85
85
|
| `contentAlignment` | `"start"` · `"center"` | `"start"` | ready 본문을 사용 영역 중앙에 배치. 긴 본문은 위가 잘리지 않게 스크롤한다. 로그인/제품 안내를 가짜 query state로 바꾸지 않는다(1.24.0) |
|
|
86
86
|
| `surface` | `"default"` · `"transparent"` | `"default"` | 투명은 제품 host의 배경·wallpaper를 보존. 배경색 style 우회 대신 사용(1.24.0) |
|
|
87
|
-
| `contentInset` | `"default"` · `"none"` · `"body-edge"` | `"default"` | `none`은 헤더·notice·본문·footer padding을 0으로(Native는 footer 위 테두리도 뺀다). host가 모든 여백을 이미 줄 때 쓴다. `body-edge`는 헤더·notice·footer 여백(16)과 footer 테두리를 유지하고 **본문 좌우 padding만 0**으로 한다. 자기 좌우 여백을 가진 전체 폭 목록 행(ConversationRow·NotificationRow 등 행 padding 16)을 본문에 바로 둘 때 쓴다(미게시). ListRow·NotificationItem은 `default`에 둔다. 값 목록은 계약 `ScreenContentInset`·`screenContentInsets` |
|
|
87
|
+
| `contentInset` | `"default"` · `"none"` · `"body-edge"` | `"default"` | `none`은 헤더·notice·본문·footer padding을 0으로(Native는 footer 위 테두리도 뺀다). host가 모든 여백을 이미 줄 때 쓴다. `body-edge`는 헤더·notice·footer 여백(16)과 footer 테두리를 유지하고 **본문 좌우 padding만 0**으로 한다. 자기 좌우 여백을 가진 전체 폭 목록 행(ConversationRow·NotificationRow 등 행 padding 16)을 본문에 바로 둘 때 쓴다(미게시). ListRow·NotificationItem은 `default`에 둔다. `body-bleed`(미게시, 1.31.0 이후)는 같은 여백을 유지하고 **본문 네 방향 padding을 모두 0**으로 해 지도·캔버스가 헤더(또는 notice)·화면 좌우·footer에 바로 닿는다. footer가 없으면 본문이 마지막 영역이라 여백 16 없이 `safeAreaBottom`(Native)과 겹친 하단 탐색 높이만 비운다. 홈 인디케이터 아래까지 그리려면 `safeAreaBottom`을 넘기지 않는다. `body-edge`·`body-bleed`에서도 로딩·빈 상태·오류 안내 묶음은 자기 여백이 없으므로 좌우 16을 유지한다(1.32.0 수정). 값 목록은 계약 `ScreenContentInset`·`screenContentInsets` |
|
|
88
88
|
| `presentation` | `"dashboard"` · `"editorial"` · `"landscape"` | 가장 가까운 profile.screens.overview / 없으면 기존 골격 | [디자인 프로필](../../design-profile.md)의 제공 범위를 따른다. 명시값이 프로필을 이긴다. 헤더 배치·읽기 폭만 바꾸고 상태·입력·행동 슬롯은 유지한다 |
|
|
89
89
|
| `as` (Web) | `"main"` · `"section"` | `"main"` | 제품 셸에 이미 `<main>`이 있으면 `section` |
|
|
90
90
|
| `initialFocus` | `first-input` · `none` | `none` | 1.28.1. 진입 시 텍스트 입력 하나에 한 번 포커스한다. 아래 [진입 포커스](#진입-포커스) |
|
|
@@ -98,10 +98,10 @@ import { ScreenLayout } from "@hjmds/react-native/screens";
|
|
|
98
98
|
| 항목 | 값 | 근거 |
|
|
99
99
|
| --- | --- | --- |
|
|
100
100
|
| 크기 | 폭 100%, 최대 `screenPatternRecipe.maxWidth`(`layout.readingMaxWidth` 720), 가운데 정렬; 높이는 host가 준 남은 높이(Web `block-size: 100%`, Native `flex: 1`) | Web `.hjm-screen`, Native `ScreenLayout` |
|
|
101
|
-
| 간격 | 바깥 padding `screenPatternRecipe.padding`(`spacing.md` 16)을 헤더 사방·notice 좌우·본문 사방·footer 사방에 준다(`contentInset="none"`이면 0, `"body-edge"`면 본문 좌우만 0); 헤더 안 `exit`·제목·`actions` 간격 `itemGap`(`spacing.sm`) 12(두 플랫폼, `contentInset="none"`이어도 유지); 상태 안내는 위아래 `sectionGap`(`spacing.xl`) 24, 안내–`stateAction` `stateGap`(`spacing.md`) 16 | Web `src/screens.tsx`(`--hjm-screen-item-gap`·`--hjm-screen-state-gap`)·`.hjm-screen__*`, Native `ScreenLayout` |
|
|
101
|
+
| 간격 | 바깥 padding `screenPatternRecipe.padding`(`spacing.md` 16)을 헤더 사방·notice 좌우·본문 사방·footer 사방에 준다(`contentInset="none"`이면 0, `"body-edge"`면 본문 좌우만 0, `"body-bleed"`면 본문 사방 0); 헤더 안 `exit`·제목·`actions` 간격 `itemGap`(`spacing.sm`) 12(두 플랫폼, `contentInset="none"`이어도 유지); 상태 안내는 위아래 `sectionGap`(`spacing.xl`) 24, 안내–`stateAction` `stateGap`(`spacing.md`) 16 | Web `src/screens.tsx`(`--hjm-screen-item-gap`·`--hjm-screen-state-gap`)·`.hjm-screen__*`, Native `ScreenLayout` |
|
|
102
102
|
| 제목 | 기본 가운데 `Heading` `screenHeaderRecipe.centeredTitleLevel`(level5), `headerAlignment="start"`면 `titleLevel`(level3). 추가 기능 버튼(`actions`)은 끝(오른쪽) 위, 나가기(`exit`)는 시작(왼쪽) 위. 헤더 높이는 두 플랫폼 모두 `screenHeaderRecipe`의 고정 띠 | `screenHeaderRecipe` |
|
|
103
103
|
| 순서·정렬 | 헤더(`exit` → 제목·설명 → `actions`) → notice → 본문 → footer; 상태 안내는 본문 세로 가운데 `exit`는 HJM이 `edge="start"`로 그려 아이콘 칸이 헤더 여백 선 16에 온다(Web·Native 31 → 16, 가운데 헤더의 같은 폭 양쪽 열·제목 중앙은 그대로). 끝 `actions`의 마지막 ghost IconButton은 제품이 `edge="end"`를 준다(2026-10-17 실측 감사, [IconButton `edge`](icon-button.md#배치)) | 렌더 순서 |
|
|
104
|
-
| 고정·스크롤 | 헤더·notice·footer 고정, `scroll="screen"`은 본문이 스크롤, `"content"`는 자식이 스크롤; footer 위 테두리 1. 마지막 영역(footer, 없으면 본문)의 아래 여백은 `max(16, 하단 inset)`이다 — Web은 `env(safe-area-inset-bottom)`, Native는 `safeAreaBottom`. 16 + inset으로 더하지 않으며, 키보드가 열려 있으면 키보드가 홈 인디케이터를 덮으므로 16만
|
|
104
|
+
| 고정·스크롤 | 헤더·notice·footer 고정, `scroll="screen"`은 본문이 스크롤, `"content"`는 자식이 스크롤; footer 위 테두리 1. 마지막 영역(footer, 없으면 본문)의 아래 여백은 `max(16, 하단 inset)`이다 — Web은 `env(safe-area-inset-bottom)`, Native는 `safeAreaBottom`. 16 + inset으로 더하지 않으며, 키보드가 열려 있으면 키보드가 홈 인디케이터를 덮으므로 16만 둔다. [BottomNavigationInsetProvider](bottom-navigation.md#막대가-덮는-높이-bottomnavigationinsetprovider-1310) 안이면 같은 마지막 영역이 `max(위 값, 16 + 덮인 높이)`를 한 번 둔다. `scroll="content"` 목록이나 ScreenLayout 위의 화면 구성이 다시 더하지 않는다(1.32.0) | Web `data-scroll`·`.hjm-screen__footer`, Native `ScrollView` |
|
|
105
105
|
| 좁은 폭·큰 글자 | 제목 열 최소 폭 `headerMinWidth` 120 × 글자 배율, 모자라면 `actions`가 다음 줄로 내려간다; 제목은 줄바꿈(`overflow-wrap: anywhere`)되고 자르지 않는다; Native 위·옆 safe area·탭바 inset은 host, 아래 inset은 `safeAreaBottom` | `screenPatternRecipe.headerMinWidth`, Web `.hjm-screen__heading` |
|
|
106
106
|
|
|
107
107
|
## 진입 포커스
|
|
@@ -163,6 +163,7 @@ import { ScreenLayout } from "@hjmds/react-native/screens";
|
|
|
163
163
|
- 이미 `<main>`이 있는 제품 셸 안에서는 `as="section"`을 준다. 중첩 main이 생긴다.
|
|
164
164
|
|
|
165
165
|
- 본문 좌우 여백을 직접 빼려고 목록에 음수 margin이나 제품 CSS를 쓰지 않는다. 행이 자기 여백을 가지면 `contentInset="body-edge"`, host가 모든 여백을 가지면 `"none"`이다. ListRow·NotificationItem은 글자를 부모 콘텐츠 가장자리에 두고 표면만 8 바깥으로 넓히므로(2026-10-17) `default` 본문에서 글자가 여백 선 16에 오고 설정 묶음 제목·알림 그룹 제목과 같은 선에 선다. `body-edge` 본문에 두면 글자가 화면 끝에 붙으므로 두지 않는다.
|
|
166
|
+
- 지도·캔버스를 화면 끝까지 그리려고 `body-edge` 본문에 음수 margin을 주거나 `none` + 직접 만든 헤더 여백을 쓰지 않는다. `contentInset="body-bleed"`다. 본문에 글자 목록을 두는 화면에는 쓰지 않는다(글자가 화면 끝에 붙는다). 지도 위에 띄우는 입력판·버튼의 여백은 제품 오버레이가 정한다.
|
|
166
167
|
|
|
167
168
|
### 디자인 프로필의 화면 표현
|
|
168
169
|
|
|
@@ -179,4 +180,6 @@ dashboard는 가로 헤더/1200 목록 폭, editorial은 세로 헤더/720 읽
|
|
|
179
180
|
- 하단 여백 `max(16, inset)`(Native `safeAreaBottom`): 2026-10-17 사용자 보고 "전체적으로 버튼 아래 여백이 많아". Native Storybook의 사진 선택과 업로드 화면에서 버튼 아래가 약 33pt였다. 원인은 둘이었다. 화면 스토리의 route host가 고정 높이 720이라 iPhone 17 Pro 스토리 영역 737보다 17 짧았고(footer 16 + 빈 칸 17), 컴포넌트는 Native footer가 safe area를 다루지 않아 host의 아래 inset 위에 16을, footer 안 BottomCTA의 `safeAreaBottom`도 16 위에 더했다(16 + 34 = 50). Web footer는 이미 `max(16, env())`였지만 footer 안 BottomCTA의 `safeAreaBottom`은 그 위에 더했다. 표준을 "마지막 컨트롤 아래 = footer 위 여백 16, 홈 인디케이터 기기에서는 max(16, inset)"으로 정하고 footer가 한 번만 소유하게 했다.
|
|
180
181
|
- 화면 여백은 ScreenLayout 소유, 바깥 여백 + `none` 미지원: 2026-10-17 바깥 여백 호스트 예제 사용자 검토. utilverse식(`Container gutter="regular"` 20 + `contentInset="none"`)을 HJM에서 지원하려고 본문 확장·footer 바 소유를 붙인 예제가 어색하다는 판단으로 지원을 접었다(2026-10-15 공통 구조는 HJM 소유 원칙). 측정상 그 구성에서는 Web 402·1280에서 행 표면이 양쪽 8 잘리고 본문이 옆으로 8 스크롤되며, Native 3x에서 선택 테두리 옆 선이 그려지지 않았다. 제품은 바깥 여백을 걷고 기본 inset을 쓴다.
|
|
181
182
|
- `contentInset="body-edge"`: 2026-10-17 사용자 결정. 화면 검토 S5#9에서 대화 목록 아바타가 화면 끝에서 약 32pt 안쪽에서 시작했다. 본문 padding 16과 ConversationRow 자체 padding 16이 겹쳤다(인스타그램 DM은 약 16). 앱 약 45곳이 "host가 모든 여백을 소유한다"는 뜻으로 `none`을 쓰고 있어 `none`의 의미를 바꿀 수 없었으므로 값을 새로 추가했다. ChatScreen의 10 타임라인 여백은 `default`일 때만 공통 여백을 대신한다.
|
|
183
|
+
- `contentInset="body-bleed"`: 2026-10-18 HJM 1.32.0 감사. 선택의창 지도 화면 세 곳(홈·경로 지도·지도에서 고르기)이 `body-edge`로 지도를 좌우 끝까지 그렸지만 본문 위아래 padding 16이 남아 헤더·footer와 지도 사이에 띠가 생겼다. `body-edge`의 뜻(전체 폭 목록 행의 좌우 여백)과 `none`의 뜻(host가 모든 여백)을 바꿀 수 없어 값을 추가했다.
|
|
184
|
+
- 하단 탐색 여백의 단일 소유: 2026-10-18 HJM 1.32.0. BottomNavigation 사용 지침이 `scroll="content"` 화면에 목록 여백으로 다시 더하라고 안내했으나 ScreenLayout은 그 화면에도 이미 적용했다(두 번 쌓임). 지침을 ScreenLayout 단일 소유로 고쳤다.
|
|
182
185
|
- 오버레이 안의 화면 진입 포커스: 2026-10-18 번뚝 검색 오버레이. Web은 화면을 감싼 제품 `aria-modal`을 화면 위의 모달로 보고 진입 포커스를 막았고, HJM Sheet 안에 둔 ScreenLayout은 Sheet의 첫 컨트롤(닫기)에 포커스를 빼앗겼다. Native는 오버레이 표시 전에 칸을 포커스해 무시될 수 있었다. 감싸는 모달은 막지 않고 오버레이 안의 화면은 오버레이와 함께 진입하도록 고쳤다(1.31.0 patch).
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
6
|
- 적용: 1.17.1
|
|
7
|
-
- 검토일: 2026-10-
|
|
8
|
-
- 근거: [반복 화면 조합](../../screen-patterns.md), Web·Native `src/screens.tsx`·`src/screen-flows.tsx`; 기존 개별 지침을 새 규격으로 통합. `onSubmit`·`filtersOverflow`는 2026-10-06 사용자 요청("검색과 필터 있는 앱 서비스 따라해")의 검색 화면 개편에서 추가. 같은 날 사용자 위임 결정(권장안)으로 미리보기에만 있던 두 단계 검색 로직(`committedQuery`·`recentQueries`·`suggestedQueries`·`suggestions`·`resultSummary`·`appliedFilters`·`filterSheet`)과 `queryLabelVisibility`를, utilverse 적용 조사로 `searching`·`searchingLabel`을 추가([계약 결정 표](../../screen-patterns.md#searchscreen-두-단계-검색)). 1.13.0 utilverse 적용에서 드러난 결함으로 `hostGutter`와 확정 시 키보드 닫기(Web 결과 영역 포커스)를 추가(1.13.1 patch). 예제 스토리는 2026-10-06 사용자 승인으로 스토리북 배포([승인 기록](../../../../../docs/STORYBOOK_NAVIGATION.md#21-2026-10-06-전체-승격과-규격-확정)). 스토리북 배포는 API 게시가 아니다(`적용` 참고)
|
|
7
|
+
- 검토일: 2026-10-18
|
|
8
|
+
- 근거: [반복 화면 조합](../../screen-patterns.md), Web·Native `src/screens.tsx`·`src/screen-flows.tsx`; 기존 개별 지침을 새 규격으로 통합. `onSubmit`·`filtersOverflow`는 2026-10-06 사용자 요청("검색과 필터 있는 앱 서비스 따라해")의 검색 화면 개편에서 추가. 같은 날 사용자 위임 결정(권장안)으로 미리보기에만 있던 두 단계 검색 로직(`committedQuery`·`recentQueries`·`suggestedQueries`·`suggestions`·`resultSummary`·`appliedFilters`·`filterSheet`)과 `queryLabelVisibility`를, utilverse 적용 조사로 `searching`·`searchingLabel`을 추가([계약 결정 표](../../screen-patterns.md#searchscreen-두-단계-검색)). 1.13.0 utilverse 적용에서 드러난 결함으로 `hostGutter`와 확정 시 키보드 닫기(Web 결과 영역 포커스)를 추가(1.13.1 patch). `filtersRole`은 2026-10-18 choose-window 적용 감사에서 추가(검색어 때문인 0건의 복구 수단인 범위 필터가 숨겨져 제품이 `resultSummary`를 쓰지 못했다). 예제 스토리는 2026-10-06 사용자 승인으로 스토리북 배포([승인 기록](../../../../../docs/STORYBOOK_NAVIGATION.md#21-2026-10-06-전체-승격과-규격-확정)). 스토리북 배포는 API 게시가 아니다(`적용` 참고)
|
|
9
9
|
- 스토리북: `배포/화면/검색/검색 결과와 필터`
|
|
10
10
|
|
|
11
11
|
## 언제 쓰나
|
|
@@ -145,7 +145,8 @@ import { SearchScreen } from "@hjmds/react-native/screen-flows";
|
|
|
145
145
|
| `queryClearLabel` | `string` | `queryField`가 없으면 필수 | 기본 입력의 지우기 버튼 이름. 비어 있으면 `TypeError` |
|
|
146
146
|
| `queryField` | `ReactNode` | 없음 | 기본 `SearchField` 대신 그릴 입력. 지우기 동작을 직접 제공한다 |
|
|
147
147
|
| `debounceMs` | `number` | `searchScreenRecipe.debounceMs` (`300`) | 유한값을 받으며 0 미만은 0. `NaN`·±`Infinity`는 `RangeError`. 두 renderer가 `resolveSearchDebounceMs`를 공유한다 |
|
|
148
|
-
| `filters` | `ReactNode` | 없음 | 검색 입력 아래, 상단에 고정. 두 단계 검색에서는 결과
|
|
148
|
+
| `filters` | `ReactNode` | 없음 | 검색 입력 아래, 상단에 고정. 두 단계 검색에서는 결과 단계에만. 검색어 때문인 0건에는 `filtersRole="narrow"`(기본)면 숨기고 `scope`면 남긴다 |
|
|
149
|
+
| `filtersRole` | `narrow` · `scope` | `narrow` | 1.32.0, 미게시. 필터 줄(`filters`·`filterSheet.trigger`)이 결과에 하는 일. `narrow`는 결과를 좁히기만 해서 적용한 필터 없이 0건이면 검색어 탓이고 어떤 필터도 결과를 되살리지 못하므로 줄을 숨긴다. `scope`는 무엇을 찾을지 고르는 필터(장소명/주소, 지역, 지도 영역)라 적용한 필터가 없어도 바꾸면 결과가 생길 수 있으므로 0건에도 줄을 남긴다. 판정은 두 renderer가 공유하는 `resolveSearchFilterRailVisible`(`@hjmds/design-contracts/screen-patterns`) |
|
|
149
150
|
| `onSubmit` | `(query: string) => void` | 없음 | 확정 신호. 모든 확정에서 키보드를 닫는다(Native `Keyboard.dismiss()`, Web은 고른 항목이면 결과 영역으로 포커스, 1.13.1 변경) — 아래 플랫폼 차이. 기본 입력의 Web Enter(`enterKeyHint="search"`, IME 조합 중 Enter는 무시)·Native 키보드 검색 키(`returnKeyType="search"`, `onSubmitEditing`)와 SearchScreen이 그린 확정 행·제안·최근·추천 검색어가 모두 여기로 온다. 앞뒤 공백을 지운 값이고 공백만이면 부르지 않는다. 고른 값이 입력과 다르면 먼저 `onQueryChange`. 대기 중인 `onSearch` debounce는 그대로 둔다. `queryField`를 주면 그 입력의 키는 연결하지 않는다 |
|
|
150
151
|
| `committedQuery` | `string` | 없음 | 결과를 보여 줄 확정 검색어. 주면 두 단계 검색(`onSubmit` 필수, 타입). 단계: 검색어 공백 = 검색 전, 확정값과 다름 = 입력 중, 같음 = 결과(앞뒤 공백 무시). `children`은 결과 단계에만 그린다 |
|
|
151
152
|
| `queryLabelVisibility` | `visible` · `hidden` | `visible` | `hidden`이면 보이는 label 없이 `queryLabel`을 접근성 이름(Web `aria-label`, Native `accessibilityLabel`)과 placeholder로 쓴다 |
|
|
@@ -188,6 +189,7 @@ import { SearchScreen } from "@hjmds/react-native/screen-flows";
|
|
|
188
189
|
`onSearch`는 보내지 않는다. `onSearch`에서 저장하면 "산", "산책"이 따로 쌓인다(2026-10-06 개편 전 공통 검색 예제의 결함).
|
|
189
190
|
- 두 단계 검색에서 `children`에는 결과 목록만 넣는다. 제안·로딩 행·0건 EmptyState·개수·정렬을 다시 그리면 SearchScreen이 그린 것과 겹친다.
|
|
190
191
|
- 적용 조건은 `appliedFilters`로 넘긴다. 0건 원인(필터면 칩 줄 유지 + `모두 해제`, 검색어면 칩 줄 숨김 + 추천 검색어)을 이 개수로 판정한다.
|
|
192
|
+
- 검색 종류·지역·지도 영역처럼 무엇을 찾을지 고르는 필터는 `filtersRole="scope"`로 표시한다. 검색어 때문인 0건에도 필터 줄이 남아 바꿔 볼 수 있다. 이 때문에 `resultSummary`를 버리고 0건·로딩을 `children`에 다시 그리지 않는다(2026-10-18 choose-window 장소명/주소 전환).
|
|
191
193
|
- 시트 `count`와 결과 개수는 같은 계산에서 나와야 한다. 다르면 "N개 결과 보기"와 적용 뒤 개수가 어긋난다.
|
|
192
194
|
- `contentInset="none"`으로 host가 여백을 주는 화면은 `hostGutter`에 그 여백 이름을 넘긴다. 없으면 `scroll` 줄이 host 여백 안에서 잘린다.
|
|
193
195
|
- 칩이 여러 개인 필터 줄은 `filtersOverflow="scroll"`로 한 줄에 둔다. 제품이 CSS·ScrollView로 가로 스크롤을 따로 만들지 않는다
|
|
@@ -159,6 +159,9 @@ Native의 선택형 `/toast-liquid`도 가장 가까운 프로필의 `radius.xl`
|
|
|
159
159
|
- Provider/Region은 앱에 하나만 두고 화면마다 새로 만들지 않는다. 진행 상태를 바꿀 때는 같은 `id`로 다시 `publish`한다.
|
|
160
160
|
- 문구는 모두 i18n 키로 만든 일반 문자열이다(ReactNode 아님). 아이콘만 있는 닫기 버튼 때문에 `closeLabel`이 필수다.
|
|
161
161
|
- 색·모양은 tone이 정한다. 카드에 브랜드 색을 덮지 않는다. 문구·id·action은 제품 소유, 카드 모양·큐·타이머는 HJM 소유다.
|
|
162
|
+
- 가장자리 상태색 띠는 없다. tone은 배지(또는 `media`)와 문구가 전달한다. 띠를 숨기는 옵션·CSS·팔레트 덮어쓰기를 두지 않는다 —
|
|
163
|
+
1.10.0에 띠를 없앴고, 미게시(1.32.0 예정)부터는 Web의 늘 숨겨져 있던 `.hjm-toast__tone-mark` 요소도 그리지 않는다.
|
|
164
|
+
Native에서 `statusAccents`·`danger`를 바탕색으로 바꾸면 띠가 아니라 tone 아이콘에 넘기는 색(`renderToneIcon`의 `color`)이 지워진다.
|
|
162
165
|
- Native는 `safeAreaInsets`를 제품이 넘긴다(기본 `{}`). 하단 고정 바가 있으면 Web `bottomOffset`, Native `keyboardOffset`으로 띄운다.
|
|
163
166
|
|
|
164
167
|
## 플랫폼 차이
|
|
@@ -174,6 +177,8 @@ Native의 선택형 `/toast-liquid`도 가장 가까운 프로필의 `radius.xl`
|
|
|
174
177
|
|
|
175
178
|
## 함정
|
|
176
179
|
|
|
180
|
+
- 2026-10-18 번뚝은 1.10.0에 이미 없어진 띠를 숨기려고 Web `.hjm-toast__tone-mark { display: none }`과 Native 토스트 영역의 팔레트 덮어쓰기를 유지하고 있었다. 띠 계약은 "없음"이며 `toastRecipe.toneMark`는 호환용으로만 남은 deprecated 값(너비 0)이다.
|
|
181
|
+
|
|
177
182
|
- `/toast-liquid`는 앱에 없을 수 있는 optional native peer `@shopify/react-native-skia`·`react-native-reanimated`·
|
|
178
183
|
`react-native-worklets`를 import한다(peerDependenciesMeta에서 모두 optional). 2026-10에 이런 subpath가
|
|
179
184
|
tsc·테스트는 통과했는데 기기 Metro에서 크래시가 났다. 세 peer가 개발 클라이언트 바이너리에 들어 있을 때만 import한다.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# TypingIndicator
|
|
2
2
|
|
|
3
3
|
- 단계: 컴포넌트
|
|
4
|
-
- 상태:
|
|
4
|
+
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
|
-
- 적용:
|
|
6
|
+
- 적용: 1.31.0
|
|
7
7
|
- 검토일: 2026-10-18
|
|
8
8
|
- 근거: [반복 화면 조합](../../screen-patterns.md), `src/screen-patterns.ts`의 `typingIndicatorRecipe`·`chatMessageRecipe`; Web·Native `src/screens.tsx`
|
|
9
|
-
- 스토리북:
|
|
9
|
+
- 스토리북: `배포/컴포넌트/상태와 알림/입력 중 표시`
|
|
10
10
|
|
|
11
11
|
## 언제 쓰나
|
|
12
12
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# 대화 목록
|
|
2
2
|
|
|
3
3
|
- 단계: 화면
|
|
4
|
-
- 상태:
|
|
4
|
+
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
6
|
- 적용: 구성 API 지침 참조
|
|
7
7
|
- 검토일: 2026-10-17
|
|
8
8
|
- 근거: 2026-10-16 사용자가 제공한 인스타그램 iOS DM 목록·길게 누르기 캡처. 행은 [ConversationRow](../components/conversation-row.md), 행 메뉴는 [ContextMenu](../components/context-menu.md)(Native canonical은 같은 날 추가, 미게시)
|
|
9
|
-
- 스토리북:
|
|
9
|
+
- 스토리북: `배포/화면/소통/대화 목록`
|
|
10
10
|
|
|
11
11
|
공통 구조·배치·상태·배지의 소유권은 [화면과 구성 선택](../SELECTION.md#소유권)을 따른다. 앱은 데이터·문구·브랜드·추가 기능을 공개 슬롯과 콜백으로 연결한다. 아래 코드 골격을 앱별 기본 구조 복제의 근거로 사용하지 않는다.
|
|
12
12
|
|