mirror of
https://github.com/ant-design/ant-design.git
synced 2025-07-30 19:36:29 +08:00
type: params type support generic (#43211)
* type: type optimization * test: add test case
This commit is contained in:
parent
90a381df2a
commit
00f4ed3dc9
@ -46,9 +46,9 @@ export type ItemType = Partial<BreadcrumbItemType & BreadcrumbSeparatorType>;
|
|||||||
|
|
||||||
export type InternalRouteType = Partial<BreadcrumbItemType & BreadcrumbSeparatorType>;
|
export type InternalRouteType = Partial<BreadcrumbItemType & BreadcrumbSeparatorType>;
|
||||||
|
|
||||||
export interface BreadcrumbProps {
|
export interface BreadcrumbProps<T extends Record<PropertyKey, any> = any> {
|
||||||
prefixCls?: string;
|
prefixCls?: string;
|
||||||
params?: any;
|
params?: T;
|
||||||
separator?: React.ReactNode;
|
separator?: React.ReactNode;
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
className?: string;
|
className?: string;
|
||||||
@ -60,19 +60,13 @@ export interface BreadcrumbProps {
|
|||||||
|
|
||||||
items?: ItemType[];
|
items?: ItemType[];
|
||||||
|
|
||||||
itemRender?: (
|
itemRender?: (route: ItemType, params: T, routes: ItemType[], paths: string[]) => React.ReactNode;
|
||||||
route: ItemType,
|
|
||||||
params: any,
|
|
||||||
routes: ItemType[],
|
|
||||||
paths: string[],
|
|
||||||
) => React.ReactNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getPath = (params: any, path?: string) => {
|
const getPath = <T extends Record<PropertyKey, any> = any>(params: T, path?: string) => {
|
||||||
if (path === undefined) {
|
if (path === undefined) {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mergedPath = (path || '').replace(/^\//, '');
|
let mergedPath = (path || '').replace(/^\//, '');
|
||||||
Object.keys(params).forEach((key) => {
|
Object.keys(params).forEach((key) => {
|
||||||
mergedPath = mergedPath.replace(`:${key}`, params[key]!);
|
mergedPath = mergedPath.replace(`:${key}`, params[key]!);
|
||||||
@ -80,7 +74,7 @@ const getPath = (params: any, path?: string) => {
|
|||||||
return mergedPath;
|
return mergedPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Breadcrumb = (props: BreadcrumbProps) => {
|
const Breadcrumb = <T extends Record<PropertyKey, any> = any>(props: BreadcrumbProps<T>) => {
|
||||||
const {
|
const {
|
||||||
prefixCls: customizePrefixCls,
|
prefixCls: customizePrefixCls,
|
||||||
separator = '/',
|
separator = '/',
|
||||||
@ -113,7 +107,7 @@ const Breadcrumb = (props: BreadcrumbProps) => {
|
|||||||
// generated by route
|
// generated by route
|
||||||
const paths: string[] = [];
|
const paths: string[] = [];
|
||||||
|
|
||||||
const itemRenderRoutes: any = items || legacyRoutes;
|
const itemRenderRoutes = items || legacyRoutes;
|
||||||
|
|
||||||
crumbs = mergedItems.map((item, index) => {
|
crumbs = mergedItems.map((item, index) => {
|
||||||
const {
|
const {
|
||||||
@ -168,7 +162,7 @@ const Breadcrumb = (props: BreadcrumbProps) => {
|
|||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
prefixCls={prefixCls}
|
prefixCls={prefixCls}
|
||||||
>
|
>
|
||||||
{mergedItemRender(item as BreadcrumbItemType, params, itemRenderRoutes, paths, href)}
|
{mergedItemRender(item, params, itemRenderRoutes!, paths, href)}
|
||||||
</InternalBreadcrumbItem>
|
</InternalBreadcrumbItem>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -37,7 +37,7 @@ export interface BreadcrumbItemProps extends SeparatorType {
|
|||||||
overlay?: DropdownProps['overlay'];
|
overlay?: DropdownProps['overlay'];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const InternalBreadcrumbItem = (props: BreadcrumbItemProps) => {
|
export const InternalBreadcrumbItem: React.FC<BreadcrumbItemProps> = (props) => {
|
||||||
const { prefixCls, separator = '/', children, menu, overlay, dropdownProps, href } = props;
|
const { prefixCls, separator = '/', children, menu, overlay, dropdownProps, href } = props;
|
||||||
|
|
||||||
// Warning for deprecated usage
|
// Warning for deprecated usage
|
||||||
@ -103,11 +103,15 @@ export const InternalBreadcrumbItem = (props: BreadcrumbItemProps) => {
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const BreadcrumbItem = (props: BreadcrumbItemProps) => {
|
type CompoundedComponent = React.FC<BreadcrumbItemProps> & {
|
||||||
|
/** @internal */
|
||||||
|
__ANT_BREADCRUMB_ITEM: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const BreadcrumbItem: CompoundedComponent = (props) => {
|
||||||
const { prefixCls: customizePrefixCls, children, href, ...restProps } = props;
|
const { prefixCls: customizePrefixCls, children, href, ...restProps } = props;
|
||||||
const { getPrefixCls } = React.useContext(ConfigContext);
|
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||||
const prefixCls = getPrefixCls('breadcrumb', customizePrefixCls);
|
const prefixCls = getPrefixCls('breadcrumb', customizePrefixCls);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InternalBreadcrumbItem {...restProps} prefixCls={prefixCls}>
|
<InternalBreadcrumbItem {...restProps} prefixCls={prefixCls}>
|
||||||
{renderItem(prefixCls, restProps as ItemType, children, href)}
|
{renderItem(prefixCls, restProps as ItemType, children, href)}
|
||||||
|
@ -384,4 +384,19 @@ describe('Breadcrumb', () => {
|
|||||||
);
|
);
|
||||||
expect(document.querySelector('.ant-dropdown')).toBeTruthy();
|
expect(document.querySelector('.ant-dropdown')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Breadcrumb params type test', () => {
|
||||||
|
interface Params {
|
||||||
|
key1?: number;
|
||||||
|
key2?: string;
|
||||||
|
}
|
||||||
|
expect(
|
||||||
|
<Breadcrumb<Params>
|
||||||
|
params={{
|
||||||
|
key1: 1,
|
||||||
|
key2: 'test',
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
).toBeTruthy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user