dockview-core 7.0.4 → 8.1.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 (380) hide show
  1. package/LICENCE.md +21 -0
  2. package/README.md +17 -86
  3. package/dist/cjs/api/component.api.d.ts +100 -9
  4. package/dist/cjs/api/dockviewGroupPanelApi.d.ts +45 -1
  5. package/dist/cjs/api/dockviewPanelApi.d.ts +21 -0
  6. package/dist/cjs/dismissableLayer.d.ts +57 -0
  7. package/dist/cjs/dnd/backend.d.ts +2 -2
  8. package/dist/cjs/dnd/dataTransfer.d.ts +1 -0
  9. package/dist/cjs/dnd/dropTargetAnchorContainer.d.ts +12 -0
  10. package/dist/cjs/dnd/droptarget.d.ts +94 -0
  11. package/dist/cjs/dnd/ghost.d.ts +1 -0
  12. package/dist/cjs/dnd/pointer/longPress.d.ts +2 -2
  13. package/dist/cjs/dnd/pointer/pointerDragController.d.ts +5 -2
  14. package/dist/cjs/dnd/pointer/pointerDragSource.d.ts +1 -1
  15. package/dist/cjs/dnd/pointer/pointerDropTarget.d.ts +30 -1
  16. package/dist/cjs/dnd/pointer/pointerGhost.d.ts +1 -1
  17. package/dist/cjs/dockview/accessibilityMessages.d.ts +6 -0
  18. package/dist/cjs/dockview/advancedDnDService.d.ts +31 -0
  19. package/dist/cjs/dockview/components/panel/content.d.ts +1 -1
  20. package/dist/cjs/dockview/components/tab/defaultTab.d.ts +2 -0
  21. package/dist/cjs/dockview/components/tab/tab.d.ts +2 -0
  22. package/dist/cjs/dockview/components/titlebar/floatingTitleBar.d.ts +2 -2
  23. package/dist/cjs/dockview/components/titlebar/groupDragSource.d.ts +1 -1
  24. package/dist/cjs/dockview/components/titlebar/tabGroupChip.d.ts +1 -1
  25. package/dist/cjs/dockview/components/titlebar/tabGroupIndicator.d.ts +73 -2
  26. package/dist/cjs/dockview/components/titlebar/tabGroups.d.ts +1 -1
  27. package/dist/cjs/dockview/components/titlebar/tabReorderController.d.ts +295 -0
  28. package/dist/cjs/dockview/components/titlebar/tabs.d.ts +120 -50
  29. package/dist/cjs/dockview/components/titlebar/tabsContainer.d.ts +48 -0
  30. package/dist/cjs/dockview/dndCapabilities.d.ts +1 -1
  31. package/dist/cjs/dockview/dockviewComponent.d.ts +307 -19
  32. package/dist/cjs/dockview/dockviewGroupPanel.d.ts +5 -0
  33. package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +76 -2
  34. package/dist/cjs/dockview/dockviewPanel.d.ts +12 -0
  35. package/dist/cjs/dockview/dockviewShell.d.ts +48 -24
  36. package/dist/cjs/dockview/edgeGroupService.d.ts +20 -0
  37. package/dist/cjs/dockview/events.d.ts +6 -0
  38. package/dist/cjs/dockview/liveRegionService.d.ts +18 -5
  39. package/dist/cjs/dockview/moduleContracts.d.ts +485 -14
  40. package/dist/cjs/dockview/modules.d.ts +101 -22
  41. package/dist/cjs/dockview/options.d.ts +336 -30
  42. package/dist/cjs/dockview/optionsModules.d.ts +73 -0
  43. package/dist/cjs/dockview/popoutWindowService.d.ts +15 -10
  44. package/dist/cjs/dockview/rootDropTargetService.d.ts +11 -0
  45. package/dist/cjs/dockview/tabGroup.d.ts +3 -0
  46. package/dist/cjs/dockview/tabGroupAccent.d.ts +1 -1
  47. package/dist/cjs/dockview/tabGroupChipsService.d.ts +10 -0
  48. package/dist/cjs/dockview/theme.d.ts +2 -2
  49. package/dist/cjs/dockview/types.d.ts +3 -0
  50. package/dist/cjs/dom.d.ts +9 -1
  51. package/dist/cjs/events.d.ts +1 -1
  52. package/dist/cjs/gridview/baseComponentGridview.d.ts +2 -2
  53. package/dist/cjs/gridview/branchNode.d.ts +16 -0
  54. package/dist/cjs/gridview/gridview.d.ts +2 -0
  55. package/dist/cjs/index.d.ts +35 -29
  56. package/dist/cjs/lifecycle.d.ts +1 -0
  57. package/dist/cjs/overlay/overlay.d.ts +4 -2
  58. package/dist/cjs/overlay/overlayRenderContainer.d.ts +8 -0
  59. package/dist/cjs/paneview/paneview.d.ts +2 -1
  60. package/dist/cjs/paneview/paneviewComponent.d.ts +3 -0
  61. package/dist/cjs/paneview/paneviewPanel.d.ts +5 -0
  62. package/dist/cjs/scrollbar.d.ts +10 -0
  63. package/dist/cjs/splitview/viewItem.d.ts +10 -0
  64. package/dist/cjs/svg.d.ts +1 -0
  65. package/dist/cjs/types.d.ts +8 -0
  66. package/dist/dockview-core.js +18513 -19679
  67. package/dist/dockview-core.min.js +4138 -6
  68. package/dist/dockview-core.min.noStyle.js +6 -7
  69. package/dist/dockview-core.noStyle.js +18512 -19656
  70. package/dist/package/main.cjs.js +18123 -19267
  71. package/dist/package/main.cjs.min.js +6 -6
  72. package/dist/package/main.esm.min.mjs +6 -6
  73. package/dist/package/main.esm.mjs +18081 -19260
  74. package/package.json +81 -77
  75. package/dist/cjs/api/component.api.js +0 -1242
  76. package/dist/cjs/api/dockviewGroupPanelApi.js +0 -200
  77. package/dist/cjs/api/dockviewPanelApi.js +0 -172
  78. package/dist/cjs/api/entryPoints.js +0 -27
  79. package/dist/cjs/api/gridviewPanelApi.js +0 -45
  80. package/dist/cjs/api/panelApi.js +0 -133
  81. package/dist/cjs/api/paneviewPanelApi.js +0 -57
  82. package/dist/cjs/api/splitviewPanelApi.js +0 -47
  83. package/dist/cjs/array.js +0 -66
  84. package/dist/cjs/constants.js +0 -11
  85. package/dist/cjs/dnd/backend.js +0 -171
  86. package/dist/cjs/dnd/dataTransfer.js +0 -100
  87. package/dist/cjs/dnd/dnd.js +0 -74
  88. package/dist/cjs/dnd/dropOverlay.js +0 -197
  89. package/dist/cjs/dnd/dropTargetAnchorContainer.js +0 -104
  90. package/dist/cjs/dnd/droptarget.js +0 -362
  91. package/dist/cjs/dnd/ghost.js +0 -17
  92. package/dist/cjs/dnd/pointer/index.js +0 -13
  93. package/dist/cjs/dnd/pointer/longPress.js +0 -151
  94. package/dist/cjs/dnd/pointer/pointerDragController.js +0 -243
  95. package/dist/cjs/dnd/pointer/pointerDragSource.js +0 -197
  96. package/dist/cjs/dnd/pointer/pointerDropTarget.js +0 -198
  97. package/dist/cjs/dnd/pointer/pointerGhost.js +0 -44
  98. package/dist/cjs/dnd/pointer/types.js +0 -2
  99. package/dist/cjs/dockview/accessibilityMessages.js +0 -51
  100. package/dist/cjs/dockview/allModules.js +0 -25
  101. package/dist/cjs/dockview/components/panel/content.js +0 -213
  102. package/dist/cjs/dockview/components/popupService.js +0 -132
  103. package/dist/cjs/dockview/components/tab/defaultTab.js +0 -70
  104. package/dist/cjs/dockview/components/tab/tab.js +0 -281
  105. package/dist/cjs/dockview/components/titlebar/floatingTitleBar.js +0 -95
  106. package/dist/cjs/dockview/components/titlebar/groupDragSource.js +0 -218
  107. package/dist/cjs/dockview/components/titlebar/tabGroupChip.js +0 -104
  108. package/dist/cjs/dockview/components/titlebar/tabGroupIndicator.js +0 -477
  109. package/dist/cjs/dockview/components/titlebar/tabGroups.js +0 -854
  110. package/dist/cjs/dockview/components/titlebar/tabOverflowControl.js +0 -19
  111. package/dist/cjs/dockview/components/titlebar/tabs.js +0 -2016
  112. package/dist/cjs/dockview/components/titlebar/tabsContainer.js +0 -458
  113. package/dist/cjs/dockview/components/titlebar/voidContainer.js +0 -120
  114. package/dist/cjs/dockview/components/watermark/watermark.js +0 -40
  115. package/dist/cjs/dockview/deserializer.js +0 -39
  116. package/dist/cjs/dockview/dndCapabilities.js +0 -39
  117. package/dist/cjs/dockview/dockviewComponent.js +0 -3896
  118. package/dist/cjs/dockview/dockviewFloatingGroupPanel.js +0 -70
  119. package/dist/cjs/dockview/dockviewGroupPanel.js +0 -204
  120. package/dist/cjs/dockview/dockviewGroupPanelModel.js +0 -1514
  121. package/dist/cjs/dockview/dockviewPanel.js +0 -265
  122. package/dist/cjs/dockview/dockviewPanelModel.js +0 -105
  123. package/dist/cjs/dockview/dockviewShell.js +0 -744
  124. package/dist/cjs/dockview/edgeGroupService.js +0 -128
  125. package/dist/cjs/dockview/events.js +0 -67
  126. package/dist/cjs/dockview/floatingGroupService.js +0 -231
  127. package/dist/cjs/dockview/framework.js +0 -2
  128. package/dist/cjs/dockview/headerActionsService.js +0 -149
  129. package/dist/cjs/dockview/liveRegionService.js +0 -185
  130. package/dist/cjs/dockview/moduleContracts.js +0 -2
  131. package/dist/cjs/dockview/modules.js +0 -304
  132. package/dist/cjs/dockview/options.js +0 -103
  133. package/dist/cjs/dockview/popoutWindowService.js +0 -261
  134. package/dist/cjs/dockview/rootDropTargetService.js +0 -87
  135. package/dist/cjs/dockview/strictEventsSequencing.js +0 -63
  136. package/dist/cjs/dockview/tabGroup.js +0 -219
  137. package/dist/cjs/dockview/tabGroupAccent.js +0 -126
  138. package/dist/cjs/dockview/theme.js +0 -139
  139. package/dist/cjs/dockview/types.js +0 -2
  140. package/dist/cjs/dockview/validate.js +0 -76
  141. package/dist/cjs/dockview/watermarkService.js +0 -61
  142. package/dist/cjs/dom.js +0 -543
  143. package/dist/cjs/events.js +0 -296
  144. package/dist/cjs/framwork.js +0 -2
  145. package/dist/cjs/gridview/baseComponentGridview.js +0 -330
  146. package/dist/cjs/gridview/basePanelView.js +0 -162
  147. package/dist/cjs/gridview/branchNode.js +0 -372
  148. package/dist/cjs/gridview/gridview.js +0 -776
  149. package/dist/cjs/gridview/gridviewComponent.js +0 -363
  150. package/dist/cjs/gridview/gridviewPanel.js +0 -249
  151. package/dist/cjs/gridview/leafNode.js +0 -169
  152. package/dist/cjs/gridview/options.js +0 -17
  153. package/dist/cjs/gridview/types.js +0 -2
  154. package/dist/cjs/index.js +0 -105
  155. package/dist/cjs/lifecycle.js +0 -80
  156. package/dist/cjs/math.js +0 -38
  157. package/dist/cjs/overlay/overlay.js +0 -602
  158. package/dist/cjs/overlay/overlayRenderContainer.js +0 -309
  159. package/dist/cjs/panel/types.js +0 -2
  160. package/dist/cjs/paneview/defaultPaneviewHeader.js +0 -92
  161. package/dist/cjs/paneview/draggablePaneviewPanel.js +0 -141
  162. package/dist/cjs/paneview/options.js +0 -44
  163. package/dist/cjs/paneview/paneview.js +0 -203
  164. package/dist/cjs/paneview/paneviewComponent.js +0 -430
  165. package/dist/cjs/paneview/paneviewPanel.js +0 -275
  166. package/dist/cjs/popoutWindow.js +0 -244
  167. package/dist/cjs/resizable.js +0 -97
  168. package/dist/cjs/scrollbar.js +0 -169
  169. package/dist/cjs/splitview/options.js +0 -19
  170. package/dist/cjs/splitview/splitview.js +0 -999
  171. package/dist/cjs/splitview/splitviewComponent.js +0 -401
  172. package/dist/cjs/splitview/splitviewPanel.js +0 -179
  173. package/dist/cjs/splitview/viewItem.js +0 -119
  174. package/dist/cjs/svg.js +0 -43
  175. package/dist/cjs/types.js +0 -2
  176. package/dist/dockview-core.min.js.map +0 -1
  177. package/dist/dockview-core.min.noStyle.js.map +0 -1
  178. package/dist/esm/api/component.api.d.ts +0 -640
  179. package/dist/esm/api/component.api.js +0 -887
  180. package/dist/esm/api/dockviewGroupPanelApi.d.ts +0 -109
  181. package/dist/esm/api/dockviewGroupPanelApi.js +0 -155
  182. package/dist/esm/api/dockviewPanelApi.d.ts +0 -84
  183. package/dist/esm/api/dockviewPanelApi.js +0 -124
  184. package/dist/esm/api/entryPoints.d.ts +0 -9
  185. package/dist/esm/api/entryPoints.js +0 -21
  186. package/dist/esm/api/gridviewPanelApi.d.ts +0 -37
  187. package/dist/esm/api/gridviewPanelApi.js +0 -23
  188. package/dist/esm/api/panelApi.d.ts +0 -100
  189. package/dist/esm/api/panelApi.js +0 -87
  190. package/dist/esm/api/paneviewPanelApi.d.ts +0 -26
  191. package/dist/esm/api/paneviewPanelApi.js +0 -27
  192. package/dist/esm/api/splitviewPanelApi.d.ts +0 -32
  193. package/dist/esm/api/splitviewPanelApi.js +0 -25
  194. package/dist/esm/array.d.ts +0 -13
  195. package/dist/esm/array.js +0 -57
  196. package/dist/esm/constants.d.ts +0 -8
  197. package/dist/esm/constants.js +0 -8
  198. package/dist/esm/dnd/backend.d.ts +0 -70
  199. package/dist/esm/dnd/backend.js +0 -148
  200. package/dist/esm/dnd/dataTransfer.d.ts +0 -31
  201. package/dist/esm/dnd/dataTransfer.js +0 -67
  202. package/dist/esm/dnd/dnd.d.ts +0 -32
  203. package/dist/esm/dnd/dnd.js +0 -51
  204. package/dist/esm/dnd/dropOverlay.d.ts +0 -20
  205. package/dist/esm/dnd/dropOverlay.js +0 -192
  206. package/dist/esm/dnd/dropTargetAnchorContainer.d.ts +0 -16
  207. package/dist/esm/dnd/dropTargetAnchorContainer.js +0 -73
  208. package/dist/esm/dnd/droptarget.d.ts +0 -116
  209. package/dist/esm/dnd/droptarget.js +0 -316
  210. package/dist/esm/dnd/ghost.d.ts +0 -4
  211. package/dist/esm/dnd/ghost.js +0 -14
  212. package/dist/esm/dnd/pointer/index.d.ts +0 -11
  213. package/dist/esm/dnd/pointer/index.js +0 -5
  214. package/dist/esm/dnd/pointer/longPress.d.ts +0 -32
  215. package/dist/esm/dnd/pointer/longPress.js +0 -127
  216. package/dist/esm/dnd/pointer/pointerDragController.d.ts +0 -60
  217. package/dist/esm/dnd/pointer/pointerDragController.js +0 -193
  218. package/dist/esm/dnd/pointer/pointerDragSource.d.ts +0 -61
  219. package/dist/esm/dnd/pointer/pointerDragSource.js +0 -173
  220. package/dist/esm/dnd/pointer/pointerDropTarget.d.ts +0 -39
  221. package/dist/esm/dnd/pointer/pointerDropTarget.js +0 -168
  222. package/dist/esm/dnd/pointer/pointerGhost.d.ts +0 -30
  223. package/dist/esm/dnd/pointer/pointerGhost.js +0 -39
  224. package/dist/esm/dnd/pointer/types.d.ts +0 -16
  225. package/dist/esm/dnd/pointer/types.js +0 -1
  226. package/dist/esm/dockview/accessibilityMessages.d.ts +0 -32
  227. package/dist/esm/dockview/accessibilityMessages.js +0 -30
  228. package/dist/esm/dockview/allModules.d.ts +0 -8
  229. package/dist/esm/dockview/allModules.js +0 -22
  230. package/dist/esm/dockview/components/panel/content.d.ts +0 -54
  231. package/dist/esm/dockview/components/panel/content.js +0 -185
  232. package/dist/esm/dockview/components/popupService.d.ts +0 -21
  233. package/dist/esm/dockview/components/popupService.js +0 -108
  234. package/dist/esm/dockview/components/tab/defaultTab.d.ts +0 -12
  235. package/dist/esm/dockview/components/tab/defaultTab.js +0 -43
  236. package/dist/esm/dockview/components/tab/tab.d.ts +0 -44
  237. package/dist/esm/dockview/components/tab/tab.js +0 -242
  238. package/dist/esm/dockview/components/titlebar/floatingTitleBar.d.ts +0 -34
  239. package/dist/esm/dockview/components/titlebar/floatingTitleBar.js +0 -65
  240. package/dist/esm/dockview/components/titlebar/groupDragSource.d.ts +0 -51
  241. package/dist/esm/dockview/components/titlebar/groupDragSource.js +0 -178
  242. package/dist/esm/dockview/components/titlebar/tabGroupChip.d.ts +0 -37
  243. package/dist/esm/dockview/components/titlebar/tabGroupChip.js +0 -77
  244. package/dist/esm/dockview/components/titlebar/tabGroupIndicator.d.ts +0 -72
  245. package/dist/esm/dockview/components/titlebar/tabGroupIndicator.js +0 -360
  246. package/dist/esm/dockview/components/titlebar/tabGroups.d.ts +0 -107
  247. package/dist/esm/dockview/components/titlebar/tabGroups.js +0 -621
  248. package/dist/esm/dockview/components/titlebar/tabOverflowControl.d.ts +0 -8
  249. package/dist/esm/dockview/components/titlebar/tabOverflowControl.js +0 -16
  250. package/dist/esm/dockview/components/titlebar/tabs.d.ts +0 -167
  251. package/dist/esm/dockview/components/titlebar/tabs.js +0 -1653
  252. package/dist/esm/dockview/components/titlebar/tabsContainer.d.ts +0 -104
  253. package/dist/esm/dockview/components/titlebar/tabsContainer.js +0 -359
  254. package/dist/esm/dockview/components/titlebar/voidContainer.d.ts +0 -21
  255. package/dist/esm/dockview/components/titlebar/voidContainer.js +0 -92
  256. package/dist/esm/dockview/components/watermark/watermark.d.ts +0 -8
  257. package/dist/esm/dockview/components/watermark/watermark.js +0 -14
  258. package/dist/esm/dockview/deserializer.d.ts +0 -12
  259. package/dist/esm/dockview/deserializer.js +0 -34
  260. package/dist/esm/dockview/dndCapabilities.d.ts +0 -19
  261. package/dist/esm/dockview/dndCapabilities.js +0 -36
  262. package/dist/esm/dockview/dockviewComponent.d.ts +0 -626
  263. package/dist/esm/dockview/dockviewComponent.js +0 -3214
  264. package/dist/esm/dockview/dockviewFloatingGroupPanel.d.ts +0 -45
  265. package/dist/esm/dockview/dockviewFloatingGroupPanel.js +0 -44
  266. package/dist/esm/dockview/dockviewGroupPanel.d.ts +0 -35
  267. package/dist/esm/dockview/dockviewGroupPanel.js +0 -142
  268. package/dist/esm/dockview/dockviewGroupPanelModel.d.ts +0 -358
  269. package/dist/esm/dockview/dockviewGroupPanelModel.js +0 -1180
  270. package/dist/esm/dockview/dockviewPanel.d.ts +0 -69
  271. package/dist/esm/dockview/dockviewPanel.js +0 -178
  272. package/dist/esm/dockview/dockviewPanelModel.d.ts +0 -37
  273. package/dist/esm/dockview/dockviewPanelModel.js +0 -81
  274. package/dist/esm/dockview/dockviewShell.d.ts +0 -150
  275. package/dist/esm/dockview/dockviewShell.js +0 -678
  276. package/dist/esm/dockview/edgeGroupService.d.ts +0 -38
  277. package/dist/esm/dockview/edgeGroupService.js +0 -63
  278. package/dist/esm/dockview/events.d.ts +0 -38
  279. package/dist/esm/dockview/events.js +0 -34
  280. package/dist/esm/dockview/floatingGroupService.d.ts +0 -37
  281. package/dist/esm/dockview/floatingGroupService.js +0 -150
  282. package/dist/esm/dockview/framework.d.ts +0 -65
  283. package/dist/esm/dockview/framework.js +0 -1
  284. package/dist/esm/dockview/headerActionsService.d.ts +0 -32
  285. package/dist/esm/dockview/headerActionsService.js +0 -86
  286. package/dist/esm/dockview/liveRegionService.d.ts +0 -53
  287. package/dist/esm/dockview/liveRegionService.js +0 -159
  288. package/dist/esm/dockview/moduleContracts.d.ts +0 -119
  289. package/dist/esm/dockview/moduleContracts.js +0 -1
  290. package/dist/esm/dockview/modules.d.ts +0 -110
  291. package/dist/esm/dockview/modules.js +0 -170
  292. package/dist/esm/dockview/options.d.ts +0 -474
  293. package/dist/esm/dockview/options.js +0 -77
  294. package/dist/esm/dockview/popoutWindowService.d.ts +0 -95
  295. package/dist/esm/dockview/popoutWindowService.js +0 -175
  296. package/dist/esm/dockview/rootDropTargetService.d.ts +0 -35
  297. package/dist/esm/dockview/rootDropTargetService.js +0 -82
  298. package/dist/esm/dockview/strictEventsSequencing.d.ts +0 -7
  299. package/dist/esm/dockview/strictEventsSequencing.js +0 -41
  300. package/dist/esm/dockview/tabGroup.d.ts +0 -99
  301. package/dist/esm/dockview/tabGroup.js +0 -144
  302. package/dist/esm/dockview/tabGroupAccent.d.ts +0 -65
  303. package/dist/esm/dockview/tabGroupAccent.js +0 -114
  304. package/dist/esm/dockview/theme.d.ts +0 -86
  305. package/dist/esm/dockview/theme.js +0 -136
  306. package/dist/esm/dockview/types.d.ts +0 -53
  307. package/dist/esm/dockview/types.js +0 -1
  308. package/dist/esm/dockview/validate.d.ts +0 -0
  309. package/dist/esm/dockview/validate.js +0 -76
  310. package/dist/esm/dockview/watermarkService.d.ts +0 -30
  311. package/dist/esm/dockview/watermarkService.js +0 -56
  312. package/dist/esm/dom.d.ts +0 -60
  313. package/dist/esm/dom.js +0 -375
  314. package/dist/esm/events.d.ts +0 -79
  315. package/dist/esm/events.js +0 -219
  316. package/dist/esm/framwork.d.ts +0 -4
  317. package/dist/esm/framwork.js +0 -1
  318. package/dist/esm/gridview/baseComponentGridview.d.ts +0 -111
  319. package/dist/esm/gridview/baseComponentGridview.js +0 -237
  320. package/dist/esm/gridview/basePanelView.d.ts +0 -40
  321. package/dist/esm/gridview/basePanelView.js +0 -91
  322. package/dist/esm/gridview/branchNode.d.ts +0 -57
  323. package/dist/esm/gridview/branchNode.js +0 -257
  324. package/dist/esm/gridview/gridview.d.ts +0 -158
  325. package/dist/esm/gridview/gridview.js +0 -681
  326. package/dist/esm/gridview/gridviewComponent.d.ts +0 -88
  327. package/dist/esm/gridview/gridviewComponent.js +0 -265
  328. package/dist/esm/gridview/gridviewPanel.d.ts +0 -77
  329. package/dist/esm/gridview/gridviewPanel.js +0 -182
  330. package/dist/esm/gridview/leafNode.d.ts +0 -34
  331. package/dist/esm/gridview/leafNode.js +0 -102
  332. package/dist/esm/gridview/options.d.ts +0 -15
  333. package/dist/esm/gridview/options.js +0 -14
  334. package/dist/esm/gridview/types.d.ts +0 -3
  335. package/dist/esm/gridview/types.js +0 -1
  336. package/dist/esm/index.d.ts +0 -58
  337. package/dist/esm/index.js +0 -44
  338. package/dist/esm/lifecycle.d.ts +0 -25
  339. package/dist/esm/lifecycle.js +0 -56
  340. package/dist/esm/math.d.ts +0 -5
  341. package/dist/esm/math.js +0 -32
  342. package/dist/esm/overlay/overlay.d.ts +0 -91
  343. package/dist/esm/overlay/overlay.js +0 -520
  344. package/dist/esm/overlay/overlayRenderContainer.d.ts +0 -24
  345. package/dist/esm/overlay/overlayRenderContainer.js +0 -249
  346. package/dist/esm/panel/types.d.ts +0 -33
  347. package/dist/esm/panel/types.js +0 -1
  348. package/dist/esm/paneview/defaultPaneviewHeader.d.ts +0 -21
  349. package/dist/esm/paneview/defaultPaneviewHeader.js +0 -65
  350. package/dist/esm/paneview/draggablePaneviewPanel.d.ts +0 -38
  351. package/dist/esm/paneview/draggablePaneviewPanel.js +0 -107
  352. package/dist/esm/paneview/options.d.ts +0 -30
  353. package/dist/esm/paneview/options.js +0 -22
  354. package/dist/esm/paneview/paneview.d.ts +0 -41
  355. package/dist/esm/paneview/paneview.js +0 -148
  356. package/dist/esm/paneview/paneviewComponent.d.ts +0 -133
  357. package/dist/esm/paneview/paneviewComponent.js +0 -306
  358. package/dist/esm/paneview/paneviewPanel.d.ts +0 -98
  359. package/dist/esm/paneview/paneviewPanel.js +0 -192
  360. package/dist/esm/popoutWindow.d.ts +0 -38
  361. package/dist/esm/popoutWindow.js +0 -170
  362. package/dist/esm/resizable.d.ts +0 -12
  363. package/dist/esm/resizable.js +0 -66
  364. package/dist/esm/scrollbar.d.ts +0 -15
  365. package/dist/esm/scrollbar.js +0 -139
  366. package/dist/esm/splitview/options.d.ts +0 -21
  367. package/dist/esm/splitview/options.js +0 -16
  368. package/dist/esm/splitview/splitview.d.ts +0 -145
  369. package/dist/esm/splitview/splitview.js +0 -770
  370. package/dist/esm/splitview/splitviewComponent.d.ts +0 -101
  371. package/dist/esm/splitview/splitviewComponent.js +0 -267
  372. package/dist/esm/splitview/splitviewPanel.d.ts +0 -45
  373. package/dist/esm/splitview/splitviewPanel.js +0 -108
  374. package/dist/esm/splitview/viewItem.d.ts +0 -25
  375. package/dist/esm/splitview/viewItem.js +0 -74
  376. package/dist/esm/svg.d.ts +0 -3
  377. package/dist/esm/svg.js +0 -31
  378. package/dist/esm/types.d.ts +0 -31
  379. package/dist/esm/types.js +0 -1
  380. package/dist/styles/dockview.css +0 -3436
@@ -1,1653 +0,0 @@
1
- import { getPanelData } from '../../../dnd/dataTransfer';
2
- import { addClasses, isChildEntirelyVisibleWithinParent, OverflowObserver, removeClasses, toggleClass, } from '../../../dom';
3
- import { addDisposableListener, Emitter } from '../../../events';
4
- import { CompositeDisposable, Disposable, MutableDisposable, } from '../../../lifecycle';
5
- import { Scrollbar } from '../../../scrollbar';
6
- import { PointerDragController } from '../../../dnd/pointer/pointerDragController';
7
- import { DockviewWillShowOverlayLocationEvent } from '../../events';
8
- import { Tab } from '../tab/tab';
9
- import { TabGroupManager } from './tabGroups';
10
- export class Tabs extends CompositeDisposable {
11
- get showTabsOverflowControl() {
12
- return this._showTabsOverflowControl;
13
- }
14
- set showTabsOverflowControl(value) {
15
- if (this._showTabsOverflowControl == value) {
16
- return;
17
- }
18
- this._showTabsOverflowControl = value;
19
- if (value) {
20
- const observer = new OverflowObserver(this._tabsList);
21
- this._observerDisposable.value = new CompositeDisposable(observer, observer.onDidChange((event) => {
22
- const hasOverflow = event.hasScrollX || event.hasScrollY;
23
- this.toggleDropdown({ reset: !hasOverflow });
24
- if (this._tabGroupManager.groupUnderlines.size > 0) {
25
- this._tabGroupManager.positionUnderlines();
26
- }
27
- }), addDisposableListener(this._tabsList, 'scroll', () => {
28
- this.toggleDropdown({ reset: false });
29
- if (this._tabGroupManager.groupUnderlines.size > 0) {
30
- this._tabGroupManager.positionUnderlines();
31
- }
32
- }));
33
- }
34
- }
35
- get element() {
36
- return this._element;
37
- }
38
- set voidContainer(el) {
39
- var _a;
40
- (_a = this._voidContainerListeners) === null || _a === void 0 ? void 0 : _a.dispose();
41
- this._voidContainerListeners = null;
42
- this._voidContainer = el;
43
- if (el) {
44
- this._voidContainerListeners = new CompositeDisposable(addDisposableListener(el, 'dragover', (event) => {
45
- if (this._animState) {
46
- event.preventDefault();
47
- }
48
- }), addDisposableListener(el, 'drop', (event) => {
49
- var _a;
50
- if (((_a = this._animState) === null || _a === void 0 ? void 0 : _a.sourceTabGroupId) &&
51
- this._animState.currentInsertionIndex !== null) {
52
- event.preventDefault();
53
- event.stopPropagation();
54
- this.handleVoidDrop();
55
- }
56
- }));
57
- }
58
- }
59
- /**
60
- * Handle a drop that occurred on the void container (empty header
61
- * space to the right of the tabs). Returns `true` if the drop was
62
- * consumed by an active group drag, `false` otherwise.
63
- */
64
- handleVoidDrop() {
65
- var _a, _b;
66
- if (!((_a = this._animState) === null || _a === void 0 ? void 0 : _a.sourceTabGroupId)) {
67
- return false;
68
- }
69
- const sourceTabGroupId = this._animState.sourceTabGroupId;
70
- const insertionIndex = (_b = this._animState.currentInsertionIndex) !== null && _b !== void 0 ? _b : this._tabs.length;
71
- this._animState = null;
72
- this._commitGroupMove(sourceTabGroupId, insertionIndex);
73
- return true;
74
- }
75
- get panels() {
76
- return this._tabs.map((_) => _.value.panel.id);
77
- }
78
- get size() {
79
- return this._tabs.length;
80
- }
81
- get tabs() {
82
- return this._tabs.map((_) => _.value);
83
- }
84
- get direction() {
85
- return this._direction;
86
- }
87
- set direction(value) {
88
- if (this._direction === value) {
89
- return;
90
- }
91
- this._direction = value;
92
- this._tabsList.setAttribute('aria-orientation', value === 'vertical' ? 'vertical' : 'horizontal');
93
- if (this._scrollbar) {
94
- this._scrollbar.orientation = value;
95
- }
96
- removeClasses(this._tabsList, 'dv-horizontal', 'dv-vertical');
97
- if (value === 'vertical') {
98
- addClasses(this._tabsList, 'dv-tabs-container-vertical', 'dv-vertical');
99
- }
100
- else {
101
- removeClasses(this._tabsList, 'dv-tabs-container-vertical');
102
- addClasses(this._tabsList, 'dv-horizontal');
103
- }
104
- for (const tab of this._tabs) {
105
- tab.value.setDirection(value);
106
- }
107
- this._tabGroupManager.updateDirection();
108
- }
109
- constructor(group, accessor, options) {
110
- super();
111
- this.group = group;
112
- this.accessor = accessor;
113
- this._observerDisposable = new MutableDisposable();
114
- this._scrollbar = null;
115
- this._tabs = [];
116
- this._tabMap = new Map();
117
- this.selectedIndex = -1;
118
- this._showTabsOverflowControl = false;
119
- this._direction = 'horizontal';
120
- this._animState = null;
121
- this._pendingMarginCleanups = new Map();
122
- this._pendingCollapse = false;
123
- this._flipTransitionCleanup = null;
124
- this._voidContainer = null;
125
- this._voidContainerListeners = null;
126
- this._extendedDropZone = null;
127
- this._pointerInsideTabsList = false;
128
- this._onTabDragStart = new Emitter();
129
- this.onTabDragStart = this._onTabDragStart.event;
130
- this._onDrop = new Emitter();
131
- this.onDrop = this._onDrop.event;
132
- this._onWillShowOverlay = new Emitter();
133
- this.onWillShowOverlay = this._onWillShowOverlay.event;
134
- this._onOverflowTabsChange = new Emitter();
135
- this.onOverflowTabsChange = this._onOverflowTabsChange.event;
136
- this._tabsList = document.createElement('div');
137
- this._tabsList.className = 'dv-tabs-container';
138
- // WAI-ARIA Tabs pattern: the strip of tabs is the tablist.
139
- this._tabsList.setAttribute('role', 'tablist');
140
- this._tabsList.setAttribute('aria-orientation', this._direction === 'vertical' ? 'vertical' : 'horizontal');
141
- this.showTabsOverflowControl = options.showTabsOverflowControl;
142
- if (accessor.options.scrollbars === 'native') {
143
- this._element = this._tabsList;
144
- }
145
- else {
146
- this._scrollbar = new Scrollbar(this._tabsList);
147
- this._scrollbar.orientation = this.direction;
148
- this._element = this._scrollbar.element;
149
- this.addDisposables(this._scrollbar);
150
- }
151
- this._tabGroupManager = new TabGroupManager({
152
- group: this.group,
153
- accessor: this.accessor,
154
- tabsList: this._tabsList,
155
- getTabs: () => this._tabs,
156
- getTabMap: () => this._tabMap,
157
- getDirection: () => this._direction,
158
- }, {
159
- onChipContextMenu: (tabGroup, event) => {
160
- var _a;
161
- (_a = this.accessor.contextMenuService) === null || _a === void 0 ? void 0 : _a.showForChip(tabGroup, this.group, event);
162
- },
163
- onChipDragStart: (tabGroup, chip, event) => {
164
- this._handleChipDragStart(tabGroup, chip, event);
165
- },
166
- onChipDragEnd: () => {
167
- // HTML5 chip dragend (incl. cancels). The Html5DragSource
168
- // owns the listener on the chip element, so this fires
169
- // even if the chip was detached cross-group — the
170
- // element keeps its listeners until the source is
171
- // disposed. resetDragAnimation is a no-op after a
172
- // successful drop (anim state already null) thanks to
173
- // the gating inside it.
174
- this.resetDragAnimation();
175
- },
176
- onChipDrop: (tabGroup, event) => {
177
- this._handleChipDrop(tabGroup, event);
178
- },
179
- });
180
- this.addDisposables(this._onOverflowTabsChange, this._observerDisposable, this._onWillShowOverlay, this._onDrop, this._onTabDragStart, {
181
- dispose: () => {
182
- var _a;
183
- (_a = this._flipTransitionCleanup) === null || _a === void 0 ? void 0 : _a.call(this);
184
- },
185
- },
186
- // Pointer-side cleanup: when any pointer drag ends, tear
187
- // down smooth-reorder anim state the dragover bridge may
188
- // have installed. The chip's pointer drag source handles
189
- // its own transfer payload + iframe-shield cleanup.
190
- PointerDragController.getInstance().onDragEnd(() => {
191
- this._pointerInsideTabsList = false;
192
- this.resetDragAnimation();
193
- }),
194
- // Pointer-event mirror of the HTML5 dragover / dragleave handlers
195
- // below. Drives smooth-reorder for `dndStrategy: 'pointer'` and
196
- // for touch drags in `'auto'`.
197
- PointerDragController.getInstance().onDragMove((e) => {
198
- this._handlePointerDragMove(e.clientX, e.clientY);
199
- }), addDisposableListener(this.element, 'pointerdown', (event) => {
200
- if (event.defaultPrevented) {
201
- return;
202
- }
203
- const isLeftClick = event.button === 0;
204
- if (isLeftClick) {
205
- this.accessor.doSetGroupActive(this.group);
206
- }
207
- }),
208
- // Trackpad / wheel forwarding. The strip scrolls along its own
209
- // axis (x for horizontal headers, y for vertical), so deltaY
210
- // from a plain mouse wheel maps onto the strip's axis too —
211
- // this gives the VS Code-style "scroll over tab bar to page
212
- // through tabs" feel. We only consume the event when the strip
213
- // is actually overflowing in the direction the user wheeled in,
214
- // so a wheel at the edge of a non-overflowing strip still
215
- // bubbles up and scrolls the page. `{ passive: false }` is
216
- // required because we call preventDefault().
217
- addDisposableListener(this._tabsList, 'wheel', (event) => {
218
- const isVertical = this._direction === 'vertical';
219
- const primary = isVertical
220
- ? event.deltaY || event.deltaX
221
- : event.deltaX || event.deltaY;
222
- if (primary === 0) {
223
- return;
224
- }
225
- const max = isVertical
226
- ? this._tabsList.scrollHeight -
227
- this._tabsList.clientHeight
228
- : this._tabsList.scrollWidth -
229
- this._tabsList.clientWidth;
230
- if (max <= 0) {
231
- return;
232
- }
233
- const current = isVertical
234
- ? this._tabsList.scrollTop
235
- : this._tabsList.scrollLeft;
236
- // At the edge in the wheel direction: let the page
237
- // scroll instead of trapping the gesture.
238
- if ((primary < 0 && current <= 0) ||
239
- (primary > 0 && current >= max)) {
240
- return;
241
- }
242
- event.preventDefault();
243
- // Custom-scrollbar mode wraps the tabs list and installs
244
- // its own wheel listener that rewrites scrollLeft from a
245
- // deltaY-only tracker. Without stopPropagation that
246
- // handler would clobber our deltaX-aware update.
247
- event.stopPropagation();
248
- if (isVertical) {
249
- this._tabsList.scrollTop = current + primary;
250
- }
251
- else {
252
- this._tabsList.scrollLeft = current + primary;
253
- }
254
- }, { passive: false }),
255
- // WAI-ARIA Tabs keyboard pattern: arrow keys move the roving
256
- // focus along the strip, Home/End jump to the ends, and
257
- // Enter/Space activate the focused tab (manual activation, so
258
- // arrowing through tabs doesn't switch panels until committed).
259
- addDisposableListener(this._tabsList, 'keydown', (event) => {
260
- this._onKeyDown(event);
261
- }), addDisposableListener(this._tabsList, 'dragover', (event) => {
262
- if (this._processDragOver(event.clientX)) {
263
- // Allow `drop` to fire on the tabs list container.
264
- event.preventDefault();
265
- }
266
- }, true), addDisposableListener(this._tabsList, 'dragleave', (event) => {
267
- this._processDragLeave(event.relatedTarget);
268
- }, true), addDisposableListener(this._tabsList, 'dragend', () => {
269
- this.resetDragAnimation();
270
- }), addDisposableListener(this._tabsList, 'drop', (event) => {
271
- var _a, _b, _c;
272
- if (!this._animState ||
273
- this._animState.currentInsertionIndex === null) {
274
- return;
275
- }
276
- // In non-smooth mode only handle group drags here;
277
- // individual tab drops are handled by tab Droptargets.
278
- if (((_a = this.accessor.options.theme) === null || _a === void 0 ? void 0 : _a.tabAnimation) !==
279
- 'smooth' &&
280
- !this._animState.sourceTabGroupId) {
281
- return;
282
- }
283
- event.stopPropagation();
284
- event.preventDefault();
285
- // The capturing stopPropagation above prevents the
286
- // individual tab's Droptarget.onDrop from firing, so
287
- // the anchor overlay won't be cleared by that path.
288
- // Clear it explicitly here before processing the drop.
289
- (_c = (_b = this.group.model.dropTargetContainer) === null || _b === void 0 ? void 0 : _b.model) === null || _c === void 0 ? void 0 : _c.clear();
290
- const animState = this._animState;
291
- this._animState = null;
292
- this._pendingCollapse = false;
293
- // Handle group drag (entire group repositioned)
294
- if (animState.sourceTabGroupId) {
295
- this._commitGroupMove(animState.sourceTabGroupId, animState.currentInsertionIndex);
296
- return;
297
- }
298
- const insertionIndex = animState.currentInsertionIndex;
299
- const sourceIndex = animState.sourceIndex;
300
- const adjustedIndex = insertionIndex -
301
- (sourceIndex !== -1 && sourceIndex < insertionIndex
302
- ? 1
303
- : 0);
304
- const sourceCurrentGroup = this.group.model.getTabGroupForPanel(animState.sourceTabId);
305
- if (adjustedIndex === sourceIndex &&
306
- !animState.targetTabGroupId &&
307
- !sourceCurrentGroup) {
308
- this._uncollapsSourceTab(animState.sourceTabId);
309
- this.resetTabTransforms();
310
- return;
311
- }
312
- this._uncollapsSourceTab(animState.sourceTabId);
313
- const firstPositions = this.snapshotTabPositions();
314
- this.resetTabTransforms();
315
- this._onDrop.fire({
316
- event,
317
- index: adjustedIndex,
318
- targetTabGroupId: animState.targetTabGroupId,
319
- });
320
- this.runFlipAnimation(firstPositions, animState.sourceTabId, animState.sourceIndex === -1, {
321
- from: Math.min(sourceIndex, adjustedIndex),
322
- to: Math.max(sourceIndex, adjustedIndex),
323
- });
324
- }, true), Disposable.from(() => {
325
- var _a;
326
- (_a = this._voidContainerListeners) === null || _a === void 0 ? void 0 : _a.dispose();
327
- this.resetDragAnimation();
328
- this._tabGroupManager.disposeAll();
329
- for (const { value, disposable } of this._tabs) {
330
- disposable.dispose();
331
- value.dispose();
332
- }
333
- this._tabs = [];
334
- this._tabMap.clear();
335
- }));
336
- }
337
- indexOf(id) {
338
- return this._tabs.findIndex((tab) => tab.value.panel.id === id);
339
- }
340
- /** DOM id of the tab element for a panel — for the tabpanel's `aria-labelledby`. */
341
- getTabId(panelId) {
342
- var _a;
343
- return (_a = this._tabMap.get(panelId)) === null || _a === void 0 ? void 0 : _a.value.element.id;
344
- }
345
- isActive(tab) {
346
- return (this.selectedIndex > -1 &&
347
- this._tabs[this.selectedIndex].value === tab);
348
- }
349
- _onKeyDown(event) {
350
- // Only handle when a tab element itself is focused — never hijack keys
351
- // typed inside a custom tab renderer's own controls (inputs etc.).
352
- const index = this._tabs.findIndex((tab) => tab.value.element === event.target);
353
- if (index === -1) {
354
- return;
355
- }
356
- const isVertical = this._direction === 'vertical';
357
- const nextKey = isVertical ? 'ArrowDown' : 'ArrowRight';
358
- const prevKey = isVertical ? 'ArrowUp' : 'ArrowLeft';
359
- const last = this._tabs.length - 1;
360
- switch (event.key) {
361
- case nextKey:
362
- event.preventDefault();
363
- this._focusTab(Math.min(index + 1, last));
364
- break;
365
- case prevKey:
366
- event.preventDefault();
367
- this._focusTab(Math.max(index - 1, 0));
368
- break;
369
- case 'Home':
370
- event.preventDefault();
371
- this._focusTab(0);
372
- break;
373
- case 'End':
374
- event.preventDefault();
375
- this._focusTab(last);
376
- break;
377
- case 'Enter':
378
- case ' ':
379
- // Manual activation of the focused tab.
380
- event.preventDefault();
381
- this.accessor.withOrigin('user', () => this._tabs[index].value.panel.api.setActive());
382
- break;
383
- case 'Delete':
384
- case 'Backspace':
385
- // Close the focused tab (Backspace covers macOS, where the
386
- // primary delete key reports as Backspace).
387
- event.preventDefault();
388
- this._closeTab(index);
389
- break;
390
- }
391
- }
392
- /**
393
- * Close the tab at `index` and move roving focus to a neighbouring tab so
394
- * keyboard focus stays in the tablist.
395
- */
396
- _closeTab(index) {
397
- var _a, _b, _c, _d, _e;
398
- const tab = (_a = this._tabs[index]) === null || _a === void 0 ? void 0 : _a.value;
399
- if (!tab) {
400
- return;
401
- }
402
- // Resolve the post-close focus target before closing mutates the list:
403
- // prefer the next tab, otherwise the previous.
404
- const neighbourId = (_e = ((_c = (_b = this._tabs[index + 1]) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : (_d = this._tabs[index - 1]) === null || _d === void 0 ? void 0 : _d.value)) === null || _e === void 0 ? void 0 : _e.panel.id;
405
- tab.panel.api.close();
406
- if (neighbourId !== undefined) {
407
- const nextIndex = this._tabs.findIndex((t) => t.value.panel.id === neighbourId);
408
- if (nextIndex > -1) {
409
- this._focusTab(nextIndex);
410
- }
411
- }
412
- }
413
- /** Move the roving focus to the tab at `index` (updates tabindex + DOM focus). */
414
- _focusTab(index) {
415
- for (let i = 0; i < this._tabs.length; i++) {
416
- this._tabs[i].value.element.tabIndex = i === index ? 0 : -1;
417
- }
418
- this._tabs[index].value.element.focus();
419
- }
420
- /** Move DOM focus to the active tab — the entry point into the tablist. */
421
- focusActiveTab() {
422
- var _a;
423
- if (this._tabs.length === 0) {
424
- return;
425
- }
426
- const activeId = (_a = this.group.activePanel) === null || _a === void 0 ? void 0 : _a.id;
427
- const activeIndex = activeId
428
- ? this._tabs.findIndex((t) => t.value.panel.id === activeId)
429
- : -1;
430
- this._focusTab(activeIndex > -1 ? activeIndex : 0);
431
- }
432
- setActivePanel(panel) {
433
- const isVertical = this._direction === 'vertical';
434
- let running = 0;
435
- for (const tab of this._tabs) {
436
- const isActivePanel = panel.id === tab.value.panel.id;
437
- tab.value.setActive(isActivePanel);
438
- if (isActivePanel) {
439
- const element = tab.value.element;
440
- const parentElement = element.parentElement;
441
- if (isVertical) {
442
- if (running < parentElement.scrollTop ||
443
- running + element.clientHeight >
444
- parentElement.scrollTop + parentElement.clientHeight) {
445
- parentElement.scrollTop = running;
446
- }
447
- }
448
- else if (running < parentElement.scrollLeft ||
449
- running + element.clientWidth >
450
- parentElement.scrollLeft + parentElement.clientWidth) {
451
- parentElement.scrollLeft = running;
452
- }
453
- }
454
- running += isVertical
455
- ? tab.value.element.clientHeight
456
- : tab.value.element.clientWidth;
457
- }
458
- // Reposition underlines so the wrap-around follows the new active tab
459
- if (this._tabGroupManager.groupUnderlines.size > 0) {
460
- this._tabGroupManager.positionUnderlines();
461
- }
462
- }
463
- openPanel(panel, index = this._tabs.length) {
464
- if (this._tabMap.has(panel.id)) {
465
- return;
466
- }
467
- const tab = new Tab(panel, this.accessor, this.group);
468
- tab.setContent(panel.view.tab);
469
- if (this._direction !== 'horizontal') {
470
- tab.setDirection(this._direction);
471
- }
472
- const disposable = new CompositeDisposable(tab.onDragStart((event) => {
473
- var _a;
474
- this._onTabDragStart.fire({ nativeEvent: event, panel });
475
- // Both HTML5 and pointer drags initialize _animState. Cleanup
476
- // is wired in both paths: HTML5 via dragend/drop on _tabsList,
477
- // pointer via PointerDragController.onDragEnd subscriptions.
478
- if (((_a = this.accessor.options.theme) === null || _a === void 0 ? void 0 : _a.tabAnimation) === 'smooth') {
479
- const tabWidth = tab.element.getBoundingClientRect().width;
480
- const sourceIndex = this._tabs.findIndex((x) => x.value === tab);
481
- this._animState = {
482
- sourceTabId: panel.id,
483
- sourceIndex,
484
- tabPositions: this.snapshotTabPositions(),
485
- chipPositions: this._tabGroupManager.snapshotChipWidths(),
486
- currentInsertionIndex: null,
487
- targetTabGroupId: null,
488
- sourceTabGroupId: null,
489
- sourceGroupPanelIds: null,
490
- sourceChipWidth: 0,
491
- cursorOffsetFromDragLeft: tabWidth / 2,
492
- sourceGapWidth: tabWidth,
493
- containerLeft: this._tabsList.getBoundingClientRect().left,
494
- };
495
- // Collapse the source tab after the browser captures the
496
- // drag image, then open the gap at the source position in
497
- // the same paint frame — no visual jump.
498
- // Both collapse and gap must be instant (no transition).
499
- this._pendingCollapse = true;
500
- requestAnimationFrame(() => {
501
- var _a;
502
- var _b;
503
- this._pendingCollapse = false;
504
- if (!this._animState) {
505
- return;
506
- }
507
- // Collapse source tab instantly (no transition)
508
- tab.element.style.transition = 'none';
509
- toggleClass(tab.element, 'dv-tab--dragging', true);
510
- void tab.element.offsetHeight; // force reflow
511
- (_a = (_b = this._animState).currentInsertionIndex) !== null && _a !== void 0 ? _a : (_b.currentInsertionIndex = sourceIndex);
512
- // Apply gap with transitions disabled on the target
513
- this.applyDragOverTransforms(true);
514
- // Re-enable transitions for subsequent moves
515
- tab.element.style.removeProperty('transition');
516
- });
517
- }
518
- }), tab.onTabClick((event) => {
519
- if (event.defaultPrevented) {
520
- return;
521
- }
522
- if (this.group.api.location.type !== 'edge') {
523
- return;
524
- }
525
- if (this.group.activePanel === panel) {
526
- // Clicking the active tab toggles expansion
527
- if (this.group.api.isCollapsed()) {
528
- this.group.api.expand();
529
- }
530
- else {
531
- this.group.api.collapse();
532
- }
533
- }
534
- else {
535
- // Clicking a non-active tab switches the active tab.
536
- // If the group is collapsed, also expand it.
537
- this.group.model.openPanel(panel);
538
- if (this.group.api.isCollapsed()) {
539
- this.group.api.expand();
540
- }
541
- }
542
- }), tab.onPointerDown((event) => {
543
- if (event.defaultPrevented) {
544
- return;
545
- }
546
- const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups;
547
- const isFloatingWithOnePanel = this.group.api.location.type === 'floating' &&
548
- this.size === 1;
549
- if (isFloatingGroupsEnabled &&
550
- !isFloatingWithOnePanel &&
551
- event.shiftKey) {
552
- event.preventDefault();
553
- const panel = this.accessor.getGroupPanel(tab.panel.id);
554
- const { top, left } = tab.element.getBoundingClientRect();
555
- const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect();
556
- this.accessor.addFloatingGroup(panel, {
557
- x: left - rootLeft,
558
- y: top - rootTop,
559
- inDragMode: true,
560
- });
561
- return;
562
- }
563
- // Edge groups are skipped here: all their tab interaction
564
- // is handled by onTabClick to avoid race conditions with
565
- // active panel state.
566
- if (event.button === 0 &&
567
- this.group.api.location.type !== 'edge' &&
568
- this.group.activePanel !== panel) {
569
- this.group.model.openPanel(panel);
570
- }
571
- }), tab.onDrop((event) => {
572
- var _a, _b, _c, _d;
573
- const animState = this._animState;
574
- this._animState = null;
575
- this._pendingCollapse = false;
576
- const tabIndex = this._tabs.findIndex((x) => x.value === tab);
577
- if (animState) {
578
- const dropIndex = event.position === 'right' ? tabIndex + 1 : tabIndex;
579
- if (animState.sourceTabGroupId) {
580
- this._commitGroupMove(animState.sourceTabGroupId, (_a = animState.currentInsertionIndex) !== null && _a !== void 0 ? _a : dropIndex);
581
- return;
582
- }
583
- this._uncollapsSourceTab(animState.sourceTabId);
584
- const firstPositions = this.snapshotTabPositions();
585
- this.resetTabTransforms();
586
- this._onDrop.fire({
587
- event: event.nativeEvent,
588
- index: dropIndex,
589
- targetTabGroupId: animState.targetTabGroupId,
590
- });
591
- if (((_b = this.accessor.options.theme) === null || _b === void 0 ? void 0 : _b.tabAnimation) === 'smooth') {
592
- this.runFlipAnimation(firstPositions, animState.sourceTabId, animState.sourceIndex === -1, animState.sourceIndex === -1
593
- ? undefined
594
- : {
595
- from: Math.min(animState.sourceIndex, dropIndex),
596
- to: Math.max(animState.sourceIndex, dropIndex),
597
- });
598
- }
599
- }
600
- else {
601
- // Compute insertion index based on which half of the tab
602
- // the pointer is over, then adjust for same-group removal:
603
- // when the source tab sits before the insertion point,
604
- // removing it shifts all subsequent indices down by one.
605
- const afterPosition = this._direction === 'vertical' ? 'bottom' : 'right';
606
- const insertionIndex = event.position === afterPosition
607
- ? tabIndex + 1
608
- : tabIndex;
609
- const data = getPanelData();
610
- const sourceIndex = data
611
- ? this._tabs.findIndex((x) => x.value.panel.id === data.panelId)
612
- : -1;
613
- const adjustedIndex = insertionIndex -
614
- (sourceIndex !== -1 && sourceIndex < insertionIndex
615
- ? 1
616
- : 0);
617
- const targetTabGroupId = (_d = (_c = this.group.model.getTabGroupForPanel(tab.panel.id)) === null || _c === void 0 ? void 0 : _c.id) !== null && _d !== void 0 ? _d : null;
618
- this._onDrop.fire({
619
- event: event.nativeEvent,
620
- index: adjustedIndex,
621
- targetTabGroupId,
622
- });
623
- }
624
- }), tab.onWillShowOverlay((event) => {
625
- this._onWillShowOverlay.fire(new DockviewWillShowOverlayLocationEvent(event, {
626
- kind: 'tab',
627
- panel: this.group.activePanel,
628
- api: this.accessor.api,
629
- group: this.group,
630
- getData: getPanelData,
631
- }));
632
- }));
633
- const value = { value: tab, disposable };
634
- this.addTab(value, index);
635
- // A new tab may have been inserted between a chip and its
636
- // group's first tab — reposition all chips to stay correct.
637
- this._tabGroupManager.positionAllChips();
638
- // If a tab was added during active drag, refresh positions
639
- if (this._animState) {
640
- this._animState.tabPositions = this.snapshotTabPositions();
641
- this._animState.chipPositions =
642
- this._tabGroupManager.snapshotChipWidths();
643
- this.applyDragOverTransforms();
644
- }
645
- }
646
- delete(id) {
647
- var _a;
648
- if (((_a = this._animState) === null || _a === void 0 ? void 0 : _a.sourceTabId) === id) {
649
- this.resetTabTransforms();
650
- this._animState = null;
651
- }
652
- // Force-clean any pending transitionend listener
653
- this._tabGroupManager.cleanupTransition(id);
654
- const index = this.indexOf(id);
655
- const tabToRemove = this._tabs.splice(index, 1)[0];
656
- this._tabMap.delete(id);
657
- if (tabToRemove) {
658
- const { value, disposable } = tabToRemove;
659
- disposable.dispose();
660
- value.dispose();
661
- value.element.remove();
662
- }
663
- // If a non-source tab was removed during active drag, refresh positions
664
- if (this._animState) {
665
- this._animState.tabPositions = this.snapshotTabPositions();
666
- this._animState.chipPositions =
667
- this._tabGroupManager.snapshotChipWidths();
668
- this.applyDragOverTransforms();
669
- }
670
- }
671
- addTab(tab, index = this._tabs.length) {
672
- if (index < 0 || index > this._tabs.length) {
673
- throw new Error('invalid location');
674
- }
675
- // Use the tab element at `index` as the reference node rather than
676
- // `children[index]`, because `_tabsList` may contain non-tab children
677
- // (e.g. group chips, underlines) that shift the DOM indices.
678
- const refNode = index < this._tabs.length ? this._tabs[index].value.element : null;
679
- this._tabsList.insertBefore(tab.value.element, refNode);
680
- this._tabs = [
681
- ...this._tabs.slice(0, index),
682
- tab,
683
- ...this._tabs.slice(index),
684
- ];
685
- this._tabMap.set(tab.value.panel.id, tab);
686
- if (this.selectedIndex < 0) {
687
- this.selectedIndex = index;
688
- }
689
- }
690
- toggleDropdown(options) {
691
- if (options.reset) {
692
- this._onOverflowTabsChange.fire({
693
- tabs: [],
694
- tabGroups: [],
695
- reset: true,
696
- });
697
- return;
698
- }
699
- const tabs = this._tabs
700
- .filter((tab) => !isChildEntirelyVisibleWithinParent(tab.value.element, this._tabsList))
701
- .map((x) => x.value.panel.id);
702
- // Detect tab groups whose chip is clipped or whose tabs are all
703
- // in the overflow set (e.g. collapsed groups scrolled out of view).
704
- const overflowTabSet = new Set(tabs);
705
- const tabGroups = [];
706
- for (const tg of this.group.model.getTabGroups()) {
707
- const chipEntry = this._tabGroupManager.chipRenderers.get(tg.id);
708
- const chipClipped = chipEntry &&
709
- !isChildEntirelyVisibleWithinParent(chipEntry.chip.element, this._tabsList);
710
- // A group is in overflow if its chip is clipped OR all its
711
- // visible tabs are in the overflow set.
712
- const allTabsOverflow = tg.panelIds.length > 0 &&
713
- tg.panelIds.every((pid) => overflowTabSet.has(pid));
714
- if (chipClipped || allTabsOverflow) {
715
- tabGroups.push(tg.id);
716
- // For collapsed groups whose chip is clipped, ensure all
717
- // member tabs are included in the overflow list so they
718
- // appear in the dropdown.
719
- if (tg.collapsed) {
720
- for (const pid of tg.panelIds) {
721
- if (!overflowTabSet.has(pid)) {
722
- overflowTabSet.add(pid);
723
- tabs.push(pid);
724
- }
725
- }
726
- }
727
- }
728
- }
729
- this._onOverflowTabsChange.fire({ tabs, tabGroups, reset: false });
730
- }
731
- updateDragAndDropState() {
732
- for (const tab of this._tabs) {
733
- tab.value.updateDragAndDropState();
734
- }
735
- this._tabGroupManager.updateDragAndDropState();
736
- }
737
- /**
738
- * Synchronize chip elements and CSS classes for all tab groups
739
- * in the parent group model. Call after any tab group mutation.
740
- */
741
- updateTabGroups() {
742
- this._tabGroupManager.update();
743
- }
744
- refreshTabGroupAccent() {
745
- this._tabGroupManager.refreshAccents();
746
- }
747
- /**
748
- * Tabs-list-specific side effects of a chip drag start. The chip's
749
- * drag sources (constructed by `TabGroupManager`) own the transfer
750
- * payload, iframe shielding, dataTransfer setup, and the HTML5 drag
751
- * image. This method just sets up the smooth-reorder anim state and
752
- * collapses the source-group tabs in the tabs list.
753
- */
754
- _handleChipDragStart(tabGroup, chip, event) {
755
- var _a;
756
- const firstPanelId = tabGroup.panelIds[0];
757
- const firstIdx = firstPanelId
758
- ? this._tabs.findIndex((t) => t.value.panel.id === firstPanelId)
759
- : -1;
760
- const chipRect = chip.element.getBoundingClientRect();
761
- // Compute total group width (chip + all tabs)
762
- let groupGapWidth = chipRect.width;
763
- for (const pid of tabGroup.panelIds) {
764
- const tabEntry = this._tabMap.get(pid);
765
- if (tabEntry) {
766
- groupGapWidth +=
767
- tabEntry.value.element.getBoundingClientRect().width;
768
- }
769
- }
770
- this._animState = {
771
- sourceTabId: '',
772
- sourceIndex: firstIdx,
773
- tabPositions: this.snapshotTabPositions(),
774
- chipPositions: this._tabGroupManager.snapshotChipWidths(),
775
- currentInsertionIndex: null,
776
- targetTabGroupId: null,
777
- sourceTabGroupId: tabGroup.id,
778
- sourceGroupPanelIds: new Set(tabGroup.panelIds),
779
- sourceChipWidth: chipRect.width,
780
- cursorOffsetFromDragLeft: event.clientX - chipRect.left,
781
- sourceGapWidth: groupGapWidth,
782
- containerLeft: this._tabsList.getBoundingClientRect().left,
783
- };
784
- if (((_a = this.accessor.options.theme) === null || _a === void 0 ? void 0 : _a.tabAnimation) !== 'smooth') {
785
- return;
786
- }
787
- // Collapse group tabs + chip after the browser captures the drag
788
- // image, then open the gap at the source position — all instant
789
- // (no transitions).
790
- const groupPanelIds = new Set(tabGroup.panelIds);
791
- this._pendingCollapse = true;
792
- requestAnimationFrame(() => {
793
- var _a;
794
- var _b;
795
- this._pendingCollapse = false;
796
- if (!this._animState) {
797
- return;
798
- }
799
- // Collapse all group tabs instantly
800
- for (const t of this._tabs) {
801
- if (groupPanelIds.has(t.value.panel.id)) {
802
- t.value.element.style.transition = 'none';
803
- toggleClass(t.value.element, 'dv-tab--dragging', true);
804
- }
805
- }
806
- // Collapse the group chip instantly
807
- const chipEntry = this._tabGroupManager.chipRenderers.get(tabGroup.id);
808
- if (chipEntry) {
809
- chipEntry.chip.element.style.transition = 'none';
810
- toggleClass(chipEntry.chip.element, 'dv-tab-group-chip--dragging', true);
811
- }
812
- // Single reflow for the entire batch
813
- void this._tabsList.offsetHeight;
814
- const underline = this._tabGroupManager.groupUnderlines.get(tabGroup.id);
815
- if (underline) {
816
- underline.style.display = 'none';
817
- }
818
- (_a = (_b = this._animState).currentInsertionIndex) !== null && _a !== void 0 ? _a : (_b.currentInsertionIndex = firstIdx);
819
- this.applyDragOverTransforms(true);
820
- for (const t of this._tabs) {
821
- if (groupPanelIds.has(t.value.panel.id)) {
822
- t.value.element.style.removeProperty('transition');
823
- }
824
- }
825
- if (chipEntry) {
826
- chipEntry.chip.element.style.removeProperty('transition');
827
- }
828
- });
829
- }
830
- /**
831
- * A drop on a tab group chip means "insert before this group". Resolve to
832
- * the index of the group's first tab, adjusting for same-group removal
833
- * (when the source tab is currently to the left of the target slot, its
834
- * removal shifts the insertion index down by one). Always clears
835
- * `targetTabGroupId` so the dropped tab lands outside the group.
836
- */
837
- _handleChipDrop(tabGroup, event) {
838
- const firstPanelId = tabGroup.panelIds[0];
839
- if (!firstPanelId) {
840
- return;
841
- }
842
- const insertionIndex = this._tabs.findIndex((x) => x.value.panel.id === firstPanelId);
843
- if (insertionIndex === -1) {
844
- return;
845
- }
846
- const data = getPanelData();
847
- const sourceIndex = (data === null || data === void 0 ? void 0 : data.groupId) === this.group.id && (data === null || data === void 0 ? void 0 : data.panelId)
848
- ? this._tabs.findIndex((x) => x.value.panel.id === data.panelId)
849
- : -1;
850
- const adjustedIndex = insertionIndex -
851
- (sourceIndex !== -1 && sourceIndex < insertionIndex ? 1 : 0);
852
- this._onDrop.fire({
853
- event: event.nativeEvent,
854
- index: adjustedIndex,
855
- targetTabGroupId: null,
856
- });
857
- }
858
- /**
859
- * Sets the broader container that is part of the same logical drop surface
860
- * as this tab list (e.g. the full header element). When a dragleave from
861
- * the tabs list lands inside this container, `_animState` is preserved so
862
- * that external dragover listeners can continue the animation.
863
- */
864
- setExtendedDropZone(el) {
865
- this._extendedDropZone = el;
866
- }
867
- /**
868
- * Allows external elements (e.g. void container, left actions) to push an
869
- * insertion index into the animation while the cursor is outside the tabs
870
- * list itself. Pass `null` to clear the indicator.
871
- */
872
- setExternalInsertionIndex(index) {
873
- if (!this._animState) {
874
- return;
875
- }
876
- if (index === this._animState.currentInsertionIndex) {
877
- return;
878
- }
879
- this._animState.currentInsertionIndex = index;
880
- this.applyDragOverTransforms();
881
- }
882
- /**
883
- * Called when the drag cursor leaves the entire header area (not just the
884
- * tabs list). Clears animation state for cross-group drags, which never
885
- * receive a `dragend` event on this tab list.
886
- */
887
- clearExternalAnimState() {
888
- if (!this._animState) {
889
- return;
890
- }
891
- this.resetTabTransforms();
892
- if (this._animState.sourceIndex === -1) {
893
- this._animState = null;
894
- }
895
- else {
896
- this._animState.currentInsertionIndex = null;
897
- }
898
- }
899
- snapshotTabPositions() {
900
- const positions = new Map();
901
- for (const tab of this._tabs) {
902
- positions.set(tab.value.panel.id, tab.value.element.getBoundingClientRect());
903
- }
904
- return positions;
905
- }
906
- getAverageTabWidth() {
907
- if (this._tabs.length === 0) {
908
- return 0;
909
- }
910
- const isVertical = this._direction === 'vertical';
911
- let total = 0;
912
- for (const tab of this._tabs) {
913
- const rect = tab.value.element.getBoundingClientRect();
914
- total += isVertical ? rect.height : rect.width;
915
- }
916
- return total / this._tabs.length;
917
- }
918
- /**
919
- * Pointer-event entry point. The HTML5 path enters via the per-element
920
- * `dragover` listener; this one hit-tests the global pointer-drag
921
- * position against the tabs list and routes through the same shared
922
- * `_processDragOver` / `_processDragLeave` helpers.
923
- */
924
- _handlePointerDragMove(clientX, clientY) {
925
- var _a;
926
- const sourceDoc = (_a = this._tabsList.ownerDocument) !== null && _a !== void 0 ? _a : document;
927
- const elAtPoint = sourceDoc.elementFromPoint(clientX, clientY);
928
- const inside = !!elAtPoint &&
929
- (this._tabsList.contains(elAtPoint) ||
930
- (!!this._extendedDropZone &&
931
- this._extendedDropZone.contains(elAtPoint)));
932
- if (!inside) {
933
- if (this._pointerInsideTabsList) {
934
- this._pointerInsideTabsList = false;
935
- this._processDragLeave(elAtPoint);
936
- }
937
- return;
938
- }
939
- this._pointerInsideTabsList = true;
940
- this._processDragOver(clientX);
941
- }
942
- /**
943
- * Shared body of the dragover entry point. Refreshes stale anim state
944
- * for a changed drag identity, initializes anim state for incoming
945
- * cross-group drags, and dispatches to the gap-following math in
946
- * `handleDragOver`. Returns true when this tabs list has taken
947
- * ownership of the drag — HTML5 callers use this to gate
948
- * `event.preventDefault()`.
949
- */
950
- _processDragOver(clientX) {
951
- var _a, _b, _c, _d;
952
- if (this.accessor.options.disableDnd) {
953
- return false;
954
- }
955
- // Stale-state guard: if a previous drag's anim state is still here
956
- // but the current drag is a different identity, drop the stale one
957
- // so the new drag starts from a clean slate.
958
- if (this._animState) {
959
- const data = getPanelData();
960
- if ((data === null || data === void 0 ? void 0 : data.tabGroupId) &&
961
- data.groupId !== this.group.id &&
962
- this._animState.sourceTabGroupId !== data.tabGroupId) {
963
- this._animState = null;
964
- }
965
- }
966
- if (!this._animState) {
967
- const data = getPanelData();
968
- // In default animation mode, individual tab drops are handled
969
- // by per-tab Droptargets; only chip drags need tabs-list-level
970
- // handling so drops on void space still work.
971
- if (((_a = this.accessor.options.theme) === null || _a === void 0 ? void 0 : _a.tabAnimation) === 'default' &&
972
- !(data === null || data === void 0 ? void 0 : data.tabGroupId)) {
973
- return false;
974
- }
975
- if (data &&
976
- (data.panelId || data.tabGroupId) &&
977
- data.groupId !== this.group.id) {
978
- const avgWidth = this.getAverageTabWidth();
979
- if (data.tabGroupId) {
980
- // External group drag — look up the source group to
981
- // size the gap.
982
- const sourceGroup = this.accessor.getPanel(data.groupId);
983
- const sourceTg = sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.model.getTabGroups().find((tg) => tg.id === data.tabGroupId);
984
- const panelCount = (_b = sourceTg === null || sourceTg === void 0 ? void 0 : sourceTg.panelIds.length) !== null && _b !== void 0 ? _b : 1;
985
- const groupGapWidth = avgWidth * panelCount + avgWidth;
986
- this._animState = {
987
- sourceTabId: '',
988
- sourceIndex: -1,
989
- tabPositions: this.snapshotTabPositions(),
990
- chipPositions: this._tabGroupManager.snapshotChipWidths(),
991
- currentInsertionIndex: null,
992
- targetTabGroupId: null,
993
- sourceTabGroupId: data.tabGroupId,
994
- sourceGroupPanelIds: sourceTg
995
- ? new Set(sourceTg.panelIds)
996
- : new Set(),
997
- sourceChipWidth: avgWidth,
998
- cursorOffsetFromDragLeft: groupGapWidth / 2,
999
- sourceGapWidth: groupGapWidth,
1000
- containerLeft: this._tabsList.getBoundingClientRect().left,
1001
- };
1002
- }
1003
- else {
1004
- this._animState = {
1005
- sourceTabId: data.panelId,
1006
- sourceIndex: -1,
1007
- tabPositions: this.snapshotTabPositions(),
1008
- chipPositions: this._tabGroupManager.snapshotChipWidths(),
1009
- currentInsertionIndex: null,
1010
- targetTabGroupId: null,
1011
- sourceTabGroupId: null,
1012
- sourceGroupPanelIds: null,
1013
- sourceChipWidth: 0,
1014
- cursorOffsetFromDragLeft: avgWidth / 2,
1015
- sourceGapWidth: avgWidth,
1016
- containerLeft: this._tabsList.getBoundingClientRect().left,
1017
- };
1018
- }
1019
- }
1020
- else {
1021
- return false;
1022
- }
1023
- }
1024
- // For intra-group drag (sourceIndex >= 0) the gap animation is the
1025
- // sole visual indicator — clear any stale anchor overlay that may
1026
- // have been set while the cursor was over the panel content area or
1027
- // another zone. External drags (sourceIndex === -1) leave the
1028
- // overlay to the individual tab Droptargets so cross-group
1029
- // animation is not disrupted.
1030
- if (this._animState.sourceIndex !== -1) {
1031
- (_d = (_c = this.group.model.dropTargetContainer) === null || _c === void 0 ? void 0 : _c.model) === null || _d === void 0 ? void 0 : _d.clear();
1032
- }
1033
- this.handleDragOver({ clientX });
1034
- return true;
1035
- }
1036
- /**
1037
- * Shared body of the dragleave entry point. Preserves anim state when
1038
- * the drag moves between tabs-list children, into the extended drop
1039
- * zone, or into the void container; tears it down otherwise.
1040
- */
1041
- _processDragLeave(related) {
1042
- var _a, _b, _c;
1043
- if (!this._animState) {
1044
- return;
1045
- }
1046
- // Moves between children of the tabs list aren't real leaves.
1047
- if (related && this._tabsList.contains(related)) {
1048
- return;
1049
- }
1050
- // Moving into the broader drop zone (e.g. void container, left
1051
- // actions) — keep anim state alive so external listeners can
1052
- // continue the gap animation.
1053
- if (related && ((_a = this._extendedDropZone) === null || _a === void 0 ? void 0 : _a.contains(related))) {
1054
- this.resetTabTransforms();
1055
- this._animState.currentInsertionIndex = null;
1056
- return;
1057
- }
1058
- // Leaving toward the void container (empty header space to the
1059
- // right): keep anim state so a drop can still land at the end.
1060
- const isVoid = this._voidContainer &&
1061
- related &&
1062
- (related === this._voidContainer ||
1063
- this._voidContainer.contains(related));
1064
- if (isVoid) {
1065
- return;
1066
- }
1067
- this.resetTabTransforms();
1068
- if (this._animState.sourceIndex === -1) {
1069
- (_c = (_b = this.group.model.dropTargetContainer) === null || _b === void 0 ? void 0 : _b.model) === null || _c === void 0 ? void 0 : _c.clear();
1070
- this._animState = null;
1071
- }
1072
- else {
1073
- this._animState.currentInsertionIndex = null;
1074
- }
1075
- }
1076
- handleDragOver(event) {
1077
- var _a, _b, _c, _d, _e;
1078
- if (!this._animState) {
1079
- return;
1080
- }
1081
- const mouseX = event.clientX;
1082
- let insertionIndex = null;
1083
- let targetTabGroupId = null;
1084
- const sourceGroupPanelIds = this._animState.sourceGroupPanelIds;
1085
- // Accumulation approach: compute where the drag image's left edge
1086
- // would be, then walk tabs left-to-right using their original widths.
1087
- // A tab fits to the left of the gap if the cumulative width of all
1088
- // preceding non-source tabs <= available space.
1089
- const dragLeftEdge = mouseX - this._animState.cursorOffsetFromDragLeft;
1090
- const availableSpace = dragLeftEdge - this._animState.containerLeft;
1091
- let accWidth = 0;
1092
- // Build lookup: first panel ID of each non-source group → group ID
1093
- // so we can add chip widths when we encounter a group's first tab.
1094
- const firstPanelToGroup = new Map();
1095
- if (this._tabGroupManager.chipRenderers.size > 0) {
1096
- const tabGroups = this.group.model.getTabGroups();
1097
- for (const tg of tabGroups) {
1098
- if (tg.id === this._animState.sourceTabGroupId) {
1099
- continue;
1100
- }
1101
- if (tg.panelIds.length > 0) {
1102
- firstPanelToGroup.set(tg.panelIds[0], tg.id);
1103
- }
1104
- }
1105
- }
1106
- for (let i = 0; i < this._tabs.length; i++) {
1107
- const tab = this._tabs[i].value;
1108
- if (tab.panel.id === this._animState.sourceTabId) {
1109
- continue;
1110
- }
1111
- if (sourceGroupPanelIds === null || sourceGroupPanelIds === void 0 ? void 0 : sourceGroupPanelIds.has(tab.panel.id)) {
1112
- continue;
1113
- }
1114
- // If this tab is the first of a non-source group, include
1115
- // the chip width (which sits before it in the DOM).
1116
- const groupId = firstPanelToGroup.get(tab.panel.id);
1117
- if (groupId) {
1118
- const chipWidth = (_a = this._animState.chipPositions.get(groupId)) !== null && _a !== void 0 ? _a : 0;
1119
- if (accWidth + chipWidth > availableSpace) {
1120
- // Chip alone overflows — gap goes before this group
1121
- insertionIndex !== null && insertionIndex !== void 0 ? insertionIndex : (insertionIndex = i);
1122
- break;
1123
- }
1124
- accWidth += chipWidth;
1125
- }
1126
- // Use original width (before collapse/transforms)
1127
- const origRect = this._animState.tabPositions.get(tab.panel.id);
1128
- const tabWidth = origRect
1129
- ? origRect.width
1130
- : tab.element.getBoundingClientRect().width;
1131
- // Shift at the midpoint: a tab moves left once the drag image
1132
- // covers half of it (like Chrome's tab drag behavior).
1133
- if (accWidth + tabWidth / 2 <= availableSpace) {
1134
- accWidth += tabWidth;
1135
- insertionIndex = i + 1;
1136
- }
1137
- else {
1138
- insertionIndex !== null && insertionIndex !== void 0 ? insertionIndex : (insertionIndex = i);
1139
- break;
1140
- }
1141
- }
1142
- // Determine which tab group (if any) the insertion index falls within.
1143
- //
1144
- // We use snapshot-based positions (accWidth from the accumulation loop
1145
- // above) to compute original chip boundaries. This avoids reading
1146
- // getBoundingClientRect() on chips whose live position is shifted by
1147
- // the drag gap margin, which caused oscillation / visual jumps.
1148
- if (insertionIndex !== null &&
1149
- this._tabGroupManager.chipRenderers.size > 0) {
1150
- const isGroupDrag = !!this._animState.sourceTabGroupId;
1151
- const tabGroups = this.group.model.getTabGroups();
1152
- // Rebuild the accumulated width up to insertionIndex so we know
1153
- // the original right edge of the chip (if any) that precedes it.
1154
- // We walk exactly the same way as the accumulation loop above.
1155
- let accUpTo = 0;
1156
- for (let i = 0; i < this._tabs.length; i++) {
1157
- const tab = this._tabs[i].value;
1158
- if (tab.panel.id === this._animState.sourceTabId) {
1159
- continue;
1160
- }
1161
- if (sourceGroupPanelIds === null || sourceGroupPanelIds === void 0 ? void 0 : sourceGroupPanelIds.has(tab.panel.id)) {
1162
- continue;
1163
- }
1164
- if (i >= insertionIndex) {
1165
- break;
1166
- }
1167
- const gid = firstPanelToGroup.get(tab.panel.id);
1168
- if (gid) {
1169
- accUpTo += (_b = this._animState.chipPositions.get(gid)) !== null && _b !== void 0 ? _b : 0;
1170
- }
1171
- const origRect = this._animState.tabPositions.get(tab.panel.id);
1172
- accUpTo += origRect
1173
- ? origRect.width
1174
- : tab.element.getBoundingClientRect().width;
1175
- }
1176
- for (const tg of tabGroups) {
1177
- // Build effective panel list: exclude the source tab
1178
- // so that dragging a tab out of its own group doesn't
1179
- // inflate the group's index range.
1180
- const effectivePanelIds = tg.panelIds.filter((pid) => pid !== this._animState.sourceTabId &&
1181
- !(sourceGroupPanelIds === null || sourceGroupPanelIds === void 0 ? void 0 : sourceGroupPanelIds.has(pid)));
1182
- if (effectivePanelIds.length === 0) {
1183
- continue;
1184
- }
1185
- const firstIdx = this._tabs.findIndex((t) => t.value.panel.id === effectivePanelIds[0]);
1186
- const lastIdx = this._tabs.findIndex((t) => t.value.panel.id ===
1187
- effectivePanelIds[effectivePanelIds.length - 1]);
1188
- if (firstIdx === -1 || lastIdx === -1) {
1189
- continue;
1190
- }
1191
- const isInsideRange = insertionIndex >= firstIdx && insertionIndex <= lastIdx;
1192
- const isJustBeforeGroup = !isInsideRange && insertionIndex === firstIdx - 1;
1193
- if (!isInsideRange && !isJustBeforeGroup) {
1194
- continue;
1195
- }
1196
- if (isGroupDrag && isInsideRange) {
1197
- // A group cannot be dropped inside another group.
1198
- // Snap the insertion index to just before or just
1199
- // after this group based on cursor position relative
1200
- // to the group's midpoint. Only applies when the
1201
- // insertion would land *inside* the group — for
1202
- // `isJustBeforeGroup`, the index is already outside
1203
- // (immediately left of the group) and is a valid
1204
- // drop position, so leave it untouched (issue #1264).
1205
- const groupMid = (firstIdx + lastIdx + 1) / 2;
1206
- if (insertionIndex < groupMid) {
1207
- insertionIndex = firstIdx;
1208
- }
1209
- else {
1210
- insertionIndex = lastIdx + 1;
1211
- }
1212
- // targetTabGroupId stays null
1213
- break;
1214
- }
1215
- if (isGroupDrag && isJustBeforeGroup) {
1216
- // Cursor is just before the group — accept this
1217
- // index as-is. Groups can be dropped at the slot
1218
- // immediately left of another group's first tab.
1219
- break;
1220
- }
1221
- if (isJustBeforeGroup) {
1222
- // Check whether only the source tab (or source group
1223
- // tabs) sits between insertionIndex and firstIdx.
1224
- // If so, the source is being dragged away from that
1225
- // slot, so we ARE effectively "just before" the group
1226
- // and should still allow dropping into position 0.
1227
- let allInBetweenAreSource = true;
1228
- for (let j = insertionIndex; j < firstIdx; j++) {
1229
- const pid = this._tabs[j].value.panel.id;
1230
- if (pid !== this._animState.sourceTabId &&
1231
- !(sourceGroupPanelIds === null || sourceGroupPanelIds === void 0 ? void 0 : sourceGroupPanelIds.has(pid))) {
1232
- allInBetweenAreSource = false;
1233
- break;
1234
- }
1235
- }
1236
- if (!allInBetweenAreSource) {
1237
- continue;
1238
- }
1239
- const chipWidth = (_c = this._animState.chipPositions.get(tg.id)) !== null && _c !== void 0 ? _c : 0;
1240
- const threshold = tg.collapsed
1241
- ? this._animState.containerLeft +
1242
- accUpTo +
1243
- chipWidth / 2
1244
- : this._animState.containerLeft + accUpTo + chipWidth;
1245
- if (mouseX >= threshold) {
1246
- insertionIndex = firstIdx;
1247
- targetTabGroupId = tg.id;
1248
- }
1249
- break;
1250
- }
1251
- if (isInsideRange) {
1252
- const chipWidth = (_d = this._animState.chipPositions.get(tg.id)) !== null && _d !== void 0 ? _d : 0;
1253
- const chipOriginalRight = this._animState.containerLeft + accUpTo + chipWidth;
1254
- if (insertionIndex === firstIdx) {
1255
- if (mouseX >= chipOriginalRight) {
1256
- targetTabGroupId = tg.id;
1257
- }
1258
- }
1259
- else {
1260
- targetTabGroupId = tg.id;
1261
- }
1262
- break;
1263
- }
1264
- }
1265
- }
1266
- if (insertionIndex === this._animState.currentInsertionIndex &&
1267
- targetTabGroupId === this._animState.targetTabGroupId) {
1268
- return;
1269
- }
1270
- this._animState.currentInsertionIndex = insertionIndex;
1271
- this._animState.targetTabGroupId = targetTabGroupId;
1272
- if (((_e = this.accessor.options.theme) === null || _e === void 0 ? void 0 : _e.tabAnimation) === 'smooth') {
1273
- this.applyDragOverTransforms();
1274
- }
1275
- }
1276
- /**
1277
- * Batch-remove a CSS class from multiple elements instantly,
1278
- * forcing only a single reflow for the entire batch.
1279
- */
1280
- _removeClassInstantlyBatch(elements, cls) {
1281
- const affected = [];
1282
- for (const el of elements) {
1283
- if (el.classList.contains(cls)) {
1284
- el.style.transition = 'none';
1285
- toggleClass(el, cls, false);
1286
- affected.push(el);
1287
- }
1288
- }
1289
- if (affected.length > 0) {
1290
- void affected[0].offsetHeight; // single reflow for entire batch
1291
- for (const el of affected) {
1292
- el.style.removeProperty('transition');
1293
- }
1294
- }
1295
- }
1296
- /**
1297
- * Remove `dv-tab--dragging` from the source tab instantly so it
1298
- * regains its real width before FLIP snapshots.
1299
- */
1300
- _uncollapsSourceTab(sourceTabId) {
1301
- const entry = this._tabMap.get(sourceTabId);
1302
- if (entry) {
1303
- this._removeClassInstantlyBatch([entry.value.element], 'dv-tab--dragging');
1304
- }
1305
- }
1306
- applyDragOverTransforms(skipTransition = false) {
1307
- if (!this._animState ||
1308
- this._animState.currentInsertionIndex === null) {
1309
- this.resetTabTransforms();
1310
- return;
1311
- }
1312
- // Don't apply transforms until the source tab has been collapsed
1313
- // in the rAF callback — otherwise the gap + visible source = jump.
1314
- if (this._pendingCollapse) {
1315
- return;
1316
- }
1317
- const insertionIndex = this._animState.currentInsertionIndex;
1318
- // For group drags, gap = sum of all group member widths
1319
- let gapWidth;
1320
- const sourceGroupPanelIds = this._animState.sourceGroupPanelIds;
1321
- if (this._animState.sourceTabGroupId && sourceGroupPanelIds) {
1322
- gapWidth = this._animState.sourceGapWidth;
1323
- }
1324
- else {
1325
- const sourceRect = this._animState.tabPositions.get(this._animState.sourceTabId);
1326
- gapWidth = sourceRect
1327
- ? sourceRect.width
1328
- : this.getAverageTabWidth();
1329
- }
1330
- // When the insertion lands at or before a group's first tab, shift
1331
- // the chip so the gap appears before the entire group.
1332
- //
1333
- // Two cases:
1334
- // 1. targetTabGroupId is null (standalone drop) — always shift chip.
1335
- // 2. targetTabGroupId is set AND the group is collapsed — shift chip
1336
- // because the collapsed tabs are invisible, so putting the gap on
1337
- // them has no visual effect.
1338
- let chipToShift = null;
1339
- if (this._tabGroupManager.chipRenderers.size > 0) {
1340
- const tabGroups = this.group.model.getTabGroups();
1341
- for (const tg of tabGroups) {
1342
- if (tg.id === this._animState.sourceTabGroupId)
1343
- continue;
1344
- // Skip the group that the dragged tab belongs to — the
1345
- // gap should appear after the chip (where the tab was),
1346
- // not before it.
1347
- if (tg.panelIds.includes(this._animState.sourceTabId))
1348
- continue;
1349
- const effectivePids = tg.panelIds.filter((pid) => pid !== this._animState.sourceTabId &&
1350
- !(sourceGroupPanelIds === null || sourceGroupPanelIds === void 0 ? void 0 : sourceGroupPanelIds.has(pid)));
1351
- if (effectivePids.length === 0)
1352
- continue;
1353
- const firstIdx = this._tabs.findIndex((t) => t.value.panel.id === effectivePids[0]);
1354
- // Only consider chip-shifting when dropping outside the
1355
- // group, or when dropping inside a collapsed group (whose
1356
- // tabs are invisible).
1357
- const shouldShiftChip = !this._animState.targetTabGroupId ||
1358
- (this._animState.targetTabGroupId === tg.id &&
1359
- tg.collapsed);
1360
- if (!shouldShiftChip)
1361
- continue;
1362
- if (firstIdx >= insertionIndex) {
1363
- let hasTabs = false;
1364
- for (let j = insertionIndex; j < firstIdx; j++) {
1365
- const pid = this._tabs[j].value.panel.id;
1366
- if (pid === this._animState.sourceTabId)
1367
- continue;
1368
- if (sourceGroupPanelIds === null || sourceGroupPanelIds === void 0 ? void 0 : sourceGroupPanelIds.has(pid))
1369
- continue;
1370
- hasTabs = true;
1371
- break;
1372
- }
1373
- if (!hasTabs) {
1374
- const chipEntry = this._tabGroupManager.chipRenderers.get(tg.id);
1375
- if (chipEntry) {
1376
- chipToShift = chipEntry.chip.element;
1377
- }
1378
- }
1379
- break;
1380
- }
1381
- }
1382
- }
1383
- // Helper: pick the correct shifting class for tabs vs chips.
1384
- const shiftingClass = (el) => el.classList.contains('dv-tab-group-chip')
1385
- ? 'dv-tab-group-chip--shifting'
1386
- : 'dv-tab--shifting';
1387
- // Helper: apply a margin-left value to an element, optionally
1388
- // bypassing CSS transitions for instant positioning.
1389
- const setMargin = (el, value) => {
1390
- if (skipTransition) {
1391
- el.style.transition = 'none';
1392
- el.style.marginLeft = value;
1393
- void el.offsetHeight;
1394
- el.style.removeProperty('transition');
1395
- }
1396
- else {
1397
- el.style.marginLeft = value;
1398
- }
1399
- toggleClass(el, shiftingClass(el), true);
1400
- };
1401
- const clearMargin = (el) => {
1402
- const cls = shiftingClass(el);
1403
- // Remove any previous pending listener for this element
1404
- const prev = this._pendingMarginCleanups.get(el);
1405
- if (prev) {
1406
- prev();
1407
- }
1408
- if (skipTransition || !el.style.marginLeft) {
1409
- el.style.removeProperty('margin-left');
1410
- toggleClass(el, cls, false);
1411
- }
1412
- else {
1413
- el.style.marginLeft = '0px';
1414
- toggleClass(el, cls, true);
1415
- const onEnd = () => {
1416
- el.style.removeProperty('margin-left');
1417
- toggleClass(el, cls, false);
1418
- el.removeEventListener('transitionend', onEnd);
1419
- clearTimeout(fallbackTimer);
1420
- this._pendingMarginCleanups.delete(el);
1421
- };
1422
- // Fallback in case transitionend never fires
1423
- // (e.g. element removed from DOM mid-transition)
1424
- const fallbackTimer = setTimeout(onEnd, 300);
1425
- this._pendingMarginCleanups.set(el, onEnd);
1426
- el.addEventListener('transitionend', onEnd);
1427
- }
1428
- };
1429
- let gapApplied = false;
1430
- // Reset all non-source chip margins first
1431
- for (const [groupId, entry] of this._tabGroupManager.chipRenderers) {
1432
- if (groupId === this._animState.sourceTabGroupId)
1433
- continue;
1434
- clearMargin(entry.chip.element);
1435
- }
1436
- // Apply gap to chip if insertion is before a group
1437
- if (chipToShift) {
1438
- setMargin(chipToShift, `${gapWidth}px`);
1439
- gapApplied = true;
1440
- }
1441
- for (let i = 0; i < this._tabs.length; i++) {
1442
- const tab = this._tabs[i].value;
1443
- if (tab.panel.id === this._animState.sourceTabId) {
1444
- continue;
1445
- }
1446
- if (sourceGroupPanelIds === null || sourceGroupPanelIds === void 0 ? void 0 : sourceGroupPanelIds.has(tab.panel.id)) {
1447
- continue;
1448
- }
1449
- if (!gapApplied && i >= insertionIndex) {
1450
- setMargin(tab.element, `${gapWidth}px`);
1451
- gapApplied = true;
1452
- }
1453
- else {
1454
- clearMargin(tab.element);
1455
- }
1456
- }
1457
- // Reposition underlines to follow shifted chips/tabs
1458
- this._tabGroupManager.trackUnderlines();
1459
- }
1460
- resetTabTransforms() {
1461
- // Cancel any pending margin transitionend listeners
1462
- for (const [, cleanup] of this._pendingMarginCleanups) {
1463
- cleanup();
1464
- }
1465
- this._pendingMarginCleanups.clear();
1466
- for (const tab of this._tabs) {
1467
- tab.value.element.style.removeProperty('margin-left');
1468
- tab.value.element.style.removeProperty('margin-right');
1469
- tab.value.element.style.removeProperty('margin-top');
1470
- tab.value.element.style.removeProperty('margin-bottom');
1471
- tab.value.element.style.removeProperty('transform');
1472
- toggleClass(tab.value.element, 'dv-tab--shifting', false);
1473
- }
1474
- for (const [, entry] of this._tabGroupManager.chipRenderers) {
1475
- entry.chip.element.style.removeProperty('margin-left');
1476
- toggleClass(entry.chip.element, 'dv-tab-group-chip--shifting', false);
1477
- }
1478
- this._tabGroupManager.positionUnderlines();
1479
- }
1480
- /**
1481
- * Commit a group-drag drop: clear drag classes, move the group
1482
- * in the model, and run a FLIP animation.
1483
- */
1484
- _commitGroupMove(sourceTabGroupId, insertionIndex) {
1485
- var _a, _b;
1486
- // Read transfer data first.
1487
- const data = getPanelData();
1488
- // Synchronously dispose the source chip's drag sources, which
1489
- // clears the panelTransfer payload + iframe shield. Cross-group
1490
- // moves dissolve the source chip on a microtask, which is too
1491
- // late: a synchronous `getPanelData()` after this method (or any
1492
- // sibling dragover handler firing in the same tick) would
1493
- // otherwise see stale data still referencing the old tabGroupId.
1494
- this._tabGroupManager.disposeChipDrag(sourceTabGroupId);
1495
- // Check if the tab group exists in this group (within-group reorder)
1496
- // or in another group (cross-group move).
1497
- const isLocal = this.group.model
1498
- .getTabGroups()
1499
- .some((tg) => tg.id === sourceTabGroupId);
1500
- if (isLocal) {
1501
- if (((_a = this.accessor.options.theme) === null || _a === void 0 ? void 0 : _a.tabAnimation) === 'smooth') {
1502
- this._clearGroupDragClasses(sourceTabGroupId);
1503
- const firstPositions = this.snapshotTabPositions();
1504
- this.resetTabTransforms();
1505
- this.group.model.moveTabGroup(sourceTabGroupId, insertionIndex);
1506
- this.runFlipAnimation(firstPositions, '', false);
1507
- }
1508
- else {
1509
- this._tabGroupManager.skipNextCollapseAnimation = true;
1510
- this.group.model.moveTabGroup(sourceTabGroupId, insertionIndex);
1511
- }
1512
- }
1513
- else if (data) {
1514
- // Cross-group: delegate to the component-level move which
1515
- // handles panel transfer and tab group recreation.
1516
- // Use the REAL tab group ID from transfer data, not the
1517
- // potentially stale one from _animState.
1518
- //
1519
- // Clear any inline gap margin / shifting class applied to
1520
- // destination tabs during dragover. Cross-group moves don't
1521
- // run the FLIP path, and `moveGroupOrPanel` only inserts new
1522
- // panels — it doesn't recreate existing destination tabs, so
1523
- // their inline `margin-left` would otherwise persist as a
1524
- // visible gap (issue #1243).
1525
- this.resetTabTransforms();
1526
- this.accessor.moveGroupOrPanel({
1527
- from: {
1528
- groupId: data.groupId,
1529
- tabGroupId: (_b = data.tabGroupId) !== null && _b !== void 0 ? _b : sourceTabGroupId,
1530
- },
1531
- to: {
1532
- group: this.group,
1533
- position: 'center',
1534
- index: insertionIndex,
1535
- },
1536
- });
1537
- }
1538
- }
1539
- _clearGroupDragClasses(sourceTabGroupId) {
1540
- const chipEntry = this._tabGroupManager.chipRenderers.get(sourceTabGroupId);
1541
- if (chipEntry) {
1542
- this._removeClassInstantlyBatch([chipEntry.chip.element], 'dv-tab-group-chip--dragging');
1543
- }
1544
- this._removeClassInstantlyBatch(this._tabs.map((t) => t.value.element), 'dv-tab--dragging');
1545
- // Restore underline
1546
- const underline = this._tabGroupManager.groupUnderlines.get(sourceTabGroupId);
1547
- if (underline) {
1548
- underline.style.removeProperty('display');
1549
- }
1550
- // The subsequent moveTabGroup will re-create tabs and call
1551
- // updateTabGroups → _updateTabGroupClasses. For collapsed groups
1552
- // the new tabs don't have dv-tab--group-collapsed yet, which
1553
- // would trigger the collapse animation. Skip it.
1554
- this._tabGroupManager.skipNextCollapseAnimation = true;
1555
- }
1556
- resetDragAnimation() {
1557
- this._pendingCollapse = false;
1558
- // After a drop, `tab.onDrop` consumes _animState (sets it to null)
1559
- // and immediately calls `runFlipAnimation`, which sets transforms
1560
- // and queues an rAF to trigger the CSS transition. dragend fires
1561
- // synchronously on the source element BEFORE that rAF runs — if
1562
- // we cleared transforms here we'd clobber the in-flight FLIP, so
1563
- // gate the cleanup on _animState still being set (i.e. drag was
1564
- // cancelled rather than dropped).
1565
- if (this._animState) {
1566
- this.resetTabTransforms();
1567
- if (this._animState.sourceTabGroupId) {
1568
- this._clearGroupDragClasses(this._animState.sourceTabGroupId);
1569
- }
1570
- else {
1571
- this._removeClassInstantlyBatch(this._tabs.map((t) => t.value.element), 'dv-tab--dragging');
1572
- }
1573
- this._animState = null;
1574
- // Restore any hidden underlines from group drags.
1575
- for (const [, el] of this._tabGroupManager.groupUnderlines) {
1576
- el.style.removeProperty('display');
1577
- }
1578
- }
1579
- }
1580
- runFlipAnimation(firstPositions, sourceTabId, isCrossGroup = false, animRange) {
1581
- const isVertical = this._direction === 'vertical';
1582
- let hasAnimation = false;
1583
- for (let i = 0; i < this._tabs.length; i++) {
1584
- const tab = this._tabs[i];
1585
- const panelId = tab.value.panel.id;
1586
- if (panelId === sourceTabId) {
1587
- if (isCrossGroup) {
1588
- // Newly inserted tab: slide in from the end
1589
- const rect = tab.value.element.getBoundingClientRect();
1590
- tab.value.element.style.transform = isVertical
1591
- ? `translateY(${rect.height}px)`
1592
- : `translateX(${rect.width}px)`;
1593
- toggleClass(tab.value.element, 'dv-tab--shifting', true);
1594
- hasAnimation = true;
1595
- }
1596
- continue;
1597
- }
1598
- // Skip tabs outside the affected range (they don't logically move)
1599
- if (animRange !== undefined &&
1600
- (i < animRange.from || i > animRange.to)) {
1601
- continue;
1602
- }
1603
- const firstRect = firstPositions.get(panelId);
1604
- if (!firstRect) {
1605
- continue;
1606
- }
1607
- const lastRect = tab.value.element.getBoundingClientRect();
1608
- const delta = isVertical
1609
- ? firstRect.top - lastRect.top
1610
- : firstRect.left - lastRect.left;
1611
- if (Math.abs(delta) < 1) {
1612
- continue;
1613
- }
1614
- tab.value.element.style.transform = isVertical
1615
- ? `translateY(${delta}px)`
1616
- : `translateX(${delta}px)`;
1617
- toggleClass(tab.value.element, 'dv-tab--shifting', true);
1618
- hasAnimation = true;
1619
- }
1620
- if (!hasAnimation) {
1621
- return;
1622
- }
1623
- requestAnimationFrame(() => {
1624
- var _a;
1625
- for (const tab of this._tabs) {
1626
- if (tab.value.element.style.transform) {
1627
- tab.value.element.style.transform = '';
1628
- }
1629
- }
1630
- // Track underlines during the FLIP transition so they
1631
- // follow tabs as they slide to their final positions.
1632
- this._tabGroupManager.trackUnderlines();
1633
- // Clean up any previous flip transition listener
1634
- (_a = this._flipTransitionCleanup) === null || _a === void 0 ? void 0 : _a.call(this);
1635
- const onTransitionEnd = (event) => {
1636
- if (event.propertyName === 'transform') {
1637
- cleanup();
1638
- for (const tab of this._tabs) {
1639
- toggleClass(tab.value.element, 'dv-tab--shifting', false);
1640
- }
1641
- // Final reposition after animation settles
1642
- this._tabGroupManager.positionUnderlines();
1643
- }
1644
- };
1645
- const cleanup = () => {
1646
- this._tabsList.removeEventListener('transitionend', onTransitionEnd);
1647
- this._flipTransitionCleanup = null;
1648
- };
1649
- this._flipTransitionCleanup = cleanup;
1650
- this._tabsList.addEventListener('transitionend', onTransitionEnd);
1651
- });
1652
- }
1653
- }