@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,99 @@
1
+ import * as i1 from '@angular/aria/toolbar';
2
+ import { Toolbar as Toolbar$1, ToolbarWidget } from '@angular/aria/toolbar';
3
+ import * as i0 from '@angular/core';
4
+ import { Component, inject, input, computed, Directive } from '@angular/core';
5
+ import { cn } from '@mesgflow/ui-kit/core';
6
+ import { cva } from 'class-variance-authority';
7
+
8
+ /**
9
+ * `<mf-toolbar><button mfToolbarButton value="bold">B</button>...</mf-toolbar>`
10
+ *
11
+ * Genel amaçlı gruplu buton çubuğu — zengin metin editörü/tuval araç
12
+ * çubukları için düşünüldü. ARIA/klavye (roving tabindex, ok tuşu
13
+ * navigasyonu) `@angular/aria/toolbar`'ın `Toolbar` pattern'inden
14
+ * `hostDirectives` ile geliyor — `SegmentedControl`'ün AYNI pattern ailesini
15
+ * kullandığı ama SEÇİM DURUMU (tek/çoklu) tuttuğu yere karşılık, bu primitif
16
+ * seçim durumu TUTMAZ: tekil aksiyon düğmeleri için `mfToolbarButton`
17
+ * yeter, dışlayıcı bir alt-grup gerekiyorsa (ör. hizalama) tüketici kendi
18
+ * `<div ngToolbarWidgetGroup [multi]="false">` sarmalayıcısını ekler (bkz.
19
+ * `@angular/aria/toolbar`'ın kendi JSDoc örneği).
20
+ */
21
+ class Toolbar {
22
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Toolbar, deps: [], target: i0.ɵɵFactoryTarget.Component });
23
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: Toolbar, isStandalone: true, selector: "mf-toolbar", host: { classAttribute: "flex items-center gap-0.5 rounded-lg border border-hairline bg-surface p-1" }, exportAs: ["mfToolbar"], hostDirectives: [{ directive: i1.Toolbar, inputs: ["orientation", "orientation", "disabled", "disabled", "wrap", "wrap"] }], ngImport: i0, template: '<ng-content />', isInline: true });
24
+ }
25
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Toolbar, decorators: [{
26
+ type: Component,
27
+ args: [{
28
+ selector: 'mf-toolbar',
29
+ exportAs: 'mfToolbar',
30
+ hostDirectives: [{ directive: Toolbar$1, inputs: ['orientation', 'disabled', 'wrap'] }],
31
+ host: {
32
+ class: 'flex items-center gap-0.5 rounded-lg border border-hairline bg-surface p-1',
33
+ },
34
+ template: '<ng-content />',
35
+ }]
36
+ }] });
37
+
38
+ const toolbarButtonVariants = cva('flex h-8 w-8 shrink-0 cursor-pointer items-center justify-center rounded-sm border-0 bg-transparent text-fg-muted transition-colors duration-fast ease-emphasis active:scale-[0.99] ' +
39
+ 'hover:bg-surface-alt hover:text-fg focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring ' +
40
+ 'disabled:pointer-events-none disabled:opacity-50 disabled:active:scale-100', {
41
+ variants: {
42
+ active: {
43
+ true: 'bg-primary-tint text-primary-tint-fg',
44
+ false: '',
45
+ },
46
+ },
47
+ defaultVariants: { active: false },
48
+ });
49
+
50
+ /**
51
+ * `<button mfToolbarButton value="bold" [pressed]="isBold()">B</button>` —
52
+ * `mf-toolbar` içine konur. `pressed`, bir `ngToolbarWidgetGroup` sarmalayıcısı
53
+ * OLMADAN da (ör. bağımsız bir toggle — kalın/italik gibi birbirinden bağımsız
54
+ * açma-kapama düğmeleri) tüketicinin kendi state'inden görsel "aktif" durumunu
55
+ * bildirmesi için var; bir grup içindeyse `widget.selected()` zaten aynı
56
+ * görevi görür, ikisi OR'lanıyor.
57
+ */
58
+ class ToolbarButton {
59
+ widget = inject(ToolbarWidget);
60
+ pressed = input(false, /* @ts-ignore */
61
+ ...(ngDevMode ? [{ debugName: "pressed" }] : /* istanbul ignore next */ []));
62
+ classes = computed(() => cn(toolbarButtonVariants({ active: this.pressed() || this.widget.selected() })), /* @ts-ignore */
63
+ ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
64
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ToolbarButton, deps: [], target: i0.ɵɵFactoryTarget.Directive });
65
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.6", type: ToolbarButton, isStandalone: true, selector: "button[mfToolbarButton]", inputs: { pressed: { classPropertyName: "pressed", publicName: "pressed", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.type": "'button'", "class": "classes()" } }, hostDirectives: [{ directive: i1.ToolbarWidget, inputs: ["value", "value", "disabled", "disabled", "id", "id"] }], ngImport: i0 });
66
+ }
67
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ToolbarButton, decorators: [{
68
+ type: Directive,
69
+ args: [{
70
+ selector: 'button[mfToolbarButton]',
71
+ hostDirectives: [{ directive: ToolbarWidget, inputs: ['value', 'disabled', 'id'] }],
72
+ host: { '[attr.type]': "'button'", '[class]': 'classes()' },
73
+ }]
74
+ }], propDecorators: { pressed: [{ type: i0.Input, args: [{ isSignal: true, alias: "pressed", required: false }] }] } });
75
+
76
+ /** `<mf-toolbar-separator />` — `mf-toolbar` içindeki buton gruplarını ayırmak için dikey çizgi. */
77
+ class ToolbarSeparator {
78
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ToolbarSeparator, deps: [], target: i0.ɵɵFactoryTarget.Component });
79
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: ToolbarSeparator, isStandalone: true, selector: "mf-toolbar-separator", host: { attributes: { "role": "separator", "aria-orientation": "vertical" }, classAttribute: "mx-1 h-5 w-px shrink-0 self-center bg-border" }, ngImport: i0, template: '', isInline: true });
80
+ }
81
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ToolbarSeparator, decorators: [{
82
+ type: Component,
83
+ args: [{
84
+ selector: 'mf-toolbar-separator',
85
+ host: {
86
+ class: 'mx-1 h-5 w-px shrink-0 self-center bg-border',
87
+ role: 'separator',
88
+ 'aria-orientation': 'vertical',
89
+ },
90
+ template: '',
91
+ }]
92
+ }] });
93
+
94
+ /**
95
+ * Generated bundle index. Do not edit.
96
+ */
97
+
98
+ export { Toolbar, ToolbarButton, ToolbarSeparator, toolbarButtonVariants };
99
+ //# sourceMappingURL=mesgflow-ui-kit-toolbar.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesgflow-ui-kit-toolbar.mjs","sources":["../../../projects/ui-kit/toolbar/toolbar.ts","../../../projects/ui-kit/toolbar/toolbar.variants.ts","../../../projects/ui-kit/toolbar/toolbar-button.ts","../../../projects/ui-kit/toolbar/toolbar-separator.ts","../../../projects/ui-kit/toolbar/mesgflow-ui-kit-toolbar.ts"],"sourcesContent":["import { Toolbar as AriaToolbar } from '@angular/aria/toolbar';\r\nimport { Component } from '@angular/core';\r\n\r\n/**\r\n * `<mf-toolbar><button mfToolbarButton value=\"bold\">B</button>...</mf-toolbar>`\r\n *\r\n * Genel amaçlı gruplu buton çubuğu — zengin metin editörü/tuval araç\r\n * çubukları için düşünüldü. ARIA/klavye (roving tabindex, ok tuşu\r\n * navigasyonu) `@angular/aria/toolbar`'ın `Toolbar` pattern'inden\r\n * `hostDirectives` ile geliyor — `SegmentedControl`'ün AYNI pattern ailesini\r\n * kullandığı ama SEÇİM DURUMU (tek/çoklu) tuttuğu yere karşılık, bu primitif\r\n * seçim durumu TUTMAZ: tekil aksiyon düğmeleri için `mfToolbarButton`\r\n * yeter, dışlayıcı bir alt-grup gerekiyorsa (ör. hizalama) tüketici kendi\r\n * `<div ngToolbarWidgetGroup [multi]=\"false\">` sarmalayıcısını ekler (bkz.\r\n * `@angular/aria/toolbar`'ın kendi JSDoc örneği).\r\n */\r\n@Component({\r\n selector: 'mf-toolbar',\r\n exportAs: 'mfToolbar',\r\n hostDirectives: [{ directive: AriaToolbar, inputs: ['orientation', 'disabled', 'wrap'] }],\r\n host: {\r\n class: 'flex items-center gap-0.5 rounded-lg border border-hairline bg-surface p-1',\r\n },\r\n template: '<ng-content />',\r\n})\r\nexport class Toolbar {}\r\n","import { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nexport const toolbarButtonVariants = cva(\r\n 'flex h-8 w-8 shrink-0 cursor-pointer items-center justify-center rounded-sm border-0 bg-transparent text-fg-muted transition-colors duration-fast ease-emphasis active:scale-[0.99] ' +\r\n 'hover:bg-surface-alt hover:text-fg focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring ' +\r\n 'disabled:pointer-events-none disabled:opacity-50 disabled:active:scale-100',\r\n {\r\n variants: {\r\n active: {\r\n true: 'bg-primary-tint text-primary-tint-fg',\r\n false: '',\r\n },\r\n },\r\n defaultVariants: { active: false },\r\n },\r\n);\r\n\r\nexport type ToolbarButtonActive = VariantProps<typeof toolbarButtonVariants>['active'];\r\n","import { ToolbarWidget as AriaToolbarWidget } from '@angular/aria/toolbar';\r\nimport { Directive, computed, inject, input } from '@angular/core';\r\nimport { cn } from '@mesgflow/ui-kit/core';\r\nimport { toolbarButtonVariants } from './toolbar.variants';\r\n\r\n/**\r\n * `<button mfToolbarButton value=\"bold\" [pressed]=\"isBold()\">B</button>` —\r\n * `mf-toolbar` içine konur. `pressed`, bir `ngToolbarWidgetGroup` sarmalayıcısı\r\n * OLMADAN da (ör. bağımsız bir toggle — kalın/italik gibi birbirinden bağımsız\r\n * açma-kapama düğmeleri) tüketicinin kendi state'inden görsel \"aktif\" durumunu\r\n * bildirmesi için var; bir grup içindeyse `widget.selected()` zaten aynı\r\n * görevi görür, ikisi OR'lanıyor.\r\n */\r\n@Directive({\r\n selector: 'button[mfToolbarButton]',\r\n hostDirectives: [{ directive: AriaToolbarWidget, inputs: ['value', 'disabled', 'id'] }],\r\n host: { '[attr.type]': \"'button'\", '[class]': 'classes()' },\r\n})\r\nexport class ToolbarButton {\r\n private readonly widget = inject(AriaToolbarWidget);\r\n readonly pressed = input(false);\r\n\r\n protected readonly classes = computed(() =>\r\n cn(toolbarButtonVariants({ active: this.pressed() || this.widget.selected() })),\r\n );\r\n}\r\n","import { Component } from '@angular/core';\r\n\r\n/** `<mf-toolbar-separator />` — `mf-toolbar` içindeki buton gruplarını ayırmak için dikey çizgi. */\r\n@Component({\r\n selector: 'mf-toolbar-separator',\r\n host: {\r\n class: 'mx-1 h-5 w-px shrink-0 self-center bg-border',\r\n role: 'separator',\r\n 'aria-orientation': 'vertical',\r\n },\r\n template: '',\r\n})\r\nexport class ToolbarSeparator {}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["AriaToolbar","AriaToolbarWidget"],"mappings":"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"}
@@ -0,0 +1,160 @@
1
+ import { Overlay } from '@angular/cdk/overlay';
2
+ import { TemplatePortal, DomPortal } from '@angular/cdk/portal';
3
+ import * as i0 from '@angular/core';
4
+ import { input, inject, ElementRef, ViewContainerRef, Directive } from '@angular/core';
5
+
6
+ const POSITIONS = {
7
+ top: [
8
+ { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -8 },
9
+ { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: 8 },
10
+ ],
11
+ bottom: [
12
+ { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: 8 },
13
+ { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -8 },
14
+ ],
15
+ left: [
16
+ { originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -8 },
17
+ { originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: 8 },
18
+ ],
19
+ right: [
20
+ { originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: 8 },
21
+ { originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -8 },
22
+ ],
23
+ };
24
+ /** `role`/`pointer-events-none` DIŞINDAKİ görsel kabuk — CDK'nın `panelClass`'ı ile OVERLAY PANELİNİN kendisine uygulanır (bkz. `show()`), hem düz metin hem şablon içeriği AYNI balon çerçevesini paylaşır. */
25
+ const BUBBLE_CLASSES = [
26
+ 'rounded-sm',
27
+ 'bg-surface-inverse',
28
+ 'px-2',
29
+ 'py-1',
30
+ 'text-xs',
31
+ 'font-medium',
32
+ 'whitespace-nowrap',
33
+ 'text-fg-inverse',
34
+ 'shadow-2',
35
+ ];
36
+ /**
37
+ * `<button mfButton [mfTooltip]="'Filtreler'">` (düz metin) veya
38
+ * `<button mfButton [mfTooltipContent]="richTpl">` (bkz. aşağıdaki örnek —
39
+ * zengin/reaktif içerik) — hover/focus'ta CDK Overlay ile konumlanan bir
40
+ * balon gösterir. `mfTooltipContent` VERİLMİŞSE `mfTooltip` YOK SAYILIR.
41
+ *
42
+ * ```html
43
+ * <button mfButton [mfTooltipContent]="kbdHint">Kaydet</button>
44
+ * <ng-template #kbdHint>
45
+ * Kaydet <kbd mfKbd>Ctrl</kbd>+<kbd mfKbd>S</kbd>
46
+ * </ng-template>
47
+ * ```
48
+ *
49
+ * Düz metin YOLU (ayrı bir Angular component/`ComponentPortal` kurmadan) ham
50
+ * bir DOM node'u ile çiziliyor — statik metin için fazla makine olurdu.
51
+ * Şablon YOLU `TemplatePortal` kullanır (gerçek Angular içeriği — binding/
52
+ * directive/başka bir bileşen barındırabilir), bunun için `ViewContainerRef`
53
+ * gerekiyor.
54
+ */
55
+ class Tooltip {
56
+ /** Boş string verilirse (ve `mfTooltipContent` de yoksa) tooltip tamamen devre dışı kalır (ör. koşullu etiketler için). */
57
+ mfTooltip = input('', /* @ts-ignore */
58
+ ...(ngDevMode ? [{ debugName: "mfTooltip" }] : /* istanbul ignore next */ []));
59
+ /** Verilmişse `mfTooltip`'in YERİNE geçer — bkz. sınıf üstündeki JSDoc örneği. */
60
+ mfTooltipContent = input(null, /* @ts-ignore */
61
+ ...(ngDevMode ? [{ debugName: "mfTooltipContent" }] : /* istanbul ignore next */ []));
62
+ tooltipPosition = input('top', /* @ts-ignore */
63
+ ...(ngDevMode ? [{ debugName: "tooltipPosition" }] : /* istanbul ignore next */ []));
64
+ overlay = inject(Overlay);
65
+ elementRef = inject((ElementRef));
66
+ viewContainerRef = inject(ViewContainerRef);
67
+ overlayRef;
68
+ bubbleEl;
69
+ showHandle;
70
+ scheduleShow() {
71
+ if (!this.mfTooltip() && !this.mfTooltipContent())
72
+ return;
73
+ clearTimeout(this.showHandle);
74
+ this.showHandle = setTimeout(() => this.show(), 350);
75
+ }
76
+ show() {
77
+ const template = this.mfTooltipContent();
78
+ const text = this.mfTooltip();
79
+ if ((!template && !text) || this.overlayRef)
80
+ return;
81
+ const positionStrategy = this.overlay
82
+ .position()
83
+ .flexibleConnectedTo(this.elementRef)
84
+ .withPositions(POSITIONS[this.tooltipPosition()])
85
+ .withPush(true);
86
+ this.overlayRef = this.overlay.create({
87
+ positionStrategy,
88
+ scrollStrategy: this.overlay.scrollStrategies.reposition(),
89
+ panelClass: [...BUBBLE_CLASSES, 'animate-overlay-in'],
90
+ });
91
+ this.overlayRef.overlayElement.setAttribute('role', 'tooltip');
92
+ this.overlayRef.overlayElement.classList.add('pointer-events-none');
93
+ if (template) {
94
+ this.overlayRef.attach(new TemplatePortal(template, this.viewContainerRef));
95
+ return;
96
+ }
97
+ // Düz `appendChild` YETMİYOR: CDK'nın konumlandırma stratejisi (flexibleConnectedTo)
98
+ // sadece `OverlayRef.attach()` çağrıldığında çalışıyor — atlanırsa panel {0,0,0,0}
99
+ // boyutunda kalıp hiçbir yerde görünmüyor (gerçek bulgu, ui-kit'te yakalandı).
100
+ // `DomPortal` gerçek bir Angular component'i olmadan (ComponentPortal'a gerek
101
+ // kalmadan) ham bir DOM node'unu attach akışına sokuyor — ama `DomPortal`
102
+ // node'un ZATEN bir parent'a bağlı olmasını şart koşuyor (detach sonrası eski
103
+ // yerine geri koyabilmek için konumunu hatırlıyor), o yüzden önce `body`'ye
104
+ // ekleyip Portal'ı ondan SONRA kuruyoruz.
105
+ const bubble = document.createElement('span');
106
+ bubble.textContent = text;
107
+ document.body.appendChild(bubble);
108
+ this.overlayRef.attach(new DomPortal(bubble));
109
+ this.bubbleEl = bubble;
110
+ }
111
+ /**
112
+ * Public: `SearchInput` gibi, kendi state değişimiyle tooltip'i ANINDA
113
+ * kapatmak isteyen tüketiciler için (bkz. search-input.ts `expand()`) —
114
+ * BİLEREK senkron: tooltip hover/focus/Escape gibi yüksek frekanslı,
115
+ * anlık etkileşimlerle kapanıyor, `Popover`'ın gecikmeli-dispose deseni
116
+ * (bkz. `popover.ts` `EXIT_MS`) burada gereksiz karmaşıklık + testlerin
117
+ * beklediği "blur → anında kaldırılır" sözleşmesini bozardı (bkz.
118
+ * `tooltip.spec.ts`). Giriş animasyonu (`show()`teki `animate-overlay-in`)
119
+ * yeterli — önceden tooltip'in HİÇ animasyonu yoktu (gerçek bulgu).
120
+ */
121
+ hide() {
122
+ clearTimeout(this.showHandle);
123
+ this.overlayRef?.dispose();
124
+ this.overlayRef = undefined;
125
+ // `dispose()` DomPortal'ı "attach öncesi" body konumuna geri koyuyor,
126
+ // DOM'dan silmiyor — silinmezse hover'dan çıkınca balon body'nin sonunda
127
+ // öksüz kalıp görünür kalıyordu (gerçek bulgu, birden fazla satırda
128
+ // sırayla hover edince ui-kit'te yakalandı). Şablon yolunda `bubbleEl`
129
+ // hiç atanmadığı için bu satır NO-OP.
130
+ this.bubbleEl?.remove();
131
+ this.bubbleEl = undefined;
132
+ }
133
+ ngOnDestroy() {
134
+ this.hide();
135
+ }
136
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Tooltip, deps: [], target: i0.ɵɵFactoryTarget.Directive });
137
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.6", type: Tooltip, isStandalone: true, selector: "[mfTooltip], [mfTooltipContent]", inputs: { mfTooltip: { classPropertyName: "mfTooltip", publicName: "mfTooltip", isSignal: true, isRequired: false, transformFunction: null }, mfTooltipContent: { classPropertyName: "mfTooltipContent", publicName: "mfTooltipContent", isSignal: true, isRequired: false, transformFunction: null }, tooltipPosition: { classPropertyName: "tooltipPosition", publicName: "tooltipPosition", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "scheduleShow()", "mouseleave": "hide()", "focus": "show()", "blur": "hide()", "keydown.escape": "hide()", "click": "hide()" } }, exportAs: ["mfTooltip"], ngImport: i0 });
138
+ }
139
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Tooltip, decorators: [{
140
+ type: Directive,
141
+ args: [{
142
+ selector: '[mfTooltip], [mfTooltipContent]',
143
+ exportAs: 'mfTooltip',
144
+ host: {
145
+ '(mouseenter)': 'scheduleShow()',
146
+ '(mouseleave)': 'hide()',
147
+ '(focus)': 'show()',
148
+ '(blur)': 'hide()',
149
+ '(keydown.escape)': 'hide()',
150
+ '(click)': 'hide()',
151
+ },
152
+ }]
153
+ }], propDecorators: { mfTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "mfTooltip", required: false }] }], mfTooltipContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "mfTooltipContent", required: false }] }], tooltipPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipPosition", required: false }] }] } });
154
+
155
+ /**
156
+ * Generated bundle index. Do not edit.
157
+ */
158
+
159
+ export { Tooltip };
160
+ //# sourceMappingURL=mesgflow-ui-kit-tooltip.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesgflow-ui-kit-tooltip.mjs","sources":["../../../projects/ui-kit/tooltip/tooltip.ts","../../../projects/ui-kit/tooltip/mesgflow-ui-kit-tooltip.ts"],"sourcesContent":["import { Overlay, type ConnectedPosition, type OverlayRef } from '@angular/cdk/overlay';\r\nimport { DomPortal, TemplatePortal } from '@angular/cdk/portal';\r\nimport {\r\n Directive,\r\n ElementRef,\r\n OnDestroy,\r\n TemplateRef,\r\n ViewContainerRef,\r\n inject,\r\n input,\r\n} from '@angular/core';\r\n\r\nexport type TooltipPosition = 'top' | 'bottom' | 'left' | 'right';\r\n\r\nconst POSITIONS: Record<TooltipPosition, ConnectedPosition[]> = {\r\n top: [\r\n { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -8 },\r\n { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: 8 },\r\n ],\r\n bottom: [\r\n { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: 8 },\r\n { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -8 },\r\n ],\r\n left: [\r\n { originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -8 },\r\n { originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: 8 },\r\n ],\r\n right: [\r\n { originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: 8 },\r\n { originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -8 },\r\n ],\r\n};\r\n\r\n/** `role`/`pointer-events-none` DIŞINDAKİ görsel kabuk — CDK'nın `panelClass`'ı ile OVERLAY PANELİNİN kendisine uygulanır (bkz. `show()`), hem düz metin hem şablon içeriği AYNI balon çerçevesini paylaşır. */\r\nconst BUBBLE_CLASSES = [\r\n 'rounded-sm',\r\n 'bg-surface-inverse',\r\n 'px-2',\r\n 'py-1',\r\n 'text-xs',\r\n 'font-medium',\r\n 'whitespace-nowrap',\r\n 'text-fg-inverse',\r\n 'shadow-2',\r\n];\r\n\r\n/**\r\n * `<button mfButton [mfTooltip]=\"'Filtreler'\">` (düz metin) veya\r\n * `<button mfButton [mfTooltipContent]=\"richTpl\">` (bkz. aşağıdaki örnek —\r\n * zengin/reaktif içerik) — hover/focus'ta CDK Overlay ile konumlanan bir\r\n * balon gösterir. `mfTooltipContent` VERİLMİŞSE `mfTooltip` YOK SAYILIR.\r\n *\r\n * ```html\r\n * <button mfButton [mfTooltipContent]=\"kbdHint\">Kaydet</button>\r\n * <ng-template #kbdHint>\r\n * Kaydet <kbd mfKbd>Ctrl</kbd>+<kbd mfKbd>S</kbd>\r\n * </ng-template>\r\n * ```\r\n *\r\n * Düz metin YOLU (ayrı bir Angular component/`ComponentPortal` kurmadan) ham\r\n * bir DOM node'u ile çiziliyor — statik metin için fazla makine olurdu.\r\n * Şablon YOLU `TemplatePortal` kullanır (gerçek Angular içeriği — binding/\r\n * directive/başka bir bileşen barındırabilir), bunun için `ViewContainerRef`\r\n * gerekiyor.\r\n */\r\n@Directive({\r\n selector: '[mfTooltip], [mfTooltipContent]',\r\n exportAs: 'mfTooltip',\r\n host: {\r\n '(mouseenter)': 'scheduleShow()',\r\n '(mouseleave)': 'hide()',\r\n '(focus)': 'show()',\r\n '(blur)': 'hide()',\r\n '(keydown.escape)': 'hide()',\r\n '(click)': 'hide()',\r\n },\r\n})\r\nexport class Tooltip implements OnDestroy {\r\n /** Boş string verilirse (ve `mfTooltipContent` de yoksa) tooltip tamamen devre dışı kalır (ör. koşullu etiketler için). */\r\n readonly mfTooltip = input('');\r\n /** Verilmişse `mfTooltip`'in YERİNE geçer — bkz. sınıf üstündeki JSDoc örneği. */\r\n readonly mfTooltipContent = input<TemplateRef<unknown> | null>(null);\r\n readonly tooltipPosition = input<TooltipPosition>('top');\r\n\r\n private readonly overlay = inject(Overlay);\r\n private readonly elementRef = inject(ElementRef<HTMLElement>);\r\n private readonly viewContainerRef = inject(ViewContainerRef);\r\n private overlayRef?: OverlayRef;\r\n private bubbleEl?: HTMLElement;\r\n private showHandle?: ReturnType<typeof setTimeout>;\r\n\r\n protected scheduleShow(): void {\r\n if (!this.mfTooltip() && !this.mfTooltipContent()) return;\r\n clearTimeout(this.showHandle);\r\n this.showHandle = setTimeout(() => this.show(), 350);\r\n }\r\n\r\n protected show(): void {\r\n const template = this.mfTooltipContent();\r\n const text = this.mfTooltip();\r\n if ((!template && !text) || this.overlayRef) return;\r\n\r\n const positionStrategy = this.overlay\r\n .position()\r\n .flexibleConnectedTo(this.elementRef)\r\n .withPositions(POSITIONS[this.tooltipPosition()])\r\n .withPush(true);\r\n\r\n this.overlayRef = this.overlay.create({\r\n positionStrategy,\r\n scrollStrategy: this.overlay.scrollStrategies.reposition(),\r\n panelClass: [...BUBBLE_CLASSES, 'animate-overlay-in'],\r\n });\r\n this.overlayRef.overlayElement.setAttribute('role', 'tooltip');\r\n this.overlayRef.overlayElement.classList.add('pointer-events-none');\r\n\r\n if (template) {\r\n this.overlayRef.attach(new TemplatePortal(template, this.viewContainerRef));\r\n return;\r\n }\r\n\r\n // Düz `appendChild` YETMİYOR: CDK'nın konumlandırma stratejisi (flexibleConnectedTo)\r\n // sadece `OverlayRef.attach()` çağrıldığında çalışıyor — atlanırsa panel {0,0,0,0}\r\n // boyutunda kalıp hiçbir yerde görünmüyor (gerçek bulgu, ui-kit'te yakalandı).\r\n // `DomPortal` gerçek bir Angular component'i olmadan (ComponentPortal'a gerek\r\n // kalmadan) ham bir DOM node'unu attach akışına sokuyor — ama `DomPortal`\r\n // node'un ZATEN bir parent'a bağlı olmasını şart koşuyor (detach sonrası eski\r\n // yerine geri koyabilmek için konumunu hatırlıyor), o yüzden önce `body`'ye\r\n // ekleyip Portal'ı ondan SONRA kuruyoruz.\r\n const bubble = document.createElement('span');\r\n bubble.textContent = text;\r\n document.body.appendChild(bubble);\r\n this.overlayRef.attach(new DomPortal(bubble));\r\n this.bubbleEl = bubble;\r\n }\r\n\r\n /**\r\n * Public: `SearchInput` gibi, kendi state değişimiyle tooltip'i ANINDA\r\n * kapatmak isteyen tüketiciler için (bkz. search-input.ts `expand()`) —\r\n * BİLEREK senkron: tooltip hover/focus/Escape gibi yüksek frekanslı,\r\n * anlık etkileşimlerle kapanıyor, `Popover`'ın gecikmeli-dispose deseni\r\n * (bkz. `popover.ts` `EXIT_MS`) burada gereksiz karmaşıklık + testlerin\r\n * beklediği \"blur → anında kaldırılır\" sözleşmesini bozardı (bkz.\r\n * `tooltip.spec.ts`). Giriş animasyonu (`show()`teki `animate-overlay-in`)\r\n * yeterli — önceden tooltip'in HİÇ animasyonu yoktu (gerçek bulgu).\r\n */\r\n hide(): void {\r\n clearTimeout(this.showHandle);\r\n this.overlayRef?.dispose();\r\n this.overlayRef = undefined;\r\n // `dispose()` DomPortal'ı \"attach öncesi\" body konumuna geri koyuyor,\r\n // DOM'dan silmiyor — silinmezse hover'dan çıkınca balon body'nin sonunda\r\n // öksüz kalıp görünür kalıyordu (gerçek bulgu, birden fazla satırda\r\n // sırayla hover edince ui-kit'te yakalandı). Şablon yolunda `bubbleEl`\r\n // hiç atanmadığı için bu satır NO-OP.\r\n this.bubbleEl?.remove();\r\n this.bubbleEl = undefined;\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.hide();\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,272 @@
1
+ import * as i0 from '@angular/core';
2
+ import { signal, computed, inject, ElementRef, afterRenderEffect, Component, Injector, DOCUMENT, Service } from '@angular/core';
3
+ import { createOverlayRef, createGlobalPositionStrategy, createFlexibleConnectedPositionStrategy, createRepositionScrollStrategy } from '@angular/cdk/overlay';
4
+ import { ComponentPortal } from '@angular/cdk/portal';
5
+ import { MF_TOUR_LABELS, isRtl } from '@mesgflow/ui-kit/core';
6
+ import * as i1 from '@angular/cdk/a11y';
7
+ import { A11yModule } from '@angular/cdk/a11y';
8
+ import { Button } from '@mesgflow/ui-kit/button';
9
+ import { Icon } from '@mesgflow/ui-kit/icon';
10
+
11
+ /** Bir tur çalışmasının durumu — servis ile spot ışığı ve kart bileşenleri bunu paylaşır. */
12
+ class TourRun {
13
+ steps;
14
+ onNavigate;
15
+ onFinish;
16
+ index = signal(0, /* @ts-ignore */
17
+ ...(ngDevMode ? [{ debugName: "index" }] : /* istanbul ignore next */ []));
18
+ /** Hedefin viewport'taki kutusu (padding dahil); hedefsiz adımda `null`. */
19
+ rect = signal(null, /* @ts-ignore */
20
+ ...(ngDevMode ? [{ debugName: "rect" }] : /* istanbul ignore next */ []));
21
+ step = computed(() => this.steps[this.index()], /* @ts-ignore */
22
+ ...(ngDevMode ? [{ debugName: "step" }] : /* istanbul ignore next */ []));
23
+ isFirst = computed(() => this.index() === 0, /* @ts-ignore */
24
+ ...(ngDevMode ? [{ debugName: "isFirst" }] : /* istanbul ignore next */ []));
25
+ isLast = computed(() => this.index() === this.steps.length - 1, /* @ts-ignore */
26
+ ...(ngDevMode ? [{ debugName: "isLast" }] : /* istanbul ignore next */ []));
27
+ constructor(steps, onNavigate, onFinish) {
28
+ this.steps = steps;
29
+ this.onNavigate = onNavigate;
30
+ this.onFinish = onFinish;
31
+ }
32
+ next() {
33
+ if (this.isLast())
34
+ this.onFinish('completed');
35
+ else
36
+ this.onNavigate(this.index() + 1);
37
+ }
38
+ back() {
39
+ if (!this.isFirst())
40
+ this.onNavigate(this.index() - 1);
41
+ }
42
+ skip() {
43
+ this.onFinish('skipped');
44
+ }
45
+ }
46
+
47
+ let tourCardIdSeq = 0;
48
+ /**
49
+ * Adım kartı — modal `role="dialog"`, odak kartın içinde tutulur (`cdkTrapFocus`). Her adım
50
+ * değişiminde odak kartın KENDİSİNE taşınır: ekran okuyucu `aria-labelledby` (başlık) +
51
+ * `aria-describedby` (içerik) üzerinden yeni adımı baştan okur. Esc turu atlar.
52
+ */
53
+ class TourCard {
54
+ run = inject(TourRun);
55
+ labels = inject(MF_TOUR_LABELS);
56
+ host = inject(ElementRef);
57
+ id = `mf-tour-${++tourCardIdSeq}`;
58
+ titleId = `${this.id}-title`;
59
+ contentId = `${this.id}-content`;
60
+ constructor() {
61
+ afterRenderEffect(() => {
62
+ this.run.index();
63
+ this.host.nativeElement.querySelector('[role="dialog"]')?.focus();
64
+ });
65
+ }
66
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TourCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
67
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: TourCard, isStandalone: true, selector: "mf-tour-card", ngImport: i0, template: "<div\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n tabindex=\"-1\"\r\n cdkTrapFocus\r\n [attr.aria-labelledby]=\"titleId\"\r\n [attr.aria-describedby]=\"contentId\"\r\n class=\"w-[min(20rem,calc(100vw-2rem))] animate-overlay-in rounded-xl border border-hairline bg-overlay p-4 shadow-3 outline-none\"\r\n (keydown.escape)=\"run.skip()\"\r\n>\r\n <div class=\"flex items-center justify-between gap-2\">\r\n <span class=\"font-mono text-eyebrow text-help uppercase tabular-nums\">\r\n {{ run.index() + 1 }} {{ labels().stepOf }} {{ run.steps.length }}\r\n </span>\r\n <button\r\n type=\"button\"\r\n class=\"-me-1.5 inline-flex size-7 cursor-pointer appearance-none items-center justify-center rounded-md border-0 bg-transparent text-fg-subtle transition-colors duration-fast ease-emphasis hover:bg-state-hover hover:text-fg focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring\"\r\n [attr.aria-label]=\"labels().skip\"\r\n (click)=\"run.skip()\"\r\n >\r\n <span mfIcon [size]=\"16\">close</span>\r\n </button>\r\n </div>\r\n\r\n <h2 [id]=\"titleId\" class=\"mt-1.5 font-display text-base font-semibold text-fg\">\r\n {{ run.step().title }}\r\n </h2>\r\n <p [id]=\"contentId\" class=\"mt-1 text-sm text-fg-muted\">{{ run.step().content }}</p>\r\n\r\n <div class=\"mt-4 flex items-center gap-2\">\r\n <!-- \u0130lerleme: ad\u0131m ba\u015F\u0131na bir \u00E7izgi; salt g\u00F6rsel, say\u0131 zaten yukar\u0131da. -->\r\n <div class=\"flex flex-1 items-center gap-1\" aria-hidden=\"true\">\r\n @for (step of run.steps; track $index) {\r\n <span\r\n class=\"h-1 flex-1 rounded-full transition-colors duration-base ease-emphasis\"\r\n [class]=\"$index <= run.index() ? 'bg-help' : 'bg-surface-alt'\"\r\n ></span>\r\n }\r\n </div>\r\n @if (!run.isFirst()) {\r\n <button\r\n mfButton\r\n appearance=\"text\"\r\n tone=\"neutral\"\r\n size=\"sm\"\r\n type=\"button\"\r\n (click)=\"run.back()\"\r\n >\r\n {{ labels().back }}\r\n </button>\r\n }\r\n <button mfButton tone=\"help\" size=\"sm\" type=\"button\" (click)=\"run.next()\">\r\n {{ run.isLast() ? labels().done : labels().next }}\r\n </button>\r\n </div>\r\n</div>\r\n", dependencies: [{ kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i1.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { 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"] }] });
68
+ }
69
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TourCard, decorators: [{
70
+ type: Component,
71
+ args: [{ selector: 'mf-tour-card', imports: [A11yModule, Button, Icon], template: "<div\r\n role=\"dialog\"\r\n aria-modal=\"true\"\r\n tabindex=\"-1\"\r\n cdkTrapFocus\r\n [attr.aria-labelledby]=\"titleId\"\r\n [attr.aria-describedby]=\"contentId\"\r\n class=\"w-[min(20rem,calc(100vw-2rem))] animate-overlay-in rounded-xl border border-hairline bg-overlay p-4 shadow-3 outline-none\"\r\n (keydown.escape)=\"run.skip()\"\r\n>\r\n <div class=\"flex items-center justify-between gap-2\">\r\n <span class=\"font-mono text-eyebrow text-help uppercase tabular-nums\">\r\n {{ run.index() + 1 }} {{ labels().stepOf }} {{ run.steps.length }}\r\n </span>\r\n <button\r\n type=\"button\"\r\n class=\"-me-1.5 inline-flex size-7 cursor-pointer appearance-none items-center justify-center rounded-md border-0 bg-transparent text-fg-subtle transition-colors duration-fast ease-emphasis hover:bg-state-hover hover:text-fg focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring\"\r\n [attr.aria-label]=\"labels().skip\"\r\n (click)=\"run.skip()\"\r\n >\r\n <span mfIcon [size]=\"16\">close</span>\r\n </button>\r\n </div>\r\n\r\n <h2 [id]=\"titleId\" class=\"mt-1.5 font-display text-base font-semibold text-fg\">\r\n {{ run.step().title }}\r\n </h2>\r\n <p [id]=\"contentId\" class=\"mt-1 text-sm text-fg-muted\">{{ run.step().content }}</p>\r\n\r\n <div class=\"mt-4 flex items-center gap-2\">\r\n <!-- \u0130lerleme: ad\u0131m ba\u015F\u0131na bir \u00E7izgi; salt g\u00F6rsel, say\u0131 zaten yukar\u0131da. -->\r\n <div class=\"flex flex-1 items-center gap-1\" aria-hidden=\"true\">\r\n @for (step of run.steps; track $index) {\r\n <span\r\n class=\"h-1 flex-1 rounded-full transition-colors duration-base ease-emphasis\"\r\n [class]=\"$index <= run.index() ? 'bg-help' : 'bg-surface-alt'\"\r\n ></span>\r\n }\r\n </div>\r\n @if (!run.isFirst()) {\r\n <button\r\n mfButton\r\n appearance=\"text\"\r\n tone=\"neutral\"\r\n size=\"sm\"\r\n type=\"button\"\r\n (click)=\"run.back()\"\r\n >\r\n {{ labels().back }}\r\n </button>\r\n }\r\n <button mfButton tone=\"help\" size=\"sm\" type=\"button\" (click)=\"run.next()\">\r\n {{ run.isLast() ? labels().done : labels().next }}\r\n </button>\r\n </div>\r\n</div>\r\n" }]
72
+ }], ctorParameters: () => [] });
73
+
74
+ /** Dialog arka planıyla aynı karartma (bkz. motion.css `.mf-dialog-backdrop`), biraz daha koyu. */
75
+ const SCRIM = 'color-mix(in srgb, var(--color-neutral-975) 55%, transparent)';
76
+ /**
77
+ * Tam ekran katman: tıklamaları yutar (tur modal) ve hedefin çevresi dışını karartır. Delik,
78
+ * hedef kutusuna oturan bir öğenin çok büyük `box-shadow`'u — maske/SVG yolu gerekmez, konumu
79
+ * `transition` ile adımlar arasında kayar. Hedefsiz adımda düz karartma.
80
+ */
81
+ class TourSpotlight {
82
+ run = inject(TourRun);
83
+ scrim = SCRIM;
84
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TourSpotlight, deps: [], target: i0.ɵɵFactoryTarget.Component });
85
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: TourSpotlight, isStandalone: true, selector: "mf-tour-spotlight", host: { classAttribute: "fixed inset-0 block" }, ngImport: i0, template: `
86
+ @if (run.rect(); as rect) {
87
+ <div class="absolute inset-0" aria-hidden="true"></div>
88
+ <div
89
+ aria-hidden="true"
90
+ class="pointer-events-none fixed rounded-lg outline outline-2 outline-offset-0 outline-help transition-[top,left,width,height] duration-base ease-emphasis"
91
+ [style.top.px]="rect.top"
92
+ [style.left.px]="rect.left"
93
+ [style.width.px]="rect.width"
94
+ [style.height.px]="rect.height"
95
+ [style.box-shadow]="'0 0 0 200vmax ' + scrim"
96
+ ></div>
97
+ } @else {
98
+ <div class="absolute inset-0" aria-hidden="true" [style.background-color]="scrim"></div>
99
+ }
100
+ `, isInline: true });
101
+ }
102
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TourSpotlight, decorators: [{
103
+ type: Component,
104
+ args: [{
105
+ selector: 'mf-tour-spotlight',
106
+ host: { class: 'fixed inset-0 block' },
107
+ template: `
108
+ @if (run.rect(); as rect) {
109
+ <div class="absolute inset-0" aria-hidden="true"></div>
110
+ <div
111
+ aria-hidden="true"
112
+ class="pointer-events-none fixed rounded-lg outline outline-2 outline-offset-0 outline-help transition-[top,left,width,height] duration-base ease-emphasis"
113
+ [style.top.px]="rect.top"
114
+ [style.left.px]="rect.left"
115
+ [style.width.px]="rect.width"
116
+ [style.height.px]="rect.height"
117
+ [style.box-shadow]="'0 0 0 200vmax ' + scrim"
118
+ ></div>
119
+ } @else {
120
+ <div class="absolute inset-0" aria-hidden="true" [style.background-color]="scrim"></div>
121
+ }
122
+ `,
123
+ }]
124
+ }] });
125
+
126
+ const GAP = 12;
127
+ const DEFAULT_PADDING = 6;
128
+ /** Tercih edilen taraf önce, sığmazsa karşısı, sonra diğer eksen. */
129
+ const POSITIONS = {
130
+ bottom: [
131
+ { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: GAP },
132
+ { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -GAP },
133
+ ],
134
+ top: [
135
+ { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', offsetY: -GAP },
136
+ { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', offsetY: GAP },
137
+ ],
138
+ end: [
139
+ { originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: GAP },
140
+ { originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -GAP },
141
+ ],
142
+ start: [
143
+ { originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', offsetX: -GAP },
144
+ { originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', offsetX: GAP },
145
+ ],
146
+ };
147
+ /**
148
+ * `const result = await tour.start([{ target: '#new-campaign', title: '…', content: '…' }, …]);`
149
+ *
150
+ * Ürün turu / coachmark — `help` tonu tam bunun için. İki overlay: tam ekran spot ışığı (karartır,
151
+ * tıklamaları yutar) ve hedefe bağlı adım kartı. Her adımda hedef görünür alana kaydırılır
152
+ * (azaltılmış harekette anında), kaydırma/yeniden boyutlandırmada delik ve kart birlikte izler.
153
+ * Bulunamayan hedef ortalanmış karta düşer (tur kırılmaz). Aynı anda tek tur; bitince odak
154
+ * turdan önceki öğeye döner. Sonuç: `'completed'` ya da `'skipped'` (Esc, ×).
155
+ */
156
+ class TourService {
157
+ injector = inject(Injector);
158
+ document = inject(DOCUMENT);
159
+ active = null;
160
+ get isActive() {
161
+ return this.active !== null;
162
+ }
163
+ start(steps, options = {}) {
164
+ if (this.active)
165
+ return this.active;
166
+ if (steps.length === 0)
167
+ return Promise.resolve('completed');
168
+ this.active = new Promise((resolve) => {
169
+ const doc = this.document;
170
+ const view = doc.defaultView;
171
+ const padding = options.padding ?? DEFAULT_PADDING;
172
+ const previousFocus = doc.activeElement;
173
+ const direction = isRtl(doc.documentElement) ? 'rtl' : 'ltr';
174
+ let target = null;
175
+ let frame = 0;
176
+ const run = new TourRun(steps, (index) => show(index), (result) => finish(result));
177
+ const injector = Injector.create({
178
+ providers: [{ provide: TourRun, useValue: run }],
179
+ parent: this.injector,
180
+ });
181
+ const spotlight = createOverlayRef(this.injector, {
182
+ positionStrategy: createGlobalPositionStrategy(this.injector),
183
+ width: '100vw',
184
+ height: '100vh',
185
+ direction,
186
+ });
187
+ spotlight.attach(new ComponentPortal(TourSpotlight, null, injector));
188
+ const card = createOverlayRef(this.injector, { direction });
189
+ const measure = () => {
190
+ frame = 0;
191
+ if (!target) {
192
+ run.rect.set(null);
193
+ return;
194
+ }
195
+ const box = target.getBoundingClientRect();
196
+ run.rect.set({
197
+ top: box.top - padding,
198
+ left: box.left - padding,
199
+ width: box.width + padding * 2,
200
+ height: box.height + padding * 2,
201
+ });
202
+ card.updatePosition();
203
+ };
204
+ const schedule = () => {
205
+ if (!frame)
206
+ frame = view?.requestAnimationFrame(measure) ?? 0;
207
+ };
208
+ const place = (step) => {
209
+ const strategy = target
210
+ ? createFlexibleConnectedPositionStrategy(this.injector, target)
211
+ .withPositions(POSITIONS[step.placement ?? 'bottom'])
212
+ .withViewportMargin(12)
213
+ .withPush(true)
214
+ : createGlobalPositionStrategy(this.injector).centerHorizontally().centerVertically();
215
+ card.updatePositionStrategy(strategy);
216
+ card.updateScrollStrategy(createRepositionScrollStrategy(this.injector));
217
+ };
218
+ const show = (index) => {
219
+ const step = steps[index];
220
+ target = resolveTarget(step.target, doc);
221
+ run.index.set(index);
222
+ options.stepChange?.(index, step);
223
+ if (target) {
224
+ const reduced = view?.matchMedia?.('(prefers-reduced-motion: reduce)').matches ?? true;
225
+ target.scrollIntoView?.({
226
+ block: 'center',
227
+ inline: 'nearest',
228
+ behavior: reduced ? 'auto' : 'smooth',
229
+ });
230
+ }
231
+ place(step);
232
+ if (!card.hasAttached())
233
+ card.attach(new ComponentPortal(TourCard, null, injector));
234
+ measure();
235
+ };
236
+ const finish = (result) => {
237
+ view?.removeEventListener('scroll', schedule, true);
238
+ view?.removeEventListener('resize', schedule);
239
+ if (frame)
240
+ view?.cancelAnimationFrame(frame);
241
+ card.dispose();
242
+ spotlight.dispose();
243
+ this.active = null;
244
+ previousFocus?.focus?.();
245
+ resolve(result);
246
+ };
247
+ view?.addEventListener('scroll', schedule, true);
248
+ view?.addEventListener('resize', schedule);
249
+ show(0);
250
+ });
251
+ return this.active;
252
+ }
253
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TourService, deps: [], target: i0.ɵɵFactoryTarget.Service });
254
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.6", ngImport: i0, type: TourService });
255
+ }
256
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: TourService, decorators: [{
257
+ type: Service
258
+ }] });
259
+ function resolveTarget(target, doc) {
260
+ if (!target)
261
+ return null;
262
+ if (typeof target === 'string')
263
+ return doc.querySelector(target);
264
+ return target instanceof ElementRef ? target.nativeElement : target;
265
+ }
266
+
267
+ /**
268
+ * Generated bundle index. Do not edit.
269
+ */
270
+
271
+ export { TourRun, TourService };
272
+ //# sourceMappingURL=mesgflow-ui-kit-tour.mjs.map