@dragonworks/ngx-dashboard-widgets 20.1.6 → 20.3.1

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, signal, computed, Component, input, numberAttribute, booleanAttribute, ElementRef, NgZone, PLATFORM_ID, DestroyRef, Directive, ChangeDetectionStrategy, Renderer2, viewChild, effect, LOCALE_ID, afterNextRender } from '@angular/core';
2
+ import { inject, signal, computed, Component, input, numberAttribute, booleanAttribute, ElementRef, NgZone, PLATFORM_ID, DestroyRef, effect, Directive, ChangeDetectionStrategy, Renderer2, viewChild, LOCALE_ID, afterNextRender } from '@angular/core';
3
3
  import { DomSanitizer } from '@angular/platform-browser';
4
4
  import * as i2 from '@angular/material/dialog';
5
5
  import { MAT_DIALOG_DATA, MatDialogRef, MatDialogModule, MatDialog } from '@angular/material/dialog';
@@ -23,6 +23,10 @@ import { MatRadioModule } from '@angular/material/radio';
23
23
  import { from, map, of } from 'rxjs';
24
24
  import { toSignal } from '@angular/core/rxjs-interop';
25
25
 
26
+ // Auto-generated by scripts/generate-versions.js
27
+ // Do not edit manually
28
+ const NGX_DASHBOARD_WIDGETS_VERSION = '20.3.1';
29
+
26
30
  // arrow-widget.metadata.ts
27
31
  const svgIcon$3 = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M320-120v-320H120l360-440 360 440H640v320H320Zm80-80h160v-320h111L480-754 289-520h111v320Zm80-320Z"/></svg>';
28
32
 
@@ -80,25 +84,50 @@ class ArrowStateDialogComponent {
80
84
  }
81
85
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: ArrowStateDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
82
86
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.1", type: ArrowStateDialogComponent, isStandalone: true, selector: "lib-arrow-state-dialog", ngImport: i0, template: `
83
- <h2 mat-dialog-title>Arrow Settings</h2>
87
+ <h2 mat-dialog-title i18n="@@ngx.dashboard.widgets.arrow.dialog.title">
88
+ Arrow Settings
89
+ </h2>
84
90
  <mat-dialog-content>
85
91
  <!-- Direction Selection -->
86
92
  <mat-form-field appearance="outline" class="direction-field">
87
- <mat-label>Arrow Direction</mat-label>
93
+ <mat-label i18n="@@ngx.dashboard.widgets.arrow.dialog.direction"
94
+ >Arrow Direction</mat-label
95
+ >
88
96
  <mat-select
89
97
  [value]="direction()"
90
98
  (selectionChange)="direction.set($any($event.value))"
91
99
  >
92
- <mat-option value="up">Up</mat-option>
93
- <mat-option value="right">Right</mat-option>
94
- <mat-option value="down">Down</mat-option>
95
- <mat-option value="left">Left</mat-option>
100
+ <mat-option
101
+ value="up"
102
+ i18n="@@ngx.dashboard.widgets.arrow.dialog.direction.up"
103
+ >Up</mat-option
104
+ >
105
+ <mat-option
106
+ value="right"
107
+ i18n="@@ngx.dashboard.widgets.arrow.dialog.direction.right"
108
+ >Right</mat-option
109
+ >
110
+ <mat-option
111
+ value="down"
112
+ i18n="@@ngx.dashboard.widgets.arrow.dialog.direction.down"
113
+ >Down</mat-option
114
+ >
115
+ <mat-option
116
+ value="left"
117
+ i18n="@@ngx.dashboard.widgets.arrow.dialog.direction.left"
118
+ >Left</mat-option
119
+ >
96
120
  </mat-select>
97
121
  </mat-form-field>
98
122
 
99
123
  <!-- Opacity Slider -->
100
124
  <div class="slider-field">
101
- <div class="field-label">Opacity: {{ formatOpacity(opacity()) }}%</div>
125
+ <div
126
+ class="field-label"
127
+ i18n="@@ngx.dashboard.widgets.arrow.dialog.opacity"
128
+ >
129
+ Opacity: {{ formatOpacity(opacity()) }}%
130
+ </div>
102
131
  <mat-slider [min]="0.1" [max]="1" [step]="0.1">
103
132
  <input matSliderThumb [(ngModel)]="opacity" />
104
133
  </mat-slider>
@@ -106,18 +135,35 @@ class ArrowStateDialogComponent {
106
135
 
107
136
  <!-- Background Toggle -->
108
137
  <div class="toggle-field">
109
- <mat-slide-toggle
138
+ <mat-slide-toggle
110
139
  [checked]="hasBackground()"
111
- (change)="onBackgroundToggle($event.checked)">
140
+ (change)="onBackgroundToggle($event.checked)"
141
+ i18n="@@ngx.dashboard.widgets.arrow.dialog.background"
142
+ >
112
143
  Background
113
144
  </mat-slide-toggle>
114
- <span class="toggle-hint">Adds a background behind the arrow</span>
145
+ <span
146
+ class="toggle-hint"
147
+ i18n="@@ngx.dashboard.widgets.arrow.dialog.backgroundHint"
148
+ >Adds a background behind the arrow</span
149
+ >
115
150
  </div>
116
151
  </mat-dialog-content>
117
152
 
118
153
  <mat-dialog-actions align="end">
119
- <button mat-button (click)="onCancel()">Cancel</button>
120
- <button mat-flat-button (click)="save()" [disabled]="!hasChanged()">
154
+ <button
155
+ mat-button
156
+ (click)="onCancel()"
157
+ i18n="@@ngx.dashboard.common.cancel"
158
+ >
159
+ Cancel
160
+ </button>
161
+ <button
162
+ mat-flat-button
163
+ (click)="save()"
164
+ [disabled]="!hasChanged()"
165
+ i18n="@@ngx.dashboard.common.save"
166
+ >
121
167
  Save
122
168
  </button>
123
169
  </mat-dialog-actions>
@@ -135,25 +181,50 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
135
181
  MatSliderModule,
136
182
  MatSlideToggleModule,
137
183
  ], template: `
138
- <h2 mat-dialog-title>Arrow Settings</h2>
184
+ <h2 mat-dialog-title i18n="@@ngx.dashboard.widgets.arrow.dialog.title">
185
+ Arrow Settings
186
+ </h2>
139
187
  <mat-dialog-content>
140
188
  <!-- Direction Selection -->
141
189
  <mat-form-field appearance="outline" class="direction-field">
142
- <mat-label>Arrow Direction</mat-label>
190
+ <mat-label i18n="@@ngx.dashboard.widgets.arrow.dialog.direction"
191
+ >Arrow Direction</mat-label
192
+ >
143
193
  <mat-select
144
194
  [value]="direction()"
145
195
  (selectionChange)="direction.set($any($event.value))"
146
196
  >
147
- <mat-option value="up">Up</mat-option>
148
- <mat-option value="right">Right</mat-option>
149
- <mat-option value="down">Down</mat-option>
150
- <mat-option value="left">Left</mat-option>
197
+ <mat-option
198
+ value="up"
199
+ i18n="@@ngx.dashboard.widgets.arrow.dialog.direction.up"
200
+ >Up</mat-option
201
+ >
202
+ <mat-option
203
+ value="right"
204
+ i18n="@@ngx.dashboard.widgets.arrow.dialog.direction.right"
205
+ >Right</mat-option
206
+ >
207
+ <mat-option
208
+ value="down"
209
+ i18n="@@ngx.dashboard.widgets.arrow.dialog.direction.down"
210
+ >Down</mat-option
211
+ >
212
+ <mat-option
213
+ value="left"
214
+ i18n="@@ngx.dashboard.widgets.arrow.dialog.direction.left"
215
+ >Left</mat-option
216
+ >
151
217
  </mat-select>
152
218
  </mat-form-field>
153
219
 
154
220
  <!-- Opacity Slider -->
155
221
  <div class="slider-field">
156
- <div class="field-label">Opacity: {{ formatOpacity(opacity()) }}%</div>
222
+ <div
223
+ class="field-label"
224
+ i18n="@@ngx.dashboard.widgets.arrow.dialog.opacity"
225
+ >
226
+ Opacity: {{ formatOpacity(opacity()) }}%
227
+ </div>
157
228
  <mat-slider [min]="0.1" [max]="1" [step]="0.1">
158
229
  <input matSliderThumb [(ngModel)]="opacity" />
159
230
  </mat-slider>
@@ -161,18 +232,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
161
232
 
162
233
  <!-- Background Toggle -->
163
234
  <div class="toggle-field">
164
- <mat-slide-toggle
235
+ <mat-slide-toggle
165
236
  [checked]="hasBackground()"
166
- (change)="onBackgroundToggle($event.checked)">
237
+ (change)="onBackgroundToggle($event.checked)"
238
+ i18n="@@ngx.dashboard.widgets.arrow.dialog.background"
239
+ >
167
240
  Background
168
241
  </mat-slide-toggle>
169
- <span class="toggle-hint">Adds a background behind the arrow</span>
242
+ <span
243
+ class="toggle-hint"
244
+ i18n="@@ngx.dashboard.widgets.arrow.dialog.backgroundHint"
245
+ >Adds a background behind the arrow</span
246
+ >
170
247
  </div>
171
248
  </mat-dialog-content>
172
249
 
173
250
  <mat-dialog-actions align="end">
174
- <button mat-button (click)="onCancel()">Cancel</button>
175
- <button mat-flat-button (click)="save()" [disabled]="!hasChanged()">
251
+ <button
252
+ mat-button
253
+ (click)="onCancel()"
254
+ i18n="@@ngx.dashboard.common.cancel"
255
+ >
256
+ Cancel
257
+ </button>
258
+ <button
259
+ mat-flat-button
260
+ (click)="save()"
261
+ [disabled]="!hasChanged()"
262
+ i18n="@@ngx.dashboard.common.save"
263
+ >
176
264
  Save
177
265
  </button>
178
266
  </mat-dialog-actions>
@@ -183,8 +271,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
183
271
  class ArrowWidgetComponent {
184
272
  static metadata = {
185
273
  widgetTypeid: '@ngx-dashboard/arrow-widget',
186
- name: 'Arrow',
187
- description: 'A generic arrow',
274
+ name: $localize `:@@ngx.dashboard.widgets.arrow.name:Arrow`,
275
+ description: $localize `:@@ngx.dashboard.widgets.arrow.description:A generic arrow`,
188
276
  svgIcon: svgIcon$3,
189
277
  };
190
278
  #sanitizer = inject(DomSanitizer);
@@ -256,6 +344,7 @@ class LabelStateDialogComponent {
256
344
  // Responsive font size constraints
257
345
  minFontSize = signal(this.data.minFontSize ?? 8, ...(ngDevMode ? [{ debugName: "minFontSize" }] : []));
258
346
  maxFontSize = signal(this.data.maxFontSize ?? 64, ...(ngDevMode ? [{ debugName: "maxFontSize" }] : []));
347
+ templateString = signal(this.data.templateString, ...(ngDevMode ? [{ debugName: "templateString" }] : []));
259
348
  // Store original values for comparison
260
349
  originalLabel = this.data.label ?? '';
261
350
  originalFontSize = this.data.fontSize ?? 16;
@@ -266,6 +355,7 @@ class LabelStateDialogComponent {
266
355
  originalResponsive = this.data.responsive ?? false;
267
356
  originalMinFontSize = this.data.minFontSize ?? 8;
268
357
  originalMaxFontSize = this.data.maxFontSize ?? 64;
358
+ originalTemplateString = this.data.templateString;
269
359
  // Validation computed properties
270
360
  isMinFontSizeValid = computed(() => {
271
361
  const min = this.minFontSize();
@@ -288,7 +378,8 @@ class LabelStateDialogComponent {
288
378
  this.hasBackground() !== this.originalHasBackground ||
289
379
  this.responsive() !== this.originalResponsive ||
290
380
  this.minFontSize() !== this.originalMinFontSize ||
291
- this.maxFontSize() !== this.originalMaxFontSize, ...(ngDevMode ? [{ debugName: "hasChanged" }] : []));
381
+ this.maxFontSize() !== this.originalMaxFontSize ||
382
+ this.templateString() !== this.originalTemplateString, ...(ngDevMode ? [{ debugName: "hasChanged" }] : []));
292
383
  formatOpacity(value) {
293
384
  return Math.round(value * 100);
294
385
  }
@@ -324,7 +415,7 @@ class LabelStateDialogComponent {
324
415
  this.dialogRef.close();
325
416
  }
326
417
  save() {
327
- this.dialogRef.close({
418
+ const state = {
328
419
  label: this.label(),
329
420
  fontSize: this.fontSize(),
330
421
  alignment: this.alignment(),
@@ -334,96 +425,158 @@ class LabelStateDialogComponent {
334
425
  responsive: this.responsive(),
335
426
  minFontSize: this.minFontSize(),
336
427
  maxFontSize: this.maxFontSize(),
337
- });
428
+ };
429
+ // Only include templateString if it has a value
430
+ const templateString = this.templateString();
431
+ if (templateString) {
432
+ state.templateString = templateString;
433
+ }
434
+ this.dialogRef.close(state);
338
435
  }
339
436
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: LabelStateDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
340
437
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: LabelStateDialogComponent, isStandalone: true, selector: "lib-label-state-dialog", ngImport: i0, template: `
341
- <h2 mat-dialog-title>Label Settings</h2>
438
+ <h2 mat-dialog-title i18n="@@ngx.dashboard.widgets.label.dialog.title">
439
+ Label Settings
440
+ </h2>
342
441
  <mat-dialog-content>
343
442
  <mat-form-field appearance="outline" class="label-text-field">
344
- <mat-label>Label Text</mat-label>
443
+ <mat-label i18n="@@ngx.dashboard.widgets.label.dialog.labelText"
444
+ >Label Text</mat-label
445
+ >
345
446
  <input
346
447
  matInput
347
448
  type="text"
348
449
  [value]="label()"
349
450
  (input)="label.set($any($event.target).value)"
451
+ i18n-placeholder="@@ngx.dashboard.widgets.label.dialog.placeholder"
350
452
  placeholder="Enter your label text..."
351
453
  />
352
454
  </mat-form-field>
353
455
 
354
456
  <!-- Responsive Text Toggle -->
355
457
  <div class="toggle-section">
356
- <mat-slide-toggle
458
+ <mat-slide-toggle
357
459
  [checked]="responsive()"
358
- (change)="responsive.set($event.checked)">
460
+ (change)="responsive.set($event.checked)"
461
+ i18n="@@ngx.dashboard.widgets.label.dialog.responsive"
462
+ >
359
463
  Responsive Text
360
464
  </mat-slide-toggle>
361
- <span class="toggle-description"
465
+ <span
466
+ class="toggle-description"
467
+ i18n="@@ngx.dashboard.widgets.label.dialog.responsiveDescription"
362
468
  >Automatically adjust text size to fit the widget</span
363
469
  >
364
470
  </div>
365
471
 
366
472
  <!-- Responsive Font Size Constraints (only shown when responsive is enabled) -->
367
473
  @if (responsive()) {
368
- <div class="responsive-section">
369
- <div class="section-label">Font Size Limits</div>
370
- <div class="row-layout">
371
- <mat-form-field appearance="outline">
372
- <mat-label>Min Size (px)</mat-label>
373
- <input
374
- matInput
375
- type="number"
376
- [value]="minFontSize()"
377
- (input)="validateAndCorrectMinFontSize(+$any($event.target).value)"
378
- (blur)="validateAndCorrectMinFontSize(minFontSize())"
379
- min="8"
380
- max="24"
381
- placeholder="8"
382
- />
383
- @if (!isMinFontSizeValid() || !isFontSizeRangeValid()) {
384
- <mat-error>
385
- @if (!isMinFontSizeValid()) {
386
- Must be between 8-24px
387
- } @else {
388
- Must be less than max size
389
- }
390
- </mat-error>
474
+ <div class="responsive-section">
475
+ <div
476
+ class="section-label"
477
+ i18n="@@ngx.dashboard.widgets.label.dialog.fontSizeLimits"
478
+ >
479
+ Font Size Limits
480
+ </div>
481
+ <div class="row-layout">
482
+ <mat-form-field appearance="outline">
483
+ <mat-label i18n="@@ngx.dashboard.widgets.label.dialog.minSize"
484
+ >Min Size (px)</mat-label
485
+ >
486
+ <input
487
+ matInput
488
+ type="number"
489
+ [value]="minFontSize()"
490
+ (input)="
491
+ validateAndCorrectMinFontSize(+$any($event.target).value)
492
+ "
493
+ (blur)="validateAndCorrectMinFontSize(minFontSize())"
494
+ min="8"
495
+ max="24"
496
+ placeholder="8"
497
+ />
498
+ @if (!isMinFontSizeValid() || !isFontSizeRangeValid()) {
499
+ <mat-error>
500
+ @if (!isMinFontSizeValid()) {
501
+ <span i18n="@@ngx.dashboard.widgets.label.dialog.minSizeError"
502
+ >Must be between 8-24px</span
503
+ >
391
504
  } @else {
392
- <mat-hint>8-24px range</mat-hint>
505
+ <span
506
+ i18n="@@ngx.dashboard.widgets.label.dialog.minSizeRangeError"
507
+ >Must be less than max size</span
508
+ >
393
509
  }
394
- </mat-form-field>
510
+ </mat-error>
511
+ } @else {
512
+ <mat-hint i18n="@@ngx.dashboard.widgets.label.dialog.minSizeHint"
513
+ >8-24px range</mat-hint
514
+ >
515
+ }
516
+ </mat-form-field>
395
517
 
396
- <mat-form-field appearance="outline">
397
- <mat-label>Max Size (px)</mat-label>
398
- <input
399
- matInput
400
- type="number"
401
- [value]="maxFontSize()"
402
- (input)="validateAndCorrectMaxFontSize(+$any($event.target).value)"
403
- (blur)="validateAndCorrectMaxFontSize(maxFontSize())"
404
- min="16"
405
- max="128"
406
- placeholder="64"
407
- />
408
- @if (!isMaxFontSizeValid() || !isFontSizeRangeValid()) {
409
- <mat-error>
410
- @if (!isMaxFontSizeValid()) {
411
- Must be between 16-128px
412
- } @else {
413
- Must be greater than min size
414
- }
415
- </mat-error>
518
+ <mat-form-field appearance="outline">
519
+ <mat-label i18n="@@ngx.dashboard.widgets.label.dialog.maxSize"
520
+ >Max Size (px)</mat-label
521
+ >
522
+ <input
523
+ matInput
524
+ type="number"
525
+ [value]="maxFontSize()"
526
+ (input)="
527
+ validateAndCorrectMaxFontSize(+$any($event.target).value)
528
+ "
529
+ (blur)="validateAndCorrectMaxFontSize(maxFontSize())"
530
+ min="16"
531
+ max="128"
532
+ placeholder="64"
533
+ />
534
+ @if (!isMaxFontSizeValid() || !isFontSizeRangeValid()) {
535
+ <mat-error>
536
+ @if (!isMaxFontSizeValid()) {
537
+ <span i18n="@@ngx.dashboard.widgets.label.dialog.maxSizeError"
538
+ >Must be between 16-128px</span
539
+ >
416
540
  } @else {
417
- <mat-hint>16-128px range</mat-hint>
541
+ <span
542
+ i18n="@@ngx.dashboard.widgets.label.dialog.maxSizeRangeError"
543
+ >Must be greater than min size</span
544
+ >
418
545
  }
419
- </mat-form-field>
420
- </div>
546
+ </mat-error>
547
+ } @else {
548
+ <mat-hint i18n="@@ngx.dashboard.widgets.label.dialog.maxSizeHint"
549
+ >16-128px range</mat-hint
550
+ >
551
+ }
552
+ </mat-form-field>
421
553
  </div>
554
+
555
+ <!-- Template String field -->
556
+ <mat-form-field appearance="outline">
557
+ <mat-label i18n="@@ngx.dashboard.widgets.label.dialog.templateString"
558
+ >Template String</mat-label
559
+ >
560
+ <input
561
+ matInput
562
+ type="text"
563
+ [value]="templateString() || ''"
564
+ (input)="templateString.set($any($event.target).value || undefined)"
565
+ i18n-placeholder="@@ngx.dashboard.widgets.label.dialog.templateStringPlaceholder"
566
+ placeholder="Optional: Text to use for size calculation"
567
+ />
568
+ <mat-hint i18n="@@ngx.dashboard.widgets.label.dialog.templateStringHint"
569
+ >Use when displayed text varies but size should remain consistent</mat-hint
570
+ >
571
+ </mat-form-field>
572
+ </div>
422
573
  }
423
574
 
424
575
  <div class="row-layout">
425
576
  <mat-form-field appearance="outline">
426
- <mat-label>Font Size (px)</mat-label>
577
+ <mat-label i18n="@@ngx.dashboard.widgets.label.dialog.fontSize"
578
+ >Font Size (px)</mat-label
579
+ >
427
580
  <input
428
581
  matInput
429
582
  type="number"
@@ -437,32 +590,61 @@ class LabelStateDialogComponent {
437
590
  </mat-form-field>
438
591
 
439
592
  <mat-form-field appearance="outline">
440
- <mat-label>Alignment</mat-label>
593
+ <mat-label i18n="@@ngx.dashboard.widgets.label.dialog.alignment"
594
+ >Alignment</mat-label
595
+ >
441
596
  <mat-select
442
597
  [value]="alignment()"
443
598
  (selectionChange)="alignment.set($any($event.value))"
444
599
  >
445
- <mat-option value="left">Left</mat-option>
446
- <mat-option value="center">Center</mat-option>
447
- <mat-option value="right">Right</mat-option>
600
+ <mat-option
601
+ value="left"
602
+ i18n="@@ngx.dashboard.widgets.label.dialog.alignment.left"
603
+ >Left</mat-option
604
+ >
605
+ <mat-option
606
+ value="center"
607
+ i18n="@@ngx.dashboard.widgets.label.dialog.alignment.center"
608
+ >Center</mat-option
609
+ >
610
+ <mat-option
611
+ value="right"
612
+ i18n="@@ngx.dashboard.widgets.label.dialog.alignment.right"
613
+ >Right</mat-option
614
+ >
448
615
  </mat-select>
449
616
  </mat-form-field>
450
617
  </div>
451
618
 
452
619
  <mat-form-field appearance="outline">
453
- <mat-label>Font Weight</mat-label>
620
+ <mat-label i18n="@@ngx.dashboard.widgets.label.dialog.fontWeight"
621
+ >Font Weight</mat-label
622
+ >
454
623
  <mat-select
455
624
  [value]="fontWeight()"
456
625
  (selectionChange)="fontWeight.set($any($event.value))"
457
626
  >
458
- <mat-option value="normal">Normal</mat-option>
459
- <mat-option value="bold">Bold</mat-option>
627
+ <mat-option
628
+ value="normal"
629
+ i18n="@@ngx.dashboard.widgets.label.dialog.fontWeight.normal"
630
+ >Normal</mat-option
631
+ >
632
+ <mat-option
633
+ value="bold"
634
+ i18n="@@ngx.dashboard.widgets.label.dialog.fontWeight.bold"
635
+ >Bold</mat-option
636
+ >
460
637
  </mat-select>
461
638
  </mat-form-field>
462
639
 
463
640
  <!-- Opacity Slider -->
464
641
  <div class="slider-section">
465
- <div class="slider-label">Opacity: {{ formatOpacity(opacity()) }}%</div>
642
+ <div
643
+ class="slider-label"
644
+ i18n="@@ngx.dashboard.widgets.label.dialog.opacity"
645
+ >
646
+ Opacity: {{ formatOpacity(opacity()) }}%
647
+ </div>
466
648
  <mat-slider [min]="0.1" [max]="1" [step]="0.1">
467
649
  <input matSliderThumb [(ngModel)]="opacity" />
468
650
  </mat-slider>
@@ -470,24 +652,39 @@ class LabelStateDialogComponent {
470
652
 
471
653
  <!-- Background Toggle -->
472
654
  <div class="toggle-section">
473
- <mat-slide-toggle
655
+ <mat-slide-toggle
474
656
  [checked]="!transparentBackground()"
475
- (change)="onBackgroundToggle($event.checked)">
657
+ (change)="onBackgroundToggle($event.checked)"
658
+ i18n="@@ngx.dashboard.widgets.label.dialog.background"
659
+ >
476
660
  Background
477
661
  </mat-slide-toggle>
478
- <span class="toggle-description"
662
+ <span
663
+ class="toggle-description"
664
+ i18n="@@ngx.dashboard.widgets.label.dialog.backgroundDescription"
479
665
  >Adds a background behind the text</span
480
666
  >
481
667
  </div>
482
668
  </mat-dialog-content>
483
669
 
484
670
  <mat-dialog-actions align="end">
485
- <button mat-button (click)="onCancel()">Cancel</button>
486
- <button mat-flat-button (click)="save()" [disabled]="!hasChanged() || !isFormValid()">
671
+ <button
672
+ mat-button
673
+ (click)="onCancel()"
674
+ i18n="@@ngx.dashboard.common.cancel"
675
+ >
676
+ Cancel
677
+ </button>
678
+ <button
679
+ mat-flat-button
680
+ (click)="save()"
681
+ [disabled]="!hasChanged() || !isFormValid()"
682
+ i18n="@@ngx.dashboard.common.save"
683
+ >
487
684
  Save
488
685
  </button>
489
686
  </mat-dialog-actions>
490
- `, isInline: true, styles: ["mat-dialog-content{display:block;overflow-y:auto;overflow-x:hidden}mat-form-field{width:100%;display:block;margin-bottom:1rem}.label-text-field{margin-top:1rem}.row-layout{display:grid;grid-template-columns:1fr 1fr;gap:1rem;margin-bottom:1rem}.row-layout mat-form-field{margin-bottom:0}.slider-section{margin-bottom:1.5rem;margin-right:1rem}.slider-label{display:block;margin-bottom:.5rem}mat-slider{width:100%;display:block}.toggle-section{display:flex;align-items:center;gap:.75rem;margin-bottom:1rem}.toggle-description{margin:0}.responsive-section{margin-bottom:1.5rem;padding:1rem;border-radius:12px;background-color:var(--mat-app-surface-variant, rgba(var(--mat-app-on-surface-rgb, 0, 0, 0), .05));border:1px solid var(--mat-app-outline-variant, rgba(var(--mat-app-on-surface-rgb, 0, 0, 0), .12))}.section-label{display:block;margin-bottom:.75rem;font-weight:500;color:var(--mat-app-on-surface-variant, rgba(var(--mat-app-on-surface-rgb, 0, 0, 0), .6))}.responsive-section .row-layout{margin-bottom:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: i6.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: i6.MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i7.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }] });
687
+ `, isInline: true, styles: ["mat-dialog-content{display:block;overflow-y:auto;overflow-x:hidden}mat-form-field{width:100%;display:block;margin-bottom:1rem}.label-text-field{margin-top:1rem}.row-layout{display:grid;grid-template-columns:1fr 1fr;gap:1rem;margin-bottom:1rem}.row-layout mat-form-field{margin-bottom:0}.slider-section{margin-bottom:1.5rem;margin-right:1rem}.slider-label{display:block;margin-bottom:.5rem}mat-slider{width:100%;display:block}.toggle-section{display:flex;align-items:center;gap:.75rem;margin-bottom:1rem}.toggle-description{margin:0}.responsive-section{margin-bottom:1.5rem;padding:1rem;border-radius:12px;background-color:var( --mat-app-surface-variant, rgba(var(--mat-app-on-surface-rgb, 0, 0, 0), .05) );border:1px solid var( --mat-app-outline-variant, rgba(var(--mat-app-on-surface-rgb, 0, 0, 0), .12) )}.section-label{display:block;margin-bottom:.75rem;font-weight:500;color:var( --mat-app-on-surface-variant, rgba(var(--mat-app-on-surface-rgb, 0, 0, 0), .6) )}.responsive-section .row-layout{margin-bottom:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "directive", type: i4.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i4.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i5.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i5.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: i6.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: i6.MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i7.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }] });
491
688
  }
492
689
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: LabelStateDialogComponent, decorators: [{
493
690
  type: Component,
@@ -502,92 +699,148 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
502
699
  MatSliderModule,
503
700
  MatSlideToggleModule, // Add this import
504
701
  ], template: `
505
- <h2 mat-dialog-title>Label Settings</h2>
702
+ <h2 mat-dialog-title i18n="@@ngx.dashboard.widgets.label.dialog.title">
703
+ Label Settings
704
+ </h2>
506
705
  <mat-dialog-content>
507
706
  <mat-form-field appearance="outline" class="label-text-field">
508
- <mat-label>Label Text</mat-label>
707
+ <mat-label i18n="@@ngx.dashboard.widgets.label.dialog.labelText"
708
+ >Label Text</mat-label
709
+ >
509
710
  <input
510
711
  matInput
511
712
  type="text"
512
713
  [value]="label()"
513
714
  (input)="label.set($any($event.target).value)"
715
+ i18n-placeholder="@@ngx.dashboard.widgets.label.dialog.placeholder"
514
716
  placeholder="Enter your label text..."
515
717
  />
516
718
  </mat-form-field>
517
719
 
518
720
  <!-- Responsive Text Toggle -->
519
721
  <div class="toggle-section">
520
- <mat-slide-toggle
722
+ <mat-slide-toggle
521
723
  [checked]="responsive()"
522
- (change)="responsive.set($event.checked)">
724
+ (change)="responsive.set($event.checked)"
725
+ i18n="@@ngx.dashboard.widgets.label.dialog.responsive"
726
+ >
523
727
  Responsive Text
524
728
  </mat-slide-toggle>
525
- <span class="toggle-description"
729
+ <span
730
+ class="toggle-description"
731
+ i18n="@@ngx.dashboard.widgets.label.dialog.responsiveDescription"
526
732
  >Automatically adjust text size to fit the widget</span
527
733
  >
528
734
  </div>
529
735
 
530
736
  <!-- Responsive Font Size Constraints (only shown when responsive is enabled) -->
531
737
  @if (responsive()) {
532
- <div class="responsive-section">
533
- <div class="section-label">Font Size Limits</div>
534
- <div class="row-layout">
535
- <mat-form-field appearance="outline">
536
- <mat-label>Min Size (px)</mat-label>
537
- <input
538
- matInput
539
- type="number"
540
- [value]="minFontSize()"
541
- (input)="validateAndCorrectMinFontSize(+$any($event.target).value)"
542
- (blur)="validateAndCorrectMinFontSize(minFontSize())"
543
- min="8"
544
- max="24"
545
- placeholder="8"
546
- />
547
- @if (!isMinFontSizeValid() || !isFontSizeRangeValid()) {
548
- <mat-error>
549
- @if (!isMinFontSizeValid()) {
550
- Must be between 8-24px
551
- } @else {
552
- Must be less than max size
553
- }
554
- </mat-error>
738
+ <div class="responsive-section">
739
+ <div
740
+ class="section-label"
741
+ i18n="@@ngx.dashboard.widgets.label.dialog.fontSizeLimits"
742
+ >
743
+ Font Size Limits
744
+ </div>
745
+ <div class="row-layout">
746
+ <mat-form-field appearance="outline">
747
+ <mat-label i18n="@@ngx.dashboard.widgets.label.dialog.minSize"
748
+ >Min Size (px)</mat-label
749
+ >
750
+ <input
751
+ matInput
752
+ type="number"
753
+ [value]="minFontSize()"
754
+ (input)="
755
+ validateAndCorrectMinFontSize(+$any($event.target).value)
756
+ "
757
+ (blur)="validateAndCorrectMinFontSize(minFontSize())"
758
+ min="8"
759
+ max="24"
760
+ placeholder="8"
761
+ />
762
+ @if (!isMinFontSizeValid() || !isFontSizeRangeValid()) {
763
+ <mat-error>
764
+ @if (!isMinFontSizeValid()) {
765
+ <span i18n="@@ngx.dashboard.widgets.label.dialog.minSizeError"
766
+ >Must be between 8-24px</span
767
+ >
555
768
  } @else {
556
- <mat-hint>8-24px range</mat-hint>
769
+ <span
770
+ i18n="@@ngx.dashboard.widgets.label.dialog.minSizeRangeError"
771
+ >Must be less than max size</span
772
+ >
557
773
  }
558
- </mat-form-field>
774
+ </mat-error>
775
+ } @else {
776
+ <mat-hint i18n="@@ngx.dashboard.widgets.label.dialog.minSizeHint"
777
+ >8-24px range</mat-hint
778
+ >
779
+ }
780
+ </mat-form-field>
559
781
 
560
- <mat-form-field appearance="outline">
561
- <mat-label>Max Size (px)</mat-label>
562
- <input
563
- matInput
564
- type="number"
565
- [value]="maxFontSize()"
566
- (input)="validateAndCorrectMaxFontSize(+$any($event.target).value)"
567
- (blur)="validateAndCorrectMaxFontSize(maxFontSize())"
568
- min="16"
569
- max="128"
570
- placeholder="64"
571
- />
572
- @if (!isMaxFontSizeValid() || !isFontSizeRangeValid()) {
573
- <mat-error>
574
- @if (!isMaxFontSizeValid()) {
575
- Must be between 16-128px
576
- } @else {
577
- Must be greater than min size
578
- }
579
- </mat-error>
782
+ <mat-form-field appearance="outline">
783
+ <mat-label i18n="@@ngx.dashboard.widgets.label.dialog.maxSize"
784
+ >Max Size (px)</mat-label
785
+ >
786
+ <input
787
+ matInput
788
+ type="number"
789
+ [value]="maxFontSize()"
790
+ (input)="
791
+ validateAndCorrectMaxFontSize(+$any($event.target).value)
792
+ "
793
+ (blur)="validateAndCorrectMaxFontSize(maxFontSize())"
794
+ min="16"
795
+ max="128"
796
+ placeholder="64"
797
+ />
798
+ @if (!isMaxFontSizeValid() || !isFontSizeRangeValid()) {
799
+ <mat-error>
800
+ @if (!isMaxFontSizeValid()) {
801
+ <span i18n="@@ngx.dashboard.widgets.label.dialog.maxSizeError"
802
+ >Must be between 16-128px</span
803
+ >
580
804
  } @else {
581
- <mat-hint>16-128px range</mat-hint>
805
+ <span
806
+ i18n="@@ngx.dashboard.widgets.label.dialog.maxSizeRangeError"
807
+ >Must be greater than min size</span
808
+ >
582
809
  }
583
- </mat-form-field>
584
- </div>
810
+ </mat-error>
811
+ } @else {
812
+ <mat-hint i18n="@@ngx.dashboard.widgets.label.dialog.maxSizeHint"
813
+ >16-128px range</mat-hint
814
+ >
815
+ }
816
+ </mat-form-field>
585
817
  </div>
818
+
819
+ <!-- Template String field -->
820
+ <mat-form-field appearance="outline">
821
+ <mat-label i18n="@@ngx.dashboard.widgets.label.dialog.templateString"
822
+ >Template String</mat-label
823
+ >
824
+ <input
825
+ matInput
826
+ type="text"
827
+ [value]="templateString() || ''"
828
+ (input)="templateString.set($any($event.target).value || undefined)"
829
+ i18n-placeholder="@@ngx.dashboard.widgets.label.dialog.templateStringPlaceholder"
830
+ placeholder="Optional: Text to use for size calculation"
831
+ />
832
+ <mat-hint i18n="@@ngx.dashboard.widgets.label.dialog.templateStringHint"
833
+ >Use when displayed text varies but size should remain consistent</mat-hint
834
+ >
835
+ </mat-form-field>
836
+ </div>
586
837
  }
587
838
 
588
839
  <div class="row-layout">
589
840
  <mat-form-field appearance="outline">
590
- <mat-label>Font Size (px)</mat-label>
841
+ <mat-label i18n="@@ngx.dashboard.widgets.label.dialog.fontSize"
842
+ >Font Size (px)</mat-label
843
+ >
591
844
  <input
592
845
  matInput
593
846
  type="number"
@@ -601,32 +854,61 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
601
854
  </mat-form-field>
602
855
 
603
856
  <mat-form-field appearance="outline">
604
- <mat-label>Alignment</mat-label>
857
+ <mat-label i18n="@@ngx.dashboard.widgets.label.dialog.alignment"
858
+ >Alignment</mat-label
859
+ >
605
860
  <mat-select
606
861
  [value]="alignment()"
607
862
  (selectionChange)="alignment.set($any($event.value))"
608
863
  >
609
- <mat-option value="left">Left</mat-option>
610
- <mat-option value="center">Center</mat-option>
611
- <mat-option value="right">Right</mat-option>
864
+ <mat-option
865
+ value="left"
866
+ i18n="@@ngx.dashboard.widgets.label.dialog.alignment.left"
867
+ >Left</mat-option
868
+ >
869
+ <mat-option
870
+ value="center"
871
+ i18n="@@ngx.dashboard.widgets.label.dialog.alignment.center"
872
+ >Center</mat-option
873
+ >
874
+ <mat-option
875
+ value="right"
876
+ i18n="@@ngx.dashboard.widgets.label.dialog.alignment.right"
877
+ >Right</mat-option
878
+ >
612
879
  </mat-select>
613
880
  </mat-form-field>
614
881
  </div>
615
882
 
616
883
  <mat-form-field appearance="outline">
617
- <mat-label>Font Weight</mat-label>
884
+ <mat-label i18n="@@ngx.dashboard.widgets.label.dialog.fontWeight"
885
+ >Font Weight</mat-label
886
+ >
618
887
  <mat-select
619
888
  [value]="fontWeight()"
620
889
  (selectionChange)="fontWeight.set($any($event.value))"
621
890
  >
622
- <mat-option value="normal">Normal</mat-option>
623
- <mat-option value="bold">Bold</mat-option>
891
+ <mat-option
892
+ value="normal"
893
+ i18n="@@ngx.dashboard.widgets.label.dialog.fontWeight.normal"
894
+ >Normal</mat-option
895
+ >
896
+ <mat-option
897
+ value="bold"
898
+ i18n="@@ngx.dashboard.widgets.label.dialog.fontWeight.bold"
899
+ >Bold</mat-option
900
+ >
624
901
  </mat-select>
625
902
  </mat-form-field>
626
903
 
627
904
  <!-- Opacity Slider -->
628
905
  <div class="slider-section">
629
- <div class="slider-label">Opacity: {{ formatOpacity(opacity()) }}%</div>
906
+ <div
907
+ class="slider-label"
908
+ i18n="@@ngx.dashboard.widgets.label.dialog.opacity"
909
+ >
910
+ Opacity: {{ formatOpacity(opacity()) }}%
911
+ </div>
630
912
  <mat-slider [min]="0.1" [max]="1" [step]="0.1">
631
913
  <input matSliderThumb [(ngModel)]="opacity" />
632
914
  </mat-slider>
@@ -634,24 +916,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
634
916
 
635
917
  <!-- Background Toggle -->
636
918
  <div class="toggle-section">
637
- <mat-slide-toggle
919
+ <mat-slide-toggle
638
920
  [checked]="!transparentBackground()"
639
- (change)="onBackgroundToggle($event.checked)">
921
+ (change)="onBackgroundToggle($event.checked)"
922
+ i18n="@@ngx.dashboard.widgets.label.dialog.background"
923
+ >
640
924
  Background
641
925
  </mat-slide-toggle>
642
- <span class="toggle-description"
926
+ <span
927
+ class="toggle-description"
928
+ i18n="@@ngx.dashboard.widgets.label.dialog.backgroundDescription"
643
929
  >Adds a background behind the text</span
644
930
  >
645
931
  </div>
646
932
  </mat-dialog-content>
647
933
 
648
934
  <mat-dialog-actions align="end">
649
- <button mat-button (click)="onCancel()">Cancel</button>
650
- <button mat-flat-button (click)="save()" [disabled]="!hasChanged() || !isFormValid()">
935
+ <button
936
+ mat-button
937
+ (click)="onCancel()"
938
+ i18n="@@ngx.dashboard.common.cancel"
939
+ >
940
+ Cancel
941
+ </button>
942
+ <button
943
+ mat-flat-button
944
+ (click)="save()"
945
+ [disabled]="!hasChanged() || !isFormValid()"
946
+ i18n="@@ngx.dashboard.common.save"
947
+ >
651
948
  Save
652
949
  </button>
653
950
  </mat-dialog-actions>
654
- `, styles: ["mat-dialog-content{display:block;overflow-y:auto;overflow-x:hidden}mat-form-field{width:100%;display:block;margin-bottom:1rem}.label-text-field{margin-top:1rem}.row-layout{display:grid;grid-template-columns:1fr 1fr;gap:1rem;margin-bottom:1rem}.row-layout mat-form-field{margin-bottom:0}.slider-section{margin-bottom:1.5rem;margin-right:1rem}.slider-label{display:block;margin-bottom:.5rem}mat-slider{width:100%;display:block}.toggle-section{display:flex;align-items:center;gap:.75rem;margin-bottom:1rem}.toggle-description{margin:0}.responsive-section{margin-bottom:1.5rem;padding:1rem;border-radius:12px;background-color:var(--mat-app-surface-variant, rgba(var(--mat-app-on-surface-rgb, 0, 0, 0), .05));border:1px solid var(--mat-app-outline-variant, rgba(var(--mat-app-on-surface-rgb, 0, 0, 0), .12))}.section-label{display:block;margin-bottom:.75rem;font-weight:500;color:var(--mat-app-on-surface-variant, rgba(var(--mat-app-on-surface-rgb, 0, 0, 0), .6))}.responsive-section .row-layout{margin-bottom:0}\n"] }]
951
+ `, styles: ["mat-dialog-content{display:block;overflow-y:auto;overflow-x:hidden}mat-form-field{width:100%;display:block;margin-bottom:1rem}.label-text-field{margin-top:1rem}.row-layout{display:grid;grid-template-columns:1fr 1fr;gap:1rem;margin-bottom:1rem}.row-layout mat-form-field{margin-bottom:0}.slider-section{margin-bottom:1.5rem;margin-right:1rem}.slider-label{display:block;margin-bottom:.5rem}mat-slider{width:100%;display:block}.toggle-section{display:flex;align-items:center;gap:.75rem;margin-bottom:1rem}.toggle-description{margin:0}.responsive-section{margin-bottom:1.5rem;padding:1rem;border-radius:12px;background-color:var( --mat-app-surface-variant, rgba(var(--mat-app-on-surface-rgb, 0, 0, 0), .05) );border:1px solid var( --mat-app-outline-variant, rgba(var(--mat-app-on-surface-rgb, 0, 0, 0), .12) )}.section-label{display:block;margin-bottom:.75rem;font-weight:500;color:var( --mat-app-on-surface-variant, rgba(var(--mat-app-on-surface-rgb, 0, 0, 0), .6) )}.responsive-section .row-layout{margin-bottom:0}\n"] }]
655
952
  }] });
656
953
 
657
954
  /**
@@ -660,7 +957,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
660
957
  *
661
958
  * @example
662
959
  * <div class="container">
663
- * <span responsiveText [minFontSize]="12" [maxFontSize]="72">Dynamic text here</span>
960
+ * <span libResponsiveText [minFontSize]="12" [maxFontSize]="72">Dynamic text here</span>
961
+ * <span libResponsiveText [templateString]="'Template for sizing'">Shorter text</span>
664
962
  * </div>
665
963
  */
666
964
  class ResponsiveTextDirective {
@@ -678,6 +976,8 @@ class ResponsiveTextDirective {
678
976
  observeMutations = input(true, ...(ngDevMode ? [{ debugName: "observeMutations", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
679
977
  /** Debounce delay in ms for resize/mutation callbacks */
680
978
  debounceMs = input(16, ...(ngDevMode ? [{ debugName: "debounceMs", transform: numberAttribute }] : [{ transform: numberAttribute }]));
979
+ /** Template string to use for size calculations instead of actual content */
980
+ templateString = input(undefined, ...(ngDevMode ? [{ debugName: "templateString" }] : []));
681
981
  /* ───────────────────────── Private state ───────────────────────── */
682
982
  el = inject(ElementRef);
683
983
  zone = inject(NgZone);
@@ -700,21 +1000,35 @@ class ResponsiveTextDirective {
700
1000
  fitTimeout;
701
1001
  // Cache for performance
702
1002
  lastText = '';
1003
+ lastTemplateString = '';
703
1004
  lastMaxW = 0;
704
1005
  lastMaxH = 0;
705
1006
  lastFontSize = 0;
1007
+ isViewInitialized = false;
706
1008
  constructor() {
707
1009
  // Set up cleanup on component destruction using modern DestroyRef
708
1010
  this.destroyRef.onDestroy(() => {
709
1011
  this.cleanup();
710
1012
  });
1013
+ // Watch for input changes and trigger refit
1014
+ effect(() => {
1015
+ // Access the signals to track them (triggers when they change)
1016
+ this.templateString();
1017
+ this.minFontSize();
1018
+ this.maxFontSize();
1019
+ // Only trigger refit if directive is initialized and view is ready
1020
+ if (this.isViewInitialized && isPlatformBrowser(this.platformId)) {
1021
+ this.zone.runOutsideAngular(() => {
1022
+ this.requestFit();
1023
+ });
1024
+ }
1025
+ });
711
1026
  }
712
1027
  ngAfterViewInit() {
713
1028
  if (!isPlatformBrowser(this.platformId))
714
1029
  return;
715
- // Set initial styles
716
- const span = this.el.nativeElement;
717
- span.style.transition = 'font-size 0.1s ease-out';
1030
+ // Mark as initialized for the effect to start watching
1031
+ this.isViewInitialized = true;
718
1032
  // All observer callbacks run outside Angular's zone
719
1033
  this.zone.runOutsideAngular(() => {
720
1034
  this.fit();
@@ -744,26 +1058,30 @@ class ResponsiveTextDirective {
744
1058
  const parent = span.parentElement;
745
1059
  if (!parent)
746
1060
  return;
747
- const text = span.textContent?.trim() || '';
748
- if (!text) {
1061
+ const actualText = span.textContent?.trim() || '';
1062
+ const templateString = this.templateString()?.trim();
1063
+ const measureText = templateString || actualText;
1064
+ if (!measureText) {
749
1065
  span.style.fontSize = `${this.minFontSize()}px`;
750
1066
  return;
751
1067
  }
752
1068
  const { maxW, maxH } = this.getAvailableSpace(parent);
753
1069
  // Check cache to avoid redundant calculations
754
- if (text === this.lastText &&
1070
+ if (actualText === this.lastText &&
1071
+ (templateString || '') === this.lastTemplateString &&
755
1072
  maxW === this.lastMaxW &&
756
1073
  maxH === this.lastMaxH &&
757
1074
  this.lastFontSize > 0) {
758
1075
  return;
759
1076
  }
760
1077
  // Calculate with conservative buffer for sub-pixel accuracy
761
- const ideal = this.calcFit(text, maxW * 0.98, maxH * 0.98);
1078
+ const ideal = this.calcFit(measureText, maxW * 0.98, maxH * 0.98);
762
1079
  span.style.fontSize = `${ideal}px`;
763
1080
  // DOM verification pass
764
1081
  this.verifyFit(span, maxW, maxH, ideal);
765
1082
  // Update cache
766
- this.lastText = text;
1083
+ this.lastText = actualText;
1084
+ this.lastTemplateString = templateString || '';
767
1085
  this.lastMaxW = maxW;
768
1086
  this.lastMaxH = maxH;
769
1087
  this.lastFontSize = parseFloat(span.style.fontSize);
@@ -901,7 +1219,7 @@ class ResponsiveTextDirective {
901
1219
  this._ctx = undefined;
902
1220
  }
903
1221
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: ResponsiveTextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
904
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.2.1", type: ResponsiveTextDirective, isStandalone: true, selector: "[libResponsiveText]", inputs: { minFontSize: { classPropertyName: "minFontSize", publicName: "minFontSize", isSignal: true, isRequired: false, transformFunction: null }, maxFontSize: { classPropertyName: "maxFontSize", publicName: "maxFontSize", isSignal: true, isRequired: false, transformFunction: null }, lineHeight: { classPropertyName: "lineHeight", publicName: "lineHeight", isSignal: true, isRequired: false, transformFunction: null }, observeMutations: { classPropertyName: "observeMutations", publicName: "observeMutations", isSignal: true, isRequired: false, transformFunction: null }, debounceMs: { classPropertyName: "debounceMs", publicName: "debounceMs", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.display": "\"block\"", "style.width": "\"100%\"", "style.white-space": "\"nowrap\"", "style.overflow": "\"visible\"" } }, ngImport: i0 });
1222
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.2.1", type: ResponsiveTextDirective, isStandalone: true, selector: "[libResponsiveText]", inputs: { minFontSize: { classPropertyName: "minFontSize", publicName: "minFontSize", isSignal: true, isRequired: false, transformFunction: null }, maxFontSize: { classPropertyName: "maxFontSize", publicName: "maxFontSize", isSignal: true, isRequired: false, transformFunction: null }, lineHeight: { classPropertyName: "lineHeight", publicName: "lineHeight", isSignal: true, isRequired: false, transformFunction: null }, observeMutations: { classPropertyName: "observeMutations", publicName: "observeMutations", isSignal: true, isRequired: false, transformFunction: null }, debounceMs: { classPropertyName: "debounceMs", publicName: "debounceMs", isSignal: true, isRequired: false, transformFunction: null }, templateString: { classPropertyName: "templateString", publicName: "templateString", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.display": "\"block\"", "style.width": "\"100%\"", "style.white-space": "\"nowrap\"", "style.overflow": "\"visible\"" } }, ngImport: i0 });
905
1223
  }
906
1224
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: ResponsiveTextDirective, decorators: [{
907
1225
  type: Directive,
@@ -921,8 +1239,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
921
1239
  class LabelWidgetComponent {
922
1240
  static metadata = {
923
1241
  widgetTypeid: '@ngx-dashboard/label-widget',
924
- name: 'Label',
925
- description: 'A generic text label',
1242
+ name: $localize `:@@ngx.dashboard.widgets.label.name:Label`,
1243
+ description: $localize `:@@ngx.dashboard.widgets.label.description:A generic text label`,
926
1244
  svgIcon: svgIcon$2,
927
1245
  };
928
1246
  #sanitizer = inject(DomSanitizer);
@@ -948,7 +1266,12 @@ class LabelWidgetComponent {
948
1266
  }
949
1267
  }
950
1268
  dashboardGetState() {
951
- return { ...this.state() };
1269
+ const state = { ...this.state() };
1270
+ // Remove templateString if undefined to maintain backward compatibility
1271
+ if (state.templateString === undefined) {
1272
+ delete state.templateString;
1273
+ }
1274
+ return state;
952
1275
  }
953
1276
  dashboardEditState() {
954
1277
  const dialogRef = this.#dialog.open(LabelStateDialogComponent, {
@@ -975,12 +1298,13 @@ class LabelWidgetComponent {
975
1298
  // Computed properties for responsive font size limits with fallbacks
976
1299
  minFontSize = computed(() => this.state().minFontSize ?? 8, ...(ngDevMode ? [{ debugName: "minFontSize" }] : []));
977
1300
  maxFontSize = computed(() => this.state().maxFontSize ?? 64, ...(ngDevMode ? [{ debugName: "maxFontSize" }] : []));
1301
+ templateString = computed(() => this.state().templateString, ...(ngDevMode ? [{ debugName: "templateString" }] : []));
978
1302
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: LabelWidgetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
979
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: LabelWidgetComponent, isStandalone: true, selector: "ngx-dashboard-label-widget", ngImport: i0, template: "@if (hasContent) {\r\n<div\r\n class=\"label-widget\"\r\n [style.fontSize.rem]=\"state().responsive ? null : state().fontSize! / 16\"\r\n [style.--widget-opacity]=\"state().opacity\"\r\n [class.text-left]=\"state().alignment === 'left'\"\r\n [class.text-right]=\"state().alignment === 'right'\"\r\n [class.font-bold]=\"state().fontWeight === 'bold'\"\r\n [class.has-background]=\"state().hasBackground\"\r\n>\r\n @if (state().responsive) {\r\n <div class=\"label-text\" libResponsiveText [minFontSize]=\"minFontSize()\" [maxFontSize]=\"maxFontSize()\">{{ label }}</div>\r\n } @else {\r\n <div class=\"label-text\">{{ label }}</div>\r\n }\r\n</div>\r\n} @else {\r\n<div class=\"svg-wrapper\" [class.has-background]=\"state().hasBackground\">\r\n <div class=\"svg-placeholder\" [innerHTML]=\"safeSvgIcon\"></div>\r\n</div>\r\n}\r\n", styles: [":host{display:block;container-type:size;width:100%;height:100%;overflow:hidden}.svg-wrapper,.label-widget{display:flex;align-items:center;justify-content:center;height:100%;width:100%;box-sizing:border-box;transition:background-color var(--mat-sys-motion-duration-medium2) var(--mat-sys-motion-easing-standard)}.has-background.svg-wrapper,.has-background.label-widget{background-color:var(--mat-sys-surface-container-high);border-radius:4px}.label-widget{overflow:hidden;container-type:size;padding:var(--mat-sys-spacing-4);color:var(--mat-sys-on-surface-variant, #6c757d);opacity:var(--widget-opacity, 1)}.label-widget.text-left{justify-content:flex-start}.label-widget.text-right{justify-content:flex-end}.label-widget.has-background{color:var(--mat-sys-on-surface, #1f1f1f)}.label-widget:hover{opacity:.3;color:var(--mat-sys-primary, #6750a4)}.label-text{width:100%;text-align:center;overflow-wrap:break-word;transition:color .2s ease}.text-left .label-text{text-align:left}.text-right .label-text{text-align:right}.font-bold .label-text{font-weight:700}.label-text[responsiveText]{overflow-wrap:normal}.svg-wrapper{overflow:hidden}.svg-placeholder{width:min(80cqw,80cqh);aspect-ratio:1/1;opacity:.3;transition:transform .3s ease-in-out,opacity .3s ease,color .2s ease;transform-origin:center center;color:var(--mat-sys-on-surface-variant, #6c757d)}.has-background .svg-placeholder{color:var(--mat-sys-on-surface, #1f1f1f)}.svg-placeholder ::ng-deep svg{width:100%;height:100%;display:block}.svg-wrapper:hover .svg-placeholder{color:var(--mat-sys-primary, #6750a4)}\n"], dependencies: [{ kind: "directive", type: ResponsiveTextDirective, selector: "[libResponsiveText]", inputs: ["minFontSize", "maxFontSize", "lineHeight", "observeMutations", "debounceMs"] }] });
1303
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: LabelWidgetComponent, isStandalone: true, selector: "ngx-dashboard-label-widget", ngImport: i0, template: "@if (hasContent) {\r\n<div\r\n class=\"label-widget\"\r\n [style.fontSize.rem]=\"state().responsive ? null : state().fontSize! / 16\"\r\n [style.--widget-opacity]=\"state().opacity\"\r\n [class.text-left]=\"state().alignment === 'left'\"\r\n [class.text-right]=\"state().alignment === 'right'\"\r\n [class.font-bold]=\"state().fontWeight === 'bold'\"\r\n [class.has-background]=\"state().hasBackground\"\r\n>\r\n @if (state().responsive) {\r\n <div class=\"label-text\" libResponsiveText [minFontSize]=\"minFontSize()\" [maxFontSize]=\"maxFontSize()\" [templateString]=\"templateString()\">{{ label }}</div>\r\n } @else {\r\n <div class=\"label-text\">{{ label }}</div>\r\n }\r\n</div>\r\n} @else {\r\n<div class=\"svg-wrapper\" [class.has-background]=\"state().hasBackground\">\r\n <div class=\"svg-placeholder\" [innerHTML]=\"safeSvgIcon\"></div>\r\n</div>\r\n}\r\n", styles: [":host{display:block;container-type:size;width:100%;height:100%;overflow:hidden}.svg-wrapper,.label-widget{display:flex;align-items:center;justify-content:center;height:100%;width:100%;box-sizing:border-box;transition:background-color var(--mat-sys-motion-duration-medium2) var(--mat-sys-motion-easing-standard)}.has-background.svg-wrapper,.has-background.label-widget{background-color:var(--mat-sys-surface-container-high);border-radius:4px}.label-widget{overflow:hidden;container-type:size;padding:var(--mat-sys-spacing-4);color:var(--mat-sys-on-surface-variant, #6c757d);opacity:var(--widget-opacity, 1)}.label-widget.text-left{justify-content:flex-start}.label-widget.text-right{justify-content:flex-end}.label-widget.has-background{color:var(--mat-sys-on-surface, #1f1f1f)}.label-widget:hover{opacity:.3;color:var(--mat-sys-primary, #6750a4)}.label-text{width:100%;text-align:center;overflow-wrap:break-word;transition:color .2s ease}.text-left .label-text{text-align:left}.text-right .label-text{text-align:right}.font-bold .label-text{font-weight:700}.label-text[responsiveText]{overflow-wrap:normal}.svg-wrapper{overflow:hidden}.svg-placeholder{width:min(80cqw,80cqh);aspect-ratio:1/1;opacity:.3;transition:transform .3s ease-in-out,opacity .3s ease,color .2s ease;transform-origin:center center;color:var(--mat-sys-on-surface-variant, #6c757d)}.has-background .svg-placeholder{color:var(--mat-sys-on-surface, #1f1f1f)}.svg-placeholder ::ng-deep svg{width:100%;height:100%;display:block}.svg-wrapper:hover .svg-placeholder{color:var(--mat-sys-primary, #6750a4)}\n"], dependencies: [{ kind: "directive", type: ResponsiveTextDirective, selector: "[libResponsiveText]", inputs: ["minFontSize", "maxFontSize", "lineHeight", "observeMutations", "debounceMs", "templateString"] }] });
980
1304
  }
981
1305
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: LabelWidgetComponent, decorators: [{
982
1306
  type: Component,
983
- args: [{ selector: 'ngx-dashboard-label-widget', imports: [ResponsiveTextDirective], template: "@if (hasContent) {\r\n<div\r\n class=\"label-widget\"\r\n [style.fontSize.rem]=\"state().responsive ? null : state().fontSize! / 16\"\r\n [style.--widget-opacity]=\"state().opacity\"\r\n [class.text-left]=\"state().alignment === 'left'\"\r\n [class.text-right]=\"state().alignment === 'right'\"\r\n [class.font-bold]=\"state().fontWeight === 'bold'\"\r\n [class.has-background]=\"state().hasBackground\"\r\n>\r\n @if (state().responsive) {\r\n <div class=\"label-text\" libResponsiveText [minFontSize]=\"minFontSize()\" [maxFontSize]=\"maxFontSize()\">{{ label }}</div>\r\n } @else {\r\n <div class=\"label-text\">{{ label }}</div>\r\n }\r\n</div>\r\n} @else {\r\n<div class=\"svg-wrapper\" [class.has-background]=\"state().hasBackground\">\r\n <div class=\"svg-placeholder\" [innerHTML]=\"safeSvgIcon\"></div>\r\n</div>\r\n}\r\n", styles: [":host{display:block;container-type:size;width:100%;height:100%;overflow:hidden}.svg-wrapper,.label-widget{display:flex;align-items:center;justify-content:center;height:100%;width:100%;box-sizing:border-box;transition:background-color var(--mat-sys-motion-duration-medium2) var(--mat-sys-motion-easing-standard)}.has-background.svg-wrapper,.has-background.label-widget{background-color:var(--mat-sys-surface-container-high);border-radius:4px}.label-widget{overflow:hidden;container-type:size;padding:var(--mat-sys-spacing-4);color:var(--mat-sys-on-surface-variant, #6c757d);opacity:var(--widget-opacity, 1)}.label-widget.text-left{justify-content:flex-start}.label-widget.text-right{justify-content:flex-end}.label-widget.has-background{color:var(--mat-sys-on-surface, #1f1f1f)}.label-widget:hover{opacity:.3;color:var(--mat-sys-primary, #6750a4)}.label-text{width:100%;text-align:center;overflow-wrap:break-word;transition:color .2s ease}.text-left .label-text{text-align:left}.text-right .label-text{text-align:right}.font-bold .label-text{font-weight:700}.label-text[responsiveText]{overflow-wrap:normal}.svg-wrapper{overflow:hidden}.svg-placeholder{width:min(80cqw,80cqh);aspect-ratio:1/1;opacity:.3;transition:transform .3s ease-in-out,opacity .3s ease,color .2s ease;transform-origin:center center;color:var(--mat-sys-on-surface-variant, #6c757d)}.has-background .svg-placeholder{color:var(--mat-sys-on-surface, #1f1f1f)}.svg-placeholder ::ng-deep svg{width:100%;height:100%;display:block}.svg-wrapper:hover .svg-placeholder{color:var(--mat-sys-primary, #6750a4)}\n"] }]
1307
+ args: [{ selector: 'ngx-dashboard-label-widget', imports: [ResponsiveTextDirective], template: "@if (hasContent) {\r\n<div\r\n class=\"label-widget\"\r\n [style.fontSize.rem]=\"state().responsive ? null : state().fontSize! / 16\"\r\n [style.--widget-opacity]=\"state().opacity\"\r\n [class.text-left]=\"state().alignment === 'left'\"\r\n [class.text-right]=\"state().alignment === 'right'\"\r\n [class.font-bold]=\"state().fontWeight === 'bold'\"\r\n [class.has-background]=\"state().hasBackground\"\r\n>\r\n @if (state().responsive) {\r\n <div class=\"label-text\" libResponsiveText [minFontSize]=\"minFontSize()\" [maxFontSize]=\"maxFontSize()\" [templateString]=\"templateString()\">{{ label }}</div>\r\n } @else {\r\n <div class=\"label-text\">{{ label }}</div>\r\n }\r\n</div>\r\n} @else {\r\n<div class=\"svg-wrapper\" [class.has-background]=\"state().hasBackground\">\r\n <div class=\"svg-placeholder\" [innerHTML]=\"safeSvgIcon\"></div>\r\n</div>\r\n}\r\n", styles: [":host{display:block;container-type:size;width:100%;height:100%;overflow:hidden}.svg-wrapper,.label-widget{display:flex;align-items:center;justify-content:center;height:100%;width:100%;box-sizing:border-box;transition:background-color var(--mat-sys-motion-duration-medium2) var(--mat-sys-motion-easing-standard)}.has-background.svg-wrapper,.has-background.label-widget{background-color:var(--mat-sys-surface-container-high);border-radius:4px}.label-widget{overflow:hidden;container-type:size;padding:var(--mat-sys-spacing-4);color:var(--mat-sys-on-surface-variant, #6c757d);opacity:var(--widget-opacity, 1)}.label-widget.text-left{justify-content:flex-start}.label-widget.text-right{justify-content:flex-end}.label-widget.has-background{color:var(--mat-sys-on-surface, #1f1f1f)}.label-widget:hover{opacity:.3;color:var(--mat-sys-primary, #6750a4)}.label-text{width:100%;text-align:center;overflow-wrap:break-word;transition:color .2s ease}.text-left .label-text{text-align:left}.text-right .label-text{text-align:right}.font-bold .label-text{font-weight:700}.label-text[responsiveText]{overflow-wrap:normal}.svg-wrapper{overflow:hidden}.svg-placeholder{width:min(80cqw,80cqh);aspect-ratio:1/1;opacity:.3;transition:transform .3s ease-in-out,opacity .3s ease,color .2s ease;transform-origin:center center;color:var(--mat-sys-on-surface-variant, #6c757d)}.has-background .svg-placeholder{color:var(--mat-sys-on-surface, #1f1f1f)}.svg-placeholder ::ng-deep svg{width:100%;height:100%;display:block}.svg-wrapper:hover .svg-placeholder{color:var(--mat-sys-primary, #6750a4)}\n"] }]
984
1308
  }] });
985
1309
 
986
1310
  const svgIcon$1 = `
@@ -1059,67 +1383,120 @@ class ClockStateDialogComponent {
1059
1383
  }
1060
1384
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: ClockStateDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1061
1385
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.1", type: ClockStateDialogComponent, isStandalone: true, selector: "lib-clock-state-dialog", ngImport: i0, template: `
1062
- <h2 mat-dialog-title>Clock Settings</h2>
1386
+ <h2 mat-dialog-title i18n="@@ngx.dashboard.widgets.clock.dialog.title">
1387
+ Clock Settings
1388
+ </h2>
1063
1389
  <mat-dialog-content>
1064
1390
  <div class="mode-selection">
1065
- <label class="section-label" for="mode-selection-group">Display Mode</label>
1391
+ <label
1392
+ class="section-label"
1393
+ for="mode-selection-group"
1394
+ i18n="@@ngx.dashboard.widgets.clock.dialog.displayMode"
1395
+ >Display Mode</label
1396
+ >
1066
1397
  <mat-radio-group
1067
1398
  id="mode-selection-group"
1068
1399
  [value]="mode()"
1069
1400
  (change)="mode.set($any($event.value))"
1070
1401
  >
1071
- <mat-radio-button value="digital">Digital</mat-radio-button>
1072
- <mat-radio-button value="analog">Analog</mat-radio-button>
1402
+ <mat-radio-button
1403
+ value="digital"
1404
+ i18n="@@ngx.dashboard.widgets.clock.dialog.mode.digital"
1405
+ >Digital</mat-radio-button
1406
+ >
1407
+ <mat-radio-button
1408
+ value="analog"
1409
+ i18n="@@ngx.dashboard.widgets.clock.dialog.mode.analog"
1410
+ >Analog</mat-radio-button
1411
+ >
1073
1412
  </mat-radio-group>
1074
1413
  </div>
1075
1414
 
1076
1415
  <!-- Time Format (only for digital mode) -->
1077
1416
  @if (mode() === 'digital') {
1078
1417
  <div class="format-selection">
1079
- <label class="section-label" for="time-format-group">Time Format</label>
1418
+ <label
1419
+ class="section-label"
1420
+ for="time-format-group"
1421
+ i18n="@@ngx.dashboard.widgets.clock.dialog.timeFormat"
1422
+ >Time Format</label
1423
+ >
1080
1424
  <mat-radio-group
1081
1425
  id="time-format-group"
1082
1426
  [value]="timeFormat()"
1083
1427
  (change)="timeFormat.set($any($event.value))"
1084
1428
  >
1085
- <mat-radio-button value="24h">24 Hour (14:30:45)</mat-radio-button>
1086
- <mat-radio-button value="12h">12 Hour (2:30:45 PM)</mat-radio-button>
1429
+ <mat-radio-button
1430
+ value="24h"
1431
+ i18n="@@ngx.dashboard.widgets.clock.dialog.format.24h"
1432
+ >24 Hour (14:30:45)</mat-radio-button
1433
+ >
1434
+ <mat-radio-button
1435
+ value="12h"
1436
+ i18n="@@ngx.dashboard.widgets.clock.dialog.format.12h"
1437
+ >12 Hour (2:30:45 PM)</mat-radio-button
1438
+ >
1087
1439
  </mat-radio-group>
1088
1440
  </div>
1089
1441
  }
1090
1442
 
1091
1443
  <!-- Show Seconds Toggle (for both digital and analog modes) -->
1092
1444
  <div class="toggle-section">
1093
- <mat-slide-toggle
1445
+ <mat-slide-toggle
1094
1446
  [checked]="showSeconds()"
1095
- (change)="showSeconds.set($event.checked)">
1447
+ (change)="showSeconds.set($event.checked)"
1448
+ i18n="@@ngx.dashboard.widgets.clock.dialog.showSeconds"
1449
+ >
1096
1450
  Show Seconds
1097
1451
  </mat-slide-toggle>
1098
1452
  <span class="toggle-description">
1099
1453
  @if (mode() === 'digital') {
1100
- Display seconds in the time
1454
+ <span
1455
+ i18n="
1456
+ @@ngx.dashboard.widgets.clock.dialog.showSecondsDescription.digital"
1457
+ >Display seconds in the time</span
1458
+ >
1101
1459
  } @else {
1102
- Show the second hand on the clock
1460
+ <span
1461
+ i18n="
1462
+ @@ngx.dashboard.widgets.clock.dialog.showSecondsDescription.analog"
1463
+ >Show the second hand on the clock</span
1464
+ >
1103
1465
  }
1104
1466
  </span>
1105
1467
  </div>
1106
1468
 
1107
1469
  <!-- Background Toggle -->
1108
1470
  <div class="toggle-section">
1109
- <mat-slide-toggle
1471
+ <mat-slide-toggle
1110
1472
  [checked]="hasBackground()"
1111
- (change)="hasBackground.set($event.checked)">
1473
+ (change)="hasBackground.set($event.checked)"
1474
+ i18n="@@ngx.dashboard.widgets.clock.dialog.background"
1475
+ >
1112
1476
  Background
1113
1477
  </mat-slide-toggle>
1114
- <span class="toggle-description"
1478
+ <span
1479
+ class="toggle-description"
1480
+ i18n="@@ngx.dashboard.widgets.clock.dialog.backgroundDescription"
1115
1481
  >Adds a background behind the clock</span
1116
1482
  >
1117
1483
  </div>
1118
1484
  </mat-dialog-content>
1119
1485
 
1120
1486
  <mat-dialog-actions align="end">
1121
- <button mat-button (click)="onCancel()">Cancel</button>
1122
- <button mat-flat-button (click)="save()" [disabled]="!hasChanged()">
1487
+ <button
1488
+ mat-button
1489
+ (click)="onCancel()"
1490
+ i18n="@@ngx.dashboard.common.cancel"
1491
+ >
1492
+ Cancel
1493
+ </button>
1494
+ <button
1495
+ mat-flat-button
1496
+ (click)="save()"
1497
+ [disabled]="!hasChanged()"
1498
+ i18n="@@ngx.dashboard.common.save"
1499
+ >
1123
1500
  Save
1124
1501
  </button>
1125
1502
  </mat-dialog-actions>
@@ -1135,67 +1512,120 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
1135
1512
  MatRadioModule,
1136
1513
  MatSlideToggleModule,
1137
1514
  ], template: `
1138
- <h2 mat-dialog-title>Clock Settings</h2>
1515
+ <h2 mat-dialog-title i18n="@@ngx.dashboard.widgets.clock.dialog.title">
1516
+ Clock Settings
1517
+ </h2>
1139
1518
  <mat-dialog-content>
1140
1519
  <div class="mode-selection">
1141
- <label class="section-label" for="mode-selection-group">Display Mode</label>
1520
+ <label
1521
+ class="section-label"
1522
+ for="mode-selection-group"
1523
+ i18n="@@ngx.dashboard.widgets.clock.dialog.displayMode"
1524
+ >Display Mode</label
1525
+ >
1142
1526
  <mat-radio-group
1143
1527
  id="mode-selection-group"
1144
1528
  [value]="mode()"
1145
1529
  (change)="mode.set($any($event.value))"
1146
1530
  >
1147
- <mat-radio-button value="digital">Digital</mat-radio-button>
1148
- <mat-radio-button value="analog">Analog</mat-radio-button>
1531
+ <mat-radio-button
1532
+ value="digital"
1533
+ i18n="@@ngx.dashboard.widgets.clock.dialog.mode.digital"
1534
+ >Digital</mat-radio-button
1535
+ >
1536
+ <mat-radio-button
1537
+ value="analog"
1538
+ i18n="@@ngx.dashboard.widgets.clock.dialog.mode.analog"
1539
+ >Analog</mat-radio-button
1540
+ >
1149
1541
  </mat-radio-group>
1150
1542
  </div>
1151
1543
 
1152
1544
  <!-- Time Format (only for digital mode) -->
1153
1545
  @if (mode() === 'digital') {
1154
1546
  <div class="format-selection">
1155
- <label class="section-label" for="time-format-group">Time Format</label>
1547
+ <label
1548
+ class="section-label"
1549
+ for="time-format-group"
1550
+ i18n="@@ngx.dashboard.widgets.clock.dialog.timeFormat"
1551
+ >Time Format</label
1552
+ >
1156
1553
  <mat-radio-group
1157
1554
  id="time-format-group"
1158
1555
  [value]="timeFormat()"
1159
1556
  (change)="timeFormat.set($any($event.value))"
1160
1557
  >
1161
- <mat-radio-button value="24h">24 Hour (14:30:45)</mat-radio-button>
1162
- <mat-radio-button value="12h">12 Hour (2:30:45 PM)</mat-radio-button>
1558
+ <mat-radio-button
1559
+ value="24h"
1560
+ i18n="@@ngx.dashboard.widgets.clock.dialog.format.24h"
1561
+ >24 Hour (14:30:45)</mat-radio-button
1562
+ >
1563
+ <mat-radio-button
1564
+ value="12h"
1565
+ i18n="@@ngx.dashboard.widgets.clock.dialog.format.12h"
1566
+ >12 Hour (2:30:45 PM)</mat-radio-button
1567
+ >
1163
1568
  </mat-radio-group>
1164
1569
  </div>
1165
1570
  }
1166
1571
 
1167
1572
  <!-- Show Seconds Toggle (for both digital and analog modes) -->
1168
1573
  <div class="toggle-section">
1169
- <mat-slide-toggle
1574
+ <mat-slide-toggle
1170
1575
  [checked]="showSeconds()"
1171
- (change)="showSeconds.set($event.checked)">
1576
+ (change)="showSeconds.set($event.checked)"
1577
+ i18n="@@ngx.dashboard.widgets.clock.dialog.showSeconds"
1578
+ >
1172
1579
  Show Seconds
1173
1580
  </mat-slide-toggle>
1174
1581
  <span class="toggle-description">
1175
1582
  @if (mode() === 'digital') {
1176
- Display seconds in the time
1583
+ <span
1584
+ i18n="
1585
+ @@ngx.dashboard.widgets.clock.dialog.showSecondsDescription.digital"
1586
+ >Display seconds in the time</span
1587
+ >
1177
1588
  } @else {
1178
- Show the second hand on the clock
1589
+ <span
1590
+ i18n="
1591
+ @@ngx.dashboard.widgets.clock.dialog.showSecondsDescription.analog"
1592
+ >Show the second hand on the clock</span
1593
+ >
1179
1594
  }
1180
1595
  </span>
1181
1596
  </div>
1182
1597
 
1183
1598
  <!-- Background Toggle -->
1184
1599
  <div class="toggle-section">
1185
- <mat-slide-toggle
1600
+ <mat-slide-toggle
1186
1601
  [checked]="hasBackground()"
1187
- (change)="hasBackground.set($event.checked)">
1602
+ (change)="hasBackground.set($event.checked)"
1603
+ i18n="@@ngx.dashboard.widgets.clock.dialog.background"
1604
+ >
1188
1605
  Background
1189
1606
  </mat-slide-toggle>
1190
- <span class="toggle-description"
1607
+ <span
1608
+ class="toggle-description"
1609
+ i18n="@@ngx.dashboard.widgets.clock.dialog.backgroundDescription"
1191
1610
  >Adds a background behind the clock</span
1192
1611
  >
1193
1612
  </div>
1194
1613
  </mat-dialog-content>
1195
1614
 
1196
1615
  <mat-dialog-actions align="end">
1197
- <button mat-button (click)="onCancel()">Cancel</button>
1198
- <button mat-flat-button (click)="save()" [disabled]="!hasChanged()">
1616
+ <button
1617
+ mat-button
1618
+ (click)="onCancel()"
1619
+ i18n="@@ngx.dashboard.common.cancel"
1620
+ >
1621
+ Cancel
1622
+ </button>
1623
+ <button
1624
+ mat-flat-button
1625
+ (click)="save()"
1626
+ [disabled]="!hasChanged()"
1627
+ i18n="@@ngx.dashboard.common.save"
1628
+ >
1199
1629
  Save
1200
1630
  </button>
1201
1631
  </mat-dialog-actions>
@@ -1369,8 +1799,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
1369
1799
  class ClockWidgetComponent {
1370
1800
  static metadata = {
1371
1801
  widgetTypeid: '@ngx-dashboard/clock-widget',
1372
- name: 'Clock',
1373
- description: 'Display time in analog or digital format',
1802
+ name: $localize `:@@ngx.dashboard.widgets.clock.name:Clock`,
1803
+ description: $localize `:@@ngx.dashboard.widgets.clock.description:Display time in analog or digital format`,
1374
1804
  svgIcon: svgIcon$1,
1375
1805
  };
1376
1806
  #sanitizer = inject(DomSanitizer);
@@ -2057,10 +2487,17 @@ class RadialGaugeStateDialogComponent {
2057
2487
  }
2058
2488
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.1", ngImport: i0, type: RadialGaugeStateDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2059
2489
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.1", type: RadialGaugeStateDialogComponent, isStandalone: true, selector: "lib-radial-gauge-state-dialog", ngImport: i0, template: `
2060
- <h2 mat-dialog-title>Radial Gauge Settings</h2>
2490
+ <h2
2491
+ mat-dialog-title
2492
+ i18n="@@ngx.dashboard.widgets.radialGauge.dialog.title"
2493
+ >
2494
+ Radial Gauge Settings
2495
+ </h2>
2061
2496
  <mat-dialog-content>
2062
2497
  <mat-form-field>
2063
- <mat-label>Value (0-100)</mat-label>
2498
+ <mat-label i18n="@@ngx.dashboard.widgets.radialGauge.dialog.value"
2499
+ >Value (0-100)</mat-label
2500
+ >
2064
2501
  <input
2065
2502
  matInput
2066
2503
  type="number"
@@ -2071,38 +2508,89 @@ class RadialGaugeStateDialogComponent {
2071
2508
  </mat-form-field>
2072
2509
 
2073
2510
  <div class="section">
2074
- <h4>Color Profile</h4>
2511
+ <h4 i18n="@@ngx.dashboard.widgets.radialGauge.dialog.colorProfile">
2512
+ Color Profile
2513
+ </h4>
2075
2514
  <mat-radio-group [(ngModel)]="localState.colorProfile">
2076
- <mat-radio-button value="dynamic">Dynamic (Theme Colors)</mat-radio-button>
2077
- <mat-radio-button value="static">Static (Performance Colors)</mat-radio-button>
2515
+ <mat-radio-button
2516
+ value="dynamic"
2517
+ i18n="
2518
+ @@ngx.dashboard.widgets.radialGauge.dialog.colorProfile.dynamic"
2519
+ >Dynamic (Theme Colors)</mat-radio-button
2520
+ >
2521
+ <mat-radio-button
2522
+ value="static"
2523
+ i18n="
2524
+ @@ngx.dashboard.widgets.radialGauge.dialog.colorProfile.static"
2525
+ >Static (Performance Colors)</mat-radio-button
2526
+ >
2078
2527
  </mat-radio-group>
2079
2528
  </div>
2080
2529
 
2081
2530
  <div class="toggle-section">
2082
- <mat-slide-toggle [(ngModel)]="localState.active">
2531
+ <mat-slide-toggle
2532
+ [(ngModel)]="localState.active"
2533
+ i18n="@@ngx.dashboard.widgets.radialGauge.dialog.activeDisplay"
2534
+ >
2083
2535
  Active Display
2084
2536
  </mat-slide-toggle>
2085
- <p class="toggle-description">Display live gauge instead of passive icon</p>
2537
+ <p
2538
+ class="toggle-description"
2539
+ i18n="
2540
+ @@ngx.dashboard.widgets.radialGauge.dialog.activeDisplayDescription"
2541
+ >
2542
+ Display live gauge instead of passive icon
2543
+ </p>
2086
2544
  </div>
2087
2545
 
2088
2546
  <div class="toggle-section">
2089
- <mat-slide-toggle [(ngModel)]="localState.hasBackground">
2547
+ <mat-slide-toggle
2548
+ [(ngModel)]="localState.hasBackground"
2549
+ i18n="@@ngx.dashboard.widgets.radialGauge.dialog.background"
2550
+ >
2090
2551
  Background
2091
2552
  </mat-slide-toggle>
2092
- <p class="toggle-description">Add a background color to the widget</p>
2553
+ <p
2554
+ class="toggle-description"
2555
+ i18n="
2556
+ @@ngx.dashboard.widgets.radialGauge.dialog.backgroundDescription"
2557
+ >
2558
+ Add a background color to the widget
2559
+ </p>
2093
2560
  </div>
2094
2561
 
2095
2562
  <div class="toggle-section">
2096
- <mat-slide-toggle [(ngModel)]="localState.showValueLabel">
2563
+ <mat-slide-toggle
2564
+ [(ngModel)]="localState.showValueLabel"
2565
+ i18n="@@ngx.dashboard.widgets.radialGauge.dialog.showValueLabel"
2566
+ >
2097
2567
  Show Value Label
2098
2568
  </mat-slide-toggle>
2099
- <p class="toggle-description">Display numeric value in gauge center</p>
2569
+ <p
2570
+ class="toggle-description"
2571
+ i18n="
2572
+ @@ngx.dashboard.widgets.radialGauge.dialog.showValueLabelDescription"
2573
+ >
2574
+ Display numeric value in gauge center
2575
+ </p>
2100
2576
  </div>
2101
2577
  </mat-dialog-content>
2102
2578
 
2103
2579
  <mat-dialog-actions align="end">
2104
- <button mat-button (click)="onCancel()">Cancel</button>
2105
- <button mat-flat-button (click)="onSave()">Save</button>
2580
+ <button
2581
+ mat-button
2582
+ (click)="onCancel()"
2583
+ i18n="@@ngx.dashboard.common.cancel"
2584
+ >
2585
+ Cancel
2586
+ </button>
2587
+ <button
2588
+ mat-flat-button
2589
+ (click)="onSave()"
2590
+ i18n="@@ngx.dashboard.common.save"
2591
+ >
2592
+ Save
2593
+ </button>
2106
2594
  </mat-dialog-actions>
2107
2595
  `, isInline: true, styles: ["mat-dialog-content{display:block;overflow-y:auto;overflow-x:hidden}mat-form-field{width:100%;display:block;margin-bottom:1rem}.section{margin-bottom:1.5rem}.section h4{margin:0 0 .5rem;font-size:.875rem;font-weight:500;color:var(--mat-sys-on-surface, #1f1f1f)}mat-radio-group{display:flex;flex-direction:column;gap:.5rem}.toggle-section{display:flex;align-items:center;gap:.75rem;margin-bottom:.5rem}.toggle-description{margin:0;flex:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i4.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i4.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i5$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i7.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i3$1.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i3$1.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
2108
2596
  }
@@ -2118,10 +2606,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
2118
2606
  MatRadioModule,
2119
2607
  FormsModule,
2120
2608
  ], template: `
2121
- <h2 mat-dialog-title>Radial Gauge Settings</h2>
2609
+ <h2
2610
+ mat-dialog-title
2611
+ i18n="@@ngx.dashboard.widgets.radialGauge.dialog.title"
2612
+ >
2613
+ Radial Gauge Settings
2614
+ </h2>
2122
2615
  <mat-dialog-content>
2123
2616
  <mat-form-field>
2124
- <mat-label>Value (0-100)</mat-label>
2617
+ <mat-label i18n="@@ngx.dashboard.widgets.radialGauge.dialog.value"
2618
+ >Value (0-100)</mat-label
2619
+ >
2125
2620
  <input
2126
2621
  matInput
2127
2622
  type="number"
@@ -2132,38 +2627,89 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
2132
2627
  </mat-form-field>
2133
2628
 
2134
2629
  <div class="section">
2135
- <h4>Color Profile</h4>
2630
+ <h4 i18n="@@ngx.dashboard.widgets.radialGauge.dialog.colorProfile">
2631
+ Color Profile
2632
+ </h4>
2136
2633
  <mat-radio-group [(ngModel)]="localState.colorProfile">
2137
- <mat-radio-button value="dynamic">Dynamic (Theme Colors)</mat-radio-button>
2138
- <mat-radio-button value="static">Static (Performance Colors)</mat-radio-button>
2634
+ <mat-radio-button
2635
+ value="dynamic"
2636
+ i18n="
2637
+ @@ngx.dashboard.widgets.radialGauge.dialog.colorProfile.dynamic"
2638
+ >Dynamic (Theme Colors)</mat-radio-button
2639
+ >
2640
+ <mat-radio-button
2641
+ value="static"
2642
+ i18n="
2643
+ @@ngx.dashboard.widgets.radialGauge.dialog.colorProfile.static"
2644
+ >Static (Performance Colors)</mat-radio-button
2645
+ >
2139
2646
  </mat-radio-group>
2140
2647
  </div>
2141
2648
 
2142
2649
  <div class="toggle-section">
2143
- <mat-slide-toggle [(ngModel)]="localState.active">
2650
+ <mat-slide-toggle
2651
+ [(ngModel)]="localState.active"
2652
+ i18n="@@ngx.dashboard.widgets.radialGauge.dialog.activeDisplay"
2653
+ >
2144
2654
  Active Display
2145
2655
  </mat-slide-toggle>
2146
- <p class="toggle-description">Display live gauge instead of passive icon</p>
2656
+ <p
2657
+ class="toggle-description"
2658
+ i18n="
2659
+ @@ngx.dashboard.widgets.radialGauge.dialog.activeDisplayDescription"
2660
+ >
2661
+ Display live gauge instead of passive icon
2662
+ </p>
2147
2663
  </div>
2148
2664
 
2149
2665
  <div class="toggle-section">
2150
- <mat-slide-toggle [(ngModel)]="localState.hasBackground">
2666
+ <mat-slide-toggle
2667
+ [(ngModel)]="localState.hasBackground"
2668
+ i18n="@@ngx.dashboard.widgets.radialGauge.dialog.background"
2669
+ >
2151
2670
  Background
2152
2671
  </mat-slide-toggle>
2153
- <p class="toggle-description">Add a background color to the widget</p>
2672
+ <p
2673
+ class="toggle-description"
2674
+ i18n="
2675
+ @@ngx.dashboard.widgets.radialGauge.dialog.backgroundDescription"
2676
+ >
2677
+ Add a background color to the widget
2678
+ </p>
2154
2679
  </div>
2155
2680
 
2156
2681
  <div class="toggle-section">
2157
- <mat-slide-toggle [(ngModel)]="localState.showValueLabel">
2682
+ <mat-slide-toggle
2683
+ [(ngModel)]="localState.showValueLabel"
2684
+ i18n="@@ngx.dashboard.widgets.radialGauge.dialog.showValueLabel"
2685
+ >
2158
2686
  Show Value Label
2159
2687
  </mat-slide-toggle>
2160
- <p class="toggle-description">Display numeric value in gauge center</p>
2688
+ <p
2689
+ class="toggle-description"
2690
+ i18n="
2691
+ @@ngx.dashboard.widgets.radialGauge.dialog.showValueLabelDescription"
2692
+ >
2693
+ Display numeric value in gauge center
2694
+ </p>
2161
2695
  </div>
2162
2696
  </mat-dialog-content>
2163
2697
 
2164
2698
  <mat-dialog-actions align="end">
2165
- <button mat-button (click)="onCancel()">Cancel</button>
2166
- <button mat-flat-button (click)="onSave()">Save</button>
2699
+ <button
2700
+ mat-button
2701
+ (click)="onCancel()"
2702
+ i18n="@@ngx.dashboard.common.cancel"
2703
+ >
2704
+ Cancel
2705
+ </button>
2706
+ <button
2707
+ mat-flat-button
2708
+ (click)="onSave()"
2709
+ i18n="@@ngx.dashboard.common.save"
2710
+ >
2711
+ Save
2712
+ </button>
2167
2713
  </mat-dialog-actions>
2168
2714
  `, styles: ["mat-dialog-content{display:block;overflow-y:auto;overflow-x:hidden}mat-form-field{width:100%;display:block;margin-bottom:1rem}.section{margin-bottom:1.5rem}.section h4{margin:0 0 .5rem;font-size:.875rem;font-weight:500;color:var(--mat-sys-on-surface, #1f1f1f)}mat-radio-group{display:flex;flex-direction:column;gap:.5rem}.toggle-section{display:flex;align-items:center;gap:.75rem;margin-bottom:.5rem}.toggle-description{margin:0;flex:1}\n"] }]
2169
2715
  }] });
@@ -2172,8 +2718,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
2172
2718
  class RadialGaugeWidgetComponent {
2173
2719
  static metadata = {
2174
2720
  widgetTypeid: '@ngx-dashboard/radial-gauge-widget',
2175
- name: 'Radial Gauge',
2176
- description: 'A semi-circular gauge indicator',
2721
+ name: $localize `:@@ngx.dashboard.widgets.radialGauge.name:Radial Gauge`,
2722
+ description: $localize `:@@ngx.dashboard.widgets.radialGauge.description:A semi-circular gauge indicator`,
2177
2723
  svgIcon,
2178
2724
  };
2179
2725
  #dialog = inject(MatDialog);
@@ -2242,11 +2788,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
2242
2788
  /*
2243
2789
  * Public API Surface of ngx-dashboard-widgets
2244
2790
  */
2245
- // Widget Components
2791
+ // Library version
2246
2792
 
2247
2793
  /**
2248
2794
  * Generated bundle index. Do not edit.
2249
2795
  */
2250
2796
 
2251
- export { ArrowWidgetComponent, ClockWidgetComponent, LabelWidgetComponent, RadialGaugeComponent, RadialGaugeWidgetComponent, ResponsiveTextDirective };
2797
+ export { ArrowWidgetComponent, ClockWidgetComponent, LabelWidgetComponent, NGX_DASHBOARD_WIDGETS_VERSION, RadialGaugeComponent, RadialGaugeWidgetComponent, ResponsiveTextDirective };
2252
2798
  //# sourceMappingURL=dragonworks-ngx-dashboard-widgets.mjs.map