ng-comps 1.0.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/fesm2022/ng-comps.mjs +4254 -0
  2. package/package.json +54 -58
  3. package/src/styles.css +54 -0
  4. package/types/ng-comps.d.ts +1348 -0
  5. package/.editorconfig +0 -17
  6. package/.github/copilot-instructions.md +0 -55
  7. package/.github/workflows/ci.yml +0 -29
  8. package/.prettierrc +0 -12
  9. package/.storybook/main.ts +0 -21
  10. package/.storybook/preview.ts +0 -27
  11. package/.storybook/tsconfig.doc.json +0 -10
  12. package/.storybook/tsconfig.json +0 -15
  13. package/.storybook/typings.d.ts +0 -4
  14. package/.vscode/extensions.json +0 -4
  15. package/.vscode/launch.json +0 -20
  16. package/.vscode/mcp.json +0 -9
  17. package/.vscode/tasks.json +0 -42
  18. package/ACCESSIBILITY.md +0 -127
  19. package/angular.json +0 -106
  20. package/documentation.json +0 -13394
  21. package/ng-package.json +0 -27
  22. package/public/favicon.ico +0 -0
  23. package/scripts/prepare-package.mjs +0 -80
  24. package/src/app/a11y/accessibility.utils.ts +0 -35
  25. package/src/app/a11y/index.ts +0 -6
  26. package/src/app/accessibility/ng-comps.a11y.spec.ts +0 -108
  27. package/src/app/app.config.ts +0 -11
  28. package/src/app/app.css +0 -107
  29. package/src/app/app.html +0 -48
  30. package/src/app/app.routes.ts +0 -3
  31. package/src/app/app.spec.ts +0 -23
  32. package/src/app/app.ts +0 -10
  33. package/src/app/components/accordion/index.ts +0 -2
  34. package/src/app/components/accordion/mf-accordion.component.css +0 -38
  35. package/src/app/components/accordion/mf-accordion.component.spec.ts +0 -48
  36. package/src/app/components/accordion/mf-accordion.component.ts +0 -53
  37. package/src/app/components/alert/index.ts +0 -2
  38. package/src/app/components/alert/mf-alert.component.css +0 -100
  39. package/src/app/components/alert/mf-alert.component.spec.ts +0 -59
  40. package/src/app/components/alert/mf-alert.component.ts +0 -68
  41. package/src/app/components/autocomplete/index.ts +0 -5
  42. package/src/app/components/autocomplete/mf-autocomplete.component.css +0 -105
  43. package/src/app/components/autocomplete/mf-autocomplete.component.spec.ts +0 -116
  44. package/src/app/components/autocomplete/mf-autocomplete.component.ts +0 -307
  45. package/src/app/components/avatar/index.ts +0 -2
  46. package/src/app/components/avatar/mf-avatar.component.css +0 -27
  47. package/src/app/components/avatar/mf-avatar.component.spec.ts +0 -49
  48. package/src/app/components/avatar/mf-avatar.component.ts +0 -99
  49. package/src/app/components/badge/index.ts +0 -2
  50. package/src/app/components/badge/mf-badge.component.css +0 -32
  51. package/src/app/components/badge/mf-badge.component.spec.ts +0 -40
  52. package/src/app/components/badge/mf-badge.component.ts +0 -105
  53. package/src/app/components/breadcrumb/index.ts +0 -2
  54. package/src/app/components/breadcrumb/mf-breadcrumb.component.css +0 -61
  55. package/src/app/components/breadcrumb/mf-breadcrumb.component.spec.ts +0 -61
  56. package/src/app/components/breadcrumb/mf-breadcrumb.component.ts +0 -75
  57. package/src/app/components/button/index.ts +0 -2
  58. package/src/app/components/button/mf-button.component.css +0 -136
  59. package/src/app/components/button/mf-button.component.ts +0 -174
  60. package/src/app/components/card/index.ts +0 -2
  61. package/src/app/components/card/mf-card.component.css +0 -82
  62. package/src/app/components/card/mf-card.component.ts +0 -59
  63. package/src/app/components/checkbox/index.ts +0 -1
  64. package/src/app/components/checkbox/mf-checkbox.component.css +0 -75
  65. package/src/app/components/checkbox/mf-checkbox.component.ts +0 -187
  66. package/src/app/components/chip/index.ts +0 -2
  67. package/src/app/components/chip/mf-chip.component.css +0 -69
  68. package/src/app/components/chip/mf-chip.component.spec.ts +0 -47
  69. package/src/app/components/chip/mf-chip.component.ts +0 -77
  70. package/src/app/components/datepicker/index.ts +0 -2
  71. package/src/app/components/datepicker/mf-datepicker.component.css +0 -102
  72. package/src/app/components/datepicker/mf-datepicker.component.spec.ts +0 -69
  73. package/src/app/components/datepicker/mf-datepicker.component.ts +0 -233
  74. package/src/app/components/dialog/index.ts +0 -3
  75. package/src/app/components/dialog/mf-dialog.component.css +0 -73
  76. package/src/app/components/dialog/mf-dialog.component.ts +0 -160
  77. package/src/app/components/dialog/mf-dialog.service.spec.ts +0 -61
  78. package/src/app/components/dialog/mf-dialog.service.ts +0 -52
  79. package/src/app/components/divider/index.ts +0 -2
  80. package/src/app/components/divider/mf-divider.component.css +0 -38
  81. package/src/app/components/divider/mf-divider.component.spec.ts +0 -40
  82. package/src/app/components/divider/mf-divider.component.ts +0 -44
  83. package/src/app/components/form-field/index.ts +0 -1
  84. package/src/app/components/form-field/mf-form-field.component.css +0 -51
  85. package/src/app/components/form-field/mf-form-field.component.ts +0 -74
  86. package/src/app/components/grid-list/index.ts +0 -2
  87. package/src/app/components/grid-list/mf-grid-list.component.css +0 -47
  88. package/src/app/components/grid-list/mf-grid-list.component.spec.ts +0 -57
  89. package/src/app/components/grid-list/mf-grid-list.component.ts +0 -68
  90. package/src/app/components/icon/index.ts +0 -2
  91. package/src/app/components/icon/mf-icon.component.css +0 -56
  92. package/src/app/components/icon/mf-icon.component.ts +0 -41
  93. package/src/app/components/input/index.ts +0 -2
  94. package/src/app/components/input/mf-input.component.css +0 -105
  95. package/src/app/components/input/mf-input.component.ts +0 -217
  96. package/src/app/components/menu/index.ts +0 -2
  97. package/src/app/components/menu/mf-menu.component.css +0 -31
  98. package/src/app/components/menu/mf-menu.component.spec.ts +0 -49
  99. package/src/app/components/menu/mf-menu.component.ts +0 -66
  100. package/src/app/components/paginator/index.ts +0 -1
  101. package/src/app/components/paginator/mf-paginator.component.css +0 -32
  102. package/src/app/components/paginator/mf-paginator.component.spec.ts +0 -44
  103. package/src/app/components/paginator/mf-paginator.component.ts +0 -52
  104. package/src/app/components/progress-bar/index.ts +0 -2
  105. package/src/app/components/progress-bar/mf-progress-bar.component.css +0 -53
  106. package/src/app/components/progress-bar/mf-progress-bar.component.spec.ts +0 -65
  107. package/src/app/components/progress-bar/mf-progress-bar.component.ts +0 -79
  108. package/src/app/components/progress-spinner/index.ts +0 -2
  109. package/src/app/components/progress-spinner/mf-progress-spinner.component.css +0 -38
  110. package/src/app/components/progress-spinner/mf-progress-spinner.component.spec.ts +0 -59
  111. package/src/app/components/progress-spinner/mf-progress-spinner.component.ts +0 -81
  112. package/src/app/components/radio-button/index.ts +0 -2
  113. package/src/app/components/radio-button/mf-radio-button.component.css +0 -86
  114. package/src/app/components/radio-button/mf-radio-button.component.spec.ts +0 -55
  115. package/src/app/components/radio-button/mf-radio-button.component.ts +0 -219
  116. package/src/app/components/select/index.ts +0 -2
  117. package/src/app/components/select/mf-select.component.css +0 -121
  118. package/src/app/components/select/mf-select.component.spec.ts +0 -108
  119. package/src/app/components/select/mf-select.component.ts +0 -252
  120. package/src/app/components/sidenav/index.ts +0 -2
  121. package/src/app/components/sidenav/mf-sidenav.component.css +0 -168
  122. package/src/app/components/sidenav/mf-sidenav.component.spec.ts +0 -57
  123. package/src/app/components/sidenav/mf-sidenav.component.ts +0 -126
  124. package/src/app/components/slide-toggle/index.ts +0 -1
  125. package/src/app/components/slide-toggle/mf-slide-toggle.component.css +0 -42
  126. package/src/app/components/slide-toggle/mf-slide-toggle.component.spec.ts +0 -43
  127. package/src/app/components/slide-toggle/mf-slide-toggle.component.ts +0 -188
  128. package/src/app/components/snackbar/index.ts +0 -2
  129. package/src/app/components/snackbar/mf-snackbar.service.css +0 -31
  130. package/src/app/components/snackbar/mf-snackbar.service.spec.ts +0 -81
  131. package/src/app/components/snackbar/mf-snackbar.service.ts +0 -77
  132. package/src/app/components/table/index.ts +0 -2
  133. package/src/app/components/table/mf-table.component.css +0 -68
  134. package/src/app/components/table/mf-table.component.spec.ts +0 -76
  135. package/src/app/components/table/mf-table.component.ts +0 -117
  136. package/src/app/components/tabs/index.ts +0 -2
  137. package/src/app/components/tabs/mf-tabs.component.css +0 -31
  138. package/src/app/components/tabs/mf-tabs.component.spec.ts +0 -50
  139. package/src/app/components/tabs/mf-tabs.component.ts +0 -62
  140. package/src/app/components/textarea/index.ts +0 -2
  141. package/src/app/components/textarea/mf-textarea.component.css +0 -48
  142. package/src/app/components/textarea/mf-textarea.component.spec.ts +0 -55
  143. package/src/app/components/textarea/mf-textarea.component.ts +0 -227
  144. package/src/app/components/toolbar/index.ts +0 -2
  145. package/src/app/components/toolbar/mf-toolbar.component.css +0 -77
  146. package/src/app/components/toolbar/mf-toolbar.component.ts +0 -56
  147. package/src/app/components/tooltip/index.ts +0 -3
  148. package/src/app/components/tooltip/mf-tooltip.component.css +0 -7
  149. package/src/app/components/tooltip/mf-tooltip.component.spec.ts +0 -37
  150. package/src/app/components/tooltip/mf-tooltip.component.ts +0 -47
  151. package/src/app/components/tooltip/mf-tooltip.directive.ts +0 -22
  152. package/src/index.html +0 -18
  153. package/src/main.ts +0 -6
  154. package/src/public-api.ts +0 -31
  155. package/src/stories/About.mdx +0 -72
  156. package/src/stories/Accessibility.mdx +0 -59
  157. package/src/stories/Welcome.mdx +0 -26
  158. package/src/stories/assets/accessibility.png +0 -0
  159. package/src/stories/assets/accessibility.svg +0 -1
  160. package/src/stories/assets/addon-library.png +0 -0
  161. package/src/stories/assets/assets.png +0 -0
  162. package/src/stories/assets/avif-test-image.avif +0 -0
  163. package/src/stories/assets/context.png +0 -0
  164. package/src/stories/assets/discord.svg +0 -1
  165. package/src/stories/assets/docs.png +0 -0
  166. package/src/stories/assets/figma-plugin.png +0 -0
  167. package/src/stories/assets/github.svg +0 -1
  168. package/src/stories/assets/share.png +0 -0
  169. package/src/stories/assets/styling.png +0 -0
  170. package/src/stories/assets/testing.png +0 -0
  171. package/src/stories/assets/theming.png +0 -0
  172. package/src/stories/assets/tutorials.svg +0 -1
  173. package/src/stories/assets/youtube.svg +0 -1
  174. package/src/stories/mf-a11y-contracts.stories.ts +0 -472
  175. package/src/stories/mf-autocomplete.stories.ts +0 -194
  176. package/src/stories/mf-button.stories.ts +0 -152
  177. package/src/stories/mf-card.stories.ts +0 -147
  178. package/src/stories/mf-checkbox.stories.ts +0 -88
  179. package/src/stories/mf-datepicker.stories.ts +0 -118
  180. package/src/stories/mf-dialog.stories.ts +0 -159
  181. package/src/stories/mf-form-field.stories.ts +0 -108
  182. package/src/stories/mf-grid-list.stories.ts +0 -104
  183. package/src/stories/mf-icon.stories.ts +0 -133
  184. package/src/stories/mf-input.stories.ts +0 -158
  185. package/src/stories/mf-menu.stories.ts +0 -71
  186. package/src/stories/mf-progress-bar.stories.ts +0 -119
  187. package/src/stories/mf-progress-spinner.stories.ts +0 -124
  188. package/src/stories/mf-radio-button.stories.ts +0 -111
  189. package/src/stories/mf-select.stories.ts +0 -184
  190. package/src/stories/mf-sidenav.stories.ts +0 -331
  191. package/src/stories/mf-table.stories.ts +0 -80
  192. package/src/stories/mf-toolbar.stories.ts +0 -112
  193. package/src/stories/user.ts +0 -3
  194. package/tsconfig.app.json +0 -15
  195. package/tsconfig.json +0 -33
  196. package/tsconfig.spec.json +0 -15
  197. package/vercel.json +0 -6
@@ -0,0 +1,4254 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, computed, ChangeDetectionStrategy, Component, output, isDevMode, inject, ChangeDetectorRef, signal, effect, forwardRef, Injectable, Directive } from '@angular/core';
3
+ import * as i1 from '@angular/material/expansion';
4
+ import { MatExpansionModule } from '@angular/material/expansion';
5
+ import * as i2 from '@angular/material/icon';
6
+ import { MatIconModule } from '@angular/material/icon';
7
+ import { NgControl, NG_VALUE_ACCESSOR } from '@angular/forms';
8
+ import * as i1$1 from '@angular/material/autocomplete';
9
+ import { MatAutocompleteModule } from '@angular/material/autocomplete';
10
+ import * as i2$1 from '@angular/material/form-field';
11
+ import { MatFormFieldModule } from '@angular/material/form-field';
12
+ import * as i4 from '@angular/material/input';
13
+ import { MatInputModule } from '@angular/material/input';
14
+ import * as i1$2 from '@angular/material/badge';
15
+ import { MatBadgeModule } from '@angular/material/badge';
16
+ import * as i1$3 from '@angular/material/button';
17
+ import { MatButtonModule } from '@angular/material/button';
18
+ import * as i1$4 from '@angular/material/card';
19
+ import { MatCardModule } from '@angular/material/card';
20
+ import * as i1$5 from '@angular/material/checkbox';
21
+ import { MatCheckboxModule } from '@angular/material/checkbox';
22
+ import * as i1$6 from '@angular/material/chips';
23
+ import { MatChipsModule } from '@angular/material/chips';
24
+ import { MatNativeDateModule } from '@angular/material/core';
25
+ import * as i1$7 from '@angular/material/datepicker';
26
+ import { MatDatepickerModule } from '@angular/material/datepicker';
27
+ import * as i1$8 from '@angular/material/dialog';
28
+ import { MatDialogRef, MatDialogModule, MatDialog } from '@angular/material/dialog';
29
+ import * as i1$9 from '@angular/material/divider';
30
+ import { MatDividerModule } from '@angular/material/divider';
31
+ import * as i1$a from '@angular/material/grid-list';
32
+ import { MatGridListModule } from '@angular/material/grid-list';
33
+ import * as i1$b from '@angular/material/menu';
34
+ import { MatMenuModule } from '@angular/material/menu';
35
+ import * as i1$c from '@angular/material/paginator';
36
+ import { MatPaginatorModule } from '@angular/material/paginator';
37
+ import * as i1$d from '@angular/material/progress-bar';
38
+ import { MatProgressBarModule } from '@angular/material/progress-bar';
39
+ import * as i1$e from '@angular/material/progress-spinner';
40
+ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
41
+ import * as i1$f from '@angular/material/radio';
42
+ import { MatRadioModule } from '@angular/material/radio';
43
+ import * as i2$2 from '@angular/material/select';
44
+ import { MatSelectModule } from '@angular/material/select';
45
+ import * as i1$g from '@angular/material/sidenav';
46
+ import { MatSidenavModule } from '@angular/material/sidenav';
47
+ import * as i1$h from '@angular/material/slide-toggle';
48
+ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
49
+ import { MatSnackBar } from '@angular/material/snack-bar';
50
+ import * as i2$3 from '@angular/material/sort';
51
+ import { MatSortModule } from '@angular/material/sort';
52
+ import * as i1$i from '@angular/material/table';
53
+ import { MatTableModule } from '@angular/material/table';
54
+ import * as i1$j from '@angular/material/tabs';
55
+ import { MatTabsModule } from '@angular/material/tabs';
56
+ import * as i1$k from '@angular/material/toolbar';
57
+ import { MatToolbarModule } from '@angular/material/toolbar';
58
+ import * as i1$l from '@angular/material/tooltip';
59
+ import { MatTooltip } from '@angular/material/tooltip';
60
+
61
+ /**
62
+ * Accordion de la librería ng-comps.
63
+ * Envuelve Angular Material `mat-accordion` / `mat-expansion-panel` y expone
64
+ * una API uniforme con look and feel de marca.
65
+ */
66
+ class MfAccordionComponent {
67
+ /** Paneles del accordion */
68
+ panels = input.required(...(ngDevMode ? [{ debugName: "panels" }] : /* istanbul ignore next */ []));
69
+ /** Permite múltiples paneles abiertos */
70
+ multi = input(false, ...(ngDevMode ? [{ debugName: "multi" }] : /* istanbul ignore next */ []));
71
+ hostClasses = computed(() => 'mf-accordion', ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
72
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfAccordionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
73
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfAccordionComponent, isStandalone: true, selector: "mf-accordion", inputs: { panels: { classPropertyName: "panels", publicName: "panels", isSignal: true, isRequired: true, transformFunction: null }, multi: { classPropertyName: "multi", publicName: "multi", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
74
+ <mat-accordion [multi]="multi()" [class]="hostClasses()">
75
+ @for (panel of panels(); track panel.title) {
76
+ <mat-expansion-panel
77
+ [expanded]="panel.expanded ?? false"
78
+ [disabled]="panel.disabled ?? false"
79
+ >
80
+ <mat-expansion-panel-header>
81
+ <mat-panel-title>{{ panel.title }}</mat-panel-title>
82
+ @if (panel.description) {
83
+ <mat-panel-description>{{ panel.description }}</mat-panel-description>
84
+ }
85
+ </mat-expansion-panel-header>
86
+ <p>{{ panel.content }}</p>
87
+ </mat-expansion-panel>
88
+ }
89
+ </mat-accordion>
90
+ `, isInline: true, styles: [":host{display:block}.mf-accordion .mat-expansion-panel{font-family:var(--mf-font-base)!important;border-radius:var(--mf-radius-md)!important;box-shadow:var(--mf-shadow-none)!important;border:1px solid var(--mf-color-border);margin-bottom:var(--mf-space-2)}.mf-accordion .mat-expansion-panel-header{font-family:var(--mf-font-base)!important}.mf-accordion .mat-expansion-panel-header-title{font-weight:var(--mf-weight-bold)!important;color:var(--mf-color-on-surface)!important}.mf-accordion .mat-expansion-panel-header-description{color:var(--mf-color-neutral-400)!important}.mf-accordion .mat-expansion-panel-body{font-size:var(--mf-text-sm)!important;color:var(--mf-color-neutral-600)!important;line-height:var(--mf-leading-normal)}.mf-accordion .mat-expansion-indicator:after{color:var(--mf-color-brand)!important}.mf-accordion .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:hover{background-color:var(--mf-color-brand-light)!important}\n"], dependencies: [{ kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i1.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i1.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i1.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i1.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i1.MatExpansionPanelDescription, selector: "mat-panel-description" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
91
+ }
92
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfAccordionComponent, decorators: [{
93
+ type: Component,
94
+ args: [{ selector: 'mf-accordion', imports: [MatExpansionModule], template: `
95
+ <mat-accordion [multi]="multi()" [class]="hostClasses()">
96
+ @for (panel of panels(); track panel.title) {
97
+ <mat-expansion-panel
98
+ [expanded]="panel.expanded ?? false"
99
+ [disabled]="panel.disabled ?? false"
100
+ >
101
+ <mat-expansion-panel-header>
102
+ <mat-panel-title>{{ panel.title }}</mat-panel-title>
103
+ @if (panel.description) {
104
+ <mat-panel-description>{{ panel.description }}</mat-panel-description>
105
+ }
106
+ </mat-expansion-panel-header>
107
+ <p>{{ panel.content }}</p>
108
+ </mat-expansion-panel>
109
+ }
110
+ </mat-accordion>
111
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.mf-accordion .mat-expansion-panel{font-family:var(--mf-font-base)!important;border-radius:var(--mf-radius-md)!important;box-shadow:var(--mf-shadow-none)!important;border:1px solid var(--mf-color-border);margin-bottom:var(--mf-space-2)}.mf-accordion .mat-expansion-panel-header{font-family:var(--mf-font-base)!important}.mf-accordion .mat-expansion-panel-header-title{font-weight:var(--mf-weight-bold)!important;color:var(--mf-color-on-surface)!important}.mf-accordion .mat-expansion-panel-header-description{color:var(--mf-color-neutral-400)!important}.mf-accordion .mat-expansion-panel-body{font-size:var(--mf-text-sm)!important;color:var(--mf-color-neutral-600)!important;line-height:var(--mf-leading-normal)}.mf-accordion .mat-expansion-indicator:after{color:var(--mf-color-brand)!important}.mf-accordion .mat-expansion-panel:not(.mat-expanded) .mat-expansion-panel-header:hover{background-color:var(--mf-color-brand-light)!important}\n"] }]
112
+ }], propDecorators: { panels: [{ type: i0.Input, args: [{ isSignal: true, alias: "panels", required: true }] }], multi: [{ type: i0.Input, args: [{ isSignal: true, alias: "multi", required: false }] }] } });
113
+
114
+ /**
115
+ * Alerta de la librería ng-comps.
116
+ * Componente de banner para mensajes de sistema, alertas y notificaciones.
117
+ * Ideal para dashboards y paneles administrativos.
118
+ */
119
+ class MfAlertComponent {
120
+ /** Mensaje principal */
121
+ message = input.required(...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
122
+ /** Título opcional */
123
+ title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
124
+ /** Severidad de la alerta */
125
+ severity = input('info', ...(ngDevMode ? [{ debugName: "severity" }] : /* istanbul ignore next */ []));
126
+ /** Se puede cerrar */
127
+ dismissible = input(false, ...(ngDevMode ? [{ debugName: "dismissible" }] : /* istanbul ignore next */ []));
128
+ mfDismiss = output();
129
+ iconName = computed(() => {
130
+ const map = {
131
+ info: 'info',
132
+ success: 'check_circle',
133
+ warning: 'warning',
134
+ error: 'error',
135
+ };
136
+ return map[this.severity()];
137
+ }, ...(ngDevMode ? [{ debugName: "iconName" }] : /* istanbul ignore next */ []));
138
+ hostClasses = computed(() => {
139
+ return ['mf-alert', `mf-alert--${this.severity()}`].join(' ');
140
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
141
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfAlertComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
142
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfAlertComponent, isStandalone: true, selector: "mf-alert", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, severity: { classPropertyName: "severity", publicName: "severity", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfDismiss: "mfDismiss" }, ngImport: i0, template: `
143
+ <div [class]="hostClasses()" role="alert">
144
+ <mat-icon class="mf-alert__icon" aria-hidden="true">{{ iconName() }}</mat-icon>
145
+ <div class="mf-alert__content">
146
+ @if (title()) {
147
+ <strong class="mf-alert__title">{{ title() }}</strong>
148
+ }
149
+ <span class="mf-alert__message">{{ message() }}</span>
150
+ </div>
151
+ @if (dismissible()) {
152
+ <button
153
+ class="mf-alert__close"
154
+ (click)="mfDismiss.emit()"
155
+ [attr.aria-label]="'Close alert'"
156
+ >
157
+ <mat-icon aria-hidden="true">close</mat-icon>
158
+ </button>
159
+ }
160
+ </div>
161
+ `, isInline: true, styles: [":host{display:block}.mf-alert{display:flex;align-items:flex-start;gap:var(--mf-space-3);padding:var(--mf-space-3) var(--mf-space-4);border-radius:var(--mf-radius-md);font-family:var(--mf-font-base);font-size:var(--mf-text-sm);line-height:var(--mf-leading-normal)}.mf-alert--info{background-color:var(--mf-color-secondary-50);border-left:4px solid var(--mf-color-secondary-500);color:var(--mf-color-secondary-900)}.mf-alert--info .mf-alert__icon{color:var(--mf-color-secondary-500)}.mf-alert--success{background-color:var(--mf-color-primary-50);border-left:4px solid var(--mf-color-primary-500);color:var(--mf-color-primary-900)}.mf-alert--success .mf-alert__icon{color:var(--mf-color-primary-500)}.mf-alert--warning{background-color:#fffbeb;border-left:4px solid var(--mf-color-accent-500);color:var(--mf-color-accent-700)}.mf-alert--warning .mf-alert__icon{color:var(--mf-color-accent-500)}.mf-alert--error{background-color:#fef2f2;border-left:4px solid var(--mf-color-error-500);color:var(--mf-color-error-700)}.mf-alert--error .mf-alert__icon{color:var(--mf-color-error-500)}.mf-alert__content{flex:1;display:flex;flex-direction:column;gap:var(--mf-space-1)}.mf-alert__title{font-weight:var(--mf-weight-bold)}.mf-alert__icon{flex-shrink:0;margin-top:1px}.mf-alert__close{display:inline-flex;align-items:center;justify-content:center;border:none;background:none;cursor:pointer;padding:var(--mf-space-1);border-radius:var(--mf-radius-sm);color:inherit;opacity:.6;transition:opacity var(--mf-duration-fast) var(--mf-ease-standard)}.mf-alert__close:hover{opacity:1}.mf-alert__close .mat-icon{font-size:18px;width:18px;height:18px}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
162
+ }
163
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfAlertComponent, decorators: [{
164
+ type: Component,
165
+ args: [{ selector: 'mf-alert', imports: [MatIconModule], template: `
166
+ <div [class]="hostClasses()" role="alert">
167
+ <mat-icon class="mf-alert__icon" aria-hidden="true">{{ iconName() }}</mat-icon>
168
+ <div class="mf-alert__content">
169
+ @if (title()) {
170
+ <strong class="mf-alert__title">{{ title() }}</strong>
171
+ }
172
+ <span class="mf-alert__message">{{ message() }}</span>
173
+ </div>
174
+ @if (dismissible()) {
175
+ <button
176
+ class="mf-alert__close"
177
+ (click)="mfDismiss.emit()"
178
+ [attr.aria-label]="'Close alert'"
179
+ >
180
+ <mat-icon aria-hidden="true">close</mat-icon>
181
+ </button>
182
+ }
183
+ </div>
184
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.mf-alert{display:flex;align-items:flex-start;gap:var(--mf-space-3);padding:var(--mf-space-3) var(--mf-space-4);border-radius:var(--mf-radius-md);font-family:var(--mf-font-base);font-size:var(--mf-text-sm);line-height:var(--mf-leading-normal)}.mf-alert--info{background-color:var(--mf-color-secondary-50);border-left:4px solid var(--mf-color-secondary-500);color:var(--mf-color-secondary-900)}.mf-alert--info .mf-alert__icon{color:var(--mf-color-secondary-500)}.mf-alert--success{background-color:var(--mf-color-primary-50);border-left:4px solid var(--mf-color-primary-500);color:var(--mf-color-primary-900)}.mf-alert--success .mf-alert__icon{color:var(--mf-color-primary-500)}.mf-alert--warning{background-color:#fffbeb;border-left:4px solid var(--mf-color-accent-500);color:var(--mf-color-accent-700)}.mf-alert--warning .mf-alert__icon{color:var(--mf-color-accent-500)}.mf-alert--error{background-color:#fef2f2;border-left:4px solid var(--mf-color-error-500);color:var(--mf-color-error-700)}.mf-alert--error .mf-alert__icon{color:var(--mf-color-error-500)}.mf-alert__content{flex:1;display:flex;flex-direction:column;gap:var(--mf-space-1)}.mf-alert__title{font-weight:var(--mf-weight-bold)}.mf-alert__icon{flex-shrink:0;margin-top:1px}.mf-alert__close{display:inline-flex;align-items:center;justify-content:center;border:none;background:none;cursor:pointer;padding:var(--mf-space-1);border-radius:var(--mf-radius-sm);color:inherit;opacity:.6;transition:opacity var(--mf-duration-fast) var(--mf-ease-standard)}.mf-alert__close:hover{opacity:1}.mf-alert__close .mat-icon{font-size:18px;width:18px;height:18px}\n"] }]
185
+ }], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: true }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], severity: [{ type: i0.Input, args: [{ isSignal: true, alias: "severity", required: false }] }], dismissible: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissible", required: false }] }], mfDismiss: [{ type: i0.Output, args: ["mfDismiss"] }] } });
186
+
187
+ let nextUniqueId = 0;
188
+ const emittedWarnings = new Set();
189
+ function createUniqueId(prefix) {
190
+ nextUniqueId += 1;
191
+ return `${prefix}-${nextUniqueId}`;
192
+ }
193
+ function mergeAriaIds(...values) {
194
+ const ids = values
195
+ .flatMap((value) => (value ? value.split(/\s+/) : []))
196
+ .map((value) => value.trim())
197
+ .filter(Boolean);
198
+ return ids.length > 0 ? Array.from(new Set(ids)).join(' ') : null;
199
+ }
200
+ function hasAccessibleName(...values) {
201
+ return values.some((value) => Boolean(value?.trim()));
202
+ }
203
+ function warnInDev(message) {
204
+ if (!isDevMode() || emittedWarnings.has(message)) {
205
+ return;
206
+ }
207
+ emittedWarnings.add(message);
208
+ console.warn(`[ng-comps:a11y] ${message}`);
209
+ }
210
+
211
+ /**
212
+ * Autocompletar de la librería ng-comps.
213
+ * Envuelve Angular Material `mat-autocomplete` y expone una API uniforme
214
+ * con look and feel de marca.
215
+ *
216
+ * El panel desplegable se estiliza con la clase global `mf-autocomplete-panel`.
217
+ * Puedes añadir clases adicionales con `panelClass`.
218
+ */
219
+ class MfAutocompleteComponent {
220
+ cdr = inject(ChangeDetectorRef);
221
+ ngControl = inject(NgControl, { self: true, optional: true });
222
+ generatedId = createUniqueId('mf-autocomplete');
223
+ disabledFromForm = signal(false, ...(ngDevMode ? [{ debugName: "disabledFromForm" }] : /* istanbul ignore next */ []));
224
+ internalValue = signal('', ...(ngDevMode ? [{ debugName: "internalValue" }] : /* istanbul ignore next */ []));
225
+ onControlChange = () => undefined;
226
+ onControlTouched = () => undefined;
227
+ errorStateMatcher = {
228
+ isErrorState: (control) => Boolean(this.error() || (control?.invalid && (control.touched || control.dirty))),
229
+ };
230
+ /** Lista completa de opciones */
231
+ options = input.required(...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
232
+ /** ID del control */
233
+ id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
234
+ /** Etiqueta flotante del campo */
235
+ label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
236
+ /** Etiqueta accesible alternativa cuando no existe label visible */
237
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
238
+ /** Referencia externa a elementos que etiquetan el control */
239
+ ariaLabelledby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : /* istanbul ignore next */ []));
240
+ /** Referencia externa a elementos descriptivos adicionales */
241
+ ariaDescribedby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaDescribedby" }] : /* istanbul ignore next */ []));
242
+ /** Placeholder del input */
243
+ placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
244
+ /** Valor actual (texto en el campo) */
245
+ value = input('', ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
246
+ /** Deshabilitado */
247
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
248
+ /** Requerido */
249
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
250
+ /** Tamaño del campo */
251
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
252
+ /** Ancho completo */
253
+ fullWidth = input(false, ...(ngDevMode ? [{ debugName: "fullWidth" }] : /* istanbul ignore next */ []));
254
+ /** Texto de ayuda debajo del campo */
255
+ hint = input(undefined, ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
256
+ /** Mensaje de error */
257
+ error = input(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
258
+ /** Icono al inicio del campo */
259
+ leadingIcon = input(undefined, ...(ngDevMode ? [{ debugName: "leadingIcon" }] : /* istanbul ignore next */ []));
260
+ /** Icono al final del campo */
261
+ trailingIcon = input(undefined, ...(ngDevMode ? [{ debugName: "trailingIcon" }] : /* istanbul ignore next */ []));
262
+ /**
263
+ * Ancho del panel del autocomplete.
264
+ * Por defecto `''`: el panel toma el mismo ancho que el campo.
265
+ * Acepta cualquier valor CSS válido ('300px', '80vw', etc.) para sobreescribirlo.
266
+ */
267
+ panelWidth = input('', ...(ngDevMode ? [{ debugName: "panelWidth" }] : /* istanbul ignore next */ []));
268
+ /**
269
+ * Clases extra que se añaden al panel del autocomplete (overlay).
270
+ * La clase `mf-autocomplete-panel` siempre está presente.
271
+ */
272
+ panelClass = input('', ...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
273
+ /** Emite el texto escrito en el campo */
274
+ mfInput = output();
275
+ /** Emite el valor de la opción seleccionada */
276
+ mfOptionSelected = output();
277
+ mfBlur = output();
278
+ constructor() {
279
+ effect(() => {
280
+ this.internalValue.set(this.value());
281
+ });
282
+ effect(() => {
283
+ if (!hasAccessibleName(this.label(), this.ariaLabel(), this.ariaLabelledby())) {
284
+ warnInDev('mf-autocomplete requiere `label`, `ariaLabel` o `ariaLabelledby` para exponer un nombre accesible.');
285
+ }
286
+ });
287
+ }
288
+ controlId = computed(() => this.id() ?? this.generatedId, ...(ngDevMode ? [{ debugName: "controlId" }] : /* istanbul ignore next */ []));
289
+ hintId = computed(() => this.hint() ? `${this.controlId()}-hint` : null, ...(ngDevMode ? [{ debugName: "hintId" }] : /* istanbul ignore next */ []));
290
+ errorId = computed(() => this.error() ? `${this.controlId()}-error` : null, ...(ngDevMode ? [{ debugName: "errorId" }] : /* istanbul ignore next */ []));
291
+ describedBy = computed(() => mergeAriaIds(this.ariaDescribedby(), this.hintId(), this.errorId()), ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
292
+ resolvedAriaLabel = computed(() => this.label() ? null : this.ariaLabel() ?? null, ...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
293
+ isDisabled = computed(() => this.disabled() || this.disabledFromForm(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
294
+ hostClasses = computed(() => {
295
+ const classes = ['mf-autocomplete', `mf-autocomplete--${this.size()}`];
296
+ if (this.fullWidth())
297
+ classes.push('mf-autocomplete--full');
298
+ if (this.error())
299
+ classes.push('mf-autocomplete--error');
300
+ return classes.join(' ');
301
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
302
+ autocompletePanelClasses = computed(() => {
303
+ const base = ['mf-autocomplete-panel'];
304
+ const extra = this.panelClass();
305
+ if (Array.isArray(extra)) {
306
+ base.push(...extra.filter(Boolean));
307
+ }
308
+ else if (extra) {
309
+ base.push(extra);
310
+ }
311
+ return base.join(' ');
312
+ }, ...(ngDevMode ? [{ debugName: "autocompletePanelClasses" }] : /* istanbul ignore next */ []));
313
+ filteredOptions = computed(() => {
314
+ const query = this.internalValue().toLowerCase().trim();
315
+ if (!query) {
316
+ return this.options();
317
+ }
318
+ return this.options().filter((option) => option.label.toLowerCase().includes(query));
319
+ }, ...(ngDevMode ? [{ debugName: "filteredOptions" }] : /* istanbul ignore next */ []));
320
+ get inputValue() {
321
+ return this.internalValue();
322
+ }
323
+ set inputValue(value) {
324
+ this.internalValue.set(value);
325
+ }
326
+ writeValue(value) {
327
+ this.internalValue.set(value ?? '');
328
+ this.cdr.markForCheck();
329
+ }
330
+ registerOnChange(fn) {
331
+ this.onControlChange = fn;
332
+ }
333
+ registerOnTouched(fn) {
334
+ this.onControlTouched = fn;
335
+ }
336
+ setDisabledState(isDisabled) {
337
+ this.disabledFromForm.set(isDisabled);
338
+ this.cdr.markForCheck();
339
+ }
340
+ isInvalid() {
341
+ const control = this.ngControl?.control;
342
+ return Boolean(this.error() || (control?.invalid && (control.touched || control.dirty)));
343
+ }
344
+ onInputChange(event) {
345
+ const value = typeof event === 'string'
346
+ ? event
347
+ : event.target.value;
348
+ this.internalValue.set(value);
349
+ this.onControlChange(value);
350
+ this.mfInput.emit(value);
351
+ }
352
+ onOptionSelected(event) {
353
+ const label = event.option.value;
354
+ const match = this.options().find((option) => option.label === label);
355
+ if (match) {
356
+ this.internalValue.set(match.label);
357
+ this.onControlChange(match.label);
358
+ this.onControlTouched();
359
+ this.mfOptionSelected.emit(match);
360
+ }
361
+ }
362
+ onBlur() {
363
+ this.onControlTouched();
364
+ this.mfBlur.emit();
365
+ }
366
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfAutocompleteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
367
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfAutocompleteComponent, isStandalone: true, selector: "mf-autocomplete", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "ariaDescribedby", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, leadingIcon: { classPropertyName: "leadingIcon", publicName: "leadingIcon", isSignal: true, isRequired: false, transformFunction: null }, trailingIcon: { classPropertyName: "trailingIcon", publicName: "trailingIcon", isSignal: true, isRequired: false, transformFunction: null }, panelWidth: { classPropertyName: "panelWidth", publicName: "panelWidth", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfInput: "mfInput", mfOptionSelected: "mfOptionSelected", mfBlur: "mfBlur" }, providers: [
368
+ {
369
+ provide: NG_VALUE_ACCESSOR,
370
+ useExisting: forwardRef(() => MfAutocompleteComponent),
371
+ multi: true,
372
+ },
373
+ ], ngImport: i0, template: `
374
+ <mat-form-field [appearance]="'outline'" [class]="hostClasses()">
375
+ @if (label()) {
376
+ <mat-label>{{ label() }}</mat-label>
377
+ }
378
+ @if (leadingIcon()) {
379
+ <mat-icon matPrefix aria-hidden="true">{{ leadingIcon() }}</mat-icon>
380
+ }
381
+ <input
382
+ matInput
383
+ [id]="controlId()"
384
+ [placeholder]="placeholder()"
385
+ [disabled]="isDisabled()"
386
+ [required]="required()"
387
+ [matAutocomplete]="auto"
388
+ [value]="internalValue()"
389
+ [errorStateMatcher]="errorStateMatcher"
390
+ [attr.aria-label]="resolvedAriaLabel()"
391
+ [attr.aria-labelledby]="ariaLabelledby() || null"
392
+ [attr.aria-describedby]="describedBy()"
393
+ [attr.aria-invalid]="isInvalid() ? 'true' : null"
394
+ [attr.aria-required]="required() ? 'true' : null"
395
+ (input)="onInputChange($event)"
396
+ (blur)="onBlur()"
397
+ />
398
+ @if (trailingIcon()) {
399
+ <mat-icon matSuffix aria-hidden="true">{{ trailingIcon() }}</mat-icon>
400
+ }
401
+ @if (hint()) {
402
+ <mat-hint [attr.id]="hintId()">{{ hint() }}</mat-hint>
403
+ }
404
+ <mat-autocomplete
405
+ #auto
406
+ [panelWidth]="panelWidth()"
407
+ [class]="autocompletePanelClasses()"
408
+ (optionSelected)="onOptionSelected($event)"
409
+ >
410
+ @for (option of filteredOptions(); track option.value) {
411
+ <mat-option [value]="option.label" [disabled]="option.disabled ?? false">
412
+ {{ option.label }}
413
+ </mat-option>
414
+ }
415
+ </mat-autocomplete>
416
+ </mat-form-field>
417
+ @if (error()) {
418
+ <p class="mf-autocomplete__error" [attr.id]="errorId()" role="alert">
419
+ {{ error() }}
420
+ </p>
421
+ }
422
+ `, isInline: true, styles: [":host{display:inline-block}.mf-autocomplete{font-family:var(--mf-font-base)!important;width:100%}.mf-autocomplete--full{width:100%}.mf-autocomplete .mat-mdc-text-field-wrapper{border-radius:var(--mf-radius-md)!important}.mf-autocomplete .mdc-notched-outline__leading,.mf-autocomplete .mdc-notched-outline__notch,.mf-autocomplete .mdc-notched-outline__trailing{border-color:var(--mf-color-border)!important;transition:border-color var(--mf-duration-base) var(--mf-ease-standard)}.mf-autocomplete .mat-mdc-form-field-focus-overlay{background-color:transparent!important}.mf-autocomplete.mat-focused .mdc-notched-outline__leading,.mf-autocomplete.mat-focused .mdc-notched-outline__notch,.mf-autocomplete.mat-focused .mdc-notched-outline__trailing{border-color:var(--mf-color-brand)!important;border-width:1.5px!important}.mf-autocomplete--error .mdc-notched-outline__leading,.mf-autocomplete--error .mdc-notched-outline__notch,.mf-autocomplete--error .mdc-notched-outline__trailing{border-color:var(--mf-color-error-500)!important}.mf-autocomplete .mat-mdc-floating-label{font-family:var(--mf-font-base)!important;font-weight:var(--mf-weight-medium)!important;color:var(--mf-color-neutral-400)!important}.mf-autocomplete.mat-focused .mat-mdc-floating-label{color:var(--mf-color-brand)!important}.mf-autocomplete .mat-mdc-input-element{font-family:var(--mf-font-base)!important;color:var(--mf-color-on-surface)!important;caret-color:var(--mf-color-brand)}.mf-autocomplete .mat-mdc-form-field-hint{font-size:var(--mf-text-xs)!important;color:var(--mf-color-neutral-400)!important}.mf-autocomplete .mat-mdc-form-field-error{font-size:var(--mf-text-xs)!important}.mf-autocomplete .mat-icon{color:var(--mf-color-neutral-400)!important;font-size:20px;width:20px;height:20px;transition:color var(--mf-duration-base) var(--mf-ease-standard)}.mf-autocomplete.mat-focused .mat-icon{color:var(--mf-color-brand)!important}.mf-autocomplete--sm .mat-mdc-input-element{font-size:var(--mf-text-sm)!important}.mf-autocomplete--md .mat-mdc-input-element{font-size:var(--mf-text-base)!important}.mf-autocomplete--lg .mat-mdc-input-element{font-size:var(--mf-text-lg)!important;padding-top:var(--mf-space-1)!important;padding-bottom:var(--mf-space-1)!important}.mf-autocomplete .mat-mdc-input-element:disabled{color:var(--mf-color-neutral-300)!important}\n"], dependencies: [{ kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i1$1.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i1$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i1$1.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
423
+ }
424
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfAutocompleteComponent, decorators: [{
425
+ type: Component,
426
+ args: [{ selector: 'mf-autocomplete', imports: [
427
+ MatAutocompleteModule,
428
+ MatFormFieldModule,
429
+ MatIconModule,
430
+ MatInputModule,
431
+ ], providers: [
432
+ {
433
+ provide: NG_VALUE_ACCESSOR,
434
+ useExisting: forwardRef(() => MfAutocompleteComponent),
435
+ multi: true,
436
+ },
437
+ ], template: `
438
+ <mat-form-field [appearance]="'outline'" [class]="hostClasses()">
439
+ @if (label()) {
440
+ <mat-label>{{ label() }}</mat-label>
441
+ }
442
+ @if (leadingIcon()) {
443
+ <mat-icon matPrefix aria-hidden="true">{{ leadingIcon() }}</mat-icon>
444
+ }
445
+ <input
446
+ matInput
447
+ [id]="controlId()"
448
+ [placeholder]="placeholder()"
449
+ [disabled]="isDisabled()"
450
+ [required]="required()"
451
+ [matAutocomplete]="auto"
452
+ [value]="internalValue()"
453
+ [errorStateMatcher]="errorStateMatcher"
454
+ [attr.aria-label]="resolvedAriaLabel()"
455
+ [attr.aria-labelledby]="ariaLabelledby() || null"
456
+ [attr.aria-describedby]="describedBy()"
457
+ [attr.aria-invalid]="isInvalid() ? 'true' : null"
458
+ [attr.aria-required]="required() ? 'true' : null"
459
+ (input)="onInputChange($event)"
460
+ (blur)="onBlur()"
461
+ />
462
+ @if (trailingIcon()) {
463
+ <mat-icon matSuffix aria-hidden="true">{{ trailingIcon() }}</mat-icon>
464
+ }
465
+ @if (hint()) {
466
+ <mat-hint [attr.id]="hintId()">{{ hint() }}</mat-hint>
467
+ }
468
+ <mat-autocomplete
469
+ #auto
470
+ [panelWidth]="panelWidth()"
471
+ [class]="autocompletePanelClasses()"
472
+ (optionSelected)="onOptionSelected($event)"
473
+ >
474
+ @for (option of filteredOptions(); track option.value) {
475
+ <mat-option [value]="option.label" [disabled]="option.disabled ?? false">
476
+ {{ option.label }}
477
+ </mat-option>
478
+ }
479
+ </mat-autocomplete>
480
+ </mat-form-field>
481
+ @if (error()) {
482
+ <p class="mf-autocomplete__error" [attr.id]="errorId()" role="alert">
483
+ {{ error() }}
484
+ </p>
485
+ }
486
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-block}.mf-autocomplete{font-family:var(--mf-font-base)!important;width:100%}.mf-autocomplete--full{width:100%}.mf-autocomplete .mat-mdc-text-field-wrapper{border-radius:var(--mf-radius-md)!important}.mf-autocomplete .mdc-notched-outline__leading,.mf-autocomplete .mdc-notched-outline__notch,.mf-autocomplete .mdc-notched-outline__trailing{border-color:var(--mf-color-border)!important;transition:border-color var(--mf-duration-base) var(--mf-ease-standard)}.mf-autocomplete .mat-mdc-form-field-focus-overlay{background-color:transparent!important}.mf-autocomplete.mat-focused .mdc-notched-outline__leading,.mf-autocomplete.mat-focused .mdc-notched-outline__notch,.mf-autocomplete.mat-focused .mdc-notched-outline__trailing{border-color:var(--mf-color-brand)!important;border-width:1.5px!important}.mf-autocomplete--error .mdc-notched-outline__leading,.mf-autocomplete--error .mdc-notched-outline__notch,.mf-autocomplete--error .mdc-notched-outline__trailing{border-color:var(--mf-color-error-500)!important}.mf-autocomplete .mat-mdc-floating-label{font-family:var(--mf-font-base)!important;font-weight:var(--mf-weight-medium)!important;color:var(--mf-color-neutral-400)!important}.mf-autocomplete.mat-focused .mat-mdc-floating-label{color:var(--mf-color-brand)!important}.mf-autocomplete .mat-mdc-input-element{font-family:var(--mf-font-base)!important;color:var(--mf-color-on-surface)!important;caret-color:var(--mf-color-brand)}.mf-autocomplete .mat-mdc-form-field-hint{font-size:var(--mf-text-xs)!important;color:var(--mf-color-neutral-400)!important}.mf-autocomplete .mat-mdc-form-field-error{font-size:var(--mf-text-xs)!important}.mf-autocomplete .mat-icon{color:var(--mf-color-neutral-400)!important;font-size:20px;width:20px;height:20px;transition:color var(--mf-duration-base) var(--mf-ease-standard)}.mf-autocomplete.mat-focused .mat-icon{color:var(--mf-color-brand)!important}.mf-autocomplete--sm .mat-mdc-input-element{font-size:var(--mf-text-sm)!important}.mf-autocomplete--md .mat-mdc-input-element{font-size:var(--mf-text-base)!important}.mf-autocomplete--lg .mat-mdc-input-element{font-size:var(--mf-text-lg)!important;padding-top:var(--mf-space-1)!important;padding-bottom:var(--mf-space-1)!important}.mf-autocomplete .mat-mdc-input-element:disabled{color:var(--mf-color-neutral-300)!important}\n"] }]
487
+ }], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledby", required: false }] }], ariaDescribedby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedby", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], leadingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "leadingIcon", required: false }] }], trailingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "trailingIcon", required: false }] }], panelWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelWidth", required: false }] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], mfInput: [{ type: i0.Output, args: ["mfInput"] }], mfOptionSelected: [{ type: i0.Output, args: ["mfOptionSelected"] }], mfBlur: [{ type: i0.Output, args: ["mfBlur"] }] } });
488
+
489
+ /**
490
+ * Avatar de la librería ng-comps.
491
+ * Muestra una imagen de perfil, iniciales o un icono.
492
+ * Componente puro sin dependencia de Angular Material.
493
+ */
494
+ class MfAvatarComponent {
495
+ /** URL de la imagen */
496
+ src = input(undefined, ...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []));
497
+ /** Texto alternativo */
498
+ alt = input('', ...(ngDevMode ? [{ debugName: "alt" }] : /* istanbul ignore next */ []));
499
+ /** Nombre completo para generar iniciales */
500
+ name = input('', ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
501
+ /** Si es decorativo, se oculta a tecnologías asistivas */
502
+ decorative = input(false, ...(ngDevMode ? [{ debugName: "decorative" }] : /* istanbul ignore next */ []));
503
+ /** Tamaño */
504
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
505
+ /** Forma */
506
+ variant = input('circle', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
507
+ constructor() {
508
+ effect(() => {
509
+ if (!this.decorative() && !hasAccessibleName(this.alt(), this.name())) {
510
+ warnInDev('mf-avatar requiere `alt` o `name` cuando no es decorativo para exponer un nombre accesible.');
511
+ }
512
+ });
513
+ }
514
+ initials = computed(() => {
515
+ const n = this.name();
516
+ if (!n)
517
+ return '?';
518
+ const parts = n.trim().split(/\s+/);
519
+ if (parts.length === 1)
520
+ return parts[0].charAt(0).toUpperCase();
521
+ return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase();
522
+ }, ...(ngDevMode ? [{ debugName: "initials" }] : /* istanbul ignore next */ []));
523
+ imageAlt = computed(() => {
524
+ if (this.decorative()) {
525
+ return '';
526
+ }
527
+ return this.alt() || this.name();
528
+ }, ...(ngDevMode ? [{ debugName: "imageAlt" }] : /* istanbul ignore next */ []));
529
+ fallbackAriaLabel = computed(() => {
530
+ if (this.decorative()) {
531
+ return null;
532
+ }
533
+ return this.alt() || this.name() || null;
534
+ }, ...(ngDevMode ? [{ debugName: "fallbackAriaLabel" }] : /* istanbul ignore next */ []));
535
+ hostClasses = computed(() => {
536
+ return [
537
+ 'mf-avatar',
538
+ `mf-avatar--${this.size()}`,
539
+ `mf-avatar--${this.variant()}`,
540
+ ].join(' ');
541
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
542
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
543
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfAvatarComponent, isStandalone: true, selector: "mf-avatar", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, decorative: { classPropertyName: "decorative", publicName: "decorative", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
544
+ @if (src()) {
545
+ <img
546
+ [src]="src()"
547
+ [alt]="imageAlt()"
548
+ [class]="hostClasses()"
549
+ [attr.aria-hidden]="decorative() ? 'true' : null"
550
+ />
551
+ } @else {
552
+ <span
553
+ [class]="hostClasses()"
554
+ [attr.aria-label]="fallbackAriaLabel()"
555
+ [attr.aria-hidden]="decorative() ? 'true' : null"
556
+ >
557
+ {{ initials() }}
558
+ </span>
559
+ }
560
+ `, isInline: true, styles: [":host{display:inline-block}.mf-avatar{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;object-fit:cover;background-color:var(--mf-color-primary-100);color:var(--mf-color-primary-800);font-family:var(--mf-font-base);font-weight:var(--mf-weight-bold);-webkit-user-select:none;user-select:none}.mf-avatar--xs{width:24px;height:24px;font-size:var(--mf-text-xs)}.mf-avatar--sm{width:32px;height:32px;font-size:var(--mf-text-sm)}.mf-avatar--md{width:40px;height:40px;font-size:var(--mf-text-base)}.mf-avatar--lg{width:56px;height:56px;font-size:var(--mf-text-xl)}.mf-avatar--xl{width:80px;height:80px;font-size:var(--mf-text-3xl)}.mf-avatar--circle{border-radius:var(--mf-radius-full)}.mf-avatar--rounded{border-radius:var(--mf-radius-md)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
561
+ }
562
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfAvatarComponent, decorators: [{
563
+ type: Component,
564
+ args: [{ selector: 'mf-avatar', imports: [], template: `
565
+ @if (src()) {
566
+ <img
567
+ [src]="src()"
568
+ [alt]="imageAlt()"
569
+ [class]="hostClasses()"
570
+ [attr.aria-hidden]="decorative() ? 'true' : null"
571
+ />
572
+ } @else {
573
+ <span
574
+ [class]="hostClasses()"
575
+ [attr.aria-label]="fallbackAriaLabel()"
576
+ [attr.aria-hidden]="decorative() ? 'true' : null"
577
+ >
578
+ {{ initials() }}
579
+ </span>
580
+ }
581
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-block}.mf-avatar{display:inline-flex;align-items:center;justify-content:center;overflow:hidden;object-fit:cover;background-color:var(--mf-color-primary-100);color:var(--mf-color-primary-800);font-family:var(--mf-font-base);font-weight:var(--mf-weight-bold);-webkit-user-select:none;user-select:none}.mf-avatar--xs{width:24px;height:24px;font-size:var(--mf-text-xs)}.mf-avatar--sm{width:32px;height:32px;font-size:var(--mf-text-sm)}.mf-avatar--md{width:40px;height:40px;font-size:var(--mf-text-base)}.mf-avatar--lg{width:56px;height:56px;font-size:var(--mf-text-xl)}.mf-avatar--xl{width:80px;height:80px;font-size:var(--mf-text-3xl)}.mf-avatar--circle{border-radius:var(--mf-radius-full)}.mf-avatar--rounded{border-radius:var(--mf-radius-md)}\n"] }]
582
+ }], ctorParameters: () => [], propDecorators: { src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], alt: [{ type: i0.Input, args: [{ isSignal: true, alias: "alt", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], decorative: [{ type: i0.Input, args: [{ isSignal: true, alias: "decorative", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }] } });
583
+
584
+ /**
585
+ * Badge de la librería ng-comps.
586
+ * Envuelve Angular Material `matBadge` y expone una API uniforme
587
+ * con look and feel de marca.
588
+ */
589
+ class MfBadgeComponent {
590
+ /** Contenido del badge (texto o número) */
591
+ content = input('', ...(ngDevMode ? [{ debugName: "content" }] : /* istanbul ignore next */ []));
592
+ /** Descripción accesible del badge */
593
+ description = input(undefined, ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
594
+ /** Si es decorativo, se oculta a tecnologías asistivas */
595
+ decorative = input(false, ...(ngDevMode ? [{ debugName: "decorative" }] : /* istanbul ignore next */ []));
596
+ /** Color semántico */
597
+ color = input('brand', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
598
+ /** Tamaño del badge */
599
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
600
+ /** Posición del badge */
601
+ position = input('above-after', ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
602
+ /** Ocultar el badge */
603
+ hidden = input(false, ...(ngDevMode ? [{ debugName: "hidden" }] : /* istanbul ignore next */ []));
604
+ /** Deshabilitado */
605
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
606
+ /** Superponer sobre el contenido */
607
+ overlap = input(true, ...(ngDevMode ? [{ debugName: "overlap" }] : /* istanbul ignore next */ []));
608
+ constructor() {
609
+ effect(() => {
610
+ if (!this.decorative() && this.content() !== '' && !this.description()) {
611
+ warnInDev('mf-badge debería incluir `description` cuando el badge transmite información relevante.');
612
+ }
613
+ });
614
+ }
615
+ badgeDescription = computed(() => this.decorative() ? '' : this.description() ?? '', ...(ngDevMode ? [{ debugName: "badgeDescription" }] : /* istanbul ignore next */ []));
616
+ matPosition = computed(() => {
617
+ const pos = this.position();
618
+ const map = {
619
+ 'above-after': 'above after',
620
+ 'above-before': 'above before',
621
+ 'below-after': 'below after',
622
+ 'below-before': 'below before',
623
+ };
624
+ return map[pos];
625
+ }, ...(ngDevMode ? [{ debugName: "matPosition" }] : /* istanbul ignore next */ []));
626
+ matSize = computed(() => {
627
+ const map = {
628
+ sm: 'small',
629
+ md: 'medium',
630
+ lg: 'large',
631
+ };
632
+ return map[this.size()];
633
+ }, ...(ngDevMode ? [{ debugName: "matSize" }] : /* istanbul ignore next */ []));
634
+ hostClasses = computed(() => {
635
+ return ['mf-badge', `mf-badge--${this.color()}`].join(' ');
636
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
637
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
638
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: MfBadgeComponent, isStandalone: true, selector: "mf-badge", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, decorative: { classPropertyName: "decorative", publicName: "decorative", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, hidden: { classPropertyName: "hidden", publicName: "hidden", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, overlap: { classPropertyName: "overlap", publicName: "overlap", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
639
+ <span
640
+ [matBadge]="content()"
641
+ [matBadgeHidden]="hidden()"
642
+ [matBadgeDisabled]="disabled()"
643
+ [matBadgeOverlap]="overlap()"
644
+ [matBadgePosition]="matPosition()"
645
+ [matBadgeSize]="matSize()"
646
+ [matBadgeDescription]="badgeDescription()"
647
+ [attr.aria-hidden]="decorative() ? 'true' : null"
648
+ [class]="hostClasses()"
649
+ >
650
+ <ng-content />
651
+ </span>
652
+ `, isInline: true, styles: [":host{display:inline-block}.mf-badge--brand .mat-badge-content{background-color:var(--mf-color-brand)!important;color:var(--mf-color-on-brand)!important}.mf-badge--accent .mat-badge-content{background-color:var(--mf-color-accent-500)!important;color:var(--mf-color-neutral-900)!important}.mf-badge--error .mat-badge-content{background-color:var(--mf-color-error-500)!important;color:var(--mf-color-neutral-0)!important}.mf-badge--neutral .mat-badge-content{background-color:var(--mf-color-neutral-400)!important;color:var(--mf-color-neutral-0)!important}.mat-badge-content{font-family:var(--mf-font-base)!important;font-weight:var(--mf-weight-bold)!important}\n"], dependencies: [{ kind: "ngmodule", type: MatBadgeModule }, { kind: "directive", type: i1$2.MatBadge, selector: "[matBadge]", inputs: ["matBadgeColor", "matBadgeOverlap", "matBadgeDisabled", "matBadgePosition", "matBadge", "matBadgeDescription", "matBadgeSize", "matBadgeHidden"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
653
+ }
654
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfBadgeComponent, decorators: [{
655
+ type: Component,
656
+ args: [{ selector: 'mf-badge', imports: [MatBadgeModule], template: `
657
+ <span
658
+ [matBadge]="content()"
659
+ [matBadgeHidden]="hidden()"
660
+ [matBadgeDisabled]="disabled()"
661
+ [matBadgeOverlap]="overlap()"
662
+ [matBadgePosition]="matPosition()"
663
+ [matBadgeSize]="matSize()"
664
+ [matBadgeDescription]="badgeDescription()"
665
+ [attr.aria-hidden]="decorative() ? 'true' : null"
666
+ [class]="hostClasses()"
667
+ >
668
+ <ng-content />
669
+ </span>
670
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-block}.mf-badge--brand .mat-badge-content{background-color:var(--mf-color-brand)!important;color:var(--mf-color-on-brand)!important}.mf-badge--accent .mat-badge-content{background-color:var(--mf-color-accent-500)!important;color:var(--mf-color-neutral-900)!important}.mf-badge--error .mat-badge-content{background-color:var(--mf-color-error-500)!important;color:var(--mf-color-neutral-0)!important}.mf-badge--neutral .mat-badge-content{background-color:var(--mf-color-neutral-400)!important;color:var(--mf-color-neutral-0)!important}.mat-badge-content{font-family:var(--mf-font-base)!important;font-weight:var(--mf-weight-bold)!important}\n"] }]
671
+ }], ctorParameters: () => [], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], decorative: [{ type: i0.Input, args: [{ isSignal: true, alias: "decorative", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], hidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidden", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], overlap: [{ type: i0.Input, args: [{ isSignal: true, alias: "overlap", required: false }] }] } });
672
+
673
+ /**
674
+ * Breadcrumb de la librería ng-comps.
675
+ * Componente de navegación jerárquica para indicar la ubicación
676
+ * del usuario en la aplicación.
677
+ */
678
+ class MfBreadcrumbComponent {
679
+ /** Items del breadcrumb */
680
+ items = input.required(...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
681
+ /** Icono separador */
682
+ separator = input('chevron_right', ...(ngDevMode ? [{ debugName: "separator" }] : /* istanbul ignore next */ []));
683
+ /** Label de accesibilidad */
684
+ ariaLabel = input('Breadcrumb', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
685
+ mfItemClick = output();
686
+ hostClasses = computed(() => 'mf-breadcrumb', ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
687
+ onItemClick(event, item) {
688
+ event.preventDefault();
689
+ this.mfItemClick.emit(item);
690
+ }
691
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
692
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfBreadcrumbComponent, isStandalone: true, selector: "mf-breadcrumb", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, separator: { classPropertyName: "separator", publicName: "separator", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfItemClick: "mfItemClick" }, ngImport: i0, template: `
693
+ <nav [attr.aria-label]="ariaLabel()" [class]="hostClasses()">
694
+ <ol class="mf-breadcrumb__list">
695
+ @for (item of items(); track item.label; let last = $last) {
696
+ <li class="mf-breadcrumb__item">
697
+ @if (!last && item.href) {
698
+ <a
699
+ class="mf-breadcrumb__link"
700
+ [href]="item.href"
701
+ (click)="onItemClick($event, item)"
702
+ >
703
+ @if (item.icon) {
704
+ <mat-icon class="mf-breadcrumb__icon" aria-hidden="true">{{ item.icon }}</mat-icon>
705
+ }
706
+ {{ item.label }}
707
+ </a>
708
+ } @else {
709
+ <span class="mf-breadcrumb__current" [attr.aria-current]="last ? 'page' : null">
710
+ @if (item.icon) {
711
+ <mat-icon class="mf-breadcrumb__icon" aria-hidden="true">{{ item.icon }}</mat-icon>
712
+ }
713
+ {{ item.label }}
714
+ </span>
715
+ }
716
+ @if (!last) {
717
+ <mat-icon class="mf-breadcrumb__separator" aria-hidden="true">{{ separator() }}</mat-icon>
718
+ }
719
+ </li>
720
+ }
721
+ </ol>
722
+ </nav>
723
+ `, isInline: true, styles: [":host{display:block}.mf-breadcrumb__list{display:flex;align-items:center;flex-wrap:wrap;list-style:none;margin:0;padding:0;gap:var(--mf-space-1)}.mf-breadcrumb__item{display:flex;align-items:center;gap:var(--mf-space-1)}.mf-breadcrumb__link{display:inline-flex;align-items:center;gap:var(--mf-space-1);color:var(--mf-color-brand);text-decoration:none;font-family:var(--mf-font-base);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-medium);padding:var(--mf-space-1) var(--mf-space-2);border-radius:var(--mf-radius-sm);transition:background-color var(--mf-duration-fast) var(--mf-ease-standard)}.mf-breadcrumb__link:hover{background-color:var(--mf-color-brand-light)}.mf-breadcrumb__current{display:inline-flex;align-items:center;gap:var(--mf-space-1);color:var(--mf-color-neutral-400);font-family:var(--mf-font-base);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-medium);padding:var(--mf-space-1) var(--mf-space-2)}.mf-breadcrumb__separator{font-size:18px!important;width:18px!important;height:18px!important;color:var(--mf-color-neutral-300)}.mf-breadcrumb__icon{font-size:16px!important;width:16px!important;height:16px!important}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
724
+ }
725
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfBreadcrumbComponent, decorators: [{
726
+ type: Component,
727
+ args: [{ selector: 'mf-breadcrumb', imports: [MatIconModule], template: `
728
+ <nav [attr.aria-label]="ariaLabel()" [class]="hostClasses()">
729
+ <ol class="mf-breadcrumb__list">
730
+ @for (item of items(); track item.label; let last = $last) {
731
+ <li class="mf-breadcrumb__item">
732
+ @if (!last && item.href) {
733
+ <a
734
+ class="mf-breadcrumb__link"
735
+ [href]="item.href"
736
+ (click)="onItemClick($event, item)"
737
+ >
738
+ @if (item.icon) {
739
+ <mat-icon class="mf-breadcrumb__icon" aria-hidden="true">{{ item.icon }}</mat-icon>
740
+ }
741
+ {{ item.label }}
742
+ </a>
743
+ } @else {
744
+ <span class="mf-breadcrumb__current" [attr.aria-current]="last ? 'page' : null">
745
+ @if (item.icon) {
746
+ <mat-icon class="mf-breadcrumb__icon" aria-hidden="true">{{ item.icon }}</mat-icon>
747
+ }
748
+ {{ item.label }}
749
+ </span>
750
+ }
751
+ @if (!last) {
752
+ <mat-icon class="mf-breadcrumb__separator" aria-hidden="true">{{ separator() }}</mat-icon>
753
+ }
754
+ </li>
755
+ }
756
+ </ol>
757
+ </nav>
758
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.mf-breadcrumb__list{display:flex;align-items:center;flex-wrap:wrap;list-style:none;margin:0;padding:0;gap:var(--mf-space-1)}.mf-breadcrumb__item{display:flex;align-items:center;gap:var(--mf-space-1)}.mf-breadcrumb__link{display:inline-flex;align-items:center;gap:var(--mf-space-1);color:var(--mf-color-brand);text-decoration:none;font-family:var(--mf-font-base);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-medium);padding:var(--mf-space-1) var(--mf-space-2);border-radius:var(--mf-radius-sm);transition:background-color var(--mf-duration-fast) var(--mf-ease-standard)}.mf-breadcrumb__link:hover{background-color:var(--mf-color-brand-light)}.mf-breadcrumb__current{display:inline-flex;align-items:center;gap:var(--mf-space-1);color:var(--mf-color-neutral-400);font-family:var(--mf-font-base);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-medium);padding:var(--mf-space-1) var(--mf-space-2)}.mf-breadcrumb__separator{font-size:18px!important;width:18px!important;height:18px!important;color:var(--mf-color-neutral-300)}.mf-breadcrumb__icon{font-size:16px!important;width:16px!important;height:16px!important}\n"] }]
759
+ }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], separator: [{ type: i0.Input, args: [{ isSignal: true, alias: "separator", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], mfItemClick: [{ type: i0.Output, args: ["mfItemClick"] }] } });
760
+
761
+ /**
762
+ * Botón de la librería ng-comps.
763
+ * Envuelve Angular Material `mat-button` / `mat-flat-button` / `mat-stroked-button`
764
+ * y expone una API uniforme con look and feel de marca.
765
+ */
766
+ class MfButtonComponent {
767
+ id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
768
+ label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
769
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
770
+ ariaLabelledby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : /* istanbul ignore next */ []));
771
+ ariaDescribedby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaDescribedby" }] : /* istanbul ignore next */ []));
772
+ variant = input('filled', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
773
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
774
+ type = input('button', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
775
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
776
+ leadingIcon = input(undefined, ...(ngDevMode ? [{ debugName: "leadingIcon" }] : /* istanbul ignore next */ []));
777
+ trailingIcon = input(undefined, ...(ngDevMode ? [{ debugName: "trailingIcon" }] : /* istanbul ignore next */ []));
778
+ fullWidth = input(false, ...(ngDevMode ? [{ debugName: "fullWidth" }] : /* istanbul ignore next */ []));
779
+ iconOnly = input(false, ...(ngDevMode ? [{ debugName: "iconOnly" }] : /* istanbul ignore next */ []));
780
+ mfClick = output();
781
+ constructor() {
782
+ effect(() => {
783
+ if (!hasAccessibleName(this.label(), this.ariaLabel(), this.ariaLabelledby())) {
784
+ warnInDev('mf-button requiere texto visible, `ariaLabel` o `ariaLabelledby` para exponer un nombre accesible.');
785
+ }
786
+ if (this.rendersAsIconButton() && !this.iconName()) {
787
+ warnInDev('mf-button en modo `iconOnly` requiere `leadingIcon` o `trailingIcon`.');
788
+ }
789
+ });
790
+ }
791
+ rendersAsIconButton = computed(() => this.iconOnly() || (!this.label()?.trim() && Boolean(this.iconName())), ...(ngDevMode ? [{ debugName: "rendersAsIconButton" }] : /* istanbul ignore next */ []));
792
+ iconName = computed(() => this.leadingIcon() ?? this.trailingIcon() ?? 'help', ...(ngDevMode ? [{ debugName: "iconName" }] : /* istanbul ignore next */ []));
793
+ resolvedAriaLabel = computed(() => this.label() ? null : this.ariaLabel() ?? null, ...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
794
+ iconButtonAriaLabel = computed(() => this.ariaLabel() ?? this.label() ?? null, ...(ngDevMode ? [{ debugName: "iconButtonAriaLabel" }] : /* istanbul ignore next */ []));
795
+ hostClasses = computed(() => {
796
+ const classes = [
797
+ 'mf-btn',
798
+ `mf-btn--${this.variant()}`,
799
+ `mf-btn--${this.size()}`,
800
+ ];
801
+ if (this.fullWidth())
802
+ classes.push('mf-btn--full');
803
+ if (this.rendersAsIconButton())
804
+ classes.push('mf-btn--icon');
805
+ return classes.join(' ');
806
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
807
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
808
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfButtonComponent, isStandalone: true, selector: "mf-button", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "ariaDescribedby", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, leadingIcon: { classPropertyName: "leadingIcon", publicName: "leadingIcon", isSignal: true, isRequired: false, transformFunction: null }, trailingIcon: { classPropertyName: "trailingIcon", publicName: "trailingIcon", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, iconOnly: { classPropertyName: "iconOnly", publicName: "iconOnly", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfClick: "mfClick" }, ngImport: i0, template: `
809
+ @if (rendersAsIconButton()) {
810
+ <button
811
+ mat-icon-button
812
+ [id]="id() || null"
813
+ [type]="type()"
814
+ [disabled]="disabled()"
815
+ [class]="hostClasses()"
816
+ [attr.aria-label]="iconButtonAriaLabel()"
817
+ [attr.aria-labelledby]="ariaLabelledby() || null"
818
+ [attr.aria-describedby]="ariaDescribedby() || null"
819
+ (click)="mfClick.emit($event)"
820
+ >
821
+ <mat-icon aria-hidden="true">{{ iconName() }}</mat-icon>
822
+ </button>
823
+ } @else if (variant() === 'filled') {
824
+ <button
825
+ mat-flat-button
826
+ [id]="id() || null"
827
+ [type]="type()"
828
+ [disabled]="disabled()"
829
+ [class]="hostClasses()"
830
+ [attr.aria-label]="resolvedAriaLabel()"
831
+ [attr.aria-labelledby]="ariaLabelledby() || null"
832
+ [attr.aria-describedby]="ariaDescribedby() || null"
833
+ (click)="mfClick.emit($event)"
834
+ >
835
+ @if (leadingIcon()) {
836
+ <mat-icon aria-hidden="true">{{ leadingIcon() }}</mat-icon>
837
+ }
838
+ @if (label()) {
839
+ <span>{{ label() }}</span>
840
+ }
841
+ @if (trailingIcon()) {
842
+ <mat-icon aria-hidden="true">{{ trailingIcon() }}</mat-icon>
843
+ }
844
+ </button>
845
+ } @else if (variant() === 'outlined') {
846
+ <button
847
+ mat-stroked-button
848
+ [id]="id() || null"
849
+ [type]="type()"
850
+ [disabled]="disabled()"
851
+ [class]="hostClasses()"
852
+ [attr.aria-label]="resolvedAriaLabel()"
853
+ [attr.aria-labelledby]="ariaLabelledby() || null"
854
+ [attr.aria-describedby]="ariaDescribedby() || null"
855
+ (click)="mfClick.emit($event)"
856
+ >
857
+ @if (leadingIcon()) {
858
+ <mat-icon aria-hidden="true">{{ leadingIcon() }}</mat-icon>
859
+ }
860
+ @if (label()) {
861
+ <span>{{ label() }}</span>
862
+ }
863
+ @if (trailingIcon()) {
864
+ <mat-icon aria-hidden="true">{{ trailingIcon() }}</mat-icon>
865
+ }
866
+ </button>
867
+ } @else {
868
+ <button
869
+ mat-button
870
+ [id]="id() || null"
871
+ [type]="type()"
872
+ [disabled]="disabled()"
873
+ [class]="hostClasses()"
874
+ [attr.aria-label]="resolvedAriaLabel()"
875
+ [attr.aria-labelledby]="ariaLabelledby() || null"
876
+ [attr.aria-describedby]="ariaDescribedby() || null"
877
+ (click)="mfClick.emit($event)"
878
+ >
879
+ @if (leadingIcon()) {
880
+ <mat-icon aria-hidden="true">{{ leadingIcon() }}</mat-icon>
881
+ }
882
+ @if (label()) {
883
+ <span>{{ label() }}</span>
884
+ }
885
+ @if (trailingIcon()) {
886
+ <mat-icon aria-hidden="true">{{ trailingIcon() }}</mat-icon>
887
+ }
888
+ </button>
889
+ }
890
+ `, isInline: true, styles: [":host{display:inline-block}:host([fullWidth]),:host-context(.mf-btn--full){display:block}.mf-btn{border-radius:var(--mf-radius-full)!important;font-family:var(--mf-font-base)!important;font-weight:var(--mf-weight-bold)!important;letter-spacing:.01em;transition:background-color var(--mf-duration-base) var(--mf-ease-standard),box-shadow var(--mf-duration-base) var(--mf-ease-standard),opacity var(--mf-duration-fast) var(--mf-ease-standard)}.mf-btn.mf-btn--full{width:100%}.mf-btn--icon{border-radius:var(--mf-radius-full)!important}.mf-btn--icon.mat-mdc-icon-button{display:inline-flex!important;align-items:center;justify-content:center;line-height:1;vertical-align:middle}.mf-btn--filled.mdc-button,.mf-btn--filled.mat-mdc-unelevated-button{background-color:var(--mf-color-brand)!important;color:var(--mf-color-on-brand)!important}.mf-btn--filled.mdc-button:hover:not([disabled]),.mf-btn--filled.mat-mdc-unelevated-button:hover:not([disabled]){background-color:var(--mf-color-brand-hover)!important;box-shadow:var(--mf-shadow-md)}.mf-btn--outlined.mdc-button,.mf-btn--outlined.mat-mdc-outlined-button{color:var(--mf-color-secondary-900)!important;border-color:var(--mf-color-border)!important;background-color:var(--mf-color-surface)}.mf-btn--outlined.mdc-button:hover:not([disabled]),.mf-btn--outlined.mat-mdc-outlined-button:hover:not([disabled]){background-color:var(--mf-color-surface-raised);box-shadow:var(--mf-shadow-sm)}.mf-btn--text.mdc-button,.mf-btn--text.mat-mdc-button{color:var(--mf-color-brand)!important}.mf-btn--text.mdc-button:hover:not([disabled]),.mf-btn--text.mat-mdc-button:hover:not([disabled]){background-color:var(--mf-color-brand-light)}.mf-btn--text.mat-mdc-icon-button:hover:not([disabled]),.mf-btn--filled.mat-mdc-icon-button:hover:not([disabled]),.mf-btn--outlined.mat-mdc-icon-button:hover:not([disabled]){background-color:var(--mf-color-brand-light)}.mf-btn--filled.mat-mdc-icon-button{color:var(--mf-color-brand)!important;background-color:var(--mf-color-brand-light)!important}.mf-btn--outlined.mat-mdc-icon-button{color:var(--mf-color-secondary-900)!important;border:1px solid var(--mf-color-border)!important}.mf-btn--sm.mdc-button{height:34px!important;padding:0 var(--mf-space-4)!important;font-size:var(--mf-text-sm)!important}.mf-btn--md.mdc-button{height:40px!important;padding:0 var(--mf-space-5)!important;font-size:var(--mf-text-sm)!important}.mf-btn--lg.mdc-button{height:48px!important;padding:0 var(--mf-space-6)!important;font-size:var(--mf-text-base)!important}.mf-btn--icon.mf-btn--sm.mat-mdc-icon-button{width:34px;height:34px;padding:5px}.mf-btn--icon.mf-btn--md.mat-mdc-icon-button{width:40px;height:40px;padding:8px}.mf-btn--icon.mf-btn--lg.mat-mdc-icon-button{width:48px;height:48px;padding:11px}.mf-btn[disabled],.mf-btn.mdc-button:disabled{opacity:.42;cursor:default;pointer-events:none}.mf-btn .mat-icon{font-size:1.1em;height:1.1em;width:1.1em;vertical-align:middle;line-height:1}.mf-btn--icon .mat-icon{display:flex;align-items:center;justify-content:center;margin:0}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i1$3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
891
+ }
892
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfButtonComponent, decorators: [{
893
+ type: Component,
894
+ args: [{ selector: 'mf-button', imports: [MatButtonModule, MatIconModule], template: `
895
+ @if (rendersAsIconButton()) {
896
+ <button
897
+ mat-icon-button
898
+ [id]="id() || null"
899
+ [type]="type()"
900
+ [disabled]="disabled()"
901
+ [class]="hostClasses()"
902
+ [attr.aria-label]="iconButtonAriaLabel()"
903
+ [attr.aria-labelledby]="ariaLabelledby() || null"
904
+ [attr.aria-describedby]="ariaDescribedby() || null"
905
+ (click)="mfClick.emit($event)"
906
+ >
907
+ <mat-icon aria-hidden="true">{{ iconName() }}</mat-icon>
908
+ </button>
909
+ } @else if (variant() === 'filled') {
910
+ <button
911
+ mat-flat-button
912
+ [id]="id() || null"
913
+ [type]="type()"
914
+ [disabled]="disabled()"
915
+ [class]="hostClasses()"
916
+ [attr.aria-label]="resolvedAriaLabel()"
917
+ [attr.aria-labelledby]="ariaLabelledby() || null"
918
+ [attr.aria-describedby]="ariaDescribedby() || null"
919
+ (click)="mfClick.emit($event)"
920
+ >
921
+ @if (leadingIcon()) {
922
+ <mat-icon aria-hidden="true">{{ leadingIcon() }}</mat-icon>
923
+ }
924
+ @if (label()) {
925
+ <span>{{ label() }}</span>
926
+ }
927
+ @if (trailingIcon()) {
928
+ <mat-icon aria-hidden="true">{{ trailingIcon() }}</mat-icon>
929
+ }
930
+ </button>
931
+ } @else if (variant() === 'outlined') {
932
+ <button
933
+ mat-stroked-button
934
+ [id]="id() || null"
935
+ [type]="type()"
936
+ [disabled]="disabled()"
937
+ [class]="hostClasses()"
938
+ [attr.aria-label]="resolvedAriaLabel()"
939
+ [attr.aria-labelledby]="ariaLabelledby() || null"
940
+ [attr.aria-describedby]="ariaDescribedby() || null"
941
+ (click)="mfClick.emit($event)"
942
+ >
943
+ @if (leadingIcon()) {
944
+ <mat-icon aria-hidden="true">{{ leadingIcon() }}</mat-icon>
945
+ }
946
+ @if (label()) {
947
+ <span>{{ label() }}</span>
948
+ }
949
+ @if (trailingIcon()) {
950
+ <mat-icon aria-hidden="true">{{ trailingIcon() }}</mat-icon>
951
+ }
952
+ </button>
953
+ } @else {
954
+ <button
955
+ mat-button
956
+ [id]="id() || null"
957
+ [type]="type()"
958
+ [disabled]="disabled()"
959
+ [class]="hostClasses()"
960
+ [attr.aria-label]="resolvedAriaLabel()"
961
+ [attr.aria-labelledby]="ariaLabelledby() || null"
962
+ [attr.aria-describedby]="ariaDescribedby() || null"
963
+ (click)="mfClick.emit($event)"
964
+ >
965
+ @if (leadingIcon()) {
966
+ <mat-icon aria-hidden="true">{{ leadingIcon() }}</mat-icon>
967
+ }
968
+ @if (label()) {
969
+ <span>{{ label() }}</span>
970
+ }
971
+ @if (trailingIcon()) {
972
+ <mat-icon aria-hidden="true">{{ trailingIcon() }}</mat-icon>
973
+ }
974
+ </button>
975
+ }
976
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-block}:host([fullWidth]),:host-context(.mf-btn--full){display:block}.mf-btn{border-radius:var(--mf-radius-full)!important;font-family:var(--mf-font-base)!important;font-weight:var(--mf-weight-bold)!important;letter-spacing:.01em;transition:background-color var(--mf-duration-base) var(--mf-ease-standard),box-shadow var(--mf-duration-base) var(--mf-ease-standard),opacity var(--mf-duration-fast) var(--mf-ease-standard)}.mf-btn.mf-btn--full{width:100%}.mf-btn--icon{border-radius:var(--mf-radius-full)!important}.mf-btn--icon.mat-mdc-icon-button{display:inline-flex!important;align-items:center;justify-content:center;line-height:1;vertical-align:middle}.mf-btn--filled.mdc-button,.mf-btn--filled.mat-mdc-unelevated-button{background-color:var(--mf-color-brand)!important;color:var(--mf-color-on-brand)!important}.mf-btn--filled.mdc-button:hover:not([disabled]),.mf-btn--filled.mat-mdc-unelevated-button:hover:not([disabled]){background-color:var(--mf-color-brand-hover)!important;box-shadow:var(--mf-shadow-md)}.mf-btn--outlined.mdc-button,.mf-btn--outlined.mat-mdc-outlined-button{color:var(--mf-color-secondary-900)!important;border-color:var(--mf-color-border)!important;background-color:var(--mf-color-surface)}.mf-btn--outlined.mdc-button:hover:not([disabled]),.mf-btn--outlined.mat-mdc-outlined-button:hover:not([disabled]){background-color:var(--mf-color-surface-raised);box-shadow:var(--mf-shadow-sm)}.mf-btn--text.mdc-button,.mf-btn--text.mat-mdc-button{color:var(--mf-color-brand)!important}.mf-btn--text.mdc-button:hover:not([disabled]),.mf-btn--text.mat-mdc-button:hover:not([disabled]){background-color:var(--mf-color-brand-light)}.mf-btn--text.mat-mdc-icon-button:hover:not([disabled]),.mf-btn--filled.mat-mdc-icon-button:hover:not([disabled]),.mf-btn--outlined.mat-mdc-icon-button:hover:not([disabled]){background-color:var(--mf-color-brand-light)}.mf-btn--filled.mat-mdc-icon-button{color:var(--mf-color-brand)!important;background-color:var(--mf-color-brand-light)!important}.mf-btn--outlined.mat-mdc-icon-button{color:var(--mf-color-secondary-900)!important;border:1px solid var(--mf-color-border)!important}.mf-btn--sm.mdc-button{height:34px!important;padding:0 var(--mf-space-4)!important;font-size:var(--mf-text-sm)!important}.mf-btn--md.mdc-button{height:40px!important;padding:0 var(--mf-space-5)!important;font-size:var(--mf-text-sm)!important}.mf-btn--lg.mdc-button{height:48px!important;padding:0 var(--mf-space-6)!important;font-size:var(--mf-text-base)!important}.mf-btn--icon.mf-btn--sm.mat-mdc-icon-button{width:34px;height:34px;padding:5px}.mf-btn--icon.mf-btn--md.mat-mdc-icon-button{width:40px;height:40px;padding:8px}.mf-btn--icon.mf-btn--lg.mat-mdc-icon-button{width:48px;height:48px;padding:11px}.mf-btn[disabled],.mf-btn.mdc-button:disabled{opacity:.42;cursor:default;pointer-events:none}.mf-btn .mat-icon{font-size:1.1em;height:1.1em;width:1.1em;vertical-align:middle;line-height:1}.mf-btn--icon .mat-icon{display:flex;align-items:center;justify-content:center;margin:0}\n"] }]
977
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledby", required: false }] }], ariaDescribedby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedby", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], leadingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "leadingIcon", required: false }] }], trailingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "trailingIcon", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], iconOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconOnly", required: false }] }], mfClick: [{ type: i0.Output, args: ["mfClick"] }] } });
978
+
979
+ /**
980
+ * Card de la librería ng-comps.
981
+ * Envuelve Angular Material `mat-card` y expone una API uniforme
982
+ * con look and feel de marca. Admite contenido proyectado mediante slots.
983
+ */
984
+ class MfCardComponent {
985
+ /** Título de la card */
986
+ title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
987
+ /** Subtítulo de la card */
988
+ subtitle = input(undefined, ...(ngDevMode ? [{ debugName: "subtitle" }] : /* istanbul ignore next */ []));
989
+ /** Variante visual */
990
+ variant = input('elevated', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
991
+ /** Padding interno */
992
+ padding = input('md', ...(ngDevMode ? [{ debugName: "padding" }] : /* istanbul ignore next */ []));
993
+ /** Interactiva (hover effect) */
994
+ interactive = input(false, ...(ngDevMode ? [{ debugName: "interactive" }] : /* istanbul ignore next */ []));
995
+ hasHeader = computed(() => !!this.title() || !!this.subtitle(), ...(ngDevMode ? [{ debugName: "hasHeader" }] : /* istanbul ignore next */ []));
996
+ hostClasses = computed(() => {
997
+ const classes = ['mf-card', `mf-card--${this.variant()}`, `mf-card--pad-${this.padding()}`];
998
+ if (this.interactive())
999
+ classes.push('mf-card--interactive');
1000
+ return classes.join(' ');
1001
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1002
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1003
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfCardComponent, isStandalone: true, selector: "mf-card", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
1004
+ <mat-card [class]="hostClasses()">
1005
+ @if (hasHeader()) {
1006
+ <mat-card-header>
1007
+ @if (title()) {
1008
+ <mat-card-title class="mf-card__title">{{ title() }}</mat-card-title>
1009
+ }
1010
+ @if (subtitle()) {
1011
+ <mat-card-subtitle class="mf-card__subtitle">{{ subtitle() }}</mat-card-subtitle>
1012
+ }
1013
+ </mat-card-header>
1014
+ }
1015
+ <mat-card-content>
1016
+ <ng-content />
1017
+ </mat-card-content>
1018
+ <ng-content select="[mfCardFooter]" />
1019
+ </mat-card>
1020
+ `, isInline: true, styles: [":host{display:block}.mf-card{font-family:var(--mf-font-base)!important;border-radius:var(--mf-radius-xl)!important;overflow:hidden;transition:box-shadow var(--mf-duration-base) var(--mf-ease-standard),transform var(--mf-duration-base) var(--mf-ease-standard)}.mf-card--elevated{background-color:var(--mf-color-surface)!important;box-shadow:var(--mf-shadow-md)!important;border:none!important}.mf-card--outlined{background-color:var(--mf-color-surface)!important;box-shadow:none!important;border:1px solid var(--mf-color-border)!important}.mf-card--flat{background-color:var(--mf-color-surface-raised)!important;box-shadow:none!important;border:none!important}.mf-card--interactive{cursor:pointer}.mf-card--interactive:hover{box-shadow:var(--mf-shadow-lg)!important;transform:translateY(-2px)}.mf-card--interactive:active{transform:translateY(0)}.mf-card--pad-none .mat-mdc-card-content{padding:0!important}.mf-card--pad-sm .mat-mdc-card-content{padding:var(--mf-space-3)!important}.mf-card--pad-md .mat-mdc-card-content{padding:var(--mf-space-5)!important}.mf-card--pad-lg .mat-mdc-card-content{padding:var(--mf-space-8)!important}.mf-card .mat-mdc-card-header{padding:var(--mf-space-5) var(--mf-space-5) 0!important}.mf-card__title{font-family:var(--mf-font-display)!important;font-size:var(--mf-text-lg)!important;font-weight:var(--mf-weight-bold)!important;color:var(--mf-color-on-surface)!important;margin:0!important}.mf-card__subtitle{font-size:var(--mf-text-sm)!important;color:var(--mf-color-neutral-400)!important;margin-top:var(--mf-space-1)!important}\n"], dependencies: [{ kind: "ngmodule", type: MatCardModule }, { kind: "component", type: i1$4.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i1$4.MatCardContent, selector: "mat-card-content" }, { kind: "component", type: i1$4.MatCardHeader, selector: "mat-card-header" }, { kind: "directive", type: i1$4.MatCardSubtitle, selector: "mat-card-subtitle, [mat-card-subtitle], [matCardSubtitle]" }, { kind: "directive", type: i1$4.MatCardTitle, selector: "mat-card-title, [mat-card-title], [matCardTitle]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1021
+ }
1022
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfCardComponent, decorators: [{
1023
+ type: Component,
1024
+ args: [{ selector: 'mf-card', imports: [MatCardModule], template: `
1025
+ <mat-card [class]="hostClasses()">
1026
+ @if (hasHeader()) {
1027
+ <mat-card-header>
1028
+ @if (title()) {
1029
+ <mat-card-title class="mf-card__title">{{ title() }}</mat-card-title>
1030
+ }
1031
+ @if (subtitle()) {
1032
+ <mat-card-subtitle class="mf-card__subtitle">{{ subtitle() }}</mat-card-subtitle>
1033
+ }
1034
+ </mat-card-header>
1035
+ }
1036
+ <mat-card-content>
1037
+ <ng-content />
1038
+ </mat-card-content>
1039
+ <ng-content select="[mfCardFooter]" />
1040
+ </mat-card>
1041
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.mf-card{font-family:var(--mf-font-base)!important;border-radius:var(--mf-radius-xl)!important;overflow:hidden;transition:box-shadow var(--mf-duration-base) var(--mf-ease-standard),transform var(--mf-duration-base) var(--mf-ease-standard)}.mf-card--elevated{background-color:var(--mf-color-surface)!important;box-shadow:var(--mf-shadow-md)!important;border:none!important}.mf-card--outlined{background-color:var(--mf-color-surface)!important;box-shadow:none!important;border:1px solid var(--mf-color-border)!important}.mf-card--flat{background-color:var(--mf-color-surface-raised)!important;box-shadow:none!important;border:none!important}.mf-card--interactive{cursor:pointer}.mf-card--interactive:hover{box-shadow:var(--mf-shadow-lg)!important;transform:translateY(-2px)}.mf-card--interactive:active{transform:translateY(0)}.mf-card--pad-none .mat-mdc-card-content{padding:0!important}.mf-card--pad-sm .mat-mdc-card-content{padding:var(--mf-space-3)!important}.mf-card--pad-md .mat-mdc-card-content{padding:var(--mf-space-5)!important}.mf-card--pad-lg .mat-mdc-card-content{padding:var(--mf-space-8)!important}.mf-card .mat-mdc-card-header{padding:var(--mf-space-5) var(--mf-space-5) 0!important}.mf-card__title{font-family:var(--mf-font-display)!important;font-size:var(--mf-text-lg)!important;font-weight:var(--mf-weight-bold)!important;color:var(--mf-color-on-surface)!important;margin:0!important}.mf-card__subtitle{font-size:var(--mf-text-sm)!important;color:var(--mf-color-neutral-400)!important;margin-top:var(--mf-space-1)!important}\n"] }]
1042
+ }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], padding: [{ type: i0.Input, args: [{ isSignal: true, alias: "padding", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }] } });
1043
+
1044
+ /**
1045
+ * Checkbox de la librería ng-comps.
1046
+ * Envuelve Angular Material `mat-checkbox` y expone una API uniforme
1047
+ * con look and feel de marca.
1048
+ */
1049
+ class MfCheckboxComponent {
1050
+ cdr = inject(ChangeDetectorRef);
1051
+ ngControl = inject(NgControl, { self: true, optional: true });
1052
+ generatedId = createUniqueId('mf-checkbox');
1053
+ disabledFromForm = signal(false, ...(ngDevMode ? [{ debugName: "disabledFromForm" }] : /* istanbul ignore next */ []));
1054
+ internalValue = signal(false, ...(ngDevMode ? [{ debugName: "internalValue" }] : /* istanbul ignore next */ []));
1055
+ onControlChange = () => undefined;
1056
+ onControlTouched = () => undefined;
1057
+ /** ID del control */
1058
+ id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
1059
+ /** Texto del checkbox */
1060
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
1061
+ /** Etiqueta accesible alternativa cuando no existe label visible */
1062
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
1063
+ /** Referencia externa a elementos que etiquetan el control */
1064
+ ariaLabelledby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : /* istanbul ignore next */ []));
1065
+ /** Referencia externa a elementos descriptivos adicionales */
1066
+ ariaDescribedby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaDescribedby" }] : /* istanbul ignore next */ []));
1067
+ /** Estado marcado */
1068
+ checked = input(false, ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
1069
+ /** Estado indeterminado */
1070
+ indeterminate = input(false, ...(ngDevMode ? [{ debugName: "indeterminate" }] : /* istanbul ignore next */ []));
1071
+ /** Deshabilitado */
1072
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
1073
+ /** Requerido */
1074
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
1075
+ /** Texto de ayuda */
1076
+ hint = input(undefined, ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
1077
+ /** Mensaje de error */
1078
+ error = input(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
1079
+ mfChange = output();
1080
+ constructor() {
1081
+ effect(() => {
1082
+ this.internalValue.set(this.checked());
1083
+ });
1084
+ effect(() => {
1085
+ if (!hasAccessibleName(this.label(), this.ariaLabel(), this.ariaLabelledby())) {
1086
+ warnInDev('mf-checkbox requiere texto visible, `ariaLabel` o `ariaLabelledby` para exponer un nombre accesible.');
1087
+ }
1088
+ });
1089
+ }
1090
+ controlId = computed(() => this.id() ?? this.generatedId, ...(ngDevMode ? [{ debugName: "controlId" }] : /* istanbul ignore next */ []));
1091
+ hintId = computed(() => this.hint() ? `${this.controlId()}-hint` : null, ...(ngDevMode ? [{ debugName: "hintId" }] : /* istanbul ignore next */ []));
1092
+ errorId = computed(() => this.error() ? `${this.controlId()}-error` : null, ...(ngDevMode ? [{ debugName: "errorId" }] : /* istanbul ignore next */ []));
1093
+ describedBy = computed(() => mergeAriaIds(this.ariaDescribedby(), this.hintId(), this.errorId()), ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
1094
+ resolvedAriaLabel = computed(() => this.label() ? null : this.ariaLabel() ?? null, ...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
1095
+ isDisabled = computed(() => this.disabled() || this.disabledFromForm(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
1096
+ hostClasses = computed(() => {
1097
+ const classes = ['mf-checkbox'];
1098
+ if (this.isDisabled())
1099
+ classes.push('mf-checkbox--disabled');
1100
+ if (this.error())
1101
+ classes.push('mf-checkbox--error');
1102
+ return classes.join(' ');
1103
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1104
+ writeValue(value) {
1105
+ this.internalValue.set(Boolean(value));
1106
+ this.cdr.markForCheck();
1107
+ }
1108
+ registerOnChange(fn) {
1109
+ this.onControlChange = fn;
1110
+ }
1111
+ registerOnTouched(fn) {
1112
+ this.onControlTouched = fn;
1113
+ }
1114
+ setDisabledState(isDisabled) {
1115
+ this.disabledFromForm.set(isDisabled);
1116
+ this.cdr.markForCheck();
1117
+ }
1118
+ isInvalid() {
1119
+ const control = this.ngControl?.control;
1120
+ return Boolean(this.error() || (control?.invalid && (control.touched || control.dirty)));
1121
+ }
1122
+ onCheckboxChange(event) {
1123
+ this.internalValue.set(event.checked);
1124
+ this.onControlChange(event.checked);
1125
+ this.onControlTouched();
1126
+ this.mfChange.emit(event.checked);
1127
+ }
1128
+ onBlur() {
1129
+ this.onControlTouched();
1130
+ }
1131
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfCheckboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1132
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfCheckboxComponent, isStandalone: true, selector: "mf-checkbox", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "ariaDescribedby", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfChange: "mfChange" }, providers: [
1133
+ {
1134
+ provide: NG_VALUE_ACCESSOR,
1135
+ useExisting: forwardRef(() => MfCheckboxComponent),
1136
+ multi: true,
1137
+ },
1138
+ ], ngImport: i0, template: `
1139
+ <div [class]="hostClasses()">
1140
+ <mat-checkbox
1141
+ [id]="controlId()"
1142
+ [checked]="internalValue()"
1143
+ [disabled]="isDisabled()"
1144
+ [indeterminate]="indeterminate()"
1145
+ [required]="required()"
1146
+ [attr.aria-label]="resolvedAriaLabel()"
1147
+ [attr.aria-labelledby]="ariaLabelledby() || null"
1148
+ [attr.aria-describedby]="describedBy()"
1149
+ [attr.aria-invalid]="isInvalid() ? 'true' : null"
1150
+ [attr.aria-required]="required() ? 'true' : null"
1151
+ (change)="onCheckboxChange($event)"
1152
+ (blur)="onBlur()"
1153
+ >
1154
+ {{ label() }}
1155
+ </mat-checkbox>
1156
+
1157
+ @if (hint()) {
1158
+ <p class="mf-checkbox__hint" [attr.id]="hintId()">{{ hint() }}</p>
1159
+ }
1160
+
1161
+ @if (error()) {
1162
+ <p class="mf-checkbox__error" [attr.id]="errorId()" role="alert">
1163
+ {{ error() }}
1164
+ </p>
1165
+ }
1166
+ </div>
1167
+ `, isInline: true, styles: [":host{display:block}.mf-checkbox{font-family:var(--mf-font-base)!important;display:flex;flex-direction:column;gap:var(--mf-space-1)}.mf-checkbox .mdc-label,.mf-checkbox .mat-mdc-checkbox-label{font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important;color:var(--mf-color-on-surface)!important;cursor:pointer}.mf-checkbox .mdc-checkbox__background{border-color:var(--mf-color-neutral-300)!important;border-radius:var(--mf-radius-sm)!important;border-width:1.5px!important;transition:border-color var(--mf-duration-base) var(--mf-ease-standard),background-color var(--mf-duration-base) var(--mf-ease-standard)}.mf-checkbox .mdc-checkbox__native-control:checked~.mdc-checkbox__background,.mf-checkbox .mdc-checkbox__native-control:indeterminate~.mdc-checkbox__background{background-color:var(--mf-color-brand)!important;border-color:var(--mf-color-brand)!important}.mf-checkbox:hover .mdc-checkbox__background{border-color:var(--mf-color-brand)!important}.mf-checkbox .mat-mdc-checkbox-ripple,.mf-checkbox .mdc-checkbox__ripple{display:none!important}.mf-checkbox .mdc-checkbox__native-control:focus~.mdc-checkbox__background{box-shadow:0 0 0 3px var(--mf-color-primary-100)}.mf-checkbox--disabled{opacity:.42;pointer-events:none}.mf-checkbox__hint,.mf-checkbox__error{margin:0;padding-left:calc(18px + var(--mf-space-3));font-size:var(--mf-text-xs);line-height:var(--mf-leading-normal)}.mf-checkbox__hint{color:var(--mf-color-neutral-600)}.mf-checkbox__error{color:var(--mf-color-error-500)}\n"], dependencies: [{ kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i1$5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "aria-expanded", "aria-controls", "aria-owns", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "disabledInteractive", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1168
+ }
1169
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfCheckboxComponent, decorators: [{
1170
+ type: Component,
1171
+ args: [{ selector: 'mf-checkbox', imports: [MatCheckboxModule], providers: [
1172
+ {
1173
+ provide: NG_VALUE_ACCESSOR,
1174
+ useExisting: forwardRef(() => MfCheckboxComponent),
1175
+ multi: true,
1176
+ },
1177
+ ], template: `
1178
+ <div [class]="hostClasses()">
1179
+ <mat-checkbox
1180
+ [id]="controlId()"
1181
+ [checked]="internalValue()"
1182
+ [disabled]="isDisabled()"
1183
+ [indeterminate]="indeterminate()"
1184
+ [required]="required()"
1185
+ [attr.aria-label]="resolvedAriaLabel()"
1186
+ [attr.aria-labelledby]="ariaLabelledby() || null"
1187
+ [attr.aria-describedby]="describedBy()"
1188
+ [attr.aria-invalid]="isInvalid() ? 'true' : null"
1189
+ [attr.aria-required]="required() ? 'true' : null"
1190
+ (change)="onCheckboxChange($event)"
1191
+ (blur)="onBlur()"
1192
+ >
1193
+ {{ label() }}
1194
+ </mat-checkbox>
1195
+
1196
+ @if (hint()) {
1197
+ <p class="mf-checkbox__hint" [attr.id]="hintId()">{{ hint() }}</p>
1198
+ }
1199
+
1200
+ @if (error()) {
1201
+ <p class="mf-checkbox__error" [attr.id]="errorId()" role="alert">
1202
+ {{ error() }}
1203
+ </p>
1204
+ }
1205
+ </div>
1206
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.mf-checkbox{font-family:var(--mf-font-base)!important;display:flex;flex-direction:column;gap:var(--mf-space-1)}.mf-checkbox .mdc-label,.mf-checkbox .mat-mdc-checkbox-label{font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important;color:var(--mf-color-on-surface)!important;cursor:pointer}.mf-checkbox .mdc-checkbox__background{border-color:var(--mf-color-neutral-300)!important;border-radius:var(--mf-radius-sm)!important;border-width:1.5px!important;transition:border-color var(--mf-duration-base) var(--mf-ease-standard),background-color var(--mf-duration-base) var(--mf-ease-standard)}.mf-checkbox .mdc-checkbox__native-control:checked~.mdc-checkbox__background,.mf-checkbox .mdc-checkbox__native-control:indeterminate~.mdc-checkbox__background{background-color:var(--mf-color-brand)!important;border-color:var(--mf-color-brand)!important}.mf-checkbox:hover .mdc-checkbox__background{border-color:var(--mf-color-brand)!important}.mf-checkbox .mat-mdc-checkbox-ripple,.mf-checkbox .mdc-checkbox__ripple{display:none!important}.mf-checkbox .mdc-checkbox__native-control:focus~.mdc-checkbox__background{box-shadow:0 0 0 3px var(--mf-color-primary-100)}.mf-checkbox--disabled{opacity:.42;pointer-events:none}.mf-checkbox__hint,.mf-checkbox__error{margin:0;padding-left:calc(18px + var(--mf-space-3));font-size:var(--mf-text-xs);line-height:var(--mf-leading-normal)}.mf-checkbox__hint{color:var(--mf-color-neutral-600)}.mf-checkbox__error{color:var(--mf-color-error-500)}\n"] }]
1207
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledby", required: false }] }], ariaDescribedby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedby", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], mfChange: [{ type: i0.Output, args: ["mfChange"] }] } });
1208
+
1209
+ /**
1210
+ * Chip de la librería ng-comps.
1211
+ * Envuelve Angular Material `mat-chip` y expone una API uniforme
1212
+ * con look and feel de marca. Ideal para tags, filtros y etiquetas.
1213
+ */
1214
+ class MfChipComponent {
1215
+ /** Texto del chip */
1216
+ label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
1217
+ /** Variante visual */
1218
+ variant = input('filled', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
1219
+ /** Color semántico */
1220
+ color = input('brand', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
1221
+ /** Seleccionado */
1222
+ selected = input(false, ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
1223
+ /** Puede ser removido */
1224
+ removable = input(false, ...(ngDevMode ? [{ debugName: "removable" }] : /* istanbul ignore next */ []));
1225
+ /** Deshabilitado */
1226
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
1227
+ /** Icono inicial */
1228
+ leadingIcon = input(undefined, ...(ngDevMode ? [{ debugName: "leadingIcon" }] : /* istanbul ignore next */ []));
1229
+ mfRemoved = output();
1230
+ hostClasses = computed(() => {
1231
+ const classes = ['mf-chip', `mf-chip--${this.variant()}`, `mf-chip--${this.color()}`];
1232
+ if (this.selected())
1233
+ classes.push('mf-chip--selected');
1234
+ return classes.join(' ');
1235
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1236
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfChipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1237
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfChipComponent, isStandalone: true, selector: "mf-chip", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, leadingIcon: { classPropertyName: "leadingIcon", publicName: "leadingIcon", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfRemoved: "mfRemoved" }, ngImport: i0, template: `
1238
+ @if (removable()) {
1239
+ <mat-chip
1240
+ [highlighted]="selected()"
1241
+ [disabled]="disabled()"
1242
+ [class]="hostClasses()"
1243
+ (removed)="mfRemoved.emit()"
1244
+ >
1245
+ @if (leadingIcon()) {
1246
+ <mat-icon matChipAvatar aria-hidden="true">{{ leadingIcon() }}</mat-icon>
1247
+ }
1248
+ {{ label() }}
1249
+ <button matChipRemove [attr.aria-label]="'Remove ' + label()">
1250
+ <mat-icon>cancel</mat-icon>
1251
+ </button>
1252
+ </mat-chip>
1253
+ } @else {
1254
+ <mat-chip
1255
+ [highlighted]="selected()"
1256
+ [disabled]="disabled()"
1257
+ [class]="hostClasses()"
1258
+ >
1259
+ @if (leadingIcon()) {
1260
+ <mat-icon matChipAvatar aria-hidden="true">{{ leadingIcon() }}</mat-icon>
1261
+ }
1262
+ {{ label() }}
1263
+ </mat-chip>
1264
+ }
1265
+ `, isInline: true, styles: [":host{display:inline-block}.mf-chip.mat-mdc-chip{font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important;font-weight:var(--mf-weight-medium)!important;border-radius:var(--mf-radius-full)!important;transition:background-color var(--mf-duration-base) var(--mf-ease-standard),box-shadow var(--mf-duration-base) var(--mf-ease-standard)}.mf-chip--filled.mf-chip--brand.mat-mdc-chip{background-color:var(--mf-color-primary-100)!important;color:var(--mf-color-primary-800)!important}.mf-chip--filled.mf-chip--accent.mat-mdc-chip{background-color:var(--mf-color-accent-300)!important;color:var(--mf-color-accent-700)!important}.mf-chip--filled.mf-chip--error.mat-mdc-chip{background-color:#fee2e2!important;color:var(--mf-color-error-700)!important}.mf-chip--filled.mf-chip--neutral.mat-mdc-chip{background-color:var(--mf-color-neutral-100)!important;color:var(--mf-color-neutral-600)!important}.mf-chip--outlined.mat-mdc-chip{background-color:transparent!important;border:1px solid var(--mf-color-border)!important}.mf-chip--outlined.mf-chip--brand.mat-mdc-chip{color:var(--mf-color-primary-700)!important;border-color:var(--mf-color-primary-200)!important}.mf-chip--outlined.mf-chip--accent.mat-mdc-chip{color:var(--mf-color-accent-700)!important;border-color:var(--mf-color-accent-300)!important}.mf-chip--outlined.mf-chip--error.mat-mdc-chip{color:var(--mf-color-error-700)!important;border-color:var(--mf-color-error-500)!important}.mf-chip--selected.mat-mdc-chip{box-shadow:var(--mf-shadow-sm)}.mf-chip.mat-mdc-chip.mat-mdc-chip-disabled{opacity:.42}\n"], dependencies: [{ kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i1$6.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["role", "id", "aria-label", "aria-description", "value", "color", "removable", "highlighted", "disableRipple", "disabled"], outputs: ["removed", "destroyed"], exportAs: ["matChip"] }, { kind: "directive", type: i1$6.MatChipAvatar, selector: "mat-chip-avatar, [matChipAvatar]" }, { kind: "directive", type: i1$6.MatChipRemove, selector: "[matChipRemove]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1266
+ }
1267
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfChipComponent, decorators: [{
1268
+ type: Component,
1269
+ args: [{ selector: 'mf-chip', imports: [MatChipsModule, MatIconModule], template: `
1270
+ @if (removable()) {
1271
+ <mat-chip
1272
+ [highlighted]="selected()"
1273
+ [disabled]="disabled()"
1274
+ [class]="hostClasses()"
1275
+ (removed)="mfRemoved.emit()"
1276
+ >
1277
+ @if (leadingIcon()) {
1278
+ <mat-icon matChipAvatar aria-hidden="true">{{ leadingIcon() }}</mat-icon>
1279
+ }
1280
+ {{ label() }}
1281
+ <button matChipRemove [attr.aria-label]="'Remove ' + label()">
1282
+ <mat-icon>cancel</mat-icon>
1283
+ </button>
1284
+ </mat-chip>
1285
+ } @else {
1286
+ <mat-chip
1287
+ [highlighted]="selected()"
1288
+ [disabled]="disabled()"
1289
+ [class]="hostClasses()"
1290
+ >
1291
+ @if (leadingIcon()) {
1292
+ <mat-icon matChipAvatar aria-hidden="true">{{ leadingIcon() }}</mat-icon>
1293
+ }
1294
+ {{ label() }}
1295
+ </mat-chip>
1296
+ }
1297
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-block}.mf-chip.mat-mdc-chip{font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important;font-weight:var(--mf-weight-medium)!important;border-radius:var(--mf-radius-full)!important;transition:background-color var(--mf-duration-base) var(--mf-ease-standard),box-shadow var(--mf-duration-base) var(--mf-ease-standard)}.mf-chip--filled.mf-chip--brand.mat-mdc-chip{background-color:var(--mf-color-primary-100)!important;color:var(--mf-color-primary-800)!important}.mf-chip--filled.mf-chip--accent.mat-mdc-chip{background-color:var(--mf-color-accent-300)!important;color:var(--mf-color-accent-700)!important}.mf-chip--filled.mf-chip--error.mat-mdc-chip{background-color:#fee2e2!important;color:var(--mf-color-error-700)!important}.mf-chip--filled.mf-chip--neutral.mat-mdc-chip{background-color:var(--mf-color-neutral-100)!important;color:var(--mf-color-neutral-600)!important}.mf-chip--outlined.mat-mdc-chip{background-color:transparent!important;border:1px solid var(--mf-color-border)!important}.mf-chip--outlined.mf-chip--brand.mat-mdc-chip{color:var(--mf-color-primary-700)!important;border-color:var(--mf-color-primary-200)!important}.mf-chip--outlined.mf-chip--accent.mat-mdc-chip{color:var(--mf-color-accent-700)!important;border-color:var(--mf-color-accent-300)!important}.mf-chip--outlined.mf-chip--error.mat-mdc-chip{color:var(--mf-color-error-700)!important;border-color:var(--mf-color-error-500)!important}.mf-chip--selected.mat-mdc-chip{box-shadow:var(--mf-shadow-sm)}.mf-chip.mat-mdc-chip.mat-mdc-chip-disabled{opacity:.42}\n"] }]
1298
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], removable: [{ type: i0.Input, args: [{ isSignal: true, alias: "removable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], leadingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "leadingIcon", required: false }] }], mfRemoved: [{ type: i0.Output, args: ["mfRemoved"] }] } });
1299
+
1300
+ /**
1301
+ * Selector de fecha de la librería ng-comps.
1302
+ * Envuelve Angular Material `mat-datepicker` y expone una API uniforme
1303
+ * con look and feel de marca.
1304
+ */
1305
+ class MfDatepickerComponent {
1306
+ cdr = inject(ChangeDetectorRef);
1307
+ ngControl = inject(NgControl, { self: true, optional: true });
1308
+ generatedId = createUniqueId('mf-datepicker');
1309
+ disabledFromForm = signal(false, ...(ngDevMode ? [{ debugName: "disabledFromForm" }] : /* istanbul ignore next */ []));
1310
+ internalValue = signal(null, ...(ngDevMode ? [{ debugName: "internalValue" }] : /* istanbul ignore next */ []));
1311
+ onControlChange = () => undefined;
1312
+ onControlTouched = () => undefined;
1313
+ errorStateMatcher = {
1314
+ isErrorState: (control) => Boolean(this.error() || (control?.invalid && (control.touched || control.dirty))),
1315
+ };
1316
+ /** ID del control */
1317
+ id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
1318
+ /** Etiqueta flotante del campo */
1319
+ label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
1320
+ /** Etiqueta accesible alternativa cuando no existe label visible */
1321
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
1322
+ /** Referencia externa a elementos que etiquetan el control */
1323
+ ariaLabelledby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : /* istanbul ignore next */ []));
1324
+ /** Referencia externa a elementos descriptivos adicionales */
1325
+ ariaDescribedby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaDescribedby" }] : /* istanbul ignore next */ []));
1326
+ /** Placeholder del input */
1327
+ placeholder = input('DD/MM/YYYY', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
1328
+ /** Tamaño del campo */
1329
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
1330
+ /** Deshabilitado */
1331
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
1332
+ /** Requerido */
1333
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
1334
+ /** Valor inicial del datepicker */
1335
+ value = input(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
1336
+ /** Texto de ayuda debajo del campo */
1337
+ hint = input(undefined, ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
1338
+ /** Mensaje de error */
1339
+ error = input(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
1340
+ /** Fecha mínima seleccionable */
1341
+ min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
1342
+ /** Fecha máxima seleccionable */
1343
+ max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
1344
+ /** Ancho completo */
1345
+ fullWidth = input(false, ...(ngDevMode ? [{ debugName: "fullWidth" }] : /* istanbul ignore next */ []));
1346
+ /** Etiqueta accesible del botón para abrir el calendario */
1347
+ toggleAriaLabel = input('Open calendar', ...(ngDevMode ? [{ debugName: "toggleAriaLabel" }] : /* istanbul ignore next */ []));
1348
+ mfChange = output();
1349
+ mfBlur = output();
1350
+ constructor() {
1351
+ effect(() => {
1352
+ this.internalValue.set(this.value());
1353
+ });
1354
+ effect(() => {
1355
+ if (!hasAccessibleName(this.label(), this.ariaLabel(), this.ariaLabelledby())) {
1356
+ warnInDev('mf-datepicker requiere `label`, `ariaLabel` o `ariaLabelledby` para exponer un nombre accesible.');
1357
+ }
1358
+ });
1359
+ }
1360
+ controlId = computed(() => this.id() ?? this.generatedId, ...(ngDevMode ? [{ debugName: "controlId" }] : /* istanbul ignore next */ []));
1361
+ hintId = computed(() => this.hint() ? `${this.controlId()}-hint` : null, ...(ngDevMode ? [{ debugName: "hintId" }] : /* istanbul ignore next */ []));
1362
+ errorId = computed(() => this.error() ? `${this.controlId()}-error` : null, ...(ngDevMode ? [{ debugName: "errorId" }] : /* istanbul ignore next */ []));
1363
+ describedBy = computed(() => mergeAriaIds(this.ariaDescribedby(), this.hintId(), this.errorId()), ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
1364
+ resolvedAriaLabel = computed(() => this.label() ? null : this.ariaLabel() ?? null, ...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
1365
+ isDisabled = computed(() => this.disabled() || this.disabledFromForm(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
1366
+ hostClasses = computed(() => {
1367
+ const classes = ['mf-datepicker', `mf-datepicker--${this.size()}`];
1368
+ if (this.fullWidth())
1369
+ classes.push('mf-datepicker--full');
1370
+ if (this.error())
1371
+ classes.push('mf-datepicker--error');
1372
+ return classes.join(' ');
1373
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1374
+ writeValue(value) {
1375
+ this.internalValue.set(value);
1376
+ this.cdr.markForCheck();
1377
+ }
1378
+ registerOnChange(fn) {
1379
+ this.onControlChange = fn;
1380
+ }
1381
+ registerOnTouched(fn) {
1382
+ this.onControlTouched = fn;
1383
+ }
1384
+ setDisabledState(isDisabled) {
1385
+ this.disabledFromForm.set(isDisabled);
1386
+ this.cdr.markForCheck();
1387
+ }
1388
+ isInvalid() {
1389
+ const control = this.ngControl?.control;
1390
+ return Boolean(this.error() || (control?.invalid && (control.touched || control.dirty)));
1391
+ }
1392
+ onDateChange(event) {
1393
+ this.internalValue.set(event.value);
1394
+ this.onControlChange(event.value);
1395
+ this.onControlTouched();
1396
+ this.mfChange.emit(event.value);
1397
+ }
1398
+ onBlur() {
1399
+ this.onControlTouched();
1400
+ this.mfBlur.emit();
1401
+ }
1402
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfDatepickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1403
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfDatepickerComponent, isStandalone: true, selector: "mf-datepicker", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "ariaDescribedby", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, toggleAriaLabel: { classPropertyName: "toggleAriaLabel", publicName: "toggleAriaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfChange: "mfChange", mfBlur: "mfBlur" }, providers: [
1404
+ {
1405
+ provide: NG_VALUE_ACCESSOR,
1406
+ useExisting: forwardRef(() => MfDatepickerComponent),
1407
+ multi: true,
1408
+ },
1409
+ ], ngImport: i0, template: `
1410
+ <mat-form-field [appearance]="'outline'" [class]="hostClasses()">
1411
+ @if (label()) {
1412
+ <mat-label>{{ label() }}</mat-label>
1413
+ }
1414
+ <input
1415
+ matInput
1416
+ [id]="controlId()"
1417
+ [matDatepicker]="picker"
1418
+ [placeholder]="placeholder()"
1419
+ [disabled]="isDisabled()"
1420
+ [required]="required()"
1421
+ [min]="min()"
1422
+ [max]="max()"
1423
+ [value]="internalValue()"
1424
+ [errorStateMatcher]="errorStateMatcher"
1425
+ [attr.aria-label]="resolvedAriaLabel()"
1426
+ [attr.aria-labelledby]="ariaLabelledby() || null"
1427
+ [attr.aria-describedby]="describedBy()"
1428
+ [attr.aria-invalid]="isInvalid() ? 'true' : null"
1429
+ [attr.aria-required]="required() ? 'true' : null"
1430
+ (dateChange)="onDateChange($event)"
1431
+ (blur)="onBlur()"
1432
+ />
1433
+ <mat-datepicker-toggle
1434
+ matIconSuffix
1435
+ [for]="picker"
1436
+ [disabled]="isDisabled()"
1437
+ [attr.aria-label]="toggleAriaLabel()"
1438
+ >
1439
+ <mat-icon matDatepickerToggleIcon aria-hidden="true">
1440
+ calendar_month
1441
+ </mat-icon>
1442
+ </mat-datepicker-toggle>
1443
+ <mat-datepicker #picker />
1444
+ @if (hint()) {
1445
+ <mat-hint [attr.id]="hintId()">{{ hint() }}</mat-hint>
1446
+ }
1447
+ </mat-form-field>
1448
+ @if (error()) {
1449
+ <p class="mf-datepicker__error" [attr.id]="errorId()" role="alert">
1450
+ {{ error() }}
1451
+ </p>
1452
+ }
1453
+ `, isInline: true, styles: [":host{display:inline-block}.mf-datepicker{font-family:var(--mf-font-base)!important;width:100%}.mf-datepicker--full{width:100%}.mf-datepicker .mat-mdc-text-field-wrapper{border-radius:var(--mf-radius-md)!important}.mf-datepicker .mdc-notched-outline__leading,.mf-datepicker .mdc-notched-outline__notch,.mf-datepicker .mdc-notched-outline__trailing{border-color:var(--mf-color-border)!important;transition:border-color var(--mf-duration-base) var(--mf-ease-standard)}.mf-datepicker .mat-mdc-form-field-focus-overlay{background-color:transparent!important}.mf-datepicker.mat-focused .mdc-notched-outline__leading,.mf-datepicker.mat-focused .mdc-notched-outline__notch,.mf-datepicker.mat-focused .mdc-notched-outline__trailing{border-color:var(--mf-color-brand)!important;border-width:1.5px!important}.mf-datepicker--error .mdc-notched-outline__leading,.mf-datepicker--error .mdc-notched-outline__notch,.mf-datepicker--error .mdc-notched-outline__trailing{border-color:var(--mf-color-error-500)!important}.mf-datepicker .mat-mdc-floating-label{font-family:var(--mf-font-base)!important;font-weight:var(--mf-weight-medium)!important;color:var(--mf-color-neutral-400)!important}.mf-datepicker.mat-focused .mat-mdc-floating-label{color:var(--mf-color-brand)!important}.mf-datepicker .mat-mdc-input-element{font-family:var(--mf-font-base)!important;color:var(--mf-color-on-surface)!important;caret-color:var(--mf-color-brand)}.mf-datepicker .mat-datepicker-toggle .mat-icon{color:var(--mf-color-neutral-400)!important;transition:color var(--mf-duration-base) var(--mf-ease-standard)}.mf-datepicker.mat-focused .mat-datepicker-toggle .mat-icon{color:var(--mf-color-brand)!important}.mf-datepicker .mat-mdc-form-field-hint{font-size:var(--mf-text-xs)!important;color:var(--mf-color-neutral-400)!important}.mf-datepicker .mat-mdc-form-field-error{font-size:var(--mf-text-xs)!important}.mf-datepicker--sm .mat-mdc-input-element{font-size:var(--mf-text-sm)!important}.mf-datepicker--md .mat-mdc-input-element{font-size:var(--mf-text-base)!important}.mf-datepicker--lg .mat-mdc-input-element{font-size:var(--mf-text-lg)!important;padding-top:var(--mf-space-1)!important;padding-bottom:var(--mf-space-1)!important}.mf-datepicker .mat-mdc-input-element:disabled{color:var(--mf-color-neutral-300)!important}\n"], dependencies: [{ kind: "ngmodule", type: MatDatepickerModule }, { kind: "component", type: i1$7.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i1$7.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i1$7.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "directive", type: i1$7.MatDatepickerToggleIcon, selector: "[matDatepickerToggleIcon]" }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatNativeDateModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1454
+ }
1455
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfDatepickerComponent, decorators: [{
1456
+ type: Component,
1457
+ args: [{ selector: 'mf-datepicker', imports: [
1458
+ MatDatepickerModule,
1459
+ MatFormFieldModule,
1460
+ MatInputModule,
1461
+ MatNativeDateModule,
1462
+ MatIconModule,
1463
+ ], providers: [
1464
+ {
1465
+ provide: NG_VALUE_ACCESSOR,
1466
+ useExisting: forwardRef(() => MfDatepickerComponent),
1467
+ multi: true,
1468
+ },
1469
+ ], template: `
1470
+ <mat-form-field [appearance]="'outline'" [class]="hostClasses()">
1471
+ @if (label()) {
1472
+ <mat-label>{{ label() }}</mat-label>
1473
+ }
1474
+ <input
1475
+ matInput
1476
+ [id]="controlId()"
1477
+ [matDatepicker]="picker"
1478
+ [placeholder]="placeholder()"
1479
+ [disabled]="isDisabled()"
1480
+ [required]="required()"
1481
+ [min]="min()"
1482
+ [max]="max()"
1483
+ [value]="internalValue()"
1484
+ [errorStateMatcher]="errorStateMatcher"
1485
+ [attr.aria-label]="resolvedAriaLabel()"
1486
+ [attr.aria-labelledby]="ariaLabelledby() || null"
1487
+ [attr.aria-describedby]="describedBy()"
1488
+ [attr.aria-invalid]="isInvalid() ? 'true' : null"
1489
+ [attr.aria-required]="required() ? 'true' : null"
1490
+ (dateChange)="onDateChange($event)"
1491
+ (blur)="onBlur()"
1492
+ />
1493
+ <mat-datepicker-toggle
1494
+ matIconSuffix
1495
+ [for]="picker"
1496
+ [disabled]="isDisabled()"
1497
+ [attr.aria-label]="toggleAriaLabel()"
1498
+ >
1499
+ <mat-icon matDatepickerToggleIcon aria-hidden="true">
1500
+ calendar_month
1501
+ </mat-icon>
1502
+ </mat-datepicker-toggle>
1503
+ <mat-datepicker #picker />
1504
+ @if (hint()) {
1505
+ <mat-hint [attr.id]="hintId()">{{ hint() }}</mat-hint>
1506
+ }
1507
+ </mat-form-field>
1508
+ @if (error()) {
1509
+ <p class="mf-datepicker__error" [attr.id]="errorId()" role="alert">
1510
+ {{ error() }}
1511
+ </p>
1512
+ }
1513
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-block}.mf-datepicker{font-family:var(--mf-font-base)!important;width:100%}.mf-datepicker--full{width:100%}.mf-datepicker .mat-mdc-text-field-wrapper{border-radius:var(--mf-radius-md)!important}.mf-datepicker .mdc-notched-outline__leading,.mf-datepicker .mdc-notched-outline__notch,.mf-datepicker .mdc-notched-outline__trailing{border-color:var(--mf-color-border)!important;transition:border-color var(--mf-duration-base) var(--mf-ease-standard)}.mf-datepicker .mat-mdc-form-field-focus-overlay{background-color:transparent!important}.mf-datepicker.mat-focused .mdc-notched-outline__leading,.mf-datepicker.mat-focused .mdc-notched-outline__notch,.mf-datepicker.mat-focused .mdc-notched-outline__trailing{border-color:var(--mf-color-brand)!important;border-width:1.5px!important}.mf-datepicker--error .mdc-notched-outline__leading,.mf-datepicker--error .mdc-notched-outline__notch,.mf-datepicker--error .mdc-notched-outline__trailing{border-color:var(--mf-color-error-500)!important}.mf-datepicker .mat-mdc-floating-label{font-family:var(--mf-font-base)!important;font-weight:var(--mf-weight-medium)!important;color:var(--mf-color-neutral-400)!important}.mf-datepicker.mat-focused .mat-mdc-floating-label{color:var(--mf-color-brand)!important}.mf-datepicker .mat-mdc-input-element{font-family:var(--mf-font-base)!important;color:var(--mf-color-on-surface)!important;caret-color:var(--mf-color-brand)}.mf-datepicker .mat-datepicker-toggle .mat-icon{color:var(--mf-color-neutral-400)!important;transition:color var(--mf-duration-base) var(--mf-ease-standard)}.mf-datepicker.mat-focused .mat-datepicker-toggle .mat-icon{color:var(--mf-color-brand)!important}.mf-datepicker .mat-mdc-form-field-hint{font-size:var(--mf-text-xs)!important;color:var(--mf-color-neutral-400)!important}.mf-datepicker .mat-mdc-form-field-error{font-size:var(--mf-text-xs)!important}.mf-datepicker--sm .mat-mdc-input-element{font-size:var(--mf-text-sm)!important}.mf-datepicker--md .mat-mdc-input-element{font-size:var(--mf-text-base)!important}.mf-datepicker--lg .mat-mdc-input-element{font-size:var(--mf-text-lg)!important;padding-top:var(--mf-space-1)!important;padding-bottom:var(--mf-space-1)!important}.mf-datepicker .mat-mdc-input-element:disabled{color:var(--mf-color-neutral-300)!important}\n"] }]
1514
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledby", required: false }] }], ariaDescribedby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedby", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], toggleAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "toggleAriaLabel", required: false }] }], mfChange: [{ type: i0.Output, args: ["mfChange"] }], mfBlur: [{ type: i0.Output, args: ["mfBlur"] }] } });
1515
+
1516
+ /**
1517
+ * Contenido de diálogo de la librería ng-comps.
1518
+ * Envuelve las directivas de Angular Material `mat-dialog-*` y expone
1519
+ * una API uniforme con look and feel de marca.
1520
+ *
1521
+ * Uso:
1522
+ * ```
1523
+ * dialog.open(MfDialogComponent, {
1524
+ * data: { title: 'Confirmar', message: '¿Deseas continuar?' }
1525
+ * });
1526
+ * ```
1527
+ */
1528
+ class MfDialogComponent {
1529
+ dialogRef = inject((MatDialogRef), {
1530
+ optional: true,
1531
+ });
1532
+ generatedId = createUniqueId('mf-dialog');
1533
+ /** ID base del diálogo */
1534
+ id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
1535
+ /** Título del diálogo */
1536
+ title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
1537
+ /** Etiqueta accesible alternativa cuando no existe título visible */
1538
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
1539
+ /** Referencia externa a elementos que etiquetan el diálogo */
1540
+ ariaLabelledby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : /* istanbul ignore next */ []));
1541
+ /** Referencia externa a elementos descriptivos adicionales */
1542
+ ariaDescribedby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaDescribedby" }] : /* istanbul ignore next */ []));
1543
+ /** Mensaje descriptivo */
1544
+ message = input(undefined, ...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
1545
+ /** Mostrar botón de cerrar */
1546
+ showClose = input(true, ...(ngDevMode ? [{ debugName: "showClose" }] : /* istanbul ignore next */ []));
1547
+ /** Mostrar área de acciones (footer) */
1548
+ showActions = input(true, ...(ngDevMode ? [{ debugName: "showActions" }] : /* istanbul ignore next */ []));
1549
+ /** Rol del diálogo */
1550
+ role = input('dialog', ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
1551
+ /** Etiqueta accesible del botón de cierre */
1552
+ closeButtonLabel = input('Close dialog', ...(ngDevMode ? [{ debugName: "closeButtonLabel" }] : /* istanbul ignore next */ []));
1553
+ mfClose = output();
1554
+ constructor() {
1555
+ effect(() => {
1556
+ if (!hasAccessibleName(this.title(), this.ariaLabel(), this.ariaLabelledby())) {
1557
+ warnInDev('mf-dialog requiere `title`, `ariaLabel` o `ariaLabelledby` para exponer un nombre accesible.');
1558
+ }
1559
+ });
1560
+ }
1561
+ dialogId = computed(() => this.id() ?? this.generatedId, ...(ngDevMode ? [{ debugName: "dialogId" }] : /* istanbul ignore next */ []));
1562
+ titleId = computed(() => `${this.dialogId()}-title`, ...(ngDevMode ? [{ debugName: "titleId" }] : /* istanbul ignore next */ []));
1563
+ descriptionId = computed(() => `${this.dialogId()}-description`, ...(ngDevMode ? [{ debugName: "descriptionId" }] : /* istanbul ignore next */ []));
1564
+ computedLabelledby = computed(() => mergeAriaIds(this.ariaLabelledby(), this.title() ? this.titleId() : null), ...(ngDevMode ? [{ debugName: "computedLabelledby" }] : /* istanbul ignore next */ []));
1565
+ computedDescribedby = computed(() => mergeAriaIds(this.ariaDescribedby(), this.message() ? this.descriptionId() : null), ...(ngDevMode ? [{ debugName: "computedDescribedby" }] : /* istanbul ignore next */ []));
1566
+ resolvedAriaLabel = computed(() => this.title() ? null : this.ariaLabel() ?? null, ...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
1567
+ hostClasses = computed(() => 'mf-dialog', ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1568
+ onClose() {
1569
+ this.mfClose.emit();
1570
+ this.dialogRef?.close();
1571
+ }
1572
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1573
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfDialogComponent, isStandalone: true, selector: "mf-dialog", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "ariaDescribedby", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, showClose: { classPropertyName: "showClose", publicName: "showClose", isSignal: true, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, closeButtonLabel: { classPropertyName: "closeButtonLabel", publicName: "closeButtonLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfClose: "mfClose" }, ngImport: i0, template: `
1574
+ <div
1575
+ [class]="hostClasses()"
1576
+ [attr.role]="role()"
1577
+ aria-modal="true"
1578
+ [attr.aria-label]="resolvedAriaLabel()"
1579
+ [attr.aria-labelledby]="computedLabelledby()"
1580
+ [attr.aria-describedby]="computedDescribedby()"
1581
+ >
1582
+ @if (title()) {
1583
+ <h2 mat-dialog-title class="mf-dialog__header" [id]="titleId()">
1584
+ <span class="mf-dialog__title">{{ title() }}</span>
1585
+ @if (showClose()) {
1586
+ <button
1587
+ mat-icon-button
1588
+ class="mf-dialog__close"
1589
+ (click)="onClose()"
1590
+ [attr.aria-label]="closeButtonLabel()"
1591
+ type="button"
1592
+ >
1593
+ <mat-icon aria-hidden="true">close</mat-icon>
1594
+ </button>
1595
+ }
1596
+ </h2>
1597
+ } @else if (showClose()) {
1598
+ <div class="mf-dialog__header mf-dialog__header--compact">
1599
+ <span></span>
1600
+ <button
1601
+ mat-icon-button
1602
+ class="mf-dialog__close"
1603
+ (click)="onClose()"
1604
+ [attr.aria-label]="closeButtonLabel()"
1605
+ type="button"
1606
+ >
1607
+ <mat-icon aria-hidden="true">close</mat-icon>
1608
+ </button>
1609
+ </div>
1610
+ }
1611
+
1612
+ <div mat-dialog-content class="mf-dialog__content">
1613
+ @if (message()) {
1614
+ <p class="mf-dialog__message" [id]="descriptionId()">{{ message() }}</p>
1615
+ }
1616
+
1617
+ <ng-content />
1618
+ </div>
1619
+
1620
+ @if (showActions()) {
1621
+ <div mat-dialog-actions class="mf-dialog__actions">
1622
+ <ng-content select="[mfDialogActions]" />
1623
+ </div>
1624
+ }
1625
+ </div>
1626
+ `, isInline: true, styles: [".mf-dialog{font-family:var(--mf-font-base);min-width:360px;max-width:560px}.mf-dialog__header{display:flex;align-items:center;justify-content:space-between;gap:var(--mf-space-3);padding:var(--mf-space-6) var(--mf-space-6) var(--mf-space-3)}.mf-dialog__header--compact{padding-bottom:0}.mf-dialog__title{font-family:var(--mf-font-display);font-size:var(--mf-text-xl);font-weight:var(--mf-weight-bold);color:var(--mf-color-on-surface);margin:0;line-height:var(--mf-leading-tight)}.mf-dialog__close{flex-shrink:0;color:var(--mf-color-neutral-400);transition:background-color var(--mf-duration-fast) var(--mf-ease-standard),color var(--mf-duration-fast) var(--mf-ease-standard)}.mf-dialog__close:hover{background-color:var(--mf-color-neutral-100);color:var(--mf-color-on-surface)}.mf-dialog__close .mat-icon{font-size:20px;width:20px;height:20px}.mf-dialog__body{padding:0 var(--mf-space-6)}.mf-dialog__message{font-size:var(--mf-text-sm);color:var(--mf-color-neutral-600);line-height:var(--mf-leading-normal);margin:0}.mf-dialog__content{padding:var(--mf-space-3) var(--mf-space-6)}.mf-dialog__content:empty{display:none}\n"], dependencies: [{ kind: "ngmodule", type: MatDialogModule }, { kind: "directive", type: i1$8.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$8.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$8.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1627
+ }
1628
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfDialogComponent, decorators: [{
1629
+ type: Component,
1630
+ args: [{ selector: 'mf-dialog', imports: [MatDialogModule, MatIconModule], template: `
1631
+ <div
1632
+ [class]="hostClasses()"
1633
+ [attr.role]="role()"
1634
+ aria-modal="true"
1635
+ [attr.aria-label]="resolvedAriaLabel()"
1636
+ [attr.aria-labelledby]="computedLabelledby()"
1637
+ [attr.aria-describedby]="computedDescribedby()"
1638
+ >
1639
+ @if (title()) {
1640
+ <h2 mat-dialog-title class="mf-dialog__header" [id]="titleId()">
1641
+ <span class="mf-dialog__title">{{ title() }}</span>
1642
+ @if (showClose()) {
1643
+ <button
1644
+ mat-icon-button
1645
+ class="mf-dialog__close"
1646
+ (click)="onClose()"
1647
+ [attr.aria-label]="closeButtonLabel()"
1648
+ type="button"
1649
+ >
1650
+ <mat-icon aria-hidden="true">close</mat-icon>
1651
+ </button>
1652
+ }
1653
+ </h2>
1654
+ } @else if (showClose()) {
1655
+ <div class="mf-dialog__header mf-dialog__header--compact">
1656
+ <span></span>
1657
+ <button
1658
+ mat-icon-button
1659
+ class="mf-dialog__close"
1660
+ (click)="onClose()"
1661
+ [attr.aria-label]="closeButtonLabel()"
1662
+ type="button"
1663
+ >
1664
+ <mat-icon aria-hidden="true">close</mat-icon>
1665
+ </button>
1666
+ </div>
1667
+ }
1668
+
1669
+ <div mat-dialog-content class="mf-dialog__content">
1670
+ @if (message()) {
1671
+ <p class="mf-dialog__message" [id]="descriptionId()">{{ message() }}</p>
1672
+ }
1673
+
1674
+ <ng-content />
1675
+ </div>
1676
+
1677
+ @if (showActions()) {
1678
+ <div mat-dialog-actions class="mf-dialog__actions">
1679
+ <ng-content select="[mfDialogActions]" />
1680
+ </div>
1681
+ }
1682
+ </div>
1683
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".mf-dialog{font-family:var(--mf-font-base);min-width:360px;max-width:560px}.mf-dialog__header{display:flex;align-items:center;justify-content:space-between;gap:var(--mf-space-3);padding:var(--mf-space-6) var(--mf-space-6) var(--mf-space-3)}.mf-dialog__header--compact{padding-bottom:0}.mf-dialog__title{font-family:var(--mf-font-display);font-size:var(--mf-text-xl);font-weight:var(--mf-weight-bold);color:var(--mf-color-on-surface);margin:0;line-height:var(--mf-leading-tight)}.mf-dialog__close{flex-shrink:0;color:var(--mf-color-neutral-400);transition:background-color var(--mf-duration-fast) var(--mf-ease-standard),color var(--mf-duration-fast) var(--mf-ease-standard)}.mf-dialog__close:hover{background-color:var(--mf-color-neutral-100);color:var(--mf-color-on-surface)}.mf-dialog__close .mat-icon{font-size:20px;width:20px;height:20px}.mf-dialog__body{padding:0 var(--mf-space-6)}.mf-dialog__message{font-size:var(--mf-text-sm);color:var(--mf-color-neutral-600);line-height:var(--mf-leading-normal);margin:0}.mf-dialog__content{padding:var(--mf-space-3) var(--mf-space-6)}.mf-dialog__content:empty{display:none}\n"] }]
1684
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledby", required: false }] }], ariaDescribedby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedby", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], showClose: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClose", required: false }] }], showActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "showActions", required: false }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], closeButtonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeButtonLabel", required: false }] }], mfClose: [{ type: i0.Output, args: ["mfClose"] }] } });
1685
+
1686
+ class MfDialogService {
1687
+ dialog = inject(MatDialog);
1688
+ open(component, config = {}) {
1689
+ const panelClass = Array.isArray(config.panelClass)
1690
+ ? ['mf-dialog-panel', ...config.panelClass]
1691
+ : ['mf-dialog-panel', ...(config.panelClass ? [config.panelClass] : [])];
1692
+ return this.dialog.open(component, {
1693
+ ...config,
1694
+ role: config.role ?? 'dialog',
1695
+ autoFocus: config.autoFocus ?? 'first-tabbable',
1696
+ restoreFocus: config.restoreFocus ?? true,
1697
+ ariaLabel: config.ariaLabel,
1698
+ ariaLabelledBy: config.ariaLabelledby,
1699
+ ariaDescribedBy: config.ariaDescribedby,
1700
+ panelClass,
1701
+ });
1702
+ }
1703
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1704
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfDialogService, providedIn: 'root' });
1705
+ }
1706
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfDialogService, decorators: [{
1707
+ type: Injectable,
1708
+ args: [{ providedIn: 'root' }]
1709
+ }] });
1710
+
1711
+ /**
1712
+ * Divider de la librería ng-comps.
1713
+ * Envuelve Angular Material `mat-divider` y expone una API uniforme
1714
+ * con look and feel de marca.
1715
+ */
1716
+ class MfDividerComponent {
1717
+ /** Orientación vertical */
1718
+ vertical = input(false, ...(ngDevMode ? [{ debugName: "vertical" }] : /* istanbul ignore next */ []));
1719
+ /** Variante visual */
1720
+ variant = input('full', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
1721
+ /** Espaciado extra arriba y abajo */
1722
+ spacing = input('none', ...(ngDevMode ? [{ debugName: "spacing" }] : /* istanbul ignore next */ []));
1723
+ insetValue = computed(() => this.variant() === 'inset', ...(ngDevMode ? [{ debugName: "insetValue" }] : /* istanbul ignore next */ []));
1724
+ hostClasses = computed(() => {
1725
+ const classes = ['mf-divider', `mf-divider--${this.variant()}`, `mf-divider--spacing-${this.spacing()}`];
1726
+ if (this.vertical())
1727
+ classes.push('mf-divider--vertical');
1728
+ return classes.join(' ');
1729
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1730
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfDividerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1731
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: MfDividerComponent, isStandalone: true, selector: "mf-divider", inputs: { vertical: { classPropertyName: "vertical", publicName: "vertical", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, spacing: { classPropertyName: "spacing", publicName: "spacing", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
1732
+ <mat-divider
1733
+ [vertical]="vertical()"
1734
+ [inset]="insetValue()"
1735
+ [class]="hostClasses()"
1736
+ />
1737
+ `, isInline: true, styles: [":host{display:block}:host:has(.mf-divider--vertical){display:inline-block;height:100%}.mf-divider .mat-divider{border-top-color:var(--mf-color-border)!important}.mf-divider--vertical .mat-divider{border-left-color:var(--mf-color-border)!important}.mf-divider--middle .mat-divider{margin-left:var(--mf-space-4)!important;margin-right:var(--mf-space-4)!important}.mf-divider--spacing-sm{padding-top:var(--mf-space-2);padding-bottom:var(--mf-space-2)}.mf-divider--spacing-md{padding-top:var(--mf-space-4);padding-bottom:var(--mf-space-4)}.mf-divider--spacing-lg{padding-top:var(--mf-space-6);padding-bottom:var(--mf-space-6)}\n"], dependencies: [{ kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i1$9.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1738
+ }
1739
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfDividerComponent, decorators: [{
1740
+ type: Component,
1741
+ args: [{ selector: 'mf-divider', imports: [MatDividerModule], template: `
1742
+ <mat-divider
1743
+ [vertical]="vertical()"
1744
+ [inset]="insetValue()"
1745
+ [class]="hostClasses()"
1746
+ />
1747
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}:host:has(.mf-divider--vertical){display:inline-block;height:100%}.mf-divider .mat-divider{border-top-color:var(--mf-color-border)!important}.mf-divider--vertical .mat-divider{border-left-color:var(--mf-color-border)!important}.mf-divider--middle .mat-divider{margin-left:var(--mf-space-4)!important;margin-right:var(--mf-space-4)!important}.mf-divider--spacing-sm{padding-top:var(--mf-space-2);padding-bottom:var(--mf-space-2)}.mf-divider--spacing-md{padding-top:var(--mf-space-4);padding-bottom:var(--mf-space-4)}.mf-divider--spacing-lg{padding-top:var(--mf-space-6);padding-bottom:var(--mf-space-6)}\n"] }]
1748
+ }], propDecorators: { vertical: [{ type: i0.Input, args: [{ isSignal: true, alias: "vertical", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], spacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "spacing", required: false }] }] } });
1749
+
1750
+ /**
1751
+ * Contenedor de campo de formulario de la librería ng-comps.
1752
+ * Proporciona estructura de layout consistente con label, contenido proyectado,
1753
+ * y mensajes opcionales de ayuda o error.
1754
+ */
1755
+ class MfFormFieldComponent {
1756
+ /** Etiqueta del campo */
1757
+ label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
1758
+ /** ID para asociar el label con el control */
1759
+ fieldId = input(undefined, ...(ngDevMode ? [{ debugName: "fieldId" }] : /* istanbul ignore next */ []));
1760
+ /** Texto de ayuda */
1761
+ hint = input(undefined, ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
1762
+ /** Mensaje de error */
1763
+ error = input(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
1764
+ /** Campo requerido (muestra asterisco) */
1765
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
1766
+ constructor() {
1767
+ effect(() => {
1768
+ if (this.label() && !this.fieldId()) {
1769
+ warnInDev('mf-form-field requiere `fieldId` cuando renderiza `label` para poder asociarlo al control proyectado.');
1770
+ }
1771
+ });
1772
+ }
1773
+ labelClasses = computed(() => {
1774
+ const classes = ['mf-form-field__label'];
1775
+ if (this.error())
1776
+ classes.push('mf-form-field__label--error');
1777
+ return classes.join(' ');
1778
+ }, ...(ngDevMode ? [{ debugName: "labelClasses" }] : /* istanbul ignore next */ []));
1779
+ hostClasses = computed(() => {
1780
+ const classes = ['mf-form-field'];
1781
+ if (this.error())
1782
+ classes.push('mf-form-field--error');
1783
+ return classes.join(' ');
1784
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1785
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfFormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1786
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfFormFieldComponent, isStandalone: true, selector: "mf-form-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, fieldId: { classPropertyName: "fieldId", publicName: "fieldId", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
1787
+ @if (label()) {
1788
+ <label [class]="labelClasses()" [attr.for]="fieldId()">{{ label() }}
1789
+ @if (required()) {
1790
+ <span class="mf-form-field__required" aria-hidden="true"> *</span>
1791
+ }
1792
+ </label>
1793
+ }
1794
+ <div class="mf-form-field__control">
1795
+ <ng-content />
1796
+ </div>
1797
+ @if (error()) {
1798
+ <p class="mf-form-field__error" role="alert">{{ error() }}</p>
1799
+ } @else if (hint()) {
1800
+ <p class="mf-form-field__hint">{{ hint() }}</p>
1801
+ }
1802
+ `, isInline: true, styles: [":host{display:block}.mf-form-field{display:flex;flex-direction:column;gap:var(--mf-space-1)}.mf-form-field__label{font-family:var(--mf-font-base);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-medium);color:var(--mf-color-on-surface);line-height:var(--mf-leading-normal);cursor:default}.mf-form-field__label--error,.mf-form-field__required{color:var(--mf-color-error-500)}.mf-form-field__control{width:100%}.mf-form-field__hint{font-family:var(--mf-font-base);font-size:var(--mf-text-xs);color:var(--mf-color-neutral-400);margin:0;padding-left:var(--mf-space-1)}.mf-form-field__error{font-family:var(--mf-font-base);font-size:var(--mf-text-xs);color:var(--mf-color-error-500);margin:0;padding-left:var(--mf-space-1)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1803
+ }
1804
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfFormFieldComponent, decorators: [{
1805
+ type: Component,
1806
+ args: [{ selector: 'mf-form-field', imports: [], template: `
1807
+ @if (label()) {
1808
+ <label [class]="labelClasses()" [attr.for]="fieldId()">{{ label() }}
1809
+ @if (required()) {
1810
+ <span class="mf-form-field__required" aria-hidden="true"> *</span>
1811
+ }
1812
+ </label>
1813
+ }
1814
+ <div class="mf-form-field__control">
1815
+ <ng-content />
1816
+ </div>
1817
+ @if (error()) {
1818
+ <p class="mf-form-field__error" role="alert">{{ error() }}</p>
1819
+ } @else if (hint()) {
1820
+ <p class="mf-form-field__hint">{{ hint() }}</p>
1821
+ }
1822
+ `, changeDetection: ChangeDetectionStrategy.OnPush, host: {
1823
+ '[class]': 'hostClasses()',
1824
+ }, styles: [":host{display:block}.mf-form-field{display:flex;flex-direction:column;gap:var(--mf-space-1)}.mf-form-field__label{font-family:var(--mf-font-base);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-medium);color:var(--mf-color-on-surface);line-height:var(--mf-leading-normal);cursor:default}.mf-form-field__label--error,.mf-form-field__required{color:var(--mf-color-error-500)}.mf-form-field__control{width:100%}.mf-form-field__hint{font-family:var(--mf-font-base);font-size:var(--mf-text-xs);color:var(--mf-color-neutral-400);margin:0;padding-left:var(--mf-space-1)}.mf-form-field__error{font-family:var(--mf-font-base);font-size:var(--mf-text-xs);color:var(--mf-color-error-500);margin:0;padding-left:var(--mf-space-1)}\n"] }]
1825
+ }], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], fieldId: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldId", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }] } });
1826
+
1827
+ /**
1828
+ * Lista en cuadrícula de la librería ng-comps.
1829
+ * Envuelve Angular Material `mat-grid-list` y expone una API uniforme
1830
+ * con look and feel de marca. Soporta tiles estáticas y content projection.
1831
+ */
1832
+ class MfGridListComponent {
1833
+ /** Número de columnas */
1834
+ cols = input(2, ...(ngDevMode ? [{ debugName: "cols" }] : /* istanbul ignore next */ []));
1835
+ /** Altura de cada fila */
1836
+ rowHeight = input('1:1', ...(ngDevMode ? [{ debugName: "rowHeight" }] : /* istanbul ignore next */ []));
1837
+ /** Espacio entre tiles */
1838
+ gutterSize = input('8px', ...(ngDevMode ? [{ debugName: "gutterSize" }] : /* istanbul ignore next */ []));
1839
+ /** Tiles a renderizar */
1840
+ tiles = input([], ...(ngDevMode ? [{ debugName: "tiles" }] : /* istanbul ignore next */ []));
1841
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfGridListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1842
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfGridListComponent, isStandalone: true, selector: "mf-grid-list", inputs: { cols: { classPropertyName: "cols", publicName: "cols", isSignal: true, isRequired: false, transformFunction: null }, rowHeight: { classPropertyName: "rowHeight", publicName: "rowHeight", isSignal: true, isRequired: false, transformFunction: null }, gutterSize: { classPropertyName: "gutterSize", publicName: "gutterSize", isSignal: true, isRequired: false, transformFunction: null }, tiles: { classPropertyName: "tiles", publicName: "tiles", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
1843
+ <mat-grid-list
1844
+ class="mf-grid-list"
1845
+ [cols]="cols()"
1846
+ [rowHeight]="rowHeight()"
1847
+ [gutterSize]="gutterSize()"
1848
+ >
1849
+ @for (tile of tiles(); track $index) {
1850
+ <mat-grid-tile
1851
+ class="mf-grid-list__tile"
1852
+ [colspan]="tile.colspan ?? 1"
1853
+ [rowspan]="tile.rowspan ?? 1"
1854
+ [style.background]="tile.background || null"
1855
+ >
1856
+ <mat-grid-tile-header>
1857
+ @if (tile.title) {
1858
+ <span class="mf-grid-list__tile-title">{{ tile.title }}</span>
1859
+ }
1860
+ @if (tile.subtitle) {
1861
+ <span class="mf-grid-list__tile-subtitle">{{ tile.subtitle }}</span>
1862
+ }
1863
+ </mat-grid-tile-header>
1864
+ </mat-grid-tile>
1865
+ }
1866
+ <ng-content />
1867
+ </mat-grid-list>
1868
+ `, isInline: true, styles: [":host{display:block}.mf-grid-list{font-family:var(--mf-font-base)!important}.mf-grid-list__tile{background-color:var(--mf-color-surface-raised);border-radius:var(--mf-radius-md)!important;overflow:hidden;transition:box-shadow var(--mf-duration-base) var(--mf-ease-standard)}.mf-grid-list__tile:hover{box-shadow:var(--mf-shadow-md)}.mf-grid-list__tile mat-grid-tile-header,.mf-grid-list__tile .mat-grid-tile-header{background:linear-gradient(to top,#0f172aa3,#0f172a00)!important;padding:var(--mf-space-3) var(--mf-space-4)!important}.mf-grid-list__tile-title{font-family:var(--mf-font-base);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-bold);color:var(--mf-color-neutral-0);display:block}.mf-grid-list__tile-subtitle{font-family:var(--mf-font-base);font-size:var(--mf-text-xs);font-weight:var(--mf-weight-regular);color:var(--mf-color-neutral-200);display:block}\n"], dependencies: [{ kind: "ngmodule", type: MatGridListModule }, { kind: "component", type: i1$a.MatGridList, selector: "mat-grid-list", inputs: ["cols", "gutterSize", "rowHeight"], exportAs: ["matGridList"] }, { kind: "component", type: i1$a.MatGridTile, selector: "mat-grid-tile", inputs: ["rowspan", "colspan"], exportAs: ["matGridTile"] }, { kind: "component", type: i1$a.MatGridTileText, selector: "mat-grid-tile-header, mat-grid-tile-footer" }, { kind: "directive", type: i1$a.MatGridTileHeaderCssMatStyler, selector: "mat-grid-tile-header" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1869
+ }
1870
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfGridListComponent, decorators: [{
1871
+ type: Component,
1872
+ args: [{ selector: 'mf-grid-list', imports: [MatGridListModule], template: `
1873
+ <mat-grid-list
1874
+ class="mf-grid-list"
1875
+ [cols]="cols()"
1876
+ [rowHeight]="rowHeight()"
1877
+ [gutterSize]="gutterSize()"
1878
+ >
1879
+ @for (tile of tiles(); track $index) {
1880
+ <mat-grid-tile
1881
+ class="mf-grid-list__tile"
1882
+ [colspan]="tile.colspan ?? 1"
1883
+ [rowspan]="tile.rowspan ?? 1"
1884
+ [style.background]="tile.background || null"
1885
+ >
1886
+ <mat-grid-tile-header>
1887
+ @if (tile.title) {
1888
+ <span class="mf-grid-list__tile-title">{{ tile.title }}</span>
1889
+ }
1890
+ @if (tile.subtitle) {
1891
+ <span class="mf-grid-list__tile-subtitle">{{ tile.subtitle }}</span>
1892
+ }
1893
+ </mat-grid-tile-header>
1894
+ </mat-grid-tile>
1895
+ }
1896
+ <ng-content />
1897
+ </mat-grid-list>
1898
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.mf-grid-list{font-family:var(--mf-font-base)!important}.mf-grid-list__tile{background-color:var(--mf-color-surface-raised);border-radius:var(--mf-radius-md)!important;overflow:hidden;transition:box-shadow var(--mf-duration-base) var(--mf-ease-standard)}.mf-grid-list__tile:hover{box-shadow:var(--mf-shadow-md)}.mf-grid-list__tile mat-grid-tile-header,.mf-grid-list__tile .mat-grid-tile-header{background:linear-gradient(to top,#0f172aa3,#0f172a00)!important;padding:var(--mf-space-3) var(--mf-space-4)!important}.mf-grid-list__tile-title{font-family:var(--mf-font-base);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-bold);color:var(--mf-color-neutral-0);display:block}.mf-grid-list__tile-subtitle{font-family:var(--mf-font-base);font-size:var(--mf-text-xs);font-weight:var(--mf-weight-regular);color:var(--mf-color-neutral-200);display:block}\n"] }]
1899
+ }], propDecorators: { cols: [{ type: i0.Input, args: [{ isSignal: true, alias: "cols", required: false }] }], rowHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowHeight", required: false }] }], gutterSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "gutterSize", required: false }] }], tiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "tiles", required: false }] }] } });
1900
+
1901
+ /**
1902
+ * Icono de la librería ng-comps.
1903
+ * Envuelve Angular Material `mat-icon` y expone una API uniforme
1904
+ * con tamaños y colores de marca.
1905
+ */
1906
+ class MfIconComponent {
1907
+ /** Nombre del icono de Material Symbols / Material Icons */
1908
+ name = input.required(...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
1909
+ /** Tamaño visual del icono */
1910
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
1911
+ /** Color semántico del icono */
1912
+ color = input('default', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
1913
+ /** Etiqueta accesible. Si se omite, el icono será decorativo (aria-hidden) */
1914
+ label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
1915
+ ariaHidden = computed(() => (this.label() ? 'false' : 'true'), ...(ngDevMode ? [{ debugName: "ariaHidden" }] : /* istanbul ignore next */ []));
1916
+ hostClasses = computed(() => {
1917
+ return ['mf-icon', `mf-icon--${this.size()}`, `mf-icon--${this.color()}`].join(' ');
1918
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
1919
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1920
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: MfIconComponent, isStandalone: true, selector: "mf-icon", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
1921
+ <mat-icon [class]="hostClasses()" [attr.aria-hidden]="ariaHidden()" [attr.aria-label]="label()">{{ name() }}</mat-icon>
1922
+ `, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center}.mf-icon{transition:color var(--mf-duration-base) var(--mf-ease-standard)}.mf-icon--sm{font-size:16px!important;width:16px!important;height:16px!important}.mf-icon--md{font-size:20px!important;width:20px!important;height:20px!important}.mf-icon--lg{font-size:24px!important;width:24px!important;height:24px!important}.mf-icon--xl{font-size:32px!important;width:32px!important;height:32px!important}.mf-icon--default{color:var(--mf-color-on-surface)}.mf-icon--brand{color:var(--mf-color-brand)}.mf-icon--muted{color:var(--mf-color-neutral-400)}.mf-icon--error{color:var(--mf-color-error-500)}.mf-icon--inherit{color:inherit}\n"], dependencies: [{ kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1923
+ }
1924
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfIconComponent, decorators: [{
1925
+ type: Component,
1926
+ args: [{ selector: 'mf-icon', imports: [MatIconModule], template: `
1927
+ <mat-icon [class]="hostClasses()" [attr.aria-hidden]="ariaHidden()" [attr.aria-label]="label()">{{ name() }}</mat-icon>
1928
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-flex;align-items:center;justify-content:center}.mf-icon{transition:color var(--mf-duration-base) var(--mf-ease-standard)}.mf-icon--sm{font-size:16px!important;width:16px!important;height:16px!important}.mf-icon--md{font-size:20px!important;width:20px!important;height:20px!important}.mf-icon--lg{font-size:24px!important;width:24px!important;height:24px!important}.mf-icon--xl{font-size:32px!important;width:32px!important;height:32px!important}.mf-icon--default{color:var(--mf-color-on-surface)}.mf-icon--brand{color:var(--mf-color-brand)}.mf-icon--muted{color:var(--mf-color-neutral-400)}.mf-icon--error{color:var(--mf-color-error-500)}.mf-icon--inherit{color:inherit}\n"] }]
1929
+ }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
1930
+
1931
+ /**
1932
+ * Campo de texto de la librería ng-comps.
1933
+ * Envuelve Angular Material `mat-form-field` + `matInput`
1934
+ * y expone una API uniforme con look and feel de marca.
1935
+ */
1936
+ class MfInputComponent {
1937
+ cdr = inject(ChangeDetectorRef);
1938
+ ngControl = inject(NgControl, { self: true, optional: true });
1939
+ generatedId = createUniqueId('mf-input');
1940
+ disabledFromForm = signal(false, ...(ngDevMode ? [{ debugName: "disabledFromForm" }] : /* istanbul ignore next */ []));
1941
+ internalValue = signal('', ...(ngDevMode ? [{ debugName: "internalValue" }] : /* istanbul ignore next */ []));
1942
+ onControlChange = () => undefined;
1943
+ onControlTouched = () => undefined;
1944
+ errorStateMatcher = {
1945
+ isErrorState: (control) => Boolean(this.error() || (control?.invalid && (control.touched || control.dirty))),
1946
+ };
1947
+ /** ID del control */
1948
+ id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
1949
+ /** Etiqueta flotante del campo */
1950
+ label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
1951
+ /** Etiqueta accesible alternativa cuando no existe label visible */
1952
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
1953
+ /** Referencia externa a elementos que etiquetan el control */
1954
+ ariaLabelledby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : /* istanbul ignore next */ []));
1955
+ /** Referencia externa a elementos descriptivos adicionales */
1956
+ ariaDescribedby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaDescribedby" }] : /* istanbul ignore next */ []));
1957
+ /** Placeholder del input */
1958
+ placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
1959
+ /** Tipo de input HTML */
1960
+ type = input('text', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
1961
+ /** Tamaño del campo */
1962
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
1963
+ /** Valor actual del campo */
1964
+ value = input('', ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
1965
+ /** Deshabilitado */
1966
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
1967
+ /** Solo lectura */
1968
+ readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
1969
+ /** Requerido */
1970
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
1971
+ /** Texto de ayuda debajo del campo */
1972
+ hint = input(undefined, ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
1973
+ /** Mensaje de error */
1974
+ error = input(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
1975
+ /** Icono al inicio */
1976
+ leadingIcon = input(undefined, ...(ngDevMode ? [{ debugName: "leadingIcon" }] : /* istanbul ignore next */ []));
1977
+ /** Icono al final */
1978
+ trailingIcon = input(undefined, ...(ngDevMode ? [{ debugName: "trailingIcon" }] : /* istanbul ignore next */ []));
1979
+ /** Ancho completo */
1980
+ fullWidth = input(false, ...(ngDevMode ? [{ debugName: "fullWidth" }] : /* istanbul ignore next */ []));
1981
+ mfInput = output();
1982
+ mfBlur = output();
1983
+ constructor() {
1984
+ effect(() => {
1985
+ this.internalValue.set(this.value());
1986
+ });
1987
+ effect(() => {
1988
+ if (!hasAccessibleName(this.label(), this.ariaLabel(), this.ariaLabelledby())) {
1989
+ warnInDev('mf-input requiere `label`, `ariaLabel` o `ariaLabelledby` para exponer un nombre accesible.');
1990
+ }
1991
+ });
1992
+ }
1993
+ controlId = computed(() => this.id() ?? this.generatedId, ...(ngDevMode ? [{ debugName: "controlId" }] : /* istanbul ignore next */ []));
1994
+ hintId = computed(() => this.hint() ? `${this.controlId()}-hint` : null, ...(ngDevMode ? [{ debugName: "hintId" }] : /* istanbul ignore next */ []));
1995
+ errorId = computed(() => this.error() ? `${this.controlId()}-error` : null, ...(ngDevMode ? [{ debugName: "errorId" }] : /* istanbul ignore next */ []));
1996
+ describedBy = computed(() => mergeAriaIds(this.ariaDescribedby(), this.hintId(), this.errorId()), ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
1997
+ resolvedAriaLabel = computed(() => this.label() ? null : this.ariaLabel() ?? null, ...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
1998
+ isDisabled = computed(() => this.disabled() || this.disabledFromForm(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
1999
+ hostClasses = computed(() => {
2000
+ const classes = ['mf-input', `mf-input--${this.size()}`];
2001
+ if (this.fullWidth())
2002
+ classes.push('mf-input--full');
2003
+ if (this.error())
2004
+ classes.push('mf-input--error');
2005
+ return classes.join(' ');
2006
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
2007
+ writeValue(value) {
2008
+ this.internalValue.set(value ?? '');
2009
+ this.cdr.markForCheck();
2010
+ }
2011
+ registerOnChange(fn) {
2012
+ this.onControlChange = fn;
2013
+ }
2014
+ registerOnTouched(fn) {
2015
+ this.onControlTouched = fn;
2016
+ }
2017
+ setDisabledState(isDisabled) {
2018
+ this.disabledFromForm.set(isDisabled);
2019
+ this.cdr.markForCheck();
2020
+ }
2021
+ isInvalid() {
2022
+ const control = this.ngControl?.control;
2023
+ return Boolean(this.error() || (control?.invalid && (control.touched || control.dirty)));
2024
+ }
2025
+ onInput(event) {
2026
+ const target = event.target;
2027
+ this.internalValue.set(target.value);
2028
+ this.onControlChange(target.value);
2029
+ this.mfInput.emit(target.value);
2030
+ }
2031
+ onBlur() {
2032
+ this.onControlTouched();
2033
+ this.mfBlur.emit();
2034
+ }
2035
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2036
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfInputComponent, isStandalone: true, selector: "mf-input", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "ariaDescribedby", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, leadingIcon: { classPropertyName: "leadingIcon", publicName: "leadingIcon", isSignal: true, isRequired: false, transformFunction: null }, trailingIcon: { classPropertyName: "trailingIcon", publicName: "trailingIcon", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfInput: "mfInput", mfBlur: "mfBlur" }, providers: [
2037
+ {
2038
+ provide: NG_VALUE_ACCESSOR,
2039
+ useExisting: forwardRef(() => MfInputComponent),
2040
+ multi: true,
2041
+ },
2042
+ ], ngImport: i0, template: `
2043
+ <mat-form-field [appearance]="'outline'" [class]="hostClasses()">
2044
+ @if (label()) {
2045
+ <mat-label>{{ label() }}</mat-label>
2046
+ }
2047
+ @if (leadingIcon()) {
2048
+ <mat-icon matPrefix aria-hidden="true">{{ leadingIcon() }}</mat-icon>
2049
+ }
2050
+ <input
2051
+ matInput
2052
+ [id]="controlId()"
2053
+ [type]="type()"
2054
+ [placeholder]="placeholder()"
2055
+ [disabled]="isDisabled()"
2056
+ [readonly]="readonly()"
2057
+ [required]="required()"
2058
+ [value]="internalValue()"
2059
+ [errorStateMatcher]="errorStateMatcher"
2060
+ [attr.aria-label]="resolvedAriaLabel()"
2061
+ [attr.aria-labelledby]="ariaLabelledby() || null"
2062
+ [attr.aria-describedby]="describedBy()"
2063
+ [attr.aria-invalid]="isInvalid() ? 'true' : null"
2064
+ [attr.aria-required]="required() ? 'true' : null"
2065
+ (input)="onInput($event)"
2066
+ (blur)="onBlur()"
2067
+ />
2068
+ @if (trailingIcon()) {
2069
+ <mat-icon matSuffix aria-hidden="true">{{ trailingIcon() }}</mat-icon>
2070
+ }
2071
+ @if (hint()) {
2072
+ <mat-hint [attr.id]="hintId()">{{ hint() }}</mat-hint>
2073
+ }
2074
+ </mat-form-field>
2075
+ @if (error()) {
2076
+ <p class="mf-input__error" [attr.id]="errorId()" role="alert">{{ error() }}</p>
2077
+ }
2078
+ `, isInline: true, styles: [":host{display:inline-block}.mf-input{font-family:var(--mf-font-base)!important;width:100%}.mf-input--full{width:100%}.mf-input .mat-mdc-text-field-wrapper{border-radius:var(--mf-radius-md)!important}.mf-input .mdc-notched-outline__leading,.mf-input .mdc-notched-outline__notch,.mf-input .mdc-notched-outline__trailing{border-color:var(--mf-color-border)!important;transition:border-color var(--mf-duration-base) var(--mf-ease-standard)}.mf-input .mat-mdc-form-field-focus-overlay{background-color:transparent!important}.mf-input.mat-focused .mdc-notched-outline__leading,.mf-input.mat-focused .mdc-notched-outline__notch,.mf-input.mat-focused .mdc-notched-outline__trailing{border-color:var(--mf-color-brand)!important;border-width:1.5px!important}.mf-input--error .mdc-notched-outline__leading,.mf-input--error .mdc-notched-outline__notch,.mf-input--error .mdc-notched-outline__trailing{border-color:var(--mf-color-error-500)!important}.mf-input .mat-mdc-floating-label{font-family:var(--mf-font-base)!important;font-weight:var(--mf-weight-medium)!important;color:var(--mf-color-neutral-400)!important}.mf-input.mat-focused .mat-mdc-floating-label{color:var(--mf-color-brand)!important}.mf-input .mat-mdc-input-element{font-family:var(--mf-font-base)!important;color:var(--mf-color-on-surface)!important;caret-color:var(--mf-color-brand)}.mf-input .mat-mdc-form-field-hint{font-size:var(--mf-text-xs)!important;color:var(--mf-color-neutral-400)!important}.mf-input .mat-mdc-form-field-error{font-size:var(--mf-text-xs)!important}.mf-input--sm .mat-mdc-input-element{font-size:var(--mf-text-sm)!important}.mf-input--md .mat-mdc-input-element{font-size:var(--mf-text-base)!important}.mf-input--lg .mat-mdc-input-element{font-size:var(--mf-text-lg)!important;padding-top:var(--mf-space-1)!important;padding-bottom:var(--mf-space-1)!important}.mf-input .mat-icon{color:var(--mf-color-neutral-400)!important;font-size:20px;width:20px;height:20px;transition:color var(--mf-duration-base) var(--mf-ease-standard)}.mf-input.mat-focused .mat-icon{color:var(--mf-color-brand)!important}.mf-input .mat-mdc-input-element:disabled{color:var(--mf-color-neutral-300)!important}\n"], dependencies: [{ kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2079
+ }
2080
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfInputComponent, decorators: [{
2081
+ type: Component,
2082
+ args: [{ selector: 'mf-input', imports: [MatFormFieldModule, MatInputModule, MatIconModule], providers: [
2083
+ {
2084
+ provide: NG_VALUE_ACCESSOR,
2085
+ useExisting: forwardRef(() => MfInputComponent),
2086
+ multi: true,
2087
+ },
2088
+ ], template: `
2089
+ <mat-form-field [appearance]="'outline'" [class]="hostClasses()">
2090
+ @if (label()) {
2091
+ <mat-label>{{ label() }}</mat-label>
2092
+ }
2093
+ @if (leadingIcon()) {
2094
+ <mat-icon matPrefix aria-hidden="true">{{ leadingIcon() }}</mat-icon>
2095
+ }
2096
+ <input
2097
+ matInput
2098
+ [id]="controlId()"
2099
+ [type]="type()"
2100
+ [placeholder]="placeholder()"
2101
+ [disabled]="isDisabled()"
2102
+ [readonly]="readonly()"
2103
+ [required]="required()"
2104
+ [value]="internalValue()"
2105
+ [errorStateMatcher]="errorStateMatcher"
2106
+ [attr.aria-label]="resolvedAriaLabel()"
2107
+ [attr.aria-labelledby]="ariaLabelledby() || null"
2108
+ [attr.aria-describedby]="describedBy()"
2109
+ [attr.aria-invalid]="isInvalid() ? 'true' : null"
2110
+ [attr.aria-required]="required() ? 'true' : null"
2111
+ (input)="onInput($event)"
2112
+ (blur)="onBlur()"
2113
+ />
2114
+ @if (trailingIcon()) {
2115
+ <mat-icon matSuffix aria-hidden="true">{{ trailingIcon() }}</mat-icon>
2116
+ }
2117
+ @if (hint()) {
2118
+ <mat-hint [attr.id]="hintId()">{{ hint() }}</mat-hint>
2119
+ }
2120
+ </mat-form-field>
2121
+ @if (error()) {
2122
+ <p class="mf-input__error" [attr.id]="errorId()" role="alert">{{ error() }}</p>
2123
+ }
2124
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-block}.mf-input{font-family:var(--mf-font-base)!important;width:100%}.mf-input--full{width:100%}.mf-input .mat-mdc-text-field-wrapper{border-radius:var(--mf-radius-md)!important}.mf-input .mdc-notched-outline__leading,.mf-input .mdc-notched-outline__notch,.mf-input .mdc-notched-outline__trailing{border-color:var(--mf-color-border)!important;transition:border-color var(--mf-duration-base) var(--mf-ease-standard)}.mf-input .mat-mdc-form-field-focus-overlay{background-color:transparent!important}.mf-input.mat-focused .mdc-notched-outline__leading,.mf-input.mat-focused .mdc-notched-outline__notch,.mf-input.mat-focused .mdc-notched-outline__trailing{border-color:var(--mf-color-brand)!important;border-width:1.5px!important}.mf-input--error .mdc-notched-outline__leading,.mf-input--error .mdc-notched-outline__notch,.mf-input--error .mdc-notched-outline__trailing{border-color:var(--mf-color-error-500)!important}.mf-input .mat-mdc-floating-label{font-family:var(--mf-font-base)!important;font-weight:var(--mf-weight-medium)!important;color:var(--mf-color-neutral-400)!important}.mf-input.mat-focused .mat-mdc-floating-label{color:var(--mf-color-brand)!important}.mf-input .mat-mdc-input-element{font-family:var(--mf-font-base)!important;color:var(--mf-color-on-surface)!important;caret-color:var(--mf-color-brand)}.mf-input .mat-mdc-form-field-hint{font-size:var(--mf-text-xs)!important;color:var(--mf-color-neutral-400)!important}.mf-input .mat-mdc-form-field-error{font-size:var(--mf-text-xs)!important}.mf-input--sm .mat-mdc-input-element{font-size:var(--mf-text-sm)!important}.mf-input--md .mat-mdc-input-element{font-size:var(--mf-text-base)!important}.mf-input--lg .mat-mdc-input-element{font-size:var(--mf-text-lg)!important;padding-top:var(--mf-space-1)!important;padding-bottom:var(--mf-space-1)!important}.mf-input .mat-icon{color:var(--mf-color-neutral-400)!important;font-size:20px;width:20px;height:20px;transition:color var(--mf-duration-base) var(--mf-ease-standard)}.mf-input.mat-focused .mat-icon{color:var(--mf-color-brand)!important}.mf-input .mat-mdc-input-element:disabled{color:var(--mf-color-neutral-300)!important}\n"] }]
2125
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledby", required: false }] }], ariaDescribedby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedby", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], leadingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "leadingIcon", required: false }] }], trailingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "trailingIcon", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], mfInput: [{ type: i0.Output, args: ["mfInput"] }], mfBlur: [{ type: i0.Output, args: ["mfBlur"] }] } });
2126
+
2127
+ /**
2128
+ * Menu de la librería ng-comps.
2129
+ * Envuelve Angular Material `mat-menu` y expone una API uniforme
2130
+ * con look and feel de marca.
2131
+ */
2132
+ class MfMenuComponent {
2133
+ /** Items del menú */
2134
+ items = input.required(...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
2135
+ /** Icono del trigger */
2136
+ triggerIcon = input('more_vert', ...(ngDevMode ? [{ debugName: "triggerIcon" }] : /* istanbul ignore next */ []));
2137
+ /** Label accesible del trigger */
2138
+ triggerLabel = input('Open menu', ...(ngDevMode ? [{ debugName: "triggerLabel" }] : /* istanbul ignore next */ []));
2139
+ mfItemClick = output();
2140
+ hostClasses = computed(() => 'mf-menu', ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
2141
+ triggerClasses = computed(() => 'mf-menu__trigger', ...(ngDevMode ? [{ debugName: "triggerClasses" }] : /* istanbul ignore next */ []));
2142
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2143
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfMenuComponent, isStandalone: true, selector: "mf-menu", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, triggerIcon: { classPropertyName: "triggerIcon", publicName: "triggerIcon", isSignal: true, isRequired: false, transformFunction: null }, triggerLabel: { classPropertyName: "triggerLabel", publicName: "triggerLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfItemClick: "mfItemClick" }, ngImport: i0, template: `
2144
+ <button
2145
+ mat-icon-button
2146
+ [matMenuTriggerFor]="menu"
2147
+ [class]="triggerClasses()"
2148
+ [attr.aria-label]="triggerLabel()"
2149
+ >
2150
+ <mat-icon>{{ triggerIcon() }}</mat-icon>
2151
+ </button>
2152
+ <mat-menu #menu="matMenu" [class]="hostClasses()">
2153
+ @for (item of items(); track item.value) {
2154
+ <button
2155
+ mat-menu-item
2156
+ [disabled]="item.disabled ?? false"
2157
+ (click)="mfItemClick.emit(item.value)"
2158
+ >
2159
+ @if (item.icon) {
2160
+ <mat-icon aria-hidden="true">{{ item.icon }}</mat-icon>
2161
+ }
2162
+ <span>{{ item.label }}</span>
2163
+ </button>
2164
+ }
2165
+ </mat-menu>
2166
+ `, isInline: true, styles: [":host{display:inline-block}.mf-menu__trigger{color:var(--mf-color-neutral-600)!important}.mf-menu__trigger:hover{color:var(--mf-color-brand)!important}.mf-menu .mat-mdc-menu-panel{border-radius:var(--mf-radius-md)!important;box-shadow:var(--mf-shadow-lg)!important}.mf-menu .mat-mdc-menu-item{font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important;color:var(--mf-color-on-surface)!important}.mf-menu .mat-mdc-menu-item:hover{background-color:var(--mf-color-brand-light)!important}.mf-menu .mat-mdc-menu-item .mat-icon{color:var(--mf-color-neutral-400)!important;margin-right:var(--mf-space-2)!important}\n"], dependencies: [{ kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1$b.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i1$b.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i1$b.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2167
+ }
2168
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfMenuComponent, decorators: [{
2169
+ type: Component,
2170
+ args: [{ selector: 'mf-menu', imports: [MatMenuModule, MatButtonModule, MatIconModule], template: `
2171
+ <button
2172
+ mat-icon-button
2173
+ [matMenuTriggerFor]="menu"
2174
+ [class]="triggerClasses()"
2175
+ [attr.aria-label]="triggerLabel()"
2176
+ >
2177
+ <mat-icon>{{ triggerIcon() }}</mat-icon>
2178
+ </button>
2179
+ <mat-menu #menu="matMenu" [class]="hostClasses()">
2180
+ @for (item of items(); track item.value) {
2181
+ <button
2182
+ mat-menu-item
2183
+ [disabled]="item.disabled ?? false"
2184
+ (click)="mfItemClick.emit(item.value)"
2185
+ >
2186
+ @if (item.icon) {
2187
+ <mat-icon aria-hidden="true">{{ item.icon }}</mat-icon>
2188
+ }
2189
+ <span>{{ item.label }}</span>
2190
+ </button>
2191
+ }
2192
+ </mat-menu>
2193
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-block}.mf-menu__trigger{color:var(--mf-color-neutral-600)!important}.mf-menu__trigger:hover{color:var(--mf-color-brand)!important}.mf-menu .mat-mdc-menu-panel{border-radius:var(--mf-radius-md)!important;box-shadow:var(--mf-shadow-lg)!important}.mf-menu .mat-mdc-menu-item{font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important;color:var(--mf-color-on-surface)!important}.mf-menu .mat-mdc-menu-item:hover{background-color:var(--mf-color-brand-light)!important}.mf-menu .mat-mdc-menu-item .mat-icon{color:var(--mf-color-neutral-400)!important;margin-right:var(--mf-space-2)!important}\n"] }]
2194
+ }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], triggerIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerIcon", required: false }] }], triggerLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerLabel", required: false }] }], mfItemClick: [{ type: i0.Output, args: ["mfItemClick"] }] } });
2195
+
2196
+ /**
2197
+ * Paginator de la librería ng-comps.
2198
+ * Envuelve Angular Material `mat-paginator` y expone una API uniforme
2199
+ * con look and feel de marca.
2200
+ */
2201
+ class MfPaginatorComponent {
2202
+ /** Total de elementos */
2203
+ length = input.required(...(ngDevMode ? [{ debugName: "length" }] : /* istanbul ignore next */ []));
2204
+ /** Tamaño de página */
2205
+ pageSize = input(10, ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
2206
+ /** Índice de página actual */
2207
+ pageIndex = input(0, ...(ngDevMode ? [{ debugName: "pageIndex" }] : /* istanbul ignore next */ []));
2208
+ /** Opciones de tamaño de página */
2209
+ pageSizeOptions = input([5, 10, 25, 50], ...(ngDevMode ? [{ debugName: "pageSizeOptions" }] : /* istanbul ignore next */ []));
2210
+ /** Mostrar botones de primera/última página */
2211
+ showFirstLastButtons = input(true, ...(ngDevMode ? [{ debugName: "showFirstLastButtons" }] : /* istanbul ignore next */ []));
2212
+ /** Ocultar selector de tamaño de página */
2213
+ hidePageSize = input(false, ...(ngDevMode ? [{ debugName: "hidePageSize" }] : /* istanbul ignore next */ []));
2214
+ mfPageChange = output();
2215
+ hostClasses = computed(() => {
2216
+ return 'mf-paginator';
2217
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
2218
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfPaginatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2219
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: MfPaginatorComponent, isStandalone: true, selector: "mf-paginator", inputs: { length: { classPropertyName: "length", publicName: "length", isSignal: true, isRequired: true, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageIndex: { classPropertyName: "pageIndex", publicName: "pageIndex", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, showFirstLastButtons: { classPropertyName: "showFirstLastButtons", publicName: "showFirstLastButtons", isSignal: true, isRequired: false, transformFunction: null }, hidePageSize: { classPropertyName: "hidePageSize", publicName: "hidePageSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfPageChange: "mfPageChange" }, ngImport: i0, template: `
2220
+ <mat-paginator
2221
+ [length]="length()"
2222
+ [pageSize]="pageSize()"
2223
+ [pageIndex]="pageIndex()"
2224
+ [pageSizeOptions]="pageSizeOptions()"
2225
+ [showFirstLastButtons]="showFirstLastButtons()"
2226
+ [hidePageSize]="hidePageSize()"
2227
+ [class]="hostClasses()"
2228
+ (page)="mfPageChange.emit($event)"
2229
+ />
2230
+ `, isInline: true, styles: [":host{display:block}.mf-paginator.mat-mdc-paginator{font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important;background-color:transparent!important}.mf-paginator .mat-mdc-paginator-container{padding:var(--mf-space-2) 0!important}.mf-paginator .mat-mdc-paginator-range-label{color:var(--mf-color-neutral-600)!important;font-family:var(--mf-font-base)!important}.mf-paginator .mat-mdc-paginator-navigation-previous,.mf-paginator .mat-mdc-paginator-navigation-next,.mf-paginator .mat-mdc-paginator-navigation-first,.mf-paginator .mat-mdc-paginator-navigation-last{color:var(--mf-color-brand)!important}.mf-paginator .mat-mdc-paginator-navigation-previous:disabled,.mf-paginator .mat-mdc-paginator-navigation-next:disabled,.mf-paginator .mat-mdc-paginator-navigation-first:disabled,.mf-paginator .mat-mdc-paginator-navigation-last:disabled{color:var(--mf-color-neutral-300)!important}\n"], dependencies: [{ kind: "ngmodule", type: MatPaginatorModule }, { kind: "component", type: i1$c.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2231
+ }
2232
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfPaginatorComponent, decorators: [{
2233
+ type: Component,
2234
+ args: [{ selector: 'mf-paginator', imports: [MatPaginatorModule], template: `
2235
+ <mat-paginator
2236
+ [length]="length()"
2237
+ [pageSize]="pageSize()"
2238
+ [pageIndex]="pageIndex()"
2239
+ [pageSizeOptions]="pageSizeOptions()"
2240
+ [showFirstLastButtons]="showFirstLastButtons()"
2241
+ [hidePageSize]="hidePageSize()"
2242
+ [class]="hostClasses()"
2243
+ (page)="mfPageChange.emit($event)"
2244
+ />
2245
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.mf-paginator.mat-mdc-paginator{font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important;background-color:transparent!important}.mf-paginator .mat-mdc-paginator-container{padding:var(--mf-space-2) 0!important}.mf-paginator .mat-mdc-paginator-range-label{color:var(--mf-color-neutral-600)!important;font-family:var(--mf-font-base)!important}.mf-paginator .mat-mdc-paginator-navigation-previous,.mf-paginator .mat-mdc-paginator-navigation-next,.mf-paginator .mat-mdc-paginator-navigation-first,.mf-paginator .mat-mdc-paginator-navigation-last{color:var(--mf-color-brand)!important}.mf-paginator .mat-mdc-paginator-navigation-previous:disabled,.mf-paginator .mat-mdc-paginator-navigation-next:disabled,.mf-paginator .mat-mdc-paginator-navigation-first:disabled,.mf-paginator .mat-mdc-paginator-navigation-last:disabled{color:var(--mf-color-neutral-300)!important}\n"] }]
2246
+ }], propDecorators: { length: [{ type: i0.Input, args: [{ isSignal: true, alias: "length", required: true }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], pageIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageIndex", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], showFirstLastButtons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFirstLastButtons", required: false }] }], hidePageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidePageSize", required: false }] }], mfPageChange: [{ type: i0.Output, args: ["mfPageChange"] }] } });
2247
+
2248
+ /**
2249
+ * Barra de progreso de la librería ng-comps.
2250
+ * Envuelve Angular Material `mat-progress-bar` y expone una API uniforme
2251
+ * con look and feel de marca.
2252
+ */
2253
+ class MfProgressBarComponent {
2254
+ /** Modo de la barra de progreso */
2255
+ mode = input('determinate', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
2256
+ /** Valor actual (0–100) */
2257
+ value = input(0, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
2258
+ /** Valor del buffer (0–100, solo en modo buffer) */
2259
+ bufferValue = input(0, ...(ngDevMode ? [{ debugName: "bufferValue" }] : /* istanbul ignore next */ []));
2260
+ /** Color de la barra */
2261
+ color = input('brand', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
2262
+ /** Etiqueta accesible */
2263
+ label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
2264
+ /** Texto accesible opcional para lectores de pantalla */
2265
+ valueText = input(undefined, ...(ngDevMode ? [{ debugName: "valueText" }] : /* istanbul ignore next */ []));
2266
+ /** Muestra el porcentaje junto a la barra */
2267
+ showValue = input(false, ...(ngDevMode ? [{ debugName: "showValue" }] : /* istanbul ignore next */ []));
2268
+ /** Altura de la barra en px */
2269
+ height = input(4, ...(ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []));
2270
+ constructor() {
2271
+ effect(() => {
2272
+ if (!hasAccessibleName(this.label())) {
2273
+ warnInDev('mf-progress-bar debería incluir `label` para anunciar el progreso de forma accesible.');
2274
+ }
2275
+ });
2276
+ }
2277
+ showsNumericValue = computed(() => this.mode() === 'determinate', ...(ngDevMode ? [{ debugName: "showsNumericValue" }] : /* istanbul ignore next */ []));
2278
+ hostClasses = computed(() => {
2279
+ return `mf-progress-bar mf-progress-bar--${this.color()}`;
2280
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
2281
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfProgressBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2282
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfProgressBarComponent, isStandalone: true, selector: "mf-progress-bar", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, bufferValue: { classPropertyName: "bufferValue", publicName: "bufferValue", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, valueText: { classPropertyName: "valueText", publicName: "valueText", isSignal: true, isRequired: false, transformFunction: null }, showValue: { classPropertyName: "showValue", publicName: "showValue", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
2283
+ <div class="mf-progress-bar__wrapper">
2284
+ @if (label()) {
2285
+ <span class="mf-progress-bar__label">{{ label() }}</span>
2286
+ }
2287
+ <mat-progress-bar
2288
+ [class]="hostClasses()"
2289
+ [mode]="mode()"
2290
+ [value]="value()"
2291
+ [bufferValue]="bufferValue()"
2292
+ [attr.aria-label]="label() || null"
2293
+ [attr.aria-valuetext]="valueText() || null"
2294
+ [attr.aria-valuenow]="showsNumericValue() ? value() : null"
2295
+ aria-valuemin="0"
2296
+ aria-valuemax="100"
2297
+ />
2298
+ @if (showValue() && mode() === 'determinate') {
2299
+ <span class="mf-progress-bar__value" aria-hidden="true">{{ value() }}%</span>
2300
+ }
2301
+ </div>
2302
+ `, isInline: true, styles: [":host{display:block}.mf-progress-bar__wrapper{display:flex;flex-direction:column;gap:var(--mf-space-2)}.mf-progress-bar__label{font-family:var(--mf-font-base);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-medium);color:var(--mf-color-on-surface)}.mf-progress-bar__value{font-family:var(--mf-font-base);font-size:var(--mf-text-xs);font-weight:var(--mf-weight-medium);color:var(--mf-color-neutral-600);align-self:flex-end}.mf-progress-bar{border-radius:var(--mf-radius-full)!important;overflow:hidden}.mf-progress-bar.mat-mdc-progress-bar{--mdc-linear-progress-track-shape: 9999px}.mf-progress-bar--brand.mat-mdc-progress-bar{--mdc-linear-progress-active-indicator-color: var(--mf-color-brand) !important;--mdc-linear-progress-track-color: var(--mf-color-primary-100) !important}.mf-progress-bar--accent.mat-mdc-progress-bar{--mdc-linear-progress-active-indicator-color: var(--mf-color-accent-500) !important;--mdc-linear-progress-track-color: var(--mf-color-accent-300) !important}.mf-progress-bar--warn.mat-mdc-progress-bar{--mdc-linear-progress-active-indicator-color: var(--mf-color-error-500) !important;--mdc-linear-progress-track-color: #fecaca !important}\n"], dependencies: [{ kind: "ngmodule", type: MatProgressBarModule }, { kind: "component", type: i1$d.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2303
+ }
2304
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfProgressBarComponent, decorators: [{
2305
+ type: Component,
2306
+ args: [{ selector: 'mf-progress-bar', imports: [MatProgressBarModule], template: `
2307
+ <div class="mf-progress-bar__wrapper">
2308
+ @if (label()) {
2309
+ <span class="mf-progress-bar__label">{{ label() }}</span>
2310
+ }
2311
+ <mat-progress-bar
2312
+ [class]="hostClasses()"
2313
+ [mode]="mode()"
2314
+ [value]="value()"
2315
+ [bufferValue]="bufferValue()"
2316
+ [attr.aria-label]="label() || null"
2317
+ [attr.aria-valuetext]="valueText() || null"
2318
+ [attr.aria-valuenow]="showsNumericValue() ? value() : null"
2319
+ aria-valuemin="0"
2320
+ aria-valuemax="100"
2321
+ />
2322
+ @if (showValue() && mode() === 'determinate') {
2323
+ <span class="mf-progress-bar__value" aria-hidden="true">{{ value() }}%</span>
2324
+ }
2325
+ </div>
2326
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.mf-progress-bar__wrapper{display:flex;flex-direction:column;gap:var(--mf-space-2)}.mf-progress-bar__label{font-family:var(--mf-font-base);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-medium);color:var(--mf-color-on-surface)}.mf-progress-bar__value{font-family:var(--mf-font-base);font-size:var(--mf-text-xs);font-weight:var(--mf-weight-medium);color:var(--mf-color-neutral-600);align-self:flex-end}.mf-progress-bar{border-radius:var(--mf-radius-full)!important;overflow:hidden}.mf-progress-bar.mat-mdc-progress-bar{--mdc-linear-progress-track-shape: 9999px}.mf-progress-bar--brand.mat-mdc-progress-bar{--mdc-linear-progress-active-indicator-color: var(--mf-color-brand) !important;--mdc-linear-progress-track-color: var(--mf-color-primary-100) !important}.mf-progress-bar--accent.mat-mdc-progress-bar{--mdc-linear-progress-active-indicator-color: var(--mf-color-accent-500) !important;--mdc-linear-progress-track-color: var(--mf-color-accent-300) !important}.mf-progress-bar--warn.mat-mdc-progress-bar{--mdc-linear-progress-active-indicator-color: var(--mf-color-error-500) !important;--mdc-linear-progress-track-color: #fecaca !important}\n"] }]
2327
+ }], ctorParameters: () => [], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], bufferValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "bufferValue", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], valueText: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueText", required: false }] }], showValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValue", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }] } });
2328
+
2329
+ /**
2330
+ * Spinner de progreso de la librería ng-comps.
2331
+ * Envuelve Angular Material `mat-progress-spinner` y expone una API uniforme
2332
+ * con look and feel de marca.
2333
+ */
2334
+ class MfProgressSpinnerComponent {
2335
+ /** Modo del spinner */
2336
+ mode = input('indeterminate', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
2337
+ /** Valor actual (0–100, solo en modo determinate) */
2338
+ value = input(0, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
2339
+ /** Diámetro en px */
2340
+ diameter = input(40, ...(ngDevMode ? [{ debugName: "diameter" }] : /* istanbul ignore next */ []));
2341
+ /** Grosor del trazo en px */
2342
+ strokeWidth = input(4, ...(ngDevMode ? [{ debugName: "strokeWidth" }] : /* istanbul ignore next */ []));
2343
+ /** Color del spinner */
2344
+ color = input('brand', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
2345
+ /** Etiqueta accesible y visible */
2346
+ label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
2347
+ /** Texto accesible opcional para lectores de pantalla */
2348
+ valueText = input(undefined, ...(ngDevMode ? [{ debugName: "valueText" }] : /* istanbul ignore next */ []));
2349
+ constructor() {
2350
+ effect(() => {
2351
+ if (!hasAccessibleName(this.label())) {
2352
+ warnInDev('mf-progress-spinner debería incluir `label` para anunciar el estado de carga de forma accesible.');
2353
+ }
2354
+ });
2355
+ }
2356
+ showsNumericValue = computed(() => this.mode() === 'determinate', ...(ngDevMode ? [{ debugName: "showsNumericValue" }] : /* istanbul ignore next */ []));
2357
+ hostClasses = computed(() => {
2358
+ return `mf-progress-spinner mf-progress-spinner--${this.color()}`;
2359
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
2360
+ wrapperClasses = computed(() => {
2361
+ const classes = ['mf-progress-spinner__wrapper'];
2362
+ if (this.label())
2363
+ classes.push('mf-progress-spinner__wrapper--labeled');
2364
+ return classes.join(' ');
2365
+ }, ...(ngDevMode ? [{ debugName: "wrapperClasses" }] : /* istanbul ignore next */ []));
2366
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfProgressSpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2367
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfProgressSpinnerComponent, isStandalone: true, selector: "mf-progress-spinner", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, diameter: { classPropertyName: "diameter", publicName: "diameter", isSignal: true, isRequired: false, transformFunction: null }, strokeWidth: { classPropertyName: "strokeWidth", publicName: "strokeWidth", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, valueText: { classPropertyName: "valueText", publicName: "valueText", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
2368
+ <div [class]="wrapperClasses()">
2369
+ <mat-progress-spinner
2370
+ [class]="hostClasses()"
2371
+ [mode]="mode()"
2372
+ [value]="value()"
2373
+ [diameter]="diameter()"
2374
+ [strokeWidth]="strokeWidth()"
2375
+ [attr.aria-label]="label() || null"
2376
+ [attr.aria-valuetext]="valueText() || null"
2377
+ [attr.aria-valuenow]="showsNumericValue() ? value() : null"
2378
+ aria-valuemin="0"
2379
+ aria-valuemax="100"
2380
+ />
2381
+ @if (label()) {
2382
+ <span class="mf-progress-spinner__label">{{ label() }}</span>
2383
+ }
2384
+ </div>
2385
+ `, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center}.mf-progress-spinner__wrapper{display:inline-flex;align-items:center;gap:var(--mf-space-3)}.mf-progress-spinner__wrapper--labeled{flex-direction:row}.mf-progress-spinner__label{font-family:var(--mf-font-base);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-medium);color:var(--mf-color-on-surface)}.mf-progress-spinner--brand.mat-mdc-progress-spinner{--mdc-circular-progress-active-indicator-color: var(--mf-color-brand) !important}.mf-progress-spinner--accent.mat-mdc-progress-spinner{--mdc-circular-progress-active-indicator-color: var(--mf-color-accent-500) !important}.mf-progress-spinner--warn.mat-mdc-progress-spinner{--mdc-circular-progress-active-indicator-color: var(--mf-color-error-500) !important}\n"], dependencies: [{ kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i1$e.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2386
+ }
2387
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfProgressSpinnerComponent, decorators: [{
2388
+ type: Component,
2389
+ args: [{ selector: 'mf-progress-spinner', imports: [MatProgressSpinnerModule], template: `
2390
+ <div [class]="wrapperClasses()">
2391
+ <mat-progress-spinner
2392
+ [class]="hostClasses()"
2393
+ [mode]="mode()"
2394
+ [value]="value()"
2395
+ [diameter]="diameter()"
2396
+ [strokeWidth]="strokeWidth()"
2397
+ [attr.aria-label]="label() || null"
2398
+ [attr.aria-valuetext]="valueText() || null"
2399
+ [attr.aria-valuenow]="showsNumericValue() ? value() : null"
2400
+ aria-valuemin="0"
2401
+ aria-valuemax="100"
2402
+ />
2403
+ @if (label()) {
2404
+ <span class="mf-progress-spinner__label">{{ label() }}</span>
2405
+ }
2406
+ </div>
2407
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-flex;align-items:center;justify-content:center}.mf-progress-spinner__wrapper{display:inline-flex;align-items:center;gap:var(--mf-space-3)}.mf-progress-spinner__wrapper--labeled{flex-direction:row}.mf-progress-spinner__label{font-family:var(--mf-font-base);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-medium);color:var(--mf-color-on-surface)}.mf-progress-spinner--brand.mat-mdc-progress-spinner{--mdc-circular-progress-active-indicator-color: var(--mf-color-brand) !important}.mf-progress-spinner--accent.mat-mdc-progress-spinner{--mdc-circular-progress-active-indicator-color: var(--mf-color-accent-500) !important}.mf-progress-spinner--warn.mat-mdc-progress-spinner{--mdc-circular-progress-active-indicator-color: var(--mf-color-error-500) !important}\n"] }]
2408
+ }], ctorParameters: () => [], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], diameter: [{ type: i0.Input, args: [{ isSignal: true, alias: "diameter", required: false }] }], strokeWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "strokeWidth", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], valueText: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueText", required: false }] }] } });
2409
+
2410
+ /**
2411
+ * Grupo de radio buttons de la librería ng-comps.
2412
+ * Envuelve Angular Material `mat-radio-group` + `mat-radio-button`
2413
+ * y expone una API uniforme con look and feel de marca.
2414
+ */
2415
+ class MfRadioButtonComponent {
2416
+ cdr = inject(ChangeDetectorRef);
2417
+ ngControl = inject(NgControl, { self: true, optional: true });
2418
+ generatedId = createUniqueId('mf-radio');
2419
+ disabledFromForm = signal(false, ...(ngDevMode ? [{ debugName: "disabledFromForm" }] : /* istanbul ignore next */ []));
2420
+ internalValue = signal(undefined, ...(ngDevMode ? [{ debugName: "internalValue" }] : /* istanbul ignore next */ []));
2421
+ onControlChange = () => undefined;
2422
+ onControlTouched = () => undefined;
2423
+ /** Opciones del grupo */
2424
+ options = input.required(...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
2425
+ /** ID del control */
2426
+ id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
2427
+ /** Etiqueta visible del grupo */
2428
+ label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
2429
+ /** Valor seleccionado */
2430
+ value = input(undefined, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
2431
+ /** Deshabilitado */
2432
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
2433
+ /** Requerido */
2434
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
2435
+ /** Dirección del grupo */
2436
+ direction = input('vertical', ...(ngDevMode ? [{ debugName: "direction" }] : /* istanbul ignore next */ []));
2437
+ /** Nombre accesible alternativo del grupo */
2438
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
2439
+ /** Etiqueta accesible para el grupo */
2440
+ ariaLabelledby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : /* istanbul ignore next */ []));
2441
+ /** Referencia externa a elementos descriptivos adicionales */
2442
+ ariaDescribedby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaDescribedby" }] : /* istanbul ignore next */ []));
2443
+ /** Texto de ayuda */
2444
+ hint = input(undefined, ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
2445
+ /** Mensaje de error */
2446
+ error = input(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
2447
+ /** Name del grupo */
2448
+ name = input(undefined, ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
2449
+ mfChange = output();
2450
+ constructor() {
2451
+ effect(() => {
2452
+ this.internalValue.set(this.value());
2453
+ });
2454
+ effect(() => {
2455
+ if (!hasAccessibleName(this.label(), this.ariaLabel(), this.ariaLabelledby())) {
2456
+ warnInDev('mf-radio-button requiere `label`, `ariaLabel` o `ariaLabelledby` para exponer un nombre accesible.');
2457
+ }
2458
+ });
2459
+ }
2460
+ controlId = computed(() => this.id() ?? this.generatedId, ...(ngDevMode ? [{ debugName: "controlId" }] : /* istanbul ignore next */ []));
2461
+ legendId = computed(() => `${this.controlId()}-legend`, ...(ngDevMode ? [{ debugName: "legendId" }] : /* istanbul ignore next */ []));
2462
+ hintId = computed(() => this.hint() ? `${this.controlId()}-hint` : null, ...(ngDevMode ? [{ debugName: "hintId" }] : /* istanbul ignore next */ []));
2463
+ errorId = computed(() => this.error() ? `${this.controlId()}-error` : null, ...(ngDevMode ? [{ debugName: "errorId" }] : /* istanbul ignore next */ []));
2464
+ computedLabelledby = computed(() => mergeAriaIds(this.ariaLabelledby(), this.label() ? this.legendId() : null), ...(ngDevMode ? [{ debugName: "computedLabelledby" }] : /* istanbul ignore next */ []));
2465
+ describedBy = computed(() => mergeAriaIds(this.ariaDescribedby(), this.hintId(), this.errorId()), ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
2466
+ groupName = computed(() => this.name() ?? this.controlId(), ...(ngDevMode ? [{ debugName: "groupName" }] : /* istanbul ignore next */ []));
2467
+ resolvedAriaLabel = computed(() => this.label() ? null : this.ariaLabel() ?? null, ...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
2468
+ isDisabled = computed(() => this.disabled() || this.disabledFromForm(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
2469
+ hostClasses = computed(() => {
2470
+ return `mf-radio mf-radio--${this.direction()}`;
2471
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
2472
+ writeValue(value) {
2473
+ this.internalValue.set(value ?? undefined);
2474
+ this.cdr.markForCheck();
2475
+ }
2476
+ registerOnChange(fn) {
2477
+ this.onControlChange = fn;
2478
+ }
2479
+ registerOnTouched(fn) {
2480
+ this.onControlTouched = fn;
2481
+ }
2482
+ setDisabledState(isDisabled) {
2483
+ this.disabledFromForm.set(isDisabled);
2484
+ this.cdr.markForCheck();
2485
+ }
2486
+ isInvalid() {
2487
+ const control = this.ngControl?.control;
2488
+ return Boolean(this.error() || (control?.invalid && (control.touched || control.dirty)));
2489
+ }
2490
+ onChange(event) {
2491
+ this.internalValue.set(event.value);
2492
+ this.onControlChange(event.value);
2493
+ this.onControlTouched();
2494
+ this.mfChange.emit(event.value);
2495
+ }
2496
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfRadioButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2497
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfRadioButtonComponent, isStandalone: true, selector: "mf-radio-button", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "ariaDescribedby", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfChange: "mfChange" }, providers: [
2498
+ {
2499
+ provide: NG_VALUE_ACCESSOR,
2500
+ useExisting: forwardRef(() => MfRadioButtonComponent),
2501
+ multi: true,
2502
+ },
2503
+ ], ngImport: i0, template: `
2504
+ <fieldset class="mf-radio__fieldset">
2505
+ @if (label()) {
2506
+ <legend class="mf-radio__legend" [id]="legendId()">
2507
+ {{ label() }}
2508
+ @if (required()) {
2509
+ <span aria-hidden="true"> *</span>
2510
+ }
2511
+ </legend>
2512
+ }
2513
+
2514
+ <mat-radio-group
2515
+ [class]="hostClasses()"
2516
+ [disabled]="isDisabled()"
2517
+ [name]="groupName()"
2518
+ [required]="required()"
2519
+ [value]="internalValue()"
2520
+ [attr.aria-label]="resolvedAriaLabel()"
2521
+ [attr.aria-labelledby]="computedLabelledby()"
2522
+ [attr.aria-describedby]="describedBy()"
2523
+ [attr.aria-invalid]="isInvalid() ? 'true' : null"
2524
+ [attr.aria-required]="required() ? 'true' : null"
2525
+ (change)="onChange($event)"
2526
+ >
2527
+ @for (option of options(); track option.value) {
2528
+ <mat-radio-button
2529
+ class="mf-radio__option"
2530
+ [value]="option.value"
2531
+ [disabled]="option.disabled ?? false"
2532
+ >
2533
+ {{ option.label }}
2534
+ </mat-radio-button>
2535
+ }
2536
+ </mat-radio-group>
2537
+
2538
+ @if (hint()) {
2539
+ <p class="mf-radio__hint" [attr.id]="hintId()">{{ hint() }}</p>
2540
+ }
2541
+
2542
+ @if (error()) {
2543
+ <p class="mf-radio__error" [attr.id]="errorId()" role="alert">
2544
+ {{ error() }}
2545
+ </p>
2546
+ }
2547
+ </fieldset>
2548
+ `, isInline: true, styles: [":host{display:block}.mf-radio__fieldset{margin:0;padding:0;border:0}.mf-radio__legend{margin-bottom:var(--mf-space-2);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-medium);color:var(--mf-color-on-surface)}.mf-radio{display:flex}.mf-radio--vertical{flex-direction:column;gap:var(--mf-space-2)}.mf-radio--horizontal{flex-direction:row;flex-wrap:wrap;gap:var(--mf-space-4)}.mf-radio__option{font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important;color:var(--mf-color-on-surface)!important}.mf-radio__option .mdc-radio .mdc-radio__outer-circle{border-color:var(--mf-color-border)!important;transition:border-color var(--mf-duration-base) var(--mf-ease-standard)}.mf-radio__option.mat-mdc-radio-checked .mdc-radio .mdc-radio__outer-circle,.mf-radio__option.mat-mdc-radio-checked .mdc-radio .mdc-radio__inner-circle{border-color:var(--mf-color-brand)!important}.mf-radio__option .mat-ripple-element{background-color:var(--mf-color-brand-light)!important}.mf-radio__option .mdc-label{font-family:var(--mf-font-base)!important;color:var(--mf-color-on-surface)!important;cursor:pointer}.mf-radio__option.mat-mdc-radio-disabled .mdc-label{color:var(--mf-color-neutral-400)!important;cursor:default}.mf-radio__hint,.mf-radio__error{margin:var(--mf-space-2) 0 0;font-size:var(--mf-text-xs);line-height:var(--mf-leading-normal)}.mf-radio__hint{color:var(--mf-color-neutral-600)}.mf-radio__error{color:var(--mf-color-error-500)}\n"], dependencies: [{ kind: "ngmodule", type: MatRadioModule }, { kind: "directive", type: i1$f.MatRadioGroup, selector: "mat-radio-group", inputs: ["color", "name", "labelPosition", "value", "selected", "disabled", "required", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioGroup"] }, { kind: "component", type: i1$f.MatRadioButton, selector: "mat-radio-button", inputs: ["id", "name", "aria-label", "aria-labelledby", "aria-describedby", "disableRipple", "tabIndex", "checked", "value", "labelPosition", "disabled", "required", "color", "disabledInteractive"], outputs: ["change"], exportAs: ["matRadioButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2549
+ }
2550
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfRadioButtonComponent, decorators: [{
2551
+ type: Component,
2552
+ args: [{ selector: 'mf-radio-button', imports: [MatRadioModule], providers: [
2553
+ {
2554
+ provide: NG_VALUE_ACCESSOR,
2555
+ useExisting: forwardRef(() => MfRadioButtonComponent),
2556
+ multi: true,
2557
+ },
2558
+ ], template: `
2559
+ <fieldset class="mf-radio__fieldset">
2560
+ @if (label()) {
2561
+ <legend class="mf-radio__legend" [id]="legendId()">
2562
+ {{ label() }}
2563
+ @if (required()) {
2564
+ <span aria-hidden="true"> *</span>
2565
+ }
2566
+ </legend>
2567
+ }
2568
+
2569
+ <mat-radio-group
2570
+ [class]="hostClasses()"
2571
+ [disabled]="isDisabled()"
2572
+ [name]="groupName()"
2573
+ [required]="required()"
2574
+ [value]="internalValue()"
2575
+ [attr.aria-label]="resolvedAriaLabel()"
2576
+ [attr.aria-labelledby]="computedLabelledby()"
2577
+ [attr.aria-describedby]="describedBy()"
2578
+ [attr.aria-invalid]="isInvalid() ? 'true' : null"
2579
+ [attr.aria-required]="required() ? 'true' : null"
2580
+ (change)="onChange($event)"
2581
+ >
2582
+ @for (option of options(); track option.value) {
2583
+ <mat-radio-button
2584
+ class="mf-radio__option"
2585
+ [value]="option.value"
2586
+ [disabled]="option.disabled ?? false"
2587
+ >
2588
+ {{ option.label }}
2589
+ </mat-radio-button>
2590
+ }
2591
+ </mat-radio-group>
2592
+
2593
+ @if (hint()) {
2594
+ <p class="mf-radio__hint" [attr.id]="hintId()">{{ hint() }}</p>
2595
+ }
2596
+
2597
+ @if (error()) {
2598
+ <p class="mf-radio__error" [attr.id]="errorId()" role="alert">
2599
+ {{ error() }}
2600
+ </p>
2601
+ }
2602
+ </fieldset>
2603
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.mf-radio__fieldset{margin:0;padding:0;border:0}.mf-radio__legend{margin-bottom:var(--mf-space-2);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-medium);color:var(--mf-color-on-surface)}.mf-radio{display:flex}.mf-radio--vertical{flex-direction:column;gap:var(--mf-space-2)}.mf-radio--horizontal{flex-direction:row;flex-wrap:wrap;gap:var(--mf-space-4)}.mf-radio__option{font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important;color:var(--mf-color-on-surface)!important}.mf-radio__option .mdc-radio .mdc-radio__outer-circle{border-color:var(--mf-color-border)!important;transition:border-color var(--mf-duration-base) var(--mf-ease-standard)}.mf-radio__option.mat-mdc-radio-checked .mdc-radio .mdc-radio__outer-circle,.mf-radio__option.mat-mdc-radio-checked .mdc-radio .mdc-radio__inner-circle{border-color:var(--mf-color-brand)!important}.mf-radio__option .mat-ripple-element{background-color:var(--mf-color-brand-light)!important}.mf-radio__option .mdc-label{font-family:var(--mf-font-base)!important;color:var(--mf-color-on-surface)!important;cursor:pointer}.mf-radio__option.mat-mdc-radio-disabled .mdc-label{color:var(--mf-color-neutral-400)!important;cursor:default}.mf-radio__hint,.mf-radio__error{margin:var(--mf-space-2) 0 0;font-size:var(--mf-text-xs);line-height:var(--mf-leading-normal)}.mf-radio__hint{color:var(--mf-color-neutral-600)}.mf-radio__error{color:var(--mf-color-error-500)}\n"] }]
2604
+ }], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledby", required: false }] }], ariaDescribedby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedby", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], mfChange: [{ type: i0.Output, args: ["mfChange"] }] } });
2605
+
2606
+ /**
2607
+ * Select de la librería ng-comps.
2608
+ * Envuelve Angular Material `mat-select` y expone una API uniforme
2609
+ * con look and feel de marca.
2610
+ *
2611
+ * El dropdown se estiliza mediante la clase global `mf-select-panel` que se
2612
+ * inserta en el overlay. Puedes añadir clases adicionales con `panelClass`.
2613
+ */
2614
+ class MfSelectComponent {
2615
+ cdr = inject(ChangeDetectorRef);
2616
+ ngControl = inject(NgControl, { self: true, optional: true });
2617
+ generatedId = createUniqueId('mf-select');
2618
+ disabledFromForm = signal(false, ...(ngDevMode ? [{ debugName: "disabledFromForm" }] : /* istanbul ignore next */ []));
2619
+ internalValue = signal(undefined, ...(ngDevMode ? [{ debugName: "internalValue" }] : /* istanbul ignore next */ []));
2620
+ onControlChange = () => undefined;
2621
+ onControlTouched = () => undefined;
2622
+ errorStateMatcher = {
2623
+ isErrorState: (control) => Boolean(this.error() || (control?.invalid && (control.touched || control.dirty))),
2624
+ };
2625
+ /** Opciones del select */
2626
+ options = input.required(...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
2627
+ /** ID del control */
2628
+ id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
2629
+ /** Etiqueta flotante */
2630
+ label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
2631
+ /** Etiqueta accesible alternativa cuando no existe label visible */
2632
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
2633
+ /** Referencia externa a elementos que etiquetan el control */
2634
+ ariaLabelledby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : /* istanbul ignore next */ []));
2635
+ /** Referencia externa a elementos descriptivos adicionales */
2636
+ ariaDescribedby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaDescribedby" }] : /* istanbul ignore next */ []));
2637
+ /** Placeholder */
2638
+ placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
2639
+ /** Valor actual */
2640
+ value = input(undefined, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
2641
+ /** Selección múltiple */
2642
+ multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
2643
+ /** Deshabilitado */
2644
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
2645
+ /** Requerido */
2646
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
2647
+ /** Texto de ayuda */
2648
+ hint = input(undefined, ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
2649
+ /** Mensaje de error */
2650
+ error = input(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
2651
+ /** Tamaño del campo */
2652
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
2653
+ /** Ancho completo */
2654
+ fullWidth = input(false, ...(ngDevMode ? [{ debugName: "fullWidth" }] : /* istanbul ignore next */ []));
2655
+ /** Icono al inicio del campo */
2656
+ leadingIcon = input(undefined, ...(ngDevMode ? [{ debugName: "leadingIcon" }] : /* istanbul ignore next */ []));
2657
+ /** Icono al final del campo */
2658
+ trailingIcon = input(undefined, ...(ngDevMode ? [{ debugName: "trailingIcon" }] : /* istanbul ignore next */ []));
2659
+ /**
2660
+ * Clases extra que se añaden al panel del dropdown (overlay).
2661
+ * La clase `mf-select-panel` siempre está presente para los estilos base.
2662
+ */
2663
+ panelClass = input('', ...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
2664
+ mfSelectionChange = output();
2665
+ constructor() {
2666
+ effect(() => {
2667
+ this.internalValue.set(this.value());
2668
+ });
2669
+ effect(() => {
2670
+ if (!hasAccessibleName(this.label(), this.ariaLabel(), this.ariaLabelledby())) {
2671
+ warnInDev('mf-select requiere `label`, `ariaLabel` o `ariaLabelledby` para exponer un nombre accesible.');
2672
+ }
2673
+ });
2674
+ }
2675
+ controlId = computed(() => this.id() ?? this.generatedId, ...(ngDevMode ? [{ debugName: "controlId" }] : /* istanbul ignore next */ []));
2676
+ hintId = computed(() => this.hint() ? `${this.controlId()}-hint` : null, ...(ngDevMode ? [{ debugName: "hintId" }] : /* istanbul ignore next */ []));
2677
+ errorId = computed(() => this.error() ? `${this.controlId()}-error` : null, ...(ngDevMode ? [{ debugName: "errorId" }] : /* istanbul ignore next */ []));
2678
+ describedBy = computed(() => mergeAriaIds(this.ariaDescribedby(), this.hintId(), this.errorId()), ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
2679
+ resolvedAriaLabel = computed(() => this.label() ? null : this.ariaLabel() ?? null, ...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
2680
+ isDisabled = computed(() => this.disabled() || this.disabledFromForm(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
2681
+ hostClasses = computed(() => {
2682
+ const classes = ['mf-select', `mf-select--${this.size()}`];
2683
+ if (this.fullWidth())
2684
+ classes.push('mf-select--full');
2685
+ if (this.error())
2686
+ classes.push('mf-select--error');
2687
+ return classes.join(' ');
2688
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
2689
+ panelClasses = computed(() => {
2690
+ const base = ['mf-select-panel'];
2691
+ const extra = this.panelClass();
2692
+ if (Array.isArray(extra)) {
2693
+ base.push(...extra.filter(Boolean));
2694
+ }
2695
+ else if (extra) {
2696
+ base.push(extra);
2697
+ }
2698
+ return base;
2699
+ }, ...(ngDevMode ? [{ debugName: "panelClasses" }] : /* istanbul ignore next */ []));
2700
+ writeValue(value) {
2701
+ this.internalValue.set(value ?? undefined);
2702
+ this.cdr.markForCheck();
2703
+ }
2704
+ registerOnChange(fn) {
2705
+ this.onControlChange = fn;
2706
+ }
2707
+ registerOnTouched(fn) {
2708
+ this.onControlTouched = fn;
2709
+ }
2710
+ setDisabledState(isDisabled) {
2711
+ this.disabledFromForm.set(isDisabled);
2712
+ this.cdr.markForCheck();
2713
+ }
2714
+ isInvalid() {
2715
+ const control = this.ngControl?.control;
2716
+ return Boolean(this.error() || (control?.invalid && (control.touched || control.dirty)));
2717
+ }
2718
+ onSelectionChange(event) {
2719
+ this.internalValue.set(event.value);
2720
+ this.onControlChange(event.value);
2721
+ this.onControlTouched();
2722
+ this.mfSelectionChange.emit(event.value);
2723
+ }
2724
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2725
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfSelectComponent, isStandalone: true, selector: "mf-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "ariaDescribedby", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, leadingIcon: { classPropertyName: "leadingIcon", publicName: "leadingIcon", isSignal: true, isRequired: false, transformFunction: null }, trailingIcon: { classPropertyName: "trailingIcon", publicName: "trailingIcon", isSignal: true, isRequired: false, transformFunction: null }, panelClass: { classPropertyName: "panelClass", publicName: "panelClass", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfSelectionChange: "mfSelectionChange" }, providers: [
2726
+ {
2727
+ provide: NG_VALUE_ACCESSOR,
2728
+ useExisting: forwardRef(() => MfSelectComponent),
2729
+ multi: true,
2730
+ },
2731
+ ], ngImport: i0, template: `
2732
+ <mat-form-field [appearance]="'outline'" [class]="hostClasses()">
2733
+ @if (label()) {
2734
+ <mat-label>{{ label() }}</mat-label>
2735
+ }
2736
+ @if (leadingIcon()) {
2737
+ <mat-icon matPrefix aria-hidden="true">{{ leadingIcon() }}</mat-icon>
2738
+ }
2739
+ <mat-select
2740
+ [id]="controlId()"
2741
+ [value]="internalValue()"
2742
+ [disabled]="isDisabled()"
2743
+ [multiple]="multiple()"
2744
+ [placeholder]="placeholder()"
2745
+ [required]="required()"
2746
+ [errorStateMatcher]="errorStateMatcher"
2747
+ [panelClass]="panelClasses()"
2748
+ [attr.aria-label]="resolvedAriaLabel()"
2749
+ [attr.aria-labelledby]="ariaLabelledby() || null"
2750
+ [attr.aria-describedby]="describedBy()"
2751
+ [attr.aria-invalid]="isInvalid() ? 'true' : null"
2752
+ [attr.aria-required]="required() ? 'true' : null"
2753
+ (selectionChange)="onSelectionChange($event)"
2754
+ >
2755
+ @for (option of options(); track option.value) {
2756
+ <mat-option [value]="option.value" [disabled]="option.disabled ?? false">
2757
+ {{ option.label }}
2758
+ </mat-option>
2759
+ }
2760
+ </mat-select>
2761
+ @if (trailingIcon()) {
2762
+ <mat-icon matSuffix aria-hidden="true">{{ trailingIcon() }}</mat-icon>
2763
+ }
2764
+ @if (hint()) {
2765
+ <mat-hint [attr.id]="hintId()">{{ hint() }}</mat-hint>
2766
+ }
2767
+ </mat-form-field>
2768
+ @if (error()) {
2769
+ <p class="mf-select__error" [attr.id]="errorId()" role="alert">{{ error() }}</p>
2770
+ }
2771
+ `, isInline: true, styles: [":host{display:inline-block}.mf-select{font-family:var(--mf-font-base)!important;width:100%}.mf-select--full{width:100%}.mf-select .mat-mdc-text-field-wrapper,.mf-select .mdc-notched-outline{border-radius:var(--mf-radius-md)!important}.mf-select .mdc-notched-outline__leading,.mf-select .mdc-notched-outline__notch,.mf-select .mdc-notched-outline__trailing{border-color:var(--mf-color-border)!important;transition:border-color var(--mf-duration-base) var(--mf-ease-standard)}.mf-select .mat-mdc-form-field-focus-overlay{background-color:transparent!important}.mf-select.mat-focused .mdc-notched-outline__leading,.mf-select.mat-focused .mdc-notched-outline__notch,.mf-select.mat-focused .mdc-notched-outline__trailing{border-color:var(--mf-color-brand)!important;border-width:1.5px!important}.mf-select--error .mdc-notched-outline__leading,.mf-select--error .mdc-notched-outline__notch,.mf-select--error .mdc-notched-outline__trailing{border-color:var(--mf-color-error-500)!important}.mf-select .mat-mdc-floating-label{font-family:var(--mf-font-base)!important;font-weight:var(--mf-weight-medium)!important;color:var(--mf-color-neutral-400)!important}.mf-select.mat-focused .mat-mdc-floating-label{color:var(--mf-color-brand)!important}.mf-select .mat-mdc-select-trigger{font-family:var(--mf-font-base)!important;color:var(--mf-color-on-surface)!important}.mf-select .mat-mdc-select-placeholder{color:var(--mf-color-neutral-400)!important}.mf-select .mat-mdc-select-arrow{color:var(--mf-color-neutral-400)!important;transition:color var(--mf-duration-base) var(--mf-ease-standard)}.mf-select.mat-focused .mat-mdc-select-arrow{color:var(--mf-color-brand)!important}.mf-select .mat-icon{color:var(--mf-color-neutral-400)!important;font-size:20px;width:20px;height:20px;transition:color var(--mf-duration-base) var(--mf-ease-standard)}.mf-select.mat-focused .mat-icon{color:var(--mf-color-brand)!important}.mf-select .mat-mdc-form-field-hint{font-size:var(--mf-text-xs)!important;color:var(--mf-color-neutral-400)!important}.mf-select .mat-mdc-form-field-error{font-size:var(--mf-text-xs)!important}.mf-select--sm .mat-mdc-select-trigger{font-size:var(--mf-text-sm)!important}.mf-select--md .mat-mdc-select-trigger{font-size:var(--mf-text-base)!important}.mf-select--lg .mat-mdc-select-trigger{font-size:var(--mf-text-lg)!important}.mf-select .mat-mdc-select-trigger[aria-disabled=true],.mf-select .mat-mdc-select-trigger.mat-mdc-select-disabled{color:var(--mf-color-neutral-300)!important}\n"], dependencies: [{ kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i2$1.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2$1.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i2$2.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i1$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2772
+ }
2773
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfSelectComponent, decorators: [{
2774
+ type: Component,
2775
+ args: [{ selector: 'mf-select', imports: [MatSelectModule, MatFormFieldModule, MatIconModule], providers: [
2776
+ {
2777
+ provide: NG_VALUE_ACCESSOR,
2778
+ useExisting: forwardRef(() => MfSelectComponent),
2779
+ multi: true,
2780
+ },
2781
+ ], template: `
2782
+ <mat-form-field [appearance]="'outline'" [class]="hostClasses()">
2783
+ @if (label()) {
2784
+ <mat-label>{{ label() }}</mat-label>
2785
+ }
2786
+ @if (leadingIcon()) {
2787
+ <mat-icon matPrefix aria-hidden="true">{{ leadingIcon() }}</mat-icon>
2788
+ }
2789
+ <mat-select
2790
+ [id]="controlId()"
2791
+ [value]="internalValue()"
2792
+ [disabled]="isDisabled()"
2793
+ [multiple]="multiple()"
2794
+ [placeholder]="placeholder()"
2795
+ [required]="required()"
2796
+ [errorStateMatcher]="errorStateMatcher"
2797
+ [panelClass]="panelClasses()"
2798
+ [attr.aria-label]="resolvedAriaLabel()"
2799
+ [attr.aria-labelledby]="ariaLabelledby() || null"
2800
+ [attr.aria-describedby]="describedBy()"
2801
+ [attr.aria-invalid]="isInvalid() ? 'true' : null"
2802
+ [attr.aria-required]="required() ? 'true' : null"
2803
+ (selectionChange)="onSelectionChange($event)"
2804
+ >
2805
+ @for (option of options(); track option.value) {
2806
+ <mat-option [value]="option.value" [disabled]="option.disabled ?? false">
2807
+ {{ option.label }}
2808
+ </mat-option>
2809
+ }
2810
+ </mat-select>
2811
+ @if (trailingIcon()) {
2812
+ <mat-icon matSuffix aria-hidden="true">{{ trailingIcon() }}</mat-icon>
2813
+ }
2814
+ @if (hint()) {
2815
+ <mat-hint [attr.id]="hintId()">{{ hint() }}</mat-hint>
2816
+ }
2817
+ </mat-form-field>
2818
+ @if (error()) {
2819
+ <p class="mf-select__error" [attr.id]="errorId()" role="alert">{{ error() }}</p>
2820
+ }
2821
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-block}.mf-select{font-family:var(--mf-font-base)!important;width:100%}.mf-select--full{width:100%}.mf-select .mat-mdc-text-field-wrapper,.mf-select .mdc-notched-outline{border-radius:var(--mf-radius-md)!important}.mf-select .mdc-notched-outline__leading,.mf-select .mdc-notched-outline__notch,.mf-select .mdc-notched-outline__trailing{border-color:var(--mf-color-border)!important;transition:border-color var(--mf-duration-base) var(--mf-ease-standard)}.mf-select .mat-mdc-form-field-focus-overlay{background-color:transparent!important}.mf-select.mat-focused .mdc-notched-outline__leading,.mf-select.mat-focused .mdc-notched-outline__notch,.mf-select.mat-focused .mdc-notched-outline__trailing{border-color:var(--mf-color-brand)!important;border-width:1.5px!important}.mf-select--error .mdc-notched-outline__leading,.mf-select--error .mdc-notched-outline__notch,.mf-select--error .mdc-notched-outline__trailing{border-color:var(--mf-color-error-500)!important}.mf-select .mat-mdc-floating-label{font-family:var(--mf-font-base)!important;font-weight:var(--mf-weight-medium)!important;color:var(--mf-color-neutral-400)!important}.mf-select.mat-focused .mat-mdc-floating-label{color:var(--mf-color-brand)!important}.mf-select .mat-mdc-select-trigger{font-family:var(--mf-font-base)!important;color:var(--mf-color-on-surface)!important}.mf-select .mat-mdc-select-placeholder{color:var(--mf-color-neutral-400)!important}.mf-select .mat-mdc-select-arrow{color:var(--mf-color-neutral-400)!important;transition:color var(--mf-duration-base) var(--mf-ease-standard)}.mf-select.mat-focused .mat-mdc-select-arrow{color:var(--mf-color-brand)!important}.mf-select .mat-icon{color:var(--mf-color-neutral-400)!important;font-size:20px;width:20px;height:20px;transition:color var(--mf-duration-base) var(--mf-ease-standard)}.mf-select.mat-focused .mat-icon{color:var(--mf-color-brand)!important}.mf-select .mat-mdc-form-field-hint{font-size:var(--mf-text-xs)!important;color:var(--mf-color-neutral-400)!important}.mf-select .mat-mdc-form-field-error{font-size:var(--mf-text-xs)!important}.mf-select--sm .mat-mdc-select-trigger{font-size:var(--mf-text-sm)!important}.mf-select--md .mat-mdc-select-trigger{font-size:var(--mf-text-base)!important}.mf-select--lg .mat-mdc-select-trigger{font-size:var(--mf-text-lg)!important}.mf-select .mat-mdc-select-trigger[aria-disabled=true],.mf-select .mat-mdc-select-trigger.mat-mdc-select-disabled{color:var(--mf-color-neutral-300)!important}\n"] }]
2822
+ }], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledby", required: false }] }], ariaDescribedby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedby", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], leadingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "leadingIcon", required: false }] }], trailingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "trailingIcon", required: false }] }], panelClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelClass", required: false }] }], mfSelectionChange: [{ type: i0.Output, args: ["mfSelectionChange"] }] } });
2823
+
2824
+ /**
2825
+ * Panel lateral de la librería ng-comps.
2826
+ * Envuelve Angular Material `mat-sidenav-container` y expone una API uniforme
2827
+ * con look and feel de marca.
2828
+ *
2829
+ * Dos formas de uso:
2830
+ * 1. **Navitems declarativos** — Proporciona `navItems`, `headerTitle` e icono.
2831
+ * 2. **Content projection** — Proyecta `[mfSidenavContent]` para control total.
2832
+ *
2833
+ * El contenido principal se proyecta sin atributo.
2834
+ */
2835
+ class MfSidenavComponent {
2836
+ /** Abierto o cerrado */
2837
+ opened = input(false, ...(ngDevMode ? [{ debugName: "opened" }] : /* istanbul ignore next */ []));
2838
+ /** Modo de apertura */
2839
+ mode = input('side', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
2840
+ /** Posición del panel */
2841
+ position = input('start', ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
2842
+ /** Muestra backdrop al abrir */
2843
+ hasBackdrop = input(null, ...(ngDevMode ? [{ debugName: "hasBackdrop" }] : /* istanbul ignore next */ []));
2844
+ /** Ancho del panel lateral */
2845
+ sidenavWidth = input('260px', ...(ngDevMode ? [{ debugName: "sidenavWidth" }] : /* istanbul ignore next */ []));
2846
+ /** Ítems de navegación declarativos */
2847
+ navItems = input([], ...(ngDevMode ? [{ debugName: "navItems" }] : /* istanbul ignore next */ []));
2848
+ /** Título de la cabecera del sidenav */
2849
+ headerTitle = input(undefined, ...(ngDevMode ? [{ debugName: "headerTitle" }] : /* istanbul ignore next */ []));
2850
+ /** Icono Material de la cabecera */
2851
+ headerIcon = input(undefined, ...(ngDevMode ? [{ debugName: "headerIcon" }] : /* istanbul ignore next */ []));
2852
+ /** Aria-label del elemento nav */
2853
+ navAriaLabel = input('Primary navigation', ...(ngDevMode ? [{ debugName: "navAriaLabel" }] : /* istanbul ignore next */ []));
2854
+ mfOpenedChange = output();
2855
+ /** Emite el ítem de navegación pulsado */
2856
+ mfNavItemClick = output();
2857
+ containerClasses = computed(() => 'mf-sidenav-container', ...(ngDevMode ? [{ debugName: "containerClasses" }] : /* istanbul ignore next */ []));
2858
+ sidenavClasses = computed(() => {
2859
+ return `mf-sidenav mf-sidenav--${this.mode()}`;
2860
+ }, ...(ngDevMode ? [{ debugName: "sidenavClasses" }] : /* istanbul ignore next */ []));
2861
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfSidenavComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2862
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfSidenavComponent, isStandalone: true, selector: "mf-sidenav", inputs: { opened: { classPropertyName: "opened", publicName: "opened", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, hasBackdrop: { classPropertyName: "hasBackdrop", publicName: "hasBackdrop", isSignal: true, isRequired: false, transformFunction: null }, sidenavWidth: { classPropertyName: "sidenavWidth", publicName: "sidenavWidth", isSignal: true, isRequired: false, transformFunction: null }, navItems: { classPropertyName: "navItems", publicName: "navItems", isSignal: true, isRequired: false, transformFunction: null }, headerTitle: { classPropertyName: "headerTitle", publicName: "headerTitle", isSignal: true, isRequired: false, transformFunction: null }, headerIcon: { classPropertyName: "headerIcon", publicName: "headerIcon", isSignal: true, isRequired: false, transformFunction: null }, navAriaLabel: { classPropertyName: "navAriaLabel", publicName: "navAriaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfOpenedChange: "mfOpenedChange", mfNavItemClick: "mfNavItemClick" }, ngImport: i0, template: `
2863
+ <mat-sidenav-container [class]="containerClasses()" [hasBackdrop]="hasBackdrop()">
2864
+ <mat-sidenav
2865
+ [class]="sidenavClasses()"
2866
+ [mode]="mode()"
2867
+ [position]="position()"
2868
+ [opened]="opened()"
2869
+ [style.width]="sidenavWidth()"
2870
+ (openedChange)="mfOpenedChange.emit($event)"
2871
+ >
2872
+ @if (navItems().length > 0) {
2873
+ <div class="mf-sidenav__nav">
2874
+ @if (headerTitle()) {
2875
+ <div class="mf-sidenav__header">
2876
+ @if (headerIcon()) {
2877
+ <mat-icon class="mf-sidenav__header-icon" aria-hidden="true">{{ headerIcon() }}</mat-icon>
2878
+ }
2879
+ <span class="mf-sidenav__header-title">{{ headerTitle() }}</span>
2880
+ </div>
2881
+ }
2882
+ <nav class="mf-sidenav__menu" [attr.aria-label]="navAriaLabel()">
2883
+ @for (item of navItems(); track item.id) {
2884
+ <button
2885
+ type="button"
2886
+ class="mf-sidenav__item"
2887
+ [class.mf-sidenav__item--active]="item.active"
2888
+ [class.mf-sidenav__item--disabled]="item.disabled"
2889
+ [disabled]="item.disabled ?? false"
2890
+ [attr.aria-current]="item.active ? 'page' : null"
2891
+ (click)="!item.disabled && mfNavItemClick.emit(item)"
2892
+ >
2893
+ <mat-icon class="mf-sidenav__item-icon" aria-hidden="true">{{ item.icon }}</mat-icon>
2894
+ <span class="mf-sidenav__item-label">{{ item.label }}</span>
2895
+ @if (item.badge && item.badge > 0) {
2896
+ <span class="mf-sidenav__item-badge" aria-label="{{ item.badge }} notifications">
2897
+ {{ item.badge > 99 ? '99+' : item.badge }}
2898
+ </span>
2899
+ }
2900
+ </button>
2901
+ }
2902
+ </nav>
2903
+ </div>
2904
+ } @else {
2905
+ <ng-content select="[mfSidenavContent]" />
2906
+ }
2907
+ </mat-sidenav>
2908
+ <mat-sidenav-content class="mf-sidenav__main">
2909
+ <ng-content />
2910
+ </mat-sidenav-content>
2911
+ </mat-sidenav-container>
2912
+ `, isInline: true, styles: [":host{display:block;height:100%}.mf-sidenav-container{height:100%;background-color:var(--mf-color-surface)!important}.mf-sidenav{background-color:var(--mf-color-surface)!important;border-right:1px solid var(--mf-color-border)!important;font-family:var(--mf-font-base)!important}.mf-sidenav--over,.mf-sidenav--push{box-shadow:var(--mf-shadow-lg)!important}.mf-sidenav--side{box-shadow:none;border-right:1px solid var(--mf-color-border)!important}.mf-sidenav__nav{display:flex;flex-direction:column;height:100%;overflow:hidden}.mf-sidenav__header{display:flex;align-items:center;gap:var(--mf-space-2);padding:var(--mf-space-5) var(--mf-space-4) var(--mf-space-4);border-bottom:1px solid var(--mf-color-border);flex-shrink:0}.mf-sidenav__header-icon{color:var(--mf-color-brand)!important;font-size:22px;width:22px;height:22px}.mf-sidenav__header-title{font-family:var(--mf-font-display)!important;font-size:var(--mf-text-base);font-weight:var(--mf-weight-bold);color:var(--mf-color-on-surface);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mf-sidenav__menu{display:flex;flex-direction:column;gap:var(--mf-space-1);padding:var(--mf-space-3) var(--mf-space-3);flex:1;overflow-y:auto}.mf-sidenav__item{display:flex;align-items:center;gap:var(--mf-space-3);width:100%;padding:var(--mf-space-2) var(--mf-space-3);border:none;border-radius:var(--mf-radius-md);background:transparent;color:var(--mf-color-neutral-600);font-family:var(--mf-font-base);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-medium);cursor:pointer;text-align:left;transition:background-color var(--mf-duration-fast) var(--mf-ease-standard),color var(--mf-duration-fast) var(--mf-ease-standard);position:relative}.mf-sidenav__item:hover:not(.mf-sidenav__item--disabled){background-color:var(--mf-color-neutral-100);color:var(--mf-color-on-surface)}.mf-sidenav__item:hover:not(.mf-sidenav__item--disabled) .mf-sidenav__item-icon{color:var(--mf-color-brand)!important}.mf-sidenav__item--active{background-color:var(--mf-color-brand-light)!important;color:var(--mf-color-brand)!important;font-weight:var(--mf-weight-bold)!important}.mf-sidenav__item--active .mf-sidenav__item-icon{color:var(--mf-color-brand)!important}.mf-sidenav__item--disabled{opacity:.4;cursor:not-allowed}.mf-sidenav__item-icon{font-size:20px;width:20px;height:20px;flex-shrink:0;color:var(--mf-color-neutral-400)!important;transition:color var(--mf-duration-fast) var(--mf-ease-standard)}.mf-sidenav__item-label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mf-sidenav__item-badge{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 var(--mf-space-1);border-radius:var(--mf-radius-full);background-color:var(--mf-color-brand);color:var(--mf-color-on-brand);font-size:.625rem;font-weight:var(--mf-weight-bold);line-height:1;flex-shrink:0}.mf-sidenav__main{background-color:var(--mf-color-surface);padding:var(--mf-space-6);font-family:var(--mf-font-base)}.mf-sidenav-container .mat-drawer-backdrop.mat-drawer-shown{background-color:#0f172a52!important}\n"], dependencies: [{ kind: "ngmodule", type: MatSidenavModule }, { kind: "component", type: i1$g.MatSidenav, selector: "mat-sidenav", inputs: ["fixedInViewport", "fixedTopGap", "fixedBottomGap"], exportAs: ["matSidenav"] }, { kind: "component", type: i1$g.MatSidenavContainer, selector: "mat-sidenav-container", exportAs: ["matSidenavContainer"] }, { kind: "component", type: i1$g.MatSidenavContent, selector: "mat-sidenav-content" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2913
+ }
2914
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfSidenavComponent, decorators: [{
2915
+ type: Component,
2916
+ args: [{ selector: 'mf-sidenav', imports: [MatSidenavModule, MatIconModule], template: `
2917
+ <mat-sidenav-container [class]="containerClasses()" [hasBackdrop]="hasBackdrop()">
2918
+ <mat-sidenav
2919
+ [class]="sidenavClasses()"
2920
+ [mode]="mode()"
2921
+ [position]="position()"
2922
+ [opened]="opened()"
2923
+ [style.width]="sidenavWidth()"
2924
+ (openedChange)="mfOpenedChange.emit($event)"
2925
+ >
2926
+ @if (navItems().length > 0) {
2927
+ <div class="mf-sidenav__nav">
2928
+ @if (headerTitle()) {
2929
+ <div class="mf-sidenav__header">
2930
+ @if (headerIcon()) {
2931
+ <mat-icon class="mf-sidenav__header-icon" aria-hidden="true">{{ headerIcon() }}</mat-icon>
2932
+ }
2933
+ <span class="mf-sidenav__header-title">{{ headerTitle() }}</span>
2934
+ </div>
2935
+ }
2936
+ <nav class="mf-sidenav__menu" [attr.aria-label]="navAriaLabel()">
2937
+ @for (item of navItems(); track item.id) {
2938
+ <button
2939
+ type="button"
2940
+ class="mf-sidenav__item"
2941
+ [class.mf-sidenav__item--active]="item.active"
2942
+ [class.mf-sidenav__item--disabled]="item.disabled"
2943
+ [disabled]="item.disabled ?? false"
2944
+ [attr.aria-current]="item.active ? 'page' : null"
2945
+ (click)="!item.disabled && mfNavItemClick.emit(item)"
2946
+ >
2947
+ <mat-icon class="mf-sidenav__item-icon" aria-hidden="true">{{ item.icon }}</mat-icon>
2948
+ <span class="mf-sidenav__item-label">{{ item.label }}</span>
2949
+ @if (item.badge && item.badge > 0) {
2950
+ <span class="mf-sidenav__item-badge" aria-label="{{ item.badge }} notifications">
2951
+ {{ item.badge > 99 ? '99+' : item.badge }}
2952
+ </span>
2953
+ }
2954
+ </button>
2955
+ }
2956
+ </nav>
2957
+ </div>
2958
+ } @else {
2959
+ <ng-content select="[mfSidenavContent]" />
2960
+ }
2961
+ </mat-sidenav>
2962
+ <mat-sidenav-content class="mf-sidenav__main">
2963
+ <ng-content />
2964
+ </mat-sidenav-content>
2965
+ </mat-sidenav-container>
2966
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block;height:100%}.mf-sidenav-container{height:100%;background-color:var(--mf-color-surface)!important}.mf-sidenav{background-color:var(--mf-color-surface)!important;border-right:1px solid var(--mf-color-border)!important;font-family:var(--mf-font-base)!important}.mf-sidenav--over,.mf-sidenav--push{box-shadow:var(--mf-shadow-lg)!important}.mf-sidenav--side{box-shadow:none;border-right:1px solid var(--mf-color-border)!important}.mf-sidenav__nav{display:flex;flex-direction:column;height:100%;overflow:hidden}.mf-sidenav__header{display:flex;align-items:center;gap:var(--mf-space-2);padding:var(--mf-space-5) var(--mf-space-4) var(--mf-space-4);border-bottom:1px solid var(--mf-color-border);flex-shrink:0}.mf-sidenav__header-icon{color:var(--mf-color-brand)!important;font-size:22px;width:22px;height:22px}.mf-sidenav__header-title{font-family:var(--mf-font-display)!important;font-size:var(--mf-text-base);font-weight:var(--mf-weight-bold);color:var(--mf-color-on-surface);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mf-sidenav__menu{display:flex;flex-direction:column;gap:var(--mf-space-1);padding:var(--mf-space-3) var(--mf-space-3);flex:1;overflow-y:auto}.mf-sidenav__item{display:flex;align-items:center;gap:var(--mf-space-3);width:100%;padding:var(--mf-space-2) var(--mf-space-3);border:none;border-radius:var(--mf-radius-md);background:transparent;color:var(--mf-color-neutral-600);font-family:var(--mf-font-base);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-medium);cursor:pointer;text-align:left;transition:background-color var(--mf-duration-fast) var(--mf-ease-standard),color var(--mf-duration-fast) var(--mf-ease-standard);position:relative}.mf-sidenav__item:hover:not(.mf-sidenav__item--disabled){background-color:var(--mf-color-neutral-100);color:var(--mf-color-on-surface)}.mf-sidenav__item:hover:not(.mf-sidenav__item--disabled) .mf-sidenav__item-icon{color:var(--mf-color-brand)!important}.mf-sidenav__item--active{background-color:var(--mf-color-brand-light)!important;color:var(--mf-color-brand)!important;font-weight:var(--mf-weight-bold)!important}.mf-sidenav__item--active .mf-sidenav__item-icon{color:var(--mf-color-brand)!important}.mf-sidenav__item--disabled{opacity:.4;cursor:not-allowed}.mf-sidenav__item-icon{font-size:20px;width:20px;height:20px;flex-shrink:0;color:var(--mf-color-neutral-400)!important;transition:color var(--mf-duration-fast) var(--mf-ease-standard)}.mf-sidenav__item-label{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mf-sidenav__item-badge{display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 var(--mf-space-1);border-radius:var(--mf-radius-full);background-color:var(--mf-color-brand);color:var(--mf-color-on-brand);font-size:.625rem;font-weight:var(--mf-weight-bold);line-height:1;flex-shrink:0}.mf-sidenav__main{background-color:var(--mf-color-surface);padding:var(--mf-space-6);font-family:var(--mf-font-base)}.mf-sidenav-container .mat-drawer-backdrop.mat-drawer-shown{background-color:#0f172a52!important}\n"] }]
2967
+ }], propDecorators: { opened: [{ type: i0.Input, args: [{ isSignal: true, alias: "opened", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], hasBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasBackdrop", required: false }] }], sidenavWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidenavWidth", required: false }] }], navItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "navItems", required: false }] }], headerTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerTitle", required: false }] }], headerIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerIcon", required: false }] }], navAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "navAriaLabel", required: false }] }], mfOpenedChange: [{ type: i0.Output, args: ["mfOpenedChange"] }], mfNavItemClick: [{ type: i0.Output, args: ["mfNavItemClick"] }] } });
2968
+
2969
+ /**
2970
+ * Slide Toggle de la librería ng-comps.
2971
+ * Envuelve Angular Material `mat-slide-toggle` y expone una API uniforme
2972
+ * con look and feel de marca.
2973
+ */
2974
+ class MfSlideToggleComponent {
2975
+ cdr = inject(ChangeDetectorRef);
2976
+ ngControl = inject(NgControl, { self: true, optional: true });
2977
+ generatedId = createUniqueId('mf-slide-toggle');
2978
+ disabledFromForm = signal(false, ...(ngDevMode ? [{ debugName: "disabledFromForm" }] : /* istanbul ignore next */ []));
2979
+ internalValue = signal(false, ...(ngDevMode ? [{ debugName: "internalValue" }] : /* istanbul ignore next */ []));
2980
+ onControlChange = () => undefined;
2981
+ onControlTouched = () => undefined;
2982
+ /** ID del control */
2983
+ id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
2984
+ /** Texto descriptivo */
2985
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
2986
+ /** Etiqueta accesible alternativa cuando no existe label visible */
2987
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
2988
+ /** Referencia externa a elementos que etiquetan el control */
2989
+ ariaLabelledby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : /* istanbul ignore next */ []));
2990
+ /** Referencia externa a elementos descriptivos adicionales */
2991
+ ariaDescribedby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaDescribedby" }] : /* istanbul ignore next */ []));
2992
+ /** Estado activado */
2993
+ checked = input(false, ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
2994
+ /** Deshabilitado */
2995
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
2996
+ /** Requerido */
2997
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
2998
+ /** Texto de ayuda */
2999
+ hint = input(undefined, ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
3000
+ /** Mensaje de error */
3001
+ error = input(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
3002
+ mfChange = output();
3003
+ constructor() {
3004
+ effect(() => {
3005
+ this.internalValue.set(this.checked());
3006
+ });
3007
+ effect(() => {
3008
+ if (!hasAccessibleName(this.label(), this.ariaLabel(), this.ariaLabelledby())) {
3009
+ warnInDev('mf-slide-toggle requiere texto visible, `ariaLabel` o `ariaLabelledby` para exponer un nombre accesible.');
3010
+ }
3011
+ });
3012
+ }
3013
+ controlId = computed(() => this.id() ?? this.generatedId, ...(ngDevMode ? [{ debugName: "controlId" }] : /* istanbul ignore next */ []));
3014
+ hintId = computed(() => this.hint() ? `${this.controlId()}-hint` : null, ...(ngDevMode ? [{ debugName: "hintId" }] : /* istanbul ignore next */ []));
3015
+ errorId = computed(() => this.error() ? `${this.controlId()}-error` : null, ...(ngDevMode ? [{ debugName: "errorId" }] : /* istanbul ignore next */ []));
3016
+ describedBy = computed(() => mergeAriaIds(this.ariaDescribedby(), this.hintId(), this.errorId()), ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
3017
+ resolvedAriaLabel = computed(() => this.label() ? null : this.ariaLabel() ?? null, ...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
3018
+ isDisabled = computed(() => this.disabled() || this.disabledFromForm(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
3019
+ hostClasses = computed(() => {
3020
+ const classes = ['mf-slide-toggle'];
3021
+ if (this.isDisabled())
3022
+ classes.push('mf-slide-toggle--disabled');
3023
+ if (this.error())
3024
+ classes.push('mf-slide-toggle--error');
3025
+ return classes.join(' ');
3026
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
3027
+ writeValue(value) {
3028
+ this.internalValue.set(Boolean(value));
3029
+ this.cdr.markForCheck();
3030
+ }
3031
+ registerOnChange(fn) {
3032
+ this.onControlChange = fn;
3033
+ }
3034
+ registerOnTouched(fn) {
3035
+ this.onControlTouched = fn;
3036
+ }
3037
+ setDisabledState(isDisabled) {
3038
+ this.disabledFromForm.set(isDisabled);
3039
+ this.cdr.markForCheck();
3040
+ }
3041
+ isInvalid() {
3042
+ const control = this.ngControl?.control;
3043
+ return Boolean(this.error() || (control?.invalid && (control.touched || control.dirty)));
3044
+ }
3045
+ onToggleChange(event) {
3046
+ this.internalValue.set(event.checked);
3047
+ this.onControlChange(event.checked);
3048
+ this.onControlTouched();
3049
+ this.mfChange.emit(event.checked);
3050
+ }
3051
+ onChange(event) {
3052
+ this.onToggleChange(event);
3053
+ }
3054
+ onBlur() {
3055
+ this.onControlTouched();
3056
+ }
3057
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfSlideToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3058
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfSlideToggleComponent, isStandalone: true, selector: "mf-slide-toggle", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "ariaDescribedby", isSignal: true, isRequired: false, transformFunction: null }, checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfChange: "mfChange" }, providers: [
3059
+ {
3060
+ provide: NG_VALUE_ACCESSOR,
3061
+ useExisting: forwardRef(() => MfSlideToggleComponent),
3062
+ multi: true,
3063
+ },
3064
+ ], ngImport: i0, template: `
3065
+ <div [class]="hostClasses()">
3066
+ <mat-slide-toggle
3067
+ [id]="controlId()"
3068
+ [checked]="internalValue()"
3069
+ [disabled]="isDisabled()"
3070
+ [required]="required()"
3071
+ [attr.aria-label]="resolvedAriaLabel()"
3072
+ [attr.aria-labelledby]="ariaLabelledby() || null"
3073
+ [attr.aria-describedby]="describedBy()"
3074
+ [attr.aria-invalid]="isInvalid() ? 'true' : null"
3075
+ [attr.aria-required]="required() ? 'true' : null"
3076
+ (change)="onToggleChange($event)"
3077
+ (blur)="onBlur()"
3078
+ >
3079
+ {{ label() }}
3080
+ </mat-slide-toggle>
3081
+
3082
+ @if (hint()) {
3083
+ <p class="mf-slide-toggle__hint" [attr.id]="hintId()">{{ hint() }}</p>
3084
+ }
3085
+
3086
+ @if (error()) {
3087
+ <p class="mf-slide-toggle__error" [attr.id]="errorId()" role="alert">
3088
+ {{ error() }}
3089
+ </p>
3090
+ }
3091
+ </div>
3092
+ `, isInline: true, styles: [":host{display:block}.mf-slide-toggle{display:flex;flex-direction:column;gap:var(--mf-space-1)}.mf-slide-toggle .mat-mdc-slide-toggle{font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important}.mf-slide-toggle .mdc-switch--selected .mdc-switch__track:after{background-color:var(--mf-color-primary-200)!important}.mf-slide-toggle .mdc-switch--selected .mdc-switch__handle:after{background-color:var(--mf-color-brand)!important}.mf-slide-toggle--disabled{opacity:.42}.mf-slide-toggle__hint,.mf-slide-toggle__error{margin:0;padding-left:calc(36px + var(--mf-space-2));font-size:var(--mf-text-xs);line-height:var(--mf-leading-normal)}.mf-slide-toggle__hint{color:var(--mf-color-neutral-600)}.mf-slide-toggle__error{color:var(--mf-color-error-500)}\n"], dependencies: [{ kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i1$h.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3093
+ }
3094
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfSlideToggleComponent, decorators: [{
3095
+ type: Component,
3096
+ args: [{ selector: 'mf-slide-toggle', imports: [MatSlideToggleModule], providers: [
3097
+ {
3098
+ provide: NG_VALUE_ACCESSOR,
3099
+ useExisting: forwardRef(() => MfSlideToggleComponent),
3100
+ multi: true,
3101
+ },
3102
+ ], template: `
3103
+ <div [class]="hostClasses()">
3104
+ <mat-slide-toggle
3105
+ [id]="controlId()"
3106
+ [checked]="internalValue()"
3107
+ [disabled]="isDisabled()"
3108
+ [required]="required()"
3109
+ [attr.aria-label]="resolvedAriaLabel()"
3110
+ [attr.aria-labelledby]="ariaLabelledby() || null"
3111
+ [attr.aria-describedby]="describedBy()"
3112
+ [attr.aria-invalid]="isInvalid() ? 'true' : null"
3113
+ [attr.aria-required]="required() ? 'true' : null"
3114
+ (change)="onToggleChange($event)"
3115
+ (blur)="onBlur()"
3116
+ >
3117
+ {{ label() }}
3118
+ </mat-slide-toggle>
3119
+
3120
+ @if (hint()) {
3121
+ <p class="mf-slide-toggle__hint" [attr.id]="hintId()">{{ hint() }}</p>
3122
+ }
3123
+
3124
+ @if (error()) {
3125
+ <p class="mf-slide-toggle__error" [attr.id]="errorId()" role="alert">
3126
+ {{ error() }}
3127
+ </p>
3128
+ }
3129
+ </div>
3130
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.mf-slide-toggle{display:flex;flex-direction:column;gap:var(--mf-space-1)}.mf-slide-toggle .mat-mdc-slide-toggle{font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important}.mf-slide-toggle .mdc-switch--selected .mdc-switch__track:after{background-color:var(--mf-color-primary-200)!important}.mf-slide-toggle .mdc-switch--selected .mdc-switch__handle:after{background-color:var(--mf-color-brand)!important}.mf-slide-toggle--disabled{opacity:.42}.mf-slide-toggle__hint,.mf-slide-toggle__error{margin:0;padding-left:calc(36px + var(--mf-space-2));font-size:var(--mf-text-xs);line-height:var(--mf-leading-normal)}.mf-slide-toggle__hint{color:var(--mf-color-neutral-600)}.mf-slide-toggle__error{color:var(--mf-color-error-500)}\n"] }]
3131
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledby", required: false }] }], ariaDescribedby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedby", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], mfChange: [{ type: i0.Output, args: ["mfChange"] }] } });
3132
+
3133
+ /**
3134
+ * Servicio de Snackbar de la librería ng-comps.
3135
+ * Envuelve Angular Material `MatSnackBar` y expone una API uniforme
3136
+ * con estilos de marca y tipos semánticos.
3137
+ */
3138
+ class MfSnackbarService {
3139
+ matSnackBar = inject(MatSnackBar);
3140
+ open(config) {
3141
+ const type = config.type ?? 'info';
3142
+ const matConfig = {
3143
+ duration: config.duration ?? this.defaultDuration(type),
3144
+ horizontalPosition: config.horizontalPosition ?? 'end',
3145
+ verticalPosition: config.verticalPosition ?? 'bottom',
3146
+ politeness: config.politeness ?? this.defaultPoliteness(type),
3147
+ announcementMessage: config.announcementMessage ?? config.message,
3148
+ panelClass: ['mf-snackbar', `mf-snackbar--${type}`],
3149
+ };
3150
+ return this.matSnackBar.open(config.message, config.action, matConfig);
3151
+ }
3152
+ info(message, action) {
3153
+ return this.open({ message, action, type: 'info' });
3154
+ }
3155
+ success(message, action) {
3156
+ return this.open({ message, action, type: 'success' });
3157
+ }
3158
+ warning(message, action) {
3159
+ return this.open({ message, action, type: 'warning' });
3160
+ }
3161
+ error(message, action) {
3162
+ return this.open({ message, action, type: 'error' });
3163
+ }
3164
+ defaultDuration(type) {
3165
+ if (type === 'error' || type === 'warning') {
3166
+ return 6000;
3167
+ }
3168
+ return 4000;
3169
+ }
3170
+ defaultPoliteness(type) {
3171
+ if (type === 'error' || type === 'warning') {
3172
+ return 'assertive';
3173
+ }
3174
+ return 'polite';
3175
+ }
3176
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfSnackbarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3177
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfSnackbarService, providedIn: 'root' });
3178
+ }
3179
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfSnackbarService, decorators: [{
3180
+ type: Injectable,
3181
+ args: [{ providedIn: 'root' }]
3182
+ }] });
3183
+
3184
+ /**
3185
+ * Enterprise-oriented table component with optional search, pagination,
3186
+ * badges, explicit row actions and client-side sorting.
3187
+ */
3188
+ class MfTableComponent {
3189
+ localSearchTerm = signal('', ...(ngDevMode ? [{ debugName: "localSearchTerm" }] : /* istanbul ignore next */ []));
3190
+ localPageIndex = signal(0, ...(ngDevMode ? [{ debugName: "localPageIndex" }] : /* istanbul ignore next */ []));
3191
+ localPageSize = signal(10, ...(ngDevMode ? [{ debugName: "localPageSize" }] : /* istanbul ignore next */ []));
3192
+ sortState = signal({ active: '', direction: '' }, ...(ngDevMode ? [{ debugName: "sortState" }] : /* istanbul ignore next */ []));
3193
+ actionColumnKey = 'mf-row-action';
3194
+ columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
3195
+ data = input([], ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
3196
+ variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
3197
+ density = input('comfortable', ...(ngDevMode ? [{ debugName: "density" }] : /* istanbul ignore next */ []));
3198
+ title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
3199
+ description = input(undefined, ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
3200
+ showSearch = input(false, ...(ngDevMode ? [{ debugName: "showSearch" }] : /* istanbul ignore next */ []));
3201
+ searchLabel = input('Search', ...(ngDevMode ? [{ debugName: "searchLabel" }] : /* istanbul ignore next */ []));
3202
+ searchPlaceholder = input('Search records', ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : /* istanbul ignore next */ []));
3203
+ searchValue = input('', ...(ngDevMode ? [{ debugName: "searchValue" }] : /* istanbul ignore next */ []));
3204
+ showPaginator = input(false, ...(ngDevMode ? [{ debugName: "showPaginator" }] : /* istanbul ignore next */ []));
3205
+ pageSize = input(10, ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
3206
+ pageIndex = input(0, ...(ngDevMode ? [{ debugName: "pageIndex" }] : /* istanbul ignore next */ []));
3207
+ pageSizeOptions = input([10, 25, 50, 100], ...(ngDevMode ? [{ debugName: "pageSizeOptions" }] : /* istanbul ignore next */ []));
3208
+ showFirstLastButtons = input(true, ...(ngDevMode ? [{ debugName: "showFirstLastButtons" }] : /* istanbul ignore next */ []));
3209
+ hidePageSize = input(false, ...(ngDevMode ? [{ debugName: "hidePageSize" }] : /* istanbul ignore next */ []));
3210
+ stickyHeader = input(false, ...(ngDevMode ? [{ debugName: "stickyHeader" }] : /* istanbul ignore next */ []));
3211
+ emptyTitle = input('No records found', ...(ngDevMode ? [{ debugName: "emptyTitle" }] : /* istanbul ignore next */ []));
3212
+ emptyDescription = input('This dataset has no rows yet. Connect data or add records to populate the table.', ...(ngDevMode ? [{ debugName: "emptyDescription" }] : /* istanbul ignore next */ []));
3213
+ rowActionLabel = input(undefined, ...(ngDevMode ? [{ debugName: "rowActionLabel" }] : /* istanbul ignore next */ []));
3214
+ rowActionHeader = input('Actions', ...(ngDevMode ? [{ debugName: "rowActionHeader" }] : /* istanbul ignore next */ []));
3215
+ rowActionAriaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "rowActionAriaLabel" }] : /* istanbul ignore next */ []));
3216
+ rowActions = input([], ...(ngDevMode ? [{ debugName: "rowActions" }] : /* istanbul ignore next */ []));
3217
+ mfSortChange = output();
3218
+ mfSearchChange = output();
3219
+ mfPageChange = output();
3220
+ mfAction = output();
3221
+ mfRowAction = output();
3222
+ mfRowClick = output();
3223
+ constructor() {
3224
+ effect(() => {
3225
+ this.localSearchTerm.set(this.searchValue());
3226
+ });
3227
+ effect(() => {
3228
+ this.localPageIndex.set(this.pageIndex());
3229
+ });
3230
+ effect(() => {
3231
+ this.localPageSize.set(this.pageSize());
3232
+ });
3233
+ effect(() => {
3234
+ const totalRows = this.filteredRows().length;
3235
+ const pageSize = Math.max(this.localPageSize(), 1);
3236
+ const maxPageIndex = Math.max(Math.ceil(totalRows / pageSize) - 1, 0);
3237
+ if (this.localPageIndex() > maxPageIndex) {
3238
+ this.localPageIndex.set(maxPageIndex);
3239
+ }
3240
+ });
3241
+ }
3242
+ visibleColumns = computed(() => this.columns().filter((column) => !column.hidden), ...(ngDevMode ? [{ debugName: "visibleColumns" }] : /* istanbul ignore next */ []));
3243
+ searchTerm = computed(() => this.localSearchTerm().trim(), ...(ngDevMode ? [{ debugName: "searchTerm" }] : /* istanbul ignore next */ []));
3244
+ showsToolbar = computed(() => Boolean(this.title() || this.description() || this.showSearch()), ...(ngDevMode ? [{ debugName: "showsToolbar" }] : /* istanbul ignore next */ []));
3245
+ resolvedActionHeader = computed(() => this.rowActionHeader(), ...(ngDevMode ? [{ debugName: "resolvedActionHeader" }] : /* istanbul ignore next */ []));
3246
+ resolvedActions = computed(() => {
3247
+ const actions = [...this.rowActions()];
3248
+ if (this.rowActionLabel()) {
3249
+ actions.unshift({
3250
+ key: 'legacy-action',
3251
+ label: this.rowActionLabel(),
3252
+ tone: 'neutral',
3253
+ ariaLabel: this.rowActionAriaLabel(),
3254
+ legacy: true,
3255
+ });
3256
+ }
3257
+ return actions;
3258
+ }, ...(ngDevMode ? [{ debugName: "resolvedActions" }] : /* istanbul ignore next */ []));
3259
+ hasActions = computed(() => this.resolvedActions().length > 0, ...(ngDevMode ? [{ debugName: "hasActions" }] : /* istanbul ignore next */ []));
3260
+ usesActionMenu = computed(() => this.resolvedActions().length > 1, ...(ngDevMode ? [{ debugName: "usesActionMenu" }] : /* istanbul ignore next */ []));
3261
+ displayedColumns = computed(() => {
3262
+ const columns = this.visibleColumns().map((column) => column.key);
3263
+ if (this.hasActions()) {
3264
+ columns.push(this.actionColumnKey);
3265
+ }
3266
+ return columns;
3267
+ }, ...(ngDevMode ? [{ debugName: "displayedColumns" }] : /* istanbul ignore next */ []));
3268
+ filteredRows = computed(() => {
3269
+ const query = this.searchTerm().toLowerCase();
3270
+ const rows = this.data();
3271
+ if (!query) {
3272
+ return rows;
3273
+ }
3274
+ const searchableColumns = this.visibleColumns().filter((column) => column.searchable !== false);
3275
+ return rows.filter((row) => searchableColumns.some((column) => this.getSearchValue(column, row).toLowerCase().includes(query)));
3276
+ }, ...(ngDevMode ? [{ debugName: "filteredRows" }] : /* istanbul ignore next */ []));
3277
+ sortedRows = computed(() => {
3278
+ const rows = [...this.filteredRows()];
3279
+ const { active, direction } = this.sortState();
3280
+ if (!active || !direction) {
3281
+ return rows;
3282
+ }
3283
+ const column = this.visibleColumns().find((item) => item.key === active);
3284
+ if (!column) {
3285
+ return rows;
3286
+ }
3287
+ return rows.sort((left, right) => {
3288
+ const leftValue = this.normalizeSortValue(column, left);
3289
+ const rightValue = this.normalizeSortValue(column, right);
3290
+ if (leftValue < rightValue) {
3291
+ return direction === 'asc' ? -1 : 1;
3292
+ }
3293
+ if (leftValue > rightValue) {
3294
+ return direction === 'asc' ? 1 : -1;
3295
+ }
3296
+ return 0;
3297
+ });
3298
+ }, ...(ngDevMode ? [{ debugName: "sortedRows" }] : /* istanbul ignore next */ []));
3299
+ paginatedRows = computed(() => {
3300
+ if (!this.showPaginator()) {
3301
+ return this.sortedRows();
3302
+ }
3303
+ const size = Math.max(this.localPageSize(), 1);
3304
+ const start = this.localPageIndex() * size;
3305
+ return this.sortedRows().slice(start, start + size);
3306
+ }, ...(ngDevMode ? [{ debugName: "paginatedRows" }] : /* istanbul ignore next */ []));
3307
+ resultSummary = computed(() => {
3308
+ const filtered = this.filteredRows().length;
3309
+ const total = this.data().length;
3310
+ if (filtered === total) {
3311
+ return `${total} records`;
3312
+ }
3313
+ return `${filtered} of ${total} records`;
3314
+ }, ...(ngDevMode ? [{ debugName: "resultSummary" }] : /* istanbul ignore next */ []));
3315
+ onSearchChange(value) {
3316
+ this.localSearchTerm.set(value);
3317
+ this.localPageIndex.set(0);
3318
+ this.mfSearchChange.emit(value);
3319
+ }
3320
+ onSortChange(sort) {
3321
+ this.sortState.set(sort);
3322
+ this.localPageIndex.set(0);
3323
+ this.mfSortChange.emit(sort);
3324
+ }
3325
+ onPageChange(event) {
3326
+ this.localPageIndex.set(event.pageIndex);
3327
+ this.localPageSize.set(event.pageSize);
3328
+ this.mfPageChange.emit(event);
3329
+ }
3330
+ onActionClick(action, row) {
3331
+ if (action.legacy) {
3332
+ this.mfRowAction.emit(row);
3333
+ this.mfRowClick.emit(row);
3334
+ }
3335
+ this.mfAction.emit({ action, row });
3336
+ }
3337
+ renderCell(column, row) {
3338
+ const value = this.getRawValue(column, row);
3339
+ if (column.formatter) {
3340
+ return column.formatter(value, row);
3341
+ }
3342
+ if (value === null || value === undefined || value === '') {
3343
+ return column.emptyValue ?? '-';
3344
+ }
3345
+ if (column.type === 'number' && typeof value === 'number') {
3346
+ return new Intl.NumberFormat('es-ES').format(value);
3347
+ }
3348
+ if (column.type === 'date') {
3349
+ const date = value instanceof Date ? value : new Date(String(value));
3350
+ if (!Number.isNaN(date.getTime())) {
3351
+ return new Intl.DateTimeFormat('es-ES').format(date);
3352
+ }
3353
+ }
3354
+ return String(value);
3355
+ }
3356
+ headerCellClasses(column) {
3357
+ return [
3358
+ 'mf-table__header-cell',
3359
+ `mf-table__cell--align-${column.align ?? 'start'}`,
3360
+ ].join(' ');
3361
+ }
3362
+ cellClasses(column) {
3363
+ const classes = [
3364
+ 'mf-table__cell',
3365
+ `mf-table__cell--align-${column.align ?? 'start'}`,
3366
+ ];
3367
+ if (column.truncate) {
3368
+ classes.push('mf-table__cell--truncate');
3369
+ }
3370
+ return classes.join(' ');
3371
+ }
3372
+ badgeClasses(column, row) {
3373
+ return [
3374
+ 'mf-table__badge',
3375
+ `mf-table__badge--${this.resolveBadgeTone(column, row)}`,
3376
+ ].join(' ');
3377
+ }
3378
+ actionClasses(action) {
3379
+ return [
3380
+ 'mf-table__action',
3381
+ `mf-table__action--${action.tone ?? 'neutral'}`,
3382
+ ].join(' ');
3383
+ }
3384
+ isActionDisabled(action, row) {
3385
+ return typeof action.disabled === 'function'
3386
+ ? action.disabled(row)
3387
+ : Boolean(action.disabled);
3388
+ }
3389
+ getActionAriaLabel(action, row) {
3390
+ return action.ariaLabel?.(row) ?? action.label ?? null;
3391
+ }
3392
+ getRowMenuAriaLabel(row) {
3393
+ const primaryColumn = this.visibleColumns()[0];
3394
+ const primaryLabel = primaryColumn
3395
+ ? this.renderCell(primaryColumn, row)
3396
+ : 'this row';
3397
+ return `Open actions for ${primaryLabel}`;
3398
+ }
3399
+ emptyDescriptionText() {
3400
+ if (this.searchTerm()) {
3401
+ return 'No rows match the current search. Try a broader query or clear the filter.';
3402
+ }
3403
+ return this.emptyDescription();
3404
+ }
3405
+ hostClasses = computed(() => ['mf-table', `mf-table--${this.variant()}`, `mf-table--${this.density()}`].join(' '), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
3406
+ getCellValue(column, row) {
3407
+ return column.sortAccessor ? column.sortAccessor(row) : this.getRawValue(column, row);
3408
+ }
3409
+ getRawValue(column, row) {
3410
+ return row[column.key];
3411
+ }
3412
+ getSearchValue(column, row) {
3413
+ if (column.searchAccessor) {
3414
+ return column.searchAccessor(row);
3415
+ }
3416
+ return this.renderCell(column, row);
3417
+ }
3418
+ normalizeSortValue(column, row) {
3419
+ const value = this.getCellValue(column, row);
3420
+ if (value === null || value === undefined || value === '') {
3421
+ return '';
3422
+ }
3423
+ if (column.type === 'number') {
3424
+ return typeof value === 'number' ? value : Number(value);
3425
+ }
3426
+ if (column.type === 'date') {
3427
+ const date = value instanceof Date ? value : new Date(String(value));
3428
+ return Number.isNaN(date.getTime()) ? '' : date.getTime();
3429
+ }
3430
+ if (typeof value === 'number') {
3431
+ return value;
3432
+ }
3433
+ return String(value).toLocaleLowerCase();
3434
+ }
3435
+ resolveBadgeTone(column, row) {
3436
+ const value = row[column.key];
3437
+ if (typeof column.badgeTone === 'function') {
3438
+ return column.badgeTone(value, row);
3439
+ }
3440
+ if (column.badgeTone) {
3441
+ return column.badgeTone;
3442
+ }
3443
+ return column.badgeTones?.[String(value)] ?? 'neutral';
3444
+ }
3445
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3446
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfTableComponent, isStandalone: true, selector: "mf-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, searchLabel: { classPropertyName: "searchLabel", publicName: "searchLabel", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, searchValue: { classPropertyName: "searchValue", publicName: "searchValue", isSignal: true, isRequired: false, transformFunction: null }, showPaginator: { classPropertyName: "showPaginator", publicName: "showPaginator", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageIndex: { classPropertyName: "pageIndex", publicName: "pageIndex", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, showFirstLastButtons: { classPropertyName: "showFirstLastButtons", publicName: "showFirstLastButtons", isSignal: true, isRequired: false, transformFunction: null }, hidePageSize: { classPropertyName: "hidePageSize", publicName: "hidePageSize", isSignal: true, isRequired: false, transformFunction: null }, stickyHeader: { classPropertyName: "stickyHeader", publicName: "stickyHeader", isSignal: true, isRequired: false, transformFunction: null }, emptyTitle: { classPropertyName: "emptyTitle", publicName: "emptyTitle", isSignal: true, isRequired: false, transformFunction: null }, emptyDescription: { classPropertyName: "emptyDescription", publicName: "emptyDescription", isSignal: true, isRequired: false, transformFunction: null }, rowActionLabel: { classPropertyName: "rowActionLabel", publicName: "rowActionLabel", isSignal: true, isRequired: false, transformFunction: null }, rowActionHeader: { classPropertyName: "rowActionHeader", publicName: "rowActionHeader", isSignal: true, isRequired: false, transformFunction: null }, rowActionAriaLabel: { classPropertyName: "rowActionAriaLabel", publicName: "rowActionAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, rowActions: { classPropertyName: "rowActions", publicName: "rowActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfSortChange: "mfSortChange", mfSearchChange: "mfSearchChange", mfPageChange: "mfPageChange", mfAction: "mfAction", mfRowAction: "mfRowAction", mfRowClick: "mfRowClick" }, ngImport: i0, template: `
3447
+ <section [class]="hostClasses()">
3448
+ @if (showsToolbar()) {
3449
+ <header class="mf-table__toolbar">
3450
+ <div class="mf-table__intro">
3451
+ @if (title()) {
3452
+ <h2 class="mf-table__title">{{ title() }}</h2>
3453
+ }
3454
+ @if (description()) {
3455
+ <p class="mf-table__description">{{ description() }}</p>
3456
+ }
3457
+ <div class="mf-table__meta">
3458
+ <span class="mf-table__metric">{{ resultSummary() }}</span>
3459
+ @if (searchTerm()) {
3460
+ <span class="mf-table__metric mf-table__metric--accent">
3461
+ Filter active
3462
+ </span>
3463
+ }
3464
+ @if (sortState().direction) {
3465
+ <span class="mf-table__metric">
3466
+ Sorted by {{ sortState().active }}
3467
+ </span>
3468
+ }
3469
+ </div>
3470
+ </div>
3471
+
3472
+ @if (showSearch()) {
3473
+ <div class="mf-table__search">
3474
+ <mf-input
3475
+ [label]="searchLabel()"
3476
+ [ariaLabel]="searchLabel()"
3477
+ [placeholder]="searchPlaceholder()"
3478
+ [value]="localSearchTerm()"
3479
+ [type]="'search'"
3480
+ [leadingIcon]="'search'"
3481
+ [fullWidth]="true"
3482
+ (mfInput)="onSearchChange($event)"
3483
+ />
3484
+ </div>
3485
+ }
3486
+ </header>
3487
+ }
3488
+
3489
+ @if (filteredRows().length > 0) {
3490
+ <div class="mf-table__surface">
3491
+ <div class="mf-table__wrapper">
3492
+ <table
3493
+ mat-table
3494
+ [dataSource]="paginatedRows()"
3495
+ matSort
3496
+ [matSortActive]="sortState().active"
3497
+ [matSortDirection]="sortState().direction"
3498
+ class="mf-table__table"
3499
+ (matSortChange)="onSortChange($event)"
3500
+ >
3501
+ @for (column of visibleColumns(); track column.key) {
3502
+ <ng-container [matColumnDef]="column.key">
3503
+ @if (column.sortable) {
3504
+ <th
3505
+ mat-header-cell
3506
+ *matHeaderCellDef
3507
+ mat-sort-header
3508
+ [style.width]="column.width || null"
3509
+ [class]="headerCellClasses(column)"
3510
+ >
3511
+ {{ column.header }}
3512
+ </th>
3513
+ } @else {
3514
+ <th
3515
+ mat-header-cell
3516
+ *matHeaderCellDef
3517
+ [style.width]="column.width || null"
3518
+ [class]="headerCellClasses(column)"
3519
+ >
3520
+ {{ column.header }}
3521
+ </th>
3522
+ }
3523
+
3524
+ <td
3525
+ mat-cell
3526
+ *matCellDef="let row"
3527
+ [style.width]="column.width || null"
3528
+ [class]="cellClasses(column)"
3529
+ >
3530
+ @if (column.type === 'badge') {
3531
+ <span [class]="badgeClasses(column, row)">
3532
+ {{ renderCell(column, row) }}
3533
+ </span>
3534
+ } @else {
3535
+ <span class="mf-table__cell-text">
3536
+ {{ renderCell(column, row) }}
3537
+ </span>
3538
+ }
3539
+ </td>
3540
+ </ng-container>
3541
+ }
3542
+
3543
+ @if (hasActions()) {
3544
+ <ng-container [matColumnDef]="actionColumnKey">
3545
+ <th
3546
+ mat-header-cell
3547
+ *matHeaderCellDef
3548
+ class="mf-table__actions-header"
3549
+ >
3550
+ {{ resolvedActionHeader() }}
3551
+ </th>
3552
+ <td
3553
+ mat-cell
3554
+ *matCellDef="let row"
3555
+ class="mf-table__actions-cell"
3556
+ >
3557
+ @if (usesActionMenu()) {
3558
+ <button
3559
+ mat-icon-button
3560
+ type="button"
3561
+ class="mf-table__action-menu-trigger"
3562
+ [matMenuTriggerFor]="actionMenu"
3563
+ [attr.aria-label]="getRowMenuAriaLabel(row)"
3564
+ >
3565
+ <mat-icon aria-hidden="true">more_vert</mat-icon>
3566
+ </button>
3567
+ <mat-menu
3568
+ #actionMenu="matMenu"
3569
+ xPosition="before"
3570
+ class="mf-table__action-menu"
3571
+ >
3572
+ @for (action of resolvedActions(); track action.key) {
3573
+ <button
3574
+ mat-menu-item
3575
+ [disabled]="isActionDisabled(action, row)"
3576
+ [attr.aria-label]="getActionAriaLabel(action, row)"
3577
+ (click)="onActionClick(action, row)"
3578
+ >
3579
+ @if (action.icon) {
3580
+ <mat-icon aria-hidden="true">{{ action.icon }}</mat-icon>
3581
+ }
3582
+ <span>{{ action.label }}</span>
3583
+ </button>
3584
+ }
3585
+ </mat-menu>
3586
+ } @else {
3587
+ <div class="mf-table__action-group">
3588
+ @for (action of resolvedActions(); track action.key) {
3589
+ <button
3590
+ mat-stroked-button
3591
+ type="button"
3592
+ [class]="actionClasses(action)"
3593
+ [disabled]="isActionDisabled(action, row)"
3594
+ [attr.aria-label]="getActionAriaLabel(action, row)"
3595
+ (click)="onActionClick(action, row)"
3596
+ >
3597
+ @if (action.icon) {
3598
+ <mat-icon aria-hidden="true">{{ action.icon }}</mat-icon>
3599
+ }
3600
+ <span>{{ action.label }}</span>
3601
+ </button>
3602
+ }
3603
+ </div>
3604
+ }
3605
+ </td>
3606
+ </ng-container>
3607
+ }
3608
+
3609
+ <tr
3610
+ mat-header-row
3611
+ *matHeaderRowDef="displayedColumns(); sticky: stickyHeader()"
3612
+ ></tr>
3613
+ <tr
3614
+ mat-row
3615
+ *matRowDef="let row; columns: displayedColumns()"
3616
+ class="mf-table__row"
3617
+ ></tr>
3618
+ </table>
3619
+ </div>
3620
+
3621
+ @if (showPaginator()) {
3622
+ <footer class="mf-table__footer">
3623
+ <mf-paginator
3624
+ [length]="filteredRows().length"
3625
+ [pageSize]="localPageSize()"
3626
+ [pageIndex]="localPageIndex()"
3627
+ [pageSizeOptions]="pageSizeOptions()"
3628
+ [showFirstLastButtons]="showFirstLastButtons()"
3629
+ [hidePageSize]="hidePageSize()"
3630
+ (mfPageChange)="onPageChange($event)"
3631
+ />
3632
+ </footer>
3633
+ }
3634
+ </div>
3635
+ } @else {
3636
+ <div class="mf-table__empty">
3637
+ <div class="mf-table__empty-icon">
3638
+ <mat-icon aria-hidden="true">table_rows</mat-icon>
3639
+ </div>
3640
+ <h3 class="mf-table__empty-title">{{ emptyTitle() }}</h3>
3641
+ <p class="mf-table__empty-description">{{ emptyDescriptionText() }}</p>
3642
+ </div>
3643
+ }
3644
+ </section>
3645
+ `, isInline: true, styles: [":host{display:block}.mf-table{border-radius:var(--mf-radius-xl);border:1px solid color-mix(in srgb,var(--mf-color-border) 70%,white);background:linear-gradient(180deg,#fffffffa,#f7fafcf5),linear-gradient(135deg,var(--mf-color-primary-50),var(--mf-color-neutral-0));box-shadow:var(--mf-shadow-lg);overflow:hidden}.mf-table__toolbar{display:grid;gap:var(--mf-space-4);padding:var(--mf-space-6);background:radial-gradient(circle at top left,rgb(20 184 166 / .08),transparent 45%),linear-gradient(135deg,var(--mf-color-neutral-0),var(--mf-color-primary-50))}.mf-table__intro{display:grid;gap:var(--mf-space-2)}.mf-table__title{margin:0;font-family:var(--mf-font-display);font-size:var(--mf-text-2xl);font-weight:var(--mf-weight-bold);line-height:var(--mf-leading-tight);color:var(--mf-color-neutral-900)}.mf-table__description{max-width:70ch;margin:0;color:var(--mf-color-neutral-600)}.mf-table__meta{display:flex;flex-wrap:wrap;gap:var(--mf-space-2)}.mf-table__metric{display:inline-flex;align-items:center;min-height:32px;padding:0 var(--mf-space-3);border-radius:var(--mf-radius-full);border:1px solid var(--mf-color-border);background-color:#ffffffc7;color:var(--mf-color-neutral-600);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-medium)}.mf-table__metric--accent{border-color:color-mix(in srgb,var(--mf-color-brand) 35%,white);background-color:var(--mf-color-brand-light);color:var(--mf-color-brand)}.mf-table__search{width:100%;max-width:none}.mf-table__search mf-input{display:block;width:100%}.mf-table__surface{display:grid;gap:var(--mf-space-4);padding:0 var(--mf-space-4) var(--mf-space-4)}.mf-table__wrapper{overflow-x:auto;border:1px solid var(--mf-color-border);border-radius:var(--mf-radius-lg);background-color:#ffffffb3}.mf-table__table,.mf-table .mat-mdc-table{width:100%;min-width:720px;background:transparent!important;font-family:var(--mf-font-base)!important}.mf-table .mat-mdc-header-row{background-color:#f7fafcf0!important}.mf-table .mat-mdc-header-cell{font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important;font-weight:var(--mf-weight-bold)!important;letter-spacing:.03em;text-transform:uppercase;color:var(--mf-color-neutral-600)!important;background-color:transparent!important;border-bottom-color:var(--mf-color-border)!important;border-bottom-width:1px!important}.mf-table .mat-mdc-cell{font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important;color:var(--mf-color-on-surface)!important;background-color:transparent!important;border-bottom-color:var(--mf-color-border)!important}.mf-table .mat-mdc-row:hover{background-color:#f0fdfad1!important}.mf-table .mat-mdc-row:last-child .mat-mdc-cell{border-bottom:none!important}.mf-table__header-cell,.mf-table__cell{padding-right:var(--mf-space-4)!important;padding-left:var(--mf-space-4)!important}.mf-table--compact .mf-table__header-cell,.mf-table--compact .mf-table__cell{padding-top:var(--mf-space-2)!important;padding-bottom:var(--mf-space-2)!important}.mf-table--comfortable .mf-table__header-cell,.mf-table--comfortable .mf-table__cell{padding-top:var(--mf-space-3)!important;padding-bottom:var(--mf-space-3)!important}.mf-table--spacious .mf-table__header-cell,.mf-table--spacious .mf-table__cell{padding-top:var(--mf-space-4)!important;padding-bottom:var(--mf-space-4)!important}.mf-table__cell-text{display:block}.mf-table__cell--truncate .mf-table__cell-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mf-table__cell--align-start{text-align:left}.mf-table__cell--align-center{text-align:center}.mf-table__cell--align-end{text-align:right}.mf-table__badge{display:inline-flex;align-items:center;justify-content:center;min-height:28px;padding:0 var(--mf-space-3);border-radius:var(--mf-radius-full);border:1px solid transparent;font-size:var(--mf-text-xs);font-weight:var(--mf-weight-bold);letter-spacing:.02em;white-space:nowrap}.mf-table__badge--brand{background-color:var(--mf-color-brand-light);border-color:color-mix(in srgb,var(--mf-color-brand) 30%,white);color:var(--mf-color-brand)}.mf-table__badge--success{background-color:#dcfce7e6;border-color:#22c55e47;color:#15803d}.mf-table__badge--warning{background-color:#fef3c7f2;border-color:#f59e0b52;color:#b45309}.mf-table__badge--error{background-color:#fee2e2f2;border-color:#dc262647;color:var(--mf-color-error-700)}.mf-table__badge--neutral{background-color:var(--mf-color-neutral-100);border-color:var(--mf-color-border);color:var(--mf-color-neutral-600)}.mf-table--striped .mat-mdc-row:nth-child(2n){background-color:#f8fafceb}.mf-table--bordered .mat-mdc-cell,.mf-table--bordered .mat-mdc-header-cell{border-right:1px solid var(--mf-color-border)!important}.mf-table--bordered .mat-mdc-cell:last-child,.mf-table--bordered .mat-mdc-header-cell:last-child{border-right:none!important}.mf-table .mat-sort-header-arrow{color:var(--mf-color-brand)!important}.mf-table__actions-header,.mf-table__actions-cell{width:1%;white-space:nowrap}.mf-table__action-group{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--mf-space-4)}.mf-table__action{min-width:0!important;display:inline-flex!important;align-items:center;gap:var(--mf-space-2);border-radius:var(--mf-radius-full)!important;font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important;font-weight:var(--mf-weight-medium)!important}.mf-table__action-menu-trigger{display:inline-flex!important;align-items:center;justify-content:center;width:40px;height:40px;border:1px solid var(--mf-color-border);border-radius:var(--mf-radius-full)!important;background-color:#ffffffe0!important;color:var(--mf-color-neutral-600)!important}.mf-table__action-menu-trigger:hover{background-color:var(--mf-color-brand-light)!important;color:var(--mf-color-brand)!important}.mf-table__action-menu-trigger .mat-icon{margin:0;width:20px;height:20px;font-size:20px}.mf-table__action .mat-icon{margin:0;width:18px;height:18px;font-size:18px}.mf-table__action--primary{border-color:color-mix(in srgb,var(--mf-color-brand) 30%,white)!important;background-color:var(--mf-color-brand-light)!important;color:var(--mf-color-brand)!important}.mf-table__action--neutral{border-color:var(--mf-color-border)!important;background-color:#ffffffe6!important;color:var(--mf-color-neutral-600)!important}.mf-table__action--danger{border-color:#dc262633!important;background-color:#fef2f2eb!important;color:var(--mf-color-error-700)!important}.mf-table__footer{padding:0 var(--mf-space-2) var(--mf-space-2);border-top:1px solid var(--mf-color-border);background-color:#ffffffb8;border:1px solid var(--mf-color-border);border-radius:var(--mf-radius-lg)}.mf-table__empty{display:grid;justify-items:center;gap:var(--mf-space-3);padding:var(--mf-space-12) var(--mf-space-6);text-align:center;background:radial-gradient(circle at top,rgb(20 184 166 / .08),transparent 38%),linear-gradient(180deg,var(--mf-color-neutral-0),var(--mf-color-primary-50))}.mf-table__empty-icon{display:grid;place-items:center;width:68px;height:68px;border-radius:50%;border:1px solid color-mix(in srgb,var(--mf-color-brand) 18%,white);background-color:#ffffffe0;color:var(--mf-color-brand);box-shadow:var(--mf-shadow-md)}.mf-table__empty-icon .mat-icon{width:30px;height:30px;font-size:30px}.mf-table__empty-title{margin:0;font-family:var(--mf-font-display);font-size:var(--mf-text-xl);color:var(--mf-color-neutral-900)}.mf-table__empty-description{max-width:56ch;margin:0;color:var(--mf-color-neutral-600)}@media(max-width:720px){.mf-table__toolbar{padding:var(--mf-space-4)}.mf-table__search{max-width:none}.mf-table__surface{padding-right:var(--mf-space-4);padding-left:var(--mf-space-4)}.mf-table__footer{padding-right:var(--mf-space-2);padding-left:var(--mf-space-2)}}\n"], dependencies: [{ kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i1$i.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i1$i.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i1$i.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i1$i.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i1$i.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i1$i.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i1$i.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i1$i.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i1$i.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i1$i.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: MatSortModule }, { kind: "directive", type: i2$3.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i2$3.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i1$3.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i1$3.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatMenuModule }, { kind: "component", type: i1$b.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i1$b.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i1$b.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "component", type: MfInputComponent, selector: "mf-input", inputs: ["id", "label", "ariaLabel", "ariaLabelledby", "ariaDescribedby", "placeholder", "type", "size", "value", "disabled", "readonly", "required", "hint", "error", "leadingIcon", "trailingIcon", "fullWidth"], outputs: ["mfInput", "mfBlur"] }, { kind: "component", type: MfPaginatorComponent, selector: "mf-paginator", inputs: ["length", "pageSize", "pageIndex", "pageSizeOptions", "showFirstLastButtons", "hidePageSize"], outputs: ["mfPageChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3646
+ }
3647
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfTableComponent, decorators: [{
3648
+ type: Component,
3649
+ args: [{ selector: 'mf-table', imports: [
3650
+ MatTableModule,
3651
+ MatSortModule,
3652
+ MatButtonModule,
3653
+ MatIconModule,
3654
+ MatMenuModule,
3655
+ MfInputComponent,
3656
+ MfPaginatorComponent,
3657
+ ], template: `
3658
+ <section [class]="hostClasses()">
3659
+ @if (showsToolbar()) {
3660
+ <header class="mf-table__toolbar">
3661
+ <div class="mf-table__intro">
3662
+ @if (title()) {
3663
+ <h2 class="mf-table__title">{{ title() }}</h2>
3664
+ }
3665
+ @if (description()) {
3666
+ <p class="mf-table__description">{{ description() }}</p>
3667
+ }
3668
+ <div class="mf-table__meta">
3669
+ <span class="mf-table__metric">{{ resultSummary() }}</span>
3670
+ @if (searchTerm()) {
3671
+ <span class="mf-table__metric mf-table__metric--accent">
3672
+ Filter active
3673
+ </span>
3674
+ }
3675
+ @if (sortState().direction) {
3676
+ <span class="mf-table__metric">
3677
+ Sorted by {{ sortState().active }}
3678
+ </span>
3679
+ }
3680
+ </div>
3681
+ </div>
3682
+
3683
+ @if (showSearch()) {
3684
+ <div class="mf-table__search">
3685
+ <mf-input
3686
+ [label]="searchLabel()"
3687
+ [ariaLabel]="searchLabel()"
3688
+ [placeholder]="searchPlaceholder()"
3689
+ [value]="localSearchTerm()"
3690
+ [type]="'search'"
3691
+ [leadingIcon]="'search'"
3692
+ [fullWidth]="true"
3693
+ (mfInput)="onSearchChange($event)"
3694
+ />
3695
+ </div>
3696
+ }
3697
+ </header>
3698
+ }
3699
+
3700
+ @if (filteredRows().length > 0) {
3701
+ <div class="mf-table__surface">
3702
+ <div class="mf-table__wrapper">
3703
+ <table
3704
+ mat-table
3705
+ [dataSource]="paginatedRows()"
3706
+ matSort
3707
+ [matSortActive]="sortState().active"
3708
+ [matSortDirection]="sortState().direction"
3709
+ class="mf-table__table"
3710
+ (matSortChange)="onSortChange($event)"
3711
+ >
3712
+ @for (column of visibleColumns(); track column.key) {
3713
+ <ng-container [matColumnDef]="column.key">
3714
+ @if (column.sortable) {
3715
+ <th
3716
+ mat-header-cell
3717
+ *matHeaderCellDef
3718
+ mat-sort-header
3719
+ [style.width]="column.width || null"
3720
+ [class]="headerCellClasses(column)"
3721
+ >
3722
+ {{ column.header }}
3723
+ </th>
3724
+ } @else {
3725
+ <th
3726
+ mat-header-cell
3727
+ *matHeaderCellDef
3728
+ [style.width]="column.width || null"
3729
+ [class]="headerCellClasses(column)"
3730
+ >
3731
+ {{ column.header }}
3732
+ </th>
3733
+ }
3734
+
3735
+ <td
3736
+ mat-cell
3737
+ *matCellDef="let row"
3738
+ [style.width]="column.width || null"
3739
+ [class]="cellClasses(column)"
3740
+ >
3741
+ @if (column.type === 'badge') {
3742
+ <span [class]="badgeClasses(column, row)">
3743
+ {{ renderCell(column, row) }}
3744
+ </span>
3745
+ } @else {
3746
+ <span class="mf-table__cell-text">
3747
+ {{ renderCell(column, row) }}
3748
+ </span>
3749
+ }
3750
+ </td>
3751
+ </ng-container>
3752
+ }
3753
+
3754
+ @if (hasActions()) {
3755
+ <ng-container [matColumnDef]="actionColumnKey">
3756
+ <th
3757
+ mat-header-cell
3758
+ *matHeaderCellDef
3759
+ class="mf-table__actions-header"
3760
+ >
3761
+ {{ resolvedActionHeader() }}
3762
+ </th>
3763
+ <td
3764
+ mat-cell
3765
+ *matCellDef="let row"
3766
+ class="mf-table__actions-cell"
3767
+ >
3768
+ @if (usesActionMenu()) {
3769
+ <button
3770
+ mat-icon-button
3771
+ type="button"
3772
+ class="mf-table__action-menu-trigger"
3773
+ [matMenuTriggerFor]="actionMenu"
3774
+ [attr.aria-label]="getRowMenuAriaLabel(row)"
3775
+ >
3776
+ <mat-icon aria-hidden="true">more_vert</mat-icon>
3777
+ </button>
3778
+ <mat-menu
3779
+ #actionMenu="matMenu"
3780
+ xPosition="before"
3781
+ class="mf-table__action-menu"
3782
+ >
3783
+ @for (action of resolvedActions(); track action.key) {
3784
+ <button
3785
+ mat-menu-item
3786
+ [disabled]="isActionDisabled(action, row)"
3787
+ [attr.aria-label]="getActionAriaLabel(action, row)"
3788
+ (click)="onActionClick(action, row)"
3789
+ >
3790
+ @if (action.icon) {
3791
+ <mat-icon aria-hidden="true">{{ action.icon }}</mat-icon>
3792
+ }
3793
+ <span>{{ action.label }}</span>
3794
+ </button>
3795
+ }
3796
+ </mat-menu>
3797
+ } @else {
3798
+ <div class="mf-table__action-group">
3799
+ @for (action of resolvedActions(); track action.key) {
3800
+ <button
3801
+ mat-stroked-button
3802
+ type="button"
3803
+ [class]="actionClasses(action)"
3804
+ [disabled]="isActionDisabled(action, row)"
3805
+ [attr.aria-label]="getActionAriaLabel(action, row)"
3806
+ (click)="onActionClick(action, row)"
3807
+ >
3808
+ @if (action.icon) {
3809
+ <mat-icon aria-hidden="true">{{ action.icon }}</mat-icon>
3810
+ }
3811
+ <span>{{ action.label }}</span>
3812
+ </button>
3813
+ }
3814
+ </div>
3815
+ }
3816
+ </td>
3817
+ </ng-container>
3818
+ }
3819
+
3820
+ <tr
3821
+ mat-header-row
3822
+ *matHeaderRowDef="displayedColumns(); sticky: stickyHeader()"
3823
+ ></tr>
3824
+ <tr
3825
+ mat-row
3826
+ *matRowDef="let row; columns: displayedColumns()"
3827
+ class="mf-table__row"
3828
+ ></tr>
3829
+ </table>
3830
+ </div>
3831
+
3832
+ @if (showPaginator()) {
3833
+ <footer class="mf-table__footer">
3834
+ <mf-paginator
3835
+ [length]="filteredRows().length"
3836
+ [pageSize]="localPageSize()"
3837
+ [pageIndex]="localPageIndex()"
3838
+ [pageSizeOptions]="pageSizeOptions()"
3839
+ [showFirstLastButtons]="showFirstLastButtons()"
3840
+ [hidePageSize]="hidePageSize()"
3841
+ (mfPageChange)="onPageChange($event)"
3842
+ />
3843
+ </footer>
3844
+ }
3845
+ </div>
3846
+ } @else {
3847
+ <div class="mf-table__empty">
3848
+ <div class="mf-table__empty-icon">
3849
+ <mat-icon aria-hidden="true">table_rows</mat-icon>
3850
+ </div>
3851
+ <h3 class="mf-table__empty-title">{{ emptyTitle() }}</h3>
3852
+ <p class="mf-table__empty-description">{{ emptyDescriptionText() }}</p>
3853
+ </div>
3854
+ }
3855
+ </section>
3856
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.mf-table{border-radius:var(--mf-radius-xl);border:1px solid color-mix(in srgb,var(--mf-color-border) 70%,white);background:linear-gradient(180deg,#fffffffa,#f7fafcf5),linear-gradient(135deg,var(--mf-color-primary-50),var(--mf-color-neutral-0));box-shadow:var(--mf-shadow-lg);overflow:hidden}.mf-table__toolbar{display:grid;gap:var(--mf-space-4);padding:var(--mf-space-6);background:radial-gradient(circle at top left,rgb(20 184 166 / .08),transparent 45%),linear-gradient(135deg,var(--mf-color-neutral-0),var(--mf-color-primary-50))}.mf-table__intro{display:grid;gap:var(--mf-space-2)}.mf-table__title{margin:0;font-family:var(--mf-font-display);font-size:var(--mf-text-2xl);font-weight:var(--mf-weight-bold);line-height:var(--mf-leading-tight);color:var(--mf-color-neutral-900)}.mf-table__description{max-width:70ch;margin:0;color:var(--mf-color-neutral-600)}.mf-table__meta{display:flex;flex-wrap:wrap;gap:var(--mf-space-2)}.mf-table__metric{display:inline-flex;align-items:center;min-height:32px;padding:0 var(--mf-space-3);border-radius:var(--mf-radius-full);border:1px solid var(--mf-color-border);background-color:#ffffffc7;color:var(--mf-color-neutral-600);font-size:var(--mf-text-sm);font-weight:var(--mf-weight-medium)}.mf-table__metric--accent{border-color:color-mix(in srgb,var(--mf-color-brand) 35%,white);background-color:var(--mf-color-brand-light);color:var(--mf-color-brand)}.mf-table__search{width:100%;max-width:none}.mf-table__search mf-input{display:block;width:100%}.mf-table__surface{display:grid;gap:var(--mf-space-4);padding:0 var(--mf-space-4) var(--mf-space-4)}.mf-table__wrapper{overflow-x:auto;border:1px solid var(--mf-color-border);border-radius:var(--mf-radius-lg);background-color:#ffffffb3}.mf-table__table,.mf-table .mat-mdc-table{width:100%;min-width:720px;background:transparent!important;font-family:var(--mf-font-base)!important}.mf-table .mat-mdc-header-row{background-color:#f7fafcf0!important}.mf-table .mat-mdc-header-cell{font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important;font-weight:var(--mf-weight-bold)!important;letter-spacing:.03em;text-transform:uppercase;color:var(--mf-color-neutral-600)!important;background-color:transparent!important;border-bottom-color:var(--mf-color-border)!important;border-bottom-width:1px!important}.mf-table .mat-mdc-cell{font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important;color:var(--mf-color-on-surface)!important;background-color:transparent!important;border-bottom-color:var(--mf-color-border)!important}.mf-table .mat-mdc-row:hover{background-color:#f0fdfad1!important}.mf-table .mat-mdc-row:last-child .mat-mdc-cell{border-bottom:none!important}.mf-table__header-cell,.mf-table__cell{padding-right:var(--mf-space-4)!important;padding-left:var(--mf-space-4)!important}.mf-table--compact .mf-table__header-cell,.mf-table--compact .mf-table__cell{padding-top:var(--mf-space-2)!important;padding-bottom:var(--mf-space-2)!important}.mf-table--comfortable .mf-table__header-cell,.mf-table--comfortable .mf-table__cell{padding-top:var(--mf-space-3)!important;padding-bottom:var(--mf-space-3)!important}.mf-table--spacious .mf-table__header-cell,.mf-table--spacious .mf-table__cell{padding-top:var(--mf-space-4)!important;padding-bottom:var(--mf-space-4)!important}.mf-table__cell-text{display:block}.mf-table__cell--truncate .mf-table__cell-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mf-table__cell--align-start{text-align:left}.mf-table__cell--align-center{text-align:center}.mf-table__cell--align-end{text-align:right}.mf-table__badge{display:inline-flex;align-items:center;justify-content:center;min-height:28px;padding:0 var(--mf-space-3);border-radius:var(--mf-radius-full);border:1px solid transparent;font-size:var(--mf-text-xs);font-weight:var(--mf-weight-bold);letter-spacing:.02em;white-space:nowrap}.mf-table__badge--brand{background-color:var(--mf-color-brand-light);border-color:color-mix(in srgb,var(--mf-color-brand) 30%,white);color:var(--mf-color-brand)}.mf-table__badge--success{background-color:#dcfce7e6;border-color:#22c55e47;color:#15803d}.mf-table__badge--warning{background-color:#fef3c7f2;border-color:#f59e0b52;color:#b45309}.mf-table__badge--error{background-color:#fee2e2f2;border-color:#dc262647;color:var(--mf-color-error-700)}.mf-table__badge--neutral{background-color:var(--mf-color-neutral-100);border-color:var(--mf-color-border);color:var(--mf-color-neutral-600)}.mf-table--striped .mat-mdc-row:nth-child(2n){background-color:#f8fafceb}.mf-table--bordered .mat-mdc-cell,.mf-table--bordered .mat-mdc-header-cell{border-right:1px solid var(--mf-color-border)!important}.mf-table--bordered .mat-mdc-cell:last-child,.mf-table--bordered .mat-mdc-header-cell:last-child{border-right:none!important}.mf-table .mat-sort-header-arrow{color:var(--mf-color-brand)!important}.mf-table__actions-header,.mf-table__actions-cell{width:1%;white-space:nowrap}.mf-table__action-group{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:var(--mf-space-4)}.mf-table__action{min-width:0!important;display:inline-flex!important;align-items:center;gap:var(--mf-space-2);border-radius:var(--mf-radius-full)!important;font-family:var(--mf-font-base)!important;font-size:var(--mf-text-sm)!important;font-weight:var(--mf-weight-medium)!important}.mf-table__action-menu-trigger{display:inline-flex!important;align-items:center;justify-content:center;width:40px;height:40px;border:1px solid var(--mf-color-border);border-radius:var(--mf-radius-full)!important;background-color:#ffffffe0!important;color:var(--mf-color-neutral-600)!important}.mf-table__action-menu-trigger:hover{background-color:var(--mf-color-brand-light)!important;color:var(--mf-color-brand)!important}.mf-table__action-menu-trigger .mat-icon{margin:0;width:20px;height:20px;font-size:20px}.mf-table__action .mat-icon{margin:0;width:18px;height:18px;font-size:18px}.mf-table__action--primary{border-color:color-mix(in srgb,var(--mf-color-brand) 30%,white)!important;background-color:var(--mf-color-brand-light)!important;color:var(--mf-color-brand)!important}.mf-table__action--neutral{border-color:var(--mf-color-border)!important;background-color:#ffffffe6!important;color:var(--mf-color-neutral-600)!important}.mf-table__action--danger{border-color:#dc262633!important;background-color:#fef2f2eb!important;color:var(--mf-color-error-700)!important}.mf-table__footer{padding:0 var(--mf-space-2) var(--mf-space-2);border-top:1px solid var(--mf-color-border);background-color:#ffffffb8;border:1px solid var(--mf-color-border);border-radius:var(--mf-radius-lg)}.mf-table__empty{display:grid;justify-items:center;gap:var(--mf-space-3);padding:var(--mf-space-12) var(--mf-space-6);text-align:center;background:radial-gradient(circle at top,rgb(20 184 166 / .08),transparent 38%),linear-gradient(180deg,var(--mf-color-neutral-0),var(--mf-color-primary-50))}.mf-table__empty-icon{display:grid;place-items:center;width:68px;height:68px;border-radius:50%;border:1px solid color-mix(in srgb,var(--mf-color-brand) 18%,white);background-color:#ffffffe0;color:var(--mf-color-brand);box-shadow:var(--mf-shadow-md)}.mf-table__empty-icon .mat-icon{width:30px;height:30px;font-size:30px}.mf-table__empty-title{margin:0;font-family:var(--mf-font-display);font-size:var(--mf-text-xl);color:var(--mf-color-neutral-900)}.mf-table__empty-description{max-width:56ch;margin:0;color:var(--mf-color-neutral-600)}@media(max-width:720px){.mf-table__toolbar{padding:var(--mf-space-4)}.mf-table__search{max-width:none}.mf-table__surface{padding-right:var(--mf-space-4);padding-left:var(--mf-space-4)}.mf-table__footer{padding-right:var(--mf-space-2);padding-left:var(--mf-space-2)}}\n"] }]
3857
+ }], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], showSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSearch", required: false }] }], searchLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchLabel", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], searchValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchValue", required: false }] }], showPaginator: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPaginator", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], pageIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageIndex", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], showFirstLastButtons: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFirstLastButtons", required: false }] }], hidePageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "hidePageSize", required: false }] }], stickyHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "stickyHeader", required: false }] }], emptyTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyTitle", required: false }] }], emptyDescription: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyDescription", required: false }] }], rowActionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowActionLabel", required: false }] }], rowActionHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowActionHeader", required: false }] }], rowActionAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowActionAriaLabel", required: false }] }], rowActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowActions", required: false }] }], mfSortChange: [{ type: i0.Output, args: ["mfSortChange"] }], mfSearchChange: [{ type: i0.Output, args: ["mfSearchChange"] }], mfPageChange: [{ type: i0.Output, args: ["mfPageChange"] }], mfAction: [{ type: i0.Output, args: ["mfAction"] }], mfRowAction: [{ type: i0.Output, args: ["mfRowAction"] }], mfRowClick: [{ type: i0.Output, args: ["mfRowClick"] }] } });
3858
+
3859
+ /**
3860
+ * Tabs de la librería ng-comps.
3861
+ * Envuelve Angular Material `mat-tab-group` y expone una API uniforme
3862
+ * con look and feel de marca.
3863
+ */
3864
+ class MfTabsComponent {
3865
+ /** Pestañas */
3866
+ tabs = input.required(...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
3867
+ /** Índice seleccionado */
3868
+ selectedIndex = input(0, ...(ngDevMode ? [{ debugName: "selectedIndex" }] : /* istanbul ignore next */ []));
3869
+ /** Variante visual */
3870
+ variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
3871
+ mfSelectedIndexChange = output();
3872
+ hostClasses = computed(() => {
3873
+ return ['mf-tabs', `mf-tabs--${this.variant()}`].join(' ');
3874
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
3875
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfTabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3876
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfTabsComponent, isStandalone: true, selector: "mf-tabs", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: true, transformFunction: null }, selectedIndex: { classPropertyName: "selectedIndex", publicName: "selectedIndex", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfSelectedIndexChange: "mfSelectedIndexChange" }, ngImport: i0, template: `
3877
+ <mat-tab-group
3878
+ [selectedIndex]="selectedIndex()"
3879
+ [class]="hostClasses()"
3880
+ [mat-stretch-tabs]="variant() === 'stretched'"
3881
+ (selectedIndexChange)="mfSelectedIndexChange.emit($event)"
3882
+ >
3883
+ @for (tab of tabs(); track tab.label) {
3884
+ <mat-tab [disabled]="tab.disabled ?? false">
3885
+ <ng-template mat-tab-label>
3886
+ @if (tab.icon) {
3887
+ <mat-icon class="mf-tabs__icon" aria-hidden="true">{{ tab.icon }}</mat-icon>
3888
+ }
3889
+ {{ tab.label }}
3890
+ </ng-template>
3891
+ </mat-tab>
3892
+ }
3893
+ </mat-tab-group>
3894
+ `, isInline: true, styles: [":host{display:block}.mf-tabs .mat-mdc-tab-header{border-bottom:1px solid var(--mf-color-border)!important}.mf-tabs .mat-mdc-tab:not(.mdc-tab--active) .mdc-tab__text-label{color:var(--mf-color-neutral-400)!important;font-family:var(--mf-font-base)!important;font-weight:var(--mf-weight-medium)!important}.mf-tabs .mat-mdc-tab.mdc-tab--active .mdc-tab__text-label{color:var(--mf-color-brand)!important;font-family:var(--mf-font-base)!important;font-weight:var(--mf-weight-bold)!important}.mf-tabs .mat-mdc-tab-header .mdc-tab-indicator__content--underline{border-color:var(--mf-color-brand)!important}.mf-tabs__icon{margin-right:var(--mf-space-2);font-size:1.1em;height:1.1em;width:1.1em;vertical-align:middle}\n"], dependencies: [{ kind: "ngmodule", type: MatTabsModule }, { kind: "directive", type: i1$j.MatTabLabel, selector: "[mat-tab-label], [matTabLabel]" }, { kind: "component", type: i1$j.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i1$j.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3895
+ }
3896
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfTabsComponent, decorators: [{
3897
+ type: Component,
3898
+ args: [{ selector: 'mf-tabs', imports: [MatTabsModule, MatIconModule], template: `
3899
+ <mat-tab-group
3900
+ [selectedIndex]="selectedIndex()"
3901
+ [class]="hostClasses()"
3902
+ [mat-stretch-tabs]="variant() === 'stretched'"
3903
+ (selectedIndexChange)="mfSelectedIndexChange.emit($event)"
3904
+ >
3905
+ @for (tab of tabs(); track tab.label) {
3906
+ <mat-tab [disabled]="tab.disabled ?? false">
3907
+ <ng-template mat-tab-label>
3908
+ @if (tab.icon) {
3909
+ <mat-icon class="mf-tabs__icon" aria-hidden="true">{{ tab.icon }}</mat-icon>
3910
+ }
3911
+ {{ tab.label }}
3912
+ </ng-template>
3913
+ </mat-tab>
3914
+ }
3915
+ </mat-tab-group>
3916
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.mf-tabs .mat-mdc-tab-header{border-bottom:1px solid var(--mf-color-border)!important}.mf-tabs .mat-mdc-tab:not(.mdc-tab--active) .mdc-tab__text-label{color:var(--mf-color-neutral-400)!important;font-family:var(--mf-font-base)!important;font-weight:var(--mf-weight-medium)!important}.mf-tabs .mat-mdc-tab.mdc-tab--active .mdc-tab__text-label{color:var(--mf-color-brand)!important;font-family:var(--mf-font-base)!important;font-weight:var(--mf-weight-bold)!important}.mf-tabs .mat-mdc-tab-header .mdc-tab-indicator__content--underline{border-color:var(--mf-color-brand)!important}.mf-tabs__icon{margin-right:var(--mf-space-2);font-size:1.1em;height:1.1em;width:1.1em;vertical-align:middle}\n"] }]
3917
+ }], propDecorators: { tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: true }] }], selectedIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIndex", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], mfSelectedIndexChange: [{ type: i0.Output, args: ["mfSelectedIndexChange"] }] } });
3918
+
3919
+ /**
3920
+ * Textarea de la librería ng-comps.
3921
+ * Envuelve Angular Material `matInput` con textarea y expone una API uniforme
3922
+ * con look and feel de marca.
3923
+ */
3924
+ class MfTextareaComponent {
3925
+ cdr = inject(ChangeDetectorRef);
3926
+ ngControl = inject(NgControl, { self: true, optional: true });
3927
+ generatedId = createUniqueId('mf-textarea');
3928
+ disabledFromForm = signal(false, ...(ngDevMode ? [{ debugName: "disabledFromForm" }] : /* istanbul ignore next */ []));
3929
+ internalValue = signal('', ...(ngDevMode ? [{ debugName: "internalValue" }] : /* istanbul ignore next */ []));
3930
+ onControlChange = () => undefined;
3931
+ onControlTouched = () => undefined;
3932
+ errorStateMatcher = {
3933
+ isErrorState: (control) => Boolean(this.error() || (control?.invalid && (control.touched || control.dirty))),
3934
+ };
3935
+ /** ID del control */
3936
+ id = input(undefined, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
3937
+ /** Etiqueta */
3938
+ label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
3939
+ /** Etiqueta accesible alternativa cuando no existe label visible */
3940
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
3941
+ /** Referencia externa a elementos que etiquetan el control */
3942
+ ariaLabelledby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : /* istanbul ignore next */ []));
3943
+ /** Referencia externa a elementos descriptivos adicionales */
3944
+ ariaDescribedby = input(undefined, ...(ngDevMode ? [{ debugName: "ariaDescribedby" }] : /* istanbul ignore next */ []));
3945
+ /** Placeholder */
3946
+ placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
3947
+ /** Valor */
3948
+ value = input('', ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
3949
+ /** Filas visibles */
3950
+ rows = input(4, ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
3951
+ /** Tamaño */
3952
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
3953
+ /** Máximo de caracteres */
3954
+ maxLength = input(undefined, ...(ngDevMode ? [{ debugName: "maxLength" }] : /* istanbul ignore next */ []));
3955
+ /** Deshabilitado */
3956
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
3957
+ /** Solo lectura */
3958
+ readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
3959
+ /** Requerido */
3960
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
3961
+ /** Texto de ayuda */
3962
+ hint = input(undefined, ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
3963
+ /** Mensaje de error */
3964
+ error = input(undefined, ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
3965
+ /** Resize */
3966
+ resize = input('vertical', ...(ngDevMode ? [{ debugName: "resize" }] : /* istanbul ignore next */ []));
3967
+ mfInput = output();
3968
+ mfBlur = output();
3969
+ constructor() {
3970
+ effect(() => {
3971
+ this.internalValue.set(this.value());
3972
+ });
3973
+ effect(() => {
3974
+ if (!hasAccessibleName(this.label(), this.ariaLabel(), this.ariaLabelledby())) {
3975
+ warnInDev('mf-textarea requiere `label`, `ariaLabel` o `ariaLabelledby` para exponer un nombre accesible.');
3976
+ }
3977
+ });
3978
+ }
3979
+ controlId = computed(() => this.id() ?? this.generatedId, ...(ngDevMode ? [{ debugName: "controlId" }] : /* istanbul ignore next */ []));
3980
+ hintId = computed(() => this.hint() ? `${this.controlId()}-hint` : null, ...(ngDevMode ? [{ debugName: "hintId" }] : /* istanbul ignore next */ []));
3981
+ errorId = computed(() => this.error() ? `${this.controlId()}-error` : null, ...(ngDevMode ? [{ debugName: "errorId" }] : /* istanbul ignore next */ []));
3982
+ counterId = computed(() => this.maxLength() ? `${this.controlId()}-count` : null, ...(ngDevMode ? [{ debugName: "counterId" }] : /* istanbul ignore next */ []));
3983
+ describedBy = computed(() => mergeAriaIds(this.ariaDescribedby(), this.hintId(), this.errorId(), this.counterId()), ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
3984
+ resolvedAriaLabel = computed(() => this.label() ? null : this.ariaLabel() ?? null, ...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
3985
+ isDisabled = computed(() => this.disabled() || this.disabledFromForm(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
3986
+ currentLength = computed(() => this.internalValue().length, ...(ngDevMode ? [{ debugName: "currentLength" }] : /* istanbul ignore next */ []));
3987
+ hostClasses = computed(() => {
3988
+ return [
3989
+ 'mf-textarea',
3990
+ `mf-textarea--${this.size()}`,
3991
+ `mf-textarea--resize-${this.resize()}`,
3992
+ ].join(' ');
3993
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
3994
+ writeValue(value) {
3995
+ this.internalValue.set(value ?? '');
3996
+ this.cdr.markForCheck();
3997
+ }
3998
+ registerOnChange(fn) {
3999
+ this.onControlChange = fn;
4000
+ }
4001
+ registerOnTouched(fn) {
4002
+ this.onControlTouched = fn;
4003
+ }
4004
+ setDisabledState(isDisabled) {
4005
+ this.disabledFromForm.set(isDisabled);
4006
+ this.cdr.markForCheck();
4007
+ }
4008
+ isInvalid() {
4009
+ const control = this.ngControl?.control;
4010
+ return Boolean(this.error() || (control?.invalid && (control.touched || control.dirty)));
4011
+ }
4012
+ onInput(event) {
4013
+ const value = event.target.value;
4014
+ this.internalValue.set(value);
4015
+ this.onControlChange(value);
4016
+ this.mfInput.emit(value);
4017
+ }
4018
+ onBlur() {
4019
+ this.onControlTouched();
4020
+ this.mfBlur.emit();
4021
+ }
4022
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfTextareaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4023
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfTextareaComponent, isStandalone: true, selector: "mf-textarea", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "ariaDescribedby", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, maxLength: { classPropertyName: "maxLength", publicName: "maxLength", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, resize: { classPropertyName: "resize", publicName: "resize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mfInput: "mfInput", mfBlur: "mfBlur" }, providers: [
4024
+ {
4025
+ provide: NG_VALUE_ACCESSOR,
4026
+ useExisting: forwardRef(() => MfTextareaComponent),
4027
+ multi: true,
4028
+ },
4029
+ ], ngImport: i0, template: `
4030
+ <mat-form-field [appearance]="'outline'" [class]="hostClasses()">
4031
+ @if (label()) {
4032
+ <mat-label>{{ label() }}</mat-label>
4033
+ }
4034
+ <textarea
4035
+ matInput
4036
+ [id]="controlId()"
4037
+ [placeholder]="placeholder()"
4038
+ [disabled]="isDisabled()"
4039
+ [readonly]="readonly()"
4040
+ [required]="required()"
4041
+ [rows]="rows()"
4042
+ [attr.maxlength]="maxLength() ?? null"
4043
+ [value]="internalValue()"
4044
+ [errorStateMatcher]="errorStateMatcher"
4045
+ [attr.aria-label]="resolvedAriaLabel()"
4046
+ [attr.aria-labelledby]="ariaLabelledby() || null"
4047
+ [attr.aria-describedby]="describedBy()"
4048
+ [attr.aria-invalid]="isInvalid() ? 'true' : null"
4049
+ [attr.aria-required]="required() ? 'true' : null"
4050
+ (input)="onInput($event)"
4051
+ (blur)="onBlur()"
4052
+ ></textarea>
4053
+ @if (hint()) {
4054
+ <mat-hint [attr.id]="hintId()">{{ hint() }}</mat-hint>
4055
+ }
4056
+ @if (maxLength()) {
4057
+ <mat-hint [attr.id]="counterId()" align="end">
4058
+ {{ currentLength() }} / {{ maxLength() }}
4059
+ </mat-hint>
4060
+ }
4061
+ </mat-form-field>
4062
+ @if (error()) {
4063
+ <p class="mf-textarea__error" [attr.id]="errorId()" role="alert">{{ error() }}</p>
4064
+ }
4065
+ `, isInline: true, styles: [":host{display:block}.mf-textarea.mat-mdc-form-field{font-family:var(--mf-font-base)!important;width:100%}.mf-textarea textarea.mat-mdc-input-element{font-family:var(--mf-font-base)!important;line-height:var(--mf-leading-normal)!important}.mf-textarea .mdc-notched-outline__leading,.mf-textarea .mdc-notched-outline__notch,.mf-textarea .mdc-notched-outline__trailing{border-color:var(--mf-color-border)!important}.mf-textarea.mat-mdc-form-field.mat-focused .mdc-notched-outline__leading,.mf-textarea.mat-mdc-form-field.mat-focused .mdc-notched-outline__notch,.mf-textarea.mat-mdc-form-field.mat-focused .mdc-notched-outline__trailing{border-color:var(--mf-color-brand)!important}.mf-textarea .mdc-notched-outline{border-radius:var(--mf-radius-md)!important}.mf-textarea--sm textarea.mat-mdc-input-element{font-size:var(--mf-text-sm)!important}.mf-textarea--md textarea.mat-mdc-input-element{font-size:var(--mf-text-base)!important}.mf-textarea--lg textarea.mat-mdc-input-element{font-size:var(--mf-text-lg)!important}.mf-textarea--resize-none textarea{resize:none}.mf-textarea--resize-vertical textarea{resize:vertical}.mf-textarea--resize-horizontal textarea{resize:horizontal}.mf-textarea--resize-both textarea{resize:both}\n"], dependencies: [{ kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$1.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "ngmodule", type: MatFormFieldModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4066
+ }
4067
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfTextareaComponent, decorators: [{
4068
+ type: Component,
4069
+ args: [{ selector: 'mf-textarea', imports: [MatInputModule, MatFormFieldModule], providers: [
4070
+ {
4071
+ provide: NG_VALUE_ACCESSOR,
4072
+ useExisting: forwardRef(() => MfTextareaComponent),
4073
+ multi: true,
4074
+ },
4075
+ ], template: `
4076
+ <mat-form-field [appearance]="'outline'" [class]="hostClasses()">
4077
+ @if (label()) {
4078
+ <mat-label>{{ label() }}</mat-label>
4079
+ }
4080
+ <textarea
4081
+ matInput
4082
+ [id]="controlId()"
4083
+ [placeholder]="placeholder()"
4084
+ [disabled]="isDisabled()"
4085
+ [readonly]="readonly()"
4086
+ [required]="required()"
4087
+ [rows]="rows()"
4088
+ [attr.maxlength]="maxLength() ?? null"
4089
+ [value]="internalValue()"
4090
+ [errorStateMatcher]="errorStateMatcher"
4091
+ [attr.aria-label]="resolvedAriaLabel()"
4092
+ [attr.aria-labelledby]="ariaLabelledby() || null"
4093
+ [attr.aria-describedby]="describedBy()"
4094
+ [attr.aria-invalid]="isInvalid() ? 'true' : null"
4095
+ [attr.aria-required]="required() ? 'true' : null"
4096
+ (input)="onInput($event)"
4097
+ (blur)="onBlur()"
4098
+ ></textarea>
4099
+ @if (hint()) {
4100
+ <mat-hint [attr.id]="hintId()">{{ hint() }}</mat-hint>
4101
+ }
4102
+ @if (maxLength()) {
4103
+ <mat-hint [attr.id]="counterId()" align="end">
4104
+ {{ currentLength() }} / {{ maxLength() }}
4105
+ </mat-hint>
4106
+ }
4107
+ </mat-form-field>
4108
+ @if (error()) {
4109
+ <p class="mf-textarea__error" [attr.id]="errorId()" role="alert">{{ error() }}</p>
4110
+ }
4111
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.mf-textarea.mat-mdc-form-field{font-family:var(--mf-font-base)!important;width:100%}.mf-textarea textarea.mat-mdc-input-element{font-family:var(--mf-font-base)!important;line-height:var(--mf-leading-normal)!important}.mf-textarea .mdc-notched-outline__leading,.mf-textarea .mdc-notched-outline__notch,.mf-textarea .mdc-notched-outline__trailing{border-color:var(--mf-color-border)!important}.mf-textarea.mat-mdc-form-field.mat-focused .mdc-notched-outline__leading,.mf-textarea.mat-mdc-form-field.mat-focused .mdc-notched-outline__notch,.mf-textarea.mat-mdc-form-field.mat-focused .mdc-notched-outline__trailing{border-color:var(--mf-color-brand)!important}.mf-textarea .mdc-notched-outline{border-radius:var(--mf-radius-md)!important}.mf-textarea--sm textarea.mat-mdc-input-element{font-size:var(--mf-text-sm)!important}.mf-textarea--md textarea.mat-mdc-input-element{font-size:var(--mf-text-base)!important}.mf-textarea--lg textarea.mat-mdc-input-element{font-size:var(--mf-text-lg)!important}.mf-textarea--resize-none textarea{resize:none}.mf-textarea--resize-vertical textarea{resize:vertical}.mf-textarea--resize-horizontal textarea{resize:horizontal}.mf-textarea--resize-both textarea{resize:both}\n"] }]
4112
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabelledby", required: false }] }], ariaDescribedby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedby", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], maxLength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxLength", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], resize: [{ type: i0.Input, args: [{ isSignal: true, alias: "resize", required: false }] }], mfInput: [{ type: i0.Output, args: ["mfInput"] }], mfBlur: [{ type: i0.Output, args: ["mfBlur"] }] } });
4113
+
4114
+ /**
4115
+ * Toolbar de la librería ng-comps.
4116
+ * Envuelve Angular Material `mat-toolbar` y expone una API uniforme
4117
+ * con look and feel de marca. Usa content projection para acciones.
4118
+ */
4119
+ class MfToolbarComponent {
4120
+ /** Título que se muestra en la toolbar */
4121
+ title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
4122
+ /** Variante visual */
4123
+ variant = input('surface', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
4124
+ /** Muestra borde inferior */
4125
+ bordered = input(true, ...(ngDevMode ? [{ debugName: "bordered" }] : /* istanbul ignore next */ []));
4126
+ /** Toolbar fija en la parte superior */
4127
+ sticky = input(false, ...(ngDevMode ? [{ debugName: "sticky" }] : /* istanbul ignore next */ []));
4128
+ /** Elevación sutil */
4129
+ elevated = input(false, ...(ngDevMode ? [{ debugName: "elevated" }] : /* istanbul ignore next */ []));
4130
+ hostClasses = computed(() => {
4131
+ const classes = ['mf-toolbar', `mf-toolbar--${this.variant()}`];
4132
+ if (this.bordered())
4133
+ classes.push('mf-toolbar--bordered');
4134
+ if (this.sticky())
4135
+ classes.push('mf-toolbar--sticky');
4136
+ if (this.elevated())
4137
+ classes.push('mf-toolbar--elevated');
4138
+ return classes.join(' ');
4139
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
4140
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfToolbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4141
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.4", type: MfToolbarComponent, isStandalone: true, selector: "mf-toolbar", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null }, sticky: { classPropertyName: "sticky", publicName: "sticky", isSignal: true, isRequired: false, transformFunction: null }, elevated: { classPropertyName: "elevated", publicName: "elevated", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
4142
+ <mat-toolbar [class]="hostClasses()">
4143
+ <div class="mf-toolbar__start">
4144
+ @if (title()) {
4145
+ <span class="mf-toolbar__title">{{ title() }}</span>
4146
+ }
4147
+ <ng-content select="[mfToolbarStart]" />
4148
+ </div>
4149
+ <div class="mf-toolbar__spacer"></div>
4150
+ <div class="mf-toolbar__end">
4151
+ <ng-content select="[mfToolbarEnd]" />
4152
+ <ng-content />
4153
+ </div>
4154
+ </mat-toolbar>
4155
+ `, isInline: true, styles: [":host{display:block}.mf-toolbar.mat-toolbar{font-family:var(--mf-font-base)!important;padding:0 var(--mf-space-6)!important;min-height:56px!important;display:flex!important;align-items:center!important;transition:background-color var(--mf-duration-base) var(--mf-ease-standard),box-shadow var(--mf-duration-base) var(--mf-ease-standard)}.mf-toolbar--surface.mat-toolbar{background-color:var(--mf-color-surface)!important;color:var(--mf-color-on-surface)!important}.mf-toolbar--brand.mat-toolbar{background-color:var(--mf-color-brand)!important;color:var(--mf-color-on-brand)!important}.mf-toolbar--transparent.mat-toolbar{background-color:transparent!important;color:var(--mf-color-on-surface)!important}.mf-toolbar--bordered.mat-toolbar{border-bottom:1px solid var(--mf-color-border)}.mf-toolbar--brand.mf-toolbar--bordered.mat-toolbar{border-bottom-color:#ffffff26}.mf-toolbar--sticky.mat-toolbar{position:sticky;top:0;z-index:1000}.mf-toolbar--elevated.mat-toolbar{box-shadow:var(--mf-shadow-sm)!important}.mf-toolbar__start{display:flex;align-items:center;gap:var(--mf-space-3)}.mf-toolbar__spacer{flex:1}.mf-toolbar__end{display:flex;align-items:center;gap:var(--mf-space-2)}.mf-toolbar__title{font-family:var(--mf-font-display)!important;font-size:var(--mf-text-lg)!important;font-weight:var(--mf-weight-bold)!important;letter-spacing:-.01em}\n"], dependencies: [{ kind: "ngmodule", type: MatToolbarModule }, { kind: "component", type: i1$k.MatToolbar, selector: "mat-toolbar", inputs: ["color"], exportAs: ["matToolbar"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4156
+ }
4157
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfToolbarComponent, decorators: [{
4158
+ type: Component,
4159
+ args: [{ selector: 'mf-toolbar', imports: [MatToolbarModule], template: `
4160
+ <mat-toolbar [class]="hostClasses()">
4161
+ <div class="mf-toolbar__start">
4162
+ @if (title()) {
4163
+ <span class="mf-toolbar__title">{{ title() }}</span>
4164
+ }
4165
+ <ng-content select="[mfToolbarStart]" />
4166
+ </div>
4167
+ <div class="mf-toolbar__spacer"></div>
4168
+ <div class="mf-toolbar__end">
4169
+ <ng-content select="[mfToolbarEnd]" />
4170
+ <ng-content />
4171
+ </div>
4172
+ </mat-toolbar>
4173
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}.mf-toolbar.mat-toolbar{font-family:var(--mf-font-base)!important;padding:0 var(--mf-space-6)!important;min-height:56px!important;display:flex!important;align-items:center!important;transition:background-color var(--mf-duration-base) var(--mf-ease-standard),box-shadow var(--mf-duration-base) var(--mf-ease-standard)}.mf-toolbar--surface.mat-toolbar{background-color:var(--mf-color-surface)!important;color:var(--mf-color-on-surface)!important}.mf-toolbar--brand.mat-toolbar{background-color:var(--mf-color-brand)!important;color:var(--mf-color-on-brand)!important}.mf-toolbar--transparent.mat-toolbar{background-color:transparent!important;color:var(--mf-color-on-surface)!important}.mf-toolbar--bordered.mat-toolbar{border-bottom:1px solid var(--mf-color-border)}.mf-toolbar--brand.mf-toolbar--bordered.mat-toolbar{border-bottom-color:#ffffff26}.mf-toolbar--sticky.mat-toolbar{position:sticky;top:0;z-index:1000}.mf-toolbar--elevated.mat-toolbar{box-shadow:var(--mf-shadow-sm)!important}.mf-toolbar__start{display:flex;align-items:center;gap:var(--mf-space-3)}.mf-toolbar__spacer{flex:1}.mf-toolbar__end{display:flex;align-items:center;gap:var(--mf-space-2)}.mf-toolbar__title{font-family:var(--mf-font-display)!important;font-size:var(--mf-text-lg)!important;font-weight:var(--mf-weight-bold)!important;letter-spacing:-.01em}\n"] }]
4174
+ }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], bordered: [{ type: i0.Input, args: [{ isSignal: true, alias: "bordered", required: false }] }], sticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "sticky", required: false }] }], elevated: [{ type: i0.Input, args: [{ isSignal: true, alias: "elevated", required: false }] }] } });
4175
+
4176
+ class MfTooltipDirective {
4177
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfTooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4178
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.4", type: MfTooltipDirective, isStandalone: true, selector: "[mfTooltip]", hostDirectives: [{ directive: i1$l.MatTooltip, inputs: ["matTooltip", "mfTooltip", "matTooltipPosition", "mfTooltipPosition", "matTooltipDisabled", "mfTooltipDisabled", "matTooltipShowDelay", "mfTooltipShowDelay", "matTooltipHideDelay", "mfTooltipHideDelay"] }], ngImport: i0 });
4179
+ }
4180
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfTooltipDirective, decorators: [{
4181
+ type: Directive,
4182
+ args: [{
4183
+ selector: '[mfTooltip]',
4184
+ standalone: true,
4185
+ hostDirectives: [
4186
+ {
4187
+ directive: MatTooltip,
4188
+ inputs: [
4189
+ 'matTooltip: mfTooltip',
4190
+ 'matTooltipPosition: mfTooltipPosition',
4191
+ 'matTooltipDisabled: mfTooltipDisabled',
4192
+ 'matTooltipShowDelay: mfTooltipShowDelay',
4193
+ 'matTooltipHideDelay: mfTooltipHideDelay',
4194
+ ],
4195
+ },
4196
+ ],
4197
+ }]
4198
+ }] });
4199
+
4200
+ /**
4201
+ * Tooltip de la librería ng-comps.
4202
+ * Envuelve Angular Material `matTooltip` y expone una API uniforme
4203
+ * con look and feel de marca.
4204
+ */
4205
+ class MfTooltipComponent {
4206
+ /** Texto del tooltip */
4207
+ text = input.required(...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
4208
+ /** Posición del tooltip */
4209
+ position = input('above', ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
4210
+ /** Deshabilitado */
4211
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
4212
+ /** Delay para mostrar (ms) */
4213
+ showDelay = input(200, ...(ngDevMode ? [{ debugName: "showDelay" }] : /* istanbul ignore next */ []));
4214
+ /** Delay para ocultar (ms) */
4215
+ hideDelay = input(0, ...(ngDevMode ? [{ debugName: "hideDelay" }] : /* istanbul ignore next */ []));
4216
+ hostClasses = computed(() => {
4217
+ return ['mf-tooltip', `mf-tooltip--${this.position()}`].join(' ');
4218
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
4219
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4220
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.4", type: MfTooltipComponent, isStandalone: true, selector: "mf-tooltip", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, showDelay: { classPropertyName: "showDelay", publicName: "showDelay", isSignal: true, isRequired: false, transformFunction: null }, hideDelay: { classPropertyName: "hideDelay", publicName: "hideDelay", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
4221
+ <span
4222
+ [mfTooltip]="text()"
4223
+ [mfTooltipPosition]="position()"
4224
+ [mfTooltipDisabled]="disabled()"
4225
+ [mfTooltipShowDelay]="showDelay()"
4226
+ [mfTooltipHideDelay]="hideDelay()"
4227
+ [class]="hostClasses()"
4228
+ >
4229
+ <ng-content />
4230
+ </span>
4231
+ `, isInline: true, styles: [":host{display:inline-block}.mf-tooltip{cursor:default}\n"], dependencies: [{ kind: "directive", type: MfTooltipDirective, selector: "[mfTooltip]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4232
+ }
4233
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.4", ngImport: i0, type: MfTooltipComponent, decorators: [{
4234
+ type: Component,
4235
+ args: [{ selector: 'mf-tooltip', imports: [MfTooltipDirective], template: `
4236
+ <span
4237
+ [mfTooltip]="text()"
4238
+ [mfTooltipPosition]="position()"
4239
+ [mfTooltipDisabled]="disabled()"
4240
+ [mfTooltipShowDelay]="showDelay()"
4241
+ [mfTooltipHideDelay]="hideDelay()"
4242
+ [class]="hostClasses()"
4243
+ >
4244
+ <ng-content />
4245
+ </span>
4246
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-block}.mf-tooltip{cursor:default}\n"] }]
4247
+ }], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: true }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDelay", required: false }] }], hideDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideDelay", required: false }] }] } });
4248
+
4249
+ /**
4250
+ * Generated bundle index. Do not edit.
4251
+ */
4252
+
4253
+ export { MfAccordionComponent, MfAlertComponent, MfAutocompleteComponent, MfAvatarComponent, MfBadgeComponent, MfBreadcrumbComponent, MfButtonComponent, MfCardComponent, MfCheckboxComponent, MfChipComponent, MfDatepickerComponent, MfDialogComponent, MfDialogService, MfDividerComponent, MfFormFieldComponent, MfGridListComponent, MfIconComponent, MfInputComponent, MfMenuComponent, MfPaginatorComponent, MfProgressBarComponent, MfProgressSpinnerComponent, MfRadioButtonComponent, MfSelectComponent, MfSidenavComponent, MfSlideToggleComponent, MfSnackbarService, MfTableComponent, MfTabsComponent, MfTextareaComponent, MfToolbarComponent, MfTooltipComponent, MfTooltipDirective };
4254
+ //# sourceMappingURL=ng-comps.mjs.map