element-vir 26.12.0 → 26.12.1

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.
Files changed (189) hide show
  1. package/dist/declarative-element/custom-tag-name.js +1 -0
  2. package/dist/declarative-element/declarative-element-init.d.ts +56 -0
  3. package/dist/declarative-element/declarative-element-init.js +1 -0
  4. package/dist/declarative-element/declarative-element.d.ts +114 -0
  5. package/dist/declarative-element/declarative-element.js +36 -0
  6. package/dist/declarative-element/define-element.d.ts +41 -0
  7. package/dist/declarative-element/define-element.js +248 -0
  8. package/{src/declarative-element/definition-options.ts → dist/declarative-element/definition-options.d.ts} +2 -7
  9. package/dist/declarative-element/definition-options.js +9 -0
  10. package/dist/declarative-element/directives/assign.directive.d.ts +24 -0
  11. package/dist/declarative-element/directives/assign.directive.js +34 -0
  12. package/dist/declarative-element/directives/async-prop.d.ts +61 -0
  13. package/{src/declarative-element/directives/async-prop.ts → dist/declarative-element/directives/async-prop.js} +8 -42
  14. package/dist/declarative-element/directives/attributes.directive.d.ts +30 -0
  15. package/dist/declarative-element/directives/attributes.directive.js +35 -0
  16. package/dist/declarative-element/directives/create-attribute-directive.d.ts +28 -0
  17. package/dist/declarative-element/directives/create-attribute-directive.js +41 -0
  18. package/dist/declarative-element/directives/directive-helpers.d.ts +27 -0
  19. package/dist/declarative-element/directives/directive-helpers.js +37 -0
  20. package/dist/declarative-element/directives/listen-to-activate.d.ts +15 -0
  21. package/{src/declarative-element/directives/listen-to-activate.ts → dist/declarative-element/directives/listen-to-activate.js} +3 -8
  22. package/dist/declarative-element/directives/listen.directive.d.ts +92 -0
  23. package/dist/declarative-element/directives/listen.directive.js +48 -0
  24. package/dist/declarative-element/directives/mutate.directive.d.ts +38 -0
  25. package/dist/declarative-element/directives/mutate.directive.js +45 -0
  26. package/dist/declarative-element/directives/on-dom-created.directive.d.ts +44 -0
  27. package/dist/declarative-element/directives/on-dom-created.directive.js +51 -0
  28. package/dist/declarative-element/directives/on-dom-rendered.directive.d.ts +41 -0
  29. package/dist/declarative-element/directives/on-dom-rendered.directive.js +45 -0
  30. package/dist/declarative-element/directives/on-intersect.directive.d.ts +64 -0
  31. package/dist/declarative-element/directives/on-intersect.directive.js +89 -0
  32. package/dist/declarative-element/directives/on-resize.directive.d.ts +74 -0
  33. package/dist/declarative-element/directives/on-resize.directive.js +106 -0
  34. package/dist/declarative-element/directives/render-async.directive.d.ts +45 -0
  35. package/dist/declarative-element/directives/render-async.directive.js +33 -0
  36. package/dist/declarative-element/directives/render-if.directive.d.ts +32 -0
  37. package/{src/declarative-element/directives/render-if.directive.ts → dist/declarative-element/directives/render-if.directive.js} +3 -12
  38. package/dist/declarative-element/directives/test-id.directive.d.ts +52 -0
  39. package/{src/declarative-element/directives/test-id.directive.ts → dist/declarative-element/directives/test-id.directive.js} +2 -7
  40. package/dist/declarative-element/has-declarative-element-parent.d.ts +1 -0
  41. package/{src/declarative-element/has-declarative-element-parent.ts → dist/declarative-element/has-declarative-element-parent.js} +4 -7
  42. package/dist/declarative-element/is-declarative-element-definition.d.ts +17 -0
  43. package/{src/declarative-element/is-declarative-element-definition.ts → dist/declarative-element/is-declarative-element-definition.js} +11 -28
  44. package/dist/declarative-element/is-declarative-element.d.ts +15 -0
  45. package/{src/declarative-element/is-declarative-element.ts → dist/declarative-element/is-declarative-element.js} +5 -11
  46. package/dist/declarative-element/properties/assign-inputs.d.ts +1 -0
  47. package/dist/declarative-element/properties/assign-inputs.js +25 -0
  48. package/dist/declarative-element/properties/css-vars.d.ts +16 -0
  49. package/dist/declarative-element/properties/css-vars.js +1 -0
  50. package/dist/declarative-element/properties/element-events.d.ts +65 -0
  51. package/dist/declarative-element/properties/element-events.js +62 -0
  52. package/dist/declarative-element/properties/element-properties.js +1 -0
  53. package/dist/declarative-element/properties/host-classes.d.ts +36 -0
  54. package/dist/declarative-element/properties/host-classes.js +16 -0
  55. package/dist/declarative-element/properties/property-proxy.d.ts +22 -0
  56. package/{src/declarative-element/properties/property-proxy.ts → dist/declarative-element/properties/property-proxy.js} +21 -58
  57. package/dist/declarative-element/properties/string-names.d.ts +28 -0
  58. package/dist/declarative-element/properties/string-names.js +40 -0
  59. package/dist/declarative-element/properties/styles.d.ts +51 -0
  60. package/dist/declarative-element/properties/styles.js +41 -0
  61. package/dist/declarative-element/properties/tag-name.js +1 -0
  62. package/dist/declarative-element/render-callback.d.ts +56 -0
  63. package/dist/declarative-element/render-callback.js +27 -0
  64. package/dist/declarative-element/wrap-define-element.d.ts +36 -0
  65. package/dist/declarative-element/wrap-define-element.js +25 -0
  66. package/{src/index.ts → dist/index.d.ts} +0 -1
  67. package/dist/index.js +43 -0
  68. package/dist/lit-exports/all-lit-exports.js +2 -0
  69. package/{src/lit-exports/base-lit-exports.ts → dist/lit-exports/base-lit-exports.d.ts} +2 -10
  70. package/dist/lit-exports/base-lit-exports.js +24 -0
  71. package/{src/lit-exports/lit-repeat-fix.ts → dist/lit-exports/lit-repeat-fix.d.ts} +16 -45
  72. package/dist/lit-exports/lit-repeat-fix.js +37 -0
  73. package/dist/readme-examples/my-app.element.d.ts +1 -0
  74. package/{src/readme-examples/my-app.element.ts → dist/readme-examples/my-app.element.js} +4 -5
  75. package/dist/readme-examples/my-custom-action.event.d.ts +1 -0
  76. package/dist/readme-examples/my-custom-action.event.js +2 -0
  77. package/dist/readme-examples/my-custom-define.d.ts +4 -0
  78. package/{src/readme-examples/my-custom-define.ts → dist/readme-examples/my-custom-define.js} +4 -9
  79. package/dist/readme-examples/my-simple.element.d.ts +1 -0
  80. package/{src/readme-examples/my-simple.element.ts → dist/readme-examples/my-simple.element.js} +3 -4
  81. package/dist/readme-examples/my-with-assignment.element.d.ts +1 -0
  82. package/dist/readme-examples/my-with-assignment.element.js +15 -0
  83. package/dist/readme-examples/my-with-async-prop.element.d.ts +10 -0
  84. package/{src/readme-examples/my-with-async-prop.element.ts → dist/readme-examples/my-with-async-prop.element.js} +16 -24
  85. package/dist/readme-examples/my-with-cleanup-callback.element.d.ts +3 -0
  86. package/{src/readme-examples/my-with-cleanup-callback.element.ts → dist/readme-examples/my-with-cleanup-callback.element.js} +4 -5
  87. package/dist/readme-examples/my-with-css-vars.element.d.ts +1 -0
  88. package/{src/readme-examples/my-with-css-vars.element.ts → dist/readme-examples/my-with-css-vars.element.js} +4 -5
  89. package/dist/readme-examples/my-with-custom-events.element.d.ts +1 -0
  90. package/dist/readme-examples/my-with-custom-events.element.js +22 -0
  91. package/dist/readme-examples/my-with-event-listening.element.d.ts +3 -0
  92. package/{src/readme-examples/my-with-event-listening.element.ts → dist/readme-examples/my-with-event-listening.element.js} +9 -10
  93. package/dist/readme-examples/my-with-events.element.d.ts +4 -0
  94. package/dist/readme-examples/my-with-events.element.js +20 -0
  95. package/dist/readme-examples/my-with-host-class-definition.element.d.ts +3 -0
  96. package/{src/readme-examples/my-with-host-class-definition.element.ts → dist/readme-examples/my-with-host-class-definition.element.js} +6 -7
  97. package/dist/readme-examples/my-with-host-class-usage.element.d.ts +1 -0
  98. package/{src/readme-examples/my-with-host-class-usage.element.ts → dist/readme-examples/my-with-host-class-usage.element.js} +4 -5
  99. package/dist/readme-examples/my-with-inputs.element.d.ts +4 -0
  100. package/dist/readme-examples/my-with-inputs.element.js +9 -0
  101. package/dist/readme-examples/my-with-on-dom-created.element.d.ts +1 -0
  102. package/{src/readme-examples/my-with-on-dom-created.element.ts → dist/readme-examples/my-with-on-dom-created.element.js} +6 -7
  103. package/dist/readme-examples/my-with-on-resize.element.d.ts +1 -0
  104. package/dist/readme-examples/my-with-on-resize.element.js +18 -0
  105. package/dist/readme-examples/my-with-render-if.element.d.ts +3 -0
  106. package/dist/readme-examples/my-with-render-if.element.js +11 -0
  107. package/dist/readme-examples/my-with-styles-and-interpolated-selector.element.d.ts +1 -0
  108. package/{src/readme-examples/my-with-styles-and-interpolated-selector.element.ts → dist/readme-examples/my-with-styles-and-interpolated-selector.element.js} +5 -6
  109. package/dist/readme-examples/my-with-styles.element.d.ts +1 -0
  110. package/{src/readme-examples/my-with-styles.element.ts → dist/readme-examples/my-with-styles.element.js} +4 -5
  111. package/dist/readme-examples/my-with-update-state.element.d.ts +8 -0
  112. package/{src/readme-examples/my-with-update-state.element.ts → dist/readme-examples/my-with-update-state.element.js} +7 -8
  113. package/dist/readme-examples/require-declarative-element.d.ts +1 -0
  114. package/dist/readme-examples/require-declarative-element.js +2 -0
  115. package/dist/require-declarative-element.d.ts +14 -0
  116. package/{src/require-declarative-element.ts → dist/require-declarative-element.js} +0 -1
  117. package/{src/template-transforms/minimal-element-definition.ts → dist/template-transforms/minimal-element-definition.d.ts} +7 -19
  118. package/dist/template-transforms/minimal-element-definition.js +19 -0
  119. package/dist/template-transforms/nested-mapped-templates.d.ts +6 -0
  120. package/dist/template-transforms/nested-mapped-templates.js +96 -0
  121. package/{src/template-transforms/template-transform-type.ts → dist/template-transforms/template-transform-type.d.ts} +1 -3
  122. package/dist/template-transforms/template-transform-type.js +1 -0
  123. package/dist/template-transforms/transform-template.d.ts +14 -0
  124. package/{src/template-transforms/transform-template.ts → dist/template-transforms/transform-template.js} +22 -70
  125. package/dist/template-transforms/vir-css/css-transform.d.ts +4 -0
  126. package/dist/template-transforms/vir-css/css-transform.js +15 -0
  127. package/dist/template-transforms/vir-css/vir-css.d.ts +12 -0
  128. package/dist/template-transforms/vir-css/vir-css.js +21 -0
  129. package/dist/template-transforms/vir-html/html-interpolation.d.ts +42 -0
  130. package/dist/template-transforms/vir-html/html-interpolation.js +1 -0
  131. package/dist/template-transforms/vir-html/html-transform.d.ts +5 -0
  132. package/dist/template-transforms/vir-html/html-transform.js +96 -0
  133. package/dist/template-transforms/vir-html/tag-name-keys.d.ts +7 -0
  134. package/{src/template-transforms/vir-html/tag-name-keys.ts → dist/template-transforms/vir-html/tag-name-keys.js} +1 -1
  135. package/dist/template-transforms/vir-html/vir-html.d.ts +11 -0
  136. package/{src/template-transforms/vir-html/vir-html.ts → dist/template-transforms/vir-html/vir-html.js} +5 -13
  137. package/dist/typed-event/typed-event.d.ts +55 -0
  138. package/dist/typed-event/typed-event.js +50 -0
  139. package/dist/util/array.d.ts +5 -0
  140. package/{src/util/array.ts → dist/util/array.js} +5 -18
  141. package/{src/util/increment.ts → dist/util/increment.d.ts} +5 -24
  142. package/dist/util/increment.js +1 -0
  143. package/dist/util/lit-template.d.ts +9 -0
  144. package/{src/util/lit-template.ts → dist/util/lit-template.js} +10 -30
  145. package/dist/util/map-async-value.d.ts +7 -0
  146. package/{src/util/map-async-value.ts → dist/util/map-async-value.js} +10 -12
  147. package/dist/util/type.js +1 -0
  148. package/package.json +4 -4
  149. package/src/declarative-element/declarative-element-init.ts +0 -115
  150. package/src/declarative-element/declarative-element.ts +0 -372
  151. package/src/declarative-element/define-element.ts +0 -515
  152. package/src/declarative-element/directives/assign.directive.ts +0 -89
  153. package/src/declarative-element/directives/attributes.directive.ts +0 -63
  154. package/src/declarative-element/directives/create-attribute-directive.ts +0 -47
  155. package/src/declarative-element/directives/directive-helpers.ts +0 -67
  156. package/src/declarative-element/directives/listen.directive.ts +0 -206
  157. package/src/declarative-element/directives/mutate.directive.ts +0 -78
  158. package/src/declarative-element/directives/on-dom-created.directive.ts +0 -68
  159. package/src/declarative-element/directives/on-dom-rendered.directive.ts +0 -61
  160. package/src/declarative-element/directives/on-intersect.directive.ts +0 -139
  161. package/src/declarative-element/directives/on-resize.directive.ts +0 -142
  162. package/src/declarative-element/directives/render-async.directive.ts +0 -111
  163. package/src/declarative-element/properties/assign-inputs.ts +0 -30
  164. package/src/declarative-element/properties/css-vars.ts +0 -24
  165. package/src/declarative-element/properties/element-events.ts +0 -161
  166. package/src/declarative-element/properties/host-classes.ts +0 -63
  167. package/src/declarative-element/properties/string-names.ts +0 -83
  168. package/src/declarative-element/properties/styles.ts +0 -112
  169. package/src/declarative-element/render-callback.ts +0 -196
  170. package/src/declarative-element/wrap-define-element.ts +0 -127
  171. package/src/readme-examples/my-custom-action.event.ts +0 -3
  172. package/src/readme-examples/my-with-assignment.element.ts +0 -16
  173. package/src/readme-examples/my-with-custom-events.element.ts +0 -23
  174. package/src/readme-examples/my-with-events.element.ts +0 -23
  175. package/src/readme-examples/my-with-inputs.element.ts +0 -13
  176. package/src/readme-examples/my-with-on-resize.element.ts +0 -19
  177. package/src/readme-examples/my-with-render-if.element.ts +0 -15
  178. package/src/readme-examples/require-declarative-element.ts +0 -3
  179. package/src/template-transforms/nested-mapped-templates.ts +0 -157
  180. package/src/template-transforms/vir-css/css-transform.ts +0 -30
  181. package/src/template-transforms/vir-css/vir-css.ts +0 -30
  182. package/src/template-transforms/vir-html/html-interpolation.ts +0 -103
  183. package/src/template-transforms/vir-html/html-transform.ts +0 -149
  184. package/src/typed-event/typed-event.ts +0 -90
  185. /package/{src/declarative-element/custom-tag-name.ts → dist/declarative-element/custom-tag-name.d.ts} +0 -0
  186. /package/{src/declarative-element/properties/element-properties.ts → dist/declarative-element/properties/element-properties.d.ts} +0 -0
  187. /package/{src/declarative-element/properties/tag-name.ts → dist/declarative-element/properties/tag-name.d.ts} +0 -0
  188. /package/{src/lit-exports/all-lit-exports.ts → dist/lit-exports/all-lit-exports.d.ts} +0 -0
  189. /package/{src/util/type.ts → dist/util/type.d.ts} +0 -0
@@ -0,0 +1,96 @@
1
+ import { check } from '@augment-vir/assert';
2
+ import { filterMap } from '@augment-vir/common';
3
+ import { hasTagName, isMinimalDefinitionWithInputs } from './minimal-element-definition.js';
4
+ function extractElementKeys(values) {
5
+ return filterMap(values, (value) => {
6
+ if (isMinimalDefinitionWithInputs(value)) {
7
+ return value.definition;
8
+ }
9
+ if (hasTagName(value)) {
10
+ return value.tagInterpolationKey || value;
11
+ }
12
+ return undefined;
13
+ }, check.isTruthy);
14
+ }
15
+ /**
16
+ * The transformed templates are written to a map so that we can preserve reference equality between
17
+ * calls. Without maintaining reference equality between html`` calls, lit-element reconstructs all
18
+ * of its children on every render.
19
+ *
20
+ * This is a WeakMap because we only care about the transformed array value as long as the original
21
+ * template array key exists.
22
+ */
23
+ const transformedTemplateStrings = new WeakMap();
24
+ export function getAlreadyMappedTemplate(templateStringsKey, values) {
25
+ const elementKeys = extractElementKeys(values);
26
+ const nestedValue = getNestedValues(transformedTemplateStrings, [
27
+ templateStringsKey,
28
+ ...elementKeys,
29
+ ]);
30
+ return nestedValue.value?.template;
31
+ }
32
+ export function setMappedTemplate(templateStringsKey, values, valueToSet) {
33
+ const elementKeys = extractElementKeys(values);
34
+ return setNestedValues(transformedTemplateStrings, [
35
+ templateStringsKey,
36
+ ...elementKeys,
37
+ ], valueToSet);
38
+ }
39
+ function getNestedValues(map, keys, index = 0) {
40
+ const { currentTemplateAndNested, reason } = getCurrentKeyAndValue(map, keys, index);
41
+ if (!currentTemplateAndNested) {
42
+ return { value: currentTemplateAndNested, reason };
43
+ }
44
+ if (index === keys.length - 1) {
45
+ return { value: currentTemplateAndNested, reason: `reached end of keys array` };
46
+ }
47
+ if (!currentTemplateAndNested.nested) {
48
+ return { value: undefined, reason: `map at key index ${index} did not have nested maps` };
49
+ }
50
+ return getNestedValues(currentTemplateAndNested.nested, keys, index + 1);
51
+ }
52
+ function getCurrentKeyAndValue(map, keys, index) {
53
+ const currentKey = keys[index];
54
+ if (currentKey == undefined) {
55
+ return {
56
+ currentKey: undefined,
57
+ currentTemplateAndNested: undefined,
58
+ reason: `key at index ${index} not found`,
59
+ };
60
+ }
61
+ if (!map.has(currentKey)) {
62
+ return {
63
+ currentKey,
64
+ currentTemplateAndNested: undefined,
65
+ reason: `key at index ${index} was not in the map`,
66
+ };
67
+ }
68
+ const currentTemplateAndNested = map.get(currentKey);
69
+ if (currentTemplateAndNested == undefined) {
70
+ return {
71
+ currentKey,
72
+ currentTemplateAndNested: undefined,
73
+ reason: `value at key at index ${index} was undefined`,
74
+ };
75
+ }
76
+ return { currentKey, currentTemplateAndNested, reason: `key and value exists` };
77
+ }
78
+ function setNestedValues(map, keys, valueToSet, index = 0) {
79
+ const { currentTemplateAndNested, currentKey, reason } = getCurrentKeyAndValue(map, keys, index);
80
+ if (!currentKey) {
81
+ return { result: false, reason };
82
+ }
83
+ const nestedAndTemplate = currentTemplateAndNested ?? { nested: undefined, template: undefined };
84
+ if (!currentTemplateAndNested) {
85
+ map.set(currentKey, nestedAndTemplate);
86
+ }
87
+ if (index === keys.length - 1) {
88
+ nestedAndTemplate.template = valueToSet;
89
+ return { result: true, reason: `set value at end of keys array` };
90
+ }
91
+ const nestedWeakMap = nestedAndTemplate.nested ?? new WeakMap();
92
+ if (!nestedAndTemplate.nested) {
93
+ nestedAndTemplate.nested = nestedWeakMap;
94
+ }
95
+ return setNestedValues(nestedWeakMap, keys, valueToSet, index + 1);
96
+ }
@@ -1,10 +1,8 @@
1
- import {type ArrayInsertion} from '../util/array.js';
2
-
1
+ import { type ArrayInsertion } from '../util/array.js';
3
2
  export type AllValueTransforms = {
4
3
  valueIndexDeletions: number[];
5
4
  valueInsertions: ArrayInsertion<unknown>[];
6
5
  };
7
-
8
6
  export type TemplateTransform = {
9
7
  templateStrings: TemplateStringsArray;
10
8
  valuesTransform(values: unknown[]): AllValueTransforms;
@@ -0,0 +1,14 @@
1
+ import { type TemplateTransform } from './template-transform-type.js';
2
+ export type ValueInsertion = {
3
+ index: number;
4
+ value: unknown;
5
+ };
6
+ export type ValueTransformCallback = (lastNewString: string, currentLitString: string, currentValue: unknown) => {
7
+ replacement: unknown;
8
+ getExtraValues: ((currentValue: unknown) => unknown[]) | undefined;
9
+ } | undefined;
10
+ export declare function getTransformedTemplate<PossibleValues>(templateStringsKey: TemplateStringsArray, values: PossibleValues[], fallbackTransform: () => TemplateTransform): {
11
+ strings: TemplateStringsArray;
12
+ values: PossibleValues[];
13
+ };
14
+ export declare function transformTemplate<PossibleValues>(inputTemplateStrings: TemplateStringsArray, inputValues: PossibleValues[], transformValue: ValueTransformCallback, assertValidString?: (templateStringPart: string) => void): TemplateTransform;
@@ -1,78 +1,36 @@
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
- ) {
1
+ import { insertAndRemoveValues } from '../util/array.js';
2
+ import { getAlreadyMappedTemplate, setMappedTemplate } from './nested-mapped-templates.js';
3
+ export function getTransformedTemplate(templateStringsKey, values, fallbackTransform) {
26
4
  const alreadyTransformedTemplateStrings = getAlreadyMappedTemplate(templateStringsKey, values);
27
-
28
- const templateTransform: TemplateTransform =
29
- alreadyTransformedTemplateStrings ?? fallbackTransform();
30
-
5
+ const templateTransform = alreadyTransformedTemplateStrings ?? fallbackTransform();
31
6
  if (!alreadyTransformedTemplateStrings) {
32
7
  const result = setMappedTemplate(templateStringsKey, values, templateTransform);
33
8
  if (!result.result) {
34
9
  throw new Error(`Failed to set template transform: ${result.reason}`);
35
10
  }
36
11
  }
37
-
38
12
  const valueTransforms = templateTransform.valuesTransform(values);
39
-
40
- const transformedValuesArray: PossibleValues[] = insertAndRemoveValues(
41
- values,
42
- valueTransforms.valueInsertions,
43
- valueTransforms.valueIndexDeletions,
44
- ) as PossibleValues[];
45
-
13
+ const transformedValuesArray = insertAndRemoveValues(values, valueTransforms.valueInsertions, valueTransforms.valueIndexDeletions);
46
14
  return {
47
15
  strings: templateTransform.templateStrings,
48
16
  values: transformedValuesArray,
49
17
  };
50
18
  }
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
-
19
+ export function transformTemplate(inputTemplateStrings, inputValues, transformValue, assertValidString) {
20
+ const newStrings = [];
21
+ const newRaws = [];
22
+ const valueIndexDeletions = [];
23
+ const valueTransforms = [];
63
24
  inputTemplateStrings.forEach((currentTemplateString, currentTemplateStringIndex) => {
64
25
  const lastNewStringsIndex = newStrings.length - 1;
65
26
  const lastNewString = newStrings[lastNewStringsIndex];
66
27
  const currentValueIndex = currentTemplateStringIndex - 1;
67
28
  const currentValue = inputValues[currentValueIndex];
68
-
69
29
  if (assertValidString) {
70
30
  assertValidString(currentTemplateString);
71
31
  }
72
-
73
- let transformOutput: ReturnType<ValueTransformCallback> | undefined = undefined;
74
- let extraValues: unknown[] = [];
75
-
32
+ let transformOutput = undefined;
33
+ let extraValues = [];
76
34
  if (typeof lastNewString === 'string') {
77
35
  transformOutput = transformValue(lastNewString, currentTemplateString, currentValue);
78
36
  if (transformOutput) {
@@ -83,7 +41,6 @@ export function transformTemplate<PossibleValues>(
83
41
  valueIndexDeletions.push(currentValueIndex);
84
42
  const getExtraValuesCallback = transformOutput.getExtraValues;
85
43
  extraValues = getExtraValuesCallback ? getExtraValuesCallback(currentValue) : [];
86
-
87
44
  if (extraValues.length && getExtraValuesCallback) {
88
45
  newStrings[lastNewStringsIndex] += ' ';
89
46
  extraValues.forEach((value, index) => {
@@ -92,7 +49,7 @@ export function transformTemplate<PossibleValues>(
92
49
  newStrings.push(' ');
93
50
  }
94
51
  });
95
- valueTransforms.push((values): ArrayInsertion<unknown> => {
52
+ valueTransforms.push((values) => {
96
53
  const latestCurrentValue = values[currentValueIndex];
97
54
  const insertions = getExtraValuesCallback(latestCurrentValue);
98
55
  return {
@@ -101,22 +58,21 @@ export function transformTemplate<PossibleValues>(
101
58
  };
102
59
  });
103
60
  newStrings.push(currentTemplateString);
104
- } else {
61
+ }
62
+ else {
105
63
  newStrings[lastNewStringsIndex] += currentTemplateString;
106
64
  }
107
65
  }
108
66
  }
109
-
110
67
  if (!transformOutput) {
111
68
  newStrings.push(currentTemplateString);
112
69
  }
113
-
114
70
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
115
- const currentRawLitString = inputTemplateStrings.raw[currentTemplateStringIndex]!;
71
+ const currentRawLitString = inputTemplateStrings.raw[currentTemplateStringIndex];
116
72
  if (transformOutput) {
117
73
  newRaws[lastNewStringsIndex] = [
118
74
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
119
- newRaws[lastNewStringsIndex]!,
75
+ newRaws[lastNewStringsIndex],
120
76
  transformOutput.replacement,
121
77
  currentRawLitString,
122
78
  ].join('');
@@ -125,22 +81,18 @@ export function transformTemplate<PossibleValues>(
125
81
  newRaws.push('');
126
82
  });
127
83
  }
128
- } else {
84
+ }
85
+ else {
129
86
  newRaws.push(currentRawLitString);
130
87
  }
131
88
  });
132
-
133
- const newTemplateStrings: TemplateStringsArray = Object.assign([], newStrings, {
89
+ const newTemplateStrings = Object.assign([], newStrings, {
134
90
  raw: newRaws,
135
91
  });
136
-
137
92
  return {
138
93
  templateStrings: newTemplateStrings,
139
- valuesTransform(values): AllValueTransforms {
140
- const insertions: ArrayInsertion<unknown>[] = valueTransforms.flatMap(
141
- (transformCallback) => transformCallback(values),
142
- );
143
-
94
+ valuesTransform(values) {
95
+ const insertions = valueTransforms.flatMap((transformCallback) => transformCallback(values));
144
96
  return {
145
97
  valueIndexDeletions,
146
98
  valueInsertions: insertions,
@@ -0,0 +1,4 @@
1
+ import { type CSSResultGroup } from '../../lit-exports/all-lit-exports.js';
2
+ import { type MinimalElementDefinition } from '../minimal-element-definition.js';
3
+ import { type TemplateTransform } from '../template-transform-type.js';
4
+ export declare function transformCssTemplate(inputTemplateStrings: TemplateStringsArray, inputValues: (number | CSSResultGroup | MinimalElementDefinition)[]): TemplateTransform;
@@ -0,0 +1,15 @@
1
+ /* eslint-disable @typescript-eslint/no-unused-vars */
2
+ import { hasTagName } from '../minimal-element-definition.js';
3
+ import { transformTemplate } from '../transform-template.js';
4
+ function transformCss(...[lastNewString, currentLitString, currentValue,]) {
5
+ if (!hasTagName(currentValue)) {
6
+ return undefined;
7
+ }
8
+ return {
9
+ replacement: currentValue.tagName,
10
+ getExtraValues: undefined,
11
+ };
12
+ }
13
+ export function transformCssTemplate(inputTemplateStrings, inputValues) {
14
+ return transformTemplate(inputTemplateStrings, inputValues, transformCss);
15
+ }
@@ -0,0 +1,12 @@
1
+ import { type CSSResult, type CSSResultGroup } from '../../lit-exports/all-lit-exports.js';
2
+ import { type MinimalElementDefinition } from '../minimal-element-definition.js';
3
+ /**
4
+ * A template literal tag used to define styles for element definitions. In particular, this is used
5
+ * for the `styles` property in an element definitions init object.
6
+ *
7
+ * For security reasons, only literal string or number values may be interpolated inside of this
8
+ * taggedTemplate. To incorporate non-literal values, wrap the value in a call to `unsafeCSS`.
9
+ *
10
+ * @category Element Definition
11
+ */
12
+ export declare function css(inputTemplateStrings: TemplateStringsArray, ...inputValues: (number | CSSResultGroup | MinimalElementDefinition | CSSResult)[]): CSSResult;
@@ -0,0 +1,21 @@
1
+ import { css as litCss } from 'lit';
2
+ import { getTransformedTemplate } from '../transform-template.js';
3
+ import { transformCssTemplate } from './css-transform.js';
4
+ /**
5
+ * A template literal tag used to define styles for element definitions. In particular, this is used
6
+ * for the `styles` property in an element definitions init object.
7
+ *
8
+ * For security reasons, only literal string or number values may be interpolated inside of this
9
+ * taggedTemplate. To incorporate non-literal values, wrap the value in a call to `unsafeCSS`.
10
+ *
11
+ * @category Element Definition
12
+ */
13
+ export function css(inputTemplateStrings, ...inputValues) {
14
+ const transformedTemplate = getTransformedTemplate(inputTemplateStrings, inputValues, () => {
15
+ return transformCssTemplate(inputTemplateStrings, inputValues);
16
+ });
17
+ const cssResult = litCss(transformedTemplate.strings,
18
+ /** The filter will remove the DeclarativeElement elements */
19
+ ...transformedTemplate.values);
20
+ return cssResult;
21
+ }
@@ -0,0 +1,42 @@
1
+ import { type AnyFunction, type Overwrite } from '@augment-vir/common';
2
+ import { type CSSResult, type TemplateResult, type nothing } from 'lit';
3
+ import { type EmptyObject, type HasRequiredKeys, type IsNever } from 'type-fest';
4
+ import { type DeclarativeElementDefinition } from '../../declarative-element/declarative-element.js';
5
+ import { type Decrement, type Increment } from '../../util/increment.js';
6
+ import { type MinimalDefinitionWithInputs, type MinimalElementDefinition } from '../minimal-element-definition.js';
7
+ /**
8
+ * Unfortunately the type for `DirectiveResult` means it's just an empty object. So in order to
9
+ * block actual objects, we have to narrow `DirectiveResult` further to this empty object type.
10
+ *
11
+ * @category Internal
12
+ */
13
+ export type DirectiveOutput = EmptyObject;
14
+ /**
15
+ * This is used in order to block accidental object interpolations into HTML, which get stringified
16
+ * into `'[object Object]'`, which nobody ever wants that.
17
+ *
18
+ * @category Internal
19
+ */
20
+ export type HtmlInterpolation = null | undefined | string | number | boolean | bigint | CSSResult | Readonly<CSSResult> | Element | Readonly<Element> | TemplateResult | Readonly<TemplateResult> | MinimalElementDefinition | Readonly<MinimalElementDefinition> | MinimalDefinitionWithInputs | Readonly<MinimalDefinitionWithInputs> | DeclarativeElementDefinition | Readonly<DeclarativeElementDefinition> | DirectiveOutput | Readonly<DirectiveOutput> | AnyFunction | typeof nothing | HtmlInterpolation[] | ReadonlyArray<HtmlInterpolation> | Iterable<HtmlInterpolation> | Readonly<Iterable<HtmlInterpolation>>;
21
+ /**
22
+ * This type ensures that interpolated element definitions are not missing their inputs, when inputs
23
+ * are required.
24
+ *
25
+ * @category Internal
26
+ */
27
+ export type VerifyHtmlValues<Values extends HtmlInterpolation[], WaitingForEndTags extends Record<string, number> = {}> = Values extends [
28
+ infer CurrentDefinition extends DeclarativeElementDefinition,
29
+ ...infer Rest extends HtmlInterpolation[]
30
+ ] ? CurrentDefinition extends DeclarativeElementDefinition<infer TagName, infer Inputs> ? HasRequiredKeys<Inputs> extends true ? IsNever<Decrement<WaitingForEndTags[TagName]>> extends true ? [
31
+ `ERROR: This element is missing its inputs.`,
32
+ ...VerifyHtmlValues<Rest, WaitingForEndTags>
33
+ ] : [
34
+ CurrentDefinition,
35
+ ...VerifyHtmlValues<Rest, Overwrite<WaitingForEndTags, Record<TagName, Decrement<WaitingForEndTags[TagName]>>>>
36
+ ] : [CurrentDefinition, ...VerifyHtmlValues<Rest, WaitingForEndTags>] : [CurrentDefinition, ...VerifyHtmlValues<Rest, WaitingForEndTags>] : Values extends [
37
+ infer CurrentDefinition extends MinimalDefinitionWithInputs,
38
+ ...infer Rest extends HtmlInterpolation[]
39
+ ] ? [
40
+ CurrentDefinition,
41
+ ...VerifyHtmlValues<Rest, Overwrite<WaitingForEndTags, Record<CurrentDefinition['definition']['tagName'], Increment<WaitingForEndTags[CurrentDefinition['definition']['tagName']]>>>>
42
+ ] : Values;
@@ -0,0 +1,5 @@
1
+ import { type HTMLTemplateResult } from '../../lit-exports/all-lit-exports.js';
2
+ import { type TemplateTransform } from '../template-transform-type.js';
3
+ import { type HtmlInterpolation } from './html-interpolation.js';
4
+ export declare function mapHtmlValues(inputTemplateStrings: TemplateStringsArray, inputValues: HtmlInterpolation[]): HtmlInterpolation[];
5
+ export declare function transformHtmlTemplate(litTemplate: HTMLTemplateResult): TemplateTransform;
@@ -0,0 +1,96 @@
1
+ /* eslint-disable @typescript-eslint/no-deprecated */
2
+ import { check } from '@augment-vir/assert';
3
+ import { collapseWhiteSpace, getOrSet, safeMatch } from '@augment-vir/common';
4
+ import { assign } from '../../declarative-element/directives/assign.directive.js';
5
+ import { declarativeElementRequired } from '../../require-declarative-element.js';
6
+ import { hasTagName, isMinimalDefinitionWithInputs, } from '../minimal-element-definition.js';
7
+ import { transformTemplate } from '../transform-template.js';
8
+ import { tagNameKeys } from './tag-name-keys.js';
9
+ export function mapHtmlValues(inputTemplateStrings, inputValues) {
10
+ return inputValues.map((currentValue, currentValueIndex) => {
11
+ const lastString = inputTemplateStrings[currentValueIndex];
12
+ const nextString = inputTemplateStrings[currentValueIndex + 1];
13
+ if (lastString && nextString) {
14
+ const { shouldHaveTagNameHere } = classifyValue(lastString, nextString);
15
+ if (shouldHaveTagNameHere && check.isString(currentValue)) {
16
+ const replacement = {
17
+ tagName: currentValue,
18
+ tagInterpolationKey: getOrSet(tagNameKeys, currentValue, () => {
19
+ return { tagName: currentValue };
20
+ }),
21
+ };
22
+ return replacement;
23
+ }
24
+ }
25
+ return currentValue;
26
+ });
27
+ }
28
+ function classifyValue(lastNewString, currentTemplateString) {
29
+ const isOpeningTag = lastNewString.trim().endsWith('<') && !!currentTemplateString.match(/^[\s>]/);
30
+ const isClosingTag = lastNewString.trim().endsWith('</') && currentTemplateString.trim().startsWith('>');
31
+ const shouldHaveTagNameHere = isOpeningTag || isClosingTag;
32
+ return {
33
+ isOpeningTag,
34
+ shouldHaveTagNameHere,
35
+ };
36
+ }
37
+ function transformHtml(...[lastNewString, currentTemplateString, rawCurrentValue,]) {
38
+ const currentValue = isMinimalDefinitionWithInputs(rawCurrentValue)
39
+ ? rawCurrentValue.definition
40
+ : rawCurrentValue;
41
+ const { isOpeningTag, shouldHaveTagNameHere } = classifyValue(lastNewString, currentTemplateString);
42
+ const isTagNameWrapper = hasTagName(currentValue);
43
+ if (isTagNameWrapper && shouldHaveTagNameHere && currentValue.tagInterpolationKey) {
44
+ return {
45
+ replacement: currentValue.tagName,
46
+ getExtraValues: undefined,
47
+ };
48
+ }
49
+ if (shouldHaveTagNameHere && !isTagNameWrapper) {
50
+ console.error({
51
+ lastNewString,
52
+ currentTemplateString,
53
+ currentValue,
54
+ });
55
+ throw new Error(`Got interpolated tag name but found no tag name on the given value: '${currentValue?.tagName ||
56
+ currentValue?.prototype?.constructor?.name ||
57
+ currentValue?.constructor?.name}'`);
58
+ }
59
+ if (!shouldHaveTagNameHere || !isTagNameWrapper) {
60
+ return undefined;
61
+ }
62
+ const replacement = currentValue.tagName;
63
+ return {
64
+ replacement,
65
+ getExtraValues(extraValueCurrentValue) {
66
+ const assignedInputs = isMinimalDefinitionWithInputs(extraValueCurrentValue)
67
+ ? extraValueCurrentValue.inputs
68
+ : undefined;
69
+ return [
70
+ isOpeningTag && assignedInputs ? assign(assignedInputs) : undefined,
71
+ ].filter(check.isTruthy);
72
+ },
73
+ };
74
+ }
75
+ function extractCustomElementTags(input) {
76
+ const tagNameMatches = safeMatch(input, /<\/\s*[^\s><]+\s*>/g);
77
+ return tagNameMatches.reduce((accum, match) => {
78
+ const tagName = collapseWhiteSpace(match.replace(/\n/g, ' ')).replace(/<\/|>/g, '');
79
+ // custom elements always have a dash in them
80
+ if (tagName.includes('-')) {
81
+ return accum.concat(tagName);
82
+ }
83
+ return accum;
84
+ }, []);
85
+ }
86
+ function stringValidator(input) {
87
+ if (declarativeElementRequired) {
88
+ const customElementTagNames = extractCustomElementTags(input);
89
+ if (customElementTagNames.length) {
90
+ console.error(`Custom element tags must be interpolated from declarative elements: ${customElementTagNames.join(', ')}`);
91
+ }
92
+ }
93
+ }
94
+ export function transformHtmlTemplate(litTemplate) {
95
+ return transformTemplate(litTemplate.strings, litTemplate.values, transformHtml, stringValidator);
96
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Used to create objects for each interpolated tag name string (tag names that aren't wrapped in a
3
+ * `DeclarativeElementDefinition`) so that we can use them as keys for the mapped template weakmap.
4
+ */
5
+ export declare const tagNameKeys: Record<string, {
6
+ tagName: string;
7
+ }>;
@@ -2,4 +2,4 @@
2
2
  * Used to create objects for each interpolated tag name string (tag names that aren't wrapped in a
3
3
  * `DeclarativeElementDefinition`) so that we can use them as keys for the mapped template weakmap.
4
4
  */
5
- export const tagNameKeys: Record<string, {tagName: string}> = {};
5
+ export const tagNameKeys = {};
@@ -0,0 +1,11 @@
1
+ import { type HTMLTemplateResult } from '../../lit-exports/all-lit-exports.js';
2
+ import { type HtmlInterpolation, type VerifyHtmlValues } from './html-interpolation.js';
3
+ /**
4
+ * Interprets a template literal as an HTML template which is lazily rendered to the DOM.
5
+ *
6
+ * Wraps lit-html's html tagged template and enables interpolations of
7
+ * `DeclarativeElementDefinition` for tag names.
8
+ *
9
+ * @category Element Definition
10
+ */
11
+ export declare function html<const Values extends HtmlInterpolation[]>(inputTemplateStrings: TemplateStringsArray, ...inputValues: VerifyHtmlValues<Values>): HTMLTemplateResult;
@@ -1,9 +1,6 @@
1
- import {html as litHtml} from 'lit';
2
- import {type HTMLTemplateResult} from '../../lit-exports/all-lit-exports.js';
3
- import {getTransformedTemplate} from '../transform-template.js';
4
- import {type HtmlInterpolation, type VerifyHtmlValues} from './html-interpolation.js';
5
- import {mapHtmlValues, transformHtmlTemplate} from './html-transform.js';
6
-
1
+ import { html as litHtml } from 'lit';
2
+ import { getTransformedTemplate } from '../transform-template.js';
3
+ import { mapHtmlValues, transformHtmlTemplate } from './html-transform.js';
7
4
  /**
8
5
  * Interprets a template literal as an HTML template which is lazily rendered to the DOM.
9
6
  *
@@ -12,18 +9,13 @@ import {mapHtmlValues, transformHtmlTemplate} from './html-transform.js';
12
9
  *
13
10
  * @category Element Definition
14
11
  */
15
- export function html<const Values extends HtmlInterpolation[]>(
16
- inputTemplateStrings: TemplateStringsArray,
17
- ...inputValues: VerifyHtmlValues<Values>
18
- ): HTMLTemplateResult {
12
+ export function html(inputTemplateStrings, ...inputValues) {
19
13
  const mappedValues = mapHtmlValues(inputTemplateStrings, inputValues);
20
-
21
14
  const litTemplate = litHtml(inputTemplateStrings, ...mappedValues);
22
15
  const transformedTemplate = getTransformedTemplate(inputTemplateStrings, mappedValues, () => {
23
16
  return transformHtmlTemplate(litTemplate);
24
17
  });
25
-
26
- const htmlTemplate: HTMLTemplateResult = {
18
+ const htmlTemplate = {
27
19
  ...litTemplate,
28
20
  strings: transformedTemplate.strings,
29
21
  values: transformedTemplate.values,
@@ -0,0 +1,55 @@
1
+ import { type NonEmptyString } from '../util/type.js';
2
+ /**
3
+ * A custom event with strict types for details and the event's `type` property.
4
+ *
5
+ * @category Internal
6
+ */
7
+ export declare class TypedEvent<EventTypeNameGeneric extends string = '', EventDetailGeneric = undefined> extends CustomEvent<EventDetailGeneric> {
8
+ readonly _type: EventTypeNameGeneric;
9
+ get type(): EventTypeNameGeneric;
10
+ constructor(type: EventTypeNameGeneric | {
11
+ type: EventTypeNameGeneric;
12
+ }, value: EventDetailGeneric);
13
+ }
14
+ /**
15
+ * A function that defines a typed event, used for defining element events in an element's
16
+ * definition.
17
+ *
18
+ * @category Internal
19
+ */
20
+ export type DefineEvent<EventDetailGeneric> = <EventTypeNameGeneric extends string>(eventType: NonEmptyString<EventTypeNameGeneric>) => DefinedTypedEvent<EventTypeNameGeneric, EventDetailGeneric>;
21
+ /**
22
+ * A concrete typed event definition.
23
+ *
24
+ * @category Internal
25
+ */
26
+ export type DefinedTypedEvent<EventTypeNameGeneric extends string, EventDetailGeneric> = (new (eventValue: EventDetailGeneric) => TypedEvent<EventTypeNameGeneric, EventDetailGeneric>) & {
27
+ type: EventTypeNameGeneric;
28
+ };
29
+ /**
30
+ * Define a stand-alone typed event that can be emitted and listened to inside of HTML templates.
31
+ *
32
+ * Make sure to use currying and call this function twice! (This is required by TypeScript's type
33
+ * parameter inference system.)
34
+ *
35
+ * @category Element Definition
36
+ * @example
37
+ *
38
+ * ```ts
39
+ * import {defineTypedEvent} from 'element-vir';
40
+ *
41
+ * const myCustomEvent = defineTypedEvent<number>()('my-custom-event');
42
+ *
43
+ * const myCustomEvent2 = defineTypedEvent<// the event's `.detail` type
44
+ * number>()(
45
+ * // the event's `.type` string
46
+ * 'my-custom-event2',
47
+ * );
48
+ * ```
49
+ */
50
+ export declare function defineTypedEvent<EventDetailGeneric>(): <
51
+ /**
52
+ * EventTypeNameGeneric is used for the event type property but not for the event value
53
+ * type... so it's named "name" instead of "type" cause type is overloaded here.
54
+ */
55
+ EventTypeNameGeneric extends string>(eventType: NonEmptyString<EventTypeNameGeneric>) => DefinedTypedEvent<EventTypeNameGeneric, EventDetailGeneric>;