@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,569 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, ElementRef, input, computed, signal, DestroyRef, afterNextRender, effect, Directive, viewChild, afterRenderEffect, Component, model, output } from '@angular/core';
3
+ import * as i1 from '@angular/aria/tabs';
4
+ import { TabList as TabList$1, Tab as Tab$1, TabPanel as TabPanel$1, Tabs as Tabs$1 } from '@angular/aria/tabs';
5
+ import { isRtl, scrollFromInlineStart, MF_TABS_LABELS, cn } from '@mesgflow/ui-kit/core';
6
+ import { Button } from '@mesgflow/ui-kit/button';
7
+ import { Icon } from '@mesgflow/ui-kit/icon';
8
+ import { cva } from 'class-variance-authority';
9
+
10
+ /**
11
+ * `<div mfTabScroller>` — taşan bir sekme şeridini kaydırılabilir yapar:
12
+ * native scrollbar'ı gizler, kenar "solma" maskesini (`mask-image`)
13
+ * kaydırılabilir yöne göre günceller, `canScrollStart`/`canScrollEnd`
14
+ * sinyallerini dışarı verir (ok butonlarının görünürlüğü için — bkz.
15
+ * `tab-list.html`/`tab-strip.html`, ikisi de bu directive'i paylaşıyor).
16
+ *
17
+ * `orientation` varsayılanı `'horizontal'` — `TabStrip` (üst sekme çubuğu)
18
+ * bunu hiç geçmez, davranışı DEĞİŞMEZ. Dikey bir grup rayı gerektiren
19
+ * tüketiciler `orientation="vertical"` geçer (bkz. `tab-list.ts`).
20
+ *
21
+ * `mask-image` template'te `[style.mask-image]` ile DEĞİL, doğrudan
22
+ * `style.setProperty` ile yazılıyor — Angular'ın stil binding sözdizimi
23
+ * tire içeren (`-webkit-`) property adlarını binding adı olarak kabul
24
+ * etmiyor, ikisini TEK yerden (burada) senkron yazmak için imperatif yol
25
+ * daha güvenli (bkz. Tooltip'in de DOM'a doğrudan yazdığı emsal).
26
+ */
27
+ class TabScroller {
28
+ el = inject(ElementRef);
29
+ orientation = input('horizontal', /* @ts-ignore */
30
+ ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
31
+ vertical = computed(() => this.orientation() === 'vertical', /* @ts-ignore */
32
+ ...(ngDevMode ? [{ debugName: "vertical" }] : /* istanbul ignore next */ []));
33
+ canScrollStart = signal(false, /* @ts-ignore */
34
+ ...(ngDevMode ? [{ debugName: "canScrollStart" }] : /* istanbul ignore next */ []));
35
+ canScrollEnd = signal(false, /* @ts-ignore */
36
+ ...(ngDevMode ? [{ debugName: "canScrollEnd" }] : /* istanbul ignore next */ []));
37
+ constructor() {
38
+ const destroyRef = inject(DestroyRef);
39
+ afterNextRender(() => {
40
+ this.updateEdges();
41
+ if (typeof ResizeObserver === 'undefined')
42
+ return;
43
+ const observer = new ResizeObserver(() => this.updateEdges());
44
+ observer.observe(this.el.nativeElement);
45
+ destroyRef.onDestroy(() => observer.disconnect());
46
+ });
47
+ effect(() => {
48
+ const start = this.canScrollStart() ? 24 : 0;
49
+ const end = this.canScrollEnd() ? 24 : 0;
50
+ // Maske satır başından sonuna — RTL'de başlangıç sağ kenar.
51
+ const direction = this.vertical()
52
+ ? 'to bottom'
53
+ : isRtl(this.el.nativeElement)
54
+ ? 'to left'
55
+ : 'to right';
56
+ const mask = `linear-gradient(${direction}, transparent, black ${start}px, black calc(100% - ${end}px), transparent 100%)`;
57
+ this.el.nativeElement.style.setProperty('mask-image', mask);
58
+ this.el.nativeElement.style.setProperty('-webkit-mask-image', mask);
59
+ });
60
+ }
61
+ scrollByDir(dir) {
62
+ const node = this.el.nativeElement;
63
+ if (this.vertical())
64
+ node.scrollBy({ top: dir * node.clientHeight * 0.8, behavior: 'smooth' });
65
+ else {
66
+ // `dir` mantıksal (−1 başa, +1 sona); RTL'de sona gitmek scrollLeft'i AZALTIR.
67
+ const sign = isRtl(node) ? -1 : 1;
68
+ node.scrollBy({ left: sign * dir * node.clientWidth * 0.8, behavior: 'smooth' });
69
+ }
70
+ }
71
+ scrollIntoViewIfNeeded(target) {
72
+ // jsdom (birim testleri) Element.scrollIntoView'ı UYGULAMIYOR — ResizeObserver'daki
73
+ // AYNI savunma deseni (bkz. constructor), gerçek tarayıcıda etkisiz bir NO-OP.
74
+ target.scrollIntoView?.({ block: 'nearest', inline: 'nearest' });
75
+ }
76
+ updateEdges() {
77
+ const node = this.el.nativeElement;
78
+ if (this.vertical()) {
79
+ const max = node.scrollHeight - node.clientHeight;
80
+ this.canScrollStart.set(node.scrollTop > 1);
81
+ this.canScrollEnd.set(max > 1 && node.scrollTop < max - 1);
82
+ return;
83
+ }
84
+ const max = node.scrollWidth - node.clientWidth;
85
+ const offset = scrollFromInlineStart(node); // RTL'de scrollLeft negatif
86
+ this.canScrollStart.set(offset > 1);
87
+ this.canScrollEnd.set(max > 1 && offset < max - 1);
88
+ }
89
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TabScroller, deps: [], target: i0.ɵɵFactoryTarget.Directive });
90
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.6", type: TabScroller, isStandalone: true, selector: "[mfTabScroller]", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "scroll": "updateEdges()" }, properties: { "class.flex": "orientation() === \"horizontal\"", "class.min-w-0": "orientation() === \"horizontal\"", "class.overflow-x-auto": "orientation() === \"horizontal\"", "class.min-h-0": "orientation() === \"vertical\"", "class.overflow-y-auto": "orientation() === \"vertical\"" }, classAttribute: "[scrollbar-width:none] [&::-webkit-scrollbar]:hidden" }, ngImport: i0 });
91
+ }
92
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TabScroller, decorators: [{
93
+ type: Directive,
94
+ args: [{
95
+ selector: '[mfTabScroller]',
96
+ host: {
97
+ class: '[scrollbar-width:none] [&::-webkit-scrollbar]:hidden',
98
+ '[class.flex]': 'orientation() === "horizontal"',
99
+ '[class.min-w-0]': 'orientation() === "horizontal"',
100
+ '[class.overflow-x-auto]': 'orientation() === "horizontal"',
101
+ '[class.min-h-0]': 'orientation() === "vertical"',
102
+ '[class.overflow-y-auto]': 'orientation() === "vertical"',
103
+ '(scroll)': 'updateEdges()',
104
+ },
105
+ }]
106
+ }], ctorParameters: () => [], propDecorators: { orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }] } });
107
+
108
+ /**
109
+ * Bkz. `tab-list.ts`. `underline`'da ray AYRI, kayan bir `<span>` (JS ile
110
+ * konumlanır — bkz. `TabList.positionIndicator`); `card`'da ray HER sekmenin
111
+ * kendi `box-shadow`'unda yaşar (bkz. `tabVariants` compound'u), çünkü
112
+ * `card` görünümünde her sekme zaten kendi kenarlığıyla ayrık bir kutu —
113
+ * kayan tek bir gösterge o kutuların üstünden "kayarak" geçmezdi, doğal
114
+ * durmazdı. `relative` — kayan gösterge `absolute` konumlanıyor buna göre.
115
+ *
116
+ * `orientation` ekseni sol dikey grup rayı gerektiren ekranlar için eklendi —
117
+ * `@angular/aria/tabs`'ın ARIA/klavye desteği zaten yön-agnostik
118
+ * (`hostDirectives`'in `orientation` girdisi, bkz. `tab-list.ts`), eksik
119
+ * olan sadece bu görsel katmandı.
120
+ */
121
+ const tabListVariants = cva('relative flex', {
122
+ variants: {
123
+ variant: {
124
+ underline: 'gap-1',
125
+ card: 'gap-1.5',
126
+ },
127
+ orientation: {
128
+ horizontal: 'min-w-max items-center',
129
+ vertical: 'w-full flex-col items-stretch',
130
+ },
131
+ },
132
+ defaultVariants: { variant: 'underline', orientation: 'horizontal' },
133
+ });
134
+ /**
135
+ * `selected`/`disabled` burada `aria-selected`/`aria-disabled` CSS
136
+ * seçicileriyle DEĞİL, `Tab`'ın kendi `computed()`'ıyla (bkz. `tab.ts`)
137
+ * okunan sinyal değerleriyle besleniyor — kod tabanındaki yerleşik desen
138
+ * (Select'in `optionClasses`, Table'ın `rowClasses`) TS'te hesaplanan koşullu
139
+ * class, CSS attribute-selector değil.
140
+ */
141
+ const tabVariants = cva('relative inline-flex shrink-0 cursor-pointer appearance-none items-center gap-1.5 whitespace-nowrap border-0 bg-transparent text-sm text-fg-muted transition-colors duration-fast ease-emphasis active:scale-[0.99] ' +
142
+ 'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring', {
143
+ variants: {
144
+ variant: {
145
+ underline: 'rounded-sm px-3 py-2',
146
+ card: 'rounded-sm border border-transparent px-3 py-1.5',
147
+ },
148
+ orientation: {
149
+ horizontal: '',
150
+ vertical: 'w-full justify-start text-start',
151
+ },
152
+ selected: {
153
+ true: '',
154
+ false: 'hover:bg-surface-alt hover:text-fg',
155
+ },
156
+ disabled: {
157
+ true: 'pointer-events-none opacity-50 active:scale-100',
158
+ false: '',
159
+ },
160
+ },
161
+ compoundVariants: [
162
+ { variant: 'underline', selected: true, class: 'text-fg font-semibold' },
163
+ /*
164
+ * `card` — aktif sekme `bg-canvas` (içerik zeminiyle birleşir) + 2px dolu
165
+ * ray. Yatayda alt kenar, dikeyde ön (sol) kenar — dikey grup rayı bunu
166
+ * kullanıyor. Ray rengi `--mf-accent-fill` (mode-swapped: light 900 /
167
+ * dark 400) — diğer TÜM "ray" kullanımlarıyla (Sidebar aktif nav,
168
+ * Table seçili satır, ikisi de `border-s-accent-fill`) TUTARLI. `var()`
169
+ * `@theme inline`'ın `--color-accent-fill` katmanını DEĞİL doğrudan
170
+ * `--mf-*`'i hedefliyor — `box-shadow` arbitrary value'su bir utility
171
+ * DEĞİL, Tailwind'in "bu inline değişkeni emit et" taramasına
172
+ * güvenmek yerine kaynağa doğrudan bağlanmak daha sağlam.
173
+ */
174
+ {
175
+ variant: 'card',
176
+ orientation: 'horizontal',
177
+ selected: true,
178
+ class: 'border-border bg-canvas text-fg font-semibold shadow-[inset_0_-2px_0_0_var(--mf-accent-fill)]',
179
+ },
180
+ {
181
+ variant: 'card',
182
+ orientation: 'vertical',
183
+ selected: true,
184
+ class: 'border-border bg-canvas text-fg font-semibold shadow-[inset_2px_0_0_0_var(--mf-accent-fill)]',
185
+ },
186
+ ],
187
+ defaultVariants: {
188
+ variant: 'underline',
189
+ orientation: 'horizontal',
190
+ selected: false,
191
+ disabled: false,
192
+ },
193
+ });
194
+
195
+ /**
196
+ * `<mf-tab-list [(selectedTab)]="active" variant="underline">…</mf-tab-list>`
197
+ * — `mf-tabs` içine konur, `mfTab` butonlarını sarar. ARIA/klavye
198
+ * (Ok tuşları/Home/End) `@angular/aria/tabs`'ın `TabList` pattern'inden
199
+ * `hostDirectives` ile geliyor (bkz. `tabs.ts` üstündeki not).
200
+ *
201
+ * İki premium detay burada yaşıyor:
202
+ * 1. **Kayan ray göstergesi** (`underline` varyantı) — aktif sekme
203
+ * değişince `positionIndicator()` DOM'dan `[aria-selected="true"]`
204
+ * elemanın `offsetLeft`/`offsetWidth`'ini (yatayda) ya da `offsetTop`/
205
+ * `offsetHeight`'ını (dikeyde) ölçüp göstergeyi kaydırıyor (emsal:
206
+ * `table-pagination.ts`'in odak restorasyonundaki `afterRenderEffect` +
207
+ * `viewChild(ElementRef)` deseni). `ResizeObserver` yeniden boyutlanmada
208
+ * (font yüklenmesi, viewport) yeniden ölçer. `card` varyantında AYRI bir
209
+ * gösterge YOK — ray her sekmenin kendi `box-shadow`'unda yaşıyor
210
+ * (bkz. tabs.variants.ts).
211
+ * 2. **Taşma yönetimi** — `mfTabScroller` (bkz. o dosya) kaydırma+kenar
212
+ * solma maskesi sağlıyor; ok butonları SADECE o yönde taşma varken
213
+ * render edilir. Aktif sekme değişince görünür alana kaydırılır.
214
+ *
215
+ * `tab-list.html`'deki sarmalayıcı `<div>`'in çapraz eksen hizalaması BİLEREK
216
+ * yöne göre koşullu: dikeyde (`flex-col`) çapraz eksen GENİŞLİK olur, `items-
217
+ * center` orada "çocukları raya GERME, kendi içerik genişliğine küçült" demek
218
+ * — bu, genişliğin `mfTabScroller`/`#row`/butonlara hiç iletilmemesine ve
219
+ * `truncate`'in (role-form.html'deki İngilizce grup adlarıyla canlı
220
+ * doğrulandı) hiç devreye girmeden ham/elipsissiz kırpılmasına yol açan
221
+ * GERÇEK bir bugdu. `items-stretch` çapraz ekseni doğru şekilde geriyor —
222
+ * bunu tekrar `items-center`'a "sadeleştirme".
223
+ *
224
+ * `orientation` girdisi `@angular/aria`'nın `TabList` pattern'inden
225
+ * `hostDirectives` ile geliyor (ARIA/klavye zaten yön-agnostik) — burada
226
+ * ikinci kez `input()` olarak TANIMLANMIYOR (NG2017, bkz. `TabPanel.
227
+ * preserveContent`'teki aynı kısıt), `ariaTabList.orientation()` üzerinden
228
+ * `protected readonly orientation` olarak okunuyor; `Tab` (tab.ts) bunu
229
+ * `variant()` ile aynı `inject()` deseniyle ebeveynden alıyor.
230
+ */
231
+ class TabList {
232
+ variant = input('underline', /* @ts-ignore */
233
+ ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
234
+ scrollStartLabel = input(/* @ts-ignore */
235
+ ...(ngDevMode ? [undefined, { debugName: "scrollStartLabel" }] : /* istanbul ignore next */ []));
236
+ scrollEndLabel = input(/* @ts-ignore */
237
+ ...(ngDevMode ? [undefined, { debugName: "scrollEndLabel" }] : /* istanbul ignore next */ []));
238
+ tabsLabels = inject(MF_TABS_LABELS);
239
+ effectiveScrollStartLabel = computed(() => this.scrollStartLabel() ?? this.tabsLabels().scrollStart, /* @ts-ignore */
240
+ ...(ngDevMode ? [{ debugName: "effectiveScrollStartLabel" }] : /* istanbul ignore next */ []));
241
+ effectiveScrollEndLabel = computed(() => this.scrollEndLabel() ?? this.tabsLabels().scrollEnd, /* @ts-ignore */
242
+ ...(ngDevMode ? [{ debugName: "effectiveScrollEndLabel" }] : /* istanbul ignore next */ []));
243
+ /** `mfTab` (bkz. tab.ts) varyantı buradan `inject()` ile okuyor — tek kaynak. */
244
+ ariaTabList = inject(TabList$1);
245
+ /** `Tab` (tab.ts) bunu `variant()` ile aynı `inject()` deseniyle okuyor — bu yüzden `public`. */
246
+ orientation = computed(() => this.ariaTabList.orientation(), /* @ts-ignore */
247
+ ...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
248
+ isVertical = computed(() => this.orientation() === 'vertical', /* @ts-ignore */
249
+ ...(ngDevMode ? [{ debugName: "isVertical" }] : /* istanbul ignore next */ []));
250
+ listClasses = computed(() => cn(tabListVariants({ variant: this.variant(), orientation: this.orientation() })), /* @ts-ignore */
251
+ ...(ngDevMode ? [{ debugName: "listClasses" }] : /* istanbul ignore next */ []));
252
+ indicatorClasses = computed(() => cn('pointer-events-none absolute rounded-full bg-accent-fill opacity-0 transition-[transform,width,height,opacity] duration-base ease-emphasis', this.isVertical() ? 'top-0 left-0 w-0.5' : 'bottom-0 left-0 h-0.5'), /* @ts-ignore */
253
+ ...(ngDevMode ? [{ debugName: "indicatorClasses" }] : /* istanbul ignore next */ []));
254
+ scroller = viewChild(TabScroller, /* @ts-ignore */
255
+ ...(ngDevMode ? [{ debugName: "scroller" }] : /* istanbul ignore next */ []));
256
+ showStartArrow = computed(() => this.scroller()?.canScrollStart() ?? false, /* @ts-ignore */
257
+ ...(ngDevMode ? [{ debugName: "showStartArrow" }] : /* istanbul ignore next */ []));
258
+ showEndArrow = computed(() => this.scroller()?.canScrollEnd() ?? false, /* @ts-ignore */
259
+ ...(ngDevMode ? [{ debugName: "showEndArrow" }] : /* istanbul ignore next */ []));
260
+ rowEl = viewChild('row', /* @ts-ignore */
261
+ ...(ngDevMode ? [{ debugName: "rowEl" }] : /* istanbul ignore next */ []));
262
+ indicatorEl = viewChild('indicator', /* @ts-ignore */
263
+ ...(ngDevMode ? [{ debugName: "indicatorEl" }] : /* istanbul ignore next */ []));
264
+ constructor() {
265
+ const destroyRef = inject(DestroyRef);
266
+ afterRenderEffect(() => {
267
+ this.ariaTabList.selectedTab();
268
+ this.positionIndicator();
269
+ });
270
+ afterNextRender(() => {
271
+ const row = this.rowEl()?.nativeElement;
272
+ if (!row || typeof ResizeObserver === 'undefined')
273
+ return;
274
+ const observer = new ResizeObserver(() => this.positionIndicator());
275
+ observer.observe(row);
276
+ destroyRef.onDestroy(() => observer.disconnect());
277
+ });
278
+ }
279
+ positionIndicator() {
280
+ const row = this.rowEl()?.nativeElement;
281
+ const indicator = this.indicatorEl()?.nativeElement;
282
+ if (!row || !indicator)
283
+ return;
284
+ const active = row.querySelector('[aria-selected="true"]');
285
+ if (!active) {
286
+ indicator.style.opacity = '0';
287
+ return;
288
+ }
289
+ indicator.style.opacity = '1';
290
+ if (this.isVertical()) {
291
+ indicator.style.transform = `translateY(${active.offsetTop}px)`;
292
+ indicator.style.height = `${active.offsetHeight}px`;
293
+ }
294
+ else {
295
+ indicator.style.transform = `translateX(${active.offsetLeft}px)`;
296
+ indicator.style.width = `${active.offsetWidth}px`;
297
+ }
298
+ this.scroller()?.scrollIntoViewIfNeeded(active);
299
+ }
300
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TabList, deps: [], target: i0.ɵɵFactoryTarget.Component });
301
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: TabList, isStandalone: true, selector: "mf-tab-list", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, scrollStartLabel: { classPropertyName: "scrollStartLabel", publicName: "scrollStartLabel", isSignal: true, isRequired: false, transformFunction: null }, scrollEndLabel: { classPropertyName: "scrollEndLabel", publicName: "scrollEndLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "block" }, viewQueries: [{ propertyName: "scroller", first: true, predicate: TabScroller, descendants: true, isSignal: true }, { propertyName: "rowEl", first: true, predicate: ["row"], descendants: true, isSignal: true }, { propertyName: "indicatorEl", first: true, predicate: ["indicator"], descendants: true, isSignal: true }], hostDirectives: [{ directive: i1.TabList, inputs: ["orientation", "orientation", "wrap", "wrap", "softDisabled", "softDisabled", "focusMode", "focusMode", "selectionMode", "selectionMode", "disabled", "disabled", "selectedTab", "selectedTab"], outputs: ["selectedTabChange", "selectedTabChange"] }], ngImport: i0, template: "<div\r\n class=\"flex gap-1\"\r\n [class.flex-col]=\"isVertical()\"\r\n [class.items-center]=\"!isVertical()\"\r\n [class.items-stretch]=\"isVertical()\"\r\n>\r\n @if (showStartArrow()) {\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 class=\"shrink-0\"\r\n [attr.aria-label]=\"effectiveScrollStartLabel()\"\r\n (click)=\"scroller()?.scrollByDir(-1)\"\r\n >\r\n <span mfIcon [size]=\"16\" class=\"rtl:-scale-x-100\">{{\r\n isVertical() ? 'keyboard_arrow_up' : 'chevron_left'\r\n }}</span>\r\n </button>\r\n }\r\n\r\n <div mfTabScroller [orientation]=\"orientation()\">\r\n <div #row [class]=\"listClasses()\">\r\n <ng-content />\r\n @if (variant() === 'underline') {\r\n <span #indicator [class]=\"indicatorClasses()\"></span>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (showEndArrow()) {\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 class=\"shrink-0\"\r\n [attr.aria-label]=\"effectiveScrollEndLabel()\"\r\n (click)=\"scroller()?.scrollByDir(1)\"\r\n >\r\n <span mfIcon [size]=\"16\" class=\"rtl:-scale-x-100\">{{\r\n isVertical() ? 'keyboard_arrow_down' : 'chevron_right'\r\n }}</span>\r\n </button>\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"] }, { kind: "directive", type: TabScroller, selector: "[mfTabScroller]", inputs: ["orientation"] }] });
302
+ }
303
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TabList, decorators: [{
304
+ type: Component,
305
+ args: [{ selector: 'mf-tab-list', imports: [Button, Icon, TabScroller], hostDirectives: [
306
+ {
307
+ directive: TabList$1,
308
+ inputs: [
309
+ 'orientation',
310
+ 'wrap',
311
+ 'softDisabled',
312
+ 'focusMode',
313
+ 'selectionMode',
314
+ 'disabled',
315
+ 'selectedTab',
316
+ ],
317
+ outputs: ['selectedTabChange'],
318
+ },
319
+ ], host: { class: 'block' }, template: "<div\r\n class=\"flex gap-1\"\r\n [class.flex-col]=\"isVertical()\"\r\n [class.items-center]=\"!isVertical()\"\r\n [class.items-stretch]=\"isVertical()\"\r\n>\r\n @if (showStartArrow()) {\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 class=\"shrink-0\"\r\n [attr.aria-label]=\"effectiveScrollStartLabel()\"\r\n (click)=\"scroller()?.scrollByDir(-1)\"\r\n >\r\n <span mfIcon [size]=\"16\" class=\"rtl:-scale-x-100\">{{\r\n isVertical() ? 'keyboard_arrow_up' : 'chevron_left'\r\n }}</span>\r\n </button>\r\n }\r\n\r\n <div mfTabScroller [orientation]=\"orientation()\">\r\n <div #row [class]=\"listClasses()\">\r\n <ng-content />\r\n @if (variant() === 'underline') {\r\n <span #indicator [class]=\"indicatorClasses()\"></span>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (showEndArrow()) {\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 class=\"shrink-0\"\r\n [attr.aria-label]=\"effectiveScrollEndLabel()\"\r\n (click)=\"scroller()?.scrollByDir(1)\"\r\n >\r\n <span mfIcon [size]=\"16\" class=\"rtl:-scale-x-100\">{{\r\n isVertical() ? 'keyboard_arrow_down' : 'chevron_right'\r\n }}</span>\r\n </button>\r\n }\r\n</div>\r\n" }]
320
+ }], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], scrollStartLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollStartLabel", required: false }] }], scrollEndLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollEndLabel", required: false }] }], scroller: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TabScroller), { isSignal: true }] }], rowEl: [{ type: i0.ViewChild, args: ['row', { isSignal: true }] }], indicatorEl: [{ type: i0.ViewChild, args: ['indicator', { isSignal: true }] }] } });
321
+
322
+ /**
323
+ * `<button mfTab value="genel">Genel</button>` — bir `mf-tab-list` içine
324
+ * konur. ARIA/klavye/seçim davranışı `@angular/aria/tabs`'ın `Tab`
325
+ * pattern'inden `hostDirectives` ile geliyor (bkz. `tabs.ts` üstündeki not);
326
+ * bu directive sadece görsel katmanı ekliyor. `value`/`disabled`/`id`
327
+ * girdileri `hostDirectives`'in `inputs` listesiyle dışarı açıldı — tüketici
328
+ * doğrudan `[value]`/`[disabled]` bağlar, `ngTab` attribute'unu YAZMAZ.
329
+ *
330
+ * Varyant (`underline`/`card`) ebeveyn `mf-tab-list`'ten `inject()` ile
331
+ * okunuyor — `Tab` kendi varyant girdisini TAŞIMIYOR, tek kaynak listede.
332
+ */
333
+ class Tab {
334
+ ariaTab = inject(Tab$1);
335
+ tabList = inject(TabList, { optional: true });
336
+ classes = computed(() => cn(tabVariants({
337
+ variant: this.tabList?.variant() ?? 'underline',
338
+ orientation: this.tabList?.orientation() ?? 'horizontal',
339
+ selected: this.ariaTab.selected(),
340
+ disabled: this.ariaTab.disabled(),
341
+ })), /* @ts-ignore */
342
+ ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
343
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Tab, deps: [], target: i0.ɵɵFactoryTarget.Directive });
344
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.6", type: Tab, isStandalone: true, selector: "button[mfTab]", host: { properties: { "attr.type": "'button'", "class": "classes()" } }, hostDirectives: [{ directive: i1.Tab, inputs: ["value", "value", "disabled", "disabled", "id", "id"] }], ngImport: i0 });
345
+ }
346
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Tab, decorators: [{
347
+ type: Directive,
348
+ args: [{
349
+ selector: 'button[mfTab]',
350
+ hostDirectives: [{ directive: Tab$1, inputs: ['value', 'disabled', 'id'] }],
351
+ host: { '[attr.type]': "'button'", '[class]': 'classes()' },
352
+ }]
353
+ }] });
354
+
355
+ /**
356
+ * ```html
357
+ * <mf-tab-panel value="genel">
358
+ * <ng-template ngTabContent>İçerik…</ng-template>
359
+ * </mf-tab-panel>
360
+ * ```
361
+ *
362
+ * `ngTabContent` (`@angular/aria/tabs`'ın `TabContent`'i) doğrudan
363
+ * kullanılır — ayrı bir `appTabContent` sarmalayıcı YOK, tek katmanlı bir
364
+ * yapıya sarmalayıcı eklemenin karşılığı yok (bkz. `TabContent`'in kendi
365
+ * `DeferredContent` mekanizması, panel aktif olana kadar içeriği hiç
366
+ * oluşturmaz — lazy). `<ng-content />` bilerek TEK satır: panelin kendi
367
+ * `role="tabpanel"`/`tabindex`/`inert` host bağlamaları `hostDirectives`'ten
368
+ * geliyor, ekstra bir sarmalayıcıya gerek yok.
369
+ *
370
+ * `[class.hidden]` ELLE eklendi — `AriaTabPanel`'in `inert` attribute'u
371
+ * elemanı erişilebilirlik ağacından/etkileşimden çıkarıyor ama GÖRSEL olarak
372
+ * gizlemiyor (kütüphanenin kendi dokümantasyonu: "Proper styling is required
373
+ * for visual hiding" — gerçek bulgu, ui-kit'te pasif panellerin boş
374
+ * dolgulu kutular olarak GÖRÜNÜR kaldığı görüldü).
375
+ */
376
+ class TabPanel {
377
+ ariaTabPanel = inject(TabPanel$1);
378
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TabPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
379
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: TabPanel, isStandalone: true, selector: "mf-tab-panel", host: { properties: { "class.hidden": "!ariaTabPanel.visible()" }, classAttribute: "block focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring" }, hostDirectives: [{ directive: i1.TabPanel, inputs: ["value", "value", "id", "id"] }], ngImport: i0, template: '<ng-content />', isInline: true });
380
+ }
381
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TabPanel, decorators: [{
382
+ type: Component,
383
+ args: [{
384
+ selector: 'mf-tab-panel',
385
+ hostDirectives: [{ directive: TabPanel$1, inputs: ['value', 'id'] }],
386
+ host: {
387
+ class: 'block focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring',
388
+ '[class.hidden]': '!ariaTabPanel.visible()',
389
+ },
390
+ template: '<ng-content />',
391
+ }]
392
+ }] });
393
+
394
+ /**
395
+ * `<mf-tab-strip [items]="items()" [(activeKey)]="active" (close)="onClose($event)" />`
396
+ *
397
+ * `mf-tabs`/`mf-tab-list` (bkz. `tabs.ts`) ARIA `tabs` pattern'i PANEL
398
+ * varsayar (`aria-controls` gerçek bir `role=tabpanel`'e işaret eder) — bu
399
+ * şerit ise bir ROTA/DOKÜMAN şeridi: panel yok, içerik `router-outlet`'ten
400
+ * gelir, sekmeler kapatılabilir. Bu yüzden `@angular/aria/tabs`'ı DEĞİL,
401
+ * elle roving tabindex kullanıyor (emsal: `table-pagination.ts`'in
402
+ * `onNavKeydown`'ı) — ARIA `tab` rolü/`aria-selected` yine de elle
403
+ * uygulanıyor, sadece pattern motoru YOK.
404
+ *
405
+ * Ok tuşları SADECE odağı taşır (`activeKey` DEĞİŞMEZ) — her ok vuruşunda
406
+ * gerçek bir router navigasyonu tetiklemek (bkz. `TabsStore.activate`)
407
+ * pahalı/istenmeyen bir yan etki olurdu. `Enter`/`Space` ya da tık asıl
408
+ * seçimi commit eder. `Delete` odaktaki (kapatılabilir) sekmeyi kapatır.
409
+ *
410
+ * Kapatma butonu gerçek bir `<button>` ama tab elemanının kendisi `role=tab`
411
+ * taşıyan bir `<div>` — `mfTab`'ın (aria Tabs sisteminin) aksine burada bir
412
+ * `<button>` İÇİNE başka bir interaktif eleman GÖMÜLMÜYOR (geçersiz HTML
413
+ * olurdu, bkz. `table-filter-bar.html`'deki chip deseni — aynı gerekçeyle
414
+ * orada da İKİ KARDEŞ buton var, iç içe değil). Kapatma butonu bilerek
415
+ * `tabindex="-1"` — birincil roving-tabindex sırasının parçası değil (fare/
416
+ * dokunma birincil, `Delete` tuşu klavye eşdeğeri).
417
+ *
418
+ * Sağ tık menüsü TAMAMEN tüketiciye ait — bu bileşen belirli bir dropdown
419
+ * kütüphanesini BİLMİYOR (bkz. projects/ui-kit/README.md "Directive mi, component
420
+ * mi?" ruhu — dropdown-agnostik kalma), sadece ham `(itemContextMenu)` olayını
421
+ * yukarı veriyor.
422
+ */
423
+ class TabStrip {
424
+ items = input.required(/* @ts-ignore */
425
+ ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
426
+ activeKey = model.required(/* @ts-ignore */
427
+ ...(ngDevMode ? [{ debugName: "activeKey" }] : /* istanbul ignore next */ []));
428
+ /** Verilirse aktif sekmenin `aria-controls`'ü buna işaret eder (tek bir paylaşımlı içerik bölgesi — router-outlet). */
429
+ contentId = input(null, /* @ts-ignore */
430
+ ...(ngDevMode ? [{ debugName: "contentId" }] : /* istanbul ignore next */ []));
431
+ scrollStartLabel = input(/* @ts-ignore */
432
+ ...(ngDevMode ? [undefined, { debugName: "scrollStartLabel" }] : /* istanbul ignore next */ []));
433
+ scrollEndLabel = input(/* @ts-ignore */
434
+ ...(ngDevMode ? [undefined, { debugName: "scrollEndLabel" }] : /* istanbul ignore next */ []));
435
+ /** Kapatma butonunun `aria-label`'ı — sekmenin kendi etiketiyle birleştirilir (ör. "Close: Roles"). */
436
+ closeLabel = input(/* @ts-ignore */
437
+ ...(ngDevMode ? [undefined, { debugName: "closeLabel" }] : /* istanbul ignore next */ []));
438
+ tabsLabels = inject(MF_TABS_LABELS);
439
+ effectiveScrollStartLabel = computed(() => this.scrollStartLabel() ?? this.tabsLabels().scrollStart, /* @ts-ignore */
440
+ ...(ngDevMode ? [{ debugName: "effectiveScrollStartLabel" }] : /* istanbul ignore next */ []));
441
+ effectiveScrollEndLabel = computed(() => this.scrollEndLabel() ?? this.tabsLabels().scrollEnd, /* @ts-ignore */
442
+ ...(ngDevMode ? [{ debugName: "effectiveScrollEndLabel" }] : /* istanbul ignore next */ []));
443
+ effectiveCloseLabel = computed(() => this.closeLabel() ?? this.tabsLabels().close, /* @ts-ignore */
444
+ ...(ngDevMode ? [{ debugName: "effectiveCloseLabel" }] : /* istanbul ignore next */ []));
445
+ // `close` adı native DOM `close` olayıyla çakışıyor (@angular-eslint/no-output-native);
446
+ // mevcut public API — yeniden adlandırma kırıcı, ileri bir sürümde ele alınacak.
447
+ // eslint-disable-next-line @angular-eslint/no-output-native
448
+ close = output();
449
+ itemContextMenu = output();
450
+ focusedKey = signal(null, /* @ts-ignore */
451
+ ...(ngDevMode ? [{ debugName: "focusedKey" }] : /* istanbul ignore next */ []));
452
+ scroller = viewChild(TabScroller, /* @ts-ignore */
453
+ ...(ngDevMode ? [{ debugName: "scroller" }] : /* istanbul ignore next */ []));
454
+ showStartArrow = computed(() => this.scroller()?.canScrollStart() ?? false, /* @ts-ignore */
455
+ ...(ngDevMode ? [{ debugName: "showStartArrow" }] : /* istanbul ignore next */ []));
456
+ showEndArrow = computed(() => this.scroller()?.canScrollEnd() ?? false, /* @ts-ignore */
457
+ ...(ngDevMode ? [{ debugName: "showEndArrow" }] : /* istanbul ignore next */ []));
458
+ rowEl = viewChild('row', /* @ts-ignore */
459
+ ...(ngDevMode ? [{ debugName: "rowEl" }] : /* istanbul ignore next */ []));
460
+ tabClasses(item) {
461
+ return cn(tabVariants({ variant: 'card', selected: item.key === this.activeKey(), disabled: false }), 'pe-1.5');
462
+ }
463
+ tabIndexFor(item) {
464
+ const focused = this.focusedKey() ?? this.activeKey();
465
+ return item.key === focused ? 0 : -1;
466
+ }
467
+ select(key) {
468
+ this.focusedKey.set(key);
469
+ this.activeKey.set(key);
470
+ }
471
+ onCloseClick(event, key) {
472
+ event.stopPropagation();
473
+ this.close.emit(key);
474
+ }
475
+ onContextMenu(event, item) {
476
+ event.preventDefault();
477
+ this.itemContextMenu.emit({ event, item });
478
+ }
479
+ onKeydown(event) {
480
+ const items = this.items();
481
+ if (items.length === 0)
482
+ return;
483
+ const currentKey = this.focusedKey() ?? this.activeKey();
484
+ const index = items.findIndex((i) => i.key === currentKey);
485
+ switch (event.key) {
486
+ case 'ArrowLeft':
487
+ event.preventDefault();
488
+ this.focusIndex(index <= 0 ? items.length - 1 : index - 1);
489
+ break;
490
+ case 'ArrowRight':
491
+ event.preventDefault();
492
+ this.focusIndex(index === -1 || index === items.length - 1 ? 0 : index + 1);
493
+ break;
494
+ case 'Home':
495
+ event.preventDefault();
496
+ this.focusIndex(0);
497
+ break;
498
+ case 'End':
499
+ event.preventDefault();
500
+ this.focusIndex(items.length - 1);
501
+ break;
502
+ case 'Enter':
503
+ case ' ':
504
+ event.preventDefault();
505
+ if (index !== -1)
506
+ this.select(items[index].key);
507
+ break;
508
+ case 'Delete':
509
+ if (index !== -1 && items[index].closable) {
510
+ event.preventDefault();
511
+ this.close.emit(items[index].key);
512
+ }
513
+ break;
514
+ }
515
+ }
516
+ focusIndex(index) {
517
+ const item = this.items()[index];
518
+ if (!item)
519
+ return;
520
+ this.focusedKey.set(item.key);
521
+ queueMicrotask(() => {
522
+ const btn = this.rowEl()?.nativeElement.querySelector(`[data-tab-key="${item.key}"]`);
523
+ btn?.focus();
524
+ if (btn)
525
+ this.scroller()?.scrollIntoViewIfNeeded(btn);
526
+ });
527
+ }
528
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TabStrip, deps: [], target: i0.ɵɵFactoryTarget.Component });
529
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: TabStrip, isStandalone: true, selector: "mf-tab-strip", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, activeKey: { classPropertyName: "activeKey", publicName: "activeKey", isSignal: true, isRequired: true, transformFunction: null }, contentId: { classPropertyName: "contentId", publicName: "contentId", isSignal: true, isRequired: false, transformFunction: null }, scrollStartLabel: { classPropertyName: "scrollStartLabel", publicName: "scrollStartLabel", isSignal: true, isRequired: false, transformFunction: null }, scrollEndLabel: { classPropertyName: "scrollEndLabel", publicName: "scrollEndLabel", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeKey: "activeKeyChange", close: "close", itemContextMenu: "itemContextMenu" }, host: { attributes: { "role": "tablist" }, classAttribute: "block" }, viewQueries: [{ propertyName: "scroller", first: true, predicate: TabScroller, descendants: true, isSignal: true }, { propertyName: "rowEl", first: true, predicate: ["row"], descendants: true, isSignal: true }], exportAs: ["mfTabStrip"], ngImport: i0, template: "<div class=\"flex items-center gap-1\">\r\n @if (showStartArrow()) {\r\n <button\r\n type=\"button\"\r\n class=\"shrink-0 appearance-none border-0 bg-transparent p-1 text-fg-subtle transition-colors duration-fast ease-emphasis hover:text-fg\"\r\n [attr.aria-label]=\"effectiveScrollStartLabel()\"\r\n (click)=\"scroller()?.scrollByDir(-1)\"\r\n >\r\n <span mfIcon [size]=\"16\" class=\"rtl:-scale-x-100\">chevron_left</span>\r\n </button>\r\n }\r\n\r\n <!-- Kayd\u0131rma kapsay\u0131c\u0131s\u0131 odaklanabilir de\u011Fil \u2014 ok tu\u015Fu gezinmesi burada delege; ger\u00E7ek odak roving tabindex ile alt sekmelerde. -->\r\n <!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\r\n <div mfTabScroller (keydown)=\"onKeydown($event)\">\r\n <div #row class=\"flex items-center gap-1 py-1\">\r\n @for (item of items(); track item.key) {\r\n <!-- Enter/Space se\u00E7imi \u00FCstteki kapsay\u0131c\u0131n\u0131n (keydown)'\u0131nda y\u00F6netiliyor (roving tabindex deseni). -->\r\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events -->\r\n <div\r\n role=\"tab\"\r\n [attr.data-tab-key]=\"item.key\"\r\n [attr.aria-selected]=\"item.key === activeKey()\"\r\n [attr.aria-controls]=\"item.key === activeKey() ? contentId() : null\"\r\n [tabindex]=\"tabIndexFor(item)\"\r\n [class]=\"tabClasses(item)\"\r\n (click)=\"select(item.key)\"\r\n (contextmenu)=\"onContextMenu($event, item)\"\r\n >\r\n @if (item.icon) {\r\n <span mfIcon [size]=\"14\">{{ item.icon }}</span>\r\n }\r\n <span class=\"truncate\">{{ item.label }}</span>\r\n @if (item.closable) {\r\n <button\r\n type=\"button\"\r\n tabindex=\"-1\"\r\n class=\"ms-0.5 inline-flex h-4 w-4 shrink-0 appearance-none items-center justify-center rounded-xs border-0 bg-transparent p-0 text-fg-subtle transition-colors duration-fast ease-emphasis hover:bg-surface-active hover:text-fg\"\r\n [attr.aria-label]=\"effectiveCloseLabel() + ': ' + item.label\"\r\n (click)=\"onCloseClick($event, item.key)\"\r\n >\r\n <span mfIcon [size]=\"13\">close</span>\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (showEndArrow()) {\r\n <button\r\n type=\"button\"\r\n class=\"shrink-0 appearance-none border-0 bg-transparent p-1 text-fg-subtle transition-colors duration-fast ease-emphasis hover:text-fg\"\r\n [attr.aria-label]=\"effectiveScrollEndLabel()\"\r\n (click)=\"scroller()?.scrollByDir(1)\"\r\n >\r\n <span mfIcon [size]=\"16\" class=\"rtl:-scale-x-100\">chevron_right</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: TabScroller, selector: "[mfTabScroller]", inputs: ["orientation"] }] });
530
+ }
531
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TabStrip, decorators: [{
532
+ type: Component,
533
+ args: [{ selector: 'mf-tab-strip', exportAs: 'mfTabStrip', imports: [Icon, TabScroller], host: { class: 'block', role: 'tablist' }, template: "<div class=\"flex items-center gap-1\">\r\n @if (showStartArrow()) {\r\n <button\r\n type=\"button\"\r\n class=\"shrink-0 appearance-none border-0 bg-transparent p-1 text-fg-subtle transition-colors duration-fast ease-emphasis hover:text-fg\"\r\n [attr.aria-label]=\"effectiveScrollStartLabel()\"\r\n (click)=\"scroller()?.scrollByDir(-1)\"\r\n >\r\n <span mfIcon [size]=\"16\" class=\"rtl:-scale-x-100\">chevron_left</span>\r\n </button>\r\n }\r\n\r\n <!-- Kayd\u0131rma kapsay\u0131c\u0131s\u0131 odaklanabilir de\u011Fil \u2014 ok tu\u015Fu gezinmesi burada delege; ger\u00E7ek odak roving tabindex ile alt sekmelerde. -->\r\n <!-- eslint-disable-next-line @angular-eslint/template/interactive-supports-focus -->\r\n <div mfTabScroller (keydown)=\"onKeydown($event)\">\r\n <div #row class=\"flex items-center gap-1 py-1\">\r\n @for (item of items(); track item.key) {\r\n <!-- Enter/Space se\u00E7imi \u00FCstteki kapsay\u0131c\u0131n\u0131n (keydown)'\u0131nda y\u00F6netiliyor (roving tabindex deseni). -->\r\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events -->\r\n <div\r\n role=\"tab\"\r\n [attr.data-tab-key]=\"item.key\"\r\n [attr.aria-selected]=\"item.key === activeKey()\"\r\n [attr.aria-controls]=\"item.key === activeKey() ? contentId() : null\"\r\n [tabindex]=\"tabIndexFor(item)\"\r\n [class]=\"tabClasses(item)\"\r\n (click)=\"select(item.key)\"\r\n (contextmenu)=\"onContextMenu($event, item)\"\r\n >\r\n @if (item.icon) {\r\n <span mfIcon [size]=\"14\">{{ item.icon }}</span>\r\n }\r\n <span class=\"truncate\">{{ item.label }}</span>\r\n @if (item.closable) {\r\n <button\r\n type=\"button\"\r\n tabindex=\"-1\"\r\n class=\"ms-0.5 inline-flex h-4 w-4 shrink-0 appearance-none items-center justify-center rounded-xs border-0 bg-transparent p-0 text-fg-subtle transition-colors duration-fast ease-emphasis hover:bg-surface-active hover:text-fg\"\r\n [attr.aria-label]=\"effectiveCloseLabel() + ': ' + item.label\"\r\n (click)=\"onCloseClick($event, item.key)\"\r\n >\r\n <span mfIcon [size]=\"13\">close</span>\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (showEndArrow()) {\r\n <button\r\n type=\"button\"\r\n class=\"shrink-0 appearance-none border-0 bg-transparent p-1 text-fg-subtle transition-colors duration-fast ease-emphasis hover:text-fg\"\r\n [attr.aria-label]=\"effectiveScrollEndLabel()\"\r\n (click)=\"scroller()?.scrollByDir(1)\"\r\n >\r\n <span mfIcon [size]=\"16\" class=\"rtl:-scale-x-100\">chevron_right</span>\r\n </button>\r\n }\r\n</div>\r\n" }]
534
+ }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], activeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeKey", required: true }] }, { type: i0.Output, args: ["activeKeyChange"] }], contentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentId", required: false }] }], scrollStartLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollStartLabel", required: false }] }], scrollEndLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollEndLabel", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], close: [{ type: i0.Output, args: ["close"] }], itemContextMenu: [{ type: i0.Output, args: ["itemContextMenu"] }], scroller: [{ type: i0.ViewChild, args: [i0.forwardRef(() => TabScroller), { isSignal: true }] }], rowEl: [{ type: i0.ViewChild, args: ['row', { isSignal: true }] }] } });
535
+
536
+ /**
537
+ * `<mf-tabs><mf-tab-list>...</mf-tab-list><mf-tab-panel>...</mf-tab-panel></mf-tabs>`
538
+ *
539
+ * Salt bir kapsayıcı — tüm ARIA/klavye/state mantığı `@angular/aria/tabs`'ın
540
+ * `Tabs` pattern'inden `hostDirectives` ile ödünç alınıyor (bkz.
541
+ * projects/ui-kit/README.md "a11y checklist": "mümkün olduğunca `@angular/aria`...
542
+ * elle ARIA yazmak son çare"). `hostDirectives`, ana bileşenin (`mf-tabs`)
543
+ * host elemanına `Tabs`'ın DI sağlayıcısını (`TABS` token) ekliyor — alttaki
544
+ * `mf-tab-list`/`mf-tab-panel` bunu `inject()` ile bulup kendini
545
+ * kaydediyor, template'te `ngTabs` attribute'unu ELLE yazmaya gerek yok
546
+ * (`hostDirectives`'te selector yok sayılır, bkz. Angular directive
547
+ * composition API).
548
+ */
549
+ class Tabs {
550
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Tabs, deps: [], target: i0.ɵɵFactoryTarget.Component });
551
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: Tabs, isStandalone: true, selector: "mf-tabs", host: { classAttribute: "block" }, exportAs: ["mfTabs"], hostDirectives: [{ directive: i1.Tabs }], ngImport: i0, template: '<ng-content />', isInline: true });
552
+ }
553
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Tabs, decorators: [{
554
+ type: Component,
555
+ args: [{
556
+ selector: 'mf-tabs',
557
+ exportAs: 'mfTabs',
558
+ hostDirectives: [Tabs$1],
559
+ host: { class: 'block' },
560
+ template: '<ng-content />',
561
+ }]
562
+ }] });
563
+
564
+ /**
565
+ * Generated bundle index. Do not edit.
566
+ */
567
+
568
+ export { Tab, TabList, TabPanel, TabScroller, TabStrip, Tabs, tabListVariants, tabVariants };
569
+ //# sourceMappingURL=mesgflow-ui-kit-tabs.mjs.map