@flowgram.ai/panel-manager-plugin 0.1.0-alpha.24 → 0.1.0-alpha.25
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/.rush/temp/chunked-rush-logs/panel-manager-plugin.build.chunks.jsonl +9 -9
- package/.rush/temp/package-deps_build.json +7 -6
- package/dist/esm/index.js +136 -74
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +10 -4
- package/dist/index.d.ts +10 -4
- package/dist/index.js +151 -89
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/rush-logs/panel-manager-plugin.build.log +9 -9
- package/src/components/panel-layer/css.ts +0 -6
- package/src/components/panel-layer/panel.tsx +27 -10
- package/src/hooks/use-panel.ts +9 -0
- package/src/services/panel-factory.ts +47 -5
- package/src/services/panel-manager.ts +0 -2
- package/src/types.ts +2 -0
- package/src/utils.ts +22 -0
|
@@ -5,26 +5,27 @@
|
|
|
5
5
|
|
|
6
6
|
import { useEffect, startTransition, useState, useRef } from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
import { shallow } from 'zustand/shallow';
|
|
10
|
-
import clsx from 'clsx';
|
|
8
|
+
import { clsx } from 'clsx';
|
|
11
9
|
|
|
12
10
|
import { Area } from '../../types';
|
|
13
11
|
import { PanelEntity } from '../../services/panel-factory';
|
|
14
12
|
import { usePanelManager } from '../../hooks/use-panel-manager';
|
|
13
|
+
import { usePanelStore } from '../../hooks/use-panel';
|
|
15
14
|
import { PanelContext } from '../../contexts';
|
|
16
15
|
|
|
17
16
|
const PanelItem: React.FC<{ panel: PanelEntity }> = ({ panel }) => {
|
|
18
17
|
const panelManager = usePanelManager();
|
|
19
18
|
const ref = useRef<HTMLDivElement>(null);
|
|
20
|
-
const resize =
|
|
21
|
-
panel.factory.resize !== undefined ? panel.factory.resize : panelManager.config.autoResize;
|
|
22
19
|
|
|
23
20
|
const isHorizontal = ['right', 'docked-right'].includes(panel.area);
|
|
24
21
|
|
|
25
|
-
const size =
|
|
22
|
+
const { size, fullscreen } = usePanelStore((s) => ({ size: s.size, fullscreen: s.fullscreen }));
|
|
26
23
|
|
|
27
|
-
const
|
|
24
|
+
const [layerSize, setLayerSize] = useState(size);
|
|
25
|
+
|
|
26
|
+
const currentSize = fullscreen ? layerSize : size;
|
|
27
|
+
|
|
28
|
+
const sizeStyle = isHorizontal ? { width: currentSize } : { height: currentSize };
|
|
28
29
|
const handleResize = (next: number) => {
|
|
29
30
|
let nextSize = next;
|
|
30
31
|
if (typeof panel.factory.maxSize === 'number' && nextSize > panel.factory.maxSize) {
|
|
@@ -37,12 +38,28 @@ const PanelItem: React.FC<{ panel: PanelEntity }> = ({ panel }) => {
|
|
|
37
38
|
|
|
38
39
|
useEffect(() => {
|
|
39
40
|
/** The set size may be illegal and needs to be updated according to the real element rendered for the first time. */
|
|
40
|
-
if (ref.current) {
|
|
41
|
+
if (ref.current && !fullscreen) {
|
|
41
42
|
const { width, height } = ref.current.getBoundingClientRect();
|
|
42
43
|
const realSize = isHorizontal ? width : height;
|
|
43
44
|
panel.store.setState({ size: realSize });
|
|
44
45
|
}
|
|
45
|
-
}, []);
|
|
46
|
+
}, [fullscreen]);
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (!fullscreen) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const layer = panel.layer;
|
|
53
|
+
if (!layer) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const observer = new ResizeObserver(([entry]) => {
|
|
57
|
+
const { width, height } = entry.contentRect;
|
|
58
|
+
setLayerSize(isHorizontal ? width : height);
|
|
59
|
+
});
|
|
60
|
+
observer.observe(layer);
|
|
61
|
+
return () => observer.disconnect();
|
|
62
|
+
}, [fullscreen]);
|
|
46
63
|
|
|
47
64
|
return (
|
|
48
65
|
<div
|
|
@@ -54,7 +71,7 @@ const PanelItem: React.FC<{ panel: PanelEntity }> = ({ panel }) => {
|
|
|
54
71
|
ref={ref}
|
|
55
72
|
style={{ ...panel.factory.style, ...panel.config.style, ...sizeStyle }}
|
|
56
73
|
>
|
|
57
|
-
{
|
|
74
|
+
{panel.resizable &&
|
|
58
75
|
panelManager.config.resizeBarRender({
|
|
59
76
|
size,
|
|
60
77
|
direction: isHorizontal ? 'vertical' : 'horizontal',
|
package/src/hooks/use-panel.ts
CHANGED
|
@@ -5,6 +5,15 @@
|
|
|
5
5
|
|
|
6
6
|
import { useContext } from 'react';
|
|
7
7
|
|
|
8
|
+
import { useStoreWithEqualityFn } from 'zustand/traditional';
|
|
9
|
+
import { shallow } from 'zustand/shallow';
|
|
10
|
+
|
|
11
|
+
import { PanelEntityState } from '../services/panel-factory';
|
|
8
12
|
import { PanelContext } from '../contexts';
|
|
9
13
|
|
|
10
14
|
export const usePanel = () => useContext(PanelContext);
|
|
15
|
+
|
|
16
|
+
export const usePanelStore = <T>(selector: (s: PanelEntityState) => T) => {
|
|
17
|
+
const panel = usePanel();
|
|
18
|
+
return useStoreWithEqualityFn(panel.store, selector, shallow);
|
|
19
|
+
};
|
|
@@ -9,6 +9,8 @@ import { inject, injectable } from 'inversify';
|
|
|
9
9
|
|
|
10
10
|
import type { PanelFactory, PanelEntityConfig, Area } from '../types';
|
|
11
11
|
import { PanelRestore } from './panel-restore';
|
|
12
|
+
import { PanelManagerConfig } from './panel-config';
|
|
13
|
+
import { merge } from '../utils';
|
|
12
14
|
|
|
13
15
|
export const PanelEntityFactory = Symbol('PanelEntityFactory');
|
|
14
16
|
export type PanelEntityFactory = (options: {
|
|
@@ -25,8 +27,9 @@ export type PanelEntityConfigConstant = PanelEntityConfig<any> & {
|
|
|
25
27
|
|
|
26
28
|
const PANEL_SIZE_DEFAULT = 400;
|
|
27
29
|
|
|
28
|
-
interface PanelEntityState {
|
|
30
|
+
export interface PanelEntityState {
|
|
29
31
|
size: number;
|
|
32
|
+
fullscreen: boolean;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
@injectable()
|
|
@@ -38,6 +41,8 @@ export class PanelEntity {
|
|
|
38
41
|
|
|
39
42
|
@inject(PanelEntityConfigConstant) public config: PanelEntityConfigConstant;
|
|
40
43
|
|
|
44
|
+
@inject(PanelManagerConfig) readonly globalConfig: PanelManagerConfig;
|
|
45
|
+
|
|
41
46
|
private initialized = false;
|
|
42
47
|
|
|
43
48
|
/** 实例唯一标识 */
|
|
@@ -52,6 +57,10 @@ export class PanelEntity {
|
|
|
52
57
|
return this.config.area;
|
|
53
58
|
}
|
|
54
59
|
|
|
60
|
+
get mode() {
|
|
61
|
+
return this.config.area.startsWith('docked') ? 'docked' : 'floating';
|
|
62
|
+
}
|
|
63
|
+
|
|
55
64
|
get key() {
|
|
56
65
|
return this.factory.key;
|
|
57
66
|
}
|
|
@@ -63,18 +72,51 @@ export class PanelEntity {
|
|
|
63
72
|
return this.node;
|
|
64
73
|
}
|
|
65
74
|
|
|
75
|
+
get fullscreen() {
|
|
76
|
+
return this.store.getState().fullscreen;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
set fullscreen(next: boolean) {
|
|
80
|
+
this.store.setState({ fullscreen: next });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
get resizable() {
|
|
84
|
+
if (this.fullscreen) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
return this.factory.resize !== undefined ? this.factory.resize : this.globalConfig.autoResize;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
get layer() {
|
|
91
|
+
return document.querySelector(
|
|
92
|
+
this.mode ? '.gedit-flow-panel-layer-wrap-docked' : '.gedit-flow-panel-layer-wrap-floating'
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
66
96
|
init() {
|
|
67
97
|
if (this.initialized) {
|
|
68
98
|
return;
|
|
69
99
|
}
|
|
70
100
|
this.initialized = true;
|
|
71
101
|
const cache = this.restore.restore<PanelEntityState>(this.key);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
102
|
+
|
|
103
|
+
const initialState = merge<PanelEntityState>(
|
|
104
|
+
{
|
|
105
|
+
size: this.config.defaultSize,
|
|
106
|
+
fullscreen: this.config.fullscreen,
|
|
107
|
+
},
|
|
108
|
+
cache ? cache : {},
|
|
109
|
+
{
|
|
110
|
+
size: this.factory.defaultSize || PANEL_SIZE_DEFAULT,
|
|
111
|
+
fullscreen: this.factory.fullscreen || false,
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
this.store = createStore<PanelEntityState>(() => initialState);
|
|
76
116
|
}
|
|
77
117
|
|
|
118
|
+
mergeState() {}
|
|
119
|
+
|
|
78
120
|
dispose() {
|
|
79
121
|
this.restore.store(this.key, this.store.getState());
|
|
80
122
|
}
|
|
@@ -56,7 +56,6 @@ export class PanelManager {
|
|
|
56
56
|
this.panels.set(panel.id, panel);
|
|
57
57
|
this.trim(area);
|
|
58
58
|
this.onPanelsChangeEvent.fire();
|
|
59
|
-
console.log('jxj', this.panels);
|
|
60
59
|
}
|
|
61
60
|
|
|
62
61
|
/** close panel */
|
|
@@ -70,7 +69,6 @@ export class PanelManager {
|
|
|
70
69
|
private trim(area: Area) {
|
|
71
70
|
const panels = this.getPanels(area);
|
|
72
71
|
const areaConfig = this.getAreaConfig(area);
|
|
73
|
-
console.log('jxj', areaConfig.max, panels.length);
|
|
74
72
|
while (panels.length > areaConfig.max) {
|
|
75
73
|
const removed = panels.shift();
|
|
76
74
|
if (removed) {
|
package/src/types.ts
CHANGED
|
@@ -13,6 +13,7 @@ export interface PanelConfig {
|
|
|
13
13
|
export interface PanelFactory<T extends any> {
|
|
14
14
|
key: string;
|
|
15
15
|
defaultSize: number;
|
|
16
|
+
fullscreen?: boolean;
|
|
16
17
|
maxSize?: number;
|
|
17
18
|
minSize?: number;
|
|
18
19
|
style?: React.CSSProperties;
|
|
@@ -24,6 +25,7 @@ export interface PanelFactory<T extends any> {
|
|
|
24
25
|
|
|
25
26
|
export interface PanelEntityConfig<T extends any = any> {
|
|
26
27
|
defaultSize?: number;
|
|
28
|
+
fullscreen?: boolean;
|
|
27
29
|
style?: React.CSSProperties;
|
|
28
30
|
props?: T;
|
|
29
31
|
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export const merge = <T>(...objs: Partial<T>[]) => {
|
|
7
|
+
const result: any = {};
|
|
8
|
+
|
|
9
|
+
for (const obj of objs) {
|
|
10
|
+
if (!obj || typeof obj !== 'object') continue;
|
|
11
|
+
|
|
12
|
+
for (const key of Object.keys(obj)) {
|
|
13
|
+
const value = (obj as any)[key];
|
|
14
|
+
|
|
15
|
+
if (result[key] === undefined) {
|
|
16
|
+
result[key] = value;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return result as T;
|
|
22
|
+
};
|