{"id":15375925,"url":"https://github.com/thepassle/cem-plugin-reactify","last_synced_at":"2025-04-15T16:17:01.092Z","repository":{"id":57195688,"uuid":"380958283","full_name":"thepassle/cem-plugin-reactify","owner":"thepassle","description":"@custom-elements-manifest/analyzer plugin to ✨ automatically ✨ create react wrappers for your custom elements","archived":false,"fork":false,"pushed_at":"2021-06-28T09:19:31.000Z","size":24,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-15T16:16:50.666Z","etag":null,"topics":["custom-elements","custom-elements-json","custom-elements-manifest","open-wc","web-components"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thepassle.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-06-28T08:21:20.000Z","updated_at":"2023-02-23T05:42:37.000Z","dependencies_parsed_at":"2022-09-17T08:21:14.939Z","dependency_job_id":null,"html_url":"https://github.com/thepassle/cem-plugin-reactify","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":"open-wc/cem-plugin-template","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepassle%2Fcem-plugin-reactify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepassle%2Fcem-plugin-reactify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepassle%2Fcem-plugin-reactify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thepassle%2Fcem-plugin-reactify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thepassle","download_url":"https://codeload.github.com/thepassle/cem-plugin-reactify/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249105474,"owners_count":21213536,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["custom-elements","custom-elements-json","custom-elements-manifest","open-wc","web-components"],"created_at":"2024-10-01T14:05:17.397Z","updated_at":"2025-04-15T16:17:01.059Z","avatar_url":"https://github.com/thepassle.png","language":"JavaScript","readme":"# cem-plugin-reactify\n\n\n[@custom-elements-manifest/analyzer](https://github.com/open-wc/custom-elements-manifest) plugin to automatically create React wrappers for your custom elements based on your custom elements manifest. You can see this plugin in action [here](https://github.com/thepassle/generic-components/tree/master/legacy), or view the live demo on [Stackblitz](https://stackblitz.com/edit/react-kghcjw).\n## Usage\n\n### Install:\n\n```bash\nnpm i -D cem-plugin-reactify\n```\n\n### Import\n\n`custom-elements-manifest.config.js`:\n```js\nimport reactify from 'cem-plugin-reactify';\n\nexport default {\n  plugins: [\n    reactify()\n  ]\n}\n```\n\n### Configuration\n\n`custom-elements-manifest.config.js`:\n```js\nimport reactify from 'cem-plugin-reactify';\n\nexport default {\n  plugins: [\n    reactify({\n      /** Directory to write the React wrappers to, defaults to `legacy` */\n      outdir: 'react',\n      \n      /** Provide an attribute mapping to avoid using JS/React reserved keywords */\n      attributeMapping: {\n        'for': '_for'\n      },\n\n      /** Array of classNames to exclude */\n      exclude: ['MyElement']\n    });\n  ]\n}\n```\n\n\n## Details\n\nYou can read more about the reactification-process in [this here](https://dev.to/thepassle/reactifying-custom-elements-using-a-custom-elements-manifest-2e) blogpost.\n\n### Slots\n\nAny children passed to the React component will get passed through to the custom element using `{children}`.\n\nExample:\n```jsx\nexport function GenericSwitch({children}) {\n  return \u003cgeneric-switch\u003e{children}\u003c/generic-switch\u003e\n}\n```\n\n#### Usage:\n```jsx\n\u003cGenericSwitch\u003e\n  Toggle me!\n\n  \u003cdiv slot=\"namedslot\"\u003e\n    This gets projected to `namedslot`\n  \u003c/div\u003e\n\u003c/GenericSwitch\u003e\n```\n\n### Properties\n\n`cem-plugin-reactify` makes a decision on whether to use an attribute or property based on whether or not an attribute has a corresponding `fieldName`. If an attribute does have a `fieldName`, the attribute will get ignored, but the property will be used instead.\n\nPrivate and protected fields will be ignored.\n\nExample:\n\n```jsx\nfunction GenericSwitch({checked}) {\n  const ref = useRef(null);\n\n  useEffect(() =\u003e {\n    if(ref.current.checked !== undefined) {\n      ref.current.checked = checked;\n    }\n  }, [checked]);\n\n  return \u003cgeneric-switch ref={ref}\u003e\u003c/generic-switch\u003e\n}\n```\n\n#### Usage:\n```jsx\n\u003cGenericSwitch checked={true}/\u003e\n```\n\n```jsx\n\u003cGenericList complexProperty={[{name: 'peter'}]}/\u003e\n```\n\n\n### Attributes\n\nSince values in React get passed as JavaScript variables, it could be the case that an attribute name clashes with a React or JS reserved keyword. For example: a custom element could have a `for` attribute, which is a reserved keyword in JavaScript. In the plugin's configuration, you can specify an `attributeMapping` to prevent this clash from happening, and rename the value that gets passed to the attribute. The attribute name itself will remain untouched.\n\nExample:\n```js\nexport default {\n  plugins: [\n    reactify({\n      attributeMapping: {\n        for: '_for',\n      },\n    }),\n  ],\n};\n```\n\nWill result in:\n```jsx\nfunction GenericSkiplink({_for}) {\n  return \u003cgeneric-skiplink for={_for}\u003e\u003c/generic-skiplink\u003e\n}\n```\n\nAdditionally, boolean attributes will receive a special handling.\n\nExample:\n```jsx\nfunction GenericSwitch({checked}) {\n  const ref = useRef(null);\n\n  useEffect(() =\u003e {\n    if (disabled !== undefined) {\n      if (disabled) {\n        ref.current.setAttribute(\"disabled\", \"\");\n      } else {\n        ref.current.removeAttribute(\"disabled\");\n      }\n    }\n  }, [disabled]);\n\n  return \u003cgeneric-switch ref={ref}\u003e\u003c/generic-switch\u003e\n}\n```\n\n#### Usage:\n```jsx\n\u003cGenericSwitch label={'hello world'}/\u003e  // regular attribute\n```\n```jsx\n\u003cGenericSwitch disabled={true}/\u003e        // boolean attribute\n```\n\n\n\n### Events\n\nEvent names are capitalized, camelized and prefixed with `'on'`, so: `'selected-changed'` becomes `onSelectedChanged`.\n\nExample:\n```jsx\nfunction GenericSwitch({onCheckedChanged}) {\n  const ref = useRef(null);\n\n  useEffect(() =\u003e {\n    if(onCheckedChanged !== undefined) {\n      ref.current.addEventListener(\"checked-changed\", onCheckedChanged);\n    }\n  }, []);\n\n  return \u003cgeneric-switch ref={ref}\u003e\u003c/generic-switch\u003e\n}\n```\n\n#### Usage:\n```jsx\n\u003cGenericSwitch onCheckedChanged={e =\u003e console.log(e)}/\u003e\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthepassle%2Fcem-plugin-reactify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthepassle%2Fcem-plugin-reactify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthepassle%2Fcem-plugin-reactify/lists"}