Skip to content

Commit a5d3cd6

Browse files
authored
fix: customize builtinPlacement should override builtin one (#933)
* chore: merge * test: test case
1 parent 7c71d9a commit a5d3cd6

File tree

3 files changed

+38
-8
lines changed

3 files changed

+38
-8
lines changed

src/BaseSelect.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { AlignType } from '@rc-component/trigger/lib/interface';
1+
import type { AlignType, BuildInPlacements } from '@rc-component/trigger/lib/interface';
22
import classNames from 'classnames';
33
import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
44
import useMergedState from 'rc-util/lib/hooks/useMergedState';
@@ -185,6 +185,7 @@ export interface BaseSelectProps extends BaseSelectPrivateProps, React.AriaAttri
185185
dropdownRender?: (menu: React.ReactElement) => React.ReactElement;
186186
dropdownAlign?: AlignType;
187187
placement?: Placement;
188+
builtinPlacements?: BuildInPlacements;
188189
getPopupContainer?: RenderDOMFunc;
189190

190191
// >>> Focus
@@ -268,6 +269,7 @@ const BaseSelect = React.forwardRef((props: BaseSelectProps, ref: React.Ref<Base
268269
dropdownRender,
269270
dropdownAlign,
270271
placement,
272+
builtinPlacements,
271273
getPopupContainer,
272274

273275
// Focus
@@ -762,6 +764,7 @@ const BaseSelect = React.forwardRef((props: BaseSelectProps, ref: React.Ref<Base
762764
dropdownRender={dropdownRender}
763765
dropdownAlign={dropdownAlign}
764766
placement={placement}
767+
builtinPlacements={builtinPlacements}
765768
getPopupContainer={getPopupContainer}
766769
empty={emptyOptions}
767770
getTriggerDOMNode={() => selectorDomRef.current}

src/SelectTrigger.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import Trigger from '@rc-component/trigger';
2-
import type { AlignType } from '@rc-component/trigger/lib/interface';
2+
import type { AlignType, BuildInPlacements } from '@rc-component/trigger/lib/interface';
33
import classNames from 'classnames';
44
import * as React from 'react';
55
import type { Placement, RenderDOMFunc } from './BaseSelect';
@@ -64,6 +64,7 @@ export interface SelectTriggerProps {
6464
transitionName?: string;
6565
containerWidth: number;
6666
placement?: Placement;
67+
builtinPlacements?: BuildInPlacements;
6768
dropdownStyle: React.CSSProperties;
6869
dropdownClassName: string;
6970
direction: string;
@@ -96,6 +97,7 @@ const SelectTrigger: React.RefForwardingComponent<RefTriggerProps, SelectTrigger
9697
dropdownClassName,
9798
direction = 'ltr',
9899
placement,
100+
builtinPlacements,
99101
dropdownMatchSelectWidth,
100102
dropdownRender,
101103
dropdownAlign,
@@ -114,9 +116,9 @@ const SelectTrigger: React.RefForwardingComponent<RefTriggerProps, SelectTrigger
114116
popupNode = dropdownRender(popupElement);
115117
}
116118

117-
const builtInPlacements = React.useMemo(
118-
() => getBuiltInPlacements(dropdownMatchSelectWidth),
119-
[dropdownMatchSelectWidth],
119+
const mergedBuiltinPlacements = React.useMemo(
120+
() => builtinPlacements || getBuiltInPlacements(dropdownMatchSelectWidth),
121+
[builtinPlacements, dropdownMatchSelectWidth],
120122
);
121123

122124
// ===================== Motion ======================
@@ -146,7 +148,7 @@ const SelectTrigger: React.RefForwardingComponent<RefTriggerProps, SelectTrigger
146148
showAction={onPopupVisibleChange ? ['click'] : []}
147149
hideAction={onPopupVisibleChange ? ['click'] : []}
148150
popupPlacement={placement || (direction === 'rtl' ? 'bottomRight' : 'bottomLeft')}
149-
builtinPlacements={builtInPlacements}
151+
builtinPlacements={mergedBuiltinPlacements}
150152
prefixCls={dropdownPrefixCls}
151153
popupTransitionName={mergedTransitionName}
152154
popup={

tests/BaseSelect.test.tsx

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import type { OptionListProps, RefOptionListProps } from '@/OptionList';
12
import { fireEvent, render } from '@testing-library/react';
2-
import BaseSelect from '../src/BaseSelect';
33
import { forwardRef } from 'react';
4-
import type { OptionListProps, RefOptionListProps } from '@/OptionList';
4+
import BaseSelect from '../src/BaseSelect';
55

66
const OptionList = forwardRef<RefOptionListProps, OptionListProps>(() => (
77
<div className="popup">Popup</div>
@@ -58,4 +58,29 @@ describe('BaseSelect', () => {
5858
).toBe('absolute');
5959
jest.useRealTimers();
6060
});
61+
62+
it('customize builtinPlacements should override default one', () => {
63+
const { container } = render(
64+
<BaseSelect
65+
prefixCls="rc-select"
66+
id="test"
67+
displayValues={[]}
68+
onDisplayValuesChange={() => {}}
69+
searchValue=""
70+
onSearch={() => {}}
71+
OptionList={OptionList}
72+
emptyOptions
73+
open
74+
// Test content
75+
builtinPlacements={{
76+
// placement not exist in `builtinPlacements`,
77+
// which means this will be same as empty one.
78+
// It's safe to test in other way if refactor
79+
fallback: {},
80+
}}
81+
/>,
82+
);
83+
84+
expect(container.querySelector('.rc-select-dropdown-placement-fallback')).toBeTruthy();
85+
});
6186
});

0 commit comments

Comments
 (0)