flexlayout-react 0.8.1 → 0.8.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flexlayout-react",
3
- "version": "0.8.1",
3
+ "version": "0.8.3",
4
4
  "description": "A multi-tab docking layout manager",
5
5
  "main": "lib/index.js",
6
6
  "types": "./declarations/index.d.ts",
@@ -38,45 +38,43 @@
38
38
  "repository": "https://github.com/caplin/FlexLayout",
39
39
  "license": "ISC",
40
40
  "peerDependencies": {
41
- "react": "^18.0.0",
42
- "react-dom": "^18.0.0"
41
+ "react": "^18.0.0 || ^19.0.0",
42
+ "react-dom": "^18.0.0 || ^19.0.0"
43
43
  },
44
44
  "eslintConfig": {
45
45
  "extends": "react-app"
46
46
  },
47
47
  "devDependencies": {
48
- "@emotion/react": "^11.13.3",
49
- "@emotion/styled": "^11.13.0",
50
- "@fontsource/roboto": "^5.0.14",
51
- "@mui/material": "^6.0.1",
52
- "@types/node": "^22.5.0",
53
- "@types/prismjs": "^1.26.4",
54
- "@types/react": "^18.3.4",
55
- "@types/react-dom": "^18.3.0",
56
- "ag-grid-community": "^32.1.0",
57
- "ag-grid-react": "^32.1.0",
58
- "chart.js": "^4.4.4",
48
+ "@emotion/react": "^11.14.0",
49
+ "@emotion/styled": "^11.14.0",
50
+ "@fontsource/roboto": "^5.1.1",
51
+ "@mui/material": "^6.4.4",
52
+ "@mui/x-data-grid": "^7.26.0",
53
+ "@types/node": "^22.13.4",
54
+ "@types/prismjs": "^1.26.5",
55
+ "@types/react": "^19.0.8",
56
+ "@types/react-dom": "^19.0.3",
57
+ "ag-grid-community": "^33.1.0",
58
+ "ag-grid-react": "^33.1.0",
59
+ "chart.js": "^4.4.7",
59
60
  "css-loader": "^7.1.2",
60
- "html-webpack-plugin": "^5.6.0",
61
- "ol": "^10.1.0",
62
- "prettier": "^3.3.3",
61
+ "html-webpack-plugin": "^5.6.3",
62
+ "ol": "^10.4.0",
63
+ "prettier": "^3.5.1",
63
64
  "prismjs": "^1.29.0",
64
- "react": "^18.3.1",
65
- "react-chartjs-2": "^5.2.0",
66
- "react-dom": "^18.3.1",
65
+ "react": "^19.0.0",
66
+ "react-chartjs-2": "^5.3.0",
67
+ "react-dom": "^19.0.0",
67
68
  "react-scripts": "5.0.1",
68
- "sass": "^1.77.8",
69
+ "sass": "^1.85.0",
69
70
  "source-map-loader": "^5.0.0",
70
71
  "style-loader": "^4.0.0",
71
- "styled-components": "^6.1.13",
72
- "ts-loader": "~9.5.1",
73
- "typedoc": "^0.26.6",
74
- "typescript": "^5.5.4",
75
- "webpack": "^5.94.0",
76
- "webpack-cli": "^5.1.4",
77
- "webpack-dev-server": "^5.0.4",
78
- "@mui/x-data-grid": "^7.15.0"
79
- },
80
- "dependencies": {
72
+ "styled-components": "^6.1.15",
73
+ "ts-loader": "~9.5.2",
74
+ "typedoc": "^0.27.7",
75
+ "typescript": "^5.7.3",
76
+ "webpack": "^5.98.0",
77
+ "webpack-cli": "^6.0.1",
78
+ "webpack-dev-server": "^5.2.0"
81
79
  }
82
80
  }
@@ -585,7 +585,7 @@ export interface ITabSetAttributes {
585
585
  enableTabStrip?: boolean;
586
586
 
587
587
  /**
588
- show tabs in location top or bottom
588
+ wrap tabs onto multiple lines
589
589
 
590
590
  Default: inherited from Global attribute tabSetEnableTabWrap (default false)
591
591
  */
@@ -4,7 +4,6 @@ import { Model } from "./Model";
4
4
  import { RowNode } from "./RowNode";
5
5
  import { Node } from "./Node";
6
6
  import { TabSetNode } from "./TabSetNode";
7
- import { keepOnScreen } from "../view/Utils";
8
7
  import { LayoutInternal } from "../view/Layout";
9
8
 
10
9
  export class LayoutWindow {
@@ -112,8 +111,7 @@ export class LayoutWindow {
112
111
  static fromJson(windowJson: IJsonPopout, model: Model, windowId: string): LayoutWindow {
113
112
  const count = model.getwindowsMap().size;
114
113
  let rect = windowJson.rect ? Rect.fromJson(windowJson.rect) : new Rect(50 + 50 * count, 50 + 50 * count, 600, 400);
115
- rect = keepOnScreen(rect); // snaps to grid of 10x10 and then moves into visible area
116
- // snapping prevents issue where window moves 1 pixel per save/restore on Chrome
114
+ rect.snap(10); // snapping prevents issue where window moves 1 pixel per save/restore on Chrome
117
115
  const layoutWindow = new LayoutWindow(windowId, rect);
118
116
  layoutWindow.root = RowNode.fromJson(windowJson.layout, model, layoutWindow);
119
117
  return layoutWindow;
@@ -16,7 +16,6 @@ import { TabNode } from "./TabNode";
16
16
  import { TabSetNode } from "./TabSetNode";
17
17
  import { randomUUID } from "./Utils";
18
18
  import { LayoutWindow } from "./LayoutWindow";
19
- import { isOnScreen } from "../view/Utils";
20
19
 
21
20
  /** @internal */
22
21
  export const DefaultMin = 0;
@@ -406,18 +405,10 @@ export class Model {
406
405
  model.borders = BorderSet.fromJson(json.borders, model);
407
406
  }
408
407
  if (json.popouts) {
409
- let i= 0;
410
- let top = 100;
411
- let left = 100;
412
408
  for (const windowId in json.popouts) {
413
409
  const windowJson = json.popouts[windowId];
414
410
  const layoutWindow = LayoutWindow.fromJson(windowJson, model, windowId);
415
411
  model.windows.set(windowId, layoutWindow);
416
- // offscreen windows will reload cascaded (since cannot reposition)
417
- if (!isOnScreen(layoutWindow.rect)) {
418
- layoutWindow.rect = new Rect(top + i*50, left+ i*50, 600, 400);
419
- i++;
420
- }
421
412
  }
422
413
  }
423
414
 
@@ -560,7 +560,7 @@ export class TabSetNode extends Node implements IDraggable, IDropTarget {
560
560
  );
561
561
 
562
562
  attributeDefinitions.addInherited("enableTabWrap", "tabSetEnableTabWrap").setDescription(
563
- `show tabs in location top or bottom`
563
+ `wrap tabs onto multiple lines`
564
564
  );
565
565
  attributeDefinitions.addInherited("tabLocation", "tabSetTabLocation").setDescription(
566
566
  `the location of the tabs either top or bottom`
@@ -85,7 +85,7 @@ export interface ILayoutProps {
85
85
  */
86
86
  export class Layout extends React.Component<ILayoutProps> {
87
87
  /** @internal */
88
- private selfRef: React.RefObject<LayoutInternal>;
88
+ private selfRef: React.RefObject<LayoutInternal | null>;
89
89
  /** @internal */
90
90
  private revision: number; // so LayoutInternal knows this is a parent render (used for optimization)
91
91
 
@@ -190,10 +190,10 @@ interface ILayoutInternalState {
190
190
  export class LayoutInternal extends React.Component<ILayoutInternalProps, ILayoutInternalState> {
191
191
  public static dragState: DragState | undefined = undefined;
192
192
 
193
- private selfRef: React.RefObject<HTMLDivElement>;
194
- private moveablesRef: React.RefObject<HTMLDivElement>;
195
- private findBorderBarSizeRef: React.RefObject<HTMLDivElement>;
196
- private mainRef: React.RefObject<HTMLDivElement>;
193
+ private selfRef: React.RefObject<HTMLDivElement | null>;
194
+ private moveablesRef: React.RefObject<HTMLDivElement | null>;
195
+ private findBorderBarSizeRef: React.RefObject<HTMLDivElement | null>;
196
+ private mainRef: React.RefObject<HTMLDivElement | null>;
197
197
  private previousModel?: Model;
198
198
  private orderedIds: string[];
199
199
  private moveableElementMap = new Map<string, HTMLElement>();
@@ -406,7 +406,7 @@ export class LayoutInternal extends React.Component<ILayoutInternalProps, ILayou
406
406
  const borderSetContentComponents = new Map<DockLocation, React.ReactNode>();
407
407
  for (const [_, location] of DockLocation.values) {
408
408
  const border = borders.get(location);
409
- const showBorder = border && (
409
+ const showBorder = border && border.isShowing() && (
410
410
  !border.isAutoHide() ||
411
411
  (border.isAutoHide() && (border.getChildren().length > 0 || this.state.showHiddenBorder === location)));
412
412
  if (showBorder) {
@@ -1033,7 +1033,7 @@ export class LayoutInternal extends React.Component<ILayoutInternalProps, ILayou
1033
1033
 
1034
1034
 
1035
1035
  public setDragComponent(event: DragEvent, component: React.ReactNode, x: number, y: number) {
1036
- let dragElement: JSX.Element = (
1036
+ let dragElement = (
1037
1037
  <div style={{ position: "unset" }}
1038
1038
  className={this.getClassName(CLASSES.FLEXLAYOUT__LAYOUT) + " " + this.getClassName(CLASSES.FLEXLAYOUT__DRAG_RECT)}>
1039
1039
  {component}
package/src/view/Tab.tsx CHANGED
@@ -95,6 +95,12 @@ export const Tab = (props: ITabProps) => {
95
95
  }
96
96
  }
97
97
 
98
+ if (parentNode instanceof BorderNode) {
99
+ if (!parentNode.isShowing()) {
100
+ style.display = "none";
101
+ }
102
+ }
103
+
98
104
  let className = cm(CLASSES.FLEXLAYOUT__TAB);
99
105
  if (parentNode instanceof BorderNode) {
100
106
  className += " " + cm(CLASSES.FLEXLAYOUT__TAB_BORDER);
@@ -154,6 +154,7 @@ export const useTabOverflow = (
154
154
  };
155
155
 
156
156
  const onMouseWheel = (event: React.WheelEvent<HTMLElement>) => {
157
+ if (node.getChildren().length===0) return;
157
158
  let delta = 0;
158
159
  if (Math.abs(event.deltaX) > Math.abs(event.deltaY)) {
159
160
  delta = -event.deltaX;
@@ -3,7 +3,6 @@ import { Node } from "../model/Node";
3
3
  import { TabNode } from "../model/TabNode";
4
4
  import { LayoutInternal } from "./Layout";
5
5
  import { TabSetNode } from "../model/TabSetNode";
6
- import { Rect } from "../Rect";
7
6
 
8
7
  /** @internal */
9
8
  export function isDesktop() {
@@ -112,29 +111,6 @@ export function canDockToWindow(node: Node) {
112
111
  return false;
113
112
  }
114
113
 
115
- export function keepOnScreen(rect: Rect) {
116
- rect.snap(10);
117
-
118
- const availableScreenWidth = window.screen.availWidth;
119
- const availableScreenHeight = window.screen.availHeight;
120
-
121
- if (rect.x + rect.width > availableScreenWidth || rect.y + rect.height > availableScreenHeight) {
122
- // Adjust the rectangle to fit within the available screen space
123
- rect.x = Math.max(0, Math.min(rect.x, availableScreenWidth - rect.width));
124
- rect.y = Math.max(0, Math.min(rect.y, availableScreenHeight - rect.height));
125
- }
126
-
127
- return rect;
128
- }
129
-
130
- export function isOnScreen(rect: Rect) {
131
- const availableScreenWidth = window.screen.availWidth;
132
- const availableScreenHeight = window.screen.availHeight;
133
-
134
- return (rect.x >= 0 && rect.getRight() <= availableScreenWidth &&
135
- rect.y >= 0 || rect.getBottom() <= availableScreenHeight);
136
- }
137
-
138
114
  export function copyInlineStyles(source: HTMLElement, target: HTMLElement): boolean {
139
115
  // Get the inline style attribute from the source element
140
116
  const sourceStyle = source.getAttribute('style');