| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- import { useFileTreeOpenContext } from '@/features/ide-react/context/file-tree-open-context'
- import {
- TAB_TRANSFER_TYPE,
- useTabsContext,
- } from '@/features/ide-react/context/tabs-context'
- import { Tab } from './tab'
- import { TabsContextMenu } from './tabs-context-menu'
- import SplitTestBadge from '@/shared/components/split-test-badge'
- import { useCallback, useMemo, useState } from 'react'
- import { throttle } from 'lodash'
- import { debugConsole } from '@/utils/debugging'
- import classNames from 'classnames'
- export const TabsContainer = () => {
- const {
- tabs,
- openTab,
- closeTab,
- moveTab,
- makeTabPermanent,
- setContextMenuTarget,
- setHeaderSlot,
- } = useTabsContext()
- const { openEntity } = useFileTreeOpenContext()
- const [hovered, setHovered] = useState<boolean>(false)
- const openContextMenu = useCallback(
- (coords: { top: number; left: number }, tabId: string) => {
- setContextMenuTarget({ ...coords, tabId })
- },
- [setContextMenuTarget]
- )
- const closeContextMenu = useCallback(() => {
- setContextMenuTarget(null)
- }, [setContextMenuTarget])
- const throttledOnDragOver = useMemo(
- () =>
- throttle(() => {
- setHovered(true)
- }, 50),
- []
- )
- const onDragOver = useCallback(
- (e: React.DragEvent) => {
- e.preventDefault()
- throttledOnDragOver()
- },
- [throttledOnDragOver]
- )
- const onDrop = useCallback(
- (e: React.DragEvent) => {
- throttledOnDragOver.cancel()
- e.stopPropagation()
- e.preventDefault()
- setHovered(false)
- const draggedTabId = e.dataTransfer.getData(TAB_TRANSFER_TYPE)
- if (!draggedTabId) {
- debugConsole.warn('No dragged tab id found in dataTransfer')
- return
- }
- const targetTabId = tabs[tabs.length - 1]?.id
- if (!targetTabId) {
- debugConsole.warn('No target tab id found for drop')
- return
- }
- moveTab(draggedTabId, targetTabId, 'right')
- },
- [tabs, moveTab, throttledOnDragOver]
- )
- const onDragLeave = useCallback(() => {
- throttledOnDragOver.cancel()
- setHovered(false)
- }, [throttledOnDragOver])
- const onWheel = useCallback((e: React.WheelEvent) => {
- if (e.deltaY !== 0 && e.deltaX === 0) {
- // if this is a purely vertical scroll, convert it to a horizontal scroll
- // instead
- e.currentTarget.scrollLeft += e.deltaY
- }
- }, [])
- return (
- <div className="editor-tabs-container">
- <div className="review-panel-header-slot" ref={setHeaderSlot} />
- <div
- className={classNames('editor-tabs-row', {
- 'editor-tabs-row-hovered': hovered,
- })}
- role="tablist"
- onDragOver={onDragOver}
- onDrop={onDrop}
- onDragLeave={onDragLeave}
- onWheel={onWheel}
- tabIndex={-1}
- >
- {tabs.map(tab => (
- <Tab
- key={tab.id}
- tab={tab}
- openTab={openTab}
- closeTab={closeTab}
- isSelected={openEntity?.entity._id === tab.id}
- onTabDrop={moveTab}
- makeTabPermanent={makeTabPermanent}
- openContextMenu={openContextMenu}
- closeContextMenu={closeContextMenu}
- />
- ))}
- </div>
- <div className="editor-tabs-labs-icon">
- <SplitTestBadge
- splitTestName="editor-tabs"
- displayOnVariants={['enabled']}
- />
- </div>
- <TabsContextMenu />
- </div>
- )
- }
|