mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-09 02:49:18 +08:00
feat(Breadcrumb,ConfigProvider): support dropdownIcon prop and config (#56250)
* feat(Breadcrumb,ConfigProvider): support dropdownIcon prop and config * refactor(Breadcrumb): import order * docs(Breadcrumb,ConfigProvider): dropdonIcon --------- Co-authored-by: thinkasany <480968828@qq.com>
This commit is contained in:
@@ -37,7 +37,7 @@ function getOffsetTop(element: HTMLElement, container: AnchorContainer): number
|
||||
|
||||
if (rect.width || rect.height) {
|
||||
if (container === window) {
|
||||
return rect.top - element.ownerDocument!.documentElement!.clientTop;
|
||||
return rect.top - element.ownerDocument.documentElement!.clientTop;
|
||||
}
|
||||
return rect.top - (container as HTMLElement).getBoundingClientRect().top;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as React from 'react';
|
||||
import { DownOutlined } from '@ant-design/icons';
|
||||
import { toArray } from '@rc-component/util';
|
||||
import pickAttrs from '@rc-component/util/lib/pickAttrs';
|
||||
import { clsx } from 'clsx';
|
||||
@@ -81,6 +82,7 @@ export interface BreadcrumbProps<T extends AnyObject = AnyObject> {
|
||||
prefixCls?: string;
|
||||
params?: T;
|
||||
separator?: React.ReactNode;
|
||||
dropdownIcon?: React.ReactNode;
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
rootClassName?: string;
|
||||
@@ -121,6 +123,7 @@ const Breadcrumb = <T extends AnyObject = AnyObject>(props: BreadcrumbProps<T>)
|
||||
params = {},
|
||||
classNames,
|
||||
styles,
|
||||
dropdownIcon,
|
||||
...restProps
|
||||
} = props;
|
||||
|
||||
@@ -132,9 +135,11 @@ const Breadcrumb = <T extends AnyObject = AnyObject>(props: BreadcrumbProps<T>)
|
||||
classNames: contextClassNames,
|
||||
styles: contextStyles,
|
||||
separator: contextSeparator,
|
||||
dropdownIcon: contextDropdownIcon,
|
||||
} = useComponentConfig('breadcrumb');
|
||||
|
||||
const mergedSeparator = separator ?? contextSeparator ?? '/';
|
||||
const mergedDropdownIcon = dropdownIcon ?? contextDropdownIcon ?? <DownOutlined />;
|
||||
|
||||
let crumbs: React.ReactNode;
|
||||
|
||||
@@ -240,6 +245,7 @@ const Breadcrumb = <T extends AnyObject = AnyObject>(props: BreadcrumbProps<T>)
|
||||
className={itemClassName}
|
||||
style={style}
|
||||
dropdownProps={dropdownProps}
|
||||
dropdownIcon={mergedDropdownIcon}
|
||||
href={href}
|
||||
separator={isLastItem ? '' : mergedSeparator}
|
||||
onClick={onClick}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import * as React from 'react';
|
||||
import DownOutlined from '@ant-design/icons/DownOutlined';
|
||||
import { clsx } from 'clsx';
|
||||
|
||||
import isNonNullable from '../_util/isNonNullable';
|
||||
@@ -33,6 +32,7 @@ export interface BreadcrumbItemProps extends SeparatorType {
|
||||
items?: MenuItem[];
|
||||
};
|
||||
dropdownProps?: DropdownProps;
|
||||
dropdownIcon?: React.ReactNode;
|
||||
onClick?: React.MouseEventHandler<HTMLAnchorElement | HTMLSpanElement>;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
@@ -40,7 +40,7 @@ export interface BreadcrumbItemProps extends SeparatorType {
|
||||
}
|
||||
|
||||
export const InternalBreadcrumbItem: React.FC<BreadcrumbItemProps> = (props) => {
|
||||
const { prefixCls, separator = '/', children, menu, dropdownProps, href } = props;
|
||||
const { prefixCls, separator = '/', children, menu, dropdownProps, href, dropdownIcon } = props;
|
||||
const breadcrumbContext = React.useContext(BreadcrumbContext);
|
||||
const { classNames: mergedClassNames, styles: mergedStyles } = breadcrumbContext;
|
||||
/** If overlay is have Wrap a Dropdown */
|
||||
@@ -74,7 +74,7 @@ export const InternalBreadcrumbItem: React.FC<BreadcrumbItemProps> = (props) =>
|
||||
<Dropdown placement="bottom" {...mergeDropDownProps}>
|
||||
<span className={`${prefixCls}-overlay-link`}>
|
||||
{breadcrumbItem}
|
||||
<DownOutlined />
|
||||
{dropdownIcon}
|
||||
</span>
|
||||
</Dropdown>
|
||||
);
|
||||
|
||||
@@ -3,7 +3,7 @@ import React from 'react';
|
||||
import { accessibilityTest } from '../../../tests/shared/accessibilityTest';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import { render } from '../../../tests/utils';
|
||||
import { render, screen } from '../../../tests/utils';
|
||||
import ConfigProvider from '../../config-provider';
|
||||
import type { ItemType } from '../Breadcrumb';
|
||||
import Breadcrumb from '../index';
|
||||
@@ -311,6 +311,75 @@ describe('Breadcrumb', () => {
|
||||
expect(document.querySelector('.ant-dropdown')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should support custom dropdownIcon', () => {
|
||||
render(
|
||||
<Breadcrumb
|
||||
items={[
|
||||
{
|
||||
title: 'test',
|
||||
menu: {
|
||||
items: [
|
||||
{
|
||||
key: '1',
|
||||
label: 'label',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
]}
|
||||
dropdownIcon={<span>foobar</span>}
|
||||
/>,
|
||||
);
|
||||
expect(screen.getByText('foobar')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should support custom dropdownIcon in ConfigProvider', () => {
|
||||
render(
|
||||
<ConfigProvider breadcrumb={{ dropdownIcon: <span>foobar</span> }}>
|
||||
<Breadcrumb
|
||||
items={[
|
||||
{
|
||||
title: 'test',
|
||||
menu: {
|
||||
items: [
|
||||
{
|
||||
key: '1',
|
||||
label: 'label',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</ConfigProvider>,
|
||||
);
|
||||
expect(screen.getByText('foobar')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should prefer custom dropdownIcon prop than ConfigProvider', () => {
|
||||
render(
|
||||
<ConfigProvider breadcrumb={{ dropdownIcon: <span>foobar</span> }}>
|
||||
<Breadcrumb
|
||||
items={[
|
||||
{
|
||||
title: 'test',
|
||||
menu: {
|
||||
items: [
|
||||
{
|
||||
key: '1',
|
||||
label: 'label',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
]}
|
||||
dropdownIcon={<span>bamboo</span>}
|
||||
/>
|
||||
</ConfigProvider>,
|
||||
);
|
||||
expect(screen.getByText('bamboo')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('Breadcrumb params type test', () => {
|
||||
interface Params {
|
||||
key1?: number;
|
||||
|
||||
@@ -53,6 +53,7 @@ Common props ref:[Common props](/docs/react/common-props)
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| classNames | Customize class for each semantic structure inside the component. Supports object or function. | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | |
|
||||
| dropdownIcon | Custom dropdown icon | ReactNode | `<DownOutlined />` | 6.2.0 |
|
||||
| itemRender | Custom item renderer | (route, params, routes, paths) => ReactNode | - | |
|
||||
| params | Routing parameters | object | - | |
|
||||
| items | The routing stack information of router | [ItemType\[\]](#itemtype) | - | 5.3.0 |
|
||||
|
||||
@@ -54,6 +54,7 @@ return <Breadcrumb routes={[{ breadcrumbName: 'sample' }]} />;
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| classNames | 用于自定义组件内部各语义化结构的 class,支持对象或函数 | Record<[SemanticDOM](#semantic-dom), string> \| (info: { props })=> Record<[SemanticDOM](#semantic-dom), string> | - | |
|
||||
| dropdownIcon | 自定义下拉图标 | ReactNode | `<DownOutlined />` | 6.2.0 |
|
||||
| itemRender | 自定义链接函数,和 react-router 配置使用 | (route, params, routes, paths) => ReactNode | - | |
|
||||
| params | 路由的参数 | object | - | |
|
||||
| items | 路由栈信息 | [items\[\]](#itemtype) | - | 5.3.0 |
|
||||
|
||||
@@ -242,7 +242,7 @@ export type AlertConfig = ComponentStyleConfig &
|
||||
export type BadgeConfig = ComponentStyleConfig & Pick<BadgeProps, 'classNames' | 'styles'>;
|
||||
|
||||
export type BreadcrumbConfig = ComponentStyleConfig &
|
||||
Pick<BreadcrumbProps, 'classNames' | 'styles' | 'separator'>;
|
||||
Pick<BreadcrumbProps, 'classNames' | 'styles' | 'separator' | 'dropdownIcon'>;
|
||||
|
||||
export type InputConfig = ComponentStyleConfig &
|
||||
Pick<InputProps, 'autoComplete' | 'classNames' | 'styles' | 'allowClear' | 'variant'>;
|
||||
|
||||
@@ -113,7 +113,7 @@ const {
|
||||
| anchor | Set Anchor common props | { className?: string, style?: React.CSSProperties, classNames?: [AnchorStyleConfig\["classNames"\]](/components/anchor#semantic-dom), styles?: [AnchorStyleConfig\["styles"\]](/components/anchor#semantic-dom), successIcon?: React.ReactNode, infoIcon?: React.ReactNode, warningIcon?: React.ReactNode, errorIcon?: React.ReactNode } | - | 5.7.0 , `classNames` and `styles`: 6.0.0, `successIcon`, `infoIcon`, `warningIcon` and `errorIcon`: 6.2.0 |
|
||||
| avatar | Set Avatar common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
|
||||
| badge | Set Badge common props | { className?: string, style?: React.CSSProperties, classNames?: [BadgeProps\["classNames"\]](/components/badge#semantic-dom), styles?: [BadgeProps\["styles"\]](/components/badge#semantic-dom) } | - | 5.7.0 |
|
||||
| breadcrumb | Set Breadcrumb common props | { className?: string, style?: React.CSSProperties, classNames?: [BreadcrumbConfig\["classNames"\]](/components/breadcrumb#semantic-dom), styles?: [BreadcrumbConfig\["styles"\]](/components/breadcrumb#semantic-dom), separator?: ReactNode } | - | 5.7.0, `classNames`, `separator` and `styles`: 6.0.0 |
|
||||
| breadcrumb | Set Breadcrumb common props | { className?: string, style?: React.CSSProperties, classNames?: [BreadcrumbConfig\["classNames"\]](/components/breadcrumb#semantic-dom), styles?: [BreadcrumbConfig\["styles"\]](/components/breadcrumb#semantic-dom), separator?: ReactNode, dropdownIcon?: ReactNode } | - | 5.7.0, `classNames`, `separator` and `styles`: 6.0.0, `dropdownIcon`: 6.2.0 |
|
||||
| button | Set Button common props | { className?: string, style?: React.CSSProperties, classNames?: [ButtonProps\["classNames"\]](/components/button#semantic-dom), styles?: [ButtonProps\["styles"\]](/components/button#semantic-dom), autoInsertSpace?: boolean, variant?: ButtonVariantType, color?: ButtonColorType, shape?: [ButtonProps\["shape"\]](/components/button#api) } | - | 5.6.0, `autoInsertSpace`: 5.17.0, `variant` and `color`: 5.25.0, `shape`: 5.27.0 |
|
||||
| card | Set Card common props | { className?: string, style?: React.CSSProperties, classNames?: [CardProps\["classNames"\]](/components/card#semantic-dom), styles?: [CardProps\["styles"\]](/components/card#semantic-dom) } | - | 5.7.0, `classNames` and `styles`: 5.14.0 |
|
||||
| cardMeta | Set Card.Meta common props | { className?: string, style?: React.CSSProperties, classNames?: [CardMetaProps\["classNames"\]](/components/card#semantic-dom), styles?: [CardMetaProps\["styles"\]](/components/card#semantic-dom) } | - | 6.0.0 |
|
||||
|
||||
@@ -115,7 +115,7 @@ const {
|
||||
| anchor | 设置 Anchor 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [AnchorStyleConfig\["classNames"\]](/components/anchor-cn#semantic-dom), styles?: [AnchorStyleConfig\["styles"\]](/components/anchor-cn#semantic-dom), successIcon?: React.ReactNode, infoIcon?: React.ReactNode, warningIcon?: React.ReactNode, errorIcon?: React.ReactNode } | - | 5.7.0, `classNames` 和 `styles`: 6.0.0, `successIcon`, `infoIcon`, `warningIcon` 和 `errorIcon`: 6.2.0 |
|
||||
| avatar | 设置 Avatar 组件的通用属性 | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
|
||||
| badge | 设置 Badge 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [BadgeProps\["classNames"\]](/components/badge-cn#semantic-dom), styles?: [BadgeProps\["styles"\]](/components/badge-cn#semantic-dom) } | - | 5.7.0 |
|
||||
| breadcrumb | 设置 Breadcrumb 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [BreadcrumbConfig\["classNames"\]](/components/breadcrumb-cn#semantic-dom), styles?: [BreadcrumbConfig\["styles"\]](/components/breadcrumb-cn#semantic-dom), separator?: ReactNode } | - | 5.7.0, `classNames`, `separator` 和 `styles`: 6.0.0 |
|
||||
| breadcrumb | 设置 Breadcrumb 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [BreadcrumbConfig\["classNames"\]](/components/breadcrumb-cn#semantic-dom), styles?: [BreadcrumbConfig\["styles"\]](/components/breadcrumb-cn#semantic-dom), separator?: ReactNode, dropdownIcon?: ReactNode } | - | 5.7.0, `classNames`, `separator` 和 `styles`: 6.0.0, `dropdownIcon`: 6.2.0 |
|
||||
| button | 设置 Button 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [ButtonProps\["classNames"\]](/components/button-cn#semantic-dom), styles?: [ButtonProps\["styles"\]](/components/button-cn#semantic-dom), autoInsertSpace?: boolean, variant?: ButtonVariantType, color?: ButtonColorType, shape?: [ButtonProps\["shape"\]](/components/button#api) } | - | 5.6.0, `autoInsertSpace`: 5.17.0, `variant` 和 `color`: 5.25.0, `shape`: 5.27.0 |
|
||||
| calendar | 设置 Calendar 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [CalendarConfig\["classNames"\]](/components/calendar-cn#semantic-dom), styles?: [CalendarConfig\["styles"\]](/components/calendar-cn#semantic-dom) } | - | 5.7.0, `classNames` 和 `styles`: 6.0.0 |
|
||||
| card | 设置 Card 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: [CardProps\["classNames"\]](/components/card-cn#semantic-dom), styles?: [CardProps\["styles"\]](/components/card-cn#semantic-dom) } | - | 5.7.0, `classNames` 和 `styles`: 5.14.0 |
|
||||
|
||||
Reference in New Issue
Block a user