@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
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- ์ํ: ๋ฐฐํฌ
|
|
5
5
|
- ์ง์: Web ยท Native
|
|
6
6
|
- ์ ์ฉ: 1.12.1
|
|
7
|
-
- ๊ฒํ ์ผ: 2026-10-
|
|
7
|
+
- ๊ฒํ ์ผ: 2026-10-17
|
|
8
8
|
- ๊ทผ๊ฑฐ: [๋ก๊ทธ์ธ ํ๋ฉด ๊ณจ๊ฒฉ](../../auth-screen.md), [1.4 ์ ํ ์ฑํ ๊ฐ์ด๋](../../product-adoption-1.4.md), recipe `authScreenRecipe`(`src/auth-screen.ts`), ํฌํธํด๋ฆฌ์ค ์์ ๊ธฐ์ค ๋ฃจํธ `docs/LOGIN_SCREEN_STANDARD.md`(LS)
|
|
9
9
|
- ์คํ ๋ฆฌ๋ถ: `๋ฐฐํฌ/์ปดํฌ๋ํธ/๋ ์ด์์/๋ก๊ทธ์ธ ํ๋ฉด`
|
|
10
10
|
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
๋ก๊ทธ์ธยท๊ฐ์
์ง์
ํ๋ฉด์ ๋ฐฐ์น์ ์ด๋ค. ์ ์์ญ(`hero` + `main`)์ ๋จ๋ ์ธ๋ก ๊ณต๊ฐ์์ ๊ฐ์ด๋ฐ ์ ๋ ฌ๋๊ณ ,
|
|
14
14
|
`footer`(๋์ ๊ณ ์งยท์ ์ฑ
๋งํฌ)๋ ๋ฐ๋ฅ์ ๋ถ๋๋ค. ๋ด์ฉ์ด ํ๋ฉด๋ณด๋ค ๊ธธ๋ฉด ์คํฌ๋กค๋ก ๋ฐ๋๋ค.
|
|
15
|
-
|
|
15
|
+
`AuthScreenLayout`์ ๋ฐฐ์น๋ฅผ ์์ ํ๊ณ , ํ์ด๋ก ๋ฌธ๊ตฌ์ ๋์ ๊ณ ์งยท์ ์ฑ
๋งํฌ๋ ๊ฐ์ ๋ชจ๋์ `AuthScreenHero`ยท`AuthScreenFooter`๊ฐ
|
|
16
|
+
๊ธ์ ๋จ๊ณยท์ยท๊ฐ๊ฒฉ์ ์์ ํ๋ค. ์ ํ์ ๋ฌธ์์ดยท๋งํฌยท๋งํฌ ๋ชฉ์ ์ง๋ง ๋๊ธด๋ค.
|
|
16
17
|
|
|
17
18
|
## ์ฐ์ง ์์ ๋
|
|
18
19
|
|
|
@@ -25,33 +26,35 @@
|
|
|
25
26
|
|
|
26
27
|
| ์ด๋ฆ | ์ญํ | Web | Native |
|
|
27
28
|
| --- | --- | --- | --- |
|
|
28
|
-
| `AuthScreenLayout` | ๊ธฐ๋ณธ | `@hjmds/react`, `/auth-screen` | `@hjmds/react-native`, `/auth-screen` |
|
|
29
|
+
| `AuthScreenLayout` | ๊ธฐ๋ณธ(๋ฐฐ์น) | `@hjmds/react`, `/auth-screen` | `@hjmds/react-native`, `/auth-screen` |
|
|
30
|
+
| `AuthScreenHero` | `hero` ์ฌ๋กฏ: ๋งํฌยทeyebrowยทํ๊ทธ๋ผ์ธยท์ค๋ช
| ๊ฐ์ | ๊ฐ์ |
|
|
31
|
+
| `AuthScreenFooter` | `footer` ์ฌ๋กฏ: ๋์ ๊ณ ์งยท์ ์ฑ
๋งํฌ(ยท๊ตฌ๋ถ) | ๊ฐ์, ๋งํฌ `href` ๋๋ `onClick` | ๊ฐ์, ๋งํฌ `onPress` |
|
|
29
32
|
|
|
30
33
|
## ์ต์ ์ฌ์ฉ ์
|
|
31
34
|
|
|
32
35
|
```tsx
|
|
33
36
|
// Web
|
|
34
|
-
import { AuthScreenLayout } from "@hjmds/react/auth-screen";
|
|
37
|
+
import { AuthScreenFooter, AuthScreenHero, AuthScreenLayout } from "@hjmds/react/auth-screen";
|
|
35
38
|
|
|
36
39
|
<AuthScreenLayout
|
|
37
40
|
mainCard
|
|
38
41
|
{...(pending ? { pendingLabel: t("auth.pending") } : {})}
|
|
39
|
-
hero={<
|
|
42
|
+
hero={<AuthScreenHero mark={<ProductMark />} title={t("auth.tagline")} description={t("auth.description")} />}
|
|
40
43
|
main={<ProviderButtons />} // pending์ด์ด๋ ๊ฐ์ ๋ชฉ๋ก
|
|
41
|
-
footer={<
|
|
44
|
+
footer={<AuthScreenFooter notice={t("auth.consent")} links={[{ label: t("legal.privacy"), href: privacyUrl }, { label: t("legal.terms"), href: termsUrl }]} />}
|
|
42
45
|
/>
|
|
43
46
|
```
|
|
44
47
|
|
|
45
48
|
```tsx
|
|
46
49
|
// Native
|
|
47
|
-
import { AuthScreenLayout } from "@hjmds/react-native/auth-screen";
|
|
50
|
+
import { AuthScreenFooter, AuthScreenHero, AuthScreenLayout } from "@hjmds/react-native/auth-screen";
|
|
48
51
|
|
|
49
52
|
<AuthScreenLayout
|
|
50
53
|
mainCard
|
|
51
54
|
{...(pending ? { pendingLabel: t("auth.pending") } : {})}
|
|
52
|
-
hero={<
|
|
55
|
+
hero={<AuthScreenHero mark={<ProductMark />} title={t("auth.tagline")} description={t("auth.description")} />}
|
|
53
56
|
main={<ProviderButtons />}
|
|
54
|
-
footer={<
|
|
57
|
+
footer={<AuthScreenFooter links={[{ label: t("legal.privacy"), onPress: openPrivacy }, { label: t("legal.terms"), onPress: openTerms }]} />}
|
|
55
58
|
testID="login-screen"
|
|
56
59
|
/>
|
|
57
60
|
```
|
|
@@ -69,6 +72,8 @@ import { AuthScreenLayout } from "@hjmds/react-native/auth-screen";
|
|
|
69
72
|
| Web `as` | `main` ยท `section` | `main` | ์ต๋ ํญ์ 416์ด๋ค |
|
|
70
73
|
| `layoutStyle` | marginยทwidthยทflexยท`alignSelf` | โ | ๋ฐ๊นฅ ๋ฐฐ์น ์ ์ฉ(WebยทNative ๋ชจ๋) |
|
|
71
74
|
| Native `testID` | `string` | โ | ๋ฟ๋ฆฌ `ScrollView` ์๋ณ |
|
|
75
|
+
| `AuthScreenHero` `title` ยท `eyebrow` ยท `description` ยท `mark` ยท `headingLevel` | ๋ฌธ์์ด ยท `ReactNode` ยท `1`~`3` | `headingLevel` 1 | ์ ๋ชฉ์ ํ์์ด๊ณ ๋น ๋ฌธ์์ด์ด๋ฉด `TypeError`. ๋ฐ๋๋ ๋ฐ๊นฅ `AuthScreenLayout`์ ๋ฐ๋ฅธ๋ค |
|
|
76
|
+
| `AuthScreenFooter` `links` ยท `notice` ยท `children` | ๋งํฌ ๋ฐฐ์ด(1๊ฐ ์ด์) ยท `ReactNode` | โ | ๋น ๋งํฌ ๋ชฉ๋กยท๋น ๋ผ๋ฒจ์ `TypeError`(LS-04: ์ฝ๊ด ๋งํฌ๋ ๋ก๊ทธ์ธ ์ ๊ฐ์ ํ๋ฉด์ ์์ด์ผ ํ๋ค). `children`์ ๋งํฌ ์๋ ์ ํ ๋ด์ฉ |
|
|
72
77
|
|
|
73
78
|
## ๋ฐฐ์น
|
|
74
79
|
|
|
@@ -76,6 +81,8 @@ import { AuthScreenLayout } from "@hjmds/react-native/auth-screen";
|
|
|
76
81
|
| --- | --- | --- |
|
|
77
82
|
| ํฌ๊ธฐ | ํ๋ฉด ์ ์ฒด(Web `min-block-size: 100dvh`, Native `ScrollView flex: 1`). ์ ๋ธ๋ก๊ณผ footer๋ ์ต๋ ํญ 416, ๋งํฌ 72(`markSize`, `radius.lg`), ์ ์ฑ
๋งํฌ ์ต์ 44(`footerMinTouchTarget`), mainCard ๋ชจ์๋ฆฌ profile์ `radius.lg`(neutral/๋ฏธ์ง์ 16) | `authScreenRecipe`, `.hjm-auth-screen*` |
|
|
78
83
|
| ๊ฐ๊ฒฉ | `regular` / `compact`: ๋ฐ๊นฅ ์ข์ฐ `layout.pagePadding.regular` 20 / `.compact` 16, ๋ฐ๊นฅ ์์๋ `spacing.xxxl` 40 / `spacing.lg` 20, hero ์ `spacing.md` 16 / `spacing.xs` 8, heroโmain `spacing.xl` 24 / `spacing.md` 16, ์ ๋ธ๋กโfooter ์ต์ `spacing.xl` 24 / `spacing.md` 16. mainCard ์์ชฝ `spacing.md` 16 | `authScreenRecipe.densities`ยท`mainCard` |
|
|
84
|
+
| ํ์ด๋ก ๋ฌธ๊ตฌ | ๋งํฌ โ ๋ฌธ๊ตฌ ๋ฌถ์์ hero ๊ฐ๊ฒฉ. eyebrow `label` 12/18ยท500ยท๋ธ๋๋์, ์๋ `spacing.xxs` 4 โ ํ๊ทธ๋ผ์ธ `regular` `typography.heading` 24/32 ยท `compact` `titleLarge` 20/28, ๊ตต๊ธฐ๋ ์ ๋ชฉ ๋จ๊ณ 500, ๊ธฐ๋ณธ ๊ธ์์, ์ค์ heading ์์(Native `header`) โ ์ค๋ช
`body` 14/20ยท400ยท๋ณด์กฐ์(`muted`), ์ `spacing.xs` 8 | `authScreenRecipe.hero`, `densities.*.titleVariant` |
|
|
85
|
+
| ๋์ ๊ณ ์งยท์ ์ฑ
๋งํฌ | ๊ณ ์ง `caption` 11/16 ํ๋ฆฐ ์, ๋งํฌ ์ค๊ณผ `spacing.xxs` 4. ๋งํฌ `caption`ยท๋ธ๋๋์ยท๋ฐ์ค, ๋งํฌ ์ฌ์ด `linkGap` 8 + `ยท` + 8(๋ณด์ด๋ ๊ธ์ ๊ฐ๊ฒฉ ์ฝ 19). ๊ฐ ๋งํฌ ๋์ด 44(๋ฐฐ๊ฒฝ ์์), ๊ฐ๋ก ํฐ์น ํญ์ ๊ตฌ๋ถ์ ์๊น์ง ๋ณด์ด์ง ์๊ฒ ๋ํ(Web ๊ฐ์ ์์, Native `hitSlop`) | `authScreenRecipe.footer`, `.hjm-auth-screen__link` |
|
|
79
86
|
| ์์ยท์ ๋ ฌ | ์โ์๋ hero(๊ฐ์ด๋ฐ ์ ๋ ฌ ๋ฌธ๊ตฌ) โ main(ํญ ๊ฝ ์ฑ์) โ footer(๋์ ๊ณ ์งยท์ ์ฑ
๋งํฌ). ์ ๋ธ๋ก์ ๋จ๋ ์ธ๋ก ๊ณต๊ฐ์์ ๊ฐ์ด๋ฐ, footer๋ ๋ฐ๋ฅ์ ๋ถ๋๋ค. ์งํ ์ค ๋ก๋ฉ์ main ์นด๋ ๊ฐ์ด๋ฐ์ ๊ฒน์น๋ค | `.hjm-auth-screen__block`(`justify-content: center`), `.hjm-auth-screen__pending` |
|
|
80
87
|
| ๊ณ ์ ยท์คํฌ๋กค | ๊ณ ์ ์์ญ์ด ์๋ค. ๋์น๋ฉด ํ๋ฉด ์ ์ฒด๊ฐ ์คํฌ๋กคํ๋ค. ์์ ์์ญ์ Native `contentInsetAdjustmentBehavior="automatic"`๊ณผ ํค๋ณด๋ inset ์๋ ์กฐ์ ์ด ์ฒ๋ฆฌํ๊ณ , Web์ safe-area inset์ ๋ํ์ง ์๋๋ค | `react-native/src/auth-screen.tsx`, `.hjm-auth-screen` |
|
|
81
88
|
| ์ข์ ํญยทํฐ ๊ธ์ | ํค ์์ ํ๋ฉดยทํฐ ๊ธ์์์๋ `compact`๋ฅผ ๊ณ ๋ฅธ๋ค. ๊ทธ๋๋ ๋์น๋ฉด ์คํฌ๋กค๋๋ฉฐ footer๋ ๋งจ ์๋๋ก ๋ฐ๋ฆฐ๋ค | `authScreenRecipe.densities` |
|
|
@@ -104,6 +111,8 @@ import { AuthScreenLayout } from "@hjmds/react-native/auth-screen";
|
|
|
104
111
|
- `pendingLabel`์ ์คํฌ๋ฆฐ๋ฆฌ๋ ์๋ด๋ก๋ง ์ฐ์ธ๋ค. ๋ก๋ฉ ์๋์ ๋ณด์ด๋ ๋ฌธ๊ตฌ๋ฅผ ๋ฐ๋ก ๋์ง ์๋๋ค.
|
|
105
112
|
์๋ฃยท์ทจ์ยท์คํจ ์ prop์ ์ ๊ฑฐํ๋ค. ์ทจ์๋ ์คํจ ๋ฌธ์ฅ ์์ด ๋ฒํผ๋ง ๋ณต๊ตฌํ๋ค(LS-09).
|
|
106
113
|
- `pendingLabel`์ ๊ธฐ์กด ์นด๋์์ ์ ํํ๋ ์ํ๋ค. ์ ๊ณต์ ๋ชฉ๋ก ์ต์ด ์กฐํ์ ๋ก๋ฉ์ ๋์ ํ์ง ์๋๋ค.
|
|
114
|
+
- ํ์ด๋ก์ `Top`(ํ๋ฉด ์ฒซ ์ ๋ชฉ, large = display 32/40)์ด๋ ์ง์ ์กฐ๋ฆฝํ `Text`๋ฅผ ๋ฃ์ง ์๋๋ค. `AuthScreenHero`๋ฅผ ์ด๋ค.
|
|
115
|
+
์ ์ฑ
๋งํฌ๋ฅผ ghost `Button` + Stack gap์ผ๋ก ๋ง๋ค์ง ์๋๋ค โ ๋ฒํผ ์์ชฝ ์ฌ๋ฐฑ์ด ๊ฐ๊ฒฉ์ ๋ํด์ง๋ค. `AuthScreenFooter`๋ฅผ ์ด๋ค.
|
|
107
116
|
- ์ฌ๋กฏ ๋ด์ฉ์ ์ ๋ถ ์ ํ ์์ ๋ค: ๋งํฌ ์์ฐ, ๋ชจ๋ ๋ฌธ๊ตฌ(i18n ํค), ์ ๊ณต์ ๋ชฉ๋ก๊ณผ ์์, ์ ์ฑ
๋งํฌ ๋ชฉ์ ์ง,
|
|
108
117
|
์ฌ์ฌ์ ํผ ๋
ธ์ถ ์กฐ๊ฑด. ์ ๊ณต์ ๋ก๊ณ ๋ฅผ HJM์ ๋ฃ์ง ์๋๋ค([AuthProviderButton](auth-provider-button.md)).
|
|
109
118
|
- iOS ์ฑ์ ์ ๊ณต์ ๋ชฉ๋ก์๋ Apple์ด ์์ด์ผ ํ๋ค(LS-02). ์ฌ์ฌ์ ์ด๋ฉ์ผ ํผ์ ์๋ฒ env์ `review=1` ๋ ์กฐ๊ฑด์ด
|
|
@@ -131,3 +140,11 @@ import { AuthScreenLayout } from "@hjmds/react-native/auth-screen";
|
|
|
131
140
|
### ํ
๋ง ์นด๋ ๋ชจ์๋ฆฌ
|
|
132
141
|
|
|
133
142
|
`mainCard`๋ ๊ฐ์ฅ ๊ฐ๊น์ด Provider์ `designProfile.tokens.radius.lg`๋ฅผ ์ ํ๋ซํผ์์ ์๋นํ๋ค. ํ
๋ง๊ฐ ์์ผ๋ฉด ๊ธฐ์กด recipe์ 16์ ์ ์งํ๋ค. ์ ๊ณต์ ๋ฒํผ์ ์ ๊ณต์ ๋ธ๋๋ ๊ท๊ฒฉ์ ์ ์งํ๋ฉฐ, ์ฒ๋ฆฌ ์ค์๋ ์นด๋์ ์
๋ ฅ์ ์ ๊ฑฐํ์ง ์๋๋ค. ์นด๋ ํ๋ฉด๊ณผ ์ ๊ณต์ ๋ธ๋๋๋ฅผ ๊ฐ์ radius๋ก ๊ฐ์ ํ๋ฉด ์ ํ ํ
๋ง๊ฐ ์ ๊ณต์ ๊ท๊ฒฉ์ ๋ฎ๊ธฐ ๋๋ฌธ์ ์ญํ ์ ๋๋๋ค.
|
|
143
|
+
|
|
144
|
+
## ๊ทผ๊ฑฐ
|
|
145
|
+
|
|
146
|
+
- `AuthScreenHero`ยท`AuthScreenFooter`์ ํ์ด๋กยท๋งํฌ ์์น: 2026-10-17 ์ฌ์ฉ์ ํผ๋๋ฐฑ("๊ตต๊ธฐ๋ ํฌ๊ธฐ ์ค์ฌ", "๊ฐ๊ฒฉ ์ค์ฌ").
|
|
147
|
+
์์ ๊ฐ ํ์ด๋ก์ `Top large`(display 32/40ยท600)๋ฅผ ๋ฃ์ด 402 ํญ์์ ํ๊ทธ๋ผ์ธ์ด ๋ ์ค์ด ๋๊ณ , ์ ์ฑ
๋งํฌ๋ ghost Button
|
|
148
|
+
์์ชฝ ์ฌ๋ฐฑ 12+12์ Stack gap 16์ด ๋ํด์ ธ ๊ธ์ ์ฌ์ด๊ฐ Web 42ยทNative 40์ด์๋ค. ์ฌ๋กฏ ๋ด์ฉ์ ์ฑ์ด ์กฐ๋ฆฝํ๋ฉด ๊ฐ์ ์ค์๊ฐ
|
|
149
|
+
์ ํ๋ง๋ค ๋ฐ๋ณต๋๋ฏ๋ก HJM์ด ๊ธ์ ๋จ๊ณยท๊ฐ๊ฒฉ์ recipe๋ก ์์ ํ๋ค. ๋ณ๊ฒฝ ํ Web 402์์ ํ๊ทธ๋ผ์ธ 24/32ยท500 ํ ์ค,
|
|
150
|
+
๋งํฌ ๊ธ์ ๊ฐ๊ฒฉ ์ฝ 19, ๋งํฌ ๋์ด 44๋ฅผ ์ธก์ ํ๋ค. ๋ฃจํธ LS ยง3๋ ๊ฐ์ ๊ฐ์ผ๋ก ๊ฐฑ์ ํ๋ค.
|
|
@@ -79,7 +79,7 @@ const insets = useSafeAreaInsets();
|
|
|
79
79
|
| ๊ฐ๊ฒฉ | ์ข์ฐ `layout.pagePadding.regular` 20, ์ `spacing.sm` 12, ์๋ `spacing.sm` 12์ ํ๋จ inset ์ค ํฐ ๊ฐ(Web์ `env(safe-area-inset-bottom)`ยท`safeAreaBottom`๋ ๋น๊ต). ์ค๋ช
โํ๋, ํ๋ ์ฌ์ด `spacing.sm` 12. ์ ๊ฒฝ๊ณ๋ `border.default` 1px(`stroke.default`), Native๋ ์๋ก ๋๋ฆฌ์ฐ๋ ๊ทธ๋ฆผ์(opacity 0.08, radius 8) | `bottomCtaRecipe`, `.hjm-bottom-cta` |
|
|
80
80
|
| ์์ยท์ ๋ ฌ | ์โ์๋ [์ค๋ช
ํ ์ค(caption, muted)] โ ํ๋ ์ค. ํ๋ ์ค์ [๋ณด์กฐ][์ฃผ] ์์๋ก ๊ฐ์ ํญ์ ๋๋๋ค. ์ฃผ ํ๋์ ํ๋๋ค | `react/src/bottom-cta.tsx`, `react-native/src/actions.tsx` |
|
|
81
81
|
| ๊ณ ์ ยท์คํฌ๋กค | ๋ณธ๋ฌธ ์คํฌ๋กค ์์ญ ์๋์ ๋ถ๋๋ค. Web์ `flow`(๋ฌธ์ ํ๋ฆ ๋) ๋๋ `sticky`(์๋ 0์ ๋ถ์, z-index `layer.sticky` 100). Native๋ ์ ํ ํ๋ฉด ๋ ์ด์์์ด ์คํฌ๋กค ์์ญ ๋ฐ ์๋์ ๋๋ค. ํค๋ณด๋๊ฐ ์ด๋ฆฌ๋ ํผ์ `KeyboardAvoiding` ๋๋ `KeyboardDock`์ผ๋ก ๊ฐ์ผ๋ค | `.hjm-bottom-cta[data-position="sticky"]`, `react-native/src/keyboard-controller.tsx` |
|
|
82
|
-
| `ScreenLayout` `footer` ์ | footer๊ฐ ์ ๊ฒฝ๊ณยท`screenPatternRecipe.padding` 16ยท๋ฐํยทsafe area๋ฅผ ๋งก์ผ๋ฏ๋ก BottomCTA๋ ๋ฐ(๊ฒฝ๊ณยท์ฌ๋ฐฑยท๋ฐํยท๊ทธ๋ฆผ์ยท์ต์ ๋์ด)๋ฅผ ๊ทธ๋ฆฌ์ง ์๊ณ ์ค๋ช
๊ณผ ํ๋ ์ค๋ง ๊ทธ๋ฆฐ๋ค. ์ง์ ๋๊ธด `safeAreaBottom
|
|
82
|
+
| `ScreenLayout` `footer` ์ | footer๊ฐ ์ ๊ฒฝ๊ณยท`screenPatternRecipe.padding` 16ยท๋ฐํยทsafe area๋ฅผ ๋งก์ผ๋ฏ๋ก BottomCTA๋ ๋ฐ(๊ฒฝ๊ณยท์ฌ๋ฐฑยท๋ฐํยท๊ทธ๋ฆผ์ยท์ต์ ๋์ด)๋ฅผ ๊ทธ๋ฆฌ์ง ์๊ณ ์ค๋ช
๊ณผ ํ๋ ์ค๋ง ๊ทธ๋ฆฐ๋ค. ๋ฒํผ ์๋ ์ฌ๋ฐฑ์ `max(footer ์๋ ์ฌ๋ฐฑ, safeAreaBottom)`์ด๋ค โ ์ง์ ๋๊ธด `safeAreaBottom`์ footer๊ฐ ์ด๋ฏธ ์ค ์ฌ๋ฐฑ์ ๋๋ ๋งํผ๋ง ๋ํ๋ค(16 + 34๊ฐ ์๋๋ผ 34). Native๋ ํ๋ฉด inset์ ScreenLayout `safeAreaBottom`์ผ๋ก ๋๊ธฐ๋ ๊ฒ์ด ๊ธฐ๋ณธ์ด๋ค. 2026-10-17 ํ๋ฉด ๋ฆฌ๋ทฐ: footer ์์ BottomCTA๊ฐ ๊ฒฝ๊ณ๋ฅผ ๋ ๊ฒน ๊ธ๊ณ ๋ฒํผ์ ํ ๋ฒ ๋ ๋ค์์ผ๋ฉฐ Native๋ footer ์์ ๊ทธ๋ฆผ์ ์๋ ํฐ ์์๋ฅผ ํ๋ ๋ ๊ทธ๋ ธ๋ค | ๋ด๋ถ `ScreenFooterContext`, Web `.hjm-bottom-cta[data-placement="screen-footer"]`, Native `BottomCTA` |
|
|
83
83
|
| ์ข์ ํญยทํฐ ๊ธ์ | Web์ ํ๋ ์นธ ๊ธฐ์ค ํญ 132(`control.minTouchTarget` ร 3)๋ณด๋ค ์ข์ผ๋ฉด ์ค๋ฐ๊ฟํ๋ค. ํฐ ๊ธ์์์๋ ์ธ๋ก๋ก ์๊ณ ์ฃผ ํ๋์ด ์์ ์จ๋ค | `.hjm-bottom-cta__actions > div`, `.hjm-bottom-cta[data-large-text="true"]` |
|
|
84
84
|
|
|
85
85
|
```text
|
|
@@ -103,7 +103,7 @@ const insets = useSafeAreaInsets();
|
|
|
103
103
|
Native Form์ ๋ด์ฅ ์ ์ถ ๋ฒํผ(`submitLabel` ํ์)์ ํญ์ ๊ทธ๋ฆฌ๋ฏ๋ก Form ๋์ ํ๋ + contracts `createFormSubmitSession`
|
|
104
104
|
(`@hjmds/design-contracts/components/form`)์ผ๋ก ์ ์ถ ์ธ์
์ ์ก๊ณ ๊ทธ ์ํ๋ฅผ `primaryAction.loading`์ ์ฐ๊ฒฐํ๋ค.
|
|
105
105
|
- ๋ฐฐ์น๋ `layoutStyle`๋ก๋ง ํ๋ค. Native `style`์ ์ ๊ฑฐ๋ ์์ฑ์ด๋ค.
|
|
106
|
-
- ํ๋จ inset์ ๋๊ธด๋ค. Native๋ ์๋์ผ๋ก ์ฝ์ง ์์ผ๋ฏ๋ก `safeAreaBottom`์ด ์์ผ๋ฉด ํ ์ธ๋์ผ์ดํฐ์ ๋ถ๋๋ค.
|
|
106
|
+
- ํ๋จ inset์ ๋๊ธด๋ค. Native๋ ์๋์ผ๋ก ์ฝ์ง ์์ผ๋ฏ๋ก `safeAreaBottom`์ด ์์ผ๋ฉด ํ ์ธ๋์ผ์ดํฐ์ ๋ถ๋๋ค. ScreenLayout `footer` ์์ด๋ฉด ScreenLayout `safeAreaBottom`์ ๋๊ธฐ๊ณ , host SafeAreaView์ ์๋ edge์ ๊ฐ์ด ์ฐ์ง ์๋๋ค(inset ์์ footer 16์ด ๋ํด์ง๋ค).
|
|
107
107
|
- ํค๋ณด๋๊ฐ ์ด๋ฆฌ๋ ํผ ํ๋ฉด(Native)์ `KeyboardAvoiding`(`/keyboard`) ๋๋ `KeyboardDock`(`/keyboard-controller`,
|
|
108
108
|
optional peer `react-native-keyboard-controller` ์ค์น ํ์)๋ก ๊ฐ์ผ๋ค.
|
|
109
109
|
|
|
@@ -126,3 +126,7 @@ const insets = useSafeAreaInsets();
|
|
|
126
126
|
- Native๋ ํ๋จ inset์ ์ค์ค๋ก ์ฝ์ง ์๋๋ค. `safeAreaBottom`์ ๋น ๋จ๋ ค๋ ์ค๋ฅ๊ฐ ์๊ณ ํ ์ธ๋์ผ์ดํฐ์ ๋ถ์ด ๋ณด์ธ๋ค.
|
|
127
127
|
|
|
128
128
|
1.15.0 ๋ณ๊ฒฝ: ํ๋กํ์ `shadow.floating` ์ยท๊ฐ๋ยท๋ฐ๊ฒฝ์ ์์ํ๋, ์ ์ฝํ
์ธ ์ ๊ฒน์น๋ footer ์ญํ ์ด๋ผ offsetY๋ `-abs(offsetY)`๋ก ์์ชฝ์ ํ์ํ๋ค. Native์ 0-opacity ํ๋กํ์ Android elevation๋ 0์ด๋ค. ํ๋กํ ์๋ Web์ ๊ธฐ์กด ๋ฌด๊ทธ๋ฆผ์, Native๋ ๊ธฐ์กด ์์ชฝ recipe ๊ทธ๋ฆผ์๋ฅผ ์ ์งํ๋ค. safe areaยทํฐ ๊ธ์ยท๋ก๋ฉ/์คํจ์ ์ ํ ํ๋ ์์ ๊ถ์ ๋ฐ๋์ง ์๋๋ค.
|
|
129
|
+
|
|
130
|
+
## ๊ทผ๊ฑฐ
|
|
131
|
+
|
|
132
|
+
- footer ์ ํ๋จ inset์ ํฉ์ด ์๋๋ผ max: 2026-10-17 ์ฌ์ฉ์ ๋ณด๊ณ "์ ์ฒด์ ์ผ๋ก ๋ฒํผ ์๋ ์ฌ๋ฐฑ์ด ๋ง์". footer 16 ์์ `safeAreaBottom`์ ๋ํด ํ ์ธ๋์ผ์ดํฐ ๊ธฐ๊ธฐ์์ ๋ฒํผ ์๋๊ฐ 50์ด ๋๋ค. ๋ง์ง๋ง ์ปจํธ๋กค ์๋ ์ฌ๋ฐฑ์ footer ์ ์ฌ๋ฐฑ 16๊ณผ ๊ฐ๊ฒ ๋๊ณ , ํ ์ธ๋์ผ์ดํฐ๊ฐ ์์ผ๋ฉด max(16, inset)๋ง ๋๋ค([ScreenLayout ๊ทผ๊ฑฐ](screen-layout.md#๊ทผ๊ฑฐ)).
|
|
@@ -65,7 +65,7 @@ Native renderer๋ ์๋ค.
|
|
|
65
65
|
| --- | --- | --- |
|
|
66
66
|
| ํฌ๊ธฐ | ๋ด์ฉ ํญ๋ง ์ฐจ์งํ๋ ํ ์ค ๊ฒฝ๋ก. ๊ธ์๋ `label` ๋ณํ(12/18). ๋งํฌ ๋์ด๊ฐ 44์ ๋ชป ๋ฏธ์น๋ฏ๋ก ํฐ์น ์ค์ฌ ํ๋ฉด์ ์ฃผ ํ์์ผ๋ก ์ฐ์ง ์๋๋ค | `breadcrumbRecipe.link`ยท`current` |
|
|
67
67
|
| ๊ฐ๊ฒฉ | ํญ๋ชฉยท๊ตฌ๋ถ์ ์ฌ์ด `spacing.xxs` 4. ๋ฐ๊นฅ ์ฌ๋ฐฑ์ด ์์ผ๋ฏ๋ก ์๋ ์ ๋ชฉยท๋ณธ๋ฌธ๊ณผ์ ๊ฐ๊ฒฉ์ ํ๋ฉด์ ์ธ๋ก [Stack](stack.md)์ด ์ ํ๋ค | `breadcrumbRecipe.gap`, `.hjm-breadcrumb` |
|
|
68
|
-
| ์์ยท์ ๋ ฌ | ํ์ด์ง ์ ๋ชฉ ๋ฐ๋ก ์, ๋ณธ๋ฌธ ์์ ์ชฝ ์ ๋ ฌ. ์์ โ ํ์ฌ ์์์ด๊ณ ํ์ฌ ์์น(๋ง์ง๋ง)๋ ๋งํฌ๊ฐ ์๋๋ฉฐ
|
|
68
|
+
| ์์ยท์ ๋ ฌ | ํ์ด์ง ์ ๋ชฉ ๋ฐ๋ก ์, ๋ณธ๋ฌธ ์์ ์ชฝ ์ ๋ ฌ. ์์ โ ํ์ฌ ์์์ด๊ณ ํ์ฌ ์์น(๋ง์ง๋ง)๋ ๋งํฌ๊ฐ ์๋๋ฉฐ medium(500)์ผ๋ก ํ์ํ๋ค | `.hjm-breadcrumb__current` |
|
|
69
69
|
| ๊ณ ์ ยท์คํฌ๋กค | ๊ณ ์ ๋์ง ์๊ณ ๋ณธ๋ฌธ๊ณผ ํจ๊ป ์คํฌ๋กคํ๋ค | `.hjm-breadcrumb__list` |
|
|
70
70
|
| ์ข์ ํญยทํฐ ๊ธ์ | ์ค๋ฐ๊ฟ๋๋ค(`flex-wrap: wrap`). ํญ๋ชฉ label๋ ์ค๋ฐ๊ฟ๋๊ณ ๊ตฌ๋ถ์๋ ์ค์ด๋ค์ง ์๋๋ค | `.hjm-breadcrumb__list`, `.hjm-breadcrumb__separator { flex-shrink: 0 }` |
|
|
71
71
|
|
|
@@ -79,3 +79,7 @@ Native renderer๋ ์๋ค.
|
|
|
79
79
|
|
|
80
80
|
- ์กฐ์ ํญ๋ชฉ์ ์ผ๋ฐ `<a href>`๋ก ๊ทธ๋ฆฐ๋ค. ๋ผ์ฐํฐ adapter prop(`renderLink` ๋ฑ)์ด ์์ผ๋ฏ๋ก
|
|
81
81
|
Next.js `Link` ๊ฐ์ ํด๋ผ์ด์ธํธ ์ ํ์ ๊ธฐ๋ํ์ง ์๋๋ค.
|
|
82
|
+
|
|
83
|
+
## ๊ทผ๊ฑฐ
|
|
84
|
+
|
|
85
|
+
2026-10-17 ์ฌ์ฉ์ ๊ฒฐ์ ("๊ตต๊ธฐ ์ข๋ ์ค์ฌ"): ๋ชจ๋ ๊ธ์ ๊ตต๊ธฐ๋ฅผ ํ ๋จ๊ณ ๋ฎ์ท๋ค. ํฐ ์ซ์ยท์ ํ ์ํ 600(ํฐ ์ ๋ชฉ ๋จ๊ณ๋ ๊ฐ์ ๋ ํ์ง), ์ ๋ชฉยท๊ฐ์กฐ 500, label 500, ๋ณธ๋ฌธ 400์ด๋ฉฐ ์ ๋ณธ์ [ํ์ดํฌ๊ทธ๋ํผ](../tokens/typography.md)๋ค.
|
|
@@ -79,7 +79,7 @@ import { CheckboxGroup } from "@hjmds/react-native/inputs";
|
|
|
79
79
|
| --- | --- | --- |
|
|
80
80
|
| ํฌ๊ธฐ | ํญ์ ์ฑ์ฐ๋ ๋ฌถ์. ๊ฐ ํ์ [Checkbox](checkbox.md) ๊ท๊ฒฉ(์ต์ ๋์ด `medium` 56 ยท `small` 44, ํ์ 24 ยท 20) | `selectionControlRecipe.sizes`, `.hjm-choice` |
|
|
81
81
|
| ๊ฐ๊ฒฉ | ๊ทธ๋ฃน ์ด๋ฆ(legend)โํญ๋ชฉ `spacing.xs` 8. ํญ๋ชฉ ์ฌ์ด ์ธ๋ก `card` `spacing.xs` 8 ยท `plain` `spacing.xxs` 4 ยท `grouped` 0, ๊ฐ๋ก `card` `spacing.md` 16 ยท `plain` `spacing.sm` 12 ยท `grouped` 0. ์ค๋ช
ยท์ค๋ฅ๋ `formSupportContract.gap` `spacing.xs` 8 | `selectionGroupRecipe.orientations`, `.hjm-checkbox-group*` |
|
|
82
|
-
| ์์ยท์ ๋ ฌ | ์โ์๋ [๊ทธ๋ฃน ์ด๋ฆ(
|
|
82
|
+
| ์์ยท์ ๋ ฌ | ์โ์๋ [๊ทธ๋ฃน ์ด๋ฆ(medium 500)] โ [์ค๋ช
] โ [ํญ๋ชฉ๋ค] โ [์ค๋ฅ]. ํญ๋ชฉ์ ์์ ์ชฝ ์ ๋ ฌ. `grouped`๋ ํญ๋ชฉ๋ค์ ํ
๋๋ฆฌ 1pxยท`radius.lg` 16 ์นด๋ ํ๋์ ๋ถ์ฌ ๋ด๋๋ค | `selectionGroupRecipe.slots`, `.hjm-checkbox-group[data-presentation="grouped"]` |
|
|
83
83
|
| ๊ณ ์ ยท์คํฌ๋กค | ๊ณ ์ ์์ญ์ด ์๋ค. ๋ชฉ๋ก์ด ๊ธธ์ด๋ ๊ทธ๋ฃน ์์์ ์คํฌ๋กค ์์ญ์ ๋ง๋ค์ง ์๋๋ค | `.hjm-checkbox-group__items` |
|
|
84
84
|
| ์ข์ ํญยทํฐ ๊ธ์ | `horizontal`์ ์ค๋ฐ๊ฟ๋๋ค(`flex-wrap: wrap`). ์ข์ ํญยทํฐ ๊ธ์์์๋ `vertical`์ ์ด๋ค | `.hjm-checkbox-group[data-orientation="horizontal"]` |
|
|
85
85
|
|
|
@@ -102,3 +102,7 @@ import { CheckboxGroup } from "@hjmds/react-native/inputs";
|
|
|
102
102
|
| ๊ทธ๋ฃน ์ ์ฒด ๋นํ์ฑ | `disabled`(fieldset) | `disabled` |
|
|
103
103
|
| ํ์ยท์ฝ๊ธฐ ์ ์ฉ ์๋ด | `aria-required`ยท`aria-readonly` | `requiredLabel`ยท`readOnlyLabel`์ ํ hint๋ก ์ฝ์ |
|
|
104
104
|
| ์ ํ ํ์ ๊ต์ฒด | ์์ | `indicator="none"`, `renderIndicator(item, props)` |
|
|
105
|
+
|
|
106
|
+
## ๊ทผ๊ฑฐ
|
|
107
|
+
|
|
108
|
+
2026-10-17 ์ฌ์ฉ์ ๊ฒฐ์ ("๊ตต๊ธฐ ์ข๋ ์ค์ฌ"): ๋ชจ๋ ๊ธ์ ๊ตต๊ธฐ๋ฅผ ํ ๋จ๊ณ ๋ฎ์ท๋ค. ํฐ ์ซ์ยท์ ํ ์ํ 600(ํฐ ์ ๋ชฉ ๋จ๊ณ๋ ๊ฐ์ ๋ ํ์ง), ์ ๋ชฉยท๊ฐ์กฐ 500, label 500, ๋ณธ๋ฌธ 400์ด๋ฉฐ ์ ๋ณธ์ [ํ์ดํฌ๊ทธ๋ํผ](../tokens/typography.md)๋ค.
|
|
@@ -124,4 +124,5 @@ Web์์ ์ธ๋ถ ์ํ ๋ณ๊ฒฝ์ผ๋ก ๋ซํ ๋ ๋ด๋ถ์ ์๋ ์ด์ ์ trigg
|
|
|
124
124
|
|
|
125
125
|
## ๊ทผ๊ฑฐ
|
|
126
126
|
|
|
127
|
+
- `edge` ์ถ์ ๋์ง ์๋๋ค: 2026-10-17 1.27.2 ์ฑํ ์ ๊ฒ. ํฌํธํด๋ฆฌ์ค ์ฌ์ดํธ ํค๋ ๋ ๋ฉ๋ด ํธ๋ฆฌ๊ฑฐ(402)์ ํผ์นจ ํ์ ์นธ ๋์ ํ๋ฉด ๋์์ 36์ด์๋๋ฐ, ํธ๋ฆฌ๊ฑฐ ์์ฒด๋ ์ข์ฐ padding 0์ด๊ณ ํ์ ์นธ ๋์ด ํธ๋ฆฌ๊ฑฐ ๋๊ณผ ๊ฐ๋ค(Storybook ์ธก์ : ํ์ ์นธ ๋ = ํธ๋ฆฌ๊ฑฐ ๋ = ๋ฃจํธ ๋). 36์ ์ ํ์ด TopBar(์๊ธฐ ์ฌ๋ฐฑ 16)๋ฅผ `Container gutter="regular"`(20) ์์ ๋ ๊ฒฐ๊ณผ๋ค. IconButton/Button `edge`๋ frameless ์ปจํธ๋กค์ ์์ชฝ padding๋งํผ ๋ฐ๊นฅ์ผ๋ก ๋ด๋ฏธ๋ ๊ท์น์ธ๋ฐ ์ด ํธ๋ฆฌ๊ฑฐ๋ ๋ด๋ฐ padding์ด ์์ด `edge`๋ ์๋ฌด๊ฒ๋ ๋ฐ๊พธ์ง ๋ชปํ๋ค. ์์น๋ ์ ํ์ ๊ฒน์น ์ฌ๋ฐฑ์์ ๊ณ ์น๋ค.
|
|
127
128
|
- 2026-10-17 ๊ตฌ์ฑ ๋ฆฌ๋ทฐ: ํ
์คํธ ํ์ โธ๊ฐ ์ฝ 8px๋ก ๊ทธ๋ ค์ ธ ํธ๋ฆฌ๊ฑฐ๊ฐ ์ ์ ๋ฌธ๊ตฌ์ฒ๋ผ ๋ณด์๋ค. ๊ทธ๋์ ๋ ํ๋ซํผ ๋ชจ๋ glyph.sm 20 chevron ์์ด์ฝ์ผ๋ก ๋ฐ๊ฟจ๋ค.
|
|
@@ -85,14 +85,14 @@ import { EffectSurface } from "@hjmds/react-native/effect-surface";
|
|
|
85
85
|
| --- | --- | --- |
|
|
86
86
|
| ํฌ๊ธฐ | ๊ธฐ๋ณธ ์ฌ๋ฐฑ์ ์๋ค(`padding="none"`). ํฌ๊ธฐ๋ children๊ณผ `padding`์ด ์ ํ๊ณ ์ฅ์ ๋ ์ด์ด๊ฐ ๊ทธ ์์ญ ์ ์ฒด(`absolute`, inset 0)๋ฅผ ๋ฎ๋๋ค. ๋์น๋ ์ฅ์์ `radius` ๋ชจ์๋ฆฌ ์์์ ์๋ฆฐ๋ค(`overflow: hidden`). ์์ ๋ Surface์ ๊ฐ์ ๊ธฐ๋ณธ radius๋ผ ๋ฅ๊ทผ ์นด๋ ๋ชจ์๋ฆฌ ๋ฐ์ผ๋ก ์ฅ์์ด ๋น์น์ง ์๋๋ค. ๋ฐฐ๊ฒฝ์ ํ
๋ง `bg`๋ค. ๋์ด๋ฅผ ๋๋ฆฌ๋ ค๋ฉด children ๋์ด, Web `layoutStyle`ยทNative `style`์ ๋์ด๋ก ์ ํ๋ค. ์ฅ์ ๋ ์ด์ด๋ ๋ฐฐ์น์ ์ฐธ์ฌํ์ง ์๋๋ค | `react/src/effect-surface.tsx`, `react-native/src/effect-surface.tsx` |
|
|
87
87
|
| ๊ฐ๊ฒฉ | ์์ชฝ ์ฌ๋ฐฑ์ `padding`(์: `lg` 20), ๋ด์ฉ ์ฌ์ด ๊ฐ๊ฒฉ์ children ์ชฝ [Stack](stack.md)์ผ๋ก ์ค๋ค. raw ์์์ padding์ ์ง์ ์ฃผ์ง ์๋๋ค | `react/src/effect-surface.tsx` |
|
|
88
|
-
| ์์ยท์ ๋ ฌ | children์ ์ผ๋ฐ ๋ ์ด์์์ด๋ค. [Stack](stack.md)์ผ๋ก eyebrow โ [Heading](heading.md) โ ์๊ฐ โ [Button](button.md)์ ์๋๋ค(Showcase ๋๋ฉ ์๋ `gap="lg"` 20, Heading `
|
|
88
|
+
| ์์ยท์ ๋ ฌ | children์ ์ผ๋ฐ ๋ ์ด์์์ด๋ค. [Stack](stack.md)์ผ๋ก eyebrow โ [Heading](heading.md) โ ์๊ฐ โ [Button](button.md)์ ์๋๋ค(Showcase ๋๋ฉ ์๋ `gap="lg"` 20, Heading `level3` 24ยทh1) | `showcase/web/src/patterns/Landing.stories.tsx` |
|
|
89
89
|
| ๊ณ ์ ยท์คํฌ๋กค | ํ๋ฉด ์์ชฝ ํ์ด๋ก ํ๋์๋ง ๋๋ค. ๊ฐ์ ํ๋ฉด์ ์ฌ๋ฌ ๊ฐ๋ฅผ ๊ฒน์น๊ฑฐ๋ ๋ชฉ๋ก ํ๋ง๋ค ๋์ง ์๋๋ค | โ |
|
|
90
90
|
| ์ข์ ํญยทํฐ ๊ธ์ | โ | โ |
|
|
91
91
|
|
|
92
92
|
```text
|
|
93
93
|
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ EffectSurface(๋ฐฐ๊ฒฝ bg + mesh/glow/grain, ํฐ์น ์์)
|
|
94
94
|
โ eyebrow โ
|
|
95
|
-
โ
|
|
95
|
+
โ ์ ๋ชฉ(Heading level3, 24) โ โ children: ์ผ๋ฐ ๋ ์ด์์(Stack gap lg 20)
|
|
96
96
|
โ ์๊ฐ ๋ฌธ์ฅ โ
|
|
97
97
|
โ [์์ํ๊ธฐ] primary โ
|
|
98
98
|
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
|
|
11
11
|
## ์ธ์ ์ฐ๋
|
|
12
12
|
|
|
13
|
-
์๋ฆฌ๋ฅผ ๋ชจ๋ฅด๋
|
|
14
|
-
์นด๋ยทํยท๋น ์ํ ์์ ์ ๋ชฉ์ฒ๋ผ
|
|
15
|
-
|
|
13
|
+
์๋ฆฌ๋ฅผ ๋ชจ๋ฅด๋ ์ ๋ชฉ ๊ธ์ ํ๋๊ฐ ํ์ํ ๋ ์ด๋ค. ๋๋ฉ ๋ํ ์ ๋ชฉ, ๊ฒฐ๊ณผ ํ๋ฉด์ ์ ๋ชฉ,
|
|
14
|
+
์นด๋ยทํยท๋น ์ํ ์์ ์ ๋ชฉ์ฒ๋ผ ๋ฌธ์ ์ ๋ชฉ ๋จ๊ณ๋ฅผ ์ค์ ๋ก ๋ด์ผ ํ๋ ์๋ฆฌ๋ค. ํฌ๊ธฐ๋ `Text`์ ๊ฐ์
|
|
15
|
+
๋จ๊ณ(์ต๋ 24px)๋ฅผ ์ด๋ค. ์ฃผ๋ณ ์ฌ๋ฐฑ์ ๊ฐ์ง ์๋๋ค. ๋ด๋ ๋ธ๋ก์ด ์ ํ๋ค.
|
|
16
16
|
|
|
17
17
|
## ์ฐ์ง ์์ ๋
|
|
18
18
|
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
// Web
|
|
35
35
|
import { Heading } from "@hjmds/react/heading";
|
|
36
36
|
|
|
37
|
-
<Heading level="
|
|
37
|
+
<Heading level="level3" semanticLevel={2}>{t("result.title")}</Heading>
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
```tsx
|
|
@@ -48,23 +48,23 @@ import { Heading } from "@hjmds/react-native/heading";
|
|
|
48
48
|
|
|
49
49
|
| prop | ๊ฐ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช
|
|
|
50
50
|
| --- | --- | --- | --- |
|
|
51
|
-
| `level`(ํ์) | `
|
|
51
|
+
| `level`(ํ์) | `level3` 24px/500 ยท `level4` 20px/500 ยท `level5` 18px/500. `level1`ยท`level2`๋ ์ฌ์ฉ ์ค๋จ๋ ์ด๋ฆ์ผ๋ก `level3`๊ณผ ๊ฐ์ 24px/500์ด๋ค | โ | recipe ๊ธฐ๋ณธ์ `level3`์ด์ง๋ง ๋ renderer ๋ชจ๋ prop์ ํ์๋ก ๋ฐ๋๋ค. ๊ฐ์ฅ ํฐ ๋จ๊ณ๋ 24px๋ค |
|
|
52
52
|
| `semanticLevel` | 1~6 | `level`์ ์ซ์ | ํฌ๊ฒ ๋ณด์ด์ง๋ง ๊ตฌ์กฐ์ h4์ธ ์นด๋ ์ ๋ชฉ์ฒ๋ผ ์๊ฐ ํฌ๊ธฐ์ ๋ฌธ์ ๋จ๊ณ๊ฐ ๋ค๋ฅด๋ฉด ๋์ ๋ฐ๋ก ์ ๋๋ค |
|
|
53
53
|
| `layoutStyle` | ๋ฐฐ์น key(marginยทํญยท์ ๋ ฌ ๋ฑ) | โ | ๋ฐ๊นฅ ๋ฐฐ์น๋ง. ํฌ๊ธฐยท์ค ๋์ดยท๊ตต๊ธฐยท์์ ๋ฐ์ง ์๋๋ค |
|
|
54
54
|
|
|
55
55
|
- ๋ฒ์ ๋ฐ ๊ฐ์ `TypeError`๋ก ๊ฑฐ๋ถ๋๋ค.
|
|
56
56
|
- ์ ํฌ๊ธฐ๋ ํ๋กํ ์๋ ๊ธฐ๋ณธ๊ฐ์ด๋ค. [๋์์ธ ํ๋กํ](../../design-profile.md)์
|
|
57
|
-
`tokens.heading
|
|
58
|
-
`
|
|
59
|
-
- `defineHjmDesignProfile`์์ `tokens.typography.heading/titleLarge/title`์ ๋ฐ๊พธ๋ฉด
|
|
60
|
-
|
|
61
|
-
๊ฐ์ด ์ฐ์ ํ๋ค.
|
|
57
|
+
`tokens.heading`์ผ๋ก ์๊ฐ ๋จ๊ณ๋ฅผ ์ง์ ํ๋ฉด ์ renderer๊ฐ ๋ฐ๋ฅด๋ฉฐ, `semanticLevel`์ ๊ทธ๋๋ก๋ค.
|
|
58
|
+
์ด๋ ๋จ๊ณ๋ `typography.heading` 24px๋ฅผ ๋์ผ๋ฉด `RangeError`๋ก ๊ฑฐ๋ถ๋๋ค. ํฌ๊ธฐ๋ฅผ ๋ง์ถ๋ ค๊ณ ๋ฌธ์ ๋จ๊ณ๋ฅผ ๋ฐ๊พธ์ง ์๋๋ค.
|
|
59
|
+
- `defineHjmDesignProfile`์์ `tokens.typography.heading/titleLarge/title`์ ๋ฐ๊พธ๋ฉด
|
|
60
|
+
level1~3/4/5๊ฐ ๊ทธ ๊ฐ์ ๋ฐ๋ฅธ๋ค. ๊ฐ์ ๋จ๊ณ์ `tokens.heading`๋ ์ง์ ํ๋ฉด ๋ช
์ํ heading
|
|
61
|
+
๊ฐ์ด ์ฐ์ ํ๋ค.
|
|
62
62
|
|
|
63
63
|
## ๋ฐฐ์น
|
|
64
64
|
|
|
65
65
|
| ํญ๋ชฉ | ๊ฐ | ๊ทผ๊ฑฐ |
|
|
66
66
|
| --- | --- | --- |
|
|
67
|
-
| ํฌ๊ธฐ | ์ค ๋์ด: `
|
|
67
|
+
| ํฌ๊ธฐ | ์ค ๋์ด: `level3` 32 ยท `level4` 28 ยท `level5` 26 (`level1`ยท`level2`๋ 32) | `foundations.ts` `heading`, `typography` |
|
|
68
68
|
| ๊ฐ๊ฒฉ | Heading์ margin์ด 0์ด๋ค(Web `.hjm-heading`). ์์๋ ๊ฐ๊ฒฉ์ ๊ฐ์ธ๋ StackยทSection์ `gap`์ด ์ ํ๋ค | `styles.css` `.hjm-heading` |
|
|
69
69
|
| ์์ยท์ ๋ ฌ | ํ ๋ธ๋ก์ Heading์ ํ๋๋ฅผ ๋งจ ์์ ๋๋ค | โ |
|
|
70
70
|
| ๊ณ ์ ยท์คํฌ๋กค | โ | โ |
|
|
@@ -88,7 +88,9 @@ import { Heading } from "@hjmds/react-native/heading";
|
|
|
88
88
|
|
|
89
89
|
## ๊ทผ๊ฑฐ
|
|
90
90
|
|
|
91
|
-
2026-10-17 ์ฌ์ฉ์
|
|
91
|
+
2026-10-17 ์ฌ์ฉ์ ๊ฒฐ์ ("๊ธ์ ๋๋ฌด ์ปค", "ํฐ ๊ธ์ ์ ์ฑ
์ ์์ "): ํฐ ๊ธ์ ๋จ๊ณ๋ฅผ ํ์งํ๋ค. Native Storybook ์๋น์ค ์๊ฐ ํ๋ฉด์ ํ์ด๋ก ์ ๋ชฉ(level1 40px)๊ณผ ๊ตฌํ ์ ๋ชฉ(level2 32px)์ด ์ง๋์น๊ฒ ์ปธ๋ ๊ฒ์ด ๊ณ๊ธฐ๋ค. `level1`ยท`level2`๋ ๊ธฐ์กด ์๋น ์ฝ๋๊ฐ ๊นจ์ง์ง ์๋๋ก ์ด๋ฆ๋ง ๋จ๊ธฐ๊ณ `level3`๊ณผ ๊ฐ์ 24/32/500์ผ๋ก ๊ณ ์ ํ์ผ๋ฉฐ ์ ์ฝ๋์์ ์ฐ์ง ์๋๋ค. ์๊ณ๋ `level3`(24) โ `level4`(20) โ `level5`(18)๋ก ๋ง๋ค๊ณ , ๋ฌธ์ ๊ตฌ์กฐ๋ `semanticLevel`๋ก ์ ๋๋ค. `Top size="large"` ์ ๋ชฉ๋ `heading.level3` 24px๋ค. ๋ธ๋ฃจํ๋ฆฌ์ฆ ํ๋ฆฌ์
์ ๊ตต๊ธฐ๋ง 800์ผ๋ก ๋ช
์ํ๊ณ ํฌ๊ธฐ๋ ๊ณตํต ๋จ๊ณ๋ฅผ ๋ฐ๋ฅธ๋ค.
|
|
92
|
+
|
|
93
|
+
๊ฐ์ ๋ ์์ ๊ตต๊ธฐ ๊ฒฐ์ : ์ ๋ชฉ ๋จ๊ณ(`level3`~`level5`)๋ 500(medium)์ด๋ฉฐ Native๋ `fonts="pretendard"`์ผ ๋ `Pretendard-Medium` face๋ก ๊ทธ๋ฆฐ๋ค. ์ด์ ์ ํฐ ์ ๋ชฉ 600(semibold) ๋จ๊ณ๋ ํฐ ๊ธ์ ๋จ๊ณ์ ํจ๊ป ์์ด์ก๋ค.
|
|
92
94
|
|
|
93
95
|
## ํจ์
|
|
94
96
|
|
|
@@ -86,7 +86,7 @@ Native ์ํ leading์ `full`์ Provider token์์ ์ฝ์ง๋ง ๊ณ ์ ์ํ
|
|
|
86
86
|
| --- | --- | --- |
|
|
87
87
|
| ํฌ๊ธฐ | ํ ํ๋ฉด(๋๋ฆยทhoverยท์ ํ ๋ฐฐ๊ฒฝ, ํฌ์ปค์ค ๋ง, ๋๋ฅผ ์ ์๋ ์์ญ)์ ๋ถ๋ชจ ์ฝํ
์ธ ํญ๋ณด๋ค ์์ชฝ์ผ๋ก `listRowRecipe.surfaceBleed`(= density `paddingHorizontal`, `spacing.xs` 8)์ฉ ๋๋ค(Web `inline-size: calc(100% + 16)` + `margin-inline: -8`, Native `marginHorizontal: -8`). ๊ธ์ยทleadingยทtrailing์ ๋ถ๋ชจ ์ฝํ
์ธ ๊ฐ์ฅ์๋ฆฌ์ ๋์ธ๋ค. leading ํ๋ ์์ 40ร40(`leadingSize`), `circle`์ด๋ฉด `radius.full`. trailing ์์ด์ฝ์ `glyph.sm` 20. ์ต์ ๋์ด๋ ์๋ density ํ | `design-contracts/src/component-recipes.ts`(`listRowRecipe`), `design-contracts/src/foundations.ts`(`layout.rowHeight`) |
|
|
88
88
|
| ๊ฐ๊ฒฉ | leadingยทcontentยทtrailing ์ฌ์ด `spacing.sm` 12(`listRowRecipe.gap`). ํ ์ ์ข์ฐ ์ฌ๋ฐฑ 8์ ํ๋ฉด์ด ๋ฐ๊นฅ์ผ๋ก ๋์ด์ง ๋งํผ์ด๋ผ ๊ธ์๋ ๋ถ๋ชจ ์ฝํ
์ธ ๊ฐ์ฅ์๋ฆฌ(๊ธฐ๋ณธ ํ๋ฉด์ด๋ฉด ์ฌ๋ฐฑ ์ 16)์์ ์์ํ๋ค. ์์๋ ์ฌ๋ฐฑ์ ์๋ density ํ. Native์ ํฌ๋ช
์ ํ ํ
๋๋ฆฌ 1์ ์ด ์ฌ๋ฐฑ ์์ ํฌํจ๋๋ค(ํ
๋๋ฆฌ + padding = 8). ์ ํ์ ํ์ margin์ ์ฃผ์ง ์๋๋ค | `design-contracts/src/component-recipes.ts`(`listRowRecipe`), `react/src/styles.css`(`.hjm-list-row`) |
|
|
89
|
-
| ์์ยท์ ๋ ฌ | leading โ content(์ ๋ชฉยท์ค๋ช
) โ trailing. trailing ๋ด์ฉ(์์ด์ฝยทSwitchยท๋ฌธ๊ตฌ)์ ํ์ ์ธ๋ก ๊ฐ์ด๋ฐ์ ๋๋ค(Web `.hjm-list-row__trailing` flex ๊ฐ์ด๋ฐ, Native ํ ๊ฐ์ด๋ฐ ์ ๋ ฌ View). `trailingAction`(๋ ํ๋ซํผ)์ ํ ๋ช
๋ น ๋ฐ๊นฅ ๋์ `listRowRecipe.gap` 12 ๋จ์ด์ ธ ๋์ด๊ณ , ๋ช
๋ น๊ณผ ํจ๊ป ํ๋์ ํ๋ฉด(์ ํ ๋ฐฐ๊ฒฝยทํ
๋๋ฆฌ)์ ์ด๋ค. ํ๋ ์์์ ๋์ ๋ถ๋ชจ ์ฝํ
์ธ ๊ฐ์ฅ์๋ฆฌ์ ๋ง์ผ๋ฏ๋ก ghost IconButton์ `edge="end"`๋ฅผ ์ฃผ๋ฉด glyph ์นธ ๋์ด ์ฌ๋ฐฑ ์ 16์ ์จ๋ค. ํ ์ฌ์ด ๊ตฌ๋ถ์ ยท๋ฐ๊นฅ ๋ฅ๊ทผ ๋ฐฐ๊ฒฝ์ [List](list.md)๊ฐ
|
|
89
|
+
| ์์ยท์ ๋ ฌ | leading โ content(์ ๋ชฉยท์ค๋ช
) โ trailing. trailing ๋ด์ฉ(์์ด์ฝยทSwitchยท๋ฌธ๊ตฌ)์ ํ์ ์ธ๋ก ๊ฐ์ด๋ฐ์ ๋๋ค(Web `.hjm-list-row__trailing` flex ๊ฐ์ด๋ฐ, Native ํ ๊ฐ์ด๋ฐ ์ ๋ ฌ View). `trailingAction`(๋ ํ๋ซํผ)์ ํ ๋ช
๋ น ๋ฐ๊นฅ ๋์ `listRowRecipe.gap` 12 ๋จ์ด์ ธ ๋์ด๊ณ , ๋ช
๋ น๊ณผ ํจ๊ป ํ๋์ ํ๋ฉด(์ ํ ๋ฐฐ๊ฒฝยทํ
๋๋ฆฌ)์ ์ด๋ค. ํ๋ ์์์ ๋์ ๋ถ๋ชจ ์ฝํ
์ธ ๊ฐ์ฅ์๋ฆฌ์ ๋ง์ผ๋ฏ๋ก ghost IconButton์ `edge="end"`๋ฅผ ์ฃผ๋ฉด glyph ์นธ ๋์ด ์ฌ๋ฐฑ ์ 16์ ์จ๋ค. ํ ์ฌ์ด ๊ตฌ๋ถ์ ยท๋ฐ๊นฅ ๋ฅ๊ทผ ๋ฐฐ๊ฒฝ์ [List](list.md)๊ฐ ๊ทธ๋ฆฐ๋ค. ํ์ leading ์ฌ๋ถ๋ฅผ List์ ์๋ ค(Web ๋ฃจํธ `data-leading`, Native List ํญ๋ชฉ context) ์๊ธฐ ์๋ `indented` ๊ตฌ๋ถ์ ์ด ๊ธ์ ์ด(leading ์์ผ๋ฉด 52, ์์ผ๋ฉด 0)์์ ์์ํ๊ฒ ํ๋ค | `react-native/src/data-display.tsx`(ListRow), `react/src/styles.css`(`.hjm-list-row__trailing`) |
|
|
90
90
|
| ๊ณ ์ ยท์คํฌ๋กค | โ | โ |
|
|
91
91
|
| ์ข์ ํญยทํฐ ๊ธ์ | ๊ธด ์ ๋ชฉยท์ค๋ช
์ ์ค๋ฐ๊ฟ๋๊ณ (`overflow-wrap: anywhere`) ํ ๋์ด๊ฐ ๋์ด๋๋ค. ํฐ ๊ธ์์์๋ ์๋ฅด์ง ์๋๋ค | `react/src/styles.css`(`.hjm-list-row`) |
|
|
92
92
|
|
|
@@ -100,7 +100,7 @@ Native ์ํ leading์ `full`์ Provider token์์ ์ฝ์ง๋ง ๊ณ ์ ์ํ
|
|
|
100
100
|
```text
|
|
101
101
|
ํ๋ฉด ๋ โ ์ฌ๋ฐฑ ์ 16 โ โ ์ฌ๋ฐฑ ์ 16
|
|
102
102
|
โโ8โโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโ8โโ โ ํ ํ๋ฉด(๋๋ฆยท์ ํ ๋ฐฐ๊ฒฝ), 8์ฉ ๋ฐ๊นฅ์ผ๋ก
|
|
103
|
-
โ โ[40ร40]โ12โ ์ ๋ชฉ(bodyLarge
|
|
103
|
+
โ โ[40ร40]โ12โ ์ ๋ชฉ(bodyLarge 500) โ12โ ๊ฐ โบโ โ
|
|
104
104
|
โ โleadingโ โ ์ค๋ช
(body, secondary) โ โtrailโ โ
|
|
105
105
|
โโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโ
|
|
106
106
|
์น์
์ ๋ชฉยท๊ฒฐ๊ณผ ๊ฐ์(16)์ ํ ๊ธ์ยทleading(16)์ด ๊ฐ์ ์ ์์ ์์ํ๋ค
|
|
@@ -113,7 +113,7 @@ Native ์ํ leading์ `full`์ Provider token์์ ์ฝ์ง๋ง ๊ณ ์ ์ํ
|
|
|
113
113
|
|
|
114
114
|
- ์ ๋ชฉยท์ค๋ช
์ i18n ํค๋ก ๋ฃ๋๋ค. leading์ ์ฌ์งยท์์ด์ฝ์ ์ฅ์์ผ๋ก ๋๊ณ ์๋ฏธ๋ ์ ๋ชฉ์ด ๋งํ๋ค.
|
|
115
115
|
- ํ ์์ ๋ค๋ฅธ ๋ฒํผ์ ๋ฃ์ง ์๋๋ค. ๋ณ๋ target์ `trailingAction`์ ๋๋ค(ํ ๋ช
๋ น ์์ ๋ฐ๋ก ๊ทธ๋ฆฐ๋ค).
|
|
116
|
-
- ํ์ ๋ถ๋ชจ๊ฐ ์ข์ฐ๋ก 8 ์ด์์ ์ฌ๋ฐฑ์ ๊ฐ์ง ๊ณณ์ ๋๋ค(ํ๋ฉด ๋ณธ๋ฌธ 16, CardยทSheetยทSidePanel ๋ณธ๋ฌธ, `grouped` List). ์ฌ๋ฐฑ์ด 0์ธ ์์(์: ์ฌ๋ฐฑ ์๋ ๋ถํ ํจ๋, ์ ํ์ ๊ฝ ์ฐฌ div)์ ๋ฐ๋ก ๋๋ฉด ํ๋ฉด์ด ์๋ฆฌ๊ณ Web์ ๊ฐ๋ก ์คํฌ๋กค์ด ์๊ธด๋ค. ๊ทธ ์์์ ์ฝํ
์ธ ์ฌ๋ฐฑ์ ์ค๋ค. `ScreenLayout contentInset="body-edge"` ๋ณธ๋ฌธ์ ์๊ธฐ ์ฌ๋ฐฑ 16์ ๊ฐ์ง ์ ์ฒด ํญ ํ(ConversationRowยทNotificationRow) ์ ์ฉ์ด๋ค. ListRowยทNotificationItem์ `default` ๋ณธ๋ฌธ์ ๋๋ค(๊ทธ๋์ผ ๊ธ์๊ฐ ์ฌ๋ฐฑ ์ 16์ ์จ๋ค).
|
|
116
|
+
- ํ์ ๋ถ๋ชจ๊ฐ ์ข์ฐ๋ก 8 ์ด์์ ์ฌ๋ฐฑ์ ๊ฐ์ง ๊ณณ์ ๋๋ค(ํ๋ฉด ๋ณธ๋ฌธ 16, CardยทSheetยทSidePanel ๋ณธ๋ฌธ, `grouped` List). ์ฌ๋ฐฑ์ด 0์ธ ์์(์: ์ฌ๋ฐฑ ์๋ ๋ถํ ํจ๋, ์ ํ์ ๊ฝ ์ฐฌ div)์ ๋ฐ๋ก ๋๋ฉด ํ๋ฉด์ด ์๋ฆฌ๊ณ Web์ ๊ฐ๋ก ์คํฌ๋กค์ด ์๊ธด๋ค. ๊ทธ ์์์ ์ฝํ
์ธ ์ฌ๋ฐฑ์ ์ค๋ค. HJM์ ์คํฌ๋กค ์์๋ ์ด ์ฌ์ ๋ฅผ ์ค์ค๋ก ๋ง๋ ๋ค: VirtualList๋ ๋ฐ๊นฅ์ผ๋ก 8 ๋ํ๊ณ ์์ชฝ 8์ ๋๋ฉฐ, ์คํฌ๋กค Sheet ๋ณธ๋ฌธ์ ์ํธ ์ฌ๋ฐฑ ๋๊น์ง ๋๊ณ ์ฌ๋ฐฑ์ ์์ชฝ์ ๋๋ค(๋ด๋ถ `listRowScrollRoom`). ์ฝํ
์ธ ์์น๋ ๊ทธ๋๋ก๋ค. ํ๋ฉด์ ๋ฐ๊นฅ Container ์ฌ๋ฐฑ + `contentInset="none"`์ผ๋ก ๊ฐ์ธ๋ ๊ตฌ์ฑ์ ์ง์ํ์ง ์๋๋ค([ScreenLayout](screen-layout.md#๊ผญ-์งํฌ-๊ฒ)). `ScreenLayout contentInset="body-edge"` ๋ณธ๋ฌธ์ ์๊ธฐ ์ฌ๋ฐฑ 16์ ๊ฐ์ง ์ ์ฒด ํญ ํ(ConversationRowยทNotificationRow) ์ ์ฉ์ด๋ค. ListRowยทNotificationItem์ `default` ๋ณธ๋ฌธ์ ๋๋ค(๊ทธ๋์ผ ๊ธ์๊ฐ ์ฌ๋ฐฑ ์ 16์ ์จ๋ค).
|
|
117
117
|
- ๋ฐฐ์น๋ `layoutStyle`๋ก ํ๋ค. ๋์ดยท์ฌ๋ฐฑยท๋ฐฐ๊ฒฝ์ ๋ฎ์ง ์๋๋ค. ๋ฐ๋๋ `density`๋ก ๋ฐ๊พผ๋ค.
|
|
118
118
|
- ์๋ฐํ ํ๋ ์์ ์ ํ์ด ๋ค์ ๊ทธ๋ฆฌ์ง ์๋๋ค. `leadingShape`๋ฅผ ์ด๋ค.
|
|
119
119
|
|
|
@@ -148,5 +148,9 @@ Web๋ Native์ ๊ฐ์ด `trailingAction`์ ์ง์ํ๋ค. ์ด ์ฌ๋กฏ์ ํ์ l
|
|
|
148
148
|
|
|
149
149
|
## ๊ทผ๊ฑฐ
|
|
150
150
|
|
|
151
|
+
2026-10-17 ์ฌ์ฉ์ ๊ฒฐ์ ("๊ตต๊ธฐ ์ข๋ ์ค์ฌ"): ๋ชจ๋ ๊ธ์ ๊ตต๊ธฐ๋ฅผ ํ ๋จ๊ณ ๋ฎ์ท๋ค. ํฐ ์ซ์ยท์ ํ ์ํ 600(ํฐ ์ ๋ชฉ ๋จ๊ณ๋ ๊ฐ์ ๋ ํ์ง), ์ ๋ชฉยท๊ฐ์กฐ 500, label 500, ๋ณธ๋ฌธ 400์ด๋ฉฐ ์ ๋ณธ์ [ํ์ดํฌ๊ทธ๋ํผ](../tokens/typography.md)๋ค.
|
|
152
|
+
|
|
153
|
+
- ์คํฌ๋กค ์์์ ํ๋ฉด ์ฌ์ : 2026-10-17 1.27.2 ์ฑํ ์ ๊ฒ. Native ์คํฌ๋กค Sheet๋ ์ฌ๋ฐฑ 20์ด ScrollView ๋ฐ๊นฅ์ ์์ด ํ ํ๋ฉด์ด ์ํธ ์ฝํ
์ธ ๋(21pt)์์ ์๋ ธ๋ค(3x ์ธก์ : ์ ํ ํ
๋๋ฆฌ ์ ์ 21โ381, ์ ์ ์์ โ ์์ ํ ์ ์ 13ยท๋ 13, ์ ๋ชฉ ์์น ๊ทธ๋๋ก). VirtualList์ ๊ฐ์ ๊ท์น์ด๋ผ ๋ด๋ถ helper ํ๋๋ก ๋ฌถ์๋ค.
|
|
151
154
|
- trailing ์ธ๋ก ๊ฐ์ด๋ฐ: 2026-10-17 ์ ๋ ฌ ์ค์ธก(Web 402). trailing span์ด block์ด๋ผ ์์ inline svg๊ฐ ๊ธ์ ๊ธฐ์ค์ ์ ๋์ฌ ํ ๊ฐ์ด๋ฐ๋ณด๋ค 2~2.5px ์์๋ค(์ค์ 334/331.5, ์ปฌ๋ ์
184/181.5). Native๋ ํ ๊ฐ์ด๋ฐ(388/388)์๋ค. trailing์ flex ๊ฐ์ด๋ฐ ์์๋ก ๋ฐ๊พผ ๋ค Web๋ 334/334, 184/184๋ก ์ธก์ ๋๋ค.
|
|
152
155
|
- ๊ธ์๋ฅผ ์ฌ๋ฐฑ ์ ์, ํ๋ฉด์ ๋ฐ๊นฅ์ผ๋ก: 2026-10-17 ์ฌ์ฉ์ ๊ฒฐ์ . ํ์ด ๋๋ฆ ๋ฐฐ๊ฒฝ์ฉ ์ข์ฐ ์ฌ๋ฐฑ 8์ ์ฝํ
์ธ ์์ ๋์ด ๊ธฐ๋ณธ ํ๋ฉด์์ ํ ๊ธ์๊ฐ 16 + 8 = 24์์ ์์ํ๊ณ , ๊ฐ์ ํ๋ฉด์ ์น์
์ ๋ชฉยท๊ฒ์ ๊ฒฐ๊ณผ ๋จธ๋ฆฌ("๊ฒฐ๊ณผ N๊ฐ")ยท์ค์ ๋ฌถ์ ์ ๋ชฉ์ 16์์ ์์ํ๋ค(Web 402 ์ค์ธก: ๊ฒ์ ๊ฒฐ๊ณผ ํ 24 / ๋จธ๋ฆฌ 16, ์ค์ leading 24 / ๋ฌถ์ ์ ๋ชฉ 16, ์๋ฆผ leading 24 / "์ค๋" 16. Native 3x ํ๋ฉด ์ํฌ: ๊ฒฐ๊ณผ ํ ์ ๋ชฉ 25 / ๊ฐ์ 16.7 โ Native๋ ํฌ๋ช
์ ํ ํ
๋๋ฆฌ 1๊น์ง ๋ํด์ก๋ค). ํ๋ฉด์ ๋ฐ๊นฅ์ผ๋ก 8 ๋ํ๋ ๋ฐฉ์์ผ๋ก ๋ฐ๊พผ ๋ค Web 402ยท1280, LTRยทRTL ๋ชจ๋ ํ ๊ธ์ยทleading ์์๊ณผ trailing ๋์ด 16(1280์ ํ๋ฉด ์ด ๊ธฐ์ค 296)์ผ๋ก, Native๋ ๊ฒฐ๊ณผ ํ ์ ๋ชฉ ์ํฌ 16, ์ค์ leading ์์ด์ฝ ์ํฌ 36 โ 27, ์๋ฆผ 42.3 โ 33(ํ๋ ์ 16 + ์์ด์ฝ ์์ชฝ ์ฌ๋ฐฑ)์ผ๋ก ์ธก์ ๋๋ค. ๊ตฌ๋ถ์ ์์๋ ๊ธ์ ์์น(52)๋ก ์ฎ๊ฒผ๋ค.
|
|
156
|
+
- ๊ตฌ๋ถ์ ์ด ํ์ ๊ธ์ ์ด์ ๋ฐ๋ฆ: 2026-10-17 ์ฌ์ฉ์ ๋ณด๊ณ (leading ์๋ ํ์์ ๊ตฌ๋ถ์ ์ด ์ค๊ฐ์์ ์๋ฆผ). ์ 52๋ leading ์๋ ํ์ ๊ธ์ ์์น์ผ ๋ฟ์ด๋ผ leading ์๋ ํ(๊ธ์ 16)์์๋ ๊ตฌ๋ถ์ ์ด 68์์ ์์ํ๋ค. ํ์ด leading ์ฌ๋ถ๋ฅผ List์ ์๋ฆฌ๋๋ก ๋ฐ๊ฟ ๊ตฌ๋ถ์ ์์์ด ๊ฐ ํ์ ๊ธ์ ์ด๊ณผ ๊ฐ์์ก๋ค([List ๊ทผ๊ฑฐ](list.md#๊ทผ๊ฑฐ)).
|
|
@@ -73,7 +73,7 @@ import { Text } from "@hjmds/react-native/primitives";
|
|
|
73
73
|
| prop | ๊ฐ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช
|
|
|
74
74
|
| --- | --- | --- | --- |
|
|
75
75
|
| `label` | ํ์งํ ๋ฌธ์์ด(ํ์) | โ | ๋ชฉ๋ก์ ์ ๊ทผ์ฑ ์ด๋ฆ. ๋น๋ฉด `TypeError` |
|
|
76
|
-
| `separator` | `indented` ยท `full` ยท `none` | `indented` | `indented`๋ leading
|
|
76
|
+
| `separator` | `indented` ยท `full` ยท `none` | `indented` | `indented`๋ ์ ํ์ ๊ธ์ ์ด์์ ์์(leading์ด ์์ผ๋ฉด 52, ์์ผ๋ฉด 0) |
|
|
77
77
|
| `appearance` | `plain` ยท `grouped` | `plain` | `grouped`๋ ๋ฐฐ๊ฒฝ๊ณผ ๋ฅ๊ทผ ๋ชจ์๋ฆฌ๋ก ํ ๋ฉ์ด๋ฆฌ |
|
|
78
78
|
| `layoutStyle` | ๋ฐฐ์น key๋ง | โ | ๋ชฉ๋ก ๋ฃจํธ ๋ฐฐ์น. Native `style`์ ์ ๊ฑฐ๋ ์์ฑ โ `layoutStyle`, ๋ชจ์์ `appearance`ยท`separator` |
|
|
79
79
|
| TaskList `items` | `readonly TaskItem[]` โ `{ id, label, completed, description?, disabled? }` | โ | `id`ยท`label`์ด ๋น๊ฑฐ๋ `id`๊ฐ ์ค๋ณต๋๊ฑฐ๋ `completed`๊ฐ boolean์ด ์๋๋ฉด `TypeError` |
|
|
@@ -93,7 +93,7 @@ Native `grouped` ํ๋ ์์ Provider์ `tokens.radius.lg`๋ฅผ ์ฝ๋๋ค. plain
|
|
|
93
93
|
| ํญ๋ชฉ | ๊ฐ | ๊ทผ๊ฑฐ |
|
|
94
94
|
| --- | --- | --- |
|
|
95
95
|
| ํฌ๊ธฐ | ํ๋ฉด ๋ณธ๋ฌธ ํญ์ ์ฑ์ฐ๋ ์ธ๋ก ๋ฌถ์์ด๋ค. `plain`์ ์๋ฅด์ง ์์ผ๋ฏ๋ก ํ ํ๋ฉด์ด ๋ถ๋ชจ ์ฌ๋ฐฑ ์ชฝ์ผ๋ก 8์ฉ ๋์ด์ง๋ค(ํ ๊ธ์๋ ๋ชฉ๋ก ์ฝํ
์ธ ๊ฐ์ฅ์๋ฆฌ). `grouped`๋ ๋ฐฐ๊ฒฝ `--hjm-color-bg`์ ๋ชจ์๋ฆฌ `radius.lg` 16์ผ๋ก ํ ๋ฉ์ด๋ฆฌ๊ฐ ๋๊ณ ๊ทธ ๋ชจ์์ผ๋ก ์๋ฅด๋ฏ๋ก, ์ข์ฐ ์์ชฝ ์ฌ๋ฐฑ `listRecipe.grouped.paddingInline`(= `listRowRecipe.surfaceBleed` 8)์ ๋์ด ํ ํ๋ฉด์ด ์๋ฆฌ์ง ์๊ณ ํ ๊ธ์๋ ์ด์ ์ฒ๋ผ ๋ฉ์ด๋ฆฌ ๋์์ 8 ์์ชฝ์ ์จ๋ค | `design-contracts/src/component-recipes.ts`(`listRecipe`), `react/src/styles.css`(`.hjm-list`), `react-native/src/data-display.tsx`(List) |
|
|
96
|
-
| ๊ฐ๊ฒฉ | ํ ์ฌ์ด ๊ฐ๊ฒฉ์ ์๊ณ ๊ตฌ๋ถ์ 1px(`--hjm-color-border`)๋ง ๋ค์ด๊ฐ๋ค. ๊ตฌ๋ถ์ ์์น๋ ๋ชฉ๋ก ์ฝํ
์ธ ๊ฐ์ฅ์๋ฆฌ(=
|
|
96
|
+
| ๊ฐ๊ฒฉ | ํ ์ฌ์ด ๊ฐ๊ฒฉ์ ์๊ณ ๊ตฌ๋ถ์ 1px(`--hjm-color-border`)๋ง ๋ค์ด๊ฐ๋ค. ๊ตฌ๋ถ์ ์์น๋ ๋ชฉ๋ก ์ฝํ
์ธ ๊ฐ์ฅ์๋ฆฌ(= leading ์๋ ํ์ ๊ธ์ ์์) ๊ธฐ์ค์ด๊ณ , ๊ฐ ๊ตฌ๋ถ์ ์ ๋ฐ๋ก ์ ํ์ ์ํ๋ค(iOS ์
๊ตฌ๋ถ์ ๊ณผ ๊ฐ๋ค). `indented`๋ ์ ํ์ ๊ธ์ ์ด์์ ์์ํ๋ค: leading์ด ์์ผ๋ฉด `leadingInsetStart` 52(leading 40 + `spacing.sm` 12), ์์ผ๋ฉด `insetStart` 0. ๋์ ํ์ trailing ๋๊ณผ ๊ฐ์ ์ฝํ
์ธ ๊ฐ์ฅ์๋ฆฌ 0์ด๋ค. `full`์ ์ ํ๊ณผ ๋ฌด๊ดํ๊ฒ ์์ยท๋ ๋ชจ๋ โ8๋ก ํ ํ๋ฉด ํญ๊ณผ ๊ฐ๋ค(`listRecipe.separators`, ๋ ํ๋ซํผ, Web `--hjm-list-separator-*`). ์ ํ์ leading ์ฌ๋ถ๋ ListRow๊ฐ ์๋ฆฐ๋ค: Web์ ํ ๋ฃจํธ์ `data-leading`, Native๋ List ํญ๋ชฉ context. ๋ฉ์ด๋ฆฌ ๋ฐ๊นฅ ์ฌ๋ฐฑยท์น์
์ฌ์ด ๊ฐ๊ฒฉ์ ๊ฐ์ธ๋ Stack์ด ์ค๋ค(ํ์ด์ง ์ข์ฐ ์ฌ๋ฐฑ์ `layout.pagePadding`, ์น์
๊ฐ๊ฒฉ์ `layout.sectionGap` = `spacing.xl` 24) | `design-contracts/src/component-recipes.ts`(`listRecipe`), `design-contracts/src/foundations.ts`(`layout`), `react/src/styles.css`(`.hjm-list`), `react-native/src/data-display.tsx`(List) |
|
|
97
97
|
| ์์ยท์ ๋ ฌ | ๋ค์ ํ์ด์ง ์์ฒญ์ ๋ชฉ๋ก ๋ฐ๋ก ์๋์ [LoadMore](load-more.md)๋ฅผ ๋๋ค | โ |
|
|
98
98
|
| ๊ณ ์ ยท์คํฌ๋กค | List ์์ฒด๋ ์คํฌ๋กคํ์ง ์๋๋ค. ํ๋ฉด ์คํฌ๋กค ์์ ๋๋ค | `react-native/src/data-display.tsx`(List) |
|
|
99
99
|
| ์ข์ ํญยทํฐ ๊ธ์ | โ | โ |
|
|
@@ -101,7 +101,7 @@ Native `grouped` ํ๋ ์์ Provider์ `tokens.radius.lg`๋ฅผ ์ฝ๋๋ค. plain
|
|
|
101
101
|
```text
|
|
102
102
|
โโ List grouped (radius.lg 16, --hjm-color-bg) โโโโโโโโโโ
|
|
103
103
|
โ ListRow โ
|
|
104
|
-
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ indented ๊ตฌ๋ถ์ (
|
|
104
|
+
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ โ indented ๊ตฌ๋ถ์ (์ ํ์ leading์ด ์์ผ๋ฉด ๊ธ์ ์ด 52, ์์ผ๋ฉด 0)
|
|
105
105
|
โ ListRow โ
|
|
106
106
|
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
|
|
107
107
|
โ ListRow โ
|
|
@@ -197,7 +197,7 @@ import { CollectionRail } from "@hjmds/react/collection-rail";
|
|
|
197
197
|
| ํญ๋ชฉ | Web | Native |
|
|
198
198
|
| --- | --- | --- |
|
|
199
199
|
| ๊ตฌ์กฐ | `role="list"` + ์์๋ง๋ค `role="listitem"` | `accessibilityRole="list"` |
|
|
200
|
-
| ๊ตฌ๋ถ์ | CSS(`data-separator`) | ํ ์ฌ์ด 1px `View` |
|
|
200
|
+
| ๊ตฌ๋ถ์ | CSS(`data-separator`, ๋ค์ ํญ๋ชฉ `::before`, ์ ํ `data-leading`์ `:has()`๋ก ์ฝ์) | ํ ์ฌ์ด 1px `View`(์ ํ ListRow๊ฐ context๋ก leading ์ฌ๋ถ๋ฅผ ์๋ฆผ) |
|
|
201
201
|
| ๋ฐฐ์น | `layoutStyle`(+ `className`) | `layoutStyle`(`style`์ ์ ๊ฑฐ๋ ์์ฑ) |
|
|
202
202
|
|
|
203
203
|
2026-10-07 Utilverse ํญ๋ชฉ ์ญ์ ์ฑํ์ ์ํด `renderItemAction`์ ์ถ๊ฐํ๋ค. ์ฒดํฌ์ ์ญ์ ์ ์ด์ ยท๋๋ฆ์ ๋ถ๋ฆฌํ๊ณ ํฐ ๊ธ์ ๋ผ๋ฒจ ํญ์ ๋ณด์กดํ๋๋ก ํ๋์ ๋ค์ ์ค์ ๋๋ค. `renderCollection`์ `renderItem`์๋ ํฌํจ๋๋ค. ์ญ์ ์ ์ฅยท์คํจยท๋๋๋ฆฌ๊ธฐ๋ ์ ํ์ด ์ฒ๋ฆฌํ๋ค.
|
|
@@ -205,4 +205,5 @@ import { CollectionRail } from "@hjmds/react/collection-rail";
|
|
|
205
205
|
ํญ๋ชฉ ์ญ์ ๋ค์๋ ์ ํ์ด ๋ค์ ํญ๋ชฉ์ ๋
๋ฆฝ ํ๋(์์ผ๋ฉด ์ด์ ํญ๋ชฉ, ๋ชฉ๋ก์ด ๋น๋ฉด ํ์ ํ๋)์ผ๋ก ์ด์ ์ ๋ณต๊ตฌํ๋ค. Web Showcase๋ ref์ ์ปค๋ฐ ํ focus ์์๋ฅผ ์ ๊ณตํ๋ค. Native ์ ๊ทผ์ฑ ์ด์ ๊ฒ์ฆ์ ์์ง ๋จ์ ์๋ค.
|
|
206
206
|
|
|
207
207
|
## ๊ทผ๊ฑฐ
|
|
208
|
+
- ๊ตฌ๋ถ์ ์์์ ์ ํ์ ๊ธ์ ์ด: 2026-10-17 ์ฌ์ฉ์ ๋ณด๊ณ (leading ์๋ ํ์์ ๊ตฌ๋ถ์ ์ด ์ค๊ฐ์์ ์๋ฆฐ ๊ฒ์ฒ๋ผ ๋ณด์). ๊ณ ์ ์์ 52๊ฐ leading ์๋ ํ์๋ ์ ์ฉ๋ผ Web 402 ๋์๋ณด๋ ๊ธฐ๋ก ๋ชฉ๋ก์์ ํ ๊ธ์ 16 / ๊ตฌ๋ถ์ 68~394(์ฝํ
์ธ ๋ 386๋ณด๋ค 8 ๋ ๋๊ฐ)์๋ค. ์ ํ์ leading ์ฌ๋ถ๋ก ์์์ ์ ํ๊ณ ๋์ ์ฝํ
์ธ ๊ฐ์ฅ์๋ฆฌ๋ก ๋ง์ถ ๋ค ๊ธ์ 16 / ๊ตฌ๋ถ์ 16~386, leading ์๋ ๋ชฉ๋ก์ ๊ธ์ 85 / ๊ตฌ๋ถ์ 85~369(์ฝํ
์ธ ๋ 369), RTL๋ ๋์นญ์ผ๋ก ์ธก์ ๋๋ค.
|
|
208
209
|
- ๊ตฌ๋ถ์ ยทgrouped ์ฌ๋ฐฑ: 2026-10-17 ์ฌ์ฉ์ ๊ฒฐ์ (ํ ๊ธ์๋ ์ฌ๋ฐฑ ์ 16, ํ๋ฉด๋ง ๋ฐ๊นฅ์ผ๋ก 8). ํ ์ฝํ
์ธ ์์๊ฐ ๋ชฉ๋ก ์ฝํ
์ธ ๊ฐ์ฅ์๋ฆฌ๋ก ์ฎ๊ฒจ์ ธ `indented` ์์์ด 60 โ 52๊ฐ ๋์ด๋ ํ๋ฉด์์ ๋ณด์ด๋ ์์น(๊ธ์ ์์)๋ ๊ฐ๋ค. ๊ธฐ๋ณธ ํ๋ฉด์์ ํ ๊ธ์๊ฐ 24, ์น์
์ ๋ชฉ์ด 16์ด๋ ์ค์ธก์ [ListRow ๊ทผ๊ฑฐ](list-row.md#๊ทผ๊ฑฐ)์ ์๋ค. ์ด์ plain ๋ชฉ๋ก์ `overflow: hidden`์ grouped ๋ชจ์๋ฆฌ๋ง์ ์ํ ๊ฒ์ด๋ผ grouped๋ก ์ฎ๊ฒผ๋ค.
|
|
@@ -95,4 +95,8 @@ 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`)์ผ๋ก ์ ์ฝ์
|
|
98
|
+
| ์ ๋ชฉ ๊ตต๊ธฐ ์กฐ์ | `Text emphasis` | ๋ ๋๋ฌ ๋น๊ณต๊ฐ ์
๋ ฅ(`hjmTitleEmphasis`)์ผ๋ก ์ ์ฝ์ `strong` 500(์ ๋ชฉ ๊ตต๊ธฐ)ยท์ฝ์ `regular` 400. ์ ๊ฑฐ๋ `ListRow.titleStyle`์ ์ฌ์ฉํ์ง ์๋๋ค. `NotificationItemProps`์๋ `titleStyle`์ด ์๋ค(1.13.0 ๋ณ๊ฒฝ) |
|
|
99
|
+
|
|
100
|
+
## ๊ทผ๊ฑฐ
|
|
101
|
+
|
|
102
|
+
2026-10-17 ์ฌ์ฉ์ ๊ฒฐ์ ("๊ตต๊ธฐ ์ข๋ ์ค์ฌ"): ๋ชจ๋ ๊ธ์ ๊ตต๊ธฐ๋ฅผ ํ ๋จ๊ณ ๋ฎ์ท๋ค. ํฐ ์ซ์ยท์ ํ ์ํ 600(ํฐ ์ ๋ชฉ ๋จ๊ณ๋ ๊ฐ์ ๋ ํ์ง), ์ ๋ชฉยท๊ฐ์กฐ 500, label 500, ๋ณธ๋ฌธ 400์ด๋ฉฐ ์ ๋ณธ์ [ํ์ดํฌ๊ทธ๋ํผ](../tokens/typography.md)๋ค.
|
|
@@ -95,7 +95,7 @@ import { PhotoSourceSheet } from "@hjmds/react-native/screen-flows";
|
|
|
95
95
|
| --- | --- | --- |
|
|
96
96
|
| ํฌ๊ธฐ | Sheet ๊ธฐ๋ณธ `placement="bottom"`ยท`size="auto"`(๋ด์ฉ ๋์ด, ํ๋ฉด ๋์ด 0.9 ์ํ), Web ์ต๋ ํญ 640; ์ ํ ๋ฒํผ์ `tone="secondary"` `Button` ๋ ๊ฐ | `sheetRecipe`, `screen-flows.tsx` |
|
|
97
97
|
| ๊ฐ๊ฒฉ | ์ํธ ์ ์ฌ๋ฐฑ์ Sheet ์์ (๋ ํ๋ซํผ ์ข์ฐ `spacing.lg` 20 ยท ์์๋ `spacing.sm` 12 + ํ๋จ safe area); ๋ ๋ฒํผ ์ฌ์ด `spacing.xs` 8(์ธ๋ก๋ก ์์ ๋ฒํผ, `actionGroupRecipe.stackedGap`); ๋ฐ๊นฅ์ padding์ ๋ํ์ง ์๋๋ค | Web `.hjm-sheet__body`, Native `sheetRecipe.content`, `Stack gap="xs"` |
|
|
98
|
-
| ์์ยท์ ๋ ฌ | Sheet
|
|
98
|
+
| ์์ยท์ ๋ ฌ | Sheet ์์ก์ด โ ์จ๋ฒ โ ์ดฌ์(`cameraAvailable`์ผ ๋๋ง). `labels.title`์ ๋ณด์ด์ง ์๋ ์ํธ ์ด๋ฆ(2026-10-17 ์ฌ์ฉ์ ๊ฒฐ์ : ์ํธ๋ ๋ณด์ด๋ ์ ๋ชฉ ์์ด `title`์ ์ ๊ทผ์ฑ ์ด๋ฆ์ผ๋ก๋ง ์ด๋ค) | Web `screen-flows.tsx` 59โ60ํ, Native 50โ51ํ |
|
|
99
99
|
| ๊ณ ์ ยท์คํฌ๋กค | ํ๋ฉด ํ๋จ์ ๋จ๋ ์ค๋ฒ๋ ์ด(๋ฐฐ๊ฒฝ ๋ง) โ ์ ํ ๋ค picker ํธ์ถ ์์ ์ ํ๋ซํผ ์ฐจ์ด ์ฐธ๊ณ | `Sheet` |
|
|
100
100
|
| ์ข์ ํญยทํฐ ๊ธ์ | ๋ฒํผ ๋ฌธ๊ตฌ๋ ์ค๋ฐ๊ฟ๋๊ณ Sheet ๋์ด๊ฐ ๋์ด๋๋ค(0.9 ์ํ์ ๋์ผ๋ฉด ๋ณธ๋ฌธ ์คํฌ๋กค); ์นด๋ฉ๋ผ๊ฐ ์์ผ๋ฉด ๋ฒํผ ํ๋๋ง ๋จ๋๋ค | `sheetRecipe.content.maxHeightRatio` |
|
|
101
101
|
|
|
@@ -85,6 +85,7 @@ import { ScreenLayout } from "@hjmds/react-native/screens";
|
|
|
85
85
|
| `contentInset` | `"default"` ยท `"none"` ยท `"body-edge"` | `"default"` | `none`์ ํค๋ยทnoticeยท๋ณธ๋ฌธยทfooter padding์ 0์ผ๋ก(Native๋ footer ์ ํ
๋๋ฆฌ๋ ๋บ๋ค). host๊ฐ ๋ชจ๋ ์ฌ๋ฐฑ์ ์ด๋ฏธ ์ค ๋ ์ด๋ค. `body-edge`๋ ํค๋ยทnoticeยทfooter ์ฌ๋ฐฑ(16)๊ณผ footer ํ
๋๋ฆฌ๋ฅผ ์ ์งํ๊ณ **๋ณธ๋ฌธ ์ข์ฐ padding๋ง 0**์ผ๋ก ํ๋ค. ์๊ธฐ ์ข์ฐ ์ฌ๋ฐฑ์ ๊ฐ์ง ์ ์ฒด ํญ ๋ชฉ๋ก ํ(ConversationRowยทNotificationRow ๋ฑ ํ padding 16)์ ๋ณธ๋ฌธ์ ๋ฐ๋ก ๋ ๋ ์ด๋ค(๋ฏธ๊ฒ์). ListRowยทNotificationItem์ `default`์ ๋๋ค. ๊ฐ ๋ชฉ๋ก์ ๊ณ์ฝ `ScreenContentInset`ยท`screenContentInsets` |
|
|
86
86
|
| `presentation` | `"dashboard"` ยท `"editorial"` ยท `"landscape"` | ๊ฐ์ฅ ๊ฐ๊น์ด profile.screens.overview / ์์ผ๋ฉด ๊ธฐ์กด ๊ณจ๊ฒฉ | [๋์์ธ ํ๋กํ](../../design-profile.md)์ ์ ๊ณต ๋ฒ์๋ฅผ ๋ฐ๋ฅธ๋ค. ๋ช
์๊ฐ์ด ํ๋กํ์ ์ด๊ธด๋ค. ํค๋ ๋ฐฐ์นยท์ฝ๊ธฐ ํญ๋ง ๋ฐ๊พธ๊ณ ์ํยท์
๋ ฅยทํ๋ ์ฌ๋กฏ์ ์ ์งํ๋ค |
|
|
87
87
|
| `as` (Web) | `"main"` ยท `"section"` | `"main"` | ์ ํ ์
ธ์ ์ด๋ฏธ `<main>`์ด ์์ผ๋ฉด `section` |
|
|
88
|
+
| `safeAreaBottom` (Native) | 0 ์ด์์ ์ ํ์ | `0`(๋ฏธ๊ฒ์) | ํ๋ฉด์ด ๋ฟ๋ ์ฐฝ ์๋ ๊ฐ์ฅ์๋ฆฌ์ safe area(`useSafeAreaInsets().bottom`, ํญ๋ฐ ์ยท์ด๋ฏธ ์๋๋ฅผ ๋ค์ธ host ์์ด๋ฉด 0). ๋ง์ง๋ง ์์ญ(footer, ์์ผ๋ฉด ๋ณธ๋ฌธ)์ด ์๋ ์ฌ๋ฐฑ์ `max(16, inset)`์ผ๋ก ํ ๋ฒ๋ง ์ค๋ค. ๋๊ธธ ๋๋ host์ ์๋ SafeAreaView edge๋ฅผ ๋นผ๊ณ , ๋์ ๊ฐ์ด ์ฐ์ง ์๋๋ค. ์์ยท๋ฌดํ๋๋ `RangeError` |
|
|
88
89
|
| `layoutStyle` | `HjmCompositionStyleProp` | ์์ | ํ๋ฉด ๋ฃจํธ ๋ฐฐ์น ์ ์ฉ(์: ๋ถํ ํ๋ฉด์ `flex`ยท`width`). ScreenLayout ์์ ๋ง๋ ํ๋ฉด์ ๋ชจ๋ ์ด prop์ ๋ฃจํธ๊น์ง ๋๊ธด๋ค |
|
|
89
90
|
| `className` (Web) | `string` | ์์ | ์๋ณยท๋ฐฐ์น ๋ณด์กฐ. ์ยท์ฌ๋ฐฑ์ ๋ฎ์ง ์๋๋ค |
|
|
90
91
|
| `testID` ยท `scrollRef` ยท `scrollProps` (Native) | `string` ยท `Ref<ScrollView>` ยท `refreshControl`ยท`keyboardDismissMode`ยท์คํฌ๋กค ๋ง๋ ํ์ยท`onScroll`ยท`onScrollBeginDrag`ยท`onScrollEndDrag`ยท`scrollEventThrottle`ยท`alwaysBounceVertical`ยท`automaticallyAdjustKeyboardInsets` | ์์ | ScrollView๊ฐ ์์ ๋(`scroll="screen"` ๋๋ ์ํ ๊ต์ฒด ์ค)๋ง `scrollRef`ยท`scrollProps`๊ฐ ์ฐ๊ฒฐ๋๋ค |
|
|
@@ -97,8 +98,8 @@ import { ScreenLayout } from "@hjmds/react-native/screens";
|
|
|
97
98
|
| ๊ฐ๊ฒฉ | ๋ฐ๊นฅ padding `screenPatternRecipe.padding`(`spacing.md` 16)์ ํค๋ ์ฌ๋ฐฉยทnotice ์ข์ฐยท๋ณธ๋ฌธ ์ฌ๋ฐฉยทfooter ์ฌ๋ฐฉ์ ์ค๋ค(`contentInset="none"`์ด๋ฉด 0, `"body-edge"`๋ฉด ๋ณธ๋ฌธ ์ข์ฐ๋ง 0); ํค๋ ์ `exit`ยท์ ๋ชฉยท`actions` ๊ฐ๊ฒฉ `itemGap`(`spacing.sm`) 12(๋ ํ๋ซํผ, `contentInset="none"`์ด์ด๋ ์ ์ง); ์ํ ์๋ด๋ ์์๋ `sectionGap`(`spacing.xl`) 24, ์๋ดโ`stateAction` `stateGap`(`spacing.md`) 16 | Web `src/screens.tsx`(`--hjm-screen-item-gap`ยท`--hjm-screen-state-gap`)ยท`.hjm-screen__*`, Native `ScreenLayout` |
|
|
98
99
|
| ์ ๋ชฉ | ๊ธฐ๋ณธ ๊ฐ์ด๋ฐ `Heading` `screenHeaderRecipe.centeredTitleLevel`(level5), `headerAlignment="start"`๋ฉด `titleLevel`(level3). ์ถ๊ฐ ๊ธฐ๋ฅ ๋ฒํผ(`actions`)์ ๋(์ค๋ฅธ์ชฝ) ์, ๋๊ฐ๊ธฐ(`exit`)๋ ์์(์ผ์ชฝ) ์. ํค๋ ๋์ด๋ ๋ ํ๋ซํผ ๋ชจ๋ `screenHeaderRecipe`์ ๊ณ ์ ๋ | `screenHeaderRecipe` |
|
|
99
100
|
| ์์ยท์ ๋ ฌ | ํค๋(`exit` โ ์ ๋ชฉยท์ค๋ช
โ `actions`) โ notice โ ๋ณธ๋ฌธ โ footer; ์ํ ์๋ด๋ ๋ณธ๋ฌธ ์ธ๋ก ๊ฐ์ด๋ฐ `exit`๋ HJM์ด `edge="start"`๋ก ๊ทธ๋ ค ์์ด์ฝ ์นธ์ด ํค๋ ์ฌ๋ฐฑ ์ 16์ ์จ๋ค(WebยทNative 31 โ 16, ๊ฐ์ด๋ฐ ํค๋์ ๊ฐ์ ํญ ์์ชฝ ์ดยท์ ๋ชฉ ์ค์์ ๊ทธ๋๋ก). ๋ `actions`์ ๋ง์ง๋ง ghost IconButton์ ์ ํ์ด `edge="end"`๋ฅผ ์ค๋ค(2026-10-17 ์ค์ธก ๊ฐ์ฌ, [IconButton `edge`](icon-button.md#๋ฐฐ์น)) | ๋ ๋ ์์ |
|
|
100
|
-
| ๊ณ ์ ยท์คํฌ๋กค | ํค๋ยทnoticeยทfooter ๊ณ ์ , `scroll="screen"`์ ๋ณธ๋ฌธ์ด ์คํฌ๋กค, `"content"`๋ ์์์ด ์คํฌ๋กค; footer ์ ํ
๋๋ฆฌ 1, Web์
|
|
101
|
-
| ์ข์ ํญยทํฐ ๊ธ์ | ์ ๋ชฉ ์ด ์ต์ ํญ `headerMinWidth` 120 ร ๊ธ์ ๋ฐฐ์จ, ๋ชจ์๋ผ๋ฉด `actions`๊ฐ ๋ค์ ์ค๋ก ๋ด๋ ค๊ฐ๋ค; ์ ๋ชฉ์ ์ค๋ฐ๊ฟ(`overflow-wrap: anywhere`)๋๊ณ ์๋ฅด์ง ์๋๋ค; Native safe areaยทํญ๋ฐ inset์ host | `screenPatternRecipe.headerMinWidth`, Web `.hjm-screen__heading` |
|
|
101
|
+
| ๊ณ ์ ยท์คํฌ๋กค | ํค๋ยทnoticeยทfooter ๊ณ ์ , `scroll="screen"`์ ๋ณธ๋ฌธ์ด ์คํฌ๋กค, `"content"`๋ ์์์ด ์คํฌ๋กค; footer ์ ํ
๋๋ฆฌ 1. ๋ง์ง๋ง ์์ญ(footer, ์์ผ๋ฉด ๋ณธ๋ฌธ)์ ์๋ ์ฌ๋ฐฑ์ `max(16, ํ๋จ inset)`์ด๋ค โ Web์ `env(safe-area-inset-bottom)`, Native๋ `safeAreaBottom`. 16 + inset์ผ๋ก ๋ํ์ง ์์ผ๋ฉฐ, ํค๋ณด๋๊ฐ ์ด๋ ค ์์ผ๋ฉด ํค๋ณด๋๊ฐ ํ ์ธ๋์ผ์ดํฐ๋ฅผ ๋ฎ์ผ๋ฏ๋ก 16๋ง ๋๋ค | Web `data-scroll`ยท`.hjm-screen__footer`, Native `ScrollView` |
|
|
102
|
+
| ์ข์ ํญยทํฐ ๊ธ์ | ์ ๋ชฉ ์ด ์ต์ ํญ `headerMinWidth` 120 ร ๊ธ์ ๋ฐฐ์จ, ๋ชจ์๋ผ๋ฉด `actions`๊ฐ ๋ค์ ์ค๋ก ๋ด๋ ค๊ฐ๋ค; ์ ๋ชฉ์ ์ค๋ฐ๊ฟ(`overflow-wrap: anywhere`)๋๊ณ ์๋ฅด์ง ์๋๋ค; Native ์ยท์ safe areaยทํญ๋ฐ inset์ host, ์๋ inset์ `safeAreaBottom` | `screenPatternRecipe.headerMinWidth`, Web `.hjm-screen__heading` |
|
|
102
103
|
|
|
103
104
|
## ๊ผญ ์งํฌ ๊ฒ
|
|
104
105
|
|
|
@@ -109,11 +110,12 @@ import { ScreenLayout } from "@hjmds/react-native/screens";
|
|
|
109
110
|
|
|
110
111
|
- Web์ ํ๋ฉด ์คํฌ๋กค ๋ณธ๋ฌธ์ Tab์ผ๋ก ์ง์
ํ ์ ์๋ค. `scroll="content"`์ ์ ์ ๋ณธ๋ฌธ์ ์์์ด ํค๋ณด๋ ์คํฌ๋กค์ ์์ ํ์ง๋ง, ์ค๋ฅยท๋น ์ํ ๋ฑ ๋์ฒด ์๋ด๋ ํ๋ฉด ์คํฌ๋กค๋ก ๋ฐ๋๋ฉฐ Tab ์ง์
๋ ํจ๊ป ๋ณต์๋๋ค.
|
|
111
112
|
- Web์์ ๋ณธ๋ฌธ์ ์ด์ ์ ๊ฐ์ง ์
๋ ฅยท์ฌ์๋ ๋ฒํผ์ด ์ํ ์ ํ์ผ๋ก ์ ๊ฑฐ๋๋ฉด ๊ฐ์ ๋ณธ๋ฌธ์ผ๋ก ์ด์ ์ ๋ณต๊ตฌํ๋ค. `scroll="content"`์ ๋ณธ๋ฌธ์ ์ด ๋ณต๊ตฌ๋ง์ ์ํ `tabIndex=-1`์ ๊ฐ์ง๋ฉฐ ์ผ๋ฐ Tab ์์์๋ ์ถ๊ฐ๋์ง ์๋๋ค. ์ฌ์ฉ์๊ฐ ๋ค๋ฅธ ์ปจํธ๋กค์ด๋ ๋ฐ๊นฅ ์์ญ์ผ๋ก ์ด์ ์ ์ฎ๊ธด ๊ฒฝ์ฐ์๋ ์ด๋์ํค์ง ์๋๋ค. 2026-10-13 ์ฌ์๋ยท๊ถํ ์ ํ ์ ํ์์ ์ด์ ์ด body๋ก ์ ์ค๋ ๊ฒฝ๋ก๋ฅผ ์์ ํ๋ค.
|
|
113
|
+
- **ํ๋ฉด ์ฌ๋ฐฑ์ ScreenLayout์ด ์์ ํ๋ค(๊ธฐ๋ณธ `contentInset`).** ํ๋ฉด์ ๋ฐ๊นฅ `Container gutter`๋ก ๊ฐ์ธ๊ณ `contentInset="none"`์ ์ฃผ๋ ๊ตฌ์ฑ์ ์ง์ํ์ง ์๋๋ค. ํ์ ํ๋ฉด bleed, footerยทBottomCTA ๋ฐ, ๋ ์ปจํธ๋กค์ `edge`๋ ๋ชจ๋ ScreenLayout์ด ์ฌ๋ฐฑ์ ๊ฐ์ง๋ค๋ ์ ์ ๋ก ๋ง์ถฐ์ ธ ์์ด, ๊ทธ ๊ตฌ์ฑ์์๋ ํ ํ๋ฉด์ด ๋ณธ๋ฌธ ๋์์ ์๋ฆฌ๊ณ footer๊ฐ ์ฌ๋ฐฑ ์์ ๋ ์๋ ์์๊ฐ ๋๋ค. `none`์ host๊ฐ ๋ชจ๋ inset์ ์์ ํ๋ ๊ธฐ์กด ์๋ฏธ ๊ทธ๋๋ก๋ค(์ ๋์ ์์).
|
|
112
114
|
- ๊ฐ์ํ ๋ชฉ๋ก(FlatList, VirtualList)์ ๋ฃ์ผ๋ฉด `scroll="content"`๋ก ๋๋ค. ์คํฌ๋กค์ ์ด์ค์ผ๋ก ์ค์ฒฉํ์ง ์๋๋ค.
|
|
113
115
|
- ์๋ก๊ณ ์นจ ์คํจยท์ ์ฅ ์ค๋ฅ๋ `state`๋ฅผ ๋ฐ๊พธ์ง ๋ง๊ณ `ready` + `notice`๋ก ์๋ฆฐ๋ค. `loading`์ผ๋ก ๋ฐ๊พธ๋ฉด ๋ณธ๋ฌธ์ด
|
|
114
116
|
unmount๋์ด ์
๋ ฅ ์ด์์ด ์ฌ๋ผ์ง๋ค.
|
|
115
117
|
- `state.title`ยท๋ฌธ๊ตฌ๋ i18n ํค๋ก ๋ฃ๋๋ค. ready ์ธ ์ํ์ ๋น `title`์ `TypeError`๋ค.
|
|
116
|
-
- Web host๋ ์ค์ ๋จ์ ๋์ด(`height:100%` ๋ฑ)๋ฅผ, Native host๋ safe area
|
|
118
|
+
- Web host๋ ์ค์ ๋จ์ ๋์ด(`height:100%` ๋ฑ)๋ฅผ, Native host๋ ์ยท์ safe area์ ํญ๋ฐ inset์ ๋จผ์ ์ฒ๋ฆฌํ๋ค. ์๋ ํ ์ธ๋์ผ์ดํฐ๋ host๊ฐ SafeAreaView๋ก ๋ค์ด์ง ๋ง๊ณ `safeAreaBottom`์ผ๋ก ๋๊ธด๋ค(๋ค์ธ ๋ค footer 16์ ๋ํ๋ฉด ๋ฒํผ ์๋๊ฐ 50์ด ๋๋ค).
|
|
117
119
|
HJM์ ๊ธฐ์ข
๋ณ ๋์ด๋ฅผ ์ถ์ธกํ์ง ์๋๋ค.
|
|
118
120
|
- ๋ฐฐ์น๋ WebยทNative ๋ชจ๋ `layoutStyle`๋ก ํ๋ค(Web์ `className`๋ ์๋ค). ์ยท์ฌ๋ฐฑ์ ๋ฎ์ง ์๋๋ค.
|
|
119
121
|
|
|
@@ -141,4 +143,6 @@ dashboard๋ ๊ฐ๋ก ํค๋/1200 ๋ชฉ๋ก ํญ, editorial์ ์ธ๋ก ํค๋/720 ์ฝ
|
|
|
141
143
|
|
|
142
144
|
## ๊ทผ๊ฑฐ
|
|
143
145
|
|
|
146
|
+
- ํ๋จ ์ฌ๋ฐฑ `max(16, inset)`(Native `safeAreaBottom`): 2026-10-17 ์ฌ์ฉ์ ๋ณด๊ณ "์ ์ฒด์ ์ผ๋ก ๋ฒํผ ์๋ ์ฌ๋ฐฑ์ด ๋ง์". Native Storybook์ ์ฌ์ง ์ ํ๊ณผ ์
๋ก๋ ํ๋ฉด์์ ๋ฒํผ ์๋๊ฐ ์ฝ 33pt์๋ค. ์์ธ์ ๋์ด์๋ค. ํ๋ฉด ์คํ ๋ฆฌ์ route host๊ฐ ๊ณ ์ ๋์ด 720์ด๋ผ iPhone 17 Pro ์คํ ๋ฆฌ ์์ญ 737๋ณด๋ค 17 ์งง์๊ณ (footer 16 + ๋น ์นธ 17), ์ปดํฌ๋ํธ๋ Native footer๊ฐ safe area๋ฅผ ๋ค๋ฃจ์ง ์์ host์ ์๋ inset ์์ 16์, footer ์ BottomCTA์ `safeAreaBottom`๋ 16 ์์ ๋ํ๋ค(16 + 34 = 50). Web footer๋ ์ด๋ฏธ `max(16, env())`์์ง๋ง footer ์ BottomCTA์ `safeAreaBottom`์ ๊ทธ ์์ ๋ํ๋ค. ํ์ค์ "๋ง์ง๋ง ์ปจํธ๋กค ์๋ = footer ์ ์ฌ๋ฐฑ 16, ํ ์ธ๋์ผ์ดํฐ ๊ธฐ๊ธฐ์์๋ max(16, inset)"์ผ๋ก ์ ํ๊ณ footer๊ฐ ํ ๋ฒ๋ง ์์ ํ๊ฒ ํ๋ค.
|
|
147
|
+
- ํ๋ฉด ์ฌ๋ฐฑ์ ScreenLayout ์์ , ๋ฐ๊นฅ ์ฌ๋ฐฑ + `none` ๋ฏธ์ง์: 2026-10-17 ๋ฐ๊นฅ ์ฌ๋ฐฑ ํธ์คํธ ์์ ์ฌ์ฉ์ ๊ฒํ . utilverse์(`Container gutter="regular"` 20 + `contentInset="none"`)์ HJM์์ ์ง์ํ๋ ค๊ณ ๋ณธ๋ฌธ ํ์ฅยทfooter ๋ฐ ์์ ๋ฅผ ๋ถ์ธ ์์ ๊ฐ ์ด์ํ๋ค๋ ํ๋จ์ผ๋ก ์ง์์ ์ ์๋ค(2026-10-15 ๊ณตํต ๊ตฌ์กฐ๋ HJM ์์ ์์น). ์ธก์ ์ ๊ทธ ๊ตฌ์ฑ์์๋ Web 402ยท1280์์ ํ ํ๋ฉด์ด ์์ชฝ 8 ์๋ฆฌ๊ณ ๋ณธ๋ฌธ์ด ์์ผ๋ก 8 ์คํฌ๋กค๋๋ฉฐ, Native 3x์์ ์ ํ ํ
๋๋ฆฌ ์ ์ ์ด ๊ทธ๋ ค์ง์ง ์์๋ค. ์ ํ์ ๋ฐ๊นฅ ์ฌ๋ฐฑ์ ๊ฑท๊ณ ๊ธฐ๋ณธ inset์ ์ด๋ค.
|
|
144
148
|
- `contentInset="body-edge"`: 2026-10-17 ์ฌ์ฉ์ ๊ฒฐ์ . ํ๋ฉด ๊ฒํ S5#9์์ ๋ํ ๋ชฉ๋ก ์๋ฐํ๊ฐ ํ๋ฉด ๋์์ ์ฝ 32pt ์์ชฝ์์ ์์ํ๋ค. ๋ณธ๋ฌธ padding 16๊ณผ ConversationRow ์์ฒด padding 16์ด ๊ฒน์ณค๋ค(์ธ์คํ๊ทธ๋จ DM์ ์ฝ 16). ์ฑ ์ฝ 45๊ณณ์ด "host๊ฐ ๋ชจ๋ ์ฌ๋ฐฑ์ ์์ ํ๋ค"๋ ๋ป์ผ๋ก `none`์ ์ฐ๊ณ ์์ด `none`์ ์๋ฏธ๋ฅผ ๋ฐ๊ฟ ์ ์์์ผ๋ฏ๋ก ๊ฐ์ ์๋ก ์ถ๊ฐํ๋ค. ChatScreen์ 10 ํ์๋ผ์ธ ์ฌ๋ฐฑ์ `default`์ผ ๋๋ง ๊ณตํต ์ฌ๋ฐฑ์ ๋์ ํ๋ค.
|
|
@@ -157,7 +157,7 @@ import { SearchScreen } from "@hjmds/react-native/screen-flows";
|
|
|
157
157
|
| `resultSummary.countVisibility` | `visible` ยท `hidden` | `visible` | `hidden`์ ์๊ฐ์ ๊ฐ์ยท๊ฐ์ Skeleton๋ง ์จ๊ธฐ๋ฉฐ ์ ๋ ฌยท๋ก๋ฉ ํยท๋น ์ํยท์ ๊ทผ์ฑ ๊ฐ์ ์๋ฆผ์ ์ ์งํ๋ค. 2026-10-14 ์ผ์์ ๊ฒ์ ๊ฒฐ๊ณผ์์ ๊ฐ์ ์๋ ๋ชฉ๋ก์ ์์ฒญํด ์ถ๊ฐํ ์ ํํ ์ถ(๋ฏธ๊ฒ์)์ด๋ค |
|
|
158
158
|
| `resultSummary.sort` | `{ label, triggerLabel, value, options: { id, label }[], onChange(id), icon? }` (Native๋ `dismissLabel` ์ถ๊ฐ) | ์์ | ๊ฒฐ๊ณผ ๋จธ๋ฆฌ ๋ Menu(single). ๋ฐ๊พธ๋ฉด ๋ณธ๋ฌธ์ ๋งจ ์๋ก |
|
|
159
159
|
| `appliedFilters` | `{ items: { key, label }[], removeLabel(label), onRemove(key), clearAllLabel, onClearAll(), removeIcon? }` | ์์ | ๊ฒฐ๊ณผ ๋จธ๋ฆฌ ์๋ ร ์นฉ + `๋ชจ๋ ํด์ `. ๊ฐ์๋ trigger ์ด๋ฆ๊ณผ 0๊ฑด ์์ธ ํ์ ์๋ ์ด๋ค |
|
|
160
|
-
| `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
|
+
| `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. `title`์ ํํฐ ์ํธ์ ๋ณด์ด์ง ์๋ ์ ๊ทผ์ฑ ์ด๋ฆ์ด๋ค(2026-10-17 ์ฌ์ฉ์ ๊ฒฐ์ : ์ํธ ์ ๋ชฉ ์ค ์์). ๊ฐ๋ฆผ๋ง์ ๋๋ฅด๋ฉด ๋ซํ๊ณ ์ด์์ ๋ฒ๋ฆฐ๋ค |
|
|
161
161
|
| `filtersOverflow` | `wrap` ยท `scroll` | `wrap` | `scroll`์ด๋ฉด `filters`๋ฅผ ํ ์ค ๊ฐ๋ก ์คํฌ๋กค ์์ญ์ ๋ฃ๊ณ ํ๋ฉด ์ข์ฐ ์ฌ๋ฐฑ(`spacing.md` 16, `contentInset="none"`์ด๋ฉด 0)์ `hostGutter`๋ฅผ ๋ํ ๋งํผ ๊ฐ์ฅ์๋ฆฌ๊น์ง ๋ํ๋ค. ์ฒซ ์นฉ์ ๊ฒ์ ์
๋ ฅ๊ณผ ๊ฐ์ ์์์ ์ ๋์ธ๋ค |
|
|
162
162
|
| `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` ์ค๋ง ์ด ๊ฐ์ ์ด๋ค |
|
|
163
163
|
| `recentSearches` | `ReactNode` | ์์ | `query`๊ฐ ๊ณต๋ฐฑ์ผ ๋๋ง ๋ณธ๋ฌธ ๋งจ ์์ ๋ณด์ธ๋ค |
|
|
@@ -78,7 +78,7 @@ import { Section } from "@hjmds/react-native/primitives";
|
|
|
78
78
|
| ํญ๋ชฉ | ๊ฐ | ๊ทผ๊ฑฐ |
|
|
79
79
|
| --- | --- | --- |
|
|
80
80
|
| ํฌ๊ธฐ | ์์ฒด ๋ฐฐ๊ฒฝยทํ
๋๋ฆฌยท์ฌ๋ฐฑ์ด ์๋ค. ํญ์ ๋ถ๋ชจ๋ฅผ ๋ฐ๋ฅธ๋ค | `.hjm-section` |
|
|
81
|
-
| ๊ธ์ | ์ ๋ชฉ `title` 18/26
|
|
81
|
+
| ๊ธ์ | ์ ๋ชฉ `title` 18/26 500(์ ๋ชฉ ๊ตต๊ธฐ), ์ค๋ช
`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
|
| ๊ณ ์ ยท์คํฌ๋กค | ๊ณ ์ ๋์ง ์๋๋ค. ํ๋ฉด ๋ณธ๋ฌธ ์คํฌ๋กค ์์ ๋๋ค | โ |
|
|
@@ -109,3 +109,7 @@ import { Section } from "@hjmds/react-native/primitives";
|
|
|
109
109
|
| heading ์์ค | `headingLevel` | ์์(header role ๊ณ ์ ) |
|
|
110
110
|
| ๋ฃจํธ | `<section>` | `View` |
|
|
111
111
|
| ๋ฐฐ์น | `className`, `layoutStyle`(HTML `style`๋ ๋ฐ์) | `layoutStyle`, slot `*Style`(`style`์ ์ ๊ฑฐ๋ ์์ฑ) |
|
|
112
|
+
|
|
113
|
+
## ๊ทผ๊ฑฐ
|
|
114
|
+
|
|
115
|
+
2026-10-17 ์ฌ์ฉ์ ๊ฒฐ์ ("๊ตต๊ธฐ ์ข๋ ์ค์ฌ"): ๋ชจ๋ ๊ธ์ ๊ตต๊ธฐ๋ฅผ ํ ๋จ๊ณ ๋ฎ์ท๋ค. ํฐ ์ซ์ยท์ ํ ์ํ 600(ํฐ ์ ๋ชฉ ๋จ๊ณ๋ ๊ฐ์ ๋ ํ์ง), ์ ๋ชฉยท๊ฐ์กฐ 500, label 500, ๋ณธ๋ฌธ 400์ด๋ฉฐ ์ ๋ณธ์ [ํ์ดํฌ๊ทธ๋ํผ](../tokens/typography.md)๋ค.
|
|
@@ -80,7 +80,7 @@ import { SegmentedControl } from "@hjmds/react-native/inputs";
|
|
|
80
80
|
|
|
81
81
|
| ํญ๋ชฉ | ๊ฐ | ๊ทผ๊ฑฐ |
|
|
82
82
|
| --- | --- | --- |
|
|
83
|
-
| ํฌ๊ธฐ |
|
|
83
|
+
| ํฌ๊ธฐ | ๋ฐ๊นฅ ๋์ด(ํธ๋ ํ
๋๋ฆฌยท์์ชฝ ์ฌ๋ฐฑ ํฌํจ) `height`๋ ๊ฐ์ ํฌ๊ธฐ์ ButtonยทIconButtonยทChip๊ณผ ๊ฐ๋ค: `medium` 44 ยท `small` 36. ํญ๋ชฉ ์ต์ ๋์ด๋ ๊ทธ๋ณด๋ค ํธ๋ ์์ชฝ ์ฌ๋ฐฑ 4์ ํ
๋๋ฆฌ 1์ ์์๋๋ก ๋บ `medium` 34 ยท `small` 26์ด๊ณ , ์์๋๋ก๋ง ๋ํ ํฐ์น ์์ญ(`hitSlop` 5 ยท 9, Web `::after`)์ผ๋ก 44๋ฅผ ์ฑ์ด๋ค. ์์ ํธ๋์ ๋ฐ๊นฅ์ผ๋ก 4 ๋ ๋์ด์ง๋ ๋ ์ด์์ ๋์ด๋ ๋์ง ์๋๋ค. ํฐ ๊ธ์์์ ์ธ๋ก๋ก ์์ด๋ฉด ํญ๋ชฉ๋ง๋ค 44. ํญ๋ชฉ ์ข์ฐ ์ฌ๋ฐฑ `medium` `spacing.md` 16 ยท `small` `spacing.sm` 12. 2026-10-17 ์ฌ์ฉ์ ์์ฒญ("๋์ด ๋ง์ถฐ")์ผ๋ก ๊ฐ์ ์ค์ ์นฉ๊ณผ ๋์ด๋ฅผ ๋ง์ท๋ค(์ด์ ์๋ ํญ๋ชฉ ๋์ด ๊ธฐ์ค์ด๋ผ ํธ๋์ด 46ยท54์๋ค) | `segmentedControlRecipe.sizes`, `.hjm-segmented__scroller`, `.hjm-segmented__item` |
|
|
84
84
|
| ๊ฐ๊ฒฉ | ํธ๋ ์์ชฝ ์ฌ๋ฐฑยทํญ๋ชฉ ๊ฐ๊ฒฉ `container.padding`ยท`gap` `spacing.xxs` 4. ํธ๋ ๋ชจ์๋ฆฌ `radius.lg` 16(ํ
๋๋ฆฌ 1). ์ ํ ํญ๋ชฉ ๋ชจ์๋ฆฌ `radius.md` 12, ์ ํ ํ
๋๋ฆฌ 2(`stroke.strong`). ์๋ ๋ด์ฉ๊ณผ `layout.contentGap` 16 | `segmentedControlRecipe.container`ยท`item`, `.hjm-segmented__items` |
|
|
85
85
|
| ์์ยท์ ๋ ฌ | ํญ๋ชฉ์ ๊ฐ์ ํญ์ผ๋ก ๋๋๊ณ (Native `flex: 1`, Web `flex: 1 1 0`) ํธ๋์ ๋ถ๋ชจ ํญ์ ์ฑ์ด๋ค. ์ ํํ ๋ด์ฉ ๋ฐ๋ก ์, ํ๋ฉด ์ข์ฐ ์ฌ๋ฐฑ(`layout.pagePadding`) ์ | Native `SegmentedControl`, `.hjm-segmented__item` |
|
|
86
86
|
| ๊ณ ์ ยท์คํฌ๋กค | ๊ณ ์ ๋์ง ์๋๋ค. Web ํญ๋ชฉ์ ๊ธ์๋ณด๋ค ์ข์์ง์ง ์์(`min-inline-size: max-content`) ๋์น๋ฉด ํธ๋์ด ๊ฐ๋ก ์คํฌ๋กค๋๋ค. Native๋ ์คํฌ๋กคํ์ง ์๋๋ค | `.hjm-segmented__items`(overflow-x) |
|