PagePathHierarchicalLink.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import React, { memo, useCallback } from 'react';
  2. import Link from 'next/link';
  3. import urljoin from 'url-join';
  4. import LinkedPagePath from '../models/linked-page-path';
  5. type PagePathHierarchicalLinkProps = {
  6. linkedPagePath: LinkedPagePath,
  7. linkedPagePathByHtml?: LinkedPagePath,
  8. basePath?: string,
  9. isInTrash?: boolean,
  10. // !!INTERNAL USE ONLY!!
  11. isInnerElem?: boolean,
  12. };
  13. // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
  14. const PagePathHierarchicalLink = memo((props: PagePathHierarchicalLinkProps): JSX.Element => {
  15. const {
  16. linkedPagePath, linkedPagePathByHtml, basePath, isInTrash, isInnerElem,
  17. } = props;
  18. // eslint-disable-next-line react/prop-types
  19. const RootElm = useCallback(({ children }) => {
  20. return isInnerElem
  21. ? <>{children}</>
  22. : <span className="grw-page-path-hierarchical-link text-break">{children}</span>;
  23. }, [isInnerElem]);
  24. // render root element
  25. if (linkedPagePath.isRoot) {
  26. if (basePath != null) {
  27. return <></>;
  28. }
  29. return isInTrash
  30. ? (
  31. <RootElm>
  32. <span className="path-segment">
  33. <Link href="/trash" prefetch={false}>
  34. <i className="icon-trash"></i>
  35. </Link>
  36. </span>
  37. <span className="separator"><a href="/">/</a></span>
  38. </RootElm>
  39. )
  40. : (
  41. <RootElm>
  42. <span className="path-segment">
  43. <Link href="/" prefetch={false}>
  44. <i className="icon-home"></i>
  45. <span className="separator">/</span>
  46. </Link>
  47. </span>
  48. </RootElm>
  49. );
  50. }
  51. const isParentExists = linkedPagePath.parent != null;
  52. const isParentRoot = linkedPagePath.parent?.isRoot;
  53. const isSeparatorRequired = isParentExists && !isParentRoot;
  54. const shouldDangerouslySetInnerHTML = linkedPagePathByHtml != null;
  55. const href = encodeURI(urljoin(basePath || '/', linkedPagePath.href));
  56. return (
  57. <RootElm>
  58. { isParentExists && (
  59. <PagePathHierarchicalLink
  60. linkedPagePath={linkedPagePath.parent}
  61. linkedPagePathByHtml={linkedPagePathByHtml?.parent}
  62. basePath={basePath}
  63. isInTrash={isInTrash || linkedPagePath.isInTrash}
  64. isInnerElem
  65. />
  66. ) }
  67. { isSeparatorRequired && (
  68. <span className="separator">/</span>
  69. ) }
  70. <Link href={href} prefetch={false} legacyBehavior>
  71. {
  72. shouldDangerouslySetInnerHTML
  73. // eslint-disable-next-line react/no-danger
  74. ? <a className="page-segment" dangerouslySetInnerHTML={{ __html: linkedPagePathByHtml.pathName }}></a>
  75. : <a className="page-segment" >{linkedPagePath.pathName}</a>
  76. }
  77. </Link>
  78. </RootElm>
  79. );
  80. });
  81. PagePathHierarchicalLink.displayName = 'PagePathHierarchicalLink';
  82. export default PagePathHierarchicalLink;