Breadcrumb.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. "use client";
  2. var __rest = this && this.__rest || function (s, e) {
  3. var t = {};
  4. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
  5. if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  6. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
  7. }
  8. return t;
  9. };
  10. import * as React from 'react';
  11. import classNames from 'classnames';
  12. import toArray from "rc-util/es/Children/toArray";
  13. import pickAttrs from "rc-util/es/pickAttrs";
  14. import { cloneElement } from '../_util/reactNode';
  15. import { devUseWarning } from '../_util/warning';
  16. import { ConfigContext } from '../config-provider';
  17. import BreadcrumbItem, { InternalBreadcrumbItem } from './BreadcrumbItem';
  18. import BreadcrumbSeparator from './BreadcrumbSeparator';
  19. import useStyle from './style';
  20. import useItemRender from './useItemRender';
  21. import useItems from './useItems';
  22. const getPath = (params, path) => {
  23. if (path === undefined) {
  24. return path;
  25. }
  26. let mergedPath = (path || '').replace(/^\//, '');
  27. Object.keys(params).forEach(key => {
  28. mergedPath = mergedPath.replace(`:${key}`, params[key]);
  29. });
  30. return mergedPath;
  31. };
  32. const Breadcrumb = props => {
  33. const {
  34. prefixCls: customizePrefixCls,
  35. separator = '/',
  36. style,
  37. className,
  38. rootClassName,
  39. routes: legacyRoutes,
  40. items,
  41. children,
  42. itemRender,
  43. params = {}
  44. } = props,
  45. restProps = __rest(props, ["prefixCls", "separator", "style", "className", "rootClassName", "routes", "items", "children", "itemRender", "params"]);
  46. const {
  47. getPrefixCls,
  48. direction,
  49. breadcrumb
  50. } = React.useContext(ConfigContext);
  51. let crumbs;
  52. const prefixCls = getPrefixCls('breadcrumb', customizePrefixCls);
  53. const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls);
  54. const mergedItems = useItems(items, legacyRoutes);
  55. if (process.env.NODE_ENV !== 'production') {
  56. const warning = devUseWarning('Breadcrumb');
  57. warning.deprecated(!legacyRoutes, 'routes', 'items');
  58. // Deprecated warning for breadcrumb children
  59. if (!mergedItems || mergedItems.length === 0) {
  60. const childList = toArray(children);
  61. warning.deprecated(childList.length === 0, 'Breadcrumb.Item and Breadcrumb.Separator', 'items');
  62. childList.forEach(element => {
  63. if (element) {
  64. process.env.NODE_ENV !== "production" ? warning(element.type && (element.type.__ANT_BREADCRUMB_ITEM === true || element.type.__ANT_BREADCRUMB_SEPARATOR === true), 'usage', "Only accepts Breadcrumb.Item and Breadcrumb.Separator as it's children") : void 0;
  65. }
  66. });
  67. }
  68. }
  69. const mergedItemRender = useItemRender(prefixCls, itemRender);
  70. if (mergedItems && mergedItems.length > 0) {
  71. // generated by route
  72. const paths = [];
  73. const itemRenderRoutes = items || legacyRoutes;
  74. crumbs = mergedItems.map((item, index) => {
  75. const {
  76. path,
  77. key,
  78. type,
  79. menu,
  80. overlay,
  81. onClick,
  82. className: itemClassName,
  83. separator: itemSeparator,
  84. dropdownProps
  85. } = item;
  86. const mergedPath = getPath(params, path);
  87. if (mergedPath !== undefined) {
  88. paths.push(mergedPath);
  89. }
  90. const mergedKey = key !== null && key !== void 0 ? key : index;
  91. if (type === 'separator') {
  92. return /*#__PURE__*/React.createElement(BreadcrumbSeparator, {
  93. key: mergedKey
  94. }, itemSeparator);
  95. }
  96. const itemProps = {};
  97. const isLastItem = index === mergedItems.length - 1;
  98. if (menu) {
  99. itemProps.menu = menu;
  100. } else if (overlay) {
  101. itemProps.overlay = overlay;
  102. }
  103. let {
  104. href
  105. } = item;
  106. if (paths.length && mergedPath !== undefined) {
  107. href = `#/${paths.join('/')}`;
  108. }
  109. return /*#__PURE__*/React.createElement(InternalBreadcrumbItem, Object.assign({
  110. key: mergedKey
  111. }, itemProps, pickAttrs(item, {
  112. data: true,
  113. aria: true
  114. }), {
  115. className: itemClassName,
  116. dropdownProps: dropdownProps,
  117. href: href,
  118. separator: isLastItem ? '' : separator,
  119. onClick: onClick,
  120. prefixCls: prefixCls
  121. }), mergedItemRender(item, params, itemRenderRoutes, paths, href));
  122. });
  123. } else if (children) {
  124. const childrenLength = toArray(children).length;
  125. crumbs = toArray(children).map((element, index) => {
  126. if (!element) {
  127. return element;
  128. }
  129. const isLastItem = index === childrenLength - 1;
  130. return cloneElement(element, {
  131. separator: isLastItem ? '' : separator,
  132. // eslint-disable-next-line react/no-array-index-key
  133. key: index
  134. });
  135. });
  136. }
  137. const breadcrumbClassName = classNames(prefixCls, breadcrumb === null || breadcrumb === void 0 ? void 0 : breadcrumb.className, {
  138. [`${prefixCls}-rtl`]: direction === 'rtl'
  139. }, className, rootClassName, hashId, cssVarCls);
  140. const mergedStyle = Object.assign(Object.assign({}, breadcrumb === null || breadcrumb === void 0 ? void 0 : breadcrumb.style), style);
  141. return wrapCSSVar(/*#__PURE__*/React.createElement("nav", Object.assign({
  142. className: breadcrumbClassName,
  143. style: mergedStyle
  144. }, restProps), /*#__PURE__*/React.createElement("ol", null, crumbs)));
  145. };
  146. Breadcrumb.Item = BreadcrumbItem;
  147. Breadcrumb.Separator = BreadcrumbSeparator;
  148. if (process.env.NODE_ENV !== 'production') {
  149. Breadcrumb.displayName = 'Breadcrumb';
  150. }
  151. export default Breadcrumb;