diff --git a/change/@microsoft-fast-element-e173d34b-0061-4c9d-94b5-415929d7dc5e.json b/change/@microsoft-fast-element-e173d34b-0061-4c9d-94b5-415929d7dc5e.json new file mode 100644 index 00000000000..076ceecae26 --- /dev/null +++ b/change/@microsoft-fast-element-e173d34b-0061-4c9d-94b5-415929d7dc5e.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Support element filters for declarative f-children directives.", + "packageName": "@microsoft/fast-element", + "email": "pradeepramolaa@gmail.com", + "dependentChangeType": "none" +} diff --git a/packages/fast-element/SIZES.md b/packages/fast-element/SIZES.md index c938cb68ff0..62c34b13c9f 100644 --- a/packages/fast-element/SIZES.md +++ b/packages/fast-element/SIZES.md @@ -19,7 +19,7 @@ Bundle sizes for `@microsoft/fast-element` exports. | repeat (@microsoft/fast-element/repeat.js) | 31.80 KB | 10.00 KB | 9.03 KB | | css (@microsoft/fast-element/css.js) | 2.43 KB | 1.00 KB | 911 B | | enableHydration (@microsoft/fast-element/hydration.js) | 46.71 KB | 13.94 KB | 12.51 KB | -| declarativeTemplate (@microsoft/fast-element/declarative.js) | 62.33 KB | 19.50 KB | 17.48 KB | +| declarativeTemplate (@microsoft/fast-element/declarative.js) | 62.44 KB | 19.52 KB | 17.47 KB | | ArrayObserver (@microsoft/fast-element/arrays.js) | 12.55 KB | 4.46 KB | 4.03 KB | | observerMap (@microsoft/fast-element/observer-map.js) | 21.96 KB | 7.73 KB | 6.97 KB | | attributeMap (@microsoft/fast-element/attribute-map.js) | 15.31 KB | 5.41 KB | 4.88 KB | diff --git a/packages/fast-element/docs/declarative/syntax.md b/packages/fast-element/docs/declarative/syntax.md index f2f7fff4b9b..cdfa2058695 100644 --- a/packages/fast-element/docs/declarative/syntax.md +++ b/packages/fast-element/docs/declarative/syntax.md @@ -336,6 +336,8 @@ Attribute directives include: Example: ```html + + ``` - **ref** diff --git a/packages/fast-element/src/declarative/template-parser.ts b/packages/fast-element/src/declarative/template-parser.ts index 4df9c5e8993..7bf75ebdbf5 100644 --- a/packages/fast-element/src/declarative/template-parser.ts +++ b/packages/fast-element/src/declarative/template-parser.ts @@ -45,6 +45,11 @@ interface TemplateResolutionContext { schema: Schema; } +interface NodeDirectiveOptions { + property: string; + filter?: ReturnType; +} + /** * Tracks string segments accumulated during template parsing and maintains * a running concatenation so that `bindingResolver` can receive the full @@ -232,27 +237,12 @@ export class TemplateParser { ): void { switch (name) { case "children": { - externalValues.push(children(propName)); + externalValues.push(children(this.resolveNodeDirectiveOptions(propName))); break; } case "slotted": { - const parts = propName.trim().split(" filter "); - const slottedOption = { - property: parts[0], - }; - - if (parts[1]) { - if (parts[1].startsWith("elements(")) { - let params = parts[1].replace("elements(", ""); - params = params.substring(0, params.lastIndexOf(")")); - Object.assign(slottedOption, { - filter: elements(params || undefined), - }); - } - } - - externalValues.push(slotted(slottedOption)); + externalValues.push(slotted(this.resolveNodeDirectiveOptions(propName))); break; } @@ -264,6 +254,21 @@ export class TemplateParser { } } + private resolveNodeDirectiveOptions(propName: string): NodeDirectiveOptions { + const parts = propName.trim().split(" filter "); + const options: NodeDirectiveOptions = { + property: parts[0], + }; + + if (parts[1]?.startsWith("elements(")) { + let params = parts[1].replace("elements(", ""); + params = params.substring(0, params.lastIndexOf(")")); + options.filter = elements(params || undefined); + } + + return options; + } + /** * Resolve an access binding — shared by content bindings, boolean-attribute * fallback, and default attribute bindings. diff --git a/packages/fast-element/test/declarative/fixtures/directives/children/children.spec.ts b/packages/fast-element/test/declarative/fixtures/directives/children/children.spec.ts index d88e1005e96..1dfe6b890e6 100644 --- a/packages/fast-element/test/declarative/fixtures/directives/children/children.spec.ts +++ b/packages/fast-element/test/declarative/fixtures/directives/children/children.spec.ts @@ -11,12 +11,29 @@ test.describe("f-template", async () => { await hydrationCompleted; const element = page.locator("test-element"); - const listItems = element.locator("li"); + const listItems = element.locator("[data-testid='list-items'] li"); await expect(listItems).toHaveCount(2); await expect(listItems).toHaveText(["Foo", "Bar"]); + const filteredNodeNames = await element.evaluate( + ( + node: HTMLElement & { + allChildren: Node[]; + filteredChildren: Node[]; + }, + ) => ({ + allChildren: node.allChildren.map(child => child.nodeName), + filteredChildren: node.filteredChildren.map(child => child.nodeName), + }), + ); + + expect(filteredNodeNames).toEqual({ + allChildren: ["LI", "LI"], + filteredChildren: ["SPAN"], + }); + await element.evaluate((node: HTMLElement & { list: Array }) => { node.list = ["A", "B", "C"]; }); @@ -24,5 +41,6 @@ test.describe("f-template", async () => { await expect(listItems).toHaveCount(3); await expect(listItems).toHaveText(["A", "B", "C"]); + await expect(element).toHaveJSProperty("allChildren.length", 3); }); }); diff --git a/packages/fast-element/test/declarative/fixtures/directives/children/index.html b/packages/fast-element/test/declarative/fixtures/directives/children/index.html index bb848854e28..ce4101fb882 100644 --- a/packages/fast-element/test/declarative/fixtures/directives/children/index.html +++ b/packages/fast-element/test/declarative/fixtures/directives/children/index.html @@ -5,9 +5,15 @@ - + - + diff --git a/packages/fast-element/test/declarative/fixtures/directives/children/main.ts b/packages/fast-element/test/declarative/fixtures/directives/children/main.ts index a05c96d1d35..215509ad4c6 100644 --- a/packages/fast-element/test/declarative/fixtures/directives/children/main.ts +++ b/packages/fast-element/test/declarative/fixtures/directives/children/main.ts @@ -7,6 +7,12 @@ class TestElement extends FASTElement { @observable listItems: Node[] = []; + @observable + allChildren: Node[] = []; + + @observable + filteredChildren: Node[] = []; + @observable list: Array = ["Foo", "Bar"]; } diff --git a/packages/fast-element/test/declarative/fixtures/directives/children/templates.html b/packages/fast-element/test/declarative/fixtures/directives/children/templates.html index 52c239daf52..eb214786789 100644 --- a/packages/fast-element/test/declarative/fixtures/directives/children/templates.html +++ b/packages/fast-element/test/declarative/fixtures/directives/children/templates.html @@ -1,3 +1,7 @@ - + diff --git a/sites/website/src/docs/3.x/resources/export-sizes.md b/sites/website/src/docs/3.x/resources/export-sizes.md index b694cb07e88..90662664cc5 100644 --- a/sites/website/src/docs/3.x/resources/export-sizes.md +++ b/sites/website/src/docs/3.x/resources/export-sizes.md @@ -34,7 +34,7 @@ Bundle sizes for `@microsoft/fast-element` exports. | repeat (@microsoft/fast-element/repeat.js) | 31.80 KB | 10.00 KB | 9.03 KB | | css (@microsoft/fast-element/css.js) | 2.43 KB | 1.00 KB | 911 B | | enableHydration (@microsoft/fast-element/hydration.js) | 46.71 KB | 13.94 KB | 12.51 KB | -| declarativeTemplate (@microsoft/fast-element/declarative.js) | 62.33 KB | 19.50 KB | 17.48 KB | +| declarativeTemplate (@microsoft/fast-element/declarative.js) | 62.44 KB | 19.52 KB | 17.47 KB | | ArrayObserver (@microsoft/fast-element/arrays.js) | 12.55 KB | 4.46 KB | 4.03 KB | | observerMap (@microsoft/fast-element/observer-map.js) | 21.96 KB | 7.73 KB | 6.97 KB | | attributeMap (@microsoft/fast-element/attribute-map.js) | 15.31 KB | 5.41 KB | 4.88 KB |