@microsoft/fast-element 1.10.2 → 2.0.0-beta.3

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 (104) hide show
  1. package/.eslintrc.json +1 -12
  2. package/CHANGELOG.json +387 -1
  3. package/CHANGELOG.md +74 -2
  4. package/README.md +2 -2
  5. package/dist/dts/components/attributes.d.ts +4 -1
  6. package/dist/dts/components/controller.d.ts +12 -11
  7. package/dist/dts/components/fast-definitions.d.ts +10 -2
  8. package/dist/dts/components/fast-element.d.ts +12 -5
  9. package/dist/dts/context.d.ts +157 -0
  10. package/dist/dts/debug.d.ts +1 -0
  11. package/dist/dts/hooks.d.ts +20 -0
  12. package/dist/dts/index.d.ts +16 -15
  13. package/dist/dts/index.debug.d.ts +2 -0
  14. package/dist/dts/index.rollup.d.ts +2 -0
  15. package/dist/dts/index.rollup.debug.d.ts +3 -0
  16. package/dist/dts/interfaces.d.ts +145 -0
  17. package/dist/dts/metadata.d.ts +25 -0
  18. package/dist/dts/observation/arrays.d.ts +207 -0
  19. package/dist/dts/observation/behavior.d.ts +4 -4
  20. package/dist/dts/observation/notifier.d.ts +18 -18
  21. package/dist/dts/observation/observable.d.ts +56 -18
  22. package/dist/dts/observation/splice-strategies.d.ts +13 -0
  23. package/dist/dts/observation/update-queue.d.ts +40 -0
  24. package/dist/dts/platform.d.ts +18 -67
  25. package/dist/dts/polyfills.d.ts +8 -0
  26. package/dist/dts/styles/css-directive.d.ts +43 -5
  27. package/dist/dts/styles/css.d.ts +19 -3
  28. package/dist/dts/styles/element-styles.d.ts +42 -62
  29. package/dist/dts/templating/binding-signal.d.ts +38 -0
  30. package/dist/dts/templating/binding-two-way.d.ts +56 -0
  31. package/dist/dts/templating/binding.d.ts +233 -65
  32. package/dist/dts/templating/children.d.ts +18 -15
  33. package/dist/dts/templating/compiler.d.ts +46 -28
  34. package/dist/dts/templating/dom.d.ts +41 -0
  35. package/dist/dts/templating/html-directive.d.ts +181 -43
  36. package/dist/dts/templating/markup.d.ts +48 -0
  37. package/dist/dts/templating/node-observation.d.ts +45 -29
  38. package/dist/dts/templating/ref.d.ts +6 -12
  39. package/dist/dts/templating/repeat.d.ts +26 -14
  40. package/dist/dts/templating/slotted.d.ts +13 -14
  41. package/dist/dts/templating/template.d.ts +27 -21
  42. package/dist/dts/templating/view.d.ts +15 -22
  43. package/dist/{tsdoc-metadata.json → dts/tsdoc-metadata.json} +1 -1
  44. package/dist/dts/utilities.d.ts +40 -0
  45. package/dist/esm/components/attributes.js +25 -24
  46. package/dist/esm/components/controller.js +77 -57
  47. package/dist/esm/components/fast-definitions.js +16 -22
  48. package/dist/esm/components/fast-element.js +10 -2
  49. package/dist/esm/context.js +159 -0
  50. package/dist/esm/debug.js +30 -0
  51. package/dist/esm/hooks.js +32 -0
  52. package/dist/esm/index.debug.js +2 -0
  53. package/dist/esm/index.js +19 -14
  54. package/dist/esm/index.rollup.debug.js +3 -0
  55. package/dist/esm/index.rollup.js +2 -0
  56. package/dist/esm/interfaces.js +8 -1
  57. package/dist/esm/metadata.js +60 -0
  58. package/dist/esm/observation/arrays.js +269 -0
  59. package/dist/esm/observation/notifier.js +27 -35
  60. package/dist/esm/observation/observable.js +93 -68
  61. package/dist/esm/observation/{array-change-records.js → splice-strategies.js} +136 -62
  62. package/dist/esm/observation/update-queue.js +67 -0
  63. package/dist/esm/platform.js +36 -42
  64. package/dist/esm/polyfills.js +85 -0
  65. package/dist/esm/styles/css-directive.js +29 -13
  66. package/dist/esm/styles/css.js +27 -40
  67. package/dist/esm/styles/element-styles.js +65 -104
  68. package/dist/esm/templating/binding-signal.js +84 -0
  69. package/dist/esm/templating/binding-two-way.js +82 -0
  70. package/dist/esm/templating/binding.js +306 -153
  71. package/dist/esm/templating/children.js +33 -23
  72. package/dist/esm/templating/compiler.js +236 -152
  73. package/dist/esm/templating/dom.js +49 -0
  74. package/dist/esm/templating/html-directive.js +128 -40
  75. package/dist/esm/templating/markup.js +75 -0
  76. package/dist/esm/templating/node-observation.js +50 -45
  77. package/dist/esm/templating/ref.js +7 -16
  78. package/dist/esm/templating/repeat.js +39 -36
  79. package/dist/esm/templating/slotted.js +23 -20
  80. package/dist/esm/templating/template.js +51 -95
  81. package/dist/esm/templating/view.js +44 -43
  82. package/dist/esm/templating/when.js +2 -1
  83. package/dist/esm/utilities.js +139 -0
  84. package/dist/fast-element.api.json +11789 -5377
  85. package/dist/fast-element.d.ts +1178 -530
  86. package/dist/fast-element.debug.js +3722 -0
  87. package/dist/fast-element.debug.min.js +1 -0
  88. package/dist/fast-element.js +3484 -4033
  89. package/dist/fast-element.min.js +1 -1
  90. package/dist/fast-element.untrimmed.d.ts +2699 -0
  91. package/docs/api-report.md +472 -219
  92. package/docs/fast-element-2-changes.md +15 -0
  93. package/docs/guide/declaring-templates.md +4 -4
  94. package/docs/guide/defining-elements.md +2 -2
  95. package/docs/guide/next-steps.md +2 -2
  96. package/docs/guide/observables-and-state.md +1 -1
  97. package/docs/guide/using-directives.md +1 -1
  98. package/karma.conf.cjs +6 -17
  99. package/package.json +63 -15
  100. package/dist/dts/dom.d.ts +0 -112
  101. package/dist/dts/observation/array-change-records.d.ts +0 -48
  102. package/dist/dts/observation/array-observer.d.ts +0 -9
  103. package/dist/esm/dom.js +0 -207
  104. package/dist/esm/observation/array-observer.js +0 -177
@@ -0,0 +1,75 @@
1
+ const marker = `fast-${Math.random().toString(36).substring(2, 8)}`;
2
+ const interpolationStart = `${marker}{`;
3
+ const interpolationEnd = `}${marker}`;
4
+ const interpolationEndLength = interpolationEnd.length;
5
+ let id = 0;
6
+ /** @internal */
7
+ export const nextId = () => `${marker}-${++id}`;
8
+ /**
9
+ * Common APIs related to markup generation.
10
+ * @public
11
+ */
12
+ export const Markup = Object.freeze({
13
+ /**
14
+ * Creates a placeholder string suitable for marking out a location *within*
15
+ * an attribute value or HTML content.
16
+ * @param index - The directive index to create the placeholder for.
17
+ * @remarks
18
+ * Used internally by binding directives.
19
+ */
20
+ interpolation: (id) => `${interpolationStart}${id}${interpolationEnd}`,
21
+ /**
22
+ * Creates a placeholder that manifests itself as an attribute on an
23
+ * element.
24
+ * @param attributeName - The name of the custom attribute.
25
+ * @param index - The directive index to create the placeholder for.
26
+ * @remarks
27
+ * Used internally by attribute directives such as `ref`, `slotted`, and `children`.
28
+ */
29
+ attribute: (id) => `${nextId()}="${interpolationStart}${id}${interpolationEnd}"`,
30
+ /**
31
+ * Creates a placeholder that manifests itself as a marker within the DOM structure.
32
+ * @param index - The directive index to create the placeholder for.
33
+ * @remarks
34
+ * Used internally by structural directives such as `repeat`.
35
+ */
36
+ comment: (id) => `<!--${interpolationStart}${id}${interpolationEnd}-->`,
37
+ });
38
+ /**
39
+ * Common APIs related to content parsing.
40
+ * @public
41
+ */
42
+ export const Parser = Object.freeze({
43
+ /**
44
+ * Parses text content or HTML attribute content, separating out the static strings
45
+ * from the directives.
46
+ * @param value - The content or attribute string to parse.
47
+ * @param factories - A list of directives to search for in the string.
48
+ * @returns A heterogeneous array of static strings interspersed with
49
+ * directives or null if no directives are found in the string.
50
+ */
51
+ parse(value, factories) {
52
+ const parts = value.split(interpolationStart);
53
+ if (parts.length === 1) {
54
+ return null;
55
+ }
56
+ const result = [];
57
+ for (let i = 0, ii = parts.length; i < ii; ++i) {
58
+ const current = parts[i];
59
+ const index = current.indexOf(interpolationEnd);
60
+ let literal;
61
+ if (index === -1) {
62
+ literal = current;
63
+ }
64
+ else {
65
+ const factoryId = current.substring(0, index);
66
+ result.push(factories[factoryId]);
67
+ literal = current.substring(index + interpolationEndLength);
68
+ }
69
+ if (literal !== "") {
70
+ result.push(literal);
71
+ }
72
+ }
73
+ return result;
74
+ },
75
+ });
@@ -1,72 +1,77 @@
1
- import { Observable } from "../observation/observable.js";
2
1
  import { emptyArray } from "../platform.js";
2
+ import { StatelessAttachedAttributeDirective, } from "./html-directive.js";
3
+ const selectElements = (value) => value.nodeType === 1;
3
4
  /**
4
5
  * Creates a function that can be used to filter a Node array, selecting only elements.
5
6
  * @param selector - An optional selector to restrict the filter to.
6
7
  * @public
7
8
  */
8
- export function elements(selector) {
9
- if (selector) {
10
- return function (value, index, array) {
11
- return value.nodeType === 1 && value.matches(selector);
12
- };
13
- }
14
- return function (value, index, array) {
15
- return value.nodeType === 1;
16
- };
17
- }
9
+ export const elements = (selector) => selector
10
+ ? value => value.nodeType === 1 && value.matches(selector)
11
+ : selectElements;
18
12
  /**
19
13
  * A base class for node observation.
20
- * @internal
14
+ * @public
15
+ * @remarks
16
+ * Internally used by the SlottedDirective and the ChildrenDirective.
21
17
  */
22
- export class NodeObservationBehavior {
23
- /**
24
- * Creates an instance of NodeObservationBehavior.
25
- * @param target - The target to assign the nodes property on.
26
- * @param options - The options to use in configuring node observation.
27
- */
28
- constructor(target, options) {
29
- this.target = target;
30
- this.options = options;
31
- this.source = null;
18
+ export class NodeObservationDirective extends StatelessAttachedAttributeDirective {
19
+ constructor() {
20
+ super(...arguments);
21
+ this.sourceProperty = `${this.id}-s`;
32
22
  }
33
23
  /**
34
24
  * Bind this behavior to the source.
35
25
  * @param source - The source to bind to.
36
26
  * @param context - The execution context that the binding is operating within.
27
+ * @param targets - The targets that behaviors in a view can attach to.
37
28
  */
38
- bind(source) {
39
- const name = this.options.property;
40
- this.shouldUpdate = Observable.getAccessors(source).some((x) => x.name === name);
41
- this.source = source;
42
- this.updateTarget(this.computeNodes());
43
- if (this.shouldUpdate) {
44
- this.observe();
45
- }
29
+ bind(source, context, targets) {
30
+ const target = targets[this.nodeId];
31
+ target[this.sourceProperty] = source;
32
+ this.updateTarget(source, this.computeNodes(target));
33
+ this.observe(target);
46
34
  }
47
35
  /**
48
36
  * Unbinds this behavior from the source.
49
37
  * @param source - The source to unbind from.
38
+ * @param context - The execution context that the binding is operating within.
39
+ * @param targets - The targets that behaviors in a view can attach to.
50
40
  */
51
- unbind() {
52
- this.updateTarget(emptyArray);
53
- this.source = null;
54
- if (this.shouldUpdate) {
55
- this.disconnect();
56
- }
41
+ unbind(source, context, targets) {
42
+ const target = targets[this.nodeId];
43
+ this.updateTarget(source, emptyArray);
44
+ this.disconnect(target);
45
+ target[this.sourceProperty] = null;
57
46
  }
58
- /** @internal */
59
- handleEvent() {
60
- this.updateTarget(this.computeNodes());
47
+ /**
48
+ * Gets the data source for the target.
49
+ * @param target - The target to get the source for.
50
+ * @returns The source.
51
+ */
52
+ getSource(target) {
53
+ return target[this.sourceProperty];
54
+ }
55
+ /**
56
+ * Updates the source property with the computed nodes.
57
+ * @param source - The source object to assign the nodes property to.
58
+ * @param value - The nodes to assign to the source object property.
59
+ */
60
+ updateTarget(source, value) {
61
+ source[this.options.property] = value;
61
62
  }
62
- computeNodes() {
63
- let nodes = this.getNodes();
64
- if (this.options.filter !== void 0) {
63
+ /**
64
+ * Computes the set of nodes that should be assigned to the source property.
65
+ * @param target - The target to compute the nodes for.
66
+ * @returns The computed nodes.
67
+ * @remarks
68
+ * Applies filters if provided.
69
+ */
70
+ computeNodes(target) {
71
+ let nodes = this.getNodes(target);
72
+ if ("filter" in this.options) {
65
73
  nodes = nodes.filter(this.options.filter);
66
74
  }
67
75
  return nodes;
68
76
  }
69
- updateTarget(value) {
70
- this.source[this.options.property] = value;
71
- }
72
77
  }
@@ -1,25 +1,17 @@
1
- import { AttachedBehaviorHTMLDirective } from "./html-directive.js";
1
+ import { HTMLDirective, StatelessAttachedAttributeDirective, } from "./html-directive.js";
2
2
  /**
3
3
  * The runtime behavior for template references.
4
4
  * @public
5
5
  */
6
- export class RefBehavior {
7
- /**
8
- * Creates an instance of RefBehavior.
9
- * @param target - The element to reference.
10
- * @param propertyName - The name of the property to assign the reference to.
11
- */
12
- constructor(target, propertyName) {
13
- this.target = target;
14
- this.propertyName = propertyName;
15
- }
6
+ export class RefDirective extends StatelessAttachedAttributeDirective {
16
7
  /**
17
8
  * Bind this behavior to the source.
18
9
  * @param source - The source to bind to.
19
10
  * @param context - The execution context that the binding is operating within.
11
+ * @param targets - The targets that behaviors in a view can attach to.
20
12
  */
21
- bind(source) {
22
- source[this.propertyName] = this.target;
13
+ bind(source, context, targets) {
14
+ source[this.options] = targets[this.nodeId];
23
15
  }
24
16
  /**
25
17
  * Unbinds this behavior from the source.
@@ -28,11 +20,10 @@ export class RefBehavior {
28
20
  /* eslint-disable-next-line @typescript-eslint/no-empty-function */
29
21
  unbind() { }
30
22
  }
23
+ HTMLDirective.define(RefDirective);
31
24
  /**
32
25
  * A directive that observes the updates a property with a reference to the element.
33
26
  * @param propertyName - The name of the property to assign the reference to.
34
27
  * @public
35
28
  */
36
- export function ref(propertyName) {
37
- return new AttachedBehaviorHTMLDirective("fast-ref", RefBehavior, propertyName);
38
- }
29
+ export const ref = (propertyName) => new RefDirective(propertyName);
@@ -1,8 +1,9 @@
1
- import { DOM } from "../dom.js";
1
+ import { isFunction } from "../interfaces.js";
2
2
  import { Observable, } from "../observation/observable.js";
3
- import { enableArrayObservation } from "../observation/array-observer.js";
4
3
  import { emptyArray } from "../platform.js";
5
- import { HTMLDirective } from "./html-directive.js";
4
+ import { ArrayObserver } from "../observation/arrays.js";
5
+ import { Markup } from "./markup.js";
6
+ import { HTMLDirective, } from "./html-directive.js";
6
7
  import { HTMLView } from "./view.js";
7
8
  const defaultRepeatOptions = Object.freeze({
8
9
  positioning: false,
@@ -12,10 +13,7 @@ function bindWithoutPositioning(view, items, index, context) {
12
13
  view.bind(items[index], context);
13
14
  }
14
15
  function bindWithPositioning(view, items, index, context) {
15
- const childContext = Object.create(context);
16
- childContext.index = index;
17
- childContext.length = items.length;
18
- view.bind(items[index], childContext);
16
+ view.bind(items[index], context.createItemContext(index, items.length));
19
17
  }
20
18
  /**
21
19
  * A behavior that renders a template for each item in an array.
@@ -40,7 +38,7 @@ export class RepeatBehavior {
40
38
  this.views = [];
41
39
  this.items = null;
42
40
  this.itemsObserver = null;
43
- this.originalContext = void 0;
41
+ this.context = void 0;
44
42
  this.childContext = void 0;
45
43
  this.bindView = bindWithoutPositioning;
46
44
  this.itemsBindingObserver = Observable.binding(itemsBinding, this, isItemsBindingVolatile);
@@ -56,12 +54,10 @@ export class RepeatBehavior {
56
54
  */
57
55
  bind(source, context) {
58
56
  this.source = source;
59
- this.originalContext = context;
60
- this.childContext = Object.create(context);
61
- this.childContext.parent = source;
62
- this.childContext.parentContext = this.originalContext;
63
- this.items = this.itemsBindingObserver.observe(source, this.originalContext);
64
- this.template = this.templateBindingObserver.observe(source, this.originalContext);
57
+ this.context = context;
58
+ this.childContext = context.createChildContext(source);
59
+ this.items = this.itemsBindingObserver.observe(source, this.context);
60
+ this.template = this.templateBindingObserver.observe(source, this.context);
65
61
  this.observeItems(true);
66
62
  this.refreshAllViews();
67
63
  }
@@ -76,20 +72,27 @@ export class RepeatBehavior {
76
72
  this.itemsObserver.unsubscribe(this);
77
73
  }
78
74
  this.unbindAllViews();
79
- this.itemsBindingObserver.disconnect();
80
- this.templateBindingObserver.disconnect();
75
+ this.itemsBindingObserver.dispose();
76
+ this.templateBindingObserver.dispose();
81
77
  }
82
- /** @internal */
78
+ /**
79
+ * Handles changes in the array, its items, and the repeat template.
80
+ * @param source - The source of the change.
81
+ * @param args - The details about what was changed.
82
+ */
83
83
  handleChange(source, args) {
84
84
  if (source === this.itemsBinding) {
85
- this.items = this.itemsBindingObserver.observe(this.source, this.originalContext);
85
+ this.items = this.itemsBindingObserver.observe(this.source, this.context);
86
86
  this.observeItems();
87
87
  this.refreshAllViews();
88
88
  }
89
89
  else if (source === this.templateBinding) {
90
- this.template = this.templateBindingObserver.observe(this.source, this.originalContext);
90
+ this.template = this.templateBindingObserver.observe(this.source, this.context);
91
91
  this.refreshAllViews(true);
92
92
  }
93
+ else if (args[0].reset) {
94
+ this.refreshAllViews();
95
+ }
93
96
  else {
94
97
  this.updateViews(args);
95
98
  }
@@ -110,8 +113,8 @@ export class RepeatBehavior {
110
113
  }
111
114
  }
112
115
  updateViews(splices) {
113
- const childContext = this.childContext;
114
116
  const views = this.views;
117
+ const childContext = this.childContext;
115
118
  const totalRemoved = [];
116
119
  const bindView = this.bindView;
117
120
  let removeDelta = 0;
@@ -143,22 +146,20 @@ export class RepeatBehavior {
143
146
  }
144
147
  if (this.options.positioning) {
145
148
  for (let i = 0, ii = views.length; i < ii; ++i) {
146
- const currentContext = views[i].context;
147
- currentContext.length = ii;
148
- currentContext.index = i;
149
+ views[i].context.updatePosition(i, ii);
149
150
  }
150
151
  }
151
152
  }
152
153
  refreshAllViews(templateChanged = false) {
153
154
  const items = this.items;
154
- const childContext = this.childContext;
155
155
  const template = this.template;
156
156
  const location = this.location;
157
157
  const bindView = this.bindView;
158
+ const childContext = this.childContext;
158
159
  let itemsLength = items.length;
159
160
  let views = this.views;
160
161
  let viewsLength = views.length;
161
- if (itemsLength === 0 || templateChanged) {
162
+ if (itemsLength === 0 || templateChanged || !this.options.recycle) {
162
163
  // all views need to be removed
163
164
  HTMLView.disposeContiguousBatch(views);
164
165
  viewsLength = 0;
@@ -205,7 +206,7 @@ export class RepeatBehavior {
205
206
  * A directive that configures list rendering.
206
207
  * @public
207
208
  */
208
- export class RepeatDirective extends HTMLDirective {
209
+ export class RepeatDirective {
209
210
  /**
210
211
  * Creates an instance of RepeatDirective.
211
212
  * @param itemsBinding - The binding that provides the array to render.
@@ -213,27 +214,29 @@ export class RepeatDirective extends HTMLDirective {
213
214
  * @param options - Options used to turn on special repeat features.
214
215
  */
215
216
  constructor(itemsBinding, templateBinding, options) {
216
- super();
217
217
  this.itemsBinding = itemsBinding;
218
218
  this.templateBinding = templateBinding;
219
219
  this.options = options;
220
- /**
221
- * Creates a placeholder string based on the directive's index within the template.
222
- * @param index - The index of the directive within the template.
223
- */
224
- this.createPlaceholder = DOM.createBlockPlaceholder;
225
- enableArrayObservation();
220
+ ArrayObserver.enable();
226
221
  this.isItemsBindingVolatile = Observable.isVolatileBinding(itemsBinding);
227
222
  this.isTemplateBindingVolatile = Observable.isVolatileBinding(templateBinding);
228
223
  }
224
+ /**
225
+ * Creates a placeholder string based on the directive's index within the template.
226
+ * @param index - The index of the directive within the template.
227
+ */
228
+ createHTML(add) {
229
+ return Markup.comment(add(this));
230
+ }
229
231
  /**
230
232
  * Creates a behavior for the provided target node.
231
233
  * @param target - The node instance to create the behavior for.
232
234
  */
233
- createBehavior(target) {
234
- return new RepeatBehavior(target, this.itemsBinding, this.isItemsBindingVolatile, this.templateBinding, this.isTemplateBindingVolatile, this.options);
235
+ createBehavior(targets) {
236
+ return new RepeatBehavior(targets[this.nodeId], this.itemsBinding, this.isItemsBindingVolatile, this.templateBinding, this.isTemplateBindingVolatile, this.options);
235
237
  }
236
238
  }
239
+ HTMLDirective.define(RepeatDirective);
237
240
  /**
238
241
  * A directive that enables list rendering.
239
242
  * @param itemsBinding - The array to render.
@@ -243,7 +246,7 @@ export class RepeatDirective extends HTMLDirective {
243
246
  * @public
244
247
  */
245
248
  export function repeat(itemsBinding, templateOrTemplateBinding, options = defaultRepeatOptions) {
246
- const templateBinding = typeof templateOrTemplateBinding === "function"
249
+ const templateBinding = isFunction(templateOrTemplateBinding)
247
250
  ? templateOrTemplateBinding
248
251
  : () => templateOrTemplateBinding;
249
252
  return new RepeatDirective(itemsBinding, templateBinding, options);
@@ -1,37 +1,40 @@
1
- import { AttachedBehaviorHTMLDirective } from "./html-directive.js";
2
- import { NodeObservationBehavior } from "./node-observation.js";
1
+ import { isString } from "../interfaces.js";
2
+ import { HTMLDirective } from "./html-directive.js";
3
+ import { NodeObservationDirective } from "./node-observation.js";
4
+ const slotEvent = "slotchange";
3
5
  /**
4
6
  * The runtime behavior for slotted node observation.
5
7
  * @public
6
8
  */
7
- export class SlottedBehavior extends NodeObservationBehavior {
8
- /**
9
- * Creates an instance of SlottedBehavior.
10
- * @param target - The slot element target to observe.
11
- * @param options - The options to use when observing the slot.
12
- */
13
- constructor(target, options) {
14
- super(target, options);
15
- }
9
+ export class SlottedDirective extends NodeObservationDirective {
16
10
  /**
17
11
  * Begins observation of the nodes.
12
+ * @param target - The target to observe.
18
13
  */
19
- observe() {
20
- this.target.addEventListener("slotchange", this);
14
+ observe(target) {
15
+ target.addEventListener(slotEvent, this);
21
16
  }
22
17
  /**
23
18
  * Disconnects observation of the nodes.
19
+ * @param target - The target to unobserve.
24
20
  */
25
- disconnect() {
26
- this.target.removeEventListener("slotchange", this);
21
+ disconnect(target) {
22
+ target.removeEventListener(slotEvent, this);
27
23
  }
28
24
  /**
29
- * Retrieves the nodes that should be assigned to the target.
25
+ * Retrieves the raw nodes that should be assigned to the source property.
26
+ * @param target - The target to get the node to.
30
27
  */
31
- getNodes() {
32
- return this.target.assignedNodes(this.options);
28
+ getNodes(target) {
29
+ return target.assignedNodes(this.options);
30
+ }
31
+ /** @internal */
32
+ handleEvent(event) {
33
+ const target = event.currentTarget;
34
+ this.updateTarget(this.getSource(target), this.computeNodes(target));
33
35
  }
34
36
  }
37
+ HTMLDirective.define(SlottedDirective);
35
38
  /**
36
39
  * A directive that observes the `assignedNodes()` of a slot and updates a property
37
40
  * whenever they change.
@@ -39,8 +42,8 @@ export class SlottedBehavior extends NodeObservationBehavior {
39
42
  * @public
40
43
  */
41
44
  export function slotted(propertyOrOptions) {
42
- if (typeof propertyOrOptions === "string") {
45
+ if (isString(propertyOrOptions)) {
43
46
  propertyOrOptions = { property: propertyOrOptions };
44
47
  }
45
- return new AttachedBehaviorHTMLDirective("fast-slotted", SlottedBehavior, propertyOrOptions);
48
+ return new SlottedDirective(propertyOrOptions);
46
49
  }