@microsoft/fast-element 2.0.0-beta.1 → 2.0.0-beta.2

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 (37) hide show
  1. package/CHANGELOG.json +51 -0
  2. package/CHANGELOG.md +15 -1
  3. package/dist/dts/components/fast-definitions.d.ts +2 -0
  4. package/dist/dts/components/fast-element.d.ts +7 -1
  5. package/dist/dts/context.d.ts +157 -0
  6. package/dist/dts/metadata.d.ts +25 -0
  7. package/dist/dts/observation/arrays.d.ts +1 -1
  8. package/dist/dts/observation/behavior.d.ts +4 -4
  9. package/dist/dts/observation/observable.d.ts +43 -62
  10. package/dist/dts/templating/binding-signal.d.ts +38 -0
  11. package/dist/dts/templating/binding-two-way.d.ts +56 -0
  12. package/dist/dts/templating/binding.d.ts +0 -88
  13. package/dist/dts/templating/compiler.d.ts +1 -2
  14. package/dist/dts/templating/repeat.d.ts +3 -49
  15. package/dist/dts/templating/template.d.ts +10 -59
  16. package/dist/dts/templating/view.d.ts +9 -9
  17. package/dist/{tsdoc-metadata.json → dts/tsdoc-metadata.json} +0 -0
  18. package/dist/esm/components/fast-definitions.js +2 -0
  19. package/dist/esm/components/fast-element.js +10 -2
  20. package/dist/esm/context.js +159 -0
  21. package/dist/esm/metadata.js +60 -0
  22. package/dist/esm/observation/arrays.js +1 -1
  23. package/dist/esm/observation/observable.js +69 -17
  24. package/dist/esm/templating/binding-signal.js +84 -0
  25. package/dist/esm/templating/binding-two-way.js +76 -0
  26. package/dist/esm/templating/binding.js +1 -158
  27. package/dist/esm/templating/repeat.js +9 -1
  28. package/dist/esm/templating/template.js +1 -21
  29. package/dist/fast-element.api.json +5586 -7541
  30. package/dist/fast-element.d.ts +119 -329
  31. package/dist/fast-element.debug.js +92 -199
  32. package/dist/fast-element.debug.min.js +1 -1
  33. package/dist/fast-element.js +92 -199
  34. package/dist/fast-element.min.js +1 -1
  35. package/dist/fast-element.untrimmed.d.ts +120 -331
  36. package/docs/api-report.md +50 -156
  37. package/package.json +20 -4
@@ -272,72 +272,124 @@ const contextEvent = FAST.getById(3 /* KernelServiceId.contextEvent */, () => {
272
272
  },
273
273
  };
274
274
  });
275
- class DefaultExecutionContext {
275
+ /**
276
+ * Provides additional contextual information available to behaviors and expressions.
277
+ * @public
278
+ */
279
+ export class ExecutionContext {
276
280
  constructor(parentSource = null, parentContext = null) {
281
+ /**
282
+ * The index of the current item within a repeat context.
283
+ */
277
284
  this.index = 0;
285
+ /**
286
+ * The length of the current collection within a repeat context.
287
+ */
278
288
  this.length = 0;
279
289
  this.parent = parentSource;
280
290
  this.parentContext = parentContext;
281
291
  }
292
+ /**
293
+ * The current event within an event handler.
294
+ */
282
295
  get event() {
283
296
  return contextEvent.get();
284
297
  }
298
+ /**
299
+ * Indicates whether the current item within a repeat context
300
+ * has an even index.
301
+ */
285
302
  get isEven() {
286
303
  return this.index % 2 === 0;
287
304
  }
305
+ /**
306
+ * Indicates whether the current item within a repeat context
307
+ * has an odd index.
308
+ */
288
309
  get isOdd() {
289
310
  return this.index % 2 !== 0;
290
311
  }
312
+ /**
313
+ * Indicates whether the current item within a repeat context
314
+ * is the first item in the collection.
315
+ */
291
316
  get isFirst() {
292
317
  return this.index === 0;
293
318
  }
319
+ /**
320
+ * Indicates whether the current item within a repeat context
321
+ * is somewhere in the middle of the collection.
322
+ */
294
323
  get isInMiddle() {
295
324
  return !this.isFirst && !this.isLast;
296
325
  }
326
+ /**
327
+ * Indicates whether the current item within a repeat context
328
+ * is the last item in the collection.
329
+ */
297
330
  get isLast() {
298
331
  return this.index === this.length - 1;
299
332
  }
333
+ /**
334
+ * Returns the typed event detail of a custom event.
335
+ */
300
336
  eventDetail() {
301
337
  return this.event.detail;
302
338
  }
339
+ /**
340
+ * Returns the typed event target of the event.
341
+ */
303
342
  eventTarget() {
304
343
  return this.event.target;
305
344
  }
345
+ /**
346
+ * Updates the position/size on a context associated with a list item.
347
+ * @param index - The new index of the item.
348
+ * @param length - The new length of the list.
349
+ */
306
350
  updatePosition(index, length) {
307
351
  this.index = index;
308
352
  this.length = length;
309
353
  }
354
+ /**
355
+ * Creates a new execution context descendent from the current context.
356
+ * @param source - The source for the context if different than the parent.
357
+ * @returns A child execution context.
358
+ */
310
359
  createChildContext(parentSource) {
311
- return new DefaultExecutionContext(parentSource, this);
360
+ return new ExecutionContext(parentSource, this);
312
361
  }
362
+ /**
363
+ * Creates a new execution context descent suitable for use in list rendering.
364
+ * @param item - The list item to serve as the source.
365
+ * @param index - The index of the item in the list.
366
+ * @param length - The length of the list.
367
+ */
313
368
  createItemContext(index, length) {
314
369
  const childContext = Object.create(this);
315
370
  childContext.index = index;
316
371
  childContext.length = length;
317
372
  return childContext;
318
373
  }
319
- }
320
- Observable.defineProperty(DefaultExecutionContext.prototype, "index");
321
- Observable.defineProperty(DefaultExecutionContext.prototype, "length");
322
- /**
323
- * The common execution context APIs.
324
- * @public
325
- */
326
- export const ExecutionContext = Object.freeze({
327
- default: new DefaultExecutionContext(),
328
374
  /**
329
375
  * Sets the event for the current execution context.
330
376
  * @param event - The event to set.
331
377
  * @internal
332
378
  */
333
- setEvent(event) {
379
+ static setEvent(event) {
334
380
  contextEvent.set(event);
335
- },
381
+ }
336
382
  /**
337
383
  * Creates a new root execution context.
338
384
  * @returns A new execution context.
339
385
  */
340
- create() {
341
- return new DefaultExecutionContext();
342
- },
343
- });
386
+ static create() {
387
+ return new ExecutionContext();
388
+ }
389
+ }
390
+ /**
391
+ * The default execution context.
392
+ */
393
+ ExecutionContext.default = new ExecutionContext();
394
+ Observable.defineProperty(ExecutionContext.prototype, "index");
395
+ Observable.defineProperty(ExecutionContext.prototype, "length");
@@ -0,0 +1,84 @@
1
+ import { isString } from "../interfaces.js";
2
+ import { BindingMode, UpdateBinding } from "./binding.js";
3
+ const signals = Object.create(null);
4
+ /**
5
+ * A binding behavior for signal bindings.
6
+ * @public
7
+ */
8
+ export class SignalBinding extends UpdateBinding {
9
+ constructor() {
10
+ super(...arguments);
11
+ this.handlerProperty = `${this.directive.id}-h`;
12
+ }
13
+ /**
14
+ * Bind this behavior to the source.
15
+ * @param source - The source to bind to.
16
+ * @param context - The execution context that the binding is operating within.
17
+ * @param targets - The targets that behaviors in a view can attach to.
18
+ */
19
+ bind(source, context, targets) {
20
+ const directive = this.directive;
21
+ const target = targets[directive.nodeId];
22
+ const signal = this.getSignal(source, context);
23
+ const handler = (target[this.handlerProperty] = () => {
24
+ this.updateTarget(target, directive.targetAspect, directive.binding(source, context), source, context);
25
+ });
26
+ handler();
27
+ const found = signals[signal];
28
+ if (found) {
29
+ Array.isArray(found)
30
+ ? found.push(handler)
31
+ : (signals[signal] = [found, handler]);
32
+ }
33
+ else {
34
+ signals[signal] = handler;
35
+ }
36
+ }
37
+ /**
38
+ * Unbinds this behavior from the source.
39
+ * @param source - The source to unbind from.
40
+ * @param context - The execution context that the binding is operating within.
41
+ * @param targets - The targets that behaviors in a view can attach to.
42
+ */
43
+ unbind(source, context, targets) {
44
+ const signal = this.getSignal(source, context);
45
+ const found = signals[signal];
46
+ if (found && Array.isArray(found)) {
47
+ const directive = this.directive;
48
+ const target = targets[directive.nodeId];
49
+ const handler = target[this.handlerProperty];
50
+ const index = found.indexOf(handler);
51
+ if (index !== -1) {
52
+ found.splice(index, 1);
53
+ }
54
+ }
55
+ else {
56
+ signals[signal] = void 0;
57
+ }
58
+ }
59
+ getSignal(source, context) {
60
+ const options = this.directive.options;
61
+ return isString(options) ? options : options(source, context);
62
+ }
63
+ /**
64
+ * Sends the specified signal to signaled bindings.
65
+ * @param signal - The signal to send.
66
+ * @public
67
+ */
68
+ static send(signal) {
69
+ const found = signals[signal];
70
+ if (found) {
71
+ Array.isArray(found) ? found.forEach(x => x()) : found();
72
+ }
73
+ }
74
+ }
75
+ const signalMode = BindingMode.define(SignalBinding);
76
+ /**
77
+ * Creates a signal binding configuration with the supplied options.
78
+ * @param options - The signal name or a binding to use to retrieve the signal name.
79
+ * @returns A binding configuration.
80
+ * @public
81
+ */
82
+ export const signal = (options) => {
83
+ return { mode: signalMode, options };
84
+ };
@@ -0,0 +1,76 @@
1
+ import { BindingConfig, BindingMode, ChangeBinding, } from "./binding.js";
2
+ let twoWaySettings = {
3
+ determineChangeEvent() {
4
+ return "change";
5
+ },
6
+ };
7
+ /**
8
+ * A binding behavior for bindings that update in two directions.
9
+ * @public
10
+ */
11
+ export class TwoWayBinding extends ChangeBinding {
12
+ /**
13
+ * Bind this behavior to the source.
14
+ * @param source - The source to bind to.
15
+ * @param context - The execution context that the binding is operating within.
16
+ * @param targets - The targets that behaviors in a view can attach to.
17
+ */
18
+ bind(source, context, targets) {
19
+ var _a;
20
+ super.bind(source, context, targets);
21
+ const directive = this.directive;
22
+ const target = targets[directive.nodeId];
23
+ if (!this.changeEvent) {
24
+ this.changeEvent =
25
+ (_a = directive.options.changeEvent) !== null && _a !== void 0 ? _a : twoWaySettings.determineChangeEvent(directive, target);
26
+ }
27
+ target.addEventListener(this.changeEvent, this);
28
+ }
29
+ /**
30
+ * Unbinds this behavior from the source.
31
+ * @param source - The source to unbind from.
32
+ * @param context - The execution context that the binding is operating within.
33
+ * @param targets - The targets that behaviors in a view can attach to.
34
+ */
35
+ unbind(source, context, targets) {
36
+ super.unbind(source, context, targets);
37
+ targets[this.directive.nodeId].removeEventListener(this.changeEvent, this);
38
+ }
39
+ /** @internal */
40
+ handleEvent(event) {
41
+ const directive = this.directive;
42
+ const target = event.currentTarget;
43
+ let value;
44
+ switch (directive.aspectType) {
45
+ case 1:
46
+ value = target.getAttribute(directive.targetAspect);
47
+ break;
48
+ case 2:
49
+ value = target.hasAttribute(directive.targetAspect);
50
+ break;
51
+ case 4:
52
+ value = target.innerText;
53
+ break;
54
+ default:
55
+ value = target[directive.targetAspect];
56
+ break;
57
+ }
58
+ const observer = this.getObserver(target);
59
+ const last = observer.last; // using internal API!!!
60
+ last.propertySource[last.propertyName] = directive.options.fromView(value);
61
+ }
62
+ /**
63
+ * Configures two-way binding.
64
+ * @param settings - The settings to use for the two-way binding system.
65
+ */
66
+ static configure(settings) {
67
+ twoWaySettings = settings;
68
+ }
69
+ }
70
+ /**
71
+ * The default twoWay binding configuration.
72
+ * @public
73
+ */
74
+ export const twoWay = BindingConfig.define(BindingMode.define(TwoWayBinding), {
75
+ fromView: v => v,
76
+ });
@@ -1,4 +1,4 @@
1
- import { isString } from "../interfaces.js";
1
+ import "../interfaces.js";
2
2
  import { ExecutionContext, Observable, } from "../observation/observable.js";
3
3
  import { FAST } from "../platform.js";
4
4
  import { DOM } from "./dom.js";
@@ -215,78 +215,6 @@ export class OneTimeBinding extends UpdateBinding {
215
215
  this.updateTarget(targets[directive.nodeId], directive.targetAspect, directive.binding(source, context), source, context);
216
216
  }
217
217
  }
218
- const signals = Object.create(null);
219
- /**
220
- * A binding behavior for signal bindings.
221
- * @public
222
- */
223
- export class SignalBinding extends UpdateBinding {
224
- constructor() {
225
- super(...arguments);
226
- this.handlerProperty = `${this.directive.id}-h`;
227
- }
228
- /**
229
- * Bind this behavior to the source.
230
- * @param source - The source to bind to.
231
- * @param context - The execution context that the binding is operating within.
232
- * @param targets - The targets that behaviors in a view can attach to.
233
- */
234
- bind(source, context, targets) {
235
- const directive = this.directive;
236
- const target = targets[directive.nodeId];
237
- const signal = this.getSignal(source, context);
238
- const handler = (target[this.handlerProperty] = () => {
239
- this.updateTarget(target, directive.targetAspect, directive.binding(source, context), source, context);
240
- });
241
- handler();
242
- const found = signals[signal];
243
- if (found) {
244
- Array.isArray(found)
245
- ? found.push(handler)
246
- : (signals[signal] = [found, handler]);
247
- }
248
- else {
249
- signals[signal] = handler;
250
- }
251
- }
252
- /**
253
- * Unbinds this behavior from the source.
254
- * @param source - The source to unbind from.
255
- * @param context - The execution context that the binding is operating within.
256
- * @param targets - The targets that behaviors in a view can attach to.
257
- */
258
- unbind(source, context, targets) {
259
- const signal = this.getSignal(source, context);
260
- const found = signals[signal];
261
- if (found && Array.isArray(found)) {
262
- const directive = this.directive;
263
- const target = targets[directive.nodeId];
264
- const handler = target[this.handlerProperty];
265
- const index = found.indexOf(handler);
266
- if (index !== -1) {
267
- found.splice(index, 1);
268
- }
269
- }
270
- else {
271
- signals[signal] = void 0;
272
- }
273
- }
274
- getSignal(source, context) {
275
- const options = this.directive.options;
276
- return isString(options) ? options : options(source, context);
277
- }
278
- /**
279
- * Sends the specified signal to signaled bindings.
280
- * @param signal - The signal to send.
281
- * @public
282
- */
283
- static send(signal) {
284
- const found = signals[signal];
285
- if (found) {
286
- Array.isArray(found) ? found.forEach(x => x()) : found();
287
- }
288
- }
289
- }
290
218
  /**
291
219
  * A binding behavior for bindings that change.
292
220
  * @public
@@ -407,86 +335,11 @@ export class EventBinding {
407
335
  }
408
336
  }
409
337
  }
410
- let twoWaySettings = {
411
- determineChangeEvent() {
412
- return "change";
413
- },
414
- };
415
- /**
416
- * A binding behavior for bindings that update in two directions.
417
- * @public
418
- */
419
- export class TwoWayBinding extends ChangeBinding {
420
- /**
421
- * Bind this behavior to the source.
422
- * @param source - The source to bind to.
423
- * @param context - The execution context that the binding is operating within.
424
- * @param targets - The targets that behaviors in a view can attach to.
425
- */
426
- bind(source, context, targets) {
427
- var _a;
428
- super.bind(source, context, targets);
429
- const directive = this.directive;
430
- const target = targets[directive.nodeId];
431
- if (!this.changeEvent) {
432
- this.changeEvent =
433
- (_a = directive.options.changeEvent) !== null && _a !== void 0 ? _a : twoWaySettings.determineChangeEvent(directive, target);
434
- }
435
- target.addEventListener(this.changeEvent, this);
436
- }
437
- /**
438
- * Unbinds this behavior from the source.
439
- * @param source - The source to unbind from.
440
- * @param context - The execution context that the binding is operating within.
441
- * @param targets - The targets that behaviors in a view can attach to.
442
- */
443
- unbind(source, context, targets) {
444
- super.unbind(source, context, targets);
445
- targets[this.directive.nodeId].removeEventListener(this.changeEvent, this);
446
- }
447
- /** @internal */
448
- handleEvent(event) {
449
- const directive = this.directive;
450
- const target = event.currentTarget;
451
- let value;
452
- switch (directive.aspectType) {
453
- case 1:
454
- value = target.getAttribute(directive.targetAspect);
455
- break;
456
- case 2:
457
- value = target.hasAttribute(directive.targetAspect);
458
- break;
459
- case 4:
460
- value = target.innerText;
461
- break;
462
- default:
463
- value = target[directive.targetAspect];
464
- break;
465
- }
466
- const observer = this.getObserver(target);
467
- const last = observer.last; // using internal API!!!
468
- last.propertySource[last.propertyName] = directive.options.fromView(value);
469
- }
470
- /**
471
- * Configures two-way binding.
472
- * @param settings - The settings to use for the two-way binding system.
473
- */
474
- static configure(settings) {
475
- twoWaySettings = settings;
476
- }
477
- }
478
338
  /**
479
339
  * The default onChange binding configuration.
480
340
  * @public
481
341
  */
482
342
  export const onChange = BindingConfig.define(BindingMode.define(ChangeBinding), {});
483
- /**
484
- * The default twoWay binding configuration.
485
- * @public
486
- */
487
- export const twoWay = BindingConfig.define(BindingMode.define(TwoWayBinding), {
488
- fromView: v => v,
489
- });
490
343
  /**
491
344
  * The default onTime binding configuration.
492
345
  * @public
@@ -494,16 +347,6 @@ export const twoWay = BindingConfig.define(BindingMode.define(TwoWayBinding), {
494
347
  export const oneTime = BindingConfig.define(BindingMode.define(OneTimeBinding), {
495
348
  once: true,
496
349
  });
497
- const signalMode = BindingMode.define(SignalBinding);
498
- /**
499
- * Creates a signal binding configuration with the supplied options.
500
- * @param options - The signal name or a binding to use to retrieve the signal name.
501
- * @returns A binding configuration.
502
- * @public
503
- */
504
- export const signal = (options) => {
505
- return { mode: signalMode, options };
506
- };
507
350
  /**
508
351
  * A directive that applies bindings.
509
352
  * @public
@@ -159,7 +159,7 @@ export class RepeatBehavior {
159
159
  let itemsLength = items.length;
160
160
  let views = this.views;
161
161
  let viewsLength = views.length;
162
- if (itemsLength === 0 || templateChanged) {
162
+ if (itemsLength === 0 || templateChanged || !this.options.recycle) {
163
163
  // all views need to be removed
164
164
  HTMLView.disposeContiguousBatch(views);
165
165
  viewsLength = 0;
@@ -237,6 +237,14 @@ export class RepeatDirective {
237
237
  }
238
238
  }
239
239
  HTMLDirective.define(RepeatDirective);
240
+ /**
241
+ * A directive that enables list rendering.
242
+ * @param itemsBinding - The array to render.
243
+ * @param templateOrTemplateBinding - The template or a template binding used obtain a template
244
+ * to render for each item in the array.
245
+ * @param options - Options used to turn on special repeat features.
246
+ * @public
247
+ */
240
248
  export function repeat(itemsBinding, templateOrTemplateBinding, options = defaultRepeatOptions) {
241
249
  const templateBinding = isFunction(templateOrTemplateBinding)
242
250
  ? templateOrTemplateBinding
@@ -1,5 +1,5 @@
1
1
  import { isFunction, isString } from "../interfaces.js";
2
- import { ExecutionContext, } from "../observation/observable.js";
2
+ import { ExecutionContext } from "../observation/observable.js";
3
3
  import { bind, oneTime } from "./binding.js";
4
4
  import { Compiler } from "./compiler.js";
5
5
  import { Aspect, HTMLDirective, } from "./html-directive.js";
@@ -105,23 +105,3 @@ export function html(strings, ...values) {
105
105
  }
106
106
  return new ViewTemplate(html + strings[strings.length - 1], factories);
107
107
  }
108
- /**
109
- * Transforms a template literal string into a ChildViewTemplate.
110
- * @param strings - The string fragments that are interpolated with the values.
111
- * @param values - The values that are interpolated with the string fragments.
112
- * @remarks
113
- * The html helper supports interpolation of strings, numbers, binding expressions,
114
- * other template instances, and Directive instances.
115
- * @public
116
- */
117
- export const child = html;
118
- /**
119
- * Transforms a template literal string into an ItemViewTemplate.
120
- * @param strings - The string fragments that are interpolated with the values.
121
- * @param values - The values that are interpolated with the string fragments.
122
- * @remarks
123
- * The html helper supports interpolation of strings, numbers, binding expressions,
124
- * other template instances, and Directive instances.
125
- * @public
126
- */
127
- export const item = html;