Skip to content
This repository has been archived by the owner on Dec 13, 2018. It is now read-only.

Commit

Permalink
feat(typescript): Improved theme typing and tests (#160)
Browse files Browse the repository at this point in the history
* feat(typescript): Improved theme typing and tests

* fix(typescript): tweaked StyledFunction

added default type (empty object literal) for ThemeProps generic in StyledFunction

* fix(typescript): removed boilerplate from tests

removed redundant generic
  • Loading branch information
luke-john authored and Kent C. Dodds committed Jun 4, 2017
1 parent d32bd24 commit 119e20d
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 69 deletions.
70 changes: 58 additions & 12 deletions test/glamorous.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,38 @@ const Static = glamorous.div({
});

// dynamic styles
const Title = glamorous.h1(
const Title = glamorous.h1<{ color: string }>(
{
"fontSize": "10px",
"zIndex": "auto",
},
(props: { color: string; }) => ({
(props) => ({
"color": props.color,
}),
);

const UseTitle = () => (
<Title color="red" />
)

// theme styles
const Divider = glamorous.span(
const Divider = glamorous.span<{}, { main: { color: string; } }>(
{
"fontSize": "10px",
"zIndex": "auto"
},
(props, theme: { main: { color: string; } }) => ({
"color": theme.main.color,
(props, theme) => ({
"color": theme && theme.main.color,
}),
);

// n-number of styles
const SpanDivider = glamorous.span(
const SpanDivider = glamorous.span<{}, { awesome: string, main: string }>(
{
"fontSize": "10px",
},
(props, theme: { awesome: { color: string } }) => ({
"color": theme.awesome.color,
(props, theme) => ({
"color": theme && theme.awesome,
}),
{
"fontWeight": 500,
Expand All @@ -48,8 +52,8 @@ const SpanDivider = glamorous.span(
"fontFamily": "Roboto",
"fontWeight": 500,
},
(props, theme: { main: { color: string; } }) => ({
"color": theme.main.color,
(props, theme) => ({
"color": theme && theme.main,
}),
);

Expand Down Expand Up @@ -116,8 +120,6 @@ class ClassToWrap extends React.Component<object, object> {
}
}

const ThemedClass = withTheme(ClassToWrap)

const WrappedClass = glamorous(ClassToWrap)({})

// React Stateless Wrapped Component
Expand All @@ -130,3 +132,47 @@ const WrappedStateless = glamorous(StatelessToWrap)({})

// Exported Component (for testing declaration generation)
export const ExportTest = glamorous.div({})

// Theme Provider

interface ExampleTheme {
color: string
}

const exampleTheme: ExampleTheme = {
color: "red",
}

const ThemedComponent = glamorous.h1<
{},
ExampleTheme
>({
fontSize: '10px'
}, (props, theme) => ({
color: theme ? theme.color : 'blue'
}))

export const ThemeProviderAndThemedComponent = () => (
<ThemeProvider theme={exampleTheme}>
<ThemedComponent />
</ThemeProvider>
);

// Extended component with theme prop

interface ExampleTheme {
color: string
}

const ComponentWithTheme: React.SFC<{
theme: ExampleTheme
title: string
}> = ({title, theme: {color}}) => (
<h3 style={{color}}>{title}</h3>
)

const NonGlamorousThemedComponent = withTheme<ExampleTheme>(ComponentWithTheme)

const UseNonGlamorousThemedComponent = (
<NonGlamorousThemedComponent color={'red'} />
)
14 changes: 5 additions & 9 deletions typings/glamorous.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,11 @@ interface ThemeProps {

export class ThemeProvider extends React.Component<ThemeProps, any> { }


export declare function withTheme<P>(component: Component<P & ThemeProps>): GlamorousComponent<P>


export declare function withTheme
<P>(
component:
| React.ComponentClass<P>
| React.StatelessComponent<P>): GlamorousComponent<P>
export function withTheme<Theme>(component: Component<{ theme: Theme }>): GlamorousComponent<Theme>
export function withTheme<Theme>(component:
| React.ComponentClass<{ theme: Theme }>
| React.StatelessComponent<{ theme: Theme }>
): GlamorousComponent<Theme>

declare const glamorous: GlamorousInterface

Expand Down
96 changes: 48 additions & 48 deletions typings/styled-function.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ export type StaticStyles<Properties> = Partial<Properties>
*
* @see {@link https://github.com/paypal/glamorous/blob/master/src/create-glamorous.js#L28-L131}
*/
export type DynamicStyledFunction<Properties, CustomProps> = (
export type DynamicStyledFunction<Properties, CustomProps, ThemeProps> = (
props: CustomProps,
theme?: object
theme?: ThemeProps
) => Partial<Properties>

type Styles<Properties, CustomProps> = Array<DynamicStyledFunction<Properties, CustomProps> | StaticStyles<Properties>>
type Styles<Properties, CustomProps, ThemeProps> = Array<DynamicStyledFunction<Properties, CustomProps, ThemeProps> | StaticStyles<Properties>>

// TODO: Using a union for a parameter kills autocomplete so we
// use overloading to give autocomplete on the first two styles
Expand All @@ -53,120 +53,120 @@ export interface ExtraGlamorousProps {
}

export interface StyledFunction<Props, Properties> {
<CustomProps>(
<CustomProps, ThemeProps = {}>(
style1: StaticStyles<Properties>,
...styles: Styles<Properties, CustomProps>
...styles: Styles<Properties, CustomProps, ThemeProps>
): GlamorousComponent<Props & CustomProps>;
}

export interface StyledFunction<Props, Properties> {
<CustomProps>(
<CustomProps, ThemeProps = {}>(
style1: StaticStyles<Properties>,
style2: StaticStyles<Properties>,
...styles: Styles<Properties, CustomProps>
...styles: Styles<Properties, CustomProps, ThemeProps>
): GlamorousComponent<Props & CustomProps>
}

export interface StyledFunction<Props, Properties> {
<CustomProps>(
<CustomProps, ThemeProps = {}>(
style1: StaticStyles<Properties>,
style2: DynamicStyledFunction<Properties, CustomProps>,
...styles: Styles<Properties, CustomProps>
style2: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
...styles: Styles<Properties, CustomProps, ThemeProps>
): GlamorousComponent<Props & CustomProps>
}

export interface StyledFunction<Props, Properties> {
<CustomProps>(
<CustomProps, ThemeProps = {}>(
style1: StaticStyles<Properties>,
style2: DynamicStyledFunction<Properties, CustomProps>,
style2: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
style3: StaticStyles<Properties>,
...styles: Styles<Properties, CustomProps>
...styles: Styles<Properties, CustomProps, ThemeProps>
): GlamorousComponent<Props & CustomProps>
}

export interface StyledFunction<Props, Properties> {
<CustomProps>(
<CustomProps, ThemeProps = {}>(
style1: StaticStyles<Properties>,
style2: DynamicStyledFunction<Properties, CustomProps>,
style3: DynamicStyledFunction<Properties, CustomProps>,
...styles: Styles<Properties, CustomProps>
style2: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
style3: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
...styles: Styles<Properties, CustomProps, ThemeProps>
): GlamorousComponent<Props & CustomProps>
}

export interface StyledFunction<Props, Properties> {
<CustomProps>(
<CustomProps, ThemeProps = {}>(
style1: StaticStyles<Properties>,
style2: StaticStyles<Properties>,
style3: DynamicStyledFunction<Properties, CustomProps>,
...styles: Styles<Properties, CustomProps>
style3: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
...styles: Styles<Properties, CustomProps, ThemeProps>
): GlamorousComponent<Props & CustomProps>
}

export interface StyledFunction<Props, Properties> {
<CustomProps>(
<CustomProps, ThemeProps = {}>(
style1: StaticStyles<Properties>,
style2: StaticStyles<Properties>,
style3: StaticStyles<Properties>,
...styles: Styles<Properties, CustomProps>
...styles: Styles<Properties, CustomProps, ThemeProps>
): GlamorousComponent<Props & CustomProps>
}

export interface StyledFunction<Props, Properties> {
<CustomProps>(
style1: DynamicStyledFunction<Properties, CustomProps>,
...styles: Styles<Properties, CustomProps>
<CustomProps, ThemeProps = {}>(
style1: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
...styles: Styles<Properties, CustomProps, ThemeProps>
): GlamorousComponent<Props & CustomProps>
}

export interface StyledFunction<Props, Properties> {
<CustomProps>(
style1: DynamicStyledFunction<Properties, CustomProps>,
<CustomProps, ThemeProps = {}>(
style1: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
style2: StaticStyles<Properties>,
...styles: Styles<Properties, CustomProps>
...styles: Styles<Properties, CustomProps, ThemeProps>
): GlamorousComponent<Props & CustomProps>
}

export interface StyledFunction<Props, Properties> {
<CustomProps>(
style1: DynamicStyledFunction<Properties, CustomProps>,
style2: DynamicStyledFunction<Properties, CustomProps>,
...styles: Styles<Properties, CustomProps>
<CustomProps, ThemeProps = {}>(
style1: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
style2: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
...styles: Styles<Properties, CustomProps, ThemeProps>
): GlamorousComponent<Props & CustomProps>
}

export interface StyledFunction<Props, Properties> {
<CustomProps>(
style1: DynamicStyledFunction<Properties, CustomProps>,
<CustomProps, ThemeProps = {}>(
style1: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
style2: StaticStyles<Properties>,
style3: DynamicStyledFunction<Properties, CustomProps>,
...styles: Styles<Properties, CustomProps>
style3: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
...styles: Styles<Properties, CustomProps, ThemeProps>
): GlamorousComponent<Props & CustomProps>
}

export interface StyledFunction<Props, Properties> {
<CustomProps>(
style1: DynamicStyledFunction<Properties, CustomProps>,
<CustomProps, ThemeProps = {}>(
style1: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
style2: StaticStyles<Properties>,
style3: StaticStyles<Properties>,
...styles: Styles<Properties, CustomProps>
...styles: Styles<Properties, CustomProps, ThemeProps>
): GlamorousComponent<Props & CustomProps>
}

export interface StyledFunction<Props, Properties> {
<CustomProps>(
style1: DynamicStyledFunction<Properties, CustomProps>,
style2: DynamicStyledFunction<Properties, CustomProps>,
<CustomProps, ThemeProps = {}>(
style1: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
style2: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
style3: StaticStyles<Properties>,
...styles: Styles<Properties, CustomProps>
...styles: Styles<Properties, CustomProps, ThemeProps>
): GlamorousComponent<Props & CustomProps>
}

export interface StyledFunction<Props, Properties> {
<CustomProps>(
style1: DynamicStyledFunction<Properties, CustomProps>,
style2: DynamicStyledFunction<Properties, CustomProps>,
style3: DynamicStyledFunction<Properties, CustomProps>,
...styles: Styles<Properties, CustomProps>
<CustomProps, ThemeProps = {}>(
style1: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
style2: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
style3: DynamicStyledFunction<Properties, CustomProps, ThemeProps>,
...styles: Styles<Properties, CustomProps, ThemeProps>
): GlamorousComponent<Props & CustomProps>
}

Expand Down

0 comments on commit 119e20d

Please sign in to comment.