diff --git a/README.md b/README.md index 660e04b..d2a4c87 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,23 @@ FullName.propTypes = { register(FullName, 'full-name'); ``` +### Creating a CustomElements without registering a tag name + +If authoring a custom-elements library, you might want to expose your CustomElements without registering their tag name, to let your users register their own tags. + +This can be achieved by calling the `toCustomElements` function on the default export: + +```js +import register from 'preact-custom-element' + +function MyComponent({ name = "World" }) { + return Hello {name}! +} + +export const MyElement = register.toCustomElement(MyComponent, ['name']) +``` + +`toCustomElement` has the same signature as `register`, omitting the second parameter (tag name). ## Related diff --git a/src/index.js b/src/index.js index 42318d7..9cb4453 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,6 @@ import { h, cloneElement, render, hydrate } from 'preact'; -export default function register(Component, tagName, propNames, options) { +function toCustomElement(Component, propNames, options) { function PreactElement() { const inst = Reflect.construct(HTMLElement, [], PreactElement); inst._vdomComponent = Component; @@ -49,12 +49,20 @@ export default function register(Component, tagName, propNames, options) { }); }); + return PreactElement; +} + +export default function register(Component, tagName, propNames, options) { + const PreactElement = toCustomElement(Component, propNames, options); + return customElements.define( tagName || Component.tagName || Component.displayName || Component.name, PreactElement ); } +register.toCustomElement = toCustomElement; + function ContextProvider(props) { this.getChildContext = () => props.context; // eslint-disable-next-line no-unused-vars diff --git a/src/index.test.jsx b/src/index.test.jsx index 00da646..5b5154a 100644 --- a/src/index.test.jsx +++ b/src/index.test.jsx @@ -245,4 +245,32 @@ describe('web components', () => { }); assert.equal(getShadowHTML(), '
Active theme: sunny
'); }); + + function ManualRegistration() { + return