diff --git a/.github/skills/typescript/SKILL.md b/.github/skills/typescript/SKILL.md index 216db771c7f..a72686fecf8 100644 --- a/.github/skills/typescript/SKILL.md +++ b/.github/skills/typescript/SKILL.md @@ -18,7 +18,7 @@ import { type Constructable, isFunction } from "../interfaces.js"; Sub-entry-points expose focused APIs through the `exports` map: ```ts -import { twoWay } from "@microsoft/fast-element/binding/two-way.js"; +import { twoWay } from "@microsoft/fast-element/two-way.js"; import { reactive } from "@microsoft/fast-element/state.js"; import { composedParent } from "@microsoft/fast-element/utilities.js"; ``` @@ -66,7 +66,9 @@ definition.define(); Templates use the `html` tagged template literal typed to the element class: ```ts -import { html, repeat, when } from "@microsoft/fast-element"; +import { html } from "@microsoft/fast-element/html.js"; +import { repeat } from "@microsoft/fast-element/repeat.js"; +import { when } from "@microsoft/fast-element/when.js"; import type { MyElement } from "./my-element.js"; export const template = html` @@ -95,7 +97,7 @@ export const template = html` Two-way bindings require a sub-entry-point import: ```ts -import { twoWay } from "@microsoft/fast-element/binding/two-way.js"; +import { twoWay } from "@microsoft/fast-element/two-way.js"; ``` ### Partial HTML @@ -115,7 +117,7 @@ Styles use the `css` tagged template literal. They attach through the element de `styles` property: ```ts -import { css } from "@microsoft/fast-element"; +import { css } from "@microsoft/fast-element/css.js"; export const styles = css` :host { @@ -144,14 +146,10 @@ both the initial shadow root template and the ``: tracked by templates. `@volatile` marks getters whose dependencies change between calls: ```ts -import { - attr, - FASTElement, - nullableNumberConverter, - Observable, - observable, - volatile, -} from "@microsoft/fast-element"; +import { FASTElement } from "@microsoft/fast-element/fast-element.js"; +import { attr, nullableNumberConverter } from "@microsoft/fast-element/attr.js"; +import { Observable, observable } from "@microsoft/fast-element/observable.js"; +import { volatile } from "@microsoft/fast-element/volatile.js"; class MyElement extends FASTElement { @attr label?: string; diff --git a/change/@microsoft-fast-element-106e0dee-a966-4f2d-9d9b-857c10599260.json b/change/@microsoft-fast-element-106e0dee-a966-4f2d-9d9b-857c10599260.json index 9ed14e27e8c..f021be0f3b6 100644 --- a/change/@microsoft-fast-element-106e0dee-a966-4f2d-9d9b-857c10599260.json +++ b/change/@microsoft-fast-element-106e0dee-a966-4f2d-9d9b-857c10599260.json @@ -1,6 +1,6 @@ { "type": "minor", - "comment": "Add definition-scoped declarative map extensions.", + "comment": "Add schema-driven attributeMap and observerMap extension subpaths, optional definition schema, and observerMap schema configuration.", "packageName": "@microsoft/fast-element", "email": "7559015+janechu@users.noreply.github.com", "dependentChangeType": "none" diff --git a/change/@microsoft-fast-element-22265526-9ae0-4996-878d-ec0bd68133c2.json b/change/@microsoft-fast-element-22265526-9ae0-4996-878d-ec0bd68133c2.json new file mode 100644 index 00000000000..8d8888a762d --- /dev/null +++ b/change/@microsoft-fast-element-22265526-9ae0-4996-878d-ec0bd68133c2.json @@ -0,0 +1,7 @@ +{ + "type": "major", + "comment": "Move optional helpers to dedicated flat fast-element subpath exports such as @microsoft/fast-element/children.js, @microsoft/fast-element/repeat.js, @microsoft/fast-element/two-way.js, @microsoft/fast-element/signal.js, @microsoft/fast-element/attribute-map.js, and @microsoft/fast-element/observer-map.js while keeping controller and definition internals on the root entrypoint.", + "packageName": "@microsoft/fast-element", + "email": "7559015+janechu@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/change/@microsoft-fast-element-3f6b286b-8276-4142-b903-7306b4c76808.json b/change/@microsoft-fast-element-3f6b286b-8276-4142-b903-7306b4c76808.json new file mode 100644 index 00000000000..4acfbf098ef --- /dev/null +++ b/change/@microsoft-fast-element-3f6b286b-8276-4142-b903-7306b4c76808.json @@ -0,0 +1,7 @@ +{ + "type": "major", + "comment": "Remove the public declarative TemplateElement configuration APIs and make declarative templates use an internal native f-template publisher with explicit hydration opt-in.", + "packageName": "@microsoft/fast-element", + "email": "7559015+janechu@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/change/@microsoft-fast-element-61e3e3bd-e227-4449-9ff6-8edc104819d9.json b/change/@microsoft-fast-element-61e3e3bd-e227-4449-9ff6-8edc104819d9.json index a7142b625e8..dbaec336601 100644 --- a/change/@microsoft-fast-element-61e3e3bd-e227-4449-9ff6-8edc104819d9.json +++ b/change/@microsoft-fast-element-61e3e3bd-e227-4449-9ff6-8edc104819d9.json @@ -1,6 +1,6 @@ { "type": "major", - "comment": "Move declarative HTML APIs into @microsoft/fast-element/declarative.js and remove the @microsoft/fast-html package.", + "comment": "Move declarative HTML APIs into @microsoft/fast-element/declarative.js, expose schema map helpers from extension subpaths, and remove the @microsoft/fast-html package.", "packageName": "@microsoft/fast-element", "dependentChangeType": "none", "email": "7559015+janechu@users.noreply.github.com" diff --git a/examples/todo-app/src/todo-app.styles.ts b/examples/todo-app/src/todo-app.styles.ts index 4d6c0366e4b..ff0a80a220a 100644 --- a/examples/todo-app/src/todo-app.styles.ts +++ b/examples/todo-app/src/todo-app.styles.ts @@ -1,5 +1,4 @@ -import { css } from "@microsoft/fast-element/styles.js"; - +import { css } from "@microsoft/fast-element/css.js"; export const styles = css` :host { display: block; diff --git a/examples/todo-app/src/todo-app.template.ts b/examples/todo-app/src/todo-app.template.ts index bbaf70eaf06..84c1879b2ef 100644 --- a/examples/todo-app/src/todo-app.template.ts +++ b/examples/todo-app/src/todo-app.template.ts @@ -1,5 +1,6 @@ -import { html, repeat } from "@microsoft/fast-element"; -import { twoWay } from "@microsoft/fast-element/binding/two-way.js"; +import { html } from "@microsoft/fast-element/html.js"; +import { repeat } from "@microsoft/fast-element/repeat.js"; +import { twoWay } from "@microsoft/fast-element/two-way.js"; import type { TodoApp } from "./todo-app.js"; import type { Todo } from "./todo-list.js"; import "./todo-form.js"; @@ -34,7 +35,7 @@ export const template = html` × - ` + `, )} `; diff --git a/examples/todo-app/src/todo-form.styles.ts b/examples/todo-app/src/todo-form.styles.ts index 56c210c60c7..2ddb6a0dd43 100644 --- a/examples/todo-app/src/todo-form.styles.ts +++ b/examples/todo-app/src/todo-form.styles.ts @@ -1,5 +1,4 @@ -import { css } from "@microsoft/fast-element/styles.js"; - +import { css } from "@microsoft/fast-element/css.js"; export const styles = css` form { display: flex; diff --git a/examples/todo-app/src/todo-form.template.ts b/examples/todo-app/src/todo-form.template.ts index 37bc3c58262..6111b92640c 100644 --- a/examples/todo-app/src/todo-form.template.ts +++ b/examples/todo-app/src/todo-form.template.ts @@ -1,5 +1,5 @@ -import { html } from "@microsoft/fast-element"; -import { twoWay } from "@microsoft/fast-element/binding/two-way.js"; +import { html } from "@microsoft/fast-element/html.js"; +import { twoWay } from "@microsoft/fast-element/two-way.js"; import type { TodoForm } from "./todo-form.js"; export const template = html` diff --git a/examples/todo-app/src/todo-form.ts b/examples/todo-app/src/todo-form.ts index c1faa199238..fd28e1a74ad 100644 --- a/examples/todo-app/src/todo-form.ts +++ b/examples/todo-app/src/todo-form.ts @@ -1,4 +1,5 @@ -import { customElement, FASTElement, observable } from "@microsoft/fast-element"; +import { customElement, FASTElement } from "@microsoft/fast-element/fast-element.js"; +import { observable } from "@microsoft/fast-element/observable.js"; import { styles } from "./todo-form.styles.js"; import { template } from "./todo-form.template.js"; import { TodoList } from "./todo-list.js"; diff --git a/examples/todo-app/src/todo-list.ts b/examples/todo-app/src/todo-list.ts index 71e15c1679e..f2175d2fc3f 100644 --- a/examples/todo-app/src/todo-list.ts +++ b/examples/todo-app/src/todo-list.ts @@ -1,6 +1,7 @@ -import { Observable, observable, volatile } from "@microsoft/fast-element"; import { Context } from "@microsoft/fast-element/context.js"; +import { Observable, observable } from "@microsoft/fast-element/observable.js"; import { reactive } from "@microsoft/fast-element/state.js"; +import { volatile } from "@microsoft/fast-element/volatile.js"; export type Todo = { description: string; done: boolean }; export type TodoListFilter = "all" | "active" | "completed"; diff --git a/packages/fast-element/ARCHITECTURE_HTML_TAGGED_TEMPLATE_LITERAL.md b/packages/fast-element/ARCHITECTURE_HTML_TAGGED_TEMPLATE_LITERAL.md index 4cc28d8414c..dcb9a8e946f 100644 --- a/packages/fast-element/ARCHITECTURE_HTML_TAGGED_TEMPLATE_LITERAL.md +++ b/packages/fast-element/ARCHITECTURE_HTML_TAGGED_TEMPLATE_LITERAL.md @@ -33,4 +33,4 @@ flowchart TD C --> E F[When a createObserver is called, the instance of the one time binding is returned which includes a bind method returning the arrow function executed against the controller source and context] B --> F -``` \ No newline at end of file +``` diff --git a/packages/fast-element/ARCHITECTURE_OVERVIEW.md b/packages/fast-element/ARCHITECTURE_OVERVIEW.md index 8783c6a1aa7..9bafffd0db2 100644 --- a/packages/fast-element/ARCHITECTURE_OVERVIEW.md +++ b/packages/fast-element/ARCHITECTURE_OVERVIEW.md @@ -28,7 +28,7 @@ Let's step back from defining the Custom Element and consider what is happening First, a global `FAST` property will be created if one does not already exist, typically in browser on the `window`. -Additionally, when Custom Elements are included in a script a few things might happen even before a Custom Element gets detected by the browser. First, there are initial side effects caused by the use of decorators. These include the `attr` and `observable` decorators made available by the `@microsoft/fast-element` package. +Additionally, when Custom Elements are included in a script a few things might happen even before a Custom Element gets detected by the browser. First, there are initial side effects caused by the use of decorators. These include the `attr` decorator from `@microsoft/fast-element` and the `observable` decorator from `@microsoft/fast-element`. Here is a basic flow of what code is executed and when during initial load of a script that contains a FAST defined Custom Element: @@ -49,4 +49,4 @@ flowchart TD I@{ shape: dbl-circ, label: "The lifecycle steps for FASTElement are executed" } G --> H H --> I -``` \ No newline at end of file +``` diff --git a/packages/fast-element/DECLARATIVE_DESIGN.md b/packages/fast-element/DECLARATIVE_DESIGN.md index ffcd33e16b3..2e63f628888 100644 --- a/packages/fast-element/DECLARATIVE_DESIGN.md +++ b/packages/fast-element/DECLARATIVE_DESIGN.md @@ -1,10 +1,9 @@ # Declarative HTML Design This document is intended for contributors who want to understand the internal -architecture of the declarative runtime in -`@microsoft/fast-element/declarative.js`. It covers the feature's purpose, core -concepts, data flow, and its integration with the rest of -`@microsoft/fast-element`. +architecture of the declarative runtime and schema-driven map extensions in +`@microsoft/fast-element`. It covers the feature's purpose, core concepts, data +flow, and its integration with the rest of `@microsoft/fast-element`. ## Table of Contents @@ -27,11 +26,12 @@ concepts, data flow, and its integration with the rest of ## Overview -`@microsoft/fast-element/declarative.js` lets you write FAST Web Component +`@microsoft/fast-element` lets you write FAST Web Component templates as plain HTML rather than JavaScript `html` tagged template literals. -The browser-side JS bundle includes the `` custom element, which -parses a declarative template at runtime and attaches it as a `ViewTemplate` to -a waiting FAST element definition. +The browser-side JS bundle defines FAST's internal native `` +publisher on demand. It parses declarative template markup at runtime and +returns a `ViewTemplate` to the waiting FAST element definition through the +registry-aware declarative template bridge. ```html @@ -55,34 +55,58 @@ a waiting FAST element definition. |---|---| | **Server-agnostic rendering** | Templates are plain HTML strings with no dependency on Node.js or any specific SSR framework. | | **Progressive enhancement** | Components can be server-rendered and then hydrated client-side without a full re-render. | -| **FAST parity** | The declarative syntax maps 1-to-1 to `@microsoft/fast-element` directives (`repeat`, `when`, `slotted`, `children`, `ref`). | +| **FAST parity** | The declarative syntax maps 1-to-1 to FAST Element directive helpers (`repeat`, `when`, `slotted`, `children`, `ref`) exported from `@microsoft/fast-element`. | | **Minimal authoring overhead** | Component authors write HTML, not tagged template strings, while retaining full reactive capabilities. | --- ## Core Concepts -### `` — the template element +### `` — the internal template publisher -`` is a custom element (class `TemplateElement`) that acts as the bridge between a declarative HTML template and the FAST element registry. When connected to the DOM it: +`` is an internal custom element implemented as a lightweight native +`HTMLElement`. It is defined automatically by `declarativeTemplate()` in the same +`CustomElementRegistry` as the FAST element definition. Consumers should not +import, subclass, or define the implementation directly. -1. Looks up the element definition registered via `define()`. -2. Delegates parsing of the inner `