-
Notifications
You must be signed in to change notification settings - Fork 671
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
[QUESTION] How do you implement custom components with Typescript + forwardRef? #881
Comments
I have similar issues. I fixed the type issues by unshamelessly stealing the (I am not good enough with TypeScript to understand them fully, so copypasting them makes me feel even worse but... At least it seems to work 🙈) import React from 'react';
import { Text, TextProps } from '@theme-ui/components';
type Assign<T, U> = {
[P in keyof (T & U)]: P extends keyof T
? T[P]
: P extends keyof U
? U[P]
: never
}
type ForwardRef<T, P> =
React.ForwardRefExoticComponent<
React.PropsWithoutRef<P>& React.RefAttributes<T>
>
export interface ParagraphProps
extends Assign<React.ComponentPropsWithRef<'p'>, TextProps> {};
export const Paragraph: ForwardRef<HTMLParagraphElement, ParagraphProps> =
React.forwardRef((props, ref) => (
<Text
as="p"
{...props}
ref={ref}
/>
)); But I am facing various type issues as soon as I want to use variants, themeKey and sx props. |
More specifically by "various issues": I am using Storybook to document components, so my issue may be related to that, but it's hard to figure out at the moment. I use a "decorator" to wrap all components under a import { merge } from 'theme-ui';
import { base } from '@theme-ui/presets';
export const theme = merge(base, {
colors: {
primary: '#3d5a80'
},
text: {
primary: {
color: 'primary',
textTransform: 'uppercase'
}
}
}); Then my story is: import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';
import { Text } from 'theme-ui';
import { Paragraph } from './Paragraph.tsx';
# Text
<Meta title="Typography/Text" component={Text} />
<Preview>
<Story name="Text">
<Text as="p" variant="primary">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</Text>
</Story>
</Preview>
<Preview>
<Story name="Paragraph">
<Paragraph variant="primary">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</Paragraph>
</Story>
</Preview> The first one renders correctly, the second does not. However, that component in a codesandbox works fine: Just wondering if there are specific MDX or props forwarding requirements to use the theme...? |
@calvinwyoung the types are incorrect in Theme UI. They are largely missing As a temporary workaround, I created a type helper that I have been using: type BoxPropsWithRef<
T extends React.ElementType,
P extends BoxOwnProps = BoxOwnProps
> = React.ComponentPropsWithRef<T> & P I can then type my custom override component: import React, { forwardRef } from 'react'
import { Label as ThemeUILabel, LabelProps as ThemeUILabelProps } from 'theme-ui'
export type LabelProps = BoxPropsWithRef<'label', ThemeUILabelProps>
export const Label = forwardRef<HTMLLabelElement, LabelProps>(
(props, ref) => <ThemeUILabel ref={ref} {...props} />
) |
I'm trying to implement a custom label component with Typescript, building on the
<Label />
component that comes with theme-ui. My first attempt looks something like this:I would've expected this to work, but instead I get the following error on
ref={ref}
:Am I doing something very silly here? Has anyone else run into a similar issue?
The text was updated successfully, but these errors were encountered: