{"id":13341607,"url":"https://github.com/iconstorm/lol-element","last_synced_at":"2025-03-11T22:31:16.113Z","repository":{"id":40653661,"uuid":"350840698","full_name":"iconstorm/lol-element","owner":"iconstorm","description":"A JavaScript base class for creating Web Components like you know what you're doing","archived":false,"fork":false,"pushed_at":"2022-08-12T17:24:39.000Z","size":199,"stargazers_count":1,"open_issues_count":5,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-18T23:17:33.126Z","etag":null,"topics":["javascript","javascript-library","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/iconstorm.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-03-23T19:58:10.000Z","updated_at":"2022-08-03T08:19:32.000Z","dependencies_parsed_at":"2022-08-10T00:01:14.456Z","dependency_job_id":null,"html_url":"https://github.com/iconstorm/lol-element","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iconstorm%2Flol-element","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iconstorm%2Flol-element/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iconstorm%2Flol-element/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iconstorm%2Flol-element/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iconstorm","download_url":"https://codeload.github.com/iconstorm/lol-element/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243125140,"owners_count":20240263,"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":["javascript","javascript-library","web-components"],"created_at":"2024-07-29T19:25:39.142Z","updated_at":"2025-03-11T22:31:15.352Z","avatar_url":"https://github.com/iconstorm.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lol element\n\n![npm (scoped)](https://img.shields.io/npm/v/@iconstorm/lol-element) ![npm bundle size (scoped)](https://img.shields.io/bundlephobia/minzip/@iconstorm/lol-element)\n\nA JavaScript base class for creating Web Components like you know what you're doing.\n\n## Goals\n\n🧬 **tiny API**: if you need to invest time in learning something, let it be how custom elements work and not ephemeral library APIs.\n\n😵‍💫 **just enough abstractions**: custom elements can be cool, but they're definitely not fancy, it is what it is.\n\n🫒 **small and lightweight**: if you need to debug, start confidently with your own code, it's probably not lol.\n\n🕳 **no build step necessary**: if you enjoy spending hours debugging a cryptic compile error in the terminal and hunting for that buggy dependency, we don't.\n\n🍭 **a list with random emoji in the README**: checked.\n\n## Install\n\nWith npm (or similar):\n\n```\nnpm install @iconstorm/lol-element\n```\n\nVia CDN, you can use a script tag:\n\n```html\n\u003cscript src=\"https://unpkg.com/@iconstorm/lol-element\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  const { LOL, css, html } = lol // global window.lol is made available\n\u003c/script\u003e\n```\n\nor hotlink in your ES modules:\n\n```js\nimport { LOL, css, html } from 'https://unpkg.com/@iconstorm/lol-element?module'\n```\n\n## Usage\n\n\u003cdetails\u003e\n  \u003csummary\u003eStarting with Web Components and custom HTML elements?\u003c/summary\u003e\n\n  Please go read the chapter dedicated to them on [the great javascript.info site](https://javascript.info/custom-elements). Once you're familiar with custom elements in general, you'll be enjoying LOL within minutes.\n  \n  Also the [Classes chapter](https://javascript.info/classes) is a recommended read.\n\u003c/details\u003e\n\nNo build step or transpiling is necessary. All of this just works in the browser.\n\nDefine a component:\n\n```js\nimport { LOL, html, css } from 'https://unpkg.com/@iconstorm/lol-element'\n\nclass HelloWorld extends LOL {\n  static get attributes () {\n    return { name: 'with-exclamation-mark', boolean: true }\n  }\n\n  static get styles () {\n    return css`\n      span { font-size: 300%; }\n    `\n  }\n\n  template () {\n    return html`\n      \u003cspan\u003eHello World${this.withExclamationMark ? '!' : ''}\u003c/span\u003e\n    `\n  }\n}\n\ncustomElements.define('lol-hello-world', HelloWorld)\n```\n\nUse it in your markup:\n\n```html\n\u003clol-hello-world with-exclamation-mark\u003e\u003c/lol-hello-world\u003e\n```\n\n🍩 [Try this on CodePen.](https://codepen.io/acstll/pen/oNWNrgb)\n\n## API\n\n- [`LOL` class](#the-lol-class)\n  - [static `shadowOptions`](#static-shadowoptions-static-getter-or-property)\n  - [static `attributes`](#static-attributes-static-getter-or-property)\n  - [static `styles`](#static-styles-static-getter-or-property)\n  - [`template()`](#template-method)\n  - [`changed()`](#changed-method)\n  - [`{propertyName}Changed()`](#propertynamechanged-method)\n  - [`emit()`](#emit-method)\n  - [`render()`](#render-method)\n  - [`renderRoot`](#renderroot-property)\n- [Lifecycle callbacks](#lifecycle-callbacks)\n- [Template syntax](#template-syntax)\n- [Named exports](#named-exports)\n\n### The `LOL` class\n\n#### static `shadowOptions` _static (getter or property)_\n\nDefine the [Shadow DOM options](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow#syntax) being passed to the `attachShadow()` call.\n\nDefaults to `{ mode: 'open' }`. Use `null` to not use Shadow DOM.\n\n---\n\n#### static `attributes` _static (getter or property)_\n\nDefine the element's attributes to be observed with an array of names or [config objects](https://github.com/iconstorm/lol-element/blob/main/src/lol-element.js#L157), with following keys:\n\n- `name` string: The name of the attribute\n- `reflect` boolean (default: `true`): Whether the attribute should be reflected in a property \n- `boolean` boolean (default: `false`): Whether the attribute is a [boolean type of attribute](https://developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML/Getting_started#boolean_attributes)\n- `read` function (default: `x =\u003e x`): A function to process the property value being accessed\n- `write` function (default: `x =\u003e x`): A function to process the value being set in the attribute\n- `fallbackValue`: The value returned by the property getter when the attribute is missing\n\nExcept for `name`, all options are optional.\n\nAn attribute being reflected means that for a given `foo-bar` attribute, a `fooBar` getter/setter property will be created. So assigning a value to `fooBar` will set the same value to the `foo-bar` attribute. `LOL` has no observable/reactivity system, for simplicity's sake, it leverages the browser's via `attributeChangedCallback`.\n\n\u003cdetails\u003e\n  \u003csummary\u003eAttributes and props?\u003c/summary\u003e\n\n  Attributes live in HTML, properties belong in JavaScript objects. If the different is not clear, [stack overflow is your friend](https://stackoverflow.com/a/6004028). This can create some confusion. This [post by Rich Harris](https://dev.to/richharris/why-i-don-t-use-web-components-2cia) can be interesting (scroll down to part 6).\n\u003c/details\u003e\n\n---\n\n#### static `styles` _static (getter or property)_\n\nDefine the styles for the component with CSS. The ` css`` ` template literal tag must be used.\n\n\u003cdetails\u003e\n  \u003csummary\u003eExample\u003c/summary\u003e\n\n  ```js\n  import { css } from '@iconstorm/lol-element'\n  \n  // ..\n  \n  static get styles() {\n    return css`\n      :host {\n        font-size: 100%;\n      }\n    `\n  }\n  ```\n\u003c/details\u003e\n\n---\n\n#### `template()` _method_\n\nDefine the markup of the component, the ` html`` ` template literal tag must be used.\n\nParameters:\n- `host` object: The element instance\n\n🔥 This method is usually called `render()` in many libraries and frameworks.\n\n\u003cdetails\u003e\n  \u003csummary\u003eExample\u003c/summary\u003e\n\n  ```js\n  import { html } from '@iconstorm/lol-element'\n  \n  // ..\n  \n  template() {\n    return html`\n      \u003cp\u003eLoren ipsum\u003c/p\u003e\n    `\n  }\n  ```\n\u003c/details\u003e\n\n---\n\n#### `changed()` _method_\n\nFires every time an attribute is added, removed, or changed. This is only an alias for `attributeChangedCallback` for the convenience of avoiding `super.attributeChangedCallback()`.\n\nParameters:\n- `name` string: The name of the attribute the changed\n- `oldValue` string\n- `newValue` string\n\n---\n\n#### `{propertyName}Changed()` _method_\n\nAn individual callback for every observed attribute, when implemented. For example, every time the `foo-bar` attribute changes, if there's a `fooBarChanged()` method defined, it will be called.\n\nParameters:\n- `oldValue` string\n- `newValue` string\n\n---\n\n#### `emit()` _method_\n\nA helper to dispatch custom events from within the element.\n\nParameters:\n- `eventName` string: The name of the event\n- `detail` any: The thing being emitted, available in `event.detail`\n- `options` object: any other options for the event, defaults to `{ bubbles: true, cancelable: true }`\n\n---\n\n#### `render()` _method_\n\nCall this method to trigger a DOM update. You shouldn't need to implement this method.\n\n---\n\n#### `renderRoot` _property_ \n\nThe DOM node where rendering happens. This is either the element's [`shadowRoot`](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot) (when using Shadow DOM) or the host element itself (when not).\n\n### Lifecycle callbacks\n\nApart from `changed()` and `{propertyName}Changed()`, no other lifecycle callbacks are provided other than the ones offered by default in HTMLElement:\n\n- `constructor()`\n- `connectedCallback()`\n- `attributeChangedCallback()`\n- `disconnectedCallback()`\n\n\u003e See [Using the lifecycle callbacks](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements#using_the_lifecycle_callbacks) in MDN.\n\n\u003cdetails\u003e\n  \u003csummary\u003e⚠️ Don't forget the `super` keyword when using these.\u003c/summary\u003e\n\n  If you don't call `super` on `constructor`, `connectedCallback` and `attributeChangedCallback`, things will break.\n\n  ```js\n  class MyComponent extends LOL {\n    constructor() {\n      super()\n      // ..\n    }\n\n    connectedCallback() {\n      super.connectedCallback()\n      // ..\n    }\n\n    attributeChangedCallback() {\n      super.attributeChangedCallback()\n      // ..\n    }\n  } \n  ```\n\n  More info: https://javascript.info/class-inheritance#overriding-a-method\n\u003c/details\u003e\n\n### Template syntax\n\nSee [µhtml](https://www.npmjs.com/package/uhtml) for now.\n\n### Named exports\n\n- `LOL` - extends `LOLElement`, \n- `LOLElement` - extends `HTMLELement`, `render()` is not implemented\n- `css`\n- `html`*\n- `svg`*\n\n```js\nimport { LOL, LOLElement, css, html, svg } from '@iconstorm/lol-element'\n```\n\n*implementation may vary depending on _flavor_ (more on this soon).\n\n## Thank-yous (prior art)\n\n- [FAST](https://github.com/microsoft/fast/)\n- [swiss](https://github.com/luwes/swiss)\n- [Lit](https://github.com/lit/lit/)\n- [Stencil](https://github.com/ionic-team/stencil)\n- [hybrids](https://github.com/hybridsjs/hybrids)\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ficonstorm%2Flol-element","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ficonstorm%2Flol-element","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ficonstorm%2Flol-element/lists"}