@hjmds/design-contracts 1.40.0 → 1.41.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/agreement.d.ts +2 -2
  2. package/dist/base-recipes.d.ts +11 -3
  3. package/dist/base-recipes.d.ts.map +1 -1
  4. package/dist/base-recipes.js +9 -4
  5. package/dist/base-recipes.js.map +1 -1
  6. package/dist/behaviors.d.ts +4 -4
  7. package/dist/card.d.ts +1 -1
  8. package/dist/card.js +1 -1
  9. package/dist/card.js.map +1 -1
  10. package/dist/catalog.d.ts +107 -85
  11. package/dist/catalog.d.ts.map +1 -1
  12. package/dist/choice-row.d.ts +26 -0
  13. package/dist/choice-row.d.ts.map +1 -0
  14. package/dist/choice-row.js +24 -0
  15. package/dist/choice-row.js.map +1 -0
  16. package/dist/colors.d.ts +2 -0
  17. package/dist/colors.d.ts.map +1 -1
  18. package/dist/colors.js +3 -1
  19. package/dist/colors.js.map +1 -1
  20. package/dist/command-palette.d.ts +2 -2
  21. package/dist/component-contracts.d.ts +2 -2
  22. package/dist/component-contracts.js +2 -2
  23. package/dist/component-contracts.js.map +1 -1
  24. package/dist/component-recipes.d.ts +76 -64
  25. package/dist/component-recipes.d.ts.map +1 -1
  26. package/dist/component-recipes.js +18 -16
  27. package/dist/component-recipes.js.map +1 -1
  28. package/dist/data-table.d.ts +1 -1
  29. package/dist/icon-button-recipe.d.ts +2 -2
  30. package/dist/icon-button-recipe.js +3 -3
  31. package/dist/icon-button-recipe.js.map +1 -1
  32. package/dist/menubar.d.ts +2 -2
  33. package/dist/palette-contrast.d.ts.map +1 -1
  34. package/dist/palette-contrast.js +2 -0
  35. package/dist/palette-contrast.js.map +1 -1
  36. package/dist/semantic-colors.d.ts +18 -1
  37. package/dist/semantic-colors.d.ts.map +1 -1
  38. package/dist/semantic-colors.js +7 -1
  39. package/dist/semantic-colors.js.map +1 -1
  40. package/dist/sidebar.d.ts +2 -2
  41. package/dist/time-picker.d.ts +16 -4
  42. package/dist/time-picker.d.ts.map +1 -1
  43. package/dist/time-picker.js +26 -5
  44. package/dist/time-picker.js.map +1 -1
  45. package/dist/toggle-group.d.ts +3 -3
  46. package/dist/toggle-group.js +3 -3
  47. package/dist/toggle-group.js.map +1 -1
  48. package/dist/transfer-list.d.ts +2 -2
  49. package/dist/tree.d.ts +2 -2
  50. package/dist/version.d.ts +1 -1
  51. package/dist/version.js +1 -1
  52. package/dist/version.js.map +1 -1
  53. package/docs/ant-design-coverage.md +6 -1
  54. package/docs/brand-boundary.md +1 -0
  55. package/docs/generated/component-maturity.md +1 -1
  56. package/docs/generated/renderer-evidence.json +3 -3
  57. package/docs/generated/renderer-evidence.md +1 -1
  58. package/docs/generated/showcase-manifest.json +1 -1
  59. package/docs/theme-palette.md +60 -0
  60. package/docs/time-picker.md +21 -0
  61. package/docs/usage/FINDING.md +71 -0
  62. package/docs/usage/README.md +5 -3
  63. package/docs/usage/SELECTION.md +8 -2
  64. package/docs/usage/components/bottom-navigation.md +5 -0
  65. package/docs/usage/components/card.md +2 -2
  66. package/docs/usage/components/chip.md +1 -1
  67. package/docs/usage/components/choice-row.md +79 -0
  68. package/docs/usage/components/keyboard-avoidance-context.md +3 -3
  69. package/docs/usage/components/segmented-control.md +1 -1
  70. package/docs/usage/components/surface.md +7 -1
  71. package/docs/usage/components/tabs.md +5 -0
  72. package/docs/usage/components/time-picker.md +20 -2
  73. package/docs/usage/components/toggle-group.md +5 -0
  74. package/docs/usage/compositions/save-feedback.md +43 -21
  75. package/docs/usage/tokens/color.md +17 -3
  76. package/package.json +7 -1
@@ -1,12 +1,12 @@
1
1
  # 저장 결과
2
2
 
3
3
  - 단계: 구성
4
- - 상태: 실험
4
+ - 상태: 배포
5
5
  - 지원: Web · Native
6
6
  - 적용: 1.37.1
7
- - 검토일: 2026-10-20
7
+ - 검토일: 2026-10-23
8
8
  - 근거: 사용자 요청으로 카드 안 저장 완료 예시(이전 3번)를 제거하고, 승인된 라이트·다크 토스트 시안으로 두 유형을 통일했다.
9
- - 스토리북: `실험/구성/피드백과 복구/저장 결과`
9
+ - 스토리북: `배포/구성/피드백과 복구/저장 결과`
10
10
 
11
11
  ## 언제 쓰나
12
12
 
@@ -14,22 +14,22 @@
14
14
 
15
15
  ## 구성 요소
16
16
 
17
- | 유형 | 쓰는 상황 | 공개 API |
17
+ | 컴포넌트 | 역할 | 지침 |
18
18
  | --- | --- | --- |
19
- | 1 · 한 줄 토스트 | 짧은 완료 확인 | Toast `description`, `tone="success"` |
20
- | 2 · 요약 토스트 | 저장한 대상까지 확인 | 같은 Toast의 `title` + `description` |
19
+ | Toast(`description`, `tone="success"`) | 1 · 한 줄 토스트: 짧은 완료 확인 | [Toast](../components/toast.md) |
20
+ | Toast(`title` + `description`) | 2 · 요약 토스트: 저장한 대상까지 확인 | [Toast](../components/toast.md) |
21
+ | ToastProvider(Web) / ToastRegion(Native) | 앱 루트에서 표시 층·큐·타이머 소유 | [Toast](../components/toast.md) |
21
22
 
22
23
  두 유형은 별도 엔진이나 변형 prop이 아니다. 웹은 ToastProvider, Native는 ToastRegion을 앱 루트에 둔다. 카드형 저장 결과는 선택지에서 제거했다. 일반 Notice·Card·Badge의 다른 용도는 유지한다.
23
24
 
24
25
  ## 배치
25
26
 
26
- | 영역 | 위치·크기 |
27
- | --- | --- |
28
- | 바깥 틀 | 최대 폭 420, 최소 높이 56, 모서리 24 |
29
- | 화면 가장자리 | 16 + 안전 영역. 광고 footer가 있으면 상단 |
30
- | 내부 | 가로 16·세로 12, 첫 줄 기준 정렬, 닫기 터치 영역 44 유지 |
31
- | 한 줄 | 장식 아이콘 → 본문 → 닫기 |
32
- | 요약 | 제목 → 보조 설명, 오른쪽 닫기. 장식 아이콘은 생략; 제품 media는 유지 |
27
+ | 영역 | 컴포넌트 | 위치 | 크기·간격 |
28
+ | --- | --- | --- | --- |
29
+ | 바깥 틀 | Toast | 화면 가장자리 16 + 안전 영역. 광고 footer가 있으면 상단 | 최대 폭 420, 최소 높이 56, 모서리 24 |
30
+ | 내부 | Toast | 첫 줄 기준 정렬 | 가로 16·세로 12, 닫기 터치 영역 44 유지 |
31
+ | 한 줄 | Toast `description` | 장식 아이콘 → 본문 → 닫기 | — |
32
+ | 요약 | Toast `title` + `description` | 제목 → 보조 설명, 오른쪽 닫기. 장식 아이콘은 생략; 제품 media는 유지 | — |
33
33
 
34
34
  ```text
35
35
  한 줄: [ ✓ KE123 저장했어요 × ]
@@ -41,20 +41,42 @@
41
41
 
42
42
  ## 흐름과 상태
43
43
 
44
- | 상태 | 표시·행동 |
45
- | --- | --- |
46
- | 저장 중 | 기존 제출 상태, 성공 알림 없음 |
47
- | 성공 | 저장 응답/영속 저장 완료 후 토스트 한 장, polite 낭독 한 번 |
48
- | 실패 | 입력 보존, 기존 오류·재시도 |
44
+ 1. 사용자가 저장을 누르면 제품의 기존 제출 상태(버튼 pending 등)만 보여 준다. 이 단계에서는 토스트를 띄우지 않는다.
45
+ 2. 저장 응답이나 영속 저장이 끝난 뒤에만 고정 `id`로 `publish`해 토스트 한 장을 띄운다.
46
+ 3. 실패하면 토스트 대신 기존 오류·재시도 흐름을 쓰고 입력을 보존한다.
47
+
48
+ | 상태 | 모습 | 포커스·알림 |
49
+ | --- | --- | --- |
50
+ | 기본 | 토스트 없음 | — |
51
+ | 진행 중 | 기존 제출 상태, 성공 알림 없음 | 포커스는 제출 버튼에 둔다 |
52
+ | 성공 | 저장 응답/영속 저장 완료 후 토스트 한 장 | polite 낭독 한 번, 포커스를 옮기지 않는다 |
53
+ | 실패 | 입력 보존, 기존 오류·재시도 | 기존 오류 안내가 낭독을 소유한다 |
49
54
 
50
55
  기본 3초이며 긴 요약은 제품에서 시간을 늘린다. 같은 성공을 카드 상태와 토스트로 중복 알리지 않는다. 이전 초안의 늦은 응답을 새 초안의 성공으로 표시하지 않는다.
51
56
 
52
57
  ## 코드 골격
53
58
 
54
59
  ```tsx
55
- // 영속 저장 성공 뒤; Native useToastRegion / Web useToast의 기존 publish.
56
- toast.publish({ id: "saved", description: savedLabel, tone: "success", closeLabel });
57
- toast.publish({ id: "saved", title: savedTitle, description: subjectSummary, tone: "success", closeLabel });
60
+ // Web — ToastProvider 안에서, 영속 저장 성공 뒤에만 publish한다.
61
+ import { useToast } from "@hjmds/react/toast";
62
+
63
+ const toast = useToast();
64
+ async function save() {
65
+ await persist(draft);
66
+ toast.publish({ id: "saved", description: savedLabel, tone: "success", closeLabel });
67
+ // 대상 요약형: toast.publish({ id: "saved", title: savedTitle, description: subjectSummary, tone: "success", closeLabel });
68
+ }
69
+ ```
70
+
71
+ ```tsx
72
+ // Native — ToastRegion 안에서, 같은 descriptor를 publish한다.
73
+ import { useToastRegion } from "@hjmds/react-native/feedback";
74
+
75
+ const toast = useToastRegion();
76
+ async function save() {
77
+ await persist(draft);
78
+ toast.publish({ id: "saved", description: savedLabel, tone: "success", closeLabel });
79
+ }
58
80
  ```
59
81
 
60
82
  실행 예제: [Web](../../../../../showcase/web/src/components/save-feedback-preview.tsx), [Native](../../../../../showcase/native/src/save-feedback-preview.tsx), [공통 문구](../../../../../showcase/shared/save-feedback.ts). 비교 예제의 durationMs: null은 제품 기본 타이머를 바꾸지 않는다.
@@ -32,6 +32,7 @@
32
32
  | `canvas` = `bg` | `#ffffff` / `#0d1116` | `--hjm-color-bg` | `theme.colors.bg` | 화면 바탕. 카드·패널(Surface·Card)도 모든 tone이 `bg`를 칠하고 층은 테두리·그림자로 나눈다 |
33
33
  | `surface.default` = `surface` | `#ffffff` / `#161b22` | `--hjm-color-surface` | `theme.colors.surface` | 바탕과 구분되는 옅은 면 |
34
34
  | `surface.sunken` = `surfaceAlt` | `#ebeef2` / `#1e232a` | `--hjm-color-surface-alt` | `theme.colors.surfaceAlt` | 한 단계 더 들어간 면(CodeBlock 바탕) |
35
+ | `selection.background` = `surfaceSelected` | `#f0f1f3` / `#30343b` | `--hjm-color-surface-selected` | `theme.colors.surfaceSelected` | 기본 선택 배경 |
35
36
  | `surface.brand` = `surfaceAccent` | `#c9e2ff` / `#224159` | `--hjm-color-surface-accent` | `theme.colors.surfaceAccent` | 브랜드가 드러나는 옅은 면 |
36
37
 
37
38
  ### 글자
@@ -41,7 +42,7 @@
41
42
  | `content.primary` = `text` | `#191f28` / `#f3f5f7` | `--hjm-color-text` | `theme.colors.text` | 제목·강조 글자. Text `tone="primary"`(기본) |
42
43
  | `content.body` = `textBody` | `#333d4b` / `#e1e5ea` | `--hjm-color-text-body` | `theme.colors.textBody` | 긴 본문. Text `tone="body"` |
43
44
  | `content.secondary` = `textMuted` | `#4e5968` / `#cad0d8` | `--hjm-color-text-muted` | `theme.colors.textMuted` | 보조 설명. Text `tone="muted"` |
44
- | `content.tertiary` = `textSub` | `#65707d` / `#9ba5b0` | `--hjm-color-text-sub` | `theme.colors.textSub` | 시간·출처 같은 약한 메타 정보. Text `tone="subtle"` |
45
+ | `content.tertiary` = `textSub` | `#646f7c` / `#9ba5b0` | `--hjm-color-text-sub` | `theme.colors.textSub` | 시간·출처 같은 약한 메타 정보. Text `tone="subtle"` |
45
46
  | `content.decorative` = `textWeak` | `#8b95a1` / `#8b96a2` | `--hjm-color-text-weak` | `theme.colors.textWeak` | 비활성·placeholder·장식 표지. Text `tone="weak"`. 읽혀야 하는 글자에는 쓰지 않는다 |
46
47
 
47
48
  ### 브랜드
@@ -86,13 +87,13 @@
86
87
  | `border.control` = `borderControl` | `#6b7684` / `#929faf` | `--hjm-color-border-control` | `theme.colors.borderControl` | 쉬고 있는 컨트롤 윤곽(Button `secondary`, 필드) |
87
88
  | `border.strong` = `textWeak` | `#8b95a1` / `#8b96a2` | `--hjm-color-text-weak` | `theme.colors.textWeak` | 강한 경계 |
88
89
  | `border.focus` | `contentBrand` | `--hjm-color-focus` | `theme.colors.contentBrand` | 포커스 링. 컴포넌트가 그린다 |
89
- | `interaction.hover` · `focus` · `pressed` · `selected` | `text` 0.06 · `contentBrand` 0.08 · `text` 0.1 · `primary` 0.1 | — | `resolveColorReference(…, theme.palette)` | 상태 덧칠. 제품 고유 누름 영역에만 직접 쓴다 |
90
+ | `interaction.hover` · `focus` · `pressed` | `text` 0.06 · `contentBrand` 0.08 · `text` 0.1 | — | `resolveColorReference(…, theme.palette)` | 상태 덧칠. 제품 고유 누름 영역에만 직접 쓴다 |
90
91
 
91
92
  ### 함께 쓰는 쌍과 최소 대비
92
93
 
93
94
  `checkBrandPaletteContrast`가 검사하는 쌍이다. 이 밖의 조합(예: `contentBrand` 글자를 `surfaceAccent` 위에)은 HJM이 대비를 보장하지 않는다.
94
95
 
95
- - 4.5 이상: `text`·`textBody`·`textMuted`·`textSub`·`contentBrand`·`danger` on `bg`·`surface`, `onPrimary` on `primary`, `onDanger` on `dangerFill`.
96
+ - 4.5 이상: `text`·`textBody`·`textMuted`·`textSub`·`contentBrand`·`danger` on `bg`·`surface`·`surfaceSelected`, `onPrimary` on `primary`, `onDanger` on `dangerFill`.
96
97
  - 3 이상: `primary`·`borderControl` vs `bg`·`surface`(형태), `textWeak` vs `bg`.
97
98
 
98
99
  ## 쓰는 법
@@ -162,3 +163,16 @@ import { HjmProvider } from "@hjmds/react/provider";
162
163
  표·표면의 회색 면을 줄이려는 사용자 결정으로 `surface`는 흰색 `#ffffff`,
163
164
  `surfaceAlt`는 보조 회색 `#ebeef2`를 사용한다. 페이지 바탕 `bg`는 흰색이며,
164
165
  표 본문은 `surface`, `raised` 카드는 `bg`를 소비한다. 근거는 [팔레트 결정 기록](../../theme-palette.md)을 따른다.
166
+
167
+ ## 기본 선택 역할
168
+
169
+ `semanticColors.selection.background` → `surfaceSelected`: light `#f0f1f3`, dark `#30343b`.
170
+ Web은 `--hjm-color-surface-selected`, Native는 `theme.colors.surfaceSelected`로 읽는다.
171
+ 선택 글자는 `semanticColors.selection.content` → `text`, 경계는 `selection.border` → `borderControl`이다.
172
+ 휠·선택 Chip·neutral SegmentedControl에 쓰며, 주요 버튼의 `primary`나 브랜드 배경의
173
+ `surfaceAccent`를 선택 배경으로 덮어쓰지 않는다. [결정 근거](../../theme-palette.md#기본-선택-배경을-브랜드에서-분리한다-2026-10-23).
174
+
175
+ 기본 선택의 적용 범위와 예외는 [선택 상태 색상 기준](../../theme-palette.md#선택-상태-색상-기준-2026-10-23)을 따른다.
176
+
177
+ `interaction.selected`는 이제 `surfaceSelected`를 가리킨다. 일반 선택 면에는 가능하면
178
+ `semanticColors.selection.background`를 사용하고, hover/focus/pressed의 투명 상태 덧칠과 구분한다.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hjmds/design-contracts",
3
- "version": "1.40.0",
3
+ "version": "1.41.1",
4
4
  "description": "Renderer-neutral design contracts, tokens, recipes, and behaviors shared by HJM products.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -607,6 +607,12 @@
607
607
  "import": "./dist/reference-controls.js",
608
608
  "default": "./dist/reference-controls.js"
609
609
  },
610
+ "./choice-row": {
611
+ "types": "./dist/choice-row.d.ts",
612
+ "react-native": "./dist/choice-row.js",
613
+ "import": "./dist/choice-row.js",
614
+ "default": "./dist/choice-row.js"
615
+ },
610
616
  "./duration-field": {
611
617
  "types": "./dist/duration-field.d.ts",
612
618
  "react-native": "./dist/duration-field.js",