@seed-design/figma 1.1.0 → 1.1.2

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 (29) hide show
  1. package/lib/codegen/index.cjs +366 -286
  2. package/lib/codegen/index.d.ts +508 -233
  3. package/lib/codegen/index.d.ts.map +1 -1
  4. package/lib/codegen/index.js +366 -286
  5. package/lib/codegen/targets/react/index.cjs +1012 -510
  6. package/lib/codegen/targets/react/index.d.ts.map +1 -1
  7. package/lib/codegen/targets/react/index.js +1012 -510
  8. package/lib/index.cjs +394 -286
  9. package/lib/index.js +394 -286
  10. package/package.json +1 -1
  11. package/src/codegen/component-properties.ts +362 -103
  12. package/src/codegen/targets/react/component/handlers/bottom-sheet.ts +2 -3
  13. package/src/codegen/targets/react/component/handlers/error-state.ts +18 -6
  14. package/src/codegen/targets/react/component/handlers/field-button.ts +197 -0
  15. package/src/codegen/targets/react/component/handlers/field.ts +167 -0
  16. package/src/codegen/targets/react/component/handlers/slider.ts +114 -0
  17. package/src/codegen/targets/react/component/handlers/text-field.ts +245 -92
  18. package/src/codegen/targets/react/component/index.ts +40 -23
  19. package/src/codegen/targets/react/element-factories.ts +1 -1
  20. package/src/codegen/targets/react/instance.ts +23 -2
  21. package/src/entities/data/__generated__/component-sets/index.d.ts +225 -222
  22. package/src/entities/data/__generated__/component-sets/index.mjs +225 -222
  23. package/src/entities/data/__generated__/components/index.d.ts +121 -0
  24. package/src/entities/data/__generated__/components/index.mjs +121 -0
  25. package/src/entities/data/__generated__/icons/index.mjs +28 -0
  26. package/src/entities/data/__generated__/styles/index.mjs +0 -56
  27. package/src/entities/data/__generated__/variable-collections/index.mjs +11 -8
  28. package/src/entities/data/__generated__/variables/index.mjs +130 -0
  29. package/src/codegen/targets/react/component/handlers/multiline-text-field.ts +0 -84
@@ -1,111 +1,264 @@
1
- import type { TextFieldProperties } from "@/codegen/component-properties";
2
1
  import { defineComponentHandler } from "@/codegen/core";
3
2
  import * as metadata from "@/entities/data/__generated__/component-sets";
4
3
  import { createLocalSnippetHelper } from "../../element-factories";
5
4
  import type { ComponentHandlerDeps } from "../deps.interface";
6
- import { handleSizeProp } from "../size";
5
+ import {
6
+ createFieldFooterHandler,
7
+ createFieldHeaderHandler,
8
+ FIELD_KEYS,
9
+ type FieldFooterProps,
10
+ type FieldHeaderProps,
11
+ } from "@/codegen/targets/react/component/handlers/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";
25
+ import { findAllInstances, findOne } from "@/utils/figma-node";
26
+ import type { NormalizedTextNode } from "@/normalizer";
7
27
 
8
28
  const { createLocalSnippetElement } = createLocalSnippetHelper("text-field");
9
29
 
10
- export const createTextFieldHandler = (ctx: ComponentHandlerDeps) =>
11
- defineComponentHandler<TextFieldProperties>(
12
- metadata.textField.key,
13
- ({ componentProperties: props }) => {
14
- const {
15
- Size: { value: size },
16
- State: { value: state },
17
- Filled: { value: filled },
18
- "Show Header#870:0": { value: showHeader },
19
- "Label#14964:0": { value: label },
20
- "Show Indicator#1259:0": { value: showIndicator },
21
- "Indicator#15327:249": { value: indicator },
22
- "Show Prefix#958:125": { value: showPrefix },
23
- "Show Prefix Icon#1267:50": { value: showPrefixIcon },
24
- "Prefix Icon#1267:25": prefixIcon,
25
- "Show Prefix Text#1267:0": { value: showPrefixText },
26
- "Prefix Text#15327:101": { value: prefix },
27
- "Placeholder#958:0": { value: placeholder },
28
- "Filled Text#1304:0": { value: defaultValue },
29
- "Show Suffix#958:100": { value: showSuffix },
30
- "Show Suffix Icon#1267:75": { value: showSuffixIcon },
31
- "Suffix Icon #1267:100": suffixIcon,
32
- "Show Suffix Text#1267:125": { value: showSuffixText },
33
- "Suffix Text#15327:138": { value: suffix },
34
- "Show Footer#958:25": { value: showFooter },
35
- "Show Description#958:50": { value: showDescription },
36
- "Description#12626:5": { value: description },
37
- "Show Character Count#958:75": { value: showCharacterCount },
38
- "Character Count#15327:64": { value: _characterCount },
39
- "Max Character Count#15327:27": { value: maxCharacterCount },
40
- } = props;
41
-
42
- const states = state.split("-");
30
+ const TEXT_INPUT_OUTLINE_KEY = "22eebd645d310c086d9f5f69d8f179ff5c7cf7ca";
31
+ const TEXT_INPUT_OUTLINE_PREFIX_KEY = "1ab174dd51bc42a5efe530f52f1dd02255c50b18";
32
+ const TEXT_INPUT_OUTLINE_SUFFIX_KEY = "555fee288d9053760e301791665bbac31d19c43f";
43
33
 
44
- const commonProps = {
45
- size: handleSizeProp(size),
46
- // header
47
- ...(showHeader && {
48
- label,
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,
49
180
  }),
50
- ...(showHeader &&
51
- showIndicator && {
52
- indicator,
53
- }),
54
- // input affixes
55
- ...(showPrefix &&
56
- showPrefixIcon && {
57
- prefixIcon: ctx.iconHandler.transform(prefixIcon),
58
- }),
59
- ...(showPrefix &&
60
- showPrefixText && {
61
- prefix,
62
- }),
63
- ...(showSuffix &&
64
- showSuffixIcon && {
65
- suffixIcon: ctx.iconHandler.transform(suffixIcon),
66
- }),
67
- ...(showSuffix &&
68
- showSuffixText && {
69
- suffix,
181
+ };
182
+
183
+ return createLocalSnippetElement(
184
+ "TextField",
185
+ {
186
+ ...fieldProps,
187
+ ...commonProps,
188
+ ...(value && {
189
+ defaultValue: value.characters,
70
190
  }),
71
- // input
72
- ...(filled === "True" && {
73
- defaultValue,
74
- }),
75
- ...(states.includes("Invalid") && {
76
- invalid: true,
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,
77
242
  }),
78
- ...(states.includes("Disabled") && {
243
+ };
244
+
245
+ const commonProps = {
246
+ ...(textarea.componentProperties.State.value === "Disabled" && {
79
247
  disabled: true,
80
248
  }),
81
- ...(states.includes("Read Only") && {
249
+ ...(textarea.componentProperties.State.value === "Read Only" && {
82
250
  readOnly: true,
83
251
  }),
84
- // footer
85
- ...(showFooter &&
86
- showDescription &&
87
- states.includes("Invalid") && {
88
- // invalid인 경우 description을 error로 사용
89
- errorMessage: description,
90
- }),
91
- ...(showFooter &&
92
- showDescription &&
93
- !states.includes("Invalid") && {
94
- // invalid가 아닌 경우 description을 description으로 사용
95
- description,
96
- }),
97
- ...(showFooter &&
98
- showCharacterCount && {
99
- maxGraphemeCount: Number(maxCharacterCount),
100
- }),
101
- };
102
-
103
- const inputProps = {
104
- placeholder,
252
+ ...(value && {
253
+ defaultValue: value.characters,
254
+ }),
105
255
  };
106
256
 
107
- const TextFieldChildren = createLocalSnippetElement("TextFieldInput", inputProps);
108
-
109
- return createLocalSnippetElement("TextField", commonProps, TextFieldChildren);
257
+ return createLocalSnippetElement(
258
+ "TextField",
259
+ { ...fieldProps, ...commonProps },
260
+ createLocalSnippetElement("TextFieldTextarea", inputProps),
261
+ );
110
262
  },
111
263
  );
264
+ };
@@ -19,6 +19,13 @@ import { createChipHandler } from "./handlers/chip";
19
19
  import { createContextualFloatingButtonHandler } from "./handlers/contextual-floating-button";
20
20
  import { createDividerHandler } from "./handlers/divider";
21
21
  import { createErrorStateHandler } from "./handlers/error-state";
22
+ import {
23
+ createFieldButtonHandler,
24
+ createAddressFieldHandler,
25
+ createDatePickerFieldHandler,
26
+ createSelectFieldHandler,
27
+ createTimePickerFieldHandler,
28
+ } from "@/codegen/targets/react/component/handlers/field-button";
22
29
  import { createFloatingActionButtonHandler } from "./handlers/floating-action-button";
23
30
  import { createHelpBubbleHandler } from "./handlers/help-bubble";
24
31
  import { createIdentityPlaceholderHandler } from "./handlers/identity-placeholder";
@@ -27,7 +34,6 @@ import { createListItemHandler } from "@/codegen/targets/react/component/handler
27
34
  import { createMannerTempBadgeHandler } from "./handlers/manner-temp-badge";
28
35
  import { createMannerTempHandler } from "./handlers/manner-temp";
29
36
  import { createMenuSheetHandler } from "./handlers/menu-sheet";
30
- import { createMultilineTextFieldHandler } from "./handlers/multiline-text-field";
31
37
  import { createPageBannerHandler } from "./handlers/page-banner";
32
38
  import { createProgressCircleHandler } from "./handlers/progress-circle";
33
39
  import { createRadioGroupItemHandler } from "@/codegen/targets/react/component/handlers/radio-group";
@@ -36,11 +42,15 @@ import { createReactionButtonHandler } from "./handlers/reaction-button";
36
42
  import { createSegmentedControlHandler } from "./handlers/segmented-control";
37
43
  import { createSelectBoxGroupHandler, createSelectBoxHandler } from "./handlers/select-box";
38
44
  import { createSkeletonHandler } from "./handlers/skeleton";
45
+ import {
46
+ createSliderHandler,
47
+ createSliderFieldHandler,
48
+ } from "@/codegen/targets/react/component/handlers/slider";
39
49
  import { createSnackbarHandler } from "./handlers/snackbar";
40
50
  import { createSwitchMarkHandler } from "@/codegen/targets/react/component/handlers/switch-mark";
41
51
  import { createSwitchHandler } from "./handlers/switch";
42
52
  import { createTabsHandler } from "@/codegen/targets/react/component/handlers/tabs";
43
- import { createTextFieldHandler } from "./handlers/text-field";
53
+ import { createTextInputFieldHandler, createTextareaFieldHandler } from "./handlers/text-field";
44
54
  import { createToggleButtonHandler } from "./handlers/toggle-button";
45
55
  import {
46
56
  createTagGroupHandler,
@@ -62,19 +72,40 @@ export function bindComponentHandler<T extends NormalizedInstanceNode["component
62
72
  export const unboundSeedComponentHandlers: Array<UnboundComponentHandler<any>> = [
63
73
  createActionButtonGhostHandler,
64
74
  createActionButtonHandler,
65
- createAlertDialogHandler,
66
- createAppBarHandler,
67
- createAvatarHandler,
68
- createAvatarStackHandler,
75
+ createTextInputFieldHandler,
76
+ createTextareaFieldHandler,
69
77
  createBadgeHandler,
70
- createBottomSheetHandler,
78
+ createChipHandler,
71
79
  createCalloutHandler,
80
+ createPageBannerHandler,
72
81
  createCheckboxHandler,
73
82
  createCheckmarkHandler,
74
- createChipHandler,
75
- createContextualFloatingButtonHandler,
83
+ createRadioGroupItemHandler,
84
+ createRadioMarkHandler,
85
+ createSwitchHandler,
86
+ createSwitchMarkHandler,
87
+ createAlertDialogHandler,
76
88
  createDividerHandler,
89
+ createAvatarHandler,
90
+ createAvatarStackHandler,
91
+ createSegmentedControlHandler,
92
+ createSelectBoxGroupHandler,
93
+ createSelectBoxHandler,
94
+ createSliderHandler,
95
+ createSliderFieldHandler,
96
+ createTabsHandler,
97
+ createTagGroupHandler,
98
+ createTagGroupItemHandler,
99
+ createToggleButtonHandler,
100
+ createAppBarHandler,
101
+ createBottomSheetHandler,
102
+ createFieldButtonHandler,
103
+ createAddressFieldHandler,
104
+ createDatePickerFieldHandler,
105
+ createSelectFieldHandler,
106
+ createTimePickerFieldHandler,
77
107
  createErrorStateHandler,
108
+ createContextualFloatingButtonHandler,
78
109
  createFloatingActionButtonHandler,
79
110
  createHelpBubbleHandler,
80
111
  createIdentityPlaceholderHandler,
@@ -83,22 +114,8 @@ export const unboundSeedComponentHandlers: Array<UnboundComponentHandler<any>> =
83
114
  createMannerTempBadgeHandler,
84
115
  createMannerTempHandler,
85
116
  createMenuSheetHandler,
86
- createMultilineTextFieldHandler,
87
- createPageBannerHandler,
88
117
  createProgressCircleHandler,
89
- createRadioGroupItemHandler,
90
- createRadioMarkHandler,
91
118
  createReactionButtonHandler,
92
- createSegmentedControlHandler,
93
- createSelectBoxGroupHandler,
94
- createSelectBoxHandler,
95
119
  createSkeletonHandler,
96
120
  createSnackbarHandler,
97
- createSwitchHandler,
98
- createSwitchMarkHandler,
99
- createTabsHandler,
100
- createTagGroupHandler,
101
- createTagGroupItemHandler,
102
- createTextFieldHandler,
103
- createToggleButtonHandler,
104
121
  ];
@@ -1,7 +1,7 @@
1
1
  import { createElement, type ElementNode } from "@/codegen/core";
2
2
 
3
3
  const SEED_REACT_IMPORT_PATH = "@seed-design/react";
4
- const LOCAL_SNIPPET_BASE_PATH = "@/seed-design/ui";
4
+ const LOCAL_SNIPPET_BASE_PATH = "seed-design/ui";
5
5
  const MONOCHROME_ICON_IMPORT_PATH = "@karrotmarket/react-monochrome-icon";
6
6
  const MULTICOLOR_ICON_IMPORT_PATH = "@karrotmarket/react-multicolor-icon";
7
7
 
@@ -8,6 +8,19 @@ import { createSeedReactElement } from "./element-factories";
8
8
  import type { IconHandler } from "./icon";
9
9
  import type { PropsConverters } from "./props";
10
10
 
11
+ const OVERRIDE_ACCEPTABLE_PROPERTIES: Set<NodeChangeProperty> = new Set([
12
+ "characters",
13
+ "parent",
14
+ "locked",
15
+ "visible",
16
+ "name",
17
+ "x",
18
+ "y",
19
+ "componentProperties",
20
+ "componentPropertyDefinitions",
21
+ "componentPropertyReferences",
22
+ ] satisfies NodeChangeProperty[]);
23
+
11
24
  export interface InstanceTransformerDeps {
12
25
  iconHandler?: IconHandler;
13
26
  propsConverters: PropsConverters;
@@ -40,13 +53,21 @@ export function createInstanceTransformer({
40
53
  const handled = componentHandler.transform(node, traverse);
41
54
 
42
55
  if (node.overrides && node.overrides.length > 0) {
43
- const overriddenFields = node.overrides.flatMap(({ overriddenFields }) => overriddenFields);
56
+ const overriddenFields = node.overrides
57
+ .flatMap(({ overriddenFields }) => overriddenFields)
58
+ .filter(
59
+ (field) => OVERRIDE_ACCEPTABLE_PROPERTIES.has(field as NodeChangeProperty) === false,
60
+ );
61
+
62
+ if (overriddenFields.length === 0) {
63
+ return handled;
64
+ }
44
65
 
45
66
  return {
46
67
  ...handled,
47
68
  meta: {
48
69
  ...handled.meta,
49
- comment: `${handled.meta.comment ? `${handled.meta.comment} ` : ""}오버라이드된 필드: ${overriddenFields.join(", ")}`,
70
+ comment: `${handled.meta.comment ? `${handled.meta.comment} ` : ""}오버라이드된 필드: ${Array.from(new Set(overriddenFields)).join(", ")}`,
50
71
  },
51
72
  };
52
73
  }