Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed an issue with wrapped class components not having a type for the ref prop #1996

Merged
merged 1 commit into from
Sep 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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} />
}