question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Export component prop types

See original GitHub issue

What package within Headless UI are you using?

@headlessui/react

What version of that package are you using?

v1.5.0

What browser are you using?

N/A

Reproduction URL

N/A

Describe your issue

In React + Typescript, a common pattern I follow is to wrap a library component for styling or custom behaviour before exposing it to the rest of the codebase. I like to mirror the underlying component props so that Typescript intellisense can provide the same prop hints to for the wrapper component as the underlying library component.

Here is an example of what I want:

// Wrapping a tab for custom styling. TabProps, however, does not exist;
function TemplateLibraryTab({ children, ...props }: TabProps) {
  return (
    <Tab
      {...props}
      className={({ selected }) =>
        clsx("p-2 rounded", selected ? "text-gray-900" : "text-gray-500")
      }
    >
      {children}
    </Tab>
  )
}

HeadlessUI does not seem to expose these props, or at least I could not find them. Would it be possible to export these prop types for this purpose? I think it is a strong use-case.

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:44
  • Comments:15

github_iconTop GitHub Comments

41reactions
CapitaineToinoncommented, May 14, 2022

Thanks to discussions/601, I got it working like this:

import { ComponentType } from 'react'
import { Dialog as HeadlessDialog } from '@headlessui/react'

type ExtractProps<T> = T extends ComponentType<infer P> ? P : T

function DialogRoot(props: ExtractProps<typeof HeadlessDialog>) {
  // add your own logic here
  return <HeadlessDialog {...props} />
}

You may also need to do something like this if you want the nested components to work too.

export let Dialog = Object.assign(DialogRoot, {
	Backdrop: HeadlessDialog.Backdrop,
	Panel: HeadlessDialog.Panel,
	Overlay: HeadlessDialog.Overlay,
	Title: HeadlessDialog.Title,
	Description: HeadlessDialog.Description,
})
14reactions
ZerNicocommented, May 9, 2022

I have been doing React.ComponentProps for exactly the same use case (I wrap all the components I import) and it worked very well so far! However v1.6.0 breaks this for me. Would love to know if there is a workaround at least, otherwise will stay with v1.5.

Yup for some reason it broke now.

Type '(<TTag extends ElementType<any> = "button">(props: Props<TTag, TabRenderPropArg, TabPropsWeControl>, ref: Ref<HTMLElement>) => ReactElement<...>) & { ...; } & { ...; }' does not satisfy the constraint 'keyof IntrinsicElements | JSXElementConstructor<any>'. Type '(<TTag extends ElementType<any> = "button">(props: Props<TTag, TabRenderPropArg, TabPropsWeControl>, ref: Ref<HTMLElement>) => ReactElement<...>) & { ...; } & { ...; }' is not assignable to type '(props: any) => ReactElement<any, any>'.

Exporting the PropTypes would probably still be the nicer solution.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Typechecking With PropTypes - React
PropTypes exports a range of validators that can be used to make sure the data you receive is valid. In this example, we're...
Read more >
Export prop types as TypeScript types in published JavaScript ...
I have a React component authored in JavaScript and published to an npm repository. This component uses the prop-types library to do runtime ......
Read more >
TypeScript Tips: Getting Component Props Types in React
Now, to fix this, one could export the UI component props types and use it from the HoC component. And, that works well...
Read more >
React Pattern: Centralized PropTypes - freeCodeCamp
I use a named import to get a reference to the exported PropType declaration on line 2. And I put it to use...
Read more >
Notes on TypeScript: Accessing Non Exported Component ...
Sometimes we need to access some component prop types, but they have not been exported. Then there are also cases where we would...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found