ng-prime-tools 1.0.12 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +13 -0
  2. package/esm2022/lib/models/card-config.model.mjs +1 -1
  3. package/esm2022/lib/models/icon-style.model.mjs +1 -1
  4. package/esm2022/lib/models/nav-bar-menu-config.model.mjs +1 -1
  5. package/esm2022/lib/models/pattern.model.mjs +1 -1
  6. package/esm2022/lib/models/text-style.model.mjs +1 -1
  7. package/esm2022/lib/pt-card/pt-card.component.mjs +34 -15
  8. package/esm2022/lib/pt-chart/pt-chart.component.mjs +19 -9
  9. package/esm2022/lib/pt-menu/pt-menu.component.mjs +2 -2
  10. package/esm2022/lib/pt-menu-fancy/pt-menu-fancy.component.mjs +2 -2
  11. package/esm2022/lib/pt-metric-card/pt-metric-card.component.mjs +28 -4
  12. package/esm2022/lib/pt-nav-bar-menu/pt-nav-bar-menu.component.mjs +34 -7
  13. package/esm2022/lib/pt-page-skeleton/pt-page-skeleton.component.mjs +3 -1
  14. package/esm2022/lib/pt-side-bar-menu/pt-side-bar-menu.component.mjs +4 -1
  15. package/fesm2022/ng-prime-tools.mjs +118 -33
  16. package/fesm2022/ng-prime-tools.mjs.map +1 -1
  17. package/lib/models/card-config.model.d.ts +1 -0
  18. package/lib/models/card-config.model.d.ts.map +1 -1
  19. package/lib/models/icon-style.model.d.ts +2 -0
  20. package/lib/models/icon-style.model.d.ts.map +1 -1
  21. package/lib/models/nav-bar-menu-config.model.d.ts +2 -0
  22. package/lib/models/nav-bar-menu-config.model.d.ts.map +1 -1
  23. package/lib/models/pattern.model.d.ts +1 -0
  24. package/lib/models/pattern.model.d.ts.map +1 -1
  25. package/lib/models/text-style.model.d.ts +1 -0
  26. package/lib/models/text-style.model.d.ts.map +1 -1
  27. package/lib/pt-card/pt-card.component.d.ts +8 -5
  28. package/lib/pt-card/pt-card.component.d.ts.map +1 -1
  29. package/lib/pt-chart/pt-chart.component.d.ts +3 -1
  30. package/lib/pt-chart/pt-chart.component.d.ts.map +1 -1
  31. package/lib/pt-menu-fancy/pt-menu-fancy.component.d.ts.map +1 -1
  32. package/lib/pt-metric-card/pt-metric-card.component.d.ts +22 -1
  33. package/lib/pt-metric-card/pt-metric-card.component.d.ts.map +1 -1
  34. package/lib/pt-nav-bar-menu/pt-nav-bar-menu.component.d.ts +8 -1
  35. package/lib/pt-nav-bar-menu/pt-nav-bar-menu.component.d.ts.map +1 -1
  36. package/lib/pt-page-skeleton/pt-page-skeleton.component.d.ts.map +1 -1
  37. package/lib/pt-side-bar-menu/pt-side-bar-menu.component.d.ts.map +1 -1
  38. package/package.json +1 -1
@@ -1846,9 +1846,16 @@ class PTMetricCardComponent {
1846
1846
  getIconStyles() {
1847
1847
  if (this.isIconObject()) {
1848
1848
  const icon = this.cardData.icon;
1849
+ const shape = icon.shape || 'circular'; // Default to 'circular' if not specified
1850
+ // Determine border radius based on shape
1851
+ const borderRadius = shape === 'circular' ? '50%' : '8px';
1849
1852
  return {
1850
1853
  color: icon.color || PTMetricCardComponent.DEFAULT_ICON_COLOR,
1851
1854
  fontSize: icon.fontSize || PTMetricCardComponent.DEFAULT_ICON_SIZE,
1855
+ 'background-color': icon.backgroundColor || 'transparent',
1856
+ 'border-radius': borderRadius,
1857
+ padding: '6px',
1858
+ display: 'inline-block',
1852
1859
  };
1853
1860
  }
1854
1861
  return {};
@@ -1859,6 +1866,7 @@ class PTMetricCardComponent {
1859
1866
  return {
1860
1867
  color: title.color || PTMetricCardComponent.DEFAULT_TITLE_COLOR,
1861
1868
  fontSize: title.fontSize || PTMetricCardComponent.DEFAULT_TITLE_SIZE,
1869
+ fontWeight: title.fontWeight || 'normal',
1862
1870
  };
1863
1871
  }
1864
1872
  return {};
@@ -1869,12 +1877,14 @@ class PTMetricCardComponent {
1869
1877
  return {
1870
1878
  color: value.color || PTMetricCardComponent.DEFAULT_VALUE_COLOR,
1871
1879
  fontSize: value.fontSize || PTMetricCardComponent.DEFAULT_VALUE_SIZE,
1880
+ fontWeight: value.fontWeight || 'bold',
1872
1881
  };
1873
1882
  }
1874
1883
  else {
1875
1884
  return {
1876
1885
  color: PTMetricCardComponent.DEFAULT_VALUE_COLOR,
1877
1886
  fontSize: PTMetricCardComponent.DEFAULT_VALUE_SIZE,
1887
+ fontWeight: 'bold',
1878
1888
  };
1879
1889
  }
1880
1890
  }
@@ -1887,12 +1897,14 @@ class PTMetricCardComponent {
1887
1897
  PTMetricCardComponent.DEFAULT_LABEL_COLOR,
1888
1898
  fontSize: label.fontSize ||
1889
1899
  PTMetricCardComponent.DEFAULT_LABEL_SIZE,
1900
+ fontWeight: label.fontWeight || 'normal',
1890
1901
  };
1891
1902
  }
1892
1903
  else {
1893
1904
  return {
1894
1905
  color: PTMetricCardComponent.DEFAULT_LABEL_COLOR,
1895
1906
  fontSize: PTMetricCardComponent.DEFAULT_LABEL_SIZE,
1907
+ fontWeight: 'normal',
1896
1908
  };
1897
1909
  }
1898
1910
  }
@@ -1904,12 +1916,14 @@ class PTMetricCardComponent {
1904
1916
  PTMetricCardComponent.DEFAULT_ADDITIONAL_INFO_COLOR,
1905
1917
  fontSize: additionalInfo.fontSize ||
1906
1918
  PTMetricCardComponent.DEFAULT_ADDITIONAL_INFO_SIZE,
1919
+ fontWeight: additionalInfo.fontWeight || 'normal',
1907
1920
  };
1908
1921
  }
1909
1922
  else {
1910
1923
  return {
1911
1924
  color: PTMetricCardComponent.DEFAULT_ADDITIONAL_INFO_COLOR,
1912
1925
  fontSize: PTMetricCardComponent.DEFAULT_ADDITIONAL_INFO_SIZE,
1926
+ fontWeight: 'normal',
1913
1927
  };
1914
1928
  }
1915
1929
  }
@@ -1921,18 +1935,28 @@ class PTMetricCardComponent {
1921
1935
  const label = this.cardData.value?.label;
1922
1936
  return (this.isLabelObject(label) && label.position === 'right');
1923
1937
  }
1924
- getBackgroundStyle() {
1938
+ getMetricCardContainerStyle() {
1939
+ return {
1940
+ 'min-width': this.cardData.size?.minWidth || '100%',
1941
+ 'max-width': this.cardData.size?.maxWidth || 'calc(25% - 16px)',
1942
+ width: this.cardData.size?.fixedWidth || 'auto',
1943
+ };
1944
+ }
1945
+ getMetricCardStyle() {
1925
1946
  return {
1926
1947
  'background-color': this.cardData.appearance?.backgroundColor ||
1927
1948
  PTMetricCardComponent.DEFAULT_BACKGROUND_COLOR,
1949
+ 'min-width': this.cardData.size?.minWidth || '100%',
1950
+ 'max-width': this.cardData.size?.maxWidth || 'calc(25% - 16px)',
1951
+ width: this.cardData.size?.fixedWidth || 'auto',
1928
1952
  };
1929
1953
  }
1930
1954
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTMetricCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1931
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTMetricCardComponent, selector: "pt-metric-card", inputs: { cardData: "cardData" }, ngImport: i0, template: "<div\n class=\"metric-card-container\"\n [ngStyle]=\"{\n 'min-width': cardData.size?.minWidth || '100%',\n 'max-width': cardData.size?.maxWidth || 'calc(25% - 16px)',\n width: cardData.size?.fixedWidth || 'auto'\n }\"\n>\n <div\n *ngIf=\"cardData.verticalLine?.show\"\n class=\"vertical-line\"\n [ngStyle]=\"{\n 'background-color': cardData.verticalLine?.color || '#5a67d8'\n }\"\n ></div>\n\n <div class=\"metric-card\" [ngStyle]=\"getBackgroundStyle()\">\n <div class=\"metric-card-header\">\n <i\n *ngIf=\"isIconObject()\"\n [ngClass]=\"getIconText()\"\n [ngStyle]=\"getIconStyles()\"\n ></i>\n <i *ngIf=\"!isIconObject()\" [ngClass]=\"cardData.icon\"></i>\n\n <span\n *ngIf=\"isTitleObject()\"\n class=\"metric-card-header-text\"\n [ngStyle]=\"getTitleStyles()\"\n >\n {{ getTitleText() }}\n </span>\n <span *ngIf=\"!isTitleObject()\" class=\"metric-card-header-text\">\n {{ cardData.title }}\n </span>\n </div>\n\n <div class=\"metric-card-content\">\n <div class=\"metric-value\" [ngStyle]=\"getValueStyles()\">\n <span\n *ngIf=\"isLabelOnLeft()\"\n class=\"value-label\"\n [ngStyle]=\"getLabelStyles('left')\"\n >\n {{ getLabelText() }}\n </span>\n\n <span [ngStyle]=\"getValueStyles()\">{{ getValueText() }}</span>\n\n <span\n *ngIf=\"isLabelOnRight()\"\n class=\"value-label\"\n [ngStyle]=\"getLabelStyles('right')\"\n >\n {{ getLabelText() }}\n </span>\n </div>\n\n <div\n *ngIf=\"cardData.divider?.show\"\n class=\"metric-divider\"\n [ngStyle]=\"{ backgroundColor: cardData.divider?.color || '#e2e8f0' }\"\n ></div>\n\n <div\n *ngIf=\"isAdditionalInfoObject()\"\n class=\"metric-additional-info\"\n [ngStyle]=\"getAdditionalInfoStyles()\"\n >\n {{ getAdditionalInfoText() }}\n </div>\n <div\n *ngIf=\"!isAdditionalInfoObject()\"\n class=\"metric-additional-info\"\n [ngStyle]=\"getAdditionalInfoStyles()\"\n >\n {{ cardData.additionalInfo }}\n </div>\n </div>\n </div>\n</div>\n", styles: [".metric-card-container{display:flex;align-items:stretch;box-sizing:border-box}.vertical-line{width:4px;border-radius:8px 0 0 8px;margin-right:-4px;z-index:2}.metric-card{background-color:#fff;border-radius:5px;box-shadow:0 1px 3px #0000001a;padding:16px;display:flex;flex-direction:column;box-sizing:border-box;margin-left:0}.metric-card-header{display:flex;align-items:center;margin-bottom:16px}.metric-card-header i.icon-text{margin-right:8px}.metric-card-content{display:flex;flex-direction:column;justify-content:space-between}.metric-number{font-weight:700}.metric-label{margin-left:8px}.metric-divider{width:100%;height:1px;margin:16px 0}.metric-additional-info{margin-top:8px}.metric-card-header-text{margin-left:6px}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
1955
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTMetricCardComponent, selector: "pt-metric-card", inputs: { cardData: "cardData" }, ngImport: i0, template: "<div class=\"metric-card-container\" [ngStyle]=\"getMetricCardContainerStyle()\">\n <div\n *ngIf=\"cardData.verticalLine?.show\"\n class=\"vertical-line\"\n [ngStyle]=\"{\n 'background-color': cardData.verticalLine?.color || '#5a67d8'\n }\"\n ></div>\n\n <div class=\"metric-card\" [ngStyle]=\"getMetricCardStyle()\">\n <div class=\"metric-card-header\">\n <i\n *ngIf=\"isIconObject()\"\n [ngClass]=\"getIconText()\"\n [ngStyle]=\"getIconStyles()\"\n ></i>\n <i *ngIf=\"!isIconObject()\" [ngClass]=\"cardData.icon\"></i>\n\n <span\n *ngIf=\"isTitleObject()\"\n class=\"metric-card-header-text\"\n [ngStyle]=\"getTitleStyles()\"\n >\n {{ getTitleText() }}\n </span>\n <span *ngIf=\"!isTitleObject()\" class=\"metric-card-header-text\">\n {{ cardData.title }}\n </span>\n </div>\n\n <div class=\"metric-card-content\">\n <div class=\"metric-value\" [ngStyle]=\"getValueStyles()\">\n <span\n *ngIf=\"isLabelOnLeft()\"\n class=\"value-label\"\n [ngStyle]=\"getLabelStyles('left')\"\n >\n {{ getLabelText() }}\n </span>\n\n <span [ngStyle]=\"getValueStyles()\">{{ getValueText() }}</span>\n\n <span\n *ngIf=\"isLabelOnRight()\"\n class=\"value-label\"\n [ngStyle]=\"getLabelStyles('right')\"\n >\n {{ getLabelText() }}\n </span>\n </div>\n\n <div\n *ngIf=\"cardData.divider?.show\"\n class=\"metric-divider\"\n [ngStyle]=\"{ backgroundColor: cardData.divider?.color || '#e2e8f0' }\"\n ></div>\n\n <div\n *ngIf=\"isAdditionalInfoObject()\"\n class=\"metric-additional-info\"\n [ngStyle]=\"getAdditionalInfoStyles()\"\n >\n {{ getAdditionalInfoText() }}\n </div>\n <div\n *ngIf=\"!isAdditionalInfoObject()\"\n class=\"metric-additional-info\"\n [ngStyle]=\"getAdditionalInfoStyles()\"\n >\n {{ cardData.additionalInfo }}\n </div>\n </div>\n </div>\n</div>\n", styles: [".metric-card-container{display:flex;align-items:stretch;box-sizing:border-box}.vertical-line{width:4px;border-radius:8px 0 0 8px;margin-right:-4px;z-index:2}.metric-card{background-color:#fff;border-radius:5px;box-shadow:0 1px 3px #0000001a;padding:16px;display:flex;flex-direction:column;box-sizing:border-box;margin-left:0}.metric-card-header{display:flex;align-items:center;margin-bottom:16px}.metric-card-header i.icon-text{margin-right:8px}.metric-card-content{display:flex;flex-direction:column;justify-content:space-between}.metric-number{font-weight:700}.metric-label{margin-left:8px}.metric-divider{width:100%;height:1px;margin:16px 0}.metric-additional-info{margin-top:8px}.metric-card-header-text{margin-left:6px}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
1932
1956
  }
1933
1957
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTMetricCardComponent, decorators: [{
1934
1958
  type: Component,
1935
- args: [{ selector: 'pt-metric-card', template: "<div\n class=\"metric-card-container\"\n [ngStyle]=\"{\n 'min-width': cardData.size?.minWidth || '100%',\n 'max-width': cardData.size?.maxWidth || 'calc(25% - 16px)',\n width: cardData.size?.fixedWidth || 'auto'\n }\"\n>\n <div\n *ngIf=\"cardData.verticalLine?.show\"\n class=\"vertical-line\"\n [ngStyle]=\"{\n 'background-color': cardData.verticalLine?.color || '#5a67d8'\n }\"\n ></div>\n\n <div class=\"metric-card\" [ngStyle]=\"getBackgroundStyle()\">\n <div class=\"metric-card-header\">\n <i\n *ngIf=\"isIconObject()\"\n [ngClass]=\"getIconText()\"\n [ngStyle]=\"getIconStyles()\"\n ></i>\n <i *ngIf=\"!isIconObject()\" [ngClass]=\"cardData.icon\"></i>\n\n <span\n *ngIf=\"isTitleObject()\"\n class=\"metric-card-header-text\"\n [ngStyle]=\"getTitleStyles()\"\n >\n {{ getTitleText() }}\n </span>\n <span *ngIf=\"!isTitleObject()\" class=\"metric-card-header-text\">\n {{ cardData.title }}\n </span>\n </div>\n\n <div class=\"metric-card-content\">\n <div class=\"metric-value\" [ngStyle]=\"getValueStyles()\">\n <span\n *ngIf=\"isLabelOnLeft()\"\n class=\"value-label\"\n [ngStyle]=\"getLabelStyles('left')\"\n >\n {{ getLabelText() }}\n </span>\n\n <span [ngStyle]=\"getValueStyles()\">{{ getValueText() }}</span>\n\n <span\n *ngIf=\"isLabelOnRight()\"\n class=\"value-label\"\n [ngStyle]=\"getLabelStyles('right')\"\n >\n {{ getLabelText() }}\n </span>\n </div>\n\n <div\n *ngIf=\"cardData.divider?.show\"\n class=\"metric-divider\"\n [ngStyle]=\"{ backgroundColor: cardData.divider?.color || '#e2e8f0' }\"\n ></div>\n\n <div\n *ngIf=\"isAdditionalInfoObject()\"\n class=\"metric-additional-info\"\n [ngStyle]=\"getAdditionalInfoStyles()\"\n >\n {{ getAdditionalInfoText() }}\n </div>\n <div\n *ngIf=\"!isAdditionalInfoObject()\"\n class=\"metric-additional-info\"\n [ngStyle]=\"getAdditionalInfoStyles()\"\n >\n {{ cardData.additionalInfo }}\n </div>\n </div>\n </div>\n</div>\n", styles: [".metric-card-container{display:flex;align-items:stretch;box-sizing:border-box}.vertical-line{width:4px;border-radius:8px 0 0 8px;margin-right:-4px;z-index:2}.metric-card{background-color:#fff;border-radius:5px;box-shadow:0 1px 3px #0000001a;padding:16px;display:flex;flex-direction:column;box-sizing:border-box;margin-left:0}.metric-card-header{display:flex;align-items:center;margin-bottom:16px}.metric-card-header i.icon-text{margin-right:8px}.metric-card-content{display:flex;flex-direction:column;justify-content:space-between}.metric-number{font-weight:700}.metric-label{margin-left:8px}.metric-divider{width:100%;height:1px;margin:16px 0}.metric-additional-info{margin-top:8px}.metric-card-header-text{margin-left:6px}\n"] }]
1959
+ args: [{ selector: 'pt-metric-card', template: "<div class=\"metric-card-container\" [ngStyle]=\"getMetricCardContainerStyle()\">\n <div\n *ngIf=\"cardData.verticalLine?.show\"\n class=\"vertical-line\"\n [ngStyle]=\"{\n 'background-color': cardData.verticalLine?.color || '#5a67d8'\n }\"\n ></div>\n\n <div class=\"metric-card\" [ngStyle]=\"getMetricCardStyle()\">\n <div class=\"metric-card-header\">\n <i\n *ngIf=\"isIconObject()\"\n [ngClass]=\"getIconText()\"\n [ngStyle]=\"getIconStyles()\"\n ></i>\n <i *ngIf=\"!isIconObject()\" [ngClass]=\"cardData.icon\"></i>\n\n <span\n *ngIf=\"isTitleObject()\"\n class=\"metric-card-header-text\"\n [ngStyle]=\"getTitleStyles()\"\n >\n {{ getTitleText() }}\n </span>\n <span *ngIf=\"!isTitleObject()\" class=\"metric-card-header-text\">\n {{ cardData.title }}\n </span>\n </div>\n\n <div class=\"metric-card-content\">\n <div class=\"metric-value\" [ngStyle]=\"getValueStyles()\">\n <span\n *ngIf=\"isLabelOnLeft()\"\n class=\"value-label\"\n [ngStyle]=\"getLabelStyles('left')\"\n >\n {{ getLabelText() }}\n </span>\n\n <span [ngStyle]=\"getValueStyles()\">{{ getValueText() }}</span>\n\n <span\n *ngIf=\"isLabelOnRight()\"\n class=\"value-label\"\n [ngStyle]=\"getLabelStyles('right')\"\n >\n {{ getLabelText() }}\n </span>\n </div>\n\n <div\n *ngIf=\"cardData.divider?.show\"\n class=\"metric-divider\"\n [ngStyle]=\"{ backgroundColor: cardData.divider?.color || '#e2e8f0' }\"\n ></div>\n\n <div\n *ngIf=\"isAdditionalInfoObject()\"\n class=\"metric-additional-info\"\n [ngStyle]=\"getAdditionalInfoStyles()\"\n >\n {{ getAdditionalInfoText() }}\n </div>\n <div\n *ngIf=\"!isAdditionalInfoObject()\"\n class=\"metric-additional-info\"\n [ngStyle]=\"getAdditionalInfoStyles()\"\n >\n {{ cardData.additionalInfo }}\n </div>\n </div>\n </div>\n</div>\n", styles: [".metric-card-container{display:flex;align-items:stretch;box-sizing:border-box}.vertical-line{width:4px;border-radius:8px 0 0 8px;margin-right:-4px;z-index:2}.metric-card{background-color:#fff;border-radius:5px;box-shadow:0 1px 3px #0000001a;padding:16px;display:flex;flex-direction:column;box-sizing:border-box;margin-left:0}.metric-card-header{display:flex;align-items:center;margin-bottom:16px}.metric-card-header i.icon-text{margin-right:8px}.metric-card-content{display:flex;flex-direction:column;justify-content:space-between}.metric-number{font-weight:700}.metric-label{margin-left:8px}.metric-divider{width:100%;height:1px;margin:16px 0}.metric-additional-info{margin-top:8px}.metric-card-header-text{margin-left:6px}\n"] }]
1936
1960
  }], propDecorators: { cardData: [{
1937
1961
  type: Input
1938
1962
  }] } });
@@ -1987,12 +2011,12 @@ class PTChartComponent {
1987
2011
  this.initializeChart();
1988
2012
  }
1989
2013
  ngOnDestroy() {
1990
- if (this.chart) {
1991
- this.chart.destroy();
1992
- }
2014
+ this.destroyChart();
1993
2015
  }
1994
2016
  initializeChart() {
1995
- const canvas = document.querySelector('canvas');
2017
+ const canvas = this.canvasRef.nativeElement;
2018
+ // Destroy the existing chart instance if it already exists
2019
+ this.destroyChart();
1996
2020
  const config = {
1997
2021
  type: this.chartConfig.type,
1998
2022
  data: this.chartConfig.data,
@@ -2006,7 +2030,7 @@ class PTChartComponent {
2006
2030
  const percentage = ((value / total) * 100).toFixed(1) + '%';
2007
2031
  return percentage;
2008
2032
  },
2009
- color: '#000', // Color of the percentage text
2033
+ color: '#000',
2010
2034
  font: {
2011
2035
  weight: 'bold',
2012
2036
  },
@@ -2015,6 +2039,7 @@ class PTChartComponent {
2015
2039
  },
2016
2040
  },
2017
2041
  };
2042
+ // Create a new Chart instance
2018
2043
  this.chart = new Chart(canvas, config);
2019
2044
  }
2020
2045
  updateChart() {
@@ -2026,14 +2051,23 @@ class PTChartComponent {
2026
2051
  this.chart.update();
2027
2052
  }
2028
2053
  }
2054
+ destroyChart() {
2055
+ if (this.chart) {
2056
+ this.chart.destroy();
2057
+ this.chart = undefined;
2058
+ }
2059
+ }
2029
2060
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2030
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTChartComponent, selector: "pt-chart", inputs: { chartConfig: "chartConfig" }, ngImport: i0, template: "<div style=\"position: relative; height: 100%; width: 100%\">\n <canvas></canvas>\n</div>\n", styles: [""] }); }
2061
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTChartComponent, selector: "pt-chart", inputs: { chartConfig: "chartConfig" }, viewQueries: [{ propertyName: "canvasRef", first: true, predicate: ["chartCanvas"], descendants: true, static: true }], ngImport: i0, template: "<div style=\"position: relative; height: 100%; width: 100%\">\n <canvas #chartCanvas></canvas>\n</div>\n", styles: [""] }); }
2031
2062
  }
2032
2063
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTChartComponent, decorators: [{
2033
2064
  type: Component,
2034
- args: [{ selector: 'pt-chart', template: "<div style=\"position: relative; height: 100%; width: 100%\">\n <canvas></canvas>\n</div>\n" }]
2065
+ args: [{ selector: 'pt-chart', template: "<div style=\"position: relative; height: 100%; width: 100%\">\n <canvas #chartCanvas></canvas>\n</div>\n" }]
2035
2066
  }], ctorParameters: () => [], propDecorators: { chartConfig: [{
2036
2067
  type: Input
2068
+ }], canvasRef: [{
2069
+ type: ViewChild,
2070
+ args: ['chartCanvas', { static: true }]
2037
2071
  }] } });
2038
2072
 
2039
2073
  class PTChartModule {
@@ -2125,11 +2159,11 @@ class PTMenuComponent {
2125
2159
  }
2126
2160
  }
2127
2161
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2128
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTMenuComponent, selector: "pt-menu", inputs: { config: "config" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<div\n [ngClass]=\"{\n open: isOpen,\n 'menu-left': config.menuDirection === 'left',\n 'menu-right': config.menuDirection === 'right'\n }\"\n class=\"pt-menu\"\n>\n <i\n class=\"menu-icon\"\n (click)=\"toggleMenu()\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n ></i>\n <div class=\"menu-dropdown\" *ngIf=\"isOpen\">\n <div\n class=\"menu-item\"\n *ngFor=\"let item of config.menuItems\"\n (click)=\"item.action()\"\n >\n <i\n [ngClass]=\"getMenuItemIconClass(item)\"\n [ngStyle]=\"getMenuItemIconStyles(item)\"\n ></i>\n <span [ngStyle]=\"getTextStyles(item)\">{{ item.text }}</span>\n </div>\n </div>\n</div>\n", styles: [".pt-menu{position:relative;display:inline-block}.pt-menu .menu-icon{font-style:normal;font-weight:400;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;border-radius:50%;padding:8px;transition:background-color .2s,box-shadow .2s}.pt-menu .menu-icon:hover{background-color:#5959591a;box-shadow:0 0 0 1px #5959591a}.pt-menu .menu-dropdown{display:none;position:absolute;background-color:#fff;box-shadow:0 8px 16px #0003;min-width:160px;z-index:1;border-radius:5px;overflow:hidden}.pt-menu .menu-item{padding:8px 16px;cursor:pointer;display:flex;align-items:center}.pt-menu .menu-item i{margin-right:10px}.pt-menu .menu-item:hover{background-color:#f1f1f1}.pt-menu.open .menu-dropdown{display:block}.pt-menu.menu-left .menu-dropdown{right:0;left:auto}.pt-menu.menu-right .menu-dropdown{left:0;right:auto}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
2162
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTMenuComponent, selector: "pt-menu", inputs: { config: "config" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<div\n [ngClass]=\"{\n open: isOpen,\n 'menu-left': config.menuDirection === 'left',\n 'menu-right': config.menuDirection === 'right'\n }\"\n class=\"pt-menu\"\n>\n <i\n class=\"menu-icon\"\n (click)=\"toggleMenu()\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n ></i>\n <div class=\"menu-dropdown\" *ngIf=\"isOpen\">\n <div\n class=\"menu-item\"\n *ngFor=\"let item of config.menuItems\"\n (click)=\"item.action()\"\n >\n <i\n [ngClass]=\"getMenuItemIconClass(item)\"\n [ngStyle]=\"getMenuItemIconStyles(item)\"\n ></i>\n <span [ngStyle]=\"getTextStyles(item)\">{{ item.text }}</span>\n </div>\n </div>\n</div>\n", styles: [".pt-menu{position:relative;display:inline-block}.pt-menu .menu-icon{font-style:normal;font-weight:400;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;border-radius:50%;padding:8px;transition:background-color .2s,box-shadow .2s}.pt-menu .menu-icon:hover{background-color:#5959591a;box-shadow:0 0 0 1px #5959591a}.pt-menu .menu-dropdown{display:none;position:absolute;background-color:#fff;box-shadow:0 8px 16px #0003;min-width:160px;z-index:1;border-radius:5px;overflow:hidden}.pt-menu .menu-item{padding:8px 16px;cursor:pointer;display:flex;align-items:center}.pt-menu .menu-item i{margin-right:10px}.pt-menu .menu-item:hover{background-color:#f1f1f1}.pt-menu.open .menu-dropdown{display:block}.pt-menu.menu-left .menu-dropdown{right:0;left:auto;z-index:2}.pt-menu.menu-right .menu-dropdown{left:0;right:auto;z-index:2}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
2129
2163
  }
2130
2164
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTMenuComponent, decorators: [{
2131
2165
  type: Component,
2132
- args: [{ selector: 'pt-menu', template: "<div\n [ngClass]=\"{\n open: isOpen,\n 'menu-left': config.menuDirection === 'left',\n 'menu-right': config.menuDirection === 'right'\n }\"\n class=\"pt-menu\"\n>\n <i\n class=\"menu-icon\"\n (click)=\"toggleMenu()\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n ></i>\n <div class=\"menu-dropdown\" *ngIf=\"isOpen\">\n <div\n class=\"menu-item\"\n *ngFor=\"let item of config.menuItems\"\n (click)=\"item.action()\"\n >\n <i\n [ngClass]=\"getMenuItemIconClass(item)\"\n [ngStyle]=\"getMenuItemIconStyles(item)\"\n ></i>\n <span [ngStyle]=\"getTextStyles(item)\">{{ item.text }}</span>\n </div>\n </div>\n</div>\n", styles: [".pt-menu{position:relative;display:inline-block}.pt-menu .menu-icon{font-style:normal;font-weight:400;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;border-radius:50%;padding:8px;transition:background-color .2s,box-shadow .2s}.pt-menu .menu-icon:hover{background-color:#5959591a;box-shadow:0 0 0 1px #5959591a}.pt-menu .menu-dropdown{display:none;position:absolute;background-color:#fff;box-shadow:0 8px 16px #0003;min-width:160px;z-index:1;border-radius:5px;overflow:hidden}.pt-menu .menu-item{padding:8px 16px;cursor:pointer;display:flex;align-items:center}.pt-menu .menu-item i{margin-right:10px}.pt-menu .menu-item:hover{background-color:#f1f1f1}.pt-menu.open .menu-dropdown{display:block}.pt-menu.menu-left .menu-dropdown{right:0;left:auto}.pt-menu.menu-right .menu-dropdown{left:0;right:auto}\n"] }]
2166
+ args: [{ selector: 'pt-menu', template: "<div\n [ngClass]=\"{\n open: isOpen,\n 'menu-left': config.menuDirection === 'left',\n 'menu-right': config.menuDirection === 'right'\n }\"\n class=\"pt-menu\"\n>\n <i\n class=\"menu-icon\"\n (click)=\"toggleMenu()\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n ></i>\n <div class=\"menu-dropdown\" *ngIf=\"isOpen\">\n <div\n class=\"menu-item\"\n *ngFor=\"let item of config.menuItems\"\n (click)=\"item.action()\"\n >\n <i\n [ngClass]=\"getMenuItemIconClass(item)\"\n [ngStyle]=\"getMenuItemIconStyles(item)\"\n ></i>\n <span [ngStyle]=\"getTextStyles(item)\">{{ item.text }}</span>\n </div>\n </div>\n</div>\n", styles: [".pt-menu{position:relative;display:inline-block}.pt-menu .menu-icon{font-style:normal;font-weight:400;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;border-radius:50%;padding:8px;transition:background-color .2s,box-shadow .2s}.pt-menu .menu-icon:hover{background-color:#5959591a;box-shadow:0 0 0 1px #5959591a}.pt-menu .menu-dropdown{display:none;position:absolute;background-color:#fff;box-shadow:0 8px 16px #0003;min-width:160px;z-index:1;border-radius:5px;overflow:hidden}.pt-menu .menu-item{padding:8px 16px;cursor:pointer;display:flex;align-items:center}.pt-menu .menu-item i{margin-right:10px}.pt-menu .menu-item:hover{background-color:#f1f1f1}.pt-menu.open .menu-dropdown{display:block}.pt-menu.menu-left .menu-dropdown{right:0;left:auto;z-index:2}.pt-menu.menu-right .menu-dropdown{left:0;right:auto;z-index:2}\n"] }]
2133
2167
  }], propDecorators: { config: [{
2134
2168
  type: Input
2135
2169
  }], onDocumentClick: [{
@@ -2154,6 +2188,14 @@ class PTCardComponent {
2154
2188
  static { this.DEFAULT_TRANSPARENCY = '100'; }
2155
2189
  static { this.DEFAULT_PADDING = '16px'; }
2156
2190
  static { this.DEFAULT_MARGIN = '16px 0'; }
2191
+ ngAfterViewInit() {
2192
+ this.logPatternUrl();
2193
+ }
2194
+ logPatternUrl() {
2195
+ if (this.config.pattern?.imageUrl) {
2196
+ console.log(`[PTCardComponent] Identifier: ${this.config.identifier}, Pattern URL: ${this.config.pattern.imageUrl}`);
2197
+ }
2198
+ }
2157
2199
  isTitleObject() {
2158
2200
  return typeof this.config.title === 'object';
2159
2201
  }
@@ -2217,13 +2259,25 @@ class PTCardComponent {
2217
2259
  getCardStyles() {
2218
2260
  const transparency = this.config.pattern?.transparencyPercentage
2219
2261
  ? parseFloat(this.config.pattern.transparencyPercentage) / 100
2220
- : 1; // Default to no transparency (1 = fully opaque)
2262
+ : 1;
2263
+ const imageUrl = this.config.pattern?.imageUrl || '';
2264
+ const backgroundColor = this.config.pattern?.backgroundColor ||
2265
+ PTCardComponent.DEFAULT_BACKGROUND_COLOR;
2266
+ const patternWidth = this.config.pattern?.width || '100%';
2267
+ const patternHeight = this.config.pattern?.height || 'auto';
2268
+ // Determine background-repeat value
2269
+ const repeatX = this.config.pattern?.repeatX ? 'repeat' : 'no-repeat';
2270
+ const repeatY = this.config.pattern?.repeatY ? 'repeat' : 'no-repeat';
2271
+ const backgroundRepeat = `${repeatX} ${repeatY}`;
2272
+ // Adjust background-size based on repeatCount if provided
2273
+ const repeatCount = this.config.pattern?.repeatCount || 1;
2274
+ const backgroundSize = repeatCount > 1
2275
+ ? `${patternWidth} ${patternHeight}`
2276
+ : `${patternWidth} ${patternHeight}`;
2277
+ // Determine background-position based on the position parameter
2278
+ const backgroundPosition = this.config.pattern?.position || 'center';
2221
2279
  return {
2222
- backgroundColor: this.config.pattern?.imageUrl
2223
- ? this.config.pattern.backgroundColor ||
2224
- PTCardComponent.DEFAULT_BACKGROUND_COLOR
2225
- : this.config.backgroundColor ||
2226
- PTCardComponent.DEFAULT_BACKGROUND_COLOR,
2280
+ backgroundColor,
2227
2281
  width: this.config.width || PTCardComponent.DEFAULT_WIDTH,
2228
2282
  height: this.config.height || PTCardComponent.DEFAULT_HEIGHT,
2229
2283
  border: this.config.noBorder
@@ -2233,12 +2287,11 @@ class PTCardComponent {
2233
2287
  margin: this.config.margin || PTCardComponent.DEFAULT_MARGIN,
2234
2288
  borderRadius: this.config.borderRadius || '8px',
2235
2289
  boxShadow: this.config.boxShadow || '0 2px 4px rgba(0, 0, 0, 0.1)',
2236
- position: 'relative', // Needed for ::before positioning
2237
- '--background-image-url': this.config.pattern?.imageUrl
2238
- ? `url(${this.config.pattern.imageUrl})`
2239
- : '',
2240
- '--image-opacity': transparency.toString(), // Pass transparency to CSS
2241
- overflow: 'hidden', // Ensure no overflow
2290
+ position: 'relative',
2291
+ backgroundImage: imageUrl ? `url(${imageUrl})` : 'none',
2292
+ backgroundSize,
2293
+ backgroundPosition,
2294
+ backgroundRepeat,
2242
2295
  };
2243
2296
  }
2244
2297
  isScrollableHorizontal() {
@@ -2248,11 +2301,11 @@ class PTCardComponent {
2248
2301
  return !!this.config.scrollableVertical;
2249
2302
  }
2250
2303
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTCardComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
2251
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTCardComponent, selector: "pt-card", inputs: { config: "config" }, ngImport: i0, template: "<div class=\"pt-card card\" [ngStyle]=\"getCardStyles()\">\n <div *ngIf=\"hasTitle()\" class=\"card-header\" [ngStyle]=\"getTitleStyles()\">\n <i\n *ngIf=\"getIconClass() && getIconPosition() === 'left'\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n class=\"card-header-icon-left\"\n ></i>\n <span>{{ getTitleText() }}</span>\n <i\n *ngIf=\"getIconClass() && getIconPosition() === 'right'\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n class=\"card-header-icon-right\"\n ></i>\n <pt-menu\n *ngIf=\"config.menu\"\n [config]=\"config.menu\"\n [ngClass]=\"{\n 'menu-left': getMenuPosition() === 'left',\n 'menu-right': getMenuPosition() === 'right'\n }\"\n ></pt-menu>\n </div>\n <div\n class=\"card-body\"\n [ngClass]=\"{\n 'card-body-scrollable-vertical': isScrollableVertical(),\n 'card-body-scrollable-horizontal': isScrollableHorizontal()\n }\"\n >\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [".pt-card .card{padding:16px;margin:16px 0;display:flex;flex-direction:column;max-height:100vh;overflow:hidden;background-color:var(--background-color, #fff);position:relative}.pt-card .card:after{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;background-image:var( --background-image-url );background-size:cover;background-position:center;opacity:var(--image-opacity, 1);pointer-events:none}.pt-card .card-body{flex-grow:1;max-width:100%;z-index:1}.pt-card .card-body-scrollable-horizontal{overflow-x:auto;padding-bottom:8px}.pt-card .card-body-scrollable-vertical{flex-grow:1;overflow-y:auto;padding-right:8px}.pt-card .card-header{margin-bottom:16px;display:flex;align-items:center;justify-content:var(--text-align, left);position:relative}.pt-card .card-header-icon-left{margin-right:6px}.pt-card .card-header-icon-right{margin-left:6px}.pt-card .menu-left{position:absolute;left:0;top:0}.pt-card .menu-right{position:absolute;right:0;top:-2px}.pt-card .card-menu{margin-left:auto;cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: PTMenuComponent, selector: "pt-menu", inputs: ["config"] }] }); }
2304
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTCardComponent, selector: "pt-card", inputs: { config: "config" }, ngImport: i0, template: "<div\n class=\"pt-card card\"\n [attr.id]=\"config.identifier\"\n [ngStyle]=\"getCardStyles()\"\n>\n <div *ngIf=\"hasTitle()\" class=\"card-header\" [ngStyle]=\"getTitleStyles()\">\n <i\n *ngIf=\"getIconClass() && getIconPosition() === 'left'\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n class=\"card-header-icon-left\"\n ></i>\n <span>{{ getTitleText() }}</span>\n <i\n *ngIf=\"getIconClass() && getIconPosition() === 'right'\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n class=\"card-header-icon-right\"\n ></i>\n <pt-menu\n *ngIf=\"config.menu\"\n [config]=\"config.menu\"\n [ngClass]=\"{\n 'menu-left': getMenuPosition() === 'left',\n 'menu-right': getMenuPosition() === 'right'\n }\"\n ></pt-menu>\n </div>\n <div\n class=\"card-body\"\n [ngClass]=\"{\n 'card-body-scrollable-vertical': isScrollableVertical(),\n 'card-body-scrollable-horizontal': isScrollableHorizontal()\n }\"\n >\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [".pt-card .card{padding:16px;margin:16px 0;display:flex;flex-direction:column;max-height:100vh;overflow:hidden;position:relative}.pt-card .card:after{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;background-size:cover;background-position:center;pointer-events:none}.pt-card .card-body{flex-grow:1;max-width:100%;z-index:1}.pt-card .card-body-scrollable-horizontal{overflow-x:auto;padding-bottom:8px}.pt-card .card-body-scrollable-vertical{flex-grow:1;overflow-y:auto;padding-right:8px}.pt-card .card-header{margin-bottom:16px;display:flex;align-items:center;justify-content:var(--text-align, left);position:relative}.pt-card .card-header-icon-left{margin-right:6px}.pt-card .card-header-icon-right{margin-left:6px}.pt-card .menu-left{position:absolute;left:0;top:0}.pt-card .menu-right{position:absolute;right:0;top:-2px}.pt-card .card-menu{margin-left:auto;cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: PTMenuComponent, selector: "pt-menu", inputs: ["config"] }] }); }
2252
2305
  }
2253
2306
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTCardComponent, decorators: [{
2254
2307
  type: Component,
2255
- args: [{ selector: 'pt-card', template: "<div class=\"pt-card card\" [ngStyle]=\"getCardStyles()\">\n <div *ngIf=\"hasTitle()\" class=\"card-header\" [ngStyle]=\"getTitleStyles()\">\n <i\n *ngIf=\"getIconClass() && getIconPosition() === 'left'\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n class=\"card-header-icon-left\"\n ></i>\n <span>{{ getTitleText() }}</span>\n <i\n *ngIf=\"getIconClass() && getIconPosition() === 'right'\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n class=\"card-header-icon-right\"\n ></i>\n <pt-menu\n *ngIf=\"config.menu\"\n [config]=\"config.menu\"\n [ngClass]=\"{\n 'menu-left': getMenuPosition() === 'left',\n 'menu-right': getMenuPosition() === 'right'\n }\"\n ></pt-menu>\n </div>\n <div\n class=\"card-body\"\n [ngClass]=\"{\n 'card-body-scrollable-vertical': isScrollableVertical(),\n 'card-body-scrollable-horizontal': isScrollableHorizontal()\n }\"\n >\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [".pt-card .card{padding:16px;margin:16px 0;display:flex;flex-direction:column;max-height:100vh;overflow:hidden;background-color:var(--background-color, #fff);position:relative}.pt-card .card:after{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;background-image:var( --background-image-url );background-size:cover;background-position:center;opacity:var(--image-opacity, 1);pointer-events:none}.pt-card .card-body{flex-grow:1;max-width:100%;z-index:1}.pt-card .card-body-scrollable-horizontal{overflow-x:auto;padding-bottom:8px}.pt-card .card-body-scrollable-vertical{flex-grow:1;overflow-y:auto;padding-right:8px}.pt-card .card-header{margin-bottom:16px;display:flex;align-items:center;justify-content:var(--text-align, left);position:relative}.pt-card .card-header-icon-left{margin-right:6px}.pt-card .card-header-icon-right{margin-left:6px}.pt-card .menu-left{position:absolute;left:0;top:0}.pt-card .menu-right{position:absolute;right:0;top:-2px}.pt-card .card-menu{margin-left:auto;cursor:pointer}\n"] }]
2308
+ args: [{ selector: 'pt-card', template: "<div\n class=\"pt-card card\"\n [attr.id]=\"config.identifier\"\n [ngStyle]=\"getCardStyles()\"\n>\n <div *ngIf=\"hasTitle()\" class=\"card-header\" [ngStyle]=\"getTitleStyles()\">\n <i\n *ngIf=\"getIconClass() && getIconPosition() === 'left'\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n class=\"card-header-icon-left\"\n ></i>\n <span>{{ getTitleText() }}</span>\n <i\n *ngIf=\"getIconClass() && getIconPosition() === 'right'\"\n [ngClass]=\"getIconClass()\"\n [ngStyle]=\"getIconStyles()\"\n class=\"card-header-icon-right\"\n ></i>\n <pt-menu\n *ngIf=\"config.menu\"\n [config]=\"config.menu\"\n [ngClass]=\"{\n 'menu-left': getMenuPosition() === 'left',\n 'menu-right': getMenuPosition() === 'right'\n }\"\n ></pt-menu>\n </div>\n <div\n class=\"card-body\"\n [ngClass]=\"{\n 'card-body-scrollable-vertical': isScrollableVertical(),\n 'card-body-scrollable-horizontal': isScrollableHorizontal()\n }\"\n >\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [".pt-card .card{padding:16px;margin:16px 0;display:flex;flex-direction:column;max-height:100vh;overflow:hidden;position:relative}.pt-card .card:after{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;background-size:cover;background-position:center;pointer-events:none}.pt-card .card-body{flex-grow:1;max-width:100%;z-index:1}.pt-card .card-body-scrollable-horizontal{overflow-x:auto;padding-bottom:8px}.pt-card .card-body-scrollable-vertical{flex-grow:1;overflow-y:auto;padding-right:8px}.pt-card .card-header{margin-bottom:16px;display:flex;align-items:center;justify-content:var(--text-align, left);position:relative}.pt-card .card-header-icon-left{margin-right:6px}.pt-card .card-header-icon-right{margin-left:6px}.pt-card .menu-left{position:absolute;left:0;top:0}.pt-card .menu-right{position:absolute;right:0;top:-2px}.pt-card .card-menu{margin-left:auto;cursor:pointer}\n"] }]
2256
2309
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { config: [{
2257
2310
  type: Input
2258
2311
  }] } });
@@ -2291,7 +2344,7 @@ class PTMenuFancyComponent {
2291
2344
  icon: { code: 'pi pi-ellipsis-v', color: '#000', fontSize: '15px' },
2292
2345
  menuDirection: 'right',
2293
2346
  };
2294
- this.cardMenuConfig = { noBorder: true };
2347
+ this.cardMenuConfig = { noBorder: true, margin: '0', padding: '5px' };
2295
2348
  this.isOpen = false;
2296
2349
  }
2297
2350
  static { this.DEFAULT_TEXT_COLOR = '#000'; }
@@ -2388,6 +2441,8 @@ class PTNavbarMenuComponent {
2388
2441
  static { this.DEFAULT_APP_NAME_FONT_SIZE = '24px'; }
2389
2442
  static { this.DEFAULT_TRANSPARENCY = '100'; }
2390
2443
  static { this.DEFAULT_ICON_COLOR = '#333'; }
2444
+ static { this.DEFAULT_TOGGLE_BUTTON_ICON = 'pi pi-bars'; }
2445
+ static { this.DEFAULT_TOGGLE_BUTTON_COLOR = '#333'; }
2391
2446
  isImageStyle(object) {
2392
2447
  return typeof object === 'object' && 'imageUrl' in object;
2393
2448
  }
@@ -2440,25 +2495,50 @@ class PTNavbarMenuComponent {
2440
2495
  getNavbarStyles() {
2441
2496
  const transparency = this.navBarMenuConfig.pattern?.transparencyPercentage ||
2442
2497
  PTNavbarMenuComponent.DEFAULT_TRANSPARENCY;
2443
- const backgroundImage = this.navBarMenuConfig.pattern
2444
- ? `linear-gradient(rgba(255, 255, 255, ${1 - parseFloat(transparency) / 100}), rgba(255, 255, 255, ${1 - parseFloat(transparency) / 100})), url(${this.navBarMenuConfig.pattern.imageUrl})`
2498
+ const imageUrl = this.navBarMenuConfig.pattern?.imageUrl || '';
2499
+ const patternWidth = this.navBarMenuConfig.pattern?.width || '100%';
2500
+ const patternHeight = this.navBarMenuConfig.pattern?.height || 'auto';
2501
+ // Determine background-repeat value
2502
+ const repeatX = this.navBarMenuConfig.pattern?.repeatX
2503
+ ? 'repeat'
2504
+ : 'no-repeat';
2505
+ const repeatY = this.navBarMenuConfig.pattern?.repeatY
2506
+ ? 'repeat'
2507
+ : 'no-repeat';
2508
+ const backgroundRepeat = `${repeatX} ${repeatY}`;
2509
+ // Use the position directly from the pattern configuration
2510
+ const backgroundPosition = this.navBarMenuConfig.pattern?.position || 'center';
2511
+ // Construct the background image style with transparency
2512
+ const backgroundImage = imageUrl
2513
+ ? `linear-gradient(rgba(255, 255, 255, ${1 - parseFloat(transparency) / 100}), rgba(255, 255, 255, ${1 - parseFloat(transparency) / 100})), url(${imageUrl})`
2445
2514
  : '';
2446
2515
  return {
2447
2516
  backgroundColor: this.navBarMenuConfig.pattern ? 'transparent' : '#fff',
2448
2517
  backgroundImage: backgroundImage,
2449
- backgroundSize: 'cover',
2450
- backgroundPosition: 'center',
2518
+ backgroundSize: `${patternWidth} ${patternHeight}`,
2519
+ backgroundPosition: backgroundPosition,
2520
+ backgroundRepeat: backgroundRepeat,
2451
2521
  };
2452
2522
  }
2453
2523
  toggleMenu() {
2454
2524
  this.toggleSidebar.emit();
2455
2525
  }
2526
+ getToggleButtonIcon() {
2527
+ return (this.navBarMenuConfig.toggleButtonIcon ||
2528
+ PTNavbarMenuComponent.DEFAULT_TOGGLE_BUTTON_ICON);
2529
+ }
2530
+ getToggleButtonStyles() {
2531
+ return {
2532
+ color: this.navBarMenuConfig.toggleButtonColor ||
2533
+ PTNavbarMenuComponent.DEFAULT_TOGGLE_BUTTON_COLOR,
2534
+ };
2535
+ }
2456
2536
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTNavbarMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2457
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTNavbarMenuComponent, selector: "pt-nav-bar-menu", inputs: { navBarMenuConfig: "navBarMenuConfig" }, outputs: { toggleSidebar: "toggleSidebar" }, ngImport: i0, template: "<div class=\"pt-nav-bar-menu\" [ngStyle]=\"getNavbarStyles()\">\n <div class=\"navbar-left\">\n <a\n [routerLink]=\"\n isImageStyle(navBarMenuConfig.logo)\n ? navBarMenuConfig.logo.routerLink\n : '/'\n \"\n class=\"logo-link\"\n >\n <img\n [src]=\"getLogoUrl()\"\n [alt]=\"getLogoAltText()\"\n [ngStyle]=\"getLogoStyles()\"\n class=\"navbar-logo\"\n />\n <span class=\"navbar-title\" [ngStyle]=\"getAppNameStyles()\">\n {{ getAppName() }}\n </span>\n </a>\n <a (click)=\"toggleMenu()\" class=\"toggle-btn\">\n <i class=\"pi pi-bars\"></i>\n </a>\n </div>\n <div class=\"navbar-right\">\n <pt-menu-fancy\n *ngFor=\"let menuConfig of navBarMenuConfig.menus\"\n [config]=\"menuConfig\"\n ></pt-menu-fancy>\n </div>\n</div>\n", styles: [".pt-nav-bar-menu{display:flex;justify-content:space-between;align-items:center;padding:10px;border-bottom:1px solid #ddd;background-color:#fff;background-size:cover;background-position:center}.pt-nav-bar-menu .navbar-left{display:flex;align-items:center}.pt-nav-bar-menu .logo-link{display:flex;align-items:center;text-decoration:none;color:inherit}.pt-nav-bar-menu .navbar-logo{margin-left:10px;margin-right:20px}.pt-nav-bar-menu .navbar-right{display:flex;align-items:center}.pt-nav-bar-menu .navbar-right a{margin-left:20px;color:#333;text-decoration:none;font-size:20px;cursor:pointer}.pt-nav-bar-menu .navbar-right a:hover{color:#000;cursor:pointer}.pt-nav-bar-menu .toggle-btn>.pi.pi-bars{font-size:1.5rem;color:#333}.pt-nav-bar-menu .toggle-btn:hover{background-color:#f1f1f1}.pt-nav-bar-menu .toggle-btn{margin-left:2rem;cursor:pointer;padding:7px}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: PTMenuFancyComponent, selector: "pt-menu-fancy", inputs: ["config"] }] }); }
2537
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.11", type: PTNavbarMenuComponent, selector: "pt-nav-bar-menu", inputs: { navBarMenuConfig: "navBarMenuConfig" }, outputs: { toggleSidebar: "toggleSidebar" }, ngImport: i0, template: "<div class=\"pt-nav-bar-menu\" [ngStyle]=\"getNavbarStyles()\">\n <div class=\"navbar-left\">\n <a\n [routerLink]=\"\n isImageStyle(navBarMenuConfig.logo)\n ? navBarMenuConfig.logo.routerLink\n : '/'\n \"\n class=\"logo-link\"\n >\n <img\n [src]=\"getLogoUrl()\"\n [alt]=\"getLogoAltText()\"\n [ngStyle]=\"getLogoStyles()\"\n class=\"navbar-logo\"\n />\n <span class=\"navbar-title\" [ngStyle]=\"getAppNameStyles()\">\n {{ getAppName() }}\n </span>\n </a>\n <!-- Toggle Button -->\n <a (click)=\"toggleMenu()\" class=\"toggle-btn\">\n <i\n [class]=\"getToggleButtonIcon()\"\n [ngStyle]=\"getToggleButtonStyles()\"\n ></i>\n </a>\n </div>\n <div class=\"navbar-right\">\n <pt-menu-fancy\n *ngFor=\"let menuConfig of navBarMenuConfig.menus\"\n [config]=\"menuConfig\"\n ></pt-menu-fancy>\n </div>\n</div>\n", styles: [".pt-nav-bar-menu{display:flex;justify-content:space-between;align-items:center;padding:10px;border-bottom:1px solid #ddd;background-color:#fff;background-size:cover;background-position:center}.pt-nav-bar-menu .navbar-left{display:flex;align-items:center}.pt-nav-bar-menu .logo-link{display:flex;align-items:center;text-decoration:none;color:inherit}.pt-nav-bar-menu .navbar-logo{margin-left:10px;margin-right:20px}.pt-nav-bar-menu .navbar-right{display:flex;align-items:center}.pt-nav-bar-menu .navbar-right a{margin-left:20px;color:#333;text-decoration:none;font-size:20px;cursor:pointer}.pt-nav-bar-menu .navbar-right a:hover{color:#000;cursor:pointer}.pt-nav-bar-menu .toggle-btn>.pi.pi-bars{font-size:1.5rem;color:#333}.pt-nav-bar-menu .toggle-btn:hover{background-color:#f1f1f1}.pt-nav-bar-menu .toggle-btn{margin-left:2rem;cursor:pointer;padding:7px}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2$2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: PTMenuFancyComponent, selector: "pt-menu-fancy", inputs: ["config"] }] }); }
2458
2538
  }
2459
2539
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PTNavbarMenuComponent, decorators: [{
2460
2540
  type: Component,
2461
- args: [{ selector: 'pt-nav-bar-menu', template: "<div class=\"pt-nav-bar-menu\" [ngStyle]=\"getNavbarStyles()\">\n <div class=\"navbar-left\">\n <a\n [routerLink]=\"\n isImageStyle(navBarMenuConfig.logo)\n ? navBarMenuConfig.logo.routerLink\n : '/'\n \"\n class=\"logo-link\"\n >\n <img\n [src]=\"getLogoUrl()\"\n [alt]=\"getLogoAltText()\"\n [ngStyle]=\"getLogoStyles()\"\n class=\"navbar-logo\"\n />\n <span class=\"navbar-title\" [ngStyle]=\"getAppNameStyles()\">\n {{ getAppName() }}\n </span>\n </a>\n <a (click)=\"toggleMenu()\" class=\"toggle-btn\">\n <i class=\"pi pi-bars\"></i>\n </a>\n </div>\n <div class=\"navbar-right\">\n <pt-menu-fancy\n *ngFor=\"let menuConfig of navBarMenuConfig.menus\"\n [config]=\"menuConfig\"\n ></pt-menu-fancy>\n </div>\n</div>\n", styles: [".pt-nav-bar-menu{display:flex;justify-content:space-between;align-items:center;padding:10px;border-bottom:1px solid #ddd;background-color:#fff;background-size:cover;background-position:center}.pt-nav-bar-menu .navbar-left{display:flex;align-items:center}.pt-nav-bar-menu .logo-link{display:flex;align-items:center;text-decoration:none;color:inherit}.pt-nav-bar-menu .navbar-logo{margin-left:10px;margin-right:20px}.pt-nav-bar-menu .navbar-right{display:flex;align-items:center}.pt-nav-bar-menu .navbar-right a{margin-left:20px;color:#333;text-decoration:none;font-size:20px;cursor:pointer}.pt-nav-bar-menu .navbar-right a:hover{color:#000;cursor:pointer}.pt-nav-bar-menu .toggle-btn>.pi.pi-bars{font-size:1.5rem;color:#333}.pt-nav-bar-menu .toggle-btn:hover{background-color:#f1f1f1}.pt-nav-bar-menu .toggle-btn{margin-left:2rem;cursor:pointer;padding:7px}\n"] }]
2541
+ args: [{ selector: 'pt-nav-bar-menu', template: "<div class=\"pt-nav-bar-menu\" [ngStyle]=\"getNavbarStyles()\">\n <div class=\"navbar-left\">\n <a\n [routerLink]=\"\n isImageStyle(navBarMenuConfig.logo)\n ? navBarMenuConfig.logo.routerLink\n : '/'\n \"\n class=\"logo-link\"\n >\n <img\n [src]=\"getLogoUrl()\"\n [alt]=\"getLogoAltText()\"\n [ngStyle]=\"getLogoStyles()\"\n class=\"navbar-logo\"\n />\n <span class=\"navbar-title\" [ngStyle]=\"getAppNameStyles()\">\n {{ getAppName() }}\n </span>\n </a>\n <!-- Toggle Button -->\n <a (click)=\"toggleMenu()\" class=\"toggle-btn\">\n <i\n [class]=\"getToggleButtonIcon()\"\n [ngStyle]=\"getToggleButtonStyles()\"\n ></i>\n </a>\n </div>\n <div class=\"navbar-right\">\n <pt-menu-fancy\n *ngFor=\"let menuConfig of navBarMenuConfig.menus\"\n [config]=\"menuConfig\"\n ></pt-menu-fancy>\n </div>\n</div>\n", styles: [".pt-nav-bar-menu{display:flex;justify-content:space-between;align-items:center;padding:10px;border-bottom:1px solid #ddd;background-color:#fff;background-size:cover;background-position:center}.pt-nav-bar-menu .navbar-left{display:flex;align-items:center}.pt-nav-bar-menu .logo-link{display:flex;align-items:center;text-decoration:none;color:inherit}.pt-nav-bar-menu .navbar-logo{margin-left:10px;margin-right:20px}.pt-nav-bar-menu .navbar-right{display:flex;align-items:center}.pt-nav-bar-menu .navbar-right a{margin-left:20px;color:#333;text-decoration:none;font-size:20px;cursor:pointer}.pt-nav-bar-menu .navbar-right a:hover{color:#000;cursor:pointer}.pt-nav-bar-menu .toggle-btn>.pi.pi-bars{font-size:1.5rem;color:#333}.pt-nav-bar-menu .toggle-btn:hover{background-color:#f1f1f1}.pt-nav-bar-menu .toggle-btn{margin-left:2rem;cursor:pointer;padding:7px}\n"] }]
2462
2542
  }], propDecorators: { navBarMenuConfig: [{
2463
2543
  type: Input
2464
2544
  }], toggleSidebar: [{
@@ -2511,10 +2591,12 @@ class PTSideBarMenuComponent {
2511
2591
  hoverColorSubMenu: '#e0e0e0', // Default hover color for submenu
2512
2592
  };
2513
2593
  this.searchCardConfig = {
2594
+ identifier: 'pt-side-bar-menu/search',
2514
2595
  backgroundColor: 'white',
2515
2596
  height: '72px',
2516
2597
  };
2517
2598
  this.cardConfig = {
2599
+ identifier: 'pt-side-bar-menu',
2518
2600
  backgroundColor: '',
2519
2601
  width: '',
2520
2602
  height: '',
@@ -2532,6 +2614,7 @@ class PTSideBarMenuComponent {
2532
2614
  }
2533
2615
  ngOnInit() {
2534
2616
  this.cardConfig = {
2617
+ identifier: 'pt-side-bar-menu',
2535
2618
  backgroundColor: this.menuConfig.backgroundColor,
2536
2619
  width: this.menuConfig.width,
2537
2620
  height: this.menuConfig.height,
@@ -2890,6 +2973,7 @@ class PTPageSkeletonComponent {
2890
2973
  // Initialize backgroundCardConfig with default values
2891
2974
  initializeBackgroundCardConfig() {
2892
2975
  this.pageSkeletonConfig.backgroundCardConfig = {
2976
+ identifier: 'pt-page-skeleton/background',
2893
2977
  noBorder: this.pageSkeletonConfig.backgroundCardConfig?.noBorder ?? true,
2894
2978
  backgroundColor: this.pageSkeletonConfig.backgroundCardConfig?.backgroundColor || '#fff',
2895
2979
  padding: this.pageSkeletonConfig.backgroundCardConfig?.padding || '20px',
@@ -2900,6 +2984,7 @@ class PTPageSkeletonComponent {
2900
2984
  // Initialize contentCardConfig with default values (if necessary)
2901
2985
  initializeContentCardConfig() {
2902
2986
  this.pageSkeletonConfig.contentCardConfig = {
2987
+ identifier: 'pt-page-skeleton/content',
2903
2988
  noBorder: this.pageSkeletonConfig.contentCardConfig?.noBorder ?? false,
2904
2989
  backgroundColor: this.pageSkeletonConfig.contentCardConfig?.backgroundColor || '#f0f0f0',
2905
2990
  padding: this.pageSkeletonConfig.contentCardConfig?.padding || '15px',