@neural-ui/core 1.6.0 → 1.6.2

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 (137) hide show
  1. package/fesm2022/neural-ui-core-accordion.mjs +5 -5
  2. package/fesm2022/neural-ui-core-accordion.mjs.map +1 -1
  3. package/fesm2022/neural-ui-core-alert.mjs +3 -3
  4. package/fesm2022/neural-ui-core-alert.mjs.map +1 -1
  5. package/fesm2022/neural-ui-core-autocomplete.mjs +3 -3
  6. package/fesm2022/neural-ui-core-autocomplete.mjs.map +1 -1
  7. package/fesm2022/neural-ui-core-avatar.mjs +3 -3
  8. package/fesm2022/neural-ui-core-avatar.mjs.map +1 -1
  9. package/fesm2022/neural-ui-core-badge.mjs +3 -3
  10. package/fesm2022/neural-ui-core-badge.mjs.map +1 -1
  11. package/fesm2022/neural-ui-core-block-ui.mjs +6 -6
  12. package/fesm2022/neural-ui-core-block-ui.mjs.map +1 -1
  13. package/fesm2022/neural-ui-core-breadcrumb.mjs +3 -3
  14. package/fesm2022/neural-ui-core-breadcrumb.mjs.map +1 -1
  15. package/fesm2022/neural-ui-core-button.mjs +3 -3
  16. package/fesm2022/neural-ui-core-button.mjs.map +1 -1
  17. package/fesm2022/neural-ui-core-calendar.mjs +41 -33
  18. package/fesm2022/neural-ui-core-calendar.mjs.map +1 -1
  19. package/fesm2022/neural-ui-core-card.mjs +3 -3
  20. package/fesm2022/neural-ui-core-card.mjs.map +1 -1
  21. package/fesm2022/neural-ui-core-chart.mjs +3 -3
  22. package/fesm2022/neural-ui-core-chart.mjs.map +1 -1
  23. package/fesm2022/neural-ui-core-checkbox.mjs +3 -3
  24. package/fesm2022/neural-ui-core-checkbox.mjs.map +1 -1
  25. package/fesm2022/neural-ui-core-chip.mjs +3 -3
  26. package/fesm2022/neural-ui-core-chip.mjs.map +1 -1
  27. package/fesm2022/neural-ui-core-code-block.mjs +4 -3
  28. package/fesm2022/neural-ui-core-code-block.mjs.map +1 -1
  29. package/fesm2022/neural-ui-core-color-picker.mjs +3 -3
  30. package/fesm2022/neural-ui-core-color-picker.mjs.map +1 -1
  31. package/fesm2022/neural-ui-core-command-palette.mjs +6 -6
  32. package/fesm2022/neural-ui-core-command-palette.mjs.map +1 -1
  33. package/fesm2022/neural-ui-core-confirm-dialog.mjs +6 -6
  34. package/fesm2022/neural-ui-core-confirm-dialog.mjs.map +1 -1
  35. package/fesm2022/neural-ui-core-context-menu.mjs +6 -6
  36. package/fesm2022/neural-ui-core-context-menu.mjs.map +1 -1
  37. package/fesm2022/neural-ui-core-dashboard-grid.mjs +3 -3
  38. package/fesm2022/neural-ui-core-dashboard-grid.mjs.map +1 -1
  39. package/fesm2022/neural-ui-core-date-input.mjs +3 -3
  40. package/fesm2022/neural-ui-core-date-input.mjs.map +1 -1
  41. package/fesm2022/neural-ui-core-divider.mjs +3 -3
  42. package/fesm2022/neural-ui-core-divider.mjs.map +1 -1
  43. package/fesm2022/neural-ui-core-empty-state.mjs +3 -3
  44. package/fesm2022/neural-ui-core-empty-state.mjs.map +1 -1
  45. package/fesm2022/neural-ui-core-filter-bar.mjs +3 -3
  46. package/fesm2022/neural-ui-core-filter-bar.mjs.map +1 -1
  47. package/fesm2022/neural-ui-core-icon.mjs +3 -3
  48. package/fesm2022/neural-ui-core-icon.mjs.map +1 -1
  49. package/fesm2022/neural-ui-core-image-gallery.mjs +3 -3
  50. package/fesm2022/neural-ui-core-image-gallery.mjs.map +1 -1
  51. package/fesm2022/neural-ui-core-image-viewer.mjs +6 -6
  52. package/fesm2022/neural-ui-core-image-viewer.mjs.map +1 -1
  53. package/fesm2022/neural-ui-core-input-otp.mjs +3 -3
  54. package/fesm2022/neural-ui-core-input-otp.mjs.map +1 -1
  55. package/fesm2022/neural-ui-core-input.mjs +3 -3
  56. package/fesm2022/neural-ui-core-input.mjs.map +1 -1
  57. package/fesm2022/neural-ui-core-kanban.mjs +5 -5
  58. package/fesm2022/neural-ui-core-kanban.mjs.map +1 -1
  59. package/fesm2022/neural-ui-core-knob.mjs +3 -3
  60. package/fesm2022/neural-ui-core-knob.mjs.map +1 -1
  61. package/fesm2022/neural-ui-core-meter-group.mjs +3 -3
  62. package/fesm2022/neural-ui-core-meter-group.mjs.map +1 -1
  63. package/fesm2022/neural-ui-core-modal.mjs +6 -6
  64. package/fesm2022/neural-ui-core-modal.mjs.map +1 -1
  65. package/fesm2022/neural-ui-core-multiselect.mjs +6 -6
  66. package/fesm2022/neural-ui-core-multiselect.mjs.map +1 -1
  67. package/fesm2022/neural-ui-core-nav.mjs +3 -3
  68. package/fesm2022/neural-ui-core-nav.mjs.map +1 -1
  69. package/fesm2022/neural-ui-core-notification-center.mjs +21 -7
  70. package/fesm2022/neural-ui-core-notification-center.mjs.map +1 -1
  71. package/fesm2022/neural-ui-core-number-input.mjs +3 -3
  72. package/fesm2022/neural-ui-core-number-input.mjs.map +1 -1
  73. package/fesm2022/neural-ui-core-pagination.mjs +3 -3
  74. package/fesm2022/neural-ui-core-pagination.mjs.map +1 -1
  75. package/fesm2022/neural-ui-core-popover.mjs +6 -6
  76. package/fesm2022/neural-ui-core-popover.mjs.map +1 -1
  77. package/fesm2022/neural-ui-core-progress-bar.mjs +3 -3
  78. package/fesm2022/neural-ui-core-progress-bar.mjs.map +1 -1
  79. package/fesm2022/neural-ui-core-radio.mjs +6 -6
  80. package/fesm2022/neural-ui-core-radio.mjs.map +1 -1
  81. package/fesm2022/neural-ui-core-rating.mjs +3 -3
  82. package/fesm2022/neural-ui-core-rating.mjs.map +1 -1
  83. package/fesm2022/neural-ui-core-rich-text-editor.mjs +13 -5
  84. package/fesm2022/neural-ui-core-rich-text-editor.mjs.map +1 -1
  85. package/fesm2022/neural-ui-core-scheduler-gantt.mjs +3 -3
  86. package/fesm2022/neural-ui-core-scheduler-gantt.mjs.map +1 -1
  87. package/fesm2022/neural-ui-core-select.mjs +9 -9
  88. package/fesm2022/neural-ui-core-select.mjs.map +1 -1
  89. package/fesm2022/neural-ui-core-sidebar.mjs +5 -5
  90. package/fesm2022/neural-ui-core-sidebar.mjs.map +1 -1
  91. package/fesm2022/neural-ui-core-skeleton.mjs +3 -3
  92. package/fesm2022/neural-ui-core-skeleton.mjs.map +1 -1
  93. package/fesm2022/neural-ui-core-slider.mjs +3 -3
  94. package/fesm2022/neural-ui-core-slider.mjs.map +1 -1
  95. package/fesm2022/neural-ui-core-spinner.mjs +3 -3
  96. package/fesm2022/neural-ui-core-spinner.mjs.map +1 -1
  97. package/fesm2022/neural-ui-core-split-button.mjs +3 -3
  98. package/fesm2022/neural-ui-core-split-button.mjs.map +1 -1
  99. package/fesm2022/neural-ui-core-splitter.mjs +3 -3
  100. package/fesm2022/neural-ui-core-splitter.mjs.map +1 -1
  101. package/fesm2022/neural-ui-core-stats-card.mjs +3 -3
  102. package/fesm2022/neural-ui-core-stats-card.mjs.map +1 -1
  103. package/fesm2022/neural-ui-core-stepper.mjs +3 -3
  104. package/fesm2022/neural-ui-core-stepper.mjs.map +1 -1
  105. package/fesm2022/neural-ui-core-switch.mjs +3 -3
  106. package/fesm2022/neural-ui-core-switch.mjs.map +1 -1
  107. package/fesm2022/neural-ui-core-table.mjs +6 -6
  108. package/fesm2022/neural-ui-core-table.mjs.map +1 -1
  109. package/fesm2022/neural-ui-core-tabs.mjs +6 -6
  110. package/fesm2022/neural-ui-core-tabs.mjs.map +1 -1
  111. package/fesm2022/neural-ui-core-textarea.mjs +3 -3
  112. package/fesm2022/neural-ui-core-textarea.mjs.map +1 -1
  113. package/fesm2022/neural-ui-core-timeline-grid.mjs +3 -3
  114. package/fesm2022/neural-ui-core-timeline-grid.mjs.map +1 -1
  115. package/fesm2022/neural-ui-core-timeline.mjs +3 -3
  116. package/fesm2022/neural-ui-core-timeline.mjs.map +1 -1
  117. package/fesm2022/neural-ui-core-toast.mjs +21 -7
  118. package/fesm2022/neural-ui-core-toast.mjs.map +1 -1
  119. package/fesm2022/neural-ui-core-toggle-button-group.mjs +3 -3
  120. package/fesm2022/neural-ui-core-toggle-button-group.mjs.map +1 -1
  121. package/fesm2022/neural-ui-core-toolbar.mjs +3 -3
  122. package/fesm2022/neural-ui-core-toolbar.mjs.map +1 -1
  123. package/fesm2022/neural-ui-core-tooltip.mjs +6 -6
  124. package/fesm2022/neural-ui-core-tooltip.mjs.map +1 -1
  125. package/fesm2022/neural-ui-core-tree-table.mjs +3 -3
  126. package/fesm2022/neural-ui-core-tree-table.mjs.map +1 -1
  127. package/fesm2022/neural-ui-core-tree.mjs +3 -3
  128. package/fesm2022/neural-ui-core-tree.mjs.map +1 -1
  129. package/fesm2022/neural-ui-core-uploader.mjs +3 -3
  130. package/fesm2022/neural-ui-core-uploader.mjs.map +1 -1
  131. package/fesm2022/neural-ui-core-url-state.mjs +3 -3
  132. package/fesm2022/neural-ui-core-url-state.mjs.map +1 -1
  133. package/fesm2022/neural-ui-core-virtual-list.mjs +6 -6
  134. package/fesm2022/neural-ui-core-virtual-list.mjs.map +1 -1
  135. package/package.json +6 -6
  136. package/types/neural-ui-core-notification-center.d.ts +2 -0
  137. package/types/neural-ui-core-toast.d.ts +2 -0
@@ -157,8 +157,8 @@ class NeuKnobComponent {
157
157
  _clamp(v) {
158
158
  return Math.min(this.max(), Math.max(this.min(), v));
159
159
  }
160
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuKnobComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
161
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: NeuKnobComponent, isStandalone: true, selector: "neu-knob", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, showValue: { classPropertyName: "showValue", publicName: "showValue", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { properties: { "class": "hostClasses()" } }, providers: [
160
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuKnobComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
161
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuKnobComponent, isStandalone: true, selector: "neu-knob", inputs: { min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, showValue: { classPropertyName: "showValue", publicName: "showValue", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { properties: { "class": "hostClasses()" } }, providers: [
162
162
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NeuKnobComponent), multi: true },
163
163
  ], ngImport: i0, template: `
164
164
  <div
@@ -235,7 +235,7 @@ class NeuKnobComponent {
235
235
  }
236
236
  `, isInline: true, styles: ["@charset \"UTF-8\";.neu-knob{display:inline-flex;flex-direction:column;align-items:center;gap:6px;-webkit-user-select:none;user-select:none}.neu-knob--disabled{opacity:.5;pointer-events:none}.neu-knob__dial{position:relative;display:flex;align-items:center;justify-content:center;cursor:grab;border-radius:50%;touch-action:none}.neu-knob__dial:focus-visible{outline:2px solid var(--neu-focus-ring, #0ea5e9);outline-offset:3px}.neu-knob__dial:active{cursor:grabbing}.neu-knob__track{stroke:var(--neu-knob-track, var(--neu-border-color, #e5e7eb))}.neu-knob__value-arc{stroke:var(--neu-color-primary, #0ea5e9);transition:stroke-dashoffset 40ms linear}.neu-knob__indicator{fill:var(--neu-color-primary, #0ea5e9)}.neu-knob__display{position:absolute;font-size:.8125rem;font-weight:600;color:var(--neu-knob-display-color, var(--neu-text, #0f172a));-webkit-text-fill-color:var(--neu-knob-display-color, var(--neu-text, #0f172a));pointer-events:none;font-variant-numeric:tabular-nums}.neu-knob__label{font-size:.8125rem;color:var(--neu-knob-label-color, var(--neu-text-muted, #64748b));cursor:pointer}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
237
237
  }
238
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuKnobComponent, decorators: [{
238
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuKnobComponent, decorators: [{
239
239
  type: Component,
240
240
  args: [{ selector: 'neu-knob', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: { '[class]': 'hostClasses()' }, providers: [
241
241
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NeuKnobComponent), multi: true },
@@ -1 +1 @@
1
- {"version":3,"file":"neural-ui-core-knob.mjs","sources":["../../../../projects/ui-core/knob/neu-knob.component.ts","../../../../projects/ui-core/knob/neural-ui-core-knob.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n computed,\n forwardRef,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nlet _seq = 0;\n\n/**\n * NeuralUI Knob Component\n *\n * Control de dial rotatorio para selección de valores numéricos. Implementa CVA.\n *\n * Uso: <neu-knob [min]=\"0\" [max]=\"100\" formControlName=\"volume\" />\n */\n@Component({\n selector: 'neu-knob',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '[class]': 'hostClasses()' },\n providers: [\n { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NeuKnobComponent), multi: true },\n ],\n template: `\n <div\n class=\"neu-knob__dial\"\n role=\"slider\"\n tabindex=\"0\"\n [attr.id]=\"_id\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"_value()\"\n [attr.aria-label]=\"label() || 'Knob'\"\n [attr.aria-disabled]=\"_cvaDisabled()\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n (mousedown)=\"onMouseDown($event)\"\n (touchstart)=\"onTouchStart($event)\"\n (keydown)=\"onKeyDown($event)\"\n >\n <svg\n class=\"neu-knob__svg\"\n [attr.viewBox]=\"'0 0 ' + size() + ' ' + size()\"\n [attr.width]=\"size()\"\n [attr.height]=\"size()\"\n aria-hidden=\"true\"\n >\n <!-- Track arc: 260° arc (same as value-arc) so the background only covers\n the usable range, not a full 360° ring. -->\n <circle\n class=\"neu-knob__track\"\n [attr.cx]=\"size() / 2\"\n [attr.cy]=\"size() / 2\"\n [attr.r]=\"_radius()\"\n fill=\"none\"\n [attr.stroke-width]=\"_strokeWidth()\"\n stroke-linecap=\"round\"\n [attr.stroke-dasharray]=\"_arcDashArray()\"\n stroke-dashoffset=\"0\"\n [attr.transform]=\"'rotate(-220 ' + size() / 2 + ' ' + size() / 2 + ')'\"\n />\n <!-- Value arc -->\n <circle\n class=\"neu-knob__value-arc\"\n [attr.cx]=\"size() / 2\"\n [attr.cy]=\"size() / 2\"\n [attr.r]=\"_radius()\"\n fill=\"none\"\n [attr.stroke-width]=\"_strokeWidth()\"\n stroke-linecap=\"round\"\n [attr.stroke-dasharray]=\"_arcDashArray()\"\n [attr.stroke-dashoffset]=\"_arcDashOffset()\"\n [attr.transform]=\"'rotate(-220 ' + size() / 2 + ' ' + size() / 2 + ')'\"\n />\n <!-- Indicator dot -->\n <circle\n class=\"neu-knob__indicator\"\n [attr.cx]=\"_indicatorX()\"\n [attr.cy]=\"_indicatorY()\"\n [attr.r]=\"_strokeWidth() / 2 + 1\"\n [attr.transform]=\"\n 'rotate(' + _indicatorAngle() + ' ' + size() / 2 + ' ' + size() / 2 + ')'\n \"\n />\n </svg>\n @if (showValue()) {\n <span\n class=\"neu-knob__display\"\n style=\"color: var(--neu-knob-display-color, var(--neu-text, #0f172a)) !important; -webkit-text-fill-color: var(--neu-knob-display-color, var(--neu-text, #0f172a)) !important;\"\n >{{ _value() }}</span\n >\n }\n </div>\n @if (label()) {\n <label class=\"neu-knob__label\" [attr.for]=\"_id\">{{ label() }}</label>\n }\n `,\n styleUrl: './neu-knob.component.scss',\n})\nexport class NeuKnobComponent implements ControlValueAccessor {\n /** Valor mínimo / Min value */\n readonly min = input<number>(0);\n /** Valor máximo / Max value */\n readonly max = input<number>(100);\n /** Incremento por paso / Step increment */\n readonly step = input<number>(1);\n /** Tamaño del dial en px / Dial size in px */\n readonly size = input<number>(80);\n /** Muestra el valor numérico en el centro / Shows the numeric value in the center */\n readonly showValue = input<boolean>(true);\n /** Etiqueta visible / Visible label */\n readonly label = input<string>('');\n /** Emitido en cada cambio / Emitted on each change */\n readonly valueChange = output<number>();\n\n readonly _id = `neu-knob-${++_seq}`;\n readonly _cvaDisabled = signal(false);\n readonly _value = signal(0);\n\n readonly _strokeWidth = computed(() => Math.max(4, this.size() * 0.1));\n readonly _radius = computed(() => (this.size() - this._strokeWidth()) / 2 - 2);\n readonly _circumference = computed(() => 2 * Math.PI * this._radius());\n /** Arc spans 260° (from -40° to 220°) */\n readonly _arcLength = computed(() => (260 / 360) * this._circumference());\n\n readonly _normalizedValue = computed(() => {\n const range = this.max() - this.min();\n return range === 0 ? 0 : (this._value() - this.min()) / range;\n });\n\n readonly _arcDashArray = computed(() => `${this._arcLength()} ${this._circumference()}`);\n readonly _arcDashOffset = computed(() => this._arcLength() * (1 - this._normalizedValue()));\n\n // Indicator position on the track (relative to SVG center)\n // El arco empieza en rotate(-220°) desde el Este del SVG.\n // El punto indicador reposa en el Norte (12 en punto).\n // Para que el indicador siga el arco, la rotación CW debe ser:\n // θ = 230° + normalizedValue × 260°\n // (arco de 7:40 → 1:20 pasando por 12:00 en la mitad)\n // Arc starts at rotate(-220°) from East; indicator natural position is North (12 o'clock).\n // Correct clockwise rotation formula: θ = 230 + normalizedValue × 260.\n readonly _indicatorAngle = computed(() => this._normalizedValue() * 260 + 230);\n readonly _indicatorX = computed(() => this.size() / 2);\n readonly _indicatorY = computed(() => this.size() / 2 - this._radius());\n\n private _dragStartAngle = 0;\n private _dragStartValue = 0;\n private _onChange: (v: number) => void = () => {};\n private _onTouched: () => void = () => {};\n\n private readonly _el = inject(ElementRef<HTMLElement>);\n\n /** Calcula el ángulo en grados desde el centro del dial al punto (x, y).\n * Calculates the angle in degrees from the dial center to point (x, y). */\n private _getAngle(clientX: number, clientY: number): number {\n const dial = this._el.nativeElement.querySelector('.neu-knob__dial') as HTMLElement;\n const rect = dial\n ? dial.getBoundingClientRect()\n : this._el.nativeElement.getBoundingClientRect();\n const cx = rect.left + rect.width / 2;\n const cy = rect.top + rect.height / 2;\n return Math.atan2(clientY - cy, clientX - cx) * (180 / Math.PI);\n }\n\n readonly hostClasses = computed(() => ({\n 'neu-knob': true,\n 'neu-knob--disabled': this._cvaDisabled(),\n }));\n\n writeValue(val: number | null): void {\n this._value.set(this._clamp(val ?? this.min()));\n }\n\n registerOnChange(fn: (v: number) => void): void {\n this._onChange = fn;\n }\n registerOnTouched(fn: () => void): void {\n this._onTouched = fn;\n }\n setDisabledState(disabled: boolean): void {\n this._cvaDisabled.set(disabled);\n }\n\n onMouseDown(event: MouseEvent): void {\n if (this._cvaDisabled()) return;\n event.preventDefault();\n this._dragStartAngle = this._getAngle(event.clientX, event.clientY);\n this._dragStartValue = this._value();\n const onMove = (e: MouseEvent) => this._applyCircularDrag(e.clientX, e.clientY);\n const onUp = () => {\n window.removeEventListener('mousemove', onMove);\n window.removeEventListener('mouseup', onUp);\n };\n window.addEventListener('mousemove', onMove);\n window.addEventListener('mouseup', onUp);\n this._onTouched();\n }\n\n onTouchStart(event: TouchEvent): void {\n if (this._cvaDisabled()) return;\n event.preventDefault();\n this._dragStartAngle = this._getAngle(event.touches[0].clientX, event.touches[0].clientY);\n this._dragStartValue = this._value();\n const onMove = (e: TouchEvent) =>\n this._applyCircularDrag(e.touches[0].clientX, e.touches[0].clientY);\n const onEnd = () => {\n window.removeEventListener('touchmove', onMove);\n window.removeEventListener('touchend', onEnd);\n };\n window.addEventListener('touchmove', onMove, { passive: false });\n window.addEventListener('touchend', onEnd);\n this._onTouched();\n }\n\n onKeyDown(event: KeyboardEvent): void {\n if (this._cvaDisabled()) return;\n let delta = 0;\n if (event.key === 'ArrowUp' || event.key === 'ArrowRight') delta = this.step();\n else if (event.key === 'ArrowDown' || event.key === 'ArrowLeft') delta = -this.step();\n else if (event.key === 'Home') {\n this._emit(this.min());\n return;\n } else if (event.key === 'End') {\n this._emit(this.max());\n return;\n }\n if (delta !== 0) {\n event.preventDefault();\n this._emit(this._clamp(this._value() + delta));\n }\n }\n\n /** Aplica el drag circular calculando el delta de ángulo respecto al punto inicial.\n * Applies circular drag by computing the angle delta from the start point. */\n private _applyCircularDrag(clientX: number, clientY: number): void {\n let deltaAngle = this._getAngle(clientX, clientY) - this._dragStartAngle;\n // Normalizar a [-180, 180] para evitar saltos al cruzar el eje / Normalize to avoid jumps\n if (deltaAngle > 180) deltaAngle -= 360;\n if (deltaAngle < -180) deltaAngle += 360;\n const range = this.max() - this.min();\n // 260° de arco = rango completo / 260° arc = full range\n const valueDelta = (deltaAngle / 260) * range;\n this._emit(this._clamp(this._dragStartValue + valueDelta));\n }\n\n private _emit(value: number): void {\n const snapped = Math.round(value / this.step()) * this.step();\n const clamped = this._clamp(snapped);\n this._value.set(clamped);\n this._onChange(clamped);\n this.valueChange.emit(clamped);\n }\n\n private _clamp(v: number): number {\n return Math.min(this.max(), Math.max(this.min(), v));\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"neural-ui-core-knob.mjs","sources":["../../../../projects/ui-core/knob/neu-knob.component.ts","../../../../projects/ui-core/knob/neural-ui-core-knob.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n computed,\n forwardRef,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nlet _seq = 0;\n\n/**\n * NeuralUI Knob Component\n *\n * Control de dial rotatorio para selección de valores numéricos. Implementa CVA.\n *\n * Uso: <neu-knob [min]=\"0\" [max]=\"100\" formControlName=\"volume\" />\n */\n@Component({\n selector: 'neu-knob',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '[class]': 'hostClasses()' },\n providers: [\n { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NeuKnobComponent), multi: true },\n ],\n template: `\n <div\n class=\"neu-knob__dial\"\n role=\"slider\"\n tabindex=\"0\"\n [attr.id]=\"_id\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"_value()\"\n [attr.aria-label]=\"label() || 'Knob'\"\n [attr.aria-disabled]=\"_cvaDisabled()\"\n [style.width.px]=\"size()\"\n [style.height.px]=\"size()\"\n (mousedown)=\"onMouseDown($event)\"\n (touchstart)=\"onTouchStart($event)\"\n (keydown)=\"onKeyDown($event)\"\n >\n <svg\n class=\"neu-knob__svg\"\n [attr.viewBox]=\"'0 0 ' + size() + ' ' + size()\"\n [attr.width]=\"size()\"\n [attr.height]=\"size()\"\n aria-hidden=\"true\"\n >\n <!-- Track arc: 260° arc (same as value-arc) so the background only covers\n the usable range, not a full 360° ring. -->\n <circle\n class=\"neu-knob__track\"\n [attr.cx]=\"size() / 2\"\n [attr.cy]=\"size() / 2\"\n [attr.r]=\"_radius()\"\n fill=\"none\"\n [attr.stroke-width]=\"_strokeWidth()\"\n stroke-linecap=\"round\"\n [attr.stroke-dasharray]=\"_arcDashArray()\"\n stroke-dashoffset=\"0\"\n [attr.transform]=\"'rotate(-220 ' + size() / 2 + ' ' + size() / 2 + ')'\"\n />\n <!-- Value arc -->\n <circle\n class=\"neu-knob__value-arc\"\n [attr.cx]=\"size() / 2\"\n [attr.cy]=\"size() / 2\"\n [attr.r]=\"_radius()\"\n fill=\"none\"\n [attr.stroke-width]=\"_strokeWidth()\"\n stroke-linecap=\"round\"\n [attr.stroke-dasharray]=\"_arcDashArray()\"\n [attr.stroke-dashoffset]=\"_arcDashOffset()\"\n [attr.transform]=\"'rotate(-220 ' + size() / 2 + ' ' + size() / 2 + ')'\"\n />\n <!-- Indicator dot -->\n <circle\n class=\"neu-knob__indicator\"\n [attr.cx]=\"_indicatorX()\"\n [attr.cy]=\"_indicatorY()\"\n [attr.r]=\"_strokeWidth() / 2 + 1\"\n [attr.transform]=\"\n 'rotate(' + _indicatorAngle() + ' ' + size() / 2 + ' ' + size() / 2 + ')'\n \"\n />\n </svg>\n @if (showValue()) {\n <span\n class=\"neu-knob__display\"\n style=\"color: var(--neu-knob-display-color, var(--neu-text, #0f172a)) !important; -webkit-text-fill-color: var(--neu-knob-display-color, var(--neu-text, #0f172a)) !important;\"\n >{{ _value() }}</span\n >\n }\n </div>\n @if (label()) {\n <label class=\"neu-knob__label\" [attr.for]=\"_id\">{{ label() }}</label>\n }\n `,\n styleUrl: './neu-knob.component.scss',\n})\nexport class NeuKnobComponent implements ControlValueAccessor {\n /** Valor mínimo / Min value */\n readonly min = input<number>(0);\n /** Valor máximo / Max value */\n readonly max = input<number>(100);\n /** Incremento por paso / Step increment */\n readonly step = input<number>(1);\n /** Tamaño del dial en px / Dial size in px */\n readonly size = input<number>(80);\n /** Muestra el valor numérico en el centro / Shows the numeric value in the center */\n readonly showValue = input<boolean>(true);\n /** Etiqueta visible / Visible label */\n readonly label = input<string>('');\n /** Emitido en cada cambio / Emitted on each change */\n readonly valueChange = output<number>();\n\n readonly _id = `neu-knob-${++_seq}`;\n readonly _cvaDisabled = signal(false);\n readonly _value = signal(0);\n\n readonly _strokeWidth = computed(() => Math.max(4, this.size() * 0.1));\n readonly _radius = computed(() => (this.size() - this._strokeWidth()) / 2 - 2);\n readonly _circumference = computed(() => 2 * Math.PI * this._radius());\n /** Arc spans 260° (from -40° to 220°) */\n readonly _arcLength = computed(() => (260 / 360) * this._circumference());\n\n readonly _normalizedValue = computed(() => {\n const range = this.max() - this.min();\n return range === 0 ? 0 : (this._value() - this.min()) / range;\n });\n\n readonly _arcDashArray = computed(() => `${this._arcLength()} ${this._circumference()}`);\n readonly _arcDashOffset = computed(() => this._arcLength() * (1 - this._normalizedValue()));\n\n // Indicator position on the track (relative to SVG center)\n // El arco empieza en rotate(-220°) desde el Este del SVG.\n // El punto indicador reposa en el Norte (12 en punto).\n // Para que el indicador siga el arco, la rotación CW debe ser:\n // θ = 230° + normalizedValue × 260°\n // (arco de 7:40 → 1:20 pasando por 12:00 en la mitad)\n // Arc starts at rotate(-220°) from East; indicator natural position is North (12 o'clock).\n // Correct clockwise rotation formula: θ = 230 + normalizedValue × 260.\n readonly _indicatorAngle = computed(() => this._normalizedValue() * 260 + 230);\n readonly _indicatorX = computed(() => this.size() / 2);\n readonly _indicatorY = computed(() => this.size() / 2 - this._radius());\n\n private _dragStartAngle = 0;\n private _dragStartValue = 0;\n private _onChange: (v: number) => void = () => {};\n private _onTouched: () => void = () => {};\n\n private readonly _el = inject(ElementRef<HTMLElement>);\n\n /** Calcula el ángulo en grados desde el centro del dial al punto (x, y).\n * Calculates the angle in degrees from the dial center to point (x, y). */\n private _getAngle(clientX: number, clientY: number): number {\n const dial = this._el.nativeElement.querySelector('.neu-knob__dial') as HTMLElement;\n const rect = dial\n ? dial.getBoundingClientRect()\n : this._el.nativeElement.getBoundingClientRect();\n const cx = rect.left + rect.width / 2;\n const cy = rect.top + rect.height / 2;\n return Math.atan2(clientY - cy, clientX - cx) * (180 / Math.PI);\n }\n\n readonly hostClasses = computed(() => ({\n 'neu-knob': true,\n 'neu-knob--disabled': this._cvaDisabled(),\n }));\n\n writeValue(val: number | null): void {\n this._value.set(this._clamp(val ?? this.min()));\n }\n\n registerOnChange(fn: (v: number) => void): void {\n this._onChange = fn;\n }\n registerOnTouched(fn: () => void): void {\n this._onTouched = fn;\n }\n setDisabledState(disabled: boolean): void {\n this._cvaDisabled.set(disabled);\n }\n\n onMouseDown(event: MouseEvent): void {\n if (this._cvaDisabled()) return;\n event.preventDefault();\n this._dragStartAngle = this._getAngle(event.clientX, event.clientY);\n this._dragStartValue = this._value();\n const onMove = (e: MouseEvent) => this._applyCircularDrag(e.clientX, e.clientY);\n const onUp = () => {\n window.removeEventListener('mousemove', onMove);\n window.removeEventListener('mouseup', onUp);\n };\n window.addEventListener('mousemove', onMove);\n window.addEventListener('mouseup', onUp);\n this._onTouched();\n }\n\n onTouchStart(event: TouchEvent): void {\n if (this._cvaDisabled()) return;\n event.preventDefault();\n this._dragStartAngle = this._getAngle(event.touches[0].clientX, event.touches[0].clientY);\n this._dragStartValue = this._value();\n const onMove = (e: TouchEvent) =>\n this._applyCircularDrag(e.touches[0].clientX, e.touches[0].clientY);\n const onEnd = () => {\n window.removeEventListener('touchmove', onMove);\n window.removeEventListener('touchend', onEnd);\n };\n window.addEventListener('touchmove', onMove, { passive: false });\n window.addEventListener('touchend', onEnd);\n this._onTouched();\n }\n\n onKeyDown(event: KeyboardEvent): void {\n if (this._cvaDisabled()) return;\n let delta = 0;\n if (event.key === 'ArrowUp' || event.key === 'ArrowRight') delta = this.step();\n else if (event.key === 'ArrowDown' || event.key === 'ArrowLeft') delta = -this.step();\n else if (event.key === 'Home') {\n this._emit(this.min());\n return;\n } else if (event.key === 'End') {\n this._emit(this.max());\n return;\n }\n if (delta !== 0) {\n event.preventDefault();\n this._emit(this._clamp(this._value() + delta));\n }\n }\n\n /** Aplica el drag circular calculando el delta de ángulo respecto al punto inicial.\n * Applies circular drag by computing the angle delta from the start point. */\n private _applyCircularDrag(clientX: number, clientY: number): void {\n let deltaAngle = this._getAngle(clientX, clientY) - this._dragStartAngle;\n // Normalizar a [-180, 180] para evitar saltos al cruzar el eje / Normalize to avoid jumps\n if (deltaAngle > 180) deltaAngle -= 360;\n if (deltaAngle < -180) deltaAngle += 360;\n const range = this.max() - this.min();\n // 260° de arco = rango completo / 260° arc = full range\n const valueDelta = (deltaAngle / 260) * range;\n this._emit(this._clamp(this._dragStartValue + valueDelta));\n }\n\n private _emit(value: number): void {\n const snapped = Math.round(value / this.step()) * this.step();\n const clamped = this._clamp(snapped);\n this._value.set(clamped);\n this._onChange(clamped);\n this.valueChange.emit(clamped);\n }\n\n private _clamp(v: number): number {\n return Math.min(this.max(), Math.max(this.min(), v));\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;AAcA,IAAI,IAAI,GAAG,CAAC;AAEZ;;;;;;AAMG;MAsFU,gBAAgB,CAAA;;AAElB,IAAA,GAAG,GAAG,KAAK,CAAS,CAAC,0EAAC;;AAEtB,IAAA,GAAG,GAAG,KAAK,CAAS,GAAG,0EAAC;;AAExB,IAAA,IAAI,GAAG,KAAK,CAAS,CAAC,2EAAC;;AAEvB,IAAA,IAAI,GAAG,KAAK,CAAS,EAAE,2EAAC;;AAExB,IAAA,SAAS,GAAG,KAAK,CAAU,IAAI,gFAAC;;AAEhC,IAAA,KAAK,GAAG,KAAK,CAAS,EAAE,4EAAC;;IAEzB,WAAW,GAAG,MAAM,EAAU;AAE9B,IAAA,GAAG,GAAG,CAAA,SAAA,EAAY,EAAE,IAAI,EAAE;AAC1B,IAAA,YAAY,GAAG,MAAM,CAAC,KAAK,mFAAC;AAC5B,IAAA,MAAM,GAAG,MAAM,CAAC,CAAC,6EAAC;IAElB,YAAY,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC,mFAAC;IAC7D,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,GAAG,CAAC,EAAA,IAAA,SAAA,GAAA,CAAA,EAAA,SAAA,EAAA,SAAA,EAAA,CAAA,8BAAA,EAAA,CAAA,CAAC;AACrE,IAAA,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,qFAAC;;AAE7D,IAAA,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,IAAI,IAAI,CAAC,cAAc,EAAE,iFAAC;AAEhE,IAAA,gBAAgB,GAAG,QAAQ,CAAC,MAAK;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE;QACrC,OAAO,KAAK,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,KAAK;AAC/D,IAAA,CAAC,uFAAC;AAEO,IAAA,aAAa,GAAG,QAAQ,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,IAAI,CAAC,cAAc,EAAE,CAAA,CAAE,oFAAC;IAC/E,cAAc,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC,qFAAC;;;;;;;;;AAUlF,IAAA,eAAe,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,GAAG,GAAG,GAAG,GAAG,sFAAC;AACrE,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,kFAAC;AAC7C,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,kFAAC;IAE/D,eAAe,GAAG,CAAC;IACnB,eAAe,GAAG,CAAC;AACnB,IAAA,SAAS,GAAwB,MAAK,EAAE,CAAC;AACzC,IAAA,UAAU,GAAe,MAAK,EAAE,CAAC;AAExB,IAAA,GAAG,GAAG,MAAM,EAAC,UAAuB,EAAC;AAEtD;AAC4E;IACpE,SAAS,CAAC,OAAe,EAAE,OAAe,EAAA;AAChD,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,aAAa,CAAC,iBAAiB,CAAgB;QACnF,MAAM,IAAI,GAAG;AACX,cAAE,IAAI,CAAC,qBAAqB;cAC1B,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,qBAAqB,EAAE;QAClD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;QACrC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC;QACrC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC;IACjE;AAES,IAAA,WAAW,GAAG,QAAQ,CAAC,OAAO;AACrC,QAAA,UAAU,EAAE,IAAI;AAChB,QAAA,oBAAoB,EAAE,IAAI,CAAC,YAAY,EAAE;AAC1C,KAAA,CAAC,kFAAC;AAEH,IAAA,UAAU,CAAC,GAAkB,EAAA;AAC3B,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACjD;AAEA,IAAA,gBAAgB,CAAC,EAAuB,EAAA;AACtC,QAAA,IAAI,CAAC,SAAS,GAAG,EAAE;IACrB;AACA,IAAA,iBAAiB,CAAC,EAAc,EAAA;AAC9B,QAAA,IAAI,CAAC,UAAU,GAAG,EAAE;IACtB;AACA,IAAA,gBAAgB,CAAC,QAAiB,EAAA;AAChC,QAAA,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC;IACjC;AAEA,IAAA,WAAW,CAAC,KAAiB,EAAA;QAC3B,IAAI,IAAI,CAAC,YAAY,EAAE;YAAE;QACzB,KAAK,CAAC,cAAc,EAAE;AACtB,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;AACnE,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,MAAM,EAAE;AACpC,QAAA,MAAM,MAAM,GAAG,CAAC,CAAa,KAAK,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC;QAC/E,MAAM,IAAI,GAAG,MAAK;AAChB,YAAA,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,MAAM,CAAC;AAC/C,YAAA,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC;AAC7C,QAAA,CAAC;AACD,QAAA,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,MAAM,CAAC;AAC5C,QAAA,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC;QACxC,IAAI,CAAC,UAAU,EAAE;IACnB;AAEA,IAAA,YAAY,CAAC,KAAiB,EAAA;QAC5B,IAAI,IAAI,CAAC,YAAY,EAAE;YAAE;QACzB,KAAK,CAAC,cAAc,EAAE;QACtB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;AACzF,QAAA,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,MAAM,EAAE;AACpC,QAAA,MAAM,MAAM,GAAG,CAAC,CAAa,KAC3B,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACrE,MAAM,KAAK,GAAG,MAAK;AACjB,YAAA,MAAM,CAAC,mBAAmB,CAAC,WAAW,EAAE,MAAM,CAAC;AAC/C,YAAA,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,KAAK,CAAC;AAC/C,QAAA,CAAC;AACD,QAAA,MAAM,CAAC,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAChE,QAAA,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,KAAK,CAAC;QAC1C,IAAI,CAAC,UAAU,EAAE;IACnB;AAEA,IAAA,SAAS,CAAC,KAAoB,EAAA;QAC5B,IAAI,IAAI,CAAC,YAAY,EAAE;YAAE;QACzB,IAAI,KAAK,GAAG,CAAC;QACb,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,KAAK,YAAY;AAAE,YAAA,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE;aACzE,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW;AAAE,YAAA,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE;AAChF,aAAA,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,EAAE;YAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACtB;QACF;AAAO,aAAA,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,EAAE;YAC9B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACtB;QACF;AACA,QAAA,IAAI,KAAK,KAAK,CAAC,EAAE;YACf,KAAK,CAAC,cAAc,EAAE;AACtB,YAAA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC;QAChD;IACF;AAEA;AAC+E;IACvE,kBAAkB,CAAC,OAAe,EAAE,OAAe,EAAA;AACzD,QAAA,IAAI,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,eAAe;;QAExE,IAAI,UAAU,GAAG,GAAG;YAAE,UAAU,IAAI,GAAG;QACvC,IAAI,UAAU,GAAG,CAAC,GAAG;YAAE,UAAU,IAAI,GAAG;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE;;QAErC,MAAM,UAAU,GAAG,CAAC,UAAU,GAAG,GAAG,IAAI,KAAK;AAC7C,QAAA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,GAAG,UAAU,CAAC,CAAC;IAC5D;AAEQ,IAAA,KAAK,CAAC,KAAa,EAAA;AACzB,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE;QAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;AACpC,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;AACxB,QAAA,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;AACvB,QAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC;IAChC;AAEQ,IAAA,MAAM,CAAC,CAAS,EAAA;QACtB,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IACtD;wGA5JW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAhB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,GAAA,EAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,UAAA,EAAA,KAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,eAAA,EAAA,EAAA,EAAA,SAAA,EA/EhB;AACT,YAAA,EAAE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,UAAU,CAAC,MAAM,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;SAC7F,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EACS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyET,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,ykCAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;4FAGU,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBArF5B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,UAAU,WACX,EAAE,EAAA,aAAA,EACI,iBAAiB,CAAC,IAAI,EAAA,eAAA,EACpB,uBAAuB,CAAC,MAAM,QACzC,EAAE,SAAS,EAAE,eAAe,EAAE,EAAA,SAAA,EACzB;AACT,wBAAA,EAAE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,UAAU,CAAC,sBAAsB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;qBAC7F,EAAA,QAAA,EACS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyET,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,ykCAAA,CAAA,EAAA;;;ACzGH;;AAEG;;;;"}
@@ -36,8 +36,8 @@ class NeuMeterGroupComponent {
36
36
  pct: Math.max(0, Math.min(100, (item.value / total) * 100)),
37
37
  }));
38
38
  }, ...(ngDevMode ? [{ debugName: "_segments" }] : /* istanbul ignore next */ []));
39
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuMeterGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
40
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: NeuMeterGroupComponent, isStandalone: true, selector: "neu-meter-group", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, showLegend: { classPropertyName: "showLegend", publicName: "showLegend", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
39
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuMeterGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
40
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuMeterGroupComponent, isStandalone: true, selector: "neu-meter-group", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, showLegend: { classPropertyName: "showLegend", publicName: "showLegend", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
41
41
  <div
42
42
  class="neu-meter-group__bar"
43
43
  role="meter"
@@ -74,7 +74,7 @@ class NeuMeterGroupComponent {
74
74
  }
75
75
  `, isInline: true, styles: ["@charset \"UTF-8\";.neu-meter-group{display:flex;flex-direction:column;gap:10px;width:100%}.neu-meter-group--rounded .neu-meter-group__bar{border-radius:var(--neu-radius-full, 9999px)}.neu-meter-group__bar{display:flex;width:100%;height:12px;background:var(--neu-meter-track, #e5e7eb);overflow:hidden;border-radius:0}.neu-meter-group__segment{height:100%;transition:width .4s cubic-bezier(.4,0,.2,1);flex-shrink:0}.neu-meter-group__segment[data-index=\"0\"]:not([style*=background]){background:var(--neu-color-primary, #0ea5e9)}.neu-meter-group__segment[data-index=\"1\"]:not([style*=background]){background:var(--neu-color-success, #22c55e)}.neu-meter-group__segment[data-index=\"2\"]:not([style*=background]){background:var(--neu-color-warning, #f59e0b)}.neu-meter-group__segment[data-index=\"3\"]:not([style*=background]){background:var(--neu-color-danger, #ef4444)}.neu-meter-group__segment[data-index=\"4\"]:not([style*=background]){background:var(--neu-color-secondary, #8b5cf6)}.neu-meter-group__legend{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:8px 16px}.neu-meter-group__legend-item{display:flex;align-items:center;gap:6px;font-size:.8125rem;color:var(--neu-text-muted, #6b7280)}.neu-meter-group__legend-dot{display:inline-block;width:10px;height:10px;border-radius:50%;flex-shrink:0}.neu-meter-group__legend-dot[data-index=\"0\"]:not([style*=background]){background:var(--neu-color-primary, #0ea5e9)}.neu-meter-group__legend-dot[data-index=\"1\"]:not([style*=background]){background:var(--neu-color-success, #22c55e)}.neu-meter-group__legend-dot[data-index=\"2\"]:not([style*=background]){background:var(--neu-color-warning, #f59e0b)}.neu-meter-group__legend-dot[data-index=\"3\"]:not([style*=background]){background:var(--neu-color-danger, #ef4444)}.neu-meter-group__legend-dot[data-index=\"4\"]:not([style*=background]){background:var(--neu-color-secondary, #8b5cf6)}.neu-meter-group__legend-label{color:var(--neu-text, #111)}.neu-meter-group__legend-value{font-variant-numeric:tabular-nums;color:var(--neu-text-muted, #6b7280)}\n"], dependencies: [{ kind: "pipe", type: DecimalPipe, name: "number" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
76
76
  }
77
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuMeterGroupComponent, decorators: [{
77
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuMeterGroupComponent, decorators: [{
78
78
  type: Component,
79
79
  args: [{ selector: 'neu-meter-group', imports: [DecimalPipe], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: { '[class]': 'hostClasses()' }, template: `
80
80
  <div
@@ -1 +1 @@
1
- {"version":3,"file":"neural-ui-core-meter-group.mjs","sources":["../../../../projects/ui-core/meter-group/neu-meter-group.component.ts","../../../../projects/ui-core/meter-group/neural-ui-core-meter-group.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n} from '@angular/core';\nimport { DecimalPipe } from '@angular/common';\n\nexport interface NeuMeterItem {\n /** Etiqueta del segmento / Segment label */\n label: string;\n /** Valor numérico del segmento / Numeric value of the segment */\n value: number;\n /** Color CSS opcional / Optional CSS color */\n color?: string;\n}\n\n/**\n * NeuralUI MeterGroup Component\n *\n * Barra de progreso multi-segmento que muestra la distribución de valores.\n *\n * Uso:\n * <neu-meter-group [items]=\"meters\" [total]=\"100\" />\n */\n@Component({\n selector: 'neu-meter-group',\n imports: [DecimalPipe],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '[class]': 'hostClasses()' },\n template: `\n <div\n class=\"neu-meter-group__bar\"\n role=\"meter\"\n [style.height.px]=\"height()\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"_effectiveTotal()\"\n [attr.aria-valuenow]=\"_usedSum()\"\n [attr.aria-label]=\"ariaLabel()\"\n >\n @for (item of _segments(); track item.label) {\n <div\n class=\"neu-meter-group__segment\"\n [style.width.%]=\"item.pct\"\n [style.background]=\"item.color || null\"\n [attr.title]=\"item.label + ': ' + item.value\"\n [attr.data-index]=\"$index\"\n ></div>\n }\n </div>\n @if (showLegend()) {\n <ul class=\"neu-meter-group__legend\" aria-hidden=\"true\">\n @for (item of _segments(); track item.label) {\n <li class=\"neu-meter-group__legend-item\">\n <span\n class=\"neu-meter-group__legend-dot\"\n [style.background]=\"item.color || null\"\n [attr.data-index]=\"$index\"\n ></span>\n <span class=\"neu-meter-group__legend-label\">{{ item.label }}</span>\n <span class=\"neu-meter-group__legend-value\">{{ item.pct | number: '1.0-1' }}%</span>\n </li>\n }\n </ul>\n }\n `,\n styleUrl: './neu-meter-group.component.scss',\n})\nexport class NeuMeterGroupComponent {\n /** Segmentos del medidor / Meter segments */\n readonly items = input<NeuMeterItem[]>([]);\n\n /** Total de referencia (0 = suma de items) / Reference total (0 = sum of items) */\n readonly total = input<number>(0);\n\n /** Altura de la barra en px / Bar height in px */\n readonly height = input<number>(12);\n\n /** Esquinas redondeadas / Rounded corners */\n readonly rounded = input<boolean>(true);\n\n /** Muestra leyenda debajo / Shows legend below */\n readonly showLegend = input<boolean>(true);\n\n /** Aria-label de la barra / Aria-label for the bar */\n readonly ariaLabel = input<string>('Medidor');\n\n readonly hostClasses = computed(() => ({\n 'neu-meter-group': true,\n 'neu-meter-group--rounded': this.rounded(),\n }));\n\n readonly _usedSum = computed(() => this.items().reduce((s, i) => s + i.value, 0));\n\n readonly _effectiveTotal = computed(() =>\n this.total() > 0 ? this.total() : this._usedSum() || 1,\n );\n\n readonly _segments = computed(() => {\n const total = this._effectiveTotal();\n return this.items().map((item) => ({\n ...item,\n pct: Math.max(0, Math.min(100, (item.value / total) * 100)),\n }));\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;AAkBA;;;;;;;AAOG;MA6CU,sBAAsB,CAAA;;AAExB,IAAA,KAAK,GAAG,KAAK,CAAiB,EAAE,4EAAC;;AAGjC,IAAA,KAAK,GAAG,KAAK,CAAS,CAAC,4EAAC;;AAGxB,IAAA,MAAM,GAAG,KAAK,CAAS,EAAE,6EAAC;;AAG1B,IAAA,OAAO,GAAG,KAAK,CAAU,IAAI,8EAAC;;AAG9B,IAAA,UAAU,GAAG,KAAK,CAAU,IAAI,iFAAC;;AAGjC,IAAA,SAAS,GAAG,KAAK,CAAS,SAAS,gFAAC;AAEpC,IAAA,WAAW,GAAG,QAAQ,CAAC,OAAO;AACrC,QAAA,iBAAiB,EAAE,IAAI;AACvB,QAAA,0BAA0B,EAAE,IAAI,CAAC,OAAO,EAAE;AAC3C,KAAA,CAAC,kFAAC;AAEM,IAAA,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,+EAAC;AAExE,IAAA,eAAe,GAAG,QAAQ,CAAC,MAClC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,sFACvD;AAEQ,IAAA,SAAS,GAAG,QAAQ,CAAC,MAAK;AACjC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,EAAE;AACpC,QAAA,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM;AACjC,YAAA,GAAG,IAAI;YACP,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;AAC5D,SAAA,CAAC,CAAC;AACL,IAAA,CAAC,gFAAC;uGApCS,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,MAAA,EAAA,EAAA,iBAAA,EAAA,QAAA,EAAA,UAAA,EAAA,QAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,eAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAtCvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,ohEAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAvCS,WAAW,EAAA,IAAA,EAAA,QAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FA0CV,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBA5ClC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,iBAAiB,WAClB,CAAC,WAAW,CAAC,EAAA,aAAA,EACP,iBAAiB,CAAC,IAAI,EAAA,eAAA,EACpB,uBAAuB,CAAC,MAAM,EAAA,IAAA,EACzC,EAAE,SAAS,EAAE,eAAe,EAAE,EAAA,QAAA,EAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,ohEAAA,CAAA,EAAA;;;ACnEH;;AAEG;;;;"}
1
+ {"version":3,"file":"neural-ui-core-meter-group.mjs","sources":["../../../../projects/ui-core/meter-group/neu-meter-group.component.ts","../../../../projects/ui-core/meter-group/neural-ui-core-meter-group.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n} from '@angular/core';\nimport { DecimalPipe } from '@angular/common';\n\nexport interface NeuMeterItem {\n /** Etiqueta del segmento / Segment label */\n label: string;\n /** Valor numérico del segmento / Numeric value of the segment */\n value: number;\n /** Color CSS opcional / Optional CSS color */\n color?: string;\n}\n\n/**\n * NeuralUI MeterGroup Component\n *\n * Barra de progreso multi-segmento que muestra la distribución de valores.\n *\n * Uso:\n * <neu-meter-group [items]=\"meters\" [total]=\"100\" />\n */\n@Component({\n selector: 'neu-meter-group',\n imports: [DecimalPipe],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '[class]': 'hostClasses()' },\n template: `\n <div\n class=\"neu-meter-group__bar\"\n role=\"meter\"\n [style.height.px]=\"height()\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"_effectiveTotal()\"\n [attr.aria-valuenow]=\"_usedSum()\"\n [attr.aria-label]=\"ariaLabel()\"\n >\n @for (item of _segments(); track item.label) {\n <div\n class=\"neu-meter-group__segment\"\n [style.width.%]=\"item.pct\"\n [style.background]=\"item.color || null\"\n [attr.title]=\"item.label + ': ' + item.value\"\n [attr.data-index]=\"$index\"\n ></div>\n }\n </div>\n @if (showLegend()) {\n <ul class=\"neu-meter-group__legend\" aria-hidden=\"true\">\n @for (item of _segments(); track item.label) {\n <li class=\"neu-meter-group__legend-item\">\n <span\n class=\"neu-meter-group__legend-dot\"\n [style.background]=\"item.color || null\"\n [attr.data-index]=\"$index\"\n ></span>\n <span class=\"neu-meter-group__legend-label\">{{ item.label }}</span>\n <span class=\"neu-meter-group__legend-value\">{{ item.pct | number: '1.0-1' }}%</span>\n </li>\n }\n </ul>\n }\n `,\n styleUrl: './neu-meter-group.component.scss',\n})\nexport class NeuMeterGroupComponent {\n /** Segmentos del medidor / Meter segments */\n readonly items = input<NeuMeterItem[]>([]);\n\n /** Total de referencia (0 = suma de items) / Reference total (0 = sum of items) */\n readonly total = input<number>(0);\n\n /** Altura de la barra en px / Bar height in px */\n readonly height = input<number>(12);\n\n /** Esquinas redondeadas / Rounded corners */\n readonly rounded = input<boolean>(true);\n\n /** Muestra leyenda debajo / Shows legend below */\n readonly showLegend = input<boolean>(true);\n\n /** Aria-label de la barra / Aria-label for the bar */\n readonly ariaLabel = input<string>('Medidor');\n\n readonly hostClasses = computed(() => ({\n 'neu-meter-group': true,\n 'neu-meter-group--rounded': this.rounded(),\n }));\n\n readonly _usedSum = computed(() => this.items().reduce((s, i) => s + i.value, 0));\n\n readonly _effectiveTotal = computed(() =>\n this.total() > 0 ? this.total() : this._usedSum() || 1,\n );\n\n readonly _segments = computed(() => {\n const total = this._effectiveTotal();\n return this.items().map((item) => ({\n ...item,\n pct: Math.max(0, Math.min(100, (item.value / total) * 100)),\n }));\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
@@ -81,8 +81,8 @@ class NeuDialogComponent {
81
81
  getFocusableElements(panel) {
82
82
  return Array.from(panel.querySelectorAll('button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter((element) => !element.hasAttribute('aria-hidden'));
83
83
  }
84
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
85
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: NeuDialogComponent, isStandalone: true, selector: "neu-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disableClose: { classPropertyName: "disableClose", publicName: "disableClose", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, host: { properties: { "class.neu-dialog--open": "open()", "attr.aria-hidden": "!open()" } }, viewQueries: [{ propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: `
84
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
85
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuDialogComponent, isStandalone: true, selector: "neu-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disableClose: { classPropertyName: "disableClose", publicName: "disableClose", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, host: { properties: { "class.neu-dialog--open": "open()", "attr.aria-hidden": "!open()" } }, viewQueries: [{ propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: `
86
86
  @if (open()) {
87
87
  <!-- Backdrop -->
88
88
  <div
@@ -128,7 +128,7 @@ class NeuDialogComponent {
128
128
  }
129
129
  `, isInline: true, styles: [".neu-dialog-backdrop{position:fixed;inset:0;background:var(--neu-overlay-bg);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:calc(var(--neu-z-modal, 200) - 1);animation:neu-backdrop-in .15s ease both}@keyframes neu-backdrop-in{0%{opacity:0}to{opacity:1}}.neu-dialog-panel{background:var(--neu-surface);border-radius:var(--neu-radius-lg, 16px);box-shadow:var(--neu-shadow-lg);border:1px solid var(--neu-border);outline:none;display:flex;flex-direction:column;max-height:90dvh;overflow:hidden;animation:neu-dialog-in .2s cubic-bezier(.22,1,.36,1) both}.neu-dialog-panel--sm{width:min(100% - 2rem,400px)}.neu-dialog-panel--md{width:min(100% - 2rem,560px)}.neu-dialog-panel--lg{width:min(100% - 2rem,720px)}.neu-dialog-panel--xl{width:min(100% - 2rem,900px)}.neu-dialog-panel--full{width:min(100% - 2rem,1120px)}@keyframes neu-dialog-in{0%{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}neu-dialog{display:contents}.neu-dialog__backdrop{position:fixed;inset:0;background:var(--neu-overlay-bg);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:calc(var(--neu-z-modal, 200) - 1);animation:neu-backdrop-in .15s ease both}.neu-dialog__panel{position:fixed;inset:0;margin:auto;background:var(--neu-surface);border-radius:var(--neu-radius-lg, 16px);box-shadow:var(--neu-shadow-lg);border:1px solid var(--neu-border);display:flex;flex-direction:column;z-index:var(--neu-z-modal, 200);max-height:90dvh;overflow:hidden;animation:neu-dialog-in .2s cubic-bezier(.22,1,.36,1) both;height:fit-content}.neu-dialog__panel--sm{width:min(100% - 2rem,400px)}.neu-dialog__panel--md{width:min(100% - 2rem,560px)}.neu-dialog__panel--lg{width:min(100% - 2rem,720px)}.neu-dialog__panel--xl{width:min(100% - 2rem,900px)}.neu-dialog__panel--full{width:min(100% - 2rem,1120px)}.neu-dialog__header{display:flex;align-items:center;justify-content:space-between;padding:var(--neu-space-4, 1rem) var(--neu-space-5, 1.25rem);border-bottom:1px solid var(--neu-border);gap:var(--neu-space-3, .75rem);flex-shrink:0}.neu-dialog__title{margin:0;font-size:var(--neu-text-lg, 1.125rem);font-weight:600;color:var(--neu-text);line-height:1.3}.neu-dialog__close{display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:1px solid var(--neu-border);border-radius:var(--neu-radius);background:transparent;color:var(--neu-text-muted);cursor:pointer;transition:all var(--neu-transition);flex-shrink:0;padding:0}.neu-dialog__close:hover{background:var(--neu-surface-2);color:var(--neu-text);border-color:var(--neu-border-hover)}.neu-dialog__body{padding:var(--neu-space-5, 1.25rem);overflow-y:auto;flex:1;overscroll-behavior:contain;color:var(--neu-text);font-size:var(--neu-text-sm, .875rem);line-height:1.6}[neu-dialog-footer]{display:flex;align-items:center;justify-content:flex-end;gap:var(--neu-space-3, .75rem);padding:var(--neu-space-4, 1rem) var(--neu-space-5, 1.25rem);border-top:1px solid var(--neu-border);flex-shrink:0}\n"], dependencies: [{ kind: "component", type: NeuIconComponent, selector: "neu-icon", inputs: ["name", "strokeWidth", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
130
130
  }
131
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuDialogComponent, decorators: [{
131
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuDialogComponent, decorators: [{
132
132
  type: Component,
133
133
  args: [{ selector: 'neu-dialog', imports: [NeuIconComponent], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
134
134
  '[class.neu-dialog--open]': 'open()',
@@ -190,10 +190,10 @@ class NeuDialogService {
190
190
  disableClose: config?.disableClose ?? false,
191
191
  });
192
192
  }
193
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
194
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuDialogService, providedIn: 'root' });
193
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
194
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuDialogService, providedIn: 'root' });
195
195
  }
196
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuDialogService, decorators: [{
196
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuDialogService, decorators: [{
197
197
  type: Injectable,
198
198
  args: [{ providedIn: 'root' }]
199
199
  }] });
@@ -1 +1 @@
1
- {"version":3,"file":"neural-ui-core-modal.mjs","sources":["../../../../projects/ui-core/modal/neu-modal.component.ts","../../../../projects/ui-core/modal/neu-dialog.service.ts","../../../../projects/ui-core/modal/neural-ui-core-modal.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n effect,\n input,\n output,\n viewChild,\n} from '@angular/core';\nimport { NeuIconComponent } from '@neural-ui/core/icon';\n\nexport type NeuDialogSize = 'sm' | 'md' | 'lg' | 'xl' | 'full';\n\n/**\n * NeuDialogComponent — Diálogo accesible con header, body y footer. / Accessible dialog with header, body and footer.\n * Úsalo directamente como componente declarativo pasando `open` como signal. / Use it directly as a declarative component passing `open` as a signal.\n *\n * Para uso programático, utiliza NeuDialogService.open().\n *\n * Uso declarativo:\n * <neu-dialog [open]=\"isOpen()\" title=\"Editar usuario\" (closed)=\"isOpen.set(false)\">\n * <p>Contenido del diálogo</p>\n * <div neu-dialog-footer>\n * <neu-button (click)=\"save()\">Guardar</neu-button>\n * </div>\n * </neu-dialog>\n */\n@Component({\n selector: 'neu-dialog',\n imports: [NeuIconComponent],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.neu-dialog--open]': 'open()',\n '[attr.aria-hidden]': '!open()',\n },\n template: `\n @if (open()) {\n <!-- Backdrop -->\n <div\n class=\"neu-dialog__backdrop\"\n (click)=\"!disableClose() && closed.emit()\"\n aria-hidden=\"true\"\n ></div>\n\n <!-- Panel -->\n <div\n #panel\n class=\"neu-dialog__panel neu-dialog__panel--{{ size() }}\"\n role=\"dialog\"\n tabindex=\"-1\"\n [id]=\"'neu-dialog-' + _uid\"\n [attr.aria-labelledby]=\"'neu-dialog-title-' + _uid\"\n [attr.aria-modal]=\"true\"\n (keydown)=\"onPanelKeydown($event)\"\n >\n <!-- Header -->\n <div class=\"neu-dialog__header\">\n <h2 class=\"neu-dialog__title\" [id]=\"'neu-dialog-title-' + _uid\">{{ title() }}</h2>\n @if (!disableClose()) {\n <button\n class=\"neu-dialog__close\"\n type=\"button\"\n aria-label=\"Close dialog\"\n (click)=\"closed.emit()\"\n >\n <neu-icon name=\"lucideX\" size=\"1.125rem\" />\n </button>\n }\n </div>\n\n <!-- Body -->\n <div class=\"neu-dialog__body\">\n <ng-content />\n </div>\n\n <!-- Footer (opcional via slot) -->\n <ng-content select=\"[neu-dialog-footer]\" />\n </div>\n }\n `,\n styleUrl: './neu-modal.component.scss',\n})\nexport class NeuDialogComponent {\n /** Controla la visibilidad del diálogo. / Controls dialog visibility. */\n open = input<boolean>(false);\n /** Título que aparece en el header. / Title shown in the header. */\n title = input<string>('');\n /** Tamaño del panel: sm | md | lg | xl | full. / Panel size: sm | md | lg | xl | full. */\n size = input<NeuDialogSize>('md');\n /** Si es true, el backdrop y el botón cerrar no funcionan. / If true, the backdrop and close button do not work. */\n disableClose = input<boolean>(false);\n\n /** Emite cuando el usuario cierra el diálogo. / Emits when the user closes the dialog. */\n closed = output<void>();\n\n private readonly panelRef = viewChild<ElementRef<HTMLElement>>('panel');\n\n /** @internal — ID único para aria-labelledby / Unique ID for aria-labelledby */\n readonly _uid = Math.random().toString(36).slice(2, 7);\n\n constructor() {\n effect(() => {\n if (!this.open()) return;\n\n queueMicrotask(() => this.focusInitialElement());\n });\n }\n\n onPanelKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n if (!this.disableClose()) {\n this.closed.emit();\n }\n return;\n }\n\n if (event.key !== 'Tab') return;\n\n const panel = this.panelRef()?.nativeElement;\n if (!panel) return;\n\n const focusable = this.getFocusableElements(panel);\n if (!focusable.length) {\n event.preventDefault();\n panel.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const activeElement = document.activeElement as HTMLElement | null;\n\n if (event.shiftKey) {\n if (activeElement === first || activeElement === panel) {\n event.preventDefault();\n last.focus();\n }\n return;\n }\n\n if (activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n }\n\n private focusInitialElement(): void {\n const panel = this.panelRef()?.nativeElement;\n if (!panel) return;\n\n const [firstFocusable] = this.getFocusableElements(panel);\n (firstFocusable ?? panel).focus();\n }\n\n private getFocusableElements(panel: HTMLElement): HTMLElement[] {\n return Array.from(\n panel.querySelectorAll<HTMLElement>(\n 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\n ),\n ).filter((element) => !element.hasAttribute('aria-hidden'));\n }\n}\n","import { Injectable, Type, inject } from '@angular/core';\nimport { Dialog, DialogConfig, DialogRef } from '@angular/cdk/dialog';\nimport { NeuDialogSize } from './neu-modal.component';\n\n/** Datos que se inyectan en el componente del diálogo / Data injected into the dialog component */\nexport interface NeuDialogData<T = unknown> {\n title?: string;\n data?: T;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class NeuDialogService {\n private readonly dialog = inject(Dialog);\n\n open<T = unknown, R = unknown>(\n component: Type<unknown>,\n config?: {\n title?: string;\n data?: T;\n size?: NeuDialogSize;\n disableClose?: boolean;\n },\n ): DialogRef<R> {\n return this.dialog.open<R>(component, {\n data: { title: config?.title, data: config?.data } satisfies NeuDialogData<T>,\n panelClass: ['neu-dialog-panel', `neu-dialog-panel--${config?.size ?? 'md'}`],\n backdropClass: 'neu-dialog-backdrop',\n disableClose: config?.disableClose ?? false,\n } satisfies DialogConfig);\n }\n}","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"neural-ui-core-modal.mjs","sources":["../../../../projects/ui-core/modal/neu-modal.component.ts","../../../../projects/ui-core/modal/neu-dialog.service.ts","../../../../projects/ui-core/modal/neural-ui-core-modal.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n effect,\n input,\n output,\n viewChild,\n} from '@angular/core';\nimport { NeuIconComponent } from '@neural-ui/core/icon';\n\nexport type NeuDialogSize = 'sm' | 'md' | 'lg' | 'xl' | 'full';\n\n/**\n * NeuDialogComponent — Diálogo accesible con header, body y footer. / Accessible dialog with header, body and footer.\n * Úsalo directamente como componente declarativo pasando `open` como signal. / Use it directly as a declarative component passing `open` as a signal.\n *\n * Para uso programático, utiliza NeuDialogService.open().\n *\n * Uso declarativo:\n * <neu-dialog [open]=\"isOpen()\" title=\"Editar usuario\" (closed)=\"isOpen.set(false)\">\n * <p>Contenido del diálogo</p>\n * <div neu-dialog-footer>\n * <neu-button (click)=\"save()\">Guardar</neu-button>\n * </div>\n * </neu-dialog>\n */\n@Component({\n selector: 'neu-dialog',\n imports: [NeuIconComponent],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.neu-dialog--open]': 'open()',\n '[attr.aria-hidden]': '!open()',\n },\n template: `\n @if (open()) {\n <!-- Backdrop -->\n <div\n class=\"neu-dialog__backdrop\"\n (click)=\"!disableClose() && closed.emit()\"\n aria-hidden=\"true\"\n ></div>\n\n <!-- Panel -->\n <div\n #panel\n class=\"neu-dialog__panel neu-dialog__panel--{{ size() }}\"\n role=\"dialog\"\n tabindex=\"-1\"\n [id]=\"'neu-dialog-' + _uid\"\n [attr.aria-labelledby]=\"'neu-dialog-title-' + _uid\"\n [attr.aria-modal]=\"true\"\n (keydown)=\"onPanelKeydown($event)\"\n >\n <!-- Header -->\n <div class=\"neu-dialog__header\">\n <h2 class=\"neu-dialog__title\" [id]=\"'neu-dialog-title-' + _uid\">{{ title() }}</h2>\n @if (!disableClose()) {\n <button\n class=\"neu-dialog__close\"\n type=\"button\"\n aria-label=\"Close dialog\"\n (click)=\"closed.emit()\"\n >\n <neu-icon name=\"lucideX\" size=\"1.125rem\" />\n </button>\n }\n </div>\n\n <!-- Body -->\n <div class=\"neu-dialog__body\">\n <ng-content />\n </div>\n\n <!-- Footer (opcional via slot) -->\n <ng-content select=\"[neu-dialog-footer]\" />\n </div>\n }\n `,\n styleUrl: './neu-modal.component.scss',\n})\nexport class NeuDialogComponent {\n /** Controla la visibilidad del diálogo. / Controls dialog visibility. */\n open = input<boolean>(false);\n /** Título que aparece en el header. / Title shown in the header. */\n title = input<string>('');\n /** Tamaño del panel: sm | md | lg | xl | full. / Panel size: sm | md | lg | xl | full. */\n size = input<NeuDialogSize>('md');\n /** Si es true, el backdrop y el botón cerrar no funcionan. / If true, the backdrop and close button do not work. */\n disableClose = input<boolean>(false);\n\n /** Emite cuando el usuario cierra el diálogo. / Emits when the user closes the dialog. */\n closed = output<void>();\n\n private readonly panelRef = viewChild<ElementRef<HTMLElement>>('panel');\n\n /** @internal — ID único para aria-labelledby / Unique ID for aria-labelledby */\n readonly _uid = Math.random().toString(36).slice(2, 7);\n\n constructor() {\n effect(() => {\n if (!this.open()) return;\n\n queueMicrotask(() => this.focusInitialElement());\n });\n }\n\n onPanelKeydown(event: KeyboardEvent): void {\n if (event.key === 'Escape') {\n if (!this.disableClose()) {\n this.closed.emit();\n }\n return;\n }\n\n if (event.key !== 'Tab') return;\n\n const panel = this.panelRef()?.nativeElement;\n if (!panel) return;\n\n const focusable = this.getFocusableElements(panel);\n if (!focusable.length) {\n event.preventDefault();\n panel.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const activeElement = document.activeElement as HTMLElement | null;\n\n if (event.shiftKey) {\n if (activeElement === first || activeElement === panel) {\n event.preventDefault();\n last.focus();\n }\n return;\n }\n\n if (activeElement === last) {\n event.preventDefault();\n first.focus();\n }\n }\n\n private focusInitialElement(): void {\n const panel = this.panelRef()?.nativeElement;\n if (!panel) return;\n\n const [firstFocusable] = this.getFocusableElements(panel);\n (firstFocusable ?? panel).focus();\n }\n\n private getFocusableElements(panel: HTMLElement): HTMLElement[] {\n return Array.from(\n panel.querySelectorAll<HTMLElement>(\n 'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])',\n ),\n ).filter((element) => !element.hasAttribute('aria-hidden'));\n }\n}\n","import { Injectable, Type, inject } from '@angular/core';\nimport { Dialog, DialogConfig, DialogRef } from '@angular/cdk/dialog';\nimport { NeuDialogSize } from './neu-modal.component';\n\n/** Datos que se inyectan en el componente del diálogo / Data injected into the dialog component */\nexport interface NeuDialogData<T = unknown> {\n title?: string;\n data?: T;\n}\n\n@Injectable({ providedIn: 'root' })\nexport class NeuDialogService {\n private readonly dialog = inject(Dialog);\n\n open<T = unknown, R = unknown>(\n component: Type<unknown>,\n config?: {\n title?: string;\n data?: T;\n size?: NeuDialogSize;\n disableClose?: boolean;\n },\n ): DialogRef<R> {\n return this.dialog.open<R>(component, {\n data: { title: config?.title, data: config?.data } satisfies NeuDialogData<T>,\n panelClass: ['neu-dialog-panel', `neu-dialog-panel--${config?.size ?? 'md'}`],\n backdropClass: 'neu-dialog-backdrop',\n disableClose: config?.disableClose ?? false,\n } satisfies DialogConfig);\n }\n}","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
@@ -22,10 +22,10 @@ import { NG_VALUE_ACCESSOR } from '@angular/forms';
22
22
  */
23
23
  class NeuMultiselectItemDirective {
24
24
  templateRef = inject(TemplateRef);
25
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuMultiselectItemDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
26
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.8", type: NeuMultiselectItemDirective, isStandalone: true, selector: "[neuMultiselectItem]", ngImport: i0 });
25
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuMultiselectItemDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
26
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.17", type: NeuMultiselectItemDirective, isStandalone: true, selector: "[neuMultiselectItem]", ngImport: i0 });
27
27
  }
28
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuMultiselectItemDirective, decorators: [{
28
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuMultiselectItemDirective, decorators: [{
29
29
  type: Directive,
30
30
  args: [{ selector: '[neuMultiselectItem]', standalone: true }]
31
31
  }] });
@@ -423,8 +423,8 @@ class NeuMultiselectComponent {
423
423
  this._viewport()?.checkViewportSize();
424
424
  });
425
425
  }
426
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuMultiselectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
427
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: NeuMultiselectComponent, isStandalone: true, selector: "neu-multiselect", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, floatingLabel: { classPropertyName: "floatingLabel", publicName: "floatingLabel", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, noResultsMessage: { classPropertyName: "noResultsMessage", publicName: "noResultsMessage", isSignal: true, isRequired: false, transformFunction: null }, clearAllLabel: { classPropertyName: "clearAllLabel", publicName: "clearAllLabel", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollVisibleItems: { classPropertyName: "virtualScrollVisibleItems", publicName: "virtualScrollVisibleItems", isSignal: true, isRequired: false, transformFunction: null }, clearAriaLabel: { classPropertyName: "clearAriaLabel", publicName: "clearAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, urlParam: { classPropertyName: "urlParam", publicName: "urlParam", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, host: { listeners: { "keydown.escape": "close()", "window:resize": "onWindowResize()" } }, providers: [
426
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuMultiselectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
427
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuMultiselectComponent, isStandalone: true, selector: "neu-multiselect", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, floatingLabel: { classPropertyName: "floatingLabel", publicName: "floatingLabel", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, noResultsMessage: { classPropertyName: "noResultsMessage", publicName: "noResultsMessage", isSignal: true, isRequired: false, transformFunction: null }, clearAllLabel: { classPropertyName: "clearAllLabel", publicName: "clearAllLabel", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollVisibleItems: { classPropertyName: "virtualScrollVisibleItems", publicName: "virtualScrollVisibleItems", isSignal: true, isRequired: false, transformFunction: null }, clearAriaLabel: { classPropertyName: "clearAriaLabel", publicName: "clearAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, urlParam: { classPropertyName: "urlParam", publicName: "urlParam", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, host: { listeners: { "keydown.escape": "close()", "window:resize": "onWindowResize()" } }, providers: [
428
428
  {
429
429
  provide: NG_VALUE_ACCESSOR,
430
430
  useExisting: forwardRef(() => NeuMultiselectComponent),
@@ -730,7 +730,7 @@ class NeuMultiselectComponent {
730
730
  }
731
731
  `, isInline: true, styles: [".neu-multiselect__static-label{display:block;font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted);margin-bottom:var(--neu-space-2)}.neu-multiselect__label{position:absolute;left:var(--neu-space-3);top:50%;transform:translateY(-50%);font-size:var(--neu-text-base);color:var(--neu-text-muted);pointer-events:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:calc(100% - var(--neu-space-8));transition:top var(--neu-transition),font-size var(--neu-transition),color var(--neu-transition),transform var(--neu-transition),padding var(--neu-transition),background var(--neu-transition)}.neu-multiselect--open .neu-multiselect__label,.neu-multiselect--has-value .neu-multiselect__label{top:0;transform:translateY(-50%);font-size:12px;font-weight:600;letter-spacing:.01em;background:var(--neu-surface);padding:0 4px;left:calc(var(--neu-space-3) - 4px)}.neu-multiselect--open .neu-multiselect__label{color:var(--neu-primary)}.neu-multiselect--error .neu-multiselect__label{color:var(--neu-error)}.neu-multiselect--disabled .neu-multiselect__label{background:var(--neu-surface-2)}.neu-multiselect{position:relative;font-family:var(--neu-font-sans)}.neu-multiselect--sm .neu-multiselect__trigger{min-height:36px;font-size:var(--neu-text-sm);padding:var(--neu-space-1) var(--neu-space-2);padding-right:36px}.neu-multiselect--lg .neu-multiselect__trigger{min-height:56px}.neu-multiselect__trigger{display:flex;align-items:center;width:100%;min-height:48px;padding:var(--neu-space-2) var(--neu-space-3);padding-right:36px;background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);cursor:pointer;text-align:left;transition:border-color var(--neu-transition),box-shadow var(--neu-transition)}.neu-multiselect__trigger:hover:not([aria-disabled=true]){border-color:var(--neu-border-hover)}.neu-multiselect__trigger:focus-visible{outline:none;border-color:var(--neu-primary);box-shadow:0 0 0 3px #007aff1f}.neu-multiselect__trigger[aria-disabled=true]{opacity:.6;cursor:not-allowed;background:var(--neu-surface-2)}.neu-multiselect--open .neu-multiselect__trigger{border-color:var(--neu-primary);box-shadow:0 0 0 3px #007aff1f}.neu-multiselect--error .neu-multiselect__trigger{border-color:var(--neu-error)}.neu-multiselect--error .neu-multiselect__trigger:focus-visible{box-shadow:0 0 0 3px #ef44441f}.neu-multiselect__chips{display:flex;flex-wrap:wrap;gap:var(--neu-space-1);flex:1;min-width:0}.neu-multiselect__placeholder{color:var(--neu-text-disabled);font-size:var(--neu-text-base);line-height:1.5}.neu-multiselect:not(.neu-multiselect--no-float):not(.neu-multiselect--open) .neu-multiselect__placeholder{visibility:hidden}.neu-multiselect__chip{display:inline-flex;align-items:center;gap:4px;padding:2px 4px 2px 8px;background:var(--neu-primary-soft, rgba(0, 122, 255, .1));color:var(--neu-primary);border-radius:var(--neu-radius-sm);font-size:var(--neu-text-xs);font-weight:500;max-width:160px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.neu-multiselect__chip-remove{display:flex;align-items:center;justify-content:center;width:16px;height:16px;padding:0;border:none;background:transparent;cursor:pointer;color:inherit;opacity:.7;border-radius:2px;transition:opacity var(--neu-transition);flex-shrink:0}.neu-multiselect__chip-remove:hover{opacity:1}.neu-multiselect__chip-remove:focus-visible{outline:2px solid var(--neu-primary);outline-offset:2px}.neu-multiselect__chip-remove svg{width:10px;height:10px}.neu-multiselect__clear{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;margin-right:2px;padding:0;border:none;background:transparent;color:var(--neu-text-muted);cursor:pointer;border-radius:var(--neu-radius-sm);flex-shrink:0;transition:color var(--neu-transition),background var(--neu-transition)}.neu-multiselect__clear svg{width:14px;height:14px}.neu-multiselect__clear:hover{color:var(--neu-text);background:var(--neu-surface-3)}.neu-multiselect__clear:focus-visible{outline:2px solid var(--neu-primary);outline-offset:2px}.neu-multiselect__chevron{position:absolute;right:var(--neu-space-3);top:50%;transform:translateY(-50%);width:16px;height:16px;color:var(--neu-text-muted);pointer-events:none;transition:transform var(--neu-transition);flex-shrink:0}.neu-multiselect--open .neu-multiselect__chevron{transform:translateY(-50%) rotate(180deg)}.neu-multiselect__panel{position:relative;z-index:200;box-sizing:border-box;width:100%;background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);box-shadow:var(--neu-shadow-lg);overflow:hidden;max-height:280px;display:flex;flex-direction:column;animation:neu-multiselect-fade-in .12s ease}.neu-multiselect__panel--virtual{overflow:visible}@media(max-width:600px){.neu-multiselect__panel{left:auto;right:0;width:min(max(100%,240px),100vw - 2rem);max-width:calc(100vw - 2rem)}}@keyframes neu-multiselect-fade-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.neu-multiselect__search{padding:var(--neu-space-2);border-bottom:1px solid var(--neu-border);flex-shrink:0}.neu-multiselect__search-input{width:100%;height:34px;padding:0 var(--neu-space-3);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius-sm);background:var(--neu-bg);font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);color:var(--neu-text);outline:none;transition:border-color var(--neu-transition),box-shadow var(--neu-transition)}.neu-multiselect__search-input:focus{border-color:var(--neu-primary);box-shadow:0 0 0 2px #007aff1f}.neu-multiselect__search-input::placeholder{color:var(--neu-text-disabled)}.neu-multiselect__options{flex:1;overflow-y:auto;min-height:0}.neu-multiselect__panel--virtual .neu-multiselect__options{overflow:hidden}.neu-multiselect__viewport{width:100%}.neu-multiselect__option{display:flex;align-items:center;gap:var(--neu-space-2);padding:10px var(--neu-space-3);min-height:var(--neu-multiselect-option-height, 44px);box-sizing:border-box;cursor:pointer;font-size:var(--neu-text-sm);color:var(--neu-text);transition:background var(--neu-transition)}.neu-multiselect__option:hover:not(.neu-multiselect__option--disabled){background:var(--neu-surface-2)}.neu-multiselect__option--selected{background:var(--neu-primary-soft, rgba(0, 122, 255, .06));color:var(--neu-primary);font-weight:500}.neu-multiselect__option--disabled{opacity:.4;cursor:not-allowed}.neu-multiselect__checkbox{display:flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:3px;border:1.5px solid var(--neu-border);background:var(--neu-bg);flex-shrink:0;transition:border-color var(--neu-transition),background var(--neu-transition)}.neu-multiselect__checkbox--checked{background:var(--neu-primary);border-color:var(--neu-primary);color:#fff}.neu-multiselect__checkbox-check{width:10px;height:8px;opacity:0;transform:scale(.6);transition:opacity .12s ease,transform .12s ease}.neu-multiselect__checkbox--checked .neu-multiselect__checkbox-check{opacity:1;transform:scale(1)}.neu-multiselect__empty{padding:var(--neu-space-4);text-align:center;font-size:var(--neu-text-sm);color:var(--neu-text-disabled);font-family:var(--neu-font-sans)}.neu-multiselect__footer{display:flex;align-items:center;justify-content:space-between;padding:var(--neu-space-2) var(--neu-space-3);border-top:1px solid var(--neu-border);background:var(--neu-surface);flex-shrink:0}.neu-multiselect__footer-count{font-size:var(--neu-text-xs);color:var(--neu-text-muted)}.neu-multiselect__footer-actions{display:flex;align-items:center;gap:var(--neu-space-2)}.neu-multiselect__footer-mode{background:none;border:1px solid var(--neu-border);border-radius:var(--neu-radius-sm);padding:2px 6px;font-size:var(--neu-text-xs);font-family:var(--neu-font-sans);color:var(--neu-text-muted);cursor:pointer;line-height:1.4}.neu-multiselect__footer-mode:hover{background:var(--neu-surface-2);color:var(--neu-text)}.neu-multiselect__footer-mode:focus-visible{outline:2px solid var(--neu-primary);outline-offset:2px}.neu-multiselect__footer-clear{background:none;border:none;padding:0;font-size:var(--neu-text-xs);font-family:var(--neu-font-sans);color:var(--neu-primary);cursor:pointer;font-weight:500}.neu-multiselect__footer-clear:hover{text-decoration:underline}.neu-multiselect__footer-clear:focus-visible{outline:2px solid var(--neu-primary);outline-offset:2px;border-radius:var(--neu-radius-sm)}.neu-multiselect__count-badge{display:inline-flex;align-items:center;padding:2px 10px;background:var(--neu-primary-100, rgba(14, 165, 233, .12));color:var(--neu-primary-dark, var(--neu-primary));border-radius:var(--neu-radius-full);font-size:var(--neu-text-sm);font-weight:500}.neu-multiselect__chip--overflow{background:var(--neu-surface-2);color:var(--neu-text-muted);border:1px dashed var(--neu-border);cursor:default;pointer-events:none}.neu-multiselect__error{margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-error-text, var(--neu-error));font-family:var(--neu-font-sans)}.neu-multiselect__hint{margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-text-muted);font-family:var(--neu-font-sans)}.neu-multiselect__sr-status{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: i1.ɵɵCdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1.ɵɵCdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1.ɵɵCdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "ngmodule", type: ScrollingModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
732
732
  }
733
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuMultiselectComponent, decorators: [{
733
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuMultiselectComponent, decorators: [{
734
734
  type: Component,
735
735
  args: [{ selector: 'neu-multiselect', imports: [NgTemplateOutlet, OverlayModule, ScrollingModule], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
736
736
  {