dockview-core 7.0.3 → 8.0.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 (374) 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/dropTargetAnchorContainer.d.ts +12 -0
  9. package/dist/cjs/dnd/droptarget.d.ts +94 -0
  10. package/dist/cjs/dnd/ghost.d.ts +1 -0
  11. package/dist/cjs/dnd/pointer/longPress.d.ts +2 -2
  12. package/dist/cjs/dnd/pointer/pointerDragController.d.ts +5 -2
  13. package/dist/cjs/dnd/pointer/pointerDragSource.d.ts +1 -1
  14. package/dist/cjs/dnd/pointer/pointerDropTarget.d.ts +30 -1
  15. package/dist/cjs/dnd/pointer/pointerGhost.d.ts +1 -1
  16. package/dist/cjs/dockview/accessibilityMessages.d.ts +6 -0
  17. package/dist/cjs/dockview/advancedDnDService.d.ts +46 -0
  18. package/dist/cjs/dockview/components/panel/content.d.ts +1 -1
  19. package/dist/cjs/dockview/components/tab/defaultTab.d.ts +2 -0
  20. package/dist/cjs/dockview/components/tab/tab.d.ts +2 -0
  21. package/dist/cjs/dockview/components/titlebar/floatingTitleBar.d.ts +2 -2
  22. package/dist/cjs/dockview/components/titlebar/groupDragSource.d.ts +1 -1
  23. package/dist/cjs/dockview/components/titlebar/tabGroupChip.d.ts +1 -1
  24. package/dist/cjs/dockview/components/titlebar/tabGroupIndicator.d.ts +73 -2
  25. package/dist/cjs/dockview/components/titlebar/tabGroups.d.ts +1 -1
  26. package/dist/cjs/dockview/components/titlebar/tabReorderController.d.ts +295 -0
  27. package/dist/cjs/dockview/components/titlebar/tabs.d.ts +120 -50
  28. package/dist/cjs/dockview/components/titlebar/tabsContainer.d.ts +48 -0
  29. package/dist/cjs/dockview/dndCapabilities.d.ts +1 -1
  30. package/dist/cjs/dockview/dockviewComponent.d.ts +303 -19
  31. package/dist/cjs/dockview/dockviewGroupPanel.d.ts +5 -0
  32. package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +52 -2
  33. package/dist/cjs/dockview/dockviewPanel.d.ts +12 -0
  34. package/dist/cjs/dockview/dockviewShell.d.ts +48 -24
  35. package/dist/cjs/dockview/edgeGroupService.d.ts +20 -0
  36. package/dist/cjs/dockview/events.d.ts +6 -0
  37. package/dist/cjs/dockview/liveRegionService.d.ts +18 -5
  38. package/dist/cjs/dockview/moduleContracts.d.ts +480 -14
  39. package/dist/cjs/dockview/modules.d.ts +101 -22
  40. package/dist/cjs/dockview/options.d.ts +337 -30
  41. package/dist/cjs/dockview/optionsModules.d.ts +73 -0
  42. package/dist/cjs/dockview/popoutWindowService.d.ts +15 -10
  43. package/dist/cjs/dockview/rootDropTargetService.d.ts +11 -0
  44. package/dist/cjs/dockview/tabGroupAccent.d.ts +1 -1
  45. package/dist/cjs/dockview/tabGroupChipsService.d.ts +10 -0
  46. package/dist/cjs/dockview/theme.d.ts +2 -2
  47. package/dist/cjs/dockview/types.d.ts +3 -0
  48. package/dist/cjs/dom.d.ts +9 -1
  49. package/dist/cjs/gridview/baseComponentGridview.d.ts +2 -2
  50. package/dist/cjs/gridview/gridview.d.ts +2 -0
  51. package/dist/cjs/index.d.ts +35 -29
  52. package/dist/cjs/lifecycle.d.ts +1 -0
  53. package/dist/cjs/overlay/overlay.d.ts +4 -2
  54. package/dist/cjs/overlay/overlayRenderContainer.d.ts +8 -0
  55. package/dist/cjs/paneview/paneview.d.ts +2 -1
  56. package/dist/cjs/paneview/paneviewComponent.d.ts +3 -0
  57. package/dist/cjs/paneview/paneviewPanel.d.ts +5 -0
  58. package/dist/cjs/svg.d.ts +1 -0
  59. package/dist/cjs/types.d.ts +8 -0
  60. package/dist/dockview-core.js +18391 -19679
  61. package/dist/dockview-core.min.js +4138 -6
  62. package/dist/dockview-core.min.noStyle.js +6 -7
  63. package/dist/dockview-core.noStyle.js +18390 -19656
  64. package/dist/package/main.cjs.js +18002 -19268
  65. package/dist/package/main.cjs.min.js +6 -6
  66. package/dist/package/main.esm.min.mjs +6 -6
  67. package/dist/package/main.esm.mjs +17959 -19260
  68. package/package.json +81 -77
  69. package/dist/cjs/api/component.api.js +0 -1242
  70. package/dist/cjs/api/dockviewGroupPanelApi.js +0 -200
  71. package/dist/cjs/api/dockviewPanelApi.js +0 -172
  72. package/dist/cjs/api/entryPoints.js +0 -27
  73. package/dist/cjs/api/gridviewPanelApi.js +0 -45
  74. package/dist/cjs/api/panelApi.js +0 -133
  75. package/dist/cjs/api/paneviewPanelApi.js +0 -57
  76. package/dist/cjs/api/splitviewPanelApi.js +0 -47
  77. package/dist/cjs/array.js +0 -66
  78. package/dist/cjs/constants.js +0 -11
  79. package/dist/cjs/dnd/backend.js +0 -171
  80. package/dist/cjs/dnd/dataTransfer.js +0 -100
  81. package/dist/cjs/dnd/dnd.js +0 -74
  82. package/dist/cjs/dnd/dropOverlay.js +0 -197
  83. package/dist/cjs/dnd/dropTargetAnchorContainer.js +0 -104
  84. package/dist/cjs/dnd/droptarget.js +0 -362
  85. package/dist/cjs/dnd/ghost.js +0 -17
  86. package/dist/cjs/dnd/pointer/index.js +0 -13
  87. package/dist/cjs/dnd/pointer/longPress.js +0 -151
  88. package/dist/cjs/dnd/pointer/pointerDragController.js +0 -243
  89. package/dist/cjs/dnd/pointer/pointerDragSource.js +0 -197
  90. package/dist/cjs/dnd/pointer/pointerDropTarget.js +0 -198
  91. package/dist/cjs/dnd/pointer/pointerGhost.js +0 -44
  92. package/dist/cjs/dnd/pointer/types.js +0 -2
  93. package/dist/cjs/dockview/accessibilityMessages.js +0 -51
  94. package/dist/cjs/dockview/allModules.js +0 -25
  95. package/dist/cjs/dockview/components/panel/content.js +0 -213
  96. package/dist/cjs/dockview/components/popupService.js +0 -132
  97. package/dist/cjs/dockview/components/tab/defaultTab.js +0 -70
  98. package/dist/cjs/dockview/components/tab/tab.js +0 -281
  99. package/dist/cjs/dockview/components/titlebar/floatingTitleBar.js +0 -95
  100. package/dist/cjs/dockview/components/titlebar/groupDragSource.js +0 -218
  101. package/dist/cjs/dockview/components/titlebar/tabGroupChip.js +0 -104
  102. package/dist/cjs/dockview/components/titlebar/tabGroupIndicator.js +0 -477
  103. package/dist/cjs/dockview/components/titlebar/tabGroups.js +0 -854
  104. package/dist/cjs/dockview/components/titlebar/tabOverflowControl.js +0 -19
  105. package/dist/cjs/dockview/components/titlebar/tabs.js +0 -2016
  106. package/dist/cjs/dockview/components/titlebar/tabsContainer.js +0 -458
  107. package/dist/cjs/dockview/components/titlebar/voidContainer.js +0 -120
  108. package/dist/cjs/dockview/components/watermark/watermark.js +0 -40
  109. package/dist/cjs/dockview/deserializer.js +0 -39
  110. package/dist/cjs/dockview/dndCapabilities.js +0 -39
  111. package/dist/cjs/dockview/dockviewComponent.js +0 -3896
  112. package/dist/cjs/dockview/dockviewFloatingGroupPanel.js +0 -70
  113. package/dist/cjs/dockview/dockviewGroupPanel.js +0 -204
  114. package/dist/cjs/dockview/dockviewGroupPanelModel.js +0 -1514
  115. package/dist/cjs/dockview/dockviewPanel.js +0 -265
  116. package/dist/cjs/dockview/dockviewPanelModel.js +0 -105
  117. package/dist/cjs/dockview/dockviewShell.js +0 -744
  118. package/dist/cjs/dockview/edgeGroupService.js +0 -128
  119. package/dist/cjs/dockview/events.js +0 -67
  120. package/dist/cjs/dockview/floatingGroupService.js +0 -231
  121. package/dist/cjs/dockview/framework.js +0 -2
  122. package/dist/cjs/dockview/headerActionsService.js +0 -149
  123. package/dist/cjs/dockview/liveRegionService.js +0 -185
  124. package/dist/cjs/dockview/moduleContracts.js +0 -2
  125. package/dist/cjs/dockview/modules.js +0 -304
  126. package/dist/cjs/dockview/options.js +0 -103
  127. package/dist/cjs/dockview/popoutWindowService.js +0 -261
  128. package/dist/cjs/dockview/rootDropTargetService.js +0 -87
  129. package/dist/cjs/dockview/strictEventsSequencing.js +0 -63
  130. package/dist/cjs/dockview/tabGroup.js +0 -219
  131. package/dist/cjs/dockview/tabGroupAccent.js +0 -126
  132. package/dist/cjs/dockview/theme.js +0 -139
  133. package/dist/cjs/dockview/types.js +0 -2
  134. package/dist/cjs/dockview/validate.js +0 -76
  135. package/dist/cjs/dockview/watermarkService.js +0 -61
  136. package/dist/cjs/dom.js +0 -543
  137. package/dist/cjs/events.js +0 -296
  138. package/dist/cjs/framwork.js +0 -2
  139. package/dist/cjs/gridview/baseComponentGridview.js +0 -330
  140. package/dist/cjs/gridview/basePanelView.js +0 -162
  141. package/dist/cjs/gridview/branchNode.js +0 -372
  142. package/dist/cjs/gridview/gridview.js +0 -776
  143. package/dist/cjs/gridview/gridviewComponent.js +0 -363
  144. package/dist/cjs/gridview/gridviewPanel.js +0 -249
  145. package/dist/cjs/gridview/leafNode.js +0 -169
  146. package/dist/cjs/gridview/options.js +0 -17
  147. package/dist/cjs/gridview/types.js +0 -2
  148. package/dist/cjs/index.js +0 -105
  149. package/dist/cjs/lifecycle.js +0 -80
  150. package/dist/cjs/math.js +0 -38
  151. package/dist/cjs/overlay/overlay.js +0 -602
  152. package/dist/cjs/overlay/overlayRenderContainer.js +0 -309
  153. package/dist/cjs/panel/types.js +0 -2
  154. package/dist/cjs/paneview/defaultPaneviewHeader.js +0 -92
  155. package/dist/cjs/paneview/draggablePaneviewPanel.js +0 -141
  156. package/dist/cjs/paneview/options.js +0 -44
  157. package/dist/cjs/paneview/paneview.js +0 -203
  158. package/dist/cjs/paneview/paneviewComponent.js +0 -430
  159. package/dist/cjs/paneview/paneviewPanel.js +0 -275
  160. package/dist/cjs/popoutWindow.js +0 -244
  161. package/dist/cjs/resizable.js +0 -97
  162. package/dist/cjs/scrollbar.js +0 -169
  163. package/dist/cjs/splitview/options.js +0 -19
  164. package/dist/cjs/splitview/splitview.js +0 -999
  165. package/dist/cjs/splitview/splitviewComponent.js +0 -401
  166. package/dist/cjs/splitview/splitviewPanel.js +0 -179
  167. package/dist/cjs/splitview/viewItem.js +0 -119
  168. package/dist/cjs/svg.js +0 -43
  169. package/dist/cjs/types.js +0 -2
  170. package/dist/dockview-core.min.js.map +0 -1
  171. package/dist/dockview-core.min.noStyle.js.map +0 -1
  172. package/dist/esm/api/component.api.d.ts +0 -640
  173. package/dist/esm/api/component.api.js +0 -887
  174. package/dist/esm/api/dockviewGroupPanelApi.d.ts +0 -109
  175. package/dist/esm/api/dockviewGroupPanelApi.js +0 -155
  176. package/dist/esm/api/dockviewPanelApi.d.ts +0 -84
  177. package/dist/esm/api/dockviewPanelApi.js +0 -124
  178. package/dist/esm/api/entryPoints.d.ts +0 -9
  179. package/dist/esm/api/entryPoints.js +0 -21
  180. package/dist/esm/api/gridviewPanelApi.d.ts +0 -37
  181. package/dist/esm/api/gridviewPanelApi.js +0 -23
  182. package/dist/esm/api/panelApi.d.ts +0 -100
  183. package/dist/esm/api/panelApi.js +0 -87
  184. package/dist/esm/api/paneviewPanelApi.d.ts +0 -26
  185. package/dist/esm/api/paneviewPanelApi.js +0 -27
  186. package/dist/esm/api/splitviewPanelApi.d.ts +0 -32
  187. package/dist/esm/api/splitviewPanelApi.js +0 -25
  188. package/dist/esm/array.d.ts +0 -13
  189. package/dist/esm/array.js +0 -57
  190. package/dist/esm/constants.d.ts +0 -8
  191. package/dist/esm/constants.js +0 -8
  192. package/dist/esm/dnd/backend.d.ts +0 -70
  193. package/dist/esm/dnd/backend.js +0 -148
  194. package/dist/esm/dnd/dataTransfer.d.ts +0 -31
  195. package/dist/esm/dnd/dataTransfer.js +0 -67
  196. package/dist/esm/dnd/dnd.d.ts +0 -32
  197. package/dist/esm/dnd/dnd.js +0 -51
  198. package/dist/esm/dnd/dropOverlay.d.ts +0 -20
  199. package/dist/esm/dnd/dropOverlay.js +0 -192
  200. package/dist/esm/dnd/dropTargetAnchorContainer.d.ts +0 -16
  201. package/dist/esm/dnd/dropTargetAnchorContainer.js +0 -73
  202. package/dist/esm/dnd/droptarget.d.ts +0 -116
  203. package/dist/esm/dnd/droptarget.js +0 -316
  204. package/dist/esm/dnd/ghost.d.ts +0 -4
  205. package/dist/esm/dnd/ghost.js +0 -14
  206. package/dist/esm/dnd/pointer/index.d.ts +0 -11
  207. package/dist/esm/dnd/pointer/index.js +0 -5
  208. package/dist/esm/dnd/pointer/longPress.d.ts +0 -32
  209. package/dist/esm/dnd/pointer/longPress.js +0 -127
  210. package/dist/esm/dnd/pointer/pointerDragController.d.ts +0 -60
  211. package/dist/esm/dnd/pointer/pointerDragController.js +0 -193
  212. package/dist/esm/dnd/pointer/pointerDragSource.d.ts +0 -61
  213. package/dist/esm/dnd/pointer/pointerDragSource.js +0 -173
  214. package/dist/esm/dnd/pointer/pointerDropTarget.d.ts +0 -39
  215. package/dist/esm/dnd/pointer/pointerDropTarget.js +0 -168
  216. package/dist/esm/dnd/pointer/pointerGhost.d.ts +0 -30
  217. package/dist/esm/dnd/pointer/pointerGhost.js +0 -39
  218. package/dist/esm/dnd/pointer/types.d.ts +0 -16
  219. package/dist/esm/dnd/pointer/types.js +0 -1
  220. package/dist/esm/dockview/accessibilityMessages.d.ts +0 -32
  221. package/dist/esm/dockview/accessibilityMessages.js +0 -30
  222. package/dist/esm/dockview/allModules.d.ts +0 -8
  223. package/dist/esm/dockview/allModules.js +0 -22
  224. package/dist/esm/dockview/components/panel/content.d.ts +0 -54
  225. package/dist/esm/dockview/components/panel/content.js +0 -185
  226. package/dist/esm/dockview/components/popupService.d.ts +0 -21
  227. package/dist/esm/dockview/components/popupService.js +0 -108
  228. package/dist/esm/dockview/components/tab/defaultTab.d.ts +0 -12
  229. package/dist/esm/dockview/components/tab/defaultTab.js +0 -43
  230. package/dist/esm/dockview/components/tab/tab.d.ts +0 -44
  231. package/dist/esm/dockview/components/tab/tab.js +0 -242
  232. package/dist/esm/dockview/components/titlebar/floatingTitleBar.d.ts +0 -34
  233. package/dist/esm/dockview/components/titlebar/floatingTitleBar.js +0 -65
  234. package/dist/esm/dockview/components/titlebar/groupDragSource.d.ts +0 -51
  235. package/dist/esm/dockview/components/titlebar/groupDragSource.js +0 -178
  236. package/dist/esm/dockview/components/titlebar/tabGroupChip.d.ts +0 -37
  237. package/dist/esm/dockview/components/titlebar/tabGroupChip.js +0 -77
  238. package/dist/esm/dockview/components/titlebar/tabGroupIndicator.d.ts +0 -72
  239. package/dist/esm/dockview/components/titlebar/tabGroupIndicator.js +0 -360
  240. package/dist/esm/dockview/components/titlebar/tabGroups.d.ts +0 -107
  241. package/dist/esm/dockview/components/titlebar/tabGroups.js +0 -621
  242. package/dist/esm/dockview/components/titlebar/tabOverflowControl.d.ts +0 -8
  243. package/dist/esm/dockview/components/titlebar/tabOverflowControl.js +0 -16
  244. package/dist/esm/dockview/components/titlebar/tabs.d.ts +0 -167
  245. package/dist/esm/dockview/components/titlebar/tabs.js +0 -1653
  246. package/dist/esm/dockview/components/titlebar/tabsContainer.d.ts +0 -104
  247. package/dist/esm/dockview/components/titlebar/tabsContainer.js +0 -359
  248. package/dist/esm/dockview/components/titlebar/voidContainer.d.ts +0 -21
  249. package/dist/esm/dockview/components/titlebar/voidContainer.js +0 -92
  250. package/dist/esm/dockview/components/watermark/watermark.d.ts +0 -8
  251. package/dist/esm/dockview/components/watermark/watermark.js +0 -14
  252. package/dist/esm/dockview/deserializer.d.ts +0 -12
  253. package/dist/esm/dockview/deserializer.js +0 -34
  254. package/dist/esm/dockview/dndCapabilities.d.ts +0 -19
  255. package/dist/esm/dockview/dndCapabilities.js +0 -36
  256. package/dist/esm/dockview/dockviewComponent.d.ts +0 -626
  257. package/dist/esm/dockview/dockviewComponent.js +0 -3214
  258. package/dist/esm/dockview/dockviewFloatingGroupPanel.d.ts +0 -45
  259. package/dist/esm/dockview/dockviewFloatingGroupPanel.js +0 -44
  260. package/dist/esm/dockview/dockviewGroupPanel.d.ts +0 -35
  261. package/dist/esm/dockview/dockviewGroupPanel.js +0 -142
  262. package/dist/esm/dockview/dockviewGroupPanelModel.d.ts +0 -358
  263. package/dist/esm/dockview/dockviewGroupPanelModel.js +0 -1180
  264. package/dist/esm/dockview/dockviewPanel.d.ts +0 -69
  265. package/dist/esm/dockview/dockviewPanel.js +0 -178
  266. package/dist/esm/dockview/dockviewPanelModel.d.ts +0 -37
  267. package/dist/esm/dockview/dockviewPanelModel.js +0 -81
  268. package/dist/esm/dockview/dockviewShell.d.ts +0 -150
  269. package/dist/esm/dockview/dockviewShell.js +0 -678
  270. package/dist/esm/dockview/edgeGroupService.d.ts +0 -38
  271. package/dist/esm/dockview/edgeGroupService.js +0 -63
  272. package/dist/esm/dockview/events.d.ts +0 -38
  273. package/dist/esm/dockview/events.js +0 -34
  274. package/dist/esm/dockview/floatingGroupService.d.ts +0 -37
  275. package/dist/esm/dockview/floatingGroupService.js +0 -150
  276. package/dist/esm/dockview/framework.d.ts +0 -65
  277. package/dist/esm/dockview/framework.js +0 -1
  278. package/dist/esm/dockview/headerActionsService.d.ts +0 -32
  279. package/dist/esm/dockview/headerActionsService.js +0 -86
  280. package/dist/esm/dockview/liveRegionService.d.ts +0 -53
  281. package/dist/esm/dockview/liveRegionService.js +0 -159
  282. package/dist/esm/dockview/moduleContracts.d.ts +0 -119
  283. package/dist/esm/dockview/moduleContracts.js +0 -1
  284. package/dist/esm/dockview/modules.d.ts +0 -110
  285. package/dist/esm/dockview/modules.js +0 -170
  286. package/dist/esm/dockview/options.d.ts +0 -474
  287. package/dist/esm/dockview/options.js +0 -77
  288. package/dist/esm/dockview/popoutWindowService.d.ts +0 -95
  289. package/dist/esm/dockview/popoutWindowService.js +0 -175
  290. package/dist/esm/dockview/rootDropTargetService.d.ts +0 -35
  291. package/dist/esm/dockview/rootDropTargetService.js +0 -82
  292. package/dist/esm/dockview/strictEventsSequencing.d.ts +0 -7
  293. package/dist/esm/dockview/strictEventsSequencing.js +0 -41
  294. package/dist/esm/dockview/tabGroup.d.ts +0 -99
  295. package/dist/esm/dockview/tabGroup.js +0 -144
  296. package/dist/esm/dockview/tabGroupAccent.d.ts +0 -65
  297. package/dist/esm/dockview/tabGroupAccent.js +0 -114
  298. package/dist/esm/dockview/theme.d.ts +0 -86
  299. package/dist/esm/dockview/theme.js +0 -136
  300. package/dist/esm/dockview/types.d.ts +0 -53
  301. package/dist/esm/dockview/types.js +0 -1
  302. package/dist/esm/dockview/validate.d.ts +0 -0
  303. package/dist/esm/dockview/validate.js +0 -76
  304. package/dist/esm/dockview/watermarkService.d.ts +0 -30
  305. package/dist/esm/dockview/watermarkService.js +0 -56
  306. package/dist/esm/dom.d.ts +0 -60
  307. package/dist/esm/dom.js +0 -375
  308. package/dist/esm/events.d.ts +0 -79
  309. package/dist/esm/events.js +0 -219
  310. package/dist/esm/framwork.d.ts +0 -4
  311. package/dist/esm/framwork.js +0 -1
  312. package/dist/esm/gridview/baseComponentGridview.d.ts +0 -111
  313. package/dist/esm/gridview/baseComponentGridview.js +0 -237
  314. package/dist/esm/gridview/basePanelView.d.ts +0 -40
  315. package/dist/esm/gridview/basePanelView.js +0 -91
  316. package/dist/esm/gridview/branchNode.d.ts +0 -57
  317. package/dist/esm/gridview/branchNode.js +0 -257
  318. package/dist/esm/gridview/gridview.d.ts +0 -158
  319. package/dist/esm/gridview/gridview.js +0 -681
  320. package/dist/esm/gridview/gridviewComponent.d.ts +0 -88
  321. package/dist/esm/gridview/gridviewComponent.js +0 -265
  322. package/dist/esm/gridview/gridviewPanel.d.ts +0 -77
  323. package/dist/esm/gridview/gridviewPanel.js +0 -182
  324. package/dist/esm/gridview/leafNode.d.ts +0 -34
  325. package/dist/esm/gridview/leafNode.js +0 -102
  326. package/dist/esm/gridview/options.d.ts +0 -15
  327. package/dist/esm/gridview/options.js +0 -14
  328. package/dist/esm/gridview/types.d.ts +0 -3
  329. package/dist/esm/gridview/types.js +0 -1
  330. package/dist/esm/index.d.ts +0 -58
  331. package/dist/esm/index.js +0 -44
  332. package/dist/esm/lifecycle.d.ts +0 -25
  333. package/dist/esm/lifecycle.js +0 -56
  334. package/dist/esm/math.d.ts +0 -5
  335. package/dist/esm/math.js +0 -32
  336. package/dist/esm/overlay/overlay.d.ts +0 -91
  337. package/dist/esm/overlay/overlay.js +0 -520
  338. package/dist/esm/overlay/overlayRenderContainer.d.ts +0 -24
  339. package/dist/esm/overlay/overlayRenderContainer.js +0 -249
  340. package/dist/esm/panel/types.d.ts +0 -33
  341. package/dist/esm/panel/types.js +0 -1
  342. package/dist/esm/paneview/defaultPaneviewHeader.d.ts +0 -21
  343. package/dist/esm/paneview/defaultPaneviewHeader.js +0 -65
  344. package/dist/esm/paneview/draggablePaneviewPanel.d.ts +0 -38
  345. package/dist/esm/paneview/draggablePaneviewPanel.js +0 -107
  346. package/dist/esm/paneview/options.d.ts +0 -30
  347. package/dist/esm/paneview/options.js +0 -22
  348. package/dist/esm/paneview/paneview.d.ts +0 -41
  349. package/dist/esm/paneview/paneview.js +0 -148
  350. package/dist/esm/paneview/paneviewComponent.d.ts +0 -133
  351. package/dist/esm/paneview/paneviewComponent.js +0 -306
  352. package/dist/esm/paneview/paneviewPanel.d.ts +0 -98
  353. package/dist/esm/paneview/paneviewPanel.js +0 -192
  354. package/dist/esm/popoutWindow.d.ts +0 -38
  355. package/dist/esm/popoutWindow.js +0 -170
  356. package/dist/esm/resizable.d.ts +0 -12
  357. package/dist/esm/resizable.js +0 -66
  358. package/dist/esm/scrollbar.d.ts +0 -15
  359. package/dist/esm/scrollbar.js +0 -139
  360. package/dist/esm/splitview/options.d.ts +0 -21
  361. package/dist/esm/splitview/options.js +0 -16
  362. package/dist/esm/splitview/splitview.d.ts +0 -145
  363. package/dist/esm/splitview/splitview.js +0 -770
  364. package/dist/esm/splitview/splitviewComponent.d.ts +0 -101
  365. package/dist/esm/splitview/splitviewComponent.js +0 -267
  366. package/dist/esm/splitview/splitviewPanel.d.ts +0 -45
  367. package/dist/esm/splitview/splitviewPanel.js +0 -108
  368. package/dist/esm/splitview/viewItem.d.ts +0 -25
  369. package/dist/esm/splitview/viewItem.js +0 -74
  370. package/dist/esm/svg.d.ts +0 -3
  371. package/dist/esm/svg.js +0 -31
  372. package/dist/esm/types.d.ts +0 -31
  373. package/dist/esm/types.js +0 -1
  374. 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
- }