Skip to content

Commit 0f7aa49

Browse files
janechuCopilot
andcommitted
feat: remove CSS behavior composition
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 299b184 commit 0f7aa49

36 files changed

Lines changed: 127 additions & 1851 deletions

change/@microsoft-fast-element-724d29c9-2cdc-4940-83c1-70ec5d64095e.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"type": "major",
3-
"comment": "Remove ElementStyles.withBehaviors and move runtime style toggles to the element controller.",
3+
"comment": "Remove ElementStyles.withBehaviors, CSS style behaviors, and CSS bindings in fast-element.",
44
"packageName": "@microsoft/fast-element",
55
"email": "7559015+janechu@users.noreply.github.com",
66
"dependentChangeType": "none"

packages/fast-element/DESIGN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ See [ARCHITECTURE_UPDATES.md](./ARCHITECTURE_UPDATES.md) for more detail.
272272

273273
**Files**: `src/styles/css.ts`, `src/styles/element-styles.ts`, `src/styles/css-directive.ts`
274274

275-
The `css` tag (analogous to `html`) builds `ElementStyles` objects. During `ElementController.connect()`, styles are applied to the element's shadow root either via `adoptedStylesheets` (preferred) or an appended `<style>` node, depending on platform support. Styles can also contain dynamic `CSSDirective`s (e.g., CSS custom property bindings) that register as `HostBehavior`s and connect/disconnect alongside the element. Arbitrary runtime style toggling is handled through `ElementController.addStyles()` / `removeStyles()`; `ElementStyles` itself is a static container and does not expose a public behavior-mutation API.
275+
The `css` tag (analogous to `html`) builds `ElementStyles` objects. During `ElementController.connect()`, styles are applied to the element's shadow root either via `adoptedStylesheets` (preferred) or an appended `<style>` node, depending on platform support. `CSSDirective`s can contribute additional static CSS during template composition, but runtime CSS bindings and style-attached `HostBehavior`s are not supported. Arbitrary runtime style toggling is handled through `ElementController.addStyles()` / `removeStyles()`; `ElementStyles` itself is a static container.
276276

277277
---
278278

packages/fast-element/MIGRATION.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,19 @@ The `install-hydratable-view-templates.js` side-effect import is still available
109109
| Removed | Replacement |
110110
|---|---|
111111
| `ElementStyles.withBehaviors()` | Move the runtime condition into the element and call `this.$fastController.addStyles()` / `this.$fastController.removeStyles()` directly. |
112+
| `ElementStyles.behaviors` | Move any runtime behavior out of the stylesheet and into the element or controller lifecycle. |
113+
| CSS bindings in `css` (for example ``css`color: ${x => x.color}```) | Move the dynamic value into the element and update classes, attributes, or inline styles from element code. |
114+
| `CSSDirective.createCSS(add)` | Update directives to implement `createCSS()` and return only static CSS content. |
112115

113116
### Changed behavior
114117

115-
- `css` and `css.partial()` still compose internal behaviors for CSS directives and CSS bindings.
116-
- `ElementStyles` remains a static style container; attaching arbitrary `HostBehavior`s is no longer part of the public API.
118+
- `css` and `css.partial()` no longer compose `HostBehavior`s.
119+
- `css` no longer accepts function or `Binding` interpolations.
120+
- `ElementStyles` is now a fully static style container.
117121

118122
### Migration steps
119123

120124
1. Keep the conditional `ElementStyles` in a separate `css` value.
121125
2. Move the external listener or condition (for example `matchMedia()` or an app event subscription) into the element lifecycle.
122126
3. Call `this.$fastController.addStyles(styles)` when the condition is active and `this.$fastController.removeStyles(styles)` when it is inactive or during cleanup.
127+
4. If you previously interpolated bindings or behavior-producing directives into `css`, replace them with element state and standard DOM or controller updates.

packages/fast-element/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,10 @@ When runtime state or external signals need to add or remove styles, create the
6464
`this.$fastController.addStyles()` / `this.$fastController.removeStyles()` from
6565
the element lifecycle or change handlers.
6666

67-
`css` templates remain static style definitions. CSS directives and CSS bindings
68-
still compose their internal behaviors automatically, but `ElementStyles` no
69-
longer exposes a public API for attaching arbitrary behaviors.
67+
`css` templates remain static style definitions. Runtime CSS bindings and
68+
behavior-producing CSS directives are no longer supported; keep the condition on
69+
the element and toggle a separate `ElementStyles` instance through the
70+
controller when styles need to change.
7071

7172
## Prerendered Content Optimization
7273

packages/fast-element/SIZES.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ Bundle sizes for `@microsoft/fast-element` exports.
44

55
| Export | Minified | Gzip | Brotli |
66
|--------|----------|------|--------|
7-
| CDN Rollup Bundle | 66.02 KB | 19.60 KB | 17.61 KB |
8-
| FASTElement | 25.31 KB | 7.94 KB | 7.17 KB |
7+
| CDN Rollup Bundle | 64.21 KB | 19.14 KB | 17.18 KB |
8+
| FASTElement | 24.90 KB | 7.84 KB | 7.09 KB |
99
| Updates | 3.61 KB | 1.48 KB | 1.26 KB |
1010
| Observable | 8.12 KB | 2.99 KB | 2.66 KB |
1111
| observable | 8.16 KB | 3.00 KB | 2.68 KB |
1212
| attr | 3.55 KB | 1.42 KB | 1.19 KB |
1313
| children | 6.15 KB | 2.34 KB | 2.06 KB |
14-
| css | 11.41 KB | 4.11 KB | 3.70 KB |
14+
| css | 4.63 KB | 1.83 KB | 1.59 KB |
1515
| ref | 5.12 KB | 2.02 KB | 1.76 KB |
1616
| slotted | 5.94 KB | 2.28 KB | 2.00 KB |
1717
| volatile | 8.22 KB | 3.02 KB | 2.69 KB |

packages/fast-element/docs/api-report.api.md

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ export interface Accessor {
1111
setValue(source: any, value: any): void;
1212
}
1313

14-
// @public
15-
export type AddBehavior = (behavior: HostBehavior<HTMLElement>) => void;
16-
1714
// @public
1815
export type AddViewBehaviorFactory = (factory: ViewBehaviorFactory) => string;
1916

@@ -185,30 +182,9 @@ export interface ContentView {
185182
// @public
186183
export const css: CSSTemplateTag;
187184

188-
// @public
189-
export class CSSBindingDirective implements HostBehavior, Subscriber, CSSDirective, BindingDirective {
190-
constructor(dataBinding: Binding, targetAspect: string);
191-
addedCallback(controller: HostController<HTMLElement & {
192-
$cssBindings: Map<CSSBindingDirective, CSSBindingEntry>;
193-
}>): void;
194-
connectedCallback(controller: HostController<HTMLElement & {
195-
$cssBindings: Map<CSSBindingDirective, CSSBindingEntry>;
196-
}>): void;
197-
createCSS(add: AddBehavior): ComposableStyles;
198-
// (undocumented)
199-
readonly dataBinding: Binding;
200-
// @internal
201-
handleChange(_: any, observer: ExpressionObserver): void;
202-
removedCallback(controller: HostController<HTMLElement & {
203-
$cssBindings: Map<CSSBindingDirective, CSSBindingEntry>;
204-
}>): void;
205-
// (undocumented)
206-
readonly targetAspect: string;
207-
}
208-
209185
// @public
210186
export interface CSSDirective {
211-
createCSS(add: AddBehavior): ComposableStyles;
187+
createCSS(): ComposableStyles;
212188
}
213189

214190
// @public
@@ -227,12 +203,12 @@ export interface CSSDirectiveDefinition<TType extends Constructable<CSSDirective
227203
}
228204

229205
// @public
230-
export type CSSTemplateTag = (<TSource = any, TParent = any>(strings: TemplateStringsArray, ...values: CSSValue<TSource, TParent>[]) => ElementStyles) & {
231-
partial<TSource = any, TParent = any>(strings: TemplateStringsArray, ...values: CSSValue<TSource, TParent>[]): CSSDirective;
206+
export type CSSTemplateTag = ((strings: TemplateStringsArray, ...values: CSSValue[]) => ElementStyles) & {
207+
partial(strings: TemplateStringsArray, ...values: CSSValue[]): CSSDirective;
232208
};
233209

234210
// @public
235-
export type CSSValue<TSource, TParent = any> = Expression<TSource, any, TParent> | Binding<TSource, any, TParent> | ComposableStyles | CSSDirective;
211+
export type CSSValue = ComposableStyles | CSSDirective;
236212

237213
// @public
238214
export function customElement(nameOrDef: string | PartialFASTElementDefinition): (type: Constructable<HTMLElement>) => void;
@@ -346,7 +322,6 @@ export class ElementStyles {
346322
constructor(styles: ReadonlyArray<ComposableStyles>);
347323
// @internal (undocumented)
348324
addStylesTo(target: StyleTarget): void;
349-
get behaviors(): ReadonlyArray<HostBehavior<HTMLElement>> | null;
350325
// @internal (undocumented)
351326
isAttachedTo(target: StyleTarget): boolean;
352327
static normalize(styles: ComposableStyles | ComposableStyles[] | undefined): ElementStyles | undefined;
@@ -1114,7 +1089,6 @@ export function when<TSource = any, TReturn = any, TParent = any>(condition: Exp
11141089
// dist/dts/components/fast-element.d.ts:60:5 - (ae-forgotten-export) The symbol "define" needs to be exported by the entry point index.d.ts
11151090
// dist/dts/components/fast-element.d.ts:61:5 - (ae-forgotten-export) The symbol "compose" needs to be exported by the entry point index.d.ts
11161091
// dist/dts/components/fast-element.d.ts:62:5 - (ae-forgotten-export) The symbol "from" needs to be exported by the entry point index.d.ts
1117-
// dist/dts/styles/css-binding-directive.d.ts:35:9 - (ae-forgotten-export) The symbol "CSSBindingEntry" needs to be exported by the entry point index.d.ts
11181092

11191093
// (No @packageDocumentation comment for this package)
11201094

0 commit comments

Comments
 (0)