@flowgram.ai/panel-manager-plugin 0.4.15

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.
@@ -0,0 +1,72 @@
1
+ import * as _flowgram_ai_core from '@flowgram.ai/core';
2
+ import * as _flowgram_ai_utils from '@flowgram.ai/utils';
3
+
4
+ /**
5
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
6
+ * SPDX-License-Identifier: MIT
7
+ */
8
+ type Area = 'right' | 'bottom';
9
+ interface PanelConfig {
10
+ /** max panel */
11
+ max: number;
12
+ }
13
+ interface PanelFactory<T extends any> {
14
+ key: string;
15
+ render: (props: T) => React.ReactNode;
16
+ }
17
+
18
+ interface PanelElement {
19
+ key: string;
20
+ el: React.ReactNode;
21
+ }
22
+ declare class FloatPanel {
23
+ private config;
24
+ elements: PanelElement[];
25
+ private onUpdateEmitter;
26
+ onUpdate: _flowgram_ai_utils.Event<void>;
27
+ constructor(config: PanelConfig);
28
+ open(factory: PanelFactory<any>, options: any): void;
29
+ close(key?: string): void;
30
+ dispose(): void;
31
+ }
32
+
33
+ /**
34
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
35
+ * SPDX-License-Identifier: MIT
36
+ */
37
+
38
+ declare class PanelManager {
39
+ private readonly config;
40
+ readonly panelRegistry: Map<string, PanelFactory<any>>;
41
+ right: FloatPanel;
42
+ bottom: FloatPanel;
43
+ init(): void;
44
+ register<T extends any>(factory: PanelFactory<T>): void;
45
+ open(key: string, area?: Area, options?: any): void;
46
+ close(key: string, area?: Area): void;
47
+ getPanel(area: Area): FloatPanel;
48
+ dispose(): void;
49
+ }
50
+
51
+ /**
52
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
53
+ * SPDX-License-Identifier: MIT
54
+ */
55
+
56
+ interface PanelManagerConfig {
57
+ factories: PanelFactory<any>[];
58
+ right: PanelConfig;
59
+ bottom: PanelConfig;
60
+ }
61
+ declare const PanelManagerConfig: unique symbol;
62
+
63
+ declare const createPanelManagerPlugin: _flowgram_ai_core.PluginCreator<Partial<PanelManagerConfig>>;
64
+
65
+ /**
66
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
67
+ * SPDX-License-Identifier: MIT
68
+ */
69
+
70
+ declare const usePanelManager: () => PanelManager;
71
+
72
+ export { type Area, type PanelFactory, PanelManager, createPanelManagerPlugin, usePanelManager };
package/dist/index.js ADDED
@@ -0,0 +1,285 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var __decorateClass = (decorators, target, key, kind) => {
20
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
21
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
22
+ if (decorator = decorators[i])
23
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
24
+ if (kind && result) __defProp(target, key, result);
25
+ return result;
26
+ };
27
+
28
+ // src/index.ts
29
+ var index_exports = {};
30
+ __export(index_exports, {
31
+ PanelManager: () => PanelManager,
32
+ createPanelManagerPlugin: () => createPanelManagerPlugin,
33
+ usePanelManager: () => usePanelManager
34
+ });
35
+ module.exports = __toCommonJS(index_exports);
36
+
37
+ // src/create-panel-manager-plugin.ts
38
+ var import_core3 = require("@flowgram.ai/core");
39
+
40
+ // src/services/panel-config.ts
41
+ var PanelManagerConfig = Symbol("PanelManagerConfig");
42
+ var defineConfig = (config) => {
43
+ const defaultConfig = {
44
+ right: {
45
+ max: 1
46
+ },
47
+ bottom: {
48
+ max: 1
49
+ },
50
+ factories: []
51
+ };
52
+ return {
53
+ ...defaultConfig,
54
+ ...config
55
+ };
56
+ };
57
+
58
+ // src/services/panel-manager.ts
59
+ var import_inversify = require("inversify");
60
+
61
+ // src/services/float-panel.ts
62
+ var import_utils = require("@flowgram.ai/utils");
63
+ var FloatPanel = class {
64
+ constructor(config) {
65
+ this.config = config;
66
+ this.elements = [];
67
+ this.onUpdateEmitter = new import_utils.Emitter();
68
+ this.onUpdate = this.onUpdateEmitter.event;
69
+ }
70
+ open(factory, options) {
71
+ const el = factory.render(options?.props);
72
+ const idx = this.elements.findIndex((e) => e.key === factory.key);
73
+ if (idx >= 0) {
74
+ this.elements[idx] = { el, key: factory.key };
75
+ } else {
76
+ this.elements.push({ el, key: factory.key });
77
+ if (this.elements.length > this.config.max) {
78
+ this.elements.shift();
79
+ }
80
+ }
81
+ this.onUpdateEmitter.fire();
82
+ }
83
+ close(key) {
84
+ if (!key) {
85
+ this.elements = [];
86
+ } else {
87
+ this.elements = this.elements.filter((e) => e.key !== key);
88
+ }
89
+ this.onUpdateEmitter.fire();
90
+ }
91
+ dispose() {
92
+ this.elements = [];
93
+ this.onUpdateEmitter.dispose();
94
+ }
95
+ };
96
+
97
+ // src/services/panel-manager.ts
98
+ var PanelManager = class {
99
+ constructor() {
100
+ this.panelRegistry = /* @__PURE__ */ new Map();
101
+ }
102
+ init() {
103
+ this.config.factories.forEach((factory) => this.register(factory));
104
+ this.right = new FloatPanel(this.config.right);
105
+ this.bottom = new FloatPanel(this.config.bottom);
106
+ }
107
+ register(factory) {
108
+ this.panelRegistry.set(factory.key, factory);
109
+ }
110
+ open(key, area = "right", options) {
111
+ const factory = this.panelRegistry.get(key);
112
+ if (!factory) {
113
+ return;
114
+ }
115
+ const panel = this.getPanel(area);
116
+ panel.open(factory, options);
117
+ }
118
+ close(key, area = "right") {
119
+ const panel = this.getPanel(area);
120
+ panel.close(key);
121
+ }
122
+ getPanel(area) {
123
+ return area === "right" ? this.right : this.bottom;
124
+ }
125
+ dispose() {
126
+ this.right.dispose();
127
+ this.bottom.dispose();
128
+ }
129
+ };
130
+ __decorateClass([
131
+ (0, import_inversify.inject)(PanelManagerConfig)
132
+ ], PanelManager.prototype, "config", 2);
133
+ PanelManager = __decorateClass([
134
+ (0, import_inversify.injectable)()
135
+ ], PanelManager);
136
+
137
+ // src/services/panel-layer.ts
138
+ var import_react2 = require("react");
139
+ var import_inversify2 = require("inversify");
140
+ var import_utils2 = require("@flowgram.ai/utils");
141
+ var import_core2 = require("@flowgram.ai/core");
142
+
143
+ // src/components/panel-layer/float-panel.tsx
144
+ var import_react = require("react");
145
+
146
+ // src/hooks/use-panel-manager.ts
147
+ var import_core = require("@flowgram.ai/core");
148
+ var usePanelManager = () => (0, import_core.useService)(PanelManager);
149
+
150
+ // src/components/panel-layer/css.ts
151
+ var panelLayer = {
152
+ pointerEvents: "none",
153
+ position: "absolute",
154
+ top: 0,
155
+ left: 0,
156
+ display: "flex",
157
+ columnGap: "4px",
158
+ width: "100%",
159
+ height: "100%",
160
+ padding: "4px",
161
+ boxSizing: "border-box"
162
+ };
163
+ var leftArea = {
164
+ width: "100%",
165
+ minWidth: 0,
166
+ flexGrow: 0,
167
+ flexShrink: 1,
168
+ display: "flex",
169
+ flexDirection: "column",
170
+ rowGap: "4px"
171
+ };
172
+ var rightArea = {
173
+ height: "100%",
174
+ flexGrow: 1,
175
+ flexShrink: 0,
176
+ minWidth: 0,
177
+ display: "flex",
178
+ columnGap: "4px"
179
+ };
180
+ var mainArea = {
181
+ position: "relative",
182
+ overflow: "hidden",
183
+ flexGrow: 0,
184
+ flexShrink: 1,
185
+ width: "100%",
186
+ height: "100%"
187
+ };
188
+ var bottomArea = {
189
+ flexGrow: 1,
190
+ flexShrink: 0,
191
+ width: "100%",
192
+ minHeight: 0
193
+ };
194
+ var floatPanelWrap = {
195
+ pointerEvents: "auto",
196
+ height: "100%",
197
+ width: "100%"
198
+ };
199
+
200
+ // src/components/panel-layer/float-panel.tsx
201
+ var import_jsx_runtime = require("react/jsx-runtime");
202
+ var FloatPanel2 = ({ area }) => {
203
+ const [, setVersion] = (0, import_react.useState)(0);
204
+ const panelManager = usePanelManager();
205
+ const panel = (0, import_react.useRef)(panelManager.getPanel(area));
206
+ const render = () => panel.current.elements.map((i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "float-panel-wrap", style: floatPanelWrap, children: i.el }, i.key));
207
+ const node = (0, import_react.useRef)(render());
208
+ (0, import_react.useEffect)(() => {
209
+ const dispose = panel.current.onUpdate(() => {
210
+ (0, import_react.startTransition)(() => {
211
+ node.current = render();
212
+ setVersion((v) => v + 1);
213
+ });
214
+ });
215
+ return () => dispose.dispose();
216
+ }, [panel]);
217
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: node.current });
218
+ };
219
+
220
+ // src/components/panel-layer/panel-layer.tsx
221
+ var import_jsx_runtime2 = require("react/jsx-runtime");
222
+ var PanelLayer = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "panel-layer", style: panelLayer, children: [
223
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "left-area", style: leftArea, children: [
224
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "main-area", style: mainArea, children }),
225
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "bottom-area", style: bottomArea, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FloatPanel2, { area: "bottom" }) })
226
+ ] }),
227
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "right-area", style: rightArea, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FloatPanel2, { area: "right" }) })
228
+ ] });
229
+
230
+ // src/services/panel-layer.ts
231
+ var PanelLayer2 = class extends import_core2.Layer {
232
+ constructor() {
233
+ super(...arguments);
234
+ this.node = import_utils2.domUtils.createDivWithClass("gedit-flow-panel-layer");
235
+ this.layout = null;
236
+ }
237
+ onReady() {
238
+ const commonStyle = {
239
+ pointerEvents: "none",
240
+ zIndex: 11
241
+ };
242
+ import_utils2.domUtils.setStyle(this.node, commonStyle);
243
+ this.config.onDataChange(() => {
244
+ const { width, height, scrollX, scrollY } = this.config.config;
245
+ import_utils2.domUtils.setStyle(this.node, {
246
+ ...commonStyle,
247
+ width,
248
+ height,
249
+ left: scrollX,
250
+ top: scrollY
251
+ });
252
+ });
253
+ }
254
+ render() {
255
+ if (!this.layout) {
256
+ this.layout = (0, import_react2.createElement)(PanelLayer);
257
+ }
258
+ return this.layout;
259
+ }
260
+ };
261
+ PanelLayer2 = __decorateClass([
262
+ (0, import_inversify2.injectable)()
263
+ ], PanelLayer2);
264
+
265
+ // src/create-panel-manager-plugin.ts
266
+ var createPanelManagerPlugin = (0, import_core3.definePluginCreator)({
267
+ onBind: ({ bind }) => {
268
+ bind(PanelManager).to(PanelManager).inSingletonScope();
269
+ bind(PanelManagerConfig).toConstantValue(defineConfig({}));
270
+ },
271
+ onInit(ctx, opt) {
272
+ ctx.playground.registerLayer(PanelLayer2);
273
+ const config = defineConfig(opt);
274
+ ctx.container.rebind(PanelManagerConfig).toConstantValue(config);
275
+ const panelManager = ctx.container.get(PanelManager);
276
+ panelManager.init();
277
+ }
278
+ });
279
+ // Annotate the CommonJS export names for ESM import in node:
280
+ 0 && (module.exports = {
281
+ PanelManager,
282
+ createPanelManagerPlugin,
283
+ usePanelManager
284
+ });
285
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/create-panel-manager-plugin.ts","../src/services/panel-config.ts","../src/services/panel-manager.ts","../src/services/float-panel.ts","../src/services/panel-layer.ts","../src/components/panel-layer/float-panel.tsx","../src/hooks/use-panel-manager.ts","../src/components/panel-layer/css.ts","../src/components/panel-layer/panel-layer.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\n/** create plugin function */\nexport { createPanelManagerPlugin } from './create-panel-manager-plugin';\n\n/** services */\nexport { PanelManager } from './services';\n\n/** react hooks */\nexport { usePanelManager } from './hooks/use-panel-manager';\n\n/** types */\nexport type { Area, PanelFactory } from './types';\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { definePluginCreator } from '@flowgram.ai/core';\n\nimport { defineConfig } from './services/panel-config';\nimport { PanelManager, PanelManagerConfig, PanelLayer } from './services';\n\nexport const createPanelManagerPlugin = definePluginCreator<Partial<PanelManagerConfig>>({\n onBind: ({ bind }) => {\n bind(PanelManager).to(PanelManager).inSingletonScope();\n bind(PanelManagerConfig).toConstantValue(defineConfig({}));\n },\n onInit(ctx, opt) {\n ctx.playground.registerLayer(PanelLayer);\n const config = defineConfig(opt);\n ctx.container.rebind(PanelManagerConfig).toConstantValue(config);\n const panelManager = ctx.container.get<PanelManager>(PanelManager);\n panelManager.init();\n },\n});\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport type { PanelFactory, PanelConfig } from '../types';\n\nexport interface PanelManagerConfig {\n factories: PanelFactory<any>[];\n right: PanelConfig;\n bottom: PanelConfig;\n}\n\nexport const PanelManagerConfig = Symbol('PanelManagerConfig');\n\nexport const defineConfig = (config: Partial<PanelManagerConfig>) => {\n const defaultConfig: PanelManagerConfig = {\n right: {\n max: 1,\n },\n bottom: {\n max: 1,\n },\n factories: [],\n };\n return {\n ...defaultConfig,\n ...config,\n };\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { injectable, inject } from 'inversify';\n\nimport { PanelManagerConfig } from './panel-config';\nimport type { Area, PanelFactory } from '../types';\nimport { FloatPanel } from './float-panel';\n\n@injectable()\nexport class PanelManager {\n @inject(PanelManagerConfig) private readonly config: PanelManagerConfig;\n\n readonly panelRegistry = new Map<string, PanelFactory<any>>();\n\n right: FloatPanel;\n\n bottom: FloatPanel;\n\n init() {\n this.config.factories.forEach((factory) => this.register(factory));\n this.right = new FloatPanel(this.config.right);\n this.bottom = new FloatPanel(this.config.bottom);\n }\n\n register<T extends any>(factory: PanelFactory<T>) {\n this.panelRegistry.set(factory.key, factory);\n }\n\n open(key: string, area: Area = 'right', options?: any) {\n const factory = this.panelRegistry.get(key);\n if (!factory) {\n return;\n }\n const panel = this.getPanel(area);\n panel.open(factory, options);\n }\n\n close(key: string, area: Area = 'right') {\n const panel = this.getPanel(area);\n panel.close(key);\n }\n\n getPanel(area: Area) {\n return area === 'right' ? this.right : this.bottom;\n }\n\n dispose() {\n this.right.dispose();\n this.bottom.dispose();\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { Emitter } from '@flowgram.ai/utils';\n\nimport type { PanelFactory, PanelConfig } from '../types';\n\nexport interface PanelElement {\n key: string;\n el: React.ReactNode;\n}\n\nexport class FloatPanel {\n elements: PanelElement[] = [];\n\n private onUpdateEmitter = new Emitter<void>();\n\n onUpdate = this.onUpdateEmitter.event;\n\n constructor(private config: PanelConfig) {}\n\n open(factory: PanelFactory<any>, options: any) {\n const el = factory.render(options?.props);\n const idx = this.elements.findIndex((e) => e.key === factory.key);\n if (idx >= 0) {\n this.elements[idx] = { el, key: factory.key };\n } else {\n this.elements.push({ el, key: factory.key });\n if (this.elements.length > this.config.max) {\n this.elements.shift();\n }\n }\n this.onUpdateEmitter.fire();\n }\n\n close(key?: string) {\n if (!key) {\n this.elements = [];\n } else {\n this.elements = this.elements.filter((e) => e.key !== key);\n }\n this.onUpdateEmitter.fire();\n }\n\n dispose() {\n this.elements = [];\n this.onUpdateEmitter.dispose();\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { createElement } from 'react';\n\nimport { injectable } from 'inversify';\nimport { domUtils } from '@flowgram.ai/utils';\nimport { Layer } from '@flowgram.ai/core';\n\nimport { PanelLayer as PanelLayerComp } from '../components/panel-layer';\n\n@injectable()\nexport class PanelLayer extends Layer {\n node = domUtils.createDivWithClass('gedit-flow-panel-layer');\n\n layout: JSX.Element | null = null;\n\n onReady(): void {\n const commonStyle = {\n pointerEvents: 'none',\n zIndex: 11,\n };\n domUtils.setStyle(this.node, commonStyle);\n this.config.onDataChange(() => {\n const { width, height, scrollX, scrollY } = this.config.config;\n domUtils.setStyle(this.node, {\n ...commonStyle,\n width,\n height,\n left: scrollX,\n top: scrollY,\n });\n });\n }\n\n render(): JSX.Element {\n if (!this.layout) {\n this.layout = createElement(PanelLayerComp);\n }\n return this.layout;\n }\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { useEffect, useRef, startTransition, useState } from 'react';\n\nimport { Area } from '../../types';\nimport { usePanelManager } from '../../hooks/use-panel-manager';\nimport { floatPanelWrap } from './css';\n\nexport const FloatPanel: React.FC<{ area: Area }> = ({ area }) => {\n const [, setVersion] = useState(0);\n const panelManager = usePanelManager();\n const panel = useRef(panelManager.getPanel(area));\n const render = () =>\n panel.current.elements.map((i) => (\n <div className=\"float-panel-wrap\" key={i.key} style={floatPanelWrap}>\n {i.el}\n </div>\n ));\n const node = useRef(render());\n\n useEffect(() => {\n const dispose = panel.current.onUpdate(() => {\n startTransition(() => {\n node.current = render();\n setVersion((v) => v + 1);\n });\n });\n return () => dispose.dispose();\n }, [panel]);\n\n return <>{node.current}</>;\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { useService } from '@flowgram.ai/core';\n\nimport { PanelManager } from '../services/panel-manager';\n\nexport const usePanelManager = () => useService<PanelManager>(PanelManager);\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nexport const panelLayer: React.CSSProperties = {\n pointerEvents: 'none',\n position: 'absolute',\n top: 0,\n left: 0,\n\n display: 'flex',\n columnGap: '4px',\n width: '100%',\n height: '100%',\n padding: '4px',\n boxSizing: 'border-box',\n};\n\nexport const leftArea: React.CSSProperties = {\n width: '100%',\n minWidth: 0,\n flexGrow: 0,\n flexShrink: 1,\n\n display: 'flex',\n flexDirection: 'column',\n rowGap: '4px',\n};\n\nexport const rightArea: React.CSSProperties = {\n height: '100%',\n flexGrow: 1,\n flexShrink: 0,\n minWidth: 0,\n\n display: 'flex',\n columnGap: '4px',\n};\n\nexport const mainArea: React.CSSProperties = {\n position: 'relative',\n overflow: 'hidden',\n flexGrow: 0,\n flexShrink: 1,\n width: '100%',\n height: '100%',\n};\n\nexport const bottomArea: React.CSSProperties = {\n flexGrow: 1,\n flexShrink: 0,\n width: '100%',\n minHeight: 0,\n};\n\nexport const floatPanelWrap: React.CSSProperties = {\n pointerEvents: 'auto',\n height: '100%',\n width: '100%',\n};\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { FloatPanel } from './float-panel';\nimport { panelLayer, leftArea, rightArea, mainArea, bottomArea } from './css';\n\nexport const PanelLayer: React.FC<React.PropsWithChildren> = ({ children }) => (\n <div className=\"panel-layer\" style={panelLayer}>\n <div className=\"left-area\" style={leftArea}>\n <div className=\"main-area\" style={mainArea}>\n {children}\n </div>\n <div className=\"bottom-area\" style={bottomArea}>\n <FloatPanel area=\"bottom\" />\n </div>\n </div>\n <div className=\"right-area\" style={rightArea}>\n <FloatPanel area=\"right\" />\n </div>\n </div>\n);\n"],"mappings":"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","names":["import_core","import_react","import_inversify","import_utils","import_core","FloatPanel","import_jsx_runtime","FloatPanel","PanelLayer","PanelLayer"]}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@flowgram.ai/panel-manager-plugin",
3
+ "version": "0.4.15",
4
+ "homepage": "https://flowgram.ai/",
5
+ "repository": "https://github.com/bytedance/flowgram.ai",
6
+ "license": "MIT",
7
+ "exports": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/esm/index.js",
10
+ "require": "./dist/index.js"
11
+ },
12
+ "main": "./dist/index.js",
13
+ "module": "./dist/esm/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "dependencies": {
16
+ "inversify": "^6.0.1",
17
+ "@flowgram.ai/core": "0.4.15",
18
+ "@flowgram.ai/utils": "0.4.15"
19
+ },
20
+ "devDependencies": {
21
+ "react": "^18",
22
+ "@types/react": "^18",
23
+ "tsup": "^8.0.1",
24
+ "typescript": "^5.8.3",
25
+ "@flowgram.ai/eslint-config": "0.4.15",
26
+ "@flowgram.ai/ts-config": "0.4.15"
27
+ },
28
+ "peerDependencies": {
29
+ "react": ">=16.8"
30
+ },
31
+ "peerDependenciesMeta": {
32
+ "react": {
33
+ "optional": true
34
+ }
35
+ },
36
+ "publishConfig": {
37
+ "access": "public",
38
+ "registry": "https://registry.npmjs.org/"
39
+ },
40
+ "scripts": {
41
+ "build": "npm run build:fast -- --dts-resolve",
42
+ "build:fast": "tsup src/index.ts --format cjs,esm --sourcemap --legacy-output",
43
+ "build:watch": "npm run build:fast -- --dts-resolve",
44
+ "clean": "rimraf dist",
45
+ "test": "exit 0",
46
+ "test:cov": "exit 0",
47
+ "ts-check": "tsc --noEmit",
48
+ "watch": "npm run build:fast -- --dts-resolve --watch --ignore-watch dist"
49
+ }
50
+ }
@@ -0,0 +1,21 @@
1
+ Invoking: npm run build:fast -- --dts-resolve
2
+
3
+ > @flowgram.ai/panel-manager-plugin@0.1.8 build:fast
4
+ > tsup src/index.ts --format cjs,esm --sourcemap --legacy-output --dts-resolve
5
+
6
+ CLI Building entry: src/index.ts
7
+ CLI Using tsconfig: tsconfig.json
8
+ CLI tsup v8.5.0
9
+ CLI Target: es2020
10
+ CJS Build start
11
+ ESM Build start
12
+ CJS dist/index.js 8.43 KB
13
+ CJS dist/index.js.map 13.65 KB
14
+ CJS ⚡️ Build success in 99ms
15
+ ESM dist/esm/index.js 6.94 KB
16
+ ESM dist/esm/index.js.map 13.19 KB
17
+ ESM ⚡️ Build success in 103ms
18
+ DTS Build start
19
+ DTS ⚡️ Build success in 3112ms
20
+ DTS dist/index.d.ts 1.87 KB
21
+ DTS dist/index.d.mts 1.87 KB
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export const panelLayer: React.CSSProperties = {
7
+ pointerEvents: 'none',
8
+ position: 'absolute',
9
+ top: 0,
10
+ left: 0,
11
+
12
+ display: 'flex',
13
+ columnGap: '4px',
14
+ width: '100%',
15
+ height: '100%',
16
+ padding: '4px',
17
+ boxSizing: 'border-box',
18
+ };
19
+
20
+ export const leftArea: React.CSSProperties = {
21
+ width: '100%',
22
+ minWidth: 0,
23
+ flexGrow: 0,
24
+ flexShrink: 1,
25
+
26
+ display: 'flex',
27
+ flexDirection: 'column',
28
+ rowGap: '4px',
29
+ };
30
+
31
+ export const rightArea: React.CSSProperties = {
32
+ height: '100%',
33
+ flexGrow: 1,
34
+ flexShrink: 0,
35
+ minWidth: 0,
36
+
37
+ display: 'flex',
38
+ columnGap: '4px',
39
+ };
40
+
41
+ export const mainArea: React.CSSProperties = {
42
+ position: 'relative',
43
+ overflow: 'hidden',
44
+ flexGrow: 0,
45
+ flexShrink: 1,
46
+ width: '100%',
47
+ height: '100%',
48
+ };
49
+
50
+ export const bottomArea: React.CSSProperties = {
51
+ flexGrow: 1,
52
+ flexShrink: 0,
53
+ width: '100%',
54
+ minHeight: 0,
55
+ };
56
+
57
+ export const floatPanelWrap: React.CSSProperties = {
58
+ pointerEvents: 'auto',
59
+ height: '100%',
60
+ width: '100%',
61
+ };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { useEffect, useRef, startTransition, useState } from 'react';
7
+
8
+ import { Area } from '../../types';
9
+ import { usePanelManager } from '../../hooks/use-panel-manager';
10
+ import { floatPanelWrap } from './css';
11
+
12
+ export const FloatPanel: React.FC<{ area: Area }> = ({ area }) => {
13
+ const [, setVersion] = useState(0);
14
+ const panelManager = usePanelManager();
15
+ const panel = useRef(panelManager.getPanel(area));
16
+ const render = () =>
17
+ panel.current.elements.map((i) => (
18
+ <div className="float-panel-wrap" key={i.key} style={floatPanelWrap}>
19
+ {i.el}
20
+ </div>
21
+ ));
22
+ const node = useRef(render());
23
+
24
+ useEffect(() => {
25
+ const dispose = panel.current.onUpdate(() => {
26
+ startTransition(() => {
27
+ node.current = render();
28
+ setVersion((v) => v + 1);
29
+ });
30
+ });
31
+ return () => dispose.dispose();
32
+ }, [panel]);
33
+
34
+ return <>{node.current}</>;
35
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export { PanelLayer } from './panel-layer';
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { FloatPanel } from './float-panel';
7
+ import { panelLayer, leftArea, rightArea, mainArea, bottomArea } from './css';
8
+
9
+ export const PanelLayer: React.FC<React.PropsWithChildren> = ({ children }) => (
10
+ <div className="panel-layer" style={panelLayer}>
11
+ <div className="left-area" style={leftArea}>
12
+ <div className="main-area" style={mainArea}>
13
+ {children}
14
+ </div>
15
+ <div className="bottom-area" style={bottomArea}>
16
+ <FloatPanel area="bottom" />
17
+ </div>
18
+ </div>
19
+ <div className="right-area" style={rightArea}>
20
+ <FloatPanel area="right" />
21
+ </div>
22
+ </div>
23
+ );
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { definePluginCreator } from '@flowgram.ai/core';
7
+
8
+ import { defineConfig } from './services/panel-config';
9
+ import { PanelManager, PanelManagerConfig, PanelLayer } from './services';
10
+
11
+ export const createPanelManagerPlugin = definePluginCreator<Partial<PanelManagerConfig>>({
12
+ onBind: ({ bind }) => {
13
+ bind(PanelManager).to(PanelManager).inSingletonScope();
14
+ bind(PanelManagerConfig).toConstantValue(defineConfig({}));
15
+ },
16
+ onInit(ctx, opt) {
17
+ ctx.playground.registerLayer(PanelLayer);
18
+ const config = defineConfig(opt);
19
+ ctx.container.rebind(PanelManagerConfig).toConstantValue(config);
20
+ const panelManager = ctx.container.get<PanelManager>(PanelManager);
21
+ panelManager.init();
22
+ },
23
+ });
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { useService } from '@flowgram.ai/core';
7
+
8
+ import { PanelManager } from '../services/panel-manager';
9
+
10
+ export const usePanelManager = () => useService<PanelManager>(PanelManager);
package/src/index.ts ADDED
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ /** create plugin function */
7
+ export { createPanelManagerPlugin } from './create-panel-manager-plugin';
8
+
9
+ /** services */
10
+ export { PanelManager } from './services';
11
+
12
+ /** react hooks */
13
+ export { usePanelManager } from './hooks/use-panel-manager';
14
+
15
+ /** types */
16
+ export type { Area, PanelFactory } from './types';