element-vir 22.2.2 → 23.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -38
- package/dist/declarative-element/custom-tag-name.d.ts +6 -0
- package/dist/declarative-element/declarative-element-init.d.ts +20 -14
- package/dist/declarative-element/declarative-element.d.ts +70 -24
- package/dist/declarative-element/declarative-element.js +34 -1
- package/dist/declarative-element/define-element-no-inputs.d.ts +31 -6
- package/dist/declarative-element/define-element-no-inputs.js +154 -257
- package/dist/declarative-element/define-element.d.ts +35 -7
- package/dist/declarative-element/define-element.js +26 -4
- package/dist/declarative-element/definition-options.d.ts +10 -0
- package/dist/declarative-element/definition-options.js +5 -0
- package/dist/declarative-element/directives/assign.directive.d.ts +8 -11
- package/dist/declarative-element/directives/assign.directive.js +6 -13
- package/dist/declarative-element/directives/async-prop.d.ts +19 -4
- package/dist/declarative-element/directives/async-prop.js +14 -4
- package/dist/declarative-element/directives/create-attribute-directive.d.ts +19 -4
- package/dist/declarative-element/directives/create-attribute-directive.js +18 -8
- package/dist/declarative-element/directives/directive-helpers.d.ts +19 -4
- package/dist/declarative-element/directives/directive-helpers.js +14 -2
- package/dist/declarative-element/directives/is-resolved.directive.d.ts +107 -1
- package/dist/declarative-element/directives/is-resolved.directive.js +107 -1
- package/dist/declarative-element/directives/listen.directive.d.ts +84 -10
- package/dist/declarative-element/directives/listen.directive.js +5 -15
- package/dist/declarative-element/directives/on-dom-created.directive.d.ts +37 -4
- package/dist/declarative-element/directives/on-dom-created.directive.js +32 -12
- package/dist/declarative-element/directives/on-dom-rendered.directive.d.ts +33 -3
- package/dist/declarative-element/directives/on-dom-rendered.directive.js +29 -6
- package/dist/declarative-element/directives/on-resize.directive.d.ts +37 -4
- package/dist/declarative-element/directives/on-resize.directive.js +37 -24
- package/dist/declarative-element/directives/render-async.directive.d.ts +44 -4
- package/dist/declarative-element/directives/render-async.directive.js +13 -3
- package/dist/declarative-element/directives/render-if.directive.d.ts +31 -0
- package/dist/declarative-element/directives/render-if.directive.js +32 -1
- package/dist/declarative-element/directives/test-id.directive.d.ts +48 -4
- package/dist/declarative-element/directives/test-id.directive.js +47 -2
- package/dist/declarative-element/has-declarative-element-parent.js +1 -1
- package/dist/declarative-element/is-declarative-element-definition.d.ts +15 -1
- package/dist/declarative-element/is-declarative-element-definition.js +21 -18
- package/dist/declarative-element/is-declarative-element.d.ts +5 -1
- package/dist/declarative-element/is-declarative-element.js +7 -3
- package/dist/declarative-element/properties/assign-inputs.js +1 -1
- package/dist/declarative-element/properties/css-properties.d.ts +11 -1
- package/dist/declarative-element/properties/css-properties.js +5 -0
- package/dist/declarative-element/properties/css-vars.d.ts +14 -4
- package/dist/declarative-element/properties/element-events.d.ts +61 -7
- package/dist/declarative-element/properties/element-events.js +40 -5
- package/dist/declarative-element/properties/element-properties.d.ts +15 -6
- package/dist/declarative-element/properties/element-properties.js +1 -21
- package/dist/declarative-element/properties/element-vir-state-setup.d.ts +43 -3
- package/dist/declarative-element/properties/element-vir-state-setup.js +17 -3
- package/dist/declarative-element/properties/host-classes.d.ts +25 -12
- package/dist/declarative-element/properties/host-classes.js +5 -0
- package/dist/declarative-element/properties/per-instance.d.ts +23 -2
- package/dist/declarative-element/properties/per-instance.js +24 -3
- package/dist/declarative-element/properties/property-proxy.d.ts +19 -4
- package/dist/declarative-element/properties/property-proxy.js +14 -4
- package/dist/declarative-element/properties/styles.d.ts +33 -8
- package/dist/declarative-element/properties/styles.js +12 -2
- package/dist/declarative-element/properties/tag-name.d.ts +5 -0
- package/dist/declarative-element/render-callback.d.ts +38 -11
- package/dist/declarative-element/render-callback.js +6 -0
- package/dist/declarative-element/slot-names.d.ts +10 -2
- package/dist/declarative-element/slot-names.js +5 -1
- package/dist/declarative-element/wrap-define-element.d.ts +38 -11
- package/dist/declarative-element/wrap-define-element.js +17 -2
- package/dist/index.d.ts +40 -40
- package/dist/index.js +40 -39
- package/dist/lit-exports/all-lit-exports.d.ts +2 -2
- package/dist/lit-exports/all-lit-exports.js +2 -2
- package/dist/lit-exports/lit-repeat-fix.d.ts +60 -4
- package/dist/lit-exports/lit-repeat-fix.js +35 -1
- package/dist/readme-examples/my-app.element.d.ts +1 -0
- package/dist/readme-examples/my-app.element.js +11 -0
- package/dist/readme-examples/my-custom-action.event.d.ts +1 -0
- package/dist/readme-examples/my-custom-action.event.js +2 -0
- package/dist/readme-examples/my-custom-define.d.ts +4 -0
- package/dist/readme-examples/my-custom-define.js +19 -0
- package/dist/readme-examples/my-simple.element.d.ts +1 -0
- package/dist/readme-examples/my-simple.element.js +9 -0
- package/dist/readme-examples/my-with-assignment.element.d.ts +1 -0
- package/dist/readme-examples/my-with-assignment.element.js +14 -0
- package/dist/readme-examples/my-with-async-prop.element.d.ts +9 -0
- package/dist/readme-examples/my-with-async-prop.element.js +46 -0
- package/dist/readme-examples/my-with-cleanup-callback.element.d.ts +3 -0
- package/dist/readme-examples/my-with-cleanup-callback.element.js +23 -0
- package/dist/readme-examples/my-with-css-vars.element.d.ts +1 -0
- package/dist/readme-examples/my-with-css-vars.element.js +24 -0
- package/dist/readme-examples/my-with-custom-events.element.d.ts +1 -0
- package/dist/readme-examples/my-with-custom-events.element.js +21 -0
- package/dist/readme-examples/my-with-event-listening.element.d.ts +3 -0
- package/dist/readme-examples/my-with-event-listening.element.js +22 -0
- package/dist/readme-examples/my-with-events.element.d.ts +4 -0
- package/dist/readme-examples/my-with-events.element.js +19 -0
- package/dist/readme-examples/my-with-host-class-definition.element.d.ts +3 -0
- package/dist/readme-examples/my-with-host-class-definition.element.js +39 -0
- package/dist/readme-examples/my-with-host-class-usage.element.d.ts +1 -0
- package/dist/readme-examples/my-with-host-class-usage.element.js +12 -0
- package/dist/readme-examples/my-with-inputs.element.d.ts +4 -0
- package/dist/readme-examples/my-with-inputs.element.js +9 -0
- package/dist/readme-examples/my-with-on-dom-created.element.d.ts +1 -0
- package/dist/readme-examples/my-with-on-dom-created.element.js +16 -0
- package/dist/readme-examples/my-with-on-resize.element.d.ts +1 -0
- package/dist/readme-examples/my-with-on-resize.element.js +17 -0
- package/dist/readme-examples/my-with-render-if.element.d.ts +3 -0
- package/dist/readme-examples/my-with-render-if.element.js +11 -0
- package/dist/readme-examples/my-with-styles-and-interpolated-selector.element.d.ts +1 -0
- package/dist/readme-examples/my-with-styles-and-interpolated-selector.element.js +15 -0
- package/dist/readme-examples/my-with-styles.element.d.ts +1 -0
- package/dist/readme-examples/my-with-styles.element.js +21 -0
- package/dist/readme-examples/my-with-update-state.element.d.ts +8 -0
- package/dist/readme-examples/my-with-update-state.element.js +23 -0
- package/dist/readme-examples/require-declarative-element.d.ts +1 -0
- package/dist/readme-examples/require-declarative-element.js +2 -0
- package/dist/require-declarative-element.d.ts +12 -0
- package/dist/require-declarative-element.js +12 -0
- package/dist/template-transforms/minimal-element-definition.d.ts +30 -2
- package/dist/template-transforms/minimal-element-definition.js +14 -3
- package/dist/template-transforms/nested-mapped-templates.d.ts +1 -1
- package/dist/template-transforms/nested-mapped-templates.js +4 -3
- package/dist/template-transforms/template-transform-type.d.ts +1 -1
- package/dist/template-transforms/transform-template.d.ts +1 -1
- package/dist/template-transforms/transform-template.js +17 -21
- package/dist/template-transforms/vir-css/css-transform.d.ts +3 -3
- package/dist/template-transforms/vir-css/css-transform.js +3 -2
- package/dist/template-transforms/vir-css/vir-css.d.ts +11 -2
- package/dist/template-transforms/vir-css/vir-css.js +11 -2
- package/dist/template-transforms/vir-html/html-interpolation.d.ts +9 -5
- package/dist/template-transforms/vir-html/html-transform.d.ts +3 -3
- package/dist/template-transforms/vir-html/html-transform.js +14 -12
- package/dist/template-transforms/vir-html/vir-html.d.ts +4 -2
- package/dist/template-transforms/vir-html/vir-html.js +4 -2
- package/dist/typed-event/typed-event.d.ts +42 -6
- package/dist/typed-event/typed-event.js +31 -28
- package/dist/util/lit-template.d.ts +6 -1
- package/dist/util/lit-template.js +10 -7
- package/dist/util/type.d.ts +5 -0
- package/package.json +37 -35
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
import { CallbackObservable, CallbackObservableInit } from 'observavir';
|
|
2
2
|
import { Constructor } from 'type-fest';
|
|
3
|
-
import { ElementVirStateSetup } from '../properties/element-vir-state-setup';
|
|
3
|
+
import { ElementVirStateSetup } from '../properties/element-vir-state-setup.js';
|
|
4
4
|
export type { AsyncValue } from 'observavir';
|
|
5
5
|
/** Class for constructing async props. Should not be referenced directly, use `AsyncProp` instead. */
|
|
6
|
-
declare class
|
|
6
|
+
declare class InternalAsyncPropClass<Value, Params> extends CallbackObservable<Value, Params> {
|
|
7
7
|
}
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* An async property created by {@link asyncProp} for use within declarative elements.
|
|
10
|
+
*
|
|
11
|
+
* @category Internal
|
|
12
|
+
*/
|
|
13
|
+
export type AsyncProp<Value, Params> = Omit<InternalAsyncPropClass<Value, Params>,
|
|
9
14
|
/** Hide these properties to make the `AsyncProp` interface much simpler. */
|
|
10
15
|
'dispatch' | 'equalityCheck' | 'getListenerCount' | 'updateCallback' | 'removeListener' | 'removeAllListeners' | 'listenToEvent' | 'listen'>;
|
|
11
|
-
|
|
16
|
+
/**
|
|
17
|
+
* An async property created by {@link asyncProp} for use within declarative elements.
|
|
18
|
+
*
|
|
19
|
+
* @category Internal
|
|
20
|
+
*/
|
|
21
|
+
export declare const AsyncProp: Constructor<AsyncProp<unknown, unknown>, ConstructorParameters<typeof InternalAsyncPropClass<unknown, unknown>>>;
|
|
22
|
+
/**
|
|
23
|
+
* Create an async prop for a declarative element's state.
|
|
24
|
+
*
|
|
25
|
+
* @category Async
|
|
26
|
+
*/
|
|
12
27
|
export declare function asyncProp<Value, Params = void>(init?: CallbackObservableInit<Value, Params>): ElementVirStateSetup<AsyncProp<Value, Params>>;
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import { CallbackObservable } from 'observavir';
|
|
2
|
-
import { stateSetupKey } from '../properties/element-vir-state-setup';
|
|
2
|
+
import { stateSetupKey } from '../properties/element-vir-state-setup.js';
|
|
3
3
|
/** Class for constructing async props. Should not be referenced directly, use `AsyncProp` instead. */
|
|
4
|
-
class
|
|
4
|
+
class InternalAsyncPropClass extends CallbackObservable {
|
|
5
5
|
}
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* An async property created by {@link asyncProp} for use within declarative elements.
|
|
8
|
+
*
|
|
9
|
+
* @category Internal
|
|
10
|
+
*/
|
|
11
|
+
export const AsyncProp = InternalAsyncPropClass;
|
|
12
|
+
/**
|
|
13
|
+
* Create an async prop for a declarative element's state.
|
|
14
|
+
*
|
|
15
|
+
* @category Async
|
|
16
|
+
*/
|
|
7
17
|
export function asyncProp(init) {
|
|
8
18
|
return {
|
|
9
19
|
[stateSetupKey]() {
|
|
10
|
-
return new
|
|
20
|
+
return new InternalAsyncPropClass(init);
|
|
11
21
|
},
|
|
12
22
|
};
|
|
13
23
|
}
|
|
@@ -1,13 +1,28 @@
|
|
|
1
|
-
import { PartInfo } from '../../lit-exports/all-lit-exports';
|
|
1
|
+
import { PartInfo } from '../../lit-exports/all-lit-exports.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a lit directive that used simply for setting attributes on its parent element.
|
|
4
|
+
*
|
|
5
|
+
* @category Internal
|
|
6
|
+
*/
|
|
2
7
|
export declare function createAttributeDirective(attributeName: string): {
|
|
3
|
-
|
|
4
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Creates a string for use with the
|
|
10
|
+
* [`querySelector`](https://developer.mozilla.org/docs/Web/API/Document/querySelector) API
|
|
11
|
+
* that selects this directive's attribute set to the given `attributeValue`.
|
|
12
|
+
*/
|
|
13
|
+
attributeSelector(this: void, attributeValue: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Instantiates the attribute directive. This must be used on an element inside of an HTML
|
|
16
|
+
* template.
|
|
17
|
+
*/
|
|
18
|
+
attributeDirective(this: void, attributeValue: string): import("lit-html/directive.js").DirectiveResult<{
|
|
5
19
|
new (partInfo: PartInfo): {
|
|
6
20
|
readonly element: Element;
|
|
7
21
|
render(attributeValue: string): symbol;
|
|
8
22
|
readonly _$isConnected: boolean;
|
|
9
|
-
update(_part: import("lit-html").Part, props: unknown
|
|
23
|
+
update(_part: import("lit-html").Part, props: Array<unknown>): unknown;
|
|
10
24
|
};
|
|
11
25
|
}>;
|
|
26
|
+
/** The name of the attribute used in the directive. */
|
|
12
27
|
attributeName: string;
|
|
13
28
|
};
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { directive, Directive, noChange } from '../../lit-exports/all-lit-exports';
|
|
2
|
-
import { extractElement } from './directive-helpers';
|
|
1
|
+
import { directive, Directive, noChange } from '../../lit-exports/all-lit-exports.js';
|
|
2
|
+
import { extractElement } from './directive-helpers.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a lit directive that used simply for setting attributes on its parent element.
|
|
5
|
+
*
|
|
6
|
+
* @category Internal
|
|
7
|
+
*/
|
|
3
8
|
export function createAttributeDirective(attributeName) {
|
|
4
9
|
const newDirective = directive(
|
|
5
10
|
/** @internal */
|
|
6
11
|
class extends Directive {
|
|
12
|
+
element;
|
|
7
13
|
constructor(partInfo) {
|
|
8
14
|
super(partInfo);
|
|
9
|
-
Object.defineProperty(this, "element", {
|
|
10
|
-
enumerable: true,
|
|
11
|
-
configurable: true,
|
|
12
|
-
writable: true,
|
|
13
|
-
value: void 0
|
|
14
|
-
});
|
|
15
15
|
this.element = extractElement(partInfo, attributeName);
|
|
16
16
|
}
|
|
17
17
|
render(attributeValue) {
|
|
@@ -20,12 +20,22 @@ export function createAttributeDirective(attributeName) {
|
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
22
|
return {
|
|
23
|
+
/**
|
|
24
|
+
* Creates a string for use with the
|
|
25
|
+
* [`querySelector`](https://developer.mozilla.org/docs/Web/API/Document/querySelector) API
|
|
26
|
+
* that selects this directive's attribute set to the given `attributeValue`.
|
|
27
|
+
*/
|
|
23
28
|
attributeSelector(attributeValue) {
|
|
24
29
|
return `[${attributeName}="${attributeValue}"]`;
|
|
25
30
|
},
|
|
31
|
+
/**
|
|
32
|
+
* Instantiates the attribute directive. This must be used on an element inside of an HTML
|
|
33
|
+
* template.
|
|
34
|
+
*/
|
|
26
35
|
attributeDirective(attributeValue) {
|
|
27
36
|
return newDirective(attributeValue);
|
|
28
37
|
},
|
|
38
|
+
/** The name of the attribute used in the directive. */
|
|
29
39
|
attributeName,
|
|
30
40
|
};
|
|
31
41
|
}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
-
import { ElementPartInfo, PartInfo } from '../../lit-exports/all-lit-exports';
|
|
2
|
-
/**
|
|
3
|
-
|
|
1
|
+
import { ElementPartInfo, PartInfo } from '../../lit-exports/all-lit-exports.js';
|
|
2
|
+
/**
|
|
3
|
+
* The full type for `ElementPartInfo` because `lit`'s built-in type leaves out of most of its
|
|
4
|
+
* interface.
|
|
5
|
+
*
|
|
6
|
+
* @category Internal
|
|
7
|
+
*/
|
|
8
|
+
export type FullElementPartInfo = ElementPartInfo /** For some reason these aren't defined in lit's types already, even though they _do_ exist. */ & {
|
|
4
9
|
element: Element;
|
|
5
10
|
options: {
|
|
6
11
|
host: Element;
|
|
@@ -8,5 +13,15 @@ export type ExtraPartInfoProperties = {
|
|
|
8
13
|
isConnected: boolean;
|
|
9
14
|
};
|
|
10
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Extracts the element from the given part info. Used in lit directives.
|
|
18
|
+
*
|
|
19
|
+
* @category Internal
|
|
20
|
+
*/
|
|
11
21
|
export declare function extractElement(partInfo: PartInfo, directiveName: string): Element;
|
|
12
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Asserts that the given part info is an instance of {@link FullElementPartInfo}.
|
|
24
|
+
*
|
|
25
|
+
* @category Internal
|
|
26
|
+
*/
|
|
27
|
+
export declare function assertIsElementPartInfo(partInfo: PartInfo, directiveName: string): asserts partInfo is FullElementPartInfo;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import { PartType } from '../../lit-exports/all-lit-exports';
|
|
1
|
+
import { PartType } from '../../lit-exports/all-lit-exports.js';
|
|
2
|
+
/**
|
|
3
|
+
* Extracts the element from the given part info. Used in lit directives.
|
|
4
|
+
*
|
|
5
|
+
* @category Internal
|
|
6
|
+
*/
|
|
2
7
|
export function extractElement(partInfo, directiveName) {
|
|
3
8
|
assertIsElementPartInfo(partInfo, directiveName);
|
|
4
9
|
const element = partInfo.element;
|
|
@@ -6,19 +11,26 @@ export function extractElement(partInfo, directiveName) {
|
|
|
6
11
|
}
|
|
7
12
|
function getPartHostTagName(partInfo) {
|
|
8
13
|
try {
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
9
15
|
const tagName = partInfo.options.host.tagName.toLowerCase();
|
|
10
16
|
return tagName;
|
|
11
17
|
}
|
|
12
|
-
catch
|
|
18
|
+
catch {
|
|
13
19
|
return undefined;
|
|
14
20
|
}
|
|
15
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Asserts that the given part info is an instance of {@link FullElementPartInfo}.
|
|
24
|
+
*
|
|
25
|
+
* @category Internal
|
|
26
|
+
*/
|
|
16
27
|
export function assertIsElementPartInfo(partInfo, directiveName) {
|
|
17
28
|
const hostTagName = getPartHostTagName(partInfo);
|
|
18
29
|
const hostTagMessage = hostTagName ? `: in ${hostTagName}` : '';
|
|
19
30
|
if (partInfo.type !== PartType.ELEMENT) {
|
|
20
31
|
throw new Error(`${directiveName} directive can only be attached directly to an element${hostTagMessage}.`);
|
|
21
32
|
}
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
22
34
|
if (!partInfo.element) {
|
|
23
35
|
throw new Error(`${directiveName} directive found no element${hostTagMessage}.`);
|
|
24
36
|
}
|
|
@@ -1,4 +1,110 @@
|
|
|
1
|
-
import { AsyncProp, AsyncValue } from './async-prop';
|
|
1
|
+
import { AsyncProp, AsyncValue } from './async-prop.js';
|
|
2
|
+
/**
|
|
3
|
+
* Checks and type guards that the given async value is resolved, meaning that it is no longer a
|
|
4
|
+
* promise. It may be an error though. This must be passed an {@link AsyncProp}'s `.value` property,
|
|
5
|
+
* not the async prop itself.
|
|
6
|
+
*
|
|
7
|
+
* @category Async
|
|
8
|
+
* @example
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import {waitValue, extractErrorMessage} from '@augment-vir/common';
|
|
12
|
+
* import {isResolved, html, defineElementNoInputs, asyncProp} from 'element-vir';
|
|
13
|
+
*
|
|
14
|
+
* const MyElement = defineElementNoInputs({
|
|
15
|
+
* tagName: 'my-element',
|
|
16
|
+
* stateInitStatic: {
|
|
17
|
+
* myProp: asyncProp({defaultValue: waitValue({seconds: 10}, 'value')}),
|
|
18
|
+
* },
|
|
19
|
+
* render({state}) {
|
|
20
|
+
* if (isAsyncError(state.myProp.value)) {
|
|
21
|
+
* return html`
|
|
22
|
+
* Error: ${extractErrorMessage(state.myProp.value)}
|
|
23
|
+
* `;
|
|
24
|
+
* } else if (isResolved(state.myProp.value)) {
|
|
25
|
+
* return html`
|
|
26
|
+
* Done!
|
|
27
|
+
* `;
|
|
28
|
+
* } else {
|
|
29
|
+
* return html`
|
|
30
|
+
* Still waiting...
|
|
31
|
+
* `;
|
|
32
|
+
* }
|
|
33
|
+
* },
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
2
37
|
export declare function isResolved<Value extends AsyncValue<any>>(asyncValue: Value extends AsyncProp<any, any> ? 'Error: pass AsyncProp.value, not AsyncProp itself.' : Value): asyncValue is Exclude<typeof asyncValue, Promise<any>>;
|
|
38
|
+
/**
|
|
39
|
+
* Checks and type guards that the given async value is an error, meaning that the async prop's
|
|
40
|
+
* promise was rejected. This must be passed an {@link AsyncProp}'s `.value` property, not the async
|
|
41
|
+
* prop itself.
|
|
42
|
+
*
|
|
43
|
+
* @category Async
|
|
44
|
+
* @example
|
|
45
|
+
*
|
|
46
|
+
* ```ts
|
|
47
|
+
* import {waitValue, extractErrorMessage} from '@augment-vir/common';
|
|
48
|
+
* import {isResolved, html, defineElementNoInputs, asyncProp} from 'element-vir';
|
|
49
|
+
*
|
|
50
|
+
* const MyElement = defineElementNoInputs({
|
|
51
|
+
* tagName: 'my-element',
|
|
52
|
+
* stateInitStatic: {
|
|
53
|
+
* myProp: asyncProp({defaultValue: waitValue({seconds: 10}, 'value')}),
|
|
54
|
+
* },
|
|
55
|
+
* render({state}) {
|
|
56
|
+
* if (isAsyncError(state.myProp.value)) {
|
|
57
|
+
* return html`
|
|
58
|
+
* Error: ${extractErrorMessage(state.myProp.value)}
|
|
59
|
+
* `;
|
|
60
|
+
* } else if (isResolved(state.myProp.value)) {
|
|
61
|
+
* return html`
|
|
62
|
+
* Done!
|
|
63
|
+
* `;
|
|
64
|
+
* } else {
|
|
65
|
+
* return html`
|
|
66
|
+
* Still waiting...
|
|
67
|
+
* `;
|
|
68
|
+
* }
|
|
69
|
+
* },
|
|
70
|
+
* });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
3
73
|
export declare function isAsyncError<Value extends AsyncValue<any>>(asyncValue: Value extends AsyncProp<any, any> ? 'Error: pass AsyncProp.value, not AsyncProp itself.' : Value): asyncValue is Extract<typeof asyncValue, Error>;
|
|
74
|
+
/**
|
|
75
|
+
* Same as {@link isResolved} but instead of a returning a boolean, it returns either the resolved
|
|
76
|
+
* value or `undefined`.
|
|
77
|
+
*
|
|
78
|
+
* @category Async
|
|
79
|
+
* @example
|
|
80
|
+
*
|
|
81
|
+
* ```ts
|
|
82
|
+
* import {waitValue, extractErrorMessage} from '@augment-vir/common';
|
|
83
|
+
* import {isResolved, html, defineElementNoInputs, asyncProp} from 'element-vir';
|
|
84
|
+
*
|
|
85
|
+
* const MyElement = defineElementNoInputs({
|
|
86
|
+
* tagName: 'my-element',
|
|
87
|
+
* stateInitStatic: {
|
|
88
|
+
* myProp: asyncProp({defaultValue: waitValue({seconds: 10}, 'value')}),
|
|
89
|
+
* },
|
|
90
|
+
* render({state}) {
|
|
91
|
+
* const resolvedValue = resolvedOrUndefined(state.myProp.value);
|
|
92
|
+
*
|
|
93
|
+
* if (!resolvedValue) {
|
|
94
|
+
* return html`
|
|
95
|
+
* Still waiting...
|
|
96
|
+
* `;
|
|
97
|
+
* } else if (isAsyncError(resolvedValue)) {
|
|
98
|
+
* return html`
|
|
99
|
+
* Error: ${extractErrorMessage(state.myProp.value)}
|
|
100
|
+
* `;
|
|
101
|
+
* }
|
|
102
|
+
*
|
|
103
|
+
* return html`
|
|
104
|
+
* Value: ${resolvedValue}
|
|
105
|
+
* `;
|
|
106
|
+
* },
|
|
107
|
+
* });
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
4
110
|
export declare function resolvedOrUndefined<Value extends AsyncValue<any>>(asyncValue: Value extends AsyncProp<any, any> ? 'Error: pass AsyncProp.value, not AsyncProp itself.' : Value): Exclude<typeof asyncValue, Promise<any>> | undefined;
|
|
@@ -1,16 +1,122 @@
|
|
|
1
|
-
import { AsyncProp } from './async-prop';
|
|
1
|
+
import { AsyncProp } from './async-prop.js';
|
|
2
|
+
/**
|
|
3
|
+
* Checks and type guards that the given async value is resolved, meaning that it is no longer a
|
|
4
|
+
* promise. It may be an error though. This must be passed an {@link AsyncProp}'s `.value` property,
|
|
5
|
+
* not the async prop itself.
|
|
6
|
+
*
|
|
7
|
+
* @category Async
|
|
8
|
+
* @example
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* import {waitValue, extractErrorMessage} from '@augment-vir/common';
|
|
12
|
+
* import {isResolved, html, defineElementNoInputs, asyncProp} from 'element-vir';
|
|
13
|
+
*
|
|
14
|
+
* const MyElement = defineElementNoInputs({
|
|
15
|
+
* tagName: 'my-element',
|
|
16
|
+
* stateInitStatic: {
|
|
17
|
+
* myProp: asyncProp({defaultValue: waitValue({seconds: 10}, 'value')}),
|
|
18
|
+
* },
|
|
19
|
+
* render({state}) {
|
|
20
|
+
* if (isAsyncError(state.myProp.value)) {
|
|
21
|
+
* return html`
|
|
22
|
+
* Error: ${extractErrorMessage(state.myProp.value)}
|
|
23
|
+
* `;
|
|
24
|
+
* } else if (isResolved(state.myProp.value)) {
|
|
25
|
+
* return html`
|
|
26
|
+
* Done!
|
|
27
|
+
* `;
|
|
28
|
+
* } else {
|
|
29
|
+
* return html`
|
|
30
|
+
* Still waiting...
|
|
31
|
+
* `;
|
|
32
|
+
* }
|
|
33
|
+
* },
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
2
37
|
export function isResolved(asyncValue) {
|
|
3
38
|
if (asyncValue instanceof AsyncProp) {
|
|
4
39
|
throw new TypeError('Pass AsyncProp.value, not AsyncProp itself.');
|
|
5
40
|
}
|
|
6
41
|
return !(asyncValue instanceof Promise);
|
|
7
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Checks and type guards that the given async value is an error, meaning that the async prop's
|
|
45
|
+
* promise was rejected. This must be passed an {@link AsyncProp}'s `.value` property, not the async
|
|
46
|
+
* prop itself.
|
|
47
|
+
*
|
|
48
|
+
* @category Async
|
|
49
|
+
* @example
|
|
50
|
+
*
|
|
51
|
+
* ```ts
|
|
52
|
+
* import {waitValue, extractErrorMessage} from '@augment-vir/common';
|
|
53
|
+
* import {isResolved, html, defineElementNoInputs, asyncProp} from 'element-vir';
|
|
54
|
+
*
|
|
55
|
+
* const MyElement = defineElementNoInputs({
|
|
56
|
+
* tagName: 'my-element',
|
|
57
|
+
* stateInitStatic: {
|
|
58
|
+
* myProp: asyncProp({defaultValue: waitValue({seconds: 10}, 'value')}),
|
|
59
|
+
* },
|
|
60
|
+
* render({state}) {
|
|
61
|
+
* if (isAsyncError(state.myProp.value)) {
|
|
62
|
+
* return html`
|
|
63
|
+
* Error: ${extractErrorMessage(state.myProp.value)}
|
|
64
|
+
* `;
|
|
65
|
+
* } else if (isResolved(state.myProp.value)) {
|
|
66
|
+
* return html`
|
|
67
|
+
* Done!
|
|
68
|
+
* `;
|
|
69
|
+
* } else {
|
|
70
|
+
* return html`
|
|
71
|
+
* Still waiting...
|
|
72
|
+
* `;
|
|
73
|
+
* }
|
|
74
|
+
* },
|
|
75
|
+
* });
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
8
78
|
export function isAsyncError(asyncValue) {
|
|
9
79
|
if (asyncValue instanceof AsyncProp) {
|
|
10
80
|
throw new TypeError('Pass AsyncProp.value, not AsyncProp itself.');
|
|
11
81
|
}
|
|
12
82
|
return asyncValue instanceof Error;
|
|
13
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Same as {@link isResolved} but instead of a returning a boolean, it returns either the resolved
|
|
86
|
+
* value or `undefined`.
|
|
87
|
+
*
|
|
88
|
+
* @category Async
|
|
89
|
+
* @example
|
|
90
|
+
*
|
|
91
|
+
* ```ts
|
|
92
|
+
* import {waitValue, extractErrorMessage} from '@augment-vir/common';
|
|
93
|
+
* import {isResolved, html, defineElementNoInputs, asyncProp} from 'element-vir';
|
|
94
|
+
*
|
|
95
|
+
* const MyElement = defineElementNoInputs({
|
|
96
|
+
* tagName: 'my-element',
|
|
97
|
+
* stateInitStatic: {
|
|
98
|
+
* myProp: asyncProp({defaultValue: waitValue({seconds: 10}, 'value')}),
|
|
99
|
+
* },
|
|
100
|
+
* render({state}) {
|
|
101
|
+
* const resolvedValue = resolvedOrUndefined(state.myProp.value);
|
|
102
|
+
*
|
|
103
|
+
* if (!resolvedValue) {
|
|
104
|
+
* return html`
|
|
105
|
+
* Still waiting...
|
|
106
|
+
* `;
|
|
107
|
+
* } else if (isAsyncError(resolvedValue)) {
|
|
108
|
+
* return html`
|
|
109
|
+
* Error: ${extractErrorMessage(state.myProp.value)}
|
|
110
|
+
* `;
|
|
111
|
+
* }
|
|
112
|
+
*
|
|
113
|
+
* return html`
|
|
114
|
+
* Value: ${resolvedValue}
|
|
115
|
+
* `;
|
|
116
|
+
* },
|
|
117
|
+
* });
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
14
120
|
export function resolvedOrUndefined(asyncValue) {
|
|
15
121
|
if (isResolved(asyncValue)) {
|
|
16
122
|
return asyncValue;
|
|
@@ -1,18 +1,92 @@
|
|
|
1
1
|
import { MaybePromise } from '@augment-vir/common';
|
|
2
|
-
import { DirectiveResult } from '../../lit-exports/all-lit-exports';
|
|
3
|
-
import { DefinedTypedEvent, TypedEvent } from '../../typed-event/typed-event';
|
|
2
|
+
import { DirectiveResult } from '../../lit-exports/all-lit-exports.js';
|
|
3
|
+
import { DefinedTypedEvent, TypedEvent } from '../../typed-event/typed-event.js';
|
|
4
4
|
/** We don't care at all what this returns, just allow anything! */
|
|
5
5
|
type ListenCallbackReturn = MaybePromise<any>;
|
|
6
6
|
/**
|
|
7
7
|
* Listen to events. These can be native DOM events (use a string for the inputType argument) or
|
|
8
|
-
* typed events (pass in a return value from defineTypedEvent).
|
|
8
|
+
* typed events (pass in a return value from {@link defineTypedEvent}).
|
|
9
9
|
*
|
|
10
|
-
* @
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
10
|
+
* @category Directives
|
|
11
|
+
* @example
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* import {html, defineElementNoInputs, listen} from 'element-vir';
|
|
15
|
+
*
|
|
16
|
+
* const MyElement = defineElementNoInputs({
|
|
17
|
+
* tagName: 'my-element',
|
|
18
|
+
* render() {
|
|
19
|
+
* return html`
|
|
20
|
+
* <div
|
|
21
|
+
* ${listen('click', () => {
|
|
22
|
+
* console.log('clicked!');
|
|
23
|
+
* })}
|
|
24
|
+
* >
|
|
25
|
+
* Some div
|
|
26
|
+
* </div>
|
|
27
|
+
* <${MyOtherElement}
|
|
28
|
+
* ${listen(MyOtherElement.events.someEvent, (event) => {
|
|
29
|
+
* console.log('event value', event.detail);
|
|
30
|
+
* })}
|
|
31
|
+
* ></${MyOtherElement}>
|
|
32
|
+
* `;
|
|
33
|
+
* },
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function listen<TypedEventTypeNameGeneric extends string, TypedEventDetailGeneric>(
|
|
38
|
+
/**
|
|
39
|
+
* Needs to come either from a declarative element (like MyDeclarativeElement.events.eventName),
|
|
40
|
+
* from a typed event created via the {@link defineTypedEvent} function, or be the name of a
|
|
41
|
+
* built-in event (like `'click'`).
|
|
42
|
+
*/
|
|
43
|
+
eventType: DefinedTypedEvent<TypedEventTypeNameGeneric, TypedEventDetailGeneric>,
|
|
44
|
+
/**
|
|
45
|
+
* The callback to fire when an event is caught. Assuming the {@link defineTypedEvent} input is
|
|
46
|
+
* properly typed, the event given to this callback will also be typed.
|
|
47
|
+
*/
|
|
48
|
+
listener: (event: TypedEvent<TypedEventTypeNameGeneric, TypedEventDetailGeneric>) => ListenCallbackReturn): DirectiveResult<any>;
|
|
49
|
+
/**
|
|
50
|
+
* Listen to events. These can be native DOM events (use a string for the inputType argument) or
|
|
51
|
+
* typed events (pass in a return value from {@link defineTypedEvent}).
|
|
52
|
+
*
|
|
53
|
+
* @category Directives
|
|
54
|
+
* @example
|
|
55
|
+
*
|
|
56
|
+
* ```ts
|
|
57
|
+
* import {html, defineElementNoInputs, listen} from 'element-vir';
|
|
58
|
+
*
|
|
59
|
+
* const MyElement = defineElementNoInputs({
|
|
60
|
+
* tagName: 'my-element',
|
|
61
|
+
* render() {
|
|
62
|
+
* return html`
|
|
63
|
+
* <div
|
|
64
|
+
* ${listen('click', () => {
|
|
65
|
+
* console.log('clicked!');
|
|
66
|
+
* })}
|
|
67
|
+
* >
|
|
68
|
+
* Some div
|
|
69
|
+
* </div>
|
|
70
|
+
* <${MyOtherElement}
|
|
71
|
+
* ${listen(MyOtherElement.events.someEvent, (event) => {
|
|
72
|
+
* console.log('event value', event.detail);
|
|
73
|
+
* })}
|
|
74
|
+
* ></${MyOtherElement}>
|
|
75
|
+
* `;
|
|
76
|
+
* },
|
|
77
|
+
* });
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export declare function listen<NativeElementEventNameGeneric extends keyof HTMLElementEventMap>(
|
|
81
|
+
/**
|
|
82
|
+
* Needs to come either from a declarative element (like MyDeclarativeElement.events.eventName),
|
|
83
|
+
* from a typed event created via the {@link defineTypedEvent} function, or be the name of a
|
|
84
|
+
* built-in event (like `'click'`).
|
|
85
|
+
*/
|
|
86
|
+
eventType: NativeElementEventNameGeneric,
|
|
87
|
+
/**
|
|
88
|
+
* The callback to fire when an event is caught. Assuming the {@link defineTypedEvent} input is
|
|
89
|
+
* properly typed, the event given to this callback will also be typed.
|
|
15
90
|
*/
|
|
16
|
-
|
|
17
|
-
export declare function listen<TypedEventTypeNameGeneric extends string, TypedEventDetailGeneric, NativeElementEventNameGeneric extends keyof HTMLElementEventMap>(eventType: NativeElementEventNameGeneric, listener: (event: HTMLElementEventMap[NativeElementEventNameGeneric]) => ListenCallbackReturn): DirectiveResult<any>;
|
|
91
|
+
listener: (event: HTMLElementEventMap[NativeElementEventNameGeneric]) => ListenCallbackReturn): DirectiveResult<any>;
|
|
18
92
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { directive, Directive, noChange, } from '../../lit-exports/all-lit-exports';
|
|
2
|
-
import { extractElement } from './directive-helpers';
|
|
1
|
+
import { directive, Directive, noChange, } from '../../lit-exports/all-lit-exports.js';
|
|
2
|
+
import { extractElement } from './directive-helpers.js';
|
|
3
3
|
export function listen(eventType, listener) {
|
|
4
4
|
return listenDirective(eventType, listener);
|
|
5
5
|
}
|
|
@@ -8,20 +8,10 @@ export function listen(eventType, listener) {
|
|
|
8
8
|
* call is wrapped in the function above.
|
|
9
9
|
*/
|
|
10
10
|
const listenDirective = directive(class extends Directive {
|
|
11
|
+
element;
|
|
12
|
+
lastListenerMetaData;
|
|
11
13
|
constructor(partInfo) {
|
|
12
14
|
super(partInfo);
|
|
13
|
-
Object.defineProperty(this, "element", {
|
|
14
|
-
enumerable: true,
|
|
15
|
-
configurable: true,
|
|
16
|
-
writable: true,
|
|
17
|
-
value: void 0
|
|
18
|
-
});
|
|
19
|
-
Object.defineProperty(this, "lastListenerMetaData", {
|
|
20
|
-
enumerable: true,
|
|
21
|
-
configurable: true,
|
|
22
|
-
writable: true,
|
|
23
|
-
value: void 0
|
|
24
|
-
});
|
|
25
15
|
this.element = extractElement(partInfo, 'listen');
|
|
26
16
|
}
|
|
27
17
|
resetListener(listenerMetaData) {
|
|
@@ -41,7 +31,7 @@ const listenDirective = directive(class extends Directive {
|
|
|
41
31
|
render(eventTypeInput, callback) {
|
|
42
32
|
const eventType = typeof eventTypeInput === 'string' ? eventTypeInput : eventTypeInput.type;
|
|
43
33
|
if (typeof eventType !== 'string') {
|
|
44
|
-
throw new
|
|
34
|
+
throw new TypeError(`Cannot listen to an event with a name that is not a string. Given event name: '${String(eventType)}'`);
|
|
45
35
|
}
|
|
46
36
|
if (this.lastListenerMetaData && this.lastListenerMetaData.eventType === eventType) {
|
|
47
37
|
/**
|
|
@@ -1,7 +1,40 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
|
|
1
|
+
import type { MaybePromise } from '@augment-vir/common';
|
|
2
|
+
import { PartInfo } from '../../lit-exports/all-lit-exports.js';
|
|
3
|
+
/**
|
|
4
|
+
* The callback / listener passed to {@link onDomCreated}. The `element` parameter is a reference to
|
|
5
|
+
* the DOM element that the directive was attached to.
|
|
6
|
+
*
|
|
7
|
+
* @category Internal
|
|
8
|
+
*/
|
|
9
|
+
export type OnDomCreatedCallback = (element: Element) => MaybePromise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* A directive that fires its listener only once, when the element that it's attached to is
|
|
12
|
+
* constructed. This is particularly useful for getting references to internal elements immediately
|
|
13
|
+
* after they've rendered.
|
|
14
|
+
*
|
|
15
|
+
* @category Directives
|
|
16
|
+
* @example
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* import {html, defineElementNoInputs, onDomCreated} from 'element-vir';
|
|
20
|
+
*
|
|
21
|
+
* const MyElement = defineElementNoInputs({
|
|
22
|
+
* tagName: 'my-element',
|
|
23
|
+
* render() {
|
|
24
|
+
* return html`
|
|
25
|
+
* <div
|
|
26
|
+
* ${onDomCreated((element) => {
|
|
27
|
+
* console.log('created!', element);
|
|
28
|
+
* })}
|
|
29
|
+
* >
|
|
30
|
+
* Some div
|
|
31
|
+
* </div>
|
|
32
|
+
* `;
|
|
33
|
+
* },
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare const onDomCreated: (callback: OnDomCreatedCallback) => import("lit-html/directive.js").DirectiveResult<{
|
|
5
38
|
new (partInfo: PartInfo): {
|
|
6
39
|
element: Element | undefined;
|
|
7
40
|
update(partInfo: PartInfo, [callback]: [OnDomCreatedCallback]): undefined;
|