UNPKG

8.35 kBJavaScriptView Raw
1/**
2 * @license
3 * Copyright 2017 Google LLC
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6/**
7 * The main LitElement module, which defines the {@linkcode LitElement} base
8 * class and related APIs.
9 *
10 * LitElement components can define a template and a set of observed
11 * properties. Changing an observed property triggers a re-render of the
12 * element.
13 *
14 * Import {@linkcode LitElement} and {@linkcode html} from this module to
15 * create a component:
16 *
17 * ```js
18 * import {LitElement, html} from 'lit-element';
19 *
20 * class MyElement extends LitElement {
21 *
22 * // Declare observed properties
23 * static get properties() {
24 * return {
25 * adjective: {}
26 * }
27 * }
28 *
29 * constructor() {
30 * this.adjective = 'awesome';
31 * }
32 *
33 * // Define the element's template
34 * render() {
35 * return html`<p>your ${adjective} template here</p>`;
36 * }
37 * }
38 *
39 * customElements.define('my-element', MyElement);
40 * ```
41 *
42 * `LitElement` extends {@linkcode ReactiveElement} and adds lit-html
43 * templating. The `ReactiveElement` class is provided for users that want to
44 * build their own custom element base classes that don't use lit-html.
45 *
46 * @packageDocumentation
47 */
48import { ReactiveElement } from '@lit/reactive-element';
49import { render, noChange } from 'lit-html';
50export * from '@lit/reactive-element';
51export * from 'lit-html';
52/*
53 * When using Closure Compiler, JSCompiler_renameProperty(property, object) is
54 * replaced at compile time by the munged name for object[property]. We cannot
55 * alias this function, so we have to use a small shim that has the same
56 * behavior when not compiling.
57 */
58/*@__INLINE__*/
59const JSCompiler_renameProperty = (prop, _obj) => prop;
60const DEV_MODE = true;
61let issueWarning;
62if (DEV_MODE) {
63 // Ensure warnings are issued only 1x, even if multiple versions of Lit
64 // are loaded.
65 const issuedWarnings = (globalThis.litIssuedWarnings ??= new Set());
66 // Issue a warning, if we haven't already.
67 issueWarning = (code, warning) => {
68 warning += ` See https://lit.dev/msg/${code} for more information.`;
69 if (!issuedWarnings.has(warning)) {
70 console.warn(warning);
71 issuedWarnings.add(warning);
72 }
73 };
74}
75/**
76 * Base element class that manages element properties and attributes, and
77 * renders a lit-html template.
78 *
79 * To define a component, subclass `LitElement` and implement a
80 * `render` method to provide the component's template. Define properties
81 * using the {@linkcode LitElement.properties properties} property or the
82 * {@linkcode property} decorator.
83 */
84export class LitElement extends ReactiveElement {
85 constructor() {
86 super(...arguments);
87 /**
88 * @category rendering
89 */
90 this.renderOptions = { host: this };
91 this.__childPart = undefined;
92 }
93 /**
94 * @category rendering
95 */
96 createRenderRoot() {
97 const renderRoot = super.createRenderRoot();
98 // When adoptedStyleSheets are shimmed, they are inserted into the
99 // shadowRoot by createRenderRoot. Adjust the renderBefore node so that
100 // any styles in Lit content render before adoptedStyleSheets. This is
101 // important so that adoptedStyleSheets have precedence over styles in
102 // the shadowRoot.
103 this.renderOptions.renderBefore ??= renderRoot.firstChild;
104 return renderRoot;
105 }
106 /**
107 * Updates the element. This method reflects property values to attributes
108 * and calls `render` to render DOM via lit-html. Setting properties inside
109 * this method will *not* trigger another update.
110 * @param changedProperties Map of changed properties with old values
111 * @category updates
112 */
113 update(changedProperties) {
114 // Setting properties in `render` should not trigger an update. Since
115 // updates are allowed after super.update, it's important to call `render`
116 // before that.
117 const value = this.render();
118 if (!this.hasUpdated) {
119 this.renderOptions.isConnected = this.isConnected;
120 }
121 super.update(changedProperties);
122 this.__childPart = render(value, this.renderRoot, this.renderOptions);
123 }
124 /**
125 * Invoked when the component is added to the document's DOM.
126 *
127 * In `connectedCallback()` you should setup tasks that should only occur when
128 * the element is connected to the document. The most common of these is
129 * adding event listeners to nodes external to the element, like a keydown
130 * event handler added to the window.
131 *
132 * ```ts
133 * connectedCallback() {
134 * super.connectedCallback();
135 * addEventListener('keydown', this._handleKeydown);
136 * }
137 * ```
138 *
139 * Typically, anything done in `connectedCallback()` should be undone when the
140 * element is disconnected, in `disconnectedCallback()`.
141 *
142 * @category lifecycle
143 */
144 connectedCallback() {
145 super.connectedCallback();
146 this.__childPart?.setConnected(true);
147 }
148 /**
149 * Invoked when the component is removed from the document's DOM.
150 *
151 * This callback is the main signal to the element that it may no longer be
152 * used. `disconnectedCallback()` should ensure that nothing is holding a
153 * reference to the element (such as event listeners added to nodes external
154 * to the element), so that it is free to be garbage collected.
155 *
156 * ```ts
157 * disconnectedCallback() {
158 * super.disconnectedCallback();
159 * window.removeEventListener('keydown', this._handleKeydown);
160 * }
161 * ```
162 *
163 * An element may be re-connected after being disconnected.
164 *
165 * @category lifecycle
166 */
167 disconnectedCallback() {
168 super.disconnectedCallback();
169 this.__childPart?.setConnected(false);
170 }
171 /**
172 * Invoked on each update to perform rendering tasks. This method may return
173 * any value renderable by lit-html's `ChildPart` - typically a
174 * `TemplateResult`. Setting properties inside this method will *not* trigger
175 * the element to update.
176 * @category rendering
177 */
178 render() {
179 return noChange;
180 }
181}
182// This property needs to remain unminified.
183LitElement['_$litElement$'] = true;
184/**
185 * Ensure this class is marked as `finalized` as an optimization ensuring
186 * it will not needlessly try to `finalize`.
187 *
188 * Note this property name is a string to prevent breaking Closure JS Compiler
189 * optimizations. See @lit/reactive-element for more information.
190 */
191LitElement[JSCompiler_renameProperty('finalized', LitElement)] = true;
192// Install hydration if available
193globalThis.litElementHydrateSupport?.({ LitElement });
194// Apply polyfills if available
195const polyfillSupport = DEV_MODE
196 ? globalThis.litElementPolyfillSupportDevMode
197 : globalThis.litElementPolyfillSupport;
198polyfillSupport?.({ LitElement });
199/**
200 * END USERS SHOULD NOT RELY ON THIS OBJECT.
201 *
202 * Private exports for use by other Lit packages, not intended for use by
203 * external users.
204 *
205 * We currently do not make a mangled rollup build of the lit-ssr code. In order
206 * to keep a number of (otherwise private) top-level exports mangled in the
207 * client side code, we export a _$LE object containing those members (or
208 * helper methods for accessing private fields of those members), and then
209 * re-export them for use in lit-ssr. This keeps lit-ssr agnostic to whether the
210 * client-side code is being used in `dev` mode or `prod` mode.
211 *
212 * This has a unique name, to disambiguate it from private exports in
213 * lit-html, since this module re-exports all of lit-html.
214 *
215 * @private
216 */
217export const _$LE = {
218 _$attributeToProperty: (el, name, value) => {
219 // eslint-disable-next-line
220 el._$attributeToProperty(name, value);
221 },
222 // eslint-disable-next-line
223 _$changedProperties: (el) => el._$changedProperties,
224};
225// IMPORTANT: do not change the property name or the assignment expression.
226// This line will be used in regexes to search for LitElement usage.
227(globalThis.litElementVersions ??= []).push('4.1.1');
228if (DEV_MODE && globalThis.litElementVersions.length > 1) {
229 issueWarning('multiple-versions', `Multiple versions of Lit loaded. Loading multiple versions ` +
230 `is not recommended.`);
231}
232//# sourceMappingURL=lit-element.js.map
\No newline at end of file