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.
@@ -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
- const renderState = getRenderStateEx(layout, node, iconFactory, titleFactory);
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.unshift(
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) {
@@ -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) {
@@ -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.unshift(
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(
@@ -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
- leadingContent = <img style={{ width: "1em", height: "1em" }} src={node.getIcon()} alt="leadingContent" />;
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[] = [];