diff --git a/packages/libs/components/src/stories/plots/Barplot.stories.tsx b/packages/libs/components/src/stories/plots/Barplot.stories.tsx index 7503231997..a43cfdb8dc 100644 --- a/packages/libs/components/src/stories/plots/Barplot.stories.tsx +++ b/packages/libs/components/src/stories/plots/Barplot.stories.tsx @@ -6,6 +6,9 @@ import FacetedBarplot from '../../plots/facetedPlots/FacetedBarplot'; import AxisRangeControl from '../../components/plotControls/AxisRangeControl'; import { NumberRange, NumberOrDateRange } from '../../types/general'; import { Toggle } from '@veupathdb/coreui'; +import DraggablePanel, { + HeightAndWidthInPixels, +} from '@veupathdb/coreui/lib/components/containers/DraggablePanel'; export default { title: 'Plots/Barplot', @@ -185,3 +188,47 @@ LogScale.args = { width: '750px', }, }; + +// demo plot resize with draggable panel +export const PlotResizeWithDraggablePanel: Story = (args) => { + const panelTitle = 'Panel 1'; + const draggablePanelHeight = 600; + const draggablePanelWidth = 900; + + const [panelDimension, setPanelDimension] = useState({ + height: draggablePanelHeight, + width: draggablePanelWidth, + }); + + return ( + { + setPanelDimension(dimensions); + }} + > + + + ); +}; diff --git a/packages/libs/coreui/src/components/containers/DraggablePanel/index.tsx b/packages/libs/coreui/src/components/containers/DraggablePanel/index.tsx index 7206c84a3a..970c76dcf2 100644 --- a/packages/libs/coreui/src/components/containers/DraggablePanel/index.tsx +++ b/packages/libs/coreui/src/components/containers/DraggablePanel/index.tsx @@ -1,4 +1,4 @@ -import { CSSProperties, ReactNode, useEffect, useState } from 'react'; +import { CSSProperties, ReactNode, useEffect, useState, useMemo } from 'react'; import Draggable, { DraggableEvent, DraggableData } from 'react-draggable'; import { css } from '@emotion/react'; import useResizeObserver from 'use-resize-observer'; @@ -102,6 +102,15 @@ export default function DraggablePanel({ } } + // convert rem to px + const dragHandleHeightValue = 2; + const dragHandleHeight = useMemo(() => { + return ( + dragHandleHeightValue * + parseFloat(getComputedStyle(document.documentElement).fontSize) + ); + }, []); + const { ref, height, width } = useResizeObserver(); useEffect( @@ -109,11 +118,15 @@ export default function DraggablePanel({ if (!onPanelResize || !height || !width) return; onPanelResize({ - height: height, + // Note: since height from useResizeObserver includes dragHandle's height, 2rem, + // dragHandle's height should be substracted from height to compute main panel size + // without this, the use of useResizeObserver's height may lead to infinite loop + // when changing plot size inside the pannel + height: height - dragHandleHeight, width: width, }); }, - [height, width, onPanelResize] + [height, width] ); const finalPosition = confineToParentContainer @@ -162,7 +175,9 @@ export default function DraggablePanel({ background: ${theme?.palette?.primary?.hue[100] ?? gray[100]}; cursor: ${isDragging ? 'grabbing' : 'grab'}; display: flex; - height: 2rem; + height: ${dragHandleHeightValue != null + ? dragHandleHeightValue + 'rem' + : '2rem'}; justify-content: center; // Because the panels are positioned absolutely and overflow auto, // the handle will get lost when the user scrolls down. We can pin the