Skip to content

Commit

Permalink
Merge pull request #401 from Polymer/static-styles
Browse files Browse the repository at this point in the history
Adds `static get styles()`
  • Loading branch information
Steve Orvell authored Jan 10, 2019
2 parents 231eb95 + 27eb2ad commit 22eca24
Show file tree
Hide file tree
Showing 9 changed files with 814 additions and 810 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
## Unreleased

### Added
* Added `static get styles()` to allow defining element styling separate from `render` method.
This takes advantage of [`adoptedStyleSheets`](https://wicg.github.io/construct-stylesheets/#using-constructed-stylesheets) when possible ([#391](https://github.com/Polymer/lit-element/issues/391)).
* Added the `performUpdate` method to allow control of update timing ([#290](https://github.com/Polymer/lit-element/issues/290)).
* Updates deferred until first connection ([#258](https://github.com/Polymer/lit-element/issues/258)).
### Changed
* [Breaking] The `createRenderRoot` method has moved from `UpdatingElement` to `LitElement`. Therefore, `UpdatingElement` no longer creates a `shadowRoot` by default ([#391](https://github.com/Polymer/lit-element/issues/391)).
* [Breaking] Changes property options to add `converter`. This option works the same as the previous `type` option except that the `converter` methods now also get `type` as the second argument. This effectively changes `type` to be a hint for the `converter`. A default `converter` is used if none is provided and it now supports `Boolean`, `String`, `Number`, `Object`, and `Array` ([#264](https://github.com/Polymer/lit-element/issues/264)).
* [Breaking] Numbers and strings now become null if their reflected attribute is removed (https://github.com/Polymer/lit-element/issues/264)).
* [Breaking] Previously, when an attribute changed as a result of a reflecting property changing, the property was prevented from mutating again as can happen when a custom
Expand Down
20 changes: 9 additions & 11 deletions demo/lit-element.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@
<ts-element message="Yo" more-info="person"></ts-element>

<script type="module">
import { LitElement, html } from '../lit-element.js';
import { LitElement, html, css } from '../lit-element.js';

class Inner extends LitElement {

static get styles() {
return [css`:host { color: green; }`];
}
render() {
return html`Hello world`;
}
Expand All @@ -34,23 +38,13 @@
static get properties() {
return {
nug: {},
zot: {},
foo: {},
bar: {},
whales: {type: Number},
fooBar: {converter: {fromAttribute: parseInt, toAttribute: (value) => value + '-attr'}, reflect: true}
}
}

// a custom getter/setter can be created to customize property processing
get zot() { return this.getAttribute('zot'); }

set zot(value) {
this.setAttribute('zot', value);
this.invalidate();
}


constructor() {
super();
this.foo = 'foo';
Expand All @@ -64,6 +58,10 @@
});
}

static get styles() {
return [css`h4 { color: orange;} `];
}

render() {
const {foo, bar, whales, fooBar, nug} = this;
return html`
Expand Down
1,213 changes: 454 additions & 759 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,24 @@
"devDependencies": {
"@types/chai": "^4.0.1",
"@types/mocha": "^5.2.4",
"@webcomponents/shadycss": "^1.5.2",
"@webcomponents/webcomponentsjs": "^2.2.1",
"@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.7.0",
"tslint": "^5.12.0",
"typedoc": "^0.8.0",
"typescript": "^3.0.3",
"typescript": "^3.2.2",
"uglify-es": "^3.3.9",
"wct-mocha": "^1.0.0",
"web-component-tester": "^6.9.0"
"web-component-tester": "^6.9.2"
},
"typings": "lit-element.d.ts",
"dependencies": {
"lit-html": "^1.0.0-rc.1"
"lit-html": "^1.0.0-rc.2"
},
"publishConfig": {
"access": "public"
Expand Down
17 changes: 17 additions & 0 deletions src/env.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
interface ShadyCSS {
styleElement(host: Element, overrideProps?: {[key: string]: string}): void;
getComputedStyleValue(element: Element, property: string): string;
ScopingShim: {
prepareAdoptedCssText(cssText: string[], name: string): void;
}
nativeShadow: boolean;
}

interface ShadyDOM {
Expand All @@ -10,4 +14,17 @@ interface ShadyDOM {
interface Window {
ShadyCSS?: ShadyCSS;
ShadyDOM?: ShadyDOM;
ShadowRoot: typeof ShadowRoot;
}

// Augment existing types with styling API
interface ShadowRoot {
adoptedStyleSheets: CSSStyleSheet[];
}

declare var ShadowRoot: {prototype: ShadowRoot; new () : ShadowRoot;}

interface CSSStyleSheet {
replaceSync(cssText: string): void;
replace(cssText: string): Promise<unknown>;
}
56 changes: 56 additions & 0 deletions src/lib/css-tag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
@license
Copyright (c) 2019 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
*/

export const supportsAdoptingStyleSheets =
('adoptedStyleSheets' in Document.prototype);

export class CSSResult {

_styleSheet?: CSSStyleSheet|null;

readonly cssText: string;

constructor(cssText: string) { this.cssText = cssText; }

// Note, this is a getter so that it's lazy. In practice, this means
// stylesheets are not created until the first element instance is made.
get styleSheet(): CSSStyleSheet|null {
if (this._styleSheet === undefined) {
// Note, if `adoptedStyleSheets` is supported then we assume CSSStyleSheet
// is constructable.
if (supportsAdoptingStyleSheets) {
this._styleSheet = new CSSStyleSheet();
this._styleSheet.replaceSync(this.cssText);
} else {
this._styleSheet = null;
}
}
return this._styleSheet;
}
}

const textFromCSSResult = (value: CSSResult) => {
if (value instanceof CSSResult) {
return value.cssText;
} else {
throw new Error(
`Value passed to 'css' function must be a 'css' function result: ${
value}.`);
}
};

export const css =
(strings: TemplateStringsArray, ...values: CSSResult[]): CSSResult => {
const cssText = values.reduce(
(acc, v, idx) => acc + textFromCSSResult(v) + strings[idx + 1],
strings[0]);
return new CSSResult(cssText);
};
40 changes: 6 additions & 34 deletions src/lib/updating-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -440,26 +440,16 @@ export abstract class UpdatingElement extends HTMLElement {
private _reflectingProperties: Map<PropertyKey, PropertyDeclaration>|
undefined = undefined;

/**
* Node or ShadowRoot into which element DOM should be rendered. Defaults
* to an open shadowRoot.
*/
protected renderRoot?: Element|DocumentFragment;

constructor() {
super();
this.initialize();
}

/**
* Performs element initialization. By default this calls `createRenderRoot`
* to create the element `renderRoot` node and captures any pre-set values for
* Performs element initialization. By default captures any pre-set values for
* registered properties.
*/
protected initialize() {
this.renderRoot = this.createRenderRoot();
this._saveInstanceProperties();
}
protected initialize() { this._saveInstanceProperties(); }

/**
* Fixes any properties set on the instance before upgrade time.
Expand Down Expand Up @@ -497,20 +487,6 @@ export abstract class UpdatingElement extends HTMLElement {
this._instanceProperties = undefined;
}

/**
* 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.
*/
protected createRenderRoot(): Element|ShadowRoot {
return this.attachShadow({mode : 'open'});
}

/**
* Uses ShadyCSS to keep element DOM updated.
*/
connectedCallback() {
this._updateState = this._updateState | STATE_HAS_CONNECTED;
// Ensure connection triggers an update. Updates cannot complete before
Expand All @@ -523,12 +499,6 @@ export abstract class UpdatingElement extends HTMLElement {
} else {
this.requestUpdate();
}
// Note, first update/render handles styleElement so we only call this if
// connected after first update.
if ((this._updateState & STATE_HAS_UPDATED) &&
window.ShadyCSS !== undefined) {
window.ShadyCSS.styleElement(this);
}
}

/**
Expand Down Expand Up @@ -675,6 +645,8 @@ export abstract class UpdatingElement extends HTMLElement {
return (this._updateState & STATE_UPDATE_REQUESTED);
}

protected get hasUpdated() { return (this._updateState & STATE_HAS_UPDATED); }

/**
* Performs an element update.
*
Expand Down Expand Up @@ -739,8 +711,8 @@ export abstract class UpdatingElement extends HTMLElement {

/**
* Updates the element. This method reflects property values to attributes.
* It can be overridden to render and keep updated DOM in the element's
* `renderRoot`. Setting properties inside this method will *not* trigger
* It can be overridden to render and keep updated element DOM.
* Setting properties inside this method will *not* trigger
* another update.
*
* * @param _changedProperties Map of changed properties with old values
Expand Down
Loading

0 comments on commit 22eca24

Please sign in to comment.