{"id":13660854,"url":"https://github.com/geocine/custom-elements-ts","last_synced_at":"2025-03-16T12:32:19.303Z","repository":{"id":148352306,"uuid":"140132447","full_name":"geocine/custom-elements-ts","owner":"geocine","description":" Create native custom elements using Typescript","archived":false,"fork":false,"pushed_at":"2020-04-24T23:15:18.000Z","size":866,"stargazers_count":62,"open_issues_count":5,"forks_count":10,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-02-27T08:54:13.467Z","etag":null,"topics":["custom-elements","decorators","shadow-dom","typescript","web-components"],"latest_commit_sha":null,"homepage":"https://geocine.github.io/custom-elements-ts/","language":"TypeScript","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/geocine.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,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-07-08T02:49:11.000Z","updated_at":"2024-08-17T21:42:00.000Z","dependencies_parsed_at":"2023-09-06T19:02:53.331Z","dependency_job_id":null,"html_url":"https://github.com/geocine/custom-elements-ts","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geocine%2Fcustom-elements-ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geocine%2Fcustom-elements-ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geocine%2Fcustom-elements-ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geocine%2Fcustom-elements-ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/geocine","download_url":"https://codeload.github.com/geocine/custom-elements-ts/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243814880,"owners_count":20352037,"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","decorators","shadow-dom","typescript","web-components"],"created_at":"2024-08-02T05:01:26.635Z","updated_at":"2025-03-16T12:32:18.940Z","avatar_url":"https://github.com/geocine.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# custom-elements-ts\n\n[![Coverage Status](https://coveralls.io/repos/github/geocine/custom-elements-ts/badge.svg?branch=master)](https://coveralls.io/github/geocine/custom-elements-ts?branch=master) \n[![Build Status](https://travis-ci.org/geocine/custom-elements-ts.svg?branch=master)](https://travis-ci.org/geocine/custom-elements-ts)\n[![npm version](https://badge.fury.io/js/custom-elements-ts.svg)](https://www.npmjs.com/package/custom-elements-ts)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\n\nCreate native custom elements using Typescript without using any third party libraries.\n\n```\nnpm install custom-elements-ts\n```\n\n## Usage\n\n```ts\nimport { CustomElement } from 'custom-elements-ts';\n\n@CustomElement({\n  tag: 'counter-element',\n  templateUrl: 'counter-element.html',\n  styleUrl: 'counter-element.scss'\n})\nexport class CounterElement extends HTMLElement {\n  // code as you would when creating a native HTMLElement\n  // full source code is at demo/counter\n}\n```\n\n```html\n\u003c!--index.html--\u003e\n\u003ccounter-element\u003e\u003c/counter-element\u003e\n\u003cscript src=\"counter.umd.js\"\u003e\u003c/script\u003e\n```\n\n## Decorators\n\n| Decorator   | Target   | Parameters         | Description                                                                                                                                                                       |\n|-------------|----------|--------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| @Prop()     | property | -                  | custom attribute/properties, reflects primitive properties to attributes                                                                                                          |\n| @Toggle()   | property | -                  | boolean attribute/properties, it is based on the presence of the attribute but also works with \"true\" and \"false\"                                                                 |\n| @Dispatch() | property | (event?)           | used to declare a CustomEvent which you could dispatch using the `.emit` method of its type `DispatchEmitter`. The `event` parameter is used to set the name of the `CustomEvent` |\n| @Watch()    | method   | (property)         | triggers the method when a `property` is changed                                                                                                                                  |\n| @Listen()   | method   | (event, selector?) | listens to an `event` on the `host` element or on the `selector` if specified                                                                                                     |\n\n### @Prop()\n```ts\nimport { CustomElement, Prop } from 'custom-elements-ts';\n\n@CustomElement({\n  tag: 'todo-list',\n  ...\n})\nexport class TodoList extends HTMLElement {\n  @Prop() color: string;\n  @Prop() list: TodoItem[];\n}\n```\nSince `color` is a primitive type of `string` it can be accessed via attributes and properties\n```ts\nconst element = document.querySelector('todo-list');\n// accessing value via attribute\nconst attrValue = element.getAttribute('color');\n// setting value via attribute\nelement.setAttribute('color', 'red');\n \n// accessing value via property\nconst propertyValue = element.color;\n// setting via property\nelement.color = 'red';\n```\n\nOn the other hand `list` is a rich data type (objects or arrays) can only be accessed/set via property\n\n### @Toggle()\nToggle attributes work the same way as HTML boolean attributes as defined by [W3C](http://www.w3.org/TR/2008/WD-html5-20080610/semantics.html#boolean) for the most part. We changed a few things to overcome confusion. Check the table below for reference:\n\n| Markup                        | `disabled` | Description                                                          |\n|-------------------------------|------------|----------------------------------------------------------------------|\n| `\u003cc-input /\u003e`                 | false      | Follows W3C standard                                                 |\n| `\u003cc-input disabled/\u003e`         | true       | Follows W3C standard                                                 |\n| `\u003cc-input disabled=\"true\"/\u003e`  | true       | Follows W3C standard                                                 |\n| `\u003cc-input disabled=\"asd\"/\u003e`   | false      | `false` since `asd` does not evaluate to a valid boolean             |\n| `\u003cc-input disabled=\"false\"/\u003e` | false      | `false` since the boolean `false` converted to a string is `\"false\"` |\n| `\u003cc-input disabled=\"true\"/\u003e`  | true       | `true` since the boolean `true` converted to a string is `\"true\"`    |\n\n### @Dispatch()\n\n**Creating a custom event**\n\n```ts\nimport { CustomElement, Dispatch, DispatchEmitter } from 'custom-elements-ts';\n\n...\nexport class TodoList extends HTMLElement {\n  // Creating a CustomEvent\n  // custom event name will be `on.change`\n  @Dispatch() onChange: DispatchEmitter;\n\n  // Creating a CustomEvent with custom name `ce.select` \n  @Dispatch('ce.select') onSelect: DispatchEmitter;\n}\n```\n**Triggering the custom event** from the example above:\n\n```ts\n  triggerOnChange() {\n    // adding more data to the event object\n    this.onChange.emit({detail: 'event changed'});\n    this.onSelect.emit({detail: 'select triggered'});\n  }\n```\n### @Watch()\n\n```ts\nimport { CustomElement, Dispatch, Prop } from 'custom-elements-ts';\n\n...\nexport class TodoList extends HTMLElement {\n  @Prop() color: string;\n\n  @Watch('color')\n  colorChanged() {\n    // trigger when color property color changes\n    // either via property or attribute\n  }\n}\n```\n\n### @Listen()\n\nListen has parameters `event` and `selector`. `Event` is any valid javascript event. `Selector` is anything that works with [querySelector()](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)\n\n```ts\nimport { CustomElement, Dispatch, Prop } from 'custom-elements-ts';\n\n...\nexport class TodoList extends HTMLElement {\n  @Listen('click')\n  elementClicked() {\n    // triggers when the element is clicked\n  }\n\n  @Listen('click','a')\n  anchorClicked() {\n    // triggers when an `a` inside the element is clicked\n  }\n}\n```\n\n## Setup\n\n### Running the demos\n\n```\nnpm start \u003celement-name\u003e\n```\n\n### Building the demo\n\n```\nnpm run build \u003celement-name\u003e\n```\nIf you want to create a minified bundle\n```\nnpm run build -- \u003celement-name\u003e --prod\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeocine%2Fcustom-elements-ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeocine%2Fcustom-elements-ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeocine%2Fcustom-elements-ts/lists"}