flexlayout-react 0.5.18 → 0.6.0

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 (92) hide show
  1. package/ChangeLog.txt +27 -0
  2. package/README.md +126 -108
  3. package/declarations/Types.d.ts +8 -1
  4. package/declarations/model/IJsonModel.d.ts +3 -0
  5. package/declarations/model/Model.d.ts +2 -0
  6. package/declarations/view/Icons.d.ts +6 -0
  7. package/declarations/view/Layout.d.ts +8 -4
  8. package/declarations/view/MenuTabButton.d.ts +1 -0
  9. package/declarations/view/TabButtonStamp.d.ts +1 -0
  10. package/declarations/view/Utils.d.ts +1 -0
  11. package/dist/flexlayout.js +53 -17
  12. package/dist/flexlayout_min.js +1 -1
  13. package/lib/PopupMenu.js +22 -12
  14. package/lib/PopupMenu.js.map +1 -1
  15. package/lib/Types.js +7 -0
  16. package/lib/Types.js.map +1 -1
  17. package/lib/model/BorderNode.js +8 -7
  18. package/lib/model/BorderNode.js.map +1 -1
  19. package/lib/model/Model.js +15 -3
  20. package/lib/model/Model.js.map +1 -1
  21. package/lib/model/RowNode.js +19 -5
  22. package/lib/model/RowNode.js.map +1 -1
  23. package/lib/model/TabNode.js +6 -1
  24. package/lib/model/TabNode.js.map +1 -1
  25. package/lib/model/TabSetNode.js +8 -4
  26. package/lib/model/TabSetNode.js.map +1 -1
  27. package/lib/view/BorderButton.js +19 -38
  28. package/lib/view/BorderButton.js.map +1 -1
  29. package/lib/view/BorderTabSet.js +19 -8
  30. package/lib/view/BorderTabSet.js.map +1 -1
  31. package/lib/view/FloatingWindow.js +13 -5
  32. package/lib/view/FloatingWindow.js.map +1 -1
  33. package/lib/view/Icons.js +36 -0
  34. package/lib/view/Icons.js.map +1 -0
  35. package/lib/view/Layout.js +148 -71
  36. package/lib/view/Layout.js.map +1 -1
  37. package/lib/view/MenuTabButton.js +22 -0
  38. package/lib/view/MenuTabButton.js.map +1 -0
  39. package/lib/view/Splitter.js +3 -3
  40. package/lib/view/Splitter.js.map +1 -1
  41. package/lib/view/Tab.js +9 -6
  42. package/lib/view/Tab.js.map +1 -1
  43. package/lib/view/TabButton.js +20 -44
  44. package/lib/view/TabButton.js.map +1 -1
  45. package/lib/view/TabButtonStamp.js +22 -0
  46. package/lib/view/TabButtonStamp.js.map +1 -0
  47. package/lib/view/TabFloating.js +29 -15
  48. package/lib/view/TabFloating.js.map +1 -1
  49. package/lib/view/TabOverflowHook.js +1 -1
  50. package/lib/view/TabSet.js +40 -25
  51. package/lib/view/TabSet.js.map +1 -1
  52. package/lib/view/Utils.js +61 -0
  53. package/lib/view/Utils.js.map +1 -0
  54. package/package.json +11 -6
  55. package/src/I18nLabel.ts +1 -1
  56. package/src/PopupMenu.tsx +54 -15
  57. package/src/Types.ts +7 -0
  58. package/src/model/BorderNode.ts +8 -7
  59. package/src/model/IJsonModel.ts +3 -0
  60. package/src/model/Model.ts +19 -3
  61. package/src/model/RowNode.ts +8 -5
  62. package/src/model/TabNode.ts +6 -1
  63. package/src/model/TabSetNode.ts +8 -4
  64. package/src/view/BorderButton.tsx +38 -43
  65. package/src/view/BorderTabSet.tsx +34 -7
  66. package/src/view/FloatingWindow.tsx +14 -6
  67. package/src/view/Icons.tsx +36 -0
  68. package/src/view/Layout.tsx +179 -88
  69. package/src/view/Splitter.tsx +4 -1
  70. package/src/view/Tab.tsx +17 -6
  71. package/src/view/TabButton.tsx +42 -55
  72. package/src/view/TabButtonStamp.tsx +47 -0
  73. package/src/view/TabFloating.tsx +47 -23
  74. package/src/view/TabOverflowHook.tsx +1 -1
  75. package/src/view/TabSet.tsx +71 -22
  76. package/src/view/Utils.tsx +71 -0
  77. package/style/_base.scss +146 -92
  78. package/style/dark.css +157 -129
  79. package/style/dark.css.map +1 -1
  80. package/style/dark.scss +31 -21
  81. package/style/gray.css +157 -129
  82. package/style/gray.css.map +1 -1
  83. package/style/gray.scss +30 -23
  84. package/style/light.css +157 -129
  85. package/style/light.css.map +1 -1
  86. package/style/light.scss +30 -20
  87. package/images/close.png +0 -0
  88. package/images/maximize.png +0 -0
  89. package/images/more.png +0 -0
  90. package/images/more2.png +0 -0
  91. package/images/popout.png +0 -0
  92. package/images/restore.png +0 -0
@@ -10,6 +10,7 @@ import { I18nLabel } from "../I18nLabel";
10
10
  import { useTabOverflow } from "./TabOverflowHook";
11
11
  import Orientation from "../Orientation";
12
12
  import { CLASSES } from "../Types";
13
+ import { isAuxMouseEvent } from "./Utils";
13
14
 
14
15
  /** @hidden @internal */
15
16
  export interface IBorderTabSetProps {
@@ -18,11 +19,12 @@ export interface IBorderTabSetProps {
18
19
  iconFactory?: (node: TabNode) => React.ReactNode | undefined;
19
20
  titleFactory?: (node: TabNode) => React.ReactNode | undefined;
20
21
  icons?: IIcons;
22
+ path: string;
21
23
  }
22
24
 
23
25
  /** @hidden @internal */
24
26
  export const BorderTabSet = (props: IBorderTabSetProps) => {
25
- const { border, layout, iconFactory, titleFactory, icons } = props;
27
+ const { border, layout, iconFactory, titleFactory, icons, path } = props;
26
28
 
27
29
  const toolbarRef = React.useRef<HTMLDivElement | null>(null);
28
30
  const overflowbuttonRef = React.useRef<HTMLButtonElement | null>(null);
@@ -30,13 +32,29 @@ export const BorderTabSet = (props: IBorderTabSetProps) => {
30
32
 
31
33
  const { selfRef, position, userControlledLeft, hiddenTabs, onMouseWheel } = useTabOverflow(border, Orientation.flip(border.getOrientation()), toolbarRef, stickyButtonsRef);
32
34
 
35
+ const onAuxMouseClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
36
+ if (isAuxMouseEvent(event)) {
37
+ layout.auxMouseClick(border, event);
38
+ }
39
+ };
40
+
41
+ const onContextMenu = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
42
+ layout.showContextMenu(border, event);
43
+ };
44
+
33
45
  const onInterceptMouseDown = (event: React.MouseEvent<HTMLDivElement, MouseEvent> | React.MouseEvent<HTMLButtonElement, MouseEvent> | React.TouchEvent<HTMLButtonElement>) => {
34
46
  event.stopPropagation();
35
47
  };
36
48
 
37
- const onOverflowClick = () => {
49
+ const onOverflowClick = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
38
50
  const element = overflowbuttonRef.current!;
39
- showPopup(layout.getRootDiv(), element, hiddenTabs, onOverflowItemSelect, layout.getClassName);
51
+ showPopup( element,
52
+ hiddenTabs,
53
+ onOverflowItemSelect,
54
+ layout,
55
+ iconFactory,
56
+ titleFactory);
57
+ event.stopPropagation();
40
58
  };
41
59
 
42
60
  const onOverflowItemSelect = (item: { node: TabNode; index: number }) => {
@@ -44,11 +62,12 @@ export const BorderTabSet = (props: IBorderTabSetProps) => {
44
62
  userControlledLeft.current = false;
45
63
  };
46
64
 
47
- const onFloatTab = () => {
65
+ const onFloatTab = (event: React.MouseEvent<HTMLElement, MouseEvent>) => {
48
66
  const selectedTabNode = border.getChildren()[border.getSelected()] as TabNode;
49
67
  if (selectedTabNode !== undefined) {
50
68
  layout.doAction(Actions.floatTab(selectedTabNode.getId()));
51
69
  }
70
+ event.stopPropagation();
52
71
  };
53
72
 
54
73
  const cm = layout.getClassName;
@@ -65,6 +84,7 @@ export const BorderTabSet = (props: IBorderTabSetProps) => {
65
84
  layout={layout}
66
85
  border={border.getLocation().getName()}
67
86
  node={child}
87
+ path={path + "/tb" + i}
68
88
  key={child.getId()}
69
89
  selected={isSelected}
70
90
  iconFactory={iconFactory}
@@ -97,7 +117,7 @@ export const BorderTabSet = (props: IBorderTabSetProps) => {
97
117
  <button
98
118
  key="overflowbutton"
99
119
  ref={overflowbuttonRef}
100
- className={cm("flexlayout__border_toolbar_button_overflow") + " " + cm("flexlayout__border_toolbar_button_overflow_" + border.getLocation().getName())}
120
+ className={cm(CLASSES.FLEXLAYOUT__BORDER_TOOLBAR_BUTTON_OVERFLOW) + " " + cm(CLASSES.FLEXLAYOUT__BORDER_TOOLBAR_BUTTON_OVERFLOW_ + border.getLocation().getName())}
101
121
  title={overflowTitle}
102
122
  onClick={onOverflowClick}
103
123
  onMouseDown={onInterceptMouseDown}
@@ -122,7 +142,9 @@ export const BorderTabSet = (props: IBorderTabSetProps) => {
122
142
  onClick={onFloatTab}
123
143
  onMouseDown={onInterceptMouseDown}
124
144
  onTouchStart={onInterceptMouseDown}
125
- />
145
+ >
146
+ {icons?.popout}
147
+ </button>
126
148
  );
127
149
  }
128
150
  }
@@ -145,7 +167,12 @@ export const BorderTabSet = (props: IBorderTabSetProps) => {
145
167
  }
146
168
 
147
169
  return (
148
- <div ref={selfRef} style={style} className={borderClasses} onWheel={onMouseWheel}>
170
+ <div ref={selfRef} dir="ltr" style={style} className={borderClasses}
171
+ data-layout-path={path}
172
+ onClick={onAuxMouseClick}
173
+ onAuxClick={onAuxMouseClick}
174
+ onContextMenu={onContextMenu}
175
+ onWheel={onMouseWheel}>
149
176
  <div style={{ height: borderHeight }} className={cm(CLASSES.FLEXLAYOUT__BORDER_INNER) + " " + cm(CLASSES.FLEXLAYOUT__BORDER_INNER_ + border.getLocation().getName())}>
150
177
  <div style={innerStyle} className={cm(CLASSES.FLEXLAYOUT__BORDER_INNER_TAB_CONTAINER) + " " + cm(CLASSES.FLEXLAYOUT__BORDER_INNER_TAB_CONTAINER_ + border.getLocation().getName())}>
151
178
  {tabs}
@@ -16,7 +16,7 @@ export interface IFloatingWindowProps {
16
16
  interface IStyleSheet {
17
17
  href: string | null;
18
18
  type: string;
19
- rules: string[];
19
+ rules: string[] | null;
20
20
  }
21
21
 
22
22
  /** @hidden @internal */
@@ -31,17 +31,23 @@ export const FloatingWindow = (props: React.PropsWithChildren<IFloatingWindowPro
31
31
  // the floating window. window.document.styleSheets is mutable and we can't guarantee
32
32
  // the styles will exist when 'popoutWindow.load' is called below.
33
33
  const styles = Array.from(window.document.styleSheets).reduce((result, styleSheet) => {
34
+ let rules: CSSRuleList | undefined = undefined;
35
+ try {
36
+ rules = styleSheet.cssRules;
37
+ } catch (e) {
38
+ // styleSheet.cssRules can throw security exception
39
+ }
40
+
34
41
  try {
35
42
  return [
36
43
  ...result,
37
44
  {
38
45
  href: styleSheet.href,
39
46
  type: styleSheet.type,
40
- rules: Array.from(styleSheet.cssRules).map(rule => rule.cssText),
47
+ rules: rules ? Array.from(rules).map(rule => rule.cssText) : null,
41
48
  }
42
49
  ];
43
50
  } catch (e) {
44
- // styleSheet.cssRules can throw security exception
45
51
  return result;
46
52
  }
47
53
  }, [] as IStyleSheet[]);
@@ -113,9 +119,11 @@ function copyStyles(doc: Document, styleSheets: IStyleSheet[]): Promise<boolean[
113
119
  })
114
120
  );
115
121
  } else {
116
- const style = doc.createElement("style");
117
- styleSheet.rules.forEach(rule => style.appendChild(doc.createTextNode(rule)));
118
- head.appendChild(style);
122
+ if (styleSheet.rules) {
123
+ const style = doc.createElement("style");
124
+ styleSheet.rules.forEach(rule => style.appendChild(doc.createTextNode(rule)));
125
+ head.appendChild(style);
126
+ }
119
127
  }
120
128
  });
121
129
  return Promise.all(promises);
@@ -0,0 +1,36 @@
1
+ import * as React from "react";
2
+
3
+ const style = {width:"1em", height:"1em", display: "flex", alignItems:"center"};
4
+
5
+ export const CloseIcon = () => {
6
+ return (
7
+ <svg xmlns="http://www.w3.org/2000/svg" style={style} viewBox="0 0 24 24" >
8
+ <path fill="none" d="M0 0h24v24H0z"/>
9
+ <path stroke="gray" fill="gray" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" />
10
+ </svg>
11
+ );
12
+ }
13
+
14
+ export const MaximizeIcon = () => {
15
+ return (
16
+ <svg xmlns="http://www.w3.org/2000/svg" style={style} viewBox="0 0 24 24" fill="gray"><path d="M0 0h24v24H0z" fill="none"/><path stroke="gray" d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></svg>
17
+ );
18
+ }
19
+
20
+ export const OverflowIcon = () => {
21
+ return (
22
+ <svg xmlns="http://www.w3.org/2000/svg" style={style} viewBox="0 0 24 24" fill="gray"><path d="M0 0h24v24H0z" fill="none"/><path stroke="gray" d="M7 10l5 5 5-5z"/></svg>
23
+ );
24
+ }
25
+
26
+ export const PopoutIcon = () => {
27
+ return (
28
+ <svg xmlns="http://www.w3.org/2000/svg" style={style} viewBox="0 0 24 24" fill="gray"><path d="M0 0h24v24H0z" fill="none"/><path stroke="gray" d="M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5z"/></svg>
29
+ );
30
+ }
31
+
32
+ export const RestoreIcon = () => {
33
+ return (
34
+ <svg xmlns="http://www.w3.org/2000/svg" style={style} viewBox="0 0 24 24" fill="gray"><path d="M0 0h24v24H0z" fill="none"/><path stroke="gray" d="M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"/></svg>
35
+ );
36
+ }