@microsoft/fast-element 3.0.0-rc.1 → 3.0.0-rc.2

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 (286) hide show
  1. package/CHANGELOG.md +51 -1
  2. package/README.md +50 -14
  3. package/dist/context/context.api.json +13 -13
  4. package/dist/declarative/declarative.api.json +654 -15
  5. package/dist/di/di.api.json +15 -15
  6. package/dist/dts/__test__/helpers.d.ts +6 -0
  7. package/dist/dts/__test__/setup-node.d.ts +0 -0
  8. package/dist/dts/binding/binding.d.ts +15 -5
  9. package/dist/dts/binding/one-time.d.ts +1 -1
  10. package/dist/dts/binding/one-way.d.ts +1 -1
  11. package/dist/dts/binding/signal.d.ts +1 -1
  12. package/dist/dts/binding/two-way.d.ts +1 -1
  13. package/dist/dts/components/attributes.d.ts +1 -1
  14. package/dist/dts/components/enable-hydration.d.ts +22 -2
  15. package/dist/dts/components/fast-definitions.d.ts +7 -4
  16. package/dist/dts/components/fast-element.d.ts +42 -12
  17. package/dist/dts/components/hydration-tracker.d.ts +47 -4
  18. package/dist/dts/components/hydration.d.ts +5 -0
  19. package/dist/dts/context.d.ts +7 -7
  20. package/dist/dts/declarative/debug.d.ts +2 -3
  21. package/dist/dts/declarative/index.d.ts +3 -2
  22. package/dist/dts/declarative/interfaces.d.ts +1 -2
  23. package/dist/dts/declarative/template.d.ts +2 -1
  24. package/dist/dts/declarative/utilities.d.ts +50 -4
  25. package/dist/dts/di/di.d.ts +6 -6
  26. package/dist/dts/dom-policy.d.ts +22 -4
  27. package/dist/dts/dom.d.ts +4 -16
  28. package/dist/dts/hydration/diagnostics.d.ts +93 -0
  29. package/dist/dts/hydration/hydration-debugger.d.ts +35 -0
  30. package/dist/dts/hydration/messages.d.ts +62 -0
  31. package/dist/dts/hydration/target-builder.d.ts +26 -1
  32. package/dist/dts/hydration.d.ts +7 -3
  33. package/dist/dts/index.d.ts +7 -3
  34. package/dist/dts/interfaces.d.ts +1 -0
  35. package/dist/dts/observation/observable.d.ts +3 -3
  36. package/dist/dts/platform.d.ts +20 -4
  37. package/dist/dts/registry.d.ts +1 -0
  38. package/dist/dts/templating/children.d.ts +1 -1
  39. package/dist/dts/templating/compiler.d.ts +1 -1
  40. package/dist/dts/templating/html-binding-directive.d.ts +6 -2
  41. package/dist/dts/templating/html-directive.d.ts +2 -1
  42. package/dist/dts/templating/hydration-view.d.ts +24 -3
  43. package/dist/dts/templating/ref.d.ts +1 -1
  44. package/dist/dts/templating/render.d.ts +2 -2
  45. package/dist/dts/templating/repeat.d.ts +1 -1
  46. package/dist/dts/templating/slotted.d.ts +1 -1
  47. package/dist/dts/templating/template.d.ts +5 -5
  48. package/dist/dts/templating/when.d.ts +1 -1
  49. package/dist/dts/testing/fakes.d.ts +4 -4
  50. package/dist/esm/__test__/helpers.js +22 -0
  51. package/dist/esm/__test__/setup-node.js +18 -0
  52. package/dist/esm/binding/two-way.js +1 -2
  53. package/dist/esm/components/attributes.js +12 -8
  54. package/dist/esm/components/element-controller.js +11 -6
  55. package/dist/esm/components/enable-hydration.js +27 -3
  56. package/dist/esm/components/fast-definitions.js +19 -18
  57. package/dist/esm/components/hydration-tracker.js +34 -5
  58. package/dist/esm/components/hydration.js +85 -6
  59. package/dist/esm/debug.js +1 -0
  60. package/dist/esm/declarative/attribute-map.js +2 -1
  61. package/dist/esm/declarative/debug.js +0 -1
  62. package/dist/esm/declarative/index.js +1 -0
  63. package/dist/esm/declarative/interfaces.js +0 -1
  64. package/dist/esm/declarative/observer-map-utilities.js +58 -55
  65. package/dist/esm/declarative/template-bridge.js +4 -14
  66. package/dist/esm/declarative/template.js +4 -3
  67. package/dist/esm/declarative/utilities.js +236 -1
  68. package/dist/esm/di/di.js +2 -1
  69. package/dist/esm/dom-policy.js +33 -4
  70. package/dist/esm/hydration/diagnostics.js +50 -0
  71. package/dist/esm/hydration/hydration-debugger.js +112 -0
  72. package/dist/esm/hydration/messages.js +84 -0
  73. package/dist/esm/hydration/target-builder.js +65 -19
  74. package/dist/esm/hydration.js +3 -1
  75. package/dist/esm/index.js +6 -2
  76. package/dist/esm/interfaces.js +1 -0
  77. package/dist/esm/metadata.js +2 -8
  78. package/dist/esm/observation/notifier.js +2 -4
  79. package/dist/esm/registry.js +1 -0
  80. package/dist/esm/templating/html-binding-directive.js +1 -1
  81. package/dist/esm/templating/hydration-view.js +20 -27
  82. package/dist/esm/templating/render.js +39 -18
  83. package/dist/esm/templating/repeat.js +51 -17
  84. package/dist/esm/templating/view.js +1 -1
  85. package/dist/esm/testing/fixture.js +2 -2
  86. package/dist/esm/testing/timeout.js +2 -2
  87. package/dist/fast-element.api.json +1329 -99
  88. package/dist/fast-element.d.ts +147 -66
  89. package/dist/fast-element.debug.js +392 -99
  90. package/dist/fast-element.debug.min.js +2 -2
  91. package/dist/fast-element.js +392 -99
  92. package/dist/fast-element.min.js +2 -2
  93. package/dist/fast-element.untrimmed.d.ts +133 -70
  94. package/dist/hydration/hydration.api.json +1280 -57
  95. package/dist/styles/styles.api.json +1 -1
  96. package/package.json +21 -9
  97. package/ARCHITECTURE_FASTELEMENT.md +0 -63
  98. package/ARCHITECTURE_HTML_TAGGED_TEMPLATE_LITERAL.md +0 -36
  99. package/ARCHITECTURE_INTRO.md +0 -10
  100. package/ARCHITECTURE_OVERVIEW.md +0 -52
  101. package/ARCHITECTURE_UPDATES.md +0 -11
  102. package/CHANGELOG.json +0 -2275
  103. package/DECLARATIVE_DESIGN.md +0 -806
  104. package/DECLARATIVE_HTML.md +0 -470
  105. package/DECLARATIVE_MIGRATION.md +0 -215
  106. package/DECLARATIVE_RENDERING.md +0 -530
  107. package/DECLARATIVE_RENDERING_LIFECYCLE.md +0 -288
  108. package/DECLARATIVE_SCHEMA_OBSERVER_MAP.md +0 -489
  109. package/DESIGN.md +0 -615
  110. package/MIGRATION.md +0 -387
  111. package/SIZES.md +0 -25
  112. package/api-extractor.arrays.json +0 -15
  113. package/api-extractor.context.json +0 -15
  114. package/api-extractor.declarative.json +0 -15
  115. package/api-extractor.di.json +0 -15
  116. package/api-extractor.hydration.json +0 -15
  117. package/api-extractor.styles.json +0 -15
  118. package/biome.json +0 -4
  119. package/docs/ACKNOWLEDGEMENTS.md +0 -12
  120. package/docs/api-report.api.md +0 -1299
  121. package/docs/arrays/api-report.api.md +0 -114
  122. package/docs/context/api-report.api.md +0 -69
  123. package/docs/declarative/api-report.api.md +0 -397
  124. package/docs/di/api-report.api.md +0 -315
  125. package/docs/fast-element-2-changes.md +0 -15
  126. package/docs/hydration/api-report.api.md +0 -285
  127. package/docs/styles/api-report.api.md +0 -135
  128. package/playwright.config.ts +0 -26
  129. package/playwright.declarative.config.ts +0 -26
  130. package/playwright.declarative.webui.config.ts +0 -20
  131. package/scripts/declarative/build-fixtures-with-webui.js +0 -135
  132. package/scripts/declarative/build-fixtures.js +0 -49
  133. package/scripts/declarative/build-fixtures.utilities.js +0 -101
  134. package/scripts/measure-sizes.js +0 -219
  135. package/scripts/run-api-extractor.js +0 -70
  136. package/test/declarative/fixtures/README.md +0 -72
  137. package/test/declarative/fixtures/WRITING_FIXTURES.md +0 -330
  138. package/test/declarative/fixtures/bindings/README.md +0 -12
  139. package/test/declarative/fixtures/bindings/attribute/entry.html +0 -13
  140. package/test/declarative/fixtures/bindings/attribute/fast-build.config.json +0 -6
  141. package/test/declarative/fixtures/bindings/attribute/index.html +0 -25
  142. package/test/declarative/fixtures/bindings/attribute/main.ts +0 -41
  143. package/test/declarative/fixtures/bindings/attribute/state.json +0 -8
  144. package/test/declarative/fixtures/bindings/attribute/templates.html +0 -11
  145. package/test/declarative/fixtures/bindings/content/entry.html +0 -12
  146. package/test/declarative/fixtures/bindings/content/fast-build.config.json +0 -6
  147. package/test/declarative/fixtures/bindings/content/index.html +0 -19
  148. package/test/declarative/fixtures/bindings/content/main.ts +0 -27
  149. package/test/declarative/fixtures/bindings/content/state.json +0 -4
  150. package/test/declarative/fixtures/bindings/content/templates.html +0 -6
  151. package/test/declarative/fixtures/bindings/dot-syntax/entry.html +0 -11
  152. package/test/declarative/fixtures/bindings/dot-syntax/fast-build.config.json +0 -6
  153. package/test/declarative/fixtures/bindings/dot-syntax/index.html +0 -47
  154. package/test/declarative/fixtures/bindings/dot-syntax/main.ts +0 -59
  155. package/test/declarative/fixtures/bindings/dot-syntax/state.json +0 -16
  156. package/test/declarative/fixtures/bindings/dot-syntax/templates.html +0 -17
  157. package/test/declarative/fixtures/bindings/event/entry.html +0 -11
  158. package/test/declarative/fixtures/bindings/event/fast-build.config.json +0 -6
  159. package/test/declarative/fixtures/bindings/event/index.html +0 -43
  160. package/test/declarative/fixtures/bindings/event/main.ts +0 -43
  161. package/test/declarative/fixtures/bindings/event/state.json +0 -3
  162. package/test/declarative/fixtures/bindings/event/templates.html +0 -18
  163. package/test/declarative/fixtures/bindings/host/entry.html +0 -40
  164. package/test/declarative/fixtures/bindings/host/fast-build.config.json +0 -6
  165. package/test/declarative/fixtures/bindings/host/index.html +0 -96
  166. package/test/declarative/fixtures/bindings/host/main.ts +0 -222
  167. package/test/declarative/fixtures/bindings/host/state.json +0 -9
  168. package/test/declarative/fixtures/bindings/host/templates.html +0 -55
  169. package/test/declarative/fixtures/directives/README.md +0 -12
  170. package/test/declarative/fixtures/directives/children/entry.html +0 -11
  171. package/test/declarative/fixtures/directives/children/fast-build.config.json +0 -6
  172. package/test/declarative/fixtures/directives/children/index.html +0 -15
  173. package/test/declarative/fixtures/directives/children/main.ts +0 -22
  174. package/test/declarative/fixtures/directives/children/state.json +0 -3
  175. package/test/declarative/fixtures/directives/children/templates.html +0 -3
  176. package/test/declarative/fixtures/directives/ref/entry.html +0 -11
  177. package/test/declarative/fixtures/directives/ref/fast-build.config.json +0 -6
  178. package/test/declarative/fixtures/directives/ref/index.html +0 -15
  179. package/test/declarative/fixtures/directives/ref/main.ts +0 -17
  180. package/test/declarative/fixtures/directives/ref/state.json +0 -1
  181. package/test/declarative/fixtures/directives/ref/templates.html +0 -3
  182. package/test/declarative/fixtures/directives/repeat/entry.html +0 -21
  183. package/test/declarative/fixtures/directives/repeat/fast-build.config.json +0 -6
  184. package/test/declarative/fixtures/directives/repeat/index.html +0 -133
  185. package/test/declarative/fixtures/directives/repeat/main.ts +0 -110
  186. package/test/declarative/fixtures/directives/repeat/sprites.svg +0 -8
  187. package/test/declarative/fixtures/directives/repeat/state.json +0 -10
  188. package/test/declarative/fixtures/directives/repeat/templates.html +0 -75
  189. package/test/declarative/fixtures/directives/slotted/entry.html +0 -17
  190. package/test/declarative/fixtures/directives/slotted/fast-build.config.json +0 -6
  191. package/test/declarative/fixtures/directives/slotted/index.html +0 -27
  192. package/test/declarative/fixtures/directives/slotted/main.ts +0 -29
  193. package/test/declarative/fixtures/directives/slotted/state.json +0 -1
  194. package/test/declarative/fixtures/directives/slotted/templates.html +0 -7
  195. package/test/declarative/fixtures/directives/when/entry.html +0 -51
  196. package/test/declarative/fixtures/directives/when/fast-build.config.json +0 -6
  197. package/test/declarative/fixtures/directives/when/index.html +0 -136
  198. package/test/declarative/fixtures/directives/when/main.ts +0 -172
  199. package/test/declarative/fixtures/directives/when/state.json +0 -12
  200. package/test/declarative/fixtures/directives/when/templates.html +0 -75
  201. package/test/declarative/fixtures/ecosystem/README.md +0 -11
  202. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/entry.html +0 -12
  203. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/fast-build.config.json +0 -6
  204. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/index.html +0 -20
  205. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/main.ts +0 -68
  206. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/state.json +0 -4
  207. package/test/declarative/fixtures/ecosystem/declarative-no-hydration/templates.html +0 -7
  208. package/test/declarative/fixtures/ecosystem/errors/entry.html +0 -12
  209. package/test/declarative/fixtures/ecosystem/errors/fast-build.config.json +0 -6
  210. package/test/declarative/fixtures/ecosystem/errors/index.html +0 -20
  211. package/test/declarative/fixtures/ecosystem/errors/main.ts +0 -17
  212. package/test/declarative/fixtures/ecosystem/errors/state.json +0 -1
  213. package/test/declarative/fixtures/ecosystem/errors/templates.html +0 -7
  214. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/entry.html +0 -17
  215. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/fast-build.config.json +0 -6
  216. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/index.html +0 -56
  217. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/main.ts +0 -134
  218. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/state.json +0 -12
  219. package/test/declarative/fixtures/ecosystem/lifecycle-callbacks/templates.html +0 -34
  220. package/test/declarative/fixtures/ecosystem/performance-metrics/entry.html +0 -25
  221. package/test/declarative/fixtures/ecosystem/performance-metrics/fast-build.config.json +0 -6
  222. package/test/declarative/fixtures/ecosystem/performance-metrics/fast-card.css +0 -10
  223. package/test/declarative/fixtures/ecosystem/performance-metrics/index.html +0 -181
  224. package/test/declarative/fixtures/ecosystem/performance-metrics/main.ts +0 -58
  225. package/test/declarative/fixtures/ecosystem/performance-metrics/state.json +0 -6
  226. package/test/declarative/fixtures/ecosystem/performance-metrics/templates.html +0 -15
  227. package/test/declarative/fixtures/extensions/README.md +0 -15
  228. package/test/declarative/fixtures/extensions/attribute-map/entry.html +0 -14
  229. package/test/declarative/fixtures/extensions/attribute-map/fast-build.config.json +0 -6
  230. package/test/declarative/fixtures/extensions/attribute-map/index.html +0 -31
  231. package/test/declarative/fixtures/extensions/attribute-map/main.ts +0 -40
  232. package/test/declarative/fixtures/extensions/attribute-map/state.json +0 -4
  233. package/test/declarative/fixtures/extensions/attribute-map/templates.html +0 -14
  234. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/entry.html +0 -12
  235. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/fast-build.config.json +0 -7
  236. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/index.html +0 -25
  237. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/main.ts +0 -31
  238. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/state.json +0 -5
  239. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy/templates.html +0 -11
  240. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/entry.html +0 -13
  241. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/fast-build.config.json +0 -7
  242. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/index.html +0 -23
  243. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/main.ts +0 -37
  244. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/state.json +0 -1
  245. package/test/declarative/fixtures/extensions/attribute-map-naming-strategy-camel-case/templates.html +0 -9
  246. package/test/declarative/fixtures/extensions/observer-map/entry.html +0 -15
  247. package/test/declarative/fixtures/extensions/observer-map/fast-build.config.json +0 -6
  248. package/test/declarative/fixtures/extensions/observer-map/index.html +0 -442
  249. package/test/declarative/fixtures/extensions/observer-map/main.ts +0 -482
  250. package/test/declarative/fixtures/extensions/observer-map/state.json +0 -158
  251. package/test/declarative/fixtures/extensions/observer-map/templates.html +0 -172
  252. package/test/declarative/fixtures/extensions/observer-map-config-object/entry.html +0 -16
  253. package/test/declarative/fixtures/extensions/observer-map-config-object/fast-build.config.json +0 -6
  254. package/test/declarative/fixtures/extensions/observer-map-config-object/index.html +0 -27
  255. package/test/declarative/fixtures/extensions/observer-map-config-object/main.ts +0 -53
  256. package/test/declarative/fixtures/extensions/observer-map-config-object/state.json +0 -9
  257. package/test/declarative/fixtures/extensions/observer-map-config-object/templates.html +0 -12
  258. package/test/declarative/fixtures/extensions/observer-map-deep-merge/README.md +0 -98
  259. package/test/declarative/fixtures/extensions/observer-map-deep-merge/entry.html +0 -156
  260. package/test/declarative/fixtures/extensions/observer-map-deep-merge/fast-build.config.json +0 -6
  261. package/test/declarative/fixtures/extensions/observer-map-deep-merge/index.html +0 -376
  262. package/test/declarative/fixtures/extensions/observer-map-deep-merge/main.ts +0 -366
  263. package/test/declarative/fixtures/extensions/observer-map-deep-merge/state.json +0 -69
  264. package/test/declarative/fixtures/extensions/observer-map-deep-merge/templates.html +0 -91
  265. package/test/declarative/fixtures/extensions/observer-map-properties/entry.html +0 -14
  266. package/test/declarative/fixtures/extensions/observer-map-properties/fast-build.config.json +0 -6
  267. package/test/declarative/fixtures/extensions/observer-map-properties/index.html +0 -110
  268. package/test/declarative/fixtures/extensions/observer-map-properties/main.ts +0 -175
  269. package/test/declarative/fixtures/extensions/observer-map-properties/state.json +0 -29
  270. package/test/declarative/fixtures/extensions/observer-map-properties/templates.html +0 -55
  271. package/test/declarative/fixtures/scenarios/README.md +0 -7
  272. package/test/declarative/fixtures/scenarios/nested-elements/entry.html +0 -16
  273. package/test/declarative/fixtures/scenarios/nested-elements/fast-build.config.json +0 -6
  274. package/test/declarative/fixtures/scenarios/nested-elements/index.html +0 -126
  275. package/test/declarative/fixtures/scenarios/nested-elements/main.ts +0 -214
  276. package/test/declarative/fixtures/scenarios/nested-elements/state.json +0 -10
  277. package/test/declarative/fixtures/scenarios/nested-elements/templates.html +0 -54
  278. package/test/declarative/index.html +0 -12
  279. package/test/declarative/vite.config.ts +0 -55
  280. package/test/declarative-main.ts +0 -6
  281. package/test/extension-subpaths-main.ts +0 -9
  282. package/test/index.html +0 -11
  283. package/test/main.ts +0 -109
  284. package/test/pure-declarative-main.ts +0 -1
  285. package/test/vite.config.ts +0 -19
  286. package/tsconfig.api-extractor.json +0 -6
@@ -1,175 +0,0 @@
1
- import { declarativeTemplate } from "@microsoft/fast-element/declarative.js";
2
- import { FASTElement } from "@microsoft/fast-element/fast-element.js";
3
- import { observerMap } from "@microsoft/fast-element/observer-map.js";
4
-
5
- class SelectiveObsElement extends FASTElement {
6
- public user = {
7
- name: "Alice",
8
- age: 28,
9
- history: {
10
- joined: "2020-01-01",
11
- visits: 100,
12
- },
13
- location: {
14
- city: "New York",
15
- country: "USA",
16
- },
17
- };
18
-
19
- public settings = {
20
- theme: "dark",
21
- language: "en",
22
- };
23
-
24
- public analytics = {
25
- charts: {
26
- activeChart: "line",
27
- cachedData: "heavy-data",
28
- },
29
- summary: "good",
30
- };
31
-
32
- public updateUserName = () => {
33
- this.user.name = "Bob";
34
- };
35
-
36
- public updateUserAge = () => {
37
- this.user.age = 29;
38
- };
39
-
40
- public updateHistory = () => {
41
- this.user.history.visits = 200;
42
- };
43
-
44
- public updateLocation = () => {
45
- this.user.location.city = "London";
46
- };
47
-
48
- public updateSettings = () => {
49
- this.settings.theme = "light";
50
- };
51
-
52
- public updateActiveChart = () => {
53
- this.analytics.charts.activeChart = "bar";
54
- };
55
-
56
- public updateCachedData = () => {
57
- this.analytics.charts.cachedData = "updated-heavy-data";
58
- };
59
-
60
- public updateSummary = () => {
61
- this.analytics.summary = "excellent";
62
- };
63
- }
64
-
65
- SelectiveObsElement.define(
66
- {
67
- name: "selective-obs-element",
68
- template: declarativeTemplate(),
69
- },
70
- [
71
- observerMap({
72
- properties: {
73
- user: {
74
- name: true,
75
- age: true,
76
- history: false,
77
- location: true,
78
- },
79
- // settings is NOT listed → skipped
80
- analytics: {
81
- charts: {
82
- $observe: false,
83
- activeChart: true,
84
- },
85
- summary: true,
86
- },
87
- },
88
- }),
89
- ],
90
- );
91
-
92
- class AllObsElement extends FASTElement {
93
- public user = {
94
- name: "Alice",
95
- };
96
-
97
- public settings = {
98
- theme: "dark",
99
- };
100
-
101
- public updateUserName = () => {
102
- this.user.name = "Bob";
103
- };
104
-
105
- public updateSettings = () => {
106
- this.settings.theme = "light";
107
- };
108
- }
109
-
110
- AllObsElement.define(
111
- {
112
- name: "all-obs-element",
113
- template: declarativeTemplate(),
114
- },
115
- [observerMap()],
116
- );
117
-
118
- class EmptyPropsElement extends FASTElement {
119
- public user = {
120
- name: "Alice",
121
- };
122
-
123
- public settings = {
124
- theme: "dark",
125
- };
126
-
127
- public updateUserName = () => {
128
- this.user.name = "Bob";
129
- };
130
-
131
- public updateSettings = () => {
132
- this.settings.theme = "light";
133
- };
134
- }
135
-
136
- EmptyPropsElement.define(
137
- {
138
- name: "empty-props-element",
139
- template: declarativeTemplate(),
140
- },
141
- [
142
- observerMap({
143
- properties: {},
144
- }),
145
- ],
146
- );
147
-
148
- class ArraySelectiveElement extends FASTElement {
149
- public items: any[] = [
150
- { text: "item-1", meta: { count: 1 } },
151
- { text: "item-2", meta: { count: 2 } },
152
- ];
153
-
154
- public updateItemText = () => {
155
- this.items[0].text = "updated-item-1";
156
- };
157
-
158
- public addItem = () => {
159
- this.items.push({ text: "item-3", meta: { count: 3 } });
160
- };
161
- }
162
-
163
- ArraySelectiveElement.define(
164
- {
165
- name: "array-selective-element",
166
- template: declarativeTemplate(),
167
- },
168
- [
169
- observerMap({
170
- properties: {
171
- items: true,
172
- },
173
- }),
174
- ],
175
- );
@@ -1,29 +0,0 @@
1
- {
2
- "user": {
3
- "name": "Alice",
4
- "age": 28,
5
- "history": {
6
- "joined": "2020-01-01",
7
- "visits": 100
8
- },
9
- "location": {
10
- "city": "New York",
11
- "country": "USA"
12
- }
13
- },
14
- "settings": {
15
- "theme": "dark",
16
- "language": "en"
17
- },
18
- "analytics": {
19
- "charts": {
20
- "activeChart": "line",
21
- "cachedData": "heavy-data"
22
- },
23
- "summary": "good"
24
- },
25
- "items": [
26
- { "text": "item-1", "meta": { "count": 1 } },
27
- { "text": "item-2", "meta": { "count": 2 } }
28
- ]
29
- }
@@ -1,55 +0,0 @@
1
- <f-template name="selective-obs-element">
2
- <template>
3
- <div class="user-section">
4
- <span class="user-name">{{user.name}}</span>
5
- <span class="user-age">{{user.age}}</span>
6
- <span class="user-history-joined">{{user.history.joined}}</span>
7
- <span class="user-history-visits">{{user.history.visits}}</span>
8
- <span class="user-location-city">{{user.location.city}}</span>
9
- </div>
10
- <div class="settings-section">
11
- <span class="settings-theme">{{settings.theme}}</span>
12
- </div>
13
- <div class="analytics-section">
14
- <span class="active-chart">{{analytics.charts.activeChart}}</span>
15
- <span class="cached-data">{{analytics.charts.cachedData}}</span>
16
- <span class="analytics-summary">{{analytics.summary}}</span>
17
- </div>
18
- <button @click="{updateUserName()}">Update Name</button>
19
- <button @click="{updateUserAge()}">Update Age</button>
20
- <button @click="{updateHistory()}">Update History</button>
21
- <button @click="{updateLocation()}">Update Location</button>
22
- <button @click="{updateSettings()}">Update Settings</button>
23
- <button @click="{updateActiveChart()}">Update Active Chart</button>
24
- <button @click="{updateCachedData()}">Update Cached Data</button>
25
- <button @click="{updateSummary()}">Update Summary</button>
26
- </template>
27
- </f-template>
28
- <f-template name="all-obs-element">
29
- <template>
30
- <span class="user-name">{{user.name}}</span>
31
- <span class="settings-theme">{{settings.theme}}</span>
32
- <button @click="{updateUserName()}">Update Name</button>
33
- <button @click="{updateSettings()}">Update Settings</button>
34
- </template>
35
- </f-template>
36
- <f-template name="empty-props-element">
37
- <template>
38
- <span class="user-name">{{user.name}}</span>
39
- <span class="settings-theme">{{settings.theme}}</span>
40
- <button @click="{updateUserName()}">Update Name</button>
41
- <button @click="{updateSettings()}">Update Settings</button>
42
- </template>
43
- </f-template>
44
- <f-template name="array-selective-element">
45
- <template>
46
- <f-repeat value="{{item in items}}">
47
- <div class="item-row">
48
- <span class="item-text">{{item.text}}</span>
49
- <span class="item-count">{{item.meta.count}}</span>
50
- </div>
51
- </f-repeat>
52
- <button @click="{updateItemText()}">Update Item Text</button>
53
- <button @click="{addItem()}">Add Item</button>
54
- </template>
55
- </f-template>
@@ -1,7 +0,0 @@
1
- # Scenarios
2
-
3
- Fixtures for complex scenarios that may involve multiple features interacting together and edge cases that arise from real-world usage patterns.
4
-
5
- | Fixture | Description |
6
- |---|---|
7
- | `nested-elements` | Nested custom elements with state propagation through shadow boundaries, event handling inside `f-repeat` with `$c.parent` context access, and `f-when` conditions within repeated content. |
@@ -1,16 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en-US">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Nested Elements Hydration Tests</title>
7
- </head>
8
- <body>
9
- <parent-element category="{{category}}"></parent-element>
10
- <parent-element title="Empty List" :items="{{emptyItems}}" category="{{category}}"></parent-element>
11
- <parent-element title="Single Item" :items="{{singleItem}}" category="{{category}}"></parent-element>
12
- <test-element-repeat-event></test-element-repeat-event>
13
- <test-when-in-repeat></test-when-in-repeat>
14
- <script type="module" src="./main.ts"></script>
15
- </body>
16
- </html>
@@ -1,6 +0,0 @@
1
- {
2
- "entry": "entry.html",
3
- "state": "state.json",
4
- "output": "index.html",
5
- "templates": "templates.html"
6
- }
@@ -1,126 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en-US">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Nested Elements Hydration Tests</title>
7
- </head>
8
- <body>
9
- <parent-element category="General"><template shadowrootmode="open" shadowroot="open"><div class="list-container">
10
- <h2><!--fe:b-->My Items<!--fe:/b--></h2>
11
- <div class="items">
12
- <!--fe:b--><!--fe:r-->
13
- <child-element text="Item 1" idx="0" category="General" data-fe="3"><template shadowrootmode="open" shadowroot="open"><div class="item">
14
- <span class="index"><!--fe:b-->0<!--fe:/b--></span>
15
- <span class="text"><!--fe:b-->Item 1<!--fe:/b--></span>
16
- <grand-child-element category="General" data-fe="1"><template shadowrootmode="open" shadowroot="open"><span class="category"><!--fe:b-->General<!--fe:/b--></span></template></grand-child-element>
17
- </div></template></child-element>
18
- <!--fe:/r--><!--fe:r-->
19
- <child-element text="Item 2" idx="1" category="General" data-fe="3"><template shadowrootmode="open" shadowroot="open"><div class="item">
20
- <span class="index"><!--fe:b-->1<!--fe:/b--></span>
21
- <span class="text"><!--fe:b-->Item 2<!--fe:/b--></span>
22
- <grand-child-element category="General" data-fe="1"><template shadowrootmode="open" shadowroot="open"><span class="category"><!--fe:b-->General<!--fe:/b--></span></template></grand-child-element>
23
- </div></template></child-element>
24
- <!--fe:/r--><!--fe:r-->
25
- <child-element text="Item 3" idx="2" category="General" data-fe="3"><template shadowrootmode="open" shadowroot="open"><div class="item">
26
- <span class="index"><!--fe:b-->2<!--fe:/b--></span>
27
- <span class="text"><!--fe:b-->Item 3<!--fe:/b--></span>
28
- <grand-child-element category="General" data-fe="1"><template shadowrootmode="open" shadowroot="open"><span class="category"><!--fe:b-->General<!--fe:/b--></span></template></grand-child-element>
29
- </div></template></child-element>
30
- <!--fe:/r--><!--fe:/b-->
31
- </div>
32
- </div></template></parent-element>
33
- <parent-element title="Empty List" category="General"><template shadowrootmode="open" shadowroot="open"><div class="list-container">
34
- <h2><!--fe:b-->Empty List<!--fe:/b--></h2>
35
- <div class="items">
36
- <!--fe:b--><!--fe:/b-->
37
- </div>
38
- </div></template></parent-element>
39
- <parent-element title="Single Item" category="General"><template shadowrootmode="open" shadowroot="open"><div class="list-container">
40
- <h2><!--fe:b-->Single Item<!--fe:/b--></h2>
41
- <div class="items">
42
- <!--fe:b--><!--fe:r-->
43
- <child-element text="Only Item" idx="0" category="General" data-fe="3"><template shadowrootmode="open" shadowroot="open"><div class="item">
44
- <span class="index"><!--fe:b-->0<!--fe:/b--></span>
45
- <span class="text"><!--fe:b-->Only Item<!--fe:/b--></span>
46
- <grand-child-element category="General" data-fe="1"><template shadowrootmode="open" shadowroot="open"><span class="category"><!--fe:b-->General<!--fe:/b--></span></template></grand-child-element>
47
- </div></template></child-element>
48
- <!--fe:/r--><!--fe:/b-->
49
- </div>
50
- </div></template></parent-element>
51
- <test-element-repeat-event><template shadowrootmode="open" shadowroot="open"><ul>
52
- <!--fe:b--><!--fe:/b-->
53
- </ul></template></test-element-repeat-event>
54
- <test-when-in-repeat><template shadowrootmode="open" shadowroot="open"><ul>
55
- <!--fe:b--><!--fe:r-->
56
- <li>
57
- <!--fe:b-->
58
- <button class="name" type="button" data-fe="1"><!--fe:b-->Alpha<!--fe:/b--></button>
59
- <!--fe:/b-->
60
- </li>
61
- <!--fe:/r--><!--fe:r-->
62
- <li>
63
- <!--fe:b-->
64
- <button class="name" type="button" data-fe="1"><!--fe:b-->Beta<!--fe:/b--></button>
65
- <!--fe:/b-->
66
- </li>
67
- <!--fe:/r--><!--fe:/b-->
68
- </ul></template></test-when-in-repeat>
69
- <f-template name="test-element-repeat-event">
70
- <template>
71
- <ul>
72
- <f-repeat value="{{item in repeatEventItems}}">
73
- <li>
74
- <button type="button" @click="{$c.parent.handleItemClick($e)}">{{item.name}}</button>
75
- </li>
76
- </f-repeat>
77
- </ul>
78
- </template>
79
- </f-template>
80
- <f-template name="test-when-in-repeat">
81
- <template>
82
- <ul>
83
- <f-repeat value="{{item in whenRepeatItems}}">
84
- <li>
85
- <f-when value="{{showNames}}">
86
- <button class="name" type="button" @click="{$c.parent.handleItemClick($e)}">{{item.name}}</button>
87
- </f-when>
88
- </li>
89
- </f-repeat>
90
- </ul>
91
- </template>
92
- </f-template>
93
- <f-template name="grand-child-element">
94
- <template>
95
- <span class="category">{{category}}</span>
96
- </template>
97
- </f-template>
98
- <f-template name="child-element">
99
- <template>
100
- <div class="item">
101
- <span class="index">{{idx}}</span>
102
- <span class="text">{{text}}</span>
103
- <grand-child-element category="{{category}}"></grand-child-element>
104
- </div>
105
- </template>
106
- </f-template>
107
- <f-template name="parent-element">
108
- <template>
109
- <div class="list-container">
110
- <h2>{{title}}</h2>
111
- <div class="items">
112
- <f-repeat value="{{item in items}}" positioning="true">
113
- <child-element
114
- text="{{item.text}}"
115
- idx="{{$index}}"
116
- category="{{category}}"
117
- ></child-element>
118
- </f-repeat>
119
- </div>
120
- </div>
121
- </template>
122
- </f-template>
123
-
124
- <script type="module" src="./main.ts"></script>
125
- </body>
126
- </html>
@@ -1,214 +0,0 @@
1
- import { attr } from "@microsoft/fast-element/attr.js";
2
- import { declarativeTemplate } from "@microsoft/fast-element/declarative.js";
3
- import { deepMerge } from "@microsoft/fast-element/declarative-utilities.js";
4
- import { FASTElement } from "@microsoft/fast-element/fast-element.js";
5
- import { enableHydration } from "@microsoft/fast-element/hydration.js";
6
- import { observable } from "@microsoft/fast-element/observable.js";
7
- import { observerMap } from "@microsoft/fast-element/observer-map.js";
8
-
9
- (window as any).messages = [];
10
-
11
- const lifecycleCallbacks = {
12
- elementDidDefine(name: string) {
13
- (window as any).messages.push(
14
- `Element did define: ${name} [${performance.now()}]`,
15
- );
16
- },
17
- elementDidRegister(name: string) {
18
- (window as any).messages.push(
19
- `Element did register: ${name} [${performance.now()}]`,
20
- );
21
- },
22
- templateDidUpdate(name: string) {
23
- (window as any).messages.push(
24
- `Template did update: ${name} [${performance.now()}]`,
25
- );
26
- },
27
- templateWillUpdate(name: string) {
28
- (window as any).messages.push(
29
- `Template will update: ${name} [${performance.now()}]`,
30
- );
31
- },
32
- };
33
-
34
- enableHydration({
35
- hydrationComplete() {
36
- (window as any).messages.push(`Hydration complete [${performance.now()}]`);
37
- (window as any).hydrationCompleted = true;
38
- },
39
- });
40
-
41
- // Mock data sources - simulating fetched data
42
- const mockDataSources = {
43
- getListData(listId: string) {
44
- const dataSets: Record<
45
- string,
46
- { title: string; items: Array<{ text: string }> }
47
- > = {
48
- "list-1": {
49
- title: "My Items",
50
- items: [{ text: "Item 1" }, { text: "Item 2" }, { text: "Item 3" }],
51
- },
52
- "list-2": {
53
- title: "Empty List",
54
- items: [],
55
- },
56
- "list-3": {
57
- title: "Single Item",
58
- items: [{ text: "Only Item" }],
59
- },
60
- };
61
- return dataSets[listId] || { title: "Unknown List", items: [] };
62
- },
63
- getItemData(itemId: string) {
64
- // Simulate fetching individual item data
65
- return { text: `Loaded: ${itemId}`, timestamp: Date.now() };
66
- },
67
- getItemById(itemId: string) {
68
- // Simulate fetching item data by ID
69
- const itemDataMap: Record<string, { text: string; idx: number }> = {
70
- "item-1": { text: "Item 1", idx: 0 },
71
- "item-2": { text: "Item 2", idx: 1 },
72
- "item-3": { text: "Item 3", idx: 2 },
73
- "item-4": { text: "Only Item", idx: 0 },
74
- };
75
- return itemDataMap[itemId] || { text: "Unknown", idx: 0 };
76
- },
77
- };
78
-
79
- export class ItemList extends FASTElement {
80
- @observable
81
- public items: Array<{ text: string }> = [];
82
-
83
- @observable
84
- public title: string = "";
85
-
86
- @attr
87
- public category!: string;
88
-
89
- // Track which list instance this is (1st, 2nd, or 3rd on the page)
90
- private static connectedCallCount = 0;
91
- private static instanceMap = new WeakMap<ItemList, number>();
92
-
93
- connectedCallback() {
94
- if (!ItemList.instanceMap.has(this)) {
95
- ItemList.connectedCallCount++;
96
- ItemList.instanceMap.set(this, ItemList.connectedCallCount);
97
- }
98
-
99
- const instanceNumber = ItemList.instanceMap.get(this) || 0;
100
- const listIds = ["list-1", "list-2", "list-3"];
101
- const listId = listIds[instanceNumber - 1] || "list-1";
102
- const data = mockDataSources.getListData(listId);
103
-
104
- // Set data BEFORE super so items are in _items before
105
- // ElementController.bindObservables replays boundObservables
106
- this.title = data.title;
107
- this.items = data.items;
108
-
109
- super.connectedCallback();
110
- }
111
- }
112
-
113
- export class Item extends FASTElement {
114
- @observable
115
- public text: string = "";
116
-
117
- @observable
118
- public idx: number = 0;
119
-
120
- @attr
121
- public category!: string;
122
-
123
- // Track which item instance this is globally
124
- private static connectedCallCount = 0;
125
- private static instanceMap = new WeakMap<Item, number>();
126
-
127
- connectedCallback() {
128
- if (!Item.instanceMap.has(this)) {
129
- Item.connectedCallCount++;
130
- Item.instanceMap.set(this, Item.connectedCallCount);
131
- }
132
-
133
- const instanceNumber = Item.instanceMap.get(this) || 0;
134
- const itemIds = ["item-1", "item-2", "item-3", "item-4"];
135
- const itemId = itemIds[instanceNumber - 1] || "item-1";
136
- const data = mockDataSources.getItemById(itemId);
137
-
138
- // Set data before super so it's available during hydration
139
- deepMerge(this, data);
140
-
141
- super.connectedCallback();
142
- }
143
- }
144
-
145
- export class GrandChildItem extends FASTElement {
146
- @attr
147
- public category!: string;
148
- }
149
-
150
- export interface RepeatItemType {
151
- name: string;
152
- }
153
-
154
- export class TestElementRepeatEvent extends FASTElement {
155
- @observable
156
- repeatEventItems: Array<RepeatItemType> = [];
157
-
158
- @observable
159
- clickedItemName: string = "";
160
-
161
- // Called via $c.parent.handleItemClick — `this` is bound to the host
162
- // because the $c.parent path resolves the method owner from the context.
163
- handleItemClick(e: Event) {
164
- this.clickedItemName = (e.currentTarget as HTMLButtonElement).textContent!;
165
- }
166
- }
167
- TestElementRepeatEvent.define({
168
- name: "test-element-repeat-event",
169
- template: declarativeTemplate(lifecycleCallbacks),
170
- });
171
-
172
- export class TestWhenInRepeat extends FASTElement {
173
- @observable whenRepeatItems: Array<RepeatItemType> = [
174
- { name: "Alpha" },
175
- { name: "Beta" },
176
- ];
177
- @observable showNames: boolean = true;
178
- @observable clickedItemName: string = "";
179
-
180
- handleItemClick(e: Event) {
181
- this.clickedItemName = (e.currentTarget as HTMLButtonElement).textContent!;
182
- }
183
- }
184
- TestWhenInRepeat.define(
185
- {
186
- name: "test-when-in-repeat",
187
- template: declarativeTemplate(lifecycleCallbacks),
188
- },
189
- [observerMap()],
190
- );
191
-
192
- ItemList.define(
193
- {
194
- name: "parent-element",
195
- template: declarativeTemplate(lifecycleCallbacks),
196
- },
197
- [observerMap()],
198
- );
199
-
200
- Item.define(
201
- {
202
- name: "child-element",
203
- template: declarativeTemplate(lifecycleCallbacks),
204
- },
205
- [observerMap()],
206
- );
207
-
208
- GrandChildItem.define(
209
- {
210
- name: "grand-child-element",
211
- template: declarativeTemplate(lifecycleCallbacks),
212
- },
213
- [observerMap()],
214
- );
@@ -1,10 +0,0 @@
1
- {
2
- "title": "My Items",
3
- "items": [{ "text": "Item 1" }, { "text": "Item 2" }, { "text": "Item 3" }],
4
- "emptyItems": [],
5
- "singleItem": [{ "text": "Only Item" }],
6
- "category": "General",
7
- "repeatEventItems": [],
8
- "whenRepeatItems": [{ "name": "Alpha" }, { "name": "Beta" }],
9
- "showNames": true
10
- }