Skip to content

Commit baa092c

Browse files
author
Dimitri BARBOT
committed
Add missing props to extracted components when expressions are used
1 parent b72f621 commit baa092c

File tree

7 files changed

+194
-70
lines changed

7 files changed

+194
-70
lines changed

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
10+
- Nothing yet!
11+
12+
## [0.3.2] - 2023-01-21
13+
14+
### Fixed
15+
16+
- Add missing props to extracted components when expressions are used
17+
18+
[unreleased]: https://github.com/dimitribarbot/tailwind-styled-components-extractor/compare/v0.3.2...HEAD
19+
[0.3.2]: https://github.com/dimitribarbot/tailwind-styled-components-extractor/compare/b72f621adfcd460d7f15241dea247ebaa074dbea...v0.3.2

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Styled-Components Extractor
1+
# Tailwind Styled-Components Extractor
22

33
Generate [tailwind-styled-components](https://www.npmjs.com/package/tailwind-styled-components) definitions from JSX tags.
44
This extension is based on the [existing one for styled-components](https://marketplace.visualstudio.com/items?itemName=FallenMax.styled-components-extractor).

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "tailwind-styled-components-extractor",
33
"displayName": "Tailwind Styled-Components Extractor",
4-
"version": "0.3.1",
4+
"version": "0.3.2",
55
"description": "Generate tailwind styled-components from JSX tags. A faster tailwind styled-component workflow.",
66
"license": "MIT",
77
"publisher": "dimitribarbot",

src/extension.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { getCorrespondingStyleFile } from "./lib/corresponding-file";
44
import {
55
collectUnboundComponents,
66
Component,
7-
extractUnboundComponentClassNameOffsets,
7+
getComponentsSortedByClassNameOffsets,
88
extractUnboundComponentNames,
99
generateDeclarations,
1010
getUnderlyingComponent,
@@ -17,7 +17,7 @@ import {
1717
insertTailwindStyledImport,
1818
insertStyles,
1919
modifyImports,
20-
removeClassNames,
20+
replaceComponentClassNamesWithPropAttributes,
2121
executeFormatCommand,
2222
renameTag
2323
} from "./lib/modify-vscode-editor";
@@ -85,10 +85,7 @@ const extractCurrentToSeparateFile = async (
8585
component.name,
8686
component.closingTagOffsets ? [component.closingTagOffsets] : []
8787
);
88-
await removeClassNames(
89-
editor,
90-
component.classNameOffsets ? [component.classNameOffsets] : []
91-
);
88+
await replaceComponentClassNamesWithPropAttributes(editor, [component]);
9289
await renameTag(editor, component.name, [component.openingTagOffsets]);
9390
await modifyImports(editor, styleFile, [component.name]);
9491
await executeFormatCommand();
@@ -112,10 +109,7 @@ const extractCurrentToSameFile = async (
112109
component.name,
113110
component.closingTagOffsets ? [component.closingTagOffsets] : []
114111
);
115-
await removeClassNames(
116-
editor,
117-
component.classNameOffsets ? [component.classNameOffsets] : []
118-
);
112+
await replaceComponentClassNamesWithPropAttributes(editor, [component]);
119113
await renameTag(editor, component.name, [component.openingTagOffsets]);
120114

121115
await insertStyles(editor, declarations);
@@ -171,9 +165,12 @@ const extractUnboundToSeparateFile = async (
171165
}
172166

173167
const unboundComponentNames = extractUnboundComponentNames(components);
174-
const unboundComponentClassNameOffsets =
175-
extractUnboundComponentClassNameOffsets(components);
176-
await removeClassNames(editor, unboundComponentClassNameOffsets);
168+
const componentsSortedByClassNameOffsets =
169+
getComponentsSortedByClassNameOffsets(components);
170+
await replaceComponentClassNamesWithPropAttributes(
171+
editor,
172+
componentsSortedByClassNameOffsets
173+
);
177174
await modifyImports(editor, styleFile, unboundComponentNames);
178175
await executeFormatCommand();
179176

@@ -191,9 +188,12 @@ const extractUnboundToSameFile = async (
191188
components: UnboundComponent[],
192189
declarations: string
193190
) => {
194-
const unboundComponentClassNameOffsets =
195-
extractUnboundComponentClassNameOffsets(components);
196-
await removeClassNames(editor, unboundComponentClassNameOffsets);
191+
const componentsSortedByClassNameOffsets =
192+
getComponentsSortedByClassNameOffsets(components);
193+
await replaceComponentClassNamesWithPropAttributes(
194+
editor,
195+
componentsSortedByClassNameOffsets
196+
);
197197

198198
await insertStyles(editor, declarations);
199199
await insertTailwindStyledImport(editor);

src/lib/extractor.test.ts

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {
22
collectUnboundComponents,
33
Component,
4-
extractUnboundComponentClassNameOffsets,
4+
getComponentsSortedByClassNameOffsets,
55
extractUnboundComponentNames,
66
generateDeclarations,
77
getUnderlyingComponent,
@@ -70,7 +70,7 @@ describe("collectUnboundComponents", () => {
7070
<Abc className="flex flex-col">
7171
<Def>
7272
<Efg className={c ? "justify-center" : "justify-start"} />
73-
<Ghi className={\`flex flex-col \${c(a?.e) && "flex"} \${(a && b) || c ? "justify-center" : "justify-start"}\`} />
73+
<Ghi className={\`flex flex-col \${c(a?.e) && "flex"} \${(a && b) || c ? "justify-center" : "justify-start"}\`} b={b} />
7474
<Efg className="justify-center" />
7575
<Ghi />
7676
<section />
@@ -85,33 +85,40 @@ describe("collectUnboundComponents", () => {
8585
}
8686
`;
8787

88-
expect(collectUnboundComponents(code)).toEqual([
88+
const expectedUnboundComponents: UnboundComponent[] = [
8989
{
9090
name: "Abc",
91+
propNames: [],
9192
className: "flex flex-col",
9293
classNameOffsets: { start: 141, end: 166 }
9394
},
9495
{
9596
name: "Efg",
97+
propNames: ["c"],
9698
className: '${({ c }) => c ? "justify-center" : "justify-start"}',
9799
classNameOffsets: { start: 197, end: 247 }
98100
},
99101
{
100102
name: "Ghi",
103+
propNames: ["c", "a"],
101104
className:
102-
'${({ c, a }) => c(a?.e) && "flex"} ${({ a, b, c }) => (a && b) || c ? "justify-center" : "justify-start"} flex flex-col',
105+
'${({ c, a }) => c(a?.e) && "flex"} ${({ c, a, b }) => (a && b) || c ? "justify-center" : "justify-start"} flex flex-col',
103106
classNameOffsets: { start: 266, end: 368 }
104107
},
105108
{
106109
name: "Efg",
110+
propNames: [],
107111
className: "justify-center",
108-
classNameOffsets: { start: 387, end: 413 }
112+
classNameOffsets: { start: 393, end: 419 }
109113
},
110114
{
111115
name: "Ghi",
116+
propNames: [],
112117
className: ""
113118
}
114-
]);
119+
];
120+
121+
expect(collectUnboundComponents(code)).toEqual(expectedUnboundComponents);
115122
});
116123

117124
it("should return collected unbound components in case of syntax error", async () => {
@@ -152,11 +159,13 @@ describe("generateDeclarations", () => {
152159
const unboundComponents: UnboundComponent[] = [
153160
{
154161
name: "Abc",
162+
propNames: [],
155163
className: "flex flex-col",
156164
classNameOffsets: { start: 124, end: 149 }
157165
},
158166
{
159167
name: "Xyz",
168+
propNames: ["c"],
160169
className: '${({ c }) => c ? "justify-center" : "justify-start"}',
161170
classNameOffsets: { start: 176, end: 226 }
162171
}
@@ -176,11 +185,13 @@ describe("generateDeclarations", () => {
176185
const unboundComponents: UnboundComponent[] = [
177186
{
178187
name: "Abc",
188+
propNames: [],
179189
className: "flex flex-col",
180190
classNameOffsets: { start: 124, end: 149 }
181191
},
182192
{
183193
name: "Xyz",
194+
propNames: ["c"],
184195
className: '${({ c }) => c ? "justify-center" : "justify-start"}',
185196
classNameOffsets: { start: 176, end: 226 }
186197
}
@@ -200,6 +211,7 @@ describe("generateDeclarations", () => {
200211
const components: Component[] = [
201212
{
202213
name: "Abc",
214+
propNames: [],
203215
type: "span",
204216
className: "flex flex-col",
205217
classNameOffsets: {
@@ -218,6 +230,7 @@ describe("generateDeclarations", () => {
218230
},
219231
{
220232
name: "Xyz",
233+
propNames: ["c"],
221234
type: "Efg",
222235
className: '${({ c }) => c ? "justify-center" : "justify-start"}',
223236
classNameOffsets: {
@@ -247,6 +260,7 @@ describe("generateDeclarations", () => {
247260
const components: Component[] = [
248261
{
249262
name: "Abc",
263+
propNames: [],
250264
type: "span",
251265
className: "flex flex-col",
252266
classNameOffsets: {
@@ -265,6 +279,7 @@ describe("generateDeclarations", () => {
265279
},
266280
{
267281
name: "Xyz",
282+
propNames: ["c"],
268283
type: "Efg",
269284
className: '${({ c }) => c ? "justify-center" : "justify-start"}',
270285
classNameOffsets: {
@@ -296,11 +311,13 @@ describe("extractUnboundComponentNames", () => {
296311
const unboundComponentNames = extractUnboundComponentNames([
297312
{
298313
name: "Abc",
314+
propNames: [],
299315
className: "flex flex-col",
300316
classNameOffsets: { start: 124, end: 149 }
301317
},
302318
{
303319
name: "Xyz",
320+
propNames: ["c"],
304321
className: '${({ c }) => c ? "justify-center" : "justify-start"}',
305322
classNameOffsets: { start: 176, end: 226 }
306323
}
@@ -309,24 +326,36 @@ describe("extractUnboundComponentNames", () => {
309326
});
310327
});
311328

312-
describe("extractUnboundComponentClassNameOffsets", () => {
329+
describe("getComponentsSortedByClassNameOffsets", () => {
313330
it("should return class name offsets", async () => {
314-
const unboundComponentClassNameOffsets =
315-
extractUnboundComponentClassNameOffsets([
331+
const componentsSortedByClassNameOffsets =
332+
getComponentsSortedByClassNameOffsets([
316333
{
317334
name: "Abc",
335+
propNames: [],
318336
className: "flex flex-col",
319337
classNameOffsets: { start: 124, end: 149 }
320338
},
321339
{
322340
name: "Xyz",
341+
propNames: ["c"],
323342
className: '${({ c }) => c ? "justify-center" : "justify-start"}',
324343
classNameOffsets: { start: 176, end: 226 }
325344
}
326345
]);
327-
expect(unboundComponentClassNameOffsets).toEqual([
328-
{ start: 176, end: 226 },
329-
{ start: 124, end: 149 }
346+
expect(componentsSortedByClassNameOffsets).toEqual([
347+
{
348+
name: "Xyz",
349+
propNames: ["c"],
350+
className: '${({ c }) => c ? "justify-center" : "justify-start"}',
351+
classNameOffsets: { start: 176, end: 226 }
352+
},
353+
{
354+
name: "Abc",
355+
propNames: [],
356+
className: "flex flex-col",
357+
classNameOffsets: { start: 124, end: 149 }
358+
}
330359
]);
331360
});
332361
});
@@ -358,8 +387,9 @@ const TestComponent: React.FC = ({ a }) => {
358387
`;
359388

360389
it("should return underlying component without self closing tag", () => {
361-
expect(getUnderlyingComponent(code, 140)).toEqual({
390+
const expectedComponent: Component = {
362391
name: "",
392+
propNames: [],
363393
type: "Abc",
364394
className: "flex flex-col",
365395
classNameOffsets: {
@@ -375,12 +405,15 @@ const TestComponent: React.FC = ({ a }) => {
375405
start: 527,
376406
end: 530
377407
}
378-
});
408+
};
409+
410+
expect(getUnderlyingComponent(code, 140)).toEqual(expectedComponent);
379411
});
380412

381413
it("should return underlying component with self closing tag", () => {
382-
expect(getUnderlyingComponent(code, 380)).toEqual({
414+
const expectedComponent: Component = {
383415
name: "",
416+
propNames: [],
384417
type: "Efg",
385418
className: "justify-center",
386419
classNameOffsets: {
@@ -393,7 +426,9 @@ const TestComponent: React.FC = ({ a }) => {
393426
},
394427
selfClosing: true,
395428
closingTagOffsets: undefined
396-
});
429+
};
430+
431+
expect(getUnderlyingComponent(code, 380)).toEqual(expectedComponent);
397432
});
398433
});
399434

0 commit comments

Comments
 (0)