@hjmds/design-contracts 1.26.1 → 1.27.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/agreement.d.ts +1 -0
- package/dist/agreement.d.ts.map +1 -1
- package/dist/agreement.js +2 -1
- package/dist/agreement.js.map +1 -1
- package/dist/auth-screen.d.ts +1 -1
- package/dist/behaviors.d.ts +1 -1
- package/dist/calendar.d.ts +1 -0
- package/dist/calendar.d.ts.map +1 -1
- package/dist/calendar.js +4 -1
- package/dist/calendar.js.map +1 -1
- package/dist/catalog.d.ts +78 -30
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +10 -5
- package/dist/catalog.js.map +1 -1
- package/dist/chart.d.ts +2 -0
- package/dist/chart.d.ts.map +1 -1
- package/dist/chart.js +1 -1
- package/dist/chart.js.map +1 -1
- package/dist/component-definitions.d.ts +1 -0
- package/dist/component-definitions.d.ts.map +1 -1
- package/dist/component-definitions.js +1 -0
- package/dist/component-definitions.js.map +1 -1
- package/dist/component-recipes.d.ts +53 -6
- package/dist/component-recipes.d.ts.map +1 -1
- package/dist/component-recipes.js +64 -10
- package/dist/component-recipes.js.map +1 -1
- package/dist/data-table.d.ts +11 -0
- package/dist/data-table.d.ts.map +1 -1
- package/dist/data-table.js +5 -0
- package/dist/data-table.js.map +1 -1
- package/dist/description-list.d.ts +3 -0
- package/dist/description-list.d.ts.map +1 -1
- package/dist/description-list.js +5 -1
- package/dist/description-list.js.map +1 -1
- package/dist/design-profile-layout.d.ts +28 -0
- package/dist/design-profile-layout.d.ts.map +1 -1
- package/dist/design-profile-layout.js +27 -3
- package/dist/design-profile-layout.js.map +1 -1
- package/dist/design-profile.d.ts.map +1 -1
- package/dist/design-profile.js +40 -8
- package/dist/design-profile.js.map +1 -1
- package/dist/field-group.d.ts +13 -0
- package/dist/field-group.d.ts.map +1 -1
- package/dist/field-group.js +17 -2
- package/dist/field-group.js.map +1 -1
- package/dist/foundations.d.ts +24 -11
- package/dist/foundations.d.ts.map +1 -1
- package/dist/foundations.js +40 -7
- package/dist/foundations.js.map +1 -1
- package/dist/heading.d.ts +5 -5
- package/dist/image-choice.d.ts +23 -0
- package/dist/image-choice.d.ts.map +1 -0
- package/dist/image-choice.js +26 -0
- package/dist/image-choice.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/masonry.d.ts +8 -0
- package/dist/masonry.d.ts.map +1 -1
- package/dist/masonry.js +12 -1
- package/dist/masonry.js.map +1 -1
- package/dist/number-field.d.ts +2 -2
- package/dist/number-field.d.ts.map +1 -1
- package/dist/number-field.js +4 -2
- package/dist/number-field.js.map +1 -1
- package/dist/qr-code-recipe.d.ts +1 -0
- package/dist/qr-code-recipe.d.ts.map +1 -1
- package/dist/qr-code-recipe.js +3 -1
- package/dist/qr-code-recipe.js.map +1 -1
- package/dist/recipes.d.ts +1 -1
- package/dist/recipes.d.ts.map +1 -1
- package/dist/recipes.js +1 -1
- package/dist/recipes.js.map +1 -1
- package/dist/result.d.ts +9 -0
- package/dist/result.d.ts.map +1 -1
- package/dist/result.js +5 -0
- package/dist/result.js.map +1 -1
- package/dist/screen-patterns.d.ts +139 -2
- package/dist/screen-patterns.d.ts.map +1 -1
- package/dist/screen-patterns.js +140 -1
- package/dist/screen-patterns.js.map +1 -1
- package/dist/sheet.d.ts +15 -1
- package/dist/sheet.d.ts.map +1 -1
- package/dist/sheet.js +20 -1
- package/dist/sheet.js.map +1 -1
- package/dist/showcase.d.ts +27 -27
- package/dist/showcase.js +27 -27
- package/dist/showcase.js.map +1 -1
- package/dist/tag.d.ts +10 -2
- package/dist/tag.d.ts.map +1 -1
- package/dist/tag.js +3 -2
- package/dist/tag.js.map +1 -1
- package/dist/tags-input.d.ts +6 -0
- package/dist/tags-input.d.ts.map +1 -1
- package/dist/tags-input.js +3 -1
- package/dist/tags-input.js.map +1 -1
- package/dist/text-formats.d.ts +2 -2
- package/dist/top.d.ts +2 -2
- package/dist/transfer-list.d.ts +1 -1
- package/dist/transfer-list.d.ts.map +1 -1
- package/dist/transfer-list.js +2 -1
- package/dist/transfer-list.js.map +1 -1
- package/dist/upload-item.d.ts +1 -10
- package/dist/upload-item.d.ts.map +1 -1
- package/dist/upload-item.js +1 -2
- package/dist/upload-item.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/activity-chip.md +4 -3
- package/docs/catalog-freeze.json +5 -2
- package/docs/chart.md +1 -1
- package/docs/consumer-policy.md +13 -6
- package/docs/description-list.md +4 -0
- package/docs/design-profile.md +28 -2
- package/docs/font-roles.md +1 -1
- package/docs/generated/component-maturity.md +5 -4
- package/docs/generated/renderer-evidence.json +92 -6
- package/docs/generated/renderer-evidence.md +5 -3
- package/docs/generated/showcase-manifest.json +49 -1
- package/docs/gravity-letters.md +7 -2
- package/docs/masonry.md +4 -2
- package/docs/screen-patterns.md +5 -2
- package/docs/showcase.md +7 -9
- package/docs/stable-promotion.md +13 -1
- package/docs/usage/README.md +40 -10
- package/docs/usage/SELECTION.md +30 -4
- package/docs/usage/STANDARD.md +11 -2
- package/docs/usage/components/account-switcher.md +98 -0
- package/docs/usage/components/activity-chip.md +4 -4
- package/docs/usage/components/badge.md +1 -1
- package/docs/usage/components/bezier-editor.md +99 -0
- package/docs/usage/components/bottom-cta.md +2 -1
- package/docs/usage/components/button.md +26 -12
- package/docs/usage/components/carousel.md +4 -4
- package/docs/usage/components/chart.md +1 -0
- package/docs/usage/components/chat-message.md +18 -12
- package/docs/usage/components/chat-screen.md +6 -3
- package/docs/usage/components/cohort-retention-table.md +83 -0
- package/docs/usage/components/collapsible.md +7 -2
- package/docs/usage/components/comment-thread-row.md +102 -0
- package/docs/usage/components/comment-thread-screen.md +27 -13
- package/docs/usage/components/composition-layout.md +1 -0
- package/docs/usage/components/context-menu.md +32 -15
- package/docs/usage/components/conversation-row.md +11 -4
- package/docs/usage/components/conversion-funnel.md +85 -0
- package/docs/usage/components/correlation-matrix.md +80 -0
- package/docs/usage/components/data-table.md +4 -0
- package/docs/usage/components/description-list.md +2 -1
- package/docs/usage/components/editor-screen.md +9 -5
- package/docs/usage/components/effect-surface.md +4 -2
- package/docs/usage/components/empty-state.md +2 -2
- package/docs/usage/components/event-attendance-card.md +104 -0
- package/docs/usage/components/expandable-search.md +105 -0
- package/docs/usage/components/file-picker.md +5 -0
- package/docs/usage/components/filter-recovery.md +97 -0
- package/docs/usage/components/follow-profile-card.md +100 -0
- package/docs/usage/components/heading.md +6 -2
- package/docs/usage/components/histogram-explorer.md +89 -0
- package/docs/usage/components/icon-button.md +18 -2
- package/docs/usage/components/icon-tile.md +12 -4
- package/docs/usage/components/image-choice-group.md +81 -0
- package/docs/usage/components/import-field-mapping.md +94 -0
- package/docs/usage/components/inline-edit.md +105 -0
- package/docs/usage/components/keyboard-avoidance-context.md +60 -0
- package/docs/usage/components/keyboard-avoiding.md +5 -1
- package/docs/usage/components/list-detail-screen.md +4 -4
- package/docs/usage/components/list.md +1 -1
- package/docs/usage/components/masonry.md +6 -7
- package/docs/usage/components/media-selection-screen.md +7 -5
- package/docs/usage/components/media-transport.md +104 -0
- package/docs/usage/components/message-composer.md +13 -3
- package/docs/usage/components/moderation-screen.md +5 -2
- package/docs/usage/components/notification-inbox-screen.md +3 -3
- package/docs/usage/components/notification-row.md +64 -8
- package/docs/usage/components/onboarding-screen.md +1 -1
- package/docs/usage/components/overview-screen.md +9 -3
- package/docs/usage/components/pagination.md +18 -3
- package/docs/usage/components/password-rules-field.md +90 -0
- package/docs/usage/components/permission-screen.md +1 -1
- package/docs/usage/components/photo-source-sheet.md +1 -1
- package/docs/usage/components/popover.md +6 -3
- package/docs/usage/components/pricing-choice.md +85 -0
- package/docs/usage/components/profile-summary.md +56 -8
- package/docs/usage/components/progress.md +3 -3
- package/docs/usage/components/qr-code.md +5 -9
- package/docs/usage/components/repeatable-field-group.md +92 -0
- package/docs/usage/components/reply-composer.md +83 -0
- package/docs/usage/components/reply-message.md +85 -0
- package/docs/usage/components/result.md +3 -3
- package/docs/usage/components/saved-items-screen.md +7 -5
- package/docs/usage/components/screen-layout.md +21 -10
- package/docs/usage/components/search-field.md +1 -1
- package/docs/usage/components/section.md +2 -2
- package/docs/usage/components/selection-action-bar.md +89 -0
- package/docs/usage/components/settings-screen.md +13 -11
- package/docs/usage/components/sheet.md +19 -7
- package/docs/usage/components/shortcut-recorder.md +77 -0
- package/docs/usage/components/split-action.md +94 -0
- package/docs/usage/components/streaming-answer.md +94 -0
- package/docs/usage/components/switch.md +6 -2
- package/docs/usage/components/table-column-settings.md +88 -0
- package/docs/usage/components/target-summary.md +79 -0
- package/docs/usage/components/text.md +11 -5
- package/docs/usage/components/toggle-feedback-button.md +94 -0
- package/docs/usage/components/top-bar.md +8 -12
- package/docs/usage/components/transfer-task.md +87 -0
- package/docs/usage/compositions/action-recovery-optimistic.md +18 -14
- package/docs/usage/compositions/action-recovery-save.md +18 -14
- package/docs/usage/compositions/action-recovery-undo.md +18 -14
- package/docs/usage/compositions/activity-status.md +1 -1
- package/docs/usage/compositions/adaptive-content.md +2 -1
- package/docs/usage/compositions/collection-detail.md +6 -5
- package/docs/usage/compositions/collection-editing.md +13 -6
- package/docs/usage/compositions/command-records.md +5 -4
- package/docs/usage/compositions/communication.md +7 -5
- package/docs/usage/compositions/compound-controls.md +7 -3
- package/docs/usage/compositions/content-transition-comparison.md +10 -5
- package/docs/usage/compositions/data-layouts.md +12 -16
- package/docs/usage/compositions/data-workflows.md +7 -4
- package/docs/usage/compositions/date-time-selection.md +5 -5
- package/docs/usage/compositions/design-profile-comparison.md +22 -6
- package/docs/usage/compositions/disclosure.md +14 -9
- package/docs/usage/compositions/document-resource.md +1 -1
- package/docs/usage/compositions/environment-matrix.md +16 -12
- package/docs/usage/compositions/expo-interactions.md +9 -8
- package/docs/usage/compositions/family-drawer.md +9 -5
- package/docs/usage/compositions/field-group.md +7 -3
- package/docs/usage/compositions/interaction-adapters.md +11 -9
- package/docs/usage/compositions/interaction-flow-apply.md +17 -15
- package/docs/usage/compositions/interaction-flow-search.md +11 -7
- package/docs/usage/compositions/live-list.md +12 -8
- package/docs/usage/compositions/navigation-bar-collection.md +8 -3
- package/docs/usage/compositions/optional-motion.md +2 -2
- package/docs/usage/compositions/paper-surface.md +11 -6
- package/docs/usage/compositions/purpose-input-comment.md +10 -4
- package/docs/usage/compositions/purpose-input-message.md +10 -4
- package/docs/usage/compositions/reference-first.md +4 -4
- package/docs/usage/compositions/reference-review.md +4 -4
- package/docs/usage/compositions/reference-settings.md +4 -4
- package/docs/usage/compositions/selection-motion.md +2 -1
- package/docs/usage/compositions/social-compositions.md +7 -6
- package/docs/usage/compositions/stea-event-ticket.md +2 -4
- package/docs/usage/compositions/stea-order-progress.md +19 -21
- package/docs/usage/compositions/stea-pixel-empty.md +26 -26
- package/docs/usage/compositions/task-controls.md +7 -2
- package/docs/usage/compositions/texture-comparison.md +5 -5
- package/docs/usage/compositions/toast-layout.md +7 -3
- package/docs/usage/compositions/toggle-feedback.md +1 -1
- package/docs/usage/compositions/visual-foundations.md +10 -5
- package/docs/usage/compositions/web-additions.md +5 -1
- package/docs/usage/screens/common-chat.md +5 -3
- package/docs/usage/screens/common-comments.md +14 -9
- package/docs/usage/screens/common-conversation-list.md +109 -0
- package/docs/usage/screens/common-inbox.md +5 -3
- package/docs/usage/screens/common-login.md +7 -4
- package/docs/usage/screens/common-profile.md +16 -12
- package/docs/usage/screens/common-saved.md +12 -8
- package/docs/usage/screens/common-search.md +16 -8
- package/docs/usage/screens/common-settings.md +12 -11
- package/docs/usage/screens/common-shell.md +12 -10
- package/docs/usage/screens/dashboard.md +59 -56
- package/docs/usage/screens/discovery-gallery.md +18 -9
- package/docs/usage/screens/flow-collection.md +10 -6
- package/docs/usage/screens/flow-editor.md +9 -6
- package/docs/usage/screens/flow-media.md +12 -7
- package/docs/usage/screens/flow-moderation.md +9 -3
- package/docs/usage/screens/flow-onboarding.md +13 -8
- package/docs/usage/screens/flow-permission.md +5 -3
- package/docs/usage/screens/landing.md +20 -14
- package/docs/usage/screens/mockup-studio.md +100 -88
- package/docs/usage/screens/notification-settings.md +9 -7
- package/docs/usage/screens/product-bento.md +22 -10
- package/docs/usage/screens/reference-comparison.md +2 -2
- package/docs/usage/tokens/font-roles.md +18 -2
- package/docs/usage/tokens/typography.md +22 -11
- package/package.json +7 -1
|
@@ -28,27 +28,28 @@
|
|
|
28
28
|
## 배치
|
|
29
29
|
|
|
30
30
|
```text
|
|
31
|
-
제목/설명
|
|
31
|
+
제목/설명
|
|
32
32
|
가로 목록: [제목/설명 → 기록 메모 → 상세 보기] × 안정 ID
|
|
33
33
|
목록 밖 끝쪽: 이전 기록 / 다음 기록
|
|
34
|
-
상세: 제목/닫기 → 상세 메모
|
|
34
|
+
상세: 제목/닫기 → 상세 메모
|
|
35
35
|
합성 예제 안내
|
|
36
|
+
(미리보기 도구: 다음 테마 — 예제 전용, 구성 밖)
|
|
36
37
|
```
|
|
37
38
|
|
|
38
39
|
| 영역 | 컴포넌트 | 위치 | 크기·간격 |
|
|
39
40
|
| --- | --- | --- | --- |
|
|
40
41
|
| 바깥 틀 | Container·Section·Stack | 세로 | gutter compact16, Stack spacing.md16 |
|
|
41
|
-
| 목록 | CollectionRail |
|
|
42
|
+
| 목록 | CollectionRail | 제목/설명 아래 | comfortable 최대360, 간격16·edgeHint24, 실제 viewport 측정 |
|
|
42
43
|
| 카드 | Card·TextField | 각각 listitem | Card recipe padding/표면과 Provider 테마 상속 |
|
|
43
44
|
| 상세 열기 | Button in Card.actions | 카드 본문 아래 | tone secondary, 카드 전체를 button으로 감싸지 않음 |
|
|
44
|
-
| 상세 | Dialog·
|
|
45
|
+
| 상세 | Dialog·TextField | 기존 modal portal/Native Modal | Dialog size/keyboard/safe-area contract |
|
|
45
46
|
|
|
46
47
|
## 흐름과 상태
|
|
47
48
|
|
|
48
49
|
1. 카드 메모를 작성하고 이전/다음·touch·Web 키보드로 탐색한다. 모든 카드의 ID/초안은 남는다.
|
|
49
50
|
2. 일부 보이는 카드의 입력에 초점을 주면 필요한 만큼 노출한다. 입력의 방향/Home/End 키를 목록이 가로채지 않는다.
|
|
50
51
|
3. 상세 보기를 열어 별도 메모를 작성한다. Dialog가 배경 잠금/닫기/초점 복귀를 소유한다.
|
|
51
|
-
4.
|
|
52
|
+
4. 닫고 다시 열어도 상세 초안이 남는다. 예제의 "다음 테마"는 구성 아래 "미리보기 도구" 묶음의 예제 전용 도구다. 눌러도 원문·초안이 유지되며, 테마 선택은 제품 화면 요소가 아니다.
|
|
52
53
|
|
|
53
54
|
| 상태 | 모습 | 포커스·알림 |
|
|
54
55
|
| --- | --- | --- |
|
|
@@ -30,15 +30,15 @@ Lucian 예제 전수 검토에서 재사용할 실익이 있는 다섯 작업을
|
|
|
30
30
|
|
|
31
31
|
```text
|
|
32
32
|
제목 편집 반복 입력 묶음 행동
|
|
33
|
-
|
|
34
|
-
[
|
|
33
|
+
라벨(caption) 이름 N개 선택
|
|
34
|
+
값(strong) [✎] [입력 ] [🗑] [보관] [해제]
|
|
35
35
|
↓ [사람 추가] [방금 작업 복구]
|
|
36
36
|
[입력]
|
|
37
37
|
[취소] [저장]
|
|
38
38
|
|
|
39
|
-
필터 완화: 자기 본문 영역 중앙 열 설정:
|
|
40
|
-
제목·설명 [✓ 이름
|
|
41
|
-
[주제 해제 · 실제 N개 보기] [✓ 점수]
|
|
39
|
+
필터 완화: 자기 본문 영역 중앙 열 설정: 그룹 라벨(Text strong) + 열마다 한 행
|
|
40
|
+
제목·설명 [✓ 이름 (고정)] [↑] [↓]
|
|
41
|
+
[주제 해제 · 실제 N개 보기] [✓ 점수] [↑] [↓]
|
|
42
42
|
실패 안내 제어된 실제 DataTable
|
|
43
43
|
```
|
|
44
44
|
|
|
@@ -46,8 +46,11 @@ Lucian 예제 전수 검토에서 재사용할 실익이 있는 다섯 작업을
|
|
|
46
46
|
| --- | --- | --- | --- |
|
|
47
47
|
| 바깥 틀 | 제품 화면 host | 기존 본문·시트·패널 안; host가 스크롤·safe area·키보드를 소유 | 기존 Container/ScreenLayout 규격 |
|
|
48
48
|
| 입력/행 | TextField, FieldGroup | 값과 같은 자리; 반복 행은 위→아래 | `collectionEditingRecipe.gap` = `md` |
|
|
49
|
-
|
|
|
49
|
+
| 제목 읽기 | Text caption muted(라벨) · Text strong(값) · IconButton(ghost, `edit`) | 라벨 위·값 아래, 수정 도구는 행 끝. IconButton label = `editLabel`, 저장·취소 뒤 포커스는 이 도구로 돌아온다 | 라벨–값 `spacing.xxs`, 값–도구 `spacing.sm` 12 |
|
|
50
|
+
| 행 삭제 | IconButton(ghost, `delete`) | 각 반복 입력 행 끝, 입력과 아래 끝 정렬. label = `removeLabel(id)`로 행 대상을 말한다([IconButton](../components/icon-button.md)) | 입력–도구 `spacing.xs` 8 |
|
|
51
|
+
| 행동 | Button | 입력 아래 취소→저장, 행 묶음 마지막 추가 | `collectionEditingRecipe.actionGap` = `sm`, 좁으면 줄바꿈 |
|
|
50
52
|
| 선택 바 | SelectionActionBar | 대상 목록 바로 아래 또는 제품 footer 슬롯 | 제품이 고정 위치 결정; 화면 전체 좌표를 새로 소유하지 않음 |
|
|
53
|
+
| 열 설정 행 | Checkbox · IconButton ×2 | 열마다 한 행: 보이기 Checkbox(남은 폭) → 앞으로·뒤로 IconButton(ghost, 위·아래 화살표). IconButton label = `earlierLabel`·`laterLabel` | 행 안 `spacing.xs` 8, 행 사이 `spacing.sm` 12. 그룹 라벨은 Web·Native 모두 HJM Text strong |
|
|
51
54
|
| 상태 | Text·Button | 해당 구성 영역 중앙 | 임의 상단 margin 없이 가로·세로 중앙 정렬 |
|
|
52
55
|
|
|
53
56
|
## 흐름과 상태
|
|
@@ -110,3 +113,7 @@ import { InlineEdit } from "@hjmds/react-native/collection-editing";
|
|
|
110
113
|
- `onAdd`가 반환한 ID와 새 field ID가 같아야 한다. 입력 값을 배열 index에 저장하지 않는다.
|
|
111
114
|
- 표 원본 descriptor의 pinned·width·sort를 보존한다. 설정 화면의 잠금은 서버 권한 검증을 대체하지 않는다.
|
|
112
115
|
- npm 1.21.0 API다. 소비 제품의 실제 설치 버전을 확인한다.
|
|
116
|
+
|
|
117
|
+
## 근거
|
|
118
|
+
|
|
119
|
+
- 2026-10-17 구성 리뷰: 반복 입력의 삭제가 행과 떨어진 전체 폭 ghost 텍스트 버튼이었고, 제목 편집은 라벨 없이 값 옆에 "제목 수정" 텍스트 버튼을 두었다. 그래서 두 행동을 행 끝 IconButton 도구로 바꾸고 읽기 상태에 라벨을 표시했다.
|
|
@@ -28,27 +28,28 @@
|
|
|
28
28
|
| CodeBlock | 선택 가능한 LTR 원문 | [코드 블록](../components/code-block.md) |
|
|
29
29
|
| ClipboardButton | Web 원문 복사와 성공/오류 callback | [코드 블록의 복사 슬롯](../components/code-block.md#최소-사용-예) |
|
|
30
30
|
| Button·Notice·Text | 갱신·진행·실패·원문 선택 안내 | [버튼](../components/button.md) · [알림](../components/notice.md) |
|
|
31
|
-
|
|
|
31
|
+
| 미리보기 도구(Showcase `PreviewTools`) | 테마 고르기와 결정적인 응답 도구. 제품 행동과 분리한 캡션·`small` 조작([선택 조립 규칙](../SELECTION.md#조립-규칙필수)) | — |
|
|
32
32
|
|
|
33
33
|
## 배치
|
|
34
34
|
|
|
35
35
|
```text
|
|
36
|
-
Section 제목/설명
|
|
36
|
+
Section 제목/설명
|
|
37
37
|
긴 줄 표시: 줄바꿈 / 가로 스크롤
|
|
38
38
|
명령 / 출력 탭 → 언어·복사 보조 행동 → 선택 가능한 원문
|
|
39
39
|
복사 실패 안내 / 닫기
|
|
40
40
|
갱신 진행 또는 원문을 유지한 실패 알림
|
|
41
41
|
표시 새로고침(주 행동) → 예제 응답 안내
|
|
42
|
-
|
|
42
|
+
미리보기 도구: 테마(SegmentedControl pills small) / 미리보기 응답 받기 / 다음 갱신 실패
|
|
43
43
|
```
|
|
44
44
|
|
|
45
45
|
| 영역 | 컴포넌트 | 위치 | 크기·간격 |
|
|
46
46
|
| --- | --- | --- | --- |
|
|
47
|
-
| 바깥 틀 | Container·Section·Stack | 세로 문서 흐름 | Container `gutter="compact"` 16, Stack `spacing.md` 16. Native ScrollView 위아래 `spacing.lg` 20 |
|
|
47
|
+
| 바깥 틀 | Container·Section·Stack | 세로 문서 흐름 | Web Container `size="reading"`, Container `gutter="compact"` 16, Stack `spacing.md` 16. Native ScrollView 위아래 `spacing.lg` 20 |
|
|
48
48
|
| 보기 선택 | SegmentedControl | 탭 목록 위 | `presentation="pills"`, 큰 글자에서 줄바꿈 |
|
|
49
49
|
| 패널 | TabPanel·CodeBlock | 탭 목록 아래 | dynamic 단일 패널. CodeBlock의 `radius.lg`·`spacing.md`·프로필 code font, 원문 LTR |
|
|
50
50
|
| 복사 | ClipboardButton | Web CodeBlock 머리 줄 끝 | `tone="secondary" size="small"`. Native는 원문 시스템 선택; 제품 host action이 있으면 같은 슬롯 |
|
|
51
51
|
| 갱신·복구 | Button·Notice | 원문 아래 | 기본 Button 높이 `control.buttonHeight.medium` 44; 진행 중 잠금, 이전 원문 유지 |
|
|
52
|
+
| 미리보기 도구 | 캡션 + SegmentedControl(`presentation="pills" size="small"`) + `small` ghost Button | 예제 안내 아래, 맨 끝 | 캡션과 조작 사이 `spacing.xs` 8, 조작 사이 `spacing.sm` 12. 제품에는 복사하지 않는다 |
|
|
52
53
|
|
|
53
54
|
## 흐름과 상태
|
|
54
55
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
## 언제 쓰나
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
검색 아이콘 버튼에서 검색 영역을 펼치거나 채팅의 실제 메시지를 선택해 답장을 전송할 때 쓴다. 이미 전체 화면으로 제공하는 검색에는 SearchScreen을 바로 쓴다. 입력 자동 높이·채팅 swipe 엔진·최근 검색 저장을 새로 만들지 않는다.
|
|
16
16
|
|
|
17
17
|
## 구성 요소
|
|
18
18
|
|
|
@@ -27,8 +27,9 @@
|
|
|
27
27
|
## 배치
|
|
28
28
|
|
|
29
29
|
```text
|
|
30
|
-
[
|
|
31
|
-
|
|
30
|
+
[🔍] ← 접힘: 영역 끝의 검색 IconButton
|
|
31
|
+
[✕] (SearchScreen 헤더 앞쪽 닫기 exit)
|
|
32
|
+
[기존 SearchScreen 검색어·제안·결과]
|
|
32
33
|
[오류: 검색 영역 중앙]
|
|
33
34
|
|
|
34
35
|
[실제 메시지·답장 동작]
|
|
@@ -40,7 +41,8 @@
|
|
|
40
41
|
| 영역 | 컴포넌트 | 위치 | 크기·간격 |
|
|
41
42
|
| --- | --- | --- | --- |
|
|
42
43
|
| 바깥 틀 | Stack | 검색·입력 영역 | sm/md |
|
|
43
|
-
|
|
|
44
|
+
| 펼침 | IconButton(ghost, 검색 아이콘) | 접힌 영역의 끝(오른쪽, RTL에서 왼쪽) | IconButton 기본 크기, label = `labels.open` |
|
|
45
|
+
| 닫기 | SearchScreen `exit`(close) | 펼친 검색 헤더 앞쪽 | 화면 exit 규격, label = `labels.cancel` |
|
|
44
46
|
| 검색 | SearchScreen | 펼친 본문 | 기존 검색 영역 구조 |
|
|
45
47
|
| 메시지 | ChatMessage | 기존 timeline | 기존 메시지 구조 |
|
|
46
48
|
| 입력 | MessageComposer | timeline 아래 | 기존 자동 높이 유지 |
|
|
@@ -93,7 +95,7 @@ import { ExpandableSearch, ReplyMessage, ReplyComposer } from "@hjmds/react-nati
|
|
|
93
95
|
|
|
94
96
|
| 항목 | Web | Native |
|
|
95
97
|
| --- | --- | --- |
|
|
96
|
-
| 검색 포커스 |
|
|
98
|
+
| 검색 포커스 | 펼치면 입력, 닫으면 검색 아이콘 버튼으로 복원 | 입력 focus·닫기 키보드 해제 |
|
|
97
99
|
| 답장 대안 | Alt+방향키 | 접근성 reply action |
|
|
98
100
|
| 시간 swipe | reply drag 대신 시간 표시 | 동일 |
|
|
99
101
|
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
| --- | --- | --- | --- |
|
|
62
62
|
| 바깥 틀 | Web 문서 스크롤 > `Container`. Native `ScrollView` > `Container` | 블록을 감싸는 제품 화면. 상단 안전 영역은 내비게이션 헤더(또는 [TopBar](../components/top-bar.md))가 맡는다 | 좌우 `Container gutter`: 폭 600 미만 `compact` 16, 이상 `regular` 20([화면 여백](../tokens/layout.md)). Native 위아래는 `contentContainerStyle` `paddingVertical: spacing.lg` 20 |
|
|
63
63
|
| 블록 | `Stack gap="xl"` | 바깥 틀 안, 본문 흐름 | 자식 사이 `spacing.xl` 24 |
|
|
64
|
-
| 소요 시간 | DurationField | 설명 아래 | NumberField 세 칸, 칸 사이 `spacing.md` 16.
|
|
64
|
+
| 소요 시간 | DurationField | 설명 아래 | NumberField 세 칸, 칸 사이 `spacing.md` 16. 세 칸이 모두 들어가면 한 줄(칸 최대 `fieldGroupRecipe.inline.maxWidth`), 아니면 세 칸 모두 세로([FieldGroup](field-group.md)) |
|
|
65
65
|
| 확인 | InlineConfirm | 트리거 자리 그대로 | 트리거와 확인 행동이 같은 자리, Button 높이 44, 질문·버튼 줄 사이와 두 버튼 사이 `spacing.sm` 12 |
|
|
66
66
|
| 반응 | ReactionPicker | 제목 아래 | `ghost` `pill` Button 묶음, 사이 `spacing.xs` 8, 넘치면 줄바꿈 |
|
|
67
67
|
| 알림 종 | NotificationBell | 블록 맨 위, 시작 쪽 정렬 | IconButton(기본 `medium` 44) + CounterBadge `floating`(끝·위 모서리) |
|
|
@@ -172,7 +172,7 @@ function CompoundBlocks() {
|
|
|
172
172
|
| 바깥 스크롤 | 문서 스크롤 | `ScrollView`(위아래 `spacing.lg`) |
|
|
173
173
|
| 종 아이콘 | `<Icon name>` | `<Icon descriptor renderGlyph>` |
|
|
174
174
|
| 확인 알림 | 포커스 이동 + Escape, 오류 `role="alert"` | iOS 명시 알림, Android live region, 오류 `accessibilityRole="alert"` |
|
|
175
|
-
| 소요 시간 칸 줄바꿈 |
|
|
175
|
+
| 소요 시간 칸 줄바꿈 | flex-basis 계산으로 측정 없이 전부-또는-세로 | 잰 행 폭으로 같은 기준 계산 |
|
|
176
176
|
|
|
177
177
|
## 함정
|
|
178
178
|
|
|
@@ -191,6 +191,10 @@ function CompoundBlocks() {
|
|
|
191
191
|
|
|
192
192
|
### 소요 시간의 하위 입력 그룹
|
|
193
193
|
|
|
194
|
-
`DurationField`는 `FieldGroup layout="inline"`으로 그룹 이름과 단위별 잠금을 연결하고, 각 값은 기존 NumberField로 편집한다. 좁은 영역에서는 시간·분·초 순서를
|
|
194
|
+
`DurationField`는 `FieldGroup layout="inline"`으로 그룹 이름과 단위별 잠금을 연결하고, 각 값은 기존 NumberField로 편집한다. 좁은 영역에서는 시간·분·초 순서를 유지한 채 세 칸 모두 세로로 쌓는다. Native의 보이는 라벨은 각 단위만, 접근성 이름은 그룹 이름과 단위를 함께 전달한다. 그룹이 잠기거나 사라진 뒤 도착한 이전 단위 callback은 값을 바꾸지 않는다. 총 초 단위 값·상한 보정은 기존 duration-field 계약이 소유한다.
|
|
195
195
|
|
|
196
196
|
2026-10-13 날짜 직접 입력과 반복되던 그룹 제목·입력 행을 FieldGroup과 공통 `fieldGroupRecipe`로 옮겼다. 자세한 배치 축은 [관련 입력 묶음](field-group.md)을 따른다.
|
|
197
|
+
|
|
198
|
+
## 근거
|
|
199
|
+
|
|
200
|
+
- 2026-10-17 구성 리뷰: 소요 시간 칸이 데스크톱에서 늘어나고 좁은 폭에서 한 칸만 다음 줄로 끊겨 FieldGroup recipe의 inline 규칙을 바꿨다.
|
|
@@ -28,21 +28,22 @@ Motion Primitives Transition Panel의 두 제공 예제를 실제 검토한 후
|
|
|
28
28
|
| OnboardingScreen | 이전·다음·마지막 완료와 진행 표시 | [안내 화면](../components/onboarding-screen.md) |
|
|
29
29
|
| TextField | 제품 상태에 보관한 같은 초안 | [텍스트 입력](../components/field.md) |
|
|
30
30
|
| SegmentedControl | 한 번에 하나의 전환 표현 선택 | [선택 입력](../components/segmented-control.md) |
|
|
31
|
-
|
|
|
31
|
+
| PreviewTools(`SegmentedControl presentation="pills"` 테마 10개, 실패 예약 Chip) | 예제 전용 비교 도구. 제품 행동처럼 보이지 않게 "미리보기 도구" 아래에 둔다 | [단일 선택](../components/segmented-control.md) |
|
|
32
|
+
| Button·Notice | 다시 비교·복구 결과 | [버튼](../components/button.md) · [알림](../components/notice.md) |
|
|
32
33
|
|
|
33
34
|
## 배치
|
|
34
35
|
|
|
35
36
|
```text
|
|
36
|
-
설명 →
|
|
37
|
+
설명 → 미리보기 도구(테마 pills, 단계 비교면 실패 예약) → [전환 표현] 보이는 이름 + pills(줄바꿈)
|
|
37
38
|
탭 비교: 탭 목록 → 현재 패널 → 제목/내용/같은 초안
|
|
38
39
|
단계 비교: 안내 제목/설명/진행 → 본문 전환/초안 → 고정 이전·다음·완료
|
|
39
|
-
마지막 단계: 실패
|
|
40
|
+
마지막 단계: 실패 알림 → 같은 완료로 재시도(예약은 미리보기 도구에서)
|
|
40
41
|
완료: 확인 알림 → 초안 → 다시 비교
|
|
41
42
|
```
|
|
42
43
|
|
|
43
44
|
| 영역 | 컴포넌트 | 위치 | 크기·간격 |
|
|
44
45
|
| --- | --- | --- | --- |
|
|
45
|
-
| 바깥 틀 | Stack·Native ScrollView | 세로, 비교 도구와 단계 viewport를 함께 스크롤 | `spacing.lg` 20 |
|
|
46
|
+
| 바깥 틀 | Stack·Native ScrollView, 스토리 `Container size="reading"` | 세로, 비교 도구와 단계 viewport를 함께 스크롤 | `spacing.lg` 20, 최대 폭 720 |
|
|
46
47
|
| 표현 선택 | SegmentedControl | 안내 아래 | 공개 `presentation="pills"`, 좁은 화면 줄바꿈 |
|
|
47
48
|
| 탭 본문 | TabPanel·ContentTransition·Stack | 탭 목록 아래 | `spacing.md` 16, 높이는 현재 내용 측정 |
|
|
48
49
|
| 단계 틀 | OnboardingScreen | 표현 선택 아래 | Web preview 70dvh/minHeight 360, Native preview 720. 이는 fixture viewport이며 제품은 실제 가용 높이 사용 |
|
|
@@ -53,7 +54,7 @@ Motion Primitives Transition Panel의 두 제공 예제를 실제 검토한 후
|
|
|
53
54
|
1. 초안을 입력하고 탭을 바꾼다. Tabs는 수동 활성화여서 Web 화살표는 포커스만 이동하고 Enter/Space로 선택한다.
|
|
54
55
|
2. 테마를 순회하거나 나타남·떠오름·옆으로·확대·즉시를 선택한다. `preset` 생략은 테마 기본값, 명시 값은 우선한다.
|
|
55
56
|
3. 단계별 완료 스토리에서 다음·이전으로 이동한다. 화면 전체를 key로 다시 마운트하지 않고 본문만 전환한다.
|
|
56
|
-
4.
|
|
57
|
+
4. 미리보기 도구의 "완료 실패 재현"을 켜고 마지막 단계에서 기록 확인을 누른다. 초안을 유지한 실패 알림 뒤 같은 완료를 다시 누른다.
|
|
57
58
|
5. 완료 시점의 확인 결과를 별도로 보관한다. 같은 예제의 탭 모드에서 초안을 수정해도 이미 확인한 결과는 바뀌지 않는다. 다시 비교하면 현재 초안을 유지한 첫 단계로 돌아가며 Web은 초안 입력에 초점을 옮긴다. 완료는 로컬 fixture이며 서버 저장·라우팅 완료로 안내하지 않는다.
|
|
58
59
|
|
|
59
60
|
| 상태 | 모습 | 포커스·알림 |
|
|
@@ -114,3 +115,7 @@ Canvas 바깥에 있어 다음 버튼에 도달할 수 없었다. Native 비교
|
|
|
114
115
|
추가해 도구와 viewport를 함께 내리며, OnboardingScreen의 내부 본문 scroll과 footer 소유권은
|
|
115
116
|
유지한다. viewport 축소로 실제 화면의 본문/행동 배치를 바꾸는 대안은 사용하지 않았다.
|
|
116
117
|
제품 host는 이 fixture 높이를 복사하지 않고 실제 가용 높이를 공급한다.
|
|
118
|
+
|
|
119
|
+
## 근거
|
|
120
|
+
|
|
121
|
+
- 2026-10-17 구성 리뷰: "다음 테마"와 실패 예약이 꽉 찬 폭 secondary 버튼이라 제품 행동처럼 보였고, 열 개 중 하나 고르기를 "다음" 버튼으로 흉내 냈다. 데스크톱에서는 입력·버튼이 약 950px로 늘어났다. 그래서 미리보기 도구와 읽기 폭으로 옮겼다. 단계 viewport의 높이 host는 제품 route 높이를 대신하는 스토리 fixture다(공개 `layoutStyle`은 높이를 받지 않는다).
|
|
@@ -35,7 +35,7 @@ VirtualList, 다른 기기로 넘길 링크는 QRCode다. 세 스토리(카드
|
|
|
35
35
|
## 배치
|
|
36
36
|
|
|
37
37
|
```text
|
|
38
|
-
카드 묶음 (Masonry, 2열) 가상 목록 (VirtualList) 공유 코드 (QRCode)
|
|
38
|
+
카드 묶음 (Masonry, 폰 2열) 가상 목록 (VirtualList) 공유 코드 (QRCode)
|
|
39
39
|
┌ 바깥 틀: 페이지 스크롤 ──────────┐ ┌ 바깥 틀: 스크롤 없음 ───────┐ ┌ 카드·시트 본문 ─┐
|
|
40
40
|
│←gutter→ Container ←gutter→ │ │←gutter→ Container │ │ ▓▓ ▓ ▓▓▓ │
|
|
41
41
|
│ ┌──── width = Container 안쪽 ─┐ │ │ ┌──── height = 남은 높이 ─┐ │ │ ▓ ▓▓▓ ▓ 192 │
|
|
@@ -54,8 +54,8 @@ VirtualList, 다른 기기로 넘길 링크는 QRCode다. 세 스토리(카드
|
|
|
54
54
|
| 영역 | 컴포넌트 | 위치 | 크기·간격 |
|
|
55
55
|
| --- | --- | --- | --- |
|
|
56
56
|
| 바깥 틀 | 카드 묶음: Web 문서 스크롤 > `Container`, Native `ScrollView` > `Container`. 가상 목록: `Container`만(바깥 세로 스크롤 없음). QR: 카드·시트 본문 | HJM 화면 골격이 소유. 상단 안전 영역은 내비게이션 헤더가 맡는다 | 좌우 `Container gutter`: 폭 600 미만 `compact` 16, 이상 `regular` 20([화면 여백](../tokens/layout.md)). Native ScrollView 위아래 `paddingVertical: spacing.lg` 20 |
|
|
57
|
-
| 카드 묶음 | Masonry | 본문 흐름 안, 페이지와 함께 스크롤 | `columns`
|
|
58
|
-
| 카드 | 제품 `renderItem` | 가장 짧은 열 아래 | 높이는 `getItemHeight`가
|
|
57
|
+
| 카드 묶음 | Masonry | 본문 흐름 안, 페이지와 함께 스크롤 | `width`·`columns` 생략: Masonry가 Container 안쪽 자리 폭을 재고 최소 열 폭 160으로 열 수를 정한다(402 폰 2열, 1200 데스크톱 6열). `gap`은 숫자(기본 12 = `spacing.sm`) |
|
|
58
|
+
| 카드 | 제품 `renderItem`(`Surface bordered padding="sm" layoutStyle={{ flex: 1 }}`) | 가장 짧은 열 아래 | 높이는 `getItemHeight`가 확정하고 카드가 항목 틀을 채운다, 안쪽 여백 `spacing.sm` 12 |
|
|
59
59
|
| 다음 페이지 | [LoadMore](../components/load-more.md) | Masonry 다음 형제, 같은 스크롤 | LoadMore 기본 |
|
|
60
60
|
| 가상 목록 | VirtualList | 고정 높이 상자, 목록 안 스크롤 | `height`는 고정 머리·하단 바를 뺀 남은 높이(스토리 400), `rowHeight` 64(예), `overscan` 기본 3 |
|
|
61
61
|
| QR | QRCode | 감싸는 레이아웃이 배치 | `size` 기본 192(모듈 수 정수배로 내림), quiet zone 4모듈 |
|
|
@@ -66,7 +66,7 @@ VirtualList, 다른 기기로 넘길 링크는 QRCode다. 세 스토리(카드
|
|
|
66
66
|
|
|
67
67
|
## 흐름과 상태
|
|
68
68
|
|
|
69
|
-
1. 카드 묶음:
|
|
69
|
+
1. 카드 묶음: Masonry가 자리 폭을 재고 열 수를 정한다. 화면은 각 항목 높이를 계산해 넘긴다. 읽기 순서는 열이 아니라 원래 순서다.
|
|
70
70
|
2. 가상 목록: 사용자가 목록 안에서 스크롤하면 보이는 범위와 앞뒤 `overscan` 행만 그린다.
|
|
71
71
|
3. 공유 코드: 카메라로 읽거나, 읽을 수 없으면 아래 대체 행동으로 같은 링크를 연다.
|
|
72
72
|
4. 데이터를 서버에서 받으면 첫 로드·다음 페이지의 진행·실패는 이 구성 바깥(제품 흐름·LoadMore)이 그린다.
|
|
@@ -91,7 +91,7 @@ import { Container, Text } from "@hjmds/react/layout";
|
|
|
91
91
|
import { spacing } from "@hjmds/design-contracts/foundations";
|
|
92
92
|
|
|
93
93
|
<Container size="content" gutter={gutter}>
|
|
94
|
-
<Masonry items={cards} keyExtractor={(c) => c.id}
|
|
94
|
+
<Masonry items={cards} keyExtractor={(c) => c.id} gap={spacing.sm} label={t("cards.label")}
|
|
95
95
|
getItemHeight={(c, itemWidth) => measureCard(c, itemWidth)}
|
|
96
96
|
renderItem={(c) => <Card title={c.title}>{c.body}</Card>} />
|
|
97
97
|
</Container>
|
|
@@ -106,8 +106,7 @@ import { spacing } from "@hjmds/design-contracts/foundations";
|
|
|
106
106
|
|
|
107
107
|
```tsx
|
|
108
108
|
// Native
|
|
109
|
-
import {
|
|
110
|
-
import { Linking, ScrollView, View, useWindowDimensions } from "react-native";
|
|
109
|
+
import { Linking, ScrollView, useWindowDimensions } from "react-native";
|
|
111
110
|
import { Masonry } from "@hjmds/react-native/masonry";
|
|
112
111
|
import { VirtualList } from "@hjmds/react-native/virtual-list";
|
|
113
112
|
import { QRCode } from "@hjmds/react-native/qr-code";
|
|
@@ -118,16 +117,13 @@ import { spacing } from "@hjmds/design-contracts/foundations";
|
|
|
118
117
|
import { resolveWindowClass } from "@hjmds/design-contracts/responsive";
|
|
119
118
|
|
|
120
119
|
const { width } = useWindowDimensions();
|
|
121
|
-
const [measuredWidth, setMeasuredWidth] = useState(0);
|
|
122
120
|
const gutter = resolveWindowClass(width) === "compact" ? "compact" : "regular";
|
|
123
121
|
|
|
124
122
|
<ScrollView contentContainerStyle={{ paddingVertical: spacing.lg }}>
|
|
125
123
|
<Container size="content" gutter={gutter}>
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
renderItem={(c) => <Card title={c.title}>{c.body}</Card>} /> : null}
|
|
130
|
-
</View>
|
|
124
|
+
<Masonry items={cards} keyExtractor={(c) => c.id} gap={spacing.sm}
|
|
125
|
+
label={t("cards.label")} getItemHeight={(c, itemWidth) => measureCard(c, itemWidth)}
|
|
126
|
+
renderItem={(c) => <Card title={c.title}>{c.body}</Card>} />
|
|
131
127
|
</Container>
|
|
132
128
|
</ScrollView>
|
|
133
129
|
|
|
@@ -140,20 +136,20 @@ const gutter = resolveWindowClass(width) === "compact" ? "compact" : "regular";
|
|
|
140
136
|
fallback={<Button onPress={() => void Linking.openURL(shareUrl)}>{t("share.open")}</Button>} />
|
|
141
137
|
```
|
|
142
138
|
|
|
143
|
-
스토리의 1000개 예시 행, 카드 높이 공식(`80 + id % 3 × 40`), 예시 URL은 제품 데이터로 바꾼다. 2026-10-06 검수에서 고정 320(Web)·창 폭 − 32(Native)가 좁은 슬롯과 넓은 창의 Container 제한을 무시하는 것을 확인했다.
|
|
139
|
+
스토리의 1000개 예시 행, 카드 높이 공식(`80 + id % 3 × 40`), 예시 URL은 제품 데이터로 바꾼다. 2026-10-06 검수에서 고정 320(Web)·창 폭 − 32(Native)가 좁은 슬롯과 넓은 창의 Container 제한을 무시하는 것을 확인했다. 2026-10-17 구성 리뷰 뒤로는 Masonry가 직접 ResizeObserver/onLayout으로 자리 폭을 재고 측정 전에는 그리지 않는다. 예제에 측정용 div·View나 셀 감싸기 div를 두지 않는다.
|
|
144
140
|
|
|
145
141
|
## 플랫폼 차이
|
|
146
142
|
|
|
147
143
|
| 항목 | Web | Native |
|
|
148
144
|
| --- | --- | --- |
|
|
149
|
-
| 폭 측정 | ResizeObserver
|
|
145
|
+
| 폭 측정 | Masonry 내부 ResizeObserver | Masonry 내부 `onLayout` |
|
|
150
146
|
| 바깥 스크롤 | 문서 스크롤 | Masonry는 `ScrollView` 안, VirtualList(`FlatList`)는 바깥 없이 |
|
|
151
147
|
| QR 대체 행동 | `<a href>` | Button + `Linking.openURL` |
|
|
152
148
|
| 카드 여백 | `var(--hjm-space-sm)` | `spacing.sm` |
|
|
153
149
|
|
|
154
150
|
## 함정
|
|
155
151
|
|
|
156
|
-
- Masonry `width`를
|
|
152
|
+
- Masonry `width`를 직접 넘길 때 0을 넘기면 `TypeError`다. 측정을 화면이 따로 하지 않는다면 `width`를 생략한다.
|
|
157
153
|
- Masonry `gap`은 토큰 이름이 아니라 숫자다(`gap={spacing.sm}`). `gap="sm"`은 타입 오류다.
|
|
158
154
|
- QR 색은 recipe가 검정/흰색으로 고정한다. 다크 테마에서도 브랜드 색으로 바꾸지 않는다.
|
|
159
155
|
- 카드 표면은 `Surface bordered padding="sm"`, 행 텍스트는 `Text`를 재사용한다. 가상 목록 바깥에 세로 ScrollView를 추가하지 않는다.
|
|
@@ -21,10 +21,10 @@ CSV 열 연결, 순차 퍼널, 가입 시점별 잔존율, 지표 상관, 목표
|
|
|
21
21
|
| 컴포넌트 | 역할 | 지침 |
|
|
22
22
|
| --- | --- | --- |
|
|
23
23
|
| ImportFieldMapping | Select, DataTable, Button | 제품 parser·실제 importer와 controlled mapping |
|
|
24
|
-
| ConversionFunnel | BarChart,
|
|
24
|
+
| ConversionFunnel | BarChart, SegmentedControl, Text | 제품 순차 count·이탈 사유 |
|
|
25
25
|
| CohortRetentionTable / CorrelationMatrix | DataTable | 실제 분모/관측값·상관값 |
|
|
26
26
|
| TargetSummary | Statistic, Progress | 실제값·목표 |
|
|
27
|
-
| HistogramExplorer | BarChart,
|
|
27
|
+
| HistogramExplorer | BarChart, SegmentedControl | 원본 samples·범위·선택 구간 수 |
|
|
28
28
|
|
|
29
29
|
## 배치
|
|
30
30
|
|
|
@@ -32,14 +32,16 @@ CSV 열 연결, 순차 퍼널, 가입 시점별 잔존율, 지표 상관, 목표
|
|
|
32
32
|
가져오기: 원본별 선택 → 검증 → 변환 미리보기 → 실제 가져오기
|
|
33
33
|
퍼널: 실제 단계 막대 → 단계 선택 → 선택한 단계 설명
|
|
34
34
|
표: 고정 행 제목 | 기간/변수 열 (가로 스크롤)
|
|
35
|
-
목표: 실제 수치·설명 → 목표가 있을 때 진행 막대
|
|
35
|
+
목표: 실제 수치·설명(Statistic) → 목표가 있을 때 진행 막대(보이는 글자 없음)
|
|
36
36
|
분포: 구간 수 선택 → 동일 y축 분포 → 관측/누락/범위 밖 요약
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
| 영역 | 컴포넌트 | 위치 | 크기·간격 |
|
|
40
40
|
| --- | --- | --- | --- |
|
|
41
41
|
| 바깥 틀 | Stack | 기존 본문·카드 안 | md, 목표는 sm |
|
|
42
|
-
|
|
|
42
|
+
| 선택 | SegmentedControl(퍼널 단계·분포 구간 수), Select(가져오기 연결) | 퍼널은 막대 아래, 분포는 막대 위 | SegmentedControl 기본 크기, 그룹 이름은 구성 `label` |
|
|
43
|
+
| 행동 | Button | 가져오기 연결 마지막 | 꽉 찬 폭 primary 하나 |
|
|
44
|
+
| 목표 진행 | Progress(`aria-label`/`accessibilityLabel`만) | Statistic 아래 | 라벨·값 글자는 Statistic이 한 번만 보인다 |
|
|
43
45
|
| 상태 | Text | 해당 구성 중앙 | 중앙 정렬, 임의 상단 margin 없음 |
|
|
44
46
|
| 표 | DataTable | 본문 폭 안 스크롤 | 첫 열 pinned start; 대각선도 실제 셀 |
|
|
45
47
|
|
|
@@ -88,6 +90,7 @@ Native 차트는 기존 react-native-svg optional peer를 사용한다. 새 제
|
|
|
88
90
|
|
|
89
91
|
- null 미래 관측을 0%로 채우거나 목표 0을 100%로 만들지 않는다.
|
|
90
92
|
- 순차가 아닌 지표를 퍼널에 넣지 않는다. 실제 원인 데이터 없이 이탈 사유를 생성하지 않는다.
|
|
93
|
+
- 단계·구간 수 선택을 `Button selected` 나열로 만들지 않는다. 선택 항목이 테두리 없는 글자로 보여 상태가 거꾸로 읽힌다(SegmentedControl이 맡는다).
|
|
91
94
|
- 히스토그램 전체 선택에서 같은 domain을 유지한다. 누락값·범위 밖 count를 제품 summaryLabel에 표현한다.
|
|
92
95
|
- mapping 변경만으로 저장을 실행하지 않는다. 서버 확정·권한·멱등성은 실제 importer 책임이다.
|
|
93
96
|
- npm 1.21.0에서 제공하며 소비 앱의 실제 설치 버전을 확인한다.
|
|
@@ -21,29 +21,29 @@
|
|
|
21
21
|
|
|
22
22
|
| 컴포넌트 | 역할 | 지침 |
|
|
23
23
|
| --- | --- | --- |
|
|
24
|
-
| Provider |
|
|
24
|
+
| Provider | 필드 표현 상속. Storybook은 미리보기 도구로 10개 테마를 순회 | [프로필 계약](../../design-profile.md) |
|
|
25
25
|
| DatePicker | ISO 날짜 하나와 표시 달, 접근 가능한 달력 표면 | [날짜 선택](../components/date-picker.md) |
|
|
26
26
|
| Select ×2 | 시·분 선택 | [선택 목록](../components/select.md) |
|
|
27
27
|
| Section·Container·Stack | 제목·전체 흐름·폭 | [구역](../components/section.md) · [컨테이너](../components/container.md) · [스택](../components/stack.md) |
|
|
28
28
|
| Button | 확인·다시 선택 | [버튼](../components/button.md) |
|
|
29
29
|
| Text·Notice | 선택값·진행·실패·확인 결과 | [텍스트](../components/text.md) · [알림](../components/notice.md) |
|
|
30
|
-
|
|
|
30
|
+
| 미리보기 도구(Showcase 전용) | 다음 테마·미리보기 응답 받기·다음 확인 실패를 본문 끝에 작은 도구로 둔다. 제품에는 없다 | [버튼](../components/button.md) · [칩](../components/chip.md) |
|
|
31
31
|
|
|
32
32
|
## 배치
|
|
33
33
|
|
|
34
34
|
```text
|
|
35
|
-
Section 제목/설명
|
|
35
|
+
Section 제목/설명
|
|
36
36
|
날짜 트리거 → 달력(선택/지우기/이전·다음 달/닫기)
|
|
37
37
|
시 Select → 분 Select
|
|
38
38
|
같은 선택값 → 시간대/서버는 제품 소유 안내
|
|
39
39
|
확인(주 행동) → 다시 고르기(보조)
|
|
40
40
|
실패/확인 결과
|
|
41
|
-
|
|
41
|
+
미리보기 도구(본문 끝): 다음 테마 · 미리보기 응답 받기 · 다음 확인 실패(켜고 끄기)
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
| 영역 | 컴포넌트 | 위치 | 크기·간격 |
|
|
45
45
|
| --- | --- | --- | --- |
|
|
46
|
-
| 바깥 틀 | Container·Section·Stack | 세로 문서 흐름; Native ScrollView | `gutter="compact"` 16, `spacing.md` 16.
|
|
46
|
+
| 바깥 틀 | Container·Section·Stack | 세로 문서 흐름; Native ScrollView | `gutter="compact"` 16, `size="reading"`(넓은 화면에서 폭 제한), `spacing.md` 16. 위아래 `spacing.lg` 20 |
|
|
47
47
|
| 날짜 | DatePicker | 제목 아래 | 기존 [날짜 필드 배치](../components/date-picker.md#배치); Web popover/Native Sheet |
|
|
48
48
|
| 시각 | Select | 날짜 아래, 시→분 | `control.fieldHeight` 44, 사이 `spacing.md` 16 |
|
|
49
49
|
| 주·보조 행동 | Button | 선택 상태 아래 | 확인→다시 고르기, `control.buttonHeight.medium` 44 기본. 고정하지 않음 |
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
6
|
- 적용: 1.16.0
|
|
7
|
-
- 검토일: 2026-10-
|
|
7
|
+
- 검토일: 2026-10-17
|
|
8
8
|
- 근거: [프로필 계약](../../design-profile.md), [조사와 QA](../../../../../docs/qa/2026-10-07-design-profile-research.md), 두 Showcase `design-profile-preview.tsx`
|
|
9
9
|
- 스토리북: `배포/구성/비교와 검증/테마 조합`
|
|
10
10
|
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
| Card | 무늬 위의 표면 질감과 초안 | [카드](../components/card.md) |
|
|
26
26
|
| Asset | 같은 그림의 프로필 둥근 액자와 명시한 정사각·원형 비교 | [자산](../components/asset.md) |
|
|
27
27
|
| Heading | 선택 테마의 5단계 제목 크기 | [제목](../components/heading.md) |
|
|
28
|
-
| BottomCTA |
|
|
28
|
+
| BottomCTA | 저장과 위쪽 그림자 | [하단 행동](../components/bottom-cta.md) |
|
|
29
29
|
| Popover(Web) | 비모달 초안과 같은 프로필 순회 | [팝오버](../components/popover.md) |
|
|
30
30
|
| Dialog·Sheet | 열린 초안과 같은 프로필 순회 | [대화상자](../components/dialog.md) · [패널](../components/sheet.md) |
|
|
31
31
|
| Notice·Skeleton·Toast | 알림·로딩·확정 후 피드백의 모서리/그림자 | [알림](../components/notice.md) · [로딩](../components/skeleton.md) · [토스트](../components/toast.md) |
|
|
@@ -36,7 +36,9 @@
|
|
|
36
36
|
|
|
37
37
|
```text
|
|
38
38
|
설명 → 앱 테마 적용(참고 테마/산책 노트/문장 모음) → 표현 선택(기존 10종)
|
|
39
|
-
|
|
39
|
+
[앱 테마 적용] 보이는 이름 + pills → [표현 선택] 보이는 이름 + pills
|
|
40
|
+
선택한 프로필: 헤더 → 저장 상태 → 이름/기간(읽기 폭, 가운데) → 같은 기록 3개 → 저장
|
|
41
|
+
화면 밖 미리보기 도구: 저장 실패 재현
|
|
40
42
|
선택한 프로필: 제목 크기 비교(5단계, 문서 단계 h3 유지)
|
|
41
43
|
표면 질감 비교: 장식 무늬 → Card 제목/설명 → 같은 초안 → 다음 테마
|
|
42
44
|
탭 선택 표시 비교: 테마 따르기/밑줄/이동/늘어남 → 기록/보관함 → 같은 초안 → 다음 테마
|
|
@@ -50,11 +52,20 @@
|
|
|
50
52
|
| --- | --- | --- | --- |
|
|
51
53
|
| 바깥 틀 | Stack | 세로 | `spacing.xl` 24 |
|
|
52
54
|
| 앱/참고 테마 | SegmentedControl | 선택 화면 위 | 앱 설정 3개 후 참고 테마 10개; `presentation="pills"`, 큰 선택 목록의 좁은 폭 배치는 공개 선택 계약을 따른다 |
|
|
53
|
-
| 이름/기간 | TextField·SegmentedControl | 도구 | `spacing.md` 16 |
|
|
54
|
-
| 목록 | OverviewScreen |
|
|
55
|
-
|
|
|
55
|
+
| 이름/기간 | TextField·SegmentedControl | 도구(최대 폭 `layout.readingMaxWidth`, 가운데) | `spacing.md` 16 |
|
|
56
|
+
| 목록 | OverviewScreen | 본문, 도구와 같은 열(같은 폭·시작 끝) | [목록 배치](../components/overview-screen.md#배치) |
|
|
57
|
+
| 저장 | BottomCTA | footer | 주 행동만 |
|
|
58
|
+
| 실패 재현 | PreviewTools 안 ghost 버튼 | OverviewScreen 밖 아래 | `spacing.md` 16 |
|
|
56
59
|
| 자산 비교 | Asset·Stack | 탭 비교 아래 | `xlarge` 120px, `spacing.md` 16, 좁으면 줄바꿈. rounded는 프로필 radius.md, square 0, circle foundation full 유지 |
|
|
57
60
|
|
|
61
|
+
### 비슷해 보이기 쉬운 세 테마
|
|
62
|
+
|
|
63
|
+
| 테마 | 밝은 모드에서 보이는 차이 |
|
|
64
|
+
| --- | --- |
|
|
65
|
+
| 미니멀 | 흰 바탕·무채색 hairline, 그림자 없음, 굵기 500 제목과 넉넉한 행간, 넓은 안쪽 여백의 테두리 카드(cards) |
|
|
66
|
+
| 에디토리얼 | 시스템 serif 제목·본문, 가장 큰 제목 단계(56/42/30px), 따뜻한 잉크색과 와인 강조, 각진 모서리, 규칙선으로 나눈 rows |
|
|
67
|
+
| 터미널 | 모든 글자 monospace, 모서리 0, 그림자 없음, 녹회색 바탕·짙은 녹색 행동·호박색 강조, 규칙선 rows. 어두운 모드는 검정 콘솔 |
|
|
68
|
+
|
|
58
69
|
## 흐름과 상태
|
|
59
70
|
|
|
60
71
|
1. 기록 이름·기간을 바꾼다. 앱 설정과 표현을 바꿔도 같은 선택 화면의 초안/선택을 유지한다.
|
|
@@ -127,3 +138,8 @@ absolute 배치를 사용한다. 전체 비교 tile마다 FAB를 붙이면 행
|
|
|
127
138
|
두 플랫폼 모두 공개 FloatingActionButton의 `onContentClearanceChange` 값을 본문 하단
|
|
128
139
|
padding으로 예약한다. 프로필 전환은 같은 버튼과 실행 횟수를 유지하며 실제 저장/서버 호출은 없다.
|
|
129
140
|
[플로팅 실행 버튼](../components/floating-action-button.md)의 원/pill과 행동·여백 계약을 따른다.
|
|
141
|
+
|
|
142
|
+
## 근거
|
|
143
|
+
|
|
144
|
+
- 2026-10-17 구성 리뷰: 예제 전용 실패 재현이 제품 화면 도구 안에 있었고, 두 pills 선택에 보이는 이름이 없었으며, 제목과 테마 이름이 regular Text였다. dashboard 도구만 왼쪽 반폭이라 가운데 정렬된 header·footer와 축이 섞였다. 그래서 실패 재현을 화면 밖 미리보기 도구로 옮기고, 보이는 이름과 Heading을 두고, 도구를 가운데 읽기 폭에 맞췄다.
|
|
145
|
+
- 2026-10-17 사용자 검토: 도구만 읽기 폭으로 제한해 카드 목록이 더 넓었고(1024px에서 카드 48–976, 입력 152–872) 좌우 끝이 맞지 않았다. 도구와 목록을 `overviewContentLayout` 한 열로 묶었다. 같은 검토에서 미니멀·에디토리얼·터미널이 밝은 모드에서 거의 같은 흰 화면으로 보여 세 테마의 팔레트·서체·깊이·구성을 함께 구분했다.
|
|
@@ -2,18 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
- 단계: 구성
|
|
4
4
|
- 상태: 배포
|
|
5
|
-
- 지원: Web
|
|
5
|
+
- 지원: Web · Native
|
|
6
6
|
- 적용: 1.12.1
|
|
7
7
|
- 검토일: 2026-10-15
|
|
8
|
-
- 근거: [Collapsible](../../collapsible.md), [ContextMenu](../../context-menu.md), [Menubar](../../menubar.md), `showcase/web/src/patterns/Disclosure.stories.tsx`, `src/collapsible.ts`, `src/menubar.ts`, `packages/react/src/styles.css`(`.hjm-collapsible`, `.hjm-context-menu`, `.hjm-menubar`)
|
|
8
|
+
- 근거: [Collapsible](../../collapsible.md), [ContextMenu](../../context-menu.md), [Menubar](../../menubar.md), `showcase/web/src/patterns/Disclosure.stories.tsx`, `showcase/native/src/Disclosure.stories.tsx`, `src/collapsible.ts`, `src/menubar.ts`, `packages/react/src/styles.css`(`.hjm-collapsible`, `.hjm-context-menu`, `.hjm-menubar`)
|
|
9
9
|
- 스토리북: `배포/구성/탐색과 이동/펼침과 메뉴`
|
|
10
10
|
|
|
11
11
|
공통 구조·배치·상태·배지의 소유권은 [화면과 구성 선택](../SELECTION.md#소유권)을 따른다. 앱은 데이터·문구·브랜드·추가 기능을 공개 슬롯과 콜백으로 연결한다. 아래 코드 골격을 앱별 기본 구조 복제의 근거로 사용하지 않는다. 전용 구성 API가 없는 콘텐츠 묶음은 [CompositionLayout](../components/composition-layout.md)의 제목·배지·행동·본문·상태·footer 슬롯을 사용한다.
|
|
12
12
|
|
|
13
13
|
## 언제 쓰나
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
내용을 숨겼다 펼치거나(Collapsible), Web에서 대상에 붙은 작업 메뉴를 우클릭·키보드로 열거나(ContextMenu),
|
|
16
16
|
데스크톱 앱처럼 상단 메뉴 막대를 두는(Menubar) 세 방식을 각각 보여 주는 모음이다. 스토리 셋은 이어진 흐름이 아니다.
|
|
17
|
+
Native 스토리는 단일 펼침(기본·어두운 테마·큰 글자)만 둔다. ContextMenu·Menubar는 Native에서 지원하지 않는다.
|
|
17
18
|
|
|
18
19
|
| 필요 | 고를 것 | 스토리 |
|
|
19
20
|
| --- | --- | --- |
|
|
@@ -35,7 +36,7 @@ ContextMenu로만 닿는 작업을 두지 않는다. 같은 작업을 보이는
|
|
|
35
36
|
| `Notice` · `Toast` | 작업 결과·실패 알림(스토리의 Notice는 데모) | [Notice](../components/notice.md), [Toast](../components/toast.md) |
|
|
36
37
|
| `Text` | 키보드 사용 안내 | [Text](../components/text.md) |
|
|
37
38
|
| `Stack gap="md"` | 세로 흐름 | [Stack](../components/stack.md) |
|
|
38
|
-
| `Container` | 바깥 틀. HJM 화면 골격이
|
|
39
|
+
| `Container` | 바깥 틀. HJM 화면 골격이 소유한다. 넓은 화면에서도 `size="reading"` 폭으로 제한한다 | [Container](../components/container.md) |
|
|
39
40
|
|
|
40
41
|
## 배치
|
|
41
42
|
|
|
@@ -62,7 +63,7 @@ ContextMenu로만 닿는 작업을 두지 않는다. 같은 작업을 보이는
|
|
|
62
63
|
| 영역 | 컴포넌트 | 위치 | 크기·간격 |
|
|
63
64
|
| --- | --- | --- | --- |
|
|
64
65
|
| 바깥 틀 | 문서 스크롤 > `Container` | HJM 화면 골격이 소유. 메뉴 표면은 `position: fixed`라 스크롤 컨테이너에 잘리지 않는다 | 좌우 `Container gutter`: 폭 600 미만 `compact` 16, 이상 `regular` 20([화면 여백](../tokens/layout.md)). Menubar는 편집 영역 맨 위 |
|
|
65
|
-
| 펼침 트리거 | `Collapsible` trigger | 펼침 내용 위, 꽉 찬 폭, 표시(
|
|
66
|
+
| 펼침 트리거 | `Collapsible` trigger | 펼침 내용 위, 꽉 찬 폭, 표시(`chevronEnd`/`chevronDown` 아이콘, glyph.sm 20)는 끝 | 최소 높이 `control.minTouchTarget` 44, 위아래 `spacing.xs` 8, 글자–표시 `spacing.sm` 12 |
|
|
66
67
|
| 펼침 내용 | `Collapsible` content | 트리거 바로 아래 | 트리거와 `collapsibleRecipe.gap` `spacing.xs` 8 |
|
|
67
68
|
| 메뉴 대상 | `ContextMenu` 자식 | HJM 구성 레이아웃 소유(스토리의 대상 상자는 showcase CSS) | 포커스 링 2px |
|
|
68
69
|
| 메뉴 표면 | ContextMenu 메뉴 | 포인터 위치에 `position: fixed`, 뷰포트 안 | 최대 폭 `min(24rem, 90vw)`, 최대 높이 뷰포트 − 2×`spacing.md`, padding `spacing.xxs` 4, radius `md` 12. 항목 높이 44, padding `spacing.xs` 8 · `spacing.sm` 12 |
|
|
@@ -122,9 +123,14 @@ import { Container, Stack, Text } from "@hjmds/react/layout";
|
|
|
122
123
|
```
|
|
123
124
|
|
|
124
125
|
```tsx
|
|
125
|
-
// Native
|
|
126
|
-
//
|
|
127
|
-
|
|
126
|
+
// Native: 단일 펼침만. ContextMenu·Menubar는 Web 전용이고, 길게 누르기 메뉴는 실험적
|
|
127
|
+
// `NativeContextMenu`(`/context-menu-native`)가 있다.
|
|
128
|
+
import { Collapsible } from "@hjmds/react-native/collapsible";
|
|
129
|
+
import { Text } from "@hjmds/react-native/primitives";
|
|
130
|
+
|
|
131
|
+
<Collapsible trigger={t("order.shipping.more")} defaultOpen>
|
|
132
|
+
<Text>{t("order.shipping.body")}</Text>
|
|
133
|
+
</Collapsible>
|
|
128
134
|
```
|
|
129
135
|
|
|
130
136
|
스토리의 항목(파일·편집·도움말, 기록 작업)과 실행 결과 Notice는 데모다. 항목 구성과 실행은 제품 소유다.
|
|
@@ -142,5 +148,4 @@ import { Container, Stack, Text } from "@hjmds/react/layout";
|
|
|
142
148
|
- `Collapsible`에 `open`과 `defaultOpen`을 함께 주거나 `open`만 주고 `onOpenChange`를 빼면 `TypeError`다.
|
|
143
149
|
- 펼침 여러 개를 Collapsible로 나열하면 구분선·그룹 키보드 이동·"하나만 열림"이 없다. 그런 묶음은 Accordion이다.
|
|
144
150
|
- `ContextMenu` `accessibilityLabel`은 필수다.
|
|
145
|
-
- 현재 단일 펼침 스토리는 Collapsible 두 개(배송·환불)를 `Stack gap="md"`로 이어 둔다. 이웃이 있는 펼침 묶음은 Accordion 기준이므로 따라 하지 않는다.
|
|
146
151
|
- 현재 스토리는 실행 결과 Notice 설명을 `` `${last} 작업을 실행했습니다.` ``처럼 템플릿 문자열로 만들고 문구가 한국어 리터럴이다. 제품은 작업 id→i18n 키 상수 표를 둔다.
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
| 행동 | Button | 미리보기 아래 | 세로 배치, Native growWithContent |
|
|
53
53
|
|
|
54
54
|
파일명은 줄바꿈한다. 미리보기 크기와 내용은 제품 host가 공급하며, 카드 전체를 링크/버튼으로
|
|
55
|
-
감싸지 않는다. `moreAction`도 독립 행동이다. 상위 화면이 스크롤을 소유한다.
|
|
55
|
+
감싸지 않는다. `moreAction`도 독립 행동이다. 정보·더보기 같은 도구 행동은 글자 버튼이 아니라 `label`을 준 `IconButton`(info/more 아이콘)으로 넣는다. 상위 화면이 스크롤을 소유한다.
|
|
56
56
|
|
|
57
57
|
미리보기와 내보내기는 각각 상태 문구·해당 행동을 한 영역으로 묶어 중앙 정렬한다.
|
|
58
58
|
파일명·설명·실제 미리보기 콘텐츠의 정렬은 유지한다. 2026-10-13 실제 예제에서 오류와 로딩
|