flexlayout-react 0.5.19 → 0.6.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 +22 -0
- package/README.md +61 -56
- package/declarations/Types.d.ts +1 -0
- package/declarations/model/IJsonModel.d.ts +3 -0
- package/declarations/model/Model.d.ts +2 -0
- package/declarations/view/Icons.d.ts +6 -0
- package/declarations/view/Layout.d.ts +6 -4
- package/declarations/view/MenuTabButton.d.ts +1 -0
- package/declarations/view/TabButtonStamp.d.ts +1 -0
- package/declarations/view/Utils.d.ts +1 -0
- package/dist/flexlayout.js +50 -14
- package/dist/flexlayout_min.js +1 -1
- package/lib/PopupMenu.js +11 -7
- package/lib/PopupMenu.js.map +1 -1
- package/lib/Types.js +1 -0
- package/lib/Types.js.map +1 -1
- package/lib/model/Model.js +8 -0
- package/lib/model/Model.js.map +1 -1
- package/lib/model/TabNode.js +6 -1
- package/lib/model/TabNode.js.map +1 -1
- package/lib/view/BorderButton.js +11 -41
- package/lib/view/BorderButton.js.map +1 -1
- package/lib/view/BorderTabSet.js +7 -7
- package/lib/view/BorderTabSet.js.map +1 -1
- package/lib/view/FloatingWindow.js +13 -5
- package/lib/view/FloatingWindow.js.map +1 -1
- package/lib/view/Icons.js +36 -0
- package/lib/view/Icons.js.map +1 -0
- package/lib/view/Layout.js +80 -25
- package/lib/view/Layout.js.map +1 -1
- package/lib/view/MenuTabButton.js +22 -0
- package/lib/view/MenuTabButton.js.map +1 -0
- package/lib/view/Splitter.js +3 -3
- package/lib/view/Splitter.js.map +1 -1
- package/lib/view/Tab.js +9 -6
- package/lib/view/Tab.js.map +1 -1
- package/lib/view/TabButton.js +13 -46
- package/lib/view/TabButton.js.map +1 -1
- package/lib/view/TabButtonStamp.js +22 -0
- package/lib/view/TabButtonStamp.js.map +1 -0
- package/lib/view/TabFloating.js +7 -5
- package/lib/view/TabFloating.js.map +1 -1
- package/lib/view/TabOverflowHook.js +1 -1
- package/lib/view/TabSet.js +15 -25
- package/lib/view/TabSet.js.map +1 -1
- package/lib/view/Utils.js +61 -0
- package/lib/view/Utils.js.map +1 -0
- package/package.json +11 -6
- package/src/I18nLabel.ts +1 -1
- package/src/PopupMenu.tsx +30 -10
- package/src/Types.ts +1 -0
- package/src/model/IJsonModel.ts +3 -0
- package/src/model/Model.ts +12 -0
- package/src/model/TabNode.ts +6 -1
- package/src/view/BorderButton.tsx +19 -43
- package/src/view/BorderTabSet.tsx +14 -4
- package/src/view/FloatingWindow.tsx +14 -6
- package/src/view/Icons.tsx +36 -0
- package/src/view/Layout.tsx +108 -41
- package/src/view/Splitter.tsx +4 -1
- package/src/view/Tab.tsx +17 -6
- package/src/view/TabButton.tsx +27 -55
- package/src/view/TabButtonStamp.tsx +47 -0
- package/src/view/TabFloating.tsx +12 -5
- package/src/view/TabOverflowHook.tsx +1 -1
- package/src/view/TabSet.tsx +27 -17
- package/src/view/Utils.tsx +71 -0
- package/style/_base.scss +82 -52
- package/style/dark.css +82 -76
- package/style/dark.css.map +1 -1
- package/style/dark.scss +15 -5
- package/style/gray.css +79 -73
- package/style/gray.css.map +1 -1
- package/style/gray.scss +10 -3
- package/style/light.css +83 -77
- package/style/light.css.map +1 -1
- package/style/light.scss +16 -6
- package/images/close.png +0 -0
- package/images/maximize.png +0 -0
- package/images/more.png +0 -0
- package/images/more2.png +0 -0
- package/images/popout.png +0 -0
- package/images/restore.png +0 -0
package/src/PopupMenu.tsx
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import * as ReactDOM from "react-dom";
|
|
3
2
|
import { DragDrop } from ".";
|
|
4
3
|
import TabNode from "./model/TabNode";
|
|
5
4
|
import { CLASSES } from "./Types";
|
|
5
|
+
import { ILayoutCallbacks } from "./view/Layout";
|
|
6
|
+
import { TabButtonStamp } from "./view/TabButtonStamp";
|
|
6
7
|
|
|
7
8
|
/** @hidden @internal */
|
|
8
9
|
export function showPopup(
|
|
9
|
-
layoutDiv: HTMLDivElement,
|
|
10
10
|
triggerElement: Element,
|
|
11
11
|
items: { index: number; node: TabNode }[],
|
|
12
12
|
onSelect: (item: { index: number; node: TabNode }) => void,
|
|
13
|
-
|
|
13
|
+
layout: ILayoutCallbacks,
|
|
14
|
+
iconFactory?: (node: TabNode) => React.ReactNode | undefined,
|
|
15
|
+
titleFactory?: (node: TabNode) => React.ReactNode | undefined,
|
|
14
16
|
) {
|
|
17
|
+
const layoutDiv = layout.getRootDiv();
|
|
18
|
+
const classNameMapper = layout.getClassName;
|
|
15
19
|
const currentDocument = triggerElement.ownerDocument;
|
|
16
20
|
const triggerRect = triggerElement.getBoundingClientRect();
|
|
17
21
|
const layoutRect = layoutDiv.getBoundingClientRect();
|
|
@@ -35,9 +39,9 @@ export function showPopup(
|
|
|
35
39
|
layoutDiv.appendChild(elm);
|
|
36
40
|
|
|
37
41
|
const onHide = () => {
|
|
42
|
+
layout.hidePortal();
|
|
38
43
|
DragDrop.instance.hideGlass();
|
|
39
44
|
layoutDiv.removeChild(elm);
|
|
40
|
-
ReactDOM.unmountComponentAtNode(elm);
|
|
41
45
|
elm.removeEventListener("mousedown", onElementMouseDown);
|
|
42
46
|
currentDocument.removeEventListener("mousedown", onDocMouseDown);
|
|
43
47
|
};
|
|
@@ -53,12 +57,15 @@ export function showPopup(
|
|
|
53
57
|
elm.addEventListener("mousedown", onElementMouseDown);
|
|
54
58
|
currentDocument.addEventListener("mousedown", onDocMouseDown);
|
|
55
59
|
|
|
56
|
-
|
|
60
|
+
layout.showPortal(<PopupMenu
|
|
57
61
|
currentDocument={currentDocument}
|
|
58
62
|
onSelect={onSelect}
|
|
59
63
|
onHide={onHide}
|
|
60
64
|
items={items}
|
|
61
65
|
classNameMapper={classNameMapper}
|
|
66
|
+
layout={layout}
|
|
67
|
+
iconFactory={iconFactory}
|
|
68
|
+
titleFactory={titleFactory}
|
|
62
69
|
/>, elm);
|
|
63
70
|
}
|
|
64
71
|
|
|
@@ -69,11 +76,14 @@ interface IPopupMenuProps {
|
|
|
69
76
|
onHide: () => void;
|
|
70
77
|
onSelect: (item: { index: number; node: TabNode }) => void;
|
|
71
78
|
classNameMapper: (defaultClassName: string) => string;
|
|
79
|
+
layout: ILayoutCallbacks;
|
|
80
|
+
iconFactory?: (node: TabNode) => React.ReactNode | undefined;
|
|
81
|
+
titleFactory?: (node: TabNode) => React.ReactNode | undefined;
|
|
72
82
|
}
|
|
73
83
|
|
|
74
84
|
/** @hidden @internal */
|
|
75
85
|
const PopupMenu = (props: IPopupMenuProps) => {
|
|
76
|
-
const { items, onHide, onSelect, classNameMapper } = props;
|
|
86
|
+
const { items, onHide, onSelect, classNameMapper, layout, iconFactory, titleFactory} = props;
|
|
77
87
|
|
|
78
88
|
const onItemClick = (item: { index: number; node: TabNode }, event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
|
79
89
|
onSelect(item);
|
|
@@ -81,17 +91,27 @@ const PopupMenu = (props: IPopupMenuProps) => {
|
|
|
81
91
|
event.stopPropagation();
|
|
82
92
|
};
|
|
83
93
|
|
|
84
|
-
const itemElements = items.map((item) => (
|
|
94
|
+
const itemElements = items.map((item, i) => (
|
|
85
95
|
<div key={item.index}
|
|
86
96
|
className={classNameMapper(CLASSES.FLEXLAYOUT__POPUP_MENU_ITEM)}
|
|
97
|
+
data-layout-path={"/popup-menu/tb" + i}
|
|
87
98
|
onClick={(event) => onItemClick(item, event)}
|
|
88
|
-
title={item.node.getHelpText()}>
|
|
89
|
-
{item.node.
|
|
99
|
+
title={item.node.getHelpText()} >
|
|
100
|
+
{item.node.getModel().isLegacyOverflowMenu() ?
|
|
101
|
+
item.node._getNameForOverflowMenu() :
|
|
102
|
+
<TabButtonStamp
|
|
103
|
+
node={item.node}
|
|
104
|
+
layout={layout}
|
|
105
|
+
iconFactory={iconFactory}
|
|
106
|
+
titleFactory={titleFactory}
|
|
107
|
+
/>}
|
|
90
108
|
</div>
|
|
91
109
|
));
|
|
92
110
|
|
|
93
111
|
return (
|
|
94
|
-
<div className={classNameMapper(CLASSES.FLEXLAYOUT__POPUP_MENU)}
|
|
112
|
+
<div className={classNameMapper(CLASSES.FLEXLAYOUT__POPUP_MENU)}
|
|
113
|
+
data-layout-path="/popup-menu"
|
|
114
|
+
>
|
|
95
115
|
{itemElements}
|
|
96
116
|
</div>);
|
|
97
117
|
};
|
package/src/Types.ts
CHANGED
|
@@ -70,6 +70,7 @@ export enum CLASSES {
|
|
|
70
70
|
FLEXLAYOUT__TAB_BUTTON_OVERFLOW = "flexlayout__tab_button_overflow",
|
|
71
71
|
FLEXLAYOUT__TAB_BUTTON_TEXTBOX = "flexlayout__tab_button_textbox",
|
|
72
72
|
FLEXLAYOUT__TAB_BUTTON_TRAILING = "flexlayout__tab_button_trailing",
|
|
73
|
+
FLEXLAYOUT__TAB_BUTTON_STAMP = "flexlayout__tab_button_stamp",
|
|
73
74
|
|
|
74
75
|
FLEXLAYOUT__TAB_FLOATING = "flexlayout__tab_floating",
|
|
75
76
|
FLEXLAYOUT__TAB_FLOATING_INNER = "flexlayout__tab_floating_inner",
|
package/src/model/IJsonModel.ts
CHANGED
|
@@ -40,6 +40,8 @@ export interface IGlobalAttributes {
|
|
|
40
40
|
borderMinSize?: number; // default: 0
|
|
41
41
|
borderSize?: number; // default: 200
|
|
42
42
|
enableEdgeDock?: boolean; // default: true
|
|
43
|
+
enableUseVisibility?: boolean; // default: false
|
|
44
|
+
legacyOverflowMenu?: boolean; // default: false
|
|
43
45
|
marginInsets?: IInsets; // default: {"top":0,"right":0,"bottom":0,"left":0}
|
|
44
46
|
rootOrientationVertical?: boolean; // default: false
|
|
45
47
|
splitterExtra?: number; // default: 0
|
|
@@ -108,6 +110,7 @@ export interface ITabSetAttributes {
|
|
|
108
110
|
width?: number;
|
|
109
111
|
}
|
|
110
112
|
export interface ITabAttributes {
|
|
113
|
+
altName?: string;
|
|
111
114
|
borderHeight?: number; // default: -1 - inherited from global tabBorderHeight
|
|
112
115
|
borderWidth?: number; // default: -1 - inherited from global tabBorderWidth
|
|
113
116
|
className?: string; // - inherited from global tabClassName
|
package/src/model/Model.ts
CHANGED
|
@@ -52,6 +52,9 @@ class Model {
|
|
|
52
52
|
/** @hidden @internal */
|
|
53
53
|
private static _createAttributeDefinitions(): AttributeDefinitions {
|
|
54
54
|
const attributeDefinitions = new AttributeDefinitions();
|
|
55
|
+
|
|
56
|
+
attributeDefinitions.add("legacyOverflowMenu", false).setType(Attribute.BOOLEAN);
|
|
57
|
+
|
|
55
58
|
// splitter
|
|
56
59
|
attributeDefinitions.add("splitterSize", -1).setType(Attribute.NUMBER);
|
|
57
60
|
attributeDefinitions.add("splitterExtra", 0).setType(Attribute.NUMBER);
|
|
@@ -59,6 +62,7 @@ class Model {
|
|
|
59
62
|
attributeDefinitions.add("rootOrientationVertical", false).setType(Attribute.BOOLEAN);
|
|
60
63
|
attributeDefinitions.add("marginInsets", { top: 0, right: 0, bottom: 0, left: 0 })
|
|
61
64
|
.setType("IInsets");
|
|
65
|
+
attributeDefinitions.add("enableUseVisibility", false).setType(Attribute.BOOLEAN);
|
|
62
66
|
|
|
63
67
|
// tab
|
|
64
68
|
attributeDefinitions.add("tabEnableClose", true).setType(Attribute.BOOLEAN);
|
|
@@ -201,6 +205,10 @@ class Model {
|
|
|
201
205
|
return this._attributes.rootOrientationVertical as boolean;
|
|
202
206
|
}
|
|
203
207
|
|
|
208
|
+
isUseVisibility() {
|
|
209
|
+
return this._attributes.enableUseVisibility as boolean;
|
|
210
|
+
}
|
|
211
|
+
|
|
204
212
|
/**
|
|
205
213
|
* Gets the
|
|
206
214
|
* @returns {BorderSet|*}
|
|
@@ -443,6 +451,10 @@ class Model {
|
|
|
443
451
|
return splitterSize;
|
|
444
452
|
}
|
|
445
453
|
|
|
454
|
+
isLegacyOverflowMenu() {
|
|
455
|
+
return this._attributes.legacyOverflowMenu as boolean;
|
|
456
|
+
}
|
|
457
|
+
|
|
446
458
|
getSplitterExtra() {
|
|
447
459
|
return this._attributes.splitterExtra as number;
|
|
448
460
|
}
|
package/src/model/TabNode.ts
CHANGED
|
@@ -26,6 +26,7 @@ class TabNode extends Node implements IDraggable {
|
|
|
26
26
|
attributeDefinitions.add("id", undefined).setType(Attribute.STRING);
|
|
27
27
|
|
|
28
28
|
attributeDefinitions.add("name", "[Unnamed Tab]").setType(Attribute.STRING);
|
|
29
|
+
attributeDefinitions.add("altName", undefined).setType(Attribute.STRING);
|
|
29
30
|
attributeDefinitions.add("helpText", undefined).setType(Attribute.STRING);
|
|
30
31
|
attributeDefinitions.add("component", undefined).setType(Attribute.STRING);
|
|
31
32
|
attributeDefinitions.add("config", undefined).setType("any");
|
|
@@ -84,7 +85,11 @@ class TabNode extends Node implements IDraggable {
|
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
/** @hidden @internal */
|
|
87
|
-
|
|
88
|
+
_getNameForOverflowMenu() {
|
|
89
|
+
const altName = this._getAttr("altName") as string;
|
|
90
|
+
if (altName !== undefined) {
|
|
91
|
+
return altName;
|
|
92
|
+
}
|
|
88
93
|
return this._renderedName;
|
|
89
94
|
}
|
|
90
95
|
|
|
@@ -3,10 +3,10 @@ import { I18nLabel } from "..";
|
|
|
3
3
|
import Actions from "../model/Actions";
|
|
4
4
|
import TabNode from "../model/TabNode";
|
|
5
5
|
import Rect from "../Rect";
|
|
6
|
-
import { IIcons, ILayoutCallbacks
|
|
6
|
+
import { IIcons, ILayoutCallbacks } from "./Layout";
|
|
7
7
|
import { ICloseType } from "../model/ICloseType";
|
|
8
8
|
import { CLASSES } from "../Types";
|
|
9
|
-
import { isAuxMouseEvent } from "./
|
|
9
|
+
import { getRenderStateEx, isAuxMouseEvent } from "./Utils";
|
|
10
10
|
|
|
11
11
|
/** @hidden @internal */
|
|
12
12
|
export interface IBorderButtonProps {
|
|
@@ -17,17 +17,17 @@ export interface IBorderButtonProps {
|
|
|
17
17
|
iconFactory?: (node: TabNode) => React.ReactNode | undefined;
|
|
18
18
|
titleFactory?: (node: TabNode) => React.ReactNode | undefined;
|
|
19
19
|
icons?: IIcons;
|
|
20
|
+
path: string;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
/** @hidden @internal */
|
|
23
24
|
export const BorderButton = (props: IBorderButtonProps) => {
|
|
24
|
-
const { layout, node, selected, border, iconFactory, titleFactory, icons } = props;
|
|
25
|
+
const { layout, node, selected, border, iconFactory, titleFactory, icons, path } = props;
|
|
25
26
|
const selfRef = React.useRef<HTMLDivElement | null>(null);
|
|
26
27
|
|
|
27
28
|
const onMouseDown = (event: React.MouseEvent<HTMLDivElement, MouseEvent> | React.TouchEvent<HTMLDivElement>) => {
|
|
28
29
|
if (!isAuxMouseEvent(event)) {
|
|
29
|
-
|
|
30
|
-
props.layout.dragStart(event, message, node, node.isEnableDrag(), onClick, (event2: Event) => undefined);
|
|
30
|
+
props.layout.dragStart(event, undefined, node, node.isEnableDrag(), onClick, (event2: Event) => undefined);
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
33
|
|
|
@@ -95,47 +95,22 @@ export const BorderButton = (props: IBorderButtonProps) => {
|
|
|
95
95
|
classNames += " " + node.getClassName();
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
let titleContent: React.ReactNode = node.getName();
|
|
100
|
-
let name = node.getName();
|
|
101
|
-
|
|
102
|
-
function isTitleObject(obj: any): obj is ITitleObject {
|
|
103
|
-
return obj.titleContent !== undefined
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (titleFactory !== undefined) {
|
|
107
|
-
const titleObj = titleFactory(node);
|
|
108
|
-
if (titleObj !== undefined) {
|
|
109
|
-
if (typeof titleObj === "string") {
|
|
110
|
-
titleContent = titleObj as string;
|
|
111
|
-
name = titleObj as string;
|
|
112
|
-
} else if (isTitleObject(titleObj)) {
|
|
113
|
-
titleContent = titleObj.titleContent;
|
|
114
|
-
name = titleObj.name;
|
|
115
|
-
} else {
|
|
116
|
-
titleContent = titleObj;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (typeof leadingContent === undefined && typeof node.getIcon() !== undefined) {
|
|
122
|
-
leadingContent = <img src={node.getIcon()} alt="leadingContent" />;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
let buttons: any[] = [];
|
|
126
|
-
|
|
127
|
-
// allow customization of leading contents (icon) and contents
|
|
128
|
-
const renderState = { leading: leadingContent, content: titleContent, name, buttons };
|
|
129
|
-
layout.customizeTab(node, renderState);
|
|
130
|
-
node._setRenderedName(renderState.name);
|
|
98
|
+
const renderState = getRenderStateEx(layout, node, iconFactory, titleFactory);
|
|
131
99
|
|
|
132
|
-
const content = <div className={cm(CLASSES.FLEXLAYOUT__BORDER_BUTTON_CONTENT)}>{renderState.content}</div
|
|
133
|
-
const leading = <div className={cm(CLASSES.FLEXLAYOUT__BORDER_BUTTON_LEADING)}>{renderState.leading}</div
|
|
100
|
+
const content = renderState.content ? (<div className={cm(CLASSES.FLEXLAYOUT__BORDER_BUTTON_CONTENT)}>{renderState.content}</div>) : null;
|
|
101
|
+
const leading = renderState.leading ? (<div className={cm(CLASSES.FLEXLAYOUT__BORDER_BUTTON_LEADING)}>{renderState.leading}</div>) : null;
|
|
134
102
|
|
|
135
103
|
if (node.isEnableClose()) {
|
|
136
104
|
const closeTitle = layout.i18nName(I18nLabel.Close_Tab);
|
|
137
|
-
buttons.push(
|
|
138
|
-
<div
|
|
105
|
+
renderState.buttons.push(
|
|
106
|
+
<div
|
|
107
|
+
key="close"
|
|
108
|
+
data-layout-path={path + "/button/close"}
|
|
109
|
+
title={closeTitle}
|
|
110
|
+
className={cm(CLASSES.FLEXLAYOUT__BORDER_BUTTON_TRAILING)}
|
|
111
|
+
onMouseDown={onCloseMouseDown}
|
|
112
|
+
onClick={onClose}
|
|
113
|
+
onTouchStart={onCloseMouseDown}>
|
|
139
114
|
{icons?.close}
|
|
140
115
|
</div>
|
|
141
116
|
);
|
|
@@ -143,6 +118,7 @@ export const BorderButton = (props: IBorderButtonProps) => {
|
|
|
143
118
|
|
|
144
119
|
return (
|
|
145
120
|
<div ref={selfRef} style={{}} className={classNames}
|
|
121
|
+
data-layout-path={path}
|
|
146
122
|
onMouseDown={onMouseDown}
|
|
147
123
|
onClick={onAuxMouseClick}
|
|
148
124
|
onAuxClick={onAuxMouseClick}
|
|
@@ -151,7 +127,7 @@ export const BorderButton = (props: IBorderButtonProps) => {
|
|
|
151
127
|
title={node.getHelpText()}>
|
|
152
128
|
{leading}
|
|
153
129
|
{content}
|
|
154
|
-
{buttons}
|
|
130
|
+
{renderState.buttons}
|
|
155
131
|
</div>
|
|
156
132
|
);
|
|
157
133
|
};
|
|
@@ -10,7 +10,7 @@ import { I18nLabel } from "../I18nLabel";
|
|
|
10
10
|
import { useTabOverflow } from "./TabOverflowHook";
|
|
11
11
|
import Orientation from "../Orientation";
|
|
12
12
|
import { CLASSES } from "../Types";
|
|
13
|
-
import { isAuxMouseEvent } from "./
|
|
13
|
+
import { isAuxMouseEvent } from "./Utils";
|
|
14
14
|
|
|
15
15
|
/** @hidden @internal */
|
|
16
16
|
export interface IBorderTabSetProps {
|
|
@@ -19,11 +19,12 @@ export interface IBorderTabSetProps {
|
|
|
19
19
|
iconFactory?: (node: TabNode) => React.ReactNode | undefined;
|
|
20
20
|
titleFactory?: (node: TabNode) => React.ReactNode | undefined;
|
|
21
21
|
icons?: IIcons;
|
|
22
|
+
path: string;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
/** @hidden @internal */
|
|
25
26
|
export const BorderTabSet = (props: IBorderTabSetProps) => {
|
|
26
|
-
const { border, layout, iconFactory, titleFactory, icons } = props;
|
|
27
|
+
const { border, layout, iconFactory, titleFactory, icons, path } = props;
|
|
27
28
|
|
|
28
29
|
const toolbarRef = React.useRef<HTMLDivElement | null>(null);
|
|
29
30
|
const overflowbuttonRef = React.useRef<HTMLButtonElement | null>(null);
|
|
@@ -47,7 +48,12 @@ export const BorderTabSet = (props: IBorderTabSetProps) => {
|
|
|
47
48
|
|
|
48
49
|
const onOverflowClick = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
|
49
50
|
const element = overflowbuttonRef.current!;
|
|
50
|
-
showPopup(
|
|
51
|
+
showPopup( element,
|
|
52
|
+
hiddenTabs,
|
|
53
|
+
onOverflowItemSelect,
|
|
54
|
+
layout,
|
|
55
|
+
iconFactory,
|
|
56
|
+
titleFactory);
|
|
51
57
|
event.stopPropagation();
|
|
52
58
|
};
|
|
53
59
|
|
|
@@ -78,6 +84,7 @@ export const BorderTabSet = (props: IBorderTabSetProps) => {
|
|
|
78
84
|
layout={layout}
|
|
79
85
|
border={border.getLocation().getName()}
|
|
80
86
|
node={child}
|
|
87
|
+
path={path + "/tb" + i}
|
|
81
88
|
key={child.getId()}
|
|
82
89
|
selected={isSelected}
|
|
83
90
|
iconFactory={iconFactory}
|
|
@@ -135,7 +142,9 @@ export const BorderTabSet = (props: IBorderTabSetProps) => {
|
|
|
135
142
|
onClick={onFloatTab}
|
|
136
143
|
onMouseDown={onInterceptMouseDown}
|
|
137
144
|
onTouchStart={onInterceptMouseDown}
|
|
138
|
-
|
|
145
|
+
>
|
|
146
|
+
{icons?.popout}
|
|
147
|
+
</button>
|
|
139
148
|
);
|
|
140
149
|
}
|
|
141
150
|
}
|
|
@@ -159,6 +168,7 @@ export const BorderTabSet = (props: IBorderTabSetProps) => {
|
|
|
159
168
|
|
|
160
169
|
return (
|
|
161
170
|
<div ref={selfRef} dir="ltr" style={style} className={borderClasses}
|
|
171
|
+
data-layout-path={path}
|
|
162
172
|
onClick={onAuxMouseClick}
|
|
163
173
|
onAuxClick={onAuxMouseClick}
|
|
164
174
|
onContextMenu={onContextMenu}
|
|
@@ -16,7 +16,7 @@ export interface IFloatingWindowProps {
|
|
|
16
16
|
interface IStyleSheet {
|
|
17
17
|
href: string | null;
|
|
18
18
|
type: string;
|
|
19
|
-
rules: string[];
|
|
19
|
+
rules: string[] | null;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/** @hidden @internal */
|
|
@@ -31,17 +31,23 @@ export const FloatingWindow = (props: React.PropsWithChildren<IFloatingWindowPro
|
|
|
31
31
|
// the floating window. window.document.styleSheets is mutable and we can't guarantee
|
|
32
32
|
// the styles will exist when 'popoutWindow.load' is called below.
|
|
33
33
|
const styles = Array.from(window.document.styleSheets).reduce((result, styleSheet) => {
|
|
34
|
+
let rules: CSSRuleList | undefined = undefined;
|
|
35
|
+
try {
|
|
36
|
+
rules = styleSheet.cssRules;
|
|
37
|
+
} catch (e) {
|
|
38
|
+
// styleSheet.cssRules can throw security exception
|
|
39
|
+
}
|
|
40
|
+
|
|
34
41
|
try {
|
|
35
42
|
return [
|
|
36
43
|
...result,
|
|
37
44
|
{
|
|
38
45
|
href: styleSheet.href,
|
|
39
46
|
type: styleSheet.type,
|
|
40
|
-
rules: Array.from(
|
|
47
|
+
rules: rules ? Array.from(rules).map(rule => rule.cssText) : null,
|
|
41
48
|
}
|
|
42
49
|
];
|
|
43
50
|
} catch (e) {
|
|
44
|
-
// styleSheet.cssRules can throw security exception
|
|
45
51
|
return result;
|
|
46
52
|
}
|
|
47
53
|
}, [] as IStyleSheet[]);
|
|
@@ -113,9 +119,11 @@ function copyStyles(doc: Document, styleSheets: IStyleSheet[]): Promise<boolean[
|
|
|
113
119
|
})
|
|
114
120
|
);
|
|
115
121
|
} else {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
122
|
+
if (styleSheet.rules) {
|
|
123
|
+
const style = doc.createElement("style");
|
|
124
|
+
styleSheet.rules.forEach(rule => style.appendChild(doc.createTextNode(rule)));
|
|
125
|
+
head.appendChild(style);
|
|
126
|
+
}
|
|
119
127
|
}
|
|
120
128
|
});
|
|
121
129
|
return Promise.all(promises);
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
const style = {width:"1em", height:"1em", display: "flex", alignItems:"center"};
|
|
4
|
+
|
|
5
|
+
export const CloseIcon = () => {
|
|
6
|
+
return (
|
|
7
|
+
<svg xmlns="http://www.w3.org/2000/svg" style={style} viewBox="0 0 24 24" >
|
|
8
|
+
<path fill="none" d="M0 0h24v24H0z"/>
|
|
9
|
+
<path stroke="gray" fill="gray" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
|
|
10
|
+
</svg>
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const MaximizeIcon = () => {
|
|
15
|
+
return (
|
|
16
|
+
<svg xmlns="http://www.w3.org/2000/svg" style={style} viewBox="0 0 24 24" fill="gray"><path d="M0 0h24v24H0z" fill="none"/><path stroke="gray" d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></svg>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const OverflowIcon = () => {
|
|
21
|
+
return (
|
|
22
|
+
<svg xmlns="http://www.w3.org/2000/svg" style={style} viewBox="0 0 24 24" fill="gray"><path d="M0 0h24v24H0z" fill="none"/><path stroke="gray" d="M7 10l5 5 5-5z"/></svg>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const PopoutIcon = () => {
|
|
27
|
+
return (
|
|
28
|
+
<svg xmlns="http://www.w3.org/2000/svg" style={style} viewBox="0 0 24 24" fill="gray"><path d="M0 0h24v24H0z" fill="none"/><path stroke="gray" d="M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5z"/></svg>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const RestoreIcon = () => {
|
|
33
|
+
return (
|
|
34
|
+
<svg xmlns="http://www.w3.org/2000/svg" style={style} viewBox="0 0 24 24" fill="gray"><path d="M0 0h24v24H0z" fill="none"/><path stroke="gray" d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"/></svg>
|
|
35
|
+
);
|
|
36
|
+
}
|