@c80/ui 1.0.52 → 1.0.54

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 (50) hide show
  1. package/esm2022/lib/card-level/card-level.component.js +4 -3
  2. package/esm2022/lib/card-level/card-level.component.js.map +1 -1
  3. package/esm2022/lib/icon/icon.component.js +30 -10
  4. package/esm2022/lib/icon/icon.component.js.map +1 -1
  5. package/esm2022/lib/icon/icon.constants.js +7 -293
  6. package/esm2022/lib/icon/icon.constants.js.map +1 -1
  7. package/esm2022/lib/icon/icon.definitions.js +379 -0
  8. package/esm2022/lib/icon/icon.definitions.js.map +1 -0
  9. package/esm2022/lib/icon/icon.types.js.map +1 -1
  10. package/esm2022/lib/icon/icon.utils.js +14 -0
  11. package/esm2022/lib/icon/icon.utils.js.map +1 -1
  12. package/esm2022/lib/modal/modal.component.js +4 -3
  13. package/esm2022/lib/modal/modal.component.js.map +1 -1
  14. package/esm2022/lib/modal/modal.service.js +3 -3
  15. package/esm2022/lib/modal/modal.service.js.map +1 -1
  16. package/esm2022/lib/select/select.component.js +14 -3
  17. package/esm2022/lib/select/select.component.js.map +1 -1
  18. package/esm2022/lib/snackbar/index.js +1 -0
  19. package/esm2022/lib/snackbar/index.js.map +1 -1
  20. package/esm2022/lib/snackbar/snackbar.component.js +6 -4
  21. package/esm2022/lib/snackbar/snackbar.component.js.map +1 -1
  22. package/esm2022/lib/snackbar/snackbar.service.js +3 -3
  23. package/esm2022/lib/snackbar/snackbar.service.js.map +1 -1
  24. package/esm2022/lib/stat-card/stat-card.component.js +4 -3
  25. package/esm2022/lib/stat-card/stat-card.component.js.map +1 -1
  26. package/esm2022/lib/tab/c80-tab-item.directive.js +3 -3
  27. package/esm2022/lib/tab/c80-tab-item.directive.js.map +1 -1
  28. package/esm2022/lib/tab/c80-tab-label.directive.js +3 -3
  29. package/esm2022/lib/tab/c80-tab-label.directive.js.map +1 -1
  30. package/esm2022/lib/tab/c80-tab.component.js +5 -4
  31. package/esm2022/lib/tab/c80-tab.component.js.map +1 -1
  32. package/esm2022/lib/table/table-column-visibility.service.js +3 -3
  33. package/esm2022/lib/table/table-column-visibility.service.js.map +1 -1
  34. package/esm2022/lib/table/table-crud-state.service.js +3 -3
  35. package/esm2022/lib/table/table-crud-state.service.js.map +1 -1
  36. package/esm2022/lib/table/table-data-converter.service.js +3 -3
  37. package/esm2022/lib/table/table-data-converter.service.js.map +1 -1
  38. package/esm2022/lib/table/table-data-utils.service.js +3 -3
  39. package/esm2022/lib/table/table-data-utils.service.js.map +1 -1
  40. package/esm2022/lib/table/table-selection.service.js +3 -3
  41. package/esm2022/lib/table/table-selection.service.js.map +1 -1
  42. package/esm2022/lib/table/table.component.js +3 -3
  43. package/esm2022/lib/table/table.component.js.map +1 -1
  44. package/lib/icon/icon.component.d.ts +10 -1
  45. package/lib/icon/icon.constants.d.ts +7 -14
  46. package/lib/icon/icon.definitions.d.ts +16 -0
  47. package/lib/icon/icon.types.d.ts +40 -5
  48. package/lib/icon/icon.utils.d.ts +5 -0
  49. package/lib/snackbar/index.d.ts +1 -0
  50. package/package.json +1 -1
@@ -2,6 +2,7 @@ import { Component, input, computed, ChangeDetectionStrategy } from '@angular/co
2
2
  import * as i0 from "@angular/core";
3
3
  export class CardLevelComponent {
4
4
  cardLevelData = input.required(...(ngDevMode ? [{ debugName: "cardLevelData" }] : []));
5
+ /* v8 ignore next */
5
6
  size = input(1, ...(ngDevMode ? [{ debugName: "size" }] : [])); // Multiplicador del tamaño base (220px)
6
7
  // ID único generado para el componente
7
8
  generatedId = computed(() => {
@@ -44,10 +45,10 @@ export class CardLevelComponent {
44
45
  }
45
46
  return 'var(--color-success)';
46
47
  }, ...(ngDevMode ? [{ debugName: "fillColor" }] : []));
47
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CardLevelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
48
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: CardLevelComponent, isStandalone: true, selector: "c80-card-level", inputs: { cardLevelData: { classPropertyName: "cardLevelData", publicName: "cardLevelData", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!-- eslint-disable @angular-eslint/template/no-inline-styles -->\n<div class=\"card-level-container\" [style.width]=\"cardWidth()\">\n <label [for]=\"generatedId()\">\n <strong>{{ cardLevelData().label }}</strong>\n\n <span class=\"value-display\">\n @if (isBidirectional()) {\n <!-- Barra bidireccional desde el centro -->\n <div class=\"bidirectional-meter\">\n <div class=\"meter-track\">\n <div class=\"center-line\"></div>\n <div class=\"meter-fill\" [class.fill-left]=\"fillDirection() === 'left'\" [class.fill-right]=\"fillDirection() === 'right'\" [style.width.%]=\"bidirectionalFillPercent()\" [style.background]=\"fillColor()\">\n </div>\n </div>\n </div>\n } @else {\n <!-- Meter est\u00E1ndar para rangos unidireccionales -->\n <meter [id]=\"generatedId()\" [optimum]=\"cardLevelData().optimum\" [min]=\"cardLevelData().min\" [max]=\"cardLevelData().max\" [low]=\"cardLevelData().low\" [high]=\"cardLevelData().high\" [value]=\"cardLevelData().value\">\n </meter>\n }\n\n {{ cardLevelData().value }}{{ cardLevelData().unit }}\n </span>\n </label>\n</div>\n<!-- eslint-enable @angular-eslint/template/no-inline-styles -->", styles: [".card-level-container{background:#fff;border-radius:5px;padding:8px;margin:4px;box-shadow:0 4px 6px #0000001a,0 1px 3px #00000014;min-width:100px;flex:1}.card-level-container label{display:flex;flex-direction:column;margin:0}.card-level-container label strong{font-size:12px;font-weight:600;color:#2d3748;text-transform:uppercase;letter-spacing:.5px;margin-bottom:4px}.card-level-container label .value-display{font-size:12px;font-weight:600;color:#1a202c;text-align:center;padding:0 5px;background:#4299e11a;border-radius:5px}.card-level-container label .bidirectional-meter{width:100%;margin-bottom:4px}.card-level-container label .bidirectional-meter .meter-track{position:relative;width:100%;height:10px;background:#e2e8f0;border-radius:12px;box-shadow:inset 0 2px 4px #0000001a;overflow:hidden}.card-level-container label .bidirectional-meter .meter-track .center-line{position:absolute;left:50%;top:0;bottom:0;width:4px;background:#4a5568;transform:translate(-50%);z-index:1}.card-level-container label .bidirectional-meter .meter-track .meter-fill{position:absolute;top:0;bottom:0;border-radius:5px}.card-level-container label .bidirectional-meter .meter-track .meter-fill.fill-right{left:50%}.card-level-container label .bidirectional-meter .meter-track .meter-fill.fill-left{right:50%}.card-level-container label meter{width:100%;border-radius:12px;border:none;background:#e2e8f0;margin-bottom:4px}.card-level-container label meter::-webkit-meter-bar{background:#e2e8f0;border-radius:12px;box-shadow:inset 0 2px 4px #0000001a}.card-level-container label meter::-webkit-meter-optimum-value{background:linear-gradient(90deg,#48bb78,#38a169);border-radius:12px}.card-level-container label meter::-webkit-meter-suboptimum-value{background:linear-gradient(90deg,#ed8936,#dd6b20);border-radius:12px}.card-level-container label meter::-webkit-meter-even-less-good-value{background:linear-gradient(90deg,#f56565,#e53e3e);border-radius:12px}.card-level-container label meter::-moz-meter-bar{background:linear-gradient(90deg,#48bb78,#38a169);border-radius:12px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
48
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: CardLevelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
49
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: CardLevelComponent, isStandalone: true, selector: "c80-card-level", inputs: { cardLevelData: { classPropertyName: "cardLevelData", publicName: "cardLevelData", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<!-- eslint-disable @angular-eslint/template/no-inline-styles -->\n<div class=\"card-level-container\" [style.width]=\"cardWidth()\">\n <label [for]=\"generatedId()\">\n <strong>{{ cardLevelData().label }}</strong>\n\n <span class=\"value-display\">\n @if (isBidirectional()) {\n <!-- Barra bidireccional desde el centro -->\n <div class=\"bidirectional-meter\">\n <div class=\"meter-track\">\n <div class=\"center-line\"></div>\n <div class=\"meter-fill\" [class.fill-left]=\"fillDirection() === 'left'\" [class.fill-right]=\"fillDirection() === 'right'\" [style.width.%]=\"bidirectionalFillPercent()\" [style.background]=\"fillColor()\">\n </div>\n </div>\n </div>\n } @else {\n <!-- Meter est\u00E1ndar para rangos unidireccionales -->\n <meter [id]=\"generatedId()\" [optimum]=\"cardLevelData().optimum\" [min]=\"cardLevelData().min\" [max]=\"cardLevelData().max\" [low]=\"cardLevelData().low\" [high]=\"cardLevelData().high\" [value]=\"cardLevelData().value\">\n </meter>\n }\n\n {{ cardLevelData().value }}{{ cardLevelData().unit }}\n </span>\n </label>\n</div>\n<!-- eslint-enable @angular-eslint/template/no-inline-styles -->", styles: [".card-level-container{background:#fff;border-radius:5px;padding:8px;margin:4px;box-shadow:0 4px 6px #0000001a,0 1px 3px #00000014;min-width:100px;flex:1}.card-level-container label{display:flex;flex-direction:column;margin:0}.card-level-container label strong{font-size:12px;font-weight:600;color:#2d3748;text-transform:uppercase;letter-spacing:.5px;margin-bottom:4px}.card-level-container label .value-display{font-size:12px;font-weight:600;color:#1a202c;text-align:center;padding:0 5px;background:#4299e11a;border-radius:5px}.card-level-container label .bidirectional-meter{width:100%;margin-bottom:4px}.card-level-container label .bidirectional-meter .meter-track{position:relative;width:100%;height:10px;background:#e2e8f0;border-radius:12px;box-shadow:inset 0 2px 4px #0000001a;overflow:hidden}.card-level-container label .bidirectional-meter .meter-track .center-line{position:absolute;left:50%;top:0;bottom:0;width:4px;background:#4a5568;transform:translate(-50%);z-index:1}.card-level-container label .bidirectional-meter .meter-track .meter-fill{position:absolute;top:0;bottom:0;border-radius:5px}.card-level-container label .bidirectional-meter .meter-track .meter-fill.fill-right{left:50%}.card-level-container label .bidirectional-meter .meter-track .meter-fill.fill-left{right:50%}.card-level-container label meter{width:100%;border-radius:12px;border:none;background:#e2e8f0;margin-bottom:4px}.card-level-container label meter::-webkit-meter-bar{background:#e2e8f0;border-radius:12px;box-shadow:inset 0 2px 4px #0000001a}.card-level-container label meter::-webkit-meter-optimum-value{background:linear-gradient(90deg,#48bb78,#38a169);border-radius:12px}.card-level-container label meter::-webkit-meter-suboptimum-value{background:linear-gradient(90deg,#ed8936,#dd6b20);border-radius:12px}.card-level-container label meter::-webkit-meter-even-less-good-value{background:linear-gradient(90deg,#f56565,#e53e3e);border-radius:12px}.card-level-container label meter::-moz-meter-bar{background:linear-gradient(90deg,#48bb78,#38a169);border-radius:12px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
49
50
  }
50
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: CardLevelComponent, decorators: [{
51
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: CardLevelComponent, decorators: [{
51
52
  type: Component,
52
53
  args: [{ selector: 'c80-card-level', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- eslint-disable @angular-eslint/template/no-inline-styles -->\n<div class=\"card-level-container\" [style.width]=\"cardWidth()\">\n <label [for]=\"generatedId()\">\n <strong>{{ cardLevelData().label }}</strong>\n\n <span class=\"value-display\">\n @if (isBidirectional()) {\n <!-- Barra bidireccional desde el centro -->\n <div class=\"bidirectional-meter\">\n <div class=\"meter-track\">\n <div class=\"center-line\"></div>\n <div class=\"meter-fill\" [class.fill-left]=\"fillDirection() === 'left'\" [class.fill-right]=\"fillDirection() === 'right'\" [style.width.%]=\"bidirectionalFillPercent()\" [style.background]=\"fillColor()\">\n </div>\n </div>\n </div>\n } @else {\n <!-- Meter est\u00E1ndar para rangos unidireccionales -->\n <meter [id]=\"generatedId()\" [optimum]=\"cardLevelData().optimum\" [min]=\"cardLevelData().min\" [max]=\"cardLevelData().max\" [low]=\"cardLevelData().low\" [high]=\"cardLevelData().high\" [value]=\"cardLevelData().value\">\n </meter>\n }\n\n {{ cardLevelData().value }}{{ cardLevelData().unit }}\n </span>\n </label>\n</div>\n<!-- eslint-enable @angular-eslint/template/no-inline-styles -->", styles: [".card-level-container{background:#fff;border-radius:5px;padding:8px;margin:4px;box-shadow:0 4px 6px #0000001a,0 1px 3px #00000014;min-width:100px;flex:1}.card-level-container label{display:flex;flex-direction:column;margin:0}.card-level-container label strong{font-size:12px;font-weight:600;color:#2d3748;text-transform:uppercase;letter-spacing:.5px;margin-bottom:4px}.card-level-container label .value-display{font-size:12px;font-weight:600;color:#1a202c;text-align:center;padding:0 5px;background:#4299e11a;border-radius:5px}.card-level-container label .bidirectional-meter{width:100%;margin-bottom:4px}.card-level-container label .bidirectional-meter .meter-track{position:relative;width:100%;height:10px;background:#e2e8f0;border-radius:12px;box-shadow:inset 0 2px 4px #0000001a;overflow:hidden}.card-level-container label .bidirectional-meter .meter-track .center-line{position:absolute;left:50%;top:0;bottom:0;width:4px;background:#4a5568;transform:translate(-50%);z-index:1}.card-level-container label .bidirectional-meter .meter-track .meter-fill{position:absolute;top:0;bottom:0;border-radius:5px}.card-level-container label .bidirectional-meter .meter-track .meter-fill.fill-right{left:50%}.card-level-container label .bidirectional-meter .meter-track .meter-fill.fill-left{right:50%}.card-level-container label meter{width:100%;border-radius:12px;border:none;background:#e2e8f0;margin-bottom:4px}.card-level-container label meter::-webkit-meter-bar{background:#e2e8f0;border-radius:12px;box-shadow:inset 0 2px 4px #0000001a}.card-level-container label meter::-webkit-meter-optimum-value{background:linear-gradient(90deg,#48bb78,#38a169);border-radius:12px}.card-level-container label meter::-webkit-meter-suboptimum-value{background:linear-gradient(90deg,#ed8936,#dd6b20);border-radius:12px}.card-level-container label meter::-webkit-meter-even-less-good-value{background:linear-gradient(90deg,#f56565,#e53e3e);border-radius:12px}.card-level-container label meter::-moz-meter-bar{background:linear-gradient(90deg,#48bb78,#38a169);border-radius:12px}\n"] }]
53
54
  }], propDecorators: { cardLevelData: [{ type: i0.Input, args: [{ isSignal: true, alias: "cardLevelData", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
@@ -1 +1 @@
1
- {"version":3,"file":"card-level.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/card-level/card-level.component.ts","../../../../../libs/ui/src/lib/card-level/card-level.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;;AAYpF,MAAM,OAAO,kBAAkB;IAC7B,aAAa,GAAG,KAAK,CAAC,QAAQ,wDAAiB,CAAC;IAChD,IAAI,GAAG,KAAK,CAAS,CAAC,gDAAC,CAAC,CAAC,wCAAwC;IAEjE,uCAAuC;IAC9B,WAAW,GAAG,QAAQ,CAAC,GAAG,EAAE;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC/E,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC;QACpD,OAAO,GAAG,KAAK,IAAI,SAAS,EAAE,CAAC;IACjC,CAAC,uDAAC,CAAC;IAEH,6BAA6B;IACpB,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE;QACjC,MAAM,SAAS,GAAG,GAAG,CAAC;QACtB,MAAM,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAChD,OAAO,GAAG,eAAe,IAAI,CAAC;IAChC,CAAC,qDAAC,CAAC;IAEH,oEAAoE;IACpE,eAAe,GAAG,QAAQ,CAAC,GAAG,EAAE;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;IACtC,CAAC,2DAAC,CAAC;IAEH,4DAA4D;IAC5D,wBAAwB,GAAG,QAAQ,CAAC,GAAG,EAAE;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QACvC,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC;IACjD,CAAC,oEAAC,CAAC;IAEH,+CAA+C;IAC/C,aAAa,GAAG,QAAQ,CAAC,GAAG,EAAE;QAC5B,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAC5D,CAAC,yDAAC,CAAC;IAEH,kCAAkC;IAClC,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAElC,IAAI,QAAQ,IAAI,OAAO,EAAE,CAAC;YACxB,OAAO,qBAAqB,CAAC;QAC/B,CAAC;QACD,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;YACvB,OAAO,sBAAsB,CAAC;QAChC,CAAC;QACD,OAAO,sBAAsB,CAAC;IAChC,CAAC,qDAAC,CAAC;uGAlDQ,kBAAkB;2FAAlB,kBAAkB,0VCZ/B,qtCAyBgE;;2FDbnD,kBAAkB;kBAT9B,SAAS;+BAEE,gBAAgB,cACd,IAAI,WACP,EAAE,mBAGM,uBAAuB,CAAC,MAAM","sourcesContent":["import { Component, input, computed, ChangeDetectionStrategy } from '@angular/core';\nimport type { CardLevelData } from './card-level.interface';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-card-level',\n standalone: true,\n imports: [],\n templateUrl: './card-level.component.html',\n styleUrl: './card-level.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CardLevelComponent {\n cardLevelData = input.required<CardLevelData>();\n size = input<number>(1); // Multiplicador del tamaño base (220px)\n\n // ID único generado para el componente\n readonly generatedId = computed(() => {\n const label = this.cardLevelData().label.toLowerCase().replaceAll(/\\s+/g, '-');\n const randomNum = Math.floor(Math.random() * 10000);\n return `${label}-${randomNum}`;\n });\n\n // Ancho calculado de la card\n readonly cardWidth = computed(() => {\n const baseWidth = 140;\n const calculatedWidth = baseWidth * this.size();\n return `${calculatedWidth}px`;\n });\n\n // Detecta si el rango es bidireccional (min negativo, max positivo)\n isBidirectional = computed(() => {\n const data = this.cardLevelData();\n return data.min < 0 && data.max > 0;\n });\n\n // Calcula el porcentaje de fill para barras bidireccionales\n bidirectionalFillPercent = computed(() => {\n const data = this.cardLevelData();\n const totalRange = data.max - data.min;\n return Math.abs(data.value / totalRange) * 100;\n });\n\n // Determina la dirección del fill (left/right)\n fillDirection = computed(() => {\n return this.cardLevelData().value >= 0 ? 'right' : 'left';\n });\n\n // Color según el valor y umbrales\n fillColor = computed(() => {\n const data = this.cardLevelData();\n const absValue = Math.abs(data.value);\n const absHigh = Math.abs(data.high);\n const absLow = Math.abs(data.low);\n\n if (absValue >= absHigh) {\n return 'var(--color-danger)';\n }\n if (absValue >= absLow) {\n return 'var(--color-warning)';\n }\n return 'var(--color-success)';\n });\n}\n","<!-- eslint-disable @angular-eslint/template/no-inline-styles -->\n<div class=\"card-level-container\" [style.width]=\"cardWidth()\">\n <label [for]=\"generatedId()\">\n <strong>{{ cardLevelData().label }}</strong>\n\n <span class=\"value-display\">\n @if (isBidirectional()) {\n <!-- Barra bidireccional desde el centro -->\n <div class=\"bidirectional-meter\">\n <div class=\"meter-track\">\n <div class=\"center-line\"></div>\n <div class=\"meter-fill\" [class.fill-left]=\"fillDirection() === 'left'\" [class.fill-right]=\"fillDirection() === 'right'\" [style.width.%]=\"bidirectionalFillPercent()\" [style.background]=\"fillColor()\">\n </div>\n </div>\n </div>\n } @else {\n <!-- Meter estándar para rangos unidireccionales -->\n <meter [id]=\"generatedId()\" [optimum]=\"cardLevelData().optimum\" [min]=\"cardLevelData().min\" [max]=\"cardLevelData().max\" [low]=\"cardLevelData().low\" [high]=\"cardLevelData().high\" [value]=\"cardLevelData().value\">\n </meter>\n }\n\n {{ cardLevelData().value }}{{ cardLevelData().unit }}\n </span>\n </label>\n</div>\n<!-- eslint-enable @angular-eslint/template/no-inline-styles -->"]}
1
+ {"version":3,"file":"card-level.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/card-level/card-level.component.ts","../../../../../libs/ui/src/lib/card-level/card-level.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;;AAYpF,MAAM,OAAO,kBAAkB;IAC7B,aAAa,GAAG,KAAK,CAAC,QAAQ,wDAAiB,CAAC;IAChD,oBAAoB;IACpB,IAAI,GAAG,KAAK,CAAS,CAAC,gDAAC,CAAC,CAAC,wCAAwC;IAEjE,uCAAuC;IAC9B,WAAW,GAAG,QAAQ,CAAC,GAAG,EAAE;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC/E,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC;QACpD,OAAO,GAAG,KAAK,IAAI,SAAS,EAAE,CAAC;IACjC,CAAC,uDAAC,CAAC;IAEH,6BAA6B;IACpB,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE;QACjC,MAAM,SAAS,GAAG,GAAG,CAAC;QACtB,MAAM,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAChD,OAAO,GAAG,eAAe,IAAI,CAAC;IAChC,CAAC,qDAAC,CAAC;IAEH,oEAAoE;IACpE,eAAe,GAAG,QAAQ,CAAC,GAAG,EAAE;QAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;IACtC,CAAC,2DAAC,CAAC;IAEH,4DAA4D;IAC5D,wBAAwB,GAAG,QAAQ,CAAC,GAAG,EAAE;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QACvC,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC;IACjD,CAAC,oEAAC,CAAC;IAEH,+CAA+C;IAC/C,aAAa,GAAG,QAAQ,CAAC,GAAG,EAAE;QAC5B,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAC5D,CAAC,yDAAC,CAAC;IAEH,kCAAkC;IAClC,SAAS,GAAG,QAAQ,CAAC,GAAG,EAAE;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAElC,IAAI,QAAQ,IAAI,OAAO,EAAE,CAAC;YACxB,OAAO,qBAAqB,CAAC;QAC/B,CAAC;QACD,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;YACvB,OAAO,sBAAsB,CAAC;QAChC,CAAC;QACD,OAAO,sBAAsB,CAAC;IAChC,CAAC,qDAAC,CAAC;wGAnDQ,kBAAkB;4FAAlB,kBAAkB,0VCZ/B,qtCAyBgE;;4FDbnD,kBAAkB;kBAT9B,SAAS;+BAEE,gBAAgB,cACd,IAAI,WACP,EAAE,mBAGM,uBAAuB,CAAC,MAAM","sourcesContent":["import { Component, input, computed, ChangeDetectionStrategy } from '@angular/core';\nimport type { CardLevelData } from './card-level.interface';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-card-level',\n standalone: true,\n imports: [],\n templateUrl: './card-level.component.html',\n styleUrl: './card-level.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CardLevelComponent {\n cardLevelData = input.required<CardLevelData>();\n /* v8 ignore next */\n size = input<number>(1); // Multiplicador del tamaño base (220px)\n\n // ID único generado para el componente\n readonly generatedId = computed(() => {\n const label = this.cardLevelData().label.toLowerCase().replaceAll(/\\s+/g, '-');\n const randomNum = Math.floor(Math.random() * 10000);\n return `${label}-${randomNum}`;\n });\n\n // Ancho calculado de la card\n readonly cardWidth = computed(() => {\n const baseWidth = 140;\n const calculatedWidth = baseWidth * this.size();\n return `${calculatedWidth}px`;\n });\n\n // Detecta si el rango es bidireccional (min negativo, max positivo)\n isBidirectional = computed(() => {\n const data = this.cardLevelData();\n return data.min < 0 && data.max > 0;\n });\n\n // Calcula el porcentaje de fill para barras bidireccionales\n bidirectionalFillPercent = computed(() => {\n const data = this.cardLevelData();\n const totalRange = data.max - data.min;\n return Math.abs(data.value / totalRange) * 100;\n });\n\n // Determina la dirección del fill (left/right)\n fillDirection = computed(() => {\n return this.cardLevelData().value >= 0 ? 'right' : 'left';\n });\n\n // Color según el valor y umbrales\n fillColor = computed(() => {\n const data = this.cardLevelData();\n const absValue = Math.abs(data.value);\n const absHigh = Math.abs(data.high);\n const absLow = Math.abs(data.low);\n\n if (absValue >= absHigh) {\n return 'var(--color-danger)';\n }\n if (absValue >= absLow) {\n return 'var(--color-warning)';\n }\n return 'var(--color-success)';\n });\n}\n","<!-- eslint-disable @angular-eslint/template/no-inline-styles -->\n<div class=\"card-level-container\" [style.width]=\"cardWidth()\">\n <label [for]=\"generatedId()\">\n <strong>{{ cardLevelData().label }}</strong>\n\n <span class=\"value-display\">\n @if (isBidirectional()) {\n <!-- Barra bidireccional desde el centro -->\n <div class=\"bidirectional-meter\">\n <div class=\"meter-track\">\n <div class=\"center-line\"></div>\n <div class=\"meter-fill\" [class.fill-left]=\"fillDirection() === 'left'\" [class.fill-right]=\"fillDirection() === 'right'\" [style.width.%]=\"bidirectionalFillPercent()\" [style.background]=\"fillColor()\">\n </div>\n </div>\n </div>\n } @else {\n <!-- Meter estándar para rangos unidireccionales -->\n <meter [id]=\"generatedId()\" [optimum]=\"cardLevelData().optimum\" [min]=\"cardLevelData().min\" [max]=\"cardLevelData().max\" [low]=\"cardLevelData().low\" [high]=\"cardLevelData().high\" [value]=\"cardLevelData().value\">\n </meter>\n }\n\n {{ cardLevelData().value }}{{ cardLevelData().unit }}\n </span>\n </label>\n</div>\n<!-- eslint-enable @angular-eslint/template/no-inline-styles -->"]}
@@ -1,18 +1,29 @@
1
1
  import { NgTemplateOutlet } from '@angular/common';
2
2
  import { Component, input, output, computed, ChangeDetectionStrategy } from '@angular/core';
3
- import { BASE_ICON_SIZE, BASE_ICON_COLORS, DISABLED_COLOR, DEFAULT_ICON_COLOR, DISABLED_OPACITY, SECONDARY_WARN_OPACITY, DEFAULT_OPACITY, ICON_PATHS, ICON_ADDITIONAL_SHAPES, } from './icon.constants';
4
- import { transformToBoolean } from './icon.utils';
3
+ import { BASE_ICON_SIZE, BASE_ICON_COLORS, DISABLED_COLOR, DEFAULT_ICON_COLOR, DISABLED_OPACITY, SECONDARY_WARN_OPACITY, DEFAULT_OPACITY, OPACITY_REDUCED_COLORS, SVG_STROKE_ATTRS, } from './icon.constants';
4
+ import { ICON_DEFINITIONS } from './icon.definitions';
5
+ import { transformToBoolean, shouldIconUseFill } from './icon.utils';
5
6
  import * as i0 from "@angular/core";
6
7
  export class C80IconComponent {
8
+ /* v8 ignore next */
7
9
  icon = input('check', ...(ngDevMode ? [{ debugName: "icon" }] : [])); // Tipo de icono a mostrar
10
+ /* v8 ignore next */
8
11
  color = input('dark', ...(ngDevMode ? [{ debugName: "color" }] : [])); // Color del icono (primary, secondary, warn, success, dark)
12
+ /* v8 ignore next */
9
13
  customColor = input(undefined, ...(ngDevMode ? [{ debugName: "customColor" }] : [])); // Color personalizado (sobrescribe color)
14
+ /* v8 ignore next */
10
15
  disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : [])); // Estado deshabilitado
16
+ /* v8 ignore next */
11
17
  size = input(1, ...(ngDevMode ? [{ debugName: "size" }] : [])); // Multiplicador de tamaño (1 = 24px)
18
+ /* v8 ignore next */
12
19
  button = input(false, ...(ngDevMode ? [{ debugName: "button", transform: transformToBoolean }] : [{ transform: transformToBoolean }])); // Renderiza como botón clickeable
20
+ /* v8 ignore next */
13
21
  border = input(false, ...(ngDevMode ? [{ debugName: "border", transform: transformToBoolean }] : [{ transform: transformToBoolean }])); // Agrega borde al wrapper
22
+ /* v8 ignore next */
14
23
  type = input('button', ...(ngDevMode ? [{ debugName: "type" }] : [])); // Tipo de botón (button, submit, reset)
24
+ /* v8 ignore next */
15
25
  textLeft = input(undefined, ...(ngDevMode ? [{ debugName: "textLeft" }] : [])); // Texto a la izquierda del icono
26
+ /* v8 ignore next */
16
27
  textRight = input(undefined, ...(ngDevMode ? [{ debugName: "textRight" }] : [])); // Texto a la derecha del icono
17
28
  iconClick = output(); // Evento emitido al hacer click (solo si button=true)
18
29
  iconSize = computed(() => BASE_ICON_SIZE * this.size(), ...(ngDevMode ? [{ debugName: "iconSize" }] : []));
@@ -28,21 +39,30 @@ export class C80IconComponent {
28
39
  if (this.disabled())
29
40
  return DISABLED_OPACITY;
30
41
  const hasCustomColor = this.customColor() !== undefined;
31
- const isSecondaryOrWarn = ['secondary', 'warn'].includes(this.color());
32
- return !hasCustomColor && isSecondaryOrWarn ? SECONDARY_WARN_OPACITY : DEFAULT_OPACITY;
42
+ const isOpacityReducedColor = OPACITY_REDUCED_COLORS.includes(this.color());
43
+ return !hasCustomColor && isOpacityReducedColor ? SECONDARY_WARN_OPACITY : DEFAULT_OPACITY;
33
44
  }, ...(ngDevMode ? [{ debugName: "iconOpacity" }] : []));
34
- iconPath = computed(() => ICON_PATHS[this.icon()] ?? ICON_PATHS['default'], ...(ngDevMode ? [{ debugName: "iconPath" }] : []));
35
- additionalShapes = computed(() => ICON_ADDITIONAL_SHAPES[this.icon()] ?? [], ...(ngDevMode ? [{ debugName: "additionalShapes" }] : []));
45
+ // Optimización: Un solo lookup a ICON_DEFINITIONS
46
+ iconDefinition = computed(() => {
47
+ return ICON_DEFINITIONS[this.icon()] ?? ICON_DEFINITIONS['default'];
48
+ }, ...(ngDevMode ? [{ debugName: "iconDefinition" }] : []));
49
+ iconPath = computed(() => this.iconDefinition().path, ...(ngDevMode ? [{ debugName: "iconPath" }] : []));
50
+ additionalShapes = computed(() => this.iconDefinition().additionalShapes ?? [], ...(ngDevMode ? [{ debugName: "additionalShapes" }] : []));
51
+ shouldFillIcon = computed(() => shouldIconUseFill(this.icon()), ...(ngDevMode ? [{ debugName: "shouldFillIcon" }] : []));
52
+ multiColorIcon = computed(() => this.iconDefinition().multiColor, ...(ngDevMode ? [{ debugName: "multiColorIcon" }] : []));
53
+ hasMultiPaths = computed(() => this.multiColorIcon() !== undefined, ...(ngDevMode ? [{ debugName: "hasMultiPaths" }] : []));
54
+ // Exponer constantes SVG al template
55
+ svgStrokeAttrs = SVG_STROKE_ATTRS;
36
56
  onButtonClick(event) {
37
57
  if (!this.disabled()) {
38
58
  this.iconClick.emit(event);
39
59
  }
40
60
  }
41
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: C80IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
42
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: C80IconComponent, isStandalone: true, selector: "c80-icon", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, customColor: { classPropertyName: "customColor", publicName: "customColor", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, button: { classPropertyName: "button", publicName: "button", isSignal: true, isRequired: false, transformFunction: null }, border: { classPropertyName: "border", publicName: "border", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, textLeft: { classPropertyName: "textLeft", publicName: "textLeft", isSignal: true, isRequired: false, transformFunction: null }, textRight: { classPropertyName: "textRight", publicName: "textRight", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { iconClick: "iconClick" }, ngImport: i0, template: "<ng-template #svgContent>\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <svg [attr.width]=\"iconSize()\" [attr.height]=\"iconSize()\" viewBox=\"0 0 24 24\" fill=\"none\" [style.opacity]=\"iconOpacity()\">\n @for (shape of additionalShapes(); track $index) {\n @if (shape.type === 'circle') {\n <circle [attr.cx]=\"shape['cx']\" [attr.cy]=\"shape['cy']\" [attr.r]=\"shape['r']\" [attr.stroke]=\"iconColor()\" stroke-width=\"1\" [attr.fill]=\"shape['fill'] === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'rect') {\n <rect [attr.x]=\"shape['x']\" [attr.y]=\"shape['y']\" [attr.width]=\"shape['width']\" [attr.height]=\"shape['height']\" [attr.rx]=\"shape['rx']\" [attr.stroke]=\"iconColor()\" stroke-width=\"1\" fill=\"none\" />\n } @else if (shape.type === 'path') {\n <path [attr.d]=\"shape['d']\" [attr.stroke]=\"iconColor()\" stroke-width=\"1\" [attr.fill]=\"shape['fill'] === 'color' ? iconColor() : 'none'\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n }\n }\n <path [attr.d]=\"iconPath()\" [attr.stroke]=\"iconColor()\" [attr.fill]=\"icon() === 'delete' ? iconColor() : 'none'\" stroke-width=\"1\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n</ng-template>\n\n<ng-template #textContent>\n @if (textLeft()) {\n <span class=\"icon-text ms-3\">{{ textLeft() }}</span>\n }\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span class=\"icon-content\" [style.width.px]=\"iconSize() + 8\" [style.height.px]=\"iconSize() + 8\">\n <ng-container *ngTemplateOutlet=\"svgContent\" />\n </span>\n @if (textRight()) {\n <span class=\"icon-text me-3\">{{ textRight() }}</span>\n }\n</ng-template>\n\n@if (button()) {\n<button [type]=\"type()\" [disabled]=\"disabled()\" class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" (click)=\"onButtonClick($event)\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</button>\n} @else {\n<span class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</span>\n}", styles: [":host .icon-wrapper{display:inline-flex;align-items:center;gap:8px;background:transparent;padding:0;border:none;outline:none;cursor:pointer;transition:opacity .2s}:host button.icon-wrapper:focus-visible{outline:none;outline-offset:2px;border-radius:4px}:host button.icon-wrapper:disabled{opacity:.5;cursor:default}:host .icon-content{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;min-width:0;min-height:0;padding:4px;margin:0 4px;transition:background .2s;box-sizing:border-box}:host button.icon-wrapper:hover:not(:disabled) .icon-content{background:var(--color-bg-hover)}:host button.icon-wrapper:active:not(:disabled) .icon-content{background:var(--color-bg-tertiary)}:host .icon-text{font-size:14px;line-height:1;white-space:nowrap;-webkit-user-select:none;user-select:none;color:var(--color-text-primary)}:host .icon-wrapper-border{border:1px solid var(--color-border-default);border-radius:4px;padding:4px 8px}:host button.icon-wrapper-border:hover:not(:disabled){border-color:var(--color-border-medium)}:host button.icon-wrapper-border:disabled{border-color:var(--color-border-light)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
61
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: C80IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
62
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: C80IconComponent, isStandalone: true, selector: "c80-icon", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, customColor: { classPropertyName: "customColor", publicName: "customColor", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, button: { classPropertyName: "button", publicName: "button", isSignal: true, isRequired: false, transformFunction: null }, border: { classPropertyName: "border", publicName: "border", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, textLeft: { classPropertyName: "textLeft", publicName: "textLeft", isSignal: true, isRequired: false, transformFunction: null }, textRight: { classPropertyName: "textRight", publicName: "textRight", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { iconClick: "iconClick" }, ngImport: i0, template: "<ng-template #svgContent>\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <svg [attr.width]=\"iconSize()\" [attr.height]=\"iconSize()\" viewBox=\"0 0 24 24\" fill=\"none\" [style.opacity]=\"iconOpacity()\">\n @for (shape of additionalShapes(); track $index) {\n @if (shape.type === 'circle') {\n <circle [attr.cx]=\"shape.cx\" [attr.cy]=\"shape.cy\" [attr.r]=\"shape.r\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'rect') {\n <rect [attr.x]=\"shape.x\" [attr.y]=\"shape.y\" [attr.width]=\"shape.width\" [attr.height]=\"shape.height\" [attr.rx]=\"shape.rx || null\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'path') {\n <path [attr.d]=\"shape.d\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.stroke-linecap]=\"svgStrokeAttrs.strokeLinecap\" [attr.stroke-linejoin]=\"svgStrokeAttrs.strokeLinejoin\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n }\n }\n\n @if (hasMultiPaths()) {\n <!-- Iconos con m\u00FAltiples paths y colores personalizados -->\n @for (path of multiColorIcon()!.paths; track $index) {\n <path [attr.d]=\"path\" [attr.fill]=\"multiColorIcon()!.colors[$index] || iconColor()\" stroke=\"none\" />\n }\n } @else {\n <!-- Iconos con un solo path -->\n <path [attr.d]=\"iconPath()\" [attr.stroke]=\"iconColor()\" [attr.fill]=\"shouldFillIcon() ? iconColor() : 'none'\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.stroke-linecap]=\"svgStrokeAttrs.strokeLinecap\"\n [attr.stroke-linejoin]=\"svgStrokeAttrs.strokeLinejoin\" />\n }\n </svg>\n</ng-template>\n\n<ng-template #textContent>\n @if (textLeft()) {\n <span class=\"icon-text ms-3\">{{ textLeft() }}</span>\n }\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span class=\"icon-content\" [style.width.px]=\"iconSize() + 8\" [style.height.px]=\"iconSize() + 8\">\n <ng-container *ngTemplateOutlet=\"svgContent\" />\n </span>\n @if (textRight()) {\n <span class=\"icon-text me-3\">{{ textRight() }}</span>\n }\n</ng-template>\n\n@if (button()) {\n<button [type]=\"type()\" [disabled]=\"disabled()\" class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" (click)=\"onButtonClick($event)\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</button>\n} @else {\n<span class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</span>\n}", styles: [":host .icon-wrapper{display:inline-flex;align-items:center;gap:8px;background:transparent;padding:0;border:none;outline:none;cursor:pointer;transition:opacity .2s}:host button.icon-wrapper:focus-visible{outline:none;outline-offset:2px;border-radius:4px}:host button.icon-wrapper:disabled{opacity:.5;cursor:default}:host .icon-content{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;min-width:0;min-height:0;padding:4px;margin:0 4px;transition:background .2s;box-sizing:border-box}:host button.icon-wrapper:hover:not(:disabled) .icon-content{background:var(--color-bg-hover)}:host button.icon-wrapper:active:not(:disabled) .icon-content{background:var(--color-bg-tertiary)}:host .icon-text{font-size:14px;line-height:1;white-space:nowrap;-webkit-user-select:none;user-select:none;color:var(--color-text-primary)}:host .icon-wrapper-border{border:1px solid var(--color-border-default);border-radius:4px;padding:4px 8px}:host button.icon-wrapper-border:hover:not(:disabled){border-color:var(--color-border-medium)}:host button.icon-wrapper-border:disabled{border-color:var(--color-border-light)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
43
63
  }
44
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: C80IconComponent, decorators: [{
64
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: C80IconComponent, decorators: [{
45
65
  type: Component,
46
- args: [{ selector: 'c80-icon', standalone: true, imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #svgContent>\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <svg [attr.width]=\"iconSize()\" [attr.height]=\"iconSize()\" viewBox=\"0 0 24 24\" fill=\"none\" [style.opacity]=\"iconOpacity()\">\n @for (shape of additionalShapes(); track $index) {\n @if (shape.type === 'circle') {\n <circle [attr.cx]=\"shape['cx']\" [attr.cy]=\"shape['cy']\" [attr.r]=\"shape['r']\" [attr.stroke]=\"iconColor()\" stroke-width=\"1\" [attr.fill]=\"shape['fill'] === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'rect') {\n <rect [attr.x]=\"shape['x']\" [attr.y]=\"shape['y']\" [attr.width]=\"shape['width']\" [attr.height]=\"shape['height']\" [attr.rx]=\"shape['rx']\" [attr.stroke]=\"iconColor()\" stroke-width=\"1\" fill=\"none\" />\n } @else if (shape.type === 'path') {\n <path [attr.d]=\"shape['d']\" [attr.stroke]=\"iconColor()\" stroke-width=\"1\" [attr.fill]=\"shape['fill'] === 'color' ? iconColor() : 'none'\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n }\n }\n <path [attr.d]=\"iconPath()\" [attr.stroke]=\"iconColor()\" [attr.fill]=\"icon() === 'delete' ? iconColor() : 'none'\" stroke-width=\"1\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n</ng-template>\n\n<ng-template #textContent>\n @if (textLeft()) {\n <span class=\"icon-text ms-3\">{{ textLeft() }}</span>\n }\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span class=\"icon-content\" [style.width.px]=\"iconSize() + 8\" [style.height.px]=\"iconSize() + 8\">\n <ng-container *ngTemplateOutlet=\"svgContent\" />\n </span>\n @if (textRight()) {\n <span class=\"icon-text me-3\">{{ textRight() }}</span>\n }\n</ng-template>\n\n@if (button()) {\n<button [type]=\"type()\" [disabled]=\"disabled()\" class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" (click)=\"onButtonClick($event)\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</button>\n} @else {\n<span class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</span>\n}", styles: [":host .icon-wrapper{display:inline-flex;align-items:center;gap:8px;background:transparent;padding:0;border:none;outline:none;cursor:pointer;transition:opacity .2s}:host button.icon-wrapper:focus-visible{outline:none;outline-offset:2px;border-radius:4px}:host button.icon-wrapper:disabled{opacity:.5;cursor:default}:host .icon-content{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;min-width:0;min-height:0;padding:4px;margin:0 4px;transition:background .2s;box-sizing:border-box}:host button.icon-wrapper:hover:not(:disabled) .icon-content{background:var(--color-bg-hover)}:host button.icon-wrapper:active:not(:disabled) .icon-content{background:var(--color-bg-tertiary)}:host .icon-text{font-size:14px;line-height:1;white-space:nowrap;-webkit-user-select:none;user-select:none;color:var(--color-text-primary)}:host .icon-wrapper-border{border:1px solid var(--color-border-default);border-radius:4px;padding:4px 8px}:host button.icon-wrapper-border:hover:not(:disabled){border-color:var(--color-border-medium)}:host button.icon-wrapper-border:disabled{border-color:var(--color-border-light)}\n"] }]
66
+ args: [{ selector: 'c80-icon', standalone: true, imports: [NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #svgContent>\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <svg [attr.width]=\"iconSize()\" [attr.height]=\"iconSize()\" viewBox=\"0 0 24 24\" fill=\"none\" [style.opacity]=\"iconOpacity()\">\n @for (shape of additionalShapes(); track $index) {\n @if (shape.type === 'circle') {\n <circle [attr.cx]=\"shape.cx\" [attr.cy]=\"shape.cy\" [attr.r]=\"shape.r\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'rect') {\n <rect [attr.x]=\"shape.x\" [attr.y]=\"shape.y\" [attr.width]=\"shape.width\" [attr.height]=\"shape.height\" [attr.rx]=\"shape.rx || null\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'path') {\n <path [attr.d]=\"shape.d\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.stroke-linecap]=\"svgStrokeAttrs.strokeLinecap\" [attr.stroke-linejoin]=\"svgStrokeAttrs.strokeLinejoin\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n }\n }\n\n @if (hasMultiPaths()) {\n <!-- Iconos con m\u00FAltiples paths y colores personalizados -->\n @for (path of multiColorIcon()!.paths; track $index) {\n <path [attr.d]=\"path\" [attr.fill]=\"multiColorIcon()!.colors[$index] || iconColor()\" stroke=\"none\" />\n }\n } @else {\n <!-- Iconos con un solo path -->\n <path [attr.d]=\"iconPath()\" [attr.stroke]=\"iconColor()\" [attr.fill]=\"shouldFillIcon() ? iconColor() : 'none'\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.stroke-linecap]=\"svgStrokeAttrs.strokeLinecap\"\n [attr.stroke-linejoin]=\"svgStrokeAttrs.strokeLinejoin\" />\n }\n </svg>\n</ng-template>\n\n<ng-template #textContent>\n @if (textLeft()) {\n <span class=\"icon-text ms-3\">{{ textLeft() }}</span>\n }\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span class=\"icon-content\" [style.width.px]=\"iconSize() + 8\" [style.height.px]=\"iconSize() + 8\">\n <ng-container *ngTemplateOutlet=\"svgContent\" />\n </span>\n @if (textRight()) {\n <span class=\"icon-text me-3\">{{ textRight() }}</span>\n }\n</ng-template>\n\n@if (button()) {\n<button [type]=\"type()\" [disabled]=\"disabled()\" class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" (click)=\"onButtonClick($event)\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</button>\n} @else {\n<span class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</span>\n}", styles: [":host .icon-wrapper{display:inline-flex;align-items:center;gap:8px;background:transparent;padding:0;border:none;outline:none;cursor:pointer;transition:opacity .2s}:host button.icon-wrapper:focus-visible{outline:none;outline-offset:2px;border-radius:4px}:host button.icon-wrapper:disabled{opacity:.5;cursor:default}:host .icon-content{display:inline-flex;align-items:center;justify-content:center;border-radius:50%;min-width:0;min-height:0;padding:4px;margin:0 4px;transition:background .2s;box-sizing:border-box}:host button.icon-wrapper:hover:not(:disabled) .icon-content{background:var(--color-bg-hover)}:host button.icon-wrapper:active:not(:disabled) .icon-content{background:var(--color-bg-tertiary)}:host .icon-text{font-size:14px;line-height:1;white-space:nowrap;-webkit-user-select:none;user-select:none;color:var(--color-text-primary)}:host .icon-wrapper-border{border:1px solid var(--color-border-default);border-radius:4px;padding:4px 8px}:host button.icon-wrapper-border:hover:not(:disabled){border-color:var(--color-border-medium)}:host button.icon-wrapper-border:disabled{border-color:var(--color-border-light)}\n"] }]
47
67
  }], propDecorators: { icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], customColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "customColor", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], button: [{ type: i0.Input, args: [{ isSignal: true, alias: "button", required: false }] }], border: [{ type: i0.Input, args: [{ isSignal: true, alias: "border", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], textLeft: [{ type: i0.Input, args: [{ isSignal: true, alias: "textLeft", required: false }] }], textRight: [{ type: i0.Input, args: [{ isSignal: true, alias: "textRight", required: false }] }], iconClick: [{ type: i0.Output, args: ["iconClick"] }] } });
48
68
  //# sourceMappingURL=icon.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"icon.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/icon/icon.component.ts","../../../../../libs/ui/src/lib/icon/icon.component.html"],"names":[],"mappings":"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","sourcesContent":["import { NgTemplateOutlet } from '@angular/common';\nimport { Component, input, output, computed, ChangeDetectionStrategy } from '@angular/core';\nimport {\n BASE_ICON_SIZE,\n BASE_ICON_COLORS,\n DISABLED_COLOR,\n DEFAULT_ICON_COLOR,\n DISABLED_OPACITY,\n SECONDARY_WARN_OPACITY,\n DEFAULT_OPACITY,\n ICON_PATHS,\n ICON_ADDITIONAL_SHAPES,\n} from './icon.constants';\nimport type { IconType, ColorType, ButtonType } from './icon.types';\nimport { transformToBoolean } from './icon.utils';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-icon',\n standalone: true,\n imports: [NgTemplateOutlet],\n templateUrl: './icon.component.html',\n styleUrls: ['./icon.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class C80IconComponent {\n readonly icon = input<IconType>('check'); // Tipo de icono a mostrar\n readonly color = input<ColorType>('dark'); // Color del icono (primary, secondary, warn, success, dark)\n readonly customColor = input<string | undefined>(undefined); // Color personalizado (sobrescribe color)\n readonly disabled = input(false); // Estado deshabilitado\n readonly size = input(1); // Multiplicador de tamaño (1 = 24px)\n readonly button = input(false, { transform: transformToBoolean }); // Renderiza como botón clickeable\n readonly border = input(false, { transform: transformToBoolean }); // Agrega borde al wrapper\n readonly type = input<ButtonType>('button'); // Tipo de botón (button, submit, reset)\n readonly textLeft = input<string | undefined>(undefined); // Texto a la izquierda del icono\n readonly textRight = input<string | undefined>(undefined); // Texto a la derecha del icono\n\n readonly iconClick = output<Event>(); // Evento emitido al hacer click (solo si button=true)\n\n readonly iconSize = computed(() => BASE_ICON_SIZE * this.size());\n\n readonly iconColor = computed(() => {\n if (this.disabled()) return DISABLED_COLOR;\n\n const custom = this.customColor();\n if (custom) return custom;\n\n return BASE_ICON_COLORS[this.color()] ?? DEFAULT_ICON_COLOR;\n });\n\n readonly iconOpacity = computed(() => {\n if (this.disabled()) return DISABLED_OPACITY;\n\n const hasCustomColor = this.customColor() !== undefined;\n const isSecondaryOrWarn = ['secondary', 'warn'].includes(this.color());\n\n return !hasCustomColor && isSecondaryOrWarn ? SECONDARY_WARN_OPACITY : DEFAULT_OPACITY;\n });\n\n readonly iconPath = computed(() => ICON_PATHS[this.icon()] ?? ICON_PATHS['default']);\n readonly additionalShapes = computed(() => ICON_ADDITIONAL_SHAPES[this.icon()] ?? []);\n\n onButtonClick(event: Event): void {\n if (!this.disabled()) {\n this.iconClick.emit(event);\n }\n }\n}\n","<ng-template #svgContent>\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <svg [attr.width]=\"iconSize()\" [attr.height]=\"iconSize()\" viewBox=\"0 0 24 24\" fill=\"none\" [style.opacity]=\"iconOpacity()\">\n @for (shape of additionalShapes(); track $index) {\n @if (shape.type === 'circle') {\n <circle [attr.cx]=\"shape['cx']\" [attr.cy]=\"shape['cy']\" [attr.r]=\"shape['r']\" [attr.stroke]=\"iconColor()\" stroke-width=\"1\" [attr.fill]=\"shape['fill'] === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'rect') {\n <rect [attr.x]=\"shape['x']\" [attr.y]=\"shape['y']\" [attr.width]=\"shape['width']\" [attr.height]=\"shape['height']\" [attr.rx]=\"shape['rx']\" [attr.stroke]=\"iconColor()\" stroke-width=\"1\" fill=\"none\" />\n } @else if (shape.type === 'path') {\n <path [attr.d]=\"shape['d']\" [attr.stroke]=\"iconColor()\" stroke-width=\"1\" [attr.fill]=\"shape['fill'] === 'color' ? iconColor() : 'none'\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n }\n }\n <path [attr.d]=\"iconPath()\" [attr.stroke]=\"iconColor()\" [attr.fill]=\"icon() === 'delete' ? iconColor() : 'none'\" stroke-width=\"1\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n</ng-template>\n\n<ng-template #textContent>\n @if (textLeft()) {\n <span class=\"icon-text ms-3\">{{ textLeft() }}</span>\n }\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span class=\"icon-content\" [style.width.px]=\"iconSize() + 8\" [style.height.px]=\"iconSize() + 8\">\n <ng-container *ngTemplateOutlet=\"svgContent\" />\n </span>\n @if (textRight()) {\n <span class=\"icon-text me-3\">{{ textRight() }}</span>\n }\n</ng-template>\n\n@if (button()) {\n<button [type]=\"type()\" [disabled]=\"disabled()\" class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" (click)=\"onButtonClick($event)\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</button>\n} @else {\n<span class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</span>\n}"]}
1
+ {"version":3,"file":"icon.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/icon/icon.component.ts","../../../../../libs/ui/src/lib/icon/icon.component.html"],"names":[],"mappings":"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","sourcesContent":["import { NgTemplateOutlet } from '@angular/common';\nimport { Component, input, output, computed, ChangeDetectionStrategy } from '@angular/core';\nimport {\n BASE_ICON_SIZE,\n BASE_ICON_COLORS,\n DISABLED_COLOR,\n DEFAULT_ICON_COLOR,\n DISABLED_OPACITY,\n SECONDARY_WARN_OPACITY,\n DEFAULT_OPACITY,\n OPACITY_REDUCED_COLORS,\n SVG_STROKE_ATTRS,\n} from './icon.constants';\nimport { ICON_DEFINITIONS } from './icon.definitions';\nimport type { ColorType, ButtonType, IconType } from './icon.types';\nimport { transformToBoolean, shouldIconUseFill } from './icon.utils';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-icon',\n standalone: true,\n imports: [NgTemplateOutlet],\n templateUrl: './icon.component.html',\n styleUrls: ['./icon.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class C80IconComponent {\n /* v8 ignore next */\n readonly icon = input<IconType>('check'); // Tipo de icono a mostrar\n /* v8 ignore next */\n readonly color = input<ColorType>('dark'); // Color del icono (primary, secondary, warn, success, dark)\n /* v8 ignore next */\n readonly customColor = input<string | undefined>(undefined); // Color personalizado (sobrescribe color)\n /* v8 ignore next */\n readonly disabled = input(false); // Estado deshabilitado\n /* v8 ignore next */\n readonly size = input(1); // Multiplicador de tamaño (1 = 24px)\n /* v8 ignore next */\n readonly button = input(false, { transform: transformToBoolean }); // Renderiza como botón clickeable\n /* v8 ignore next */\n readonly border = input(false, { transform: transformToBoolean }); // Agrega borde al wrapper\n /* v8 ignore next */\n readonly type = input<ButtonType>('button'); // Tipo de botón (button, submit, reset)\n /* v8 ignore next */\n readonly textLeft = input<string | undefined>(undefined); // Texto a la izquierda del icono\n /* v8 ignore next */\n readonly textRight = input<string | undefined>(undefined); // Texto a la derecha del icono\n\n readonly iconClick = output<Event>(); // Evento emitido al hacer click (solo si button=true)\n\n readonly iconSize = computed(() => BASE_ICON_SIZE * this.size());\n\n readonly iconColor = computed(() => {\n if (this.disabled()) return DISABLED_COLOR;\n\n const custom = this.customColor();\n if (custom) return custom;\n\n return BASE_ICON_COLORS[this.color()] ?? DEFAULT_ICON_COLOR;\n });\n\n readonly iconOpacity = computed(() => {\n if (this.disabled()) return DISABLED_OPACITY;\n\n const hasCustomColor = this.customColor() !== undefined;\n const isOpacityReducedColor = OPACITY_REDUCED_COLORS.includes(this.color());\n\n return !hasCustomColor && isOpacityReducedColor ? SECONDARY_WARN_OPACITY : DEFAULT_OPACITY;\n });\n\n // Optimización: Un solo lookup a ICON_DEFINITIONS\n readonly iconDefinition = computed(() => {\n return ICON_DEFINITIONS[this.icon()] ?? ICON_DEFINITIONS['default'];\n });\n\n readonly iconPath = computed(() => this.iconDefinition().path);\n\n readonly additionalShapes = computed(() => this.iconDefinition().additionalShapes ?? []);\n\n readonly shouldFillIcon = computed(() => shouldIconUseFill(this.icon()));\n\n readonly multiColorIcon = computed(() => this.iconDefinition().multiColor);\n\n readonly hasMultiPaths = computed(() => this.multiColorIcon() !== undefined);\n\n // Exponer constantes SVG al template\n readonly svgStrokeAttrs = SVG_STROKE_ATTRS;\n\n onButtonClick(event: Event): void {\n if (!this.disabled()) {\n this.iconClick.emit(event);\n }\n }\n}\n","<ng-template #svgContent>\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <svg [attr.width]=\"iconSize()\" [attr.height]=\"iconSize()\" viewBox=\"0 0 24 24\" fill=\"none\" [style.opacity]=\"iconOpacity()\">\n @for (shape of additionalShapes(); track $index) {\n @if (shape.type === 'circle') {\n <circle [attr.cx]=\"shape.cx\" [attr.cy]=\"shape.cy\" [attr.r]=\"shape.r\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'rect') {\n <rect [attr.x]=\"shape.x\" [attr.y]=\"shape.y\" [attr.width]=\"shape.width\" [attr.height]=\"shape.height\" [attr.rx]=\"shape.rx || null\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n } @else if (shape.type === 'path') {\n <path [attr.d]=\"shape.d\" [attr.stroke]=\"iconColor()\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.stroke-linecap]=\"svgStrokeAttrs.strokeLinecap\" [attr.stroke-linejoin]=\"svgStrokeAttrs.strokeLinejoin\"\n [attr.fill]=\"shape.fill === 'color' ? iconColor() : 'none'\" />\n }\n }\n\n @if (hasMultiPaths()) {\n <!-- Iconos con múltiples paths y colores personalizados -->\n @for (path of multiColorIcon()!.paths; track $index) {\n <path [attr.d]=\"path\" [attr.fill]=\"multiColorIcon()!.colors[$index] || iconColor()\" stroke=\"none\" />\n }\n } @else {\n <!-- Iconos con un solo path -->\n <path [attr.d]=\"iconPath()\" [attr.stroke]=\"iconColor()\" [attr.fill]=\"shouldFillIcon() ? iconColor() : 'none'\" [attr.stroke-width]=\"svgStrokeAttrs.strokeWidth\" [attr.stroke-linecap]=\"svgStrokeAttrs.strokeLinecap\"\n [attr.stroke-linejoin]=\"svgStrokeAttrs.strokeLinejoin\" />\n }\n </svg>\n</ng-template>\n\n<ng-template #textContent>\n @if (textLeft()) {\n <span class=\"icon-text ms-3\">{{ textLeft() }}</span>\n }\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span class=\"icon-content\" [style.width.px]=\"iconSize() + 8\" [style.height.px]=\"iconSize() + 8\">\n <ng-container *ngTemplateOutlet=\"svgContent\" />\n </span>\n @if (textRight()) {\n <span class=\"icon-text me-3\">{{ textRight() }}</span>\n }\n</ng-template>\n\n@if (button()) {\n<button [type]=\"type()\" [disabled]=\"disabled()\" class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" (click)=\"onButtonClick($event)\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</button>\n} @else {\n<span class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</span>\n}"]}
@@ -1,88 +1,3 @@
1
- export const ICON_NAMES = [
2
- 'check',
3
- 'cancel',
4
- 'edit',
5
- 'delete',
6
- 'add',
7
- 'view',
8
- 'get',
9
- 'settings',
10
- 'schedule',
11
- 'refresh',
12
- 'checkCircle',
13
- 'cancelCircle',
14
- 'error',
15
- 'queue',
16
- 'arrowUp',
17
- 'arrowDown',
18
- 'toggleOn',
19
- 'toggleOff',
20
- 'search',
21
- 'upload',
22
- 'pendingActions',
23
- 'playCircle',
24
- 'play',
25
- 'stop',
26
- 'tune',
27
- 'visibility',
28
- 'visibilityOff',
29
- 'close',
30
- 'record',
31
- 'star',
32
- 'xCircle',
33
- 'key',
34
- 'exclamationTriangle',
35
- 'clipboard',
36
- 'download',
37
- 'shield',
38
- 'person',
39
- 'envelope',
40
- 'infoCircle',
41
- 'checkSquare',
42
- 'square',
43
- 'dashSquare',
44
- 'people',
45
- 'boxSeam',
46
- 'personBadge',
47
- 'listTask',
48
- 'shuffle',
49
- 'motor',
50
- 'box',
51
- 'bell',
52
- 'message',
53
- 'send',
54
- 'file',
55
- 'folder',
56
- 'save',
57
- 'print',
58
- 'clock',
59
- 'calendar',
60
- 'timer',
61
- 'lock',
62
- 'unlock',
63
- 'chart',
64
- 'table',
65
- 'database',
66
- 'home',
67
- 'menu',
68
- 'arrowLeft',
69
- 'arrowRight',
70
- 'copy',
71
- 'filter',
72
- 'sort',
73
- 'help',
74
- 'warning',
75
- 'dashboard',
76
- 'settingsApplications',
77
- 'route',
78
- 'developerBoard',
79
- 'directions',
80
- 'category',
81
- 'logout',
82
- 'sun',
83
- 'moon',
84
- 'default',
85
- ];
86
1
  export const BASE_ICON_COLORS = {
87
2
  primary: '#003775c8',
88
3
  secondary: '#6b7280',
@@ -96,213 +11,12 @@ export const DISABLED_OPACITY = 0.5;
96
11
  export const SECONDARY_WARN_OPACITY = 0.7;
97
12
  export const DEFAULT_OPACITY = 1;
98
13
  export const BASE_ICON_SIZE = 24;
99
- /**
100
- * ICON PATHS - SVG path definitions
101
- *
102
- * IMPORTANTE: Al crear o modificar iconos, SIEMPRE buscar primero en Material Design Icons oficial:
103
- * - Repositorio: https://github.com/google/material-design-icons
104
- * - Navegador: https://fonts.google.com/icons
105
- * - Usar paths oficiales de Material Design siempre que sea posible
106
- * - ViewBox: 24x24 (compatible con BASE_ICON_SIZE)
107
- * - Máximo 300 caracteres por línea (usar concatenación con + si es necesario)
108
- */
109
- export const ICON_PATHS = {
110
- check: 'M5 13l4 4L19 7',
111
- cancel: 'M6 6l12 12M6 18L18 6',
112
- edit: 'M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4 12.5-12.5z',
113
- delete: 'M6 19a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z',
114
- add: 'M12 5v14M5 12h14',
115
- view: 'M12 5C7 5 2.73 8.11 1 12c1.73 3.89 6 7 11 7s9.27-3.11 11-7c-1.73-3.89-6-7-11-7z',
116
- get: 'm8.5 8.5 7 7',
117
- settings: 'M12 1v6m0 6v10M3.34 7l5.2 3M15.46 14l5.2 3M3.34 17l5.2-3M15.46 10l5.2-3',
118
- schedule: 'M12 6v6l4 2',
119
- refresh: 'M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8M21 3v5h-5M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16M3 21v-5h5',
120
- checkCircle: 'm9 12 2 2 4-4',
121
- cancelCircle: 'm15 9-6 6m0-6 6 6',
122
- error: 'M15 9L9 15M9 9l6 6',
123
- queue: 'M3 12h18m-9-9v18',
124
- arrowUp: 'm18 15-6-6-6 6',
125
- arrowDown: 'm6 9 6 6 6-6',
126
- toggleOn: '',
127
- toggleOff: '',
128
- search: 'm21 21-6-6m2-5a7 7 0 1 1-14 0 7 7 0 0 1 14 0z',
129
- upload: 'M12 15V3m0 0l-4 4m4-4l4 4M2 17l.621 2.485A2 2 0 0 0 4.561 21h14.878a2 2 0 0 0 1.94-1.515L22 17',
130
- pendingActions: 'M12 8v4l3 3m6-3a9 9 0 1 1-18 0 9 9 0 0 1 18 0z',
131
- playCircle: 'M14.752 11.168l-3.197-2.132A1 1 0 0 0 10 9.87v4.263a1 1 0 0 0 1.555.832l3.197-2.132a1 1 0 0 0 0-1.664z',
132
- play: 'M8 5v14l11-7z',
133
- stop: 'M6 6h12v12H6z',
134
- // Material Design: tune (adjustments/sliders)
135
- tune: 'M3 17v2h6v-2H3zM3 5v2h10V5H3zm10 16v-2h8v-2h-8v-2h-2v6h2zM7 9v2H3v2h4v2h2V9H7zm14 4v-2H11v2h10zm-6-4h2V7h4V5h-4V3h-2v6z',
136
- visibility: 'M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5z',
137
- visibilityOff: 'M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7z' +
138
- 'M2 4.27l2.28 2.28.46.46A11.804 11.804 0 0 0 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27z' +
139
- 'M7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2z' +
140
- 'm4.31-.78 3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z',
141
- close: 'M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z',
142
- record: '',
143
- star: 'M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z',
144
- xCircle: 'M15 9l-6 6m0-6l6 6',
145
- key: 'M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4',
146
- exclamationTriangle: 'M12 9v4m0 4h.01',
147
- clipboard: 'M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2',
148
- download: 'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4m4-5l5 5m0 0l5-5m-5 5V3',
149
- shield: 'M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z',
150
- // Material Design: person (single user)
151
- person: 'M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z',
152
- envelope: 'M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z',
153
- infoCircle: 'M12 16v-4m0-4h.01',
154
- checkSquare: 'm9 11 3 3L22 4',
155
- square: '',
156
- dashSquare: 'M8 12h8',
157
- people: 'M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3z' +
158
- 'm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z',
159
- boxSeam: 'M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z',
160
- personBadge: 'M12 2L4 6v5c0 5.55 3.84 10.74 8 12 4.16-1.26 8-6.45 8-12V6l-8-4z',
161
- listTask: 'M9 6h12M9 12h12M9 18h12',
162
- shuffle: 'M16 3h5v5M4 20L21 3M21 16v5h-5M15 15l6 6M4 4l5 5',
163
- motor: 'M9 3v3m6-3v3M9 18v3m6-3v3M3 9h3M3 15h3m12-6h3m-3 6h3',
164
- box: 'M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8z',
165
- bell: 'M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9M13.73 21a2 2 0 0 1-3.46 0',
166
- message: 'M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z',
167
- send: 'M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z',
168
- file: 'M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z',
169
- folder: 'M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z',
170
- save: 'M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z',
171
- print: 'M6 9V2h12v7M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2',
172
- clock: 'M12 6v6l4 2',
173
- calendar: 'M8 2v4m8-4v4M3 10h18',
174
- timer: 'M12 8v4l2 2',
175
- lock: 'M19 11H5a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7a2 2 0 0 0-2-2zM7 11V7a5 5 0 0 1 10 0v4',
176
- unlock: 'M19 11H5a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7a2 2 0 0 0-2-2zM7 11V7a5 5 0 0 1 9.9-1',
177
- chart: 'M3 3v18h18M7 16l4-4 4 4 6-6',
178
- table: 'M3 3h18v18H3zM3 9h18M3 15h18M9 3v18',
179
- database: 'M12 8c-4.97 0-9-1.34-9-3s4.03-3 9-3 9 1.34 9 3-4.03 3-9 3zM3 5v5c0 1.66 4.03 3 9 3s9-1.34 9-3V5M3 10v5c0 1.66 4.03 3 9 3s9-1.34 9-3v-5',
180
- home: 'm3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z',
181
- menu: 'M3 12h18M3 6h18M3 18h18',
182
- arrowLeft: 'm19 12H5m0 0 7 7m-7-7 7-7',
183
- arrowRight: 'm5 12 7 7m0 0 5-5m-5 5V5',
184
- copy: 'M8 4v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V7.242a2 2 0 0 0-.602-1.43L16.083 2.57A2 2 0 0 0 14.685 2H10a2 2 0 0 0-2 2z',
185
- filter: 'M22 3H2l8 9.46V19l4 2v-8.54L22 3z',
186
- sort: 'M11 5h10M11 9h7M11 13h4M3 17l3 3m0 0l3-3m-3 3V4',
187
- help: 'M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3m.08 4h.01',
188
- warning: 'M12 9v4',
189
- dashboard: 'M3 13h8V3H3zm0 8h8v-6H3zm10 0h8V11h-8zm0-18v6h8V3z',
190
- // Material Design: settings_applications (system profiles/configuration)
191
- settingsApplications: 'M12 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm7-7H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2z' +
192
- 'm-1.75 9c0 .23-.02.46-.05.68l1.48 1.16c.13.11.17.3.08.45l-1.4 2.42c-.09.15-.27.21-.43.15l-1.74-.7c-.36.28-.76.51-1.18.69l-.26 1.85c-.03.17-.18.3-.35.3h-2.8' +
193
- 'c-.17 0-.32-.13-.35-.29l-.26-1.85c-.43-.18-.82-.41-1.18-.69l-1.74.7c-.16.06-.34 0-.43-.15l-1.4-2.42c-.09-.15-.05-.34.08-.45l1.48-1.16c-.03-.23-.05-.46-.05-.69 0-.23.02-.46.05-.68' +
194
- 'l-1.48-1.16c-.13-.11-.17-.3-.08-.45l1.4-2.42c.09-.15.27-.21.43-.15l1.74.7c.36-.28.76-.51 1.18-.69l.26-1.85c.03-.17.18-.3.35-.3h2.8' +
195
- 'c.17 0 .32.13.35.29l.26 1.85c.43.18.82.41 1.18.69l1.74-.7c.16-.06.34 0 .43.15l1.4 2.42c.09.15.05.34-.08.45l-1.48 1.16c.03.23.05.46.05.69z',
196
- route: 'M19 15.18V7c0-2.21-1.79-4-4-4s-4 1.79-4 4v10c0 1.1-.9 2-2 2s-2-.9-2-2V8.82C8.16 8.4 9 7.3 9 6c0-1.66-1.34-3-3-3S3 4.34 3 6c0 1.3.84 2.4 2 2.82V17c0 2.21 1.79 4 4 4s4-1.79 4-4V7c0-1.1.9-2 2-2s2 .9 2 2v8.18A2.996 2.996 0 0 0 15 18c0 1.66 1.34 3 3 3s3-1.34 3-3c0-1.3-.84-2.4-2-2.82z',
197
- developerBoard: 'M9 2v4m6-4v4M9 18v4m6-18v4M2 9h4M2 15h4m16-6h4m-4 6h4',
198
- // Material Design: directions (map navigation icon with arrow)
199
- directions: 'm21.41 10.59-7.99-8c-.78-.78-2.05-.78-2.83 0l-8.01 8c-.78.78-.78 2.05 0 2.83l8.01 8c.78.78 2.05.78 2.83 0l7.99-8c.79-.79.79-2.05 0-2.83zM13.5 14.5V12H10v3H8v-4c0-.55.45-1 1-1h4.5V7.5L17 11l-3.5 3.5z',
200
- category: 'M12 2 6.5 11h11z',
201
- logout: 'M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4m7 14 5-5m0 0-5-5m5 5H9',
202
- // Material Design: light_mode (sun icon)
203
- sun: 'M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zM2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1zm18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1z' +
204
- 'M11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1zm0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1z' +
205
- 'M5.99 4.58c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41L5.99 4.58zm12.37 12.37c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0 .39-.39.39-1.03 0-1.41l-1.06-1.06z' +
206
- 'm1.06-10.96c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06zM7.05 18.36c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06z',
207
- // Material Design: dark_mode (moon icon)
208
- moon: 'M9.37 5.51C9.19 6.15 9.1 6.82 9.1 7.5c0 4.08 3.32 7.4 7.4 7.4.68 0 1.35-.09 1.99-.27C17.45 17.19 14.93 19 12 19c-3.86 0-7-3.14-7-7 0-2.93 1.81-5.45 4.37-6.49z' +
209
- 'M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-2.98 0-5.4-2.42-5.4-5.4 0-1.81.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1z',
210
- default: '',
211
- };
212
- export const ICON_ADDITIONAL_SHAPES = {
213
- view: [{ type: 'circle', cx: '12', cy: '12', r: '3' }],
214
- get: [
215
- { type: 'circle', cx: '6', cy: '6', r: '3' },
216
- { type: 'circle', cx: '18', cy: '18', r: '3' },
217
- { type: 'path', d: 'm13 11 2 2-2 2' },
218
- ],
219
- settings: [{ type: 'circle', cx: '12', cy: '12', r: '3' }],
220
- schedule: [{ type: 'circle', cx: '12', cy: '12', r: '10' }],
221
- checkCircle: [{ type: 'circle', cx: '12', cy: '12', r: '10' }],
222
- cancelCircle: [{ type: 'circle', cx: '12', cy: '12', r: '10' }],
223
- error: [{ type: 'circle', cx: '12', cy: '12', r: '10' }],
224
- queue: [
225
- { type: 'rect', x: '2', y: '3', width: '20', height: '6', rx: '1' },
226
- { type: 'rect', x: '2', y: '15', width: '20', height: '6', rx: '1' },
227
- ],
228
- toggleOn: [
229
- { type: 'rect', x: '2', y: '7', width: '20', height: '10', rx: '5' },
230
- { type: 'circle', cx: '18', cy: '12', r: '4', fill: 'color' },
231
- ],
232
- toggleOff: [
233
- { type: 'rect', x: '2', y: '7', width: '20', height: '10', rx: '5' },
234
- { type: 'circle', cx: '6', cy: '12', r: '4', fill: 'color' },
235
- ],
236
- playCircle: [{ type: 'circle', cx: '12', cy: '12', r: '10' }],
237
- visibility: [{ type: 'circle', cx: '12', cy: '12', r: '3' }],
238
- record: [{ type: 'circle', cx: '12', cy: '12', r: '5', fill: 'color' }],
239
- xCircle: [{ type: 'circle', cx: '12', cy: '12', r: '10' }],
240
- exclamationTriangle: [{ type: 'path', d: 'M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z' }],
241
- person: [],
242
- envelope: [{ type: 'path', d: 'm22 6-10 7L2 6' }],
243
- infoCircle: [{ type: 'circle', cx: '12', cy: '12', r: '10' }],
244
- checkSquare: [{ type: 'rect', x: '3', y: '3', width: '18', height: '18', rx: '2' }],
245
- square: [{ type: 'rect', x: '3', y: '3', width: '18', height: '18', rx: '2' }],
246
- dashSquare: [{ type: 'rect', x: '3', y: '3', width: '18', height: '18', rx: '2' }],
247
- people: [],
248
- boxSeam: [{ type: 'path', d: 'M21 8.5v7c0 .6-.2 1.2-.6 1.7l-7 4c-.3.2-.6.3-1 .3-.3 0-.7-.1-1-.3l-7-4c-.4-.5-.6-1.1-.6-1.7v-7c0-.6.2-1.2.6-1.7l7-4c.6-.4 1.4-.4 2 0l7 4c.4.5.6 1.1.6 1.7z' }, { type: 'path', d: 'M3.3 7L12 12l8.7-5M12 22.5V12' }],
249
- personBadge: [
250
- { type: 'circle', cx: '12', cy: '12', r: '1.5' },
251
- { type: 'path', d: 'M12 9.5v1m0 3v1m2.5-2.5h-1m-3 0h-1' }
252
- ],
253
- listTask: [
254
- { type: 'path', d: 'M3 5l1.5 1.5L7 4' },
255
- { type: 'path', d: 'M3 11l1.5 1.5L7 10' },
256
- { type: 'path', d: 'M3 17l1.5 1.5L7 16' },
257
- ],
258
- shuffle: [],
259
- motor: [
260
- { type: 'circle', cx: '12', cy: '12', r: '8' },
261
- { type: 'circle', cx: '12', cy: '12', r: '3', fill: 'color' },
262
- { type: 'path', d: 'M12 4v2m0 12v2M4 12h2m12 0h2M7.05 7.05l1.42 1.42m7.07 7.07l1.41 1.41M7.05 16.95l1.42-1.42m7.07-7.07l1.41-1.41' }
263
- ],
264
- box: [{ type: 'path', d: 'M12 2.7L3.3 7v9.3l8.7 5 8.7-5V7L12 2.7z' }, { type: 'path', d: 'M12 22V12M3.3 7L12 12l8.7-5' }],
265
- bell: [],
266
- message: [],
267
- send: [],
268
- file: [{ type: 'path', d: 'M13 2v7h7' }],
269
- folder: [],
270
- save: [{ type: 'path', d: 'M15 3v6h4M9 21v-8h6v8' }],
271
- print: [{ type: 'rect', x: '6', y: '14', width: '12', height: '8', rx: '1' }],
272
- clock: [{ type: 'circle', cx: '12', cy: '12', r: '10' }],
273
- calendar: [{ type: 'rect', x: '3', y: '4', width: '18', height: '18', rx: '2' }],
274
- timer: [{ type: 'circle', cx: '12', cy: '13', r: '9' }, { type: 'path', d: 'M9 2h6' }],
275
- lock: [],
276
- unlock: [],
277
- chart: [],
278
- table: [],
279
- database: [],
280
- home: [{ type: 'path', d: 'M9 22V12h6v10' }],
281
- menu: [],
282
- arrowLeft: [],
283
- arrowRight: [],
284
- copy: [{ type: 'rect', x: '4', y: '8', width: '12', height: '12', rx: '2' }],
285
- filter: [],
286
- sort: [],
287
- help: [{ type: 'circle', cx: '12', cy: '12', r: '10' }],
288
- warning: [{ type: 'circle', cx: '12', cy: '12', r: '10' }, { type: 'circle', cx: '12', cy: '17', r: '0.5', fill: 'color' }],
289
- dashboard: [],
290
- settingsApplications: [],
291
- route: [],
292
- developerBoard: [
293
- { type: 'rect', x: '5', y: '5', width: '14', height: '14', rx: '2' },
294
- { type: 'rect', x: '9', y: '9', width: '6', height: '6', rx: '0.5' },
295
- { type: 'circle', cx: '12', cy: '12', r: '1.5', fill: 'color' },
296
- ],
297
- directions: [],
298
- category: [
299
- { type: 'circle', cx: '17.5', cy: '17.5', r: '3.5' },
300
- { type: 'rect', x: '3', y: '14', width: '7', height: '7', rx: '1' },
301
- ],
302
- logout: [],
303
- sun: [],
304
- moon: [],
305
- default: [{ type: 'circle', cx: '12', cy: '12', r: '10' }],
306
- edit: [{ type: 'rect', x: '5', y: '19', width: '14', height: '2', rx: '1' }],
14
+ // Optimización: Colores que requieren opacidad reducida
15
+ export const OPACITY_REDUCED_COLORS = ['secondary', 'warn'];
16
+ // Optimización: Atributos SVG comunes
17
+ export const SVG_STROKE_ATTRS = {
18
+ strokeWidth: '1',
19
+ strokeLinecap: 'round',
20
+ strokeLinejoin: 'round'
307
21
  };
308
22
  //# sourceMappingURL=icon.constants.js.map