diff --git a/superset-frontend/packages/superset-ui-core/src/components/Select/Select.test.tsx b/superset-frontend/packages/superset-ui-core/src/components/Select/Select.test.tsx
index a8c4f844815..2f8cb6860a2 100644
--- a/superset-frontend/packages/superset-ui-core/src/components/Select/Select.test.tsx
+++ b/superset-frontend/packages/superset-ui-core/src/components/Select/Select.test.tsx
@@ -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(
+
+
+
,
+ );
+
+ 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(
,
diff --git a/superset-frontend/packages/superset-ui-core/src/components/Select/Select.tsx b/superset-frontend/packages/superset-ui-core/src/components/Select/Select.tsx
index 2ce52dd66cc..ead92724684 100644
--- a/superset-frontend/packages/superset-ui-core/src/components/Select/Select.tsx
+++ b/superset-frontend/packages/superset-ui-core/src/components/Select/Select.tsx
@@ -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(null);
+ const [dropdownWidth, setDropdownWidth] = useState(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 (
-
+
{header && (
{header}
)}
@@ -777,7 +794,7 @@ const Select = forwardRef(
options={visibleOptions}
optionRender={option => {option.label || option.value}}
oneLine={oneLine}
- popupMatchSelectWidth
+ popupMatchSelectWidth={oneLine ? dropdownWidth : true}
css={props.css}
dropdownAlign={DROPDOWN_ALIGN_BOTTOM}
{...props}