@hjmds/design-contracts 1.27.2 → 1.28.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/activity-chip.d.ts +1 -1
- package/dist/activity-chip.js +1 -1
- package/dist/activity-chip.js.map +1 -1
- package/dist/auth-screen.d.ts +71 -5
- package/dist/auth-screen.d.ts.map +1 -1
- package/dist/auth-screen.js +60 -2
- package/dist/auth-screen.js.map +1 -1
- package/dist/base-recipes.d.ts +1 -1
- package/dist/base-recipes.js +1 -1
- package/dist/base-recipes.js.map +1 -1
- package/dist/behaviors.d.ts +1 -1
- package/dist/breadcrumb.d.ts +1 -1
- package/dist/breadcrumb.js +1 -1
- package/dist/breadcrumb.js.map +1 -1
- package/dist/calendar.d.ts +1 -1
- package/dist/calendar.js +2 -2
- package/dist/calendar.js.map +1 -1
- package/dist/catalog.d.ts +131 -87
- package/dist/catalog.d.ts.map +1 -1
- package/dist/component-contracts.d.ts +1 -1
- package/dist/component-contracts.js +1 -1
- package/dist/component-contracts.js.map +1 -1
- package/dist/component-recipes.d.ts +85 -57
- package/dist/component-recipes.d.ts.map +1 -1
- package/dist/component-recipes.js +95 -60
- package/dist/component-recipes.js.map +1 -1
- package/dist/conversation-row.d.ts +2 -2
- package/dist/conversation-row.d.ts.map +1 -1
- package/dist/conversation-row.js +6 -4
- package/dist/conversation-row.js.map +1 -1
- package/dist/counter-badge-recipe.d.ts +1 -1
- package/dist/counter-badge-recipe.js +1 -1
- package/dist/counter-badge-recipe.js.map +1 -1
- package/dist/data-table.d.ts +4 -4
- package/dist/data-table.js +4 -4
- package/dist/data-table.js.map +1 -1
- package/dist/date-picker.d.ts +1 -1
- package/dist/design-profile.d.ts.map +1 -1
- package/dist/design-profile.js +19 -16
- package/dist/design-profile.js.map +1 -1
- package/dist/file-picker.d.ts +1 -1
- package/dist/file-picker.js +1 -1
- package/dist/file-picker.js.map +1 -1
- package/dist/foundations.d.ts +18 -14
- package/dist/foundations.d.ts.map +1 -1
- package/dist/foundations.js +18 -13
- package/dist/foundations.js.map +1 -1
- package/dist/heading.d.ts +13 -13
- package/dist/heading.js.map +1 -1
- package/dist/number-field.d.ts +1 -1
- package/dist/otp-field.d.ts +1 -1
- package/dist/password-field.d.ts +1 -1
- package/dist/result.d.ts +1 -1
- package/dist/result.js +2 -2
- package/dist/result.js.map +1 -1
- package/dist/semantic-colors.d.ts +10 -0
- package/dist/semantic-colors.d.ts.map +1 -1
- package/dist/semantic-colors.js +6 -0
- package/dist/semantic-colors.js.map +1 -1
- package/dist/sheet.d.ts +7 -4
- package/dist/sheet.d.ts.map +1 -1
- package/dist/sheet.js +8 -5
- package/dist/sheet.js.map +1 -1
- package/dist/side-panel.d.ts +1 -1
- package/dist/side-panel.js +2 -2
- package/dist/side-panel.js.map +1 -1
- package/dist/steps.d.ts +1 -1
- package/dist/steps.js +1 -1
- package/dist/steps.js.map +1 -1
- package/dist/tag.d.ts +1 -1
- package/dist/tag.js +1 -1
- package/dist/tag.js.map +1 -1
- package/dist/timeline.d.ts +1 -1
- package/dist/timeline.js +1 -1
- package/dist/timeline.js.map +1 -1
- package/dist/top.d.ts +4 -4
- package/dist/top.d.ts.map +1 -1
- package/dist/top.js +3 -1
- package/dist/top.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/docs/activity-chip.md +5 -1
- package/docs/auth-screen.md +2 -0
- package/docs/design-profile.md +14 -10
- package/docs/generated/component-maturity.md +1 -1
- package/docs/generated/renderer-evidence.json +9 -5
- package/docs/generated/renderer-evidence.md +1 -1
- package/docs/generated/showcase-manifest.json +1 -1
- package/docs/heading.md +14 -9
- package/docs/sheet.md +2 -0
- package/docs/top.md +4 -3
- package/docs/usage/README.md +1 -1
- package/docs/usage/components/auth-screen-layout.md +26 -9
- package/docs/usage/components/bottom-cta.md +6 -2
- package/docs/usage/components/breadcrumb.md +5 -1
- package/docs/usage/components/checkbox-group.md +5 -1
- package/docs/usage/components/collapsible.md +1 -0
- package/docs/usage/components/effect-surface.md +2 -2
- package/docs/usage/components/heading.md +14 -12
- package/docs/usage/components/list-row.md +7 -3
- package/docs/usage/components/list.md +5 -4
- package/docs/usage/components/notification-item.md +5 -1
- package/docs/usage/components/photo-source-sheet.md +1 -1
- package/docs/usage/components/screen-layout.md +7 -3
- package/docs/usage/components/search-screen.md +1 -1
- package/docs/usage/components/section.md +5 -1
- package/docs/usage/components/segmented-control.md +1 -1
- package/docs/usage/components/sheet.md +17 -13
- package/docs/usage/components/skeleton.md +41 -15
- package/docs/usage/components/statistic.md +5 -1
- package/docs/usage/components/switch.md +3 -2
- package/docs/usage/components/tag.md +5 -1
- package/docs/usage/components/text.md +6 -4
- package/docs/usage/components/top.md +1 -1
- package/docs/usage/compositions/adaptive-content.md +5 -1
- package/docs/usage/compositions/compound-controls.md +2 -1
- package/docs/usage/compositions/design-profile-comparison.md +1 -1
- package/docs/usage/compositions/family-drawer.md +5 -3
- package/docs/usage/compositions/input-sheet.md +1 -1
- package/docs/usage/compositions/interaction-flow-apply.md +3 -3
- package/docs/usage/compositions/photo-source.md +3 -3
- package/docs/usage/compositions/selection-motion.md +5 -1
- package/docs/usage/compositions/visual-foundations.md +5 -4
- package/docs/usage/screens/common-login.md +9 -7
- package/docs/usage/screens/landing.md +15 -14
- package/docs/usage/screens/notification-settings.md +4 -2
- package/docs/usage/tokens/typography.md +21 -13
- package/package.json +1 -1
|
@@ -29,20 +29,20 @@
|
|
|
29
29
|
│ ┌ ① 히어로 EffectSurface(mesh+grain) ──┐ │
|
|
30
30
|
│ │ (안쪽 여백 spacing.xl 24 — HJM 구성 소유) │ │
|
|
31
31
|
│ │ eyebrow Text tone=muted │ │ Stack gap lg 20
|
|
32
|
-
│ │ 제목 Heading
|
|
32
|
+
│ │ 제목 Heading level3 (h1) 24 │ │
|
|
33
33
|
│ │ 소개 Text as=p │ │
|
|
34
34
|
│ │ [ 첫 기록 써보기 ] ← 주 행동(primary) │ │
|
|
35
35
|
│ └──────────────────────────────────────┘ │
|
|
36
36
|
│ ↕ spacing.xl 24 │
|
|
37
37
|
│ ┌ ② 미리보기 Surface padding lg 20 ────┐ │
|
|
38
|
-
│ │ Heading
|
|
38
|
+
│ │ Heading level4 (h2) 20 │ │ Stack gap md 16
|
|
39
39
|
│ │ (저장 직후) "추가했어요" status │ │
|
|
40
40
|
│ │ List > ListRow 한 줄씩(최신이 위) │ │
|
|
41
41
|
│ └──────────────────────────────────────┘ │
|
|
42
|
-
│ ③ 기능 Heading
|
|
43
|
-
│ ┌ Surface padding lg ─┐ Heading
|
|
42
|
+
│ ③ 기능 Heading level4 (h2) │
|
|
43
|
+
│ ┌ Surface padding lg ─┐ Heading level5 (h3) + Text (Stack gap sm 12)
|
|
44
44
|
│ └─────────────────────┘ × 3, 사이 24 │
|
|
45
|
-
│ ④ FAQ Heading
|
|
45
|
+
│ ④ FAQ Heading level4 (h2) │
|
|
46
46
|
│ ▸ 질문 1 Collapsible (트리거 최소 44) │
|
|
47
47
|
│ ▸ 질문 2 │
|
|
48
48
|
│ ⑤ [ 첫 기록 써보기 ] ← 같은 행동 반복 │ secondary
|
|
@@ -67,8 +67,8 @@
|
|
|
67
67
|
| 바깥 틀 | Web `main` > `Container size="content" gutter={gutter}` > `Stack gap="xl"`(문서 스크롤) · Native `ScrollView`(`contentContainerStyle={{ paddingVertical: spacing.lg }}`) > `Container size="content" gutter={gutter}` > `Stack gap="xl"` | 화면 전체, 스크롤. 위 안전 영역은 내비게이션 헤더(또는 [TopBar](../components/top-bar.md) `safeAreaTop`)가 맡고 헤더 없이 띄울 때만 제품이 감싼다. 아래 고정 영역은 없다. 바깥에는 입력이 없어 키보드 처리는 ⑥ 시트가 맡는다 | 좌우 gutter: 폭 600 미만 `compact` 16(`layout.pagePadding.compact`), 이상 `regular` 20([화면 여백](../tokens/layout.md)). Native 위아래 `spacing.lg` 20. 직계 요소 사이 `spacing.xl` 24(`layout.sectionGap`) |
|
|
68
68
|
| ① 히어로 | EffectSurface `descriptor={{ layers: ["mesh","grain"], active: false }}` > Surface `padding="xl"` > Stack `gap="lg"` > Text·Heading·Text·Button | 맨 위 | 요소 사이 `spacing.lg` 20. EffectSurface 안에 Surface `padding="xl"`을 두어 spacing.xl 24를 준다. 실제 양 플랫폼 예제와 같은 공개 구성이다 |
|
|
69
69
|
| ② 미리보기 | Surface `padding="lg"` > Stack `gap="md"` > Heading·상태 Text·List | 히어로 아래 | 안쪽 20, 요소 사이 `spacing.md` 16, 한 줄 행 최소 56(`layout.rowHeight.singleLine`). 새 기록이 맨 위 |
|
|
70
|
-
| ③ 기능 | Heading
|
|
71
|
-
| ④ FAQ | Heading
|
|
70
|
+
| ③ 기능 | Heading level4(h2) + Surface `padding="lg"` ×3 > Stack `gap="sm"` | 미리보기 아래 | 카드 안 `spacing.sm` 12, 카드 사이 24 |
|
|
71
|
+
| ④ FAQ | Heading level4(h2) + Collapsible × n | 기능 아래 | 트리거 최소 44(`control.minTouchTarget`), 트리거 위아래 `spacing.xs` 8(Web) |
|
|
72
72
|
| ⑤ 마지막 행동 | Button `secondary` + Text `tone="muted"` | 맨 아래 | 사이 24 |
|
|
73
73
|
| ⑥ 입력 | Sheet(Native `keyboardAvoidance` `scrollable`) > Stack `gap="lg"` > Notice(실패 때)·TextField, 제출은 `footer` | 오버레이, 화면 아래 | 시트 좌우 `spacing.lg` 20, TextField 높이 44(`control.fieldHeight`). 아래 안전 영역·키보드는 시트가 맡는다 |
|
|
74
74
|
|
|
@@ -134,7 +134,7 @@ footer의 저장과 같은 동작을 실행한다. Web에서 IME 조합 확정
|
|
|
134
134
|
| [Container](../components/container.md) | 바깥 틀 폭·좌우 여백 |
|
|
135
135
|
| [화면 여백과 너비](../tokens/layout.md) | gutter 선택(`resolveWindowClass`) |
|
|
136
136
|
| [EffectSurface](../components/effect-surface.md) | ① 히어로 배경 장식 |
|
|
137
|
-
| [Heading](../components/heading.md) | 히어로
|
|
137
|
+
| [Heading](../components/heading.md) | 히어로 level3(h1, 24), 영역 제목 level4(h2, 20), 기능 카드 level5(h3, 18) |
|
|
138
138
|
| [Text](../components/text.md) | eyebrow·소개·범위 안내·상태 문구 |
|
|
139
139
|
| [Button](../components/button.md) | 주 행동, 반복 행동, 시트 제출 |
|
|
140
140
|
| [Surface](../components/surface.md) | ② 미리보기, ③ 기능 카드 |
|
|
@@ -179,20 +179,20 @@ const gutter = resolveWindowClass(window.innerWidth) === "compact" ? "compact" :
|
|
|
179
179
|
<EffectSurface descriptor={{ layers: ["mesh", "grain"], seed: "landing", active: false }}><Surface padding="xl">
|
|
180
180
|
<Stack gap="lg" align="start">
|
|
181
181
|
<Text tone="muted">{t("landing.eyebrow")}</Text>
|
|
182
|
-
<Heading level="
|
|
182
|
+
<Heading level="level3" semanticLevel={1}>{t("landing.title")}</Heading>
|
|
183
183
|
<Text as="p">{t("landing.intro")}</Text>
|
|
184
184
|
<Button onClick={start}>{t("landing.cta")}</Button>
|
|
185
185
|
</Stack>
|
|
186
186
|
</Surface></EffectSurface>
|
|
187
187
|
<Surface padding="lg"><Stack gap="md">
|
|
188
|
-
<Heading level="
|
|
188
|
+
<Heading level="level4" semanticLevel={2}>{t("landing.preview")}</Heading>
|
|
189
189
|
{saved ? <Text role="status">{t("landing.saved")}</Text> : null}
|
|
190
190
|
<List label={t("landing.preview")}>{notes.map(n => <ListRow key={n.id} title={n.text} />)}</List>
|
|
191
191
|
</Stack></Surface>
|
|
192
|
-
<Heading level="
|
|
192
|
+
<Heading level="level4" semanticLevel={2}>{t("landing.features")}</Heading>
|
|
193
193
|
{features.map(f => <Surface key={f.id} padding="lg"><Stack gap="sm">
|
|
194
|
-
<Heading level="
|
|
195
|
-
<Heading level="
|
|
194
|
+
<Heading level="level5" semanticLevel={3}>{t(f.titleKey)}</Heading><Text>{t(f.bodyKey)}</Text></Stack></Surface>)}
|
|
195
|
+
<Heading level="level4" semanticLevel={2}>{t("landing.faq")}</Heading>
|
|
196
196
|
{faqs.map(q => <Collapsible key={q.id} trigger={t(q.questionKey)}><Text>{t(q.answerKey)}</Text></Collapsible>)}
|
|
197
197
|
<Stack gap="xl" align="start"><Button tone="secondary" onClick={start}>{t("landing.cta")}</Button>
|
|
198
198
|
<Text tone="muted">{t("landing.scope")}</Text></Stack>
|
|
@@ -229,7 +229,7 @@ const gutter = resolveWindowClass(width) === "compact" ? "compact" : "regular";
|
|
|
229
229
|
<Container size="content" gutter={gutter}><Stack gap="xl">
|
|
230
230
|
<EffectSurface descriptor={{ layers: ["mesh", "grain"], seed: "landing", active: false }}><Surface padding="xl">
|
|
231
231
|
<Stack gap="lg">
|
|
232
|
-
<Heading level="
|
|
232
|
+
<Heading level="level3" semanticLevel={1}>{t("landing.title")}</Heading>
|
|
233
233
|
<Text>{t("landing.intro")}</Text>
|
|
234
234
|
<Button onPress={start}>{t("landing.cta")}</Button>
|
|
235
235
|
</Stack>
|
|
@@ -366,6 +366,7 @@ import { ScreenLayout } from "@hjmds/react-native/screens";
|
|
|
366
366
|
|
|
367
367
|
## 근거
|
|
368
368
|
|
|
369
|
+
- 2026-10-17 사용자 결정("글자 너무 커", "큰 글자 정책은 없애"): 히어로 제목 level1 40px·영역 제목 level2 32px가 지나치게 커서 큰 글자 단계를 폐지했다. 히어로는 HJM 상한인 level3 24px(h1), 영역 제목은 level4 20px(h2), 기능 카드는 level5 18px(h3)로 위계를 만든다.
|
|
369
370
|
- FAQ는 Collapsible(기본·변형): 2026-10-16 사용자 지적 — 변형 스토리가 `selected` 토글 Button 하나로 펼침을 흉내 내 눌림 토글로 읽혔다.
|
|
370
371
|
- 닫을 때 초안 보존·성공 제출만 한 번 추가: 2026-10-13 실제 예제 검수에서 닫은 뒤 초안 소실과 연속 제출 시 중복 행을 재현했다.
|
|
371
372
|
- 히어로 padding·시트 저장 footer: 2026-10-06 지침과 예제 정합성 수정.
|
|
@@ -28,7 +28,7 @@ ScreenLayout: 제목(고정) → 본문(스크롤) → footer(고정)
|
|
|
28
28
|
| --- | --- | --- | --- |
|
|
29
29
|
| 바깥 틀 | ScreenLayout | host의 남은 높이 | 공통 화면 폭·padding·본문 스크롤 |
|
|
30
30
|
| 설정 묶음 | CompositionLayout | 본문 | 공통 제목·설명·내용 간격 |
|
|
31
|
-
| 설정 값 | Switch | 구성 본문 | 제품 데이터·변경 콜백 |
|
|
31
|
+
| 설정 값 | List(`separator="none"`) > Switch `presentation="row"` | 구성 본문 | 행 사이 gap 없음 — 행 간격 56은 Switch 행 높이·여백이 맡는다. 제품 데이터·변경 콜백 |
|
|
32
32
|
| 저장 | footer | 화면 하단 | HJM 고정 영역; 제품 저장 요청과 pending 연결 |
|
|
33
33
|
|
|
34
34
|
## 버튼과 행동 위치
|
|
@@ -74,7 +74,8 @@ ScreenLayout: 제목(고정) → 본문(스크롤) → footer(고정)
|
|
|
74
74
|
| [Notice](../components/notice.md) | 저장 결과·오류 |
|
|
75
75
|
| [Skeleton](../components/skeleton.md) | 첫 값 불러오기 |
|
|
76
76
|
| [Button](../components/button.md) | ③ 하단 저장 |
|
|
77
|
-
| [Stack](../components/stack.md) | 세 층
|
|
77
|
+
| [Stack](../components/stack.md) | 세 층 사이 |
|
|
78
|
+
| [List](../components/list.md) | 스위치 목록(행 사이 여백 없이) |
|
|
78
79
|
| [화면 여백과 너비](../tokens/layout.md) | `layout.readingMaxWidth`, `layout.pagePadding.compact`·`regular`, `resolveWindowClass` |
|
|
79
80
|
| [간격](../tokens/spacing.md) | `spacing.xxs`·`xs`·`sm`·`md`·`lg` |
|
|
80
81
|
|
|
@@ -114,3 +115,4 @@ ScreenLayout이 화면 여백과 스크롤을, CompositionLayout이 묶음 간
|
|
|
114
115
|
## 근거
|
|
115
116
|
|
|
116
117
|
- 설정 초안의 저장 경계 상황 표: 2026-10-13 전수 점검 — 최초 조회와 변경 요청의 상태를 같은 골격으로 설명하던 부분을 구체화했다.
|
|
118
|
+
- 스위치 목록 List·gap 없음: 2026-10-17 사용자 보고("간격이 커") — Stack `gap="md"` 16이 Switch 행 최소 높이 위에 더해져 행 간격이 84였다.
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
| `typography.label` | 12 / 줄 18 / 500 | `--hjm-type-label-*` | `theme.tokens.typography.label` | 라벨·도움말·small 버튼 글자 |
|
|
24
24
|
| `typography.body` | 14 / 줄 20 / 400 | `--hjm-type-body-*` | `theme.tokens.typography.body` | 기본 본문·medium 버튼·필드 글자 |
|
|
25
25
|
| `typography.bodyLarge` | 16 / 줄 24 / 400 | `--hjm-type-body-large-*` | `theme.tokens.typography.bodyLarge` | 읽기용 긴 본문·large 버튼 글자 |
|
|
26
|
-
| `typography.title` | 18 / 줄 26 /
|
|
27
|
-
| `typography.titleLarge` | 20 / 줄 28 /
|
|
28
|
-
| `typography.heading` | 24 / 줄 32 /
|
|
26
|
+
| `typography.title` | 18 / 줄 26 / 500 | `--hjm-type-title-*` | `theme.tokens.typography.title` | 카드 제목(`heading.level5`) |
|
|
27
|
+
| `typography.titleLarge` | 20 / 줄 28 / 500 | `--hjm-type-title-large-*` | `theme.tokens.typography.titleLarge` | 큰 구획 제목(`heading.level4`) |
|
|
28
|
+
| `typography.heading` | 24 / 줄 32 / 500 | `--hjm-type-heading-*` | `theme.tokens.typography.heading` | 화면의 가장 큰 제목. **HJM 글자 크기의 상한** |
|
|
29
29
|
|
|
30
30
|
굵기 열은 토큰 원본값이다. 프로필 없는 Text는 기본 `emphasis="regular"`(400)를 사용하므로
|
|
31
31
|
variant만 지정해도 위 굵기가 자동 적용되는 것은 아니다. 예외는 `label`이다. `label`은 프로필이 없어도
|
|
@@ -37,11 +37,10 @@ Heading은 제목 단계의 굵기를 쓴다. 두 renderer가 같은 resolver를
|
|
|
37
37
|
|
|
38
38
|
| 토큰 | 값 | Web CSS 변수 | Native 경로 | 용도 |
|
|
39
39
|
| --- | --- | --- | --- | --- |
|
|
40
|
-
| `heading.
|
|
41
|
-
| `heading.level2` | 32 / 줄 40 / 700 | — | `heading.level2` | 긴 페이지의 큰 구획 제목 |
|
|
42
|
-
| `heading.level3` | = `typography.heading` 24 | `--hjm-type-heading-*` | `heading.level3` | 화면 제목 |
|
|
40
|
+
| `heading.level3` | = `typography.heading` 24 | `--hjm-type-heading-*` | `heading.level3` | 화면 제목·랜딩 대표 제목 |
|
|
43
41
|
| `heading.level4` | = `typography.titleLarge` 20 | `--hjm-type-title-large-*` | `heading.level4` | 구획 제목 |
|
|
44
42
|
| `heading.level5` | = `typography.title` 18 | `--hjm-type-title-*` | `heading.level5` | 카드 제목 |
|
|
43
|
+
| `heading.level1` · `level2` | = `heading.level3` 24 (사용 중단) | `--hjm-type-heading-*` | `heading.level1` · `level2` | 새 코드에서 쓰지 않는다. 기존 소비 코드가 깨지지 않도록 이름만 남기고 값은 상한 24로 고정했다 |
|
|
45
44
|
|
|
46
45
|
### 서체·굵기·자간·숫자
|
|
47
46
|
|
|
@@ -49,12 +48,12 @@ Heading은 제목 단계의 굵기를 쓴다. 두 renderer가 같은 resolver를
|
|
|
49
48
|
| --- | --- | --- | --- | --- |
|
|
50
49
|
| `fontFamily.ui` | Pretendard Variable, Pretendard, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif | `--hjm-font-family-ui` | `fontFamily.ui` | 화면 글자. Native는 `fonts="pretendard"`일 때 굵기별 Pretendard face, 그 전에는 OS 서체. 불러오기는 [글꼴 역할](font-roles.md#기본-서체-pretendard-불러오기필수) |
|
|
51
50
|
| `fontFamily.code` | ui-monospace, SFMono-Regular, SF Mono, Menlo, Monaco, Cascadia Mono, Consolas, Liberation Mono, monospace | — (`--hjm-font-family-code` fallback) | `fontFamily.code` | 코드 |
|
|
52
|
-
| `fontWeight.regular` · `medium` · `semibold` · `bold` · `heavy` | 400 · 500 · 600 · 700 · 800 | `--hjm-font-weight-<이름>` | `fontWeight.<이름>` | Text `emphasis`: `regular` 400 · `medium`
|
|
51
|
+
| `fontWeight.regular` · `medium` · `semibold` · `bold` · `heavy` | 400 · 500 · 600 · 700 · 800 | `--hjm-font-weight-<이름>` | `fontWeight.<이름>` | Text `emphasis`: `regular` 400 · `medium` 500 · `strong` 500 (2026-10-17, 가장 강한 강조 = 제목 굵기). 컴포넌트 recipe는 제목 500, 큰 숫자(Statistic 값)·선택 상태 600을 쓰고 700·800은 브루탈리즘 프리셋 외에 쓰지 않는다 |
|
|
53
52
|
| `letterSpacing.tight` · `normal` · `wide` | -0.2 · 0 · 0.2 | — | `letterSpacing.<이름>` | 자간 조정이 필요한 제품 고유 글자. HJM 컴포넌트는 자간을 지정하지 않는다 |
|
|
54
53
|
| `numeric.tabular` · `proportional` | `tabular-nums` · `proportional-nums` | — | `numeric.<이름>` | 바뀌는 숫자(카운터·통계·날짜 칸)는 `tabular`로 폭을 고정 |
|
|
55
54
|
| `largeTextThreshold` | 1.6 | 루트 `data-large-text="true"` | `largeTextThreshold` | 글자 배율이 이 값 이상이면 큰 글자 배치로 바꾼다 |
|
|
56
55
|
|
|
57
|
-
Native는 `fonts="pretendard"`일 때 500을 `Pretendard-Medium`,
|
|
56
|
+
Native는 `fonts="pretendard"`일 때 500을 `Pretendard-Medium`, 600을 `Pretendard-SemiBold` face로 그린다(`resolvePretendardNativeFace`).
|
|
58
57
|
`@hjmds/react-native/fonts`의 `hjmPretendardFonts`가 400~800 다섯 face를 모두 번들한다. Web은 Pretendard Variable 한 파일이 모든 굵기를 덮는다.
|
|
59
58
|
|
|
60
59
|
Native 경로의 `theme`은 `useHjmNativeTheme()`, 나머지 이름은 `@hjmds/design-contracts/foundations` import다.
|
|
@@ -62,9 +61,17 @@ Web 크기 변수는 `rem × --hjm-text-scale`이라 Provider의 `textScale`을
|
|
|
62
61
|
|
|
63
62
|
## 근거
|
|
64
63
|
|
|
65
|
-
2026-10-17 사용자 결정: `label`은 폼 라벨·섹션 부제목이 본문 대비 약해 500
|
|
64
|
+
2026-10-17 사용자 결정: `label`은 폼 라벨·섹션 부제목이 본문 대비 약해 500으로 정하고
|
|
66
65
|
Web·Native 모두 기본으로 그린다. `heading.level1`·`level2`는 Pretendard 800이 큰 크기에서 무겁고 거칠어 700으로
|
|
67
|
-
낮췄다(제목 단계 3~5는 같은 날 600).
|
|
66
|
+
낮췄다(제목 단계 3~5는 같은 날 600). 같은 날 두 번째 검토("굵기 좀더 줄여")에서 한 단계씩 더 낮춰 큰 제목 600,
|
|
67
|
+
제목 단계 500, 강조 `strong` 500이 됐다. Web CSS는 `--hjm-type-title-weight`·`--hjm-text-emphasis-*` 역할 변수로 같은 값을 읽는다.
|
|
68
|
+
브루탈리즘 프리셋은 강한 강조 프리셋이라 `typography.heading`(따라서 Heading level1~3) 굵기를 800으로 명시해 유지한다. 크기는 공통 단계를 따른다.
|
|
69
|
+
|
|
70
|
+
2026-10-17 사용자 결정("글자 너무 커", "큰 글자 정책은 없애"): 큰 글자 단계(display)를 폐지했다. HJM에서 가장 큰 글자는
|
|
71
|
+
`typography.heading` 24 / 줄 32다. 계기는 Native Storybook 서비스 소개 화면의 히어로 제목(level1 40)과 구획 제목(level2 32)이
|
|
72
|
+
화면에 비해 지나치게 컸던 것이다. `heading.level1`·`level2`의 40·32와 semibold 600 단계를 없애고 두 이름을 `level3`(24/32/500)과
|
|
73
|
+
같은 값으로 고정했다. 디자인 프로필도 이 상한을 넘는 글자 크기를 `RangeError`로 거부하므로 에디토리얼(56/42/30)·브루탈리즘(48/38/30)의
|
|
74
|
+
확대 크기도 함께 없앴다. 랜딩 대표 제목은 `level3`, 구획 제목은 `level4`, 카드 제목은 `level5`로 위계를 만든다.
|
|
68
75
|
|
|
69
76
|
## 쓰는 법
|
|
70
77
|
|
|
@@ -94,6 +101,7 @@ import { Heading } from "@hjmds/react-native/heading";
|
|
|
94
101
|
## 하지 말 것
|
|
95
102
|
|
|
96
103
|
- `font-size: 15px`, `fontWeight: "900"`처럼 단계 밖 값을 쓰지 않는다.
|
|
104
|
+
- 24보다 큰 글자(히어로·큰 숫자·표지 제목)를 제품 CSS·StyleSheet로 만들지 않는다. 강조는 위계(level3 → level4 → level5)·굵기·여백으로 한다.
|
|
97
105
|
- 크기를 맞추려고 Heading의 `semanticLevel`을 바꾸지 않는다. 시각 크기는 `level`, 문서 구조는 `semanticLevel`이다.
|
|
98
106
|
- 글자 크기를 고정해 OS 글자 크기 설정을 막지 않는다(`allowFontScaling={false}`, px 고정 `font-size`).
|
|
99
107
|
- 줄 높이를 지워 글자를 겹치게 하지 않는다. 한국어 본문은 토큰 줄 높이를 그대로 쓴다.
|
|
@@ -117,10 +125,10 @@ import { Heading } from "@hjmds/react-native/heading";
|
|
|
117
125
|
프로필 계약에서 확인하고 앱 CSS로 내부 값을 덮지 않는다.
|
|
118
126
|
|
|
119
127
|
|
|
120
|
-
Heading의
|
|
121
|
-
일괄 지정한다. Web `--hjm-heading-size/line-height/weight`, Native Heading의 Text
|
|
128
|
+
Heading의 시각 단계는 `defineHjmDesignProfile({ tokens: { heading: ... } })`로
|
|
129
|
+
일괄 지정한다. 어느 단계도 `typography.heading` 24를 넘을 수 없다. Web `--hjm-heading-size/line-height/weight`, Native Heading의 Text
|
|
122
130
|
metrics로 연결된다. 해당 heading을 담은 Provider에서 가장 가까운 profile을 읽는다.
|
|
123
|
-
|
|
131
|
+
level1/2/3은 typography heading, level4/5는 titleLarge/title override를 기본으로 병합하며
|
|
124
132
|
명시적인 heading 값이 우선한다. 문서의 h1~h6 순서는 `semanticLevel`이 소유한다.
|
|
125
133
|
|
|
126
134
|
제목·본문에 서로 다른 글꼴이 필요하면 [표시·읽기·기술 글자](font-roles.md)를 사용한다.
|