yukit-web 0.0.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 (196) hide show
  1. package/.npm/_logs/2026-08-20T08_40_55_706Z-debug-0.log +38 -0
  2. package/.npm/_logs/2026-08-20T08_40_56_280Z-debug-0.log +14 -0
  3. package/README.md +1465 -0
  4. package/fesm2022/yukit-web-helm-accordion.mjs +141 -0
  5. package/fesm2022/yukit-web-helm-accordion.mjs.map +1 -0
  6. package/fesm2022/yukit-web-helm-alert-dialog.mjs +250 -0
  7. package/fesm2022/yukit-web-helm-alert-dialog.mjs.map +1 -0
  8. package/fesm2022/yukit-web-helm-alert.mjs +94 -0
  9. package/fesm2022/yukit-web-helm-alert.mjs.map +1 -0
  10. package/fesm2022/yukit-web-helm-aspect-ratio.mjs +47 -0
  11. package/fesm2022/yukit-web-helm-aspect-ratio.mjs.map +1 -0
  12. package/fesm2022/yukit-web-helm-attachment.mjs +211 -0
  13. package/fesm2022/yukit-web-helm-attachment.mjs.map +1 -0
  14. package/fesm2022/yukit-web-helm-autocomplete.mjs +361 -0
  15. package/fesm2022/yukit-web-helm-autocomplete.mjs.map +1 -0
  16. package/fesm2022/yukit-web-helm-avatar.mjs +152 -0
  17. package/fesm2022/yukit-web-helm-avatar.mjs.map +1 -0
  18. package/fesm2022/yukit-web-helm-badge.mjs +47 -0
  19. package/fesm2022/yukit-web-helm-badge.mjs.map +1 -0
  20. package/fesm2022/yukit-web-helm-breadcrumb.mjs +196 -0
  21. package/fesm2022/yukit-web-helm-breadcrumb.mjs.map +1 -0
  22. package/fesm2022/yukit-web-helm-bubble.mjs +121 -0
  23. package/fesm2022/yukit-web-helm-bubble.mjs.map +1 -0
  24. package/fesm2022/yukit-web-helm-button-group.mjs +86 -0
  25. package/fesm2022/yukit-web-helm-button-group.mjs.map +1 -0
  26. package/fesm2022/yukit-web-helm-button.mjs +77 -0
  27. package/fesm2022/yukit-web-helm-button.mjs.map +1 -0
  28. package/fesm2022/yukit-web-helm-calendar.mjs +937 -0
  29. package/fesm2022/yukit-web-helm-calendar.mjs.map +1 -0
  30. package/fesm2022/yukit-web-helm-card.mjs +141 -0
  31. package/fesm2022/yukit-web-helm-card.mjs.map +1 -0
  32. package/fesm2022/yukit-web-helm-carousel.mjs +270 -0
  33. package/fesm2022/yukit-web-helm-carousel.mjs.map +1 -0
  34. package/fesm2022/yukit-web-helm-checkbox.mjs +147 -0
  35. package/fesm2022/yukit-web-helm-checkbox.mjs.map +1 -0
  36. package/fesm2022/yukit-web-helm-collapsible.mjs +62 -0
  37. package/fesm2022/yukit-web-helm-collapsible.mjs.map +1 -0
  38. package/fesm2022/yukit-web-helm-combobox.mjs +624 -0
  39. package/fesm2022/yukit-web-helm-combobox.mjs.map +1 -0
  40. package/fesm2022/yukit-web-helm-command.mjs +315 -0
  41. package/fesm2022/yukit-web-helm-command.mjs.map +1 -0
  42. package/fesm2022/yukit-web-helm-context-menu.mjs +71 -0
  43. package/fesm2022/yukit-web-helm-context-menu.mjs.map +1 -0
  44. package/fesm2022/yukit-web-helm-date-picker.mjs +1517 -0
  45. package/fesm2022/yukit-web-helm-date-picker.mjs.map +1 -0
  46. package/fesm2022/yukit-web-helm-dialog.mjs +271 -0
  47. package/fesm2022/yukit-web-helm-dialog.mjs.map +1 -0
  48. package/fesm2022/yukit-web-helm-drawer.mjs +233 -0
  49. package/fesm2022/yukit-web-helm-drawer.mjs.map +1 -0
  50. package/fesm2022/yukit-web-helm-dropdown-menu.mjs +508 -0
  51. package/fesm2022/yukit-web-helm-dropdown-menu.mjs.map +1 -0
  52. package/fesm2022/yukit-web-helm-empty.mjs +125 -0
  53. package/fesm2022/yukit-web-helm-empty.mjs.map +1 -0
  54. package/fesm2022/yukit-web-helm-field.mjs +325 -0
  55. package/fesm2022/yukit-web-helm-field.mjs.map +1 -0
  56. package/fesm2022/yukit-web-helm-hover-card.mjs +102 -0
  57. package/fesm2022/yukit-web-helm-hover-card.mjs.map +1 -0
  58. package/fesm2022/yukit-web-helm-input-group.mjs +171 -0
  59. package/fesm2022/yukit-web-helm-input-group.mjs.map +1 -0
  60. package/fesm2022/yukit-web-helm-input-otp.mjs +127 -0
  61. package/fesm2022/yukit-web-helm-input-otp.mjs.map +1 -0
  62. package/fesm2022/yukit-web-helm-input.mjs +32 -0
  63. package/fesm2022/yukit-web-helm-input.mjs.map +1 -0
  64. package/fesm2022/yukit-web-helm-item.mjs +242 -0
  65. package/fesm2022/yukit-web-helm-item.mjs.map +1 -0
  66. package/fesm2022/yukit-web-helm-kbd.mjs +46 -0
  67. package/fesm2022/yukit-web-helm-kbd.mjs.map +1 -0
  68. package/fesm2022/yukit-web-helm-label.mjs +30 -0
  69. package/fesm2022/yukit-web-helm-label.mjs.map +1 -0
  70. package/fesm2022/yukit-web-helm-marker.mjs +77 -0
  71. package/fesm2022/yukit-web-helm-marker.mjs.map +1 -0
  72. package/fesm2022/yukit-web-helm-menubar.mjs +90 -0
  73. package/fesm2022/yukit-web-helm-menubar.mjs.map +1 -0
  74. package/fesm2022/yukit-web-helm-message.mjs +115 -0
  75. package/fesm2022/yukit-web-helm-message.mjs.map +1 -0
  76. package/fesm2022/yukit-web-helm-native-select.mjs +180 -0
  77. package/fesm2022/yukit-web-helm-native-select.mjs.map +1 -0
  78. package/fesm2022/yukit-web-helm-navigation-menu.mjs +173 -0
  79. package/fesm2022/yukit-web-helm-navigation-menu.mjs.map +1 -0
  80. package/fesm2022/yukit-web-helm-pagination.mjs +745 -0
  81. package/fesm2022/yukit-web-helm-pagination.mjs.map +1 -0
  82. package/fesm2022/yukit-web-helm-popover.mjs +136 -0
  83. package/fesm2022/yukit-web-helm-popover.mjs.map +1 -0
  84. package/fesm2022/yukit-web-helm-progress.mjs +60 -0
  85. package/fesm2022/yukit-web-helm-progress.mjs.map +1 -0
  86. package/fesm2022/yukit-web-helm-radio-group.mjs +185 -0
  87. package/fesm2022/yukit-web-helm-radio-group.mjs.map +1 -0
  88. package/fesm2022/yukit-web-helm-resizable.mjs +98 -0
  89. package/fesm2022/yukit-web-helm-resizable.mjs.map +1 -0
  90. package/fesm2022/yukit-web-helm-scroll-area.mjs +36 -0
  91. package/fesm2022/yukit-web-helm-scroll-area.mjs.map +1 -0
  92. package/fesm2022/yukit-web-helm-select.mjs +412 -0
  93. package/fesm2022/yukit-web-helm-select.mjs.map +1 -0
  94. package/fesm2022/yukit-web-helm-separator.mjs +33 -0
  95. package/fesm2022/yukit-web-helm-separator.mjs.map +1 -0
  96. package/fesm2022/yukit-web-helm-sheet.mjs +254 -0
  97. package/fesm2022/yukit-web-helm-sheet.mjs.map +1 -0
  98. package/fesm2022/yukit-web-helm-sidebar.mjs +857 -0
  99. package/fesm2022/yukit-web-helm-sidebar.mjs.map +1 -0
  100. package/fesm2022/yukit-web-helm-skeleton.mjs +29 -0
  101. package/fesm2022/yukit-web-helm-skeleton.mjs.map +1 -0
  102. package/fesm2022/yukit-web-helm-slider.mjs +123 -0
  103. package/fesm2022/yukit-web-helm-slider.mjs.map +1 -0
  104. package/fesm2022/yukit-web-helm-sonner.mjs +126 -0
  105. package/fesm2022/yukit-web-helm-sonner.mjs.map +1 -0
  106. package/fesm2022/yukit-web-helm-spinner.mjs +48 -0
  107. package/fesm2022/yukit-web-helm-spinner.mjs.map +1 -0
  108. package/fesm2022/yukit-web-helm-switch.mjs +126 -0
  109. package/fesm2022/yukit-web-helm-switch.mjs.map +1 -0
  110. package/fesm2022/yukit-web-helm-table.mjs +180 -0
  111. package/fesm2022/yukit-web-helm-table.mjs.map +1 -0
  112. package/fesm2022/yukit-web-helm-tabs.mjs +251 -0
  113. package/fesm2022/yukit-web-helm-tabs.mjs.map +1 -0
  114. package/fesm2022/yukit-web-helm-textarea.mjs +32 -0
  115. package/fesm2022/yukit-web-helm-textarea.mjs.map +1 -0
  116. package/fesm2022/yukit-web-helm-toggle-group.mjs +95 -0
  117. package/fesm2022/yukit-web-helm-toggle-group.mjs.map +1 -0
  118. package/fesm2022/yukit-web-helm-toggle.mjs +61 -0
  119. package/fesm2022/yukit-web-helm-toggle.mjs.map +1 -0
  120. package/fesm2022/yukit-web-helm-tooltip.mjs +57 -0
  121. package/fesm2022/yukit-web-helm-tooltip.mjs.map +1 -0
  122. package/fesm2022/yukit-web-helm-typography.mjs +205 -0
  123. package/fesm2022/yukit-web-helm-typography.mjs.map +1 -0
  124. package/fesm2022/yukit-web-helm-utils.mjs +272 -0
  125. package/fesm2022/yukit-web-helm-utils.mjs.map +1 -0
  126. package/fesm2022/yukit-web.mjs +3592 -0
  127. package/fesm2022/yukit-web.mjs.map +1 -0
  128. package/package.json +291 -0
  129. package/src/lib/theme/spartan-overwrites/accordion.css +4 -0
  130. package/src/lib/theme/theme.css +161 -0
  131. package/src/lib/theme/tokens/color.css +356 -0
  132. package/src/lib/theme/tokens/component-colors.css +167 -0
  133. package/src/lib/theme/tokens/radius.css +18 -0
  134. package/src/lib/theme/tokens/typography.css +201 -0
  135. package/types/yukit-web-helm-accordion.d.ts +32 -0
  136. package/types/yukit-web-helm-alert-dialog.d.ts +85 -0
  137. package/types/yukit-web-helm-alert.d.ts +37 -0
  138. package/types/yukit-web-helm-aspect-ratio.d.ts +16 -0
  139. package/types/yukit-web-helm-attachment.d.ts +80 -0
  140. package/types/yukit-web-helm-autocomplete.d.ts +91 -0
  141. package/types/yukit-web-helm-avatar.d.ts +45 -0
  142. package/types/yukit-web-helm-badge.d.ts +19 -0
  143. package/types/yukit-web-helm-breadcrumb.d.ts +52 -0
  144. package/types/yukit-web-helm-bubble.d.ts +46 -0
  145. package/types/yukit-web-helm-button-group.d.ts +25 -0
  146. package/types/yukit-web-helm-button.d.ts +33 -0
  147. package/types/yukit-web-helm-calendar.d.ts +89 -0
  148. package/types/yukit-web-helm-card.d.ts +49 -0
  149. package/types/yukit-web-helm-carousel.d.ts +79 -0
  150. package/types/yukit-web-helm-checkbox.d.ts +60 -0
  151. package/types/yukit-web-helm-collapsible.d.ts +22 -0
  152. package/types/yukit-web-helm-combobox.d.ts +150 -0
  153. package/types/yukit-web-helm-command.d.ts +84 -0
  154. package/types/yukit-web-helm-context-menu.d.ts +29 -0
  155. package/types/yukit-web-helm-date-picker.d.ts +574 -0
  156. package/types/yukit-web-helm-dialog.d.ts +90 -0
  157. package/types/yukit-web-helm-drawer.d.ts +71 -0
  158. package/types/yukit-web-helm-dropdown-menu.d.ts +171 -0
  159. package/types/yukit-web-helm-empty.d.ts +49 -0
  160. package/types/yukit-web-helm-field.d.ts +102 -0
  161. package/types/yukit-web-helm-hover-card.d.ts +31 -0
  162. package/types/yukit-web-helm-input-group.d.ts +47 -0
  163. package/types/yukit-web-helm-input-otp.d.ts +40 -0
  164. package/types/yukit-web-helm-input.d.ts +13 -0
  165. package/types/yukit-web-helm-item.d.ts +96 -0
  166. package/types/yukit-web-helm-kbd.d.ts +17 -0
  167. package/types/yukit-web-helm-label.d.ts +12 -0
  168. package/types/yukit-web-helm-marker.d.ts +31 -0
  169. package/types/yukit-web-helm-menubar.d.ts +35 -0
  170. package/types/yukit-web-helm-message.d.ts +44 -0
  171. package/types/yukit-web-helm-native-select.d.ts +65 -0
  172. package/types/yukit-web-helm-navigation-menu.d.ts +49 -0
  173. package/types/yukit-web-helm-pagination.d.ts +187 -0
  174. package/types/yukit-web-helm-popover.d.ts +49 -0
  175. package/types/yukit-web-helm-progress.d.ts +22 -0
  176. package/types/yukit-web-helm-radio-group.d.ts +66 -0
  177. package/types/yukit-web-helm-resizable.d.ts +27 -0
  178. package/types/yukit-web-helm-scroll-area.d.ts +11 -0
  179. package/types/yukit-web-helm-select.d.ts +114 -0
  180. package/types/yukit-web-helm-separator.d.ts +13 -0
  181. package/types/yukit-web-helm-sheet.d.ts +75 -0
  182. package/types/yukit-web-helm-sidebar.d.ts +232 -0
  183. package/types/yukit-web-helm-skeleton.d.ts +11 -0
  184. package/types/yukit-web-helm-slider.d.ts +14 -0
  185. package/types/yukit-web-helm-sonner.d.ts +52 -0
  186. package/types/yukit-web-helm-spinner.d.ts +18 -0
  187. package/types/yukit-web-helm-switch.d.ts +54 -0
  188. package/types/yukit-web-helm-table.d.ts +82 -0
  189. package/types/yukit-web-helm-tabs.d.ts +66 -0
  190. package/types/yukit-web-helm-textarea.d.ts +13 -0
  191. package/types/yukit-web-helm-toggle-group.d.ts +34 -0
  192. package/types/yukit-web-helm-toggle.d.ts +22 -0
  193. package/types/yukit-web-helm-tooltip.d.ts +17 -0
  194. package/types/yukit-web-helm-typography.d.ts +89 -0
  195. package/types/yukit-web-helm-utils.d.ts +44 -0
  196. package/types/yukit-web.d.ts +2426 -0
@@ -0,0 +1,1517 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, inject, computed, input, ChangeDetectionStrategy, Component, forwardRef, viewChild, contentChild, booleanAttribute, linkedSignal, signal, output, ElementRef, effect, Directive, numberAttribute, untracked } from '@angular/core';
3
+ import { NgIcon, provideIcons } from '@ng-icons/core';
4
+ import { lucideX, lucideCalendar, lucideChevronDown } from '@ng-icons/lucide';
5
+ import { BrnDateInput, provideBrnDatePickerTrigger, BrnDatePickerTriggerToken, provideBrnDatePicker, injectBrnDatePicker } from '@spartan-ng/brain/date-picker';
6
+ import * as i1$1 from '@spartan-ng/brain/field';
7
+ import { BrnFieldControl, provideBrnLabelable, BrnFieldControlDescribedBy } from '@spartan-ng/brain/field';
8
+ import * as i1 from 'yukit-web/helm/input-group';
9
+ import { HlmInputGroup, HlmInputGroupImports } from 'yukit-web/helm/input-group';
10
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
11
+ import { BrnPopover } from '@spartan-ng/brain/popover';
12
+ import * as i3 from 'yukit-web/helm/calendar';
13
+ import { HlmCalendar, HlmCalendarMulti, HlmCalendarRange, HlmCalendarImports } from 'yukit-web/helm/calendar';
14
+ import * as i2 from 'yukit-web/helm/popover';
15
+ import { HlmPopoverImports, HlmPopoverTrigger } from 'yukit-web/helm/popover';
16
+ import { BrnOverlay } from '@spartan-ng/brain/overlay';
17
+ import * as i1$2 from 'yukit-web/helm/button';
18
+ import { HlmButtonImports } from 'yukit-web/helm/button';
19
+ import { hlm } from 'yukit-web/helm/utils';
20
+
21
+ function getDefaultConfig$3() {
22
+ return {
23
+ formatDates: (dates) => dates.map((date) => (date instanceof Date ? date.toDateString() : `${date}`)).join(', '),
24
+ formatInputDates: (dates) => dates
25
+ .map((date) => {
26
+ if (!(date instanceof Date))
27
+ return `${date}`;
28
+ const day = String(date.getDate()).padStart(2, '0');
29
+ const month = String(date.getMonth() + 1).padStart(2, '0');
30
+ const year = date.getFullYear();
31
+ return `${day}/${month}/${year}`;
32
+ })
33
+ .join(', '),
34
+ transformDates: (dates) => dates,
35
+ autoCloseOnMaxSelection: false,
36
+ parseDate: (value) => {
37
+ if (typeof value !== 'string')
38
+ return null;
39
+ const parts = value.split(',').map((v) => v.trim());
40
+ const result = [];
41
+ for (const part of parts) {
42
+ const match = part.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
43
+ if (!match)
44
+ return null;
45
+ const day = Number(match[1]);
46
+ const month = Number(match[2]);
47
+ const year = Number(match[3]);
48
+ if (month < 1 || month > 12)
49
+ return null;
50
+ if (day < 1 || day > 31)
51
+ return null;
52
+ const date = new Date(year, month - 1, day);
53
+ if (date.getFullYear() !== year || date.getMonth() !== month - 1 || date.getDate() !== day) {
54
+ return null;
55
+ }
56
+ result.push(date);
57
+ }
58
+ return result;
59
+ },
60
+ };
61
+ }
62
+ const HlmDatePickerMultiConfigToken = new InjectionToken('HlmDatePickerMultiConfig');
63
+ function provideHlmDatePickerMultiConfig(config) {
64
+ return { provide: HlmDatePickerMultiConfigToken, useValue: { ...getDefaultConfig$3(), ...config } };
65
+ }
66
+ function injectHlmDatePickerMultiConfig() {
67
+ const injectedConfig = inject(HlmDatePickerMultiConfigToken, { optional: true });
68
+ return injectedConfig ? injectedConfig : getDefaultConfig$3();
69
+ }
70
+
71
+ class HlmDateMultiInput extends BrnDateInput {
72
+ constructor() {
73
+ super(...arguments);
74
+ this._config = injectHlmDatePickerMultiConfig();
75
+ this._fieldControl = inject(BrnFieldControl, { optional: true });
76
+ this._invalid = this._fieldControl?.invalid;
77
+ this._spartanInvalid = computed(() => this.forceInvalid() || this._fieldControl?.spartanInvalid(), ...(ngDevMode ? [{ debugName: "_spartanInvalid" }] : /* istanbul ignore next */ []));
78
+ this._dirty = this._fieldControl?.dirty;
79
+ this._touched = this._fieldControl?.touched;
80
+ this._ariaInvalid = computed(() => (this._invalid?.() ? 'true' : null), ...(ngDevMode ? [{ debugName: "_ariaInvalid" }] : /* istanbul ignore next */ []));
81
+ /**
82
+ * Parses input text into dates. Return `null` for invalid input - the
83
+ * picker's dates are cleared while the text is preserved so the user can
84
+ * fix it.
85
+ *
86
+ * Defaults to `parseDate` from `HlmDatePickerMultiConfig`.
87
+ */
88
+ this.parseDate = input(this._config.parseDate, ...(ngDevMode ? [{ debugName: "parseDate" }] : /* istanbul ignore next */ []));
89
+ /**
90
+ * Formats the current dates into the input/edit format shown while the
91
+ * input is focused. On blur the picker's display format is restored.
92
+ *
93
+ * Defaults to `formatInputDates` from `HlmDatePickerMultiConfig`.
94
+ */
95
+ this.formatInputDates = input(this._config.formatInputDates, ...(ngDevMode ? [{ debugName: "formatInputDates" }] : /* istanbul ignore next */ []));
96
+ }
97
+ parseValue(value) {
98
+ return this.parseDate()(value);
99
+ }
100
+ formatInputValue(value) {
101
+ return this.formatInputDates()(value);
102
+ }
103
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmDateMultiInput, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
104
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: HlmDateMultiInput, isStandalone: true, selector: "hlm-date-multi-input", inputs: { parseDate: { classPropertyName: "parseDate", publicName: "parseDate", isSignal: true, isRequired: false, transformFunction: null }, formatInputDates: { classPropertyName: "formatInputDates", publicName: "formatInputDates", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideIcons({ lucideCalendar, lucideX }), provideBrnDatePickerTrigger(HlmDateMultiInput)], usesInheritance: true, hostDirectives: [{ directive: i1.HlmInputGroup }], ngImport: i0, template: `
105
+ <input
106
+ #input
107
+ hlmInputGroupInput
108
+ [value]="_inputValue()"
109
+ [id]="inputId()"
110
+ [placeholder]="placeholder()"
111
+ [disabled]="_disabled()"
112
+ [forceInvalid]="forceInvalid()"
113
+ [attr.aria-invalid]="_ariaInvalid()"
114
+ [attr.data-invalid]="_ariaInvalid()"
115
+ [attr.data-touched]="_touched?.() ? 'true' : null"
116
+ [attr.data-dirty]="_dirty?.() ? 'true' : null"
117
+ [attr.data-matches-spartan-invalid]="_spartanInvalid() ? 'true' : null"
118
+ (click)="_handleClick()"
119
+ (keydown.arrowDown)="_open()"
120
+ (keydown.enter)="_handleEnter($event)"
121
+ (input)="_handleInputChange($event)"
122
+ (focus)="_handleFocus()"
123
+ (blur)="_handleBlur()"
124
+ />
125
+ <hlm-input-group-addon align="inline-end">
126
+ @if (_showClearButton()) {
127
+ <button
128
+ hlmInputGroupButton
129
+ size="icon-xs"
130
+ variant="ghost"
131
+ [attr.aria-label]="clearAriaLabel()"
132
+ (click)="_clear()"
133
+ [disabled]="_disabled()"
134
+ >
135
+ <ng-icon name="lucideX" />
136
+ </button>
137
+ }
138
+ <button
139
+ hlmInputGroupButton
140
+ size="icon-xs"
141
+ [attr.aria-label]="calendarAriaLabel()"
142
+ (click)="_popover().open()"
143
+ [disabled]="_disabled()"
144
+ >
145
+ <ng-icon name="lucideCalendar" />
146
+ </button>
147
+ </hlm-input-group-addon>
148
+ `, isInline: true, dependencies: [{ kind: "directive", type: i1.HlmInputGroupAddon, selector: "[hlmInputGroupAddon],hlm-input-group-addon", inputs: ["align"] }, { kind: "directive", type: i1.HlmInputGroupButton, selector: "button[hlmInputGroupButton]", inputs: ["size", "type"] }, { kind: "directive", type: i1.HlmInputGroupInput, selector: "input[hlmInputGroupInput]" }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
149
+ }
150
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmDateMultiInput, decorators: [{
151
+ type: Component,
152
+ args: [{
153
+ selector: 'hlm-date-multi-input',
154
+ imports: [HlmInputGroupImports, NgIcon],
155
+ providers: [provideIcons({ lucideCalendar, lucideX }), provideBrnDatePickerTrigger(HlmDateMultiInput)],
156
+ changeDetection: ChangeDetectionStrategy.OnPush,
157
+ hostDirectives: [HlmInputGroup],
158
+ template: `
159
+ <input
160
+ #input
161
+ hlmInputGroupInput
162
+ [value]="_inputValue()"
163
+ [id]="inputId()"
164
+ [placeholder]="placeholder()"
165
+ [disabled]="_disabled()"
166
+ [forceInvalid]="forceInvalid()"
167
+ [attr.aria-invalid]="_ariaInvalid()"
168
+ [attr.data-invalid]="_ariaInvalid()"
169
+ [attr.data-touched]="_touched?.() ? 'true' : null"
170
+ [attr.data-dirty]="_dirty?.() ? 'true' : null"
171
+ [attr.data-matches-spartan-invalid]="_spartanInvalid() ? 'true' : null"
172
+ (click)="_handleClick()"
173
+ (keydown.arrowDown)="_open()"
174
+ (keydown.enter)="_handleEnter($event)"
175
+ (input)="_handleInputChange($event)"
176
+ (focus)="_handleFocus()"
177
+ (blur)="_handleBlur()"
178
+ />
179
+ <hlm-input-group-addon align="inline-end">
180
+ @if (_showClearButton()) {
181
+ <button
182
+ hlmInputGroupButton
183
+ size="icon-xs"
184
+ variant="ghost"
185
+ [attr.aria-label]="clearAriaLabel()"
186
+ (click)="_clear()"
187
+ [disabled]="_disabled()"
188
+ >
189
+ <ng-icon name="lucideX" />
190
+ </button>
191
+ }
192
+ <button
193
+ hlmInputGroupButton
194
+ size="icon-xs"
195
+ [attr.aria-label]="calendarAriaLabel()"
196
+ (click)="_popover().open()"
197
+ [disabled]="_disabled()"
198
+ >
199
+ <ng-icon name="lucideCalendar" />
200
+ </button>
201
+ </hlm-input-group-addon>
202
+ `,
203
+ }]
204
+ }], propDecorators: { parseDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "parseDate", required: false }] }], formatInputDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatInputDates", required: false }] }] } });
205
+
206
+ function getDefaultConfig$2() {
207
+ return {
208
+ formatDate: (date) => (date instanceof Date ? date.toDateString() : `${date}`),
209
+ formatInputDate: (date) => (date instanceof Date ? date.toDateString() : `${date}`),
210
+ transformDate: (date) => date,
211
+ parseDate: (value) => {
212
+ const date = new Date(value);
213
+ return isNaN(date.getTime()) ? null : date;
214
+ },
215
+ autoCloseOnSelect: false,
216
+ };
217
+ }
218
+ const HlmDatePickerConfigToken = new InjectionToken('HlmDatePickerConfig');
219
+ function provideHlmDatePickerConfig(config) {
220
+ return { provide: HlmDatePickerConfigToken, useValue: { ...getDefaultConfig$2(), ...config } };
221
+ }
222
+ function injectHlmDatePickerConfig() {
223
+ const injectedConfig = inject(HlmDatePickerConfigToken, { optional: true });
224
+ return injectedConfig ? injectedConfig : getDefaultConfig$2();
225
+ }
226
+
227
+ const HLM_DATE_PICKER_VALUE_ACCESSOR = {
228
+ provide: NG_VALUE_ACCESSOR,
229
+ useExisting: forwardRef(() => HlmDatePicker),
230
+ multi: true,
231
+ };
232
+ class HlmDatePicker {
233
+ constructor() {
234
+ this._config = injectHlmDatePickerConfig();
235
+ this.popover = viewChild.required(BrnPopover);
236
+ this._trigger = contentChild(BrnDatePickerTriggerToken, ...(ngDevMode ? [{ debugName: "_trigger" }] : /* istanbul ignore next */ []));
237
+ this.align = input('center', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
238
+ /** Show dropdowns to navigate between months or years. */
239
+ this.captionLayout = input('label', ...(ngDevMode ? [{ debugName: "captionLayout" }] : /* istanbul ignore next */ []));
240
+ /** The minimum date that can be selected. */
241
+ this.minDate = input(...(ngDevMode ? [undefined, { debugName: "minDate" }] : /* istanbul ignore next */ []));
242
+ /** The maximum date that can be selected. */
243
+ this.maxDate = input(...(ngDevMode ? [undefined, { debugName: "maxDate" }] : /* istanbul ignore next */ []));
244
+ /** Determine if the date picker is disabled. */
245
+ this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
246
+ /** The selected value. */
247
+ this.date = input(...(ngDevMode ? [undefined, { debugName: "date" }] : /* istanbul ignore next */ []));
248
+ /** The date the calendar focuses on first open when no date is selected. */
249
+ this.defaultFocusedDate = input(...(ngDevMode ? [undefined, { debugName: "defaultFocusedDate" }] : /* istanbul ignore next */ []));
250
+ this._mutableDate = linkedSignal(this.date, ...(ngDevMode ? [{ debugName: "_mutableDate" }] : /* istanbul ignore next */ []));
251
+ /** If true, the date picker will close when a date is selected. */
252
+ this.autoCloseOnSelect = input(this._config.autoCloseOnSelect, { ...(ngDevMode ? { debugName: "autoCloseOnSelect" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
253
+ /** Defines how the date should be displayed in the UI. */
254
+ this.formatDate = input(this._config.formatDate, ...(ngDevMode ? [{ debugName: "formatDate" }] : /* istanbul ignore next */ []));
255
+ /** Defines how the date should be transformed before saving to model/form. */
256
+ this.transformDate = input(this._config.transformDate, ...(ngDevMode ? [{ debugName: "transformDate" }] : /* istanbul ignore next */ []));
257
+ this._popoverState = signal(null, ...(ngDevMode ? [{ debugName: "_popoverState" }] : /* istanbul ignore next */ []));
258
+ this._disabled = linkedSignal(this.disabled, ...(ngDevMode ? [{ debugName: "_disabled" }] : /* istanbul ignore next */ []));
259
+ /** @internal The disabled state as a readonly signal */
260
+ this.disabledState = this._disabled.asReadonly();
261
+ this.formattedDate = computed(() => {
262
+ const date = this._mutableDate();
263
+ return date ? this.formatDate()(date) : undefined;
264
+ }, ...(ngDevMode ? [{ debugName: "formattedDate" }] : /* istanbul ignore next */ []));
265
+ this.dateChange = output();
266
+ this.labelableId = computed(() => this._trigger()?.triggerId(), ...(ngDevMode ? [{ debugName: "labelableId" }] : /* istanbul ignore next */ []));
267
+ this.hasDate = computed(() => !!this._mutableDate(), ...(ngDevMode ? [{ debugName: "hasDate" }] : /* istanbul ignore next */ []));
268
+ /** @internal The current raw value, used by inputs to reformat on focus. */
269
+ this.value = computed(() => this._mutableDate() ?? null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
270
+ }
271
+ _onStateChange(state) {
272
+ this._popoverState.set(state);
273
+ if (state === 'closed')
274
+ this._onTouched?.();
275
+ }
276
+ _handleChange(value) {
277
+ if (this._disabled())
278
+ return;
279
+ this.updateDate(value ?? null);
280
+ if (this.autoCloseOnSelect()) {
281
+ this._popoverState.set('closed');
282
+ }
283
+ }
284
+ /**
285
+ * Commit a date to the picker. Updates the internal model, notifies form
286
+ * controls, and emits `dateChange`. Unlike `_handleChange`, this does not
287
+ * close the popover - it's intended to be called from a text input that
288
+ * is parsing user-entered values while typing.
289
+ */
290
+ updateDate(value) {
291
+ if (this._disabled())
292
+ return;
293
+ const transformedDate = value != null ? this.transformDate()(value) : undefined;
294
+ this._mutableDate.set(transformedDate);
295
+ this._onChange?.(transformedDate ?? null);
296
+ this.dateChange.emit(transformedDate ?? null);
297
+ }
298
+ /** CONTROL VALUE ACCESSOR */
299
+ writeValue(value) {
300
+ this._mutableDate.set(value ? this.transformDate()(value) : undefined);
301
+ }
302
+ registerOnChange(fn) {
303
+ this._onChange = fn;
304
+ }
305
+ registerOnTouched(fn) {
306
+ this._onTouched = fn;
307
+ }
308
+ touched() {
309
+ this._onTouched?.();
310
+ }
311
+ setDisabledState(isDisabled) {
312
+ this._disabled.set(isDisabled);
313
+ }
314
+ open() {
315
+ this._popoverState.set('open');
316
+ }
317
+ close() {
318
+ this._popoverState.set('closed');
319
+ }
320
+ reset() {
321
+ this._mutableDate.set(undefined);
322
+ this._onChange?.(null);
323
+ this.dateChange.emit(null);
324
+ }
325
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmDatePicker, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
326
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.8", type: HlmDatePicker, isStandalone: true, selector: "hlm-date-picker", inputs: { align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, captionLayout: { classPropertyName: "captionLayout", publicName: "captionLayout", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: false, transformFunction: null }, defaultFocusedDate: { classPropertyName: "defaultFocusedDate", publicName: "defaultFocusedDate", isSignal: true, isRequired: false, transformFunction: null }, autoCloseOnSelect: { classPropertyName: "autoCloseOnSelect", publicName: "autoCloseOnSelect", isSignal: true, isRequired: false, transformFunction: null }, formatDate: { classPropertyName: "formatDate", publicName: "formatDate", isSignal: true, isRequired: false, transformFunction: null }, transformDate: { classPropertyName: "transformDate", publicName: "transformDate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateChange: "dateChange" }, host: { classAttribute: "block" }, providers: [HLM_DATE_PICKER_VALUE_ACCESSOR, provideBrnDatePicker(HlmDatePicker), provideBrnLabelable(HlmDatePicker)], queries: [{ propertyName: "_trigger", first: true, predicate: BrnDatePickerTriggerToken, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "popover", first: true, predicate: BrnPopover, descendants: true, isSignal: true }], hostDirectives: [{ directive: i1$1.BrnFieldControl }], ngImport: i0, template: `
327
+ <hlm-popover [align]="align()" sideOffset="5" [state]="_popoverState()" (stateChanged)="_onStateChange($event)">
328
+ <ng-content />
329
+
330
+ <hlm-popover-content class="w-fit p-0" *hlmPopoverPortal="let ctx">
331
+ <ng-content select="[hlmDatePickerHeader]" />
332
+ <hlm-calendar
333
+ class="rounded-none border-0"
334
+ [captionLayout]="captionLayout()"
335
+ [date]="_mutableDate()"
336
+ [defaultFocusedDate]="_mutableDate() ?? defaultFocusedDate()"
337
+ [min]="minDate()"
338
+ [max]="maxDate()"
339
+ [disabled]="_disabled()"
340
+ (dateChange)="_handleChange($event)"
341
+ />
342
+ <ng-content select="[hlmDatePickerFooter]" />
343
+ </hlm-popover-content>
344
+ </hlm-popover>
345
+ `, isInline: true, dependencies: [{ kind: "directive", type: i2.HlmPopover, selector: "[hlmPopover],hlm-popover" }, { kind: "directive", type: i2.HlmPopoverContent, selector: "[hlmPopoverContent],hlm-popover-content" }, { kind: "directive", type: i2.HlmPopoverPortal, selector: "[hlmPopoverPortal]" }, { kind: "component", type: HlmCalendar, selector: "hlm-calendar", inputs: ["captionLayout"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
346
+ }
347
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmDatePicker, decorators: [{
348
+ type: Component,
349
+ args: [{
350
+ selector: 'hlm-date-picker',
351
+ imports: [HlmPopoverImports, HlmCalendar],
352
+ providers: [HLM_DATE_PICKER_VALUE_ACCESSOR, provideBrnDatePicker(HlmDatePicker), provideBrnLabelable(HlmDatePicker)],
353
+ changeDetection: ChangeDetectionStrategy.OnPush,
354
+ hostDirectives: [BrnFieldControl],
355
+ host: { class: 'block' },
356
+ template: `
357
+ <hlm-popover [align]="align()" sideOffset="5" [state]="_popoverState()" (stateChanged)="_onStateChange($event)">
358
+ <ng-content />
359
+
360
+ <hlm-popover-content class="w-fit p-0" *hlmPopoverPortal="let ctx">
361
+ <ng-content select="[hlmDatePickerHeader]" />
362
+ <hlm-calendar
363
+ class="rounded-none border-0"
364
+ [captionLayout]="captionLayout()"
365
+ [date]="_mutableDate()"
366
+ [defaultFocusedDate]="_mutableDate() ?? defaultFocusedDate()"
367
+ [min]="minDate()"
368
+ [max]="maxDate()"
369
+ [disabled]="_disabled()"
370
+ (dateChange)="_handleChange($event)"
371
+ />
372
+ <ng-content select="[hlmDatePickerFooter]" />
373
+ </hlm-popover-content>
374
+ </hlm-popover>
375
+ `,
376
+ }]
377
+ }], propDecorators: { popover: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnPopover), { isSignal: true }] }], _trigger: [{ type: i0.ContentChild, args: [i0.forwardRef(() => BrnDatePickerTriggerToken), { isSignal: true }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], captionLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "captionLayout", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], date: [{ type: i0.Input, args: [{ isSignal: true, alias: "date", required: false }] }], defaultFocusedDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultFocusedDate", required: false }] }], autoCloseOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCloseOnSelect", required: false }] }], formatDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatDate", required: false }] }], transformDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformDate", required: false }] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }] } });
378
+
379
+ class HlmDatePickerAnchor {
380
+ constructor() {
381
+ this._host = inject(ElementRef, { host: true });
382
+ this._brnOverlay = inject(BrnOverlay, { optional: true });
383
+ this.hlmDatePickerAnchorForInput = input(undefined, { ...(ngDevMode ? { debugName: "hlmDatePickerAnchorForInput" } : /* istanbul ignore next */ {}), alias: 'hlmDatePickerAnchorFor' });
384
+ this.hlmDatePickerAnchorFor = linkedSignal(this.hlmDatePickerAnchorForInput, ...(ngDevMode ? [{ debugName: "hlmDatePickerAnchorFor" }] : /* istanbul ignore next */ []));
385
+ effect(() => {
386
+ this.hlmDatePickerAnchorFor()?.setOrigin(this._host.nativeElement);
387
+ });
388
+ this._brnOverlay?.setOrigin(this._host.nativeElement);
389
+ }
390
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmDatePickerAnchor, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
391
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.8", type: HlmDatePickerAnchor, isStandalone: true, selector: "[hlmDatePickerAnchor]", inputs: { hlmDatePickerAnchorForInput: { classPropertyName: "hlmDatePickerAnchorForInput", publicName: "hlmDatePickerAnchorFor", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
392
+ }
393
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmDatePickerAnchor, decorators: [{
394
+ type: Directive,
395
+ args: [{ selector: '[hlmDatePickerAnchor]' }]
396
+ }], ctorParameters: () => [], propDecorators: { hlmDatePickerAnchorForInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "hlmDatePickerAnchorFor", required: false }] }] } });
397
+
398
+ class HlmDatePickerInput extends BrnDateInput {
399
+ constructor() {
400
+ super(...arguments);
401
+ this._config = injectHlmDatePickerConfig();
402
+ this._fieldControl = inject(BrnFieldControl, { optional: true });
403
+ this._invalid = this._fieldControl?.invalid;
404
+ this._spartanInvalid = computed(() => this.forceInvalid() || this._fieldControl?.spartanInvalid(), ...(ngDevMode ? [{ debugName: "_spartanInvalid" }] : /* istanbul ignore next */ []));
405
+ this._dirty = this._fieldControl?.dirty;
406
+ this._touched = this._fieldControl?.touched;
407
+ this._ariaInvalid = computed(() => (this._invalid?.() ? 'true' : null), ...(ngDevMode ? [{ debugName: "_ariaInvalid" }] : /* istanbul ignore next */ []));
408
+ /**
409
+ * Parses input text into a date value. Return `null` for invalid
410
+ * input - the picker's date is cleared while the text is preserved so
411
+ * the user can fix it.
412
+ *
413
+ * Defaults to `parseDate` from `HlmDatePickerConfig`.
414
+ */
415
+ this.parseDate = input(this._config.parseDate, ...(ngDevMode ? [{ debugName: "parseDate" }] : /* istanbul ignore next */ []));
416
+ /**
417
+ * Formats the current date into the input/edit format shown while the
418
+ * input is focused. On blur the picker's display format is restored.
419
+ *
420
+ * Defaults to `formatInputDate` from `HlmDatePickerConfig`.
421
+ */
422
+ this.formatInputDate = input(this._config.formatInputDate, ...(ngDevMode ? [{ debugName: "formatInputDate" }] : /* istanbul ignore next */ []));
423
+ }
424
+ parseValue(value) {
425
+ return this.parseDate()(value);
426
+ }
427
+ formatInputValue(value) {
428
+ return this.formatInputDate()(value);
429
+ }
430
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmDatePickerInput, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
431
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: HlmDatePickerInput, isStandalone: true, selector: "hlm-date-picker-input", inputs: { parseDate: { classPropertyName: "parseDate", publicName: "parseDate", isSignal: true, isRequired: false, transformFunction: null }, formatInputDate: { classPropertyName: "formatInputDate", publicName: "formatInputDate", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideIcons({ lucideCalendar, lucideX }), provideBrnDatePickerTrigger(HlmDatePickerInput)], usesInheritance: true, hostDirectives: [{ directive: i1.HlmInputGroup }], ngImport: i0, template: `
432
+ <input
433
+ #input
434
+ hlmInputGroupInput
435
+ [value]="_inputValue()"
436
+ [id]="inputId()"
437
+ [placeholder]="placeholder()"
438
+ [disabled]="_disabled()"
439
+ [forceInvalid]="forceInvalid()"
440
+ [attr.aria-invalid]="_ariaInvalid()"
441
+ [attr.data-invalid]="_ariaInvalid()"
442
+ [attr.data-touched]="_touched?.() ? 'true' : null"
443
+ [attr.data-dirty]="_dirty?.() ? 'true' : null"
444
+ [attr.data-matches-spartan-invalid]="_spartanInvalid() ? 'true' : null"
445
+ (click)="_handleClick()"
446
+ (keydown.arrowDown)="_open()"
447
+ (keydown.enter)="_handleEnter($event)"
448
+ (input)="_handleInputChange($event)"
449
+ (focus)="_handleFocus()"
450
+ (blur)="_handleBlur()"
451
+ />
452
+ <hlm-input-group-addon align="inline-end">
453
+ @if (_showClearButton()) {
454
+ <button
455
+ hlmInputGroupButton
456
+ size="icon-xs"
457
+ variant="ghost"
458
+ [attr.aria-label]="clearAriaLabel()"
459
+ (click)="_clear()"
460
+ [disabled]="_disabled()"
461
+ >
462
+ <ng-icon name="lucideX" />
463
+ </button>
464
+ }
465
+ <button
466
+ hlmInputGroupButton
467
+ size="icon-xs"
468
+ [attr.aria-label]="calendarAriaLabel()"
469
+ (click)="_popover().open()"
470
+ [disabled]="_disabled()"
471
+ >
472
+ <ng-icon name="lucideCalendar" />
473
+ </button>
474
+ </hlm-input-group-addon>
475
+ `, isInline: true, dependencies: [{ kind: "directive", type: i1.HlmInputGroupAddon, selector: "[hlmInputGroupAddon],hlm-input-group-addon", inputs: ["align"] }, { kind: "directive", type: i1.HlmInputGroupButton, selector: "button[hlmInputGroupButton]", inputs: ["size", "type"] }, { kind: "directive", type: i1.HlmInputGroupInput, selector: "input[hlmInputGroupInput]" }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
476
+ }
477
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmDatePickerInput, decorators: [{
478
+ type: Component,
479
+ args: [{
480
+ selector: 'hlm-date-picker-input',
481
+ imports: [HlmInputGroupImports, NgIcon],
482
+ providers: [provideIcons({ lucideCalendar, lucideX }), provideBrnDatePickerTrigger(HlmDatePickerInput)],
483
+ changeDetection: ChangeDetectionStrategy.OnPush,
484
+ hostDirectives: [HlmInputGroup],
485
+ template: `
486
+ <input
487
+ #input
488
+ hlmInputGroupInput
489
+ [value]="_inputValue()"
490
+ [id]="inputId()"
491
+ [placeholder]="placeholder()"
492
+ [disabled]="_disabled()"
493
+ [forceInvalid]="forceInvalid()"
494
+ [attr.aria-invalid]="_ariaInvalid()"
495
+ [attr.data-invalid]="_ariaInvalid()"
496
+ [attr.data-touched]="_touched?.() ? 'true' : null"
497
+ [attr.data-dirty]="_dirty?.() ? 'true' : null"
498
+ [attr.data-matches-spartan-invalid]="_spartanInvalid() ? 'true' : null"
499
+ (click)="_handleClick()"
500
+ (keydown.arrowDown)="_open()"
501
+ (keydown.enter)="_handleEnter($event)"
502
+ (input)="_handleInputChange($event)"
503
+ (focus)="_handleFocus()"
504
+ (blur)="_handleBlur()"
505
+ />
506
+ <hlm-input-group-addon align="inline-end">
507
+ @if (_showClearButton()) {
508
+ <button
509
+ hlmInputGroupButton
510
+ size="icon-xs"
511
+ variant="ghost"
512
+ [attr.aria-label]="clearAriaLabel()"
513
+ (click)="_clear()"
514
+ [disabled]="_disabled()"
515
+ >
516
+ <ng-icon name="lucideX" />
517
+ </button>
518
+ }
519
+ <button
520
+ hlmInputGroupButton
521
+ size="icon-xs"
522
+ [attr.aria-label]="calendarAriaLabel()"
523
+ (click)="_popover().open()"
524
+ [disabled]="_disabled()"
525
+ >
526
+ <ng-icon name="lucideCalendar" />
527
+ </button>
528
+ </hlm-input-group-addon>
529
+ `,
530
+ }]
531
+ }], propDecorators: { parseDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "parseDate", required: false }] }], formatInputDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatInputDate", required: false }] }] } });
532
+
533
+ const HLM_DATE_PICKER_MUTLI_VALUE_ACCESSOR = {
534
+ provide: NG_VALUE_ACCESSOR,
535
+ useExisting: forwardRef(() => HlmDatePickerMulti),
536
+ multi: true,
537
+ };
538
+ class HlmDatePickerMulti {
539
+ constructor() {
540
+ this._config = injectHlmDatePickerMultiConfig();
541
+ this.popover = viewChild.required(BrnPopover);
542
+ this._trigger = contentChild(BrnDatePickerTriggerToken, ...(ngDevMode ? [{ debugName: "_trigger" }] : /* istanbul ignore next */ []));
543
+ this.align = input('center', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
544
+ /** Show dropdowns to navigate between months or years. */
545
+ this.captionLayout = input('label', ...(ngDevMode ? [{ debugName: "captionLayout" }] : /* istanbul ignore next */ []));
546
+ /** The minimum date that can be selected.*/
547
+ this.minDate = input(...(ngDevMode ? [undefined, { debugName: "minDate" }] : /* istanbul ignore next */ []));
548
+ /** The maximum date that can be selected. */
549
+ this.maxDate = input(...(ngDevMode ? [undefined, { debugName: "maxDate" }] : /* istanbul ignore next */ []));
550
+ /** The minimum selectable dates. */
551
+ this.minSelection = input(undefined, { ...(ngDevMode ? { debugName: "minSelection" } : /* istanbul ignore next */ {}), transform: numberAttribute });
552
+ /** The maximum selectable dates. */
553
+ this.maxSelection = input(undefined, { ...(ngDevMode ? { debugName: "maxSelection" } : /* istanbul ignore next */ {}), transform: numberAttribute });
554
+ /** Determine if the date picker is disabled. */
555
+ this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
556
+ /** The selected value. */
557
+ this.date = input(...(ngDevMode ? [undefined, { debugName: "date" }] : /* istanbul ignore next */ []));
558
+ this._mutableDate = linkedSignal(this.date, ...(ngDevMode ? [{ debugName: "_mutableDate" }] : /* istanbul ignore next */ []));
559
+ /** If true, the date picker will close when the max selection of dates is reached. */
560
+ this.autoCloseOnMaxSelection = input(this._config.autoCloseOnMaxSelection, { ...(ngDevMode ? { debugName: "autoCloseOnMaxSelection" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
561
+ /** Defines how the date should be displayed in the UI. */
562
+ this.formatDates = input(this._config.formatDates, ...(ngDevMode ? [{ debugName: "formatDates" }] : /* istanbul ignore next */ []));
563
+ /** Defines how the date should be transformed before saving to model/form. */
564
+ this.transformDates = input(this._config.transformDates, ...(ngDevMode ? [{ debugName: "transformDates" }] : /* istanbul ignore next */ []));
565
+ this._popoverState = signal(null, ...(ngDevMode ? [{ debugName: "_popoverState" }] : /* istanbul ignore next */ []));
566
+ this._disabled = linkedSignal(this.disabled, ...(ngDevMode ? [{ debugName: "_disabled" }] : /* istanbul ignore next */ []));
567
+ /** @internal The disabled state as a readonly signal */
568
+ this.disabledState = this._disabled.asReadonly();
569
+ this.formattedDate = computed(() => {
570
+ const dates = this._mutableDate();
571
+ return dates ? this.formatDates()(dates) : undefined;
572
+ }, ...(ngDevMode ? [{ debugName: "formattedDate" }] : /* istanbul ignore next */ []));
573
+ this.dateChange = output();
574
+ this.labelableId = computed(() => this._trigger()?.triggerId(), ...(ngDevMode ? [{ debugName: "labelableId" }] : /* istanbul ignore next */ []));
575
+ this.hasDate = computed(() => !!this._mutableDate()?.length, ...(ngDevMode ? [{ debugName: "hasDate" }] : /* istanbul ignore next */ []));
576
+ /** @internal The current raw value, used by inputs to reformat on focus. */
577
+ this.value = computed(() => this._mutableDate() ?? null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
578
+ }
579
+ _onStateChange(state) {
580
+ this._popoverState.set(state);
581
+ if (state === 'closed')
582
+ this._onTouched?.();
583
+ }
584
+ _handleChange(value) {
585
+ if (value === undefined)
586
+ return;
587
+ if (this._disabled())
588
+ return;
589
+ const transformedDate = value !== undefined ? this.transformDates()(value) : value;
590
+ this._mutableDate.set(transformedDate);
591
+ this._onChange?.(transformedDate);
592
+ this.dateChange.emit(transformedDate);
593
+ if (this.autoCloseOnMaxSelection() && this._mutableDate()?.length === this.maxSelection()) {
594
+ this._popoverState.set('closed');
595
+ }
596
+ }
597
+ /**
598
+ * Commit dates to the picker. Updates the internal model, notifies form
599
+ * controls, and emits `dateChange`. Intended to be called from a text input
600
+ * that parses user-entered values. Pass `null` to clear the selection.
601
+ */
602
+ updateDate(value) {
603
+ if (this._disabled())
604
+ return;
605
+ const transformedDate = value ? this.transformDates()(value) : undefined;
606
+ this._mutableDate.set(transformedDate);
607
+ this._onChange?.(transformedDate ?? []);
608
+ this.dateChange.emit(transformedDate ?? []);
609
+ }
610
+ touched() {
611
+ this._onTouched?.();
612
+ }
613
+ /** CONTROL VALUE ACCESSOR */
614
+ writeValue(value) {
615
+ this._mutableDate.set(value ? this.transformDates()(value) : undefined);
616
+ }
617
+ registerOnChange(fn) {
618
+ this._onChange = fn;
619
+ }
620
+ registerOnTouched(fn) {
621
+ this._onTouched = fn;
622
+ }
623
+ setDisabledState(isDisabled) {
624
+ this._disabled.set(isDisabled);
625
+ }
626
+ open() {
627
+ this._popoverState.set('open');
628
+ }
629
+ close() {
630
+ this._popoverState.set('closed');
631
+ }
632
+ reset() {
633
+ this._mutableDate.set(undefined);
634
+ this._onChange?.([]);
635
+ this.dateChange.emit([]);
636
+ }
637
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmDatePickerMulti, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
638
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.8", type: HlmDatePickerMulti, isStandalone: true, selector: "hlm-date-picker-multi", inputs: { align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, captionLayout: { classPropertyName: "captionLayout", publicName: "captionLayout", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, minSelection: { classPropertyName: "minSelection", publicName: "minSelection", isSignal: true, isRequired: false, transformFunction: null }, maxSelection: { classPropertyName: "maxSelection", publicName: "maxSelection", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: false, transformFunction: null }, autoCloseOnMaxSelection: { classPropertyName: "autoCloseOnMaxSelection", publicName: "autoCloseOnMaxSelection", isSignal: true, isRequired: false, transformFunction: null }, formatDates: { classPropertyName: "formatDates", publicName: "formatDates", isSignal: true, isRequired: false, transformFunction: null }, transformDates: { classPropertyName: "transformDates", publicName: "transformDates", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateChange: "dateChange" }, host: { classAttribute: "block" }, providers: [
639
+ HLM_DATE_PICKER_MUTLI_VALUE_ACCESSOR,
640
+ provideBrnDatePicker(HlmDatePickerMulti),
641
+ provideBrnLabelable(HlmDatePickerMulti),
642
+ ], queries: [{ propertyName: "_trigger", first: true, predicate: BrnDatePickerTriggerToken, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "popover", first: true, predicate: BrnPopover, descendants: true, isSignal: true }], hostDirectives: [{ directive: i1$1.BrnFieldControl }], ngImport: i0, template: `
643
+ <hlm-popover [align]="align()" sideOffset="5" [state]="_popoverState()" (stateChanged)="_onStateChange($event)">
644
+ <ng-content />
645
+
646
+ <hlm-popover-content class="w-fit p-0" *hlmPopoverPortal="let ctx">
647
+ <ng-content select="[hlmDatePickerHeader]" />
648
+ <hlm-calendar-multi
649
+ class="rounded-none border-0"
650
+ [date]="_mutableDate()"
651
+ [captionLayout]="captionLayout()"
652
+ [min]="minDate()"
653
+ [max]="maxDate()"
654
+ [minSelection]="minSelection()"
655
+ [maxSelection]="maxSelection()"
656
+ [disabled]="_disabled()"
657
+ (dateChange)="_handleChange($event)"
658
+ />
659
+ <ng-content select="[hlmDatePickerFooter]" />
660
+ </hlm-popover-content>
661
+ </hlm-popover>
662
+ `, isInline: true, dependencies: [{ kind: "directive", type: i2.HlmPopover, selector: "[hlmPopover],hlm-popover" }, { kind: "directive", type: i2.HlmPopoverContent, selector: "[hlmPopoverContent],hlm-popover-content" }, { kind: "directive", type: i2.HlmPopoverPortal, selector: "[hlmPopoverPortal]" }, { kind: "component", type: HlmCalendarMulti, selector: "hlm-calendar-multi", inputs: ["captionLayout"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
663
+ }
664
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmDatePickerMulti, decorators: [{
665
+ type: Component,
666
+ args: [{
667
+ selector: 'hlm-date-picker-multi',
668
+ imports: [HlmPopoverImports, HlmCalendarMulti],
669
+ providers: [
670
+ HLM_DATE_PICKER_MUTLI_VALUE_ACCESSOR,
671
+ provideBrnDatePicker(HlmDatePickerMulti),
672
+ provideBrnLabelable(HlmDatePickerMulti),
673
+ ],
674
+ changeDetection: ChangeDetectionStrategy.OnPush,
675
+ hostDirectives: [BrnFieldControl],
676
+ host: { class: 'block' },
677
+ template: `
678
+ <hlm-popover [align]="align()" sideOffset="5" [state]="_popoverState()" (stateChanged)="_onStateChange($event)">
679
+ <ng-content />
680
+
681
+ <hlm-popover-content class="w-fit p-0" *hlmPopoverPortal="let ctx">
682
+ <ng-content select="[hlmDatePickerHeader]" />
683
+ <hlm-calendar-multi
684
+ class="rounded-none border-0"
685
+ [date]="_mutableDate()"
686
+ [captionLayout]="captionLayout()"
687
+ [min]="minDate()"
688
+ [max]="maxDate()"
689
+ [minSelection]="minSelection()"
690
+ [maxSelection]="maxSelection()"
691
+ [disabled]="_disabled()"
692
+ (dateChange)="_handleChange($event)"
693
+ />
694
+ <ng-content select="[hlmDatePickerFooter]" />
695
+ </hlm-popover-content>
696
+ </hlm-popover>
697
+ `,
698
+ }]
699
+ }], propDecorators: { popover: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnPopover), { isSignal: true }] }], _trigger: [{ type: i0.ContentChild, args: [i0.forwardRef(() => BrnDatePickerTriggerToken), { isSignal: true }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], captionLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "captionLayout", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], minSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "minSelection", required: false }] }], maxSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSelection", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], date: [{ type: i0.Input, args: [{ isSignal: true, alias: "date", required: false }] }], autoCloseOnMaxSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCloseOnMaxSelection", required: false }] }], formatDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatDates", required: false }] }], transformDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformDates", required: false }] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }] } });
700
+
701
+ class HlmDatePickerTrigger {
702
+ constructor() {
703
+ this._fieldControl = inject(BrnFieldControl, { optional: true });
704
+ this._datePicker = injectBrnDatePicker();
705
+ this._invalid = this._fieldControl?.invalid;
706
+ this._spartanInvalid = computed(() => this.forceInvalid() || this._fieldControl?.spartanInvalid(), ...(ngDevMode ? [{ debugName: "_spartanInvalid" }] : /* istanbul ignore next */ []));
707
+ this._dirty = this._fieldControl?.dirty;
708
+ this._touched = this._fieldControl?.touched;
709
+ this._ariaInvalid = computed(() => (this._invalid?.() ? 'true' : null), ...(ngDevMode ? [{ debugName: "_ariaInvalid" }] : /* istanbul ignore next */ []));
710
+ this.userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
711
+ this._computedClass = computed(() => hlm('data-placeholder:text-muted-foreground justify-between', this.userClass()), ...(ngDevMode ? [{ debugName: "_computedClass" }] : /* istanbul ignore next */ []));
712
+ this._isPlaceholder = computed(() => !this._datePicker.hasDate(), ...(ngDevMode ? [{ debugName: "_isPlaceholder" }] : /* istanbul ignore next */ []));
713
+ /** The id of the button that opens the date picker. */
714
+ this.buttonId = input(`hlm-date-picker-${++HlmDatePickerTrigger._nextId}`, ...(ngDevMode ? [{ debugName: "buttonId" }] : /* istanbul ignore next */ []));
715
+ /** @internal The id of the button that opens the date picker, used for labeling. */
716
+ this.triggerId = this.buttonId;
717
+ /** Forces the invalid state visually, regardless of form control state. */
718
+ this.forceInvalid = input(false, { ...(ngDevMode ? { debugName: "forceInvalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
719
+ this.variant = input('outline', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
720
+ this.showTrigger = input(true, { ...(ngDevMode ? { debugName: "showTrigger" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
721
+ this._popover = this._datePicker.popover;
722
+ this._disabled = this._datePicker.disabledState;
723
+ this._formattedDate = this._datePicker.formattedDate;
724
+ }
725
+ static { this._nextId = 0; }
726
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmDatePickerTrigger, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
727
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: HlmDatePickerTrigger, isStandalone: true, selector: "hlm-date-picker-trigger", inputs: { userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, buttonId: { classPropertyName: "buttonId", publicName: "buttonId", isSignal: true, isRequired: false, transformFunction: null }, forceInvalid: { classPropertyName: "forceInvalid", publicName: "forceInvalid", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, showTrigger: { classPropertyName: "showTrigger", publicName: "showTrigger", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "data-slot": "date-picker-trigger" } }, providers: [provideIcons({ lucideChevronDown }), provideBrnDatePickerTrigger(HlmDatePickerTrigger)], ngImport: i0, template: `
728
+ <button
729
+ [id]="buttonId()"
730
+ type="button"
731
+ [class]="_computedClass()"
732
+ [disabled]="_disabled()"
733
+ [attr.aria-invalid]="_ariaInvalid()"
734
+ [attr.data-invalid]="_ariaInvalid()"
735
+ [attr.data-touched]="_touched?.() ? 'true' : null"
736
+ [attr.data-dirty]="_dirty?.() ? 'true' : null"
737
+ [attr.data-matches-spartan-invalid]="_spartanInvalid() ? 'true' : null"
738
+ hlmBtn
739
+ [variant]="variant()"
740
+ hlmPopoverTrigger
741
+ [hlmPopoverTriggerFor]="_popover()"
742
+ brnFieldControlDescribedBy
743
+ [attr.data-placeholder]="_isPlaceholder() ? '' : null"
744
+ >
745
+ <span class="truncate">
746
+ @if (_formattedDate(); as formattedDate) {
747
+ {{ formattedDate }}
748
+ } @else {
749
+ <ng-content />
750
+ }
751
+ </span>
752
+
753
+ @if (showTrigger()) {
754
+ <ng-icon name="lucideChevronDown" />
755
+ }
756
+ </button>
757
+ `, isInline: true, dependencies: [{ kind: "directive", type: i1$2.HlmButton, selector: "button[hlmBtn], a[hlmBtn]", inputs: ["variant", "size"], exportAs: ["hlmBtn"] }, { kind: "directive", type: HlmPopoverTrigger, selector: "button[hlmPopoverTrigger],button[hlmPopoverTriggerFor]" }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "directive", type: BrnFieldControlDescribedBy, selector: "[brnFieldControlDescribedBy]", inputs: ["aria-describedby"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
758
+ }
759
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmDatePickerTrigger, decorators: [{
760
+ type: Component,
761
+ args: [{
762
+ selector: 'hlm-date-picker-trigger',
763
+ imports: [HlmButtonImports, HlmPopoverTrigger, NgIcon, BrnFieldControlDescribedBy],
764
+ providers: [provideIcons({ lucideChevronDown }), provideBrnDatePickerTrigger(HlmDatePickerTrigger)],
765
+ changeDetection: ChangeDetectionStrategy.OnPush,
766
+ host: { 'data-slot': 'date-picker-trigger' },
767
+ template: `
768
+ <button
769
+ [id]="buttonId()"
770
+ type="button"
771
+ [class]="_computedClass()"
772
+ [disabled]="_disabled()"
773
+ [attr.aria-invalid]="_ariaInvalid()"
774
+ [attr.data-invalid]="_ariaInvalid()"
775
+ [attr.data-touched]="_touched?.() ? 'true' : null"
776
+ [attr.data-dirty]="_dirty?.() ? 'true' : null"
777
+ [attr.data-matches-spartan-invalid]="_spartanInvalid() ? 'true' : null"
778
+ hlmBtn
779
+ [variant]="variant()"
780
+ hlmPopoverTrigger
781
+ [hlmPopoverTriggerFor]="_popover()"
782
+ brnFieldControlDescribedBy
783
+ [attr.data-placeholder]="_isPlaceholder() ? '' : null"
784
+ >
785
+ <span class="truncate">
786
+ @if (_formattedDate(); as formattedDate) {
787
+ {{ formattedDate }}
788
+ } @else {
789
+ <ng-content />
790
+ }
791
+ </span>
792
+
793
+ @if (showTrigger()) {
794
+ <ng-icon name="lucideChevronDown" />
795
+ }
796
+ </button>
797
+ `,
798
+ }]
799
+ }], propDecorators: { userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], buttonId: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonId", required: false }] }], forceInvalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "forceInvalid", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], showTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTrigger", required: false }] }] } });
800
+
801
+ function getDefaultConfig$1() {
802
+ return {
803
+ formatDates: (dates) => dates
804
+ .filter(Boolean)
805
+ .map((date) => (date instanceof Date ? date.toDateString() : `${date}`))
806
+ .join(' - '),
807
+ formatInputDates: (dates) => dates
808
+ .filter(Boolean)
809
+ .map((date) => (date instanceof Date ? date.toDateString() : `${date}`))
810
+ .join(' - '),
811
+ transformDates: (dates) => dates,
812
+ autoCloseOnEndSelection: false,
813
+ parseDate: (value) => {
814
+ if (typeof value !== 'string')
815
+ return null;
816
+ const parts = value.split(' - ').map((part) => part.trim());
817
+ if (parts.length === 0 || parts.length > 2)
818
+ return null;
819
+ const start = new Date(parts[0]);
820
+ if (isNaN(start.getTime()))
821
+ return null;
822
+ const end = parts.length === 2 ? new Date(parts[1]) : start;
823
+ return [start, isNaN(end.getTime()) ? start : end];
824
+ },
825
+ };
826
+ }
827
+ const HlmDateRangePickerConfigToken = new InjectionToken('HlmDateRangePickerConfig');
828
+ function provideHlmDateRangePickerConfig(config) {
829
+ return { provide: HlmDateRangePickerConfigToken, useValue: { ...getDefaultConfig$1(), ...config } };
830
+ }
831
+ function injectHlmDateRangePickerConfig() {
832
+ const injectedConfig = inject(HlmDateRangePickerConfigToken, { optional: true });
833
+ return injectedConfig ? injectedConfig : getDefaultConfig$1();
834
+ }
835
+
836
+ class HlmDateRangeInput extends BrnDateInput {
837
+ constructor() {
838
+ super(...arguments);
839
+ this._config = injectHlmDateRangePickerConfig();
840
+ this._fieldControl = inject(BrnFieldControl, { optional: true });
841
+ this._invalid = this._fieldControl?.invalid;
842
+ this._spartanInvalid = computed(() => this.forceInvalid() || this._fieldControl?.spartanInvalid(), ...(ngDevMode ? [{ debugName: "_spartanInvalid" }] : /* istanbul ignore next */ []));
843
+ this._dirty = this._fieldControl?.dirty;
844
+ this._touched = this._fieldControl?.touched;
845
+ this._ariaInvalid = computed(() => (this._invalid?.() ? 'true' : null), ...(ngDevMode ? [{ debugName: "_ariaInvalid" }] : /* istanbul ignore next */ []));
846
+ /**
847
+ * Parses input text into a date range. Return `null` for invalid
848
+ * input - the picker's range is cleared while the text is preserved so
849
+ * the user can fix it.
850
+ *
851
+ * Defaults to `parseDate` from `HlmDateRangePickerConfig`.
852
+ */
853
+ this.parseDate = input(this._config.parseDate, ...(ngDevMode ? [{ debugName: "parseDate" }] : /* istanbul ignore next */ []));
854
+ /**
855
+ * Formats the current range into the input/edit format shown while the
856
+ * input is focused. On blur the picker's display format is restored.
857
+ *
858
+ * Defaults to `formatInputDates` from `HlmDateRangePickerConfig`.
859
+ */
860
+ this.formatInputDates = input(this._config.formatInputDates, ...(ngDevMode ? [{ debugName: "formatInputDates" }] : /* istanbul ignore next */ []));
861
+ }
862
+ parseValue(value) {
863
+ return this.parseDate()(value);
864
+ }
865
+ formatInputValue(value) {
866
+ return this.formatInputDates()(value);
867
+ }
868
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmDateRangeInput, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
869
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: HlmDateRangeInput, isStandalone: true, selector: "hlm-date-range-input", inputs: { parseDate: { classPropertyName: "parseDate", publicName: "parseDate", isSignal: true, isRequired: false, transformFunction: null }, formatInputDates: { classPropertyName: "formatInputDates", publicName: "formatInputDates", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideIcons({ lucideCalendar, lucideX }), provideBrnDatePickerTrigger(HlmDateRangeInput)], usesInheritance: true, hostDirectives: [{ directive: i1.HlmInputGroup }], ngImport: i0, template: `
870
+ <input
871
+ #input
872
+ hlmInputGroupInput
873
+ [value]="_inputValue()"
874
+ [id]="inputId()"
875
+ [placeholder]="placeholder()"
876
+ [disabled]="_disabled()"
877
+ [forceInvalid]="forceInvalid()"
878
+ [attr.aria-invalid]="_ariaInvalid()"
879
+ [attr.data-invalid]="_ariaInvalid()"
880
+ [attr.data-touched]="_touched?.() ? 'true' : null"
881
+ [attr.data-dirty]="_dirty?.() ? 'true' : null"
882
+ [attr.data-matches-spartan-invalid]="_spartanInvalid() ? 'true' : null"
883
+ (click)="_handleClick()"
884
+ (keydown.arrowDown)="_open()"
885
+ (keydown.enter)="_handleEnter($event)"
886
+ (input)="_handleInputChange($event)"
887
+ (focus)="_handleFocus()"
888
+ (blur)="_handleBlur()"
889
+ />
890
+ <hlm-input-group-addon align="inline-end">
891
+ @if (_showClearButton()) {
892
+ <button
893
+ hlmInputGroupButton
894
+ size="icon-xs"
895
+ variant="ghost"
896
+ [attr.aria-label]="clearAriaLabel()"
897
+ (click)="_clear()"
898
+ [disabled]="_disabled()"
899
+ >
900
+ <ng-icon name="lucideX" />
901
+ </button>
902
+ }
903
+ <button
904
+ hlmInputGroupButton
905
+ size="icon-xs"
906
+ [attr.aria-label]="calendarAriaLabel()"
907
+ (click)="_popover().open()"
908
+ [disabled]="_disabled()"
909
+ >
910
+ <ng-icon name="lucideCalendar" />
911
+ </button>
912
+ </hlm-input-group-addon>
913
+ `, isInline: true, dependencies: [{ kind: "directive", type: i1.HlmInputGroupAddon, selector: "[hlmInputGroupAddon],hlm-input-group-addon", inputs: ["align"] }, { kind: "directive", type: i1.HlmInputGroupButton, selector: "button[hlmInputGroupButton]", inputs: ["size", "type"] }, { kind: "directive", type: i1.HlmInputGroupInput, selector: "input[hlmInputGroupInput]" }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
914
+ }
915
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmDateRangeInput, decorators: [{
916
+ type: Component,
917
+ args: [{
918
+ selector: 'hlm-date-range-input',
919
+ imports: [HlmInputGroupImports, NgIcon],
920
+ providers: [provideIcons({ lucideCalendar, lucideX }), provideBrnDatePickerTrigger(HlmDateRangeInput)],
921
+ changeDetection: ChangeDetectionStrategy.OnPush,
922
+ hostDirectives: [HlmInputGroup],
923
+ template: `
924
+ <input
925
+ #input
926
+ hlmInputGroupInput
927
+ [value]="_inputValue()"
928
+ [id]="inputId()"
929
+ [placeholder]="placeholder()"
930
+ [disabled]="_disabled()"
931
+ [forceInvalid]="forceInvalid()"
932
+ [attr.aria-invalid]="_ariaInvalid()"
933
+ [attr.data-invalid]="_ariaInvalid()"
934
+ [attr.data-touched]="_touched?.() ? 'true' : null"
935
+ [attr.data-dirty]="_dirty?.() ? 'true' : null"
936
+ [attr.data-matches-spartan-invalid]="_spartanInvalid() ? 'true' : null"
937
+ (click)="_handleClick()"
938
+ (keydown.arrowDown)="_open()"
939
+ (keydown.enter)="_handleEnter($event)"
940
+ (input)="_handleInputChange($event)"
941
+ (focus)="_handleFocus()"
942
+ (blur)="_handleBlur()"
943
+ />
944
+ <hlm-input-group-addon align="inline-end">
945
+ @if (_showClearButton()) {
946
+ <button
947
+ hlmInputGroupButton
948
+ size="icon-xs"
949
+ variant="ghost"
950
+ [attr.aria-label]="clearAriaLabel()"
951
+ (click)="_clear()"
952
+ [disabled]="_disabled()"
953
+ >
954
+ <ng-icon name="lucideX" />
955
+ </button>
956
+ }
957
+ <button
958
+ hlmInputGroupButton
959
+ size="icon-xs"
960
+ [attr.aria-label]="calendarAriaLabel()"
961
+ (click)="_popover().open()"
962
+ [disabled]="_disabled()"
963
+ >
964
+ <ng-icon name="lucideCalendar" />
965
+ </button>
966
+ </hlm-input-group-addon>
967
+ `,
968
+ }]
969
+ }], propDecorators: { parseDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "parseDate", required: false }] }], formatInputDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatInputDates", required: false }] }] } });
970
+
971
+ const HLM_DATE_RANGE_PICKER_VALUE_ACCESSOR = {
972
+ provide: NG_VALUE_ACCESSOR,
973
+ useExisting: forwardRef(() => HlmDateRangePicker),
974
+ multi: true,
975
+ };
976
+ class HlmDateRangePicker {
977
+ constructor() {
978
+ this._config = injectHlmDateRangePickerConfig();
979
+ this.popover = viewChild.required(BrnPopover);
980
+ this._trigger = contentChild(BrnDatePickerTriggerToken, ...(ngDevMode ? [{ debugName: "_trigger" }] : /* istanbul ignore next */ []));
981
+ this.align = input('center', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
982
+ /** Show dropdowns to navigate between months or years. */
983
+ this.captionLayout = input('label', ...(ngDevMode ? [{ debugName: "captionLayout" }] : /* istanbul ignore next */ []));
984
+ /** The minimum date that can be selected.*/
985
+ this.minDate = input(...(ngDevMode ? [undefined, { debugName: "minDate" }] : /* istanbul ignore next */ []));
986
+ /** The maximum date that can be selected. */
987
+ this.maxDate = input(...(ngDevMode ? [undefined, { debugName: "maxDate" }] : /* istanbul ignore next */ []));
988
+ /** Determine if the date picker is disabled. */
989
+ this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
990
+ /** The selected value. */
991
+ this.date = input(...(ngDevMode ? [undefined, { debugName: "date" }] : /* istanbul ignore next */ []));
992
+ this._mutableDate = linkedSignal(this.date, ...(ngDevMode ? [{ debugName: "_mutableDate" }] : /* istanbul ignore next */ []));
993
+ this._start = linkedSignal(() => this._mutableDate()?.[0], ...(ngDevMode ? [{ debugName: "_start" }] : /* istanbul ignore next */ []));
994
+ this._end = linkedSignal(() => this._mutableDate()?.[1], ...(ngDevMode ? [{ debugName: "_end" }] : /* istanbul ignore next */ []));
995
+ /** If true, the date picker will close when the end date is selected */
996
+ this.autoCloseOnEndSelection = input(this._config.autoCloseOnEndSelection, { ...(ngDevMode ? { debugName: "autoCloseOnEndSelection" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
997
+ /** Defines how the date should be displayed in the UI. */
998
+ this.formatDates = input(this._config.formatDates, ...(ngDevMode ? [{ debugName: "formatDates" }] : /* istanbul ignore next */ []));
999
+ /** Defines how the date should be transformed before saving to model/form. */
1000
+ this.transformDates = input(this._config.transformDates, ...(ngDevMode ? [{ debugName: "transformDates" }] : /* istanbul ignore next */ []));
1001
+ this._popoverState = signal(null, ...(ngDevMode ? [{ debugName: "_popoverState" }] : /* istanbul ignore next */ []));
1002
+ this._disabled = linkedSignal(this.disabled, ...(ngDevMode ? [{ debugName: "_disabled" }] : /* istanbul ignore next */ []));
1003
+ /** @internal The disabled state as a readonly signal */
1004
+ this.disabledState = this._disabled.asReadonly();
1005
+ this.formattedDate = computed(() => {
1006
+ const start = this._start();
1007
+ const end = this._end();
1008
+ return start || end ? this.formatDates()([start ?? null, end ?? null]) : undefined;
1009
+ }, ...(ngDevMode ? [{ debugName: "formattedDate" }] : /* istanbul ignore next */ []));
1010
+ this.dateChange = output();
1011
+ this.labelableId = computed(() => this._trigger()?.triggerId(), ...(ngDevMode ? [{ debugName: "labelableId" }] : /* istanbul ignore next */ []));
1012
+ this.hasDate = computed(() => !!this._start() || !!this._end(), ...(ngDevMode ? [{ debugName: "hasDate" }] : /* istanbul ignore next */ []));
1013
+ /** @internal The current raw value, used by inputs to reformat on focus. */
1014
+ this.value = computed(() => this._mutableDate() ?? null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
1015
+ }
1016
+ _onStateChange(state) {
1017
+ this._popoverState.set(state);
1018
+ if (state === 'closed') {
1019
+ this._onClose();
1020
+ this._onTouched?.();
1021
+ }
1022
+ }
1023
+ _handleStartDayChange(value) {
1024
+ this._start.set(value);
1025
+ }
1026
+ _handleEndDateChange(value) {
1027
+ this._end.set(value);
1028
+ if (this._disabled())
1029
+ return;
1030
+ const start = this._start();
1031
+ if (start && value) {
1032
+ const transformedDates = this.transformDates()([start, value]);
1033
+ this._mutableDate.set(transformedDates);
1034
+ this.dateChange.emit(transformedDates);
1035
+ this._onChange?.(transformedDates);
1036
+ if (this.autoCloseOnEndSelection()) {
1037
+ this._popoverState.set('closed');
1038
+ }
1039
+ }
1040
+ }
1041
+ /**
1042
+ * Commit a range to the picker. Updates the internal model, notifies form
1043
+ * controls, and emits `dateChange`. Intended to be called from a text input
1044
+ * that parses user-entered values. Pass `null` to clear the range.
1045
+ */
1046
+ updateDate(value) {
1047
+ if (this._disabled())
1048
+ return;
1049
+ if (!value) {
1050
+ this._mutableDate.set(undefined);
1051
+ this._start.set(undefined);
1052
+ this._end.set(undefined);
1053
+ this._onChange?.(null);
1054
+ this.dateChange.emit(null);
1055
+ return;
1056
+ }
1057
+ const transformedDates = this.transformDates()(value);
1058
+ this._mutableDate.set(transformedDates);
1059
+ this._start.set(transformedDates[0]);
1060
+ this._end.set(transformedDates[1]);
1061
+ this._onChange?.(transformedDates);
1062
+ this.dateChange.emit(transformedDates);
1063
+ }
1064
+ touched() {
1065
+ this._onTouched?.();
1066
+ }
1067
+ /** CONTROL VALUE ACCESSOR */
1068
+ writeValue(value) {
1069
+ untracked(() => {
1070
+ if (!value) {
1071
+ this._mutableDate.set(undefined);
1072
+ }
1073
+ else {
1074
+ this._mutableDate.set(this.transformDates()(value));
1075
+ }
1076
+ });
1077
+ }
1078
+ registerOnChange(fn) {
1079
+ this._onChange = fn;
1080
+ }
1081
+ registerOnTouched(fn) {
1082
+ this._onTouched = fn;
1083
+ }
1084
+ setDisabledState(isDisabled) {
1085
+ this._disabled.set(isDisabled);
1086
+ }
1087
+ open() {
1088
+ this._popoverState.set('open');
1089
+ }
1090
+ close() {
1091
+ this._popoverState.set('closed');
1092
+ }
1093
+ reset() {
1094
+ this._mutableDate.set(undefined);
1095
+ this._start.set(undefined);
1096
+ this._end.set(undefined);
1097
+ this._onChange?.(null);
1098
+ this.dateChange.emit(null);
1099
+ }
1100
+ _onClose() {
1101
+ const dates = this._mutableDate();
1102
+ if (this._start() && !this._end() && dates) {
1103
+ this._start.set(dates[0]);
1104
+ this._end.set(dates[1]);
1105
+ }
1106
+ }
1107
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmDateRangePicker, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1108
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.8", type: HlmDateRangePicker, isStandalone: true, selector: "hlm-date-range-picker", inputs: { align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, captionLayout: { classPropertyName: "captionLayout", publicName: "captionLayout", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: false, transformFunction: null }, autoCloseOnEndSelection: { classPropertyName: "autoCloseOnEndSelection", publicName: "autoCloseOnEndSelection", isSignal: true, isRequired: false, transformFunction: null }, formatDates: { classPropertyName: "formatDates", publicName: "formatDates", isSignal: true, isRequired: false, transformFunction: null }, transformDates: { classPropertyName: "transformDates", publicName: "transformDates", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateChange: "dateChange" }, host: { classAttribute: "block" }, providers: [
1109
+ HLM_DATE_RANGE_PICKER_VALUE_ACCESSOR,
1110
+ provideBrnDatePicker(HlmDateRangePicker),
1111
+ provideBrnLabelable(HlmDateRangePicker),
1112
+ ], queries: [{ propertyName: "_trigger", first: true, predicate: BrnDatePickerTriggerToken, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "popover", first: true, predicate: BrnPopover, descendants: true, isSignal: true }], hostDirectives: [{ directive: i1$1.BrnFieldControl }], ngImport: i0, template: `
1113
+ <hlm-popover [align]="align()" sideOffset="5" [state]="_popoverState()" (stateChanged)="_onStateChange($event)">
1114
+ <ng-content />
1115
+
1116
+ <hlm-popover-content class="w-fit p-0" *hlmPopoverPortal="let ctx">
1117
+ <ng-content select="[hlmDatePickerHeader]" />
1118
+ <hlm-calendar-range
1119
+ class="rounded-none border-0"
1120
+ [startDate]="_start()"
1121
+ [captionLayout]="captionLayout()"
1122
+ [endDate]="_end()"
1123
+ [min]="minDate()"
1124
+ [max]="maxDate()"
1125
+ [disabled]="_disabled()"
1126
+ (startDateChange)="_handleStartDayChange($event)"
1127
+ (endDateChange)="_handleEndDateChange($event)"
1128
+ />
1129
+ <ng-content select="[hlmDatePickerFooter]" />
1130
+ </hlm-popover-content>
1131
+ </hlm-popover>
1132
+ `, isInline: true, dependencies: [{ kind: "directive", type: i2.HlmPopover, selector: "[hlmPopover],hlm-popover" }, { kind: "directive", type: i2.HlmPopoverContent, selector: "[hlmPopoverContent],hlm-popover-content" }, { kind: "directive", type: i2.HlmPopoverPortal, selector: "[hlmPopoverPortal]" }, { kind: "component", type: HlmCalendarRange, selector: "hlm-calendar-range", inputs: ["captionLayout"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1133
+ }
1134
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmDateRangePicker, decorators: [{
1135
+ type: Component,
1136
+ args: [{
1137
+ selector: 'hlm-date-range-picker',
1138
+ imports: [HlmPopoverImports, HlmCalendarRange],
1139
+ providers: [
1140
+ HLM_DATE_RANGE_PICKER_VALUE_ACCESSOR,
1141
+ provideBrnDatePicker(HlmDateRangePicker),
1142
+ provideBrnLabelable(HlmDateRangePicker),
1143
+ ],
1144
+ changeDetection: ChangeDetectionStrategy.OnPush,
1145
+ hostDirectives: [BrnFieldControl],
1146
+ host: { class: 'block' },
1147
+ template: `
1148
+ <hlm-popover [align]="align()" sideOffset="5" [state]="_popoverState()" (stateChanged)="_onStateChange($event)">
1149
+ <ng-content />
1150
+
1151
+ <hlm-popover-content class="w-fit p-0" *hlmPopoverPortal="let ctx">
1152
+ <ng-content select="[hlmDatePickerHeader]" />
1153
+ <hlm-calendar-range
1154
+ class="rounded-none border-0"
1155
+ [startDate]="_start()"
1156
+ [captionLayout]="captionLayout()"
1157
+ [endDate]="_end()"
1158
+ [min]="minDate()"
1159
+ [max]="maxDate()"
1160
+ [disabled]="_disabled()"
1161
+ (startDateChange)="_handleStartDayChange($event)"
1162
+ (endDateChange)="_handleEndDateChange($event)"
1163
+ />
1164
+ <ng-content select="[hlmDatePickerFooter]" />
1165
+ </hlm-popover-content>
1166
+ </hlm-popover>
1167
+ `,
1168
+ }]
1169
+ }], propDecorators: { popover: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnPopover), { isSignal: true }] }], _trigger: [{ type: i0.ContentChild, args: [i0.forwardRef(() => BrnDatePickerTriggerToken), { isSignal: true }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], captionLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "captionLayout", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], date: [{ type: i0.Input, args: [{ isSignal: true, alias: "date", required: false }] }], autoCloseOnEndSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCloseOnEndSelection", required: false }] }], formatDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatDates", required: false }] }], transformDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformDates", required: false }] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }] } });
1170
+
1171
+ const mmYYYY = (date) => {
1172
+ if (!(date instanceof Date))
1173
+ return `${date}`;
1174
+ const month = String(date.getMonth() + 1).padStart(2, '0');
1175
+ const year = date.getFullYear();
1176
+ return `${month}/${year}`;
1177
+ };
1178
+ function getDefaultConfig() {
1179
+ return {
1180
+ formatDate: mmYYYY,
1181
+ formatInputDate: mmYYYY,
1182
+ transformDate: (date) => date,
1183
+ parseDate: (value) => {
1184
+ if (typeof value !== 'string')
1185
+ return null;
1186
+ const match = value.match(/^(\d{2})\/(\d{4})$/);
1187
+ if (!match)
1188
+ return null;
1189
+ const month = Number(match[1]);
1190
+ const year = Number(match[2]);
1191
+ if (month < 1 || month > 12)
1192
+ return null;
1193
+ const date = new Date(year, month - 1, 1);
1194
+ return date;
1195
+ },
1196
+ autoCloseOnSelect: false,
1197
+ };
1198
+ }
1199
+ const HlmMonthYearPickerConfigToken = new InjectionToken('HlmMonthYearPickerConfig');
1200
+ function provideHlmMonthYearPickerConfig(config) {
1201
+ return { provide: HlmMonthYearPickerConfigToken, useValue: { ...getDefaultConfig(), ...config } };
1202
+ }
1203
+ function injectHlmMonthYearPickerConfig() {
1204
+ const injectedConfig = inject(HlmMonthYearPickerConfigToken, { optional: true });
1205
+ return injectedConfig ? injectedConfig : getDefaultConfig();
1206
+ }
1207
+
1208
+ class HlmMonthYearInput extends BrnDateInput {
1209
+ constructor() {
1210
+ super(...arguments);
1211
+ this._config = injectHlmMonthYearPickerConfig();
1212
+ this._fieldControl = inject(BrnFieldControl, { optional: true });
1213
+ this._invalid = this._fieldControl?.invalid;
1214
+ this._spartanInvalid = computed(() => this.forceInvalid() || this._fieldControl?.spartanInvalid(), ...(ngDevMode ? [{ debugName: "_spartanInvalid" }] : /* istanbul ignore next */ []));
1215
+ this._dirty = this._fieldControl?.dirty;
1216
+ this._touched = this._fieldControl?.touched;
1217
+ this._ariaInvalid = computed(() => (this._invalid?.() ? 'true' : null), ...(ngDevMode ? [{ debugName: "_ariaInvalid" }] : /* istanbul ignore next */ []));
1218
+ /**
1219
+ * Parses input text into a date value. Return `null` for invalid
1220
+ * input - the picker's date is cleared while the text is preserved so
1221
+ * the user can fix it.
1222
+ *
1223
+ * Defaults to `parseDate` from `HlmMonthYearPickerConfig`.
1224
+ */
1225
+ this.parseDate = input(this._config.parseDate, ...(ngDevMode ? [{ debugName: "parseDate" }] : /* istanbul ignore next */ []));
1226
+ /**
1227
+ * Formats the current date into the input/edit format shown while the
1228
+ * input is focused. On blur the picker's display format is restored.
1229
+ *
1230
+ * Defaults to `formatInputDate` from `HlmMonthYearPickerConfig`.
1231
+ */
1232
+ this.formatInputDate = input(this._config.formatInputDate, ...(ngDevMode ? [{ debugName: "formatInputDate" }] : /* istanbul ignore next */ []));
1233
+ }
1234
+ parseValue(value) {
1235
+ return this.parseDate()(value);
1236
+ }
1237
+ formatInputValue(value) {
1238
+ return this.formatInputDate()(value);
1239
+ }
1240
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmMonthYearInput, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1241
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: HlmMonthYearInput, isStandalone: true, selector: "hlm-month-year-input", inputs: { parseDate: { classPropertyName: "parseDate", publicName: "parseDate", isSignal: true, isRequired: false, transformFunction: null }, formatInputDate: { classPropertyName: "formatInputDate", publicName: "formatInputDate", isSignal: true, isRequired: false, transformFunction: null } }, providers: [provideIcons({ lucideCalendar, lucideX }), provideBrnDatePickerTrigger(HlmMonthYearInput)], usesInheritance: true, hostDirectives: [{ directive: i1.HlmInputGroup }], ngImport: i0, template: `
1242
+ <input
1243
+ #input
1244
+ hlmInputGroupInput
1245
+ [value]="_inputValue()"
1246
+ [id]="inputId()"
1247
+ [placeholder]="placeholder()"
1248
+ [disabled]="_disabled()"
1249
+ [forceInvalid]="forceInvalid()"
1250
+ [attr.aria-invalid]="_ariaInvalid()"
1251
+ [attr.data-invalid]="_ariaInvalid()"
1252
+ [attr.data-touched]="_touched?.() ? 'true' : null"
1253
+ [attr.data-dirty]="_dirty?.() ? 'true' : null"
1254
+ [attr.data-matches-spartan-invalid]="_spartanInvalid() ? 'true' : null"
1255
+ (click)="_handleClick()"
1256
+ (keydown.arrowDown)="_open()"
1257
+ (keydown.enter)="_handleEnter($event)"
1258
+ (input)="_handleInputChange($event)"
1259
+ (focus)="_handleFocus()"
1260
+ (blur)="_handleBlur()"
1261
+ />
1262
+ <hlm-input-group-addon align="inline-end">
1263
+ @if (_showClearButton()) {
1264
+ <button
1265
+ hlmInputGroupButton
1266
+ size="icon-xs"
1267
+ variant="ghost"
1268
+ [attr.aria-label]="clearAriaLabel()"
1269
+ (click)="_clear()"
1270
+ [disabled]="_disabled()"
1271
+ >
1272
+ <ng-icon name="lucideX" />
1273
+ </button>
1274
+ }
1275
+ <button
1276
+ hlmInputGroupButton
1277
+ size="icon-xs"
1278
+ [attr.aria-label]="calendarAriaLabel()"
1279
+ (click)="_popover().open()"
1280
+ [disabled]="_disabled()"
1281
+ >
1282
+ <ng-icon name="lucideCalendar" />
1283
+ </button>
1284
+ </hlm-input-group-addon>
1285
+ `, isInline: true, dependencies: [{ kind: "directive", type: i1.HlmInputGroupAddon, selector: "[hlmInputGroupAddon],hlm-input-group-addon", inputs: ["align"] }, { kind: "directive", type: i1.HlmInputGroupButton, selector: "button[hlmInputGroupButton]", inputs: ["size", "type"] }, { kind: "directive", type: i1.HlmInputGroupInput, selector: "input[hlmInputGroupInput]" }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1286
+ }
1287
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmMonthYearInput, decorators: [{
1288
+ type: Component,
1289
+ args: [{
1290
+ selector: 'hlm-month-year-input',
1291
+ imports: [HlmInputGroupImports, NgIcon],
1292
+ providers: [provideIcons({ lucideCalendar, lucideX }), provideBrnDatePickerTrigger(HlmMonthYearInput)],
1293
+ changeDetection: ChangeDetectionStrategy.OnPush,
1294
+ hostDirectives: [HlmInputGroup],
1295
+ template: `
1296
+ <input
1297
+ #input
1298
+ hlmInputGroupInput
1299
+ [value]="_inputValue()"
1300
+ [id]="inputId()"
1301
+ [placeholder]="placeholder()"
1302
+ [disabled]="_disabled()"
1303
+ [forceInvalid]="forceInvalid()"
1304
+ [attr.aria-invalid]="_ariaInvalid()"
1305
+ [attr.data-invalid]="_ariaInvalid()"
1306
+ [attr.data-touched]="_touched?.() ? 'true' : null"
1307
+ [attr.data-dirty]="_dirty?.() ? 'true' : null"
1308
+ [attr.data-matches-spartan-invalid]="_spartanInvalid() ? 'true' : null"
1309
+ (click)="_handleClick()"
1310
+ (keydown.arrowDown)="_open()"
1311
+ (keydown.enter)="_handleEnter($event)"
1312
+ (input)="_handleInputChange($event)"
1313
+ (focus)="_handleFocus()"
1314
+ (blur)="_handleBlur()"
1315
+ />
1316
+ <hlm-input-group-addon align="inline-end">
1317
+ @if (_showClearButton()) {
1318
+ <button
1319
+ hlmInputGroupButton
1320
+ size="icon-xs"
1321
+ variant="ghost"
1322
+ [attr.aria-label]="clearAriaLabel()"
1323
+ (click)="_clear()"
1324
+ [disabled]="_disabled()"
1325
+ >
1326
+ <ng-icon name="lucideX" />
1327
+ </button>
1328
+ }
1329
+ <button
1330
+ hlmInputGroupButton
1331
+ size="icon-xs"
1332
+ [attr.aria-label]="calendarAriaLabel()"
1333
+ (click)="_popover().open()"
1334
+ [disabled]="_disabled()"
1335
+ >
1336
+ <ng-icon name="lucideCalendar" />
1337
+ </button>
1338
+ </hlm-input-group-addon>
1339
+ `,
1340
+ }]
1341
+ }], propDecorators: { parseDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "parseDate", required: false }] }], formatInputDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatInputDate", required: false }] }] } });
1342
+
1343
+ const HLM_MONTH_YEAR_PICKER_VALUE_ACCESSOR = {
1344
+ provide: NG_VALUE_ACCESSOR,
1345
+ useExisting: forwardRef(() => HlmMonthYearPicker),
1346
+ multi: true,
1347
+ };
1348
+ class HlmMonthYearPicker {
1349
+ constructor() {
1350
+ this._config = injectHlmMonthYearPickerConfig();
1351
+ this.popover = viewChild.required(BrnPopover);
1352
+ this._trigger = contentChild(BrnDatePickerTriggerToken, ...(ngDevMode ? [{ debugName: "_trigger" }] : /* istanbul ignore next */ []));
1353
+ this.align = input('center', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
1354
+ /** The minimum date that can be selected.*/
1355
+ this.minDate = input(...(ngDevMode ? [undefined, { debugName: "minDate" }] : /* istanbul ignore next */ []));
1356
+ /** The maximum date that can be selected. */
1357
+ this.maxDate = input(...(ngDevMode ? [undefined, { debugName: "maxDate" }] : /* istanbul ignore next */ []));
1358
+ /** Determine if the date picker is disabled. */
1359
+ this.disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1360
+ /** The selected value. */
1361
+ this.date = input(...(ngDevMode ? [undefined, { debugName: "date" }] : /* istanbul ignore next */ []));
1362
+ /** The date the calendar focuses on first open when no date is selected. */
1363
+ this.defaultFocusedDate = input(...(ngDevMode ? [undefined, { debugName: "defaultFocusedDate" }] : /* istanbul ignore next */ []));
1364
+ this._mutableDate = linkedSignal(this.date, ...(ngDevMode ? [{ debugName: "_mutableDate" }] : /* istanbul ignore next */ []));
1365
+ /** If true, the date picker will close when a date is selected. */
1366
+ this.autoCloseOnSelect = input(this._config.autoCloseOnSelect, { ...(ngDevMode ? { debugName: "autoCloseOnSelect" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
1367
+ /** Defines how the date should be displayed in the UI. */
1368
+ this.formatDate = input(this._config.formatDate, ...(ngDevMode ? [{ debugName: "formatDate" }] : /* istanbul ignore next */ []));
1369
+ /** Defines how the date should be transformed before saving to model/form. */
1370
+ this.transformDate = input(this._config.transformDate, ...(ngDevMode ? [{ debugName: "transformDate" }] : /* istanbul ignore next */ []));
1371
+ this._popoverState = signal(null, ...(ngDevMode ? [{ debugName: "_popoverState" }] : /* istanbul ignore next */ []));
1372
+ this._disabled = linkedSignal(this.disabled, ...(ngDevMode ? [{ debugName: "_disabled" }] : /* istanbul ignore next */ []));
1373
+ /** @internal The disabled state as a readonly signal */
1374
+ this.disabledState = this._disabled.asReadonly();
1375
+ this.formattedDate = computed(() => {
1376
+ const date = this._mutableDate();
1377
+ return date ? this.formatDate()(date) : undefined;
1378
+ }, ...(ngDevMode ? [{ debugName: "formattedDate" }] : /* istanbul ignore next */ []));
1379
+ this.dateChange = output();
1380
+ this.labelableId = computed(() => this._trigger()?.triggerId(), ...(ngDevMode ? [{ debugName: "labelableId" }] : /* istanbul ignore next */ []));
1381
+ this.hasDate = computed(() => !!this._mutableDate(), ...(ngDevMode ? [{ debugName: "hasDate" }] : /* istanbul ignore next */ []));
1382
+ /** @internal The current raw value, used by inputs to reformat on focus. */
1383
+ this.value = computed(() => this._mutableDate() ?? null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
1384
+ }
1385
+ _onStateChange(state) {
1386
+ this._popoverState.set(state);
1387
+ if (state === 'closed')
1388
+ this._onTouched?.();
1389
+ }
1390
+ _handleChange(value) {
1391
+ if (this._disabled())
1392
+ return;
1393
+ this.updateDate(value ?? null);
1394
+ if (this.autoCloseOnSelect()) {
1395
+ this._popoverState.set('closed');
1396
+ }
1397
+ }
1398
+ /**
1399
+ * Commit a date to the picker. Updates the internal model, notifies form
1400
+ * controls, and emits `dateChange`. Unlike `_handleChange`, this does not
1401
+ * close the popover - it's intended to be called from a text input that
1402
+ * is parsing user-entered values while typing.
1403
+ */
1404
+ updateDate(value) {
1405
+ if (this._disabled())
1406
+ return;
1407
+ const transformedDate = value != null ? this.transformDate()(value) : undefined;
1408
+ this._mutableDate.set(transformedDate);
1409
+ this._onChange?.(transformedDate ?? null);
1410
+ this.dateChange.emit(transformedDate ?? null);
1411
+ }
1412
+ /** CONTROL VALUE ACCESSOR */
1413
+ writeValue(value) {
1414
+ this._mutableDate.set(value ? this.transformDate()(value) : undefined);
1415
+ }
1416
+ registerOnChange(fn) {
1417
+ this._onChange = fn;
1418
+ }
1419
+ registerOnTouched(fn) {
1420
+ this._onTouched = fn;
1421
+ }
1422
+ touched() {
1423
+ this._onTouched?.();
1424
+ }
1425
+ setDisabledState(isDisabled) {
1426
+ this._disabled.set(isDisabled);
1427
+ }
1428
+ open() {
1429
+ this._popoverState.set('open');
1430
+ }
1431
+ close() {
1432
+ this._popoverState.set('closed');
1433
+ }
1434
+ reset() {
1435
+ this._mutableDate.set(undefined);
1436
+ this._onChange?.(null);
1437
+ this.dateChange.emit(null);
1438
+ }
1439
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmMonthYearPicker, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1440
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.8", type: HlmMonthYearPicker, isStandalone: true, selector: "hlm-month-year-picker", inputs: { align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: false, transformFunction: null }, defaultFocusedDate: { classPropertyName: "defaultFocusedDate", publicName: "defaultFocusedDate", isSignal: true, isRequired: false, transformFunction: null }, autoCloseOnSelect: { classPropertyName: "autoCloseOnSelect", publicName: "autoCloseOnSelect", isSignal: true, isRequired: false, transformFunction: null }, formatDate: { classPropertyName: "formatDate", publicName: "formatDate", isSignal: true, isRequired: false, transformFunction: null }, transformDate: { classPropertyName: "transformDate", publicName: "transformDate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateChange: "dateChange" }, host: { classAttribute: "block" }, providers: [
1441
+ HLM_MONTH_YEAR_PICKER_VALUE_ACCESSOR,
1442
+ provideBrnDatePicker(HlmMonthYearPicker),
1443
+ provideBrnLabelable(HlmMonthYearPicker),
1444
+ ], queries: [{ propertyName: "_trigger", first: true, predicate: BrnDatePickerTriggerToken, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "popover", first: true, predicate: BrnPopover, descendants: true, isSignal: true }], hostDirectives: [{ directive: i1$1.BrnFieldControl }], ngImport: i0, template: `
1445
+ <hlm-popover [align]="align()" sideOffset="5" [state]="_popoverState()" (stateChanged)="_onStateChange($event)">
1446
+ <ng-content />
1447
+
1448
+ <hlm-popover-content class="w-fit p-0" *hlmPopoverPortal="let ctx">
1449
+ <ng-content select="[hlmDatePickerHeader]" />
1450
+ <hlm-month-year-calendar
1451
+ class="rounded-none border-0"
1452
+ [date]="_mutableDate()"
1453
+ [defaultFocusedDate]="_mutableDate() ?? defaultFocusedDate()"
1454
+ [min]="minDate()"
1455
+ [max]="maxDate()"
1456
+ [disabled]="_disabled()"
1457
+ (dateChange)="_handleChange($event)"
1458
+ />
1459
+ <ng-content select="[hlmDatePickerFooter]" />
1460
+ </hlm-popover-content>
1461
+ </hlm-popover>
1462
+ `, isInline: true, dependencies: [{ kind: "directive", type: i2.HlmPopover, selector: "[hlmPopover],hlm-popover" }, { kind: "directive", type: i2.HlmPopoverContent, selector: "[hlmPopoverContent],hlm-popover-content" }, { kind: "directive", type: i2.HlmPopoverPortal, selector: "[hlmPopoverPortal]" }, { kind: "component", type: i3.HlmMonthYearCalendar, selector: "hlm-month-year-calendar" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1463
+ }
1464
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: HlmMonthYearPicker, decorators: [{
1465
+ type: Component,
1466
+ args: [{
1467
+ selector: 'hlm-month-year-picker',
1468
+ imports: [HlmPopoverImports, HlmCalendarImports],
1469
+ providers: [
1470
+ HLM_MONTH_YEAR_PICKER_VALUE_ACCESSOR,
1471
+ provideBrnDatePicker(HlmMonthYearPicker),
1472
+ provideBrnLabelable(HlmMonthYearPicker),
1473
+ ],
1474
+ changeDetection: ChangeDetectionStrategy.OnPush,
1475
+ hostDirectives: [BrnFieldControl],
1476
+ host: { class: 'block' },
1477
+ template: `
1478
+ <hlm-popover [align]="align()" sideOffset="5" [state]="_popoverState()" (stateChanged)="_onStateChange($event)">
1479
+ <ng-content />
1480
+
1481
+ <hlm-popover-content class="w-fit p-0" *hlmPopoverPortal="let ctx">
1482
+ <ng-content select="[hlmDatePickerHeader]" />
1483
+ <hlm-month-year-calendar
1484
+ class="rounded-none border-0"
1485
+ [date]="_mutableDate()"
1486
+ [defaultFocusedDate]="_mutableDate() ?? defaultFocusedDate()"
1487
+ [min]="minDate()"
1488
+ [max]="maxDate()"
1489
+ [disabled]="_disabled()"
1490
+ (dateChange)="_handleChange($event)"
1491
+ />
1492
+ <ng-content select="[hlmDatePickerFooter]" />
1493
+ </hlm-popover-content>
1494
+ </hlm-popover>
1495
+ `,
1496
+ }]
1497
+ }], propDecorators: { popover: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnPopover), { isSignal: true }] }], _trigger: [{ type: i0.ContentChild, args: [i0.forwardRef(() => BrnDatePickerTriggerToken), { isSignal: true }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], date: [{ type: i0.Input, args: [{ isSignal: true, alias: "date", required: false }] }], defaultFocusedDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultFocusedDate", required: false }] }], autoCloseOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCloseOnSelect", required: false }] }], formatDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatDate", required: false }] }], transformDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformDate", required: false }] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }] } });
1498
+
1499
+ const HlmDatePickerImports = [
1500
+ HlmDatePicker,
1501
+ HlmDatePickerAnchor,
1502
+ HlmDatePickerInput,
1503
+ HlmDatePickerMulti,
1504
+ HlmDateMultiInput,
1505
+ HlmDateRangeInput,
1506
+ HlmDateRangePicker,
1507
+ HlmDatePickerTrigger,
1508
+ HlmMonthYearPicker,
1509
+ HlmMonthYearInput,
1510
+ ];
1511
+
1512
+ /**
1513
+ * Generated bundle index. Do not edit.
1514
+ */
1515
+
1516
+ export { HLM_DATE_PICKER_MUTLI_VALUE_ACCESSOR, HLM_DATE_PICKER_VALUE_ACCESSOR, HLM_DATE_RANGE_PICKER_VALUE_ACCESSOR, HLM_MONTH_YEAR_PICKER_VALUE_ACCESSOR, HlmDateMultiInput, HlmDatePicker, HlmDatePickerAnchor, HlmDatePickerImports, HlmDatePickerInput, HlmDatePickerMulti, HlmDatePickerTrigger, HlmDateRangeInput, HlmDateRangePicker, HlmMonthYearInput, HlmMonthYearPicker, injectHlmDatePickerConfig, injectHlmDatePickerMultiConfig, injectHlmDateRangePickerConfig, injectHlmMonthYearPickerConfig, provideHlmDatePickerConfig, provideHlmDatePickerMultiConfig, provideHlmDateRangePickerConfig, provideHlmMonthYearPickerConfig };
1517
+ //# sourceMappingURL=yukit-web-helm-date-picker.mjs.map