diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c5c28e..8e72cfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +- **breaking change** upgrade to TypeScript 4+ and make use of Factory API (#379) + ## [1.6.0] - namespace prefix to help multiple instances of the library not clash (fix #381 in #395) diff --git a/package.json b/package.json index 5c651ff..fa0e763 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "typings": "dist/index.d.ts", "peerDependencies": { - "typescript": "^2.5.2 || ^3.0 || ^4.0" + "typescript": "^4.0" }, "devDependencies": { "@types/jest": "^25.2.1", @@ -33,7 +33,7 @@ "jest-specific-snapshot": "^2.0.0", "ts-jest": "24.3.0", "ts-node": "^8.0.2", - "typescript": "^3.3.1" + "typescript": "~4.2" }, "files": [ "dist" diff --git a/src/__tests__/baselines/base/issue33.ts.baseline b/src/__tests__/baselines/base/issue33.ts.baseline index 8051f5b..203ccdc 100644 --- a/src/__tests__/baselines/base/issue33.ts.baseline +++ b/src/__tests__/baselines/base/issue33.ts.baseline @@ -45,5 +45,13 @@ TypeScript after transform: const Button4 = _.extend \` color: red \`; +TypeScript after transpile module: + + const Button1 = Button.extend \` color: red \`; + const Button2 = $.extend \` color: red \`; + const Button3 = jQuery.extend \` color: red \`; + const Button4 = _.extend \` color: red \`; + + `; diff --git a/src/__tests__/baselines/base/sample1.ts.baseline b/src/__tests__/baselines/base/sample1.ts.baseline index e82141a..e43b98f 100644 --- a/src/__tests__/baselines/base/sample1.ts.baseline +++ b/src/__tests__/baselines/base/sample1.ts.baseline @@ -40,7 +40,7 @@ Source code: TypeScript before transform: - import styled from "styled-components"; + import styled from 'styled-components'; const Button = styled.button \` color: red; \`; @@ -60,7 +60,7 @@ TypeScript before transform: export const SmallButton = Button.extend \` font-size: .7em; \`; - const MiniButton = styled(SmallButton).attrs({ size: "mini" }) \` + const MiniButton = styled(SmallButton).attrs({ size: 'mini' }) \` font-size: .1em; \`; @@ -87,7 +87,33 @@ TypeScript after transform: export const SmallButton = Button.extend \` font-size: .7em; \`; - const MiniButton = styled(SmallButton).attrs({ size: "mini" }).withConfig({ displayName: "MiniButton" }) \` + const MiniButton = styled(SmallButton).attrs({ size: 'mini' }).withConfig({ displayName: "MiniButton" }) \` + font-size: .1em; + \`; + + +TypeScript after transpile module: + + import styled from 'styled-components'; + const Button = styled.button.withConfig({ displayName: "Button" }) \` + color: red; + \`; + const NonButton = nonStyled.button \` + yo + \`; + const OtherButton = styled(Button).withConfig({ displayName: "OtherButton" }) \` + color: blue; + \`; + const SuperButton = Button.extend \` + color: super; + \`; + export default styled.link \` + color: black; + \`; + export const SmallButton = Button.extend \` + font-size: .7em; + \`; + const MiniButton = styled(SmallButton).attrs({ size: 'mini' }).withConfig({ displayName: "MiniButton" }) \` font-size: .1em; \`; diff --git a/src/__tests__/baselines/base/sample2.ts.baseline b/src/__tests__/baselines/base/sample2.ts.baseline index 0ce743f..261414c 100644 --- a/src/__tests__/baselines/base/sample2.ts.baseline +++ b/src/__tests__/baselines/base/sample2.ts.baseline @@ -15,7 +15,7 @@ Source code: TypeScript before transform: - import styled from "styled-components"; + import styled from 'styled-components'; const styled2 = styled; const NonButton = styled.button; const NonStyled = styled \` color: red; \`; @@ -31,5 +31,14 @@ TypeScript after transform: const Link = styled(NonStyled).withConfig({ displayName: "Link" }) \` color: red; \`; +TypeScript after transpile module: + + import styled from 'styled-components'; + const styled2 = styled; + const NonButton = styled.button; + const NonStyled = styled \` color: red; \`; + const Link = styled(NonStyled).withConfig({ displayName: "Link" }) \` color: red; \`; + + `; diff --git a/src/__tests__/baselines/base/sample3.tsx.baseline b/src/__tests__/baselines/base/sample3.tsx.baseline index 3cbcdf4..2ae5c79 100644 --- a/src/__tests__/baselines/base/sample3.tsx.baseline +++ b/src/__tests__/baselines/base/sample3.tsx.baseline @@ -24,14 +24,14 @@ Source code: TypeScript before transform: - import * as React from "react"; - import styled from "../themed-styled"; - import { SmallButton } from "./sample1"; + import * as React from 'react'; + import styled from '../themed-styled'; + import { SmallButton } from './sample1'; interface LabelProps { size: number; } const CustomLabel = styled.label \` - font-size: \${(props: LabelProps) => props.size + "px"} + font-size: \${(props: LabelProps) => props.size + 'px'} \`; const LabeledLink = () => ; export default CustomLabel; @@ -52,5 +52,15 @@ TypeScript after transform: export default CustomLabel; +TypeScript after transpile module: + + import styled from '../themed-styled'; + const CustomLabel = styled.label.withConfig({ displayName: "CustomLabel" }) \` + font-size: \${(props) => props.size + 'px'} + \`; + const LabeledLink = () => />;; + export default CustomLabel; + + `; diff --git a/src/__tests__/baselines/base/style-objects.ts.baseline b/src/__tests__/baselines/base/style-objects.ts.baseline index 95d4e16..c5b6205 100644 --- a/src/__tests__/baselines/base/style-objects.ts.baseline +++ b/src/__tests__/baselines/base/style-objects.ts.baseline @@ -42,26 +42,26 @@ TypeScript before transform: declare const styled: any; const Button = styled.button({ - color: "red" + color: 'red' }); declare const nonStyled: any; const NonButton = nonStyled.button({ - color: "red" + color: 'red' }); const OtherButton = styled(Button)({ - color: "blue" + color: 'blue' }); const SuperButton = Button.extend({ - color: "super" + color: 'super' }); export default styled.link({ - color: "black" + color: 'black' }); export const SmallButton = Button.extend({ - fontSize: ".7em" + fontSize: '.7em' }); - const MiniButton = styled(SmallButton).attrs({ size: "mini" })({ - fontSize: ".1em" + const MiniButton = styled(SmallButton).attrs({ size: 'mini' })({ + fontSize: '.1em' }); @@ -87,7 +87,32 @@ TypeScript after transform: export const SmallButton = Button.extend({ fontSize: '.7em' }); - const MiniButton = styled(SmallButton).attrs({ size: "mini" }).withConfig({ displayName: "MiniButton" })({ + const MiniButton = styled(SmallButton).attrs({ size: 'mini' }).withConfig({ displayName: "MiniButton" })({ + fontSize: '.1em' + }); + + +TypeScript after transpile module: + + const Button = styled.button.withConfig({ displayName: "Button" })({ + color: 'red' + }); + const NonButton = nonStyled.button({ + color: 'red' + }); + const OtherButton = styled(Button).withConfig({ displayName: "OtherButton" })({ + color: 'blue' + }); + const SuperButton = Button.extend({ + color: 'super' + }); + export default styled.link({ + color: 'black' + }); + export const SmallButton = Button.extend({ + fontSize: '.7em' + }); + const MiniButton = styled(SmallButton).attrs({ size: 'mini' }).withConfig({ displayName: "MiniButton" })({ fontSize: '.1em' }); diff --git a/src/__tests__/baselines/componentIdPrefix/issue33.ts.baseline b/src/__tests__/baselines/componentIdPrefix/issue33.ts.baseline index 8051f5b..203ccdc 100644 --- a/src/__tests__/baselines/componentIdPrefix/issue33.ts.baseline +++ b/src/__tests__/baselines/componentIdPrefix/issue33.ts.baseline @@ -45,5 +45,13 @@ TypeScript after transform: const Button4 = _.extend \` color: red \`; +TypeScript after transpile module: + + const Button1 = Button.extend \` color: red \`; + const Button2 = $.extend \` color: red \`; + const Button3 = jQuery.extend \` color: red \`; + const Button4 = _.extend \` color: red \`; + + `; diff --git a/src/__tests__/baselines/componentIdPrefix/multiple-components.tsx.baseline b/src/__tests__/baselines/componentIdPrefix/multiple-components.tsx.baseline index a792748..b1d3a9f 100644 --- a/src/__tests__/baselines/componentIdPrefix/multiple-components.tsx.baseline +++ b/src/__tests__/baselines/componentIdPrefix/multiple-components.tsx.baseline @@ -24,7 +24,7 @@ Source code: TypeScript before transform: - import styled from "styled-components"; + import styled from 'styled-components'; export function createButtons() { const A = styled.button \` color: red; \`; const B = styled(A) \` color: blue; \`; @@ -41,13 +41,28 @@ TypeScript after transform: import styled from 'styled-components'; export function createButtons() { - const A = styled.button.withConfig({ displayName: "test-A", componentId: "test-hana72" }) \` color: red; \`; - const B = styled(A).withConfig({ displayName: "test-B", componentId: "test-ke4nds" }) \` color: blue; \`; + const A = styled.button.withConfig({ displayName: "test-A", componentId: "test-h2cmto" }) \` color: red; \`; + const B = styled(A).withConfig({ displayName: "test-B", componentId: "test-3cja5" }) \` color: blue; \`; + return { A, B }; + } + export function createDivs() { + const A = styled.div.withConfig({ displayName: "test-A", componentId: "test-1oubriv" }) \` color: green; \`; + const B = styled(A).withConfig({ displayName: "test-B", componentId: "test-lfixbl" }) \` color: yellow; \`; + return { A, B }; + } + + +TypeScript after transpile module: + + import styled from 'styled-components'; + export function createButtons() { + const A = styled.button.withConfig({ displayName: "test-A", componentId: "test-1lfj0gb" }) \` color: red; \`; + const B = styled(A).withConfig({ displayName: "test-B", componentId: "test-kjhsv6" }) \` color: blue; \`; return { A, B }; } export function createDivs() { - const A = styled.div.withConfig({ displayName: "test-A", componentId: "test-1q7vmnt" }) \` color: green; \`; - const B = styled(A).withConfig({ displayName: "test-B", componentId: "test-7q8oop" }) \` color: yellow; \`; + const A = styled.div.withConfig({ displayName: "test-A", componentId: "test-wzcq75" }) \` color: green; \`; + const B = styled(A).withConfig({ displayName: "test-B", componentId: "test-6zek9o" }) \` color: yellow; \`; return { A, B }; } diff --git a/src/__tests__/baselines/componentIdPrefix/sample1.ts.baseline b/src/__tests__/baselines/componentIdPrefix/sample1.ts.baseline index 5a7066a..b0e2927 100644 --- a/src/__tests__/baselines/componentIdPrefix/sample1.ts.baseline +++ b/src/__tests__/baselines/componentIdPrefix/sample1.ts.baseline @@ -40,7 +40,7 @@ Source code: TypeScript before transform: - import styled from "styled-components"; + import styled from 'styled-components'; const Button = styled.button \` color: red; \`; @@ -60,7 +60,7 @@ TypeScript before transform: export const SmallButton = Button.extend \` font-size: .7em; \`; - const MiniButton = styled(SmallButton).attrs({ size: "mini" }) \` + const MiniButton = styled(SmallButton).attrs({ size: 'mini' }) \` font-size: .1em; \`; @@ -68,14 +68,14 @@ TypeScript before transform: TypeScript after transform: import styled from 'styled-components'; - const Button = styled.button.withConfig({ displayName: "test-Button", componentId: "test-1okqsxw" }) \` + const Button = styled.button.withConfig({ displayName: "test-Button", componentId: "test-uezo0r" }) \` color: red; \`; declare const nonStyled: any; const NonButton = nonStyled.button \` yo \`; - const OtherButton = styled(Button).withConfig({ displayName: "test-OtherButton", componentId: "test-ce0fkl" }) \` + const OtherButton = styled(Button).withConfig({ displayName: "test-OtherButton", componentId: "test-1x4ml5" }) \` color: blue; \`; const SuperButton = Button.extend \` @@ -87,7 +87,33 @@ TypeScript after transform: export const SmallButton = Button.extend \` font-size: .7em; \`; - const MiniButton = styled(SmallButton).attrs({ size: "mini" }).withConfig({ displayName: "test-MiniButton", componentId: "test-ndnumj" }) \` + const MiniButton = styled(SmallButton).attrs({ size: 'mini' }).withConfig({ displayName: "test-MiniButton", componentId: "test-1ktoxg0" }) \` + font-size: .1em; + \`; + + +TypeScript after transpile module: + + import styled from 'styled-components'; + const Button = styled.button.withConfig({ displayName: "test-Button", componentId: "test-1nbxxpw" }) \` + color: red; + \`; + const NonButton = nonStyled.button \` + yo + \`; + const OtherButton = styled(Button).withConfig({ displayName: "test-OtherButton", componentId: "test-17xltiv" }) \` + color: blue; + \`; + const SuperButton = Button.extend \` + color: super; + \`; + export default styled.link.withConfig({ componentId: "test-ep20on" }) \` + color: black; + \`; + export const SmallButton = Button.extend \` + font-size: .7em; + \`; + const MiniButton = styled(SmallButton).attrs({ size: 'mini' }).withConfig({ displayName: "test-MiniButton", componentId: "test-am1bk" }) \` font-size: .1em; \`; diff --git a/src/__tests__/baselines/componentIdPrefix/sample2.ts.baseline b/src/__tests__/baselines/componentIdPrefix/sample2.ts.baseline index 7554e7e..bceceb6 100644 --- a/src/__tests__/baselines/componentIdPrefix/sample2.ts.baseline +++ b/src/__tests__/baselines/componentIdPrefix/sample2.ts.baseline @@ -15,7 +15,7 @@ Source code: TypeScript before transform: - import styled from "styled-components"; + import styled from 'styled-components'; const styled2 = styled; const NonButton = styled.button; const NonStyled = styled \` color: red; \`; @@ -28,7 +28,16 @@ TypeScript after transform: const styled2 = styled; const NonButton = styled.button; const NonStyled = styled \` color: red; \`; - const Link = styled(NonStyled).withConfig({ displayName: "test-Link", componentId: "test-1xlc242" }) \` color: red; \`; + const Link = styled(NonStyled).withConfig({ displayName: "test-Link", componentId: "test-1gbt9xq" }) \` color: red; \`; + + +TypeScript after transpile module: + + import styled from 'styled-components'; + const styled2 = styled; + const NonButton = styled.button; + const NonStyled = styled \` color: red; \`; + const Link = styled(NonStyled).withConfig({ displayName: "test-Link", componentId: "test-gbrvon" }) \` color: red; \`; diff --git a/src/__tests__/baselines/componentIdPrefix/sample3.tsx.baseline b/src/__tests__/baselines/componentIdPrefix/sample3.tsx.baseline index cf12265..363da31 100644 --- a/src/__tests__/baselines/componentIdPrefix/sample3.tsx.baseline +++ b/src/__tests__/baselines/componentIdPrefix/sample3.tsx.baseline @@ -24,14 +24,14 @@ Source code: TypeScript before transform: - import * as React from "react"; - import styled from "../themed-styled"; - import { SmallButton } from "./sample1"; + import * as React from 'react'; + import styled from '../themed-styled'; + import { SmallButton } from './sample1'; interface LabelProps { size: number; } const CustomLabel = styled.label \` - font-size: \${(props: LabelProps) => props.size + "px"} + font-size: \${(props: LabelProps) => props.size + 'px'} \`; const LabeledLink = () => ; export default CustomLabel; @@ -45,12 +45,22 @@ TypeScript after transform: interface LabelProps { size: number; } - const CustomLabel = styled.label.withConfig({ displayName: "test-CustomLabel", componentId: "test-1ydgk9x" }) \` + const CustomLabel = styled.label.withConfig({ displayName: "test-CustomLabel", componentId: "test-xtd6b" }) \` font-size: \${(props: LabelProps) => props.size + 'px'} \`; const LabeledLink = () => ; export default CustomLabel; +TypeScript after transpile module: + + import styled from '../themed-styled'; + const CustomLabel = styled.label.withConfig({ displayName: "test-CustomLabel", componentId: "test-mqylua" }) \` + font-size: \${(props) => props.size + 'px'} + \`; + const LabeledLink = () => />;; + export default CustomLabel; + + `; diff --git a/src/__tests__/baselines/componentIdPrefix/style-objects.ts.baseline b/src/__tests__/baselines/componentIdPrefix/style-objects.ts.baseline index 32cae79..dc73858 100644 --- a/src/__tests__/baselines/componentIdPrefix/style-objects.ts.baseline +++ b/src/__tests__/baselines/componentIdPrefix/style-objects.ts.baseline @@ -42,40 +42,40 @@ TypeScript before transform: declare const styled: any; const Button = styled.button({ - color: "red" + color: 'red' }); declare const nonStyled: any; const NonButton = nonStyled.button({ - color: "red" + color: 'red' }); const OtherButton = styled(Button)({ - color: "blue" + color: 'blue' }); const SuperButton = Button.extend({ - color: "super" + color: 'super' }); export default styled.link({ - color: "black" + color: 'black' }); export const SmallButton = Button.extend({ - fontSize: ".7em" + fontSize: '.7em' }); - const MiniButton = styled(SmallButton).attrs({ size: "mini" })({ - fontSize: ".1em" + const MiniButton = styled(SmallButton).attrs({ size: 'mini' })({ + fontSize: '.1em' }); TypeScript after transform: declare const styled: any; - const Button = styled.button.withConfig({ displayName: "test-Button", componentId: "test-7b7p9e" })({ + const Button = styled.button.withConfig({ displayName: "test-Button", componentId: "test-1qkmci6" })({ color: 'red' }); declare const nonStyled: any; const NonButton = nonStyled.button({ color: 'red' }); - const OtherButton = styled(Button).withConfig({ displayName: "test-OtherButton", componentId: "test-14ah7t" })({ + const OtherButton = styled(Button).withConfig({ displayName: "test-OtherButton", componentId: "test-6fha6t" })({ color: 'blue' }); const SuperButton = Button.extend({ @@ -87,7 +87,32 @@ TypeScript after transform: export const SmallButton = Button.extend({ fontSize: '.7em' }); - const MiniButton = styled(SmallButton).attrs({ size: "mini" }).withConfig({ displayName: "test-MiniButton", componentId: "test-ad4g7l" })({ + const MiniButton = styled(SmallButton).attrs({ size: 'mini' }).withConfig({ displayName: "test-MiniButton", componentId: "test-nrep0p" })({ + fontSize: '.1em' + }); + + +TypeScript after transpile module: + + const Button = styled.button.withConfig({ displayName: "test-Button", componentId: "test-1nbxxpw" })({ + color: 'red' + }); + const NonButton = nonStyled.button({ + color: 'red' + }); + const OtherButton = styled(Button).withConfig({ displayName: "test-OtherButton", componentId: "test-17xltiv" })({ + color: 'blue' + }); + const SuperButton = Button.extend({ + color: 'super' + }); + export default styled.link.withConfig({ componentId: "test-ep20on" })({ + color: 'black' + }); + export const SmallButton = Button.extend({ + fontSize: '.7em' + }); + const MiniButton = styled(SmallButton).attrs({ size: 'mini' }).withConfig({ displayName: "test-MiniButton", componentId: "test-am1bk" })({ fontSize: '.1em' }); diff --git a/src/__tests__/baselines/minification-only/issue142.tsx.baseline b/src/__tests__/baselines/minification-only/issue142.tsx.baseline index 897ef04..802baac 100644 --- a/src/__tests__/baselines/minification-only/issue142.tsx.baseline +++ b/src/__tests__/baselines/minification-only/issue142.tsx.baseline @@ -36,5 +36,10 @@ TypeScript after transform: const Header = styled.div \`display:flex;align-items:center;justify-content:space-between;font-weight:600;padding:0.8em 1.6em;background:peachpuff;\`; +TypeScript after transpile module: + + const Header = styled.div \`display:flex;align-items:center;justify-content:space-between;font-weight:600;padding:0.8em 1.6em;background:peachpuff;\`; + + `; diff --git a/src/__tests__/baselines/minification-only/issue36-extended.ts.baseline b/src/__tests__/baselines/minification-only/issue36-extended.ts.baseline index b29b244..41ab3e4 100644 --- a/src/__tests__/baselines/minification-only/issue36-extended.ts.baseline +++ b/src/__tests__/baselines/minification-only/issue36-extended.ts.baseline @@ -30,18 +30,18 @@ TypeScript before transform: declare const styled: any; export const A = styled.div \` - border: \${"solid"} 10px; + border: \${'solid'} 10px; \`; styled.div \` - border: \${"solid"}// comment here + border: \${'solid'}// comment here 10px; border: solid// comment here 10px; \`; styled.div \` - border: \${"solid"}/* comment here + border: \${'solid'}/* comment here */10px; - border: \${"solid"}/* comment here + border: \${'solid'}/* comment here */ 10px; \`; @@ -54,5 +54,12 @@ TypeScript after transform: styled.div \`border:\${'solid'} 10px;border:\${'solid'} 10px;\`; +TypeScript after transpile module: + + export const A = styled.div \`border:\${'solid'} 10px;\`; + styled.div \`border:\${'solid'} 10px;border:solid 10px;\`; + styled.div \`border:\${'solid'} 10px;border:\${'solid'} 10px;\`; + + `; diff --git a/src/__tests__/baselines/minification-only/issue36.tsx.baseline b/src/__tests__/baselines/minification-only/issue36.tsx.baseline index 87777aa..bde12fa 100644 --- a/src/__tests__/baselines/minification-only/issue36.tsx.baseline +++ b/src/__tests__/baselines/minification-only/issue36.tsx.baseline @@ -53,5 +53,11 @@ TypeScript after transform: export const StyledDiv = styled.div \`width:100px;height:100px;background-color:greenyellow;animation:\${rotate360} 2s linear infinite;\`; +TypeScript after transpile module: + + const rotate360 = keyframes \`from{transform:rotate(0deg);}to{transform:rotate(360deg);}\`; + export const StyledDiv = styled.div \`width:100px;height:100px;background-color:greenyellow;animation:\${rotate360} 2s linear infinite;\`; + + `; diff --git a/src/__tests__/baselines/minification-only/issue40.ts.baseline b/src/__tests__/baselines/minification-only/issue40.ts.baseline index 200e58b..6df145f 100644 --- a/src/__tests__/baselines/minification-only/issue40.ts.baseline +++ b/src/__tests__/baselines/minification-only/issue40.ts.baseline @@ -13,7 +13,7 @@ Source code: TypeScript before transform: declare const styled: any; - styled.div \`padding: 0 0 13px \${"50px"};\`; + styled.div \`padding: 0 0 13px \${'50px'};\`; TypeScript after transform: @@ -22,5 +22,10 @@ TypeScript after transform: styled.div \`padding:0 0 13px \${'50px'};\`; +TypeScript after transpile module: + + styled.div \`padding:0 0 13px \${'50px'};\`; + + `; diff --git a/src/__tests__/baselines/minification-only/issue44.tsx.baseline b/src/__tests__/baselines/minification-only/issue44.tsx.baseline index 70c6c02..2ecfb75 100644 --- a/src/__tests__/baselines/minification-only/issue44.tsx.baseline +++ b/src/__tests__/baselines/minification-only/issue44.tsx.baseline @@ -14,7 +14,7 @@ TypeScript before transform: declare const styled: any; styled.div \` transition: width \${100}ms ease-in;\`; - styled.div \` transition: width \${"100ms"} ease-in;\`; + styled.div \` transition: width \${'100ms'} ease-in;\`; TypeScript after transform: @@ -24,5 +24,11 @@ TypeScript after transform: styled.div \`transition:width \${'100ms'} ease-in;\`; +TypeScript after transpile module: + + styled.div \`transition:width \${100}ms ease-in;\`; + styled.div \`transition:width \${'100ms'} ease-in;\`; + + `; diff --git a/src/__tests__/baselines/minification-only/minify-css-in-helpers.ts.baseline b/src/__tests__/baselines/minification-only/minify-css-in-helpers.ts.baseline index c92c8aa..273a6a8 100644 --- a/src/__tests__/baselines/minification-only/minify-css-in-helpers.ts.baseline +++ b/src/__tests__/baselines/minification-only/minify-css-in-helpers.ts.baseline @@ -69,5 +69,14 @@ TypeScript after transform: export {}; +TypeScript after transpile module: + + const key = keyframes \`to{transform:rotate(360deg);}\`; + const color = css \`color:\${theColor};\`; + const MyRedBody = createGlobalStyle \`body{background-color:red;\${color}//\${color} + }\`; + export {}; + + `; diff --git a/src/__tests__/baselines/minification-only/minify-css-to-use-with-transpilation.ts.baseline b/src/__tests__/baselines/minification-only/minify-css-to-use-with-transpilation.ts.baseline index 9bb1b51..d40be8d 100644 --- a/src/__tests__/baselines/minification-only/minify-css-to-use-with-transpilation.ts.baseline +++ b/src/__tests__/baselines/minification-only/minify-css-to-use-with-transpilation.ts.baseline @@ -68,5 +68,15 @@ TypeScript after transform: export {}; +TypeScript after transpile module: + + const Simple = styled.div \`width:100%;\`; + const Interpolation = styled.div \`content:" \${props => props.text} ";\`; + const SpecialCharacters = styled.div \`content:" \${props => props.text} ";color:red;\`; + const Comment = styled.div \`color:red;\`; + const Parens = styled.div \`&:hover{color:blue;}\`; + export {}; + + `; diff --git a/src/__tests__/baselines/minification-only/minify-css-to-use-without-transpilation.ts.baseline b/src/__tests__/baselines/minification-only/minify-css-to-use-without-transpilation.ts.baseline index 213dac2..2b32a9a 100644 --- a/src/__tests__/baselines/minification-only/minify-css-to-use-without-transpilation.ts.baseline +++ b/src/__tests__/baselines/minification-only/minify-css-to-use-without-transpilation.ts.baseline @@ -92,5 +92,16 @@ TypeScript after transform: export {}; +TypeScript after transpile module: + + const Simple = styled.div \`width:100%;\`; + const Interpolation = styled.div \`content:"https://test.com/\${props => props.endpoint}";\`; + const SpecialCharacters = styled.div \`content:" \${props => props.text} ";color:red;\`; + const Comment = styled.div \`width:100%;color:red;\`; + const Parens = styled.div \`&:hover{color:blue;}color:red;\`; + const UrlComments = styled.div \`color:red;background:red;border:1px solid green;\`; + export {}; + + `; diff --git a/src/__tests__/baselines/minification-only/minify-single-line-comments-with-interpolations.ts.baseline b/src/__tests__/baselines/minification-only/minify-single-line-comments-with-interpolations.ts.baseline index f4e8c67..b80c5bc 100644 --- a/src/__tests__/baselines/minification-only/minify-single-line-comments-with-interpolations.ts.baseline +++ b/src/__tests__/baselines/minification-only/minify-single-line-comments-with-interpolations.ts.baseline @@ -62,41 +62,41 @@ TypeScript before transform: declare const styled: any; const Test1 = styled.div \` width: 100%; - // color: \${"red"}; + // color: \${'red'}; \`; const Test2 = styled.div \` width: 100%; - // color: pale\${"red"}; + // color: pale\${'red'}; \`; const Test3 = styled.div \` width: 100%; // color - \${"red"}; + \${'red'}; \`; const Test4 = styled.div \` width: 100%; - // color: \${"red"}-blue; + // color: \${'red'}-blue; \`; const Test5 = styled.div \` width: 100%; - // color: \${"red"}\${"blue"}; + // color: \${'red'}\${'blue'}; \`; const Test6 = styled.div \` background: url("https://google.com"); width: 100%; - \${"green"} // color: \${"red"}\${"blue"}; + \${'green'} // color: \${'red'}\${'blue'}; \`; const Test7 = styled.div \` background: url("https://google.com"); width: \${p => p.props.width}; - \${"green"} // color: \${"red"}\${"blue"}; + \${'green'} // color: \${'red'}\${'blue'}; height: \${p => p.props.height}; \`; const Test8 = styled.dev \` - color: /* \${"red"} ... disabled */ blue; + color: /* \${'red'} ... disabled */ blue; \`; const Test9 = styled.dev \` - color: // \${"red"} ... disabled + color: // \${'red'} ... disabled blue \`; export {}; @@ -119,5 +119,21 @@ TypeScript after transform: export {}; +TypeScript after transpile module: + + const Test1 = styled.div \`width:100%;//\${'red'}\`; + const Test2 = styled.div \`width:100%;//\${'red'}\`; + const Test3 = styled.div \`width:100%;\${'red'};\`; + const Test4 = styled.div \`width:100%;//\${'red'}\`; + const Test5 = styled.div \`width:100%;//\${'red'}\${'blue'}\`; + const Test6 = styled.div \`background:url("https://google.com");width:100%;\${'green'}//\${'red'}\${'blue'}\`; + const Test7 = styled.div \`background:url("https://google.com");width:\${p => p.props.width};\${'green'}//\${'red'}\${'blue'} + height:\${p => p.props.height};\`; + const Test8 = styled.dev \`color:/*\${'red'}*/blue;\`; + const Test9 = styled.dev \`color://\${'red'} + blue\`; + export {}; + + `; diff --git a/src/__tests__/baselines/minification-only/simple.ts.baseline b/src/__tests__/baselines/minification-only/simple.ts.baseline index 78f6ee9..8fbab68 100644 --- a/src/__tests__/baselines/minification-only/simple.ts.baseline +++ b/src/__tests__/baselines/minification-only/simple.ts.baseline @@ -187,5 +187,54 @@ TypeScript after transform: styled.div \`;" : "' : ';\`; +TypeScript after transpile module: + + // splits a line by potential comment starts and joins until one is an actual comment + // \`abc def\` + styled.div \`abc def\`; + // ignores comment markers that are inside strings + // \`abc def"//"ghi\\'//\\'jkl\` + styled.div \`abc def"//"ghi'//'jkl\`; + // \`abc def"//"\` + styled.div \`abc def"//"\`; + // ignores comment markers that are inside parantheses + // \`bla (//) bla\` + styled.div \`bla (//)bla\`; + // ignores even unescaped URLs + // \`https://test.com\` + styled.div \`https:\`; + // removes multi-line comments + // \`this is a test\` + styled.div \`this is a test\`; + // joins all lines of code + // \`this is a test\` + styled.div \`this is a test\`; + // removes line comments filling an entire line + // \`line one{line:two;}\` + styled.div \`line one{line:two;}\`; + // removes line comments at the end of lines of code + // \`valid line with out comments\` + styled.div \`valid line with out comments\`; + // preserves multi-line comments starting with /*! + // \`this is a /*! dont ignore me please */ test\` + styled.div \`this is a test\`; + // returns the indices of removed placeholders (expressions) + // \`this is some input with \${placeholder1} and //\${placeholder2}\` + styled.div \`this is some input with \${placeholder1} and//\${placeholder2}\`; + // works with raw escape codes + // \`this\\\\nis\\\\na \\\\ntest\` + styled.div \`this\\\\nis\\\\na \\\\ntest\`; + // \`this\\nis\\na \\ntest\` + styled.div \`this is a test\`; + // \`this is a test\` + styled.div \`this is a test\`; + // removes spaces around symbols + // \`;:{},;\` + styled.div \`;:{},;\`; + // ignores symbols inside strings + // \`;" : "\\' : \\';\` + styled.div \`;" : "' : ';\`; + + `; diff --git a/src/__tests__/baselines/minification-only/simple2.ts.baseline b/src/__tests__/baselines/minification-only/simple2.ts.baseline index 3697adc..77017e7 100644 --- a/src/__tests__/baselines/minification-only/simple2.ts.baseline +++ b/src/__tests__/baselines/minification-only/simple2.ts.baseline @@ -43,5 +43,17 @@ TypeScript after transform: styled.div \`a b ( c )d\`; // \`a b ( c )d\` +TypeScript after transpile module: + + // spaces before and after ' " ( ) + styled.div \`a b" c "d\`; // \`a b" c "d\` + styled.div \`a b' c 'd\`; // \`a b' c 'd\` + styled.div \`a b( c )d\`; // \`a b( c )d\` + styled.div \`a b " c "d\`; // \`a b " c "d\` + styled.div \`a b ' c 'd\`; // \`a b ' c 'd\` + styled.div \`a b ( c )d\`; // \`a b ( c )d\` + export {}; + + `; diff --git a/src/__tests__/baselines/minification/issue142.tsx.baseline b/src/__tests__/baselines/minification/issue142.tsx.baseline index 9ad0559..bc4ec60 100644 --- a/src/__tests__/baselines/minification/issue142.tsx.baseline +++ b/src/__tests__/baselines/minification/issue142.tsx.baseline @@ -36,5 +36,10 @@ TypeScript after transform: const Header = styled.div.withConfig({ displayName: "Header" }) \`display:flex;align-items:center;justify-content:space-between;font-weight:600;padding:0.8em 1.6em;background:peachpuff;\`; +TypeScript after transpile module: + + const Header = styled.div.withConfig({ displayName: "Header" }) \`display:flex;align-items:center;justify-content:space-between;font-weight:600;padding:0.8em 1.6em;background:peachpuff;\`; + + `; diff --git a/src/__tests__/baselines/minification/issue36-extended.ts.baseline b/src/__tests__/baselines/minification/issue36-extended.ts.baseline index 8cdb3d1..fe3cdb1 100644 --- a/src/__tests__/baselines/minification/issue36-extended.ts.baseline +++ b/src/__tests__/baselines/minification/issue36-extended.ts.baseline @@ -30,18 +30,18 @@ TypeScript before transform: declare const styled: any; export const A = styled.div \` - border: \${"solid"} 10px; + border: \${'solid'} 10px; \`; styled.div \` - border: \${"solid"}// comment here + border: \${'solid'}// comment here 10px; border: solid// comment here 10px; \`; styled.div \` - border: \${"solid"}/* comment here + border: \${'solid'}/* comment here */10px; - border: \${"solid"}/* comment here + border: \${'solid'}/* comment here */ 10px; \`; @@ -54,5 +54,12 @@ TypeScript after transform: styled.div \`border:\${'solid'} 10px;border:\${'solid'} 10px;\`; +TypeScript after transpile module: + + export const A = styled.div.withConfig({ displayName: "A" }) \`border:\${'solid'} 10px;\`; + styled.div \`border:\${'solid'} 10px;border:solid 10px;\`; + styled.div \`border:\${'solid'} 10px;border:\${'solid'} 10px;\`; + + `; diff --git a/src/__tests__/baselines/minification/issue36.tsx.baseline b/src/__tests__/baselines/minification/issue36.tsx.baseline index 2f16c02..e37e4e0 100644 --- a/src/__tests__/baselines/minification/issue36.tsx.baseline +++ b/src/__tests__/baselines/minification/issue36.tsx.baseline @@ -53,5 +53,11 @@ TypeScript after transform: export const StyledDiv = styled.div.withConfig({ displayName: "StyledDiv" }) \`width:100px;height:100px;background-color:greenyellow;animation:\${rotate360} 2s linear infinite;\`; +TypeScript after transpile module: + + const rotate360 = keyframes \`from{transform:rotate(0deg);}to{transform:rotate(360deg);}\`; + export const StyledDiv = styled.div.withConfig({ displayName: "StyledDiv" }) \`width:100px;height:100px;background-color:greenyellow;animation:\${rotate360} 2s linear infinite;\`; + + `; diff --git a/src/__tests__/baselines/minification/issue40.ts.baseline b/src/__tests__/baselines/minification/issue40.ts.baseline index 200e58b..6df145f 100644 --- a/src/__tests__/baselines/minification/issue40.ts.baseline +++ b/src/__tests__/baselines/minification/issue40.ts.baseline @@ -13,7 +13,7 @@ Source code: TypeScript before transform: declare const styled: any; - styled.div \`padding: 0 0 13px \${"50px"};\`; + styled.div \`padding: 0 0 13px \${'50px'};\`; TypeScript after transform: @@ -22,5 +22,10 @@ TypeScript after transform: styled.div \`padding:0 0 13px \${'50px'};\`; +TypeScript after transpile module: + + styled.div \`padding:0 0 13px \${'50px'};\`; + + `; diff --git a/src/__tests__/baselines/minification/issue44.tsx.baseline b/src/__tests__/baselines/minification/issue44.tsx.baseline index 70c6c02..2ecfb75 100644 --- a/src/__tests__/baselines/minification/issue44.tsx.baseline +++ b/src/__tests__/baselines/minification/issue44.tsx.baseline @@ -14,7 +14,7 @@ TypeScript before transform: declare const styled: any; styled.div \` transition: width \${100}ms ease-in;\`; - styled.div \` transition: width \${"100ms"} ease-in;\`; + styled.div \` transition: width \${'100ms'} ease-in;\`; TypeScript after transform: @@ -24,5 +24,11 @@ TypeScript after transform: styled.div \`transition:width \${'100ms'} ease-in;\`; +TypeScript after transpile module: + + styled.div \`transition:width \${100}ms ease-in;\`; + styled.div \`transition:width \${'100ms'} ease-in;\`; + + `; diff --git a/src/__tests__/baselines/minification/minify-css-in-helpers.ts.baseline b/src/__tests__/baselines/minification/minify-css-in-helpers.ts.baseline index c92c8aa..273a6a8 100644 --- a/src/__tests__/baselines/minification/minify-css-in-helpers.ts.baseline +++ b/src/__tests__/baselines/minification/minify-css-in-helpers.ts.baseline @@ -69,5 +69,14 @@ TypeScript after transform: export {}; +TypeScript after transpile module: + + const key = keyframes \`to{transform:rotate(360deg);}\`; + const color = css \`color:\${theColor};\`; + const MyRedBody = createGlobalStyle \`body{background-color:red;\${color}//\${color} + }\`; + export {}; + + `; diff --git a/src/__tests__/baselines/minification/minify-css-to-use-with-transpilation.ts.baseline b/src/__tests__/baselines/minification/minify-css-to-use-with-transpilation.ts.baseline index 18e1925..4541316 100644 --- a/src/__tests__/baselines/minification/minify-css-to-use-with-transpilation.ts.baseline +++ b/src/__tests__/baselines/minification/minify-css-to-use-with-transpilation.ts.baseline @@ -68,5 +68,15 @@ TypeScript after transform: export {}; +TypeScript after transpile module: + + const Simple = styled.div.withConfig({ displayName: "Simple" }) \`width:100%;\`; + const Interpolation = styled.div.withConfig({ displayName: "Interpolation" }) \`content:" \${props => props.text} ";\`; + const SpecialCharacters = styled.div.withConfig({ displayName: "SpecialCharacters" }) \`content:" \${props => props.text} ";color:red;\`; + const Comment = styled.div.withConfig({ displayName: "Comment" }) \`color:red;\`; + const Parens = styled.div.withConfig({ displayName: "Parens" }) \`&:hover{color:blue;}\`; + export {}; + + `; diff --git a/src/__tests__/baselines/minification/minify-css-to-use-without-transpilation.ts.baseline b/src/__tests__/baselines/minification/minify-css-to-use-without-transpilation.ts.baseline index e0a8cbe..71c4ef1 100644 --- a/src/__tests__/baselines/minification/minify-css-to-use-without-transpilation.ts.baseline +++ b/src/__tests__/baselines/minification/minify-css-to-use-without-transpilation.ts.baseline @@ -92,5 +92,16 @@ TypeScript after transform: export {}; +TypeScript after transpile module: + + const Simple = styled.div.withConfig({ displayName: "Simple" }) \`width:100%;\`; + const Interpolation = styled.div.withConfig({ displayName: "Interpolation" }) \`content:"https://test.com/\${props => props.endpoint}";\`; + const SpecialCharacters = styled.div.withConfig({ displayName: "SpecialCharacters" }) \`content:" \${props => props.text} ";color:red;\`; + const Comment = styled.div.withConfig({ displayName: "Comment" }) \`width:100%;color:red;\`; + const Parens = styled.div.withConfig({ displayName: "Parens" }) \`&:hover{color:blue;}color:red;\`; + const UrlComments = styled.div.withConfig({ displayName: "UrlComments" }) \`color:red;background:red;border:1px solid green;\`; + export {}; + + `; diff --git a/src/__tests__/baselines/minification/minify-single-line-comments-with-interpolations.ts.baseline b/src/__tests__/baselines/minification/minify-single-line-comments-with-interpolations.ts.baseline index 58db74e..da3958a 100644 --- a/src/__tests__/baselines/minification/minify-single-line-comments-with-interpolations.ts.baseline +++ b/src/__tests__/baselines/minification/minify-single-line-comments-with-interpolations.ts.baseline @@ -62,41 +62,41 @@ TypeScript before transform: declare const styled: any; const Test1 = styled.div \` width: 100%; - // color: \${"red"}; + // color: \${'red'}; \`; const Test2 = styled.div \` width: 100%; - // color: pale\${"red"}; + // color: pale\${'red'}; \`; const Test3 = styled.div \` width: 100%; // color - \${"red"}; + \${'red'}; \`; const Test4 = styled.div \` width: 100%; - // color: \${"red"}-blue; + // color: \${'red'}-blue; \`; const Test5 = styled.div \` width: 100%; - // color: \${"red"}\${"blue"}; + // color: \${'red'}\${'blue'}; \`; const Test6 = styled.div \` background: url("https://google.com"); width: 100%; - \${"green"} // color: \${"red"}\${"blue"}; + \${'green'} // color: \${'red'}\${'blue'}; \`; const Test7 = styled.div \` background: url("https://google.com"); width: \${p => p.props.width}; - \${"green"} // color: \${"red"}\${"blue"}; + \${'green'} // color: \${'red'}\${'blue'}; height: \${p => p.props.height}; \`; const Test8 = styled.dev \` - color: /* \${"red"} ... disabled */ blue; + color: /* \${'red'} ... disabled */ blue; \`; const Test9 = styled.dev \` - color: // \${"red"} ... disabled + color: // \${'red'} ... disabled blue \`; export {}; @@ -119,5 +119,21 @@ TypeScript after transform: export {}; +TypeScript after transpile module: + + const Test1 = styled.div.withConfig({ displayName: "Test1" }) \`width:100%;//\${'red'}\`; + const Test2 = styled.div.withConfig({ displayName: "Test2" }) \`width:100%;//\${'red'}\`; + const Test3 = styled.div.withConfig({ displayName: "Test3" }) \`width:100%;\${'red'};\`; + const Test4 = styled.div.withConfig({ displayName: "Test4" }) \`width:100%;//\${'red'}\`; + const Test5 = styled.div.withConfig({ displayName: "Test5" }) \`width:100%;//\${'red'}\${'blue'}\`; + const Test6 = styled.div.withConfig({ displayName: "Test6" }) \`background:url("https://google.com");width:100%;\${'green'}//\${'red'}\${'blue'}\`; + const Test7 = styled.div.withConfig({ displayName: "Test7" }) \`background:url("https://google.com");width:\${p => p.props.width};\${'green'}//\${'red'}\${'blue'} + height:\${p => p.props.height};\`; + const Test8 = styled.dev.withConfig({ displayName: "Test8" }) \`color:/*\${'red'}*/blue;\`; + const Test9 = styled.dev.withConfig({ displayName: "Test9" }) \`color://\${'red'} + blue\`; + export {}; + + `; diff --git a/src/__tests__/baselines/minification/simple.ts.baseline b/src/__tests__/baselines/minification/simple.ts.baseline index 78f6ee9..8fbab68 100644 --- a/src/__tests__/baselines/minification/simple.ts.baseline +++ b/src/__tests__/baselines/minification/simple.ts.baseline @@ -187,5 +187,54 @@ TypeScript after transform: styled.div \`;" : "' : ';\`; +TypeScript after transpile module: + + // splits a line by potential comment starts and joins until one is an actual comment + // \`abc def\` + styled.div \`abc def\`; + // ignores comment markers that are inside strings + // \`abc def"//"ghi\\'//\\'jkl\` + styled.div \`abc def"//"ghi'//'jkl\`; + // \`abc def"//"\` + styled.div \`abc def"//"\`; + // ignores comment markers that are inside parantheses + // \`bla (//) bla\` + styled.div \`bla (//)bla\`; + // ignores even unescaped URLs + // \`https://test.com\` + styled.div \`https:\`; + // removes multi-line comments + // \`this is a test\` + styled.div \`this is a test\`; + // joins all lines of code + // \`this is a test\` + styled.div \`this is a test\`; + // removes line comments filling an entire line + // \`line one{line:two;}\` + styled.div \`line one{line:two;}\`; + // removes line comments at the end of lines of code + // \`valid line with out comments\` + styled.div \`valid line with out comments\`; + // preserves multi-line comments starting with /*! + // \`this is a /*! dont ignore me please */ test\` + styled.div \`this is a test\`; + // returns the indices of removed placeholders (expressions) + // \`this is some input with \${placeholder1} and //\${placeholder2}\` + styled.div \`this is some input with \${placeholder1} and//\${placeholder2}\`; + // works with raw escape codes + // \`this\\\\nis\\\\na \\\\ntest\` + styled.div \`this\\\\nis\\\\na \\\\ntest\`; + // \`this\\nis\\na \\ntest\` + styled.div \`this is a test\`; + // \`this is a test\` + styled.div \`this is a test\`; + // removes spaces around symbols + // \`;:{},;\` + styled.div \`;:{},;\`; + // ignores symbols inside strings + // \`;" : "\\' : \\';\` + styled.div \`;" : "' : ';\`; + + `; diff --git a/src/__tests__/baselines/minification/simple2.ts.baseline b/src/__tests__/baselines/minification/simple2.ts.baseline index 3697adc..77017e7 100644 --- a/src/__tests__/baselines/minification/simple2.ts.baseline +++ b/src/__tests__/baselines/minification/simple2.ts.baseline @@ -43,5 +43,17 @@ TypeScript after transform: styled.div \`a b ( c )d\`; // \`a b ( c )d\` +TypeScript after transpile module: + + // spaces before and after ' " ( ) + styled.div \`a b" c "d\`; // \`a b" c "d\` + styled.div \`a b' c 'd\`; // \`a b' c 'd\` + styled.div \`a b( c )d\`; // \`a b( c )d\` + styled.div \`a b " c "d\`; // \`a b " c "d\` + styled.div \`a b ' c 'd\`; // \`a b ' c 'd\` + styled.div \`a b ( c )d\`; // \`a b ( c )d\` + export {}; + + `; diff --git a/src/__tests__/baselines/ssr/issue33.ts.baseline b/src/__tests__/baselines/ssr/issue33.ts.baseline index 8051f5b..203ccdc 100644 --- a/src/__tests__/baselines/ssr/issue33.ts.baseline +++ b/src/__tests__/baselines/ssr/issue33.ts.baseline @@ -45,5 +45,13 @@ TypeScript after transform: const Button4 = _.extend \` color: red \`; +TypeScript after transpile module: + + const Button1 = Button.extend \` color: red \`; + const Button2 = $.extend \` color: red \`; + const Button3 = jQuery.extend \` color: red \`; + const Button4 = _.extend \` color: red \`; + + `; diff --git a/src/__tests__/baselines/ssr/multiple-components.tsx.baseline b/src/__tests__/baselines/ssr/multiple-components.tsx.baseline index 23386a9..194f444 100644 --- a/src/__tests__/baselines/ssr/multiple-components.tsx.baseline +++ b/src/__tests__/baselines/ssr/multiple-components.tsx.baseline @@ -24,7 +24,7 @@ Source code: TypeScript before transform: - import styled from "styled-components"; + import styled from 'styled-components'; export function createButtons() { const A = styled.button \` color: red; \`; const B = styled(A) \` color: blue; \`; @@ -41,13 +41,28 @@ TypeScript after transform: import styled from 'styled-components'; export function createButtons() { - const A = styled.button.withConfig({ displayName: "A", componentId: "sc-hana72" }) \` color: red; \`; - const B = styled(A).withConfig({ displayName: "B", componentId: "sc-ke4nds" }) \` color: blue; \`; + const A = styled.button.withConfig({ displayName: "A", componentId: "-hana72" }) \` color: red; \`; + const B = styled(A).withConfig({ displayName: "B", componentId: "-ke4nds" }) \` color: blue; \`; + return { A, B }; + } + export function createDivs() { + const A = styled.div.withConfig({ displayName: "A", componentId: "-1q7vmnt" }) \` color: green; \`; + const B = styled(A).withConfig({ displayName: "B", componentId: "-7q8oop" }) \` color: yellow; \`; + return { A, B }; + } + + +TypeScript after transpile module: + + import styled from 'styled-components'; + export function createButtons() { + const A = styled.button.withConfig({ displayName: "A", componentId: "-67koye" }) \` color: red; \`; + const B = styled(A).withConfig({ displayName: "B", componentId: "-1svbc9u" }) \` color: blue; \`; return { A, B }; } export function createDivs() { - const A = styled.div.withConfig({ displayName: "A", componentId: "sc-1q7vmnt" }) \` color: green; \`; - const B = styled(A).withConfig({ displayName: "B", componentId: "sc-7q8oop" }) \` color: yellow; \`; + const A = styled.div.withConfig({ displayName: "A", componentId: "-uo2lv8" }) \` color: green; \`; + const B = styled(A).withConfig({ displayName: "B", componentId: "-1cxyj9q" }) \` color: yellow; \`; return { A, B }; } diff --git a/src/__tests__/baselines/ssr/sample1.ts.baseline b/src/__tests__/baselines/ssr/sample1.ts.baseline index 50ae487..d8493cd 100644 --- a/src/__tests__/baselines/ssr/sample1.ts.baseline +++ b/src/__tests__/baselines/ssr/sample1.ts.baseline @@ -40,7 +40,7 @@ Source code: TypeScript before transform: - import styled from "styled-components"; + import styled from 'styled-components'; const Button = styled.button \` color: red; \`; @@ -60,7 +60,7 @@ TypeScript before transform: export const SmallButton = Button.extend \` font-size: .7em; \`; - const MiniButton = styled(SmallButton).attrs({ size: "mini" }) \` + const MiniButton = styled(SmallButton).attrs({ size: 'mini' }) \` font-size: .1em; \`; @@ -68,26 +68,52 @@ TypeScript before transform: TypeScript after transform: import styled from 'styled-components'; - const Button = styled.button.withConfig({ displayName: "Button", componentId: "sc-1okqsxw" }) \` + const Button = styled.button.withConfig({ displayName: "Button", componentId: "-1okqsxw" }) \` color: red; \`; declare const nonStyled: any; const NonButton = nonStyled.button \` yo \`; - const OtherButton = styled(Button).withConfig({ displayName: "OtherButton", componentId: "sc-ce0fkl" }) \` + const OtherButton = styled(Button).withConfig({ displayName: "OtherButton", componentId: "-ce0fkl" }) \` + color: blue; + \`; + const SuperButton = Button.extend \` + color: super; + \`; + export default styled.link.withConfig({ componentId: "-vba0dl" }) \` + color: black; + \`; + export const SmallButton = Button.extend \` + font-size: .7em; + \`; + const MiniButton = styled(SmallButton).attrs({ size: 'mini' }).withConfig({ displayName: "MiniButton", componentId: "-ndnumj" }) \` + font-size: .1em; + \`; + + +TypeScript after transpile module: + + import styled from 'styled-components'; + const Button = styled.button.withConfig({ displayName: "Button", componentId: "-13dat8f" }) \` + color: red; + \`; + const NonButton = nonStyled.button \` + yo + \`; + const OtherButton = styled(Button).withConfig({ displayName: "OtherButton", componentId: "-1pbo6g5" }) \` color: blue; \`; const SuperButton = Button.extend \` color: super; \`; - export default styled.link.withConfig({ componentId: "sc-vba0dl" }) \` + export default styled.link.withConfig({ componentId: "-ep20on" }) \` color: black; \`; export const SmallButton = Button.extend \` font-size: .7em; \`; - const MiniButton = styled(SmallButton).attrs({ size: "mini" }).withConfig({ displayName: "MiniButton", componentId: "sc-ndnumj" }) \` + const MiniButton = styled(SmallButton).attrs({ size: 'mini' }).withConfig({ displayName: "MiniButton", componentId: "-1cgykmr" }) \` font-size: .1em; \`; diff --git a/src/__tests__/baselines/ssr/sample2.ts.baseline b/src/__tests__/baselines/ssr/sample2.ts.baseline index 65b986a..6036a86 100644 --- a/src/__tests__/baselines/ssr/sample2.ts.baseline +++ b/src/__tests__/baselines/ssr/sample2.ts.baseline @@ -15,7 +15,7 @@ Source code: TypeScript before transform: - import styled from "styled-components"; + import styled from 'styled-components'; const styled2 = styled; const NonButton = styled.button; const NonStyled = styled \` color: red; \`; @@ -28,7 +28,16 @@ TypeScript after transform: const styled2 = styled; const NonButton = styled.button; const NonStyled = styled \` color: red; \`; - const Link = styled(NonStyled).withConfig({ displayName: "Link", componentId: "sc-1xlc242" }) \` color: red; \`; + const Link = styled(NonStyled).withConfig({ displayName: "Link", componentId: "-1xlc242" }) \` color: red; \`; + + +TypeScript after transpile module: + + import styled from 'styled-components'; + const styled2 = styled; + const NonButton = styled.button; + const NonStyled = styled \` color: red; \`; + const Link = styled(NonStyled).withConfig({ displayName: "Link", componentId: "-z7xxm1" }) \` color: red; \`; diff --git a/src/__tests__/baselines/ssr/sample3.tsx.baseline b/src/__tests__/baselines/ssr/sample3.tsx.baseline index 1292317..ba0b8d9 100644 --- a/src/__tests__/baselines/ssr/sample3.tsx.baseline +++ b/src/__tests__/baselines/ssr/sample3.tsx.baseline @@ -24,14 +24,14 @@ Source code: TypeScript before transform: - import * as React from "react"; - import styled from "../themed-styled"; - import { SmallButton } from "./sample1"; + import * as React from 'react'; + import styled from '../themed-styled'; + import { SmallButton } from './sample1'; interface LabelProps { size: number; } const CustomLabel = styled.label \` - font-size: \${(props: LabelProps) => props.size + "px"} + font-size: \${(props: LabelProps) => props.size + 'px'} \`; const LabeledLink = () => ; export default CustomLabel; @@ -45,12 +45,22 @@ TypeScript after transform: interface LabelProps { size: number; } - const CustomLabel = styled.label.withConfig({ displayName: "CustomLabel", componentId: "sc-1ydgk9x" }) \` + const CustomLabel = styled.label.withConfig({ displayName: "CustomLabel", componentId: "-1ydgk9x" }) \` font-size: \${(props: LabelProps) => props.size + 'px'} \`; const LabeledLink = () => ; export default CustomLabel; +TypeScript after transpile module: + + import styled from '../themed-styled'; + const CustomLabel = styled.label.withConfig({ displayName: "CustomLabel", componentId: "-xc3x4h" }) \` + font-size: \${(props) => props.size + 'px'} + \`; + const LabeledLink = () => />;; + export default CustomLabel; + + `; diff --git a/src/__tests__/baselines/ssr/style-objects.ts.baseline b/src/__tests__/baselines/ssr/style-objects.ts.baseline index 623e570..436e284 100644 --- a/src/__tests__/baselines/ssr/style-objects.ts.baseline +++ b/src/__tests__/baselines/ssr/style-objects.ts.baseline @@ -42,52 +42,77 @@ TypeScript before transform: declare const styled: any; const Button = styled.button({ - color: "red" + color: 'red' }); declare const nonStyled: any; const NonButton = nonStyled.button({ - color: "red" + color: 'red' }); const OtherButton = styled(Button)({ - color: "blue" + color: 'blue' }); const SuperButton = Button.extend({ - color: "super" + color: 'super' }); export default styled.link({ - color: "black" + color: 'black' }); export const SmallButton = Button.extend({ - fontSize: ".7em" + fontSize: '.7em' }); - const MiniButton = styled(SmallButton).attrs({ size: "mini" })({ - fontSize: ".1em" + const MiniButton = styled(SmallButton).attrs({ size: 'mini' })({ + fontSize: '.1em' }); TypeScript after transform: declare const styled: any; - const Button = styled.button.withConfig({ displayName: "Button", componentId: "sc-7b7p9e" })({ + const Button = styled.button.withConfig({ displayName: "Button", componentId: "-7b7p9e" })({ color: 'red' }); declare const nonStyled: any; const NonButton = nonStyled.button({ color: 'red' }); - const OtherButton = styled(Button).withConfig({ displayName: "OtherButton", componentId: "sc-14ah7t" })({ + const OtherButton = styled(Button).withConfig({ displayName: "OtherButton", componentId: "-14ah7t" })({ + color: 'blue' + }); + const SuperButton = Button.extend({ + color: 'super' + }); + export default styled.link.withConfig({ componentId: "-8xjslt" })({ + color: 'black' + }); + export const SmallButton = Button.extend({ + fontSize: '.7em' + }); + const MiniButton = styled(SmallButton).attrs({ size: 'mini' }).withConfig({ displayName: "MiniButton", componentId: "-ad4g7l" })({ + fontSize: '.1em' + }); + + +TypeScript after transpile module: + + const Button = styled.button.withConfig({ displayName: "Button", componentId: "-13dat8f" })({ + color: 'red' + }); + const NonButton = nonStyled.button({ + color: 'red' + }); + const OtherButton = styled(Button).withConfig({ displayName: "OtherButton", componentId: "-1pbo6g5" })({ color: 'blue' }); const SuperButton = Button.extend({ color: 'super' }); - export default styled.link.withConfig({ componentId: "sc-8xjslt" })({ + export default styled.link.withConfig({ componentId: "-ep20on" })({ color: 'black' }); export const SmallButton = Button.extend({ fontSize: '.7em' }); - const MiniButton = styled(SmallButton).attrs({ size: "mini" }).withConfig({ displayName: "MiniButton", componentId: "sc-ad4g7l" })({ + const MiniButton = styled(SmallButton).attrs({ size: 'mini' }).withConfig({ displayName: "MiniButton", componentId: "-1cgykmr" })({ fontSize: '.1em' }); diff --git a/src/__tests__/expectTransform.ts b/src/__tests__/expectTransform.ts index a00e631..0c0a460 100644 --- a/src/__tests__/expectTransform.ts +++ b/src/__tests__/expectTransform.ts @@ -11,6 +11,7 @@ interface TransformBaseline { content: string; source: string; transformed: string; + transpiled: string; } const serializer = { @@ -29,6 +30,10 @@ TypeScript after transform: ${indent(obj.transformed)} +TypeScript after transpile module: + +${indent(obj.transpiled)} + ` }; @@ -36,17 +41,28 @@ addSerializer(serializer); export function expectTransform(transformer: ts.TransformerFactory, filename: string, path: string, outpath: string) { const content = fs.readFileSync(path + '/' + filename).toString(); - const sourceFile = ts.createSourceFile(filename, content, ts.ScriptTarget.Latest); + const sourceFile = ts.createSourceFile(filename, content, ts.ScriptTarget.Latest, /* setParentNodes */ true); const source = printer.printFile(sourceFile); const transformedFile = ts.transform(sourceFile, [transformer]).transformed[0]; const transformed = printer.printFile(transformedFile); + const transpileOutput = ts.transpileModule(content, { + compilerOptions: { + target: ts.ScriptTarget.Latest + }, + transformers: { + before: [transformer] + } + }) + const transpiled = transpileOutput.outputText + const snapshot: TransformBaseline = { type: 'transform-baseline', filename, content, source, - transformed + transformed, + transpiled }; expect(snapshot).toMatchSpecificSnapshot(outpath + '/' + filename + '.baseline'); diff --git a/src/createTransformer.ts b/src/createTransformer.ts index 8955b5b..27bbc29 100644 --- a/src/createTransformer.ts +++ b/src/createTransformer.ts @@ -21,15 +21,17 @@ import { minifyTemplate } from './minify'; * styled(Component) * styled('tag') * styledFunction.attrs(attributes) -*/ -function isStyledFunction(node: ts.Node, identifiers: CustomStyledIdentifiers): boolean { + */ +function isStyledFunction( + node: ts.Node, + identifiers: CustomStyledIdentifiers +): node is ts.PropertyAccessExpression | ts.CallExpression { if (isPropertyAccessExpression(node)) { if (isStyledObject(node.expression, identifiers)) { return true; } - if (isStyledExtendIdentifier(node.name.text, identifiers) - && isValidComponent(node.expression)) { + if (isStyledExtendIdentifier(node.name.text, identifiers) && isValidComponent(node.expression)) { return true; } @@ -37,7 +39,6 @@ function isStyledFunction(node: ts.Node, identifiers: CustomStyledIdentifiers): } if (isCallExpression(node) && node.arguments.length === 1) { - if (isStyledObject(node.expression, identifiers)) { return true; } @@ -71,7 +72,7 @@ function isValidTagName(name: string) { } function isValidComponentName(name: string) { - return isLetter(name[0]) && (name[0] === name[0].toUpperCase()); + return isLetter(name[0]) && name[0] === name[0].toUpperCase(); } function isStyledAttrsIdentifier(name: string, { attrs: attrsIdentifiers = ['attrs'] }: CustomStyledIdentifiers) { @@ -79,9 +80,12 @@ function isStyledAttrsIdentifier(name: string, { attrs: attrsIdentifiers = ['att } function isStyledAttrs(node: ts.Node, identifiers: CustomStyledIdentifiers) { - return node && isPropertyAccessExpression(node) - && isStyledAttrsIdentifier(node.name.text, identifiers) - && isStyledFunction((node as ts.PropertyAccessExpression).expression, identifiers); + return ( + node && + isPropertyAccessExpression(node) && + isStyledAttrsIdentifier(node.name.text, identifiers) && + isStyledFunction((node as ts.PropertyAccessExpression).expression, identifiers) + ); } function isStyledKeyframesIdentifier(name: string, { keyframes = ['keyframes'] }: CustomStyledIdentifiers) { @@ -92,7 +96,10 @@ function isStyledCssIdentifier(name: string, { css = ['css'] }: CustomStyledIden return css.indexOf(name) >= 0; } -function isStyledCreateGlobalStyleIdentifier(name: string, { createGlobalStyle = ['createGlobalStyle'] }: CustomStyledIdentifiers) { +function isStyledCreateGlobalStyleIdentifier( + name: string, + { createGlobalStyle = ['createGlobalStyle'] }: CustomStyledIdentifiers +) { return createGlobalStyle.indexOf(name) >= 0; } @@ -101,55 +108,59 @@ function isStyledExtendIdentifier(name: string, { extend = [] }: CustomStyledIde } function isMinifyableStyledFunction(node: ts.Node, identifiers: CustomStyledIdentifiers) { - return isStyledFunction(node, identifiers) - || ( - isIdentifier(node) - && ( - isStyledKeyframesIdentifier(node.text, identifiers) - || isStyledCssIdentifier(node.text, identifiers) - || isStyledCreateGlobalStyleIdentifier(node.text, identifiers) - ) - ); + return ( + isStyledFunction(node, identifiers) || + (isIdentifier(node) && + (isStyledKeyframesIdentifier(node.text, identifiers) || + isStyledCssIdentifier(node.text, identifiers) || + isStyledCreateGlobalStyleIdentifier(node.text, identifiers))) + ); } function defaultGetDisplayName(filename: string, bindingName: string | undefined): string | undefined { return bindingName; } -export function createTransformer(options?: Partial): ts.TransformerFactory +export function createTransformer(options?: Partial): ts.TransformerFactory; export function createTransformer({ getDisplayName = defaultGetDisplayName, identifiers = {}, ssr = true, displayName = true, minify = false, - componentIdPrefix = '', -} : Partial = {}) { - + componentIdPrefix = '' +}: Partial = {}) { /** * Infers display name of a styled component. * Recognizes the following patterns: * * (const|var|let) ComponentName = styled... * export default styled... - */ - function getDisplayNameFromNode(node: ts.Node, componentIdPrefix?: string): string | undefined { + */ + function getDisplayNameFromNode(node: ts.Node, sourceFile: ts.SourceFile): string | undefined { if (isVariableDeclaration(node) && isIdentifier(node.name)) { - return (!!componentIdPrefix ? `${componentIdPrefix}-` : '') + getDisplayName(node.getSourceFile().fileName, node.name.text); + return (componentIdPrefix ? componentIdPrefix + '-' : '') + getDisplayName(sourceFile.fileName, node.name.text); } if (isExportAssignment(node)) { - return getDisplayName(node.getSourceFile().fileName, undefined); + return getDisplayName(sourceFile.fileName, undefined); } return undefined; } - function getIdFromNode(node: ts.Node, sourceRoot: string | undefined, position: number, componentIdPrefix?: string): string | undefined { + function getIdFromNode( + node: ts.Node, + sourceRoot: string | undefined, + position: number, + sourceFile: ts.SourceFile + ): string | undefined { if ((isVariableDeclaration(node) && isIdentifier(node.name)) || isExportAssignment(node)) { - const fileName = node.getSourceFile().fileName; - const filePath = sourceRoot ? path.relative(sourceRoot, fileName).replace(path.sep, path.posix.sep) : fileName; - return `${!!componentIdPrefix ? componentIdPrefix : 'sc'}-` + hash(`${getDisplayNameFromNode(node)}${filePath}${position}`); + const fileName = sourceFile.fileName; + const filePath = sourceRoot + ? path.relative(sourceRoot, fileName).replace(path.sep, path.posix.sep) + : fileName; + return (componentIdPrefix ?? 'sc') + '-' + hash(`${getDisplayNameFromNode(node, sourceFile)}${filePath}${position}`); } return undefined; } @@ -157,67 +168,121 @@ export function createTransformer({ const transformer: ts.TransformerFactory = (context) => { const { sourceRoot } = context.getCompilerOptions(); - return (node) => { + return (sourceFile) => { let lastComponentPosition = 0; - const visitor: ts.Visitor = (node) => { - if ( - minify - && isTaggedTemplateExpression(node) - && isMinifyableStyledFunction(node.tag, identifiers) - ) { - const minifiedTemplate = minifyTemplate(node.template); - if (minifiedTemplate && minifiedTemplate !== node.template) { - const newNode = ts.createTaggedTemplate(node.tag, node.typeArguments, minifiedTemplate); - newNode.parent = node.parent; - node = newNode; - } + const withConfig = (node: ts.Expression, properties: ts.PropertyAssignment[]) => + properties.length > 0 + ? context.factory.createCallExpression( + context.factory.createPropertyAccessExpression(node, 'withConfig'), + undefined, + [context.factory.createObjectLiteralExpression(properties)] + ) + : node; + + const createDisplayNameConfig = (displayNameValue: string | undefined) => + displayNameValue + ? [ + context.factory.createPropertyAssignment( + 'displayName', + context.factory.createStringLiteral(displayNameValue) + ), + ] + : []; + const createIdConfig = (componentId: string | undefined) => + componentId + ? [ + context.factory.createPropertyAssignment( + 'componentId', + context.factory.createStringLiteral(componentId) + ), + ] + : []; + + const transformStyledFunction = ( + binding: ts.VariableDeclaration | ts.ExportAssignment, + node: ts.Expression + ) => + withConfig(node, [ + ...(displayName ? createDisplayNameConfig(getDisplayNameFromNode(binding, sourceFile)) : []), + ...(ssr + ? createIdConfig(getIdFromNode(binding, sourceRoot, ++lastComponentPosition, sourceFile)) + : []), + ]); + + const transformTemplateLiteral = (templateLiteral: ts.TemplateLiteral) => + minify ? minifyTemplate(templateLiteral, context.factory) : templateLiteral; + + const transformTaggedTemplateExpression = (node: ts.TaggedTemplateExpression) => + isMinifyableStyledFunction(node.tag, identifiers) + ? context.factory.updateTaggedTemplateExpression( + node, + node.tag, + node.typeArguments, + transformTemplateLiteral(node.template) + ) + : node; + + const transformBindingExpression = ( + binding: ts.VariableDeclaration | ts.ExportAssignment, + node: ts.Expression + ) => { + if (isTaggedTemplateExpression(node) && isStyledFunction(node.tag, identifiers)) { + return context.factory.updateTaggedTemplateExpression( + node, + transformStyledFunction(binding, node.tag), + node.typeArguments, + transformTemplateLiteral(node.template) + ); } - - if ( - node.parent - && ( - isTaggedTemplateExpression(node.parent) && node.parent.tag === node - || isCallExpression(node.parent) - ) - && node.parent.parent - && (isVariableDeclaration(node.parent.parent) || isExportAssignment(node.parent.parent)) - && isStyledFunction(node, identifiers) - ) { - - const styledConfig = []; - - if (displayName) { - const displayNameValue = getDisplayNameFromNode(node.parent.parent, componentIdPrefix); - if (displayNameValue) { - styledConfig.push(ts.createPropertyAssignment('displayName', ts.createLiteral(displayNameValue))); - } - } - - if (ssr) { - const componentId = getIdFromNode(node.parent.parent, sourceRoot, ++lastComponentPosition, componentIdPrefix); - if (componentId) { - styledConfig.push(ts.createPropertyAssignment('componentId', ts.createLiteral(componentId))); - } - } - - if (styledConfig.length > 0) { - return ts.createCall( - ts.createPropertyAccess(node as ts.Expression, 'withConfig'), - undefined, - [ts.createObjectLiteral(styledConfig)]); - } + if (isCallExpression(node) && isStyledFunction(node.expression, identifiers)) { + return context.factory.updateCallExpression( + node, + transformStyledFunction(binding, node.expression), + node.typeArguments, + node.arguments + ); } - - ts.forEachChild(node, n => { - if (!n.parent) - n.parent = node; - }); - - return ts.visitEachChild(node, visitor, context); - } - - return ts.visitNode(node, visitor); + }; + + const updateNode = ( + node: T, + data: D | undefined, + updateFn: (node: T, data: D) => T + ) => (data ? updateFn(node, data) : undefined); + + const updateVariableDeclarationInitializer = (node: ts.VariableDeclaration, initializer: ts.Expression) => + context.factory.updateVariableDeclaration( + node, + node.name, + node.exclamationToken, + node.type, + initializer + ); + + const updateExportAssignmentExpression = (node: ts.ExportAssignment, expression: ts.Expression) => + context.factory.updateExportAssignment(node, node.decorators, node.modifiers, expression); + + const transformNode = (node: ts.Node) => + isVariableDeclaration(node) && node.initializer + ? updateNode( + node, + transformBindingExpression(node, node.initializer), + updateVariableDeclarationInitializer + ) + : isExportAssignment(node) + ? updateNode( + node, + transformBindingExpression(node, node.expression), + updateExportAssignmentExpression + ) + : minify && isTaggedTemplateExpression(node) + ? transformTaggedTemplateExpression(node) + : undefined; + + const visitNode: ts.Visitor = (node) => transformNode(node) || ts.visitEachChild(node, visitNode, context); + + return ts.visitNode(sourceFile, visitNode); }; }; diff --git a/src/minify.ts b/src/minify.ts index ca3112b..4faab8c 100644 --- a/src/minify.ts +++ b/src/minify.ts @@ -218,19 +218,19 @@ export function createMinifier(): (next: string, last?: boolean) => string { } } -export function minifyTemplate(templateLiteral: ts.TemplateLiteral) { +export function minifyTemplate(templateLiteral: ts.TemplateLiteral, factory: ts.NodeFactory) { const minifier = createMinifier(); if (isNoSubstitutionTemplateLiteral(templateLiteral)) { - const node = ts.createNoSubstitutionTemplateLiteral(minifier(templateLiteral.text, true)); + const node = factory.createNoSubstitutionTemplateLiteral(minifier(templateLiteral.text, true)); return node; } else if (isTemplateExpression(templateLiteral)) { - const head = ts.createTemplateHead(minifier(templateLiteral.head.text)); - const templateSpans = templateLiteral.templateSpans.map(span => ts.createTemplateSpan(span.expression, + const head = factory.createTemplateHead(minifier(templateLiteral.head.text)); + const templateSpans = templateLiteral.templateSpans.map(span => factory.createTemplateSpan(span.expression, span.literal.kind === ts.SyntaxKind.TemplateMiddle - ? ts.createTemplateMiddle(minifier(span.literal.text)) - : ts.createTemplateTail(minifier(span.literal.text, true)))); - const node = ts.createTemplateExpression(head, templateSpans); + ? factory.createTemplateMiddle(minifier(span.literal.text)) + : factory.createTemplateTail(minifier(span.literal.text, true)))); + const node = factory.createTemplateExpression(head, templateSpans); return node; } diff --git a/yarn.lock b/yarn.lock index 57ea4ae..3fda6f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3652,10 +3652,10 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -typescript@^3.3.1: - version "3.7.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae" - integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw== +typescript@~4.2: + version "4.2.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" + integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== uglify-js@^3.1.4: version "3.13.3"