element-vir 26.15.0 → 26.16.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 +1 -1
- package/dist/declarative-element/declarative-element-init.d.ts +9 -14
- package/dist/declarative-element/declarative-element.d.ts +6 -6
- package/dist/declarative-element/define-element.d.ts +1 -1
- package/dist/declarative-element/define-element.js +7 -17
- package/dist/declarative-element/directives/on-resize.directive.js +1 -1
- package/dist/declarative-element/properties/element-events.js +1 -1
- package/dist/declarative-element/properties/string-names.d.ts +23 -1
- package/dist/declarative-element/properties/string-names.js +35 -1
- package/dist/declarative-element/properties/styles.d.ts +8 -5
- package/dist/declarative-element/properties/styles.js +4 -1
- package/dist/declarative-element/render-callback.d.ts +3 -3
- package/dist/lit-exports/lit-repeat-fix.d.ts +1 -1
- package/dist/readme-examples/my-custom-define.js +1 -1
- package/dist/template-transforms/nested-mapped-templates.js +3 -3
- package/dist/template-transforms/vir-html/html-interpolation.d.ts +8 -2
- package/dist/util/increment.d.ts +8 -2
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -523,7 +523,7 @@ export const defineVirElement = wrapDefineElement<VirTagName>();
|
|
|
523
523
|
export const defineVerifiedVirElement = wrapDefineElement<VirTagName>({
|
|
524
524
|
assertInputs: (inputs) => {
|
|
525
525
|
if (!inputs.tagName.startsWith('vir-')) {
|
|
526
|
-
throw new Error(
|
|
526
|
+
throw new Error('all custom elements must start with "vir-"');
|
|
527
527
|
}
|
|
528
528
|
},
|
|
529
529
|
});
|
|
@@ -14,17 +14,23 @@ import { type InitCallback, type RenderCallback, type RenderParams } from './ren
|
|
|
14
14
|
*
|
|
15
15
|
* @category Internal
|
|
16
16
|
*/
|
|
17
|
-
export type DeclarativeElementInit<TagName extends CustomElementTagName, Inputs extends PropertyInitMapBase, State extends PropertyInitMapBase, EventsInit extends EventsInitMap, HostClassKeys extends BaseStringName<TagName
|
|
17
|
+
export type DeclarativeElementInit<TagName extends CustomElementTagName, Inputs extends PropertyInitMapBase, State extends PropertyInitMapBase, EventsInit extends EventsInitMap, HostClassKeys extends BaseStringName<NoInfer<TagName>>, CssVarKeys extends BaseStringName<NoInfer<TagName>>, SlotNames extends ReadonlyArray<string>, TestIds extends ReadonlyArray<string>> = {
|
|
18
18
|
/**
|
|
19
19
|
* HTML tag name. This should not be used directly, as interpolating it with the html tagged
|
|
20
20
|
* template from this package is preferred.
|
|
21
21
|
*/
|
|
22
22
|
tagName: TagName;
|
|
23
23
|
/** Static styles. These should not and cannot change. */
|
|
24
|
-
styles?: CSSResult | StylesCallback<TagName, HostClassKeys, CssVarKeys> | undefined;
|
|
24
|
+
styles?: CSSResult | StylesCallback<TagName, HostClassKeys, CssVarKeys, SlotNames> | undefined;
|
|
25
25
|
/** Events that the element can dispatch. (These can be thought of as "outputs".) */
|
|
26
26
|
events?: EventsInit | undefined;
|
|
27
|
-
|
|
27
|
+
/**
|
|
28
|
+
* An array of slot names that for type safe usage in rendering HTML, CSS, and in consumers for
|
|
29
|
+
* assigning slots. Each slot name must be prefixed with the element's tag name. This prefix is
|
|
30
|
+
* enforced at compile time only: runtimes accept any strings so existing consumers do not
|
|
31
|
+
* break.
|
|
32
|
+
*/
|
|
33
|
+
slotNames?: (SlotNames & ReadonlyArray<BaseStringName<TagName>>) | undefined;
|
|
28
34
|
testIds?: TestIds | undefined;
|
|
29
35
|
/**
|
|
30
36
|
* HTML host classes. Values can be callbacks to determine when a host class should be defined,
|
|
@@ -50,17 +56,6 @@ export type DeclarativeElementInit<TagName extends CustomElementTagName, Inputs
|
|
|
50
56
|
state?: (params: Omit<RenderParams<TagName, Inputs, any, EventsInit, HostClassKeys, CssVarKeys, SlotNames, TestIds>, 'state' | 'updateState'>) => Extract<keyof State, keyof HTMLElement> extends never ? Extract<keyof State, keyof Inputs> extends never ? State : `ERROR: Cannot define an element state property that clashes with input properties: ${Extract<keyof State, keyof Inputs> extends string | number | bigint | boolean | null | undefined ? Extract<keyof State, keyof Inputs> : ''}` : `ERROR: Cannot define an element state property that clashes with native HTMLElement properties: ${Extract<keyof State, keyof HTMLElement>}`;
|
|
51
57
|
/** Called as part of the first render call, before the first render call. */
|
|
52
58
|
init?: InitCallback<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames, TestIds> | undefined;
|
|
53
|
-
/**
|
|
54
|
-
* Optional callback to create a cache key from the current inputs and state. When provided, and
|
|
55
|
-
* the callback returns a non-undefined and non-null value, the element's render output is
|
|
56
|
-
* automatically wrapped in {@link keyedCache}, preserving DOM state (typed input values,
|
|
57
|
-
* checkbox state, etc.) across key changes. If `undefined` or `null` are returned,
|
|
58
|
-
* {@link keyedCache} will not be used.
|
|
59
|
-
*/
|
|
60
|
-
cacheKey?: ((params: Readonly<{
|
|
61
|
-
inputs: Readonly<Inputs>;
|
|
62
|
-
state: Readonly<State>;
|
|
63
|
-
}>) => PropertyKey | undefined | null) | undefined;
|
|
64
59
|
/** Called whenever an element updates. This creates the element's HTML. */
|
|
65
60
|
render: RenderCallback<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames, TestIds>;
|
|
66
61
|
/** Called whenever an element is detached from the DOM. */
|
|
@@ -10,7 +10,7 @@ import { type EventDescriptorMap, type EventsInitMap } from './properties/elemen
|
|
|
10
10
|
import { type PropertyInitMapBase } from './properties/element-properties.js';
|
|
11
11
|
import { type HostClassNamesMap } from './properties/host-classes.js';
|
|
12
12
|
import { type ObservableListenerMap } from './properties/property-proxy.js';
|
|
13
|
-
import { type BaseStringName, type StringNameMap } from './properties/string-names.js';
|
|
13
|
+
import { type BaseStringName, type SlotNamesMap, type StringNameMap } from './properties/string-names.js';
|
|
14
14
|
import { type RenderCallback, type RenderParams, type UpdateStateCallback } from './render-callback.js';
|
|
15
15
|
/**
|
|
16
16
|
* The `host` type for a declarative element. This references a declarative element instance's
|
|
@@ -18,13 +18,13 @@ import { type RenderCallback, type RenderParams, type UpdateStateCallback } from
|
|
|
18
18
|
*
|
|
19
19
|
* @category Internal
|
|
20
20
|
*/
|
|
21
|
-
export type DeclarativeElementHost<TagName extends CustomElementTagName = any, Inputs extends PropertyInitMapBase = any, State extends PropertyInitMapBase = any, EventsInit extends EventsInitMap = any, HostClassKeys extends BaseStringName<TagName
|
|
21
|
+
export type DeclarativeElementHost<TagName extends CustomElementTagName = any, Inputs extends PropertyInitMapBase = any, State extends PropertyInitMapBase = any, EventsInit extends EventsInitMap = any, HostClassKeys extends BaseStringName<NoInfer<TagName>> = any, CssVarKeys extends BaseStringName<NoInfer<TagName>> = any, SlotNames extends ReadonlyArray<string> = any, TestIds extends ReadonlyArray<string> = any> = SetRequiredAndNotNull<Omit<DeclarativeElement<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames, TestIds>, Exclude<keyof StaticDeclarativeElementProperties<any, any, any, any, any, any, any, any>, keyof HTMLElement>>, 'shadowRoot'>;
|
|
22
22
|
/**
|
|
23
23
|
* The full definition for a declarative element.
|
|
24
24
|
*
|
|
25
25
|
* @category Internal
|
|
26
26
|
*/
|
|
27
|
-
export type DeclarativeElementDefinition<TagName extends CustomElementTagName = any, Inputs extends PropertyInitMapBase = any, State extends PropertyInitMapBase = any, EventsInit extends EventsInitMap = any, HostClassKeys extends BaseStringName<TagName
|
|
27
|
+
export type DeclarativeElementDefinition<TagName extends CustomElementTagName = any, Inputs extends PropertyInitMapBase = any, State extends PropertyInitMapBase = any, EventsInit extends EventsInitMap = any, HostClassKeys extends BaseStringName<NoInfer<TagName>> = any, CssVarKeys extends BaseStringName<NoInfer<TagName>> = any, SlotNames extends ReadonlyArray<string> = any, TestIds extends ReadonlyArray<string> = any> = (new () => DeclarativeElementHost<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames, TestIds>) & StaticDeclarativeElementProperties<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames, TestIds> & {
|
|
28
28
|
InstanceType: DeclarativeElementHost<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames, TestIds>;
|
|
29
29
|
};
|
|
30
30
|
/**
|
|
@@ -32,7 +32,7 @@ export type DeclarativeElementDefinition<TagName extends CustomElementTagName =
|
|
|
32
32
|
*
|
|
33
33
|
* @category Internal
|
|
34
34
|
*/
|
|
35
|
-
export declare abstract class DeclarativeElement<TagName extends CustomElementTagName = any, Inputs extends PropertyInitMapBase = any, State extends PropertyInitMapBase = any, EventsInit extends EventsInitMap = any, HostClassKeys extends BaseStringName<TagName
|
|
35
|
+
export declare abstract class DeclarativeElement<TagName extends CustomElementTagName = any, Inputs extends PropertyInitMapBase = any, State extends PropertyInitMapBase = any, EventsInit extends EventsInitMap = any, HostClassKeys extends BaseStringName<NoInfer<TagName>> = any, CssVarKeys extends BaseStringName<NoInfer<TagName>> = any, SlotNames extends ReadonlyArray<string> = any, TestIds extends ReadonlyArray<string> = any> extends LitElement {
|
|
36
36
|
/**
|
|
37
37
|
* Assign inputs to an element instantiation. Use only on the opening tag.
|
|
38
38
|
*
|
|
@@ -93,14 +93,14 @@ export type AssignMethod<TagName extends CustomElementTagName, Inputs extends Pr
|
|
|
93
93
|
*
|
|
94
94
|
* @category Internal
|
|
95
95
|
*/
|
|
96
|
-
export type StaticDeclarativeElementProperties<TagName extends CustomElementTagName, Inputs extends PropertyInitMapBase, State extends PropertyInitMapBase, EventsInit extends EventsInitMap, HostClassKeys extends BaseStringName<TagName
|
|
96
|
+
export type StaticDeclarativeElementProperties<TagName extends CustomElementTagName, Inputs extends PropertyInitMapBase, State extends PropertyInitMapBase, EventsInit extends EventsInitMap, HostClassKeys extends BaseStringName<NoInfer<TagName>>, CssVarKeys extends BaseStringName<NoInfer<TagName>>, SlotNames extends ReadonlyArray<string>, TestIds extends ReadonlyArray<string>> = {
|
|
97
97
|
/** Assign inputs to an element directly on its interpolated tag. */
|
|
98
98
|
readonly assign: AssignMethod<TagName, Inputs>;
|
|
99
99
|
assignedInputs: Inputs | undefined;
|
|
100
100
|
/** Pass through the render callback for direct unit testability */
|
|
101
101
|
readonly render: RenderCallback<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames, TestIds>;
|
|
102
102
|
readonly events: EventDescriptorMap<TagName, EventsInit>;
|
|
103
|
-
readonly slotNames:
|
|
103
|
+
readonly slotNames: SlotNamesMap<SlotNames>;
|
|
104
104
|
readonly testIds: Readonly<StringNameMap<TagName, 'test-id', TestIds>>;
|
|
105
105
|
readonly init: DeclarativeElementInit<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames, TestIds>;
|
|
106
106
|
readonly elementOptions: DeclarativeElementDefinitionOptions;
|
|
@@ -38,4 +38,4 @@ export declare function defineElement<Inputs extends PropertyInitMapBase = {}>(
|
|
|
38
38
|
* These `errorParams` is present when there are problems with the `Inputs` type. If it is
|
|
39
39
|
* present, the error should be fixed. This should always be empty.
|
|
40
40
|
*/
|
|
41
|
-
...errorParams: DeclarativeElementInputErrorParams<Inputs>): <const TagName extends CustomElementTagName, State extends PropertyInitMapBase = {}, EventsInit extends EventsInitMap = {}, const HostClassKeys extends BaseStringName<TagName
|
|
41
|
+
...errorParams: DeclarativeElementInputErrorParams<Inputs>): <const TagName extends CustomElementTagName, State extends PropertyInitMapBase = {}, EventsInit extends EventsInitMap = {}, const HostClassKeys extends BaseStringName<NoInfer<TagName>> = `${NoInfer<TagName>}-`, const CssVarKeys extends BaseStringName<NoInfer<TagName>> = `${NoInfer<TagName>}-`, const SlotNames extends ReadonlyArray<string> = Readonly<[]>, const TestIds extends ReadonlyArray<string> = Readonly<[]>>(initInput: DeclarativeElementInit<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames, TestIds>) => DeclarativeElementDefinition<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames, TestIds>;
|
|
@@ -3,15 +3,13 @@ import { assert, check } from '@augment-vir/assert';
|
|
|
3
3
|
import { StringCase, ensureErrorAndPrependMessage, extractErrorMessage, getObjectTypedKeys, kebabCaseToCamelCase, } from '@augment-vir/common';
|
|
4
4
|
import { defineCssVars } from 'lit-css-vars';
|
|
5
5
|
import { css } from '../template-transforms/vir-css/vir-css.js';
|
|
6
|
-
import { html } from '../template-transforms/vir-html/vir-html.js';
|
|
7
6
|
import { DeclarativeElement, } from './declarative-element.js';
|
|
8
7
|
import { defaultDeclarativeElementDefinitionOptions, } from './definition-options.js';
|
|
9
|
-
import { keyedCache } from './directives/keyed-cache.directive.js';
|
|
10
8
|
import { assignInputs } from './properties/assign-inputs.js';
|
|
11
9
|
import { createEventDescriptorMap, } from './properties/element-events.js';
|
|
12
10
|
import { createHostClassNamesMap } from './properties/host-classes.js';
|
|
13
11
|
import { bindReactiveProperty, createElementPropertyProxy } from './properties/property-proxy.js';
|
|
14
|
-
import { assertValidStringNames, createStringNameMap, } from './properties/string-names.js';
|
|
12
|
+
import { assertValidStringNames, createSlotNamesMap, createStringNameMap, } from './properties/string-names.js';
|
|
15
13
|
import { applyHostClasses, createStylesCallbackInput } from './properties/styles.js';
|
|
16
14
|
import { createRenderParams } from './render-callback.js';
|
|
17
15
|
/**
|
|
@@ -72,10 +70,10 @@ function internalDefineElement(init) {
|
|
|
72
70
|
const eventsMap = createEventDescriptorMap(init.tagName, init.events);
|
|
73
71
|
const hostClassNames = createHostClassNamesMap(init.hostClasses);
|
|
74
72
|
if (init.hostClasses) {
|
|
75
|
-
assertValidStringNames(init.tagName, init.hostClasses);
|
|
73
|
+
assertValidStringNames(init.tagName, Object.keys(init.hostClasses));
|
|
76
74
|
}
|
|
77
75
|
if (init.cssVars) {
|
|
78
|
-
assertValidStringNames(init.tagName, init.cssVars);
|
|
76
|
+
assertValidStringNames(init.tagName, Object.keys(init.cssVars));
|
|
79
77
|
}
|
|
80
78
|
/**
|
|
81
79
|
* As casts here are to prevent defineCssVars from complaining that our CSS var names are too
|
|
@@ -84,12 +82,13 @@ function internalDefineElement(init) {
|
|
|
84
82
|
* specific types externally.)
|
|
85
83
|
*/
|
|
86
84
|
const cssVars = (init.cssVars ? defineCssVars(init.cssVars) : {});
|
|
87
|
-
const slotNamesMap =
|
|
85
|
+
const slotNamesMap = createSlotNamesMap(init.tagName, init.slotNames);
|
|
88
86
|
const testIdsMap = createStringNameMap(init.tagName, 'test-id', init.testIds);
|
|
89
87
|
const calculatedStyles = typeof init.styles === 'function'
|
|
90
88
|
? init.styles(createStylesCallbackInput({
|
|
91
89
|
hostClassNames,
|
|
92
90
|
cssVars,
|
|
91
|
+
slotNamesMap,
|
|
93
92
|
}))
|
|
94
93
|
: init.styles || css ``;
|
|
95
94
|
const typedRenderCallback = init.render;
|
|
@@ -162,19 +161,10 @@ function internalDefineElement(init) {
|
|
|
162
161
|
throw new TypeError('init cannot be asynchronous');
|
|
163
162
|
}
|
|
164
163
|
}
|
|
165
|
-
const
|
|
166
|
-
if (
|
|
164
|
+
const renderResult = typedRenderCallback(renderParams);
|
|
165
|
+
if (renderResult instanceof Promise) {
|
|
167
166
|
throw new TypeError('render cannot be asynchronous');
|
|
168
167
|
}
|
|
169
|
-
const computedCacheKey = init.cacheKey?.({
|
|
170
|
-
inputs: renderParams.inputs,
|
|
171
|
-
state: renderParams.state,
|
|
172
|
-
});
|
|
173
|
-
const renderResult = computedCacheKey == undefined
|
|
174
|
-
? rawRenderResult
|
|
175
|
-
: html `
|
|
176
|
-
${keyedCache(computedCacheKey, rawRenderResult)}
|
|
177
|
-
`;
|
|
178
168
|
applyHostClasses({
|
|
179
169
|
host: renderParams.host,
|
|
180
170
|
hostClassesInit: init.hostClasses,
|
|
@@ -64,7 +64,7 @@ function handleOnResizeCallback(element, callback, entries) {
|
|
|
64
64
|
const resizeEntry = entries[0];
|
|
65
65
|
if (!resizeEntry) {
|
|
66
66
|
console.error(entries);
|
|
67
|
-
throw new Error(
|
|
67
|
+
throw new Error('Resize observation triggered but the first entry was empty.');
|
|
68
68
|
}
|
|
69
69
|
void callback({
|
|
70
70
|
target: resizeEntry.target,
|
|
@@ -47,7 +47,7 @@ export function createEventDescriptorMap(tagName, eventsInit) {
|
|
|
47
47
|
throw new TypeError(`Expected event key of type string but got type '${typeof currentElementEventKey}' for key ${String(currentElementEventKey)}`);
|
|
48
48
|
}
|
|
49
49
|
else if (currentElementEventKey === '') {
|
|
50
|
-
throw new Error(
|
|
50
|
+
throw new Error('Got empty string for events key.');
|
|
51
51
|
}
|
|
52
52
|
return true;
|
|
53
53
|
})
|
|
@@ -11,7 +11,7 @@ export type BaseStringName<ElementTagName extends CustomElementTagName> = `${Ele
|
|
|
11
11
|
*
|
|
12
12
|
* @category Internal
|
|
13
13
|
*/
|
|
14
|
-
export declare function assertValidStringNames(elementTagName: CustomElementTagName, stringNames:
|
|
14
|
+
export declare function assertValidStringNames(elementTagName: CustomElementTagName, stringNames: ReadonlyArray<string>): void;
|
|
15
15
|
/**
|
|
16
16
|
* Type safe mapping of string names to themself with the element tag name inserted.
|
|
17
17
|
*
|
|
@@ -26,3 +26,25 @@ export type StringNameMap<ElementTagName extends CustomElementTagName, NameType
|
|
|
26
26
|
* @category Internal
|
|
27
27
|
*/
|
|
28
28
|
export declare function createStringNameMap<ElementTagName extends CustomElementTagName, NameType extends string, StringNames extends ReadonlyArray<string>>(elementTagName: ElementTagName, nameType: NameType, stringNames: StringNames | undefined): StringNameMap<ElementTagName, NameType, StringNames>;
|
|
29
|
+
/**
|
|
30
|
+
* Identity map of slot names. Slot names are defined with the element's tag name as a prefix, so no
|
|
31
|
+
* extra string generation is required: each map key maps to itself.
|
|
32
|
+
*
|
|
33
|
+
* Note that if a slot name is _incorrectly_ defined without the element's tag name as the prefix,
|
|
34
|
+
* then the runtime value will actually be `${ElementTagName}-slot-${Name}`.
|
|
35
|
+
*
|
|
36
|
+
* @category Internal
|
|
37
|
+
*/
|
|
38
|
+
export type SlotNamesMap<SlotNames extends ReadonlyArray<string>> = Readonly<{
|
|
39
|
+
[Name in ArrayElement<SlotNames>]: Name;
|
|
40
|
+
}>;
|
|
41
|
+
/**
|
|
42
|
+
* Converts an array of slot names into a {@link SlotNamesMap}.
|
|
43
|
+
*
|
|
44
|
+
* Slot names that start with the element's tag name pass through unchanged. Slot names that do not
|
|
45
|
+
* are transformed into the legacy `${tagName}-slot-${name}` format so existing elements that
|
|
46
|
+
* pre-date the tag prefix convention keep working.
|
|
47
|
+
*
|
|
48
|
+
* @category Internal
|
|
49
|
+
*/
|
|
50
|
+
export declare function createSlotNamesMap<ElementTagName extends CustomElementTagName, SlotNames extends ReadonlyArray<string>>(elementTagName: ElementTagName, slotNames: SlotNames | undefined): SlotNamesMap<SlotNames>;
|
|
@@ -9,7 +9,7 @@ export function assertValidStringNames(elementTagName, stringNames) {
|
|
|
9
9
|
elementTagName,
|
|
10
10
|
'-',
|
|
11
11
|
].join('');
|
|
12
|
-
|
|
12
|
+
stringNames.forEach((stringName) => {
|
|
13
13
|
if (!stringName.startsWith(requiredNameStart)) {
|
|
14
14
|
throw new Error(`Invalid element string name '${stringName}' in '${elementTagName}': element string names must begin with the element's tag name.`);
|
|
15
15
|
}
|
|
@@ -38,3 +38,37 @@ export function createStringNameMap(elementTagName, nameType, stringNames) {
|
|
|
38
38
|
});
|
|
39
39
|
return stringNameMap;
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Converts an array of slot names into a {@link SlotNamesMap}.
|
|
43
|
+
*
|
|
44
|
+
* Slot names that start with the element's tag name pass through unchanged. Slot names that do not
|
|
45
|
+
* are transformed into the legacy `${tagName}-slot-${name}` format so existing elements that
|
|
46
|
+
* pre-date the tag prefix convention keep working.
|
|
47
|
+
*
|
|
48
|
+
* @category Internal
|
|
49
|
+
*/
|
|
50
|
+
export function createSlotNamesMap(elementTagName, slotNames) {
|
|
51
|
+
if (!slotNames) {
|
|
52
|
+
return {};
|
|
53
|
+
}
|
|
54
|
+
const requiredNameStart = [
|
|
55
|
+
elementTagName,
|
|
56
|
+
'-',
|
|
57
|
+
].join('');
|
|
58
|
+
const slotNamesMap = arrayToObject(slotNames, (slotName) => {
|
|
59
|
+
const value = slotName.startsWith(requiredNameStart)
|
|
60
|
+
? slotName
|
|
61
|
+
: [
|
|
62
|
+
elementTagName,
|
|
63
|
+
'slot',
|
|
64
|
+
slotName,
|
|
65
|
+
].join('-');
|
|
66
|
+
return {
|
|
67
|
+
key: slotName,
|
|
68
|
+
value,
|
|
69
|
+
};
|
|
70
|
+
}, {
|
|
71
|
+
useRequired: true,
|
|
72
|
+
});
|
|
73
|
+
return slotNamesMap;
|
|
74
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { type ArrayElement } from '@augment-vir/common';
|
|
1
2
|
import { type CSSResult } from '../../lit-exports/base-lit-exports.js';
|
|
2
3
|
import { type CustomElementTagName } from '../custom-tag-name.js';
|
|
3
4
|
import { type CssVars } from './css-vars.js';
|
|
4
5
|
import { type PropertyInitMapBase } from './element-properties.js';
|
|
5
6
|
import { type HostClassNamesMap, type HostClassesInitMap } from './host-classes.js';
|
|
6
|
-
import { type BaseStringName } from './string-names.js';
|
|
7
|
+
import { type BaseStringName, type SlotNamesMap } from './string-names.js';
|
|
7
8
|
/**
|
|
8
9
|
* A host class instance to be referenced inside of an element definition's `styles` callback.
|
|
9
10
|
*
|
|
@@ -18,25 +19,27 @@ export type HostClass = {
|
|
|
18
19
|
*
|
|
19
20
|
* @category Internal
|
|
20
21
|
*/
|
|
21
|
-
export type StylesCallbackInput<TagName extends CustomElementTagName, HostClassKeys extends BaseStringName<TagName
|
|
22
|
+
export type StylesCallbackInput<TagName extends CustomElementTagName, HostClassKeys extends BaseStringName<NoInfer<TagName>>, CssVarKeys extends BaseStringName<NoInfer<TagName>>, SlotNames extends ReadonlyArray<string>> = {
|
|
22
23
|
hostClasses: Record<HostClassKeys, HostClass>;
|
|
23
24
|
cssVars: Readonly<CssVars<TagName, CssVarKeys>>;
|
|
25
|
+
slotNames: Readonly<Record<ArrayElement<SlotNames>, CSSResult>>;
|
|
24
26
|
};
|
|
25
27
|
/**
|
|
26
28
|
* The type for an element definition's `styles` callback.
|
|
27
29
|
*
|
|
28
30
|
* @category Internal
|
|
29
31
|
*/
|
|
30
|
-
export type StylesCallback<TagName extends CustomElementTagName, HostClassKeys extends BaseStringName<TagName
|
|
32
|
+
export type StylesCallback<TagName extends CustomElementTagName, HostClassKeys extends BaseStringName<NoInfer<TagName>>, CssVarKeys extends BaseStringName<NoInfer<TagName>>, SlotNames extends ReadonlyArray<string>> = (input: StylesCallbackInput<TagName, HostClassKeys, CssVarKeys, SlotNames>) => CSSResult;
|
|
31
33
|
/**
|
|
32
34
|
* Creates the input for an element definition's `styles` callback.
|
|
33
35
|
*
|
|
34
36
|
* @category Internal
|
|
35
37
|
*/
|
|
36
|
-
export declare function createStylesCallbackInput<TagName extends CustomElementTagName, HostClassKeys extends BaseStringName<TagName
|
|
38
|
+
export declare function createStylesCallbackInput<TagName extends CustomElementTagName, HostClassKeys extends BaseStringName<NoInfer<TagName>>, CssVarKeys extends BaseStringName<NoInfer<TagName>>, SlotNames extends ReadonlyArray<string>>({ hostClassNames, cssVars, slotNamesMap, }: {
|
|
37
39
|
hostClassNames: HostClassNamesMap<TagName, HostClassKeys>;
|
|
38
40
|
cssVars: Readonly<CssVars<TagName, CssVarKeys>>;
|
|
39
|
-
|
|
41
|
+
slotNamesMap: SlotNamesMap<SlotNames>;
|
|
42
|
+
}): StylesCallbackInput<TagName, HostClassKeys, CssVarKeys, SlotNames>;
|
|
40
43
|
/**
|
|
41
44
|
* Used inside of an element instance to apply host classes on each render.
|
|
42
45
|
*
|
|
@@ -5,7 +5,7 @@ import { unsafeCSS } from '../../lit-exports/base-lit-exports.js';
|
|
|
5
5
|
*
|
|
6
6
|
* @category Internal
|
|
7
7
|
*/
|
|
8
|
-
export function createStylesCallbackInput({ hostClassNames, cssVars, }) {
|
|
8
|
+
export function createStylesCallbackInput({ hostClassNames, cssVars, slotNamesMap, }) {
|
|
9
9
|
return {
|
|
10
10
|
hostClasses: mapObjectValues(hostClassNames, (key, name) => {
|
|
11
11
|
return {
|
|
@@ -14,6 +14,9 @@ export function createStylesCallbackInput({ hostClassNames, cssVars, }) {
|
|
|
14
14
|
};
|
|
15
15
|
}),
|
|
16
16
|
cssVars,
|
|
17
|
+
slotNames: mapObjectValues(slotNamesMap, (key, name) => {
|
|
18
|
+
return unsafeCSS(name);
|
|
19
|
+
}),
|
|
17
20
|
};
|
|
18
21
|
}
|
|
19
22
|
/**
|
|
@@ -5,7 +5,7 @@ import { type DeclarativeElement, type DeclarativeElementHost } from './declarat
|
|
|
5
5
|
import { type CssVars } from './properties/css-vars.js';
|
|
6
6
|
import { type EventDescriptorMap, type EventInitMapEventDetailExtractor, type EventsInitMap } from './properties/element-events.js';
|
|
7
7
|
import { type PropertyInitMapBase } from './properties/element-properties.js';
|
|
8
|
-
import { type BaseStringName, type StringNameMap } from './properties/string-names.js';
|
|
8
|
+
import { type BaseStringName, type SlotNamesMap, type StringNameMap } from './properties/string-names.js';
|
|
9
9
|
/**
|
|
10
10
|
* Type for the `render` element definition method.
|
|
11
11
|
*
|
|
@@ -35,7 +35,7 @@ export type RenderParams<TagName extends CustomElementTagName, Inputs extends Pr
|
|
|
35
35
|
updateState: UpdateStateCallback<State>;
|
|
36
36
|
events: EventDescriptorMap<TagName, EventsInit>;
|
|
37
37
|
host: DeclarativeElementHost<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames, TestIds>;
|
|
38
|
-
slotNames:
|
|
38
|
+
slotNames: SlotNamesMap<SlotNames>;
|
|
39
39
|
testIds: Readonly<StringNameMap<TagName, 'test-id', TestIds>>;
|
|
40
40
|
/** Dispatch an event from the current element. */
|
|
41
41
|
dispatch: <EventTypeName extends keyof EventsInit>(event: TypedEvent<EventTypeName extends string ? EventTypeName : never, EventInitMapEventDetailExtractor<EventTypeName, EventsInit>> | Event) => boolean;
|
|
@@ -51,6 +51,6 @@ export declare function createRenderParams<TagName extends CustomElementTagName,
|
|
|
51
51
|
element: DeclarativeElement<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames, TestIds>;
|
|
52
52
|
eventsMap: EventDescriptorMap<TagName, EventsInit>;
|
|
53
53
|
cssVars: Readonly<CssVars<TagName, CssVarKeys>>;
|
|
54
|
-
slotNamesMap:
|
|
54
|
+
slotNamesMap: SlotNamesMap<SlotNames>;
|
|
55
55
|
testIdsMap: Readonly<StringNameMap<TagName, 'test-id', TestIds>>;
|
|
56
56
|
}): RenderParams<TagName, Inputs, State, EventsInit, HostClassKeys, CssVarKeys, SlotNames, TestIds>;
|
|
@@ -21,7 +21,7 @@ declare class RepeatDirective extends Directive {
|
|
|
21
21
|
/** Updates the repeated templates. */
|
|
22
22
|
update<T>(containerPart: ChildPart, [items, keyFnOrTemplate, template,]: [
|
|
23
23
|
Iterable<T>,
|
|
24
|
-
|
|
24
|
+
KeyFn<T> | ItemTemplate<T>,
|
|
25
25
|
ItemTemplate<T>
|
|
26
26
|
]): HtmlInterpolation[] | typeof noChange;
|
|
27
27
|
}
|
|
@@ -4,7 +4,7 @@ export const defineVirElement = wrapDefineElement();
|
|
|
4
4
|
export const defineVerifiedVirElement = wrapDefineElement({
|
|
5
5
|
assertInputs: (inputs) => {
|
|
6
6
|
if (!inputs.tagName.startsWith('vir-')) {
|
|
7
|
-
throw new Error(
|
|
7
|
+
throw new Error('all custom elements must start with "vir-"');
|
|
8
8
|
}
|
|
9
9
|
},
|
|
10
10
|
});
|
|
@@ -47,7 +47,7 @@ function getNestedValues(map, keys, index = 0) {
|
|
|
47
47
|
else if (index === keys.length - 1) {
|
|
48
48
|
return {
|
|
49
49
|
value: currentTemplateAndNested,
|
|
50
|
-
reason:
|
|
50
|
+
reason: 'reached end of keys array',
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
53
|
else if (!currentTemplateAndNested.nested) {
|
|
@@ -85,7 +85,7 @@ function getCurrentKeyAndValue(map, keys, index) {
|
|
|
85
85
|
return {
|
|
86
86
|
currentKey,
|
|
87
87
|
currentTemplateAndNested,
|
|
88
|
-
reason:
|
|
88
|
+
reason: 'key and value exists',
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
91
|
function setNestedValues(map, keys, valueToSet, index = 0) {
|
|
@@ -107,7 +107,7 @@ function setNestedValues(map, keys, valueToSet, index = 0) {
|
|
|
107
107
|
nestedAndTemplate.template = valueToSet;
|
|
108
108
|
return {
|
|
109
109
|
result: true,
|
|
110
|
-
reason:
|
|
110
|
+
reason: 'set value at end of keys array',
|
|
111
111
|
};
|
|
112
112
|
}
|
|
113
113
|
const nestedWeakMap = nestedAndTemplate.nested ?? new WeakMap();
|
|
@@ -28,12 +28,18 @@ export type VerifyHtmlValues<Values extends HtmlInterpolation[], WaitingForEndTa
|
|
|
28
28
|
infer CurrentDefinition extends DeclarativeElementDefinition,
|
|
29
29
|
...infer Rest extends HtmlInterpolation[]
|
|
30
30
|
] ? CurrentDefinition extends DeclarativeElementDefinition<infer TagName, infer Inputs> ? HasRequiredKeys<Inputs> extends true ? IsNever<Decrement<WaitingForEndTags[TagName]>> extends true ? [
|
|
31
|
-
|
|
31
|
+
'ERROR: This element is missing its inputs.',
|
|
32
32
|
...VerifyHtmlValues<Rest, WaitingForEndTags>
|
|
33
33
|
] : [
|
|
34
34
|
CurrentDefinition,
|
|
35
35
|
...VerifyHtmlValues<Rest, Overwrite<WaitingForEndTags, Record<TagName, Decrement<WaitingForEndTags[TagName]>>>>
|
|
36
|
-
] : [
|
|
36
|
+
] : [
|
|
37
|
+
CurrentDefinition,
|
|
38
|
+
...VerifyHtmlValues<Rest, WaitingForEndTags>
|
|
39
|
+
] : [
|
|
40
|
+
CurrentDefinition,
|
|
41
|
+
...VerifyHtmlValues<Rest, WaitingForEndTags>
|
|
42
|
+
] : Values extends [
|
|
37
43
|
infer CurrentDefinition extends MinimalDefinitionWithInputs,
|
|
38
44
|
...infer Rest extends HtmlInterpolation[]
|
|
39
45
|
] ? [
|
package/dist/util/increment.d.ts
CHANGED
|
@@ -46,10 +46,16 @@ export type Incrementable = [
|
|
|
46
46
|
*
|
|
47
47
|
* @category Internal
|
|
48
48
|
*/
|
|
49
|
-
export type Increment<T> = IsNever<Extract<ArrayElement<Incrementable>, T>> extends true ? IsNever<T> extends true ? 1 : never : Incrementable extends [
|
|
49
|
+
export type Increment<T> = IsNever<Extract<ArrayElement<Incrementable>, T>> extends true ? IsNever<T> extends true ? 1 : never : Incrementable extends [
|
|
50
|
+
any,
|
|
51
|
+
...infer Rest
|
|
52
|
+
] ? T extends keyof Rest ? Rest[T] extends undefined ? never : Rest[T] : 1 : 1;
|
|
50
53
|
/**
|
|
51
54
|
* Decrements the given number. If an invalid type parameter is given, `never` is the output.
|
|
52
55
|
*
|
|
53
56
|
* @category Internal
|
|
54
57
|
*/
|
|
55
|
-
export type Decrement<T> = IsNever<Extract<ArrayElement<Incrementable>, T>> extends true ? never : T extends keyof Incrementable ? [
|
|
58
|
+
export type Decrement<T> = IsNever<Extract<ArrayElement<Incrementable>, T>> extends true ? never : T extends keyof Incrementable ? [
|
|
59
|
+
never,
|
|
60
|
+
...Incrementable
|
|
61
|
+
][T] : never;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "element-vir",
|
|
3
|
-
"version": "26.
|
|
3
|
+
"version": "26.16.0",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"custom",
|
|
6
6
|
"web",
|
|
@@ -39,19 +39,19 @@
|
|
|
39
39
|
"test:docs": "virmator docs check"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@augment-vir/assert": "^31.
|
|
43
|
-
"@augment-vir/common": "^31.
|
|
44
|
-
"date-vir": "^8.2
|
|
42
|
+
"@augment-vir/assert": "^31.70.0",
|
|
43
|
+
"@augment-vir/common": "^31.70.0",
|
|
44
|
+
"date-vir": "^8.3.2",
|
|
45
45
|
"lit": "^3.3.2",
|
|
46
46
|
"lit-css-vars": "^3.6.2",
|
|
47
47
|
"lit-html": "^3.3.2",
|
|
48
|
-
"object-shape-tester": "^6.
|
|
48
|
+
"object-shape-tester": "^6.12.1",
|
|
49
49
|
"observavir": "^2.3.2",
|
|
50
50
|
"typed-event-target": "^4.3.0"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@augment-vir/test": "^31.
|
|
54
|
-
"@augment-vir/web": "^31.
|
|
53
|
+
"@augment-vir/test": "^31.70.0",
|
|
54
|
+
"@augment-vir/web": "^31.70.0",
|
|
55
55
|
"@web/dev-server-esbuild": "^1.0.5",
|
|
56
56
|
"@web/test-runner": "^0.20.2",
|
|
57
57
|
"@web/test-runner-commands": "^0.9.0",
|
|
@@ -59,11 +59,11 @@
|
|
|
59
59
|
"@web/test-runner-visual-regression": "^0.10.0",
|
|
60
60
|
"html-spec-tags": "^2.2.3",
|
|
61
61
|
"istanbul-smart-text-reporter": "^1.1.5",
|
|
62
|
-
"markdown-code-example-inserter": "^3.0.
|
|
63
|
-
"type-fest": "^5.
|
|
64
|
-
"typedoc": "^0.28.
|
|
62
|
+
"markdown-code-example-inserter": "^3.0.5",
|
|
63
|
+
"type-fest": "^5.6.0",
|
|
64
|
+
"typedoc": "^0.28.19",
|
|
65
65
|
"typescript": "5.9.3",
|
|
66
|
-
"vite": "^8.0.
|
|
66
|
+
"vite": "^8.0.11",
|
|
67
67
|
"vite-tsconfig-paths": "^6.1.1"
|
|
68
68
|
},
|
|
69
69
|
"engines": {
|