element-vir 22.2.1 → 23.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -36
- package/dist/declarative-element/custom-tag-name.d.ts +6 -0
- package/dist/declarative-element/declarative-element-init.d.ts +20 -14
- package/dist/declarative-element/declarative-element.d.ts +70 -24
- package/dist/declarative-element/declarative-element.js +34 -1
- package/dist/declarative-element/define-element-no-inputs.d.ts +31 -6
- package/dist/declarative-element/define-element-no-inputs.js +154 -257
- package/dist/declarative-element/define-element.d.ts +35 -7
- package/dist/declarative-element/define-element.js +26 -4
- package/dist/declarative-element/definition-options.d.ts +10 -0
- package/dist/declarative-element/definition-options.js +5 -0
- package/dist/declarative-element/directives/assign.directive.d.ts +8 -11
- package/dist/declarative-element/directives/assign.directive.js +6 -13
- package/dist/declarative-element/directives/async-prop.d.ts +19 -4
- package/dist/declarative-element/directives/async-prop.js +15 -4
- package/dist/declarative-element/directives/create-attribute-directive.d.ts +19 -4
- package/dist/declarative-element/directives/create-attribute-directive.js +18 -8
- package/dist/declarative-element/directives/directive-helpers.d.ts +19 -4
- package/dist/declarative-element/directives/directive-helpers.js +14 -2
- package/dist/declarative-element/directives/is-resolved.directive.d.ts +107 -1
- package/dist/declarative-element/directives/is-resolved.directive.js +107 -1
- package/dist/declarative-element/directives/listen.directive.d.ts +84 -10
- package/dist/declarative-element/directives/listen.directive.js +5 -15
- package/dist/declarative-element/directives/on-dom-created.directive.d.ts +37 -4
- package/dist/declarative-element/directives/on-dom-created.directive.js +32 -12
- package/dist/declarative-element/directives/on-dom-rendered.directive.d.ts +33 -3
- package/dist/declarative-element/directives/on-dom-rendered.directive.js +29 -6
- package/dist/declarative-element/directives/on-resize.directive.d.ts +37 -4
- package/dist/declarative-element/directives/on-resize.directive.js +37 -24
- package/dist/declarative-element/directives/render-async.directive.d.ts +44 -4
- package/dist/declarative-element/directives/render-async.directive.js +13 -3
- package/dist/declarative-element/directives/render-if.directive.d.ts +31 -0
- package/dist/declarative-element/directives/render-if.directive.js +32 -1
- package/dist/declarative-element/directives/test-id.directive.d.ts +48 -4
- package/dist/declarative-element/directives/test-id.directive.js +47 -2
- package/dist/declarative-element/has-declarative-element-parent.js +1 -1
- package/dist/declarative-element/is-declarative-element-definition.d.ts +15 -1
- package/dist/declarative-element/is-declarative-element-definition.js +21 -18
- package/dist/declarative-element/is-declarative-element.d.ts +5 -1
- package/dist/declarative-element/is-declarative-element.js +7 -3
- package/dist/declarative-element/properties/assign-inputs.js +1 -1
- package/dist/declarative-element/properties/css-properties.d.ts +11 -1
- package/dist/declarative-element/properties/css-properties.js +5 -0
- package/dist/declarative-element/properties/css-vars.d.ts +14 -4
- package/dist/declarative-element/properties/element-events.d.ts +61 -7
- package/dist/declarative-element/properties/element-events.js +40 -5
- package/dist/declarative-element/properties/element-properties.d.ts +15 -6
- package/dist/declarative-element/properties/element-properties.js +1 -21
- package/dist/declarative-element/properties/element-vir-state-setup.d.ts +43 -3
- package/dist/declarative-element/properties/element-vir-state-setup.js +17 -3
- package/dist/declarative-element/properties/host-classes.d.ts +25 -12
- package/dist/declarative-element/properties/host-classes.js +5 -0
- package/dist/declarative-element/properties/per-instance.d.ts +23 -2
- package/dist/declarative-element/properties/per-instance.js +24 -3
- package/dist/declarative-element/properties/property-proxy.d.ts +19 -4
- package/dist/declarative-element/properties/property-proxy.js +15 -4
- package/dist/declarative-element/properties/styles.d.ts +33 -8
- package/dist/declarative-element/properties/styles.js +12 -2
- package/dist/declarative-element/properties/tag-name.d.ts +5 -0
- package/dist/declarative-element/render-callback.d.ts +38 -11
- package/dist/declarative-element/render-callback.js +6 -0
- package/dist/declarative-element/slot-names.d.ts +10 -2
- package/dist/declarative-element/slot-names.js +5 -1
- package/dist/declarative-element/wrap-define-element.d.ts +38 -11
- package/dist/declarative-element/wrap-define-element.js +17 -2
- package/dist/index.d.ts +40 -40
- package/dist/index.js +40 -39
- package/dist/lit-exports/all-lit-exports.d.ts +2 -2
- package/dist/lit-exports/all-lit-exports.js +2 -2
- package/dist/lit-exports/lit-repeat-fix.d.ts +60 -4
- package/dist/lit-exports/lit-repeat-fix.js +35 -1
- package/dist/readme-examples/my-app.element.d.ts +1 -0
- package/dist/readme-examples/my-app.element.js +11 -0
- package/dist/readme-examples/my-custom-action.event.d.ts +1 -0
- package/dist/readme-examples/my-custom-action.event.js +2 -0
- package/dist/readme-examples/my-custom-define.d.ts +4 -0
- package/dist/readme-examples/my-custom-define.js +19 -0
- package/dist/readme-examples/my-simple.element.d.ts +1 -0
- package/dist/readme-examples/my-simple.element.js +9 -0
- package/dist/readme-examples/my-with-assignment.element.d.ts +1 -0
- package/dist/readme-examples/my-with-assignment.element.js +14 -0
- package/dist/readme-examples/my-with-async-prop.element.d.ts +9 -0
- package/dist/readme-examples/my-with-async-prop.element.js +46 -0
- package/dist/readme-examples/my-with-cleanup-callback.element.d.ts +3 -0
- package/dist/readme-examples/my-with-cleanup-callback.element.js +23 -0
- package/dist/readme-examples/my-with-css-vars.element.d.ts +1 -0
- package/dist/readme-examples/my-with-css-vars.element.js +24 -0
- package/dist/readme-examples/my-with-custom-events.element.d.ts +1 -0
- package/dist/readme-examples/my-with-custom-events.element.js +21 -0
- package/dist/readme-examples/my-with-event-listening.element.d.ts +3 -0
- package/dist/readme-examples/my-with-event-listening.element.js +22 -0
- package/dist/readme-examples/my-with-events.element.d.ts +4 -0
- package/dist/readme-examples/my-with-events.element.js +19 -0
- package/dist/readme-examples/my-with-host-class-definition.element.d.ts +3 -0
- package/dist/readme-examples/my-with-host-class-definition.element.js +39 -0
- package/dist/readme-examples/my-with-host-class-usage.element.d.ts +1 -0
- package/dist/readme-examples/my-with-host-class-usage.element.js +12 -0
- package/dist/readme-examples/my-with-inputs.element.d.ts +4 -0
- package/dist/readme-examples/my-with-inputs.element.js +9 -0
- package/dist/readme-examples/my-with-on-dom-created.element.d.ts +1 -0
- package/dist/readme-examples/my-with-on-dom-created.element.js +16 -0
- package/dist/readme-examples/my-with-on-resize.element.d.ts +1 -0
- package/dist/readme-examples/my-with-on-resize.element.js +17 -0
- package/dist/readme-examples/my-with-render-if.element.d.ts +3 -0
- package/dist/readme-examples/my-with-render-if.element.js +11 -0
- package/dist/readme-examples/my-with-styles-and-interpolated-selector.element.d.ts +1 -0
- package/dist/readme-examples/my-with-styles-and-interpolated-selector.element.js +15 -0
- package/dist/readme-examples/my-with-styles.element.d.ts +1 -0
- package/dist/readme-examples/my-with-styles.element.js +21 -0
- package/dist/readme-examples/my-with-update-state.element.d.ts +8 -0
- package/dist/readme-examples/my-with-update-state.element.js +23 -0
- package/dist/readme-examples/require-declarative-element.d.ts +1 -0
- package/dist/readme-examples/require-declarative-element.js +2 -0
- package/dist/require-declarative-element.d.ts +12 -0
- package/dist/require-declarative-element.js +12 -0
- package/dist/template-transforms/minimal-element-definition.d.ts +30 -2
- package/dist/template-transforms/minimal-element-definition.js +14 -3
- package/dist/template-transforms/nested-mapped-templates.d.ts +1 -1
- package/dist/template-transforms/nested-mapped-templates.js +4 -3
- package/dist/template-transforms/template-transform-type.d.ts +1 -1
- package/dist/template-transforms/transform-template.d.ts +1 -1
- package/dist/template-transforms/transform-template.js +17 -21
- package/dist/template-transforms/vir-css/css-transform.d.ts +3 -3
- package/dist/template-transforms/vir-css/css-transform.js +3 -2
- package/dist/template-transforms/vir-css/vir-css.d.ts +11 -2
- package/dist/template-transforms/vir-css/vir-css.js +11 -2
- package/dist/template-transforms/vir-html/html-interpolation.d.ts +9 -5
- package/dist/template-transforms/vir-html/html-transform.d.ts +3 -3
- package/dist/template-transforms/vir-html/html-transform.js +14 -12
- package/dist/template-transforms/vir-html/vir-html.d.ts +4 -2
- package/dist/template-transforms/vir-html/vir-html.js +4 -2
- package/dist/typed-event/typed-event.d.ts +42 -6
- package/dist/typed-event/typed-event.js +31 -28
- package/dist/util/lit-template.d.ts +6 -1
- package/dist/util/lit-template.js +10 -7
- package/dist/util/type.d.ts +5 -0
- package/package.json +35 -34
|
@@ -1,34 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
4
|
-
};
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-empty-object-type */
|
|
2
|
+
import { check } from '@augment-vir/assert';
|
|
5
3
|
import { ensureErrorAndPrependMessage, extractErrorMessage, getObjectTypedKeys, kebabCaseToCamelCase, } from '@augment-vir/common';
|
|
6
4
|
import { defineCssVars } from 'lit-css-vars';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
|
|
5
|
+
import { css } from '../template-transforms/vir-css/vir-css.js';
|
|
6
|
+
import { DeclarativeElement, } from './declarative-element.js';
|
|
7
|
+
import { defaultDeclarativeElementDefinitionOptions, } from './definition-options.js';
|
|
8
|
+
import { hasDeclarativeElementParent } from './has-declarative-element-parent.js';
|
|
9
|
+
import { assignInputs } from './properties/assign-inputs.js';
|
|
10
|
+
import { assertValidCssProperties } from './properties/css-properties.js';
|
|
11
|
+
import { createEventDescriptorMap, } from './properties/element-events.js';
|
|
12
|
+
import { createHostClassNamesMap } from './properties/host-classes.js';
|
|
13
|
+
import { bindReactiveProperty, createElementPropertyProxy } from './properties/property-proxy.js';
|
|
14
|
+
import { applyHostClasses, createStylesCallbackInput } from './properties/styles.js';
|
|
15
|
+
import { createRenderParams } from './render-callback.js';
|
|
16
|
+
import { createSlotNamesMap } from './slot-names.js';
|
|
17
|
+
/**
|
|
18
|
+
* Defines an element without any inputs.
|
|
19
|
+
*
|
|
20
|
+
* @category Element Definition
|
|
21
|
+
* @example
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* import {defineElementNoInputs, html} from 'element-vir';
|
|
25
|
+
*
|
|
26
|
+
* const MyElement = defineElementNoInputs({
|
|
27
|
+
* tagName: 'my-element',
|
|
28
|
+
* render() {
|
|
29
|
+
* return html`
|
|
30
|
+
* <p>hi</p>
|
|
31
|
+
* `;
|
|
32
|
+
* },
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
20
36
|
export function defineElementNoInputs(initInput) {
|
|
21
|
-
var _a;
|
|
22
37
|
/** This as cast is safe only because of the following run-time type check. */
|
|
23
38
|
const init = initInput;
|
|
24
|
-
if (!
|
|
25
|
-
throw new
|
|
39
|
+
if (!check.isObject(init)) {
|
|
40
|
+
throw new TypeError('Cannot define element with non-object init: ${init}');
|
|
26
41
|
}
|
|
27
|
-
if (!
|
|
28
|
-
throw new
|
|
42
|
+
if (!check.isString(init.tagName)) {
|
|
43
|
+
throw new TypeError('Missing valid tagName (expected a string).');
|
|
29
44
|
}
|
|
30
|
-
|
|
31
|
-
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
46
|
+
if (!init.render || typeof init.render === 'string') {
|
|
47
|
+
throw new Error(`Failed to define element '${init.tagName}': render is not a function`);
|
|
32
48
|
}
|
|
33
49
|
const elementOptions = {
|
|
34
50
|
...defaultDeclarativeElementDefinitionOptions,
|
|
@@ -51,9 +67,9 @@ export function defineElementNoInputs(initInput) {
|
|
|
51
67
|
const cssVars = (init.cssVars ? defineCssVars(init.cssVars) : {});
|
|
52
68
|
const slotNamesMap = createSlotNamesMap(init.slotNames);
|
|
53
69
|
const calculatedStyles = typeof init.styles === 'function'
|
|
54
|
-
? init.styles(
|
|
70
|
+
? init.styles(createStylesCallbackInput({ hostClassNames, cssVars }))
|
|
55
71
|
: init.styles || css ``;
|
|
56
|
-
const typedRenderCallback = init.
|
|
72
|
+
const typedRenderCallback = init.render;
|
|
57
73
|
function typedAssignCallback(...[inputs]) {
|
|
58
74
|
const wrappedDefinition = {
|
|
59
75
|
_elementVirIsMinimalDefinitionWithInputs: true,
|
|
@@ -62,240 +78,127 @@ export function defineElementNoInputs(initInput) {
|
|
|
62
78
|
};
|
|
63
79
|
return wrappedDefinition;
|
|
64
80
|
}
|
|
65
|
-
const anonymousClass =
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
state: renderParams.state,
|
|
106
|
-
inputs: renderParams.inputs,
|
|
107
|
-
});
|
|
108
|
-
this._lastRenderedProps = {
|
|
109
|
-
inputs: { ...renderParams.inputs },
|
|
110
|
-
state: { ...renderParams.state },
|
|
111
|
-
};
|
|
112
|
-
return renderResult;
|
|
113
|
-
}
|
|
114
|
-
catch (caught) {
|
|
115
|
-
const error = ensureErrorAndPrependMessage(caught, `Failed to render ${init.tagName}`);
|
|
116
|
-
console.error(error);
|
|
117
|
-
this._lastRenderError = error;
|
|
118
|
-
return extractErrorMessage(error);
|
|
81
|
+
const anonymousClass = class extends DeclarativeElement {
|
|
82
|
+
static elementOptions = elementOptions;
|
|
83
|
+
static tagName = init.tagName;
|
|
84
|
+
static styles = calculatedStyles;
|
|
85
|
+
_lastRenderError = undefined;
|
|
86
|
+
_internalRenderCount = 0;
|
|
87
|
+
createRenderParams() {
|
|
88
|
+
return createRenderParams({ element: this, eventsMap, cssVars, slotNamesMap });
|
|
89
|
+
}
|
|
90
|
+
static assign = typedAssignCallback;
|
|
91
|
+
static events = eventsMap;
|
|
92
|
+
static render = typedRenderCallback;
|
|
93
|
+
static hostClasses = hostClassNames;
|
|
94
|
+
static cssVars = cssVars;
|
|
95
|
+
static init = init;
|
|
96
|
+
static slotNames = slotNamesMap;
|
|
97
|
+
static stateInitStatic = init.stateInitStatic;
|
|
98
|
+
get instanceType() {
|
|
99
|
+
throw new Error(`"instanceType" was called on ${init.tagName} as a value but it is only for types.`);
|
|
100
|
+
}
|
|
101
|
+
static get inputsType() {
|
|
102
|
+
throw new Error(`"inputsType" was called on ${init.tagName} as a value but it is only for types.`);
|
|
103
|
+
}
|
|
104
|
+
static get stateType() {
|
|
105
|
+
throw new Error(`"stateType" was called on ${init.tagName} as a value but it is only for types.`);
|
|
106
|
+
}
|
|
107
|
+
_initCalled = false;
|
|
108
|
+
_hasRendered = false;
|
|
109
|
+
_lastRenderedProps = undefined;
|
|
110
|
+
_haveInputsBeenSet = false;
|
|
111
|
+
render() {
|
|
112
|
+
this._internalRenderCount++;
|
|
113
|
+
try {
|
|
114
|
+
if (
|
|
115
|
+
// This ignores elements at the root of a page, as they can't receive inputs from
|
|
116
|
+
// other elements (cause they have no custom element ancestors).
|
|
117
|
+
hasDeclarativeElementParent(this) &&
|
|
118
|
+
!this._haveInputsBeenSet &&
|
|
119
|
+
!elementOptions.ignoreUnsetInputs) {
|
|
120
|
+
console.warn(this, `${init.tagName} got rendered before its input object was set. This was most likely caused by forgetting to use '.assign()' on its opening tag. If no inputs are intended, use '${defineElementNoInputs.name}' to define ${init.tagName}.`);
|
|
119
121
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (this._hasRendered && !this._initCalled && init.initCallback) {
|
|
122
|
+
this._hasRendered = true;
|
|
123
|
+
const renderParams = this.createRenderParams();
|
|
124
|
+
if (!this._initCalled && init.init) {
|
|
124
125
|
this._initCalled = true;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
throw new Error(`initCallback in '${init.tagName}' cannot be asynchronous`);
|
|
126
|
+
if (init.init(renderParams) instanceof Promise) {
|
|
127
|
+
throw new TypeError('init cannot be asynchronous');
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
130
|
+
const renderResult = typedRenderCallback(renderParams);
|
|
131
|
+
if (renderResult instanceof Promise) {
|
|
132
|
+
throw new TypeError('render cannot be asynchronous');
|
|
133
|
+
}
|
|
134
|
+
applyHostClasses({
|
|
135
|
+
host: renderParams.host,
|
|
136
|
+
hostClassesInit: init.hostClasses,
|
|
137
|
+
hostClassNames,
|
|
138
|
+
state: renderParams.state,
|
|
139
|
+
inputs: renderParams.inputs,
|
|
137
140
|
});
|
|
141
|
+
this._lastRenderedProps = {
|
|
142
|
+
inputs: { ...renderParams.inputs },
|
|
143
|
+
state: { ...renderParams.state },
|
|
144
|
+
};
|
|
145
|
+
return renderResult;
|
|
138
146
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
throw new Error(`cleanupCallback in '${init.tagName}' cannot be asynchronous`);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
this.destroy();
|
|
148
|
-
this._initCalled = false;
|
|
147
|
+
catch (caught) {
|
|
148
|
+
const error = ensureErrorAndPrependMessage(caught, `Failed to render ${init.tagName}`);
|
|
149
|
+
console.error(error);
|
|
150
|
+
this._lastRenderError = error;
|
|
151
|
+
return extractErrorMessage(error);
|
|
149
152
|
}
|
|
150
|
-
|
|
151
|
-
|
|
153
|
+
}
|
|
154
|
+
connectedCallback() {
|
|
155
|
+
super.connectedCallback();
|
|
156
|
+
if (this._hasRendered && !this._initCalled && init.init) {
|
|
157
|
+
this._initCalled = true;
|
|
158
|
+
const renderParams = this.createRenderParams();
|
|
159
|
+
if (init.init(renderParams) instanceof Promise) {
|
|
160
|
+
throw new TypeError(`init in '${init.tagName}' cannot be asynchronous`);
|
|
161
|
+
}
|
|
152
162
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
enumerable: true,
|
|
169
|
-
configurable: true,
|
|
170
|
-
writable: true,
|
|
171
|
-
value: false
|
|
172
|
-
});
|
|
173
|
-
Object.defineProperty(this, "_hasRendered", {
|
|
174
|
-
enumerable: true,
|
|
175
|
-
configurable: true,
|
|
176
|
-
writable: true,
|
|
177
|
-
value: false
|
|
178
|
-
});
|
|
179
|
-
Object.defineProperty(this, "_lastRenderedProps", {
|
|
180
|
-
enumerable: true,
|
|
181
|
-
configurable: true,
|
|
182
|
-
writable: true,
|
|
183
|
-
value: undefined
|
|
184
|
-
});
|
|
185
|
-
Object.defineProperty(this, "_haveInputsBeenSet", {
|
|
186
|
-
enumerable: true,
|
|
187
|
-
configurable: true,
|
|
188
|
-
writable: true,
|
|
189
|
-
value: false
|
|
190
|
-
});
|
|
191
|
-
// this is set below in Object.defineProperties
|
|
192
|
-
Object.defineProperty(this, "definition", {
|
|
193
|
-
enumerable: true,
|
|
194
|
-
configurable: true,
|
|
195
|
-
writable: true,
|
|
196
|
-
value: {}
|
|
197
|
-
});
|
|
198
|
-
Object.defineProperty(this, "observablePropertyListenerMap", {
|
|
199
|
-
enumerable: true,
|
|
200
|
-
configurable: true,
|
|
201
|
-
writable: true,
|
|
202
|
-
value: {}
|
|
203
|
-
});
|
|
204
|
-
Object.defineProperty(this, "instanceInputs", {
|
|
205
|
-
enumerable: true,
|
|
206
|
-
configurable: true,
|
|
207
|
-
writable: true,
|
|
208
|
-
value: createElementPropertyProxy(this, false)
|
|
209
|
-
});
|
|
210
|
-
Object.defineProperty(this, "instanceState", {
|
|
211
|
-
enumerable: true,
|
|
212
|
-
configurable: true,
|
|
213
|
-
writable: true,
|
|
214
|
-
value: createElementPropertyProxy(this, !elementOptions.allowPolymorphicState)
|
|
215
|
-
});
|
|
216
|
-
const stateInitStatic = init.stateInitStatic || {};
|
|
217
|
-
getObjectTypedKeys(stateInitStatic).forEach((stateKey) => {
|
|
218
|
-
bindReactiveProperty(this, stateKey);
|
|
219
|
-
this.instanceState[stateKey] = stateInitStatic[stateKey];
|
|
220
|
-
});
|
|
221
|
-
this.definition = anonymousClass;
|
|
163
|
+
}
|
|
164
|
+
destroy() {
|
|
165
|
+
Object.values(this.instanceState).forEach((stateValue) => {
|
|
166
|
+
if (check.hasKey(stateValue, 'destroy') && check.isFunction(stateValue.destroy)) {
|
|
167
|
+
stateValue.destroy();
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
disconnectedCallback() {
|
|
172
|
+
super.disconnectedCallback();
|
|
173
|
+
if (init.cleanup) {
|
|
174
|
+
const renderParams = this.createRenderParams();
|
|
175
|
+
if (init.cleanup(renderParams) instanceof Promise) {
|
|
176
|
+
throw new TypeError(`cleanup in '${init.tagName}' cannot be asynchronous`);
|
|
177
|
+
}
|
|
222
178
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
writable: true,
|
|
247
|
-
value: typedAssignCallback
|
|
248
|
-
}),
|
|
249
|
-
// this gets set below in Object.defineProperties
|
|
250
|
-
Object.defineProperty(_a, "isStrictInstance", {
|
|
251
|
-
enumerable: true,
|
|
252
|
-
configurable: true,
|
|
253
|
-
writable: true,
|
|
254
|
-
value: () => false
|
|
255
|
-
}),
|
|
256
|
-
Object.defineProperty(_a, "events", {
|
|
257
|
-
enumerable: true,
|
|
258
|
-
configurable: true,
|
|
259
|
-
writable: true,
|
|
260
|
-
value: eventsMap
|
|
261
|
-
}),
|
|
262
|
-
Object.defineProperty(_a, "renderCallback", {
|
|
263
|
-
enumerable: true,
|
|
264
|
-
configurable: true,
|
|
265
|
-
writable: true,
|
|
266
|
-
value: typedRenderCallback
|
|
267
|
-
}),
|
|
268
|
-
Object.defineProperty(_a, "hostClasses", {
|
|
269
|
-
enumerable: true,
|
|
270
|
-
configurable: true,
|
|
271
|
-
writable: true,
|
|
272
|
-
value: hostClassNames
|
|
273
|
-
}),
|
|
274
|
-
Object.defineProperty(_a, "cssVars", {
|
|
275
|
-
enumerable: true,
|
|
276
|
-
configurable: true,
|
|
277
|
-
writable: true,
|
|
278
|
-
value: cssVars
|
|
279
|
-
}),
|
|
280
|
-
Object.defineProperty(_a, "init", {
|
|
281
|
-
enumerable: true,
|
|
282
|
-
configurable: true,
|
|
283
|
-
writable: true,
|
|
284
|
-
value: init
|
|
285
|
-
}),
|
|
286
|
-
Object.defineProperty(_a, "slotNames", {
|
|
287
|
-
enumerable: true,
|
|
288
|
-
configurable: true,
|
|
289
|
-
writable: true,
|
|
290
|
-
value: slotNamesMap
|
|
291
|
-
}),
|
|
292
|
-
Object.defineProperty(_a, "stateInitStatic", {
|
|
293
|
-
enumerable: true,
|
|
294
|
-
configurable: true,
|
|
295
|
-
writable: true,
|
|
296
|
-
value: init.stateInitStatic
|
|
297
|
-
}),
|
|
298
|
-
_a);
|
|
179
|
+
this.destroy();
|
|
180
|
+
this._initCalled = false;
|
|
181
|
+
}
|
|
182
|
+
// this is set below in Object.defineProperties
|
|
183
|
+
definition = {};
|
|
184
|
+
assignInputs(inputs) {
|
|
185
|
+
assignInputs(this, inputs);
|
|
186
|
+
}
|
|
187
|
+
observablePropertyListenerMap = {};
|
|
188
|
+
instanceInputs = createElementPropertyProxy(this, false);
|
|
189
|
+
instanceState = createElementPropertyProxy(this, !elementOptions.allowPolymorphicState);
|
|
190
|
+
constructor() {
|
|
191
|
+
super();
|
|
192
|
+
const stateInitStatic =
|
|
193
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
194
|
+
init.stateInitStatic || {};
|
|
195
|
+
getObjectTypedKeys(stateInitStatic).forEach((stateKey) => {
|
|
196
|
+
bindReactiveProperty(this, stateKey);
|
|
197
|
+
this.instanceState[stateKey] = stateInitStatic[stateKey];
|
|
198
|
+
});
|
|
199
|
+
this.definition = anonymousClass;
|
|
200
|
+
}
|
|
201
|
+
};
|
|
299
202
|
Object.defineProperties(anonymousClass, {
|
|
300
203
|
name: {
|
|
301
204
|
value: kebabCaseToCamelCase(init.tagName, {
|
|
@@ -303,12 +206,6 @@ export function defineElementNoInputs(initInput) {
|
|
|
303
206
|
}),
|
|
304
207
|
writable: true,
|
|
305
208
|
},
|
|
306
|
-
isStrictInstance: {
|
|
307
|
-
value: (element) => {
|
|
308
|
-
return element instanceof anonymousClass;
|
|
309
|
-
},
|
|
310
|
-
writable: false,
|
|
311
|
-
},
|
|
312
209
|
});
|
|
313
210
|
if (window.customElements.get(init.tagName)) {
|
|
314
211
|
console.warn(`Tried to define custom element '${init.tagName}' but it is already defined.`);
|
|
@@ -1,8 +1,36 @@
|
|
|
1
|
-
import { CustomElementTagName } from './custom-tag-name';
|
|
2
|
-
import { DeclarativeElementDefinition } from './declarative-element';
|
|
3
|
-
import { VerifiedElementNoInputsInit } from './define-element-no-inputs';
|
|
4
|
-
import { BaseCssPropertyName } from './properties/css-properties';
|
|
5
|
-
import { EventsInitMap } from './properties/element-events';
|
|
6
|
-
import { PropertyInitMapBase } from './properties/element-properties';
|
|
1
|
+
import { CustomElementTagName } from './custom-tag-name.js';
|
|
2
|
+
import { DeclarativeElementDefinition } from './declarative-element.js';
|
|
3
|
+
import { VerifiedElementNoInputsInit } from './define-element-no-inputs.js';
|
|
4
|
+
import { BaseCssPropertyName } from './properties/css-properties.js';
|
|
5
|
+
import { EventsInitMap } from './properties/element-events.js';
|
|
6
|
+
import { PropertyInitMapBase } from './properties/element-properties.js';
|
|
7
|
+
/**
|
|
8
|
+
* Verifies that the given {@link DeclarativeElementInit} for an element definition with inputs does
|
|
9
|
+
* not have any state or input properties that clash with built-in HTML element properties, or state
|
|
10
|
+
* / input properties that clash with each other.
|
|
11
|
+
*
|
|
12
|
+
* @category Internal
|
|
13
|
+
*/
|
|
7
14
|
export type VerifiedElementInit<TagName extends CustomElementTagName, Inputs extends PropertyInitMapBase, StateInit extends PropertyInitMapBase, EventsInit extends EventsInitMap, HostClassKeys extends BaseCssPropertyName<TagName>, CssVarKeys extends BaseCssPropertyName<TagName>, SlotNames extends ReadonlyArray<string>> = Extract<keyof StateInit, keyof Inputs> extends never ? Extract<keyof Inputs, keyof HTMLElement> extends never ? VerifiedElementNoInputsInit<TagName, Inputs, StateInit, EventsInit, HostClassKeys, CssVarKeys, SlotNames> : 'ERROR: Cannot define an element input property that clashes with native HTMLElement properties.' : "ERROR: Cannot define an element state property that clashes with the element's input properties.";
|
|
8
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Defines an element with inputs. If the element actually has no inputs, use
|
|
17
|
+
* {@link defineElementNoInputs} instead. Note that this function must be called twice, due to
|
|
18
|
+
* TypeScript type inference limitations.
|
|
19
|
+
*
|
|
20
|
+
* @category Element Definition
|
|
21
|
+
* @example
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* import {defineElement, html} from 'element-vir';
|
|
25
|
+
*
|
|
26
|
+
* const MyElement = defineElement<{username: string}>()({
|
|
27
|
+
* tagName: 'my-element',
|
|
28
|
+
* render({inputs}) {
|
|
29
|
+
* return html`
|
|
30
|
+
* <p>hi: ${inputs.username}</p>
|
|
31
|
+
* `;
|
|
32
|
+
* },
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function defineElement<Inputs extends PropertyInitMapBase = {}>(): <const TagName extends CustomElementTagName, StateInit extends PropertyInitMapBase = {}, EventsInit extends EventsInitMap = {}, const HostClassKeys extends BaseCssPropertyName<TagName> = `${TagName}-`, const CssVarKeys extends BaseCssPropertyName<TagName> = `${TagName}-`, const SlotNames extends ReadonlyArray<string> = readonly []>(initInput: VerifiedElementInit<TagName, Inputs, StateInit, EventsInit, HostClassKeys, CssVarKeys, SlotNames>) => DeclarativeElementDefinition<TagName, Inputs, StateInit, EventsInit, HostClassKeys, CssVarKeys, SlotNames>;
|
|
@@ -1,10 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-empty-object-type */
|
|
2
|
+
import { check } from '@augment-vir/assert';
|
|
3
|
+
import { defineElementNoInputs } from './define-element-no-inputs.js';
|
|
4
|
+
/**
|
|
5
|
+
* Defines an element with inputs. If the element actually has no inputs, use
|
|
6
|
+
* {@link defineElementNoInputs} instead. Note that this function must be called twice, due to
|
|
7
|
+
* TypeScript type inference limitations.
|
|
8
|
+
*
|
|
9
|
+
* @category Element Definition
|
|
10
|
+
* @example
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* import {defineElement, html} from 'element-vir';
|
|
14
|
+
*
|
|
15
|
+
* const MyElement = defineElement<{username: string}>()({
|
|
16
|
+
* tagName: 'my-element',
|
|
17
|
+
* render({inputs}) {
|
|
18
|
+
* return html`
|
|
19
|
+
* <p>hi: ${inputs.username}</p>
|
|
20
|
+
* `;
|
|
21
|
+
* },
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
3
25
|
export function defineElement() {
|
|
4
26
|
return (initInput) => {
|
|
5
27
|
const init = initInput;
|
|
6
|
-
if (!
|
|
7
|
-
throw new
|
|
28
|
+
if (!check.isObject(init)) {
|
|
29
|
+
throw new TypeError('Cannot define element with non-object init: ${init}');
|
|
8
30
|
}
|
|
9
31
|
return defineElementNoInputs({
|
|
10
32
|
...init,
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extra options for defining elements. These should be used very rarely.
|
|
3
|
+
*
|
|
4
|
+
* @category Internal
|
|
5
|
+
*/
|
|
1
6
|
export type DeclarativeElementDefinitionOptions = {
|
|
2
7
|
/** For internal use only. */
|
|
3
8
|
ignoreUnsetInputs: boolean;
|
|
@@ -7,4 +12,9 @@ export type DeclarativeElementDefinitionOptions = {
|
|
|
7
12
|
*/
|
|
8
13
|
allowPolymorphicState: boolean;
|
|
9
14
|
};
|
|
15
|
+
/**
|
|
16
|
+
* Default values for {@link DeclarativeElementDefinitionOptions}.
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
10
20
|
export declare const defaultDeclarativeElementDefinitionOptions: DeclarativeElementDefinitionOptions;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { EmptyObject } from 'type-fest';
|
|
2
|
+
import { DirectiveResult } from '../../lit-exports/all-lit-exports.js';
|
|
3
|
+
import { PropertyInitMapBase } from '../properties/element-properties.js';
|
|
3
4
|
export type ElementDefinitionWithInputsType<InputsType extends PropertyInitMapBase = PropertyInitMapBase> = {
|
|
4
5
|
inputsType: InputsType;
|
|
5
6
|
};
|
|
@@ -8,20 +9,16 @@ export type ElementDefinitionWithInputsType<InputsType extends PropertyInitMapBa
|
|
|
8
9
|
*
|
|
9
10
|
* @deprecated Instead of using this directive, assign inputs directly on the element's
|
|
10
11
|
* interpolation opening tag interpolation.
|
|
11
|
-
* @example
|
|
12
|
-
*
|
|
13
|
-
* should be
|
|
14
|
-
* html`<${MyElement.assign({value: 1})}>...`
|
|
12
|
+
* @example Html`<${MyElement} ${assign(MyElement, {value: 1})}>...` should be
|
|
13
|
+
* html`<${MyElement.assign({value: 1})}>...`
|
|
15
14
|
*/
|
|
16
|
-
export declare function assign<const SpecificDeclarativeElement extends ElementDefinitionWithInputsType>(declarativeElement: SpecificDeclarativeElement, inputsObject:
|
|
15
|
+
export declare function assign<const SpecificDeclarativeElement extends ElementDefinitionWithInputsType>(declarativeElement: SpecificDeclarativeElement, inputsObject: EmptyObject extends Required<SpecificDeclarativeElement['inputsType']> ? never : SpecificDeclarativeElement['inputsType']): DirectiveResult;
|
|
17
16
|
/**
|
|
18
17
|
* Assign an object matching an element's inputs to its inputs.
|
|
19
18
|
*
|
|
20
19
|
* @deprecated Instead of using this directive, assign inputs directly on the element's
|
|
21
20
|
* interpolation opening tag interpolation.
|
|
22
|
-
* @example
|
|
23
|
-
*
|
|
24
|
-
* should be
|
|
25
|
-
* html`<${MyElement.assign({value: 1})}>...`
|
|
21
|
+
* @example Html`<${MyElement} ${assign(MyElement, {value: 1})}>...` should be
|
|
22
|
+
* html`<${MyElement.assign({value: 1})}>...`
|
|
26
23
|
*/
|
|
27
24
|
export declare function assign<const SpecificDeclarativeElement extends ElementDefinitionWithInputsType, const SpecificInput extends SpecificDeclarativeElement['inputsType']>(inputsObject: SpecificInput extends typeof HTMLElement ? never : SpecificInput): DirectiveResult;
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import { directive, Directive, noChange, } from '../../lit-exports/all-lit-exports';
|
|
2
|
-
import { assignInputs } from '../properties/assign-inputs';
|
|
3
|
-
import { extractElement } from './directive-helpers';
|
|
1
|
+
import { directive, Directive, noChange, } from '../../lit-exports/all-lit-exports.js';
|
|
2
|
+
import { assignInputs } from '../properties/assign-inputs.js';
|
|
3
|
+
import { extractElement } from './directive-helpers.js';
|
|
4
4
|
/**
|
|
5
5
|
* Assign an object matching an element's inputs to its inputs.
|
|
6
6
|
*
|
|
7
7
|
* @deprecated Instead of using this directive, assign inputs directly on the element's
|
|
8
8
|
* interpolation opening tag interpolation.
|
|
9
|
-
* @example
|
|
10
|
-
*
|
|
11
|
-
* should be
|
|
12
|
-
* html`<${MyElement.assign({value: 1})}>...`
|
|
9
|
+
* @example Html`<${MyElement} ${assign(MyElement, {value: 1})}>...` should be
|
|
10
|
+
* html`<${MyElement.assign({value: 1})}>...`
|
|
13
11
|
*/
|
|
14
12
|
export function assign(declarativeElementOrInputs, inputsObject) {
|
|
15
13
|
/**
|
|
@@ -24,14 +22,9 @@ export function assign(declarativeElementOrInputs, inputsObject) {
|
|
|
24
22
|
}
|
|
25
23
|
}
|
|
26
24
|
const assignDirective = directive(class extends Directive {
|
|
25
|
+
element;
|
|
27
26
|
constructor(partInfo) {
|
|
28
27
|
super(partInfo);
|
|
29
|
-
Object.defineProperty(this, "element", {
|
|
30
|
-
enumerable: true,
|
|
31
|
-
configurable: true,
|
|
32
|
-
writable: true,
|
|
33
|
-
value: void 0
|
|
34
|
-
});
|
|
35
28
|
this.element = extractElement(partInfo, 'assign');
|
|
36
29
|
}
|
|
37
30
|
render(elementDefinition, inputsObject) {
|