@seed-design/figma 1.2.0 → 1.2.1

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 (116) hide show
  1. package/lib/codegen/index.cjs +12280 -190
  2. package/lib/codegen/index.d.ts.map +1 -1
  3. package/lib/codegen/index.js +12280 -190
  4. package/lib/codegen/targets/react/index.cjs +17366 -3198
  5. package/lib/codegen/targets/react/index.d.ts.map +1 -1
  6. package/lib/codegen/targets/react/index.js +17366 -3198
  7. package/lib/index.cjs +12286 -196
  8. package/lib/index.d.ts.map +1 -1
  9. package/lib/index.js +12286 -196
  10. package/package.json +4 -4
  11. package/src/codegen/component-properties.archive.ts +1019 -0
  12. package/src/codegen/component-properties.ts +191 -893
  13. package/src/codegen/index.ts +1 -1
  14. package/src/codegen/targets/react/component/handlers/action-button.ts +69 -66
  15. package/src/codegen/targets/react/component/handlers/alert-dialog.ts +2 -4
  16. package/src/codegen/targets/react/component/handlers/app-bar.ts +90 -87
  17. package/src/codegen/targets/react/component/handlers/archive/action-button.ts +144 -0
  18. package/src/codegen/targets/react/component/handlers/archive/alert-dialog.ts +122 -0
  19. package/src/codegen/targets/react/component/handlers/archive/app-bar.ts +149 -0
  20. package/src/codegen/targets/react/component/handlers/archive/avatar-stack.ts +35 -0
  21. package/src/codegen/targets/react/component/handlers/archive/avatar.ts +55 -0
  22. package/src/codegen/targets/react/component/handlers/archive/badge.ts +18 -0
  23. package/src/codegen/targets/react/component/handlers/archive/bottom-sheet.ts +70 -0
  24. package/src/codegen/targets/react/component/handlers/archive/callout.ts +88 -0
  25. package/src/codegen/targets/react/component/handlers/archive/checkbox.ts +41 -0
  26. package/src/codegen/targets/react/component/handlers/archive/checkmark.ts +29 -0
  27. package/src/codegen/targets/react/component/handlers/archive/chip.ts +90 -0
  28. package/src/codegen/targets/react/component/handlers/archive/contextual-floating-button.ts +52 -0
  29. package/src/codegen/targets/react/component/handlers/archive/divider.ts +25 -0
  30. package/src/codegen/targets/react/component/handlers/archive/field-button.ts +197 -0
  31. package/src/codegen/targets/react/component/handlers/archive/field.ts +167 -0
  32. package/src/codegen/targets/react/component/handlers/archive/floating-action-button.ts +48 -0
  33. package/src/codegen/targets/react/component/handlers/archive/help-bubble.ts +73 -0
  34. package/src/codegen/targets/react/component/handlers/archive/identity-placeholder.ts +21 -0
  35. package/src/codegen/targets/react/component/handlers/archive/index.ts +41 -0
  36. package/src/codegen/targets/react/component/handlers/archive/legacy-select-box.ts +89 -0
  37. package/src/codegen/targets/react/component/handlers/archive/legacy-text-field.ts +198 -0
  38. package/src/codegen/targets/react/component/handlers/archive/list-header.ts +20 -0
  39. package/src/codegen/targets/react/component/handlers/archive/list-item.ts +162 -0
  40. package/src/codegen/targets/react/component/handlers/archive/manner-temp-badge.ts +21 -0
  41. package/src/codegen/targets/react/component/handlers/archive/manner-temp.ts +18 -0
  42. package/src/codegen/targets/react/component/handlers/archive/menu-sheet.ts +108 -0
  43. package/src/codegen/targets/react/component/handlers/archive/page-banner.ts +101 -0
  44. package/src/codegen/targets/react/component/handlers/archive/progress-circle.ts +55 -0
  45. package/src/codegen/targets/react/component/handlers/archive/radio-group.ts +31 -0
  46. package/src/codegen/targets/react/component/handlers/archive/radiomark.ts +27 -0
  47. package/src/codegen/targets/react/component/handlers/archive/reaction-button.ts +37 -0
  48. package/src/codegen/targets/react/component/handlers/archive/result-section.ts +67 -0
  49. package/src/codegen/targets/react/component/handlers/archive/segmented-control.ts +64 -0
  50. package/src/codegen/targets/react/component/handlers/archive/skeleton.ts +26 -0
  51. package/src/codegen/targets/react/component/handlers/archive/slider.ts +114 -0
  52. package/src/codegen/targets/react/component/handlers/archive/snackbar.ts +25 -0
  53. package/src/codegen/targets/react/component/handlers/archive/switch.ts +39 -0
  54. package/src/codegen/targets/react/component/handlers/archive/switchmark.ts +26 -0
  55. package/src/codegen/targets/react/component/handlers/archive/tabs.ts +297 -0
  56. package/src/codegen/targets/react/component/handlers/archive/tag-group.ts +86 -0
  57. package/src/codegen/targets/react/component/handlers/archive/text-field.ts +264 -0
  58. package/src/codegen/targets/react/component/handlers/archive/toggle-button.ts +43 -0
  59. package/src/codegen/targets/react/component/handlers/avatar-stack.ts +5 -2
  60. package/src/codegen/targets/react/component/handlers/avatar.ts +42 -39
  61. package/src/codegen/targets/react/component/handlers/badge.ts +1 -1
  62. package/src/codegen/targets/react/component/handlers/bottom-sheet.ts +56 -49
  63. package/src/codegen/targets/react/component/handlers/callout.ts +1 -1
  64. package/src/codegen/targets/react/component/handlers/checkbox.ts +1 -1
  65. package/src/codegen/targets/react/component/handlers/checkmark.ts +1 -1
  66. package/src/codegen/targets/react/component/handlers/chip.ts +8 -5
  67. package/src/codegen/targets/react/component/handlers/contextual-floating-button.ts +1 -1
  68. package/src/codegen/targets/react/component/handlers/divider.ts +1 -1
  69. package/src/codegen/targets/react/component/handlers/field-button.ts +18 -16
  70. package/src/codegen/targets/react/component/handlers/field.ts +71 -74
  71. package/src/codegen/targets/react/component/handlers/floating-action-button.ts +3 -6
  72. package/src/codegen/targets/react/component/handlers/help-bubble.ts +1 -1
  73. package/src/codegen/targets/react/component/handlers/identity-placeholder.ts +10 -2
  74. package/src/codegen/targets/react/component/handlers/index.ts +41 -0
  75. package/src/codegen/targets/react/component/handlers/legacy-select-box.ts +3 -5
  76. package/src/codegen/targets/react/component/handlers/legacy-text-field.ts +3 -5
  77. package/src/codegen/targets/react/component/handlers/list-header.ts +1 -1
  78. package/src/codegen/targets/react/component/handlers/list-item.ts +19 -18
  79. package/src/codegen/targets/react/component/handlers/manner-temp-badge.ts +1 -1
  80. package/src/codegen/targets/react/component/handlers/manner-temp.ts +1 -1
  81. package/src/codegen/targets/react/component/handlers/menu-sheet.ts +45 -42
  82. package/src/codegen/targets/react/component/handlers/page-banner.ts +77 -72
  83. package/src/codegen/targets/react/component/handlers/progress-circle.ts +1 -1
  84. package/src/codegen/targets/react/component/handlers/radio-group.ts +1 -1
  85. package/src/codegen/targets/react/component/handlers/radiomark.ts +1 -1
  86. package/src/codegen/targets/react/component/handlers/reaction-button.ts +1 -1
  87. package/src/codegen/targets/react/component/handlers/result-section.ts +1 -1
  88. package/src/codegen/targets/react/component/handlers/segmented-control.ts +2 -3
  89. package/src/codegen/targets/react/component/handlers/skeleton.ts +1 -1
  90. package/src/codegen/targets/react/component/handlers/slider.ts +11 -8
  91. package/src/codegen/targets/react/component/handlers/snackbar.ts +1 -1
  92. package/src/codegen/targets/react/component/handlers/switch.ts +1 -1
  93. package/src/codegen/targets/react/component/handlers/switchmark.ts +1 -1
  94. package/src/codegen/targets/react/component/handlers/tabs.ts +39 -42
  95. package/src/codegen/targets/react/component/handlers/tag-group.ts +45 -41
  96. package/src/codegen/targets/react/component/handlers/text-field.ts +11 -22
  97. package/src/codegen/targets/react/component/handlers/toggle-button.ts +1 -1
  98. package/src/codegen/targets/react/component/index.ts +5 -115
  99. package/src/entities/data/__generated__/archive/component-sets/index.d.ts +2074 -0
  100. package/src/entities/data/__generated__/archive/component-sets/index.mjs +2074 -0
  101. package/src/entities/data/__generated__/archive/components/index.d.ts +116 -0
  102. package/src/entities/data/__generated__/archive/components/index.mjs +116 -0
  103. package/src/entities/data/__generated__/archive/styles/index.d.ts +3 -0
  104. package/src/entities/data/__generated__/archive/styles/index.mjs +429 -0
  105. package/src/entities/data/__generated__/archive/variable-collections/index.d.ts +3 -0
  106. package/src/entities/data/__generated__/archive/variable-collections/index.mjs +501 -0
  107. package/src/entities/data/__generated__/archive/variables/index.d.ts +3 -0
  108. package/src/entities/data/__generated__/archive/variables/index.mjs +7019 -0
  109. package/src/entities/data/__generated__/component-sets/index.d.ts +3442 -1306
  110. package/src/entities/data/__generated__/component-sets/index.mjs +3442 -1306
  111. package/src/entities/data/__generated__/components/index.d.ts +87 -85
  112. package/src/entities/data/__generated__/components/index.mjs +87 -85
  113. package/src/entities/data/__generated__/styles/index.mjs +9 -2
  114. package/src/entities/data/__generated__/variable-collections/index.mjs +150 -173
  115. package/src/entities/data/__generated__/variables/index.mjs +0 -74
  116. package/src/entities/index.ts +21 -7
@@ -0,0 +1,297 @@
1
+ import { createLocalSnippetHelper } from "../../../element-factories";
2
+ import type {
3
+ ChipProperties,
4
+ ChipTabsTriggerProperties,
5
+ TabsChipWrapperProperties,
6
+ TabsLineTriggerFillProperties,
7
+ TabsLineTriggerHugProperties,
8
+ TabsLineWrapperProperties,
9
+ TabsProperties,
10
+ } from "@/codegen/component-properties.archive";
11
+ import { defineComponentHandler } from "@/codegen/core";
12
+ import * as metadata from "@/entities/data/__generated__/archive/component-sets";
13
+ import { camelCase } from "change-case";
14
+ import type { ComponentHandlerDeps } from "../../deps.interface";
15
+ import { handleSizeProp } from "../../size";
16
+ import { match } from "ts-pattern";
17
+ import { findAllInstances } from "@/utils/figma-node";
18
+
19
+ const { createLocalSnippetElement: createTabsLocalSnippetElement } =
20
+ createLocalSnippetHelper("tabs");
21
+
22
+ const { createLocalSnippetElement: createChipTabsLocalSnippetElement } =
23
+ createLocalSnippetHelper("chip-tabs");
24
+
25
+ const LINE_TABS_WRAPPER_KEY = "e114161387f800d3668d0585bed1d109e4edcbe4";
26
+ const CHIP_TABS_WRAPPER_KEY = "d7cf2983c79c8394aaab0185af83a9d1b9d10ece";
27
+
28
+ export const createTabsHandler = (_ctx: ComponentHandlerDeps) => {
29
+ const lineHandler = createLineTabsHandler(_ctx);
30
+ const chipHandler = createChipTabsHandler(_ctx);
31
+
32
+ return defineComponentHandler<TabsProperties>(metadata.tabs.key, (node, traverse) => {
33
+ const props = node.componentProperties;
34
+
35
+ const elementNode = match(props.Variant.value)
36
+ .with("Line", () => {
37
+ const [wrapper] = findAllInstances<TabsLineWrapperProperties>({
38
+ node,
39
+ key: LINE_TABS_WRAPPER_KEY,
40
+ });
41
+
42
+ if (!wrapper) throw new Error("Line Tab wrapper not found");
43
+
44
+ return lineHandler.transform(wrapper, traverse);
45
+ })
46
+ .with("Chip", () => {
47
+ const [wrapper] = findAllInstances<TabsChipWrapperProperties>({
48
+ node,
49
+ key: CHIP_TABS_WRAPPER_KEY,
50
+ });
51
+
52
+ if (!wrapper) throw new Error("Chip Tab wrapper not found");
53
+
54
+ return chipHandler.transform(wrapper, traverse);
55
+ })
56
+ .exhaustive();
57
+
58
+ return elementNode;
59
+ });
60
+ };
61
+
62
+ /*
63
+ <TabsRoot defaultValue="2" triggerLayout="fill">
64
+ <TabsList>
65
+ <TabsTrigger value="1">라벨1</TabsTrigger>
66
+ <TabsTrigger value="2">라벨2</TabsTrigger>
67
+ <TabsTrigger value="3">라벨3</TabsTrigger>
68
+ </TabsList>
69
+ <TabsCarousel>
70
+ <TabsContent value="1">
71
+ <Content>Content 1</Content>
72
+ </TabsContent>
73
+ <TabsContent value="2">
74
+ <Content>Content 2</Content>
75
+ </TabsContent>
76
+ <TabsContent value="3">
77
+ <Content>Content 3</Content>
78
+ </TabsContent>
79
+ </TabsCarousel>
80
+ </TabsRoot>
81
+ */
82
+
83
+ const LINE_TABS_HUG_ITEM_KEY = "946cc52671ac3f46e20a8ff12fcc1c7f618da675";
84
+ const LINE_TABS_FILL_ITEM_KEY = "78039b6b86852b685a6e93e9b6743b9e577cd7db";
85
+
86
+ const createLineTabsHandler = (_ctx: ComponentHandlerDeps) => {
87
+ const hugHandler = createLineTriggerHugHandler(_ctx);
88
+ const fillHandler = createLineTriggerFillHandler(_ctx);
89
+
90
+ return defineComponentHandler<TabsLineWrapperProperties>(
91
+ LINE_TABS_WRAPPER_KEY,
92
+ (node, traverse) => {
93
+ const props = node.componentProperties;
94
+
95
+ const { triggers, defaultValue } = match(props.Layout.value)
96
+ .with("Hug", () => {
97
+ const nodes = findAllInstances<TabsLineTriggerHugProperties>({
98
+ node,
99
+ key: LINE_TABS_HUG_ITEM_KEY,
100
+ });
101
+
102
+ return {
103
+ triggers: nodes.map((node) => ({
104
+ elementNode: hugHandler.transform(node, traverse),
105
+ value: node.componentProperties["Label#4478:2"].value,
106
+ })),
107
+ defaultValue: nodes.find((node) => node.componentProperties.State.value === "Selected")
108
+ ?.componentProperties["Label#4478:2"].value,
109
+ };
110
+ })
111
+ .with("Fill", () => {
112
+ const nodes = findAllInstances<TabsLineTriggerFillProperties>({
113
+ node,
114
+ key: LINE_TABS_FILL_ITEM_KEY,
115
+ });
116
+
117
+ return {
118
+ triggers: nodes.map((node) => ({
119
+ elementNode: fillHandler.transform(node, traverse),
120
+ value: node.componentProperties["Label#4478:2"].value,
121
+ })),
122
+ defaultValue: nodes.find((node) => node.componentProperties.State.value === "Selected")
123
+ ?.componentProperties["Label#4478:2"].value,
124
+ };
125
+ })
126
+ .exhaustive();
127
+
128
+ const rootProps = {
129
+ triggerLayout: camelCase(props.Layout.value),
130
+ size: handleSizeProp(props.Size.value),
131
+ defaultValue,
132
+ };
133
+
134
+ const tabsCarousel = createTabsLocalSnippetElement(
135
+ "TabsCarousel",
136
+ undefined,
137
+ triggers.map(({ value }) => createTabsLocalSnippetElement("TabsContent", { value }, value)),
138
+ );
139
+
140
+ const tabsList = createTabsLocalSnippetElement(
141
+ "TabsList",
142
+ undefined,
143
+ triggers.map(({ elementNode }) => elementNode),
144
+ );
145
+
146
+ return createTabsLocalSnippetElement("TabsRoot", rootProps, [tabsList, tabsCarousel]);
147
+ },
148
+ );
149
+ };
150
+
151
+ const LINE_TRIGGER_HUG_KEY = "946cc52671ac3f46e20a8ff12fcc1c7f618da675";
152
+
153
+ const createLineTriggerHugHandler = (_ctx: ComponentHandlerDeps) =>
154
+ defineComponentHandler<TabsLineTriggerHugProperties>(
155
+ LINE_TRIGGER_HUG_KEY,
156
+ ({ componentProperties: props }) => {
157
+ const commonProps = {
158
+ value: props["Label#4478:2"].value,
159
+ ...(props.State.value === "Disabled" && {
160
+ disabled: true,
161
+ }),
162
+ ...(props["Has Notification#32892:0"].value && {
163
+ notification: true,
164
+ }),
165
+ };
166
+
167
+ return createTabsLocalSnippetElement("TabsTrigger", commonProps);
168
+ },
169
+ );
170
+
171
+ const LINE_TRIGGER_FILL_KEY = "78039b6b86852b685a6e93e9b6743b9e577cd7db";
172
+
173
+ const createLineTriggerFillHandler = (_ctx: ComponentHandlerDeps) =>
174
+ defineComponentHandler<TabsLineTriggerFillProperties>(
175
+ LINE_TRIGGER_FILL_KEY,
176
+ ({ componentProperties: props }) => {
177
+ const commonProps = {
178
+ value: props["Label#4478:2"].value,
179
+ ...(props.State.value === "Disabled" && {
180
+ disabled: true,
181
+ }),
182
+ ...(props["Has Notification#32904:13"].value && {
183
+ notification: true,
184
+ }),
185
+ };
186
+
187
+ return createTabsLocalSnippetElement("TabsTrigger", commonProps);
188
+ },
189
+ );
190
+
191
+ /*
192
+ <ChipTabsRoot
193
+ variant="neutralOutline"
194
+ defaultValue="1"
195
+ >
196
+ <ChipTabsList>
197
+ <ChipTabsTrigger value="1">라벨1</ChipTabsTrigger>
198
+ <ChipTabsTrigger value="2">라벨2</ChipTabsTrigger>
199
+ <ChipTabsTrigger value="3">라벨3</ChipTabsTrigger>
200
+ </ChipTabsList>
201
+ <ChipTabsCarousel>
202
+ <ChipTabsContent value="1">
203
+ <Content>Content 1</Content>
204
+ </ChipTabsContent>
205
+ <ChipTabsContent value="2">
206
+ <Content>Content 2</Content>
207
+ </ChipTabsContent>
208
+ <ChipTabsContent value="3">
209
+ <Content>Content 3</Content>
210
+ </ChipTabsContent>
211
+ </ChipTabsCarousel>
212
+ </ChipTabsRoot>
213
+ */
214
+
215
+ const createChipTabsHandler = (_ctx: ComponentHandlerDeps) => {
216
+ const triggerHandler = createChipTabsTriggerHandler(_ctx);
217
+
218
+ return defineComponentHandler<TabsChipWrapperProperties>(
219
+ CHIP_TABS_WRAPPER_KEY,
220
+ (node, traverse) => {
221
+ const props = node.componentProperties;
222
+
223
+ const nodes = findAllInstances<ChipTabsTriggerProperties>({ node, key: CHIP_TRIGGER_KEY });
224
+
225
+ const triggers = nodes.map((node) => {
226
+ // this is redundant; can this be better?
227
+ const [chip] = findAllInstances<ChipProperties>({ node, key: metadata.chip.key });
228
+ if (!chip) throw new Error("Chip not found in ChipTabsTrigger");
229
+
230
+ return {
231
+ elementNode: triggerHandler.transform(node, traverse),
232
+ value: chip.componentProperties["Label#7185:0"].value,
233
+ };
234
+ });
235
+
236
+ const selectedTrigger = nodes.find(
237
+ (node) => node.componentProperties.State.value === "Selected",
238
+ );
239
+ const [selectedChip] = selectedTrigger
240
+ ? findAllInstances<ChipProperties>({ node: selectedTrigger, key: metadata.chip.key })
241
+ : [undefined];
242
+ if (!selectedChip) throw new Error("Chip not found in ChipTabsTrigger");
243
+
244
+ const defaultValue = selectedChip.componentProperties["Label#7185:0"].value;
245
+
246
+ const variant = match(props.Variant.value)
247
+ .with("Outline", () => "neutralOutline")
248
+ .with("Solid", () => "neutralSolid")
249
+ .exhaustive();
250
+
251
+ const rootProps = {
252
+ size: handleSizeProp(props.Size.value),
253
+ variant,
254
+ defaultValue,
255
+ };
256
+
257
+ const tabsCarousel = createChipTabsLocalSnippetElement(
258
+ "ChipTabsCarousel",
259
+ { swipeable: false },
260
+ triggers.map(({ value }) =>
261
+ createChipTabsLocalSnippetElement("ChipTabsContent", { value }, value),
262
+ ),
263
+ );
264
+
265
+ const tabsList = createChipTabsLocalSnippetElement(
266
+ "ChipTabsList",
267
+ undefined,
268
+ triggers.map(({ elementNode }) => elementNode),
269
+ );
270
+
271
+ return createChipTabsLocalSnippetElement("ChipTabsRoot", rootProps, [tabsList, tabsCarousel]);
272
+ },
273
+ );
274
+ };
275
+
276
+ const CHIP_TRIGGER_KEY = "95bf31a329f9e8bba0d9aa2299d1552f1d388148";
277
+
278
+ const createChipTabsTriggerHandler = (_ctx: ComponentHandlerDeps) =>
279
+ defineComponentHandler<ChipTabsTriggerProperties>(CHIP_TRIGGER_KEY, (node) => {
280
+ const [chip] = findAllInstances<ChipProperties>({ node, key: metadata.chip.key });
281
+ if (!chip) throw new Error("Chip not found in ChipTabsTrigger");
282
+
283
+ const props = node.componentProperties;
284
+ const chipProps = chip.componentProperties;
285
+
286
+ const commonProps = {
287
+ value: chipProps["Label#7185:0"].value,
288
+ ...(chipProps.State.value === "Disabled" && {
289
+ disabled: true,
290
+ }),
291
+ ...(props["Has Notification"].value === "True" && {
292
+ notification: true,
293
+ }),
294
+ };
295
+
296
+ return createChipTabsLocalSnippetElement("ChipTabsTrigger", commonProps);
297
+ });
@@ -0,0 +1,86 @@
1
+ import type { TagGroupItemProperties, TagGroupProperties } from "@/codegen/component-properties.archive";
2
+ import { defineComponentHandler, type ElementNode } 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 { camelCase } from "change-case";
7
+ import { match } from "ts-pattern";
8
+ import { findAllInstances } from "@/utils/figma-node";
9
+
10
+ const { createLocalSnippetElement } = createLocalSnippetHelper("tag-group");
11
+
12
+ export const createTagGroupHandler = (ctx: ComponentHandlerDeps) => {
13
+ const itemHandler = createTagGroupItemHandler(ctx);
14
+
15
+ return defineComponentHandler<TagGroupProperties>(metadata.tagGroup.key, (node, traverse) => {
16
+ const itemNodes = findAllInstances<TagGroupItemProperties>({ node, key: TAG_GROUP_ITEM_KEY });
17
+
18
+ const items = itemNodes.map((itemNode) =>
19
+ itemHandler.transform(itemNode, traverse),
20
+ ) as (ElementNode & {
21
+ props: { size?: string; weight?: string; tone?: string };
22
+ })[];
23
+
24
+ if (items.length === 0) {
25
+ return createLocalSnippetElement("TagGroupRoot");
26
+ }
27
+
28
+ // if size/weight/tone are all the same among item[n].props, lift them up to TagGroupRoot
29
+
30
+ const consistent = {
31
+ size: items.map((item) => item.props.size).every((size) => size === items[0].props.size),
32
+ weight: items
33
+ .map((item) => item.props.weight)
34
+ .every((weight) => weight === items[0].props.weight),
35
+ tone: items.map((item) => item.props.tone).every((tone) => tone === items[0].props.tone),
36
+ };
37
+
38
+ return createLocalSnippetElement(
39
+ "TagGroupRoot",
40
+ {
41
+ // lift up consistent props
42
+ ...(consistent.size && { size: items[0].props.size }),
43
+ ...(consistent.weight && { weight: items[0].props.weight }),
44
+ ...(consistent.tone && { tone: items[0].props.tone }),
45
+ },
46
+ items.map((item) => ({
47
+ ...item,
48
+ props: {
49
+ // remove lifted props
50
+ ...item.props,
51
+ size: consistent.size ? undefined : item.props.size,
52
+ weight: consistent.weight ? undefined : item.props.weight,
53
+ tone: consistent.tone ? undefined : item.props.tone,
54
+ },
55
+ })),
56
+ { comment: "`truncate` prop을 통해 한 줄로 표시되도록 할 수 있습니다." },
57
+ );
58
+ });
59
+ };
60
+
61
+ const TAG_GROUP_ITEM_KEY = "a7bbc318919053f96be00e509469f6294d6bb6bb";
62
+
63
+ export const createTagGroupItemHandler = (ctx: ComponentHandlerDeps) =>
64
+ defineComponentHandler<TagGroupItemProperties>(
65
+ TAG_GROUP_ITEM_KEY,
66
+ ({ componentProperties: props }) => {
67
+ const size = match(props.Size.value)
68
+ .with("t2(12pt)", () => "t2")
69
+ .with("t3(13pt)", () => "t3")
70
+ .with("t4(14pt)", () => "t4")
71
+ .exhaustive();
72
+
73
+ return createLocalSnippetElement("TagGroupItem", {
74
+ size,
75
+ weight: camelCase(props["Weight"].value),
76
+ tone: camelCase(props["Tone"].value),
77
+ label: props["Label#5409:0"].value,
78
+ ...(props.Layout.value === "Icon First" && {
79
+ prefixIcon: ctx.iconHandler.transform(props["Prefix Icon#47948:0"]),
80
+ }),
81
+ ...(props.Layout.value === "Icon Last" && {
82
+ suffixIcon: ctx.iconHandler.transform(props["Suffix Icon#47948:55"]),
83
+ }),
84
+ });
85
+ },
86
+ );
@@ -0,0 +1,264 @@
1
+ import { defineComponentHandler } from "@/codegen/core";
2
+ import * as metadata from "@/entities/data/__generated__/archive/component-sets";
3
+ import { createLocalSnippetHelper } from "../../../element-factories";
4
+ import type { ComponentHandlerDeps } from "../../deps.interface";
5
+ import {
6
+ createFieldFooterHandler,
7
+ createFieldHeaderHandler,
8
+ FIELD_KEYS,
9
+ type FieldFooterProps,
10
+ type FieldHeaderProps,
11
+ } from "@/codegen/targets/react/component/handlers/archive/field";
12
+ import type {
13
+ FieldHeaderProperties,
14
+ FieldFooterProperties,
15
+ TextareaProperties,
16
+ TextInputFieldProperties,
17
+ TextInputOutlineProperties,
18
+ TextInputUnderlineProperties,
19
+ TextInputOutlinePrefixProperties,
20
+ TextInputOutlineSuffixProperties,
21
+ TextInputUnderlinePrefixProperties,
22
+ TextInputUnderlineSuffixProperties,
23
+ TextareaFieldProperties,
24
+ } from "@/codegen/component-properties.archive";
25
+ import { findAllInstances, findOne } from "@/utils/figma-node";
26
+ import type { NormalizedTextNode } from "@/normalizer";
27
+
28
+ const { createLocalSnippetElement } = createLocalSnippetHelper("text-field");
29
+
30
+ const TEXT_INPUT_OUTLINE_KEY = "22eebd645d310c086d9f5f69d8f179ff5c7cf7ca";
31
+ const TEXT_INPUT_OUTLINE_PREFIX_KEY = "1ab174dd51bc42a5efe530f52f1dd02255c50b18";
32
+ const TEXT_INPUT_OUTLINE_SUFFIX_KEY = "555fee288d9053760e301791665bbac31d19c43f";
33
+
34
+ const TEXT_INPUT_UNDERLINE_KEY = "16e9e343fc319190149369bd61076d6415e09a8a";
35
+ const TEXT_INPUT_UNDERLINE_PREFIX_KEY = "a7ceae43b6daf4490e8ab408d2c29fb63b2eb891";
36
+ const TEXT_INPUT_UNDERLINE_SUFFIX_KEY = "1b88368820be61f358e24a8aaa601e7f2a2ea101";
37
+
38
+ const TEXTAREA_KEY = "22bb206483f00cd635188eea6ae8a6aac058b5d5";
39
+
40
+ export const createTextInputFieldHandler = (ctx: ComponentHandlerDeps) => {
41
+ const fieldHeaderHandler = createFieldHeaderHandler(ctx);
42
+ const fieldFooterHandler = createFieldFooterHandler(ctx);
43
+
44
+ return defineComponentHandler<TextInputFieldProperties>(
45
+ metadata.templateTextField.key,
46
+ (node, traverse) => {
47
+ const props = node.componentProperties;
48
+
49
+ const [textInputOutline] = findAllInstances<TextInputOutlineProperties>({
50
+ node,
51
+ key: TEXT_INPUT_OUTLINE_KEY,
52
+ });
53
+ const [textInputUnderline] = findAllInstances<TextInputUnderlineProperties>({
54
+ node,
55
+ key: TEXT_INPUT_UNDERLINE_KEY,
56
+ });
57
+
58
+ const [fieldHeader] = findAllInstances<FieldHeaderProperties>({
59
+ node,
60
+ key: FIELD_KEYS.HEADER,
61
+ });
62
+ const [fieldFooter] = findAllInstances<FieldFooterProperties>({
63
+ node,
64
+ key: FIELD_KEYS.FOOTER,
65
+ });
66
+
67
+ const fieldProps = {
68
+ ...(props["Show Header#40606:8"].value && fieldHeader
69
+ ? (fieldHeaderHandler.transform(fieldHeader, traverse).props as FieldHeaderProps)
70
+ : {}),
71
+ ...(props["Show Footer#40606:9"].value && fieldFooter
72
+ ? (fieldFooterHandler.transform(fieldFooter, traverse).props as FieldFooterProps)
73
+ : {}),
74
+ };
75
+
76
+ const commonProps = (() => {
77
+ if (textInputOutline) {
78
+ const [prefix] = findAllInstances<TextInputOutlinePrefixProperties>({
79
+ node: textInputOutline,
80
+ key: TEXT_INPUT_OUTLINE_PREFIX_KEY,
81
+ });
82
+
83
+ const [suffix] = findAllInstances<TextInputOutlineSuffixProperties>({
84
+ node: textInputOutline,
85
+ key: TEXT_INPUT_OUTLINE_SUFFIX_KEY,
86
+ });
87
+
88
+ return {
89
+ variant: "outline",
90
+ ...(textInputOutline.componentProperties.State.value === "Disabled" && {
91
+ disabled: true,
92
+ }),
93
+ ...(textInputOutline.componentProperties.State.value === "Read Only" && {
94
+ readOnly: true,
95
+ }),
96
+ ...(textInputOutline.componentProperties.State.value === "Error" && {
97
+ invalid: true,
98
+ }),
99
+ ...(textInputOutline.componentProperties.State.value === "Error Focused" && {
100
+ invalid: true,
101
+ }),
102
+ ...(textInputOutline.componentProperties["Has Prefix#32514:10"].value === true &&
103
+ prefix &&
104
+ prefix.componentProperties.Type.value === "Icon" && {
105
+ prefixIcon: ctx.iconHandler.transform(prefix.componentProperties["Icon#34021:2"]),
106
+ }),
107
+ ...(textInputOutline.componentProperties["Has Suffix#32865:68"].value === true &&
108
+ suffix &&
109
+ suffix.componentProperties["Type (Figma Only)"].value === "Icon" && {
110
+ suffixIcon: ctx.iconHandler.transform(suffix.componentProperties["Icon#45391:0"]),
111
+ }),
112
+ ...(textInputOutline.componentProperties["Has Suffix#32865:68"].value === true &&
113
+ suffix &&
114
+ suffix.componentProperties["Type (Figma Only)"].value === "Text" && {
115
+ suffix: suffix.componentProperties["Suffix Text#34021:4"].value,
116
+ }),
117
+ };
118
+ }
119
+
120
+ if (textInputUnderline) {
121
+ const [prefix] = findAllInstances<TextInputUnderlinePrefixProperties>({
122
+ node: textInputUnderline,
123
+ key: TEXT_INPUT_UNDERLINE_PREFIX_KEY,
124
+ });
125
+
126
+ const [suffix] = findAllInstances<TextInputUnderlineSuffixProperties>({
127
+ node: textInputUnderline,
128
+ key: TEXT_INPUT_UNDERLINE_SUFFIX_KEY,
129
+ });
130
+
131
+ return {
132
+ variant: "underline",
133
+ ...(textInputUnderline.componentProperties.State.value === "Disabled" && {
134
+ disabled: true,
135
+ }),
136
+ ...(textInputUnderline.componentProperties.State.value === "Read Only" && {
137
+ readOnly: true,
138
+ }),
139
+ ...(textInputUnderline.componentProperties.State.value === "Error" && {
140
+ invalid: true,
141
+ }),
142
+ ...(textInputUnderline.componentProperties.State.value === "Error Focused" && {
143
+ invalid: true,
144
+ }),
145
+ ...(textInputUnderline.componentProperties["Has Prefix#34125:0"].value === true &&
146
+ prefix &&
147
+ prefix.componentProperties.Type.value === "Icon" && {
148
+ prefixIcon: ctx.iconHandler.transform(prefix.componentProperties["Icon#34021:2"]),
149
+ }),
150
+ ...(textInputUnderline.componentProperties["Has Suffix#34125:8"].value === true &&
151
+ suffix &&
152
+ suffix.componentProperties["Type (Figma Only)"].value === "Icon" && {
153
+ suffixIcon: ctx.iconHandler.transform(suffix.componentProperties["Icon#45391:5"]),
154
+ }),
155
+ ...(textInputUnderline.componentProperties["Has Suffix#34125:8"].value === true &&
156
+ suffix &&
157
+ suffix.componentProperties["Type (Figma Only)"].value === "Text" && {
158
+ suffix: suffix.componentProperties["Suffix Text#34021:4"].value,
159
+ }),
160
+ };
161
+ }
162
+
163
+ return {};
164
+ })();
165
+
166
+ // these can be fragile but better than having 9 different handlers
167
+ const placeholder = findOne(
168
+ node,
169
+ (node) => node.type === "TEXT" && node.name.toLowerCase().includes("placeholder"),
170
+ ) as NormalizedTextNode;
171
+
172
+ const value = findOne(
173
+ node,
174
+ (node) => node.type === "TEXT" && node.name.toLowerCase().includes("value"),
175
+ ) as NormalizedTextNode;
176
+
177
+ const inputProps = {
178
+ ...(placeholder && {
179
+ placeholder: placeholder.characters,
180
+ }),
181
+ };
182
+
183
+ return createLocalSnippetElement(
184
+ "TextField",
185
+ {
186
+ ...fieldProps,
187
+ ...commonProps,
188
+ ...(value && {
189
+ defaultValue: value.characters,
190
+ }),
191
+ },
192
+ createLocalSnippetElement("TextFieldInput", inputProps),
193
+ );
194
+ },
195
+ );
196
+ };
197
+
198
+ export const createTextareaFieldHandler = (ctx: ComponentHandlerDeps) => {
199
+ const fieldHeaderHandler = createFieldHeaderHandler(ctx);
200
+ const fieldFooterHandler = createFieldFooterHandler(ctx);
201
+
202
+ return defineComponentHandler<TextareaFieldProperties>(
203
+ metadata.templateTextareaField.key,
204
+ (node, traverse) => {
205
+ const [textarea] = findAllInstances<TextareaProperties>({
206
+ node,
207
+ key: TEXTAREA_KEY,
208
+ });
209
+ const [fieldHeader] = findAllInstances<FieldHeaderProperties>({
210
+ node,
211
+ key: FIELD_KEYS.HEADER,
212
+ });
213
+ const [fieldFooter] = findAllInstances<FieldFooterProperties>({
214
+ node,
215
+ key: FIELD_KEYS.FOOTER,
216
+ });
217
+
218
+ const fieldProps = {
219
+ ...(fieldHeader
220
+ ? (fieldHeaderHandler.transform(fieldHeader, traverse).props as FieldHeaderProps)
221
+ : {}),
222
+ ...(fieldFooter
223
+ ? (fieldFooterHandler.transform(fieldFooter, traverse).props as FieldFooterProps)
224
+ : {}),
225
+ };
226
+
227
+ // these can be fragile but better than having 9 different handlers
228
+ const placeholder = findOne(
229
+ node,
230
+ (node) => node.type === "TEXT" && node.name.toLowerCase().includes("placeholder"),
231
+ ) as NormalizedTextNode;
232
+
233
+ const value = findOne(
234
+ node,
235
+ (node) => node.type === "TEXT" && node.name.toLowerCase().includes("value"),
236
+ ) as NormalizedTextNode;
237
+
238
+ const inputProps = {
239
+ autoresize: textarea.componentProperties["Auto Size (Figma Only)"].value === "true",
240
+ ...(placeholder && {
241
+ placeholder: placeholder.characters,
242
+ }),
243
+ };
244
+
245
+ const commonProps = {
246
+ ...(textarea.componentProperties.State.value === "Disabled" && {
247
+ disabled: true,
248
+ }),
249
+ ...(textarea.componentProperties.State.value === "Read Only" && {
250
+ readOnly: true,
251
+ }),
252
+ ...(value && {
253
+ defaultValue: value.characters,
254
+ }),
255
+ };
256
+
257
+ return createLocalSnippetElement(
258
+ "TextField",
259
+ { ...fieldProps, ...commonProps },
260
+ createLocalSnippetElement("TextFieldTextarea", inputProps),
261
+ );
262
+ },
263
+ );
264
+ };
@@ -0,0 +1,43 @@
1
+ import type { ToggleButtonProperties } 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, createSeedReactElement } from "../../../element-factories";
6
+ import type { ComponentHandlerDeps } from "../../deps.interface";
7
+ import { handleSizeProp } from "../../size";
8
+
9
+ const { createLocalSnippetElement } = createLocalSnippetHelper("toggle-button");
10
+
11
+ export const createToggleButtonHandler = (ctx: ComponentHandlerDeps) =>
12
+ defineComponentHandler<ToggleButtonProperties>(
13
+ metadata.toggleButton.key,
14
+ ({ componentProperties: props }) => {
15
+ const commonProps = {
16
+ variant: camelCase(props.Variant.value),
17
+ size: handleSizeProp(props.Size.value),
18
+ ...(props.Selected.value === "True" && {
19
+ defaultPressed: true,
20
+ }),
21
+ ...(props.State.value === "Disabled" && {
22
+ disabled: true,
23
+ }),
24
+ ...(props.State.value === "Loading" && {
25
+ loading: true,
26
+ }),
27
+ };
28
+
29
+ return createLocalSnippetElement("ToggleButton", commonProps, [
30
+ props["Show Prefix Icon#6122:392"].value
31
+ ? createSeedReactElement("PrefixIcon", {
32
+ svg: ctx.iconHandler.transform(props["Prefix Icon#6122:98"]),
33
+ })
34
+ : undefined,
35
+ props["Label#6122:49"].value,
36
+ props["Show Suffix Icon#6122:147"].value
37
+ ? createSeedReactElement("SuffixIcon", {
38
+ svg: ctx.iconHandler.transform(props["Suffix Icon#6122:343"]),
39
+ })
40
+ : undefined,
41
+ ]);
42
+ },
43
+ );