mirror of
https://github.com/apache/superset.git
synced 2026-05-05 16:04:19 +00:00
Compare commits
4 Commits
fix/check-
...
fix/dropdo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf6e779200 | ||
|
|
ce6501c36c | ||
|
|
6ea6b01f4f | ||
|
|
c1376c05a9 |
@@ -51,8 +51,16 @@ test('renders children with custom horizontal spacing', () => {
|
|||||||
expect(screen.getByTestId('container')).toHaveStyle('gap: 20px');
|
expect(screen.getByTestId('container')).toHaveStyle('gap: 20px');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('does not render a dropdown button when not overflowing', () => {
|
test('renders dropdown button when items exist even when not overflowing', () => {
|
||||||
render(<DropdownContainer items={generateItems(3)} />);
|
render(<DropdownContainer items={generateItems(3)} />);
|
||||||
|
// Button should always be visible when items exist to prevent layout shifts
|
||||||
|
expect(screen.getByText('More')).toBeInTheDocument();
|
||||||
|
// Badge should show 0 when nothing is overflowing
|
||||||
|
expect(screen.getByText('0')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('does not render a dropdown button when no items', () => {
|
||||||
|
render(<DropdownContainer items={[]} />);
|
||||||
expect(screen.queryByText('More')).not.toBeInTheDocument();
|
expect(screen.queryByText('More')).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ import { t } from '@apache-superset/core/translation';
|
|||||||
import { usePrevious } from '@superset-ui/core';
|
import { usePrevious } from '@superset-ui/core';
|
||||||
import { css, useTheme } from '@apache-superset/core/theme';
|
import { css, useTheme } from '@apache-superset/core/theme';
|
||||||
import { useResizeDetector } from 'react-resize-detector';
|
import { useResizeDetector } from 'react-resize-detector';
|
||||||
import { Badge, Icons, Button, Tooltip, Popover } from '..';
|
import { Badge, Icons, Button, Popover } from '..';
|
||||||
import { DropdownContainerProps, DropdownItem, DropdownRef } from './types';
|
import { DropdownContainerProps, DropdownItem, DropdownRef } from './types';
|
||||||
|
|
||||||
const MAX_HEIGHT = 500;
|
const MAX_HEIGHT = 500;
|
||||||
@@ -234,6 +234,10 @@ export const DropdownContainer = forwardRef(
|
|||||||
const overflowingCount =
|
const overflowingCount =
|
||||||
overflowingIndex !== -1 ? items.length - overflowingIndex : 0;
|
overflowingIndex !== -1 ? items.length - overflowingIndex : 0;
|
||||||
|
|
||||||
|
// Always show button when items exist to prevent layout shifts
|
||||||
|
// and ensure consistent UI even when no items are overflowing
|
||||||
|
const shouldShowButton = items.length > 0 || !!dropdownContent;
|
||||||
|
|
||||||
const popoverContent = useMemo(
|
const popoverContent = useMemo(
|
||||||
() =>
|
() =>
|
||||||
dropdownContent || overflowingCount ? (
|
dropdownContent || overflowingCount ? (
|
||||||
@@ -293,6 +297,44 @@ export const DropdownContainer = forwardRef(
|
|||||||
};
|
};
|
||||||
}, [popoverVisible]);
|
}, [popoverVisible]);
|
||||||
|
|
||||||
|
const triggerButton = (
|
||||||
|
<Button
|
||||||
|
buttonStyle="secondary"
|
||||||
|
data-test="dropdown-container-btn"
|
||||||
|
icon={dropdownTriggerIcon}
|
||||||
|
disabled={!popoverContent}
|
||||||
|
tooltip={dropdownTriggerTooltip}
|
||||||
|
css={css`
|
||||||
|
padding-left: ${theme.paddingXS}px;
|
||||||
|
padding-right: ${theme.paddingXXS}px;
|
||||||
|
gap: ${theme.sizeXXS}px;
|
||||||
|
`}
|
||||||
|
>
|
||||||
|
{dropdownTriggerText}
|
||||||
|
<Badge
|
||||||
|
count={dropdownTriggerCount ?? overflowingCount}
|
||||||
|
color={
|
||||||
|
(dropdownTriggerCount ?? overflowingCount) > 0
|
||||||
|
? theme.colorPrimary
|
||||||
|
: theme.colorTextSecondary
|
||||||
|
}
|
||||||
|
showZero
|
||||||
|
css={css`
|
||||||
|
margin-left: ${theme.sizeUnit * 2}px;
|
||||||
|
`}
|
||||||
|
/>
|
||||||
|
<Icons.DownOutlined
|
||||||
|
iconSize="m"
|
||||||
|
iconColor={theme.colorIcon}
|
||||||
|
css={css`
|
||||||
|
.anticon {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
ref={ref}
|
ref={ref}
|
||||||
@@ -314,7 +356,7 @@ export const DropdownContainer = forwardRef(
|
|||||||
>
|
>
|
||||||
{notOverflowedItems.map(item => item.element)}
|
{notOverflowedItems.map(item => item.element)}
|
||||||
</div>
|
</div>
|
||||||
{popoverContent && (
|
{shouldShowButton && (
|
||||||
<>
|
<>
|
||||||
<Global
|
<Global
|
||||||
styles={css`
|
styles={css`
|
||||||
@@ -339,57 +381,27 @@ export const DropdownContainer = forwardRef(
|
|||||||
`}
|
`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Popover
|
{popoverContent ? (
|
||||||
styles={{
|
<Popover
|
||||||
body: {
|
styles={{
|
||||||
maxHeight: `${MAX_HEIGHT}px`,
|
body: {
|
||||||
overflow: showOverflow ? 'auto' : 'visible',
|
maxHeight: `${MAX_HEIGHT}px`,
|
||||||
},
|
overflow: showOverflow ? 'auto' : 'visible',
|
||||||
}}
|
},
|
||||||
content={popoverContent}
|
}}
|
||||||
trigger="click"
|
content={popoverContent}
|
||||||
open={popoverVisible}
|
trigger="click"
|
||||||
onOpenChange={visible => setPopoverVisible(visible)}
|
open={popoverVisible}
|
||||||
placement="bottom"
|
onOpenChange={visible => setPopoverVisible(visible)}
|
||||||
forceRender={forceRender}
|
placement="bottom"
|
||||||
fresh // This prop prevents caching and stale data for filter scoping.
|
forceRender={forceRender}
|
||||||
>
|
fresh // This prop prevents caching and stale data for filter scoping.
|
||||||
<Tooltip title={dropdownTriggerTooltip}>
|
>
|
||||||
<Button
|
{triggerButton}
|
||||||
buttonStyle="secondary"
|
</Popover>
|
||||||
data-test="dropdown-container-btn"
|
) : (
|
||||||
icon={dropdownTriggerIcon}
|
triggerButton
|
||||||
css={css`
|
)}
|
||||||
padding-left: ${theme.paddingXS}px;
|
|
||||||
padding-right: ${theme.paddingXXS}px;
|
|
||||||
gap: ${theme.sizeXXS}px;
|
|
||||||
`}
|
|
||||||
>
|
|
||||||
{dropdownTriggerText}
|
|
||||||
<Badge
|
|
||||||
count={dropdownTriggerCount ?? overflowingCount}
|
|
||||||
color={
|
|
||||||
(dropdownTriggerCount ?? overflowingCount) > 0
|
|
||||||
? theme.colorPrimary
|
|
||||||
: theme.colorTextSecondary
|
|
||||||
}
|
|
||||||
showZero
|
|
||||||
css={css`
|
|
||||||
margin-left: ${theme.sizeUnit * 2}px;
|
|
||||||
`}
|
|
||||||
/>
|
|
||||||
<Icons.DownOutlined
|
|
||||||
iconSize="m"
|
|
||||||
iconColor={theme.colorIcon}
|
|
||||||
css={css`
|
|
||||||
.anticon {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
/>
|
|
||||||
</Button>
|
|
||||||
</Tooltip>
|
|
||||||
</Popover>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user