Files
ant-design/components/breadcrumb/useItemRender.tsx
lijianan f96282a4f9 refactor: reuse isNonNullable (#55827)
* refactor: reuse isNonNullable

* update
2025-11-23 16:25:26 +08:00

73 lines
1.9 KiB
TypeScript

import * as React from 'react';
import pickAttrs from '@rc-component/util/lib/pickAttrs';
import { clsx } from 'clsx';
import isNonNullable from '../_util/isNonNullable';
import type { BreadcrumbProps, InternalRouteType, ItemType } from './Breadcrumb';
type AddParameters<TFunction extends (...args: any) => any, TParameters extends [...args: any]> = (
...args: [...Parameters<TFunction>, ...TParameters]
) => ReturnType<TFunction>;
type ItemRender = NonNullable<BreadcrumbProps['itemRender']>;
type InternalItemRenderParams = AddParameters<ItemRender, [href?: string]>;
function getBreadcrumbName(route: InternalRouteType, params: any) {
if (!isNonNullable(route.title)) {
return null;
}
const paramsKeys = Object.keys(params).join('|');
return typeof route.title === 'object'
? route.title
: String(route.title).replace(
new RegExp(`:(${paramsKeys})`, 'g'),
(replacement, key) => params[key] || replacement,
);
}
export function renderItem(
prefixCls: string,
item: ItemType,
children: React.ReactNode,
href?: string,
) {
if (!isNonNullable(children)) {
return null;
}
const { className, onClick, ...restItem } = item;
const passedProps = {
...pickAttrs(restItem, { data: true, aria: true }),
onClick,
};
if (href !== undefined) {
return (
<a {...passedProps} className={clsx(`${prefixCls}-link`, className)} href={href}>
{children}
</a>
);
}
return (
<span {...passedProps} className={clsx(`${prefixCls}-link`, className)}>
{children}
</span>
);
}
export default function useItemRender(prefixCls: string, itemRender?: ItemRender) {
const mergedItemRender: InternalItemRenderParams = (item, params, routes, path, href) => {
if (itemRender) {
return itemRender(item, params, routes, path);
}
const name = getBreadcrumbName(item, params);
return renderItem(prefixCls, item, name, href);
};
return mergedItemRender;
}