Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@
"rc-virtual-list": "^3.2.0"
},
"devDependencies": {
"@types/enzyme": "^3.10.5",
"@types/jest": "^26.0.0",
"@types/enzyme": "^3.10.9",
"@types/jest": "^26.0.24",
"@types/react": "^17.0.15",
"@types/react-dom": "^17.0.3",
"cross-env": "^7.0.0",
Expand Down
12 changes: 8 additions & 4 deletions src/SelectTrigger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as React from 'react';
import Trigger from 'rc-trigger';
import classNames from 'classnames';
import type { RenderDOMFunc } from './interface';
import type { Placement } from './generate';

const getBuiltInPlacements = (dropdownMatchSelectWidth: number | boolean) => {
// Enable horizontal overflow auto-adjustment when a custom dropdown width is provided
Expand Down Expand Up @@ -57,6 +58,7 @@ export interface SelectTriggerProps {
animation?: string;
transitionName?: string;
containerWidth: number;
placement?: Placement;
dropdownStyle: React.CSSProperties;
dropdownClassName: string;
direction: string;
Expand Down Expand Up @@ -86,6 +88,7 @@ const SelectTrigger: React.RefForwardingComponent<RefTriggerProps, SelectTrigger
dropdownStyle,
dropdownClassName,
direction = 'ltr',
placement,
dropdownMatchSelectWidth = true,
dropdownRender,
dropdownAlign,
Expand All @@ -103,9 +106,10 @@ const SelectTrigger: React.RefForwardingComponent<RefTriggerProps, SelectTrigger
popupNode = dropdownRender(popupElement);
}

const builtInPlacements = React.useMemo(() => getBuiltInPlacements(dropdownMatchSelectWidth), [
dropdownMatchSelectWidth,
]);
const builtInPlacements = React.useMemo(
() => getBuiltInPlacements(dropdownMatchSelectWidth),
[dropdownMatchSelectWidth],
);

// ===================== Motion ======================
const mergedTransitionName = animation ? `${dropdownPrefixCls}-${animation}` : transitionName;
Expand Down Expand Up @@ -133,7 +137,7 @@ const SelectTrigger: React.RefForwardingComponent<RefTriggerProps, SelectTrigger
{...restProps}
showAction={onPopupVisibleChange ? ['click'] : []}
hideAction={onPopupVisibleChange ? ['click'] : []}
popupPlacement={direction === 'rtl' ? 'bottomRight' : 'bottomLeft'}
popupPlacement={placement || (direction === 'rtl' ? 'bottomRight' : 'bottomLeft')}
builtinPlacements={builtInPlacements}
prefixCls={dropdownPrefixCls}
popupTransitionName={mergedTransitionName}
Expand Down
5 changes: 5 additions & 0 deletions src/generate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ export interface RefSelectProps {
scrollTo?: ScrollTo;
}

export type Placement = 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight';

export interface SelectProps<OptionsType extends object[], ValueType> extends React.AriaAttributes {
prefixCls?: string;
id?: string;
Expand Down Expand Up @@ -119,6 +121,7 @@ export interface SelectProps<OptionsType extends object[], ValueType> extends Re
dropdownStyle?: React.CSSProperties;
dropdownClassName?: string;
dropdownMatchSelectWidth?: boolean | number;
placement?: Placement;
virtual?: boolean;
dropdownRender?: (menu: React.ReactElement) => React.ReactElement;
dropdownAlign?: any;
Expand Down Expand Up @@ -301,6 +304,7 @@ export default function generateSelector<
getPopupContainer,

// Dropdown
placement,
listHeight = 200,
listItemHeight = 20,
animation,
Expand Down Expand Up @@ -1075,6 +1079,7 @@ export default function generateSelector<
dropdownMatchSelectWidth={dropdownMatchSelectWidth}
dropdownRender={dropdownRender}
dropdownAlign={dropdownAlign}
placement={placement}
getPopupContainer={getPopupContainer}
empty={!mergedOptions.length}
getTriggerDOMNode={() => selectorDomRef.current}
Expand Down
17 changes: 17 additions & 0 deletions tests/Select.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1680,4 +1680,21 @@ describe('Select.Basic', () => {
wrapper.find('input.rc-select-selection-search-input').getDOMNode().getAttribute('tabindex'),
).toBe('0');
});

describe('placement', () => {
it('default', () => {
const wrapper = mount(<Select open />);
expect(wrapper.find('Trigger').prop('popupPlacement')).toEqual('bottomLeft');
});

it('rtl', () => {
const wrapper = mount(<Select direction="rtl" open />);
expect(wrapper.find('Trigger').prop('popupPlacement')).toEqual('bottomRight');
});

it('customize', () => {
const wrapper = mount(<Select placement="topRight" open />);
expect(wrapper.find('Trigger').prop('popupPlacement')).toEqual('topRight');
});
});
});
2 changes: 1 addition & 1 deletion tests/SelectTrigger.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ describe('Select.Trigger', () => {
</SimpleSelectTrigger>,
);

expect(wrapper.find('Trigger').props().popupTransitionName).toBe('rc-select-dropdown-slide-up');
expect(wrapper.find('Trigger').prop('popupTransitionName')).toBe('rc-select-dropdown-slide-up');
});
});