@microsoft/fast-html 1.0.0-alpha.1 → 1.0.0-alpha.10

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.
Files changed (69) hide show
  1. package/README.md +100 -7
  2. package/dist/dts/components/index.d.ts +1 -0
  3. package/dist/dts/components/template.d.ts +74 -0
  4. package/dist/dts/components/utilities.d.ts +111 -0
  5. package/dist/dts/components/utilities.spec.d.ts +1 -0
  6. package/dist/dts/debug.d.ts +3 -0
  7. package/dist/dts/fixtures/attribute/attribute.spec.d.ts +1 -0
  8. package/dist/dts/fixtures/attribute/main.d.ts +1 -0
  9. package/dist/dts/fixtures/binding/binding.spec.d.ts +1 -0
  10. package/dist/dts/fixtures/binding/main.d.ts +1 -0
  11. package/dist/dts/fixtures/children/children.spec.d.ts +1 -0
  12. package/dist/dts/fixtures/children/main.d.ts +1 -0
  13. package/dist/dts/fixtures/dot-syntax/dot-syntax.spec.d.ts +1 -0
  14. package/dist/dts/fixtures/dot-syntax/main.d.ts +1 -0
  15. package/dist/dts/fixtures/event/event.spec.d.ts +1 -0
  16. package/dist/dts/fixtures/event/main.d.ts +1 -0
  17. package/dist/dts/fixtures/partial/main.d.ts +1 -0
  18. package/dist/dts/fixtures/partial/partial.spec.d.ts +1 -0
  19. package/dist/dts/fixtures/ref/main.d.ts +1 -0
  20. package/dist/dts/fixtures/ref/ref.spec.d.ts +1 -0
  21. package/dist/dts/fixtures/repeat/main.d.ts +1 -0
  22. package/dist/dts/fixtures/repeat/repeat.spec.d.ts +1 -0
  23. package/dist/dts/fixtures/slotted/main.d.ts +1 -0
  24. package/dist/dts/fixtures/slotted/slotted.spec.d.ts +1 -0
  25. package/dist/dts/fixtures/when/main.d.ts +1 -0
  26. package/dist/dts/fixtures/when/when.spec.d.ts +1 -0
  27. package/dist/dts/index.d.ts +1 -0
  28. package/dist/dts/interfaces.d.ts +7 -0
  29. package/dist/dts/tsdoc-metadata.json +11 -0
  30. package/dist/esm/components/index.js +1 -0
  31. package/dist/esm/components/template.js +313 -0
  32. package/dist/esm/components/utilities.js +370 -0
  33. package/dist/esm/components/utilities.spec.js +189 -0
  34. package/dist/esm/debug.js +3 -0
  35. package/dist/esm/fixtures/attribute/attribute.spec.js +23 -0
  36. package/dist/esm/fixtures/attribute/main.js +26 -0
  37. package/dist/esm/fixtures/binding/binding.spec.js +23 -0
  38. package/dist/esm/fixtures/binding/main.js +40 -0
  39. package/dist/esm/fixtures/children/children.spec.js +37 -0
  40. package/dist/esm/fixtures/children/main.js +31 -0
  41. package/dist/esm/fixtures/dot-syntax/dot-syntax.spec.js +9 -0
  42. package/dist/esm/fixtures/dot-syntax/main.js +23 -0
  43. package/dist/esm/fixtures/event/event.spec.js +28 -0
  44. package/dist/esm/fixtures/event/main.js +35 -0
  45. package/dist/esm/fixtures/partial/main.js +38 -0
  46. package/dist/esm/fixtures/partial/partial.spec.js +14 -0
  47. package/dist/esm/fixtures/ref/main.js +21 -0
  48. package/dist/esm/fixtures/ref/ref.spec.js +13 -0
  49. package/dist/esm/fixtures/repeat/main.js +27 -0
  50. package/dist/esm/fixtures/repeat/repeat.spec.js +29 -0
  51. package/dist/esm/fixtures/slotted/main.js +29 -0
  52. package/dist/esm/fixtures/slotted/slotted.spec.js +25 -0
  53. package/dist/esm/fixtures/when/main.js +198 -0
  54. package/dist/esm/fixtures/when/when.spec.js +82 -0
  55. package/dist/esm/index.js +4 -0
  56. package/dist/esm/interfaces.js +1 -0
  57. package/dist/esm/tsconfig.tsbuildinfo +1 -0
  58. package/dist/fast-html.api.json +356 -0
  59. package/dist/fast-html.d.ts +78 -0
  60. package/dist/fast-html.untrimmed.d.ts +78 -0
  61. package/package.json +12 -6
  62. package/rules/attribute-directives.yml +38 -0
  63. package/rules/call-expression-with-event-argument.yml +41 -0
  64. package/rules/member-expression.yml +33 -0
  65. package/rules/tag-function-to-template-literal.yml +16 -0
  66. package/CHANGELOG.json +0 -26
  67. package/CHANGELOG.md +0 -14
  68. package/docs/api-report.api.md +0 -18
  69. package/webpack.common.config.js +0 -18
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
 
@@ -47,7 +61,15 @@ Example:
47
61
 
48
62
  ### Syntax
49
63
 
50
- All bindings use a handlebars syntax.
64
+ All bindings use a handlebars-like syntax.
65
+
66
+ Some bindings are only relevant to the browser, such as for click handlers or other pieces of dynamic interaction. As such, their bindings use single curly braces `{}`, this is to prevent an intial SSR (Server Side Rendering) or other build time rendering technologies from needing to interpret them.
67
+
68
+ If a binding is relevant to both client and the back end rendering engine, it will use `{{}}` or `{{{}}}` depending on what type of data injection is being done.
69
+
70
+ Browser-only bindings:
71
+ - Event bindings
72
+ - Attribute directives
51
73
 
52
74
  #### Content binding
53
75
 
@@ -60,33 +82,47 @@ All bindings use a handlebars syntax.
60
82
  Event bindings must include the `()` as well as being preceeded by `@` in keeping with `@microsoft/fast-element` tagged template `html` syntax.
61
83
 
62
84
  ```html
63
- <button @click="{{handleClick()}}"></button>
85
+ <button @click="{handleClick()}"></button>
86
+ ```
87
+
88
+ In addition you may include an event or attribute or observable, events are denoted with `e` as a reserved letter.
89
+
90
+ Event:
91
+ ```html
92
+ <button @click="{handleClick(e)}"></button>
93
+ ```
94
+
95
+ Attribute/Observable:
96
+ ```html
97
+ <button @click="{handleClick(foo)}"></button>
64
98
  ```
65
99
 
66
100
  #### Directives
67
101
 
68
102
  Directives are assumed to be either an attribute directive or a directive that also serves a template. Both are prepended by `f-`. The logic of these directives and what their use cases are is explained in the [FAST html documentation](https://fast.design/docs/getting-started/html-directives).
69
103
 
104
+ Attribute directives are part of [client side binding](#syntax) and therefore use the `{}` syntax.
105
+
70
106
  Attribute directives include:
71
107
  - **slotted**
72
108
 
73
109
  Example:
74
110
  ```html
75
- <slot f-slotted="{{slottedNodes}}"></slot>
111
+ <slot f-slotted="{slottedNodes}"></slot>
76
112
  ```
77
113
 
78
114
  - **children**
79
115
 
80
116
  Example:
81
117
  ```html
82
- <ul f-children="{{listItems}}"><f-repeat value="{{item in list}}"><li>{{item}}</li></f-repeat></ul>
118
+ <ul f-children="{listItems}"><f-repeat value="{{item in list}}"><li>{{item}}</li></f-repeat></ul>
83
119
  ```
84
120
 
85
121
  - **ref**
86
122
 
87
123
  Example:
88
124
  ```html
89
- <video f-ref="{{video}}"></video>
125
+ <video f-ref="{video}"></video>
90
126
  ```
91
127
 
92
128
  Template directives include:
@@ -95,8 +131,21 @@ Template directives include:
95
131
  Example:
96
132
  ```html
97
133
  <f-when value="{{show}}">Hello world</f-when>
134
+ <f-when value="{{!show}}">Goodbye world</f-when>
98
135
  ```
99
136
 
137
+ The following operators can also be used:
138
+ - `==`
139
+ - `!=`
140
+ - `>=`
141
+ - `>`
142
+ - `<=`
143
+ - `<`
144
+ - `||`
145
+ - `&&`
146
+
147
+ Where the right operand can be either a reference to a value (string e.g. `{{foo == 'bar'}}`, boolean e.g. `{{foo == true}}`, number e.g. `{{foo == 3}}`) or another binding value.
148
+
100
149
  - **repeat**
101
150
 
102
151
  Example:
@@ -104,6 +153,13 @@ Template directives include:
104
153
  <ul><f-repeat value="{{item in list}}"><li>{{item}}</li></f-repeat></ul>
105
154
  ```
106
155
 
156
+ Should you need to refer to the parent element (not the individual item in the list), you can use `../`. This will map to what `html` tag template literal uses, `c.parent`.
157
+
158
+ Example:
159
+ ```html
160
+ <ul><f-repeat value="{{item in list}}"><li>{{item}} - {{../title}}</li></f-repeat></ul>
161
+ ```
162
+
107
163
  - **partial & apply**
108
164
 
109
165
  These directives are new to the declarative HTML model and allow for the ability to declare a `partial` directive containing a template partial which can then be referenced by an `apply` directive.
@@ -120,10 +176,47 @@ Template directives include:
120
176
  <f-apply partial="test" value="{{items}}"></f-apply>
121
177
  ```
122
178
 
179
+ #### Unescaped HTML
180
+
181
+ You can add unescaped HTML using triple braces, this will create an additional `div` element as the HTML needs an element to bind to. Where possible it is advisable to not use unescaped HTML and instead use other binding techniques as well as partials.
182
+
183
+ Example:
184
+ ```html
185
+ {{{html}}}
186
+ ```
187
+
123
188
  ### Writing Components
124
189
 
125
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.
126
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
+
127
220
  ## Acknowledgements
128
221
 
129
222
  This project has been heavily inspired by [Handlebars](https://handlebarsjs.com/) and [Vue.js](https://vuejs.org/).
@@ -0,0 +1 @@
1
+ export { TemplateElement } from "./template.js";
@@ -0,0 +1,74 @@
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
+ }
10
+ /**
11
+ * The <f-template> custom element that will provide view logic to the element
12
+ */
13
+ declare class TemplateElement extends FASTElement {
14
+ /**
15
+ * The name of the custom element this template will be applied to
16
+ */
17
+ name?: string;
18
+ /**
19
+ * A dictionary of custom element options
20
+ */
21
+ static elementOptions: ElementOptions;
22
+ private partials;
23
+ static options(elementOptions?: ElementOptions): typeof TemplateElement;
24
+ connectedCallback(): void;
25
+ /**
26
+ * Resolve strings and values from an innerHTML string
27
+ * @param innerHTML - The innerHTML.
28
+ * @param self - Indicates that this should refer to itself instead of a property when creating bindings.
29
+ */
30
+ private resolveStringsAndValues;
31
+ /**
32
+ * Resolve a template or behavior
33
+ * @param strings - The strings array.
34
+ * @param values - The interpreted values.
35
+ */
36
+ private resolveTemplateOrBehavior;
37
+ /**
38
+ * Resolve a template directive
39
+ * @param behaviorConfig - The directive behavior configuration object.
40
+ * @param externalValues - The interpreted values from the parent.
41
+ * @param innerHTML - The innerHTML.
42
+ */
43
+ private resolveTemplateDirective;
44
+ /**
45
+ * Resolve a template directive
46
+ * @param name - The name of the directive.
47
+ * @param propName - The property name to pass to the directive.
48
+ * @param externalValues - The interpreted values from the parent.
49
+ */
50
+ private resolveAttributeDirective;
51
+ /**
52
+ * Resolver of a data binding
53
+ * @param innerHTML - The innerHTML.
54
+ * @param strings - The strings array.
55
+ * @param values - The interpreted values.
56
+ * @param self - Indicates that this should refer to itself instead of a property when creating bindings.
57
+ * @param behaviorConfig - The binding behavior configuration object.
58
+ */
59
+ private resolveDataBinding;
60
+ /**
61
+ * Resolver of the innerHTML string
62
+ * @param innerHTML - The innerHTML.
63
+ * @param strings - The strings array.
64
+ * @param values - The interpreted values.
65
+ * @param self - Indicates that this should refer to itself instead of a property when creating bindings.
66
+ */
67
+ private resolveInnerHTML;
68
+ /**
69
+ * Resolve all partial templates
70
+ * @param unresolvedInnerHTML - The innerHTML.
71
+ */
72
+ private resolveAllPartials;
73
+ }
74
+ export { TemplateElement };
@@ -0,0 +1,111 @@
1
+ type BehaviorType = "dataBinding" | "templateDirective";
2
+ type TemplateDirective = "when" | "repeat" | "apply";
3
+ export type AttributeDirective = "children" | "slotted" | "ref";
4
+ type DataBindingBindingType = "client" | "default" | "unescaped";
5
+ interface BehaviorConfig {
6
+ type: BehaviorType;
7
+ }
8
+ export interface ContentDataBindingBehaviorConfig extends BaseDataBindingBehaviorConfig {
9
+ subtype: "content";
10
+ }
11
+ export interface AttributeDataBindingBehaviorConfig extends BaseDataBindingBehaviorConfig {
12
+ subtype: "attribute";
13
+ aspect: "@" | ":" | "?" | null;
14
+ }
15
+ export interface AttributeDirectiveBindingBehaviorConfig extends BaseDataBindingBehaviorConfig {
16
+ subtype: "attributeDirective";
17
+ name: AttributeDirective;
18
+ }
19
+ export type DataBindingBehaviorConfig = ContentDataBindingBehaviorConfig | AttributeDataBindingBehaviorConfig | AttributeDirectiveBindingBehaviorConfig;
20
+ export interface BaseDataBindingBehaviorConfig extends BehaviorConfig {
21
+ type: "dataBinding";
22
+ bindingType: DataBindingBindingType;
23
+ openingStartIndex: number;
24
+ openingEndIndex: number;
25
+ closingStartIndex: number;
26
+ closingEndIndex: number;
27
+ }
28
+ export interface TemplateDirectiveBehaviorConfig extends BehaviorConfig {
29
+ type: "templateDirective";
30
+ name: TemplateDirective;
31
+ value: string;
32
+ openingTagStartIndex: number;
33
+ openingTagEndIndex: number;
34
+ closingTagStartIndex: number;
35
+ closingTagEndIndex: number;
36
+ }
37
+ interface PartialTemplateConfig {
38
+ innerHTML: string;
39
+ startIndex: number;
40
+ endIndex: number;
41
+ }
42
+ /**
43
+ * Get the index of the next matching tag
44
+ * @param openingTagStartSlice - The slice starting from the opening tag
45
+ * @param openingTag - The opening tag string
46
+ * @param closingTag - The closing tag
47
+ * @param openingTagStartIndex - The opening tag start index derived from the innerHTML
48
+ * @returns index
49
+ */
50
+ export declare function getIndexOfNextMatchingTag(openingTagStartSlice: string, openingTag: string, closingTag: string, openingTagStartIndex: number): number;
51
+ /**
52
+ * Get the next behavior
53
+ * @param innerHTML - The innerHTML string to evaluate
54
+ * @returns DataBindingBehaviorConfig | DirectiveBehaviorConfig | null - A configuration object or null
55
+ */
56
+ export declare function getNextBehavior(innerHTML: string): DataBindingBehaviorConfig | TemplateDirectiveBehaviorConfig | null;
57
+ /**
58
+ * Gets all the partials with their IDs
59
+ * @param innerHTML - The innerHTML string to evaluate
60
+ * @param offset - The index offset from the innerHTML
61
+ * @param partials - The partials found
62
+ * @returns {[key: string]: PartialTemplateConfig}
63
+ */
64
+ export declare function getAllPartials(innerHTML: string, offset?: number, partials?: {
65
+ [key: string]: PartialTemplateConfig;
66
+ }): {
67
+ [key: string]: PartialTemplateConfig;
68
+ };
69
+ /**
70
+ * Create a function to resolve a value from an object using a path with dot syntax.
71
+ * e.g. "foo.bar"
72
+ * @param path - The dot syntax path to an objects property.
73
+ * @param self - Where the first item in the path path refers to the item itself (used by repeat).
74
+ * @returns A function to access the value from a given path.
75
+ */
76
+ export declare function pathResolver(path: string, self?: boolean): (accessibleObject: any, context: any) => any;
77
+ /**
78
+ * Available operators include:
79
+ *
80
+ * - access (no operator)
81
+ * - not (!)
82
+ * - equals (==)
83
+ * - not equal (!=)
84
+ * - greater than or equal (>=)
85
+ * - greater than (>)
86
+ * - less than or equal (<=)
87
+ * - less than (<)
88
+ * - or (||)
89
+ * - and (&&) and the HTML character entity (&amp;&amp;)
90
+ */
91
+ type Operator = "access" | "!" | "==" | "!=" | ">=" | ">" | "<=" | "<" | "||" | "&&" | "&amp;&amp;";
92
+ interface OperatorConfig {
93
+ operator: Operator;
94
+ left: string;
95
+ right: string | boolean | number | null;
96
+ rightIsValue: boolean | null;
97
+ }
98
+ /**
99
+ * Get the operator used.
100
+ * @param value the binded value
101
+ * @returns Operator
102
+ */
103
+ export declare function getOperator(value: string): OperatorConfig;
104
+ /**
105
+ * This is the transform utility for rationalizing declarative HTML syntax
106
+ * with bindings in the ViewTemplate
107
+ * @param innerHTML The innerHTML to transform
108
+ * @param index The index to start the current slice of HTML to evaluate
109
+ */
110
+ export declare function transformInnerHTML(innerHTML: string, index?: number): string;
111
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export declare const debugMessages: {
2
+ 2000: string;
3
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export { TemplateElement } from "./components/index.js";
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Warning and error messages.
3
+ * @internal
4
+ */
5
+ export declare const enum Message {
6
+ noTemplateProvided = 2000
7
+ }
@@ -0,0 +1,11 @@
1
+ // This file is read by tools that parse documentation comments conforming to the TSDoc standard.
2
+ // It should be published with your NPM package. It should not be tracked by Git.
3
+ {
4
+ "tsdocVersion": "0.12",
5
+ "toolPackages": [
6
+ {
7
+ "packageName": "@microsoft/api-extractor",
8
+ "packageVersion": "7.47.0"
9
+ }
10
+ ]
11
+ }
@@ -0,0 +1 @@
1
+ export { TemplateElement } from "./template.js";