Skip to content

Commit

Permalink
feat: rename dropdown to popup (#1103)
Browse files Browse the repository at this point in the history
* feat: rename dropdown to popup

* chore: adjust some logic

* test: add test case

* chore: trigger CI build

* refactor: remove compatible code
  • Loading branch information
aojunhao123 authored Jan 13, 2025
1 parent 4779fb8 commit 4d77993
Show file tree
Hide file tree
Showing 13 changed files with 92 additions and 84 deletions.
10 changes: 5 additions & 5 deletions docs/examples/auto-adjust-dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ class Test extends React.Component {
>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<div>
<Select onChange={this.onChange} dropdownMatchSelectWidth={500} value={value}>
<Select onChange={this.onChange} popupMatchSelectWidth={500} value={value}>
<Option value="1">Jack Jack Jack Jack Jack Jack Jack Jack Jack Jack Jack</Option>
<Option value="2">Lucy Lucy Lucy Lucy Lucy Lucy Lucy Lucy Lucy Lucy</Option>
<Option value="3">Jill</Option>
</Select>
</div>
<div>
<Select onChange={this.onChange} dropdownMatchSelectWidth={500} value={value}>
<Select onChange={this.onChange} popupMatchSelectWidth={500} value={value}>
<Option value="1">Jack Jack Jack Jack Jack Jack Jack Jack Jack Jack Jack</Option>
<Option value="2">Lucy Lucy Lucy Lucy Lucy Lucy Lucy Lucy Lucy Lucy</Option>{' '}
<Option value="3">Jill</Option>
Expand All @@ -50,7 +50,7 @@ class Test extends React.Component {
</div>
<div style={{ display: 'flex', justifyContent: 'center' }}>
<div>
<Select onChange={this.onChange} dropdownMatchSelectWidth={500} value={value}>
<Select onChange={this.onChange} popupMatchSelectWidth={500} value={value}>
<Option value="1">Jack Jack Jack Jack Jack Jack Jack Jack Jack Jack Jack</Option>
<Option value="2">Lucy Lucy Lucy Lucy Lucy Lucy Lucy Lucy Lucy Lucy</Option>
<Option value="3">Jill</Option>
Expand All @@ -64,14 +64,14 @@ class Test extends React.Component {
}}
>
<div>
<Select onChange={this.onChange} dropdownMatchSelectWidth={500} value={value}>
<Select onChange={this.onChange} popupMatchSelectWidth={500} value={value}>
<Option value="1">Jack Jack Jack Jack Jack Jack Jack Jack Jack Jack Jack</Option>
<Option value="2">Lucy Lucy Lucy Lucy Lucy Lucy Lucy Lucy Lucy Lucy</Option>
<Option value="3">Jill</Option>
</Select>
</div>
<div>
<Select onChange={this.onChange} dropdownMatchSelectWidth={500} value={value}>
<Select onChange={this.onChange} popupMatchSelectWidth={500} value={value}>
<Option value="1">Jack Jack Jack Jack Jack Jack Jack Jack Jack Jack Jack</Option>
<Option value="2">Lucy Lucy Lucy Lucy Lucy Lucy Lucy Lucy Lucy Lucy</Option>
<Option value="3">Jill</Option>
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/controlled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class Controlled extends React.Component<{}, ControlledState> {
console.log('onFocus');
};

onDropdownVisibleChange = (open) => {
onPopupVisibleChange = (open) => {
this.setState({ open });
};

Expand All @@ -68,7 +68,7 @@ class Controlled extends React.Component<{}, ControlledState> {
optionLabelProp="children"
optionFilterProp="text"
onChange={this.onChange}
onDropdownVisibleChange={this.onDropdownVisibleChange}
onPopupVisibleChange={this.onPopupVisibleChange}
>
<Option value="01" text="jack" title="jack">
<b
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/dropdownRender.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class Test extends React.Component {
tokenSeparators={[' ', ',']}
onFocus={() => console.log('focus')}
onBlur={() => console.log('blur')}
dropdownRender={(menu) => (
popupRender={(menu) => (
<React.Fragment>
<div
onClick={() => {
Expand Down
6 changes: 3 additions & 3 deletions docs/examples/getPopupContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ class Test extends React.Component {
>
<h3 style={{ width: '100%' }}>Transform: 150%</h3>
<MySelect />
<MySelect dropdownMatchSelectWidth />
<MySelect dropdownMatchSelectWidth={false} />
<MySelect dropdownMatchSelectWidth={300} />
<MySelect popupMatchSelectWidth />
<MySelect popupMatchSelectWidth={false} />
<MySelect popupMatchSelectWidth={300} />
</div>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/single-animation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const Test = () => (
animation="slide-up"
showSearch
onChange={onChange}
dropdownStyle={{
popupStyle={{
width: 'auto',
}}
>
Expand Down
4 changes: 2 additions & 2 deletions docs/examples/single.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ class Test extends React.Component {
id="my-select-rtl"
placeholder="rtl"
direction="rtl"
dropdownMatchSelectWidth={300}
dropdownStyle={{ minWidth: 300 }}
popupMatchSelectWidth={300}
popupStyle={{ minWidth: 300 }}
style={{ width: 500 }}
>
<Option value="1">1</Option>
Expand Down
42 changes: 22 additions & 20 deletions src/BaseSelect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ export interface BaseSelectProps extends BaseSelectPrivateProps, React.AriaAttri
// >>> Open
open?: boolean;
defaultOpen?: boolean;
onDropdownVisibleChange?: (open: boolean) => void;
onPopupVisibleChange?: (open: boolean) => void;

// >>> Customize Input
/** @private Internal usage. Do not use in your production. */
Expand Down Expand Up @@ -184,14 +184,16 @@ export interface BaseSelectProps extends BaseSelectPrivateProps, React.AriaAttri
/** Selector remove icon */
removeIcon?: RenderNode;

// >>> Dropdown
// >>> Dropdown/Popup
animation?: string;
transitionName?: string;
dropdownStyle?: React.CSSProperties;
dropdownClassName?: string;
dropdownMatchSelectWidth?: boolean | number;
dropdownRender?: (menu: React.ReactElement) => React.ReactElement;
dropdownAlign?: AlignType;

popupStyle?: React.CSSProperties;
popupClassName?: string;
popupMatchSelectWidth?: boolean | number;
popupRender?: (menu: React.ReactElement) => React.ReactElement;
popupAlign?: AlignType;

placement?: Placement;
builtinPlacements?: BuildInPlacements;
getPopupContainer?: RenderDOMFunc;
Expand Down Expand Up @@ -245,7 +247,7 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
// Open
open,
defaultOpen,
onDropdownVisibleChange,
onPopupVisibleChange,

// Active
activeValue,
Expand All @@ -269,11 +271,11 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
OptionList,
animation,
transitionName,
dropdownStyle,
dropdownClassName,
dropdownMatchSelectWidth,
dropdownRender,
dropdownAlign,
popupStyle,
popupClassName,
popupMatchSelectWidth,
popupRender,
popupAlign,
placement,
builtinPlacements,
getPopupContainer,
Expand Down Expand Up @@ -389,11 +391,11 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
setInnerOpen(nextOpen);

if (mergedOpen !== nextOpen) {
onDropdownVisibleChange?.(nextOpen);
onPopupVisibleChange?.(nextOpen);
}
}
},
[disabled, mergedOpen, setInnerOpen, onDropdownVisibleChange],
[disabled, mergedOpen, setInnerOpen, onPopupVisibleChange],
);

// ============================= Search =============================
Expand Down Expand Up @@ -767,12 +769,12 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
popupElement={optionList}
animation={animation}
transitionName={transitionName}
dropdownStyle={dropdownStyle}
dropdownClassName={dropdownClassName}
popupStyle={popupStyle}
popupClassName={popupClassName}
direction={direction}
dropdownMatchSelectWidth={dropdownMatchSelectWidth}
dropdownRender={dropdownRender}
dropdownAlign={dropdownAlign}
popupMatchSelectWidth={popupMatchSelectWidth}
popupRender={popupRender}
popupAlign={popupAlign}
placement={placement}
builtinPlacements={builtinPlacements}
getPopupContainer={getPopupContainer}
Expand Down
8 changes: 4 additions & 4 deletions src/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ const Select = React.forwardRef<BaseSelectRef, SelectProps<any, DefaultOptionTyp
// Select
onSelect,
onDeselect,
dropdownMatchSelectWidth = true,
popupMatchSelectWidth = true,

// Options
filterOption,
Expand Down Expand Up @@ -609,7 +609,7 @@ const Select = React.forwardRef<BaseSelectRef, SelectProps<any, DefaultOptionTyp

// ========================== Context ===========================
const selectContext = React.useMemo<SelectContextProps>(() => {
const realVirtual = virtual !== false && dropdownMatchSelectWidth !== false;
const realVirtual = virtual !== false && popupMatchSelectWidth !== false;
return {
...parsedOptions,
flattenOptions: displayOptions,
Expand Down Expand Up @@ -638,7 +638,7 @@ const Select = React.forwardRef<BaseSelectRef, SelectProps<any, DefaultOptionTyp
rawValues,
mergedFieldNames,
virtual,
dropdownMatchSelectWidth,
popupMatchSelectWidth,
direction,
listHeight,
listItemHeight,
Expand Down Expand Up @@ -675,7 +675,7 @@ const Select = React.forwardRef<BaseSelectRef, SelectProps<any, DefaultOptionTyp
onSearch={onInternalSearch}
autoClearSearchValue={autoClearSearchValue}
onSearchSplit={onInternalSearchSplit}
dropdownMatchSelectWidth={dropdownMatchSelectWidth}
popupMatchSelectWidth={popupMatchSelectWidth}
// >>> OptionList
OptionList={OptionList}
emptyOptions={!displayOptions.length}
Expand Down
64 changes: 35 additions & 29 deletions src/SelectTrigger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import * as React from 'react';
import type { Placement, RenderDOMFunc } from './BaseSelect';

const getBuiltInPlacements = (
dropdownMatchSelectWidth: number | boolean,
popupMatchSelectWidth: number | boolean,
): Record<string, AlignType> => {
// Enable horizontal overflow auto-adjustment when a custom dropdown width is provided
const adjustX = dropdownMatchSelectWidth === true ? 0 : 1;
const adjustX = popupMatchSelectWidth === true ? 0 : 1;
return {
bottomLeft: {
points: ['tl', 'bl'],
Expand Down Expand Up @@ -64,13 +64,13 @@ export interface SelectTriggerProps {
transitionName?: string;
placement?: Placement;
builtinPlacements?: BuildInPlacements;
dropdownStyle: React.CSSProperties;
dropdownClassName: string;
popupStyle: React.CSSProperties;
popupClassName: string;
direction: string;
dropdownMatchSelectWidth?: boolean | number;
dropdownRender?: (menu: React.ReactElement) => React.ReactElement;
popupMatchSelectWidth?: boolean | number;
popupRender?: (menu: React.ReactElement) => React.ReactElement;
getPopupContainer?: RenderDOMFunc;
dropdownAlign: AlignType;
popupAlign: AlignType;
empty: boolean;

getTriggerDOMNode: (node: HTMLElement) => HTMLElement;
Expand All @@ -91,14 +91,14 @@ const SelectTrigger: React.ForwardRefRenderFunction<RefTriggerProps, SelectTrigg
popupElement,
animation,
transitionName,
dropdownStyle,
dropdownClassName,
popupStyle,
popupClassName,
direction = 'ltr',
placement,
builtinPlacements,
dropdownMatchSelectWidth,
dropdownRender,
dropdownAlign,
popupMatchSelectWidth,
popupRender,
popupAlign,
getPopupContainer,
empty,
getTriggerDOMNode,
Expand All @@ -107,38 +107,44 @@ const SelectTrigger: React.ForwardRefRenderFunction<RefTriggerProps, SelectTrigg
...restProps
} = props;

const dropdownPrefixCls = `${prefixCls}-dropdown`;
// We still use `dropdown` className to keep compatibility
// This is used for:
// 1. Styles
// 2. Animation
// 3. Theme customization
// Please do not modify this since it's a breaking change
const popupPrefixCls = `${prefixCls}-dropdown`;

let popupNode = popupElement;
if (dropdownRender) {
popupNode = dropdownRender(popupElement);
if (popupRender) {
popupNode = popupRender(popupElement);
}

const mergedBuiltinPlacements = React.useMemo(
() => builtinPlacements || getBuiltInPlacements(dropdownMatchSelectWidth),
[builtinPlacements, dropdownMatchSelectWidth],
() => builtinPlacements || getBuiltInPlacements(popupMatchSelectWidth),
[builtinPlacements, popupMatchSelectWidth],
);

// ===================== Motion ======================
const mergedTransitionName = animation ? `${dropdownPrefixCls}-${animation}` : transitionName;
const mergedTransitionName = animation ? `${popupPrefixCls}-${animation}` : transitionName;

// =================== Popup Width ===================
const isNumberPopupWidth = typeof dropdownMatchSelectWidth === 'number';
const isNumberPopupWidth = typeof popupMatchSelectWidth === 'number';

const stretch = React.useMemo(() => {
if (isNumberPopupWidth) {
return null;
}

return dropdownMatchSelectWidth === false ? 'minWidth' : 'width';
}, [dropdownMatchSelectWidth, isNumberPopupWidth]);
return popupMatchSelectWidth === false ? 'minWidth' : 'width';
}, [popupMatchSelectWidth, isNumberPopupWidth]);

let popupStyle = dropdownStyle;
let mergedPopupStyle = popupStyle;

if (isNumberPopupWidth) {
popupStyle = {
mergedPopupStyle = {
...popupStyle,
width: dropdownMatchSelectWidth,
width: popupMatchSelectWidth,
};
}

Expand All @@ -156,18 +162,18 @@ const SelectTrigger: React.ForwardRefRenderFunction<RefTriggerProps, SelectTrigg
hideAction={onPopupVisibleChange ? ['click'] : []}
popupPlacement={placement || (direction === 'rtl' ? 'bottomRight' : 'bottomLeft')}
builtinPlacements={mergedBuiltinPlacements}
prefixCls={dropdownPrefixCls}
prefixCls={popupPrefixCls}
popupTransitionName={mergedTransitionName}
popup={<div onMouseEnter={onPopupMouseEnter}>{popupNode}</div>}
ref={triggerPopupRef}
stretch={stretch}
popupAlign={dropdownAlign}
popupAlign={popupAlign}
popupVisible={visible}
getPopupContainer={getPopupContainer}
popupClassName={classNames(dropdownClassName, {
[`${dropdownPrefixCls}-empty`]: empty,
popupClassName={classNames(popupClassName, {
[`${popupPrefixCls}-empty`]: empty,
})}
popupStyle={popupStyle}
popupStyle={mergedPopupStyle}
getTriggerDOMNode={getTriggerDOMNode}
onPopupVisibleChange={onPopupVisibleChange}
>
Expand Down
6 changes: 3 additions & 3 deletions tests/Combobox.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -455,16 +455,16 @@ describe('Select.Combobox', () => {
// https://github.com/ant-design/ant-design/issues/16572
it('close when enter press without active option', () => {
jest.useFakeTimers();
const onDropdownVisibleChange = jest.fn();
const onPopupVisibleChange = jest.fn();
const { container } = render(
<Select mode="combobox" open onDropdownVisibleChange={onDropdownVisibleChange}>
<Select mode="combobox" open onPopupVisibleChange={onPopupVisibleChange}>
<Option value="One">One</Option>
<Option value="Two">Two</Option>
</Select>,
);
keyDown(container.querySelector('input')!, KeyCode.ENTER);
jest.runAllTimers();
expect(onDropdownVisibleChange).toHaveBeenCalledWith(false);
expect(onPopupVisibleChange).toHaveBeenCalledWith(false);
jest.useRealTimers();
});

Expand Down
Loading

0 comments on commit 4d77993

Please sign in to comment.