@a2ui/angular 0.8.3 → 0.9.0-alpha.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.
- package/LICENSE +203 -0
- package/README.md +111 -3
- package/fesm2022/a2ui-angular-src-v0_8.mjs +1797 -0
- package/fesm2022/a2ui-angular-src-v0_8.mjs.map +1 -0
- package/fesm2022/a2ui-angular-src-v0_9.mjs +2330 -0
- package/fesm2022/a2ui-angular-src-v0_9.mjs.map +1 -0
- package/fesm2022/a2ui-angular-v0_8.mjs +1797 -0
- package/fesm2022/a2ui-angular-v0_8.mjs.map +1 -0
- package/fesm2022/a2ui-angular-v0_9.mjs +2330 -0
- package/fesm2022/a2ui-angular-v0_9.mjs.map +1 -0
- package/fesm2022/a2ui-angular.mjs +1558 -616
- package/fesm2022/a2ui-angular.mjs.map +1 -1
- package/package.json +51 -7
- package/types/a2ui-angular-src-v0_8.d.ts +400 -0
- package/types/a2ui-angular-src-v0_9.d.ts +813 -0
- package/types/a2ui-angular-v0_8.d.ts +400 -0
- package/types/a2ui-angular-v0_9.d.ts +813 -0
- package/types/a2ui-angular.d.ts +362 -35
- package/fesm2022/a2ui-angular-audio-DoZb9mn_.mjs +0 -48
- package/fesm2022/a2ui-angular-audio-DoZb9mn_.mjs.map +0 -1
- package/fesm2022/a2ui-angular-button-CvH0kAtN.mjs +0 -61
- package/fesm2022/a2ui-angular-button-CvH0kAtN.mjs.map +0 -1
- package/fesm2022/a2ui-angular-card-Ix6OIdUv.mjs +0 -48
- package/fesm2022/a2ui-angular-card-Ix6OIdUv.mjs.map +0 -1
- package/fesm2022/a2ui-angular-checkbox-BN4EF2Ci.mjs +0 -78
- package/fesm2022/a2ui-angular-checkbox-BN4EF2Ci.mjs.map +0 -1
- package/fesm2022/a2ui-angular-datetime-input-dmZAjvrF.mjs +0 -120
- package/fesm2022/a2ui-angular-datetime-input-dmZAjvrF.mjs.map +0 -1
- package/fesm2022/a2ui-angular-divider-BizPl3qL.mjs +0 -30
- package/fesm2022/a2ui-angular-divider-BizPl3qL.mjs.map +0 -1
- package/fesm2022/a2ui-angular-icon-BE9Hj9V6.mjs +0 -48
- package/fesm2022/a2ui-angular-icon-BE9Hj9V6.mjs.map +0 -1
- package/fesm2022/a2ui-angular-image-BWzAw0rh.mjs +0 -54
- package/fesm2022/a2ui-angular-image-BWzAw0rh.mjs.map +0 -1
- package/fesm2022/a2ui-angular-list-nEeT59V3.mjs +0 -45
- package/fesm2022/a2ui-angular-list-nEeT59V3.mjs.map +0 -1
- package/fesm2022/a2ui-angular-modal-mr9LmczA.mjs +0 -108
- package/fesm2022/a2ui-angular-modal-mr9LmczA.mjs.map +0 -1
- package/fesm2022/a2ui-angular-multiple-choice-Bry7X74i.mjs +0 -78
- package/fesm2022/a2ui-angular-multiple-choice-Bry7X74i.mjs.map +0 -1
- package/fesm2022/a2ui-angular-slider-BgseUbN2.mjs +0 -79
- package/fesm2022/a2ui-angular-slider-BgseUbN2.mjs.map +0 -1
- package/fesm2022/a2ui-angular-tabs-q5Mn9vgq.mjs +0 -87
- package/fesm2022/a2ui-angular-tabs-q5Mn9vgq.mjs.map +0 -1
- package/fesm2022/a2ui-angular-text-field-Deokh07j.mjs +0 -85
- package/fesm2022/a2ui-angular-text-field-Deokh07j.mjs.map +0 -1
- package/fesm2022/a2ui-angular-video-DuFTfN0B.mjs +0 -48
- package/fesm2022/a2ui-angular-video-DuFTfN0B.mjs.map +0 -1
|
@@ -0,0 +1,2330 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, Inject, Injectable, signal, inject, DestroyRef, NgZone, input, ChangeDetectionStrategy, Component, computed as computed$1, effect as effect$1 } from '@angular/core';
|
|
3
|
+
import { MessageProcessor, effect, computed, ComponentContext, Catalog, DataContext } from '@a2ui/web_core/v0_9';
|
|
4
|
+
export { signal as preactSignal } from '@a2ui/web_core/v0_9';
|
|
5
|
+
import { NgComponentOutlet } from '@angular/common';
|
|
6
|
+
import { DateTimeInputApi, SliderApi, ChoicePickerApi, CheckBoxApi, DividerApi, ModalApi, TabsApi, CardApi, ListApi, AudioPlayerApi, VideoApi, IconApi, ImageApi, TextFieldApi, ButtonApi, ColumnApi, RowApi, TextApi, BASIC_FUNCTIONS } from '@a2ui/web_core/v0_9/basic_catalog';
|
|
7
|
+
export { BASIC_FUNCTIONS } from '@a2ui/web_core/v0_9/basic_catalog';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Copyright 2026 Google LLC
|
|
11
|
+
*
|
|
12
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
13
|
+
* you may not use this file except in compliance with the License.
|
|
14
|
+
* You may obtain a copy of the License at
|
|
15
|
+
*
|
|
16
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
17
|
+
*
|
|
18
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
19
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
20
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
21
|
+
* See the License for the specific language governing permissions and
|
|
22
|
+
* limitations under the License.
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Injection token for the A2UI renderer configuration.
|
|
26
|
+
*/
|
|
27
|
+
const A2UI_RENDERER_CONFIG = new InjectionToken('A2UI_RENDERER_CONFIG');
|
|
28
|
+
/**
|
|
29
|
+
* Manages A2UI v0.9 rendering sessions by bridging the MessageProcessor to Angular.
|
|
30
|
+
*
|
|
31
|
+
* This service is the central entry point for the A2UI renderer. It maintains a
|
|
32
|
+
* {@link MessageProcessor} that turns A2UI protocol messages into a reactive
|
|
33
|
+
* {@link SurfaceGroupModel}.
|
|
34
|
+
*/
|
|
35
|
+
class A2uiRendererService {
|
|
36
|
+
config;
|
|
37
|
+
_messageProcessor;
|
|
38
|
+
_catalogs = [];
|
|
39
|
+
constructor(config) {
|
|
40
|
+
this.config = config;
|
|
41
|
+
this._catalogs = this.config.catalogs;
|
|
42
|
+
this._messageProcessor = new MessageProcessor(this._catalogs, this.config.actionHandler);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Processes a list of A2UI messages and updates the internal surface models.
|
|
46
|
+
*
|
|
47
|
+
* This should be called whenever new messages arrive from an agent or orchestrator.
|
|
48
|
+
*
|
|
49
|
+
* @param messages The list of {@link A2uiMessage}s to process.
|
|
50
|
+
*/
|
|
51
|
+
processMessages(messages) {
|
|
52
|
+
this._messageProcessor.processMessages(messages);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The current surface group model containing all active surfaces.
|
|
56
|
+
*
|
|
57
|
+
* Surfaces can be retrieved from this group using their `surfaceId`.
|
|
58
|
+
*/
|
|
59
|
+
get surfaceGroup() {
|
|
60
|
+
return this._messageProcessor.model;
|
|
61
|
+
}
|
|
62
|
+
ngOnDestroy() {
|
|
63
|
+
this._messageProcessor.model.dispose();
|
|
64
|
+
}
|
|
65
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: A2uiRendererService, deps: [{ token: A2UI_RENDERER_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
66
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: A2uiRendererService });
|
|
67
|
+
}
|
|
68
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: A2uiRendererService, decorators: [{
|
|
69
|
+
type: Injectable
|
|
70
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
71
|
+
type: Inject,
|
|
72
|
+
args: [A2UI_RENDERER_CONFIG]
|
|
73
|
+
}] }] });
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Copyright 2026 Google LLC
|
|
77
|
+
*
|
|
78
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
79
|
+
* you may not use this file except in compliance with the License.
|
|
80
|
+
* You may obtain a copy of the License at
|
|
81
|
+
*
|
|
82
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
83
|
+
*
|
|
84
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
85
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
86
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
87
|
+
* See the License for the specific language governing permissions and
|
|
88
|
+
* limitations under the License.
|
|
89
|
+
*/
|
|
90
|
+
function toAngularSignal(preactSignal, destroyRef, ngZone) {
|
|
91
|
+
const s = signal(preactSignal.peek());
|
|
92
|
+
const dispose = effect(() => {
|
|
93
|
+
if (ngZone) {
|
|
94
|
+
ngZone.run(() => s.set(preactSignal.value));
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
s.set(preactSignal.value);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
destroyRef.onDestroy(() => {
|
|
101
|
+
dispose();
|
|
102
|
+
// Some signals returned by DataContext.resolveSignal have a custom unsubscribe for AbortControllers
|
|
103
|
+
if (preactSignal.unsubscribe) {
|
|
104
|
+
preactSignal.unsubscribe();
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return s.asReadonly();
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Normalizes a data model path by combining a relative path with a base context.
|
|
111
|
+
*
|
|
112
|
+
* This is used to create unique absolute paths for components within a repeating
|
|
113
|
+
* collection or nested structure.
|
|
114
|
+
*
|
|
115
|
+
* @param path The relative or absolute path from the component properties.
|
|
116
|
+
* @param dataContextPath The current base data context path.
|
|
117
|
+
* @param index The index of the child component.
|
|
118
|
+
* @returns A fully normalized absolute path for the indexed child.
|
|
119
|
+
*/
|
|
120
|
+
function getNormalizedPath(path, dataContextPath, index) {
|
|
121
|
+
let normalized = path || '';
|
|
122
|
+
if (!normalized.startsWith('/')) {
|
|
123
|
+
const base = dataContextPath === '/' ? '' : dataContextPath;
|
|
124
|
+
normalized = `${base}/${normalized}`;
|
|
125
|
+
}
|
|
126
|
+
if (normalized.endsWith('/')) {
|
|
127
|
+
normalized = normalized.slice(0, -1);
|
|
128
|
+
}
|
|
129
|
+
return `${normalized}/${index}`;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Copyright 2026 Google LLC
|
|
134
|
+
*
|
|
135
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
136
|
+
* you may not use this file except in compliance with the License.
|
|
137
|
+
* You may obtain a copy of the License at
|
|
138
|
+
*
|
|
139
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
140
|
+
*
|
|
141
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
142
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
143
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
144
|
+
* See the License for the specific language governing permissions and
|
|
145
|
+
* limitations under the License.
|
|
146
|
+
*/
|
|
147
|
+
/**
|
|
148
|
+
* Binds A2UI ComponentModel properties to reactive Angular Signals.
|
|
149
|
+
*
|
|
150
|
+
* This service is used by {@link ComponentHostComponent} to resolve data bindings
|
|
151
|
+
* from the A2UI DataContext and expose them as Angular Signals. It ensures that
|
|
152
|
+
* property updates from the A2UI protocol are correctly reflected in Angular
|
|
153
|
+
* components and provides callbacks for updating the data model.
|
|
154
|
+
*/
|
|
155
|
+
class ComponentBinder {
|
|
156
|
+
destroyRef = inject(DestroyRef);
|
|
157
|
+
ngZone = inject(NgZone);
|
|
158
|
+
/**
|
|
159
|
+
* Binds all properties of a component to an object of Angular Signals.
|
|
160
|
+
*
|
|
161
|
+
* @param context The ComponentContext containing the model and data context.
|
|
162
|
+
* @returns An object where each key corresponds to a component prop and its value is an Angular Signal.
|
|
163
|
+
*/
|
|
164
|
+
bind(context) {
|
|
165
|
+
const props = context.componentModel.properties;
|
|
166
|
+
const bound = {};
|
|
167
|
+
for (const key of Object.keys(props)) {
|
|
168
|
+
const value = props[key];
|
|
169
|
+
let preactSig;
|
|
170
|
+
const isChildListTemplate = value && typeof value === 'object' && 'componentId' in value && 'path' in value;
|
|
171
|
+
const isBoundPath = value && typeof value === 'object' && 'path' in value && !('componentId' in value);
|
|
172
|
+
if (isChildListTemplate) {
|
|
173
|
+
const listSig = context.dataContext.resolveSignal({ path: value.path });
|
|
174
|
+
const listContext = context.dataContext.nested(value.path);
|
|
175
|
+
preactSig = computed(() => {
|
|
176
|
+
const arr = listSig.value;
|
|
177
|
+
const currentArr = Array.isArray(arr) ? arr : [];
|
|
178
|
+
return currentArr.map((_, i) => ({
|
|
179
|
+
id: value.componentId,
|
|
180
|
+
basePath: listContext.nested(String(i)).path,
|
|
181
|
+
}));
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
preactSig = context.dataContext.resolveSignal(value);
|
|
186
|
+
}
|
|
187
|
+
if (['child', 'trigger', 'content'].includes(key)) {
|
|
188
|
+
const originalSig = preactSig;
|
|
189
|
+
preactSig = computed(() => {
|
|
190
|
+
const val = originalSig.value;
|
|
191
|
+
if (!val)
|
|
192
|
+
return null;
|
|
193
|
+
if (typeof val === 'object' && val !== null && 'id' in val) {
|
|
194
|
+
return val;
|
|
195
|
+
}
|
|
196
|
+
return { id: val, basePath: context.dataContext.path };
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
else if (key === 'children') {
|
|
200
|
+
const originalSig = preactSig;
|
|
201
|
+
preactSig = computed(() => {
|
|
202
|
+
const val = originalSig.value;
|
|
203
|
+
const arr = Array.isArray(val) ? val : [];
|
|
204
|
+
return arr.map(item => {
|
|
205
|
+
if (typeof item === 'object' && item !== null && 'id' in item) {
|
|
206
|
+
return item;
|
|
207
|
+
}
|
|
208
|
+
return { id: item, basePath: context.dataContext.path };
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
const angSig = toAngularSignal(preactSig, this.destroyRef, this.ngZone);
|
|
213
|
+
bound[key] = {
|
|
214
|
+
value: angSig,
|
|
215
|
+
raw: value,
|
|
216
|
+
onUpdate: isBoundPath
|
|
217
|
+
? (newValue) => context.dataContext.set(value.path, newValue)
|
|
218
|
+
: () => { }, // No-op for non-bound values
|
|
219
|
+
};
|
|
220
|
+
if (key === 'checks') {
|
|
221
|
+
const checksArray = Array.isArray(value) ? value : [];
|
|
222
|
+
const ruleResults = checksArray.map((rule) => {
|
|
223
|
+
const condition = rule.condition || rule;
|
|
224
|
+
const message = rule.message || 'Validation failed';
|
|
225
|
+
const conditionSig = context.dataContext.resolveSignal(condition);
|
|
226
|
+
return { conditionSig, message };
|
|
227
|
+
});
|
|
228
|
+
const isValidPreactSig = computed(() => {
|
|
229
|
+
return ruleResults.every((r) => !!r.conditionSig.value);
|
|
230
|
+
});
|
|
231
|
+
const validationErrorsPreactSig = computed(() => {
|
|
232
|
+
return ruleResults
|
|
233
|
+
.filter((r) => !r.conditionSig.value)
|
|
234
|
+
.map((r) => r.message);
|
|
235
|
+
});
|
|
236
|
+
bound['isValid'] = {
|
|
237
|
+
value: toAngularSignal(isValidPreactSig, this.destroyRef, this.ngZone),
|
|
238
|
+
raw: null,
|
|
239
|
+
onUpdate: () => { },
|
|
240
|
+
};
|
|
241
|
+
bound['validationErrors'] = {
|
|
242
|
+
value: toAngularSignal(validationErrorsPreactSig, this.destroyRef, this.ngZone),
|
|
243
|
+
raw: null,
|
|
244
|
+
onUpdate: () => { },
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return bound;
|
|
249
|
+
}
|
|
250
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ComponentBinder, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
251
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ComponentBinder, providedIn: 'root' });
|
|
252
|
+
}
|
|
253
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ComponentBinder, decorators: [{
|
|
254
|
+
type: Injectable,
|
|
255
|
+
args: [{
|
|
256
|
+
providedIn: 'root',
|
|
257
|
+
}]
|
|
258
|
+
}] });
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Copyright 2026 Google LLC
|
|
262
|
+
*
|
|
263
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
264
|
+
* you may not use this file except in compliance with the License.
|
|
265
|
+
* You may obtain a copy of the License at
|
|
266
|
+
*
|
|
267
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
268
|
+
*
|
|
269
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
270
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
271
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
272
|
+
* See the License for the specific language governing permissions and
|
|
273
|
+
* limitations under the License.
|
|
274
|
+
*/
|
|
275
|
+
/**
|
|
276
|
+
* Dynamically renders an A2UI component as defined in the current surface model.
|
|
277
|
+
*
|
|
278
|
+
* This component acts as a bridge between the A2UI surface model and Angular components.
|
|
279
|
+
* It resolves the appropriate component from the catalog based on the component's type,
|
|
280
|
+
* and uses {@link ComponentBinder} to create reactive property bindings.
|
|
281
|
+
*
|
|
282
|
+
* Usually, you'll use the higher-level {@link SurfaceComponent} which automatically
|
|
283
|
+
* sets up a host for the 'root' component.
|
|
284
|
+
*/
|
|
285
|
+
class ComponentHostComponent {
|
|
286
|
+
/** The key of the component to render, either an ID string or an object with ID and basePath. Defaults to 'root'. */
|
|
287
|
+
componentKey = input('root', ...(ngDevMode ? [{ debugName: "componentKey" }] : /* istanbul ignore next */ []));
|
|
288
|
+
/** The unique identifier of the surface this component belongs to. */
|
|
289
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
290
|
+
rendererService = inject(A2uiRendererService);
|
|
291
|
+
binder = inject(ComponentBinder);
|
|
292
|
+
destroyRef = inject(DestroyRef);
|
|
293
|
+
componentType = null;
|
|
294
|
+
props = {};
|
|
295
|
+
context;
|
|
296
|
+
resolvedComponentId = '';
|
|
297
|
+
resolvedDataContextPath = '/';
|
|
298
|
+
ngOnInit() {
|
|
299
|
+
const surface = this.rendererService.surfaceGroup?.getSurface(this.surfaceId());
|
|
300
|
+
if (!surface) {
|
|
301
|
+
console.warn(`Surface ${this.surfaceId()} not found`);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
const key = this.componentKey();
|
|
305
|
+
let id;
|
|
306
|
+
let basePath;
|
|
307
|
+
if (typeof key === 'object' && key !== null && 'id' in key) {
|
|
308
|
+
id = key.id;
|
|
309
|
+
basePath = key.basePath || '/';
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
id = key;
|
|
313
|
+
basePath = '/';
|
|
314
|
+
}
|
|
315
|
+
this.resolvedComponentId = id;
|
|
316
|
+
const componentModel = surface.componentsModel.get(id);
|
|
317
|
+
if (!componentModel) {
|
|
318
|
+
console.warn(`Component ${id} not found in surface ${this.surfaceId()}`);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
// Resolve component from the surface's catalog
|
|
322
|
+
const catalog = surface.catalog;
|
|
323
|
+
const api = catalog.components.get(componentModel.type);
|
|
324
|
+
if (!api) {
|
|
325
|
+
console.error(`Component type "${componentModel.type}" not found in catalog "${catalog.id}"`);
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
this.componentType = api.component;
|
|
329
|
+
// Create context
|
|
330
|
+
this.context = new ComponentContext(surface, id, basePath);
|
|
331
|
+
this.props = this.binder.bind(this.context);
|
|
332
|
+
this.resolvedDataContextPath = this.context.dataContext.path;
|
|
333
|
+
this.destroyRef.onDestroy(() => {
|
|
334
|
+
// ComponentContext itself doesn't have a dispose, but its inner components might.
|
|
335
|
+
// However, SurfaceModel takes care of component disposal.
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ComponentHostComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
339
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ComponentHostComponent, isStandalone: true, selector: "a2ui-v09-component-host", inputs: { componentKey: { classPropertyName: "componentKey", publicName: "componentKey", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
|
|
340
|
+
@if (componentType) {
|
|
341
|
+
<ng-container
|
|
342
|
+
*ngComponentOutlet="
|
|
343
|
+
componentType;
|
|
344
|
+
inputs: {
|
|
345
|
+
props: props,
|
|
346
|
+
surfaceId: surfaceId(),
|
|
347
|
+
componentId: resolvedComponentId,
|
|
348
|
+
dataContextPath: resolvedDataContextPath,
|
|
349
|
+
}
|
|
350
|
+
"
|
|
351
|
+
></ng-container>
|
|
352
|
+
}
|
|
353
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
354
|
+
}
|
|
355
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ComponentHostComponent, decorators: [{
|
|
356
|
+
type: Component,
|
|
357
|
+
args: [{
|
|
358
|
+
selector: 'a2ui-v09-component-host',
|
|
359
|
+
imports: [NgComponentOutlet],
|
|
360
|
+
template: `
|
|
361
|
+
@if (componentType) {
|
|
362
|
+
<ng-container
|
|
363
|
+
*ngComponentOutlet="
|
|
364
|
+
componentType;
|
|
365
|
+
inputs: {
|
|
366
|
+
props: props,
|
|
367
|
+
surfaceId: surfaceId(),
|
|
368
|
+
componentId: resolvedComponentId,
|
|
369
|
+
dataContextPath: resolvedDataContextPath,
|
|
370
|
+
}
|
|
371
|
+
"
|
|
372
|
+
></ng-container>
|
|
373
|
+
}
|
|
374
|
+
`,
|
|
375
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
376
|
+
}]
|
|
377
|
+
}], propDecorators: { componentKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentKey", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }] } });
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Copyright 2026 Google LLC
|
|
381
|
+
*
|
|
382
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
383
|
+
* you may not use this file except in compliance with the License.
|
|
384
|
+
* You may obtain a copy of the License at
|
|
385
|
+
*
|
|
386
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
387
|
+
*
|
|
388
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
389
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
390
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
391
|
+
* See the License for the specific language governing permissions and
|
|
392
|
+
* limitations under the License.
|
|
393
|
+
*/
|
|
394
|
+
/**
|
|
395
|
+
* High-level component for rendering an entire A2UI surface.
|
|
396
|
+
*
|
|
397
|
+
* This component handles the boilerplate of setting up a {@link ComponentHostComponent}
|
|
398
|
+
* for the 'root' component of a surface. It is the recommended way to embed an
|
|
399
|
+
* A2UI surface in an Angular application.
|
|
400
|
+
*/
|
|
401
|
+
class SurfaceComponent {
|
|
402
|
+
/** The unique identifier of the surface to render. */
|
|
403
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
404
|
+
/**
|
|
405
|
+
* The path within the surface's data model that represents the current state.
|
|
406
|
+
* Defaults to the root ('/').
|
|
407
|
+
*/
|
|
408
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
409
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SurfaceComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
410
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: SurfaceComponent, isStandalone: true, selector: "a2ui-v09-surface", inputs: { surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
411
|
+
<a2ui-v09-component-host
|
|
412
|
+
[componentKey]="{ id: 'root', basePath: dataContextPath() }"
|
|
413
|
+
[surfaceId]="surfaceId()"
|
|
414
|
+
>
|
|
415
|
+
</a2ui-v09-component-host>
|
|
416
|
+
`, isInline: true, dependencies: [{ kind: "component", type: ComponentHostComponent, selector: "a2ui-v09-component-host", inputs: ["componentKey", "surfaceId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
417
|
+
}
|
|
418
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SurfaceComponent, decorators: [{
|
|
419
|
+
type: Component,
|
|
420
|
+
args: [{
|
|
421
|
+
selector: 'a2ui-v09-surface',
|
|
422
|
+
standalone: true,
|
|
423
|
+
imports: [ComponentHostComponent],
|
|
424
|
+
template: `
|
|
425
|
+
<a2ui-v09-component-host
|
|
426
|
+
[componentKey]="{ id: 'root', basePath: dataContextPath() }"
|
|
427
|
+
[surfaceId]="surfaceId()"
|
|
428
|
+
>
|
|
429
|
+
</a2ui-v09-component-host>
|
|
430
|
+
`,
|
|
431
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
432
|
+
}]
|
|
433
|
+
}], propDecorators: { surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Copyright 2026 Google LLC
|
|
437
|
+
*
|
|
438
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
439
|
+
* you may not use this file except in compliance with the License.
|
|
440
|
+
* You may obtain a copy of the License at
|
|
441
|
+
*
|
|
442
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
443
|
+
*
|
|
444
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
445
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
446
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
447
|
+
* See the License for the specific language governing permissions and
|
|
448
|
+
* limitations under the License.
|
|
449
|
+
*/
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Copyright 2026 Google LLC
|
|
453
|
+
*
|
|
454
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
455
|
+
* you may not use this file except in compliance with the License.
|
|
456
|
+
* You may obtain a copy of the License at
|
|
457
|
+
*
|
|
458
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
459
|
+
*
|
|
460
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
461
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
462
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
463
|
+
* See the License for the specific language governing permissions and
|
|
464
|
+
* limitations under the License.
|
|
465
|
+
*/
|
|
466
|
+
/**
|
|
467
|
+
* A collection of Angular component and function implementations mapped to
|
|
468
|
+
* A2UI protocol types.
|
|
469
|
+
*
|
|
470
|
+
* Catalogs are used by the {@link MessageProcessor} to resolve component
|
|
471
|
+
* definitions and by {@link ComponentHostComponent} to instantiate the
|
|
472
|
+
* correct Angular components.
|
|
473
|
+
*/
|
|
474
|
+
class AngularCatalog extends Catalog {
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Copyright 2026 Google LLC
|
|
479
|
+
*
|
|
480
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
481
|
+
* you may not use this file except in compliance with the License.
|
|
482
|
+
* You may obtain a copy of the License at
|
|
483
|
+
*
|
|
484
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
485
|
+
*
|
|
486
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
487
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
488
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
489
|
+
* See the License for the specific language governing permissions and
|
|
490
|
+
* limitations under the License.
|
|
491
|
+
*/
|
|
492
|
+
class MarkdownRenderer {
|
|
493
|
+
}
|
|
494
|
+
class DefaultMarkdownRenderer extends MarkdownRenderer {
|
|
495
|
+
static warningLogged = false;
|
|
496
|
+
async render(markdown, options) {
|
|
497
|
+
try {
|
|
498
|
+
// @ts-ignore - optional peer dependency
|
|
499
|
+
const { renderMarkdown } = await import('@a2ui/markdown-it');
|
|
500
|
+
return await renderMarkdown(markdown, options);
|
|
501
|
+
}
|
|
502
|
+
catch (e) {
|
|
503
|
+
if (!DefaultMarkdownRenderer.warningLogged) {
|
|
504
|
+
console.warn("[DefaultMarkdownRenderer] Failed to load optional `@a2ui/markdown-it` renderer. Using fallback.");
|
|
505
|
+
DefaultMarkdownRenderer.warningLogged = true;
|
|
506
|
+
}
|
|
507
|
+
return markdown;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DefaultMarkdownRenderer, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
511
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DefaultMarkdownRenderer, providedIn: 'root' });
|
|
512
|
+
}
|
|
513
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DefaultMarkdownRenderer, decorators: [{
|
|
514
|
+
type: Injectable,
|
|
515
|
+
args: [{
|
|
516
|
+
providedIn: 'root',
|
|
517
|
+
}]
|
|
518
|
+
}] });
|
|
519
|
+
function provideMarkdownRenderer(renderFn) {
|
|
520
|
+
if (renderFn) {
|
|
521
|
+
return {
|
|
522
|
+
provide: MarkdownRenderer,
|
|
523
|
+
useValue: {
|
|
524
|
+
render: renderFn,
|
|
525
|
+
},
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
return { provide: MarkdownRenderer, useClass: DefaultMarkdownRenderer };
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Copyright 2026 Google LLC
|
|
533
|
+
*
|
|
534
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
535
|
+
* you may not use this file except in compliance with the License.
|
|
536
|
+
* You may obtain a copy of the License at
|
|
537
|
+
*
|
|
538
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
539
|
+
*
|
|
540
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
541
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
542
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
543
|
+
* See the License for the specific language governing permissions and
|
|
544
|
+
* limitations under the License.
|
|
545
|
+
*/
|
|
546
|
+
/**
|
|
547
|
+
* Angular implementation of the A2UI Text component (v0.9).
|
|
548
|
+
*
|
|
549
|
+
* Renders text with support for simple Markdown.
|
|
550
|
+
*/
|
|
551
|
+
class TextComponent {
|
|
552
|
+
/**
|
|
553
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
554
|
+
*
|
|
555
|
+
* Expected properties:
|
|
556
|
+
* - `text`: The string content to display.
|
|
557
|
+
* - `variant`: A hint for the base text style ('h1', 'h2', 'h3', 'h4', 'h5', 'caption', 'body').
|
|
558
|
+
*/
|
|
559
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
560
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
561
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
562
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
563
|
+
markdownRenderer = inject(MarkdownRenderer);
|
|
564
|
+
variant = computed$1(() => this.props()['variant']?.value() || 'body', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
565
|
+
text = computed$1(() => this.props()['text']?.value() || '', ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
|
|
566
|
+
resolvedText = signal('', ...(ngDevMode ? [{ debugName: "resolvedText" }] : /* istanbul ignore next */ []));
|
|
567
|
+
renderRequestId = 0;
|
|
568
|
+
constructor() {
|
|
569
|
+
effect$1(() => {
|
|
570
|
+
const text = this.text();
|
|
571
|
+
const variant = this.variant();
|
|
572
|
+
let value = text;
|
|
573
|
+
switch (variant) {
|
|
574
|
+
case 'h1':
|
|
575
|
+
value = `# ${text}`;
|
|
576
|
+
break;
|
|
577
|
+
case 'h2':
|
|
578
|
+
value = `## ${text}`;
|
|
579
|
+
break;
|
|
580
|
+
case 'h3':
|
|
581
|
+
value = `### ${text}`;
|
|
582
|
+
break;
|
|
583
|
+
case 'h4':
|
|
584
|
+
value = `#### ${text}`;
|
|
585
|
+
break;
|
|
586
|
+
case 'h5':
|
|
587
|
+
value = `##### ${text}`;
|
|
588
|
+
break;
|
|
589
|
+
case 'caption':
|
|
590
|
+
value = `*${text}*`;
|
|
591
|
+
break;
|
|
592
|
+
}
|
|
593
|
+
const requestId = ++this.renderRequestId;
|
|
594
|
+
this.markdownRenderer.render(value).then(rendered => {
|
|
595
|
+
if (requestId === this.renderRequestId) {
|
|
596
|
+
this.resolvedText.set(rendered);
|
|
597
|
+
}
|
|
598
|
+
});
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
602
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: TextComponent, isStandalone: true, selector: "a2ui-v09-text", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
603
|
+
<span [class]="'a2ui-text ' + variant()" [innerHTML]="resolvedText()">
|
|
604
|
+
</span>
|
|
605
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
606
|
+
}
|
|
607
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TextComponent, decorators: [{
|
|
608
|
+
type: Component,
|
|
609
|
+
args: [{
|
|
610
|
+
selector: 'a2ui-v09-text',
|
|
611
|
+
standalone: true,
|
|
612
|
+
template: `
|
|
613
|
+
<span [class]="'a2ui-text ' + variant()" [innerHTML]="resolvedText()">
|
|
614
|
+
</span>
|
|
615
|
+
`,
|
|
616
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
617
|
+
}]
|
|
618
|
+
}], ctorParameters: () => [], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* Copyright 2026 Google LLC
|
|
622
|
+
*
|
|
623
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
624
|
+
* you may not use this file except in compliance with the License.
|
|
625
|
+
* You may obtain a copy of the License at
|
|
626
|
+
*
|
|
627
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
628
|
+
*
|
|
629
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
630
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
631
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
632
|
+
* See the License for the specific language governing permissions and
|
|
633
|
+
* limitations under the License.
|
|
634
|
+
*/
|
|
635
|
+
/**
|
|
636
|
+
* Angular implementation of the A2UI Row component (v0.9).
|
|
637
|
+
*
|
|
638
|
+
* Arranges child components in a horizontal flex layout. Supports both static
|
|
639
|
+
* lists of children and repeating templates bound to a data collection.
|
|
640
|
+
*/
|
|
641
|
+
class RowComponent {
|
|
642
|
+
/**
|
|
643
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
644
|
+
*
|
|
645
|
+
* Expected properties:
|
|
646
|
+
* - `children`: A list of component IDs OR a repeating collection definition.
|
|
647
|
+
* - `justify`: Flexbox justify-content value (e.g., 'flex-start', 'center').
|
|
648
|
+
* - `align`: Flexbox align-items value (e.g., 'flex-start', 'center').
|
|
649
|
+
*/
|
|
650
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
651
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
652
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
653
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
654
|
+
justify = computed$1(() => this.props()['justify']?.value(), ...(ngDevMode ? [{ debugName: "justify" }] : /* istanbul ignore next */ []));
|
|
655
|
+
align = computed$1(() => this.props()['align']?.value(), ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
|
|
656
|
+
children = computed$1(() => {
|
|
657
|
+
const raw = this.props()['children']?.value() || [];
|
|
658
|
+
return Array.isArray(raw) ? raw : [];
|
|
659
|
+
}, ...(ngDevMode ? [{ debugName: "children" }] : /* istanbul ignore next */ []));
|
|
660
|
+
isRepeating = computed$1(() => {
|
|
661
|
+
return !!this.props()['children']?.raw?.componentId;
|
|
662
|
+
}, ...(ngDevMode ? [{ debugName: "isRepeating" }] : /* istanbul ignore next */ []));
|
|
663
|
+
templateId = computed$1(() => {
|
|
664
|
+
return this.props()['children']?.raw?.componentId;
|
|
665
|
+
}, ...(ngDevMode ? [{ debugName: "templateId" }] : /* istanbul ignore next */ []));
|
|
666
|
+
normalizedChildren = computed$1(() => {
|
|
667
|
+
if (this.isRepeating())
|
|
668
|
+
return [];
|
|
669
|
+
return this.children().map(child => {
|
|
670
|
+
if (typeof child === 'object' && child !== null && 'id' in child) {
|
|
671
|
+
return child;
|
|
672
|
+
}
|
|
673
|
+
return { id: child, basePath: this.dataContextPath() };
|
|
674
|
+
});
|
|
675
|
+
}, ...(ngDevMode ? [{ debugName: "normalizedChildren" }] : /* istanbul ignore next */ []));
|
|
676
|
+
getNormalizedPath(index) {
|
|
677
|
+
return getNormalizedPath(this.props()['children']?.raw?.path, this.dataContextPath(), index);
|
|
678
|
+
}
|
|
679
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
680
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: RowComponent, isStandalone: true, selector: "a2ui-v09-row", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
681
|
+
<div
|
|
682
|
+
class="a2ui-row"
|
|
683
|
+
[style.justify-content]="justify()"
|
|
684
|
+
[style.align-items]="align()"
|
|
685
|
+
style="display: flex; flex-direction: row; width: 100%; gap: 4px;"
|
|
686
|
+
>
|
|
687
|
+
@if (!isRepeating()) {
|
|
688
|
+
@for (child of normalizedChildren(); track child.id) {
|
|
689
|
+
<a2ui-v09-component-host
|
|
690
|
+
[componentKey]="child"
|
|
691
|
+
[surfaceId]="surfaceId()"
|
|
692
|
+
>
|
|
693
|
+
</a2ui-v09-component-host>
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
@if (isRepeating()) {
|
|
698
|
+
@for (item of children(); track item; let i = $index) {
|
|
699
|
+
<a2ui-v09-component-host
|
|
700
|
+
[componentKey]="{ id: templateId()!, basePath: getNormalizedPath(i) }"
|
|
701
|
+
[surfaceId]="surfaceId()"
|
|
702
|
+
>
|
|
703
|
+
</a2ui-v09-component-host>
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
</div>
|
|
707
|
+
`, isInline: true, dependencies: [{ kind: "component", type: ComponentHostComponent, selector: "a2ui-v09-component-host", inputs: ["componentKey", "surfaceId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
708
|
+
}
|
|
709
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RowComponent, decorators: [{
|
|
710
|
+
type: Component,
|
|
711
|
+
args: [{
|
|
712
|
+
selector: 'a2ui-v09-row',
|
|
713
|
+
standalone: true,
|
|
714
|
+
imports: [ComponentHostComponent],
|
|
715
|
+
template: `
|
|
716
|
+
<div
|
|
717
|
+
class="a2ui-row"
|
|
718
|
+
[style.justify-content]="justify()"
|
|
719
|
+
[style.align-items]="align()"
|
|
720
|
+
style="display: flex; flex-direction: row; width: 100%; gap: 4px;"
|
|
721
|
+
>
|
|
722
|
+
@if (!isRepeating()) {
|
|
723
|
+
@for (child of normalizedChildren(); track child.id) {
|
|
724
|
+
<a2ui-v09-component-host
|
|
725
|
+
[componentKey]="child"
|
|
726
|
+
[surfaceId]="surfaceId()"
|
|
727
|
+
>
|
|
728
|
+
</a2ui-v09-component-host>
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
@if (isRepeating()) {
|
|
733
|
+
@for (item of children(); track item; let i = $index) {
|
|
734
|
+
<a2ui-v09-component-host
|
|
735
|
+
[componentKey]="{ id: templateId()!, basePath: getNormalizedPath(i) }"
|
|
736
|
+
[surfaceId]="surfaceId()"
|
|
737
|
+
>
|
|
738
|
+
</a2ui-v09-component-host>
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
</div>
|
|
742
|
+
`,
|
|
743
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
744
|
+
}]
|
|
745
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
746
|
+
|
|
747
|
+
/**
|
|
748
|
+
* Copyright 2026 Google LLC
|
|
749
|
+
*
|
|
750
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
751
|
+
* you may not use this file except in compliance with the License.
|
|
752
|
+
* You may obtain a copy of the License at
|
|
753
|
+
*
|
|
754
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
755
|
+
*
|
|
756
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
757
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
758
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
759
|
+
* See the License for the specific language governing permissions and
|
|
760
|
+
* limitations under the License.
|
|
761
|
+
*/
|
|
762
|
+
/**
|
|
763
|
+
* Angular implementation of the A2UI Column component (v0.9).
|
|
764
|
+
*
|
|
765
|
+
* Arranges child components in a vertical flex layout. Supports both static
|
|
766
|
+
* lists of children and repeating templates bound to a data collection.
|
|
767
|
+
*/
|
|
768
|
+
class ColumnComponent {
|
|
769
|
+
/**
|
|
770
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
771
|
+
*
|
|
772
|
+
* Expected properties:
|
|
773
|
+
* - `children`: A list of component IDs OR a repeating collection definition.
|
|
774
|
+
* - `justify`: Flexbox justify-content value (e.g., 'flex-start', 'center').
|
|
775
|
+
* - `align`: Flexbox align-items value (e.g., 'flex-start', 'center').
|
|
776
|
+
*/
|
|
777
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
778
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
779
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
780
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
781
|
+
justify = computed$1(() => this.props()['justify']?.value(), ...(ngDevMode ? [{ debugName: "justify" }] : /* istanbul ignore next */ []));
|
|
782
|
+
align = computed$1(() => this.props()['align']?.value(), ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
|
|
783
|
+
children = computed$1(() => {
|
|
784
|
+
const raw = this.props()['children']?.value() || [];
|
|
785
|
+
return Array.isArray(raw) ? raw : [];
|
|
786
|
+
}, ...(ngDevMode ? [{ debugName: "children" }] : /* istanbul ignore next */ []));
|
|
787
|
+
isRepeating = computed$1(() => {
|
|
788
|
+
return !!this.props()['children']?.raw?.componentId;
|
|
789
|
+
}, ...(ngDevMode ? [{ debugName: "isRepeating" }] : /* istanbul ignore next */ []));
|
|
790
|
+
templateId = computed$1(() => {
|
|
791
|
+
return this.props()['children']?.raw?.componentId;
|
|
792
|
+
}, ...(ngDevMode ? [{ debugName: "templateId" }] : /* istanbul ignore next */ []));
|
|
793
|
+
normalizedChildren = computed$1(() => {
|
|
794
|
+
if (this.isRepeating())
|
|
795
|
+
return [];
|
|
796
|
+
return this.children().map(child => {
|
|
797
|
+
if (typeof child === 'object' && child !== null && 'id' in child) {
|
|
798
|
+
return child;
|
|
799
|
+
}
|
|
800
|
+
return { id: child, basePath: this.dataContextPath() };
|
|
801
|
+
});
|
|
802
|
+
}, ...(ngDevMode ? [{ debugName: "normalizedChildren" }] : /* istanbul ignore next */ []));
|
|
803
|
+
getNormalizedPath(index) {
|
|
804
|
+
return getNormalizedPath(this.props()['children']?.raw?.path, this.dataContextPath(), index);
|
|
805
|
+
}
|
|
806
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
807
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ColumnComponent, isStandalone: true, selector: "a2ui-v09-column", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
808
|
+
<div
|
|
809
|
+
class="a2ui-column"
|
|
810
|
+
[style.justify-content]="justify()"
|
|
811
|
+
[style.align-items]="align()"
|
|
812
|
+
style="display: flex; flex-direction: column; width: 100%; gap: 4px;"
|
|
813
|
+
>
|
|
814
|
+
@if (!isRepeating()) {
|
|
815
|
+
@for (child of normalizedChildren(); track child.id) {
|
|
816
|
+
<a2ui-v09-component-host
|
|
817
|
+
[componentKey]="child"
|
|
818
|
+
[surfaceId]="surfaceId()"
|
|
819
|
+
>
|
|
820
|
+
</a2ui-v09-component-host>
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
@if (isRepeating()) {
|
|
825
|
+
@for (item of children(); track item; let i = $index) {
|
|
826
|
+
<a2ui-v09-component-host
|
|
827
|
+
[componentKey]="{ id: templateId()!, basePath: getNormalizedPath(i) }"
|
|
828
|
+
[surfaceId]="surfaceId()"
|
|
829
|
+
>
|
|
830
|
+
</a2ui-v09-component-host>
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
</div>
|
|
834
|
+
`, isInline: true, dependencies: [{ kind: "component", type: ComponentHostComponent, selector: "a2ui-v09-component-host", inputs: ["componentKey", "surfaceId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
835
|
+
}
|
|
836
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ColumnComponent, decorators: [{
|
|
837
|
+
type: Component,
|
|
838
|
+
args: [{
|
|
839
|
+
selector: 'a2ui-v09-column',
|
|
840
|
+
standalone: true,
|
|
841
|
+
imports: [ComponentHostComponent],
|
|
842
|
+
template: `
|
|
843
|
+
<div
|
|
844
|
+
class="a2ui-column"
|
|
845
|
+
[style.justify-content]="justify()"
|
|
846
|
+
[style.align-items]="align()"
|
|
847
|
+
style="display: flex; flex-direction: column; width: 100%; gap: 4px;"
|
|
848
|
+
>
|
|
849
|
+
@if (!isRepeating()) {
|
|
850
|
+
@for (child of normalizedChildren(); track child.id) {
|
|
851
|
+
<a2ui-v09-component-host
|
|
852
|
+
[componentKey]="child"
|
|
853
|
+
[surfaceId]="surfaceId()"
|
|
854
|
+
>
|
|
855
|
+
</a2ui-v09-component-host>
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
@if (isRepeating()) {
|
|
860
|
+
@for (item of children(); track item; let i = $index) {
|
|
861
|
+
<a2ui-v09-component-host
|
|
862
|
+
[componentKey]="{ id: templateId()!, basePath: getNormalizedPath(i) }"
|
|
863
|
+
[surfaceId]="surfaceId()"
|
|
864
|
+
>
|
|
865
|
+
</a2ui-v09-component-host>
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
</div>
|
|
869
|
+
`,
|
|
870
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
871
|
+
}]
|
|
872
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
873
|
+
|
|
874
|
+
/**
|
|
875
|
+
* Copyright 2026 Google LLC
|
|
876
|
+
*
|
|
877
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
878
|
+
* you may not use this file except in compliance with the License.
|
|
879
|
+
* You may obtain a copy of the License at
|
|
880
|
+
*
|
|
881
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
882
|
+
*
|
|
883
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
884
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
885
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
886
|
+
* See the License for the specific language governing permissions and
|
|
887
|
+
* limitations under the License.
|
|
888
|
+
*/
|
|
889
|
+
/**
|
|
890
|
+
* Angular implementation of the A2UI Button component (v0.9).
|
|
891
|
+
*
|
|
892
|
+
* Renders a clickable button with a single child component (usually Text).
|
|
893
|
+
* Dispatches an action when clicked if an `action` property is provided.
|
|
894
|
+
*/
|
|
895
|
+
class ButtonComponent {
|
|
896
|
+
/**
|
|
897
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
898
|
+
*
|
|
899
|
+
* Expected properties:
|
|
900
|
+
* - `child`: The ID of the component to render inside the button.
|
|
901
|
+
* - `variant`: Button style variant ('default', 'primary', 'borderless').
|
|
902
|
+
* - `action`: The A2UI action to dispatch on click.
|
|
903
|
+
* - `checks`: Optional validation rules.
|
|
904
|
+
*/
|
|
905
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
906
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
907
|
+
componentId = input.required(...(ngDevMode ? [{ debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
908
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
909
|
+
rendererService = inject(A2uiRendererService);
|
|
910
|
+
variant = computed$1(() => this.props()['variant']?.value() ?? 'default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
911
|
+
child = computed$1(() => this.props()['child']?.value(), ...(ngDevMode ? [{ debugName: "child" }] : /* istanbul ignore next */ []));
|
|
912
|
+
action = computed$1(() => this.props()['action']?.value(), ...(ngDevMode ? [{ debugName: "action" }] : /* istanbul ignore next */ []));
|
|
913
|
+
handleClick() {
|
|
914
|
+
const action = this.action();
|
|
915
|
+
if (action) {
|
|
916
|
+
const surface = this.rendererService.surfaceGroup?.getSurface(this.surfaceId());
|
|
917
|
+
if (surface) {
|
|
918
|
+
const dataContext = new DataContext(surface, this.dataContextPath());
|
|
919
|
+
const resolvedAction = dataContext.resolveAction(action);
|
|
920
|
+
surface.dispatchAction(resolvedAction, this.componentId());
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
925
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ButtonComponent, isStandalone: true, selector: "a2ui-v09-button", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: true, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
926
|
+
<button
|
|
927
|
+
[type]="variant() === 'primary' ? 'submit' : 'button'"
|
|
928
|
+
[class]="'a2ui-button ' + variant()"
|
|
929
|
+
(click)="handleClick()"
|
|
930
|
+
[disabled]="props()['isValid']?.value() === false"
|
|
931
|
+
>
|
|
932
|
+
@if (child()) {
|
|
933
|
+
<a2ui-v09-component-host
|
|
934
|
+
[componentKey]="child()!"
|
|
935
|
+
[surfaceId]="surfaceId()"
|
|
936
|
+
>
|
|
937
|
+
</a2ui-v09-component-host>
|
|
938
|
+
}
|
|
939
|
+
</button>
|
|
940
|
+
`, isInline: true, styles: [".a2ui-button{padding:8px 16px;border-radius:4px;border:1px solid #ccc;cursor:pointer}.a2ui-button.primary{background-color:#007bff;color:#fff;border-color:#0069d9}.a2ui-button.borderless{background:none;border:none;padding:0;color:#007bff}.a2ui-button:disabled{background-color:#e9ecef;color:#6c757d;border-color:#ced4da;cursor:not-allowed}\n"], dependencies: [{ kind: "component", type: ComponentHostComponent, selector: "a2ui-v09-component-host", inputs: ["componentKey", "surfaceId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
941
|
+
}
|
|
942
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ButtonComponent, decorators: [{
|
|
943
|
+
type: Component,
|
|
944
|
+
args: [{ selector: 'a2ui-v09-button', standalone: true, imports: [ComponentHostComponent], template: `
|
|
945
|
+
<button
|
|
946
|
+
[type]="variant() === 'primary' ? 'submit' : 'button'"
|
|
947
|
+
[class]="'a2ui-button ' + variant()"
|
|
948
|
+
(click)="handleClick()"
|
|
949
|
+
[disabled]="props()['isValid']?.value() === false"
|
|
950
|
+
>
|
|
951
|
+
@if (child()) {
|
|
952
|
+
<a2ui-v09-component-host
|
|
953
|
+
[componentKey]="child()!"
|
|
954
|
+
[surfaceId]="surfaceId()"
|
|
955
|
+
>
|
|
956
|
+
</a2ui-v09-component-host>
|
|
957
|
+
}
|
|
958
|
+
</button>
|
|
959
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".a2ui-button{padding:8px 16px;border-radius:4px;border:1px solid #ccc;cursor:pointer}.a2ui-button.primary{background-color:#007bff;color:#fff;border-color:#0069d9}.a2ui-button.borderless{background:none;border:none;padding:0;color:#007bff}.a2ui-button:disabled{background-color:#e9ecef;color:#6c757d;border-color:#ced4da;cursor:not-allowed}\n"] }]
|
|
960
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: true }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
961
|
+
|
|
962
|
+
/**
|
|
963
|
+
* Copyright 2026 Google LLC
|
|
964
|
+
*
|
|
965
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
966
|
+
* you may not use this file except in compliance with the License.
|
|
967
|
+
* You may obtain a copy of the License at
|
|
968
|
+
*
|
|
969
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
970
|
+
*
|
|
971
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
972
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
973
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
974
|
+
* See the License for the specific language governing permissions and
|
|
975
|
+
* limitations under the License.
|
|
976
|
+
*/
|
|
977
|
+
/**
|
|
978
|
+
* Angular implementation of the A2UI TextField component (v0.9).
|
|
979
|
+
*
|
|
980
|
+
* Renders a text input field with an optional label and placeholder.
|
|
981
|
+
* Updates the bound data model property on every input change.
|
|
982
|
+
*/
|
|
983
|
+
class TextFieldComponent {
|
|
984
|
+
/**
|
|
985
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
986
|
+
*
|
|
987
|
+
* Expected properties:
|
|
988
|
+
* - `value`: The current string value of the input.
|
|
989
|
+
* - `label`: Optional label text to display above the input.
|
|
990
|
+
* - `placeholder`: Hint text shown when the input is empty.
|
|
991
|
+
* - `variant`: Input type variant ('default', 'obscured' (password), 'number').
|
|
992
|
+
* - `checks`: Optional validation rules.
|
|
993
|
+
*/
|
|
994
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
995
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
996
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
997
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
998
|
+
label = computed$1(() => this.props()['label']?.value(), ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
999
|
+
value = computed$1(() => this.props()['value']?.value() || '', ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
1000
|
+
placeholder = computed$1(() => this.props()['placeholder']?.value() || '', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
1001
|
+
variant = computed$1(() => this.props()['variant']?.value(), ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
1002
|
+
inputType = computed$1(() => {
|
|
1003
|
+
switch (this.variant()) {
|
|
1004
|
+
case 'obscured':
|
|
1005
|
+
return 'password';
|
|
1006
|
+
case 'number':
|
|
1007
|
+
return 'number';
|
|
1008
|
+
default:
|
|
1009
|
+
return 'text';
|
|
1010
|
+
}
|
|
1011
|
+
}, ...(ngDevMode ? [{ debugName: "inputType" }] : /* istanbul ignore next */ []));
|
|
1012
|
+
handleInput(event) {
|
|
1013
|
+
const value = event.target.value;
|
|
1014
|
+
// Update the data path. If anything is listening to this path, it will be
|
|
1015
|
+
// notified.
|
|
1016
|
+
this.props()['value']?.onUpdate(value);
|
|
1017
|
+
}
|
|
1018
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TextFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1019
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: TextFieldComponent, isStandalone: true, selector: "a2ui-v09-text-field", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
1020
|
+
<div class="a2ui-text-field-container">
|
|
1021
|
+
@if (label()) {
|
|
1022
|
+
<label>{{ label() }}</label>
|
|
1023
|
+
}
|
|
1024
|
+
<input
|
|
1025
|
+
[type]="inputType()"
|
|
1026
|
+
[value]="value()"
|
|
1027
|
+
(input)="handleInput($event)"
|
|
1028
|
+
[placeholder]="placeholder()"
|
|
1029
|
+
[class.invalid]="props()['isValid']?.value() === false"
|
|
1030
|
+
/>
|
|
1031
|
+
@for (message of props()['validationErrors']?.value(); track message) {
|
|
1032
|
+
<div class="a2ui-error-message">{{ message }}</div>
|
|
1033
|
+
}
|
|
1034
|
+
</div>
|
|
1035
|
+
`, isInline: true, styles: [":host{display:block;flex:1;width:100%}.a2ui-text-field-container{display:flex;flex-direction:column;gap:4px;margin:4px}input{padding:8px;border:1px solid #ccc;border-radius:4px}input.invalid{border-color:red}.a2ui-error-message{color:red;font-size:12px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1036
|
+
}
|
|
1037
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TextFieldComponent, decorators: [{
|
|
1038
|
+
type: Component,
|
|
1039
|
+
args: [{ selector: 'a2ui-v09-text-field', standalone: true, imports: [], template: `
|
|
1040
|
+
<div class="a2ui-text-field-container">
|
|
1041
|
+
@if (label()) {
|
|
1042
|
+
<label>{{ label() }}</label>
|
|
1043
|
+
}
|
|
1044
|
+
<input
|
|
1045
|
+
[type]="inputType()"
|
|
1046
|
+
[value]="value()"
|
|
1047
|
+
(input)="handleInput($event)"
|
|
1048
|
+
[placeholder]="placeholder()"
|
|
1049
|
+
[class.invalid]="props()['isValid']?.value() === false"
|
|
1050
|
+
/>
|
|
1051
|
+
@for (message of props()['validationErrors']?.value(); track message) {
|
|
1052
|
+
<div class="a2ui-error-message">{{ message }}</div>
|
|
1053
|
+
}
|
|
1054
|
+
</div>
|
|
1055
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;flex:1;width:100%}.a2ui-text-field-container{display:flex;flex-direction:column;gap:4px;margin:4px}input{padding:8px;border:1px solid #ccc;border-radius:4px}input.invalid{border-color:red}.a2ui-error-message{color:red;font-size:12px}\n"] }]
|
|
1056
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
1057
|
+
|
|
1058
|
+
/**
|
|
1059
|
+
* Copyright 2026 Google LLC
|
|
1060
|
+
*
|
|
1061
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1062
|
+
* you may not use this file except in compliance with the License.
|
|
1063
|
+
* You may obtain a copy of the License at
|
|
1064
|
+
*
|
|
1065
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1066
|
+
*
|
|
1067
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1068
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1069
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1070
|
+
* See the License for the specific language governing permissions and
|
|
1071
|
+
* limitations under the License.
|
|
1072
|
+
*/
|
|
1073
|
+
/**
|
|
1074
|
+
* Angular implementation of the A2UI Image component (v0.9).
|
|
1075
|
+
*
|
|
1076
|
+
* Renders an image with configurable fit and shape variants.
|
|
1077
|
+
*/
|
|
1078
|
+
class ImageComponent {
|
|
1079
|
+
/**
|
|
1080
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
1081
|
+
*
|
|
1082
|
+
* Expected properties:
|
|
1083
|
+
* - `url`: The absolute URL of the image.
|
|
1084
|
+
* - `description`: Accessibility text for the image.
|
|
1085
|
+
* - `fit`: Object-fit mode ('cover', 'contain', 'fill', 'none', 'scale-down').
|
|
1086
|
+
* - `variant`: Style variant ('default', 'circle', 'rounded', 'icon', 'avatar', 'smallFeature', 'mediumFeature', 'largeFeature', 'header').
|
|
1087
|
+
*/
|
|
1088
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
1089
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
1090
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
1091
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
1092
|
+
url = computed$1(() => this.props()['url']?.value(), ...(ngDevMode ? [{ debugName: "url" }] : /* istanbul ignore next */ []));
|
|
1093
|
+
description = computed$1(() => this.props()['description']?.value() || '', ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
|
|
1094
|
+
fit = computed$1(() => this.props()['fit']?.value() || 'cover', ...(ngDevMode ? [{ debugName: "fit" }] : /* istanbul ignore next */ []));
|
|
1095
|
+
variant = computed$1(() => this.props()['variant']?.value() || 'default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
1096
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ImageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1097
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: ImageComponent, isStandalone: true, selector: "a2ui-v09-image", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
1098
|
+
<img
|
|
1099
|
+
[src]="url()"
|
|
1100
|
+
[alt]="description()"
|
|
1101
|
+
[style.object-fit]="fit()"
|
|
1102
|
+
[class]="'a2ui-image ' + variant()"
|
|
1103
|
+
/>
|
|
1104
|
+
`, isInline: true, styles: [".a2ui-image{display:block;max-width:100%;height:auto}.a2ui-image.circle{border-radius:50%;aspect-ratio:1 / 1}.a2ui-image.rounded{border-radius:8px}.a2ui-image.icon{width:24px;height:24px}.a2ui-image.avatar{width:40px;height:40px;border-radius:50%}.a2ui-image.smallFeature{width:100px;height:100px}.a2ui-image.mediumFeature{max-width:300px;height:auto}.a2ui-image.largeFeature{width:100%;max-height:400px}.a2ui-image.header{width:100%;height:200px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1105
|
+
}
|
|
1106
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ImageComponent, decorators: [{
|
|
1107
|
+
type: Component,
|
|
1108
|
+
args: [{ selector: 'a2ui-v09-image', standalone: true, imports: [], template: `
|
|
1109
|
+
<img
|
|
1110
|
+
[src]="url()"
|
|
1111
|
+
[alt]="description()"
|
|
1112
|
+
[style.object-fit]="fit()"
|
|
1113
|
+
[class]="'a2ui-image ' + variant()"
|
|
1114
|
+
/>
|
|
1115
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".a2ui-image{display:block;max-width:100%;height:auto}.a2ui-image.circle{border-radius:50%;aspect-ratio:1 / 1}.a2ui-image.rounded{border-radius:8px}.a2ui-image.icon{width:24px;height:24px}.a2ui-image.avatar{width:40px;height:40px;border-radius:50%}.a2ui-image.smallFeature{width:100px;height:100px}.a2ui-image.mediumFeature{max-width:300px;height:auto}.a2ui-image.largeFeature{width:100%;max-height:400px}.a2ui-image.header{width:100%;height:200px}\n"] }]
|
|
1116
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
1117
|
+
|
|
1118
|
+
/**
|
|
1119
|
+
* Copyright 2026 Google LLC
|
|
1120
|
+
*
|
|
1121
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1122
|
+
* you may not use this file except in compliance with the License.
|
|
1123
|
+
* You may obtain a copy of the License at
|
|
1124
|
+
*
|
|
1125
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1126
|
+
*
|
|
1127
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1128
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1129
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1130
|
+
* See the License for the specific language governing permissions and
|
|
1131
|
+
* limitations under the License.
|
|
1132
|
+
*/
|
|
1133
|
+
/**
|
|
1134
|
+
* Angular implementation of the A2UI Icon component (v0.9).
|
|
1135
|
+
*
|
|
1136
|
+
* Supports both Material Icons (by name) and custom SVG icons (by path).
|
|
1137
|
+
*/
|
|
1138
|
+
class IconComponent {
|
|
1139
|
+
/**
|
|
1140
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
1141
|
+
*
|
|
1142
|
+
* Expected properties:
|
|
1143
|
+
* - `name`: The name of the icon (e.g., 'home', 'settings') OR an object
|
|
1144
|
+
* with a `path` property for SVG icons.
|
|
1145
|
+
* - `color`: The CSS color to apply to the icon.
|
|
1146
|
+
*/
|
|
1147
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
1148
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
1149
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
1150
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
1151
|
+
color = computed$1(() => this.props()['color']?.value(), ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
1152
|
+
iconNameRaw = computed$1(() => this.props()['name']?.value(), ...(ngDevMode ? [{ debugName: "iconNameRaw" }] : /* istanbul ignore next */ []));
|
|
1153
|
+
isPath = computed$1(() => {
|
|
1154
|
+
const name = this.iconNameRaw();
|
|
1155
|
+
return typeof name === 'object' && name !== null && 'path' in name;
|
|
1156
|
+
}, ...(ngDevMode ? [{ debugName: "isPath" }] : /* istanbul ignore next */ []));
|
|
1157
|
+
path = computed$1(() => {
|
|
1158
|
+
const name = this.iconNameRaw();
|
|
1159
|
+
return name?.path || '';
|
|
1160
|
+
}, ...(ngDevMode ? [{ debugName: "path" }] : /* istanbul ignore next */ []));
|
|
1161
|
+
iconName = computed$1(() => {
|
|
1162
|
+
const name = this.iconNameRaw();
|
|
1163
|
+
if (typeof name !== 'string')
|
|
1164
|
+
return '';
|
|
1165
|
+
// Convert camelCase to snake_case for Material Icons
|
|
1166
|
+
return name.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
1167
|
+
}, ...(ngDevMode ? [{ debugName: "iconName" }] : /* istanbul ignore next */ []));
|
|
1168
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1169
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: IconComponent, isStandalone: true, selector: "a2ui-v09-icon", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
1170
|
+
@if (isPath()) {
|
|
1171
|
+
<svg class="a2ui-icon svg" viewBox="0 0 24 24" [style.fill]="color() || 'currentColor'">
|
|
1172
|
+
<path [attr.d]="path()"></path>
|
|
1173
|
+
</svg>
|
|
1174
|
+
} @else {
|
|
1175
|
+
<i class="material-icons a2ui-icon" [style.color]="color()">
|
|
1176
|
+
{{ iconName() }}
|
|
1177
|
+
</i>
|
|
1178
|
+
}
|
|
1179
|
+
`, isInline: true, styles: [".a2ui-icon{display:inline-block;width:24px;height:24px;font-size:24px;font-family:Material Icons;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:\"liga\";vertical-align:middle}.a2ui-icon.svg{fill:currentColor}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1180
|
+
}
|
|
1181
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: IconComponent, decorators: [{
|
|
1182
|
+
type: Component,
|
|
1183
|
+
args: [{ selector: 'a2ui-v09-icon', standalone: true, imports: [], template: `
|
|
1184
|
+
@if (isPath()) {
|
|
1185
|
+
<svg class="a2ui-icon svg" viewBox="0 0 24 24" [style.fill]="color() || 'currentColor'">
|
|
1186
|
+
<path [attr.d]="path()"></path>
|
|
1187
|
+
</svg>
|
|
1188
|
+
} @else {
|
|
1189
|
+
<i class="material-icons a2ui-icon" [style.color]="color()">
|
|
1190
|
+
{{ iconName() }}
|
|
1191
|
+
</i>
|
|
1192
|
+
}
|
|
1193
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".a2ui-icon{display:inline-block;width:24px;height:24px;font-size:24px;font-family:Material Icons;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:\"liga\";vertical-align:middle}.a2ui-icon.svg{fill:currentColor}\n"] }]
|
|
1194
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
1195
|
+
|
|
1196
|
+
/**
|
|
1197
|
+
* Copyright 2026 Google LLC
|
|
1198
|
+
*
|
|
1199
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1200
|
+
* you may not use this file except in compliance with the License.
|
|
1201
|
+
* You may obtain a copy of the License at
|
|
1202
|
+
*
|
|
1203
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1204
|
+
*
|
|
1205
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1206
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1207
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1208
|
+
* See the License for the specific language governing permissions and
|
|
1209
|
+
* limitations under the License.
|
|
1210
|
+
*/
|
|
1211
|
+
/**
|
|
1212
|
+
* Angular implementation of the A2UI Video component (v0.9).
|
|
1213
|
+
*
|
|
1214
|
+
* Renders a video player with standard controls and an optional poster image.
|
|
1215
|
+
*/
|
|
1216
|
+
class VideoComponent {
|
|
1217
|
+
/**
|
|
1218
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
1219
|
+
*
|
|
1220
|
+
* Expected properties:
|
|
1221
|
+
* - `url`: The absolute URL of the video file.
|
|
1222
|
+
* - `posterUrl`: The URL of an image to show before the video starts.
|
|
1223
|
+
*/
|
|
1224
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
1225
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
1226
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
1227
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
1228
|
+
url = computed$1(() => this.props()['url']?.value(), ...(ngDevMode ? [{ debugName: "url" }] : /* istanbul ignore next */ []));
|
|
1229
|
+
posterUrl = computed$1(() => this.props()['posterUrl']?.value(), ...(ngDevMode ? [{ debugName: "posterUrl" }] : /* istanbul ignore next */ []));
|
|
1230
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: VideoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1231
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: VideoComponent, isStandalone: true, selector: "a2ui-v09-video", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
1232
|
+
<div class="a2ui-video-container">
|
|
1233
|
+
<video
|
|
1234
|
+
[attr.src]="url() || null"
|
|
1235
|
+
controls
|
|
1236
|
+
[attr.poster]="posterUrl() || null"
|
|
1237
|
+
class="a2ui-video"
|
|
1238
|
+
>
|
|
1239
|
+
Your browser does not support the video tag.
|
|
1240
|
+
</video>
|
|
1241
|
+
</div>
|
|
1242
|
+
`, isInline: true, styles: [".a2ui-video-container{width:100%;max-width:100%}.a2ui-video{width:100%;height:auto;display:block}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1243
|
+
}
|
|
1244
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: VideoComponent, decorators: [{
|
|
1245
|
+
type: Component,
|
|
1246
|
+
args: [{ selector: 'a2ui-v09-video', standalone: true, imports: [], template: `
|
|
1247
|
+
<div class="a2ui-video-container">
|
|
1248
|
+
<video
|
|
1249
|
+
[attr.src]="url() || null"
|
|
1250
|
+
controls
|
|
1251
|
+
[attr.poster]="posterUrl() || null"
|
|
1252
|
+
class="a2ui-video"
|
|
1253
|
+
>
|
|
1254
|
+
Your browser does not support the video tag.
|
|
1255
|
+
</video>
|
|
1256
|
+
</div>
|
|
1257
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".a2ui-video-container{width:100%;max-width:100%}.a2ui-video{width:100%;height:auto;display:block}\n"] }]
|
|
1258
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
1259
|
+
|
|
1260
|
+
/**
|
|
1261
|
+
* Copyright 2026 Google LLC
|
|
1262
|
+
*
|
|
1263
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1264
|
+
* you may not use this file except in compliance with the License.
|
|
1265
|
+
* You may obtain a copy of the License at
|
|
1266
|
+
*
|
|
1267
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1268
|
+
*
|
|
1269
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1270
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1271
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1272
|
+
* See the License for the specific language governing permissions and
|
|
1273
|
+
* limitations under the License.
|
|
1274
|
+
*/
|
|
1275
|
+
/**
|
|
1276
|
+
* Angular implementation of the A2UI AudioPlayer component (v0.9).
|
|
1277
|
+
*
|
|
1278
|
+
* Renders an audio player with standard controls and an optional description.
|
|
1279
|
+
*/
|
|
1280
|
+
class AudioPlayerComponent {
|
|
1281
|
+
/**
|
|
1282
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
1283
|
+
*
|
|
1284
|
+
* Expected properties:
|
|
1285
|
+
* - `url`: The absolute URL of the audio file.
|
|
1286
|
+
* - `description`: Optional text to display above the player.
|
|
1287
|
+
*/
|
|
1288
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
1289
|
+
surfaceId = input(...(ngDevMode ? [undefined, { debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
1290
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
1291
|
+
dataContextPath = input(...(ngDevMode ? [undefined, { debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
1292
|
+
description = computed$1(() => this.props()['description']?.value(), ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
|
|
1293
|
+
url = computed$1(() => this.props()['url']?.value(), ...(ngDevMode ? [{ debugName: "url" }] : /* istanbul ignore next */ []));
|
|
1294
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AudioPlayerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1295
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: AudioPlayerComponent, isStandalone: true, selector: "a2ui-v09-audio-player", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: false, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
1296
|
+
<div class="a2ui-audio-player">
|
|
1297
|
+
@if (description()) {
|
|
1298
|
+
<div class="a2ui-audio-description">
|
|
1299
|
+
{{ description() }}
|
|
1300
|
+
</div>
|
|
1301
|
+
}
|
|
1302
|
+
<audio [attr.src]="url() || null" controls class="a2ui-audio">
|
|
1303
|
+
Your browser does not support the audio tag.
|
|
1304
|
+
</audio>
|
|
1305
|
+
</div>
|
|
1306
|
+
`, isInline: true, styles: [".a2ui-audio-player{display:flex;flex-direction:column;gap:8px;width:100%}.a2ui-audio-description{font-size:14px;color:#666}.a2ui-audio{width:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1307
|
+
}
|
|
1308
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AudioPlayerComponent, decorators: [{
|
|
1309
|
+
type: Component,
|
|
1310
|
+
args: [{ selector: 'a2ui-v09-audio-player', standalone: true, imports: [], template: `
|
|
1311
|
+
<div class="a2ui-audio-player">
|
|
1312
|
+
@if (description()) {
|
|
1313
|
+
<div class="a2ui-audio-description">
|
|
1314
|
+
{{ description() }}
|
|
1315
|
+
</div>
|
|
1316
|
+
}
|
|
1317
|
+
<audio [attr.src]="url() || null" controls class="a2ui-audio">
|
|
1318
|
+
Your browser does not support the audio tag.
|
|
1319
|
+
</audio>
|
|
1320
|
+
</div>
|
|
1321
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".a2ui-audio-player{display:flex;flex-direction:column;gap:8px;width:100%}.a2ui-audio-description{font-size:14px;color:#666}.a2ui-audio{width:100%}\n"] }]
|
|
1322
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: false }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
1323
|
+
|
|
1324
|
+
/**
|
|
1325
|
+
* Copyright 2026 Google LLC
|
|
1326
|
+
*
|
|
1327
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1328
|
+
* you may not use this file except in compliance with the License.
|
|
1329
|
+
* You may obtain a copy of the License at
|
|
1330
|
+
*
|
|
1331
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1332
|
+
*
|
|
1333
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1334
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1335
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1336
|
+
* See the License for the specific language governing permissions and
|
|
1337
|
+
* limitations under the License.
|
|
1338
|
+
*/
|
|
1339
|
+
/**
|
|
1340
|
+
* Angular implementation of the A2UI List component (v0.9).
|
|
1341
|
+
*
|
|
1342
|
+
* Renders a list of child components with support for ordered, unordered,
|
|
1343
|
+
* and unstyled layouts in both vertical and horizontal orientations.
|
|
1344
|
+
*/
|
|
1345
|
+
class ListComponent {
|
|
1346
|
+
/**
|
|
1347
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
1348
|
+
*
|
|
1349
|
+
* Expected properties:
|
|
1350
|
+
* - `children`: A list of component IDs to render as list items.
|
|
1351
|
+
* - `listStyle`: The type of list ('ordered', 'unordered', 'none').
|
|
1352
|
+
* - `orientation`: The layout direction ('vertical', 'horizontal').
|
|
1353
|
+
*/
|
|
1354
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
1355
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
1356
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
1357
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
1358
|
+
listStyle = computed$1(() => this.props()['listStyle']?.value(), ...(ngDevMode ? [{ debugName: "listStyle" }] : /* istanbul ignore next */ []));
|
|
1359
|
+
orientation = computed$1(() => this.props()['orientation']?.value() || 'vertical', ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
|
|
1360
|
+
children = computed$1(() => {
|
|
1361
|
+
const raw = this.props()['children']?.value();
|
|
1362
|
+
return Array.isArray(raw) ? raw : [];
|
|
1363
|
+
}, ...(ngDevMode ? [{ debugName: "children" }] : /* istanbul ignore next */ []));
|
|
1364
|
+
listTag = computed$1(() => {
|
|
1365
|
+
const style = this.listStyle();
|
|
1366
|
+
if (style === 'ordered')
|
|
1367
|
+
return 'ol';
|
|
1368
|
+
if (style === 'unordered')
|
|
1369
|
+
return 'ul';
|
|
1370
|
+
return 'div';
|
|
1371
|
+
}, ...(ngDevMode ? [{ debugName: "listTag" }] : /* istanbul ignore next */ []));
|
|
1372
|
+
styleType = computed$1(() => {
|
|
1373
|
+
const style = this.listStyle();
|
|
1374
|
+
if (style === 'none')
|
|
1375
|
+
return 'none';
|
|
1376
|
+
return '';
|
|
1377
|
+
}, ...(ngDevMode ? [{ debugName: "styleType" }] : /* istanbul ignore next */ []));
|
|
1378
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1379
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ListComponent, isStandalone: true, selector: "a2ui-v09-list", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
1380
|
+
@switch (listTag()) {
|
|
1381
|
+
@case ('ol') {
|
|
1382
|
+
<ol [class]="'a2ui-list ' + orientation()" [style.list-style-type]="styleType()">
|
|
1383
|
+
@for (child of children(); track child.id) {
|
|
1384
|
+
<li>
|
|
1385
|
+
<a2ui-v09-component-host
|
|
1386
|
+
[componentKey]="child"
|
|
1387
|
+
[surfaceId]="surfaceId()"
|
|
1388
|
+
>
|
|
1389
|
+
</a2ui-v09-component-host>
|
|
1390
|
+
</li>
|
|
1391
|
+
}
|
|
1392
|
+
</ol>
|
|
1393
|
+
}
|
|
1394
|
+
@case ('ul') {
|
|
1395
|
+
<ul [class]="'a2ui-list ' + orientation()" [style.list-style-type]="styleType()">
|
|
1396
|
+
@for (child of children(); track child.id) {
|
|
1397
|
+
<li>
|
|
1398
|
+
<a2ui-v09-component-host
|
|
1399
|
+
[componentKey]="child"
|
|
1400
|
+
[surfaceId]="surfaceId()"
|
|
1401
|
+
>
|
|
1402
|
+
</a2ui-v09-component-host>
|
|
1403
|
+
</li>
|
|
1404
|
+
}
|
|
1405
|
+
</ul>
|
|
1406
|
+
}
|
|
1407
|
+
@default {
|
|
1408
|
+
<div [class]="'a2ui-list ' + orientation()" style="list-style-type: none;">
|
|
1409
|
+
@for (child of children(); track child.id) {
|
|
1410
|
+
<div class="a2ui-list-item-none">
|
|
1411
|
+
<a2ui-v09-component-host
|
|
1412
|
+
[componentKey]="child"
|
|
1413
|
+
[surfaceId]="surfaceId()"
|
|
1414
|
+
>
|
|
1415
|
+
</a2ui-v09-component-host>
|
|
1416
|
+
</div>
|
|
1417
|
+
}
|
|
1418
|
+
</div>
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
`, isInline: true, styles: [".a2ui-list{display:flex;padding-inline-start:24px;margin:0}.a2ui-list.vertical{flex-direction:column;gap:8px}.a2ui-list.horizontal{flex-direction:row;gap:16px;list-style-position:inside}.a2ui-list-item-none{display:block}.horizontal .a2ui-list-item-none{display:inline-block}\n"], dependencies: [{ kind: "component", type: ComponentHostComponent, selector: "a2ui-v09-component-host", inputs: ["componentKey", "surfaceId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1422
|
+
}
|
|
1423
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ListComponent, decorators: [{
|
|
1424
|
+
type: Component,
|
|
1425
|
+
args: [{ selector: 'a2ui-v09-list', standalone: true, imports: [ComponentHostComponent], template: `
|
|
1426
|
+
@switch (listTag()) {
|
|
1427
|
+
@case ('ol') {
|
|
1428
|
+
<ol [class]="'a2ui-list ' + orientation()" [style.list-style-type]="styleType()">
|
|
1429
|
+
@for (child of children(); track child.id) {
|
|
1430
|
+
<li>
|
|
1431
|
+
<a2ui-v09-component-host
|
|
1432
|
+
[componentKey]="child"
|
|
1433
|
+
[surfaceId]="surfaceId()"
|
|
1434
|
+
>
|
|
1435
|
+
</a2ui-v09-component-host>
|
|
1436
|
+
</li>
|
|
1437
|
+
}
|
|
1438
|
+
</ol>
|
|
1439
|
+
}
|
|
1440
|
+
@case ('ul') {
|
|
1441
|
+
<ul [class]="'a2ui-list ' + orientation()" [style.list-style-type]="styleType()">
|
|
1442
|
+
@for (child of children(); track child.id) {
|
|
1443
|
+
<li>
|
|
1444
|
+
<a2ui-v09-component-host
|
|
1445
|
+
[componentKey]="child"
|
|
1446
|
+
[surfaceId]="surfaceId()"
|
|
1447
|
+
>
|
|
1448
|
+
</a2ui-v09-component-host>
|
|
1449
|
+
</li>
|
|
1450
|
+
}
|
|
1451
|
+
</ul>
|
|
1452
|
+
}
|
|
1453
|
+
@default {
|
|
1454
|
+
<div [class]="'a2ui-list ' + orientation()" style="list-style-type: none;">
|
|
1455
|
+
@for (child of children(); track child.id) {
|
|
1456
|
+
<div class="a2ui-list-item-none">
|
|
1457
|
+
<a2ui-v09-component-host
|
|
1458
|
+
[componentKey]="child"
|
|
1459
|
+
[surfaceId]="surfaceId()"
|
|
1460
|
+
>
|
|
1461
|
+
</a2ui-v09-component-host>
|
|
1462
|
+
</div>
|
|
1463
|
+
}
|
|
1464
|
+
</div>
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".a2ui-list{display:flex;padding-inline-start:24px;margin:0}.a2ui-list.vertical{flex-direction:column;gap:8px}.a2ui-list.horizontal{flex-direction:row;gap:16px;list-style-position:inside}.a2ui-list-item-none{display:block}.horizontal .a2ui-list-item-none{display:inline-block}\n"] }]
|
|
1468
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
1469
|
+
|
|
1470
|
+
/**
|
|
1471
|
+
* Copyright 2026 Google LLC
|
|
1472
|
+
*
|
|
1473
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1474
|
+
* you may not use this file except in compliance with the License.
|
|
1475
|
+
* You may obtain a copy of the License at
|
|
1476
|
+
*
|
|
1477
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1478
|
+
*
|
|
1479
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1480
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1481
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1482
|
+
* See the License for the specific language governing permissions and
|
|
1483
|
+
* limitations under the License.
|
|
1484
|
+
*/
|
|
1485
|
+
/**
|
|
1486
|
+
* Angular implementation of the A2UI Card component (v0.9).
|
|
1487
|
+
*
|
|
1488
|
+
* Renders a container with a shadow and rounded corners for grouping related content.
|
|
1489
|
+
*/
|
|
1490
|
+
class CardComponent {
|
|
1491
|
+
/**
|
|
1492
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
1493
|
+
*
|
|
1494
|
+
* Expected properties:
|
|
1495
|
+
* - `child`: The component ID to render inside the card.
|
|
1496
|
+
*/
|
|
1497
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
1498
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
1499
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
1500
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
1501
|
+
child = computed$1(() => this.props()['child']?.value(), ...(ngDevMode ? [{ debugName: "child" }] : /* istanbul ignore next */ []));
|
|
1502
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1503
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: CardComponent, isStandalone: true, selector: "a2ui-v09-card", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
1504
|
+
<div class="a2ui-card">
|
|
1505
|
+
@if (child()) {
|
|
1506
|
+
<a2ui-v09-component-host
|
|
1507
|
+
[componentKey]="child()!"
|
|
1508
|
+
[surfaceId]="surfaceId()"
|
|
1509
|
+
>
|
|
1510
|
+
</a2ui-v09-component-host>
|
|
1511
|
+
}
|
|
1512
|
+
</div>
|
|
1513
|
+
`, isInline: true, styles: [".a2ui-card{padding:16px;border-radius:8px;box-shadow:0 4px 6px #0000001a;background-color:#fff;border:1px solid #eee}\n"], dependencies: [{ kind: "component", type: ComponentHostComponent, selector: "a2ui-v09-component-host", inputs: ["componentKey", "surfaceId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1514
|
+
}
|
|
1515
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardComponent, decorators: [{
|
|
1516
|
+
type: Component,
|
|
1517
|
+
args: [{ selector: 'a2ui-v09-card', standalone: true, imports: [ComponentHostComponent], template: `
|
|
1518
|
+
<div class="a2ui-card">
|
|
1519
|
+
@if (child()) {
|
|
1520
|
+
<a2ui-v09-component-host
|
|
1521
|
+
[componentKey]="child()!"
|
|
1522
|
+
[surfaceId]="surfaceId()"
|
|
1523
|
+
>
|
|
1524
|
+
</a2ui-v09-component-host>
|
|
1525
|
+
}
|
|
1526
|
+
</div>
|
|
1527
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".a2ui-card{padding:16px;border-radius:8px;box-shadow:0 4px 6px #0000001a;background-color:#fff;border:1px solid #eee}\n"] }]
|
|
1528
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
1529
|
+
|
|
1530
|
+
/**
|
|
1531
|
+
* Copyright 2026 Google LLC
|
|
1532
|
+
*
|
|
1533
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1534
|
+
* you may not use this file except in compliance with the License.
|
|
1535
|
+
* You may obtain a copy of the License at
|
|
1536
|
+
*
|
|
1537
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1538
|
+
*
|
|
1539
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1540
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1541
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1542
|
+
* See the License for the specific language governing permissions and
|
|
1543
|
+
* limitations under the License.
|
|
1544
|
+
*/
|
|
1545
|
+
/**
|
|
1546
|
+
* Angular implementation of the A2UI Tabs component (v0.9).
|
|
1547
|
+
*
|
|
1548
|
+
* Renders a set of tabs where each tab has a label and associated content.
|
|
1549
|
+
* Manages the active tab state internally.
|
|
1550
|
+
*/
|
|
1551
|
+
class TabsComponent {
|
|
1552
|
+
/**
|
|
1553
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
1554
|
+
*
|
|
1555
|
+
* Expected properties:
|
|
1556
|
+
* - `tabs`: A list of tab objects, each containing a `label` and `content` ID.
|
|
1557
|
+
*/
|
|
1558
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
1559
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
1560
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
1561
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
1562
|
+
activeTabIndex = signal(0, ...(ngDevMode ? [{ debugName: "activeTabIndex" }] : /* istanbul ignore next */ []));
|
|
1563
|
+
tabs = computed$1(() => this.props()['tabs']?.value() || [], ...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
|
|
1564
|
+
activeTab = computed$1(() => this.tabs()[this.activeTabIndex()], ...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
|
|
1565
|
+
normalizedActiveTabContent = computed$1(() => {
|
|
1566
|
+
const content = this.activeTab()?.content;
|
|
1567
|
+
if (!content)
|
|
1568
|
+
return null;
|
|
1569
|
+
if (typeof content === 'object' && content !== null && 'id' in content) {
|
|
1570
|
+
return content;
|
|
1571
|
+
}
|
|
1572
|
+
return { id: content, basePath: this.dataContextPath() };
|
|
1573
|
+
}, ...(ngDevMode ? [{ debugName: "normalizedActiveTabContent" }] : /* istanbul ignore next */ []));
|
|
1574
|
+
setActiveTab(index) {
|
|
1575
|
+
this.activeTabIndex.set(index);
|
|
1576
|
+
}
|
|
1577
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1578
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: TabsComponent, isStandalone: true, selector: "a2ui-v09-tabs", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
1579
|
+
<div class="a2ui-tabs">
|
|
1580
|
+
<div class="a2ui-tab-bar">
|
|
1581
|
+
@for (tab of tabs(); track tab; let i = $index) {
|
|
1582
|
+
<button
|
|
1583
|
+
class="a2ui-tab-button"
|
|
1584
|
+
[class.active]="activeTabIndex() === i"
|
|
1585
|
+
(click)="setActiveTab(i)"
|
|
1586
|
+
>
|
|
1587
|
+
{{ tab.label }}
|
|
1588
|
+
</button>
|
|
1589
|
+
}
|
|
1590
|
+
</div>
|
|
1591
|
+
@if (normalizedActiveTabContent()) {
|
|
1592
|
+
<div class="a2ui-tab-content">
|
|
1593
|
+
<a2ui-v09-component-host
|
|
1594
|
+
[componentKey]="normalizedActiveTabContent()!"
|
|
1595
|
+
[surfaceId]="surfaceId()"
|
|
1596
|
+
>
|
|
1597
|
+
</a2ui-v09-component-host>
|
|
1598
|
+
</div>
|
|
1599
|
+
}
|
|
1600
|
+
</div>
|
|
1601
|
+
`, isInline: true, styles: [".a2ui-tabs{display:flex;flex-direction:column;width:100%}.a2ui-tab-bar{display:flex;border-bottom:2px solid #eee;gap:16px}.a2ui-tab-button{padding:8px 16px;border:none;background:none;cursor:pointer;font-weight:500;color:#666;border-bottom:2px solid transparent;margin-bottom:-2px}.a2ui-tab-button.active{color:#007bff;border-bottom:2px solid #007bff}.a2ui-tab-content{padding:16px 0}\n"], dependencies: [{ kind: "component", type: ComponentHostComponent, selector: "a2ui-v09-component-host", inputs: ["componentKey", "surfaceId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1602
|
+
}
|
|
1603
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TabsComponent, decorators: [{
|
|
1604
|
+
type: Component,
|
|
1605
|
+
args: [{ selector: 'a2ui-v09-tabs', standalone: true, imports: [ComponentHostComponent], template: `
|
|
1606
|
+
<div class="a2ui-tabs">
|
|
1607
|
+
<div class="a2ui-tab-bar">
|
|
1608
|
+
@for (tab of tabs(); track tab; let i = $index) {
|
|
1609
|
+
<button
|
|
1610
|
+
class="a2ui-tab-button"
|
|
1611
|
+
[class.active]="activeTabIndex() === i"
|
|
1612
|
+
(click)="setActiveTab(i)"
|
|
1613
|
+
>
|
|
1614
|
+
{{ tab.label }}
|
|
1615
|
+
</button>
|
|
1616
|
+
}
|
|
1617
|
+
</div>
|
|
1618
|
+
@if (normalizedActiveTabContent()) {
|
|
1619
|
+
<div class="a2ui-tab-content">
|
|
1620
|
+
<a2ui-v09-component-host
|
|
1621
|
+
[componentKey]="normalizedActiveTabContent()!"
|
|
1622
|
+
[surfaceId]="surfaceId()"
|
|
1623
|
+
>
|
|
1624
|
+
</a2ui-v09-component-host>
|
|
1625
|
+
</div>
|
|
1626
|
+
}
|
|
1627
|
+
</div>
|
|
1628
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".a2ui-tabs{display:flex;flex-direction:column;width:100%}.a2ui-tab-bar{display:flex;border-bottom:2px solid #eee;gap:16px}.a2ui-tab-button{padding:8px 16px;border:none;background:none;cursor:pointer;font-weight:500;color:#666;border-bottom:2px solid transparent;margin-bottom:-2px}.a2ui-tab-button.active{color:#007bff;border-bottom:2px solid #007bff}.a2ui-tab-content{padding:16px 0}\n"] }]
|
|
1629
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
1630
|
+
|
|
1631
|
+
/**
|
|
1632
|
+
* Copyright 2026 Google LLC
|
|
1633
|
+
*
|
|
1634
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1635
|
+
* you may not use this file except in compliance with the License.
|
|
1636
|
+
* You may obtain a copy of the License at
|
|
1637
|
+
*
|
|
1638
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1639
|
+
*
|
|
1640
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1641
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1642
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1643
|
+
* See the License for the specific language governing permissions and
|
|
1644
|
+
* limitations under the License.
|
|
1645
|
+
*/
|
|
1646
|
+
/**
|
|
1647
|
+
* Angular implementation of the A2UI Modal component (v0.9).
|
|
1648
|
+
*
|
|
1649
|
+
* Renders a trigger component that opening an overlay containing a content component.
|
|
1650
|
+
*/
|
|
1651
|
+
class ModalComponent {
|
|
1652
|
+
/**
|
|
1653
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
1654
|
+
*
|
|
1655
|
+
* Expected properties:
|
|
1656
|
+
* - `trigger`: The ID of the component that opens the modal.
|
|
1657
|
+
* - `content`: The ID of the component to display inside the modal.
|
|
1658
|
+
*/
|
|
1659
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
1660
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
1661
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
1662
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
1663
|
+
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
1664
|
+
trigger = computed$1(() => this.props()['trigger']?.value(), ...(ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []));
|
|
1665
|
+
content = computed$1(() => this.props()['content']?.value(), ...(ngDevMode ? [{ debugName: "content" }] : /* istanbul ignore next */ []));
|
|
1666
|
+
openModal() {
|
|
1667
|
+
this.isOpen.set(true);
|
|
1668
|
+
}
|
|
1669
|
+
closeModal() {
|
|
1670
|
+
this.isOpen.set(false);
|
|
1671
|
+
}
|
|
1672
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1673
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ModalComponent, isStandalone: true, selector: "a2ui-v09-modal", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
1674
|
+
<div class="a2ui-modal-wrapper">
|
|
1675
|
+
<div (click)="openModal()" class="a2ui-modal-trigger">
|
|
1676
|
+
@if (trigger()) {
|
|
1677
|
+
<a2ui-v09-component-host
|
|
1678
|
+
[componentKey]="trigger()!"
|
|
1679
|
+
[surfaceId]="surfaceId()"
|
|
1680
|
+
>
|
|
1681
|
+
</a2ui-v09-component-host>
|
|
1682
|
+
}
|
|
1683
|
+
</div>
|
|
1684
|
+
|
|
1685
|
+
@if (isOpen()) {
|
|
1686
|
+
<div class="a2ui-modal-overlay" (click)="closeModal()">
|
|
1687
|
+
<div class="a2ui-modal-content" (click)="$event.stopPropagation()">
|
|
1688
|
+
<button class="a2ui-modal-close" (click)="closeModal()">×</button>
|
|
1689
|
+
@if (content()) {
|
|
1690
|
+
<a2ui-v09-component-host
|
|
1691
|
+
[componentKey]="content()!"
|
|
1692
|
+
[surfaceId]="surfaceId()"
|
|
1693
|
+
>
|
|
1694
|
+
</a2ui-v09-component-host>
|
|
1695
|
+
}
|
|
1696
|
+
</div>
|
|
1697
|
+
</div>
|
|
1698
|
+
}
|
|
1699
|
+
</div>
|
|
1700
|
+
`, isInline: true, styles: [".a2ui-modal-wrapper{display:inline-block}.a2ui-modal-trigger{cursor:pointer}.a2ui-modal-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#00000080;display:flex;justify-content:center;align-items:center;z-index:1000}.a2ui-modal-content{background:#fff;padding:32px;border-radius:8px;position:relative;min-width:300px;max-width:80%;max-height:80%;overflow-y:auto;box-shadow:0 10px 25px #0003}.a2ui-modal-close{position:absolute;top:10px;right:15px;border:none;background:none;font-size:24px;cursor:pointer;color:#999}.a2ui-modal-close:hover{color:#333}\n"], dependencies: [{ kind: "component", type: ComponentHostComponent, selector: "a2ui-v09-component-host", inputs: ["componentKey", "surfaceId"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1701
|
+
}
|
|
1702
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ModalComponent, decorators: [{
|
|
1703
|
+
type: Component,
|
|
1704
|
+
args: [{ selector: 'a2ui-v09-modal', standalone: true, imports: [ComponentHostComponent], template: `
|
|
1705
|
+
<div class="a2ui-modal-wrapper">
|
|
1706
|
+
<div (click)="openModal()" class="a2ui-modal-trigger">
|
|
1707
|
+
@if (trigger()) {
|
|
1708
|
+
<a2ui-v09-component-host
|
|
1709
|
+
[componentKey]="trigger()!"
|
|
1710
|
+
[surfaceId]="surfaceId()"
|
|
1711
|
+
>
|
|
1712
|
+
</a2ui-v09-component-host>
|
|
1713
|
+
}
|
|
1714
|
+
</div>
|
|
1715
|
+
|
|
1716
|
+
@if (isOpen()) {
|
|
1717
|
+
<div class="a2ui-modal-overlay" (click)="closeModal()">
|
|
1718
|
+
<div class="a2ui-modal-content" (click)="$event.stopPropagation()">
|
|
1719
|
+
<button class="a2ui-modal-close" (click)="closeModal()">×</button>
|
|
1720
|
+
@if (content()) {
|
|
1721
|
+
<a2ui-v09-component-host
|
|
1722
|
+
[componentKey]="content()!"
|
|
1723
|
+
[surfaceId]="surfaceId()"
|
|
1724
|
+
>
|
|
1725
|
+
</a2ui-v09-component-host>
|
|
1726
|
+
}
|
|
1727
|
+
</div>
|
|
1728
|
+
</div>
|
|
1729
|
+
}
|
|
1730
|
+
</div>
|
|
1731
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".a2ui-modal-wrapper{display:inline-block}.a2ui-modal-trigger{cursor:pointer}.a2ui-modal-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#00000080;display:flex;justify-content:center;align-items:center;z-index:1000}.a2ui-modal-content{background:#fff;padding:32px;border-radius:8px;position:relative;min-width:300px;max-width:80%;max-height:80%;overflow-y:auto;box-shadow:0 10px 25px #0003}.a2ui-modal-close{position:absolute;top:10px;right:15px;border:none;background:none;font-size:24px;cursor:pointer;color:#999}.a2ui-modal-close:hover{color:#333}\n"] }]
|
|
1732
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
1733
|
+
|
|
1734
|
+
/**
|
|
1735
|
+
* Copyright 2026 Google LLC
|
|
1736
|
+
*
|
|
1737
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1738
|
+
* you may not use this file except in compliance with the License.
|
|
1739
|
+
* You may obtain a copy of the License at
|
|
1740
|
+
*
|
|
1741
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1742
|
+
*
|
|
1743
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1744
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1745
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1746
|
+
* See the License for the specific language governing permissions and
|
|
1747
|
+
* limitations under the License.
|
|
1748
|
+
*/
|
|
1749
|
+
/**
|
|
1750
|
+
* Angular implementation of the A2UI Divider component (v0.9).
|
|
1751
|
+
*
|
|
1752
|
+
* Renders a horizontal or vertical line to separate content.
|
|
1753
|
+
*/
|
|
1754
|
+
class DividerComponent {
|
|
1755
|
+
/**
|
|
1756
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
1757
|
+
*
|
|
1758
|
+
* Expected properties:
|
|
1759
|
+
* - `axis`: The orientation of the divider ('horizontal' (default) or 'vertical').
|
|
1760
|
+
*/
|
|
1761
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
1762
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
1763
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
1764
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
1765
|
+
axis = computed$1(() => this.props()['axis']?.value() ?? 'horizontal', ...(ngDevMode ? [{ debugName: "axis" }] : /* istanbul ignore next */ []));
|
|
1766
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DividerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1767
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: DividerComponent, isStandalone: true, selector: "a2ui-v09-divider", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
1768
|
+
<hr
|
|
1769
|
+
class="a2ui-divider"
|
|
1770
|
+
[class.horizontal]="axis() === 'horizontal'"
|
|
1771
|
+
[class.vertical]="axis() === 'vertical'"
|
|
1772
|
+
/>
|
|
1773
|
+
`, isInline: true, styles: [".a2ui-divider{border:0;border-top:1px solid #eee;margin:16px 0;width:100%}.a2ui-divider.vertical{width:1px;height:100%;margin:0 16px;border-top:0;border-left:1px solid #eee}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1774
|
+
}
|
|
1775
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DividerComponent, decorators: [{
|
|
1776
|
+
type: Component,
|
|
1777
|
+
args: [{ selector: 'a2ui-v09-divider', standalone: true, imports: [], template: `
|
|
1778
|
+
<hr
|
|
1779
|
+
class="a2ui-divider"
|
|
1780
|
+
[class.horizontal]="axis() === 'horizontal'"
|
|
1781
|
+
[class.vertical]="axis() === 'vertical'"
|
|
1782
|
+
/>
|
|
1783
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".a2ui-divider{border:0;border-top:1px solid #eee;margin:16px 0;width:100%}.a2ui-divider.vertical{width:1px;height:100%;margin:0 16px;border-top:0;border-left:1px solid #eee}\n"] }]
|
|
1784
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
1785
|
+
|
|
1786
|
+
/**
|
|
1787
|
+
* Copyright 2026 Google LLC
|
|
1788
|
+
*
|
|
1789
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1790
|
+
* you may not use this file except in compliance with the License.
|
|
1791
|
+
* You may obtain a copy of the License at
|
|
1792
|
+
*
|
|
1793
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1794
|
+
*
|
|
1795
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1796
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1797
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1798
|
+
* See the License for the specific language governing permissions and
|
|
1799
|
+
* limitations under the License.
|
|
1800
|
+
*/
|
|
1801
|
+
/**
|
|
1802
|
+
* Angular implementation of the A2UI CheckBox component (v0.9).
|
|
1803
|
+
*
|
|
1804
|
+
* Renders a checkbox with a label. Updates the bound data model property
|
|
1805
|
+
* when the checked state changes.
|
|
1806
|
+
*/
|
|
1807
|
+
class CheckBoxComponent {
|
|
1808
|
+
/**
|
|
1809
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
1810
|
+
*
|
|
1811
|
+
* Expected properties:
|
|
1812
|
+
* - `label`: The text to display next to the checkbox.
|
|
1813
|
+
* - `value`: Boolean indicating whether the checkbox is checked.
|
|
1814
|
+
*/
|
|
1815
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
1816
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
1817
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
1818
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
1819
|
+
value = computed$1(() => this.props()['value']?.value() === true, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
1820
|
+
label = computed$1(() => this.props()['label']?.value(), ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
1821
|
+
handleChange(event) {
|
|
1822
|
+
const checked = event.target.checked;
|
|
1823
|
+
this.props()['value']?.onUpdate(checked);
|
|
1824
|
+
}
|
|
1825
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CheckBoxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1826
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: CheckBoxComponent, isStandalone: true, selector: "a2ui-v09-check-box", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
1827
|
+
<label class="a2ui-check-box-label">
|
|
1828
|
+
<input
|
|
1829
|
+
type="checkbox"
|
|
1830
|
+
[checked]="value()"
|
|
1831
|
+
(change)="handleChange($event)"
|
|
1832
|
+
class="a2ui-check-box-input"
|
|
1833
|
+
/>
|
|
1834
|
+
<span class="a2ui-check-box-text">{{ label() }}</span>
|
|
1835
|
+
</label>
|
|
1836
|
+
`, isInline: true, styles: [".a2ui-check-box-label{display:flex;align-items:center;gap:8px;cursor:pointer;padding:4px 0}.a2ui-check-box-input{width:18px;height:18px;cursor:pointer}.a2ui-check-box-text{font-size:16px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1837
|
+
}
|
|
1838
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CheckBoxComponent, decorators: [{
|
|
1839
|
+
type: Component,
|
|
1840
|
+
args: [{ selector: 'a2ui-v09-check-box', standalone: true, imports: [], template: `
|
|
1841
|
+
<label class="a2ui-check-box-label">
|
|
1842
|
+
<input
|
|
1843
|
+
type="checkbox"
|
|
1844
|
+
[checked]="value()"
|
|
1845
|
+
(change)="handleChange($event)"
|
|
1846
|
+
class="a2ui-check-box-input"
|
|
1847
|
+
/>
|
|
1848
|
+
<span class="a2ui-check-box-text">{{ label() }}</span>
|
|
1849
|
+
</label>
|
|
1850
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".a2ui-check-box-label{display:flex;align-items:center;gap:8px;cursor:pointer;padding:4px 0}.a2ui-check-box-input{width:18px;height:18px;cursor:pointer}.a2ui-check-box-text{font-size:16px}\n"] }]
|
|
1851
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
1852
|
+
|
|
1853
|
+
/**
|
|
1854
|
+
* Copyright 2026 Google LLC
|
|
1855
|
+
*
|
|
1856
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
1857
|
+
* you may not use this file except in compliance with the License.
|
|
1858
|
+
* You may obtain a copy of the License at
|
|
1859
|
+
*
|
|
1860
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
1861
|
+
*
|
|
1862
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
1863
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
1864
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
1865
|
+
* See the License for the specific language governing permissions and
|
|
1866
|
+
* limitations under the License.
|
|
1867
|
+
*/
|
|
1868
|
+
/**
|
|
1869
|
+
* Angular implementation of the A2UI ChoicePicker component (v0.9).
|
|
1870
|
+
*
|
|
1871
|
+
* Renders a set of options as either radio buttons/checkboxes or chips.
|
|
1872
|
+
* Supports both single and multiple selection.
|
|
1873
|
+
*/
|
|
1874
|
+
class ChoicePickerComponent {
|
|
1875
|
+
/**
|
|
1876
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
1877
|
+
*
|
|
1878
|
+
* Expected properties:
|
|
1879
|
+
* - `value`: The currently selected value(s).
|
|
1880
|
+
* - `choices` or `options`: List of choice objects (label and value).
|
|
1881
|
+
* - `displayStyle`: How to render the choices ('default' or 'chips').
|
|
1882
|
+
* - `variant`: Selection mode ('singleSelection' or 'multipleSelection').
|
|
1883
|
+
*/
|
|
1884
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
1885
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
1886
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
1887
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
1888
|
+
displayStyle = computed$1(() => this.props()['displayStyle']?.value(), ...(ngDevMode ? [{ debugName: "displayStyle" }] : /* istanbul ignore next */ []));
|
|
1889
|
+
choices = computed$1(() => this.props()['choices']?.value() || this.props()['options']?.value() || [], ...(ngDevMode ? [{ debugName: "choices" }] : /* istanbul ignore next */ []));
|
|
1890
|
+
variant = computed$1(() => this.props()['variant']?.value(), ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
1891
|
+
selectedValue = computed$1(() => this.props()['value']?.value(), ...(ngDevMode ? [{ debugName: "selectedValue" }] : /* istanbul ignore next */ []));
|
|
1892
|
+
isMultiple() {
|
|
1893
|
+
return this.variant() === 'multipleSelection';
|
|
1894
|
+
}
|
|
1895
|
+
isSelected(value) {
|
|
1896
|
+
const selected = this.selectedValue();
|
|
1897
|
+
if (Array.isArray(selected)) {
|
|
1898
|
+
return selected.includes(value);
|
|
1899
|
+
}
|
|
1900
|
+
return selected === value;
|
|
1901
|
+
}
|
|
1902
|
+
onCheckChange(value, event) {
|
|
1903
|
+
const checked = event.target.checked;
|
|
1904
|
+
this.updateValue(value, checked);
|
|
1905
|
+
}
|
|
1906
|
+
toggleActive(value) {
|
|
1907
|
+
const current = this.isSelected(value);
|
|
1908
|
+
this.updateValue(value, !current);
|
|
1909
|
+
}
|
|
1910
|
+
updateValue(value, active) {
|
|
1911
|
+
const current = this.selectedValue();
|
|
1912
|
+
if (this.isMultiple()) {
|
|
1913
|
+
let next = Array.isArray(current) ? [...current] : [];
|
|
1914
|
+
if (active) {
|
|
1915
|
+
if (!next.includes(value))
|
|
1916
|
+
next.push(value);
|
|
1917
|
+
}
|
|
1918
|
+
else {
|
|
1919
|
+
next = next.filter((v) => v !== value);
|
|
1920
|
+
}
|
|
1921
|
+
this.props()['value']?.onUpdate(next);
|
|
1922
|
+
}
|
|
1923
|
+
else {
|
|
1924
|
+
if (active) {
|
|
1925
|
+
this.props()['value']?.onUpdate(value);
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ChoicePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1930
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ChoicePickerComponent, isStandalone: true, selector: "a2ui-v09-choice-picker", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
1931
|
+
<div class="a2ui-choice-picker">
|
|
1932
|
+
<!-- Chips Variant -->
|
|
1933
|
+
@if (displayStyle() === 'chips') {
|
|
1934
|
+
<div class="a2ui-chips-group">
|
|
1935
|
+
@for (choice of choices(); track choice.value) {
|
|
1936
|
+
<button
|
|
1937
|
+
class="a2ui-chip"
|
|
1938
|
+
[class.active]="isSelected(choice.value)"
|
|
1939
|
+
(click)="toggleActive(choice.value)"
|
|
1940
|
+
>
|
|
1941
|
+
{{ choice.label }}
|
|
1942
|
+
</button>
|
|
1943
|
+
}
|
|
1944
|
+
</div>
|
|
1945
|
+
} @else {
|
|
1946
|
+
<!-- Checkbox/Radio Variant -->
|
|
1947
|
+
<div class="a2ui-options-group">
|
|
1948
|
+
@for (choice of choices(); track choice.value) {
|
|
1949
|
+
<label class="a2ui-option-label">
|
|
1950
|
+
<input
|
|
1951
|
+
[type]="isMultiple() ? 'checkbox' : 'radio'"
|
|
1952
|
+
[name]="componentId()"
|
|
1953
|
+
[value]="choice.value"
|
|
1954
|
+
[checked]="isSelected(choice.value)"
|
|
1955
|
+
(change)="onCheckChange(choice.value, $event)"
|
|
1956
|
+
class="a2ui-option-input"
|
|
1957
|
+
/>
|
|
1958
|
+
<span class="a2ui-option-text">{{ choice.label }}</span>
|
|
1959
|
+
</label>
|
|
1960
|
+
}
|
|
1961
|
+
</div>
|
|
1962
|
+
}
|
|
1963
|
+
</div>
|
|
1964
|
+
`, isInline: true, styles: [".a2ui-choice-picker{width:100%}.a2ui-options-group{display:flex;flex-direction:column;gap:8px}.a2ui-option-label{display:flex;align-items:center;gap:8px;cursor:pointer}.a2ui-option-input{width:18px;height:18px}.a2ui-chips-group{display:flex;flex-wrap:wrap;gap:8px}.a2ui-chip{padding:4px 12px;border-radius:16px;border:1px solid #ccc;background:#fff;cursor:pointer;transition:all .2s}.a2ui-chip.active{background-color:#007bff;color:#fff;border-color:#007bff}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1965
|
+
}
|
|
1966
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ChoicePickerComponent, decorators: [{
|
|
1967
|
+
type: Component,
|
|
1968
|
+
args: [{ selector: 'a2ui-v09-choice-picker', standalone: true, imports: [], template: `
|
|
1969
|
+
<div class="a2ui-choice-picker">
|
|
1970
|
+
<!-- Chips Variant -->
|
|
1971
|
+
@if (displayStyle() === 'chips') {
|
|
1972
|
+
<div class="a2ui-chips-group">
|
|
1973
|
+
@for (choice of choices(); track choice.value) {
|
|
1974
|
+
<button
|
|
1975
|
+
class="a2ui-chip"
|
|
1976
|
+
[class.active]="isSelected(choice.value)"
|
|
1977
|
+
(click)="toggleActive(choice.value)"
|
|
1978
|
+
>
|
|
1979
|
+
{{ choice.label }}
|
|
1980
|
+
</button>
|
|
1981
|
+
}
|
|
1982
|
+
</div>
|
|
1983
|
+
} @else {
|
|
1984
|
+
<!-- Checkbox/Radio Variant -->
|
|
1985
|
+
<div class="a2ui-options-group">
|
|
1986
|
+
@for (choice of choices(); track choice.value) {
|
|
1987
|
+
<label class="a2ui-option-label">
|
|
1988
|
+
<input
|
|
1989
|
+
[type]="isMultiple() ? 'checkbox' : 'radio'"
|
|
1990
|
+
[name]="componentId()"
|
|
1991
|
+
[value]="choice.value"
|
|
1992
|
+
[checked]="isSelected(choice.value)"
|
|
1993
|
+
(change)="onCheckChange(choice.value, $event)"
|
|
1994
|
+
class="a2ui-option-input"
|
|
1995
|
+
/>
|
|
1996
|
+
<span class="a2ui-option-text">{{ choice.label }}</span>
|
|
1997
|
+
</label>
|
|
1998
|
+
}
|
|
1999
|
+
</div>
|
|
2000
|
+
}
|
|
2001
|
+
</div>
|
|
2002
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".a2ui-choice-picker{width:100%}.a2ui-options-group{display:flex;flex-direction:column;gap:8px}.a2ui-option-label{display:flex;align-items:center;gap:8px;cursor:pointer}.a2ui-option-input{width:18px;height:18px}.a2ui-chips-group{display:flex;flex-wrap:wrap;gap:8px}.a2ui-chip{padding:4px 12px;border-radius:16px;border:1px solid #ccc;background:#fff;cursor:pointer;transition:all .2s}.a2ui-chip.active{background-color:#007bff;color:#fff;border-color:#007bff}\n"] }]
|
|
2003
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
2004
|
+
|
|
2005
|
+
/**
|
|
2006
|
+
* Copyright 2026 Google LLC
|
|
2007
|
+
*
|
|
2008
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
2009
|
+
* you may not use this file except in compliance with the License.
|
|
2010
|
+
* You may obtain a copy of the License at
|
|
2011
|
+
*
|
|
2012
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
2013
|
+
*
|
|
2014
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
2015
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
2016
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
2017
|
+
* See the License for the specific language governing permissions and
|
|
2018
|
+
* limitations under the License.
|
|
2019
|
+
*/
|
|
2020
|
+
/**
|
|
2021
|
+
* Angular implementation of the A2UI Slider component (v0.9).
|
|
2022
|
+
*
|
|
2023
|
+
* Renders a range input slider with a label and its current value.
|
|
2024
|
+
*/
|
|
2025
|
+
class SliderComponent {
|
|
2026
|
+
/**
|
|
2027
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
2028
|
+
*
|
|
2029
|
+
* Expected properties:
|
|
2030
|
+
* - `value`: The current numeric value.
|
|
2031
|
+
* - `label`: Label text to display.
|
|
2032
|
+
* - `min`: Minimum value (default: 0).
|
|
2033
|
+
* - `max`: Maximum value (default: 100).
|
|
2034
|
+
* - `step`: Increment step (default: 1).
|
|
2035
|
+
*/
|
|
2036
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
2037
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
2038
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
2039
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
2040
|
+
label = computed$1(() => this.props()['label']?.value(), ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
2041
|
+
value = computed$1(() => this.props()['value']?.value(), ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
2042
|
+
min = computed$1(() => this.props()['min']?.value() ?? 0, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
|
|
2043
|
+
max = computed$1(() => this.props()['max']?.value() ?? 100, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
|
|
2044
|
+
step = computed$1(() => this.props()['step']?.value() ?? 1, ...(ngDevMode ? [{ debugName: "step" }] : /* istanbul ignore next */ []));
|
|
2045
|
+
handleInput(event) {
|
|
2046
|
+
const val = Number(event.target.value);
|
|
2047
|
+
this.props()['value']?.onUpdate(val);
|
|
2048
|
+
}
|
|
2049
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SliderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2050
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: SliderComponent, isStandalone: true, selector: "a2ui-v09-slider", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
2051
|
+
<div class="a2ui-slider-container">
|
|
2052
|
+
<div class="a2ui-slider-header">
|
|
2053
|
+
<span class="a2ui-slider-label">{{ label() }}</span>
|
|
2054
|
+
<span class="a2ui-slider-value">{{ value() }}</span>
|
|
2055
|
+
</div>
|
|
2056
|
+
<input
|
|
2057
|
+
type="range"
|
|
2058
|
+
[min]="min()"
|
|
2059
|
+
[max]="max()"
|
|
2060
|
+
[step]="step()"
|
|
2061
|
+
[value]="value() ?? min()"
|
|
2062
|
+
(input)="handleInput($event)"
|
|
2063
|
+
class="a2ui-slider"
|
|
2064
|
+
/>
|
|
2065
|
+
</div>
|
|
2066
|
+
`, isInline: true, styles: [".a2ui-slider-container{width:100%;display:flex;flex-direction:column;gap:4px}.a2ui-slider-header{display:flex;justify-content:space-between;font-size:14px}.a2ui-slider{width:100%;cursor:pointer}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2067
|
+
}
|
|
2068
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: SliderComponent, decorators: [{
|
|
2069
|
+
type: Component,
|
|
2070
|
+
args: [{ selector: 'a2ui-v09-slider', standalone: true, imports: [], template: `
|
|
2071
|
+
<div class="a2ui-slider-container">
|
|
2072
|
+
<div class="a2ui-slider-header">
|
|
2073
|
+
<span class="a2ui-slider-label">{{ label() }}</span>
|
|
2074
|
+
<span class="a2ui-slider-value">{{ value() }}</span>
|
|
2075
|
+
</div>
|
|
2076
|
+
<input
|
|
2077
|
+
type="range"
|
|
2078
|
+
[min]="min()"
|
|
2079
|
+
[max]="max()"
|
|
2080
|
+
[step]="step()"
|
|
2081
|
+
[value]="value() ?? min()"
|
|
2082
|
+
(input)="handleInput($event)"
|
|
2083
|
+
class="a2ui-slider"
|
|
2084
|
+
/>
|
|
2085
|
+
</div>
|
|
2086
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".a2ui-slider-container{width:100%;display:flex;flex-direction:column;gap:4px}.a2ui-slider-header{display:flex;justify-content:space-between;font-size:14px}.a2ui-slider{width:100%;cursor:pointer}\n"] }]
|
|
2087
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
2088
|
+
|
|
2089
|
+
/**
|
|
2090
|
+
* Copyright 2026 Google LLC
|
|
2091
|
+
*
|
|
2092
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
2093
|
+
* you may not use this file except in compliance with the License.
|
|
2094
|
+
* You may obtain a copy of the License at
|
|
2095
|
+
*
|
|
2096
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
2097
|
+
*
|
|
2098
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
2099
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
2100
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
2101
|
+
* See the License for the specific language governing permissions and
|
|
2102
|
+
* limitations under the License.
|
|
2103
|
+
*/
|
|
2104
|
+
/**
|
|
2105
|
+
* Angular implementation of the A2UI DateTimeInput component (v0.9).
|
|
2106
|
+
*
|
|
2107
|
+
* Renders date and/or time input fields. Combines them into an ISO string
|
|
2108
|
+
* for the bound data model property.
|
|
2109
|
+
*/
|
|
2110
|
+
class DateTimeInputComponent {
|
|
2111
|
+
/**
|
|
2112
|
+
* Reactive properties resolved from the A2UI {@link ComponentModel}.
|
|
2113
|
+
*
|
|
2114
|
+
* Expected properties:
|
|
2115
|
+
* - `value`: The current ISO date/time string.
|
|
2116
|
+
* - `label`: Optional label text.
|
|
2117
|
+
* - `enableDate`: Whether to show the date picker (default: true).
|
|
2118
|
+
* - `enableTime`: Whether to show the time picker (default: false).
|
|
2119
|
+
*/
|
|
2120
|
+
props = input({}, ...(ngDevMode ? [{ debugName: "props" }] : /* istanbul ignore next */ []));
|
|
2121
|
+
surfaceId = input.required(...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
2122
|
+
componentId = input(...(ngDevMode ? [undefined, { debugName: "componentId" }] : /* istanbul ignore next */ []));
|
|
2123
|
+
dataContextPath = input('/', ...(ngDevMode ? [{ debugName: "dataContextPath" }] : /* istanbul ignore next */ []));
|
|
2124
|
+
label = computed$1(() => this.props()['label']?.value(), ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
2125
|
+
enableDate = computed$1(() => this.props()['enableDate']?.value() ?? true, ...(ngDevMode ? [{ debugName: "enableDate" }] : /* istanbul ignore next */ []));
|
|
2126
|
+
enableTime = computed$1(() => this.props()['enableTime']?.value() ?? false, ...(ngDevMode ? [{ debugName: "enableTime" }] : /* istanbul ignore next */ []));
|
|
2127
|
+
rawValue = computed$1(() => this.props()['value']?.value() || '', ...(ngDevMode ? [{ debugName: "rawValue" }] : /* istanbul ignore next */ []));
|
|
2128
|
+
dateValue = computed$1(() => {
|
|
2129
|
+
const val = this.rawValue();
|
|
2130
|
+
if (!val)
|
|
2131
|
+
return '';
|
|
2132
|
+
return val.includes('T') ? val.split('T')[0] : val;
|
|
2133
|
+
}, ...(ngDevMode ? [{ debugName: "dateValue" }] : /* istanbul ignore next */ []));
|
|
2134
|
+
timeValue = computed$1(() => {
|
|
2135
|
+
const val = this.rawValue();
|
|
2136
|
+
if (!val || !val.includes('T'))
|
|
2137
|
+
return '';
|
|
2138
|
+
return val.split('T')[1].substring(0, 5);
|
|
2139
|
+
}, ...(ngDevMode ? [{ debugName: "timeValue" }] : /* istanbul ignore next */ []));
|
|
2140
|
+
handleDateChange(event) {
|
|
2141
|
+
const date = event.target.value;
|
|
2142
|
+
const current = this.rawValue();
|
|
2143
|
+
if (this.enableTime()) {
|
|
2144
|
+
const time = current.includes('T') ? current.split('T')[1] : '00:00:00';
|
|
2145
|
+
this.props()['value']?.onUpdate(`${date}T${time}`);
|
|
2146
|
+
}
|
|
2147
|
+
else {
|
|
2148
|
+
this.props()['value']?.onUpdate(date);
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
handleTimeChange(event) {
|
|
2152
|
+
const time = event.target.value;
|
|
2153
|
+
const current = this.rawValue();
|
|
2154
|
+
const date = current.includes('T')
|
|
2155
|
+
? current.split('T')[0]
|
|
2156
|
+
: current || new Date().toISOString().split('T')[0];
|
|
2157
|
+
this.props()['value']?.onUpdate(`${date}T${time}:00`);
|
|
2158
|
+
}
|
|
2159
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DateTimeInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2160
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: DateTimeInputComponent, isStandalone: true, selector: "a2ui-v09-date-time-input", inputs: { props: { classPropertyName: "props", publicName: "props", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: true, transformFunction: null }, componentId: { classPropertyName: "componentId", publicName: "componentId", isSignal: true, isRequired: false, transformFunction: null }, dataContextPath: { classPropertyName: "dataContextPath", publicName: "dataContextPath", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
2161
|
+
<div class="a2ui-date-time-container">
|
|
2162
|
+
@if (label()) {
|
|
2163
|
+
<label class="a2ui-date-time-label">
|
|
2164
|
+
{{ label() }}
|
|
2165
|
+
</label>
|
|
2166
|
+
}
|
|
2167
|
+
<div class="a2ui-date-time-inputs">
|
|
2168
|
+
@if (enableDate()) {
|
|
2169
|
+
<input
|
|
2170
|
+
type="date"
|
|
2171
|
+
[value]="dateValue()"
|
|
2172
|
+
(change)="handleDateChange($event)"
|
|
2173
|
+
class="a2ui-date-time-input"
|
|
2174
|
+
/>
|
|
2175
|
+
}
|
|
2176
|
+
@if (enableTime()) {
|
|
2177
|
+
<input
|
|
2178
|
+
type="time"
|
|
2179
|
+
[value]="timeValue()"
|
|
2180
|
+
(change)="handleTimeChange($event)"
|
|
2181
|
+
class="a2ui-date-time-input"
|
|
2182
|
+
/>
|
|
2183
|
+
}
|
|
2184
|
+
</div>
|
|
2185
|
+
</div>
|
|
2186
|
+
`, isInline: true, styles: [".a2ui-date-time-container{display:flex;flex-direction:column;gap:4px;width:100%}.a2ui-date-time-label{font-size:14px;color:#666}.a2ui-date-time-inputs{display:flex;gap:8px;width:100%}.a2ui-date-time-input{padding:8px;border-radius:4px;border:1px solid #ccc;font-family:inherit;flex:1}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2187
|
+
}
|
|
2188
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DateTimeInputComponent, decorators: [{
|
|
2189
|
+
type: Component,
|
|
2190
|
+
args: [{ selector: 'a2ui-v09-date-time-input', standalone: true, imports: [], template: `
|
|
2191
|
+
<div class="a2ui-date-time-container">
|
|
2192
|
+
@if (label()) {
|
|
2193
|
+
<label class="a2ui-date-time-label">
|
|
2194
|
+
{{ label() }}
|
|
2195
|
+
</label>
|
|
2196
|
+
}
|
|
2197
|
+
<div class="a2ui-date-time-inputs">
|
|
2198
|
+
@if (enableDate()) {
|
|
2199
|
+
<input
|
|
2200
|
+
type="date"
|
|
2201
|
+
[value]="dateValue()"
|
|
2202
|
+
(change)="handleDateChange($event)"
|
|
2203
|
+
class="a2ui-date-time-input"
|
|
2204
|
+
/>
|
|
2205
|
+
}
|
|
2206
|
+
@if (enableTime()) {
|
|
2207
|
+
<input
|
|
2208
|
+
type="time"
|
|
2209
|
+
[value]="timeValue()"
|
|
2210
|
+
(change)="handleTimeChange($event)"
|
|
2211
|
+
class="a2ui-date-time-input"
|
|
2212
|
+
/>
|
|
2213
|
+
}
|
|
2214
|
+
</div>
|
|
2215
|
+
</div>
|
|
2216
|
+
`, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".a2ui-date-time-container{display:flex;flex-direction:column;gap:4px;width:100%}.a2ui-date-time-label{font-size:14px;color:#666}.a2ui-date-time-inputs{display:flex;gap:8px;width:100%}.a2ui-date-time-input{padding:8px;border-radius:4px;border:1px solid #ccc;font-family:inherit;flex:1}\n"] }]
|
|
2217
|
+
}], propDecorators: { props: [{ type: i0.Input, args: [{ isSignal: true, alias: "props", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: true }] }], componentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "componentId", required: false }] }], dataContextPath: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataContextPath", required: false }] }] } });
|
|
2218
|
+
|
|
2219
|
+
/**
|
|
2220
|
+
* Copyright 2026 Google LLC
|
|
2221
|
+
*
|
|
2222
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
2223
|
+
* you may not use this file except in compliance with the License.
|
|
2224
|
+
* You may obtain a copy of the License at
|
|
2225
|
+
*
|
|
2226
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
2227
|
+
*
|
|
2228
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
2229
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
2230
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
2231
|
+
* See the License for the specific language governing permissions and
|
|
2232
|
+
* limitations under the License.
|
|
2233
|
+
*/
|
|
2234
|
+
/**
|
|
2235
|
+
* The set of default Angular implementations for each component in the basic catalog.
|
|
2236
|
+
*/
|
|
2237
|
+
const DEFAULT_COMPONENT_IMPLEMENTATIONS = {
|
|
2238
|
+
text: { ...TextApi, component: TextComponent },
|
|
2239
|
+
row: { ...RowApi, component: RowComponent },
|
|
2240
|
+
column: { ...ColumnApi, component: ColumnComponent },
|
|
2241
|
+
button: { ...ButtonApi, component: ButtonComponent },
|
|
2242
|
+
textField: { ...TextFieldApi, component: TextFieldComponent },
|
|
2243
|
+
image: { ...ImageApi, component: ImageComponent },
|
|
2244
|
+
icon: { ...IconApi, component: IconComponent },
|
|
2245
|
+
video: { ...VideoApi, component: VideoComponent },
|
|
2246
|
+
audioPlayer: { ...AudioPlayerApi, component: AudioPlayerComponent },
|
|
2247
|
+
list: { ...ListApi, component: ListComponent },
|
|
2248
|
+
card: { ...CardApi, component: CardComponent },
|
|
2249
|
+
tabs: { ...TabsApi, component: TabsComponent },
|
|
2250
|
+
modal: { ...ModalApi, component: ModalComponent },
|
|
2251
|
+
divider: { ...DividerApi, component: DividerComponent },
|
|
2252
|
+
checkBox: { ...CheckBoxApi, component: CheckBoxComponent },
|
|
2253
|
+
choicePicker: { ...ChoicePickerApi, component: ChoicePickerComponent },
|
|
2254
|
+
slider: { ...SliderApi, component: SliderComponent },
|
|
2255
|
+
dateTimeInput: { ...DateTimeInputApi, component: DateTimeInputComponent },
|
|
2256
|
+
};
|
|
2257
|
+
/**
|
|
2258
|
+
* The set of Angular UI components provided by the basic catalog.
|
|
2259
|
+
*/
|
|
2260
|
+
const BASIC_COMPONENTS = Object.values(DEFAULT_COMPONENT_IMPLEMENTATIONS);
|
|
2261
|
+
/**
|
|
2262
|
+
* A base class for basic catalogs, providing extensibility for non-DI use cases.
|
|
2263
|
+
*/
|
|
2264
|
+
class BasicCatalogBase extends AngularCatalog {
|
|
2265
|
+
constructor(options = {}) {
|
|
2266
|
+
const id = options.id ?? 'https://a2ui.org/specification/v0_9/basic_catalog.json';
|
|
2267
|
+
const functions = options.functions ?? BASIC_FUNCTIONS;
|
|
2268
|
+
const overrides = options.components ?? {};
|
|
2269
|
+
const components = [
|
|
2270
|
+
...Object.entries(DEFAULT_COMPONENT_IMPLEMENTATIONS).map(([key, defaultValue]) => {
|
|
2271
|
+
const impl = overrides[key] ?? defaultValue;
|
|
2272
|
+
return { ...impl, name: impl.name || key };
|
|
2273
|
+
}),
|
|
2274
|
+
...(options.extraComponents ?? []),
|
|
2275
|
+
];
|
|
2276
|
+
super(id, components, functions);
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
/**
|
|
2280
|
+
* A basic catalog of components and functions for v0.9 verification.
|
|
2281
|
+
*
|
|
2282
|
+
* This catalog includes a wide range of UI components (Text, Button, Row, etc.)
|
|
2283
|
+
* and utility functions (capitalize, formatString) defined in the A2UI v0.9
|
|
2284
|
+
* basic catalog specification.
|
|
2285
|
+
*/
|
|
2286
|
+
class BasicCatalog extends BasicCatalogBase {
|
|
2287
|
+
constructor() {
|
|
2288
|
+
super();
|
|
2289
|
+
}
|
|
2290
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: BasicCatalog, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2291
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: BasicCatalog, providedIn: 'root' });
|
|
2292
|
+
}
|
|
2293
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: BasicCatalog, decorators: [{
|
|
2294
|
+
type: Injectable,
|
|
2295
|
+
args: [{
|
|
2296
|
+
providedIn: 'root',
|
|
2297
|
+
}]
|
|
2298
|
+
}], ctorParameters: () => [] });
|
|
2299
|
+
|
|
2300
|
+
/*
|
|
2301
|
+
* Copyright 2026 Google LLC
|
|
2302
|
+
*
|
|
2303
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
2304
|
+
* you may not use this file except in compliance with the License.
|
|
2305
|
+
* You may obtain a copy of the License at
|
|
2306
|
+
*
|
|
2307
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
2308
|
+
*
|
|
2309
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
2310
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
2311
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
2312
|
+
* See the License for the specific language governing permissions and
|
|
2313
|
+
* limitations under the License.
|
|
2314
|
+
*/
|
|
2315
|
+
/**
|
|
2316
|
+
* Public API surface for A2UI Angular Renderer v0.9.
|
|
2317
|
+
*
|
|
2318
|
+
* This module provides the core services, components, and catalogs required
|
|
2319
|
+
* to render A2UI surfaces using the v0.9 protocol.
|
|
2320
|
+
*
|
|
2321
|
+
* @module v0.9
|
|
2322
|
+
*/
|
|
2323
|
+
// Core Services and Components
|
|
2324
|
+
|
|
2325
|
+
/**
|
|
2326
|
+
* Generated bundle index. Do not edit.
|
|
2327
|
+
*/
|
|
2328
|
+
|
|
2329
|
+
export { A2UI_RENDERER_CONFIG, A2uiRendererService, AngularCatalog, AudioPlayerComponent, BASIC_COMPONENTS, BasicCatalog, BasicCatalogBase, ButtonComponent, CardComponent, CheckBoxComponent, ChoicePickerComponent, ColumnComponent, ComponentBinder, ComponentHostComponent, DateTimeInputComponent, DividerComponent, IconComponent, ImageComponent, ListComponent, ModalComponent, RowComponent, SliderComponent, SurfaceComponent, TabsComponent, TextComponent, TextFieldComponent, VideoComponent, getNormalizedPath, toAngularSignal };
|
|
2330
|
+
//# sourceMappingURL=a2ui-angular-v0_9.mjs.map
|