@hjmds/design-contracts 1.18.0 → 1.20.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/behaviors.d.ts +8 -6
- package/dist/behaviors.d.ts.map +1 -1
- package/dist/behaviors.js +4 -3
- package/dist/behaviors.js.map +1 -1
- package/dist/bottom-navigation.d.ts +14 -0
- package/dist/bottom-navigation.d.ts.map +1 -1
- package/dist/bottom-navigation.js +21 -0
- package/dist/bottom-navigation.js.map +1 -1
- package/dist/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 +61 -0
- package/dist/catalog.d.ts.map +1 -1
- package/dist/component-recipes.d.ts +67 -0
- package/dist/component-recipes.d.ts.map +1 -1
- package/dist/component-recipes.js +27 -1
- package/dist/component-recipes.js.map +1 -1
- package/dist/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/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/screen-patterns.d.ts +4 -0
- package/dist/screen-patterns.d.ts.map +1 -1
- package/dist/screen-patterns.js +12 -3
- package/dist/screen-patterns.js.map +1 -1
- package/dist/semantic-colors.d.ts +9 -0
- package/dist/semantic-colors.d.ts.map +1 -1
- package/dist/semantic-colors.js +5 -0
- package/dist/semantic-colors.js.map +1 -1
- package/dist/toast.d.ts +10 -1
- package/dist/toast.d.ts.map +1 -1
- package/dist/toast.js +43 -2
- 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/asset.md +7 -0
- package/docs/bottom-navigation.md +22 -0
- 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 +41 -2
- package/docs/usage/README.md +248 -245
- 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/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 +30 -6
- package/docs/usage/components/button.md +2 -2
- package/docs/usage/components/card.md +1 -1
- package/docs/usage/components/carousel.md +12 -4
- package/docs/usage/components/chat-message.md +6 -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 +2 -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 +3 -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 +11 -49
- 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 +2 -3
- package/docs/usage/components/text.md +85 -4
- package/docs/usage/components/timeline.md +2 -2
- package/docs/usage/components/toast.md +17 -7
- 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 +11 -5
- 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 +1 -1
|
@@ -95,7 +95,7 @@ import { Notice } from "@hjmds/react-native/feedback";
|
|
|
95
95
|
## 꼭 지킬 것
|
|
96
96
|
|
|
97
97
|
- 제목·설명·행동 문구는 i18n 키로 넣는다. 아이콘은 제품 소유 자산이고 색은 tone이 정한다.
|
|
98
|
-
- 배치는 `layoutStyle`로만 한다. 색·padding·radius를 `style`/`className`으로 덮지 않는다. Native `style`은
|
|
98
|
+
- 배치는 `layoutStyle`로만 한다. 색·padding·radius를 `style`/`className`으로 덮지 않는다. Native `style`은 제거된 속성이다.
|
|
99
99
|
- 같은 화면에 같은 내용의 Notice와 Toast를 동시에 띄우지 않는다.
|
|
100
100
|
|
|
101
101
|
## 플랫폼 차이
|
|
@@ -105,7 +105,7 @@ import { Notice } from "@hjmds/react-native/feedback";
|
|
|
105
105
|
| 발표 | 항상 live region. `danger`는 `role="alert"`+assertive, 나머지는 `role="status"`+polite | `announcement`: `none`(기본) · `polite` · `assertive`. 지정해야 발표한다 |
|
|
106
106
|
| title/description 타입 | `ReactNode` | `string` |
|
|
107
107
|
| 아이콘 렌더 함수 | 없음 | `renderIcon` |
|
|
108
|
-
| 배치 | `className`, `layoutStyle`(HTML `style`도 받음) | `layoutStyle`(`style`은
|
|
108
|
+
| 배치 | `className`, `layoutStyle`(HTML `style`도 받음) | `layoutStyle`(`style`은 제거된 속성) |
|
|
109
109
|
|
|
110
110
|
## 함정
|
|
111
111
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
- 단계: 컴포넌트
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
|
-
- 적용:
|
|
6
|
+
- 적용: 1.17.1
|
|
7
7
|
- 검토일: 2026-10-06
|
|
8
8
|
- 근거: [반복 화면 조합](../../screen-patterns.md), Web·Native `src/screens.tsx`·`src/screen-flows.tsx`; 기존 개별 지침을 새 규격으로 통합. 예제 스토리는 2026-10-06 사용자 승인으로 스토리북 배포([승인 기록](../../../../../docs/STORYBOOK_NAVIGATION.md#21-2026-10-06-전체-승격과-규격-확정)). 스토리북 배포는 API 게시가 아니다(`적용` 참고)
|
|
9
9
|
- 스토리북: `배포/화면/소통/알림함`
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
- 단계: 컴포넌트
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
|
-
- 적용:
|
|
6
|
+
- 적용: 1.17.1
|
|
7
7
|
- 검토일: 2026-10-06
|
|
8
8
|
- 근거: [반복 화면 조합](../../screen-patterns.md), Web·Native `src/screens.tsx`·`src/screen-flows.tsx`; 기존 개별 지침을 새 규격으로 통합. 예제 스토리는 2026-10-06 사용자 승인으로 스토리북 배포([승인 기록](../../../../../docs/STORYBOOK_NAVIGATION.md#21-2026-10-06-전체-승격과-규격-확정)). 스토리북 배포는 API 게시가 아니다(`적용` 참고)
|
|
9
9
|
- 스토리북: `배포/구성/정보 표시/알림 항목`, `배포/화면/소통/알림함`
|
|
@@ -95,4 +95,4 @@ import { NotificationItem } from "@hjmds/react-native/screens";
|
|
|
95
95
|
| 상태·시각 줄 | 설명 아래 caption `Text` | `description`과 줄바꿈(`\n`)으로 합친 한 문자열 |
|
|
96
96
|
| 이동 | `href`, `onClick` | `onPress` |
|
|
97
97
|
| 추가 슬롯 | `className`, `layoutStyle` | `titleMetadata`, `trailingAction`, `trailingText`, `layoutStyle` |
|
|
98
|
-
| 제목 굵기 조정 | `Text emphasis` | 렌더러 비공개 입력(`hjmTitleEmphasis`)으로 안 읽음 700(`fontWeight.bold`)·읽음 400(`fontWeight.regular`).
|
|
98
|
+
| 제목 굵기 조정 | `Text emphasis` | 렌더러 비공개 입력(`hjmTitleEmphasis`)으로 안 읽음 700(`fontWeight.bold`)·읽음 400(`fontWeight.regular`). 제거된 `ListRow.titleStyle`을 사용하지 않는다. `NotificationItemProps`에는 `titleStyle`이 없다(1.13.0 변경) |
|
|
@@ -120,7 +120,7 @@ Native는 제품 프로필의 `tokens.fontFamily.ui`를 실제 텍스트/입력
|
|
|
120
120
|
- 단위·통화·소수 자릿수 표시는 만들지 않는다. 보조기기용 문구가 필요하면 `getValueText`로 제품이 포맷한다.
|
|
121
121
|
- 제어형과 비제어형을 렌더 사이에 바꾸지 않는다(`value`를 넣었다 뺐다 하면 던진다).
|
|
122
122
|
- `min ≥ max`, `step ≤ 0`, 범위 밖 `value`는 던진다. DurationField도 범위 밖·정수 아닌 초를 던진다.
|
|
123
|
-
- 색·높이를 덮지 않는다. 배치는 `layoutStyle`로 한다. Native `inputStyle`·`containerStyle`은
|
|
123
|
+
- 색·높이를 덮지 않는다. 배치는 `layoutStyle`로 한다. Native `inputStyle`·`containerStyle`은 제거된 속성 — 높이·글꼴은 `size`, 배치는 `layoutStyle`.
|
|
124
124
|
|
|
125
125
|
## 플랫폼 차이
|
|
126
126
|
|
|
@@ -129,5 +129,5 @@ Native는 제품 프로필의 `tokens.fontFamily.ui`를 실제 텍스트/입력
|
|
|
129
129
|
| 역할 | `spinbutton`, `type="text"` | 입력 + 증감 button, accessibility action |
|
|
130
130
|
| label·description·error 타입 | `ReactNode` | `string` |
|
|
131
131
|
| 추가 이름 | 없음 | `accessibilityLabel`, `accessibilityHint` |
|
|
132
|
-
| 클래스·스타일 | `className`, `inputClassName`, `layoutStyle`(필드 전체). `style`은 안쪽 input | `layoutStyle`(필드 전체). `inputStyle`·`containerStyle`은
|
|
133
|
-
| DurationField 배치 | `className`, `layoutStyle`(fieldset) | `layoutStyle`(
|
|
132
|
+
| 클래스·스타일 | `className`, `inputClassName`, `layoutStyle`(필드 전체). `style`은 안쪽 input | `layoutStyle`(필드 전체). `inputStyle`·`containerStyle`은 제거된 속성 |
|
|
133
|
+
| DurationField 배치 | `className`, `layoutStyle`(fieldset) | `layoutStyle`(1.13.0 변경, 1.12.1은 감싸는 View) |
|
|
@@ -97,5 +97,5 @@ import { OtpField } from "@hjmds/react-native/otp-field";
|
|
|
97
97
|
| 항목 | Web | Native |
|
|
98
98
|
| --- | --- | --- |
|
|
99
99
|
| 이름 | `label` | `label` 또는 `accessibilityLabel`만 |
|
|
100
|
-
| 칸 스타일 통로 | 없음 | `slotStyle`, `slotTextStyle`은
|
|
100
|
+
| 칸 스타일 통로 | 없음 | `slotStyle`, `slotTextStyle`은 제거된 속성. 외형은 `size`·`presentation` |
|
|
101
101
|
| busy 표현 | read-only + `aria-busy` | `editable={false}` + `accessibilityState.busy` |
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
같은 데이터와 기능을 유지하면서 테마별 행·카드·격자와 도구 배치를 선택하는 목록 화면에 쓴다.
|
|
14
14
|
|
|
15
|
-
기본 공개 API는 npm 1.15.0에 있다.
|
|
15
|
+
기본 공개 API는 npm 1.15.0에 있다. 글자 역할·종이 줄 간격·토큰 소비 개선은 1.16.0 변경이다. 실제 설치 버전과 기기 검증은 별도로 확인한다.
|
|
16
16
|
|
|
17
17
|
## 쓰지 않을 때
|
|
18
18
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
- 단계: 컴포넌트
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
|
-
- 적용:
|
|
6
|
+
- 적용: 1.17.1
|
|
7
7
|
- 검토일: 2026-10-06
|
|
8
8
|
- 근거: [반복 화면 조합](../../screen-patterns.md), Web·Native `src/screens.tsx`·`src/screen-flows.tsx`; 기존 개별 지침을 새 규격으로 통합. 예제 스토리는 2026-10-06 사용자 승인으로 스토리북 배포([승인 기록](../../../../../docs/STORYBOOK_NAVIGATION.md#21-2026-10-06-전체-승격과-규격-확정)). 스토리북 배포는 API 게시가 아니다(`적용` 참고)
|
|
9
9
|
- 스토리북: `배포/화면/소개/권한 안내`
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
- 단계: 컴포넌트
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
|
-
- 적용:
|
|
6
|
+
- 적용: 1.17.1
|
|
7
7
|
- 검토일: 2026-10-06
|
|
8
8
|
- 근거: [반복 화면 조합](../../screen-patterns.md), Web·Native `src/screens.tsx`·`src/screen-flows.tsx`; 기존 개별 지침을 새 규격으로 통합. 예제 스토리는 2026-10-06 사용자 승인으로 스토리북 배포([승인 기록](../../../../../docs/STORYBOOK_NAVIGATION.md#21-2026-10-06-전체-승격과-규격-확정)). 스토리북 배포는 API 게시가 아니다(`적용` 참고)
|
|
9
9
|
- 스토리북: `배포/구성/선택과 필터/사진 촬영과 앨범 선택`
|
|
@@ -63,7 +63,7 @@ Native 예는 없다(renderer 없음).
|
|
|
63
63
|
| `dismissPolicy`(부분 지정) | `{ dismissible?, outsideDismiss?, escapeDismiss?, focusOutDismiss? }`(`boolean`) | 모두 `true` | |
|
|
64
64
|
| `open` · `defaultOpen` | `boolean` | 비제어 `false` | 제어하면 `onOpenChange` 필수 |
|
|
65
65
|
| `onOpenChange` | `(open: boolean, details: { reason }) => void` | — | `reason`: `trigger` · `close-action` · `outside-pointer` · `outside-focus` · `escape` · `programmatic` |
|
|
66
|
-
| `motionOrigin` | `TransitionRect` | — |
|
|
66
|
+
| `motionOrigin` | `TransitionRect` | — | 1.14.0 추가: 열기 직전 viewport 좌표. 위치 확정 뒤 공간 전환하며 기존 비모달 초점·닫기 정책 유지 |
|
|
67
67
|
| `initialFocusRef` | `RefObject<HTMLElement \| null>` | 첫 포커스 가능 요소 | 열릴 때 처음 포커스 |
|
|
68
68
|
| `portalContainer` | `HTMLElement` | `document.body` | 표면을 붙일 곳 |
|
|
69
69
|
| `className` | 문자열 | — | `layoutStyle`은 받지 않는다(아래 함정) |
|
|
@@ -113,7 +113,7 @@ Native 예는 없다(renderer 없음).
|
|
|
113
113
|
- 초안은 Popover 위의 제품 상태에 둔다. 종료 후 portal이 제거되므로 내부 비제어 입력에만 두면 사라진다.
|
|
114
114
|
- 공간 전환 실험은 [버튼에서 이어지는 편집](../compositions/origin-dialog.md)의 Web 전용 변형이다.
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
1.15.0 변경: 가장 가까운 프로필의 `shadow.floating`을 열린 portal에도 상속한다. 프로필이 없으면 기존 recipe 그림자를 유지한다. 초안과 비모달 초점/닫기 계약은 그대로이며 Native는 기존 Sheet 경로를 쓴다.
|
|
117
117
|
|
|
118
118
|
[Motion 세 편집 예제 검토](../../../../../docs/qa/2026-10-07-motion-reference-page-review.md)에서
|
|
119
119
|
aria-modal 표시와 실제 초점 경계가 다르고, 닫기 후 defaultValue 편집이 초기화되는 것을 확인했다.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
- 단계: 컴포넌트
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
|
-
- 적용:
|
|
6
|
+
- 적용: 1.17.1
|
|
7
7
|
- 검토일: 2026-10-06
|
|
8
8
|
- 근거: [반복 화면 조합](../../screen-patterns.md), Web·Native `src/screens.tsx`·`src/screen-flows.tsx`; 기존 개별 지침을 새 규격으로 통합. 예제 스토리는 2026-10-06 사용자 승인으로 스토리북 배포([승인 기록](../../../../../docs/STORYBOOK_NAVIGATION.md#21-2026-10-06-전체-승격과-규격-확정)). 스토리북 배포는 API 게시가 아니다(`적용` 참고)
|
|
9
9
|
- 스토리북: `배포/화면/계정/프로필`
|
|
@@ -104,7 +104,7 @@ linear circular (Web) circular (Native)
|
|
|
104
104
|
`max ≤ 0`, 범위 밖 `value`는 던진다.
|
|
105
105
|
- 이름은 지역화한 `label`로 준다. Native는 보이는 label 없이 `accessibilityLabel`만 줄 수도 있다(`ScrollProgress`는 `label` 필수).
|
|
106
106
|
- 색은 `tone`, 두께는 `size`로만 바꾸고 배치는 `layoutStyle`로 한다. Native의 `style`·`labelStyle`·`valueStyle`·`trackStyle`·`indicatorStyle`은
|
|
107
|
-
|
|
107
|
+
제거된 속성이다.
|
|
108
108
|
- `ScrollProgress`는 window에 자동으로 붙지 않는다. Web은 스크롤 host를, Native는 측정값을 반드시 넘긴다.
|
|
109
109
|
- 작업 완료율에는 `ScrollProgress`가 아니라 `Progress`를 쓴다.
|
|
110
110
|
|
|
@@ -125,7 +125,7 @@ linear circular (Web) circular (Native)
|
|
|
125
125
|
|
|
126
126
|
2026-10-07 레퍼런스 조사에서 끝까지 스크롤한 마지막 행도 블러에 가려지는 문제를 확인했다.
|
|
127
127
|
새 `resolveScrollEdges`는 같은 `ScrollMetrics`에서 논리적 이전/다음 콘텐츠 존재 여부를 계산한다.
|
|
128
|
-
|
|
128
|
+
1.14.0부터 `/scroll-progress` subpath에서 제공한다. 블러 renderer 자체를 제공한다는 뜻은 아니다.
|
|
129
129
|
|
|
130
130
|
```ts
|
|
131
131
|
import { resolveScrollEdges } from "@hjmds/design-contracts/scroll-progress";
|
|
@@ -76,7 +76,7 @@ import { spacing } from "@hjmds/design-contracts/foundations";
|
|
|
76
76
|
| `fallback` | `ReactNode` | 필수 | QR 아래에 그려지는 대체 행동(`null`·`false`면 `TypeError`) |
|
|
77
77
|
| `size` | 숫자(px) | `192` | 실제 크기는 모듈 수의 정수배로 내림된다. 모듈당 2px 미만이면 `TypeError` |
|
|
78
78
|
| `level` | `L` · `M` · `Q` · `H` | `M` | 오류 정정 수준 |
|
|
79
|
-
| `layoutStyle` | 배치 전용 style 객체 | — | 루트 배치만(Native는
|
|
79
|
+
| `layoutStyle` | 배치 전용 style 객체 | — | 루트 배치만(Native는 1.13.0 변경) |
|
|
80
80
|
|
|
81
81
|
콜백은 없다. `style`·`className`은 두 renderer 모두 없다. 1.12.1 Native는 `layoutStyle`이 없어 감싸는 레이아웃에서 배치한다.
|
|
82
82
|
|
|
@@ -117,6 +117,6 @@ import { spacing } from "@hjmds/design-contracts/foundations";
|
|
|
117
117
|
| --- | --- | --- |
|
|
118
118
|
| 그리기 | 인라인 `<svg role="img">` | `react-native-svg`, 감싼 `View`가 `accessibilityRole="image"` |
|
|
119
119
|
| 필요한 peer | `qrcode-generator` | `qrcode-generator`, `react-native-svg` |
|
|
120
|
-
| 배치 | `layoutStyle` | `layoutStyle`(
|
|
120
|
+
| 배치 | `layoutStyle` | `layoutStyle`(1.13.0 변경, 1.12.1은 감싸는 View) |
|
|
121
121
|
|
|
122
122
|
- 2026-10-06 독립 재구현에서 QRCode 바깥 Stack의 gap으로 내부 QR–fallback 간격을 바꿀 수 없음을 확인해 슬롯 안 여백 예제로 수정했다.
|
|
@@ -108,8 +108,7 @@ card(vertical) grouped(vertical)
|
|
|
108
108
|
`value`/`defaultValue`가 items에 없으면 `RangeError`를 던진다. 서버 목록은 정리한 뒤 넘긴다.
|
|
109
109
|
- 옛 Native `options` prop은 1.11에서 제거됐다. 넘기면 `TypeError`다([이관표](../../migration-native-legacy-removal.md)).
|
|
110
110
|
- 오류 문구는 `error`로 넘긴다. 그룹 아래에 별도 Text로 직접 그리지 않는다.
|
|
111
|
-
- 배치는 `layoutStyle`로 한다. Native의 `style`과 slot style(`controlStyle`·`indicatorStyle`·`labelStyle` 등)은
|
|
112
|
-
(개발 모드 경고, 다음 major 제거)다([소비 정책 §3.1](../../consumer-policy.md)). 외형은 `presentation`·`size`·`renderIndicator`로 바꾼다.
|
|
111
|
+
- 배치는 `layoutStyle`로 한다. Native의 `style`과 slot style(`controlStyle`·`indicatorStyle`·`labelStyle` 등)은 제거된 속성이다([소비 정책 §3.1](../../consumer-policy.md)). 외형은 `presentation`·`size`·`renderIndicator`로 바꾼다.
|
|
113
112
|
|
|
114
113
|
## 플랫폼 차이
|
|
115
114
|
|
|
@@ -88,8 +88,7 @@ import { Radio } from "@hjmds/react-native/inputs";
|
|
|
88
88
|
- 묶음의 접근성 이름(fieldset/radiogroup)은 Radio가 만들지 않는다. 단독 Radio 여러 개로 묶음을
|
|
89
89
|
흉내 내지 말고 RadioGroup을 쓴다.
|
|
90
90
|
- 선택 표시는 indicator(dot)가 맡는다. 색만으로 선택을 알리도록 바꾸지 않는다.
|
|
91
|
-
- 배치는 `layoutStyle`로 한다. Native의 `style`·`controlStyle`·`labelStyle` 등 slot style은
|
|
92
|
-
다음 major 제거)다. 색·글자·radius·높이를 덮지 않는다([소비 정책 §3.1](../../consumer-policy.md)).
|
|
91
|
+
- 배치는 `layoutStyle`로 한다. Native의 `style`·`controlStyle`·`labelStyle` 등 slot style은 제거된 속성이다. 색·글자·radius·높이를 덮지 않는다([소비 정책 §3.1](../../consumer-policy.md)).
|
|
93
92
|
|
|
94
93
|
## 플랫폼 차이
|
|
95
94
|
|
|
@@ -113,4 +113,4 @@ import { Result } from "@hjmds/react-native/feedback";
|
|
|
113
113
|
| 아이콘 | `icon`(ReactNode) | `renderIcon({ status, color, backgroundColor })` |
|
|
114
114
|
| 제목 heading 수준 | `headingLevel` | `accessibilityRole="header"` 고정 |
|
|
115
115
|
| 실패 알림 | `role="alert"`(그 외 `status`) | assertive live region, iOS는 `announceForAccessibility` |
|
|
116
|
-
| 바깥 배치 | `className`, `layoutStyle`(HTML `style`도 받음) | `layoutStyle`(`style`은
|
|
116
|
+
| 바깥 배치 | `className`, `layoutStyle`(HTML `style`도 받음) | `layoutStyle`(`style`은 제거된 속성) |
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
- 단계: 컴포넌트
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
|
-
- 적용:
|
|
6
|
+
- 적용: 1.17.1
|
|
7
7
|
- 검토일: 2026-10-07
|
|
8
8
|
- 근거: [반복 화면 계약](../../screen-patterns.md); 저장한 항목을 Instagram의 컬렉션 탐색 방식으로 바꾸라는 사용자 요청. 기존 ListDetailScreen·Grid를 합성하며 별도 저장 엔진은 만들지 않는다. 예제 스토리는 2026-10-06 사용자 승인으로 스토리북 배포([승인 기록](../../../../../docs/STORYBOOK_NAVIGATION.md#21-2026-10-06-전체-승격과-규격-확정)). 스토리북 배포는 API 게시가 아니다(`적용` 참고)
|
|
9
9
|
- 스토리북: `배포/화면/콘텐츠/저장한 항목`
|
|
@@ -87,7 +87,7 @@ import { SavedItemsScreen } from "@hjmds/react-native/saved-items";
|
|
|
87
87
|
| actions · leading | ScreenLayout 상속 | 없음 | 홈에서는 제품 `actions` 대신 컬렉션 만들기 버튼이 그 자리를 쓰고 제품 `leading`은 유지된다. 컬렉션·상세에서는 `leading`이 뒤로 버튼이 되고 제품 `actions`가 보인다 |
|
|
88
88
|
| renderThumbnail · renderDetail | `(item) => ReactNode`, 필수 | — | 사진·상세 슬롯, API·자산은 제품 소유 |
|
|
89
89
|
| state · notice | ScreenLayout 상속 | ready · 없음 | 조회 상태, 저장 해제/복구 안내 |
|
|
90
|
-
| layoutStyle | `HjmCompositionStyleProp` | 없음 | Web·Native 모두 목록·상세를 담는 ListDetailScreen 바깥 틀에 적용한다(컬렉션·격자·상세 전환과 상관없이 같은 루트).
|
|
90
|
+
| layoutStyle | `HjmCompositionStyleProp` | 없음 | Web·Native 모두 목록·상세를 담는 ListDetailScreen 바깥 틀에 적용한다(컬렉션·격자·상세 전환과 상관없이 같은 루트). 1.13.0 변경 |
|
|
91
91
|
| className(Web) | `string` | 없음 | 안쪽 목록 ScreenLayout에 붙는다 |
|
|
92
92
|
|
|
93
93
|
## 배치
|
|
@@ -126,3 +126,5 @@ Native collection cover의 모서리는 Provider의 `tokens.radius.md`다. 저
|
|
|
126
126
|
|
|
127
127
|
- 비공개 안내는 권한 구현이 아니다. 서버에서 소유자 접근을 검사한다.
|
|
128
128
|
- HTML/WebView나 Instagram 자산을 복사하는 구현이 아니다. 제품 사진·테마·문구를 슬롯으로 전달한다.
|
|
129
|
+
|
|
130
|
+
미게시(1.18.0 이후): 선택한 컬렉션의 항목이 0개면 별도 Text 행 대신 ListDetailScreen의 empty 상태를 사용해 남은 본문 중앙에 안내한다. 명시한 loading/error/restricted가 우선하고 컬렉션 개요는 ready를 유지한다. 커버는 그룹별로 한 번 계산하며 기존 items 순서의 첫 네 항목을 사용한다.
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
- 단계: 컴포넌트
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
|
-
- 적용:
|
|
7
|
-
- 검토일: 2026-10-
|
|
6
|
+
- 적용: 1.17.1
|
|
7
|
+
- 검토일: 2026-10-13
|
|
8
8
|
- 근거: [반복 화면 조합](../../screen-patterns.md), Web·Native `src/screens.tsx`·`src/screen-flows.tsx`; 기존 개별 지침을 새 규격으로 통합. 예제 스토리는 2026-10-06 사용자 승인으로 스토리북 배포([승인 기록](../../../../../docs/STORYBOOK_NAVIGATION.md#21-2026-10-06-전체-승격과-규격-확정)). 스토리북 배포는 API 게시가 아니다(`적용` 참고)
|
|
9
9
|
- 스토리북: `배포/화면/화면 틀과 도구/화면 골격과 상태`
|
|
10
10
|
|
|
@@ -79,7 +79,7 @@ import { ScreenLayout } from "@hjmds/react-native/screens";
|
|
|
79
79
|
| `stateAction` | `ReactNode` | 없음 | 상태 안내 아래 행동(재시도 등) |
|
|
80
80
|
| `scroll` | `"screen"` · `"content"` | `"screen"` | `content`는 본문 자식(가상화 목록)이 스크롤을 소유한다. 상태 교체 중에는 `screen`으로 돌아간다 |
|
|
81
81
|
| `contentInset` | `"default"` · `"none"` | `"default"` | `none`은 헤더·notice·본문·footer padding을 0으로(Native는 footer 위 테두리도 뺀다) |
|
|
82
|
-
| `presentation` | `"dashboard"` · `"editorial"` · `"landscape"` | 가장 가까운 profile.screens.overview / 없으면 기존 골격 |
|
|
82
|
+
| `presentation` | `"dashboard"` · `"editorial"` · `"landscape"` | 가장 가까운 profile.screens.overview / 없으면 기존 골격 | [디자인 프로필](../../design-profile.md)의 제공 범위를 따른다. 명시값이 프로필을 이긴다. 헤더 배치·읽기 폭만 바꾸고 상태·입력·행동 슬롯은 유지한다 |
|
|
83
83
|
| `as` (Web) | `"main"` · `"section"` | `"main"` | 제품 셸에 이미 `<main>`이 있으면 `section` |
|
|
84
84
|
| `layoutStyle` | `HjmCompositionStyleProp` | 없음 | 화면 루트 배치 전용(예: 분할 화면의 `flex`·`width`). ScreenLayout 위에 만든 화면은 모두 이 prop을 루트까지 넘긴다 |
|
|
85
85
|
| `className` (Web) | `string` | 없음 | 식별·배치 보조. 색·여백을 덮지 않는다 |
|
|
@@ -98,6 +98,7 @@ import { ScreenLayout } from "@hjmds/react-native/screens";
|
|
|
98
98
|
## 꼭 지킬 것
|
|
99
99
|
|
|
100
100
|
- Web의 화면 스크롤 본문은 Tab으로 진입할 수 있다. `scroll="content"`의 정상 본문은 자식이 키보드 스크롤을 소유하지만, 오류·빈 상태 등 대체 안내는 화면 스크롤로 바뀌며 Tab 진입도 함께 복원된다.
|
|
101
|
+
- Web에서 본문에 초점을 가진 입력·재시도 버튼이 상태 전환으로 제거되면 같은 본문으로 초점을 복구한다. `scroll="content"`의 본문은 이 복구만을 위한 `tabIndex=-1`을 가지며 일반 Tab 순서에는 추가되지 않는다. 사용자가 다른 컨트롤이나 바깥 영역으로 초점을 옮긴 경우에는 이동시키지 않는다. 2026-10-13 재시도·권한 제한 전환에서 초점이 body로 유실된 경로를 수정했다.
|
|
101
102
|
- 가상화 목록(FlatList, VirtualList)을 넣으면 `scroll="content"`로 둔다. 스크롤을 이중으로 중첩하지 않는다.
|
|
102
103
|
- 새로고침 실패·저장 오류는 `state`를 바꾸지 말고 `ready` + `notice`로 알린다. `loading`으로 바꾸면 본문이
|
|
103
104
|
unmount되어 입력 초안이 사라진다.
|
|
@@ -117,7 +117,7 @@ Native는 제품 프로필의 `tokens.fontFamily.ui`를 실제 텍스트/입력
|
|
|
117
117
|
| --- | --- | --- |
|
|
118
118
|
| 진행 상태 prop | `loading`(+`renderLoadingIndicator`) | `busy`(+`renderBusyIndicator`, `busyLabel` 필수) |
|
|
119
119
|
| 검색 아이콘 | `renderSearchIcon`, 또는 `leading` | `renderLeading`, 또는 `leading` |
|
|
120
|
-
| 진행 중 입력 | 입력 가능(`aria-busy`) | 입력 가능(`accessibilityState.busy`). 2026-10-06까지 Native는 `busy`인 동안 입력을 무시했다(1.
|
|
120
|
+
| 진행 중 입력 | 입력 가능(`aria-busy`) | 입력 가능(`accessibilityState.busy`). 2026-10-06까지 Native는 `busy`인 동안 입력을 무시했다(1.13.0 변경) |
|
|
121
121
|
| 입력 요소 | `<input type="search">`, 원시 `onChange`도 전달 | `TextInput` |
|
|
122
122
|
| 배치 | `layoutStyle`·`fieldClassName`(필드 틀), `style`은 안쪽 input | `layoutStyle` |
|
|
123
123
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
- 단계: 컴포넌트
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
|
-
- 적용:
|
|
6
|
+
- 적용: 1.17.1
|
|
7
7
|
- 검토일: 2026-10-06
|
|
8
8
|
- 근거: [반복 화면 조합](../../screen-patterns.md), Web·Native `src/screens.tsx`·`src/screen-flows.tsx`; 기존 개별 지침을 새 규격으로 통합. `onSubmit`·`filtersOverflow`는 2026-10-06 사용자 요청("검색과 필터 있는 앱 서비스 따라해")의 검색 화면 개편에서 추가. 같은 날 사용자 위임 결정(권장안)으로 미리보기에만 있던 두 단계 검색 로직(`committedQuery`·`recentQueries`·`suggestedQueries`·`suggestions`·`resultSummary`·`appliedFilters`·`filterSheet`)과 `queryLabelVisibility`를, utilverse 적용 조사로 `searching`·`searchingLabel`을 추가([계약 결정 표](../../screen-patterns.md#searchscreen-두-단계-검색)). 1.13.0 utilverse 적용에서 드러난 결함으로 `hostGutter`와 확정 시 키보드 닫기(Web 결과 영역 포커스)를 추가(1.13.1 patch). 예제 스토리는 2026-10-06 사용자 승인으로 스토리북 배포([승인 기록](../../../../../docs/STORYBOOK_NAVIGATION.md#21-2026-10-06-전체-승격과-규격-확정)). 스토리북 배포는 API 게시가 아니다(`적용` 참고)
|
|
9
9
|
- 스토리북: `배포/화면/검색/검색 결과와 필터`
|
|
@@ -144,9 +144,9 @@ import { SearchScreen } from "@hjmds/react-native/screen-flows";
|
|
|
144
144
|
| `onSearch` | `(query: string, context: { signal: AbortSignal }) => void` | 필수 | `debounceMs` 뒤 호출. 값이 바뀌면 이전 타이머를 지우고 이전 신호를 abort한다 |
|
|
145
145
|
| `queryClearLabel` | `string` | `queryField`가 없으면 필수 | 기본 입력의 지우기 버튼 이름. 비어 있으면 `TypeError` |
|
|
146
146
|
| `queryField` | `ReactNode` | 없음 | 기본 `SearchField` 대신 그릴 입력. 지우기 동작을 직접 제공한다 |
|
|
147
|
-
| `debounceMs` | `number` | `300` | 0 미만은 0 |
|
|
147
|
+
| `debounceMs` | `number` | `searchScreenRecipe.debounceMs` (`300`) | 유한값을 받으며 0 미만은 0. `NaN`·±`Infinity`는 `RangeError`. 두 renderer가 `resolveSearchDebounceMs`를 공유한다 |
|
|
148
148
|
| `filters` | `ReactNode` | 없음 | 검색 입력 아래, 상단에 고정. 두 단계 검색에서는 결과 단계에만, 검색어 때문인 0건에는 숨긴다 |
|
|
149
|
-
| `onSubmit` | `(query: string) => void` | 없음 | 확정 신호. 모든 확정에서 키보드를 닫는다(Native `Keyboard.dismiss()`, Web은 고른 항목이면 결과 영역으로 포커스,
|
|
149
|
+
| `onSubmit` | `(query: string) => void` | 없음 | 확정 신호. 모든 확정에서 키보드를 닫는다(Native `Keyboard.dismiss()`, Web은 고른 항목이면 결과 영역으로 포커스, 1.13.1 변경) — 아래 플랫폼 차이. 기본 입력의 Web Enter(`enterKeyHint="search"`, IME 조합 중 Enter는 무시)·Native 키보드 검색 키(`returnKeyType="search"`, `onSubmitEditing`)와 SearchScreen이 그린 확정 행·제안·최근·추천 검색어가 모두 여기로 온다. 앞뒤 공백을 지운 값이고 공백만이면 부르지 않는다. 고른 값이 입력과 다르면 먼저 `onQueryChange`. 대기 중인 `onSearch` debounce는 그대로 둔다. `queryField`를 주면 그 입력의 키는 연결하지 않는다 |
|
|
150
150
|
| `committedQuery` | `string` | 없음 | 결과를 보여 줄 확정 검색어. 주면 두 단계 검색(`onSubmit` 필수, 타입). 단계: 검색어 공백 = 검색 전, 확정값과 다름 = 입력 중, 같음 = 결과(앞뒤 공백 무시). `children`은 결과 단계에만 그린다 |
|
|
151
151
|
| `queryLabelVisibility` | `visible` · `hidden` | `visible` | `hidden`이면 보이는 label 없이 `queryLabel`을 접근성 이름(Web `aria-label`, Native `accessibilityLabel`)과 placeholder로 쓴다 |
|
|
152
152
|
| `searching` · `searchingLabel` | `boolean` · `string` | 없음 | 기본 입력의 진행 표시(Web `loading`, Native `busy`+`busyLabel`). 함께 주거나 함께 생략(타입). 켜져 있으면 `searchingLabel`을 낭독한다 |
|
|
@@ -158,7 +158,7 @@ import { SearchScreen } from "@hjmds/react-native/screen-flows";
|
|
|
158
158
|
| `appliedFilters` | `{ items: { key, label }[], removeLabel(label), onRemove(key), clearAllLabel, onClearAll(), removeIcon? }` | 없음 | 결과 머리 아래 × 칩 + `모두 해제`. 개수는 trigger 이름과 0건 원인 판정에도 쓴다 |
|
|
159
159
|
| `filterSheet` | `{ open, onOpenChange(open), title, value, onApply(next), count(draft): number \| null, reset(draft), isDefault(draft), renderContent(draft, setDraft), labels: { close, reset, apply(count) }, size?, trigger? }` | 없음 | 열 때 `value`를 초안으로 복사, 닫히면 초안을 버림, 주 행동에서만 `onApply`. `count = 0`이면 주 행동 비활성, `isDefault`면 초기화 비활성. `trigger`를 주면 칩 줄 맨 앞에 `label(적용 개수)` Chip |
|
|
160
160
|
| `filtersOverflow` | `wrap` · `scroll` | `wrap` | `scroll`이면 `filters`를 한 줄 가로 스크롤 영역에 넣고 화면 좌우 여백(`spacing.md` 16, `contentInset="none"`이면 0)에 `hostGutter`를 더한 만큼 가장자리까지 넓힌다. 첫 칩은 검색 입력과 같은 시작선에 놓인다 |
|
|
161
|
-
| `hostGutter` | `none` · `compact` · `regular` · `spacious` | `none` |
|
|
161
|
+
| `hostGutter` | `none` · `compact` · `regular` · `spacious` | `none` | 1.13.1 변경. 이 화면을 감싼 host가 이미 준 좌우 여백 이름(`containerRecipe.gutters`: 0 · `spacing.md` 16 · `spacing.lg` 20 · `spacing.xl` 24). Container 안이면 그 `gutter`, Sheet 본문 안이면 `regular`(`sheetRecipe.content.paddingHorizontal`과 같은 `spacing.lg`). `scroll` 줄만 이 값을 쓴다 |
|
|
162
162
|
| `recentSearches` | `ReactNode` | 없음 | `query`가 공백일 때만 본문 맨 위에 보인다 |
|
|
163
163
|
| `children` | `ReactNode` | 필수 | 결과 |
|
|
164
164
|
| 나머지 | `ScreenLayout`과 같음(`children`·`footer` 제외) | — | `notice`는 필터 아래에 붙는다 |
|
|
@@ -78,7 +78,7 @@ import { Section } from "@hjmds/react-native/primitives";
|
|
|
78
78
|
| 항목 | 값 | 근거 |
|
|
79
79
|
| --- | --- | --- |
|
|
80
80
|
| 크기 | 자체 배경·테두리·여백이 없다. 폭은 부모를 따른다 | `.hjm-section` |
|
|
81
|
-
| 글자 | 제목 `title` 18/26 bold, 설명 `caption` 11/16(두 플랫폼). 2026-10-06까지 Web은 둘 다 본문 14를 물려받았다(1.
|
|
81
|
+
| 글자 | 제목 `title` 18/26 bold, 설명 `caption` 11/16(두 플랫폼). 2026-10-06까지 Web은 둘 다 본문 14를 물려받았다(1.13.0 변경) | `sectionRecipe.title`·`description`, `.hjm-section__title`·`__description` |
|
|
82
82
|
| 간격 | 머리와 본문 사이 `spacing.xs` 8, 글자 묶음과 행동 사이 `spacing.sm` 12, 제목과 설명 사이 `spacing.xxs` 4. Section끼리의 간격은 Section이 주지 않는다. 감싸는 [Stack](stack.md)이나 `layoutStyle`로 `layout.sectionGap`(`spacing.xl` 24)을 둔다 | `sectionRecipe.gap`·`headerGap`·`copyGap`, `layout.sectionGap` |
|
|
83
83
|
| 순서·정렬 | 머리 행동은 끝(LTR 오른쪽)에 하나, 글자 묶음과 세로 가운데 정렬. 보통 [Link](link.md) 또는 `tone="link"` [Button](button.md) | `.hjm-section__header`, Native `Section` |
|
|
84
84
|
| 고정·스크롤 | 고정되지 않는다. 화면 본문 스크롤 안에 둔다 | — |
|
|
@@ -98,7 +98,7 @@ import { Section } from "@hjmds/react-native/primitives";
|
|
|
98
98
|
|
|
99
99
|
- 제목·설명은 i18n 문구로 넣는다. Native는 `string`만 받는다.
|
|
100
100
|
- 배치는 `layoutStyle`로 한다. Native slot 배치는 `headerStyle`·`copyStyle`·`actionStyle`·`contentStyle`(모두 배치 전용 타입)이다.
|
|
101
|
-
Native `style`은
|
|
101
|
+
Native `style`은 제거된 속성이다.
|
|
102
102
|
- 머리 행동은 하나로 둔다. 여러 행동은 본문 안이나 [Menu](menu.md)로 옮긴다.
|
|
103
103
|
|
|
104
104
|
## 플랫폼 차이
|
|
@@ -108,4 +108,4 @@ import { Section } from "@hjmds/react-native/primitives";
|
|
|
108
108
|
| `title`·`description` 타입 | `ReactNode` | `string` |
|
|
109
109
|
| heading 수준 | `headingLevel` | 없음(header role 고정) |
|
|
110
110
|
| 루트 | `<section>` | `View` |
|
|
111
|
-
| 배치 | `className`, `layoutStyle`(HTML `style`도 받음) | `layoutStyle`, slot `*Style`(`style`은
|
|
111
|
+
| 배치 | `className`, `layoutStyle`(HTML `style`도 받음) | `layoutStyle`, slot `*Style`(`style`은 제거된 속성) |
|
|
@@ -66,7 +66,7 @@ import { SegmentedControl } from "@hjmds/react-native/inputs";
|
|
|
66
66
|
| prop | 값 | 기본값 | 설명 |
|
|
67
67
|
| --- | --- | --- | --- |
|
|
68
68
|
| `items` | Web `readonly { value: string; label: ReactNode; disabled? }[]` · Native `readonly { value: Value; label: string; disabled?; leading?; renderLeading? }[]` | 필수 | 값이 비거나 중복이면 던진다 |
|
|
69
|
-
| `presentation` | `connected` · `pills` | `connected` | 연결된 보기 전환 / 독립된 카테고리 필터. `pills`는
|
|
69
|
+
| `presentation` | `connected` · `pills` | `connected` | 연결된 보기 전환 / 독립된 카테고리 필터. `pills`는 1.13.0 변경 |
|
|
70
70
|
| `size` | `small` · `medium` | `medium` | 항목 최소 높이 36(+hitSlop 4) · 44 |
|
|
71
71
|
| `value` · `defaultValue` | 항목 값 | 첫 번째 활성 항목 | 선택 해제 상태는 없다 |
|
|
72
72
|
| `onValueChange` | Web `(value: string) => void` · Native `(value: Value) => void` | — | 다른 항목을 고를 때. `null`은 오지 않는다 |
|
|
@@ -74,7 +74,7 @@ import { SegmentedControl } from "@hjmds/react-native/inputs";
|
|
|
74
74
|
| `disabled` | `boolean` | `false` | 전체 비활성(Web은 fieldset 속성) |
|
|
75
75
|
| `layoutStyle` | 배치 전용 style 객체 | — | 바깥 배치 |
|
|
76
76
|
|
|
77
|
-
`connected`는 글자 크기 160% 이상(`stackAtFontScale`)에서 항목을 세로로 쌓는다. `pills`는 쌓지 않는다(`pills.largeTextLayout` `wrap`,
|
|
77
|
+
`connected`는 글자 크기 160% 이상(`stackAtFontScale`)에서 항목을 세로로 쌓는다. `pills`는 쌓지 않는다(`pills.largeTextLayout` `wrap`, 1.13.1 변경).
|
|
78
78
|
|
|
79
79
|
## 배치
|
|
80
80
|
|
|
@@ -103,7 +103,7 @@ import { SegmentedControl } from "@hjmds/react-native/inputs";
|
|
|
103
103
|
`value`가 비활성 항목이어도 `RangeError`다.
|
|
104
104
|
- 옛 Native `options` prop은 제거됐다. 넘기면 `TypeError`다([이관표](../../migration-native-legacy-removal.md)).
|
|
105
105
|
- 연결형의 선택 표시는 focus 색 테두리(ring), `pills`는 본문색 채움과 반전 글자다. 제품에서 선택 배경을 직접 덮지 않는다. 배치는 `layoutStyle`로 하고, Native `style`은
|
|
106
|
-
|
|
106
|
+
제거된 속성이다.
|
|
107
107
|
|
|
108
108
|
## 플랫폼 차이
|
|
109
109
|
|
|
@@ -134,7 +134,7 @@ import { SegmentedControl } from "@hjmds/react/selection";
|
|
|
134
134
|
items={categories} value={category} onValueChange={setCategory} />
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
-
Native는 `@hjmds/react-native/inputs`에서 같은 prop을 사용한다. `presentation`은
|
|
137
|
+
Native는 `@hjmds/react-native/inputs`에서 같은 prop을 사용한다. `presentation`은 1.13.0 추가 API다. 연결형과 pills는 같은 단일 선택 계약을 따른다.
|
|
138
138
|
스토리는 `버튼형 선택`의 `알약 모양`·`비활성`·`알약 모양 · 큰 글자`다. 2026-10-06 사용자 승인으로 실험 `입력/카테고리 필터` 항목을 배포하면서 별도 공개 API가 아니라 이 표현이라 그 스토리로 합쳤다([승인 기록](../../../../../docs/STORYBOOK_NAVIGATION.md#21-2026-10-06-전체-승격과-규격-확정)). Storybook 배포는 npm 게시가 아니다.
|
|
139
139
|
|
|
140
140
|
## 함정
|
|
@@ -107,7 +107,7 @@ import { NativeSelect } from "@hjmds/react/forms";
|
|
|
107
107
|
| 항목 | 값 | 근거 |
|
|
108
108
|
| --- | --- | --- |
|
|
109
109
|
| 크기 | 트리거 최소 높이 `medium` 44 · `large` 52, 폼 열 폭을 채운다(Web `inline-size: 100%`). 선택지 행 `comfortable` 56 · `compact` 44. Web 목록 최대 폭 420(`min(26.25rem, 100vw − 2×spacing.md)`)·최대 높이 360. Native sheet 최대 높이 75% | `fieldFrameContract.minHeight`, `control.buttonHeight.large`, `selectRecipe.density`·`popover`, `.hjm-select__listbox`, Native `forms.tsx` |
|
|
110
|
-
| 간격 | 트리거 좌우 `medium` `spacing.md` 16 · `large` `spacing.lg` 20(recipe), 안쪽 요소 사이 `spacing.sm` 12. 라벨·설명·오류와 `spacing.xs` 8. Web 목록은 트리거에서 8 떨어지고 안쪽 여백 `spacing.xs` 8(`selectRecipe.popover.padding`; 2026-10-06까지 4, 1.
|
|
110
|
+
| 간격 | 트리거 좌우 `medium` `spacing.md` 16 · `large` `spacing.lg` 20(recipe), 안쪽 요소 사이 `spacing.sm` 12. 라벨·설명·오류와 `spacing.xs` 8. Web 목록은 트리거에서 8 떨어지고 안쪽 여백 `spacing.xs` 8(`selectRecipe.popover.padding`; 2026-10-06까지 4, 1.13.0 변경), 화면 가장자리에서 8(`selectRecipe.popover.collisionPadding`). Native sheet 안쪽 `spacing.md` 16, 머리와 목록 사이 `spacing.sm` 12 | `selectRecipe.sizes`·`value.gap`, `formSupportContract.gap`, `selectRecipe.popover`(sideOffset 8, collisionPadding 8, padding 8), Native `forms.tsx` |
|
|
111
111
|
| 순서·정렬 | 트리거: 앞 아이콘 → 값(넘치면 말줄임) → 펼침 표시. Web 목록은 트리거 아래·트리거와 같은 폭, 공간이 없으면 위로 뒤집힌다. Native sheet 머리는 제목 + 끝쪽 닫기 ×(44). 확인 버튼은 없고 항목을 누르면 선택하고 닫힌다 | `.hjm-select__trigger`, `select.tsx`(`matchAnchorWidth`), `CollectionSheetHeader` |
|
|
112
112
|
| 고정·스크롤 | Web 목록은 `position: fixed` popover(z-index `layer.dropdown` 400), 넘치면 목록 안에서 스크롤. Native는 화면 아래에서 올라오는 modal sheet로 목록만 스크롤되고, 아래 여백에 안전 영역(`safeArea.bottom`)을 더한다. 배경(scrim)을 누르면 닫힌다 | `.hjm-select__listbox`, Native `Select`(Modal·ScrollView) |
|
|
113
113
|
| 좁은 폭·큰 글자 | 트리거 높이는 최소값이라 큰 글자에서 늘어나고 값은 한 줄 말줄임이다. Web 목록 폭은 화면 폭 − 32를 넘지 않는다 | `.hjm-select__value`, `.hjm-select__listbox` |
|
|
@@ -135,8 +135,7 @@ Web popover Native sheet
|
|
|
135
135
|
- 옛 Native `options`·`value`·`onValueChange`는 1.11에서 제거됐다. `items`/`selectedKey`/`onSelectionChange`를 쓴다.
|
|
136
136
|
- Native 선택 후 화면 이동·다른 modal 열기는 `onSelectionAfterDismiss`에서 한다. sheet가 닫히기 전에
|
|
137
137
|
다음 modal을 띄우지 않는다.
|
|
138
|
-
- 배치는 `layoutStyle`로 한다. Web `className`·`style`은 트리거 버튼에 붙는다. Native `style`은
|
|
139
|
-
다음 major 제거)다.
|
|
138
|
+
- 배치는 `layoutStyle`로 한다. Web `className`·`style`은 트리거 버튼에 붙는다. Native `style`은 제거된 속성이다.
|
|
140
139
|
|
|
141
140
|
## 플랫폼 차이
|
|
142
141
|
|
|
@@ -34,55 +34,17 @@
|
|
|
34
34
|
|
|
35
35
|
## 최소 사용 예
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
presentation="row"
|
|
49
|
-
label={t("settings.push.label")}
|
|
50
|
-
description={t("settings.push.description")}
|
|
51
|
-
checked={pushEnabled}
|
|
52
|
-
onCheckedChange={setPushEnabled}
|
|
53
|
-
/>
|
|
54
|
-
) },
|
|
55
|
-
{ id: "account", title: t("settings.account"), children: (
|
|
56
|
-
<ListRow title={t("settings.language")} description={currentLanguageName} onClick={openLanguageSheet} />
|
|
57
|
-
) },
|
|
58
|
-
]}
|
|
59
|
-
/>
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
```tsx
|
|
63
|
-
// Native — Switch는 /inputs, ListRow는 /data-display, 행 이동은 onPress
|
|
64
|
-
import { SettingsScreen } from "@hjmds/react-native/screens";
|
|
65
|
-
import { Switch } from "@hjmds/react-native/inputs";
|
|
66
|
-
import { ListRow } from "@hjmds/react-native/data-display";
|
|
67
|
-
|
|
68
|
-
<SettingsScreen
|
|
69
|
-
title={t("settings.title")}
|
|
70
|
-
sections={[
|
|
71
|
-
{ id: "notifications", title: t("settings.notifications"), children: (
|
|
72
|
-
<Switch
|
|
73
|
-
presentation="row"
|
|
74
|
-
label={t("settings.push.label")}
|
|
75
|
-
description={t("settings.push.description")}
|
|
76
|
-
checked={pushEnabled}
|
|
77
|
-
onCheckedChange={setPushEnabled}
|
|
78
|
-
/>
|
|
79
|
-
) },
|
|
80
|
-
{ id: "account", title: t("settings.account"), children: (
|
|
81
|
-
<ListRow title={t("settings.language")} description={currentLanguageName} onPress={openLanguageSheet} />
|
|
82
|
-
) },
|
|
83
|
-
]}
|
|
84
|
-
/>
|
|
85
|
-
```
|
|
37
|
+
문서와 Storybook은 같은 실행 예제를 참조한다. 제품 데이터·문구·저장·라우팅은 제품에서 연결하고,
|
|
38
|
+
아래 preview의 메모리 상태를 서버 저장으로 취급하지 않는다. 예제는 읽기용이며 제품에서 showcase를 import하지 않는다.
|
|
39
|
+
|
|
40
|
+
<!-- usage-example: Web ../../../../../showcase/web/src/patterns/settings-page-preview.tsx -->
|
|
41
|
+
- [Web 실행 예제](../../../../../showcase/web/src/patterns/settings-page-preview.tsx): 공개 SettingsScreen·행·Sheet 조합과 로컬 설정 상태.
|
|
42
|
+
<!-- usage-example: Native ../../../../../showcase/native/src/settings-page-preview.tsx -->
|
|
43
|
+
- [Native 실행 예제](../../../../../showcase/native/src/settings-page-preview.tsx): 같은 흐름의 Native 공개 API와 이벤트 연결.
|
|
44
|
+
|
|
45
|
+
설치 패키지에서 소스 링크를 열 수 없다면 [Web 원본](https://github.com/jim1286/hjm-design-system/blob/v1.17.1/showcase/web/src/patterns/settings-page-preview.tsx)과
|
|
46
|
+
[Native 원본](https://github.com/jim1286/hjm-design-system/blob/v1.17.1/showcase/native/src/settings-page-preview.tsx)을 참고한다.
|
|
47
|
+
고정 버전 예제와 현재 checkout의 후속 변경은 구분하며 설치된 타입을 기준으로 사용한다.
|
|
86
48
|
|
|
87
49
|
## 축과 기본값
|
|
88
50
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
6
|
- 적용: 1.12.1
|
|
7
|
-
- 검토일: 2026-10-
|
|
7
|
+
- 검토일: 2026-10-13
|
|
8
8
|
- 근거: [Sheet 입력 화면과 가용 영역](../../sheet.md), [optional adapters](../../optional-adapters.md)(Native 제스처 확장), `src/component-recipes.ts`(`sheetRecipe`), `src/sheet.ts`(`sheetBehaviorDefaults`)
|
|
9
9
|
- 스토리북: `배포/컴포넌트/오버레이/시트`
|
|
10
10
|
|
|
@@ -50,12 +50,17 @@ import { TextField } from "@hjmds/react/forms";
|
|
|
50
50
|
import { Sheet } from "@hjmds/react/overlays";
|
|
51
51
|
|
|
52
52
|
<Sheet open={open} onOpenChange={(next) => setOpen(next)}
|
|
53
|
+
returnFocusRef={openButtonRef}
|
|
53
54
|
title={t("profile.edit.title")} closeLabel={t("common.close")}
|
|
54
55
|
footer={<Button onClick={save} loading={saving}>{t("common.save")}</Button>}>
|
|
55
56
|
<TextField label={t("profile.name")} value={name} onValueChange={setName} />
|
|
56
57
|
</Sheet>
|
|
57
58
|
```
|
|
58
59
|
|
|
60
|
+
Web의 외부 열기 버튼과 `returnFocusRef`에 같은 `useRef<HTMLButtonElement>(null)`을 연결한다.
|
|
61
|
+
버튼 클릭 시 초점을 주지 않는 macOS WebKit에서도 닫은 뒤 호출 위치로 돌아오기 위해서다.
|
|
62
|
+
`trigger` 슬롯을 쓰면 내부에서 연결한다([Dialog 초점 복귀](dialog.md#최소-사용-예)).
|
|
63
|
+
|
|
59
64
|
```tsx
|
|
60
65
|
// Native — 입력 폼은 keyboardAvoidance + scrollable
|
|
61
66
|
import { Button } from "@hjmds/react-native/actions";
|
|
@@ -86,7 +91,7 @@ import { Sheet } from "@hjmds/react-native/overlays";
|
|
|
86
91
|
| `detents`(Web) · `activeDetent` · `onDetentChange` | `readonly ("medium" \| "large" \| "full")[]` · `(detent) => void` | — | 사용자가 높이를 바꿀 단계. `detentLabels: { expand, collapse }` 필수 |
|
|
87
92
|
| `keyboardAvoidance` · `scrollable`(Native) | `boolean` | `false` | 입력 폼은 둘 다 켠다 |
|
|
88
93
|
| `safeAreaInsets`(Native) | `Partial<Insets>` | provider inset | — |
|
|
89
|
-
| `contentStyle`(Native) | 배치 key만 | — | 배치
|
|
94
|
+
| `contentStyle`(Native) | 배치 key만 | — | `HjmCompositionStyleProp` 배치 전용 타입. 색·padding·높이 등 시각 key는 받지 않는다 |
|
|
90
95
|
|
|
91
96
|
### 디자인 프로필 상속
|
|
92
97
|
|
|
@@ -108,7 +113,7 @@ import { Sheet } from "@hjmds/react-native/overlays";
|
|
|
108
113
|
| 크기 | 하단 시트 높이: `auto` 내용 높이(최대 화면 높이 × `maxHeightRatio` 0.9), `medium` 60%, `large` 85%, `full` 위 safe area 안 전체 높이(0.9 상한 없음). Web 하단 시트 최대 폭 640. 위 두 모서리만 `radius.xl` 24. 옆 시트(`start`·`end`): Web 폭 `min(28rem, 100%)`·높이 화면 − 32, Native 폭 88%(최대 420)·화면 높이 | `sheetRecipe.sizes`·`content`·`web`, `.hjm-sheet`, Native `Sheet` |
|
|
109
114
|
| 간격 | 두 플랫폼 같은 값: 좌우 `content.paddingHorizontal`(`spacing.lg` 20), 위·아래 `content.paddingTop/Bottom`(`spacing.sm` 12, 하단 시트는 아래 safe area를 더함), 머리·본문·footer 사이 `body.gap`(`spacing.md` 16), footer 위 `footer.paddingTop`(`spacing.sm` 12), 제목–닫기 `header.gap`(`spacing.sm` 12), footer 버튼 사이 `footer.gap`(`spacing.sm` 12) | `.hjm-sheet__*`, `sheetRecipe.content`·`body`·`footer` |
|
|
110
115
|
| 순서·정렬 | 머리(제목·설명 + 닫기) → 본문 → `footer`. 머리 최소 높이 44(`control.minTouchTarget`), 닫기는 끝 쪽에서 제목 세로 중앙. Web footer는 오른쪽 정렬 가로 줄 [보조][주]. Native footer는 세로 열이라 꽉 찬 폭 버튼을 주 행동 먼저 둔다. Web에서 `detents`를 주면 위 가운데 36×4 손잡이 버튼(터치 최소 폭 44 · 높이 `spacing.lg` 20). Native 기본 Sheet는 손잡이가 없다 | `sheetRecipe.header`·`handle`, `.hjm-sheet__footer`, `.hjm-sheet__handle` |
|
|
111
|
-
| 고정·스크롤 | 본문만 스크롤, 머리·`footer` 고정(Native는 `scrollable`일 때 ScrollView). 고정 높이(`medium`·`large`·`full`, 옆 시트)에서는 본문이 머리·footer를 뺀 남은 높이를 차지하고 `footer`는 시트 아래에 붙는다. 그래서 본문의 `flex: 1` 자식(SearchScreen, 목록 화면)이 그 높이를 채운다(Web `.hjm-sheet__body` `flex: 1 1 auto`, Native 본문 `flexGrow: 1`·`minHeight: 0`,
|
|
116
|
+
| 고정·스크롤 | 본문만 스크롤, 머리·`footer` 고정(Native는 `scrollable`일 때 ScrollView). 고정 높이(`medium`·`large`·`full`, 옆 시트)에서는 본문이 머리·footer를 뺀 남은 높이를 차지하고 `footer`는 시트 아래에 붙는다. 그래서 본문의 `flex: 1` 자식(SearchScreen, 목록 화면)이 그 높이를 채운다(Web `.hjm-sheet__body` `flex: 1 1 auto`, Native 본문 `flexGrow: 1`·`minHeight: 0`, 1.13.1 변경). `auto`는 내용 높이 그대로다. 저장·확인은 `footer`에. 아래 안전 영역은 시트가 자기 여백에 더한다(`spacing.sm` 12 + 아래 inset, Web은 `env(safe-area-inset-bottom)`). 위 inset은 시트가 올라갈 높이를 줄인다. 제품이 inset을 다시 더하지 않는다 | `.hjm-sheet__body`, `sheetRecipe.safeArea`, Native `Sheet` |
|
|
112
117
|
| 좁은 폭·큰 글자 | 폭 < 640이면 하단 시트가 화면 폭을 채운다. Web footer는 줄을 바꾼다. 큰 글자로 내용이 길어지면 `auto`는 최대 90%에서 멈추고 본문이 스크롤된다(`full`은 위 safe area까지) | `.hjm-sheet[data-placement="bottom"]`, `maxHeightRatio` |
|
|
113
118
|
|
|
114
119
|
```text
|
|
@@ -136,7 +141,7 @@ import { Sheet } from "@hjmds/react-native/overlays";
|
|
|
136
141
|
- 닫힌 뒤 다른 modal을 열거나 화면 이동은 `onDismissComplete`에서 한다. 두 modal을 동시에 띄우지 않는다.
|
|
137
142
|
- 문구(`title`, `closeLabel`, 본문)는 i18n 키로 넣는다. 제목 정렬을 위해 `as unknown as string` 캐스트나
|
|
138
143
|
`.hjm-sheet__header` CSS 덮어쓰기를 하지 않는다.
|
|
139
|
-
- Native `contentStyle`은 배치 key만 쓴다. 높이는 `size`로 정한다(`contentStyle={{ height }}` 금지, 배치 밖 key는
|
|
144
|
+
- Native `contentStyle`은 배치 key만 쓴다. 높이는 `size`로 정한다(`contentStyle={{ height }}` 금지, 배치 밖 key는 지원하지 않음).
|
|
140
145
|
- Web Sheet는 `layoutStyle`을 받지 않는다(Web `layoutStyle` 제외 15개 중 하나). 표면 위치·크기는 `placement`·`size`가 정한다.
|
|
141
146
|
|
|
142
147
|
## 플랫폼 차이
|
|
@@ -162,7 +167,7 @@ import { Sheet } from "@hjmds/react-native/overlays";
|
|
|
162
167
|
|
|
163
168
|
## 함정
|
|
164
169
|
|
|
165
|
-
-
|
|
170
|
+
- `size="full"`(Web `detents`의 `full` 포함)은 위 안전 영역을 뺀 전체 높이를 사용한다. 0.9 상한은 `auto`에만 적용된다(1.13.0 변경).
|
|
166
171
|
- 1.13.0 이하 Native 고정 높이 Sheet는 본문이 내용 높이라서 `flex: 1` 자식이 0pt가 됐다. 시트 안 SearchScreen이 검색 입력만 그리고
|
|
167
172
|
필터 줄·목록이 사라졌다(2026-10-06 utilverse 채팅 도구 선택, iPhone 17 Pro · iOS 26.5). 제품은 창 높이 `flexBasis`로 우회했다.
|
|
168
173
|
1.13.1부터는 그 우회 없이 채워진다. 1.13.0 이하에서도 footer는 본문 바로 아래에 있었고, 1.13.1부터 고정 높이 시트에서는 시트 아래에 붙는다.
|
|
@@ -110,4 +110,4 @@ Native: 없음. 폰은 BottomNavigation, 태블릿 split view는 navigator가
|
|
|
110
110
|
|
|
111
111
|
2026-10-07 소비 감사에서 Web 항목의 숫자 recipe 모서리가 프로필을 우회했다. 기존 `radius.md` 역할을 가까운 Provider의 CSS 변수로 읽고 변수 없는 독립 사용은 recipe 12를 유지한다. 레일 폭·링크·현재 위치·접기·초점과 Web 전용 범위는 바꾸지 않는다.
|
|
112
112
|
|
|
113
|
-
프로필 연결은 1.
|
|
113
|
+
프로필 연결은 1.16.0 변경이며, 기본 배포 계약과 실제 Native 기기 검증은 구분한다.
|
|
@@ -90,7 +90,7 @@ import { Skeleton } from "@hjmds/react-native/feedback";
|
|
|
90
90
|
|
|
91
91
|
- 실제 콘텐츠와 같은 자리·비슷한 크기로 둔다. 로딩이 끝나면 Skeleton을 내용으로 **바꾼다**(겹쳐 두지 않는다).
|
|
92
92
|
- 색·테두리는 recipe와 테마가 정한다. 배치는 `layoutStyle`로 하고 `style`/`className`으로 회색 배경을 덮지 않는다.
|
|
93
|
-
Native `style`은
|
|
93
|
+
Native `style`은 제거된 속성이다.
|
|
94
94
|
- Web Skeleton은 `aria-hidden`이다. 로딩 사실을 알려야 하면 영역 단위로 한 번 알린다
|
|
95
95
|
(예: 감싼 영역의 `aria-busy`, 또는 Spinner 하나). Skeleton마다 라벨을 붙이지 않는다.
|
|
96
96
|
- Web은 `HjmProvider` 안에서 렌더한다. 원 지름·펄스 값을 provider가 내보내는 `--hjm-skeleton-*` 변수로 읽는다.
|
|
@@ -79,4 +79,4 @@ Native: 없음.
|
|
|
79
79
|
|
|
80
80
|
2026-10-07 소비 감사에서 Web 링크의 숫자 recipe 모서리가 프로필을 우회했다. 기존 `radius.md` 역할을 가까운 Provider의 CSS 변수로 읽고 변수 없는 독립 사용은 recipe 12를 유지한다. 숨김·고정 위치·표시·본문 초점 이동과 Web 전용 범위는 바꾸지 않는다.
|
|
81
81
|
|
|
82
|
-
프로필 연결은 1.
|
|
82
|
+
프로필 연결은 1.16.0 변경이며, 기본 배포 계약과 실제 Native 기기 검증은 구분한다.
|
|
@@ -104,7 +104,7 @@ Native는 제품 프로필의 `tokens.fontFamily.ui`를 실제 텍스트/입력
|
|
|
104
104
|
- `label`·`getValueText`·(Native) `incrementLabel`/`decrementLabel`은 i18n 문구로 준다. 단위·형식은 제품 소유다.
|
|
105
105
|
- 사용자 입력만 step으로 snap된다. 제품이 준 `value`가 범위 안이면 step 밖이어도 그대로 그린다.
|
|
106
106
|
- 색·트랙 두께·thumb 크기는 HJM 소유다. 배치는 `layoutStyle`로 한다. Web `style`/`className`/`inputClassName`은 배치용으로만 쓰고,
|
|
107
|
-
Native `containerStyle`/`controlStyle`은
|
|
107
|
+
Native `containerStyle`/`controlStyle`은 제거된 속성이다.
|
|
108
108
|
|
|
109
109
|
## 플랫폼 차이
|
|
110
110
|
|
|
@@ -113,7 +113,7 @@ Native는 제품 프로필의 `tokens.fontFamily.ui`를 실제 텍스트/입력
|
|
|
113
113
|
| 접근성 | `input type="range"`, `aria-valuetext` | role `adjustable`, `accessibilityValue` |
|
|
114
114
|
| 키 조작 | 방향키·Home/End·PageUp/PageDown(step×10) | `increment`/`decrement` action만(페이지 이동 없음) |
|
|
115
115
|
| 필수 추가 문구 | 없음 | `incrementLabel`, `decrementLabel` |
|
|
116
|
-
| 스타일 슬롯 | `layoutStyle`, `style`(루트), `className`, `inputClassName` | `layoutStyle`. `containerStyle`·`controlStyle`은
|
|
116
|
+
| 스타일 슬롯 | `layoutStyle`, `style`(루트), `className`, `inputClassName` | `layoutStyle`. `containerStyle`·`controlStyle`은 제거된 속성(`style` prop 없음) |
|
|
117
117
|
| 의존성 | 없음 | 없음(PanResponder 사용) |
|
|
118
118
|
|
|
119
119
|
## 함정
|
|
@@ -53,7 +53,7 @@ import { Spinner } from "@hjmds/react-native/feedback";
|
|
|
53
53
|
| `tone`(Web) | `brand` · `neutral` · `inverse` | `brand` | — |
|
|
54
54
|
| `size`(Native) | `small` · `large` | `small` | 플랫폼 `ActivityIndicator`를 테마 `contentBrand` 색으로 그린다. `tone`은 없다 |
|
|
55
55
|
| `layoutStyle` | `HjmCompositionStyleProp`(margin·width·flex 계열·`alignSelf`) | — | 루트 배치. Web·Native 모두 |
|
|
56
|
-
| `style`(Native) |
|
|
56
|
+
| `style`(Native) | 지원하지 않음 | — | 제거된 속성 — `layoutStyle` 또는 `size`. 현재 공개 props에서 제거되었다 |
|
|
57
57
|
|
|
58
58
|
## 배치
|
|
59
59
|
|
|
@@ -83,4 +83,4 @@ import { Spinner } from "@hjmds/react-native/feedback";
|
|
|
83
83
|
| 크기 | 3단계 | `small`·`large` 2단계 |
|
|
84
84
|
| tone | 있음 | 없음(항상 brand 색) |
|
|
85
85
|
| reduced motion | 회전 멈춤(CSS) | 별도 처리 없음(`ActivityIndicator` 그대로) |
|
|
86
|
-
| `style` | HTML 속성(`layoutStyle`과 합쳐지고 `layoutStyle`이 이김) |
|
|
86
|
+
| `style` | HTML 속성(`layoutStyle`과 합쳐지고 `layoutStyle`이 이김) | 제거된 속성 |
|