flexlayout-react 0.7.15 → 0.8.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.
Files changed (252) hide show
  1. package/ChangeLog.txt +28 -0
  2. package/README.md +157 -330
  3. package/Screenshot_light.png +0 -0
  4. package/Screenshot_rounded.png +0 -0
  5. package/declarations/Attribute.d.ts +1 -1
  6. package/declarations/AttributeDefinitions.d.ts +1 -1
  7. package/declarations/DockLocation.d.ts +12 -12
  8. package/declarations/DropInfo.d.ts +12 -12
  9. package/declarations/I18nLabel.d.ts +12 -14
  10. package/declarations/Orientation.d.ts +7 -7
  11. package/declarations/PopupMenu.d.ts +1 -1
  12. package/declarations/Rect.d.ts +41 -28
  13. package/declarations/Types.d.ts +95 -79
  14. package/declarations/examples/demo/Utils.d.ts +4 -0
  15. package/declarations/index.d.ts +21 -22
  16. package/declarations/model/Action.d.ts +5 -5
  17. package/declarations/model/Actions.d.ts +127 -110
  18. package/declarations/model/BorderNode.d.ts +30 -34
  19. package/declarations/model/BorderSet.d.ts +3 -4
  20. package/declarations/model/ICloseType.d.ts +5 -5
  21. package/declarations/model/IDraggable.d.ts +2 -2
  22. package/declarations/model/IDropTarget.d.ts +2 -2
  23. package/declarations/model/IJsonModel.d.ts +811 -149
  24. package/declarations/model/LayoutWindow.d.ts +28 -0
  25. package/declarations/model/Model.d.ts +91 -86
  26. package/declarations/model/Node.d.ts +17 -17
  27. package/declarations/model/RowNode.d.ts +10 -11
  28. package/declarations/model/TabNode.d.ts +44 -37
  29. package/declarations/model/TabSetNode.d.ts +44 -41
  30. package/declarations/model/Utils.d.ts +1 -1
  31. package/declarations/model/WindowLayout.d.ts +24 -0
  32. package/declarations/src/Attribute.d.ts +1 -0
  33. package/declarations/src/AttributeDefinitions.d.ts +1 -0
  34. package/declarations/src/DockLocation.d.ts +12 -0
  35. package/declarations/src/DropInfo.d.ts +12 -0
  36. package/declarations/src/I18nLabel.d.ts +10 -0
  37. package/declarations/src/Orientation.d.ts +7 -0
  38. package/declarations/src/PopupMenu.d.ts +1 -0
  39. package/declarations/src/Rect.d.ts +31 -0
  40. package/declarations/src/Types.d.ts +92 -0
  41. package/declarations/src/index.d.ts +20 -0
  42. package/declarations/src/model/Action.d.ts +5 -0
  43. package/declarations/src/model/Actions.d.ts +110 -0
  44. package/declarations/src/model/BorderNode.d.ts +28 -0
  45. package/declarations/src/model/BorderSet.d.ts +3 -0
  46. package/declarations/src/model/ICloseType.d.ts +5 -0
  47. package/declarations/src/model/IDraggable.d.ts +2 -0
  48. package/declarations/src/model/IDropTarget.d.ts +2 -0
  49. package/declarations/src/model/IJsonModel.d.ts +153 -0
  50. package/declarations/src/model/Model.d.ts +98 -0
  51. package/declarations/src/model/Node.d.ts +16 -0
  52. package/declarations/src/model/RowNode.d.ts +11 -0
  53. package/declarations/src/model/TabNode.d.ts +36 -0
  54. package/declarations/src/model/TabSetNode.d.ts +37 -0
  55. package/declarations/src/model/Utils.d.ts +1 -0
  56. package/declarations/src/view/BorderButton.d.ts +1 -0
  57. package/declarations/src/view/BorderTab.d.ts +2 -0
  58. package/declarations/src/view/BorderTabSet.d.ts +1 -0
  59. package/declarations/src/view/DragContainer.d.ts +1 -0
  60. package/declarations/src/view/ErrorBoundary.d.ts +1 -0
  61. package/declarations/src/view/FloatingWindow.d.ts +1 -0
  62. package/declarations/src/view/Icons.d.ts +7 -0
  63. package/declarations/src/view/Layout.d.ts +113 -0
  64. package/declarations/src/view/Overlay.d.ts +1 -0
  65. package/declarations/src/view/PopupMenu.d.ts +1 -0
  66. package/declarations/src/view/Row.d.ts +1 -0
  67. package/declarations/src/view/Splitter.d.ts +1 -0
  68. package/declarations/src/view/Tab.d.ts +1 -0
  69. package/declarations/src/view/TabButton.d.ts +1 -0
  70. package/declarations/src/view/TabButtonStamp.d.ts +1 -0
  71. package/declarations/src/view/TabOverflowHook.d.ts +1 -0
  72. package/declarations/src/view/TabSet.d.ts +1 -0
  73. package/declarations/src/view/Utils.d.ts +4 -0
  74. package/declarations/view/BorderButton.d.ts +1 -1
  75. package/declarations/view/BorderTab.d.ts +2 -0
  76. package/declarations/view/BorderTabSet.d.ts +1 -1
  77. package/declarations/view/DragContainer.d.ts +1 -0
  78. package/declarations/view/ErrorBoundary.d.ts +1 -1
  79. package/declarations/view/ExtendedResizeObserver.d.ts +23 -0
  80. package/declarations/view/FloatingWindow.d.ts +1 -1
  81. package/declarations/view/Icons.d.ts +8 -7
  82. package/declarations/view/Layout.d.ts +140 -161
  83. package/declarations/view/Overlay.d.ts +1 -0
  84. package/declarations/view/PopoutWindow.d.ts +1 -0
  85. package/declarations/view/PopupMenu.d.ts +1 -0
  86. package/declarations/view/Row.d.ts +1 -0
  87. package/declarations/view/SizeTracker.d.ts +10 -0
  88. package/declarations/view/Splitter.d.ts +1 -1
  89. package/declarations/view/Tab.d.ts +1 -1
  90. package/declarations/view/TabButton.d.ts +1 -1
  91. package/declarations/view/TabButtonStamp.d.ts +1 -1
  92. package/declarations/view/TabOverflowHook.d.ts +1 -1
  93. package/declarations/view/TabSet.d.ts +1 -1
  94. package/declarations/view/Utils.d.ts +11 -1
  95. package/dist/bundles/demo.js +232052 -0
  96. package/dist/bundles/demo.js.map +1 -0
  97. package/dist/flexlayout.js +122 -92
  98. package/dist/flexlayout_min.js +1 -1
  99. package/lib/Attribute.js +42 -31
  100. package/lib/Attribute.js.map +1 -1
  101. package/lib/AttributeDefinitions.js +131 -108
  102. package/lib/AttributeDefinitions.js.map +1 -1
  103. package/lib/DockLocation.js +120 -124
  104. package/lib/DockLocation.js.map +1 -1
  105. package/lib/DropInfo.js +9 -13
  106. package/lib/DropInfo.js.map +1 -1
  107. package/lib/I18nLabel.js +13 -18
  108. package/lib/I18nLabel.js.map +1 -1
  109. package/lib/Orientation.js +22 -26
  110. package/lib/Orientation.js.map +1 -1
  111. package/lib/Rect.js +104 -72
  112. package/lib/Rect.js.map +1 -1
  113. package/lib/Types.js +96 -83
  114. package/lib/Types.js.map +1 -1
  115. package/lib/index.js +21 -38
  116. package/lib/index.js.map +1 -1
  117. package/lib/model/Action.js +6 -10
  118. package/lib/model/Action.js.map +1 -1
  119. package/lib/model/Actions.js +169 -155
  120. package/lib/model/Actions.js.map +1 -1
  121. package/lib/model/BorderNode.js +385 -406
  122. package/lib/model/BorderNode.js.map +1 -1
  123. package/lib/model/BorderSet.js +66 -121
  124. package/lib/model/BorderSet.js.map +1 -1
  125. package/lib/model/ICloseType.js +6 -9
  126. package/lib/model/ICloseType.js.map +1 -1
  127. package/lib/model/IDraggable.js +1 -2
  128. package/lib/model/IDropTarget.js +1 -2
  129. package/lib/model/IJsonModel.js +1 -2
  130. package/lib/model/LayoutWindow.js +83 -0
  131. package/lib/model/LayoutWindow.js.map +1 -0
  132. package/lib/model/Model.js +614 -496
  133. package/lib/model/Model.js.map +1 -1
  134. package/lib/model/Node.js +217 -228
  135. package/lib/model/Node.js.map +1 -1
  136. package/lib/model/RowNode.js +491 -504
  137. package/lib/model/RowNode.js.map +1 -1
  138. package/lib/model/TabNode.js +289 -184
  139. package/lib/model/TabNode.js.map +1 -1
  140. package/lib/model/TabSetNode.js +459 -446
  141. package/lib/model/TabSetNode.js.map +1 -1
  142. package/lib/model/Utils.js +47 -82
  143. package/lib/model/Utils.js.map +1 -1
  144. package/lib/view/BorderButton.js +129 -138
  145. package/lib/view/BorderButton.js.map +1 -1
  146. package/lib/view/BorderTab.js +47 -0
  147. package/lib/view/BorderTab.js.map +1 -0
  148. package/lib/view/BorderTabSet.js +134 -128
  149. package/lib/view/BorderTabSet.js.map +1 -1
  150. package/lib/view/DragContainer.js +16 -0
  151. package/lib/view/DragContainer.js.map +1 -0
  152. package/lib/view/ErrorBoundary.js +23 -27
  153. package/lib/view/ErrorBoundary.js.map +1 -1
  154. package/lib/view/Icons.js +40 -45
  155. package/lib/view/Icons.js.map +1 -1
  156. package/lib/view/Layout.js +919 -907
  157. package/lib/view/Layout.js.map +1 -1
  158. package/lib/view/Overlay.js +9 -0
  159. package/lib/view/Overlay.js.map +1 -0
  160. package/lib/view/PopoutWindow.js +129 -0
  161. package/lib/view/PopoutWindow.js.map +1 -0
  162. package/lib/view/PopupMenu.js +71 -0
  163. package/lib/view/PopupMenu.js.map +1 -0
  164. package/lib/view/Row.js +45 -0
  165. package/lib/view/Row.js.map +1 -0
  166. package/lib/view/SizeTracker.js +11 -0
  167. package/lib/view/SizeTracker.js.map +1 -0
  168. package/lib/view/Splitter.js +191 -147
  169. package/lib/view/Splitter.js.map +1 -1
  170. package/lib/view/Tab.js +86 -60
  171. package/lib/view/Tab.js.map +1 -1
  172. package/lib/view/TabButton.js +127 -135
  173. package/lib/view/TabButton.js.map +1 -1
  174. package/lib/view/TabButtonStamp.js +16 -21
  175. package/lib/view/TabButtonStamp.js.map +1 -1
  176. package/lib/view/TabOverflowHook.js +150 -149
  177. package/lib/view/TabOverflowHook.js.map +1 -1
  178. package/lib/view/TabSet.js +272 -234
  179. package/lib/view/TabSet.js.map +1 -1
  180. package/lib/view/Utils.js +126 -68
  181. package/lib/view/Utils.js.map +1 -1
  182. package/package.json +36 -30
  183. package/src/Attribute.ts +23 -0
  184. package/src/AttributeDefinitions.ts +38 -15
  185. package/src/DockLocation.ts +13 -13
  186. package/src/I18nLabel.ts +7 -9
  187. package/src/Rect.ts +53 -1
  188. package/src/Types.ts +16 -0
  189. package/src/index.ts +1 -2
  190. package/src/model/Actions.ts +49 -29
  191. package/src/model/BorderNode.ts +208 -214
  192. package/src/model/BorderSet.ts +42 -91
  193. package/src/model/IJsonModel.ts +883 -103
  194. package/src/model/LayoutWindow.ts +121 -0
  195. package/src/model/Model.ts +488 -366
  196. package/src/model/Node.ts +98 -111
  197. package/src/model/RowNode.ts +323 -319
  198. package/src/model/TabNode.ts +294 -110
  199. package/src/model/TabSetNode.ts +303 -242
  200. package/src/model/Utils.ts +6 -32
  201. package/src/view/BorderButton.tsx +36 -52
  202. package/src/view/BorderTab.tsx +70 -0
  203. package/src/view/BorderTabSet.tsx +64 -52
  204. package/src/view/DragContainer.tsx +32 -0
  205. package/src/view/Icons.tsx +6 -0
  206. package/src/view/Layout.tsx +1053 -1046
  207. package/src/view/Overlay.tsx +22 -0
  208. package/src/view/PopoutWindow.tsx +152 -0
  209. package/src/{PopupMenu.tsx → view/PopupMenu.tsx} +36 -31
  210. package/src/view/Row.tsx +68 -0
  211. package/src/view/SizeTracker.tsx +20 -0
  212. package/src/view/Splitter.tsx +167 -112
  213. package/src/view/Tab.tsx +76 -42
  214. package/src/view/TabButton.tsx +39 -54
  215. package/src/view/TabButtonStamp.tsx +5 -9
  216. package/src/view/TabOverflowHook.tsx +14 -9
  217. package/src/view/TabSet.tsx +221 -176
  218. package/src/view/Utils.tsx +119 -39
  219. package/style/_base.scss +140 -34
  220. package/style/dark.css +140 -35
  221. package/style/dark.css.map +1 -1
  222. package/style/dark.scss +3 -1
  223. package/style/gray.css +139 -34
  224. package/style/gray.css.map +1 -1
  225. package/style/gray.scss +2 -0
  226. package/style/light.css +141 -36
  227. package/style/light.css.map +1 -1
  228. package/style/light.scss +4 -2
  229. package/style/rounded.css +697 -0
  230. package/style/rounded.css.map +1 -0
  231. package/style/rounded.scss +194 -0
  232. package/style/underline.css +139 -34
  233. package/style/underline.css.map +1 -1
  234. package/style/underline.scss +2 -0
  235. package/cypress.config.ts +0 -16
  236. package/lib/DragDrop.js +0 -316
  237. package/lib/DragDrop.js.map +0 -1
  238. package/lib/PopupMenu.js +0 -68
  239. package/lib/PopupMenu.js.map +0 -1
  240. package/lib/model/SplitterNode.js +0 -72
  241. package/lib/model/SplitterNode.js.map +0 -1
  242. package/lib/view/FloatingWindow.js +0 -123
  243. package/lib/view/FloatingWindow.js.map +0 -1
  244. package/lib/view/FloatingWindowTab.js +0 -19
  245. package/lib/view/FloatingWindowTab.js.map +0 -1
  246. package/lib/view/TabFloating.js +0 -66
  247. package/lib/view/TabFloating.js.map +0 -1
  248. package/src/DragDrop.ts +0 -392
  249. package/src/model/SplitterNode.ts +0 -78
  250. package/src/view/FloatingWindow.tsx +0 -140
  251. package/src/view/FloatingWindowTab.tsx +0 -29
  252. package/src/view/TabFloating.tsx +0 -101
@@ -0,0 +1,22 @@
1
+ import * as React from "react";
2
+ import { LayoutInternal } from "./Layout";
3
+ import { CLASSES } from "../Types";
4
+
5
+ /** @internal */
6
+ export interface IOverlayProps {
7
+ layout: LayoutInternal;
8
+ show: boolean;
9
+ }
10
+
11
+ /** @internal */
12
+ export const Overlay = (props: IOverlayProps) => {
13
+ const {layout, show} = props;
14
+
15
+ return (
16
+ <div
17
+ className={layout.getClassName(CLASSES.FLEXLAYOUT__LAYOUT_OVERLAY)}
18
+ style={{display: (show ? "flex" : "none")
19
+ }}
20
+ />
21
+ );
22
+ }
@@ -0,0 +1,152 @@
1
+ import * as React from "react";
2
+ import { createPortal } from "react-dom";
3
+ import { CLASSES } from "../Types";
4
+ import { LayoutInternal } from "./Layout";
5
+ import { LayoutWindow } from "../model/LayoutWindow";
6
+
7
+ /** @internal */
8
+ export interface IPopoutWindowProps {
9
+ title: string;
10
+ layout: LayoutInternal;
11
+ layoutWindow: LayoutWindow;
12
+ url: string;
13
+ onCloseWindow: (layoutWindow: LayoutWindow) => void;
14
+ onSetWindow: (layoutWindow: LayoutWindow, window: Window) => void;
15
+ }
16
+
17
+ /** @internal */
18
+ export const PopoutWindow = (props: React.PropsWithChildren<IPopoutWindowProps>) => {
19
+ const { title, layout, layoutWindow, url, onCloseWindow, onSetWindow, children } = props; const popoutWindow = React.useRef<Window | null>(null);
20
+ const [content, setContent] = React.useState<HTMLElement | undefined>(undefined);
21
+ // map from main docs style -> this docs equivalent style
22
+ const styleMap = new Map<HTMLElement, HTMLElement>();
23
+
24
+ React.useLayoutEffect(() => {
25
+ if (!popoutWindow.current) { // only create window once, even in strict mode
26
+ const windowId = layoutWindow.windowId;
27
+ const rect = layoutWindow.rect;
28
+
29
+ popoutWindow.current = window.open(url, windowId, `left=${rect.x},top=${rect.y},width=${rect.width},height=${rect.height}`);
30
+
31
+ if (popoutWindow.current) {
32
+ layoutWindow.window = popoutWindow.current;
33
+ onSetWindow(layoutWindow, popoutWindow.current);
34
+
35
+ // listen for parent unloading to remove all popouts
36
+ window.addEventListener("beforeunload", () => {
37
+ if (popoutWindow.current) {
38
+ const closedWindow = popoutWindow.current;
39
+ popoutWindow.current = null; // need to set to null before close, since this will trigger popup window before unload...
40
+ closedWindow.close();
41
+ }
42
+ });
43
+
44
+ popoutWindow.current.addEventListener("load", () => {
45
+ if (popoutWindow.current) {
46
+ popoutWindow.current.focus();
47
+
48
+ // note: resizeto must be before moveto in chrome otherwise the window will end up at 0,0
49
+ popoutWindow.current.resizeTo(rect.width, rect.height);
50
+ popoutWindow.current.moveTo(rect.x, rect.y);
51
+
52
+ const popoutDocument = popoutWindow.current.document;
53
+ popoutDocument.title = title;
54
+ const popoutContent = popoutDocument.createElement("div");
55
+ popoutContent.className = CLASSES.FLEXLAYOUT__FLOATING_WINDOW_CONTENT;
56
+ popoutDocument.body.appendChild(popoutContent);
57
+ copyStyles(popoutDocument, styleMap).then(() => {
58
+ setContent(popoutContent); // re-render once link styles loaded
59
+ });
60
+
61
+ // listen for style mutations
62
+ const observer = new MutationObserver((mutationsList: any) => handleStyleMutations(mutationsList, popoutDocument, styleMap));
63
+ observer.observe(document.head, { childList: true });
64
+
65
+ // listen for popout unloading (needs to be after load for safari)
66
+ popoutWindow.current.addEventListener("beforeunload", () => {
67
+ if (popoutWindow.current) {
68
+ onCloseWindow(layoutWindow); // remove the layoutWindow in the model
69
+ popoutWindow.current = null;
70
+ observer.disconnect();
71
+ }
72
+ });
73
+ }
74
+ });
75
+ } else {
76
+ console.warn(`Unable to open window ${url}`);
77
+ onCloseWindow(layoutWindow); // remove the layoutWindow in the model
78
+ }
79
+ }
80
+ return () => {
81
+ // only close popoutWindow if windowId has been removed from the model (ie this was due to model change)
82
+ if (!layout.getModel().getwindowsMap().has(layoutWindow.windowId)) {
83
+ popoutWindow.current?.close();
84
+ popoutWindow.current = null;
85
+ }
86
+ }
87
+ }, []);
88
+
89
+ if (content !== undefined) {
90
+ return createPortal(children, content!);
91
+ } else {
92
+ return null;
93
+ }
94
+ };
95
+
96
+ function handleStyleMutations(mutationsList: any, popoutDocument: Document, styleMap: Map<HTMLElement, HTMLElement>) {
97
+ for (const mutation of mutationsList) {
98
+ if (mutation.type === 'childList') {
99
+ for (const addition of mutation.addedNodes) {
100
+ if (addition instanceof HTMLLinkElement || addition instanceof HTMLStyleElement) {
101
+ copyStyle(popoutDocument, addition, styleMap);
102
+ }
103
+ }
104
+ for (const removal of mutation.removedNodes) {
105
+ if (removal instanceof HTMLLinkElement || removal instanceof HTMLStyleElement) {
106
+ const popoutStyle = styleMap.get(removal);
107
+ if (popoutStyle) {
108
+ popoutDocument.head.removeChild(popoutStyle);
109
+ }
110
+ }
111
+ }
112
+ }
113
+ }
114
+ };
115
+
116
+
117
+
118
+ /** @internal */
119
+ function copyStyles(popoutDoc: Document, styleMap: Map<HTMLElement, HTMLElement>): Promise<boolean[]> {
120
+ const promises: Promise<boolean>[] = [];
121
+ const styleElements = document.querySelectorAll('style, link[rel="stylesheet"]') as NodeListOf<HTMLElement>
122
+ for (const element of styleElements) {
123
+ copyStyle(popoutDoc, element, styleMap, promises);
124
+ }
125
+ return Promise.all(promises);
126
+ }
127
+
128
+ /** @internal */
129
+ function copyStyle(popoutDoc: Document, element: HTMLElement, styleMap: Map<HTMLElement, HTMLElement>, promises?: Promise<boolean>[]) {
130
+ if (element instanceof HTMLLinkElement) {
131
+ // prefer links since they will keep paths to images etc
132
+ const linkElement = element.cloneNode(true) as HTMLLinkElement;
133
+ popoutDoc.head.appendChild(linkElement);
134
+ styleMap.set(element, linkElement);
135
+
136
+ if (promises) {
137
+ promises.push(new Promise((resolve) => {
138
+ linkElement.onload = () => resolve(true);
139
+ }));
140
+ }
141
+ } else if (element instanceof HTMLStyleElement) {
142
+ try {
143
+ const styleElement = element.cloneNode(true) as HTMLStyleElement;
144
+ popoutDoc.head.appendChild(styleElement);
145
+ styleMap.set(element, styleElement);
146
+ } catch (e) {
147
+ // can throw an exception
148
+ }
149
+ }
150
+ }
151
+
152
+
@@ -1,18 +1,15 @@
1
1
  import * as React from "react";
2
- import { DragDrop } from "./DragDrop";
3
- import { TabNode } from "./model/TabNode";
4
- import { CLASSES } from "./Types";
5
- import { IconFactory, ILayoutCallbacks, TitleFactory } from "./view/Layout";
6
- import { TabButtonStamp } from "./view/TabButtonStamp";
2
+ import { TabNode } from "../model/TabNode";
3
+ import { CLASSES } from "../Types";
4
+ import { LayoutInternal } from "./Layout";
5
+ import { TabButtonStamp } from "./TabButtonStamp";
7
6
 
8
7
  /** @internal */
9
8
  export function showPopup(
10
9
  triggerElement: Element,
11
10
  items: { index: number; node: TabNode }[],
12
11
  onSelect: (item: { index: number; node: TabNode }) => void,
13
- layout: ILayoutCallbacks,
14
- iconFactory?: IconFactory,
15
- titleFactory?: TitleFactory,
12
+ layout: LayoutInternal,
16
13
  ) {
17
14
  const layoutDiv = layout.getRootDiv();
18
15
  const classNameMapper = layout.getClassName;
@@ -33,43 +30,41 @@ export function showPopup(
33
30
  } else {
34
31
  elm.style.bottom = layoutRect.bottom - triggerRect.bottom + "px";
35
32
  }
36
- DragDrop.instance.addGlass(() => onHide());
37
- DragDrop.instance.setGlassCursorOverride("default");
33
+
34
+ layout.showOverlay(true);
38
35
 
39
36
  if (layoutDiv) {
40
37
  layoutDiv.appendChild(elm);
41
38
  }
42
39
 
43
40
  const onHide = () => {
44
- layout.hidePortal();
45
- DragDrop.instance.hideGlass();
41
+ layout.hideControlInPortal();
42
+ layout.showOverlay(false);
46
43
  if (layoutDiv) {
47
44
  layoutDiv.removeChild(elm);
48
45
  }
49
- elm.removeEventListener("mousedown", onElementMouseDown);
50
- currentDocument.removeEventListener("mousedown", onDocMouseDown);
46
+ elm.removeEventListener("pointerdown", onElementPointerDown);
47
+ currentDocument.removeEventListener("pointerdown", onDocPointerDown);
51
48
  };
52
49
 
53
- const onElementMouseDown = (event: Event) => {
50
+ const onElementPointerDown = (event: Event) => {
54
51
  event.stopPropagation();
55
52
  };
56
53
 
57
- const onDocMouseDown = (_event: Event) => {
54
+ const onDocPointerDown = (_event: Event) => {
58
55
  onHide();
59
56
  };
60
57
 
61
- elm.addEventListener("mousedown", onElementMouseDown);
62
- currentDocument.addEventListener("mousedown", onDocMouseDown);
58
+ elm.addEventListener("pointerdown", onElementPointerDown);
59
+ currentDocument.addEventListener("pointerdown", onDocPointerDown);
63
60
 
64
- layout.showPortal(<PopupMenu
61
+ layout.showControlInPortal(<PopupMenu
65
62
  currentDocument={currentDocument}
66
63
  onSelect={onSelect}
67
64
  onHide={onHide}
68
65
  items={items}
69
66
  classNameMapper={classNameMapper}
70
67
  layout={layout}
71
- iconFactory={iconFactory}
72
- titleFactory={titleFactory}
73
68
  />, elm);
74
69
  }
75
70
 
@@ -80,35 +75,45 @@ interface IPopupMenuProps {
80
75
  onHide: () => void;
81
76
  onSelect: (item: { index: number; node: TabNode }) => void;
82
77
  classNameMapper: (defaultClassName: string) => string;
83
- layout: ILayoutCallbacks;
84
- iconFactory?: IconFactory;
85
- titleFactory?: TitleFactory;
78
+ layout: LayoutInternal;
86
79
  }
87
80
 
88
81
  /** @internal */
89
82
  const PopupMenu = (props: IPopupMenuProps) => {
90
- const { items, onHide, onSelect, classNameMapper, layout, iconFactory, titleFactory} = props;
83
+ const { items, onHide, onSelect, classNameMapper, layout} = props;
91
84
 
92
- const onItemClick = (item: { index: number; node: TabNode }, event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
85
+ const onItemClick = (item: { index: number; node: TabNode }, event: React.MouseEvent<HTMLElement, MouseEvent>) => {
93
86
  onSelect(item);
94
87
  onHide();
95
88
  event.stopPropagation();
96
89
  };
97
90
 
91
+ const onDragStart = (event: React.DragEvent<HTMLElement>, node:TabNode) => {
92
+ event.stopPropagation(); // prevent starting a tabset drag as well
93
+ layout.setDragNode(event.nativeEvent, node as TabNode);
94
+ setTimeout(() => {
95
+ onHide();
96
+ }, 0);
97
+
98
+ };
99
+
100
+ const onDragEnd = (event: React.DragEvent<HTMLElement>) => {
101
+ layout.clearDragMain();
102
+ };
103
+
98
104
  const itemElements = items.map((item, i) => (
99
105
  <div key={item.index}
100
106
  className={classNameMapper(CLASSES.FLEXLAYOUT__POPUP_MENU_ITEM)}
101
107
  data-layout-path={"/popup-menu/tb" + i}
102
108
  onClick={(event) => onItemClick(item, event)}
109
+ draggable={true}
110
+ onDragStart={(e) => onDragStart(e, item.node)}
111
+ onDragEnd={onDragEnd}
103
112
  title={item.node.getHelpText()} >
104
- {item.node.getModel().isLegacyOverflowMenu() ?
105
- item.node._getNameForOverflowMenu() :
106
113
  <TabButtonStamp
107
114
  node={item.node}
108
115
  layout={layout}
109
- iconFactory={iconFactory}
110
- titleFactory={titleFactory}
111
- />}
116
+ />
112
117
  </div>
113
118
  ));
114
119
 
@@ -0,0 +1,68 @@
1
+ import * as React from "react";
2
+ import { RowNode } from "../model/RowNode";
3
+ import { TabSetNode } from "../model/TabSetNode";
4
+ import { CLASSES } from "../Types";
5
+ import { LayoutInternal } from "./Layout";
6
+ import { TabSet } from "./TabSet";
7
+ import { Splitter } from "./Splitter";
8
+ import { Orientation } from "../Orientation";
9
+
10
+ /** @internal */
11
+ export interface IRowProps {
12
+ layout: LayoutInternal;
13
+ node: RowNode;
14
+ }
15
+
16
+ /** @internal */
17
+ export const Row = (props: IRowProps) => {
18
+ const { layout, node } = props;
19
+ const selfRef = React.useRef<HTMLDivElement | null>(null);
20
+
21
+ const horizontal = node.getOrientation() === Orientation.HORZ;
22
+
23
+ React.useLayoutEffect(() => {
24
+ node.setRect(layout.getBoundingClientRect(selfRef.current!));
25
+ });
26
+
27
+ const items: React.ReactNode[] = [];
28
+
29
+ let i = 0;
30
+
31
+ for (const child of node.getChildren()) {
32
+ if (i > 0) {
33
+ items.push(<Splitter key={"splitter" + i} layout={layout} node={node} index={i} horizontal={horizontal} />)
34
+ }
35
+ if (child instanceof RowNode) {
36
+ items.push(<Row key={child.getId()} layout={layout} node={child} />);
37
+ } else if (child instanceof TabSetNode) {
38
+ items.push(<TabSet key={child.getId()} layout={layout} node={child} />);
39
+ }
40
+ i++;
41
+ }
42
+
43
+ const style: Record<string, any> = {
44
+ flexGrow: Math.max(1, node.getWeight()*1000), // NOTE: flex-grow cannot have values < 1 otherwise will not fill parent, need to normalize
45
+ minWidth: node.getMinWidth(),
46
+ minHeight: node.getMinHeight(),
47
+ maxWidth: node.getMaxWidth(),
48
+ maxHeight: node.getMaxHeight(),
49
+ };
50
+
51
+ if (horizontal) {
52
+ style.flexDirection = "row";
53
+ } else {
54
+ style.flexDirection = "column";
55
+ }
56
+
57
+ return (
58
+ <div
59
+ ref={selfRef}
60
+ className={layout.getClassName(CLASSES.FLEXLAYOUT__ROW)}
61
+ style={style}
62
+ >
63
+ {items}
64
+ </div>
65
+ );
66
+ };
67
+
68
+
@@ -0,0 +1,20 @@
1
+ import * as React from "react";
2
+ import { Rect } from "../Rect";
3
+
4
+ export interface ISizeTrackerProps {
5
+ rect: Rect;
6
+ selected: boolean;
7
+ forceRevision: number;
8
+ tabsRevision: number;
9
+ children: React.ReactNode;
10
+ }
11
+ // only render if size changed or forceRevision changed or tabsRevision changed
12
+ export const SizeTracker = React.memo(({ children }: ISizeTrackerProps) => {
13
+ return <>{children}</>
14
+ }, (prevProps, nextProps) => {
15
+ return prevProps.rect.equalSize(nextProps.rect) &&
16
+ prevProps.selected === nextProps.selected &&
17
+ prevProps.forceRevision === nextProps.forceRevision &&
18
+ prevProps.tabsRevision === nextProps.tabsRevision
19
+ });
20
+