@acorex/components 22.1.2 → 22.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (18) hide show
  1. package/fesm2022/acorex-components-accordion.mjs +2 -2
  2. package/fesm2022/acorex-components-accordion.mjs.map +1 -1
  3. package/fesm2022/acorex-components-audio-wave.mjs +252 -277
  4. package/fesm2022/acorex-components-audio-wave.mjs.map +1 -1
  5. package/fesm2022/{acorex-components-conversation-acorex-components-conversation-BtkyQUlh.mjs → acorex-components-conversation-acorex-components-conversation-CdAHDQD1.mjs} +447 -133
  6. package/fesm2022/acorex-components-conversation-acorex-components-conversation-CdAHDQD1.mjs.map +1 -0
  7. package/fesm2022/{acorex-components-conversation-open-composer-picker-for-files-BKKO_8x6.mjs → acorex-components-conversation-open-composer-picker-for-files-DBWQaSVC.mjs} +2 -2
  8. package/fesm2022/{acorex-components-conversation-open-composer-picker-for-files-BKKO_8x6.mjs.map → acorex-components-conversation-open-composer-picker-for-files-DBWQaSVC.mjs.map} +1 -1
  9. package/fesm2022/{acorex-components-conversation-picker-rename-file-dialog.component-BNKFb5yO.mjs → acorex-components-conversation-picker-rename-file-dialog.component-swqLQ8g0.mjs} +2 -2
  10. package/fesm2022/{acorex-components-conversation-picker-rename-file-dialog.component-BNKFb5yO.mjs.map → acorex-components-conversation-picker-rename-file-dialog.component-swqLQ8g0.mjs.map} +1 -1
  11. package/fesm2022/acorex-components-conversation.mjs +1 -1
  12. package/fesm2022/acorex-components-file-viewer.mjs +84 -4
  13. package/fesm2022/acorex-components-file-viewer.mjs.map +1 -1
  14. package/package.json +5 -4
  15. package/types/acorex-components-audio-wave.d.ts +108 -73
  16. package/types/acorex-components-conversation.d.ts +89 -13
  17. package/types/acorex-components-file-viewer.d.ts +22 -3
  18. package/fesm2022/acorex-components-conversation-acorex-components-conversation-BtkyQUlh.mjs.map +0 -1
@@ -1,13 +1,16 @@
1
1
  import { AXComponent } from '@acorex/cdk/common';
2
- import { AXSkeletonComponent, AXSkeletonModule } from '@acorex/components/skeleton';
3
- import { AXTranslatorPipe, AXTranslationModule } from '@acorex/core/translation';
4
- import { isPlatformBrowser, NgStyle, AsyncPipe, CommonModule } from '@angular/common';
2
+ import { AXSkeletonComponent } from '@acorex/components/skeleton';
3
+ import { AXTranslatorPipe } from '@acorex/core/translation';
4
+ import { isPlatformBrowser, AsyncPipe } from '@angular/common';
5
5
  import * as i0 from '@angular/core';
6
- import { input, output, signal, inject, NgZone, PLATFORM_ID, afterNextRender, ViewChild, ViewEncapsulation, Component, NgModule } from '@angular/core';
6
+ import { viewChild, input, output, signal, computed, inject, NgZone, PLATFORM_ID, DestroyRef, afterRenderEffect, ChangeDetectionStrategy, ViewEncapsulation, Component, NgModule } from '@angular/core';
7
7
  import WaveSurfer from 'wavesurfer.js';
8
- import { AXButtonModule } from '@acorex/components/button';
9
- import { AXDecoratorModule } from '@acorex/components/decorators';
10
8
 
9
+ const DEFAULT_BAR_WIDTH = 2;
10
+ const DEFAULT_BAR_GAP = 2;
11
+ const DEFAULT_BAR_RADIUS = 2;
12
+ const DEFAULT_HEIGHT = 36;
13
+ const FALLBACK_RGB = '128, 128, 128';
11
14
  /**
12
15
  * Displays and interacts with audio waveform visualization.
13
16
  *
@@ -15,9 +18,14 @@ import { AXDecoratorModule } from '@acorex/components/decorators';
15
18
  */
16
19
  class AXAudioWaveComponent {
17
20
  /**
18
- * @ignore
21
+ * @ignore
19
22
  */
20
23
  constructor() {
24
+ /**
25
+ * @ignore
26
+ */
27
+ this.wave = viewChild('wave', /* @ts-ignore */
28
+ ...(ngDevMode ? [{ debugName: "wave" }] : /* istanbul ignore next */ []));
21
29
  /**
22
30
  * Configuration settings for the audio wave.
23
31
  */
@@ -29,58 +37,89 @@ class AXAudioWaveComponent {
29
37
  * @event
30
38
  */
31
39
  this.onStatusChanged = output();
32
- this.audioState = signal('paused', /* @ts-ignore */
40
+ /**
41
+ * @ignore
42
+ */
43
+ this.audioState = signal('loading', /* @ts-ignore */
33
44
  ...(ngDevMode ? [{ debugName: "audioState" }] : /* istanbul ignore next */ []));
45
+ /**
46
+ * @ignore
47
+ */
34
48
  this.errorMessage = signal('', /* @ts-ignore */
35
49
  ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
36
50
  /**
37
- * @ignore
51
+ * @ignore
52
+ */
53
+ this.isWaveVisible = computed(() => {
54
+ const state = this.audioState();
55
+ return state === 'ready' || state === 'playing' || state === 'paused';
56
+ }, /* @ts-ignore */
57
+ ...(ngDevMode ? [{ debugName: "isWaveVisible" }] : /* istanbul ignore next */ []));
58
+ /**
59
+ * @ignore
60
+ */
61
+ this.loadedUrl = '';
62
+ /**
63
+ * @ignore
64
+ */
65
+ this.lastVisualKey = '';
66
+ /**
67
+ * @ignore
68
+ */
69
+ this.isDestroyed = false;
70
+ /**
71
+ * @ignore
38
72
  */
39
73
  this.ngZone = inject(NgZone);
40
- this.platformID = inject(PLATFORM_ID);
41
- afterNextRender(() => {
42
- if (isPlatformBrowser(this.platformID)) {
43
- const primary200 = getComputedStyle(document.body).getPropertyValue('--ax-sys-color-primary-200');
44
- const primary700 = getComputedStyle(document.body).getPropertyValue('--ax-sys-color-primary-700');
45
- this.audio = WaveSurfer.create({
46
- container: this.div.nativeElement,
47
- waveColor: this.config()?.waveColor || `rgba(${primary200})`,
48
- progressColor: this.config()?.progressColor || `rgba(${primary700})`,
49
- url: this.config()?.url || '',
50
- barWidth: this.config()?.barWidth || 2,
51
- barRadius: this.config()?.barRadius || 2,
52
- barGap: this.config()?.barGap || 2,
53
- height: this.config()?.height || 36,
54
- });
74
+ /**
75
+ * @ignore
76
+ */
77
+ this.platformId = inject(PLATFORM_ID);
78
+ /**
79
+ * @ignore
80
+ */
81
+ this.destroyRef = inject(DestroyRef);
82
+ afterRenderEffect(() => {
83
+ const container = this.wave()?.nativeElement;
84
+ const config = this.config();
85
+ if (this.isDestroyed || !isPlatformBrowser(this.platformId) || !container) {
86
+ return;
55
87
  }
56
- this.load();
57
- this.audio?.on('loading', () => {
58
- this.audioState.set('loading');
59
- });
60
- this.audio?.on('ready', () => {
61
- this.audioState.set('ready');
62
- });
63
- this.audio?.on('error', (e) => {
64
- this.errorMessage.set(e?.message);
65
- this.audioState.set('error');
66
- });
67
- this.bindEvents();
88
+ if (!this.audio) {
89
+ this.createWaveSurfer(container, config);
90
+ return;
91
+ }
92
+ this.syncFromConfig(config);
93
+ });
94
+ this.destroyRef.onDestroy(() => {
95
+ this.isDestroyed = true;
96
+ this.audio?.destroy();
97
+ this.audio = undefined;
68
98
  });
69
99
  }
70
100
  /**
71
101
  * Loads the audio from the specified URL.
72
102
  *
73
103
  * @param url - The URL of the audio to load. Defaults to the URL from the config.
104
+ * @returns A promise that resolves when loading starts, or immediately when unavailable.
74
105
  */
75
- load(url = this.config().url) {
76
- this.audio.load(url);
106
+ load(url = this.config()?.url) {
107
+ const nextUrl = url?.trim();
108
+ if (!this.audio || !nextUrl) {
109
+ return Promise.resolve();
110
+ }
111
+ this.loadedUrl = nextUrl;
112
+ this.audioState.set('loading');
113
+ this.errorMessage.set('');
114
+ return this.audio.load(nextUrl);
77
115
  }
78
116
  /**
79
117
  * Plays the audio.
80
118
  *
119
+ * @returns A promise that resolves when playback starts.
81
120
  */
82
121
  play() {
83
- return this.audio?.play();
122
+ return this.audio?.play() ?? Promise.resolve();
84
123
  }
85
124
  /**
86
125
  * Pauses the audio.
@@ -89,21 +128,25 @@ class AXAudioWaveComponent {
89
128
  this.audio?.pause();
90
129
  }
91
130
  /**
92
- * Retrieves the duration of the audio.
131
+ * Retrieves the duration of the audio in seconds.
93
132
  *
133
+ * @returns The audio duration, or `0` when unavailable.
94
134
  */
95
135
  getDuration() {
96
136
  return this.audio?.getDuration() ?? 0;
97
137
  }
98
138
  /**
99
- * Retrieves the media element of the audio.
139
+ * Retrieves the underlying HTML media element.
100
140
  *
141
+ * @returns The media element used by WaveSurfer, or `undefined` when unavailable.
101
142
  */
102
143
  getMediaElement() {
103
144
  return this.audio?.getMediaElement();
104
145
  }
105
146
  /**
106
147
  * Retrieves the current playback position in seconds.
148
+ *
149
+ * @returns The current time, or `0` when unavailable.
107
150
  */
108
151
  getCurrentTime() {
109
152
  return this.audio?.getCurrentTime() ?? this.getMediaElement()?.currentTime ?? 0;
@@ -114,7 +157,7 @@ class AXAudioWaveComponent {
114
157
  * @param rate - The playback rate to set.
115
158
  */
116
159
  setRate(rate) {
117
- this.audio.setPlaybackRate(rate);
160
+ this.audio?.setPlaybackRate(rate);
118
161
  }
119
162
  /**
120
163
  * Mutes or unmutes the audio.
@@ -122,11 +165,7 @@ class AXAudioWaveComponent {
122
165
  * @param muted - Whether the audio should be muted.
123
166
  */
124
167
  setMuted(muted) {
125
- const media = this.getMediaElement();
126
- if (media) {
127
- media.muted = muted;
128
- }
129
- this.audio?.setVolume(muted ? 0 : 1);
168
+ this.audio?.setMuted(muted);
130
169
  }
131
170
  /**
132
171
  * Indicates whether the audio is currently muted.
@@ -134,279 +173,215 @@ class AXAudioWaveComponent {
134
173
  * @returns True when muted; otherwise false.
135
174
  */
136
175
  isMuted() {
137
- const media = this.getMediaElement();
138
- return media?.muted ?? this.audio?.getVolume() === 0;
176
+ return this.audio?.getMuted() ?? false;
139
177
  }
140
178
  /**
141
- * @ignore
179
+ * @ignore
142
180
  */
143
- bindEvents() {
144
- this.handleLoad();
145
- this.handleLoading();
146
- this.handleDecode();
147
- this.handleReady();
148
- this.handleRedRawComplete();
149
- this.handlePlay();
150
- this.handlePause();
151
- this.handleFinish();
152
- this.handleTimeUpdate();
153
- this.handleSeeking();
154
- this.handleInteraction();
155
- this.handleClick();
156
- this.handleDrag();
157
- this.handleScroll();
158
- this.handleZoom();
159
- this.handleDestroy();
160
- this.handleError();
161
- }
162
- /** When audio starts loading */
163
- handleLoad() {
164
- this.audio?.on('load', (url) => {
165
- this.ngZone.run(() => {
166
- this.onStatusChanged.emit({
167
- component: this,
168
- data: { url: url },
169
- status: 'load',
170
- isUserInteraction: false,
171
- });
172
- });
181
+ createWaveSurfer(container, config) {
182
+ const visualOptions = this.resolveVisualOptions(config);
183
+ this.lastVisualKey = JSON.stringify(visualOptions);
184
+ this.audio = WaveSurfer.create({
185
+ container,
186
+ ...visualOptions,
173
187
  });
188
+ this.bindEvents();
189
+ this.applyUrlAndRate(config);
174
190
  }
175
- /** During audio loading */
176
- handleLoading() {
177
- this.audio?.on('loading', (percent) => {
178
- this.ngZone.run(() => {
179
- this.onStatusChanged.emit({
180
- component: this,
181
- data: { percent: percent },
182
- status: 'loading',
183
- isUserInteraction: false,
184
- });
185
- });
186
- });
191
+ /**
192
+ * @ignore
193
+ */
194
+ syncFromConfig(config) {
195
+ if (!this.audio) {
196
+ return;
197
+ }
198
+ const visualOptions = this.resolveVisualOptions(config);
199
+ const visualKey = JSON.stringify(visualOptions);
200
+ if (visualKey !== this.lastVisualKey) {
201
+ this.lastVisualKey = visualKey;
202
+ this.audio.setOptions(visualOptions);
203
+ }
204
+ this.applyUrlAndRate(config);
187
205
  }
188
- /** When the audio has been decoded */
189
- handleDecode() {
190
- this.audio?.on('decode', (duration) => {
191
- this.ngZone.run(() => {
192
- this.onStatusChanged.emit({
193
- component: this,
194
- data: { duration: duration },
195
- status: 'decode',
196
- isUserInteraction: false,
197
- });
206
+ /**
207
+ * @ignore
208
+ */
209
+ applyUrlAndRate(config) {
210
+ const url = config?.url?.trim() ?? '';
211
+ if (url && url !== this.loadedUrl) {
212
+ this.loadedUrl = url;
213
+ void this.audio?.load(url);
214
+ }
215
+ else if (!url) {
216
+ queueMicrotask(() => {
217
+ if (!this.isDestroyed && !this.loadedUrl && this.audioState() === 'loading') {
218
+ this.audioState.set('paused');
219
+ }
198
220
  });
199
- });
221
+ }
222
+ if (config?.audioRate != null) {
223
+ this.audio?.setPlaybackRate(config.audioRate);
224
+ }
200
225
  }
201
- /** When the audio is both decoded and can play */
202
- handleReady() {
203
- this.audio?.on('ready', (duration) => {
204
- this.ngZone.run(() => {
205
- this.onStatusChanged.emit({
206
- component: this,
207
- data: { duration: duration },
208
- status: 'ready',
209
- isUserInteraction: false,
210
- });
211
- });
212
- });
226
+ /**
227
+ * @ignore
228
+ */
229
+ resolveVisualOptions(config) {
230
+ const primary200 = this.readCssRgbVar('--ax-sys-color-primary-200');
231
+ const primary700 = this.readCssRgbVar('--ax-sys-color-primary-700');
232
+ return {
233
+ waveColor: config?.waveColor ?? `rgba(${primary200})`,
234
+ progressColor: config?.progressColor ?? `rgba(${primary700})`,
235
+ barWidth: config?.barWidth ?? DEFAULT_BAR_WIDTH,
236
+ barGap: config?.barGap ?? DEFAULT_BAR_GAP,
237
+ barRadius: config?.barRadius ?? DEFAULT_BAR_RADIUS,
238
+ height: config?.height ?? DEFAULT_HEIGHT,
239
+ };
213
240
  }
214
- /** When all audio channel chunks of the waveform have drawn */
215
- handleRedRawComplete() {
216
- this.audio?.on('redrawcomplete', () => {
217
- this.ngZone.run(() => {
218
- this.onStatusChanged.emit({
219
- component: this,
220
- data: null,
221
- status: 'redrawcomplete',
222
- isUserInteraction: false,
223
- });
224
- });
225
- });
241
+ /**
242
+ * @ignore
243
+ */
244
+ readCssRgbVar(name) {
245
+ if (!isPlatformBrowser(this.platformId)) {
246
+ return FALLBACK_RGB;
247
+ }
248
+ return getComputedStyle(document.documentElement).getPropertyValue(name).trim() || FALLBACK_RGB;
226
249
  }
227
- /** When the audio starts playing */
228
- handlePlay() {
229
- this.audio?.on('play', () => {
230
- this.ngZone.run(() => {
231
- this.audioState.set('ready');
232
- this.onStatusChanged.emit({ component: this, data: null, status: 'play', isUserInteraction: false });
233
- });
250
+ /**
251
+ * @ignore
252
+ */
253
+ bindEvents() {
254
+ if (!this.audio) {
255
+ return;
256
+ }
257
+ this.audio.on('load', (url) => {
258
+ this.emitStatus('load', { url }, false);
234
259
  });
235
- }
236
- /** When the audio pauses */
237
- handlePause() {
238
- this.audio?.on('pause', () => {
239
- this.ngZone.run(() => {
240
- this.onStatusChanged.emit({ component: this, data: null, status: 'pause', isUserInteraction: false });
260
+ this.audio.on('loading', (percent) => {
261
+ this.runInZone(() => {
262
+ this.errorMessage.set('');
263
+ this.audioState.set('loading');
264
+ this.emitStatus('loading', { percent }, false, false);
241
265
  });
242
266
  });
243
- }
244
- /** When the audio finishes playing */
245
- handleFinish() {
246
- this.audio?.on('finish', () => {
247
- this.ngZone.run(() => {
248
- this.onStatusChanged.emit({
249
- component: this,
250
- data: null,
251
- status: 'finish',
252
- isUserInteraction: false,
253
- });
254
- });
267
+ this.audio.on('decode', (duration) => {
268
+ this.emitStatus('decode', { duration }, false);
255
269
  });
256
- }
257
- /** On audio position change, fires continuously during playback */
258
- handleTimeUpdate() {
259
- this.audio?.on('timeupdate', (currentTime) => {
260
- this.ngZone.run(() => {
261
- this.onStatusChanged.emit({
262
- component: this,
263
- data: { currentTime: currentTime },
264
- status: 'timeupdate',
265
- isUserInteraction: false,
266
- });
270
+ this.audio.on('ready', (duration) => {
271
+ this.runInZone(() => {
272
+ if (this.audioState() !== 'playing') {
273
+ this.audioState.set('ready');
274
+ }
275
+ this.emitStatus('ready', { duration }, false, false);
267
276
  });
268
277
  });
269
- }
270
- /** When the user seeks to a new position */
271
- handleSeeking() {
272
- this.audio?.on('seeking', (currentTime) => {
273
- this.ngZone.run(() => {
274
- this.onStatusChanged.emit({
275
- component: this,
276
- data: { currentTime: currentTime },
277
- status: 'seeking',
278
- isUserInteraction: false,
279
- });
280
- });
278
+ this.audio.on('redrawcomplete', () => {
279
+ this.emitStatus('redrawcomplete', null, false);
281
280
  });
282
- }
283
- /** When the user interacts with the waveform (i.g. clicks or drags on it) */
284
- handleInteraction() {
285
- this.audio?.on('interaction', (newTime) => {
286
- this.ngZone.run(() => {
287
- this.onStatusChanged.emit({
288
- component: this,
289
- data: { newTime: newTime },
290
- status: 'interaction',
291
- isUserInteraction: false,
292
- });
281
+ this.audio.on('play', () => {
282
+ this.runInZone(() => {
283
+ this.audioState.set('playing');
284
+ this.emitStatus('play', null, false, false);
293
285
  });
294
286
  });
295
- }
296
- /** When the user clicks on the waveform */
297
- handleClick() {
298
- this.audio?.on('click', (relativeX) => {
299
- this.ngZone.run(() => {
300
- this.onStatusChanged.emit({
301
- component: this,
302
- data: { relativeX: relativeX },
303
- status: 'click',
304
- isUserInteraction: false,
305
- });
287
+ this.audio.on('pause', () => {
288
+ this.runInZone(() => {
289
+ if (this.audioState() !== 'error') {
290
+ this.audioState.set('paused');
291
+ }
292
+ this.emitStatus('pause', null, false, false);
306
293
  });
307
294
  });
308
- }
309
- /** When the user drags the cursor */
310
- handleDrag() {
311
- this.audio?.on('drag', (relativeX) => {
312
- this.ngZone.run(() => {
313
- this.onStatusChanged.emit({
314
- component: this,
315
- data: { relativeX: relativeX },
316
- status: 'drag',
317
- isUserInteraction: false,
318
- });
295
+ this.audio.on('finish', () => {
296
+ this.runInZone(() => {
297
+ this.audioState.set('paused');
298
+ this.emitStatus('finish', null, false, false);
319
299
  });
320
300
  });
321
- }
322
- /** When the waveform is scrolled (panned) */
323
- handleScroll() {
324
- this.audio?.on('scroll', (visibleStartTime, visibleEndTime) => {
325
- this.ngZone.run(() => {
326
- this.onStatusChanged.emit({
327
- component: this,
328
- data: { visibleStartTime, visibleEndTime },
329
- status: 'scroll',
330
- isUserInteraction: false,
331
- });
332
- });
301
+ this.audio.on('timeupdate', (currentTime) => {
302
+ this.emitStatus('timeupdate', { currentTime }, false);
333
303
  });
334
- }
335
- /** When the zoom level changes */
336
- handleZoom() {
337
- this.audio?.on('zoom', (minPxPerSec) => {
338
- this.ngZone.run(() => {
339
- this.onStatusChanged.emit({
340
- component: this,
341
- data: { minPxPerSec: minPxPerSec },
342
- status: 'zoom',
343
- isUserInteraction: false,
344
- });
345
- });
304
+ this.audio.on('seeking', (currentTime) => {
305
+ this.emitStatus('seeking', { currentTime }, true);
346
306
  });
347
- }
348
- /** Just before the waveform is destroyed so you can clean up your events */
349
- handleDestroy() {
350
- this.audio?.on('destroy', () => {
351
- this.ngZone.run(() => {
352
- this.onStatusChanged.emit({
353
- component: this,
354
- data: null,
355
- status: 'destroy',
356
- isUserInteraction: false,
357
- });
307
+ this.audio.on('interaction', (newTime) => {
308
+ this.emitStatus('interaction', { newTime }, true);
309
+ });
310
+ this.audio.on('click', (relativeX, relativeY) => {
311
+ this.emitStatus('click', { relativeX, relativeY }, true);
312
+ });
313
+ this.audio.on('drag', (relativeX) => {
314
+ this.emitStatus('drag', { relativeX }, true);
315
+ });
316
+ this.audio.on('scroll', (visibleStartTime, visibleEndTime) => {
317
+ this.emitStatus('scroll', { visibleStartTime, visibleEndTime }, true);
318
+ });
319
+ this.audio.on('zoom', (minPxPerSec) => {
320
+ this.emitStatus('zoom', { minPxPerSec }, false);
321
+ });
322
+ this.audio.on('destroy', () => {
323
+ this.emitStatus('destroy', null, false);
324
+ });
325
+ this.audio.on('error', (error) => {
326
+ this.runInZone(() => {
327
+ const message = error?.message ?? '';
328
+ this.errorMessage.set(message);
329
+ this.audioState.set('error');
330
+ this.emitStatus('error', { message }, false, false);
358
331
  });
359
332
  });
360
333
  }
361
- /** Just before the waveform is destroyed so you can clean up your events */
362
- handleError() {
363
- this.audio?.on('error', (e) => {
364
- this.ngZone.run(() => {
365
- this.onStatusChanged.emit({ component: this, data: e, status: 'error', isUserInteraction: false });
334
+ /**
335
+ * @ignore
336
+ */
337
+ emitStatus(status, data, isUserInteraction, wrapInZone = true) {
338
+ if (this.isDestroyed) {
339
+ return;
340
+ }
341
+ const emit = () => {
342
+ this.onStatusChanged.emit({
343
+ component: this,
344
+ data,
345
+ status,
346
+ isUserInteraction,
366
347
  });
367
- });
348
+ };
349
+ if (wrapInZone) {
350
+ this.runInZone(emit);
351
+ return;
352
+ }
353
+ emit();
368
354
  }
369
- ngOnDestroy() {
370
- this.audio?.destroy();
355
+ /**
356
+ * @ignore
357
+ */
358
+ runInZone(fn) {
359
+ if (this.isDestroyed) {
360
+ return;
361
+ }
362
+ this.ngZone.run(fn);
371
363
  }
372
364
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXAudioWaveComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
373
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXAudioWaveComponent, isStandalone: true, selector: "ax-audio-wave", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onStatusChanged: "onStatusChanged" }, providers: [{ provide: AXComponent, useExisting: AXAudioWaveComponent }], viewQueries: [{ propertyName: "div", first: true, predicate: ["d"], descendants: true }], ngImport: i0, template: "<div class=\"ax-audio-wave\" #d [ngStyle]=\"{ display: audioState() === 'ready' ? 'block' : 'none' }\"></div>\n\n@switch (audioState()) {\n @case ('loading') {\n <ax-skeleton class=\"h-5 w-full rounded-full\"></ax-skeleton>\n }\n @case ('error') {\n <div class=\"ax-wave-message\">\n {{ '@acorex:error.message' | translate: { params: { message: errorMessage() } } | async }}\n </div>\n }\n}\n", styles: ["@layer components{ax-audio-wave{display:block;width:100%;flex:1}ax-audio-wave .ax-wave-message{padding-inline-start:calc(var(--spacing, .25rem) * 2);padding-inline-start:.5rem}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
365
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: AXAudioWaveComponent, isStandalone: true, selector: "ax-audio-wave", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onStatusChanged: "onStatusChanged" }, host: { properties: { "attr.aria-busy": "audioState() === \"loading\" || null", "attr.aria-invalid": "audioState() === \"error\" || null" } }, providers: [{ provide: AXComponent, useExisting: AXAudioWaveComponent }], viewQueries: [{ propertyName: "wave", first: true, predicate: ["wave"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"ax-audio-wave-host\" [class.ax-audio-wave-host--loading]=\"audioState() === 'loading'\">\n <div class=\"ax-audio-wave\" #wave [class.ax-audio-wave--hidden]=\"!isWaveVisible()\"></div>\n\n @switch (audioState()) {\n @case ('loading') {\n <ax-skeleton class=\"ax-audio-wave-skeleton\"></ax-skeleton>\n }\n @case ('error') {\n <div class=\"ax-wave-message\">\n {{ '@acorex:error.message' | translate: { params: { message: errorMessage() } } | async }}\n </div>\n }\n }\n</div>\n", styles: ["@layer properties;@layer components{ax-audio-wave{display:block;width:100%;flex:1}ax-audio-wave .ax-audio-wave-host{position:relative;display:block;width:100%}ax-audio-wave .ax-audio-wave-host--loading{min-height:1.25rem}ax-audio-wave .ax-audio-wave{width:100%}ax-audio-wave .ax-audio-wave--hidden{visibility:hidden}ax-audio-wave .ax-audio-wave-skeleton{position:absolute;inset-inline:calc(var(--spacing, .25rem) * 0);top:50%;height:calc(var(--spacing, .25rem) * 5);width:100%;--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);border-radius:calc(infinity * 1px)}ax-audio-wave .ax-wave-message{position:absolute;inset-inline:calc(var(--spacing, .25rem) * 0);top:50%;--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);padding-inline-start:calc(var(--spacing, .25rem) * 2)}}@property --tw-translate-x{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-y{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-z{syntax: \"*\"; inherits: false; initial-value: 0;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x: 0;--tw-translate-y: 0;--tw-translate-z: 0}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "component", type: AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
374
366
  }
375
367
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXAudioWaveComponent, decorators: [{
376
368
  type: Component,
377
- args: [{ selector: 'ax-audio-wave', encapsulation: ViewEncapsulation.None, imports: [NgStyle, AsyncPipe, AXTranslatorPipe, AXSkeletonComponent], providers: [{ provide: AXComponent, useExisting: AXAudioWaveComponent }], template: "<div class=\"ax-audio-wave\" #d [ngStyle]=\"{ display: audioState() === 'ready' ? 'block' : 'none' }\"></div>\n\n@switch (audioState()) {\n @case ('loading') {\n <ax-skeleton class=\"h-5 w-full rounded-full\"></ax-skeleton>\n }\n @case ('error') {\n <div class=\"ax-wave-message\">\n {{ '@acorex:error.message' | translate: { params: { message: errorMessage() } } | async }}\n </div>\n }\n}\n", styles: ["@layer components{ax-audio-wave{display:block;width:100%;flex:1}ax-audio-wave .ax-wave-message{padding-inline-start:calc(var(--spacing, .25rem) * 2);padding-inline-start:.5rem}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
378
- }], ctorParameters: () => [], propDecorators: { div: [{
379
- type: ViewChild,
380
- args: ['d', { static: false }]
381
- }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], onStatusChanged: [{ type: i0.Output, args: ["onStatusChanged"] }] } });
369
+ args: [{ selector: 'ax-audio-wave', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [AsyncPipe, AXTranslatorPipe, AXSkeletonComponent], providers: [{ provide: AXComponent, useExisting: AXAudioWaveComponent }], host: {
370
+ '[attr.aria-busy]': 'audioState() === "loading" || null',
371
+ '[attr.aria-invalid]': 'audioState() === "error" || null',
372
+ }, template: "<div class=\"ax-audio-wave-host\" [class.ax-audio-wave-host--loading]=\"audioState() === 'loading'\">\n <div class=\"ax-audio-wave\" #wave [class.ax-audio-wave--hidden]=\"!isWaveVisible()\"></div>\n\n @switch (audioState()) {\n @case ('loading') {\n <ax-skeleton class=\"ax-audio-wave-skeleton\"></ax-skeleton>\n }\n @case ('error') {\n <div class=\"ax-wave-message\">\n {{ '@acorex:error.message' | translate: { params: { message: errorMessage() } } | async }}\n </div>\n }\n }\n</div>\n", styles: ["@layer properties;@layer components{ax-audio-wave{display:block;width:100%;flex:1}ax-audio-wave .ax-audio-wave-host{position:relative;display:block;width:100%}ax-audio-wave .ax-audio-wave-host--loading{min-height:1.25rem}ax-audio-wave .ax-audio-wave{width:100%}ax-audio-wave .ax-audio-wave--hidden{visibility:hidden}ax-audio-wave .ax-audio-wave-skeleton{position:absolute;inset-inline:calc(var(--spacing, .25rem) * 0);top:50%;height:calc(var(--spacing, .25rem) * 5);width:100%;--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);border-radius:calc(infinity * 1px)}ax-audio-wave .ax-wave-message{position:absolute;inset-inline:calc(var(--spacing, .25rem) * 0);top:50%;--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);padding-inline-start:calc(var(--spacing, .25rem) * 2)}}@property --tw-translate-x{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-y{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-z{syntax: \"*\"; inherits: false; initial-value: 0;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x: 0;--tw-translate-y: 0;--tw-translate-z: 0}}}\n/*! tailwindcss v4.1.16 | MIT License | https://tailwindcss.com */\n"] }]
373
+ }], ctorParameters: () => [], propDecorators: { wave: [{ type: i0.ViewChild, args: ['wave', { isSignal: true }] }], config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: false }] }], onStatusChanged: [{ type: i0.Output, args: ["onStatusChanged"] }] } });
382
374
 
383
375
  class AXAudioWaveModule {
384
376
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXAudioWaveModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
385
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXAudioWaveModule, imports: [CommonModule,
386
- AXButtonModule,
387
- AXDecoratorModule,
388
- AXSkeletonModule,
389
- AXTranslationModule,
390
- AXAudioWaveComponent], exports: [AXAudioWaveComponent] }); }
391
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXAudioWaveModule, imports: [CommonModule,
392
- AXButtonModule,
393
- AXDecoratorModule,
394
- AXSkeletonModule,
395
- AXTranslationModule,
396
- AXAudioWaveComponent] }); }
377
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AXAudioWaveModule, imports: [AXAudioWaveComponent], exports: [AXAudioWaveComponent] }); }
378
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXAudioWaveModule, imports: [AXAudioWaveComponent] }); }
397
379
  }
398
380
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXAudioWaveModule, decorators: [{
399
381
  type: NgModule,
400
382
  args: [{
401
383
  exports: [AXAudioWaveComponent],
402
- imports: [
403
- CommonModule,
404
- AXButtonModule,
405
- AXDecoratorModule,
406
- AXSkeletonModule,
407
- AXTranslationModule,
408
- AXAudioWaveComponent,
409
- ],
384
+ imports: [AXAudioWaveComponent],
410
385
  }]
411
386
  }] });
412
387