mirror of
https://github.com/apache/superset.git
synced 2026-04-18 15:44:57 +00:00
fix(popup): Dropdown popup width doesn't match input width when tags collapse in oneLine mode (#39136)
This commit is contained in:
@@ -814,6 +814,62 @@ test('Maintains stable maxTagCount to prevent click target disappearing in oneLi
|
||||
expect(withinSelector.getByText('+ 2 ...')).toBeVisible();
|
||||
});
|
||||
|
||||
test('dropdown width matches input width after tags collapse in oneLine mode', async () => {
|
||||
render(
|
||||
<div style={{ width: '300px' }}>
|
||||
<Select
|
||||
{...defaultProps}
|
||||
value={[OPTIONS[0], OPTIONS[1], OPTIONS[2]]}
|
||||
mode="multiple"
|
||||
oneLine
|
||||
/>
|
||||
</div>,
|
||||
);
|
||||
|
||||
await open();
|
||||
|
||||
// Wait for RAF to complete and tags to collapse
|
||||
await waitFor(() => {
|
||||
const withinSelector = within(
|
||||
getElementByClassName('.ant-select-selector'),
|
||||
);
|
||||
expect(
|
||||
withinSelector.queryByText(OPTIONS[0].label),
|
||||
).not.toBeInTheDocument();
|
||||
expect(withinSelector.getByText('+ 3 ...')).toBeVisible();
|
||||
});
|
||||
|
||||
const selectElement = document.querySelector('.ant-select') as HTMLElement;
|
||||
expect(selectElement).toBeInTheDocument();
|
||||
|
||||
// Mock the select element's width since JSDOM doesn't perform real layout
|
||||
jest.spyOn(selectElement, 'getBoundingClientRect').mockReturnValue({
|
||||
width: 300,
|
||||
height: 32,
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 300,
|
||||
bottom: 32,
|
||||
x: 0,
|
||||
y: 0,
|
||||
toJSON: () => ({}),
|
||||
} as DOMRect);
|
||||
|
||||
// Close and reopen to trigger width measurement with mocked value
|
||||
await type('{esc}');
|
||||
await open();
|
||||
|
||||
const dropdown = document.querySelector(
|
||||
'.ant-select-dropdown',
|
||||
) as HTMLElement;
|
||||
expect(dropdown).toBeInTheDocument();
|
||||
|
||||
// Verify the dropdown has inline width matching the mocked select width
|
||||
await waitFor(() => {
|
||||
expect(parseInt(dropdown.style.width, 10)).toBe(300);
|
||||
});
|
||||
});
|
||||
|
||||
test('does not render "Select all" when there are 0 or 1 options', async () => {
|
||||
const { rerender } = render(
|
||||
<Select {...defaultProps} options={[]} mode="multiple" allowNewOptions />,
|
||||
|
||||
@@ -149,6 +149,8 @@ const Select = forwardRef(
|
||||
// Prevent maxTagCount change during click events to avoid click target disappearing
|
||||
const [stableMaxTagCount, setStableMaxTagCount] = useState(maxTagCount);
|
||||
const isOpeningRef = useRef(false);
|
||||
const selectContainerRef = useRef<HTMLDivElement>(null);
|
||||
const [dropdownWidth, setDropdownWidth] = useState<number | true>(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (oneLine) {
|
||||
@@ -159,12 +161,23 @@ const Select = forwardRef(
|
||||
requestAnimationFrame(() => {
|
||||
setStableMaxTagCount(0);
|
||||
isOpeningRef.current = false;
|
||||
|
||||
// Measure collapsed width and update dropdown width
|
||||
const selectElement =
|
||||
selectContainerRef.current?.querySelector('.ant-select');
|
||||
if (selectElement) {
|
||||
const { width } = selectElement.getBoundingClientRect();
|
||||
if (width > 0) {
|
||||
setDropdownWidth(width);
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!isDropdownVisible) {
|
||||
// When closing, immediately show the first tag
|
||||
setStableMaxTagCount(1);
|
||||
setDropdownWidth(true); // Reset to default when closing
|
||||
isOpeningRef.current = false;
|
||||
}
|
||||
return;
|
||||
@@ -717,7 +730,11 @@ const Select = forwardRef(
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledContainer className={className} headerPosition={headerPosition}>
|
||||
<StyledContainer
|
||||
ref={selectContainerRef}
|
||||
className={className}
|
||||
headerPosition={headerPosition}
|
||||
>
|
||||
{header && (
|
||||
<StyledHeader headerPosition={headerPosition}>{header}</StyledHeader>
|
||||
)}
|
||||
@@ -777,7 +794,7 @@ const Select = forwardRef(
|
||||
options={visibleOptions}
|
||||
optionRender={option => <Space>{option.label || option.value}</Space>}
|
||||
oneLine={oneLine}
|
||||
popupMatchSelectWidth
|
||||
popupMatchSelectWidth={oneLine ? dropdownWidth : true}
|
||||
css={props.css}
|
||||
dropdownAlign={DROPDOWN_ALIGN_BOTTOM}
|
||||
{...props}
|
||||
|
||||
Reference in New Issue
Block a user