@hjmds/design-contracts 1.50.0 โ 3.0.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/base-recipes.d.ts +0 -7
- package/dist/base-recipes.d.ts.map +1 -1
- package/dist/base-recipes.js +3 -7
- package/dist/base-recipes.js.map +1 -1
- package/dist/behaviors.d.ts +7 -7
- package/dist/catalog.d.ts +66 -9
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +1 -1
- package/dist/catalog.js.map +1 -1
- package/dist/component-recipes.d.ts +14 -0
- package/dist/component-recipes.d.ts.map +1 -1
- package/dist/component-recipes.js +4 -0
- package/dist/component-recipes.js.map +1 -1
- package/dist/date-range.d.ts +56 -8
- package/dist/date-range.d.ts.map +1 -1
- package/dist/date-range.js +37 -5
- package/dist/date-range.js.map +1 -1
- package/dist/icon-button-recipe.d.ts +0 -6
- package/dist/icon-button-recipe.d.ts.map +1 -1
- package/dist/icon-button-recipe.js +8 -11
- package/dist/icon-button-recipe.js.map +1 -1
- package/dist/image.d.ts +36 -0
- package/dist/image.d.ts.map +1 -1
- package/dist/image.js +44 -0
- package/dist/image.js.map +1 -1
- package/dist/screen-patterns.d.ts +8 -0
- package/dist/screen-patterns.d.ts.map +1 -1
- package/dist/screen-patterns.js +5 -0
- package/dist/screen-patterns.js.map +1 -1
- package/dist/tag.d.ts +20 -7
- package/dist/tag.d.ts.map +1 -1
- package/dist/tag.js +20 -9
- package/dist/tag.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- 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 +3 -2
- package/docs/tag.md +14 -5
- package/docs/theme-palette.md +3 -1
- package/docs/usage/components/auth-screen-layout.md +2 -0
- package/docs/usage/components/avatar.md +13 -0
- package/docs/usage/components/button.md +4 -3
- package/docs/usage/components/chart.md +1 -0
- package/docs/usage/components/comment-thread-row.md +4 -1
- package/docs/usage/components/date-range-picker.md +9 -3
- package/docs/usage/components/icon-button.md +6 -6
- package/docs/usage/components/image.md +7 -0
- package/docs/usage/components/profile-summary.md +27 -2
- package/docs/usage/components/radio-group.md +18 -0
- package/docs/usage/components/sheet.md +1 -1
- package/docs/usage/components/tag.md +8 -5
- package/package.json +1 -1
package/dist/tag.js
CHANGED
|
@@ -3,6 +3,8 @@ import { semanticColors } from "./semantic-colors.js";
|
|
|
3
3
|
import { fontWeight, spacing, stroke } from "./foundations.js";
|
|
4
4
|
export const tagDefaults = {
|
|
5
5
|
tone: "neutral",
|
|
6
|
+
// The approved border-only capsule is the shared default (2026-10-29).
|
|
7
|
+
variant: "outline",
|
|
6
8
|
};
|
|
7
9
|
function assertCopy(value, field) {
|
|
8
10
|
if (value.trim().length === 0) {
|
|
@@ -18,6 +20,9 @@ const supportedTones = [
|
|
|
18
20
|
];
|
|
19
21
|
export function validateTagDescriptor(descriptor) {
|
|
20
22
|
assertCopy(descriptor.label, "label");
|
|
23
|
+
if (descriptor.variant !== undefined && !["default", "outline"].includes(descriptor.variant)) {
|
|
24
|
+
throw new TypeError(`Unsupported Tag variant: ${String(descriptor.variant)}`);
|
|
25
|
+
}
|
|
21
26
|
if (descriptor.tone !== undefined &&
|
|
22
27
|
!supportedTones.includes(descriptor.tone)) {
|
|
23
28
|
throw new TypeError(`Unsupported Tag tone: ${String(descriptor.tone)}`);
|
|
@@ -28,14 +33,10 @@ export function resolveTagDescriptor(descriptor) {
|
|
|
28
33
|
return {
|
|
29
34
|
label: descriptor.label,
|
|
30
35
|
tone: descriptor.tone ?? tagDefaults.tone,
|
|
36
|
+
variant: descriptor.variant ?? tagDefaults.variant,
|
|
31
37
|
};
|
|
32
38
|
}
|
|
33
|
-
/**
|
|
34
|
-
* Rectangular, not the pill `radius.full` that `chipRecipe`
|
|
35
|
-
* use, so a static Tag never reads as a pressable Chip or a status Badge at a
|
|
36
|
-
* glance. No `states` and no `focus` contract: nothing here is ever pressed
|
|
37
|
-
* or focused.
|
|
38
|
-
*/
|
|
39
|
+
/** Static metadata has no focus or press contract, including the outline capsule. */
|
|
39
40
|
export const tagRecipe = {
|
|
40
41
|
slots: ["root", "label"],
|
|
41
42
|
defaults: tagDefaults,
|
|
@@ -77,15 +78,25 @@ export const tagRecipe = {
|
|
|
77
78
|
textVariant: "caption",
|
|
78
79
|
fontWeight: fontWeight.medium,
|
|
79
80
|
},
|
|
81
|
+
// Profile fact rails need breathing room without a colored plate (2026-10-29 approved preview).
|
|
82
|
+
outline: {
|
|
83
|
+
minHeight: 32,
|
|
84
|
+
paddingHorizontal: 10,
|
|
85
|
+
paddingVertical: 6,
|
|
86
|
+
radius: "full",
|
|
87
|
+
fontWeight: fontWeight.regular,
|
|
88
|
+
background: "transparent",
|
|
89
|
+
content: semanticColors.content.primary,
|
|
90
|
+
},
|
|
80
91
|
radius: "sm",
|
|
81
92
|
borderWidth: stroke.default,
|
|
82
93
|
};
|
|
83
94
|
/** Resolve the same Tag recipe for non-CSS renderers. */
|
|
84
|
-
export function resolveTagPresentation(tone, palette) {
|
|
95
|
+
export function resolveTagPresentation(tone, palette, variant = tagDefaults.variant) {
|
|
85
96
|
const contract = tagRecipe.tones[tone];
|
|
86
97
|
return {
|
|
87
|
-
background: resolveColorReference(contract.background, palette),
|
|
88
|
-
content: resolveColorReference(contract.content, palette),
|
|
98
|
+
background: variant === "outline" ? "transparent" : resolveColorReference(contract.background, palette),
|
|
99
|
+
content: resolveColorReference(variant === "outline" && tone === "neutral" ? tagRecipe.outline.content : contract.content, palette),
|
|
89
100
|
border: contract.border === null
|
|
90
101
|
? null
|
|
91
102
|
: resolveColorReference(contract.border, palette),
|
package/dist/tag.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tag.js","sourceRoot":"","sources":["../src/tag.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,GAEtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"tag.js","sourceRoot":"","sources":["../src/tag.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n resolveColorReference,\n type ColorReferencePalette,\n} from \"./color-references.js\";\nimport { semanticColors } from \"./semantic-colors.js\";\nimport { fontWeight, spacing, stroke } from \"./foundations.js\";\n\nexport type TagTone = \"neutral\" | \"info\" | \"success\" | \"attention\" | \"brand\";\n\nexport type TagVariant = \"default\" | \"outline\";\n\nexport const tagDefaults = {\n tone: \"neutral\",\n // The approved border-only capsule is the shared default (2026-10-29).\n variant: \"outline\",\n} as const satisfies Readonly<{ tone: TagTone; variant: TagVariant }>;\n\n/**\n * A single piece of static metadata (a position, a grade, a season). Tag has\n * no interaction axis at all โ no selected, no pressed, no closable. Removing\n * or toggling a tag is deselection, which belongs to `Chip`.\n */\nexport type TagDescriptor = Readonly<{\n label: string;\n tone?: TagTone;\n variant?: TagVariant;\n}>;\n\nexport type ResolvedTagDescriptor = Readonly<{\n label: string;\n tone: TagTone;\n variant: TagVariant;\n}>;\n\nfunction assertCopy(value: string, field: string): void {\n if (value.trim().length === 0) {\n throw new TypeError(`Tag ${field} must not be empty`);\n }\n}\n\nconst supportedTones: readonly TagTone[] = [\n \"neutral\",\n \"info\",\n \"success\",\n \"attention\",\n \"brand\",\n];\n\nexport function validateTagDescriptor(descriptor: TagDescriptor): void {\n assertCopy(descriptor.label, \"label\");\n if (descriptor.variant !== undefined && ![\"default\", \"outline\"].includes(descriptor.variant)) {\n throw new TypeError(`Unsupported Tag variant: ${String(descriptor.variant)}`);\n }\n if (\n descriptor.tone !== undefined &&\n !supportedTones.includes(descriptor.tone)\n ) {\n throw new TypeError(`Unsupported Tag tone: ${String(descriptor.tone)}`);\n }\n}\n\nexport function resolveTagDescriptor(\n descriptor: TagDescriptor,\n): ResolvedTagDescriptor {\n validateTagDescriptor(descriptor);\n return {\n label: descriptor.label,\n tone: descriptor.tone ?? tagDefaults.tone,\n variant: descriptor.variant ?? tagDefaults.variant,\n };\n}\n\n/** Static metadata has no focus or press contract, including the outline capsule. */\nexport const tagRecipe = {\n slots: [\"root\", \"label\"] as const,\n defaults: tagDefaults,\n tones: {\n // Same as badgeRecipe: a canvas plate without a border vanished on the canvas (2026-10-17 review E3).\n neutral: {\n background: semanticColors.canvas,\n content: semanticColors.content.secondary,\n border: semanticColors.border.default,\n },\n brand: {\n background: semanticColors.canvas,\n content: semanticColors.content.brand,\n border: semanticColors.border.default,\n },\n info: {\n background: semanticColors.canvas,\n content: semanticColors.feedback.info.foreground,\n border: semanticColors.feedback.info.border,\n },\n success: {\n background: semanticColors.feedback.success.badgeBackground,\n content: semanticColors.feedback.success.foreground,\n border: semanticColors.feedback.success.border,\n },\n attention: {\n background: semanticColors.feedback.attention.badgeBackground,\n content: semanticColors.feedback.attention.foreground,\n border: semanticColors.feedback.attention.border,\n },\n },\n size: {\n // Static metadata still participates in Dynamic Type. A fixed 20px frame\n // clips the label at accessibility sizes; minHeight preserves the compact\n // base shape while allowing the intrinsic line box to grow.\n minHeight: 20,\n paddingHorizontal: spacing.xxs,\n gap: spacing.xxs,\n textVariant: \"caption\",\n fontWeight: fontWeight.medium,\n },\n // Profile fact rails need breathing room without a colored plate (2026-10-29 approved preview).\n outline: {\n minHeight: 32,\n paddingHorizontal: 10,\n paddingVertical: 6,\n radius: \"full\",\n fontWeight: fontWeight.regular,\n background: \"transparent\",\n content: semanticColors.content.primary,\n },\n radius: \"sm\",\n borderWidth: stroke.default,\n} as const;\n\nexport type ResolvedTagPresentation = Readonly<{\n background: string;\n content: string;\n border: string | null;\n}>;\n\n/** Resolve the same Tag recipe for non-CSS renderers. */\nexport function resolveTagPresentation(\n tone: TagTone,\n palette: ColorReferencePalette,\n variant: TagVariant = tagDefaults.variant,\n): ResolvedTagPresentation {\n const contract = tagRecipe.tones[tone];\n return {\n background: variant === \"outline\" ? \"transparent\" : resolveColorReference(contract.background, palette),\n content: resolveColorReference(variant === \"outline\" && tone === \"neutral\" ? tagRecipe.outline.content : contract.content, palette),\n border:\n contract.border === null\n ? null\n : resolveColorReference(contract.border, palette),\n };\n}\n"]}
|
package/dist/version.d.ts
CHANGED
package/dist/version.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,EAAG,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,EAAG,OAAgB,CAAC"}
|
package/dist/version.js
CHANGED
package/dist/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,OAAgB,CAAC","sourcesContent":["/** Package release shown by documentation surfaces. Kept in sync by a test. */\nexport const designSystemVersion = \"3.0.0\" as const;\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Component maturity and evidence manifest
|
|
2
2
|
|
|
3
|
-
> Generated from `@hjmds/design-contracts`
|
|
3
|
+
> Generated from `@hjmds/design-contracts` 3.0.0. 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": "
|
|
3
|
+
"designSystemVersion": "3.0.0",
|
|
4
4
|
"source": "packages/design-contracts/docs/generated/showcase-manifest.json",
|
|
5
5
|
"surfaces": {
|
|
6
6
|
"web": {
|
|
7
7
|
"packageName": "@hjmds/react",
|
|
8
|
-
"packageVersion": "
|
|
8
|
+
"packageVersion": "3.0.0",
|
|
9
9
|
"activeComponents": 132,
|
|
10
10
|
"claimedComponents": 132,
|
|
11
11
|
"completeScenarioComponents": 131,
|
|
@@ -7114,7 +7114,7 @@
|
|
|
7114
7114
|
},
|
|
7115
7115
|
"native": {
|
|
7116
7116
|
"packageName": "@hjmds/react-native",
|
|
7117
|
-
"packageVersion": "
|
|
7117
|
+
"packageVersion": "3.0.0",
|
|
7118
7118
|
"activeComponents": 115,
|
|
7119
7119
|
"claimedComponents": 115,
|
|
7120
7120
|
"completeScenarioComponents": 112,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Renderer evidence coverage
|
|
2
2
|
|
|
3
|
-
> Generated for HJM
|
|
3
|
+
> Generated for HJM 3.0.0. 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
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
|
-
"designSystemVersion": "
|
|
3
|
+
"designSystemVersion": "3.0.0",
|
|
4
4
|
"packageName": "@hjmds/design-contracts",
|
|
5
5
|
"components": [
|
|
6
6
|
{
|
|
@@ -4295,7 +4295,8 @@
|
|
|
4295
4295
|
"extensions": [
|
|
4296
4296
|
"GridReveal",
|
|
4297
4297
|
"ImageViewer",
|
|
4298
|
-
"ImageViewerTrigger"
|
|
4298
|
+
"ImageViewerTrigger",
|
|
4299
|
+
"CircularPhotoCropper"
|
|
4299
4300
|
],
|
|
4300
4301
|
"category": "data-display",
|
|
4301
4302
|
"platform": "shared",
|
package/docs/tag.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
`2026 ์์ฆ` โ ์ ์ผ๊ด๋ ์ด๋ฆ๊ณผ ํค์ ๋ถ์
๋๋ค. ์ด ๋ผ๋ฒจ์ ๋๋ฅผ ์ ์๊ณ , ์ ํ๋์ง๋ ์๊ณ ,
|
|
5
5
|
์ง์์ง์ง๋ ์์ต๋๋ค.
|
|
6
6
|
|
|
7
|
-
**์ผ๋ฐํํ ๊ณ์ฝ.** ํ์ `label`๊ณผ ์ ํ์ `tone
|
|
7
|
+
**์ผ๋ฐํํ ๊ณ์ฝ.** ํ์ `label`๊ณผ ์ ํ์ `tone`ยท`variant`๋ฅผ ๋ฐ๋ ํํ ๊ณ์ฝ์
๋๋ค(Statistic์ฒ๋ผ
|
|
8
8
|
์ ํ์ด ์์ฑํ ๋ฌธ์์ด์ ๋ฐ์ต๋๋ค). id, collection ๋ฉค๋ฒ์ญ, ์ ํ state๋ ์์ต๋๋ค โ Tag๋
|
|
9
9
|
Collection ๊ธฐ๋ณธ ๊ณ์ฝ์ ๋์์ด ์๋๋ผ ๋ฑ๊ฐ ํ์ ๋จ์์
๋๋ค.
|
|
10
10
|
|
|
@@ -28,9 +28,10 @@ Notice/Badge์ ์ญํ ์ด๊ณ , Tag๋ ์ฌ์ค์ ๋์ดํ ๋ฟ ์ํํ์ง ์์ต
|
|
|
28
28
|
- `closable`(์ง์ธ ์ ์๋ ํ๊ทธ)์ ์ด ๊ณ์ฝ์ **์์ต๋๋ค**. ํ๊ทธ๋ฅผ ์ง์ฐ๋ ๊ฒ์ ์ ํ ํด์ ์ด๊ณ ,
|
|
29
29
|
์ ํ ํด์ ๋ Chip์ `selected` ์ถ์ด ์ด๋ฏธ ์์ ํ ๋ฌธ์ ์
๋๋ค. Tag์ ๋ณ๋์ dismiss ์ถ์
|
|
30
30
|
์ถ๊ฐํ๋ฉด ๊ฐ์ "์ ํ ํด์ "๋ฅผ ๋ ์ปดํฌ๋ํธ๊ฐ ์๋ก ๋ค๋ฅธ ์ด๋ฆ์ผ๋ก ๊ณ์ฝํ๊ฒ ๋ฉ๋๋ค.
|
|
31
|
-
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
- ๊ธฐ๋ณธ์ `variant="outline"`์ธ ๋ฐฐ๊ฒฝ ์๋ capsule(`full`)์
๋๋ค.
|
|
32
|
+
์์ ์ฌ๊ฐํ์ ๋ช
์์ ์ธ `variant="default"`๋ก ์ ์งํฉ๋๋ค.
|
|
33
|
+
2026-10-29 ์ ์ ํ๋กํ ์ ๋ณด ์์ ์น์ธ์ ๋ฐ๋ผ ์ ํ UI์ ๋ถ๋ฆฌ๋ ์ฝ๊ธฐ ์ ์ฉ ํํ๋ก ์ถ๊ฐํ์ต๋๋ค.
|
|
34
|
+
ํํ์ ๋ฌด๊ดํ๊ฒ ๋ฒํผ roleยท์ ํ ์ํยทํฌ์ปค์คยทํ์ฑํ ์ด๋ฒคํธ๋ฅผ ์ถ๊ฐํ์ง ์์ต๋๋ค.
|
|
34
35
|
- ์ผ์์์ `AppBadge`๊ฐ ์ด ์ญํ (ํฌ์ง์
ยท๋ฑ๊ธยท์์ฆ ๋ผ๋ฒจ)์ ์ํํ ์ ํ ๊ทผ๊ฑฐ์์ Tag ๊ณ์ฝ์
|
|
35
36
|
์ถ์ถํ์ต๋๋ค. Web/RN ๊ณต์ renderer๋ ์ด ๊ณ์ฝ์ ์ง์ ์๋นํ๋ฉฐ, ์ ํ์ ๊ธฐ์กด ์ด๋ฆ์ Tag๋ก
|
|
36
37
|
๋ฐ๊พธ๋ ์ผ ์์ฒด๋ ์๋น ์ฑ์ ํ์ migration์
๋๋ค.
|
|
@@ -42,7 +43,7 @@ keyboard, focus, accessibilityState ๊ณ์ฝ์ด ํ์ ์์ต๋๋ค โ ์ ๊ทผ์ฑ
|
|
|
42
43
|
๋
ธ๋ ํ๋๋ก ์ถฉ๋ถํฉ๋๋ค. ์ฌ๋ฌ Tag๋ฅผ ํ ์ค์ ๋์ดํ ๋ ๊ฐ๊ฒฉ ์กฐํฉ์ ๋์ค์ Stack/Inline
|
|
43
44
|
recipe๊ฐ ์์ ํ๋๋ฉด ๊ทธ์ชฝ์ ์์ํ๊ณ , ์ด ๊ณ์ฝ์๋ ๋ฃ์ง ์์ต๋๋ค.
|
|
44
45
|
|
|
45
|
-
๊ธฐ๋ณธ ๋์ด๋
|
|
46
|
+
๊ธฐ๋ณธ ์ต์ ๋์ด๋ 32px์ด๋ฉฐ ๊ณ ์ ๋์ด๊ฐ ์๋๋๋ค. Dynamic Type์์ ํ ์ค ๋ผ๋ฒจ์ ๊ณ ์ ๋์ด๋งํผ
|
|
46
47
|
๋์ด๋๋ฉฐ, renderer๋ ๋ผ๋ฒจ์ ๊ณ ์ ํ๋ ์ ์์์ ์๋ฅด์ง ์์ต๋๋ค.
|
|
47
48
|
|
|
48
49
|
## ํ์ฌ maturity์ ๋จ์ ์ฆ๊ฑฐ
|
|
@@ -54,3 +55,11 @@ scenario matrix๊ฐ dark(๋ผ์ดํธ ์ ์ฉ ์ ๋์ ์์), 2๋ฐฐ ๊ธ์, RTL,
|
|
|
54
55
|
|
|
55
56
|
stable์ ์ ์ฒด ํ๊ฒฝ ์ธ์ฆ์ ๋ปํ์ง ์์ต๋๋ค. screen reader ์ค์ฌ์ฉ๊ณผ ์ค์ device screenshot์
|
|
56
57
|
์ ํ ๊ธฐ๊ธฐ QA์ ๋ฒ์์
๋๋ค.
|
|
58
|
+
|
|
59
|
+
## Outline ํํ
|
|
60
|
+
|
|
61
|
+
`variant`๋ `default | outline`, ๊ธฐ๋ณธ๊ฐ์ `outline`์
๋๋ค.
|
|
62
|
+
2026-10-29 ์ฌ์ฉ์๊ฐ ์น์ธํ ํ
๋๋ฆฌํ์ ๊ธฐ๋ณธ์ผ๋ก ์ง์ ํ์ต๋๋ค. Outline์ ํฌ๋ช
๋ฐฐ๊ฒฝยท1px ํ
๋๋ฆฌยท
|
|
63
|
+
`radius.full`, ์ต์ ๋์ด 32, ์ข์ฐ 10ยท์ํ 6, caption regular(400)์
๋๋ค.
|
|
64
|
+
neutral ๊ธ์๋ `content.primary`, ๋ค๋ฅธ tone์ ๊ธฐ์กด ๊ธ์ยทํ
๋๋ฆฌ ์๋ฏธ๋ฅผ ์ ์งํฉ๋๋ค.
|
|
65
|
+
ํฐ ๋ฐฐ๊ฒฝ ์ ์ฉ ์์ ํ๋์ฝ๋ฉํ์ง ์๊ณ Provider์ light/dark ๋ฐ ์ ํ ํ๋ ํธ๋ฅผ ๋ฐ๋ฆ
๋๋ค.
|
package/docs/theme-palette.md
CHANGED
|
@@ -122,13 +122,15 @@ SegmentedControl์ `selectionTone="brand"`์ solid ํญ์ ๋ธ๋๋ ๊ฐ์กฐ๋ฅผ
|
|
|
122
122
|
|
|
123
123
|
| ์๋ฏธ | ์์ ๊ธฐ์ค | ํด๋น ๊ณต๊ฐ ํ๋ฉด |
|
|
124
124
|
| --- | --- | --- |
|
|
125
|
-
| ์ง์๋๋ ์ผ๋ฐ ์ ํ ๋ฉด | `selection.background`/`selection.content`, ๊ฒฝ๊ณ๊ฐ ํ์ํ๋ฉด `selection.border` | Chipยท์นฉ ๊ทธ๋ฃน, neutral SegmentedControl, TimePicker, filled Tabs, capsule BottomNavigation, ReactionPicker, ToggleGroup,
|
|
125
|
+
| ์ง์๋๋ ์ผ๋ฐ ์ ํ ๋ฉด | `selection.background`/`selection.content`, ๊ฒฝ๊ณ๊ฐ ํ์ํ๋ฉด `selection.border` | Chipยท์นฉ ๊ทธ๋ฃน, neutral SegmentedControl, TimePicker, filled Tabs, capsule BottomNavigation, ReactionPicker, ToggleGroup, ์ ํ CardยทListRowยทSelectยทComboboxยทMenuยทTreeยทTransferListยทDataTable ํ |
|
|
126
126
|
| ํ์ฌ ์กฐ์ ์์น | ๊ธฐ์กด focus/hover/pressed ์ญํ . ํ์ ์ ํ๊ณผ ํฉ์น์ง ์์ | CommandPaletteยทMentionsยทTagsInput ์ ์์ active descendant, SelectยทCombobox์ active ํญ๋ชฉ, ํฌ์ปค์ค ๋ง |
|
|
127
127
|
| ์งํ ๋ธ๋๋ ๋ฉด | `primary`/`onPrimary` | `Tabs indicator="solid"`, `SegmentedControl` ๊ธฐ๋ณธ `selectionTone="brand"`, `BottomNavigation selection="tile"`, prominent destination |
|
|
128
128
|
| ์์ ๊ฐ ํ์ยทํ์ฌ ์์น ํ์ | ๊ธฐ์กด ์ ์ฉ ์ฒดํฌยท์ ยท๋ฐ์คยทํ
๋๋ฆฌ ๊ณ์ฝ | CheckboxยทRadio์ glyph, Switch on, Calendar ๋ ์ง ์, underline/text Tabs, ์ผ๋ฐ BottomNavigation ์์ด์ฝยท๊ธ์, PaginationยทStepsยทAnchorยทCarousel ์์น ํ์, ์ฝ๊ธฐ ์ ์ฉ ๋ฐ์ ์์ฝ |
|
|
129
129
|
| ๋ธ๋๋ยท์ฅ์ยท์
๋ฌด ๊ฐ์กฐ | ๊ธฐ์กด ๋ธ๋๋/์ํ ์ญํ | ChatMessage outgoing, ํด๋ ๊ทธ๋ฆผ, liquid toast, ํ์ `highlighted` ์
๋ฌด ๊ฐ์กฐ, ๋ธ๋๋ Surface/Badge, ์ค๋ฅยท์ฑ๊ณต ๋ฑ ์ํ |
|
|
130
130
|
| ๋ฏธ๋์ด ์ ์ ํ ์ฆ๊ฑฐ | ์ฝ์ ์ ์๋ ์ ์ฉ ๋งยท์คํฌ๋ฆผ ์ ์ง | ImageChoiceยทMediaSelection. ํ์ ๋ฉด์ผ๋ก ์ฌ์ง์ ๋ฎ์ง ์์ |
|
|
131
131
|
|
|
132
|
+
ํ๋ ํ ๊ธ์ธ ButtonยทIconButton๊ณผ ํ์ฌ ๊ฒฝ๋ก์ธ IconButtonLink๋ 2026-10-28 ์ฌ์ฉ์ ์ง์๋ก ์ด ์ ํ ๋ฉด์ ์ ์ฉํ์ง ์๋๋ค. ์ ํ ์ ํ ์๋ tone ๋ฐฐ๊ฒฝยทํ
๋๋ฆฌ๋ฅผ ์ ์งํ๋ฉฐ ์ ๊ฒฝ ํํยท์ฑ์ด glyph์ ์ ๊ทผ์ฑ ์ํ๋ก ์ ํ์ ์๋ฆฐ๋ค. ์คํํธ์ ๊ฝ ๋ฐ์ ์ฃผ๋ณ์ ์ ํ ๋ฐฐ๊ฒฝ์ด ์ค๋ณต์ผ๋ก ์๊ธด ์ฌ๋ก์ ๋ฐ๋ฅธ ๋ณ๊ฒฝ์ด๋ค. ์ ํ ์ปดํฌ๋ํธ์ ์ ์ฉ ์ํ ๊ณ์ฝ์ ํด๋น ์ปดํฌ๋ํธ ์ง์นจ์ด ์์ ํ๋ค.
|
|
133
|
+
|
|
132
134
|
### ์ ์ฉ ๊ท์น
|
|
133
135
|
|
|
134
136
|
- ์ ํ ํ ํฐ์ ํ์ฌ theme๊ณผ product palette๋ก ํด์ํ๋ค. ์ ํ๋ณ ์ง์ ์์ ๋ถ๊ธฐ๋ ์ถ๊ฐํ์ง ์๋๋ค.
|
|
@@ -88,6 +88,7 @@ import { AuthScreenFooter, AuthScreenHero, AuthScreenLayout } from "@hjmds/react
|
|
|
88
88
|
| `layoutStyle` | marginยทwidthยทflexยท`alignSelf` | โ | ๋ฐ๊นฅ ๋ฐฐ์น ์ ์ฉ(WebยทNative ๋ชจ๋) |
|
|
89
89
|
| `initialFocus` | `first-input` ยท `none` | `first-input` | ํ์ด์ง ์ง์
์ ์ฒซ ์ ํจ ์
๋ ฅ ๋๋ `initialFocusTarget` ์นธ์ ํ ๋ฒ ํฌ์ปค์คํ๋ค. ๊ธฐ๋ณธ๊ฐยท์ง์
ํ์ ์ ์ฑ
๋ณ๊ฒฝ์ 1.33.0๋ถํฐ ์ ๊ณต. ์ง์
์ข
๋ฃ ๋ค ๋จ๊ณ ๋ณ๊ฒฝยท์
๋ ฅ ํ์๋ก ์๋ ํฌ์ปค์ค๋ฅผ ๋ค์ ์์ํ์ง ์์ผ๋ฉฐ ํ๋จ ์ํธ ์์์๋ ์๋ ํฌ์ปค์คํ์ง ์๋๋ค. [์ง์
ํฌ์ปค์ค](screen-layout.md#์ง์
-ํฌ์ปค์ค) |
|
|
90
90
|
| Native `testID` | `string` | โ | ๋ณธ๋ฌธ `ScrollView` ์๋ณ(๋จธ๋ฆฌ ๋ ๊ฐ ์์ด๋ ๊ฐ์ `ScrollView`) |
|
|
91
|
+
| Native `backdrop` | `ReactNode` | โ | ๋ฏธ๊ฒ์(checkout ๊ฐ๋ฐ). ์คํฌ๋กค ๋ด์ฉ ๋งจ ์ ๋ค์ ๊น๋ฆฌ๋ ์ฅ์ ์ฅ๋ฉด(์ ํ ํ๋ ๋ ๋ฑ). heroยทmainยทfooter์ **ํจ๊ป ์คํฌ๋กค**ํ๊ณ ํฐ์นยท์ ๊ทผ์ฑ์์ ๋น ์ง๋ค. ์ ํ ๋
ธ๋๋ ๋ด์ฉ ์ ๋ ๊ธฐ์ค ์ ๋ ์์น๋ก ๋์ผ๋ฉฐ ์ข์ฐ ์ฌ๋ฐฑ ๋ฐ๊น์ง ๋ฟ๋๋ค. ํ๋ฉด ๋ค์ ๊ณ ์ ํ ๊ทธ๋ฆผ ์๋ก ๊ธ์๊ฐ ์ง๋๊ฐ์ง ์๊ฒ ํ๋ค |
|
|
91
92
|
| Native `safeAreaBottom` | 0 ์ด์์ ์ ํ์ | `0` | ํ๋ฉด์ด ๋ฟ๋ ์ฐฝ ์๋ ๊ฐ์ฅ์๋ฆฌ์ safe area(`useSafeAreaInsets().bottom`, ์ด๋ฏธ ์๋๋ฅผ ๋ค์ธ host ์์ด๋ฉด 0). ์๋ ์ฌ๋ฐฑ์ด `max(paddingBlock, inset)` โ `regular` max(40, inset), `compact` max(20, inset) โ ์ผ๋ก ํ ๋ฒ๋ง ๋ค์ด๊ฐ๋ค(ScreenLayout๊ณผ ๊ฐ์ ๊ท์น, ํฉ์ฐ ์์). ํค๋ณด๋๊ฐ ์ด๋ฆฌ๋ฉด paddingBlock๋ง. ์์ยท๋ฌดํ๋๋ `RangeError` |
|
|
92
93
|
| `AuthScreenHero` `title` ยท `eyebrow` ยท `description` ยท `mark` ยท `headingLevel` | ๋ฌธ์์ด ยท `ReactNode` ยท `1`~`3` | `headingLevel` 1 | ์ ๋ชฉ์ ํ์์ด๊ณ ๋น ๋ฌธ์์ด์ด๋ฉด `TypeError`. ๋ฐ๋๋ ๋ฐ๊นฅ `AuthScreenLayout`์ ๋ฐ๋ฅธ๋ค |
|
|
93
94
|
| `AuthScreenFooter` `links` ยท `notice` ยท `children` | ๋งํฌ ๋ฐฐ์ด(1๊ฐ ์ด์) ยท `ReactNode` | โ | ๋น ๋งํฌ ๋ชฉ๋กยท๋น ๋ผ๋ฒจ์ `TypeError`(LS-04: ์ฝ๊ด ๋งํฌ๋ ๋ก๊ทธ์ธ ์ ๊ฐ์ ํ๋ฉด์ ์์ด์ผ ํ๋ค). `children`์ ๋งํฌ ์๋ ์ ํ ๋ด์ฉ |
|
|
@@ -156,6 +157,7 @@ import { AuthScreenFooter, AuthScreenHero, AuthScreenLayout } from "@hjmds/react
|
|
|
156
157
|
|
|
157
158
|
- `title`ยท`exit`๋ฅผ ์ฐ๋ฉด ๋ฐ๊นฅ์ ์น๋ TopBarยท์ ํ ํค๋๋ฅผ ์ง์ด๋ค. ๋ ๋ค ๋๋ฉด ๋จธ๋ฆฌ๊ฐ ๋ ์ค์ด ๋๋ค. Native์์ host TopBar๊ฐ ๋งก๋ ์ safe area(`safeAreaTop`)๋ host์ SafeAreaView top์ผ๋ก ์ฎ๊ธด๋ค.
|
|
158
159
|
|
|
160
|
+
- Native์์ ํ๋ ๋ ๊ฐ์ ์ฅ์์ ๋ ์ด์์ ๋ฐ๊นฅ(ํ๋ฉด ๋ค)์ ๊ณ ์ ํ์ง ์๋๋ค. ๋ด์ฉ์ด ๋์ณ ์คํฌ๋กค๋๋ฉด ๊ธ์๊ฐ ๊ทธ๋ฆผ ์๋ก ์ง๋๊ฐ ์ฝํ์ง ์๋๋ค(2026-10-28 ๋ค์๋ฆฌ ๊ฐ์
๋จ๊ณ). `backdrop`์ผ๋ก ๋๊ธด๋ค.
|
|
159
161
|
- Native์์ ์๋ ํ ์ธ๋์ผ์ดํฐ๋ฅผ `SafeAreaView edges={['bottom']}`ยท`paddingBottom: insets.bottom` ๋ํผ๋ก ๋ค์ด์ง ๋ง๊ณ `safeAreaBottom`์ผ๋ก ๋๊ธด๋ค. ๋์ ๊ฐ์ด ์ฃผ๋ฉด inset + paddingBlock์ด ๋ค์ ๋ํด์ง๋ค.
|
|
160
162
|
- 1.28.0๊น์ง Native๋ iOS `contentInsetAdjustmentBehavior="automatic"`์ผ๋ก ์ยท์๋ safe area๋ฅผ iOS์์๋ง ๋ํ๋ค. 1.28.1๋ถํฐ ์๋ host, ์๋๋ `safeAreaBottom`์ด๋ค. ์ safe area๋ฅผ ์๋ฌด๋ ๋ค์ด์ง ์๋ ํ๋ฉด์ host์์ TopBar `safeAreaTop`์ด๋ SafeAreaView top์ผ๋ก ๋ค์ธ๋ค.
|
|
161
163
|
- Native๋ ์์ฒด๋ก ํค๋ณด๋ ์คํฌ๋กค ์ฌ๋ฐฑ์ ์ค๋ค. ๋ถ๋ชจ๊ฐ ๋ค์ keyboard avoidance๋ฅผ ํ๋ฉด ์ฌ๋ฐฑ์ด ์ค๋ณต๋ ์ ์์ผ๋
|
|
@@ -180,6 +180,10 @@ Avatar๋ฅผ ์ฐ์ง ๋ชปํ ์ด์ (์ด๋ฆ ํ์, Web ์ด๋ฏธ์ง ํธ์คํธ ์์, 4
|
|
|
180
180
|
์ผ๋ฐ ๋ชฉ๋ก์ `ListRow.leadingAction`, ์นด๋ ์์ฑ์๋ `Card.leadingAction`, ๋ํ ๋ชฉ๋ก์ `ConversationRow.avatarAction` + `renderBody`, ์ฐธ์ฌ์๋ `ChatRoomMembers.memberProfile`์ด๋ค.
|
|
181
181
|
๊ฐ์ ์ฌ์ง์ `Avatar.action`๊ณผ ์์ `avatarAction`์ ํจ๊ป ๋ฃ์ง ์๋๋ค. ๋ณธ๋ฌธ ๋งํฌ/๋ฒํผ๊ณผ ๋
๋ฆฝ ํ๋กํ ๋ฒํผ์ ํ์ ๋ค.
|
|
182
182
|
|
|
183
|
+
์ฌ์ง ์์ ๋ฐ๋ก ๋ณด์ด๋ ํ์ ๋๋ค์๋ ๊ฐ์ ํ๋กํ๋ก ์ด๋ํ๋ค(2026-10-29 ์ฌ์ฉ์ ์ง์: Spint ๋๊ธ์์ ๋๋ค์์ ๋๋ฌ๋ ๋ฐ์์ด ์์๋ค).
|
|
184
|
+
๋๊ธ `CommentThreadRow`๋ `avatarAction`์ด ์์ผ๋ฉด ์์ฑ์ ์ด๋ฆ๋ ๊ฐ์ ํ๋ยท์ ๊ทผ์ฑ ์ด๋ฆ์ ๊ธ์ ๋ฒํผ์ผ๋ก ๊ทธ๋ฆฐ๋ค(Web `hjm-identity-name-action`,
|
|
185
|
+
Native ์ค์ฒฉ `Text` press). ์ ํ์ ์ถ๊ฐ prop ์์ด `avatarAction`๋ง ๊ณต๊ธํ๋ค. ํ ์ ์ฒด๊ฐ ๋ํ๋ฐฉยท์๋ฆผ ๋ชฉ์ ์ง์ธ ๊ธ์ ์์ ์ด๋ฆ์ ๋ฒํผ์ ์ค์ฒฉํ์ง ์๋๋ค.
|
|
186
|
+
|
|
183
187
|
ํ์ ์๋ณ์๊ฐ ์๋ ์ฅ์ยท๋ฐฉ ์ฌ์ง์ ํ์ ํ๋กํ๋ก ์ฐ๊ฒฐํ์ง ์๋๋ค. ๋ช
์์ ์ธ ์ฌ์ง ํธ์งยท๊ณต์ ๋์ ์ ํ์ ์๋ ์์
์ ์ ์งํ๋ค.
|
|
184
188
|
|
|
185
189
|
๋ด ํ๋กํ ํ๋ฉด์ ๋ด ์ฌ์ง์ ์์ธ๋ก ๊ทธ ์์ฒด๊ฐ ์ฌ์ง ๋ณ๊ฒฝ ๋ฒํผ์ด๋ค(2026-10-25 ์ฌ์ฉ์ ์ง์). `action={{label: t("photo.change"), onPress: openPhotoPicker}}`๋ฅผ ์ฐ๊ฒฐํ๊ณ ์ฌ์ง ๊ณ ๋ฅด๊ธฐยท์๋ฅด๊ธฐยท์
๋ก๋๋ ์ ํ์ด ์์ ํ๋ค. ๊ฐ์ ํ๋ฉด์ ์ค๋ณต "์ฌ์ง ๋ฐ๊พธ๊ธฐ" ๋ฒํผ์ ๋์ง ์๋๋ค.
|
|
@@ -192,3 +196,12 @@ Avatar๋ฅผ ์ฐ์ง ๋ชปํ ์ด์ (์ด๋ฆ ํ์, Web ์ด๋ฏธ์ง ํธ์คํธ ์์, 4
|
|
|
192
196
|
์ฌ์ฉ์ ์์ฒญ์ผ๋ก WebยทNative ๊ธฐ๋ณธ๊ฐ์ `size="large"`(48), `shape="circle"`์ด๋ค. ํ๋กํ๊ณผ ์ผ๋ฐ ํ์ ๋ชฉ๋ก์๋ 48์ ์ฐ๊ณ ๋๊ธยท์ฑํ
๋ฑ ์ด์ดํ ๋ชฉ๋ก์ ๋ช
์์ ์ธ ์์ ๋จ๊ณ๋ ์ ์งํ๋ค. ์ ํ๋ณ ์ฌ์งยท์ด๋์
ยท์ด๋ชจ์งยท๋๋ฌผ ๊ทธ๋ฆผ๋ ๊ฐ์ ํ์ ํ๋ ์์ ๋ฐ๋ฅธ๋ค. ์ฝํ
์ธ ์ธ๋ค์ผยท์ฑ ์์ด์ฝ์ ๋ชจ์์ด๋ ํฌ๊ธฐ์๋ ์ ์ฉํ์ง ์๋๋ค.
|
|
193
197
|
|
|
194
198
|
๊ธฐ๋ณธ `frame="outlined"`๋ `border.control` 50% alpha, 1px์ ์ํ ์ค๊ณฝ์ด๋ค. 2026-10-25 ๋ฒ๋ ์ด๋ชจ์ง ์๋ฐํ์์ ๊ธฐ์กด ์ ์ ํ๋ฆฌ๊ณ 2px ๋ถํฌ๋ช
์ ์ ์งํ๋ค๋ ํผ๋๋ฐฑ์ ๊ฑฐ์ณ 1pxยท50%๋ก ์กฐ์ ํ์ผ๋ฉฐ, ์ฌ์ฉ์๊ฐ ์ด ๊ฐ์ ๋์์ธ ์์คํ
๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ง์ ํ๋ค. ์ง๋ฆ์ ํ
๋๋ฆฌ ํฌํจ์ด๊ณ WebยทNative์ ๋์ผํ๋ค. ๋ฏธ๊ฒ์ ๊ฐ๋ฐ ์ค ์ถ๊ฐํ๋ `strong` ์ต์
์ ๊ธฐ๋ณธ๊ฐ๊ณผ ํฉ์ณ ์ ๊ฑฐํ๋ค. ์ ํ์์ ๋ณ๋ frame์ ์ง์ ํ ํ์๊ฐ ์๋ค.
|
|
199
|
+
|
|
200
|
+
### ๊ทธ๋ฆผ ์ ์ฒด ํ์ (2026-10-28)
|
|
201
|
+
|
|
202
|
+
์คํํธ์์ ์ง์ ๊ทธ๋ฆฐ ์ ์ฌ๊ฐํ ๊ทธ๋ฆผ์ ๋ชจ์๋ฆฌ๊ฐ ์ํ ํ๋กํ์์ ์๋ฆฐ ์ฌ๋ก๋ก `imageFit="contain"`์ ์ถ๊ฐํ๋ค. ๊ธฐ๋ณธ `cover`๋ ๊ธฐ์กด ์ฌ์ง ์ฑ์์ ์ ์งํ๋ค. `contain`์ ์ฌ์งยท๊ทธ๋ฆผ ์ ์ฒด๋ฅผ ํ๋ ์ ์์ ๋ฃ๊ณ ์ฌ๋ฐฑ์ ๋จ๊ธด๋ค. ๊ณตํต recipe์ `1 / โ2` ๋น์จ๋ก ์ ์ฌ๊ฐํ ๋๊ฐ์ ๊น์ง ์ ์์ ๋ค์ด์ค๋ฉฐ ์ด๋ฏธ์ง์ ๋ชจ์๋ฆฌ๋ฅผ ๋ค์ ๋ฅ๊ธ๊ฒ ์๋ฅด์ง ์๋๋ค. WebยทNative์ ๊ธฐ์กด ์ ์ฅ ์ด๋ฏธ์ง์ ๋์ผํ๊ฒ ์ ์ฉํ๋ค. Native `renderImage`์ `size`์๋ ์ค์ ์ด๋ฏธ์ง ์์ญ ํฌ๊ธฐ๊ฐ ์ ๋ฌ๋๋ค.
|
|
203
|
+
|
|
204
|
+
**ํ์ ํ๋กํ ์ฌ์ง์ ์์ ๊ฝ ์ฑ์ด๋ค(`cover`, ๊ธฐ๋ณธ๊ฐ) โ 2026-10-29 ์ฌ์ฉ์ ์ง์.** `contain`์ ์์ ์ ์์ ๋ค๋ชจ๋ ์ฌ์ง์ด ์๊ฒ ๋ค์ด๊ฐ๊ณ
|
|
205
|
+
๋น ํ
๋๋ฆฌ๊ฐ ๋จ์ ์ฌ์ง์ฒ๋ผ ๋ณด์ด์ง ์์๋ค(Spint). ์ฌ์ง ์ ์ฒด๋ ํ๋กํ์ "์ฌ์ง ํฌ๊ฒ ๋ณด๊ธฐ"(`ProfileSummary.avatarView` + `ImageViewer`)์์
|
|
206
|
+
๋ณธ๋ค. ํ์ ์๋ฐํยท๋๊ธยท์ฑํ
ยท์๋ฆผยท๋ชฉ๋ก์ ์ฌ์ง์ `contain`์ ์ฐ์ง ์๋๋ค. `contain`์ ์๋ฆฌ๋ฉด ๋ป์ด ๋ฐ๋๋ ๋น์ฌ์ง ๊ทธ๋ฆผ(๋ก๊ณ ยท์คํฐ์ปคยท๋๊ฐ
|
|
207
|
+
์ผ๋ฌ์คํธ)์๋ง ์ฐ๊ณ ๊ทธ ์ด์ ๋ฅผ ์ฌ์ฉ์ฒ ์ฃผ์์ ๋จ๊ธด๋ค.
|
|
@@ -131,7 +131,7 @@ WebยทNative์ ๋ผ์ดํธยท๋คํฌ ํ
๋ง์ ๋์ผํ๊ฒ ์ ์ฉํ๋ค.
|
|
|
131
131
|
Native์์ `style`ยท`labelStyle`์ ๋๊ธฐ๋ฉด ์คํ ์ค `TypeError`๊ฐ ๋๋ค.
|
|
132
132
|
- ์์ tone๊ณผ ์ ํ ํ
๋ง ํ ํฐ์ผ๋ก ๋ฐ๊พผ๋ค. ๋ฒํผ๋ง๋ค ๋ธ๋๋ ์์ ํ๋์ฝ๋ฉํ์ง ์๋๋ค.
|
|
133
133
|
- ์งํ ์ค ์ํ๋ `loading`์ผ๋ก ํ์ํ๊ณ ๊ฐ์ ์๋ฆฌ์ ๋ณ๋ Spinner๋ฅผ ๊ฒน์น์ง ์๋๋ค. children์ ๋น ๋ฌธ์์ด์ด๋ ๋ค๋ฅธ ๊ธธ์ด์ ์งํ ๋ฌธ๊ตฌ๋ก ๋ฐ๊พธ์ง ์๋๋ค. ๋ ๋๋ฌ๊ฐ ๋ฌธ๊ตฌยท์์ด์ฝ์ ์จ๊ธด ์๋ฆฌ์ ์ค์ ์คํผ๋๋ง ํ์ํ๊ณ ๊ธฐ์กด ํฌ๊ธฐยท์ ๊ทผ์ฑ ์ด๋ฆ์ ์ ์งํ๋ค.
|
|
134
|
-
-
|
|
134
|
+
- `selected`๋ ์๋ tone์ ๋ฐฐ๊ฒฝ์ ์ ์งํ๋ฏ๋ก `primary` ๋ฒํผ์ด๋ฉด ์ฃผ ํ๋ ๊ฐ์์ ํฌํจํ๋ค. SheetยทDialog ์์ ํ๋์ ๊ทธ ํ๋ฉด ์์์ primary ํ๋๋ฅผ ์ผ๋ค([Sheet](sheet.md) `footer`).
|
|
135
135
|
|
|
136
136
|
- `selected` ๋ฒํผ ์ฌ๋ฌ ๊ฐ๋ฅผ ๋๋ํ ๋์ด ํ๋ ๊ณ ๋ฅด๊ธฐยท์ฌ๋ฌ ๊ฐ ๊ณ ๋ฅด๊ธฐยท์ผ๊ณ ๋๊ธฐ๋ฅผ ํ๋ด ๋ด์ง ์๋๋ค. ๊ทธ ์๋๋ [์ ํ ์กฐ๋ฆฝ ๊ท์น](../SELECTION.md#์กฐ๋ฆฝ-๊ท์นํ์)์ SegmentedControlยทRadioGroupยทChipยทSwitch๋ฅผ ์ด๋ค.
|
|
137
137
|
|
|
@@ -150,8 +150,7 @@ WebยทNative์ ๋ผ์ดํธยท๋คํฌ ํ
๋ง์ ๋์ผํ๊ฒ ์ ์ฉํ๋ค.
|
|
|
150
150
|
|
|
151
151
|
- footer ์์๋ฅผ ๋ชจ๋ ๋ณธ๋ฌธ ํ๋์ ๊ฐ์ ํ์ง ์๋๋ค. ์๊ฐ ์ ํ์ฒ๋ผ ์ฃผ ํ๋ ๋ค์์ ์ด๊ธฐํ๊ฐ ์ค๋ ๊ตฌ์ฑ๊ณผ AlertDialog์ ์ข์ ํญ ์์๋ ๊ฐ๊ฐ ๋ช
์๋ ๊ตฌ์ฑ ๊ณ์ฝ์ ๋ฐ๋ฅธ๋ค.
|
|
152
152
|
|
|
153
|
-
`selected
|
|
154
|
-
contentBrand ๊ธ์ยท์์ด์ฝ ์์ ์ ์งํ๋ฉฐ ํค๋ณด๋ focus outline์ ์ ํ๊ณผ ๋ณ๋๋ก ์ ์งํ๋ค.
|
|
153
|
+
2026-10-28 ์ฌ์ฉ์ ์ง์: `selected`๋ก ๋ฐฐ๊ฒฝ์์ ๋ฐ๊พธ์ง ์๋๋ค. ์๋ tone์ ๋ฐฐ๊ฒฝยทํ
๋๋ฆฌ๋ฅผ ์ ์งํ๊ณ ์ ํ ํ
๋๋ฆฌ๋ฅผ ์ถ๊ฐํ์ง ์๋๋ค. ghost๋ ํฌ๋ช
ํ๊ฒ ๋จ์ผ๋ฉฐ primaryยทdanger์ ์ฑ์๊ณผ ์ญ์ ๊ธ์์๋ ์ ์งํ๋ค. ์ ํ์ ์ ๊ฒฝ์ยท์ฑ์ด ์์ด์ฝ ๋๋ ์ํ ๋ผ๋ฒจ๋ก ํํํ๋ฉฐ `aria-pressed`/Native ์ ๊ทผ์ฑ ์ํ์ ํค๋ณด๋ focus outline์ ์ ์งํ๋ค. ๊ฝ ๋ฐ์์ ์ ํ ๋ฉด์ด ์ค๋ณต์ผ๋ก ์๊ธด ์ฌ๋ก ๋๋ฌธ์ ๊ธฐ์กด ์ ํ ๋ฐฐ๊ฒฝ ์ง์นจ์ ๋์ฒดํ๋ค. IconButton๋ ๊ฐ์ ๊ท์น์ ์ด๋ค.
|
|
155
154
|
|
|
156
155
|
## ์ ์ฅ ํ์ ๋ผ๋ฒจ๊ณผ ํ๋ ์ ์์ฝ (npm 1.21.0 ยท 2026-10-15)
|
|
157
156
|
|
|
@@ -237,3 +236,5 @@ import { ButtonLink } from "@hjmds/react/actions";
|
|
|
237
236
|
2026-10-20 ๋ค์๋ฆฌ์ ์ง๋/์ฅ์ ์ด๋์์ ์ด์ ๋ณดํธยท์คํ๋ผ์ธ ์ฐจ๋จ์ ์ ์งํ๊ธฐ ์ํด ์ถ๊ฐํ๋ค.
|
|
238
237
|
์ ๋ฌ๋ฐ์ anchor props์ `ref`๋ฅผ ์ค์ ๋งํฌ์ ๊ทธ๋๋ก ์ฐ๊ฒฐํ๋ฉฐ, `href`๊ฐ ์์ผ๋ฉด ๋ด๋ถ ๋ผ์ฐํ
๋ ํ์ง ์๋๋ค.
|
|
239
238
|
๋ฒํผ์ ์/ํฌ๊ธฐ/์ด์ /๋นํ์ฑยท์์ ํค/์ ํญ ์๋ฏธ๋ HJM์ด ์์ ํ๊ณ ์ ํ์ ๋ชฉ์ ์งยท์ด๋ ์ฒ๋ฆฌ๋ฅผ ์ฐ๊ฒฐํ๋ค.
|
|
239
|
+
|
|
240
|
+
์ ํ recipe ์ง์ ์๋น์ ๋ณ๊ฒฝ: `states.selected`๋ ์ ๊ฒฝ๋ง ์์ ํ๋ฉฐ ๋ฐฐ๊ฒฝยทํ
๋๋ฆฌ๋ `tones[tone]`์์ ์ฝ๋๋ค. ํ๋ ์ ๊ฑฐ๋ ๋ค์ contracts major ๊ฒ์ ๋์์ผ๋ก ๊ธฐ๋กํ๋ฉฐ ์ปดํฌ๋ํธ์ `selected` ์ฌ์ฉ๋ฒ์ ๋์ผํ๋ค.
|
|
@@ -116,6 +116,7 @@ import { BarChart, Sparkline } from "@hjmds/react-native/chart";
|
|
|
116
116
|
| `focusIndex` | `number \| null` | โ | ์ ์ด ํฌ์ปค์ค |
|
|
117
117
|
| `defaultFocusIndex` | `number \| null` | ๋ง์ง๋ง ๊ด์ธก index | ๋น์ ์ด ์์ ํฌ์ปค์ค |
|
|
118
118
|
| `onFocusChange` | `(index: number \| null, detail: { scrubbing: boolean }) => void` | โ | ์คํฌ๋ฝ ์ค `scrubbing: true`, ์์ ๋ผ๋ฉด `false` |
|
|
119
|
+
| `showFocusLabel` | `boolean` | `false` | LineChartยทBarChart์์ ๋๋ฆ์ ๋์ ๋ค์๋ ์ ํํ ์ ์ ๋งํ์ ์ ์ง (2026-10-29 ๊ธฐ๋ก ์ฐจํธ ์์ฒญ) |
|
|
119
120
|
| `cursorLabel` | `(index: number) => string` | `categories[index]` | ์คํฌ๋ฝ ์ค ์ปค์ ์ ๋งํ์ |
|
|
120
121
|
|
|
121
122
|
### BarChart
|
|
@@ -65,10 +65,12 @@ import { CommentThreadRow } from "@hjmds/react-native/screen-flows";
|
|
|
65
65
|
| `id`ยท`parentId`ยท`author`ยท`body`ยท`timeLabel`ยท`likeCountLabel`ยท`likeIcon`ยท`likeLabel` | ํ์ | `parentId`๊ฐ `null`์ด๋ฉด ์ต์์ ๋๊ธ |
|
|
66
66
|
| `bodyText` | ์์ | ์ฃผ๋ฉด `author`์ ๋ณธ๋ฌธ์ ํ ๋ฌธ์ฅ์ผ๋ก, ์๊ฐ์ ์๋ ํ๋ ์ค๋ก ์ฎ๊ธด๋ค |
|
|
67
67
|
| `timePlacement` | `"auto"` | ๋ฏธ๊ฒ์. `"auto"`๋ `bodyText`๊ฐ ์์ผ๋ฉด ์๊ฐ์ ์์ฑ์ ์์ ๋๋ค. `"actions"`๋ ๊ธ์ด ์๋ ๋ณธ๋ฌธ(๊ฝ ๋์ฅยท์นด๋)์์๋ ์๊ฐ์ ๋ณธ๋ฌธ ์๋ ๋ฐ์ ์์ฝยท๋ต๊ธ๊ณผ ๊ฐ์ ์ค ๋งจ ์์ผ๋ก ์ฎ๊ธด๋ค |
|
|
68
|
+
| `textActions` | ์์ | ๋ฏธ๊ฒ์. ๋ต๊ธ ์ค์ ๋ต๊ธ ๋ค์ ๋ถ๋ ์ ํ ๋ฌธ๊ตฌ ํ๋ `{ id, label, onPress, disabled? }[]`. ๋ต๊ธ๊ณผ ๊ฐ์ muted caption ๋ฌธ๊ตฌ ๋ฒํผ์ด๋ฉฐ ์์๋๋ก ๋์ธ๋ค(์: ๋ฒ์ญ ๋๊ธ์ "์๋ณธ ๋ณด๊ธฐ"/"๋ฒ์ญ ๋ณด๊ธฐ"). ๋ฌธ๊ตฌยท์ํ๋ ์ ํ์ด ์์ ํ๋ค |
|
|
68
69
|
| `panel` | ์์ | ๋ฏธ๊ฒ์. ๋๊ธ๋ณ ์ธ๋ผ์ธ ํจ๋(์์ ยท์ ๊ณ ยท์ฐจ๋จ ์์). ๋ต๊ธ ์ค ์๋, ๊ธธ๊ฒ ๋๋ฅด๊ธฐ ๋์ ๋ฐ์ `panelGap` 8 ๊ฐ๊ฒฉ์ผ๋ก ๋์ธ๋ค. ์ด๋ฆผ ์ํยท์ด์ ยท์ ์ถยท๋ซ๊ธฐ๋ ์ ํ์ด ์์ ํ๋ค |
|
|
69
70
|
| `mediaAlbum` | ์์ | ๋ฏธ๊ฒ์. ํ ์ฅ์ฉ ๋๊ธฐ๋ ์ฌ์ง ๋ฌถ์ `{ count, renderPage(index), pageLabel(index, count), previousLabel, nextLabel, aspectRatio?, onPress?(index), index?ยทonIndexChange?ยทdefaultIndex? }`. `renderPage`๋ ํ๋ฉด์ ๋ณด์ด๋ ์ฅ์๋ง ํธ์ถ๋์ด ์ ํ์ด ๊ทธ ์ฌ์ง๋ง ์กฐํยท๋์ฝ๋ฉํ๋ค. ๋ถ๋ฌ์ค๋ ์คยท์คํจ ์ฅ์ `MediaAlbumPageStatus`(`@hjmds/react(-native)/screens`, [ChatMessage](chat-message.md#์ถ๊ณผ-๊ธฐ๋ณธ๊ฐ))๋ก ๊ทธ๋ ค ์์ชฝ ๋ด์ฉ์ด ๋ญ๋
๊ธฐ์ ๋ฟ๊ฒ ํ๋ค. `media`์ ํจ๊ป ์ฃผ๋ฉด `TypeError`. ๋ณธ๋ฌธ ์๋, ๊ธธ๊ฒ ๋๋ฅด๊ธฐ ๋์ ๋ฐ์ ๋์ธ๋ค |
|
|
70
71
|
| `authorBadge` | ์์ | ๋ฏธ๊ฒ์. ๋๋ค์ ๋ฐ๋ก ๋ค, ๊ฐ์ ์ค์ ๋๋ ์ ํ ๋ฐฐ์ง. ๊ฐ๊ฒฉ `spacing.xxs` 4, ์ข์ ํญ์์๋ ์ค๋ฐ๊ฟํ๋ค. `bodyText` ๋ชจ๋์์๋ ์์ฑ์ยท๋ฐฐ์งยท๋ณธ๋ฌธ ์์๋ก ๋ฐฐ์นํ๋ค. ๋ฐฐ์ง ๋ฌธ๊ตฌยท๋
ธ์ถ ์กฐ๊ฑด์ ์ ํ์ด ์์ ํ๋ค |
|
|
71
72
|
| `avatar` | ์์ | ์ ํ ์๋ฐํ. ์ต์์ 32ยท๋ต๊ธ 24 ํญ ์นธ์ ๋๋ค |
|
|
73
|
+
| `avatarAction` | ์์ | ํ์ ํ๋กํ ์ด๋ `{ label, onPress, disabled? }`. ์ฌ์ง๊ณผ **์์ฑ์ ์ด๋ฆ**์ด ๊ฐ์ ํ๋์ ์ด๋ค(์ด๋ฆ์ 2026-10-29๋ถํฐ, [Avatar ์ง์นจ](avatar.md#ํ์-ํ๋กํ-์ด๋-2026-10-25)) |
|
|
72
74
|
| `canReply` | `parentId === null` | ๋ต๊ธ ํ๋ ํ์ ์ฌ๋ถ |
|
|
73
75
|
| `replyDisabled` | false | ๋ต๊ธ ํ๋ ๋นํ์ฑ |
|
|
74
76
|
| `likeAction`ยท`actions` | ์์ | ๊ธฐ๋ณธ ์ข์์ ๋ฒํผ ๋์ฒดยท์์ ์ถ๊ฐ |
|
|
@@ -92,7 +94,7 @@ import { CommentThreadRow } from "@hjmds/react-native/screen-flows";
|
|
|
92
94
|
|
|
93
95
|
- ๊ฐ์ํ host์์ ํ ์ฌ์ด ๊ฐ๊ฒฉ(`commentThreadRecipe.rowGap`)๊ณผ ๋ต๊ธ ๋ค์ฌ์ฐ๊ธฐ(`replyIndent`)๋ฅผ ์ง์ ์ค ๋๋ recipe ๊ฐ์ ์ด๋ค. ์ ํ ์ซ์๋ก ๋ค์ ์ ํ์ง ์๋๋ค.
|
|
94
96
|
- ๋ต๊ธ ํผ์น๊ธฐยท์ ๋ ฌยท๊ถํยท์ข์์ ์ ์ฅ์ ์ ํ์ด ์์ ํ๋ค. ํ์ ์ฝ๋ฐฑ๋ง ํธ์ถํ๋ค.
|
|
95
|
-
- ํ ์์ ๋ ๋ฒ์งธ ๋ ์ด์์์ ๋ง๋ค์ง ๋ง๊ณ `actions`ยท`likeAction`ยท`media`ยท`mediaAlbum`ยท`panel` ์ฌ๋กฏ์ผ๋ก ์ถ๊ฐํ๋ค. ์๊ฐยท๋ต๊ธ ์ค์ ๋ณธ๋ฌธ ๋
ธ๋ ์์ ๋ค์ ๊ทธ๋ฆฌ์ง ๋ง๊ณ `timePlacement: "actions"`์ `canReply`๋ฅผ ์ด๋ค.
|
|
97
|
+
- ํ ์์ ๋ ๋ฒ์งธ ๋ ์ด์์์ ๋ง๋ค์ง ๋ง๊ณ `actions`ยท`likeAction`ยท`media`ยท`mediaAlbum`ยท`panel` ์ฌ๋กฏ์ผ๋ก ์ถ๊ฐํ๋ค. ์๊ฐยท๋ต๊ธ ์ค์ ๋ณธ๋ฌธ ๋
ธ๋ ์์ ๋ค์ ๊ทธ๋ฆฌ์ง ๋ง๊ณ `timePlacement: "actions"`์ `canReply`๋ฅผ ์ด๋ค. ๋ต๊ธ ์ ๋ฌธ๊ตฌ ํ๋๋ ๋ณธ๋ฌธ์ ๋ฒํผ์ ๋์ง ๋ง๊ณ `textActions`๋ก ์ค๋ค.
|
|
96
98
|
- `mediaAlbum`์ ์ฌ์ง ์กฐํยท๊ถํ ํ์ธยท์บ์ ์๋ช
์ ์ ํ์ด `renderPage` ์์์ ์์ ํ๋ค. HJM์ ๋ณด์ด๋ ์ฅ๋ง ๋ง์ดํธํ๊ณ ๋๊น ์ํ๋ฅผ ํ ์์ ๋๋ค(์ ์ดํ์ `index`+`onIndexChange`).
|
|
97
99
|
|
|
98
100
|
## ์ํ์ ์ํธ์์ฉ
|
|
@@ -106,6 +108,7 @@ import { CommentThreadRow } from "@hjmds/react-native/screen-flows";
|
|
|
106
108
|
- 2026-10-20 Spint์ โ๋โ ๋ฐฐ์ง๊ฐ ๋ณธ๋ฌธ ์ฒซ ์ค์ ์ฐจ์งํ๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด `authorBadge` ์ฌ๋กฏ์ ์ถ๊ฐํ๋ค. ์์ฑ์์ ๋ถ๋ ํ์๋ HJM์ด ๋๋ค์ ์์ ๋ฐฐ์นํ๊ณ ์ ํ์ ๋ฐฐ์ง ๋ด์ฉ๋ง ๊ณต๊ธํ๋ค. ๊ฐ๋ฐ ์์ค ๋ณ๊ฒฝ์ด๋ฉฐ ๋ฏธ๊ฒ์๋ค.
|
|
107
109
|
|
|
108
110
|
- 2026-10-20 Spint ๋๊ธ์ด ์ด์ดํ๋ค๋ ์ฌ์ฉ์ ํผ๋๋ฐฑ์ ๋ฐ๋ผ ๊ณตํต ํ ์ฌ์ด ๊ฐ๊ฒฉ์ 12โ20, ๋ด๋ถ ์ค ์ฌ์ด ๊ฐ๊ฒฉ์ 2โ4๋ก ์กฐ์ ํ๋ค. WebยทNative๊ฐ ๊ฐ์ recipe๋ฅผ ์ฌ์ฉํ๋ค. ๊ฐ๋ฐ ์์ค ๋ณ๊ฒฝ์ด๋ฉฐ ๋ฏธ๊ฒ์๋ค.
|
|
111
|
+
- `textActions`: 2026-10-29 Spint ๋๊ธ ๋ฒ์ญ. ์ฌ์ฉ์๊ฐ Instagram์ฒ๋ผ "๋ต๊ธ ๋ฌ๊ธฐ" ์์ "์๋ณธ ๋ณด๊ธฐ"/"๋ฒ์ญ ๋ณด๊ธฐ"๋ฅผ ๋๋ผ๊ณ ์์ฒญํ๋๋ฐ, ๋ต๊ธ ์ค์ ์ ํ ํ๋ ์๋ฆฌ๊ฐ ์์ด ๋ณธ๋ฌธ ์๋ ๋ณ๋ ์ค๋ก ๊ทธ๋ฆฌ๊ณ ์์๋ค.
|
|
109
112
|
- `timePlacement`ยท`panel`ยท`mediaAlbum`: 2026-10-18 HJM 1.30.0 ์ฑํ ๊ฐ์ฌ. Spint๋ ๊ฝ ๋์ฅ ๋ณธ๋ฌธ์์ ์๊ฐ์ ๋ต๊ธ ์ค์ ๋๋ ค๊ณ ์๊ฐยท๋ต๊ธ ํ์ ๋ณธ๋ฌธ ์์ ๋ค์ ๊ทธ๋ ธ๊ณ , Utilverse๋ ์์ ยท์ ๊ณ ยท์ฐจ๋จ ์์์ ๋ณธ๋ฌธ ๋
ธ๋ ์(๊ธธ๊ฒ ๋๋ฅด๊ธฐ ๋์ ์)์ ๋ฃ์์ผ๋ฉฐ, ์ฌ์ง ๋ฌถ์์ ์ ํํ ์ฅ๋ง ์กฐํํ๋ ์ ํ ์จ๋ฒ์ ๋ฐ๋ก ๋ง๋ค์๋ค.
|
|
110
113
|
|
|
111
114
|
## ํ๋ซํผ ์ฐจ์ด
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
- ์ํ: ๋ฐฐํฌ
|
|
5
5
|
- ์ง์: Web ยท Native
|
|
6
6
|
- ์ ์ฉ: 1.12.1
|
|
7
|
-
- ๊ฒํ ์ผ: 2026-10-
|
|
7
|
+
- ๊ฒํ ์ผ: 2026-10-28
|
|
8
8
|
- ๊ทผ๊ฑฐ: [DateRange](../../date-range.md), ๊ฒฉ์๋ [Calendar](../../calendar.md), ๊ท์น ํจ์ `src/date-range.ts`
|
|
9
9
|
- ์คํ ๋ฆฌ๋ถ: `๋ฐฐํฌ/์ปดํฌ๋ํธ/์
๋ ฅ/๊ธฐ๊ฐ ์ ํ`
|
|
10
10
|
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
| --- | --- |
|
|
21
21
|
| ๋ ์ง ํ๋ | [DatePicker](date-picker.md) |
|
|
22
22
|
| ๋ฌ๋ ฅ์ ๋ณด์ฌ ์ฃผ๊ธฐ๋ง ํ๊ฑฐ๋ ๋ ์ง ํ๋๋ฅผ ์ธ๋ผ์ธ์ผ๋ก ๊ณ ๋ฆ | [Calendar](calendar.md) |
|
|
23
|
-
|
|
|
23
|
+
| ์ค๋ฒ๋ ์ด์์ ๊ณ ๋ฅด๊ณ ์ ์ฉ ๋ฒํผ์ผ๋ก ํ์ | [Sheet](sheet.md) ์์ ํฉ์ฑํ๊ณ `footer`์ `BottomCTA`๋ฅผ ๋๋ค. ๋ณธ๋ฌธ ์์์ ์ ์ด ๋๊ธฐ๋ง ํ๋ฉด `collapsible`์ ์ด๋ค |
|
|
24
24
|
|
|
25
25
|
## ๊ณต๊ฐ ์ด๋ฆ๊ณผ import
|
|
26
26
|
|
|
@@ -80,7 +80,8 @@ import { DateRangePicker } from "@hjmds/react-native/date-range";
|
|
|
80
80
|
| `previousMonth` ยท `nextMonth` | `{ month: string, label: string }` | โ | ์์ผ๋ฉด ์ด๋ ๋ฒํผ์ด ์๋ค |
|
|
81
81
|
| `renderCellContent` | `(date: string) => ReactNode` | โ | ๋ ์ง ์๋ ๋ณด์กฐ ํ์. ๋๊ธธ ๋๋ง ํ์ ๋ณด์กฐ ์ค์ด ์๊ธด๋ค |
|
|
82
82
|
| `summary` | `{ startLabel, endLabel, placeholder, formatDate(date) }` | โ | ๊ฒฉ์ ์ ์์์ผยท์ข
๋ฃ์ผ ์นธ. ์ง๊ธ ๊ณ ๋ฅด๋ ์ชฝ(`resolveDateRangeActiveEdge`: ๋น์์ผ๋ฉด ์์, ๊ณ ๋ฅด๋ ์ค์ด๋ฉด ๋, ์์ฑ๋๋ฉด ์์)์ ํ
๋๋ฆฌ๋ก ํ์ํ๋ค. ๋ฌธ๊ตฌ๋ i18n, ๋ ์ง ํ์์ ์ ํ ์์ |
|
|
83
|
-
| `presets` | `{ id, label, length: { days } \| { months } }[]` | โ | ์์ฝ ์๋ ๋จ์ผ ์ ํ Chip
|
|
83
|
+
| `presets` | `{ id, label, length: { days } \| { months } \| { all: true } }[]` | โ | ์์ฝ ์๋ ๋จ์ผ ์ ํ Chip ์ค. `days`ยท`months`๋ `grid.todayDate`๋ก ๋๋๊ณ `all`์ ๋น ๊ตฌ๊ฐ(๋ ์ง ์ ํ ์์)์ด๋ค(`resolveDateRangePreset`). ๊ฐ์ด ๊ทธ ๊ตฌ๊ฐ๊ณผ ๊ฐ์ ๋๋ง ์ ํ์ผ๋ก ๋ณด์ธ๋ค. ๋๋ฅด๋ฉด ๋ ๋ฌ๋ก `onFocusedMonthChange(month, "jump")`๋ฅผ ์์ฒญํ๋ค(`all` ์ ์ธ). ๊ธฐ๊ฐ ํํฐ์ ํ์ค ์นฉ์ `dateRangeRecipe.presets.standard`(1์ผยท1์ฃผ์ผยท1๊ฐ์ยท3๊ฐ์ยท์ ์ฒด)์ด๊ณ ๋ฌธ๊ตฌ๋ ์ ํ i18n์ด๋ค |
|
|
84
|
+
| `collapsible` | `{ expanded?, defaultExpanded?, onExpandedChange? }` | ์์(๋ ํผ์นจ) | ์ฃผ๋ฉด ๊ฒฉ์๋ง `summary` ๋ค๋ก ์ ๊ณ `presets`๋ ๊ณ์ ๋ณด์ธ๋ค. `summary`๊ฐ ํ์์ด๊ณ (์์ผ๋ฉด `TypeError`) ๊ทธ ์ค์ด ํผ์นจ ๋ฒํผ(`aria-expanded`ยทNative `expanded` ์ํ, ๋์ ์๋/์ ํ์ดํ)์ด ๋๋ค. ์ ํ ์ฑ ์์ํ๊ณ (`defaultExpanded` ๊ธฐ๋ณธ `false`), ํ๋ฆฌ์
์ ๋๋ฅด๊ฑฐ๋ ๋ ์ง ํญ์ผ๋ก ๊ตฌ๊ฐ์ด ์์ฑ๋๋ฉด ๋ค์ ์ ๋๋ค(`resolveDateRangeExpandedAfterSelection`) |
|
|
84
85
|
| Web `layoutStyle` | ๋ฐฐ์น ์ ์ฉ style | โ | ๋ฃจํธ ๋ฐฐ์น |
|
|
85
86
|
|
|
86
87
|
## ๋ฐฐ์น
|
|
@@ -98,6 +99,7 @@ import { DateRangePicker } from "@hjmds/react-native/date-range";
|
|
|
98
99
|
| ์ | ๋ `primary` 15% tint(๋ ๋๊ณผ ๊ฐ์ ๋ธ๋๋์. ์ฒ์ ์ด `surfaceSelected`๋ ๊ธฐ๋ณธ ํ๋ ํธ์์ #f0f1f3 ํ์์ด๋ผ ๊ตฌ๊ฐ์ด ๊ฑฐ์ ๋ณด์ด์ง ์์๋ค), ๋ ๋ Calendar ์ ํ ์(`action.brand`). ์นธ ๋ฐํ `surface.sunken`, ๋ค์์ ๊ณ ๋ฅผ ์นธ ํ
๋๋ฆฌ 2 `action.brand`, ๋น ๊ฐ `content.tertiary` | `dateRangeRecipe` |
|
|
99
100
|
| ์์ยท์ ๋ ฌ | ์ค๋ฒ๋ ์ด ์์ด ๋ณธ๋ฌธ(ํผยทํํฐ ์์ญยท[Section](section.md)) ์์ ๊ฒฉ์๋ฅผ ํผ์ณ ๋๋ค. ์์์ `summary`(์์์ผ ยท ์ข
๋ฃ์ผ) โ `presets` ์นฉ ์ค โ ์ ๋จธ๋ฆฌ(์ด์ ยท ์ ์ด๋ฆ ยท ๋ค์) โ ์์ผ โ ๋ ์ง ๊ฒฉ์. ์ ์ถ ํ๋์ ๊ฒฉ์ **์๋**์ ๋๋ค. ์ํธ์์๋ `footer`์ `BottomCTA` [๋ณด์กฐ(์ ์ฒด ๋ ์ง ๋ฑ)][์ฃผ(์ ์ฉ)] ํ ์ค๋ก ๋๊ณ ์ํธ ๋์ด๋ `auto`๋ก ๋ง์ถ๋ค. `summary`๋ฅผ ์ฐ๋ฉด ๋ณ๋ ์๋ดยท๊ฒฐ๊ณผ ๋ฌธ์ฅ์ ๋์ง ์๋๋ค. ์ ์ถ ๋ฒํผ์ `isCompleteDateRange(value)`๊ฐ ์ฐธ์ผ ๋๋ง ํ์ฑ์ด๋ค | ๊ฐ์ ํ์ผ |
|
|
100
101
|
| ๊ณ ์ ยท์คํฌ๋กค | ๋ณธ๋ฌธ๊ณผ ํจ๊ป ์คํฌ๋กคํ๋ค(์ค๋ฒ๋ ์ด ์์) | โ |
|
|
102
|
+
| ์ ๊ธฐ | `collapsible`์ด๋ฉด ์์ฝ ๋ ์นธ ๋ค์ ํ์ดํ ์ด(`dateRangeRecipe.toggle`: ์์ด์ฝ `glyph.sm` 20, ์นธ๊ณผ ๊ฐ๊ฒฉ `spacing.xs` 8)์ด ๋ถ๊ณ ์์ฝ ์ค ์ ์ฒด๊ฐ ๋ฒํผ์ด๋ค. ์ ํ๋ฉด ์์ฝ๊ณผ ํ๋ฆฌ์
์นฉ ์ค๋ง ๋จ๊ณ ๊ฒฉ์๋ ๊ทธ๋ฆฌ์ง ์๋๋ค. ๊ฒ์ ํ๋๊ฐ ์์ผ๋ฉด ๊ทธ ์๋์ ์์ฝ โ ์นฉ โ (ํผ์ณค์ ๋) ๊ฒฉ์ ์์๋ก ๋๋ค | `dateRangeRecipe.toggle`, `.hjm-date-range__summary[data-toggle]` |
|
|
101
103
|
| ์ข์ ํญยทํฐ ๊ธ์ | Web ๊ฒฉ์ ์ต์ ํญ 308๋ณด๋ค ์ข์ ์ปจํ
์ด๋์ ๋์ง ์๋๋ค | `packages/react/src/styles.css` `.hjm-calendar__grid` |
|
|
102
104
|
|
|
103
105
|
## ๊ผญ ์งํฌ ๊ฒ
|
|
@@ -107,6 +109,10 @@ import { DateRangePicker } from "@hjmds/react-native/date-range";
|
|
|
107
109
|
- `rangeLabels`์ ์
์ด๋ฆ(`composeAccessibleName`)์ i18n ํค๋ก ๋ง๋ ๋ค. ๊ตฌ๊ฐ ์์น ์ ๋ฏธ์ฌ๋ ์ปดํฌ๋ํธ๊ฐ
|
|
108
110
|
์
์ด๋ฆ ๋ค์ `, `๋ก ๋ถ์ธ๋ค.
|
|
109
111
|
- ๋ฌ์ ๋๊ธฐ๋ฉด ์ ํ์ด ์ ๋ฌ์ `cells`์ `monthLabel`์ ๋ค์ ๋ง๋ค์ด ๋๊ธด๋ค.
|
|
112
|
+
- ํํฐ์ฒ๋ผ ๊ณ ๋ฅธ ๊ธฐ๊ฐ์ ๋ฐ๋ก ๋ฐ์ํ๋ ์๋ฆฌ์์๋ `collapsible`๊ณผ ํ์ค ํ๋ฆฌ์
(1์ผยท1์ฃผ์ผยท1๊ฐ์ยท3๊ฐ์ยท์ ์ฒด)์ ์ฐ๊ณ ,
|
|
113
|
+
๋น ๊ฐ(์ ์ฒด)์ ๊ธฐ๋ณธ์ผ๋ก ๋๋ค. [์ ์ฒดยท์ค๋ยท๊ธฐ๊ฐ ์ง์ ] ๊ฐ์ ๋ณ๋ ํญ์ ์์ ๊ฒน์ณ ๋์ง ์๋๋ค. ํ๋ฆฌ์
๊ณผ ๊ฐ์ ์ ํ์ ๋ ๋ฒ ํ๋ค.
|
|
114
|
+
2026-10-28 ์ฌ์ฉ์ ์์ฒญ: ๋ค์๋ฆฌ ๋ง๋ ๋๋ฌผ ํํฐ์์ ๊ธฐ๊ฐ์ ๊ณ ๋ฅธ ๋ค์๋ ๋ฌ๋ ฅ์ด ๋ ํผ์ณ์ ธ ๋ชฉ๋ก์ ๋ฐ์ด๋๊ณ , ํญ๊ณผ ํ๋ฆฌ์
์ด ๊ฒน์ณค๋ค.
|
|
115
|
+
- ์ ์ฉ ๋ฒํผ์ด ์๋ ์ํธ์์๋ `all` ์นฉ ๋์ `BottomCTA` ๋ณด์กฐ ํ๋(์ ์ฒด ๋ ์ง)์ ๋๋ค. ์ ์ฉ ๋ฒํผ์ ์์ฑ๋ ๊ตฌ๊ฐ์์๋ง ์ผ์ง๋ค.
|
|
110
116
|
|
|
111
117
|
## ํ๋ซํผ ์ฐจ์ด
|
|
112
118
|
|
|
@@ -80,14 +80,13 @@ import { NotificationBell } from "@hjmds/react-native/notification-bell";
|
|
|
80
80
|
### ์์ด์ฝ ๋งํฌ โ `IconButtonLink` (2026-10-23, ๊ฐ๋ฐ ์์คยท๋ฏธ๊ฒ์)
|
|
81
81
|
|
|
82
82
|
Button์ ๋ํ ButtonLink์ฒ๋ผ IconButton ํ(`tone`ยท`size`ยท`shape`ยท`edge`ยท`hitSlop`ยท`layoutStyle`)์ ์ด๋ ๋งํฌ์ ์ด๋ค.
|
|
83
|
-
ํ ๊ธยท๋ก๋ฉยท๋ณ๊ฒฝ ํ๋์ IconButton์ ๋จ๋๋ค. `current`๋ ์ง๊ธ ๋ณด๊ณ ์๋ ํ๋ฉด์ ์ง์
์ ์ด๋ฉฐ ์ ํ๋ IconButton๊ณผ
|
|
84
|
-
(`iconButtonRecipe.states.selected`)์ผ๋ก ์น ํ๊ณ Web `aria-current="page"`, Native `accessibilityState.selected`๋ก ์๋ฆฐ๋ค.
|
|
83
|
+
ํ ๊ธยท๋ก๋ฉยท๋ณ๊ฒฝ ํ๋์ IconButton์ ๋จ๋๋ค. `current`๋ ์ง๊ธ ๋ณด๊ณ ์๋ ํ๋ฉด์ ์ง์
์ ์ด๋ฉฐ ์ ํ๋ IconButton๊ณผ ๊ฐ์ด ๊ธฐ์กด tone์ ๋ฐฐ๊ฒฝ์ ์ ์งํ๊ณ Web `aria-current="page"`, Native `accessibilityState.selected`๋ก ์๋ฆฐ๋ค.
|
|
85
84
|
|
|
86
85
|
| prop | Web | Native | ๊ธฐ๋ณธ๊ฐ |
|
|
87
86
|
| --- | --- | --- | --- |
|
|
88
87
|
| ๋ชฉ์ ์ง | `href: string` | `destination: LinkDestination` | ํ์ |
|
|
89
88
|
| ์ด๋ฆ | `label: string`(์ ๊ทผ์ฑ ์ด๋ฆ, ๋น ๊ฐ์ด๋ฉด `TypeError`) | ๊ฐ์ | ํ์ |
|
|
90
|
-
| `current` | `boolean` โ `aria-current="page"` +
|
|
89
|
+
| `current` | `boolean` โ `aria-current="page"` + ๊ธฐ์กด ๋ฐฐ๊ฒฝ ์ ์ง | `boolean` โ `selected` + ๊ธฐ์กด ๋ฐฐ๊ฒฝ ์ ์ง | `false` |
|
|
91
90
|
| `disabled` | `href`๋ฅผ ์ง์ฐ๊ณ ํด๋ฆญยท๊ฐ์ด๋ฐ ํด๋ฆญ์ ๋ง๋๋ค(ButtonLink์ ๊ฐ๋ค) | ๋๋ฆ์ ๋ง๋๋ค | `false` |
|
|
92
91
|
| router ์ฐ๊ฒฐ | `renderAnchor(props)` โ `ref`ยท`href`ยท์ด๋ฆยท`aria-current`ยท์ฐจ๋จ ํธ๋ค๋ฌ๊ฐ ๋ด๊ธด props๋ฅผ ์๊ธฐ ๋งํฌ์ ํผ์น๋ค | `onNavigate(destination)` ๋๋ `renderLink(props)`(TopBarAction `intent="link"`์ ๊ฐ๋ค). ๋ ๋ค ์์ผ๋ฉด `TypeError` | โ |
|
|
93
92
|
|
|
@@ -124,7 +123,7 @@ Client Component์์ ์ฐ๊ฒฐํ๋ค.
|
|
|
124
123
|
| `size` | `small` 36 ยท `medium` 44 ยท `large` 52 | `medium` | `small`์ ํฐ์น ์ฌ๋ฐฑ 4 ์ถ๊ฐ. ์์ด์ฝ ํฌ๊ธฐ๋ ๊ฐ๊ฐ `sm`ยท`md`ยท`lg` |
|
|
125
124
|
| `shape` | `rounded` ยท `circle` | `rounded` | โ |
|
|
126
125
|
| `elevation` | `none` ยท `raised` ยท `floating` ยท `overlay` | `none` | ๋ ์๋ ์ปจํธ๋กค(๋ฒ๋ Dock ๊ฐ์ด๋ฐ ๋ฒํผ)์ ๊ทธ๋ฆผ์ ํ ํฐ ๋จ๊ณ(`iconButtonRecipe.elevation`). `primary`ยท`secondary`ยท`danger`๋ง ๋ฐ๊ณ `ghost`์ ์ฃผ๋ฉด `TypeError`. Web์ `--hjm-shadow-<๋จ๊ณ>`, Native๋ iOS ๊ทธ๋ฆผ์ + Android elevation. `IconButtonLink`์๋ ์๋ค(๋ฏธ๊ฒ์, 2026-10-23) |
|
|
127
|
-
| `selected` | `true` ยท `false` | โ | ์ฃผ๋ฉด ํ ๊ธ์ด ๋๋ค(Web `aria-pressed`, Native ์ ๊ทผ์ฑ state) |
|
|
126
|
+
| `selected` | `true` ยท `false` | โ | ์ฃผ๋ฉด ํ ๊ธ์ด ๋๋ค(Web `aria-pressed`, Native ์ ๊ทผ์ฑ state). ์ ํ ์ ํ tone ๋ฐฐ๊ฒฝ์ ์ ์งํ๋ค |
|
|
128
127
|
| `edge` | `start` ยท `end` ยท `both` | โ | ๋ฒํผ์ด ๋์ธ ์ปจํ
์ด๋ ๊ฐ์ฅ์๋ฆฌ(๋
ผ๋ฆฌ ๋ฐฉํฅ, RTL์์ ๋ค์งํ). `ghost`๋ฉด ํฐ์น ์์ญ์ ๊ทธ๋๋ก ๋๊ณ ๊ทธ ์ชฝ์ผ๋ก (๋ณด์ด๋ ์ง๋ฆ โ ์์ด์ฝ ์นธ) / 2๋งํผ ๋ด๋ฏผ๋ค(`medium` 10, `small` 8, `large` 12, `resolveIconButtonEdgeOverhang`). ํ
๋๋ฆฌยท๋ฐฐ๊ฒฝ์ด ์๋ tone์ ํ์ด ์ ๋ ฌ ๊ธฐ์ค์ด๋ผ ์์ง์ด์ง ์๋๋ค |
|
|
129
128
|
| `loading` | `true` ยท `false` | โ | ๋๋ฆ์ ๋ง๊ณ ์คํผ๋๋ก ๋ฐ๊พผ๋ค. Native๋ ๊ธฐ๋ณธ์ผ๋ก ํฌ์ปค์ค๋ฅผ ์ ์งํ๋ค(`disableWhileLoading`์ผ๋ก๋ง ์ ๋์) |
|
|
130
129
|
| `loading` ์ค `renderLoadingIndicator`(Native) | `(props: { color: string; size: "small" }) => ReactNode` | ๊ธฐ๋ณธ ์คํผ๋ | ์คํผ๋๋ฅผ ๋ฐ๊ฟ ๋๋ง |
|
|
@@ -187,8 +186,7 @@ TopBar
|
|
|
187
186
|
`tone="inverse"`๋ฅผ ์ค๋ค. ๋ค๋ฅธ ์์ด์ฝ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ปดํฌ๋ํธ๋ฅผ ์ง์ ๋ฃ์ผ๋ฉด(Native) ์์ ์ ํ์ด ๋๊ฒจ์ผ ํ๋ค.
|
|
188
187
|
- Native `IconButton`์ `style`์ ์ ๊ฑฐ๋์๋ค. ๋ฐฐ์น๋ `layoutStyle`, ์ธํ์ `tone`ยท`size`ยท`shape`๋ก ์ง์ ํ๋ค.
|
|
189
188
|
|
|
190
|
-
2026-10-
|
|
191
|
-
ํ์ํ๊ณ ์ถ๊ฐ ์ ํ ํ
๋๋ฆฌ๋ ์๋ค. aria-pressed/Native selected์ ํค๋ณด๋ focus outline์ ์ ์งํ๋ค.
|
|
189
|
+
2026-10-28 ์ฌ์ฉ์ ์ง์: **์ ํํด๋ ๋ฐฐ๊ฒฝ์์ ๋ฐ๊พธ์ง ์๋๋ค.** ButtonยทIconButtonยทํ์ฌ ๊ฒฝ๋ก์ธ IconButtonLink๋ ์๋ tone์ ๋ฐฐ๊ฒฝ๊ณผ ํ
๋๋ฆฌ๋ฅผ ์ ์งํ๋ค. ghost๋ ์ ํ ํ์๋ ํฌ๋ช
ํ๋ฉฐ primaryยทdanger๋ ์๋ ์ฑ์๊ณผ ๋๋น๋๋ ๊ธ์์์ ์ ์งํ๋ค. ์ ํ์ ๊ธ์ยท์์ด์ฝ์ ์ ๊ฒฝ ํํ ๋๋ ์ฑ์ด glyph๋ก ํ์ํ๋ค. Web `aria-pressed`/`aria-current`, Native `accessibilityState.selected`์ ํค๋ณด๋ focus outline์ ์ ์งํ๋ค. ์คํํธ ๊ฝ ๋ฐ์ ์ฃผ๋ณ์ ์ ํ ๋ฉด์ด ์ค๋ณต์ผ๋ก ์๊ธด ์ฌ๋ก๊ฐ ๊ณ๊ธฐ์ด๋ฉฐ 2026-10-10์ ์ ํ ๋ฐฐ๊ฒฝ ์ง์นจ์ ๋์ฒดํ๋ค. ์ ํ๋ณ ์ ๊ทผ์ฑ ์ํ ์ฐํ๋ ๋ฐฐ๊ฒฝ ๋ฎ์ด์ฐ๊ธฐ๋ฅผ ์ถ๊ฐํ์ง ์๊ณ `selected`๋ฅผ ๊ทธ๋๋ก ์ด๋ค.
|
|
192
190
|
|
|
193
191
|
## ๊ทผ๊ฑฐ
|
|
194
192
|
|
|
@@ -199,3 +197,5 @@ TopBar
|
|
|
199
197
|
์ปดํฌ๋ํธ๋ง๋ค ์คํ์
์ ๋ฐ๋ก ๋์ง ์๊ณ ์ด ํ ๊ท์น๊ณผ ๊ณ์ฝ ๊ฐ์ผ๋ก ๋ง์ท๋ค. Toast ๋ซ๊ธฐ(๊ฐ์ ๋ `toastRecipe.close.inlineOverhang`)์ ๊ฐ์ ์์ด๋ค.
|
|
200
198
|
- ๋๊ตฌ์ฑ ํ๋์ IconButton: 2026-10-17 ์ฌ์ฉ์ ์ง์ โ '๋์ ๊ธฐ๋ก' ํค๋์ ์๋ก๊ณ ์นจยท์ ๊ธฐ๋ก ๊ธ์ ๋ฒํผ.
|
|
201
199
|
- ์ ํ ํํ: 2026-10-10 ์ฌ์ฉ์ ์์ฒญ โ Button๊ณผ ๊ฐ์ ์ ํ ํํ์ ์ด๋ค.
|
|
200
|
+
|
|
201
|
+
๊ณต๊ฐ recipe ์ง์ ์๋น ์ `states.selected.background`ยท`border` ๋์ `tones[tone].background`ยท`border`๋ฅผ ์ฝ๋๋ค. ์ ํ recipe๋ ์ ๊ฒฝ๋ง ์์ ํ๋ค. ์ด recipe ํ๋ ์ ๊ฑฐ๋ ๋ค์ ๊ฒ์ ์ contracts์ major ๋ณ๊ฒฝ์ผ๋ก ๊ธฐ๋กํ๋ฉฐ ์ปดํฌ๋ํธ์ `selected`ยท`current` ์ฌ์ฉ๋ฒ์ ๋ฐ๊พธ์ง ์๋๋ค.
|
|
@@ -66,6 +66,13 @@ import { ImageViewer } from "@hjmds/react-native/image-viewer";
|
|
|
66
66
|
errorLabel={t("viewer.loadFailed")} retryLabel={t("common.retry")} />
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
+
### ์๋๋ก ๋์ด ๋ซ๊ธฐ (๊ธฐ๋ณธ ๋์, 2026-10-30)
|
|
70
|
+
|
|
71
|
+
๋ค๋ฅธ ์ฌ์ง ๋ทฐ์ด์ฒ๋ผ ํ๋ํ์ง ์์ ์ฌ์ง์ ์๋๋ก ๋๋ฉด `onClose`๊ฐ ๋ถ๋ฆฐ๋ค(์ฌ์ฉ์ ์์ฒญ). ์ฌ์ง์ด ์๊ฐ๋ฝ์ ๋ฐ๋ผ
|
|
72
|
+
๋ด๋ ค์ค๊ณ ์์๋ ์กฐ์๋ถ๊ฐ ํ๋ ค์ง๋ฉฐ, 120pt ์ด์ ๋๊ฑฐ๋ ๋น ๋ฅด๊ฒ ๋ด๋ฆฌ๋ฉด ๋ซํ๋ค. ์งง๊ฒ ๋๊ฑฐ๋ ์๋ก ๋๋ฉด ์ ์๋ฆฌ๋ก
|
|
73
|
+
๋์์จ๋ค. ํ๋ํ ์ฌ์ง์ ๋๋ฉด ์ด๋ํ๋ฏ๋ก ๋ซํ์ง ์๋๋ค. ์ ํ์ ๋ฐ๋ก ์ฐ๊ฒฐํ ๊ฒ์ด ์๊ณ , ๋ซ๊ธฐ ๋ฒํผ์ ์ ๊ทผ์ฑ ๊ฒฝ๋ก๋ก ๋จ๋๋ค.
|
|
74
|
+
Web๋ ๊ฐ์ ๊ธฐ์ค์ผ๋ก ํฐ์นยทํ์ผ๋ก ๋๋ฉด ๋ซํ๊ณ , ๋ง์ฐ์ค๋ ๋ซ๊ธฐ ๋ฒํผ๊ณผ Esc๋ฅผ ์ด๋ค. ์ฌ์ฉ์๊ฐ ๋ชจ๋ ์ฑยท์น์ ๊ธฐ๋ณธ ์ง์นจ์ผ๋ก ์ ํ์ผ๋ฏ๋ก ์ ํ์ด ์ด ๋์์ ๋๊ฑฐ๋ ์์ฒด ๋ทฐ์ด๋ก ๋์ฒดํ์ง ์๋๋ค.
|
|
75
|
+
|
|
69
76
|
### ์ฌ์ง์ ๋๋ฌ ํฌ๊ฒ ๋ณด๊ธฐ (`ImageViewerTrigger`, 2026-10-23)
|
|
70
77
|
|
|
71
78
|
์ฌ์ง์ ์์ `button`ยท`Pressable`๋ก ๊ฐ์ธ ๋ทฐ์ด๋ฅผ ์ด์ง ์๋๋ค(ํฌํธํด๋ฆฌ์ค ์ฌ์ดํธ `App.tsx`, Spint `MarkPhoto`ยท`ComposeScreen`์ด๋ ์ฐํ).
|
|
@@ -50,7 +50,7 @@ import { ProfileSummary } from '@hjmds/react-native/screen-flows';
|
|
|
50
50
|
| badge | ReactNode | ์์ | ์ด๋ฆ ์ ๋ฐฐ์ง |
|
|
51
51
|
| nameActions | ReactNode | ์์ | ์ด๋ฆ ํ์ ํ๋ |
|
|
52
52
|
| nameEdit | `{label,onAction,disabled?,pending?}` | ์์ | ์ด๋ฆ ์ ํธ์ง(์ฐํ) ์์ด์ฝ ๋ฒํผ. ๋ด ํ๋กํ์์ ๋๋ค์ ๋ฐ๊พธ๊ธฐ๋ฅผ ์ฐ๋ค(2026-10-25, ์๋ ์ ) |
|
|
53
|
-
| stats | `{id,value,label,onPress?,disabled?}[]` | `[]` | ํต๊ณ ์์น. `onPress`๊ฐ ์์ผ๋ฉด
|
|
53
|
+
| stats | `{id,value,label,onPress?,disabled?}[]` | `[]` | ํต๊ณ ์์น. `onPress`๊ฐ ์์ผ๋ฉด ๋ฒํผ. ํ ์ค ์ต๋ 4์นธ(`profileSummaryRecipe.stats.maxPerRow`), ๋์น๋ฉด ๋ค์ ์ค๋ก ๊ฐ๊ณ ๋ง์ง๋ง ์ค๋ ๊ฐ์ ์นธ ํญ์ด๋ค |
|
|
54
54
|
| actionsLayout | `inline` ยท `stacked` ยท `equal` | `inline` | ๊ฐ๋ก ๋ณด์กฐ ํ๋์ inline ์ค๋ฐ๊ฟ ํ, ์ธ๋ก ์ ์ฒด ํญ์ stacked, ๊ฐ์ ํญ์ ๊ฐ๋ก ํ๋์ equal(๊ฐ๋ฐ ์์ค) |
|
|
55
55
|
| actions | ReactNode | ์์ | ์์น ์๋ ํ๋ ์ค. [ProfileScreen](profile-screen.md) `editPlacement="summary"` ์์์๋ ๊ทธ ํ๋ฉด์ `edit`์ด ์ด ์ค ๋งจ ์์ `secondary` `small` ๋ฒํผ(`profileSummaryRecipe.editAction`)์ผ๋ก ๋จผ์ ๋ค์ด๊ฐ๋ค(1.31.0) |
|
|
56
56
|
| children | ReactNode | ์์ | ํ๋จ footer |
|
|
@@ -62,7 +62,7 @@ import { ProfileSummary } from '@hjmds/react-native/screen-flows';
|
|
|
62
62
|
| ํญ๋ชฉ | ๊ฐ | ๊ทผ๊ฑฐ |
|
|
63
63
|
| --- | --- | --- |
|
|
64
64
|
| ํฌ๊ธฐ | ์ํ ์๋ฐํ ํ๋ ์ 48. ProfileScreen ์์ ํ๋์ `Button` `secondary` `small` | `profileSummaryRecipe.avatarSize`ยท`editAction` |
|
|
65
|
-
| ๊ฐ๊ฒฉ | ์์น ์นธ ์ฌ์ด `spacing.md` 16, ๊ฐยท๋ผ๋ฒจ ์ฌ์ด `spacing.xxs` 4, ํ๋ ์ฌ์ด `spacing.xs` 8. ์์ญ ๊ฐ๊ฒฉ์ [CompositionLayout](composition-layout.md) | ์ renderer |
|
|
65
|
+
| ๊ฐ๊ฒฉ | ์์น ์นธ ์ฌ์ดยท์์น ์ค ์ฌ์ด `spacing.md` 16, ๊ฐยท๋ผ๋ฒจ ์ฌ์ด `spacing.xxs` 4, ํ๋ ์ฌ์ด `spacing.xs` 8. ์์ญ ๊ฐ๊ฒฉ์ [CompositionLayout](composition-layout.md) | ์ renderer |
|
|
66
66
|
| ์์ยท์ ๋ ฌ | ๋จธ๋ฆฌ(์๋ฐํ โ ์ด๋ฆยท๋ฐฐ์ง โ nameActions) โ ์์น ์ค โ actions โ children, ์์น ์นธ์ ๊ท ๋ฑ ํญยท๊ฐ์ด๋ฐ | `CompositionLayout` + `flex: 1` ์นธ |
|
|
67
67
|
| ๊ณ ์ ยท์คํฌ๋กค | ์์. ProfileScreen ๋ณธ๋ฌธ ์คํฌ๋กค ์์ ๋์ธ๋ค | โ |
|
|
68
68
|
| ์ข์ ํญยทํฐ ๊ธ์ | ์์น ์นธ์ `minWidth: 0`์ผ๋ก ๋๋ ๊ฐ๊ณ , ํ๋ ์ค์ `wrap` | ์ renderer |
|
|
@@ -103,6 +103,31 @@ Web์ ํ
์คํธ/์ด๋ชจ์ง artwork๋ ์ํ72 ํ๋ ์ ์์์ glyph.xxl48
|
|
|
103
103
|
- ๋จ์ ํ๋กํ์๋ `nameEdit`๋ฅผ ๋ฃ์ง ์๊ณ , ์ฌ์ง์ ํ์ ์๋ฐํ ๊ธฐ์ค(ํ๋ยท์ ๊ณ )์ ๋ฐ๋ฅธ๋ค.
|
|
104
104
|
- ์ ํ์ด ProfileSummary ๋์ ๊ณ ์ ๋จธ๋ฆฌ๋ฅผ ๊ทธ๋ฆฌ๋ ๊ฒฝ์ฐ์๋ ์ฌ์ง = ์ฌ์ง ๋ณ๊ฒฝ, ์ด๋ฆ = ๋๋ค์ ๋ณ๊ฒฝ์ ์งํจ๋ค. ์ด๋ฆ์ด ๊ทธ๋ฆผ(์: Spint ๋ด ์ ์์ ๋๋ฌด ํป๋ง)์ด๋ฉด ์ฐํ์ ๋ฐ๋ก ๋์ง ์๊ณ ๊ทธ ์ด๋ฆ ๊ทธ๋ฆผ ์์ฒด๋ฅผ ๋๋ค์ ๋ณ๊ฒฝ ๋ฒํผ์ผ๋ก ํ๋ค(2026-10-25 ์ฌ์ฉ์ ๊ฒฐ์ ).
|
|
105
105
|
|
|
106
|
+
### ํ๋กํ ์ฌ์ง ์ฌ๋ฆฌ๊ธฐ: ์์ผ๋ก ๋ง์ถ๊ธฐ (2026-10-29)
|
|
107
|
+
|
|
108
|
+
์ฌ์ฉ์ ์ง์๋ก ๋ชจ๋ ์ฑยท์น์์ ํ๋กํ ์ฌ์ง์ ์ฌ๋ฆด ๋ **์ธ์คํ๊ทธ๋จ์ฒ๋ผ ์ ์์์ ์์น์ ํฌ๊ธฐ๋ฅผ ๋ง์ถ๋ค.** ์์คํ
์ ์ฌ๊ฐ ์๋ฅด๊ธฐ
|
|
109
|
+
(`allowsEditing`, `aspect: [1, 1]`)๋ ์ํ ์๋ฐํ์ ๋ชจ์์ด ๋ฌ๋ผ ๊ฒฐ๊ณผ๋ฅผ ์์ธกํ ์ ์์๋ค.
|
|
110
|
+
|
|
111
|
+
- ์ฌ์ง์ ๊ณ ๋ฅธ ๋ค(์์คํ
ํธ์ง ๋) `image-viewer` ํ์ ๊ฒฝ๋ก์ `CircularPhotoCropper`๋ฅผ ์ฐ๋ค. ๋์ด์ ์ฎ๊ธฐ๊ณ ๋ ์๊ฐ๋ฝ(์น์ ํ ยท๋ ์๊ฐ๋ฝ)์ผ๋ก
|
|
112
|
+
ํ๋ํ๋ค. ์ ๋ฐ์ ์ด๋ก๊ฒ ๊ฐ๋ฆฌ๊ณ , ๋์ผ๋ฉด ์ ์์ ๋น ๊ณณ์ด ์๊ธฐ์ง ์๊ฒ ๋๋์๊ฐ๋ค(`clampCircularPhotoCrop`, ์ต๋ `maxZoom` 4๋ฐฐ).
|
|
113
|
+
- `onConfirm(crop)`์ ์๋ณธ ํฝ์
์ ์ฌ๊ฐํ `{ originX, originY, width, height }`์ด๋ค. ์ ํ์ด ๊ทธ ์์ญ์ ์๋ฅด๊ณ (Native `expo-image-manipulator`
|
|
114
|
+
`crop`, Web canvas) ๊ธฐ์กด ํฌ๊ธฐ ์ ํยท์์ถ์ผ๋ก ์ฌ๋ฆฐ๋ค. ์๋ฅด๊ธฐยท์
๋ก๋ ์ค์๋ `busy`๋ก ๋ ๋ฒํผ์ ์ ๊ทผ๋ค.
|
|
115
|
+
- ์ ์ฌ๊ฐํ์ ์ ์ฅํ๊ณ ์ ๋ชจ์์ ํ์(`cover`)๊ฐ ๋ง๋ ๋ค. ์ํ ํฌ๋ช
PNG๋ฅผ ๋ง๋ค์ง ์๋๋ค.
|
|
116
|
+
- ๊ธ ์ฒจ๋ถ ์ฌ์ง์ฒ๋ผ ์ํ์ด ์๋ ์ฌ์ง์๋ ์ฐ์ง ์๋๋ค.
|
|
117
|
+
|
|
118
|
+
### ๋จ์ ํ๋กํ: ์ฌ์ง์ ๋๋ฅด๋ฉด ํฌ๊ฒ ๋ณด๊ธฐ (2026-10-29)
|
|
119
|
+
|
|
120
|
+
์ฌ์ฉ์ ์ง์๋ก ๋ชจ๋ ์ฑยท์น์ ํ์ ํ๋กํ ํ๋ฉด์์ **๊ทธ ํ์์ ํ๋กํ ์ฌ์ง์ ๋๋ฅด๋ฉด ์ฌ์ง์ด ํฌ๊ฒ ์ด๋ฆฐ๋ค.** Spint ํ์ ํ๋กํ์์
|
|
121
|
+
์ฌ์ง์ ๋๋ฌ๋ ๋ฐ์์ด ์์๊ณ , Utilverse๋ง ์ ํ ์ฝ๋๋ก ํ๋๋ฅผ ๋ฐ๋ก ๋ง๋ค์ด ์ฑ๋ง๋ค ๋์์ด ๋ฌ๋๋ค.
|
|
122
|
+
|
|
123
|
+
- `avatarView={{ label: t("photo.view"), onPress: () => setViewerOpen(true) }}`๋ฅผ ์ค๋ค. HJM์ด ์๋ฐํ ํ ์ ์ฒด๋ฅผ ์ด๋ฏธ์ง ๋ฒํผ
|
|
124
|
+
(`ImageViewerTrigger`, Native `imagebutton` ์ญํ )์ผ๋ก ๋ง๋ค๊ณ ํฌ๊ธฐยท์ํยท๋๋ฆ ์ํ๋ฅผ ์์ ํ๋ค.
|
|
125
|
+
- ์ ํ์ `image-viewer` ํ์ ๊ฒฝ๋ก์ `ImageViewer`๋ฅผ ์ฐ๋ค(Native๋ gesture-handlerยทzoom-toolkit ์ ํ ์์กด์ฑ์ด ๊ทธ ๊ฒฝ๋ก์๋ง ์๋ค).
|
|
126
|
+
์ฌ์ง ์กฐํยท๊ถํยท์บ์๋ `items`/`renderImage`๋ก ๊ณต๊ธํ๋ค. ์ฌ์ง ์ ๊ณ ๋ ์ ํ์ ๊ธฐ์กด ๊ฒฝ๋ก๋ฅผ ์ ์งํ๋ฉฐ ํ๋ ํ๋ฉด์ ๋ ๋๋ `actions`๋ฅผ ์ด๋ค.
|
|
127
|
+
- ์ฌ์ง์ด ์์ด ์ด๋์
ยท๊ธฐ๋ณธ ์ผ๊ตด๋ง ์์ผ๋ฉด `avatarView`๋ฅผ ๋ฃ์ง ์๋๋ค(ํฌ๊ฒ ๋ณผ ์ฌ์ง์ด ์๋ค).
|
|
128
|
+
- ๋ด ํ๋กํ์ ์ฌ์ง = ์ฌ์ง ๋ณ๊ฒฝ(`Avatar.action`)์ด๋ฏ๋ก `avatarView`๋ฅผ ๋ฃ์ง ์๋๋ค. ๋ ํ๋์ ํ ์ฌ์ง์ ๊ฐ์ด ๋ฃ์ง ์๋๋ค.
|
|
129
|
+
- ์ ํ ๊ณ ์ ๋จธ๋ฆฌ(ProfileSummary ๋์ ๊ทธ๋ฆฐ ์นด๋)๋ ๊ฐ์ ๊ท์น์ `ImageViewerTrigger` + `ImageViewer`๋ก ์งํจ๋ค.
|
|
130
|
+
|
|
106
131
|
### ํ๋กํ ์นด๋ ํ (2026-10-25)
|
|
107
132
|
|
|
108
133
|
๊ฐ์ ๋ ์ฌ์ฉ์ ์ง์ : Utilverse ํ๋กํ ์นด๋(ํํํ `default`, radius `lg`)๊ฐ BurnTok ์นด๋(`raised` ๊ทธ๋ฆผ์, ํ
๋๋ฆฌ, radius `xl`)์
|
|
@@ -163,3 +163,21 @@ Chip/์ง์ wrap์ผ๋ก ์กฐ๋ฆฝํ๊ณ ์์๋ค. `presentation="chips"`๋ ๊ธฐ์กด
|
|
|
163
163
|
### ๊ทธ๋ฆผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ์ ๊ธฐ๋ณธ ์ ํ ํ์
|
|
164
164
|
|
|
165
165
|
2026-10-20 ๋ค์๋ฆฌ ๋ฐ์ ์นด๋ ์ด๊ด: Web๋ Native์ ๊ฐ์ด `indicator="none"`์ผ๋ก ๊ธฐ๋ณธ ์ํ ํ์๋ฅผ ์จ๊ธธ ์ ์๋ค(๋ก์ปฌยท๋ฏธ๊ฒ์). `renderLabel`์ ๋น์ํธ์์ฉ ๊ทธ๋ฆผ/๋ฌธ๊ตฌ์ ๊ณตํต ์นด๋์ ์ ํ ์์ผ๋ก ์ํ๋ฅผ ๋ํ๋ผ ๋ ์ฌ์ฉํ๋ค. ์ค์ radioยท๊ทธ๋ฃน ์ด๋ฆยทcheckedยทํค๋ณด๋ ์ ํยท๋นํ์ฑ ๊ณ์ฝ์ ์ ์ง๋๋ฉฐ, ๊ธฐ๋ณธ๊ฐ `default`๋ ๊ธฐ์กด ์ํ ํ์๋ฅผ ์ ์งํ๋ค. ์ ํ์์ ์นด๋ ํ
๋๋ฆฌ/๋๋ฆผ/์ ํ ํ์ ๋ค์ ๋ง๋ค์ง ์๋๋ค.
|
|
166
|
+
|
|
167
|
+
### ๊ฐ๋ก ์คํฌ๋กค ์นด๋ (2026-10-28 ๊ฐ๋ฐ ์์ค)
|
|
168
|
+
|
|
169
|
+
์ค๋์ผ๊ตฌ์ ์ผ์ ์นด๋ ์์ฒญ์ผ๋ก `overflow="scroll"`์ Web/Native RadioGroup์ ์ถ๊ฐํ๋ค.
|
|
170
|
+
`presentation="card"` ๋๋ `"chips"`์์ `grid` ์์ด ์ฌ์ฉํ๋ฉฐ ๊ธฐ๋ณธ `wrap` ๋์์ ์ ์งํ๋ค.
|
|
171
|
+
๊ณตํต ๋ ์ผ์ด ๊ฐ๋ก ์คํฌ๋กค๊ณผ ์ ํ ํญ๋ชฉ ๋
ธ์ถ์ ์์ ํ๋ค. ์ ํ์ `renderLabel`๋ก ์์ผยท์ผ์ ๋ฑ
|
|
172
|
+
์ฝํ
์ธ ๋ง ๊ณต๊ธํ๋ค. ๋นํ์ฑ์ธ ์ ํ ๋ ์ง๋ ํ์ํ ์ ์๋ค. ์กฐํ ์คํจ๋ฅผ ๋นํ์ฑ ๋ ์ง๋ก ๋ฐ๊พธ์ง ์๋๋ค.
|
|
173
|
+
์ด API๋ ์์ง ๊ฒ์ํ์ง ์์ ๊ฐ๋ฐ ์์ค ๋ณ๊ฒฝ์ด๋ค.
|
|
174
|
+
|
|
175
|
+
### ์ ํ ๋ฉด์ ๋ธ๋๋ ๊ฐ์กฐ (2026-10-29 ๊ฐ๋ฐ ์์ค ยท ๋ฏธ๊ฒ์)
|
|
176
|
+
|
|
177
|
+
`selectionTone="neutral" | "brand" | "brand-outline"`๋ฅผ Web/Native์์ ์ง์ ํ๋ค. ๊ธฐ๋ณธ๊ฐ์ `neutral`์ด๋ค.
|
|
178
|
+
์ค๋์ผ๊ตฌ ๋ ์ง ์นด๋์ ์ ํ์ผ์ ํ๋ ๋ฐฐ๊ฒฝยทํฐ ๊ธ์๋ก ๊ฐ์กฐํด ๋ฌ๋ผ๋ ์์ฒญ์ด ๊ณ๊ธฐ๋ค.
|
|
179
|
+
`brand`๋ ํ
๋ง์ `primary`/`onPrimary` ์์ ์ฌ์ฉํ๊ณ ๋ฏธ์ ํ ๋ฉด์ ๊ธฐ์กด canvas๋ฅผ ์ ์งํ๋ค(light๋ ํฐ์).
|
|
180
|
+
๋ผ๋ฒจยท์ค๋ช
๊ณผ Native `renderLabel` ์์ ์ค๋ฆฝ Text๋ ์ ํ ๋ฉด์ ๊ธ์์์ ์์ํ๋ค.
|
|
181
|
+
๋ธ๋๋์ยท์ํ์์ ๋ช
์ํ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ ์ ํ์ด ์๋ฏธ์ ๋ง๊ฒ ๊ณต๊ธํ๋ค.
|
|
182
|
+
|
|
183
|
+
๊ฐ์ ๋ ์ฌ์ฉ์ ํ์ ์์ฒญ์ผ๋ก `brand-outline`์ ์ ํ ๋ฐฐ๊ฒฝ๋ canvas(light ํฐ์)๋ก ์ ์งํ๊ณ ํ
๋๋ฆฌ๋ง ๋ํ์ primary๋ก ๊ฐ์กฐํ๋ค. ์ผ๋ฐ ๊ธ์์๊ณผ ๋นํ์ฑ ๊ณ์ฝ์ ์ ์งํ๋ค.
|
|
@@ -134,7 +134,7 @@ Native ์คํฌ๋กค ๋ณธ๋ฌธ์ viewport ๋์ด๋งํผ content๋ฅผ ์ฑ์ด๋ค(๋ฏธ๊ฒ์)
|
|
|
134
134
|
| --- | --- | --- |
|
|
135
135
|
| ํฌ๊ธฐ | ํ๋จ ์ํธ ๋์ด: `auto` ๋ด์ฉ ๋์ด(์ต๋ ํ๋ฉด ๋์ด ร `maxHeightRatio` 0.9), `medium` 60%, `large` 85%, `full` ์ safe area ์ ์ ์ฒด ๋์ด(0.9 ์ํ ์์). Web ํ๋จ ์ํธ ์ต๋ ํญ 640. ์ ๋ ๋ชจ์๋ฆฌ๋ง `radius.xl` 24. ์ ์ํธ(`start`ยท`end`): Web ํญ `min(28rem, 100%)`ยท๋์ด ํ๋ฉด โ 32, Native ํญ 88%(์ต๋ 420)ยทํ๋ฉด ๋์ด | `sheetRecipe.sizes`ยท`content`ยท`web`, `.hjm-sheet`, Native `Sheet` |
|
|
136
136
|
| ๊ฐ๊ฒฉ | ๋ ํ๋ซํผ ๊ฐ์ ๊ฐ: ์ข์ฐ `content.paddingHorizontal`(`spacing.lg` 20), ์ยท์๋ `content.paddingTop/Bottom`(`spacing.sm` 12, ํ๋จ ์ํธ๋ ์๋ safe area๋ฅผ ๋ํจ), ๋จธ๋ฆฌยท๋ณธ๋ฌธยทfooter ์ฌ์ด `body.gap`(`spacing.md` 16), footer ์ `footer.paddingTop`(`spacing.sm` 12), ์ ๋ชฉโ๋ซ๊ธฐ `header.gap`(`spacing.sm` 12), footer ๋ฒํผ ์ฌ์ด `footer.gap`(`spacing.xs` 8) | `.hjm-sheet__*`, `sheetRecipe.content`ยท`body`ยท`footer` |
|
|
137
|
-
| ์์ยท์ ๋ ฌ | ์์ก์ด(ํ๋จ) โ ๋จธ๋ฆฌ(์ค๋ช
+ ๋ซ๊ธฐ, ๋ ๋ค ์์ผ๋ฉด ๊ทธ๋ฆฌ์ง ์์) โ ๋ณธ๋ฌธ โ `footer`. ๋ณด์ด๋ ์ ๋ชฉ ์ค์ ์๋ค(๋ฏธ๊ฒ์). ๋จธ๋ฆฌ ์ต์ ๋์ด 44(`control.minTouchTarget`), ร๋ ์ค๋ช
์ด ์์ด๋ ๋ ์ชฝ ๊ฐ์ ์๋ฆฌ๋ค. ๊ธฐ๋ณธ ํ๋จ ์ํธ๋ ๋จธ๋ฆฌ๊ฐ ์์ด ๋ณธ๋ฌธ์ด ์์ก์ด ์์ญ ๋ฐ๋ก ์๋ `body.gap` 16์์ ์์ํ๋ค. Web footer๋ ์ค๋ฅธ์ชฝ ์ ๋ ฌ ๊ฐ๋ก ์ค [๋ณด์กฐ][์ฃผ]. Native footer๋ ์ธ๋ก ์ด์ด๋ผ ๊ฝ ์ฐฌ ํญ ๋ฒํผ์ ์ฃผ ํ๋ ๋จผ์ ๋๋ค. ํ๋จ ์ํธ๋ ํญ์ ์ ๊ฐ์ด๋ฐ 36ร4 ์์ก์ด(ํฐ์น ์ต์ ํญยท๋์ด44)๋ฅผ ๋๋ค. `detents`๊ฐ ์์ผ๋ฉด ๋์ด ์ ํ ๋ฒํผ, ์๊ณ ร๊ฐ ์์ผ๋ฉด `closeLabel` ์ด๋ฆ์ ๋ซ๊ธฐ ๋ฒํผ์ด๋ค. `showClose: true`๋ก ร๋ฅผ ํ์ํ๋ฉด ์์ก์ด๋ ์ฅ์์ผ๋ก ๋จ๊ฒจ ๊ฐ์ ๋ซ๊ธฐ ๋ฒํผ์ด ์ค๋ณต๋์ง ์๋๋ค(๋ฏธ๊ฒ์). ์์ก์ดยท๋จธ๋ฆฌ ์์ญ์ ์๋๋ก ๋์ด `sheetDragRecipe.dismissDistanceRatio`(์ํธ ๋์ด์ 25%) ๋๋ `dismissVelocity` 0.5px/ms๋ฅผ ๋๊ธฐ๋ฉด `swipe`๋ก ๋ซ๊ณ , ์๋๋ฉด ์ ์๋ฆฌ๋ก ๋์๊ฐ๋ค(๋ฏธ๊ฒ์, WebยทNative ๋์ผ). ๋ณธ๋ฌธ๋ ๊ฐ์ ๋๊ธฐ๋ก ๋ซ๋๋ค(2026-10-27 ์ฌ์ฉ์ ๊ฒฐ์ , ๋ฏธ๊ฒ์). ์คํฌ๋กค ๋ณธ๋ฌธ์ ์ด๋ฏธ ๋งจ ์์ผ ๋ ์์ํ ์๋ ๋๊ธฐ๋ง ์ํธ๊ฐ ๊ฐ์ ธ๊ฐ๊ณ , ์คํฌ๋กค๋ ์ํ์์๋ ๊ฐ์ ๋์์ด ๋จผ์ ๋ด์ฉ์ ์๋ก ๋๋๋ฆฐ๋ค. iOS๋ UIScrollView๊ฐ JS ์๋ต์ ์๋์๋ ์ค์ค๋ก ๋๊ธฐ๋ฅผ ๊ฐ์ ธ๊ฐ๋ฏ๋ก ๋ณธ๋ฌธ ๋งจ ์์ ๋น๊น(overscroll)์ผ๋ก ์ํธ๋ฅผ ์์ง์ด๊ณ UIKit ํ์ฑ ๊ฑฐ๋ฆฌ๋ก ํ์ฐํ ๊ฐ์ ์๊ณ๊ฐ์ ์ด๋ค. Web ๋ณธ๋ฌธ ๋๊ธฐ๋ ํฐ์น๋ง ๋ฐ๊ณ ๋ง์ฐ์ค๋ ๊ธ์ ์ ํ์ ์ํด ์์ก์ด๋ฅผ ์ด๋ค. ์
๋ ฅ์นธ์์ ์์ํ ๋๊ธฐ์ ๊ฐ๋ก ๋๊ธฐ๋ ๋ณธ๋ฌธ ์์ ํ๋์ผ๋ก ๋จ๊ธด๋ค | `sheetRecipe.header`ยท`handle`, `.hjm-sheet__footer`, `.hjm-sheet__handle` |
|
|
137
|
+
| ์์ยท์ ๋ ฌ | ์์ก์ด(ํ๋จ) โ ๋จธ๋ฆฌ(์ค๋ช
+ ๋ซ๊ธฐ, ๋ ๋ค ์์ผ๋ฉด ๊ทธ๋ฆฌ์ง ์์) โ ๋ณธ๋ฌธ โ `footer`. ๋ณด์ด๋ ์ ๋ชฉ ์ค์ ์๋ค(๋ฏธ๊ฒ์). ๋จธ๋ฆฌ ์ต์ ๋์ด 44(`control.minTouchTarget`), ร๋ ์ค๋ช
์ด ์์ด๋ ๋ ์ชฝ ๊ฐ์ ์๋ฆฌ๋ค. ๊ธฐ๋ณธ ํ๋จ ์ํธ๋ ๋จธ๋ฆฌ๊ฐ ์์ด ๋ณธ๋ฌธ์ด ์์ก์ด ์์ญ ๋ฐ๋ก ์๋ `body.gap` 16์์ ์์ํ๋ค. Web footer๋ ์ค๋ฅธ์ชฝ ์ ๋ ฌ ๊ฐ๋ก ์ค [๋ณด์กฐ][์ฃผ]. Native footer๋ ์ธ๋ก ์ด์ด๋ผ ๊ฝ ์ฐฌ ํญ ๋ฒํผ์ ์ฃผ ํ๋ ๋จผ์ ๋๋ค. ํ๋จ ์ํธ๋ ํญ์ ์ ๊ฐ์ด๋ฐ 36ร4 ์์ก์ด(ํฐ์น ์ต์ ํญยท๋์ด44)๋ฅผ ๋๋ค. `detents`๊ฐ ์์ผ๋ฉด ๋์ด ์ ํ ๋ฒํผ, ์๊ณ ร๊ฐ ์์ผ๋ฉด `closeLabel` ์ด๋ฆ์ ๋ซ๊ธฐ ๋ฒํผ์ด๋ค. `showClose: true`๋ก ร๋ฅผ ํ์ํ๋ฉด ์์ก์ด๋ ์ฅ์์ผ๋ก ๋จ๊ฒจ ๊ฐ์ ๋ซ๊ธฐ ๋ฒํผ์ด ์ค๋ณต๋์ง ์๋๋ค(๋ฏธ๊ฒ์). ์์ก์ดยท๋จธ๋ฆฌ ์์ญ์ ์๋๋ก ๋์ด `sheetDragRecipe.dismissDistanceRatio`(์ํธ ๋์ด์ 25%) ๋๋ `dismissVelocity` 0.5px/ms๋ฅผ ๋๊ธฐ๋ฉด `swipe`๋ก ๋ซ๊ณ , ์๋๋ฉด ์ ์๋ฆฌ๋ก ๋์๊ฐ๋ค(๋ฏธ๊ฒ์, WebยทNative ๋์ผ). ๋ณธ๋ฌธ๋ ๊ฐ์ ๋๊ธฐ๋ก ๋ซ๋๋ค(2026-10-27 ์ฌ์ฉ์ ๊ฒฐ์ , ๋ฏธ๊ฒ์). ์คํฌ๋กค ๋ณธ๋ฌธ์ ์ด๋ฏธ ๋งจ ์์ผ ๋ ์์ํ ์๋ ๋๊ธฐ๋ง ์ํธ๊ฐ ๊ฐ์ ธ๊ฐ๊ณ , ์คํฌ๋กค๋ ์ํ์์๋ ๊ฐ์ ๋์์ด ๋จผ์ ๋ด์ฉ์ ์๋ก ๋๋๋ฆฐ๋ค. ์คํฌ๋กคํ์ง ์๋ ๋ณธ๋ฌธ ์์ ๋ค์ด๊ฐ ๋ชฉ๋ก ์คํฌ๋กค(์ํธ ์ `SearchScreen embedded`)๋ ๊ฐ์ ๊ท์น์ ๋ฐ๋ฅธ๋ค. Native๋ ๊ทธ ๋ชฉ๋ก์ด ์ํธ์ ๋๊ธฐ ์ฐ๊ฒฐ์ ๋๊ฒจ๋ฐ์ ๋ชฉ๋ก ์์น๋ก ํ๋จํ๋ค(2026-10-30 Spint ๋์ ์ํธ์์ ์คํฌ๋กค๋ ๋ชฉ๋ก์ ๋๋๋ฆฌ๋ฉด ์ํธ๋ ํจ๊ป ๋ด๋ ค๊ฐ๋ ๊ฒฐํจ, ๋ฏธ๊ฒ์). iOS๋ UIScrollView๊ฐ JS ์๋ต์ ์๋์๋ ์ค์ค๋ก ๋๊ธฐ๋ฅผ ๊ฐ์ ธ๊ฐ๋ฏ๋ก ๋ณธ๋ฌธ ๋งจ ์์ ๋น๊น(overscroll)์ผ๋ก ์ํธ๋ฅผ ์์ง์ด๊ณ UIKit ํ์ฑ ๊ฑฐ๋ฆฌ๋ก ํ์ฐํ ๊ฐ์ ์๊ณ๊ฐ์ ์ด๋ค. Web ๋ณธ๋ฌธ ๋๊ธฐ๋ ํฐ์น๋ง ๋ฐ๊ณ ๋ง์ฐ์ค๋ ๊ธ์ ์ ํ์ ์ํด ์์ก์ด๋ฅผ ์ด๋ค. ์
๋ ฅ์นธ์์ ์์ํ ๋๊ธฐ์ ๊ฐ๋ก ๋๊ธฐ๋ ๋ณธ๋ฌธ ์์ ํ๋์ผ๋ก ๋จ๊ธด๋ค | `sheetRecipe.header`ยท`handle`, `.hjm-sheet__footer`, `.hjm-sheet__handle` |
|
|
138
138
|
| ๊ณ ์ ยท์คํฌ๋กค | ๋ณธ๋ฌธ๋ง ์คํฌ๋กค, ๋จธ๋ฆฌยท`footer` ๊ณ ์ (Native๋ `scrollable`์ผ ๋ ScrollView). ์คํฌ๋กค ์์ญ์ ์ํธ ์ข์ฐ ์ฌ๋ฐฑ(`sheetRecipe.content.paddingHorizontal` 20) ๋๊น์ง ๋๊ณ ์ฌ๋ฐฑ์ ์คํฌ๋กค ๋ด์ฉ ์์ชฝ์ ๋๋ค(Web `.hjm-sheet__body` padding, Native ScrollView `marginHorizontal: -20` + ๋ด์ฉ `paddingHorizontal: 20`). ๊ทธ๋์ ๋ณธ๋ฌธ ListRow์ 8 ํ๋ฉด์ด ์๋ฆฌ์ง ์๊ณ ๋ด์ฉ ์์น๋ ๊ทธ๋๋ก๋ค. ๊ณ ์ ๋์ด(`medium`ยท`large`ยท`full`, ์ ์ํธ)์์๋ ๋ณธ๋ฌธ์ด ๋จธ๋ฆฌยทfooter๋ฅผ ๋บ ๋จ์ ๋์ด๋ฅผ ์ฐจ์งํ๊ณ `footer`๋ ์ํธ ์๋์ ๋ถ๋๋ค. ๊ทธ๋์ ๋ณธ๋ฌธ์ `flex: 1` ์์(SearchScreen, ๋ชฉ๋ก ํ๋ฉด)์ด ๊ทธ ๋์ด๋ฅผ ์ฑ์ด๋ค(Web `.hjm-sheet__body` `flex: 1 1 auto`, Native ๋ณธ๋ฌธ `flexGrow: 1`ยท`minHeight: 0`, 1.13.1 ๋ณ๊ฒฝ). `auto`๋ ๋ด์ฉ ๋์ด ๊ทธ๋๋ก๋ค. ์ ์ฅยทํ์ธ์ `footer`์. ์๋ ์์ ์์ญ์ ์ํธ๊ฐ ์๊ธฐ ์ฌ๋ฐฑ์ ๋ํ๋ค(`spacing.sm` 12 + ์๋ inset, Web์ `env(safe-area-inset-bottom)`). ์ inset์ ์ํธ๊ฐ ์ฌ๋ผ๊ฐ ๋์ด๋ฅผ ์ค์ธ๋ค. ์ ํ์ด inset์ ๋ค์ ๋ํ์ง ์๋๋ค | `.hjm-sheet__body`, `sheetRecipe.safeArea`, Native `Sheet` |
|
|
139
139
|
| ์ข์ ํญยทํฐ ๊ธ์ | ํญ < 640์ด๋ฉด ํ๋จ ์ํธ๊ฐ ํ๋ฉด ํญ์ ์ฑ์ด๋ค. Web footer๋ ์ค์ ๋ฐ๊พผ๋ค. ํฐ ๊ธ์๋ก ๋ด์ฉ์ด ๊ธธ์ด์ง๋ฉด `auto`๋ ์ต๋ 90%์์ ๋ฉ์ถ๊ณ ๋ณธ๋ฌธ์ด ์คํฌ๋กค๋๋ค(`full`์ ์ safe area๊น์ง) | `.hjm-sheet[data-placement="bottom"]`, `maxHeightRatio` |
|
|
140
140
|
|