@hjmds/design-contracts 1.17.2 → 1.19.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/action-session.d.ts +16 -0
- package/dist/action-session.d.ts.map +1 -1
- package/dist/action-session.js +18 -0
- package/dist/action-session.js.map +1 -1
- package/dist/activity-chip.d.ts +127 -0
- package/dist/activity-chip.d.ts.map +1 -0
- package/dist/activity-chip.js +65 -0
- package/dist/activity-chip.js.map +1 -0
- package/dist/base-recipes.d.ts +1 -1
- package/dist/base-recipes.d.ts.map +1 -1
- package/dist/base-recipes.js +2 -1
- package/dist/base-recipes.js.map +1 -1
- package/dist/behaviors.d.ts +9 -6
- package/dist/behaviors.d.ts.map +1 -1
- package/dist/behaviors.js +5 -3
- package/dist/behaviors.js.map +1 -1
- package/dist/bottom-navigation.d.ts +16 -0
- package/dist/bottom-navigation.d.ts.map +1 -1
- package/dist/bottom-navigation.js +18 -0
- package/dist/bottom-navigation.js.map +1 -1
- package/dist/card.d.ts +4 -0
- package/dist/card.d.ts.map +1 -1
- package/dist/card.js +4 -1
- package/dist/card.js.map +1 -1
- package/dist/carousel.d.ts +3 -0
- package/dist/carousel.d.ts.map +1 -1
- package/dist/carousel.js.map +1 -1
- package/dist/catalog.d.ts +80 -9
- package/dist/catalog.d.ts.map +1 -1
- package/dist/component-recipes.d.ts +74 -3
- package/dist/component-recipes.d.ts.map +1 -1
- package/dist/component-recipes.js +38 -6
- package/dist/component-recipes.js.map +1 -1
- package/dist/content-transition.d.ts +1 -1
- package/dist/content-transition.d.ts.map +1 -1
- package/dist/content-transition.js +2 -2
- package/dist/content-transition.js.map +1 -1
- package/dist/field-group.d.ts +14 -0
- package/dist/field-group.d.ts.map +1 -1
- package/dist/field-group.js +9 -0
- package/dist/field-group.js.map +1 -1
- package/dist/form.d.ts.map +1 -1
- package/dist/form.js +10 -3
- package/dist/form.js.map +1 -1
- package/dist/icon-button-recipe.d.ts +1 -5
- package/dist/icon-button-recipe.d.ts.map +1 -1
- package/dist/icon-button-recipe.js +2 -1
- package/dist/icon-button-recipe.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/screen-patterns.d.ts +10 -0
- package/dist/screen-patterns.d.ts.map +1 -1
- package/dist/screen-patterns.js +17 -3
- package/dist/screen-patterns.js.map +1 -1
- package/dist/toast-liquid.d.ts +1 -1
- package/dist/toast-liquid.d.ts.map +1 -1
- package/dist/toast-liquid.js +3 -2
- package/dist/toast-liquid.js.map +1 -1
- package/dist/toast.d.ts +29 -2
- package/dist/toast.d.ts.map +1 -1
- package/dist/toast.js +59 -3
- package/dist/toast.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/action-session.md +2 -0
- package/docs/activity-chip.md +34 -0
- package/docs/asset.md +7 -0
- package/docs/bottom-navigation.md +16 -1
- package/docs/brand-boundary.md +3 -3
- package/docs/collection-rail.md +4 -0
- package/docs/compound-controls.md +8 -3
- package/docs/consumer-policy.md +39 -120
- 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/gravity-letters.md +2 -0
- package/docs/grid-reveal.md +2 -0
- package/docs/layout.md +2 -2
- package/docs/load-more.md +5 -0
- package/docs/migration-native-legacy-removal.md +30 -17
- package/docs/optional-adapters.md +4 -0
- package/docs/screen-patterns.md +23 -1
- package/docs/toast.md +64 -2
- package/docs/usage/README.md +248 -243
- package/docs/usage/SELECTION.md +43 -0
- package/docs/usage/STANDARD.md +22 -10
- package/docs/usage/components/accordion.md +5 -3
- package/docs/usage/components/activity-chip.md +109 -0
- package/docs/usage/components/agreement.md +6 -9
- package/docs/usage/components/alert-dialog.md +12 -6
- package/docs/usage/components/asset.md +10 -4
- package/docs/usage/components/auth-provider-button.md +2 -2
- package/docs/usage/components/avatar.md +8 -6
- package/docs/usage/components/badge.md +4 -4
- package/docs/usage/components/bottom-cta.md +4 -4
- package/docs/usage/components/bottom-info.md +2 -2
- package/docs/usage/components/bottom-navigation.md +18 -6
- package/docs/usage/components/button.md +6 -3
- package/docs/usage/components/card.md +28 -7
- package/docs/usage/components/carousel.md +12 -4
- package/docs/usage/components/chat-message.md +10 -2
- package/docs/usage/components/chat-screen.md +5 -5
- package/docs/usage/components/checkbox-group.md +1 -1
- package/docs/usage/components/checkbox.md +2 -2
- package/docs/usage/components/chip.md +2 -2
- package/docs/usage/components/code-block.md +3 -4
- package/docs/usage/components/collapsible.md +6 -4
- package/docs/usage/components/combobox.md +2 -2
- package/docs/usage/components/command-palette.md +1 -1
- package/docs/usage/components/comment-thread-screen.md +7 -4
- package/docs/usage/components/container.md +1 -1
- package/docs/usage/components/content-transition.md +3 -2
- package/docs/usage/components/context-menu.md +2 -2
- package/docs/usage/components/counter-badge.md +3 -3
- package/docs/usage/components/data-table.md +1 -1
- package/docs/usage/components/date-picker.md +4 -4
- package/docs/usage/components/description-list.md +3 -3
- package/docs/usage/components/design-system-provider.md +2 -2
- package/docs/usage/components/dialog.md +14 -3
- package/docs/usage/components/divider.md +2 -2
- package/docs/usage/components/editor-screen.md +5 -3
- package/docs/usage/components/effect-surface.md +1 -1
- package/docs/usage/components/empty-state.md +6 -6
- package/docs/usage/components/field.md +5 -3
- package/docs/usage/components/file-picker.md +6 -3
- package/docs/usage/components/form.md +1 -1
- package/docs/usage/components/heading.md +3 -3
- package/docs/usage/components/icon-button.md +6 -3
- package/docs/usage/components/icon.md +1 -1
- package/docs/usage/components/image.md +5 -4
- package/docs/usage/components/keyboard-dock.md +1 -1
- package/docs/usage/components/layout.md +1 -1
- package/docs/usage/components/link.md +2 -2
- package/docs/usage/components/list-detail-screen.md +6 -6
- package/docs/usage/components/list-row.md +13 -4
- package/docs/usage/components/list.md +5 -4
- package/docs/usage/components/masonry.md +2 -1
- package/docs/usage/components/media-selection-screen.md +11 -5
- package/docs/usage/components/mentions.md +2 -2
- package/docs/usage/components/menu.md +3 -2
- package/docs/usage/components/menubar.md +2 -2
- package/docs/usage/components/message-composer.md +3 -3
- package/docs/usage/components/moderation-screen.md +3 -2
- package/docs/usage/components/notice.md +2 -2
- package/docs/usage/components/notification-inbox-screen.md +1 -1
- package/docs/usage/components/notification-item.md +2 -2
- package/docs/usage/components/number-field.md +3 -3
- package/docs/usage/components/otp-field.md +1 -1
- package/docs/usage/components/overview-screen.md +1 -1
- 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 +2 -2
- package/docs/usage/components/profile-screen.md +1 -1
- package/docs/usage/components/progress.md +2 -2
- package/docs/usage/components/qr-code.md +2 -2
- package/docs/usage/components/radio-group.md +1 -2
- package/docs/usage/components/radio.md +1 -2
- package/docs/usage/components/result.md +1 -1
- package/docs/usage/components/saved-items-screen.md +4 -2
- package/docs/usage/components/screen-layout.md +4 -3
- package/docs/usage/components/search-field.md +1 -1
- package/docs/usage/components/search-screen.md +4 -4
- package/docs/usage/components/section.md +3 -3
- package/docs/usage/components/segmented-control.md +4 -4
- package/docs/usage/components/select.md +2 -3
- package/docs/usage/components/settings-screen.md +18 -56
- package/docs/usage/components/sheet.md +10 -5
- package/docs/usage/components/sidebar.md +1 -1
- package/docs/usage/components/skeleton.md +1 -1
- package/docs/usage/components/skip-nav.md +1 -1
- package/docs/usage/components/slider.md +2 -2
- package/docs/usage/components/spinner.md +2 -2
- package/docs/usage/components/splitter.md +1 -1
- package/docs/usage/components/statistic.md +5 -4
- package/docs/usage/components/steps.md +2 -2
- package/docs/usage/components/surface.md +2 -3
- package/docs/usage/components/switch.md +1 -1
- package/docs/usage/components/tabs.md +4 -4
- package/docs/usage/components/tag.md +2 -2
- package/docs/usage/components/tags-input.md +4 -4
- package/docs/usage/components/text-area.md +5 -3
- package/docs/usage/components/text.md +85 -4
- package/docs/usage/components/timeline.md +2 -2
- package/docs/usage/components/toast.md +41 -13
- package/docs/usage/components/toggle-group.md +3 -3
- package/docs/usage/components/tooltip.md +1 -1
- package/docs/usage/components/top-bar.md +5 -4
- package/docs/usage/components/top.md +3 -3
- package/docs/usage/components/transfer-list.md +5 -4
- package/docs/usage/components/upload-item.md +3 -3
- package/docs/usage/components/virtual-list.md +1 -0
- package/docs/usage/compositions/action-feedback.md +42 -6
- package/docs/usage/compositions/action-recovery-optimistic.md +6 -1
- package/docs/usage/compositions/action-recovery-save.md +19 -23
- package/docs/usage/compositions/action-recovery-undo.md +6 -1
- package/docs/usage/compositions/activity-status.md +168 -0
- package/docs/usage/compositions/collection-detail.md +2 -0
- package/docs/usage/compositions/command-records.md +15 -5
- package/docs/usage/compositions/common-message.md +4 -2
- package/docs/usage/compositions/common-notification.md +5 -3
- package/docs/usage/compositions/compound-controls.md +13 -5
- package/docs/usage/compositions/content-transition-comparison.md +2 -2
- package/docs/usage/compositions/date-entry.md +10 -5
- package/docs/usage/compositions/date-time-selection.md +3 -3
- package/docs/usage/compositions/design-profile-comparison.md +7 -5
- package/docs/usage/compositions/disclosure.md +1 -1
- package/docs/usage/compositions/document-resource.md +10 -3
- package/docs/usage/compositions/expo-interactions.md +3 -2
- package/docs/usage/compositions/family-drawer.md +9 -4
- package/docs/usage/compositions/field-group.md +7 -1
- package/docs/usage/compositions/floating-action-button.md +18 -18
- package/docs/usage/compositions/illustrated-outcome.md +3 -2
- package/docs/usage/compositions/input-sheet.md +6 -2
- package/docs/usage/compositions/interaction-adapters.md +1 -1
- package/docs/usage/compositions/interaction-flow-apply.md +6 -3
- package/docs/usage/compositions/interaction-flow-draft.md +5 -2
- package/docs/usage/compositions/interaction-flow-search.md +5 -2
- package/docs/usage/compositions/live-list.md +7 -5
- package/docs/usage/compositions/navigation-bar-collection.md +8 -7
- package/docs/usage/compositions/optional-adapters.md +1 -1
- package/docs/usage/compositions/origin-dialog.md +5 -5
- package/docs/usage/compositions/paper-surface.md +1 -1
- package/docs/usage/compositions/photo-source.md +1 -1
- package/docs/usage/compositions/purpose-input-comment.md +5 -3
- package/docs/usage/compositions/purpose-input-message.md +5 -3
- package/docs/usage/compositions/reference-first.md +63 -42
- package/docs/usage/compositions/reference-review.md +60 -50
- package/docs/usage/compositions/reference-settings.md +60 -50
- package/docs/usage/compositions/selection-scope.md +48 -35
- package/docs/usage/compositions/stea-order-progress.md +1 -0
- package/docs/usage/compositions/stea-otp-verify.md +5 -3
- package/docs/usage/compositions/stea-pixel-empty.md +3 -3
- package/docs/usage/compositions/time-selection.md +6 -5
- package/docs/usage/compositions/upload-recovery.md +10 -1
- package/docs/usage/compositions/video-dialog.md +10 -3
- package/docs/usage/compositions/web-additions.md +5 -5
- package/docs/usage/compositions/web-navigation.md +1 -1
- package/docs/usage/screens/common-chat.md +21 -8
- package/docs/usage/screens/common-comments.md +13 -1
- package/docs/usage/screens/common-inbox.md +19 -6
- package/docs/usage/screens/common-login.md +19 -7
- package/docs/usage/screens/common-profile.md +22 -9
- package/docs/usage/screens/common-saved.md +16 -2
- package/docs/usage/screens/common-search.md +24 -4
- package/docs/usage/screens/common-settings.md +22 -50
- package/docs/usage/screens/common-shell.md +14 -2
- package/docs/usage/screens/dashboard.md +52 -109
- package/docs/usage/screens/discovery-gallery.md +57 -148
- package/docs/usage/screens/flow-collection.md +38 -9
- package/docs/usage/screens/flow-editor.md +25 -7
- package/docs/usage/screens/flow-media.md +23 -7
- package/docs/usage/screens/flow-moderation.md +15 -2
- package/docs/usage/screens/flow-onboarding.md +3 -3
- package/docs/usage/screens/flow-permission.md +17 -3
- package/docs/usage/screens/landing.md +37 -20
- package/docs/usage/screens/mockup-studio.md +22 -7
- package/docs/usage/screens/notification-settings.md +18 -4
- package/docs/usage/screens/product-bento.md +18 -9
- package/docs/usage/screens/reference-comparison.md +29 -10
- package/docs/usage/tokens/color.md +6 -3
- package/docs/usage/tokens/elevation-opacity.md +4 -2
- package/docs/usage/tokens/font-roles.md +2 -2
- package/docs/usage/tokens/layers.md +3 -3
- package/docs/usage/tokens/motion.md +2 -2
- package/docs/usage/tokens/radius.md +4 -2
- package/docs/usage/tokens/spacing.md +3 -3
- package/docs/usage/tokens/theme-studio.md +2 -2
- package/docs/usage/tokens/typography-studio.md +14 -8
- package/docs/usage/tokens/typography.md +15 -5
- package/package.json +7 -1
package/docs/consumer-policy.md
CHANGED
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
상태: **Normative**
|
|
4
4
|
정책 버전: **2.0.0**
|
|
5
|
-
검토일: 2026-10-
|
|
5
|
+
검토일: 2026-10-13 · 현재 소비 계약과 변경 범위 검증
|
|
6
6
|
적용 대상: 신규 HJM Web·React Native 앱과 기존 앱의 새 화면
|
|
7
7
|
|
|
8
8
|
이 원문은 `@hjmds/design-contracts/consumer-policy.md`에서 제공한다. 소비 앱은 설치한
|
|
9
9
|
패키지 버전의 정책과 HJM-APP-STANDARD release snapshot을 함께 확인한다. 이 checkout의
|
|
10
|
-
|
|
10
|
+
미게시 변경을 설치된 패키지의 기능으로 판단하지 않는다.
|
|
11
|
+
|
|
12
|
+
2026-10-13 지침 점검에서 종료된 foundation bridge와 스타일 제거 예정 조건이 현재 규칙에
|
|
13
|
+
남아 있었다. 해당 레거시 절차는 제거하고 과거 버전의 이관표와 검증 기록은 보존한다.
|
|
11
14
|
|
|
12
15
|
이 문서는 "HJM답게 보인다"를 특정 화면 복제로 정의하지 않습니다. 모든 제품이 공유해야
|
|
13
16
|
하는 것은 정보 위계, semantic role, 상태 피드백, 접근성 품질과 플랫폼별 행동입니다.
|
|
@@ -24,6 +27,10 @@
|
|
|
24
27
|
- 앱 runtime은 granular subpath를 우선하고 catalog·showcase·evidence entry는 CI나
|
|
25
28
|
tooling에서만 사용해야 합니다(SHOULD).
|
|
26
29
|
|
|
30
|
+
저장소의 `module.contract.json` 소비 목록은 호환성 검토 대상을 기록하며 설치·배포 완료를
|
|
31
|
+
뜻하지 않는다. 2026-10-13 실제 package 의존성을 대조해 누락된 Utilverse와 App Release Hub를
|
|
32
|
+
추가했다. Hub는 정책 사이트 생성에 colors/foundations만 사용하므로 renderer 이관과 구분한다.
|
|
33
|
+
|
|
27
34
|
## 2. 성숙도별 채택
|
|
28
35
|
|
|
29
36
|
| 사용할 surface 상태 | 신규 앱 기본 정책 | 추가 조건 |
|
|
@@ -34,7 +41,8 @@
|
|
|
34
41
|
| `deprecated` | 신규 사용 금지 | 공지된 migration 기한 안에 제거 |
|
|
35
42
|
|
|
36
43
|
`surfaceStatus`가 사용 플랫폼의 채택 기준입니다. contract `status`가 stable이어도
|
|
37
|
-
다른 renderer까지 안정화됐다는 뜻은 아닙니다.
|
|
44
|
+
다른 renderer까지 안정화됐다는 뜻은 아닙니다. 현재 값은 설치 버전의
|
|
45
|
+
[성숙도 표](generated/component-maturity.md)를 확인합니다. Storybook의 배포/실험은 API 안정성이나 npm 게시 상태가 아닙니다.
|
|
38
46
|
|
|
39
47
|
신규 앱 scaffold의 기본 선택은 Stable Core입니다(SHOULD). Beta 사용은 정책 예외가 아닙니다.
|
|
40
48
|
앱의 기존 contract 또는 TASKS 한 곳에 컴포넌트·표면, 사용하는 이유, 담당자와 관련 회귀
|
|
@@ -42,40 +50,12 @@
|
|
|
42
50
|
재검토 날짜는 요구하지 않습니다. 실제 기기·브라우저 QA는 바뀐 사용자 흐름과 플랫폼 위험에
|
|
43
51
|
맞춰 앱 릴리스에서 수행합니다. Beta라는 이유만으로 제품 전체 QA를 반복하지 않습니다.
|
|
44
52
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
1.5.0에서 Stable Core는 17개 컴포넌트였습니다. 1.4까지의 `Surface`, `Button`, `Field`, `TextArea`에
|
|
53
|
-
더해, 첫 제품 화면에 필요한 foundation인 `Text`, `Icon`, `Stack`, `Container`,
|
|
54
|
-
`DesignSystemProvider`와 세 제품 이상이 쓰는 `IconButton`, `Badge`, `Card`, `Tag`, `Notice`,
|
|
55
|
-
`Progress`, `Spinner`, `Skeleton`이 stable로 승격됐습니다. 승격 근거는 이름뿐이던 시나리오 증거를
|
|
56
|
-
실제 계산 스타일 검사로 바꾼 뒤 두 renderer에서 요구 시나리오가 모두 통과한 것입니다
|
|
57
|
-
([Stable Core](stable-core.md)). 이번 개정에서는 `Divider`, `Section`, `ListRow`, `Statistic`,
|
|
58
|
-
`DescriptionList`, `EmptyState`, `Result`, `Heading`, `Top`, `BottomCTA`를 양쪽에서 승격하고,
|
|
59
|
-
`TopBar`는 계약·Web만 승격했습니다. 계약/Web stable은 28개, Native stable은 27개입니다.
|
|
60
|
-
배포된 패키지의 catalog가 소비 앱의 기준입니다. 남은 beta를 `stable`로
|
|
61
|
-
간주하거나 `betaAdoptions: []`로 기록하는 것은 허용하지 않습니다(MUST NOT).
|
|
62
|
-
|
|
63
|
-
HJM-APP-STANDARD가 versioned `requiredFoundations` 목록을 선언한 경우 다음 bridge를
|
|
64
|
-
적용합니다.
|
|
65
|
-
|
|
66
|
-
- 필수 foundation의 채택 이유와 최소 목록은 중앙 profile이 소유합니다. 앱마다 같은
|
|
67
|
-
선택 이유를 새로 발명하지 않습니다(MUST).
|
|
68
|
-
- 각 앱은 실제 adapter와 사용 환경에 대한 evidence를 소유합니다(MUST). `draft` /
|
|
69
|
-
`incubating` contract에서는 evidence가 `planned`일 수 있지만, `active` 또는 release gate는
|
|
70
|
-
timestamp가 있는 `verified` evidence 없이는 통과하면 안 됩니다(MUST NOT).
|
|
71
|
-
- 중앙 필수 목록 밖의 `beta`는 제품별 optional adoption이며 §2의 간단한 채택 기록을
|
|
72
|
-
사용합니다. 예전 profile이 ADR·verified evidence를 요구하면 해당 profile 갱신 때 이관합니다.
|
|
73
|
-
- foundation이 catalog에서 `stable`로 승격되면 기존 표준의 의미를 조용히 바꾸지 않고
|
|
74
|
-
다음 versioned app profile에서 bridge 목록을 줄입니다(MUST).
|
|
75
|
-
|
|
76
|
-
이 bridge는 성숙도 예외가 아니라 공개된 임시 채택 계약입니다. 1.5.0에서 bridge의 다섯
|
|
77
|
-
foundation이 모두 stable이 됐으므로, 중앙 app profile의 다음 개정에서 `requiredFoundations`
|
|
78
|
-
목록을 비웁니다. 개정 전까지 기존 profile을 쓰는 앱의 evidence 요구는 조용히 바뀌지 않습니다.
|
|
53
|
+
컴포넌트 승격은 [승격 기준](stable-promotion.md)을 따르고 과거 판정은
|
|
54
|
+
[Stable Core 기록](stable-core.md)에 보존한다. 현재 규칙에 이전 버전의 개수나 임시 foundation
|
|
55
|
+
bridge를 복제하지 않는다. 구버전 소비자는 설치된 정책·profile과 해당 이관표를 확인한다.
|
|
56
|
+
|
|
57
|
+
화면은 [선택 기준](usage/SELECTION.md)에 따라 그대로 사용, 공개 슬롯 확장, 제품 전용 구성 중 고른다.
|
|
58
|
+
이름이 같다는 이유로 저장·스크롤·권한 흐름이 다른 화면에 공통 API를 강제하지 않는다.
|
|
79
59
|
|
|
80
60
|
## 3. 코드 경계
|
|
81
61
|
|
|
@@ -85,83 +65,22 @@ foundation이 모두 stable이 됐으므로, 중앙 app profile의 다음 개정
|
|
|
85
65
|
또는 제품 어댑터를 사용해야 합니다(MUST).
|
|
86
66
|
- 도메인 상태는 화면마다 색을 정하지 않고 제품 어댑터에서 HJM `AccentTone`과 component
|
|
87
67
|
variant에 매핑해야 합니다(MUST).
|
|
88
|
-
- HJM component의 `
|
|
68
|
+
- HJM component의 `layoutStyle`은 배치용 margin, width, flex와 화면 composition에만
|
|
89
69
|
사용해야 합니다(SHOULD). color, typography, radius, control height와 interaction state를
|
|
90
70
|
덮어쓰는 용도로 사용하면 안 됩니다(MUST NOT).
|
|
91
71
|
- 플랫폼 primitive가 필요한 경우 접근성 또는 플랫폼 관습 때문에 필요한 adapter에
|
|
92
72
|
한정하고, 그 이유를 해당 adapter test로 고정해야 합니다(MUST).
|
|
93
73
|
|
|
94
|
-
### 3.1
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
요소이며 그 목록과 이유는 `@hjmds/react`의 `composition-style.ts`와 각 props 타입 주석에 있습니다.
|
|
105
|
-
- `HjmCompositionStyle` / `layoutStyle`은 margin, width, flex 계열과 `alignSelf`만 제공합니다. color,
|
|
106
|
-
typography, padding, gap, border, radius, height, opacity, transform은 recipe/semantic API 소유입니다.
|
|
107
|
-
- 내부 조합의 스타일은 비공개 renderer에 두며 앱에서 해당 내부 파일을 import하지 않습니다.
|
|
108
|
-
- 정식 플랫폼 host·제품 소유 슬롯·이미지 renderer 스타일을 deprecated 별칭과 혼동하지 않습니다.
|
|
109
|
-
|
|
110
|
-
소비 앱의 legacy prop이 실제로 무엇을 덮어쓰고 있었는지 확인한 뒤, 배치가 아닌 값은
|
|
111
|
-
semantic axis로 옮겼습니다. 아래는 그 축과 대체 대상입니다.
|
|
112
|
-
|
|
113
|
-
| 제품이 덮어썼던 것 | semantic axis |
|
|
114
|
-
| --- | --- |
|
|
115
|
-
| 컨트롤에 `minHeight: 44`를 다시 얹어 compact recipe의 36pt를 가리기 | provider 환경의 `minimumVisualTarget` |
|
|
116
|
-
| Button `borderRadius: 999`로 pill 만들기 | `shape="pill"` |
|
|
117
|
-
| Button `justifyContent: "flex-start"`로 라벨 좌측 정렬 | `align="leading"` |
|
|
118
|
-
| ListRow leading slot에 40pt 원형 avatar 프레임을 제품이 다시 계산 | `leadingShape` (`listRowRecipe.leadingSize`를 renderer가 바인딩) |
|
|
119
|
-
| 중첩 web Provider의 `display: contents` 인라인 중화 | `host="contents"` |
|
|
120
|
-
| secondary 컨트롤 테두리를 제품 boundary 색으로 덮기 | `borderControl` semantic key + `semanticColors.border.control` |
|
|
121
|
-
|
|
122
|
-
### Web renderer의 캐스케이드
|
|
123
|
-
|
|
124
|
-
`@hjmds/react/styles.css`는 **CSS 레이어 밖**에 있다(레이어된 opt-in 파일과 전환 조건은
|
|
125
|
-
[brand-boundary.md §3](./brand-boundary.md#3-css-재정의는-지원하는-테마-경로가-아니다)). Tailwind 4를 쓰는 소비 앱의
|
|
126
|
-
유틸리티는 `@layer utilities` 안에 들어가고, 레이어 밖 규칙은 레이어 안 규칙을
|
|
127
|
-
이긴다. 따라서 HJM 컴포넌트에 `px-0`·`rounded-none`·`justify-start` 같은
|
|
128
|
-
유틸리티를 붙여 recipe 값을 덮으려는 시도는 **조용히 아무 일도 하지 않는다.**
|
|
129
|
-
|
|
130
|
-
이건 결함이 아니라 이 정책이 의도한 결과다 — recipe 소유 값은 지나가는
|
|
131
|
-
유틸리티로 흔들리면 안 된다. 다만 **조용하다**는 점이 문제라, 소비 앱은 다음을
|
|
132
|
-
알고 있어야 한다.
|
|
133
|
-
|
|
134
|
-
- 유틸리티로 recipe 값을 덮는 코드는 리뷰에서 걸러야 한다. 필요한 값은 semantic
|
|
135
|
-
axis로 요청한다.
|
|
136
|
-
- HJM이 표현할 수 없는 값은 `.hjm-*` 재정의로 우회하지 않는다. 계약 공백으로 올린다. 기존 재정의는
|
|
137
|
-
추적되는 부채이며 이관 경로(opt-in `styles.layered.css`)와 규칙은 [brand-boundary.md](./brand-boundary.md)가 정한다.
|
|
138
|
-
- 인라인 `style`은 모든 규칙을 이기므로 이관 전에는 보이던 값이 이관 후 조용히
|
|
139
|
-
사라질 수 있다. 이관은 브라우저에서 실제 렌더를 확인하며 진행한다.
|
|
140
|
-
|
|
141
|
-
> `ThemeColors`에 semantic key를 더하는 것은 `brandPalette` 부분 주입 소비자에게는
|
|
142
|
-
> 무해하지만, **완전한 팔레트를 직접 선언하는 소비자에게는 타입 파괴적**이다.
|
|
143
|
-
> 0.x train에서는 patch로 내보내되 릴리스 노트에 그 사실을 적고, 소비자는 새 key를
|
|
144
|
-
> 채워야 한다. 1.0 이후에는 이 형태의 추가를 minor 이상으로 올린다.
|
|
145
|
-
| 토글 Button·IconButton의 selected 배경·테두리를 제품 style로 칠하기 | `selected` (`buttonRecipe.states.selected`, `iconButtonRecipe.states.selected`) |
|
|
146
|
-
| `link` tone Button에서 `paddingHorizontal: 0`으로 인라인 정렬 복원 | tone별 `paddingHorizontal` (link=0) |
|
|
147
|
-
| Web ListRow의 1행/2행 최소 높이·padding·gap을 제품이 다시 계산 | `--hjm-list-row-*` 변수로 density recipe를 stylesheet에 바인딩 |
|
|
148
|
-
| Web Switch에 size 축이 없어 track/thumb 크기를 제품 변수로 구현 | `size` prop + `--hjm-switch-*` (`switchRecipe.sizes` 바인딩) |
|
|
149
|
-
| Surface에 `overflow: hidden`을 얹어 자식 이미지의 라운드 코너 침범 막기 | `surfaceRecipe[tone].clipsContent` (elevated tone은 그림자가 잘리므로 예외) |
|
|
150
|
-
| Chip·ListRow·Image·LoadMore·DescriptionList의 배치용 `style` | 각 컴포넌트의 `layoutStyle` |
|
|
151
|
-
|
|
152
|
-
legacy raw style surface는 다음 조건이 모두 충족된 뒤 공지된 breaking train에서 제거합니다.
|
|
153
|
-
|
|
154
|
-
1. Stable Core가 canonical `layoutStyle` 또는 동등한 좁은 composition API를 제공한다.
|
|
155
|
-
2. HJM showcase와 관리 중인 앱이 새 API로 이동하고 light/dark, large text, RTL과 touch-target
|
|
156
|
-
evidence를 다시 검증한다.
|
|
157
|
-
3. 최소 한 fixed release train 동안 deprecation과 migration 문서를 제공한다.
|
|
158
|
-
4. 제거 Changeset이 영향을 받는 prop과 semantic 대안을 열거한다.
|
|
159
|
-
|
|
160
|
-
2026-09-23 소비 감사에서 1.3.5에도 deprecated prop이 남아 있음을 확인했습니다. 이전의
|
|
161
|
-
“1.0.0 이전 제거” 기한은 실제 release/API와 어긋나므로 폐기합니다. 이미 게시한 1.x의 타입과
|
|
162
|
-
런타임을 minor에서 삭제하는 대신, 위 네 조건과 소비 앱별 이관 목록을 충족한 다음 major에서
|
|
163
|
-
제거합니다. 1.4는 semantic API와 이관 경로를 추가하는 train이며, 기존 prop을 새 화면에 쓰는
|
|
164
|
-
것은 계속 금지합니다. 2026-10-02 사용자의 전체 이관 결정으로 제거 train을 1.11로 확정했습니다.
|
|
74
|
+
### 3.1 배치와 시각 값
|
|
75
|
+
|
|
76
|
+
- 배치에는 `layoutStyle`을 쓰고, 제공하지 않는 컴포넌트는 외부 composition wrapper를 쓴다.
|
|
77
|
+
지원 속성은 각 renderer의 `HjmCompositionStyle` 타입과 컴포넌트 Props를 따른다.
|
|
78
|
+
- 색·글꼴·모서리·높이·상태 표현은 semantic API, `brandPalette`, `designProfile`로 지정한다.
|
|
79
|
+
앱에서 내부 selector나 제거된 `style`·`labelStyle` 별칭으로 덮지 않는다.
|
|
80
|
+
- 플랫폼 host·제품 소유 슬롯·이미지 renderer의 정식 style은 제거된 별칭과 구분한다.
|
|
81
|
+
- CSS 레이어와 기존 재정의의 이관은 [브랜드 경계](brand-boundary.md#3-css-재정의는-지원하는-테마-경로가-아니다)가 소유한다.
|
|
82
|
+
- 제거된 API와 대체 prop은 [Native 호환 API 이관표](migration-native-legacy-removal.md)에 보존한다.
|
|
83
|
+
종료된 제거 예정 조건이나 0.x 버전 규칙을 현재 소비 경로로 안내하지 않는다.
|
|
165
84
|
|
|
166
85
|
권장 구조는 다음과 같습니다. 실제 폴더명은 stack 관습에 맞춰도 역할은 유지합니다.
|
|
167
86
|
|
|
@@ -195,27 +114,28 @@ on-color 대비, 색에 의존하지 않는 상태 표지, reduce-motion을 제
|
|
|
195
114
|
|
|
196
115
|
## 5. 필수 검증과 evidence
|
|
197
116
|
|
|
198
|
-
|
|
117
|
+
다음 제품 계약을 유지하고, 변경한 코드와 직접 소비하는 표면의 타입·빌드·관련 동작을 검사한다.
|
|
118
|
+
같은 SHA·같은 범위의 성공은 재사용하며 전체 회귀는 명시적으로 선택한다.
|
|
119
|
+
문서 형식·Storybook 분류·검사 명령 문자열은 제품 배포의 차단 조건이 아니다.
|
|
199
120
|
|
|
200
121
|
1. contracts/renderer exact version 일치와 금지 dependency 형식 검사
|
|
201
|
-
2.
|
|
122
|
+
2. 설치된 catalog·앱 profile과 실제 사용 표면의 일치
|
|
202
123
|
3. HJM Provider 존재와 제품 theme adapter 존재 검사
|
|
203
124
|
4. 원시 색·간격·radius의 화면 레이어 유입 방지 검사
|
|
204
125
|
5. typecheck, unit/component test, production build
|
|
205
|
-
6. light/dark,
|
|
126
|
+
6. 영향 화면의 light/dark, 지원 방향과 reduced motion 등 변경에 관련된 환경
|
|
206
127
|
7. optional Beta component를 쓴다면 §2의 채택 기록과 변경한 사용자 흐름의 회귀 검사
|
|
207
128
|
|
|
208
129
|
앱이 지원하지 않는 플랫폼이나 환경은 가짜 통과 script로 만들지 않고 app contract에서
|
|
209
130
|
`not-applicable`과 이유를 선언해야 합니다(MUST).
|
|
210
131
|
|
|
211
|
-
|
|
132
|
+
OS 최대 글자 및 그 최대값 모사는 설계·검증·후속 조건에서 제외한다.
|
|
212
133
|
|
|
213
|
-
|
|
134
|
+
## 6. 예외와 변경 절차
|
|
214
135
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
- 만료 또는 재검토 날짜
|
|
136
|
+
계약 변경이나 예외의 이유·영향·검사 결과·미확인 범위는 기존 계약 문서, TASKS 또는 커밋에 남긴다.
|
|
137
|
+
작은 수정에 별도 ADR, 고정 항목 수, 중복 승인을 요구하지 않는다. 임시 우회에는 제거 조건을 적는다.
|
|
138
|
+
공개 API·데이터·호환성을 바꾸면 해당 계약과 migration을 갱신한다.
|
|
219
139
|
|
|
220
140
|
공통 API를 바꾸는 것이 한 제품의 local override보다 적절하면 제품 코드를 복제하지 않고
|
|
221
141
|
HJM에 Changeset과 Web/RN evidence를 먼저 제출합니다. 반대로 제품 의미가 들어가면 공통
|
|
@@ -226,8 +146,7 @@ package로 승격하지 않습니다.
|
|
|
226
146
|
다음 질문에 모두 "예"라고 답할 수 있어야 HJM 채택이 완료된 것입니다.
|
|
227
147
|
|
|
228
148
|
- exact fixed-train dependency와 Provider가 CI에서 검증되는가?
|
|
229
|
-
-
|
|
230
|
-
optional Beta는 채택 기록과 관련 회귀 검사로 추적되는가?
|
|
149
|
+
- 설치 버전의 surfaceStatus를 따르고 optional Beta는 채택 기록과 관련 회귀 검사로 추적되는가?
|
|
231
150
|
- screen 코드가 semantic token·component를 우회하지 않는가?
|
|
232
151
|
- 같은 상태가 Web/RN에서 같은 의미와 자연스러운 플랫폼 행동을 갖는가?
|
|
233
152
|
- 로고를 제거해도 제품의 핵심 콘텐츠와 정보 구조가 다른 제품과 구분되는가?
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Component maturity and evidence manifest
|
|
2
2
|
|
|
3
|
-
> Generated from `@hjmds/design-contracts` 1.
|
|
3
|
+
> Generated from `@hjmds/design-contracts` 1.19.0. Do not edit this file directly; run `pnpm contracts:sync`.
|
|
4
4
|
|
|
5
5
|
This document is the human-readable projection of the same catalog and Showcase manifest consumed by product CI.
|
|
6
6
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"designSystemVersion": "1.
|
|
3
|
+
"designSystemVersion": "1.19.0",
|
|
4
4
|
"source": "packages/design-contracts/docs/generated/showcase-manifest.json",
|
|
5
5
|
"surfaces": {
|
|
6
6
|
"web": {
|
|
7
7
|
"packageName": "@hjmds/react",
|
|
8
|
-
"packageVersion": "1.
|
|
8
|
+
"packageVersion": "1.19.0",
|
|
9
9
|
"activeComponents": 103,
|
|
10
10
|
"claimedComponents": 103,
|
|
11
11
|
"completeScenarioComponents": 103,
|
|
@@ -5642,7 +5642,7 @@
|
|
|
5642
5642
|
},
|
|
5643
5643
|
"native": {
|
|
5644
5644
|
"packageName": "@hjmds/react-native",
|
|
5645
|
-
"packageVersion": "1.
|
|
5645
|
+
"packageVersion": "1.19.0",
|
|
5646
5646
|
"activeComponents": 83,
|
|
5647
5647
|
"claimedComponents": 83,
|
|
5648
5648
|
"completeScenarioComponents": 83,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Renderer evidence coverage
|
|
2
2
|
|
|
3
|
-
> Generated for HJM 1.
|
|
3
|
+
> Generated for HJM 1.19.0. Do not edit directly; run `pnpm evidence:sync`.
|
|
4
4
|
|
|
5
5
|
This projection joins the canonical surface maturity manifest with first-party renderer claims. Missing scenarios are explicit beta promotion debt; stable surfaces are blocked by CI until none remain.
|
|
6
6
|
|
package/docs/gravity-letters.md
CHANGED
|
@@ -24,3 +24,5 @@ Both Storybooks: `컴포넌트 / Display / Gravity Letters`, with Default, Dark
|
|
|
24
24
|
and LargeText. Web glyph typography can be inherited from a surrounding heading
|
|
25
25
|
Text. Renderer behavior tests cover explicit replay and motion bypass; Native
|
|
26
26
|
mock tests do not prove actual device rendering.
|
|
27
|
+
|
|
28
|
+
장식 animation 생성이 중간에 실패하면 이미 만든 animation을 정리하고 정적인 글자를 유지한다. 장식 실패로 본문을 제거하지 않는다.
|
package/docs/grid-reveal.md
CHANGED
|
@@ -9,3 +9,5 @@
|
|
|
9
9
|
Web은 WAAPI, Native는 Core Animated를 사용한다. Native 화면이 mounted인 채 가려지면 제품이 active=false를 전달해야 한다. 부모를 이미지 크기에 맞게 배치하며, 둥근 이미지 모서리가 필요하면 동일한 클리핑 프레임으로 둘을 감싼다.
|
|
10
10
|
|
|
11
11
|
양쪽 Storybook 컴포넌트/시각 효과/Grid Reveal에서 Default/Dark/LargeText, 다시 보기와 이미지 실패/재시도를 제공한다. 예제 풍경은 코드로 만든 자체 이미지다. [Native 후속 검증](../../../docs/evidence/component-flows-2026-10-01/README.md)에서 기존 iPhone 17 / iOS 27 시뮬레이터의 큰 글씨 오류·재시도 화면을 실제 조작하고 확인했다. Image 계약에 따라 오류 전후 같은 이미지 설명을 유지하며, 시각적 오류 문구는 중복 접근성 이름으로 읽지 않는다. 물리 기기의 GPU 비용과 프레임별 효과 타이밍 검증은 별도다.
|
|
12
|
+
|
|
13
|
+
장식 animation 생성이 중간에 실패하면 이미 만든 animation과 마스크를 정리하여 본문을 즉시 드러낸다.
|
package/docs/layout.md
CHANGED
|
@@ -69,8 +69,8 @@ Web의 `footer` slot은 `Layout`이 `<footer>` contentinfo를 정확히 한 번
|
|
|
69
69
|
`BottomNavigation`은 자체 루트를 이름 있는 `<nav>`로 렌더링하고 contentinfo를
|
|
70
70
|
만들지 않으므로 `footer={<BottomNavigation ... />}` 합성 결과도 `<footer>` 하나와
|
|
71
71
|
`<nav>` 하나다. Native `Layout`은 같은 source order만 유지하며 skip link를
|
|
72
|
-
렌더링하거나 요구하지 않는다.
|
|
73
|
-
|
|
72
|
+
렌더링하거나 요구하지 않는다. Native `LayoutProps`에는 `skipLinkLabel`이 없다.
|
|
73
|
+
Web의 skip-link 입력을 Native에 공통 props로 넘기지 않는다.
|
|
74
74
|
|
|
75
75
|
**현재 검증.** 공통 descriptor를 직접 소비하는 first-party Web/RN renderer가 실제
|
|
76
76
|
landmark, source order, overlay adapter를 검증한다. Web Chromium test는 skip-link가 첫
|
package/docs/load-more.md
CHANGED
|
@@ -28,6 +28,11 @@ ready(requestKey) ─ request ─→ loading(requestKey)
|
|
|
28
28
|
- loading copy는 status로, 오류는 alert로 한 번만 발표합니다. retry/manual target은 44-unit
|
|
29
29
|
이상이고 focus indicator를 유지합니다.
|
|
30
30
|
|
|
31
|
+
2026-10-13 수명 검수: 성공으로 완료된 Native viewport 요청만 같은 cursor의 자동 재요청을
|
|
32
|
+
막는다. 진행 중 다른 요청에 막힌 cursor와 실패한 요청은 재시도할 수 있다. Web/Native 모두
|
|
33
|
+
unmount 또는 mode 변경으로 교체된 footer의 늦은 outcome/error 콜백을 전달하지 않는다.
|
|
34
|
+
제품 query 자체의 취소·데이터 저장은 여전히 제품 adapter가 소유한다.
|
|
35
|
+
|
|
31
36
|
Web `IntersectionObserver`와 RN `onEndReached`는 감지 방식만 다르며 같은 controller와 state를
|
|
32
37
|
사용합니다. 페이지 번호가 필요한 탐색은 `Pagination`, 사용자 의도 없이 계속 이어지는 긴
|
|
33
38
|
목록은 `LoadMore`로 분리합니다.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Native 호환 API 제거와 소비 이관
|
|
2
2
|
|
|
3
|
-
검토일: 2026-10-
|
|
3
|
+
검토일: 2026-10-13 · 잔여 시각 style 제거는 breaking 소스 변경 · npm 게시와 소비 설치는 별도 확인
|
|
4
|
+
|
|
5
|
+
## 1.11 제거 이력
|
|
4
6
|
|
|
5
7
|
사용자가 전체 소비 앱을 함께 버전업하므로 구형 호환 API도 제거하라고 요청했다.
|
|
6
8
|
별칭과 deprecated 스타일 통로를 유지하는 대신 기존 canonical API로 이관한다.
|
|
@@ -46,34 +48,39 @@ renderer에 주입하는 이미지 스타일, 제품 소유 슬롯과 private re
|
|
|
46
48
|
LoadMore의 내부 Button 조합은 비공개 RecipeButton을 써서 recipe의 크기·색·그림자를 보존한다.
|
|
47
49
|
해당 구현을 패키지 entry에서 export하지 않는다.
|
|
48
50
|
|
|
49
|
-
##
|
|
51
|
+
## 2026-10-13 잔여 시각 style 제거
|
|
52
|
+
|
|
53
|
+
1.13에서는 2026-10-06에 발견한 잔여 raw `StyleProp` 통로의 동작을 유지하고 개발 모드에서
|
|
54
|
+
한 번 경고했다. 이는 당시 minor 호환성 조치였다. 2026-10-13 레거시 제거 요구에 따라 아래
|
|
55
|
+
공개 속성과 시각 style 병합을 소스에서 제거했다. 최초 major 후보를 준비한 뒤 사용자가
|
|
56
|
+
이번 버전도 minor로 올리도록 명시하여 **1.19.0**으로 결정했다. 호환성이 깨지는 제거이므로
|
|
57
|
+
아래 소비 호출을 함께 이관한다. 버전 준비·npm 게시·소비 설치는 각각 별도로 확인한다.
|
|
50
58
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
네 조건을 채운 다음 major에서 한다.
|
|
59
|
+
정식 배치는 [consumer-policy §3.1](consumer-policy.md#31-배치와-시각-값)을 따른다.
|
|
60
|
+
제거 속성은 타입 오류다. JavaScript 호출도 더 이상 외형을 바꾸지 못하며, host로 나머지 props를
|
|
61
|
+
전달하는 컴포넌트는 제거 속성을 명시적으로 거부한다. 그 외 컴포넌트의 미지정 속성 무시는
|
|
62
|
+
호환 지원을 뜻하지 않는다. 일반 Link 아이콘·Dialog 오류 진단은 `internal/diagnostics.ts`로
|
|
63
|
+
분리해 보존했다.
|
|
57
64
|
|
|
58
|
-
| 컴포넌트 |
|
|
65
|
+
| 컴포넌트 | 제거한 prop | 대체 |
|
|
59
66
|
| --- | --- | --- |
|
|
60
67
|
| IconButton, Link, BottomCTA, Agreement, Asset, AssetGroup, AuthProviderButton, BottomInfo, Carousel, Collapsible, Container, Section, Icon, Steps, Top, UploadItem | `style` | 배치는 `layoutStyle`, 외형은 각 recipe·semantic prop |
|
|
61
68
|
| Heading | `style`(TextStyle) | `layoutStyle`, 크기·굵기는 `level` |
|
|
62
69
|
| Badge, Tag | `style`, `labelStyle` | `layoutStyle`, `tone`/`size`/`variant` |
|
|
63
|
-
| ListRow | `titleStyle`, `descriptionStyle` | `density`·`selected`, listRowRecipe typography |
|
|
70
|
+
| ListRow | `titleStyle`, `descriptionStyle` | `density`·`selected`·`tone="danger"`, listRowRecipe typography |
|
|
64
71
|
| Avatar | `style`, `imageStyle` | `layoutStyle`, `size`/`renderFallback` |
|
|
65
72
|
| Divider, CounterBadge, List, Timeline | `style` | `layoutStyle`, 각 컴포넌트 축 |
|
|
66
73
|
| Accordion | `style`, `itemStyle`, `triggerStyle`, `titleStyle`, `indicatorStyle`, `panelStyle` | `layoutStyle`, `density`/`renderIndicator` |
|
|
67
74
|
| DescriptionList, StatisticGroup | `style`, `itemStyle` | `layoutStyle`, descriptor·`density` |
|
|
68
75
|
| Statistic | `style`, `labelStyle`, `valueStyle`, `affixStyle`, `trendStyle`, `hintStyle` | `layoutStyle`, `density`/`presentation` |
|
|
69
76
|
| Notice, Result, Spinner, Skeleton, Toast | `style` | `layoutStyle`, `tone`/`status`/`size`/`shape`·`width`·`height` |
|
|
70
|
-
| EmptyState | `style`, `illustrationStyle`, `titleStyle`, `descriptionStyle`, `actionStyle` | `layoutStyle`, `density`/`align
|
|
77
|
+
| EmptyState | `style`, `illustrationStyle`, `titleStyle`, `descriptionStyle`, `actionStyle` | `layoutStyle`, `density`/`align`. illustration은 최소 크기와 실제 콘텐츠 크기를 함께 존중 |
|
|
71
78
|
| Progress | `style`, `labelStyle`, `valueStyle`, `trackStyle`, `indicatorStyle` | `layoutStyle`, `tone`/`size`/`shape` |
|
|
72
79
|
| ToastRegion | `style`, `toastStyle` | `layoutStyle`, `placement`/`safeAreaInsets` |
|
|
73
|
-
| AlertDialog, Sheet | `contentStyle`의 배치 밖 key | 배치 key만 사용.
|
|
80
|
+
| AlertDialog, Sheet | `contentStyle`의 배치 밖 key | `HjmCompositionStyleProp` 배치 key만 사용. AlertDialog 크기는 `size="small" | "medium" | "large"` |
|
|
74
81
|
| Tabs | `style`, `tabListStyle` / TabPanel `style` | `layoutStyle`, `size`/`layout`/`overflow`/`appearance` |
|
|
75
82
|
| BottomNavigation | `style`, `surfaceStyle`, `listStyle`, `primaryActionStyle` | `layoutStyle`, `configuration` |
|
|
76
|
-
| TopBar | `style`, `leadingStyle`, `titleStyle`, `trailingStyle`
|
|
83
|
+
| TopBar | `style`, `leadingStyle`, `titleStyle`, `trailingStyle` | `layoutStyle`, `centered`/`labelVisibility` |
|
|
77
84
|
| Menu | `style` | `layoutStyle`, `density` |
|
|
78
85
|
| Checkbox, Radio, CheckboxGroup, RadioGroup | `style`, `controlStyle`, `indicatorStyle`, `leadingStyle`, `contentStyle`, `labelStyle`, `descriptionStyle` | `layoutStyle`(행 또는 그룹), selection control recipe |
|
|
79
86
|
| Switch, SegmentedControl, Form, Select, Combobox, TagsInput, ToggleGroup, DatePicker, FilePicker, TransferList | `style` | `layoutStyle`, 각 컴포넌트 `size`·descriptor |
|
|
@@ -85,9 +92,10 @@ LoadMore의 내부 Button 조합은 비공개 RecipeButton을 써서 recipe의
|
|
|
85
92
|
|
|
86
93
|
제외(정식 host·renderer 스타일): KeyboardAvoiding·KeyboardDock(플랫폼 host), Image·ImageAdapter `style`(renderer 주입),
|
|
87
94
|
EffectSurface·ThinkingOrb·SharedTransition(optional motion host frame), Text·Stack·AspectRatio·Grid·Layout(내부 조합 전반이
|
|
88
|
-
쓰는 layout primitive
|
|
95
|
+
쓰는 layout primitive). TopBar `renderAction`에 주입하는 action appearance의 `style`·`labelStyle`,
|
|
96
|
+
Section 슬롯과 Chip leading/indicator/trailing의 정식 배치 속성도 보존한다.
|
|
89
97
|
|
|
90
|
-
이관:
|
|
98
|
+
이관: 위 표의 호출과 래퍼 전파를 찾아 margin·width·flex·alignSelf만 남긴 값은 `layoutStyle`로 옮기고, 색·글꼴·padding·
|
|
91
99
|
높이·radius는 semantic prop으로 옮긴다. 표현할 축이 없으면 `.hjm-*`·style 우회 대신 계약 공백으로 올린다.
|
|
92
100
|
|
|
93
101
|
## 관리 소비 저장소
|
|
@@ -95,7 +103,12 @@ EffectSurface·ThinkingOrb·SharedTransition(optional motion host frame), Text·
|
|
|
95
103
|
번뚝·다에리·비행중·모펀의 직접 호출과 제품 래퍼를 함께 이관한다. 스핀트·유틸버스·포트폴리오
|
|
96
104
|
사이트·App Release Hub도 새 공개 타입으로 검사한다. 웹과 앱이 있는 제품은 양쪽을 확인한다.
|
|
97
105
|
소스 검사, 새 패키지 설치/lock 갱신, 기기 검증, npm 게시·운영 배포는 별개의 단계다.
|
|
98
|
-
로컬 후보 선언을 연결한 검사만으로 게시된
|
|
106
|
+
로컬 후보 선언을 연결한 검사만으로 게시된 패키지의 소비 설치를 주장하지 않는다.
|
|
107
|
+
|
|
108
|
+
설치된 1.18.0에도 있는 `layoutStyle` 이관은 먼저 적용할 수 있다. 새 `ListRow.tone`과
|
|
109
|
+
`AlertDialog.size`는 후보 패키지에만 있으므로 기존 1.18.0 선언을 캐스트로 우회하지 않는다.
|
|
110
|
+
Utilverse 계정 탈퇴 행과 BurnTok 대화상자 크기 어댑터는 새 패키지 설치·타입검사와 함께
|
|
111
|
+
이관해야 한다. 이 두 호출이 남아 있는 동안 해당 흐름의 로컬 소스 모드를 완료로 보고하지 않는다.
|
|
99
112
|
|
|
100
113
|
## Storybook
|
|
101
114
|
|
|
@@ -172,3 +172,7 @@ existing Avatar. They are optional factories, not new canonical components or
|
|
|
172
172
|
root exports. See the [fallback contract](avatar-fallback.md) for installation,
|
|
173
173
|
source recovery and identity/accessibility rules. This addition does not imply
|
|
174
174
|
that the earlier device evidence covers Blobatar.
|
|
175
|
+
|
|
176
|
+
### 사진 앨범 탐색과 로딩 (2026-10-12)
|
|
177
|
+
|
|
178
|
+
`CarouselMotion`의 선택적 `navigation="counter"`는 이전·현재/전체·다음 한 줄 컨트롤을 Web/Native에 제공한다. 기존 기본 버튼 탐색·유한한 keyed selection·숨겨진 항목의 초점 차단·동작 줄이기 계약은 유지한다. 번뚝의 사진 넘김을 기존 모션 어댑터에 연결하기 위한 표현이며 새 어댑터/peer를 만들지 않는다. `ImageViewer`의 loading 상태는 액자 중앙 Spinner와 접근성 전용 loadingLabel을 사용한다. 제품의 private query·Expo onDisplay·cachePolicy=none은 host 책임이다.
|
package/docs/screen-patterns.md
CHANGED
|
@@ -180,6 +180,10 @@ import { SearchScreen } from "@hjmds/react/screen-flows";
|
|
|
180
180
|
Native는 import만 해당 renderer의 `screen-flows`로 바꾸고 플랫폼별 자식/host를 제공한다.
|
|
181
181
|
React Query 등을 쓰는 제품은 이 화면의 callback을 기존 제품 query 상태와 연결하며 별도 캐시를 만들지 않는다.
|
|
182
182
|
필터 변경은 debounce query 변경과 독립적이므로 제품 query key에 필터도 포함한다.
|
|
183
|
+
|
|
184
|
+
`debounceMs` 기본값은 `searchScreenRecipe.debounceMs`(300ms)이며 양 renderer가
|
|
185
|
+
`resolveSearchDebounceMs`로 해석한다. 0과 유한한 사용자 지연은 유지하고 음수는 기존처럼 0으로
|
|
186
|
+
맞춘다. `NaN`·±`Infinity`는 호스트 타이머마다 다르게 해석될 수 있어 예약 전에 `RangeError`로 거부한다.
|
|
183
187
|
예제 미디어는 로컬 샘플 사진과 모의 업로드이며 기기 갤러리·네트워크 업로드를 실행하지 않는다.
|
|
184
188
|
예제 권한은 상태 분기만 보여 주며 실제 OS 권한을 바꾸지 않는다.
|
|
185
189
|
|
|
@@ -303,7 +307,7 @@ SearchScreen accepts a queryField slot for an existing accessible SearchField wi
|
|
|
303
307
|
| 레일 첫 칩(`filterSheet.trigger`)은 HJM이 그리고 이름에 적용 개수를 넣는다(Web `aria-haspopup="dialog"`) | 적용 칩·모두 해제 뒤 포커스가 돌아갈 고정 대상이 필요하다 | 제품이 trigger를 그림(포커스 복귀 대상을 HJM이 모름) |
|
|
304
308
|
| Web: 적용 칩·최근 검색 행을 지우면 같은 자리 다음 항목, 없으면 trigger(최근 검색은 입력)로 포커스. 목록이 실제로 줄어든 뒤에 옮긴다(`resolveFocusAfterRemoval`). Native는 옮기지 않는다 | 지운 버튼이 사라져 포커스가 `<body>`로 떨어지는 것을 막는다. Native는 프로그램 포커스 이동이 화면을 다시 읽게 해 낭독 커서를 그대로 둔다 | 항상 입력으로 이동(칩 줄 탐색이 끊김) |
|
|
305
309
|
| 개수 낭독은 HJM: 입력 중 "제안 N개", 결과 개수, `searching`이면 `searchingLabel`. Web은 숨긴 `role="status"`, Native는 `announceForAccessibilityWithOptions(queue)`. 문구가 바뀔 때만 | 제품마다 live region을 다시 만들면 중복·누락 낭독이 생긴다 | 제품 소유 |
|
|
306
|
-
| `resultSummary.count === null`이면 결과 머리 개수 자리에 Skeleton, `children` 대신 로딩 행 4개(`searchScreenRecipe.loadingRows`).
|
|
310
|
+
| `resultSummary.count === null`이면 결과 머리 개수 자리에 Skeleton, `children` 대신 로딩 행 4개(`searchScreenRecipe.loadingRows`). 양 renderer는 ListRow `loading`으로 같은 두 줄 행 geometry를 사용하며 첫 행에만 loadingLabel을 제공 | 결과가 도착할 때 목록이 뛰지 않는다 | spinner로 본문 교체(`state="loading"`, 입력·필터·이전 결과가 사라짐) |
|
|
307
311
|
| 정렬은 결과 머리 끝 Menu(single). 바꾸면 본문을 맨 위로 | Menu 지침이 정렬을 용도로 명시. 시트 안 정렬은 정렬 하나에 시트 왕복이 필요 | 필터 시트 안 정렬 |
|
|
308
312
|
| `queryLabelVisibility="hidden"`: 보이는 label을 빼고 `queryLabel`을 접근성 이름(Web `aria-label`, Native `accessibilityLabel`)과 placeholder로 쓴다 | 참고 서비스 공통 모양. 1배 약 22, 2배 약 40만큼 고정 영역을 아낀다(2026-10-06 실측). placeholder가 검색 대상을 알린다(Apple HIG) | placeholder 없이 숨김(보이는 이름이 없는 입력) |
|
|
309
313
|
| `searching`+`searchingLabel`: Web `loading`, Native `busy`+`busyLabel`을 한 이름으로. 둘 다 주거나 둘 다 생략(타입) | 2026-10-06 utilverse 적용 조사: 진행 표시 하나 때문에 제품이 입력을 `queryField`로 통째로 바꿨다 | 플랫폼별 이름 그대로 노출 |
|
|
@@ -387,3 +391,21 @@ CommentThreadScreen의 optional threadHeader는 첫 댓글 앞의 스크롤 콘
|
|
|
387
391
|
모두 같은 본문에 배치하고 상태 교체 시 함께 숨긴다. fixed header는 짧은 탐색 영역, composer는
|
|
388
392
|
고정 작성 영역이다. Spint의 2026-10-08 이중 스크롤 문제 때문에 추가했으며 상세 사용법은
|
|
389
393
|
[댓글 화면](usage/components/comment-thread-screen.md#배치)을 따른다.
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
### 화면별 독립 복구와 첫 행동 (미게시, 1.18.0 이후)
|
|
397
|
+
|
|
398
|
+
2026-10-13 계층 점검에서 빈 채팅의 첫 입력이 사라지고 상세 조회 실패를 제품이 다시 조립해야 하는
|
|
399
|
+
누락을 확인했다. 기존 화면 API를 다음과 같이 보강한다.
|
|
400
|
+
|
|
401
|
+
- `ChatScreen`은 ready뿐 아니라 empty에서도 composer를 유지한다. loading/error/restricted에서는
|
|
402
|
+
입력을 숨긴다. 전송 실패는 ready/empty를 유지하고 notice로 알린다.
|
|
403
|
+
- `ListDetailScreen.detail`에 선택 `state`, `stateAction`, `notice`를 받는다. 상세만 본문 교체 또는
|
|
404
|
+
비차단 실패를 표현하고 숨겨진 목록의 입력·스크롤은 유지한다. 기존 title/content는 호환된다.
|
|
405
|
+
- `OnboardingScreen`은 complete.pending 또는 skip.pending 동안 다음·이전·완료·건너뛰기를
|
|
406
|
+
함께 잠근다. 제품의 입력값과 라우터 이탈 처리는 제품 소유다.
|
|
407
|
+
- `CommentThreadScreen`은 루트마다 전체 items를 재탐색하지 않고 한 번 만든 부모별 인덱스로
|
|
408
|
+
답글을 읽는다. 루트·답글의 서버 순서와 펼침·동작 계약은 유지한다. 가상화 구현은 아니다.
|
|
409
|
+
|
|
410
|
+
검증: 각 renderer의 `screen-recovery` 테스트. Web은 Chromium 동작 검사, Native는 host 렌더 검사이며
|
|
411
|
+
실기기 성능·운영 서버·npm 게시·소비 앱 반영을 뜻하지 않는다.
|
package/docs/toast.md
CHANGED
|
@@ -45,7 +45,7 @@ const result = store.publish({
|
|
|
45
45
|
`accessibilityLabel`에 완전한 이름을 제공합니다.
|
|
46
46
|
- 기본 알림과 리퀴드 알림은 모두 표시 후 3초에 자동 닫힘을 시작합니다. 리퀴드는 진입 연출 동안 타이머를 멈춥니다.
|
|
47
47
|
2026-10-02 사용자 요청으로 기존 5초 기본값·최솟값을 3초로 변경했습니다.
|
|
48
|
-
- action
|
|
48
|
+
- action 또는 press가 있는 Toast는 기본 persistent입니다. 제품이 명시한 `durationMs`도 3000ms보다
|
|
49
49
|
짧아질 수 없으며, `null`은 명시적 persistent입니다.
|
|
50
50
|
|
|
51
51
|
`publish` 결과에는 stable id와 `visible | queued` 위치가 포함됩니다. 호출자는 반환된 함수
|
|
@@ -93,11 +93,50 @@ queued(waiting, 3000) ─ show ─→ visible(running, 3000)
|
|
|
93
93
|
`action` reason으로 닫으며, `dismissOnAction: false`면 알림은 남지만 같은 action은 다시
|
|
94
94
|
실행되지 않습니다. stable id update는 새 revision이므로 새 action을 한 번 실행할 수 있습니다.
|
|
95
95
|
|
|
96
|
-
`timeout | action | close-action | escape | swipe | programmatic | queue-overflow | interrupted`
|
|
96
|
+
`timeout | action | press | close-action | escape | swipe | programmatic | queue-overflow | interrupted`
|
|
97
97
|
reason 중 하나만 최종 `onDismiss`로 전달됩니다. visible Toast는 exit 완료 시 callback을
|
|
98
98
|
정산하고 queued overflow와 provider teardown은 visual exit 없이 즉시 정산합니다. 중복 action,
|
|
99
99
|
close, exit complete와 두 번째 provider dispose는 아무 상태도 바꾸지 않습니다.
|
|
100
100
|
|
|
101
|
+
## 카드 전체 활성화 — 2026-10-13 (미게시)
|
|
102
|
+
|
|
103
|
+
댓글·답장 알림에서 카드 본문을 눌러 관련 화면으로 이동하도록 `press`를 추가했다.
|
|
104
|
+
기존 `action`은 보이는 실행 버튼, `press`는 카드의 본문·미디어·여백을 누르는 동작이다.
|
|
105
|
+
별도 알림 컴포넌트를 만들지 않고 동일 Toast descriptor/session/store에 연결한다.
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
store.publish({
|
|
109
|
+
id: "reply:42",
|
|
110
|
+
title: t("reply.receivedTitle"),
|
|
111
|
+
description: t("reply.receivedBody"),
|
|
112
|
+
closeLabel: t("common.closeNotification"),
|
|
113
|
+
press: { accessibilityLabel: t("reply.open"), onPress: openReply },
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
참조 분석: MIT [expo-dynamic-notifications `use-dismiss-gesture.ts` @ 5de059a](https://github.com/rit3zh/expo-dynamic-notifications/blob/5de059a5cbefbe28c14efbe785166665a7c70bc5/src/hooks/use-dismiss-gesture.ts)는
|
|
118
|
+
`Gesture.Exclusive(pan, tap)`으로 입력을 나누고 성공한 탭에서 콜백 후 dismiss를 예약한다.
|
|
119
|
+
HJM은 그 동작 순서를 독립 구현한다. Native 표준/리퀴드와 Web이 같은 순수 session을 사용하며,
|
|
120
|
+
이미 존재하는 큐·타이머를 교체하거나 optional gesture 의존성을 표준 Toast에 추가하지 않는다.
|
|
121
|
+
|
|
122
|
+
- `press.accessibilityLabel`과 `press.onPress`는 필수. 라우팅과 문구는 제품 소유다.
|
|
123
|
+
- 카드·실행·닫기는 형제 조작이다. Web의 실제 button은 Tab·Enter·Space와 포커스 표시를 제공한다.
|
|
124
|
+
Native는 독립 Pressable과 읽을 수 있는 이름/설명을 제공하고, 리퀴드의 상위 swipe responder가 탭을 취소한다.
|
|
125
|
+
- `invokePress`는 visible revision당 한 번 실행하고 콜백 뒤 `press` 사유로 닫는다.
|
|
126
|
+
action/press의 재진입과 이미 닫히는 카드의 입력은 무시한다. 콜백이 같은 id를 새 revision으로 갱신하면
|
|
127
|
+
새 내용을 닫지 않으며, provider가 제거되면 기존 `interrupted` 정산을 보존한다.
|
|
128
|
+
- 동기 콜백이 throw해도 닫힘을 시작하고 오류를 호출자에게 전달한다. 비동기 라우팅/요청 완료는 기다리지 않는다.
|
|
129
|
+
- press가 있으면 기본 persistent, 명시적 duration은 기존 3초 하한을 적용한다. press가 없으면 기존 동작 그대로다.
|
|
130
|
+
- 검증 파일: `test/toast-press.test.ts`(contracts), `packages/react/test/toast-press.browser.test.tsx`,
|
|
131
|
+
`packages/react-native/test/toast-press.test.tsx`, `packages/react-native/test/toast-liquid.test.tsx`.
|
|
132
|
+
Native host 테스트는 실제 기기 hit-test·스크린리더 검증이나 소비 앱 적용 증거가 아니다.
|
|
133
|
+
|
|
134
|
+
검증: 계약 41개, Web Chromium 11개, Native host 20개의 관련 테스트 통과.
|
|
135
|
+
세 패키지와 두 Showcase 타입 검사, 세 패키지 빌드 및 Web light/dark 기본 글자 화면을 확인했다.
|
|
136
|
+
전체 회귀·실기기·npm 게시·소비 앱 적용은 미실행. `usage:sync`는 기존 다른 작업의
|
|
137
|
+
`components/carousel.md`·`components/chat-message.md` 절 형식 2건으로 실패했으며 해당 변경은 보존했다.
|
|
138
|
+
공개 API 이름 대응표는 변경 없이 검사 통과했다.
|
|
139
|
+
|
|
101
140
|
## Renderer acceptance
|
|
102
141
|
|
|
103
142
|
### Compact Web layout — 2026-09-15
|
|
@@ -169,6 +208,29 @@ overflow와 update를 검증합니다.
|
|
|
169
208
|
- [Radix Toast](https://www.radix-ui.com/primitives/docs/components/toast)
|
|
170
209
|
- [React Spectrum Toast](https://react-spectrum.adobe.com/Toast)
|
|
171
210
|
|
|
211
|
+
## 패널 Toast — 미게시(1.17.2 이후)
|
|
212
|
+
|
|
213
|
+
2026-10-10 사용자 요청("칩이랑 패널 디자인시스템에 넣고 … 패널은 디자인 시스템에 있는 토스트를 대체하고 리퀴드
|
|
214
|
+
토스트의 토스트도 대체해 — 패널이 토스트가 되는거지")으로 BurnTok이 검수 상태용으로 만든 패널을 Toast 자체의
|
|
215
|
+
모양으로 삼습니다. 별도 `Panel` API를 만들지 않은 이유: 같은 id 갱신·지속·닫기·낭독·큐를 Toast store가 이미
|
|
216
|
+
소유하고, 두 번째 떠 있는 층을 만들면 큐와 낭독이 둘이 됩니다.
|
|
217
|
+
|
|
218
|
+
- 모양: 모든 Toast의 모서리는 `xl`(24)입니다. Native 리퀴드 카드도 같은 패널 열(미디어/배지 · 문구 · 닫기)을
|
|
219
|
+
그리고, 프로필이 없을 때의 리퀴드 모서리도 12 → 24로 바뀝니다. 리퀴드의 투명 chrome·물방울 연출은 유지합니다.
|
|
220
|
+
- `media?: unknown`: 제품 마스코트·아바타 같은 장식 시각물입니다. core는 검사하지 않고 그대로 넘기며
|
|
221
|
+
(`ResolvedToastDescriptor.media`, 없으면 `null`), renderer는 ReactNode로 그려 tone badge 자리(44, `toastRecipe.media.size`)를
|
|
222
|
+
대신하고 보조기술에서 숨깁니다. tone은 `data-tone`과 문구가 계속 전달합니다. renderer 전용 prop을 버린 이유는
|
|
223
|
+
store가 descriptor를 해석·보관하므로 그 밖의 값은 갱신 때 사라지기 때문입니다.
|
|
224
|
+
- `progress?: { steps: readonly string[]; current: number }`: 실행 중인 작업 단계입니다. 단계는 2~5개의 비어 있지 않은
|
|
225
|
+
현지화 문자열이고(320 폭에서 한 줄 유지가 목표, 넘치면 줄바꿈) `current`는 0부터 시작하는 실행 단계 index입니다.
|
|
226
|
+
앞 단계는 완료로 그립니다. 기본 announcement는 `title. description. <현재 단계>`입니다.
|
|
227
|
+
점은 장식이고 단계 이름이 옆에 있어 색만으로 상태를 전달하지 않습니다(Web은 `ol`과 `aria-current="step"`).
|
|
228
|
+
- action은 둘째 줄 끝이 아니라 **문구 아래 시작 쪽**(`toastRecipe.action.align = "start"`)입니다. 눈이 이미 있는 자리에
|
|
229
|
+
둔다는 BurnTok 패널 배치를 따랐습니다. pill 모양·44 target·대비는 1.10.0 그대로입니다.
|
|
230
|
+
- 작업 상태 패널은 `id` 고정 + `durationMs: null`로 열고, 단계·결과가 바뀔 때 같은 id로 다시 publish해 제자리에서
|
|
231
|
+
갱신합니다. 여닫는 트리거는 [`ActivityChip`](activity-chip.md), 흐름은
|
|
232
|
+
[백그라운드 작업 상태 구성](usage/compositions/activity-status.md)입니다.
|
|
233
|
+
|
|
172
234
|
## 프로필 행간 소비 — 미게시
|
|
173
235
|
|
|
174
236
|
2026-10-07 소비 감사에서 Web 제목/설명의 1.35/1.45 고정 행간이 `typography.body.lineHeight`를
|