element-vir 26.11.2 → 26.12.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/package.json +12 -12
- package/src/declarative-element/declarative-element-init.ts +115 -0
- package/src/declarative-element/declarative-element.ts +372 -0
- package/src/declarative-element/define-element.ts +515 -0
- package/{dist/declarative-element/definition-options.d.ts → src/declarative-element/definition-options.ts} +7 -2
- package/src/declarative-element/directives/assign.directive.ts +89 -0
- package/{dist/declarative-element/directives/async-prop.js → src/declarative-element/directives/async-prop.ts} +42 -8
- package/src/declarative-element/directives/attributes.directive.ts +63 -0
- package/src/declarative-element/directives/create-attribute-directive.ts +47 -0
- package/src/declarative-element/directives/directive-helpers.ts +67 -0
- package/{dist/declarative-element/directives/listen-to-activate.js → src/declarative-element/directives/listen-to-activate.ts} +8 -3
- package/src/declarative-element/directives/listen.directive.ts +206 -0
- package/src/declarative-element/directives/mutate.directive.ts +78 -0
- package/src/declarative-element/directives/on-dom-created.directive.ts +68 -0
- package/src/declarative-element/directives/on-dom-rendered.directive.ts +61 -0
- package/src/declarative-element/directives/on-intersect.directive.ts +139 -0
- package/src/declarative-element/directives/on-resize.directive.ts +142 -0
- package/src/declarative-element/directives/render-async.directive.ts +111 -0
- package/{dist/declarative-element/directives/render-if.directive.js → src/declarative-element/directives/render-if.directive.ts} +12 -3
- package/{dist/declarative-element/directives/test-id.directive.js → src/declarative-element/directives/test-id.directive.ts} +7 -2
- package/{dist/declarative-element/has-declarative-element-parent.js → src/declarative-element/has-declarative-element-parent.ts} +7 -4
- package/{dist/declarative-element/is-declarative-element-definition.js → src/declarative-element/is-declarative-element-definition.ts} +28 -11
- package/{dist/declarative-element/is-declarative-element.js → src/declarative-element/is-declarative-element.ts} +11 -5
- package/src/declarative-element/properties/assign-inputs.ts +30 -0
- package/src/declarative-element/properties/css-vars.ts +24 -0
- package/src/declarative-element/properties/element-events.ts +161 -0
- package/src/declarative-element/properties/host-classes.ts +63 -0
- package/{dist/declarative-element/properties/property-proxy.js → src/declarative-element/properties/property-proxy.ts} +58 -21
- package/src/declarative-element/properties/string-names.ts +83 -0
- package/src/declarative-element/properties/styles.ts +112 -0
- package/src/declarative-element/render-callback.ts +196 -0
- package/src/declarative-element/wrap-define-element.ts +127 -0
- package/{dist/index.d.ts → src/index.ts} +2 -0
- package/{dist/lit-exports/base-lit-exports.js → src/lit-exports/base-lit-exports.ts} +10 -1
- package/{dist/lit-exports/lit-repeat-fix.d.ts → src/lit-exports/lit-repeat-fix.ts} +45 -16
- package/{dist/readme-examples/my-app.element.js → src/readme-examples/my-app.element.ts} +5 -4
- package/src/readme-examples/my-custom-action.event.ts +3 -0
- package/{dist/readme-examples/my-custom-define.js → src/readme-examples/my-custom-define.ts} +9 -4
- package/{dist/readme-examples/my-simple.element.js → src/readme-examples/my-simple.element.ts} +4 -3
- package/src/readme-examples/my-with-assignment.element.ts +16 -0
- package/{dist/readme-examples/my-with-async-prop.element.js → src/readme-examples/my-with-async-prop.element.ts} +24 -16
- package/{dist/readme-examples/my-with-cleanup-callback.element.js → src/readme-examples/my-with-cleanup-callback.element.ts} +5 -4
- package/{dist/readme-examples/my-with-css-vars.element.js → src/readme-examples/my-with-css-vars.element.ts} +5 -4
- package/src/readme-examples/my-with-custom-events.element.ts +23 -0
- package/{dist/readme-examples/my-with-event-listening.element.js → src/readme-examples/my-with-event-listening.element.ts} +10 -9
- package/src/readme-examples/my-with-events.element.ts +23 -0
- package/{dist/readme-examples/my-with-host-class-definition.element.js → src/readme-examples/my-with-host-class-definition.element.ts} +7 -6
- package/{dist/readme-examples/my-with-host-class-usage.element.js → src/readme-examples/my-with-host-class-usage.element.ts} +5 -4
- package/src/readme-examples/my-with-inputs.element.ts +13 -0
- package/{dist/readme-examples/my-with-on-dom-created.element.js → src/readme-examples/my-with-on-dom-created.element.ts} +7 -6
- package/src/readme-examples/my-with-on-resize.element.ts +19 -0
- package/src/readme-examples/my-with-render-if.element.ts +15 -0
- package/{dist/readme-examples/my-with-styles-and-interpolated-selector.element.js → src/readme-examples/my-with-styles-and-interpolated-selector.element.ts} +6 -5
- package/{dist/readme-examples/my-with-styles.element.js → src/readme-examples/my-with-styles.element.ts} +5 -4
- package/{dist/readme-examples/my-with-update-state.element.js → src/readme-examples/my-with-update-state.element.ts} +8 -7
- package/src/readme-examples/require-declarative-element.ts +3 -0
- package/{dist/require-declarative-element.js → src/require-declarative-element.ts} +1 -0
- package/{dist/template-transforms/minimal-element-definition.d.ts → src/template-transforms/minimal-element-definition.ts} +19 -7
- package/src/template-transforms/nested-mapped-templates.ts +157 -0
- package/{dist/template-transforms/template-transform-type.d.ts → src/template-transforms/template-transform-type.ts} +3 -1
- package/{dist/template-transforms/transform-template.js → src/template-transforms/transform-template.ts} +70 -22
- package/src/template-transforms/vir-css/css-transform.ts +30 -0
- package/src/template-transforms/vir-css/vir-css.ts +30 -0
- package/src/template-transforms/vir-html/html-interpolation.ts +103 -0
- package/src/template-transforms/vir-html/html-transform.ts +149 -0
- package/{dist/template-transforms/vir-html/tag-name-keys.js → src/template-transforms/vir-html/tag-name-keys.ts} +1 -1
- package/{dist/template-transforms/vir-html/vir-html.js → src/template-transforms/vir-html/vir-html.ts} +13 -5
- package/src/typed-event/typed-event.ts +90 -0
- package/{dist/util/array.js → src/util/array.ts} +18 -5
- package/{dist/util/increment.d.ts → src/util/increment.ts} +24 -5
- package/{dist/util/lit-template.js → src/util/lit-template.ts} +30 -10
- package/src/util/map-async-value.ts +33 -0
- package/dist/declarative-element/custom-tag-name.js +0 -1
- package/dist/declarative-element/declarative-element-init.d.ts +0 -56
- package/dist/declarative-element/declarative-element-init.js +0 -1
- package/dist/declarative-element/declarative-element.d.ts +0 -114
- package/dist/declarative-element/declarative-element.js +0 -36
- package/dist/declarative-element/define-element.d.ts +0 -41
- package/dist/declarative-element/define-element.js +0 -248
- package/dist/declarative-element/definition-options.js +0 -9
- package/dist/declarative-element/directives/assign.directive.d.ts +0 -24
- package/dist/declarative-element/directives/assign.directive.js +0 -34
- package/dist/declarative-element/directives/async-prop.d.ts +0 -61
- package/dist/declarative-element/directives/attributes.directive.d.ts +0 -30
- package/dist/declarative-element/directives/attributes.directive.js +0 -35
- package/dist/declarative-element/directives/create-attribute-directive.d.ts +0 -28
- package/dist/declarative-element/directives/create-attribute-directive.js +0 -41
- package/dist/declarative-element/directives/directive-helpers.d.ts +0 -27
- package/dist/declarative-element/directives/directive-helpers.js +0 -37
- package/dist/declarative-element/directives/listen-to-activate.d.ts +0 -15
- package/dist/declarative-element/directives/listen.directive.d.ts +0 -92
- package/dist/declarative-element/directives/listen.directive.js +0 -48
- package/dist/declarative-element/directives/mutate.directive.d.ts +0 -38
- package/dist/declarative-element/directives/mutate.directive.js +0 -45
- package/dist/declarative-element/directives/on-dom-created.directive.d.ts +0 -44
- package/dist/declarative-element/directives/on-dom-created.directive.js +0 -51
- package/dist/declarative-element/directives/on-dom-rendered.directive.d.ts +0 -41
- package/dist/declarative-element/directives/on-dom-rendered.directive.js +0 -45
- package/dist/declarative-element/directives/on-intersect.directive.d.ts +0 -64
- package/dist/declarative-element/directives/on-intersect.directive.js +0 -89
- package/dist/declarative-element/directives/on-resize.directive.d.ts +0 -74
- package/dist/declarative-element/directives/on-resize.directive.js +0 -106
- package/dist/declarative-element/directives/render-async.directive.d.ts +0 -45
- package/dist/declarative-element/directives/render-async.directive.js +0 -33
- package/dist/declarative-element/directives/render-if.directive.d.ts +0 -32
- package/dist/declarative-element/directives/test-id.directive.d.ts +0 -52
- package/dist/declarative-element/has-declarative-element-parent.d.ts +0 -1
- package/dist/declarative-element/is-declarative-element-definition.d.ts +0 -17
- package/dist/declarative-element/is-declarative-element.d.ts +0 -15
- package/dist/declarative-element/properties/assign-inputs.d.ts +0 -1
- package/dist/declarative-element/properties/assign-inputs.js +0 -25
- package/dist/declarative-element/properties/css-vars.d.ts +0 -16
- package/dist/declarative-element/properties/css-vars.js +0 -1
- package/dist/declarative-element/properties/element-events.d.ts +0 -65
- package/dist/declarative-element/properties/element-events.js +0 -62
- package/dist/declarative-element/properties/element-properties.js +0 -1
- package/dist/declarative-element/properties/host-classes.d.ts +0 -36
- package/dist/declarative-element/properties/host-classes.js +0 -16
- package/dist/declarative-element/properties/property-proxy.d.ts +0 -22
- package/dist/declarative-element/properties/string-names.d.ts +0 -28
- package/dist/declarative-element/properties/string-names.js +0 -40
- package/dist/declarative-element/properties/styles.d.ts +0 -51
- package/dist/declarative-element/properties/styles.js +0 -41
- package/dist/declarative-element/properties/tag-name.js +0 -1
- package/dist/declarative-element/render-callback.d.ts +0 -56
- package/dist/declarative-element/render-callback.js +0 -27
- package/dist/declarative-element/wrap-define-element.d.ts +0 -36
- package/dist/declarative-element/wrap-define-element.js +0 -25
- package/dist/index.js +0 -42
- package/dist/lit-exports/all-lit-exports.js +0 -2
- package/dist/lit-exports/base-lit-exports.d.ts +0 -25
- package/dist/lit-exports/lit-repeat-fix.js +0 -37
- package/dist/readme-examples/my-app.element.d.ts +0 -1
- package/dist/readme-examples/my-custom-action.event.d.ts +0 -1
- package/dist/readme-examples/my-custom-action.event.js +0 -2
- package/dist/readme-examples/my-custom-define.d.ts +0 -4
- package/dist/readme-examples/my-simple.element.d.ts +0 -1
- package/dist/readme-examples/my-with-assignment.element.d.ts +0 -1
- package/dist/readme-examples/my-with-assignment.element.js +0 -15
- package/dist/readme-examples/my-with-async-prop.element.d.ts +0 -10
- package/dist/readme-examples/my-with-cleanup-callback.element.d.ts +0 -3
- package/dist/readme-examples/my-with-css-vars.element.d.ts +0 -1
- package/dist/readme-examples/my-with-custom-events.element.d.ts +0 -1
- package/dist/readme-examples/my-with-custom-events.element.js +0 -22
- package/dist/readme-examples/my-with-event-listening.element.d.ts +0 -3
- package/dist/readme-examples/my-with-events.element.d.ts +0 -4
- package/dist/readme-examples/my-with-events.element.js +0 -20
- package/dist/readme-examples/my-with-host-class-definition.element.d.ts +0 -3
- package/dist/readme-examples/my-with-host-class-usage.element.d.ts +0 -1
- package/dist/readme-examples/my-with-inputs.element.d.ts +0 -4
- package/dist/readme-examples/my-with-inputs.element.js +0 -9
- package/dist/readme-examples/my-with-on-dom-created.element.d.ts +0 -1
- package/dist/readme-examples/my-with-on-resize.element.d.ts +0 -1
- package/dist/readme-examples/my-with-on-resize.element.js +0 -18
- package/dist/readme-examples/my-with-render-if.element.d.ts +0 -3
- package/dist/readme-examples/my-with-render-if.element.js +0 -11
- package/dist/readme-examples/my-with-styles-and-interpolated-selector.element.d.ts +0 -1
- package/dist/readme-examples/my-with-styles.element.d.ts +0 -1
- package/dist/readme-examples/my-with-update-state.element.d.ts +0 -8
- package/dist/readme-examples/require-declarative-element.d.ts +0 -1
- package/dist/readme-examples/require-declarative-element.js +0 -2
- package/dist/require-declarative-element.d.ts +0 -14
- package/dist/template-transforms/minimal-element-definition.js +0 -19
- package/dist/template-transforms/nested-mapped-templates.d.ts +0 -6
- package/dist/template-transforms/nested-mapped-templates.js +0 -96
- package/dist/template-transforms/template-transform-type.js +0 -1
- package/dist/template-transforms/transform-template.d.ts +0 -14
- package/dist/template-transforms/vir-css/css-transform.d.ts +0 -4
- package/dist/template-transforms/vir-css/css-transform.js +0 -15
- package/dist/template-transforms/vir-css/vir-css.d.ts +0 -12
- package/dist/template-transforms/vir-css/vir-css.js +0 -21
- package/dist/template-transforms/vir-html/html-interpolation.d.ts +0 -42
- package/dist/template-transforms/vir-html/html-interpolation.js +0 -1
- package/dist/template-transforms/vir-html/html-transform.d.ts +0 -5
- package/dist/template-transforms/vir-html/html-transform.js +0 -96
- package/dist/template-transforms/vir-html/tag-name-keys.d.ts +0 -7
- package/dist/template-transforms/vir-html/vir-html.d.ts +0 -11
- package/dist/typed-event/typed-event.d.ts +0 -55
- package/dist/typed-event/typed-event.js +0 -50
- package/dist/util/array.d.ts +0 -5
- package/dist/util/increment.js +0 -1
- package/dist/util/lit-template.d.ts +0 -9
- package/dist/util/type.js +0 -1
- /package/{dist/declarative-element/custom-tag-name.d.ts → src/declarative-element/custom-tag-name.ts} +0 -0
- /package/{dist/declarative-element/properties/element-properties.d.ts → src/declarative-element/properties/element-properties.ts} +0 -0
- /package/{dist/declarative-element/properties/tag-name.d.ts → src/declarative-element/properties/tag-name.ts} +0 -0
- /package/{dist/lit-exports/all-lit-exports.d.ts → src/lit-exports/all-lit-exports.ts} +0 -0
- /package/{dist/util/type.d.ts → src/util/type.ts} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import {defineElement} from 'element-vir';
|
|
2
|
+
import {html, listen} from '../index.js';
|
|
3
|
+
import {MyWithEvents} from './my-with-events.element.js';
|
|
4
|
+
|
|
4
5
|
export const MyWithEventListening = defineElement()({
|
|
5
6
|
tagName: 'my-with-event-listening',
|
|
6
7
|
state() {
|
|
@@ -8,16 +9,16 @@ export const MyWithEventListening = defineElement()({
|
|
|
8
9
|
myNumber: -1,
|
|
9
10
|
};
|
|
10
11
|
},
|
|
11
|
-
render({
|
|
12
|
-
return html
|
|
12
|
+
render({state, updateState}) {
|
|
13
|
+
return html`
|
|
13
14
|
<h1>My App</h1>
|
|
14
15
|
<${MyWithEvents}
|
|
15
16
|
${listen(MyWithEvents.events.logoutClick, () => {
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
console.info('logout triggered');
|
|
18
|
+
})}
|
|
18
19
|
${listen(MyWithEvents.events.randomNumber, (event) => {
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
updateState({myNumber: event.detail});
|
|
21
|
+
})}
|
|
21
22
|
></${MyWithEvents}>
|
|
22
23
|
<span>${state.myNumber}</span>
|
|
23
24
|
`;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {randomInteger} from '@augment-vir/common';
|
|
2
|
+
import {defineElement} from 'element-vir';
|
|
3
|
+
import {defineElementEvent, html, listen} from '../index.js';
|
|
4
|
+
|
|
5
|
+
export const MyWithEvents = defineElement()({
|
|
6
|
+
tagName: 'my-with-events',
|
|
7
|
+
events: {
|
|
8
|
+
logoutClick: defineElementEvent<void>(),
|
|
9
|
+
randomNumber: defineElementEvent<number>(),
|
|
10
|
+
},
|
|
11
|
+
render({dispatch, events}) {
|
|
12
|
+
return html`
|
|
13
|
+
<button ${listen('click', () => dispatch(new events.logoutClick()))}>log out</button>
|
|
14
|
+
<button
|
|
15
|
+
${listen('click', () =>
|
|
16
|
+
dispatch(new events.randomNumber(randomInteger({min: 0, max: 1_000_000}))),
|
|
17
|
+
)}
|
|
18
|
+
>
|
|
19
|
+
generate random number
|
|
20
|
+
</button>
|
|
21
|
+
`;
|
|
22
|
+
},
|
|
23
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {defineElement} from 'element-vir';
|
|
2
|
+
import {css, html} from '../index.js';
|
|
3
|
+
|
|
3
4
|
export const MyWithHostClassDefinition = defineElement()({
|
|
4
5
|
tagName: 'my-with-host-class-definition',
|
|
5
6
|
state() {
|
|
@@ -17,7 +18,7 @@ export const MyWithHostClassDefinition = defineElement()({
|
|
|
17
18
|
* This host class will be automatically applied if the given callback is evaluated to true
|
|
18
19
|
* after a call to render.
|
|
19
20
|
*/
|
|
20
|
-
'my-with-host-class-definition-automatic': ({
|
|
21
|
+
'my-with-host-class-definition-automatic': ({state}) => {
|
|
21
22
|
return state.myProp === 'foo';
|
|
22
23
|
},
|
|
23
24
|
},
|
|
@@ -25,7 +26,7 @@ export const MyWithHostClassDefinition = defineElement()({
|
|
|
25
26
|
* Apply styles to the host classes by using a callback for "styles". The callback's argument
|
|
26
27
|
* contains the host classes defined above in the "hostClasses" property.
|
|
27
28
|
*/
|
|
28
|
-
styles: ({
|
|
29
|
+
styles: ({hostClasses}) => css`
|
|
29
30
|
${hostClasses['my-with-host-class-definition-automatic'].selector} {
|
|
30
31
|
color: blue;
|
|
31
32
|
}
|
|
@@ -34,8 +35,8 @@ export const MyWithHostClassDefinition = defineElement()({
|
|
|
34
35
|
color: red;
|
|
35
36
|
}
|
|
36
37
|
`,
|
|
37
|
-
render({
|
|
38
|
-
return html
|
|
38
|
+
render({state}) {
|
|
39
|
+
return html`
|
|
39
40
|
${state.myProp}
|
|
40
41
|
`;
|
|
41
42
|
},
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import {defineElement} from 'element-vir';
|
|
2
|
+
import {html} from '../index.js';
|
|
3
|
+
import {MyWithHostClassDefinition} from './my-with-host-class-definition.element.js';
|
|
4
|
+
|
|
4
5
|
export const MyWithHostClassUsage = defineElement()({
|
|
5
6
|
tagName: 'my-with-host-class-usage',
|
|
6
7
|
render() {
|
|
7
|
-
return html
|
|
8
|
+
return html`
|
|
8
9
|
<${MyWithHostClassDefinition}
|
|
9
10
|
class=${MyWithHostClassDefinition.hostClasses['my-with-host-class-definition-a']}
|
|
10
11
|
></${MyWithHostClassDefinition}>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {defineElement, html} from '../index.js';
|
|
2
|
+
|
|
3
|
+
export const MyWithInputs = defineElement<{
|
|
4
|
+
username: string;
|
|
5
|
+
email: string;
|
|
6
|
+
}>()({
|
|
7
|
+
tagName: 'my-with-inputs',
|
|
8
|
+
render({inputs}) {
|
|
9
|
+
return html`
|
|
10
|
+
<span>Hello there ${inputs.username}!</span>
|
|
11
|
+
`;
|
|
12
|
+
},
|
|
13
|
+
});
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {defineElement} from 'element-vir';
|
|
2
|
+
import {html, onDomCreated} from '../index.js';
|
|
3
|
+
|
|
3
4
|
export const MyWithOnDomCreated = defineElement()({
|
|
4
5
|
tagName: 'my-with-on-dom-created',
|
|
5
6
|
render() {
|
|
6
|
-
return html
|
|
7
|
+
return html`
|
|
7
8
|
<span
|
|
8
9
|
${onDomCreated((element) => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
// logs a span element
|
|
11
|
+
console.info(element);
|
|
12
|
+
})}
|
|
12
13
|
>
|
|
13
14
|
Hello there!
|
|
14
15
|
</span>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {defineElement} from 'element-vir';
|
|
2
|
+
import {html, onResize} from '../index.js';
|
|
3
|
+
|
|
4
|
+
export const MyWithOnResize = defineElement()({
|
|
5
|
+
tagName: 'my-with-on-resize',
|
|
6
|
+
render() {
|
|
7
|
+
return html`
|
|
8
|
+
<span
|
|
9
|
+
${onResize((entry) => {
|
|
10
|
+
// this will track resizing of this span
|
|
11
|
+
// the entry parameter contains target and contentRect properties
|
|
12
|
+
console.info(entry);
|
|
13
|
+
})}
|
|
14
|
+
>
|
|
15
|
+
Hello there!
|
|
16
|
+
</span>
|
|
17
|
+
`;
|
|
18
|
+
},
|
|
19
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {defineElement, html, renderIf} from '../index.js';
|
|
2
|
+
|
|
3
|
+
export const MyWithRenderIf = defineElement<{shouldRender: boolean}>()({
|
|
4
|
+
tagName: 'my-with-render-if',
|
|
5
|
+
render({inputs}) {
|
|
6
|
+
return html`
|
|
7
|
+
${renderIf(
|
|
8
|
+
inputs.shouldRender,
|
|
9
|
+
html`
|
|
10
|
+
I'm conditionally rendered!
|
|
11
|
+
`,
|
|
12
|
+
)}
|
|
13
|
+
`;
|
|
14
|
+
},
|
|
15
|
+
});
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import {defineElement} from 'element-vir';
|
|
2
|
+
import {css, html} from '../index.js';
|
|
3
|
+
import {MySimple} from './my-simple.element.js';
|
|
4
|
+
|
|
4
5
|
export const MyWithStylesAndInterpolatedSelector = defineElement()({
|
|
5
6
|
tagName: 'my-with-styles-and-interpolated-selector',
|
|
6
|
-
styles: css
|
|
7
|
+
styles: css`
|
|
7
8
|
${MySimple} {
|
|
8
9
|
background-color: blue;
|
|
9
10
|
}
|
|
10
11
|
`,
|
|
11
12
|
render() {
|
|
12
|
-
return html
|
|
13
|
+
return html`
|
|
13
14
|
<${MySimple}></${MySimple}>
|
|
14
15
|
`;
|
|
15
16
|
},
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {defineElement} from 'element-vir';
|
|
2
|
+
import {css, html} from '../index.js';
|
|
3
|
+
|
|
3
4
|
export const MyWithStyles = defineElement()({
|
|
4
5
|
tagName: 'my-with-styles',
|
|
5
|
-
styles: css
|
|
6
|
+
styles: css`
|
|
6
7
|
:host {
|
|
7
8
|
display: flex;
|
|
8
9
|
flex-direction: column;
|
|
@@ -14,7 +15,7 @@ export const MyWithStyles = defineElement()({
|
|
|
14
15
|
}
|
|
15
16
|
`,
|
|
16
17
|
render() {
|
|
17
|
-
return html
|
|
18
|
+
return html`
|
|
18
19
|
<span>Hello there!</span>
|
|
19
20
|
<span>How are you doing?</span>
|
|
20
21
|
`;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {defineElement} from 'element-vir';
|
|
2
|
+
import {html, listen} from '../index.js';
|
|
3
|
+
|
|
3
4
|
export const MyWithUpdateState = defineElement()({
|
|
4
5
|
tagName: 'my-with-update-state',
|
|
5
6
|
state() {
|
|
@@ -9,15 +10,15 @@ export const MyWithUpdateState = defineElement()({
|
|
|
9
10
|
* Use "as" to create state properties that can be types other than the initial value's
|
|
10
11
|
* type. This is particularly useful when, as below, the initial value is undefined.
|
|
11
12
|
*/
|
|
12
|
-
email: undefined,
|
|
13
|
+
email: undefined as string | undefined,
|
|
13
14
|
};
|
|
14
15
|
},
|
|
15
|
-
render({
|
|
16
|
-
return html
|
|
16
|
+
render({state, updateState}) {
|
|
17
|
+
return html`
|
|
17
18
|
<span
|
|
18
19
|
${listen('click', () => {
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
updateState({username: 'new name!'});
|
|
21
|
+
})}
|
|
21
22
|
>
|
|
22
23
|
Hello there ${state.username}!
|
|
23
24
|
</span>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {check} from '@augment-vir/assert';
|
|
2
|
+
import {type DeclarativeElementDefinitionOptions} from '../declarative-element/definition-options.js';
|
|
3
|
+
import {type PropertyInitMapBase} from '../declarative-element/properties/element-properties.js';
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* A minimal element definition used for interpolating element definitions into HTML templates with
|
|
5
7
|
* a more generic type (to prevent insane circular dependencies).
|
|
@@ -10,10 +12,9 @@ export type MinimalElementDefinition<TagName extends string = string> = {
|
|
|
10
12
|
tagName: TagName;
|
|
11
13
|
elementOptions?: DeclarativeElementDefinitionOptions | undefined;
|
|
12
14
|
/** This is used when wrapping interpolated raw tag name strings. */
|
|
13
|
-
tagInterpolationKey?: {
|
|
14
|
-
tagName: string;
|
|
15
|
-
} | undefined;
|
|
15
|
+
tagInterpolationKey?: {tagName: string} | undefined;
|
|
16
16
|
};
|
|
17
|
+
|
|
17
18
|
/**
|
|
18
19
|
* A parent definition of {@link MinimalElementDefinition} with inputs also specified with allows the
|
|
19
20
|
* `.assign()` method to be used inside of HTML templates.
|
|
@@ -30,16 +31,27 @@ export type MinimalDefinitionWithInputs<TagName extends string = string> = {
|
|
|
30
31
|
definition: MinimalElementDefinition<TagName>;
|
|
31
32
|
inputs: PropertyInitMapBase;
|
|
32
33
|
};
|
|
34
|
+
|
|
33
35
|
/**
|
|
34
36
|
* Checks if the input is an instance of {@link MinimalDefinitionWithInputs}.
|
|
35
37
|
*
|
|
36
38
|
* @category Internal
|
|
37
39
|
*/
|
|
38
|
-
export
|
|
40
|
+
export function isMinimalDefinitionWithInputs(
|
|
41
|
+
value: unknown,
|
|
42
|
+
): value is MinimalDefinitionWithInputs {
|
|
43
|
+
return (
|
|
44
|
+
check.hasKey(value, '_elementVirIsMinimalDefinitionWithInputs') &&
|
|
45
|
+
!!value._elementVirIsMinimalDefinitionWithInputs
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
39
49
|
/**
|
|
40
50
|
* Checks if the input is an object that has a `tagName` property. Used inside of the HTML tagged
|
|
41
51
|
* template functions for checking if interpolated values should be treated as element tags.
|
|
42
52
|
*
|
|
43
53
|
* @category Internal
|
|
44
54
|
*/
|
|
45
|
-
export
|
|
55
|
+
export function hasTagName(value: unknown): value is MinimalElementDefinition {
|
|
56
|
+
return check.hasKey(value, 'tagName') && !!value.tagName && typeof value.tagName === 'string';
|
|
57
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import {check} from '@augment-vir/assert';
|
|
2
|
+
import {filterMap} from '@augment-vir/common';
|
|
3
|
+
import {hasTagName, isMinimalDefinitionWithInputs} from './minimal-element-definition.js';
|
|
4
|
+
import {type TemplateTransform} from './template-transform-type.js';
|
|
5
|
+
|
|
6
|
+
type WeakMapElementKey = {
|
|
7
|
+
tagName: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
type TemplateAndNested = {
|
|
11
|
+
template: TemplateTransform | undefined;
|
|
12
|
+
nested: NestedTemplatesWeakMap | undefined;
|
|
13
|
+
};
|
|
14
|
+
type NestedTemplatesWeakMap = WeakMap<WeakMapElementKey, TemplateAndNested>;
|
|
15
|
+
type TemplatesWeakMap = WeakMap<TemplateStringsArray, TemplateAndNested>;
|
|
16
|
+
|
|
17
|
+
function extractElementKeys(values: unknown[]): WeakMapElementKey[] {
|
|
18
|
+
return filterMap(
|
|
19
|
+
values,
|
|
20
|
+
(value): WeakMapElementKey | undefined => {
|
|
21
|
+
if (isMinimalDefinitionWithInputs(value)) {
|
|
22
|
+
return value.definition;
|
|
23
|
+
}
|
|
24
|
+
if (hasTagName(value)) {
|
|
25
|
+
return value.tagInterpolationKey || value;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return undefined;
|
|
29
|
+
},
|
|
30
|
+
check.isTruthy,
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The transformed templates are written to a map so that we can preserve reference equality between
|
|
36
|
+
* calls. Without maintaining reference equality between html`` calls, lit-element reconstructs all
|
|
37
|
+
* of its children on every render.
|
|
38
|
+
*
|
|
39
|
+
* This is a WeakMap because we only care about the transformed array value as long as the original
|
|
40
|
+
* template array key exists.
|
|
41
|
+
*/
|
|
42
|
+
const transformedTemplateStrings: TemplatesWeakMap = new WeakMap();
|
|
43
|
+
|
|
44
|
+
export function getAlreadyMappedTemplate<PossibleValues>(
|
|
45
|
+
templateStringsKey: TemplateStringsArray,
|
|
46
|
+
values: PossibleValues[],
|
|
47
|
+
) {
|
|
48
|
+
const elementKeys = extractElementKeys(values);
|
|
49
|
+
const nestedValue = getNestedValues(transformedTemplateStrings, [
|
|
50
|
+
templateStringsKey,
|
|
51
|
+
...elementKeys,
|
|
52
|
+
]);
|
|
53
|
+
return nestedValue.value?.template;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function setMappedTemplate<PossibleValues>(
|
|
57
|
+
templateStringsKey: TemplateStringsArray,
|
|
58
|
+
values: PossibleValues[],
|
|
59
|
+
valueToSet: TemplateTransform,
|
|
60
|
+
) {
|
|
61
|
+
const elementKeys = extractElementKeys(values);
|
|
62
|
+
return setNestedValues(
|
|
63
|
+
transformedTemplateStrings,
|
|
64
|
+
[
|
|
65
|
+
templateStringsKey,
|
|
66
|
+
...elementKeys,
|
|
67
|
+
],
|
|
68
|
+
valueToSet,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function getNestedValues(
|
|
73
|
+
map: TemplatesWeakMap | NestedTemplatesWeakMap,
|
|
74
|
+
keys: (TemplateStringsArray | WeakMapElementKey)[],
|
|
75
|
+
index = 0,
|
|
76
|
+
): {value: undefined | TemplateAndNested; reason: string} {
|
|
77
|
+
const {currentTemplateAndNested, reason} = getCurrentKeyAndValue(map, keys, index);
|
|
78
|
+
if (!currentTemplateAndNested) {
|
|
79
|
+
return {value: currentTemplateAndNested, reason};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (index === keys.length - 1) {
|
|
83
|
+
return {value: currentTemplateAndNested, reason: `reached end of keys array`};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (!currentTemplateAndNested.nested) {
|
|
87
|
+
return {value: undefined, reason: `map at key index ${index} did not have nested maps`};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return getNestedValues(currentTemplateAndNested.nested, keys, index + 1);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function getCurrentKeyAndValue(
|
|
94
|
+
map: TemplatesWeakMap | NestedTemplatesWeakMap,
|
|
95
|
+
keys: (TemplateStringsArray | WeakMapElementKey)[],
|
|
96
|
+
index: number,
|
|
97
|
+
): {
|
|
98
|
+
currentKey: TemplateStringsArray | WeakMapElementKey | undefined;
|
|
99
|
+
currentTemplateAndNested: TemplateAndNested | undefined;
|
|
100
|
+
reason: string;
|
|
101
|
+
} {
|
|
102
|
+
const currentKey = keys[index];
|
|
103
|
+
if (currentKey == undefined) {
|
|
104
|
+
return {
|
|
105
|
+
currentKey: undefined,
|
|
106
|
+
currentTemplateAndNested: undefined,
|
|
107
|
+
reason: `key at index ${index} not found`,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
if (!map.has(currentKey as any)) {
|
|
111
|
+
return {
|
|
112
|
+
currentKey,
|
|
113
|
+
currentTemplateAndNested: undefined,
|
|
114
|
+
reason: `key at index ${index} was not in the map`,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const currentTemplateAndNested = map.get(currentKey as any);
|
|
118
|
+
if (currentTemplateAndNested == undefined) {
|
|
119
|
+
return {
|
|
120
|
+
currentKey,
|
|
121
|
+
currentTemplateAndNested: undefined,
|
|
122
|
+
reason: `value at key at index ${index} was undefined`,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return {currentKey, currentTemplateAndNested, reason: `key and value exists`};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function setNestedValues(
|
|
130
|
+
map: TemplatesWeakMap | NestedTemplatesWeakMap,
|
|
131
|
+
keys: (TemplateStringsArray | WeakMapElementKey)[],
|
|
132
|
+
valueToSet: TemplateTransform,
|
|
133
|
+
index = 0,
|
|
134
|
+
): {result: boolean; reason: string} {
|
|
135
|
+
const {currentTemplateAndNested, currentKey, reason} = getCurrentKeyAndValue(map, keys, index);
|
|
136
|
+
if (!currentKey) {
|
|
137
|
+
return {result: false, reason};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const nestedAndTemplate = currentTemplateAndNested ?? {nested: undefined, template: undefined};
|
|
141
|
+
if (!currentTemplateAndNested) {
|
|
142
|
+
map.set(currentKey as any, nestedAndTemplate);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (index === keys.length - 1) {
|
|
146
|
+
nestedAndTemplate.template = valueToSet;
|
|
147
|
+
return {result: true, reason: `set value at end of keys array`};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const nestedWeakMap = nestedAndTemplate.nested ?? new WeakMap();
|
|
151
|
+
|
|
152
|
+
if (!nestedAndTemplate.nested) {
|
|
153
|
+
nestedAndTemplate.nested = nestedWeakMap;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return setNestedValues(nestedWeakMap, keys, valueToSet, index + 1);
|
|
157
|
+
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {type ArrayInsertion} from '../util/array.js';
|
|
2
|
+
|
|
2
3
|
export type AllValueTransforms = {
|
|
3
4
|
valueIndexDeletions: number[];
|
|
4
5
|
valueInsertions: ArrayInsertion<unknown>[];
|
|
5
6
|
};
|
|
7
|
+
|
|
6
8
|
export type TemplateTransform = {
|
|
7
9
|
templateStrings: TemplateStringsArray;
|
|
8
10
|
valuesTransform(values: unknown[]): AllValueTransforms;
|
|
@@ -1,36 +1,78 @@
|
|
|
1
|
-
import { insertAndRemoveValues
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import {type ArrayInsertion, insertAndRemoveValues} from '../util/array.js';
|
|
2
|
+
import {getAlreadyMappedTemplate, setMappedTemplate} from './nested-mapped-templates.js';
|
|
3
|
+
import {type AllValueTransforms, type TemplateTransform} from './template-transform-type.js';
|
|
4
|
+
|
|
5
|
+
export type ValueInsertion = {
|
|
6
|
+
index: number;
|
|
7
|
+
value: unknown;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type ValueTransformCallback = (
|
|
11
|
+
lastNewString: string,
|
|
12
|
+
currentLitString: string,
|
|
13
|
+
currentValue: unknown,
|
|
14
|
+
) =>
|
|
15
|
+
| {
|
|
16
|
+
replacement: unknown;
|
|
17
|
+
getExtraValues: ((currentValue: unknown) => unknown[]) | undefined;
|
|
18
|
+
}
|
|
19
|
+
| undefined;
|
|
20
|
+
|
|
21
|
+
export function getTransformedTemplate<PossibleValues>(
|
|
22
|
+
templateStringsKey: TemplateStringsArray,
|
|
23
|
+
values: PossibleValues[],
|
|
24
|
+
fallbackTransform: () => TemplateTransform,
|
|
25
|
+
) {
|
|
4
26
|
const alreadyTransformedTemplateStrings = getAlreadyMappedTemplate(templateStringsKey, values);
|
|
5
|
-
|
|
27
|
+
|
|
28
|
+
const templateTransform: TemplateTransform =
|
|
29
|
+
alreadyTransformedTemplateStrings ?? fallbackTransform();
|
|
30
|
+
|
|
6
31
|
if (!alreadyTransformedTemplateStrings) {
|
|
7
32
|
const result = setMappedTemplate(templateStringsKey, values, templateTransform);
|
|
8
33
|
if (!result.result) {
|
|
9
34
|
throw new Error(`Failed to set template transform: ${result.reason}`);
|
|
10
35
|
}
|
|
11
36
|
}
|
|
37
|
+
|
|
12
38
|
const valueTransforms = templateTransform.valuesTransform(values);
|
|
13
|
-
|
|
39
|
+
|
|
40
|
+
const transformedValuesArray: PossibleValues[] = insertAndRemoveValues(
|
|
41
|
+
values,
|
|
42
|
+
valueTransforms.valueInsertions,
|
|
43
|
+
valueTransforms.valueIndexDeletions,
|
|
44
|
+
) as PossibleValues[];
|
|
45
|
+
|
|
14
46
|
return {
|
|
15
47
|
strings: templateTransform.templateStrings,
|
|
16
48
|
values: transformedValuesArray,
|
|
17
49
|
};
|
|
18
50
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
51
|
+
|
|
52
|
+
export function transformTemplate<PossibleValues>(
|
|
53
|
+
inputTemplateStrings: TemplateStringsArray,
|
|
54
|
+
inputValues: PossibleValues[],
|
|
55
|
+
transformValue: ValueTransformCallback,
|
|
56
|
+
assertValidString?: (templateStringPart: string) => void,
|
|
57
|
+
): TemplateTransform {
|
|
58
|
+
const newStrings: string[] = [];
|
|
59
|
+
const newRaws: string[] = [];
|
|
60
|
+
const valueIndexDeletions: AllValueTransforms['valueIndexDeletions'] = [];
|
|
61
|
+
const valueTransforms: ((values: unknown[]) => ArrayInsertion<unknown>)[] = [];
|
|
62
|
+
|
|
24
63
|
inputTemplateStrings.forEach((currentTemplateString, currentTemplateStringIndex) => {
|
|
25
64
|
const lastNewStringsIndex = newStrings.length - 1;
|
|
26
65
|
const lastNewString = newStrings[lastNewStringsIndex];
|
|
27
66
|
const currentValueIndex = currentTemplateStringIndex - 1;
|
|
28
67
|
const currentValue = inputValues[currentValueIndex];
|
|
68
|
+
|
|
29
69
|
if (assertValidString) {
|
|
30
70
|
assertValidString(currentTemplateString);
|
|
31
71
|
}
|
|
32
|
-
|
|
33
|
-
let
|
|
72
|
+
|
|
73
|
+
let transformOutput: ReturnType<ValueTransformCallback> | undefined = undefined;
|
|
74
|
+
let extraValues: unknown[] = [];
|
|
75
|
+
|
|
34
76
|
if (typeof lastNewString === 'string') {
|
|
35
77
|
transformOutput = transformValue(lastNewString, currentTemplateString, currentValue);
|
|
36
78
|
if (transformOutput) {
|
|
@@ -41,6 +83,7 @@ export function transformTemplate(inputTemplateStrings, inputValues, transformVa
|
|
|
41
83
|
valueIndexDeletions.push(currentValueIndex);
|
|
42
84
|
const getExtraValuesCallback = transformOutput.getExtraValues;
|
|
43
85
|
extraValues = getExtraValuesCallback ? getExtraValuesCallback(currentValue) : [];
|
|
86
|
+
|
|
44
87
|
if (extraValues.length && getExtraValuesCallback) {
|
|
45
88
|
newStrings[lastNewStringsIndex] += ' ';
|
|
46
89
|
extraValues.forEach((value, index) => {
|
|
@@ -49,7 +92,7 @@ export function transformTemplate(inputTemplateStrings, inputValues, transformVa
|
|
|
49
92
|
newStrings.push(' ');
|
|
50
93
|
}
|
|
51
94
|
});
|
|
52
|
-
valueTransforms.push((values) => {
|
|
95
|
+
valueTransforms.push((values): ArrayInsertion<unknown> => {
|
|
53
96
|
const latestCurrentValue = values[currentValueIndex];
|
|
54
97
|
const insertions = getExtraValuesCallback(latestCurrentValue);
|
|
55
98
|
return {
|
|
@@ -58,21 +101,22 @@ export function transformTemplate(inputTemplateStrings, inputValues, transformVa
|
|
|
58
101
|
};
|
|
59
102
|
});
|
|
60
103
|
newStrings.push(currentTemplateString);
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
104
|
+
} else {
|
|
63
105
|
newStrings[lastNewStringsIndex] += currentTemplateString;
|
|
64
106
|
}
|
|
65
107
|
}
|
|
66
108
|
}
|
|
109
|
+
|
|
67
110
|
if (!transformOutput) {
|
|
68
111
|
newStrings.push(currentTemplateString);
|
|
69
112
|
}
|
|
113
|
+
|
|
70
114
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
71
|
-
const currentRawLitString = inputTemplateStrings.raw[currentTemplateStringIndex]
|
|
115
|
+
const currentRawLitString = inputTemplateStrings.raw[currentTemplateStringIndex]!;
|
|
72
116
|
if (transformOutput) {
|
|
73
117
|
newRaws[lastNewStringsIndex] = [
|
|
74
118
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
75
|
-
newRaws[lastNewStringsIndex]
|
|
119
|
+
newRaws[lastNewStringsIndex]!,
|
|
76
120
|
transformOutput.replacement,
|
|
77
121
|
currentRawLitString,
|
|
78
122
|
].join('');
|
|
@@ -81,18 +125,22 @@ export function transformTemplate(inputTemplateStrings, inputValues, transformVa
|
|
|
81
125
|
newRaws.push('');
|
|
82
126
|
});
|
|
83
127
|
}
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
128
|
+
} else {
|
|
86
129
|
newRaws.push(currentRawLitString);
|
|
87
130
|
}
|
|
88
131
|
});
|
|
89
|
-
|
|
132
|
+
|
|
133
|
+
const newTemplateStrings: TemplateStringsArray = Object.assign([], newStrings, {
|
|
90
134
|
raw: newRaws,
|
|
91
135
|
});
|
|
136
|
+
|
|
92
137
|
return {
|
|
93
138
|
templateStrings: newTemplateStrings,
|
|
94
|
-
valuesTransform(values) {
|
|
95
|
-
const insertions = valueTransforms.flatMap(
|
|
139
|
+
valuesTransform(values): AllValueTransforms {
|
|
140
|
+
const insertions: ArrayInsertion<unknown>[] = valueTransforms.flatMap(
|
|
141
|
+
(transformCallback) => transformCallback(values),
|
|
142
|
+
);
|
|
143
|
+
|
|
96
144
|
return {
|
|
97
145
|
valueIndexDeletions,
|
|
98
146
|
valueInsertions: insertions,
|