@microsoft/fast-element 2.0.0-beta.8 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/.eslintrc.json +1 -1
  2. package/CHANGELOG.json +512 -0
  3. package/CHANGELOG.md +180 -1
  4. package/README.md +1 -9
  5. package/api-extractor.context.json +14 -0
  6. package/api-extractor.di.json +14 -0
  7. package/dist/context/context.api.json +1068 -0
  8. package/dist/di/di.api.json +4929 -0
  9. package/dist/dts/binding/binding.d.ts +49 -0
  10. package/dist/dts/binding/normalize.d.ts +9 -0
  11. package/dist/dts/binding/one-time.d.ts +11 -0
  12. package/dist/dts/binding/one-way.d.ts +20 -0
  13. package/dist/dts/{templating/binding-signal.d.ts → binding/signal.d.ts} +19 -4
  14. package/dist/dts/{templating/binding-two-way.d.ts → binding/two-way.d.ts} +9 -5
  15. package/dist/dts/components/attributes.d.ts +6 -0
  16. package/dist/dts/components/element-controller.d.ts +104 -8
  17. package/dist/dts/components/element-hydration.d.ts +2 -0
  18. package/dist/dts/components/fast-definitions.d.ts +6 -0
  19. package/dist/dts/components/hydration.d.ts +56 -0
  20. package/dist/dts/components/install-hydration.d.ts +1 -0
  21. package/dist/dts/context.d.ts +29 -15
  22. package/dist/dts/di/di.d.ts +0 -5
  23. package/dist/dts/dom-policy.d.ts +83 -0
  24. package/dist/dts/dom.d.ts +100 -0
  25. package/dist/dts/hydration/target-builder.d.ts +63 -0
  26. package/dist/dts/index.d.ts +33 -26
  27. package/dist/dts/index.rollup.d.ts +0 -1
  28. package/dist/dts/index.rollup.debug.d.ts +0 -1
  29. package/dist/dts/interfaces.d.ts +32 -82
  30. package/dist/dts/metadata.d.ts +6 -5
  31. package/dist/dts/observation/arrays.d.ts +1 -1
  32. package/dist/dts/observation/observable.bench.d.ts +18 -0
  33. package/dist/dts/observation/observable.d.ts +5 -5
  34. package/dist/dts/pending-task.d.ts +19 -7
  35. package/dist/dts/platform.d.ts +11 -2
  36. package/dist/dts/polyfills.d.ts +0 -8
  37. package/dist/dts/styles/css-binding-directive.d.ts +60 -0
  38. package/dist/dts/styles/css.d.ts +9 -7
  39. package/dist/dts/styles/element-styles.d.ts +1 -14
  40. package/dist/dts/styles/host.d.ts +2 -5
  41. package/dist/dts/styles/style-strategy.d.ts +42 -0
  42. package/dist/dts/templating/compiler.d.ts +11 -13
  43. package/dist/dts/templating/{binding.d.ts → html-binding-directive.d.ts} +22 -42
  44. package/dist/dts/templating/html-directive.d.ts +44 -140
  45. package/dist/dts/templating/install-hydratable-view-templates.d.ts +1 -0
  46. package/dist/dts/templating/node-observation.d.ts +11 -1
  47. package/dist/dts/templating/ref.d.ts +4 -0
  48. package/dist/dts/templating/render.bench.d.ts +3 -0
  49. package/dist/dts/templating/render.d.ts +49 -9
  50. package/dist/dts/templating/repeat-basic-reverse.bench.d.ts +3 -0
  51. package/dist/dts/templating/repeat-basic-shift.bench.d.ts +3 -0
  52. package/dist/dts/templating/repeat.d.ts +31 -9
  53. package/dist/dts/templating/template.d.ts +97 -12
  54. package/dist/dts/templating/view.d.ts +149 -26
  55. package/dist/dts/templating/when-basic.bench.d.ts +3 -0
  56. package/dist/dts/templating/when-conditional.bench.d.ts +3 -0
  57. package/dist/dts/templating/when-switch.bench.d.ts +3 -0
  58. package/dist/dts/templating/when.d.ts +3 -1
  59. package/dist/dts/testing/fakes.d.ts +12 -1
  60. package/dist/dts/tsdoc-metadata.json +1 -1
  61. package/dist/dts/utilities.d.ts +55 -1
  62. package/dist/esm/binding/binding.js +18 -0
  63. package/dist/esm/binding/normalize.js +17 -0
  64. package/dist/esm/binding/one-time.js +21 -0
  65. package/dist/esm/binding/one-way.js +30 -0
  66. package/dist/esm/{templating/binding-signal.js → binding/signal.js} +22 -6
  67. package/dist/esm/{templating/binding-two-way.js → binding/two-way.js} +18 -12
  68. package/dist/esm/components/attributes.js +16 -1
  69. package/dist/esm/components/element-controller.js +319 -49
  70. package/dist/esm/components/element-hydration.js +2 -0
  71. package/dist/esm/components/fast-definitions.js +12 -4
  72. package/dist/esm/components/fast-element.js +3 -1
  73. package/dist/esm/components/hydration.js +104 -0
  74. package/dist/esm/components/install-hydration.js +3 -0
  75. package/dist/esm/context.js +26 -4
  76. package/dist/esm/debug.js +8 -2
  77. package/dist/esm/di/di.js +9 -12
  78. package/dist/esm/dom-policy.js +345 -0
  79. package/dist/esm/dom.js +101 -0
  80. package/dist/esm/hydration/target-builder.js +175 -0
  81. package/dist/esm/index.js +34 -25
  82. package/dist/esm/index.rollup.debug.js +3 -1
  83. package/dist/esm/index.rollup.js +3 -1
  84. package/dist/esm/interfaces.js +51 -3
  85. package/dist/esm/metadata.js +11 -8
  86. package/dist/esm/observation/arrays.js +1 -1
  87. package/dist/esm/observation/observable.bench.js +79 -0
  88. package/dist/esm/observation/observable.js +20 -15
  89. package/dist/esm/observation/update-queue.js +2 -2
  90. package/dist/esm/pending-task.js +13 -1
  91. package/dist/esm/platform.js +12 -2
  92. package/dist/esm/polyfills.js +3 -61
  93. package/dist/esm/styles/css-binding-directive.js +76 -0
  94. package/dist/esm/styles/css.js +14 -7
  95. package/dist/esm/styles/element-styles.js +0 -33
  96. package/dist/esm/styles/style-strategy.js +1 -0
  97. package/dist/esm/templating/children.js +8 -4
  98. package/dist/esm/templating/compiler.js +37 -44
  99. package/dist/esm/templating/html-binding-directive.js +218 -0
  100. package/dist/esm/templating/html-directive.js +25 -152
  101. package/dist/esm/templating/install-hydratable-view-templates.js +17 -0
  102. package/dist/esm/templating/node-observation.js +14 -8
  103. package/dist/esm/templating/ref.js +1 -1
  104. package/dist/esm/templating/render.bench.js +56 -0
  105. package/dist/esm/templating/render.js +74 -30
  106. package/dist/esm/templating/repeat-basic-reverse.bench.js +43 -0
  107. package/dist/esm/templating/repeat-basic-shift.bench.js +43 -0
  108. package/dist/esm/templating/repeat.js +116 -17
  109. package/dist/esm/templating/template.js +135 -60
  110. package/dist/esm/templating/view.js +259 -32
  111. package/dist/esm/templating/when-basic.bench.js +36 -0
  112. package/dist/esm/templating/when-conditional.bench.js +39 -0
  113. package/dist/esm/templating/when-switch.bench.js +68 -0
  114. package/dist/esm/templating/when.js +12 -5
  115. package/dist/esm/testing/fakes.js +32 -1
  116. package/dist/esm/testing/fixture.js +1 -1
  117. package/dist/esm/utilities.js +97 -1
  118. package/dist/fast-element.api.json +9804 -5622
  119. package/dist/fast-element.d.ts +813 -2386
  120. package/dist/fast-element.debug.js +2797 -974
  121. package/dist/fast-element.debug.min.js +3 -1
  122. package/dist/fast-element.js +2642 -825
  123. package/dist/fast-element.min.js +3 -1
  124. package/dist/fast-element.untrimmed.d.ts +669 -315
  125. package/docs/{api-report.md → api-report.api.md} +243 -158
  126. package/docs/context/api-report.api.md +69 -0
  127. package/docs/di/api-report.api.md +315 -0
  128. package/karma.conf.cjs +2 -1
  129. package/package.json +59 -47
  130. package/scripts/run-api-extractor.js +51 -0
  131. package/scripts/run-benchmarks.js +46 -0
  132. package/tensile.config.js +12 -0
  133. package/dist/dts/templating/dom.d.ts +0 -41
  134. package/dist/esm/templating/binding.js +0 -282
  135. package/dist/esm/templating/dom.js +0 -49
  136. package/docs/guide/declaring-templates.md +0 -230
  137. package/docs/guide/defining-elements.md +0 -214
  138. package/docs/guide/leveraging-css.md +0 -253
  139. package/docs/guide/next-steps.md +0 -13
  140. package/docs/guide/observables-and-state.md +0 -213
  141. package/docs/guide/using-directives.md +0 -576
  142. package/docs/guide/working-with-shadow-dom.md +0 -296
@@ -0,0 +1,68 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { attr, FASTElement, html, nullableNumberConverter, when } from "../index.js";
11
+ const emotionalTemplates = {
12
+ depressed: html `
13
+ <div>
14
+ <span>I'm so depressed :O</span>
15
+ </div>
16
+ `,
17
+ sad: html `
18
+ <div>
19
+ <span>I'm so sad :(</span>
20
+ </div>
21
+ `,
22
+ happy: html `
23
+ <div>
24
+ <span>I'm so happy :)</span>
25
+ </div>
26
+ `,
27
+ ecstatic: html `
28
+ <div>
29
+ <span>I'm so ecstatic :D</span>
30
+ </div>
31
+ `,
32
+ indifferent: html `
33
+ <div>
34
+ <span>I'm indifferent :|</span>
35
+ </div>
36
+ `,
37
+ };
38
+ class TestWhen extends FASTElement {
39
+ constructor() {
40
+ super(...arguments);
41
+ this.value = 0;
42
+ }
43
+ }
44
+ __decorate([
45
+ attr({
46
+ mode: "fromView",
47
+ converter: nullableNumberConverter,
48
+ }),
49
+ __metadata("design:type", Number)
50
+ ], TestWhen.prototype, "value", void 0);
51
+ TestWhen.define({
52
+ name: "test-when",
53
+ template: html `
54
+ <button @click="${x => x.update(true)}">Click Me</button>
55
+ ${when(x => x.value <= 1, emotionalTemplates.depressed)}
56
+ ${when(x => x.value === 2 || x.value === 3, emotionalTemplates.sad)}
57
+ ${when(x => x.value === 4 || x.value === 5, emotionalTemplates.indifferent)}
58
+ ${when(x => x.value >= 6 && x.value < 9, emotionalTemplates.happy)}
59
+ ${when(x => x.value === 9 || x.value === 10, emotionalTemplates.ecstatic)}
60
+ `,
61
+ });
62
+ const itemRenderer = () => {
63
+ const testWhen = document.createElement("test-when");
64
+ testWhen.click();
65
+ return testWhen;
66
+ };
67
+ export default itemRenderer;
68
+ export { tests } from "@tensile-perf/web-components";
@@ -1,15 +1,22 @@
1
1
  import { isFunction } from "../interfaces.js";
2
+ const noTemplate = () => null;
3
+ function normalizeBinding(value) {
4
+ return value === undefined ? noTemplate : isFunction(value) ? value : () => value;
5
+ }
2
6
  /**
3
7
  * A directive that enables basic conditional rendering in a template.
4
8
  * @param condition - The condition to test for rendering.
5
9
  * @param templateOrTemplateBinding - The template or a binding that gets
6
10
  * the template to render when the condition is true.
11
+ * @param elseTemplateOrTemplateBinding - Optional template or binding that that
12
+ * gets the template to render when the conditional is false.
7
13
  * @public
8
14
  */
9
- export function when(condition, templateOrTemplateBinding) {
15
+ export function when(condition, templateOrTemplateBinding, elseTemplateOrTemplateBinding) {
10
16
  const dataBinding = isFunction(condition) ? condition : () => condition;
11
- const templateBinding = isFunction(templateOrTemplateBinding)
12
- ? templateOrTemplateBinding
13
- : () => templateOrTemplateBinding;
14
- return (source, context) => dataBinding(source, context) ? templateBinding(source, context) : null;
17
+ const templateBinding = normalizeBinding(templateOrTemplateBinding);
18
+ const elseBinding = normalizeBinding(elseTemplateOrTemplateBinding);
19
+ return (source, context) => dataBinding(source, context)
20
+ ? templateBinding(source, context)
21
+ : elseBinding(source, context);
15
22
  }
@@ -1,4 +1,5 @@
1
- import { ExecutionContext } from "../index.js";
1
+ import { noop } from "../interfaces.js";
2
+ import { ExecutionContext } from "../observation/observable.js";
2
3
  export const Fake = Object.freeze({
3
4
  executionContext(parent, parentContext) {
4
5
  return {
@@ -73,4 +74,34 @@ export const Fake = Object.freeze({
73
74
  },
74
75
  };
75
76
  },
77
+ viewController(targets = {}, ...behaviors) {
78
+ const unbindables = new Set();
79
+ return {
80
+ isBound: false,
81
+ context: null,
82
+ onUnbind(object) {
83
+ unbindables.add(object);
84
+ },
85
+ source: null,
86
+ targets,
87
+ toJSON: noop,
88
+ bind(source, context = Fake.executionContext()) {
89
+ if (this.isBound) {
90
+ return;
91
+ }
92
+ this.source = source;
93
+ this.context = context;
94
+ behaviors.forEach(x => x.bind(this));
95
+ this.isBound = true;
96
+ },
97
+ unbind() {
98
+ if (this.isBound) {
99
+ unbindables.forEach(x => x.unbind(this));
100
+ this.source = null;
101
+ this.context = null;
102
+ this.isBound = false;
103
+ }
104
+ },
105
+ };
106
+ },
76
107
  });
@@ -46,7 +46,7 @@ export function fixture(templateNameOrType, options = {}) {
46
46
  }
47
47
  if (typeof templateNameOrType === "string") {
48
48
  const html = `<${templateNameOrType}></${templateNameOrType}>`;
49
- templateNameOrType = new ViewTemplate(html, {});
49
+ templateNameOrType = new ViewTemplate(html);
50
50
  }
51
51
  const view = templateNameOrType.create();
52
52
  const element = findElement(view);
@@ -1,3 +1,6 @@
1
+ import { DOM } from "./dom.js";
2
+ import { ExecutionContext } from "./observation/observable.js";
3
+ import { nextId } from "./templating/markup.js";
1
4
  /**
2
5
  * Retrieves the "composed parent" element of a node, ignoring DOM tree boundaries.
3
6
  * When the parent of a node is a shadow-root, it will return the host
@@ -25,7 +28,7 @@ export function composedParent(element) {
25
28
  * Determines if the reference element contains the test element in a "composed" DOM tree that
26
29
  * ignores shadow DOM boundaries.
27
30
  *
28
- * Returns true of the test element is a descendent of the reference, or exist in
31
+ * Returns true of the test element is a descendent of the reference, or exists in
29
32
  * a shadow DOM that is a logical descendent of the reference. Otherwise returns false.
30
33
  * @param reference - The element to test for containment against.
31
34
  * @param test - The element being tested for containment.
@@ -42,3 +45,96 @@ export function composedContains(reference, test) {
42
45
  }
43
46
  return false;
44
47
  }
48
+ /**
49
+ * An extension of MutationObserver that supports unobserving nodes.
50
+ * @internal
51
+ */
52
+ export class UnobservableMutationObserver extends MutationObserver {
53
+ /**
54
+ * Creates an instance of UnobservableMutationObserver.
55
+ * @param callback - The callback to invoke when observed nodes are changed.
56
+ */
57
+ constructor(callback) {
58
+ function handler(mutations) {
59
+ this.callback.call(null, mutations.filter(record => this.observedNodes.has(record.target)));
60
+ }
61
+ super(handler);
62
+ this.callback = callback;
63
+ this.observedNodes = new Set();
64
+ }
65
+ observe(target, options) {
66
+ this.observedNodes.add(target);
67
+ super.observe(target, options);
68
+ }
69
+ unobserve(target) {
70
+ this.observedNodes.delete(target);
71
+ if (this.observedNodes.size < 1) {
72
+ this.disconnect();
73
+ }
74
+ }
75
+ }
76
+ /**
77
+ * Bridges between ViewBehaviors and HostBehaviors, enabling a host to
78
+ * control ViewBehaviors.
79
+ * @public
80
+ */
81
+ export const ViewBehaviorOrchestrator = Object.freeze({
82
+ /**
83
+ * Creates a ViewBehaviorOrchestrator.
84
+ * @param source - The source to to associate behaviors with.
85
+ * @returns A ViewBehaviorOrchestrator.
86
+ */
87
+ create(source) {
88
+ const behaviors = [];
89
+ const targets = {};
90
+ let unbindables = null;
91
+ let isConnected = false;
92
+ return {
93
+ source,
94
+ context: ExecutionContext.default,
95
+ targets,
96
+ get isBound() {
97
+ return isConnected;
98
+ },
99
+ addBehaviorFactory(factory, target) {
100
+ var _a, _b, _c, _d;
101
+ const compiled = factory;
102
+ compiled.id = (_a = compiled.id) !== null && _a !== void 0 ? _a : nextId();
103
+ compiled.targetNodeId = (_b = compiled.targetNodeId) !== null && _b !== void 0 ? _b : nextId();
104
+ compiled.targetTagName = (_c = target.tagName) !== null && _c !== void 0 ? _c : null;
105
+ compiled.policy = (_d = compiled.policy) !== null && _d !== void 0 ? _d : DOM.policy;
106
+ this.addTarget(compiled.targetNodeId, target);
107
+ this.addBehavior(compiled.createBehavior());
108
+ },
109
+ addTarget(nodeId, target) {
110
+ targets[nodeId] = target;
111
+ },
112
+ addBehavior(behavior) {
113
+ behaviors.push(behavior);
114
+ if (isConnected) {
115
+ behavior.bind(this);
116
+ }
117
+ },
118
+ onUnbind(unbindable) {
119
+ if (unbindables === null) {
120
+ unbindables = [];
121
+ }
122
+ unbindables.push(unbindable);
123
+ },
124
+ connectedCallback(controller) {
125
+ if (!isConnected) {
126
+ isConnected = true;
127
+ behaviors.forEach(x => x.bind(this));
128
+ }
129
+ },
130
+ disconnectedCallback(controller) {
131
+ if (isConnected) {
132
+ isConnected = false;
133
+ if (unbindables !== null) {
134
+ unbindables.forEach(x => x.unbind(this));
135
+ }
136
+ }
137
+ },
138
+ };
139
+ },
140
+ });