From 59bfd27bf6b5d17c6d9485d8d08b0db3e42add13 Mon Sep 17 00:00:00 2001 From: Jessica Date: Mon, 26 Nov 2018 19:09:42 +0900 Subject: [PATCH 1/6] Add support to the `css` prop from babel-plugin-styled-components --- types/styled-components/index.d.ts | 20 +++++++ types/styled-components/test/index.tsx | 74 +++++++++++++++++++++++--- 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/types/styled-components/index.d.ts b/types/styled-components/index.d.ts index a842c94c63..ee64b37772 100644 --- a/types/styled-components/index.d.ts +++ b/types/styled-components/index.d.ts @@ -436,4 +436,24 @@ export class StyleSheetManager extends React.Component< StyleSheetManagerProps > {} +export type CSSIntrinsicAttributeType = + | string + | CSSObject + | FlattenSimpleInterpolation + // Sad, but because this is global, there is no way to override it with the ThemedStyledComponentsModule + // Only augmenting DefaultTheme will work for inline css prop + | FlattenInterpolation>>; + export default styled; + +declare module "react" { + interface Attributes { + // NOTE: unlike the plain javascript version, it is not possible to get access + // to the element's own attributes inside function interpolations. + // Only theme will be accessible, and only with the DefaultTheme due to the global + // nature of this declaration. + // If you are writing this inline you already have access to all the attributes anyway, + // no need for the extra indirection. + css?: import(".").CSSIntrinsicAttributeType; // tslint:disable-line whitespace + } +} diff --git a/types/styled-components/test/index.tsx b/types/styled-components/test/index.tsx index e435d90011..c152ffd66e 100644 --- a/types/styled-components/test/index.tsx +++ b/types/styled-components/test/index.tsx @@ -172,7 +172,6 @@ const styledButton = styled.button` const name = "hey"; const ThemedMyButton = withTheme(MyButton); - ; /** @@ -290,7 +289,6 @@ const ObjectStylesBox = styled.div` fontSize: 2 }}; `; - ; /** @@ -322,7 +320,6 @@ const AttrsWithOnlyNewProps = styled.h2.attrs({ as: "h1" })` `; const AttrsInputExtra = styled(AttrsInput).attrs({ autoComplete: "off" })``; - ; /** @@ -419,10 +416,8 @@ const Component = (props: WithThemeProps) => ( ); const ComponentWithTheme = withTheme(Component); - ; // ok ; // ok - {theme => }; /** @@ -610,7 +605,6 @@ const divFnRef = (ref: HTMLDivElement | null) => { const divRef = React.createRef(); const StyledDiv = styled.div``; - ; ; ; // $ExpectError @@ -771,3 +765,71 @@ async function themeAugmentation() { ); } + +// NOTE: this is needed for some tests inside cssProp, +// but actually running this module augmentation will cause +// tests elsewhere to break, and there is no way to contain it. +// Uncomment out as needed to run tests. + +// declare module "styled-components" { +// interface DefaultTheme { +// background: string; +// } +// } + +function cssProp() { + function Custom(props: React.ComponentPropsWithoutRef<"div">) { + return
; + } + + return ( + <> +
+
+
+
+
"blue"}; + `} + /> +
{ + // This requires the DefaultTheme augmentation + // // $ExpectType string + // props.theme.background; + return props.theme.background; + }}; + `} + /> + + + + + "blue"}; + `} + /> + { + // This requires the DefaultTheme augmentation + // // $ExpectType string + // props.theme.background; + return props.theme.background; + }}; + `} + /> + + ); +} From 3fc77b020c5482986330cc606cddc0981052e784 Mon Sep 17 00:00:00 2001 From: Jessica Date: Mon, 26 Nov 2018 19:22:27 +0900 Subject: [PATCH 2/6] Fix the types in rebass__grid --- types/rebass__grid/index.d.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/types/rebass__grid/index.d.ts b/types/rebass__grid/index.d.ts index 079506e631..f49d43a6c6 100644 --- a/types/rebass__grid/index.d.ts +++ b/types/rebass__grid/index.d.ts @@ -10,7 +10,7 @@ export type Omit = Pick; import { ComponentType } from "react"; -import { StyledComponent, Interpolation } from "styled-components"; +import { StyledComponent, CSSIntrinsicAttributeType } from "styled-components"; export type ResponsiveProp = number | string | Array; @@ -34,7 +34,10 @@ export interface CommonProps { px?: ResponsiveProp; py?: ResponsiveProp; theme?: any; - css?: Interpolation; + /** + * NOTE: this is not compatible with the styled-components babel plugin anymore + */ + css?: CSSIntrinsicAttributeType; } export interface BoxProps From 12b2403208f432eab01af6d45acd095fdcfb9ea6 Mon Sep 17 00:00:00 2001 From: Jessica Date: Thu, 29 Nov 2018 13:57:50 +0900 Subject: [PATCH 3/6] Simplify css attribute declaration, add jsdoc --- types/styled-components/index.d.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/types/styled-components/index.d.ts b/types/styled-components/index.d.ts index ee64b37772..2f3b6b4ec5 100644 --- a/types/styled-components/index.d.ts +++ b/types/styled-components/index.d.ts @@ -454,6 +454,11 @@ declare module "react" { // nature of this declaration. // If you are writing this inline you already have access to all the attributes anyway, // no need for the extra indirection. - css?: import(".").CSSIntrinsicAttributeType; // tslint:disable-line whitespace + /** + * If present, this React element will be converted by + * `babel-plugin-styled-components` into a styled component + * with the given css as its styles. + */ + css?: CSSIntrinsicAttributeType; } } From 38c7639b434636ebe7587b75021d047b6094db49 Mon Sep 17 00:00:00 2001 From: Jessica Date: Fri, 30 Nov 2018 19:29:09 +0900 Subject: [PATCH 4/6] Don't augment the css prop by default, check and document limitations --- types/rebass__grid/index.d.ts | 7 +-- types/rebass__grid/rebass__grid-tests.tsx | 3 ++ types/styled-components/cssprop.d.ts | 19 ++++++++ types/styled-components/index.d.ts | 54 +++++++++++++---------- types/styled-components/macro.d.ts | 5 +++ types/styled-components/test/index.tsx | 28 ++++++++++-- 6 files changed, 86 insertions(+), 30 deletions(-) create mode 100644 types/styled-components/cssprop.d.ts diff --git a/types/rebass__grid/index.d.ts b/types/rebass__grid/index.d.ts index f49d43a6c6..3f5012851f 100644 --- a/types/rebass__grid/index.d.ts +++ b/types/rebass__grid/index.d.ts @@ -10,7 +10,7 @@ export type Omit = Pick; import { ComponentType } from "react"; -import { StyledComponent, CSSIntrinsicAttributeType } from "styled-components"; +import { StyledComponent, Interpolation } from "styled-components"; export type ResponsiveProp = number | string | Array; @@ -34,10 +34,11 @@ export interface CommonProps { px?: ResponsiveProp; py?: ResponsiveProp; theme?: any; + // this is actually more powerful than the plugin because of some limitations of the transform /** - * NOTE: this is not compatible with the styled-components babel plugin anymore + * This works even without babel-plugin-styled-components. */ - css?: CSSIntrinsicAttributeType; + css?: Interpolation; } export interface BoxProps diff --git a/types/rebass__grid/rebass__grid-tests.tsx b/types/rebass__grid/rebass__grid-tests.tsx index 2cef66a972..147f3ff084 100644 --- a/types/rebass__grid/rebass__grid-tests.tsx +++ b/types/rebass__grid/rebass__grid-tests.tsx @@ -1,8 +1,11 @@ import * as React from "react"; import { Flex, Box } from "@rebass/grid"; +import { css } from "styled-components"; const Layout = () => ( ); + +const cssTest = ; diff --git a/types/styled-components/cssprop.d.ts b/types/styled-components/cssprop.d.ts new file mode 100644 index 0000000000..e19b03dc2c --- /dev/null +++ b/types/styled-components/cssprop.d.ts @@ -0,0 +1,19 @@ +import {} from "react"; +import { CSSProp } from "."; + +declare module "react" { + interface Attributes { + // NOTE: unlike the plain javascript version, it is not possible to get access + // to the element's own attributes inside function interpolations. + // Only theme will be accessible, and only with the DefaultTheme due to the global + // nature of this declaration. + // If you are writing this inline you already have access to all the attributes anyway, + // no need for the extra indirection. + /** + * If present, this React element will be converted by + * `babel-plugin-styled-components` into a styled component + * with the given css as its styles. + */ + css?: CSSProp; + } +} diff --git a/types/styled-components/index.d.ts b/types/styled-components/index.d.ts index 2f3b6b4ec5..761c48a104 100644 --- a/types/styled-components/index.d.ts +++ b/types/styled-components/index.d.ts @@ -436,29 +436,35 @@ export class StyleSheetManager extends React.Component< StyleSheetManagerProps > {} -export type CSSIntrinsicAttributeType = - | string - | CSSObject - | FlattenSimpleInterpolation - // Sad, but because this is global, there is no way to override it with the ThemedStyledComponentsModule - // Only augmenting DefaultTheme will work for inline css prop - | FlattenInterpolation>>; +/** + * The CSS prop is not declared by default in the types as it would cause 'css' to be present + * on the types of anything that uses styled-components indirectly, even if they do not use the + * babel plugin. + * + * You can load a default declaration by using writing this special import from + * a typescript file. This module does not exist in reality, which is why the {} is important: + * + * ```ts + * import {} from 'styled-components/cssprop' + * ``` + * + * Or you can declare your own module augmentation, which allows you to specify the type of Theme: + * + * ```ts + * import { CSSProp } from 'styled-components' + * + * interface MyTheme {} + * + * declare module 'react' { + * interface Attributes { + * css?: CSSProp + * } + * } + * ``` + */ +// ONLY string literals and inline invocations of css`` are supported, anything else crashes the plugin +export type CSSProp> = + string | + FlattenInterpolation>; export default styled; - -declare module "react" { - interface Attributes { - // NOTE: unlike the plain javascript version, it is not possible to get access - // to the element's own attributes inside function interpolations. - // Only theme will be accessible, and only with the DefaultTheme due to the global - // nature of this declaration. - // If you are writing this inline you already have access to all the attributes anyway, - // no need for the extra indirection. - /** - * If present, this React element will be converted by - * `babel-plugin-styled-components` into a styled component - * with the given css as its styles. - */ - css?: CSSIntrinsicAttributeType; - } -} diff --git a/types/styled-components/macro.d.ts b/types/styled-components/macro.d.ts index 08cee96a96..51f6cced26 100644 --- a/types/styled-components/macro.d.ts +++ b/types/styled-components/macro.d.ts @@ -1,2 +1,7 @@ export { default } from '.'; export * from '.'; + +/** + * Recommended: also `import {} from 'styled-components/cssprop'`, + * or augment react's `Attribute` interface with your own version. + */ diff --git a/types/styled-components/test/index.tsx b/types/styled-components/test/index.tsx index c152ffd66e..43f0f68607 100644 --- a/types/styled-components/test/index.tsx +++ b/types/styled-components/test/index.tsx @@ -16,6 +16,7 @@ import styled, { StyledComponent, ThemedStyledComponentsModule } from "styled-components"; +import {} from "styled-components/cssprop"; /** * general usage @@ -782,16 +783,34 @@ function cssProp() { return
; } + const myCss = 'background: blue;'; + return ( <>
-
-
+
+
+
+
"blue"}; @@ -808,7 +827,10 @@ function cssProp() { `} /> - + Date: Fri, 30 Nov 2018 20:32:32 +0900 Subject: [PATCH 5/6] Add missing file declaration --- types/styled-components/tsconfig.json | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/types/styled-components/tsconfig.json b/types/styled-components/tsconfig.json index 22af0d4a13..fb9b5a0f7b 100644 --- a/types/styled-components/tsconfig.json +++ b/types/styled-components/tsconfig.json @@ -3,20 +3,26 @@ "baseUrl": "../", "forceConsistentCasingInFileNames": true, "jsx": "react", - "lib": ["es6", "dom"], + "lib": [ + "es6", + "dom" + ], "module": "commonjs", "noEmit": true, "noImplicitAny": true, "noImplicitThis": true, "strictFunctionTypes": true, "strictNullChecks": true, - "typeRoots": ["../"], + "typeRoots": [ + "../" + ], "types": [] }, "files": [ "index.d.ts", "macro.d.ts", + "cssprop.d.ts", "test/index.tsx", "test/macro.tsx" ] -} +} \ No newline at end of file From c5bc70efc08abdaebef17c425bbe9edbaf9cbd84 Mon Sep 17 00:00:00 2001 From: Jessica Date: Fri, 30 Nov 2018 20:35:04 +0900 Subject: [PATCH 6/6] Fix lint --- types/styled-components/index.d.ts | 10 +++++----- types/styled-components/test/index.tsx | 17 +++++++---------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/types/styled-components/index.d.ts b/types/styled-components/index.d.ts index 761c48a104..7007a3d829 100644 --- a/types/styled-components/index.d.ts +++ b/types/styled-components/index.d.ts @@ -440,21 +440,21 @@ export class StyleSheetManager extends React.Component< * The CSS prop is not declared by default in the types as it would cause 'css' to be present * on the types of anything that uses styled-components indirectly, even if they do not use the * babel plugin. - * + * * You can load a default declaration by using writing this special import from * a typescript file. This module does not exist in reality, which is why the {} is important: - * + * * ```ts * import {} from 'styled-components/cssprop' * ``` - * + * * Or you can declare your own module augmentation, which allows you to specify the type of Theme: - * + * * ```ts * import { CSSProp } from 'styled-components' * * interface MyTheme {} - * + * * declare module 'react' { * interface Attributes { * css?: CSSProp diff --git a/types/styled-components/test/index.tsx b/types/styled-components/test/index.tsx index 43f0f68607..6e8715730e 100644 --- a/types/styled-components/test/index.tsx +++ b/types/styled-components/test/index.tsx @@ -783,15 +783,16 @@ function cssProp() { return
; } - const myCss = 'background: blue;'; + const myCss = "background: blue;"; return ( <>
-
+ {/* + For some reason $ExpectError doesn't work on this expression. + Only strings work, objects crash the plugin. +
+ */}
-