@c80/ui 1.0.57 → 1.0.58

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 (115) hide show
  1. package/esm2022/index.js +12 -8
  2. package/esm2022/index.js.map +1 -1
  3. package/esm2022/lib/action-list/action-list.component.js +7 -0
  4. package/esm2022/lib/action-list/action-list.component.js.map +1 -1
  5. package/esm2022/lib/action-list/action-list.types.js.map +1 -1
  6. package/esm2022/lib/card-level/card-level.component.js +3 -0
  7. package/esm2022/lib/card-level/card-level.component.js.map +1 -1
  8. package/esm2022/lib/header/header.component.js +8 -2
  9. package/esm2022/lib/header/header.component.js.map +1 -1
  10. package/esm2022/lib/header/header.types.js.map +1 -1
  11. package/esm2022/lib/icon/icon.component.js +10 -2
  12. package/esm2022/lib/icon/icon.component.js.map +1 -1
  13. package/esm2022/lib/icon/icon.definitions.js +34 -1
  14. package/esm2022/lib/icon/icon.definitions.js.map +1 -1
  15. package/esm2022/lib/icon/icon.types.js.map +1 -1
  16. package/esm2022/lib/icon/icon.utils.js +7 -0
  17. package/esm2022/lib/icon/icon.utils.js.map +1 -1
  18. package/esm2022/lib/icon/theme.service.js +17 -0
  19. package/esm2022/lib/icon/theme.service.js.map +1 -1
  20. package/esm2022/lib/info-list/info-list.component.js +3 -0
  21. package/esm2022/lib/info-list/info-list.component.js.map +1 -1
  22. package/esm2022/lib/input-field/input-field.component.js +19 -2
  23. package/esm2022/lib/input-field/input-field.component.js.map +1 -1
  24. package/esm2022/lib/input-search/c80-input-search.component.js +26 -0
  25. package/esm2022/lib/input-search/c80-input-search.component.js.map +1 -0
  26. package/esm2022/lib/input-search/index.js +2 -0
  27. package/esm2022/lib/input-search/index.js.map +1 -0
  28. package/esm2022/lib/modal/modal.component.js +57 -0
  29. package/esm2022/lib/modal/modal.component.js.map +1 -1
  30. package/esm2022/lib/modal/modal.service.js +60 -3
  31. package/esm2022/lib/modal/modal.service.js.map +1 -1
  32. package/esm2022/lib/profile-stats/profile-stats.component.js +6 -2
  33. package/esm2022/lib/profile-stats/profile-stats.component.js.map +1 -1
  34. package/esm2022/lib/profile-stats/profile-stats.types.js.map +1 -1
  35. package/esm2022/lib/rating-display/index.js +2 -0
  36. package/esm2022/lib/rating-display/index.js.map +1 -0
  37. package/esm2022/lib/rating-display/rating-display.component.js +24 -0
  38. package/esm2022/lib/rating-display/rating-display.component.js.map +1 -0
  39. package/esm2022/lib/rating-stars/index.js +2 -0
  40. package/esm2022/lib/rating-stars/index.js.map +1 -0
  41. package/esm2022/lib/rating-stars/rating-stars.component.js +33 -0
  42. package/esm2022/lib/rating-stars/rating-stars.component.js.map +1 -0
  43. package/esm2022/lib/select/select.component.js +27 -0
  44. package/esm2022/lib/select/select.component.js.map +1 -1
  45. package/esm2022/lib/snackbar/snackbar.component.js +17 -0
  46. package/esm2022/lib/snackbar/snackbar.component.js.map +1 -1
  47. package/esm2022/lib/snackbar/snackbar.service.js +9 -0
  48. package/esm2022/lib/snackbar/snackbar.service.js.map +1 -1
  49. package/esm2022/lib/spinner/index.js +2 -0
  50. package/esm2022/lib/spinner/index.js.map +1 -0
  51. package/esm2022/lib/spinner/spinner.component.js +22 -0
  52. package/esm2022/lib/spinner/spinner.component.js.map +1 -0
  53. package/esm2022/lib/stat-card/stat-card.component.js +3 -0
  54. package/esm2022/lib/stat-card/stat-card.component.js.map +1 -1
  55. package/esm2022/lib/tab/c80-tab.component.js +19 -2
  56. package/esm2022/lib/tab/c80-tab.component.js.map +1 -1
  57. package/esm2022/lib/tab/directives/c80-tab-item.directive.js +3 -0
  58. package/esm2022/lib/tab/directives/c80-tab-item.directive.js.map +1 -1
  59. package/esm2022/lib/tab/directives/c80-tab-label.directive.js +3 -0
  60. package/esm2022/lib/tab/directives/c80-tab-label.directive.js.map +1 -1
  61. package/esm2022/lib/table/table-column-visibility.service.js +27 -34
  62. package/esm2022/lib/table/table-column-visibility.service.js.map +1 -1
  63. package/esm2022/lib/table/table-crud-state.service.js +7 -7
  64. package/esm2022/lib/table/table-crud-state.service.js.map +1 -1
  65. package/esm2022/lib/table/table-data-converter.service.js +18 -10
  66. package/esm2022/lib/table/table-data-converter.service.js.map +1 -1
  67. package/esm2022/lib/table/table-data-utils.service.js +17 -1
  68. package/esm2022/lib/table/table-data-utils.service.js.map +1 -1
  69. package/esm2022/lib/table/table-selection.service.js +14 -3
  70. package/esm2022/lib/table/table-selection.service.js.map +1 -1
  71. package/esm2022/lib/table/table.component.js +58 -16
  72. package/esm2022/lib/table/table.component.js.map +1 -1
  73. package/esm2022/lib/table/table.types.js.map +1 -1
  74. package/esm2022/lib/table/table.utils.js +7 -0
  75. package/esm2022/lib/table/table.utils.js.map +1 -1
  76. package/index.d.ts +12 -8
  77. package/lib/action-list/action-list.component.d.ts +7 -0
  78. package/lib/action-list/action-list.types.d.ts +2 -1
  79. package/lib/card-level/card-level.component.d.ts +4 -1
  80. package/lib/header/header.component.d.ts +7 -1
  81. package/lib/header/header.types.d.ts +2 -0
  82. package/lib/icon/icon.component.d.ts +9 -1
  83. package/lib/icon/icon.types.d.ts +2 -0
  84. package/lib/icon/icon.utils.d.ts +7 -0
  85. package/lib/icon/theme.service.d.ts +17 -0
  86. package/lib/info-list/info-list.component.d.ts +3 -0
  87. package/lib/input-field/input-field.component.d.ts +17 -0
  88. package/lib/input-search/c80-input-search.component.d.ts +16 -0
  89. package/lib/input-search/index.d.ts +1 -0
  90. package/lib/modal/modal.component.d.ts +57 -0
  91. package/lib/modal/modal.service.d.ts +72 -3
  92. package/lib/profile-stats/profile-stats.component.d.ts +4 -0
  93. package/lib/profile-stats/profile-stats.types.d.ts +6 -2
  94. package/lib/rating-display/index.d.ts +1 -0
  95. package/lib/rating-display/rating-display.component.d.ts +12 -0
  96. package/lib/rating-stars/index.d.ts +1 -0
  97. package/lib/rating-stars/rating-stars.component.d.ts +19 -0
  98. package/lib/select/select.component.d.ts +27 -0
  99. package/lib/snackbar/snackbar.component.d.ts +17 -0
  100. package/lib/snackbar/snackbar.service.d.ts +9 -0
  101. package/lib/spinner/index.d.ts +1 -0
  102. package/lib/spinner/spinner.component.d.ts +12 -0
  103. package/lib/stat-card/stat-card.component.d.ts +3 -0
  104. package/lib/tab/c80-tab.component.d.ts +17 -0
  105. package/lib/tab/directives/c80-tab-item.directive.d.ts +3 -0
  106. package/lib/tab/directives/c80-tab-label.directive.d.ts +3 -0
  107. package/lib/table/table-column-visibility.service.d.ts +19 -6
  108. package/lib/table/table-crud-state.service.d.ts +23 -13
  109. package/lib/table/table-data-converter.service.d.ts +2 -0
  110. package/lib/table/table-data-utils.service.d.ts +7 -0
  111. package/lib/table/table-selection.service.d.ts +14 -12
  112. package/lib/table/table.component.d.ts +3 -0
  113. package/lib/table/table.types.d.ts +1 -0
  114. package/lib/table/table.utils.d.ts +2 -0
  115. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"icon.utils.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/icon/icon.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD,MAAM,UAAU,kBAAkB,CAAC,GAAwC;IACzE,OAAO,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,OAAO,CAAC;AAC/E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAkB;IAClD,MAAM,OAAO,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAE3C,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAE3B,2CAA2C;IAC3C,IAAI,OAAO,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAEpC,0EAA0E;IAC1E,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC,IAAI,CAAC;IAEpD,2DAA2D;IAC3D,OAAO,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC,KAAsB,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,KAAK,CAAC;AACrG,CAAC","sourcesContent":["import { ICON_DEFINITIONS } from './icon.definitions';\nimport type { IconType, ShapeAttributes } from './icon.types';\n\nexport function transformToBoolean(val: boolean | string | null | undefined): boolean {\n return val !== null && val !== undefined && val !== false && val !== 'false';\n}\n\n/**\n * Determina si un icono debería usar fill basado en su definición explícita\n */\nexport function shouldIconUseFill(iconName: IconType): boolean {\n const iconDef = ICON_DEFINITIONS[iconName];\n\n if (!iconDef) return false;\n\n // Los iconos multi-color siempre usan fill\n if (iconDef.multiColor) return true;\n\n // Si la definición especifica explícitamente fill, usar esa configuración\n if (iconDef.fill !== undefined) return iconDef.fill;\n\n // Iconos con shapes que tienen fill='color' necesitan fill\n return iconDef.additionalShapes?.some((shape: ShapeAttributes) => shape.fill === 'color') ?? false;\n}\n"]}
1
+ {"version":3,"file":"icon.utils.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/icon/icon.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAwC;IACzE,OAAO,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,OAAO,CAAC;AAC/E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAkB;IAClD,MAAM,OAAO,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAE3C,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAE3B,2CAA2C;IAC3C,IAAI,OAAO,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAEpC,0EAA0E;IAC1E,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC,IAAI,CAAC;IAEpD,2DAA2D;IAC3D,OAAO,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC,KAAsB,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,IAAI,KAAK,CAAC;AACrG,CAAC","sourcesContent":["import { ICON_DEFINITIONS } from './icon.definitions';\nimport type { IconType, ShapeAttributes } from './icon.types';\n\n/**\n *\n * @param val\n * @returns Valor convertido a boolean\n */\nexport function transformToBoolean(val: boolean | string | null | undefined): boolean {\n return val !== null && val !== undefined && val !== false && val !== 'false';\n}\n\n/**\n * Determina si un icono debería usar fill basado en su definición explícita\n * @param iconName\n * @returns true si el icono debe usar fill\n */\nexport function shouldIconUseFill(iconName: IconType): boolean {\n const iconDef = ICON_DEFINITIONS[iconName];\n\n if (!iconDef) return false;\n\n // Los iconos multi-color siempre usan fill\n if (iconDef.multiColor) return true;\n\n // Si la definición especifica explícitamente fill, usar esa configuración\n if (iconDef.fill !== undefined) return iconDef.fill;\n\n // Iconos con shapes que tienen fill='color' necesitan fill\n return iconDef.additionalShapes?.some((shape: ShapeAttributes) => shape.fill === 'color') ?? false;\n}\n"]}
@@ -1,7 +1,14 @@
1
1
  import { Injectable, signal } from '@angular/core';
2
2
  import * as i0 from "@angular/core";
3
+ /**
4
+ *
5
+ */
3
6
  export class ThemeService {
4
7
  isDark = signal(this.getInitialTheme(), ...(ngDevMode ? [{ debugName: "isDark" }] : []));
8
+ /**
9
+ *
10
+ * @returns true si el tema es oscuro
11
+ */
5
12
  getInitialTheme() {
6
13
  const stored = localStorage.getItem('theme');
7
14
  if (stored) {
@@ -9,6 +16,9 @@ export class ThemeService {
9
16
  }
10
17
  return globalThis.matchMedia('(prefers-color-scheme: dark)').matches;
11
18
  }
19
+ /**
20
+ *
21
+ */
12
22
  toggle() {
13
23
  this.isDark.update(current => {
14
24
  const newValue = !current;
@@ -17,9 +27,16 @@ export class ThemeService {
17
27
  return newValue;
18
28
  });
19
29
  }
30
+ /**
31
+ *
32
+ * @param isDark
33
+ */
20
34
  applyTheme(isDark) {
21
35
  document.documentElement.dataset['theme'] = isDark ? 'dark' : 'light';
22
36
  }
37
+ /**
38
+ *
39
+ */
23
40
  initialize() {
24
41
  this.applyTheme(this.isDark());
25
42
  globalThis.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
@@ -1 +1 @@
1
- {"version":3,"file":"theme.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/icon/theme.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;;AAGnD,MAAM,OAAO,YAAY;IACZ,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,kDAAC,CAAC;IAEzC,eAAe;QACnB,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,MAAM,EAAE,CAAC;YACT,OAAO,MAAM,KAAK,MAAM,CAAC;QAC7B,CAAC;QACD,OAAO,UAAU,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,OAAO,CAAC;IACzE,CAAC;IAED,MAAM;QACF,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;YACzB,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC;YAC1B,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAC3D,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC1B,OAAO,QAAQ,CAAC;QACpB,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,UAAU,CAAC,MAAe;QAC9B,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAC1E,CAAC;IAED,UAAU;QACN,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAE/B,UAAU,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;YACnF,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBACjC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBAC3B,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;wGAjCQ,YAAY;4GAAZ,YAAY,cADC,MAAM;;4FACnB,YAAY;kBADxB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE","sourcesContent":["import { Injectable, signal } from '@angular/core';\n\n@Injectable({ providedIn: 'root' })\nexport class ThemeService {\n readonly isDark = signal(this.getInitialTheme());\n\n private getInitialTheme(): boolean {\n const stored = localStorage.getItem('theme');\n if (stored) {\n return stored === 'dark';\n }\n return globalThis.matchMedia('(prefers-color-scheme: dark)').matches;\n }\n\n toggle(): void {\n this.isDark.update(current => {\n const newValue = !current;\n localStorage.setItem('theme', newValue ? 'dark' : 'light');\n this.applyTheme(newValue);\n return newValue;\n });\n }\n\n private applyTheme(isDark: boolean): void {\n document.documentElement.dataset['theme'] = isDark ? 'dark' : 'light';\n }\n\n initialize(): void {\n this.applyTheme(this.isDark());\n\n globalThis.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {\n if (!localStorage.getItem('theme')) {\n this.isDark.set(e.matches);\n this.applyTheme(e.matches);\n }\n });\n }\n}\n"]}
1
+ {"version":3,"file":"theme.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/icon/theme.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;;AAEnD;;GAEG;AAEH,MAAM,OAAO,YAAY;IACZ,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,kDAAC,CAAC;IAEjD;;;OAGG;IACK,eAAe;QACnB,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,MAAM,EAAE,CAAC;YACT,OAAO,MAAM,KAAK,MAAM,CAAC;QAC7B,CAAC;QACD,OAAO,UAAU,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,OAAO,CAAC;IACzE,CAAC;IAED;;OAEG;IACH,MAAM;QACF,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;YACzB,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC;YAC1B,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAC3D,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC1B,OAAO,QAAQ,CAAC;QACpB,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;OAGG;IACK,UAAU,CAAC,MAAe;QAC9B,QAAQ,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAC1E,CAAC;IAED;;OAEG;IACH,UAAU;QACN,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAE/B,UAAU,CAAC,UAAU,CAAC,8BAA8B,CAAC,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;YACnF,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBACjC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBAC3B,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YAC/B,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;wGA/CQ,YAAY;4GAAZ,YAAY,cADC,MAAM;;4FACnB,YAAY;kBADxB,UAAU;mBAAC,EAAE,UAAU,EAAE,MAAM,EAAE","sourcesContent":["import { Injectable, signal } from '@angular/core';\n\n/**\n *\n */\n@Injectable({ providedIn: 'root' })\nexport class ThemeService {\n readonly isDark = signal(this.getInitialTheme());\n\n /**\n *\n * @returns true si el tema es oscuro\n */\n private getInitialTheme(): boolean {\n const stored = localStorage.getItem('theme');\n if (stored) {\n return stored === 'dark';\n }\n return globalThis.matchMedia('(prefers-color-scheme: dark)').matches;\n }\n\n /**\n *\n */\n toggle(): void {\n this.isDark.update(current => {\n const newValue = !current;\n localStorage.setItem('theme', newValue ? 'dark' : 'light');\n this.applyTheme(newValue);\n return newValue;\n });\n }\n\n /**\n *\n * @param isDark\n */\n private applyTheme(isDark: boolean): void {\n document.documentElement.dataset['theme'] = isDark ? 'dark' : 'light';\n }\n\n /**\n *\n */\n initialize(): void {\n this.applyTheme(this.isDark());\n\n globalThis.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {\n if (!localStorage.getItem('theme')) {\n this.isDark.set(e.matches);\n this.applyTheme(e.matches);\n }\n });\n }\n}\n"]}
@@ -1,5 +1,8 @@
1
1
  import { Component, input, ChangeDetectionStrategy } from '@angular/core';
2
2
  import * as i0 from "@angular/core";
3
+ /**
4
+ *
5
+ */
3
6
  export class InfoListComponent {
4
7
  items = input.required(...(ngDevMode ? [{ debugName: "items" }] : []));
5
8
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: InfoListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -1 +1 @@
1
- {"version":3,"file":"info-list.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/info-list/info-list.component.ts","../../../../../libs/ui/src/lib/info-list/info-list.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;;AAY1E,MAAM,OAAO,iBAAiB;IACjB,KAAK,GAAG,KAAK,CAAC,QAAQ,gDAAc,CAAC;wGADrC,iBAAiB;4FAAjB,iBAAiB,4MCZ9B,0SASM;;4FDGO,iBAAiB;kBAT7B,SAAS;+BAEI,eAAe,cACb,IAAI,WACP,EAAE,mBAGM,uBAAuB,CAAC,MAAM","sourcesContent":["import { Component, input, ChangeDetectionStrategy } from '@angular/core';\nimport type { InfoItem } from './info-list.types';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-info-list',\n standalone: true,\n imports: [],\n templateUrl: './info-list.component.html',\n styleUrl: './info-list.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class InfoListComponent {\n readonly items = input.required<InfoItem[]>();\n}","<div class=\"info-list\">\n @for (item of items(); track $index) {\n @if (item.value) {\n <div class=\"info-list__item\">\n <span class=\"info-list__label\">{{ item.label }}</span>\n <span class=\"info-list__value\">{{ item.value }}</span>\n </div>\n }\n }\n</div>"]}
1
+ {"version":3,"file":"info-list.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/info-list/info-list.component.ts","../../../../../libs/ui/src/lib/info-list/info-list.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;;AAG1E;;GAEG;AAUH,MAAM,OAAO,iBAAiB;IACjB,KAAK,GAAG,KAAK,CAAC,QAAQ,gDAAc,CAAC;wGADrC,iBAAiB;4FAAjB,iBAAiB,4MCf9B,0SASM;;4FDMO,iBAAiB;kBAT7B,SAAS;+BAEI,eAAe,cACb,IAAI,WACP,EAAE,mBAGM,uBAAuB,CAAC,MAAM","sourcesContent":["import { Component, input, ChangeDetectionStrategy } from '@angular/core';\nimport type { InfoItem } from './info-list.types';\n\n/**\n *\n */\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-info-list',\n standalone: true,\n imports: [],\n templateUrl: './info-list.component.html',\n styleUrl: './info-list.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class InfoListComponent {\n readonly items = input.required<InfoItem[]>();\n}","<div class=\"info-list\">\n @for (item of items(); track $index) {\n @if (item.value) {\n <div class=\"info-list__item\">\n <span class=\"info-list__label\">{{ item.label }}</span>\n <span class=\"info-list__value\">{{ item.value }}</span>\n </div>\n }\n }\n</div>"]}
@@ -1,5 +1,8 @@
1
1
  import { ChangeDetectionStrategy, Component, output, signal } from '@angular/core';
2
2
  import * as i0 from "@angular/core";
3
+ /**
4
+ *
5
+ */
3
6
  export class InputFieldComponent {
4
7
  label = signal('', ...(ngDevMode ? [{ debugName: "label" }] : []));
5
8
  value = signal('', ...(ngDevMode ? [{ debugName: "value" }] : []));
@@ -11,27 +14,41 @@ export class InputFieldComponent {
11
14
  valueChange = output();
12
15
  enterPressed = output();
13
16
  isFocused = signal(false, ...(ngDevMode ? [{ debugName: "isFocused" }] : []));
17
+ /**
18
+ *
19
+ * @param event
20
+ */
14
21
  onValueChange(event) {
15
22
  const newValue = event.target.value;
16
23
  this.value.set(newValue);
17
24
  this.valueChange.emit(newValue);
18
25
  }
26
+ /**
27
+ *
28
+ */
19
29
  onFocus() {
20
30
  this.isFocused.set(true);
21
31
  }
32
+ /**
33
+ *
34
+ */
22
35
  onBlur() {
23
36
  this.isFocused.set(false);
24
37
  }
38
+ /**
39
+ *
40
+ * @param event
41
+ */
25
42
  onKeyDown(event) {
26
43
  if (event.key === 'Enter') {
27
44
  this.enterPressed.emit();
28
45
  }
29
46
  }
30
47
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: InputFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
31
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.10", type: InputFieldComponent, isStandalone: true, selector: "c80-input-field", outputs: { valueChange: "valueChange", enterPressed: "enterPressed" }, ngImport: i0, template: "<div class=\"input-field\">\n <div class=\"input-field__item\">\n <span class=\"input-field__label\">{{ label() }}</span>\n <input class=\"input-field__input\" [class.input-field__input--focused]=\"isFocused()\" [type]=\"type()\" [value]=\"value()\" [placeholder]=\"placeholder()\" [attr.maxlength]=\"maxLength()\" [readonly]=\"readonly()\" [required]=\"required()\"\n (input)=\"onValueChange($event)\" (focus)=\"onFocus()\" (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" />\n </div>\n</div>", styles: [".input-field{width:100%}.input-field__item{display:flex;justify-content:space-between;align-items:center;padding:1rem;background:var(--color-surface);border-radius:var(--radius-lg);gap:1rem;transition:all var(--transition-base)}.input-field__item:hover{background:var(--color-bg-dark)}.input-field__label{font-size:1rem;font-weight:500;color:var(--color-text-primary);min-width:fit-content}.input-field__input{flex:1;background:transparent;border:none;outline:none;font-size:1rem;color:var(--color-text-primary);text-align:right;padding:.5rem 0;min-width:0}.input-field__input::placeholder{color:var(--color-text-tertiary);font-style:italic}.input-field__input:focus{color:var(--color-primary)}.input-field__input[readonly]{cursor:default;color:var(--color-text-secondary)}.input-field__input--focused{color:var(--color-primary)}@media(max-width:768px){.input-field__item{padding:.75rem;gap:.75rem}.input-field__label,.input-field__input{font-size:.875rem}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
48
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.10", type: InputFieldComponent, isStandalone: true, selector: "c80-input-field", outputs: { valueChange: "valueChange", enterPressed: "enterPressed" }, ngImport: i0, template: "<div class=\"input-field\">\n <div class=\"input-field__item\">\n <span class=\"input-field__label\">{{ label() }}</span>\n <input class=\"input-field__input\" [class.input-field__input--focused]=\"isFocused()\" [type]=\"type()\" [value]=\"value()\" [placeholder]=\"placeholder()\" [attr.maxlength]=\"maxLength()\" [readonly]=\"readonly()\" [required]=\"required()\"\n (input)=\"onValueChange($event)\" (focus)=\"onFocus()\" (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" />\n </div>\n</div>", styles: [".input-field{width:100%}.input-field__item{display:flex;justify-content:space-between;align-items:center;padding:1rem;background:var(--color-surface);border-radius:.5rem;gap:1rem;transition:all var(--transition-base)}.input-field__item:hover{background:var(--color-bg-dark)}.input-field__label{color:var(--color-text-primary);min-width:fit-content;font-size:.875rem;font-weight:500}.input-field__input{flex:1;background:transparent;border:none;outline:none;color:var(--color-text-primary);text-align:right;padding:.5rem 0;min-width:0}.input-field__input::placeholder{color:var(--color-text-tertiary);font-style:italic}.input-field__input:focus{color:var(--color-primary)}.input-field__input[readonly]{cursor:default;color:var(--color-text-secondary)}.input-field__input--focused{color:var(--color-primary)}@media(max-width:768px){.input-field__item{padding:.75rem;gap:.75rem}.input-field__label,.input-field__input{font-size:.875rem}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
32
49
  }
33
50
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: InputFieldComponent, decorators: [{
34
51
  type: Component,
35
- args: [{ selector: 'c80-input-field', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"input-field\">\n <div class=\"input-field__item\">\n <span class=\"input-field__label\">{{ label() }}</span>\n <input class=\"input-field__input\" [class.input-field__input--focused]=\"isFocused()\" [type]=\"type()\" [value]=\"value()\" [placeholder]=\"placeholder()\" [attr.maxlength]=\"maxLength()\" [readonly]=\"readonly()\" [required]=\"required()\"\n (input)=\"onValueChange($event)\" (focus)=\"onFocus()\" (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" />\n </div>\n</div>", styles: [".input-field{width:100%}.input-field__item{display:flex;justify-content:space-between;align-items:center;padding:1rem;background:var(--color-surface);border-radius:var(--radius-lg);gap:1rem;transition:all var(--transition-base)}.input-field__item:hover{background:var(--color-bg-dark)}.input-field__label{font-size:1rem;font-weight:500;color:var(--color-text-primary);min-width:fit-content}.input-field__input{flex:1;background:transparent;border:none;outline:none;font-size:1rem;color:var(--color-text-primary);text-align:right;padding:.5rem 0;min-width:0}.input-field__input::placeholder{color:var(--color-text-tertiary);font-style:italic}.input-field__input:focus{color:var(--color-primary)}.input-field__input[readonly]{cursor:default;color:var(--color-text-secondary)}.input-field__input--focused{color:var(--color-primary)}@media(max-width:768px){.input-field__item{padding:.75rem;gap:.75rem}.input-field__label,.input-field__input{font-size:.875rem}}\n"] }]
52
+ args: [{ selector: 'c80-input-field', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"input-field\">\n <div class=\"input-field__item\">\n <span class=\"input-field__label\">{{ label() }}</span>\n <input class=\"input-field__input\" [class.input-field__input--focused]=\"isFocused()\" [type]=\"type()\" [value]=\"value()\" [placeholder]=\"placeholder()\" [attr.maxlength]=\"maxLength()\" [readonly]=\"readonly()\" [required]=\"required()\"\n (input)=\"onValueChange($event)\" (focus)=\"onFocus()\" (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" />\n </div>\n</div>", styles: [".input-field{width:100%}.input-field__item{display:flex;justify-content:space-between;align-items:center;padding:1rem;background:var(--color-surface);border-radius:.5rem;gap:1rem;transition:all var(--transition-base)}.input-field__item:hover{background:var(--color-bg-dark)}.input-field__label{color:var(--color-text-primary);min-width:fit-content;font-size:.875rem;font-weight:500}.input-field__input{flex:1;background:transparent;border:none;outline:none;color:var(--color-text-primary);text-align:right;padding:.5rem 0;min-width:0}.input-field__input::placeholder{color:var(--color-text-tertiary);font-style:italic}.input-field__input:focus{color:var(--color-primary)}.input-field__input[readonly]{cursor:default;color:var(--color-text-secondary)}.input-field__input--focused{color:var(--color-primary)}@media(max-width:768px){.input-field__item{padding:.75rem;gap:.75rem}.input-field__label,.input-field__input{font-size:.875rem}}\n"] }]
36
53
  }], propDecorators: { valueChange: [{ type: i0.Output, args: ["valueChange"] }], enterPressed: [{ type: i0.Output, args: ["enterPressed"] }] } });
37
54
  //# sourceMappingURL=input-field.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"input-field.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/input-field/input-field.component.ts","../../../../../libs/ui/src/lib/input-field/input-field.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;;AAWnF,MAAM,OAAO,mBAAmB;IACnB,KAAK,GAAG,MAAM,CAAS,EAAE,iDAAC,CAAC;IAC3B,KAAK,GAAG,MAAM,CAAS,EAAE,iDAAC,CAAC;IAC3B,WAAW,GAAG,MAAM,CAAS,EAAE,uDAAC,CAAC;IACjC,IAAI,GAAG,MAAM,CAAgC,MAAM,gDAAC,CAAC;IACrD,SAAS,GAAG,MAAM,CAAqB,SAAS,qDAAC,CAAC;IAClD,QAAQ,GAAG,MAAM,CAAU,KAAK,oDAAC,CAAC;IAClC,QAAQ,GAAG,MAAM,CAAU,KAAK,oDAAC,CAAC;IAE3C,WAAW,GAAG,MAAM,EAAU,CAAC;IAC/B,YAAY,GAAG,MAAM,EAAQ,CAAC;IAEX,SAAS,GAAG,MAAM,CAAC,KAAK,qDAAC,CAAC;IAEnC,aAAa,CAAC,KAAY;QAChC,MAAM,QAAQ,GAAI,KAAK,CAAC,MAA2B,CAAC,KAAK,CAAC;QAC1D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACzB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IAES,OAAO;QACb,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAES,MAAM;QACZ,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAES,SAAS,CAAC,KAAoB;QACpC,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;wGAhCQ,mBAAmB;4FAAnB,mBAAmB,kJCXhC,ihBAMM;;4FDKO,mBAAmB;kBAT/B,SAAS;+BAEI,iBAAiB,cACf,IAAI,WACP,EAAE,mBAGM,uBAAuB,CAAC,MAAM","sourcesContent":["import { ChangeDetectionStrategy, Component, output, signal } from '@angular/core';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-input-field',\n standalone: true,\n imports: [],\n templateUrl: './input-field.component.html',\n styleUrl: './input-field.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class InputFieldComponent {\n readonly label = signal<string>('');\n readonly value = signal<string>('');\n readonly placeholder = signal<string>('');\n readonly type = signal<'text' | 'email' | 'password'>('text');\n readonly maxLength = signal<number | undefined>(undefined);\n readonly readonly = signal<boolean>(false);\n readonly required = signal<boolean>(false);\n\n valueChange = output<string>();\n enterPressed = output<void>();\n\n protected readonly isFocused = signal(false);\n\n protected onValueChange(event: Event): void {\n const newValue = (event.target as HTMLInputElement).value;\n this.value.set(newValue);\n this.valueChange.emit(newValue);\n }\n\n protected onFocus(): void {\n this.isFocused.set(true);\n }\n\n protected onBlur(): void {\n this.isFocused.set(false);\n }\n\n protected onKeyDown(event: KeyboardEvent): void {\n if (event.key === 'Enter') {\n this.enterPressed.emit();\n }\n }\n}","<div class=\"input-field\">\n <div class=\"input-field__item\">\n <span class=\"input-field__label\">{{ label() }}</span>\n <input class=\"input-field__input\" [class.input-field__input--focused]=\"isFocused()\" [type]=\"type()\" [value]=\"value()\" [placeholder]=\"placeholder()\" [attr.maxlength]=\"maxLength()\" [readonly]=\"readonly()\" [required]=\"required()\"\n (input)=\"onValueChange($event)\" (focus)=\"onFocus()\" (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" />\n </div>\n</div>"]}
1
+ {"version":3,"file":"input-field.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/input-field/input-field.component.ts","../../../../../libs/ui/src/lib/input-field/input-field.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;;AAEnF;;GAEG;AAUH,MAAM,OAAO,mBAAmB;IACnB,KAAK,GAAG,MAAM,CAAS,EAAE,iDAAC,CAAC;IAC3B,KAAK,GAAG,MAAM,CAAS,EAAE,iDAAC,CAAC;IAC3B,WAAW,GAAG,MAAM,CAAS,EAAE,uDAAC,CAAC;IACjC,IAAI,GAAG,MAAM,CAAgC,MAAM,gDAAC,CAAC;IACrD,SAAS,GAAG,MAAM,CAAqB,SAAS,qDAAC,CAAC;IAClD,QAAQ,GAAG,MAAM,CAAU,KAAK,oDAAC,CAAC;IAClC,QAAQ,GAAG,MAAM,CAAU,KAAK,oDAAC,CAAC;IAE3C,WAAW,GAAG,MAAM,EAAU,CAAC;IAC/B,YAAY,GAAG,MAAM,EAAQ,CAAC;IAEX,SAAS,GAAG,MAAM,CAAC,KAAK,qDAAC,CAAC;IAE7C;;;OAGG;IACO,aAAa,CAAC,KAAY;QAChC,MAAM,QAAQ,GAAI,KAAK,CAAC,MAA2B,CAAC,KAAK,CAAC;QAC1D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACzB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACO,OAAO;QACb,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED;;OAEG;IACO,MAAM;QACZ,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED;;;OAGG;IACO,SAAS,CAAC,KAAoB;QACpC,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QAC7B,CAAC;IACL,CAAC;wGA9CQ,mBAAmB;4FAAnB,mBAAmB,kJCdhC,ihBAMM;;4FDQO,mBAAmB;kBAT/B,SAAS;+BAEI,iBAAiB,cACf,IAAI,WACP,EAAE,mBAGM,uBAAuB,CAAC,MAAM","sourcesContent":["import { ChangeDetectionStrategy, Component, output, signal } from '@angular/core';\n\n/**\n *\n */\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-input-field',\n standalone: true,\n imports: [],\n templateUrl: './input-field.component.html',\n styleUrl: './input-field.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class InputFieldComponent {\n readonly label = signal<string>('');\n readonly value = signal<string>('');\n readonly placeholder = signal<string>('');\n readonly type = signal<'text' | 'email' | 'password'>('text');\n readonly maxLength = signal<number | undefined>(undefined);\n readonly readonly = signal<boolean>(false);\n readonly required = signal<boolean>(false);\n\n valueChange = output<string>();\n enterPressed = output<void>();\n\n protected readonly isFocused = signal(false);\n\n /**\n *\n * @param event\n */\n protected onValueChange(event: Event): void {\n const newValue = (event.target as HTMLInputElement).value;\n this.value.set(newValue);\n this.valueChange.emit(newValue);\n }\n\n /**\n *\n */\n protected onFocus(): void {\n this.isFocused.set(true);\n }\n\n /**\n *\n */\n protected onBlur(): void {\n this.isFocused.set(false);\n }\n\n /**\n *\n * @param event\n */\n protected onKeyDown(event: KeyboardEvent): void {\n if (event.key === 'Enter') {\n this.enterPressed.emit();\n }\n }\n}","<div class=\"input-field\">\n <div class=\"input-field__item\">\n <span class=\"input-field__label\">{{ label() }}</span>\n <input class=\"input-field__input\" [class.input-field__input--focused]=\"isFocused()\" [type]=\"type()\" [value]=\"value()\" [placeholder]=\"placeholder()\" [attr.maxlength]=\"maxLength()\" [readonly]=\"readonly()\" [required]=\"required()\"\n (input)=\"onValueChange($event)\" (focus)=\"onFocus()\" (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" />\n </div>\n</div>"]}
@@ -0,0 +1,26 @@
1
+ import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';
2
+ import { IconComponent } from '../icon';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ *
6
+ */
7
+ export class InputSearchComponent {
8
+ value = input('', ...(ngDevMode ? [{ debugName: "value" }] : []));
9
+ placeholder = input('Buscar...', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
10
+ inputChange = output();
11
+ /**
12
+ *
13
+ * @param event
14
+ */
15
+ onInput(event) {
16
+ const val = event.target.value;
17
+ this.inputChange.emit(val);
18
+ }
19
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: InputSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
20
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.10", type: InputSearchComponent, isStandalone: true, selector: "c80-input-search", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { inputChange: "inputChange" }, ngImport: i0, template: "<div class=\"c80-input-search\">\n <c80-icon icon=\"search\" [button]=\"false\" [size]=\"1.2\" class=\"c80-input-search__icon\" />\n <input type=\"search\" class=\"c80-input-search__input\" [placeholder]=\"placeholder()\" [value]=\"value()\" (input)=\"onInput($event)\" autocomplete=\"off\" />\n</div>", styles: [".c80-input-search{display:flex;align-items:center;position:relative;background:var(--color-surface);border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:.25rem .75rem;border:1px solid var(--color-border);transition:box-shadow var(--transition-base);width:100%;min-height:48px}.c80-input-search__icon{margin-right:.5rem;color:var(--color-text-secondary);flex-shrink:0;font-size:1.2rem}.c80-input-search__input{border:none;outline:none;background:transparent;font-size:1rem;color:var(--color-text-primary);width:100%;padding:0;box-shadow:none;font-family:inherit}\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 });
21
+ }
22
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: InputSearchComponent, decorators: [{
23
+ type: Component,
24
+ args: [{ selector: 'c80-input-search', standalone: true, imports: [IconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"c80-input-search\">\n <c80-icon icon=\"search\" [button]=\"false\" [size]=\"1.2\" class=\"c80-input-search__icon\" />\n <input type=\"search\" class=\"c80-input-search__input\" [placeholder]=\"placeholder()\" [value]=\"value()\" (input)=\"onInput($event)\" autocomplete=\"off\" />\n</div>", styles: [".c80-input-search{display:flex;align-items:center;position:relative;background:var(--color-surface);border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:.25rem .75rem;border:1px solid var(--color-border);transition:box-shadow var(--transition-base);width:100%;min-height:48px}.c80-input-search__icon{margin-right:.5rem;color:var(--color-text-secondary);flex-shrink:0;font-size:1.2rem}.c80-input-search__input{border:none;outline:none;background:transparent;font-size:1rem;color:var(--color-text-primary);width:100%;padding:0;box-shadow:none;font-family:inherit}\n"] }]
25
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], inputChange: [{ type: i0.Output, args: ["inputChange"] }] } });
26
+ //# sourceMappingURL=c80-input-search.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"c80-input-search.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/input-search/c80-input-search.component.ts","../../../../../libs/ui/src/lib/input-search/c80-input-search.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;;AAExC;;GAEG;AAUH,MAAM,OAAO,oBAAoB;IACpB,KAAK,GAAG,KAAK,CAAS,EAAE,iDAAC,CAAC;IAC1B,WAAW,GAAG,KAAK,CAAS,WAAW,uDAAC,CAAC;IACzC,WAAW,GAAG,MAAM,EAAU,CAAC;IAExC;;;OAGG;IACO,OAAO,CAAC,KAAY;QAC1B,MAAM,GAAG,GAAI,KAAK,CAAC,MAA2B,CAAC,KAAK,CAAC;QACrD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;wGAZQ,oBAAoB;4FAApB,oBAAoB,mYCfjC,qTAGM,2nBDOQ,aAAa;;4FAKd,oBAAoB;kBAThC,SAAS;+BAEI,kBAAkB,cAChB,IAAI,WACP,CAAC,aAAa,CAAC,mBAGP,uBAAuB,CAAC,MAAM","sourcesContent":["import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';\nimport { IconComponent } from '../icon';\n\n/**\n *\n */\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-input-search',\n standalone: true,\n imports: [IconComponent],\n templateUrl: './c80-input-search.component.html',\n styleUrl: './c80-input-search.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class InputSearchComponent {\n readonly value = input<string>('');\n readonly placeholder = input<string>('Buscar...');\n readonly inputChange = output<string>();\n\n /**\n *\n * @param event\n */\n protected onInput(event: Event): void {\n const val = (event.target as HTMLInputElement).value;\n this.inputChange.emit(val);\n }\n}\n","<div class=\"c80-input-search\">\n <c80-icon icon=\"search\" [button]=\"false\" [size]=\"1.2\" class=\"c80-input-search__icon\" />\n <input type=\"search\" class=\"c80-input-search__input\" [placeholder]=\"placeholder()\" [value]=\"value()\" (input)=\"onInput($event)\" autocomplete=\"off\" />\n</div>"]}
@@ -0,0 +1,2 @@
1
+ export * from './c80-input-search.component';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/input-search/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC","sourcesContent":["export * from './c80-input-search.component';\n"]}
@@ -2,11 +2,17 @@ import { Component, computed, effect, inject, ChangeDetectionStrategy } from '@a
2
2
  import { ModalService } from './modal.service';
3
3
  import { IconComponent } from './../icon';
4
4
  import * as i0 from "@angular/core";
5
+ /**
6
+ *
7
+ */
5
8
  export class ModalComponent {
6
9
  modalService = inject(ModalService);
7
10
  isOpen = this.modalService.modalState.isOpen;
8
11
  config = this.modalService.modalState.config;
9
12
  isVisible = computed(() => this.isOpen(), ...(ngDevMode ? [{ debugName: "isVisible" }] : []));
13
+ /**
14
+ *
15
+ */
10
16
  constructor() {
11
17
  effect(() => {
12
18
  if (this.isOpen()) {
@@ -21,26 +27,49 @@ export class ModalComponent {
21
27
  }
22
28
  });
23
29
  }
30
+ /**
31
+ * Maneja la confirmación del modal
32
+ */
24
33
  onConfirm() {
25
34
  this.modalService.handleResult({ action: 'confirm', confirmed: true });
26
35
  }
36
+ /**
37
+ * Maneja la cancelación del modal
38
+ */
27
39
  onCancel() {
28
40
  this.modalService.handleResult({ action: 'cancel', confirmed: false });
29
41
  }
42
+ /**
43
+ * Maneja la respuesta afirmativa del modal
44
+ */
30
45
  onYes() {
31
46
  this.modalService.handleResult({ action: 'yes', confirmed: true });
32
47
  }
48
+ /**
49
+ * Maneja la respuesta negativa del modal
50
+ */
33
51
  onNo() {
34
52
  this.modalService.handleResult({ action: 'no', confirmed: false });
35
53
  }
54
+ /**
55
+ * Cierra el modal actual
56
+ */
36
57
  closeModal() {
37
58
  this.modalService.closeModal();
38
59
  }
60
+ /**
61
+ * Maneja el clic en el backdrop del modal
62
+ * @param event - Evento de clic
63
+ */
39
64
  onBackdropClick(event) {
40
65
  if (event.target === event.currentTarget) {
41
66
  this.closeModal();
42
67
  }
43
68
  }
69
+ /**
70
+ *
71
+ * @returns Clase CSS del botón primario según el tipo de modal
72
+ */
44
73
  getPrimaryButtonClass() {
45
74
  const configValue = this.config();
46
75
  switch (configValue.type) {
@@ -55,25 +84,53 @@ export class ModalComponent {
55
84
  return 'btn-info';
56
85
  }
57
86
  }
87
+ /**
88
+ *
89
+ * @returns true si debe mostrar botones Sí/No
90
+ */
58
91
  showYesNoButtons() {
59
92
  return this.config().type === 'yesNo';
60
93
  }
94
+ /**
95
+ *
96
+ * @returns true si debe mostrar botones Confirmar/Cancelar
97
+ */
61
98
  showConfirmButtons() {
62
99
  const type = this.config().type;
63
100
  return type === 'confirm' || type === 'warning' || type === 'error';
64
101
  }
102
+ /**
103
+ *
104
+ * @returns true si debe mostrar botón OK
105
+ */
65
106
  showOkButton() {
66
107
  return this.config().type === 'info';
67
108
  }
109
+ /**
110
+ *
111
+ * @returns Texto del botón de confirmación
112
+ */
68
113
  getConfirmText() {
69
114
  return this.config().confirmText ?? 'Confirmar';
70
115
  }
116
+ /**
117
+ *
118
+ * @returns Texto del botón de cancelar
119
+ */
71
120
  getCancelText() {
72
121
  return this.config().cancelText ?? 'Cancelar';
73
122
  }
123
+ /**
124
+ *
125
+ * @returns Texto del botón Sí
126
+ */
74
127
  getYesText() {
75
128
  return this.config().yesText ?? 'Sí';
76
129
  }
130
+ /**
131
+ *
132
+ * @returns Texto del botón No
133
+ */
77
134
  getNoText() {
78
135
  return this.config().noText ?? 'No';
79
136
  }
@@ -1 +1 @@
1
- {"version":3,"file":"modal.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/modal/modal.component.ts","../../../../../libs/ui/src/lib/modal/modal.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, computed, effect, inject, ChangeDetectionStrategy } from '@angular/core';\nimport { ModalService } from './modal.service';\nimport { IconComponent } from './../icon';\n\nexport type ModalType = 'info' | 'confirm' | 'yesNo' | 'warning' | 'error';\n\nexport interface ModalConfig {\n title: string;\n message: string;\n type?: ModalType;\n confirmText?: string;\n cancelText?: string;\n yesText?: string;\n noText?: string;\n showCancel?: boolean;\n}\n\nexport interface ModalResult {\n action: 'confirm' | 'cancel' | 'yes' | 'no';\n confirmed: boolean;\n}\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-modal',\n standalone: true,\n imports: [IconComponent],\n templateUrl: './modal.component.html',\n styleUrl: './modal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ModalComponent {\n private readonly modalService = inject(ModalService);\n\n readonly isOpen = this.modalService.modalState.isOpen;\n readonly config = this.modalService.modalState.config;\n readonly isVisible = computed(() => this.isOpen());\n\n constructor() {\n effect(() => {\n if (this.isOpen()) {\n // Auto-focus modal when opened for accessibility\n /* v8 ignore next 8 */\n setTimeout(() => {\n const backdrop = document.querySelector(\n '.modal-backdrop'\n ) as HTMLElement;\n if (backdrop) {\n backdrop.focus();\n }\n }, 100);\n }\n });\n }\n\n onConfirm() {\n this.modalService.handleResult({ action: 'confirm', confirmed: true });\n }\n\n onCancel() {\n this.modalService.handleResult({ action: 'cancel', confirmed: false });\n }\n\n onYes() {\n this.modalService.handleResult({ action: 'yes', confirmed: true });\n }\n\n onNo() {\n this.modalService.handleResult({ action: 'no', confirmed: false });\n }\n\n closeModal() {\n this.modalService.closeModal();\n }\n\n onBackdropClick(event: Event) {\n if (event.target === event.currentTarget) {\n this.closeModal();\n }\n }\n\n getPrimaryButtonClass(): string {\n const configValue = this.config();\n switch (configValue.type) {\n case 'warning':\n return 'btn-warning';\n case 'error':\n return 'btn-danger';\n case 'confirm':\n case 'yesNo':\n return 'btn-primary';\n default:\n return 'btn-info';\n }\n }\n\n showYesNoButtons(): boolean {\n return this.config().type === 'yesNo';\n }\n\n showConfirmButtons(): boolean {\n const type = this.config().type;\n return type === 'confirm' || type === 'warning' || type === 'error';\n }\n\n showOkButton(): boolean {\n return this.config().type === 'info';\n }\n\n getConfirmText(): string {\n return this.config().confirmText ?? 'Confirmar';\n }\n\n getCancelText(): string {\n return this.config().cancelText ?? 'Cancelar';\n }\n\n getYesText(): string {\n return this.config().yesText ?? 'Sí';\n }\n\n getNoText(): string {\n return this.config().noText ?? 'No';\n }\n}\n","<!-- Modal Backdrop -->\n@if (isOpen()) {\n<div class=\"modal-backdrop\" [class.show]=\"isVisible()\" tabindex=\"-1\" (click)=\"onBackdropClick($event)\" (keydown.escape)=\"closeModal()\">\n\n <!-- Modal Container -->\n <dialog class=\"modal-container\" [class.show]=\"isVisible()\" [attr.aria-labelledby]=\"'modal-title'\" [open]=\"isVisible()\">\n\n <!-- Modal Header -->\n <div class=\"modal-header\">\n <h4 class=\"modal-title\" id=\"modal-title\">{{ config().title }}</h4>\n <c80-icon [button]=\"true\" icon=\"close\" (iconClick)=\"closeModal()\" title=\"Cerrar\" color=\"warn\" />\n </div>\n\n <!-- Modal Body -->\n <div class=\"modal-body\">\n <p class=\"modal-message\">{{ config().message }}</p>\n </div>\n\n <!-- Modal Footer -->\n <div class=\"modal-footer\">\n\n <!-- Info Modal - Solo OK -->\n @if (showOkButton()) {\n <c80-icon [button]=\"true\" icon=\"check\" textRight=\"OK\" (iconClick)=\"onConfirm()\" [border]=\"true\" />\n }\n\n <!-- Yes/No Modal -->\n @if (showYesNoButtons()) {\n <c80-icon [button]=\"true\" icon=\"check\" [textRight]=\"getYesText()\" (iconClick)=\"onYes()\" [border]=\"true\" />\n <c80-icon [button]=\"true\" icon=\"cancel\" [textRight]=\"getNoText()\" color=\"warn\" (iconClick)=\"onNo()\" [border]=\"true\" />\n }\n\n <!-- Confirm Modal -->\n @if (showConfirmButtons()) {\n <c80-icon [button]=\"true\" icon=\"check\" [textRight]=\"getConfirmText()\" (iconClick)=\"onConfirm()\" [border]=\"true\" />\n <c80-icon [button]=\"true\" icon=\"cancel\" [textRight]=\"getCancelText()\" color=\"warn\" (iconClick)=\"onCancel()\" [border]=\"true\" />\n }\n\n </div>\n </dialog>\n</div>\n}"]}
1
+ {"version":3,"file":"modal.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/modal/modal.component.ts","../../../../../libs/ui/src/lib/modal/modal.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, computed, effect, inject, ChangeDetectionStrategy } from '@angular/core';\nimport { ModalService } from './modal.service';\nimport { IconComponent } from './../icon';\n\nexport type ModalType = 'info' | 'confirm' | 'yesNo' | 'warning' | 'error';\n\nexport interface ModalConfig {\n title: string;\n message: string;\n type?: ModalType;\n confirmText?: string;\n cancelText?: string;\n yesText?: string;\n noText?: string;\n showCancel?: boolean;\n}\n\nexport interface ModalResult {\n action: 'confirm' | 'cancel' | 'yes' | 'no';\n confirmed: boolean;\n}\n\n/**\n *\n */\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-modal',\n standalone: true,\n imports: [IconComponent],\n templateUrl: './modal.component.html',\n styleUrl: './modal.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ModalComponent {\n private readonly modalService = inject(ModalService);\n\n readonly isOpen = this.modalService.modalState.isOpen;\n readonly config = this.modalService.modalState.config;\n readonly isVisible = computed(() => this.isOpen());\n\n /**\n *\n */\n constructor() {\n effect(() => {\n if (this.isOpen()) {\n // Auto-focus modal when opened for accessibility\n /* v8 ignore next 8 */\n setTimeout(() => {\n const backdrop = document.querySelector(\n '.modal-backdrop'\n ) as HTMLElement;\n if (backdrop) {\n backdrop.focus();\n }\n }, 100);\n }\n });\n }\n\n /**\n * Maneja la confirmación del modal\n */\n onConfirm(): void {\n this.modalService.handleResult({ action: 'confirm', confirmed: true });\n }\n\n /**\n * Maneja la cancelación del modal\n */\n onCancel(): void {\n this.modalService.handleResult({ action: 'cancel', confirmed: false });\n }\n\n /**\n * Maneja la respuesta afirmativa del modal\n */\n onYes(): void {\n this.modalService.handleResult({ action: 'yes', confirmed: true });\n }\n\n /**\n * Maneja la respuesta negativa del modal\n */\n onNo(): void {\n this.modalService.handleResult({ action: 'no', confirmed: false });\n }\n\n /**\n * Cierra el modal actual\n */\n closeModal(): void {\n this.modalService.closeModal();\n }\n\n /**\n * Maneja el clic en el backdrop del modal\n * @param event - Evento de clic\n */\n onBackdropClick(event: Event): void {\n if (event.target === event.currentTarget) {\n this.closeModal();\n }\n }\n\n /**\n *\n * @returns Clase CSS del botón primario según el tipo de modal\n */\n getPrimaryButtonClass(): string {\n const configValue = this.config();\n switch (configValue.type) {\n case 'warning':\n return 'btn-warning';\n case 'error':\n return 'btn-danger';\n case 'confirm':\n case 'yesNo':\n return 'btn-primary';\n default:\n return 'btn-info';\n }\n }\n\n /**\n *\n * @returns true si debe mostrar botones Sí/No\n */\n showYesNoButtons(): boolean {\n return this.config().type === 'yesNo';\n }\n\n /**\n *\n * @returns true si debe mostrar botones Confirmar/Cancelar\n */\n showConfirmButtons(): boolean {\n const type = this.config().type;\n return type === 'confirm' || type === 'warning' || type === 'error';\n }\n\n /**\n *\n * @returns true si debe mostrar botón OK\n */\n showOkButton(): boolean {\n return this.config().type === 'info';\n }\n\n /**\n *\n * @returns Texto del botón de confirmación\n */\n getConfirmText(): string {\n return this.config().confirmText ?? 'Confirmar';\n }\n\n /**\n *\n * @returns Texto del botón de cancelar\n */\n getCancelText(): string {\n return this.config().cancelText ?? 'Cancelar';\n }\n\n /**\n *\n * @returns Texto del botón Sí\n */\n getYesText(): string {\n return this.config().yesText ?? 'Sí';\n }\n\n /**\n *\n * @returns Texto del botón No\n */\n getNoText(): string {\n return this.config().noText ?? 'No';\n }\n}\n","<!-- Modal Backdrop -->\n@if (isOpen()) {\n<div class=\"modal-backdrop\" [class.show]=\"isVisible()\" tabindex=\"-1\" (click)=\"onBackdropClick($event)\" (keydown.escape)=\"closeModal()\">\n\n <!-- Modal Container -->\n <dialog class=\"modal-container\" [class.show]=\"isVisible()\" [attr.aria-labelledby]=\"'modal-title'\" [open]=\"isVisible()\">\n\n <!-- Modal Header -->\n <div class=\"modal-header\">\n <h4 class=\"modal-title\" id=\"modal-title\">{{ config().title }}</h4>\n <c80-icon [button]=\"true\" icon=\"close\" (iconClick)=\"closeModal()\" title=\"Cerrar\" color=\"warn\" />\n </div>\n\n <!-- Modal Body -->\n <div class=\"modal-body\">\n <p class=\"modal-message\">{{ config().message }}</p>\n </div>\n\n <!-- Modal Footer -->\n <div class=\"modal-footer\">\n\n <!-- Info Modal - Solo OK -->\n @if (showOkButton()) {\n <c80-icon [button]=\"true\" icon=\"check\" textRight=\"OK\" (iconClick)=\"onConfirm()\" [border]=\"true\" />\n }\n\n <!-- Yes/No Modal -->\n @if (showYesNoButtons()) {\n <c80-icon [button]=\"true\" icon=\"check\" [textRight]=\"getYesText()\" (iconClick)=\"onYes()\" [border]=\"true\" />\n <c80-icon [button]=\"true\" icon=\"cancel\" [textRight]=\"getNoText()\" color=\"warn\" (iconClick)=\"onNo()\" [border]=\"true\" />\n }\n\n <!-- Confirm Modal -->\n @if (showConfirmButtons()) {\n <c80-icon [button]=\"true\" icon=\"check\" [textRight]=\"getConfirmText()\" (iconClick)=\"onConfirm()\" [border]=\"true\" />\n <c80-icon [button]=\"true\" icon=\"cancel\" [textRight]=\"getCancelText()\" color=\"warn\" (iconClick)=\"onCancel()\" [border]=\"true\" />\n }\n\n </div>\n </dialog>\n</div>\n}"]}
@@ -1,5 +1,8 @@
1
1
  import { Injectable, signal } from '@angular/core';
2
2
  import * as i0 from "@angular/core";
3
+ /**
4
+ *
5
+ */
3
6
  export class ModalService {
4
7
  isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
5
8
  config = signal({
@@ -12,6 +15,10 @@ export class ModalService {
12
15
  isOpen: this.isOpen.asReadonly(),
13
16
  config: this.config.asReadonly(),
14
17
  };
18
+ /**
19
+ *
20
+ * @param config
21
+ */
15
22
  async showModal(config) {
16
23
  this.config.set(config);
17
24
  this.isOpen.set(true);
@@ -19,7 +26,17 @@ export class ModalService {
19
26
  this.resolvePromise = resolve;
20
27
  });
21
28
  }
22
- async confirm(title, message, confirmText = 'Confirmar', cancelText = 'Cancelar') {
29
+ /**
30
+ *
31
+ * @param options
32
+ * @param options.title
33
+ * @param options.message
34
+ * @param options.confirmText
35
+ * @param options.cancelText
36
+ * @returns Promise que resuelve true si se confirmó
37
+ */
38
+ async confirm(options) {
39
+ const { title, message, confirmText = 'Confirmar', cancelText = 'Cancelar' } = options;
23
40
  return this.showModal({
24
41
  title,
25
42
  message,
@@ -28,7 +45,17 @@ export class ModalService {
28
45
  cancelText,
29
46
  }).then((result) => result.confirmed);
30
47
  }
31
- async yesNo(title, message, yesText = 'Sí', noText = 'No') {
48
+ /**
49
+ *
50
+ * @param options
51
+ * @param options.title
52
+ * @param options.message
53
+ * @param options.yesText
54
+ * @param options.noText
55
+ * @returns Promise que resuelve true si se eligió Sí
56
+ */
57
+ async yesNo(options) {
58
+ const { title, message, yesText = 'Sí', noText = 'No' } = options;
32
59
  return this.showModal({
33
60
  title,
34
61
  message,
@@ -37,6 +64,12 @@ export class ModalService {
37
64
  noText,
38
65
  }).then((result) => result.action === 'yes');
39
66
  }
67
+ /**
68
+ *
69
+ * @param title
70
+ * @param message
71
+ * @returns Promise que resuelve cuando se cierra el modal
72
+ */
40
73
  async info(title, message) {
41
74
  return this.showModal({
42
75
  title,
@@ -44,7 +77,17 @@ export class ModalService {
44
77
  type: 'info',
45
78
  }).then(() => void 0);
46
79
  }
47
- async warning(title, message, confirmText = 'Entendido', cancelText = 'Cancelar') {
80
+ /**
81
+ *
82
+ * @param options
83
+ * @param options.title
84
+ * @param options.message
85
+ * @param options.confirmText
86
+ * @param options.cancelText
87
+ * @returns Promise que resuelve true si se confirmó
88
+ */
89
+ async warning(options) {
90
+ const { title, message, confirmText = 'Entendido', cancelText = 'Cancelar' } = options;
48
91
  return this.showModal({
49
92
  title,
50
93
  message,
@@ -53,6 +96,13 @@ export class ModalService {
53
96
  cancelText,
54
97
  }).then((result) => result.confirmed);
55
98
  }
99
+ /**
100
+ *
101
+ * @param title
102
+ * @param message
103
+ * @param confirmText
104
+ * @returns Promise que resuelve true si se confirmó
105
+ */
56
106
  async error(title, message, confirmText = 'Entendido') {
57
107
  return this.showModal({
58
108
  title,
@@ -61,6 +111,10 @@ export class ModalService {
61
111
  confirmText,
62
112
  }).then(() => void 0);
63
113
  }
114
+ /**
115
+ * Maneja el resultado del modal y resuelve la promesa
116
+ * @param result - Resultado de la acción del modal
117
+ */
64
118
  handleResult(result) {
65
119
  if (this.resolvePromise) {
66
120
  this.resolvePromise(result);
@@ -68,6 +122,9 @@ export class ModalService {
68
122
  }
69
123
  this.closeModal();
70
124
  }
125
+ /**
126
+ * Cierra el modal actual
127
+ */
71
128
  closeModal() {
72
129
  this.isOpen.set(false);
73
130
  }
@@ -1 +1 @@
1
- {"version":3,"file":"modal.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/modal/modal.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, signal } from '@angular/core';\r\nimport type { ModalConfig, ModalResult } from './modal.component';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class ModalService {\r\n private readonly isOpen = signal(false);\r\n private readonly config = signal<ModalConfig>({\r\n title: '',\r\n message: '',\r\n type: 'info',\r\n });\r\n\r\n private resolvePromise?: (result: ModalResult) => void;\r\n\r\n readonly modalState = {\r\n isOpen: this.isOpen.asReadonly(),\r\n config: this.config.asReadonly(),\r\n };\r\n\r\n async showModal(config: ModalConfig): Promise<ModalResult> {\r\n this.config.set(config);\r\n this.isOpen.set(true);\r\n\r\n return new Promise<ModalResult>((resolve) => {\r\n this.resolvePromise = resolve;\r\n });\r\n }\r\n\r\n async confirm(\r\n title: string,\r\n message: string,\r\n confirmText = 'Confirmar',\r\n cancelText = 'Cancelar'\r\n ): Promise<boolean> {\r\n return this.showModal({\r\n title,\r\n message,\r\n type: 'confirm',\r\n confirmText,\r\n cancelText,\r\n }).then((result) => result.confirmed);\r\n }\r\n\r\n async yesNo(\r\n title: string,\r\n message: string,\r\n yesText = 'Sí',\r\n noText = 'No'\r\n ): Promise<boolean> {\r\n return this.showModal({\r\n title,\r\n message,\r\n type: 'yesNo',\r\n yesText,\r\n noText,\r\n }).then((result) => result.action === 'yes');\r\n }\r\n\r\n async info(title: string, message: string): Promise<void> {\r\n return this.showModal({\r\n title,\r\n message,\r\n type: 'info',\r\n }).then(() => void 0);\r\n }\r\n\r\n async warning(\r\n title: string,\r\n message: string,\r\n confirmText = 'Entendido',\r\n cancelText = 'Cancelar'\r\n ): Promise<boolean> {\r\n return this.showModal({\r\n title,\r\n message,\r\n type: 'warning',\r\n confirmText,\r\n cancelText,\r\n }).then((result) => result.confirmed);\r\n }\r\n\r\n async error(\r\n title: string,\r\n message: string,\r\n confirmText = 'Entendido'\r\n ): Promise<void> {\r\n return this.showModal({\r\n title,\r\n message,\r\n type: 'error',\r\n confirmText,\r\n }).then(() => void 0);\r\n }\r\n\r\n handleResult(result: ModalResult) {\r\n if (this.resolvePromise) {\r\n this.resolvePromise(result);\r\n this.resolvePromise = undefined;\r\n }\r\n this.closeModal();\r\n }\r\n\r\n closeModal() {\r\n this.isOpen.set(false);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"modal.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/modal/modal.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, signal } from '@angular/core';\nimport type { ModalConfig, ModalResult } from './modal.component';\n\n/**\n *\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class ModalService {\n private readonly isOpen = signal(false);\n private readonly config = signal<ModalConfig>({\n title: '',\n message: '',\n type: 'info',\n });\n\n private resolvePromise?: (result: ModalResult) => void;\n\n readonly modalState = {\n isOpen: this.isOpen.asReadonly(),\n config: this.config.asReadonly(),\n };\n\n /**\n *\n * @param config\n */\n async showModal(config: ModalConfig): Promise<ModalResult> {\n this.config.set(config);\n this.isOpen.set(true);\n\n return new Promise<ModalResult>((resolve) => {\n this.resolvePromise = resolve;\n });\n }\n\n /**\n *\n * @param options\n * @param options.title\n * @param options.message\n * @param options.confirmText\n * @param options.cancelText\n * @returns Promise que resuelve true si se confirmó\n */\n async confirm(options: {\n title: string;\n message: string;\n confirmText?: string;\n cancelText?: string;\n }): Promise<boolean> {\n const { title, message, confirmText = 'Confirmar', cancelText = 'Cancelar' } = options;\n return this.showModal({\n title,\n message,\n type: 'confirm',\n confirmText,\n cancelText,\n }).then((result) => result.confirmed);\n }\n\n /**\n *\n * @param options\n * @param options.title\n * @param options.message\n * @param options.yesText\n * @param options.noText\n * @returns Promise que resuelve true si se eligió Sí\n */\n async yesNo(options: {\n title: string;\n message: string;\n yesText?: string;\n noText?: string;\n }): Promise<boolean> {\n const { title, message, yesText = 'Sí', noText = 'No' } = options;\n return this.showModal({\n title,\n message,\n type: 'yesNo',\n yesText,\n noText,\n }).then((result) => result.action === 'yes');\n }\n\n /**\n *\n * @param title\n * @param message\n * @returns Promise que resuelve cuando se cierra el modal\n */\n async info(title: string, message: string): Promise<void> {\n return this.showModal({\n title,\n message,\n type: 'info',\n }).then(() => void 0);\n }\n\n /**\n *\n * @param options\n * @param options.title\n * @param options.message\n * @param options.confirmText\n * @param options.cancelText\n * @returns Promise que resuelve true si se confirmó\n */\n async warning(options: {\n title: string;\n message: string;\n confirmText?: string;\n cancelText?: string;\n }): Promise<boolean> {\n const { title, message, confirmText = 'Entendido', cancelText = 'Cancelar' } = options;\n return this.showModal({\n title,\n message,\n type: 'warning',\n confirmText,\n cancelText,\n }).then((result) => result.confirmed);\n }\n\n /**\n *\n * @param title\n * @param message\n * @param confirmText\n * @returns Promise que resuelve true si se confirmó\n */\n async error(\n title: string,\n message: string,\n confirmText = 'Entendido'\n ): Promise<void> {\n return this.showModal({\n title,\n message,\n type: 'error',\n confirmText,\n }).then(() => void 0);\n }\n\n /**\n * Maneja el resultado del modal y resuelve la promesa\n * @param result - Resultado de la acción del modal\n */\n handleResult(result: ModalResult): void {\n if (this.resolvePromise) {\n this.resolvePromise(result);\n this.resolvePromise = undefined;\n }\n this.closeModal();\n }\n\n /**\n * Cierra el modal actual\n */\n closeModal(): void {\n this.isOpen.set(false);\n }\n}\n"]}
@@ -1,12 +1,16 @@
1
1
  import { ChangeDetectionStrategy, Component, input } from '@angular/core';
2
2
  import * as i0 from "@angular/core";
3
+ /**
4
+ * Componente para mostrar estadísticas del usuario
5
+ * Soporta valores con etiquetas o botones de acción
6
+ */
3
7
  export class ProfileStatsComponent {
4
8
  stats = input.required(...(ngDevMode ? [{ debugName: "stats" }] : []));
5
9
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ProfileStatsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: ProfileStatsComponent, isStandalone: true, selector: "c80-profile-stats", inputs: { stats: { classPropertyName: "stats", publicName: "stats", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"stats\">\n @for (stat of stats(); track $index) {\n <div class=\"stats__item\">\n <span class=\"stats__value\">{{ stat.value }}</span>\n <span class=\"stats__label\">{{ stat.label }}</span>\n </div>\n }\n</div>", styles: [".stats{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--spacing-md);text-align:center}.stats__item{display:flex;flex-direction:column;align-items:center;gap:var(--spacing-xs)}.stats__value{font-size:1.25rem;font-weight:var(--font-weight-bold);color:var(--color-text-primary);line-height:1}.stats__label{font-size:.8125rem;color:var(--color-text-secondary);text-transform:lowercase}@media(max-width:768px){.stats{gap:var(--spacing-sm)}.stats__value{font-size:1.125rem}.stats__label{font-size:.75rem}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.10", type: ProfileStatsComponent, isStandalone: true, selector: "c80-profile-stats", inputs: { stats: { classPropertyName: "stats", publicName: "stats", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"stats\">\n @for (stat of stats(); track $index) {\n <div class=\"stats__item\" [class.stats__item--centered]=\"!stat.label && !stat.button\">\n <span class=\"stats__value\">{{ stat.value }}</span>\n @if (stat.button) {\n <button class=\"stats__button\" (click)=\"stat.button.onClick()\">\n {{ stat.button.text }}\n </button>\n } @else if (stat.label) {\n <span class=\"stats__label\">{{ stat.label }}</span>\n }\n </div>\n }\n</div>", styles: [".stats{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--spacing-md);text-align:center}.stats__item{display:flex;flex-direction:column;align-items:center;gap:var(--spacing-xs)}.stats__item--centered{justify-content:center}.stats__value{font-size:1.25rem;font-weight:var(--font-weight-bold);color:var(--color-text-primary);line-height:1}.stats__label{font-size:.8125rem;color:var(--color-text-secondary);text-transform:lowercase}.stats__button{padding:3px 20%;font-size:.8125rem;font-weight:700;color:var(--color-primary);background:transparent;border:1px solid var(--color-primary);border-radius:var(--radius-sm);cursor:pointer;transition:all .2s ease;text-transform:lowercase}@media(max-width:768px){.stats{gap:var(--spacing-sm)}.stats__value{font-size:1.125rem}.stats__label{font-size:.75rem}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7
11
  }
8
12
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: ProfileStatsComponent, decorators: [{
9
13
  type: Component,
10
- args: [{ selector: 'c80-profile-stats', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"stats\">\n @for (stat of stats(); track $index) {\n <div class=\"stats__item\">\n <span class=\"stats__value\">{{ stat.value }}</span>\n <span class=\"stats__label\">{{ stat.label }}</span>\n </div>\n }\n</div>", styles: [".stats{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--spacing-md);text-align:center}.stats__item{display:flex;flex-direction:column;align-items:center;gap:var(--spacing-xs)}.stats__value{font-size:1.25rem;font-weight:var(--font-weight-bold);color:var(--color-text-primary);line-height:1}.stats__label{font-size:.8125rem;color:var(--color-text-secondary);text-transform:lowercase}@media(max-width:768px){.stats{gap:var(--spacing-sm)}.stats__value{font-size:1.125rem}.stats__label{font-size:.75rem}}\n"] }]
14
+ args: [{ selector: 'c80-profile-stats', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"stats\">\n @for (stat of stats(); track $index) {\n <div class=\"stats__item\" [class.stats__item--centered]=\"!stat.label && !stat.button\">\n <span class=\"stats__value\">{{ stat.value }}</span>\n @if (stat.button) {\n <button class=\"stats__button\" (click)=\"stat.button.onClick()\">\n {{ stat.button.text }}\n </button>\n } @else if (stat.label) {\n <span class=\"stats__label\">{{ stat.label }}</span>\n }\n </div>\n }\n</div>", styles: [".stats{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--spacing-md);text-align:center}.stats__item{display:flex;flex-direction:column;align-items:center;gap:var(--spacing-xs)}.stats__item--centered{justify-content:center}.stats__value{font-size:1.25rem;font-weight:var(--font-weight-bold);color:var(--color-text-primary);line-height:1}.stats__label{font-size:.8125rem;color:var(--color-text-secondary);text-transform:lowercase}.stats__button{padding:3px 20%;font-size:.8125rem;font-weight:700;color:var(--color-primary);background:transparent;border:1px solid var(--color-primary);border-radius:var(--radius-sm);cursor:pointer;transition:all .2s ease;text-transform:lowercase}@media(max-width:768px){.stats{gap:var(--spacing-sm)}.stats__value{font-size:1.125rem}.stats__label{font-size:.75rem}}\n"] }]
11
15
  }], propDecorators: { stats: [{ type: i0.Input, args: [{ isSignal: true, alias: "stats", required: true }] }] } });
12
16
  //# sourceMappingURL=profile-stats.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"profile-stats.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/profile-stats/profile-stats.component.ts","../../../../../libs/ui/src/lib/profile-stats/profile-stats.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;;AAW1E,MAAM,OAAO,qBAAqB;IAC9B,KAAK,GAAG,KAAK,CAAC,QAAQ,gDAAc,CAAC;wGAD5B,qBAAqB;4FAArB,qBAAqB,gNCXlC,2PAOM;;4FDIO,qBAAqB;kBARjC,SAAS;+BAEI,mBAAmB,cACjB,IAAI,mBAGC,uBAAuB,CAAC,MAAM","sourcesContent":["import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport type { StatItem } from './profile-stats.types';\n\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-profile-stats',\n standalone: true,\n templateUrl: './profile-stats.component.html',\n styleUrl: './profile-stats.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ProfileStatsComponent {\n stats = input.required<StatItem[]>();\n}","<div class=\"stats\">\n @for (stat of stats(); track $index) {\n <div class=\"stats__item\">\n <span class=\"stats__value\">{{ stat.value }}</span>\n <span class=\"stats__label\">{{ stat.label }}</span>\n </div>\n }\n</div>"]}
1
+ {"version":3,"file":"profile-stats.component.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/profile-stats/profile-stats.component.ts","../../../../../libs/ui/src/lib/profile-stats/profile-stats.component.html"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;;AAG1E;;;GAGG;AASH,MAAM,OAAO,qBAAqB;IAC9B,KAAK,GAAG,KAAK,CAAC,QAAQ,gDAAc,CAAC;wGAD5B,qBAAqB;4FAArB,qBAAqB,gNCflC,ugBAaM;;4FDEO,qBAAqB;kBARjC,SAAS;+BAEI,mBAAmB,cACjB,IAAI,mBAGC,uBAAuB,CAAC,MAAM","sourcesContent":["import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport type { StatItem } from './profile-stats.types';\n\n/**\n * Componente para mostrar estadísticas del usuario\n * Soporta valores con etiquetas o botones de acción\n */\n@Component({\n // eslint-disable-next-line @angular-eslint/component-selector\n selector: 'c80-profile-stats',\n standalone: true,\n templateUrl: './profile-stats.component.html',\n styleUrl: './profile-stats.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class ProfileStatsComponent {\n stats = input.required<StatItem[]>();\n}","<div class=\"stats\">\n @for (stat of stats(); track $index) {\n <div class=\"stats__item\" [class.stats__item--centered]=\"!stat.label && !stat.button\">\n <span class=\"stats__value\">{{ stat.value }}</span>\n @if (stat.button) {\n <button class=\"stats__button\" (click)=\"stat.button.onClick()\">\n {{ stat.button.text }}\n </button>\n } @else if (stat.label) {\n <span class=\"stats__label\">{{ stat.label }}</span>\n }\n </div>\n }\n</div>"]}
@@ -1 +1 @@
1
- {"version":3,"file":"profile-stats.types.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/profile-stats/profile-stats.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface StatItem {\n label: string;\n value: number | string;\n}"]}
1
+ {"version":3,"file":"profile-stats.types.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/profile-stats/profile-stats.types.ts"],"names":[],"mappings":"","sourcesContent":["export interface StatItem {\n value?: number | string;\n label?: string;\n button?: {\n text: string;\n onClick: () => void;\n };\n}"]}
@@ -0,0 +1,2 @@
1
+ export * from './rating-display.component';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/rating-display/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC","sourcesContent":["export * from './rating-display.component';\n"]}