@mandujs/mcp 0.12.2 → 0.13.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.
Files changed (141) hide show
  1. package/README.md +367 -367
  2. package/package.json +2 -2
  3. package/src/activity-monitor.ts +847 -847
  4. package/src/adapters/index.ts +20 -20
  5. package/src/adapters/monitor-adapter.ts +100 -100
  6. package/src/adapters/tool-adapter.ts +88 -88
  7. package/src/executor/error-handler.ts +250 -250
  8. package/src/executor/index.ts +22 -22
  9. package/src/executor/tool-executor.ts +148 -148
  10. package/src/hooks/config-watcher.ts +174 -174
  11. package/src/hooks/index.ts +23 -23
  12. package/src/hooks/mcp-hooks.ts +227 -227
  13. package/src/index.ts +106 -106
  14. package/src/logging/index.ts +15 -15
  15. package/src/logging/mcp-transport.ts +134 -134
  16. package/src/registry/index.ts +13 -13
  17. package/src/registry/mcp-tool-registry.ts +298 -298
  18. package/src/resources/skills/guides.ts +1136 -1136
  19. package/src/resources/skills/index.ts +12 -12
  20. package/src/resources/skills/loader.ts +218 -218
  21. package/src/resources/skills/mandu-composition/SKILL.md +91 -91
  22. package/src/resources/skills/mandu-composition/metadata.json +13 -13
  23. package/src/resources/skills/mandu-composition/rules/_sections.md +26 -26
  24. package/src/resources/skills/mandu-composition/rules/_template.md +77 -77
  25. package/src/resources/skills/mandu-composition/rules/comp-arch-avoid-boolean-props.md +146 -146
  26. package/src/resources/skills/mandu-composition/rules/comp-arch-compound-components.md +164 -164
  27. package/src/resources/skills/mandu-composition/rules/comp-island-event.md +161 -161
  28. package/src/resources/skills/mandu-composition/rules/comp-island-slot-split.md +167 -167
  29. package/src/resources/skills/mandu-composition/rules/comp-pattern-children.md +149 -149
  30. package/src/resources/skills/mandu-composition/rules/comp-state-context-interface.md +148 -148
  31. package/src/resources/skills/mandu-composition/rules/comp-state-lift-state.md +150 -150
  32. package/src/resources/skills/mandu-deployment/SKILL.md +92 -92
  33. package/src/resources/skills/mandu-deployment/_sections.md +41 -41
  34. package/src/resources/skills/mandu-deployment/_template.md +38 -38
  35. package/src/resources/skills/mandu-deployment/metadata.json +13 -13
  36. package/src/resources/skills/mandu-deployment/rules/deploy-build-bun.md +109 -109
  37. package/src/resources/skills/mandu-deployment/rules/deploy-build-output.md +115 -115
  38. package/src/resources/skills/mandu-deployment/rules/deploy-cicd-github.md +219 -219
  39. package/src/resources/skills/mandu-deployment/rules/deploy-docker-bun.md +150 -150
  40. package/src/resources/skills/mandu-deployment/rules/deploy-docker-compose.md +223 -223
  41. package/src/resources/skills/mandu-deployment/rules/deploy-platform-fly.md +152 -152
  42. package/src/resources/skills/mandu-deployment/rules/deploy-platform-render.md +179 -179
  43. package/src/resources/skills/mandu-deployment/rules/deploy-platform-supabase.md +323 -323
  44. package/src/resources/skills/mandu-deployment/rules/deploy-platform-vercel.md +140 -140
  45. package/src/resources/skills/mandu-fs-routes/SKILL.md +82 -82
  46. package/src/resources/skills/mandu-fs-routes/metadata.json +12 -12
  47. package/src/resources/skills/mandu-fs-routes/rules/_sections.md +36 -36
  48. package/src/resources/skills/mandu-fs-routes/rules/_template.md +69 -69
  49. package/src/resources/skills/mandu-fs-routes/rules/routes-api-methods.md +65 -65
  50. package/src/resources/skills/mandu-fs-routes/rules/routes-dynamic-param.md +93 -93
  51. package/src/resources/skills/mandu-fs-routes/rules/routes-naming-page.md +55 -55
  52. package/src/resources/skills/mandu-guard/SKILL.md +129 -129
  53. package/src/resources/skills/mandu-guard/metadata.json +12 -12
  54. package/src/resources/skills/mandu-guard/rules/_sections.md +36 -36
  55. package/src/resources/skills/mandu-guard/rules/_template.md +82 -82
  56. package/src/resources/skills/mandu-guard/rules/guard-config-rules.md +100 -100
  57. package/src/resources/skills/mandu-guard/rules/guard-layer-direction.md +76 -76
  58. package/src/resources/skills/mandu-guard/rules/guard-preset-mandu.md +81 -81
  59. package/src/resources/skills/mandu-guard/rules/guard-validate-import.md +80 -80
  60. package/src/resources/skills/mandu-hydration/SKILL.md +91 -91
  61. package/src/resources/skills/mandu-hydration/metadata.json +12 -12
  62. package/src/resources/skills/mandu-hydration/rules/_sections.md +31 -31
  63. package/src/resources/skills/mandu-hydration/rules/_template.md +72 -72
  64. package/src/resources/skills/mandu-hydration/rules/hydration-data-event.md +109 -109
  65. package/src/resources/skills/mandu-hydration/rules/hydration-directive-use-client.md +55 -55
  66. package/src/resources/skills/mandu-hydration/rules/hydration-island-setup.md +113 -113
  67. package/src/resources/skills/mandu-hydration/rules/hydration-priority-visible.md +68 -68
  68. package/src/resources/skills/mandu-performance/SKILL.md +85 -85
  69. package/src/resources/skills/mandu-performance/metadata.json +14 -14
  70. package/src/resources/skills/mandu-performance/rules/_sections.md +31 -31
  71. package/src/resources/skills/mandu-performance/rules/_template.md +64 -64
  72. package/src/resources/skills/mandu-performance/rules/perf-async-defer-await.md +103 -103
  73. package/src/resources/skills/mandu-performance/rules/perf-async-parallel.md +95 -95
  74. package/src/resources/skills/mandu-performance/rules/perf-bun-file.md +124 -124
  75. package/src/resources/skills/mandu-performance/rules/perf-bun-serve.md +125 -125
  76. package/src/resources/skills/mandu-performance/rules/perf-bundle-imports.md +80 -80
  77. package/src/resources/skills/mandu-performance/rules/perf-bundle-island-lazy.md +145 -145
  78. package/src/resources/skills/mandu-performance/rules/perf-cache-react.md +98 -98
  79. package/src/resources/skills/mandu-performance/rules/perf-render-transitions.md +154 -154
  80. package/src/resources/skills/mandu-security/SKILL.md +87 -87
  81. package/src/resources/skills/mandu-security/metadata.json +13 -13
  82. package/src/resources/skills/mandu-security/rules/_sections.md +31 -31
  83. package/src/resources/skills/mandu-security/rules/_template.md +74 -74
  84. package/src/resources/skills/mandu-security/rules/sec-auth-guard.md +127 -127
  85. package/src/resources/skills/mandu-security/rules/sec-env-management.md +133 -133
  86. package/src/resources/skills/mandu-security/rules/sec-input-validate.md +148 -148
  87. package/src/resources/skills/mandu-security/rules/sec-protect-csrf.md +146 -146
  88. package/src/resources/skills/mandu-security/rules/sec-protect-headers.md +138 -138
  89. package/src/resources/skills/mandu-slot/SKILL.md +85 -85
  90. package/src/resources/skills/mandu-slot/metadata.json +12 -12
  91. package/src/resources/skills/mandu-slot/rules/_sections.md +36 -36
  92. package/src/resources/skills/mandu-slot/rules/_template.md +63 -63
  93. package/src/resources/skills/mandu-slot/rules/slot-basic-structure.md +38 -38
  94. package/src/resources/skills/mandu-slot/rules/slot-ctx-response.md +56 -56
  95. package/src/resources/skills/mandu-slot/rules/slot-guard-auth.md +59 -59
  96. package/src/resources/skills/mandu-slot/rules/slot-http-methods.md +64 -64
  97. package/src/resources/skills/mandu-styling/SKILL.md +154 -154
  98. package/src/resources/skills/mandu-styling/_sections.md +43 -43
  99. package/src/resources/skills/mandu-styling/_template.md +32 -32
  100. package/src/resources/skills/mandu-styling/metadata.json +15 -15
  101. package/src/resources/skills/mandu-styling/rules/style-component-compound.md +235 -235
  102. package/src/resources/skills/mandu-styling/rules/style-component-slots.md +255 -255
  103. package/src/resources/skills/mandu-styling/rules/style-component-tokens.md +205 -205
  104. package/src/resources/skills/mandu-styling/rules/style-island-animations.md +272 -272
  105. package/src/resources/skills/mandu-styling/rules/style-island-scoping.md +167 -167
  106. package/src/resources/skills/mandu-styling/rules/style-island-variants.md +221 -221
  107. package/src/resources/skills/mandu-styling/rules/style-perf-critical.md +209 -209
  108. package/src/resources/skills/mandu-styling/rules/style-perf-purge.md +192 -192
  109. package/src/resources/skills/mandu-styling/rules/style-setup-modules.md +162 -162
  110. package/src/resources/skills/mandu-styling/rules/style-setup-panda.md +164 -164
  111. package/src/resources/skills/mandu-styling/rules/style-setup-tailwind.md +170 -170
  112. package/src/resources/skills/mandu-styling/rules/style-tailwind-v4-gotchas.md +179 -179
  113. package/src/resources/skills/mandu-styling/rules/style-theme-darkmode.md +229 -229
  114. package/src/resources/skills/mandu-testing/SKILL.md +99 -99
  115. package/src/resources/skills/mandu-testing/metadata.json +13 -13
  116. package/src/resources/skills/mandu-testing/rules/_sections.md +26 -26
  117. package/src/resources/skills/mandu-testing/rules/_template.md +65 -65
  118. package/src/resources/skills/mandu-testing/rules/test-component-island.md +195 -195
  119. package/src/resources/skills/mandu-testing/rules/test-e2e-playwright.md +196 -196
  120. package/src/resources/skills/mandu-testing/rules/test-mock-fetch.md +219 -219
  121. package/src/resources/skills/mandu-testing/rules/test-slot-unit.md +192 -192
  122. package/src/resources/skills/mandu-ui/SKILL.md +117 -117
  123. package/src/resources/skills/mandu-ui/_sections.md +23 -23
  124. package/src/resources/skills/mandu-ui/_template.md +32 -32
  125. package/src/resources/skills/mandu-ui/metadata.json +13 -13
  126. package/src/resources/skills/mandu-ui/rules/ui-accessibility-aria.md +232 -232
  127. package/src/resources/skills/mandu-ui/rules/ui-accessibility-focus.md +238 -238
  128. package/src/resources/skills/mandu-ui/rules/ui-composition-patterns.md +259 -259
  129. package/src/resources/skills/mandu-ui/rules/ui-island-integration.md +258 -258
  130. package/src/resources/skills/mandu-ui/rules/ui-radix-patterns.md +213 -213
  131. package/src/resources/skills/mandu-ui/rules/ui-shadcn-setup.md +209 -209
  132. package/src/resources/skills/recipes.ts +932 -932
  133. package/src/tools/generate.ts +7 -4
  134. package/src/tools/guard.ts +17 -4
  135. package/src/tools/hydration.ts +10 -10
  136. package/src/tools/project.ts +334 -334
  137. package/src/tools/runtime.ts +497 -497
  138. package/src/tools/seo.ts +417 -417
  139. package/src/tools/spec.ts +80 -159
  140. package/src/utils/project.ts +22 -12
  141. package/src/utils/withWarnings.ts +83 -83
@@ -1,13 +1,13 @@
1
- {
2
- "version": "1.0.0",
3
- "organization": "Mandu Framework",
4
- "date": "February 2026",
5
- "abstract": "Mandu 애플리케이션을 위한 React 컴포지션 패턴 가이드. Island 컴파운드 컴포넌트, state/actions/meta 인터페이스, Provider 패턴, useIslandEvent를 통한 Island 간 통신, slot-client 분리 패턴을 다룹니다. Vercel Composition Patterns 기반으로 Mandu 컨텍스트에 맞게 변환되었습니다.",
6
- "references": [
7
- "https://react.dev/learn/passing-data-deeply-with-context",
8
- "https://react.dev/learn/scaling-up-with-reducer-and-context",
9
- "https://www.patterns.dev/react/compound-pattern",
10
- "https://kentcdodds.com/blog/compound-components-with-react-hooks"
11
- ],
12
- "tags": ["composition", "compound", "context", "state", "island", "mandu"]
13
- }
1
+ {
2
+ "version": "1.0.0",
3
+ "organization": "Mandu Framework",
4
+ "date": "February 2026",
5
+ "abstract": "Mandu 애플리케이션을 위한 React 컴포지션 패턴 가이드. Island 컴파운드 컴포넌트, state/actions/meta 인터페이스, Provider 패턴, useIslandEvent를 통한 Island 간 통신, slot-client 분리 패턴을 다룹니다. Vercel Composition Patterns 기반으로 Mandu 컨텍스트에 맞게 변환되었습니다.",
6
+ "references": [
7
+ "https://react.dev/learn/passing-data-deeply-with-context",
8
+ "https://react.dev/learn/scaling-up-with-reducer-and-context",
9
+ "https://www.patterns.dev/react/compound-pattern",
10
+ "https://kentcdodds.com/blog/compound-components-with-react-hooks"
11
+ ],
12
+ "tags": ["composition", "compound", "context", "state", "island", "mandu"]
13
+ }
@@ -1,26 +1,26 @@
1
- # Sections
2
-
3
- This file defines all sections, their ordering, impact levels, and descriptions.
4
- The section ID (in parentheses) is the filename prefix used to group rules.
5
-
6
- ---
7
-
8
- ## 1. Component Architecture (comp-arch)
9
-
10
- **Impact:** HIGH
11
- **Description:** Boolean props 대신 컴포지션 사용, 컴파운드 컴포넌트 구조화. 코드베이스가 확장됨에 따라 유지보수성에 큰 영향을 미칩니다.
12
-
13
- ## 2. State Management (comp-state)
14
-
15
- **Impact:** HIGH
16
- **Description:** state/actions/meta 인터페이스 정의, Provider를 통한 의존성 주입. 같은 UI를 다양한 상태 구현과 함께 재사용할 수 있게 합니다.
17
-
18
- ## 3. Island Patterns (comp-island)
19
-
20
- **Impact:** MEDIUM
21
- **Description:** Mandu Island 특화 패턴. 컴파운드 Island, Island 간 이벤트 통신, slot-client 분리를 다룹니다.
22
-
23
- ## 4. Implementation Patterns (comp-pattern)
24
-
25
- **Impact:** MEDIUM
26
- **Description:** children 활용, Provider 경계 이해 등 구현 세부 사항. 올바른 패턴 적용으로 유연성을 확보합니다.
1
+ # Sections
2
+
3
+ This file defines all sections, their ordering, impact levels, and descriptions.
4
+ The section ID (in parentheses) is the filename prefix used to group rules.
5
+
6
+ ---
7
+
8
+ ## 1. Component Architecture (comp-arch)
9
+
10
+ **Impact:** HIGH
11
+ **Description:** Boolean props 대신 컴포지션 사용, 컴파운드 컴포넌트 구조화. 코드베이스가 확장됨에 따라 유지보수성에 큰 영향을 미칩니다.
12
+
13
+ ## 2. State Management (comp-state)
14
+
15
+ **Impact:** HIGH
16
+ **Description:** state/actions/meta 인터페이스 정의, Provider를 통한 의존성 주입. 같은 UI를 다양한 상태 구현과 함께 재사용할 수 있게 합니다.
17
+
18
+ ## 3. Island Patterns (comp-island)
19
+
20
+ **Impact:** MEDIUM
21
+ **Description:** Mandu Island 특화 패턴. 컴파운드 Island, Island 간 이벤트 통신, slot-client 분리를 다룹니다.
22
+
23
+ ## 4. Implementation Patterns (comp-pattern)
24
+
25
+ **Impact:** MEDIUM
26
+ **Description:** children 활용, Provider 경계 이해 등 구현 세부 사항. 올바른 패턴 적용으로 유연성을 확보합니다.
@@ -1,77 +1,77 @@
1
- # Rule Template
2
-
3
- Use this template when creating new rules for mandu-composition.
4
-
5
- ---
6
-
7
- ```markdown
8
- ---
9
- title: Rule Title Here
10
- impact: HIGH | MEDIUM | LOW
11
- impactDescription: 영향 설명 (예: "enables flexible composition")
12
- tags: composition, tag1, tag2
13
- ---
14
-
15
- ## Rule Title Here
16
-
17
- **Impact: {LEVEL} ({impactDescription})**
18
-
19
- 규칙의 목적과 아키텍처적 영향을 설명합니다.
20
-
21
- **Incorrect (문제가 되는 패턴):**
22
-
23
- \`\`\`tsx
24
- // ❌ Boolean props로 기능 추가
25
- function Composer({
26
- showAttachments,
27
- showFormatting,
28
- showEmojis,
29
- isCompact,
30
- isReadOnly,
31
- }: Props) {
32
- return (
33
- <form>
34
- {!isReadOnly && <Input />}
35
- {showAttachments && <Attachments />}
36
- {showFormatting && <Formatting />}
37
- {showEmojis && <Emojis />}
38
- </form>
39
- );
40
- }
41
- ```
42
-
43
- **Correct (컴포지션 패턴):**
44
-
45
- \`\`\`tsx
46
- // ✅ 컴포지션으로 유연하게 구성
47
- <Composer.Provider state={state} actions={actions}>
48
- <Composer.Frame>
49
- <Composer.Input />
50
- <Composer.Footer>
51
- <Composer.Emojis />
52
- <Composer.Submit />
53
- </Composer.Footer>
54
- </Composer.Frame>
55
- </Composer.Provider>
56
- \`\`\`
57
-
58
- ## Mandu Context
59
-
60
- Mandu Island에서 이 패턴을 적용하는 방법을 설명합니다.
61
-
62
- Reference: [관련 문서 링크](https://example.com)
63
- ```
64
-
65
- ---
66
-
67
- ## Naming Convention
68
-
69
- - 파일명: `comp-{category}-{rule-name}.md`
70
- - 예시: `comp-arch-compound-components.md`, `comp-state-context-interface.md`
71
-
72
- ## Core Principle
73
-
74
- **Lift state, compose internals, make state dependency-injectable.**
75
-
76
- UI는 조합 가능한 조각들이고, 상태는 Provider가 주입합니다.
77
- Provider를 바꾸면 UI는 그대로 유지됩니다.
1
+ # Rule Template
2
+
3
+ Use this template when creating new rules for mandu-composition.
4
+
5
+ ---
6
+
7
+ ```markdown
8
+ ---
9
+ title: Rule Title Here
10
+ impact: HIGH | MEDIUM | LOW
11
+ impactDescription: 영향 설명 (예: "enables flexible composition")
12
+ tags: composition, tag1, tag2
13
+ ---
14
+
15
+ ## Rule Title Here
16
+
17
+ **Impact: {LEVEL} ({impactDescription})**
18
+
19
+ 규칙의 목적과 아키텍처적 영향을 설명합니다.
20
+
21
+ **Incorrect (문제가 되는 패턴):**
22
+
23
+ \`\`\`tsx
24
+ // ❌ Boolean props로 기능 추가
25
+ function Composer({
26
+ showAttachments,
27
+ showFormatting,
28
+ showEmojis,
29
+ isCompact,
30
+ isReadOnly,
31
+ }: Props) {
32
+ return (
33
+ <form>
34
+ {!isReadOnly && <Input />}
35
+ {showAttachments && <Attachments />}
36
+ {showFormatting && <Formatting />}
37
+ {showEmojis && <Emojis />}
38
+ </form>
39
+ );
40
+ }
41
+ ```
42
+
43
+ **Correct (컴포지션 패턴):**
44
+
45
+ \`\`\`tsx
46
+ // ✅ 컴포지션으로 유연하게 구성
47
+ <Composer.Provider state={state} actions={actions}>
48
+ <Composer.Frame>
49
+ <Composer.Input />
50
+ <Composer.Footer>
51
+ <Composer.Emojis />
52
+ <Composer.Submit />
53
+ </Composer.Footer>
54
+ </Composer.Frame>
55
+ </Composer.Provider>
56
+ \`\`\`
57
+
58
+ ## Mandu Context
59
+
60
+ Mandu Island에서 이 패턴을 적용하는 방법을 설명합니다.
61
+
62
+ Reference: [관련 문서 링크](https://example.com)
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Naming Convention
68
+
69
+ - 파일명: `comp-{category}-{rule-name}.md`
70
+ - 예시: `comp-arch-compound-components.md`, `comp-state-context-interface.md`
71
+
72
+ ## Core Principle
73
+
74
+ **Lift state, compose internals, make state dependency-injectable.**
75
+
76
+ UI는 조합 가능한 조각들이고, 상태는 Provider가 주입합니다.
77
+ Provider를 바꾸면 UI는 그대로 유지됩니다.
@@ -1,146 +1,146 @@
1
- ---
2
- title: Use Composition Instead of Boolean Props
3
- impact: HIGH
4
- impactDescription: Prevents prop explosion and improves flexibility
5
- tags: composition, boolean, props, architecture
6
- ---
7
-
8
- ## Use Composition Instead of Boolean Props
9
-
10
- **Impact: HIGH (Prevents prop explosion and improves flexibility)**
11
-
12
- 동작을 커스터마이즈하기 위해 boolean props를 추가하지 마세요. 대신 컴포지션을 사용하세요.
13
-
14
- **Incorrect (boolean props 폭발):**
15
-
16
- ```tsx
17
- // ❌ Boolean props가 계속 늘어남
18
- function Card({
19
- title,
20
- children,
21
- showHeader,
22
- showFooter,
23
- showActions,
24
- isCompact,
25
- isHighlighted,
26
- isBordered,
27
- isClickable,
28
- isLoading,
29
- }: CardProps) {
30
- return (
31
- <div className={cn(
32
- "card",
33
- isCompact && "card--compact",
34
- isHighlighted && "card--highlighted",
35
- isBordered && "card--bordered",
36
- isClickable && "card--clickable",
37
- )}>
38
- {isLoading && <Spinner />}
39
- {showHeader && <Header>{title}</Header>}
40
- {children}
41
- {showFooter && <Footer />}
42
- {showActions && <Actions />}
43
- </div>
44
- );
45
- }
46
-
47
- // 사용 시 복잡한 props 조합
48
- <Card
49
- title="Settings"
50
- showHeader
51
- showFooter
52
- showActions
53
- isCompact
54
- isBordered
55
- isClickable={false}
56
- isLoading={loading}
57
- >
58
- {content}
59
- </Card>
60
- ```
61
-
62
- **Correct (컴포지션 패턴):**
63
-
64
- ```tsx
65
- // ✅ 기본 Card와 조합 가능한 서브컴포넌트
66
- function Card({ children, className }: CardProps) {
67
- return <div className={cn("card", className)}>{children}</div>;
68
- }
69
-
70
- function CardHeader({ children }: { children: React.ReactNode }) {
71
- return <div className="card-header">{children}</div>;
72
- }
73
-
74
- function CardFooter({ children }: { children: React.ReactNode }) {
75
- return <div className="card-footer">{children}</div>;
76
- }
77
-
78
- function CardActions({ children }: { children: React.ReactNode }) {
79
- return <div className="card-actions">{children}</div>;
80
- }
81
-
82
- // Variants는 명시적 컴포넌트로
83
- function CompactCard({ children }: CardProps) {
84
- return <Card className="card--compact">{children}</Card>;
85
- }
86
-
87
- function HighlightedCard({ children }: CardProps) {
88
- return <Card className="card--highlighted">{children}</Card>;
89
- }
90
-
91
- // Export
92
- export { Card, CardHeader, CardFooter, CardActions, CompactCard, HighlightedCard };
93
- ```
94
-
95
- **사용법:**
96
-
97
- ```tsx
98
- // 필요한 것만 명시적으로 조합
99
- <Card>
100
- <CardHeader>Settings</CardHeader>
101
- <SettingsContent />
102
- <CardFooter>
103
- <CardActions>
104
- <SaveButton />
105
- <CancelButton />
106
- </CardActions>
107
- </CardFooter>
108
- </Card>
109
-
110
- // Compact variant
111
- <CompactCard>
112
- <QuickStats />
113
- </CompactCard>
114
- ```
115
-
116
- ## Mandu Island에서의 적용
117
-
118
- ```tsx
119
- // app/dashboard/client.tsx
120
- "use client";
121
-
122
- // ❌ 피해야 할 패턴
123
- export function DashboardIsland({
124
- showCharts,
125
- showStats,
126
- showAlerts,
127
- isCompact,
128
- }: Props) { ... }
129
-
130
- // ✅ 권장 패턴
131
- export const Dashboard = {
132
- Provider: DashboardProvider,
133
- Charts: DashboardCharts,
134
- Stats: DashboardStats,
135
- Alerts: DashboardAlerts,
136
- CompactLayout: DashboardCompactLayout,
137
- };
138
- ```
139
-
140
- ## 언제 Boolean Props가 괜찮은가?
141
-
142
- - 단일 시각적 상태 (disabled, loading)
143
- - 토글 가능한 단일 기능 (checked, open)
144
- - 컴포지션이 과도한 경우의 간단한 변형
145
-
146
- Reference: [Avoid Boolean Props](https://spicefactory.co/blog/2019/03/26/how-to-avoid-the-boolean-trap-when-designing-react-components/)
1
+ ---
2
+ title: Use Composition Instead of Boolean Props
3
+ impact: HIGH
4
+ impactDescription: Prevents prop explosion and improves flexibility
5
+ tags: composition, boolean, props, architecture
6
+ ---
7
+
8
+ ## Use Composition Instead of Boolean Props
9
+
10
+ **Impact: HIGH (Prevents prop explosion and improves flexibility)**
11
+
12
+ 동작을 커스터마이즈하기 위해 boolean props를 추가하지 마세요. 대신 컴포지션을 사용하세요.
13
+
14
+ **Incorrect (boolean props 폭발):**
15
+
16
+ ```tsx
17
+ // ❌ Boolean props가 계속 늘어남
18
+ function Card({
19
+ title,
20
+ children,
21
+ showHeader,
22
+ showFooter,
23
+ showActions,
24
+ isCompact,
25
+ isHighlighted,
26
+ isBordered,
27
+ isClickable,
28
+ isLoading,
29
+ }: CardProps) {
30
+ return (
31
+ <div className={cn(
32
+ "card",
33
+ isCompact && "card--compact",
34
+ isHighlighted && "card--highlighted",
35
+ isBordered && "card--bordered",
36
+ isClickable && "card--clickable",
37
+ )}>
38
+ {isLoading && <Spinner />}
39
+ {showHeader && <Header>{title}</Header>}
40
+ {children}
41
+ {showFooter && <Footer />}
42
+ {showActions && <Actions />}
43
+ </div>
44
+ );
45
+ }
46
+
47
+ // 사용 시 복잡한 props 조합
48
+ <Card
49
+ title="Settings"
50
+ showHeader
51
+ showFooter
52
+ showActions
53
+ isCompact
54
+ isBordered
55
+ isClickable={false}
56
+ isLoading={loading}
57
+ >
58
+ {content}
59
+ </Card>
60
+ ```
61
+
62
+ **Correct (컴포지션 패턴):**
63
+
64
+ ```tsx
65
+ // ✅ 기본 Card와 조합 가능한 서브컴포넌트
66
+ function Card({ children, className }: CardProps) {
67
+ return <div className={cn("card", className)}>{children}</div>;
68
+ }
69
+
70
+ function CardHeader({ children }: { children: React.ReactNode }) {
71
+ return <div className="card-header">{children}</div>;
72
+ }
73
+
74
+ function CardFooter({ children }: { children: React.ReactNode }) {
75
+ return <div className="card-footer">{children}</div>;
76
+ }
77
+
78
+ function CardActions({ children }: { children: React.ReactNode }) {
79
+ return <div className="card-actions">{children}</div>;
80
+ }
81
+
82
+ // Variants는 명시적 컴포넌트로
83
+ function CompactCard({ children }: CardProps) {
84
+ return <Card className="card--compact">{children}</Card>;
85
+ }
86
+
87
+ function HighlightedCard({ children }: CardProps) {
88
+ return <Card className="card--highlighted">{children}</Card>;
89
+ }
90
+
91
+ // Export
92
+ export { Card, CardHeader, CardFooter, CardActions, CompactCard, HighlightedCard };
93
+ ```
94
+
95
+ **사용법:**
96
+
97
+ ```tsx
98
+ // 필요한 것만 명시적으로 조합
99
+ <Card>
100
+ <CardHeader>Settings</CardHeader>
101
+ <SettingsContent />
102
+ <CardFooter>
103
+ <CardActions>
104
+ <SaveButton />
105
+ <CancelButton />
106
+ </CardActions>
107
+ </CardFooter>
108
+ </Card>
109
+
110
+ // Compact variant
111
+ <CompactCard>
112
+ <QuickStats />
113
+ </CompactCard>
114
+ ```
115
+
116
+ ## Mandu Island에서의 적용
117
+
118
+ ```tsx
119
+ // app/dashboard/client.tsx
120
+ "use client";
121
+
122
+ // ❌ 피해야 할 패턴
123
+ export function DashboardIsland({
124
+ showCharts,
125
+ showStats,
126
+ showAlerts,
127
+ isCompact,
128
+ }: Props) { ... }
129
+
130
+ // ✅ 권장 패턴
131
+ export const Dashboard = {
132
+ Provider: DashboardProvider,
133
+ Charts: DashboardCharts,
134
+ Stats: DashboardStats,
135
+ Alerts: DashboardAlerts,
136
+ CompactLayout: DashboardCompactLayout,
137
+ };
138
+ ```
139
+
140
+ ## 언제 Boolean Props가 괜찮은가?
141
+
142
+ - 단일 시각적 상태 (disabled, loading)
143
+ - 토글 가능한 단일 기능 (checked, open)
144
+ - 컴포지션이 과도한 경우의 간단한 변형
145
+
146
+ Reference: [Avoid Boolean Props](https://spicefactory.co/blog/2019/03/26/how-to-avoid-the-boolean-trap-when-designing-react-components/)