react-resize-demo 1.0.2 → 2.0.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.
- package/CHANGELOG.md +93 -1
- package/README.md +203 -110
- package/dist/components/ResizeHandle/index.js +92 -0
- package/dist/components/ResizeHandle/index.js.map +1 -0
- package/dist/components/ResizePanel/index.js +33 -0
- package/dist/components/ResizePanel/index.js.map +1 -0
- package/dist/components/ResizePanelGroup/index.js +61 -0
- package/dist/components/ResizePanelGroup/index.js.map +1 -0
- package/dist/components/shared/context.js +35 -0
- package/dist/components/shared/context.js.map +1 -0
- package/dist/esm/components/ResizeHandle/index.js +90 -0
- package/dist/esm/components/ResizeHandle/index.js.map +1 -0
- package/dist/esm/components/ResizePanel/index.js +31 -0
- package/dist/esm/components/ResizePanel/index.js.map +1 -0
- package/dist/esm/components/ResizePanelGroup/index.js +59 -0
- package/dist/esm/components/ResizePanelGroup/index.js.map +1 -0
- package/dist/esm/components/shared/context.js +32 -0
- package/dist/esm/components/shared/context.js.map +1 -0
- package/dist/esm/index.js +6 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/utils/resizeAble.js +427 -0
- package/dist/esm/utils/resizeAble.js.map +1 -0
- package/dist/esm/utils/virtualNode.js +164 -0
- package/dist/esm/utils/virtualNode.js.map +1 -0
- package/dist/index.js +9 -721
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +68 -2
- package/dist/utils/resizeAble.js +431 -0
- package/dist/utils/resizeAble.js.map +1 -0
- package/dist/utils/virtualNode.js +168 -0
- package/dist/utils/virtualNode.js.map +1 -0
- package/package.json +30 -3
- package/dist/components/ResizeHandle/index.d.ts +0 -8
- package/dist/components/ResizeHandle/index.d.ts.map +0 -1
- package/dist/components/ResizePanel/index.d.ts +0 -19
- package/dist/components/ResizePanel/index.d.ts.map +0 -1
- package/dist/index.d.ts +0 -22
- package/dist/index.d.ts.map +0 -1
- package/dist/index.esm.js +0 -724
- package/dist/index.esm.js.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/utils/index.d.ts +0 -5
- package/dist/utils/index.d.ts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/ResizePanel/index.tsx"],"sourcesContent":["/**\r\n * 可调整大小的面板组件\r\n * 负责展示面板内容和管理面板的注册/注销\r\n */\r\nimport React, { useRef, useEffect } from 'react';\r\nimport { useResizableContext } from '../shared/context';\r\n\r\nexport interface ResizePanelProps {\r\n children: React.ReactNode;\r\n minSize?: number;\r\n onResize?: (width: number) => void;\r\n}\r\n\r\nexport const ResizePanel: React.FC<ResizePanelProps> = ({\r\n children,\r\n minSize = 100,\r\n // onResize, // 暂时未使用,保留以备将来使用\r\n}) => {\r\n const panelRef = useRef<HTMLDivElement>(null);\r\n const panelIndexRef = useRef<number>(-1);\r\n const { registerPanel, unregisterPanel, direction } = useResizableContext();\r\n \r\n useEffect(() => {\r\n if(!panelRef.current) return;\r\n const panelEl = panelRef.current;\r\n panelIndexRef.current = registerPanel(panelEl, minSize);\r\n return () => {\r\n unregisterPanel(panelEl);\r\n }\r\n }, [minSize, registerPanel, unregisterPanel]);\r\n\r\n return (\r\n <div\r\n ref={panelRef}\r\n style={{\r\n flex: 1,\r\n minWidth: direction === 'horizontal' ? minSize : undefined,\r\n minHeight: direction === 'vertical' ? minSize : undefined,\r\n width: 'auto',\r\n overflow: 'hidden',\r\n position: 'relative',\r\n }}\r\n >\r\n <div style={{height: '100%', padding: 16}}>\r\n {children}\r\n </div>\r\n </div>\r\n )\r\n};\r\n"],"names":["useRef","useResizableContext","useEffect","_jsx"],"mappings":";;;;;;AAaO,MAAM,WAAW,GAA+B,CAAC,EACpD,QAAQ,EACR,OAAO,GAAG,GAAG;AACb;AACH,EAAA,KAAI;AACD,IAAA,MAAM,QAAQ,GAAGA,YAAM,CAAiB,IAAI,CAAC;AAC7C,IAAA,MAAM,aAAa,GAAGA,YAAM,CAAS,EAAE,CAAC;IACxC,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,SAAS,EAAE,GAAGC,2BAAmB,EAAE;IAE3EC,eAAS,CAAC,MAAK;QACX,IAAG,CAAC,QAAQ,CAAC,OAAO;YAAE;AACtB,QAAA,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO;QAChC,aAAa,CAAC,OAAO,GAAG,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC;AACvD,QAAA,OAAO,MAAK;YACR,eAAe,CAAC,OAAO,CAAC;AAC5B,QAAA,CAAC;IACL,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC;AAE7C,IAAA,QACIC,cAAA,CAAA,KAAA,EAAA,EACI,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE;AACH,YAAA,IAAI,EAAE,CAAC;YACP,QAAQ,EAAE,SAAS,KAAK,YAAY,GAAG,OAAO,GAAG,SAAS;YAC1D,SAAS,EAAE,SAAS,KAAK,UAAU,GAAG,OAAO,GAAG,SAAS;AACzD,YAAA,KAAK,EAAE,MAAM;AACb,YAAA,QAAQ,EAAE,QAAQ;AAClB,YAAA,QAAQ,EAAE,UAAU;AACvB,SAAA,EAAA,QAAA,EAEDA,wBAAK,KAAK,EAAE,EAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAC,EAAA,QAAA,EACpC,QAAQ,EAAA,CACP,EAAA,CACJ;AAEd;;;;"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var context = require('../shared/context.js');
|
|
6
|
+
var index = require('../ResizeHandle/index.js');
|
|
7
|
+
|
|
8
|
+
const ResizePanelGroup = ({ children, direction = 'horizontal', style, virtual = false, virtualConfig = {}, }) => {
|
|
9
|
+
const panelInfos = React.useRef([]);
|
|
10
|
+
const [panelCount, setPanelCount] = React.useState(0);
|
|
11
|
+
const registerPanel = React.useCallback((panelEl, minSize) => {
|
|
12
|
+
const index = panelInfos.current.length;
|
|
13
|
+
panelInfos.current.push({ panelEl, minSize });
|
|
14
|
+
setPanelCount(panelInfos.current.length);
|
|
15
|
+
return index;
|
|
16
|
+
}, []);
|
|
17
|
+
const unregisterPanel = React.useCallback((panelEl) => {
|
|
18
|
+
panelInfos.current = panelInfos.current.filter(info => info.panelEl !== panelEl);
|
|
19
|
+
setPanelCount(panelInfos.current.length);
|
|
20
|
+
}, []);
|
|
21
|
+
const getPanelInfo = React.useCallback((index) => {
|
|
22
|
+
return panelInfos.current[index] || null;
|
|
23
|
+
}, []);
|
|
24
|
+
const getPanelIndex = React.useCallback((panelEl) => {
|
|
25
|
+
return panelInfos.current.findIndex(info => info.panelEl === panelEl);
|
|
26
|
+
}, []);
|
|
27
|
+
const childrenArray = React.Children.toArray(children);
|
|
28
|
+
const panelsWithHandles = [];
|
|
29
|
+
childrenArray.forEach((child, index$1) => {
|
|
30
|
+
panelsWithHandles.push(child);
|
|
31
|
+
// 在面板之间插入拖拽器(最后一个面板后不插入)
|
|
32
|
+
if (index$1 < childrenArray.length - 1) {
|
|
33
|
+
panelsWithHandles.push(jsxRuntime.jsx(index.ResizeHandle, { prePanelIndex: index$1, nextPanelIndex: index$1 + 1, direction: direction }, `handle-${index$1}`));
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
// 合并虚拟化配置
|
|
37
|
+
const mergedVirtualConfig = {
|
|
38
|
+
enabled: virtual,
|
|
39
|
+
...virtualConfig,
|
|
40
|
+
};
|
|
41
|
+
const contextValue = {
|
|
42
|
+
panelCount: panelCount,
|
|
43
|
+
registerPanel,
|
|
44
|
+
unregisterPanel,
|
|
45
|
+
getPanelInfo,
|
|
46
|
+
getPanelIndex,
|
|
47
|
+
direction,
|
|
48
|
+
panelInfos: panelInfos.current,
|
|
49
|
+
virtualConfig: mergedVirtualConfig,
|
|
50
|
+
};
|
|
51
|
+
return (jsxRuntime.jsx(context.ResizableContext.Provider, { value: contextValue, children: jsxRuntime.jsx("div", { style: {
|
|
52
|
+
display: 'flex',
|
|
53
|
+
flexDirection: direction === 'horizontal' ? 'row' : 'column',
|
|
54
|
+
height: '100%',
|
|
55
|
+
position: 'relative', // 为虚拟节点定位提供参考
|
|
56
|
+
...style,
|
|
57
|
+
}, children: panelsWithHandles }) }));
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
exports.ResizePanelGroup = ResizePanelGroup;
|
|
61
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/components/ResizePanelGroup/index.tsx"],"sourcesContent":["/**\r\n * 可调整大小的面板组容器组件\r\n * 负责管理多个面板的布局和拖拽手柄的插入\r\n */\r\nimport React, { useRef, useState, useCallback } from 'react';\r\nimport { ResizableContext, ResizableContextValue } from '../shared/context';\r\nimport { ResizeHandle } from '../ResizeHandle';\r\nimport { PanelInfo, VirtualConfig, ResizeDirection } from '../../types';\r\n\r\nexport interface ResizePanelGroupProps {\r\n children: React.ReactNode;\r\n direction?: ResizeDirection;\r\n virtual?: boolean; // 是否启用虚拟化,默认false\r\n virtualConfig?: VirtualConfig; // 虚拟化配置\r\n style?: React.CSSProperties;\r\n}\r\n\r\nexport const ResizePanelGroup: React.FC<ResizePanelGroupProps> = ({\r\n children,\r\n direction = 'horizontal',\r\n style,\r\n virtual = false,\r\n virtualConfig = {},\r\n}) => {\r\n const panelInfos = useRef<PanelInfo[]>([]);\r\n const [panelCount, setPanelCount] = useState(0);\r\n \r\n const registerPanel = useCallback((panelEl: HTMLElement, minSize: number): number => {\r\n const index = panelInfos.current.length;\r\n panelInfos.current.push({ panelEl, minSize });\r\n setPanelCount(panelInfos.current.length);\r\n return index;\r\n }, []);\r\n \r\n const unregisterPanel = useCallback((panelEl: HTMLElement) => {\r\n panelInfos.current = panelInfos.current.filter(info => info.panelEl !== panelEl);\r\n setPanelCount(panelInfos.current.length);\r\n }, []);\r\n \r\n const getPanelInfo = useCallback((index: number): PanelInfo | null => {\r\n return panelInfos.current[index] || null;\r\n }, []);\r\n \r\n const getPanelIndex = useCallback((panelEl: HTMLElement): number => {\r\n return panelInfos.current.findIndex(info => info.panelEl === panelEl);\r\n }, []);\r\n\r\n const childrenArray = React.Children.toArray(children);\r\n const panelsWithHandles: React.ReactNode[] = [];\r\n\r\n childrenArray.forEach((child, index) => {\r\n panelsWithHandles.push(child);\r\n \r\n // 在面板之间插入拖拽器(最后一个面板后不插入)\r\n if (index < childrenArray.length - 1) {\r\n panelsWithHandles.push(\r\n <ResizeHandle\r\n key={`handle-${index}`}\r\n prePanelIndex={index}\r\n nextPanelIndex={index + 1}\r\n direction={direction}\r\n />\r\n );\r\n }\r\n });\r\n\r\n // 合并虚拟化配置\r\n const mergedVirtualConfig: VirtualConfig = {\r\n enabled: virtual,\r\n ...virtualConfig,\r\n };\r\n\r\n const contextValue: ResizableContextValue = {\r\n panelCount: panelCount,\r\n registerPanel, \r\n unregisterPanel,\r\n getPanelInfo,\r\n getPanelIndex,\r\n direction,\r\n panelInfos: panelInfos.current,\r\n virtualConfig: mergedVirtualConfig,\r\n };\r\n\r\n return (\r\n <ResizableContext.Provider value={contextValue}>\r\n <div style={{\r\n display: 'flex',\r\n flexDirection: direction === 'horizontal' ? 'row' : 'column',\r\n height: '100%',\r\n position: 'relative', // 为虚拟节点定位提供参考\r\n ...style,\r\n }}>\r\n {panelsWithHandles}\r\n </div>\r\n </ResizableContext.Provider>\r\n )\r\n};\r\n\r\n"],"names":["useRef","useState","useCallback","index","_jsx","ResizeHandle","ResizableContext"],"mappings":";;;;;;;MAiBa,gBAAgB,GAAoC,CAAC,EAC9D,QAAQ,EACR,SAAS,GAAG,YAAY,EACxB,KAAK,EACL,OAAO,GAAG,KAAK,EACf,aAAa,GAAG,EAAE,GACrB,KAAI;AACD,IAAA,MAAM,UAAU,GAAGA,YAAM,CAAc,EAAE,CAAC;IAC1C,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAGC,cAAQ,CAAC,CAAC,CAAC;IAE/C,MAAM,aAAa,GAAGC,iBAAW,CAAC,CAAC,OAAoB,EAAE,OAAe,KAAY;AAChF,QAAA,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM;QACvC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC7C,QAAA,aAAa,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC;AACxC,QAAA,OAAO,KAAK;IAChB,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,MAAM,eAAe,GAAGA,iBAAW,CAAC,CAAC,OAAoB,KAAI;AACzD,QAAA,UAAU,CAAC,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC;AAChF,QAAA,aAAa,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC;IAC5C,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,MAAM,YAAY,GAAGA,iBAAW,CAAC,CAAC,KAAa,KAAsB;QACjE,OAAO,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI;IAC5C,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,MAAM,aAAa,GAAGA,iBAAW,CAAC,CAAC,OAAoB,KAAY;AAC/D,QAAA,OAAO,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC;IACzE,CAAC,EAAE,EAAE,CAAC;IAEN,MAAM,aAAa,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC;IACtD,MAAM,iBAAiB,GAAsB,EAAE;IAE/C,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,EAAEC,OAAK,KAAI;AACnC,QAAA,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC;;QAG7B,IAAIA,OAAK,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;YAClC,iBAAiB,CAAC,IAAI,CAClBC,cAAA,CAACC,kBAAY,IAET,aAAa,EAAEF,OAAK,EACpB,cAAc,EAAEA,OAAK,GAAG,CAAC,EACzB,SAAS,EAAE,SAAS,EAAA,EAHf,CAAA,OAAA,EAAUA,OAAK,CAAA,CAAE,CAIxB,CACL;QACL;AACJ,IAAA,CAAC,CAAC;;AAGF,IAAA,MAAM,mBAAmB,GAAkB;AACvC,QAAA,OAAO,EAAE,OAAO;AAChB,QAAA,GAAG,aAAa;KACnB;AAED,IAAA,MAAM,YAAY,GAA0B;AACxC,QAAA,UAAU,EAAE,UAAU;QACtB,aAAa;QACb,eAAe;QACf,YAAY;QACZ,aAAa;QACb,SAAS;QACT,UAAU,EAAE,UAAU,CAAC,OAAO;AAC9B,QAAA,aAAa,EAAE,mBAAmB;KACrC;AAED,IAAA,QACIC,cAAA,CAACE,wBAAgB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,YAAY,EAAA,QAAA,EAC1CF,cAAA,CAAA,KAAA,EAAA,EAAK,KAAK,EAAE;AACJ,gBAAA,OAAO,EAAE,MAAM;gBACf,aAAa,EAAE,SAAS,KAAK,YAAY,GAAG,KAAK,GAAG,QAAQ;AAC5D,gBAAA,MAAM,EAAE,MAAM;gBACd,QAAQ,EAAE,UAAU;AACpB,gBAAA,GAAG,KAAK;AACf,aAAA,EAAA,QAAA,EACI,iBAAiB,EAAA,CAChB,EAAA,CACkB;AAEpC;;;;"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Resizable Context 默认值
|
|
7
|
+
*/
|
|
8
|
+
const defaultContextValue = {
|
|
9
|
+
panelCount: 0,
|
|
10
|
+
registerPanel: () => 0,
|
|
11
|
+
unregisterPanel: () => { },
|
|
12
|
+
getPanelInfo: () => null,
|
|
13
|
+
getPanelIndex: () => -1,
|
|
14
|
+
direction: 'horizontal',
|
|
15
|
+
panelInfos: [],
|
|
16
|
+
virtualConfig: { enabled: false },
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Resizable Context
|
|
20
|
+
*/
|
|
21
|
+
const ResizableContext = React.createContext(defaultContextValue);
|
|
22
|
+
/**
|
|
23
|
+
* 使用 Resizable Context 的 Hook
|
|
24
|
+
*/
|
|
25
|
+
const useResizableContext = () => {
|
|
26
|
+
const context = React.useContext(ResizableContext);
|
|
27
|
+
if (!context) {
|
|
28
|
+
throw new Error('useResizableContext must be used within ResizablePanelGroup');
|
|
29
|
+
}
|
|
30
|
+
return context;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
exports.ResizableContext = ResizableContext;
|
|
34
|
+
exports.useResizableContext = useResizableContext;
|
|
35
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sources":["../../../src/components/shared/context.tsx"],"sourcesContent":["import React from 'react';\r\nimport { PanelInfo, VirtualConfig, ResizeDirection } from '../../types';\r\n\r\n/**\r\n * Resizable Context 接口定义\r\n */\r\nexport interface ResizableContextValue {\r\n panelCount: number;\r\n registerPanel: (panelEl: HTMLElement, minSize: number) => number; // 返回索引\r\n unregisterPanel: (panelEl: HTMLElement) => void;\r\n getPanelInfo: (index: number) => PanelInfo | null;\r\n getPanelIndex: (panelEl: HTMLElement) => number;\r\n direction: ResizeDirection;\r\n panelInfos: PanelInfo[];\r\n virtualConfig: VirtualConfig;\r\n}\r\n\r\n/**\r\n * Resizable Context 默认值\r\n */\r\nconst defaultContextValue: ResizableContextValue = {\r\n panelCount: 0,\r\n registerPanel: () => 0,\r\n unregisterPanel: () => {},\r\n getPanelInfo: () => null,\r\n getPanelIndex: () => -1,\r\n direction: 'horizontal',\r\n panelInfos: [],\r\n virtualConfig: { enabled: false },\r\n};\r\n\r\n/**\r\n * Resizable Context\r\n */\r\nexport const ResizableContext = React.createContext<ResizableContextValue>(defaultContextValue);\r\n\r\n/**\r\n * 使用 Resizable Context 的 Hook\r\n */\r\nexport const useResizableContext = () => {\r\n const context = React.useContext(ResizableContext);\r\n if (!context) {\r\n throw new Error('useResizableContext must be used within ResizablePanelGroup');\r\n }\r\n return context;\r\n};\r\n\r\n"],"names":[],"mappings":";;;;AAiBA;;AAEG;AACH,MAAM,mBAAmB,GAA0B;AAC/C,IAAA,UAAU,EAAE,CAAC;AACb,IAAA,aAAa,EAAE,MAAM,CAAC;AACtB,IAAA,eAAe,EAAE,MAAK,EAAE,CAAC;AACzB,IAAA,YAAY,EAAE,MAAM,IAAI;AACxB,IAAA,aAAa,EAAE,MAAM,EAAE;AACvB,IAAA,SAAS,EAAE,YAAY;AACvB,IAAA,UAAU,EAAE,EAAE;AACd,IAAA,aAAa,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;CACpC;AAED;;AAEG;AACI,MAAM,gBAAgB,GAAG,KAAK,CAAC,aAAa,CAAwB,mBAAmB;AAE9F;;AAEG;AACI,MAAM,mBAAmB,GAAG,MAAK;IACpC,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,gBAAgB,CAAC;IAClD,IAAI,CAAC,OAAO,EAAE;AACV,QAAA,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC;IAClF;AACA,IAAA,OAAO,OAAO;AAClB;;;;;"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useRef, useEffect } from 'react';
|
|
3
|
+
import ResizeAbleCore from '../../utils/resizeAble.js';
|
|
4
|
+
import { useResizableContext } from '../shared/context.js';
|
|
5
|
+
|
|
6
|
+
const ResizeHandle = ({ prePanelIndex, nextPanelIndex, direction, }) => {
|
|
7
|
+
const handleRef = useRef(null);
|
|
8
|
+
const coreInstanceRef = useRef(null);
|
|
9
|
+
const { getPanelInfo, panelCount, virtualConfig } = useResizableContext();
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
// 确保所需的面板索引都已注册
|
|
12
|
+
// 需要确保 nextPanelIndex 对应的面板已经注册(因为索引从0开始,所以需要 >= nextPanelIndex + 1)
|
|
13
|
+
if (panelCount <= nextPanelIndex || !handleRef.current) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const prePanelInfo = getPanelInfo(prePanelIndex);
|
|
17
|
+
const nextPanelInfo = getPanelInfo(nextPanelIndex);
|
|
18
|
+
if (!prePanelInfo || !nextPanelInfo)
|
|
19
|
+
return;
|
|
20
|
+
// 获取拖拽器的尺寸
|
|
21
|
+
const handleSize = handleRef.current
|
|
22
|
+
? (direction === 'horizontal'
|
|
23
|
+
? handleRef.current.offsetWidth
|
|
24
|
+
: handleRef.current.offsetHeight)
|
|
25
|
+
: (direction === 'horizontal' ? 10 : 10); // 默认10px
|
|
26
|
+
coreInstanceRef.current = new ResizeAbleCore({
|
|
27
|
+
prePanelEl: prePanelInfo.panelEl,
|
|
28
|
+
nextPanelEl: nextPanelInfo.panelEl,
|
|
29
|
+
getPanelInfo,
|
|
30
|
+
prePanelIndex,
|
|
31
|
+
nextPanelIndex,
|
|
32
|
+
direction,
|
|
33
|
+
virtualEnabled: virtualConfig.enabled || false,
|
|
34
|
+
virtualConfig: {
|
|
35
|
+
style: virtualConfig.style,
|
|
36
|
+
className: virtualConfig.className,
|
|
37
|
+
},
|
|
38
|
+
handleSize, // 传递拖拽器尺寸
|
|
39
|
+
});
|
|
40
|
+
// 将拖拽器的开始/移动/结束事件绑定至核心类
|
|
41
|
+
const handleEl = handleRef.current;
|
|
42
|
+
let isResizing = false;
|
|
43
|
+
let startPos = 0;
|
|
44
|
+
const startResize = (e) => {
|
|
45
|
+
e.preventDefault();
|
|
46
|
+
isResizing = true;
|
|
47
|
+
startPos = direction === 'horizontal' ? e.clientX : e.clientY;
|
|
48
|
+
if (coreInstanceRef.current) {
|
|
49
|
+
coreInstanceRef.current.startResize();
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const onResizeMove = (e) => {
|
|
53
|
+
if (!isResizing || !coreInstanceRef.current)
|
|
54
|
+
return;
|
|
55
|
+
const currentPos = direction === 'horizontal' ? e.clientX : e.clientY;
|
|
56
|
+
const delta = currentPos - startPos;
|
|
57
|
+
coreInstanceRef.current.onResize(delta);
|
|
58
|
+
};
|
|
59
|
+
const endResize = () => {
|
|
60
|
+
if (isResizing && coreInstanceRef.current) {
|
|
61
|
+
isResizing = false;
|
|
62
|
+
coreInstanceRef.current.endResize();
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
handleEl.addEventListener('mousedown', startResize);
|
|
66
|
+
document.addEventListener('mousemove', onResizeMove);
|
|
67
|
+
document.addEventListener('mouseup', endResize);
|
|
68
|
+
return () => {
|
|
69
|
+
handleEl.removeEventListener('mousedown', startResize);
|
|
70
|
+
document.removeEventListener('mousemove', onResizeMove);
|
|
71
|
+
document.removeEventListener('mouseup', endResize);
|
|
72
|
+
if (coreInstanceRef.current) {
|
|
73
|
+
coreInstanceRef.current.destroy();
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}, [prePanelIndex, nextPanelIndex, direction, getPanelInfo, panelCount, virtualConfig]);
|
|
77
|
+
const isHorizontal = direction === 'horizontal';
|
|
78
|
+
return (jsx("div", { ref: handleRef, style: {
|
|
79
|
+
position: 'relative',
|
|
80
|
+
width: isHorizontal ? '10px' : '100%',
|
|
81
|
+
height: isHorizontal ? '100%' : '10px',
|
|
82
|
+
backgroundColor: '#000',
|
|
83
|
+
cursor: isHorizontal ? 'ew-resize' : 'ns-resize',
|
|
84
|
+
zIndex: 1000,
|
|
85
|
+
flexShrink: 0,
|
|
86
|
+
} }));
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export { ResizeHandle };
|
|
90
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/ResizeHandle/index.tsx"],"sourcesContent":["/**\r\n * 拖拽手柄组件\r\n * 负责处理面板之间的拖拽调整功能\r\n */\r\nimport React, { useRef, useEffect } from 'react';\r\nimport ResizeAbleCore from '../../utils/resizeAble';\r\nimport { useResizableContext } from '../shared/context';\r\nimport { ResizeDirection } from '../../types';\r\n\r\nexport interface ResizeHandleProps {\r\n prePanelIndex: number;\r\n nextPanelIndex: number;\r\n direction: ResizeDirection;\r\n}\r\n\r\nexport const ResizeHandle: React.FC<ResizeHandleProps> = ({\r\n prePanelIndex,\r\n nextPanelIndex,\r\n direction,\r\n}) => {\r\n const handleRef = useRef<HTMLDivElement>(null);\r\n const coreInstanceRef = useRef<InstanceType<typeof ResizeAbleCore> | null>(null);\r\n const { getPanelInfo, panelCount, virtualConfig } = useResizableContext();\r\n\r\n useEffect(() => {\r\n // 确保所需的面板索引都已注册\r\n // 需要确保 nextPanelIndex 对应的面板已经注册(因为索引从0开始,所以需要 >= nextPanelIndex + 1)\r\n if (panelCount <= nextPanelIndex || !handleRef.current) {\r\n return;\r\n }\r\n \r\n const prePanelInfo = getPanelInfo(prePanelIndex);\r\n const nextPanelInfo = getPanelInfo(nextPanelIndex);\r\n if(!prePanelInfo || !nextPanelInfo) return;\r\n \r\n // 获取拖拽器的尺寸\r\n const handleSize = handleRef.current \r\n ? (direction === 'horizontal' \r\n ? handleRef.current.offsetWidth \r\n : handleRef.current.offsetHeight)\r\n : (direction === 'horizontal' ? 10 : 10); // 默认10px\r\n \r\n coreInstanceRef.current = new ResizeAbleCore({\r\n prePanelEl: prePanelInfo.panelEl,\r\n nextPanelEl: nextPanelInfo.panelEl,\r\n getPanelInfo,\r\n prePanelIndex,\r\n nextPanelIndex,\r\n direction,\r\n virtualEnabled: virtualConfig.enabled || false,\r\n virtualConfig: {\r\n style: virtualConfig.style,\r\n className: virtualConfig.className,\r\n },\r\n handleSize, // 传递拖拽器尺寸\r\n });\r\n\r\n // 将拖拽器的开始/移动/结束事件绑定至核心类\r\n const handleEl = handleRef.current;\r\n let isResizing = false;\r\n let startPos = 0;\r\n\r\n const startResize = (e: MouseEvent) => {\r\n e.preventDefault();\r\n isResizing = true;\r\n startPos = direction === 'horizontal' ? e.clientX : e.clientY;\r\n if (coreInstanceRef.current) {\r\n coreInstanceRef.current.startResize();\r\n }\r\n };\r\n \r\n const onResizeMove = (e: MouseEvent) => {\r\n if(!isResizing || !coreInstanceRef.current) return;\r\n const currentPos = direction === 'horizontal' ? e.clientX : e.clientY;\r\n const delta = currentPos - startPos;\r\n coreInstanceRef.current.onResize(delta);\r\n };\r\n \r\n const endResize = () => {\r\n if(isResizing && coreInstanceRef.current) {\r\n isResizing = false;\r\n coreInstanceRef.current.endResize();\r\n }\r\n }\r\n \r\n handleEl.addEventListener('mousedown', startResize);\r\n document.addEventListener('mousemove', onResizeMove);\r\n document.addEventListener('mouseup', endResize);\r\n \r\n return () => {\r\n handleEl.removeEventListener('mousedown', startResize);\r\n document.removeEventListener('mousemove', onResizeMove);\r\n document.removeEventListener('mouseup', endResize);\r\n if(coreInstanceRef.current) {\r\n coreInstanceRef.current.destroy();\r\n }\r\n }\r\n }, [prePanelIndex, nextPanelIndex, direction, getPanelInfo, panelCount, virtualConfig]);\r\n\r\n const isHorizontal = direction === 'horizontal';\r\n return (\r\n <div\r\n ref={handleRef}\r\n style={{\r\n position: 'relative',\r\n width: isHorizontal ? '10px' : '100%',\r\n height: isHorizontal ? '100%' : '10px',\r\n backgroundColor: '#000',\r\n cursor: isHorizontal ? 'ew-resize' : 'ns-resize',\r\n zIndex: 1000,\r\n flexShrink: 0,\r\n }}\r\n />\r\n )\r\n};\r\n\r\n"],"names":["_jsx"],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useRef, useEffect } from 'react';
|
|
3
|
+
import { useResizableContext } from '../shared/context.js';
|
|
4
|
+
|
|
5
|
+
const ResizePanel = ({ children, minSize = 100,
|
|
6
|
+
// onResize, // 暂时未使用,保留以备将来使用
|
|
7
|
+
}) => {
|
|
8
|
+
const panelRef = useRef(null);
|
|
9
|
+
const panelIndexRef = useRef(-1);
|
|
10
|
+
const { registerPanel, unregisterPanel, direction } = useResizableContext();
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!panelRef.current)
|
|
13
|
+
return;
|
|
14
|
+
const panelEl = panelRef.current;
|
|
15
|
+
panelIndexRef.current = registerPanel(panelEl, minSize);
|
|
16
|
+
return () => {
|
|
17
|
+
unregisterPanel(panelEl);
|
|
18
|
+
};
|
|
19
|
+
}, [minSize, registerPanel, unregisterPanel]);
|
|
20
|
+
return (jsx("div", { ref: panelRef, style: {
|
|
21
|
+
flex: 1,
|
|
22
|
+
minWidth: direction === 'horizontal' ? minSize : undefined,
|
|
23
|
+
minHeight: direction === 'vertical' ? minSize : undefined,
|
|
24
|
+
width: 'auto',
|
|
25
|
+
overflow: 'hidden',
|
|
26
|
+
position: 'relative',
|
|
27
|
+
}, children: jsx("div", { style: { height: '100%', padding: 16 }, children: children }) }));
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export { ResizePanel };
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/ResizePanel/index.tsx"],"sourcesContent":["/**\r\n * 可调整大小的面板组件\r\n * 负责展示面板内容和管理面板的注册/注销\r\n */\r\nimport React, { useRef, useEffect } from 'react';\r\nimport { useResizableContext } from '../shared/context';\r\n\r\nexport interface ResizePanelProps {\r\n children: React.ReactNode;\r\n minSize?: number;\r\n onResize?: (width: number) => void;\r\n}\r\n\r\nexport const ResizePanel: React.FC<ResizePanelProps> = ({\r\n children,\r\n minSize = 100,\r\n // onResize, // 暂时未使用,保留以备将来使用\r\n}) => {\r\n const panelRef = useRef<HTMLDivElement>(null);\r\n const panelIndexRef = useRef<number>(-1);\r\n const { registerPanel, unregisterPanel, direction } = useResizableContext();\r\n \r\n useEffect(() => {\r\n if(!panelRef.current) return;\r\n const panelEl = panelRef.current;\r\n panelIndexRef.current = registerPanel(panelEl, minSize);\r\n return () => {\r\n unregisterPanel(panelEl);\r\n }\r\n }, [minSize, registerPanel, unregisterPanel]);\r\n\r\n return (\r\n <div\r\n ref={panelRef}\r\n style={{\r\n flex: 1,\r\n minWidth: direction === 'horizontal' ? minSize : undefined,\r\n minHeight: direction === 'vertical' ? minSize : undefined,\r\n width: 'auto',\r\n overflow: 'hidden',\r\n position: 'relative',\r\n }}\r\n >\r\n <div style={{height: '100%', padding: 16}}>\r\n {children}\r\n </div>\r\n </div>\r\n )\r\n};\r\n"],"names":["_jsx"],"mappings":";;;;AAaO,MAAM,WAAW,GAA+B,CAAC,EACpD,QAAQ,EACR,OAAO,GAAG,GAAG;AACb;AACH,EAAA,KAAI;AACD,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAiB,IAAI,CAAC;AAC7C,IAAA,MAAM,aAAa,GAAG,MAAM,CAAS,EAAE,CAAC;IACxC,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,SAAS,EAAE,GAAG,mBAAmB,EAAE;IAE3E,SAAS,CAAC,MAAK;QACX,IAAG,CAAC,QAAQ,CAAC,OAAO;YAAE;AACtB,QAAA,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO;QAChC,aAAa,CAAC,OAAO,GAAG,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC;AACvD,QAAA,OAAO,MAAK;YACR,eAAe,CAAC,OAAO,CAAC;AAC5B,QAAA,CAAC;IACL,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC;AAE7C,IAAA,QACIA,GAAA,CAAA,KAAA,EAAA,EACI,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE;AACH,YAAA,IAAI,EAAE,CAAC;YACP,QAAQ,EAAE,SAAS,KAAK,YAAY,GAAG,OAAO,GAAG,SAAS;YAC1D,SAAS,EAAE,SAAS,KAAK,UAAU,GAAG,OAAO,GAAG,SAAS;AACzD,YAAA,KAAK,EAAE,MAAM;AACb,YAAA,QAAQ,EAAE,QAAQ;AAClB,YAAA,QAAQ,EAAE,UAAU;AACvB,SAAA,EAAA,QAAA,EAEDA,aAAK,KAAK,EAAE,EAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAC,EAAA,QAAA,EACpC,QAAQ,EAAA,CACP,EAAA,CACJ;AAEd;;;;"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import React, { useRef, useState, useCallback } from 'react';
|
|
3
|
+
import { ResizableContext } from '../shared/context.js';
|
|
4
|
+
import { ResizeHandle } from '../ResizeHandle/index.js';
|
|
5
|
+
|
|
6
|
+
const ResizePanelGroup = ({ children, direction = 'horizontal', style, virtual = false, virtualConfig = {}, }) => {
|
|
7
|
+
const panelInfos = useRef([]);
|
|
8
|
+
const [panelCount, setPanelCount] = useState(0);
|
|
9
|
+
const registerPanel = useCallback((panelEl, minSize) => {
|
|
10
|
+
const index = panelInfos.current.length;
|
|
11
|
+
panelInfos.current.push({ panelEl, minSize });
|
|
12
|
+
setPanelCount(panelInfos.current.length);
|
|
13
|
+
return index;
|
|
14
|
+
}, []);
|
|
15
|
+
const unregisterPanel = useCallback((panelEl) => {
|
|
16
|
+
panelInfos.current = panelInfos.current.filter(info => info.panelEl !== panelEl);
|
|
17
|
+
setPanelCount(panelInfos.current.length);
|
|
18
|
+
}, []);
|
|
19
|
+
const getPanelInfo = useCallback((index) => {
|
|
20
|
+
return panelInfos.current[index] || null;
|
|
21
|
+
}, []);
|
|
22
|
+
const getPanelIndex = useCallback((panelEl) => {
|
|
23
|
+
return panelInfos.current.findIndex(info => info.panelEl === panelEl);
|
|
24
|
+
}, []);
|
|
25
|
+
const childrenArray = React.Children.toArray(children);
|
|
26
|
+
const panelsWithHandles = [];
|
|
27
|
+
childrenArray.forEach((child, index) => {
|
|
28
|
+
panelsWithHandles.push(child);
|
|
29
|
+
// 在面板之间插入拖拽器(最后一个面板后不插入)
|
|
30
|
+
if (index < childrenArray.length - 1) {
|
|
31
|
+
panelsWithHandles.push(jsx(ResizeHandle, { prePanelIndex: index, nextPanelIndex: index + 1, direction: direction }, `handle-${index}`));
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
// 合并虚拟化配置
|
|
35
|
+
const mergedVirtualConfig = {
|
|
36
|
+
enabled: virtual,
|
|
37
|
+
...virtualConfig,
|
|
38
|
+
};
|
|
39
|
+
const contextValue = {
|
|
40
|
+
panelCount: panelCount,
|
|
41
|
+
registerPanel,
|
|
42
|
+
unregisterPanel,
|
|
43
|
+
getPanelInfo,
|
|
44
|
+
getPanelIndex,
|
|
45
|
+
direction,
|
|
46
|
+
panelInfos: panelInfos.current,
|
|
47
|
+
virtualConfig: mergedVirtualConfig,
|
|
48
|
+
};
|
|
49
|
+
return (jsx(ResizableContext.Provider, { value: contextValue, children: jsx("div", { style: {
|
|
50
|
+
display: 'flex',
|
|
51
|
+
flexDirection: direction === 'horizontal' ? 'row' : 'column',
|
|
52
|
+
height: '100%',
|
|
53
|
+
position: 'relative', // 为虚拟节点定位提供参考
|
|
54
|
+
...style,
|
|
55
|
+
}, children: panelsWithHandles }) }));
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export { ResizePanelGroup };
|
|
59
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/ResizePanelGroup/index.tsx"],"sourcesContent":["/**\r\n * 可调整大小的面板组容器组件\r\n * 负责管理多个面板的布局和拖拽手柄的插入\r\n */\r\nimport React, { useRef, useState, useCallback } from 'react';\r\nimport { ResizableContext, ResizableContextValue } from '../shared/context';\r\nimport { ResizeHandle } from '../ResizeHandle';\r\nimport { PanelInfo, VirtualConfig, ResizeDirection } from '../../types';\r\n\r\nexport interface ResizePanelGroupProps {\r\n children: React.ReactNode;\r\n direction?: ResizeDirection;\r\n virtual?: boolean; // 是否启用虚拟化,默认false\r\n virtualConfig?: VirtualConfig; // 虚拟化配置\r\n style?: React.CSSProperties;\r\n}\r\n\r\nexport const ResizePanelGroup: React.FC<ResizePanelGroupProps> = ({\r\n children,\r\n direction = 'horizontal',\r\n style,\r\n virtual = false,\r\n virtualConfig = {},\r\n}) => {\r\n const panelInfos = useRef<PanelInfo[]>([]);\r\n const [panelCount, setPanelCount] = useState(0);\r\n \r\n const registerPanel = useCallback((panelEl: HTMLElement, minSize: number): number => {\r\n const index = panelInfos.current.length;\r\n panelInfos.current.push({ panelEl, minSize });\r\n setPanelCount(panelInfos.current.length);\r\n return index;\r\n }, []);\r\n \r\n const unregisterPanel = useCallback((panelEl: HTMLElement) => {\r\n panelInfos.current = panelInfos.current.filter(info => info.panelEl !== panelEl);\r\n setPanelCount(panelInfos.current.length);\r\n }, []);\r\n \r\n const getPanelInfo = useCallback((index: number): PanelInfo | null => {\r\n return panelInfos.current[index] || null;\r\n }, []);\r\n \r\n const getPanelIndex = useCallback((panelEl: HTMLElement): number => {\r\n return panelInfos.current.findIndex(info => info.panelEl === panelEl);\r\n }, []);\r\n\r\n const childrenArray = React.Children.toArray(children);\r\n const panelsWithHandles: React.ReactNode[] = [];\r\n\r\n childrenArray.forEach((child, index) => {\r\n panelsWithHandles.push(child);\r\n \r\n // 在面板之间插入拖拽器(最后一个面板后不插入)\r\n if (index < childrenArray.length - 1) {\r\n panelsWithHandles.push(\r\n <ResizeHandle\r\n key={`handle-${index}`}\r\n prePanelIndex={index}\r\n nextPanelIndex={index + 1}\r\n direction={direction}\r\n />\r\n );\r\n }\r\n });\r\n\r\n // 合并虚拟化配置\r\n const mergedVirtualConfig: VirtualConfig = {\r\n enabled: virtual,\r\n ...virtualConfig,\r\n };\r\n\r\n const contextValue: ResizableContextValue = {\r\n panelCount: panelCount,\r\n registerPanel, \r\n unregisterPanel,\r\n getPanelInfo,\r\n getPanelIndex,\r\n direction,\r\n panelInfos: panelInfos.current,\r\n virtualConfig: mergedVirtualConfig,\r\n };\r\n\r\n return (\r\n <ResizableContext.Provider value={contextValue}>\r\n <div style={{\r\n display: 'flex',\r\n flexDirection: direction === 'horizontal' ? 'row' : 'column',\r\n height: '100%',\r\n position: 'relative', // 为虚拟节点定位提供参考\r\n ...style,\r\n }}>\r\n {panelsWithHandles}\r\n </div>\r\n </ResizableContext.Provider>\r\n )\r\n};\r\n\r\n"],"names":["_jsx"],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resizable Context 默认值
|
|
5
|
+
*/
|
|
6
|
+
const defaultContextValue = {
|
|
7
|
+
panelCount: 0,
|
|
8
|
+
registerPanel: () => 0,
|
|
9
|
+
unregisterPanel: () => { },
|
|
10
|
+
getPanelInfo: () => null,
|
|
11
|
+
getPanelIndex: () => -1,
|
|
12
|
+
direction: 'horizontal',
|
|
13
|
+
panelInfos: [],
|
|
14
|
+
virtualConfig: { enabled: false },
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Resizable Context
|
|
18
|
+
*/
|
|
19
|
+
const ResizableContext = React.createContext(defaultContextValue);
|
|
20
|
+
/**
|
|
21
|
+
* 使用 Resizable Context 的 Hook
|
|
22
|
+
*/
|
|
23
|
+
const useResizableContext = () => {
|
|
24
|
+
const context = React.useContext(ResizableContext);
|
|
25
|
+
if (!context) {
|
|
26
|
+
throw new Error('useResizableContext must be used within ResizablePanelGroup');
|
|
27
|
+
}
|
|
28
|
+
return context;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export { ResizableContext, useResizableContext };
|
|
32
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sources":["../../../../src/components/shared/context.tsx"],"sourcesContent":["import React from 'react';\r\nimport { PanelInfo, VirtualConfig, ResizeDirection } from '../../types';\r\n\r\n/**\r\n * Resizable Context 接口定义\r\n */\r\nexport interface ResizableContextValue {\r\n panelCount: number;\r\n registerPanel: (panelEl: HTMLElement, minSize: number) => number; // 返回索引\r\n unregisterPanel: (panelEl: HTMLElement) => void;\r\n getPanelInfo: (index: number) => PanelInfo | null;\r\n getPanelIndex: (panelEl: HTMLElement) => number;\r\n direction: ResizeDirection;\r\n panelInfos: PanelInfo[];\r\n virtualConfig: VirtualConfig;\r\n}\r\n\r\n/**\r\n * Resizable Context 默认值\r\n */\r\nconst defaultContextValue: ResizableContextValue = {\r\n panelCount: 0,\r\n registerPanel: () => 0,\r\n unregisterPanel: () => {},\r\n getPanelInfo: () => null,\r\n getPanelIndex: () => -1,\r\n direction: 'horizontal',\r\n panelInfos: [],\r\n virtualConfig: { enabled: false },\r\n};\r\n\r\n/**\r\n * Resizable Context\r\n */\r\nexport const ResizableContext = React.createContext<ResizableContextValue>(defaultContextValue);\r\n\r\n/**\r\n * 使用 Resizable Context 的 Hook\r\n */\r\nexport const useResizableContext = () => {\r\n const context = React.useContext(ResizableContext);\r\n if (!context) {\r\n throw new Error('useResizableContext must be used within ResizablePanelGroup');\r\n }\r\n return context;\r\n};\r\n\r\n"],"names":[],"mappings":";;AAiBA;;AAEG;AACH,MAAM,mBAAmB,GAA0B;AAC/C,IAAA,UAAU,EAAE,CAAC;AACb,IAAA,aAAa,EAAE,MAAM,CAAC;AACtB,IAAA,eAAe,EAAE,MAAK,EAAE,CAAC;AACzB,IAAA,YAAY,EAAE,MAAM,IAAI;AACxB,IAAA,aAAa,EAAE,MAAM,EAAE;AACvB,IAAA,SAAS,EAAE,YAAY;AACvB,IAAA,UAAU,EAAE,EAAE;AACd,IAAA,aAAa,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;CACpC;AAED;;AAEG;AACI,MAAM,gBAAgB,GAAG,KAAK,CAAC,aAAa,CAAwB,mBAAmB;AAE9F;;AAEG;AACI,MAAM,mBAAmB,GAAG,MAAK;IACpC,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,gBAAgB,CAAC;IAClD,IAAI,CAAC,OAAO,EAAE;AACV,QAAA,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC;IAClF;AACA,IAAA,OAAO,OAAO;AAClB;;;;"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { ResizePanelGroup as ResizablePanelGroup, ResizePanelGroup as ResizeablePanelGroup } from './components/ResizePanelGroup/index.js';
|
|
2
|
+
export { ResizePanel as ResizablePanel, ResizePanel as ResizeablePanel } from './components/ResizePanel/index.js';
|
|
3
|
+
import 'react/jsx-runtime';
|
|
4
|
+
import 'react';
|
|
5
|
+
import './components/shared/context.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|