flexlayout-react 0.7.10 → 0.7.11
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 +7 -0
- package/README.md +4 -2
- package/declarations/Types.d.ts +4 -0
- package/declarations/model/IJsonModel.d.ts +3 -0
- package/declarations/model/Model.d.ts +7 -0
- package/declarations/view/Layout.d.ts +1 -0
- package/dist/flexlayout.js +7 -7
- package/dist/flexlayout_min.js +1 -1
- package/lib/Types.js +4 -0
- package/lib/Types.js.map +1 -1
- package/lib/model/Model.js +21 -3
- package/lib/model/Model.js.map +1 -1
- package/lib/view/BorderButton.js +10 -1
- package/lib/view/BorderButton.js.map +1 -1
- package/lib/view/BorderTabSet.js +13 -10
- package/lib/view/BorderTabSet.js.map +1 -1
- package/lib/view/Layout.js +4 -4
- package/lib/view/Layout.js.map +1 -1
- package/lib/view/TabSet.js +13 -10
- package/lib/view/TabSet.js.map +1 -1
- package/lib/view/Utils.js +10 -2
- package/lib/view/Utils.js.map +1 -1
- package/package.json +1 -1
- package/src/Types.ts +5 -0
- package/src/model/IJsonModel.ts +5 -0
- package/src/model/Model.ts +27 -4
- package/src/view/BorderButton.tsx +10 -1
- package/src/view/BorderTabSet.tsx +24 -20
- package/src/view/Layout.tsx +9 -6
- package/src/view/TabSet.tsx +24 -20
- package/src/view/Utils.tsx +10 -2
- package/style/light.css +544 -544
package/src/model/Model.ts
CHANGED
|
@@ -52,15 +52,16 @@ export class Model {
|
|
|
52
52
|
const attributeDefinitions = new AttributeDefinitions();
|
|
53
53
|
|
|
54
54
|
attributeDefinitions.add("legacyOverflowMenu", false).setType(Attribute.BOOLEAN);
|
|
55
|
-
|
|
56
|
-
// splitter
|
|
57
|
-
attributeDefinitions.add("splitterSize", -1).setType(Attribute.NUMBER);
|
|
58
|
-
attributeDefinitions.add("splitterExtra", 0).setType(Attribute.NUMBER);
|
|
59
55
|
attributeDefinitions.add("enableEdgeDock", true).setType(Attribute.BOOLEAN);
|
|
60
56
|
attributeDefinitions.add("rootOrientationVertical", false).setType(Attribute.BOOLEAN);
|
|
61
57
|
attributeDefinitions.add("marginInsets", { top: 0, right: 0, bottom: 0, left: 0 })
|
|
62
58
|
.setType("IInsets");
|
|
63
59
|
attributeDefinitions.add("enableUseVisibility", false).setType(Attribute.BOOLEAN);
|
|
60
|
+
attributeDefinitions.add("enableRotateBorderIcons", true).setType(Attribute.BOOLEAN);
|
|
61
|
+
|
|
62
|
+
// splitter
|
|
63
|
+
attributeDefinitions.add("splitterSize", -1).setType(Attribute.NUMBER);
|
|
64
|
+
attributeDefinitions.add("splitterExtra", 0).setType(Attribute.NUMBER);
|
|
64
65
|
|
|
65
66
|
// tab
|
|
66
67
|
attributeDefinitions.add("tabEnableClose", true).setType(Attribute.BOOLEAN);
|
|
@@ -207,6 +208,10 @@ export class Model {
|
|
|
207
208
|
return this._attributes.enableUseVisibility as boolean;
|
|
208
209
|
}
|
|
209
210
|
|
|
211
|
+
isEnableRotateBorderIcons() {
|
|
212
|
+
return this._attributes.enableRotateBorderIcons as boolean;
|
|
213
|
+
}
|
|
214
|
+
|
|
210
215
|
/**
|
|
211
216
|
* Gets the
|
|
212
217
|
* @returns {BorderSet|*}
|
|
@@ -247,6 +252,24 @@ export class Model {
|
|
|
247
252
|
return this._idMap[id];
|
|
248
253
|
}
|
|
249
254
|
|
|
255
|
+
/**
|
|
256
|
+
* Finds the first/top left tab set of the given node.
|
|
257
|
+
* @param node The top node you want to begin searching from, deafults to the root node
|
|
258
|
+
* @returns The first Tab Set
|
|
259
|
+
*/
|
|
260
|
+
getFirstTabSet(node = this._root as Node): Node
|
|
261
|
+
{
|
|
262
|
+
const child = node.getChildren()[0];
|
|
263
|
+
if (child instanceof TabSetNode)
|
|
264
|
+
{
|
|
265
|
+
return child;
|
|
266
|
+
}
|
|
267
|
+
else
|
|
268
|
+
{
|
|
269
|
+
return this.getFirstTabSet(child);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
250
273
|
/**
|
|
251
274
|
* Update the node tree by performing the given action,
|
|
252
275
|
* Actions should be generated via static methods on the Actions class
|
|
@@ -137,7 +137,16 @@ export const BorderButton = (props: IBorderButtonProps) => {
|
|
|
137
137
|
classNames += " " + node.getClassName();
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
let iconAngle = 0;
|
|
141
|
+
if (node.getModel().isEnableRotateBorderIcons() === false) {
|
|
142
|
+
if (border === "left") {
|
|
143
|
+
iconAngle = 90;
|
|
144
|
+
} else if (border === "right") {
|
|
145
|
+
iconAngle = -90;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const renderState = getRenderStateEx(layout, node, iconFactory, titleFactory, iconAngle);
|
|
141
150
|
|
|
142
151
|
let content = renderState.content ? (
|
|
143
152
|
<div className={cm(CLASSES.FLEXLAYOUT__BORDER_BUTTON_CONTENT)}>
|
|
@@ -3,7 +3,7 @@ import { DockLocation } from "../DockLocation";
|
|
|
3
3
|
import { BorderNode } from "../model/BorderNode";
|
|
4
4
|
import { TabNode } from "../model/TabNode";
|
|
5
5
|
import { BorderButton } from "./BorderButton";
|
|
6
|
-
import { IIcons, ILayoutCallbacks, ITitleObject } from "./Layout";
|
|
6
|
+
import { IIcons, ILayoutCallbacks, ITabSetRenderValues, ITitleObject } from "./Layout";
|
|
7
7
|
import { showPopup } from "../PopupMenu";
|
|
8
8
|
import { Actions } from "../model/Actions";
|
|
9
9
|
import { I18nLabel } from "../I18nLabel";
|
|
@@ -117,9 +117,30 @@ export const BorderTabSet = (props: IBorderTabSetProps) => {
|
|
|
117
117
|
// allow customization of tabset right/bottom buttons
|
|
118
118
|
let buttons: any[] = [];
|
|
119
119
|
let stickyButtons: any[] = [];
|
|
120
|
-
const renderState = { headerContent: undefined, buttons, stickyButtons: stickyButtons, headerButtons: [] };
|
|
120
|
+
const renderState : ITabSetRenderValues= { headerContent: undefined, buttons, stickyButtons: stickyButtons, headerButtons: [], overflowPosition: undefined };
|
|
121
121
|
layout.customizeTabSet(border, renderState);
|
|
122
122
|
buttons = renderState.buttons;
|
|
123
|
+
|
|
124
|
+
if (renderState.overflowPosition === undefined) {
|
|
125
|
+
renderState.overflowPosition = stickyButtons.length;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (stickyButtons.length > 0) {
|
|
129
|
+
if (tabsTruncated) {
|
|
130
|
+
buttons = [...stickyButtons, ...buttons];
|
|
131
|
+
} else {
|
|
132
|
+
tabs.push(<div
|
|
133
|
+
ref={stickyButtonsRef}
|
|
134
|
+
key="sticky_buttons_container"
|
|
135
|
+
onMouseDown={onInterceptMouseDown}
|
|
136
|
+
onTouchStart={onInterceptMouseDown}
|
|
137
|
+
onDragStart={(e) => { e.preventDefault() }}
|
|
138
|
+
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_STICKY_BUTTONS_CONTAINER)}
|
|
139
|
+
>
|
|
140
|
+
{stickyButtons}
|
|
141
|
+
</div>);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
123
144
|
|
|
124
145
|
if (hiddenTabs.length > 0) {
|
|
125
146
|
const overflowTitle = layout.i18nName(I18nLabel.Overflow_Menu_Tooltip);
|
|
@@ -132,7 +153,7 @@ export const BorderTabSet = (props: IBorderTabSetProps) => {
|
|
|
132
153
|
<div className={cm(CLASSES.FLEXLAYOUT__TAB_BUTTON_OVERFLOW_COUNT)}>{hiddenTabs.length}</div>
|
|
133
154
|
</>);
|
|
134
155
|
}
|
|
135
|
-
buttons.
|
|
156
|
+
buttons.splice(Math.min(renderState.overflowPosition, buttons.length), 0,
|
|
136
157
|
<button
|
|
137
158
|
key="overflowbutton"
|
|
138
159
|
ref={overflowbuttonRef}
|
|
@@ -146,23 +167,6 @@ export const BorderTabSet = (props: IBorderTabSetProps) => {
|
|
|
146
167
|
</button>
|
|
147
168
|
);
|
|
148
169
|
}
|
|
149
|
-
|
|
150
|
-
if (stickyButtons.length > 0) {
|
|
151
|
-
if (tabsTruncated) {
|
|
152
|
-
buttons = [...stickyButtons, ...buttons];
|
|
153
|
-
} else {
|
|
154
|
-
tabs.push(<div
|
|
155
|
-
ref={stickyButtonsRef}
|
|
156
|
-
key="sticky_buttons_container"
|
|
157
|
-
onMouseDown={onInterceptMouseDown}
|
|
158
|
-
onTouchStart={onInterceptMouseDown}
|
|
159
|
-
onDragStart={(e) => { e.preventDefault() }}
|
|
160
|
-
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_STICKY_BUTTONS_CONTAINER)}
|
|
161
|
-
>
|
|
162
|
-
{stickyButtons}
|
|
163
|
-
</div>);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
170
|
|
|
167
171
|
const selectedIndex = border.getSelected();
|
|
168
172
|
if (selectedIndex !== -1) {
|
package/src/view/Layout.tsx
CHANGED
|
@@ -101,6 +101,9 @@ export interface ITabSetRenderValues {
|
|
|
101
101
|
stickyButtons: React.ReactNode[];
|
|
102
102
|
buttons: React.ReactNode[];
|
|
103
103
|
headerButtons: React.ReactNode[];
|
|
104
|
+
// position to insert overflow button within [...stickyButtons, ...buttons]
|
|
105
|
+
// if left undefined position will be after the sticky buttons (if any)
|
|
106
|
+
overflowPosition: number | undefined;
|
|
104
107
|
}
|
|
105
108
|
|
|
106
109
|
export interface ITabRenderValues {
|
|
@@ -510,10 +513,10 @@ export class Layout extends React.Component<ILayoutProps, ILayoutState> {
|
|
|
510
513
|
const offset = this.edgeRectLength / 2;
|
|
511
514
|
const className = this.getClassName(CLASSES.FLEXLAYOUT__EDGE_RECT);
|
|
512
515
|
const radius = 50;
|
|
513
|
-
edges.push(<div key="North" style={{ top: r.y, left: r.x + r.width / 2 - offset, width: length, height: width, borderBottomLeftRadius: radius, borderBottomRightRadius: radius }} className={className}></div>)
|
|
514
|
-
edges.push(<div key="West" style={{ top: r.y + r.height / 2 - offset, left: r.x, width: width, height: length, borderTopRightRadius: radius, borderBottomRightRadius: radius }} className={className}></div>)
|
|
515
|
-
edges.push(<div key="South" style={{ top: r.y + r.height - width, left: r.x + r.width / 2 - offset, width: length, height: width, borderTopLeftRadius: radius, borderTopRightRadius: radius }} className={className}></div>)
|
|
516
|
-
edges.push(<div key="East" style={{ top: r.y + r.height / 2 - offset, left: r.x + r.width - width, width: width, height: length, borderTopLeftRadius: radius, borderBottomLeftRadius: radius }} className={className}></div>)
|
|
516
|
+
edges.push(<div key="North" style={{ top: r.y, left: r.x + r.width / 2 - offset, width: length, height: width, borderBottomLeftRadius: radius, borderBottomRightRadius: radius }} className={className + " " + this.getClassName(CLASSES.FLEXLAYOUT__EDGE_RECT_TOP)}></div>);
|
|
517
|
+
edges.push(<div key="West" style={{ top: r.y + r.height / 2 - offset, left: r.x, width: width, height: length, borderTopRightRadius: radius, borderBottomRightRadius: radius }} className={className + " " + this.getClassName(CLASSES.FLEXLAYOUT__EDGE_RECT_LEFT)}></div>);
|
|
518
|
+
edges.push(<div key="South" style={{ top: r.y + r.height - width, left: r.x + r.width / 2 - offset, width: length, height: width, borderTopLeftRadius: radius, borderTopRightRadius: radius }} className={className + " " + this.getClassName(CLASSES.FLEXLAYOUT__EDGE_RECT_BOTTOM)}></div>);
|
|
519
|
+
edges.push(<div key="East" style={{ top: r.y + r.height / 2 - offset, left: r.x + r.width - width, width: width, height: length, borderTopLeftRadius: radius, borderBottomLeftRadius: radius }} className={className + " " + this.getClassName(CLASSES.FLEXLAYOUT__EDGE_RECT_RIGHT)}></div>);
|
|
517
520
|
}
|
|
518
521
|
|
|
519
522
|
// this.layoutTime = (Date.now() - this.start);
|
|
@@ -596,8 +599,8 @@ export class Layout extends React.Component<ILayoutProps, ILayoutState> {
|
|
|
596
599
|
if (this.supportsPopout && child.isFloating()) {
|
|
597
600
|
const rect = this._getScreenRect(child);
|
|
598
601
|
|
|
599
|
-
const tabBorderWidth= child._getAttr("borderWidth");
|
|
600
|
-
const tabBorderHeight= child._getAttr("borderHeight");
|
|
602
|
+
const tabBorderWidth = child._getAttr("borderWidth");
|
|
603
|
+
const tabBorderHeight = child._getAttr("borderHeight");
|
|
601
604
|
if (tabBorderWidth !== -1 && border.getLocation().getOrientation() === Orientation.HORZ) {
|
|
602
605
|
rect.width = tabBorderWidth;
|
|
603
606
|
} else if (tabBorderHeight !== -1 && border.getLocation().getOrientation() === Orientation.VERT) {
|
package/src/view/TabSet.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import { Actions } from "../model/Actions";
|
|
|
4
4
|
import { TabNode } from "../model/TabNode";
|
|
5
5
|
import { TabSetNode } from "../model/TabSetNode";
|
|
6
6
|
import { showPopup } from "../PopupMenu";
|
|
7
|
-
import { IIcons, ILayoutCallbacks, ITitleObject } from "./Layout";
|
|
7
|
+
import { IIcons, ILayoutCallbacks, ITabSetRenderValues, ITitleObject } from "./Layout";
|
|
8
8
|
import { TabButton } from "./TabButton";
|
|
9
9
|
import { useTabOverflow } from "./TabOverflowHook";
|
|
10
10
|
import { Orientation } from "../Orientation";
|
|
@@ -160,13 +160,34 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
160
160
|
let headerButtons: React.ReactNode[] = [];
|
|
161
161
|
|
|
162
162
|
// allow customization of header contents and buttons
|
|
163
|
-
const renderState = { headerContent: node.getName(), stickyButtons, buttons, headerButtons };
|
|
163
|
+
const renderState : ITabSetRenderValues = { headerContent: node.getName(), stickyButtons, buttons, headerButtons, overflowPosition: undefined };
|
|
164
164
|
layout.customizeTabSet(node, renderState);
|
|
165
165
|
const headerContent = renderState.headerContent;
|
|
166
166
|
stickyButtons = renderState.stickyButtons;
|
|
167
167
|
buttons = renderState.buttons;
|
|
168
168
|
headerButtons = renderState.headerButtons;
|
|
169
169
|
|
|
170
|
+
if (renderState.overflowPosition === undefined) {
|
|
171
|
+
renderState.overflowPosition = stickyButtons.length;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (stickyButtons.length > 0) {
|
|
175
|
+
if (tabsTruncated) {
|
|
176
|
+
buttons = [...stickyButtons, ...buttons];
|
|
177
|
+
} else {
|
|
178
|
+
tabs.push(<div
|
|
179
|
+
ref={stickyButtonsRef}
|
|
180
|
+
key="sticky_buttons_container"
|
|
181
|
+
onMouseDown={onInterceptMouseDown}
|
|
182
|
+
onTouchStart={onInterceptMouseDown}
|
|
183
|
+
onDragStart={(e) => { e.preventDefault() }}
|
|
184
|
+
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_STICKY_BUTTONS_CONTAINER)}
|
|
185
|
+
>
|
|
186
|
+
{stickyButtons}
|
|
187
|
+
</div>);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
170
191
|
if (hiddenTabs.length > 0) {
|
|
171
192
|
const overflowTitle = layout.i18nName(I18nLabel.Overflow_Menu_Tooltip);
|
|
172
193
|
let overflowContent;
|
|
@@ -178,7 +199,7 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
178
199
|
<div className={cm(CLASSES.FLEXLAYOUT__TAB_BUTTON_OVERFLOW_COUNT)}>{hiddenTabs.length}</div>
|
|
179
200
|
</>);
|
|
180
201
|
}
|
|
181
|
-
buttons.
|
|
202
|
+
buttons.splice(Math.min(renderState.overflowPosition, buttons.length), 0,
|
|
182
203
|
<button
|
|
183
204
|
key="overflowbutton"
|
|
184
205
|
data-layout-path={path + "/button/overflow"}
|
|
@@ -195,23 +216,6 @@ export const TabSet = (props: ITabSetProps) => {
|
|
|
195
216
|
);
|
|
196
217
|
}
|
|
197
218
|
|
|
198
|
-
if (stickyButtons.length > 0) {
|
|
199
|
-
if (tabsTruncated) {
|
|
200
|
-
buttons = [...stickyButtons, ...buttons];
|
|
201
|
-
} else {
|
|
202
|
-
tabs.push(<div
|
|
203
|
-
ref={stickyButtonsRef}
|
|
204
|
-
key="sticky_buttons_container"
|
|
205
|
-
onMouseDown={onInterceptMouseDown}
|
|
206
|
-
onTouchStart={onInterceptMouseDown}
|
|
207
|
-
onDragStart={(e) => { e.preventDefault() }}
|
|
208
|
-
className={cm(CLASSES.FLEXLAYOUT__TAB_TOOLBAR_STICKY_BUTTONS_CONTAINER)}
|
|
209
|
-
>
|
|
210
|
-
{stickyButtons}
|
|
211
|
-
</div>);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
219
|
if (selectedTabNode !== undefined && layout.isSupportsPopout() && selectedTabNode.isEnableFloat() && !selectedTabNode.isFloating()) {
|
|
216
220
|
const floatTitle = layout.i18nName(I18nLabel.Float_Tab);
|
|
217
221
|
buttons.push(
|
package/src/view/Utils.tsx
CHANGED
|
@@ -7,11 +7,15 @@ export function getRenderStateEx(
|
|
|
7
7
|
layout: ILayoutCallbacks,
|
|
8
8
|
node: TabNode,
|
|
9
9
|
iconFactory?: IconFactory,
|
|
10
|
-
titleFactory?: TitleFactory
|
|
10
|
+
titleFactory?: TitleFactory,
|
|
11
|
+
iconAngle?: number
|
|
11
12
|
) {
|
|
12
13
|
let leadingContent = iconFactory ? iconFactory(node) : undefined;
|
|
13
14
|
let titleContent: React.ReactNode = node.getName();
|
|
14
15
|
let name = node.getName();
|
|
16
|
+
if (iconAngle === undefined) {
|
|
17
|
+
iconAngle = 0;
|
|
18
|
+
}
|
|
15
19
|
|
|
16
20
|
function isTitleObject(obj: any): obj is ITitleObject {
|
|
17
21
|
return obj.titleContent !== undefined
|
|
@@ -33,7 +37,11 @@ export function getRenderStateEx(
|
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
if (leadingContent === undefined && node.getIcon() !== undefined) {
|
|
36
|
-
|
|
40
|
+
if (iconAngle !== 0) {
|
|
41
|
+
leadingContent = <img style={{ width: "1em", height: "1em", transform: "rotate(" + iconAngle + "deg)" }} src={node.getIcon()} alt="leadingContent" />;
|
|
42
|
+
} else {
|
|
43
|
+
leadingContent = <img style={{ width: "1em", height: "1em" }} src={node.getIcon()} alt="leadingContent" />;
|
|
44
|
+
}
|
|
37
45
|
}
|
|
38
46
|
|
|
39
47
|
let buttons: any[] = [];
|