element-vir 5.4.2 → 5.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/README.md +85 -4
  2. package/dist/{cjs/augments → augments}/array.d.ts +0 -0
  3. package/dist/{esm/augments → augments}/array.js +0 -0
  4. package/dist/{cjs/augments → augments}/type.d.ts +0 -0
  5. package/dist/{esm/augments → augments}/type.js +0 -0
  6. package/dist/functional-element/css-vars.d.ts +6 -0
  7. package/dist/functional-element/css-vars.js +22 -0
  8. package/dist/functional-element/define-functional-element.d.ts +4 -0
  9. package/dist/{esm/functional-element → functional-element}/define-functional-element.js +30 -3
  10. package/dist/{cjs/functional-element → functional-element}/directives/assign-with-clean-up.directive.d.ts +0 -0
  11. package/dist/{esm/functional-element → functional-element}/directives/assign-with-clean-up.directive.js +0 -0
  12. package/dist/{types/functional-element → functional-element}/directives/assign.directive.d.ts +2 -2
  13. package/dist/{esm/functional-element → functional-element}/directives/assign.directive.js +0 -0
  14. package/dist/{esm/functional-element → functional-element}/directives/directive-util.d.ts +2 -2
  15. package/dist/{esm/functional-element → functional-element}/directives/directive-util.js +0 -0
  16. package/dist/{cjs/functional-element → functional-element}/directives/listen.directive.d.ts +0 -0
  17. package/dist/{esm/functional-element → functional-element}/directives/listen.directive.js +0 -0
  18. package/dist/{cjs/functional-element → functional-element}/directives/on-dom-created.directive.d.ts +0 -0
  19. package/dist/{esm/functional-element → functional-element}/directives/on-dom-created.directive.js +0 -0
  20. package/dist/{cjs/functional-element → functional-element}/directives/on-resize.directive.d.ts +0 -0
  21. package/dist/{esm/functional-element → functional-element}/directives/on-resize.directive.js +0 -0
  22. package/dist/{cjs/functional-element → functional-element}/element-events.d.ts +0 -0
  23. package/dist/{esm/functional-element → functional-element}/element-events.js +0 -0
  24. package/dist/{esm/functional-element → functional-element}/element-properties.d.ts +2 -2
  25. package/dist/{esm/functional-element → functional-element}/element-properties.js +0 -0
  26. package/dist/{esm/functional-element → functional-element}/functional-element.d.ts +25 -10
  27. package/dist/{esm/functional-element → functional-element}/functional-element.js +0 -0
  28. package/dist/functional-element/host-classes.d.ts +19 -0
  29. package/dist/functional-element/host-classes.js +12 -0
  30. package/dist/{types/functional-element → functional-element}/render-callback.d.ts +3 -3
  31. package/dist/{esm/functional-element → functional-element}/render-callback.js +0 -0
  32. package/dist/functional-element/styles.d.ts +16 -0
  33. package/dist/functional-element/styles.js +29 -0
  34. package/dist/functional-element/tag-name.d.ts +2 -0
  35. package/dist/functional-element/tag-name.js +4 -0
  36. package/dist/{cjs/index.d.ts → index.d.ts} +0 -0
  37. package/dist/{esm/index.js → index.js} +0 -0
  38. package/dist/{cjs/require-functional-element.d.ts → require-functional-element.d.ts} +0 -0
  39. package/dist/{esm/require-functional-element.js → require-functional-element.js} +0 -0
  40. package/dist/{cjs/template-transforms → template-transforms}/has-static-tag-name.d.ts +0 -0
  41. package/dist/{esm/template-transforms → template-transforms}/has-static-tag-name.js +0 -0
  42. package/dist/{cjs/template-transforms → template-transforms}/transform-template.d.ts +0 -0
  43. package/dist/{esm/template-transforms → template-transforms}/transform-template.js +0 -0
  44. package/dist/{cjs/template-transforms → template-transforms}/vir-css/css-transform.d.ts +0 -0
  45. package/dist/{esm/template-transforms → template-transforms}/vir-css/css-transform.js +0 -0
  46. package/dist/{cjs/template-transforms → template-transforms}/vir-css/vir-css.d.ts +0 -0
  47. package/dist/{esm/template-transforms → template-transforms}/vir-css/vir-css.js +0 -0
  48. package/dist/{cjs/template-transforms → template-transforms}/vir-html/html-transform.d.ts +0 -0
  49. package/dist/{esm/template-transforms → template-transforms}/vir-html/html-transform.js +0 -0
  50. package/dist/{cjs/template-transforms → template-transforms}/vir-html/vir-html.d.ts +0 -0
  51. package/dist/{esm/template-transforms → template-transforms}/vir-html/vir-html.js +0 -0
  52. package/dist/{cjs/typed-event → typed-event}/typed-event.d.ts +0 -0
  53. package/dist/{esm/typed-event → typed-event}/typed-event.js +0 -0
  54. package/package.json +8 -9
  55. package/dist/cjs/augments/array.js +0 -7
  56. package/dist/cjs/augments/type.js +0 -2
  57. package/dist/cjs/functional-element/define-functional-element.d.ts +0 -4
  58. package/dist/cjs/functional-element/define-functional-element.js +0 -47
  59. package/dist/cjs/functional-element/directives/assign-with-clean-up.directive.js +0 -40
  60. package/dist/cjs/functional-element/directives/assign.directive.d.ts +0 -15
  61. package/dist/cjs/functional-element/directives/assign.directive.js +0 -27
  62. package/dist/cjs/functional-element/directives/directive-util.d.ts +0 -15
  63. package/dist/cjs/functional-element/directives/directive-util.js +0 -27
  64. package/dist/cjs/functional-element/directives/listen.directive.js +0 -51
  65. package/dist/cjs/functional-element/directives/on-dom-created.directive.js +0 -26
  66. package/dist/cjs/functional-element/directives/on-resize.directive.js +0 -39
  67. package/dist/cjs/functional-element/element-events.js +0 -29
  68. package/dist/cjs/functional-element/element-properties.d.ts +0 -16
  69. package/dist/cjs/functional-element/element-properties.js +0 -55
  70. package/dist/cjs/functional-element/functional-element.d.ts +0 -42
  71. package/dist/cjs/functional-element/functional-element.js +0 -7
  72. package/dist/cjs/functional-element/render-callback.d.ts +0 -21
  73. package/dist/cjs/functional-element/render-callback.js +0 -24
  74. package/dist/cjs/index.js +0 -33
  75. package/dist/cjs/require-functional-element.js +0 -8
  76. package/dist/cjs/template-transforms/has-static-tag-name.js +0 -10
  77. package/dist/cjs/template-transforms/transform-template.js +0 -74
  78. package/dist/cjs/template-transforms/vir-css/css-transform.js +0 -16
  79. package/dist/cjs/template-transforms/vir-css/vir-css.js +0 -16
  80. package/dist/cjs/template-transforms/vir-html/html-transform.js +0 -48
  81. package/dist/cjs/template-transforms/vir-html/vir-html.js +0 -20
  82. package/dist/cjs/typed-event/typed-event.js +0 -37
  83. package/dist/esm/augments/array.d.ts +0 -1
  84. package/dist/esm/augments/type.d.ts +0 -1
  85. package/dist/esm/functional-element/define-functional-element.d.ts +0 -4
  86. package/dist/esm/functional-element/directives/assign-with-clean-up.directive.d.ts +0 -19
  87. package/dist/esm/functional-element/directives/assign.directive.d.ts +0 -15
  88. package/dist/esm/functional-element/directives/listen.directive.d.ts +0 -13
  89. package/dist/esm/functional-element/directives/on-dom-created.directive.d.ts +0 -11
  90. package/dist/esm/functional-element/directives/on-resize.directive.d.ts +0 -15
  91. package/dist/esm/functional-element/element-events.d.ts +0 -10
  92. package/dist/esm/functional-element/render-callback.d.ts +0 -21
  93. package/dist/esm/index.d.ts +0 -15
  94. package/dist/esm/require-functional-element.d.ts +0 -2
  95. package/dist/esm/template-transforms/has-static-tag-name.d.ts +0 -4
  96. package/dist/esm/template-transforms/transform-template.d.ts +0 -16
  97. package/dist/esm/template-transforms/vir-css/css-transform.d.ts +0 -7
  98. package/dist/esm/template-transforms/vir-css/vir-css.d.ts +0 -3
  99. package/dist/esm/template-transforms/vir-html/html-transform.d.ts +0 -3
  100. package/dist/esm/template-transforms/vir-html/vir-html.d.ts +0 -3
  101. package/dist/esm/typed-event/typed-event.d.ts +0 -19
  102. package/dist/types/augments/array.d.ts +0 -1
  103. package/dist/types/augments/type.d.ts +0 -1
  104. package/dist/types/functional-element/define-functional-element.d.ts +0 -4
  105. package/dist/types/functional-element/directives/assign-with-clean-up.directive.d.ts +0 -19
  106. package/dist/types/functional-element/directives/directive-util.d.ts +0 -15
  107. package/dist/types/functional-element/directives/listen.directive.d.ts +0 -13
  108. package/dist/types/functional-element/directives/on-dom-created.directive.d.ts +0 -11
  109. package/dist/types/functional-element/directives/on-resize.directive.d.ts +0 -15
  110. package/dist/types/functional-element/element-events.d.ts +0 -10
  111. package/dist/types/functional-element/element-properties.d.ts +0 -16
  112. package/dist/types/functional-element/functional-element.d.ts +0 -42
  113. package/dist/types/index.d.ts +0 -15
  114. package/dist/types/require-functional-element.d.ts +0 -2
  115. package/dist/types/template-transforms/has-static-tag-name.d.ts +0 -4
  116. package/dist/types/template-transforms/transform-template.d.ts +0 -16
  117. package/dist/types/template-transforms/vir-css/css-transform.d.ts +0 -7
  118. package/dist/types/template-transforms/vir-css/vir-css.d.ts +0 -3
  119. package/dist/types/template-transforms/vir-html/html-transform.d.ts +0 -3
  120. package/dist/types/template-transforms/vir-html/vir-html.d.ts +0 -3
  121. package/dist/types/typed-event/typed-event.d.ts +0 -19
package/README.md CHANGED
@@ -11,7 +11,7 @@ _**It's just TypeScript.**_
11
11
 
12
12
  Uses the power of _native_ JavaScript custom web elements, _native_ JavaScript template literals, _native_ JavaScript functions<sup>\*</sup>, _native_ HTML, and [lit-element](http://lit.dev).
13
13
 
14
- In reality this is basically a [lit-element](http://lit.dev) wrapper that adds type-safe element tag usage and I/O with functional-programming style component definition.
14
+ In reality this is basically a [lit-element](http://lit.dev) wrapper that adds type-safe element tag usage and I/O with functional-programming style component definition. (As functional as possible, element property mutations are still possible cause without that, how would you do anything?)
15
15
 
16
16
  [Works in every major web browser except Internet Explorer.](https://caniuse.com/mdn-api_window_customelements)
17
17
 
@@ -150,7 +150,7 @@ export const MySimpleWithPropsElement = defineFunctionalElement({
150
150
  });
151
151
  ```
152
152
 
153
- ## Updating properties
153
+ ### Updating properties
154
154
 
155
155
  Grab `setProps` from `renderCallback`'s parameters to update the values in `props`. This causes a re-render. (Note that this example also uses the `listen` directive to respond to click events.)
156
156
 
@@ -177,7 +177,7 @@ export const MySimpleWithPropsElement = defineFunctionalElement({
177
177
  });
178
178
  ```
179
179
 
180
- ## Assigning to properties (inputs)
180
+ ### Assigning to properties (inputs)
181
181
 
182
182
  Use the `assign` directive to assign properties to child custom elements:
183
183
 
@@ -228,7 +228,7 @@ export const MySimpleWithEventsElement = defineFunctionalElement({
228
228
  });
229
229
  ```
230
230
 
231
- ## Listening to typed events (outputs)
231
+ ### Listening to typed events (outputs)
232
232
 
233
233
  Use the `listen` directive to listen to typed events emitted by your custom functional elements:
234
234
 
@@ -303,6 +303,87 @@ export const MyElementWithCustomEvents = defineFunctionalElement({
303
303
  });
304
304
  ```
305
305
 
306
+ ## Host classes
307
+
308
+ Host classes can be defined and used with type safety. Host classes are used to provide alternative styles for components. They are purely driven by CSS and are thus applied via the `class` HTML attribute.
309
+
310
+ Host classes that are defined with a callback will automatically get applied if that callback returns true after a render is executed. These are executed _after_ `renderCallback` is executed. When a definition is set to `false`, it's left to the element's consumer to apply the host class.
311
+
312
+ Apply host classes in the element's stylesheet by using a callback for the styles property.
313
+
314
+ <!-- example-link: src/readme-examples/host-class-definition.ts -->
315
+
316
+ ```TypeScript
317
+ import {css, defineFunctionalElement, html} from 'element-vir';
318
+
319
+ export const MyAppWithHostClasses = defineFunctionalElement({
320
+ tagName: 'my-app-with-host-classes',
321
+ props: {
322
+ myProp: 'hello there',
323
+ },
324
+ hostClasses: {
325
+ /**
326
+ * Setting the value to false means this host class will not ever automatically be applied.
327
+ * It will simply be a static member on the element for manual application in consumers when desired.
328
+ */
329
+ styleVariationA: false,
330
+ /**
331
+ * This host class will be automatically applied if the given callback evaluated to true
332
+ * after a call to renderCallback.
333
+ */
334
+ automaticallyAppliedVariation: ({props}) => {
335
+ return props.myProp === 'foo';
336
+ },
337
+ },
338
+ /**
339
+ * Apply styles to the host classes by using a callback for "styles". The callback's argument
340
+ * contains the host classes defined above in the "hostClasses" property.
341
+ */
342
+ styles: ({hostClass}) => css`
343
+ ${hostClass.automaticallyAppliedVariation} {
344
+ color: blue;
345
+ }
346
+
347
+ ${hostClass.styleVariationA} {
348
+ color: red;
349
+ }
350
+ `,
351
+ renderCallback: ({props}) => html`
352
+ ${props.myProp}
353
+ `,
354
+ });
355
+ ```
356
+
357
+ ## CSS Vars
358
+
359
+ Typed CSS vars are created in a similar way as host classes:
360
+
361
+ <!-- example-link: src/readme-examples/css-vars-definition.ts -->
362
+
363
+ ```TypeScript
364
+ import {css, defineFunctionalElement, html} from 'element-vir';
365
+
366
+ export const MyAppWithCssVars = defineFunctionalElement({
367
+ tagName: 'my-app-with-css-vars',
368
+ cssVars: {
369
+ /**
370
+ * The value assigned here ('blue') becomes the fallback value for this CSS var when used
371
+ * via "cssVarValue".
372
+ */
373
+ myCssVar: 'blue',
374
+ },
375
+ styles: ({cssVarName, cssVarValue}) => css`
376
+ :host {
377
+ /* Set CSS vars (or reference the name directly) via "cssVarName" */
378
+ ${cssVarName.myCssVar}: yellow;
379
+ /* Use CSS vars with "cssVarValue". This includes a "var" wrapper and the assigned fallback value (which in this case is 'blue'). */
380
+ color: ${cssVarValue.myCssVar};
381
+ }
382
+ `,
383
+ renderCallback: () => html``,
384
+ });
385
+ ```
386
+
306
387
  ## Directives
307
388
 
308
389
  The following custom [`lit` directives](https://lit.dev/docs/templates/custom-directives/) are contained within this package.
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,6 @@
1
+ import { CSSResult } from 'lit';
2
+ export declare type CssVarsInitMap<CssVarKeys extends string> = Record<CssVarKeys, string>;
3
+ export declare type CssVarName<TagName extends string> = `--${TagName}-string`;
4
+ export declare 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>;
@@ -0,0 +1,22 @@
1
+ import { mapObject } from 'augment-vir';
2
+ import { unsafeCSS } from 'lit';
3
+ import { toHtmlSafeWithTagName } from './tag-name';
4
+ export function createCssVarNamesMap(tagName, cssVarsInit) {
5
+ if (cssVarsInit) {
6
+ return mapObject(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 mapObject(cssVarInitMap, (key, fallbackValue) => {
19
+ const name = cssVarNamesMap[key];
20
+ return unsafeCSS(`var(${name}, ${fallbackValue})`);
21
+ });
22
+ }
@@ -0,0 +1,4 @@
1
+ import { EventsInitMap } from './element-events';
2
+ import { PropertyInitMapBase } from './element-properties';
3
+ import { FunctionalElement, FunctionalElementInit } from './functional-element';
4
+ export declare function defineFunctionalElement<HostClassKeys extends string = '', CssVarKeys extends string = '', EventsInitGeneric extends EventsInitMap = {}, PropertyInitGeneric extends PropertyInitMapBase = {}>(functionalElementInit: FunctionalElementInit<PropertyInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>): FunctionalElement<PropertyInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
@@ -1,12 +1,34 @@
1
1
  import { css } from 'lit';
2
2
  import { property } from 'lit/decorators.js';
3
+ import { createCssVarNamesMap, createCssVarValuesMap } from './css-vars';
3
4
  import { createEventDescriptorMap } from './element-events';
4
5
  import { createPropertyDescriptorMap, createPropertyProxy, } from './element-properties';
5
6
  import { FunctionalElementBaseClass, } from './functional-element';
7
+ import { createHostClassNamesMap } from './host-classes';
6
8
  import { createRenderParams } from './render-callback';
9
+ import { applyHostClasses, hostClassNamesToStylesInput } from './styles';
10
+ const defaultInit = {
11
+ events: {},
12
+ props: {},
13
+ };
7
14
  export function defineFunctionalElement(functionalElementInit) {
8
15
  var _a;
9
16
  const eventsMap = createEventDescriptorMap(functionalElementInit.events);
17
+ const hostClassNames = createHostClassNamesMap(functionalElementInit.tagName, functionalElementInit.hostClasses);
18
+ const cssVarNames = createCssVarNamesMap(functionalElementInit.tagName, functionalElementInit.cssVars);
19
+ const cssVarValues = createCssVarValuesMap(functionalElementInit.cssVars, cssVarNames);
20
+ console.log({ hostClassNames });
21
+ console.log(hostClassNamesToStylesInput({
22
+ hostClassNames,
23
+ cssVarNames,
24
+ cssVarValues,
25
+ }));
26
+ const calculatedStyles = typeof functionalElementInit.styles === 'function'
27
+ ? functionalElementInit.styles(hostClassNamesToStylesInput({ hostClassNames, cssVarNames, cssVarValues }))
28
+ : functionalElementInit.styles || css ``;
29
+ if (typeof functionalElementInit.styles === 'function') {
30
+ console.log({ calculatedStyles: String(calculatedStyles) });
31
+ }
10
32
  const anonymousClass = (_a = class extends FunctionalElementBaseClass {
11
33
  constructor() {
12
34
  super();
@@ -28,15 +50,20 @@ export function defineFunctionalElement(functionalElementInit) {
28
50
  this.initCalled = true;
29
51
  functionalElementInit.initCallback(renderParams);
30
52
  }
31
- return functionalElementInit.renderCallback(renderParams);
53
+ const renderResult = functionalElementInit.renderCallback(renderParams);
54
+ applyHostClasses(renderParams.host, functionalElementInit.hostClasses, hostClassNames, renderParams.props);
55
+ return renderResult;
32
56
  }
33
57
  },
34
58
  _a.tagName = functionalElementInit.tagName,
35
- _a.styles = functionalElementInit.styles || css ``,
36
- _a.initInput = functionalElementInit,
59
+ _a.styles = calculatedStyles,
60
+ _a.init = { ...defaultInit, ...functionalElementInit },
37
61
  _a.events = eventsMap,
38
62
  _a.renderCallback = functionalElementInit.renderCallback,
39
63
  _a.props = createPropertyDescriptorMap(functionalElementInit.props),
64
+ _a.hostClasses = hostClassNames,
65
+ _a.cssVarNames = cssVarNames,
66
+ _a.cssVarValues = cssVarNames,
40
67
  _a);
41
68
  window.customElements.define(functionalElementInit.tagName, anonymousClass);
42
69
  return anonymousClass;
@@ -1,13 +1,13 @@
1
1
  import { PartInfo } from 'lit/directive.js';
2
2
  import { PropertyInitMapBase, StaticElementPropertyDescriptor } from '../element-properties';
3
- import { FunctionalElementInstance } from '../functional-element';
3
+ import { FunctionalElementInstanceFromInit } from '../functional-element';
4
4
  /**
5
5
  * The directive generics (in listenDirective) are not strong enough to maintain their values. Thus,
6
6
  * the directive call is wrapped in this function.
7
7
  */
8
8
  export declare function assign<PropName extends string, PropValue>(propertyDescriptor: StaticElementPropertyDescriptor<PropName, PropValue>, value: typeof propertyDescriptor['initValue']): import("lit-html/directive").DirectiveResult<{
9
9
  new (partInfo: PartInfo): {
10
- readonly element: FunctionalElementInstance<PropertyInitMapBase>;
10
+ readonly element: FunctionalElementInstanceFromInit<PropertyInitMapBase>;
11
11
  render(propName: string, value: unknown): symbol;
12
12
  readonly _$isConnected: boolean;
13
13
  update(_part: import("lit-html").Part, props: unknown[]): unknown;
@@ -1,6 +1,6 @@
1
1
  import { ElementPartInfo, PartInfo } from 'lit/directive.js';
2
2
  import { PropertyInitMapBase } from '../element-properties';
3
- import { FunctionalElementInstance } from '../functional-element';
3
+ import { FunctionalElementInstanceFromInit } from '../functional-element';
4
4
  /** For some reason these aren't defined in lit's types already. */
5
5
  export declare type ExtraPartInfoProperties = {
6
6
  element: Element;
@@ -10,6 +10,6 @@ export declare type ExtraPartInfoProperties = {
10
10
  isConnected: boolean;
11
11
  };
12
12
  };
13
- export declare function extractFunctionalElement<PropertyInitGeneric extends PropertyInitMapBase>(partInfo: PartInfo, directiveName: string): FunctionalElementInstance<PropertyInitGeneric>;
13
+ export declare function extractFunctionalElement<PropertyInitGeneric extends PropertyInitMapBase>(partInfo: PartInfo, directiveName: string): FunctionalElementInstanceFromInit<PropertyInitGeneric>;
14
14
  export declare function extractElement<ElementType = HTMLElement>(partInfo: PartInfo, directiveName: string, constructorClass: (new () => ElementType) | (abstract new () => ElementType)): ElementType;
15
15
  export declare function assertsIsElementPartInfo(partInfo: PartInfo, directiveName: string): asserts partInfo is ElementPartInfo & ExtraPartInfoProperties;
@@ -1,4 +1,4 @@
1
- import { FunctionalElementInstance } from './functional-element';
1
+ import { FunctionalElementInstanceFromInit } from './functional-element';
2
2
  export declare type PropertyInitMapBase = Record<string, unknown>;
3
3
  export declare type ElementProperty<KeyGeneric extends string | number | symbol, ValueGeneric> = {
4
4
  name: KeyGeneric;
@@ -12,5 +12,5 @@ export declare type StaticElementPropertyDescriptor<PropName extends string, Pro
12
12
  export declare type ElementPropertyDescriptorMap<PropertyInitGeneric extends PropertyInitMapBase> = {
13
13
  [Property in keyof PropertyInitGeneric]: StaticElementPropertyDescriptor<string, PropertyInitGeneric[Property]>;
14
14
  };
15
- export declare function createPropertyProxy<PropertyInitGeneric extends PropertyInitMapBase>(propsInitMap: PropertyInitGeneric | undefined, element: FunctionalElementInstance<PropertyInitGeneric>): PropertyInitGeneric;
15
+ export declare function createPropertyProxy<PropertyInitGeneric extends PropertyInitMapBase>(propsInitMap: PropertyInitGeneric | undefined, element: FunctionalElementInstanceFromInit<PropertyInitGeneric>): PropertyInitGeneric;
16
16
  export declare function createPropertyDescriptorMap<PropertyInitGeneric extends PropertyInitMapBase>(propertyInit: PropertyInitGeneric | undefined): ElementPropertyDescriptorMap<PropertyInitGeneric>;
@@ -1,20 +1,31 @@
1
+ import { RequiredBy } from 'augment-vir';
1
2
  import { CSSResult, LitElement, TemplateResult } from 'lit';
3
+ import { CssVarNameOrValueMap, CssVarsInitMap } from './css-vars';
2
4
  import { EventDescriptorMap, EventsInitMap } from './element-events';
3
5
  import { ElementPropertyDescriptorMap, PropertyInitMapBase } from './element-properties';
6
+ import { HostClassesInitMap, HostClassNamesMap } from './host-classes';
4
7
  import { InitCallback, RenderCallback } from './render-callback';
8
+ import { StylesCallback } from './styles';
5
9
  export declare type CustomElementTagName = `${string}-${string}`;
6
- export declare type FunctionalElementInit<PropertyInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap> = {
10
+ export declare type FunctionalElementInit<PropertyInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string> = {
7
11
  /**
8
12
  * HTML tag name. This should not be used directly, as interpolating it with the html tagged
9
13
  * template from this package is preferred.
10
14
  */
11
15
  tagName: CustomElementTagName;
12
16
  /** Static styles. These should not and cannot change. */
13
- styles?: CSSResult | undefined;
14
- /** Initializer for element properties. (These can be thought of as "inputs".) */
15
- props?: PropertyInitGeneric | undefined;
16
- /** Initializer for events that the element can dispatch. (These can be thought of as "outputs".) */
17
- events?: EventsInitGeneric | undefined;
17
+ styles?: CSSResult | StylesCallback<HostClassKeys, CssVarKeys>;
18
+ /** Element properties. (These can be thought of as "inputs".) */
19
+ props?: PropertyInitGeneric;
20
+ /** Events that the element can dispatch. (These can be thought of as "outputs".) */
21
+ events?: EventsInitGeneric;
22
+ /**
23
+ * CSS host classes. Values can be callbacks to determine when a host class should be defined,
24
+ * based on current instance props, or just undefined to indicate that the host class will only
25
+ * be manually set.
26
+ */
27
+ hostClasses?: HostClassesInitMap<HostClassKeys, PropertyInitGeneric>;
28
+ cssVars?: CssVarsInitMap<CssVarKeys>;
18
29
  /** Called as part of the first renderCallback call, before the first renderCallback call. */
19
30
  initCallback?: InitCallback<PropertyInitGeneric, EventsInitGeneric>;
20
31
  renderCallback: RenderCallback<PropertyInitGeneric, EventsInitGeneric>;
@@ -25,14 +36,18 @@ export declare abstract class FunctionalElementBaseClass<PropertyInitGeneric ext
25
36
  abstract render(): TemplateResult | Promise<TemplateResult>;
26
37
  abstract readonly instanceProps: PropertyInitGeneric;
27
38
  }
28
- export declare type FunctionalElementInstance<PropertyInitGeneric extends PropertyInitMapBase = {}> = FunctionalElementBaseClass<PropertyInitGeneric> & PropertyInitGeneric;
29
- export declare type FunctionalElement<PropertyInitGeneric extends PropertyInitMapBase = any, EventsInitGeneric extends EventsInitMap = any> = (new () => FunctionalElementInstance<PropertyInitGeneric>) & ExtraStaticFunctionalElementProperties<PropertyInitGeneric, EventsInitGeneric>;
30
- export declare type ExtraStaticFunctionalElementProperties<PropertyInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap> = Readonly<{
39
+ export declare type FunctionalElementInstanceFromInit<PropertyInitGeneric extends PropertyInitMapBase = {}> = FunctionalElementBaseClass<NonNullable<Required<PropertyInitGeneric>>> & PropertyInitGeneric;
40
+ export declare type FunctionalElementInstance<FunctionalElementGeneric extends FunctionalElement> = FunctionalElementInstanceFromInit<FunctionalElementGeneric['init']['props']>;
41
+ export declare type FunctionalElement<PropertyInitGeneric extends PropertyInitMapBase = any, EventsInitGeneric extends EventsInitMap = any, HostClassKeys extends string = string, CssVarKeys extends string = string> = (new () => FunctionalElementInstanceFromInit<PropertyInitGeneric>) & ExtraStaticFunctionalElementProperties<PropertyInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>;
42
+ export declare type ExtraStaticFunctionalElementProperties<PropertyInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap, HostClassKeys extends string, CssVarKeys extends string> = Readonly<{
31
43
  /** Pass through the render callback for direct unit testability */
32
44
  renderCallback: RenderCallback<PropertyInitGeneric, EventsInitGeneric>;
33
45
  events: EventDescriptorMap<EventsInitGeneric>;
34
46
  props: ElementPropertyDescriptorMap<PropertyInitGeneric>;
35
- initInput: FunctionalElementInit<PropertyInitGeneric, EventsInitGeneric>;
47
+ init: RequiredBy<FunctionalElementInit<PropertyInitGeneric, EventsInitGeneric, HostClassKeys, CssVarKeys>, 'props' | 'events'>;
48
+ hostClasses: HostClassNamesMap<string, HostClassKeys>;
49
+ cssVarNames: CssVarNameOrValueMap<CssVarKeys>;
50
+ cssVarValues: CssVarNameOrValueMap<CssVarKeys>;
36
51
  /**
37
52
  * Static properties have to be copied here cause they get nuked in the "new () =>
38
53
  * FunctionalElementInstance<PropertyInitGeneric>" type.
@@ -0,0 +1,19 @@
1
+ import { PropertyInitMapBase } from './element-properties';
2
+ import { WithTagName } from './tag-name';
3
+ export declare type HostClassToggleCallbackInput<PropertyInitGeneric extends PropertyInitMapBase> = {
4
+ props: Readonly<PropertyInitGeneric>;
5
+ };
6
+ export declare type HostClassToggleCallback<PropertyInitGeneric extends PropertyInitMapBase> = (inputs: HostClassToggleCallbackInput<PropertyInitGeneric>) => boolean;
7
+ export declare type HostClassesInitMap<HostClassKeys extends string, PropertyInitGeneric extends PropertyInitMapBase> = Record<HostClassKeys,
8
+ /**
9
+ * Callback to determine when host class should be enabled (based on current props), or just
10
+ * undefined to mark that this host class name will only be manually applied.
11
+ */
12
+ HostClassToggleCallback<PropertyInitGeneric> | false>;
13
+ export declare type HostClassName<TagName extends string, HostClassPropName extends string> = `${TagName}-${HostClassPropName}`;
14
+ export declare type HostClassNamesMap<TagName extends string, HostClassKeys extends string> = Record<HostClassKeys, WithTagName<TagName, string>>;
15
+ export declare function createHostClassNamesMap<TagName extends string, HostClassKeys extends string, HostClassesInitGeneric extends HostClassesInitMap<HostClassKeys,
16
+ /**
17
+ * We can use any here because we don't care what the prop names are, we just care what the
18
+ * host class names are
19
+ */ any>>(tagName: TagName, hostClassesInit?: HostClassesInitGeneric): HostClassNamesMap<TagName, HostClassKeys>;
@@ -0,0 +1,12 @@
1
+ import { mapObject } from 'augment-vir';
2
+ import { toHtmlSafeWithTagName } from './tag-name';
3
+ export function createHostClassNamesMap(tagName, hostClassesInit) {
4
+ if (hostClassesInit) {
5
+ return mapObject(hostClassesInit, (key) => {
6
+ return toHtmlSafeWithTagName(tagName, String(key));
7
+ });
8
+ }
9
+ else {
10
+ return {};
11
+ }
12
+ }
@@ -2,7 +2,7 @@ import { TemplateResult } from 'lit';
2
2
  import { TypedEvent } from '../typed-event/typed-event';
3
3
  import { EventDescriptorMap, EventInitMapEventDetailExtractor, EventsInitMap } from './element-events';
4
4
  import { PropertyInitMapBase } from './element-properties';
5
- import { FunctionalElementInstance } from './functional-element';
5
+ import { FunctionalElementInstanceFromInit } from './functional-element';
6
6
  export declare type RenderCallback<PropertyInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap> = (params: RenderParams<PropertyInitGeneric, EventsInitGeneric>) => TemplateResult;
7
7
  export declare type InitCallback<PropertyInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap> = (params: RenderParams<PropertyInitGeneric, EventsInitGeneric>) => void;
8
8
  export declare type SetPropCallback<PropertyInitGeneric extends PropertyInitMapBase> = (props: Partial<PropertyInitGeneric>) => void;
@@ -10,7 +10,7 @@ export declare type RenderParams<PropertyInitGeneric extends PropertyInitMapBase
10
10
  props: Readonly<PropertyInitGeneric>;
11
11
  setProps: SetPropCallback<PropertyInitGeneric>;
12
12
  events: EventDescriptorMap<EventsInitGeneric>;
13
- host: FunctionalElementInstance<PropertyInitGeneric>;
13
+ host: FunctionalElementInstanceFromInit<PropertyInitGeneric>;
14
14
  dispatch: <EventTypeNameGeneric extends keyof EventsInitGeneric>(event: TypedEvent<EventTypeNameGeneric extends string ? EventTypeNameGeneric : never, EventInitMapEventDetailExtractor<EventTypeNameGeneric, EventsInitGeneric>>) => boolean;
15
15
  /**
16
16
  * Same as dispatchElementEvent but without the extra types. This allows you to emit any events,
@@ -18,4 +18,4 @@ export declare type RenderParams<PropertyInitGeneric extends PropertyInitMapBase
18
18
  */
19
19
  genericDispatch: (event: Event) => boolean;
20
20
  };
21
- export declare function createRenderParams<PropertyInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap>(element: FunctionalElementInstance<PropertyInitGeneric>, eventsMap: EventDescriptorMap<EventsInitGeneric>): RenderParams<PropertyInitGeneric, EventsInitGeneric>;
21
+ export declare function createRenderParams<PropertyInitGeneric extends PropertyInitMapBase, EventsInitGeneric extends EventsInitMap>(element: FunctionalElementInstanceFromInit<PropertyInitGeneric>, eventsMap: EventDescriptorMap<EventsInitGeneric>): RenderParams<PropertyInitGeneric, EventsInitGeneric>;
@@ -0,0 +1,16 @@
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 declare type StylesCallbackInput<HostClassKeys extends string, CssVarKeys extends string> = {
6
+ hostClass: Record<HostClassKeys, CSSResult>;
7
+ cssVarName: Record<CssVarKeys, CSSResult>;
8
+ cssVarValue: Record<CssVarKeys, CSSResult>;
9
+ };
10
+ export declare type StylesCallback<HostClassKeys extends string, CssVarKeys extends string> = (input: StylesCallbackInput<HostClassKeys, CssVarKeys>) => CSSResult;
11
+ export declare function hostClassNamesToStylesInput<HostClassKeys extends string, CssVarKeys extends string>({ hostClassNames, cssVarNames, cssVarValues, }: {
12
+ hostClassNames: HostClassNamesMap<string, HostClassKeys>;
13
+ cssVarNames: CssVarNameOrValueMap<CssVarKeys>;
14
+ cssVarValues: CssVarNameOrValueMap<CssVarKeys>;
15
+ }): StylesCallbackInput<HostClassKeys, CssVarKeys>;
16
+ export declare function applyHostClasses<PropertyInitGeneric extends PropertyInitMapBase, HostClassKeys extends string>(host: HTMLElement, hostClassesInit: Readonly<HostClassesInitMap<HostClassKeys, PropertyInitGeneric>> | undefined, hostClassNames: HostClassNamesMap<string, HostClassKeys>, props: Readonly<PropertyInitGeneric>): void;
@@ -0,0 +1,29 @@
1
+ import { getObjectTypedKeys, mapObject } from 'augment-vir';
2
+ import { unsafeCSS } from 'lit';
3
+ export function hostClassNamesToStylesInput({ hostClassNames, cssVarNames, cssVarValues, }) {
4
+ return {
5
+ hostClass: mapObject(hostClassNames, (key, name) => {
6
+ return unsafeCSS(`:host(.${name})`);
7
+ }),
8
+ cssVarName: cssVarNames,
9
+ cssVarValue: cssVarValues,
10
+ };
11
+ }
12
+ export function applyHostClasses(host, hostClassesInit, hostClassNames, props) {
13
+ if (!hostClassesInit) {
14
+ return;
15
+ }
16
+ getObjectTypedKeys(hostClassesInit).forEach((hostClassKey) => {
17
+ const maybeCallback = hostClassesInit[hostClassKey];
18
+ const hostClassName = hostClassNames[hostClassKey];
19
+ if (typeof maybeCallback === 'function') {
20
+ const shouldApplyHostClass = maybeCallback({ props });
21
+ if (shouldApplyHostClass) {
22
+ host.classList.add(hostClassName);
23
+ }
24
+ else {
25
+ host.classList.remove(hostClassName);
26
+ }
27
+ }
28
+ });
29
+ }
@@ -0,0 +1,2 @@
1
+ export declare 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>;
@@ -0,0 +1,4 @@
1
+ import { camelCaseToKebabCase } from 'augment-vir';
2
+ export function toHtmlSafeWithTagName(tagName, forHtmlSafe) {
3
+ return `${tagName}-${camelCaseToKebabCase(forHtmlSafe)}`;
4
+ }
File without changes
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "element-vir",
3
- "version": "5.4.2",
3
+ "version": "5.6.0",
4
4
  "keywords": [
5
5
  "custom",
6
6
  "web",
@@ -22,11 +22,10 @@
22
22
  "name": "electrovir",
23
23
  "url": "https://github.com/electrovir"
24
24
  },
25
- "main": "dist/cjs/index.js",
26
- "module": "dist/esm/index.js",
27
- "types": "dist/types/index.d.ts",
25
+ "main": "dist/index.js",
26
+ "types": "dist/index.d.ts",
28
27
  "scripts": {
29
- "compile": "rm -rf dist && tsc --project tsconfig.json && tsc --project tsconfig.cjs.json && tsc --project tsconfig.esm.json",
28
+ "compile": "rm -rf dist && tsc --project tsconfig.json",
30
29
  "format": "virmator format write",
31
30
  "jest": "jest --config ./src/jest/jest.config.ts",
32
31
  "prepublishOnly": "npm run compile && npm run test:full",
@@ -38,12 +37,12 @@
38
37
  "update-docs": "virmator code-in-markdown README.md --index src/index.ts"
39
38
  },
40
39
  "dependencies": {
41
- "augment-vir": "2.2.0",
42
- "lit": "2.2.3"
40
+ "augment-vir": "2.2.1",
41
+ "lit": "2.2.7"
43
42
  },
44
43
  "devDependencies": {
45
- "jest-environment-jsdom": "28.1.0",
44
+ "jest-environment-jsdom": "28.1.2",
46
45
  "virmator": "2.0.7",
47
- "vite": "2.9.8"
46
+ "vite": "2.9.13"
48
47
  }
49
48
  }
@@ -1,7 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.filterOutArrayIndexes = void 0;
4
- function filterOutArrayIndexes(array, indexes) {
5
- return array.filter((_, index) => !indexes.includes(index));
6
- }
7
- exports.filterOutArrayIndexes = filterOutArrayIndexes;
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,4 +0,0 @@
1
- import { EventsInitMap } from './element-events';
2
- import { PropertyInitMapBase } from './element-properties';
3
- import { FunctionalElement, FunctionalElementInit } from './functional-element';
4
- export declare function defineFunctionalElement<EventsInitGeneric extends EventsInitMap = {}, PropertyInitGeneric extends PropertyInitMapBase = {}>(functionalElementInit: FunctionalElementInit<PropertyInitGeneric, EventsInitGeneric>): FunctionalElement<PropertyInitGeneric, EventsInitGeneric>;