[styled-components] Upgrade to 4.0.0 (#29389)

* [styled-components] Upgrade to 4.0.0

* [styled-components] Remove 2.9 dependent test, lower ts version

* [styled-components] Add ThemeConsumer

* [styled-components] Remove unused import in test

* [styled-components] Add v3 typings

* [styled-components] Fix themed keyframes return type

* Loosen up type for as prop, add extra test case

* Remove unnecessary generic prop
This commit is contained in:
Adam Lavin
2018-10-09 23:48:36 +01:00
committed by Andy
parent 163df17a1f
commit fe3bb114a3
6 changed files with 862 additions and 49 deletions

View File

@@ -1,7 +1,8 @@
// Type definitions for styled-components 3.0
// Type definitions for styled-components 4.0
// Project: https://github.com/styled-components/styled-components
// Definitions by: Igor Oleinikov <https://github.com/Igorbek>
// Ihor Chulinda <https://github.com/Igmat>
// Adam Lavin <https://github.com/lavoaster>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.8
@@ -17,10 +18,8 @@ export type ThemedStyledProps<P, T> = P & ThemeProps<T>;
export type StyledProps<P> = ThemedStyledProps<P, any>;
export type ThemedOuterStyledProps<P, T> = P & {
as?: React.ReactType | keyof JSX.IntrinsicElements;
theme?: T;
innerRef?:
| ((instance: any) => void)
| React.RefObject<HTMLElement | SVGElement | React.Component>;
};
export type OuterStyledProps<P> = ThemedOuterStyledProps<P, any>;
@@ -52,10 +51,15 @@ type Attrs<P, A extends Partial<P>, T> = {
[K in keyof A]: ((props: ThemedStyledProps<P, T>) => A[K]) | A[K]
};
export type ThemedGlobalStyledClassProps<P, T> = P & {
theme?: T;
};
export interface GlobalStyleClass<P, T>
extends React.ComponentClass<ThemedGlobalStyledClassProps<P, T>> {}
export interface StyledComponentClass<P, T, O = P>
extends React.ComponentClass<ThemedOuterStyledProps<O, T>> {
extend: ThemedStyledFunction<P, T, O>;
withComponent<K extends keyof JSX.IntrinsicElements>(
tag: K,
): StyledComponentClass<
@@ -148,14 +152,17 @@ export interface ThemedStyledComponentsModule<T> {
keyframes(
strings: TemplateStringsArray,
...interpolations: SimpleInterpolation[]
): string;
injectGlobal(
): Keyframes;
createGlobalStyle<P = {}>(
strings: TemplateStringsArray,
...interpolations: SimpleInterpolation[]
): void;
...interpolations: Array<Interpolation<ThemedStyledProps<P, T>>>
): GlobalStyleClass<P, T>;
withTheme: WithThemeFnInterface<T>;
ThemeProvider: ThemeProviderComponent<T>;
ThemeConsumer: ThemeConsumerComponent<T>;
}
declare const styled: StyledInterface;
@@ -168,17 +175,26 @@ export type BaseWithThemeFnInterface<T> = <P extends { theme?: T }>(
export type WithThemeFnInterface<T> = BaseWithThemeFnInterface<Extract<keyof T, string> extends never ? any : T>;
export const withTheme: WithThemeFnInterface<DefaultTheme>;
export interface ThemeConsumerProps<T> {
children(theme: T): React.ReactNode;
}
export type BaseThemeConsumerComponent<T> = React.ComponentClass<ThemeConsumerProps<T>>;
export type ThemeConsumerComponent<T> = BaseThemeConsumerComponent<Extract<keyof T, string> extends never ? any : T>;
export const ThemeConsumer: ThemeConsumerComponent<object>;
export interface Keyframes {
getName(): string;
}
export function keyframes(
strings: TemplateStringsArray,
...interpolations: SimpleInterpolation[]
): string;
): Keyframes;
export function injectGlobal(
export function createGlobalStyle<P = {}>(
strings: TemplateStringsArray,
...interpolations: SimpleInterpolation[]
): void;
export function consolidateStreamedStyles(): void;
...interpolations: Array<Interpolation<ThemedStyledProps<P, DefaultTheme>>>
): GlobalStyleClass<P, DefaultTheme>;
export function isStyledComponent(
target: any,

View File

@@ -4,7 +4,7 @@ import * as ReactDOMServer from 'react-dom/server';
import styled, {
css,
injectGlobal,
createGlobalStyle,
isStyledComponent,
keyframes,
ServerStyleSheet,
@@ -12,6 +12,7 @@ import styled, {
ThemeProps,
ThemeProvider,
withTheme,
ThemeConsumer,
} from 'styled-components';
/**
@@ -100,7 +101,7 @@ const theme = {
main: 'mediumseagreen',
};
injectGlobal`
const ExampleGlobalStyle = createGlobalStyle`
@font-face {
font-family: 'Operator Mono';
src: url('../fonts/Operator-Mono.ttf');
@@ -115,6 +116,7 @@ class Example extends React.Component {
render() {
return (
<ThemeProvider theme={theme}>
<ExampleGlobalStyle />
<Wrapper>
<Title>
Hello World, this is my first styled component!
@@ -139,12 +141,6 @@ const cssWithValues2 = css`
${[cssWithValues1, cssWithValues1]}
font-weight: ${'bold'};
`;
// injectGlobal accepts simple interpolations if they're not using functions
injectGlobal`
${'font-size'}: ${10}pt;
${cssWithValues1}
${[cssWithValues1, cssWithValues2]}
`;
// css which uses function interpolations with common props
const cssWithFunc1 = css`
@@ -161,12 +157,6 @@ const styledButton = styled.button`
${cssWithFunc1} ${[cssWithFunc1, cssWithFunc2]}
${() => [cssWithFunc1, cssWithFunc2]}
`;
// css with function interpolations cannot be used in injectGlobal
/*
injectGlobal`
${cssWithFunc1}
`;
*/
const name = 'hey';
@@ -332,25 +322,6 @@ styled(C); // used to fail; see issue trail linked below
// https://github.com/Microsoft/TypeScript/issues/21175
// https://github.com/styled-components/styled-components/pull/1427
/**
* extend
*/
const ExtendButton = styled.button`
color: palevioletred;
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
// We're extending Button with some extra styles
const TomatoExtendButton = ExtendButton.extend`
color: tomato;
border-color: tomato;
`;
/**
* function themes
*/
@@ -423,6 +394,10 @@ const ComponentWithTheme = withTheme(Component);
<ComponentWithTheme text={'hi'} />; // ok
<ComponentWithTheme text={'hi'} theme={{ color: 'red' }} />; // ok
<ThemeConsumer>
{(theme) => <Component text="hi" theme={theme} />}
</ThemeConsumer>;
/**
* isStyledComponent utility
*/
@@ -546,3 +521,37 @@ const test = () => [
<WithComponentFirstStyledA color={'black'} />,
<WithComponentFirstStyledB b={2} color={'black'} />,
];
// 4.0 With Component
const asTest = (
<>
<WithComponentH1 as="h2" />
<WithComponentH1 as={WithComponentH2} />
</>
);
interface TestContainerProps {
size: 'big' | 'small';
test?: boolean;
}
const TestContainer = ({ size, test }: TestContainerProps) => {
return null;
};
const StyledTestContainer = styled(TestContainer)`
background: red;
`;
interface Test2ContainerProps {
type: 'foo' | 'bar';
}
class Test2Container extends React.Component<Test2ContainerProps> {
render() {
return null;
}
}
const containerTest = (
<StyledTestContainer as={Test2Container} size="small" />
);

215
types/styled-components/v3/index.d.ts vendored Normal file
View File

@@ -0,0 +1,215 @@
// Type definitions for styled-components 3.0
// Project: https://github.com/styled-components/styled-components
// Definitions by: Igor Oleinikov <https://github.com/Igorbek>
// Ihor Chulinda <https://github.com/Igmat>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.8
/// <reference types="node" />
import * as React from 'react';
export interface ThemeProps<T> {
theme: T;
}
export type ThemedStyledProps<P, T> = P & ThemeProps<T>;
export type StyledProps<P> = ThemedStyledProps<P, any>;
export type ThemedOuterStyledProps<P, T> = P & {
theme?: T;
innerRef?:
| ((instance: any) => void)
| React.RefObject<HTMLElement | SVGElement | React.Component>;
};
export type OuterStyledProps<P> = ThemedOuterStyledProps<P, any>;
export type FalseyValue = undefined | null | false;
export type Interpolation<P> =
| FlattenInterpolation<P>
| ReadonlyArray<
FlattenInterpolation<P> | ReadonlyArray<FlattenInterpolation<P>>
>;
export type FlattenInterpolation<P> =
| InterpolationValue
| InterpolationFunction<P>;
export type InterpolationValue =
| string
| number
| Styles
| FalseyValue
| StyledComponentClass<any, any>;
export type SimpleInterpolation =
| InterpolationValue
| ReadonlyArray<InterpolationValue | ReadonlyArray<InterpolationValue>>;
export interface Styles {
[ruleOrSelector: string]: string | number | Styles;
}
export type InterpolationFunction<P> = (props: P) => Interpolation<P>;
type Attrs<P, A extends Partial<P>, T> = {
[K in keyof A]: ((props: ThemedStyledProps<P, T>) => A[K]) | A[K]
};
export interface StyledComponentClass<P, T, O = P>
extends React.ComponentClass<ThemedOuterStyledProps<O, T>> {
extend: ThemedStyledFunction<P, T, O>;
withComponent<K extends keyof JSX.IntrinsicElements>(
tag: K,
): StyledComponentClass<
JSX.IntrinsicElements[K],
T,
JSX.IntrinsicElements[K] & O
>;
withComponent<U = {}>(
element: React.ComponentType<U>,
): StyledComponentClass<U, T, U & O>;
}
export interface ThemedStyledFunction<P, T, O = P> {
(
strings: TemplateStringsArray,
...interpolations: Array<Interpolation<ThemedStyledProps<P, T>>>
): StyledComponentClass<P, T, O>;
<U>(
strings: TemplateStringsArray,
...interpolations: Array<Interpolation<ThemedStyledProps<P & U, T>>>
): StyledComponentClass<P & U, T, O & U>;
attrs<U, A extends Partial<P & U> = {}>(
attrs: Attrs<P & U, A, T>,
): ThemedStyledFunction<DiffBetween<A, P & U>, T, DiffBetween<A, O & U>>;
}
export type StyledFunction<P> = ThemedStyledFunction<P, any>;
type ThemedStyledComponentFactories<T> = {
[TTag in keyof JSX.IntrinsicElements]: ThemedStyledFunction<
JSX.IntrinsicElements[TTag],
T
>
};
export interface ThemedBaseStyledInterface<T>
extends ThemedStyledComponentFactories<T> {
<P, TTag extends keyof JSX.IntrinsicElements>(
tag: TTag,
): ThemedStyledFunction<P, T, P & JSX.IntrinsicElements[TTag]>;
<P, O>(component: StyledComponentClass<P, T, O>): ThemedStyledFunction<
P,
T,
O
>;
<P extends { [prop: string]: any; theme?: T }>(
component: React.ComponentType<P>,
): ThemedStyledFunction<P, T, WithOptionalTheme<P, T>>;
}
export type ThemedStyledInterface<T> = ThemedBaseStyledInterface<Extract<keyof T, string> extends never ? any : T>;
export type StyledInterface = ThemedStyledInterface<DefaultTheme>;
// tslint:disable-next-line:no-empty-interface
export interface DefaultTheme {}
export interface ThemeProviderProps<T> {
theme?: T | ((theme: T) => T);
}
export type BaseThemeProviderComponent<T> = React.ComponentClass<
ThemeProviderProps<T>
>;
export type ThemeProviderComponent<T> = BaseThemeProviderComponent<Extract<keyof T, string> extends never ? any : T>;
export interface BaseThemedCssFunction<T> {
(
strings: TemplateStringsArray,
...interpolations: SimpleInterpolation[]
): InterpolationValue[];
<P>(
strings: TemplateStringsArray,
...interpolations: Array<Interpolation<ThemedStyledProps<P, T>>>
): Array<FlattenInterpolation<ThemedStyledProps<P, T>>>;
}
export type ThemedCssFunction<T> = BaseThemedCssFunction<Extract<keyof T, string> extends never ? any : T>;
// Helper type operators
type KeyofBase = keyof any;
type Diff<T extends KeyofBase, U extends KeyofBase> = ({ [P in T]: P } &
{ [P in U]: never })[T];
type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>;
type DiffBetween<T, U> = Pick<T, Diff<keyof T, keyof U>> &
Pick<U, Diff<keyof U, keyof T>>;
type WithOptionalTheme<P extends { theme?: T }, T> = Omit<P, 'theme'> & {
theme?: T;
};
export interface ThemedStyledComponentsModule<T> {
default: ThemedStyledInterface<T>;
css: ThemedCssFunction<T>;
keyframes(
strings: TemplateStringsArray,
...interpolations: SimpleInterpolation[]
): string;
injectGlobal(
strings: TemplateStringsArray,
...interpolations: SimpleInterpolation[]
): void;
withTheme: WithThemeFnInterface<T>;
ThemeProvider: ThemeProviderComponent<T>;
}
declare const styled: StyledInterface;
export const css: ThemedCssFunction<DefaultTheme>;
export type BaseWithThemeFnInterface<T> = <P extends { theme?: T }>(
component: React.ComponentType<P>,
) => React.ComponentClass<WithOptionalTheme<P, T>>;
export type WithThemeFnInterface<T> = BaseWithThemeFnInterface<Extract<keyof T, string> extends never ? any : T>;
export const withTheme: WithThemeFnInterface<DefaultTheme>;
export function keyframes(
strings: TemplateStringsArray,
...interpolations: SimpleInterpolation[]
): string;
export function injectGlobal(
strings: TemplateStringsArray,
...interpolations: SimpleInterpolation[]
): void;
export function consolidateStreamedStyles(): void;
export function isStyledComponent(
target: any,
): target is StyledComponentClass<{}, {}>;
export const ThemeProvider: ThemeProviderComponent<object>;
interface StylesheetComponentProps {
sheet: ServerStyleSheet;
}
interface StyleSheetManagerProps {
sheet?: StyleSheet;
target?: Node;
}
export class StyleSheetManager extends React.Component<
StyleSheetManagerProps
> {}
export class ServerStyleSheet {
collectStyles(
tree: React.ReactNode,
): React.ReactElement<StylesheetComponentProps>;
getStyleTags(): string;
getStyleElement(): Array<React.ReactElement<{}>>;
interleaveWithNodeStream(
readableStream: NodeJS.ReadableStream,
): NodeJS.ReadableStream;
instance: StyleSheet;
}
export default styled;

View File

@@ -0,0 +1,548 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import * as ReactDOMServer from 'react-dom/server';
import styled, {
css,
injectGlobal,
isStyledComponent,
keyframes,
ServerStyleSheet,
StyleSheetManager,
ThemeProps,
ThemeProvider,
withTheme,
} from 'styled-components';
/**
* general usage
*/
// Create a <Title> react component that renders an <h1> which is
// centered, palevioletred and sized at 1.5em
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
// Create a <Wrapper> react component that renders a <section> with
// some padding and a papayawhip background
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;
const Input = styled.input`
font-size: 1.25em;
padding: 0.5em;
margin: 0.5em;
color: palevioletred;
background: papayawhip;
border: none;
border-radius: 3px;
&:hover {
box-shadow: inset 1px 1px 2px rgba(0, 0, 0, 0.1);
}
`;
interface MyTheme {
primary: string;
}
interface ButtonProps {
name: string;
primary?: boolean;
theme: MyTheme;
}
class MyButton extends React.Component<ButtonProps> {
render() {
return <button>Custom button</button>;
}
}
const TomatoButton = styled(MyButton)`
color: tomato;
border-color: tomato;
`;
const CustomizableButton = styled(MyButton)`
/* Adapt the colors based on primary prop */
background: ${props => (props.primary ? 'palevioletred' : 'white')};
color: ${props => (props.primary ? 'white' : 'palevioletred')};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid ${props => props.theme.primary};
border-radius: 3px;
`;
const example = css`
font-size: 1.5em;
text-align: center;
color: ${props => props.theme.primary};
border-color: ${'red'};
`;
const fadeIn = keyframes`
0% {
opacity: 0;
}
100% {
opacity: 1;
}
`;
const theme = {
main: 'mediumseagreen',
};
injectGlobal`
@font-face {
font-family: 'Operator Mono';
src: url('../fonts/Operator-Mono.ttf');
}
body {
margin: 0;
}
`;
class Example extends React.Component {
render() {
return (
<ThemeProvider theme={theme}>
<Wrapper>
<Title>
Hello World, this is my first styled component!
</Title>
<Input placeholder="@mxstbr" type="text" />
<TomatoButton name="demo" />
</Wrapper>
;
</ThemeProvider>
);
}
}
// css which only uses simple interpolations without functions
const cssWithValues1 = css`
font-size: ${14} ${'pt'};
`;
// css which uses other simple interpolations without functions
const cssWithValues2 = css`
${cssWithValues1}
${[cssWithValues1, cssWithValues1]}
font-weight: ${'bold'};
`;
// injectGlobal accepts simple interpolations if they're not using functions
injectGlobal`
${'font-size'}: ${10}pt;
${cssWithValues1}
${[cssWithValues1, cssWithValues2]}
`;
// css which uses function interpolations with common props
const cssWithFunc1 = css`
font-size: ${props => props.theme.fontSizePt}pt;
`;
const cssWithFunc2 = css`
${cssWithFunc1}
${props => cssWithFunc1}
${[cssWithFunc1, cssWithValues1]}
`;
// such css can be used in styled components
const styledButton = styled.button`
${cssWithValues1} ${[cssWithValues1, cssWithValues2]}
${cssWithFunc1} ${[cssWithFunc1, cssWithFunc2]}
${() => [cssWithFunc1, cssWithFunc2]}
`;
// css with function interpolations cannot be used in injectGlobal
/*
injectGlobal`
${cssWithFunc1}
`;
*/
const name = 'hey';
const ThemedMyButton = withTheme(MyButton);
<ThemedMyButton name={name} />;
/**
* nested styles
*/
const Link = styled.a`
color: red;
`;
const AlternativeLink = styled.a`
color: blue;
`;
const freeStyles = css`
background-color: black;
color: white;
${Link} {
color: blue;
}
`;
const Article = styled.section`
color: red;
${freeStyles}
& > ${Link} {
color: green;
}
${p => (p.theme.useAlternativeLink ? AlternativeLink : Link)} {
color: black
}
`;
// A Link instance should be backed by an HTMLAnchorElement
const ComposedLink = () => (
<Link onClick={(e: React.MouseEvent<HTMLAnchorElement>) => undefined} />
);
/**
* construction via string tag
*/
// Create a <LinkFromString> react component that renders an <a> which is
// centered, palevioletred and sized at 1.5em
const LinkFromString = styled('a')`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
// A LinkFromString instance should be backed by an HTMLAnchorElement
const MyOtherComponent = () => (
<LinkFromString
onClick={(e: React.MouseEvent<HTMLAnchorElement>) => undefined}
/>
);
// Create a <LinkFromStringWithProps> react component that renders an <a>
// which takes extra props
interface LinkProps {
canClick: boolean;
}
const LinkFromStringWithProps = styled('a')`
font-size: 1.5em;
text-align: center;
color: ${(a: LinkProps) => (a.canClick ? 'palevioletred' : 'gray')};
`;
// A LinkFromStringWithProps instance should be backed by an HTMLAnchorElement
const MyOtherComponentWithProps = () => (
<LinkFromStringWithProps
canClick={false}
onClick={(e: React.MouseEvent<HTMLAnchorElement>) => undefined}
/>
);
// Create a <LinkFromStringWithPropsAndGenerics> react component that renders an <a>
// which takes extra props passed as a generic type argument
const LinkFromStringWithPropsAndGenerics = styled<LinkProps, 'a'>('a')`
font-size: 1.5em;
text-align: center;
color: ${a => (a.canClick ? 'palevioletred' : 'gray')};
`;
// A LinkFromStringWithPropsAndGenerics instance should be backed by an HTMLAnchorElement
const MyOtherComponentWithPropsAndGenerics = () => (
<LinkFromStringWithPropsAndGenerics
canClick={false}
onClick={(e: React.MouseEvent<HTMLAnchorElement>) => undefined}
/>
);
/**
* object styles
*/
interface ObjectStyleProps {
size: string;
}
const functionReturningStyleObject = (props: ObjectStyleProps) => ({
padding: props.size === 'big' ? '10px' : 2,
});
const ObjectStylesBox = styled.div`
${functionReturningStyleObject} ${{
backgroundColor: 'red',
// Supports nested objects (pseudo selectors, media queries, etc)
'@media screen and (min-width: 800px)': {
backgroundColor: 'blue',
},
fontSize: 2,
}};
`;
<ObjectStylesBox size="big" />;
/**
* attrs
*/
const AttrsInput = styled.input.attrs({
// we can define static props
type: 'password',
// or we can define dynamic ones
margin: (props: any) => (props.size as string) || '1em',
padding: (props: any) => (props.size as string) || '1em',
})`
color: palevioletred;
font-size: 1em;
border: 2px solid palevioletred;
border-radius: 3px;
/* here we use the dynamically computed props */
margin: ${props => props.margin};
padding: ${props => props.padding};
`;
/**
* component type
*/
declare const A: React.ComponentClass;
declare const B: React.StatelessComponent;
declare const C: React.ComponentType;
styled(A); // succeeds
styled(B); // succeeds
styled(C); // used to fail; see issue trail linked below
// https://github.com/mui-org/material-ui/pull/8781#issuecomment-349460247
// https://github.com/mui-org/material-ui/issues/9838
// https://github.com/styled-components/styled-components/pull/1420
// https://github.com/Microsoft/TypeScript/issues/21175
// https://github.com/styled-components/styled-components/pull/1427
/**
* extend
*/
const ExtendButton = styled.button`
color: palevioletred;
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
// We're extending Button with some extra styles
const TomatoExtendButton = ExtendButton.extend`
color: tomato;
border-color: tomato;
`;
/**
* function themes
*/
// Define our button, but with the use of props.theme this time
const ThemedButton = styled.button`
color: ${props => props.theme.fg};
border: 2px solid ${props => props.theme.fg};
background: ${props => props.theme.bg};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border-radius: 3px;
`;
// Define our `fg` and `bg` on the theme
const theme2 = {
fg: 'palevioletred',
bg: 'white',
};
// This theme swaps `fg` and `bg`
const invertTheme = ({ fg, bg }: { fg: string; bg: string }) => ({
fg: bg,
bg: fg,
});
const MyApp = (
<ThemeProvider theme={theme2}>
<div>
<ThemedButton>Default Theme</ThemedButton>
<ThemeProvider theme={invertTheme}>
<ThemedButton>Inverted Theme</ThemedButton>
</ThemeProvider>
</div>
</ThemeProvider>
);
/**
* withTheme HOC
*/
class MyComponent extends React.Component<ThemeProps<{}>> {
render() {
const { theme } = this.props;
console.log('Current theme: ', theme);
return <h1>Hello</h1>;
}
}
const ThemedMyComponent = withTheme(MyComponent);
interface WithThemeProps {
theme: {
color: string;
};
text: string;
}
const Component = (props: WithThemeProps) => (
<div style={{ color: props.theme.color }}>{props.text}</div>
);
const ComponentWithTheme = withTheme(Component);
<ComponentWithTheme text={'hi'} />; // ok
<ComponentWithTheme text={'hi'} theme={{ color: 'red' }} />; // ok
/**
* isStyledComponent utility
*/
const StyledComponent = styled.h1``;
const StatelessComponent = () => <div />;
class ClassComponent extends React.Component {
render() {
return <div />;
}
}
isStyledComponent(StyledComponent);
isStyledComponent(StatelessComponent);
isStyledComponent(ClassComponent);
isStyledComponent('div');
/**
* server side rendering
*/
const SSRTitle = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
const sheet = new ServerStyleSheet();
const html = sheet.collectStyles(<SSRTitle>Hello world</SSRTitle>);
const styleHtml = sheet.getStyleTags();
const styleElement = sheet.getStyleElement();
const sheet2 = new ServerStyleSheet();
const element = (
<StyleSheetManager sheet={sheet2.instance}>
<SSRTitle>Hello world</SSRTitle>
</StyleSheetManager>
);
const css2 = sheet2.getStyleElement();
// Wrapping a node stream returned from renderToNodeStream with interleaveWithNodeStream
const sheet3 = new ServerStyleSheet();
const appStream = ReactDOMServer.renderToNodeStream(<Title>Hello world</Title>);
const wrappedCssStream: NodeJS.ReadableStream = sheet3.interleaveWithNodeStream(
appStream,
);
/**
* StyledComponent.withComponent
*/
const WithComponentH1 = styled.h1`
color: palevioletred;
font-size: 1em;
`;
function getRandomInt(min: number, max: number) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
class Random extends React.Component<any, any> {
render() {
const i = getRandomInt(1, 6);
switch (i) {
case 1:
return <h1>Hello World</h1>;
case 2:
return <h2>Hello World</h2>;
case 3:
return <h3>Hello World</h3>;
case 4:
return <h4>Hello World</h4>;
case 5:
return <h5>Hello World</h5>;
case 6:
return <h6>Hello World</h6>;
default:
return null;
}
}
}
const WithComponentH2 = WithComponentH1.withComponent('h2');
const WithComponentAbbr = WithComponentH1.withComponent('abbr');
const WithComponentAnchor = WithComponentH1.withComponent('a');
const AnchorContainer = () => (
<WithComponentAnchor href="https://example.com">
withComponent Anchor
</WithComponentAnchor>
);
const WithComponentRandomHeading = WithComponentH1.withComponent(Random);
const WithComponentCompA: React.SFC<{ a: number; className?: string }> = ({
className,
}) => <div className={className} />;
const WithComponentCompB: React.SFC<{ b: number; className?: string }> = ({
className,
}) => <div className={className} />;
const WithComponentStyledA = styled(WithComponentCompA)`
color: ${(props: { color: string }) => props.color};
`;
const WithComponentFirstStyledA = styled(WithComponentStyledA).attrs({
a: 1,
})``;
const WithComponentFirstStyledB = WithComponentFirstStyledA.withComponent(
WithComponentCompB,
);
const test = () => [
<WithComponentFirstStyledA color={'black'} />,
<WithComponentFirstStyledB b={2} color={'black'} />,
];

View File

@@ -0,0 +1,24 @@
{
"compilerOptions": {
"baseUrl": "../../",
"forceConsistentCasingInFileNames": true,
"jsx": "react",
"lib": ["es6", "dom"],
"module": "commonjs",
"noEmit": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"typeRoots": [
"../../"
],
"paths": {
"styled-components": [
"styled-components/v3"
]
},
"types": []
},
"files": ["index.d.ts", "styled-components-tests.tsx"]
}

View File

@@ -0,0 +1 @@
{ "extends": "dtslint/dt.json" }