@neural-ui/core 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/README.md +56 -88
  2. package/accordion/package.json +4 -0
  3. package/alert/package.json +4 -0
  4. package/autocomplete/package.json +4 -0
  5. package/avatar/package.json +4 -0
  6. package/badge/package.json +4 -0
  7. package/block-ui/package.json +4 -0
  8. package/breadcrumb/package.json +4 -0
  9. package/button/package.json +4 -0
  10. package/card/package.json +4 -0
  11. package/chart/package.json +4 -0
  12. package/checkbox/package.json +4 -0
  13. package/chip/package.json +4 -0
  14. package/code-block/package.json +4 -0
  15. package/color-picker/package.json +4 -0
  16. package/command-palette/package.json +4 -0
  17. package/confirm-dialog/package.json +4 -0
  18. package/context-menu/package.json +4 -0
  19. package/dashboard-grid/package.json +4 -0
  20. package/date-input/package.json +4 -0
  21. package/divider/package.json +4 -0
  22. package/empty-state/package.json +4 -0
  23. package/fesm2022/neural-ui-core-accordion.mjs +162 -0
  24. package/fesm2022/neural-ui-core-accordion.mjs.map +1 -0
  25. package/fesm2022/neural-ui-core-alert.mjs +116 -0
  26. package/fesm2022/neural-ui-core-alert.mjs.map +1 -0
  27. package/fesm2022/neural-ui-core-autocomplete.mjs +332 -0
  28. package/fesm2022/neural-ui-core-autocomplete.mjs.map +1 -0
  29. package/fesm2022/neural-ui-core-avatar.mjs +109 -0
  30. package/fesm2022/neural-ui-core-avatar.mjs.map +1 -0
  31. package/fesm2022/neural-ui-core-badge.mjs +54 -0
  32. package/fesm2022/neural-ui-core-badge.mjs.map +1 -0
  33. package/fesm2022/neural-ui-core-block-ui.mjs +95 -0
  34. package/fesm2022/neural-ui-core-block-ui.mjs.map +1 -0
  35. package/fesm2022/neural-ui-core-breadcrumb.mjs +84 -0
  36. package/fesm2022/neural-ui-core-breadcrumb.mjs.map +1 -0
  37. package/fesm2022/neural-ui-core-button.mjs +125 -0
  38. package/fesm2022/neural-ui-core-button.mjs.map +1 -0
  39. package/fesm2022/neural-ui-core-card.mjs +69 -0
  40. package/fesm2022/neural-ui-core-card.mjs.map +1 -0
  41. package/fesm2022/neural-ui-core-chart.mjs +287 -0
  42. package/fesm2022/neural-ui-core-chart.mjs.map +1 -0
  43. package/fesm2022/neural-ui-core-checkbox.mjs +138 -0
  44. package/fesm2022/neural-ui-core-checkbox.mjs.map +1 -0
  45. package/fesm2022/neural-ui-core-chip.mjs +130 -0
  46. package/fesm2022/neural-ui-core-chip.mjs.map +1 -0
  47. package/fesm2022/neural-ui-core-code-block.mjs +250 -0
  48. package/fesm2022/neural-ui-core-code-block.mjs.map +1 -0
  49. package/fesm2022/neural-ui-core-color-picker.mjs +435 -0
  50. package/fesm2022/neural-ui-core-color-picker.mjs.map +1 -0
  51. package/fesm2022/neural-ui-core-command-palette.mjs +235 -0
  52. package/fesm2022/neural-ui-core-command-palette.mjs.map +1 -0
  53. package/fesm2022/neural-ui-core-confirm-dialog.mjs +118 -0
  54. package/fesm2022/neural-ui-core-confirm-dialog.mjs.map +1 -0
  55. package/fesm2022/neural-ui-core-context-menu.mjs +158 -0
  56. package/fesm2022/neural-ui-core-context-menu.mjs.map +1 -0
  57. package/fesm2022/neural-ui-core-dashboard-grid.mjs +144 -0
  58. package/fesm2022/neural-ui-core-dashboard-grid.mjs.map +1 -0
  59. package/fesm2022/neural-ui-core-date-input.mjs +1332 -0
  60. package/fesm2022/neural-ui-core-date-input.mjs.map +1 -0
  61. package/fesm2022/neural-ui-core-divider.mjs +54 -0
  62. package/fesm2022/neural-ui-core-divider.mjs.map +1 -0
  63. package/fesm2022/neural-ui-core-empty-state.mjs +84 -0
  64. package/fesm2022/neural-ui-core-empty-state.mjs.map +1 -0
  65. package/fesm2022/neural-ui-core-filter-bar.mjs +118 -0
  66. package/fesm2022/neural-ui-core-filter-bar.mjs.map +1 -0
  67. package/fesm2022/neural-ui-core-icon.mjs +50 -0
  68. package/fesm2022/neural-ui-core-icon.mjs.map +1 -0
  69. package/fesm2022/neural-ui-core-image-viewer.mjs +309 -0
  70. package/fesm2022/neural-ui-core-image-viewer.mjs.map +1 -0
  71. package/fesm2022/neural-ui-core-input-otp.mjs +192 -0
  72. package/fesm2022/neural-ui-core-input-otp.mjs.map +1 -0
  73. package/fesm2022/neural-ui-core-input.mjs +320 -0
  74. package/fesm2022/neural-ui-core-input.mjs.map +1 -0
  75. package/fesm2022/neural-ui-core-knob.mjs +323 -0
  76. package/fesm2022/neural-ui-core-knob.mjs.map +1 -0
  77. package/fesm2022/neural-ui-core-meter-group.mjs +122 -0
  78. package/fesm2022/neural-ui-core-meter-group.mjs.map +1 -0
  79. package/fesm2022/neural-ui-core-modal.mjs +156 -0
  80. package/fesm2022/neural-ui-core-modal.mjs.map +1 -0
  81. package/fesm2022/neural-ui-core-multiselect.mjs +748 -0
  82. package/fesm2022/neural-ui-core-multiselect.mjs.map +1 -0
  83. package/fesm2022/neural-ui-core-nav.mjs +952 -0
  84. package/fesm2022/neural-ui-core-nav.mjs.map +1 -0
  85. package/fesm2022/neural-ui-core-notification-center.mjs +264 -0
  86. package/fesm2022/neural-ui-core-notification-center.mjs.map +1 -0
  87. package/fesm2022/neural-ui-core-number-input.mjs +331 -0
  88. package/fesm2022/neural-ui-core-number-input.mjs.map +1 -0
  89. package/fesm2022/neural-ui-core-pagination.mjs +198 -0
  90. package/fesm2022/neural-ui-core-pagination.mjs.map +1 -0
  91. package/fesm2022/neural-ui-core-popover.mjs +207 -0
  92. package/fesm2022/neural-ui-core-popover.mjs.map +1 -0
  93. package/fesm2022/neural-ui-core-progress-bar.mjs +105 -0
  94. package/fesm2022/neural-ui-core-progress-bar.mjs.map +1 -0
  95. package/fesm2022/neural-ui-core-radio.mjs +171 -0
  96. package/fesm2022/neural-ui-core-radio.mjs.map +1 -0
  97. package/fesm2022/neural-ui-core-rating.mjs +151 -0
  98. package/fesm2022/neural-ui-core-rating.mjs.map +1 -0
  99. package/fesm2022/neural-ui-core-select.mjs +638 -0
  100. package/fesm2022/neural-ui-core-select.mjs.map +1 -0
  101. package/fesm2022/neural-ui-core-sidebar.mjs +214 -0
  102. package/fesm2022/neural-ui-core-sidebar.mjs.map +1 -0
  103. package/fesm2022/neural-ui-core-skeleton.mjs +40 -0
  104. package/fesm2022/neural-ui-core-skeleton.mjs.map +1 -0
  105. package/fesm2022/neural-ui-core-slider.mjs +146 -0
  106. package/fesm2022/neural-ui-core-slider.mjs.map +1 -0
  107. package/fesm2022/neural-ui-core-spinner.mjs +113 -0
  108. package/fesm2022/neural-ui-core-spinner.mjs.map +1 -0
  109. package/fesm2022/neural-ui-core-split-button.mjs +252 -0
  110. package/fesm2022/neural-ui-core-split-button.mjs.map +1 -0
  111. package/fesm2022/neural-ui-core-splitter.mjs +174 -0
  112. package/fesm2022/neural-ui-core-splitter.mjs.map +1 -0
  113. package/fesm2022/neural-ui-core-stats-card.mjs +163 -0
  114. package/fesm2022/neural-ui-core-stats-card.mjs.map +1 -0
  115. package/fesm2022/neural-ui-core-stepper.mjs +204 -0
  116. package/fesm2022/neural-ui-core-stepper.mjs.map +1 -0
  117. package/fesm2022/neural-ui-core-switch.mjs +111 -0
  118. package/fesm2022/neural-ui-core-switch.mjs.map +1 -0
  119. package/fesm2022/neural-ui-core-table.mjs +1860 -0
  120. package/fesm2022/neural-ui-core-table.mjs.map +1 -0
  121. package/fesm2022/neural-ui-core-tabs.mjs +246 -0
  122. package/fesm2022/neural-ui-core-tabs.mjs.map +1 -0
  123. package/fesm2022/neural-ui-core-textarea.mjs +188 -0
  124. package/fesm2022/neural-ui-core-textarea.mjs.map +1 -0
  125. package/fesm2022/neural-ui-core-timeline.mjs +117 -0
  126. package/fesm2022/neural-ui-core-timeline.mjs.map +1 -0
  127. package/fesm2022/neural-ui-core-toast.mjs +171 -0
  128. package/fesm2022/neural-ui-core-toast.mjs.map +1 -0
  129. package/fesm2022/neural-ui-core-toggle-button-group.mjs +162 -0
  130. package/fesm2022/neural-ui-core-toggle-button-group.mjs.map +1 -0
  131. package/fesm2022/neural-ui-core-toolbar.mjs +67 -0
  132. package/fesm2022/neural-ui-core-toolbar.mjs.map +1 -0
  133. package/fesm2022/neural-ui-core-tooltip.mjs +151 -0
  134. package/fesm2022/neural-ui-core-tooltip.mjs.map +1 -0
  135. package/fesm2022/neural-ui-core-url-state.mjs +96 -0
  136. package/fesm2022/neural-ui-core-url-state.mjs.map +1 -0
  137. package/fesm2022/neural-ui-core-virtual-list.mjs +126 -0
  138. package/fesm2022/neural-ui-core-virtual-list.mjs.map +1 -0
  139. package/fesm2022/neural-ui-core.mjs +11 -8544
  140. package/fesm2022/neural-ui-core.mjs.map +1 -1
  141. package/filter-bar/package.json +4 -0
  142. package/icon/package.json +4 -0
  143. package/image-viewer/package.json +4 -0
  144. package/input/package.json +4 -0
  145. package/input-otp/package.json +4 -0
  146. package/knob/package.json +4 -0
  147. package/meter-group/package.json +4 -0
  148. package/modal/package.json +4 -0
  149. package/multiselect/package.json +4 -0
  150. package/nav/package.json +4 -0
  151. package/notification-center/package.json +4 -0
  152. package/number-input/package.json +4 -0
  153. package/package.json +252 -5
  154. package/pagination/package.json +4 -0
  155. package/popover/package.json +4 -0
  156. package/progress-bar/package.json +4 -0
  157. package/radio/package.json +4 -0
  158. package/rating/package.json +4 -0
  159. package/select/package.json +4 -0
  160. package/sidebar/package.json +4 -0
  161. package/skeleton/package.json +4 -0
  162. package/slider/package.json +4 -0
  163. package/spinner/package.json +4 -0
  164. package/split-button/package.json +4 -0
  165. package/splitter/package.json +4 -0
  166. package/stats-card/package.json +4 -0
  167. package/stepper/package.json +4 -0
  168. package/styles/_tokens.scss +209 -7
  169. package/styles.scss +1 -0
  170. package/switch/package.json +4 -0
  171. package/table/package.json +4 -0
  172. package/tabs/package.json +4 -0
  173. package/textarea/package.json +4 -0
  174. package/timeline/package.json +4 -0
  175. package/toast/package.json +4 -0
  176. package/toggle-button-group/package.json +4 -0
  177. package/toolbar/package.json +4 -0
  178. package/tooltip/package.json +4 -0
  179. package/types/neural-ui-core-accordion.d.ts +55 -0
  180. package/types/neural-ui-core-alert.d.ts +47 -0
  181. package/types/neural-ui-core-autocomplete.d.ts +69 -0
  182. package/types/neural-ui-core-avatar.d.ts +39 -0
  183. package/types/neural-ui-core-badge.d.ts +36 -0
  184. package/types/neural-ui-core-block-ui.d.ts +46 -0
  185. package/types/neural-ui-core-breadcrumb.d.ts +38 -0
  186. package/types/neural-ui-core-button.d.ts +55 -0
  187. package/types/neural-ui-core-card.d.ts +37 -0
  188. package/types/neural-ui-core-chart.d.ts +236 -0
  189. package/types/neural-ui-core-checkbox.d.ts +33 -0
  190. package/types/neural-ui-core-chip.d.ts +53 -0
  191. package/types/neural-ui-core-code-block.d.ts +55 -0
  192. package/types/neural-ui-core-color-picker.d.ts +55 -0
  193. package/types/neural-ui-core-command-palette.d.ts +56 -0
  194. package/types/neural-ui-core-confirm-dialog.d.ts +50 -0
  195. package/types/neural-ui-core-context-menu.d.ts +66 -0
  196. package/types/neural-ui-core-dashboard-grid.d.ts +41 -0
  197. package/types/neural-ui-core-date-input.d.ts +178 -0
  198. package/types/neural-ui-core-divider.d.ts +20 -0
  199. package/types/neural-ui-core-empty-state.d.ts +32 -0
  200. package/types/neural-ui-core-filter-bar.d.ts +49 -0
  201. package/types/neural-ui-core-icon.d.ts +33 -0
  202. package/types/neural-ui-core-image-viewer.d.ts +67 -0
  203. package/types/neural-ui-core-input-otp.d.ts +49 -0
  204. package/types/neural-ui-core-input.d.ts +86 -0
  205. package/types/neural-ui-core-knob.d.ts +68 -0
  206. package/types/neural-ui-core-meter-group.d.ts +52 -0
  207. package/types/neural-ui-core-modal.d.ts +54 -0
  208. package/types/neural-ui-core-multiselect.d.ts +129 -0
  209. package/types/neural-ui-core-nav.d.ts +69 -0
  210. package/types/neural-ui-core-notification-center.d.ts +60 -0
  211. package/types/neural-ui-core-number-input.d.ts +63 -0
  212. package/types/neural-ui-core-pagination.d.ts +30 -0
  213. package/types/neural-ui-core-popover.d.ts +73 -0
  214. package/types/neural-ui-core-progress-bar.d.ts +35 -0
  215. package/types/neural-ui-core-radio.d.ts +51 -0
  216. package/types/neural-ui-core-rating.d.ts +34 -0
  217. package/types/neural-ui-core-select.d.ts +161 -0
  218. package/types/neural-ui-core-sidebar.d.ts +57 -0
  219. package/types/neural-ui-core-skeleton.d.ts +22 -0
  220. package/types/neural-ui-core-slider.d.ts +42 -0
  221. package/types/neural-ui-core-spinner.d.ts +38 -0
  222. package/types/neural-ui-core-split-button.d.ts +65 -0
  223. package/types/neural-ui-core-splitter.d.ts +28 -0
  224. package/types/neural-ui-core-stats-card.d.ts +39 -0
  225. package/types/neural-ui-core-stepper.d.ts +51 -0
  226. package/types/neural-ui-core-switch.d.ts +34 -0
  227. package/types/neural-ui-core-table.d.ts +282 -0
  228. package/types/neural-ui-core-tabs.d.ts +76 -0
  229. package/types/neural-ui-core-textarea.d.ts +52 -0
  230. package/types/neural-ui-core-timeline.d.ts +33 -0
  231. package/types/neural-ui-core-toast.d.ts +70 -0
  232. package/types/neural-ui-core-toggle-button-group.d.ts +63 -0
  233. package/types/neural-ui-core-toolbar.d.ts +36 -0
  234. package/types/neural-ui-core-tooltip.d.ts +48 -0
  235. package/types/neural-ui-core-url-state.d.ts +58 -0
  236. package/types/neural-ui-core-virtual-list.d.ts +60 -0
  237. package/types/neural-ui-core.d.ts +5 -2107
  238. package/url-state/package.json +4 -0
  239. package/virtual-list/package.json +4 -0
@@ -0,0 +1,1332 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, ElementRef, input, output, signal, computed, forwardRef, HostListener, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
3
+ import { DOCUMENT } from '@angular/common';
4
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
5
+
6
+ // ── Private helpers ──────────────────────────────────────────────────────────
7
+ let _neuDateInputIdSeq = 0;
8
+ function sameDay(a, b) {
9
+ return (a.getFullYear() === b.getFullYear() &&
10
+ a.getMonth() === b.getMonth() &&
11
+ a.getDate() === b.getDate());
12
+ }
13
+ function cloneDate(d) {
14
+ return new Date(d.getTime());
15
+ }
16
+ // ── Component ────────────────────────────────────────────────────────────────
17
+ /**
18
+ * NeuralUI DateInput — campo de fecha/hora unificado con modo rango.
19
+ * Unified date/time field with range mode.
20
+ *
21
+ * Uso básico / Basic usage:
22
+ * <neu-date-input type="date" [formControl]="dateCtrl" />
23
+ * <neu-date-input type="time" [formControl]="timeCtrl" />
24
+ * <neu-date-input type="datetime-local" [formControl]="dateTimeCtrl" />
25
+ * <neu-date-input type="range" [formControl]="rangeCtrl" />
26
+ */
27
+ class NeuDateInputComponent {
28
+ el = inject(ElementRef);
29
+ doc = inject(DOCUMENT);
30
+ _langObserver;
31
+ /** Tipo del campo / Field type */
32
+ type = input('date', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
33
+ /** Etiqueta / Label */
34
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
35
+ /** Texto de ayuda / Help text */
36
+ hint = input('', ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
37
+ /** Mensaje de error / Error message */
38
+ errorMessage = input('', ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
39
+ /** Deshabilita / Disabled */
40
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
41
+ /** Tamaño del campo: 'sm' = 36px | 'md' = 48px | 'lg' = 56px / Field size */
42
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
43
+ /** Solo lectura / Read only */
44
+ readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
45
+ /** Nombre / Field name */
46
+ name = input('', ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
47
+ /** ID accesible / Accessible ID */
48
+ inputId = input('', ...(ngDevMode ? [{ debugName: "inputId" }] : /* istanbul ignore next */ []));
49
+ /** Requerido / Required */
50
+ required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
51
+ /** Mínimo / Minimum */
52
+ min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
53
+ /** Máximo / Maximum */
54
+ max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
55
+ /** Paso / Step */
56
+ step = input(null, ...(ngDevMode ? [{ debugName: "step" }] : /* istanbul ignore next */ []));
57
+ /** Locale explícito opcional / Optional explicit locale */
58
+ locale = input(null, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
59
+ // ── Range-mode inputs ────────────────────────────────────────────
60
+ /** Placeholder del trigger de rango / Range trigger placeholder */
61
+ placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
62
+ /** Formato de fecha en modo rango / Date display format in range mode */
63
+ dateFormat = input('short', ...(ngDevMode ? [{ debugName: "dateFormat" }] : /* istanbul ignore next */ []));
64
+ // ── Outputs ──────────────────────────────────────────────────────
65
+ /** Emitido al confirmar el rango / Emitted when range is confirmed */
66
+ rangeChange = output();
67
+ // ── Estado interno / Internal state ──────────────────────────────
68
+ _id = `neu-date-input-${++_neuDateInputIdSeq}`;
69
+ isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
70
+ _isRange = computed(() => this.type() === 'range', ...(ngDevMode ? [{ debugName: "_isRange" }] : /* istanbul ignore next */ []));
71
+ _cvaDisabled = signal(false, ...(ngDevMode ? [{ debugName: "_cvaDisabled" }] : /* istanbul ignore next */ []));
72
+ isDisabledFinal = computed(() => this.disabled() || this._cvaDisabled(), ...(ngDevMode ? [{ debugName: "isDisabledFinal" }] : /* istanbul ignore next */ []));
73
+ hasError = computed(() => !!this.errorMessage(), ...(ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []));
74
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
+ _onChange = () => { };
76
+ _onTouched = () => { };
77
+ // ── State — single ────────────────────────────────────────────────
78
+ _value = signal('', ...(ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []));
79
+ _viewYear = signal(new Date().getFullYear(), ...(ngDevMode ? [{ debugName: "_viewYear" }] : /* istanbul ignore next */ []));
80
+ _viewMonth = signal(new Date().getMonth(), ...(ngDevMode ? [{ debugName: "_viewMonth" }] : /* istanbul ignore next */ []));
81
+ _selYear = signal(null, ...(ngDevMode ? [{ debugName: "_selYear" }] : /* istanbul ignore next */ []));
82
+ _selMonth = signal(null, ...(ngDevMode ? [{ debugName: "_selMonth" }] : /* istanbul ignore next */ []));
83
+ _selDay = signal(null, ...(ngDevMode ? [{ debugName: "_selDay" }] : /* istanbul ignore next */ []));
84
+ _selHour = signal(0, ...(ngDevMode ? [{ debugName: "_selHour" }] : /* istanbul ignore next */ []));
85
+ _selMinute = signal(0, ...(ngDevMode ? [{ debugName: "_selMinute" }] : /* istanbul ignore next */ []));
86
+ // ── State — range ─────────────────────────────────────────────────
87
+ _today = new Date();
88
+ _documentLang = signal(this.#normalizedLocale(this.doc.documentElement.lang) || 'es', ...(ngDevMode ? [{ debugName: "_documentLang" }] : /* istanbul ignore next */ []));
89
+ _pickStart = signal(null, ...(ngDevMode ? [{ debugName: "_pickStart" }] : /* istanbul ignore next */ []));
90
+ _pickEnd = signal(null, ...(ngDevMode ? [{ debugName: "_pickEnd" }] : /* istanbul ignore next */ []));
91
+ _hoverDate = signal(null, ...(ngDevMode ? [{ debugName: "_hoverDate" }] : /* istanbul ignore next */ []));
92
+ _leftCursor = signal(new Date(this._today.getFullYear(), this._today.getMonth(), 1), ...(ngDevMode ? [{ debugName: "_leftCursor" }] : /* istanbul ignore next */ []));
93
+ _rightCursor = computed(() => {
94
+ const l = this._leftCursor();
95
+ return new Date(l.getFullYear(), l.getMonth() + 1, 1);
96
+ }, ...(ngDevMode ? [{ debugName: "_rightCursor" }] : /* istanbul ignore next */ []));
97
+ _hasRange = computed(() => !!this._pickStart(), ...(ngDevMode ? [{ debugName: "_hasRange" }] : /* istanbul ignore next */ []));
98
+ _canApply = computed(() => this._pickStart() !== null && this._pickEnd() !== null, ...(ngDevMode ? [{ debugName: "_canApply" }] : /* istanbul ignore next */ []));
99
+ _resolvedLocale = computed(() => this.#normalizedLocale(this.locale()) || this._documentLang() || 'es', ...(ngDevMode ? [{ debugName: "_resolvedLocale" }] : /* istanbul ignore next */ []));
100
+ _texts = computed(() => {
101
+ const spanish = this._resolvedLocale().toLowerCase().startsWith('es');
102
+ return spanish
103
+ ? {
104
+ rangeAriaLabel: 'Seleccionar rango de fechas',
105
+ prevMonth: 'Mes anterior',
106
+ nextMonth: 'Mes siguiente',
107
+ clear: 'Limpiar',
108
+ apply: 'Aplicar',
109
+ chooseDate: 'Seleccionar fecha',
110
+ delete: 'Borrar',
111
+ today: 'Hoy',
112
+ prevHour: 'Hora anterior',
113
+ nextHour: 'Hora siguiente',
114
+ prevMinute: 'Minuto anterior',
115
+ nextMinute: 'Minuto siguiente',
116
+ rangePlaceholder: 'Seleccionar fechas',
117
+ timePlaceholder: 'hh:mm',
118
+ datePlaceholder: 'dd/mm/aaaa',
119
+ dateTimePlaceholder: 'dd/mm/aaaa, hh:mm',
120
+ }
121
+ : {
122
+ rangeAriaLabel: 'Select date range',
123
+ prevMonth: 'Previous month',
124
+ nextMonth: 'Next month',
125
+ clear: 'Clear',
126
+ apply: 'Apply',
127
+ chooseDate: 'Choose date',
128
+ delete: 'Clear',
129
+ today: 'Today',
130
+ prevHour: 'Previous hour',
131
+ nextHour: 'Next hour',
132
+ prevMinute: 'Previous minute',
133
+ nextMinute: 'Next minute',
134
+ rangePlaceholder: 'Select dates',
135
+ timePlaceholder: 'hh:mm',
136
+ datePlaceholder: 'mm/dd/yyyy',
137
+ dateTimePlaceholder: 'mm/dd/yyyy, hh:mm',
138
+ };
139
+ }, ...(ngDevMode ? [{ debugName: "_texts" }] : /* istanbul ignore next */ []));
140
+ _weekDayLabels = computed(() => this.#buildWeekdayLabels('short'), ...(ngDevMode ? [{ debugName: "_weekDayLabels" }] : /* istanbul ignore next */ []));
141
+ _leftTitle = computed(() => this._monthTitle(this._leftCursor()), ...(ngDevMode ? [{ debugName: "_leftTitle" }] : /* istanbul ignore next */ []));
142
+ _rightTitle = computed(() => this._monthTitle(this._rightCursor()), ...(ngDevMode ? [{ debugName: "_rightTitle" }] : /* istanbul ignore next */ []));
143
+ _leftDays = computed(() => this._buildRangeMonth(this._leftCursor()), ...(ngDevMode ? [{ debugName: "_leftDays" }] : /* istanbul ignore next */ []));
144
+ _rightDays = computed(() => this._buildRangeMonth(this._rightCursor()), ...(ngDevMode ? [{ debugName: "_rightDays" }] : /* istanbul ignore next */ []));
145
+ _rangePlaceholderText = computed(() => this.placeholder() || this._texts().rangePlaceholder, ...(ngDevMode ? [{ debugName: "_rangePlaceholderText" }] : /* istanbul ignore next */ []));
146
+ constructor() {
147
+ if (typeof MutationObserver !== 'undefined') {
148
+ this._langObserver = new MutationObserver(() => {
149
+ this._documentLang.set(this.#normalizedLocale(this.doc.documentElement.lang) || 'es');
150
+ });
151
+ this._langObserver.observe(this.doc.documentElement, {
152
+ attributes: true,
153
+ attributeFilter: ['lang'],
154
+ });
155
+ }
156
+ }
157
+ ngOnDestroy() {
158
+ this._langObserver?.disconnect();
159
+ }
160
+ _monthTitle(d) {
161
+ return this.#capitalize(new Intl.DateTimeFormat(this._resolvedLocale(), { month: 'long', year: 'numeric' }).format(d));
162
+ }
163
+ _rangeDisplayValue = computed(() => {
164
+ const s = this._pickStart();
165
+ const e = this._pickEnd();
166
+ if (!s)
167
+ return this.placeholder();
168
+ if (!e)
169
+ return this._fmtDate(s);
170
+ return `${this._fmtDate(s)} – ${this._fmtDate(e)}`;
171
+ }, ...(ngDevMode ? [{ debugName: "_rangeDisplayValue" }] : /* istanbul ignore next */ []));
172
+ _fmtDate(d) {
173
+ const fmt = this.dateFormat();
174
+ const opts = {
175
+ short: { day: '2-digit', month: '2-digit', year: 'numeric' },
176
+ medium: { day: '2-digit', month: 'short', year: 'numeric' },
177
+ long: { day: 'numeric', month: 'long', year: 'numeric' },
178
+ full: { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' },
179
+ numeric: { day: 'numeric', month: 'numeric', year: '2-digit' },
180
+ };
181
+ return d.toLocaleDateString(this._resolvedLocale(), opts[fmt] ?? opts['short']);
182
+ }
183
+ _buildRangeMonth(cursor) {
184
+ const year = cursor.getFullYear();
185
+ const month = cursor.getMonth();
186
+ const firstDay = new Date(year, month, 1);
187
+ const lastDay = new Date(year, month + 1, 0);
188
+ const startOffset = (firstDay.getDay() + 6) % 7;
189
+ const cells = [];
190
+ for (let i = startOffset - 1; i >= 0; i--) {
191
+ cells.push(this._rangeCell(new Date(year, month, -i), false));
192
+ }
193
+ for (let d = 1; d <= lastDay.getDate(); d++) {
194
+ cells.push(this._rangeCell(new Date(year, month, d), true));
195
+ }
196
+ while (cells.length % 7 !== 0 || cells.length < 42) {
197
+ cells.push(this._rangeCell(new Date(year, month + 1, cells.length - startOffset - lastDay.getDate() + 1), false));
198
+ }
199
+ return cells;
200
+ }
201
+ _rangeCell(date, current) {
202
+ const s = this._pickStart();
203
+ const e = this._pickEnd();
204
+ const h = this._hoverDate();
205
+ const rangeEnd = e ?? h;
206
+ const inRange = s && rangeEnd
207
+ ? (date > s && date < rangeEnd) || (rangeEnd < s && date > rangeEnd && date < s)
208
+ : false;
209
+ return {
210
+ date,
211
+ day: date.getDate(),
212
+ ts: date.getTime(),
213
+ current,
214
+ today: sameDay(date, this._today),
215
+ selected: (s && sameDay(date, s)) || (e && sameDay(date, e)) || false,
216
+ rangeStart: s ? sameDay(date, s) : false,
217
+ rangeEnd: e ? sameDay(date, e) : false,
218
+ inRange: !!inRange,
219
+ label: date.toLocaleDateString(this._resolvedLocale()),
220
+ };
221
+ }
222
+ // ── Range actions ─────────────────────────────────────────────────
223
+ _prevLeft() {
224
+ this._leftCursor.update((d) => new Date(d.getFullYear(), d.getMonth() - 1, 1));
225
+ }
226
+ _nextLeft() {
227
+ this._leftCursor.update((d) => new Date(d.getFullYear(), d.getMonth() + 1, 1));
228
+ }
229
+ _prevRight() {
230
+ this._leftCursor.update((d) => new Date(d.getFullYear(), d.getMonth() - 1, 1));
231
+ }
232
+ _nextRight() {
233
+ this._leftCursor.update((d) => new Date(d.getFullYear(), d.getMonth() + 1, 1));
234
+ }
235
+ _selectDay(date) {
236
+ const s = this._pickStart();
237
+ if (!s || this._pickEnd()) {
238
+ this._pickStart.set(cloneDate(date));
239
+ this._pickEnd.set(null);
240
+ this._hoverDate.set(null);
241
+ }
242
+ else {
243
+ if (date < s) {
244
+ this._pickEnd.set(cloneDate(s));
245
+ this._pickStart.set(cloneDate(date));
246
+ }
247
+ else {
248
+ this._pickEnd.set(cloneDate(date));
249
+ }
250
+ this._hoverDate.set(null);
251
+ }
252
+ }
253
+ _hoverDay(date) {
254
+ if (this._pickStart() && !this._pickEnd())
255
+ this._hoverDate.set(date);
256
+ }
257
+ _applyRange() {
258
+ const range = { start: this._pickStart(), end: this._pickEnd() };
259
+ this._onChange(range);
260
+ this.rangeChange.emit(range);
261
+ this._onTouched();
262
+ this.isOpen.set(false);
263
+ }
264
+ _clearRange() {
265
+ this._pickStart.set(null);
266
+ this._pickEnd.set(null);
267
+ this._hoverDate.set(null);
268
+ const range = { start: null, end: null };
269
+ this._onChange(range);
270
+ this.rangeChange.emit(range);
271
+ }
272
+ // ── Single computed ───────────────────────────────────────────────
273
+ displayValue = computed(() => {
274
+ const v = this._value();
275
+ if (!v)
276
+ return '';
277
+ const t = this.type();
278
+ if (t === 'date') {
279
+ const d = new Date(v + 'T00:00:00');
280
+ return isNaN(d.getTime())
281
+ ? v
282
+ : d.toLocaleDateString(this._resolvedLocale(), {
283
+ day: '2-digit',
284
+ month: '2-digit',
285
+ year: 'numeric',
286
+ });
287
+ }
288
+ if (t === 'time')
289
+ return v;
290
+ const [datePart, timePart] = v.split('T');
291
+ const d = new Date(datePart + 'T00:00:00');
292
+ return ((isNaN(d.getTime())
293
+ ? datePart
294
+ : d.toLocaleDateString(this._resolvedLocale(), {
295
+ day: '2-digit',
296
+ month: '2-digit',
297
+ year: 'numeric',
298
+ })) +
299
+ ', ' +
300
+ (timePart?.slice(0, 5) ?? ''));
301
+ }, ...(ngDevMode ? [{ debugName: "displayValue" }] : /* istanbul ignore next */ []));
302
+ placeholderText = computed(() => {
303
+ switch (this.type()) {
304
+ case 'time':
305
+ return this._texts().timePlaceholder;
306
+ case 'datetime-local':
307
+ return this._texts().dateTimePlaceholder;
308
+ default:
309
+ return this._texts().datePlaceholder;
310
+ }
311
+ }, ...(ngDevMode ? [{ debugName: "placeholderText" }] : /* istanbul ignore next */ []));
312
+ monthLabel = computed(() => this.#capitalize(new Date(this._viewYear(), this._viewMonth(), 1).toLocaleDateString(this._resolvedLocale(), {
313
+ month: 'long',
314
+ year: 'numeric',
315
+ })), ...(ngDevMode ? [{ debugName: "monthLabel" }] : /* istanbul ignore next */ []));
316
+ weekdays = computed(() => this.#buildWeekdayLabels('narrow'), ...(ngDevMode ? [{ debugName: "weekdays" }] : /* istanbul ignore next */ []));
317
+ calendarDays = computed(() => {
318
+ const year = this._viewYear();
319
+ const month = this._viewMonth();
320
+ const today = new Date();
321
+ const firstDay = new Date(year, month, 1);
322
+ const startDow = (firstDay.getDay() + 6) % 7;
323
+ const days = [];
324
+ for (let i = startDow; i > 0; i--) {
325
+ days.push({
326
+ date: new Date(year, month, 1 - i),
327
+ inMonth: false,
328
+ isToday: false,
329
+ isSelected: false,
330
+ });
331
+ }
332
+ const daysInMonth = new Date(year, month + 1, 0).getDate();
333
+ for (let d = 1; d <= daysInMonth; d++) {
334
+ const date = new Date(year, month, d);
335
+ days.push({
336
+ date,
337
+ inMonth: true,
338
+ isToday: date.toDateString() === today.toDateString(),
339
+ isSelected: this._selYear() === year && this._selMonth() === month && this._selDay() === d,
340
+ });
341
+ }
342
+ let next = 1;
343
+ while (days.length < 42) {
344
+ days.push({
345
+ date: new Date(year, month + 1, next++),
346
+ inMonth: false,
347
+ isToday: false,
348
+ isSelected: false,
349
+ });
350
+ }
351
+ return days;
352
+ }, ...(ngDevMode ? [{ debugName: "calendarDays" }] : /* istanbul ignore next */ []));
353
+ hourSlots = computed(() => this._drumSlots(this._selHour(), 24), ...(ngDevMode ? [{ debugName: "hourSlots" }] : /* istanbul ignore next */ []));
354
+ minuteSlots = computed(() => this._drumSlots(this._selMinute(), 60), ...(ngDevMode ? [{ debugName: "minuteSlots" }] : /* istanbul ignore next */ []));
355
+ _drumSlots(value, max) {
356
+ return [-1, 0, 1].map((offset) => {
357
+ const v = (((value + offset) % max) + max) % max;
358
+ return { value: v, offset, label: String(v).padStart(2, '0') };
359
+ });
360
+ }
361
+ // ── Single actions ────────────────────────────────────────────────
362
+ toggle() {
363
+ if (this.isDisabledFinal())
364
+ return;
365
+ if (!this._isRange() && this.readonly())
366
+ return;
367
+ this.isOpen.update((v) => !v);
368
+ }
369
+ close() {
370
+ this.isOpen.set(false);
371
+ }
372
+ onDocumentClick(event) {
373
+ if (!this.el.nativeElement.contains(event.target))
374
+ this.close();
375
+ }
376
+ prevMonth() {
377
+ if (this._viewMonth() === 0) {
378
+ this._viewMonth.set(11);
379
+ this._viewYear.update((y) => y - 1);
380
+ }
381
+ else
382
+ this._viewMonth.update((m) => m - 1);
383
+ }
384
+ nextMonth() {
385
+ if (this._viewMonth() === 11) {
386
+ this._viewMonth.set(0);
387
+ this._viewYear.update((y) => y + 1);
388
+ }
389
+ else
390
+ this._viewMonth.update((m) => m + 1);
391
+ }
392
+ selectDay(day) {
393
+ if (!day.inMonth)
394
+ return;
395
+ this._selYear.set(day.date.getFullYear());
396
+ this._selMonth.set(day.date.getMonth());
397
+ this._selDay.set(day.date.getDate());
398
+ this._emitValue();
399
+ if (this.type() === 'date')
400
+ this.close();
401
+ }
402
+ formatDayLabel(date) {
403
+ return date.toLocaleDateString(this._resolvedLocale(), {
404
+ weekday: 'long',
405
+ year: 'numeric',
406
+ month: 'long',
407
+ day: 'numeric',
408
+ });
409
+ }
410
+ today() {
411
+ const d = new Date();
412
+ this._viewYear.set(d.getFullYear());
413
+ this._viewMonth.set(d.getMonth());
414
+ this.selectDay({ date: d, inMonth: true, isToday: true, isSelected: false });
415
+ }
416
+ clear() {
417
+ this._selYear.set(null);
418
+ this._selMonth.set(null);
419
+ this._selDay.set(null);
420
+ this._value.set('');
421
+ this._onChange('');
422
+ this.close();
423
+ }
424
+ changeHour(delta) {
425
+ this._selHour.update((h) => (((h + delta) % 24) + 24) % 24);
426
+ this._emitValue();
427
+ }
428
+ changeMinute(delta) {
429
+ this._selMinute.update((m) => (((m + delta) % 60) + 60) % 60);
430
+ this._emitValue();
431
+ }
432
+ onHourWheel(e) {
433
+ e.preventDefault();
434
+ this.changeHour(e.deltaY > 0 ? 1 : -1);
435
+ }
436
+ onMinuteWheel(e) {
437
+ e.preventDefault();
438
+ this.changeMinute(e.deltaY > 0 ? 1 : -1);
439
+ }
440
+ _emitValue() {
441
+ const t = this.type();
442
+ let v = '';
443
+ if (t === 'date' || t === 'datetime-local') {
444
+ if (this._selYear() === null)
445
+ return;
446
+ const y = this._selYear();
447
+ const mo = String(this._selMonth() + 1).padStart(2, '0');
448
+ const d = String(this._selDay()).padStart(2, '0');
449
+ const ds = `${y}-${mo}-${d}`;
450
+ v =
451
+ t === 'date'
452
+ ? ds
453
+ : `${ds}T${String(this._selHour()).padStart(2, '0')}:${String(this._selMinute()).padStart(2, '0')}`;
454
+ }
455
+ else {
456
+ v = `${String(this._selHour()).padStart(2, '0')}:${String(this._selMinute()).padStart(2, '0')}`;
457
+ }
458
+ this._value.set(v);
459
+ this._onChange(v);
460
+ }
461
+ // ── CVA ───────────────────────────────────────────────────────────
462
+ writeValue(value) {
463
+ if (this.type() === 'range') {
464
+ const v = value;
465
+ this._pickStart.set(v?.start ?? null);
466
+ this._pickEnd.set(v?.end ?? null);
467
+ }
468
+ else {
469
+ const v = value ?? '';
470
+ this._value.set(v);
471
+ if (!v)
472
+ return;
473
+ const t = this.type();
474
+ if (t === 'date') {
475
+ const d = new Date(v + 'T00:00:00');
476
+ if (!isNaN(d.getTime())) {
477
+ this._selYear.set(d.getFullYear());
478
+ this._selMonth.set(d.getMonth());
479
+ this._selDay.set(d.getDate());
480
+ this._viewYear.set(d.getFullYear());
481
+ this._viewMonth.set(d.getMonth());
482
+ }
483
+ }
484
+ else if (t === 'time') {
485
+ const [h, m] = v.split(':').map(Number);
486
+ if (!isNaN(h))
487
+ this._selHour.set(h);
488
+ if (!isNaN(m))
489
+ this._selMinute.set(m);
490
+ }
491
+ else {
492
+ const [datePart, timePart] = v.split('T');
493
+ if (datePart) {
494
+ const d = new Date(datePart + 'T00:00:00');
495
+ if (!isNaN(d.getTime())) {
496
+ this._selYear.set(d.getFullYear());
497
+ this._selMonth.set(d.getMonth());
498
+ this._selDay.set(d.getDate());
499
+ this._viewYear.set(d.getFullYear());
500
+ this._viewMonth.set(d.getMonth());
501
+ }
502
+ }
503
+ if (timePart) {
504
+ const [h, m] = timePart.split(':').map(Number);
505
+ if (!isNaN(h))
506
+ this._selHour.set(h);
507
+ if (!isNaN(m))
508
+ this._selMinute.set(m);
509
+ }
510
+ }
511
+ }
512
+ }
513
+ registerOnChange(fn) {
514
+ this._onChange = fn;
515
+ }
516
+ registerOnTouched(fn) {
517
+ this._onTouched = fn;
518
+ }
519
+ setDisabledState(isDisabled) {
520
+ this._cvaDisabled.set(isDisabled);
521
+ }
522
+ #normalizedLocale(locale) {
523
+ return locale?.trim() || '';
524
+ }
525
+ #capitalize(value) {
526
+ return value ? value.charAt(0).toUpperCase() + value.slice(1) : value;
527
+ }
528
+ #buildWeekdayLabels(style) {
529
+ const formatter = new Intl.DateTimeFormat(this._resolvedLocale(), {
530
+ weekday: style,
531
+ timeZone: 'UTC',
532
+ });
533
+ return Array.from({ length: 7 }, (_, index) => {
534
+ const label = formatter
535
+ .format(new Date(Date.UTC(2024, 0, 1 + index)))
536
+ .replace(/\.$/, '')
537
+ .trim();
538
+ if (style === 'narrow') {
539
+ return label.slice(0, 1).toUpperCase();
540
+ }
541
+ return this.#capitalize(label);
542
+ });
543
+ }
544
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuDateInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
545
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: NeuDateInputComponent, isStandalone: true, selector: "neu-date-input", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, dateFormat: { classPropertyName: "dateFormat", publicName: "dateFormat", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rangeChange: "rangeChange" }, host: { listeners: { "keydown.escape": "close()", "document:click": "onDocumentClick($event)" }, properties: { "class.neu-date-input-host--sm": "size() === \"sm\"", "class.neu-date-input-host--lg": "size() === \"lg\"", "class.neu-drp": "_isRange()", "class.neu-drp--open": "_isRange() && isOpen()", "class.neu-drp--disabled": "_isRange() && isDisabledFinal()" }, classAttribute: "neu-date-input-host" }, providers: [
546
+ {
547
+ provide: NG_VALUE_ACCESSOR,
548
+ useExisting: forwardRef(() => NeuDateInputComponent),
549
+ multi: true,
550
+ },
551
+ ], ngImport: i0, template: `
552
+ @if (_isRange()) {
553
+ @if (label()) {
554
+ <label class="neu-drp__label" [for]="_id">{{ label() }}</label>
555
+ }
556
+ <button
557
+ type="button"
558
+ [id]="_id"
559
+ class="neu-drp__trigger"
560
+ [attr.aria-expanded]="isOpen()"
561
+ [attr.aria-label]="label() || _texts().rangeAriaLabel"
562
+ [disabled]="isDisabledFinal()"
563
+ (click)="toggle()"
564
+ >
565
+ <span class="neu-drp__icon" aria-hidden="true">
566
+ <svg
567
+ viewBox="0 0 24 24"
568
+ fill="none"
569
+ stroke="currentColor"
570
+ stroke-width="1.8"
571
+ stroke-linecap="round"
572
+ stroke-linejoin="round"
573
+ >
574
+ <rect x="3" y="4" width="18" height="18" rx="2" />
575
+ <line x1="16" y1="2" x2="16" y2="6" />
576
+ <line x1="8" y1="2" x2="8" y2="6" />
577
+ <line x1="3" y1="10" x2="21" y2="10" />
578
+ </svg>
579
+ </span>
580
+ <span class="neu-drp__value" [class.neu-drp__value--placeholder]="!_hasRange()">
581
+ {{ _hasRange() ? _rangeDisplayValue() : _rangePlaceholderText() }}
582
+ </span>
583
+ </button>
584
+ @if (isOpen()) {
585
+ <div
586
+ class="neu-drp__panel"
587
+ role="dialog"
588
+ aria-modal="true"
589
+ [attr.aria-label]="_texts().rangeAriaLabel"
590
+ (click)="$event.stopPropagation()"
591
+ >
592
+ <div class="neu-drp__calendars">
593
+ <div class="neu-drp__cal">
594
+ <div class="neu-drp__cal-nav">
595
+ <button type="button" [attr.aria-label]="_texts().prevMonth" (click)="_prevLeft()">
596
+
597
+ </button>
598
+ <span class="neu-drp__cal-title">{{ _leftTitle() }}</span>
599
+ <button type="button" [attr.aria-label]="_texts().nextMonth" (click)="_nextLeft()">
600
+
601
+ </button>
602
+ </div>
603
+ <div class="neu-drp__cal-grid">
604
+ @for (d of _weekDayLabels(); track d) {
605
+ <span class="neu-drp__day-label">{{ d }}</span>
606
+ }
607
+ @for (cell of _leftDays(); track cell.ts) {
608
+ <button
609
+ type="button"
610
+ class="neu-drp__cell"
611
+ [class.neu-drp__cell--other-month]="!cell.current"
612
+ [class.neu-drp__cell--today]="cell.today"
613
+ [class.neu-drp__cell--selected]="cell.selected"
614
+ [class.neu-drp__cell--range-start]="cell.rangeStart"
615
+ [class.neu-drp__cell--range-end]="cell.rangeEnd"
616
+ [class.neu-drp__cell--in-range]="cell.inRange"
617
+ [attr.aria-label]="cell.label"
618
+ [attr.aria-pressed]="cell.selected"
619
+ (click)="_selectDay(cell.date)"
620
+ (mouseenter)="_hoverDay(cell.date)"
621
+ >
622
+ {{ cell.day }}
623
+ </button>
624
+ }
625
+ </div>
626
+ </div>
627
+ <div class="neu-drp__cal">
628
+ <div class="neu-drp__cal-nav">
629
+ <button type="button" [attr.aria-label]="_texts().prevMonth" (click)="_prevRight()">
630
+
631
+ </button>
632
+ <span class="neu-drp__cal-title">{{ _rightTitle() }}</span>
633
+ <button type="button" [attr.aria-label]="_texts().nextMonth" (click)="_nextRight()">
634
+
635
+ </button>
636
+ </div>
637
+ <div class="neu-drp__cal-grid">
638
+ @for (d of _weekDayLabels(); track d) {
639
+ <span class="neu-drp__day-label">{{ d }}</span>
640
+ }
641
+ @for (cell of _rightDays(); track cell.ts) {
642
+ <button
643
+ type="button"
644
+ class="neu-drp__cell"
645
+ [class.neu-drp__cell--other-month]="!cell.current"
646
+ [class.neu-drp__cell--today]="cell.today"
647
+ [class.neu-drp__cell--selected]="cell.selected"
648
+ [class.neu-drp__cell--range-start]="cell.rangeStart"
649
+ [class.neu-drp__cell--range-end]="cell.rangeEnd"
650
+ [class.neu-drp__cell--in-range]="cell.inRange"
651
+ [attr.aria-label]="cell.label"
652
+ [attr.aria-pressed]="cell.selected"
653
+ (click)="_selectDay(cell.date)"
654
+ (mouseenter)="_hoverDay(cell.date)"
655
+ >
656
+ {{ cell.day }}
657
+ </button>
658
+ }
659
+ </div>
660
+ </div>
661
+ </div>
662
+ <div class="neu-drp__footer">
663
+ <button type="button" class="neu-drp__clear" (click)="_clearRange()">
664
+ {{ _texts().clear }}
665
+ </button>
666
+ <button
667
+ type="button"
668
+ class="neu-drp__apply"
669
+ [disabled]="!_canApply()"
670
+ (click)="_applyRange()"
671
+ >
672
+ {{ _texts().apply }}
673
+ </button>
674
+ </div>
675
+ </div>
676
+ }
677
+ } @else {
678
+ @if (label()) {
679
+ <label class="neu-date-input__label" [for]="_id">{{ label() }}</label>
680
+ }
681
+ <div
682
+ class="neu-date-input"
683
+ [class.neu-date-input--open]="isOpen()"
684
+ [class.neu-date-input--disabled]="isDisabledFinal()"
685
+ [class.neu-date-input--error]="hasError()"
686
+ >
687
+ <button
688
+ class="neu-date-input__trigger"
689
+ type="button"
690
+ [id]="_id"
691
+ [disabled]="isDisabledFinal() || readonly()"
692
+ [attr.aria-expanded]="isOpen()"
693
+ [attr.aria-haspopup]="'dialog'"
694
+ (click)="toggle()"
695
+ >
696
+ <span class="neu-date-input__icon" aria-hidden="true">
697
+ @if (type() === 'time') {
698
+ <svg
699
+ viewBox="0 0 24 24"
700
+ fill="none"
701
+ stroke="currentColor"
702
+ stroke-width="1.8"
703
+ stroke-linecap="round"
704
+ stroke-linejoin="round"
705
+ >
706
+ <circle cx="12" cy="12" r="10" />
707
+ <polyline points="12 6 12 12 16 14" />
708
+ </svg>
709
+ } @else {
710
+ <svg
711
+ viewBox="0 0 24 24"
712
+ fill="none"
713
+ stroke="currentColor"
714
+ stroke-width="1.8"
715
+ stroke-linecap="round"
716
+ stroke-linejoin="round"
717
+ >
718
+ <rect x="3" y="4" width="18" height="18" rx="2" />
719
+ <line x1="16" y1="2" x2="16" y2="6" />
720
+ <line x1="8" y1="2" x2="8" y2="6" />
721
+ <line x1="3" y1="10" x2="21" y2="10" />
722
+ </svg>
723
+ }
724
+ </span>
725
+ <span
726
+ class="neu-date-input__display"
727
+ [class.neu-date-input__display--placeholder]="!_value()"
728
+ >
729
+ {{ displayValue() || placeholderText() }}
730
+ </span>
731
+ </button>
732
+ @if (isOpen()) {
733
+ <div
734
+ class="neu-date-input__panel"
735
+ [class.neu-date-input__panel--time-only]="type() === 'time'"
736
+ role="dialog"
737
+ [attr.aria-label]="_texts().chooseDate + (monthLabel() ? ': ' + monthLabel() : '')"
738
+ (click)="$event.stopPropagation()"
739
+ >
740
+ @if (type() !== 'time') {
741
+ <div class="neu-date-input__calendar">
742
+ <div class="neu-date-input__cal-nav">
743
+ <button
744
+ class="neu-date-input__cal-arrow"
745
+ type="button"
746
+ (click)="prevMonth()"
747
+ [attr.aria-label]="_texts().prevMonth"
748
+ >
749
+ <svg
750
+ viewBox="0 0 24 24"
751
+ fill="none"
752
+ stroke="currentColor"
753
+ stroke-width="2"
754
+ stroke-linecap="round"
755
+ aria-hidden="true"
756
+ >
757
+ <polyline points="15 18 9 12 15 6" />
758
+ </svg>
759
+ </button>
760
+ <span class="neu-date-input__cal-title">{{ monthLabel() }}</span>
761
+ <button
762
+ class="neu-date-input__cal-arrow"
763
+ type="button"
764
+ (click)="nextMonth()"
765
+ [attr.aria-label]="_texts().nextMonth"
766
+ >
767
+ <svg
768
+ viewBox="0 0 24 24"
769
+ fill="none"
770
+ stroke="currentColor"
771
+ stroke-width="2"
772
+ stroke-linecap="round"
773
+ aria-hidden="true"
774
+ >
775
+ <polyline points="9 18 15 12 9 6" />
776
+ </svg>
777
+ </button>
778
+ </div>
779
+ <div class="neu-date-input__cal-weekdays">
780
+ @for (d of weekdays(); track d) {
781
+ <span>{{ d }}</span>
782
+ }
783
+ </div>
784
+ <div class="neu-date-input__cal-grid">
785
+ @for (day of calendarDays(); track day.date.getTime()) {
786
+ <button
787
+ class="neu-date-input__cal-day"
788
+ type="button"
789
+ [class.neu-date-input__cal-day--other]="!day.inMonth"
790
+ [class.neu-date-input__cal-day--today]="day.isToday"
791
+ [class.neu-date-input__cal-day--selected]="day.isSelected"
792
+ [attr.aria-label]="formatDayLabel(day.date)"
793
+ [attr.aria-pressed]="day.isSelected"
794
+ (click)="selectDay(day)"
795
+ >
796
+ {{ day.date.getDate() }}
797
+ </button>
798
+ }
799
+ </div>
800
+ <div class="neu-date-input__cal-footer">
801
+ <button class="neu-date-input__cal-footer-btn" type="button" (click)="clear()">
802
+ {{ _texts().delete }}
803
+ </button>
804
+ <button
805
+ class="neu-date-input__cal-footer-btn neu-date-input__cal-footer-btn--today"
806
+ type="button"
807
+ (click)="today()"
808
+ >
809
+ {{ _texts().today }}
810
+ </button>
811
+ </div>
812
+ </div>
813
+ }
814
+ @if (type() === 'datetime-local') {
815
+ <div class="neu-date-input__sep"></div>
816
+ }
817
+ @if (type() !== 'date') {
818
+ <div class="neu-date-input__time">
819
+ <div class="neu-date-input__drum">
820
+ <button
821
+ class="neu-date-input__drum-arrow"
822
+ type="button"
823
+ (click)="changeHour(-1)"
824
+ [attr.aria-label]="_texts().prevHour"
825
+ >
826
+ <svg
827
+ viewBox="0 0 24 24"
828
+ fill="none"
829
+ stroke="currentColor"
830
+ stroke-width="2.5"
831
+ stroke-linecap="round"
832
+ aria-hidden="true"
833
+ >
834
+ <polyline points="18 15 12 9 6 15" />
835
+ </svg>
836
+ </button>
837
+ <div class="neu-date-input__drum-track" (wheel)="onHourWheel($event)">
838
+ @for (slot of hourSlots(); track slot.offset) {
839
+ <div
840
+ class="neu-date-input__drum-item"
841
+ [class.neu-date-input__drum-item--selected]="slot.offset === 0"
842
+ [class.neu-date-input__drum-item--adjacent]="slot.offset !== 0"
843
+ (click)="slot.offset !== 0 && changeHour(slot.offset)"
844
+ >
845
+ {{ slot.label }}
846
+ </div>
847
+ }
848
+ </div>
849
+ <button
850
+ class="neu-date-input__drum-arrow"
851
+ type="button"
852
+ (click)="changeHour(1)"
853
+ [attr.aria-label]="_texts().nextHour"
854
+ >
855
+ <svg
856
+ viewBox="0 0 24 24"
857
+ fill="none"
858
+ stroke="currentColor"
859
+ stroke-width="2.5"
860
+ stroke-linecap="round"
861
+ aria-hidden="true"
862
+ >
863
+ <polyline points="6 9 12 15 18 9" />
864
+ </svg>
865
+ </button>
866
+ </div>
867
+ <span class="neu-date-input__time-colon">:</span>
868
+ <div class="neu-date-input__drum">
869
+ <button
870
+ class="neu-date-input__drum-arrow"
871
+ type="button"
872
+ (click)="changeMinute(-1)"
873
+ [attr.aria-label]="_texts().prevMinute"
874
+ >
875
+ <svg
876
+ viewBox="0 0 24 24"
877
+ fill="none"
878
+ stroke="currentColor"
879
+ stroke-width="2.5"
880
+ stroke-linecap="round"
881
+ aria-hidden="true"
882
+ >
883
+ <polyline points="18 15 12 9 6 15" />
884
+ </svg>
885
+ </button>
886
+ <div class="neu-date-input__drum-track" (wheel)="onMinuteWheel($event)">
887
+ @for (slot of minuteSlots(); track slot.offset) {
888
+ <div
889
+ class="neu-date-input__drum-item"
890
+ [class.neu-date-input__drum-item--selected]="slot.offset === 0"
891
+ [class.neu-date-input__drum-item--adjacent]="slot.offset !== 0"
892
+ (click)="slot.offset !== 0 && changeMinute(slot.offset)"
893
+ >
894
+ {{ slot.label }}
895
+ </div>
896
+ }
897
+ </div>
898
+ <button
899
+ class="neu-date-input__drum-arrow"
900
+ type="button"
901
+ (click)="changeMinute(1)"
902
+ [attr.aria-label]="_texts().nextMinute"
903
+ >
904
+ <svg
905
+ viewBox="0 0 24 24"
906
+ fill="none"
907
+ stroke="currentColor"
908
+ stroke-width="2.5"
909
+ stroke-linecap="round"
910
+ aria-hidden="true"
911
+ >
912
+ <polyline points="6 9 12 15 18 9" />
913
+ </svg>
914
+ </button>
915
+ </div>
916
+ </div>
917
+ }
918
+ </div>
919
+ }
920
+ </div>
921
+ @if (hasError()) {
922
+ <p class="neu-date-input__error" role="alert">{{ errorMessage() }}</p>
923
+ } @else if (hint()) {
924
+ <p class="neu-date-input__hint">{{ hint() }}</p>
925
+ }
926
+ }
927
+ `, isInline: true, styles: [".neu-date-input-host{display:block;font-family:var(--neu-font-sans)}.neu-date-input__label{display:block;font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted);margin-bottom:var(--neu-space-2)}.neu-date-input{position:relative;font-family:var(--neu-font-sans)}.neu-date-input__trigger{display:flex;align-items:center;gap:var(--neu-space-2);width:100%;min-height:48px;padding:0 var(--neu-space-3);background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);cursor:pointer;text-align:left;font-family:var(--neu-font-sans);font-size:var(--neu-text-base);color:var(--neu-text);transition:border-color var(--neu-transition),box-shadow var(--neu-transition)}.neu-date-input__trigger:hover:not(:disabled){border-color:var(--neu-border-hover, var(--neu-border))}.neu-date-input__trigger:disabled{opacity:.6;cursor:not-allowed;background:var(--neu-surface-2)}.neu-date-input--open .neu-date-input__trigger{border-color:var(--neu-primary);box-shadow:var(--neu-focus-ring)}.neu-date-input--error .neu-date-input__trigger{border-color:var(--neu-error)}.neu-date-input__icon{display:flex;align-items:center;color:var(--neu-text-muted);flex-shrink:0}.neu-date-input__icon svg{width:18px;height:18px}.neu-date-input__display{flex:1;color:var(--neu-text);white-space:nowrap}.neu-date-input__display--placeholder{color:var(--neu-text-disabled)}.neu-date-input__panel{position:absolute;top:calc(100% + 6px);left:0;z-index:200;background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);box-shadow:var(--neu-shadow-lg);display:flex;flex-direction:column;overflow:hidden;animation:neu-datepicker-in .12s ease}.neu-date-input__panel--time-only{flex-direction:row}@media(max-width:600px){.neu-date-input__panel{left:auto;right:0;width:min(280px,100vw - 2rem);max-width:calc(100vw - 2rem)}}@keyframes neu-datepicker-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.neu-date-input__calendar{padding:var(--neu-space-3);width:280px;flex-shrink:0}.neu-date-input__cal-nav{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--neu-space-2)}.neu-date-input__cal-title{font-size:var(--neu-text-sm);font-weight:600;color:var(--neu-text);text-transform:capitalize}.neu-date-input__cal-arrow{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:none;border:none;border-radius:var(--neu-radius-sm);color:var(--neu-text-muted);cursor:pointer;transition:background var(--neu-transition),color var(--neu-transition)}.neu-date-input__cal-arrow:hover{background:var(--neu-surface-2);color:var(--neu-text)}.neu-date-input__cal-arrow svg{width:15px;height:15px}.neu-date-input__cal-weekdays{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;margin-bottom:4px}.neu-date-input__cal-weekdays span{font-size:11px;font-weight:600;color:var(--neu-text-muted);padding:4px 0;text-transform:uppercase}.neu-date-input__cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.neu-date-input__cal-day{display:flex;align-items:center;justify-content:center;aspect-ratio:1;width:100%;padding:0;background:none;border:none;border-radius:var(--neu-radius-sm);font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);color:var(--neu-text);cursor:pointer;transition:background var(--neu-transition),color var(--neu-transition)}.neu-date-input__cal-day:hover:not(.neu-date-input__cal-day--other):not(.neu-date-input__cal-day--selected){background:var(--neu-surface-2)}.neu-date-input__cal-day--other{color:var(--neu-text-disabled);pointer-events:none;cursor:default}.neu-date-input__cal-day--today{color:var(--neu-primary);font-weight:700}.neu-date-input__cal-day--selected{background:var(--neu-primary)!important;color:var(--neu-primary-fg)!important;font-weight:600}.neu-date-input__cal-footer{display:flex;justify-content:space-between;align-items:center;margin-top:var(--neu-space-2);padding-top:var(--neu-space-2);border-top:1px solid var(--neu-border)}.neu-date-input__cal-footer-btn{background:none;border:none;padding:4px 8px;font-family:var(--neu-font-sans);font-size:var(--neu-text-xs);color:var(--neu-text-muted);cursor:pointer;border-radius:var(--neu-radius-sm);transition:background var(--neu-transition),color var(--neu-transition)}.neu-date-input__cal-footer-btn:hover{background:var(--neu-surface-2);color:var(--neu-text)}.neu-date-input__cal-footer-btn--today{color:var(--neu-primary);font-weight:500}.neu-date-input__cal-footer-btn--today:hover{color:var(--neu-primary)}.neu-date-input__sep{height:1px;width:100%;background:var(--neu-border);flex-shrink:0}.neu-date-input__time{display:flex;align-items:center;justify-content:center;gap:var(--neu-space-1);padding:var(--neu-space-3) var(--neu-space-4);flex-shrink:0}.neu-date-input__time-colon{font-size:20px;font-weight:700;color:var(--neu-text);line-height:1;margin-bottom:4px;-webkit-user-select:none;user-select:none}.neu-date-input__drum{display:flex;flex-direction:column;align-items:center;gap:4px}.neu-date-input__drum-arrow{display:flex;align-items:center;justify-content:center;width:36px;height:24px;padding:0;background:none;border:none;border-radius:var(--neu-radius-sm);color:var(--neu-text-muted);cursor:pointer;transition:background var(--neu-transition),color var(--neu-transition)}.neu-date-input__drum-arrow:hover{background:var(--neu-surface-2);color:var(--neu-text)}.neu-date-input__drum-arrow svg{width:14px;height:14px}.neu-date-input__drum-track{position:relative;display:flex;flex-direction:column;align-items:center}.neu-date-input__drum-track:before{content:\"\";position:absolute;top:36px;left:-6px;right:-6px;height:36px;background:var(--neu-primary-soft, rgba(0, 122, 255, .1));border-radius:var(--neu-radius-sm);pointer-events:none}.neu-date-input__drum-item{position:relative;display:flex;align-items:center;justify-content:center;width:52px;height:36px;font-family:var(--neu-font-sans);font-weight:500;-webkit-user-select:none;user-select:none;border-radius:var(--neu-radius-sm);transition:opacity var(--neu-transition)}.neu-date-input__drum-item--adjacent{font-size:13px;color:var(--neu-text-muted);opacity:.45;cursor:pointer}.neu-date-input__drum-item--adjacent:hover{opacity:.75}.neu-date-input__drum-item--selected{font-size:22px;font-weight:700;color:var(--neu-primary);cursor:default}.neu-date-input__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-date-input__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-drp{position:relative;display:block;font-family:var(--neu-font-sans)}.neu-drp--disabled{opacity:.55;pointer-events:none}.neu-drp__label{display:block;font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted);margin-bottom:var(--neu-space-2)}.neu-drp__trigger{all:unset;display:flex;align-items:center;gap:var(--neu-space-2);width:100%;min-height:48px;padding:0 var(--neu-space-3);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);background:var(--neu-surface);color:var(--neu-text);font-size:var(--neu-text-base);font-family:var(--neu-font-sans);cursor:pointer;box-sizing:border-box;transition:border-color var(--neu-transition),box-shadow var(--neu-transition)}.neu-drp__trigger:hover:not([disabled]){border-color:var(--neu-border-hover, var(--neu-border))}.neu-drp__trigger:focus-visible{outline:none;border-color:var(--neu-primary);box-shadow:var(--neu-focus-ring)}.neu-drp__trigger[disabled]{opacity:.6;cursor:not-allowed;background:var(--neu-surface-2)}.neu-drp--open .neu-drp__trigger{border-color:var(--neu-primary);box-shadow:var(--neu-focus-ring)}.neu-drp__icon{display:flex;align-items:center;color:var(--neu-text-muted);flex-shrink:0}.neu-drp__icon svg{width:18px;height:18px}.neu-drp__value{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.neu-drp__value--placeholder{color:var(--neu-text-disabled)}.neu-drp__panel{position:absolute;top:calc(100% + 6px);left:0;background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius-lg);box-shadow:var(--neu-shadow-lg);padding:var(--neu-space-4);z-index:1000;animation:neu-drp-in .1s ease;min-width:560px}@keyframes neu-drp-in{0%{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:translateY(0)}}.neu-drp__calendars{display:flex;gap:var(--neu-space-6)}.neu-drp__cal{flex:1}.neu-drp__cal-nav{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--neu-space-3)}.neu-drp__cal-nav button{all:unset;padding:4px 8px;border-radius:var(--neu-radius);cursor:pointer;font-size:1.1rem;color:var(--neu-text-muted)}.neu-drp__cal-nav button:hover{background:var(--neu-surface-2)}.neu-drp__cal-title{font-size:var(--neu-text-sm);font-weight:600;text-transform:capitalize;color:var(--neu-text)}.neu-drp__cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.neu-drp__day-label{text-align:center;font-size:.7rem;font-weight:600;color:var(--neu-text-muted);padding:4px 0}.neu-drp__cell{all:unset;display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;font-size:var(--neu-text-sm);cursor:pointer;transition:background var(--neu-transition);box-sizing:border-box;margin:1px auto}.neu-drp__cell:hover{background:var(--neu-surface-2)}.neu-drp__cell--other-month{opacity:.35}.neu-drp__cell--today{font-weight:700;border:1.5px solid var(--neu-primary)}.neu-drp__cell--selected,.neu-drp__cell--range-start,.neu-drp__cell--range-end{background:var(--neu-primary);color:var(--neu-primary-fg);border-radius:50%}.neu-drp__cell--in-range{background:var(--neu-primary-soft, rgba(14, 165, 233, .15));border-radius:0}.neu-drp__footer{display:flex;justify-content:flex-end;gap:var(--neu-space-2);padding-top:var(--neu-space-3);border-top:1px solid var(--neu-border);margin-top:var(--neu-space-3)}.neu-drp__clear{all:unset;padding:7px 14px;border-radius:var(--neu-radius);font-size:var(--neu-text-sm);color:var(--neu-text-muted);cursor:pointer;background:var(--neu-surface-2)}.neu-drp__clear:hover{background:var(--neu-surface-3, var(--neu-surface-2));color:var(--neu-text)}.neu-drp__apply{all:unset;padding:7px 18px;border-radius:var(--neu-radius);font-size:var(--neu-text-sm);font-weight:500;background:var(--neu-primary);color:var(--neu-primary-fg);cursor:pointer}.neu-drp__apply:hover:not([disabled]){filter:brightness(1.08)}.neu-drp__apply[disabled]{opacity:.4;cursor:not-allowed}.neu-drp__apply:focus-visible{outline:2px solid var(--neu-primary);outline-offset:2px}@media(max-width:600px){.neu-drp__panel{left:0;right:auto;min-width:0;width:min(100%,360px,100vw - 2rem);max-width:calc(100vw - 2rem);padding:var(--neu-space-2)}.neu-drp__calendars{flex-direction:column;gap:var(--neu-space-4)}.neu-drp__cal{width:100%;max-width:320px;margin-inline:auto}.neu-drp__footer{flex-wrap:wrap}}.neu-date-input-host--sm .neu-date-input__trigger{min-height:36px;font-size:var(--neu-text-sm)}.neu-date-input-host--lg .neu-date-input__trigger{min-height:56px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
928
+ }
929
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: NeuDateInputComponent, decorators: [{
930
+ type: Component,
931
+ args: [{ selector: 'neu-date-input', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
932
+ class: 'neu-date-input-host',
933
+ '[class.neu-date-input-host--sm]': 'size() === "sm"',
934
+ '[class.neu-date-input-host--lg]': 'size() === "lg"',
935
+ '[class.neu-drp]': '_isRange()',
936
+ '[class.neu-drp--open]': '_isRange() && isOpen()',
937
+ '[class.neu-drp--disabled]': '_isRange() && isDisabledFinal()',
938
+ '(keydown.escape)': 'close()',
939
+ }, providers: [
940
+ {
941
+ provide: NG_VALUE_ACCESSOR,
942
+ useExisting: forwardRef(() => NeuDateInputComponent),
943
+ multi: true,
944
+ },
945
+ ], template: `
946
+ @if (_isRange()) {
947
+ @if (label()) {
948
+ <label class="neu-drp__label" [for]="_id">{{ label() }}</label>
949
+ }
950
+ <button
951
+ type="button"
952
+ [id]="_id"
953
+ class="neu-drp__trigger"
954
+ [attr.aria-expanded]="isOpen()"
955
+ [attr.aria-label]="label() || _texts().rangeAriaLabel"
956
+ [disabled]="isDisabledFinal()"
957
+ (click)="toggle()"
958
+ >
959
+ <span class="neu-drp__icon" aria-hidden="true">
960
+ <svg
961
+ viewBox="0 0 24 24"
962
+ fill="none"
963
+ stroke="currentColor"
964
+ stroke-width="1.8"
965
+ stroke-linecap="round"
966
+ stroke-linejoin="round"
967
+ >
968
+ <rect x="3" y="4" width="18" height="18" rx="2" />
969
+ <line x1="16" y1="2" x2="16" y2="6" />
970
+ <line x1="8" y1="2" x2="8" y2="6" />
971
+ <line x1="3" y1="10" x2="21" y2="10" />
972
+ </svg>
973
+ </span>
974
+ <span class="neu-drp__value" [class.neu-drp__value--placeholder]="!_hasRange()">
975
+ {{ _hasRange() ? _rangeDisplayValue() : _rangePlaceholderText() }}
976
+ </span>
977
+ </button>
978
+ @if (isOpen()) {
979
+ <div
980
+ class="neu-drp__panel"
981
+ role="dialog"
982
+ aria-modal="true"
983
+ [attr.aria-label]="_texts().rangeAriaLabel"
984
+ (click)="$event.stopPropagation()"
985
+ >
986
+ <div class="neu-drp__calendars">
987
+ <div class="neu-drp__cal">
988
+ <div class="neu-drp__cal-nav">
989
+ <button type="button" [attr.aria-label]="_texts().prevMonth" (click)="_prevLeft()">
990
+
991
+ </button>
992
+ <span class="neu-drp__cal-title">{{ _leftTitle() }}</span>
993
+ <button type="button" [attr.aria-label]="_texts().nextMonth" (click)="_nextLeft()">
994
+
995
+ </button>
996
+ </div>
997
+ <div class="neu-drp__cal-grid">
998
+ @for (d of _weekDayLabels(); track d) {
999
+ <span class="neu-drp__day-label">{{ d }}</span>
1000
+ }
1001
+ @for (cell of _leftDays(); track cell.ts) {
1002
+ <button
1003
+ type="button"
1004
+ class="neu-drp__cell"
1005
+ [class.neu-drp__cell--other-month]="!cell.current"
1006
+ [class.neu-drp__cell--today]="cell.today"
1007
+ [class.neu-drp__cell--selected]="cell.selected"
1008
+ [class.neu-drp__cell--range-start]="cell.rangeStart"
1009
+ [class.neu-drp__cell--range-end]="cell.rangeEnd"
1010
+ [class.neu-drp__cell--in-range]="cell.inRange"
1011
+ [attr.aria-label]="cell.label"
1012
+ [attr.aria-pressed]="cell.selected"
1013
+ (click)="_selectDay(cell.date)"
1014
+ (mouseenter)="_hoverDay(cell.date)"
1015
+ >
1016
+ {{ cell.day }}
1017
+ </button>
1018
+ }
1019
+ </div>
1020
+ </div>
1021
+ <div class="neu-drp__cal">
1022
+ <div class="neu-drp__cal-nav">
1023
+ <button type="button" [attr.aria-label]="_texts().prevMonth" (click)="_prevRight()">
1024
+
1025
+ </button>
1026
+ <span class="neu-drp__cal-title">{{ _rightTitle() }}</span>
1027
+ <button type="button" [attr.aria-label]="_texts().nextMonth" (click)="_nextRight()">
1028
+
1029
+ </button>
1030
+ </div>
1031
+ <div class="neu-drp__cal-grid">
1032
+ @for (d of _weekDayLabels(); track d) {
1033
+ <span class="neu-drp__day-label">{{ d }}</span>
1034
+ }
1035
+ @for (cell of _rightDays(); track cell.ts) {
1036
+ <button
1037
+ type="button"
1038
+ class="neu-drp__cell"
1039
+ [class.neu-drp__cell--other-month]="!cell.current"
1040
+ [class.neu-drp__cell--today]="cell.today"
1041
+ [class.neu-drp__cell--selected]="cell.selected"
1042
+ [class.neu-drp__cell--range-start]="cell.rangeStart"
1043
+ [class.neu-drp__cell--range-end]="cell.rangeEnd"
1044
+ [class.neu-drp__cell--in-range]="cell.inRange"
1045
+ [attr.aria-label]="cell.label"
1046
+ [attr.aria-pressed]="cell.selected"
1047
+ (click)="_selectDay(cell.date)"
1048
+ (mouseenter)="_hoverDay(cell.date)"
1049
+ >
1050
+ {{ cell.day }}
1051
+ </button>
1052
+ }
1053
+ </div>
1054
+ </div>
1055
+ </div>
1056
+ <div class="neu-drp__footer">
1057
+ <button type="button" class="neu-drp__clear" (click)="_clearRange()">
1058
+ {{ _texts().clear }}
1059
+ </button>
1060
+ <button
1061
+ type="button"
1062
+ class="neu-drp__apply"
1063
+ [disabled]="!_canApply()"
1064
+ (click)="_applyRange()"
1065
+ >
1066
+ {{ _texts().apply }}
1067
+ </button>
1068
+ </div>
1069
+ </div>
1070
+ }
1071
+ } @else {
1072
+ @if (label()) {
1073
+ <label class="neu-date-input__label" [for]="_id">{{ label() }}</label>
1074
+ }
1075
+ <div
1076
+ class="neu-date-input"
1077
+ [class.neu-date-input--open]="isOpen()"
1078
+ [class.neu-date-input--disabled]="isDisabledFinal()"
1079
+ [class.neu-date-input--error]="hasError()"
1080
+ >
1081
+ <button
1082
+ class="neu-date-input__trigger"
1083
+ type="button"
1084
+ [id]="_id"
1085
+ [disabled]="isDisabledFinal() || readonly()"
1086
+ [attr.aria-expanded]="isOpen()"
1087
+ [attr.aria-haspopup]="'dialog'"
1088
+ (click)="toggle()"
1089
+ >
1090
+ <span class="neu-date-input__icon" aria-hidden="true">
1091
+ @if (type() === 'time') {
1092
+ <svg
1093
+ viewBox="0 0 24 24"
1094
+ fill="none"
1095
+ stroke="currentColor"
1096
+ stroke-width="1.8"
1097
+ stroke-linecap="round"
1098
+ stroke-linejoin="round"
1099
+ >
1100
+ <circle cx="12" cy="12" r="10" />
1101
+ <polyline points="12 6 12 12 16 14" />
1102
+ </svg>
1103
+ } @else {
1104
+ <svg
1105
+ viewBox="0 0 24 24"
1106
+ fill="none"
1107
+ stroke="currentColor"
1108
+ stroke-width="1.8"
1109
+ stroke-linecap="round"
1110
+ stroke-linejoin="round"
1111
+ >
1112
+ <rect x="3" y="4" width="18" height="18" rx="2" />
1113
+ <line x1="16" y1="2" x2="16" y2="6" />
1114
+ <line x1="8" y1="2" x2="8" y2="6" />
1115
+ <line x1="3" y1="10" x2="21" y2="10" />
1116
+ </svg>
1117
+ }
1118
+ </span>
1119
+ <span
1120
+ class="neu-date-input__display"
1121
+ [class.neu-date-input__display--placeholder]="!_value()"
1122
+ >
1123
+ {{ displayValue() || placeholderText() }}
1124
+ </span>
1125
+ </button>
1126
+ @if (isOpen()) {
1127
+ <div
1128
+ class="neu-date-input__panel"
1129
+ [class.neu-date-input__panel--time-only]="type() === 'time'"
1130
+ role="dialog"
1131
+ [attr.aria-label]="_texts().chooseDate + (monthLabel() ? ': ' + monthLabel() : '')"
1132
+ (click)="$event.stopPropagation()"
1133
+ >
1134
+ @if (type() !== 'time') {
1135
+ <div class="neu-date-input__calendar">
1136
+ <div class="neu-date-input__cal-nav">
1137
+ <button
1138
+ class="neu-date-input__cal-arrow"
1139
+ type="button"
1140
+ (click)="prevMonth()"
1141
+ [attr.aria-label]="_texts().prevMonth"
1142
+ >
1143
+ <svg
1144
+ viewBox="0 0 24 24"
1145
+ fill="none"
1146
+ stroke="currentColor"
1147
+ stroke-width="2"
1148
+ stroke-linecap="round"
1149
+ aria-hidden="true"
1150
+ >
1151
+ <polyline points="15 18 9 12 15 6" />
1152
+ </svg>
1153
+ </button>
1154
+ <span class="neu-date-input__cal-title">{{ monthLabel() }}</span>
1155
+ <button
1156
+ class="neu-date-input__cal-arrow"
1157
+ type="button"
1158
+ (click)="nextMonth()"
1159
+ [attr.aria-label]="_texts().nextMonth"
1160
+ >
1161
+ <svg
1162
+ viewBox="0 0 24 24"
1163
+ fill="none"
1164
+ stroke="currentColor"
1165
+ stroke-width="2"
1166
+ stroke-linecap="round"
1167
+ aria-hidden="true"
1168
+ >
1169
+ <polyline points="9 18 15 12 9 6" />
1170
+ </svg>
1171
+ </button>
1172
+ </div>
1173
+ <div class="neu-date-input__cal-weekdays">
1174
+ @for (d of weekdays(); track d) {
1175
+ <span>{{ d }}</span>
1176
+ }
1177
+ </div>
1178
+ <div class="neu-date-input__cal-grid">
1179
+ @for (day of calendarDays(); track day.date.getTime()) {
1180
+ <button
1181
+ class="neu-date-input__cal-day"
1182
+ type="button"
1183
+ [class.neu-date-input__cal-day--other]="!day.inMonth"
1184
+ [class.neu-date-input__cal-day--today]="day.isToday"
1185
+ [class.neu-date-input__cal-day--selected]="day.isSelected"
1186
+ [attr.aria-label]="formatDayLabel(day.date)"
1187
+ [attr.aria-pressed]="day.isSelected"
1188
+ (click)="selectDay(day)"
1189
+ >
1190
+ {{ day.date.getDate() }}
1191
+ </button>
1192
+ }
1193
+ </div>
1194
+ <div class="neu-date-input__cal-footer">
1195
+ <button class="neu-date-input__cal-footer-btn" type="button" (click)="clear()">
1196
+ {{ _texts().delete }}
1197
+ </button>
1198
+ <button
1199
+ class="neu-date-input__cal-footer-btn neu-date-input__cal-footer-btn--today"
1200
+ type="button"
1201
+ (click)="today()"
1202
+ >
1203
+ {{ _texts().today }}
1204
+ </button>
1205
+ </div>
1206
+ </div>
1207
+ }
1208
+ @if (type() === 'datetime-local') {
1209
+ <div class="neu-date-input__sep"></div>
1210
+ }
1211
+ @if (type() !== 'date') {
1212
+ <div class="neu-date-input__time">
1213
+ <div class="neu-date-input__drum">
1214
+ <button
1215
+ class="neu-date-input__drum-arrow"
1216
+ type="button"
1217
+ (click)="changeHour(-1)"
1218
+ [attr.aria-label]="_texts().prevHour"
1219
+ >
1220
+ <svg
1221
+ viewBox="0 0 24 24"
1222
+ fill="none"
1223
+ stroke="currentColor"
1224
+ stroke-width="2.5"
1225
+ stroke-linecap="round"
1226
+ aria-hidden="true"
1227
+ >
1228
+ <polyline points="18 15 12 9 6 15" />
1229
+ </svg>
1230
+ </button>
1231
+ <div class="neu-date-input__drum-track" (wheel)="onHourWheel($event)">
1232
+ @for (slot of hourSlots(); track slot.offset) {
1233
+ <div
1234
+ class="neu-date-input__drum-item"
1235
+ [class.neu-date-input__drum-item--selected]="slot.offset === 0"
1236
+ [class.neu-date-input__drum-item--adjacent]="slot.offset !== 0"
1237
+ (click)="slot.offset !== 0 && changeHour(slot.offset)"
1238
+ >
1239
+ {{ slot.label }}
1240
+ </div>
1241
+ }
1242
+ </div>
1243
+ <button
1244
+ class="neu-date-input__drum-arrow"
1245
+ type="button"
1246
+ (click)="changeHour(1)"
1247
+ [attr.aria-label]="_texts().nextHour"
1248
+ >
1249
+ <svg
1250
+ viewBox="0 0 24 24"
1251
+ fill="none"
1252
+ stroke="currentColor"
1253
+ stroke-width="2.5"
1254
+ stroke-linecap="round"
1255
+ aria-hidden="true"
1256
+ >
1257
+ <polyline points="6 9 12 15 18 9" />
1258
+ </svg>
1259
+ </button>
1260
+ </div>
1261
+ <span class="neu-date-input__time-colon">:</span>
1262
+ <div class="neu-date-input__drum">
1263
+ <button
1264
+ class="neu-date-input__drum-arrow"
1265
+ type="button"
1266
+ (click)="changeMinute(-1)"
1267
+ [attr.aria-label]="_texts().prevMinute"
1268
+ >
1269
+ <svg
1270
+ viewBox="0 0 24 24"
1271
+ fill="none"
1272
+ stroke="currentColor"
1273
+ stroke-width="2.5"
1274
+ stroke-linecap="round"
1275
+ aria-hidden="true"
1276
+ >
1277
+ <polyline points="18 15 12 9 6 15" />
1278
+ </svg>
1279
+ </button>
1280
+ <div class="neu-date-input__drum-track" (wheel)="onMinuteWheel($event)">
1281
+ @for (slot of minuteSlots(); track slot.offset) {
1282
+ <div
1283
+ class="neu-date-input__drum-item"
1284
+ [class.neu-date-input__drum-item--selected]="slot.offset === 0"
1285
+ [class.neu-date-input__drum-item--adjacent]="slot.offset !== 0"
1286
+ (click)="slot.offset !== 0 && changeMinute(slot.offset)"
1287
+ >
1288
+ {{ slot.label }}
1289
+ </div>
1290
+ }
1291
+ </div>
1292
+ <button
1293
+ class="neu-date-input__drum-arrow"
1294
+ type="button"
1295
+ (click)="changeMinute(1)"
1296
+ [attr.aria-label]="_texts().nextMinute"
1297
+ >
1298
+ <svg
1299
+ viewBox="0 0 24 24"
1300
+ fill="none"
1301
+ stroke="currentColor"
1302
+ stroke-width="2.5"
1303
+ stroke-linecap="round"
1304
+ aria-hidden="true"
1305
+ >
1306
+ <polyline points="6 9 12 15 18 9" />
1307
+ </svg>
1308
+ </button>
1309
+ </div>
1310
+ </div>
1311
+ }
1312
+ </div>
1313
+ }
1314
+ </div>
1315
+ @if (hasError()) {
1316
+ <p class="neu-date-input__error" role="alert">{{ errorMessage() }}</p>
1317
+ } @else if (hint()) {
1318
+ <p class="neu-date-input__hint">{{ hint() }}</p>
1319
+ }
1320
+ }
1321
+ `, styles: [".neu-date-input-host{display:block;font-family:var(--neu-font-sans)}.neu-date-input__label{display:block;font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted);margin-bottom:var(--neu-space-2)}.neu-date-input{position:relative;font-family:var(--neu-font-sans)}.neu-date-input__trigger{display:flex;align-items:center;gap:var(--neu-space-2);width:100%;min-height:48px;padding:0 var(--neu-space-3);background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);cursor:pointer;text-align:left;font-family:var(--neu-font-sans);font-size:var(--neu-text-base);color:var(--neu-text);transition:border-color var(--neu-transition),box-shadow var(--neu-transition)}.neu-date-input__trigger:hover:not(:disabled){border-color:var(--neu-border-hover, var(--neu-border))}.neu-date-input__trigger:disabled{opacity:.6;cursor:not-allowed;background:var(--neu-surface-2)}.neu-date-input--open .neu-date-input__trigger{border-color:var(--neu-primary);box-shadow:var(--neu-focus-ring)}.neu-date-input--error .neu-date-input__trigger{border-color:var(--neu-error)}.neu-date-input__icon{display:flex;align-items:center;color:var(--neu-text-muted);flex-shrink:0}.neu-date-input__icon svg{width:18px;height:18px}.neu-date-input__display{flex:1;color:var(--neu-text);white-space:nowrap}.neu-date-input__display--placeholder{color:var(--neu-text-disabled)}.neu-date-input__panel{position:absolute;top:calc(100% + 6px);left:0;z-index:200;background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);box-shadow:var(--neu-shadow-lg);display:flex;flex-direction:column;overflow:hidden;animation:neu-datepicker-in .12s ease}.neu-date-input__panel--time-only{flex-direction:row}@media(max-width:600px){.neu-date-input__panel{left:auto;right:0;width:min(280px,100vw - 2rem);max-width:calc(100vw - 2rem)}}@keyframes neu-datepicker-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.neu-date-input__calendar{padding:var(--neu-space-3);width:280px;flex-shrink:0}.neu-date-input__cal-nav{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--neu-space-2)}.neu-date-input__cal-title{font-size:var(--neu-text-sm);font-weight:600;color:var(--neu-text);text-transform:capitalize}.neu-date-input__cal-arrow{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;background:none;border:none;border-radius:var(--neu-radius-sm);color:var(--neu-text-muted);cursor:pointer;transition:background var(--neu-transition),color var(--neu-transition)}.neu-date-input__cal-arrow:hover{background:var(--neu-surface-2);color:var(--neu-text)}.neu-date-input__cal-arrow svg{width:15px;height:15px}.neu-date-input__cal-weekdays{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;margin-bottom:4px}.neu-date-input__cal-weekdays span{font-size:11px;font-weight:600;color:var(--neu-text-muted);padding:4px 0;text-transform:uppercase}.neu-date-input__cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.neu-date-input__cal-day{display:flex;align-items:center;justify-content:center;aspect-ratio:1;width:100%;padding:0;background:none;border:none;border-radius:var(--neu-radius-sm);font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);color:var(--neu-text);cursor:pointer;transition:background var(--neu-transition),color var(--neu-transition)}.neu-date-input__cal-day:hover:not(.neu-date-input__cal-day--other):not(.neu-date-input__cal-day--selected){background:var(--neu-surface-2)}.neu-date-input__cal-day--other{color:var(--neu-text-disabled);pointer-events:none;cursor:default}.neu-date-input__cal-day--today{color:var(--neu-primary);font-weight:700}.neu-date-input__cal-day--selected{background:var(--neu-primary)!important;color:var(--neu-primary-fg)!important;font-weight:600}.neu-date-input__cal-footer{display:flex;justify-content:space-between;align-items:center;margin-top:var(--neu-space-2);padding-top:var(--neu-space-2);border-top:1px solid var(--neu-border)}.neu-date-input__cal-footer-btn{background:none;border:none;padding:4px 8px;font-family:var(--neu-font-sans);font-size:var(--neu-text-xs);color:var(--neu-text-muted);cursor:pointer;border-radius:var(--neu-radius-sm);transition:background var(--neu-transition),color var(--neu-transition)}.neu-date-input__cal-footer-btn:hover{background:var(--neu-surface-2);color:var(--neu-text)}.neu-date-input__cal-footer-btn--today{color:var(--neu-primary);font-weight:500}.neu-date-input__cal-footer-btn--today:hover{color:var(--neu-primary)}.neu-date-input__sep{height:1px;width:100%;background:var(--neu-border);flex-shrink:0}.neu-date-input__time{display:flex;align-items:center;justify-content:center;gap:var(--neu-space-1);padding:var(--neu-space-3) var(--neu-space-4);flex-shrink:0}.neu-date-input__time-colon{font-size:20px;font-weight:700;color:var(--neu-text);line-height:1;margin-bottom:4px;-webkit-user-select:none;user-select:none}.neu-date-input__drum{display:flex;flex-direction:column;align-items:center;gap:4px}.neu-date-input__drum-arrow{display:flex;align-items:center;justify-content:center;width:36px;height:24px;padding:0;background:none;border:none;border-radius:var(--neu-radius-sm);color:var(--neu-text-muted);cursor:pointer;transition:background var(--neu-transition),color var(--neu-transition)}.neu-date-input__drum-arrow:hover{background:var(--neu-surface-2);color:var(--neu-text)}.neu-date-input__drum-arrow svg{width:14px;height:14px}.neu-date-input__drum-track{position:relative;display:flex;flex-direction:column;align-items:center}.neu-date-input__drum-track:before{content:\"\";position:absolute;top:36px;left:-6px;right:-6px;height:36px;background:var(--neu-primary-soft, rgba(0, 122, 255, .1));border-radius:var(--neu-radius-sm);pointer-events:none}.neu-date-input__drum-item{position:relative;display:flex;align-items:center;justify-content:center;width:52px;height:36px;font-family:var(--neu-font-sans);font-weight:500;-webkit-user-select:none;user-select:none;border-radius:var(--neu-radius-sm);transition:opacity var(--neu-transition)}.neu-date-input__drum-item--adjacent{font-size:13px;color:var(--neu-text-muted);opacity:.45;cursor:pointer}.neu-date-input__drum-item--adjacent:hover{opacity:.75}.neu-date-input__drum-item--selected{font-size:22px;font-weight:700;color:var(--neu-primary);cursor:default}.neu-date-input__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-date-input__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-drp{position:relative;display:block;font-family:var(--neu-font-sans)}.neu-drp--disabled{opacity:.55;pointer-events:none}.neu-drp__label{display:block;font-size:var(--neu-text-sm);font-weight:500;color:var(--neu-text-muted);margin-bottom:var(--neu-space-2)}.neu-drp__trigger{all:unset;display:flex;align-items:center;gap:var(--neu-space-2);width:100%;min-height:48px;padding:0 var(--neu-space-3);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);background:var(--neu-surface);color:var(--neu-text);font-size:var(--neu-text-base);font-family:var(--neu-font-sans);cursor:pointer;box-sizing:border-box;transition:border-color var(--neu-transition),box-shadow var(--neu-transition)}.neu-drp__trigger:hover:not([disabled]){border-color:var(--neu-border-hover, var(--neu-border))}.neu-drp__trigger:focus-visible{outline:none;border-color:var(--neu-primary);box-shadow:var(--neu-focus-ring)}.neu-drp__trigger[disabled]{opacity:.6;cursor:not-allowed;background:var(--neu-surface-2)}.neu-drp--open .neu-drp__trigger{border-color:var(--neu-primary);box-shadow:var(--neu-focus-ring)}.neu-drp__icon{display:flex;align-items:center;color:var(--neu-text-muted);flex-shrink:0}.neu-drp__icon svg{width:18px;height:18px}.neu-drp__value{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.neu-drp__value--placeholder{color:var(--neu-text-disabled)}.neu-drp__panel{position:absolute;top:calc(100% + 6px);left:0;background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius-lg);box-shadow:var(--neu-shadow-lg);padding:var(--neu-space-4);z-index:1000;animation:neu-drp-in .1s ease;min-width:560px}@keyframes neu-drp-in{0%{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:translateY(0)}}.neu-drp__calendars{display:flex;gap:var(--neu-space-6)}.neu-drp__cal{flex:1}.neu-drp__cal-nav{display:flex;align-items:center;justify-content:space-between;margin-bottom:var(--neu-space-3)}.neu-drp__cal-nav button{all:unset;padding:4px 8px;border-radius:var(--neu-radius);cursor:pointer;font-size:1.1rem;color:var(--neu-text-muted)}.neu-drp__cal-nav button:hover{background:var(--neu-surface-2)}.neu-drp__cal-title{font-size:var(--neu-text-sm);font-weight:600;text-transform:capitalize;color:var(--neu-text)}.neu-drp__cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.neu-drp__day-label{text-align:center;font-size:.7rem;font-weight:600;color:var(--neu-text-muted);padding:4px 0}.neu-drp__cell{all:unset;display:flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;font-size:var(--neu-text-sm);cursor:pointer;transition:background var(--neu-transition);box-sizing:border-box;margin:1px auto}.neu-drp__cell:hover{background:var(--neu-surface-2)}.neu-drp__cell--other-month{opacity:.35}.neu-drp__cell--today{font-weight:700;border:1.5px solid var(--neu-primary)}.neu-drp__cell--selected,.neu-drp__cell--range-start,.neu-drp__cell--range-end{background:var(--neu-primary);color:var(--neu-primary-fg);border-radius:50%}.neu-drp__cell--in-range{background:var(--neu-primary-soft, rgba(14, 165, 233, .15));border-radius:0}.neu-drp__footer{display:flex;justify-content:flex-end;gap:var(--neu-space-2);padding-top:var(--neu-space-3);border-top:1px solid var(--neu-border);margin-top:var(--neu-space-3)}.neu-drp__clear{all:unset;padding:7px 14px;border-radius:var(--neu-radius);font-size:var(--neu-text-sm);color:var(--neu-text-muted);cursor:pointer;background:var(--neu-surface-2)}.neu-drp__clear:hover{background:var(--neu-surface-3, var(--neu-surface-2));color:var(--neu-text)}.neu-drp__apply{all:unset;padding:7px 18px;border-radius:var(--neu-radius);font-size:var(--neu-text-sm);font-weight:500;background:var(--neu-primary);color:var(--neu-primary-fg);cursor:pointer}.neu-drp__apply:hover:not([disabled]){filter:brightness(1.08)}.neu-drp__apply[disabled]{opacity:.4;cursor:not-allowed}.neu-drp__apply:focus-visible{outline:2px solid var(--neu-primary);outline-offset:2px}@media(max-width:600px){.neu-drp__panel{left:0;right:auto;min-width:0;width:min(100%,360px,100vw - 2rem);max-width:calc(100vw - 2rem);padding:var(--neu-space-2)}.neu-drp__calendars{flex-direction:column;gap:var(--neu-space-4)}.neu-drp__cal{width:100%;max-width:320px;margin-inline:auto}.neu-drp__footer{flex-wrap:wrap}}.neu-date-input-host--sm .neu-date-input__trigger{min-height:36px;font-size:var(--neu-text-sm)}.neu-date-input-host--lg .neu-date-input__trigger{min-height:56px}\n"] }]
1322
+ }], ctorParameters: () => [], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], dateFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateFormat", required: false }] }], rangeChange: [{ type: i0.Output, args: ["rangeChange"] }], onDocumentClick: [{
1323
+ type: HostListener,
1324
+ args: ['document:click', ['$event']]
1325
+ }] } });
1326
+
1327
+ /**
1328
+ * Generated bundle index. Do not edit.
1329
+ */
1330
+
1331
+ export { NeuDateInputComponent };
1332
+ //# sourceMappingURL=neural-ui-core-date-input.mjs.map