From 9ed5b4efa23b9aa85f973d3956e46b9cba38912e Mon Sep 17 00:00:00 2001 From: Juan Cabanas Date: Wed, 30 Apr 2025 10:04:31 -0300 Subject: [PATCH] Grafana UI: Update `CollapsableSection` to be controlled (#104642) --- .../Collapse/CollapsableSection.tsx | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/grafana-ui/src/components/Collapse/CollapsableSection.tsx b/packages/grafana-ui/src/components/Collapse/CollapsableSection.tsx index ac5852785a3..d36e48528d6 100644 --- a/packages/grafana-ui/src/components/Collapse/CollapsableSection.tsx +++ b/packages/grafana-ui/src/components/Collapse/CollapsableSection.tsx @@ -38,9 +38,12 @@ export const CollapsableSection = ({ contentDataTestId, unmountContentWhenClosed = true, }: Props) => { - const [open, toggleOpen] = useState(isOpen); + const [internalOpenState, toggleInternalOpenState] = useState(isOpen); const styles = useStyles2(collapsableSectionStyles); + const isControlled = isOpen !== undefined && onToggle !== undefined; + const isSectionOpen = isControlled ? isOpen : internalOpenState; + const onClick = (e: React.MouseEvent) => { if (e.target instanceof HTMLElement && e.target.tagName === 'A') { return; @@ -49,8 +52,11 @@ export const CollapsableSection = ({ e.preventDefault(); e.stopPropagation(); - onToggle?.(!open); - toggleOpen(!open); + onToggle?.(!isOpen); + + if (!isControlled) { + toggleInternalOpenState(!internalOpenState); + } }; const { current: id } = useRef(uniqueId()); @@ -60,7 +66,7 @@ export const CollapsableSection = ({
@@ -79,21 +85,21 @@ export const CollapsableSection = ({ id={`collapse-button-${id}`} className={styles.button} onClick={onClick} - aria-expanded={open && !loading} + aria-expanded={isSectionOpen && !loading} aria-controls={`collapse-content-${id}`} aria-labelledby={buttonLabelId} > {loading ? ( ) : ( - + )}
{label}
- {unmountContentWhenClosed ? open && content : content} + {unmountContentWhenClosed ? isSectionOpen && content : content} ); };