Skip to content

Commit

Permalink
Fixed an issue with wrapped class components not having a type for th…
Browse files Browse the repository at this point in the history
…e `ref` prop
  • Loading branch information
Andarist committed Sep 5, 2020
1 parent 0895f1f commit 3430109
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/cyan-apes-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@emotion/styled': patch
---

Fixed an issue with wrapped class components not having a type for the `ref` prop.
64 changes: 58 additions & 6 deletions packages/styled/types/base.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,18 @@ export interface StyledOptions<Props> {
*/
export interface StyledComponent<
ComponentProps extends {},
SpecificComponentProps extends {} = {}
> extends React.FC<ComponentProps & SpecificComponentProps>, ComponentSelector {
SpecificComponentProps extends {} = {},
JSXProps extends {} = {}
>
extends React.FC<ComponentProps & SpecificComponentProps & JSXProps>,
ComponentSelector {
withComponent<C extends React.ComponentClass<React.ComponentProps<C>>>(
component: C
): StyledComponent<
ComponentProps & PropsOf<C>,
{},
{ ref?: React.Ref<InstanceType<C>> }
>
withComponent<C extends React.ComponentType<React.ComponentProps<C>>>(
component: C
): StyledComponent<ComponentProps & PropsOf<C>>
Expand All @@ -51,7 +61,8 @@ export interface StyledComponent<
*/
export interface CreateStyledComponent<
ComponentProps extends {},
SpecificComponentProps extends {} = {}
SpecificComponentProps extends {} = {},
JSXProps extends {} = {}
> {
/**
* @typeparam AdditionalProps Additional props to add to your styled component
Expand All @@ -64,14 +75,18 @@ export interface CreateStyledComponent<
AdditionalProps & { theme: Theme }
>
>
): StyledComponent<ComponentProps & AdditionalProps, SpecificComponentProps>
): StyledComponent<
ComponentProps & AdditionalProps,
SpecificComponentProps,
JSXProps
>

(
template: TemplateStringsArray,
...styles: Array<
Interpolation<ComponentProps & SpecificComponentProps & { theme: Theme }>
>
): StyledComponent<ComponentProps, SpecificComponentProps>
): StyledComponent<ComponentProps, SpecificComponentProps, JSXProps>

/**
* @typeparam AdditionalProps Additional props to add to your styled component
Expand All @@ -85,7 +100,11 @@ export interface CreateStyledComponent<
AdditionalProps & { theme: Theme }
>
>
): StyledComponent<ComponentProps & AdditionalProps, SpecificComponentProps>
): StyledComponent<
ComponentProps & AdditionalProps,
SpecificComponentProps,
JSXProps
>
}

/**
Expand All @@ -98,6 +117,39 @@ export interface CreateStyledComponent<
* @example styled('div')<Props>(props => ({ width: props.width })
*/
export interface CreateStyled {
<
C extends React.ComponentClass<React.ComponentProps<C>>,
ForwardedProps extends keyof React.ComponentProps<
C
> = keyof React.ComponentProps<C>
>(
component: C,
options: FilteringStyledOptions<React.ComponentProps<C>, ForwardedProps>
): CreateStyledComponent<
Pick<PropsOf<C>, ForwardedProps> & {
theme?: Theme
as?: React.ElementType
},
{},
{
ref?: React.Ref<InstanceType<C>>
}
>

<C extends React.ComponentClass<React.ComponentProps<C>>>(
component: C,
options?: StyledOptions<React.ComponentProps<C>>
): CreateStyledComponent<
PropsOf<C> & {
theme?: Theme
as?: React.ElementType
},
{},
{
ref?: React.Ref<InstanceType<C>>
}
>

<
C extends React.ComponentType<React.ComponentProps<C>>,
ForwardedProps extends keyof React.ComponentProps<
Expand Down
37 changes: 35 additions & 2 deletions packages/styled/types/tests-base.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@ const StyledClass0 = styled(ReactClassComponent0)({})
declare const ref0_0: (element: ReactClassComponent0 | null) => void
declare const ref0_1: (element: ReactClassComponent1 | null) => void
declare const ref0_2: (element: HTMLDivElement | null) => void
// $ExpectError
;<StyledClass0 column={true} ref={ref0_0} />
// $ExpectError
;<StyledClass0 column={true} ref={ref0_1} />
Expand All @@ -272,7 +271,6 @@ const StyledClass1 = StyledClass0.withComponent(ReactClassComponent1)
declare const ref1_0: (element: ReactClassComponent1 | null) => void
declare const ref1_1: (element: ReactClassComponent0 | null) => void
declare const ref1_2: (element: HTMLDivElement | null) => void
// $ExpectError
;<StyledClass1 column={true} value="" ref={ref1_0} />
// $ExpectError
;<StyledClass1 column={true} value="" ref={ref1_1} />
Expand Down Expand Up @@ -442,3 +440,38 @@ const Section = styled('section')`
// $ExpectError
;<StyledMemoedComponent />
}

{
// simple class ref test
class FixedSizeList extends React.Component {
scrollTo = () => {}

render() {
return null
}
}

const StyledList = styled(FixedSizeList)`
color: hotpink;
`
const listRef = React.useRef<FixedSizeList | null>(null)
;<StyledList ref={listRef} />
}

{
// withComponent class ref test
class FixedSizeList extends React.Component {
scrollTo = () => {}

render() {
return null
}
}

const StyledList = styled('li')`
color: hotpink;
`
const StyledFixedStyleList = StyledList.withComponent(FixedSizeList)
const listRef = React.useRef<FixedSizeList | null>(null)
;<StyledFixedStyleList ref={listRef} />
}

0 comments on commit 3430109

Please sign in to comment.