From c6b9e8a436b7b52e5df02182b663167bb34cad8a Mon Sep 17 00:00:00 2001 From: Jane Chu <7559015+janechu@users.noreply.github.com> Date: Wed, 15 Jan 2025 15:29:17 -0800 Subject: [PATCH] Add documentation explaining some architectural concepts (#7033) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Pull Request ## 📖 Description This PR adds documentation on the internals of `FASTElement` and it's lifecycle events. This is meant to serve as a general overview for contributors looking to understand the architecture of FAST custom elements. ## ✅ Checklist ### General - [ ] I have included a change request file using `$ npm run change` - [ ] I have added tests for my changes. - [ ] I have tested my changes. - [x] I have updated the project documentation to reflect my changes. - [x] I have read the [CONTRIBUTING](https://github.com/microsoft/fast/blob/master/CONTRIBUTING.md) documentation and followed the [standards](https://github.com/microsoft/fast/blob/master/CODE_OF_CONDUCT.md#our-standards) for this project. --- ...-e44aecad-1602-46a6-a317-92f22a19d964.json | 7 +++ .../fast-element/ARCHITECTURE_FASTELEMENT.md | 63 +++++++++++++++++++ ...CHITECTURE_HTML_TAGGED_TEMPLATE_LITERAL.md | 34 ++++++++++ .../fast-element/ARCHITECTURE_INTRO.md | 10 +++ .../fast-element/ARCHITECTURE_OVERVIEW.md | 52 +++++++++++++++ .../fast-element/ARCHITECTURE_UPDATES.md | 11 ++++ 6 files changed, 177 insertions(+) create mode 100644 change/@microsoft-fast-element-e44aecad-1602-46a6-a317-92f22a19d964.json create mode 100644 packages/web-components/fast-element/ARCHITECTURE_FASTELEMENT.md create mode 100644 packages/web-components/fast-element/ARCHITECTURE_HTML_TAGGED_TEMPLATE_LITERAL.md create mode 100644 packages/web-components/fast-element/ARCHITECTURE_INTRO.md create mode 100644 packages/web-components/fast-element/ARCHITECTURE_OVERVIEW.md create mode 100644 packages/web-components/fast-element/ARCHITECTURE_UPDATES.md diff --git a/change/@microsoft-fast-element-e44aecad-1602-46a6-a317-92f22a19d964.json b/change/@microsoft-fast-element-e44aecad-1602-46a6-a317-92f22a19d964.json new file mode 100644 index 00000000000..1486986567e --- /dev/null +++ b/change/@microsoft-fast-element-e44aecad-1602-46a6-a317-92f22a19d964.json @@ -0,0 +1,7 @@ +{ + "type": "none", + "comment": "Add documentation explaining some architectural concepts", + "packageName": "@microsoft/fast-element", + "email": "7559015+janechu@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/packages/web-components/fast-element/ARCHITECTURE_FASTELEMENT.md b/packages/web-components/fast-element/ARCHITECTURE_FASTELEMENT.md new file mode 100644 index 00000000000..e227474a2bf --- /dev/null +++ b/packages/web-components/fast-element/ARCHITECTURE_FASTELEMENT.md @@ -0,0 +1,63 @@ +# FASTElement + +The `FASTElement` is our extension of the `HTMLElement`. As such it leverages the lifecycles but also requires additional setup before before the class `constructor` or the `connectedCallback` method is executed which are explained in the [overview](./ARCHITECTURE_OVERVIEW.md). This document explains specifically what `FASTElement` leverages inside the `HTMLElement`s lifecycle hooks. + +For an explanation into `HTMLElement` lifecycle hooks refer to the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks). + +## A Custom Element is Detected by the Browser + +Because the `FASTElement` is an extension of the `HTMLElement`, it makes use of the same lifecycle hooks and extends them with `$fastController`. It also initializes using another class `ElementController`, the methods this are called during the custom elements native `constructor`, `connectedCallback`, `disconnectedCallback`, and `attributeChangedCallback` lifecycle hooks. + +### 🔄 **Lifecycle**: Initialization + +```mermaid +flowchart TD + A[A FASTElement web component is added to the DOM] --> B + B[FASTElement initializes the ElementController.forCustomElement passing the Custom Element instance] --> C + B --> F[Observables applied to the FASTElement are updated on the FAST global without values] + C{Is an ElementController available?} + C --> |yes|E + C --> |no|D + D[Initialize a new ElementController referred to as setting an element controller strategy] + D --> F + E[ElementController captures the Custom Element instance and the definition and attaches them to the $fastController which is then attached to the instance] +``` + +### 🔄 **Lifecycle**: Component is connected + +```mermaid +flowchart TD + A[browser HTMLElement's connectedCallback is called] --> B + B[this.$fastController.connect in FASTElement is called] --> C + B --> D + B --> E + B --> F + C[bind observables by capturing the Custom Elements properties and setting the values from the bound observables on the Custom Element] + D[connect behaviors by call the connectedCallback on all behaviors] + E[render template, execute an ElementViewTemplate's render method] + F[add styles either as an appended StyleElement node or an adoptedStylesheet which may include and attach behaviors] +``` + +#### Render Template + +The rendering of the template on the `ElementController` is by the `renderTemplate` method which is called during the `ElementController.connect` method which is triggered by `HTMLElement`s `connectedCallback` lifecycle. + +The `renderTemplate` identifies the Custom Element, and the shadow root associated with the Custom Element. This then places a rendering of the template (an `ElementView`) onto the internal `view` of the controller. When creating the `ElementView`/`HTMLView` using the `ViewTemplate.render`, the `Compile.compile()` method identifies a `DocumentFragment` either by using an existing `