From 1b8f98f7a61c74a27d1ff469d19ddcbbce43e7d7 Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" Date: Mon, 28 Nov 2022 18:10:43 -0500 Subject: [PATCH 1/2] feat: Adds overflow to the DropdownContainer popover --- .github/CODEOWNERS | 1 + .../components/DropdownContainer/index.tsx | 67 +++++++++++++------ 2 files changed, 48 insertions(+), 20 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9ca3516f8fb9b..931ede6b484db 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -14,6 +14,7 @@ /superset-frontend/src/components/Select/ @michael-s-molina @geido @ktmud /superset-frontend/src/components/MetadataBar/ @michael-s-molina +/superset-frontend/src/components/DropdownContainer/ @michael-s-molina # Notify Helm Chart maintainers about changes in it diff --git a/superset-frontend/src/components/DropdownContainer/index.tsx b/superset-frontend/src/components/DropdownContainer/index.tsx index d364d3542ee73..73e57e7ab3469 100644 --- a/superset-frontend/src/components/DropdownContainer/index.tsx +++ b/superset-frontend/src/components/DropdownContainer/index.tsx @@ -26,6 +26,7 @@ import React, { useLayoutEffect, useMemo, useState, + useRef, } from 'react'; import { css, t, useTheme } from '@superset-ui/core'; import { useResizeDetector } from 'react-resize-detector'; @@ -35,6 +36,8 @@ import Icons from '../Icons'; import Button from '../Button'; import Popover from '../Popover'; +const MAX_HEIGHT = 500; + /** * Container item. */ @@ -104,12 +107,12 @@ const DropdownContainer = forwardRef( { items, onOverflowingStateChange, - dropdownContent: getPopoverContent, - dropdownRef: popoverRef, - dropdownStyle: popoverStyle = {}, - dropdownTriggerCount: popoverTriggerCount, - dropdownTriggerIcon: popoverTriggerIcon, - dropdownTriggerText: popoverTriggerText = t('More'), + dropdownContent, + dropdownRef, + dropdownStyle = {}, + dropdownTriggerCount, + dropdownTriggerIcon, + dropdownTriggerText = t('More'), style, }: DropdownContainerProps, outerRef: RefObject, @@ -124,6 +127,13 @@ const DropdownContainer = forwardRef( // We use React.useState to be able to mock the state in Jest const [overflowingIndex, setOverflowingIndex] = React.useState(-1); + let targetRef = useRef(null); + if (dropdownRef) { + targetRef = dropdownRef; + } + + const [showOverflow, setShowOverflow] = useState(false); + useLayoutEffect(() => { const container = current?.children.item(0); if (container) { @@ -214,7 +224,7 @@ const DropdownContainer = forwardRef( const popoverContent = useMemo( () => - getPopoverContent || overflowingCount ? ( + dropdownContent || overflowingCount ? (
- {getPopoverContent - ? getPopoverContent(overflowedItems) + {dropdownContent + ? dropdownContent(overflowedItems) : overflowedItems.map(item => item.element)}
) : null, [ - getPopoverContent, - overflowedItems, + dropdownContent, overflowingCount, - popoverRef, - popoverStyle, theme.gridUnit, + dropdownStyle, + targetRef, + overflowedItems, ], ); + useLayoutEffect(() => { + if (popoverVisible) { + // Measures scroll height after rendering the elements + setTimeout(() => { + if (targetRef.current) { + // We only set overflow when there's enough space to display + // Select's popovers because they are restrained by the overflow property. + setShowOverflow(targetRef.current.scrollHeight > MAX_HEIGHT); + } + }, 100); + } + }, [popoverVisible]); + useImperativeHandle( outerRef, () => ({ @@ -277,15 +300,19 @@ const DropdownContainer = forwardRef( visible={popoverVisible} onVisibleChange={visible => setPopoverVisible(visible)} placement="bottom" + overlayInnerStyle={{ + maxHeight: MAX_HEIGHT, + overflow: showOverflow ? 'auto' : 'visible', + }} > - + } + `} + /> + setPopoverVisible(visible)} + placement="bottom" + > + + + )} );