@interactivethings/scripts 0.0.9 → 2.0.0
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/README.md +210 -12
- package/codemods/__testfixtures__/sx-to-use-styles.input.js +50 -0
- package/codemods/__testfixtures__/sx-to-use-styles.output.js +59 -0
- package/codemods/__tests__/defineTest.ts +9 -0
- package/codemods/__tests__/sx-to-use-styles.test.js +3 -0
- package/codemods/sx-to-use-styles.js +162 -0
- package/dist/__tests__/figma-cli.test.js +189 -0
- package/dist/__tests__/tokens-studio-cli.test.js +197 -0
- package/dist/__tests__/vercel-cli.test.js +86 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +94 -0
- package/dist/config.d.ts +78 -0
- package/dist/config.js +157 -0
- package/dist/figma/api.d.ts +71 -0
- package/dist/figma/api.js +175 -0
- package/dist/figma/cli.d.ts +20 -0
- package/dist/figma/cli.js +153 -0
- package/dist/figma/cli.test.js +187 -0
- package/dist/figma/images.js +53 -0
- package/dist/figma/optimizeImage.js +53 -0
- package/dist/figma/utils.d.ts +10 -0
- package/dist/figma/utils.js +26 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +43 -0
- package/dist/init/cli.d.ts +3 -0
- package/dist/init/cli.js +312 -0
- package/dist/mui-tokens-studio.js +0 -0
- package/dist/plugins/figma/index.js +653 -0
- package/dist/plugins/tokens-studio/utils.js +155 -0
- package/dist/tokens-studio/__tests__/fixtures/invalid-transformer.js +12 -0
- package/dist/tokens-studio/__tests__/fixtures/test-transformer.js +18 -0
- package/dist/tokens-studio/cli.d.ts +8 -0
- package/dist/tokens-studio/cli.js +119 -0
- package/dist/tokens-studio/cli.test.js +150 -0
- package/dist/tokens-studio/index.d.ts +14 -0
- package/dist/tokens-studio/index.js +46 -0
- package/dist/tokens-studio/mui.js +212 -0
- package/dist/tokens-studio/require.js +17 -0
- package/dist/tokens-studio/tailwind.js +211 -0
- package/dist/tokens-studio/types.js +2 -0
- package/dist/tokens-studio/utils.d.ts +49 -0
- package/dist/tokens-studio/utils.js +156 -0
- package/dist/types.d.ts +1 -0
- package/dist/vercel/cli.d.ts +4 -0
- package/dist/vercel/cli.js +70 -0
- package/dist/vercel/cli.test.js +86 -0
- package/dist/vercel/deployments.js +42 -0
- package/dist/vercel/waitForDeploymentReady.js +43 -0
- package/package.json +46 -6
package/README.md
CHANGED
|
@@ -1,28 +1,226 @@
|
|
|
1
1
|
# ixt-scripts
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A collection of useful development tools by Interactive Things for managing design tokens, Figma assets, and deployment workflows.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
yarn add @interactivethings/scripts
|
|
9
|
+
# or
|
|
10
|
+
npm install @interactivethings/scripts
|
|
10
11
|
```
|
|
11
12
|
|
|
12
|
-
##
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
1. Create a TypeScript configuration file in your project root:
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// ixt.config.ts
|
|
19
|
+
import { defineConfig } from "@interactivethings/scripts";
|
|
20
|
+
|
|
21
|
+
export default defineConfig({
|
|
22
|
+
figma: {
|
|
23
|
+
assets: [
|
|
24
|
+
{
|
|
25
|
+
name: "icons",
|
|
26
|
+
url: "https://www.figma.com/design/YOUR_FILE_ID/Design-System?node-id=123-456",
|
|
27
|
+
output: "src/assets/icons",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "illustrations",
|
|
31
|
+
url: "https://www.figma.com/design/YOUR_FILE_ID/Design-System?node-id=789-012",
|
|
32
|
+
output: "src/assets/illustrations",
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
tokensStudio: {
|
|
37
|
+
input: "./tokens",
|
|
38
|
+
output: "src/theme/tokens.json",
|
|
39
|
+
handler: "./transforms/mui-transform.ts",
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
2. Create a `.env.local` file with your API tokens:
|
|
13
45
|
|
|
14
46
|
```bash
|
|
15
|
-
|
|
47
|
+
FIGMA_TOKEN=fig_***
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
ℹ️ Environment variables are loaded using @next/env the same way as Next.js.
|
|
51
|
+
|
|
52
|
+
3. Use the CLI commands:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Download Figma assets
|
|
56
|
+
ixt figma download
|
|
57
|
+
|
|
58
|
+
# Transform design tokens
|
|
59
|
+
ixt tokens-studio transform
|
|
16
60
|
```
|
|
17
61
|
|
|
18
|
-
##
|
|
62
|
+
## Configuration
|
|
19
63
|
|
|
20
|
-
|
|
21
|
-
a Typescript runtime.
|
|
64
|
+
ixt-scripts uses a unified configuration system with a single `ixt.config.ts` file that provides full TypeScript support and type safety.
|
|
22
65
|
|
|
23
|
-
###
|
|
66
|
+
### Supported Config Files
|
|
67
|
+
|
|
68
|
+
- `ixt.config.ts` (TypeScript configuration with full type safety)
|
|
69
|
+
|
|
70
|
+
For detailed configuration options and schema reference, see [CONFIG.md](./CONFIG.md).
|
|
71
|
+
|
|
72
|
+
## Creating Custom Transformers
|
|
73
|
+
|
|
74
|
+
You can create custom transformers for the tokens-studio command:
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// transforms/my-transform.ts
|
|
78
|
+
export function transform(input: { metadata: any; tokenData: any }) {
|
|
79
|
+
// Transform the tokens to your desired format
|
|
80
|
+
return {
|
|
81
|
+
colors: transformColors(input.tokenData.colors),
|
|
82
|
+
typography: transformTypography(input.tokenData.typography),
|
|
83
|
+
// ... other transformations
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Then reference it in your config:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
export default defineConfig({
|
|
92
|
+
tokensStudio: {
|
|
93
|
+
handler: "./transforms/my-transform.ts",
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Available Commands
|
|
99
|
+
|
|
100
|
+
### Figma Commands
|
|
101
|
+
|
|
102
|
+
Download assets from Figma:
|
|
24
103
|
|
|
25
104
|
```bash
|
|
26
|
-
#
|
|
27
|
-
|
|
105
|
+
# Download all configured assets
|
|
106
|
+
ixt figma download
|
|
107
|
+
|
|
108
|
+
# Download specific asset collection
|
|
109
|
+
ixt figma download icons
|
|
110
|
+
|
|
111
|
+
# Get node information
|
|
112
|
+
ixt figma get "https://www.figma.com/design/..."
|
|
28
113
|
```
|
|
114
|
+
|
|
115
|
+
**Features:**
|
|
116
|
+
|
|
117
|
+
- Download SVG icons and optimize them
|
|
118
|
+
- Download assets exported from Figma
|
|
119
|
+
- Automatic asset optimization
|
|
120
|
+
|
|
121
|
+
⚠️ Assets must be exported in Figma to be visible to the tool.
|
|
122
|
+
|
|
123
|
+
### Tokens Studio Commands
|
|
124
|
+
|
|
125
|
+
Transform design tokens exported from Tokens Studio:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Transform using config file settings
|
|
129
|
+
ixt tokens-studio transform
|
|
130
|
+
|
|
131
|
+
# Override config settings
|
|
132
|
+
ixt tokens-studio transform --handler ./custom-transform.ts --output theme.json
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Concept:**
|
|
136
|
+
UI frameworks like MUI and Tailwind require variables in specific formats, while designers work with Figma Tokens. The `tokens-studio` tool bridges this gap by transforming design tokens into framework-compatible variables.
|
|
137
|
+
|
|
138
|
+
**Workflow:**
|
|
139
|
+
|
|
140
|
+
1. Designers create tokens in Figma
|
|
141
|
+
2. Designers export tokens using Tokens Studio plugin
|
|
142
|
+
3. Developers store token files in the code repository
|
|
143
|
+
4. Developers run `ixt tokens-studio transform` to convert tokens for their framework
|
|
144
|
+
|
|
145
|
+
### Vercel Commands
|
|
146
|
+
|
|
147
|
+
Utilities for Vercel deployments:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
# Wait for deployment to complete
|
|
151
|
+
ixt vercel wait-deployment COMMIT_SHA --team TEAM_ID --project PROJECT_ID
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Framework Integration Examples
|
|
155
|
+
|
|
156
|
+
After transforming your design tokens, you can use them directly in your framework configuration:
|
|
157
|
+
|
|
158
|
+
### Tailwind CSS v3
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
// tailwind.config.ts
|
|
162
|
+
import theme from "src/theme/tokens.json";
|
|
163
|
+
|
|
164
|
+
export default {
|
|
165
|
+
darkMode: ["class"],
|
|
166
|
+
content: [
|
|
167
|
+
"./src/**/*.{js,ts,jsx,tsx,mdx}",
|
|
168
|
+
process.env.TAILWIND_STORIES === "false"
|
|
169
|
+
? "!./src/**/*.stories.{js,ts,jsx,tsx,mdx}"
|
|
170
|
+
: undefined,
|
|
171
|
+
].filter(Boolean),
|
|
172
|
+
theme: {
|
|
173
|
+
extend: {
|
|
174
|
+
colors: {
|
|
175
|
+
...theme.colors,
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Material-UI (MUI)
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
// theme.tsx
|
|
186
|
+
import { createTheme } from "@mui/material/styles";
|
|
187
|
+
import tokens from "src/theme/tokens.json";
|
|
188
|
+
|
|
189
|
+
export const theme = createTheme({
|
|
190
|
+
typography: {
|
|
191
|
+
fontFamily: `${tokens.typography.body1.desktop.fontFamily}, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif`,
|
|
192
|
+
h1: omit(tokens.typography.h1.desktop, ["fontFamily"]),
|
|
193
|
+
h2: omit(tokens.typography.h2.desktop, ["fontFamily"]),
|
|
194
|
+
h3: omit(tokens.typography.h3.desktop, ["fontFamily"]),
|
|
195
|
+
body1: omit(tokens.typography.body1.desktop, ["fontFamily"]),
|
|
196
|
+
body2: omit(tokens.typography.body2.desktop, ["fontFamily"]),
|
|
197
|
+
},
|
|
198
|
+
palette: {
|
|
199
|
+
primary: {
|
|
200
|
+
main: tokens.palette.primary.main,
|
|
201
|
+
light: tokens.palette.primary.light,
|
|
202
|
+
dark: tokens.palette.primary.dark,
|
|
203
|
+
},
|
|
204
|
+
secondary: {
|
|
205
|
+
main: tokens.palette.secondary.main,
|
|
206
|
+
},
|
|
207
|
+
error: {
|
|
208
|
+
main: tokens.palette.functional.error,
|
|
209
|
+
},
|
|
210
|
+
warning: {
|
|
211
|
+
main: tokens.palette.functional.warning,
|
|
212
|
+
},
|
|
213
|
+
success: {
|
|
214
|
+
main: tokens.palette.functional.success,
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Publishing
|
|
221
|
+
|
|
222
|
+
Publishing is done automatically through semantic-release via a GitHub action job, from the branch main. Commit prefixes will trigger different types of versions and we use the default commit analyser.
|
|
223
|
+
|
|
224
|
+
- 'fix:' commits will trigger a patch version
|
|
225
|
+
- 'feat:' commits will trigger a minor version
|
|
226
|
+
- 'BREAKING CHANGE:' in the body of a commit will trigger a major version
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Button, Typography, Paper } from "@mui/material";
|
|
3
|
+
|
|
4
|
+
// Component using MUI and sx props
|
|
5
|
+
const ExampleComponent = () => {
|
|
6
|
+
return (
|
|
7
|
+
<Paper
|
|
8
|
+
sx={{
|
|
9
|
+
py: 2,
|
|
10
|
+
display: "flex",
|
|
11
|
+
flexDirection: "column",
|
|
12
|
+
alignItems: "center",
|
|
13
|
+
justifyContent: "center",
|
|
14
|
+
minHeight: "200px",
|
|
15
|
+
bgcolor: "#f0f0f0",
|
|
16
|
+
}}
|
|
17
|
+
>
|
|
18
|
+
<Typography variant="h4" sx={{ marginBottom: 2 }}>
|
|
19
|
+
Welcome to MUI with sx props!
|
|
20
|
+
</Typography>
|
|
21
|
+
{[1, 2, 3].map((_x) => {
|
|
22
|
+
return (
|
|
23
|
+
<Box
|
|
24
|
+
sx={{
|
|
25
|
+
mx: 3,
|
|
26
|
+
display: "flex",
|
|
27
|
+
flexDirection: "column",
|
|
28
|
+
alignItems: "center",
|
|
29
|
+
justifyContent: "center",
|
|
30
|
+
minHeight: "200px",
|
|
31
|
+
backgroundColor: "#f0f0f0",
|
|
32
|
+
}}
|
|
33
|
+
>
|
|
34
|
+
List item {i}
|
|
35
|
+
</Box>
|
|
36
|
+
);
|
|
37
|
+
})}
|
|
38
|
+
<Button
|
|
39
|
+
variant="contained"
|
|
40
|
+
color="primary"
|
|
41
|
+
sx={{ marginTop: 2 }}
|
|
42
|
+
onClick={() => alert("Button clicked!")}
|
|
43
|
+
>
|
|
44
|
+
Click me
|
|
45
|
+
</Button>
|
|
46
|
+
</Paper>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default ExampleComponent;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { Button, Typography, Paper } from "@mui/material";
|
|
4
|
+
|
|
5
|
+
const useStyles = makeStyles()(_theme => ({
|
|
6
|
+
root0: {
|
|
7
|
+
paddingTop: 2,
|
|
8
|
+
paddingBottom: 2,
|
|
9
|
+
display: "flex",
|
|
10
|
+
flexDirection: "column",
|
|
11
|
+
alignItems: "center",
|
|
12
|
+
justifyContent: "center",
|
|
13
|
+
minHeight: "200px",
|
|
14
|
+
backgroundColor: "#f0f0f0"
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
root1: {
|
|
18
|
+
marginLeft: 3,
|
|
19
|
+
marginRight: 3,
|
|
20
|
+
display: "flex",
|
|
21
|
+
flexDirection: "column",
|
|
22
|
+
alignItems: "center",
|
|
23
|
+
justifyContent: "center",
|
|
24
|
+
minHeight: "200px",
|
|
25
|
+
backgroundColor: "#f0f0f0"
|
|
26
|
+
}
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
// Component using MUI and sx props
|
|
30
|
+
const ExampleComponent = () => {
|
|
31
|
+
const { classes } = useStyles()
|
|
32
|
+
return (
|
|
33
|
+
(<Paper
|
|
34
|
+
className={classes.root0}
|
|
35
|
+
>
|
|
36
|
+
<Typography variant="h4" sx={{ marginBottom: 2 }}>
|
|
37
|
+
Welcome to MUI with sx props!
|
|
38
|
+
</Typography>
|
|
39
|
+
{[1, 2, 3].map((_x) => {
|
|
40
|
+
return (
|
|
41
|
+
(<Box
|
|
42
|
+
className={classes.root1}
|
|
43
|
+
>List item{i}
|
|
44
|
+
</Box>)
|
|
45
|
+
);
|
|
46
|
+
})}
|
|
47
|
+
<Button
|
|
48
|
+
variant="contained"
|
|
49
|
+
color="primary"
|
|
50
|
+
sx={{ marginTop: 2 }}
|
|
51
|
+
onClick={() => alert("Button clicked!")}
|
|
52
|
+
>
|
|
53
|
+
Click me
|
|
54
|
+
</Button>
|
|
55
|
+
</Paper>)
|
|
56
|
+
);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default ExampleComponent;
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
function findHighestFunctionBlock(path) {
|
|
2
|
+
let current = path;
|
|
3
|
+
let highest = null;
|
|
4
|
+
|
|
5
|
+
while (current && current.node && current.parentPath?.node) {
|
|
6
|
+
const grandParentNode = current.parentPath.node;
|
|
7
|
+
const grandParentType = grandParentNode.type;
|
|
8
|
+
const currentType = current.node.type;
|
|
9
|
+
|
|
10
|
+
if (
|
|
11
|
+
currentType === "BlockStatement" &&
|
|
12
|
+
(grandParentType === "ArrowFunctionExpression" ||
|
|
13
|
+
grandParentType === "FunctionDeclaration" ||
|
|
14
|
+
grandParentType === "ArrowFunctionExpression")
|
|
15
|
+
) {
|
|
16
|
+
highest = current;
|
|
17
|
+
}
|
|
18
|
+
current = current.parentPath;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return highest;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** sx in MUI supports extra properties */
|
|
25
|
+
const propertyMapping = {
|
|
26
|
+
m: "margin",
|
|
27
|
+
p: "padding",
|
|
28
|
+
pt: "paddingTop",
|
|
29
|
+
pb: "paddingBottom",
|
|
30
|
+
pl: "paddingLeft",
|
|
31
|
+
pr: "paddingRight",
|
|
32
|
+
ml: "marginLeft",
|
|
33
|
+
mr: "marginRight",
|
|
34
|
+
mt: "marginTop",
|
|
35
|
+
mb: "marginBottom",
|
|
36
|
+
px: ["paddingLeft", "paddingRight"],
|
|
37
|
+
mx: ["marginLeft", "marginRight"],
|
|
38
|
+
py: ["paddingTop", "paddingBottom"],
|
|
39
|
+
my: ["marginTop", "marginBottom"],
|
|
40
|
+
bgcolor: "backgroundColor",
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
function transform(fileInfo, api) {
|
|
44
|
+
/**
|
|
45
|
+
* @type {import("jscodeshift").JSCodeshift}
|
|
46
|
+
*/
|
|
47
|
+
const j = api.jscodeshift;
|
|
48
|
+
const root = j(fileInfo.source);
|
|
49
|
+
|
|
50
|
+
let i = 0;
|
|
51
|
+
|
|
52
|
+
const makeStyleOptions = j.objectExpression([]);
|
|
53
|
+
const makeStyleFunction = j.arrowFunctionExpression(
|
|
54
|
+
[j.identifier("_theme")],
|
|
55
|
+
makeStyleOptions
|
|
56
|
+
);
|
|
57
|
+
const useStylesDeclaration = j.expressionStatement(
|
|
58
|
+
j.assignmentExpression(
|
|
59
|
+
"=",
|
|
60
|
+
j.identifier(`const useStyles`),
|
|
61
|
+
j.callExpression(j.identifier("makeStyles()"), [makeStyleFunction])
|
|
62
|
+
)
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const alreadyAddedUseStyles = new Set();
|
|
66
|
+
// Step 1: Find every React element with an sx property
|
|
67
|
+
root
|
|
68
|
+
.find(j.JSXElement)
|
|
69
|
+
.find(j.JSXAttribute, {
|
|
70
|
+
name: {
|
|
71
|
+
type: "JSXIdentifier",
|
|
72
|
+
name: "sx",
|
|
73
|
+
},
|
|
74
|
+
})
|
|
75
|
+
.forEach((path) => {
|
|
76
|
+
// Step 2: Extract content of the sx property into a useStyles hook
|
|
77
|
+
const jsxElement = path.parentPath.parentPath; // JSXElement
|
|
78
|
+
const jsxAttributes = jsxElement.node.attributes;
|
|
79
|
+
const sxAttributeIndex = jsxAttributes.findIndex(
|
|
80
|
+
(attr) => attr.name && attr.name.name === "sx"
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
if (sxAttributeIndex >= 0) {
|
|
84
|
+
const sxAttribute = jsxAttributes[sxAttributeIndex];
|
|
85
|
+
const sxValue = sxAttribute.value;
|
|
86
|
+
|
|
87
|
+
if (
|
|
88
|
+
sxValue.expression.properties &&
|
|
89
|
+
sxValue.expression.properties.length < 4
|
|
90
|
+
) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Add the useStyles hook above the function
|
|
95
|
+
let parentFunction = findHighestFunctionBlock(jsxElement);
|
|
96
|
+
|
|
97
|
+
if (!parentFunction) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Step 4: Create the useStylesDeclaration with makeStyles
|
|
102
|
+
makeStyleOptions.properties.push(
|
|
103
|
+
j.property("init", j.identifier(`root${i}`), sxValue.expression)
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
// Traverse through the object expression properties
|
|
107
|
+
if (sxValue.expression.type === "ObjectExpression") {
|
|
108
|
+
sxValue.expression.properties = sxValue.expression.properties
|
|
109
|
+
.flatMap((property) => {
|
|
110
|
+
if (
|
|
111
|
+
property.type !== "Property" ||
|
|
112
|
+
property.key.type !== "Identifier"
|
|
113
|
+
) {
|
|
114
|
+
return property;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const propertyName = property.key.name;
|
|
118
|
+
const mappedPropertyName = propertyMapping[propertyName];
|
|
119
|
+
|
|
120
|
+
if (!mappedPropertyName) {
|
|
121
|
+
return property;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (Array.isArray(mappedPropertyName)) {
|
|
125
|
+
return mappedPropertyName.map((name) => ({
|
|
126
|
+
...property,
|
|
127
|
+
key: name,
|
|
128
|
+
}));
|
|
129
|
+
} else {
|
|
130
|
+
// Replace the property key with the mapped key
|
|
131
|
+
property.key = j.identifier(mappedPropertyName);
|
|
132
|
+
return property;
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
.filter((x) => !!x);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (!alreadyAddedUseStyles.has(parentFunction)) {
|
|
139
|
+
parentFunction.node.body.unshift(`const { classes } = useStyles()`);
|
|
140
|
+
alreadyAddedUseStyles.add(parentFunction);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Remove the sx attribute
|
|
144
|
+
jsxAttributes.splice(sxAttributeIndex, 1);
|
|
145
|
+
jsxAttributes.push(
|
|
146
|
+
j.jsxAttribute(
|
|
147
|
+
j.jsxIdentifier("className"),
|
|
148
|
+
j.jsxExpressionContainer(j.identifier(`classes.root${i}`))
|
|
149
|
+
)
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
i++;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Step 5: Insert the useStylesDeclaration at module level
|
|
157
|
+
const lastImport = root.find(j.ImportDeclaration).at(-1);
|
|
158
|
+
lastImport.insertAfter(useStylesDeclaration);
|
|
159
|
+
return root.toSource();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
module.exports = transform;
|