@seed-design/figma 0.0.4 → 0.0.6

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 (211) hide show
  1. package/lib/index.cjs +10589 -12261
  2. package/lib/index.d.ts +1732 -41
  3. package/lib/index.js +10565 -12262
  4. package/package.json +2 -2
  5. package/src/codegen/context.ts +148 -0
  6. package/src/{component/type-helper.ts → codegen/core/component.ts} +1 -12
  7. package/src/codegen/core/index.ts +14 -0
  8. package/src/{jsx.ts → codegen/core/jsx.ts} +13 -3
  9. package/src/codegen/core/transformer.ts +40 -0
  10. package/src/{data → codegen/data}/icons.ts +2 -6
  11. package/src/{data → codegen/data}/styles.ts +87 -29
  12. package/src/codegen/data/variable-collections.ts +310 -0
  13. package/src/{data → codegen/data}/variables.ts +2821 -5887
  14. package/src/codegen/domain/codegen.service.ts +69 -0
  15. package/src/codegen/domain/figma-component.service.ts +21 -0
  16. package/src/codegen/domain/frame.service.ts +108 -0
  17. package/src/codegen/domain/icon.interface.ts +5 -0
  18. package/src/codegen/domain/icon.repository.ts +11 -0
  19. package/src/codegen/domain/icon.service.ts +35 -0
  20. package/src/codegen/domain/index.ts +22 -0
  21. package/src/codegen/domain/instance.service.ts +91 -0
  22. package/src/codegen/domain/props/container-layout-props.service.ts +248 -0
  23. package/src/codegen/domain/props/fill-props.service.ts +75 -0
  24. package/src/codegen/domain/props/radius-props.service.ts +105 -0
  25. package/src/codegen/domain/props/self-layout-props.service.ts +127 -0
  26. package/src/codegen/domain/props/stroke-props.service.ts +45 -0
  27. package/src/codegen/domain/props/type-style-props.service.ts +31 -0
  28. package/src/codegen/domain/rectangle.service.ts +31 -0
  29. package/src/codegen/domain/seed-component/deps.interface.ts +6 -0
  30. package/src/codegen/domain/seed-component/index.ts +75 -0
  31. package/src/{component/type.ts → codegen/domain/seed-component/properties.type.ts} +2 -2
  32. package/src/{component/properties.ts → codegen/domain/seed-component/size.ts} +4 -2
  33. package/src/codegen/domain/seed-component/transformers/action-button.ts +69 -0
  34. package/src/codegen/domain/seed-component/transformers/action-chip.ts +82 -0
  35. package/src/codegen/domain/seed-component/transformers/action-sheet.ts +78 -0
  36. package/src/{component/handlers → codegen/domain/seed-component/transformers}/app-bar.ts +114 -111
  37. package/src/codegen/domain/seed-component/transformers/avatar-stack.ts +30 -0
  38. package/src/codegen/domain/seed-component/transformers/avatar.ts +39 -0
  39. package/src/codegen/domain/seed-component/transformers/badge.ts +22 -0
  40. package/src/codegen/domain/seed-component/transformers/callout.ts +90 -0
  41. package/src/codegen/domain/seed-component/transformers/checkbox.ts +34 -0
  42. package/src/codegen/domain/seed-component/transformers/chip-tabs.ts +55 -0
  43. package/src/codegen/domain/seed-component/transformers/control-chip.ts +86 -0
  44. package/src/codegen/domain/seed-component/transformers/error-state.ts +39 -0
  45. package/src/codegen/domain/seed-component/transformers/extended-action-sheet.ts +99 -0
  46. package/src/codegen/domain/seed-component/transformers/extended-fab.ts +25 -0
  47. package/src/codegen/domain/seed-component/transformers/fab.ts +18 -0
  48. package/src/codegen/domain/seed-component/transformers/help-bubble.ts +68 -0
  49. package/src/codegen/domain/seed-component/transformers/identity-placeholder.ts +18 -0
  50. package/src/{component/handlers → codegen/domain/seed-component/transformers}/inline-banner.ts +11 -13
  51. package/src/codegen/domain/seed-component/transformers/manner-temp-badge.ts +19 -0
  52. package/src/codegen/domain/seed-component/transformers/multiline-text-field.ts +82 -0
  53. package/src/codegen/domain/seed-component/transformers/progress-circle.ts +51 -0
  54. package/src/codegen/domain/seed-component/transformers/reaction-button.ts +37 -0
  55. package/src/codegen/domain/seed-component/transformers/segmented-control.ts +59 -0
  56. package/src/codegen/domain/seed-component/transformers/select-box.ts +82 -0
  57. package/src/codegen/domain/seed-component/transformers/skeleton.ts +52 -0
  58. package/src/codegen/domain/seed-component/transformers/snackbar.ts +23 -0
  59. package/src/codegen/domain/seed-component/transformers/switch.ts +31 -0
  60. package/src/codegen/domain/seed-component/transformers/tabs.ts +129 -0
  61. package/src/{component/handlers → codegen/domain/seed-component/transformers}/text-button.ts +16 -18
  62. package/src/codegen/domain/seed-component/transformers/text-field.ts +109 -0
  63. package/src/codegen/domain/seed-component/transformers/toggle-button.ts +47 -0
  64. package/src/codegen/domain/style.interface.ts +5 -0
  65. package/src/codegen/domain/style.repository.ts +23 -0
  66. package/src/codegen/domain/style.service.ts +38 -0
  67. package/src/codegen/domain/text.service.ts +62 -0
  68. package/src/codegen/domain/variable.interface.ts +18 -0
  69. package/src/codegen/domain/variable.repository.ts +44 -0
  70. package/src/codegen/domain/variable.service.ts +95 -0
  71. package/src/codegen/index.ts +13 -0
  72. package/src/index.ts +2 -2
  73. package/src/normalizer/from-plugin.ts +29 -28
  74. package/src/normalizer/from-rest.ts +5 -1
  75. package/src/normalizer/types.ts +80 -32
  76. package/src/utils/common.ts +19 -0
  77. package/src/utils/css.ts +13 -0
  78. package/src/utils/figma-variable.ts +13 -0
  79. package/src/component/handlers/action-button.ts +0 -66
  80. package/src/component/handlers/action-chip.ts +0 -71
  81. package/src/component/handlers/action-sheet.ts +0 -74
  82. package/src/component/handlers/avatar-stack.ts +0 -35
  83. package/src/component/handlers/avatar.ts +0 -37
  84. package/src/component/handlers/badge.ts +0 -20
  85. package/src/component/handlers/callout.ts +0 -87
  86. package/src/component/handlers/checkbox.ts +0 -32
  87. package/src/component/handlers/chip-tabs.ts +0 -51
  88. package/src/component/handlers/control-chip.ts +0 -75
  89. package/src/component/handlers/error-state.ts +0 -37
  90. package/src/component/handlers/extended-action-sheet.ts +0 -86
  91. package/src/component/handlers/extended-fab.ts +0 -24
  92. package/src/component/handlers/fab.ts +0 -17
  93. package/src/component/handlers/help-bubble.ts +0 -66
  94. package/src/component/handlers/identity-placeholder.ts +0 -16
  95. package/src/component/handlers/manner-temp-badge.ts +0 -17
  96. package/src/component/handlers/multiline-text-field.ts +0 -80
  97. package/src/component/handlers/progress-circle.ts +0 -49
  98. package/src/component/handlers/reaction-button.ts +0 -36
  99. package/src/component/handlers/segmented-control.ts +0 -51
  100. package/src/component/handlers/select-box.ts +0 -76
  101. package/src/component/handlers/skeleton.ts +0 -51
  102. package/src/component/handlers/snackbar.ts +0 -21
  103. package/src/component/handlers/switch.ts +0 -29
  104. package/src/component/handlers/tabs.ts +0 -107
  105. package/src/component/handlers/text-field.ts +0 -108
  106. package/src/component/handlers/toggle-button.ts +0 -44
  107. package/src/component/index.ts +0 -76
  108. package/src/generate-code.ts +0 -251
  109. package/src/icon.ts +0 -46
  110. package/src/layout.ts +0 -31
  111. package/src/props/color.ts +0 -78
  112. package/src/props/layout.ts +0 -292
  113. package/src/props/sizing.ts +0 -58
  114. package/src/props/text.ts +0 -21
  115. package/src/props/variable.ts +0 -66
  116. /package/src/{data → codegen/data}/__generated__/component-sets/action-button.d.ts +0 -0
  117. /package/src/{data → codegen/data}/__generated__/component-sets/action-button.mjs +0 -0
  118. /package/src/{data → codegen/data}/__generated__/component-sets/action-chip.d.ts +0 -0
  119. /package/src/{data → codegen/data}/__generated__/component-sets/action-chip.mjs +0 -0
  120. /package/src/{data → codegen/data}/__generated__/component-sets/action-sheet.d.ts +0 -0
  121. /package/src/{data → codegen/data}/__generated__/component-sets/action-sheet.mjs +0 -0
  122. /package/src/{data → codegen/data}/__generated__/component-sets/avatar-stack.d.ts +0 -0
  123. /package/src/{data → codegen/data}/__generated__/component-sets/avatar-stack.mjs +0 -0
  124. /package/src/{data → codegen/data}/__generated__/component-sets/avatar.d.ts +0 -0
  125. /package/src/{data → codegen/data}/__generated__/component-sets/avatar.mjs +0 -0
  126. /package/src/{data → codegen/data}/__generated__/component-sets/badge.d.ts +0 -0
  127. /package/src/{data → codegen/data}/__generated__/component-sets/badge.mjs +0 -0
  128. /package/src/{data → codegen/data}/__generated__/component-sets/bottom-navigation-global.d.ts +0 -0
  129. /package/src/{data → codegen/data}/__generated__/component-sets/bottom-navigation-global.mjs +0 -0
  130. /package/src/{data → codegen/data}/__generated__/component-sets/bottom-navigation-kr.d.ts +0 -0
  131. /package/src/{data → codegen/data}/__generated__/component-sets/bottom-navigation-kr.mjs +0 -0
  132. /package/src/{data → codegen/data}/__generated__/component-sets/bottom-sheet.d.ts +0 -0
  133. /package/src/{data → codegen/data}/__generated__/component-sets/bottom-sheet.mjs +0 -0
  134. /package/src/{data → codegen/data}/__generated__/component-sets/callout.d.ts +0 -0
  135. /package/src/{data → codegen/data}/__generated__/component-sets/callout.mjs +0 -0
  136. /package/src/{data → codegen/data}/__generated__/component-sets/checkbox.d.ts +0 -0
  137. /package/src/{data → codegen/data}/__generated__/component-sets/checkbox.mjs +0 -0
  138. /package/src/{data → codegen/data}/__generated__/component-sets/chip-tablist.d.ts +0 -0
  139. /package/src/{data → codegen/data}/__generated__/component-sets/chip-tablist.mjs +0 -0
  140. /package/src/{data → codegen/data}/__generated__/component-sets/control-chip.d.ts +0 -0
  141. /package/src/{data → codegen/data}/__generated__/component-sets/control-chip.mjs +0 -0
  142. /package/src/{data → codegen/data}/__generated__/component-sets/divider.d.ts +0 -0
  143. /package/src/{data → codegen/data}/__generated__/component-sets/divider.mjs +0 -0
  144. /package/src/{data → codegen/data}/__generated__/component-sets/error-state.d.ts +0 -0
  145. /package/src/{data → codegen/data}/__generated__/component-sets/error-state.mjs +0 -0
  146. /package/src/{data → codegen/data}/__generated__/component-sets/extended-action-sheet.d.ts +0 -0
  147. /package/src/{data → codegen/data}/__generated__/component-sets/extended-action-sheet.mjs +0 -0
  148. /package/src/{data → codegen/data}/__generated__/component-sets/extended-floating-action-button.d.ts +0 -0
  149. /package/src/{data → codegen/data}/__generated__/component-sets/extended-floating-action-button.mjs +0 -0
  150. /package/src/{data → codegen/data}/__generated__/component-sets/floating-action-button.d.ts +0 -0
  151. /package/src/{data → codegen/data}/__generated__/component-sets/floating-action-button.mjs +0 -0
  152. /package/src/{data → codegen/data}/__generated__/component-sets/help-bubble.d.ts +0 -0
  153. /package/src/{data → codegen/data}/__generated__/component-sets/help-bubble.mjs +0 -0
  154. /package/src/{data → codegen/data}/__generated__/component-sets/identity-placeholder.d.ts +0 -0
  155. /package/src/{data → codegen/data}/__generated__/component-sets/identity-placeholder.mjs +0 -0
  156. /package/src/{data → codegen/data}/__generated__/component-sets/index.d.ts +0 -0
  157. /package/src/{data → codegen/data}/__generated__/component-sets/index.mjs +0 -0
  158. /package/src/{data → codegen/data}/__generated__/component-sets/inline-banner.d.ts +0 -0
  159. /package/src/{data → codegen/data}/__generated__/component-sets/inline-banner.mjs +0 -0
  160. /package/src/{data → codegen/data}/__generated__/component-sets/main-tab-navigation-global.d.ts +0 -0
  161. /package/src/{data → codegen/data}/__generated__/component-sets/main-tab-navigation-global.mjs +0 -0
  162. /package/src/{data → codegen/data}/__generated__/component-sets/main-tab-navigation-kr.d.ts +0 -0
  163. /package/src/{data → codegen/data}/__generated__/component-sets/main-tab-navigation-kr.mjs +0 -0
  164. /package/src/{data → codegen/data}/__generated__/component-sets/manner-temp-badge.d.ts +0 -0
  165. /package/src/{data → codegen/data}/__generated__/component-sets/manner-temp-badge.mjs +0 -0
  166. /package/src/{data → codegen/data}/__generated__/component-sets/manner-temp-bar.d.ts +0 -0
  167. /package/src/{data → codegen/data}/__generated__/component-sets/manner-temp-bar.mjs +0 -0
  168. /package/src/{data → codegen/data}/__generated__/component-sets/manner-temp.d.ts +0 -0
  169. /package/src/{data → codegen/data}/__generated__/component-sets/manner-temp.mjs +0 -0
  170. /package/src/{data → codegen/data}/__generated__/component-sets/multiline-text-field.d.ts +0 -0
  171. /package/src/{data → codegen/data}/__generated__/component-sets/multiline-text-field.mjs +0 -0
  172. /package/src/{data → codegen/data}/__generated__/component-sets/progress-circle.d.ts +0 -0
  173. /package/src/{data → codegen/data}/__generated__/component-sets/progress-circle.mjs +0 -0
  174. /package/src/{data → codegen/data}/__generated__/component-sets/radio.d.ts +0 -0
  175. /package/src/{data → codegen/data}/__generated__/component-sets/radio.mjs +0 -0
  176. /package/src/{data → codegen/data}/__generated__/component-sets/range-slider.d.ts +0 -0
  177. /package/src/{data → codegen/data}/__generated__/component-sets/range-slider.mjs +0 -0
  178. /package/src/{data → codegen/data}/__generated__/component-sets/reaction-button.d.ts +0 -0
  179. /package/src/{data → codegen/data}/__generated__/component-sets/reaction-button.mjs +0 -0
  180. /package/src/{data → codegen/data}/__generated__/component-sets/segmented-control.d.ts +0 -0
  181. /package/src/{data → codegen/data}/__generated__/component-sets/segmented-control.mjs +0 -0
  182. /package/src/{data → codegen/data}/__generated__/component-sets/select-box.d.ts +0 -0
  183. /package/src/{data → codegen/data}/__generated__/component-sets/select-box.mjs +0 -0
  184. /package/src/{data → codegen/data}/__generated__/component-sets/skeleton.d.ts +0 -0
  185. /package/src/{data → codegen/data}/__generated__/component-sets/skeleton.mjs +0 -0
  186. /package/src/{data → codegen/data}/__generated__/component-sets/slider.d.ts +0 -0
  187. /package/src/{data → codegen/data}/__generated__/component-sets/slider.mjs +0 -0
  188. /package/src/{data → codegen/data}/__generated__/component-sets/snackbar.d.ts +0 -0
  189. /package/src/{data → codegen/data}/__generated__/component-sets/snackbar.mjs +0 -0
  190. /package/src/{data → codegen/data}/__generated__/component-sets/standard-navigation.d.ts +0 -0
  191. /package/src/{data → codegen/data}/__generated__/component-sets/standard-navigation.mjs +0 -0
  192. /package/src/{data → codegen/data}/__generated__/component-sets/switch.d.ts +0 -0
  193. /package/src/{data → codegen/data}/__generated__/component-sets/switch.mjs +0 -0
  194. /package/src/{data → codegen/data}/__generated__/component-sets/tablist.d.ts +0 -0
  195. /package/src/{data → codegen/data}/__generated__/component-sets/tablist.mjs +0 -0
  196. /package/src/{data → codegen/data}/__generated__/component-sets/template-bottom-fixed-bar.d.ts +0 -0
  197. /package/src/{data → codegen/data}/__generated__/component-sets/template-bottom-fixed-bar.mjs +0 -0
  198. /package/src/{data → codegen/data}/__generated__/component-sets/template-button-group.d.ts +0 -0
  199. /package/src/{data → codegen/data}/__generated__/component-sets/template-button-group.mjs +0 -0
  200. /package/src/{data → codegen/data}/__generated__/component-sets/template-chip-group.d.ts +0 -0
  201. /package/src/{data → codegen/data}/__generated__/component-sets/template-chip-group.mjs +0 -0
  202. /package/src/{data → codegen/data}/__generated__/component-sets/template-select-box-group.d.ts +0 -0
  203. /package/src/{data → codegen/data}/__generated__/component-sets/template-select-box-group.mjs +0 -0
  204. /package/src/{data → codegen/data}/__generated__/component-sets/template-top-navigation.d.ts +0 -0
  205. /package/src/{data → codegen/data}/__generated__/component-sets/template-top-navigation.mjs +0 -0
  206. /package/src/{data → codegen/data}/__generated__/component-sets/text-button.d.ts +0 -0
  207. /package/src/{data → codegen/data}/__generated__/component-sets/text-button.mjs +0 -0
  208. /package/src/{data → codegen/data}/__generated__/component-sets/text-field.d.ts +0 -0
  209. /package/src/{data → codegen/data}/__generated__/component-sets/text-field.mjs +0 -0
  210. /package/src/{data → codegen/data}/__generated__/component-sets/toggle-button.d.ts +0 -0
  211. /package/src/{data → codegen/data}/__generated__/component-sets/toggle-button.mjs +0 -0
@@ -0,0 +1,23 @@
1
+ import { defineComponentTransformer } from "@/codegen/core";
2
+ import { camelCase } from "change-case";
3
+ import * as metadata from "../../../data/__generated__/component-sets";
4
+ import { createElement } from "../../../core/jsx";
5
+ import type { SnackbarProperties } from "../properties.type";
6
+ import type { SeedComponentTransformerDeps } from "../deps.interface";
7
+
8
+ export const createSnackbarTransformer = (_ctx: SeedComponentTransformerDeps) =>
9
+ defineComponentTransformer<SnackbarProperties>(
10
+ metadata.snackbar.key,
11
+ ({ componentProperties: props }) => {
12
+ const commonProps = {
13
+ message: props["Message#1528:4"].value,
14
+ variant: camelCase(props.Variant.value),
15
+ ...(props["Show Action Button#1528:0"].value && {
16
+ actionLabel: props["Action Button Label#1528:8"].value,
17
+ }),
18
+ };
19
+
20
+ // TODO: adapter.create({ render })
21
+ return createElement("Snackbar", commonProps);
22
+ },
23
+ );
@@ -0,0 +1,31 @@
1
+ import { defineComponentTransformer } from "@/codegen/core";
2
+ import * as metadata from "../../../data/__generated__/component-sets";
3
+ import { createElement } from "../../../core/jsx";
4
+ import { handleSizeProp } from "../size";
5
+ import type { SwitchProperties } from "../properties.type";
6
+ import type { SeedComponentTransformerDeps } from "../deps.interface";
7
+
8
+ export const createSwitchTransformer = (_ctx: SeedComponentTransformerDeps) =>
9
+ defineComponentTransformer<SwitchProperties>(
10
+ metadata.switch.key,
11
+ ({ componentProperties: props }) => {
12
+ const states = props.State.value.split("-");
13
+
14
+ const size = handleSizeProp(props.Size.value);
15
+
16
+ const commonProps = {
17
+ size,
18
+ ...(size === "small" && {
19
+ label: props["Label#15191:2"].value,
20
+ }),
21
+ ...(states.includes("Selected") && {
22
+ defaultChecked: true,
23
+ }),
24
+ ...(states.includes("Disabled") && {
25
+ disabled: true,
26
+ }),
27
+ };
28
+
29
+ return createElement("Switch", commonProps);
30
+ },
31
+ );
@@ -0,0 +1,129 @@
1
+ import { defineComponentTransformer } from "@/codegen/core";
2
+ import { camelCase } from "change-case";
3
+ import * as metadata from "../../../data/__generated__/component-sets";
4
+ import { createElement } from "../../../core/jsx";
5
+ import type { NormalizedInstanceNode } from "../../../../normalizer";
6
+ import { handleSizeProp } from "../size";
7
+ import type {
8
+ TabsFillItemProperties,
9
+ TabsHugItemProperties,
10
+ TabsProperties,
11
+ } from "../properties.type";
12
+ import type { SeedComponentTransformerDeps } from "../deps.interface";
13
+
14
+ const TABS_HUG_ITEM_KEY = "c242492543b327ceb84fa9933841512fc62a898c";
15
+ const createTabsHugItemTransformer = (_ctx: SeedComponentTransformerDeps) =>
16
+ defineComponentTransformer<TabsHugItemProperties>(
17
+ TABS_HUG_ITEM_KEY,
18
+ ({ componentProperties: props }) => {
19
+ const states = props.State.value.split("-");
20
+
21
+ const commonProps = {
22
+ value: props["Label#4478:2"].value,
23
+ ...(props.Notification.value === "True" && {
24
+ alert: true,
25
+ }),
26
+ ...(states.includes("Disabled") && {
27
+ disabled: true,
28
+ }),
29
+ };
30
+
31
+ return createElement("TabsTrigger", commonProps, props["Label#4478:2"].value);
32
+ },
33
+ );
34
+
35
+ const TABS_FILL_ITEM_KEY = "7275293344efb40ee9a3f5248ba2659b94a0b305";
36
+ const createTabsFillItemTransformer = (_ctx: SeedComponentTransformerDeps) =>
37
+ defineComponentTransformer<TabsFillItemProperties>(
38
+ TABS_FILL_ITEM_KEY,
39
+ ({ componentProperties: props }) => {
40
+ const states = props.State.value.split("-");
41
+
42
+ const commonProps = {
43
+ value: props["Label#4478:2"].value,
44
+ ...(props.Notification.value === "True" && {
45
+ alert: true,
46
+ }),
47
+ ...(states.includes("Disabled") && {
48
+ disabled: true,
49
+ }),
50
+ };
51
+
52
+ return createElement("TabsTrigger", commonProps, props["Label#4478:2"].value);
53
+ },
54
+ );
55
+
56
+ export const createTabsTransformer = (ctx: SeedComponentTransformerDeps) => {
57
+ const tabsHugItemTransformer = createTabsHugItemTransformer(ctx);
58
+ const tabsFillItemTransformer = createTabsFillItemTransformer(ctx);
59
+
60
+ return defineComponentTransformer<TabsProperties>(metadata.tablist.key, (node) => {
61
+ const { componentProperties: props, children } = node;
62
+
63
+ const mappedItems = children.map(
64
+ (
65
+ child,
66
+ ): {
67
+ triggerLayout: "hug" | "fill";
68
+ node: NormalizedInstanceNode & {
69
+ componentProperties: TabsHugItemProperties | TabsFillItemProperties;
70
+ };
71
+ } | null => {
72
+ if (child.type !== "INSTANCE") return null;
73
+
74
+ const componentKey = child.componentSetKey ? child.componentSetKey : child.componentKey;
75
+
76
+ if (componentKey === tabsHugItemTransformer.key)
77
+ return {
78
+ triggerLayout: "hug" as const,
79
+ node: child as NormalizedInstanceNode & { componentProperties: TabsHugItemProperties },
80
+ };
81
+
82
+ if (componentKey === tabsFillItemTransformer.key)
83
+ return {
84
+ triggerLayout: "fill" as const,
85
+ node: child as NormalizedInstanceNode & { componentProperties: TabsFillItemProperties },
86
+ };
87
+
88
+ return null;
89
+ },
90
+ );
91
+
92
+ const tabsItems = mappedItems.filter(
93
+ (item): item is NonNullable<(typeof mappedItems)[number]> => item !== null,
94
+ );
95
+
96
+ const selectedTabsItem = tabsItems.find(({ node: { componentProperties } }) =>
97
+ componentProperties.State.value.split("-").includes("Selected"),
98
+ )?.node;
99
+
100
+ const tabTriggerList = createElement(
101
+ "TabsList",
102
+ undefined,
103
+ tabsItems.map(({ triggerLayout, node }) => {
104
+ switch (triggerLayout) {
105
+ case "hug":
106
+ return tabsHugItemTransformer.transform(node);
107
+ case "fill":
108
+ return tabsFillItemTransformer.transform(node);
109
+ }
110
+ }),
111
+ );
112
+
113
+ const tabContents = tabsItems.map(({ node }) => {
114
+ const value = node.componentProperties["Label#4478:2"].value;
115
+
116
+ return createElement("TabsContent", { value }, "{/* TODO: 컨텐츠 추가 */}");
117
+ });
118
+
119
+ const commonProps = {
120
+ triggerLayout: camelCase(props.Layout.value),
121
+ size: handleSizeProp(props.Size.value),
122
+ ...(selectedTabsItem && {
123
+ defaultValue: selectedTabsItem.componentProperties["Label#4478:2"].value,
124
+ }),
125
+ };
126
+
127
+ return createElement("TabsRoot", commonProps, [tabTriggerList, ...tabContents]);
128
+ });
129
+ };
@@ -1,25 +1,24 @@
1
+ import { defineComponentTransformer } from "@/codegen/core";
1
2
  import { camelCase } from "change-case";
2
3
  import { match } from "ts-pattern";
3
- import * as metadata from "../../data/__generated__/component-sets";
4
- import { createIconTagNameFromKey } from "../../icon";
5
- import { createElement } from "../../jsx";
6
- import { findOne } from "../../utils/figma-node";
7
- import type { NormalizedInstanceNode } from "../../normalizer";
8
- import { handleSize } from "../properties";
9
- import type { TextButtonProperties } from "../type";
10
- import type { ComponentHandler } from "../type-helper";
4
+ import * as metadata from "../../../data/__generated__/component-sets";
5
+ import { createElement } from "../../../core/jsx";
6
+ import { findOne } from "../../../../utils/figma-node";
7
+ import type { NormalizedInstanceNode } from "../../../../normalizer";
8
+ import { handleSizeProp } from "../size";
9
+ import type { TextButtonProperties } from "../properties.type";
10
+ import type { SeedComponentTransformerDeps } from "../deps.interface";
11
11
 
12
- export const textButtonHandler: ComponentHandler<TextButtonProperties> = {
13
- key: metadata.textButton.key,
14
- codegen: async (node) => {
12
+ export const createTextButtonTransformer = (ctx: SeedComponentTransformerDeps) =>
13
+ defineComponentTransformer<TextButtonProperties>(metadata.textButton.key, (node) => {
15
14
  const { componentProperties: props } = node;
16
15
 
17
16
  const states = props.State.value.split("-");
18
17
 
19
- const { prefixIcon, suffixIcon, children } = await match(props.Layout.value)
20
- .with("Icon First", async () => ({
18
+ const { prefixIcon, suffixIcon, children } = match(props.Layout.value)
19
+ .with("Icon First", () => ({
21
20
  prefixIcon: createElement(
22
- createIconTagNameFromKey(props["Prefix Icon#7561:0"].componentKey),
21
+ ctx.iconService.createIconTagName(props["Prefix Icon#7561:0"].componentKey),
23
22
  ),
24
23
  suffixIcon: undefined,
25
24
  children: props["Label#6148:0"].value,
@@ -35,7 +34,7 @@ export const textButtonHandler: ComponentHandler<TextButtonProperties> = {
35
34
  return {
36
35
  prefixIcon: undefined,
37
36
  suffixIcon: suffixIconComponentKey
38
- ? createElement(createIconTagNameFromKey(suffixIconComponentKey))
37
+ ? createElement(ctx.iconService.createIconTagName(suffixIconComponentKey))
39
38
  : undefined,
40
39
  children: props["Label#6148:0"].value,
41
40
  };
@@ -44,7 +43,7 @@ export const textButtonHandler: ComponentHandler<TextButtonProperties> = {
44
43
 
45
44
  const commonProps = {
46
45
  tone: camelCase(props.Tone.value),
47
- size: handleSize(props.Size.value),
46
+ size: handleSizeProp(props.Size.value),
48
47
  prefixIcon,
49
48
  suffixIcon,
50
49
  ...(states.includes("Disabled") && {
@@ -53,5 +52,4 @@ export const textButtonHandler: ComponentHandler<TextButtonProperties> = {
53
52
  };
54
53
 
55
54
  return createElement("TextButton", commonProps, children);
56
- },
57
- };
55
+ });
@@ -0,0 +1,109 @@
1
+ import { defineComponentTransformer } from "@/codegen/core";
2
+ import * as metadata from "../../../data/__generated__/component-sets";
3
+ import { createElement } from "../../../core/jsx";
4
+ import { handleSizeProp } from "../size";
5
+ import type { TextFieldProperties } from "../properties.type";
6
+ import type { SeedComponentTransformerDeps } from "../deps.interface";
7
+
8
+ export const createTextFieldTransformer = (ctx: SeedComponentTransformerDeps) =>
9
+ defineComponentTransformer<TextFieldProperties>(
10
+ metadata.textField.key,
11
+ ({ componentProperties: props }) => {
12
+ const {
13
+ Size: { value: size },
14
+ State: { value: state },
15
+ Filled: { value: filled },
16
+ "Show Header#870:0": { value: showHeader },
17
+ "Label#14964:0": { value: label },
18
+ "Show Indicator#1259:0": { value: showIndicator },
19
+ "Indicator#15327:249": { value: indicator },
20
+ "Show Prefix#958:125": { value: showPrefix },
21
+ "Show Prefix Icon#1267:50": { value: showPrefixIcon },
22
+ "Prefix Icon#1267:25": { value: prefixIcon },
23
+ "Show Prefix Text#1267:0": { value: showPrefixText },
24
+ "Prefix Text#15327:101": { value: prefix },
25
+ "Placeholder#958:0": { value: placeholder },
26
+ "Filled Text#1304:0": { value: defaultValue },
27
+ "Show Suffix#958:100": { value: showSuffix },
28
+ "Show Suffix Icon#1267:75": { value: showSuffixIcon },
29
+ "Suffix Icon #1267:100": { value: suffixIcon },
30
+ "Show Suffix Text#1267:125": { value: showSuffixText },
31
+ "Suffix Text#15327:138": { value: suffix },
32
+ "Show Footer#958:25": { value: showFooter },
33
+ "Show Description#958:50": { value: showDescription },
34
+ "Description#12626:5": { value: description },
35
+ "Show Character Count#958:75": { value: showCharacterCount },
36
+ "Character Count#15327:64": { value: _characterCount },
37
+ "Max Character Count#15327:27": { value: maxCharacterCount },
38
+ } = props;
39
+
40
+ const states = state.split("-");
41
+
42
+ const commonProps = {
43
+ size: handleSizeProp(size),
44
+ // header
45
+ ...(showHeader && {
46
+ label,
47
+ }),
48
+ ...(showHeader &&
49
+ showIndicator && {
50
+ indicator,
51
+ }),
52
+ // input affixes
53
+ ...(showPrefix &&
54
+ showPrefixIcon && {
55
+ prefixIcon: createElement(ctx.iconService.createIconTagName(prefixIcon)),
56
+ }),
57
+ ...(showPrefix &&
58
+ showPrefixText && {
59
+ prefix,
60
+ }),
61
+ ...(showSuffix &&
62
+ showSuffixIcon && {
63
+ suffixIcon: createElement(ctx.iconService.createIconTagName(suffixIcon)),
64
+ }),
65
+ ...(showSuffix &&
66
+ showSuffixText && {
67
+ suffix,
68
+ }),
69
+ // input
70
+ ...(filled === "True" && {
71
+ defaultValue,
72
+ }),
73
+ ...(states.includes("Invalid") && {
74
+ invalid: true,
75
+ }),
76
+ ...(states.includes("Disabled") && {
77
+ disabled: true,
78
+ }),
79
+ ...(states.includes("Read Only") && {
80
+ readOnly: true,
81
+ }),
82
+ // footer
83
+ ...(showFooter &&
84
+ showDescription &&
85
+ states.includes("Invalid") && {
86
+ // invalid인 경우 description을 error로 사용
87
+ errorMessage: description,
88
+ }),
89
+ ...(showFooter &&
90
+ showDescription &&
91
+ !states.includes("Invalid") && {
92
+ // invalid가 아닌 경우 description을 description으로 사용
93
+ description,
94
+ }),
95
+ ...(showFooter &&
96
+ showCharacterCount && {
97
+ maxGraphemeCount: Number(maxCharacterCount),
98
+ }),
99
+ };
100
+
101
+ const inputProps = {
102
+ placeholder,
103
+ };
104
+
105
+ const TextFieldChildren = createElement("TextFieldInput", inputProps);
106
+
107
+ return createElement("TextField", commonProps, TextFieldChildren);
108
+ },
109
+ );
@@ -0,0 +1,47 @@
1
+ import { defineComponentTransformer } from "@/codegen/core";
2
+ import { camelCase } from "change-case";
3
+ import * as metadata from "../../../data/__generated__/component-sets";
4
+ import { createElement } from "../../../core/jsx";
5
+ import { handleSizeProp } from "../size";
6
+ import type { ToggleButtonProperties } from "../properties.type";
7
+ import type { SeedComponentTransformerDeps } from "../deps.interface";
8
+
9
+ export const createToggleButtonTransformer = (ctx: SeedComponentTransformerDeps) =>
10
+ defineComponentTransformer<ToggleButtonProperties>(
11
+ metadata.toggleButton.key,
12
+ ({ componentProperties: props }) => {
13
+ const states = props.State.value.split("-");
14
+
15
+ const commonProps = {
16
+ variant: camelCase(props.Variant.value),
17
+ size: handleSizeProp(props.Size.value),
18
+ ...(states.includes("Selected") && {
19
+ defaultPressed: true,
20
+ }),
21
+ ...(states.includes("Disabled") && {
22
+ disabled: true,
23
+ }),
24
+ ...(states.includes("Loading") && {
25
+ loading: true,
26
+ }),
27
+ };
28
+
29
+ return createElement("ToggleButton", commonProps, [
30
+ props["Show Prefix Icon#6122:392"].value
31
+ ? createElement("PrefixIcon", {
32
+ svg: createElement(
33
+ ctx.iconService.createIconTagName(props["Prefix Icon#6122:98"].componentKey),
34
+ ),
35
+ })
36
+ : undefined,
37
+ props["Label#6122:49"].value,
38
+ props["Show Suffix Icon#6122:147"].value
39
+ ? createElement("SuffixIcon", {
40
+ svg: createElement(
41
+ ctx.iconService.createIconTagName(props["Suffix Icon#6122:343"].componentKey),
42
+ ),
43
+ })
44
+ : undefined,
45
+ ]);
46
+ },
47
+ );
@@ -0,0 +1,5 @@
1
+ import type { Style as FigmaStyle, StyleType as FigmaStyleType } from "@figma/rest-api-spec";
2
+
3
+ export type Style = FigmaStyle;
4
+
5
+ export type StyleType = FigmaStyleType;
@@ -0,0 +1,23 @@
1
+ import type { Style } from "./style.interface";
2
+
3
+ export interface StyleRepository {
4
+ getAll(): Style[];
5
+ getTextStyles(): Style[];
6
+ getColorStyles(): Style[];
7
+ getOne(key: string): Style | undefined;
8
+ }
9
+
10
+ export function createStaticStyleRepository(styles: Style[]): StyleRepository {
11
+ const stylesMap = new Map<string, Style>();
12
+
13
+ for (const style of styles) {
14
+ stylesMap.set(style.key, style);
15
+ }
16
+
17
+ return {
18
+ getAll: () => styles,
19
+ getTextStyles: () => styles.filter((style) => style.styleType === "TEXT"),
20
+ getColorStyles: () => styles.filter((style) => style.styleType === "FILL"),
21
+ getOne: (key) => stylesMap.get(key),
22
+ };
23
+ }
@@ -0,0 +1,38 @@
1
+ import type { StyleRepository } from "./style.repository";
2
+
3
+ export interface StyleService {
4
+ getStyleName: (id: string) => string;
5
+ }
6
+
7
+ // TODO: inferStyleName 추가해야 함, rest api에서 style value가 제공되지 않고 있어 보류
8
+ export function createStyleService({
9
+ styleRepository,
10
+ styleNameTransformer,
11
+ }: {
12
+ styleRepository: StyleRepository;
13
+ styleNameTransformer: ({ slug }: { slug: string[] }) => string;
14
+ }): StyleService {
15
+ function getFigmaStyleName(id: string) {
16
+ const style = styleRepository.getOne(id);
17
+
18
+ if (!style) {
19
+ throw new Error(`Style not found: ${id}`);
20
+ }
21
+
22
+ return style.name;
23
+ }
24
+
25
+ function getFigmaStyleSlug(id: string): string[] {
26
+ const name = getFigmaStyleName(id);
27
+ return name.split("/");
28
+ }
29
+
30
+ function getStyleName(id: string) {
31
+ const slug = getFigmaStyleSlug(id);
32
+ return styleNameTransformer({ slug });
33
+ }
34
+
35
+ return {
36
+ getStyleName,
37
+ };
38
+ }
@@ -0,0 +1,62 @@
1
+ import type { NormalizedTextNode } from "@/normalizer";
2
+ import { compactObject } from "@/utils/common";
3
+ import { camelCase } from "change-case";
4
+ import { createElement, defineElementTransformer, type ElementTransformer } from "../core";
5
+ import type { FillPropsService, ShapeFillProps } from "./props/fill-props.service";
6
+ import type { TypeStylePropsService } from "./props/type-style-props.service";
7
+ import type { StyleService } from "./style.service";
8
+
9
+ export interface TextService {
10
+ transform: ElementTransformer<NormalizedTextNode>;
11
+ }
12
+
13
+ export interface SeedTextServiceDeps {
14
+ styleService: StyleService;
15
+ fillPropsService: FillPropsService<ShapeFillProps>;
16
+ typeStylePropsService: TypeStylePropsService;
17
+ }
18
+
19
+ export function createSeedTextService({
20
+ styleService,
21
+ fillPropsService,
22
+ typeStylePropsService,
23
+ }: SeedTextServiceDeps): TextService {
24
+ const transform = defineElementTransformer((node: NormalizedTextNode, traverse) => {
25
+ const maxLines =
26
+ node.style.textTruncation === "ENDING" ? (node.style.maxLines ?? undefined) : undefined;
27
+
28
+ const hasMultipleFills = node.fills.length > 1;
29
+
30
+ const fillProps = fillPropsService.transform(node, traverse);
31
+
32
+ const styleName = node.textStyleKey ? styleService.getStyleName(node.textStyleKey) : undefined;
33
+ const { fontSize, fontWeight, lineHeight } = typeStylePropsService.transform(node, traverse);
34
+
35
+ const props = styleName
36
+ ? compactObject({
37
+ textStyle: camelCase(styleName, { mergeAmbiguousCharacters: true }),
38
+ maxLines,
39
+ ...fillProps,
40
+ })
41
+ : compactObject({
42
+ fontSize,
43
+ fontWeight,
44
+ lineHeight,
45
+ maxLines,
46
+ ...fillProps,
47
+ });
48
+
49
+ return createElement(
50
+ "Text",
51
+ props,
52
+ node.characters.replace(/\n/g, "<br />"),
53
+ hasMultipleFills
54
+ ? "Multiple fills in Text node encountered, only the first fill is used."
55
+ : "",
56
+ );
57
+ });
58
+
59
+ return {
60
+ transform,
61
+ };
62
+ }
@@ -0,0 +1,18 @@
1
+ import type {
2
+ LocalVariable,
3
+ LocalVariableCollection,
4
+ VariableAlias,
5
+ VariableResolvedDataType,
6
+ } from "@figma/rest-api-spec";
7
+
8
+ export type Variable = LocalVariable;
9
+
10
+ export type VariableCollection = LocalVariableCollection;
11
+
12
+ export type VariableType = VariableResolvedDataType;
13
+
14
+ export type VariableValue = Variable["valuesByMode"][string];
15
+
16
+ export type VariableValueResolved = Exclude<VariableValue, VariableAlias>;
17
+
18
+ export type { VariableScope } from "@figma/rest-api-spec";
@@ -0,0 +1,44 @@
1
+ import type { Variable, VariableCollection } from "./variable.interface";
2
+
3
+ export interface VariableRepository {
4
+ getVariableList(): Variable[];
5
+ getVariableCollectionList(): VariableCollection[];
6
+ findVariableByKey(key: string): Variable | undefined;
7
+ findVariableById(id: string): Variable | undefined;
8
+ findVariableCollectionByKey(key: string): VariableCollection | undefined;
9
+ findVariableCollectionById(id: string): VariableCollection | undefined;
10
+ }
11
+
12
+ export function createStaticVariableRepository({
13
+ variables,
14
+ variableCollections,
15
+ }: {
16
+ variables: Record<string, Variable>;
17
+ variableCollections: Record<string, VariableCollection>;
18
+ }): VariableRepository {
19
+ const variablesKeyMap = new Map<string, Variable>();
20
+ const variablesIdMap = new Map<string, Variable>();
21
+ const variableCollectionsKeyMap = new Map<string, VariableCollection>();
22
+ const variableCollectionsIdMap = new Map<string, VariableCollection>();
23
+ const variablesList = Object.values(variables);
24
+ const variableCollectionsList = Object.values(variableCollections);
25
+
26
+ for (const variable of variablesList) {
27
+ variablesKeyMap.set(variable.key, variable);
28
+ variablesIdMap.set(variable.id, variable);
29
+ }
30
+
31
+ for (const variableCollection of variableCollectionsList) {
32
+ variableCollectionsKeyMap.set(variableCollection.key, variableCollection);
33
+ variableCollectionsIdMap.set(variableCollection.id, variableCollection);
34
+ }
35
+
36
+ return {
37
+ getVariableList: () => variablesList,
38
+ getVariableCollectionList: () => variableCollectionsList,
39
+ findVariableByKey: (key: string) => variablesKeyMap.get(key),
40
+ findVariableById: (id: string) => variablesIdMap.get(id),
41
+ findVariableCollectionByKey: (key: string) => variableCollectionsKeyMap.get(key),
42
+ findVariableCollectionById: (id: string) => variableCollectionsIdMap.get(id),
43
+ };
44
+ }