@a2ui/angular 0.9.1 → 0.10.0

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.
@@ -25,8 +25,8 @@ class MessageProcessor {
25
25
  baseProcessor;
26
26
  eventsSubject = new Subject();
27
27
  events = this.eventsSubject.asObservable();
28
- // Signal to track the version of the data in the MessageProcessor. Since the base processor updates
29
- // surfaces in-place (mutating the Map), we use this to force Angular's change detection to
28
+ // Signal to track the version of the data in the MessageProcessor. Since the base processor updates
29
+ // surfaces in-place (mutating the Map), we use this to force Angular's change detection to
30
30
  // re-evaluate any components or effects that depend on getSurfaces().
31
31
  versionSignal = signal(0, ...(ngDevMode ? [{ debugName: "versionSignal" }] : /* istanbul ignore next */ []));
32
32
  version = this.versionSignal.asReadonly();
@@ -38,7 +38,7 @@ class MessageProcessor {
38
38
  * This should be called after any update to the underlying base processor's surfaces.
39
39
  */
40
40
  notify() {
41
- this.versionSignal.update((v) => v + 1);
41
+ this.versionSignal.update(v => v + 1);
42
42
  }
43
43
  processMessages(messages) {
44
44
  this.baseProcessor.processMessages(messages);
@@ -48,8 +48,8 @@ class MessageProcessor {
48
48
  const completion = new Subject();
49
49
  const promise = new Promise((resolve, reject) => {
50
50
  completion.subscribe({
51
- next: (msgs) => resolve(msgs),
52
- error: (err) => reject(err),
51
+ next: msgs => resolve(msgs),
52
+ error: err => reject(err),
53
53
  });
54
54
  });
55
55
  this.eventsSubject.next({ message, completion });
@@ -141,7 +141,7 @@ class DefaultMarkdownRenderer extends MarkdownRenderer {
141
141
  }
142
142
  catch (e) {
143
143
  if (!DefaultMarkdownRenderer.warningLogged) {
144
- console.warn("[DefaultMarkdownRenderer] Failed to load optional `@a2ui/markdown-it` renderer. Using fallback regex.");
144
+ console.warn('[DefaultMarkdownRenderer] Failed to load optional `@a2ui/markdown-it` renderer. Using fallback regex.');
145
145
  DefaultMarkdownRenderer.warningLogged = true;
146
146
  }
147
147
  // Basic implementation for v0.8
@@ -409,8 +409,8 @@ class Renderer {
409
409
  Renderer.hasInsertedStyles = true;
410
410
  }
411
411
  effect(() => {
412
- // Explicitly depend on the MessageProcessor's version signal. This ensures that the effect re-runs
413
- // whenever data model changes occur, even if the node's object reference remains identical
412
+ // Explicitly depend on the MessageProcessor's version signal. This ensures that the effect re-runs
413
+ // whenever data model changes occur, even if the node's object reference remains identical
414
414
  // (as in the case of in-place mutations from local updates).
415
415
  this.processor.version();
416
416
  let node = this.component();
@@ -431,7 +431,7 @@ class Renderer {
431
431
  const type = node.type;
432
432
  // Focus Loss Prevention:
433
433
  // If we have an existing component and its unique identity (ID and Type) hasn't changed,
434
- // we update its @Input() values in-place. This preserves the underlying DOM element,
434
+ // we update its @Input() values in-place. This preserves the underlying DOM element,
435
435
  // maintaining focus, text selection, and cursor position.
436
436
  if (this.currentComponentRef && this.currentId === id && this.currentType === type) {
437
437
  this.updateInputs(this.currentComponentRef, node, surfaceId);
@@ -454,7 +454,7 @@ class Renderer {
454
454
  render(container, node, surfaceId, config) {
455
455
  const componentTypeOrPromise = this.resolveComponentType(config);
456
456
  if (componentTypeOrPromise instanceof Promise) {
457
- componentTypeOrPromise.then((componentType) => {
457
+ componentTypeOrPromise.then(componentType => {
458
458
  // Ensure we are still supposed to render this component
459
459
  if (this.currentId === node.id && this.currentType === node.type) {
460
460
  const componentRef = container.createComponent(componentType);
@@ -491,13 +491,15 @@ class Renderer {
491
491
  componentRef.setInput('surfaceId', surfaceId);
492
492
  componentRef.setInput('component', node);
493
493
  componentRef.setInput('weight', node.weight ?? 0);
494
- const props = node.properties;
495
- for (const [key, value] of Object.entries(props)) {
496
- try {
497
- componentRef.setInput(key, value);
498
- }
499
- catch (e) {
500
- console.warn(`[Renderer] Property "${key}" could not be set on component ${node.type}. If this property is required by the specification, ensure the component declares it as an input.`);
494
+ if (node.properties) {
495
+ const props = node.properties;
496
+ for (const [key, value] of Object.entries(props)) {
497
+ try {
498
+ componentRef.setInput(key, value);
499
+ }
500
+ catch (e) {
501
+ console.warn(`[Renderer] Property "${key}" could not be set on component ${node.type}. If this property is required by the specification, ensure the component declares it as an input.`);
502
+ }
501
503
  }
502
504
  }
503
505
  componentRef.changeDetectorRef.markForCheck();
@@ -638,22 +640,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
638
640
  */
639
641
  class Checkbox extends DynamicComponent {
640
642
  label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
641
- checked = input.required(...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
642
- inputChecked = computed(() => super.resolvePrimitive(this.checked()) ?? false, ...(ngDevMode ? [{ debugName: "inputChecked" }] : /* istanbul ignore next */ []));
643
+ value = input.required(...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
644
+ inputChecked = computed(() => super.resolvePrimitive(this.value()) ?? false, ...(ngDevMode ? [{ debugName: "inputChecked" }] : /* istanbul ignore next */ []));
643
645
  resolvedLabel = computed(() => super.resolvePrimitive(this.label()), ...(ngDevMode ? [{ debugName: "resolvedLabel" }] : /* istanbul ignore next */ []));
644
646
  inputId = super.getUniqueId('a2ui-checkbox');
645
647
  onToggle(event) {
646
648
  const checked = event.target.checked;
647
- const checkedNode = this.checked();
648
- if (checkedNode && typeof checkedNode === 'object' && 'path' in checkedNode && checkedNode.path) {
649
+ const checkedNode = this.value();
650
+ if (checkedNode &&
651
+ typeof checkedNode === 'object' &&
652
+ 'path' in checkedNode &&
653
+ checkedNode.path) {
649
654
  // Update the local data model directly to ensure immediate UI feedback and avoid unnecessary network requests.
650
- this.processor.processMessages([{
655
+ this.processor.processMessages([
656
+ {
651
657
  dataModelUpdate: {
652
658
  surfaceId: this.surfaceId(),
653
659
  path: this.processor.resolvePath(checkedNode.path, this.component().dataContextPath),
654
660
  contents: [{ key: '.', valueBoolean: checked }],
655
661
  },
656
- }]);
662
+ },
663
+ ]);
657
664
  }
658
665
  else {
659
666
  this.sendAction({
@@ -663,7 +670,7 @@ class Checkbox extends DynamicComponent {
663
670
  }
664
671
  }
665
672
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: Checkbox, deps: null, target: i0.ɵɵFactoryTarget.Component });
666
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: Checkbox, isStandalone: true, selector: "a2ui-checkbox", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
673
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: Checkbox, isStandalone: true, selector: "a2ui-checkbox", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
667
674
  <label>
668
675
  <input
669
676
  type="checkbox"
@@ -688,7 +695,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
688
695
  {{ resolvedLabel() }}
689
696
  </label>
690
697
  `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:flex;align-items:center;gap:.5rem}\n"] }]
691
- }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: true }] }] } });
698
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }] } });
692
699
 
693
700
  /*
694
701
  * Copyright 2025 Google LLC
@@ -773,13 +780,15 @@ class DateTimeInput extends DynamicComponent {
773
780
  const valueNode = this.value();
774
781
  if (valueNode && typeof valueNode === 'object' && 'path' in valueNode && valueNode.path) {
775
782
  // Update the local data model directly to ensure immediate UI feedback and avoid unnecessary network requests.
776
- this.processor.processMessages([{
783
+ this.processor.processMessages([
784
+ {
777
785
  dataModelUpdate: {
778
786
  surfaceId: this.surfaceId(),
779
787
  path: this.processor.resolvePath(valueNode.path, this.component().dataContextPath),
780
788
  contents: [{ key: '.', valueString: value }],
781
789
  },
782
- }]);
790
+ },
791
+ ]);
783
792
  }
784
793
  else {
785
794
  this.handleAction('change', { value });
@@ -1033,11 +1042,7 @@ class Modal extends DynamicComponent {
1033
1042
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: Modal, isStandalone: true, selector: "a2ui-modal", inputs: { entryPointChild: { classPropertyName: "entryPointChild", publicName: "entryPointChild", isSignal: true, isRequired: true, transformFunction: null }, contentChild: { classPropertyName: "contentChild", publicName: "contentChild", isSignal: true, isRequired: true, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
1034
1043
  <div class="a2ui-modal-entry-point" (click)="openModal()">
1035
1044
  @if (entryPointChild()) {
1036
- <ng-container
1037
- a2ui-renderer
1038
- [surfaceId]="surfaceId()!"
1039
- [component]="entryPointChild()!"
1040
- />
1045
+ <ng-container a2ui-renderer [surfaceId]="surfaceId()!" [component]="entryPointChild()!" />
1041
1046
  }
1042
1047
  </div>
1043
1048
 
@@ -1045,11 +1050,7 @@ class Modal extends DynamicComponent {
1045
1050
  <div [class]="theme.components.Modal.backdrop" (click)="closeModal()">
1046
1051
  <div [class]="theme.components.Modal.element" (click)="$event.stopPropagation()">
1047
1052
  @if (contentChild()) {
1048
- <ng-container
1049
- a2ui-renderer
1050
- [surfaceId]="surfaceId()!"
1051
- [component]="contentChild()!"
1052
- />
1053
+ <ng-container a2ui-renderer [surfaceId]="surfaceId()!" [component]="contentChild()!" />
1053
1054
  }
1054
1055
  </div>
1055
1056
  </div>
@@ -1061,11 +1062,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
1061
1062
  args: [{ selector: 'a2ui-modal', imports: [Renderer], template: `
1062
1063
  <div class="a2ui-modal-entry-point" (click)="openModal()">
1063
1064
  @if (entryPointChild()) {
1064
- <ng-container
1065
- a2ui-renderer
1066
- [surfaceId]="surfaceId()!"
1067
- [component]="entryPointChild()!"
1068
- />
1065
+ <ng-container a2ui-renderer [surfaceId]="surfaceId()!" [component]="entryPointChild()!" />
1069
1066
  }
1070
1067
  </div>
1071
1068
 
@@ -1073,11 +1070,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
1073
1070
  <div [class]="theme.components.Modal.backdrop" (click)="closeModal()">
1074
1071
  <div [class]="theme.components.Modal.element" (click)="$event.stopPropagation()">
1075
1072
  @if (contentChild()) {
1076
- <ng-container
1077
- a2ui-renderer
1078
- [surfaceId]="surfaceId()!"
1079
- [component]="contentChild()!"
1080
- />
1073
+ <ng-container a2ui-renderer [surfaceId]="surfaceId()!" [component]="contentChild()!" />
1081
1074
  }
1082
1075
  </div>
1083
1076
  </div>
@@ -1106,7 +1099,7 @@ class MultipleChoice extends DynamicComponent {
1106
1099
  selections = input.required(...(ngDevMode ? [{ debugName: "selections" }] : /* istanbul ignore next */ []));
1107
1100
  selectId = super.getUniqueId('a2ui-multiple-choice');
1108
1101
  resolvedLabel = computed(() => this.resolvePrimitive(this.label()), ...(ngDevMode ? [{ debugName: "resolvedLabel" }] : /* istanbul ignore next */ []));
1109
- resolvedOptions = computed(() => this.options().map((opt) => ({
1102
+ resolvedOptions = computed(() => this.options().map(opt => ({
1110
1103
  label: this.resolvePrimitive(opt.label),
1111
1104
  value: opt.value,
1112
1105
  })), ...(ngDevMode ? [{ debugName: "resolvedOptions" }] : /* istanbul ignore next */ []));
@@ -1120,15 +1113,20 @@ class MultipleChoice extends DynamicComponent {
1120
1113
  onChange(event) {
1121
1114
  const value = event.target.value;
1122
1115
  const selectionsNode = this.selections();
1123
- if (selectionsNode && typeof selectionsNode === 'object' && 'path' in selectionsNode && selectionsNode.path) {
1116
+ if (selectionsNode &&
1117
+ typeof selectionsNode === 'object' &&
1118
+ 'path' in selectionsNode &&
1119
+ selectionsNode.path) {
1124
1120
  // Update the local data model directly to ensure immediate UI feedback and avoid unnecessary network requests.
1125
- this.processor.processMessages([{
1121
+ this.processor.processMessages([
1122
+ {
1126
1123
  dataModelUpdate: {
1127
1124
  surfaceId: this.surfaceId(),
1128
1125
  path: this.processor.resolvePath(selectionsNode.path, this.component().dataContextPath),
1129
1126
  contents: [{ key: '.', valueString: JSON.stringify({ literalArray: [value] }) }],
1130
1127
  },
1131
- }]);
1128
+ },
1129
+ ]);
1132
1130
  }
1133
1131
  else {
1134
1132
  this.handleAction('change', { value });
@@ -1269,13 +1267,15 @@ class Slider extends DynamicComponent {
1269
1267
  const valueNode = this.value();
1270
1268
  if (valueNode && typeof valueNode === 'object' && 'path' in valueNode && valueNode.path) {
1271
1269
  // Update the local data model directly to ensure immediate UI feedback and avoid unnecessary network requests.
1272
- this.processor.processMessages([{
1270
+ this.processor.processMessages([
1271
+ {
1273
1272
  dataModelUpdate: {
1274
1273
  surfaceId: this.surfaceId(),
1275
1274
  path: this.processor.resolvePath(valueNode.path, this.component().dataContextPath),
1276
1275
  contents: [{ key: '.', valueNumber: value }],
1277
1276
  },
1278
- }]);
1277
+ },
1278
+ ]);
1279
1279
  }
1280
1280
  else {
1281
1281
  this.handleAction('change', { value });
@@ -1300,7 +1300,7 @@ class Slider extends DynamicComponent {
1300
1300
  type="range"
1301
1301
  [class]="theme.components.Slider.element"
1302
1302
  [id]="inputId"
1303
- [attr.aria-labelledby]="labelId"
1303
+ [attr.aria-label]="resolvedLabel() ? resolvedLabel() : 'Slider'"
1304
1304
  [min]="minValue()"
1305
1305
  [max]="maxValue()"
1306
1306
  [value]="resolvedValue() ?? 0"
@@ -1320,7 +1320,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
1320
1320
  type="range"
1321
1321
  [class]="theme.components.Slider.element"
1322
1322
  [id]="inputId"
1323
- [attr.aria-labelledby]="labelId"
1323
+ [attr.aria-label]="resolvedLabel() ? resolvedLabel() : 'Slider'"
1324
1324
  [min]="minValue()"
1325
1325
  [max]="maxValue()"
1326
1326
  [value]="resolvedValue() ?? 0"
@@ -1471,7 +1471,7 @@ class Text extends DynamicComponent {
1471
1471
  return false;
1472
1472
  }
1473
1473
  const expected = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'caption', 'body'];
1474
- return expected.every((v) => v in styles);
1474
+ return expected.every(v => v in styles);
1475
1475
  }
1476
1476
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: Text, deps: null, target: i0.ɵɵFactoryTarget.Component });
1477
1477
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: Text, isStandalone: true, selector: "a2ui-text", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, usageHint: { classPropertyName: "usageHint", publicName: "usageHint", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
@@ -1530,13 +1530,15 @@ class TextField extends DynamicComponent {
1530
1530
  const textNode = this.text();
1531
1531
  if (textNode && typeof textNode === 'object' && 'path' in textNode && textNode.path) {
1532
1532
  // Update the local data model directly to ensure immediate UI feedback and avoid unnecessary network requests.
1533
- this.processor.processMessages([{
1533
+ this.processor.processMessages([
1534
+ {
1534
1535
  dataModelUpdate: {
1535
1536
  surfaceId: this.surfaceId(),
1536
1537
  path: this.processor.resolvePath(textNode.path, this.component().dataContextPath),
1537
1538
  contents: [{ key: '.', valueString: value }],
1538
1539
  },
1539
- }]);
1540
+ },
1541
+ ]);
1540
1542
  }
1541
1543
  else {
1542
1544
  this.handleAction('input', { value });
@@ -1773,6 +1775,10 @@ function provideA2UI(config) {
1773
1775
  * limitations under the License.
1774
1776
  */
1775
1777
 
1778
+ var types = /*#__PURE__*/Object.freeze({
1779
+ __proto__: null
1780
+ });
1781
+
1776
1782
  /**
1777
1783
  * Copyright 2026 Google LLC
1778
1784
  *
@@ -1793,5 +1799,5 @@ function provideA2UI(config) {
1793
1799
  * Generated bundle index. Do not edit.
1794
1800
  */
1795
1801
 
1796
- export { AudioPlayer, Button, Card, Catalog, Checkbox, Column, DEFAULT_CATALOG, DateTimeInput, Divider, DynamicComponent, Icon, Image, List, MessageProcessor, Modal, MultipleChoice, Renderer, Row, Slider, Surface, Tabs, Text, TextField, Theme, Video, provideA2UI, provideMarkdownRenderer, registerStandardComponents };
1802
+ export { AudioPlayer, Button, Card, Catalog, Checkbox, Column, DEFAULT_CATALOG, DateTimeInput, Divider, DynamicComponent, Icon, Image, List, MessageProcessor, Modal, MultipleChoice, Renderer, Row, Slider, Surface, Tabs, Text, TextField, Theme, types as Types, Video, provideA2UI, provideMarkdownRenderer, registerStandardComponents };
1797
1803
  //# sourceMappingURL=a2ui-angular-v0_8.mjs.map