float-panel.tsx 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. /**
  2. * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
  3. * SPDX-License-Identifier: MIT
  4. */
  5. import { useEffect, useRef, startTransition, useState, useCallback } from 'react';
  6. import { Area } from '../../types';
  7. import { usePanelManager } from '../../hooks/use-panel-manager';
  8. import { floatPanelWrap } from './css';
  9. import { ResizeBar } from '../resize-bar';
  10. export const FloatPanel: React.FC<{ area: Area }> = ({ area }) => {
  11. const [, setVersion] = useState(0);
  12. const panelManager = usePanelManager();
  13. const panel = useRef(panelManager.getPanel(area));
  14. const render = () =>
  15. panel.current.elements.map((i) => (
  16. <div className="float-panel-wrap" key={i.key} style={{ ...floatPanelWrap, ...i.style }}>
  17. {i.el}
  18. </div>
  19. ));
  20. const node = useRef(render());
  21. useEffect(() => {
  22. const dispose = panel.current.onUpdate(() => {
  23. startTransition(() => {
  24. node.current = render();
  25. setVersion((v) => v + 1);
  26. });
  27. });
  28. return () => dispose.dispose();
  29. }, [panel]);
  30. const onResize = useCallback((newSize: number) => panel.current!.updateSize(newSize), []);
  31. const size = panel.current!.currentSize;
  32. const sizeStyle =
  33. area === 'right' ? { width: size, height: '100%' } : { height: size, width: '100%' };
  34. return (
  35. <div
  36. className="gedit-flow-panel"
  37. style={{
  38. position: 'relative',
  39. display: panel.current.visible ? 'block' : 'none',
  40. ...sizeStyle,
  41. }}
  42. >
  43. {panelManager.config.autoResize && (
  44. <ResizeBar size={size} isVertical={area === 'right'} onResize={onResize} />
  45. )}
  46. {node.current}
  47. </div>
  48. );
  49. };