@hjmds/design-contracts 1.29.0 → 1.31.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.
- package/dist/behaviors.d.ts +1 -0
- package/dist/behaviors.d.ts.map +1 -1
- package/dist/bottom-navigation.d.ts +24 -0
- package/dist/bottom-navigation.d.ts.map +1 -1
- package/dist/bottom-navigation.js +34 -0
- package/dist/bottom-navigation.js.map +1 -1
- package/dist/carousel.d.ts +30 -0
- package/dist/carousel.d.ts.map +1 -1
- package/dist/carousel.js +32 -0
- package/dist/carousel.js.map +1 -1
- package/dist/catalog.d.ts +382 -64
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +147 -131
- package/dist/catalog.js.map +1 -1
- package/dist/component-definitions.d.ts +21 -131
- package/dist/component-definitions.d.ts.map +1 -1
- package/dist/component-definitions.js +9 -132
- package/dist/component-definitions.js.map +1 -1
- package/dist/component-recipes.d.ts +87 -0
- package/dist/component-recipes.d.ts.map +1 -1
- package/dist/component-recipes.js +44 -1
- package/dist/component-recipes.js.map +1 -1
- package/dist/icon.d.ts +58 -1
- package/dist/icon.d.ts.map +1 -1
- package/dist/icon.js +69 -0
- package/dist/icon.js.map +1 -1
- package/dist/image-choice.d.ts +7 -0
- package/dist/image-choice.d.ts.map +1 -1
- package/dist/image-choice.js +7 -0
- package/dist/image-choice.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/recipes.d.ts +1 -1
- package/dist/recipes.d.ts.map +1 -1
- package/dist/recipes.js.map +1 -1
- package/dist/screen-patterns.d.ts +100 -0
- package/dist/screen-patterns.d.ts.map +1 -1
- package/dist/screen-patterns.js +98 -3
- package/dist/screen-patterns.js.map +1 -1
- package/dist/showcase.d.ts.map +1 -1
- package/dist/showcase.js +10 -0
- package/dist/showcase.js.map +1 -1
- package/dist/steps.d.ts +16 -7
- package/dist/steps.d.ts.map +1 -1
- package/dist/steps.js +6 -1
- package/dist/steps.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/architecture.md +18 -0
- package/docs/bottom-navigation.md +10 -0
- package/docs/carousel.md +8 -0
- package/docs/dialog.md +23 -0
- package/docs/generated/component-maturity.md +32 -29
- package/docs/generated/renderer-evidence.json +1551 -1118
- package/docs/generated/renderer-evidence.md +243 -237
- package/docs/generated/showcase-manifest.json +688 -69
- package/docs/icon.md +9 -0
- package/docs/screen-patterns.md +18 -0
- package/docs/stable-core.md +22 -0
- package/docs/steps.md +4 -3
- package/docs/usage/README.md +28 -25
- package/docs/usage/SELECTION.md +1 -1
- package/docs/usage/components/auth-screen-layout.md +15 -5
- package/docs/usage/components/bottom-navigation.md +65 -2
- package/docs/usage/components/card.md +36 -5
- package/docs/usage/components/carousel.md +1 -0
- package/docs/usage/components/chat-date-separator.md +86 -0
- package/docs/usage/components/chat-message.md +10 -1
- package/docs/usage/components/chat-screen.md +3 -2
- package/docs/usage/components/comment-thread-row.md +11 -3
- package/docs/usage/components/comment-thread-screen.md +1 -1
- package/docs/usage/components/dialog.md +69 -0
- package/docs/usage/components/editor-screen.md +6 -2
- package/docs/usage/components/field.md +13 -0
- package/docs/usage/components/icon-button.md +1 -0
- package/docs/usage/components/icon-tile.md +10 -1
- package/docs/usage/components/icon.md +45 -6
- package/docs/usage/components/image-choice-group.md +3 -1
- package/docs/usage/components/media-selection-screen.md +17 -0
- package/docs/usage/components/message-composer.md +4 -1
- package/docs/usage/components/moderation-screen.md +88 -2
- package/docs/usage/components/page-indicator.md +102 -0
- package/docs/usage/components/profile-screen.md +9 -3
- package/docs/usage/components/profile-summary.md +3 -3
- package/docs/usage/components/screen-layout.md +9 -0
- package/docs/usage/components/steps.md +14 -7
- package/docs/usage/components/tabs.md +21 -1
- package/docs/usage/components/text.md +30 -1
- package/docs/usage/components/typing-indicator.md +89 -0
- package/docs/usage/screens/common-login.md +3 -1
- package/docs/usage/screens/common-profile.md +3 -3
- package/docs/usage/screens/flow-editor.md +13 -2
- package/docs/usage/screens/flow-moderation.md +31 -3
- package/package.json +2 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# TypingIndicator
|
|
2
|
+
|
|
3
|
+
- 단계: 컴포넌트
|
|
4
|
+
- 상태: 실험
|
|
5
|
+
- 지원: Web · Native
|
|
6
|
+
- 적용: 미게시(1.30.0 이후)
|
|
7
|
+
- 검토일: 2026-10-18
|
|
8
|
+
- 근거: [반복 화면 조합](../../screen-patterns.md), `src/screen-patterns.ts`의 `typingIndicatorRecipe`·`chatMessageRecipe`; Web·Native `src/screens.tsx`
|
|
9
|
+
- 스토리북: `실험/컴포넌트/상태와 알림/입력 중 표시`
|
|
10
|
+
|
|
11
|
+
## 언제 쓰나
|
|
12
|
+
|
|
13
|
+
대화 타임라인에서 상대가 지금 입력 중임을 보여 줄 때 쓴다. 수신 말풍선 자리에 점 세 개가 차례로 깜박이는 말풍선을 그리고,
|
|
14
|
+
보조기술에는 제품이 준 문구("서연님이 입력 중")를 한 번 알린다. 입력 중 여부(presence) 판단과 표시 시점은 제품이 정한다.
|
|
15
|
+
|
|
16
|
+
## 쓰지 않을 때
|
|
17
|
+
|
|
18
|
+
| 상황 | 대신 쓸 것 |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| 내 메시지 전송 중 | [ChatMessage](chat-message.md) `deliveryLabel` |
|
|
21
|
+
| 화면·영역 로딩 | [Spinner](spinner.md), ScreenLayout `state` |
|
|
22
|
+
| AI 답변 생성 중 | [StreamingAnswer](streaming-answer.md)·[ThinkingOrb](thinking-orb.md) |
|
|
23
|
+
|
|
24
|
+
## 공개 이름과 import
|
|
25
|
+
|
|
26
|
+
| 이름 | 역할 | Web | Native |
|
|
27
|
+
| --- | --- | --- | --- |
|
|
28
|
+
| `TypingIndicator` | 기본 | `@hjmds/react/screens` | `@hjmds/react-native/screens` |
|
|
29
|
+
|
|
30
|
+
루트 barrel에는 없다.
|
|
31
|
+
|
|
32
|
+
## 최소 사용 예
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
// Web
|
|
36
|
+
import { ChatMessage, ChatScreen, TypingIndicator } from "@hjmds/react/screens";
|
|
37
|
+
|
|
38
|
+
<ChatScreen title={peer.name} composer={composer}>
|
|
39
|
+
<div>
|
|
40
|
+
{messages.map(m => <ChatMessage key={m.id} {...toMessageProps(m)}>{m.text}</ChatMessage>)}
|
|
41
|
+
{peerTyping ? <TypingIndicator label={t("chat.typing", { name: peer.name })} /> : null}
|
|
42
|
+
</div>
|
|
43
|
+
</ChatScreen>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
// Native — 가상화 목록의 ListFooterComponent로 둔다
|
|
48
|
+
import { FlatList } from "react-native";
|
|
49
|
+
import { TypingIndicator } from "@hjmds/react-native/screens";
|
|
50
|
+
|
|
51
|
+
<FlatList data={messages} renderItem={renderMessage}
|
|
52
|
+
ListFooterComponent={peerTyping ? <TypingIndicator label={t("chat.typing", { name: peer.name })} /> : null} />
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## 축과 기본값
|
|
56
|
+
|
|
57
|
+
| prop | 값 | 기본값 | 설명 |
|
|
58
|
+
| --- | --- | --- | --- |
|
|
59
|
+
| `label` | `string` | 필수 | 지역화한 상태 문구. 화면에는 보이지 않고 보조기술 이름·알림이 된다. 빈 문자열은 `TypeError` |
|
|
60
|
+
| `avatar` | `ReactNode` | 없음 | 단톡방에서 입력 중인 사람 사진. ChatMessage 아바타와 같은 32(`chatMessageRecipe.avatarSize`)로 넘긴다 |
|
|
61
|
+
| `layoutStyle` | `HjmCompositionStyleProp` | 없음 | 행 배치 전용. 색·여백을 덮지 않는다 |
|
|
62
|
+
|
|
63
|
+
## 배치
|
|
64
|
+
|
|
65
|
+
| 항목 | 값 | 근거 |
|
|
66
|
+
| --- | --- | --- |
|
|
67
|
+
| 크기 | 점 `dotSize` 6(원), 말풍선 최소 높이 = 본문 줄 높이 + 위아래 `bubblePaddingBlock` 6 — 한 줄 수신 말풍선과 같은 높이; radius `bubbleRadius` 14, 표면 `surface` | `typingIndicatorRecipe`, `chatMessageRecipe` |
|
|
68
|
+
| 간격 | 점 사이 `dotGap`(`spacing.xxs`) 4, 말풍선 안 좌우 10; 위 `groupGap` 12(새 묶음처럼 떨어진다); 아바타–말풍선 `avatarGap` 8 | `typingIndicatorRecipe`, `chatMessageRecipe` |
|
|
69
|
+
| 순서·정렬 | 수신 쪽(시작 쪽) 정렬, 마지막 메시지 뒤. 아바타가 없으면 꼬리 폭 `tailWidth` 7만큼 들여 수신 말풍선과 가장자리를 맞춘다 | Web·Native `TypingIndicator` |
|
|
70
|
+
| 고정·스크롤 | 자체 고정 없음. 타임라인 목록 안에서 함께 스크롤한다 | — |
|
|
71
|
+
| 좁은 폭·큰 글자 | 점 크기는 고정. 글자 배율과 무관하다 | Web·Native `TypingIndicator` |
|
|
72
|
+
|
|
73
|
+
## 꼭 지킬 것
|
|
74
|
+
|
|
75
|
+
- 상대가 실제로 입력 중일 때만 렌더하고, 멈추면 제품이 제거한다. 표시 시간을 HJM이 정하지 않는다.
|
|
76
|
+
- 문구는 제품 i18n으로 넘긴다. 점 표시 옆에 같은 문구를 보이는 글자로 다시 쓰지 않는다.
|
|
77
|
+
- 움직임: 한 주기 `cycleMs` 1200 동안 점마다 `restOpacity` 0.35 ↔ 1로 깜박이고 점 사이 시작 간격은 `staggerMs` 160이다. 동작 줄이기(Provider `reducedMotion`, Web은 `prefers-reduced-motion`도)에서는 점이 깜박이지 않고 불투명하게 멈춘다.
|
|
78
|
+
- 알림은 정중(polite)하다. 나타날 때 한 번 읽고 진행 중인 낭독을 끊지 않는다. 타임라인 전체를 live region으로 감싸지 않는다.
|
|
79
|
+
|
|
80
|
+
## 플랫폼 차이
|
|
81
|
+
|
|
82
|
+
| 항목 | Web | Native |
|
|
83
|
+
| --- | --- | --- |
|
|
84
|
+
| 알림 | `role="status"` + 숨긴 문구 | 접근성 요소 하나(`accessibilityLabel`), Android polite live region, iOS는 나타날 때 `announceForAccessibilityWithOptions(queue)` |
|
|
85
|
+
| 움직임 | CSS keyframes(`hjm-typing-pulse`) | `Animated.loop`(native driver) |
|
|
86
|
+
|
|
87
|
+
## 근거
|
|
88
|
+
|
|
89
|
+
- 공통 입력 중 표시: 2026-10-18 번뚝 DM. Web·Native가 각자 점(●●●)과 문구 말풍선을 만들었다(Web `role="status"` 문구, Native 별도 컴포넌트와 Animated 깜박임). 공통 타임라인 구조는 HJM 소유라는 2026-10-15 원칙에 따라 공개 조각으로 옮겼다.
|
|
@@ -18,12 +18,13 @@ AuthScreenLayout을 사용해 로그인 흐름을 구성한다. 제품이 데이
|
|
|
18
18
|
|
|
19
19
|
```text
|
|
20
20
|
host: 남은 높이·safe area·키보드
|
|
21
|
-
└─ 히어로 → 제공자 카드 → 하단 동의
|
|
21
|
+
└─ (머리 띠: [뒤로/닫기] 로그인) → 히어로 → 제공자 카드 → 하단 동의
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
| 영역 | 컴포넌트 | 위치 | 크기·간격 |
|
|
25
25
|
| --- | --- | --- | --- |
|
|
26
26
|
| 바깥 틀 | AuthScreenLayout | route 본문 | [API 배치 규칙](../components/auth-screen-layout.md#배치), host 남은 높이 |
|
|
27
|
+
| 머리(선택) | AuthScreenLayout `title`·`exit`(1.31.0) | 맨 위 고정, 화면 가장자리까지 | ScreenLayout 가운데 머리 띠(최소 52). 바깥에 TopBar를 따로 얹지 않는다 |
|
|
27
28
|
| 내용 | 공개 슬롯 | 히어로 → 제공자 카드 → 하단 동의 | 화면 recipe의 sectionGap·itemGap; 슬롯 안은 각 지침 토큰 |
|
|
28
29
|
| 상태 | pendingLabel 또는 main 안 Notice | 제공자 카드 내부 | 카드 크기를 유지하고 동의 고지를 남긴다 |
|
|
29
30
|
|
|
@@ -33,6 +34,7 @@ host: 남은 높이·safe area·키보드
|
|
|
33
34
|
| --- | --- | --- | --- |
|
|
34
35
|
| 작업 | AuthScreenLayout 공개 행동 슬롯 | 제공자 버튼에는 이름만; 로그인 중 카드 중앙 스피너 하나 | 같은 표면에 경쟁하는 primary 하나만 |
|
|
35
36
|
| 복구 | Button·secondary | 오류 근처 | 재시도할 대상과 범위를 표시 |
|
|
37
|
+
| 나가기 | AuthScreenLayout `exit`(아이콘 뒤로/닫기) | 머리 띠 시작 끝 | 0~1. 로그인 진행 중에는 제품이 `disabled` |
|
|
36
38
|
|
|
37
39
|
## 상태
|
|
38
40
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
6
|
- 적용: 구성 API 지침 참조
|
|
7
|
-
- 검토일: 2026-10-
|
|
7
|
+
- 검토일: 2026-10-18
|
|
8
8
|
- 근거: [반복 화면 조합](../../screen-patterns.md), Web·Native `src/screen-flows.tsx`(`ProfileScreen`·`EditorScreen`), 예제 `showcase/*/screen-flow-previews.tsx`(`AccountFlowPreview`)·`saved-profile-previews.tsx`(`ProfileEditFields`), 기본 얼굴 `showcase/web/src/patterns/ProfileStudio.previews.tsx`·`showcase/native/src/profile-face-preview.tsx`·`showcase/shared/profile-studio.ts`. 2026-10-06 사용자 승인으로 실험 `공통 화면/프로필`을 배포하면서 같은 프로필 수정을 직접 조립으로 보이던 배포 `화면/프로필 편집`과 합쳤다(API 기반 우선, Web id `patterns-profile-studio` 보존, [승인 기록](../../../../../docs/STORYBOOK_NAVIGATION.md#21-2026-10-06-전체-승격과-규격-확정))
|
|
9
9
|
- 스토리북: `배포/화면/계정/프로필`
|
|
10
10
|
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
| 바깥 틀 | ProfileScreen · EditorScreen(둘 다 ScreenLayout) | route 본문, host가 남은 높이·safe area·키보드를 준다 | 폭 최대 720, 바깥 padding `spacing.md` 16([ScreenLayout 배치](../components/screen-layout.md#배치)), 본문 스크롤 |
|
|
54
54
|
| 머리 | `title` + `actions`(IconButton ghost 계정 메뉴) | 맨 위, 고정 | 제목 열 최소 120 × 글자 배율 |
|
|
55
55
|
| 요약 | `summary`(제품) | 본문 맨 위 | 요약 안 배치는 제품 소유 |
|
|
56
|
-
| 수정 진입 | `edit` → Button ghost | 요약 아래 | 요약과 `spacing.md` 16 |
|
|
56
|
+
| 수정 진입 | `edit` → Button ghost | 요약 아래 | 요약과 `spacing.md` 16. 프로필 카드 안에 두는 제품은 `editPlacement="summary"`(ProfileSummary 행동 줄 맨 앞, `secondary` `small`, 1.31.0) |
|
|
57
57
|
| 게시물 | `children` > Stack `gap="md"` > 탭 Button 줄 + Grid `columns={{ compact: 3 }}` | 수정 아래 | 요약 묶음과 `spacing.xl` 24, 격자 간격 `spacing.xxs` |
|
|
58
58
|
| 계정 메뉴 | Sheet > ListRow, `footer` > Button ghost 로그아웃 → AlertDialog | 오버레이 | footer 고정 |
|
|
59
59
|
| 수정 화면 | EditorScreen `submitPlacement="footer"` > 사진·이름·소개 필드 | 같은 route에서 보기 대신 | footer: 초안 상태 → 저장 primary, 사이 `spacing.sm` 12 |
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
|
|
78
78
|
| 행동 | 컴포넌트·tone | 위치 | 개수·순서 |
|
|
79
79
|
| --- | --- | --- | --- |
|
|
80
|
-
| 프로필 수정 | `edit` → Button ghost | 요약 아래 | 1 |
|
|
80
|
+
| 프로필 수정 | `edit` → Button ghost(`editPlacement="summary"`면 ProfileSummary 안 `secondary` `small`) | 요약 아래(또는 요약 카드 안 행동 줄 맨 앞) | 1 |
|
|
81
81
|
| 계정 메뉴 | IconButton ghost(접근성 이름 "계정 메뉴") | 머리 끝(`actions`) | 1. 로그아웃·연결 계정은 메뉴 안 |
|
|
82
82
|
| 게시물·저장됨 전환 | [SegmentedControl](../components/segmented-control.md)(label "프로필 보기") | 게시물 영역 맨 위 | 2개 항목, 단일 선택. 선택 상태를 ghost Button으로 흉내 내지 않는다 |
|
|
83
83
|
| 게시물 열기 | 사진 칸 전체 | 격자 | 칸마다 1. 상세는 ScreenLayout + `exit` 뒤로 아이콘 |
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
6
|
- 적용: 구성 API 지침 참조
|
|
7
|
-
- 검토일: 2026-10-
|
|
7
|
+
- 검토일: 2026-10-18
|
|
8
8
|
- 근거: [반복 화면 조합](../../screen-patterns.md); 공통 API와 실제 Web·Native 예제의 슬롯·상태를 대조해 중복 조립 방지. 2026-10-06 사용자 승인으로 스토리북 배포(이전 `실험/화면/기본 흐름/작성과 수정`, [승인 기록](../../../../../docs/STORYBOOK_NAVIGATION.md#21-2026-10-06-전체-승격과-규격-확정))
|
|
9
9
|
- 스토리북: `배포/화면/콘텐츠/작성과 수정`
|
|
10
10
|
|
|
@@ -31,7 +31,7 @@ host: 남은 높이·safe area·키보드
|
|
|
31
31
|
|
|
32
32
|
| 행동 | 컴포넌트·tone | 위치 | 개수·순서 |
|
|
33
33
|
| --- | --- | --- | --- |
|
|
34
|
-
| 작업 | EditorScreen 공개 행동 슬롯 | 취소는
|
|
34
|
+
| 작업 | EditorScreen 공개 행동 슬롯 | 취소는 헤더(단계형은 두 번째 단계부터 `stepBack` 뒤로); 저장은 footer; 수정한 채 이탈하면 확인 | 같은 표면에 경쟁하는 primary 하나만 |
|
|
35
35
|
| 복구 | Button·secondary | 오류 근처 | 재시도할 대상과 범위를 표시 |
|
|
36
36
|
|
|
37
37
|
## 상태
|
|
@@ -54,6 +54,17 @@ host: 남은 높이·safe area·키보드
|
|
|
54
54
|
| 저장 성공 | 제출 snapshot을 saved로 갱신 | 요청 후 새로 쓴 내용까지 saved로 처리하지 않는다. draftStatus는 실제 임시 저장 성공 때만 표시한다 |
|
|
55
55
|
| 브라우저·OS 뒤로 | 제품 router의 이탈 가드 | EditorScreen cancel의 discard와 같은 제품 결정을 공유한다 |
|
|
56
56
|
|
|
57
|
+
### 단계형 작성(1.31.0)
|
|
58
|
+
|
|
59
|
+
색 → 이모지 → 글처럼 단계가 나뉜 작성은 같은 EditorScreen 안에서 단계를 바꾼다. 앞 단계로 돌아가는 길은 둘이다.
|
|
60
|
+
|
|
61
|
+
| 행동 | 연결 | 규칙 |
|
|
62
|
+
| --- | --- | --- |
|
|
63
|
+
| 헤더 뒤로 | EditorScreen `stepBack`(두 번째 단계부터) | 헤더 시작 끝이 × 대신 뒤로 화살표가 된다. 단계를 되돌릴 뿐 이탈이 아니라 `discard` 확인을 띄우지 않는다. 첫 단계에서는 `stepBack`을 빼 × 닫기(`cancel`·`discard`)로 돌아간다. 저장 중에는 잠긴다 |
|
|
64
|
+
| 지난 단계 누르기 | 본문 맨 위 [Steps](../components/steps.md) `onStepPress` | 커서 앞 단계만 버튼이다. 현재·다음 단계는 누를 수 없다(검증을 건너뛰지 않는다). 제출 중처럼 흐름이 잠긴 동안은 `onStepPress`를 빼면 모두 표시 전용이 된다 |
|
|
65
|
+
|
|
66
|
+
2026-10-18 spint 작성 화면이 이 두 행동 때문에 EditorScreen 머리를 제품 TopBar로 바꾸고 단계 표시를 직접 그렸다.
|
|
67
|
+
|
|
57
68
|
본문이 ready가 아닌 최초 조회·오류·제한 상태에서는 헤더/하단 어느 위치의 저장도 비활성이다. 실패한 저장은
|
|
58
69
|
본문을 오류 화면으로 교체하지 않고 위 표처럼 ready + notice로 유지한다.
|
|
59
70
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
6
|
- 적용: 구성 API 지침 참조
|
|
7
|
-
- 검토일: 2026-10-
|
|
7
|
+
- 검토일: 2026-10-18
|
|
8
8
|
- 근거: [반복 화면 조합](../../screen-patterns.md); 공통 API와 실제 Web·Native 예제의 슬롯·상태를 대조해 중복 조립 방지. 2026-10-06 사용자 승인으로 스토리북 배포(이전 `실험/화면/기본 흐름/신고와 차단`, [승인 기록](../../../../../docs/STORYBOOK_NAVIGATION.md#21-2026-10-06-전체-승격과-규격-확정))
|
|
9
9
|
- 스토리북: `배포/화면/소통/신고와 차단`
|
|
10
10
|
|
|
@@ -32,7 +32,7 @@ host: 남은 높이·safe area·키보드
|
|
|
32
32
|
| 행동 | 컴포넌트·tone | 위치 | 개수·순서 |
|
|
33
33
|
| --- | --- | --- | --- |
|
|
34
34
|
| 닫기 | ScreenLayout `exit` `kind="close"` | 헤더 시작 끝 아이콘 버튼 | 1. 신고하지 않고 화면을 닫는다 |
|
|
35
|
-
| 작업 | ModerationScreen 공개 행동 슬롯 | 신고는 footer; 차단은 별도 확인 후
|
|
35
|
+
| 작업 | ModerationScreen 공개 행동 슬롯 | 신고는 footer; 차단은 별도 확인 후 실행. 운영자 검토(`variant="review"`)는 결정 버튼을 footer에 세로로 쌓는다 | 같은 표면에 경쟁하는 primary 하나만 |
|
|
36
36
|
| 복구 | Button·secondary | 오류 근처 | 재시도할 대상과 범위를 표시 |
|
|
37
37
|
|
|
38
38
|
## 상태
|
|
@@ -55,11 +55,39 @@ host: 남은 높이·safe area·키보드
|
|
|
55
55
|
| 차단 실패 | AlertDialog 유지 | Promise 실패를 전달한다. 확인창을 먼저 닫고 성공 처리하지 않는다 |
|
|
56
56
|
| 대상 변경 | 대상 id와 초안·요청 묶음 갱신 | 이전 대상의 늦은 응답이 새 대상 상태를 덮지 않게 한다 |
|
|
57
57
|
|
|
58
|
+
### 편지·카드·Sheet 안에서 신고(1.31.0)
|
|
59
|
+
|
|
60
|
+
신고가 별도 route가 아니라 편지 아래에 펼쳐지거나 Sheet 안에 열리면 [ModerationForm](../components/moderation-screen.md#moderationform-화면-틀-없는-신고-폼)을 쓴다.
|
|
61
|
+
ModerationScreen과 같은 사유 선택·추가 설명·신고/차단 버튼과 규칙을 화면 머리·바깥 여백 없이 그린다.
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
편지(제품 Surface)
|
|
65
|
+
└─ [신고] 제목(선택) → 사유 선택 → 추가 설명 → [신고하기] → [차단] → [취소]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
| 행동 | 연결 | 규칙 |
|
|
69
|
+
| --- | --- | --- |
|
|
70
|
+
| 펼친 신고 접기 | `cancel` → 마지막 ghost 버튼 | Sheet 안에서는 Sheet 닫기가 있으므로 생략 가능 |
|
|
71
|
+
| 제목 | `title`(구성 제목 `level3`) | 제목 줄이 있는 Sheet·Dialog 안에서는 생략한다 |
|
|
72
|
+
| 화면 틀 | ModerationScreen에 `contentInset="none"`·`scroll="content"`를 주어 끄지 않는다 | 머리 띠와 footer 표면이 남는다 |
|
|
73
|
+
|
|
74
|
+
### 운영자 검토(1.31.0)
|
|
75
|
+
|
|
76
|
+
신고·이의 신청 처리 화면은 ModerationScreen `variant="review"`다. 신고된 내용(`children`) → 처리 사유 자유 입력 → 결정 버튼(기각·숨기기·유지·번복 등, 문구는 제품) 순이다.
|
|
77
|
+
|
|
78
|
+
| 상황 | 연결 | 유지·복구 |
|
|
79
|
+
| --- | --- | --- |
|
|
80
|
+
| 사유 미입력 | 모든 결정 비활성(`decisionReason.required` 기본 `true`) | 공백만 있는 사유는 입력하지 않은 것으로 본다 |
|
|
81
|
+
| 되돌리기 어려운 결정 | 결정의 `confirmation`(AlertDialog `confirm`, 보통 `tone: "danger"`) | 버튼은 확인창만 열고 `onConfirm`이 실행한다. 실패는 Promise로 넘겨 확인창을 유지한다 |
|
|
82
|
+
| 결정 진행 중 | 그 결정 `pending` | 다른 결정과 사유 입력을 HJM이 잠근다 |
|
|
83
|
+
| 이미 처리됨 | `resolution`(예: Notice `success` + 처리 사유) | 사유 입력과 결정 버튼 자리를 대체한다 |
|
|
84
|
+
| 처리 결과·충돌 | `notice` 또는 `children` 안 Notice | 서버 확정 후에만 성공을 표시한다 |
|
|
85
|
+
|
|
58
86
|
## 사용하는 지침
|
|
59
87
|
|
|
60
88
|
| 지침 | 쓰는 곳 |
|
|
61
89
|
| --- | --- |
|
|
62
|
-
| [ModerationScreen](../components/moderation-screen.md) | 필수 props·슬롯·플랫폼
|
|
90
|
+
| [ModerationScreen](../components/moderation-screen.md) | 필수 props·슬롯·플랫폼 차이, 운영자 검토 `variant="review"`, 화면 틀 없는 `ModerationForm` |
|
|
63
91
|
| [Button](../components/button.md) | 동작·로딩·보조 행동 |
|
|
64
92
|
| [ScreenLayout](../components/screen-layout.md) | 화면 높이·본문 교체·스크롤 소유 |
|
|
65
93
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hjmds/design-contracts",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.31.0",
|
|
4
4
|
"description": "Renderer-neutral design contracts, tokens, recipes, and behaviors shared by HJM products.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -801,6 +801,7 @@
|
|
|
801
801
|
},
|
|
802
802
|
"./conversation-row": {
|
|
803
803
|
"types": "./dist/conversation-row.d.ts",
|
|
804
|
+
"react-native": "./dist/conversation-row.js",
|
|
804
805
|
"import": "./dist/conversation-row.js",
|
|
805
806
|
"default": "./dist/conversation-row.js"
|
|
806
807
|
}
|