@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.
- package/dist/agreement.d.ts +2 -2
- package/dist/base-recipes.d.ts +11 -3
- package/dist/base-recipes.d.ts.map +1 -1
- package/dist/base-recipes.js +9 -4
- package/dist/base-recipes.js.map +1 -1
- package/dist/behaviors.d.ts +4 -4
- package/dist/card.d.ts +1 -1
- package/dist/card.js +1 -1
- package/dist/card.js.map +1 -1
- package/dist/catalog.d.ts +107 -85
- package/dist/catalog.d.ts.map +1 -1
- package/dist/choice-row.d.ts +26 -0
- package/dist/choice-row.d.ts.map +1 -0
- package/dist/choice-row.js +24 -0
- package/dist/choice-row.js.map +1 -0
- package/dist/colors.d.ts +2 -0
- package/dist/colors.d.ts.map +1 -1
- package/dist/colors.js +3 -1
- package/dist/colors.js.map +1 -1
- package/dist/command-palette.d.ts +2 -2
- package/dist/component-contracts.d.ts +2 -2
- package/dist/component-contracts.js +2 -2
- package/dist/component-contracts.js.map +1 -1
- package/dist/component-recipes.d.ts +76 -64
- package/dist/component-recipes.d.ts.map +1 -1
- package/dist/component-recipes.js +18 -16
- package/dist/component-recipes.js.map +1 -1
- package/dist/data-table.d.ts +1 -1
- package/dist/icon-button-recipe.d.ts +2 -2
- package/dist/icon-button-recipe.js +3 -3
- package/dist/icon-button-recipe.js.map +1 -1
- package/dist/menubar.d.ts +2 -2
- package/dist/palette-contrast.d.ts.map +1 -1
- package/dist/palette-contrast.js +2 -0
- package/dist/palette-contrast.js.map +1 -1
- package/dist/semantic-colors.d.ts +18 -1
- package/dist/semantic-colors.d.ts.map +1 -1
- package/dist/semantic-colors.js +7 -1
- package/dist/semantic-colors.js.map +1 -1
- package/dist/sidebar.d.ts +2 -2
- package/dist/time-picker.d.ts +16 -4
- package/dist/time-picker.d.ts.map +1 -1
- package/dist/time-picker.js +26 -5
- package/dist/time-picker.js.map +1 -1
- package/dist/toggle-group.d.ts +3 -3
- package/dist/toggle-group.js +3 -3
- package/dist/toggle-group.js.map +1 -1
- package/dist/transfer-list.d.ts +2 -2
- package/dist/tree.d.ts +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/docs/ant-design-coverage.md +6 -1
- package/docs/brand-boundary.md +1 -0
- 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/theme-palette.md +60 -0
- package/docs/time-picker.md +21 -0
- package/docs/usage/FINDING.md +71 -0
- package/docs/usage/README.md +5 -3
- package/docs/usage/SELECTION.md +8 -2
- package/docs/usage/components/bottom-navigation.md +5 -0
- package/docs/usage/components/card.md +2 -2
- package/docs/usage/components/chip.md +1 -1
- package/docs/usage/components/choice-row.md +79 -0
- package/docs/usage/components/keyboard-avoidance-context.md +3 -3
- package/docs/usage/components/segmented-control.md +1 -1
- package/docs/usage/components/surface.md +7 -1
- package/docs/usage/components/tabs.md +5 -0
- package/docs/usage/components/time-picker.md +20 -2
- package/docs/usage/components/toggle-group.md +5 -0
- package/docs/usage/compositions/save-feedback.md +43 -21
- package/docs/usage/tokens/color.md +17 -3
- package/package.json +7 -1
|
@@ -52,11 +52,16 @@ message와 notification을 가르는 축(정보 층, 지속 시간, 동시 개
|
|
|
52
52
|
|
|
53
53
|
| 종류 | 뜻 | 예 | 재검토 신호 |
|
|
54
54
|
|---|---|---|---|
|
|
55
|
-
| **흡수됨** | 그 문제를 이미 다른 컴포넌트가 완결한다 | `Notification`→Toast, `Dropdown`→Menu, `ContextPanel`→SidePanel/Sheet, `Flex`→Stack
|
|
55
|
+
| **흡수됨** | 그 문제를 이미 다른 컴포넌트가 완결한다 | `Notification`→Toast, `Dropdown`→Menu, `ContextPanel`→SidePanel/Sheet, `Flex`→Stack | 흡수한 쪽이 못 푸는 요구가 나올 때 |
|
|
56
56
|
| **검증할 화면이 없음** | 계약 자체는 유효하나 이를 확인할 제품 화면이 없다 | `Anchor` | 그 화면이 실제로 생길 때 |
|
|
57
57
|
| **거절됨** | 계약도 유효하고 화면이 생겨도 만들지 않는다 | `BorderBeam`(장식), `AppProvider`(런타임뿐), `Utility`(실체 없음) | 정체성이나 아키텍처 경계가 바뀔 때만 |
|
|
58
58
|
| **흡수 대기** | 흡수 판정은 끝났으나 **선결 축이 아직 없다** | `Cascader`(TreeSelect에 `valueMode`/`commitAt`가 추가돼야 성립) | 그 축이 실제로 추가될 때 |
|
|
59
59
|
|
|
60
|
+
흡수 판정이 실제로 뒤집힌 예도 있습니다. 표에서 빼고 현재 계약을 따릅니다(2026-10-23 문서 대조에서 표가 옛 판정으로 남아 있던 것을 정정).
|
|
61
|
+
|
|
62
|
+
- `TimePicker`: 2026-10-19 선택의창의 시트 안 시·분 선택 요구로 독립 canonical 컴포넌트가 됐습니다([time-picker.md](time-picker.md)). crosswalk는 `direct`입니다.
|
|
63
|
+
- `Rating`: 2026-10-06 레퍼런스 적용 요청으로 정수 선택·미평가·소수 평균 표시를 구분하는 supplemental `Rating`(`/rating`)이 추가됐습니다([reference-controls.md](reference-controls.md#rating)). supplemental은 catalog `ComponentId`가 아니므로 antd `Rate`의 crosswalk target은 계속 `Slider`/`Statistic`입니다.
|
|
64
|
+
|
|
60
65
|
둘을 섞으면 안 됩니다. **흡수됨**은 설계 판단이라 제품이 늘어나도 웬만해선 뒤집히지 않지만,
|
|
61
66
|
**검증할 화면이 없음**은 사실 관찰이라 **커밋 하나로 낡습니다**. 실제로 그런 일이 있었습니다
|
|
62
67
|
(`docs/expansion-roadmap.md`의 「vertical slice가 없는 계약」).
|
package/docs/brand-boundary.md
CHANGED
|
@@ -45,6 +45,7 @@ theme별 병합 결과를 검사하고, theme별 기준 미달 쌍을 돌려준
|
|
|
45
45
|
| --- | --- | --- |
|
|
46
46
|
| `text`·`textBody`·`textMuted`·`textSub` on `bg`·`surface` | 4.5 | WCAG 1.4.3 본문. `textSub`는 `Text tone="subtle"`의 실제 글자색이다 |
|
|
47
47
|
| `contentBrand`·`danger` on `bg`·`surface` | 4.5 | 링크·현재 위치·오류 문구는 글자로 읽힌다 |
|
|
48
|
+
| `text`·`textBody`·`textMuted`·`textSub`·`contentBrand`·`danger` on `surfaceSelected` | 4.5 | 일반 선택 면 위 글자. 선택색 분리와 적용 확대에 따른 실제 소비 쌍(2026-10-23) |
|
|
48
49
|
| `onPrimary` on `primary`, `onDanger` on `dangerFill` | 4.5 | 채운 버튼의 라벨 |
|
|
49
50
|
| `onStatusFill` on `neutralFill`·`strongFill`·고정 `accentFill.<tone>` | 4.5 | 채운 Badge의 실제 라벨·바탕 쌍 |
|
|
50
51
|
| `primary`·`borderControl` vs `bg`·`surface` | 3 | WCAG 1.4.11. 채운 컨트롤과 쉬고 있는 컨트롤 윤곽선은 형태로 식별돼야 한다 |
|
|
@@ -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.41.1. 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.41.1",
|
|
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.41.1",
|
|
9
9
|
"activeComponents": 131,
|
|
10
10
|
"claimedComponents": 131,
|
|
11
11
|
"completeScenarioComponents": 130,
|
|
@@ -7062,7 +7062,7 @@
|
|
|
7062
7062
|
},
|
|
7063
7063
|
"native": {
|
|
7064
7064
|
"packageName": "@hjmds/react-native",
|
|
7065
|
-
"packageVersion": "1.
|
|
7065
|
+
"packageVersion": "1.41.1",
|
|
7066
7066
|
"activeComponents": 113,
|
|
7067
7067
|
"claimedComponents": 113,
|
|
7068
7068
|
"completeScenarioComponents": 110,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Renderer evidence coverage
|
|
2
2
|
|
|
3
|
-
> Generated for HJM 1.
|
|
3
|
+
> Generated for HJM 1.41.1. 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/theme-palette.md
CHANGED
|
@@ -102,3 +102,63 @@ Ant의 원시 색상이나 낮은 테두리 대비까지 복제하지 않고, HJ
|
|
|
102
102
|
이전 제품 표면색을 HJM의 밝은 테마 기본값으로 채택한다. `surface`는 `#ffffff`,
|
|
103
103
|
`surfaceAlt`는 `#ebeef2`다. `bg`는 기존 흰색을 유지하며 `raised` 카드도 기존처럼 `bg`를 쓴다.
|
|
104
104
|
다크 테마와 브랜드·상태 강조색은 이번 결정의 변경 대상이 아니다. 웹·Native가 같은 `THEMES`를 소비한다.
|
|
105
|
+
|
|
106
|
+
## 기본 선택 배경을 브랜드에서 분리한다 (2026-10-23)
|
|
107
|
+
|
|
108
|
+
휠의 하늘색과 카테고리 선택색을 비교한 뒤 사용자가 기본 테마의 뉴트럴 안을 승인했다.
|
|
109
|
+
`surfaceSelected`는 light `#f0f1f3`, dark `#30343b`이고 `semanticColors.selection`이 배경·글자·테두리를 묶는다.
|
|
110
|
+
TimePicker, Chip(그룹의 chips 표현 포함)과 기본 neutral SegmentedControl이 같은 선택 배경을 쓴다.
|
|
111
|
+
글자는 기존 `text`, Chip 테두리는 `borderControl`을 쓰며 체크·선택 테두리·포커스 표시를 보존한다.
|
|
112
|
+
이 결정은 위 2026-09-29 기록의 해당 선택 배경을 대체하며 입력 필드 배경은 바꾸지 않는다.
|
|
113
|
+
`surfaceAccent`는 브랜드 보조 배경, `primary`는 주요 동작으로 유지한다.
|
|
114
|
+
명시적인 `selectionTone="brand"`와 solid 탭은 기존 브랜드 강조를 유지한다.
|
|
115
|
+
제품은 `brandPalette`의 `surfaceSelected`로 선택 배경을 지정할 수 있다. 기존 팔레트 대비 검사에 `text`/`surfaceSelected` 4.5:1 쌍을 포함한다.
|
|
116
|
+
|
|
117
|
+
## 선택 상태 색상 기준 (2026-10-23)
|
|
118
|
+
|
|
119
|
+
기본 테마의 선택 토큰이 일부 컴포넌트에만 연결된 공백을 사용자 검토에서 확인했다.
|
|
120
|
+
색 이름이나 HTML `aria-selected`만으로 일괄 치환하지 않고, 제품에서 유지하는 값인지
|
|
121
|
+
현재 키보드/포인터 조작 위치인지에 따라 다음처럼 적용한다. 각 API의 기존 지원 플랫폼에 적용한다.
|
|
122
|
+
|
|
123
|
+
| 의미 | 색상 기준 | 해당 공개 표면 |
|
|
124
|
+
| --- | --- | --- |
|
|
125
|
+
| 지속되는 일반 선택 면 | `selection.background`/`selection.content`, 경계가 필요하면 `selection.border` | Chip·칩 그룹, neutral SegmentedControl, TimePicker, filled Tabs, capsule BottomNavigation, ReactionPicker, ToggleGroup, selected Button·IconButton, 선택 Card·ListRow·Select·Combobox·Menu·Tree·TransferList·DataTable 행 |
|
|
126
|
+
| 현재 조작 위치 | 기존 focus/hover/pressed 역할. 확정 선택과 합치지 않음 | CommandPalette·Mentions·TagsInput 제안의 active descendant, Select·Combobox의 active 항목, 포커스 링 |
|
|
127
|
+
| 명시적인 진한 브랜드 면 | `primary`/`onPrimary` | `Tabs indicator="solid"`, `SegmentedControl selectionTone="brand"`, `BottomNavigation selection="tile"`, prominent destination |
|
|
128
|
+
| 작은 값 표시·현재 위치 표시 | 기존 전용 체크·점·밑줄·테두리 계약 | Checkbox·Radio의 glyph, Switch on, Calendar 날짜 원, underline/text Tabs, 일반 BottomNavigation 아이콘·글자, Pagination·Steps·Anchor·Carousel 위치 표시, 읽기 전용 반응 요약 |
|
|
129
|
+
| 브랜드·장식·업무 강조 | 기존 브랜드/상태 역할 | ChatMessage outgoing, 폴더 그림, liquid toast, 표의 `highlighted` 업무 강조, 브랜드 Surface/Badge, 오류·성공 등 상태 |
|
|
130
|
+
| 미디어 위 선택 증거 | 읽을 수 있는 전용 링·스크림 유지 | ImageChoice·MediaSelection. 회색 면으로 사진을 덮지 않음 |
|
|
131
|
+
|
|
132
|
+
### 적용 규칙
|
|
133
|
+
|
|
134
|
+
- 선택 토큰은 현재 theme과 product palette로 해석한다. 제품별 직접 색상 분기는 추가하지 않는다.
|
|
135
|
+
- 정적 면과 이동하는 선택 배경은 같은 역할을 쓴다. reduced motion은 이동만 바꾸며 색상 의미를 바꾸지 않는다.
|
|
136
|
+
- 선택 값을 표현하는 체크·굵기·radio/pressed/selected 의미와 비활성·읽기 전용 동작은 보존한다.
|
|
137
|
+
- `Surface tone="selected"`는 선택 Card의 공통 면이다. `accent`는 브랜드 면으로 유지한다.
|
|
138
|
+
- 일반 선택을 브랜드로 보이게 하려고 primary를 바꾸거나, 포커스 위치를 확정 선택값처럼 칠하지 않는다.
|
|
139
|
+
- 선택 면에서 본문·보조·브랜드·위험 글자의 대비는 기존 palette 검사에서 각각 4.5:1을 확인한다.
|
|
140
|
+
`textWeak`의 비활성/장식 용도는 기존 경계를 따른다.
|
|
141
|
+
|
|
142
|
+
선택 Card로 적용 범위를 넓히면서 light `textSub`가 새 회색 위에서 4.46:1인 것을 확인했다.
|
|
143
|
+
선택 면 `#f0f1f3`을 유지하고 `textSub`를 `#65707d`에서 `#646f7c`로 한 단계 조정해 4.52:1로 보완했다.
|
|
144
|
+
위 2026-09-26 값은 과거 기록이며 현재 값의 근거는 이 절이다.
|
|
145
|
+
|
|
146
|
+
### 확인 경계
|
|
147
|
+
|
|
148
|
+
이 기준은 HJM 개발 소스의 의미·renderer 연결 기준이다. 새 패키지 게시, 소비 앱의 설치 버전 채택,
|
|
149
|
+
각 제품 테마의 실기기 화면 확인을 대신하지 않는다. 브라우저의 light/dark·제품 선택색 override와
|
|
150
|
+
Native host 검사를 수행한 범위를 기록하며 실기기 결과는 따로 구분한다.
|
|
151
|
+
|
|
152
|
+
2026-10-23 개발 확인: Web/Native 선택색 회귀(정적·이동 면, 제품 override, 명시적 solid 강조,
|
|
153
|
+
Combobox의 확정 선택과 활성 후보 분리), 관련 선택 동작, palette 대비 검사에서 총 123건 통과했다.
|
|
154
|
+
기본 neutral을 포함한 11개 preset의 light/dark 22개 팔레트에서도 새 선택 면의 글자 대비 쌍을 확인했다.
|
|
155
|
+
Web의 `core-normalization.ssr.test.tsx` 중 기존 small Button/IconButton hit-slop CSS 문자열 검사
|
|
156
|
+
2건은 변경 전 HEAD에서도 불일치하며, 이번 선택색과 무관한 실패로 남겼다. 변경한 Card/선택 상태
|
|
157
|
+
검사는 통과했다. 세 패키지 소스 빌드는 통과했으며 Native 실기기 확인·패키지 게시·소비 앱 채택은 미실행이다.
|
|
158
|
+
|
|
159
|
+
같은 날 후속 수정에서 남겨 둔 실패를 해결했다. Web의 오래된 hit-slop CSS 문자열 기대는
|
|
160
|
+
SSR 검사에서 제거하고 기존 브라우저 검사에서 Button/IconButton의 기본 확장·명시적 0·실제 포인터
|
|
161
|
+
hit-test와 클릭 전달을 확인한다. Native 모션 검사는 기본 스크롤 레일의 필수 layout 측정을
|
|
162
|
+
허용하되 선택 항목 노출·애니메이션 미설치·모션 미실행을 검증하도록 바로잡았다.
|
|
163
|
+
Web core SSR 15건, 브라우저 대상 동작 1건, Native 모션 3건 모두 통과했다.
|
|
164
|
+
런타임 구현 변경이나 검사 skip 추가 없이 테스트의 오래된 구현 가정을 수정한 결과다.
|
package/docs/time-picker.md
CHANGED
|
@@ -8,15 +8,36 @@
|
|
|
8
8
|
- 계약과 recipe: `src/time-picker.ts`. Web/RN: `@hjmds/react/time-picker`, `@hjmds/react-native/time-picker`.
|
|
9
9
|
- `presentation="field"`(기본): 필드 한 개 → Web Popover / Native Sheet 한 개. 두 열 선택은 초안이며 확인 버튼으로만 `onValueChange`한다. 닫기·Escape·바깥 누름·시트 dismiss는 확정하지 않는다.
|
|
10
10
|
- `presentation="inline"`: 같은 두 열을 기존 폼·시트 안에 표시한다. 최종 확인은 바깥 폼이 소유한다. 각 선택에서 완전하고 사용 가능한 값은 `HH:mm`, 미완성·선택 불가 초안은 `null`로 전달한다. 부모가 null을 반영해도 사용 중인 부분 선택은 유지한다.
|
|
11
|
+
- 2026-10-23 휠 피커 도입 요청: `selectionStyle="list"`(기본)는 기존 탭 목록, `"wheel"`은 관성 스크롤과 중앙 스냅이다. 별도의 WheelPicker를 만들지 않고 같은 초안·확정 계약을 확장했다. 추가 Native peer는 없다. 이 옵션은 개발 소스의 미게시 변경이다.
|
|
12
|
+
- 휠의 양 끝에 두 행씩 여백을 두어 첫 값·마지막 값도 중앙에 놓인다. 가장 가까운 사용 가능 행으로 스냅하고, 같은 거리이면 앞 행을 선택한다. 초기 배치·외부 값 갱신·프로그램 정렬은 선택 이벤트가 아니다. 빈 값은 첫 행을 보여도 선택하지 않으며, 기존 off-grid·불가한 조합을 자동으로 고치지 않는다.
|
|
13
|
+
- 사용자 스크롤이 지나는 사용 가능 값은 초안에 반영한다. field 확인은 스크롤 중 비활성이고 멈춘 뒤에 가능하다. inline의 각 값 변경은 바깥 폼의 초안이며 최종 확정은 바깥 폼이 소유한다. 시 변경으로 선택한 분이 불가능해져도 분을 임의로 바꾸지 않는다.
|
|
11
14
|
- 값은 `HH:mm | null`, 날짜·시간대·서머타임·현재 시각 계산은 제품 소유. 자정 `00:00`도 유효하다.
|
|
12
15
|
- `minuteStep` 기본 1. 60의 양의 정수 약수만 허용한다. 기존 값이 간격과 맞지 않아도 자동 반올림하지 않는다.
|
|
13
16
|
- `isTimeUnavailable(time)`은 제품이 제공한다. 시는 사용 가능한 분이 하나라도 있으면 선택할 수 있다. 선택한 분을 몰래 바꾸지 않으며, 그 조합이 불가하면 확인할 수 없다.
|
|
14
17
|
- 외부 `value` 변경은 초안에 반영한다. 비활성·읽기 전용으로 전환하면 열린 선택기를 닫고 확정하지 않는다.
|
|
15
18
|
- Web: 열마다 roving focus, 방향키·Home·End가 비활성 항목을 건너뛰며 선택한다. Enter/Space는 버튼 기본 동작. Popover가 초점·Escape·바깥/blur dismiss·복귀를 소유한다.
|
|
16
19
|
- Native: 각 값은 이름·checked/disabled 상태를 가진 radio이며 host 활성화를 사용한다. Sheet가 back·dismiss·safe area·복귀를 소유한다. 실제 VoiceOver/TalkBack 기기 검증과 host action 검사는 구분한다.
|
|
20
|
+
- 휠의 Web 표현은 기존 listbox·option·roving keyboard를 유지하고 CSS scroll snap과 [scrollend](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollend_event)로 멈춤을 판정한다. scrollend 지원 브라우저가 필요하며 오래된 브라우저 대상은 기존 list를 선택한다. Native는 [ScrollView의 snapToOffsets](https://reactnative.dev/docs/scrollview#snaptooffsets)와 drag/momentum 이벤트를 사용한다. 열마다 adjustable 역할과 increment/decrement로 불가한 행을 건너뛴다. 내부 radio들은 휠에서 보조기술에 중복 노출하지 않는다.
|
|
21
|
+
- 동작 줄이기는 Provider 설정을 따른다. 값 정렬을 즉시 수행하며 Native 감속률은 0으로 설정한다. 스크롤 선택과 확정·취소 의미는 유지한다.
|
|
17
22
|
|
|
18
23
|
기존 Collection/Select는 단일 선택으로 닫히는 계약이다. TimePicker는 그 wrapper가 아니라 두 부분을 한 번에 확정하는 세션이다. 목록 값과 공통 Popover/Sheet/Button을 재사용하며, 날짜 엔진이나 새 native peer를 추가하지 않는다.
|
|
19
24
|
|
|
20
25
|
디자인 모티브: [Ant Design](https://ant.design/components/time-picker/)의 통합 열·확정,
|
|
21
26
|
[Material 3](https://m3.material.io/components/time-pickers/)의 큰 시각 표시.
|
|
22
27
|
색·모서리·간격은 HJM recipe와 소비 제품의 semantic palette를 따른다.
|
|
28
|
+
|
|
29
|
+
## 2026-10-23 개발 확인 범위
|
|
30
|
+
|
|
31
|
+
공통 계약 4개, Web 브라우저 13개, Native host 10개, 검색 연결 브라우저 1개가 통과했다.
|
|
32
|
+
양 renderer의 소스 빌드와 Web·Native Showcase 타입 확인도 통과했다. Web 실화면에서 분 휠을 굴려
|
|
33
|
+
`14:30 → 14:55` 변경과 중앙 정렬을 확인했다. 전체 renderer 테스트 타입 검사에는 기존
|
|
34
|
+
`packages/react/test/selection-motion.browser.test.tsx`의 미사용 `page` import 오류가 남아 있으며 변경 범위 밖이다.
|
|
35
|
+
|
|
36
|
+
Native 실제 제스처·VoiceOver/TalkBack 확인은 **미완료**다. 기존 iPhone 17 Pro·iOS 26.5에 설치된
|
|
37
|
+
Showcase 바이너리는 RN 0.86.2이고 소스는 0.88.0이어서 호환 개발 빌드를 시도했다.
|
|
38
|
+
메뉴 헤더 import와 이미지 로더 프로토콜은 기존 pnpm 패치에서 바로잡았지만,
|
|
39
|
+
`react-native-ios-utilities@5.2.0/ios/Sources/ObjcHelpers/UIView+RNIPaperHelpers.mm:34`가 RN 0.88에서
|
|
40
|
+
제거된 `RCTSurfacePresenterBridgeAdapter.bridge`를 참조하여 빌드가 중단됐다.
|
|
41
|
+
[어댑터 이관 조건](../../../docs/interaction-adapters.md#sdk-58-native-showcase-build-blocker-2026-10-23)을 해결한 뒤
|
|
42
|
+
현재 소스로 개발 바이너리를 빌드·설치하고 휠 제스처·취소·확정·보조기술 액션을 재개해야 한다.
|
|
43
|
+
호환성 미확인을 휠의 기기 검증 완료나 패키지 게시로 해석하지 않는다.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# 쉬운 말로 찾고 비교하기
|
|
2
|
+
|
|
3
|
+
2026-10-23 [앱 UI 메뉴판](https://giting.kr/skills/app-menu)의 별칭 → 명칭 → 요청 예시 접근을 참고했다.
|
|
4
|
+
일상 표현으로 기존 HJM API에 도달하도록 안내하며, 외부 사전의 플랫폼 설명을 HJM의 지원 계약으로 사용하지 않는다.
|
|
5
|
+
|
|
6
|
+
[Storybook 컴포넌트 찾기](https://storybook.jmstudioapps.com/?path=/story/components-overview--explorer)에서
|
|
7
|
+
쉬운 말·한글 이름·API 이름을 검색한다. 현재 checkout의 개발 변경이며 공개 사이트 반영은 별도다.
|
|
8
|
+
결과 카드에서 선택 기준·요청 예시를 읽고 실행 예제와 사용 지침으로 이동한다.
|
|
9
|
+
웹 Storybook은 작성 도구이며 Web 예제로 Native 동작을 검증했다고 판단하지 않는다.
|
|
10
|
+
|
|
11
|
+
## 이름이 떠오르지 않을 때
|
|
12
|
+
|
|
13
|
+
| 찾는 말 | 먼저 볼 API·지침 | 실행 예제 |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| 아래에서 올라오는 판 | [Sheet](components/sheet.md) | [시트](https://storybook.jmstudioapps.com/?path=/story/components-overlays--sheet) |
|
|
16
|
+
| 맨 아래 붙은 버튼 | [BottomCTA](components/bottom-cta.md) | [하단 행동](https://storybook.jmstudioapps.com/?path=/story/components-actions--bottom-cta) |
|
|
17
|
+
| 목록 한 줄, 오른쪽 현재 값 | [ListRow](components/list-row.md) | [목록 행](https://storybook.jmstudioapps.com/?path=/story/components-data-display--list-row) |
|
|
18
|
+
| 밀면 나오는 삭제 버튼 | [SwipeActions](components/swipe-actions.md) | [끌기·밀기](https://storybook.jmstudioapps.com/?path=/story/experimental-interaction-adapters--default) |
|
|
19
|
+
| 꾹 눌러 순서 바꾸기 | [SortableCollection](components/sortable-collection.md) | [끌기·밀기](https://storybook.jmstudioapps.com/?path=/story/experimental-interaction-adapters--default) |
|
|
20
|
+
| 끝까지 내리면 더 나옴 | [LoadMore](components/load-more.md) | [추가 로딩](https://storybook.jmstudioapps.com/?path=/story/components-navigation--load-more) |
|
|
21
|
+
| 키보드가 입력칸을 가려 | [KeyboardFormScrollView](components/keyboard-form-scroll-view.md)·[입력 시트](compositions/input-sheet.md) | [입력 시트](https://storybook.jmstudioapps.com/?path=/story/patterns-input-sheet--default) |
|
|
22
|
+
| 갤러리·카메라 선택 | [PhotoSourceSheet](components/photo-source-sheet.md) | [사진 출처](https://storybook.jmstudioapps.com/?path=/story/components-overlays--photo-source-sheet) |
|
|
23
|
+
|
|
24
|
+
검색 결과에서 List·Form·Sheet가 나오면 카드에 안내된 선택형 API도 확인한다.
|
|
25
|
+
예를 들어 List는 표시 계약이고, SwipeActions·SortableCollection은 별도의 공개 진입점이다.
|
|
26
|
+
검색어를 공개 export 이름이나 canonical API 별칭으로 추가하지 않는다.
|
|
27
|
+
|
|
28
|
+
## 비슷한 UI 중 고르기
|
|
29
|
+
|
|
30
|
+
| 필요한 일 | 선택 | 비교할 경계 |
|
|
31
|
+
| --- | --- | --- |
|
|
32
|
+
| 앱의 주요 구역 이동 | [BottomNavigation](components/bottom-navigation.md) | 한 화면 안 짧은 보기 전환은 SegmentedControl, 관련 패널 탐색은 Tabs |
|
|
33
|
+
| 실행할 행동 고르기 | [Menu](components/menu.md) | 값 입력은 Select, 삭제 직전 확인은 AlertDialog |
|
|
34
|
+
| 보조 선택·입력 작업 | [Sheet](components/sheet.md) | 짧은 집중 작업은 Dialog. “모달”이라는 말만으로 풀스크린을 결정하지 않음 |
|
|
35
|
+
| 끌어서 높이 바꾸는 시트 | [선택형 Native GestureSheet](compositions/optional-adapters.md) | 기본 Sheet의 지원과 optional peer 설치·provider 조건을 구분 |
|
|
36
|
+
| 켜짐·꺼짐 설정 | [Switch](components/switch.md) | 여러 항목 동의는 Checkbox·Agreement, 하나의 선택지는 RadioGroup |
|
|
37
|
+
| 수량 늘리고 줄이기 | [NumberField](components/number-field.md) | Steps는 진행 단계 표시이며 수량 입력이 아님 |
|
|
38
|
+
| 처음 데이터가 없음 | [EmptyState](components/empty-state.md) | 로딩·오류·검색 결과 없음과 실제 상태를 구분 |
|
|
39
|
+
| 설정 화면 구성 | [SettingsScreen](screens/common-settings.md) | 제품에서 그룹·행 배치를 다시 조립하기 전에 화면 API부터 선택 |
|
|
40
|
+
|
|
41
|
+
웹·앱의 표현은 각 API 지침의 플랫폼 차이를 읽는다. 모든 Native Select를 시트로 바꾸거나,
|
|
42
|
+
모든 모달을 풀스크린으로 만드는 규칙은 두지 않는다. 화면 이동·딥링크·스플래시 초기화·권한·서버 저장은
|
|
43
|
+
[제품 소유 경계](SELECTION.md#소유권)다. HJM에는 공통 표시와 상호작용을 연결한다.
|
|
44
|
+
|
|
45
|
+
## 요청을 구현으로 연결하기
|
|
46
|
+
|
|
47
|
+
`화면 목적 + 필요한 구조 + 실제 상태 + 제품 콜백`으로 요청한다. 배치·지원 prop은 연결한 지침이 정본이다.
|
|
48
|
+
|
|
49
|
+
| 요청 예시 | 수정 위치 → 공개 API → 확인 범위 |
|
|
50
|
+
| --- | --- |
|
|
51
|
+
| “설정을 계정·알림·정보 그룹으로 나누고 행 오른쪽에 현재 값을 보여줘” | 제품 설정 데이터 → SettingsScreen·ListRow → 그룹 순서·값·행동 연결 |
|
|
52
|
+
| “댓글 더보기에서 신고·차단을 고르게 해줘” | 제품의 허용 행동 → Menu의 anchored 표현 → 대상·닫힘·후속 행동. [메뉴 지침](components/menu.md) |
|
|
53
|
+
| “사진 출처를 고른 뒤 카메라를 열어줘” | 제품 권한·picker adapter → PhotoSourceSheet → 닫힘 뒤 실행·권한 거부. [사진 출처 지침](components/photo-source-sheet.md) |
|
|
54
|
+
| “저장 실패하면 입력을 유지하고 키보드가 마지막 필드를 가리지 않게 해줘” | 제품 초안·요청 상태 → Form과 입력 host → 실패 후 초안·필드 도달·저장 행동. [입력 시트](compositions/input-sheet.md) |
|
|
55
|
+
|
|
56
|
+
공통 배치가 부족하면 제품별 보정 여백을 더하지 않고 [선택 기준](SELECTION.md)에 따라 HJM 소유 구현을 보완한다.
|
|
57
|
+
필요한 검사만 고르며 이 안내는 새 자동 검사나 승인 절차를 추가하지 않는다.
|
|
58
|
+
|
|
59
|
+
## 휠 피커 검토 결과
|
|
60
|
+
|
|
61
|
+
2026-10-23 구현: [TimePicker](components/time-picker.md)는 Web·Native 모두 `selectionStyle="wheel"`로
|
|
62
|
+
관성 스크롤과 중앙 스냅을 제공한다. 기본 `list`는 기존 탭 목록이다. 휠 옵션은 개발 소스의 미게시 변경이며,
|
|
63
|
+
검색에서 “휠 피커”를 입력하면 기존 TimePicker와 실행 예제로 연결한다.
|
|
64
|
+
|
|
65
|
+
선택한 설계는 **시각 선택에는 기존 TimePicker를 확장하는 방식**이다. 일반 WheelPicker를 먼저 별도로 만들면
|
|
66
|
+
초안·확정·취소·사용 불가 시각 계약이 중복된다. 기존 `HH:mm | null` 값·`minuteStep`·선택 불가 판정·명시적 확정을 유지하고,
|
|
67
|
+
선택 표현 옵션으로 스냅·관성·중앙 선택 표시를 추가했다. 일반 항목 선택 요구가 실제로 생기면
|
|
68
|
+
공유할 내부 선택 엔진의 범위를 판단한다.
|
|
69
|
+
|
|
70
|
+
검증은 스크롤 초안과 최종 확정, 불가능한 값 건너뛰기, 취소 복원, 보조기술 액션, 동작 줄이기와
|
|
71
|
+
플랫폼별 실제 동작으로 나눈다. host 검사·브라우저 검사·Native 기기 확인의 결과는 각각 구분한다.
|
package/docs/usage/README.md
CHANGED
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
단계는 Storybook과 같은 `토큰 → 컴포넌트 → 구성 → 화면`이다. 화면을 만들 때는 화면 지침의 영역 구조와
|
|
6
6
|
버튼 위치에서 시작해 구성·컴포넌트 지침으로 내려가고, 값은 토큰 지침에서 고른다.
|
|
7
7
|
[선택 기준](SELECTION.md)으로 그대로 사용·공개 슬롯 확장·공통 API 보완·제품 고유 기능 연결을 고른다. 설치 버전의 지침을 본다: `node_modules/@hjmds/design-contracts/docs/usage/`.
|
|
8
|
+
이름을 모르면 [쉬운 말로 찾고 비교하기](FINDING.md)에서 일상 표현과 선택 기준·요청 예시로 시작한다.
|
|
8
9
|
제공 기준은 확인한 기본 API 버전이며 최초 출시 버전이 아니다. 구성·화면은 각 API 지침의 제공 버전을 확인한다.
|
|
9
|
-
API 안정성은 1.
|
|
10
|
+
API 안정성은 1.40.0의 생성 manifest에서 읽은 정규(canonical) API 기준이다. 동반·선택형 확장은 개별 계약을 확인한다.
|
|
10
11
|
Storybook 배포/실험은 예제 분류이며 npm 게시·기기 검증·제품 반영을 의미하지 않는다.
|
|
11
12
|
`분류`는 Storybook 제목 `<배포|실험>/<단계>/<분류>/<항목>`의 셋째 마디이고, 토큰·구성·화면은 Storybook 메뉴와 같은 순서다.
|
|
12
13
|
|
|
@@ -63,6 +64,7 @@ Storybook 배포/실험은 예제 분류이며 npm 게시·기기 검증·제품
|
|
|
63
64
|
| [Checkbox](components/checkbox.md) | 입력 | 독립된 예/아니오 하나를 고르는 항목에 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
|
|
64
65
|
| [CheckboxGroup](components/checkbox-group.md) | 입력 | 한 질문에 대한 여러 선택지 중 0개 이상을 고르게 할 때 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
|
|
65
66
|
| [Chip](components/chip.md) | 입력 | 누를 수 있는 작은 pill이다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
|
|
67
|
+
| [ChoiceRow](components/choice-row.md) | 입력 | 설정 화면에서 언어·화면 테마·기본 정렬처럼 **여러 값 중 하나를 고르는 설정**에 쓴다. | 1.41.0 | Web · Native | 개별 API 계약 참조 | 배포 |
|
|
66
68
|
| [CodeBlock](components/code-block.md) | 데이터 표시 | 코드·명령·설정 조각을 읽기 전용으로 보여 주고 사용자가 선택·복사하게 할 때 쓴다. | 1.12.1 | Web · Native | 개별 API 계약 참조 | 배포 |
|
|
67
69
|
| [CohortRetentionTable](components/cohort-retention-table.md) | 구성/정보 표시 | 가입 시점(코호트)별로 기간마다 남은 인원 비율을 직사각형 표와 heat 색으로 비교할 때 쓴다. | 1.21.0 | Web · Native | 개별 API 계약 참조 | 배포 |
|
|
68
70
|
| [Collapsible](components/collapsible.md) | 데이터 표시 | 이웃 없이 혼자 접었다 펴는 한 덩어리에 쓴다. | 1.12.1 | Web · Native | Web stable / Native stable | 배포 |
|
|
@@ -108,7 +110,7 @@ Storybook 배포/실험은 예제 분류이며 npm 게시·기기 검증·제품
|
|
|
108
110
|
| [ImageComparison](components/image-comparison.md) | 데이터 표시 | 같은 좌표와 비율의 두 이미지를 겹쳐 변화량을 비교할 때 쓴다. | 1.14.0 | Web · Native | 개별 API 계약 참조 | 배포 |
|
|
109
111
|
| [ImportFieldMapping](components/import-field-mapping.md) | 구성/입력과 작성 | CSV 등 원본 열을 제품의 대상 필드에 연결하고, 검증을 통과한 연결만 가져오기로 넘길 때 쓴다. | 1.21.0 | Web · Native | 개별 API 계약 참조 | 배포 |
|
|
110
112
|
| [InlineEdit](components/inline-edit.md) | 구성/입력과 작성 | 목록·상세의 제목처럼 이미 확정된 짧은 값 하나를 그 자리에서 명시적으로 편집·저장·취소할 때 쓴다. | 1.21.0 | Web · Native | 개별 API 계약 참조 | 배포 |
|
|
111
|
-
| [KeyboardAvoidanceContext](components/keyboard-avoidance-context.md) | — | 제품이 직접 만든 키보드 대응 영역 안에서 HJM `ScreenLayout`·`Sheet`가 여백을 두 번 주지 않게 할 때 쓴다. |
|
|
113
|
+
| [KeyboardAvoidanceContext](components/keyboard-avoidance-context.md) | — | 제품이 직접 만든 키보드 대응 영역 안에서 HJM `ScreenLayout`·`Sheet`가 여백을 두 번 주지 않게 할 때 쓴다. | 1.27.0 | Native | 개별 API 계약 참조 | 배포 |
|
|
112
114
|
| [KeyboardAvoiding](components/keyboard-avoiding.md) | — | 추가 native peer 없이 하단 행동(BottomCTA, 채팅 입력창)이 소프트웨어 키보드에 가려지지 않게 할 때 쓴다. | 1.12.1 | Native | 개별 API 계약 참조 | 배포 |
|
|
113
115
|
| [KeyboardDock](components/keyboard-dock.md) | 구성/직접 조작과 모션 | `react-native-keyboard-controller`를 설치한 앱에서 화면 하단에 고정된 행동(BottomCTA, 채팅 입력창)이 키보드와 함께 위아래로 움직이게 할 때 쓴다(Native 전용, 별도 보조 기능. API 성숙도는 실험적 어댑터). 내부는 `KeyboardStickyView`이며, 여백을 바꾸는 대신 키보드 움직임을 따라 translate 한다. | 1.12.1 | Native | 개별 API 계약 참조 | 배포 |
|
|
114
116
|
| [KeyboardFormScrollView](components/keyboard-form-scroll-view.md) | 구성/직접 조작과 모션 | 입력 필드가 여러 개인 세로 스크롤 폼(가입, 프로필 수정, 주소 입력)에서 포커스된 필드가 키보드에 가려지지 않게 스크롤해 줄 때 쓴다(Native 전용, 별도 보조 기능. API 성숙도는 실험적 어댑터). 내부는 `react-native-keyboard-controller`의 `KeyboardAwareScrollView`이고, `keyboardShouldPersistTaps="handled"`로 고정돼 키보드가 열린 채 버튼을 눌러도 탭이 전달된다. | 1.12.1 | Native | 개별 API 계약 참조 | 배포 |
|
|
@@ -262,7 +264,7 @@ Storybook 배포/실험은 예제 분류이며 npm 게시·기기 검증·제품
|
|
|
262
264
|
| [보관과 실행 취소](compositions/action-recovery-undo.md) | 피드백과 복구 | 보관·숨기기·목록에서 빼기처럼 제품이 역연산을 제공하는 작업 뒤에, 같은 자리에서 실행 취소를 주고 그 복구 요청이 성공해야 화면을 되돌릴 때 쓴다. | 1.12.1 | Web · Native | 구성 API별 | 배포 |
|
|
263
265
|
| [선택과 오류 복구](compositions/upload-recovery.md) | 피드백과 복구 | 파일 선택과 전송 상태의 취소·재시도를 연결할 때 쓴다. | 1.14.0 | Web · Native | 구성 API별 | 배포 |
|
|
264
266
|
| [스트림 응답과 중지](compositions/streaming-answer.md) | 피드백과 복구 | 실제 provider가 보내는 응답 delta를 표시하고 중지·재생성·오류를 같은 영역에서 제공할 때 쓴다. | 1.21.0 | Web · Native | 구성 API별 | 배포 |
|
|
265
|
-
| [저장 결과](compositions/save-feedback.md) | 피드백과 복구 | 실제 영속 저장 성공 뒤 짧게 결과를 알린다. | 1.37.1 | Web · Native | 구성 API별 |
|
|
267
|
+
| [저장 결과](compositions/save-feedback.md) | 피드백과 복구 | 실제 영속 저장 성공 뒤 짧게 결과를 알린다. | 1.37.1 | Web · Native | 구성 API별 | 배포 |
|
|
266
268
|
| [저장과 재시도](compositions/action-recovery-save.md) | 피드백과 복구 | 입력한 내용을 서버에 저장하는 폼 한 덩어리에서 저장 중 중복 실행을 막고, 실패하면 입력을 지우지 않은 채 제출했던 값 그대로 다시 보낼 때 쓴다. | 1.12.1 | Web · Native | 구성 API별 | 배포 |
|
|
267
269
|
| [전송 진행과 취소](compositions/transfer-task.md) | 피드백과 복구 | 실제 다운로드·업로드·작업의 시작/대기/진행·취소·실패 복구를 한 구성으로 제공할 때 쓴다. | 1.21.0 | Web · Native | 구성 API별 | 배포 |
|
|
268
270
|
| [중단해도 남는 현재 상태](compositions/expo-interactions.md) | 피드백과 복구 | 버튼으로 상태를 빠르게 바꾸거나 전환 도중 내용을 닫아도 현재 상태가 바로 보이고 남아야 하는 영역에 쓴다. | 1.12.1 | Native | 구성 API별 | 배포 |
|
package/docs/usage/SELECTION.md
CHANGED
|
@@ -30,6 +30,12 @@
|
|
|
30
30
|
|
|
31
31
|
## 선택 기준
|
|
32
32
|
|
|
33
|
+
선택 상태의 색상은 [기본 테마 선택 상태 기준](../theme-palette.md#선택-상태-색상-기준-2026-10-23)을 따른다.
|
|
34
|
+
지속되는 선택, 현재 조작 위치, 명시적 브랜드 강조를 구분하고 공통 recipe에서 연결한다.
|
|
35
|
+
|
|
36
|
+
이름을 모르면 [쉬운 말로 찾고 비교하기](FINDING.md)에서 일상 표현·유사 UI 차이·요청 예시로 시작한다.
|
|
37
|
+
Storybook의 기존 **컴포넌트 찾기**에서도 같은 쉬운 말로 검색해 실행 예제를 연다.
|
|
38
|
+
|
|
33
39
|
| 선택 | 조건 | 구현 경로 |
|
|
34
40
|
| --- | --- | --- |
|
|
35
41
|
| 그대로 사용 | 제공하는 화면·구성이 제품의 목적에 맞는다 | HJM 공개 API에 데이터·문구·콜백 연결 |
|
|
@@ -71,8 +77,8 @@ HJM의 기존 API를 확장하거나 하위 구성을 공개한다. 도메인
|
|
|
71
77
|
|
|
72
78
|
| 의도 | 쓸 것 | 쓰지 않을 것 |
|
|
73
79
|
| --- | --- | --- |
|
|
74
|
-
| 하나 고르기(주제·정렬·탭) | `Chip`(`selectionMode="single"`), `SegmentedControl`, `RadioGroup
|
|
75
|
-
| 여러 개 고르기 | `Chip`(`selectionMode="multiple"`), `CheckboxGroup` | 버튼 토글 |
|
|
80
|
+
| 하나 고르기(주제·정렬·탭) | `Chip`(`selectionMode="single"`), `SegmentedControl`, `RadioGroup` | `selected`를 준 `Button` 나열, `ToggleGroup`(단일 모드가 없는 다중 토글 계약) |
|
|
81
|
+
| 여러 개 고르기 | `Chip`(`selectionMode="multiple"`), `CheckboxGroup`, 짧은 서식·필터 토글 묶음은 `ToggleGroup` | 버튼 토글 |
|
|
76
82
|
| 켜고 끄기 설정 | `Switch`(제목·설명 포함), 설정 목록은 `ListRow` + `Switch` | "○○ 켜짐/꺼짐" 글자 버튼 |
|
|
77
83
|
| 주 행동 | 화면 지침의 "버튼과 행동 위치"대로 하나의 primary, 하단 고정이면 `BottomCTA`/`footer` | 같은 표면에 경쟁하는 primary 여럿, 폭이 제각각인 버튼 줄 |
|
|
78
84
|
| 보조 행동 | 주 행동 아래 같은 폭 secondary, 또는 헤더 `actions` | 본문 중간에 흩어진 버튼, 나가기를 보조 행동으로 두기 |
|
|
@@ -274,3 +274,8 @@ floating 그림자는 그리지 않는다. 옆면이 높이를 표현하므로
|
|
|
274
274
|
개발 브라우저에서 Native renderer를 실행할 때도 현재 목적지의 선택 상태와 비활성 상태를 전달한다.
|
|
275
275
|
Tab은 탐색 막대에 한 번 진입하고, 방향키·Home·End는 포커스만 옮긴다. Enter·Space로 목적지를
|
|
276
276
|
활성화하며 실제 경로 선택은 계속 제품 navigator가 공급한다.
|
|
277
|
+
|
|
278
|
+
### 기본 선택 면
|
|
279
|
+
|
|
280
|
+
`presentation: "capsule"`의 선택 항목은 `selectionCapsule`의 neutral 선택 배경과 글자를 쓴다.
|
|
281
|
+
기본 아이콘·글자 탐색의 위치 강조와 명시적 `selection: "tile"`의 브랜드 면은 기존 계약을 따른다.
|
|
@@ -79,12 +79,12 @@ Web·Native 모두 기존 `raised` Surface의 테두리·그림자를 재사용
|
|
|
79
79
|
|
|
80
80
|
| prop | 값 | 기본값 | 설명 |
|
|
81
81
|
| --- | --- | --- | --- |
|
|
82
|
-
| `tone` | `default` · `raised` · `accent` · `sunken` · `subtle`(Surface tone) | `raised` | 테두리와 공통 raised shadow로 입체감 표시. 평면 카드는 `tone="default"` 지정 |
|
|
82
|
+
| `tone` | `default` · `raised` · `accent` · `sunken` · `subtle` · `selected`(Surface tone) | `raised` | 테두리와 공통 raised shadow로 입체감 표시. 평면 카드는 `tone="default"` 지정 |
|
|
83
83
|
| `badgesAlign` | `start` · `center` | `start` | 미게시. 들판 대표 카드처럼 그림 아래의 배지 묶음을 가운데 배치할 때 `center` 사용. 줄바꿈된 행에도 적용 |
|
|
84
84
|
| `bordered` | `boolean` | `true` | Surface 기본 `false`와 다르다 |
|
|
85
85
|
| `padding` | spacing 이름 | `md`(16) | — |
|
|
86
86
|
| `radius` | radius 이름 | `lg`(foundation 16) | 선택한 designProfile의 같은 radius 역할로 frame과 media clip을 함께 변경 |
|
|
87
|
-
| `selected` | `boolean` | `false` | `true`면 tone이 `
|
|
87
|
+
| `selected` | `boolean` | `false` | `true`면 tone이 `selected`로 바뀐다(`cardRecipe.selectedTone`) |
|
|
88
88
|
| `headingLevel`(Web만) | `2` · `3` · `4` | `3` | 제목이 `h3`로 렌더되므로 문서 위계에 맞춰 고른다 |
|
|
89
89
|
| `title` · `description` · `leading` · `media` · `badges` · `actions` · `children` | `ReactNode` | — | 슬롯. 순서는 HJM이 고정한다 |
|
|
90
90
|
| `headerActions` | `ReactNode` | 없음 | 미게시. 제목 줄 끝의 배지·독립 명령. 카드 열기와 별도 대상으로 남으며 HJM이 위치와 제목 여유 폭을 소유한다 |
|
|
@@ -76,7 +76,7 @@ import { Chip } from "@hjmds/react-native/inputs";
|
|
|
76
76
|
| --- | --- | --- |
|
|
77
77
|
| 크기 | 내용 폭. 최소 높이 `small` 36 · `medium` 44(`control.chipHeight`, 두 플랫폼 모두 최소값이라 라벨이 크면 늘어난다), 모서리 `radius.full`. `small`은 위아래 4를 넓혀(Native hitSlop, Web `::after`) 터치 영역을 44에 맞춘다 | `chipRecipe.sizes`, `react-native/src/inputs.tsx` |
|
|
78
78
|
| 간격 | 좌우 여백 `small` `spacing.sm` 12 · `medium` `spacing.md` 16, 아이콘↔라벨 `small` `spacing.xxs` 4 · `medium` `spacing.xs` 8(두 플랫폼). 칩 사이는 부모가 정한다(`spacing.xs` 8 권장) | `chipRecipe.sizes`, `.hjm-chip` |
|
|
79
|
-
| 순서·정렬 | 필터 줄·태그 묶음으로 가로로 나란히 둔다. 안쪽은 [선택 표시] → [leading] → [라벨] → [trailing]. 선택 상태는
|
|
79
|
+
| 순서·정렬 | 필터 줄·태그 묶음으로 가로로 나란히 둔다. 안쪽은 [선택 표시] → [leading] → [라벨] → [trailing]. 선택 상태는 `surfaceSelected` 회색 배경·`text` 글자·`borderControl` 테두리와 체크 표시 | `chipRecipe.slots`, `.hjm-chip[data-selected]` |
|
|
80
80
|
| 고정·스크롤 | 고정 영역이 없다. 칩이 많으면 부모가 줄바꿈하거나 가로 스크롤 영역을 둔다. 검색 화면의 필터 칩 줄은 [SearchScreen](search-screen.md) `filtersOverflow="scroll"`이 가로 스크롤을 소유한다 | `SearchScreen` |
|
|
81
81
|
| 좁은 폭·큰 글자 | 라벨이 줄바꿈된다(Web `overflow-wrap: anywhere`). 높이는 최소값이라 라벨 높이만큼 늘어난다(Web `min-block-size`, Native `minHeight`) | `.hjm-chip__label`, Native `Chip` |
|
|
82
82
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# ChoiceRow
|
|
2
|
+
|
|
3
|
+
- 단계: 컴포넌트
|
|
4
|
+
- 상태: 배포
|
|
5
|
+
- 지원: Web · Native
|
|
6
|
+
- 적용: 1.41.0
|
|
7
|
+
- 검토일: 2026-10-23
|
|
8
|
+
- 근거: `src/choice-row.ts`(`resolveChoiceRow`). 2026-10-23 조사에서 언어 설정 행을 spint(`Select`)·utilverse(`ListRow`+`Sheet`+`RadioGroup`)·번뚝(자체 시트)이 각자 만들고, 테마 전환도 번뚝·야잘알이 따로 구현하고 있어 HJM으로 옮겼다.
|
|
9
|
+
- 스토리북: `배포/컴포넌트/입력/설정 값 선택`
|
|
10
|
+
|
|
11
|
+
## 언제 쓰나
|
|
12
|
+
|
|
13
|
+
설정 화면에서 언어·화면 테마·기본 정렬처럼 **여러 값 중 하나를 고르는 설정**에 쓴다. 행에는 현재 확인된 값을 보여 주고,
|
|
14
|
+
누르면 시트에서 고른다. 저장이 비동기면 시트가 저장 중으로 잠기고, 실패하면 시트를 연 채 오류를 보여 준다.
|
|
15
|
+
행에는 제품이 저장을 확인한 값만 보이므로, 실패한 선택이 저장된 것처럼 남지 않는다.
|
|
16
|
+
|
|
17
|
+
## 쓰지 않을 때
|
|
18
|
+
|
|
19
|
+
| 상황 | 대신 쓸 것 |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| 켜고 끄기 설정 | [Switch](switch.md)를 둔 [ListRow](list-row.md) |
|
|
22
|
+
| 폼 안에서 여러 필드와 함께 제출하는 선택 | [Select](select.md) 또는 [RadioGroup](radio-group.md) |
|
|
23
|
+
| 선택지가 화면에 펼쳐져 있어야 함(2~4개, 즉시 비교) | [SegmentedControl](segmented-control.md) 또는 [RadioGroup](radio-group.md) |
|
|
24
|
+
| 선택 외에 입력·설명이 많은 편집 패널 | [Sheet](sheet.md)를 직접 구성 |
|
|
25
|
+
|
|
26
|
+
## 공개 이름과 import
|
|
27
|
+
|
|
28
|
+
| 이름 | 역할 | Web | Native |
|
|
29
|
+
| --- | --- | --- | --- |
|
|
30
|
+
| `ChoiceRow` | 독립 supplemental. root에서는 내보내지 않는다 | `@hjmds/react/choice-row` | `@hjmds/react-native/choice-row` |
|
|
31
|
+
| `ChoiceRowItem` | 선택지 타입 | 같은 경로 | 같은 경로 |
|
|
32
|
+
|
|
33
|
+
## 최소 사용 예
|
|
34
|
+
|
|
35
|
+
```tsx
|
|
36
|
+
// Web
|
|
37
|
+
import { ChoiceRow } from "@hjmds/react/choice-row";
|
|
38
|
+
<ChoiceRow title={t("language")} items={languages} value={confirmedLanguage}
|
|
39
|
+
onValueChange={(next) => savePreference({ language: next })} closeLabel={t("close")} errorLabel={t("saveFailed")} />
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
// Native
|
|
44
|
+
import { ChoiceRow } from "@hjmds/react-native/choice-row";
|
|
45
|
+
<ChoiceRow title={t("language")} items={languages} value={confirmedLanguage}
|
|
46
|
+
onValueChange={(next) => savePreference({ language: next })} closeLabel={t("close")} errorLabel={t("saveFailed")} />
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
`savePreference`가 성공한 뒤에 제품이 `confirmedLanguage`를 바꾼다. "기기 설정 따르기"는 `items`의 한 선택지로 넣는다.
|
|
50
|
+
|
|
51
|
+
## 축과 기본값
|
|
52
|
+
|
|
53
|
+
| prop | 값 | 기본값 | 설명 |
|
|
54
|
+
| --- | --- | --- | --- |
|
|
55
|
+
| `value` | 선택지 값 또는 null | 필수 | 제품이 확인한 값. null이면 `placeholder`가 필요하다 |
|
|
56
|
+
| `items` | `ChoiceRowItem[]` | 필수 | 2개 이상, 값 중복 금지. `description`·`disabled` 지원 |
|
|
57
|
+
| `onValueChange` | `(value) => void \| Promise<void>` | 필수 | Promise를 돌려주면 끝날 때까지 시트가 잠긴다. 거부되면 시트를 연 채 `errorLabel`을 보인다 |
|
|
58
|
+
| `sheetTitle`·`sheetDescription` | string | `title`·없음 | 시트 머리 |
|
|
59
|
+
| `leading`·`trailing` | ReactNode | 없음 | 제품 아이콘·꼬리 표시. ListRow 슬롯 그대로 |
|
|
60
|
+
| Native `accessibilityHint` | string | 없음 | 행을 눌렀을 때 일어날 일(예: 언어 목록 열기)을 제품 언어로 |
|
|
61
|
+
| `disabled`·`loading` | boolean | false | ListRow의 비활성·자리 유지 로딩 |
|
|
62
|
+
|
|
63
|
+
## 배치
|
|
64
|
+
|
|
65
|
+
| 항목 | 값 | 근거 |
|
|
66
|
+
| --- | --- | --- |
|
|
67
|
+
| 크기 | ListRow 기본 높이와 터치 영역. 시트는 내용 높이(`size="auto"`) | [ListRow](list-row.md#배치), [Sheet](sheet.md#배치) |
|
|
68
|
+
| 간격 | ListRow·RadioGroup recipe 간격을 그대로 쓴다 | 같은 recipe |
|
|
69
|
+
| 순서·정렬 | 행: leading → 제목·현재 값(description) → trailing. 시트: 제목 → 설명 → 세로 선택지 → 오류 | [설정 화면](../screens/common-settings.md#버튼과-행동-위치) |
|
|
70
|
+
| 고정·스크롤 | 행은 바깥 화면 스크롤을 따른다. 선택지가 길면 시트 본문이 스크롤된다 | Sheet |
|
|
71
|
+
| 좁은 폭·큰 글자 | 제목과 현재 값이 줄바꿈되며 행 높이가 늘어난다 | ListRow |
|
|
72
|
+
|
|
73
|
+
## 꼭 지킬 것
|
|
74
|
+
|
|
75
|
+
- `value`는 저장이 확인된 값만 넣는다. 선택 직후 낙관적으로 바꾸면 실패해도 행이 바뀐 값으로 남는다.
|
|
76
|
+
- 즉시 저장 설정에 쓴다. 하단 저장 버튼으로 모아 저장하는 설정은 [설정 화면의 일괄 저장](../screens/common-settings.md#즉시-저장과-일괄-저장-선택)대로 초안을 따로 둔다.
|
|
77
|
+
- 저장 중에는 시트를 닫거나 다른 값을 고를 수 없다. 다시 고르면 이전 오류는 지워진다.
|
|
78
|
+
- 행은 시트가 열렸는지를 낭독한다(Web `aria-expanded`·`aria-haspopup="dialog"`, Native `expanded`). 시트는 머리를 고정하고 선택지만 스크롤한다(1.41.1, utilverse 언어 행 이관에서 확인).
|
|
79
|
+
- 문구·선택지·저장은 제품이 공급한다. 언어 목록이나 테마 적용 로직은 이 컴포넌트에 없다.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# KeyboardAvoidanceContext
|
|
2
2
|
|
|
3
3
|
- 단계: 컴포넌트
|
|
4
|
-
- 상태:
|
|
4
|
+
- 상태: 배포
|
|
5
5
|
- 지원: Native
|
|
6
|
-
- 적용:
|
|
7
|
-
- 검토일: 2026-10-
|
|
6
|
+
- 적용: 1.27.0
|
|
7
|
+
- 검토일: 2026-10-23
|
|
8
8
|
- 근거: Native `src/keyboard.tsx`; 2026-10-16 키보드 전수 조사에서 바깥 KeyboardAvoiding과 안쪽 ScreenLayout이 같은 키보드 이벤트에 동시에 여백을 주지 않게 하려고 추가
|
|
9
9
|
- 스토리북: 없음
|
|
10
10
|
|
|
@@ -132,7 +132,7 @@ import { SegmentedControl } from "@hjmds/react-native/inputs";
|
|
|
132
132
|
|
|
133
133
|
- `presentation="pills"`: 카테고리·작성자·기간처럼 같은 목록의 범위를 좁힐 때 쓴다.
|
|
134
134
|
- 표면 높이·좌우 여백·글자는 같은 size의 Chip과 맞춘다. 터치 영역은 최소 `control.minTouchTarget` 44이며 안쪽 표면은 위아래 `spacing.xxs` 4만큼 들어간다. 2026-10-20 Utilverse 혼합 필터 행에서 작은 Chip36과 pill28의 불일치가 확인돼 공통 크기로 정렬했다(미게시). 누름 영역은 줄이지 않는다.
|
|
135
|
-
- 좌우 여백은 Chip과 같이 small12/medium16, 항목 사이 `spacing.xs` 8, 모서리 `radius.full`. 비선택은 `surface.raised`(`canvas`) 바탕과 `border.control` 1pt 테두리, 선택은 `
|
|
135
|
+
- 좌우 여백은 Chip과 같이 small12/medium16, 항목 사이 `spacing.xs` 8, 모서리 `radius.full`. 비선택은 `surface.raised`(`canvas`) 바탕과 `border.control` 1pt 테두리, 기본 선택은 `selection.background`(`surfaceSelected`)/`selection.content`(`text`) 조합이다. 2026-10-20 Utilverse의 파스텔 배경에서 비선택 버튼 경계가 묻힌 사용자 지적에 따라 inset 표면을 공통으로 보완했다(미게시). 색은 제품 provider에서 따라온다.
|
|
136
136
|
- 항목은 내용 폭이며 좁아지면 줄바꿈한다. 큰 글자에서도 세로로 쌓지 않는다(`pills.largeTextLayout` `wrap`): 블록 안에서는 줄바꿈하고, 가로 스크롤 줄 안에서는 한 줄로 남아 스크롤된다. 라벨 높이만큼 항목도 늘어난다. 선택 상태(radio)와 포커스 이동(Web 화살표, Native 접근성 순서)은 배치와 관계없이 같다.
|
|
137
137
|
- 그룹 이름은 `label`, 하나의 선택은 `value`/`onValueChange`. 복수 조건은 ToggleGroup, 화면 이동은 Tabs/Navigation을 쓴다.
|
|
138
138
|
- 예제의 전체 선택값도 실제 항목으로 넣는다. 선택된 항목을 다시 눌러도 선택을 해제하지 않는다.
|
|
@@ -62,7 +62,7 @@ import { Surface } from "@hjmds/react-native/primitives";
|
|
|
62
62
|
|
|
63
63
|
| prop | 값 | 기본값 | 설명 |
|
|
64
64
|
| --- | --- | --- | --- |
|
|
65
|
-
| `tone` | `default` · `raised` · `sunken` · `accent` · `subtle` | `default` | `raised`는 그림자, `accent`는 primary 색 테두리.
|
|
65
|
+
| `tone` | `default` · `raised` · `sunken` · `accent` · `subtle` · `selected` | `default` | `raised`는 그림자, `accent`는 primary 색 테두리. `selected`는 `surfaceSelected` 배경, 나머지는 테마 `bg` 바탕에 테두리·그림자로 위계를 나타낸다 |
|
|
66
66
|
| `padding` | `none` 또는 spacing 토큰(`xxs`~`xxxl`) | `none` | — |
|
|
67
67
|
| `radius` | `sm` · `md` · `lg` · `xl` · `full` | `lg`(16) | — |
|
|
68
68
|
| `bordered` | `boolean` | 생략 시 테두리 그림 | 모든 tone이 `borderAlways`. `bordered={false}`로만 끈다 |
|
|
@@ -104,3 +104,9 @@ subtree라 질감을 바꾸거나 host가 실패해도 본문/초안은 유지
|
|
|
104
104
|
| 그림자(`raised`) | CSS | `elevation: 4`와 iOS shadow |
|
|
105
105
|
| ref | `forwardRef` | 없음 |
|
|
106
106
|
| import 경로 | `/layout` | `/primitives` |
|
|
107
|
+
|
|
108
|
+
### 선택 면
|
|
109
|
+
|
|
110
|
+
`tone="selected"`는 `surfaceSelected` 배경과 `borderControl` 경계를 사용한다.
|
|
111
|
+
선택 Card는 공통 `cardRecipe.selectedTone`을 통해 이 면을 사용한다.
|
|
112
|
+
브랜드 `accent`나 포커스 위치를 일반 선택 면으로 대신하지 않는다.
|
|
@@ -194,3 +194,8 @@ source 객체는 렌더마다 바꾸지 않도록 `useMemo` 또는 제품 어댑
|
|
|
194
194
|
### 진한 브랜드 선택 — 개발 소스, 미게시 (2026-10-21)
|
|
195
195
|
|
|
196
196
|
다에리·스핀트의 선택 배경이 너무 옅다는 사용자 피드백에 따라 `indicator="solid"`로 선택 탭을 `primary`로 채우고 글자·아이콘에 `onPrimary`를 쓴다. 기존 `filled`는 옅은 선택을 유지한다.
|
|
197
|
+
|
|
198
|
+
### 기본 선택 면
|
|
199
|
+
|
|
200
|
+
`indicator="filled"`는 neutral `selection.background`/`selection.content`를 쓴다.
|
|
201
|
+
정적·slide·gooey의 이동 배경도 같은 역할이며 `solid`는 명시적 `primary`/`onPrimary` 강조다.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- 상태: 배포
|
|
5
5
|
- 지원: Web · Native
|
|
6
6
|
- 적용: 미게시(1.34.0 이후)
|
|
7
|
-
- 검토일: 2026-10-
|
|
7
|
+
- 검토일: 2026-10-23
|
|
8
8
|
- 근거: [TimePicker](../../time-picker.md), `src/time-picker.ts`의 `timePickerRecipe`, 양 renderer `src/time-picker.tsx`
|
|
9
9
|
- 스토리북: `배포/컴포넌트/입력/시각 선택`
|
|
10
10
|
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
Web Popover / Native Sheet를 열고 명시적으로 확정한다. 기존 날짜 시트 안에서는 `inline`을 쓴다.
|
|
15
15
|
현재 checkout의 개발 소스에서 제공하며 npm 게시 버전은 아직 없다.
|
|
16
16
|
|
|
17
|
+
기존 탭 목록은 `selectionStyle="list"`(기본), 관성 스크롤·중앙 스냅은 `selectionStyle="wheel"`로 고른다.
|
|
18
|
+
휠 옵션은 2026-10-23 개발 소스에 추가한 미게시 기능이다. 값·초안·확정·취소 계약은 같으며
|
|
19
|
+
[도입 결정](../FINDING.md#휠-피커-검토-결과)에 따라 별도 WheelPicker 공개 API를 추가하지 않았다.
|
|
20
|
+
|
|
17
21
|
## 쓰지 않을 때
|
|
18
22
|
|
|
19
23
|
| 상황 | 대신 쓸 것 |
|
|
@@ -30,7 +34,7 @@ Web Popover / Native Sheet를 열고 명시적으로 확정한다. 기존 날짜
|
|
|
30
34
|
|
|
31
35
|
필수: `value: string | null`, `onValueChange(value: string | null)`,
|
|
32
36
|
`labels: { label, hour, minute, placeholder, confirm, cancel }`.
|
|
33
|
-
선택: `presentation`(`field` 기본/`inline`), `minuteStep`(1 기본), `isTimeUnavailable`,
|
|
37
|
+
선택: `presentation`(`field` 기본/`inline`), `selectionStyle`(`list` 기본/`wheel`), `minuteStep`(1 기본), `isTimeUnavailable`,
|
|
34
38
|
`disabled`, `readOnly`, `description`, `error`, 외부 배치용 `layoutStyle`.
|
|
35
39
|
Native `safeAreaInsets`는 단독 Sheet에 전달한다.
|
|
36
40
|
|
|
@@ -50,6 +54,17 @@ import { TimePicker } from '@hjmds/react/time-picker';
|
|
|
50
54
|
labels={{ label: '시간', hour: '시', minute: '분', placeholder: '시간 선택', confirm: '선택 완료', cancel: '취소' }} />
|
|
51
55
|
```
|
|
52
56
|
|
|
57
|
+
휠 예제는 양 renderer에서 같은 옵션을 쓴다. `presentation="inline"`이면 바깥 폼이 최종 확정을 소유한다.
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
// Web 또는 Native
|
|
61
|
+
<TimePicker selectionStyle="wheel" minuteStep={5} value={time} onValueChange={setTime}
|
|
62
|
+
labels={{ label: '시간', hour: '시', minute: '분', placeholder: '시간 선택', confirm: '선택 완료', cancel: '취소' }} />
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
실행 예제: Web·Native의 `TimePicker.stories.tsx`에 `Wheel`(필드), `WheelInline`(본문),
|
|
66
|
+
`WheelReducedMotion`(동작 줄이기)이 있다. [Web 휠](https://storybook.jmstudioapps.com/?path=/story/components-inputs-time-picker--wheel)은 공개 사이트 반영 후 이용할 수 있다.
|
|
67
|
+
|
|
53
68
|
실행되는 원본은 [Web preview](https://github.com/jim1286/hjm-design-system/blob/main/showcase/web/src/components/preview-registry.tsx)의 `TimePickerPreview`,
|
|
54
69
|
[Native preview](https://github.com/jim1286/hjm-design-system/blob/main/showcase/native/src/component-examples.tsx)의 `TimePickerExample`이다.
|
|
55
70
|
|
|
@@ -74,6 +89,7 @@ import { TimePicker } from '@hjmds/react/time-picker';
|
|
|
74
89
|
| 고정·스크롤 | 제목·확인은 공통 overlay 영역, 시·분 목록만 세로 스크롤 | Popover / Sheet / TimePicker |
|
|
75
90
|
| 좁은 폭·큰 글자 | 좁은 폭은 두 열을 같은 폭으로 유지. 최대 글자 조건은 사용자 지침으로 범위 제외 | 포트폴리오 AGENTS.md |
|
|
76
91
|
| 선택 표시 | radius.md, surfaceAccent 배경·text 글자·500 굵기 | 시간 값은 주요 글자로 강조하고, 제품 선택 배경과 확정 버튼 대표색을 구분(2026-10-20 토스 공개 팔레트 참고 요청) |
|
|
92
|
+
| 휠 중앙·끝 여백 | 행 44, 5행 높이 220, 위아래 여백 88, 중앙 테두리 stroke.default(1) | timePickerRecipe와 양 renderer. 첫 값·마지막 값도 중앙 정렬 |
|
|
77
93
|
| 설명·오류 | 입력 아래 description/error. 오류는 보조기술에도 알림 | 양 renderer |
|
|
78
94
|
|
|
79
95
|
|
|
@@ -84,5 +100,7 @@ import { TimePicker } from '@hjmds/react/time-picker';
|
|
|
84
100
|
- `HH:mm | null`을 사용한다. `00:00`도 유효하며 날짜·시간대 변환은 제품이 담당한다.
|
|
85
101
|
- `minuteStep`은 60의 양의 정수 약수. 기존 값을 자동 반올림하거나 불가한 분을 몰래 교체하지 않는다.
|
|
86
102
|
- 빈 값은 `--:--`. 두 부분을 고르기 전에는 확정하지 않는다. 닫기는 초안을 취소한다.
|
|
103
|
+
- 휠의 초기 정렬은 선택이 아니다. 스크롤 중에는 초안만 바뀌며 field 확인은 멈춘 뒤 가능하다. 간격 밖 외부 값은 자동 반올림하지 않는다.
|
|
104
|
+
- Web 휠은 scrollend 지원 브라우저를 대상으로 한다. 방향키·Home·End와 탭 선택도 지원한다. Native 휠은 열마다 adjustable 증감 액션을 제공한다. 동작 줄이기는 Provider에서 설정한다.
|
|
87
105
|
- inline은 완전하고 사용 가능한 값만 문자열, 미완성·불가한 조합은 null을 전달한다. 바깥 확인 버튼은 null을 확정하지 않는다.
|
|
88
106
|
- 시간 선택의 공통 배치·초안·취소·키보드 처리를 앱에서 다시 조립하지 않는다. 상세 동작은 [계약](../../time-picker.md)을 따른다.
|
|
@@ -101,3 +101,8 @@ import { ToggleGroup } from "@hjmds/react-native/toggle-group";
|
|
|
101
101
|
사용하고 없으면 기존 `toggleGroupRecipe.radius` 12를 유지한다. 새 style prop이나
|
|
102
102
|
별도 토글 엔진을 추가하지 않는다. 중첩 Provider에서 별도 profile을 생략하면 상속하며,
|
|
103
103
|
명시적인 neutral profile은 중립 모서리로 돌아간다. 테마 변경은 눌린 항목·비활성·초점을 초기화하지 않는다.
|
|
104
|
+
|
|
105
|
+
### 선택 면
|
|
106
|
+
|
|
107
|
+
지속되는 `pressedIds`는 `selection.background`/`selection.content`/`selection.border`를 쓴다.
|
|
108
|
+
순간적인 포인터 누름과 키보드 포커스는 이 선택값과 별개다.
|