@seed-design/figma 0.0.0-alpha-20260324091316

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 (181) hide show
  1. package/lib/codegen/index.cjs +23543 -0
  2. package/lib/codegen/index.d.ts +2957 -0
  3. package/lib/codegen/index.d.ts.map +1 -0
  4. package/lib/codegen/index.js +23514 -0
  5. package/lib/codegen/targets/react/index.cjs +31980 -0
  6. package/lib/codegen/targets/react/index.d.ts +308 -0
  7. package/lib/codegen/targets/react/index.d.ts.map +1 -0
  8. package/lib/codegen/targets/react/index.js +31961 -0
  9. package/lib/index.cjs +26905 -0
  10. package/lib/index.d.ts +221 -0
  11. package/lib/index.d.ts.map +1 -0
  12. package/lib/index.js +26884 -0
  13. package/package.json +56 -0
  14. package/src/codegen/component-properties.archive.ts +1019 -0
  15. package/src/codegen/component-properties.ts +369 -0
  16. package/src/codegen/core/codegen.ts +112 -0
  17. package/src/codegen/core/component-handler.ts +23 -0
  18. package/src/codegen/core/component-type-helper.ts +35 -0
  19. package/src/codegen/core/element-transformer.ts +13 -0
  20. package/src/codegen/core/index.ts +19 -0
  21. package/src/codegen/core/infer-layout.test.ts +286 -0
  22. package/src/codegen/core/infer-layout.ts +416 -0
  23. package/src/codegen/core/jsx.ts +174 -0
  24. package/src/codegen/core/props-converter.ts +78 -0
  25. package/src/codegen/core/value-resolver.ts +381 -0
  26. package/src/codegen/default-services.ts +44 -0
  27. package/src/codegen/index.ts +3 -0
  28. package/src/codegen/skip-components.ts +7 -0
  29. package/src/codegen/targets/figma/frame.ts +38 -0
  30. package/src/codegen/targets/figma/index.ts +6 -0
  31. package/src/codegen/targets/figma/instance.ts +36 -0
  32. package/src/codegen/targets/figma/pipeline.ts +106 -0
  33. package/src/codegen/targets/figma/props.ts +262 -0
  34. package/src/codegen/targets/figma/shape.ts +65 -0
  35. package/src/codegen/targets/figma/text.ts +30 -0
  36. package/src/codegen/targets/figma/value-resolver.ts +75 -0
  37. package/src/codegen/targets/index.ts +2 -0
  38. package/src/codegen/targets/react/component/deps.interface.ts +7 -0
  39. package/src/codegen/targets/react/component/handlers/action-button.ts +149 -0
  40. package/src/codegen/targets/react/component/handlers/alert-dialog.ts +120 -0
  41. package/src/codegen/targets/react/component/handlers/app-bar.ts +169 -0
  42. package/src/codegen/targets/react/component/handlers/archive/action-button.ts +144 -0
  43. package/src/codegen/targets/react/component/handlers/archive/alert-dialog.ts +122 -0
  44. package/src/codegen/targets/react/component/handlers/archive/app-bar.ts +149 -0
  45. package/src/codegen/targets/react/component/handlers/archive/avatar-stack.ts +35 -0
  46. package/src/codegen/targets/react/component/handlers/archive/avatar.ts +55 -0
  47. package/src/codegen/targets/react/component/handlers/archive/badge.ts +18 -0
  48. package/src/codegen/targets/react/component/handlers/archive/bottom-sheet.ts +70 -0
  49. package/src/codegen/targets/react/component/handlers/archive/callout.ts +88 -0
  50. package/src/codegen/targets/react/component/handlers/archive/checkbox.ts +43 -0
  51. package/src/codegen/targets/react/component/handlers/archive/checkmark.ts +29 -0
  52. package/src/codegen/targets/react/component/handlers/archive/chip.ts +90 -0
  53. package/src/codegen/targets/react/component/handlers/archive/contextual-floating-button.ts +52 -0
  54. package/src/codegen/targets/react/component/handlers/archive/divider.ts +25 -0
  55. package/src/codegen/targets/react/component/handlers/archive/field-button.ts +197 -0
  56. package/src/codegen/targets/react/component/handlers/archive/field.ts +167 -0
  57. package/src/codegen/targets/react/component/handlers/archive/floating-action-button.ts +48 -0
  58. package/src/codegen/targets/react/component/handlers/archive/help-bubble.ts +73 -0
  59. package/src/codegen/targets/react/component/handlers/archive/identity-placeholder.ts +21 -0
  60. package/src/codegen/targets/react/component/handlers/archive/index.ts +40 -0
  61. package/src/codegen/targets/react/component/handlers/archive/legacy-select-box.ts +89 -0
  62. package/src/codegen/targets/react/component/handlers/archive/legacy-text-field.ts +198 -0
  63. package/src/codegen/targets/react/component/handlers/archive/list-header.ts +20 -0
  64. package/src/codegen/targets/react/component/handlers/archive/list-item.ts +162 -0
  65. package/src/codegen/targets/react/component/handlers/archive/manner-temp-badge.ts +21 -0
  66. package/src/codegen/targets/react/component/handlers/archive/manner-temp.ts +18 -0
  67. package/src/codegen/targets/react/component/handlers/archive/menu-sheet.ts +108 -0
  68. package/src/codegen/targets/react/component/handlers/archive/page-banner.ts +101 -0
  69. package/src/codegen/targets/react/component/handlers/archive/progress-circle.ts +55 -0
  70. package/src/codegen/targets/react/component/handlers/archive/radio-group.ts +31 -0
  71. package/src/codegen/targets/react/component/handlers/archive/radiomark.ts +27 -0
  72. package/src/codegen/targets/react/component/handlers/archive/reaction-button.ts +37 -0
  73. package/src/codegen/targets/react/component/handlers/archive/result-section.ts +67 -0
  74. package/src/codegen/targets/react/component/handlers/archive/segmented-control.ts +64 -0
  75. package/src/codegen/targets/react/component/handlers/archive/skeleton.ts +26 -0
  76. package/src/codegen/targets/react/component/handlers/archive/slider.ts +114 -0
  77. package/src/codegen/targets/react/component/handlers/archive/snackbar.ts +25 -0
  78. package/src/codegen/targets/react/component/handlers/archive/switch.ts +39 -0
  79. package/src/codegen/targets/react/component/handlers/archive/switchmark.ts +26 -0
  80. package/src/codegen/targets/react/component/handlers/archive/tabs.ts +297 -0
  81. package/src/codegen/targets/react/component/handlers/archive/tag-group.ts +86 -0
  82. package/src/codegen/targets/react/component/handlers/archive/text-field.ts +264 -0
  83. package/src/codegen/targets/react/component/handlers/archive/toggle-button.ts +43 -0
  84. package/src/codegen/targets/react/component/handlers/avatar-stack.ts +38 -0
  85. package/src/codegen/targets/react/component/handlers/avatar.ts +58 -0
  86. package/src/codegen/targets/react/component/handlers/badge.ts +18 -0
  87. package/src/codegen/targets/react/component/handlers/bottom-sheet.ts +74 -0
  88. package/src/codegen/targets/react/component/handlers/callout.ts +88 -0
  89. package/src/codegen/targets/react/component/handlers/checkbox.ts +129 -0
  90. package/src/codegen/targets/react/component/handlers/checkmark.ts +29 -0
  91. package/src/codegen/targets/react/component/handlers/chip.ts +93 -0
  92. package/src/codegen/targets/react/component/handlers/content-placeholder.ts +20 -0
  93. package/src/codegen/targets/react/component/handlers/contextual-floating-button.ts +52 -0
  94. package/src/codegen/targets/react/component/handlers/divider.ts +25 -0
  95. package/src/codegen/targets/react/component/handlers/field-button.ts +192 -0
  96. package/src/codegen/targets/react/component/handlers/field.ts +164 -0
  97. package/src/codegen/targets/react/component/handlers/floating-action-button.ts +45 -0
  98. package/src/codegen/targets/react/component/handlers/help-bubble.ts +73 -0
  99. package/src/codegen/targets/react/component/handlers/identity-placeholder.ts +20 -0
  100. package/src/codegen/targets/react/component/handlers/image-frame.ts +147 -0
  101. package/src/codegen/targets/react/component/handlers/index.ts +43 -0
  102. package/src/codegen/targets/react/component/handlers/legacy-select-box.ts +87 -0
  103. package/src/codegen/targets/react/component/handlers/legacy-text-field.ts +196 -0
  104. package/src/codegen/targets/react/component/handlers/list-header.ts +20 -0
  105. package/src/codegen/targets/react/component/handlers/list-item.ts +163 -0
  106. package/src/codegen/targets/react/component/handlers/manner-temp-badge.ts +21 -0
  107. package/src/codegen/targets/react/component/handlers/manner-temp.ts +18 -0
  108. package/src/codegen/targets/react/component/handlers/menu-sheet.ts +111 -0
  109. package/src/codegen/targets/react/component/handlers/page-banner.ts +106 -0
  110. package/src/codegen/targets/react/component/handlers/progress-circle.ts +55 -0
  111. package/src/codegen/targets/react/component/handlers/radio-group.ts +109 -0
  112. package/src/codegen/targets/react/component/handlers/radiomark.ts +27 -0
  113. package/src/codegen/targets/react/component/handlers/reaction-button.ts +37 -0
  114. package/src/codegen/targets/react/component/handlers/result-section.ts +67 -0
  115. package/src/codegen/targets/react/component/handlers/segmented-control.ts +63 -0
  116. package/src/codegen/targets/react/component/handlers/select-box.ts +333 -0
  117. package/src/codegen/targets/react/component/handlers/skeleton.ts +26 -0
  118. package/src/codegen/targets/react/component/handlers/slider.ts +117 -0
  119. package/src/codegen/targets/react/component/handlers/snackbar.ts +25 -0
  120. package/src/codegen/targets/react/component/handlers/switch.ts +35 -0
  121. package/src/codegen/targets/react/component/handlers/switchmark.ts +26 -0
  122. package/src/codegen/targets/react/component/handlers/tabs.ts +298 -0
  123. package/src/codegen/targets/react/component/handlers/tag-group.ts +90 -0
  124. package/src/codegen/targets/react/component/handlers/text-field.ts +253 -0
  125. package/src/codegen/targets/react/component/handlers/toggle-button.ts +43 -0
  126. package/src/codegen/targets/react/component/index.ts +24 -0
  127. package/src/codegen/targets/react/component/size.ts +22 -0
  128. package/src/codegen/targets/react/element-factories.ts +59 -0
  129. package/src/codegen/targets/react/frame.ts +96 -0
  130. package/src/codegen/targets/react/icon.ts +55 -0
  131. package/src/codegen/targets/react/index.ts +7 -0
  132. package/src/codegen/targets/react/instance.ts +82 -0
  133. package/src/codegen/targets/react/pipeline.ts +133 -0
  134. package/src/codegen/targets/react/props.ts +417 -0
  135. package/src/codegen/targets/react/shape.ts +47 -0
  136. package/src/codegen/targets/react/text.ts +31 -0
  137. package/src/codegen/targets/react/value-resolver.ts +93 -0
  138. package/src/entities/component.interface.ts +7 -0
  139. package/src/entities/component.repository.ts +16 -0
  140. package/src/entities/data/__generated__/archive/component-sets/index.d.ts +2074 -0
  141. package/src/entities/data/__generated__/archive/component-sets/index.mjs +2074 -0
  142. package/src/entities/data/__generated__/archive/components/index.d.ts +116 -0
  143. package/src/entities/data/__generated__/archive/components/index.mjs +116 -0
  144. package/src/entities/data/__generated__/archive/styles/index.d.ts +3 -0
  145. package/src/entities/data/__generated__/archive/styles/index.mjs +429 -0
  146. package/src/entities/data/__generated__/archive/variable-collections/index.d.ts +3 -0
  147. package/src/entities/data/__generated__/archive/variable-collections/index.mjs +501 -0
  148. package/src/entities/data/__generated__/archive/variables/index.d.ts +3 -0
  149. package/src/entities/data/__generated__/archive/variables/index.mjs +7019 -0
  150. package/src/entities/data/__generated__/component-sets/index.d.ts +4325 -0
  151. package/src/entities/data/__generated__/component-sets/index.mjs +4325 -0
  152. package/src/entities/data/__generated__/components/index.d.ts +378 -0
  153. package/src/entities/data/__generated__/components/index.mjs +378 -0
  154. package/src/entities/data/__generated__/icons/index.d.ts +3 -0
  155. package/src/entities/data/__generated__/icons/index.mjs +3476 -0
  156. package/src/entities/data/__generated__/styles/index.d.ts +3 -0
  157. package/src/entities/data/__generated__/styles/index.mjs +436 -0
  158. package/src/entities/data/__generated__/variable-collections/index.d.ts +3 -0
  159. package/src/entities/data/__generated__/variable-collections/index.mjs +479 -0
  160. package/src/entities/data/__generated__/variables/index.d.ts +3 -0
  161. package/src/entities/data/__generated__/variables/index.mjs +6969 -0
  162. package/src/entities/icon.interface.ts +5 -0
  163. package/src/entities/icon.repository.ts +11 -0
  164. package/src/entities/icon.service.ts +26 -0
  165. package/src/entities/index.ts +60 -0
  166. package/src/entities/style.interface.ts +5 -0
  167. package/src/entities/style.repository.ts +27 -0
  168. package/src/entities/style.service.ts +36 -0
  169. package/src/entities/variable.interface.ts +18 -0
  170. package/src/entities/variable.repository.ts +57 -0
  171. package/src/entities/variable.service.ts +101 -0
  172. package/src/index.ts +3 -0
  173. package/src/normalizer/from-plugin.ts +602 -0
  174. package/src/normalizer/from-rest.ts +577 -0
  175. package/src/normalizer/index.ts +3 -0
  176. package/src/normalizer/types.ts +208 -0
  177. package/src/utils/common.ts +38 -0
  178. package/src/utils/css.ts +19 -0
  179. package/src/utils/figma-gradient.ts +72 -0
  180. package/src/utils/figma-node.ts +95 -0
  181. package/src/utils/figma-variable.ts +49 -0
@@ -0,0 +1,333 @@
1
+ import type {
2
+ FieldFooterProperties,
3
+ FieldHeaderProperties,
4
+ SelectBoxGroupFieldProperties,
5
+ SelectBoxGroupProperties,
6
+ SelectBoxHorizontalProperties,
7
+ SelectBoxPrefixIconProperties,
8
+ SelectBoxVerticalProperties,
9
+ } from "@/codegen/component-properties";
10
+ import { defineComponentHandler } from "@/codegen/core";
11
+ import * as metadata from "@/entities/data/__generated__/component-sets";
12
+ import * as components from "@/entities/data/__generated__/components";
13
+ import { findAllInstances } from "@/utils/figma-node";
14
+ import { match } from "ts-pattern";
15
+ import { createLocalSnippetHelper, createSeedReactElement } from "../../element-factories";
16
+ import type { ComponentHandlerDeps } from "../deps.interface";
17
+ import {
18
+ createFieldFooterHandler,
19
+ createFieldHeaderHandler,
20
+ type FieldFooterProps,
21
+ type FieldHeaderProps,
22
+ } from "@/codegen/targets/react/component/handlers/field";
23
+
24
+ const PREFIX_KEYS = [
25
+ components.componentSelectBoxItemPrefixIcon.key,
26
+ components.componentSelectBoxItemPrefixAvatar.key,
27
+ components.componentSelectBoxItemPrefixImage.key,
28
+ components.componentSelectBoxItemPrefixBadge.key,
29
+ components.componentSelectBoxItemPrefixCustom.key,
30
+ ];
31
+
32
+ const { createLocalSnippetElement } = createLocalSnippetHelper("select-box");
33
+
34
+ const createSelectBoxHorizontalHandler = (ctx: ComponentHandlerDeps) =>
35
+ defineComponentHandler<SelectBoxHorizontalProperties>(
36
+ metadata.componentSelectBoxItemHorizontal.key,
37
+ (node) => {
38
+ const { componentProperties: props } = node;
39
+
40
+ const { tag, suffix } = match(props.Control.value)
41
+ .with("Checkmark", () => ({
42
+ tag: "CheckSelectBox" as const,
43
+ suffix: createLocalSnippetElement("CheckSelectBoxCheckmark"),
44
+ }))
45
+ .with("Radiomark", () => ({
46
+ tag: "RadioSelectBoxItem" as const,
47
+ suffix: createLocalSnippetElement("RadioSelectBoxRadiomark"),
48
+ }))
49
+ .with("None", () => ({
50
+ tag: "UnknownSelectBox" as const,
51
+ suffix: undefined,
52
+ }))
53
+ .exhaustive();
54
+
55
+ const prefixNode = (() => {
56
+ if (props["Has Prefix#28452:85"].value === false) return null;
57
+
58
+ for (const key of PREFIX_KEYS) {
59
+ const [found] = findAllInstances<SelectBoxPrefixIconProperties | {}>({ node, key });
60
+
61
+ if (found) return found;
62
+ }
63
+
64
+ return null;
65
+ })();
66
+
67
+ const prefixIcon = (() => {
68
+ if (!prefixNode) return undefined;
69
+
70
+ if ("Icon#2475:0" in prefixNode.componentProperties) {
71
+ return ctx.iconHandler.transform(prefixNode.componentProperties["Icon#2475:0"]);
72
+ }
73
+
74
+ // React Select Box only supports icon for now
75
+ // return undefined if not icon
76
+
77
+ return undefined;
78
+ })();
79
+
80
+ const commonProps = {
81
+ // layout: "horizontal",
82
+
83
+ ...(prefixIcon && { prefixIcon }),
84
+
85
+ label: props["Title#28452:21"].value,
86
+
87
+ ...(props["Show Description#28469:1"].value && {
88
+ description: props["Description#56540:0"].value,
89
+ }),
90
+
91
+ ...(suffix && { suffix }),
92
+
93
+ ...(props["Show Custom Content#56903:0"].value && {
94
+ footer: createSeedReactElement("Box", undefined, "Footer Placeholder"),
95
+ }),
96
+
97
+ ...(tag === "RadioSelectBoxItem" && {
98
+ value: props["Title#28452:21"].value,
99
+ }),
100
+
101
+ ...(tag === "CheckSelectBox" &&
102
+ props.Selected.value === "True" && {
103
+ defaultChecked: true,
104
+ }),
105
+
106
+ ...(props.State.value === "Disabled" && {
107
+ disabled: true,
108
+ }),
109
+ };
110
+
111
+ return createLocalSnippetElement(tag, commonProps, undefined);
112
+ },
113
+ );
114
+
115
+ const createSelectBoxVerticalHandler = (ctx: ComponentHandlerDeps) =>
116
+ defineComponentHandler<SelectBoxVerticalProperties>(
117
+ metadata.componentSelectBoxItemVertical.key,
118
+ (node) => {
119
+ const { componentProperties: props } = node;
120
+
121
+ const { tag, suffix } = match(props.Control.value)
122
+ .with("Checkmark", () => ({
123
+ tag: "CheckSelectBox" as const,
124
+ suffix: createLocalSnippetElement("CheckSelectBoxCheckmark"),
125
+ }))
126
+ .with("Radiomark", () => ({
127
+ tag: "RadioSelectBoxItem" as const,
128
+ suffix: createLocalSnippetElement("RadioSelectBoxRadiomark"),
129
+ }))
130
+ .with("None", () => ({
131
+ tag: "UnknownSelectBox" as const,
132
+ suffix: undefined,
133
+ }))
134
+ .exhaustive();
135
+
136
+ const prefixNode = (() => {
137
+ if (props["Has Prefix#58766:115"].value === false) return null;
138
+
139
+ for (const key of PREFIX_KEYS) {
140
+ const [found] = findAllInstances<SelectBoxPrefixIconProperties | {}>({ node, key });
141
+
142
+ if (found) return found;
143
+ }
144
+
145
+ return null;
146
+ })();
147
+
148
+ const prefixIcon = (() => {
149
+ if (!prefixNode) return undefined;
150
+
151
+ if ("Icon#2475:0" in prefixNode.componentProperties) {
152
+ return ctx.iconHandler.transform(prefixNode.componentProperties["Icon#2475:0"]);
153
+ }
154
+
155
+ // React Select Box only supports icon for now
156
+ // return undefined if not icon
157
+
158
+ return undefined;
159
+ })();
160
+
161
+ const commonProps = {
162
+ // layout: "vertical",
163
+
164
+ ...(prefixIcon && { prefixIcon }),
165
+
166
+ label: props["Title#58766:114"].value,
167
+
168
+ ...(props["Show Description#58766:117"].value && {
169
+ description: props["Description#58766:118"].value,
170
+ }),
171
+
172
+ ...(suffix && { suffix }),
173
+
174
+ ...(props["Show Custom Content#58766:119"].value && {
175
+ footer: createSeedReactElement("Box", undefined, "Footer Placeholder"),
176
+ }),
177
+
178
+ ...(tag === "RadioSelectBoxItem" && {
179
+ value: props["Title#58766:114"].value,
180
+ }),
181
+
182
+ ...(tag === "CheckSelectBox" &&
183
+ props.Selected.value === "True" && {
184
+ defaultChecked: true,
185
+ }),
186
+
187
+ ...(props.State.value === "Disabled" && {
188
+ disabled: true,
189
+ }),
190
+ };
191
+
192
+ return createLocalSnippetElement(tag, commonProps, undefined);
193
+ },
194
+ );
195
+
196
+ export const createSelectBoxGroupHandler = (ctx: ComponentHandlerDeps) => {
197
+ const horizontalHandler = createSelectBoxHorizontalHandler(ctx);
198
+ const verticalHandler = createSelectBoxVerticalHandler(ctx);
199
+
200
+ return defineComponentHandler<SelectBoxGroupProperties>(
201
+ metadata.componentSelectBoxGroup.key,
202
+ (node, traverse) => {
203
+ const props = node.componentProperties;
204
+
205
+ const horizontalBoxes = findAllInstances<SelectBoxHorizontalProperties>({
206
+ node,
207
+ key: horizontalHandler.key,
208
+ });
209
+
210
+ const verticalBoxes = findAllInstances<SelectBoxVerticalProperties>({
211
+ node,
212
+ key: verticalHandler.key,
213
+ });
214
+
215
+ const boxes = [...horizontalBoxes, ...verticalBoxes];
216
+
217
+ const selectedSelectBox = boxes.find(
218
+ (selectBox) => selectBox.componentProperties.Selected.value === "True",
219
+ );
220
+
221
+ const { tag, comment } = match([
222
+ boxes.every((box) => box.componentProperties.Control.value === "Radiomark"),
223
+ boxes.every((box) => box.componentProperties.Control.value === "Checkmark"),
224
+ ])
225
+ .with([true, false], () => ({ tag: "RadioSelectBoxRoot" as const, comment: undefined }))
226
+ .with([false, true], () => ({ tag: "CheckSelectBoxGroup" as const, comment: undefined }))
227
+ .otherwise(() => ({
228
+ tag: "UnknownSelectBoxGroup" as const,
229
+ comment:
230
+ "모든 SelectBox의 Control 프로퍼티가 동일하지 않거나 None이 포함되어 있기 때문에 코드에서 어떻게 사용될지 파악할 수 없습니다. 모든 children 요소들을 CheckSelectBox 또는 RadioSelectBoxItem으로 변경하고 CheckSelectBoxGroup 또는 RadioSelectBoxRoot로 묶어 사용하세요.",
231
+ }));
232
+
233
+ const selectedSelectBoxProperties = selectedSelectBox?.componentProperties;
234
+
235
+ const commonProps = {
236
+ columns: Number(props.Column.value[0]),
237
+
238
+ ...(selectedSelectBoxProperties &&
239
+ tag === "RadioSelectBoxRoot" && {
240
+ defaultValue:
241
+ "Title#28452:21" in selectedSelectBoxProperties
242
+ ? selectedSelectBoxProperties["Title#28452:21"].value
243
+ : selectedSelectBoxProperties["Title#58766:114"].value,
244
+ }),
245
+ };
246
+
247
+ const children = [
248
+ ...horizontalBoxes.map((box) => horizontalHandler.transform(box, traverse)),
249
+ ...verticalBoxes.map((box) => verticalHandler.transform(box, traverse)),
250
+ ];
251
+
252
+ return createLocalSnippetElement(tag, commonProps, children, { comment });
253
+ },
254
+ );
255
+ };
256
+
257
+ export const createSelectBoxGroupFieldHandler = (ctx: ComponentHandlerDeps) => {
258
+ const fieldHeaderHandler = createFieldHeaderHandler(ctx);
259
+ const fieldFooterHandler = createFieldFooterHandler(ctx);
260
+ const selectBoxGroupHandler = createSelectBoxGroupHandler(ctx);
261
+
262
+ return defineComponentHandler<SelectBoxGroupFieldProperties>(
263
+ metadata.templateSelectBoxField.key,
264
+ (node, traverse) => {
265
+ const { componentProperties: props } = node;
266
+
267
+ const [group] = findAllInstances<SelectBoxGroupProperties>({
268
+ node,
269
+ key: selectBoxGroupHandler.key,
270
+ });
271
+
272
+ const [fieldHeader] = findAllInstances<FieldHeaderProperties>({
273
+ node,
274
+ key: fieldHeaderHandler.key,
275
+ });
276
+ const [fieldFooter] = findAllInstances<FieldFooterProperties>({
277
+ node,
278
+ key: fieldFooterHandler.key,
279
+ });
280
+
281
+ const __headerProps =
282
+ props["Show Header#40606:8"].value && fieldHeader
283
+ ? (fieldHeaderHandler.transform(fieldHeader, traverse).props as FieldHeaderProps)
284
+ : {};
285
+ const __footerProps =
286
+ props["Show Footer#40606:9"].value && fieldFooter
287
+ ? (fieldFooterHandler.transform(fieldFooter, traverse).props as FieldFooterProps)
288
+ : {};
289
+
290
+ const groupResult = selectBoxGroupHandler.transform(group, traverse);
291
+
292
+ const { headerProps, footerProps } = match(
293
+ groupResult.tag as "RadioSelectBoxRoot" | "CheckSelectBoxGroup" | "UnknownSelectBoxGroup",
294
+ )
295
+ .with("RadioSelectBoxRoot", () => {
296
+ const { required: _required, ...headerProps } = __headerProps;
297
+ const { maxGraphemeCount: _maxGraphemeCount, ...footerProps } = __footerProps;
298
+
299
+ return { headerProps, footerProps };
300
+ })
301
+ .with("CheckSelectBoxGroup", () => {
302
+ const { required: _required, ...headerProps } = __headerProps;
303
+ const {
304
+ maxGraphemeCount: _maxGraphemeCount,
305
+ invalid: _invalid,
306
+ ...footerProps
307
+ } = __footerProps;
308
+
309
+ return { headerProps, footerProps };
310
+ })
311
+ .with("UnknownSelectBoxGroup", () => {
312
+ const { required: _required, ...headerProps } = __headerProps;
313
+ const {
314
+ maxGraphemeCount: _maxGraphemeCount,
315
+ invalid: _invalid,
316
+ ...footerProps
317
+ } = __footerProps;
318
+
319
+ return { headerProps, footerProps };
320
+ })
321
+ .exhaustive();
322
+
323
+ return {
324
+ ...groupResult,
325
+ props: {
326
+ ...groupResult.props,
327
+ ...headerProps,
328
+ ...footerProps,
329
+ },
330
+ };
331
+ },
332
+ );
333
+ };
@@ -0,0 +1,26 @@
1
+ import type { SkeletonProperties } from "@/codegen/component-properties";
2
+ import { defineComponentHandler } from "@/codegen/core";
3
+ import * as metadata from "@/entities/data/__generated__/component-sets";
4
+ import { camelCase } from "change-case";
5
+ import { match } from "ts-pattern";
6
+ import { createSeedReactElement } from "../../element-factories";
7
+ import type { ComponentHandlerDeps } from "../deps.interface";
8
+
9
+ export const createSkeletonHandler = (ctx: ComponentHandlerDeps) =>
10
+ defineComponentHandler<SkeletonProperties>(metadata.componentSkeleton.key, (node) => {
11
+ const { componentProperties: props, layoutSizingHorizontal, layoutSizingVertical } = node;
12
+
13
+ const commonProps = {
14
+ radius: camelCase(props.Radius.value),
15
+ width: match(layoutSizingHorizontal)
16
+ .with("FIXED", () => ctx.valueResolver.getFormattedValue.width(node))
17
+ .with("FILL", () => "full")
18
+ .otherwise(() => "full"),
19
+ height: match(layoutSizingVertical)
20
+ .with("FIXED", () => ctx.valueResolver.getFormattedValue.height(node))
21
+ .with("FILL", () => "full")
22
+ .otherwise(() => "full"),
23
+ };
24
+
25
+ return createSeedReactElement("Skeleton", commonProps);
26
+ });
@@ -0,0 +1,117 @@
1
+ import type {
2
+ FieldFooterProperties,
3
+ FieldHeaderProperties,
4
+ SliderFieldProperties,
5
+ SliderProperties,
6
+ SliderTicksProperties,
7
+ } from "@/codegen/component-properties";
8
+ import { defineComponentHandler } from "@/codegen/core";
9
+ import * as metadata from "@/entities/data/__generated__/component-sets";
10
+ import { createLocalSnippetHelper } from "../../element-factories";
11
+ import type { ComponentHandlerDeps } from "../deps.interface";
12
+ import { match } from "ts-pattern";
13
+ import { findAllInstances } from "@/utils/figma-node";
14
+ import {
15
+ createFieldFooterHandler,
16
+ createFieldHeaderHandler,
17
+ type FieldFooterProps,
18
+ type FieldHeaderProps,
19
+ } from "@/codegen/targets/react/component/handlers/field";
20
+
21
+ const { createLocalSnippetElement } = createLocalSnippetHelper("slider");
22
+
23
+ function getSliderComment(props: { markers?: unknown; ticks?: unknown } & Record<string, unknown>) {
24
+ return [
25
+ "min, max, step 값을 적절히 조정해주세요.",
26
+ props.markers && "markers 배열을 채워주세요.",
27
+ props.ticks && "ticks 배열을 채워주세요.",
28
+ ]
29
+ .filter(Boolean)
30
+ .join(" ");
31
+ }
32
+
33
+ export const createSliderFieldHandler = (ctx: ComponentHandlerDeps) => {
34
+ const sliderHandler = createSliderHandler(ctx);
35
+ const fieldHeaderHandler = createFieldHeaderHandler(ctx);
36
+ const fieldFooterHandler = createFieldFooterHandler(ctx);
37
+
38
+ return defineComponentHandler<SliderFieldProperties>(
39
+ metadata.templateSliderField.key,
40
+ (node, traverse) => {
41
+ const props = node.componentProperties;
42
+
43
+ const [slider] = findAllInstances<SliderProperties>({
44
+ node,
45
+ key: sliderHandler.key,
46
+ });
47
+ const [fieldHeader] = findAllInstances<FieldHeaderProperties>({
48
+ node,
49
+ key: fieldHeaderHandler.key,
50
+ });
51
+ const [fieldFooter] = findAllInstances<FieldFooterProperties>({
52
+ node,
53
+ key: fieldFooterHandler.key,
54
+ });
55
+
56
+ const sliderProps = sliderHandler.transform(slider, traverse).props;
57
+
58
+ // maxGraphemeCount and required can't be props of Slider
59
+ const { required: _required, ...headerProps } =
60
+ props["Show Header#40606:8"].value && fieldHeader
61
+ ? (fieldHeaderHandler.transform(fieldHeader, traverse).props as FieldHeaderProps)
62
+ : {};
63
+ const { maxGraphemeCount: _maxGraphemeCount, ...footerProps } =
64
+ props["Show Footer#40606:9"].value && fieldFooter
65
+ ? (fieldFooterHandler.transform(fieldFooter, traverse).props as FieldFooterProps)
66
+ : {};
67
+
68
+ const commonProps = {
69
+ ...sliderProps,
70
+ ...headerProps,
71
+ ...footerProps,
72
+ };
73
+
74
+ return createLocalSnippetElement("Slider", commonProps, undefined, {
75
+ comment: getSliderComment(commonProps),
76
+ });
77
+ },
78
+ );
79
+ };
80
+
81
+ export const createSliderHandler = (_ctx: ComponentHandlerDeps) => {
82
+ return defineComponentHandler<SliderProperties>(metadata.componentSlider.key, (node) => {
83
+ const { componentProperties: props } = node;
84
+
85
+ const { min, max, defaultValues } = match(props.Value.value)
86
+ .with("Single", () => ({ min: 0, max: 100, defaultValues: [50] }))
87
+ .with("Range", () => ({ min: 0, max: 100, defaultValues: [0, 50] }))
88
+ .exhaustive();
89
+
90
+ const [ticks] = findAllInstances<SliderTicksProperties>({
91
+ node,
92
+ key: metadata.privateComponentSliderItemTickMark.key,
93
+ });
94
+
95
+ const commonProps = {
96
+ min,
97
+ max,
98
+ defaultValues,
99
+ hideRange: props["Show Active Track#48156:0"].value === false,
100
+ ...(props["Show Markers#49596:0"].value === true && {
101
+ markers: [],
102
+ }),
103
+ ...(props["Has Tick Mark#47921:0"].value === true &&
104
+ ticks && {
105
+ ticks: [],
106
+ tickWeight: ticks.componentProperties.Type.value === "Discrete" ? "thick" : "thin",
107
+ }),
108
+ ...(props.State.value === "Disabled" && {
109
+ disabled: true,
110
+ }),
111
+ };
112
+
113
+ return createLocalSnippetElement("Slider", commonProps, undefined, {
114
+ comment: getSliderComment(commonProps),
115
+ });
116
+ });
117
+ };
@@ -0,0 +1,25 @@
1
+ import type { SnackbarProperties } from "@/codegen/component-properties";
2
+ import { defineComponentHandler } from "@/codegen/core";
3
+ import * as metadata from "@/entities/data/__generated__/component-sets";
4
+ import { camelCase } from "change-case";
5
+ import { createLocalSnippetHelper } from "../../element-factories";
6
+ import type { ComponentHandlerDeps } from "../deps.interface";
7
+
8
+ const { createLocalSnippetElement } = createLocalSnippetHelper("snackbar");
9
+
10
+ export const createSnackbarHandler = (_ctx: ComponentHandlerDeps) =>
11
+ defineComponentHandler<SnackbarProperties>(
12
+ metadata.componentSnackbar.key,
13
+ ({ componentProperties: props }) => {
14
+ const commonProps = {
15
+ message: props["Message#1528:4"].value,
16
+ variant: camelCase(props.Variant.value),
17
+ ...(props["Show Action#1528:0"].value && {
18
+ actionLabel: props["Action Label#1528:8"].value,
19
+ }),
20
+ };
21
+
22
+ // TODO: adapter.create({ render })
23
+ return createLocalSnippetElement("Snackbar", commonProps);
24
+ },
25
+ );
@@ -0,0 +1,35 @@
1
+ import type { SwitchProperties } from "@/codegen/component-properties";
2
+ import { defineComponentHandler } from "@/codegen/core";
3
+ import * as metadata from "@/entities/data/__generated__/component-sets";
4
+ import { createLocalSnippetHelper } from "../../element-factories";
5
+ import type { ComponentHandlerDeps } from "../deps.interface";
6
+ import { match } from "ts-pattern";
7
+
8
+ const { createLocalSnippetElement } = createLocalSnippetHelper("switch");
9
+
10
+ export const createSwitchHandler = (_ctx: ComponentHandlerDeps) =>
11
+ defineComponentHandler<SwitchProperties>(
12
+ metadata.componentSwitch.key,
13
+ ({ componentProperties: props }) => {
14
+ const tone = match(props.Tone.value)
15
+ .with("Neutral", () => "neutral")
16
+ .with("🚫[Deprecated] Brand", () => "brand")
17
+ .exhaustive();
18
+
19
+ const commonProps = {
20
+ tone,
21
+ size: props.Size.value,
22
+ };
23
+
24
+ return createLocalSnippetElement("Switch", {
25
+ ...commonProps,
26
+ label: props["Label#36578:0"].value,
27
+ ...(props.Selected.value === "True" && {
28
+ defaultChecked: true,
29
+ }),
30
+ ...(props.State.value === "Disabled" && {
31
+ disabled: true,
32
+ }),
33
+ });
34
+ },
35
+ );
@@ -0,0 +1,26 @@
1
+ import type { SwitchmarkProperties } from "@/codegen/component-properties";
2
+ import { defineComponentHandler } from "@/codegen/core";
3
+ import * as metadata from "@/entities/data/__generated__/component-sets";
4
+ import { createLocalSnippetHelper } from "../../element-factories";
5
+ import type { ComponentHandlerDeps } from "../deps.interface";
6
+ import { match } from "ts-pattern";
7
+
8
+ const { createLocalSnippetElement } = createLocalSnippetHelper("switch");
9
+
10
+ export const createSwitchmarkHandler = (_ctx: ComponentHandlerDeps) =>
11
+ defineComponentHandler<SwitchmarkProperties>(
12
+ metadata.componentSwitchmark.key,
13
+ ({ componentProperties: props }) => {
14
+ const tone = match(props.Tone.value)
15
+ .with("Neutral", () => "neutral")
16
+ .with("🚫[Deprecated] Brand", () => "brand")
17
+ .exhaustive();
18
+
19
+ const commonProps = {
20
+ tone,
21
+ size: props.Size.value,
22
+ };
23
+
24
+ return createLocalSnippetElement("Switchmark", commonProps);
25
+ },
26
+ );