@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,101 @@
1
+ import type {
2
+ PageBannerButtonProperties,
3
+ PageBannerProperties,
4
+ } from "@/codegen/component-properties.archive";
5
+ import { createElement, defineComponentHandler } from "@/codegen/core";
6
+ import * as metadata from "@/entities/data/__generated__/archive/component-sets";
7
+ import type { NormalizedInstanceNode, NormalizedTextNode } from "@/normalizer";
8
+ import { findAllInstances, findOne } from "@/utils/figma-node";
9
+ import { camelCase } from "change-case";
10
+ import { createLocalSnippetHelper } from "../../../element-factories";
11
+ import type { ComponentHandlerDeps } from "../../deps.interface";
12
+ import { match } from "ts-pattern";
13
+
14
+ const { createLocalSnippetElement } = createLocalSnippetHelper("page-banner");
15
+
16
+ const SUFFIX_BUTTON_KEY = "7dce4e1242761ccd8e5da42278fc2d870918039c";
17
+
18
+ const createPageBannerButtonHandler = (_ctx: ComponentHandlerDeps) =>
19
+ defineComponentHandler<PageBannerButtonProperties>(SUFFIX_BUTTON_KEY, (node) => {
20
+ return createElement(
21
+ "PageBannerButton",
22
+ undefined,
23
+ node.componentProperties["Label#39890:0"].value,
24
+ );
25
+ });
26
+
27
+ export const createPageBannerHandler = (ctx: ComponentHandlerDeps) => {
28
+ const buttonHandler = createPageBannerButtonHandler(ctx);
29
+
30
+ return defineComponentHandler<PageBannerProperties>(metadata.pageBanner.key, (node, traverse) => {
31
+ const { componentProperties: props } = node;
32
+
33
+ const { tag, suffix } = match(props.Interaction.value)
34
+ .with("Actionable", () => ({ tag: "ActionablePageBanner", suffix: undefined }))
35
+ .with("Dismissible", () => ({ tag: "DismissiblePageBanner", suffix: undefined }))
36
+ .with("Display", () => ({ tag: "PageBanner", suffix: undefined }))
37
+ .with("Display (With Action)", () => {
38
+ const [buttonNode] = findAllInstances<PageBannerButtonProperties>({
39
+ node,
40
+ key: SUFFIX_BUTTON_KEY,
41
+ });
42
+ const suffix = buttonNode ? buttonHandler.transform(buttonNode, traverse) : undefined;
43
+
44
+ return { tag: "PageBanner", suffix };
45
+ })
46
+ .with("Actionable (Custom)", () => ({
47
+ tag: "PageBanner",
48
+ suffix: createElement("div", undefined, "Custom Content"),
49
+ }))
50
+ .exhaustive();
51
+
52
+ const textNode = findOne(
53
+ node,
54
+ (child) => child.type === "TEXT" && child.name === "Text",
55
+ ) as NormalizedTextNode | null;
56
+
57
+ if (!textNode) {
58
+ return createLocalSnippetElement(tag, undefined, undefined, {
59
+ comment: "내용을 제공해주세요.",
60
+ });
61
+ }
62
+
63
+ const slices = textNode.segments;
64
+
65
+ let title: string | undefined;
66
+ let description: string | undefined;
67
+
68
+ switch (slices.length) {
69
+ case 1: {
70
+ description = slices[0]?.characters.trim();
71
+
72
+ break;
73
+ }
74
+ case 2: {
75
+ title = slices[0]?.characters.trim();
76
+ description = slices[1]?.characters.trim();
77
+
78
+ break;
79
+ }
80
+ }
81
+
82
+ const iconNode = findOne(
83
+ node,
84
+ (child) => child.type === "INSTANCE" && child.name === "icon",
85
+ ) as NormalizedInstanceNode | null;
86
+
87
+ const showPrefixIcon = props["Show Prefix Icon#11840:27"].value && iconNode;
88
+ const prefixIcon = showPrefixIcon ? ctx.iconHandler.transform(iconNode) : undefined;
89
+
90
+ const commonProps = {
91
+ title,
92
+ description,
93
+ prefixIcon,
94
+ tone: camelCase(props.Tone.value),
95
+ variant: camelCase(props.Variant.value),
96
+ ...(suffix && { suffix }),
97
+ };
98
+
99
+ return createLocalSnippetElement(tag, commonProps);
100
+ });
101
+ };
@@ -0,0 +1,55 @@
1
+ import type { ProgressCircleProperties } from "@/codegen/component-properties.archive";
2
+ import { defineComponentHandler } from "@/codegen/core";
3
+ import * as metadata from "@/entities/data/__generated__/archive/component-sets";
4
+ import { camelCase } from "change-case";
5
+ import { match } from "ts-pattern";
6
+ import { createLocalSnippetHelper } from "../../../element-factories";
7
+ import type { ComponentHandlerDeps } from "../../deps.interface";
8
+
9
+ const { createLocalSnippetElement } = createLocalSnippetHelper("progress-circle");
10
+
11
+ export const createProgressCircleHandler = (_ctx: ComponentHandlerDeps) =>
12
+ defineComponentHandler<ProgressCircleProperties>(
13
+ metadata.progressCircle.key,
14
+ ({ componentProperties: props }) => {
15
+ const { value, minValue, maxValue } = match(props.Value.value)
16
+ .with("Indeterminate", () => ({
17
+ value: undefined,
18
+ minValue: undefined,
19
+ maxValue: undefined,
20
+ }))
21
+ .with("0%", () => ({
22
+ value: 0,
23
+ minValue: 0,
24
+ maxValue: 100,
25
+ }))
26
+ .with("25%", () => ({
27
+ value: 25,
28
+ minValue: 0,
29
+ maxValue: 100,
30
+ }))
31
+ .with("75%", () => ({
32
+ value: 75,
33
+ minValue: 0,
34
+ maxValue: 100,
35
+ }))
36
+ .with("100%", () => ({
37
+ value: 100,
38
+ minValue: 0,
39
+ maxValue: 100,
40
+ }))
41
+ .exhaustive();
42
+
43
+ const commonProps = {
44
+ value,
45
+ minValue,
46
+ maxValue,
47
+ size: props.Size.value,
48
+ ...(props.Tone.value !== "Custom(inherit)" && {
49
+ tone: camelCase(props.Tone.value),
50
+ }),
51
+ };
52
+
53
+ return createLocalSnippetElement("ProgressCircle", commonProps);
54
+ },
55
+ );
@@ -0,0 +1,31 @@
1
+ import type { RadioProperties } from "@/codegen/component-properties.archive";
2
+ import { defineComponentHandler } from "@/codegen/core";
3
+ import * as metadata from "@/entities/data/__generated__/archive/component-sets";
4
+ import { createLocalSnippetHelper } from "../../../element-factories";
5
+ import type { ComponentHandlerDeps } from "../../deps.interface";
6
+ import { handleSizeProp } from "../../size";
7
+ import { camelCase } from "change-case";
8
+ import { match } from "ts-pattern";
9
+
10
+ const { createLocalSnippetElement } = createLocalSnippetHelper("radio-group");
11
+
12
+ export const createRadioGroupItemHandler = (_ctx: ComponentHandlerDeps) =>
13
+ defineComponentHandler<RadioProperties>(metadata.radio.key, ({ 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
+ ...(props.State.value === "Disabled" && {
21
+ disabled: true,
22
+ }),
23
+ label: props["Label#49990:171"].value,
24
+ value: props["Label#49990:171"].value,
25
+ size: handleSizeProp(props.Size.value),
26
+ tone,
27
+ weight: camelCase(props.Weight.value),
28
+ };
29
+
30
+ return createLocalSnippetElement("RadioGroupItem", commonProps);
31
+ });
@@ -0,0 +1,27 @@
1
+ import type { RadiomarkProperties } from "@/codegen/component-properties.archive";
2
+ import { defineComponentHandler } from "@/codegen/core";
3
+ import * as metadata from "@/entities/data/__generated__/archive/component-sets";
4
+ import { createLocalSnippetHelper } from "../../../element-factories";
5
+ import type { ComponentHandlerDeps } from "../../deps.interface";
6
+ import { handleSizeProp } from "../../size";
7
+ import { match } from "ts-pattern";
8
+
9
+ const { createLocalSnippetElement } = createLocalSnippetHelper("radio-group");
10
+
11
+ export const createRadiomarkHandler = (_ctx: ComponentHandlerDeps) =>
12
+ defineComponentHandler<RadiomarkProperties>(
13
+ metadata.radiomark.key,
14
+ ({ componentProperties: props }) => {
15
+ const tone = match(props.Tone.value)
16
+ .with("Neutral", () => "neutral")
17
+ .with("🚫[Deprecated]Brand", () => "brand")
18
+ .exhaustive();
19
+
20
+ const commonProps = {
21
+ tone,
22
+ size: handleSizeProp(props.Size.value),
23
+ };
24
+
25
+ return createLocalSnippetElement("Radiomark", commonProps);
26
+ },
27
+ );
@@ -0,0 +1,37 @@
1
+ import type { ReactionButtonProperties } from "@/codegen/component-properties.archive";
2
+ import { defineComponentHandler } from "@/codegen/core";
3
+ import * as metadata from "@/entities/data/__generated__/archive/component-sets";
4
+ import { createLocalSnippetHelper, createSeedReactElement } from "../../../element-factories";
5
+ import type { ComponentHandlerDeps } from "../../deps.interface";
6
+ import { handleSizeProp } from "../../size";
7
+
8
+ const { createLocalSnippetElement } = createLocalSnippetHelper("reaction-button");
9
+
10
+ export const createReactionButtonHandler = (ctx: ComponentHandlerDeps) =>
11
+ defineComponentHandler<ReactionButtonProperties>(
12
+ metadata.reactionButton.key,
13
+ ({ componentProperties: props }) => {
14
+ const commonProps = {
15
+ size: handleSizeProp(props.Size.value),
16
+ ...(props.State.value === "Loading" && {
17
+ loading: true,
18
+ }),
19
+ ...(props.State.value === "Disabled" && {
20
+ disabled: true,
21
+ }),
22
+ ...(props.Selected.value === "True" && {
23
+ defaultPressed: true,
24
+ }),
25
+ };
26
+
27
+ return createLocalSnippetElement("ReactionButton", commonProps, [
28
+ createSeedReactElement("PrefixIcon", {
29
+ svg: ctx.iconHandler.transform(props["Icon#12379:0"]),
30
+ }),
31
+ props["Label#6397:0"].value,
32
+ props["Show Count#6397:33"].value
33
+ ? createSeedReactElement("Count", {}, props["Count#15816:0"].value)
34
+ : undefined,
35
+ ]);
36
+ },
37
+ );
@@ -0,0 +1,67 @@
1
+ import type {
2
+ ActionButtonGhostProperties,
3
+ ActionButtonProperties,
4
+ ResultSectionProperties,
5
+ } from "@/codegen/component-properties.archive";
6
+ import { createElement, defineComponentHandler } from "@/codegen/core";
7
+ import * as metadata from "@/entities/data/__generated__/archive/component-sets";
8
+ import { findAllInstances } from "@/utils/figma-node";
9
+ import { createLocalSnippetHelper, createSeedReactElement } from "../../../element-factories";
10
+ import type { ComponentHandlerDeps } from "../../deps.interface";
11
+ import { createActionButtonGhostHandler, createActionButtonHandler } from "./action-button";
12
+ import { handleSizeProp } from "@/codegen/targets/react/component/size";
13
+
14
+ const { createLocalSnippetElement } = createLocalSnippetHelper("result-section");
15
+
16
+ export const createResultSectionHandler = (ctx: ComponentHandlerDeps) => {
17
+ const actionButtonHandler = createActionButtonHandler(ctx);
18
+ const ghostButtonHandler = createActionButtonGhostHandler(ctx);
19
+
20
+ return defineComponentHandler<ResultSectionProperties>(
21
+ metadata.resultSection.key,
22
+ (node, traverse) => {
23
+ const props = node.componentProperties;
24
+
25
+ const [actionButton] =
26
+ props["Show Buttons#53435:0"].value && props["ㄴShow First Button#53766:0"].value
27
+ ? findAllInstances<ActionButtonProperties>({
28
+ node,
29
+ key: actionButtonHandler.key,
30
+ })
31
+ : [undefined];
32
+
33
+ const [ghostButton] =
34
+ props["Show Buttons#53435:0"].value && props["ㄴShow Second Button#53766:3"].value
35
+ ? findAllInstances<ActionButtonGhostProperties>({
36
+ node,
37
+ key: ghostButtonHandler.key,
38
+ })
39
+ : [undefined];
40
+
41
+ const commonProps = {
42
+ size: handleSizeProp(props.Size.value),
43
+ ...(props["Show Asset#45154:14"].value && {
44
+ asset: createSeedReactElement(
45
+ "Box",
46
+ undefined,
47
+ createElement("div", undefined, undefined, { comment: "Asset Placeholder" }),
48
+ ),
49
+ }),
50
+ title: props["Title#16237:0"].value,
51
+ description: props["Description#16237:5"].value,
52
+ ...(actionButton && {
53
+ primaryActionProps: {
54
+ children: actionButtonHandler.transform(actionButton, traverse).children[0],
55
+ },
56
+ }),
57
+ ...(ghostButton && {
58
+ secondaryActionProps: {
59
+ children: ghostButtonHandler.transform(ghostButton, traverse).children[0],
60
+ },
61
+ }),
62
+ };
63
+
64
+ return createLocalSnippetElement("ResultSection", commonProps);
65
+ },
66
+ );
67
+ };
@@ -0,0 +1,64 @@
1
+ import type {
2
+ SegmentedControlItemProperties,
3
+ SegmentedControlProperties,
4
+ } from "@/codegen/component-properties.archive";
5
+ import { defineComponentHandler } from "@/codegen/core";
6
+ import * as metadata from "@/entities/data/__generated__/archive/component-sets";
7
+ import { findAllInstances } from "@/utils/figma-node";
8
+ import { createLocalSnippetHelper } from "../../../element-factories";
9
+ import type { ComponentHandlerDeps } from "../../deps.interface";
10
+
11
+ const { createLocalSnippetElement } = createLocalSnippetHelper("segmented-control");
12
+
13
+ const SEGMENTED_CONTROL_ITEM_KEY = "9a7ba0d4c041ddbce84ee48881788434fd6bccc8";
14
+ const createSegmentedControlItemHandler = (_ctx: ComponentHandlerDeps) =>
15
+ defineComponentHandler<SegmentedControlItemProperties>(
16
+ SEGMENTED_CONTROL_ITEM_KEY,
17
+ ({ componentProperties: props }) => {
18
+ const states = props.State.value.split("-");
19
+ const commonProps = {
20
+ value: props["Label#11366:15"].value,
21
+ ...(states.includes("Disabled") && {
22
+ disabled: true,
23
+ }),
24
+ };
25
+
26
+ return createLocalSnippetElement(
27
+ "SegmentedControlItem",
28
+ commonProps,
29
+ props["Label#11366:15"].value,
30
+ );
31
+ },
32
+ );
33
+
34
+ export const createSegmentedControlHandler = (ctx: ComponentHandlerDeps) => {
35
+ const segmentedControlItemHandler = createSegmentedControlItemHandler(ctx);
36
+
37
+ return defineComponentHandler<SegmentedControlProperties>(
38
+ metadata.segmentedControl.key,
39
+ (node, traverse) => {
40
+ const segments = findAllInstances<SegmentedControlItemProperties>({
41
+ node,
42
+ key: segmentedControlItemHandler.key,
43
+ });
44
+
45
+ const selectedSegment = segments.find((segment) =>
46
+ segment.componentProperties.State.value.split("-").includes("Selected"),
47
+ );
48
+
49
+ const segmentedControlChildren = segments.map((segment) =>
50
+ segmentedControlItemHandler.transform(segment, traverse),
51
+ );
52
+
53
+ const commonProps = {
54
+ ...(selectedSegment && {
55
+ defaultValue: selectedSegment.componentProperties["Label#11366:15"].value,
56
+ }),
57
+ };
58
+
59
+ return createLocalSnippetElement("SegmentedControl", commonProps, segmentedControlChildren, {
60
+ comment: "aria-label이나 aria-labelledby 중 하나를 제공해야 합니다.",
61
+ });
62
+ },
63
+ );
64
+ };
@@ -0,0 +1,26 @@
1
+ import type { SkeletonProperties } from "@/codegen/component-properties.archive";
2
+ import { defineComponentHandler } from "@/codegen/core";
3
+ import * as metadata from "@/entities/data/__generated__/archive/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.skeleton.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,114 @@
1
+ import type {
2
+ FieldFooterProperties,
3
+ FieldHeaderProperties,
4
+ SliderFieldProperties,
5
+ SliderProperties,
6
+ SliderTicksProperties,
7
+ } from "@/codegen/component-properties.archive";
8
+ import { defineComponentHandler } from "@/codegen/core";
9
+ import * as metadata from "@/entities/data/__generated__/archive/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
+ FIELD_KEYS,
18
+ type FieldFooterProps,
19
+ type FieldHeaderProps,
20
+ } from "@/codegen/targets/react/component/handlers/archive/field";
21
+
22
+ const { createLocalSnippetElement } = createLocalSnippetHelper("slider");
23
+
24
+ const SLIDER_TICK_KEY = "ace432ffb7a2af13bce549b19c932ac5f96a9a78";
25
+
26
+ function getSliderComment(props: { markers?: unknown; ticks?: unknown } & Record<string, unknown>) {
27
+ return [
28
+ "min, max, step 값을 적절히 조정해주세요.",
29
+ props.markers && "markers 배열을 채워주세요.",
30
+ props.ticks && "ticks 배열을 채워주세요.",
31
+ ]
32
+ .filter(Boolean)
33
+ .join(" ");
34
+ }
35
+
36
+ export const createSliderFieldHandler = (ctx: ComponentHandlerDeps) => {
37
+ const sliderHandler = createSliderHandler(ctx);
38
+ const fieldHeaderHandler = createFieldHeaderHandler(ctx);
39
+ const fieldFooterHandler = createFieldFooterHandler(ctx);
40
+
41
+ return defineComponentHandler<SliderFieldProperties>(
42
+ metadata.templateSliderField.key,
43
+ (node, traverse) => {
44
+ const props = node.componentProperties;
45
+
46
+ const [slider] = findAllInstances<SliderProperties>({ node, key: metadata.slider.key });
47
+ const [fieldHeader] = findAllInstances<FieldHeaderProperties>({
48
+ node,
49
+ key: FIELD_KEYS.HEADER,
50
+ });
51
+ const [fieldFooter] = findAllInstances<FieldFooterProperties>({
52
+ node,
53
+ key: FIELD_KEYS.FOOTER,
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.slider.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>({ node, key: SLIDER_TICK_KEY });
91
+
92
+ const commonProps = {
93
+ min,
94
+ max,
95
+ defaultValues,
96
+ hideRange: props["Show Active Track#48156:0"].value === false,
97
+ ...(props["Show Markers#49596:0"].value === true && {
98
+ markers: [],
99
+ }),
100
+ ...(props["Has Tick Mark#47921:0"].value === true &&
101
+ ticks && {
102
+ ticks: [],
103
+ tickWeight: ticks.componentProperties.Type.value === "Discrete" ? "thick" : "thin",
104
+ }),
105
+ ...(props.State.value === "Disabled" && {
106
+ disabled: true,
107
+ }),
108
+ };
109
+
110
+ return createLocalSnippetElement("Slider", commonProps, undefined, {
111
+ comment: getSliderComment(commonProps),
112
+ });
113
+ });
114
+ };
@@ -0,0 +1,25 @@
1
+ import type { SnackbarProperties } from "@/codegen/component-properties.archive";
2
+ import { defineComponentHandler } from "@/codegen/core";
3
+ import * as metadata from "@/entities/data/__generated__/archive/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.snackbar.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,39 @@
1
+ import type { SwitchProperties } from "@/codegen/component-properties.archive";
2
+ import { defineComponentHandler } from "@/codegen/core";
3
+ import * as metadata from "@/entities/data/__generated__/archive/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._switch.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
+ if (props["Layout(Figma Only)"].value === "🚫[Switch Mark 사용] Switch Only") {
25
+ return createLocalSnippetElement("Switchmark", commonProps);
26
+ }
27
+
28
+ return createLocalSnippetElement("Switch", {
29
+ ...commonProps,
30
+ label: props["Label#36578:0"].value,
31
+ ...(props.Selected.value === "True" && {
32
+ defaultChecked: true,
33
+ }),
34
+ ...(props.State.value === "Disabled" && {
35
+ disabled: true,
36
+ }),
37
+ });
38
+ },
39
+ );
@@ -0,0 +1,26 @@
1
+ import type { SwitchmarkProperties } from "@/codegen/component-properties.archive";
2
+ import { defineComponentHandler } from "@/codegen/core";
3
+ import * as metadata from "@/entities/data/__generated__/archive/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.switchmark.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
+ );