mirror of
https://github.com/ant-design/ant-design.git
synced 2025-08-06 16:06:28 +08:00
feat: dropdown support arrow pointing at center (#33658)
* feat: add pointAtCenter prop for dropdown * feat: dropdown support arrow pointing at center * chore: code clean * chore: use getPlacements in tooltip * feat: dropdown support 'top' and 'bottom' * chore: update snapshot * chore: move placements to util folder * feat: make 'topCenter' and 'bottomCenter' in Dropdown deprecated * test: update snapshot * test: add test for topCenter and bottomCenter
This commit is contained in:
parent
5fb13e9681
commit
e5451a95cb
@ -42,6 +42,7 @@ export default function getPlacements(config: PlacementsConfig) {
|
|||||||
horizontalArrowShift = 16,
|
horizontalArrowShift = 16,
|
||||||
verticalArrowShift = 8,
|
verticalArrowShift = 8,
|
||||||
autoAdjustOverflow,
|
autoAdjustOverflow,
|
||||||
|
arrowPointAtCenter,
|
||||||
} = config;
|
} = config;
|
||||||
const placementMap: BuildInPlacements = {
|
const placementMap: BuildInPlacements = {
|
||||||
left: {
|
left: {
|
||||||
@ -94,7 +95,7 @@ export default function getPlacements(config: PlacementsConfig) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
Object.keys(placementMap).forEach(key => {
|
Object.keys(placementMap).forEach(key => {
|
||||||
placementMap[key] = config.arrowPointAtCenter
|
placementMap[key] = arrowPointAtCenter
|
||||||
? {
|
? {
|
||||||
...placementMap[key],
|
...placementMap[key],
|
||||||
overflow: getOverflowOptions(autoAdjustOverflow),
|
overflow: getOverflowOptions(autoAdjustOverflow),
|
@ -30,7 +30,7 @@ const BreadcrumbItem: BreadcrumbItemInterface = ({
|
|||||||
const renderBreadcrumbNode = (breadcrumbItem: React.ReactNode) => {
|
const renderBreadcrumbNode = (breadcrumbItem: React.ReactNode) => {
|
||||||
if (overlay) {
|
if (overlay) {
|
||||||
return (
|
return (
|
||||||
<DropDown overlay={overlay} placement="bottomCenter" {...dropdownProps}>
|
<DropDown overlay={overlay} placement="bottom" {...dropdownProps}>
|
||||||
<span className={`${prefixCls}-overlay-link`}>
|
<span className={`${prefixCls}-overlay-link`}>
|
||||||
{breadcrumbItem}
|
{breadcrumbItem}
|
||||||
<DownOutlined />
|
<DownOutlined />
|
||||||
@ -62,9 +62,7 @@ const BreadcrumbItem: BreadcrumbItemInterface = ({
|
|||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
{link}
|
{link}
|
||||||
{separator && (
|
{separator && <span className={`${prefixCls}-separator`}>{separator}</span>}
|
||||||
<span className={`${prefixCls}-separator`}>{separator}</span>
|
|
||||||
)}
|
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,7 @@ Array [
|
|||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
bottomCenter
|
bottom
|
||||||
</span>
|
</span>
|
||||||
</button>,
|
</button>,
|
||||||
<button
|
<button
|
||||||
@ -40,7 +40,61 @@ Array [
|
|||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
topCenter
|
top
|
||||||
|
</span>
|
||||||
|
</button>,
|
||||||
|
<button
|
||||||
|
class="ant-btn ant-dropdown-trigger"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
topRight
|
||||||
|
</span>
|
||||||
|
</button>,
|
||||||
|
]
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`renders ./components/dropdown/demo/arrow-center.md correctly 1`] = `
|
||||||
|
Array [
|
||||||
|
<button
|
||||||
|
class="ant-btn ant-dropdown-trigger"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
bottomLeft
|
||||||
|
</span>
|
||||||
|
</button>,
|
||||||
|
<button
|
||||||
|
class="ant-btn ant-dropdown-trigger"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
bottom
|
||||||
|
</span>
|
||||||
|
</button>,
|
||||||
|
<button
|
||||||
|
class="ant-btn ant-dropdown-trigger"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
bottomRight
|
||||||
|
</span>
|
||||||
|
</button>,
|
||||||
|
<br />,
|
||||||
|
<button
|
||||||
|
class="ant-btn ant-dropdown-trigger"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
topLeft
|
||||||
|
</span>
|
||||||
|
</button>,
|
||||||
|
<button
|
||||||
|
class="ant-btn ant-dropdown-trigger"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
top
|
||||||
</span>
|
</span>
|
||||||
</button>,
|
</button>,
|
||||||
<button
|
<button
|
||||||
@ -658,7 +712,7 @@ exports[`renders ./components/dropdown/demo/placement.md correctly 1`] = `
|
|||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
bottomCenter
|
bottom
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -706,7 +760,7 @@ exports[`renders ./components/dropdown/demo/placement.md correctly 1`] = `
|
|||||||
type="button"
|
type="button"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
topCenter
|
top
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -59,4 +59,24 @@ describe('Dropdown', () => {
|
|||||||
await sleep(500);
|
await sleep(500);
|
||||||
expect(wrapper.find(Dropdown).find('#customExpandIcon').length).toBe(1);
|
expect(wrapper.find(Dropdown).find('#customExpandIcon').length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should warn if use topCenter or bottomCenter', () => {
|
||||||
|
const error = jest.spyOn(console, 'error');
|
||||||
|
mount(
|
||||||
|
<div>
|
||||||
|
<Dropdown overlay="123" placement="bottomCenter">
|
||||||
|
<button type="button">bottomCenter</button>
|
||||||
|
</Dropdown>
|
||||||
|
<Dropdown overlay="123" placement="topCenter">
|
||||||
|
<button type="button">topCenter</button>
|
||||||
|
</Dropdown>
|
||||||
|
</div>,
|
||||||
|
);
|
||||||
|
expect(error).toHaveBeenCalledWith(
|
||||||
|
expect.stringContaining("[antd: Dropdown] You are using 'bottomCenter'"),
|
||||||
|
);
|
||||||
|
expect(error).toHaveBeenCalledWith(
|
||||||
|
expect.stringContaining("[antd: Dropdown] You are using 'topCenter'"),
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
75
components/dropdown/demo/arrow-center.md
Normal file
75
components/dropdown/demo/arrow-center.md
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
---
|
||||||
|
order: 3
|
||||||
|
title:
|
||||||
|
zh-CN: 箭头指向
|
||||||
|
en-US: Arrow pointing at the center
|
||||||
|
---
|
||||||
|
|
||||||
|
## zh-CN
|
||||||
|
|
||||||
|
设置 `arrow` 为 `{ pointAtCenter: true }` 后,箭头将指向目标元素的中心。
|
||||||
|
|
||||||
|
## en-US
|
||||||
|
|
||||||
|
By specifying `arrow` prop with `{ pointAtCenter: true }`, the arrow will point to the center of the target element.
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
import { Menu, Dropdown, Button } from 'antd';
|
||||||
|
|
||||||
|
const menu = (
|
||||||
|
<Menu>
|
||||||
|
<Menu.Item>
|
||||||
|
<a target="_blank" rel="noopener noreferrer" href="https://www.antgroup.com">
|
||||||
|
1st menu item
|
||||||
|
</a>
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item>
|
||||||
|
<a target="_blank" rel="noopener noreferrer" href="https://www.aliyun.com">
|
||||||
|
2nd menu item
|
||||||
|
</a>
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item>
|
||||||
|
<a target="_blank" rel="noopener noreferrer" href="https://www.luohanacademy.com">
|
||||||
|
3rd menu item
|
||||||
|
</a>
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<>
|
||||||
|
<Dropdown overlay={menu} placement="bottomLeft" arrow={{ pointAtCenter: true }}>
|
||||||
|
<Button>bottomLeft</Button>
|
||||||
|
</Dropdown>
|
||||||
|
<Dropdown overlay={menu} placement="bottom" arrow={{ pointAtCenter: true }}>
|
||||||
|
<Button>bottom</Button>
|
||||||
|
</Dropdown>
|
||||||
|
<Dropdown overlay={menu} placement="bottomRight" arrow={{ pointAtCenter: true }}>
|
||||||
|
<Button>bottomRight</Button>
|
||||||
|
</Dropdown>
|
||||||
|
<br />
|
||||||
|
<Dropdown overlay={menu} placement="topLeft" arrow={{ pointAtCenter: true }}>
|
||||||
|
<Button>topLeft</Button>
|
||||||
|
</Dropdown>
|
||||||
|
<Dropdown overlay={menu} placement="top" arrow={{ pointAtCenter: true }}>
|
||||||
|
<Button>top</Button>
|
||||||
|
</Dropdown>
|
||||||
|
<Dropdown overlay={menu} placement="topRight" arrow={{ pointAtCenter: true }}>
|
||||||
|
<Button>topRight</Button>
|
||||||
|
</Dropdown>
|
||||||
|
</>,
|
||||||
|
mountNode,
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
```css
|
||||||
|
#components-dropdown-demo-arrow-center .ant-btn {
|
||||||
|
margin-right: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
.ant-row-rtl #components-dropdown-demo-arrow-center .ant-btn {
|
||||||
|
margin-right: 0;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
```
|
@ -41,8 +41,8 @@ ReactDOM.render(
|
|||||||
<Dropdown overlay={menu} placement="bottomLeft" arrow>
|
<Dropdown overlay={menu} placement="bottomLeft" arrow>
|
||||||
<Button>bottomLeft</Button>
|
<Button>bottomLeft</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
<Dropdown overlay={menu} placement="bottomCenter" arrow>
|
<Dropdown overlay={menu} placement="bottom" arrow>
|
||||||
<Button>bottomCenter</Button>
|
<Button>bottom</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
<Dropdown overlay={menu} placement="bottomRight" arrow>
|
<Dropdown overlay={menu} placement="bottomRight" arrow>
|
||||||
<Button>bottomRight</Button>
|
<Button>bottomRight</Button>
|
||||||
@ -51,8 +51,8 @@ ReactDOM.render(
|
|||||||
<Dropdown overlay={menu} placement="topLeft" arrow>
|
<Dropdown overlay={menu} placement="topLeft" arrow>
|
||||||
<Button>topLeft</Button>
|
<Button>topLeft</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
<Dropdown overlay={menu} placement="topCenter" arrow>
|
<Dropdown overlay={menu} placement="top" arrow>
|
||||||
<Button>topCenter</Button>
|
<Button>top</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
<Dropdown overlay={menu} placement="topRight" arrow>
|
<Dropdown overlay={menu} placement="topRight" arrow>
|
||||||
<Button>topRight</Button>
|
<Button>topRight</Button>
|
||||||
|
@ -46,7 +46,7 @@ ReactDOM.render(
|
|||||||
<Dropdown.Button onClick={handleButtonClick} overlay={menu}>
|
<Dropdown.Button onClick={handleButtonClick} overlay={menu}>
|
||||||
Dropdown
|
Dropdown
|
||||||
</Dropdown.Button>
|
</Dropdown.Button>
|
||||||
<Dropdown.Button overlay={menu} placement="bottomCenter" icon={<UserOutlined />}>
|
<Dropdown.Button overlay={menu} placement="bottom" icon={<UserOutlined />}>
|
||||||
Dropdown
|
Dropdown
|
||||||
</Dropdown.Button>
|
</Dropdown.Button>
|
||||||
<Dropdown.Button onClick={handleButtonClick} overlay={menu} disabled>
|
<Dropdown.Button onClick={handleButtonClick} overlay={menu} disabled>
|
||||||
|
@ -42,8 +42,8 @@ ReactDOM.render(
|
|||||||
<Dropdown overlay={menu} placement="bottomLeft">
|
<Dropdown overlay={menu} placement="bottomLeft">
|
||||||
<Button>bottomLeft</Button>
|
<Button>bottomLeft</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
<Dropdown overlay={menu} placement="bottomCenter">
|
<Dropdown overlay={menu} placement="bottom">
|
||||||
<Button>bottomCenter</Button>
|
<Button>bottom</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
<Dropdown overlay={menu} placement="bottomRight">
|
<Dropdown overlay={menu} placement="bottomRight">
|
||||||
<Button>bottomRight</Button>
|
<Button>bottomRight</Button>
|
||||||
@ -53,8 +53,8 @@ ReactDOM.render(
|
|||||||
<Dropdown overlay={menu} placement="topLeft">
|
<Dropdown overlay={menu} placement="topLeft">
|
||||||
<Button>topLeft</Button>
|
<Button>topLeft</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
<Dropdown overlay={menu} placement="topCenter">
|
<Dropdown overlay={menu} placement="top">
|
||||||
<Button>topCenter</Button>
|
<Button>top</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
<Dropdown overlay={menu} placement="topRight">
|
<Dropdown overlay={menu} placement="topRight">
|
||||||
<Button>topRight</Button>
|
<Button>topRight</Button>
|
||||||
|
@ -7,6 +7,7 @@ import { ConfigContext } from '../config-provider';
|
|||||||
import devWarning from '../_util/devWarning';
|
import devWarning from '../_util/devWarning';
|
||||||
import { tuple } from '../_util/type';
|
import { tuple } from '../_util/type';
|
||||||
import { cloneElement } from '../_util/reactNode';
|
import { cloneElement } from '../_util/reactNode';
|
||||||
|
import getPlacements from '../_util/placements';
|
||||||
|
|
||||||
const Placements = tuple(
|
const Placements = tuple(
|
||||||
'topLeft',
|
'topLeft',
|
||||||
@ -15,6 +16,8 @@ const Placements = tuple(
|
|||||||
'bottomLeft',
|
'bottomLeft',
|
||||||
'bottomCenter',
|
'bottomCenter',
|
||||||
'bottomRight',
|
'bottomRight',
|
||||||
|
'top',
|
||||||
|
'bottom',
|
||||||
);
|
);
|
||||||
|
|
||||||
type Placement = typeof Placements[number];
|
type Placement = typeof Placements[number];
|
||||||
@ -34,8 +37,12 @@ type Align = {
|
|||||||
useCssTransform?: boolean;
|
useCssTransform?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type DropdownArrowOptions = {
|
||||||
|
pointAtCenter?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
export interface DropDownProps {
|
export interface DropDownProps {
|
||||||
arrow?: boolean;
|
arrow?: boolean | DropdownArrowOptions;
|
||||||
trigger?: ('click' | 'hover' | 'contextMenu')[];
|
trigger?: ('click' | 'hover' | 'contextMenu')[];
|
||||||
overlay: React.ReactElement | OverlayFunc;
|
overlay: React.ReactElement | OverlayFunc;
|
||||||
onVisibleChange?: (visible: boolean) => void;
|
onVisibleChange?: (visible: boolean) => void;
|
||||||
@ -129,10 +136,21 @@ const Dropdown: DropdownInterface = props => {
|
|||||||
|
|
||||||
const getPlacement = () => {
|
const getPlacement = () => {
|
||||||
const { placement } = props;
|
const { placement } = props;
|
||||||
if (placement !== undefined) {
|
if (!placement) {
|
||||||
return placement;
|
return direction === 'rtl' ? ('bottomRight' as Placement) : ('bottomLeft' as Placement);
|
||||||
}
|
}
|
||||||
return direction === 'rtl' ? ('bottomRight' as Placement) : ('bottomLeft' as Placement);
|
|
||||||
|
if (placement.includes('Center')) {
|
||||||
|
const newPlacement = placement.slice(0, placement.indexOf('Center'));
|
||||||
|
devWarning(
|
||||||
|
!placement.includes('Center'),
|
||||||
|
'Dropdown',
|
||||||
|
`You are using '${placement}' placement in Dropdown, which is deprecated. Try to use '${newPlacement}' instead.`,
|
||||||
|
);
|
||||||
|
return newPlacement;
|
||||||
|
}
|
||||||
|
|
||||||
|
return placement;
|
||||||
};
|
};
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -169,11 +187,16 @@ const Dropdown: DropdownInterface = props => {
|
|||||||
alignPoint = true;
|
alignPoint = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const builtinPlacements = getPlacements({
|
||||||
|
arrowPointAtCenter: typeof arrow === 'object' && arrow.pointAtCenter,
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RcDropdown
|
<RcDropdown
|
||||||
arrow={arrow}
|
|
||||||
alignPoint={alignPoint}
|
alignPoint={alignPoint}
|
||||||
{...props}
|
{...props}
|
||||||
|
builtinPlacements={builtinPlacements}
|
||||||
|
arrow={!!arrow}
|
||||||
overlayClassName={overlayClassNameCustomized}
|
overlayClassName={overlayClassNameCustomized}
|
||||||
prefixCls={prefixCls}
|
prefixCls={prefixCls}
|
||||||
getPopupContainer={getPopupContainer || getContextPopupContainer}
|
getPopupContainer={getPopupContainer || getContextPopupContainer}
|
||||||
|
@ -17,14 +17,14 @@ When there are more than a few options to choose from, you can wrap them in a `D
|
|||||||
|
|
||||||
| Property | Description | Type | Default | Version |
|
| Property | Description | Type | Default | Version |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| arrow | Whether the dropdown arrow should be visible | boolean | false | |
|
| arrow | Whether the dropdown arrow should be visible | boolean \| { pointAtCenter: boolean } | false | |
|
||||||
| disabled | Whether the dropdown menu is disabled | boolean | - | |
|
| disabled | Whether the dropdown menu is disabled | boolean | - | |
|
||||||
| destroyPopupOnHide | Whether destroy dropdown when hidden | boolean | false | |
|
| destroyPopupOnHide | Whether destroy dropdown when hidden | boolean | false | |
|
||||||
| getPopupContainer | To set the container of the dropdown menu. The default is to create a div element in body, but you can reset it to the scrolling area and make a relative reposition. [Example on CodePen](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | (triggerNode: HTMLElement) => HTMLElement | () => document.body | |
|
| getPopupContainer | To set the container of the dropdown menu. The default is to create a div element in body, but you can reset it to the scrolling area and make a relative reposition. [Example on CodePen](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | (triggerNode: HTMLElement) => HTMLElement | () => document.body | |
|
||||||
| overlay | The dropdown menu | [Menu](/components/menu) \| () => Menu | - | |
|
| overlay | The dropdown menu | [Menu](/components/menu) \| () => Menu | - | |
|
||||||
| overlayClassName | The class name of the dropdown root element | string | - | |
|
| overlayClassName | The class name of the dropdown root element | string | - | |
|
||||||
| overlayStyle | The style of the dropdown root element | CSSProperties | - | |
|
| overlayStyle | The style of the dropdown root element | CSSProperties | - | |
|
||||||
| placement | Placement of popup menu: `bottomLeft`, `bottomCenter`, `bottomRight`, `topLeft`, `topCenter` or `topRight` | string | `bottomLeft` | |
|
| placement | Placement of popup menu: `bottom` `bottomLeft` `bottomRight` `top` `topLeft` `topRight` | string | `bottomLeft` | |
|
||||||
| trigger | The trigger mode which executes the dropdown action. Note that hover can't be used on touchscreens | Array<`click`\|`hover`\|`contextMenu`> | \[`hover`] | |
|
| trigger | The trigger mode which executes the dropdown action. Note that hover can't be used on touchscreens | Array<`click`\|`hover`\|`contextMenu`> | \[`hover`] | |
|
||||||
| visible | Whether the dropdown menu is currently visible | boolean | - | |
|
| visible | Whether the dropdown menu is currently visible | boolean | - | |
|
||||||
| onVisibleChange | Called when the visible state is changed. Not trigger when hidden by click item | (visible: boolean) => void | - | |
|
| onVisibleChange | Called when the visible state is changed. Not trigger when hidden by click item | (visible: boolean) => void | - | |
|
||||||
@ -44,7 +44,7 @@ You should use [Menu](/components/menu/) as `overlay`. The menu items and divide
|
|||||||
| disabled | Whether the dropdown menu is disabled | boolean | - | |
|
| disabled | Whether the dropdown menu is disabled | boolean | - | |
|
||||||
| icon | Icon (appears on the right) | ReactNode | - | |
|
| icon | Icon (appears on the right) | ReactNode | - | |
|
||||||
| overlay | The dropdown menu | [Menu](/components/menu) | - | |
|
| overlay | The dropdown menu | [Menu](/components/menu) | - | |
|
||||||
| placement | Placement of popup menu: `bottomLeft` `bottomCenter` `bottomRight` `topLeft` `topCenter` `topRight` | string | `bottomLeft` | |
|
| placement | Placement of popup menu: `bottom` `bottomLeft` `bottomRight` `top` `topLeft` `topRight` | string | `bottomLeft` | |
|
||||||
| size | Size of the button, the same as [Button](/components/button/#API) | string | `default` | |
|
| size | Size of the button, the same as [Button](/components/button/#API) | string | `default` | |
|
||||||
| trigger | The trigger mode which executes the dropdown action | Array<`click`\|`hover`\|`contextMenu`> | \[`hover`] | |
|
| trigger | The trigger mode which executes the dropdown action | Array<`click`\|`hover`\|`contextMenu`> | \[`hover`] | |
|
||||||
| type | Type of the button, the same as [Button](/components/button/#API) | string | `default` | |
|
| type | Type of the button, the same as [Button](/components/button/#API) | string | `default` | |
|
||||||
|
@ -21,14 +21,14 @@ cover: https://gw.alipayobjects.com/zos/alicdn/eedWN59yJ/Dropdown.svg
|
|||||||
|
|
||||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| arrow | 下拉框箭头是否显示 | boolean | false | |
|
| arrow | 下拉框箭头是否显示 | boolean \| { pointAtCenter: boolean } | false | |
|
||||||
| disabled | 菜单是否禁用 | boolean | - | |
|
| disabled | 菜单是否禁用 | boolean | - | |
|
||||||
| destroyPopupOnHide | 关闭后是否销毁 Dropdown | boolean | false | |
|
| destroyPopupOnHide | 关闭后是否销毁 Dropdown | boolean | false | |
|
||||||
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | (triggerNode: HTMLElement) => HTMLElement | () => document.body | |
|
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | (triggerNode: HTMLElement) => HTMLElement | () => document.body | |
|
||||||
| overlay | 菜单 | [Menu](/components/menu) \| () => Menu | - | |
|
| overlay | 菜单 | [Menu](/components/menu) \| () => Menu | - | |
|
||||||
| overlayClassName | 下拉根元素的类名称 | string | - | |
|
| overlayClassName | 下拉根元素的类名称 | string | - | |
|
||||||
| overlayStyle | 下拉根元素的样式 | CSSProperties | - | |
|
| overlayStyle | 下拉根元素的样式 | CSSProperties | - | |
|
||||||
| placement | 菜单弹出位置:`bottomLeft` `bottomCenter` `bottomRight` `topLeft` `topCenter` `topRight` | string | `bottomLeft` | |
|
| placement | 菜单弹出位置:`bottom` `bottomLeft` `bottomRight` `top` `topLeft` `topRight` | string | `bottomLeft` | |
|
||||||
| trigger | 触发下拉的行为, 移动端不支持 hover | Array<`click`\|`hover`\|`contextMenu`> | \[`hover`] | |
|
| trigger | 触发下拉的行为, 移动端不支持 hover | Array<`click`\|`hover`\|`contextMenu`> | \[`hover`] | |
|
||||||
| visible | 菜单是否显示 | boolean | - | |
|
| visible | 菜单是否显示 | boolean | - | |
|
||||||
| onVisibleChange | 菜单显示状态改变时调用,参数为 `visible`。点击菜单按钮导致的消失不会触发 | (visible: boolean) => void | - | |
|
| onVisibleChange | 菜单显示状态改变时调用,参数为 `visible`。点击菜单按钮导致的消失不会触发 | (visible: boolean) => void | - | |
|
||||||
@ -48,7 +48,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/eedWN59yJ/Dropdown.svg
|
|||||||
| disabled | 菜单是否禁用 | boolean | - | |
|
| disabled | 菜单是否禁用 | boolean | - | |
|
||||||
| icon | 右侧的 icon | ReactNode | - | |
|
| icon | 右侧的 icon | ReactNode | - | |
|
||||||
| overlay | 菜单 | [Menu](/components/menu/) | - | |
|
| overlay | 菜单 | [Menu](/components/menu/) | - | |
|
||||||
| placement | 菜单弹出位置:`bottomLeft` `bottomCenter` `bottomRight` `topLeft` `topCenter` `topRight` | string | `bottomLeft` | |
|
| placement | 菜单弹出位置:`bottom` `bottomLeft` `bottomRight` `top` `topLeft` `topRight` | string | `bottomLeft` | |
|
||||||
| size | 按钮大小,和 [Button](/components/button/#API) 一致 | string | `default` | |
|
| size | 按钮大小,和 [Button](/components/button/#API) 一致 | string | `default` | |
|
||||||
| trigger | 触发下拉的行为 | Array<`click`\|`hover`\|`contextMenu`> | \[`hover`] | |
|
| trigger | 触发下拉的行为 | Array<`click`\|`hover`\|`contextMenu`> | \[`hover`] | |
|
||||||
| type | 按钮类型,和 [Button](/components/button/#API) 一致 | string | `default` | |
|
| type | 按钮类型,和 [Button](/components/button/#API) 一致 | string | `default` | |
|
||||||
|
@ -49,14 +49,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Offset the popover to account for the dropdown arrow
|
// Offset the popover to account for the dropdown arrow
|
||||||
&-show-arrow&-placement-topCenter,
|
|
||||||
&-show-arrow&-placement-topLeft,
|
&-show-arrow&-placement-topLeft,
|
||||||
|
&-show-arrow&-placement-top,
|
||||||
&-show-arrow&-placement-topRight {
|
&-show-arrow&-placement-topRight {
|
||||||
padding-bottom: @popover-distance;
|
padding-bottom: @popover-distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-show-arrow&-placement-bottomCenter,
|
|
||||||
&-show-arrow&-placement-bottomLeft,
|
&-show-arrow&-placement-bottomLeft,
|
||||||
|
&-show-arrow&-placement-bottom,
|
||||||
&-show-arrow&-placement-bottomRight {
|
&-show-arrow&-placement-bottomRight {
|
||||||
padding-top: @popover-distance;
|
padding-top: @popover-distance;
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@
|
|||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
&-placement-topCenter > &-arrow,
|
&-placement-top > &-arrow,
|
||||||
&-placement-topLeft > &-arrow,
|
&-placement-topLeft > &-arrow,
|
||||||
&-placement-topRight > &-arrow {
|
&-placement-topRight > &-arrow {
|
||||||
bottom: @popover-distance - @popover-arrow-width + 2.2px;
|
bottom: @popover-distance - @popover-arrow-width + 2.2px;
|
||||||
@ -84,7 +84,7 @@
|
|||||||
box-shadow: 3px 3px 7px fade(@black, 7%);
|
box-shadow: 3px 3px 7px fade(@black, 7%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&-placement-topCenter > &-arrow {
|
&-placement-top > &-arrow {
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%) rotate(45deg);
|
transform: translateX(-50%) rotate(45deg);
|
||||||
}
|
}
|
||||||
@ -97,7 +97,7 @@
|
|||||||
right: 16px;
|
right: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-placement-bottomCenter > &-arrow,
|
&-placement-bottom > &-arrow,
|
||||||
&-placement-bottomLeft > &-arrow,
|
&-placement-bottomLeft > &-arrow,
|
||||||
&-placement-bottomRight > &-arrow {
|
&-placement-bottomRight > &-arrow {
|
||||||
top: @popover-distance - @popover-arrow-width + 2px;
|
top: @popover-distance - @popover-arrow-width + 2px;
|
||||||
@ -105,7 +105,7 @@
|
|||||||
box-shadow: -2px -2px 5px fade(@black, 6%);
|
box-shadow: -2px -2px 5px fade(@black, 6%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&-placement-bottomCenter > &-arrow {
|
&-placement-bottom > &-arrow {
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%) rotate(45deg);
|
transform: translateX(-50%) rotate(45deg);
|
||||||
}
|
}
|
||||||
@ -300,8 +300,8 @@
|
|||||||
|
|
||||||
&.@{ant-prefix}-slide-down-enter.@{ant-prefix}-slide-down-enter-active&-placement-bottomLeft,
|
&.@{ant-prefix}-slide-down-enter.@{ant-prefix}-slide-down-enter-active&-placement-bottomLeft,
|
||||||
&.@{ant-prefix}-slide-down-appear.@{ant-prefix}-slide-down-appear-active&-placement-bottomLeft,
|
&.@{ant-prefix}-slide-down-appear.@{ant-prefix}-slide-down-appear-active&-placement-bottomLeft,
|
||||||
&.@{ant-prefix}-slide-down-enter.@{ant-prefix}-slide-down-enter-active&-placement-bottomCenter,
|
&.@{ant-prefix}-slide-down-enter.@{ant-prefix}-slide-down-enter-active&-placement-bottom,
|
||||||
&.@{ant-prefix}-slide-down-appear.@{ant-prefix}-slide-down-appear-active&-placement-bottomCenter,
|
&.@{ant-prefix}-slide-down-appear.@{ant-prefix}-slide-down-appear-active&-placement-bottom,
|
||||||
&.@{ant-prefix}-slide-down-enter.@{ant-prefix}-slide-down-enter-active&-placement-bottomRight,
|
&.@{ant-prefix}-slide-down-enter.@{ant-prefix}-slide-down-enter-active&-placement-bottomRight,
|
||||||
&.@{ant-prefix}-slide-down-appear.@{ant-prefix}-slide-down-appear-active&-placement-bottomRight {
|
&.@{ant-prefix}-slide-down-appear.@{ant-prefix}-slide-down-appear-active&-placement-bottomRight {
|
||||||
animation-name: antSlideUpIn;
|
animation-name: antSlideUpIn;
|
||||||
@ -309,21 +309,21 @@
|
|||||||
|
|
||||||
&.@{ant-prefix}-slide-up-enter.@{ant-prefix}-slide-up-enter-active&-placement-topLeft,
|
&.@{ant-prefix}-slide-up-enter.@{ant-prefix}-slide-up-enter-active&-placement-topLeft,
|
||||||
&.@{ant-prefix}-slide-up-appear.@{ant-prefix}-slide-up-appear-active&-placement-topLeft,
|
&.@{ant-prefix}-slide-up-appear.@{ant-prefix}-slide-up-appear-active&-placement-topLeft,
|
||||||
&.@{ant-prefix}-slide-up-enter.@{ant-prefix}-slide-up-enter-active&-placement-topCenter,
|
&.@{ant-prefix}-slide-up-enter.@{ant-prefix}-slide-up-enter-active&-placement-top,
|
||||||
&.@{ant-prefix}-slide-up-appear.@{ant-prefix}-slide-up-appear-active&-placement-topCenter,
|
&.@{ant-prefix}-slide-up-appear.@{ant-prefix}-slide-up-appear-active&-placement-top,
|
||||||
&.@{ant-prefix}-slide-up-enter.@{ant-prefix}-slide-up-enter-active&-placement-topRight,
|
&.@{ant-prefix}-slide-up-enter.@{ant-prefix}-slide-up-enter-active&-placement-topRight,
|
||||||
&.@{ant-prefix}-slide-up-appear.@{ant-prefix}-slide-up-appear-active&-placement-topRight {
|
&.@{ant-prefix}-slide-up-appear.@{ant-prefix}-slide-up-appear-active&-placement-topRight {
|
||||||
animation-name: antSlideDownIn;
|
animation-name: antSlideDownIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.@{ant-prefix}-slide-down-leave.@{ant-prefix}-slide-down-leave-active&-placement-bottomLeft,
|
&.@{ant-prefix}-slide-down-leave.@{ant-prefix}-slide-down-leave-active&-placement-bottomLeft,
|
||||||
&.@{ant-prefix}-slide-down-leave.@{ant-prefix}-slide-down-leave-active&-placement-bottomCenter,
|
&.@{ant-prefix}-slide-down-leave.@{ant-prefix}-slide-down-leave-active&-placement-bottom,
|
||||||
&.@{ant-prefix}-slide-down-leave.@{ant-prefix}-slide-down-leave-active&-placement-bottomRight {
|
&.@{ant-prefix}-slide-down-leave.@{ant-prefix}-slide-down-leave-active&-placement-bottomRight {
|
||||||
animation-name: antSlideUpOut;
|
animation-name: antSlideUpOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.@{ant-prefix}-slide-up-leave.@{ant-prefix}-slide-up-leave-active&-placement-topLeft,
|
&.@{ant-prefix}-slide-up-leave.@{ant-prefix}-slide-up-leave-active&-placement-topLeft,
|
||||||
&.@{ant-prefix}-slide-up-leave.@{ant-prefix}-slide-up-leave-active&-placement-topCenter,
|
&.@{ant-prefix}-slide-up-leave.@{ant-prefix}-slide-up-leave-active&-placement-top,
|
||||||
&.@{ant-prefix}-slide-up-leave.@{ant-prefix}-slide-up-leave-active&-placement-topRight {
|
&.@{ant-prefix}-slide-up-leave.@{ant-prefix}-slide-up-leave-active&-placement-topRight {
|
||||||
animation-name: antSlideDownOut;
|
animation-name: antSlideDownOut;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import useMergedState from 'rc-util/lib/hooks/useMergedState';
|
|||||||
import { TooltipProps as RcTooltipProps } from 'rc-tooltip/lib/Tooltip';
|
import { TooltipProps as RcTooltipProps } from 'rc-tooltip/lib/Tooltip';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { placements as Placements } from 'rc-tooltip/lib/placements';
|
import { placements as Placements } from 'rc-tooltip/lib/placements';
|
||||||
import getPlacements, { AdjustOverflow, PlacementsConfig } from './placements';
|
import getPlacements, { AdjustOverflow, PlacementsConfig } from '../_util/placements';
|
||||||
import { cloneElement, isValidElement } from '../_util/reactNode';
|
import { cloneElement, isValidElement } from '../_util/reactNode';
|
||||||
import { ConfigContext } from '../config-provider';
|
import { ConfigContext } from '../config-provider';
|
||||||
import { PresetColorType, PresetColorTypes } from '../_util/colors';
|
import { PresetColorType, PresetColorTypes } from '../_util/colors';
|
||||||
@ -130,9 +130,11 @@ function getDisabledCompatibleChildren(element: React.ReactElement<any>, prefixC
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
||||||
const { getPopupContainer: getContextPopupContainer, getPrefixCls, direction } = React.useContext(
|
const {
|
||||||
ConfigContext,
|
getPopupContainer: getContextPopupContainer,
|
||||||
);
|
getPrefixCls,
|
||||||
|
direction,
|
||||||
|
} = React.useContext(ConfigContext);
|
||||||
|
|
||||||
const [visible, setVisible] = useMergedState(false, {
|
const [visible, setVisible] = useMergedState(false, {
|
||||||
value: props.visible,
|
value: props.visible,
|
||||||
@ -167,11 +169,11 @@ const Tooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
|
|||||||
const onPopupAlign = (domNode: HTMLElement, align: any) => {
|
const onPopupAlign = (domNode: HTMLElement, align: any) => {
|
||||||
const placements: any = getTooltipPlacements();
|
const placements: any = getTooltipPlacements();
|
||||||
// 当前返回的位置
|
// 当前返回的位置
|
||||||
const placement = Object.keys(placements).filter(
|
const placement = Object.keys(placements).find(
|
||||||
key =>
|
key =>
|
||||||
placements[key].points[0] === align.points[0] &&
|
placements[key].points[0] === align.points[0] &&
|
||||||
placements[key].points[1] === align.points[1],
|
placements[key].points[1] === align.points[1],
|
||||||
)[0];
|
);
|
||||||
if (!placement) {
|
if (!placement) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@
|
|||||||
"rc-collapse": "~3.1.0",
|
"rc-collapse": "~3.1.0",
|
||||||
"rc-dialog": "~8.6.0",
|
"rc-dialog": "~8.6.0",
|
||||||
"rc-drawer": "~4.4.2",
|
"rc-drawer": "~4.4.2",
|
||||||
"rc-dropdown": "~3.2.0",
|
"rc-dropdown": "~3.2.2",
|
||||||
"rc-field-form": "~1.22.0-2",
|
"rc-field-form": "~1.22.0-2",
|
||||||
"rc-image": "~5.2.5",
|
"rc-image": "~5.2.5",
|
||||||
"rc-input-number": "~7.3.0",
|
"rc-input-number": "~7.3.0",
|
||||||
|
@ -523,7 +523,7 @@ class MainContent extends Component {
|
|||||||
</section>
|
</section>
|
||||||
{componentPage && (
|
{componentPage && (
|
||||||
<div className="fixed-widgets">
|
<div className="fixed-widgets">
|
||||||
<Dropdown overlay={this.getThemeSwitchMenu()} placement="topCenter">
|
<Dropdown overlay={this.getThemeSwitchMenu()} placement="top">
|
||||||
<Avatar className="fixed-widgets-avatar" size={44} icon={<ThemeIcon />} />
|
<Avatar className="fixed-widgets-avatar" size={44} icon={<ThemeIcon />} />
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user