@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 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
- TemplateElement.define({
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.define({
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.define({
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.define({
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.define({
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.define({
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.define({
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.define({
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.define({
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.define({
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.define({
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
  });