@seed-design/figma 0.1.6 → 0.1.8
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.
- package/lib/codegen/index.cjs +746 -646
- package/lib/codegen/index.d.ts +707 -627
- package/lib/codegen/index.d.ts.map +1 -1
- package/lib/codegen/index.js +746 -646
- package/lib/codegen/targets/react/index.cjs +1170 -1180
- package/lib/codegen/targets/react/index.d.ts +20 -9
- package/lib/codegen/targets/react/index.d.ts.map +1 -1
- package/lib/codegen/targets/react/index.js +1170 -1180
- package/lib/index.cjs +883 -668
- package/lib/index.d.ts +3 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +883 -668
- package/package.json +3 -3
- package/src/codegen/component-properties.ts +283 -146
- package/src/codegen/core/component-handler.ts +9 -3
- package/src/codegen/core/jsx.ts +7 -2
- package/src/codegen/core/value-resolver.ts +35 -21
- package/src/codegen/targets/figma/pipeline.ts +4 -2
- package/src/codegen/targets/figma/value-resolver.ts +38 -2
- package/src/codegen/targets/react/component/handlers/action-button.ts +69 -5
- package/src/codegen/targets/react/component/handlers/alert-dialog.ts +81 -0
- package/src/codegen/targets/react/component/handlers/app-bar.ts +93 -128
- package/src/codegen/targets/react/component/handlers/avatar.ts +17 -8
- package/src/codegen/targets/react/component/handlers/badge.ts +0 -1
- package/src/codegen/targets/react/component/handlers/bottom-sheet.ts +71 -0
- package/src/codegen/targets/react/component/handlers/callout.ts +13 -17
- package/src/codegen/targets/react/component/handlers/chip.ts +66 -0
- package/src/codegen/targets/react/component/handlers/contextual-floating-button.ts +52 -0
- package/src/codegen/targets/react/component/handlers/divider.ts +19 -0
- package/src/codegen/targets/react/component/handlers/error-state.ts +26 -23
- package/src/codegen/targets/react/component/handlers/floating-action-button.ts +48 -0
- package/src/codegen/targets/react/component/handlers/help-bubble.ts +4 -5
- package/src/codegen/targets/react/component/handlers/identity-placeholder.ts +3 -2
- package/src/codegen/targets/react/component/handlers/inline-banner.ts +7 -14
- package/src/codegen/targets/react/component/handlers/manner-temp.ts +18 -0
- package/src/codegen/targets/react/component/handlers/menu-sheet.ts +106 -0
- package/src/codegen/targets/react/component/handlers/multiline-text-field.ts +1 -1
- package/src/codegen/targets/react/component/handlers/progress-circle.ts +3 -1
- package/src/codegen/targets/react/component/handlers/segmented-control.ts +4 -2
- package/src/codegen/targets/react/component/handlers/select-box.ts +7 -4
- package/src/codegen/targets/react/component/handlers/snackbar.ts +2 -2
- package/src/codegen/targets/react/component/handlers/tabs.ts +8 -125
- package/src/codegen/targets/react/component/index.ts +22 -19
- package/src/codegen/targets/react/instance.ts +1 -1
- package/src/codegen/targets/react/pipeline.ts +4 -2
- package/src/codegen/targets/react/props.ts +11 -4
- package/src/codegen/targets/react/value-resolver.ts +38 -3
- package/src/entities/data/__generated__/component-sets/action-button.d.ts +5 -5
- package/src/entities/data/__generated__/component-sets/action-button.mjs +5 -5
- package/src/entities/data/__generated__/component-sets/alert-dialog.d.ts +26 -0
- package/src/entities/data/__generated__/component-sets/alert-dialog.mjs +26 -0
- package/src/entities/data/__generated__/component-sets/avatar-stack.d.ts +5 -18
- package/src/entities/data/__generated__/component-sets/avatar-stack.mjs +5 -18
- package/src/entities/data/__generated__/component-sets/avatar.d.ts +11 -5
- package/src/entities/data/__generated__/component-sets/avatar.mjs +11 -5
- package/src/entities/data/__generated__/component-sets/badge.d.ts +0 -7
- package/src/entities/data/__generated__/component-sets/badge.mjs +0 -7
- package/src/entities/data/__generated__/component-sets/bottom-navigation-global.d.ts +3 -0
- package/src/entities/data/__generated__/component-sets/bottom-navigation-global.mjs +3 -0
- package/src/entities/data/__generated__/component-sets/bottom-navigation-kr.d.ts +3 -0
- package/src/entities/data/__generated__/component-sets/bottom-navigation-kr.mjs +3 -0
- package/src/entities/data/__generated__/component-sets/bottom-sheet.d.ts +53 -4
- package/src/entities/data/__generated__/component-sets/bottom-sheet.mjs +53 -4
- package/src/entities/data/__generated__/component-sets/callout.d.ts +13 -22
- package/src/entities/data/__generated__/component-sets/callout.mjs +13 -22
- package/src/entities/data/__generated__/component-sets/checkbox.d.ts +3 -3
- package/src/entities/data/__generated__/component-sets/checkbox.mjs +3 -3
- package/src/entities/data/__generated__/component-sets/checkmark.d.ts +34 -0
- package/src/entities/data/__generated__/component-sets/checkmark.mjs +34 -0
- package/src/entities/data/__generated__/component-sets/chip.d.ts +86 -0
- package/src/entities/data/__generated__/component-sets/chip.mjs +86 -0
- package/src/entities/data/__generated__/component-sets/chlid.d.ts +14 -0
- package/src/entities/data/__generated__/component-sets/chlid.mjs +14 -0
- package/src/entities/data/__generated__/component-sets/{extended-floating-action-button.d.ts → contextual-floating-button.d.ts} +12 -10
- package/src/entities/data/__generated__/component-sets/{extended-floating-action-button.mjs → contextual-floating-button.mjs} +12 -10
- package/src/entities/data/__generated__/component-sets/floating-action-button.d.ts +4 -8
- package/src/entities/data/__generated__/component-sets/floating-action-button.mjs +4 -8
- package/src/entities/data/__generated__/component-sets/help-bubble.d.ts +3 -10
- package/src/entities/data/__generated__/component-sets/help-bubble.mjs +3 -10
- package/src/entities/data/__generated__/component-sets/index.d.ts +13 -13
- package/src/entities/data/__generated__/component-sets/index.mjs +13 -13
- package/src/entities/data/__generated__/component-sets/inline-banner.d.ts +3 -3
- package/src/entities/data/__generated__/component-sets/inline-banner.mjs +3 -3
- package/src/entities/data/__generated__/component-sets/main-tab-navigation-global.d.ts +2 -2
- package/src/entities/data/__generated__/component-sets/main-tab-navigation-global.mjs +2 -2
- package/src/entities/data/__generated__/component-sets/manner-temp-badge.d.ts +2 -2
- package/src/entities/data/__generated__/component-sets/manner-temp-badge.mjs +2 -2
- package/src/entities/data/__generated__/component-sets/manner-temp.d.ts +2 -2
- package/src/entities/data/__generated__/component-sets/manner-temp.mjs +2 -2
- package/src/entities/data/__generated__/component-sets/{extended-action-sheet.d.ts → menu-sheet.d.ts} +17 -13
- package/src/entities/data/__generated__/component-sets/{extended-action-sheet.mjs → menu-sheet.mjs} +17 -13
- package/src/entities/data/__generated__/component-sets/multiline-text-field.d.ts +18 -18
- package/src/entities/data/__generated__/component-sets/multiline-text-field.mjs +18 -18
- package/src/entities/data/__generated__/component-sets/progress-circle.d.ts +2 -1
- package/src/entities/data/__generated__/component-sets/progress-circle.mjs +2 -1
- package/src/entities/data/__generated__/component-sets/radio-mark.d.ts +34 -0
- package/src/entities/data/__generated__/component-sets/radio-mark.mjs +34 -0
- package/src/entities/data/__generated__/component-sets/radio.d.ts +2 -2
- package/src/entities/data/__generated__/component-sets/radio.mjs +2 -2
- package/src/entities/data/__generated__/component-sets/reaction-button.d.ts +6 -6
- package/src/entities/data/__generated__/component-sets/reaction-button.mjs +6 -6
- package/src/entities/data/__generated__/component-sets/resizable-child.d.ts +18 -0
- package/src/entities/data/__generated__/component-sets/resizable-child.mjs +18 -0
- package/src/entities/data/__generated__/component-sets/resizable-icon.d.ts +18 -0
- package/src/entities/data/__generated__/component-sets/resizable-icon.mjs +18 -0
- package/src/entities/data/__generated__/component-sets/select-box.d.ts +4 -4
- package/src/entities/data/__generated__/component-sets/select-box.mjs +4 -4
- package/src/entities/data/__generated__/component-sets/skeleton.d.ts +7 -0
- package/src/entities/data/__generated__/component-sets/skeleton.mjs +7 -0
- package/src/entities/data/__generated__/component-sets/snackbar.d.ts +4 -4
- package/src/entities/data/__generated__/component-sets/snackbar.mjs +4 -4
- package/src/entities/data/__generated__/component-sets/switch.d.ts +1 -1
- package/src/entities/data/__generated__/component-sets/switch.mjs +1 -1
- package/src/entities/data/__generated__/component-sets/tabs.d.ts +13 -0
- package/src/entities/data/__generated__/component-sets/tabs.mjs +13 -0
- package/src/entities/data/__generated__/component-sets/template-button-group.d.ts +9 -33
- package/src/entities/data/__generated__/component-sets/template-button-group.mjs +9 -33
- package/src/entities/data/__generated__/component-sets/template-chip-group.d.ts +15 -12
- package/src/entities/data/__generated__/component-sets/template-chip-group.mjs +15 -12
- package/src/entities/data/__generated__/component-sets/template-completion.d.ts +28 -0
- package/src/entities/data/__generated__/component-sets/template-completion.mjs +28 -0
- package/src/entities/data/__generated__/component-sets/{error-state.d.ts → template-error-state.d.ts} +5 -5
- package/src/entities/data/__generated__/component-sets/{error-state.mjs → template-error-state.mjs} +5 -5
- package/src/entities/data/__generated__/component-sets/template-top-navigation.d.ts +9 -7
- package/src/entities/data/__generated__/component-sets/template-top-navigation.mjs +9 -7
- package/src/entities/data/__generated__/component-sets/text-field.d.ts +35 -36
- package/src/entities/data/__generated__/component-sets/text-field.mjs +35 -36
- package/src/entities/data/__generated__/component-sets/toggle-button.d.ts +7 -7
- package/src/entities/data/__generated__/component-sets/toggle-button.mjs +7 -7
- package/src/entities/data/__generated__/component-sets/top-navigation.d.ts +42 -0
- package/src/entities/data/__generated__/component-sets/top-navigation.mjs +42 -0
- package/src/entities/data/styles.ts +94 -0
- package/src/entities/index.ts +5 -2
- package/src/normalizer/from-plugin.ts +104 -44
- package/src/normalizer/types.ts +3 -1
- package/src/utils/figma-gradient.ts +72 -0
- package/src/utils/figma-node.ts +4 -3
- package/src/codegen/targets/react/component/handlers/action-chip.ts +0 -72
- package/src/codegen/targets/react/component/handlers/action-sheet.ts +0 -82
- package/src/codegen/targets/react/component/handlers/chip-tabs.ts +0 -57
- package/src/codegen/targets/react/component/handlers/control-chip.ts +0 -81
- package/src/codegen/targets/react/component/handlers/extended-action-sheet.ts +0 -98
- package/src/codegen/targets/react/component/handlers/extended-fab.ts +0 -25
- package/src/codegen/targets/react/component/handlers/fab.ts +0 -22
- package/src/codegen/targets/react/component/handlers/text-button.ts +0 -49
- package/src/entities/data/__generated__/component-sets/action-chip.d.ts +0 -57
- package/src/entities/data/__generated__/component-sets/action-chip.mjs +0 -57
- package/src/entities/data/__generated__/component-sets/action-sheet.d.ts +0 -40
- package/src/entities/data/__generated__/component-sets/action-sheet.mjs +0 -40
- package/src/entities/data/__generated__/component-sets/chip-tablist.d.ts +0 -24
- package/src/entities/data/__generated__/component-sets/chip-tablist.mjs +0 -24
- package/src/entities/data/__generated__/component-sets/control-chip.d.ts +0 -60
- package/src/entities/data/__generated__/component-sets/control-chip.mjs +0 -60
- package/src/entities/data/__generated__/component-sets/identity-placeholder.d.ts +0 -13
- package/src/entities/data/__generated__/component-sets/identity-placeholder.mjs +0 -13
- package/src/entities/data/__generated__/component-sets/manner-temp-bar.d.ts +0 -23
- package/src/entities/data/__generated__/component-sets/manner-temp-bar.mjs +0 -23
- package/src/entities/data/__generated__/component-sets/standard-navigation.d.ts +0 -23
- package/src/entities/data/__generated__/component-sets/standard-navigation.mjs +0 -23
- package/src/entities/data/__generated__/component-sets/tablist.d.ts +0 -29
- package/src/entities/data/__generated__/component-sets/tablist.mjs +0 -29
- package/src/entities/data/__generated__/component-sets/template-bottom-fixed-bar.d.ts +0 -42
- package/src/entities/data/__generated__/component-sets/template-bottom-fixed-bar.mjs +0 -42
- package/src/entities/data/__generated__/component-sets/text-button.d.ts +0 -45
- package/src/entities/data/__generated__/component-sets/text-button.mjs +0 -45
|
@@ -16,11 +16,11 @@ import {
|
|
|
16
16
|
import type { RGBA } from "@figma/rest-api-spec";
|
|
17
17
|
import type { VariableService } from "../../entities/variable.service";
|
|
18
18
|
|
|
19
|
-
export interface ValueResolver<TColor, TDimension, TFontDimension, TFontWeight> {
|
|
19
|
+
export interface ValueResolver<TColor, TGradient, TDimension, TFontDimension, TFontWeight> {
|
|
20
20
|
getFormattedValue: {
|
|
21
21
|
frameFill: (
|
|
22
22
|
node: NormalizedHasGeometryTrait & NormalizedIsLayerTrait,
|
|
23
|
-
) => string | TColor | undefined;
|
|
23
|
+
) => string | TColor | TGradient | undefined;
|
|
24
24
|
shapeFill: (
|
|
25
25
|
node: NormalizedHasGeometryTrait & NormalizedIsLayerTrait,
|
|
26
26
|
) => string | TColor | undefined;
|
|
@@ -90,11 +90,12 @@ export interface ValueResolver<TColor, TDimension, TFontDimension, TFontWeight>
|
|
|
90
90
|
) => string | undefined; // TODO: we might turn this into a generic; not sure yet
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
export interface ValueResolverDeps<TColor, TDimension, TFontDimension, TFontWeight> {
|
|
93
|
+
export interface ValueResolverDeps<TColor, TGradient, TDimension, TFontDimension, TFontWeight> {
|
|
94
94
|
variableService: VariableService;
|
|
95
95
|
variableNameFormatter: (props: { slug: string[] }) => string;
|
|
96
96
|
styleService: StyleService;
|
|
97
|
-
|
|
97
|
+
textStyleNameFormatter: (props: { slug: string[] }) => string;
|
|
98
|
+
fillStyleResolver: (props: { slug: string[] }) => TGradient | undefined;
|
|
98
99
|
rawValueFormatters: {
|
|
99
100
|
color: (value: RGBA) => string | TColor;
|
|
100
101
|
dimension: (value: number) => string | TDimension;
|
|
@@ -104,15 +105,17 @@ export interface ValueResolverDeps<TColor, TDimension, TFontDimension, TFontWeig
|
|
|
104
105
|
shouldInferVariableName: boolean;
|
|
105
106
|
}
|
|
106
107
|
|
|
107
|
-
export function createValueResolver<TColor, TDimension, TFontDimension, TFontWeight>({
|
|
108
|
+
export function createValueResolver<TColor, TGradient, TDimension, TFontDimension, TFontWeight>({
|
|
108
109
|
variableService,
|
|
109
110
|
variableNameFormatter,
|
|
110
111
|
styleService,
|
|
111
|
-
|
|
112
|
+
textStyleNameFormatter,
|
|
113
|
+
fillStyleResolver,
|
|
112
114
|
rawValueFormatters,
|
|
113
115
|
shouldInferVariableName,
|
|
114
|
-
}: ValueResolverDeps<TColor, TDimension, TFontDimension, TFontWeight>): ValueResolver<
|
|
116
|
+
}: ValueResolverDeps<TColor, TGradient, TDimension, TFontDimension, TFontWeight>): ValueResolver<
|
|
115
117
|
TColor,
|
|
118
|
+
TGradient,
|
|
116
119
|
TDimension,
|
|
117
120
|
TFontDimension,
|
|
118
121
|
TFontWeight
|
|
@@ -141,16 +144,6 @@ export function createValueResolver<TColor, TDimension, TFontDimension, TFontWei
|
|
|
141
144
|
return getVariableName(inferred.key);
|
|
142
145
|
}
|
|
143
146
|
|
|
144
|
-
function getStyleName(key: string) {
|
|
145
|
-
const slug = styleService.getSlug(key);
|
|
146
|
-
|
|
147
|
-
if (!slug) {
|
|
148
|
-
return undefined;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
return styleNameFormatter({ slug });
|
|
152
|
-
}
|
|
153
|
-
|
|
154
147
|
function processColor(
|
|
155
148
|
key: string | undefined,
|
|
156
149
|
value: RGBA | undefined,
|
|
@@ -167,6 +160,16 @@ export function createValueResolver<TColor, TDimension, TFontDimension, TFontWei
|
|
|
167
160
|
return undefined;
|
|
168
161
|
}
|
|
169
162
|
|
|
163
|
+
function processFillStyle(key: string) {
|
|
164
|
+
const slug = styleService.getSlug(key);
|
|
165
|
+
|
|
166
|
+
if (!slug) {
|
|
167
|
+
return undefined;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return fillStyleResolver({ slug });
|
|
171
|
+
}
|
|
172
|
+
|
|
170
173
|
function processDimension(
|
|
171
174
|
key: string | undefined,
|
|
172
175
|
value: number | undefined,
|
|
@@ -229,6 +232,7 @@ export function createValueResolver<TColor, TDimension, TFontDimension, TFontWei
|
|
|
229
232
|
|
|
230
233
|
const getFormattedValue: ValueResolver<
|
|
231
234
|
TColor,
|
|
235
|
+
TGradient,
|
|
232
236
|
TDimension,
|
|
233
237
|
TFontDimension,
|
|
234
238
|
TFontWeight
|
|
@@ -264,7 +268,13 @@ export function createValueResolver<TColor, TDimension, TFontDimension, TFontWei
|
|
|
264
268
|
itemSpacing: (node) =>
|
|
265
269
|
processDimension(node.boundVariables?.itemSpacing?.id, node.itemSpacing, "GAP"),
|
|
266
270
|
frameFill: (node) =>
|
|
267
|
-
|
|
271
|
+
node.fillStyleKey
|
|
272
|
+
? processFillStyle(node.fillStyleKey)
|
|
273
|
+
: processColor(
|
|
274
|
+
getFirstFillVariable(node)?.id,
|
|
275
|
+
getFirstSolidFill(node)?.color,
|
|
276
|
+
"FRAME_FILL",
|
|
277
|
+
),
|
|
268
278
|
shapeFill: (node) =>
|
|
269
279
|
processColor(getFirstFillVariable(node)?.id, getFirstSolidFill(node)?.color, "SHAPE_FILL"),
|
|
270
280
|
textFill: (node) =>
|
|
@@ -312,11 +322,15 @@ export function createValueResolver<TColor, TDimension, TFontDimension, TFontWei
|
|
|
312
322
|
};
|
|
313
323
|
|
|
314
324
|
function getTextStyleValue(node: NormalizedTypePropertiesTrait & NormalizedIsLayerTrait) {
|
|
315
|
-
if (node.textStyleKey)
|
|
316
|
-
|
|
325
|
+
if (!node.textStyleKey) return undefined;
|
|
326
|
+
|
|
327
|
+
const slug = styleService.getSlug(node.textStyleKey);
|
|
328
|
+
|
|
329
|
+
if (!slug) {
|
|
330
|
+
return undefined;
|
|
317
331
|
}
|
|
318
332
|
|
|
319
|
-
return
|
|
333
|
+
return textStyleNameFormatter({ slug });
|
|
320
334
|
}
|
|
321
335
|
|
|
322
336
|
return {
|
|
@@ -21,8 +21,9 @@ import {
|
|
|
21
21
|
} from "./shape";
|
|
22
22
|
import { createTextTransformer } from "./text";
|
|
23
23
|
import {
|
|
24
|
+
defaultFillStyleResolver,
|
|
24
25
|
defaultRawValueFormatters,
|
|
25
|
-
|
|
26
|
+
defaultTextStyleNameFormatter,
|
|
26
27
|
defaultVariableNameFormatter,
|
|
27
28
|
} from "./value-resolver";
|
|
28
29
|
|
|
@@ -38,7 +39,8 @@ export function createPipeline(options: CreatePipelineConfig = {}): CodeGenerato
|
|
|
38
39
|
variableService,
|
|
39
40
|
variableNameFormatter: defaultVariableNameFormatter,
|
|
40
41
|
styleService,
|
|
41
|
-
|
|
42
|
+
textStyleNameFormatter: defaultTextStyleNameFormatter,
|
|
43
|
+
fillStyleResolver: defaultFillStyleResolver,
|
|
42
44
|
rawValueFormatters: defaultRawValueFormatters,
|
|
43
45
|
shouldInferVariableName,
|
|
44
46
|
});
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import type { ValueResolver } from "@/codegen/core";
|
|
2
2
|
import { toCssRgba } from "@/utils/css";
|
|
3
|
+
import { camelCase } from "change-case";
|
|
3
4
|
|
|
4
|
-
export type FigmaValueResolver = ValueResolver<
|
|
5
|
+
export type FigmaValueResolver = ValueResolver<
|
|
6
|
+
string,
|
|
7
|
+
{ value: string; direction?: string },
|
|
8
|
+
number,
|
|
9
|
+
number,
|
|
10
|
+
number
|
|
11
|
+
>;
|
|
5
12
|
|
|
6
13
|
export const defaultVariableNameFormatter = ({ slug }: { slug: string[] }) =>
|
|
7
14
|
slug
|
|
@@ -9,7 +16,36 @@ export const defaultVariableNameFormatter = ({ slug }: { slug: string[] }) =>
|
|
|
9
16
|
.map((s) => s.replaceAll(",", "_"))
|
|
10
17
|
.join("/");
|
|
11
18
|
|
|
12
|
-
export const
|
|
19
|
+
export const defaultTextStyleNameFormatter = ({ slug }: { slug: string[] }) =>
|
|
20
|
+
slug[slug.length - 1]!;
|
|
21
|
+
|
|
22
|
+
export const defaultFillStyleResolver = ({ slug }: { slug: string[] }) => {
|
|
23
|
+
const [, ...rest] = slug;
|
|
24
|
+
|
|
25
|
+
if (rest.includes("fade")) {
|
|
26
|
+
// ["fade", "layer-default", "↓(to-bottom)"]
|
|
27
|
+
|
|
28
|
+
const last = rest[rest.length - 1];
|
|
29
|
+
|
|
30
|
+
const direction = (() => {
|
|
31
|
+
if (last.startsWith("↓")) return "to bottom";
|
|
32
|
+
if (last.startsWith("↑")) return "to top";
|
|
33
|
+
if (last.startsWith("→")) return "to right";
|
|
34
|
+
if (last.startsWith("←")) return "to left";
|
|
35
|
+
|
|
36
|
+
return "unknown";
|
|
37
|
+
})();
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
value: camelCase(rest.slice(0, -1).join("-"), { mergeAmbiguousCharacters: true }),
|
|
41
|
+
direction,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
value: camelCase(rest.join("-"), { mergeAmbiguousCharacters: true }),
|
|
47
|
+
};
|
|
48
|
+
};
|
|
13
49
|
|
|
14
50
|
export const defaultRawValueFormatters = {
|
|
15
51
|
color: (value: RGBA) => toCssRgba(value),
|
|
@@ -3,9 +3,12 @@ import * as metadata from "@/entities/data/__generated__/component-sets";
|
|
|
3
3
|
import { camelCase } from "change-case";
|
|
4
4
|
import { match } from "ts-pattern";
|
|
5
5
|
import type { ComponentHandlerDeps } from "../deps.interface";
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
ActionButtonGhostProperties,
|
|
8
|
+
ActionButtonProperties,
|
|
9
|
+
} from "@/codegen/component-properties";
|
|
7
10
|
import { handleSizeProp } from "../size";
|
|
8
|
-
import { createLocalSnippetHelper } from "../../element-factories";
|
|
11
|
+
import { createLocalSnippetHelper, createSeedReactElement } from "../../element-factories";
|
|
9
12
|
|
|
10
13
|
const { createLocalSnippetElement } = createLocalSnippetHelper("action-button");
|
|
11
14
|
|
|
@@ -19,7 +22,7 @@ export const createActionButtonHandler = (ctx: ComponentHandlerDeps) =>
|
|
|
19
22
|
.with("Icon Only", () => ({
|
|
20
23
|
layout: "iconOnly",
|
|
21
24
|
children: [
|
|
22
|
-
|
|
25
|
+
createSeedReactElement("Icon", {
|
|
23
26
|
svg: ctx.iconHandler.transform(props["Icon#7574:0"]),
|
|
24
27
|
}),
|
|
25
28
|
],
|
|
@@ -27,7 +30,7 @@ export const createActionButtonHandler = (ctx: ComponentHandlerDeps) =>
|
|
|
27
30
|
.with("Icon First", () => ({
|
|
28
31
|
layout: "withText",
|
|
29
32
|
children: [
|
|
30
|
-
|
|
33
|
+
createSeedReactElement("PrefixIcon", {
|
|
31
34
|
svg: ctx.iconHandler.transform(props["Prefix Icon#5987:305"]),
|
|
32
35
|
}),
|
|
33
36
|
props["Label#5987:61"].value,
|
|
@@ -37,7 +40,7 @@ export const createActionButtonHandler = (ctx: ComponentHandlerDeps) =>
|
|
|
37
40
|
layout: "withText",
|
|
38
41
|
children: [
|
|
39
42
|
props["Label#5987:61"].value,
|
|
40
|
-
|
|
43
|
+
createSeedReactElement("SuffixIcon", {
|
|
41
44
|
svg: ctx.iconHandler.transform(props["Suffix Icon#5987:244"]),
|
|
42
45
|
}),
|
|
43
46
|
],
|
|
@@ -63,3 +66,64 @@ export const createActionButtonHandler = (ctx: ComponentHandlerDeps) =>
|
|
|
63
66
|
return createLocalSnippetElement("ActionButton", commonProps, children);
|
|
64
67
|
},
|
|
65
68
|
);
|
|
69
|
+
|
|
70
|
+
const ACTION_BUTTON_GHOST_BUTTON_KEY = "ea69291fb4d76217419f3d9613ae16aadafb56a5";
|
|
71
|
+
|
|
72
|
+
export const createActionButtonGhostHandler = (ctx: ComponentHandlerDeps) =>
|
|
73
|
+
defineComponentHandler<ActionButtonGhostProperties>(
|
|
74
|
+
ACTION_BUTTON_GHOST_BUTTON_KEY,
|
|
75
|
+
({ componentProperties: props }) => {
|
|
76
|
+
const states = props.State.value.split("-");
|
|
77
|
+
|
|
78
|
+
const { layout, children } = match(props.Layout.value)
|
|
79
|
+
.with("Icon Only", () => ({
|
|
80
|
+
layout: "iconOnly",
|
|
81
|
+
children: [
|
|
82
|
+
createSeedReactElement("Icon", {
|
|
83
|
+
svg: ctx.iconHandler.transform(props["Icon#30525:15"]),
|
|
84
|
+
}),
|
|
85
|
+
],
|
|
86
|
+
}))
|
|
87
|
+
.with("Icon First", () => ({
|
|
88
|
+
layout: "withText",
|
|
89
|
+
children: [
|
|
90
|
+
createSeedReactElement("PrefixIcon", {
|
|
91
|
+
svg: ctx.iconHandler.transform(props["Prefix Icon#30511:3"]),
|
|
92
|
+
}),
|
|
93
|
+
props["Label#30511:2"].value,
|
|
94
|
+
],
|
|
95
|
+
}))
|
|
96
|
+
.with("Icon Last", () => ({
|
|
97
|
+
layout: "withText",
|
|
98
|
+
children: [
|
|
99
|
+
props["Label#30511:2"].value,
|
|
100
|
+
createSeedReactElement("SuffixIcon", {
|
|
101
|
+
svg: ctx.iconHandler.transform(props["Suffix Icon#30525:0"]),
|
|
102
|
+
}),
|
|
103
|
+
],
|
|
104
|
+
}))
|
|
105
|
+
.with("Text Only", () => ({
|
|
106
|
+
layout: "withText",
|
|
107
|
+
children: props["Label#30511:2"].value,
|
|
108
|
+
}))
|
|
109
|
+
.exhaustive();
|
|
110
|
+
|
|
111
|
+
const commonProps = {
|
|
112
|
+
...(states.includes("Disabled") && {
|
|
113
|
+
disabled: true,
|
|
114
|
+
}),
|
|
115
|
+
...(states.includes("Loading") && {
|
|
116
|
+
loading: true,
|
|
117
|
+
}),
|
|
118
|
+
size: handleSizeProp(props.Size.value),
|
|
119
|
+
variant: "ghost",
|
|
120
|
+
layout,
|
|
121
|
+
...(props.Bleed.value === "true" && {
|
|
122
|
+
bleedX: "asPadding",
|
|
123
|
+
bleedY: "asPadding",
|
|
124
|
+
}),
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
return createLocalSnippetElement("ActionButton", commonProps, children);
|
|
128
|
+
},
|
|
129
|
+
);
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { defineComponentHandler } from "@/codegen/core";
|
|
2
|
+
import type {
|
|
3
|
+
AlertDialogFooterProperties,
|
|
4
|
+
AlertDialogProperties,
|
|
5
|
+
} from "@/codegen/component-properties";
|
|
6
|
+
import * as metadata from "@/entities/data/__generated__/component-sets";
|
|
7
|
+
import { createLocalSnippetHelper, createSeedReactElement } from "../../element-factories";
|
|
8
|
+
import type { ComponentHandlerDeps } from "../deps.interface";
|
|
9
|
+
import { findAllInstances } from "@/utils/figma-node";
|
|
10
|
+
import { match } from "ts-pattern";
|
|
11
|
+
|
|
12
|
+
const { createLocalSnippetElement } = createLocalSnippetHelper("alert-dialog");
|
|
13
|
+
const { createLocalSnippetElement: createLocalSnippetElementTrigger } =
|
|
14
|
+
createLocalSnippetHelper("action-button");
|
|
15
|
+
|
|
16
|
+
const ALERT_DIALOG_FOOTER_KEY = "00b1b131d67edf2875a7a1df8dfa88098d7c04be";
|
|
17
|
+
|
|
18
|
+
export const createAlertDialogHandler = (_ctx: ComponentHandlerDeps) =>
|
|
19
|
+
defineComponentHandler<AlertDialogProperties>(metadata.alertDialog.key, (node, traverse) => {
|
|
20
|
+
const props = node.componentProperties;
|
|
21
|
+
const alertDialogHeader = createLocalSnippetElement("AlertDialogHeader", undefined, [
|
|
22
|
+
...(props["Show Title#20361:14"].value
|
|
23
|
+
? [
|
|
24
|
+
createLocalSnippetElement(
|
|
25
|
+
"AlertDialogTitle",
|
|
26
|
+
undefined,
|
|
27
|
+
props["Title Text#20361:0"].value,
|
|
28
|
+
),
|
|
29
|
+
]
|
|
30
|
+
: []),
|
|
31
|
+
createLocalSnippetElement(
|
|
32
|
+
"AlertDialogDescription",
|
|
33
|
+
undefined,
|
|
34
|
+
props["Description Text#20361:7"].value,
|
|
35
|
+
),
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
const footerNodes = findAllInstances<AlertDialogFooterProperties>({
|
|
39
|
+
node,
|
|
40
|
+
key: ALERT_DIALOG_FOOTER_KEY,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
if (footerNodes.length === 0 || footerNodes.length > 1) {
|
|
44
|
+
return createLocalSnippetElement("AlertDialog", undefined, alertDialogHeader, {
|
|
45
|
+
comment: "Footer 영역을 확인해주세요.",
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const footerNode = footerNodes[0];
|
|
50
|
+
const footerNodeProps = traverse(footerNode)?.props;
|
|
51
|
+
|
|
52
|
+
const buttons = footerNode.children.map(traverse);
|
|
53
|
+
|
|
54
|
+
const alertDialogFooterChildren = match(footerNode.componentProperties.Type.value)
|
|
55
|
+
.with("Single", () => buttons)
|
|
56
|
+
.with("Neutral", "Critical", () =>
|
|
57
|
+
createSeedReactElement("ResponsivePair", footerNodeProps, buttons),
|
|
58
|
+
)
|
|
59
|
+
.with("Neutral (Overflow)", "Critical (Overflow)", "Nonpreferred", () =>
|
|
60
|
+
createSeedReactElement("VStack", footerNodeProps, buttons),
|
|
61
|
+
)
|
|
62
|
+
.exhaustive();
|
|
63
|
+
|
|
64
|
+
const alertDialogFooter = createLocalSnippetElement(
|
|
65
|
+
"AlertDialogFooter",
|
|
66
|
+
undefined,
|
|
67
|
+
alertDialogFooterChildren,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
return createLocalSnippetElement("AlertDialogRoot", { open: true }, [
|
|
71
|
+
createLocalSnippetElement(
|
|
72
|
+
"AlertDialogTrigger",
|
|
73
|
+
{ asChild: true },
|
|
74
|
+
createLocalSnippetElementTrigger("ActionButton", {}, "AlertDialog 열기"),
|
|
75
|
+
),
|
|
76
|
+
createLocalSnippetElement("AlertDialogContent", undefined, [
|
|
77
|
+
alertDialogHeader,
|
|
78
|
+
alertDialogFooter,
|
|
79
|
+
]),
|
|
80
|
+
]);
|
|
81
|
+
});
|
|
@@ -1,173 +1,138 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
AppBarLeftProperties,
|
|
3
|
-
AppBarMainProperties,
|
|
4
2
|
AppBarProperties,
|
|
5
|
-
|
|
3
|
+
AppBarMainProperties,
|
|
4
|
+
AppBarRightIconButtonProperties,
|
|
5
|
+
AppBarLeftIconButtonProperties,
|
|
6
6
|
} from "@/codegen/component-properties";
|
|
7
7
|
import { defineComponentHandler } from "@/codegen/core";
|
|
8
8
|
import * as metadata from "@/entities/data/__generated__/component-sets";
|
|
9
|
-
import
|
|
10
|
-
import { findAll, findAllInstances, findOne } from "@/utils/figma-node";
|
|
9
|
+
import { findAllInstances } from "@/utils/figma-node";
|
|
11
10
|
import { match } from "ts-pattern";
|
|
12
11
|
import { createLocalSnippetHelper } from "../../element-factories";
|
|
13
12
|
import type { ComponentHandlerDeps } from "../deps.interface";
|
|
14
13
|
|
|
15
14
|
const { createLocalSnippetElement } = createLocalSnippetHelper("app-bar");
|
|
16
15
|
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
const APP_BAR_TITLE_KEY = "d2cc4f615b2b44098be89448ad1c573f94af0355";
|
|
17
|
+
const APP_BAR_LEFT_ICON_BUTTON_KEY = "5a953f7bafc0df744777517458396e9f6c915825";
|
|
18
|
+
const APP_BAR_RIGHT_ICON_BUTTON_KEY = "c08db793288077e53bd45ef11aa419a835e88fce";
|
|
19
|
+
|
|
20
|
+
const createAppBarMainHandler = (_ctx: ComponentHandlerDeps) => {
|
|
21
|
+
return defineComponentHandler<AppBarMainProperties>(
|
|
22
|
+
APP_BAR_TITLE_KEY,
|
|
21
23
|
({ componentProperties: props }) => {
|
|
22
|
-
const { title, subtitle
|
|
24
|
+
const { title, subtitle } = match(props.Type.value)
|
|
23
25
|
.with("Title", () => ({
|
|
24
26
|
title: props["Title#16944:0"].value,
|
|
25
27
|
subtitle: undefined,
|
|
26
|
-
layout: undefined,
|
|
27
28
|
}))
|
|
28
29
|
.with("Title-Subtitle", () => ({
|
|
29
30
|
title: props["Title#16944:0"].value,
|
|
30
31
|
subtitle: props["Subtitle#16958:9"].value,
|
|
31
|
-
layout: "withSubtitle",
|
|
32
32
|
}))
|
|
33
|
-
.
|
|
33
|
+
.with("Logo (Figma Only)", () => ({
|
|
34
34
|
title: undefined,
|
|
35
35
|
subtitle: undefined,
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
}))
|
|
37
|
+
.exhaustive();
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
title,
|
|
41
|
-
|
|
42
|
-
layout,
|
|
43
|
-
};
|
|
39
|
+
if (title) {
|
|
40
|
+
return createLocalSnippetElement("AppBarMain", { title, subtitle });
|
|
41
|
+
}
|
|
44
42
|
|
|
45
|
-
return createLocalSnippetElement("AppBarMain",
|
|
46
|
-
comment:
|
|
43
|
+
return createLocalSnippetElement("AppBarMain", undefined, undefined, {
|
|
44
|
+
comment: "AppBarMain 내부를 직접 작성해주세요.",
|
|
47
45
|
});
|
|
48
46
|
},
|
|
49
47
|
);
|
|
48
|
+
};
|
|
50
49
|
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
|
|
50
|
+
export const createAppBarHandler = (ctx: ComponentHandlerDeps) => {
|
|
51
|
+
const appBarMainHandler = createAppBarMainHandler(ctx);
|
|
52
|
+
|
|
53
|
+
return defineComponentHandler<AppBarProperties>(metadata.topNavigation.key, (node, traverse) => {
|
|
54
54
|
const props = node.componentProperties;
|
|
55
55
|
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
return createLocalSnippetElement(
|
|
73
|
-
"AppBarIconButton",
|
|
74
|
-
undefined,
|
|
75
|
-
ctx.iconHandler.transform(iconNode),
|
|
76
|
-
{
|
|
77
|
-
comment: "aria-label 또는 aria-labelledby를 제공해주세요.",
|
|
78
|
-
},
|
|
79
|
-
);
|
|
80
|
-
}
|
|
56
|
+
const { theme, tone } = {
|
|
57
|
+
theme: match(props["OS (Figma Only)"].value)
|
|
58
|
+
.with("Android", () => "android")
|
|
59
|
+
.with("iOS", () => "cupertino")
|
|
60
|
+
.exhaustive(),
|
|
61
|
+
|
|
62
|
+
tone: match(props.Variant.value)
|
|
63
|
+
.with("Layer Default", () => "layer")
|
|
64
|
+
.with("Transparent", () => "transparent")
|
|
65
|
+
.exhaustive(),
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const main = (() => {
|
|
69
|
+
if (!props["Show Title#33588:82"].value) {
|
|
70
|
+
return undefined;
|
|
81
71
|
}
|
|
82
|
-
})();
|
|
83
72
|
|
|
84
|
-
|
|
85
|
-
});
|
|
73
|
+
const [mainNode] = findAllInstances<AppBarMainProperties>({ node, key: APP_BAR_TITLE_KEY });
|
|
86
74
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const props = node.componentProperties;
|
|
91
|
-
|
|
92
|
-
const children = (() => {
|
|
93
|
-
switch (props.Type.value) {
|
|
94
|
-
case "1 Text": {
|
|
95
|
-
const textNode = findOne(
|
|
96
|
-
node,
|
|
97
|
-
(child) => child.type === "TEXT",
|
|
98
|
-
) as NormalizedTextNode | null;
|
|
75
|
+
if (!mainNode) {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
99
78
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
default: {
|
|
103
|
-
const iconNodes = findAll(
|
|
104
|
-
node,
|
|
105
|
-
(child) => child.type === "INSTANCE" && child.name === "Icon",
|
|
106
|
-
) as NormalizedInstanceNode[];
|
|
79
|
+
return appBarMainHandler.transform(mainNode, traverse);
|
|
80
|
+
})();
|
|
107
81
|
|
|
108
|
-
|
|
82
|
+
const leftChildren = match(props.Left.value)
|
|
83
|
+
.with("None", () => undefined)
|
|
84
|
+
.with("Back", () => [createLocalSnippetElement("AppBarBackButton")])
|
|
85
|
+
.with("Close", () => [createLocalSnippetElement("AppBarCloseButton")])
|
|
86
|
+
.with("Custom", () => {
|
|
87
|
+
const buttons = findAllInstances<AppBarLeftIconButtonProperties>({
|
|
88
|
+
node,
|
|
89
|
+
key: APP_BAR_LEFT_ICON_BUTTON_KEY,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
if (buttons.length > 0) {
|
|
93
|
+
return buttons.map((button) =>
|
|
109
94
|
createLocalSnippetElement(
|
|
110
95
|
"AppBarIconButton",
|
|
111
96
|
undefined,
|
|
112
|
-
ctx.iconHandler.transform(
|
|
113
|
-
{
|
|
114
|
-
comment: "aria-label 또는 aria-labelledby를 제공해주세요.",
|
|
115
|
-
},
|
|
97
|
+
ctx.iconHandler.transform(button.componentProperties["Icon#33580:0"]),
|
|
98
|
+
{ comment: "AppBarIconButton에 aria-label 속성을 추가해주세요." },
|
|
116
99
|
),
|
|
117
100
|
);
|
|
118
101
|
}
|
|
119
|
-
}
|
|
120
|
-
})();
|
|
121
|
-
|
|
122
|
-
return createLocalSnippetElement("AppBarRight", undefined, children);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
export const createAppBarHandler = (ctx: ComponentHandlerDeps) => {
|
|
126
|
-
const appBarMainHandler = createAppBarMainHandler(ctx);
|
|
127
|
-
const appBarLeftHandler = createAppBarLeftHandler(ctx);
|
|
128
|
-
const appBarRightHandler = createAppBarRightHandler(ctx);
|
|
129
|
-
|
|
130
|
-
return defineComponentHandler<AppBarProperties>(metadata.standardNavigation.key, (node) => {
|
|
131
|
-
const props = node.componentProperties;
|
|
132
102
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
key: appBarRightHandler.key,
|
|
167
|
-
node,
|
|
168
|
-
});
|
|
169
|
-
const onlyRightNode = rightNode.length === 1 ? rightNode[0] : undefined;
|
|
170
|
-
const right = onlyRightNode ? appBarRightHandler.transform(onlyRightNode) : undefined;
|
|
103
|
+
return undefined;
|
|
104
|
+
})
|
|
105
|
+
.exhaustive();
|
|
106
|
+
|
|
107
|
+
const left =
|
|
108
|
+
leftChildren && leftChildren.length > 0
|
|
109
|
+
? createLocalSnippetElement("AppBarLeft", {}, leftChildren)
|
|
110
|
+
: undefined;
|
|
111
|
+
|
|
112
|
+
const rightChildren = match(props.Right.value)
|
|
113
|
+
.with("None", () => undefined)
|
|
114
|
+
.with("1 Icon Button", "2 Icon Button", "3 Icon Button", () => {
|
|
115
|
+
const buttons = findAllInstances<AppBarRightIconButtonProperties>({
|
|
116
|
+
node,
|
|
117
|
+
key: APP_BAR_RIGHT_ICON_BUTTON_KEY,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
return buttons.map((button) =>
|
|
121
|
+
createLocalSnippetElement(
|
|
122
|
+
"AppBarIconButton",
|
|
123
|
+
undefined,
|
|
124
|
+
ctx.iconHandler.transform(button.componentProperties["Icon#6406:3"]),
|
|
125
|
+
{ comment: "AppBarIconButton에 aria-label 속성을 추가해주세요." },
|
|
126
|
+
),
|
|
127
|
+
);
|
|
128
|
+
})
|
|
129
|
+
.with("Text Button", () => undefined)
|
|
130
|
+
.exhaustive();
|
|
131
|
+
|
|
132
|
+
const right =
|
|
133
|
+
rightChildren && rightChildren.length > 0
|
|
134
|
+
? createLocalSnippetElement("AppBarRight", {}, rightChildren)
|
|
135
|
+
: undefined;
|
|
171
136
|
|
|
172
137
|
return createLocalSnippetElement(
|
|
173
138
|
"AppBar",
|