@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,154 @@
1
+ import * as i0 from '@angular/core';
2
+ import { model, input, inject, computed, signal, viewChild, effect, untracked, forwardRef, Component } from '@angular/core';
3
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
4
+ import { ValueAccessorBase, MF_SEARCH_INPUT_LABELS } from '@mesgflow/ui-kit/core';
5
+ import { Icon } from '@mesgflow/ui-kit/icon';
6
+ import { Input } from '@mesgflow/ui-kit/input';
7
+ import { Tooltip } from '@mesgflow/ui-kit/tooltip';
8
+
9
+ /**
10
+ * `<mf-search-input [(value)]="term" [loading]="fetching()" placeholder="Ara..." />`
11
+ *
12
+ * Kapalıyken sadece bir ikon-buton genişliğinde (ikon tıklanabilir/odaklanabilir
13
+ * — hem mouse hem klavye ile genişliyor), odak alınca/tıklanınca genişliyor.
14
+ * Yazarken debounce süresi boyunca VE (varsa) dışarıdan verilen `loading`
15
+ * true olduğu sürece dönen bir spinner gösteriyor — "arıyor" hissi debounce
16
+ * bitiminde kaybolmuyor, gerçek sorgu sonucu gelene kadar sürüyor.
17
+ *
18
+ * Component (directive değil) — Field/Switch gibi gerçek iç yapı (ikon+input+
19
+ * temizle butonu+genişleme animasyonu) gerektiriyor (bkz. projects/ui-kit/README.md
20
+ * "Directive mi, component mi?").
21
+ */
22
+ class SearchInput extends ValueAccessorBase {
23
+ value = model('', /* @ts-ignore */
24
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
25
+ placeholder = input(/* @ts-ignore */
26
+ ...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ []));
27
+ ariaLabel = input(/* @ts-ignore */
28
+ ...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
29
+ tooltipLabel = input(/* @ts-ignore */
30
+ ...(ngDevMode ? [undefined, { debugName: "tooltipLabel" }] : /* istanbul ignore next */ []));
31
+ /** Tüketicinin gerçek veri çekme durumu — debounce bittikten sonra da spinner'ı sürdürür. */
32
+ loading = input(false, /* @ts-ignore */
33
+ ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
34
+ debounceMs = input(300, /* @ts-ignore */
35
+ ...(ngDevMode ? [{ debugName: "debounceMs" }] : /* istanbul ignore next */ []));
36
+ /**
37
+ * `false` → her zaman tam genişlikte açık, ikon tıklanabilir bir "kapı"
38
+ * değil (bkz. `table/table.ts` — bir VERİ TABLOSUNDA arama gizlenmez,
39
+ * bu bir navbar deseni; Table `[collapsible]="false"` geçiyor).
40
+ * Varsayılan `true` — bu bileşenin bugünkü tek gerçek davranışı, henüz
41
+ * başka bir tüketici yok ama gelecekte navbar/toolbar gibi dar bağlamlarda
42
+ * ihtiyaç olabilir diye korunuyor.
43
+ */
44
+ collapsible = input(true, /* @ts-ignore */
45
+ ...(ngDevMode ? [{ debugName: "collapsible" }] : /* istanbul ignore next */ []));
46
+ /**
47
+ * `true` → kutu sabit `w-64` (256px) yerine kapsayıcısının TAM genişliğinde
48
+ * açılır — kutunun panelin geri kalanıyla (ör. yan yana duran bir sekme
49
+ * listesiyle) aynı genişlikte hizalanması gereken bağlamlar için.
50
+ * `collapsible` ile birlikte anlamlı (`[collapsible]="false"` olmadan
51
+ * daralmış hâl `w-10` sabit kalır, `fullWidth` sadece GENİŞLEMİŞ genişliği
52
+ * değiştirir). Varsayılan `false` — navbar/toolbar'daki bugünkü sabit
53
+ * genişlik davranışı değişmez.
54
+ */
55
+ fullWidth = input(false, /* @ts-ignore */
56
+ ...(ngDevMode ? [{ debugName: "fullWidth" }] : /* istanbul ignore next */ []));
57
+ searchInputLabels = inject(MF_SEARCH_INPUT_LABELS);
58
+ effectivePlaceholder = computed(() => this.placeholder() ?? this.searchInputLabels().placeholder, /* @ts-ignore */
59
+ ...(ngDevMode ? [{ debugName: "effectivePlaceholder" }] : /* istanbul ignore next */ []));
60
+ effectiveAriaLabel = computed(() => this.ariaLabel() ?? this.searchInputLabels().ariaLabel, /* @ts-ignore */
61
+ ...(ngDevMode ? [{ debugName: "effectiveAriaLabel" }] : /* istanbul ignore next */ []));
62
+ effectiveTooltipLabel = computed(() => this.tooltipLabel() ?? this.searchInputLabels().ariaLabel, /* @ts-ignore */
63
+ ...(ngDevMode ? [{ debugName: "effectiveTooltipLabel" }] : /* istanbul ignore next */ []));
64
+ effectiveClearAriaLabel = computed(() => this.searchInputLabels().clearAriaLabel, /* @ts-ignore */
65
+ ...(ngDevMode ? [{ debugName: "effectiveClearAriaLabel" }] : /* istanbul ignore next */ []));
66
+ expandedState = signal(false, /* @ts-ignore */
67
+ ...(ngDevMode ? [{ debugName: "expandedState" }] : /* istanbul ignore next */ []));
68
+ /** `collapsible()` false ise HER ZAMAN true — genişleme mekaniği devre dışı kalır ama `expandedState` yine de "odaklanınca tooltip'i kapat" gibi yan mantık için iç durumu takip etmeye devam eder. */
69
+ expanded = computed(() => !this.collapsible() || this.expandedState(), /* @ts-ignore */
70
+ ...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
71
+ /** `w-64`/`w-10` yerine `w-full` — bkz. `fullWidth` doc yorumu. */
72
+ inputWidthClass = computed(() => this.fullWidth()
73
+ ? 'w-full cursor-text pe-8 ps-9'
74
+ : this.expanded()
75
+ ? 'w-64 cursor-text pe-8 ps-9'
76
+ : 'w-10 cursor-pointer caret-transparent pe-2 ps-9', /* @ts-ignore */
77
+ ...(ngDevMode ? [{ debugName: "inputWidthClass" }] : /* istanbul ignore next */ []));
78
+ draft = signal('', /* @ts-ignore */
79
+ ...(ngDevMode ? [{ debugName: "draft" }] : /* istanbul ignore next */ []));
80
+ pending = signal(false, /* @ts-ignore */
81
+ ...(ngDevMode ? [{ debugName: "pending" }] : /* istanbul ignore next */ []));
82
+ showSpinner = computed(() => this.pending() || this.loading(), /* @ts-ignore */
83
+ ...(ngDevMode ? [{ debugName: "showSpinner" }] : /* istanbul ignore next */ []));
84
+ inputEl = viewChild('inputEl', /* @ts-ignore */
85
+ ...(ngDevMode ? [{ debugName: "inputEl" }] : /* istanbul ignore next */ []));
86
+ tooltipRef = viewChild(Tooltip, /* @ts-ignore */
87
+ ...(ngDevMode ? [{ debugName: "tooltipRef" }] : /* istanbul ignore next */ []));
88
+ debounceHandle;
89
+ constructor() {
90
+ super();
91
+ // Dışarıdan (ör. "Filtreleri temizle") value() sıfırlanırsa draft de eşlensin.
92
+ effect(() => {
93
+ const current = this.value();
94
+ untracked(() => this.draft.set(current));
95
+ });
96
+ }
97
+ writeValue(value) {
98
+ this.value.set(value);
99
+ }
100
+ expand() {
101
+ this.expandedState.set(true);
102
+ // Tooltip'in kendi `(focus)` dinleyicisi AYNI olayda tetiklendiğinden
103
+ // ("Ara..." balonu) genişlemiş, placeholder'ı zaten aynı metni gösteren
104
+ // input'un üstünde gereksiz kalıyordu — anında kapatılıyor (gerçek bulgu).
105
+ this.tooltipRef()?.hide();
106
+ }
107
+ collapseIfEmpty() {
108
+ if (!this.draft().trim())
109
+ this.expandedState.set(false);
110
+ }
111
+ onInput(raw) {
112
+ this.draft.set(raw);
113
+ this.pending.set(true);
114
+ this.onTouched();
115
+ clearTimeout(this.debounceHandle);
116
+ this.debounceHandle = setTimeout(() => {
117
+ this.pending.set(false);
118
+ this.value.set(raw);
119
+ this.onChange(raw);
120
+ }, this.debounceMs());
121
+ }
122
+ clear() {
123
+ clearTimeout(this.debounceHandle);
124
+ this.pending.set(false);
125
+ this.draft.set('');
126
+ this.value.set('');
127
+ this.onChange('');
128
+ this.onTouched();
129
+ this.inputEl()?.nativeElement.focus();
130
+ }
131
+ onEscape() {
132
+ if (this.draft())
133
+ this.clear();
134
+ else
135
+ this.inputEl()?.nativeElement.blur();
136
+ }
137
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SearchInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
138
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SearchInput, isStandalone: true, selector: "mf-search-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, tooltipLabel: { classPropertyName: "tooltipLabel", publicName: "tooltipLabel", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, debounceMs: { classPropertyName: "debounceMs", publicName: "debounceMs", isSignal: true, isRequired: false, transformFunction: null }, collapsible: { classPropertyName: "collapsible", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { properties: { "class.w-full": "fullWidth()" }, classAttribute: "inline-block" }, providers: [
139
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SearchInput), multi: true },
140
+ ], viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["inputEl"], descendants: true, isSignal: true }, { propertyName: "tooltipRef", first: true, predicate: Tooltip, descendants: true, isSignal: true }], exportAs: ["mfSearchInput"], usesInheritance: true, ngImport: i0, template: "<div class=\"relative inline-flex items-center\" [class.w-full]=\"fullWidth()\">\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 [class.animate-spin]=\"showSpinner()\"\r\n >{{ showSpinner() ? 'progress_activity' : 'search' }}</span\r\n >\r\n <input\r\n mfInput\r\n #inputEl\r\n type=\"text\"\r\n [class]=\"inputWidthClass()\"\r\n class=\"transition-[width] duration-base ease-out\"\r\n [value]=\"draft()\"\r\n [placeholder]=\"expanded() ? effectivePlaceholder() : ''\"\r\n [attr.aria-label]=\"effectiveAriaLabel()\"\r\n [mfTooltip]=\"expanded() ? '' : effectiveTooltipLabel()\"\r\n (focus)=\"expand()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (blur)=\"collapseIfEmpty()\"\r\n (keydown.escape)=\"onEscape()\"\r\n />\r\n @if (expanded() && draft()) {\r\n <button\r\n type=\"button\"\r\n class=\"absolute top-1/2 end-2 -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 (click)=\"clear()\"\r\n [attr.aria-label]=\"effectiveClearAriaLabel()\"\r\n >\r\n <span mfIcon [size]=\"16\">close</span>\r\n </button>\r\n }\r\n</div>\r\n", dependencies: [{ 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: "directive", type: Tooltip, selector: "[mfTooltip], [mfTooltipContent]", inputs: ["mfTooltip", "mfTooltipContent", "tooltipPosition"], exportAs: ["mfTooltip"] }] });
141
+ }
142
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SearchInput, decorators: [{
143
+ type: Component,
144
+ args: [{ selector: 'mf-search-input', exportAs: 'mfSearchInput', imports: [Icon, Input, Tooltip], host: { class: 'inline-block', '[class.w-full]': 'fullWidth()' }, providers: [
145
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SearchInput), multi: true },
146
+ ], template: "<div class=\"relative inline-flex items-center\" [class.w-full]=\"fullWidth()\">\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 [class.animate-spin]=\"showSpinner()\"\r\n >{{ showSpinner() ? 'progress_activity' : 'search' }}</span\r\n >\r\n <input\r\n mfInput\r\n #inputEl\r\n type=\"text\"\r\n [class]=\"inputWidthClass()\"\r\n class=\"transition-[width] duration-base ease-out\"\r\n [value]=\"draft()\"\r\n [placeholder]=\"expanded() ? effectivePlaceholder() : ''\"\r\n [attr.aria-label]=\"effectiveAriaLabel()\"\r\n [mfTooltip]=\"expanded() ? '' : effectiveTooltipLabel()\"\r\n (focus)=\"expand()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (blur)=\"collapseIfEmpty()\"\r\n (keydown.escape)=\"onEscape()\"\r\n />\r\n @if (expanded() && draft()) {\r\n <button\r\n type=\"button\"\r\n class=\"absolute top-1/2 end-2 -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 (click)=\"clear()\"\r\n [attr.aria-label]=\"effectiveClearAriaLabel()\"\r\n >\r\n <span mfIcon [size]=\"16\">close</span>\r\n </button>\r\n }\r\n</div>\r\n" }]
147
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], tooltipLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipLabel", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], debounceMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "debounceMs", required: false }] }], collapsible: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], inputEl: [{ type: i0.ViewChild, args: ['inputEl', { isSignal: true }] }], tooltipRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => Tooltip), { isSignal: true }] }] } });
148
+
149
+ /**
150
+ * Generated bundle index. Do not edit.
151
+ */
152
+
153
+ export { SearchInput };
154
+ //# sourceMappingURL=mesgflow-ui-kit-search-input.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesgflow-ui-kit-search-input.mjs","sources":["../../../projects/ui-kit/search-input/search-input.ts","../../../projects/ui-kit/search-input/search-input.html","../../../projects/ui-kit/search-input/mesgflow-ui-kit-search-input.ts"],"sourcesContent":["import {\r\n Component,\r\n ElementRef,\r\n computed,\r\n effect,\r\n forwardRef,\r\n inject,\r\n input,\r\n model,\r\n signal,\r\n untracked,\r\n viewChild,\r\n} from '@angular/core';\r\nimport { NG_VALUE_ACCESSOR, type ControlValueAccessor } from '@angular/forms';\r\nimport { MF_SEARCH_INPUT_LABELS, ValueAccessorBase } from '@mesgflow/ui-kit/core';\r\nimport { Icon } from '@mesgflow/ui-kit/icon';\r\nimport { Input } from '@mesgflow/ui-kit/input';\r\nimport { Tooltip } from '@mesgflow/ui-kit/tooltip';\r\n\r\n/**\r\n * `<mf-search-input [(value)]=\"term\" [loading]=\"fetching()\" placeholder=\"Ara...\" />`\r\n *\r\n * Kapalıyken sadece bir ikon-buton genişliğinde (ikon tıklanabilir/odaklanabilir\r\n * — hem mouse hem klavye ile genişliyor), odak alınca/tıklanınca genişliyor.\r\n * Yazarken debounce süresi boyunca VE (varsa) dışarıdan verilen `loading`\r\n * true olduğu sürece dönen bir spinner gösteriyor — \"arıyor\" hissi debounce\r\n * bitiminde kaybolmuyor, gerçek sorgu sonucu gelene kadar sürüyor.\r\n *\r\n * Component (directive değil) — Field/Switch gibi gerçek iç yapı (ikon+input+\r\n * temizle butonu+genişleme animasyonu) gerektiriyor (bkz. projects/ui-kit/README.md\r\n * \"Directive mi, component mi?\").\r\n */\r\n@Component({\r\n selector: 'mf-search-input',\r\n exportAs: 'mfSearchInput',\r\n imports: [Icon, Input, Tooltip],\r\n host: { class: 'inline-block', '[class.w-full]': 'fullWidth()' },\r\n templateUrl: './search-input.html',\r\n providers: [\r\n { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SearchInput), multi: true },\r\n ],\r\n})\r\nexport class SearchInput extends ValueAccessorBase<string> implements ControlValueAccessor {\r\n readonly value = model('');\r\n readonly placeholder = input<string>();\r\n readonly ariaLabel = input<string>();\r\n readonly tooltipLabel = input<string>();\r\n /** Tüketicinin gerçek veri çekme durumu — debounce bittikten sonra da spinner'ı sürdürür. */\r\n readonly loading = input(false);\r\n readonly debounceMs = input(300);\r\n /**\r\n * `false` → her zaman tam genişlikte açık, ikon tıklanabilir bir \"kapı\"\r\n * değil (bkz. `table/table.ts` — bir VERİ TABLOSUNDA arama gizlenmez,\r\n * bu bir navbar deseni; Table `[collapsible]=\"false\"` geçiyor).\r\n * Varsayılan `true` — bu bileşenin bugünkü tek gerçek davranışı, henüz\r\n * başka bir tüketici yok ama gelecekte navbar/toolbar gibi dar bağlamlarda\r\n * ihtiyaç olabilir diye korunuyor.\r\n */\r\n readonly collapsible = input(true);\r\n /**\r\n * `true` → kutu sabit `w-64` (256px) yerine kapsayıcısının TAM genişliğinde\r\n * açılır — kutunun panelin geri kalanıyla (ör. yan yana duran bir sekme\r\n * listesiyle) aynı genişlikte hizalanması gereken bağlamlar için.\r\n * `collapsible` ile birlikte anlamlı (`[collapsible]=\"false\"` olmadan\r\n * daralmış hâl `w-10` sabit kalır, `fullWidth` sadece GENİŞLEMİŞ genişliği\r\n * değiştirir). Varsayılan `false` — navbar/toolbar'daki bugünkü sabit\r\n * genişlik davranışı değişmez.\r\n */\r\n readonly fullWidth = input(false);\r\n\r\n private readonly searchInputLabels = inject(MF_SEARCH_INPUT_LABELS);\r\n protected readonly effectivePlaceholder = computed(\r\n () => this.placeholder() ?? this.searchInputLabels().placeholder,\r\n );\r\n protected readonly effectiveAriaLabel = computed(\r\n () => this.ariaLabel() ?? this.searchInputLabels().ariaLabel,\r\n );\r\n protected readonly effectiveTooltipLabel = computed(\r\n () => this.tooltipLabel() ?? this.searchInputLabels().ariaLabel,\r\n );\r\n protected readonly effectiveClearAriaLabel = computed(\r\n () => this.searchInputLabels().clearAriaLabel,\r\n );\r\n\r\n private readonly expandedState = signal(false);\r\n /** `collapsible()` false ise HER ZAMAN true — genişleme mekaniği devre dışı kalır ama `expandedState` yine de \"odaklanınca tooltip'i kapat\" gibi yan mantık için iç durumu takip etmeye devam eder. */\r\n protected readonly expanded = computed(() => !this.collapsible() || this.expandedState());\r\n /** `w-64`/`w-10` yerine `w-full` — bkz. `fullWidth` doc yorumu. */\r\n protected readonly inputWidthClass = computed(() =>\r\n this.fullWidth()\r\n ? 'w-full cursor-text pe-8 ps-9'\r\n : this.expanded()\r\n ? 'w-64 cursor-text pe-8 ps-9'\r\n : 'w-10 cursor-pointer caret-transparent pe-2 ps-9',\r\n );\r\n protected readonly draft = signal('');\r\n protected readonly pending = signal(false);\r\n protected readonly showSpinner = computed(() => this.pending() || this.loading());\r\n\r\n private readonly inputEl = viewChild<ElementRef<HTMLInputElement>>('inputEl');\r\n private readonly tooltipRef = viewChild(Tooltip);\r\n private debounceHandle?: ReturnType<typeof setTimeout>;\r\n\r\n constructor() {\r\n super();\r\n // Dışarıdan (ör. \"Filtreleri temizle\") value() sıfırlanırsa draft de eşlensin.\r\n effect(() => {\r\n const current = this.value();\r\n untracked(() => this.draft.set(current));\r\n });\r\n }\r\n\r\n writeValue(value: string): void {\r\n this.value.set(value);\r\n }\r\n\r\n protected expand(): void {\r\n this.expandedState.set(true);\r\n // Tooltip'in kendi `(focus)` dinleyicisi AYNI olayda tetiklendiğinden\r\n // (\"Ara...\" balonu) genişlemiş, placeholder'ı zaten aynı metni gösteren\r\n // input'un üstünde gereksiz kalıyordu — anında kapatılıyor (gerçek bulgu).\r\n this.tooltipRef()?.hide();\r\n }\r\n\r\n protected collapseIfEmpty(): void {\r\n if (!this.draft().trim()) this.expandedState.set(false);\r\n }\r\n\r\n protected onInput(raw: string): void {\r\n this.draft.set(raw);\r\n this.pending.set(true);\r\n this.onTouched();\r\n clearTimeout(this.debounceHandle);\r\n this.debounceHandle = setTimeout(() => {\r\n this.pending.set(false);\r\n this.value.set(raw);\r\n this.onChange(raw);\r\n }, this.debounceMs());\r\n }\r\n\r\n protected clear(): void {\r\n clearTimeout(this.debounceHandle);\r\n this.pending.set(false);\r\n this.draft.set('');\r\n this.value.set('');\r\n this.onChange('');\r\n this.onTouched();\r\n this.inputEl()?.nativeElement.focus();\r\n }\r\n\r\n protected onEscape(): void {\r\n if (this.draft()) this.clear();\r\n else this.inputEl()?.nativeElement.blur();\r\n }\r\n}\r\n","<div class=\"relative inline-flex items-center\" [class.w-full]=\"fullWidth()\">\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 [class.animate-spin]=\"showSpinner()\"\r\n >{{ showSpinner() ? 'progress_activity' : 'search' }}</span\r\n >\r\n <input\r\n mfInput\r\n #inputEl\r\n type=\"text\"\r\n [class]=\"inputWidthClass()\"\r\n class=\"transition-[width] duration-base ease-out\"\r\n [value]=\"draft()\"\r\n [placeholder]=\"expanded() ? effectivePlaceholder() : ''\"\r\n [attr.aria-label]=\"effectiveAriaLabel()\"\r\n [mfTooltip]=\"expanded() ? '' : effectiveTooltipLabel()\"\r\n (focus)=\"expand()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (blur)=\"collapseIfEmpty()\"\r\n (keydown.escape)=\"onEscape()\"\r\n />\r\n @if (expanded() && draft()) {\r\n <button\r\n type=\"button\"\r\n class=\"absolute top-1/2 end-2 -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 (click)=\"clear()\"\r\n [attr.aria-label]=\"effectiveClearAriaLabel()\"\r\n >\r\n <span mfIcon [size]=\"16\">close</span>\r\n </button>\r\n }\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ import { Toolbar, ToolbarWidgetGroup, ToolbarWidget } from '@angular/aria/toolbar';
2
+ import * as i0 from '@angular/core';
3
+ import { input, model, computed, forwardRef, Component } from '@angular/core';
4
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
5
+ import { ValueAccessorBase, cn } from '@mesgflow/ui-kit/core';
6
+ import { cva } from 'class-variance-authority';
7
+
8
+ const segmentedTrackVariants = cva('inline-flex items-center gap-0.5 rounded-md bg-surface-alt p-0.5', {
9
+ variants: {
10
+ size: {
11
+ sm: 'text-xs',
12
+ md: 'text-sm',
13
+ },
14
+ },
15
+ defaultVariants: { size: 'md' },
16
+ });
17
+ const segmentedItemVariants = cva('cursor-pointer appearance-none whitespace-nowrap rounded-sm border-0 bg-transparent px-2.5 py-1 text-fg-muted transition-colors duration-fast ease-emphasis active:scale-[0.99] ' +
18
+ 'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring', {
19
+ variants: {
20
+ selected: {
21
+ true: 'bg-surface text-fg shadow-1',
22
+ false: 'hover:text-fg',
23
+ },
24
+ disabled: {
25
+ true: 'pointer-events-none opacity-50 active:scale-100',
26
+ false: '',
27
+ },
28
+ },
29
+ defaultVariants: { selected: false, disabled: false },
30
+ });
31
+
32
+ /**
33
+ * `<mf-segmented-control [options]="opts" [(value)]="mode" />` — hizalama,
34
+ * cihaz önizlemesi gibi KISA/tek-seçimli seçenek kümeleri için. `Tabs`'tan
35
+ * farkı: içerik paneli YOK, sadece bir değer seçimi. ARIA/klavye (roving
36
+ * tabindex, ok tuşu navigasyonu) `@angular/aria/toolbar`'ın
37
+ * `Toolbar`/`ToolbarWidgetGroup`/`ToolbarWidget` pattern'inden geliyor —
38
+ * dokümantasyondaki kompozisyon şekli birebir izlendi (dıştaki `ngToolbar`,
39
+ * içteki `ngToolbarWidgetGroup [multi]="false"`).
40
+ */
41
+ class SegmentedControl extends ValueAccessorBase {
42
+ options = input.required(/* @ts-ignore */
43
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
44
+ value = model(null, /* @ts-ignore */
45
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
46
+ size = input('md', /* @ts-ignore */
47
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
48
+ ariaLabel = input('', /* @ts-ignore */
49
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
50
+ disabled = input(false, /* @ts-ignore */
51
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
52
+ toolbarValue = computed(() => this.value() == null ? [] : [this.value()], /* @ts-ignore */
53
+ ...(ngDevMode ? [{ debugName: "toolbarValue" }] : /* istanbul ignore next */ []));
54
+ trackClasses = computed(() => cn(segmentedTrackVariants({ size: this.size() })), /* @ts-ignore */
55
+ ...(ngDevMode ? [{ debugName: "trackClasses" }] : /* istanbul ignore next */ []));
56
+ writeValue(value) {
57
+ this.value.set(value);
58
+ }
59
+ /**
60
+ * `@angular/aria/toolbar`'ın kendi widget-kayıt döngüsü, gerçek bir tıklama
61
+ * OLMADAN da BOŞ bir dizi ile (`values: []`) tetiklenebiliyor (gerçek bulgu
62
+ * — bir seçeneğe tıklarken bile araya giren, seçimle ilgisiz iç kayıt
63
+ * event'leri). `this.value` her event'te güncellenir (görsel durum ETKİLENMEZ,
64
+ * zaten `values[0]` genelde mevcut değerle AYNI), ama CVA `onChange`/`onTouched`
65
+ * SADECE dolu bir dizi (gerçek bir seçim) geldiğinde tetiklenir — aksi halde
66
+ * Reactive Forms'a sahte "null'a değişti" bildirimleri sızardı.
67
+ */
68
+ onToolbarValueChange(values) {
69
+ this.value.set(values[0] ?? null);
70
+ if (values.length > 0) {
71
+ this.onChange(values[0]);
72
+ this.onTouched();
73
+ }
74
+ }
75
+ itemClasses(option) {
76
+ return cn(segmentedItemVariants({ selected: option.value === this.value(), disabled: this.disabled() }));
77
+ }
78
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SegmentedControl, deps: null, target: i0.ɵɵFactoryTarget.Component });
79
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SegmentedControl, isStandalone: true, selector: "mf-segmented-control", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { classAttribute: "inline-block" }, providers: [
80
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SegmentedControl), multi: true },
81
+ ], exportAs: ["mfSegmentedControl"], usesInheritance: true, ngImport: i0, template: "<div\r\n ngToolbar\r\n [disabled]=\"disabled()\"\r\n [value]=\"toolbarValue()\"\r\n (valueChange)=\"onToolbarValueChange($event)\"\r\n [attr.aria-label]=\"ariaLabel() || null\"\r\n [class]=\"trackClasses()\"\r\n>\r\n <div ngToolbarWidgetGroup [multi]=\"false\" [disabled]=\"disabled()\" class=\"contents\">\r\n @for (option of options(); track option.value) {\r\n <button type=\"button\" ngToolbarWidget [value]=\"option.value\" [class]=\"itemClasses(option)\">\r\n {{ option.label }}\r\n </button>\r\n }\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "directive", type: Toolbar, selector: "[ngToolbar]", inputs: ["orientation", "softDisabled", "disabled", "wrap", "value"], outputs: ["valueChange"], exportAs: ["ngToolbar"] }, { kind: "directive", type: ToolbarWidgetGroup, selector: "[ngToolbarWidgetGroup]", inputs: ["disabled", "multi"], exportAs: ["ngToolbarWidgetGroup"] }, { kind: "directive", type: ToolbarWidget, selector: "[ngToolbarWidget]", inputs: ["id", "disabled", "value"], exportAs: ["ngToolbarWidget"] }] });
82
+ }
83
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SegmentedControl, decorators: [{
84
+ type: Component,
85
+ args: [{ selector: 'mf-segmented-control', exportAs: 'mfSegmentedControl', imports: [Toolbar, ToolbarWidgetGroup, ToolbarWidget], host: { class: 'inline-block' }, providers: [
86
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SegmentedControl), multi: true },
87
+ ], template: "<div\r\n ngToolbar\r\n [disabled]=\"disabled()\"\r\n [value]=\"toolbarValue()\"\r\n (valueChange)=\"onToolbarValueChange($event)\"\r\n [attr.aria-label]=\"ariaLabel() || null\"\r\n [class]=\"trackClasses()\"\r\n>\r\n <div ngToolbarWidgetGroup [multi]=\"false\" [disabled]=\"disabled()\" class=\"contents\">\r\n @for (option of options(); track option.value) {\r\n <button type=\"button\" ngToolbarWidget [value]=\"option.value\" [class]=\"itemClasses(option)\">\r\n {{ option.label }}\r\n </button>\r\n }\r\n </div>\r\n</div>\r\n" }]
88
+ }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
89
+
90
+ /**
91
+ * Generated bundle index. Do not edit.
92
+ */
93
+
94
+ export { SegmentedControl, segmentedItemVariants, segmentedTrackVariants };
95
+ //# sourceMappingURL=mesgflow-ui-kit-segmented-control.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesgflow-ui-kit-segmented-control.mjs","sources":["../../../projects/ui-kit/segmented-control/segmented-control.variants.ts","../../../projects/ui-kit/segmented-control/segmented-control.ts","../../../projects/ui-kit/segmented-control/segmented-control.html","../../../projects/ui-kit/segmented-control/mesgflow-ui-kit-segmented-control.ts"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nexport const segmentedTrackVariants = cva(\r\n 'inline-flex items-center gap-0.5 rounded-md bg-surface-alt p-0.5',\r\n {\r\n variants: {\r\n size: {\r\n sm: 'text-xs',\r\n md: 'text-sm',\r\n },\r\n },\r\n defaultVariants: { size: 'md' },\r\n },\r\n);\r\n\r\nexport const segmentedItemVariants = cva(\r\n 'cursor-pointer appearance-none whitespace-nowrap rounded-sm border-0 bg-transparent px-2.5 py-1 text-fg-muted transition-colors duration-fast ease-emphasis active:scale-[0.99] ' +\r\n 'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring',\r\n {\r\n variants: {\r\n selected: {\r\n true: 'bg-surface text-fg shadow-1',\r\n false: 'hover:text-fg',\r\n },\r\n disabled: {\r\n true: 'pointer-events-none opacity-50 active:scale-100',\r\n false: '',\r\n },\r\n },\r\n defaultVariants: { selected: false, disabled: false },\r\n },\r\n);\r\n\r\nexport type SegmentedControlSize = VariantProps<typeof segmentedTrackVariants>['size'];\r\n","import {\r\n Toolbar as AriaToolbar,\r\n ToolbarWidget as AriaToolbarWidget,\r\n ToolbarWidgetGroup as AriaToolbarWidgetGroup,\r\n} from '@angular/aria/toolbar';\r\nimport { Component, computed, forwardRef, input, model } from '@angular/core';\r\nimport { NG_VALUE_ACCESSOR, type ControlValueAccessor } from '@angular/forms';\r\nimport { ValueAccessorBase, cn } from '@mesgflow/ui-kit/core';\r\nimport {\r\n segmentedItemVariants,\r\n segmentedTrackVariants,\r\n type SegmentedControlSize,\r\n} from './segmented-control.variants';\r\n\r\nexport interface SegmentedOption<T> {\r\n label: string;\r\n value: T;\r\n}\r\n\r\n/**\r\n * `<mf-segmented-control [options]=\"opts\" [(value)]=\"mode\" />` — hizalama,\r\n * cihaz önizlemesi gibi KISA/tek-seçimli seçenek kümeleri için. `Tabs`'tan\r\n * farkı: içerik paneli YOK, sadece bir değer seçimi. ARIA/klavye (roving\r\n * tabindex, ok tuşu navigasyonu) `@angular/aria/toolbar`'ın\r\n * `Toolbar`/`ToolbarWidgetGroup`/`ToolbarWidget` pattern'inden geliyor —\r\n * dokümantasyondaki kompozisyon şekli birebir izlendi (dıştaki `ngToolbar`,\r\n * içteki `ngToolbarWidgetGroup [multi]=\"false\"`).\r\n */\r\n@Component({\r\n selector: 'mf-segmented-control',\r\n exportAs: 'mfSegmentedControl',\r\n imports: [AriaToolbar, AriaToolbarWidgetGroup, AriaToolbarWidget],\r\n host: { class: 'inline-block' },\r\n templateUrl: './segmented-control.html',\r\n providers: [\r\n { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SegmentedControl), multi: true },\r\n ],\r\n})\r\nexport class SegmentedControl<T>\r\n extends ValueAccessorBase<T | null>\r\n implements ControlValueAccessor\r\n{\r\n readonly options = input.required<SegmentedOption<T>[]>();\r\n readonly value = model<T | null>(null);\r\n readonly size = input<SegmentedControlSize>('md');\r\n readonly ariaLabel = input('');\r\n readonly disabled = input(false);\r\n\r\n protected readonly toolbarValue = computed<T[]>(() =>\r\n this.value() == null ? [] : [this.value() as T],\r\n );\r\n protected readonly trackClasses = computed(() =>\r\n cn(segmentedTrackVariants({ size: this.size() })),\r\n );\r\n\r\n writeValue(value: T | null): void {\r\n this.value.set(value);\r\n }\r\n\r\n /**\r\n * `@angular/aria/toolbar`'ın kendi widget-kayıt döngüsü, gerçek bir tıklama\r\n * OLMADAN da BOŞ bir dizi ile (`values: []`) tetiklenebiliyor (gerçek bulgu\r\n * — bir seçeneğe tıklarken bile araya giren, seçimle ilgisiz iç kayıt\r\n * event'leri). `this.value` her event'te güncellenir (görsel durum ETKİLENMEZ,\r\n * zaten `values[0]` genelde mevcut değerle AYNI), ama CVA `onChange`/`onTouched`\r\n * SADECE dolu bir dizi (gerçek bir seçim) geldiğinde tetiklenir — aksi halde\r\n * Reactive Forms'a sahte \"null'a değişti\" bildirimleri sızardı.\r\n */\r\n protected onToolbarValueChange(values: readonly T[]): void {\r\n this.value.set(values[0] ?? null);\r\n if (values.length > 0) {\r\n this.onChange(values[0]!);\r\n this.onTouched();\r\n }\r\n }\r\n\r\n protected itemClasses(option: SegmentedOption<T>): string {\r\n return cn(\r\n segmentedItemVariants({ selected: option.value === this.value(), disabled: this.disabled() }),\r\n );\r\n }\r\n}\r\n","<div\r\n ngToolbar\r\n [disabled]=\"disabled()\"\r\n [value]=\"toolbarValue()\"\r\n (valueChange)=\"onToolbarValueChange($event)\"\r\n [attr.aria-label]=\"ariaLabel() || null\"\r\n [class]=\"trackClasses()\"\r\n>\r\n <div ngToolbarWidgetGroup [multi]=\"false\" [disabled]=\"disabled()\" class=\"contents\">\r\n @for (option of options(); track option.value) {\r\n <button type=\"button\" ngToolbarWidget [value]=\"option.value\" [class]=\"itemClasses(option)\">\r\n {{ option.label }}\r\n </button>\r\n }\r\n </div>\r\n</div>\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["AriaToolbar","AriaToolbarWidgetGroup","AriaToolbarWidget"],"mappings":";;;;;;;AAEO,MAAM,sBAAsB,GAAG,GAAG,CACvC,kEAAkE,EAClE;AACE,IAAA,QAAQ,EAAE;AACR,QAAA,IAAI,EAAE;AACJ,YAAA,EAAE,EAAE,SAAS;AACb,YAAA,EAAE,EAAE,SAAS;AACd,SAAA;AACF,KAAA;AACD,IAAA,eAAe,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;AAChC,CAAA;AAGI,MAAM,qBAAqB,GAAG,GAAG,CACtC,kLAAkL;AAChL,IAAA,+GAA+G,EACjH;AACE,IAAA,QAAQ,EAAE;AACR,QAAA,QAAQ,EAAE;AACR,YAAA,IAAI,EAAE,6BAA6B;AACnC,YAAA,KAAK,EAAE,eAAe;AACvB,SAAA;AACD,QAAA,QAAQ,EAAE;AACR,YAAA,IAAI,EAAE,iDAAiD;AACvD,YAAA,KAAK,EAAE,EAAE;AACV,SAAA;AACF,KAAA;IACD,eAAe,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE;AACtD,CAAA;;ACXH;;;;;;;;AAQG;AAWG,MAAO,gBACX,SAAQ,iBAA2B,CAAA;IAG1B,OAAO,GAAG,KAAK,CAAC,QAAQ;gFAAwB;IAChD,KAAK,GAAG,KAAK,CAAW,IAAI;8EAAC;IAC7B,IAAI,GAAG,KAAK,CAAuB,IAAI;6EAAC;IACxC,SAAS,GAAG,KAAK,CAAC,EAAE;kFAAC;IACrB,QAAQ,GAAG,KAAK,CAAC,KAAK;iFAAC;IAEb,YAAY,GAAG,QAAQ,CAAM,MAC9C,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,EAAO,CAAC;qFAChD;AACkB,IAAA,YAAY,GAAG,QAAQ,CAAC,MACzC,EAAE,CAAC,sBAAsB,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;qFAClD;AAED,IAAA,UAAU,CAAC,KAAe,EAAA;AACxB,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;IACvB;AAEA;;;;;;;;AAQG;AACO,IAAA,oBAAoB,CAAC,MAAoB,EAAA;AACjD,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACjC,QAAA,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;YACrB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC;YACzB,IAAI,CAAC,SAAS,EAAE;QAClB;IACF;AAEU,IAAA,WAAW,CAAC,MAA0B,EAAA;QAC9C,OAAO,EAAE,CACP,qBAAqB,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAC9F;IACH;uGA1CW,gBAAgB,EAAA,IAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAhB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,gBAAgB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,SAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,KAAA,EAAA,aAAA,EAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,cAAA,EAAA,EAAA,SAAA,EAJhB;AACT,YAAA,EAAE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,UAAU,CAAC,MAAM,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;AAC7F,SAAA,EAAA,QAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,eAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECpCH,kjBAgBA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDeYA,OAAW,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,cAAA,EAAA,UAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAAA,OAAA,EAAA,CAAA,aAAA,CAAA,EAAA,QAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAEC,kBAAsB,sIAAEC,aAAiB,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,IAAA,EAAA,UAAA,EAAA,OAAA,CAAA,EAAA,QAAA,EAAA,CAAA,iBAAA,CAAA,EAAA,CAAA,EAAA,CAAA;;2FAOrD,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAV5B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,sBAAsB,YACtB,oBAAoB,EAAA,OAAA,EACrB,CAACF,OAAW,EAAEC,kBAAsB,EAAEC,aAAiB,CAAC,QAC3D,EAAE,KAAK,EAAE,cAAc,EAAE,EAAA,SAAA,EAEpB;AACT,wBAAA,EAAE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,UAAU,CAAC,sBAAsB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;AAC7F,qBAAA,EAAA,QAAA,EAAA,kjBAAA,EAAA;;;AEpCH;;AAEG;;"}
@@ -0,0 +1,227 @@
1
+ import * as i1 from '@angular/cdk/overlay';
2
+ import { OverlayModule } from '@angular/cdk/overlay';
3
+ import * as i0 from '@angular/core';
4
+ import { input, model, inject, computed, signal, forwardRef, Component } from '@angular/core';
5
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
6
+ import { Chip } from '@mesgflow/ui-kit/chip';
7
+ import { Icon } from '@mesgflow/ui-kit/icon';
8
+ import { MF_SELECT_LABELS, cn } from '@mesgflow/ui-kit/core';
9
+ import { Popover } from '@mesgflow/ui-kit/popover';
10
+ import { cva } from 'class-variance-authority';
11
+
12
+ /**
13
+ * Bkz. `core/recipes.ts` `controlSurface` — aynı kabuk, tetikleyici bir
14
+ * <button>'a uygulanıyor. `focus:border-accent` — Input/Combobox'ın ZATEN
15
+ * sahip olduğu odak kenarlığı burada eksikti (gerçek bulgu): odaklı bir
16
+ * select yalnızca outline ile belli oluyordu, kenarlık aksanlanmıyordu.
17
+ */
18
+ const selectTriggerVariants = cva(
19
+ /*
20
+ * `appearance-none`: bkz. button.variants.ts'teki aynı gerekçe — sıfırlamazsan
21
+ * tarayıcının varsayılan `<button>` kenarlığı+dolgusu bu cva'nın
22
+ * border/padding'iyle ÜST ÜSTE biner (gerçek bulgu, ilk ekran görüntüsünde
23
+ * kolon başlıklarındaki sıralama butonları yanlışlıkla select kutusu gibi
24
+ * göründü).
25
+ */
26
+ 'inline-flex w-full appearance-none items-center justify-between gap-2 rounded-md border border-border bg-surface text-fg shadow-control ' +
27
+ 'transition-colors duration-fast ease-emphasis ' +
28
+ 'hover:border-border-strong ' +
29
+ 'focus:border-accent ' +
30
+ 'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring ' +
31
+ 'disabled:cursor-not-allowed disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none disabled:hover:border-border', {
32
+ variants: {
33
+ size: {
34
+ sm: 'h-control-sm px-2.5 text-sm',
35
+ md: 'h-control-md px-3 text-sm',
36
+ lg: 'h-control-lg px-3.5 text-base',
37
+ },
38
+ /** Input/NumberInput ile aynı emsal — `@angular/forms/signals` rezerve `invalid` yerine `hasError`. */
39
+ hasError: {
40
+ true: 'border-danger focus-visible:outline-danger',
41
+ false: '',
42
+ },
43
+ },
44
+ defaultVariants: { size: 'md', hasError: false },
45
+ });
46
+
47
+ /**
48
+ * `<mf-select [options]="opts" [(value)]="chosen" placeholder="Seç" />`
49
+ * (tek-seçimli, varsayılan) veya `<mf-select multiple [options]="opts"
50
+ * [(values)]="chosen" />` (çoklu-seçim — tetikleyici seçilenleri Chip
51
+ * özeti olarak gösterir, bir seçeneğe tıklamak paneli KAPATMAZ, tekrar
52
+ * tıklamak seçimi KALDIRIR).
53
+ *
54
+ * `multiple` AÇIKKEN `value`/`(valueChange)` KULLANILMAZ — ayrı bir
55
+ * `values: model<T[]>` var (bkz. aşağıda). İkisini AYIRMANIN sebebi:
56
+ * `value`'nun TİPİNİ (`T | null`) tek-seçimli kullanım için DEĞİŞTİRMEDEN
57
+ * bırakmak — mevcut tüm `[(value)]="tekTip"` tüketicileri (Table'ın alan/
58
+ * operatör/sayfa-boyutu seçicileri, TableFilterBar'ın VE/VEYA seçicisi)
59
+ * BİREBİR aynı tipte kalıyor, çoklu-seçim EKLENTİ, DEĞİŞİKLİK değil.
60
+ *
61
+ * Bu kitin ilk overlay tabanlı primitifi — native `<select>` değil,
62
+ * çünkü açılır panelin kendisi (arka plan/kenarlık/hover rengi) native
63
+ * `<select>` popup'ında tarayıcı-bağımlı ve stillenemez kalıyordu; CDK Overlay
64
+ * + kendi listbox'ımız panel dahil her pikseli bizim token sistemimizle
65
+ * boyayabiliyor. `@angular/cdk` zaten bağımlı, ek paket gerekmedi — pozisyonlama
66
+ * CSS'i `styles.css`'teki resmi `@angular/cdk/overlay-prebuilt.css`
67
+ * import'undan geliyor (bkz. o import'un yanındaki not).
68
+ *
69
+ * Arama/virtual-scroll YOK — Table'ın alan/operatör/sayfa-boyutu
70
+ * seçicileri gibi kısa listeler için kasıtlı olarak minimal.
71
+ */
72
+ class Select {
73
+ options = input.required(/* @ts-ignore */
74
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
75
+ value = model(null, /* @ts-ignore */
76
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
77
+ multiple = input(false, /* @ts-ignore */
78
+ ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
79
+ /** SADECE `multiple=true`'da kullanılır — bkz. sınıf üstündeki JSDoc. */
80
+ values = model([], /* @ts-ignore */
81
+ ...(ngDevMode ? [{ debugName: "values" }] : /* istanbul ignore next */ []));
82
+ maxVisibleChips = input(3, /* @ts-ignore */
83
+ ...(ngDevMode ? [{ debugName: "maxVisibleChips" }] : /* istanbul ignore next */ []));
84
+ placeholder = input(/* @ts-ignore */
85
+ ...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ []));
86
+ disabled = input(false, /* @ts-ignore */
87
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
88
+ size = input('md', /* @ts-ignore */
89
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
90
+ hasError = input(false, /* @ts-ignore */
91
+ ...(ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []));
92
+ ariaLabel = input('', /* @ts-ignore */
93
+ ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
94
+ // `ControlValueAccessor`'ın gerçek Angular arayüzü `any` kullanıyor (bkz.
95
+ // `@angular/forms`'un kendi tip tanımı) — burada `T | T[] | null` YAZMAK bu
96
+ // sözleşmeyi İHLAL ETMİYOR, sadece tek/çoklu iki modu TEK bir callback
97
+ // çiftinde (onChange/onTouched) taşımayı mümkün kılıyor.
98
+ onChange = () => { };
99
+ onTouched = () => { };
100
+ selectLabels = inject(MF_SELECT_LABELS);
101
+ effectivePlaceholder = computed(() => this.placeholder() ?? this.selectLabels().placeholder, /* @ts-ignore */
102
+ ...(ngDevMode ? [{ debugName: "effectivePlaceholder" }] : /* istanbul ignore next */ []));
103
+ open = signal(false, /* @ts-ignore */
104
+ ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
105
+ highlighted = signal(0, /* @ts-ignore */
106
+ ...(ngDevMode ? [{ debugName: "highlighted" }] : /* istanbul ignore next */ []));
107
+ triggerClasses = computed(() => cn(selectTriggerVariants({ size: this.size(), hasError: this.hasError() })), /* @ts-ignore */
108
+ ...(ngDevMode ? [{ debugName: "triggerClasses" }] : /* istanbul ignore next */ []));
109
+ selectedLabel = computed(() => {
110
+ const current = this.value();
111
+ return this.options().find((option) => option.value === current)?.label ?? '';
112
+ }, /* @ts-ignore */
113
+ ...(ngDevMode ? [{ debugName: "selectedLabel" }] : /* istanbul ignore next */ []));
114
+ selectedOptions = computed(() => {
115
+ if (!this.multiple())
116
+ return [];
117
+ const selected = new Set(this.values());
118
+ return this.options().filter((o) => selected.has(o.value));
119
+ }, /* @ts-ignore */
120
+ ...(ngDevMode ? [{ debugName: "selectedOptions" }] : /* istanbul ignore next */ []));
121
+ visibleChips = computed(() => this.selectedOptions().slice(0, this.maxVisibleChips()), /* @ts-ignore */
122
+ ...(ngDevMode ? [{ debugName: "visibleChips" }] : /* istanbul ignore next */ []));
123
+ overflowChipCount = computed(() => Math.max(0, this.selectedOptions().length - this.maxVisibleChips()), /* @ts-ignore */
124
+ ...(ngDevMode ? [{ debugName: "overflowChipCount" }] : /* istanbul ignore next */ []));
125
+ toggle() {
126
+ if (this.disabled())
127
+ return;
128
+ if (!this.open())
129
+ this.highlighted.set(Math.max(0, this.options().findIndex((o) => o.value === this.value())));
130
+ this.open.update((v) => !v);
131
+ }
132
+ close() {
133
+ this.open.set(false);
134
+ this.onTouched();
135
+ }
136
+ /** Tek-seçimli modda seçeneği commit eder VE paneli kapatır; çoklu-seçim modunda `toggleValue`'ya devreder (panel AÇIK kalır — bkz. `toggleValue`). */
137
+ select(option) {
138
+ if (this.multiple()) {
139
+ this.toggleValue(option.value);
140
+ return;
141
+ }
142
+ this.value.set(option.value);
143
+ this.onChange(option.value);
144
+ this.close();
145
+ }
146
+ /** Çoklu-seçimde bir değeri ekler/çıkarır — panel KAPANMAZ, kullanıcı birden fazla seçim yapabilir (Escape/dışarı tıklama ile kapatır). */
147
+ toggleValue(v) {
148
+ const current = this.values();
149
+ const next = current.includes(v) ? current.filter((x) => x !== v) : [...current, v];
150
+ this.values.set(next);
151
+ this.onChange(next);
152
+ this.onTouched();
153
+ }
154
+ writeValue(value) {
155
+ if (this.multiple()) {
156
+ this.values.set(Array.isArray(value) ? value : []);
157
+ }
158
+ else {
159
+ this.value.set(Array.isArray(value) ? null : value);
160
+ }
161
+ }
162
+ registerOnChange(fn) {
163
+ this.onChange = fn;
164
+ }
165
+ registerOnTouched(fn) {
166
+ this.onTouched = fn;
167
+ }
168
+ isSelected(option) {
169
+ if (this.multiple())
170
+ return this.values().includes(option.value);
171
+ return option.value === this.value();
172
+ }
173
+ optionClasses(option, index) {
174
+ return cn(
175
+ // `rounded-sm`(6px) — panelin kendi `rounded-lg`(12px) kapsayıcısı
176
+ // içindeki İÇ İÇE (nested) daha küçük radius, bkz. styles.css radius
177
+ // notu: menü öğesi gibi kontrol-içi satırlar bir kademe küçük kalıyor.
178
+ 'flex cursor-pointer items-center justify-between gap-2 rounded-sm px-2.5 py-1.5 text-fg-muted transition-colors duration-fast ease-emphasis', index === this.highlighted() && !this.isSelected(option) && 'bg-surface-alt',
179
+ // Seçili satır Badge/Avatar'daki aynı tonal işaret rol token'ını
180
+ // konuşuyor (`color-mix()` tabanlı) — tutarlı "tint fill" imzası.
181
+ this.isSelected(option) && 'bg-primary-tint text-primary-tint-fg');
182
+ }
183
+ onTriggerKeydown(event) {
184
+ if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {
185
+ event.preventDefault();
186
+ if (!this.open())
187
+ this.toggle();
188
+ }
189
+ }
190
+ onPanelKeydown(event) {
191
+ const options = this.options();
192
+ if (event.key === 'Escape') {
193
+ event.preventDefault();
194
+ this.close();
195
+ return;
196
+ }
197
+ if (event.key === 'ArrowDown') {
198
+ event.preventDefault();
199
+ this.highlighted.update((i) => Math.min(options.length - 1, i + 1));
200
+ return;
201
+ }
202
+ if (event.key === 'ArrowUp') {
203
+ event.preventDefault();
204
+ this.highlighted.update((i) => Math.max(0, i - 1));
205
+ return;
206
+ }
207
+ if (event.key === 'Enter' || event.key === ' ') {
208
+ event.preventDefault();
209
+ const option = options[this.highlighted()];
210
+ if (option)
211
+ this.select(option);
212
+ }
213
+ }
214
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Select, deps: [], target: i0.ɵɵFactoryTarget.Component });
215
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Select, isStandalone: true, selector: "mf-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, values: { classPropertyName: "values", publicName: "values", isSignal: true, isRequired: false, transformFunction: null }, maxVisibleChips: { classPropertyName: "maxVisibleChips", publicName: "maxVisibleChips", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, 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", values: "valuesChange" }, host: { classAttribute: "block" }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => Select), multi: true }], exportAs: ["mfSelect"], ngImport: i0, template: "<button\r\n type=\"button\"\r\n cdkOverlayOrigin\r\n #origin=\"cdkOverlayOrigin\"\r\n [class]=\"triggerClasses()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"ariaLabel() || null\"\r\n [attr.aria-expanded]=\"open()\"\r\n aria-haspopup=\"listbox\"\r\n (click)=\"toggle()\"\r\n (keydown)=\"onTriggerKeydown($event)\"\r\n>\r\n @if (multiple()) {\r\n @if (selectedOptions().length > 0) {\r\n <span class=\"flex min-w-0 flex-1 flex-wrap items-center gap-1\">\r\n @for (option of visibleChips(); track option.label) {\r\n <mf-chip size=\"sm\">{{ option.label }}</mf-chip>\r\n }\r\n @if (overflowChipCount() > 0) {\r\n <mf-chip size=\"sm\">+{{ overflowChipCount() }}</mf-chip>\r\n }\r\n </span>\r\n } @else {\r\n <span class=\"truncate text-fg-subtle\">{{ effectivePlaceholder() }}</span>\r\n }\r\n } @else {\r\n <span class=\"truncate\" [class.text-fg-subtle]=\"!selectedLabel()\">\r\n {{ selectedLabel() || effectivePlaceholder() }}\r\n </span>\r\n }\r\n <span mfIcon [size]=\"18\" class=\"shrink-0 text-fg-subtle\">unfold_more</span>\r\n</button>\r\n\r\n<mf-popover\r\n [origin]=\"origin\"\r\n [open]=\"open()\"\r\n placement=\"bottom-start\"\r\n padding=\"sm\"\r\n [matchTriggerWidth]=\"true\"\r\n (closed)=\"close()\"\r\n>\r\n <ul\r\n role=\"listbox\"\r\n tabindex=\"0\"\r\n [attr.aria-multiselectable]=\"multiple() || null\"\r\n class=\"w-full max-h-64 min-w-[8rem] text-sm\"\r\n (keydown)=\"onPanelKeydown($event)\"\r\n >\r\n @for (option of options(); track option.label; let i = $index) {\r\n <!-- role=\"option\" B\u0130LEREK odaklanabilir de\u011Fil \u2014 klavye gezinmesi yukar\u0131daki listbox (keydown)'da merkezi. -->\r\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\r\n <li\r\n role=\"option\"\r\n [attr.aria-selected]=\"isSelected(option)\"\r\n [class]=\"optionClasses(option, i)\"\r\n (mouseenter)=\"highlighted.set(i)\"\r\n (click)=\"select(option)\"\r\n >\r\n <span class=\"truncate\">{{ option.label }}</span>\r\n @if (isSelected(option)) {\r\n <span mfIcon [size]=\"16\">check</span>\r\n }\r\n </li>\r\n }\r\n </ul>\r\n</mf-popover>\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: Popover, selector: "mf-popover", inputs: ["origin", "open", "placement", "padding", "hasBackdrop", "matchTriggerWidth", "panelClass"], outputs: ["openChange", "closed"], exportAs: ["mfPopover"] }, { kind: "component", type: Chip, selector: "mf-chip", inputs: ["tone", "size", "selected", "disabled", "removable", "removeLabel"], outputs: ["removed"], exportAs: ["mfChip"] }] });
216
+ }
217
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Select, decorators: [{
218
+ type: Component,
219
+ args: [{ selector: 'mf-select', exportAs: 'mfSelect', imports: [OverlayModule, Icon, Popover, Chip], host: { class: 'block' }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => Select), multi: true }], template: "<button\r\n type=\"button\"\r\n cdkOverlayOrigin\r\n #origin=\"cdkOverlayOrigin\"\r\n [class]=\"triggerClasses()\"\r\n [disabled]=\"disabled()\"\r\n [attr.aria-label]=\"ariaLabel() || null\"\r\n [attr.aria-expanded]=\"open()\"\r\n aria-haspopup=\"listbox\"\r\n (click)=\"toggle()\"\r\n (keydown)=\"onTriggerKeydown($event)\"\r\n>\r\n @if (multiple()) {\r\n @if (selectedOptions().length > 0) {\r\n <span class=\"flex min-w-0 flex-1 flex-wrap items-center gap-1\">\r\n @for (option of visibleChips(); track option.label) {\r\n <mf-chip size=\"sm\">{{ option.label }}</mf-chip>\r\n }\r\n @if (overflowChipCount() > 0) {\r\n <mf-chip size=\"sm\">+{{ overflowChipCount() }}</mf-chip>\r\n }\r\n </span>\r\n } @else {\r\n <span class=\"truncate text-fg-subtle\">{{ effectivePlaceholder() }}</span>\r\n }\r\n } @else {\r\n <span class=\"truncate\" [class.text-fg-subtle]=\"!selectedLabel()\">\r\n {{ selectedLabel() || effectivePlaceholder() }}\r\n </span>\r\n }\r\n <span mfIcon [size]=\"18\" class=\"shrink-0 text-fg-subtle\">unfold_more</span>\r\n</button>\r\n\r\n<mf-popover\r\n [origin]=\"origin\"\r\n [open]=\"open()\"\r\n placement=\"bottom-start\"\r\n padding=\"sm\"\r\n [matchTriggerWidth]=\"true\"\r\n (closed)=\"close()\"\r\n>\r\n <ul\r\n role=\"listbox\"\r\n tabindex=\"0\"\r\n [attr.aria-multiselectable]=\"multiple() || null\"\r\n class=\"w-full max-h-64 min-w-[8rem] text-sm\"\r\n (keydown)=\"onPanelKeydown($event)\"\r\n >\r\n @for (option of options(); track option.label; let i = $index) {\r\n <!-- role=\"option\" B\u0130LEREK odaklanabilir de\u011Fil \u2014 klavye gezinmesi yukar\u0131daki listbox (keydown)'da merkezi. -->\r\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\r\n <li\r\n role=\"option\"\r\n [attr.aria-selected]=\"isSelected(option)\"\r\n [class]=\"optionClasses(option, i)\"\r\n (mouseenter)=\"highlighted.set(i)\"\r\n (click)=\"select(option)\"\r\n >\r\n <span class=\"truncate\">{{ option.label }}</span>\r\n @if (isSelected(option)) {\r\n <span mfIcon [size]=\"16\">check</span>\r\n }\r\n </li>\r\n }\r\n </ul>\r\n</mf-popover>\r\n" }]
220
+ }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], values: [{ type: i0.Input, args: [{ isSignal: true, alias: "values", required: false }] }, { type: i0.Output, args: ["valuesChange"] }], maxVisibleChips: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxVisibleChips", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], hasError: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasError", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
221
+
222
+ /**
223
+ * Generated bundle index. Do not edit.
224
+ */
225
+
226
+ export { Select, selectTriggerVariants };
227
+ //# sourceMappingURL=mesgflow-ui-kit-select.mjs.map