import * as React from "react"; import { I18nLabel } from "../I18nLabel"; import Actions from "../model/Actions"; import TabNode from "../model/TabNode"; import TabSetNode from "../model/TabSetNode"; import { showPopup } from "../PopupMenu"; import { IIcons, ILayoutCallbacks } from "./Layout"; import { TabButton } from "./TabButton"; import { useTabOverflow } from "./TabOverflowHook"; import Orientation from "../Orientation"; import { CLASSES } from "../Types"; import { hideElement } from "./Tab"; /** @hidden @internal */ export interface ITabSetProps { layout: ILayoutCallbacks; node: TabSetNode; iconFactory?: (node: TabNode) => React.ReactNode | undefined; titleFactory?: (node: TabNode) => React.ReactNode | undefined; icons?: IIcons; editingTab?: TabNode; path?: string; } /** @hidden @internal */ export const TabSet = (props: ITabSetProps) => { const { node, layout, iconFactory, titleFactory, icons, path } = props; const toolbarRef = React.useRef(null); const overflowbuttonRef = React.useRef(null); const tabbarInnerRef = React.useRef(null); const stickyButtonsRef = React.useRef(null); const { selfRef, position, userControlledLeft, hiddenTabs, onMouseWheel, tabsTruncated } = useTabOverflow(node, Orientation.HORZ, toolbarRef, stickyButtonsRef); const onOverflowClick = (event: React.MouseEvent) => { const element = overflowbuttonRef.current!; showPopup(layout.getRootDiv(), element, hiddenTabs, onOverflowItemSelect, layout.getClassName); event.stopPropagation(); }; const onOverflowItemSelect = (item: { node: TabNode; index: number }) => { layout.doAction(Actions.selectTab(item.node.getId())); userControlledLeft.current = false; }; const onMouseDown = (event: React.MouseEvent | React.TouchEvent) => { if (!isAuxMouseEvent(event)) { let name = node.getName(); if (name === undefined) { name = ""; } else { name = ": " + name; } layout.doAction(Actions.setActiveTabset(node.getId())); if (!layout.getEditingTab()) { const message = layout.i18nName(I18nLabel.Move_Tabset, name); layout.dragStart(event, message, node, node.isEnableDrag(), (event2: Event) => undefined, onDoubleClick); } } }; const onAuxMouseClick = (event: React.MouseEvent) => { if (isAuxMouseEvent(event)) { layout.auxMouseClick(node, event); } }; const onContextMenu = (event: React.MouseEvent) => { layout.showContextMenu(node, event); }; const onInterceptMouseDown = (event: React.MouseEvent | React.TouchEvent) => { event.stopPropagation(); }; const onMaximizeToggle = (event: React.MouseEvent) => { if (node.canMaximize()) { layout.maximize(node); } event.stopPropagation(); }; const onClose = (event: React.MouseEvent) => { layout.doAction(Actions.deleteTabset(node.getId())); event.stopPropagation(); }; const onFloatTab = (event: React.MouseEvent) => { if (selectedTabNode !== undefined) { layout.doAction(Actions.floatTab(selectedTabNode.getId())); } event.stopPropagation(); }; const onDoubleClick = (event: Event) => { if (node.canMaximize()) { layout.maximize(node); } }; // Start Render const cm = layout.getClassName; // tabbar inner can get shifted left via tab rename, this resets scrollleft to 0 if (tabbarInnerRef.current !== null && tabbarInnerRef.current!.scrollLeft !== 0) { tabbarInnerRef.current.scrollLeft = 0; } const selectedTabNode: TabNode = node.getSelectedNode() as TabNode; let style = node._styleWithPosition(); if (node.getModel().getMaximizedTabset() !== undefined && !node.isMaximized()) { hideElement(style, node.getModel().isUseVisibility()) } const tabs = []; if (node.isEnableTabStrip()) { for (let i = 0; i < node.getChildren().length; i++) { const child = node.getChildren()[i] as TabNode; let isSelected = node.getSelected() === i; tabs.push( ); } } const showHeader = node.getName() !== undefined; let stickyButtons: React.ReactNode[] = []; let buttons: React.ReactNode[] = []; let headerButtons: React.ReactNode[] = []; // allow customization of header contents and buttons const renderState = { headerContent: node.getName(), stickyButtons, buttons, headerButtons }; layout.customizeTabSet(node, renderState); const headerContent = renderState.headerContent; stickyButtons = renderState.stickyButtons; buttons = renderState.buttons; headerButtons = renderState.headerButtons; if (stickyButtons.length > 0) { if (tabsTruncated) { buttons = [...stickyButtons, ...buttons]; } else { tabs.push(
{ e.preventDefault() }} className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_STICKY_BUTTONS_CONTAINER)} > {stickyButtons}
); } } let toolbar; if (hiddenTabs.length > 0) { const overflowTitle = layout.i18nName(I18nLabel.Overflow_Menu_Tooltip); buttons.push( ); } if (selectedTabNode !== undefined && layout.isSupportsPopout() && selectedTabNode.isEnableFloat() && !selectedTabNode.isFloating()) { const floatTitle = layout.i18nName(I18nLabel.Float_Tab); buttons.push( ); } if (node.canMaximize()) { const minTitle = layout.i18nName(I18nLabel.Restore); const maxTitle = layout.i18nName(I18nLabel.Maximize); const btns = showHeader ? headerButtons : buttons; btns.push( ); } if (!node.isMaximized() && node.isEnableClose()) { const title = layout.i18nName(I18nLabel.Close_Tabset); const btns = showHeader ? headerButtons : buttons; btns.push( ); } toolbar = (
{ e.preventDefault() }} > {buttons}
); let header; let tabStrip; let tabStripClasses = cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_OUTER); if (node.getClassNameTabStrip() !== undefined) { tabStripClasses += " " + node.getClassNameTabStrip(); } tabStripClasses += " " + CLASSES.FLEXLAYOUT__TABSET_TABBAR_OUTER_ + node.getTabLocation(); if (node.isActive() && !showHeader) { tabStripClasses += " " + cm(CLASSES.FLEXLAYOUT__TABSET_SELECTED); } if (node.isMaximized() && !showHeader) { tabStripClasses += " " + cm(CLASSES.FLEXLAYOUT__TABSET_MAXIMIZED); } if (showHeader) { const headerToolbar = (
{ e.preventDefault() }} > {headerButtons}
); let tabHeaderClasses = cm(CLASSES.FLEXLAYOUT__TABSET_HEADER); if (node.isActive()) { tabHeaderClasses += " " + cm(CLASSES.FLEXLAYOUT__TABSET_SELECTED); } if (node.isMaximized()) { tabHeaderClasses += " " + cm(CLASSES.FLEXLAYOUT__TABSET_MAXIMIZED); } if (node.getClassNameHeader() !== undefined) { tabHeaderClasses += " " + node.getClassNameHeader(); } header = (
{headerContent}
{headerToolbar}
); } const tabStripStyle: { [key: string]: string } = { height: node.getTabStripHeight() + "px" }; if (node.getTabLocation() === "top") { const top = showHeader ? node.getHeaderHeight() + "px" : "0px"; tabStripStyle["top"] = top; } else { tabStripStyle["bottom"] = "0px"; } tabStrip = (
{tabs}
{toolbar}
); style = layout.styleFont(style); return (
{header} {tabStrip}
); }; /** @hidden @internal */ export function isAuxMouseEvent(event: React.MouseEvent | React.TouchEvent) { let auxEvent = false; if (event.nativeEvent instanceof MouseEvent) { if (event.nativeEvent.button !== 0 || event.ctrlKey || event.altKey || event.metaKey || event.shiftKey) { auxEvent = true; } } return auxEvent; }