Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

Latest commit

 

History

History
138 lines (103 loc) · 3.45 KB

README.md

File metadata and controls

138 lines (103 loc) · 3.45 KB

@polymorphic-factory/preact

CodeCov MIT License Github Stars Bundle Size NPM Downloads

Create polymorphic Preact components with a customizable styled function.

A polymorphic component is a component that can be rendered with a different element. This is useful for component libraries that want to provide a consistent API for their users and want to allow them to customize the underlying element.

Installation

npm install @polymorphic-factory/preact

or

yarn add @polymorphic-factory/preact

or

pnpm install @polymorphic-factory/preact

Usage

Import the polymorphic factory and create your element factory.

import { polymorphicFactory } from '@polymorphic-factory/preact'
const poly = polymorphicFactory()

Custom styled function

You can override the default implementation by passing styled function in the options.

const poly = polymorphicFactory({
  styled: (component, options) => (props) => {
    const Component = props.as || component
    return <Component data-custom-styled data-options={JSON.stringify(options)} {...props} />
  },
})

const WithOptions = poly('div', { hello: 'world' })

const App = () => {
  return (
    <>
      <poly.div hello="world" />
      {/* renders <div data-custom-styled hello="world" /> */}

      <WithOptions />
      {/* renders <div data-custom-styled data-options="{ \"hello\": \"world\" }" /> */}
    </>
  )
}

Inline

Use the element factory to create elements inline. Every JSX element is supported div, main, aside, etc.

<>
  <poly.div />
  <poly.main>
    <poly.section>
      <poly.div as="p">This is rendered as a p element</poly.div>
    </poly.section>
  </poly.main>
</>

Factory

Use the factory to wrap custom components.

const OriginalComponent = (props) => <div data-original="true" {...props}></div>
const MyComponent = poly(OriginalComponent)

const App = () => <MyComponent />
// render <div data-original="true" />

It still supports the as prop, which would replace the OriginalComponent.

<MyComponent as="div" />
// renders <div />

Refs

You can use ref on the component, and it will have the correct typings.

const App = () => {
  const ref = useRef<HTMLAnchorElement>(null)
  return <poly.button as="a" ref={ref} />
}

Types

import type { HTMLPolymorphicComponents, HTMLPolymorphicProps } from '@polymorphic-factory/preact'

type PolymorphicDiv = HTMLPolymorphicComponents['div']
type DivProps = HTMLPolymorphicProps<'div'>

License

MIT © Tim Kolberger