element-vir 22.2.1 → 23.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/README.md +42 -36
  2. package/dist/declarative-element/custom-tag-name.d.ts +6 -0
  3. package/dist/declarative-element/declarative-element-init.d.ts +20 -14
  4. package/dist/declarative-element/declarative-element.d.ts +70 -24
  5. package/dist/declarative-element/declarative-element.js +34 -1
  6. package/dist/declarative-element/define-element-no-inputs.d.ts +31 -6
  7. package/dist/declarative-element/define-element-no-inputs.js +154 -257
  8. package/dist/declarative-element/define-element.d.ts +35 -7
  9. package/dist/declarative-element/define-element.js +26 -4
  10. package/dist/declarative-element/definition-options.d.ts +10 -0
  11. package/dist/declarative-element/definition-options.js +5 -0
  12. package/dist/declarative-element/directives/assign.directive.d.ts +8 -11
  13. package/dist/declarative-element/directives/assign.directive.js +6 -13
  14. package/dist/declarative-element/directives/async-prop.d.ts +19 -4
  15. package/dist/declarative-element/directives/async-prop.js +15 -4
  16. package/dist/declarative-element/directives/create-attribute-directive.d.ts +19 -4
  17. package/dist/declarative-element/directives/create-attribute-directive.js +18 -8
  18. package/dist/declarative-element/directives/directive-helpers.d.ts +19 -4
  19. package/dist/declarative-element/directives/directive-helpers.js +14 -2
  20. package/dist/declarative-element/directives/is-resolved.directive.d.ts +107 -1
  21. package/dist/declarative-element/directives/is-resolved.directive.js +107 -1
  22. package/dist/declarative-element/directives/listen.directive.d.ts +84 -10
  23. package/dist/declarative-element/directives/listen.directive.js +5 -15
  24. package/dist/declarative-element/directives/on-dom-created.directive.d.ts +37 -4
  25. package/dist/declarative-element/directives/on-dom-created.directive.js +32 -12
  26. package/dist/declarative-element/directives/on-dom-rendered.directive.d.ts +33 -3
  27. package/dist/declarative-element/directives/on-dom-rendered.directive.js +29 -6
  28. package/dist/declarative-element/directives/on-resize.directive.d.ts +37 -4
  29. package/dist/declarative-element/directives/on-resize.directive.js +37 -24
  30. package/dist/declarative-element/directives/render-async.directive.d.ts +44 -4
  31. package/dist/declarative-element/directives/render-async.directive.js +13 -3
  32. package/dist/declarative-element/directives/render-if.directive.d.ts +31 -0
  33. package/dist/declarative-element/directives/render-if.directive.js +32 -1
  34. package/dist/declarative-element/directives/test-id.directive.d.ts +48 -4
  35. package/dist/declarative-element/directives/test-id.directive.js +47 -2
  36. package/dist/declarative-element/has-declarative-element-parent.js +1 -1
  37. package/dist/declarative-element/is-declarative-element-definition.d.ts +15 -1
  38. package/dist/declarative-element/is-declarative-element-definition.js +21 -18
  39. package/dist/declarative-element/is-declarative-element.d.ts +5 -1
  40. package/dist/declarative-element/is-declarative-element.js +7 -3
  41. package/dist/declarative-element/properties/assign-inputs.js +1 -1
  42. package/dist/declarative-element/properties/css-properties.d.ts +11 -1
  43. package/dist/declarative-element/properties/css-properties.js +5 -0
  44. package/dist/declarative-element/properties/css-vars.d.ts +14 -4
  45. package/dist/declarative-element/properties/element-events.d.ts +61 -7
  46. package/dist/declarative-element/properties/element-events.js +40 -5
  47. package/dist/declarative-element/properties/element-properties.d.ts +15 -6
  48. package/dist/declarative-element/properties/element-properties.js +1 -21
  49. package/dist/declarative-element/properties/element-vir-state-setup.d.ts +43 -3
  50. package/dist/declarative-element/properties/element-vir-state-setup.js +17 -3
  51. package/dist/declarative-element/properties/host-classes.d.ts +25 -12
  52. package/dist/declarative-element/properties/host-classes.js +5 -0
  53. package/dist/declarative-element/properties/per-instance.d.ts +23 -2
  54. package/dist/declarative-element/properties/per-instance.js +24 -3
  55. package/dist/declarative-element/properties/property-proxy.d.ts +19 -4
  56. package/dist/declarative-element/properties/property-proxy.js +15 -4
  57. package/dist/declarative-element/properties/styles.d.ts +33 -8
  58. package/dist/declarative-element/properties/styles.js +12 -2
  59. package/dist/declarative-element/properties/tag-name.d.ts +5 -0
  60. package/dist/declarative-element/render-callback.d.ts +38 -11
  61. package/dist/declarative-element/render-callback.js +6 -0
  62. package/dist/declarative-element/slot-names.d.ts +10 -2
  63. package/dist/declarative-element/slot-names.js +5 -1
  64. package/dist/declarative-element/wrap-define-element.d.ts +38 -11
  65. package/dist/declarative-element/wrap-define-element.js +17 -2
  66. package/dist/index.d.ts +40 -40
  67. package/dist/index.js +40 -39
  68. package/dist/lit-exports/all-lit-exports.d.ts +2 -2
  69. package/dist/lit-exports/all-lit-exports.js +2 -2
  70. package/dist/lit-exports/lit-repeat-fix.d.ts +60 -4
  71. package/dist/lit-exports/lit-repeat-fix.js +35 -1
  72. package/dist/readme-examples/my-app.element.d.ts +1 -0
  73. package/dist/readme-examples/my-app.element.js +11 -0
  74. package/dist/readme-examples/my-custom-action.event.d.ts +1 -0
  75. package/dist/readme-examples/my-custom-action.event.js +2 -0
  76. package/dist/readme-examples/my-custom-define.d.ts +4 -0
  77. package/dist/readme-examples/my-custom-define.js +19 -0
  78. package/dist/readme-examples/my-simple.element.d.ts +1 -0
  79. package/dist/readme-examples/my-simple.element.js +9 -0
  80. package/dist/readme-examples/my-with-assignment.element.d.ts +1 -0
  81. package/dist/readme-examples/my-with-assignment.element.js +14 -0
  82. package/dist/readme-examples/my-with-async-prop.element.d.ts +9 -0
  83. package/dist/readme-examples/my-with-async-prop.element.js +46 -0
  84. package/dist/readme-examples/my-with-cleanup-callback.element.d.ts +3 -0
  85. package/dist/readme-examples/my-with-cleanup-callback.element.js +23 -0
  86. package/dist/readme-examples/my-with-css-vars.element.d.ts +1 -0
  87. package/dist/readme-examples/my-with-css-vars.element.js +24 -0
  88. package/dist/readme-examples/my-with-custom-events.element.d.ts +1 -0
  89. package/dist/readme-examples/my-with-custom-events.element.js +21 -0
  90. package/dist/readme-examples/my-with-event-listening.element.d.ts +3 -0
  91. package/dist/readme-examples/my-with-event-listening.element.js +22 -0
  92. package/dist/readme-examples/my-with-events.element.d.ts +4 -0
  93. package/dist/readme-examples/my-with-events.element.js +19 -0
  94. package/dist/readme-examples/my-with-host-class-definition.element.d.ts +3 -0
  95. package/dist/readme-examples/my-with-host-class-definition.element.js +39 -0
  96. package/dist/readme-examples/my-with-host-class-usage.element.d.ts +1 -0
  97. package/dist/readme-examples/my-with-host-class-usage.element.js +12 -0
  98. package/dist/readme-examples/my-with-inputs.element.d.ts +4 -0
  99. package/dist/readme-examples/my-with-inputs.element.js +9 -0
  100. package/dist/readme-examples/my-with-on-dom-created.element.d.ts +1 -0
  101. package/dist/readme-examples/my-with-on-dom-created.element.js +16 -0
  102. package/dist/readme-examples/my-with-on-resize.element.d.ts +1 -0
  103. package/dist/readme-examples/my-with-on-resize.element.js +17 -0
  104. package/dist/readme-examples/my-with-render-if.element.d.ts +3 -0
  105. package/dist/readme-examples/my-with-render-if.element.js +11 -0
  106. package/dist/readme-examples/my-with-styles-and-interpolated-selector.element.d.ts +1 -0
  107. package/dist/readme-examples/my-with-styles-and-interpolated-selector.element.js +15 -0
  108. package/dist/readme-examples/my-with-styles.element.d.ts +1 -0
  109. package/dist/readme-examples/my-with-styles.element.js +21 -0
  110. package/dist/readme-examples/my-with-update-state.element.d.ts +8 -0
  111. package/dist/readme-examples/my-with-update-state.element.js +23 -0
  112. package/dist/readme-examples/require-declarative-element.d.ts +1 -0
  113. package/dist/readme-examples/require-declarative-element.js +2 -0
  114. package/dist/require-declarative-element.d.ts +12 -0
  115. package/dist/require-declarative-element.js +12 -0
  116. package/dist/template-transforms/minimal-element-definition.d.ts +30 -2
  117. package/dist/template-transforms/minimal-element-definition.js +14 -3
  118. package/dist/template-transforms/nested-mapped-templates.d.ts +1 -1
  119. package/dist/template-transforms/nested-mapped-templates.js +4 -3
  120. package/dist/template-transforms/template-transform-type.d.ts +1 -1
  121. package/dist/template-transforms/transform-template.d.ts +1 -1
  122. package/dist/template-transforms/transform-template.js +17 -21
  123. package/dist/template-transforms/vir-css/css-transform.d.ts +3 -3
  124. package/dist/template-transforms/vir-css/css-transform.js +3 -2
  125. package/dist/template-transforms/vir-css/vir-css.d.ts +11 -2
  126. package/dist/template-transforms/vir-css/vir-css.js +11 -2
  127. package/dist/template-transforms/vir-html/html-interpolation.d.ts +9 -5
  128. package/dist/template-transforms/vir-html/html-transform.d.ts +3 -3
  129. package/dist/template-transforms/vir-html/html-transform.js +14 -12
  130. package/dist/template-transforms/vir-html/vir-html.d.ts +4 -2
  131. package/dist/template-transforms/vir-html/vir-html.js +4 -2
  132. package/dist/typed-event/typed-event.d.ts +42 -6
  133. package/dist/typed-event/typed-event.js +31 -28
  134. package/dist/util/lit-template.d.ts +6 -1
  135. package/dist/util/lit-template.js +10 -7
  136. package/dist/util/type.d.ts +5 -0
  137. package/package.json +35 -34
@@ -1,7 +1,9 @@
1
- import { typedHasProperties, typedHasProperty } from '@augment-vir/common';
1
+ import { check } from '@augment-vir/assert';
2
2
  /**
3
3
  * Checks if the input is an instance of a DeclarativeElement, the super class of all custom
4
4
  * elements defined with element-vir.
5
+ *
6
+ * @category Util
5
7
  */
6
8
  export function isDeclarativeElement(input) {
7
9
  const markerProperties = [
@@ -9,15 +11,17 @@ export function isDeclarativeElement(input) {
9
11
  'instanceState',
10
12
  'definition',
11
13
  ];
12
- return typedHasProperties(input, markerProperties);
14
+ return check.hasKeys(input, markerProperties);
13
15
  }
14
16
  /**
15
17
  * Checks if the input is an instance of a DeclarativeElement, the super class of all custom
16
18
  * elements defined with element-vir.
19
+ *
20
+ * @category Util
17
21
  */
18
22
  export function assertIsDeclarativeElement(input) {
19
23
  if (!isDeclarativeElement(input)) {
20
24
  console.error('this is not a declarative element:', input);
21
- throw new Error(`${typedHasProperty(input, 'tagName') ? input.tagName : input} is not a declarative element.`);
25
+ throw new Error(`${String(check.hasKey(input, 'tagName') ? input.tagName : input)} is not a declarative element.`);
22
26
  }
23
27
  }
@@ -3,7 +3,7 @@ export function assignInputs(element, inputs) {
3
3
  const instanceState = element.instanceState;
4
4
  getObjectTypedKeys(inputs).forEach((newInputKey) => {
5
5
  if (instanceState && newInputKey in instanceState) {
6
- throw new Error(`Cannot set input '${newInputKey}' on '${element.tagName}'. '${element.tagName}' already has a state property with the same name.`);
6
+ throw new Error(`Cannot set input '${String(newInputKey)}' on '${element.tagName}'. '${element.tagName}' already has a state property with the same name.`);
7
7
  }
8
8
  if ('instanceInputs' in element) {
9
9
  element.instanceInputs[newInputKey] =
@@ -1,3 +1,13 @@
1
- import { CustomElementTagName } from '../custom-tag-name';
1
+ import { CustomElementTagName } from '../custom-tag-name.js';
2
+ /**
3
+ * Base requirement for all CSS property names (like CSS var names).
4
+ *
5
+ * @category Internal
6
+ */
2
7
  export type BaseCssPropertyName<ElementTagName extends CustomElementTagName> = `${ElementTagName}-${string}`;
8
+ /**
9
+ * Asserts that all the given CSS properties for the given element are valid.
10
+ *
11
+ * @category Internal
12
+ */
3
13
  export declare function assertValidCssProperties(elementTagName: CustomElementTagName, cssProperties: Record<BaseCssPropertyName<CustomElementTagName>, any>): void;
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Asserts that all the given CSS properties for the given element are valid.
3
+ *
4
+ * @category Internal
5
+ */
1
6
  export function assertValidCssProperties(elementTagName, cssProperties) {
2
7
  const requiredCssPropKeyStart = [
3
8
  elementTagName,
@@ -1,6 +1,16 @@
1
- import { PropertyValueType } from '@augment-vir/common';
1
+ import { Values } from '@augment-vir/common';
2
2
  import { CssVarDefinitions, CssVarsSetup } from 'lit-css-vars';
3
- import { CustomElementTagName } from '../custom-tag-name';
4
- import { BaseCssPropertyName } from './css-properties';
5
- export type CssVarsInitMap<ElementTagName extends CustomElementTagName, CssVarKeys extends BaseCssPropertyName<ElementTagName>> = Readonly<Record<CssVarKeys, PropertyValueType<CssVarsSetup>>>;
3
+ import { CustomElementTagName } from '../custom-tag-name.js';
4
+ import { BaseCssPropertyName } from './css-properties.js';
5
+ /**
6
+ * Base type for a declarative element definition's CSS vars.
7
+ *
8
+ * @category Internal
9
+ */
10
+ export type CssVarsInitMap<ElementTagName extends CustomElementTagName, CssVarKeys extends BaseCssPropertyName<ElementTagName>> = Readonly<Record<CssVarKeys, Values<CssVarsSetup>>>;
11
+ /**
12
+ * CSS vars ready for use within a declarative element's `render` or `styles` method.
13
+ *
14
+ * @category Internal
15
+ */
6
16
  export type CssVars<ElementTagName extends CustomElementTagName, CssVarKeys extends BaseCssPropertyName<ElementTagName>> = CssVarDefinitions<CssVarsInitMap<ElementTagName, CssVarKeys>>;
@@ -1,11 +1,65 @@
1
- import { DefinedTypedEvent, DefinedTypedEventNameDefinition, TypedEvent } from '../../typed-event/typed-event';
2
- import { CustomElementTagName } from '../custom-tag-name';
3
- export type EventsInitMap = Record<string, DefinedTypedEventNameDefinition<any>>;
4
- export declare function defineElementEvent<EventDetailGeneric>(): DefinedTypedEventNameDefinition<EventDetailGeneric>;
5
- export type EventInitMapEventDetailExtractor<EventTypeNameGeneric extends keyof EventsInitGeneric, EventsInitGeneric extends EventsInitMap> = EventsInitGeneric[EventTypeNameGeneric] extends DefinedTypedEventNameDefinition<infer R> ? R : never;
1
+ import { DefinedTypedEvent, DefineEvent, TypedEvent } from '../../typed-event/typed-event.js';
2
+ import { CustomElementTagName } from '../custom-tag-name.js';
3
+ /**
4
+ * Base type for defining element events inside of an element definition.
5
+ *
6
+ * @category Internal
7
+ */
8
+ export type EventsInitMap = Record<string, DefineEvent<any>>;
9
+ /**
10
+ * Used to define element events, with a type.
11
+ *
12
+ * @category Element Definition
13
+ * @example
14
+ *
15
+ * ```ts
16
+ * import {html, defineElementNoInputs, defineElementEvent, listen} from 'element-vir';
17
+ *
18
+ * const MyElement = defineElementNoInputs({
19
+ * tagName: 'my-element',
20
+ * events: {
21
+ * myOutput: defineElementEvent<number>(),
22
+ * },
23
+ * render({events, dispatch}) {
24
+ * return html`
25
+ * <div
26
+ * ${listen('click', () => {
27
+ * dispatch(new events.myOutput(1));
28
+ * })}
29
+ * >
30
+ * Some div
31
+ * </div>
32
+ * `;
33
+ * },
34
+ * });
35
+ * ```
36
+ */
37
+ export declare function defineElementEvent<EventDetailGeneric>(): DefineEvent<EventDetailGeneric>;
38
+ /**
39
+ * Extracts the detail type of the given event name from the given event init map.
40
+ *
41
+ * @category Internal
42
+ */
43
+ export type EventInitMapEventDetailExtractor<EventTypeNameGeneric extends keyof EventsInitGeneric, EventsInitGeneric extends EventsInitMap> = EventsInitGeneric[EventTypeNameGeneric] extends DefineEvent<infer Detail> ? Detail : never;
44
+ /**
45
+ * Maps the given element tag name and map of event names to their run-time event type strings.
46
+ *
47
+ * @category Internal
48
+ */
6
49
  export type EventDescriptorMap<TagName extends CustomElementTagName, EventsInitGeneric extends EventsInitMap> = {
7
50
  [CurrentEventTypeName in keyof EventsInitGeneric]: DefinedTypedEvent<CurrentEventTypeName extends string ? `${TagName}-${CurrentEventTypeName}` : never, EventInitMapEventDetailExtractor<CurrentEventTypeName, EventsInitGeneric>>;
8
51
  };
9
- export type EventObjectEventDetailExtractor<EventObjectGeneric extends DefinedTypedEvent<any, any>> = EventObjectGeneric extends DefinedTypedEvent<string, infer R> ? R : never;
10
- export type ElementEventDetailExtractor<ElementEventGeneric extends TypedEvent<any, any>> = ElementEventGeneric extends TypedEvent<string, infer R> ? R : never;
52
+ /**
53
+ * Extract the event detail type from a {@link TypedEvent}, {@link DefinedTypedEvent}, or
54
+ * `CustomEvent.
55
+ *
56
+ * @category Internal
57
+ */
58
+ export type EventDetail<ElementEvent extends TypedEvent<any, any> | DefinedTypedEvent<any, any> | CustomEvent> = ElementEvent extends TypedEvent<string, infer Detail> ? Detail : ElementEvent extends DefinedTypedEvent<any, infer Detail> ? Detail : ElementEvent extends CustomEvent<infer Detail> ? Detail : 'TYPE ERROR: failed to extract event detail type';
59
+ /**
60
+ * Maps an element definition initialization's tag name and event map to a map of ready-to-construct
61
+ * event classes. This also verifies that the input event init map has valid keys.
62
+ *
63
+ * @category Internal
64
+ */
11
65
  export declare function createEventDescriptorMap<TagName extends CustomElementTagName, EventsInitGeneric extends EventsInitMap>(tagName: CustomElementTagName, eventsInit: EventsInitGeneric | undefined): EventDescriptorMap<TagName, EventsInitGeneric>;
@@ -1,17 +1,52 @@
1
- import { defineTypedEvent, } from '../../typed-event/typed-event';
1
+ import { defineTypedEvent, } from '../../typed-event/typed-event.js';
2
+ /**
3
+ * Used to define element events, with a type.
4
+ *
5
+ * @category Element Definition
6
+ * @example
7
+ *
8
+ * ```ts
9
+ * import {html, defineElementNoInputs, defineElementEvent, listen} from 'element-vir';
10
+ *
11
+ * const MyElement = defineElementNoInputs({
12
+ * tagName: 'my-element',
13
+ * events: {
14
+ * myOutput: defineElementEvent<number>(),
15
+ * },
16
+ * render({events, dispatch}) {
17
+ * return html`
18
+ * <div
19
+ * ${listen('click', () => {
20
+ * dispatch(new events.myOutput(1));
21
+ * })}
22
+ * >
23
+ * Some div
24
+ * </div>
25
+ * `;
26
+ * },
27
+ * });
28
+ * ```
29
+ */
2
30
  export function defineElementEvent() {
3
31
  return defineTypedEvent();
4
32
  }
33
+ /**
34
+ * Maps an element definition initialization's tag name and event map to a map of ready-to-construct
35
+ * event classes. This also verifies that the input event init map has valid keys.
36
+ *
37
+ * @category Internal
38
+ */
5
39
  export function createEventDescriptorMap(tagName, eventsInit) {
6
40
  if (!eventsInit) {
7
41
  return {};
8
42
  }
9
- return Object.keys(eventsInit)
43
+ return (Object.keys(eventsInit)
44
+ /** Verify event keys. */
10
45
  .filter((currentElementEventKey) => {
11
46
  if (typeof currentElementEventKey !== 'string') {
12
- throw new Error(`Expected event key of type string but got type "${typeof currentElementEventKey}" for key ${String(currentElementEventKey)}`);
47
+ throw new TypeError(`Expected event key of type string but got type '${typeof currentElementEventKey}' for key ${String(currentElementEventKey)}`);
13
48
  }
14
- if (currentElementEventKey === '') {
49
+ else if (currentElementEventKey === '') {
15
50
  throw new Error(`Got empty string for events key.`);
16
51
  }
17
52
  return true;
@@ -23,5 +58,5 @@ export function createEventDescriptorMap(tagName, eventsInit) {
23
58
  ].join('-'));
24
59
  accum[currentElementEventKey] = eventObject;
25
60
  return accum;
26
- }, {});
61
+ }, {}));
27
62
  }
@@ -1,14 +1,23 @@
1
+ /**
2
+ * The base type for any property maps (like state or inputs).
3
+ *
4
+ * @category Internal
5
+ */
1
6
  export type PropertyInitMapBase = Record<PropertyKey, unknown>;
2
- export type ElementProperty<KeyGeneric extends string | number | symbol, ValueGeneric> = {
3
- name: KeyGeneric;
4
- setProp(value: ValueGeneric): void;
5
- getProp(): ValueGeneric;
6
- };
7
+ /**
8
+ * Describes a static element property.
9
+ *
10
+ * @category Internal
11
+ */
7
12
  export type StaticElementPropertyDescriptor<PropName extends string, PropValue> = {
8
13
  propName: PropName;
9
14
  initValue: PropValue;
10
15
  };
16
+ /**
17
+ * Maps a property init map into static element descriptions.
18
+ *
19
+ * @category Internal
20
+ */
11
21
  export type ElementPropertyDescriptorMap<PropertyInitGeneric extends PropertyInitMapBase> = {
12
22
  [Property in keyof PropertyInitGeneric]: StaticElementPropertyDescriptor<string, PropertyInitGeneric[Property]>;
13
23
  };
14
- export declare function createPropertyDescriptorMap<PropertyInitGeneric extends PropertyInitMapBase>(propertyInit: PropertyInitGeneric | undefined): ElementPropertyDescriptorMap<PropertyInitGeneric>;
@@ -1,21 +1 @@
1
- export function createPropertyDescriptorMap(propertyInit) {
2
- if (!propertyInit) {
3
- return {};
4
- }
5
- return Object.keys(propertyInit)
6
- .filter((key) => {
7
- if (typeof key === 'string') {
8
- return true;
9
- }
10
- else {
11
- throw new Error(`Property init cannot have non string keys: "${key}"`);
12
- }
13
- })
14
- .reduce((accum, currentKey) => {
15
- accum[currentKey] = {
16
- propName: currentKey,
17
- initValue: propertyInit[currentKey],
18
- };
19
- return accum;
20
- }, {});
21
- }
1
+ export {};
@@ -1,14 +1,54 @@
1
- import { PropertyInitMapBase } from './element-properties';
1
+ import { PropertyInitMapBase } from './element-properties.js';
2
+ /**
3
+ * Use this key with a function value on any object set in `stateInitStatic` to, rather than using
4
+ * the object itself, call the function during each element's initialization and use the output of
5
+ * that function rather than the object itself.
6
+ *
7
+ * See `perInstance` for an example usage.
8
+ *
9
+ * @category Util
10
+ */
2
11
  export declare const stateSetupKey: unique symbol;
12
+ /**
13
+ * The type for an object that uses {@link stateSetupKey}.
14
+ *
15
+ * @category Internal
16
+ */
3
17
  export type ElementVirStateSetup<InnerValue> = {
4
18
  [key in typeof stateSetupKey]: () => InnerValue;
5
19
  };
20
+ /**
21
+ * Check if the given value is a value {@link ElementVirStateSetup} implementation.
22
+ *
23
+ * @category Internal
24
+ */
6
25
  export declare function isElementVirStateSetup<T = unknown>(input: unknown): input is ElementVirStateSetup<T>;
26
+ /**
27
+ * If the type parameter is an instance of {@link ElementVirStateSetup}, this unwraps that instance
28
+ * to its type parameter. Otherwise, the original type parameter is used.
29
+ *
30
+ * @category Internal
31
+ */
7
32
  export type UnwrapElementVirStateSetup<T> = T extends ElementVirStateSetup<infer U> ? U : T;
33
+ /**
34
+ * Allow wrapped state setup objects.
35
+ *
36
+ * @category Internal
37
+ */
8
38
  export type MaybeElementVirStateSetup<T> = UnwrapElementVirStateSetup<T> | ElementVirStateSetup<UnwrapElementVirStateSetup<T>>;
9
- export type FlattenElementVirStateSetup<OriginalObject extends PropertyInitMapBase> = {
10
- [Prop in keyof OriginalObject]: Extract<OriginalObject[Prop], ElementVirStateSetup<any>> extends never ? OriginalObject[Prop] : Extract<OriginalObject[Prop], ElementVirStateSetup<any>> extends ElementVirStateSetup<infer InnerValue> ? InnerValue | Exclude<OriginalObject[Prop], ElementVirStateSetup<any>> : OriginalObject[Prop];
39
+ /**
40
+ * Unwraps all {@link ElementVirStateSetup} properties in the given state init object type parameter.
41
+ *
42
+ * @category Internal
43
+ */
44
+ export type FlattenElementVirStateSetup<StateInit extends PropertyInitMapBase> = {
45
+ [Prop in keyof StateInit]: Extract<StateInit[Prop], ElementVirStateSetup<any>> extends never ? StateInit[Prop] : Extract<StateInit[Prop], ElementVirStateSetup<any>> extends ElementVirStateSetup<infer InnerValue> ? InnerValue | Exclude<StateInit[Prop], ElementVirStateSetup<any>> : StateInit[Prop];
11
46
  };
47
+ /**
48
+ * Allows setting stat with {@link ElementVirStateSetup} properties.
49
+ *
50
+ * @category Internal
51
+ */
12
52
  export type AllowElementVirStateSetup<OriginalObject extends PropertyInitMapBase> = {
13
53
  [Prop in keyof OriginalObject]: MaybeElementVirStateSetup<OriginalObject[Prop]>;
14
54
  };
@@ -1,8 +1,22 @@
1
- import { isObject } from '@augment-vir/common';
1
+ import { check } from '@augment-vir/assert';
2
+ /**
3
+ * Use this key with a function value on any object set in `stateInitStatic` to, rather than using
4
+ * the object itself, call the function during each element's initialization and use the output of
5
+ * that function rather than the object itself.
6
+ *
7
+ * See `perInstance` for an example usage.
8
+ *
9
+ * @category Util
10
+ */
2
11
  export const stateSetupKey = Symbol('element-vir-state-setup');
12
+ /**
13
+ * Check if the given value is a value {@link ElementVirStateSetup} implementation.
14
+ *
15
+ * @category Internal
16
+ */
3
17
  export function isElementVirStateSetup(input) {
4
- if (!isObject(input)) {
18
+ if (!check.isObject(input)) {
5
19
  return false;
6
20
  }
7
- return stateSetupKey in input;
21
+ return stateSetupKey in input && check.isFunction(input[stateSetupKey]);
8
22
  }
@@ -1,21 +1,34 @@
1
- import { CustomElementTagName } from '../custom-tag-name';
2
- import { BaseCssPropertyName } from './css-properties';
3
- import { PropertyInitMapBase } from './element-properties';
4
- import { FlattenElementVirStateSetup } from './element-vir-state-setup';
5
- import { WithTagName } from './tag-name';
6
- export type HostClassToggleCallbackInput<Inputs extends PropertyInitMapBase, StateInit extends PropertyInitMapBase> = {
7
- state: Readonly<FlattenElementVirStateSetup<StateInit>>;
8
- inputs: Readonly<Inputs>;
9
- };
10
- export type HostClassToggleCallback<Inputs extends PropertyInitMapBase, StateInit extends PropertyInitMapBase> = (inputs: HostClassToggleCallbackInput<Inputs, StateInit>) => boolean;
1
+ import { CustomElementTagName } from '../custom-tag-name.js';
2
+ import { BaseCssPropertyName } from './css-properties.js';
3
+ import { PropertyInitMapBase } from './element-properties.js';
4
+ import { FlattenElementVirStateSetup } from './element-vir-state-setup.js';
5
+ import { WithTagName } from './tag-name.js';
6
+ /**
7
+ * Base init map for defining host classes in an element definition.
8
+ *
9
+ * @category Internal
10
+ */
11
11
  export type HostClassesInitMap<TagName extends CustomElementTagName, HostClassKeys extends BaseCssPropertyName<TagName>, Inputs extends PropertyInitMapBase, StateInit extends PropertyInitMapBase> = Record<HostClassKeys,
12
12
  /**
13
13
  * Callback to determine when host class should be enabled (based on current inputs and state),
14
14
  * or just undefined to mark that this host class name will only be manually applied.
15
15
  */
16
- HostClassToggleCallback<Inputs, StateInit> | false>;
17
- export type HostClassName<TagName extends string, HostClassPropName extends string> = `${TagName}-${HostClassPropName}`;
16
+ ((inputs: {
17
+ state: Readonly<FlattenElementVirStateSetup<StateInit>>;
18
+ inputs: Readonly<Inputs>;
19
+ }) => boolean) | false>;
20
+ /**
21
+ * Creates a mapping of host class keys (as defined in an element definition) to their runtime host
22
+ * class names.
23
+ *
24
+ * @category Internal
25
+ */
18
26
  export type HostClassNamesMap<TagName extends string, HostClassKeys extends string> = Record<HostClassKeys, WithTagName<TagName, string>>;
27
+ /**
28
+ * Maps element definition host class definitions to their runtime host class name equivalents.
29
+ *
30
+ * @category Internal
31
+ */
19
32
  export declare function createHostClassNamesMap<TagName extends CustomElementTagName, HostClassKeys extends BaseCssPropertyName<TagName>, HostClassesInit extends HostClassesInitMap<TagName, HostClassKeys,
20
33
  /**
21
34
  * We can use any here because we don't care what the state or input names are, we just care
@@ -1,4 +1,9 @@
1
1
  import { mapObjectValues } from '@augment-vir/common';
2
+ /**
3
+ * Maps element definition host class definitions to their runtime host class name equivalents.
4
+ *
5
+ * @category Internal
6
+ */
2
7
  export function createHostClassNamesMap(hostClassesInit) {
3
8
  if (hostClassesInit) {
4
9
  return mapObjectValues(hostClassesInit, (key) => {
@@ -1,5 +1,26 @@
1
1
  /**
2
- * A state prop helper that sets up the given callback for each instance of the element that this
3
- * state is contained within.
2
+ * For use within `stateInitStatic`: use this as the value of a state prop to call the given
3
+ * callback on each element's creation rather than creating a static state init value.
4
+ *
5
+ * @category Directives
6
+ * @example
7
+ *
8
+ * ```ts
9
+ * import {waitValue, extractErrorMessage} from '@augment-vir/common';
10
+ * import {isResolved, html, defineElementNoInputs, perInstance} from 'element-vir';
11
+ *
12
+ * const MyElement = defineElementNoInputs({
13
+ * tagName: 'my-element',
14
+ * stateInitStatic: {
15
+ * // each instance of `MyElement` will have a different `randomValue`
16
+ * randomValue: perInstance(() => Math.random()),
17
+ * },
18
+ * render({state}) {
19
+ * return html`
20
+ * Value: ${state.randomValue}
21
+ * `;
22
+ * },
23
+ * });
24
+ * ```
4
25
  */
5
26
  export declare function perInstance<T>(creationCallback: () => T): T;
@@ -1,7 +1,28 @@
1
- import { stateSetupKey } from './element-vir-state-setup';
1
+ import { stateSetupKey } from './element-vir-state-setup.js';
2
2
  /**
3
- * A state prop helper that sets up the given callback for each instance of the element that this
4
- * state is contained within.
3
+ * For use within `stateInitStatic`: use this as the value of a state prop to call the given
4
+ * callback on each element's creation rather than creating a static state init value.
5
+ *
6
+ * @category Directives
7
+ * @example
8
+ *
9
+ * ```ts
10
+ * import {waitValue, extractErrorMessage} from '@augment-vir/common';
11
+ * import {isResolved, html, defineElementNoInputs, perInstance} from 'element-vir';
12
+ *
13
+ * const MyElement = defineElementNoInputs({
14
+ * tagName: 'my-element',
15
+ * stateInitStatic: {
16
+ * // each instance of `MyElement` will have a different `randomValue`
17
+ * randomValue: perInstance(() => Math.random()),
18
+ * },
19
+ * render({state}) {
20
+ * return html`
21
+ * Value: ${state.randomValue}
22
+ * `;
23
+ * },
24
+ * });
25
+ * ```
5
26
  */
6
27
  export function perInstance(creationCallback) {
7
28
  const stateSetup = {
@@ -1,7 +1,22 @@
1
- import { ObservableListener } from 'observavir';
2
- import { DeclarativeElement } from '../declarative-element';
3
- import { PropertyInitMapBase } from './element-properties';
1
+ import { type ObservableListener } from 'observavir';
2
+ import { type DeclarativeElement } from '../declarative-element.js';
3
+ import { type PropertyInitMapBase } from './element-properties.js';
4
+ /**
5
+ * Used for a map of all observables registered to an element instance.
6
+ *
7
+ * @category Internal
8
+ */
4
9
  export type ObservableListenerMap<OriginalPropertyMap extends PropertyInitMapBase> = Partial<Record<keyof OriginalPropertyMap, ObservableListener<any> | undefined>>;
5
- /** Binds the given property key as a reactive property on the given element. */
10
+ /**
11
+ * Binds the given property key as a reactive property on the given element.
12
+ *
13
+ * @category Internal
14
+ */
6
15
  export declare function bindReactiveProperty(element: HTMLElement, propertyKey: PropertyKey): void;
16
+ /**
17
+ * Creates an internal proxy for setting inputs and state properties and then updating them on the
18
+ * element itself so they will trigger lit's change detection.
19
+ *
20
+ * @category Internal
21
+ */
7
22
  export declare function createElementPropertyProxy<PropertyInitGeneric extends PropertyInitMapBase>(element: DeclarativeElement, shouldAlreadyExist: boolean): PropertyInitGeneric;
@@ -1,7 +1,11 @@
1
1
  import { isObservableBase } from 'observavir';
2
- import { property } from '../../lit-exports/all-lit-exports';
3
- import { isElementVirStateSetup, stateSetupKey } from './element-vir-state-setup';
4
- /** Binds the given property key as a reactive property on the given element. */
2
+ import { property } from '../../lit-exports/base-lit-exports.js';
3
+ import { isElementVirStateSetup, stateSetupKey } from './element-vir-state-setup.js';
4
+ /**
5
+ * Binds the given property key as a reactive property on the given element.
6
+ *
7
+ * @category Internal
8
+ */
5
9
  export function bindReactiveProperty(element, propertyKey) {
6
10
  if (!(propertyKey in element)) {
7
11
  property()(element, propertyKey);
@@ -9,12 +13,18 @@ export function bindReactiveProperty(element, propertyKey) {
9
13
  }
10
14
  function assertValidPropertyName(propKey, element, elementTagName) {
11
15
  if (typeof propKey !== 'string' && typeof propKey !== 'number' && typeof propKey !== 'symbol') {
12
- throw new Error(`Property name must be a string, got type '${typeof propKey}' from: '${String(propKey)}' for '${elementTagName.toLowerCase()}'`);
16
+ throw new TypeError(`Property name must be a string, got type '${typeof propKey}' from: '${String(propKey)}' for '${elementTagName.toLowerCase()}'`);
13
17
  }
14
18
  if (!(propKey in element)) {
15
19
  throw new Error(`Property '${String(propKey)}' does not exist on '${elementTagName.toLowerCase()}'.`);
16
20
  }
17
21
  }
22
+ /**
23
+ * Creates an internal proxy for setting inputs and state properties and then updating them on the
24
+ * element itself so they will trigger lit's change detection.
25
+ *
26
+ * @category Internal
27
+ */
18
28
  export function createElementPropertyProxy(element, shouldAlreadyExist) {
19
29
  /**
20
30
  * Lit element updates state and inputs by setting them directly on the element, so we must do
@@ -23,6 +33,7 @@ export function createElementPropertyProxy(element, shouldAlreadyExist) {
23
33
  */
24
34
  const elementAsProps = element;
25
35
  function verifyProperty(propertyKey) {
36
+ // eslint-disable-next-line sonarjs/no-selector-parameter
26
37
  if (shouldAlreadyExist) {
27
38
  assertValidPropertyName(propertyKey, element, element.tagName);
28
39
  }
@@ -1,23 +1,48 @@
1
- import { CSSResult } from '../../lit-exports/all-lit-exports';
2
- import { CustomElementTagName } from '../custom-tag-name';
3
- import { BaseCssPropertyName } from './css-properties';
4
- import { CssVars } from './css-vars';
5
- import { PropertyInitMapBase } from './element-properties';
6
- import { FlattenElementVirStateSetup } from './element-vir-state-setup';
7
- import { HostClassNamesMap, HostClassesInitMap } from './host-classes';
1
+ import { type CSSResult } from '../../lit-exports/base-lit-exports.js';
2
+ import { type CustomElementTagName } from '../custom-tag-name.js';
3
+ import { type BaseCssPropertyName } from './css-properties.js';
4
+ import { type CssVars } from './css-vars.js';
5
+ import { type PropertyInitMapBase } from './element-properties.js';
6
+ import { type FlattenElementVirStateSetup } from './element-vir-state-setup.js';
7
+ import { type HostClassNamesMap, type HostClassesInitMap } from './host-classes.js';
8
+ /**
9
+ * A host class instance to be referenced inside of an element definition's `styles` callback.
10
+ *
11
+ * @category Internal
12
+ */
8
13
  export type HostClass = {
9
14
  selector: CSSResult;
10
15
  name: CSSResult;
11
16
  };
17
+ /**
18
+ * Input type for an element definition's `styles` callback.
19
+ *
20
+ * @category Internal
21
+ */
12
22
  export type StylesCallbackInput<TagName extends CustomElementTagName, HostClassKeys extends BaseCssPropertyName<TagName>, CssVarKeys extends BaseCssPropertyName<TagName>> = {
13
23
  hostClasses: Record<HostClassKeys, HostClass>;
14
24
  cssVars: Readonly<CssVars<TagName, CssVarKeys>>;
15
25
  };
26
+ /**
27
+ * The type for an element definition's `styles` callback.
28
+ *
29
+ * @category Internal
30
+ */
16
31
  export type StylesCallback<TagName extends CustomElementTagName, HostClassKeys extends BaseCssPropertyName<TagName>, CssVarKeys extends BaseCssPropertyName<TagName>> = (input: StylesCallbackInput<TagName, HostClassKeys, CssVarKeys>) => CSSResult;
17
- export declare function hostClassNamesToStylesInput<TagName extends CustomElementTagName, HostClassKeys extends BaseCssPropertyName<TagName>, CssVarKeys extends BaseCssPropertyName<TagName>>({ hostClassNames, cssVars, }: {
32
+ /**
33
+ * Creates the input for an element definition's `styles` callback.
34
+ *
35
+ * @category Internal
36
+ */
37
+ export declare function createStylesCallbackInput<TagName extends CustomElementTagName, HostClassKeys extends BaseCssPropertyName<TagName>, CssVarKeys extends BaseCssPropertyName<TagName>>({ hostClassNames, cssVars, }: {
18
38
  hostClassNames: HostClassNamesMap<TagName, HostClassKeys>;
19
39
  cssVars: Readonly<CssVars<TagName, CssVarKeys>>;
20
40
  }): StylesCallbackInput<TagName, HostClassKeys, CssVarKeys>;
41
+ /**
42
+ * Used inside of an element instance to apply host classes on each render.
43
+ *
44
+ * @category Internal
45
+ */
21
46
  export declare function applyHostClasses<TagName extends CustomElementTagName, Inputs extends PropertyInitMapBase, StateInit extends PropertyInitMapBase, HostClassKeys extends BaseCssPropertyName<TagName>>({ host, hostClassesInit, hostClassNames, state, inputs, }: {
22
47
  host: HTMLElement;
23
48
  hostClassesInit: Readonly<HostClassesInitMap<TagName, HostClassKeys, Inputs, StateInit>> | undefined;
@@ -1,6 +1,11 @@
1
1
  import { getObjectTypedKeys, mapObjectValues } from '@augment-vir/common';
2
- import { unsafeCSS } from '../../lit-exports/all-lit-exports';
3
- export function hostClassNamesToStylesInput({ hostClassNames, cssVars, }) {
2
+ import { unsafeCSS } from '../../lit-exports/base-lit-exports.js';
3
+ /**
4
+ * Creates the input for an element definition's `styles` callback.
5
+ *
6
+ * @category Internal
7
+ */
8
+ export function createStylesCallbackInput({ hostClassNames, cssVars, }) {
4
9
  return {
5
10
  hostClasses: mapObjectValues(hostClassNames, (key, name) => {
6
11
  return {
@@ -11,6 +16,11 @@ export function hostClassNamesToStylesInput({ hostClassNames, cssVars, }) {
11
16
  cssVars,
12
17
  };
13
18
  }
19
+ /**
20
+ * Used inside of an element instance to apply host classes on each render.
21
+ *
22
+ * @category Internal
23
+ */
14
24
  export function applyHostClasses({ host, hostClassesInit, hostClassNames, state, inputs, }) {
15
25
  if (!hostClassesInit) {
16
26
  return;
@@ -1 +1,6 @@
1
+ /**
2
+ * Prefixes any given `Suffix` with a element's `TagName`.
3
+ *
4
+ * @category Internal
5
+ */
1
6
  export type WithTagName<TagName extends string, Suffix extends string> = `${TagName}-${Suffix}`;