@dragonworks/ngx-dashboard-widgets 20.0.5 → 20.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { AfterViewInit, OnDestroy } from '@angular/core';
2
+ import { AfterViewInit } from '@angular/core';
3
3
  import * as _angular_platform_browser from '@angular/platform-browser';
4
4
  import { Widget, WidgetMetadata } from '@dragonworks/ngx-dashboard';
5
5
 
@@ -69,6 +69,30 @@ declare class ClockWidgetComponent implements Widget {
69
69
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<ClockWidgetComponent, "ngx-dashboard-clock-widget", never, {}, {}, never, never, true, never>;
70
70
  }
71
71
 
72
+ interface RadialGaugeWidgetState {
73
+ value?: number;
74
+ colorProfile?: 'dynamic' | 'static';
75
+ active?: boolean;
76
+ hasBackground?: boolean;
77
+ showValueLabel?: boolean;
78
+ }
79
+ declare class RadialGaugeWidgetComponent implements Widget {
80
+ #private;
81
+ static metadata: WidgetMetadata;
82
+ readonly safeSvgIcon: _angular_platform_browser.SafeHtml;
83
+ readonly state: _angular_core.WritableSignal<RadialGaugeWidgetState>;
84
+ readonly segments: _angular_core.Signal<{
85
+ from: number;
86
+ to: number;
87
+ color: string;
88
+ }[]>;
89
+ dashboardSetState(state?: unknown): void;
90
+ dashboardGetState(): RadialGaugeWidgetState;
91
+ dashboardEditState(): void;
92
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<RadialGaugeWidgetComponent, never>;
93
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<RadialGaugeWidgetComponent, "ngx-dashboard-radial-gauge-widget", never, {}, {}, never, never, true, never>;
94
+ }
95
+
72
96
  /**
73
97
  * Directive that automatically adjusts font size to fit text within its parent container.
74
98
  * Uses canvas-based measurement for performance and DOM verification for accuracy.
@@ -78,7 +102,7 @@ declare class ClockWidgetComponent implements Widget {
78
102
  * <span responsiveText [minFontSize]="12" [maxFontSize]="72">Dynamic text here</span>
79
103
  * </div>
80
104
  */
81
- declare class ResponsiveTextDirective implements AfterViewInit, OnDestroy {
105
+ declare class ResponsiveTextDirective implements AfterViewInit {
82
106
  /** Minimum font-size in pixels (accessibility floor) */
83
107
  minFontSize: _angular_core.InputSignalWithTransform<number, unknown>;
84
108
  /** Maximum font-size in pixels (layout ceiling) */
@@ -105,8 +129,8 @@ declare class ResponsiveTextDirective implements AfterViewInit, OnDestroy {
105
129
  private lastMaxW;
106
130
  private lastMaxH;
107
131
  private lastFontSize;
132
+ constructor();
108
133
  ngAfterViewInit(): void;
109
- ngOnDestroy(): void;
110
134
  /**
111
135
  * Debounced fit handler to prevent excessive recalculations
112
136
  */
@@ -144,8 +168,365 @@ declare class ResponsiveTextDirective implements AfterViewInit, OnDestroy {
144
168
  */
145
169
  private cleanup;
146
170
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<ResponsiveTextDirective, never>;
147
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ResponsiveTextDirective, "[responsiveText]", never, { "minFontSize": { "alias": "minFontSize"; "required": false; "isSignal": true; }; "maxFontSize": { "alias": "maxFontSize"; "required": false; "isSignal": true; }; "lineHeight": { "alias": "lineHeight"; "required": false; "isSignal": true; }; "observeMutations": { "alias": "observeMutations"; "required": false; "isSignal": true; }; "debounceMs": { "alias": "debounceMs"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
171
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<ResponsiveTextDirective, "[libResponsiveText]", never, { "minFontSize": { "alias": "minFontSize"; "required": false; "isSignal": true; }; "maxFontSize": { "alias": "maxFontSize"; "required": false; "isSignal": true; }; "lineHeight": { "alias": "lineHeight"; "required": false; "isSignal": true; }; "observeMutations": { "alias": "observeMutations"; "required": false; "isSignal": true; }; "debounceMs": { "alias": "debounceMs"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
172
+ }
173
+
174
+ interface RadialGaugeSegment {
175
+ from: number;
176
+ to: number;
177
+ color: string;
178
+ }
179
+ /**
180
+ * Responsive radial gauge component with hybrid sizing and thickness control.
181
+ *
182
+ * This component provides a highly flexible gauge system with three independent
183
+ * control dimensions that can be mixed and matched for different use cases:
184
+ *
185
+ * ## Size Control:
186
+ * - **Fixed Size**: Use manual `size` input (traditional behavior)
187
+ * - **Container Responsive**: Enable `fitToContainer` for automatic sizing
188
+ *
189
+ * ## Thickness Control:
190
+ * - **Manual Thickness**: Use individual thickness inputs (traditional behavior)
191
+ * - **Proportional Thickness**: Enable `responsiveMode` for size-based scaling
192
+ *
193
+ * ## Usage Scenarios:
194
+ *
195
+ * ### 1. Dashboard Widgets (Recommended)
196
+ * ```html
197
+ * <ngx-radial-gauge
198
+ * [value]="cpuUsage"
199
+ * [fitToContainer]="true"
200
+ * [responsiveMode]="true"
201
+ * [sizeToThicknessRatio]="12" />
202
+ * ```
203
+ * **Best for**: Grid layouts, dashboard panels, adaptive containers
204
+ * **Behavior**: Automatically resizes to fit available space while maintaining
205
+ * consistent proportional appearance across all sizes.
206
+ *
207
+ * ### 2. Fixed Layouts (Traditional)
208
+ * ```html
209
+ * <ngx-radial-gauge
210
+ * [value]="temperature"
211
+ * [size]="300"
212
+ * [outerThickness]="36"
213
+ * [innerThickness]="12" />
214
+ * ```
215
+ * **Best for**: Static designs, precise sizing requirements, print layouts
216
+ * **Behavior**: Exact pixel control over all dimensions, predictable appearance.
217
+ *
218
+ * ### 3. Scalable Designs
219
+ * ```html
220
+ * <ngx-radial-gauge
221
+ * [value]="batteryLevel"
222
+ * [size]="gaugeSize"
223
+ * [responsiveMode]="true"
224
+ * [sizeToThicknessRatio]="20" />
225
+ * ```
226
+ * **Best for**: User-configurable sizing, responsive breakpoints, zoom interfaces
227
+ * **Behavior**: Manual size control with automatic thickness scaling. As size
228
+ * increases/decreases, ring thickness scales proportionally to maintain visual balance.
229
+ *
230
+ * ## Mathematical Relationships:
231
+ *
232
+ * When `responsiveMode=true`, thickness follows this formula:
233
+ * ```
234
+ * baseThickness = effectiveSize / sizeToThicknessRatio
235
+ * outerThickness = baseThickness × responsiveProportions.outer (default: 3)
236
+ * innerThickness = baseThickness × responsiveProportions.inner (default: 1)
237
+ * gap = baseThickness × responsiveProportions.gap (default: 0.5)
238
+ * totalThickness = baseThickness × 4.5 (outer + inner + gap)
239
+ * ```
240
+ *
241
+ * Example with 300px gauge and ratio=20 (ultra-thin):
242
+ * - baseThickness = 15px
243
+ * - outerThickness = 45px (15×3)
244
+ * - innerThickness = 15px (15×1)
245
+ * - gap = 7.5px (15×0.5)
246
+ * - totalThickness = 67.5px (22.5% of diameter)
247
+ *
248
+ * ## Container Responsiveness:
249
+ *
250
+ * When `fitToContainer=true`, the component uses ResizeObserver to:
251
+ * 1. Monitor parent container dimension changes
252
+ * 2. Calculate maximum diameter maintaining 2:1 aspect ratio (width:height)
253
+ * 3. Apply containerPadding for safe margins
254
+ * 4. Update gauge size in real-time
255
+ *
256
+ * This provides true responsive behavior for dashboard widgets, grid layouts,
257
+ * and adaptive interfaces.
258
+ *
259
+ * ## Accessibility:
260
+ *
261
+ * The component implements ARIA meter role with proper labeling:
262
+ * - `role="meter"` for semantic meaning
263
+ * - `aria-valuemin/max/now` for screen readers
264
+ * - `aria-label` with contextual information
265
+ * - Internationalized number formatting
266
+ *
267
+ */
268
+ declare class RadialGaugeComponent {
269
+ private readonly valueTextEl;
270
+ private readonly valueGroupEl;
271
+ private readonly refTextEl;
272
+ readonly value: _angular_core.InputSignal<number>;
273
+ readonly min: _angular_core.InputSignal<number>;
274
+ readonly max: _angular_core.InputSignal<number>;
275
+ readonly segments: _angular_core.InputSignal<RadialGaugeSegment[] | undefined>;
276
+ readonly title: _angular_core.InputSignal<string>;
277
+ readonly description: _angular_core.InputSignal<string>;
278
+ readonly segmentGapPx: _angular_core.InputSignal<number>;
279
+ /**
280
+ * Whether the gauge should display with a background.
281
+ * Affects text color contrast and other visual elements.
282
+ * @default false
283
+ */
284
+ readonly hasBackground: _angular_core.InputSignal<boolean>;
285
+ /**
286
+ * Whether to display the numeric value label in the center of the gauge.
287
+ * @default true
288
+ */
289
+ readonly showValueLabel: _angular_core.InputSignal<boolean>;
290
+ /**
291
+ * Base gauge diameter in pixels. Used as fallback when fitToContainer is false.
292
+ * @default 300
293
+ */
294
+ readonly size: _angular_core.InputSignal<number>;
295
+ /**
296
+ * Automatically resize gauge to fit its container dimensions.
297
+ * When true, the gauge will observe container size changes and adjust accordingly.
298
+ * Maintains semicircle aspect ratio (2:1 width:height).
299
+ * @default false
300
+ */
301
+ readonly fitToContainer: _angular_core.InputSignal<boolean>;
302
+ /**
303
+ * Padding in pixels to maintain from container edges when fitToContainer is true.
304
+ * @default 10
305
+ */
306
+ readonly containerPadding: _angular_core.InputSignal<number>;
307
+ /**
308
+ * Use proportional thickness scaling based on gauge size.
309
+ * When true, all thickness values are calculated as multiples of baseThickness.
310
+ * Overrides manual outerThickness, innerThickness, and gap inputs.
311
+ * @default false
312
+ */
313
+ readonly responsiveMode: _angular_core.InputSignal<boolean>;
314
+ /**
315
+ * Ratio used to calculate base thickness from gauge size.
316
+ * baseThickness = effectiveSize / sizeToThicknessRatio
317
+ * Higher values create thinner gauge rings for ultra-thin appearance.
318
+ * @default 20
319
+ * @example
320
+ * - ratio=15: thicker rings (bt = size/15)
321
+ * - ratio=20: ultra-thin balanced appearance (bt = size/20)
322
+ * - ratio=30: extremely thin rings (bt = size/30)
323
+ */
324
+ readonly sizeToThicknessRatio: _angular_core.InputSignal<number>;
325
+ /**
326
+ * Proportional multipliers for responsive thickness calculations.
327
+ * - outer: Multiplier for outer ring thickness (default: 3)
328
+ * - inner: Multiplier for inner ring thickness (default: 1)
329
+ * - gap: Multiplier for gap between rings (default: 0.5)
330
+ * Total thickness = baseThickness × (outer + inner + gap) = bt × 4.5
331
+ * @default { outer: 3, inner: 1, gap: 0.5 }
332
+ */
333
+ readonly responsiveProportions: _angular_core.InputSignal<{
334
+ outer: number;
335
+ inner: number;
336
+ gap: number;
337
+ }>;
338
+ /**
339
+ * Manual outer ring thickness in pixels. Ignored when responsiveMode is true.
340
+ * @default 36
341
+ */
342
+ readonly outerThickness: _angular_core.InputSignal<number>;
343
+ /**
344
+ * Manual inner ring thickness in pixels. Ignored when responsiveMode is true.
345
+ * @default 12
346
+ */
347
+ readonly innerThickness: _angular_core.InputSignal<number>;
348
+ /**
349
+ * Manual gap between rings in pixels. Ignored when responsiveMode is true.
350
+ * @default 8
351
+ */
352
+ readonly gap: _angular_core.InputSignal<number>;
353
+ readonly titleId: string;
354
+ readonly descId: string;
355
+ readonly clipId: string;
356
+ private readonly locale;
357
+ private readonly elementRef;
358
+ private readonly destroyRef;
359
+ private readonly nf;
360
+ /**
361
+ * Tracks the container's available size for responsive sizing.
362
+ * Updated by ResizeObserver when fitToContainer is enabled.
363
+ * @private
364
+ */
365
+ private readonly containerSize;
366
+ /**
367
+ * ResizeObserver instance for monitoring container size changes.
368
+ * Created when fitToContainer is enabled, destroyed on component cleanup.
369
+ * @private
370
+ */
371
+ private resizeObserver;
372
+ readonly viewReady: _angular_core.Signal<boolean>;
373
+ readonly fontsReady: _angular_core.Signal<boolean>;
374
+ constructor();
375
+ /**
376
+ * Effect that manages ResizeObserver lifecycle based on fitToContainer input.
377
+ * Automatically connects/disconnects observer when the input changes.
378
+ * @private
379
+ */
380
+ private readonly containerObserverEffect;
381
+ referenceString: _angular_core.Signal<string>;
382
+ valueTransform: _angular_core.Signal<string>;
383
+ /** Guarded getBBox that avoids 0/NaN on detached or invisible nodes. */
384
+ safeBBox(node: SVGGraphicsElement): DOMRect;
385
+ /**
386
+ * The effective gauge diameter, accounting for container sizing and manual size input.
387
+ * Priority: containerSize (when fitToContainer=true) > manual size input
388
+ * @returns Effective diameter in pixels
389
+ *
390
+ * @example
391
+ * // Fixed size mode
392
+ * fitToContainer=false, size=300 → effectiveSize=300
393
+ *
394
+ * // Container responsive mode
395
+ * fitToContainer=true, container=400px wide → effectiveSize=380 (minus padding)
396
+ */
397
+ private readonly effectiveSize;
398
+ /**
399
+ * Base thickness calculated from effective size for proportional scaling.
400
+ * Only used when responsiveMode is enabled.
401
+ * Formula: baseThickness = effectiveSize / sizeToThicknessRatio
402
+ * @returns Base thickness in pixels, or 0 when responsiveMode is false
403
+ *
404
+ * @example
405
+ * // effectiveSize=300, sizeToThicknessRatio=12
406
+ * baseThickness = 300/12 = 25px
407
+ * // Total ring thickness = 25 × 4.5 = 112.5px (37.5% of diameter)
408
+ */
409
+ private readonly baseThickness;
410
+ /**
411
+ * Effective outer ring thickness, supporting both manual and responsive modes.
412
+ * - Responsive mode: baseThickness × responsiveProportions.outer
413
+ * - Manual mode: outerThickness input value
414
+ * @returns Outer ring thickness in pixels
415
+ */
416
+ readonly effectiveOuterThickness: _angular_core.Signal<number>;
417
+ /**
418
+ * Effective inner ring thickness, supporting both manual and responsive modes.
419
+ * - Responsive mode: baseThickness × responsiveProportions.inner
420
+ * - Manual mode: innerThickness input value
421
+ * @returns Inner ring thickness in pixels
422
+ */
423
+ readonly effectiveInnerThickness: _angular_core.Signal<number>;
424
+ /**
425
+ * Effective gap between rings, supporting both manual and responsive modes.
426
+ * - Responsive mode: baseThickness × responsiveProportions.gap
427
+ * - Manual mode: gap input value
428
+ * @returns Gap between rings in pixels
429
+ */
430
+ readonly effectiveGap: _angular_core.Signal<number>;
431
+ private readonly svgPadding;
432
+ readonly svgWidth: _angular_core.Signal<number>;
433
+ readonly svgHeight: _angular_core.Signal<number>;
434
+ readonly centerX: _angular_core.Signal<number>;
435
+ readonly centerY: _angular_core.Signal<number>;
436
+ /**
437
+ * If a string is provided, we measure it and allocate space for that width.
438
+ * If a number is provided, we build a string of that many `referenceGlyph`s.
439
+ * If omitted, we fall back to measuring the actual label.
440
+ */
441
+ labelReference: _angular_core.InputSignal<string | number | undefined>;
442
+ /** Glyph to repeat when labelReference is a number (defaults to '0'). */
443
+ referenceGlyph: _angular_core.InputSignal<string>;
444
+ /** Extra breathing room inside the inner semicircle box (in px). */
445
+ labelPadding: _angular_core.InputSignal<number>;
446
+ /** Safety multiplier to avoid clipping ascenders/descenders. */
447
+ baselineSafety: _angular_core.InputSignal<number>;
448
+ readonly outerRadius: _angular_core.Signal<number>;
449
+ readonly innerRadius: _angular_core.Signal<number>;
450
+ readonly legendOuterRadius: _angular_core.Signal<number>;
451
+ readonly legendInnerRadius: _angular_core.Signal<number>;
452
+ private readonly startAngle;
453
+ private readonly endAngle;
454
+ readonly clampedValue: _angular_core.Signal<number>;
455
+ readonly percentage: _angular_core.Signal<number>;
456
+ readonly percent: _angular_core.Signal<number>;
457
+ private readonly defaultSegments;
458
+ readonly actualSegments: _angular_core.Signal<RadialGaugeSegment[]>;
459
+ readonly formattedLabel: _angular_core.Signal<string>;
460
+ readonly valueColor: _angular_core.Signal<string>;
461
+ readonly backgroundArcPath: _angular_core.Signal<string>;
462
+ readonly segmentPaths: _angular_core.Signal<{
463
+ path: string;
464
+ color: string;
465
+ }[]>;
466
+ readonly ariaLabel: _angular_core.Signal<string>;
467
+ private clamp;
468
+ /**
469
+ * Converts a percentage (0-1) to an angle position on the gauge arc.
470
+ * The gauge spans from startAngle (-180°) to endAngle (0°), creating a semicircle.
471
+ * @param p - Percentage value between 0 and 1
472
+ * @returns Angle in degrees for the given percentage along the gauge arc
473
+ * @example
474
+ * angleForPercentage(0) => -180° (start of gauge)
475
+ * angleForPercentage(0.5) => -90° (middle of gauge)
476
+ * angleForPercentage(1) => 0° (end of gauge)
477
+ */
478
+ private angleForPercentage;
479
+ /**
480
+ * Converts polar coordinates (radius, angle) to Cartesian coordinates (x, y).
481
+ * Uses standard trigonometric conversion where angle 0° points to the right (3 o'clock).
482
+ * @param cx - Center X coordinate of the circle
483
+ * @param cy - Center Y coordinate of the circle
484
+ * @param r - Radius distance from center
485
+ * @param angle - Angle in degrees (0° = right, 90° = down, 180° = left, -90° = up)
486
+ * @returns Object with x and y Cartesian coordinates
487
+ * @example
488
+ * polarToCartesian(100, 100, 50, 0) => {x: 150, y: 100} // 3 o'clock
489
+ * polarToCartesian(100, 100, 50, -90) => {x: 100, y: 50} // 12 o'clock
490
+ */
491
+ private polarToCartesian;
492
+ /**
493
+ * Creates an SVG path string for a circular arc segment.
494
+ * Uses SVG arc path commands to draw an arc from start angle to end angle.
495
+ * @param r - Radius of the arc
496
+ * @param a0 - Starting angle in degrees
497
+ * @param a1 - Ending angle in degrees
498
+ * @returns SVG path string defining the arc
499
+ * @example
500
+ * createArcPath(50, -180, 0) => "M cx-50 cy A 50 50 0 1 1 cx+50 cy"
501
+ * This creates a semicircle from left (-180°) to right (0°)
502
+ *
503
+ * SVG Arc Parameters:
504
+ * - rx, ry: Radii (equal for circular arc)
505
+ * - x-axis-rotation: 0 (no rotation for circles)
506
+ * - large-arc-flag: 1 if arc > 180°, 0 otherwise
507
+ * - sweep-flag: 1 for clockwise, 0 for counter-clockwise
508
+ */
509
+ private createArcPath;
510
+ /**
511
+ * Calculates the angular gap in degrees needed for a specific pixel gap at a given radius.
512
+ * Used to create visual separation between legend segments.
513
+ * @param px - Desired gap size in pixels
514
+ * @param r - Radius at which the gap will appear
515
+ * @returns Gap size in degrees, clamped between 0° and 180°
516
+ * @example
517
+ * For a 4px gap on a radius of 100px:
518
+ * Arc length = π * 100 = 314.16px (semicircle)
519
+ * Degrees = 180 * (4 / 314.16) ≈ 2.3°
520
+ *
521
+ * Mathematical basis:
522
+ * - Semicircle arc length = π * r
523
+ * - Ratio of gap to semicircle = px / (π * r)
524
+ * - Convert ratio to degrees by multiplying by 180°
525
+ */
526
+ private gapDegreesForRadius;
527
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<RadialGaugeComponent, never>;
528
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<RadialGaugeComponent, "ngx-radial-gauge", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "segments": { "alias": "segments"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "segmentGapPx": { "alias": "segmentGapPx"; "required": false; "isSignal": true; }; "hasBackground": { "alias": "hasBackground"; "required": false; "isSignal": true; }; "showValueLabel": { "alias": "showValueLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "fitToContainer": { "alias": "fitToContainer"; "required": false; "isSignal": true; }; "containerPadding": { "alias": "containerPadding"; "required": false; "isSignal": true; }; "responsiveMode": { "alias": "responsiveMode"; "required": false; "isSignal": true; }; "sizeToThicknessRatio": { "alias": "sizeToThicknessRatio"; "required": false; "isSignal": true; }; "responsiveProportions": { "alias": "responsiveProportions"; "required": false; "isSignal": true; }; "outerThickness": { "alias": "outerThickness"; "required": false; "isSignal": true; }; "innerThickness": { "alias": "innerThickness"; "required": false; "isSignal": true; }; "gap": { "alias": "gap"; "required": false; "isSignal": true; }; "labelReference": { "alias": "labelReference"; "required": false; "isSignal": true; }; "referenceGlyph": { "alias": "referenceGlyph"; "required": false; "isSignal": true; }; "labelPadding": { "alias": "labelPadding"; "required": false; "isSignal": true; }; "baselineSafety": { "alias": "baselineSafety"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
148
529
  }
149
530
 
150
- export { ArrowWidgetComponent, ClockWidgetComponent, LabelWidgetComponent, ResponsiveTextDirective };
151
- export type { ArrowWidgetState, ClockWidgetState, LabelWidgetState };
531
+ export { ArrowWidgetComponent, ClockWidgetComponent, LabelWidgetComponent, RadialGaugeComponent, RadialGaugeWidgetComponent, ResponsiveTextDirective };
532
+ export type { ArrowWidgetState, ClockWidgetState, LabelWidgetState, RadialGaugeSegment, RadialGaugeWidgetState };
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@dragonworks/ngx-dashboard-widgets",
3
- "version": "20.0.5",
3
+ "version": "20.1.0",
4
4
  "description": "Widget collection for ngx-dashboard with Material Design 3 compliance including arrow, label, clock widgets and responsive text directive",
5
5
  "peerDependencies": {
6
- "@angular/common": "^20.0.0",
7
- "@angular/core": "^20.0.0",
6
+ "@angular/common": "^20.2.0",
7
+ "@angular/core": "^20.2.0",
8
8
  "@dragonworks/ngx-dashboard": "^20.0.0"
9
9
  },
10
10
  "dependencies": {