{"id":22886768,"url":"https://github.com/evolutionjobs/polymer-vdom","last_synced_at":"2025-06-25T10:36:44.802Z","repository":{"id":101027659,"uuid":"100602491","full_name":"EvolutionJobs/polymer-vdom","owner":"EvolutionJobs","description":"Virtual DOM builder for Polymer","archived":false,"fork":false,"pushed_at":"2017-08-30T06:44:35.000Z","size":31,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-07T10:53:16.037Z","etag":null,"topics":["dom","jsx","polymer","polymer-components","polymer-vdom","shadow-dom"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/EvolutionJobs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-17T12:43:43.000Z","updated_at":"2018-09-30T01:42:51.000Z","dependencies_parsed_at":null,"dependency_job_id":"6e1463b5-6b98-4d97-9409-5ae4f926bb38","html_url":"https://github.com/EvolutionJobs/polymer-vdom","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/EvolutionJobs/polymer-vdom","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EvolutionJobs%2Fpolymer-vdom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EvolutionJobs%2Fpolymer-vdom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EvolutionJobs%2Fpolymer-vdom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EvolutionJobs%2Fpolymer-vdom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EvolutionJobs","download_url":"https://codeload.github.com/EvolutionJobs/polymer-vdom/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EvolutionJobs%2Fpolymer-vdom/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261853211,"owners_count":23219824,"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":["dom","jsx","polymer","polymer-components","polymer-vdom","shadow-dom"],"created_at":"2024-12-13T20:27:44.362Z","updated_at":"2025-06-25T10:36:44.777Z","avatar_url":"https://github.com/EvolutionJobs.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Polymer VDOM\r\n\r\nI like React, especially its core idea of Virtual DOM - objects that represent the DOM and can be merged with it rapidly, allowing it to quickly and easily build and alter large amounts of HTML. React uses JSX tools to build low level JS.\r\n\r\nI like Polymer, expecially its core idea of **#UseThePlatform** - it extends and shims web components and shadow DOM to make them easier to build modular applications. Polymer doesn't help with building lots of dynamic HTML content - `dom-if` and `dom-repeat` templates are useful, but painful where a lot of content can change.\r\n\r\nReact has its own component model; Polymer uses the platform's component model. It seems to make a lot of sense to use the component model that's actually built into the browser, rather than a proprietary one (even if it's good, and React's is). \r\n\r\nPolymer components can be used (to some extent) in React JSX, but not the other way round (though you can add wrappers to achieve this), and there are a couple of conflicts. Downloading all of React (or even Preact) just to use the JSX VDOM builder is a lot of overhead. \r\n\r\nThe goal of this project is to use JSX tools (where appropriate) to build the shadow DOM in Polymer components, with minimal overhead.\r\n\r\n## Demo \r\n\r\n`\u003ccalendrical-heatmap\u003e` has a [sample version](https://github.com/EvolutionJobs/calendrical-heatmap/blob/master/calendrical-heatmap.tsx) written using this.\r\n\r\n## Set Up\r\n\r\nFor TypeScript `*.tsx` support include [`builder.ts`](Builder.ts) and [`polymer-vdom.ts`](polymer-vdom.js), and set `tsconfig.json` to tell `tsc` to output `h` when parsing JSX:\r\n\r\n```json\r\n{\r\n  \"compilerOptions\": {\r\n    \"jsx\": \"react\",\r\n    \"jsxFactory\": \"h\"\r\n  }\r\n}\r\n```\r\n\r\nFor JSX `*.jsx` support include [`polymer-vdom.js`](polymer-vdom.js), and update `.babelrc` (assuming Babel 6):\r\n\r\n```json\r\n{\r\n  \"plugins\": [\r\n    [\"transform-react-jsx\", { \"pragma\":\"h\" }]\r\n  ]\r\n}\r\n```\r\n\r\nThese are the same settings as for Preact, the the config are interchangeable.\r\n\r\n## Example\r\n\r\nUse the mixin `WithVdom` around `Polymer.Element`, `HTMLElement` or whatever you want to extend. \r\nInside that class you can use `render` to output JSX into the attached shadow DOM:\r\n\r\n```js\r\nimport WithVdom from './polymer-vdom.js'\r\nclass VdomTest extends WithVdom(Polymer.Element) {\r\n    static get is() { return 'vdom-test'; }\r\n\r\n    ready() {\r\n        super.ready();\r\n        super.render(\u003cdiv\u003eThe time is {new Date()}\u003c/div\u003e);\r\n    }\r\n}\r\n\r\ncustomElements.define(VdomTest.is, VdomTest);\r\n```\r\n\r\nEach time `render()` is called the shadow DOM root is updated with the new JSX content, following the same rules as React for keys:\r\n\r\n```js\r\nsuper.render(\u003cul\u003e\r\n    \u003cli key=\"b\"\u003eB\u003c/li\u003e\r\n    \u003cli key=\"c\"\u003eC\u003c/li\u003e\r\n\u003c/ul\u003e);\r\n\r\n// This will add the \"a\" \u003cli\u003e and remove the \"c\", rather than update two nodes\r\nsuper.render(\u003cul\u003e\r\n    \u003cli key=\"a\"\u003eA\u003c/li\u003e\r\n    \u003cli key=\"b\"\u003eB\u003c/li\u003e\r\n\u003c/ul\u003e);\r\n```\r\n\r\nWhere this differs from React is the component model - names of component classes wll be ignored. Instead use any tags registered with `customElements.define`:\r\n\r\n```js\r\n// Bad\r\nsuper.render(\u003cdiv\u003e\u003cVdomTest /\u003e\u003c/div\u003e);\r\n\r\n// Good #usetheplatform\r\nsuper.render(\u003cdiv\u003e\u003cvdom-test\u003e\u003c/vdom-test\u003e\u003c/div\u003e);\r\n```\r\n\r\nAt the moment this code needs to be in a `*.tsx`|`*.jsx` file. Next step will be build tools to add the JSX output to a `\u003cscript\u003e` tag in and HTML import.\r\n\r\nEvents can use Preact inline (`onclick`) or Polymer hyphens (`on-click`). \r\nHowever, web components also allow mixed case events, which means React's camelCase (`onClick`) is not supported.\r\n\r\n## Using Without JSX\r\n\r\nYou can render VDOM without the JSX step:\r\n\r\n```js\r\n// Using VDOM objects\r\nsuper.render({\r\n  type: 'ul',\r\n  props: {\r\n    children: [\r\n      { type: 'li', props: { key: 'a', children: 'A' } },\r\n      { type: 'li', props: { key: 'b', children: 'B' } }\r\n    ]\r\n  })\r\n\r\n// Or function calls JSX outputs to\r\nsuper.render(\r\n  h('ul', null\r\n    h('li', { key: 'a' }, 'A'),\r\n    h('li', { key: 'b' }, 'B'))\r\n```\r\n\r\nIt's recommended to use TypeScript (or some other type checker) if doing this to find errors at compile time. \r\nImplement `JSX.Element` from [JSX.d.ts](JSX.d.ts). ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevolutionjobs%2Fpolymer-vdom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fevolutionjobs%2Fpolymer-vdom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevolutionjobs%2Fpolymer-vdom/lists"}