Skip to content

Commit

Permalink
Add missing props to extracted components when expressions are used
Browse files Browse the repository at this point in the history
  • Loading branch information
Dimitri BARBOT committed Jan 20, 2023
1 parent b72f621 commit baa092c
Show file tree
Hide file tree
Showing 7 changed files with 194 additions and 70 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

- Nothing yet!

## [0.3.2] - 2023-01-21

### Fixed

- Add missing props to extracted components when expressions are used

[unreleased]: https://github.com/dimitribarbot/tailwind-styled-components-extractor/compare/v0.3.2...HEAD
[0.3.2]: https://github.com/dimitribarbot/tailwind-styled-components-extractor/compare/b72f621adfcd460d7f15241dea247ebaa074dbea...v0.3.2
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Styled-Components Extractor
# Tailwind Styled-Components Extractor

Generate [tailwind-styled-components](https://www.npmjs.com/package/tailwind-styled-components) definitions from JSX tags.
This extension is based on the [existing one for styled-components](https://marketplace.visualstudio.com/items?itemName=FallenMax.styled-components-extractor).
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "tailwind-styled-components-extractor",
"displayName": "Tailwind Styled-Components Extractor",
"version": "0.3.1",
"version": "0.3.2",
"description": "Generate tailwind styled-components from JSX tags. A faster tailwind styled-component workflow.",
"license": "MIT",
"publisher": "dimitribarbot",
Expand Down
32 changes: 16 additions & 16 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getCorrespondingStyleFile } from "./lib/corresponding-file";
import {
collectUnboundComponents,
Component,
extractUnboundComponentClassNameOffsets,
getComponentsSortedByClassNameOffsets,
extractUnboundComponentNames,
generateDeclarations,
getUnderlyingComponent,
Expand All @@ -17,7 +17,7 @@ import {
insertTailwindStyledImport,
insertStyles,
modifyImports,
removeClassNames,
replaceComponentClassNamesWithPropAttributes,
executeFormatCommand,
renameTag
} from "./lib/modify-vscode-editor";
Expand Down Expand Up @@ -85,10 +85,7 @@ const extractCurrentToSeparateFile = async (
component.name,
component.closingTagOffsets ? [component.closingTagOffsets] : []
);
await removeClassNames(
editor,
component.classNameOffsets ? [component.classNameOffsets] : []
);
await replaceComponentClassNamesWithPropAttributes(editor, [component]);
await renameTag(editor, component.name, [component.openingTagOffsets]);
await modifyImports(editor, styleFile, [component.name]);
await executeFormatCommand();
Expand All @@ -112,10 +109,7 @@ const extractCurrentToSameFile = async (
component.name,
component.closingTagOffsets ? [component.closingTagOffsets] : []
);
await removeClassNames(
editor,
component.classNameOffsets ? [component.classNameOffsets] : []
);
await replaceComponentClassNamesWithPropAttributes(editor, [component]);
await renameTag(editor, component.name, [component.openingTagOffsets]);

await insertStyles(editor, declarations);
Expand Down Expand Up @@ -171,9 +165,12 @@ const extractUnboundToSeparateFile = async (
}

const unboundComponentNames = extractUnboundComponentNames(components);
const unboundComponentClassNameOffsets =
extractUnboundComponentClassNameOffsets(components);
await removeClassNames(editor, unboundComponentClassNameOffsets);
const componentsSortedByClassNameOffsets =
getComponentsSortedByClassNameOffsets(components);
await replaceComponentClassNamesWithPropAttributes(
editor,
componentsSortedByClassNameOffsets
);
await modifyImports(editor, styleFile, unboundComponentNames);
await executeFormatCommand();

Expand All @@ -191,9 +188,12 @@ const extractUnboundToSameFile = async (
components: UnboundComponent[],
declarations: string
) => {
const unboundComponentClassNameOffsets =
extractUnboundComponentClassNameOffsets(components);
await removeClassNames(editor, unboundComponentClassNameOffsets);
const componentsSortedByClassNameOffsets =
getComponentsSortedByClassNameOffsets(components);
await replaceComponentClassNamesWithPropAttributes(
editor,
componentsSortedByClassNameOffsets
);

await insertStyles(editor, declarations);
await insertTailwindStyledImport(editor);
Expand Down
67 changes: 51 additions & 16 deletions src/lib/extractor.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
collectUnboundComponents,
Component,
extractUnboundComponentClassNameOffsets,
getComponentsSortedByClassNameOffsets,
extractUnboundComponentNames,
generateDeclarations,
getUnderlyingComponent,
Expand Down Expand Up @@ -70,7 +70,7 @@ describe("collectUnboundComponents", () => {
<Abc className="flex flex-col">
<Def>
<Efg className={c ? "justify-center" : "justify-start"} />
<Ghi className={\`flex flex-col \${c(a?.e) && "flex"} \${(a && b) || c ? "justify-center" : "justify-start"}\`} />
<Ghi className={\`flex flex-col \${c(a?.e) && "flex"} \${(a && b) || c ? "justify-center" : "justify-start"}\`} b={b} />
<Efg className="justify-center" />
<Ghi />
<section />
Expand All @@ -85,33 +85,40 @@ describe("collectUnboundComponents", () => {
}
`;

expect(collectUnboundComponents(code)).toEqual([
const expectedUnboundComponents: UnboundComponent[] = [
{
name: "Abc",
propNames: [],
className: "flex flex-col",
classNameOffsets: { start: 141, end: 166 }
},
{
name: "Efg",
propNames: ["c"],
className: '${({ c }) => c ? "justify-center" : "justify-start"}',
classNameOffsets: { start: 197, end: 247 }
},
{
name: "Ghi",
propNames: ["c", "a"],
className:
'${({ c, a }) => c(a?.e) && "flex"} ${({ a, b, c }) => (a && b) || c ? "justify-center" : "justify-start"} flex flex-col',
'${({ c, a }) => c(a?.e) && "flex"} ${({ c, a, b }) => (a && b) || c ? "justify-center" : "justify-start"} flex flex-col',
classNameOffsets: { start: 266, end: 368 }
},
{
name: "Efg",
propNames: [],
className: "justify-center",
classNameOffsets: { start: 387, end: 413 }
classNameOffsets: { start: 393, end: 419 }
},
{
name: "Ghi",
propNames: [],
className: ""
}
]);
];

expect(collectUnboundComponents(code)).toEqual(expectedUnboundComponents);
});

it("should return collected unbound components in case of syntax error", async () => {
Expand Down Expand Up @@ -152,11 +159,13 @@ describe("generateDeclarations", () => {
const unboundComponents: UnboundComponent[] = [
{
name: "Abc",
propNames: [],
className: "flex flex-col",
classNameOffsets: { start: 124, end: 149 }
},
{
name: "Xyz",
propNames: ["c"],
className: '${({ c }) => c ? "justify-center" : "justify-start"}',
classNameOffsets: { start: 176, end: 226 }
}
Expand All @@ -176,11 +185,13 @@ describe("generateDeclarations", () => {
const unboundComponents: UnboundComponent[] = [
{
name: "Abc",
propNames: [],
className: "flex flex-col",
classNameOffsets: { start: 124, end: 149 }
},
{
name: "Xyz",
propNames: ["c"],
className: '${({ c }) => c ? "justify-center" : "justify-start"}',
classNameOffsets: { start: 176, end: 226 }
}
Expand All @@ -200,6 +211,7 @@ describe("generateDeclarations", () => {
const components: Component[] = [
{
name: "Abc",
propNames: [],
type: "span",
className: "flex flex-col",
classNameOffsets: {
Expand All @@ -218,6 +230,7 @@ describe("generateDeclarations", () => {
},
{
name: "Xyz",
propNames: ["c"],
type: "Efg",
className: '${({ c }) => c ? "justify-center" : "justify-start"}',
classNameOffsets: {
Expand Down Expand Up @@ -247,6 +260,7 @@ describe("generateDeclarations", () => {
const components: Component[] = [
{
name: "Abc",
propNames: [],
type: "span",
className: "flex flex-col",
classNameOffsets: {
Expand All @@ -265,6 +279,7 @@ describe("generateDeclarations", () => {
},
{
name: "Xyz",
propNames: ["c"],
type: "Efg",
className: '${({ c }) => c ? "justify-center" : "justify-start"}',
classNameOffsets: {
Expand Down Expand Up @@ -296,11 +311,13 @@ describe("extractUnboundComponentNames", () => {
const unboundComponentNames = extractUnboundComponentNames([
{
name: "Abc",
propNames: [],
className: "flex flex-col",
classNameOffsets: { start: 124, end: 149 }
},
{
name: "Xyz",
propNames: ["c"],
className: '${({ c }) => c ? "justify-center" : "justify-start"}',
classNameOffsets: { start: 176, end: 226 }
}
Expand All @@ -309,24 +326,36 @@ describe("extractUnboundComponentNames", () => {
});
});

describe("extractUnboundComponentClassNameOffsets", () => {
describe("getComponentsSortedByClassNameOffsets", () => {
it("should return class name offsets", async () => {
const unboundComponentClassNameOffsets =
extractUnboundComponentClassNameOffsets([
const componentsSortedByClassNameOffsets =
getComponentsSortedByClassNameOffsets([
{
name: "Abc",
propNames: [],
className: "flex flex-col",
classNameOffsets: { start: 124, end: 149 }
},
{
name: "Xyz",
propNames: ["c"],
className: '${({ c }) => c ? "justify-center" : "justify-start"}',
classNameOffsets: { start: 176, end: 226 }
}
]);
expect(unboundComponentClassNameOffsets).toEqual([
{ start: 176, end: 226 },
{ start: 124, end: 149 }
expect(componentsSortedByClassNameOffsets).toEqual([
{
name: "Xyz",
propNames: ["c"],
className: '${({ c }) => c ? "justify-center" : "justify-start"}',
classNameOffsets: { start: 176, end: 226 }
},
{
name: "Abc",
propNames: [],
className: "flex flex-col",
classNameOffsets: { start: 124, end: 149 }
}
]);
});
});
Expand Down Expand Up @@ -358,8 +387,9 @@ const TestComponent: React.FC = ({ a }) => {
`;

it("should return underlying component without self closing tag", () => {
expect(getUnderlyingComponent(code, 140)).toEqual({
const expectedComponent: Component = {
name: "",
propNames: [],
type: "Abc",
className: "flex flex-col",
classNameOffsets: {
Expand All @@ -375,12 +405,15 @@ const TestComponent: React.FC = ({ a }) => {
start: 527,
end: 530
}
});
};

expect(getUnderlyingComponent(code, 140)).toEqual(expectedComponent);
});

it("should return underlying component with self closing tag", () => {
expect(getUnderlyingComponent(code, 380)).toEqual({
const expectedComponent: Component = {
name: "",
propNames: [],
type: "Efg",
className: "justify-center",
classNameOffsets: {
Expand All @@ -393,7 +426,9 @@ const TestComponent: React.FC = ({ a }) => {
},
selfClosing: true,
closingTagOffsets: undefined
});
};

expect(getUnderlyingComponent(code, 380)).toEqual(expectedComponent);
});
});

Expand Down
Loading

0 comments on commit baa092c

Please sign in to comment.