@flowgram.ai/panel-manager-plugin 0.1.0-alpha.20 → 0.1.0-alpha.22

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": "@flowgram.ai/panel-manager-plugin",
3
- "version": "0.1.0-alpha.20",
3
+ "version": "0.1.0-alpha.22",
4
4
  "homepage": "https://flowgram.ai/",
5
5
  "repository": "https://github.com/bytedance/flowgram.ai",
6
6
  "license": "MIT",
@@ -15,8 +15,8 @@
15
15
  "dependencies": {
16
16
  "inversify": "^6.0.1",
17
17
  "clsx": "^1.1.1",
18
- "@flowgram.ai/core": "0.1.0-alpha.20",
19
- "@flowgram.ai/utils": "0.1.0-alpha.20"
18
+ "@flowgram.ai/core": "0.1.0-alpha.22",
19
+ "@flowgram.ai/utils": "0.1.0-alpha.22"
20
20
  },
21
21
  "devDependencies": {
22
22
  "react": "^18",
@@ -25,8 +25,8 @@
25
25
  "@types/react-dom": "^18",
26
26
  "tsup": "^8.0.1",
27
27
  "typescript": "^5.8.3",
28
- "@flowgram.ai/ts-config": "0.1.0-alpha.20",
29
- "@flowgram.ai/eslint-config": "0.1.0-alpha.20"
28
+ "@flowgram.ai/ts-config": "0.1.0-alpha.22",
29
+ "@flowgram.ai/eslint-config": "0.1.0-alpha.22"
30
30
  },
31
31
  "peerDependencies": {
32
32
  "react": ">=16.8",
@@ -9,13 +9,13 @@ CLI tsup v8.5.0
9
9
  CLI Target: es2020
10
10
  CJS Build start
11
11
  ESM Build start
12
- CJS dist/index.js 13.82 KB
13
- CJS dist/index.js.map 22.26 KB
14
- CJS ⚡️ Build success in 98ms
15
- ESM dist/esm/index.js 11.54 KB
16
- ESM dist/esm/index.js.map 21.81 KB
17
- ESM ⚡️ Build success in 99ms
12
+ ESM dist/esm/index.js 13.07 KB
13
+ ESM dist/esm/index.js.map 24.15 KB
14
+ ESM ⚡️ Build success in 91ms
15
+ CJS dist/index.js 15.42 KB
16
+ CJS dist/index.js.map 24.71 KB
17
+ CJS ⚡️ Build success in 107ms
18
18
  DTS Build start
19
- DTS ⚡️ Build success in 3462ms
20
- DTS dist/index.d.ts 2.78 KB
21
- DTS dist/index.d.mts 2.78 KB
19
+ DTS ⚡️ Build success in 3627ms
20
+ DTS dist/index.d.ts 3.49 KB
21
+ DTS dist/index.d.mts 3.49 KB
@@ -4,59 +4,62 @@
4
4
  */
5
5
 
6
6
  export const globalCSS = `
7
- .gedit-flow-panel-layer * {
7
+ .gedit-flow-panel-layer-wrap * {
8
8
  box-sizing: border-box;
9
9
  }
10
10
  .gedit-flow-panel-layer-wrap {
11
- pointer-events: none;
12
11
  position: absolute;
13
12
  top: 0;
14
13
  left: 0;
15
14
  display: flex;
16
- column-gap: 4px;
17
15
  width: 100%;
18
16
  height: 100%;
19
- padding: 4px;
20
17
  overflow: hidden;
21
18
  }
22
- `;
23
-
24
- export const leftArea: React.CSSProperties = {
25
- width: '100%',
26
- minWidth: 0,
27
- flexGrow: 0,
28
- flexShrink: 1,
29
-
30
- display: 'flex',
31
- flexDirection: 'column',
32
- rowGap: '4px',
33
- };
34
-
35
- export const rightArea: React.CSSProperties = {
36
- height: '100%',
37
- flexGrow: 1,
38
- flexShrink: 0,
39
- minWidth: 0,
19
+ .gedit-flow-panel-layer-wrap-docked {
40
20
 
41
- display: 'flex',
42
- columnGap: '4px',
43
- };
44
-
45
- export const mainArea: React.CSSProperties = {
46
- position: 'relative',
47
- overflow: 'hidden',
48
- flexGrow: 0,
49
- flexShrink: 1,
50
- width: '100%',
51
- height: '100%',
52
- };
21
+ }
22
+ .gedit-flow-panel-layer-wrap-floating {
23
+ column-gap: 4px;
24
+ padding: 4px;
25
+ pointer-events: none;
26
+ }
53
27
 
54
- export const bottomArea: React.CSSProperties = {
55
- flexGrow: 1,
56
- flexShrink: 0,
57
- width: '100%',
58
- minHeight: 0,
59
- };
28
+ .gedit-flow-panel-left-area {
29
+ width: 100%;
30
+ min-width: 0;
31
+ flex-grow: 0;
32
+ flex-shrink: 1;
33
+ display: flex;
34
+ flex-direction: column;
35
+ }
36
+ .gedit-flow-panel-layer-wrap-floating .gedit-flow-panel-left-area {
37
+ row-gap: 4px;
38
+ }
39
+ .gedit-flow-panel-right-area {
40
+ height: 100%;
41
+ flex-grow: 1;
42
+ flex-shrink: 0;
43
+ min-width: 0;
44
+ display: flex;
45
+ column-gap: 4px;
46
+ }
47
+
48
+ .gedit-flow-panel-main-area {
49
+ position: relative;
50
+ overflow: hidden;
51
+ flex-grow: 0;
52
+ flex-shrink: 1;
53
+ width: 100%;
54
+ height: 100%;
55
+ }
56
+ .gedit-flow-panel-bottom-area {
57
+ flex-grow: 1;
58
+ flex-shrink: 0;
59
+ width: 100%;
60
+ min-height: 0;
61
+ }
62
+ `;
60
63
 
61
64
  export const floatPanelWrap: React.CSSProperties = {
62
65
  pointerEvents: 'auto',
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { PanelLayer, PanelLayerProps } from './panel-layer';
7
+
8
+ export type DockedPanelLayerProps = Omit<PanelLayerProps, 'mode'>;
9
+
10
+ export const DockedPanelLayer: React.FC<DockedPanelLayerProps> = (props) => (
11
+ <PanelLayer mode="docked" {...props} />
12
+ );
@@ -8,12 +8,14 @@ import { useEffect, useRef, startTransition, useState, useCallback } from 'react
8
8
  import { Area } from '../../types';
9
9
  import { usePanelManager } from '../../hooks/use-panel-manager';
10
10
  import { floatPanelWrap } from './css';
11
- import { ResizeBar } from '../resize-bar';
12
11
 
13
12
  export const FloatPanel: React.FC<{ area: Area }> = ({ area }) => {
14
13
  const [, setVersion] = useState(0);
15
14
  const panelManager = usePanelManager();
16
15
  const panel = useRef(panelManager.getPanel(area));
16
+
17
+ const isHorizontal = ['right', 'docked-right'].includes(area);
18
+
17
19
  const render = () =>
18
20
  panel.current.elements.map((i) => (
19
21
  <div className="float-panel-wrap" key={i.key} style={{ ...floatPanelWrap, ...i.style }}>
@@ -33,8 +35,9 @@ export const FloatPanel: React.FC<{ area: Area }> = ({ area }) => {
33
35
  }, [panel]);
34
36
  const onResize = useCallback((newSize: number) => panel.current!.updateSize(newSize), []);
35
37
  const size = panel.current!.currentSize;
36
- const sizeStyle =
37
- area === 'right' ? { width: size, height: '100%' } : { height: size, width: '100%' };
38
+ const sizeStyle = isHorizontal
39
+ ? { width: size, height: '100%' }
40
+ : { height: size, width: '100%' };
38
41
 
39
42
  return (
40
43
  <div
@@ -45,9 +48,11 @@ export const FloatPanel: React.FC<{ area: Area }> = ({ area }) => {
45
48
  ...sizeStyle,
46
49
  }}
47
50
  >
48
- {panelManager.config.autoResize && panel.current.elements.length > 0 && (
49
- <ResizeBar size={size} isVertical={area === 'right'} onResize={onResize} />
50
- )}
51
+ {panelManager.config.resizeBarRender({
52
+ size,
53
+ direction: isHorizontal ? 'vertical' : 'horizontal',
54
+ onResize,
55
+ })}
51
56
  {node.current}
52
57
  </div>
53
58
  );
@@ -4,3 +4,4 @@
4
4
  */
5
5
 
6
6
  export { PanelLayer, type PanelLayerProps } from './panel-layer';
7
+ export { DockedPanelLayer, type DockedPanelLayerProps } from './docked-panel-layer';
@@ -7,31 +7,44 @@ import clsx from 'clsx';
7
7
 
8
8
  import { useGlobalCSS } from '../../hooks/use-global-css';
9
9
  import { FloatPanel } from './float-panel';
10
- import { leftArea, rightArea, mainArea, bottomArea, globalCSS } from './css';
10
+ import { globalCSS } from './css';
11
11
 
12
12
  export type PanelLayerProps = React.PropsWithChildren<{
13
+ /** 模式:悬浮|挤压 */
14
+ mode?: 'floating' | 'docked';
13
15
  className?: string;
14
16
  style?: React.CSSProperties;
15
17
  }>;
16
18
 
17
- export const PanelLayer: React.FC<PanelLayerProps> = ({ className, style, children }) => {
19
+ export const PanelLayer: React.FC<PanelLayerProps> = ({
20
+ mode = 'floating',
21
+ className,
22
+ style,
23
+ children,
24
+ }) => {
18
25
  useGlobalCSS({
19
26
  cssText: globalCSS,
20
27
  id: 'flow-panel-layer-css',
21
28
  });
22
29
 
23
30
  return (
24
- <div className={clsx('gedit-flow-panel-layer-wrap', className)} style={style}>
25
- <div className="gedit-flow-panel-left-area" style={leftArea}>
26
- <div className="gedit-flow-panel-main-area" style={mainArea}>
27
- {children}
28
- </div>
29
- <div className="gedit-flow-panel-bottom-area" style={bottomArea}>
30
- <FloatPanel area="bottom" />
31
+ <div
32
+ className={clsx(
33
+ 'gedit-flow-panel-layer-wrap',
34
+ mode === 'docked' && 'gedit-flow-panel-layer-wrap-docked',
35
+ mode === 'floating' && 'gedit-flow-panel-layer-wrap-floating',
36
+ className
37
+ )}
38
+ style={style}
39
+ >
40
+ <div className="gedit-flow-panel-left-area">
41
+ <div className="gedit-flow-panel-main-area">{children}</div>
42
+ <div className="gedit-flow-panel-bottom-area">
43
+ <FloatPanel area={mode === 'docked' ? 'docked-bottom' : 'bottom'} />
31
44
  </div>
32
45
  </div>
33
- <div className="gedit-flow-panel-right-area" style={rightArea}>
34
- <FloatPanel area="right" />
46
+ <div className="gedit-flow-panel-right-area">
47
+ <FloatPanel area={mode === 'docked' ? 'docked-right' : 'right'} />
35
48
  </div>
36
49
  </div>
37
50
  );
@@ -6,15 +6,18 @@
6
6
  import React, { useRef, useState } from 'react';
7
7
 
8
8
  interface Props {
9
- onResize: (w: number) => void;
10
9
  size: number;
11
- isVertical?: boolean;
10
+ direction?: 'vertical' | 'horizontal';
11
+ onResize: (w: number) => void;
12
12
  }
13
13
 
14
- export const ResizeBar: React.FC<Props> = ({ onResize, size, isVertical }) => {
14
+ export const ResizeBar: React.FC<Props> = ({ onResize, size, direction }) => {
15
15
  const currentPoint = useRef<null | number>(null);
16
16
  const [isDragging, setIsDragging] = useState(false);
17
17
  const [isHovered, setIsHovered] = useState(false);
18
+
19
+ const isVertical = direction === 'vertical';
20
+
18
21
  return (
19
22
  <div
20
23
  onMouseDown={(e) => {
package/src/index.ts CHANGED
@@ -12,6 +12,7 @@ export { PanelManager, type PanelManagerConfig } from './services';
12
12
  /** react hooks */
13
13
  export { usePanelManager } from './hooks/use-panel-manager';
14
14
 
15
+ export { DockedPanelLayer, type DockedPanelLayerProps } from './components/panel-layer';
15
16
  export { ResizeBar } from './components/resize-bar';
16
17
 
17
18
  /** types */
@@ -6,14 +6,24 @@
6
6
  import { PluginContext } from '@flowgram.ai/core';
7
7
 
8
8
  import type { PanelFactory, PanelConfig } from '../types';
9
+ import { ResizeBar } from '../components/resize-bar';
9
10
  import type { PanelLayerProps } from '../components/panel-layer';
10
11
 
11
12
  export interface PanelManagerConfig {
12
13
  factories: PanelFactory<any>[];
13
14
  right: PanelConfig;
14
15
  bottom: PanelConfig;
16
+ dockedRight: PanelConfig;
17
+ dockedBottom: PanelConfig;
15
18
  autoResize: boolean;
16
19
  layerProps: PanelLayerProps;
20
+ resizeBarRender: ({
21
+ size,
22
+ }: {
23
+ size: number;
24
+ direction?: 'vertical' | 'horizontal';
25
+ onResize: (size: number) => void;
26
+ }) => React.ReactNode;
17
27
  getPopupContainer: (ctx: PluginContext) => HTMLElement; // default playground.node.parentElement
18
28
  }
19
29
 
@@ -27,9 +37,16 @@ export const defineConfig = (config: Partial<PanelManagerConfig>) => {
27
37
  bottom: {
28
38
  max: 1,
29
39
  },
40
+ dockedRight: {
41
+ max: 1,
42
+ },
43
+ dockedBottom: {
44
+ max: 1,
45
+ },
30
46
  factories: [],
31
47
  autoResize: true,
32
48
  layerProps: {},
49
+ resizeBarRender: ResizeBar,
33
50
  getPopupContainer: (ctx: PluginContext) => ctx.playground.node.parentNode as HTMLElement,
34
51
  };
35
52
  return {
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import { injectable, inject } from 'inversify';
7
+ import { Playground } from '@flowgram.ai/core';
7
8
 
8
9
  import { PanelManagerConfig } from './panel-config';
9
10
  import type { Area, PanelFactory } from '../types';
@@ -11,6 +12,8 @@ import { FloatPanel } from './float-panel';
11
12
 
12
13
  @injectable()
13
14
  export class PanelManager {
15
+ @inject(Playground) readonly playground: Playground;
16
+
14
17
  @inject(PanelManagerConfig) readonly config: PanelManagerConfig;
15
18
 
16
19
  readonly panelRegistry = new Map<string, PanelFactory<any>>();
@@ -19,10 +22,16 @@ export class PanelManager {
19
22
 
20
23
  bottom: FloatPanel;
21
24
 
25
+ dockedRight: FloatPanel;
26
+
27
+ dockedBottom: FloatPanel;
28
+
22
29
  init() {
23
30
  this.config.factories.forEach((factory) => this.register(factory));
24
31
  this.right = new FloatPanel(this.config.right);
25
32
  this.bottom = new FloatPanel(this.config.bottom);
33
+ this.dockedRight = new FloatPanel(this.config.dockedRight);
34
+ this.dockedBottom = new FloatPanel(this.config.dockedBottom);
26
35
  }
27
36
 
28
37
  register<T extends any>(factory: PanelFactory<T>) {
@@ -41,14 +50,28 @@ export class PanelManager {
41
50
  close(key?: string) {
42
51
  this.right.close(key);
43
52
  this.bottom.close(key);
53
+ this.dockedRight.close(key);
54
+ this.dockedBottom.close(key);
44
55
  }
45
56
 
46
57
  getPanel(area: Area) {
47
- return area === 'right' ? this.right : this.bottom;
58
+ switch (area) {
59
+ case 'docked-bottom':
60
+ return this.dockedBottom;
61
+ case 'docked-right':
62
+ return this.dockedRight;
63
+ case 'bottom':
64
+ return this.bottom;
65
+ case 'right':
66
+ default:
67
+ return this.right;
68
+ }
48
69
  }
49
70
 
50
71
  dispose() {
51
72
  this.right.dispose();
52
73
  this.bottom.dispose();
74
+ this.dockedBottom.dispose();
75
+ this.dockedRight.dispose();
53
76
  }
54
77
  }
package/src/types.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  * SPDX-License-Identifier: MIT
4
4
  */
5
5
 
6
- export type Area = 'right' | 'bottom';
6
+ export type Area = 'right' | 'bottom' | 'docked-right' | 'docked-bottom';
7
7
 
8
8
  export interface PanelConfig {
9
9
  /** max panel */