@neural-ui/core 1.5.14 → 1.6.1

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 +13 -9
  2. package/fesm2022/neural-ui-core-accordion.mjs.map +1 -1
  3. package/fesm2022/neural-ui-core-alert.mjs +25 -14
  4. package/fesm2022/neural-ui-core-alert.mjs.map +1 -1
  5. package/fesm2022/neural-ui-core-autocomplete.mjs +53 -28
  6. package/fesm2022/neural-ui-core-autocomplete.mjs.map +1 -1
  7. package/fesm2022/neural-ui-core-avatar.mjs +23 -13
  8. package/fesm2022/neural-ui-core-avatar.mjs.map +1 -1
  9. package/fesm2022/neural-ui-core-badge.mjs +15 -9
  10. package/fesm2022/neural-ui-core-badge.mjs.map +1 -1
  11. package/fesm2022/neural-ui-core-block-ui.mjs +16 -11
  12. package/fesm2022/neural-ui-core-block-ui.mjs.map +1 -1
  13. package/fesm2022/neural-ui-core-breadcrumb.mjs +8 -6
  14. package/fesm2022/neural-ui-core-breadcrumb.mjs.map +1 -1
  15. package/fesm2022/neural-ui-core-button.mjs +29 -16
  16. package/fesm2022/neural-ui-core-button.mjs.map +1 -1
  17. package/fesm2022/neural-ui-core-calendar.mjs +75 -50
  18. package/fesm2022/neural-ui-core-calendar.mjs.map +1 -1
  19. package/fesm2022/neural-ui-core-card.mjs +13 -8
  20. package/fesm2022/neural-ui-core-card.mjs.map +1 -1
  21. package/fesm2022/neural-ui-core-chart.mjs +45 -24
  22. package/fesm2022/neural-ui-core-chart.mjs.map +1 -1
  23. package/fesm2022/neural-ui-core-checkbox.mjs +15 -9
  24. package/fesm2022/neural-ui-core-checkbox.mjs.map +1 -1
  25. package/fesm2022/neural-ui-core-chip.mjs +23 -13
  26. package/fesm2022/neural-ui-core-chip.mjs.map +1 -1
  27. package/fesm2022/neural-ui-core-code-block.mjs +32 -17
  28. package/fesm2022/neural-ui-core-code-block.mjs.map +1 -1
  29. package/fesm2022/neural-ui-core-color-picker.mjs +19 -11
  30. package/fesm2022/neural-ui-core-color-picker.mjs.map +1 -1
  31. package/fesm2022/neural-ui-core-command-palette.mjs +16 -11
  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-context-menu.mjs +12 -9
  35. package/fesm2022/neural-ui-core-context-menu.mjs.map +1 -1
  36. package/fesm2022/neural-ui-core-dashboard-grid.mjs +11 -7
  37. package/fesm2022/neural-ui-core-dashboard-grid.mjs.map +1 -1
  38. package/fesm2022/neural-ui-core-date-input.mjs +111 -57
  39. package/fesm2022/neural-ui-core-date-input.mjs.map +1 -1
  40. package/fesm2022/neural-ui-core-divider.mjs +7 -5
  41. package/fesm2022/neural-ui-core-divider.mjs.map +1 -1
  42. package/fesm2022/neural-ui-core-empty-state.mjs +13 -8
  43. package/fesm2022/neural-ui-core-empty-state.mjs.map +1 -1
  44. package/fesm2022/neural-ui-core-filter-bar.mjs +19 -11
  45. package/fesm2022/neural-ui-core-filter-bar.mjs.map +1 -1
  46. package/fesm2022/neural-ui-core-icon.mjs +11 -7
  47. package/fesm2022/neural-ui-core-icon.mjs.map +1 -1
  48. package/fesm2022/neural-ui-core-image-gallery.mjs +23 -13
  49. package/fesm2022/neural-ui-core-image-gallery.mjs.map +1 -1
  50. package/fesm2022/neural-ui-core-image-viewer.mjs +22 -14
  51. package/fesm2022/neural-ui-core-image-viewer.mjs.map +1 -1
  52. package/fesm2022/neural-ui-core-input-otp.mjs +19 -11
  53. package/fesm2022/neural-ui-core-input-otp.mjs.map +1 -1
  54. package/fesm2022/neural-ui-core-input.mjs +67 -35
  55. package/fesm2022/neural-ui-core-input.mjs.map +1 -1
  56. package/fesm2022/neural-ui-core-kanban.mjs +17 -11
  57. package/fesm2022/neural-ui-core-kanban.mjs.map +1 -1
  58. package/fesm2022/neural-ui-core-knob.mjs +41 -22
  59. package/fesm2022/neural-ui-core-knob.mjs.map +1 -1
  60. package/fesm2022/neural-ui-core-meter-group.mjs +23 -13
  61. package/fesm2022/neural-ui-core-meter-group.mjs.map +1 -1
  62. package/fesm2022/neural-ui-core-modal.mjs +16 -11
  63. package/fesm2022/neural-ui-core-modal.mjs.map +1 -1
  64. package/fesm2022/neural-ui-core-multiselect.mjs +72 -39
  65. package/fesm2022/neural-ui-core-multiselect.mjs.map +1 -1
  66. package/fesm2022/neural-ui-core-nav.mjs +22 -13
  67. package/fesm2022/neural-ui-core-nav.mjs.map +1 -1
  68. package/fesm2022/neural-ui-core-notification-center.mjs +27 -10
  69. package/fesm2022/neural-ui-core-notification-center.mjs.map +1 -1
  70. package/fesm2022/neural-ui-core-number-input.mjs +35 -19
  71. package/fesm2022/neural-ui-core-number-input.mjs.map +1 -1
  72. package/fesm2022/neural-ui-core-pagination.mjs +15 -9
  73. package/fesm2022/neural-ui-core-pagination.mjs.map +1 -1
  74. package/fesm2022/neural-ui-core-popover.mjs +22 -14
  75. package/fesm2022/neural-ui-core-popover.mjs.map +1 -1
  76. package/fesm2022/neural-ui-core-progress-bar.mjs +19 -11
  77. package/fesm2022/neural-ui-core-progress-bar.mjs.map +1 -1
  78. package/fesm2022/neural-ui-core-radio.mjs +24 -15
  79. package/fesm2022/neural-ui-core-radio.mjs.map +1 -1
  80. package/fesm2022/neural-ui-core-rating.mjs +13 -8
  81. package/fesm2022/neural-ui-core-rating.mjs.map +1 -1
  82. package/fesm2022/neural-ui-core-rich-text-editor.mjs +773 -0
  83. package/fesm2022/neural-ui-core-rich-text-editor.mjs.map +1 -0
  84. package/fesm2022/neural-ui-core-scheduler-gantt.mjs +41 -22
  85. package/fesm2022/neural-ui-core-scheduler-gantt.mjs.map +1 -1
  86. package/fesm2022/neural-ui-core-select.mjs +77 -43
  87. package/fesm2022/neural-ui-core-select.mjs.map +1 -1
  88. package/fesm2022/neural-ui-core-sidebar.mjs +23 -14
  89. package/fesm2022/neural-ui-core-sidebar.mjs.map +1 -1
  90. package/fesm2022/neural-ui-core-skeleton.mjs +11 -7
  91. package/fesm2022/neural-ui-core-skeleton.mjs.map +1 -1
  92. package/fesm2022/neural-ui-core-slider.mjs +23 -13
  93. package/fesm2022/neural-ui-core-slider.mjs.map +1 -1
  94. package/fesm2022/neural-ui-core-spinner.mjs +17 -10
  95. package/fesm2022/neural-ui-core-spinner.mjs.map +1 -1
  96. package/fesm2022/neural-ui-core-split-button.mjs +27 -15
  97. package/fesm2022/neural-ui-core-split-button.mjs.map +1 -1
  98. package/fesm2022/neural-ui-core-splitter.mjs +9 -6
  99. package/fesm2022/neural-ui-core-splitter.mjs.map +1 -1
  100. package/fesm2022/neural-ui-core-stats-card.mjs +19 -11
  101. package/fesm2022/neural-ui-core-stats-card.mjs.map +1 -1
  102. package/fesm2022/neural-ui-core-stepper.mjs +13 -8
  103. package/fesm2022/neural-ui-core-stepper.mjs.map +1 -1
  104. package/fesm2022/neural-ui-core-switch.mjs +15 -9
  105. package/fesm2022/neural-ui-core-switch.mjs.map +1 -1
  106. package/fesm2022/neural-ui-core-table.mjs +242 -124
  107. package/fesm2022/neural-ui-core-table.mjs.map +1 -1
  108. package/fesm2022/neural-ui-core-tabs.mjs +30 -18
  109. package/fesm2022/neural-ui-core-tabs.mjs.map +1 -1
  110. package/fesm2022/neural-ui-core-textarea.mjs +43 -23
  111. package/fesm2022/neural-ui-core-textarea.mjs.map +1 -1
  112. package/fesm2022/neural-ui-core-timeline-grid.mjs +21 -12
  113. package/fesm2022/neural-ui-core-timeline-grid.mjs.map +1 -1
  114. package/fesm2022/neural-ui-core-timeline.mjs +5 -4
  115. package/fesm2022/neural-ui-core-timeline.mjs.map +1 -1
  116. package/fesm2022/neural-ui-core-toast.mjs +25 -9
  117. package/fesm2022/neural-ui-core-toast.mjs.map +1 -1
  118. package/fesm2022/neural-ui-core-toggle-button-group.mjs +17 -10
  119. package/fesm2022/neural-ui-core-toggle-button-group.mjs.map +1 -1
  120. package/fesm2022/neural-ui-core-toolbar.mjs +13 -8
  121. package/fesm2022/neural-ui-core-toolbar.mjs.map +1 -1
  122. package/fesm2022/neural-ui-core-tooltip.mjs +16 -11
  123. package/fesm2022/neural-ui-core-tooltip.mjs.map +1 -1
  124. package/fesm2022/neural-ui-core-tree-table.mjs +57 -30
  125. package/fesm2022/neural-ui-core-tree-table.mjs.map +1 -1
  126. package/fesm2022/neural-ui-core-tree.mjs +31 -17
  127. package/fesm2022/neural-ui-core-tree.mjs.map +1 -1
  128. package/fesm2022/neural-ui-core-uploader.mjs +91 -47
  129. package/fesm2022/neural-ui-core-uploader.mjs.map +1 -1
  130. package/fesm2022/neural-ui-core-url-state.mjs +7 -5
  131. package/fesm2022/neural-ui-core-url-state.mjs.map +1 -1
  132. package/fesm2022/neural-ui-core-virtual-list.mjs +32 -19
  133. package/fesm2022/neural-ui-core-virtual-list.mjs.map +1 -1
  134. package/package.json +5 -1
  135. package/types/neural-ui-core-notification-center.d.ts +2 -0
  136. package/types/neural-ui-core-rich-text-editor.d.ts +97 -0
  137. package/types/neural-ui-core-toast.d.ts +2 -0
@@ -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":"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"}
@@ -12,32 +12,42 @@ import { DecimalPipe } from '@angular/common';
12
12
  */
13
13
  class NeuMeterGroupComponent {
14
14
  /** Segmentos del medidor / Meter segments */
15
- items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
15
+ items = input([], /* @ts-ignore */
16
+ ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
16
17
  /** Total de referencia (0 = suma de items) / Reference total (0 = sum of items) */
17
- total = input(0, ...(ngDevMode ? [{ debugName: "total" }] : /* istanbul ignore next */ []));
18
+ total = input(0, /* @ts-ignore */
19
+ ...(ngDevMode ? [{ debugName: "total" }] : /* istanbul ignore next */ []));
18
20
  /** Altura de la barra en px / Bar height in px */
19
- height = input(12, ...(ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []));
21
+ height = input(12, /* @ts-ignore */
22
+ ...(ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []));
20
23
  /** Esquinas redondeadas / Rounded corners */
21
- rounded = input(true, ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
24
+ rounded = input(true, /* @ts-ignore */
25
+ ...(ngDevMode ? [{ debugName: "rounded" }] : /* istanbul ignore next */ []));
22
26
  /** Muestra leyenda debajo / Shows legend below */
23
- showLegend = input(true, ...(ngDevMode ? [{ debugName: "showLegend" }] : /* istanbul ignore next */ []));
27
+ showLegend = input(true, /* @ts-ignore */
28
+ ...(ngDevMode ? [{ debugName: "showLegend" }] : /* istanbul ignore next */ []));
24
29
  /** Aria-label de la barra / Aria-label for the bar */
25
- ariaLabel = input('Medidor', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
30
+ ariaLabel = input('Medidor', /* @ts-ignore */
31
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
26
32
  hostClasses = computed(() => ({
27
33
  'neu-meter-group': true,
28
34
  'neu-meter-group--rounded': this.rounded(),
29
- }), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
30
- _usedSum = computed(() => this.items().reduce((s, i) => s + i.value, 0), ...(ngDevMode ? [{ debugName: "_usedSum" }] : /* istanbul ignore next */ []));
31
- _effectiveTotal = computed(() => this.total() > 0 ? this.total() : this._usedSum() || 1, ...(ngDevMode ? [{ debugName: "_effectiveTotal" }] : /* istanbul ignore next */ []));
35
+ }), /* @ts-ignore */
36
+ ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
37
+ _usedSum = computed(() => this.items().reduce((s, i) => s + i.value, 0), /* @ts-ignore */
38
+ ...(ngDevMode ? [{ debugName: "_usedSum" }] : /* istanbul ignore next */ []));
39
+ _effectiveTotal = computed(() => this.total() > 0 ? this.total() : this._usedSum() || 1, /* @ts-ignore */
40
+ ...(ngDevMode ? [{ debugName: "_effectiveTotal" }] : /* istanbul ignore next */ []));
32
41
  _segments = computed(() => {
33
42
  const total = this._effectiveTotal();
34
43
  return this.items().map((item) => ({
35
44
  ...item,
36
45
  pct: Math.max(0, Math.min(100, (item.value / total) * 100)),
37
46
  }));
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: `
47
+ }, /* @ts-ignore */
48
+ ...(ngDevMode ? [{ debugName: "_segments" }] : /* istanbul ignore next */ []));
49
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NeuMeterGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
50
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", 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
51
  <div
42
52
  class="neu-meter-group__bar"
43
53
  role="meter"
@@ -74,7 +84,7 @@ class NeuMeterGroupComponent {
74
84
  }
75
85
  `, 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
86
  }
77
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuMeterGroupComponent, decorators: [{
87
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NeuMeterGroupComponent, decorators: [{
78
88
  type: Component,
79
89
  args: [{ selector: 'neu-meter-group', imports: [DecimalPipe], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: { '[class]': 'hostClasses()' }, template: `
80
90
  <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":"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"}
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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"}
@@ -19,16 +19,21 @@ import { Dialog } from '@angular/cdk/dialog';
19
19
  */
20
20
  class NeuDialogComponent {
21
21
  /** Controla la visibilidad del diálogo. / Controls dialog visibility. */
22
- open = input(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
22
+ open = input(false, /* @ts-ignore */
23
+ ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
23
24
  /** Título que aparece en el header. / Title shown in the header. */
24
- title = input('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
25
+ title = input('', /* @ts-ignore */
26
+ ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
25
27
  /** Tamaño del panel: sm | md | lg | xl | full. / Panel size: sm | md | lg | xl | full. */
26
- size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
28
+ size = input('md', /* @ts-ignore */
29
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
27
30
  /** Si es true, el backdrop y el botón cerrar no funcionan. / If true, the backdrop and close button do not work. */
28
- disableClose = input(false, ...(ngDevMode ? [{ debugName: "disableClose" }] : /* istanbul ignore next */ []));
31
+ disableClose = input(false, /* @ts-ignore */
32
+ ...(ngDevMode ? [{ debugName: "disableClose" }] : /* istanbul ignore next */ []));
29
33
  /** Emite cuando el usuario cierra el diálogo. / Emits when the user closes the dialog. */
30
34
  closed = output();
31
- panelRef = viewChild('panel', ...(ngDevMode ? [{ debugName: "panelRef" }] : /* istanbul ignore next */ []));
35
+ panelRef = viewChild('panel', /* @ts-ignore */
36
+ ...(ngDevMode ? [{ debugName: "panelRef" }] : /* istanbul ignore next */ []));
32
37
  /** @internal — ID único para aria-labelledby / Unique ID for aria-labelledby */
33
38
  _uid = Math.random().toString(36).slice(2, 7);
34
39
  constructor() {
@@ -81,8 +86,8 @@ class NeuDialogComponent {
81
86
  getFocusableElements(panel) {
82
87
  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
88
  }
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: `
89
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NeuDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
90
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", 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
91
  @if (open()) {
87
92
  <!-- Backdrop -->
88
93
  <div
@@ -128,7 +133,7 @@ class NeuDialogComponent {
128
133
  }
129
134
  `, 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
135
  }
131
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuDialogComponent, decorators: [{
136
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NeuDialogComponent, decorators: [{
132
137
  type: Component,
133
138
  args: [{ selector: 'neu-dialog', imports: [NeuIconComponent], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
134
139
  '[class.neu-dialog--open]': 'open()',
@@ -190,10 +195,10 @@ class NeuDialogService {
190
195
  disableClose: config?.disableClose ?? false,
191
196
  });
192
197
  }
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' });
198
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NeuDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
199
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NeuDialogService, providedIn: 'root' });
195
200
  }
196
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuDialogService, decorators: [{
201
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NeuDialogService, decorators: [{
197
202
  type: Injectable,
198
203
  args: [{ providedIn: 'root' }]
199
204
  }] });
@@ -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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"}