@mesgflow/ui-kit 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +200 -0
  3. package/fesm2022/mesgflow-ui-kit-accordion.mjs +75 -0
  4. package/fesm2022/mesgflow-ui-kit-accordion.mjs.map +1 -0
  5. package/fesm2022/mesgflow-ui-kit-alert.mjs +165 -0
  6. package/fesm2022/mesgflow-ui-kit-alert.mjs.map +1 -0
  7. package/fesm2022/mesgflow-ui-kit-avatar-group.mjs +88 -0
  8. package/fesm2022/mesgflow-ui-kit-avatar-group.mjs.map +1 -0
  9. package/fesm2022/mesgflow-ui-kit-avatar.mjs +123 -0
  10. package/fesm2022/mesgflow-ui-kit-avatar.mjs.map +1 -0
  11. package/fesm2022/mesgflow-ui-kit-badge.mjs +68 -0
  12. package/fesm2022/mesgflow-ui-kit-badge.mjs.map +1 -0
  13. package/fesm2022/mesgflow-ui-kit-banner.mjs +111 -0
  14. package/fesm2022/mesgflow-ui-kit-banner.mjs.map +1 -0
  15. package/fesm2022/mesgflow-ui-kit-box-input.mjs +78 -0
  16. package/fesm2022/mesgflow-ui-kit-box-input.mjs.map +1 -0
  17. package/fesm2022/mesgflow-ui-kit-brand.mjs +120 -0
  18. package/fesm2022/mesgflow-ui-kit-brand.mjs.map +1 -0
  19. package/fesm2022/mesgflow-ui-kit-breadcrumb.mjs +84 -0
  20. package/fesm2022/mesgflow-ui-kit-breadcrumb.mjs.map +1 -0
  21. package/fesm2022/mesgflow-ui-kit-button-group.mjs +37 -0
  22. package/fesm2022/mesgflow-ui-kit-button-group.mjs.map +1 -0
  23. package/fesm2022/mesgflow-ui-kit-button.mjs +359 -0
  24. package/fesm2022/mesgflow-ui-kit-button.mjs.map +1 -0
  25. package/fesm2022/mesgflow-ui-kit-card.mjs +128 -0
  26. package/fesm2022/mesgflow-ui-kit-card.mjs.map +1 -0
  27. package/fesm2022/mesgflow-ui-kit-chart.mjs +538 -0
  28. package/fesm2022/mesgflow-ui-kit-chart.mjs.map +1 -0
  29. package/fesm2022/mesgflow-ui-kit-checkbox.mjs +45 -0
  30. package/fesm2022/mesgflow-ui-kit-checkbox.mjs.map +1 -0
  31. package/fesm2022/mesgflow-ui-kit-chip.mjs +123 -0
  32. package/fesm2022/mesgflow-ui-kit-chip.mjs.map +1 -0
  33. package/fesm2022/mesgflow-ui-kit-code-block.mjs +71 -0
  34. package/fesm2022/mesgflow-ui-kit-code-block.mjs.map +1 -0
  35. package/fesm2022/mesgflow-ui-kit-collapsible.mjs +89 -0
  36. package/fesm2022/mesgflow-ui-kit-collapsible.mjs.map +1 -0
  37. package/fesm2022/mesgflow-ui-kit-color-picker.mjs +210 -0
  38. package/fesm2022/mesgflow-ui-kit-color-picker.mjs.map +1 -0
  39. package/fesm2022/mesgflow-ui-kit-combobox.mjs +181 -0
  40. package/fesm2022/mesgflow-ui-kit-combobox.mjs.map +1 -0
  41. package/fesm2022/mesgflow-ui-kit-command.mjs +491 -0
  42. package/fesm2022/mesgflow-ui-kit-command.mjs.map +1 -0
  43. package/fesm2022/mesgflow-ui-kit-context-menu.mjs +92 -0
  44. package/fesm2022/mesgflow-ui-kit-context-menu.mjs.map +1 -0
  45. package/fesm2022/mesgflow-ui-kit-copy-button.mjs +167 -0
  46. package/fesm2022/mesgflow-ui-kit-copy-button.mjs.map +1 -0
  47. package/fesm2022/mesgflow-ui-kit-core.mjs +624 -0
  48. package/fesm2022/mesgflow-ui-kit-core.mjs.map +1 -0
  49. package/fesm2022/mesgflow-ui-kit-date-picker.mjs +643 -0
  50. package/fesm2022/mesgflow-ui-kit-date-picker.mjs.map +1 -0
  51. package/fesm2022/mesgflow-ui-kit-description-list.mjs +76 -0
  52. package/fesm2022/mesgflow-ui-kit-description-list.mjs.map +1 -0
  53. package/fesm2022/mesgflow-ui-kit-dialog.mjs +700 -0
  54. package/fesm2022/mesgflow-ui-kit-dialog.mjs.map +1 -0
  55. package/fesm2022/mesgflow-ui-kit-divider.mjs +62 -0
  56. package/fesm2022/mesgflow-ui-kit-divider.mjs.map +1 -0
  57. package/fesm2022/mesgflow-ui-kit-dropzone.mjs +126 -0
  58. package/fesm2022/mesgflow-ui-kit-dropzone.mjs.map +1 -0
  59. package/fesm2022/mesgflow-ui-kit-empty-state.mjs +70 -0
  60. package/fesm2022/mesgflow-ui-kit-empty-state.mjs.map +1 -0
  61. package/fesm2022/mesgflow-ui-kit-field.mjs +42 -0
  62. package/fesm2022/mesgflow-ui-kit-field.mjs.map +1 -0
  63. package/fesm2022/mesgflow-ui-kit-hover-card.mjs +171 -0
  64. package/fesm2022/mesgflow-ui-kit-hover-card.mjs.map +1 -0
  65. package/fesm2022/mesgflow-ui-kit-i18n-tr.mjs +258 -0
  66. package/fesm2022/mesgflow-ui-kit-i18n-tr.mjs.map +1 -0
  67. package/fesm2022/mesgflow-ui-kit-icon.mjs +174 -0
  68. package/fesm2022/mesgflow-ui-kit-icon.mjs.map +1 -0
  69. package/fesm2022/mesgflow-ui-kit-input.mjs +448 -0
  70. package/fesm2022/mesgflow-ui-kit-input.mjs.map +1 -0
  71. package/fesm2022/mesgflow-ui-kit-kbd.mjs +24 -0
  72. package/fesm2022/mesgflow-ui-kit-kbd.mjs.map +1 -0
  73. package/fesm2022/mesgflow-ui-kit-link.mjs +48 -0
  74. package/fesm2022/mesgflow-ui-kit-link.mjs.map +1 -0
  75. package/fesm2022/mesgflow-ui-kit-menu.mjs +105 -0
  76. package/fesm2022/mesgflow-ui-kit-menu.mjs.map +1 -0
  77. package/fesm2022/mesgflow-ui-kit-number-input.mjs +153 -0
  78. package/fesm2022/mesgflow-ui-kit-number-input.mjs.map +1 -0
  79. package/fesm2022/mesgflow-ui-kit-otp-input.mjs +164 -0
  80. package/fesm2022/mesgflow-ui-kit-otp-input.mjs.map +1 -0
  81. package/fesm2022/mesgflow-ui-kit-page-header.mjs +83 -0
  82. package/fesm2022/mesgflow-ui-kit-page-header.mjs.map +1 -0
  83. package/fesm2022/mesgflow-ui-kit-pagination.mjs +99 -0
  84. package/fesm2022/mesgflow-ui-kit-pagination.mjs.map +1 -0
  85. package/fesm2022/mesgflow-ui-kit-password-input.mjs +120 -0
  86. package/fesm2022/mesgflow-ui-kit-password-input.mjs.map +1 -0
  87. package/fesm2022/mesgflow-ui-kit-popover.mjs +213 -0
  88. package/fesm2022/mesgflow-ui-kit-popover.mjs.map +1 -0
  89. package/fesm2022/mesgflow-ui-kit-progress.mjs +82 -0
  90. package/fesm2022/mesgflow-ui-kit-progress.mjs.map +1 -0
  91. package/fesm2022/mesgflow-ui-kit-radio.mjs +123 -0
  92. package/fesm2022/mesgflow-ui-kit-radio.mjs.map +1 -0
  93. package/fesm2022/mesgflow-ui-kit-rating.mjs +116 -0
  94. package/fesm2022/mesgflow-ui-kit-rating.mjs.map +1 -0
  95. package/fesm2022/mesgflow-ui-kit-scroll-area.mjs +84 -0
  96. package/fesm2022/mesgflow-ui-kit-scroll-area.mjs.map +1 -0
  97. package/fesm2022/mesgflow-ui-kit-search-input.mjs +154 -0
  98. package/fesm2022/mesgflow-ui-kit-search-input.mjs.map +1 -0
  99. package/fesm2022/mesgflow-ui-kit-segmented-control.mjs +95 -0
  100. package/fesm2022/mesgflow-ui-kit-segmented-control.mjs.map +1 -0
  101. package/fesm2022/mesgflow-ui-kit-select.mjs +227 -0
  102. package/fesm2022/mesgflow-ui-kit-select.mjs.map +1 -0
  103. package/fesm2022/mesgflow-ui-kit-sidebar.mjs +449 -0
  104. package/fesm2022/mesgflow-ui-kit-sidebar.mjs.map +1 -0
  105. package/fesm2022/mesgflow-ui-kit-skeleton.mjs +74 -0
  106. package/fesm2022/mesgflow-ui-kit-skeleton.mjs.map +1 -0
  107. package/fesm2022/mesgflow-ui-kit-slider.mjs +179 -0
  108. package/fesm2022/mesgflow-ui-kit-slider.mjs.map +1 -0
  109. package/fesm2022/mesgflow-ui-kit-spinner.mjs +67 -0
  110. package/fesm2022/mesgflow-ui-kit-spinner.mjs.map +1 -0
  111. package/fesm2022/mesgflow-ui-kit-splitter.mjs +97 -0
  112. package/fesm2022/mesgflow-ui-kit-splitter.mjs.map +1 -0
  113. package/fesm2022/mesgflow-ui-kit-stat-tile.mjs +98 -0
  114. package/fesm2022/mesgflow-ui-kit-stat-tile.mjs.map +1 -0
  115. package/fesm2022/mesgflow-ui-kit-stepper.mjs +133 -0
  116. package/fesm2022/mesgflow-ui-kit-stepper.mjs.map +1 -0
  117. package/fesm2022/mesgflow-ui-kit-switch.mjs +73 -0
  118. package/fesm2022/mesgflow-ui-kit-switch.mjs.map +1 -0
  119. package/fesm2022/mesgflow-ui-kit-table.mjs +1783 -0
  120. package/fesm2022/mesgflow-ui-kit-table.mjs.map +1 -0
  121. package/fesm2022/mesgflow-ui-kit-tabs.mjs +569 -0
  122. package/fesm2022/mesgflow-ui-kit-tabs.mjs.map +1 -0
  123. package/fesm2022/mesgflow-ui-kit-tag-input.mjs +138 -0
  124. package/fesm2022/mesgflow-ui-kit-tag-input.mjs.map +1 -0
  125. package/fesm2022/mesgflow-ui-kit-theme-switcher.mjs +53 -0
  126. package/fesm2022/mesgflow-ui-kit-theme-switcher.mjs.map +1 -0
  127. package/fesm2022/mesgflow-ui-kit-theming.mjs +1016 -0
  128. package/fesm2022/mesgflow-ui-kit-theming.mjs.map +1 -0
  129. package/fesm2022/mesgflow-ui-kit-time-picker.mjs +138 -0
  130. package/fesm2022/mesgflow-ui-kit-time-picker.mjs.map +1 -0
  131. package/fesm2022/mesgflow-ui-kit-timeline.mjs +91 -0
  132. package/fesm2022/mesgflow-ui-kit-timeline.mjs.map +1 -0
  133. package/fesm2022/mesgflow-ui-kit-toast.mjs +202 -0
  134. package/fesm2022/mesgflow-ui-kit-toast.mjs.map +1 -0
  135. package/fesm2022/mesgflow-ui-kit-toggle.mjs +243 -0
  136. package/fesm2022/mesgflow-ui-kit-toggle.mjs.map +1 -0
  137. package/fesm2022/mesgflow-ui-kit-toolbar.mjs +99 -0
  138. package/fesm2022/mesgflow-ui-kit-toolbar.mjs.map +1 -0
  139. package/fesm2022/mesgflow-ui-kit-tooltip.mjs +160 -0
  140. package/fesm2022/mesgflow-ui-kit-tooltip.mjs.map +1 -0
  141. package/fesm2022/mesgflow-ui-kit-tour.mjs +272 -0
  142. package/fesm2022/mesgflow-ui-kit-tour.mjs.map +1 -0
  143. package/fesm2022/mesgflow-ui-kit-tree-select.mjs +177 -0
  144. package/fesm2022/mesgflow-ui-kit-tree-select.mjs.map +1 -0
  145. package/fesm2022/mesgflow-ui-kit-tree.mjs +82 -0
  146. package/fesm2022/mesgflow-ui-kit-tree.mjs.map +1 -0
  147. package/fesm2022/mesgflow-ui-kit.mjs +12851 -0
  148. package/fesm2022/mesgflow-ui-kit.mjs.map +1 -0
  149. package/package.json +374 -0
  150. package/preset.css +20 -0
  151. package/tokens/color.css +693 -0
  152. package/tokens/contrast.css +68 -0
  153. package/tokens/elevation.css +68 -0
  154. package/tokens/motion.css +277 -0
  155. package/tokens/radius.css +69 -0
  156. package/tokens/typography.css +127 -0
  157. package/tokens.css +41 -0
  158. package/types/mesgflow-ui-kit-accordion.d.ts +42 -0
  159. package/types/mesgflow-ui-kit-alert.d.ts +60 -0
  160. package/types/mesgflow-ui-kit-avatar-group.d.ts +28 -0
  161. package/types/mesgflow-ui-kit-avatar.d.ts +23 -0
  162. package/types/mesgflow-ui-kit-badge.d.ts +39 -0
  163. package/types/mesgflow-ui-kit-banner.d.ts +42 -0
  164. package/types/mesgflow-ui-kit-box-input.d.ts +45 -0
  165. package/types/mesgflow-ui-kit-brand.d.ts +48 -0
  166. package/types/mesgflow-ui-kit-breadcrumb.d.ts +26 -0
  167. package/types/mesgflow-ui-kit-button-group.d.ts +17 -0
  168. package/types/mesgflow-ui-kit-button.d.ts +75 -0
  169. package/types/mesgflow-ui-kit-card.d.ts +71 -0
  170. package/types/mesgflow-ui-kit-chart.d.ts +242 -0
  171. package/types/mesgflow-ui-kit-checkbox.d.ts +17 -0
  172. package/types/mesgflow-ui-kit-chip.d.ts +46 -0
  173. package/types/mesgflow-ui-kit-code-block.d.ts +56 -0
  174. package/types/mesgflow-ui-kit-collapsible.d.ts +39 -0
  175. package/types/mesgflow-ui-kit-color-picker.d.ts +78 -0
  176. package/types/mesgflow-ui-kit-combobox.d.ts +74 -0
  177. package/types/mesgflow-ui-kit-command.d.ts +185 -0
  178. package/types/mesgflow-ui-kit-context-menu.d.ts +40 -0
  179. package/types/mesgflow-ui-kit-copy-button.d.ts +47 -0
  180. package/types/mesgflow-ui-kit-core.d.ts +508 -0
  181. package/types/mesgflow-ui-kit-date-picker.d.ts +215 -0
  182. package/types/mesgflow-ui-kit-description-list.d.ts +23 -0
  183. package/types/mesgflow-ui-kit-dialog.d.ts +342 -0
  184. package/types/mesgflow-ui-kit-divider.d.ts +23 -0
  185. package/types/mesgflow-ui-kit-dropzone.d.ts +47 -0
  186. package/types/mesgflow-ui-kit-empty-state.d.ts +18 -0
  187. package/types/mesgflow-ui-kit-field.d.ts +26 -0
  188. package/types/mesgflow-ui-kit-hover-card.d.ts +52 -0
  189. package/types/mesgflow-ui-kit-i18n-tr.d.ts +14 -0
  190. package/types/mesgflow-ui-kit-icon.d.ts +76 -0
  191. package/types/mesgflow-ui-kit-input.d.ts +186 -0
  192. package/types/mesgflow-ui-kit-kbd.d.ts +9 -0
  193. package/types/mesgflow-ui-kit-link.d.ts +20 -0
  194. package/types/mesgflow-ui-kit-menu.d.ts +53 -0
  195. package/types/mesgflow-ui-kit-number-input.d.ts +55 -0
  196. package/types/mesgflow-ui-kit-otp-input.d.ts +44 -0
  197. package/types/mesgflow-ui-kit-page-header.d.ts +31 -0
  198. package/types/mesgflow-ui-kit-pagination.d.ts +50 -0
  199. package/types/mesgflow-ui-kit-password-input.d.ts +33 -0
  200. package/types/mesgflow-ui-kit-popover.d.ts +62 -0
  201. package/types/mesgflow-ui-kit-progress.d.ts +32 -0
  202. package/types/mesgflow-ui-kit-radio.d.ts +59 -0
  203. package/types/mesgflow-ui-kit-rating.d.ts +56 -0
  204. package/types/mesgflow-ui-kit-scroll-area.d.ts +27 -0
  205. package/types/mesgflow-ui-kit-search-input.d.ts +72 -0
  206. package/types/mesgflow-ui-kit-segmented-control.d.ts +54 -0
  207. package/types/mesgflow-ui-kit-select.d.ts +89 -0
  208. package/types/mesgflow-ui-kit-sidebar.d.ts +224 -0
  209. package/types/mesgflow-ui-kit-skeleton.d.ts +29 -0
  210. package/types/mesgflow-ui-kit-slider.d.ts +40 -0
  211. package/types/mesgflow-ui-kit-spinner.d.ts +31 -0
  212. package/types/mesgflow-ui-kit-splitter.d.ts +40 -0
  213. package/types/mesgflow-ui-kit-stat-tile.d.ts +54 -0
  214. package/types/mesgflow-ui-kit-stepper.d.ts +48 -0
  215. package/types/mesgflow-ui-kit-switch.d.ts +34 -0
  216. package/types/mesgflow-ui-kit-table.d.ts +805 -0
  217. package/types/mesgflow-ui-kit-tabs.d.ts +269 -0
  218. package/types/mesgflow-ui-kit-tag-input.d.ts +33 -0
  219. package/types/mesgflow-ui-kit-theme-switcher.d.ts +27 -0
  220. package/types/mesgflow-ui-kit-theming.d.ts +745 -0
  221. package/types/mesgflow-ui-kit-time-picker.d.ts +54 -0
  222. package/types/mesgflow-ui-kit-timeline.d.ts +27 -0
  223. package/types/mesgflow-ui-kit-toast.d.ts +94 -0
  224. package/types/mesgflow-ui-kit-toggle.d.ts +110 -0
  225. package/types/mesgflow-ui-kit-toolbar.d.ts +52 -0
  226. package/types/mesgflow-ui-kit-tooltip.d.ts +55 -0
  227. package/types/mesgflow-ui-kit-tour.d.ts +66 -0
  228. package/types/mesgflow-ui-kit-tree-select.d.ts +65 -0
  229. package/types/mesgflow-ui-kit-tree.d.ts +44 -0
  230. package/types/mesgflow-ui-kit.d.ts +5444 -0
@@ -0,0 +1,643 @@
1
+ import * as i0 from '@angular/core';
2
+ import { model, input, output, inject, computed, signal, viewChild, effect, untracked, afterRenderEffect, Component, forwardRef } from '@angular/core';
3
+ import { startOfDay, startOfMonth, subDays, startOfWeek, endOfWeek, endOfMonth, eachDayOfInterval, isSameMonth, isSameDay as isSameDay$1, isWithinInterval, addMonths, subMonths, addYears, subYears, format, parse, isValid, addDays } from 'date-fns';
4
+ import { Button } from '@mesgflow/ui-kit/button';
5
+ import { Icon } from '@mesgflow/ui-kit/icon';
6
+ import { MF_DATE_LOCALE, MF_DATE_PICKER_LABELS, cn, ValueAccessorBase } from '@mesgflow/ui-kit/core';
7
+ import * as i1 from '@angular/cdk/overlay';
8
+ import { OverlayModule } from '@angular/cdk/overlay';
9
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
10
+ import { Input, InputGroup, InputPrefix, InputSuffix } from '@mesgflow/ui-kit/input';
11
+ import { Popover } from '@mesgflow/ui-kit/popover';
12
+
13
+ /**
14
+ * Hazır tarih aralıkları — kurumsal panellerde tarih filtresinin %90'ı bunlar
15
+ * (bkz. eski `table-filter.model.ts` `dateRangeFor`, ISO metin üreten
16
+ * kardeşi — burada `Date` nesneleri üretiyor, ISO'ya çevirme çağıranın işi,
17
+ * bkz. `date-picker.model.ts` kullanan `table-filter.model.ts`'teki
18
+ * `dateToIso`). `date-picker`'ın kendi paketi TEK KAYNAK — Table bunu import
19
+ * eder, tersi değil.
20
+ */
21
+ function dateRangeForPreset(preset) {
22
+ const today = startOfDay(new Date());
23
+ if (preset === 'today')
24
+ return { start: today, end: today };
25
+ if (preset === 'thisMonth')
26
+ return { start: startOfMonth(today), end: today };
27
+ const days = preset === 'last7' ? 6 : 29;
28
+ return { start: subDays(today, days), end: today };
29
+ }
30
+ /**
31
+ * Bir ay ızgarası — 6 satır × 7 sütun, komşu ay günleri dahil (haftanın ilk
32
+ * günü `locale`'e göre — tr Pazartesi, en-US Pazar; `date-fns/locale`'in
33
+ * `weekStartsOn`'undan otomatik gelir, elle YAZILMAZ).
34
+ */
35
+ function buildMonthMatrix(month, locale) {
36
+ const gridStart = startOfWeek(startOfMonth(month), { locale });
37
+ const gridEnd = endOfWeek(endOfMonth(month), { locale });
38
+ const days = eachDayOfInterval({ start: gridStart, end: gridEnd });
39
+ const weeks = [];
40
+ for (let i = 0; i < days.length; i += 7)
41
+ weeks.push(days.slice(i, i + 7));
42
+ return weeks;
43
+ }
44
+ function isCurrentMonth(day, month) {
45
+ return isSameMonth(day, month);
46
+ }
47
+ function isSameDay(a, b) {
48
+ if (!a || !b)
49
+ return false;
50
+ return isSameDay$1(a, b);
51
+ }
52
+ function isWithinRange(day, start, end) {
53
+ if (!start || !end)
54
+ return false;
55
+ return isWithinInterval(day, { start, end });
56
+ }
57
+ function isDayDisabled(day, min, max) {
58
+ const time = startOfDay(day).getTime();
59
+ if (min && time < startOfDay(min).getTime())
60
+ return true;
61
+ if (max && time > startOfDay(max).getTime())
62
+ return true;
63
+ return false;
64
+ }
65
+ function shiftMonth(month, delta) {
66
+ return delta >= 0 ? addMonths(month, delta) : subMonths(month, -delta);
67
+ }
68
+ function shiftYear(month, delta) {
69
+ return delta >= 0 ? addYears(month, delta) : subYears(month, -delta);
70
+ }
71
+ /** `date-fns`'in `formatLong.date({width:'short'})`'u — `'P'` token'ının ARKASINDAKİ gerçek örüntü (tr: `dd.MM.yyyy`, en-US: `MM/dd/yyyy`). `parse()` `'P'`'yi DOĞRUDAN kabul etmiyor (yalnızca `format()` yerelleştirilmiş token'ları çözer) — yazarak girişi geri okumak için bu örüntü gerekiyor. */
72
+ function shortDatePattern(locale) {
73
+ return locale.formatLong?.date({ width: 'short' }) ?? 'P';
74
+ }
75
+ function formatDateInput(date, locale) {
76
+ return format(date, shortDatePattern(locale), { locale });
77
+ }
78
+ /** Kullanıcının yazdığı metni çözer; geçersizse `null` (çağıran son geçerli değere geri döner). Sonuç HER ZAMAN gün sınırına (`startOfDay`) normalize edilir. */
79
+ function parseDateInput(text, locale) {
80
+ const trimmed = text.trim();
81
+ if (!trimmed)
82
+ return null;
83
+ const parsed = parse(trimmed, shortDatePattern(locale), new Date(), { locale });
84
+ return isValid(parsed) ? startOfDay(parsed) : null;
85
+ }
86
+
87
+ /**
88
+ * `<mf-calendar [(month)]="visibleMonth" [selected]="value()" (dayPick)="onPick($event)" />`
89
+ *
90
+ * Takvim ızgarasının gövdesi — hem `DatePicker`/`DateRangePicker`'ın overlay
91
+ * paneli İÇİNDE hem inline (overlay'siz) kullanılabilir. `@angular/aria/grid`
92
+ * KULLANILMADI (bkz. plan): sağ ok ayın son gününden sonraki ayın ilk gününe
93
+ * ATLAMALI, `PageUp`/`PageDown` ±1 ay/±1 yıl yapmalı — grid pattern'i
94
+ * render edilmiş satır/sütun sınırlarıyla kapalı, bu ikisini karşılamıyor.
95
+ * Roving tabindex elle kuruldu (emsal: `table-pagination.ts`'in
96
+ * `afterRenderEffect` + `viewChild(ElementRef)` deseni).
97
+ *
98
+ * Üç görünüm (`view`) — gün ızgarası, ay ızgarası, yıl ızgarası — klasik
99
+ * drill-up/down: başlıktaki "Eylül 2026" ay/yıl görünümüne, oradaki yıl
100
+ * yıl ızgarasına götürür; seçim tersine iner.
101
+ */
102
+ class Calendar {
103
+ month = model(startOfMonth(new Date()), /* @ts-ignore */
104
+ ...(ngDevMode ? [{ debugName: "month" }] : /* istanbul ignore next */ []));
105
+ mode = input('single', /* @ts-ignore */
106
+ ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
107
+ selected = input(null, /* @ts-ignore */
108
+ ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
109
+ rangeStart = input(null, /* @ts-ignore */
110
+ ...(ngDevMode ? [{ debugName: "rangeStart" }] : /* istanbul ignore next */ []));
111
+ rangeEnd = input(null, /* @ts-ignore */
112
+ ...(ngDevMode ? [{ debugName: "rangeEnd" }] : /* istanbul ignore next */ []));
113
+ /** Fare aralığın ikinci ucunun üzerinde gezinirken önizleme — `rangeEnd()` doluysa yok sayılır. */
114
+ hoverEnd = input(null, /* @ts-ignore */
115
+ ...(ngDevMode ? [{ debugName: "hoverEnd" }] : /* istanbul ignore next */ []));
116
+ min = input(null, /* @ts-ignore */
117
+ ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
118
+ max = input(null, /* @ts-ignore */
119
+ ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
120
+ locale = input(/* @ts-ignore */
121
+ ...(ngDevMode ? [undefined, { debugName: "locale" }] : /* istanbul ignore next */ []));
122
+ labels = input(/* @ts-ignore */
123
+ ...(ngDevMode ? [undefined, { debugName: "labels" }] : /* istanbul ignore next */ []));
124
+ /**
125
+ * `false` → başlık ok/ay-yıl drill-down kontrolleri GİZLENİR, sadece ay/yıl
126
+ * ETİKETİ (statik metin) kalır. `DateRangePicker`'ın İKİNCİ (takipçi)
127
+ * takvimi için — "ikinci ay = birincinin bir fazlası" değişmezini korumak
128
+ * amacıyla o takvim kendi başına gezilemez (bkz. date-range-picker.ts).
129
+ * Gün ızgarası yine TAM etkileşimli kalır — sadece ay/yıl DEĞİŞTİRME devre
130
+ * dışı.
131
+ */
132
+ navigable = input(true, /* @ts-ignore */
133
+ ...(ngDevMode ? [{ debugName: "navigable" }] : /* istanbul ignore next */ []));
134
+ dayPick = output();
135
+ dayHover = output();
136
+ dateLocaleToken = inject(MF_DATE_LOCALE);
137
+ datePickerLabels = inject(MF_DATE_PICKER_LABELS);
138
+ effectiveLocale = computed(() => this.locale() ?? this.dateLocaleToken(), /* @ts-ignore */
139
+ ...(ngDevMode ? [{ debugName: "effectiveLocale" }] : /* istanbul ignore next */ []));
140
+ effectiveLabels = computed(() => this.labels() ?? this.datePickerLabels(), /* @ts-ignore */
141
+ ...(ngDevMode ? [{ debugName: "effectiveLabels" }] : /* istanbul ignore next */ []));
142
+ view = signal('day', /* @ts-ignore */
143
+ ...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
144
+ focusedDay = signal(new Date(), /* @ts-ignore */
145
+ ...(ngDevMode ? [{ debugName: "focusedDay" }] : /* istanbul ignore next */ []));
146
+ yearPageStart = signal(Math.floor(new Date().getFullYear() / 12) * 12, /* @ts-ignore */
147
+ ...(ngDevMode ? [{ debugName: "yearPageStart" }] : /* istanbul ignore next */ []));
148
+ weeks = computed(() => buildMonthMatrix(this.month(), this.effectiveLocale()), /* @ts-ignore */
149
+ ...(ngDevMode ? [{ debugName: "weeks" }] : /* istanbul ignore next */ []));
150
+ monthGrid = computed(() => {
151
+ const year = this.month().getFullYear();
152
+ return Array.from({ length: 12 }, (_, i) => new Date(year, i, 1));
153
+ }, /* @ts-ignore */
154
+ ...(ngDevMode ? [{ debugName: "monthGrid" }] : /* istanbul ignore next */ []));
155
+ yearGrid = computed(() => Array.from({ length: 12 }, (_, i) => this.yearPageStart() + i), /* @ts-ignore */
156
+ ...(ngDevMode ? [{ debugName: "yearGrid" }] : /* istanbul ignore next */ []));
157
+ weekdayLabels = computed(() => {
158
+ const locale = this.effectiveLocale();
159
+ const start = startOfWeek(new Date(), { locale });
160
+ return Array.from({ length: 7 }, (_, i) => format(addDays(start, i), 'EEEEEE', { locale }));
161
+ }, /* @ts-ignore */
162
+ ...(ngDevMode ? [{ debugName: "weekdayLabels" }] : /* istanbul ignore next */ []));
163
+ monthYearLabel = computed(() => format(this.month(), 'LLLL yyyy', { locale: this.effectiveLocale() }), /* @ts-ignore */
164
+ ...(ngDevMode ? [{ debugName: "monthYearLabel" }] : /* istanbul ignore next */ []));
165
+ gridEl = viewChild('grid', /* @ts-ignore */
166
+ ...(ngDevMode ? [{ debugName: "gridEl" }] : /* istanbul ignore next */ []));
167
+ focusPending = false;
168
+ shiftMonth = shiftMonth;
169
+ shiftYear = shiftYear;
170
+ constructor() {
171
+ // `month()` dışarıdan (ok butonu, klavye, ya da tüketicinin kendi
172
+ // `[(month)]` bağlaması) değiştiğinde odaklı gün YENİ ayın dışında
173
+ // kalmışsa içeri çekilir — `selected()` yeni ayın içindeyse ona, değilse
174
+ // ayın 1'ine.
175
+ effect(() => {
176
+ const month = this.month();
177
+ untracked(() => {
178
+ if (!isCurrentMonth(this.focusedDay(), month)) {
179
+ const preferred = this.selected() ?? new Date();
180
+ this.focusedDay.set(isCurrentMonth(preferred, month) ? preferred : startOfMonth(month));
181
+ }
182
+ });
183
+ });
184
+ afterRenderEffect(() => {
185
+ this.focusedDay();
186
+ if (!this.focusPending)
187
+ return;
188
+ this.focusPending = false;
189
+ const key = this.dayKey(this.focusedDay());
190
+ this.gridEl()?.nativeElement.querySelector(`[data-day-key="${key}"]`)?.focus();
191
+ });
192
+ }
193
+ dayKey(day) {
194
+ return format(day, 'yyyy-MM-dd');
195
+ }
196
+ tabIndexFor(day) {
197
+ return isSameDay(day, this.focusedDay()) ? 0 : -1;
198
+ }
199
+ isDisabled(day) {
200
+ return isDayDisabled(day, this.min(), this.max());
201
+ }
202
+ isSameDaySafe(day) {
203
+ if (this.mode() === 'single')
204
+ return isSameDay(day, this.selected());
205
+ return isSameDay(day, this.rangeStart()) || isSameDay(day, this.rangeEnd());
206
+ }
207
+ dayClasses(day) {
208
+ const outside = !isCurrentMonth(day, this.month());
209
+ const today = isSameDay(day, new Date());
210
+ const isRangeMode = this.mode() === 'range';
211
+ const effectiveEnd = this.rangeEnd() ?? this.hoverEnd();
212
+ const isStart = isRangeMode && isSameDay(day, this.rangeStart());
213
+ const isEnd = isRangeMode &&
214
+ (isSameDay(day, this.rangeEnd()) || (!this.rangeEnd() && isSameDay(day, this.hoverEnd())));
215
+ const isEdge = isStart || isEnd;
216
+ const inRange = isRangeMode && isWithinRange(day, this.rangeStart(), effectiveEnd);
217
+ const isSelectedSingle = !isRangeMode && isSameDay(day, this.selected());
218
+ return cn('relative flex h-9 w-9 shrink-0 appearance-none items-center justify-center rounded-sm border-0 bg-transparent text-sm tabular-nums text-fg transition-colors duration-fast ease-emphasis ' +
219
+ 'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring ' +
220
+ 'disabled:pointer-events-none disabled:opacity-40', outside && 'text-fg-subtle', !isSelectedSingle && !isEdge && 'hover:bg-surface-alt', inRange && 'rounded-none bg-primary-tint', inRange && isStart && 'rounded-s-sm', inRange && isEnd && 'rounded-e-sm', (isSelectedSingle || isEdge) &&
221
+ 'rounded-sm bg-primary-tint font-semibold text-primary-tint-fg', today &&
222
+ !isSelectedSingle &&
223
+ !isEdge &&
224
+ "after:absolute after:bottom-1 after:h-1 after:w-1 after:rounded-full after:bg-accent after:content-['']");
225
+ }
226
+ cellClasses(active) {
227
+ return cn('rounded-sm px-2 py-2.5 text-sm text-fg capitalize transition-colors duration-fast ease-emphasis', active ? 'bg-primary-tint font-semibold text-primary-tint-fg' : 'hover:bg-surface-alt');
228
+ }
229
+ monthLabel(m) {
230
+ return format(m, 'LLL', { locale: this.effectiveLocale() });
231
+ }
232
+ openMonthView() {
233
+ this.view.set('month');
234
+ }
235
+ openYearView() {
236
+ this.yearPageStart.set(Math.floor(this.month().getFullYear() / 12) * 12);
237
+ this.view.set('year');
238
+ }
239
+ shiftYearPage(delta) {
240
+ this.yearPageStart.update((y) => y + delta * 12);
241
+ }
242
+ pickMonth(m) {
243
+ this.month.set(new Date(this.month().getFullYear(), m.getMonth(), 1));
244
+ this.view.set('day');
245
+ }
246
+ pickYear(y) {
247
+ this.month.set(new Date(y, this.month().getMonth(), 1));
248
+ this.view.set('month');
249
+ }
250
+ pick(day) {
251
+ if (this.isDisabled(day))
252
+ return;
253
+ this.focusedDay.set(day);
254
+ this.dayPick.emit(day);
255
+ }
256
+ onDayMouseEnter(day) {
257
+ if (this.mode() === 'range')
258
+ this.dayHover.emit(day);
259
+ }
260
+ onGridKeydown(event) {
261
+ const current = this.focusedDay();
262
+ switch (event.key) {
263
+ case 'ArrowLeft':
264
+ event.preventDefault();
265
+ this.moveFocus(addDays(current, -1));
266
+ break;
267
+ case 'ArrowRight':
268
+ event.preventDefault();
269
+ this.moveFocus(addDays(current, 1));
270
+ break;
271
+ case 'ArrowUp':
272
+ event.preventDefault();
273
+ this.moveFocus(addDays(current, -7));
274
+ break;
275
+ case 'ArrowDown':
276
+ event.preventDefault();
277
+ this.moveFocus(addDays(current, 7));
278
+ break;
279
+ case 'Home':
280
+ event.preventDefault();
281
+ this.moveFocus(startOfWeek(current, { locale: this.effectiveLocale() }));
282
+ break;
283
+ case 'End':
284
+ event.preventDefault();
285
+ this.moveFocus(endOfWeek(current, { locale: this.effectiveLocale() }));
286
+ break;
287
+ case 'PageUp':
288
+ event.preventDefault();
289
+ this.moveFocus(event.shiftKey ? shiftYear(current, -1) : shiftMonth(current, -1));
290
+ break;
291
+ case 'PageDown':
292
+ event.preventDefault();
293
+ this.moveFocus(event.shiftKey ? shiftYear(current, 1) : shiftMonth(current, 1));
294
+ break;
295
+ case 'Enter':
296
+ case ' ':
297
+ event.preventDefault();
298
+ this.pick(current);
299
+ break;
300
+ }
301
+ }
302
+ moveFocus(day) {
303
+ this.focusPending = true;
304
+ this.focusedDay.set(day);
305
+ if (!isCurrentMonth(day, this.month()))
306
+ this.month.set(startOfMonth(day));
307
+ }
308
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Calendar, deps: [], target: i0.ɵɵFactoryTarget.Component });
309
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Calendar, isStandalone: true, selector: "mf-calendar", inputs: { month: { classPropertyName: "month", publicName: "month", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, rangeStart: { classPropertyName: "rangeStart", publicName: "rangeStart", isSignal: true, isRequired: false, transformFunction: null }, rangeEnd: { classPropertyName: "rangeEnd", publicName: "rangeEnd", isSignal: true, isRequired: false, transformFunction: null }, hoverEnd: { classPropertyName: "hoverEnd", publicName: "hoverEnd", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, navigable: { classPropertyName: "navigable", publicName: "navigable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { month: "monthChange", dayPick: "dayPick", dayHover: "dayHover" }, host: { classAttribute: "block" }, viewQueries: [{ propertyName: "gridEl", first: true, predicate: ["grid"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"flex w-64 flex-col gap-2\">\r\n @switch (view()) {\r\n @case ('day') {\r\n <div class=\"flex items-center justify-between\">\r\n @if (navigable()) {\r\n <button\r\n mfButton\r\n tone=\"neutral\"\r\n appearance=\"text\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"effectiveLabels().previousMonth\"\r\n (click)=\"month.set(shiftMonth(month(), -1))\"\r\n >\r\n <span mfIcon [size]=\"18\" class=\"rtl:-scale-x-100\">chevron_left</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"inline-flex appearance-none items-center gap-0.5 border-0 bg-transparent px-1 font-display text-title-sm text-fg capitalize transition-colors duration-fast ease-emphasis hover:text-accent\"\r\n [attr.aria-label]=\"effectiveLabels().chooseMonth\"\r\n (click)=\"openMonthView()\"\r\n >\r\n {{ monthYearLabel() }}\r\n <span mfIcon [size]=\"16\">expand_more</span>\r\n </button>\r\n <button\r\n mfButton\r\n tone=\"neutral\"\r\n appearance=\"text\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"effectiveLabels().nextMonth\"\r\n (click)=\"month.set(shiftMonth(month(), 1))\"\r\n >\r\n <span mfIcon [size]=\"18\" class=\"rtl:-scale-x-100\">chevron_right</span>\r\n </button>\r\n } @else {\r\n <span class=\"px-1 font-display text-title-sm text-fg capitalize\">{{\r\n monthYearLabel()\r\n }}</span>\r\n }\r\n </div>\r\n\r\n <div class=\"grid grid-cols-7\">\r\n @for (label of weekdayLabels(); track $index) {\r\n <span class=\"text-eyebrow flex h-6 items-center justify-center text-fg-subtle\">{{\r\n label\r\n }}</span>\r\n }\r\n </div>\r\n\r\n <!--\r\n `role=\"grid\"` kapsay\u0131c\u0131s\u0131 odaklanabilir DE\u011E\u0130L \u2014 h\u00FCcreler (`role=\"gridcell\"`)\r\n ger\u00E7ek `<button>` elemanlar\u0131, roving tabindex ile kendi odaklar\u0131n\u0131 ta\u015F\u0131r;\r\n bu `(keydown)` yaln\u0131zca ok tu\u015Fu gezinmesini merkezi y\u00F6netmek i\u00E7in.\r\n -->\r\n <!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\r\n <div\r\n #grid\r\n role=\"grid\"\r\n [attr.aria-label]=\"monthYearLabel()\"\r\n class=\"grid grid-cols-7 gap-y-1\"\r\n (keydown)=\"onGridKeydown($event)\"\r\n (mouseleave)=\"dayHover.emit(null)\"\r\n >\r\n @for (week of weeks(); track $index) {\r\n <div role=\"row\" class=\"contents\">\r\n @for (day of week; track day.getTime()) {\r\n <button\r\n type=\"button\"\r\n role=\"gridcell\"\r\n [attr.data-day-key]=\"dayKey(day)\"\r\n [attr.aria-selected]=\"isSameDaySafe(day)\"\r\n [tabindex]=\"tabIndexFor(day)\"\r\n [disabled]=\"isDisabled(day)\"\r\n [class]=\"dayClasses(day)\"\r\n (click)=\"pick(day)\"\r\n (mouseenter)=\"onDayMouseEnter(day)\"\r\n >\r\n {{ day.getDate() }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n @case ('month') {\r\n <div class=\"flex items-center justify-between\">\r\n <button\r\n mfButton\r\n tone=\"neutral\"\r\n appearance=\"text\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"effectiveLabels().previousYear\"\r\n (click)=\"month.set(shiftYear(month(), -1))\"\r\n >\r\n <span mfIcon [size]=\"18\" class=\"rtl:-scale-x-100\">chevron_left</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"inline-flex appearance-none items-center gap-0.5 border-0 bg-transparent px-1 font-display text-title-sm tabular-nums text-fg transition-colors duration-fast ease-emphasis hover:text-accent\"\r\n [attr.aria-label]=\"effectiveLabels().chooseYear\"\r\n (click)=\"openYearView()\"\r\n >\r\n {{ month().getFullYear() }}\r\n <span mfIcon [size]=\"16\">expand_more</span>\r\n </button>\r\n <button\r\n mfButton\r\n tone=\"neutral\"\r\n appearance=\"text\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"effectiveLabels().nextYear\"\r\n (click)=\"month.set(shiftYear(month(), 1))\"\r\n >\r\n <span mfIcon [size]=\"18\" class=\"rtl:-scale-x-100\">chevron_right</span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"grid grid-cols-3 gap-1 py-1\">\r\n @for (m of monthGrid(); track m.getMonth()) {\r\n <button\r\n type=\"button\"\r\n [class]=\"cellClasses(m.getMonth() === month().getMonth())\"\r\n (click)=\"pickMonth(m)\"\r\n >\r\n {{ monthLabel(m) }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n @case ('year') {\r\n <div class=\"flex items-center justify-between\">\r\n <button\r\n mfButton\r\n tone=\"neutral\"\r\n appearance=\"text\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"effectiveLabels().previousYear\"\r\n (click)=\"shiftYearPage(-1)\"\r\n >\r\n <span mfIcon [size]=\"18\" class=\"rtl:-scale-x-100\">chevron_left</span>\r\n </button>\r\n <span class=\"font-display text-title-sm tabular-nums text-fg\"\r\n >{{ yearGrid()[0] }}\u2013{{ yearGrid()[11] }}</span\r\n >\r\n <button\r\n mfButton\r\n tone=\"neutral\"\r\n appearance=\"text\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"effectiveLabels().nextYear\"\r\n (click)=\"shiftYearPage(1)\"\r\n >\r\n <span mfIcon [size]=\"18\" class=\"rtl:-scale-x-100\">chevron_right</span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"grid grid-cols-3 gap-1 py-1\">\r\n @for (y of yearGrid(); track y) {\r\n <button\r\n type=\"button\"\r\n class=\"tabular-nums\"\r\n [class]=\"cellClasses(y === month().getFullYear())\"\r\n (click)=\"pickYear(y)\"\r\n >\r\n {{ y }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n }\r\n</div>\r\n", dependencies: [{ kind: "component", type: Button, selector: "button[mfButton], a[mfButton]", inputs: ["tone", "appearance", "size", "shape", "type", "loading", "iconStart", "iconEnd"], exportAs: ["mfButton"] }, { kind: "directive", type: Icon, selector: "span[mfIcon]", inputs: ["size", "filled"] }] });
310
+ }
311
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Calendar, decorators: [{
312
+ type: Component,
313
+ args: [{ selector: 'mf-calendar', imports: [Button, Icon], host: { class: 'block' }, template: "<div class=\"flex w-64 flex-col gap-2\">\r\n @switch (view()) {\r\n @case ('day') {\r\n <div class=\"flex items-center justify-between\">\r\n @if (navigable()) {\r\n <button\r\n mfButton\r\n tone=\"neutral\"\r\n appearance=\"text\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"effectiveLabels().previousMonth\"\r\n (click)=\"month.set(shiftMonth(month(), -1))\"\r\n >\r\n <span mfIcon [size]=\"18\" class=\"rtl:-scale-x-100\">chevron_left</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"inline-flex appearance-none items-center gap-0.5 border-0 bg-transparent px-1 font-display text-title-sm text-fg capitalize transition-colors duration-fast ease-emphasis hover:text-accent\"\r\n [attr.aria-label]=\"effectiveLabels().chooseMonth\"\r\n (click)=\"openMonthView()\"\r\n >\r\n {{ monthYearLabel() }}\r\n <span mfIcon [size]=\"16\">expand_more</span>\r\n </button>\r\n <button\r\n mfButton\r\n tone=\"neutral\"\r\n appearance=\"text\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"effectiveLabels().nextMonth\"\r\n (click)=\"month.set(shiftMonth(month(), 1))\"\r\n >\r\n <span mfIcon [size]=\"18\" class=\"rtl:-scale-x-100\">chevron_right</span>\r\n </button>\r\n } @else {\r\n <span class=\"px-1 font-display text-title-sm text-fg capitalize\">{{\r\n monthYearLabel()\r\n }}</span>\r\n }\r\n </div>\r\n\r\n <div class=\"grid grid-cols-7\">\r\n @for (label of weekdayLabels(); track $index) {\r\n <span class=\"text-eyebrow flex h-6 items-center justify-center text-fg-subtle\">{{\r\n label\r\n }}</span>\r\n }\r\n </div>\r\n\r\n <!--\r\n `role=\"grid\"` kapsay\u0131c\u0131s\u0131 odaklanabilir DE\u011E\u0130L \u2014 h\u00FCcreler (`role=\"gridcell\"`)\r\n ger\u00E7ek `<button>` elemanlar\u0131, roving tabindex ile kendi odaklar\u0131n\u0131 ta\u015F\u0131r;\r\n bu `(keydown)` yaln\u0131zca ok tu\u015Fu gezinmesini merkezi y\u00F6netmek i\u00E7in.\r\n -->\r\n <!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\r\n <div\r\n #grid\r\n role=\"grid\"\r\n [attr.aria-label]=\"monthYearLabel()\"\r\n class=\"grid grid-cols-7 gap-y-1\"\r\n (keydown)=\"onGridKeydown($event)\"\r\n (mouseleave)=\"dayHover.emit(null)\"\r\n >\r\n @for (week of weeks(); track $index) {\r\n <div role=\"row\" class=\"contents\">\r\n @for (day of week; track day.getTime()) {\r\n <button\r\n type=\"button\"\r\n role=\"gridcell\"\r\n [attr.data-day-key]=\"dayKey(day)\"\r\n [attr.aria-selected]=\"isSameDaySafe(day)\"\r\n [tabindex]=\"tabIndexFor(day)\"\r\n [disabled]=\"isDisabled(day)\"\r\n [class]=\"dayClasses(day)\"\r\n (click)=\"pick(day)\"\r\n (mouseenter)=\"onDayMouseEnter(day)\"\r\n >\r\n {{ day.getDate() }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n @case ('month') {\r\n <div class=\"flex items-center justify-between\">\r\n <button\r\n mfButton\r\n tone=\"neutral\"\r\n appearance=\"text\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"effectiveLabels().previousYear\"\r\n (click)=\"month.set(shiftYear(month(), -1))\"\r\n >\r\n <span mfIcon [size]=\"18\" class=\"rtl:-scale-x-100\">chevron_left</span>\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"inline-flex appearance-none items-center gap-0.5 border-0 bg-transparent px-1 font-display text-title-sm tabular-nums text-fg transition-colors duration-fast ease-emphasis hover:text-accent\"\r\n [attr.aria-label]=\"effectiveLabels().chooseYear\"\r\n (click)=\"openYearView()\"\r\n >\r\n {{ month().getFullYear() }}\r\n <span mfIcon [size]=\"16\">expand_more</span>\r\n </button>\r\n <button\r\n mfButton\r\n tone=\"neutral\"\r\n appearance=\"text\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"effectiveLabels().nextYear\"\r\n (click)=\"month.set(shiftYear(month(), 1))\"\r\n >\r\n <span mfIcon [size]=\"18\" class=\"rtl:-scale-x-100\">chevron_right</span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"grid grid-cols-3 gap-1 py-1\">\r\n @for (m of monthGrid(); track m.getMonth()) {\r\n <button\r\n type=\"button\"\r\n [class]=\"cellClasses(m.getMonth() === month().getMonth())\"\r\n (click)=\"pickMonth(m)\"\r\n >\r\n {{ monthLabel(m) }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n @case ('year') {\r\n <div class=\"flex items-center justify-between\">\r\n <button\r\n mfButton\r\n tone=\"neutral\"\r\n appearance=\"text\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"effectiveLabels().previousYear\"\r\n (click)=\"shiftYearPage(-1)\"\r\n >\r\n <span mfIcon [size]=\"18\" class=\"rtl:-scale-x-100\">chevron_left</span>\r\n </button>\r\n <span class=\"font-display text-title-sm tabular-nums text-fg\"\r\n >{{ yearGrid()[0] }}\u2013{{ yearGrid()[11] }}</span\r\n >\r\n <button\r\n mfButton\r\n tone=\"neutral\"\r\n appearance=\"text\"\r\n size=\"icon\"\r\n shape=\"square\"\r\n type=\"button\"\r\n [attr.aria-label]=\"effectiveLabels().nextYear\"\r\n (click)=\"shiftYearPage(1)\"\r\n >\r\n <span mfIcon [size]=\"18\" class=\"rtl:-scale-x-100\">chevron_right</span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"grid grid-cols-3 gap-1 py-1\">\r\n @for (y of yearGrid(); track y) {\r\n <button\r\n type=\"button\"\r\n class=\"tabular-nums\"\r\n [class]=\"cellClasses(y === month().getFullYear())\"\r\n (click)=\"pickYear(y)\"\r\n >\r\n {{ y }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n }\r\n</div>\r\n" }]
314
+ }], ctorParameters: () => [], propDecorators: { month: [{ type: i0.Input, args: [{ isSignal: true, alias: "month", required: false }] }, { type: i0.Output, args: ["monthChange"] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], rangeStart: [{ type: i0.Input, args: [{ isSignal: true, alias: "rangeStart", required: false }] }], rangeEnd: [{ type: i0.Input, args: [{ isSignal: true, alias: "rangeEnd", required: false }] }], hoverEnd: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverEnd", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], navigable: [{ type: i0.Input, args: [{ isSignal: true, alias: "navigable", required: false }] }], dayPick: [{ type: i0.Output, args: ["dayPick"] }], dayHover: [{ type: i0.Output, args: ["dayHover"] }], gridEl: [{ type: i0.ViewChild, args: ['grid', { isSignal: true }] }] } });
315
+
316
+ /**
317
+ * `<mf-date-picker [(value)]="date" [min]="minDate()" />`
318
+ *
319
+ * Tetikleyici GERÇEK bir `<input mfInput>` — ikon+temizle butonu üstüne
320
+ * bindirilmiş (emsal: `search-input.html`, ayrı bir bordürlü kutuyla
321
+ * SARMALAMIYORUZ, `Input`'un kendi border/shadow/focus'u tek kaynak kalıyor,
322
+ * "çift kenarlık" görünümü olmasın diye). Yazarak giriş + takvimden seçim
323
+ * AYNI `value` model'ine yazıyor.
324
+ *
325
+ * Panel `select.html`'deki CDK overlay bloğunun birebir aynısı (şeffaf
326
+ * backdrop, `(backdropClick)`/`(detach)` → kapat, bottom-start + flip
327
+ * pozisyon). Panel kabuğu sabit formül: `rounded-lg bg-overlay p-3 shadow-2
328
+ * dark:border dark:border-border-subtle` (bkz. table-filter-menu.html).
329
+ */
330
+ class DatePicker extends ValueAccessorBase {
331
+ value = model(null, /* @ts-ignore */
332
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
333
+ min = input(null, /* @ts-ignore */
334
+ ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
335
+ max = input(null, /* @ts-ignore */
336
+ ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
337
+ locale = input(/* @ts-ignore */
338
+ ...(ngDevMode ? [undefined, { debugName: "locale" }] : /* istanbul ignore next */ []));
339
+ labels = input(/* @ts-ignore */
340
+ ...(ngDevMode ? [undefined, { debugName: "labels" }] : /* istanbul ignore next */ []));
341
+ disabled = input(false, /* @ts-ignore */
342
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
343
+ hasError = input(false, /* @ts-ignore */
344
+ ...(ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []));
345
+ ariaLabel = input('', /* @ts-ignore */
346
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
347
+ dateLocaleToken = inject(MF_DATE_LOCALE);
348
+ datePickerLabels = inject(MF_DATE_PICKER_LABELS);
349
+ effectiveLocale = computed(() => this.locale() ?? this.dateLocaleToken(), /* @ts-ignore */
350
+ ...(ngDevMode ? [{ debugName: "effectiveLocale" }] : /* istanbul ignore next */ []));
351
+ effectiveLabels = computed(() => this.labels() ?? this.datePickerLabels(), /* @ts-ignore */
352
+ ...(ngDevMode ? [{ debugName: "effectiveLabels" }] : /* istanbul ignore next */ []));
353
+ open = signal(false, /* @ts-ignore */
354
+ ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
355
+ draft = signal('', /* @ts-ignore */
356
+ ...(ngDevMode ? [{ debugName: "draft" }] : /* istanbul ignore next */ []));
357
+ month = signal(startOfMonth(new Date()), /* @ts-ignore */
358
+ ...(ngDevMode ? [{ debugName: "month" }] : /* istanbul ignore next */ []));
359
+ inputEl = viewChild('inputEl', /* @ts-ignore */
360
+ ...(ngDevMode ? [{ debugName: "inputEl" }] : /* istanbul ignore next */ []));
361
+ constructor() {
362
+ super();
363
+ // `value()`/`locale()` değişince taslak metin ve görünen ay yeniden
364
+ // hesaplanır — `locale()` BİLEREK izlenen bağımlılıklardan biri (dil
365
+ // değişince mevcut değer YENİ yerel kısa biçimde gösterilsin).
366
+ effect(() => {
367
+ const v = this.value();
368
+ const locale = this.effectiveLocale();
369
+ untracked(() => {
370
+ this.draft.set(v ? formatDateInput(v, locale) : '');
371
+ this.month.set(startOfMonth(v ?? new Date()));
372
+ });
373
+ });
374
+ }
375
+ writeValue(value) {
376
+ this.value.set(value);
377
+ }
378
+ setValue(next) {
379
+ this.value.set(next);
380
+ this.onChange(next);
381
+ this.onTouched();
382
+ }
383
+ onInput(raw) {
384
+ this.draft.set(raw);
385
+ this.onTouched();
386
+ }
387
+ commitDraft() {
388
+ const text = this.draft().trim();
389
+ if (!text) {
390
+ this.setValue(null);
391
+ return;
392
+ }
393
+ const parsed = parseDateInput(text, this.effectiveLocale());
394
+ if (parsed && !isDayDisabled(parsed, this.min(), this.max())) {
395
+ this.setValue(parsed);
396
+ }
397
+ else {
398
+ const v = this.value();
399
+ this.draft.set(v ? formatDateInput(v, this.effectiveLocale()) : '');
400
+ }
401
+ }
402
+ onDayPick(day) {
403
+ this.setValue(day);
404
+ this.close();
405
+ }
406
+ pickToday() {
407
+ this.onDayPick(startOfDay(new Date()));
408
+ }
409
+ clear() {
410
+ this.setValue(null);
411
+ this.inputEl()?.nativeElement.focus();
412
+ }
413
+ close() {
414
+ this.open.set(false);
415
+ }
416
+ onEscape() {
417
+ if (!this.open())
418
+ return;
419
+ const v = this.value();
420
+ this.draft.set(v ? formatDateInput(v, this.effectiveLocale()) : '');
421
+ this.close();
422
+ }
423
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: DatePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
424
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: DatePicker, isStandalone: true, selector: "mf-date-picker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hasError: { classPropertyName: "hasError", publicName: "hasError", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { classAttribute: "block" }, providers: [
425
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DatePicker), multi: true },
426
+ ], viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["inputEl"], descendants: true, isSignal: true }], exportAs: ["mfDatePicker"], usesInheritance: true, ngImport: i0, template: "<div class=\"relative w-full\" cdkOverlayOrigin #origin=\"cdkOverlayOrigin\">\r\n <span\r\n mfIcon\r\n [size]=\"18\"\r\n class=\"pointer-events-none absolute top-1/2 start-2.5 -translate-y-1/2 text-fg-subtle\"\r\n >calendar_today</span\r\n >\r\n <input\r\n mfInput\r\n #inputEl\r\n type=\"text\"\r\n class=\"ps-9\"\r\n [class.pr-8]=\"!!value()\"\r\n [hasError]=\"hasError()\"\r\n [disabled]=\"disabled()\"\r\n [placeholder]=\"effectiveLabels().placeholder\"\r\n [value]=\"draft()\"\r\n [attr.aria-label]=\"ariaLabel() || null\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (focus)=\"open.set(true)\"\r\n (keydown.enter)=\"commitDraft()\"\r\n (keydown.escape)=\"onEscape()\"\r\n />\r\n @if (value()) {\r\n <button\r\n type=\"button\"\r\n class=\"absolute top-1/2 end-2.5 -translate-y-1/2 appearance-none border-0 bg-transparent p-0 text-fg-subtle transition-colors duration-fast ease-emphasis hover:text-fg\"\r\n [attr.aria-label]=\"effectiveLabels().clear\"\r\n (click)=\"clear()\"\r\n >\r\n <span mfIcon [size]=\"16\">close</span>\r\n </button>\r\n }\r\n\r\n <mf-popover\r\n [origin]=\"origin\"\r\n [open]=\"open()\"\r\n placement=\"bottom-start\"\r\n padding=\"lg\"\r\n panelClass=\"w-auto\"\r\n (closed)=\"onEscape()\"\r\n >\r\n <mf-calendar\r\n [(month)]=\"month\"\r\n [selected]=\"value()\"\r\n [min]=\"min()\"\r\n [max]=\"max()\"\r\n [locale]=\"effectiveLocale()\"\r\n [labels]=\"effectiveLabels()\"\r\n (dayPick)=\"onDayPick($event)\"\r\n />\r\n <div class=\"mt-2 flex items-center justify-between border-t border-border pt-2\">\r\n <button\r\n type=\"button\"\r\n class=\"appearance-none border-0 bg-transparent p-0 text-xs font-medium text-accent transition-colors duration-fast ease-emphasis hover:text-accent-strong\"\r\n (click)=\"pickToday()\"\r\n >\r\n {{ effectiveLabels().today }}\r\n </button>\r\n @if (value()) {\r\n <button\r\n type=\"button\"\r\n class=\"appearance-none border-0 bg-transparent p-0 text-xs font-medium text-fg-subtle transition-colors duration-fast ease-emphasis hover:text-fg\"\r\n (click)=\"clear()\"\r\n >\r\n {{ effectiveLabels().clear }}\r\n </button>\r\n }\r\n </div>\r\n </mf-popover>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: Icon, selector: "span[mfIcon]", inputs: ["size", "filled"] }, { kind: "directive", type: Input, selector: "input[mfInput]:not([type=checkbox]):not([type=radio]), textarea[mfInput]", inputs: ["size", "hasError", "autosize", "minRows", "maxRows"] }, { kind: "component", type: Calendar, selector: "mf-calendar", inputs: ["month", "mode", "selected", "rangeStart", "rangeEnd", "hoverEnd", "min", "max", "locale", "labels", "navigable"], outputs: ["monthChange", "dayPick", "dayHover"] }, { kind: "component", type: Popover, selector: "mf-popover", inputs: ["origin", "open", "placement", "padding", "hasBackdrop", "matchTriggerWidth", "panelClass"], outputs: ["openChange", "closed"], exportAs: ["mfPopover"] }] });
427
+ }
428
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: DatePicker, decorators: [{
429
+ type: Component,
430
+ args: [{ selector: 'mf-date-picker', exportAs: 'mfDatePicker', imports: [OverlayModule, Icon, Input, Calendar, Popover], host: { class: 'block' }, providers: [
431
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DatePicker), multi: true },
432
+ ], template: "<div class=\"relative w-full\" cdkOverlayOrigin #origin=\"cdkOverlayOrigin\">\r\n <span\r\n mfIcon\r\n [size]=\"18\"\r\n class=\"pointer-events-none absolute top-1/2 start-2.5 -translate-y-1/2 text-fg-subtle\"\r\n >calendar_today</span\r\n >\r\n <input\r\n mfInput\r\n #inputEl\r\n type=\"text\"\r\n class=\"ps-9\"\r\n [class.pr-8]=\"!!value()\"\r\n [hasError]=\"hasError()\"\r\n [disabled]=\"disabled()\"\r\n [placeholder]=\"effectiveLabels().placeholder\"\r\n [value]=\"draft()\"\r\n [attr.aria-label]=\"ariaLabel() || null\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (focus)=\"open.set(true)\"\r\n (keydown.enter)=\"commitDraft()\"\r\n (keydown.escape)=\"onEscape()\"\r\n />\r\n @if (value()) {\r\n <button\r\n type=\"button\"\r\n class=\"absolute top-1/2 end-2.5 -translate-y-1/2 appearance-none border-0 bg-transparent p-0 text-fg-subtle transition-colors duration-fast ease-emphasis hover:text-fg\"\r\n [attr.aria-label]=\"effectiveLabels().clear\"\r\n (click)=\"clear()\"\r\n >\r\n <span mfIcon [size]=\"16\">close</span>\r\n </button>\r\n }\r\n\r\n <mf-popover\r\n [origin]=\"origin\"\r\n [open]=\"open()\"\r\n placement=\"bottom-start\"\r\n padding=\"lg\"\r\n panelClass=\"w-auto\"\r\n (closed)=\"onEscape()\"\r\n >\r\n <mf-calendar\r\n [(month)]=\"month\"\r\n [selected]=\"value()\"\r\n [min]=\"min()\"\r\n [max]=\"max()\"\r\n [locale]=\"effectiveLocale()\"\r\n [labels]=\"effectiveLabels()\"\r\n (dayPick)=\"onDayPick($event)\"\r\n />\r\n <div class=\"mt-2 flex items-center justify-between border-t border-border pt-2\">\r\n <button\r\n type=\"button\"\r\n class=\"appearance-none border-0 bg-transparent p-0 text-xs font-medium text-accent transition-colors duration-fast ease-emphasis hover:text-accent-strong\"\r\n (click)=\"pickToday()\"\r\n >\r\n {{ effectiveLabels().today }}\r\n </button>\r\n @if (value()) {\r\n <button\r\n type=\"button\"\r\n class=\"appearance-none border-0 bg-transparent p-0 text-xs font-medium text-fg-subtle transition-colors duration-fast ease-emphasis hover:text-fg\"\r\n (click)=\"clear()\"\r\n >\r\n {{ effectiveLabels().clear }}\r\n </button>\r\n }\r\n </div>\r\n </mf-popover>\r\n</div>\r\n" }]
433
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], hasError: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasError", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], inputEl: [{ type: i0.ViewChild, args: ['inputEl', { isSignal: true }] }] } });
434
+
435
+ const PRESETS = ['today', 'last7', 'last30', 'thisMonth'];
436
+ /**
437
+ * `<mf-date-range-picker [(value)]="range" />` — `value` şekli
438
+ * `{ start: Date | null; end: Date | null }` (bkz. `DateRange`).
439
+ *
440
+ * Tetikleyici tek kutu içinde İKİ metin input'u (başlangıç/bitiş) —
441
+ * `DatePicker`'ın aksine burada `mfInput`'un KENDİ border/shadow'unu
442
+ * KULLANMIYORUZ (iki input yan yana, "çift kenarlık" olmasın diye border/
443
+ * shadow/focus DIŞ kutuya taşındı, iç input'lar çıplak — tek gerekçeli
444
+ * istisna).
445
+ *
446
+ * Panelde solda ön ayar sütunu + sağda iki takvim (ikincisi
447
+ * `[navigable]="false"` — bkz. `calendar.ts`, "birincinin bir fazlası"
448
+ * değişmezini koruyor). Onay YALNIZCA "Uygula"da dışarı çıkar — takvimde
449
+ * gezinme/seçim kendi `draftRange` sinyalinde kalır, `value()` her tık ile
450
+ * DEĞİŞMEZ (emsal: `table-page-jump.ts` — her tuş vuruşunda backend'e istek
451
+ * atmama notu). "Temizle" bunun istisnası — anında commit eder.
452
+ */
453
+ class DateRangePicker extends ValueAccessorBase {
454
+ value = model({ start: null, end: null }, /* @ts-ignore */
455
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
456
+ min = input(null, /* @ts-ignore */
457
+ ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
458
+ max = input(null, /* @ts-ignore */
459
+ ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
460
+ locale = input(/* @ts-ignore */
461
+ ...(ngDevMode ? [undefined, { debugName: "locale" }] : /* istanbul ignore next */ []));
462
+ labels = input(/* @ts-ignore */
463
+ ...(ngDevMode ? [undefined, { debugName: "labels" }] : /* istanbul ignore next */ []));
464
+ disabled = input(false, /* @ts-ignore */
465
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
466
+ hasError = input(false, /* @ts-ignore */
467
+ ...(ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []));
468
+ dateLocaleToken = inject(MF_DATE_LOCALE);
469
+ datePickerLabels = inject(MF_DATE_PICKER_LABELS);
470
+ effectiveLocale = computed(() => this.locale() ?? this.dateLocaleToken(), /* @ts-ignore */
471
+ ...(ngDevMode ? [{ debugName: "effectiveLocale" }] : /* istanbul ignore next */ []));
472
+ effectiveLabels = computed(() => this.labels() ?? this.datePickerLabels(), /* @ts-ignore */
473
+ ...(ngDevMode ? [{ debugName: "effectiveLabels" }] : /* istanbul ignore next */ []));
474
+ open = signal(false, /* @ts-ignore */
475
+ ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
476
+ startDraft = signal('', /* @ts-ignore */
477
+ ...(ngDevMode ? [{ debugName: "startDraft" }] : /* istanbul ignore next */ []));
478
+ endDraft = signal('', /* @ts-ignore */
479
+ ...(ngDevMode ? [{ debugName: "endDraft" }] : /* istanbul ignore next */ []));
480
+ draftRange = signal({ start: null, end: null }, /* @ts-ignore */
481
+ ...(ngDevMode ? [{ debugName: "draftRange" }] : /* istanbul ignore next */ []));
482
+ pickStage = signal('start', /* @ts-ignore */
483
+ ...(ngDevMode ? [{ debugName: "pickStage" }] : /* istanbul ignore next */ []));
484
+ hoverEnd = signal(null, /* @ts-ignore */
485
+ ...(ngDevMode ? [{ debugName: "hoverEnd" }] : /* istanbul ignore next */ []));
486
+ monthLeft = signal(startOfMonth(new Date()), /* @ts-ignore */
487
+ ...(ngDevMode ? [{ debugName: "monthLeft" }] : /* istanbul ignore next */ []));
488
+ monthRight = signal(addMonths(startOfMonth(new Date()), 1), /* @ts-ignore */
489
+ ...(ngDevMode ? [{ debugName: "monthRight" }] : /* istanbul ignore next */ []));
490
+ presets = PRESETS;
491
+ startEl = viewChild('startEl', /* @ts-ignore */
492
+ ...(ngDevMode ? [{ debugName: "startEl" }] : /* istanbul ignore next */ []));
493
+ constructor() {
494
+ super();
495
+ // `value()`/`locale()` değişince iki taslak metin yeniden hesaplanır.
496
+ effect(() => {
497
+ const v = this.value();
498
+ const locale = this.effectiveLocale();
499
+ untracked(() => {
500
+ this.startDraft.set(v.start ? formatDateInput(v.start, locale) : '');
501
+ this.endDraft.set(v.end ? formatDateInput(v.end, locale) : '');
502
+ });
503
+ });
504
+ // Sol takvim değişince sağ takvim HER ZAMAN bir fazlası — kendi başına
505
+ // gezilemiyor (bkz. `Calendar.navigable`), tek yönlü senkron yeterli.
506
+ effect(() => {
507
+ const left = this.monthLeft();
508
+ untracked(() => this.monthRight.set(addMonths(left, 1)));
509
+ });
510
+ // Panel her açılışta `value()`'dan taze bir taslakla başlar.
511
+ effect(() => {
512
+ if (!this.open())
513
+ return;
514
+ untracked(() => {
515
+ const v = this.value();
516
+ this.draftRange.set(v);
517
+ this.pickStage.set(v.start && !v.end ? 'end' : 'start');
518
+ this.hoverEnd.set(null);
519
+ this.monthLeft.set(startOfMonth(v.start ?? new Date()));
520
+ });
521
+ });
522
+ }
523
+ writeValue(value) {
524
+ this.value.set(value);
525
+ }
526
+ setValue(next) {
527
+ this.value.set(next);
528
+ this.onChange(next);
529
+ this.onTouched();
530
+ }
531
+ presetLabel(preset) {
532
+ const labels = this.effectiveLabels();
533
+ if (preset === 'today')
534
+ return labels.presetToday;
535
+ if (preset === 'last7')
536
+ return labels.presetLast7;
537
+ if (preset === 'last30')
538
+ return labels.presetLast30;
539
+ return labels.presetThisMonth;
540
+ }
541
+ applyPreset(preset) {
542
+ const range = dateRangeForPreset(preset);
543
+ this.setValue(range);
544
+ this.close();
545
+ }
546
+ onStartInput(raw) {
547
+ this.startDraft.set(raw);
548
+ this.onTouched();
549
+ }
550
+ onEndInput(raw) {
551
+ this.endDraft.set(raw);
552
+ this.onTouched();
553
+ }
554
+ commitStartDraft() {
555
+ const text = this.startDraft().trim();
556
+ const current = this.value();
557
+ if (!text) {
558
+ this.setValue({ ...current, start: null });
559
+ return;
560
+ }
561
+ const parsed = parseDateInput(text, this.effectiveLocale());
562
+ if (parsed && !isDayDisabled(parsed, this.min(), this.max())) {
563
+ const end = current.end && parsed > current.end ? null : current.end;
564
+ this.setValue({ start: parsed, end });
565
+ }
566
+ else {
567
+ this.startDraft.set(current.start ? formatDateInput(current.start, this.effectiveLocale()) : '');
568
+ }
569
+ }
570
+ commitEndDraft() {
571
+ const text = this.endDraft().trim();
572
+ const current = this.value();
573
+ if (!text) {
574
+ this.setValue({ ...current, end: null });
575
+ return;
576
+ }
577
+ const parsed = parseDateInput(text, this.effectiveLocale());
578
+ const validOrder = !current.start || (parsed && parsed >= current.start);
579
+ if (parsed && validOrder && !isDayDisabled(parsed, this.min(), this.max())) {
580
+ this.setValue({ ...current, end: parsed });
581
+ }
582
+ else {
583
+ this.endDraft.set(current.end ? formatDateInput(current.end, this.effectiveLocale()) : '');
584
+ }
585
+ }
586
+ onDayHover(day) {
587
+ this.hoverEnd.set(day);
588
+ }
589
+ onDayPick(day) {
590
+ const draft = this.draftRange();
591
+ if (this.pickStage() === 'start' || (draft.start && draft.end)) {
592
+ this.draftRange.set({ start: day, end: null });
593
+ this.pickStage.set('end');
594
+ this.hoverEnd.set(null);
595
+ return;
596
+ }
597
+ const start = draft.start;
598
+ this.draftRange.set(day < start ? { start: day, end: start } : { start, end: day });
599
+ this.pickStage.set('start');
600
+ this.hoverEnd.set(null);
601
+ }
602
+ apply() {
603
+ const draft = this.draftRange();
604
+ if (!draft.start)
605
+ return;
606
+ this.setValue({ start: draft.start, end: draft.end ?? draft.start });
607
+ this.close();
608
+ }
609
+ clear() {
610
+ this.setValue({ start: null, end: null });
611
+ this.draftRange.set({ start: null, end: null });
612
+ this.pickStage.set('start');
613
+ this.startEl()?.nativeElement.focus();
614
+ }
615
+ close() {
616
+ this.open.set(false);
617
+ }
618
+ onEscape() {
619
+ if (!this.open())
620
+ return;
621
+ const v = this.value();
622
+ this.startDraft.set(v.start ? formatDateInput(v.start, this.effectiveLocale()) : '');
623
+ this.endDraft.set(v.end ? formatDateInput(v.end, this.effectiveLocale()) : '');
624
+ this.close();
625
+ }
626
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: DateRangePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
627
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: DateRangePicker, isStandalone: true, selector: "mf-date-range-picker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, hasError: { classPropertyName: "hasError", publicName: "hasError", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { classAttribute: "block" }, providers: [
628
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DateRangePicker), multi: true },
629
+ ], viewQueries: [{ propertyName: "startEl", first: true, predicate: ["startEl"], descendants: true, isSignal: true }], exportAs: ["mfDateRangePicker"], usesInheritance: true, ngImport: i0, template: "<div class=\"relative w-full\" cdkOverlayOrigin #origin=\"cdkOverlayOrigin\">\r\n <mf-input-group [hasError]=\"hasError()\" [disabled]=\"disabled()\">\r\n <span mfInputPrefix><span mfIcon [size]=\"18\">calendar_today</span></span>\r\n <input\r\n #startEl\r\n type=\"text\"\r\n class=\"w-0 min-w-0 flex-1 appearance-none border-0 bg-transparent p-0 text-sm text-fg placeholder:text-fg-subtle focus:outline-none\"\r\n [placeholder]=\"effectiveLabels().startDate\"\r\n [value]=\"startDraft()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"effectiveLabels().startDate\"\r\n (input)=\"onStartInput($any($event.target).value)\"\r\n (focus)=\"open.set(true)\"\r\n (keydown.enter)=\"commitStartDraft()\"\r\n (keydown.escape)=\"onEscape()\"\r\n />\r\n <span class=\"shrink-0 text-fg-subtle\" aria-hidden=\"true\">\u2013</span>\r\n <input\r\n type=\"text\"\r\n class=\"w-0 min-w-0 flex-1 appearance-none border-0 bg-transparent p-0 text-sm text-fg placeholder:text-fg-subtle focus:outline-none\"\r\n [placeholder]=\"effectiveLabels().endDate\"\r\n [value]=\"endDraft()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"effectiveLabels().endDate\"\r\n (input)=\"onEndInput($any($event.target).value)\"\r\n (focus)=\"open.set(true)\"\r\n (keydown.enter)=\"commitEndDraft()\"\r\n (keydown.escape)=\"onEscape()\"\r\n />\r\n @if (value().start || value().end) {\r\n <button\r\n mfInputSuffix\r\n type=\"button\"\r\n class=\"appearance-none border-0 bg-transparent p-0 transition-colors duration-fast ease-emphasis hover:text-fg\"\r\n [attr.aria-label]=\"effectiveLabels().clear\"\r\n (click)=\"clear()\"\r\n >\r\n <span mfIcon [size]=\"16\">close</span>\r\n </button>\r\n }\r\n </mf-input-group>\r\n\r\n <mf-popover\r\n [origin]=\"origin\"\r\n [open]=\"open()\"\r\n placement=\"bottom-start\"\r\n padding=\"none\"\r\n panelClass=\"flex w-auto\"\r\n (closed)=\"onEscape()\"\r\n >\r\n <div class=\"flex flex-col gap-0.5 border-e border-border p-2\">\r\n @for (preset of presets; track preset) {\r\n <button\r\n type=\"button\"\r\n class=\"appearance-none whitespace-nowrap rounded-sm border-0 bg-transparent px-2.5 py-1.5 text-start text-sm text-fg-muted transition-colors duration-fast ease-emphasis hover:bg-surface-alt\"\r\n (click)=\"applyPreset(preset)\"\r\n >\r\n {{ presetLabel(preset) }}\r\n </button>\r\n }\r\n </div>\r\n\r\n <div class=\"flex flex-col gap-2 p-3\">\r\n <div class=\"flex gap-4\">\r\n <mf-calendar\r\n mode=\"range\"\r\n [(month)]=\"monthLeft\"\r\n [rangeStart]=\"draftRange().start\"\r\n [rangeEnd]=\"draftRange().end\"\r\n [hoverEnd]=\"hoverEnd()\"\r\n [min]=\"min()\"\r\n [max]=\"max()\"\r\n [locale]=\"effectiveLocale()\"\r\n [labels]=\"effectiveLabels()\"\r\n (dayPick)=\"onDayPick($event)\"\r\n (dayHover)=\"onDayHover($event)\"\r\n />\r\n <div class=\"hidden sm:block\">\r\n <mf-calendar\r\n mode=\"range\"\r\n [month]=\"monthRight()\"\r\n [navigable]=\"false\"\r\n [rangeStart]=\"draftRange().start\"\r\n [rangeEnd]=\"draftRange().end\"\r\n [hoverEnd]=\"hoverEnd()\"\r\n [min]=\"min()\"\r\n [max]=\"max()\"\r\n [locale]=\"effectiveLocale()\"\r\n [labels]=\"effectiveLabels()\"\r\n (dayPick)=\"onDayPick($event)\"\r\n (dayHover)=\"onDayHover($event)\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"flex items-center justify-end gap-2 border-t border-border pt-2\">\r\n <button mfButton tone=\"neutral\" appearance=\"text\" size=\"sm\" type=\"button\" (click)=\"clear()\">\r\n {{ effectiveLabels().clear }}\r\n </button>\r\n <button\r\n mfButton\r\n tone=\"primary\"\r\n appearance=\"filled\"\r\n size=\"sm\"\r\n type=\"button\"\r\n [disabled]=\"!draftRange().start\"\r\n (click)=\"apply()\"\r\n >\r\n {{ effectiveLabels().apply }}\r\n </button>\r\n </div>\r\n </div>\r\n </mf-popover>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: Icon, selector: "span[mfIcon]", inputs: ["size", "filled"] }, { kind: "component", type: Button, selector: "button[mfButton], a[mfButton]", inputs: ["tone", "appearance", "size", "shape", "type", "loading", "iconStart", "iconEnd"], exportAs: ["mfButton"] }, { kind: "component", type: Calendar, selector: "mf-calendar", inputs: ["month", "mode", "selected", "rangeStart", "rangeEnd", "hoverEnd", "min", "max", "locale", "labels", "navigable"], outputs: ["monthChange", "dayPick", "dayHover"] }, { kind: "component", type: Popover, selector: "mf-popover", inputs: ["origin", "open", "placement", "padding", "hasBackdrop", "matchTriggerWidth", "panelClass"], outputs: ["openChange", "closed"], exportAs: ["mfPopover"] }, { kind: "component", type: InputGroup, selector: "mf-input-group", inputs: ["size", "disabled", "hasError", "padded", "wrap"], exportAs: ["mfInputGroup"] }, { kind: "directive", type: InputPrefix, selector: "[mfInputPrefix]", inputs: ["addon"] }, { kind: "directive", type: InputSuffix, selector: "[mfInputSuffix]", inputs: ["addon"] }] });
630
+ }
631
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: DateRangePicker, decorators: [{
632
+ type: Component,
633
+ args: [{ selector: 'mf-date-range-picker', exportAs: 'mfDateRangePicker', imports: [OverlayModule, Icon, Button, Calendar, Popover, InputGroup, InputPrefix, InputSuffix], host: { class: 'block' }, providers: [
634
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DateRangePicker), multi: true },
635
+ ], template: "<div class=\"relative w-full\" cdkOverlayOrigin #origin=\"cdkOverlayOrigin\">\r\n <mf-input-group [hasError]=\"hasError()\" [disabled]=\"disabled()\">\r\n <span mfInputPrefix><span mfIcon [size]=\"18\">calendar_today</span></span>\r\n <input\r\n #startEl\r\n type=\"text\"\r\n class=\"w-0 min-w-0 flex-1 appearance-none border-0 bg-transparent p-0 text-sm text-fg placeholder:text-fg-subtle focus:outline-none\"\r\n [placeholder]=\"effectiveLabels().startDate\"\r\n [value]=\"startDraft()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"effectiveLabels().startDate\"\r\n (input)=\"onStartInput($any($event.target).value)\"\r\n (focus)=\"open.set(true)\"\r\n (keydown.enter)=\"commitStartDraft()\"\r\n (keydown.escape)=\"onEscape()\"\r\n />\r\n <span class=\"shrink-0 text-fg-subtle\" aria-hidden=\"true\">\u2013</span>\r\n <input\r\n type=\"text\"\r\n class=\"w-0 min-w-0 flex-1 appearance-none border-0 bg-transparent p-0 text-sm text-fg placeholder:text-fg-subtle focus:outline-none\"\r\n [placeholder]=\"effectiveLabels().endDate\"\r\n [value]=\"endDraft()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"effectiveLabels().endDate\"\r\n (input)=\"onEndInput($any($event.target).value)\"\r\n (focus)=\"open.set(true)\"\r\n (keydown.enter)=\"commitEndDraft()\"\r\n (keydown.escape)=\"onEscape()\"\r\n />\r\n @if (value().start || value().end) {\r\n <button\r\n mfInputSuffix\r\n type=\"button\"\r\n class=\"appearance-none border-0 bg-transparent p-0 transition-colors duration-fast ease-emphasis hover:text-fg\"\r\n [attr.aria-label]=\"effectiveLabels().clear\"\r\n (click)=\"clear()\"\r\n >\r\n <span mfIcon [size]=\"16\">close</span>\r\n </button>\r\n }\r\n </mf-input-group>\r\n\r\n <mf-popover\r\n [origin]=\"origin\"\r\n [open]=\"open()\"\r\n placement=\"bottom-start\"\r\n padding=\"none\"\r\n panelClass=\"flex w-auto\"\r\n (closed)=\"onEscape()\"\r\n >\r\n <div class=\"flex flex-col gap-0.5 border-e border-border p-2\">\r\n @for (preset of presets; track preset) {\r\n <button\r\n type=\"button\"\r\n class=\"appearance-none whitespace-nowrap rounded-sm border-0 bg-transparent px-2.5 py-1.5 text-start text-sm text-fg-muted transition-colors duration-fast ease-emphasis hover:bg-surface-alt\"\r\n (click)=\"applyPreset(preset)\"\r\n >\r\n {{ presetLabel(preset) }}\r\n </button>\r\n }\r\n </div>\r\n\r\n <div class=\"flex flex-col gap-2 p-3\">\r\n <div class=\"flex gap-4\">\r\n <mf-calendar\r\n mode=\"range\"\r\n [(month)]=\"monthLeft\"\r\n [rangeStart]=\"draftRange().start\"\r\n [rangeEnd]=\"draftRange().end\"\r\n [hoverEnd]=\"hoverEnd()\"\r\n [min]=\"min()\"\r\n [max]=\"max()\"\r\n [locale]=\"effectiveLocale()\"\r\n [labels]=\"effectiveLabels()\"\r\n (dayPick)=\"onDayPick($event)\"\r\n (dayHover)=\"onDayHover($event)\"\r\n />\r\n <div class=\"hidden sm:block\">\r\n <mf-calendar\r\n mode=\"range\"\r\n [month]=\"monthRight()\"\r\n [navigable]=\"false\"\r\n [rangeStart]=\"draftRange().start\"\r\n [rangeEnd]=\"draftRange().end\"\r\n [hoverEnd]=\"hoverEnd()\"\r\n [min]=\"min()\"\r\n [max]=\"max()\"\r\n [locale]=\"effectiveLocale()\"\r\n [labels]=\"effectiveLabels()\"\r\n (dayPick)=\"onDayPick($event)\"\r\n (dayHover)=\"onDayHover($event)\"\r\n />\r\n </div>\r\n </div>\r\n <div class=\"flex items-center justify-end gap-2 border-t border-border pt-2\">\r\n <button mfButton tone=\"neutral\" appearance=\"text\" size=\"sm\" type=\"button\" (click)=\"clear()\">\r\n {{ effectiveLabels().clear }}\r\n </button>\r\n <button\r\n mfButton\r\n tone=\"primary\"\r\n appearance=\"filled\"\r\n size=\"sm\"\r\n type=\"button\"\r\n [disabled]=\"!draftRange().start\"\r\n (click)=\"apply()\"\r\n >\r\n {{ effectiveLabels().apply }}\r\n </button>\r\n </div>\r\n </div>\r\n </mf-popover>\r\n</div>\r\n" }]
636
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], hasError: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasError", required: false }] }], startEl: [{ type: i0.ViewChild, args: ['startEl', { isSignal: true }] }] } });
637
+
638
+ /**
639
+ * Generated bundle index. Do not edit.
640
+ */
641
+
642
+ export { Calendar, DatePicker, DateRangePicker, buildMonthMatrix, dateRangeForPreset, formatDateInput, isCurrentMonth, isDayDisabled, isSameDay, isWithinRange, parseDateInput, shiftMonth, shiftYear };
643
+ //# sourceMappingURL=mesgflow-ui-kit-date-picker.mjs.map