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
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import {getObjectTypedKeys, type SetRequiredAndNotNull} from '@augment-vir/common';
|
|
2
|
+
import {type HtmlInterpolation} from '../template-transforms/vir-html/html-interpolation.js';
|
|
3
|
+
import {type TypedEvent} from '../typed-event/typed-event.js';
|
|
4
|
+
import {type CustomElementTagName} from './custom-tag-name.js';
|
|
5
|
+
import {type DeclarativeElement, type DeclarativeElementHost} from './declarative-element.js';
|
|
6
|
+
import {type CssVars} from './properties/css-vars.js';
|
|
7
|
+
import {
|
|
8
|
+
type EventDescriptorMap,
|
|
9
|
+
type EventInitMapEventDetailExtractor,
|
|
10
|
+
type EventsInitMap,
|
|
11
|
+
} from './properties/element-events.js';
|
|
12
|
+
import {type PropertyInitMapBase} from './properties/element-properties.js';
|
|
13
|
+
import {type BaseStringName, type StringNameMap} from './properties/string-names.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Type for the `render` element definition method.
|
|
17
|
+
*
|
|
18
|
+
* @category Internal
|
|
19
|
+
*/
|
|
20
|
+
export type RenderCallback<
|
|
21
|
+
TagName extends CustomElementTagName = any,
|
|
22
|
+
Inputs extends PropertyInitMapBase = any,
|
|
23
|
+
State extends PropertyInitMapBase = any,
|
|
24
|
+
EventsInit extends EventsInitMap = any,
|
|
25
|
+
HostClassKeys extends BaseStringName<TagName> = any,
|
|
26
|
+
CssVarKeys extends BaseStringName<TagName> = any,
|
|
27
|
+
SlotNames extends ReadonlyArray<string> = any,
|
|
28
|
+
TestIds extends ReadonlyArray<string> = any,
|
|
29
|
+
> = (
|
|
30
|
+
params: RenderParams<
|
|
31
|
+
TagName,
|
|
32
|
+
Inputs,
|
|
33
|
+
State,
|
|
34
|
+
EventsInit,
|
|
35
|
+
HostClassKeys,
|
|
36
|
+
CssVarKeys,
|
|
37
|
+
SlotNames,
|
|
38
|
+
TestIds
|
|
39
|
+
>,
|
|
40
|
+
) => HtmlInterpolation;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Type for the `init` and `cleanup` element definition methods.
|
|
44
|
+
*
|
|
45
|
+
* @category Internal
|
|
46
|
+
*/
|
|
47
|
+
export type InitCallback<
|
|
48
|
+
TagName extends CustomElementTagName,
|
|
49
|
+
Inputs extends PropertyInitMapBase,
|
|
50
|
+
State extends PropertyInitMapBase,
|
|
51
|
+
EventsInit extends EventsInitMap,
|
|
52
|
+
HostClassKeys extends BaseStringName<TagName>,
|
|
53
|
+
CssVarKeys extends BaseStringName<TagName>,
|
|
54
|
+
SlotNames extends ReadonlyArray<string>,
|
|
55
|
+
TestIds extends ReadonlyArray<string>,
|
|
56
|
+
> = (
|
|
57
|
+
params: RenderParams<
|
|
58
|
+
TagName,
|
|
59
|
+
Inputs,
|
|
60
|
+
State,
|
|
61
|
+
EventsInit,
|
|
62
|
+
HostClassKeys,
|
|
63
|
+
CssVarKeys,
|
|
64
|
+
SlotNames,
|
|
65
|
+
TestIds
|
|
66
|
+
>,
|
|
67
|
+
) => undefined | void;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Type for the `updateState` render parameter.
|
|
71
|
+
*
|
|
72
|
+
* @category Internal
|
|
73
|
+
*/
|
|
74
|
+
export type UpdateStateCallback<State extends PropertyInitMapBase> = (
|
|
75
|
+
newState: Partial<State>,
|
|
76
|
+
) => void;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The full parameters object passed to `render`, `init`, and `cleanup` element definition methods.
|
|
80
|
+
*
|
|
81
|
+
* @category Internal
|
|
82
|
+
*/
|
|
83
|
+
export type RenderParams<
|
|
84
|
+
TagName extends CustomElementTagName,
|
|
85
|
+
Inputs extends PropertyInitMapBase,
|
|
86
|
+
State extends PropertyInitMapBase,
|
|
87
|
+
EventsInit extends EventsInitMap,
|
|
88
|
+
HostClassKeys extends BaseStringName<TagName>,
|
|
89
|
+
CssVarKeys extends BaseStringName<TagName>,
|
|
90
|
+
SlotNames extends ReadonlyArray<string>,
|
|
91
|
+
TestIds extends ReadonlyArray<string>,
|
|
92
|
+
> = {
|
|
93
|
+
state: Readonly<State>;
|
|
94
|
+
cssVars: Readonly<CssVars<TagName, CssVarKeys>>;
|
|
95
|
+
updateState: UpdateStateCallback<State>;
|
|
96
|
+
events: EventDescriptorMap<TagName, EventsInit>;
|
|
97
|
+
host: DeclarativeElementHost<
|
|
98
|
+
TagName,
|
|
99
|
+
Inputs,
|
|
100
|
+
State,
|
|
101
|
+
EventsInit,
|
|
102
|
+
HostClassKeys,
|
|
103
|
+
CssVarKeys,
|
|
104
|
+
SlotNames,
|
|
105
|
+
TestIds
|
|
106
|
+
>;
|
|
107
|
+
slotNames: Readonly<StringNameMap<TagName, 'slot', SlotNames>>;
|
|
108
|
+
testIds: Readonly<StringNameMap<TagName, 'test-id', TestIds>>;
|
|
109
|
+
/** Dispatch an event from the current element. */
|
|
110
|
+
dispatch: <EventTypeName extends keyof EventsInit>(
|
|
111
|
+
event:
|
|
112
|
+
| TypedEvent<
|
|
113
|
+
EventTypeName extends string ? EventTypeName : never,
|
|
114
|
+
EventInitMapEventDetailExtractor<EventTypeName, EventsInit>
|
|
115
|
+
>
|
|
116
|
+
| Event,
|
|
117
|
+
) => boolean;
|
|
118
|
+
inputs: Readonly<Inputs>;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* This is used to create the parameters passed to the `render`, `init`, and `cleanup` element
|
|
123
|
+
* definition methods whenever they are called.
|
|
124
|
+
*
|
|
125
|
+
* @category Internal
|
|
126
|
+
*/
|
|
127
|
+
export function createRenderParams<
|
|
128
|
+
TagName extends CustomElementTagName,
|
|
129
|
+
Inputs extends PropertyInitMapBase,
|
|
130
|
+
State extends PropertyInitMapBase,
|
|
131
|
+
EventsInit extends EventsInitMap,
|
|
132
|
+
HostClassKeys extends BaseStringName<TagName>,
|
|
133
|
+
CssVarKeys extends BaseStringName<TagName>,
|
|
134
|
+
SlotNames extends ReadonlyArray<string>,
|
|
135
|
+
TestIds extends ReadonlyArray<string>,
|
|
136
|
+
>({
|
|
137
|
+
element,
|
|
138
|
+
eventsMap,
|
|
139
|
+
cssVars,
|
|
140
|
+
slotNamesMap,
|
|
141
|
+
testIdsMap,
|
|
142
|
+
}: {
|
|
143
|
+
element: DeclarativeElement<
|
|
144
|
+
TagName,
|
|
145
|
+
Inputs,
|
|
146
|
+
State,
|
|
147
|
+
EventsInit,
|
|
148
|
+
HostClassKeys,
|
|
149
|
+
CssVarKeys,
|
|
150
|
+
SlotNames,
|
|
151
|
+
TestIds
|
|
152
|
+
>;
|
|
153
|
+
eventsMap: EventDescriptorMap<TagName, EventsInit>;
|
|
154
|
+
cssVars: Readonly<CssVars<TagName, CssVarKeys>>;
|
|
155
|
+
slotNamesMap: Readonly<StringNameMap<TagName, 'slot', SlotNames>>;
|
|
156
|
+
testIdsMap: Readonly<StringNameMap<TagName, 'test-id', TestIds>>;
|
|
157
|
+
}): RenderParams<
|
|
158
|
+
TagName,
|
|
159
|
+
Inputs,
|
|
160
|
+
State,
|
|
161
|
+
EventsInit,
|
|
162
|
+
HostClassKeys,
|
|
163
|
+
CssVarKeys,
|
|
164
|
+
SlotNames,
|
|
165
|
+
TestIds
|
|
166
|
+
> {
|
|
167
|
+
function updateState(newStatePartial: Parameters<UpdateStateCallback<State>>[0]) {
|
|
168
|
+
getObjectTypedKeys(newStatePartial).forEach((stateKey) => {
|
|
169
|
+
const newValue = newStatePartial[stateKey] as State[typeof stateKey];
|
|
170
|
+
|
|
171
|
+
element.instanceState[stateKey] = newValue;
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const renderParams: RenderParams<
|
|
176
|
+
TagName,
|
|
177
|
+
Inputs,
|
|
178
|
+
State,
|
|
179
|
+
EventsInit,
|
|
180
|
+
HostClassKeys,
|
|
181
|
+
CssVarKeys,
|
|
182
|
+
SlotNames,
|
|
183
|
+
TestIds
|
|
184
|
+
> = {
|
|
185
|
+
cssVars,
|
|
186
|
+
slotNames: slotNamesMap,
|
|
187
|
+
testIds: testIdsMap,
|
|
188
|
+
dispatch: (event) => element.dispatchEvent(event),
|
|
189
|
+
events: eventsMap,
|
|
190
|
+
host: element as SetRequiredAndNotNull<typeof element, 'shadowRoot'>,
|
|
191
|
+
inputs: element.instanceInputs,
|
|
192
|
+
state: element.instanceState,
|
|
193
|
+
updateState,
|
|
194
|
+
};
|
|
195
|
+
return renderParams;
|
|
196
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-empty-object-type */
|
|
2
|
+
|
|
3
|
+
import {type PartialWithNullable} from '@augment-vir/common';
|
|
4
|
+
import {type CustomElementTagName} from './custom-tag-name.js';
|
|
5
|
+
import {type DeclarativeElementInit} from './declarative-element-init.js';
|
|
6
|
+
import {type DeclarativeElementInputErrorParams, defineElement} from './define-element.js';
|
|
7
|
+
import {type EventsInitMap} from './properties/element-events.js';
|
|
8
|
+
import {type PropertyInitMapBase} from './properties/element-properties.js';
|
|
9
|
+
import {type BaseStringName} from './properties/string-names.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Options for {@link wrapDefineElement}.
|
|
13
|
+
*
|
|
14
|
+
* @category Internal
|
|
15
|
+
*/
|
|
16
|
+
export type WrapDefineElementOptions<
|
|
17
|
+
TagNameRequirement extends CustomElementTagName = CustomElementTagName,
|
|
18
|
+
InputsRequirement extends PropertyInitMapBase = {},
|
|
19
|
+
StateRequirement extends PropertyInitMapBase = {},
|
|
20
|
+
EventsInitRequirement extends EventsInitMap = {},
|
|
21
|
+
> = PartialWithNullable<{
|
|
22
|
+
/**
|
|
23
|
+
* An optional callback which asserts that an element definition init object given to the
|
|
24
|
+
* wrapped element definition functions is valid.
|
|
25
|
+
*/
|
|
26
|
+
assertInputs: (
|
|
27
|
+
inputInit: DeclarativeElementInit<
|
|
28
|
+
TagNameRequirement,
|
|
29
|
+
InputsRequirement,
|
|
30
|
+
StateRequirement,
|
|
31
|
+
EventsInitRequirement,
|
|
32
|
+
BaseStringName<TagNameRequirement>,
|
|
33
|
+
BaseStringName<TagNameRequirement>,
|
|
34
|
+
ReadonlyArray<string>,
|
|
35
|
+
ReadonlyArray<string>
|
|
36
|
+
>,
|
|
37
|
+
) => void;
|
|
38
|
+
/**
|
|
39
|
+
* An optional callback which transforms a element definition init object given to the wrapped
|
|
40
|
+
* element definition.
|
|
41
|
+
*/
|
|
42
|
+
transformInputs: (
|
|
43
|
+
inputInit: DeclarativeElementInit<
|
|
44
|
+
TagNameRequirement,
|
|
45
|
+
InputsRequirement,
|
|
46
|
+
StateRequirement,
|
|
47
|
+
EventsInitRequirement,
|
|
48
|
+
BaseStringName<TagNameRequirement>,
|
|
49
|
+
BaseStringName<TagNameRequirement>,
|
|
50
|
+
ReadonlyArray<string>,
|
|
51
|
+
ReadonlyArray<string>
|
|
52
|
+
>,
|
|
53
|
+
) => DeclarativeElementInit<
|
|
54
|
+
TagNameRequirement,
|
|
55
|
+
InputsRequirement,
|
|
56
|
+
StateRequirement,
|
|
57
|
+
EventsInitRequirement,
|
|
58
|
+
BaseStringName<TagNameRequirement>,
|
|
59
|
+
BaseStringName<TagNameRequirement>,
|
|
60
|
+
ReadonlyArray<string>,
|
|
61
|
+
ReadonlyArray<string>
|
|
62
|
+
>;
|
|
63
|
+
}>;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Wraps {@link defineElement} in a superset of requirements. For example:
|
|
67
|
+
*
|
|
68
|
+
* - You could create element definition functions that require all elements to start with a common
|
|
69
|
+
* prefix, like `vir-`.
|
|
70
|
+
* - You could create element definition functions that require all elements to have _at least_ a
|
|
71
|
+
* specified set of input properties.
|
|
72
|
+
* - Etc.
|
|
73
|
+
*
|
|
74
|
+
* @category Element Definition
|
|
75
|
+
*/
|
|
76
|
+
export function wrapDefineElement<
|
|
77
|
+
TagNameRequirement extends CustomElementTagName = CustomElementTagName,
|
|
78
|
+
InputsRequirement extends PropertyInitMapBase = {},
|
|
79
|
+
StateRequirement extends PropertyInitMapBase = {},
|
|
80
|
+
EventsInitRequirement extends EventsInitMap = {},
|
|
81
|
+
>(options?: WrapDefineElementOptions | undefined) {
|
|
82
|
+
const {assertInputs, transformInputs}: WrapDefineElementOptions = {
|
|
83
|
+
assertInputs: options?.assertInputs ?? (() => {}),
|
|
84
|
+
transformInputs: options?.transformInputs ?? ((inputs: any) => inputs),
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
return <Inputs extends InputsRequirement>(
|
|
88
|
+
...errorParams: DeclarativeElementInputErrorParams<Inputs>
|
|
89
|
+
) => {
|
|
90
|
+
return <
|
|
91
|
+
const TagName extends TagNameRequirement,
|
|
92
|
+
State extends StateRequirement,
|
|
93
|
+
EventsInit extends EventsInitRequirement,
|
|
94
|
+
const HostClassKeys extends BaseStringName<TagName> = `${TagName}-`,
|
|
95
|
+
const CssVarKeys extends BaseStringName<TagName> = `${TagName}-`,
|
|
96
|
+
const SlotNames extends ReadonlyArray<string> = Readonly<[]>,
|
|
97
|
+
const TestIds extends ReadonlyArray<string> = Readonly<[]>,
|
|
98
|
+
>(
|
|
99
|
+
inputs: DeclarativeElementInit<
|
|
100
|
+
TagName,
|
|
101
|
+
Inputs,
|
|
102
|
+
State,
|
|
103
|
+
EventsInit,
|
|
104
|
+
HostClassKeys,
|
|
105
|
+
CssVarKeys,
|
|
106
|
+
SlotNames,
|
|
107
|
+
TestIds
|
|
108
|
+
>,
|
|
109
|
+
) => {
|
|
110
|
+
assertInputs(inputs as DeclarativeElementInit<any, any, any, any, any, any, any, any>);
|
|
111
|
+
return defineElement<Inputs>(...errorParams)(
|
|
112
|
+
transformInputs(
|
|
113
|
+
inputs as DeclarativeElementInit<any, any, any, any, any, any, any, any>,
|
|
114
|
+
) as unknown as DeclarativeElementInit<
|
|
115
|
+
TagName,
|
|
116
|
+
Inputs,
|
|
117
|
+
State,
|
|
118
|
+
EventsInit,
|
|
119
|
+
HostClassKeys,
|
|
120
|
+
CssVarKeys,
|
|
121
|
+
SlotNames,
|
|
122
|
+
TestIds
|
|
123
|
+
>,
|
|
124
|
+
);
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from 'observavir';
|
|
2
|
+
|
|
2
3
|
export * from './declarative-element/custom-tag-name.js';
|
|
3
4
|
export * from './declarative-element/declarative-element-init.js';
|
|
4
5
|
export * from './declarative-element/declarative-element.js';
|
|
@@ -39,4 +40,5 @@ export * from './template-transforms/vir-html/vir-html.js';
|
|
|
39
40
|
export * from './typed-event/typed-event.js';
|
|
40
41
|
export * from './util/increment.js';
|
|
41
42
|
export * from './util/lit-template.js';
|
|
43
|
+
export * from './util/map-async-value.js';
|
|
42
44
|
export * from './util/type.js';
|
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {LitElement, noChange, nothing, svg, unsafeCSS} from 'lit';
|
|
2
|
+
export type {
|
|
3
|
+
CSSResult,
|
|
4
|
+
CSSResultGroup,
|
|
5
|
+
CompiledTemplate,
|
|
6
|
+
CompiledTemplateResult,
|
|
7
|
+
HTMLTemplateResult,
|
|
8
|
+
SVGTemplateResult,
|
|
9
|
+
TemplateResult,
|
|
10
|
+
} from 'lit';
|
|
2
11
|
export * from 'lit/async-directive.js';
|
|
3
12
|
export * from 'lit/decorators.js';
|
|
4
13
|
export * from 'lit/directive-helpers.js';
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
export type {
|
|
2
|
-
export type {
|
|
3
|
-
|
|
4
|
-
import { type
|
|
5
|
-
import {
|
|
6
|
-
import { type
|
|
1
|
+
export type {KeyFn} from 'lit/directives/repeat.js';
|
|
2
|
+
export type {RepeatDirective};
|
|
3
|
+
|
|
4
|
+
import {type Directive, type PartInfo} from 'lit-html/directive.js';
|
|
5
|
+
import {type KeyFn} from 'lit-html/directives/repeat.js';
|
|
6
|
+
import {type ChildPart, type noChange} from 'lit-html/lit-html.js';
|
|
7
|
+
import {repeat as repeatImport} from 'lit/directives/repeat.js';
|
|
8
|
+
import {type HtmlInterpolation} from '../template-transforms/vir-html/html-interpolation.js';
|
|
9
|
+
|
|
7
10
|
/**
|
|
8
11
|
* A modified class type for the built-in lit `repeat` directive which works for element-vir
|
|
9
12
|
* declarative elements.
|
|
@@ -15,16 +18,32 @@ declare class RepeatDirective extends Directive {
|
|
|
15
18
|
constructor(partInfo: PartInfo);
|
|
16
19
|
private _getValuesAndKeys;
|
|
17
20
|
/** Renders the repeated templates. */
|
|
18
|
-
render<T>(items: Iterable<T>, template: ItemTemplate<T>): Array<HtmlInterpolation>;
|
|
21
|
+
public render<T>(items: Iterable<T>, template: ItemTemplate<T>): Array<HtmlInterpolation>;
|
|
19
22
|
/** Renders the repeated templates. */
|
|
20
|
-
render<T>(
|
|
23
|
+
public render<T>(
|
|
24
|
+
items: Iterable<T>,
|
|
25
|
+
keyFn: KeyFn<T> | ItemTemplate<T>,
|
|
26
|
+
template: ItemTemplate<T>,
|
|
27
|
+
): Array<HtmlInterpolation>;
|
|
28
|
+
|
|
21
29
|
/** Updates the repeated templates. */
|
|
22
|
-
update<T>(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
public update<T>(
|
|
31
|
+
containerPart: ChildPart,
|
|
32
|
+
[
|
|
33
|
+
items,
|
|
34
|
+
keyFnOrTemplate,
|
|
35
|
+
template,
|
|
36
|
+
]: [
|
|
37
|
+
Iterable<T>,
|
|
38
|
+
(
|
|
39
|
+
| KeyFn<T>
|
|
40
|
+
| ItemTemplate<T>
|
|
41
|
+
),
|
|
42
|
+
ItemTemplate<T>,
|
|
43
|
+
],
|
|
44
|
+
): HtmlInterpolation[] | typeof noChange;
|
|
27
45
|
}
|
|
46
|
+
|
|
28
47
|
/**
|
|
29
48
|
* A modified `ItemTemplate` type for the built-in lit `repeat` directive which works for
|
|
30
49
|
* element-vir declarative elements.
|
|
@@ -32,6 +51,7 @@ declare class RepeatDirective extends Directive {
|
|
|
32
51
|
* @category Internal
|
|
33
52
|
*/
|
|
34
53
|
export type ItemTemplate<T> = (item: T, index: number) => HtmlInterpolation;
|
|
54
|
+
|
|
35
55
|
/**
|
|
36
56
|
* A modified `RepeatDirectiveFn` type for the built-in lit `repeat` directive which works for
|
|
37
57
|
* element-vir declarative elements.
|
|
@@ -39,10 +59,19 @@ export type ItemTemplate<T> = (item: T, index: number) => HtmlInterpolation;
|
|
|
39
59
|
* @category Internal
|
|
40
60
|
*/
|
|
41
61
|
export interface RepeatDirectiveFn {
|
|
42
|
-
<T>(
|
|
62
|
+
<T>(
|
|
63
|
+
items: Iterable<T>,
|
|
64
|
+
keyFnOrTemplate: KeyFn<T> | ItemTemplate<T>,
|
|
65
|
+
template?: ItemTemplate<T>,
|
|
66
|
+
): HtmlInterpolation[];
|
|
43
67
|
<T>(items: Iterable<T>, template: ItemTemplate<T>): HtmlInterpolation[];
|
|
44
|
-
<T>(
|
|
68
|
+
<T>(
|
|
69
|
+
items: Iterable<T>,
|
|
70
|
+
keyFn: KeyFn<T> | ItemTemplate<T>,
|
|
71
|
+
template: ItemTemplate<T>,
|
|
72
|
+
): HtmlInterpolation[];
|
|
45
73
|
}
|
|
74
|
+
|
|
46
75
|
/**
|
|
47
76
|
* A directive that repeats a series of values (usually `TemplateResults`) generated from an
|
|
48
77
|
* iterable, and updates those items efficiently when the iterable changes based on user-provided
|
|
@@ -78,4 +107,4 @@ export interface RepeatDirectiveFn {
|
|
|
78
107
|
* If no `keyFn` is provided, this directive will perform similar to mapping items to values, and
|
|
79
108
|
* DOM will be reused against potentially different items.
|
|
80
109
|
*/
|
|
81
|
-
export
|
|
110
|
+
export const repeat = repeatImport as RepeatDirectiveFn;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import {defineElement} from 'element-vir';
|
|
2
|
+
import {html} from '../index.js';
|
|
3
|
+
import {MySimple} from './my-simple.element.js';
|
|
4
|
+
|
|
4
5
|
export const MyApp = defineElement()({
|
|
5
6
|
tagName: 'my-app',
|
|
6
7
|
render() {
|
|
7
|
-
return html
|
|
8
|
+
return html`
|
|
8
9
|
<h1>My App</h1>
|
|
9
10
|
<${MySimple}></${MySimple}>
|
|
10
11
|
`;
|
package/{dist/readme-examples/my-custom-define.js → src/readme-examples/my-custom-define.ts}
RENAMED
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {wrapDefineElement} from '../index.js';
|
|
2
|
+
|
|
3
|
+
export type VirTagName = `vir-${string}`;
|
|
4
|
+
|
|
5
|
+
export const defineVirElement = wrapDefineElement<VirTagName>();
|
|
6
|
+
|
|
3
7
|
// add an optional assert callback
|
|
4
|
-
export const defineVerifiedVirElement = wrapDefineElement({
|
|
8
|
+
export const defineVerifiedVirElement = wrapDefineElement<VirTagName>({
|
|
5
9
|
assertInputs: (inputs) => {
|
|
6
10
|
if (!inputs.tagName.startsWith('vir-')) {
|
|
7
11
|
throw new Error(`all custom elements must start with "vir-"`);
|
|
8
12
|
}
|
|
9
13
|
},
|
|
10
14
|
});
|
|
15
|
+
|
|
11
16
|
// add an optional transform callback
|
|
12
|
-
export const defineTransformedVirElement = wrapDefineElement({
|
|
17
|
+
export const defineTransformedVirElement = wrapDefineElement<VirTagName>({
|
|
13
18
|
transformInputs: (inputs) => {
|
|
14
19
|
return {
|
|
15
20
|
...inputs,
|
package/{dist/readme-examples/my-simple.element.js → src/readme-examples/my-simple.element.ts}
RENAMED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {defineElement} from 'element-vir';
|
|
2
|
+
import {html} from '../index.js';
|
|
3
|
+
|
|
3
4
|
export const MySimple = defineElement()({
|
|
4
5
|
tagName: 'my-simple',
|
|
5
6
|
render() {
|
|
6
|
-
return html
|
|
7
|
+
return html`
|
|
7
8
|
<span>Hello there!</span>
|
|
8
9
|
`;
|
|
9
10
|
},
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {defineElement} from 'element-vir';
|
|
2
|
+
import {html} from '../index.js';
|
|
3
|
+
import {MyWithInputs} from './my-with-inputs.element.js';
|
|
4
|
+
|
|
5
|
+
export const MyWithAssignment = defineElement()({
|
|
6
|
+
tagName: 'my-with-assignment',
|
|
7
|
+
render() {
|
|
8
|
+
return html`
|
|
9
|
+
<h1>My App</h1>
|
|
10
|
+
<${MyWithInputs.assign({
|
|
11
|
+
email: 'user@example.com',
|
|
12
|
+
username: 'user',
|
|
13
|
+
})}></${MyWithInputs}>
|
|
14
|
+
`;
|
|
15
|
+
},
|
|
16
|
+
});
|
|
@@ -1,46 +1,54 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {asyncProp, defineElement, html, listen, renderAsync} from '../index.js';
|
|
2
|
+
|
|
3
|
+
type EndpointData = number[];
|
|
4
|
+
|
|
5
|
+
async function loadSomething(endpoint: string): Promise<EndpointData> {
|
|
3
6
|
// load something from the network
|
|
4
|
-
const data = await (
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const data = await (
|
|
8
|
+
await fetch(
|
|
9
|
+
[
|
|
10
|
+
'',
|
|
11
|
+
'api',
|
|
12
|
+
endpoint,
|
|
13
|
+
].join('/'),
|
|
14
|
+
)
|
|
15
|
+
).json();
|
|
9
16
|
return data;
|
|
10
17
|
}
|
|
11
|
-
|
|
18
|
+
|
|
19
|
+
export const MyWithAsyncProp = defineElement<{endpoint: string}>()({
|
|
12
20
|
tagName: 'my-with-async-prop',
|
|
13
21
|
state() {
|
|
14
22
|
return {
|
|
15
23
|
data: asyncProp({
|
|
16
|
-
async updateCallback({ endpoint }) {
|
|
24
|
+
async updateCallback({endpoint}: {endpoint: string}) {
|
|
17
25
|
return loadSomething(endpoint);
|
|
18
26
|
},
|
|
19
27
|
}),
|
|
20
28
|
hi: '',
|
|
21
29
|
};
|
|
22
30
|
},
|
|
23
|
-
render({
|
|
31
|
+
render({inputs, state}) {
|
|
24
32
|
/**
|
|
25
33
|
* This causes the a promise which automatically updates the state.data prop once the
|
|
26
34
|
* promise resolves. It only creates a new promise if the first input, the trigger, value
|
|
27
35
|
* changes from previous calls.
|
|
28
36
|
*/
|
|
29
37
|
state.data.update(inputs);
|
|
30
|
-
return html
|
|
38
|
+
return html`
|
|
31
39
|
Here's the data:
|
|
32
40
|
<br />
|
|
33
41
|
${renderAsync(state.data, 'Loading...', (loadedData) => {
|
|
34
|
-
|
|
42
|
+
return html`
|
|
35
43
|
Got the data: ${loadedData}
|
|
36
44
|
`;
|
|
37
|
-
|
|
45
|
+
})}
|
|
38
46
|
<br />
|
|
39
47
|
<button
|
|
40
48
|
${listen('click', () => {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
49
|
+
/** You can force asyncProp to update by calling forceUpdate. */
|
|
50
|
+
state.data.forceUpdate(inputs);
|
|
51
|
+
})}
|
|
44
52
|
>
|
|
45
53
|
Refresh
|
|
46
54
|
</button>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {defineElement} from 'element-vir';
|
|
2
|
+
import {html} from '../index.js';
|
|
3
|
+
|
|
3
4
|
export const MyWithAssignmentCleanupCallback = defineElement()({
|
|
4
5
|
tagName: 'my-with-cleanup-callback',
|
|
5
6
|
state() {
|
|
@@ -8,11 +9,11 @@ export const MyWithAssignmentCleanupCallback = defineElement()({
|
|
|
8
9
|
};
|
|
9
10
|
},
|
|
10
11
|
render() {
|
|
11
|
-
return html
|
|
12
|
+
return html`
|
|
12
13
|
<h1>My App</h1>
|
|
13
14
|
`;
|
|
14
15
|
},
|
|
15
|
-
cleanup({
|
|
16
|
+
cleanup({state}) {
|
|
16
17
|
window.clearInterval(state.intervalId);
|
|
17
18
|
},
|
|
18
19
|
});
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import {defineElement} from 'element-vir';
|
|
2
|
+
import {css, html} from '../index.js';
|
|
3
|
+
|
|
3
4
|
export const MyWithCssVars = defineElement()({
|
|
4
5
|
tagName: 'my-with-css-vars',
|
|
5
6
|
cssVars: {
|
|
6
7
|
/** The value assigned here ('blue') becomes the fallback value for this CSS var. */
|
|
7
8
|
'my-with-css-vars-my-var': 'blue',
|
|
8
9
|
},
|
|
9
|
-
styles: ({
|
|
10
|
+
styles: ({cssVars}) => css`
|
|
10
11
|
:host {
|
|
11
12
|
/*
|
|
12
13
|
Set CSS vars (or reference the name directly) via the ".name" property
|
|
@@ -20,6 +21,6 @@ export const MyWithCssVars = defineElement()({
|
|
|
20
21
|
}
|
|
21
22
|
`,
|
|
22
23
|
render() {
|
|
23
|
-
return html
|
|
24
|
+
return html``;
|
|
24
25
|
},
|
|
25
26
|
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {randomInteger} from '@augment-vir/common';
|
|
2
|
+
import {defineElement} from 'element-vir';
|
|
3
|
+
import {html, listen} from '../index.js';
|
|
4
|
+
import {MyCustomActionEvent} from './my-custom-action.event.js';
|
|
5
|
+
|
|
6
|
+
export const MyWithCustomEvents = defineElement()({
|
|
7
|
+
tagName: 'my-with-custom-events',
|
|
8
|
+
render({dispatch}) {
|
|
9
|
+
return html`
|
|
10
|
+
<div
|
|
11
|
+
${listen(MyCustomActionEvent, (event) => {
|
|
12
|
+
console.info(`Got a number! ${event.detail}`);
|
|
13
|
+
})}
|
|
14
|
+
>
|
|
15
|
+
<div
|
|
16
|
+
${listen('click', () => {
|
|
17
|
+
dispatch(new MyCustomActionEvent(randomInteger({min: 0, max: 1_000_000})));
|
|
18
|
+
})}
|
|
19
|
+
></div>
|
|
20
|
+
</div>
|
|
21
|
+
`;
|
|
22
|
+
},
|
|
23
|
+
});
|