Skip to content

Commit

Permalink
[styled-components v4] Various small improvements to the libdefs (#3731)
Browse files Browse the repository at this point in the history
* [styled-components v4] minor fix to StyleSheetManager

* [styled-components v4] Implicitly support style, className and children
  • Loading branch information
omninonsense committed Feb 14, 2020
1 parent 3110361 commit bc582bb
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ declare module 'styled-components' {
| false // falsy values are OK, true is the only one not allowed, because it renders as "true"
| null
| void
| {[ruleOrSelector: string]: string | number, ...} // CSS-in-JS object returned by polished are also supported
| {[ruleOrSelector: string]: string | number, ...} // CSS-in-JS object returned by polished are also supported, partially

declare export type TaggedTemplateLiteral<I, R> = (strings: string[], ...interpolations: Interpolation<I>[]) => R

Expand Down Expand Up @@ -100,7 +100,7 @@ declare module 'styled-components' {

declare export class StyleSheetManager extends React$Component<SCMProps> {
getContext(sheet: ?StyleSheet, target: ?HTMLElement): StyleSheet;
render(): React$Element<StyleSheetProvider>
render(): React$Element<typeof StyleSheetProvider>
}

declare export class ServerStyleSheet {
Expand Down Expand Up @@ -164,14 +164,21 @@ declare module 'styled-components' {
theme: T
|}

declare type CommonSCProps = {|
children?: React$Node,
className?: ?string,
style?: {[string]: string | number, ...},
|}

declare export type PropsWithTheme<Props, T> = {|
...ThemeProps<T>,
...CommonSCProps, // Not sure how useful this is here, but it's technically correct to have it
...$Exact<Props>
|}

declare export function withTheme<Theme, Config: {...}, Instance>(Component: React$AbstractComponent<Config, Instance>): React$AbstractComponent<$Diff<Config, ThemeProps<Theme | void>>, Instance>

declare export type StyledComponent<Props, Theme, Instance> = React$AbstractComponent<Props, Instance> & Class<InterpolatableComponent<Props>>
declare export type StyledComponent<Props, Theme, Instance, MergedProps = {...$Exact<Props>, ...CommonSCProps, ...}> = React$AbstractComponent<MergedProps, Instance> & Class<InterpolatableComponent<MergedProps>>

declare export type StyledFactory<StyleProps, Theme, Instance> = {|
[[call]]: TaggedTemplateLiteral<PropsWithTheme<StyleProps, Theme>, StyledComponent<StyleProps, Theme, Instance>>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,21 +96,6 @@ describe('styled builtins', () => {
const div2 = <Div color="maroon" background="salmon" />
})

it('should respect strict props', () => {
// {| ... |} breaks syntax highlighting in vs code
// if all on one line, so put here instead of inlined
type Props = {|
color?: string,
|}

const Span: StyledComponent<Props, *, *> = styled.span`
color: ${props => props.color || 'pink'};
`

// $ExpectError - typo; someone used the British spelling by accident
const span1 = <Span colour="maroon" />
})

it('should validate template props', () => {
const Span: StyledComponent<{ color: string, ... }, *, *> = styled.span`
color: ${// $ExpectError - background is not in props
Expand All @@ -128,6 +113,26 @@ describe('styled builtins', () => {
`
})

it('supports common props that styled components accept', () => {
const Span: StyledComponent<{ color: string, ... }, *, *> = styled.span`
color: ${props => props.color};
`

const span1 = <Span color="maroon" className="marooned" />
const span2 = <Span color="maroon" style={{padding: 5}} />

// $ExpectError - Make sure we don't break soundness when props are missing!
const span3 = <Span style={{padding: 5}} />
})

it('exposes common props inside interpolations', () => {
const Span: StyledComponent<{ color: string, ... }, *, *> = styled.span`
color: ${props => props.color};
/* People reading this test: this is a horrible way to dynamically scale your component! */
height: calc(${props => React.Children.count(props.children)} * 20px);
`
})

it('should validate theme', () => {
// $ExpectError - oops, someone meant accent, not primary
const Span: StyledComponent<{ color?: string, ... }, { accent: string, ... }, *> = styled.span`
Expand Down

0 comments on commit bc582bb

Please sign in to comment.