@seed-design/figma 1.1.0 → 1.1.3

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 (30) hide show
  1. package/lib/codegen/index.cjs +366 -286
  2. package/lib/codegen/index.d.ts +663 -256
  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 +1155 -542
  6. package/lib/codegen/targets/react/index.d.ts.map +1 -1
  7. package/lib/codegen/targets/react/index.js +1155 -542
  8. package/lib/index.cjs +394 -286
  9. package/lib/index.js +394 -286
  10. package/package.json +2 -2
  11. package/src/codegen/component-properties.ts +496 -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/legacy-text-field.ts +196 -0
  17. package/src/codegen/targets/react/component/handlers/slider.ts +114 -0
  18. package/src/codegen/targets/react/component/handlers/text-field.ts +245 -92
  19. package/src/codegen/targets/react/component/index.ts +48 -23
  20. package/src/codegen/targets/react/element-factories.ts +1 -1
  21. package/src/codegen/targets/react/instance.ts +23 -2
  22. package/src/entities/data/__generated__/component-sets/index.d.ts +225 -222
  23. package/src/entities/data/__generated__/component-sets/index.mjs +225 -222
  24. package/src/entities/data/__generated__/components/index.d.ts +121 -0
  25. package/src/entities/data/__generated__/components/index.mjs +121 -0
  26. package/src/entities/data/__generated__/icons/index.mjs +28 -0
  27. package/src/entities/data/__generated__/styles/index.mjs +0 -56
  28. package/src/entities/data/__generated__/variable-collections/index.mjs +11 -8
  29. package/src/entities/data/__generated__/variables/index.mjs +130 -0
  30. package/src/codegen/targets/react/component/handlers/multiline-text-field.ts +0 -84
@@ -28,9 +28,8 @@ export const createBottomSheetHandler = (_ctx: ComponentHandlerDeps) =>
28
28
  ...(props["Show Description#25192:0"].value === true && {
29
29
  description: props["Description#19787:7"].value,
30
30
  }),
31
- ...(props["Show Close Button#19787:11"].value === false && {
32
- hideCloseButton: true,
33
- }),
31
+ showHandle: props["Show Handle#49774:6"].value,
32
+ showCloseButton: props["Show Close Button#19787:11"].value,
34
33
  };
35
34
 
36
35
  const bodyNodes = findAllInstances({
@@ -1,39 +1,51 @@
1
- import type { ActionButtonProperties, ErrorStateProperties } from "@/codegen/component-properties";
1
+ import type {
2
+ ActionButtonGhostProperties,
3
+ ActionButtonProperties,
4
+ ErrorStateProperties,
5
+ } from "@/codegen/component-properties";
2
6
  import { defineComponentHandler } from "@/codegen/core";
3
7
  import * as metadata from "@/entities/data/__generated__/component-sets";
4
8
  import { findAllInstances } from "@/utils/figma-node";
5
9
  import { camelCase } from "change-case";
6
10
  import { createLocalSnippetHelper } from "../../element-factories";
7
11
  import type { ComponentHandlerDeps } from "../deps.interface";
8
- import { createActionButtonHandler } from "./action-button";
12
+ import { createActionButtonGhostHandler, createActionButtonHandler } from "./action-button";
9
13
 
10
14
  const { createLocalSnippetElement } = createLocalSnippetHelper("error-state");
11
15
 
12
16
  export const createErrorStateHandler = (ctx: ComponentHandlerDeps) => {
13
17
  const actionButtonHandler = createActionButtonHandler(ctx);
18
+ const ghostButtonHandler = createActionButtonGhostHandler(ctx);
14
19
 
15
20
  return defineComponentHandler<ErrorStateProperties>(
16
21
  metadata.templateErrorState.key,
17
22
  (node, traverse) => {
18
23
  const props = node.componentProperties;
19
24
 
20
- const [actionButtonNode] = findAllInstances<ActionButtonProperties>({
25
+ const [actionButton] = findAllInstances<ActionButtonProperties>({
21
26
  node,
22
27
  key: actionButtonHandler.key,
23
28
  });
24
29
 
30
+ const [ghostButton] = findAllInstances<ActionButtonGhostProperties>({
31
+ node,
32
+ key: ghostButtonHandler.key,
33
+ });
34
+
25
35
  const commonProps = {
26
36
  variant: camelCase(props.Variant.value),
27
37
  ...(props.Layout.value === "With Title" && {
28
38
  title: props["Title#16237:0"].value,
29
39
  }),
30
40
  description: props["Description#16237:5"].value,
31
- ...(actionButtonNode && {
41
+ ...(actionButton && {
32
42
  primaryActionProps: {
33
- children: actionButtonHandler.transform(actionButtonNode, traverse).children[0],
43
+ children: actionButtonHandler.transform(actionButton, traverse).children[0],
34
44
  },
45
+ }),
46
+ ...(ghostButton && {
35
47
  secondaryActionProps: {
36
- children: props["Secondary Action Label#17042:0"].value,
48
+ children: ghostButtonHandler.transform(ghostButton, traverse).children[0],
37
49
  },
38
50
  }),
39
51
  };
@@ -0,0 +1,197 @@
1
+ import { defineComponentHandler } from "@/codegen/core";
2
+ import * as sets from "@/entities/data/__generated__/component-sets";
3
+ import * as components from "@/entities/data/__generated__/components";
4
+ import { createLocalSnippetHelper } from "../../element-factories";
5
+ import type { ComponentHandlerDeps } from "../deps.interface";
6
+ import {
7
+ createFieldFooterHandler,
8
+ createFieldHeaderHandler,
9
+ FIELD_KEYS,
10
+ type FieldFooterProps,
11
+ type FieldHeaderProps,
12
+ } from "@/codegen/targets/react/component/handlers/field";
13
+ import type {
14
+ FieldHeaderProperties,
15
+ FieldFooterProperties,
16
+ FieldButtonProperties,
17
+ InputButtonProperties,
18
+ InputButtonPrefixProperties,
19
+ InputButtonSuffixProperties,
20
+ ActionButtonGhostProperties,
21
+ GenericFieldButtonProps,
22
+ } from "@/codegen/component-properties";
23
+ import { findAllInstances, findOne } from "@/utils/figma-node";
24
+ import type { NormalizedTextNode } from "@/normalizer";
25
+
26
+ const { createLocalSnippetElement } = createLocalSnippetHelper("field-button");
27
+
28
+ const INPUT_BUTTON_KEY = "965bdecb58755af9a08d60cc3c8d2d33b42e15f0";
29
+ const INPUT_BUTTON_PREFIX_KEY = "12b40c736a098298c64ba16de85702b4b460d1f1";
30
+ const INPUT_BUTTON_SUFFIX_KEY = "5dda27af9f4afafa471925c17acf97d81912877a";
31
+
32
+ export const createFieldButtonHandler = (ctx: ComponentHandlerDeps) => {
33
+ const fieldHeaderHandler = createFieldHeaderHandler(ctx);
34
+ const fieldFooterHandler = createFieldFooterHandler(ctx);
35
+
36
+ return defineComponentHandler<FieldButtonProperties>(
37
+ sets.templateCustomPickerField.key,
38
+ (node, traverse) => {
39
+ const props = node.componentProperties;
40
+
41
+ const [inputButton] = findAllInstances<InputButtonProperties>({
42
+ node,
43
+ key: INPUT_BUTTON_KEY,
44
+ });
45
+
46
+ const [clearButton] = findAllInstances<ActionButtonGhostProperties>({
47
+ node,
48
+ key: sets.actionButtonGhostButton.key,
49
+ });
50
+
51
+ const [fieldHeader] = findAllInstances<FieldHeaderProperties>({
52
+ node,
53
+ key: FIELD_KEYS.HEADER,
54
+ });
55
+ const [fieldFooter] = findAllInstances<FieldFooterProperties>({
56
+ node,
57
+ key: FIELD_KEYS.FOOTER,
58
+ });
59
+
60
+ // maxGraphemeCount and required can't be props of FieldButton
61
+ const { required: __required, ...headerProps } =
62
+ props["Show Header#40606:8"].value && fieldHeader
63
+ ? (fieldHeaderHandler.transform(fieldHeader, traverse).props as FieldHeaderProps)
64
+ : {};
65
+ const { maxGraphemeCount: __maxGraphemeCount, ...footerProps } =
66
+ props["Show Footer#40606:9"].value && fieldFooter
67
+ ? (fieldFooterHandler.transform(fieldFooter, traverse).props as FieldFooterProps)
68
+ : {};
69
+
70
+ const [prefix] = findAllInstances<InputButtonPrefixProperties>({
71
+ node: inputButton,
72
+ key: INPUT_BUTTON_PREFIX_KEY,
73
+ });
74
+
75
+ const [suffix] = findAllInstances<InputButtonSuffixProperties>({
76
+ node: inputButton,
77
+ key: INPUT_BUTTON_SUFFIX_KEY,
78
+ });
79
+
80
+ const commonProps = {
81
+ ...(inputButton.componentProperties.State.value === "Disabled" && {
82
+ disabled: true,
83
+ }),
84
+ ...((inputButton.componentProperties.State.value === "Error" ||
85
+ inputButton.componentProperties.State.value === "Error Pressed") && {
86
+ invalid: true,
87
+ }),
88
+ ...(clearButton && {
89
+ showClearButton: true,
90
+ }),
91
+ ...(inputButton.componentProperties["Has Prefix#32514:10"].value === true &&
92
+ prefix &&
93
+ prefix.componentProperties.Type.value === "Icon" && {
94
+ prefixIcon: ctx.iconHandler.transform(prefix.componentProperties["Icon#34021:2"]),
95
+ }),
96
+ ...(inputButton.componentProperties["Has Suffix#32865:68"].value === true &&
97
+ suffix &&
98
+ suffix.componentProperties["Type (Figma Only)"].value === "Icon" && {
99
+ suffixIcon: ctx.iconHandler.transform(suffix.componentProperties["Icon#37963:0"]),
100
+ }),
101
+ ...(inputButton.componentProperties["Has Suffix#32865:68"].value === true &&
102
+ suffix &&
103
+ suffix.componentProperties["Type (Figma Only)"].value === "Text" && {
104
+ suffix: suffix.componentProperties["Suffix Text#34021:4"].value,
105
+ }),
106
+ };
107
+
108
+ // these can be fragile but better than having 9 different handlers
109
+ const placeholder = findOne(
110
+ node,
111
+ (node) => node.type === "TEXT" && node.name.toLowerCase().includes("placeholder"),
112
+ ) as NormalizedTextNode;
113
+
114
+ const value = findOne(
115
+ node,
116
+ (node) => node.type === "TEXT" && node.name.toLowerCase().includes("value"),
117
+ ) as NormalizedTextNode;
118
+
119
+ return createLocalSnippetElement(
120
+ "FieldButton",
121
+ { ...headerProps, ...footerProps, ...commonProps },
122
+ props["Has Value"].value === "True" && value
123
+ ? createLocalSnippetElement("FieldButtonValue", undefined, value.characters)
124
+ : placeholder
125
+ ? createLocalSnippetElement("FieldButtonPlaceholder", undefined, placeholder.characters)
126
+ : undefined,
127
+ { comment: "buttonProps를 통해 aria-label을 제공하세요." },
128
+ );
129
+ },
130
+ );
131
+ };
132
+
133
+ // TODO: those 4 are basically the same
134
+
135
+ export const createSelectFieldHandler = (ctx: ComponentHandlerDeps) => {
136
+ const fieldButtonHandler = createFieldButtonHandler(ctx);
137
+
138
+ return defineComponentHandler<GenericFieldButtonProps>(
139
+ components.templateSelectField.key,
140
+ (node, traverse) => {
141
+ const [fieldButton] = findAllInstances<FieldButtonProperties>({
142
+ node,
143
+ key: fieldButtonHandler.key,
144
+ });
145
+
146
+ return fieldButtonHandler.transform(fieldButton, traverse);
147
+ },
148
+ );
149
+ };
150
+
151
+ export const createDatePickerFieldHandler = (ctx: ComponentHandlerDeps) => {
152
+ const fieldButtonHandler = createFieldButtonHandler(ctx);
153
+
154
+ return defineComponentHandler<GenericFieldButtonProps>(
155
+ components.templateDatePickerField.key,
156
+ (node, traverse) => {
157
+ const [fieldButton] = findAllInstances<FieldButtonProperties>({
158
+ node,
159
+ key: fieldButtonHandler.key,
160
+ });
161
+
162
+ return fieldButtonHandler.transform(fieldButton, traverse);
163
+ },
164
+ );
165
+ };
166
+
167
+ export const createTimePickerFieldHandler = (ctx: ComponentHandlerDeps) => {
168
+ const fieldButtonHandler = createFieldButtonHandler(ctx);
169
+
170
+ return defineComponentHandler<GenericFieldButtonProps>(
171
+ components.templateTimePickerField.key,
172
+ (node, traverse) => {
173
+ const [fieldButton] = findAllInstances<FieldButtonProperties>({
174
+ node,
175
+ key: fieldButtonHandler.key,
176
+ });
177
+
178
+ return fieldButtonHandler.transform(fieldButton, traverse);
179
+ },
180
+ );
181
+ };
182
+
183
+ export const createAddressFieldHandler = (ctx: ComponentHandlerDeps) => {
184
+ const fieldButtonHandler = createFieldButtonHandler(ctx);
185
+
186
+ return defineComponentHandler<GenericFieldButtonProps>(
187
+ components.templateAddressPickerField.key,
188
+ (node, traverse) => {
189
+ const [fieldButton] = findAllInstances<FieldButtonProperties>({
190
+ node,
191
+ key: fieldButtonHandler.key,
192
+ });
193
+
194
+ return fieldButtonHandler.transform(fieldButton, traverse);
195
+ },
196
+ );
197
+ };
@@ -0,0 +1,167 @@
1
+ import type {
2
+ FieldCharacterCountProperties,
3
+ FieldFooterProperties,
4
+ FieldHeaderProperties,
5
+ FieldIndicatorProperties,
6
+ } from "@/codegen/component-properties";
7
+ import { defineComponentHandler } from "@/codegen/core";
8
+ import { createSeedReactElement } from "../../element-factories";
9
+ import type { ComponentHandlerDeps } from "../deps.interface";
10
+ import { match } from "ts-pattern";
11
+ import { findAllInstances } from "@/utils/figma-node";
12
+ import { camelCase } from "change-case";
13
+
14
+ const FIELD_HEADER_KEY = "84fe2e479c3291177662e41c71af29716e48789b";
15
+ const FIELD_INDICATOR_KEY = "a0a170973212ea0cd952b45a8acb11a92561f402";
16
+ const FIELD_FOOTER_KEY = "ab528f3b51a6dc529bb144de1495b07deef77ffa";
17
+ const FIELD_CHARACTER_COUNT_KEY = "25dd9a96f4bf3b866b8713f6d8deec370eebfa72";
18
+
19
+ export const FIELD_KEYS = {
20
+ HEADER: FIELD_HEADER_KEY,
21
+ FOOTER: FIELD_FOOTER_KEY,
22
+ };
23
+
24
+ export type FieldHeaderProps = FieldIndicatorProps & {
25
+ label?: string;
26
+ labelWeight?: string;
27
+ };
28
+
29
+ /**
30
+ * NOTE: only gives useful 'props' for field-related components but doesn't give fully functional code.
31
+ */
32
+ export const createFieldHeaderHandler = (ctx: ComponentHandlerDeps) => {
33
+ const indicatorHandler = createFieldIndicatorHandler(ctx);
34
+
35
+ return defineComponentHandler<FieldHeaderProperties>(FIELD_HEADER_KEY, (node, traverse) => {
36
+ const { componentProperties: props } = node;
37
+
38
+ const [indicator] = findAllInstances<FieldIndicatorProperties>({
39
+ node,
40
+ key: FIELD_INDICATOR_KEY,
41
+ });
42
+
43
+ // only returns some nice common props for Slider, TextField and more
44
+ return createSeedReactElement("__FieldHeader__", {
45
+ label: props["Label#34796:0"].value,
46
+ labelWeight: camelCase(props.Weight.value),
47
+ ...(indicator &&
48
+ (indicatorHandler.transform(indicator, traverse).props as FieldIndicatorProps)),
49
+ } satisfies FieldHeaderProps);
50
+ });
51
+ };
52
+
53
+ type FieldIndicatorProps = {
54
+ required?: boolean;
55
+ showRequiredIndicator?: boolean;
56
+ indicator?: string;
57
+ };
58
+
59
+ /**
60
+ * NOTE: only gives useful 'props' for field-related components but doesn't give fully functional code.
61
+ */
62
+ const createFieldIndicatorHandler = (_ctx: ComponentHandlerDeps) => {
63
+ return defineComponentHandler<FieldIndicatorProperties>(
64
+ FIELD_INDICATOR_KEY,
65
+ ({ componentProperties: props }) => {
66
+ const { required, showRequiredIndicator, indicator } = match(props.Type.value)
67
+ .with("Required Mark", () => ({
68
+ required: true,
69
+ showRequiredIndicator: true,
70
+ indicator: undefined,
71
+ }))
72
+ .with("Text", () => ({
73
+ required: undefined,
74
+ showRequiredIndicator: undefined,
75
+ indicator: props["Required Label#40606:3"].value,
76
+ }))
77
+ .exhaustive();
78
+
79
+ // only returns some nice common props for Slider, TextField and more
80
+ return createSeedReactElement("__FieldIndicator__", {
81
+ required,
82
+ showRequiredIndicator,
83
+ indicator,
84
+ } satisfies FieldIndicatorProps);
85
+ },
86
+ );
87
+ };
88
+
89
+ export type FieldFooterProps = FieldCharacterCountProps & {
90
+ description?: string;
91
+ maxGraphemeCount?: number;
92
+ invalid?: boolean;
93
+ errorMessage?: string;
94
+ };
95
+
96
+ /**
97
+ * NOTE: only gives useful 'props' for field-related components but doesn't give fully functional code.
98
+ */
99
+ export const createFieldFooterHandler = (ctx: ComponentHandlerDeps) => {
100
+ const characterCountHandler = createFieldCharacterCountHandler(ctx);
101
+
102
+ return defineComponentHandler<FieldFooterProperties>(FIELD_FOOTER_KEY, (node, traverse) => {
103
+ const { componentProperties: props } = node;
104
+
105
+ const { description, maxGraphemeCount } = match(props.Type.value)
106
+ .with("Description", () => ({
107
+ description: props["Text#2770:0"].value,
108
+ maxGraphemeCount: undefined,
109
+ }))
110
+ .with("Description With Character Count", () => ({
111
+ description: props["Text#2770:0"].value,
112
+ maxGraphemeCount: undefined,
113
+ }))
114
+ .with("Character Count", () => {
115
+ const [characterCount] = findAllInstances<FieldCharacterCountProperties>({
116
+ node,
117
+ key: FIELD_CHARACTER_COUNT_KEY,
118
+ });
119
+
120
+ return {
121
+ description: undefined,
122
+ ...(characterCount &&
123
+ (characterCountHandler.transform(characterCount, traverse)
124
+ .props as FieldCharacterCountProps)),
125
+ };
126
+ })
127
+ .exhaustive();
128
+
129
+ const { errorMessage, invalid } = match(props.Error.value === "true")
130
+ .with(true, () => ({
131
+ invalid: true,
132
+ errorMessage: props["Error Text#32821:0"].value,
133
+ }))
134
+ .with(false, () => ({
135
+ invalid: undefined,
136
+ errorMessage: undefined,
137
+ }))
138
+ .exhaustive();
139
+
140
+ // only returns some nice common props for Slider, TextField and more
141
+ return createSeedReactElement("__FieldFooter__", {
142
+ description,
143
+ maxGraphemeCount,
144
+ invalid,
145
+ errorMessage,
146
+ } satisfies FieldFooterProps);
147
+ });
148
+ };
149
+
150
+ type FieldCharacterCountProps = {
151
+ maxGraphemeCount?: number;
152
+ };
153
+
154
+ /**
155
+ * NOTE: only gives useful 'props' for field-related components but doesn't give fully functional code.
156
+ */
157
+ const createFieldCharacterCountHandler = (_ctx: ComponentHandlerDeps) => {
158
+ return defineComponentHandler<FieldCharacterCountProperties>(
159
+ FIELD_CHARACTER_COUNT_KEY,
160
+ ({ componentProperties: props }) => {
161
+ // only returns some nice common props for Slider, TextField and more
162
+ return createSeedReactElement("__FieldCharacterCount__", {
163
+ maxGraphemeCount: Number(props["Max Count#40960:4"].value),
164
+ } satisfies FieldCharacterCountProps);
165
+ },
166
+ );
167
+ };
@@ -0,0 +1,196 @@
1
+ import type {
2
+ LegacyMultilineTextFieldProperties,
3
+ LegacyTextFieldProperties,
4
+ } from "@/codegen/component-properties";
5
+ import { defineComponentHandler } from "@/codegen/core";
6
+ import { createLocalSnippetHelper } from "../../element-factories";
7
+ import type { ComponentHandlerDeps } from "../deps.interface";
8
+ import { handleSizeProp } from "../size";
9
+
10
+ const { createLocalSnippetElement } = createLocalSnippetHelper("text-field");
11
+
12
+ const LEGACY_TEXT_FIELD_KEY = "c49873c37a639f0dffdea4efd0eb43760d66c141";
13
+ const LEGACY_MULTILINE_TEXT_FIELD_KEY = "88b2399c930c85f9ce2972163a078bc684b84bbe";
14
+
15
+ export const createLegacyTextFieldHandler = (ctx: ComponentHandlerDeps) =>
16
+ defineComponentHandler<LegacyTextFieldProperties>(
17
+ LEGACY_TEXT_FIELD_KEY,
18
+ ({ componentProperties: props }) => {
19
+ const {
20
+ Size: { value: size },
21
+ State: { value: state },
22
+ Filled: { value: filled },
23
+ "Show Header#870:0": { value: showHeader },
24
+ "Label#14964:0": { value: label },
25
+ "Show Indicator#1259:0": { value: showIndicator },
26
+ "Indicator#15327:249": { value: indicator },
27
+ "Show Prefix#958:125": { value: showPrefix },
28
+ "Show Prefix Icon#1267:50": { value: showPrefixIcon },
29
+ "Prefix Icon#1267:25": prefixIcon,
30
+ "Show Prefix Text#1267:0": { value: showPrefixText },
31
+ "Prefix Text#15327:101": { value: prefix },
32
+ "Placeholder#958:0": { value: placeholder },
33
+ "Filled Text#1304:0": { value: defaultValue },
34
+ "Show Suffix#958:100": { value: showSuffix },
35
+ "Show Suffix Icon#1267:75": { value: showSuffixIcon },
36
+ "Suffix Icon #1267:100": suffixIcon,
37
+ "Show Suffix Text#1267:125": { value: showSuffixText },
38
+ "Suffix Text#15327:138": { value: suffix },
39
+ "Show Footer#958:25": { value: showFooter },
40
+ "Show Description#958:50": { value: showDescription },
41
+ "Description#12626:5": { value: description },
42
+ "Show Character Count#958:75": { value: showCharacterCount },
43
+ "Character Count#15327:64": { value: _characterCount },
44
+ "Max Character Count#15327:27": { value: maxCharacterCount },
45
+ } = props;
46
+
47
+ const states = state.split("-");
48
+
49
+ const commonProps = {
50
+ size: handleSizeProp(size),
51
+ // header
52
+ ...(showHeader && {
53
+ label,
54
+ }),
55
+ ...(showHeader &&
56
+ showIndicator && {
57
+ indicator,
58
+ }),
59
+ // input affixes
60
+ ...(showPrefix &&
61
+ showPrefixIcon && {
62
+ prefixIcon: ctx.iconHandler.transform(prefixIcon),
63
+ }),
64
+ ...(showPrefix &&
65
+ showPrefixText && {
66
+ prefix,
67
+ }),
68
+ ...(showSuffix &&
69
+ showSuffixIcon && {
70
+ suffixIcon: ctx.iconHandler.transform(suffixIcon),
71
+ }),
72
+ ...(showSuffix &&
73
+ showSuffixText && {
74
+ suffix,
75
+ }),
76
+ // input
77
+ ...(filled === "True" && {
78
+ defaultValue,
79
+ }),
80
+ ...(states.includes("Invalid") && {
81
+ invalid: true,
82
+ }),
83
+ ...(states.includes("Disabled") && {
84
+ disabled: true,
85
+ }),
86
+ ...(states.includes("Read Only") && {
87
+ readOnly: true,
88
+ }),
89
+ // footer
90
+ ...(showFooter &&
91
+ showDescription &&
92
+ states.includes("Invalid") && {
93
+ // invalid인 경우 description을 error로 사용
94
+ errorMessage: description,
95
+ }),
96
+ ...(showFooter &&
97
+ showDescription &&
98
+ !states.includes("Invalid") && {
99
+ // invalid가 아닌 경우 description을 description으로 사용
100
+ description,
101
+ }),
102
+ ...(showFooter &&
103
+ showCharacterCount && {
104
+ maxGraphemeCount: Number(maxCharacterCount),
105
+ }),
106
+ };
107
+
108
+ const inputProps = {
109
+ placeholder,
110
+ };
111
+
112
+ const TextFieldChildren = createLocalSnippetElement("TextFieldInput", inputProps);
113
+
114
+ return createLocalSnippetElement("TextField", commonProps, TextFieldChildren, {
115
+ comment: "이 Figma 컴포넌트는 @seed-design/react@1.1보다 낮은 버전의 TextField입니다.",
116
+ });
117
+ },
118
+ );
119
+
120
+ export const createLegacyMultilineTextFieldHandler = (_ctx: ComponentHandlerDeps) =>
121
+ defineComponentHandler<LegacyMultilineTextFieldProperties>(
122
+ LEGACY_MULTILINE_TEXT_FIELD_KEY,
123
+ ({ componentProperties: props }) => {
124
+ const {
125
+ Size: { value: size },
126
+ State: { value: state },
127
+ Filled: { value: filled },
128
+ "Show Header#870:0": { value: showHeader },
129
+ "Label#15327:323": { value: label },
130
+ "Show Indicator#1259:0": { value: showIndicator },
131
+ "Indicator#15327:286": { value: indicator },
132
+ "Placeholder#958:0": { value: placeholder },
133
+ "Filled Text#1304:0": { value: defaultValue },
134
+ "Show Footer#958:25": { value: showFooter },
135
+ "Show Description#958:50": { value: showDescription },
136
+ "Description#15327:212": { value: description },
137
+ "Show Character count#958:75": { value: showCharacterCount },
138
+ "Character Count#15327:360": { value: _characterCount },
139
+ "Max Character Count#15327:175": { value: maxCharacterCount },
140
+ } = props;
141
+
142
+ const states = state.split("-");
143
+
144
+ const commonProps = {
145
+ size: handleSizeProp(size),
146
+ // header
147
+ ...(showHeader && {
148
+ label,
149
+ }),
150
+ ...(showHeader &&
151
+ showIndicator && {
152
+ indicator,
153
+ }),
154
+ // input
155
+ ...(filled === "True" && {
156
+ defaultValue,
157
+ }),
158
+ ...(states.includes("Invalid") && {
159
+ invalid: true,
160
+ }),
161
+ ...(states.includes("Disabled") && {
162
+ disabled: true,
163
+ }),
164
+ ...(states.includes("Read Only") && {
165
+ readOnly: true,
166
+ }),
167
+ // footer
168
+ ...(showFooter &&
169
+ showDescription &&
170
+ states.includes("Invalid") && {
171
+ // invalid인 경우 description을 error로 사용
172
+ errorMessage: description,
173
+ }),
174
+ ...(showFooter &&
175
+ showDescription &&
176
+ !states.includes("Invalid") && {
177
+ // invalid가 아닌 경우 description을 description으로 사용
178
+ description,
179
+ }),
180
+ ...(showFooter &&
181
+ showCharacterCount && {
182
+ maxGraphemeCount: Number(maxCharacterCount),
183
+ }),
184
+ };
185
+
186
+ const inputProps = {
187
+ placeholder,
188
+ };
189
+
190
+ const TextFieldChildren = createLocalSnippetElement("TextFieldTextarea", inputProps);
191
+
192
+ return createLocalSnippetElement("TextField", commonProps, TextFieldChildren, {
193
+ comment: "이 Figma 컴포넌트는 @seed-design/react@1.1보다 낮은 버전의 TextField입니다.",
194
+ });
195
+ },
196
+ );