flexlayout-react 0.7.15 → 0.8.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.
- package/ChangeLog.txt +23 -0
- package/README.md +157 -330
- package/Screenshot_light.png +0 -0
- package/Screenshot_rounded.png +0 -0
- package/declarations/Attribute.d.ts +1 -1
- package/declarations/AttributeDefinitions.d.ts +1 -1
- package/declarations/DockLocation.d.ts +12 -12
- package/declarations/DropInfo.d.ts +12 -12
- package/declarations/I18nLabel.d.ts +12 -14
- package/declarations/Orientation.d.ts +7 -7
- package/declarations/PopupMenu.d.ts +1 -1
- package/declarations/Rect.d.ts +41 -28
- package/declarations/Types.d.ts +95 -79
- package/declarations/examples/demo/Utils.d.ts +4 -0
- package/declarations/index.d.ts +21 -22
- package/declarations/model/Action.d.ts +5 -5
- package/declarations/model/Actions.d.ts +127 -110
- package/declarations/model/BorderNode.d.ts +30 -34
- package/declarations/model/BorderSet.d.ts +3 -4
- package/declarations/model/ICloseType.d.ts +5 -5
- package/declarations/model/IDraggable.d.ts +2 -2
- package/declarations/model/IDropTarget.d.ts +2 -2
- package/declarations/model/IJsonModel.d.ts +811 -149
- package/declarations/model/LayoutWindow.d.ts +28 -0
- package/declarations/model/Model.d.ts +91 -86
- package/declarations/model/Node.d.ts +17 -17
- package/declarations/model/RowNode.d.ts +10 -11
- package/declarations/model/TabNode.d.ts +44 -37
- package/declarations/model/TabSetNode.d.ts +44 -41
- package/declarations/model/Utils.d.ts +1 -1
- package/declarations/model/WindowLayout.d.ts +24 -0
- package/declarations/src/Attribute.d.ts +1 -0
- package/declarations/src/AttributeDefinitions.d.ts +1 -0
- package/declarations/src/DockLocation.d.ts +12 -0
- package/declarations/src/DropInfo.d.ts +12 -0
- package/declarations/src/I18nLabel.d.ts +10 -0
- package/declarations/src/Orientation.d.ts +7 -0
- package/declarations/src/PopupMenu.d.ts +1 -0
- package/declarations/src/Rect.d.ts +31 -0
- package/declarations/src/Types.d.ts +92 -0
- package/declarations/src/index.d.ts +20 -0
- package/declarations/src/model/Action.d.ts +5 -0
- package/declarations/src/model/Actions.d.ts +110 -0
- package/declarations/src/model/BorderNode.d.ts +28 -0
- package/declarations/src/model/BorderSet.d.ts +3 -0
- package/declarations/src/model/ICloseType.d.ts +5 -0
- package/declarations/src/model/IDraggable.d.ts +2 -0
- package/declarations/src/model/IDropTarget.d.ts +2 -0
- package/declarations/src/model/IJsonModel.d.ts +153 -0
- package/declarations/src/model/Model.d.ts +98 -0
- package/declarations/src/model/Node.d.ts +16 -0
- package/declarations/src/model/RowNode.d.ts +11 -0
- package/declarations/src/model/TabNode.d.ts +36 -0
- package/declarations/src/model/TabSetNode.d.ts +37 -0
- package/declarations/src/model/Utils.d.ts +1 -0
- package/declarations/src/view/BorderButton.d.ts +1 -0
- package/declarations/src/view/BorderTab.d.ts +2 -0
- package/declarations/src/view/BorderTabSet.d.ts +1 -0
- package/declarations/src/view/DragContainer.d.ts +1 -0
- package/declarations/src/view/ErrorBoundary.d.ts +1 -0
- package/declarations/src/view/FloatingWindow.d.ts +1 -0
- package/declarations/src/view/Icons.d.ts +7 -0
- package/declarations/src/view/Layout.d.ts +113 -0
- package/declarations/src/view/Overlay.d.ts +1 -0
- package/declarations/src/view/PopupMenu.d.ts +1 -0
- package/declarations/src/view/Row.d.ts +1 -0
- package/declarations/src/view/Splitter.d.ts +1 -0
- package/declarations/src/view/Tab.d.ts +1 -0
- package/declarations/src/view/TabButton.d.ts +1 -0
- package/declarations/src/view/TabButtonStamp.d.ts +1 -0
- package/declarations/src/view/TabOverflowHook.d.ts +1 -0
- package/declarations/src/view/TabSet.d.ts +1 -0
- package/declarations/src/view/Utils.d.ts +4 -0
- package/declarations/view/BorderButton.d.ts +1 -1
- package/declarations/view/BorderTab.d.ts +2 -0
- package/declarations/view/BorderTabSet.d.ts +1 -1
- package/declarations/view/DragContainer.d.ts +1 -0
- package/declarations/view/ErrorBoundary.d.ts +1 -1
- package/declarations/view/ExtendedResizeObserver.d.ts +23 -0
- package/declarations/view/FloatingWindow.d.ts +1 -1
- package/declarations/view/Icons.d.ts +8 -7
- package/declarations/view/Layout.d.ts +139 -161
- package/declarations/view/Overlay.d.ts +1 -0
- package/declarations/view/PopoutWindow.d.ts +1 -0
- package/declarations/view/PopupMenu.d.ts +1 -0
- package/declarations/view/Row.d.ts +1 -0
- package/declarations/view/SizeTracker.d.ts +10 -0
- package/declarations/view/Splitter.d.ts +1 -1
- package/declarations/view/Tab.d.ts +1 -1
- package/declarations/view/TabButton.d.ts +1 -1
- package/declarations/view/TabButtonStamp.d.ts +1 -1
- package/declarations/view/TabOverflowHook.d.ts +1 -1
- package/declarations/view/TabSet.d.ts +1 -1
- package/declarations/view/Utils.d.ts +11 -1
- package/dist/bundles/demo.js +232052 -0
- package/dist/bundles/demo.js.map +1 -0
- package/dist/flexlayout.js +122 -92
- package/dist/flexlayout_min.js +1 -1
- package/lib/Attribute.js +42 -31
- package/lib/Attribute.js.map +1 -1
- package/lib/AttributeDefinitions.js +131 -108
- package/lib/AttributeDefinitions.js.map +1 -1
- package/lib/DockLocation.js +120 -124
- package/lib/DockLocation.js.map +1 -1
- package/lib/DropInfo.js +9 -13
- package/lib/DropInfo.js.map +1 -1
- package/lib/I18nLabel.js +13 -18
- package/lib/I18nLabel.js.map +1 -1
- package/lib/Orientation.js +22 -26
- package/lib/Orientation.js.map +1 -1
- package/lib/Rect.js +104 -72
- package/lib/Rect.js.map +1 -1
- package/lib/Types.js +96 -83
- package/lib/Types.js.map +1 -1
- package/lib/index.js +21 -38
- package/lib/index.js.map +1 -1
- package/lib/model/Action.js +6 -10
- package/lib/model/Action.js.map +1 -1
- package/lib/model/Actions.js +169 -155
- package/lib/model/Actions.js.map +1 -1
- package/lib/model/BorderNode.js +385 -406
- package/lib/model/BorderNode.js.map +1 -1
- package/lib/model/BorderSet.js +66 -121
- package/lib/model/BorderSet.js.map +1 -1
- package/lib/model/ICloseType.js +6 -9
- package/lib/model/ICloseType.js.map +1 -1
- package/lib/model/IDraggable.js +1 -2
- package/lib/model/IDropTarget.js +1 -2
- package/lib/model/IJsonModel.js +1 -2
- package/lib/model/LayoutWindow.js +83 -0
- package/lib/model/LayoutWindow.js.map +1 -0
- package/lib/model/Model.js +614 -496
- package/lib/model/Model.js.map +1 -1
- package/lib/model/Node.js +217 -228
- package/lib/model/Node.js.map +1 -1
- package/lib/model/RowNode.js +491 -504
- package/lib/model/RowNode.js.map +1 -1
- package/lib/model/TabNode.js +289 -184
- package/lib/model/TabNode.js.map +1 -1
- package/lib/model/TabSetNode.js +457 -446
- package/lib/model/TabSetNode.js.map +1 -1
- package/lib/model/Utils.js +47 -82
- package/lib/model/Utils.js.map +1 -1
- package/lib/view/BorderButton.js +124 -138
- package/lib/view/BorderButton.js.map +1 -1
- package/lib/view/BorderTab.js +47 -0
- package/lib/view/BorderTab.js.map +1 -0
- package/lib/view/BorderTabSet.js +134 -128
- package/lib/view/BorderTabSet.js.map +1 -1
- package/lib/view/DragContainer.js +16 -0
- package/lib/view/DragContainer.js.map +1 -0
- package/lib/view/ErrorBoundary.js +23 -27
- package/lib/view/ErrorBoundary.js.map +1 -1
- package/lib/view/Icons.js +40 -45
- package/lib/view/Icons.js.map +1 -1
- package/lib/view/Layout.js +918 -907
- package/lib/view/Layout.js.map +1 -1
- package/lib/view/Overlay.js +9 -0
- package/lib/view/Overlay.js.map +1 -0
- package/lib/view/PopoutWindow.js +129 -0
- package/lib/view/PopoutWindow.js.map +1 -0
- package/lib/view/PopupMenu.js +71 -0
- package/lib/view/PopupMenu.js.map +1 -0
- package/lib/view/Row.js +45 -0
- package/lib/view/Row.js.map +1 -0
- package/lib/view/SizeTracker.js +11 -0
- package/lib/view/SizeTracker.js.map +1 -0
- package/lib/view/Splitter.js +191 -147
- package/lib/view/Splitter.js.map +1 -1
- package/lib/view/Tab.js +86 -60
- package/lib/view/Tab.js.map +1 -1
- package/lib/view/TabButton.js +122 -135
- package/lib/view/TabButton.js.map +1 -1
- package/lib/view/TabButtonStamp.js +16 -21
- package/lib/view/TabButtonStamp.js.map +1 -1
- package/lib/view/TabOverflowHook.js +150 -149
- package/lib/view/TabOverflowHook.js.map +1 -1
- package/lib/view/TabSet.js +267 -234
- package/lib/view/TabSet.js.map +1 -1
- package/lib/view/Utils.js +126 -68
- package/lib/view/Utils.js.map +1 -1
- package/package.json +36 -30
- package/src/Attribute.ts +23 -0
- package/src/AttributeDefinitions.ts +38 -15
- package/src/DockLocation.ts +13 -13
- package/src/I18nLabel.ts +7 -9
- package/src/Rect.ts +53 -1
- package/src/Types.ts +16 -0
- package/src/index.ts +1 -2
- package/src/model/Actions.ts +49 -29
- package/src/model/BorderNode.ts +208 -214
- package/src/model/BorderSet.ts +42 -91
- package/src/model/IJsonModel.ts +883 -103
- package/src/model/LayoutWindow.ts +121 -0
- package/src/model/Model.ts +488 -366
- package/src/model/Node.ts +98 -111
- package/src/model/RowNode.ts +323 -319
- package/src/model/TabNode.ts +294 -110
- package/src/model/TabSetNode.ts +300 -242
- package/src/model/Utils.ts +6 -32
- package/src/view/BorderButton.tsx +32 -52
- package/src/view/BorderTab.tsx +70 -0
- package/src/view/BorderTabSet.tsx +64 -52
- package/src/view/DragContainer.tsx +32 -0
- package/src/view/Icons.tsx +6 -0
- package/src/view/Layout.tsx +1051 -1046
- package/src/view/Overlay.tsx +22 -0
- package/src/view/PopoutWindow.tsx +152 -0
- package/src/{PopupMenu.tsx → view/PopupMenu.tsx} +36 -31
- package/src/view/Row.tsx +68 -0
- package/src/view/SizeTracker.tsx +20 -0
- package/src/view/Splitter.tsx +167 -112
- package/src/view/Tab.tsx +76 -42
- package/src/view/TabButton.tsx +36 -55
- package/src/view/TabButtonStamp.tsx +5 -9
- package/src/view/TabOverflowHook.tsx +14 -9
- package/src/view/TabSet.tsx +217 -176
- package/src/view/Utils.tsx +119 -39
- package/style/_base.scss +140 -34
- package/style/dark.css +685 -580
- package/style/dark.css.map +1 -1
- package/style/dark.scss +3 -1
- package/style/gray.css +668 -563
- package/style/gray.css.map +1 -1
- package/style/gray.scss +2 -0
- package/style/light.css +669 -564
- package/style/light.css.map +1 -1
- package/style/light.scss +4 -2
- package/style/rounded.css +697 -0
- package/style/rounded.css.map +1 -0
- package/style/rounded.scss +194 -0
- package/style/underline.css +690 -585
- package/style/underline.css.map +1 -1
- package/style/underline.scss +2 -0
- package/cypress.config.ts +0 -16
- package/lib/DragDrop.js +0 -316
- package/lib/DragDrop.js.map +0 -1
- package/lib/PopupMenu.js +0 -68
- package/lib/PopupMenu.js.map +0 -1
- package/lib/model/SplitterNode.js +0 -72
- package/lib/model/SplitterNode.js.map +0 -1
- package/lib/view/FloatingWindow.js +0 -123
- package/lib/view/FloatingWindow.js.map +0 -1
- package/lib/view/FloatingWindowTab.js +0 -19
- package/lib/view/FloatingWindowTab.js.map +0 -1
- package/lib/view/TabFloating.js +0 -66
- package/lib/view/TabFloating.js.map +0 -1
- package/src/DragDrop.ts +0 -392
- package/src/model/SplitterNode.ts +0 -78
- package/src/view/FloatingWindow.tsx +0 -140
- package/src/view/FloatingWindowTab.tsx +0 -29
- package/src/view/TabFloating.tsx +0 -101
package/src/view/TabSet.tsx
CHANGED
|
@@ -3,35 +3,52 @@ import { I18nLabel } from "../I18nLabel";
|
|
|
3
3
|
import { Actions } from "../model/Actions";
|
|
4
4
|
import { TabNode } from "../model/TabNode";
|
|
5
5
|
import { TabSetNode } from "../model/TabSetNode";
|
|
6
|
-
import { showPopup } from "
|
|
7
|
-
import {
|
|
6
|
+
import { showPopup } from "./PopupMenu";
|
|
7
|
+
import { LayoutInternal, ITabSetRenderValues } from "./Layout";
|
|
8
8
|
import { TabButton } from "./TabButton";
|
|
9
9
|
import { useTabOverflow } from "./TabOverflowHook";
|
|
10
10
|
import { Orientation } from "../Orientation";
|
|
11
11
|
import { CLASSES } from "../Types";
|
|
12
|
-
import {
|
|
12
|
+
import { isAuxMouseEvent } from "./Utils";
|
|
13
|
+
import { createPortal } from "react-dom";
|
|
14
|
+
import { Rect } from "../Rect";
|
|
13
15
|
|
|
14
16
|
/** @internal */
|
|
15
17
|
export interface ITabSetProps {
|
|
16
|
-
layout:
|
|
18
|
+
layout: LayoutInternal;
|
|
17
19
|
node: TabSetNode;
|
|
18
|
-
iconFactory?: (node: TabNode) => (React.ReactNode | undefined);
|
|
19
|
-
titleFactory?: (node: TabNode) => (ITitleObject | React.ReactNode | undefined);
|
|
20
|
-
icons: IIcons;
|
|
21
|
-
editingTab?: TabNode;
|
|
22
|
-
path?: string;
|
|
23
20
|
}
|
|
24
21
|
|
|
25
22
|
/** @internal */
|
|
26
23
|
export const TabSet = (props: ITabSetProps) => {
|
|
27
|
-
const { node, layout
|
|
24
|
+
const { node, layout } = props;
|
|
28
25
|
|
|
29
|
-
const
|
|
26
|
+
const tabStripRef = React.useRef<HTMLDivElement | null>(null);
|
|
27
|
+
const tabStripInnerRef = React.useRef<HTMLDivElement | null>(null);
|
|
28
|
+
const contentRef = React.useRef<HTMLDivElement | null>(null);
|
|
29
|
+
const buttonBarRef = React.useRef<HTMLDivElement | null>(null);
|
|
30
30
|
const overflowbuttonRef = React.useRef<HTMLButtonElement | null>(null);
|
|
31
|
-
const tabbarInnerRef = React.useRef<HTMLDivElement | null>(null);
|
|
32
31
|
const stickyButtonsRef = React.useRef<HTMLDivElement | null>(null);
|
|
33
32
|
|
|
34
|
-
const
|
|
33
|
+
const icons = layout.getIcons();
|
|
34
|
+
|
|
35
|
+
// must use useEffect (rather than useLayoutEffect) otherwise contentrect not set correctly (has height 0 when changing theme in demo)
|
|
36
|
+
React.useEffect(() => {
|
|
37
|
+
node.setRect(layout.getBoundingClientRect(selfRef.current!));
|
|
38
|
+
|
|
39
|
+
if (tabStripRef.current) {
|
|
40
|
+
node.setTabStripRect(layout.getBoundingClientRect(tabStripRef.current!));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const newContentRect = Rect.getContentRect(contentRef.current!).relativeTo(layout.getDomRect()!);
|
|
44
|
+
if (!node.getContentRect().equals(newContentRect)) {
|
|
45
|
+
node.setContentRect(newContentRect);
|
|
46
|
+
layout.redrawInternal("tabset content rect " + newContentRect);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// this must be after the useEffect, so the node rect is already set (else window popin will not position tabs correctly)
|
|
51
|
+
const { selfRef, position, userControlledLeft, hiddenTabs, onMouseWheel, tabsTruncated } = useTabOverflow(node, Orientation.HORZ, buttonBarRef, stickyButtonsRef);
|
|
35
52
|
|
|
36
53
|
const onOverflowClick = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
|
37
54
|
const callback = layout.getShowOverflowMenu();
|
|
@@ -43,9 +60,7 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
43
60
|
element,
|
|
44
61
|
hiddenTabs,
|
|
45
62
|
onOverflowItemSelect,
|
|
46
|
-
layout
|
|
47
|
-
iconFactory,
|
|
48
|
-
titleFactory,
|
|
63
|
+
layout
|
|
49
64
|
);
|
|
50
65
|
}
|
|
51
66
|
event.stopPropagation();
|
|
@@ -56,7 +71,16 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
56
71
|
userControlledLeft.current = false;
|
|
57
72
|
};
|
|
58
73
|
|
|
59
|
-
const
|
|
74
|
+
const onDragStart = (event: React.DragEvent<HTMLElement>) => {
|
|
75
|
+
if (!layout.getEditingTab()) {
|
|
76
|
+
event.stopPropagation();
|
|
77
|
+
layout.setDragNode(event.nativeEvent, node as TabSetNode);
|
|
78
|
+
} else {
|
|
79
|
+
event.preventDefault();
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const onPointerDown = (event: React.PointerEvent<HTMLElement>) => {
|
|
60
84
|
if (!isAuxMouseEvent(event)) {
|
|
61
85
|
let name = node.getName();
|
|
62
86
|
if (name === undefined) {
|
|
@@ -64,29 +88,21 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
64
88
|
} else {
|
|
65
89
|
name = ": " + name;
|
|
66
90
|
}
|
|
67
|
-
layout.doAction(Actions.setActiveTabset(node.getId()));
|
|
68
|
-
if (!layout.getEditingTab()) {
|
|
69
|
-
const message = layout.i18nName(I18nLabel.Move_Tabset, name);
|
|
70
|
-
if (node.getModel().getMaximizedTabset() !== undefined) {
|
|
71
|
-
layout.dragStart(event, message, node, false, (event2: Event) => undefined, onDoubleClick);
|
|
72
|
-
} else {
|
|
73
|
-
layout.dragStart(event, message, node, node.isEnableDrag(), (event2: Event) => undefined, onDoubleClick);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
91
|
+
layout.doAction(Actions.setActiveTabset(node.getId(), layout.getWindowId()));
|
|
76
92
|
}
|
|
77
93
|
};
|
|
78
94
|
|
|
79
|
-
const onAuxMouseClick = (event: React.MouseEvent<
|
|
95
|
+
const onAuxMouseClick = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
|
80
96
|
if (isAuxMouseEvent(event)) {
|
|
81
97
|
layout.auxMouseClick(node, event);
|
|
82
98
|
}
|
|
83
99
|
};
|
|
84
100
|
|
|
85
|
-
const onContextMenu = (event: React.MouseEvent<
|
|
101
|
+
const onContextMenu = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
|
86
102
|
layout.showContextMenu(node, event);
|
|
87
103
|
};
|
|
88
104
|
|
|
89
|
-
const
|
|
105
|
+
const onInterceptPointerDown = (event: React.PointerEvent) => {
|
|
90
106
|
event.stopPropagation();
|
|
91
107
|
};
|
|
92
108
|
|
|
@@ -107,33 +123,31 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
107
123
|
event.stopPropagation();
|
|
108
124
|
};
|
|
109
125
|
|
|
110
|
-
const
|
|
126
|
+
const onPopoutTab = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
|
111
127
|
if (selectedTabNode !== undefined) {
|
|
112
|
-
layout.doAction(Actions.
|
|
128
|
+
layout.doAction(Actions.popoutTab(selectedTabNode.getId()));
|
|
129
|
+
// layout.doAction(Actions.popoutTabset(node.getId()));
|
|
113
130
|
}
|
|
114
131
|
event.stopPropagation();
|
|
115
132
|
};
|
|
116
133
|
|
|
117
|
-
const onDoubleClick = (event:
|
|
134
|
+
const onDoubleClick = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
|
118
135
|
if (node.canMaximize()) {
|
|
119
136
|
layout.maximize(node);
|
|
120
137
|
}
|
|
121
138
|
};
|
|
122
139
|
|
|
123
140
|
// Start Render
|
|
141
|
+
|
|
124
142
|
const cm = layout.getClassName;
|
|
125
143
|
|
|
126
144
|
// tabbar inner can get shifted left via tab rename, this resets scrollleft to 0
|
|
127
|
-
if (
|
|
128
|
-
|
|
145
|
+
if (tabStripInnerRef.current !== null && tabStripInnerRef.current!.scrollLeft !== 0) {
|
|
146
|
+
tabStripInnerRef.current.scrollLeft = 0;
|
|
129
147
|
}
|
|
130
148
|
|
|
131
149
|
const selectedTabNode: TabNode = node.getSelectedNode() as TabNode;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (node.getModel().getMaximizedTabset() !== undefined && !node.isMaximized()) {
|
|
135
|
-
hideElement(style, node.getModel().isUseVisibility())
|
|
136
|
-
}
|
|
150
|
+
const path = node.getPath();
|
|
137
151
|
|
|
138
152
|
const tabs = [];
|
|
139
153
|
if (node.isEnableTabStrip()) {
|
|
@@ -147,30 +161,23 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
147
161
|
path={path + "/tb" + i}
|
|
148
162
|
key={child.getId()}
|
|
149
163
|
selected={isSelected}
|
|
150
|
-
iconFactory={iconFactory}
|
|
151
|
-
titleFactory={titleFactory}
|
|
152
|
-
icons={icons}
|
|
153
164
|
/>);
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
165
|
+
if (i < node.getChildren().length - 1) {
|
|
166
|
+
tabs.push(
|
|
167
|
+
<div key={"divider" + i} className={cm(CLASSES.FLEXLAYOUT__TABSET_TAB_DIVIDER)}></div>
|
|
168
|
+
);
|
|
169
|
+
}
|
|
159
170
|
}
|
|
160
171
|
}
|
|
161
172
|
|
|
162
|
-
const showHeader = node.getName() !== undefined;
|
|
163
173
|
let stickyButtons: React.ReactNode[] = [];
|
|
164
174
|
let buttons: React.ReactNode[] = [];
|
|
165
|
-
let headerButtons: React.ReactNode[] = [];
|
|
166
175
|
|
|
167
176
|
// allow customization of header contents and buttons
|
|
168
|
-
const renderState
|
|
177
|
+
const renderState: ITabSetRenderValues = { stickyButtons, buttons, overflowPosition: undefined };
|
|
169
178
|
layout.customizeTabSet(node, renderState);
|
|
170
|
-
const headerContent = renderState.headerContent;
|
|
171
179
|
stickyButtons = renderState.stickyButtons;
|
|
172
180
|
buttons = renderState.buttons;
|
|
173
|
-
headerButtons = renderState.headerButtons;
|
|
174
181
|
|
|
175
182
|
const isTabStretch = node.isEnableSingleTabStretch() && node.getChildren().length === 1;
|
|
176
183
|
const showClose = (isTabStretch && ((node.getChildren()[0] as TabNode).isEnableClose())) || node.isEnableClose();
|
|
@@ -178,16 +185,15 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
178
185
|
if (renderState.overflowPosition === undefined) {
|
|
179
186
|
renderState.overflowPosition = stickyButtons.length;
|
|
180
187
|
}
|
|
181
|
-
|
|
188
|
+
|
|
182
189
|
if (stickyButtons.length > 0) {
|
|
183
|
-
if (tabsTruncated || isTabStretch) {
|
|
190
|
+
if (!node.isEnableTabWrap() && (tabsTruncated || isTabStretch)) {
|
|
184
191
|
buttons = [...stickyButtons, ...buttons];
|
|
185
192
|
} else {
|
|
186
193
|
tabs.push(<div
|
|
187
194
|
ref={stickyButtonsRef}
|
|
188
195
|
key="sticky_buttons_container"
|
|
189
|
-
|
|
190
|
-
onTouchStart={onInterceptMouseDown}
|
|
196
|
+
onPointerDown={onInterceptPointerDown}
|
|
191
197
|
onDragStart={(e) => { e.preventDefault() }}
|
|
192
198
|
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_STICKY_BUTTONS_CONTAINER)}
|
|
193
199
|
>
|
|
@@ -195,64 +201,67 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
195
201
|
</div>);
|
|
196
202
|
}
|
|
197
203
|
}
|
|
198
|
-
|
|
199
|
-
if (
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
204
|
+
|
|
205
|
+
if (!node.isEnableTabWrap()) {
|
|
206
|
+
if (hiddenTabs.length > 0) {
|
|
207
|
+
const overflowTitle = layout.i18nName(I18nLabel.Overflow_Menu_Tooltip);
|
|
208
|
+
let overflowContent;
|
|
209
|
+
if (typeof icons.more === "function") {
|
|
210
|
+
overflowContent = icons.more(node, hiddenTabs);
|
|
211
|
+
} else {
|
|
212
|
+
overflowContent = (<>
|
|
213
|
+
{icons.more}
|
|
214
|
+
<div className={cm(CLASSES.FLEXLAYOUT__TAB_BUTTON_OVERFLOW_COUNT)}>{hiddenTabs.length}</div>
|
|
215
|
+
</>);
|
|
216
|
+
}
|
|
217
|
+
buttons.splice(Math.min(renderState.overflowPosition, buttons.length), 0,
|
|
218
|
+
<button
|
|
219
|
+
key="overflowbutton"
|
|
220
|
+
data-layout-path={path + "/button/overflow"}
|
|
221
|
+
|
|
222
|
+
ref={overflowbuttonRef}
|
|
223
|
+
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON) + " " + cm(CLASSES.FLEXLAYOUT__TAB_BUTTON_OVERFLOW)}
|
|
224
|
+
title={overflowTitle}
|
|
225
|
+
onClick={onOverflowClick}
|
|
226
|
+
onPointerDown={onInterceptPointerDown}
|
|
227
|
+
>
|
|
228
|
+
{overflowContent}
|
|
229
|
+
</button>
|
|
230
|
+
);
|
|
209
231
|
}
|
|
210
|
-
buttons.splice(Math.min(renderState.overflowPosition, buttons.length), 0,
|
|
211
|
-
<button
|
|
212
|
-
key="overflowbutton"
|
|
213
|
-
data-layout-path={path + "/button/overflow"}
|
|
214
|
-
|
|
215
|
-
ref={overflowbuttonRef}
|
|
216
|
-
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON) + " " + cm(CLASSES.FLEXLAYOUT__TAB_BUTTON_OVERFLOW)}
|
|
217
|
-
title={overflowTitle}
|
|
218
|
-
onClick={onOverflowClick}
|
|
219
|
-
onMouseDown={onInterceptMouseDown}
|
|
220
|
-
onTouchStart={onInterceptMouseDown}
|
|
221
|
-
>
|
|
222
|
-
{overflowContent}
|
|
223
|
-
</button>
|
|
224
|
-
);
|
|
225
232
|
}
|
|
226
233
|
|
|
227
|
-
if (selectedTabNode !== undefined &&
|
|
228
|
-
|
|
234
|
+
if (selectedTabNode !== undefined &&
|
|
235
|
+
layout.isSupportsPopout() &&
|
|
236
|
+
selectedTabNode.isEnablePopout() &&
|
|
237
|
+
selectedTabNode.isEnablePopoutIcon() ) {
|
|
238
|
+
|
|
239
|
+
const popoutTitle = layout.i18nName(I18nLabel.Popout_Tab);
|
|
229
240
|
buttons.push(
|
|
230
241
|
<button
|
|
231
|
-
key="
|
|
232
|
-
data-layout-path={path + "/button/
|
|
233
|
-
title={
|
|
242
|
+
key="popout"
|
|
243
|
+
data-layout-path={path + "/button/popout"}
|
|
244
|
+
title={popoutTitle}
|
|
234
245
|
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON) + " " + cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON_FLOAT)}
|
|
235
|
-
onClick={
|
|
236
|
-
|
|
237
|
-
onTouchStart={onInterceptMouseDown}
|
|
246
|
+
onClick={onPopoutTab}
|
|
247
|
+
onPointerDown={onInterceptPointerDown}
|
|
238
248
|
>
|
|
239
249
|
{(typeof icons.popout === "function") ? icons.popout(selectedTabNode) : icons.popout}
|
|
240
250
|
</button>
|
|
241
251
|
);
|
|
242
252
|
}
|
|
253
|
+
|
|
243
254
|
if (node.canMaximize()) {
|
|
244
255
|
const minTitle = layout.i18nName(I18nLabel.Restore);
|
|
245
256
|
const maxTitle = layout.i18nName(I18nLabel.Maximize);
|
|
246
|
-
|
|
247
|
-
btns.push(
|
|
257
|
+
buttons.push(
|
|
248
258
|
<button
|
|
249
259
|
key="max"
|
|
250
260
|
data-layout-path={path + "/button/max"}
|
|
251
261
|
title={node.isMaximized() ? minTitle : maxTitle}
|
|
252
262
|
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON) + " " + cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON_ + (node.isMaximized() ? "max" : "min"))}
|
|
253
263
|
onClick={onMaximizeToggle}
|
|
254
|
-
|
|
255
|
-
onTouchStart={onInterceptMouseDown}
|
|
264
|
+
onPointerDown={onInterceptPointerDown}
|
|
256
265
|
>
|
|
257
266
|
{node.isMaximized() ?
|
|
258
267
|
(typeof icons.restore === "function") ? icons.restore(node) : icons.restore :
|
|
@@ -263,34 +272,44 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
263
272
|
|
|
264
273
|
if (!node.isMaximized() && showClose) {
|
|
265
274
|
const title = isTabStretch ? layout.i18nName(I18nLabel.Close_Tab) : layout.i18nName(I18nLabel.Close_Tabset);
|
|
266
|
-
|
|
267
|
-
btns.push(
|
|
275
|
+
buttons.push(
|
|
268
276
|
<button
|
|
269
277
|
key="close"
|
|
270
278
|
data-layout-path={path + "/button/close"}
|
|
271
279
|
title={title}
|
|
272
280
|
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON) + " " + cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON_CLOSE)}
|
|
273
281
|
onClick={isTabStretch ? onCloseTab : onClose}
|
|
274
|
-
|
|
275
|
-
onTouchStart={onInterceptMouseDown}
|
|
282
|
+
onPointerDown={onInterceptPointerDown}
|
|
276
283
|
>
|
|
277
284
|
{(typeof icons.closeTabset === "function") ? icons.closeTabset(node) : icons.closeTabset}
|
|
278
285
|
</button>
|
|
279
286
|
);
|
|
280
287
|
}
|
|
281
288
|
|
|
282
|
-
|
|
283
|
-
|
|
289
|
+
if (node.isActive() && node.isEnableActiveIcon()) {
|
|
290
|
+
const title = layout.i18nName(I18nLabel.Active_Tabset);
|
|
291
|
+
buttons.push(
|
|
292
|
+
<div
|
|
293
|
+
key="active"
|
|
294
|
+
data-layout-path={path + "/button/active"}
|
|
295
|
+
title={title}
|
|
296
|
+
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_ICON) }
|
|
297
|
+
>
|
|
298
|
+
{(typeof icons.activeTabset === "function") ? icons.activeTabset(node) : icons.activeTabset}
|
|
299
|
+
</div>
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const buttonbar = (
|
|
304
|
+
<div key="buttonbar" ref={buttonBarRef}
|
|
284
305
|
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR)}
|
|
285
|
-
|
|
286
|
-
onTouchStart={onInterceptMouseDown}
|
|
306
|
+
onPointerDown={onInterceptPointerDown}
|
|
287
307
|
onDragStart={(e) => { e.preventDefault() }}
|
|
288
308
|
>
|
|
289
309
|
{buttons}
|
|
290
310
|
</div>
|
|
291
311
|
);
|
|
292
312
|
|
|
293
|
-
let header;
|
|
294
313
|
let tabStrip;
|
|
295
314
|
|
|
296
315
|
let tabStripClasses = cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_OUTER);
|
|
@@ -299,111 +318,133 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
299
318
|
}
|
|
300
319
|
tabStripClasses += " " + CLASSES.FLEXLAYOUT__TABSET_TABBAR_OUTER_ + node.getTabLocation();
|
|
301
320
|
|
|
302
|
-
if (node.isActive()
|
|
321
|
+
if (node.isActive()) {
|
|
303
322
|
tabStripClasses += " " + cm(CLASSES.FLEXLAYOUT__TABSET_SELECTED);
|
|
304
323
|
}
|
|
305
324
|
|
|
306
|
-
if (node.isMaximized()
|
|
325
|
+
if (node.isMaximized()) {
|
|
307
326
|
tabStripClasses += " " + cm(CLASSES.FLEXLAYOUT__TABSET_MAXIMIZED);
|
|
308
327
|
}
|
|
309
328
|
|
|
310
329
|
if (isTabStretch) {
|
|
311
|
-
const tabNode = node.getChildren()[0] as TabNode;
|
|
330
|
+
const tabNode = node.getChildren()[0] as TabNode;
|
|
312
331
|
if (tabNode.getTabSetClassName() !== undefined) {
|
|
313
332
|
tabStripClasses += " " + tabNode.getTabSetClassName();
|
|
314
333
|
}
|
|
315
334
|
}
|
|
316
335
|
|
|
317
|
-
if (
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
if (node.isActive()) {
|
|
332
|
-
tabHeaderClasses += " " + cm(CLASSES.FLEXLAYOUT__TABSET_SELECTED);
|
|
333
|
-
}
|
|
334
|
-
if (node.isMaximized()) {
|
|
335
|
-
tabHeaderClasses += " " + cm(CLASSES.FLEXLAYOUT__TABSET_MAXIMIZED);
|
|
336
|
-
}
|
|
337
|
-
if (node.getClassNameHeader() !== undefined) {
|
|
338
|
-
tabHeaderClasses += " " + node.getClassNameHeader();
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
header = (
|
|
342
|
-
<div className={tabHeaderClasses} style={{ height: node.getHeaderHeight() + "px" }}
|
|
343
|
-
data-layout-path={path + "/header"}
|
|
344
|
-
onMouseDown={onMouseDown}
|
|
345
|
-
onContextMenu={onContextMenu}
|
|
346
|
-
onClick={onAuxMouseClick}
|
|
347
|
-
onAuxClick={onAuxMouseClick}
|
|
348
|
-
onTouchStart={onMouseDown}>
|
|
349
|
-
<div className={cm(CLASSES.FLEXLAYOUT__TABSET_HEADER_CONTENT)}>{headerContent}</div>
|
|
350
|
-
{headerToolbar}
|
|
351
|
-
</div>
|
|
352
|
-
);
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
const tabStripStyle: { [key: string]: string } = { height: node.getTabStripHeight() + "px" };
|
|
356
|
-
tabStrip = (
|
|
357
|
-
<div className={tabStripClasses} style={tabStripStyle}
|
|
358
|
-
data-layout-path={path + "/tabstrip"}
|
|
359
|
-
onMouseDown={onMouseDown}
|
|
360
|
-
onContextMenu={onContextMenu}
|
|
361
|
-
onClick={onAuxMouseClick}
|
|
362
|
-
onAuxClick={onAuxMouseClick}
|
|
363
|
-
onTouchStart={onMouseDown}>
|
|
364
|
-
<div ref={tabbarInnerRef} className={cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_INNER) + " " + cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_INNER_ + node.getTabLocation())}>
|
|
365
|
-
<div
|
|
366
|
-
style={{ left: position, width: (isTabStretch? "100%": "10000px")}}
|
|
367
|
-
className={cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_INNER_TAB_CONTAINER) + " " + cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_INNER_TAB_CONTAINER_ + node.getTabLocation())}
|
|
336
|
+
if (node.isEnableTabWrap()) {
|
|
337
|
+
if (node.isEnableTabStrip()) {
|
|
338
|
+
tabStrip = (
|
|
339
|
+
<div className={tabStripClasses}
|
|
340
|
+
style={{ flexWrap: "wrap", gap:"1px", marginTop:"2px" }}
|
|
341
|
+
ref={tabStripRef}
|
|
342
|
+
data-layout-path={path + "/tabstrip"}
|
|
343
|
+
onPointerDown={onPointerDown}
|
|
344
|
+
onDoubleClick={onDoubleClick}
|
|
345
|
+
onContextMenu={onContextMenu}
|
|
346
|
+
onClick={onAuxMouseClick}
|
|
347
|
+
onAuxClick={onAuxMouseClick}
|
|
348
|
+
draggable={true}
|
|
349
|
+
onDragStart={onDragStart}
|
|
368
350
|
>
|
|
369
351
|
{tabs}
|
|
352
|
+
<div style={{ flexGrow: 1 }} />
|
|
353
|
+
{buttonbar}
|
|
370
354
|
</div>
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
} else {
|
|
358
|
+
if (node.isEnableTabStrip()) {
|
|
359
|
+
tabStrip = (
|
|
360
|
+
<div className={tabStripClasses}
|
|
361
|
+
ref={tabStripRef}
|
|
362
|
+
data-layout-path={path + "/tabstrip"}
|
|
363
|
+
onPointerDown={onPointerDown}
|
|
364
|
+
onDoubleClick={onDoubleClick}
|
|
365
|
+
onContextMenu={onContextMenu}
|
|
366
|
+
onClick={onAuxMouseClick}
|
|
367
|
+
onAuxClick={onAuxMouseClick}
|
|
368
|
+
draggable={true}
|
|
369
|
+
onWheel={onMouseWheel}
|
|
370
|
+
onDragStart={onDragStart}
|
|
371
|
+
>
|
|
372
|
+
<div ref={tabStripInnerRef} className={cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_INNER) + " " + cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_INNER_ + node.getTabLocation())}>
|
|
373
|
+
<div
|
|
374
|
+
style={{ left: position, width: (isTabStretch ? "100%" : "10000px") }}
|
|
375
|
+
className={cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_INNER_TAB_CONTAINER) + " " + cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_INNER_TAB_CONTAINER_ + node.getTabLocation())}
|
|
376
|
+
>
|
|
377
|
+
{tabs}
|
|
378
|
+
</div>
|
|
379
|
+
</div>
|
|
380
|
+
{buttonbar}
|
|
381
|
+
</div>
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
377
385
|
|
|
378
|
-
var
|
|
386
|
+
var emptyTabset: React.ReactNode;
|
|
379
387
|
if (node.getChildren().length === 0) {
|
|
380
388
|
const placeHolderCallback = layout.getTabSetPlaceHolderCallback();
|
|
381
389
|
if (placeHolderCallback) {
|
|
382
|
-
|
|
390
|
+
emptyTabset = placeHolderCallback(node);
|
|
383
391
|
}
|
|
384
392
|
}
|
|
385
393
|
|
|
386
|
-
|
|
387
|
-
{
|
|
394
|
+
let content = <div ref={contentRef} className={cm(CLASSES.FLEXLAYOUT__TABSET_CONTENT)}>
|
|
395
|
+
{emptyTabset}
|
|
388
396
|
</div>
|
|
389
397
|
|
|
390
|
-
var content;
|
|
391
398
|
if (node.getTabLocation() === "top") {
|
|
392
|
-
content = <>{
|
|
399
|
+
content = <>{tabStrip}{content}</>;
|
|
393
400
|
} else {
|
|
394
|
-
content = <>{
|
|
401
|
+
content = <>{content}{tabStrip}</>;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
let style: Record<string, any> = {
|
|
405
|
+
flexGrow: Math.max(1, node.getWeight() * 1000),
|
|
406
|
+
minWidth: node.getMinWidth(),
|
|
407
|
+
minHeight: node.getMinHeight(),
|
|
408
|
+
maxWidth: node.getMaxWidth(),
|
|
409
|
+
maxHeight: node.getMaxHeight()
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
if (node.getModel().getMaximizedTabset(layout.getWindowId()) !== undefined && !node.isMaximized()) {
|
|
413
|
+
style.display = "none";
|
|
395
414
|
}
|
|
396
415
|
|
|
397
|
-
|
|
416
|
+
// note: tabset container is needed to allow flexbox to size without border/padding/margin
|
|
417
|
+
// then inner tabset can have border/padding/margin for styling
|
|
418
|
+
const tabset = (
|
|
398
419
|
<div ref={selfRef}
|
|
399
|
-
|
|
400
|
-
data-layout-path={path}
|
|
420
|
+
className={cm(CLASSES.FLEXLAYOUT__TABSET_CONTAINER)}
|
|
401
421
|
style={style}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
422
|
+
>
|
|
423
|
+
<div className={cm(CLASSES.FLEXLAYOUT__TABSET)}
|
|
424
|
+
data-layout-path={path}
|
|
425
|
+
>
|
|
426
|
+
{content}
|
|
427
|
+
</div>
|
|
405
428
|
</div>
|
|
406
429
|
);
|
|
430
|
+
|
|
431
|
+
if (node.isMaximized()) {
|
|
432
|
+
if (layout.getMainElement()) {
|
|
433
|
+
return createPortal(
|
|
434
|
+
<div style={{
|
|
435
|
+
position: "absolute",
|
|
436
|
+
display: "flex",
|
|
437
|
+
top: 0, left: 0, bottom: 0, right: 0
|
|
438
|
+
}}>
|
|
439
|
+
{tabset}
|
|
440
|
+
</div>, layout.getMainElement()!);
|
|
441
|
+
} else {
|
|
442
|
+
return tabset;
|
|
443
|
+
}
|
|
444
|
+
} else {
|
|
445
|
+
return tabset;
|
|
446
|
+
}
|
|
447
|
+
|
|
407
448
|
};
|
|
408
449
|
|
|
409
450
|
|