@microsoft/fast-html 1.0.0-alpha.8 → 1.0.0-alpha.9
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.
- package/README.md +44 -2
- package/dist/dts/components/template.d.ts +14 -1
- package/dist/esm/components/template.js +12 -0
- package/dist/esm/fixtures/attribute/main.js +8 -1
- package/dist/esm/fixtures/binding/main.js +13 -1
- package/dist/esm/fixtures/children/main.js +8 -1
- package/dist/esm/fixtures/dot-syntax/main.js +8 -1
- package/dist/esm/fixtures/event/main.js +8 -1
- package/dist/esm/fixtures/partial/main.js +8 -1
- package/dist/esm/fixtures/ref/main.js +8 -1
- package/dist/esm/fixtures/repeat/main.js +8 -1
- package/dist/esm/fixtures/slotted/main.js +8 -1
- package/dist/esm/fixtures/when/main.js +53 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/fast-html.api.json +85 -0
- package/dist/fast-html.d.ts +15 -0
- package/dist/fast-html.untrimmed.d.ts +15 -0
- package/package.json +9 -5
- package/rules/attribute-directives.yml +38 -0
- package/rules/call-expression-with-event-argument.yml +41 -0
- package/rules/member-expression.yml +33 -0
- package/rules/tag-function-to-template-literal.yml +16 -0
package/README.md
CHANGED
|
@@ -23,13 +23,27 @@ In your JS bundle you will need to include the `@microsoft/fast-html` package:
|
|
|
23
23
|
|
|
24
24
|
```typescript
|
|
25
25
|
import { TemplateElement } from "@microsoft/fast-html";
|
|
26
|
+
import { MyCustomElement } from "./my-custom-element";
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
MyCustomElement.define({
|
|
29
|
+
name: "my-custom-element",
|
|
30
|
+
shadowOptions: null,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
TemplateElement.options({
|
|
34
|
+
"my-custom-element": {
|
|
35
|
+
shadowOptions: {
|
|
36
|
+
mode: "closed",
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
}).define({
|
|
28
40
|
name: "f-template",
|
|
29
41
|
});
|
|
30
42
|
```
|
|
31
43
|
|
|
32
|
-
This will include the `<f-template>` custom element and all logic for interpreting the declarative HTML syntax for a FAST web component.
|
|
44
|
+
This will include the `<f-template>` custom element and all logic for interpreting the declarative HTML syntax for a FAST web component as well as the `shadowOptions` for any element an `<f-template>` has been used to define.
|
|
45
|
+
|
|
46
|
+
It is necessary to set the initial `shadowOptions` of your custom elements to `null` otherwise a shadowRoot will be attached and cause a FOUC (Flash Of Unstyled Content).
|
|
33
47
|
|
|
34
48
|
The template must be wrapped in `<f-template name="[custom-element-name]"><template>[template logic]</template></f-template>` with a `name` attribute for the custom elements name, and the template logic inside.
|
|
35
49
|
|
|
@@ -175,6 +189,34 @@ Example:
|
|
|
175
189
|
|
|
176
190
|
When writing components with the intention of using the declarative HTML syntax, it is imperative that components are written with styling and rendering of the component to be less reliant on any JavaScript state management. An example of this is relying on `elementInterals` state to style a component.
|
|
177
191
|
|
|
192
|
+
### Converting Components
|
|
193
|
+
|
|
194
|
+
FAST Components written using the `html` tag template literal can be partially converted via the supplied `.yml` rules made for use with [ast-grep](https://ast-grep.github.io/).
|
|
195
|
+
|
|
196
|
+
Example:
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
// before
|
|
200
|
+
export const template = html`
|
|
201
|
+
<slot ${slotted("slottedNodes")}></slot>
|
|
202
|
+
`;
|
|
203
|
+
// after
|
|
204
|
+
export const template = `
|
|
205
|
+
<slot f-slotted="{slottedNodes}"></slot>
|
|
206
|
+
`;
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Which creates a starting point for converting the tag template literals to the declarative HTML syntax.
|
|
210
|
+
|
|
211
|
+
If your template includes JavaScript specific logic that does not conform to those rules, the fix may not be applied or may apply incorrectly. It is therefore suggested that complex logic instead leverages the custom elements JavaScript class.
|
|
212
|
+
|
|
213
|
+
#### Available Rules
|
|
214
|
+
|
|
215
|
+
- `@microsoft/fast-html/rules/attribute-directive.yml`
|
|
216
|
+
- `@microsoft/fast-html/rules/call-expression-with-event-argument.yml`
|
|
217
|
+
- `@microsoft/fast-html/rules/member-expression.yml`
|
|
218
|
+
- `@microsoft/fast-html/rules/tag-function-to-template-literal.yml`
|
|
219
|
+
|
|
178
220
|
## Acknowledgements
|
|
179
221
|
|
|
180
222
|
This project has been heavily inspired by [Handlebars](https://handlebarsjs.com/) and [Vue.js](https://vuejs.org/).
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import { FASTElement } from "@microsoft/fast-element";
|
|
1
|
+
import { FASTElement, ShadowRootOptions } from "@microsoft/fast-element";
|
|
2
|
+
/**
|
|
3
|
+
* A dictionary of element options the TemplateElement will use to update the registered element
|
|
4
|
+
*/
|
|
5
|
+
interface ElementOptions {
|
|
6
|
+
[key: string]: {
|
|
7
|
+
shadowOptions: ShadowRootOptions | undefined;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
2
10
|
/**
|
|
3
11
|
* The <f-template> custom element that will provide view logic to the element
|
|
4
12
|
*/
|
|
@@ -7,7 +15,12 @@ declare class TemplateElement extends FASTElement {
|
|
|
7
15
|
* The name of the custom element this template will be applied to
|
|
8
16
|
*/
|
|
9
17
|
name?: string;
|
|
18
|
+
/**
|
|
19
|
+
* A dictionary of custom element options
|
|
20
|
+
*/
|
|
21
|
+
static elementOptions: ElementOptions;
|
|
10
22
|
private partials;
|
|
23
|
+
static options(elementOptions?: ElementOptions): typeof TemplateElement;
|
|
11
24
|
connectedCallback(): void;
|
|
12
25
|
/**
|
|
13
26
|
* Resolve strings and values from an innerHTML string
|
|
@@ -15,12 +15,17 @@ class TemplateElement extends FASTElement {
|
|
|
15
15
|
super(...arguments);
|
|
16
16
|
this.partials = {};
|
|
17
17
|
}
|
|
18
|
+
static options(elementOptions = {}) {
|
|
19
|
+
this.elementOptions = elementOptions;
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
18
22
|
connectedCallback() {
|
|
19
23
|
super.connectedCallback();
|
|
20
24
|
if (this.name) {
|
|
21
25
|
this.$fastController.definition.registry
|
|
22
26
|
.whenDefined(this.name)
|
|
23
27
|
.then((value) => __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
var _a;
|
|
24
29
|
const registeredFastElement = fastElementRegistry.getByType(value);
|
|
25
30
|
const template = this.getElementsByTagName("template").item(0);
|
|
26
31
|
if (template) {
|
|
@@ -31,6 +36,9 @@ class TemplateElement extends FASTElement {
|
|
|
31
36
|
// all new elements will get the updated template
|
|
32
37
|
registeredFastElement.template =
|
|
33
38
|
this.resolveTemplateOrBehavior(strings, values);
|
|
39
|
+
// set shadow options as defined by the f-template
|
|
40
|
+
registeredFastElement.shadowOptions =
|
|
41
|
+
(_a = TemplateElement.elementOptions[this.name]) === null || _a === void 0 ? void 0 : _a.shadowOptions;
|
|
34
42
|
}
|
|
35
43
|
}
|
|
36
44
|
else {
|
|
@@ -294,6 +302,10 @@ class TemplateElement extends FASTElement {
|
|
|
294
302
|
});
|
|
295
303
|
}
|
|
296
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* A dictionary of custom element options
|
|
307
|
+
*/
|
|
308
|
+
TemplateElement.elementOptions = {};
|
|
297
309
|
__decorate([
|
|
298
310
|
attr,
|
|
299
311
|
__metadata("design:type", String)
|
|
@@ -13,7 +13,14 @@ __decorate([
|
|
|
13
13
|
], TestElement.prototype, "type", void 0);
|
|
14
14
|
TestElement.define({
|
|
15
15
|
name: "test-element",
|
|
16
|
+
shadowOptions: null,
|
|
16
17
|
});
|
|
17
|
-
TemplateElement.
|
|
18
|
+
TemplateElement.options({
|
|
19
|
+
"test-element": {
|
|
20
|
+
shadowOptions: {
|
|
21
|
+
mode: "closed",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
}).define({
|
|
18
25
|
name: "f-template",
|
|
19
26
|
});
|
|
@@ -22,7 +22,19 @@ class TestElementUnescaped extends FASTElement {
|
|
|
22
22
|
}
|
|
23
23
|
TestElementUnescaped.define({
|
|
24
24
|
name: "test-element-unescaped",
|
|
25
|
+
shadowOptions: null,
|
|
25
26
|
});
|
|
26
|
-
TemplateElement.
|
|
27
|
+
TemplateElement.options({
|
|
28
|
+
"test-element": {
|
|
29
|
+
shadowOptions: {
|
|
30
|
+
mode: "closed",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
"test-element-unescaped": {
|
|
34
|
+
shadowOptions: {
|
|
35
|
+
mode: "closed",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
}).define({
|
|
27
39
|
name: "f-template",
|
|
28
40
|
});
|
|
@@ -18,7 +18,14 @@ __decorate([
|
|
|
18
18
|
], TestElement.prototype, "list", void 0);
|
|
19
19
|
TestElement.define({
|
|
20
20
|
name: "test-element",
|
|
21
|
+
shadowOptions: null,
|
|
21
22
|
});
|
|
22
|
-
TemplateElement.
|
|
23
|
+
TemplateElement.options({
|
|
24
|
+
"test-element": {
|
|
25
|
+
shadowOptions: {
|
|
26
|
+
mode: "closed",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
}).define({
|
|
23
30
|
name: "f-template",
|
|
24
31
|
});
|
|
@@ -10,7 +10,14 @@ class TestElement extends FASTElement {
|
|
|
10
10
|
}
|
|
11
11
|
TestElement.define({
|
|
12
12
|
name: "test-element",
|
|
13
|
+
shadowOptions: null,
|
|
13
14
|
});
|
|
14
|
-
TemplateElement.
|
|
15
|
+
TemplateElement.options({
|
|
16
|
+
"test-element": {
|
|
17
|
+
shadowOptions: {
|
|
18
|
+
mode: "closed",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
}).define({
|
|
15
22
|
name: "f-template",
|
|
16
23
|
});
|
|
@@ -22,7 +22,14 @@ __decorate([
|
|
|
22
22
|
], TestElement.prototype, "foo", void 0);
|
|
23
23
|
TestElement.define({
|
|
24
24
|
name: "test-element",
|
|
25
|
+
shadowOptions: null,
|
|
25
26
|
});
|
|
26
|
-
TemplateElement.
|
|
27
|
+
TemplateElement.options({
|
|
28
|
+
"test-element": {
|
|
29
|
+
shadowOptions: {
|
|
30
|
+
mode: "closed",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
}).define({
|
|
27
34
|
name: "f-template",
|
|
28
35
|
});
|
|
@@ -25,7 +25,14 @@ class TestElement extends FASTElement {
|
|
|
25
25
|
}
|
|
26
26
|
TestElement.define({
|
|
27
27
|
name: "test-element",
|
|
28
|
+
shadowOptions: null,
|
|
28
29
|
});
|
|
29
|
-
TemplateElement.
|
|
30
|
+
TemplateElement.options({
|
|
31
|
+
"test-element": {
|
|
32
|
+
shadowOptions: {
|
|
33
|
+
mode: "closed",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
}).define({
|
|
30
37
|
name: "f-template",
|
|
31
38
|
});
|
|
@@ -8,7 +8,14 @@ class TestElement extends FASTElement {
|
|
|
8
8
|
}
|
|
9
9
|
TestElement.define({
|
|
10
10
|
name: "test-element",
|
|
11
|
+
shadowOptions: null,
|
|
11
12
|
});
|
|
12
|
-
TemplateElement.
|
|
13
|
+
TemplateElement.options({
|
|
14
|
+
"test-element": {
|
|
15
|
+
shadowOptions: {
|
|
16
|
+
mode: "closed",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
}).define({
|
|
13
20
|
name: "f-template",
|
|
14
21
|
});
|
|
@@ -14,7 +14,14 @@ __decorate([
|
|
|
14
14
|
], TestElement.prototype, "list", void 0);
|
|
15
15
|
TestElement.define({
|
|
16
16
|
name: "test-element",
|
|
17
|
+
shadowOptions: null,
|
|
17
18
|
});
|
|
18
|
-
TemplateElement.
|
|
19
|
+
TemplateElement.options({
|
|
20
|
+
"test-element": {
|
|
21
|
+
shadowOptions: {
|
|
22
|
+
mode: "closed",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
}).define({
|
|
19
26
|
name: "f-template",
|
|
20
27
|
});
|
|
@@ -16,7 +16,14 @@ __decorate([
|
|
|
16
16
|
], TestElement.prototype, "slottedNodes", void 0);
|
|
17
17
|
TestElement.define({
|
|
18
18
|
name: "test-element",
|
|
19
|
+
shadowOptions: null,
|
|
19
20
|
});
|
|
20
|
-
TemplateElement.
|
|
21
|
+
TemplateElement.options({
|
|
22
|
+
"test-element": {
|
|
23
|
+
shadowOptions: {
|
|
24
|
+
mode: "closed",
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
}).define({
|
|
21
28
|
name: "f-template",
|
|
22
29
|
});
|
|
@@ -140,7 +140,59 @@ __decorate([
|
|
|
140
140
|
], TestElementAnd.prototype, "thatVar", void 0);
|
|
141
141
|
TestElementAnd.define({
|
|
142
142
|
name: "test-element-and",
|
|
143
|
+
shadowOptions: null,
|
|
143
144
|
});
|
|
144
|
-
TemplateElement.
|
|
145
|
+
TemplateElement.options({
|
|
146
|
+
"test-element": {
|
|
147
|
+
shadowOptions: {
|
|
148
|
+
mode: "closed",
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
"test-element-not": {
|
|
152
|
+
shadowOptions: {
|
|
153
|
+
mode: "closed",
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
"test-element-equals": {
|
|
157
|
+
shadowOptions: {
|
|
158
|
+
mode: "closed",
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
"test-element-not-equals": {
|
|
162
|
+
shadowOptions: {
|
|
163
|
+
mode: "closed",
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
"test-element-ge": {
|
|
167
|
+
shadowOptions: {
|
|
168
|
+
mode: "closed",
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
"test-element-gt": {
|
|
172
|
+
shadowOptions: {
|
|
173
|
+
mode: "closed",
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
"test-element-le": {
|
|
177
|
+
shadowOptions: {
|
|
178
|
+
mode: "closed",
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
"test-element-lt": {
|
|
182
|
+
shadowOptions: {
|
|
183
|
+
mode: "closed",
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
"test-element-or": {
|
|
187
|
+
shadowOptions: {
|
|
188
|
+
mode: "closed",
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
"test-element-and": {
|
|
192
|
+
shadowOptions: {
|
|
193
|
+
mode: "closed",
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
}).define({
|
|
145
197
|
name: "f-template",
|
|
146
198
|
});
|