lit-element
Advanced tools
Comparing version 1.0.0 to 2.0.0-dev.2283329
@@ -1,71 +0,199 @@ | ||
import { html, render as litRender } from '../lit-html/lit-html.js' | ||
export default class LitElement extends HTMLElement { | ||
constructor() { | ||
super(); | ||
this.attachShadow({mode: "open"}); | ||
/** | ||
* @license | ||
* Copyright (c) 2017 The Polymer Project Authors. All rights reserved. | ||
* This code may only be used under the BSD style license found at | ||
* http://polymer.github.io/LICENSE.txt | ||
* The complete set of authors may be found at | ||
* http://polymer.github.io/AUTHORS.txt | ||
* The complete set of contributors may be found at | ||
* http://polymer.github.io/CONTRIBUTORS.txt | ||
* Code distributed by Google as part of the polymer project is also | ||
* subject to an additional IP rights grant found at | ||
* http://polymer.github.io/PATENTS.txt | ||
*/ | ||
import { TemplateResult } from 'lit-html'; | ||
import { render } from 'lit-html/lib/shady-render'; | ||
import { UpdatingElement } from './lib/updating-element.js'; | ||
export * from './lib/updating-element.js'; | ||
export * from './lib/decorators.js'; | ||
export { html, svg, TemplateResult, SVGTemplateResult } from 'lit-html/lit-html'; | ||
import { supportsAdoptingStyleSheets } from './lib/css-tag.js'; | ||
export * from './lib/css-tag.js'; | ||
// IMPORTANT: do not change the property name or the assignment expression. | ||
// This line will be used in regexes to search for LitElement usage. | ||
// TODO(justinfagnani): inject version number at build time | ||
(window['litElementVersions'] || (window['litElementVersions'] = [])) | ||
.push('2.0.0'); | ||
/** | ||
* Minimal implementation of Array.prototype.flat | ||
* @param arr the array to flatten | ||
* @param result the accumlated result | ||
*/ | ||
function arrayFlat(styles, result = []) { | ||
for (let i = 0, length = styles.length; i < length; i++) { | ||
const value = styles[i]; | ||
if (Array.isArray(value)) { | ||
arrayFlat(value, result); | ||
} | ||
else { | ||
result.push(value); | ||
} | ||
} | ||
connectedCallback() { | ||
const props = this.constructor.properties; | ||
for(let prop in props) { | ||
if(typeof props[prop] === 'object') { | ||
this._makeComplexGetterSetter(prop, props[prop]) | ||
} else { | ||
this._makeGetterSetter(prop, props[prop]) | ||
} | ||
return result; | ||
} | ||
/** Deeply flattens styles array. Uses native flat if available. */ | ||
const flattenStyles = (styles) => styles.flat ? styles.flat(Infinity) : arrayFlat(styles); | ||
export class LitElement extends UpdatingElement { | ||
/** @nocollapse */ | ||
static finalize() { | ||
super.finalize(); | ||
// Prepare styling that is stamped at first render time. Styling | ||
// is built from user provided `styles` or is inherited from the superclass. | ||
this._styles = | ||
this.hasOwnProperty(JSCompiler_renameProperty('styles', this)) ? | ||
this._getUniqueStyles() : | ||
this._styles || []; | ||
} | ||
/** @nocollapse */ | ||
static _getUniqueStyles() { | ||
// Take care not to call `this.styles` multiple times since this generates | ||
// new CSSResults each time. | ||
// TODO(sorvell): Since we do not cache CSSResults by input, any | ||
// shared styles will generate new stylesheet objects, which is wasteful. | ||
// This should be addressed when a browser ships constructable | ||
// stylesheets. | ||
const userStyles = this.styles; | ||
const styles = []; | ||
if (Array.isArray(userStyles)) { | ||
const flatStyles = flattenStyles(userStyles); | ||
// As a performance optimization to avoid duplicated styling that can | ||
// occur especially when composing via subclassing, de-duplicate styles | ||
// preserving the last item in the list. The last item is kept to | ||
// try to preserve cascade order with the assumption that it's most | ||
// important that last added styles override previous styles. | ||
const styleSet = flatStyles.reduceRight((set, s) => { | ||
set.add(s); | ||
// on IE set.add does not return the set. | ||
return set; | ||
}, new Set()); | ||
// Array.from does not work on Set in IE | ||
styleSet.forEach((v) => styles.unshift(v)); | ||
} | ||
litRender(this.render(), this.shadowRoot); | ||
else if (userStyles) { | ||
styles.push(userStyles); | ||
} | ||
return styles; | ||
} | ||
_makeGetterSetter(prop, val) { | ||
if(!this.__data) | ||
this.__data = {}; | ||
Object.defineProperty(this, prop, { | ||
get() { | ||
return this.__data[prop] | ||
}, | ||
set(val) { | ||
this.__data[prop] = val; | ||
this._propertiesChanged() | ||
} | ||
}) | ||
this[prop] = undefined; | ||
/** | ||
* Performs element initialization. By default this calls `createRenderRoot` | ||
* to create the element `renderRoot` node and captures any pre-set values for | ||
* registered properties. | ||
*/ | ||
initialize() { | ||
super.initialize(); | ||
this.renderRoot = this.createRenderRoot(); | ||
// Note, if renderRoot is not a shadowRoot, styles would/could apply to the | ||
// element's getRootNode(). While this could be done, we're choosing not to | ||
// support this now since it would require different logic around de-duping. | ||
if (window.ShadowRoot && this.renderRoot instanceof window.ShadowRoot) { | ||
this.adoptStyles(); | ||
} | ||
} | ||
_makeComplexGetterSetter(prop, info) { | ||
if(!this.__data) | ||
this.__data = {}; | ||
Object.defineProperty(this, prop, { | ||
get() { | ||
if(info.reflectToAttribute) { | ||
if(info.type === Object || info.type === Array) | ||
console.warn('Rich Data shouldn\'t be set as attribte!') | ||
return this.getAttribute(prop); | ||
} else return this.__data[prop]; | ||
}, | ||
set(val) { | ||
if(info.reflectToAttribute) { | ||
if(info.type === Object || info.type === Array) | ||
console.warn('Rich Data shouldn\'t be set as attribte!') | ||
this.setAttribute(prop, val); | ||
} else this.__data[prop] = val; | ||
this._propertiesChanged(); | ||
} | ||
}); | ||
if(info.value) { | ||
typeof info.value === 'function' | ||
? this[prop] = info.value() | ||
: this[prop] = info.value; | ||
/** | ||
* Returns the node into which the element should render and by default | ||
* creates and returns an open shadowRoot. Implement to customize where the | ||
* element's DOM is rendered. For example, to render into the element's | ||
* childNodes, return `this`. | ||
* @returns {Element|DocumentFragment} Returns a node into which to render. | ||
*/ | ||
createRenderRoot() { | ||
return this.attachShadow({ mode: 'open' }); | ||
} | ||
/** | ||
* Applies styling to the element shadowRoot using the `static get styles` | ||
* property. Styling will apply using `shadowRoot.adoptedStyleSheets` where | ||
* available and will fallback otherwise. When Shadow DOM is polyfilled, | ||
* ShadyCSS scopes styles and adds them to the document. When Shadow DOM | ||
* is available but `adoptedStyleSheets` is not, styles are appended to the | ||
* end of the `shadowRoot` to [mimic spec | ||
* behavior](https://wicg.github.io/construct-stylesheets/#using-constructed-stylesheets). | ||
*/ | ||
adoptStyles() { | ||
const styles = this.constructor._styles; | ||
if (styles.length === 0) { | ||
return; | ||
} | ||
// There are three separate cases here based on Shadow DOM support. | ||
// (1) shadowRoot polyfilled: use ShadyCSS | ||
// (2) shadowRoot.adoptedStyleSheets available: use it. | ||
// (3) shadowRoot.adoptedStyleSheets polyfilled: append styles after | ||
// rendering | ||
if (window.ShadyCSS !== undefined && !window.ShadyCSS.nativeShadow) { | ||
window.ShadyCSS.ScopingShim.prepareAdoptedCssText(styles.map((s) => s.cssText), this.localName); | ||
} | ||
else if (supportsAdoptingStyleSheets) { | ||
this.renderRoot.adoptedStyleSheets = | ||
styles.map((s) => s.styleSheet); | ||
} | ||
else { | ||
// This must be done after rendering so the actual style insertion is done | ||
// in `update`. | ||
this._needsShimAdoptedStyleSheets = true; | ||
} | ||
} | ||
_propertiesChanged() { | ||
litRender(this.render(), this.shadowRoot) | ||
connectedCallback() { | ||
super.connectedCallback(); | ||
// Note, first update/render handles styleElement so we only call this if | ||
// connected after first update. | ||
if (this.hasUpdated && window.ShadyCSS !== undefined) { | ||
window.ShadyCSS.styleElement(this); | ||
} | ||
} | ||
/** | ||
* Updates the element. This method reflects property values to attributes | ||
* and calls `render` to render DOM via lit-html. Setting properties inside | ||
* this method will *not* trigger another update. | ||
* * @param _changedProperties Map of changed properties with old values | ||
*/ | ||
update(changedProperties) { | ||
super.update(changedProperties); | ||
const templateResult = this.render(); | ||
if (templateResult instanceof TemplateResult) { | ||
this.constructor | ||
.render(templateResult, this.renderRoot, { scopeName: this.localName, eventContext: this }); | ||
} | ||
// When native Shadow DOM is used but adoptedStyles are not supported, | ||
// insert styling after rendering to ensure adoptedStyles have highest | ||
// priority. | ||
if (this._needsShimAdoptedStyleSheets) { | ||
this._needsShimAdoptedStyleSheets = false; | ||
this.constructor._styles.forEach((s) => { | ||
const style = document.createElement('style'); | ||
style.textContent = s.cssText; | ||
this.renderRoot.appendChild(style); | ||
}); | ||
} | ||
} | ||
/** | ||
* Invoked on each update to perform rendering tasks. This method must return | ||
* a lit-html TemplateResult. Setting properties inside this method will *not* | ||
* trigger the element to update. | ||
*/ | ||
render() { | ||
return html`Render Function not defined` | ||
} | ||
} | ||
} | ||
/** | ||
* Ensure this class is marked as `finalized` as an optimization ensuring | ||
* it will not needlessly try to `finalize`. | ||
*/ | ||
LitElement.finalized = true; | ||
/** | ||
* Render method used to render the lit-html TemplateResult to the element's | ||
* DOM. | ||
* @param {TemplateResult} Template to render. | ||
* @param {Element|DocumentFragment} Node into which to render. | ||
* @param {String} Element name. | ||
* @nocollapse | ||
*/ | ||
LitElement.render = render; | ||
//# sourceMappingURL=lit-element.js.map |
{ | ||
"name": "lit-element", | ||
"version": "2.0.0-dev.2283329", | ||
"description": "Polymer based lit-html custom element", | ||
"license": "BSD-3-Clause", | ||
"repository": "Polymer/lit-element", | ||
"main": "lit-element.js", | ||
"module": "lit-element.js", | ||
"directories": { | ||
"test": "test" | ||
}, | ||
"files": [ | ||
"/lib/", | ||
"/src/", | ||
"!/src/demo/", | ||
"!/src/test/", | ||
"/lit-element.d.ts", | ||
"/lit-element.d.ts.map", | ||
"/lit-element.js", | ||
"/lit-element.js.map" | ||
], | ||
"scripts": { | ||
"build": "tsc", | ||
"build:babel-test": "babel src/test/lib/decorators_test.ts --out-file test/lib/decorators-babel_test.js", | ||
"gen-docs": "typedoc --readme docs/_api/api-readme.md --tsconfig tsconfig_apidoc.json --mode modules --theme docs/_api/theme --excludeNotExported --excludePrivate --ignoreCompilerErrors --exclude '{**/*test*,**/node_modules/**,**/test/**}' --out ./docs/api --gaID UA-39334307-23 src/**/*.ts", | ||
"test": "npm run build && npm run build:babel-test && wct", | ||
"checksize": "rollup -c ; rm lit-element.bundled.js", | ||
"format": "find src test | grep '\\.js$\\|\\.ts$' | xargs clang-format --style=file -i", | ||
"lint": "tslint --project ./", | ||
"prepublishOnly": "npm run build", | ||
"prepare": "npm run build", | ||
"regen-package-lock": "rm -rf node_modules package-lock.json; npm install", | ||
"publish-dev": "npm test && VERSION=${npm_package_version%-*}-dev.`git rev-parse --short HEAD` && npm version --no-git-tag-version $VERSION && npm publish --tag dev" | ||
}, | ||
"author": "The Polymer Authors", | ||
"devDependencies": { | ||
"@babel/cli": "^7.2.3", | ||
"@babel/plugin-proposal-class-properties": "^7.2.3", | ||
"@babel/plugin-proposal-decorators": "^7.2.3", | ||
"@babel/plugin-transform-typescript": "^7.2.0", | ||
"@types/chai": "^4.0.1", | ||
"@types/mocha": "^5.2.4", | ||
"@webcomponents/shadycss": "^1.8.0", | ||
"@webcomponents/webcomponentsjs": "^2.2.3", | ||
"chai": "^4.0.2", | ||
"mocha": "^5.0.5", | ||
"rollup": "^0.64.1", | ||
"rollup-plugin-filesize": "^4.0.1", | ||
"rollup-plugin-node-resolve": "^3.4.0", | ||
"rollup-plugin-terser": "^1.0.1", | ||
"tslint": "^5.12.0", | ||
"typedoc": "^0.8.0", | ||
"typescript": "^3.2.2", | ||
"uglify-es": "^3.3.9", | ||
"wct-mocha": "^1.0.0", | ||
"web-component-tester": "^6.9.2" | ||
}, | ||
"typings": "lit-element.d.ts", | ||
"dependencies": { | ||
"lit-html": "^0.6.0" | ||
"lit-html": "1.0.0-dev.c8753bc" | ||
}, | ||
"name": "lit-element", | ||
"version": "1.0.0", | ||
"description": "Implements lit-html via a LitElement class. Made for custom Elements.", | ||
"main": "lit-element.js", | ||
"repository": "https://github.com/DiiLord/lit-element.git", | ||
"author": "DiiLord <d.drodt@gmx.de>", | ||
"license": "MIT" | ||
"publishConfig": { | ||
"access": "public" | ||
} | ||
} |
108
README.md
@@ -1,41 +0,85 @@ | ||
# lit-element | ||
Implements [lit-html](https://github.com/PolymerLabs/lit-html) via a LitElement class. Made for custom Elements. | ||
# LitElement | ||
A simple base class for creating fast, lightweight web components with [lit-html](https://lit-html.polymer-project.org/). | ||
## Default Usage | ||
[![Build Status](https://travis-ci.org/Polymer/lit-element.svg?branch=master)](https://travis-ci.org/Polymer/lit-element) | ||
[![Published on npm](https://img.shields.io/npm/v/lit-element.svg)](https://www.npmjs.com/package/lit-element) | ||
[![Published on webcomponents.org](https://img.shields.io/badge/webcomponents.org-published-blue.svg)](https://www.webcomponents.org/element/lit-element) | ||
[![Mentioned in Awesome lit-html](https://awesome.re/mentioned-badge.svg)](https://github.com/web-padawan/awesome-lit-html) | ||
```javascript | ||
// import html from lit-html | ||
import {html} from '../node-modules/lit-html/lit-html.js' | ||
## Documentation | ||
// import lit-element | ||
import LitElement from './lit-element.js' | ||
Full documentation is available at [lit-element.polymer-project.org](https://lit-element.polymer-project.org). | ||
// define Custom Element | ||
class MyElement extends LitElement { | ||
## Overview | ||
// define properties similiar to Polymer 2/3 | ||
static get properties() { | ||
return { | ||
title: String, | ||
body: { | ||
type: String, | ||
value: 'That is a cool LitElement' | ||
} | ||
} | ||
LitElement uses [lit-html](https://lit-html.polymer-project.org/) to render into the | ||
element's [Shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM) | ||
and adds API to help manage element properties and attributes. LitElement reacts to changes in properties | ||
and renders declaratively using `lit-html`. See the [lit-html guide](https://lit-html.polymer-project.org/guide) | ||
for additional information on how to create templates for lit-element. | ||
```ts | ||
import {LitElement, html, css, customElement, property} from 'lit-element'; | ||
// This decorator defines the element. | ||
@customElement('my-element'); | ||
export class MyElement extends LitElement { | ||
// This decorator creates a property accessor that triggers rendering and | ||
// an observed attribute. | ||
@property() | ||
mood = 'great'; | ||
static styles = css` | ||
span { | ||
color: green; | ||
}`; | ||
// Render element DOM by returning a `lit-html` template. | ||
render() { | ||
return html`Web Components are <span>${this.mood}</span>!`; | ||
} | ||
} | ||
// define your template in render | ||
render() { | ||
this.title = 'This is lit'; | ||
return html` | ||
<h1>${this.title}</h1> | ||
<p>${this.body}</h1> | ||
`; | ||
} | ||
} | ||
``` | ||
## Notes | ||
```html | ||
<my-element mood="awesome"></my-element> | ||
``` | ||
- This Element does not use Polymer, just Polymer-like syntax for properties. | ||
- Currently only `reflectToAttribute` and `value` are supported for properties. | ||
Note, this example uses decorators to create properties. Decorators are a proposed | ||
standard currently available in [TypeScript](https://www.typescriptlang.org/) or [Babel](https://babeljs.io/docs/en/babel-plugin-proposal-decorators). LitElement also supports a [vanilla JavaScript method](https://lit-element.polymer-project.org/guide/properties#declare) of declaring reactive properties. | ||
## Examples | ||
* Runs in all [supported](#supported-browsers) browsers: [Glitch](https://glitch.com/edit/#!/hello-lit-element?path=index.html) | ||
* Runs in browsers with [JavaScript Modules](https://caniuse.com/#search=modules): [Stackblitz](https://stackblitz.com/edit/lit-element-demo?file=src%2Fmy-element.js), [JSFiddle](https://jsfiddle.net/sorvell1/801f9cdu/), [JSBin](http://jsbin.com/vecuyan/edit?html,output), | ||
[CodePen](https://codepen.io/sorvell/pen/RYQyoe?editors=1000). | ||
* You can also copy [this HTML file](https://gist.githubusercontent.com/sorvell/48f4b7be35c8748e8f6db5c66d36ee29/raw/67346e4e8bc4c81d5a7968d18f0a6a8bc00d792e/index.html) into a local file and run it in any browser that supports [JavaScript Modules]((https://caniuse.com/#search=modules)). | ||
## Installation | ||
From inside your project folder, run: | ||
```bash | ||
$ npm install lit-element | ||
``` | ||
To install the web components polyfills needed for older browsers: | ||
```bash | ||
$ npm i -D @webcomponents/webcomponentsjs | ||
``` | ||
## Supported Browsers | ||
The last 2 versions of all modern browsers are supported, including | ||
Chrome, Safari, Opera, Firefox, Edge. In addition, Internet Explorer 11 is also supported. | ||
Edge and Internet Explorer 11 require the web components polyfills. | ||
## Contributing | ||
Please see [CONTRIBUTING.md](./CONTRIBUTING.md). |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
203860
25
2761
0
85
20
2
1
+ Addedlit-html@1.0.0-dev.c8753bc(transitive)
- Removedlit-html@0.6.0(transitive)
Updatedlit-html@1.0.0-dev.c8753bc