tabs-container.tsx 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import { useFileTreeOpenContext } from '@/features/ide-react/context/file-tree-open-context'
  2. import {
  3. TAB_TRANSFER_TYPE,
  4. useTabsContext,
  5. } from '@/features/ide-react/context/tabs-context'
  6. import { Tab } from './tab'
  7. import SplitTestBadge from '@/shared/components/split-test-badge'
  8. import { useCallback, useMemo, useState } from 'react'
  9. import { throttle } from 'lodash'
  10. import { debugConsole } from '@/utils/debugging'
  11. import classNames from 'classnames'
  12. export const TabsContainer = () => {
  13. const { tabs, openTab, closeTab, moveTab, makeTabPermanent } =
  14. useTabsContext()
  15. const { openEntity } = useFileTreeOpenContext()
  16. const [hovered, setHovered] = useState<boolean>(false)
  17. const throttledOnDragOver = useMemo(
  18. () =>
  19. throttle(() => {
  20. setHovered(true)
  21. }, 50),
  22. []
  23. )
  24. const onDragOver = useCallback(
  25. (e: React.DragEvent) => {
  26. e.preventDefault()
  27. throttledOnDragOver()
  28. },
  29. [throttledOnDragOver]
  30. )
  31. const onDrop = useCallback(
  32. (e: React.DragEvent) => {
  33. throttledOnDragOver.cancel()
  34. e.stopPropagation()
  35. e.preventDefault()
  36. setHovered(false)
  37. const draggedTabId = e.dataTransfer.getData(TAB_TRANSFER_TYPE)
  38. if (!draggedTabId) {
  39. debugConsole.warn('No dragged tab id found in dataTransfer')
  40. return
  41. }
  42. const targetTabId = tabs[tabs.length - 1]?.id
  43. if (!targetTabId) {
  44. debugConsole.warn('No target tab id found for drop')
  45. return
  46. }
  47. moveTab(draggedTabId, targetTabId, 'right')
  48. },
  49. [tabs, moveTab, throttledOnDragOver]
  50. )
  51. const onDragLeave = useCallback(() => {
  52. throttledOnDragOver.cancel()
  53. setHovered(false)
  54. }, [throttledOnDragOver])
  55. return (
  56. <div className="editor-tabs-container">
  57. <div
  58. className={classNames('editor-tabs-row', {
  59. 'editor-tabs-row-hovered': hovered,
  60. })}
  61. role="tablist"
  62. onDragOver={onDragOver}
  63. onDrop={onDrop}
  64. onDragLeave={onDragLeave}
  65. tabIndex={-1}
  66. >
  67. {tabs.map(tab => (
  68. <Tab
  69. key={tab.id}
  70. tab={tab}
  71. openTab={openTab}
  72. closeTab={closeTab}
  73. isSelected={openEntity?.entity._id === tab.id}
  74. onTabDrop={moveTab}
  75. makeTabPermanent={makeTabPermanent}
  76. />
  77. ))}
  78. </div>
  79. <div className="editor-tabs-labs-icon">
  80. <SplitTestBadge
  81. splitTestName="editor-tabs"
  82. displayOnVariants={['enabled']}
  83. />
  84. </div>
  85. </div>
  86. )
  87. }