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 (104 loc) · 3.41 KB

README.md

File metadata and controls

138 lines (104 loc) · 3.41 KB

@polymorphic-factory/solid

CodeCov MIT License Github Stars Bundle Size NPM Downloads

Create polymorphic SolidJS 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/solid

or

yarn add @polymorphic-factory/solid

or

pnpm install @polymorphic-factory/solid

Usage

Import the polymorphic factory and create your element factory.

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

Custom styled function

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

import { Dynamic } from 'solid-js/web'

const poly = polymorphicFactory({
  styled: (component, options) => (props) => {
    const [local, others] = splitProps(props, ['as'])
    const component = local.as || originalComponent

    return (
      <Dynamic
        component={component}
        data-custom-styled
        data-options={JSON.stringify(options)}
        {...others}
      />
    )
  },
})

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 />

Types

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

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

License

MIT © Tim Kolberger