flexlayout-react 0.7.15 → 0.8.1
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 +28 -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 +140 -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 +459 -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 +129 -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 +919 -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 +127 -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 +272 -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 +303 -242
- package/src/model/Utils.ts +6 -32
- package/src/view/BorderButton.tsx +36 -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 +1053 -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 +39 -54
- package/src/view/TabButtonStamp.tsx +5 -9
- package/src/view/TabOverflowHook.tsx +14 -9
- package/src/view/TabSet.tsx +221 -176
- package/src/view/Utils.tsx +119 -39
- package/style/_base.scss +140 -34
- package/style/dark.css +140 -35
- package/style/dark.css.map +1 -1
- package/style/dark.scss +3 -1
- package/style/gray.css +139 -34
- package/style/gray.css.map +1 -1
- package/style/gray.scss +2 -0
- package/style/light.css +141 -36
- 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 +139 -34
- 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,20 @@ 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
|
+
if (node.isEnableDrag()) {
|
|
77
|
+
event.stopPropagation();
|
|
78
|
+
layout.setDragNode(event.nativeEvent, node as TabSetNode);
|
|
79
|
+
} else {
|
|
80
|
+
event.preventDefault();
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
event.preventDefault();
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const onPointerDown = (event: React.PointerEvent<HTMLElement>) => {
|
|
60
88
|
if (!isAuxMouseEvent(event)) {
|
|
61
89
|
let name = node.getName();
|
|
62
90
|
if (name === undefined) {
|
|
@@ -64,29 +92,21 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
64
92
|
} else {
|
|
65
93
|
name = ": " + name;
|
|
66
94
|
}
|
|
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
|
-
}
|
|
95
|
+
layout.doAction(Actions.setActiveTabset(node.getId(), layout.getWindowId()));
|
|
76
96
|
}
|
|
77
97
|
};
|
|
78
98
|
|
|
79
|
-
const onAuxMouseClick = (event: React.MouseEvent<
|
|
99
|
+
const onAuxMouseClick = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
|
80
100
|
if (isAuxMouseEvent(event)) {
|
|
81
101
|
layout.auxMouseClick(node, event);
|
|
82
102
|
}
|
|
83
103
|
};
|
|
84
104
|
|
|
85
|
-
const onContextMenu = (event: React.MouseEvent<
|
|
105
|
+
const onContextMenu = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
|
86
106
|
layout.showContextMenu(node, event);
|
|
87
107
|
};
|
|
88
108
|
|
|
89
|
-
const
|
|
109
|
+
const onInterceptPointerDown = (event: React.PointerEvent) => {
|
|
90
110
|
event.stopPropagation();
|
|
91
111
|
};
|
|
92
112
|
|
|
@@ -107,33 +127,31 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
107
127
|
event.stopPropagation();
|
|
108
128
|
};
|
|
109
129
|
|
|
110
|
-
const
|
|
130
|
+
const onPopoutTab = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
|
111
131
|
if (selectedTabNode !== undefined) {
|
|
112
|
-
layout.doAction(Actions.
|
|
132
|
+
layout.doAction(Actions.popoutTab(selectedTabNode.getId()));
|
|
133
|
+
// layout.doAction(Actions.popoutTabset(node.getId()));
|
|
113
134
|
}
|
|
114
135
|
event.stopPropagation();
|
|
115
136
|
};
|
|
116
137
|
|
|
117
|
-
const onDoubleClick = (event:
|
|
138
|
+
const onDoubleClick = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
|
118
139
|
if (node.canMaximize()) {
|
|
119
140
|
layout.maximize(node);
|
|
120
141
|
}
|
|
121
142
|
};
|
|
122
143
|
|
|
123
144
|
// Start Render
|
|
145
|
+
|
|
124
146
|
const cm = layout.getClassName;
|
|
125
147
|
|
|
126
148
|
// tabbar inner can get shifted left via tab rename, this resets scrollleft to 0
|
|
127
|
-
if (
|
|
128
|
-
|
|
149
|
+
if (tabStripInnerRef.current !== null && tabStripInnerRef.current!.scrollLeft !== 0) {
|
|
150
|
+
tabStripInnerRef.current.scrollLeft = 0;
|
|
129
151
|
}
|
|
130
152
|
|
|
131
153
|
const selectedTabNode: TabNode = node.getSelectedNode() as TabNode;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (node.getModel().getMaximizedTabset() !== undefined && !node.isMaximized()) {
|
|
135
|
-
hideElement(style, node.getModel().isUseVisibility())
|
|
136
|
-
}
|
|
154
|
+
const path = node.getPath();
|
|
137
155
|
|
|
138
156
|
const tabs = [];
|
|
139
157
|
if (node.isEnableTabStrip()) {
|
|
@@ -147,30 +165,23 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
147
165
|
path={path + "/tb" + i}
|
|
148
166
|
key={child.getId()}
|
|
149
167
|
selected={isSelected}
|
|
150
|
-
iconFactory={iconFactory}
|
|
151
|
-
titleFactory={titleFactory}
|
|
152
|
-
icons={icons}
|
|
153
168
|
/>);
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
169
|
+
if (i < node.getChildren().length - 1) {
|
|
170
|
+
tabs.push(
|
|
171
|
+
<div key={"divider" + i} className={cm(CLASSES.FLEXLAYOUT__TABSET_TAB_DIVIDER)}></div>
|
|
172
|
+
);
|
|
173
|
+
}
|
|
159
174
|
}
|
|
160
175
|
}
|
|
161
176
|
|
|
162
|
-
const showHeader = node.getName() !== undefined;
|
|
163
177
|
let stickyButtons: React.ReactNode[] = [];
|
|
164
178
|
let buttons: React.ReactNode[] = [];
|
|
165
|
-
let headerButtons: React.ReactNode[] = [];
|
|
166
179
|
|
|
167
180
|
// allow customization of header contents and buttons
|
|
168
|
-
const renderState
|
|
181
|
+
const renderState: ITabSetRenderValues = { stickyButtons, buttons, overflowPosition: undefined };
|
|
169
182
|
layout.customizeTabSet(node, renderState);
|
|
170
|
-
const headerContent = renderState.headerContent;
|
|
171
183
|
stickyButtons = renderState.stickyButtons;
|
|
172
184
|
buttons = renderState.buttons;
|
|
173
|
-
headerButtons = renderState.headerButtons;
|
|
174
185
|
|
|
175
186
|
const isTabStretch = node.isEnableSingleTabStretch() && node.getChildren().length === 1;
|
|
176
187
|
const showClose = (isTabStretch && ((node.getChildren()[0] as TabNode).isEnableClose())) || node.isEnableClose();
|
|
@@ -178,16 +189,15 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
178
189
|
if (renderState.overflowPosition === undefined) {
|
|
179
190
|
renderState.overflowPosition = stickyButtons.length;
|
|
180
191
|
}
|
|
181
|
-
|
|
192
|
+
|
|
182
193
|
if (stickyButtons.length > 0) {
|
|
183
|
-
if (tabsTruncated || isTabStretch) {
|
|
194
|
+
if (!node.isEnableTabWrap() && (tabsTruncated || isTabStretch)) {
|
|
184
195
|
buttons = [...stickyButtons, ...buttons];
|
|
185
196
|
} else {
|
|
186
197
|
tabs.push(<div
|
|
187
198
|
ref={stickyButtonsRef}
|
|
188
199
|
key="sticky_buttons_container"
|
|
189
|
-
|
|
190
|
-
onTouchStart={onInterceptMouseDown}
|
|
200
|
+
onPointerDown={onInterceptPointerDown}
|
|
191
201
|
onDragStart={(e) => { e.preventDefault() }}
|
|
192
202
|
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_STICKY_BUTTONS_CONTAINER)}
|
|
193
203
|
>
|
|
@@ -195,64 +205,67 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
195
205
|
</div>);
|
|
196
206
|
}
|
|
197
207
|
}
|
|
198
|
-
|
|
199
|
-
if (
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
208
|
+
|
|
209
|
+
if (!node.isEnableTabWrap()) {
|
|
210
|
+
if (hiddenTabs.length > 0) {
|
|
211
|
+
const overflowTitle = layout.i18nName(I18nLabel.Overflow_Menu_Tooltip);
|
|
212
|
+
let overflowContent;
|
|
213
|
+
if (typeof icons.more === "function") {
|
|
214
|
+
overflowContent = icons.more(node, hiddenTabs);
|
|
215
|
+
} else {
|
|
216
|
+
overflowContent = (<>
|
|
217
|
+
{icons.more}
|
|
218
|
+
<div className={cm(CLASSES.FLEXLAYOUT__TAB_BUTTON_OVERFLOW_COUNT)}>{hiddenTabs.length}</div>
|
|
219
|
+
</>);
|
|
220
|
+
}
|
|
221
|
+
buttons.splice(Math.min(renderState.overflowPosition, buttons.length), 0,
|
|
222
|
+
<button
|
|
223
|
+
key="overflowbutton"
|
|
224
|
+
data-layout-path={path + "/button/overflow"}
|
|
225
|
+
|
|
226
|
+
ref={overflowbuttonRef}
|
|
227
|
+
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON) + " " + cm(CLASSES.FLEXLAYOUT__TAB_BUTTON_OVERFLOW)}
|
|
228
|
+
title={overflowTitle}
|
|
229
|
+
onClick={onOverflowClick}
|
|
230
|
+
onPointerDown={onInterceptPointerDown}
|
|
231
|
+
>
|
|
232
|
+
{overflowContent}
|
|
233
|
+
</button>
|
|
234
|
+
);
|
|
209
235
|
}
|
|
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
236
|
}
|
|
226
237
|
|
|
227
|
-
if (selectedTabNode !== undefined &&
|
|
228
|
-
|
|
238
|
+
if (selectedTabNode !== undefined &&
|
|
239
|
+
layout.isSupportsPopout() &&
|
|
240
|
+
selectedTabNode.isEnablePopout() &&
|
|
241
|
+
selectedTabNode.isEnablePopoutIcon() ) {
|
|
242
|
+
|
|
243
|
+
const popoutTitle = layout.i18nName(I18nLabel.Popout_Tab);
|
|
229
244
|
buttons.push(
|
|
230
245
|
<button
|
|
231
|
-
key="
|
|
232
|
-
data-layout-path={path + "/button/
|
|
233
|
-
title={
|
|
246
|
+
key="popout"
|
|
247
|
+
data-layout-path={path + "/button/popout"}
|
|
248
|
+
title={popoutTitle}
|
|
234
249
|
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON) + " " + cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON_FLOAT)}
|
|
235
|
-
onClick={
|
|
236
|
-
|
|
237
|
-
onTouchStart={onInterceptMouseDown}
|
|
250
|
+
onClick={onPopoutTab}
|
|
251
|
+
onPointerDown={onInterceptPointerDown}
|
|
238
252
|
>
|
|
239
253
|
{(typeof icons.popout === "function") ? icons.popout(selectedTabNode) : icons.popout}
|
|
240
254
|
</button>
|
|
241
255
|
);
|
|
242
256
|
}
|
|
257
|
+
|
|
243
258
|
if (node.canMaximize()) {
|
|
244
259
|
const minTitle = layout.i18nName(I18nLabel.Restore);
|
|
245
260
|
const maxTitle = layout.i18nName(I18nLabel.Maximize);
|
|
246
|
-
|
|
247
|
-
btns.push(
|
|
261
|
+
buttons.push(
|
|
248
262
|
<button
|
|
249
263
|
key="max"
|
|
250
264
|
data-layout-path={path + "/button/max"}
|
|
251
265
|
title={node.isMaximized() ? minTitle : maxTitle}
|
|
252
266
|
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON) + " " + cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON_ + (node.isMaximized() ? "max" : "min"))}
|
|
253
267
|
onClick={onMaximizeToggle}
|
|
254
|
-
|
|
255
|
-
onTouchStart={onInterceptMouseDown}
|
|
268
|
+
onPointerDown={onInterceptPointerDown}
|
|
256
269
|
>
|
|
257
270
|
{node.isMaximized() ?
|
|
258
271
|
(typeof icons.restore === "function") ? icons.restore(node) : icons.restore :
|
|
@@ -263,34 +276,44 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
263
276
|
|
|
264
277
|
if (!node.isMaximized() && showClose) {
|
|
265
278
|
const title = isTabStretch ? layout.i18nName(I18nLabel.Close_Tab) : layout.i18nName(I18nLabel.Close_Tabset);
|
|
266
|
-
|
|
267
|
-
btns.push(
|
|
279
|
+
buttons.push(
|
|
268
280
|
<button
|
|
269
281
|
key="close"
|
|
270
282
|
data-layout-path={path + "/button/close"}
|
|
271
283
|
title={title}
|
|
272
284
|
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON) + " " + cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_BUTTON_CLOSE)}
|
|
273
285
|
onClick={isTabStretch ? onCloseTab : onClose}
|
|
274
|
-
|
|
275
|
-
onTouchStart={onInterceptMouseDown}
|
|
286
|
+
onPointerDown={onInterceptPointerDown}
|
|
276
287
|
>
|
|
277
288
|
{(typeof icons.closeTabset === "function") ? icons.closeTabset(node) : icons.closeTabset}
|
|
278
289
|
</button>
|
|
279
290
|
);
|
|
280
291
|
}
|
|
281
292
|
|
|
282
|
-
|
|
283
|
-
|
|
293
|
+
if (node.isActive() && node.isEnableActiveIcon()) {
|
|
294
|
+
const title = layout.i18nName(I18nLabel.Active_Tabset);
|
|
295
|
+
buttons.push(
|
|
296
|
+
<div
|
|
297
|
+
key="active"
|
|
298
|
+
data-layout-path={path + "/button/active"}
|
|
299
|
+
title={title}
|
|
300
|
+
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_ICON) }
|
|
301
|
+
>
|
|
302
|
+
{(typeof icons.activeTabset === "function") ? icons.activeTabset(node) : icons.activeTabset}
|
|
303
|
+
</div>
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const buttonbar = (
|
|
308
|
+
<div key="buttonbar" ref={buttonBarRef}
|
|
284
309
|
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR)}
|
|
285
|
-
|
|
286
|
-
onTouchStart={onInterceptMouseDown}
|
|
310
|
+
onPointerDown={onInterceptPointerDown}
|
|
287
311
|
onDragStart={(e) => { e.preventDefault() }}
|
|
288
312
|
>
|
|
289
313
|
{buttons}
|
|
290
314
|
</div>
|
|
291
315
|
);
|
|
292
316
|
|
|
293
|
-
let header;
|
|
294
317
|
let tabStrip;
|
|
295
318
|
|
|
296
319
|
let tabStripClasses = cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_OUTER);
|
|
@@ -299,111 +322,133 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
299
322
|
}
|
|
300
323
|
tabStripClasses += " " + CLASSES.FLEXLAYOUT__TABSET_TABBAR_OUTER_ + node.getTabLocation();
|
|
301
324
|
|
|
302
|
-
if (node.isActive()
|
|
325
|
+
if (node.isActive()) {
|
|
303
326
|
tabStripClasses += " " + cm(CLASSES.FLEXLAYOUT__TABSET_SELECTED);
|
|
304
327
|
}
|
|
305
328
|
|
|
306
|
-
if (node.isMaximized()
|
|
329
|
+
if (node.isMaximized()) {
|
|
307
330
|
tabStripClasses += " " + cm(CLASSES.FLEXLAYOUT__TABSET_MAXIMIZED);
|
|
308
331
|
}
|
|
309
332
|
|
|
310
333
|
if (isTabStretch) {
|
|
311
|
-
const tabNode = node.getChildren()[0] as TabNode;
|
|
334
|
+
const tabNode = node.getChildren()[0] as TabNode;
|
|
312
335
|
if (tabNode.getTabSetClassName() !== undefined) {
|
|
313
336
|
tabStripClasses += " " + tabNode.getTabSetClassName();
|
|
314
337
|
}
|
|
315
338
|
}
|
|
316
339
|
|
|
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())}
|
|
340
|
+
if (node.isEnableTabWrap()) {
|
|
341
|
+
if (node.isEnableTabStrip()) {
|
|
342
|
+
tabStrip = (
|
|
343
|
+
<div className={tabStripClasses}
|
|
344
|
+
style={{ flexWrap: "wrap", gap:"1px", marginTop:"2px" }}
|
|
345
|
+
ref={tabStripRef}
|
|
346
|
+
data-layout-path={path + "/tabstrip"}
|
|
347
|
+
onPointerDown={onPointerDown}
|
|
348
|
+
onDoubleClick={onDoubleClick}
|
|
349
|
+
onContextMenu={onContextMenu}
|
|
350
|
+
onClick={onAuxMouseClick}
|
|
351
|
+
onAuxClick={onAuxMouseClick}
|
|
352
|
+
draggable={true}
|
|
353
|
+
onDragStart={onDragStart}
|
|
368
354
|
>
|
|
369
355
|
{tabs}
|
|
356
|
+
<div style={{ flexGrow: 1 }} />
|
|
357
|
+
{buttonbar}
|
|
370
358
|
</div>
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
} else {
|
|
362
|
+
if (node.isEnableTabStrip()) {
|
|
363
|
+
tabStrip = (
|
|
364
|
+
<div className={tabStripClasses}
|
|
365
|
+
ref={tabStripRef}
|
|
366
|
+
data-layout-path={path + "/tabstrip"}
|
|
367
|
+
onPointerDown={onPointerDown}
|
|
368
|
+
onDoubleClick={onDoubleClick}
|
|
369
|
+
onContextMenu={onContextMenu}
|
|
370
|
+
onClick={onAuxMouseClick}
|
|
371
|
+
onAuxClick={onAuxMouseClick}
|
|
372
|
+
draggable={true}
|
|
373
|
+
onWheel={onMouseWheel}
|
|
374
|
+
onDragStart={onDragStart}
|
|
375
|
+
>
|
|
376
|
+
<div ref={tabStripInnerRef} className={cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_INNER) + " " + cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_INNER_ + node.getTabLocation())}>
|
|
377
|
+
<div
|
|
378
|
+
style={{ left: position, width: (isTabStretch ? "100%" : "10000px") }}
|
|
379
|
+
className={cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_INNER_TAB_CONTAINER) + " " + cm(CLASSES.FLEXLAYOUT__TABSET_TABBAR_INNER_TAB_CONTAINER_ + node.getTabLocation())}
|
|
380
|
+
>
|
|
381
|
+
{tabs}
|
|
382
|
+
</div>
|
|
383
|
+
</div>
|
|
384
|
+
{buttonbar}
|
|
385
|
+
</div>
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
377
389
|
|
|
378
|
-
var
|
|
390
|
+
var emptyTabset: React.ReactNode;
|
|
379
391
|
if (node.getChildren().length === 0) {
|
|
380
392
|
const placeHolderCallback = layout.getTabSetPlaceHolderCallback();
|
|
381
393
|
if (placeHolderCallback) {
|
|
382
|
-
|
|
394
|
+
emptyTabset = placeHolderCallback(node);
|
|
383
395
|
}
|
|
384
396
|
}
|
|
385
397
|
|
|
386
|
-
|
|
387
|
-
{
|
|
398
|
+
let content = <div ref={contentRef} className={cm(CLASSES.FLEXLAYOUT__TABSET_CONTENT)}>
|
|
399
|
+
{emptyTabset}
|
|
388
400
|
</div>
|
|
389
401
|
|
|
390
|
-
var content;
|
|
391
402
|
if (node.getTabLocation() === "top") {
|
|
392
|
-
content = <>{
|
|
403
|
+
content = <>{tabStrip}{content}</>;
|
|
393
404
|
} else {
|
|
394
|
-
content = <>{
|
|
405
|
+
content = <>{content}{tabStrip}</>;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
let style: Record<string, any> = {
|
|
409
|
+
flexGrow: Math.max(1, node.getWeight() * 1000),
|
|
410
|
+
minWidth: node.getMinWidth(),
|
|
411
|
+
minHeight: node.getMinHeight(),
|
|
412
|
+
maxWidth: node.getMaxWidth(),
|
|
413
|
+
maxHeight: node.getMaxHeight()
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
if (node.getModel().getMaximizedTabset(layout.getWindowId()) !== undefined && !node.isMaximized()) {
|
|
417
|
+
style.display = "none";
|
|
395
418
|
}
|
|
396
419
|
|
|
397
|
-
|
|
420
|
+
// note: tabset container is needed to allow flexbox to size without border/padding/margin
|
|
421
|
+
// then inner tabset can have border/padding/margin for styling
|
|
422
|
+
const tabset = (
|
|
398
423
|
<div ref={selfRef}
|
|
399
|
-
|
|
400
|
-
data-layout-path={path}
|
|
424
|
+
className={cm(CLASSES.FLEXLAYOUT__TABSET_CONTAINER)}
|
|
401
425
|
style={style}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
426
|
+
>
|
|
427
|
+
<div className={cm(CLASSES.FLEXLAYOUT__TABSET)}
|
|
428
|
+
data-layout-path={path}
|
|
429
|
+
>
|
|
430
|
+
{content}
|
|
431
|
+
</div>
|
|
405
432
|
</div>
|
|
406
433
|
);
|
|
434
|
+
|
|
435
|
+
if (node.isMaximized()) {
|
|
436
|
+
if (layout.getMainElement()) {
|
|
437
|
+
return createPortal(
|
|
438
|
+
<div style={{
|
|
439
|
+
position: "absolute",
|
|
440
|
+
display: "flex",
|
|
441
|
+
top: 0, left: 0, bottom: 0, right: 0
|
|
442
|
+
}}>
|
|
443
|
+
{tabset}
|
|
444
|
+
</div>, layout.getMainElement()!);
|
|
445
|
+
} else {
|
|
446
|
+
return tabset;
|
|
447
|
+
}
|
|
448
|
+
} else {
|
|
449
|
+
return tabset;
|
|
450
|
+
}
|
|
451
|
+
|
|
407
452
|
};
|
|
408
453
|
|
|
409
454
|
|