flexlayout-react 0.8.8 → 0.8.10

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.8",
3
+ "version": "0.8.10",
4
4
  "description": "A multi-tab docking layout manager",
5
5
  "main": "lib/index.js",
6
6
  "types": "./declarations/index.d.ts",
@@ -30,7 +30,7 @@
30
30
  "build:umd": "webpack --mode=development --config webpack_build.config.js",
31
31
  "build:umd:min": "webpack --mode=production --config webpack_build_min.config.js",
32
32
  "build:demo": "webpack",
33
- "lint:eslint": "eslint src/*",
33
+ "lint": "eslint src/*",
34
34
  "doc": "typedoc --out typedoc --exclude \"**/examples/**/*.tsx\" --excludeInternal --disableSources --excludePrivate --excludeProtected --readme none ./src",
35
35
  "css": "sass style/rounded.scss style/rounded.css && sass style/underline.scss style/underline.css && sass style/gray.scss style/gray.css && sass style/light.scss style/light.css && sass style/light.scss test/style/light.css && sass style/dark.scss style/dark.css && sass style/combined.scss style/combined.css"
36
36
  },
@@ -47,6 +47,7 @@
47
47
  "devDependencies": {
48
48
  "@emotion/react": "^11.14.0",
49
49
  "@emotion/styled": "^11.14.0",
50
+ "@eslint/js": "^9.24.0",
50
51
  "@mui/material": "^6.4.4",
51
52
  "@mui/x-data-grid": "^7.26.0",
52
53
  "@types/node": "^22.13.4",
@@ -57,6 +58,9 @@
57
58
  "ag-grid-react": "^33.1.0",
58
59
  "chart.js": "^4.4.7",
59
60
  "css-loader": "^7.1.2",
61
+ "eslint": "^9.24.0",
62
+ "eslint-plugin-react": "^7.37.5",
63
+ "globals": "^16.0.0",
60
64
  "html-webpack-plugin": "^5.6.3",
61
65
  "ol": "^10.4.0",
62
66
  "prettier": "^3.5.1",
@@ -72,6 +76,7 @@
72
76
  "ts-loader": "~9.5.2",
73
77
  "typedoc": "^0.27.7",
74
78
  "typescript": "^5.7.3",
79
+ "typescript-eslint": "^8.29.1",
75
80
  "webpack": "^5.98.0",
76
81
  "webpack-cli": "^6.0.1",
77
82
  "webpack-dev-server": "^5.2.0"
@@ -62,7 +62,7 @@ export class AttributeDefinitions {
62
62
 
63
63
  update(jsonObj: any, obj: any) {
64
64
  for (const attr of this.attributes) {
65
- if (jsonObj.hasOwnProperty(attr.name)) {
65
+ if (Object.prototype.hasOwnProperty.call(jsonObj, attr.name)) {
66
66
  const fromValue = jsonObj[attr.name];
67
67
  if (fromValue === undefined) {
68
68
  delete obj[attr.name];
@@ -113,7 +113,7 @@ export class AttributeDefinitions {
113
113
  type = attr.type;
114
114
  }
115
115
 
116
- let defValue = JSON.stringify(defaultValue);
116
+ const defValue = JSON.stringify(defaultValue);
117
117
 
118
118
  const required = attr.required ? "" : "?";
119
119
 
package/src/Rect.ts CHANGED
@@ -34,7 +34,7 @@ export class Rect {
34
34
  }
35
35
 
36
36
  static getBoundingClientRect(element: Element) {
37
- let { x, y, width, height } = element.getBoundingClientRect();
37
+ const { x, y, width, height } = element.getBoundingClientRect();
38
38
  return new Rect(x, y, width, height);
39
39
  }
40
40
 
@@ -174,6 +174,10 @@ export class TabNode extends Node implements IDraggable {
174
174
  return this.getAttr("maxHeight") as number;
175
175
  }
176
176
 
177
+ isVisible() {
178
+ return this.visible;
179
+ }
180
+
177
181
  toJson(): IJsonTabNode {
178
182
  const json = {};
179
183
  TabNode.attributeDefinitions.toJson(json, this.attributes);
@@ -215,8 +219,8 @@ export class TabNode extends Node implements IDraggable {
215
219
  /** @internal */
216
220
  setVisible(visible: boolean) {
217
221
  if (visible !== this.visible) {
218
- this.fireEvent("visibility", { visible });
219
222
  this.visible = visible;
223
+ this.fireEvent("visibility", { visible });
220
224
  }
221
225
  }
222
226
 
@@ -86,8 +86,7 @@ export const BorderButton = (props: IBorderButtonProps) => {
86
86
  const onClose = (event: React.MouseEvent<HTMLElement>) => {
87
87
  if (isClosable()) {
88
88
  layout.doAction(Actions.deleteTab(node.getId()));
89
- } else {
90
- onClick();
89
+ event.stopPropagation();
91
90
  }
92
91
  };
93
92
 
@@ -110,7 +109,7 @@ export const BorderButton = (props: IBorderButtonProps) => {
110
109
  if (event.code === 'Escape') {
111
110
  // esc
112
111
  layout.setEditingTab(undefined);
113
- } else if (event.code === 'Enter') {
112
+ } else if (event.code === 'Enter' || event.code === 'NumpadEnter') {
114
113
  // enter
115
114
  layout.setEditingTab(undefined);
116
115
  layout.doAction(Actions.renameTab(node.getId(), (event.target as HTMLInputElement).value));
@@ -197,7 +197,8 @@ export class LayoutInternal extends React.Component<ILayoutInternalProps, ILayou
197
197
  private findBorderBarSizeRef: React.RefObject<HTMLDivElement | null>;
198
198
  private mainRef: React.RefObject<HTMLDivElement | null>;
199
199
  private previousModel?: Model;
200
- private orderedIds: string[];
200
+ private orderedTabIds: string[];
201
+ private orderedTabMoveableIds: string[];
201
202
  private moveableElementMap = new Map<string, HTMLElement>();
202
203
  private dropInfo: DropInfo | undefined;
203
204
  private outlineDiv?: HTMLElement;
@@ -222,7 +223,8 @@ export class LayoutInternal extends React.Component<ILayoutInternalProps, ILayou
222
223
  constructor(props: ILayoutInternalProps) {
223
224
  super(props);
224
225
 
225
- this.orderedIds = [];
226
+ this.orderedTabIds = [];
227
+ this.orderedTabMoveableIds = [];
226
228
  this.selfRef = React.createRef<HTMLDivElement>();
227
229
  this.moveablesRef = React.createRef<HTMLDivElement>();
228
230
  this.mainRef = React.createRef<HTMLDivElement>();
@@ -356,17 +358,18 @@ export class LayoutInternal extends React.Component<ILayoutInternalProps, ILayou
356
358
  const outer = this.renderBorders(inner);
357
359
 
358
360
  const tabs = this.renderTabs();
359
- const reorderedTabs = this.reorderComponents(tabs, this.orderedIds);
361
+ const reorderedTabs = this.reorderComponents(tabs, this.orderedTabIds);
360
362
 
361
363
  let floatingWindows = null;
362
- let tabMoveables = null;
364
+ let reorderedTabMoveables = null;
363
365
  let tabStamps = null;
364
366
  let metricElements = null;
365
367
 
366
368
  if (this.isMainWindow) {
367
369
  floatingWindows = this.renderWindows();
368
370
  metricElements = this.renderMetricsElements();
369
- tabMoveables = this.renderTabMoveables();
371
+ const tabMoveables = this.renderTabMoveables();
372
+ reorderedTabMoveables = this.reorderComponents(tabMoveables, this.orderedTabMoveableIds);
370
373
  tabStamps = <div key="__tabStamps__" className={this.getClassName(CLASSES.FLEXLAYOUT__LAYOUT_TAB_STAMPS)}>
371
374
  {this.renderTabStamps()}
372
375
  </div>;
@@ -386,7 +389,7 @@ export class LayoutInternal extends React.Component<ILayoutInternalProps, ILayou
386
389
  <Overlay key="__overlay__" layout={this} show={this.state.showOverlay} />
387
390
  {outer}
388
391
  {reorderedTabs}
389
- {tabMoveables}
392
+ {reorderedTabMoveables}
390
393
  {tabStamps}
391
394
  {this.state.portal}
392
395
  {floatingWindows}
@@ -553,7 +556,8 @@ export class LayoutInternal extends React.Component<ILayoutInternalProps, ILayou
553
556
  }
554
557
 
555
558
  renderTabMoveables() {
556
- const tabMoveables: React.ReactNode[] = [];
559
+ // const tabMoveables: React.ReactNode[] = [];
560
+ const tabMoveables = new Map<string, React.ReactNode>();
557
561
 
558
562
  this.props.model.visitNodes((node) => {
559
563
  if (node instanceof TabNode) {
@@ -570,7 +574,7 @@ export class LayoutInternal extends React.Component<ILayoutInternalProps, ILayou
570
574
  if (renderTab) {
571
575
  // console.log("rendertab", child.getName(), this.props.renderRevision);
572
576
  const key = child.getId() + (child.isEnableWindowReMount() ? child.getWindowId() : "");
573
- tabMoveables.push(createPortal(
577
+ tabMoveables.set(node.getId(), createPortal(
574
578
  <SizeTracker rect={rect} selected={child.isSelected()} forceRevision={this.state.forceRevision} tabsRevision={this.props.renderRevision} key={key}>
575
579
  <ErrorBoundary message={this.i18nName(I18nLabel.Error_rendering_component)}>
576
580
  {this.props.factory(child)}
@@ -1228,7 +1232,7 @@ export class LayoutInternal extends React.Component<ILayoutInternalProps, ILayou
1228
1232
  // *************************** End Drag Drop *************************************
1229
1233
  }
1230
1234
 
1231
- export const FlexLayoutVersion = "0.8.8";
1235
+ export const FlexLayoutVersion = "0.8.10";
1232
1236
 
1233
1237
  export type DragRectRenderCallback = (
1234
1238
  content: React.ReactNode | undefined,
@@ -93,8 +93,7 @@ export const TabButton = (props: ITabButtonProps) => {
93
93
  const onClose = (event: React.MouseEvent<HTMLElement>) => {
94
94
  if (isClosable()) {
95
95
  layout.doAction(Actions.deleteTab(node.getId()));
96
- } else {
97
- onClick();
96
+ event.stopPropagation();
98
97
  }
99
98
  };
100
99
 
@@ -110,7 +109,7 @@ export const TabButton = (props: ITabButtonProps) => {
110
109
  if (event.code === 'Escape') {
111
110
  // esc
112
111
  layout.setEditingTab(undefined);
113
- } else if (event.code === 'Enter') {
112
+ } else if (event.code === 'Enter' || event.code === 'NumpadEnter') {
114
113
  // enter
115
114
  layout.setEditingTab(undefined);
116
115
  layout.doAction(Actions.renameTab(node.getId(), (event.target as HTMLInputElement).value));
@@ -28,12 +28,12 @@ export const useTabOverflow = (
28
28
  const repositioningRef = React.useRef<boolean>(false);
29
29
  hiddenTabsRef.current = hiddenTabs;
30
30
 
31
- // if node changes (new model) then reset scroll to 0
31
+ // if node id changes (new model) then reset scroll to 0
32
32
  React.useLayoutEffect(() => {
33
33
  if (tabStripRef.current) {
34
34
  setScrollPosition(0);
35
35
  }
36
- }, [node]);
36
+ }, [node.getId()]);
37
37
 
38
38
  // if selected node or tabset/border rectangle change then unset usercontrolled (so selected tab will be kept in view)
39
39
  React.useLayoutEffect(() => {