Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/frigus02/react-custom-element-wrapper
Use Custom Elements with properties or events in React
https://github.com/frigus02/react-custom-element-wrapper
Last synced: 25 days ago
JSON representation
Use Custom Elements with properties or events in React
- Host: GitHub
- URL: https://github.com/frigus02/react-custom-element-wrapper
- Owner: frigus02
- License: mit
- Created: 2019-04-03T18:47:49.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2019-04-03T19:59:46.000Z (over 5 years ago)
- Last Synced: 2024-10-17T20:24:05.191Z (about 1 month ago)
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/react-custom-element-wrapper
- Size: 12.7 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# React Custom Element Wrapper
[![npm](https://img.shields.io/npm/v/react-custom-element-wrapper.svg)](https://www.npmjs.com/package/react-custom-element-wrapper)
Use Custom Elements with properties or events in React.
[Custom Elements](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements) can define their API with attributes, properties, events and children (slots). React supports attributes and children out of the box. But there are some challenges with the rest:
- Properties don't work because React calls `setAttribute` on custom elements.
- Events don't work because React has [synthetic events](https://reactjs.org/docs/events.html), which don't support custom DOM events.People are working on a solution (see [React RFC about custom element support](https://github.com/reactjs/rfcs/pull/15)). But we can already use a workaround using [refs](https://reactjs.org/docs/refs-and-the-dom.html) now. This library is a tiny wrapper you can put around any custom element to make it work in React.
Note: If the custom element you want to use only uses attributes and children, you don't have to use this wrapper. Just use the custom element directly.
## Table of Contents
- [Install](#install)
- [Usage](#usage)
- [PropTypes](#proptypes)
- [TypeScript](#typescript)
- [Contributing](#contributing)
- [License](#license)## Install
```sh
# npm
npm install react-custom-element-wrapper# yarn
yarn add react-custom-element-wrapper
```## Usage
Create a wrapper around your custom element.
```js
import customElement from "react-custom-element-wrapper";// Load Custom Element JavaScript
import "my-greeting";// Define React props and how they match to the elements attributes, properties and events
const MyGreeting = customElement("my-greeting", {
salutation: { type: "attribute", name: "salutation" },
traits: { type: "property", name: "traits" },
onWave: { type: "event", name: "wave" },
});export default MyGreeting;
```Then use the wrapper in the same way as any other React component.
```js
import MyGreeting from "./MyGreeting";const App = () => (
Bear
);
```## PropTypes
Components generated using this library automatically get these basic [prop-types](https://github.com/facebook/prop-types):
- Attributes: `PropTypes.string`
- Properties: `PropTypes.any`
- Events: `PropTypes.function`## TypeScript
You can type elements generated using this library by defining a type for the React props. When doing so, your types have to match a certain schema:
- Attributes can only be mapped to a prop of type `string`.
- Properties can be mapped to anything.
- Events can only be mapped to a [`EventListenerOrEventListenerObject`](https://github.com/Microsoft/TypeScript/blob/8a19e4bcf95de764ca18bc0276697ab86bd783e4/lib/lib.dom.d.ts#L17493). You probably want to use something like `CustomElement => void`. And if the custom element provides a typed event object, you can use that instead.```ts
import customElement from "react-custom-element-wrapper";
import "my-greeting";// Define React props
type Props = {
salutation: string,
traits: string[],
onWave: CustomEvent => void
};const MyGreeting = customElement("my-greeting", {
salutation: { type: "attribute", name: "salutation" },
traits: { type: "property", name: "traits" },
onWave: { type: "event", name: "wave" },
});export default MyGreeting;
```## Contributing
Please see [CONTRIBUTING.md](CONTRIBUTING.md).
## License
[MIT](LICENSE)