element-vir 7.0.0 → 7.0.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.
- package/dist/augments/array.d.ts +2 -0
- package/dist/augments/array.js +3 -0
- package/dist/augments/type.d.ts +9 -0
- package/dist/augments/type.js +13 -0
- package/dist/declarative-element/declarative-element-init.d.ts +45 -0
- package/dist/declarative-element/declarative-element-init.js +1 -0
- package/dist/declarative-element/declarative-element.d.ts +49 -0
- package/dist/declarative-element/declarative-element.js +18 -0
- package/dist/declarative-element/define-element-no-inputs.d.ts +6 -0
- package/dist/declarative-element/define-element-no-inputs.js +133 -0
- package/dist/declarative-element/define-element.d.ts +6 -0
- package/dist/declarative-element/define-element.js +13 -0
- package/dist/declarative-element/definition-options.d.ts +6 -0
- package/dist/declarative-element/definition-options.js +4 -0
- package/dist/declarative-element/directives/assign-with-clean-up.directive.d.ts +24 -0
- package/dist/declarative-element/directives/assign-with-clean-up.directive.js +43 -0
- package/dist/declarative-element/directives/assign.directive.d.ts +13 -0
- package/dist/declarative-element/directives/assign.directive.js +28 -0
- package/dist/declarative-element/directives/directive-helpers.d.ts +15 -0
- package/dist/declarative-element/directives/directive-helpers.js +21 -0
- package/dist/declarative-element/directives/listen.directive.d.ts +15 -0
- package/dist/declarative-element/directives/listen.directive.js +47 -0
- package/dist/declarative-element/directives/on-dom-created.directive.d.ts +12 -0
- package/dist/declarative-element/directives/on-dom-created.directive.js +23 -0
- package/dist/declarative-element/directives/on-resize.directive.d.ts +16 -0
- package/dist/declarative-element/directives/on-resize.directive.js +36 -0
- package/dist/declarative-element/directives/render-async-prop.directive.d.ts +10 -0
- package/dist/declarative-element/directives/render-async-prop.directive.js +12 -0
- package/dist/declarative-element/directives/render-if.directive.d.ts +2 -0
- package/dist/declarative-element/directives/render-if.directive.js +4 -0
- package/dist/declarative-element/has-declarative-element-parent.d.ts +2 -0
- package/dist/declarative-element/has-declarative-element-parent.js +16 -0
- package/dist/declarative-element/properties/async-prop.d.ts +27 -0
- package/dist/declarative-element/properties/async-prop.js +102 -0
- package/dist/declarative-element/properties/css-vars.d.ts +7 -0
- package/dist/declarative-element/properties/css-vars.js +22 -0
- package/dist/declarative-element/properties/element-events.d.ts +11 -0
- package/dist/declarative-element/properties/element-events.js +24 -0
- package/dist/declarative-element/properties/element-properties.d.ts +15 -0
- package/dist/declarative-element/properties/element-properties.js +21 -0
- package/dist/declarative-element/properties/element-updater-proxy.d.ts +4 -0
- package/dist/declarative-element/properties/element-updater-proxy.js +56 -0
- package/dist/declarative-element/properties/host-classes.d.ts +22 -0
- package/dist/declarative-element/properties/host-classes.js +12 -0
- package/dist/declarative-element/properties/styles.d.ts +24 -0
- package/dist/declarative-element/properties/styles.js +32 -0
- package/dist/declarative-element/properties/tag-name.d.ts +3 -0
- package/dist/declarative-element/properties/tag-name.js +4 -0
- package/dist/declarative-element/render-callback.d.ts +27 -0
- package/dist/declarative-element/render-callback.js +31 -0
- package/dist/declarative-element-marker-symbol.d.ts +2 -0
- package/dist/declarative-element-marker-symbol.js +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +19 -0
- package/dist/require-declarative-element.d.ts +3 -0
- package/dist/require-declarative-element.js +4 -0
- package/dist/template-transforms/has-static-tag-name.d.ts +5 -0
- package/dist/template-transforms/has-static-tag-name.js +6 -0
- package/dist/template-transforms/nested-mapped-templates.d.ts +7 -0
- package/dist/template-transforms/nested-mapped-templates.js +96 -0
- package/dist/template-transforms/transform-template.d.ts +17 -0
- package/dist/template-transforms/transform-template.js +87 -0
- package/dist/template-transforms/vir-css/css-transform.d.ts +8 -0
- package/dist/template-transforms/vir-css/css-transform.js +12 -0
- package/dist/template-transforms/vir-css/vir-css.d.ts +4 -0
- package/dist/template-transforms/vir-css/vir-css.js +12 -0
- package/dist/template-transforms/vir-html/html-transform.d.ts +4 -0
- package/dist/template-transforms/vir-html/html-transform.js +44 -0
- package/dist/template-transforms/vir-html/vir-html.d.ts +4 -0
- package/dist/template-transforms/vir-html/vir-html.js +16 -0
- package/dist/typed-event/typed-event.d.ts +20 -0
- package/dist/typed-event/typed-event.js +32 -0
- package/package.json +2 -2
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { directive, Directive } from 'lit/directive.js';
|
|
2
|
+
import { assertIsElementPartInfo } from './directive-helpers';
|
|
3
|
+
const directiveName = 'onResize';
|
|
4
|
+
export const onResize = directive(class extends Directive {
|
|
5
|
+
constructor(partInfo) {
|
|
6
|
+
super(partInfo);
|
|
7
|
+
this.resizeObserver = new ResizeObserver((entries) => this.fireCallback(entries));
|
|
8
|
+
assertIsElementPartInfo(partInfo, directiveName);
|
|
9
|
+
}
|
|
10
|
+
fireCallback(entries) {
|
|
11
|
+
var _a;
|
|
12
|
+
const resizeEntry = entries[0];
|
|
13
|
+
if (!resizeEntry) {
|
|
14
|
+
console.error(entries);
|
|
15
|
+
throw new Error(`${directiveName} observation triggered but the first entry was empty.`);
|
|
16
|
+
}
|
|
17
|
+
(_a = this.callback) === null || _a === void 0 ? void 0 : _a.call(this, { target: resizeEntry.target, contentRect: resizeEntry.contentRect });
|
|
18
|
+
}
|
|
19
|
+
update(partInfo, [callback]) {
|
|
20
|
+
assertIsElementPartInfo(partInfo, directiveName);
|
|
21
|
+
this.callback = callback;
|
|
22
|
+
const newElement = partInfo.element;
|
|
23
|
+
// if the element changes we need to observe the new one
|
|
24
|
+
if (newElement !== this.element) {
|
|
25
|
+
if (this.element) {
|
|
26
|
+
this.resizeObserver.unobserve(this.element);
|
|
27
|
+
}
|
|
28
|
+
this.resizeObserver.observe(newElement);
|
|
29
|
+
this.element = newElement;
|
|
30
|
+
}
|
|
31
|
+
return this.render(callback);
|
|
32
|
+
}
|
|
33
|
+
render(callback) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { UnPromise } from '@augment-vir/common';
|
|
2
|
+
import { AsyncProp } from '../properties/async-prop';
|
|
3
|
+
export declare function renderAsyncProp<T>({ asyncProp, fallback, resolutionRender, errorRender, }: {
|
|
4
|
+
asyncProp: AsyncProp<T>;
|
|
5
|
+
/** This value will be rendered if the async state has not settled yet. */
|
|
6
|
+
fallback: unknown;
|
|
7
|
+
resolutionRender: (resolved: UnPromise<T>) => unknown;
|
|
8
|
+
errorRender?: (error: Error) => unknown;
|
|
9
|
+
}): unknown;
|
|
10
|
+
//# sourceMappingURL=render-async-prop.directive.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { extractErrorMessage } from '@augment-vir/common';
|
|
2
|
+
export function renderAsyncProp({ asyncProp, fallback, resolutionRender, errorRender, }) {
|
|
3
|
+
if (asyncProp === null || asyncProp === void 0 ? void 0 : asyncProp.error) {
|
|
4
|
+
return errorRender ? errorRender(asyncProp.error) : extractErrorMessage(asyncProp.error);
|
|
5
|
+
}
|
|
6
|
+
else if (asyncProp === null || asyncProp === void 0 ? void 0 : asyncProp.resolution) {
|
|
7
|
+
return resolutionRender(asyncProp.resolution);
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
return fallback;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { DeclarativeElement } from './declarative-element';
|
|
2
|
+
export function hasDeclarativeElementParent(input) {
|
|
3
|
+
const rootNode = input.getRootNode();
|
|
4
|
+
if (!(rootNode instanceof ShadowRoot)) {
|
|
5
|
+
// declarative elements all use shadow DOM, so if a shadow root doesn't exist then we're not
|
|
6
|
+
// in a declarative element.
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
const host = rootNode.host;
|
|
10
|
+
if (host instanceof DeclarativeElement) {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
return hasDeclarativeElementParent(host);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { UnPromise } from '@augment-vir/common';
|
|
2
|
+
import { JsonValue } from 'type-fest';
|
|
3
|
+
export type AsyncProp<ValueGeneric> = {
|
|
4
|
+
error?: Error;
|
|
5
|
+
promise?: Promise<UnPromise<ValueGeneric>>;
|
|
6
|
+
resolution?: UnPromise<ValueGeneric>;
|
|
7
|
+
isChainedAlready?: true;
|
|
8
|
+
lastTrigger?: JsonValue;
|
|
9
|
+
} | undefined | null;
|
|
10
|
+
declare const unsetSymbol: unique symbol;
|
|
11
|
+
export declare function asyncProp<ValueGeneric>(initialValue?: UnPromise<ValueGeneric> | Promise<UnPromise<ValueGeneric>> | typeof unsetSymbol): AsyncProp<ValueGeneric>;
|
|
12
|
+
export type SetAsyncPropInputs<ValueGeneric> = {
|
|
13
|
+
updateIfThisChanges?: JsonValue;
|
|
14
|
+
} & ({
|
|
15
|
+
createPromise: () => Promise<UnPromise<ValueGeneric>>;
|
|
16
|
+
} | {
|
|
17
|
+
resolution: UnPromise<ValueGeneric>;
|
|
18
|
+
} | {
|
|
19
|
+
promise: Promise<UnPromise<ValueGeneric>>;
|
|
20
|
+
});
|
|
21
|
+
export declare function ensureAsyncProp<ValueGeneric, StatePropGeneric extends PropertyKey>({ state, stateProp, updateState: inputUpdateState, ...newValue }: {
|
|
22
|
+
state: Record<StatePropGeneric, AsyncProp<ValueGeneric>>;
|
|
23
|
+
stateProp: StatePropGeneric;
|
|
24
|
+
updateState: (newState: Record<StatePropGeneric, AsyncProp<ValueGeneric>>) => void;
|
|
25
|
+
} & SetAsyncPropInputs<ValueGeneric>): void;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=async-prop.d.ts.map
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { areJsonEqual, ensureError, isPromiseLike, typedHasProperty, } from '@augment-vir/common';
|
|
2
|
+
const unsetSymbol = Symbol('unset');
|
|
3
|
+
export function asyncProp(initialValue = unsetSymbol) {
|
|
4
|
+
if (initialValue === unsetSymbol) {
|
|
5
|
+
return undefined;
|
|
6
|
+
}
|
|
7
|
+
else if (isPromiseLike(initialValue)) {
|
|
8
|
+
return {
|
|
9
|
+
promise: initialValue,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
return {
|
|
14
|
+
resolution: initialValue,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function shouldForceUpdate(newValue, currentValue) {
|
|
19
|
+
if (!currentValue) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
if (typedHasProperty(newValue, 'updateIfThisChanges')) {
|
|
23
|
+
if (typedHasProperty(currentValue, 'lastTrigger')) {
|
|
24
|
+
return !areJsonEqual(currentValue.lastTrigger, newValue.updateIfThisChanges);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
export function ensureAsyncProp({ state, stateProp, updateState: inputUpdateState, ...newValue }) {
|
|
33
|
+
function updateState(newStateValue) {
|
|
34
|
+
/**
|
|
35
|
+
* As cast needed here because the RecordGeneric type isn't strong enough to narrow its keys
|
|
36
|
+
* to StatePropGeneric, it just thinks they're all strings
|
|
37
|
+
*/
|
|
38
|
+
inputUpdateState({ [stateProp]: newStateValue });
|
|
39
|
+
}
|
|
40
|
+
const forceUpdate = shouldForceUpdate(newValue, state[stateProp]);
|
|
41
|
+
const currentValue = forceUpdate ? undefined : state[stateProp];
|
|
42
|
+
if (currentValue === null || currentValue === void 0 ? void 0 : currentValue.error) {
|
|
43
|
+
// abort if there's an error
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (currentValue && 'resolution' in currentValue) {
|
|
47
|
+
// abort if the async value has already been resolved
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const lastTriggerObject = typedHasProperty(newValue, 'updateIfThisChanges')
|
|
51
|
+
? { lastTrigger: newValue.updateIfThisChanges }
|
|
52
|
+
: {};
|
|
53
|
+
// if given a resolution value, set that
|
|
54
|
+
if ('resolution' in newValue) {
|
|
55
|
+
return updateState({
|
|
56
|
+
resolution: newValue.resolution,
|
|
57
|
+
...lastTriggerObject,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
// if there is no promise or resolution, set a promise
|
|
61
|
+
const needsNewPromise = currentValue == undefined || !('promise' in currentValue);
|
|
62
|
+
const needsChaining = currentValue == undefined || !currentValue.isChainedAlready;
|
|
63
|
+
if (!needsNewPromise && !needsChaining) {
|
|
64
|
+
// abort, there is nothing to do
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const newPromise = needsNewPromise
|
|
68
|
+
? 'promise' in newValue
|
|
69
|
+
? newValue.promise
|
|
70
|
+
: 'createPromise' in newValue
|
|
71
|
+
? newValue.createPromise()
|
|
72
|
+
: undefined
|
|
73
|
+
: undefined;
|
|
74
|
+
if (needsNewPromise && !newPromise) {
|
|
75
|
+
throw new Error(`Was not able to create a new promise for state.${String(stateProp)}: missing "promise" or "createPromise" key for ${ensureAsyncProp.name}`);
|
|
76
|
+
}
|
|
77
|
+
const promiseToChain = newPromise !== null && newPromise !== void 0 ? newPromise : currentValue === null || currentValue === void 0 ? void 0 : currentValue.promise;
|
|
78
|
+
if (!promiseToChain) {
|
|
79
|
+
// at this point there is definitely a promise to chain
|
|
80
|
+
throw new Error('Failed to find promise to chain.');
|
|
81
|
+
}
|
|
82
|
+
promiseToChain
|
|
83
|
+
.then((value) => {
|
|
84
|
+
updateState({
|
|
85
|
+
promise: promiseToChain,
|
|
86
|
+
resolution: value,
|
|
87
|
+
...lastTriggerObject,
|
|
88
|
+
});
|
|
89
|
+
})
|
|
90
|
+
.catch((error) => {
|
|
91
|
+
updateState({
|
|
92
|
+
promise: promiseToChain,
|
|
93
|
+
error: ensureError(error),
|
|
94
|
+
...lastTriggerObject,
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
updateState({
|
|
98
|
+
promise: promiseToChain,
|
|
99
|
+
isChainedAlready: true,
|
|
100
|
+
...lastTriggerObject,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CSSResult } from 'lit';
|
|
2
|
+
export type CssVarsInitMap<CssVarKeys extends string> = Record<CssVarKeys, string | CSSResult>;
|
|
3
|
+
export type CssVarName<TagName extends string> = `--${TagName}-string`;
|
|
4
|
+
export type CssVarNameOrValueMap<CssVarKeys extends string> = Record<CssVarKeys, CSSResult>;
|
|
5
|
+
export declare function createCssVarNamesMap<TagName extends string, CssVarKeys extends string>(tagName: TagName, cssVarsInit: CssVarsInitMap<CssVarKeys> | undefined): CssVarNameOrValueMap<CssVarKeys>;
|
|
6
|
+
export declare function createCssVarValuesMap<CssVarKeys extends string>(cssVarInitMap: CssVarsInitMap<CssVarKeys> | undefined, cssVarNamesMap: CssVarNameOrValueMap<CssVarKeys>): CssVarNameOrValueMap<CssVarKeys>;
|
|
7
|
+
//# sourceMappingURL=css-vars.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { mapObjectValues } from '@augment-vir/common';
|
|
2
|
+
import { unsafeCSS } from 'lit';
|
|
3
|
+
import { toHtmlSafeWithTagName } from './tag-name';
|
|
4
|
+
export function createCssVarNamesMap(tagName, cssVarsInit) {
|
|
5
|
+
if (cssVarsInit) {
|
|
6
|
+
return mapObjectValues(cssVarsInit, (key) => {
|
|
7
|
+
return unsafeCSS(`--${toHtmlSafeWithTagName(tagName, String(key))}`);
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
return {};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export function createCssVarValuesMap(cssVarInitMap, cssVarNamesMap) {
|
|
15
|
+
if (!cssVarInitMap) {
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
return mapObjectValues(cssVarInitMap, (key, fallbackValue) => {
|
|
19
|
+
const name = cssVarNamesMap[key];
|
|
20
|
+
return unsafeCSS(`var(${name}, ${fallbackValue})`);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DefinedTypedEvent, DefinedTypedEventNameDefinition, TypedEvent } from '../../typed-event/typed-event';
|
|
2
|
+
export type EventsInitMap = Record<string, DefinedTypedEventNameDefinition<any>>;
|
|
3
|
+
export declare function defineElementEvent<EventDetailGeneric>(): DefinedTypedEventNameDefinition<EventDetailGeneric>;
|
|
4
|
+
export type EventInitMapEventDetailExtractor<EventTypeNameGeneric extends keyof EventsInitGeneric, EventsInitGeneric extends EventsInitMap> = EventsInitGeneric[EventTypeNameGeneric] extends DefinedTypedEventNameDefinition<infer R> ? R : never;
|
|
5
|
+
export type EventDescriptorMap<EventsInitGeneric extends EventsInitMap> = {
|
|
6
|
+
[CurrentEventTypeName in keyof EventsInitGeneric]: DefinedTypedEvent<CurrentEventTypeName extends string ? CurrentEventTypeName : never, EventInitMapEventDetailExtractor<CurrentEventTypeName, EventsInitGeneric>>;
|
|
7
|
+
};
|
|
8
|
+
export type EventObjectEventDetailExtractor<EventObjectGeneric extends DefinedTypedEvent<any, any>> = EventObjectGeneric extends DefinedTypedEvent<string, infer R> ? R : never;
|
|
9
|
+
export type ElementEventDetailExtractor<ElementEventGeneric extends TypedEvent<any, any>> = ElementEventGeneric extends TypedEvent<string, infer R> ? R : never;
|
|
10
|
+
export declare function createEventDescriptorMap<EventsInitGeneric extends EventsInitMap>(eventsInit: EventsInitGeneric | undefined): EventDescriptorMap<EventsInitGeneric>;
|
|
11
|
+
//# sourceMappingURL=element-events.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { defineTypedEvent, } from '../../typed-event/typed-event';
|
|
2
|
+
export function defineElementEvent() {
|
|
3
|
+
return defineTypedEvent();
|
|
4
|
+
}
|
|
5
|
+
export function createEventDescriptorMap(eventsInit) {
|
|
6
|
+
if (!eventsInit) {
|
|
7
|
+
return {};
|
|
8
|
+
}
|
|
9
|
+
return Object.keys(eventsInit)
|
|
10
|
+
.filter((currentElementEventKey) => {
|
|
11
|
+
if (typeof currentElementEventKey !== 'string') {
|
|
12
|
+
throw new Error(`Expected event key of type string but got type "${typeof currentElementEventKey}" for key ${String(currentElementEventKey)}`);
|
|
13
|
+
}
|
|
14
|
+
if (currentElementEventKey === '') {
|
|
15
|
+
throw new Error(`Got empty string for events key.`);
|
|
16
|
+
}
|
|
17
|
+
return true;
|
|
18
|
+
})
|
|
19
|
+
.reduce((accum, currentElementEventKey) => {
|
|
20
|
+
const eventObject = defineTypedEvent()(currentElementEventKey);
|
|
21
|
+
accum[currentElementEventKey] = eventObject;
|
|
22
|
+
return accum;
|
|
23
|
+
}, {});
|
|
24
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
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
|
+
export type StaticElementPropertyDescriptor<PropName extends string, PropValue> = {
|
|
8
|
+
propName: PropName;
|
|
9
|
+
initValue: PropValue;
|
|
10
|
+
};
|
|
11
|
+
export type ElementPropertyDescriptorMap<PropertyInitGeneric extends PropertyInitMapBase> = {
|
|
12
|
+
[Property in keyof PropertyInitGeneric]: StaticElementPropertyDescriptor<string, PropertyInitGeneric[Property]>;
|
|
13
|
+
};
|
|
14
|
+
export declare function createPropertyDescriptorMap<PropertyInitGeneric extends PropertyInitMapBase>(propertyInit: PropertyInitGeneric | undefined): ElementPropertyDescriptorMap<PropertyInitGeneric>;
|
|
15
|
+
//# sourceMappingURL=element-properties.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { DeclarativeElement } from '../declarative-element';
|
|
2
|
+
import { PropertyInitMapBase } from './element-properties';
|
|
3
|
+
export declare function createElementUpdaterProxy<PropertyInitGeneric extends PropertyInitMapBase>(element: DeclarativeElement, verifyExists: boolean): PropertyInitGeneric;
|
|
4
|
+
//# sourceMappingURL=element-updater-proxy.d.ts.map
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
function assertValidPropertyName(propKey, element, elementTagName) {
|
|
2
|
+
if (typeof propKey !== 'string' && typeof propKey !== 'number' && typeof propKey !== 'symbol') {
|
|
3
|
+
throw new Error(`Property name must be a string, got type "${typeof propKey}" from: "${String(propKey)}" for ${elementTagName.toLowerCase()}`);
|
|
4
|
+
}
|
|
5
|
+
if (!(propKey in element)) {
|
|
6
|
+
throw new Error(`Property "${String(propKey)}" does not exist on ${elementTagName.toLowerCase()}.`);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export function createElementUpdaterProxy(element, verifyExists) {
|
|
10
|
+
/**
|
|
11
|
+
* Lit element updates state and inputs by setting them directly on the element, so we must do
|
|
12
|
+
* that here. DeclarativeElement's types, however, do not expose this behavior, so we add that
|
|
13
|
+
* back in here.
|
|
14
|
+
*/
|
|
15
|
+
const elementAsProps = element;
|
|
16
|
+
const propsProxy = new Proxy({}, {
|
|
17
|
+
get: (target, propertyName) => {
|
|
18
|
+
if (verifyExists) {
|
|
19
|
+
assertValidPropertyName(propertyName, element, element.tagName);
|
|
20
|
+
}
|
|
21
|
+
return elementAsProps[propertyName];
|
|
22
|
+
},
|
|
23
|
+
set: (target, propertyName, newValue) => {
|
|
24
|
+
if (verifyExists) {
|
|
25
|
+
assertValidPropertyName(propertyName, element, element.tagName);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Don't worry about storing the value (no need to have duplicates of teh values) but at
|
|
29
|
+
* least set the property on target so we can detect it in "ownKeys" and
|
|
30
|
+
* "getOwnPropertyDescriptor".
|
|
31
|
+
*/
|
|
32
|
+
target[propertyName] = undefined;
|
|
33
|
+
elementAsProps[propertyName] = newValue;
|
|
34
|
+
return true;
|
|
35
|
+
},
|
|
36
|
+
ownKeys: (target) => {
|
|
37
|
+
return Reflect.ownKeys(target);
|
|
38
|
+
},
|
|
39
|
+
getOwnPropertyDescriptor(target, propertyName) {
|
|
40
|
+
if (propertyName in target) {
|
|
41
|
+
return {
|
|
42
|
+
get value() {
|
|
43
|
+
return elementAsProps[propertyName];
|
|
44
|
+
},
|
|
45
|
+
configurable: true,
|
|
46
|
+
enumerable: true,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
return undefined;
|
|
50
|
+
},
|
|
51
|
+
has: (target, propertyName) => {
|
|
52
|
+
return Reflect.has(target, propertyName);
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
return propsProxy;
|
|
56
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { PropertyInitMapBase } from './element-properties';
|
|
2
|
+
import { WithTagName } from './tag-name';
|
|
3
|
+
export type HostClassToggleCallbackInput<InputsGeneric extends PropertyInitMapBase, StateGeneric extends PropertyInitMapBase> = {
|
|
4
|
+
state: Readonly<StateGeneric>;
|
|
5
|
+
inputs: Readonly<InputsGeneric>;
|
|
6
|
+
};
|
|
7
|
+
export type HostClassToggleCallback<InputsGeneric extends PropertyInitMapBase, StateGeneric extends PropertyInitMapBase> = (inputs: HostClassToggleCallbackInput<InputsGeneric, StateGeneric>) => boolean;
|
|
8
|
+
export type HostClassesInitMap<HostClassKeys extends string, InputsGeneric extends PropertyInitMapBase, StateGeneric extends PropertyInitMapBase> = Record<HostClassKeys,
|
|
9
|
+
/**
|
|
10
|
+
* Callback to determine when host class should be enabled (based on current inputs and state),
|
|
11
|
+
* or just undefined to mark that this host class name will only be manually applied.
|
|
12
|
+
*/
|
|
13
|
+
HostClassToggleCallback<InputsGeneric, StateGeneric> | false>;
|
|
14
|
+
export type HostClassName<TagName extends string, HostClassPropName extends string> = `${TagName}-${HostClassPropName}`;
|
|
15
|
+
export type HostClassNamesMap<TagName extends string, HostClassKeys extends string> = Record<HostClassKeys, WithTagName<TagName, string>>;
|
|
16
|
+
export declare function createHostClassNamesMap<TagName extends string, HostClassKeys extends string, HostClassesInitGeneric extends HostClassesInitMap<HostClassKeys,
|
|
17
|
+
/**
|
|
18
|
+
* We can use any here because we don't care what the state or input names are, we just care
|
|
19
|
+
* what the host class names are
|
|
20
|
+
*/
|
|
21
|
+
any, any>>(tagName: TagName, hostClassesInit?: HostClassesInitGeneric): HostClassNamesMap<TagName, HostClassKeys>;
|
|
22
|
+
//# sourceMappingURL=host-classes.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { mapObjectValues } from '@augment-vir/common';
|
|
2
|
+
import { toHtmlSafeWithTagName } from './tag-name';
|
|
3
|
+
export function createHostClassNamesMap(tagName, hostClassesInit) {
|
|
4
|
+
if (hostClassesInit) {
|
|
5
|
+
return mapObjectValues(hostClassesInit, (key) => {
|
|
6
|
+
return toHtmlSafeWithTagName(tagName, String(key));
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
return {};
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { CSSResult } from 'lit';
|
|
2
|
+
import { CssVarNameOrValueMap } from './css-vars';
|
|
3
|
+
import { PropertyInitMapBase } from './element-properties';
|
|
4
|
+
import { HostClassesInitMap, HostClassNamesMap } from './host-classes';
|
|
5
|
+
export type StylesCallbackInput<HostClassKeys extends string, CssVarKeys extends string> = {
|
|
6
|
+
hostClassSelectors: Record<HostClassKeys, CSSResult>;
|
|
7
|
+
hostClassNames: Record<HostClassKeys, CSSResult>;
|
|
8
|
+
cssVarNames: Record<CssVarKeys, CSSResult>;
|
|
9
|
+
cssVarValues: Record<CssVarKeys, CSSResult>;
|
|
10
|
+
};
|
|
11
|
+
export type StylesCallback<HostClassKeys extends string, CssVarKeys extends string> = (input: StylesCallbackInput<HostClassKeys, CssVarKeys>) => CSSResult;
|
|
12
|
+
export declare function hostClassNamesToStylesInput<HostClassKeys extends string, CssVarKeys extends string>({ hostClassNames, cssVarNames, cssVarValues, }: {
|
|
13
|
+
hostClassNames: HostClassNamesMap<string, HostClassKeys>;
|
|
14
|
+
cssVarNames: CssVarNameOrValueMap<CssVarKeys>;
|
|
15
|
+
cssVarValues: CssVarNameOrValueMap<CssVarKeys>;
|
|
16
|
+
}): StylesCallbackInput<HostClassKeys, CssVarKeys>;
|
|
17
|
+
export declare function applyHostClasses<InputsGeneric extends PropertyInitMapBase, StateGeneric extends PropertyInitMapBase, HostClassKeys extends string>({ host, hostClassesInit, hostClassNames, state, inputs, }: {
|
|
18
|
+
host: HTMLElement;
|
|
19
|
+
hostClassesInit: Readonly<HostClassesInitMap<HostClassKeys, InputsGeneric, StateGeneric>> | undefined;
|
|
20
|
+
hostClassNames: HostClassNamesMap<string, HostClassKeys>;
|
|
21
|
+
state: Readonly<StateGeneric>;
|
|
22
|
+
inputs: Readonly<InputsGeneric>;
|
|
23
|
+
}): void;
|
|
24
|
+
//# sourceMappingURL=styles.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { getObjectTypedKeys, mapObjectValues } from '@augment-vir/common';
|
|
2
|
+
import { unsafeCSS } from 'lit';
|
|
3
|
+
export function hostClassNamesToStylesInput({ hostClassNames, cssVarNames, cssVarValues, }) {
|
|
4
|
+
return {
|
|
5
|
+
hostClassSelectors: mapObjectValues(hostClassNames, (key, name) => {
|
|
6
|
+
return unsafeCSS(`:host(.${name})`);
|
|
7
|
+
}),
|
|
8
|
+
hostClassNames: mapObjectValues(hostClassNames, (key, name) => {
|
|
9
|
+
return unsafeCSS(name);
|
|
10
|
+
}),
|
|
11
|
+
cssVarNames: cssVarNames,
|
|
12
|
+
cssVarValues: cssVarValues,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export function applyHostClasses({ host, hostClassesInit, hostClassNames, state, inputs, }) {
|
|
16
|
+
if (!hostClassesInit) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
getObjectTypedKeys(hostClassesInit).forEach((hostClassKey) => {
|
|
20
|
+
const maybeCallback = hostClassesInit[hostClassKey];
|
|
21
|
+
const hostClassName = hostClassNames[hostClassKey];
|
|
22
|
+
if (typeof maybeCallback === 'function') {
|
|
23
|
+
const shouldApplyHostClass = maybeCallback({ state, inputs });
|
|
24
|
+
if (shouldApplyHostClass) {
|
|
25
|
+
host.classList.add(hostClassName);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
host.classList.remove(hostClassName);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export type WithTagName<TagName extends string, Suffix extends string> = `${TagName}-${Suffix}`;
|
|
2
|
+
export declare function toHtmlSafeWithTagName<TagName extends string>(tagName: TagName, forHtmlSafe: string): WithTagName<TagName, string>;
|
|
3
|
+
//# sourceMappingURL=tag-name.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { TemplateResult } from 'lit';
|
|
2
|
+
import { TypedEvent } from '../typed-event/typed-event';
|
|
3
|
+
import { DeclarativeElement, HostInstanceType } from './declarative-element';
|
|
4
|
+
import { AsyncProp, SetAsyncPropInputs } from './properties/async-prop';
|
|
5
|
+
import { EventDescriptorMap, EventInitMapEventDetailExtractor, EventsInitMap } from './properties/element-events';
|
|
6
|
+
import { PropertyInitMapBase } from './properties/element-properties';
|
|
7
|
+
export type RenderCallback<InputsGeneric extends PropertyInitMapBase = any, StateGeneric extends PropertyInitMapBase = any, EventsInitGeneric extends EventsInitMap = any, HostClassKeys extends string = any, CssVarKeys extends string = any> = (params: RenderParams<InputsGeneric, StateGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>) => TemplateResult;
|
|
8
|
+
export type InitCallback<InputsGeneric extends PropertyInitMapBase, StateGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string> = (params: RenderParams<InputsGeneric, StateGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>) => void;
|
|
9
|
+
export type UpdateStateCallback<StateGeneric extends PropertyInitMapBase> = (newState: Partial<StateGeneric>) => void;
|
|
10
|
+
export type RenderParams<InputsGeneric extends PropertyInitMapBase, StateInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string> = {
|
|
11
|
+
state: Readonly<StateInitGeneric>;
|
|
12
|
+
updateState: UpdateStateCallback<StateInitGeneric>;
|
|
13
|
+
events: EventDescriptorMap<EventsInitGeneric>;
|
|
14
|
+
host: HostInstanceType<InputsGeneric, StateInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
|
|
15
|
+
dispatch: <EventTypeNameGeneric extends keyof EventsInitGeneric>(event: TypedEvent<EventTypeNameGeneric extends string ? EventTypeNameGeneric : never, EventInitMapEventDetailExtractor<EventTypeNameGeneric, EventsInitGeneric>> | Event) => boolean;
|
|
16
|
+
inputs: InputsGeneric;
|
|
17
|
+
/**
|
|
18
|
+
* Updates async props in the state if they have not already been set. Once promises settle,
|
|
19
|
+
* this automatically updates the state. In order to re-trigger an async prop, set it to
|
|
20
|
+
* undefined first.
|
|
21
|
+
*/
|
|
22
|
+
ensureAsyncProp: (values: Partial<{
|
|
23
|
+
[StateKey in keyof StateInitGeneric as StateInitGeneric[StateKey] extends AsyncProp<any> ? StateKey : never]: StateInitGeneric[StateKey] extends AsyncProp<infer ValueGeneric> ? SetAsyncPropInputs<ValueGeneric> : never;
|
|
24
|
+
}>) => void;
|
|
25
|
+
};
|
|
26
|
+
export declare function createRenderParams<InputsGeneric extends PropertyInitMapBase, StateGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string>(element: DeclarativeElement<InputsGeneric, StateGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>, eventsMap: EventDescriptorMap<EventsInitGeneric>): RenderParams<InputsGeneric, StateGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
|
|
27
|
+
//# sourceMappingURL=render-callback.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { getObjectTypedKeys } from '@augment-vir/common';
|
|
2
|
+
import { ensureAsyncProp } from './properties/async-prop';
|
|
3
|
+
export function createRenderParams(element, eventsMap) {
|
|
4
|
+
function updateState(partialProps) {
|
|
5
|
+
getObjectTypedKeys(partialProps).forEach((propKey) => {
|
|
6
|
+
element.instanceState[propKey] = partialProps[propKey];
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
const renderParams = {
|
|
10
|
+
dispatch: (event) => element.dispatchEvent(event),
|
|
11
|
+
updateState,
|
|
12
|
+
inputs: element.instanceInputs,
|
|
13
|
+
host: element,
|
|
14
|
+
state: element.instanceState,
|
|
15
|
+
events: eventsMap,
|
|
16
|
+
ensureAsyncProp: (values) => {
|
|
17
|
+
Object.entries(values).forEach(([stateKey, newSet,]) => {
|
|
18
|
+
if (!(stateKey in element.instanceState)) {
|
|
19
|
+
throw new Error(`Invalid key given to ensureAsyncProp: ${stateKey}`);
|
|
20
|
+
}
|
|
21
|
+
ensureAsyncProp({
|
|
22
|
+
state: element.instanceState,
|
|
23
|
+
updateState: updateState,
|
|
24
|
+
stateProp: stateKey,
|
|
25
|
+
...newSet,
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
return renderParams;
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const DeclarativeElementMarkerSymbol = Symbol('this-is-an-element-vir-declarative-element');
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export * from './declarative-element/declarative-element';
|
|
2
|
+
export * from './declarative-element/define-element';
|
|
3
|
+
export * from './declarative-element/define-element-no-inputs';
|
|
4
|
+
export type { DeclarativeElementDefinitionOptions } from './declarative-element/definition-options';
|
|
5
|
+
export * from './declarative-element/directives/assign-with-clean-up.directive';
|
|
6
|
+
export * from './declarative-element/directives/assign.directive';
|
|
7
|
+
export * from './declarative-element/directives/directive-helpers';
|
|
8
|
+
export * from './declarative-element/directives/listen.directive';
|
|
9
|
+
export * from './declarative-element/directives/on-dom-created.directive';
|
|
10
|
+
export * from './declarative-element/directives/on-resize.directive';
|
|
11
|
+
export * from './declarative-element/directives/render-async-prop.directive';
|
|
12
|
+
export * from './declarative-element/directives/render-if.directive';
|
|
13
|
+
export * from './declarative-element/properties/async-prop';
|
|
14
|
+
export * from './declarative-element/properties/element-events';
|
|
15
|
+
export * from './declarative-element/properties/element-properties';
|
|
16
|
+
export * from './declarative-element/render-callback';
|
|
17
|
+
export { requireAllCustomElementsToBeDeclarativeElements } from './require-declarative-element';
|
|
18
|
+
export * from './template-transforms/vir-css/vir-css';
|
|
19
|
+
export * from './template-transforms/vir-html/vir-html';
|
|
20
|
+
export * from './typed-event/typed-event';
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export * from './declarative-element/declarative-element';
|
|
2
|
+
export * from './declarative-element/define-element';
|
|
3
|
+
export * from './declarative-element/define-element-no-inputs';
|
|
4
|
+
export * from './declarative-element/directives/assign-with-clean-up.directive';
|
|
5
|
+
export * from './declarative-element/directives/assign.directive';
|
|
6
|
+
export * from './declarative-element/directives/directive-helpers';
|
|
7
|
+
export * from './declarative-element/directives/listen.directive';
|
|
8
|
+
export * from './declarative-element/directives/on-dom-created.directive';
|
|
9
|
+
export * from './declarative-element/directives/on-resize.directive';
|
|
10
|
+
export * from './declarative-element/directives/render-async-prop.directive';
|
|
11
|
+
export * from './declarative-element/directives/render-if.directive';
|
|
12
|
+
export * from './declarative-element/properties/async-prop';
|
|
13
|
+
export * from './declarative-element/properties/element-events';
|
|
14
|
+
export * from './declarative-element/properties/element-properties';
|
|
15
|
+
export * from './declarative-element/render-callback';
|
|
16
|
+
export { requireAllCustomElementsToBeDeclarativeElements } from './require-declarative-element';
|
|
17
|
+
export * from './template-transforms/vir-css/vir-css';
|
|
18
|
+
export * from './template-transforms/vir-html/vir-html';
|
|
19
|
+
export * from './typed-event/typed-event';
|