@c80/ui 1.0.53 → 1.0.56

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 (103) hide show
  1. package/esm2022/index.js +5 -0
  2. package/esm2022/index.js.map +1 -1
  3. package/esm2022/lib/action-list/action-list.component.js +23 -0
  4. package/esm2022/lib/action-list/action-list.component.js.map +1 -0
  5. package/esm2022/lib/action-list/action-list.types.js +2 -0
  6. package/esm2022/lib/action-list/action-list.types.js.map +1 -0
  7. package/esm2022/lib/action-list/index.js +3 -0
  8. package/esm2022/lib/action-list/index.js.map +1 -0
  9. package/esm2022/lib/card-level/card-level.component.js +7 -0
  10. package/esm2022/lib/card-level/card-level.component.js.map +1 -1
  11. package/esm2022/lib/header/header.component.js +18 -0
  12. package/esm2022/lib/header/header.component.js.map +1 -0
  13. package/esm2022/lib/header/header.types.js +2 -0
  14. package/esm2022/lib/header/header.types.js.map +1 -0
  15. package/esm2022/lib/header/index.js +3 -0
  16. package/esm2022/lib/header/index.js.map +1 -0
  17. package/esm2022/lib/icon/icon.component.js +36 -15
  18. package/esm2022/lib/icon/icon.component.js.map +1 -1
  19. package/esm2022/lib/icon/icon.constants.js +10 -294
  20. package/esm2022/lib/icon/icon.constants.js.map +1 -1
  21. package/esm2022/lib/icon/icon.definitions.js +393 -0
  22. package/esm2022/lib/icon/icon.definitions.js.map +1 -0
  23. package/esm2022/lib/icon/icon.types.js.map +1 -1
  24. package/esm2022/lib/icon/icon.utils.js +17 -0
  25. package/esm2022/lib/icon/icon.utils.js.map +1 -1
  26. package/esm2022/lib/icon/index.js +1 -0
  27. package/esm2022/lib/icon/index.js.map +1 -1
  28. package/esm2022/lib/icon/theme.service.js +39 -0
  29. package/esm2022/lib/icon/theme.service.js.map +1 -0
  30. package/esm2022/lib/info-list/index.js +3 -0
  31. package/esm2022/lib/info-list/index.js.map +1 -0
  32. package/esm2022/lib/info-list/info-list.component.js +12 -0
  33. package/esm2022/lib/info-list/info-list.component.js.map +1 -0
  34. package/esm2022/lib/info-list/info-list.types.js +2 -0
  35. package/esm2022/lib/info-list/info-list.types.js.map +1 -0
  36. package/esm2022/lib/input-field/index.js +2 -0
  37. package/esm2022/lib/input-field/index.js.map +1 -0
  38. package/esm2022/lib/input-field/input-field.component.js +37 -0
  39. package/esm2022/lib/input-field/input-field.component.js.map +1 -0
  40. package/esm2022/lib/modal/modal.component.js +6 -6
  41. package/esm2022/lib/modal/modal.component.js.map +1 -1
  42. package/esm2022/lib/profile-stats/index.js +3 -0
  43. package/esm2022/lib/profile-stats/index.js.map +1 -0
  44. package/esm2022/lib/profile-stats/profile-stats.component.js +12 -0
  45. package/esm2022/lib/profile-stats/profile-stats.component.js.map +1 -0
  46. package/esm2022/lib/profile-stats/profile-stats.types.js +2 -0
  47. package/esm2022/lib/profile-stats/profile-stats.types.js.map +1 -0
  48. package/esm2022/lib/stat-card/stat-card.component.js +6 -6
  49. package/esm2022/lib/stat-card/stat-card.component.js.map +1 -1
  50. package/esm2022/lib/tab/c80-tab.component.js +6 -6
  51. package/esm2022/lib/tab/c80-tab.component.js.map +1 -1
  52. package/esm2022/lib/tab/directives/c80-tab-item.directive.js.map +1 -0
  53. package/esm2022/lib/tab/directives/c80-tab-label.directive.js.map +1 -0
  54. package/esm2022/lib/tab/index.js +3 -3
  55. package/esm2022/lib/tab/index.js.map +1 -1
  56. package/esm2022/lib/table/table-column-visibility.service.js.map +1 -1
  57. package/esm2022/lib/table/table-crud-state.service.js.map +1 -1
  58. package/esm2022/lib/table/table-data-converter.service.js.map +1 -1
  59. package/esm2022/lib/table/table-data-utils.service.js.map +1 -1
  60. package/esm2022/lib/table/table.component.js +26 -7
  61. package/esm2022/lib/table/table.component.js.map +1 -1
  62. package/esm2022/lib/table/table.types.js.map +1 -1
  63. package/esm2022/lib/table/table.utils.js.map +1 -1
  64. package/index.d.ts +5 -0
  65. package/lib/action-list/action-list.component.d.ts +10 -0
  66. package/lib/action-list/action-list.types.d.ts +8 -0
  67. package/lib/action-list/index.d.ts +2 -0
  68. package/lib/header/header.component.d.ts +9 -0
  69. package/lib/header/header.types.d.ts +3 -0
  70. package/lib/header/index.d.ts +2 -0
  71. package/lib/icon/icon.component.d.ts +17 -5
  72. package/lib/icon/icon.constants.d.ts +9 -14
  73. package/lib/icon/icon.definitions.d.ts +16 -0
  74. package/lib/icon/icon.types.d.ts +43 -6
  75. package/lib/icon/icon.utils.d.ts +5 -0
  76. package/lib/icon/index.d.ts +1 -0
  77. package/lib/icon/theme.service.d.ts +10 -0
  78. package/lib/info-list/index.d.ts +2 -0
  79. package/lib/info-list/info-list.component.d.ts +7 -0
  80. package/lib/info-list/info-list.types.d.ts +4 -0
  81. package/lib/input-field/index.d.ts +1 -0
  82. package/lib/input-field/input-field.component.d.ts +19 -0
  83. package/lib/modal/modal.component.d.ts +3 -3
  84. package/lib/profile-stats/index.d.ts +2 -0
  85. package/lib/profile-stats/profile-stats.component.d.ts +7 -0
  86. package/lib/profile-stats/profile-stats.types.d.ts +4 -0
  87. package/lib/stat-card/stat-card.component.d.ts +3 -3
  88. package/lib/tab/c80-tab.component.d.ts +5 -5
  89. package/lib/tab/index.d.ts +3 -3
  90. package/lib/table/table-column-visibility.service.d.ts +5 -5
  91. package/lib/table/table-crud-state.service.d.ts +3 -3
  92. package/lib/table/table-data-converter.service.d.ts +2 -2
  93. package/lib/table/table-data-utils.service.d.ts +6 -6
  94. package/lib/table/table.component.d.ts +14 -14
  95. package/lib/table/table.types.d.ts +1 -1
  96. package/lib/table/table.utils.d.ts +2 -2
  97. package/package.json +1 -1
  98. package/esm2022/lib/tab/c80-tab-item.directive.js.map +0 -1
  99. package/esm2022/lib/tab/c80-tab-label.directive.js.map +0 -1
  100. /package/esm2022/lib/tab/{c80-tab-item.directive.js → directives/c80-tab-item.directive.js} +0 -0
  101. /package/esm2022/lib/tab/{c80-tab-label.directive.js → directives/c80-tab-label.directive.js} +0 -0
  102. /package/lib/tab/{c80-tab-item.directive.d.ts → directives/c80-tab-item.directive.d.ts} +0 -0
  103. /package/lib/tab/{c80-tab-label.directive.d.ts → directives/c80-tab-label.directive.d.ts} +0 -0
package/esm2022/index.js CHANGED
@@ -6,4 +6,9 @@ export * from './lib/modal';
6
6
  export * from './lib/select';
7
7
  export * from './lib/snackbar';
8
8
  export * from './lib/tab';
9
+ export * from './lib/info-list';
10
+ export * from './lib/action-list';
11
+ export * from './lib/header';
12
+ export * from './lib/profile-stats';
13
+ export * from './lib//input-field';
9
14
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../libs/ui/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC","sourcesContent":["export * from './lib/table';\nexport * from './lib/icon';\nexport * from './lib/stat-card';\nexport * from './lib/card-level';\nexport * from './lib/modal';\nexport * from './lib/select';\nexport * from './lib/snackbar';\nexport * from './lib/tab';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../libs/ui/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC","sourcesContent":["export * from './lib/table';\nexport * from './lib/icon';\nexport * from './lib/stat-card';\nexport * from './lib/card-level';\nexport * from './lib/modal';\nexport * from './lib/select';\nexport * from './lib/snackbar';\nexport * from './lib/tab';\nexport * from './lib/info-list';\nexport * from './lib/action-list';\nexport * from './lib/header';\nexport * from './lib/profile-stats';\nexport * from './lib//input-field';\n"]}
@@ -0,0 +1,23 @@
1
+ import { Component, input, output, ChangeDetectionStrategy } from '@angular/core';
2
+ import { IconComponent } from '../icon';
3
+ import * as i0 from "@angular/core";
4
+ export class ActionListComponent {
5
+ title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
6
+ actions = input([], ...(ngDevMode ? [{ debugName: "actions" }] : []));
7
+ actionClick = output();
8
+ onActionClick(action) {
9
+ if (typeof action.action === 'string') {
10
+ this.actionClick.emit(action.action);
11
+ }
12
+ else if (typeof action.action === 'function') {
13
+ action.action();
14
+ }
15
+ }
16
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ActionListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
17
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: ActionListComponent, isStandalone: true, selector: "c80-action-list", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionClick: "actionClick" }, ngImport: i0, template: "<div class=\"action-list\">\n @if (title()) {\n <h2 class=\"action-list__title\">{{ title() }}</h2>\n }\n\n @for (action of actions(); track $index) {\n <button class=\"action-list__item\" [class.action-list__item--danger]=\"action.isDanger\" [class.action-list__item--navigable]=\"action.isNavigable\" (click)=\"onActionClick(action)\">\n\n <div class=\"action-list__info\">\n <span class=\"action-list__label\">{{ action.label }}</span>\n @if (action.description) {\n <span class=\"action-list__description\">{{ action.description }}</span>\n }\n </div>\n\n @if (action.icon || action.isNavigable) {\n <c80-icon [button]=\"!action.isNavigable\" [icon]=\"action.icon || (action.isNavigable ? 'arrowRight' : '')\" [color]=\"action.isDanger ? 'warn' : undefined\" [title]=\"action.label\" />\n }\n </button>\n }\n</div>", styles: [".action-list__title{font-size:.875rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--color-text-secondary);margin:1rem 0px .4rem}.action-list__item{display:flex;justify-content:space-between;align-items:center;padding:1rem;background:var(--color-surface);border-radius:var(--radius-lg);margin-bottom:.75rem;border:none;width:100%;text-align:left;cursor:pointer;transition:all var(--transition-base)}.action-list__item:hover{transform:translate(2px);background:var(--color-bg-dark)}.action-list__item:last-child{margin-bottom:0}.action-list__item--danger .action-list__label{color:var(--color-accent)}.action-list__item--navigable:hover{transform:translate(2px);background:var(--color-bg-dark)}.action-list__info{display:flex;flex-direction:column;gap:.25rem}.action-list__label{font-size:1rem;font-weight:500;color:var(--color-text-primary)}.action-list__description{font-size:.875rem;color:var(--color-text-secondary)}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "c80-icon", inputs: ["icon", "color", "customColor", "disabled", "size", "button", "border", "type", "textLeft", "textRight", "dark"], outputs: ["iconClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
18
+ }
19
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ActionListComponent, decorators: [{
20
+ type: Component,
21
+ args: [{ selector: 'c80-action-list', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"action-list\">\n @if (title()) {\n <h2 class=\"action-list__title\">{{ title() }}</h2>\n }\n\n @for (action of actions(); track $index) {\n <button class=\"action-list__item\" [class.action-list__item--danger]=\"action.isDanger\" [class.action-list__item--navigable]=\"action.isNavigable\" (click)=\"onActionClick(action)\">\n\n <div class=\"action-list__info\">\n <span class=\"action-list__label\">{{ action.label }}</span>\n @if (action.description) {\n <span class=\"action-list__description\">{{ action.description }}</span>\n }\n </div>\n\n @if (action.icon || action.isNavigable) {\n <c80-icon [button]=\"!action.isNavigable\" [icon]=\"action.icon || (action.isNavigable ? 'arrowRight' : '')\" [color]=\"action.isDanger ? 'warn' : undefined\" [title]=\"action.label\" />\n }\n </button>\n }\n</div>", styles: [".action-list__title{font-size:.875rem;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--color-text-secondary);margin:1rem 0px .4rem}.action-list__item{display:flex;justify-content:space-between;align-items:center;padding:1rem;background:var(--color-surface);border-radius:var(--radius-lg);margin-bottom:.75rem;border:none;width:100%;text-align:left;cursor:pointer;transition:all var(--transition-base)}.action-list__item:hover{transform:translate(2px);background:var(--color-bg-dark)}.action-list__item:last-child{margin-bottom:0}.action-list__item--danger .action-list__label{color:var(--color-accent)}.action-list__item--navigable:hover{transform:translate(2px);background:var(--color-bg-dark)}.action-list__info{display:flex;flex-direction:column;gap:.25rem}.action-list__label{font-size:1rem;font-weight:500;color:var(--color-text-primary)}.action-list__description{font-size:.875rem;color:var(--color-text-secondary)}\n"] }]
22
+ }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], actionClick: [{ type: i0.Output, args: ["actionClick"] }] } });
23
+ //# sourceMappingURL=action-list.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-list.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/action-list/action-list.component.ts","../../../../../libs/ui/src/lib/action-list/action-list.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAElF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;;AAUxC,MAAM,OAAO,mBAAmB;IAC5B,KAAK,GAAG,KAAK,CAAS,EAAE,iDAAC,CAAC;IAC1B,OAAO,GAAG,KAAK,CAAe,EAAE,mDAAC,CAAC;IAElC,WAAW,GAAG,MAAM,EAAU,CAAC;IAErB,aAAa,CAAC,MAAkB;QACtC,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;aAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAC7C,MAAM,CAAC,MAAM,EAAE,CAAC;QACpB,CAAC;IACL,CAAC;wGAZQ,mBAAmB;4FAAnB,mBAAmB,sXCZhC,w5BAoBM,8+BDbQ,aAAa;;4FAKd,mBAAmB;kBAR/B,SAAS;+BACI,iBAAiB,cACf,IAAI,WACP,CAAC,aAAa,CAAC,mBAGP,uBAAuB,CAAC,MAAM","sourcesContent":["import { Component, input, output, ChangeDetectionStrategy } from '@angular/core';\nimport type { ActionItem } from './action-list.types';\nimport { IconComponent } from '../icon';\n\n@Component({\n selector: 'c80-action-list',\n standalone: true,\n imports: [IconComponent],\n templateUrl: './action-list.component.html',\n styleUrl: './action-list.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ActionListComponent {\n title = input<string>('');\n actions = input<ActionItem[]>([]);\n\n actionClick = output<string>();\n\n protected onActionClick(action: ActionItem): void {\n if (typeof action.action === 'string') {\n this.actionClick.emit(action.action);\n } else if (typeof action.action === 'function') {\n action.action();\n }\n }\n}","<div class=\"action-list\">\n @if (title()) {\n <h2 class=\"action-list__title\">{{ title() }}</h2>\n }\n\n @for (action of actions(); track $index) {\n <button class=\"action-list__item\" [class.action-list__item--danger]=\"action.isDanger\" [class.action-list__item--navigable]=\"action.isNavigable\" (click)=\"onActionClick(action)\">\n\n <div class=\"action-list__info\">\n <span class=\"action-list__label\">{{ action.label }}</span>\n @if (action.description) {\n <span class=\"action-list__description\">{{ action.description }}</span>\n }\n </div>\n\n @if (action.icon || action.isNavigable) {\n <c80-icon [button]=\"!action.isNavigable\" [icon]=\"action.icon || (action.isNavigable ? 'arrowRight' : '')\" [color]=\"action.isDanger ? 'warn' : undefined\" [title]=\"action.label\" />\n }\n </button>\n }\n</div>"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=action-list.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-list.types.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/action-list/action-list.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface ActionItem {\n label: string;\n description?: string;\n icon?: string;\n action?: string | (() => void);\n isDanger?: boolean;\n isNavigable?: boolean;\n}"]}
@@ -0,0 +1,3 @@
1
+ export * from './action-list.component';
2
+ export * from './action-list.types';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/action-list/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC","sourcesContent":["export * from './action-list.component';\nexport * from './action-list.types';"]}
@@ -1,37 +1,44 @@
1
1
  import { Component, input, computed, ChangeDetectionStrategy } from '@angular/core';
2
2
  import * as i0 from "@angular/core";
3
3
  export class CardLevelComponent {
4
+ /* v8 ignore next */
4
5
  cardLevelData = input.required(...(ngDevMode ? [{ debugName: "cardLevelData" }] : []));
5
6
  /* v8 ignore next */
6
7
  size = input(1, ...(ngDevMode ? [{ debugName: "size" }] : [])); // Multiplicador del tamaño base (220px)
7
8
  // ID único generado para el componente
9
+ /* v8 ignore next 5 */
8
10
  generatedId = computed(() => {
9
11
  const label = this.cardLevelData().label.toLowerCase().replaceAll(/\s+/g, '-');
10
12
  const randomNum = Math.floor(Math.random() * 10000);
11
13
  return `${label}-${randomNum}`;
12
14
  }, ...(ngDevMode ? [{ debugName: "generatedId" }] : []));
13
15
  // Ancho calculado de la card
16
+ /* v8 ignore next 4 */
14
17
  cardWidth = computed(() => {
15
18
  const baseWidth = 140;
16
19
  const calculatedWidth = baseWidth * this.size();
17
20
  return `${calculatedWidth}px`;
18
21
  }, ...(ngDevMode ? [{ debugName: "cardWidth" }] : []));
19
22
  // Detecta si el rango es bidireccional (min negativo, max positivo)
23
+ /* v8 ignore next 4 */
20
24
  isBidirectional = computed(() => {
21
25
  const data = this.cardLevelData();
22
26
  return data.min < 0 && data.max > 0;
23
27
  }, ...(ngDevMode ? [{ debugName: "isBidirectional" }] : []));
24
28
  // Calcula el porcentaje de fill para barras bidireccionales
29
+ /* v8 ignore next 4 */
25
30
  bidirectionalFillPercent = computed(() => {
26
31
  const data = this.cardLevelData();
27
32
  const totalRange = data.max - data.min;
28
33
  return Math.abs(data.value / totalRange) * 100;
29
34
  }, ...(ngDevMode ? [{ debugName: "bidirectionalFillPercent" }] : []));
30
35
  // Determina la dirección del fill (left/right)
36
+ /* v8 ignore next 3 */
31
37
  fillDirection = computed(() => {
32
38
  return this.cardLevelData().value >= 0 ? 'right' : 'left';
33
39
  }, ...(ngDevMode ? [{ debugName: "fillDirection" }] : []));
34
40
  // Color según el valor y umbrales
41
+ /* v8 ignore next 11 */
35
42
  fillColor = computed(() => {
36
43
  const data = this.cardLevelData();
37
44
  const absValue = Math.abs(data.value);
@@ -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,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
+ {"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,oBAAoB;IACpB,aAAa,GAAG,KAAK,CAAC,QAAQ,wDAAiB,CAAC;IAChD,oBAAoB;IACpB,IAAI,GAAG,KAAK,CAAS,CAAC,gDAAC,CAAC,CAAC,wCAAwC;IAEjE,uCAAuC;IACvC,sBAAsB;IACb,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;IAC7B,sBAAsB;IACb,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,sBAAsB;IACtB,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,sBAAsB;IACtB,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,sBAAsB;IACtB,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,uBAAuB;IACvB,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;wGA1DQ,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 /* v8 ignore next */\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 /* v8 ignore next 5 */\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 /* v8 ignore next 4 */\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 /* v8 ignore next 4 */\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 /* v8 ignore next 4 */\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 /* v8 ignore next 3 */\n fillDirection = computed(() => {\n return this.cardLevelData().value >= 0 ? 'right' : 'left';\n });\n\n // Color según el valor y umbrales\n /* v8 ignore next 11 */\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 -->"]}
@@ -0,0 +1,18 @@
1
+ import { Location } from '@angular/common';
2
+ import { ChangeDetectionStrategy, Component, inject, input } from '@angular/core';
3
+ import { IconComponent } from '../icon';
4
+ import * as i0 from "@angular/core";
5
+ export class HeaderComponent {
6
+ location = inject(Location);
7
+ config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
8
+ onBackClick() {
9
+ this.location.back();
10
+ }
11
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: HeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.10", type: HeaderComponent, isStandalone: true, selector: "c80-header", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<header class=\"header\">\n <c80-icon button icon=\"arrowLeft\" [size]=\"1.2\" (iconClick)=\"onBackClick()\" title=\"Volver\" class=\"header__back-btn\" />\n <h1 class=\"header__title\">{{ config().title }}</h1>\n <span class=\"header__spacer\"></span>\n</header>", styles: [".header{display:flex;align-items:center;gap:1rem;margin-bottom:2rem;padding:1rem;border-bottom:1px solid var(--color-border)}.header__back-btn{flex-shrink:0}.header__title{font-size:1.5rem;font-weight:600;color:var(--color-text-primary);margin:0}.header__spacer{flex:1}@media(max-width:768px){.header{padding:.75rem;gap:.75rem;margin-bottom:1.5rem}.header__title{font-size:1.25rem}}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "c80-icon", inputs: ["icon", "color", "customColor", "disabled", "size", "button", "border", "type", "textLeft", "textRight", "dark"], outputs: ["iconClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
13
+ }
14
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: HeaderComponent, decorators: [{
15
+ type: Component,
16
+ args: [{ selector: 'c80-header', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<header class=\"header\">\n <c80-icon button icon=\"arrowLeft\" [size]=\"1.2\" (iconClick)=\"onBackClick()\" title=\"Volver\" class=\"header__back-btn\" />\n <h1 class=\"header__title\">{{ config().title }}</h1>\n <span class=\"header__spacer\"></span>\n</header>", styles: [".header{display:flex;align-items:center;gap:1rem;margin-bottom:2rem;padding:1rem;border-bottom:1px solid var(--color-border)}.header__back-btn{flex-shrink:0}.header__title{font-size:1.5rem;font-weight:600;color:var(--color-text-primary);margin:0}.header__spacer{flex:1}@media(max-width:768px){.header{padding:.75rem;gap:.75rem;margin-bottom:1.5rem}.header__title{font-size:1.25rem}}\n"] }]
17
+ }], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }] } });
18
+ //# sourceMappingURL=header.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"header.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/header/header.component.ts","../../../../../libs/ui/src/lib/header/header.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;;AAWxC,MAAM,OAAO,eAAe;IACP,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAE7C,MAAM,GAAG,KAAK,CAAC,QAAQ,iDAAgB,CAAC;IAE9B,WAAW;QACjB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;wGAPQ,eAAe;4FAAf,eAAe,4MCb5B,kRAIS,0bDIK,aAAa;;4FAKd,eAAe;kBAR3B,SAAS;+BACI,YAAY,cACV,IAAI,WACP,CAAC,aAAa,CAAC,mBAGP,uBAAuB,CAAC,MAAM","sourcesContent":["import { Location } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, inject, input } from '@angular/core';\nimport { IconComponent } from '../icon';\nimport type { HeaderConfig } from './header.types';\n\n@Component({\n selector: 'c80-header',\n standalone: true,\n imports: [IconComponent],\n templateUrl: './header.component.html',\n styleUrl: './header.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class HeaderComponent {\n private readonly location = inject(Location);\n\n config = input.required<HeaderConfig>();\n\n protected onBackClick(): void {\n this.location.back();\n }\n}","<header class=\"header\">\n <c80-icon button icon=\"arrowLeft\" [size]=\"1.2\" (iconClick)=\"onBackClick()\" title=\"Volver\" class=\"header__back-btn\" />\n <h1 class=\"header__title\">{{ config().title }}</h1>\n <span class=\"header__spacer\"></span>\n</header>"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=header.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"header.types.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/header/header.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface HeaderConfig {\n title: string;\n}"]}
@@ -0,0 +1,3 @@
1
+ export * from './header.component';
2
+ export * from './header.types';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/header/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC","sourcesContent":["export * from './header.component';\nexport * from './header.types';"]}
@@ -1,13 +1,16 @@
1
1
  import { NgTemplateOutlet } from '@angular/common';
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';
2
+ import { Component, input, output, computed, ChangeDetectionStrategy, inject } from '@angular/core';
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, THEME_DARK_COLOR, THEME_LIGHT_COLOR, } from './icon.constants';
4
+ import { ICON_DEFINITIONS } from './icon.definitions';
5
+ import { transformToBoolean, shouldIconUseFill } from './icon.utils';
6
+ import { ThemeService } from './theme.service';
5
7
  import * as i0 from "@angular/core";
6
- export class C80IconComponent {
8
+ export class IconComponent {
9
+ themeService = inject(ThemeService);
7
10
  /* v8 ignore next */
8
11
  icon = input('check', ...(ngDevMode ? [{ debugName: "icon" }] : [])); // Tipo de icono a mostrar
9
12
  /* v8 ignore next */
10
- color = input('dark', ...(ngDevMode ? [{ debugName: "color" }] : [])); // Color del icono (primary, secondary, warn, success, dark)
13
+ color = input(undefined, ...(ngDevMode ? [{ debugName: "color" }] : [])); // Color del icono (primary, secondary, warn, success)
11
14
  /* v8 ignore next */
12
15
  customColor = input(undefined, ...(ngDevMode ? [{ debugName: "customColor" }] : [])); // Color personalizado (sobrescribe color)
13
16
  /* v8 ignore next */
@@ -24,35 +27,53 @@ export class C80IconComponent {
24
27
  textLeft = input(undefined, ...(ngDevMode ? [{ debugName: "textLeft" }] : [])); // Texto a la izquierda del icono
25
28
  /* v8 ignore next */
26
29
  textRight = input(undefined, ...(ngDevMode ? [{ debugName: "textRight" }] : [])); // Texto a la derecha del icono
30
+ /* v8 ignore next */
31
+ dark = input(false, ...(ngDevMode ? [{ debugName: "dark", transform: transformToBoolean }] : [{ transform: transformToBoolean }])); // Modo oscuro
27
32
  iconClick = output(); // Evento emitido al hacer click (solo si button=true)
28
33
  iconSize = computed(() => BASE_ICON_SIZE * this.size(), ...(ngDevMode ? [{ debugName: "iconSize" }] : []));
34
+ isDarkMode = computed(() => this.dark() || this.themeService.isDark(), ...(ngDevMode ? [{ debugName: "isDarkMode" }] : []));
29
35
  iconColor = computed(() => {
30
36
  if (this.disabled())
31
37
  return DISABLED_COLOR;
32
38
  const custom = this.customColor();
33
39
  if (custom)
34
40
  return custom;
35
- return BASE_ICON_COLORS[this.color()] ?? DEFAULT_ICON_COLOR;
41
+ const colorType = this.color();
42
+ // Si no hay color específico, usar color adaptativo al tema
43
+ if (!colorType) {
44
+ return this.themeService.isDark() ? THEME_DARK_COLOR : THEME_LIGHT_COLOR;
45
+ }
46
+ return BASE_ICON_COLORS[colorType] ?? DEFAULT_ICON_COLOR;
36
47
  }, ...(ngDevMode ? [{ debugName: "iconColor" }] : []));
37
48
  iconOpacity = computed(() => {
38
49
  if (this.disabled())
39
50
  return DISABLED_OPACITY;
40
51
  const hasCustomColor = this.customColor() !== undefined;
41
- const isSecondaryOrWarn = ['secondary', 'warn'].includes(this.color());
42
- return !hasCustomColor && isSecondaryOrWarn ? SECONDARY_WARN_OPACITY : DEFAULT_OPACITY;
52
+ const colorType = this.color();
53
+ const isOpacityReducedColor = colorType && OPACITY_REDUCED_COLORS.includes(colorType);
54
+ return !hasCustomColor && isOpacityReducedColor ? SECONDARY_WARN_OPACITY : DEFAULT_OPACITY;
43
55
  }, ...(ngDevMode ? [{ debugName: "iconOpacity" }] : []));
44
- iconPath = computed(() => ICON_PATHS[this.icon()] ?? ICON_PATHS['default'], ...(ngDevMode ? [{ debugName: "iconPath" }] : []));
45
- additionalShapes = computed(() => ICON_ADDITIONAL_SHAPES[this.icon()] ?? [], ...(ngDevMode ? [{ debugName: "additionalShapes" }] : []));
56
+ // Optimización: Un solo lookup a ICON_DEFINITIONS
57
+ iconDefinition = computed(() => {
58
+ return ICON_DEFINITIONS[this.icon()] ?? ICON_DEFINITIONS['default'];
59
+ }, ...(ngDevMode ? [{ debugName: "iconDefinition" }] : []));
60
+ iconPath = computed(() => this.iconDefinition().path, ...(ngDevMode ? [{ debugName: "iconPath" }] : []));
61
+ additionalShapes = computed(() => this.iconDefinition().additionalShapes ?? [], ...(ngDevMode ? [{ debugName: "additionalShapes" }] : []));
62
+ shouldFillIcon = computed(() => shouldIconUseFill(this.icon()), ...(ngDevMode ? [{ debugName: "shouldFillIcon" }] : []));
63
+ multiColorIcon = computed(() => this.iconDefinition().multiColor, ...(ngDevMode ? [{ debugName: "multiColorIcon" }] : []));
64
+ hasMultiPaths = computed(() => this.multiColorIcon() !== undefined, ...(ngDevMode ? [{ debugName: "hasMultiPaths" }] : []));
65
+ // Exponer constantes SVG al template
66
+ svgStrokeAttrs = SVG_STROKE_ATTRS;
46
67
  onButtonClick(event) {
47
68
  if (!this.disabled()) {
48
69
  this.iconClick.emit(event);
49
70
  }
50
71
  }
51
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: C80IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
52
- 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()\" 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 });
72
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
73
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: IconComponent, 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 }, dark: { classPropertyName: "dark", publicName: "dark", 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()\" [class.dark-mode]=\"isDarkMode()\" (click)=\"onButtonClick($event)\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</button>\n} @else {\n<span class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" [class.dark-mode]=\"isDarkMode()\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</span>\n}", styles: [":host{--icon-border-color: #e5e7eb;--icon-border-color-hover: #d1d5db;--icon-border-color-disabled: #f3f4f6;--icon-bg-hover: #f3f4f6;--icon-bg-active: #e5e7eb;--icon-text-color: #111827;--icon-border-radius: 4px;--icon-transition: .2s}:host .dark-mode{--icon-border-color: #374151;--icon-border-color-hover: #4b5563;--icon-border-color-disabled: #1f2937;--icon-bg-hover: #374151;--icon-bg-active: #4b5563;--icon-text-color: #f9fafb}:host .icon-wrapper{display:inline-flex;align-items:center;gap:8px;background:transparent;padding:0;border:none;outline:none;cursor:pointer;transition:opacity var(--icon-transition)}:host button.icon-wrapper:focus-visible{outline:none;outline-offset:2px;border-radius:var(--icon-border-radius)}: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 var(--icon-transition);box-sizing:border-box}:host button.icon-wrapper:hover:not(:disabled) .icon-content{background:var(--icon-bg-hover)}:host button.icon-wrapper:active:not(:disabled) .icon-content{background:var(--icon-bg-active)}:host .icon-text{font-size:14px;line-height:1;white-space:nowrap;-webkit-user-select:none;user-select:none;color:var(--icon-text-color)}:host .icon-wrapper-border{border:1px solid var(--icon-border-color);border-radius:var(--icon-border-radius);padding:4px 8px}:host button.icon-wrapper-border:hover:not(:disabled){border-color:var(--icon-border-color-hover)}:host button.icon-wrapper-border:disabled{border-color:var(--icon-border-color-disabled)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
53
74
  }
54
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: C80IconComponent, decorators: [{
75
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: IconComponent, decorators: [{
55
76
  type: Component,
56
- 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"] }]
57
- }], 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"] }] } });
77
+ 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()\" [class.dark-mode]=\"isDarkMode()\" (click)=\"onButtonClick($event)\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</button>\n} @else {\n<span class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" [class.dark-mode]=\"isDarkMode()\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</span>\n}", styles: [":host{--icon-border-color: #e5e7eb;--icon-border-color-hover: #d1d5db;--icon-border-color-disabled: #f3f4f6;--icon-bg-hover: #f3f4f6;--icon-bg-active: #e5e7eb;--icon-text-color: #111827;--icon-border-radius: 4px;--icon-transition: .2s}:host .dark-mode{--icon-border-color: #374151;--icon-border-color-hover: #4b5563;--icon-border-color-disabled: #1f2937;--icon-bg-hover: #374151;--icon-bg-active: #4b5563;--icon-text-color: #f9fafb}:host .icon-wrapper{display:inline-flex;align-items:center;gap:8px;background:transparent;padding:0;border:none;outline:none;cursor:pointer;transition:opacity var(--icon-transition)}:host button.icon-wrapper:focus-visible{outline:none;outline-offset:2px;border-radius:var(--icon-border-radius)}: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 var(--icon-transition);box-sizing:border-box}:host button.icon-wrapper:hover:not(:disabled) .icon-content{background:var(--icon-bg-hover)}:host button.icon-wrapper:active:not(:disabled) .icon-content{background:var(--icon-bg-active)}:host .icon-text{font-size:14px;line-height:1;white-space:nowrap;-webkit-user-select:none;user-select:none;color:var(--icon-text-color)}:host .icon-wrapper-border{border:1px solid var(--icon-border-color);border-radius:var(--icon-border-radius);padding:4px 8px}:host button.icon-wrapper-border:hover:not(:disabled){border-color:var(--icon-border-color-hover)}:host button.icon-wrapper-border:disabled{border-color:var(--icon-border-color-disabled)}\n"] }]
78
+ }], 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 }] }], dark: [{ type: i0.Input, args: [{ isSignal: true, alias: "dark", required: false }] }], iconClick: [{ type: i0.Output, args: ["iconClick"] }] } });
58
79
  //# 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 /* 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 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, inject } 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 THEME_DARK_COLOR,\n THEME_LIGHT_COLOR,\n} from './icon.constants';\nimport { ICON_DEFINITIONS } from './icon.definitions';\nimport type { ColorType, ButtonType, IconType } from './icon.types';\nimport { transformToBoolean, shouldIconUseFill } from './icon.utils';\nimport { ThemeService } from './theme.service';\n\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 IconComponent {\n private readonly themeService = inject(ThemeService);\n\n /* v8 ignore next */\n readonly icon = input<IconType>('check'); // Tipo de icono a mostrar\n /* v8 ignore next */\n readonly color = input<ColorType | undefined>(undefined); // Color del icono (primary, secondary, warn, success)\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 /* v8 ignore next */\n readonly dark = input(false, { transform: transformToBoolean }); // Modo oscuro\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 isDarkMode = computed(() => this.dark() || this.themeService.isDark());\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 const colorType = this.color();\n\n // Si no hay color específico, usar color adaptativo al tema\n if (!colorType) {\n return this.themeService.isDark() ? THEME_DARK_COLOR : THEME_LIGHT_COLOR;\n }\n\n return BASE_ICON_COLORS[colorType] ?? 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 colorType = this.color();\n const isOpacityReducedColor = colorType && OPACITY_REDUCED_COLORS.includes(colorType);\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()\" [class.dark-mode]=\"isDarkMode()\" (click)=\"onButtonClick($event)\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</button>\n} @else {\n<span class=\"icon-wrapper\" [class.icon-wrapper-border]=\"border()\" [class.dark-mode]=\"isDarkMode()\">\n <ng-container *ngTemplateOutlet=\"textContent\" />\n</span>\n}"]}