PagePathHierarchicalLink.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import React, { memo } 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,
  17. } = props;
  18. // render root element
  19. if (linkedPagePath.isRoot) {
  20. if (basePath != null) {
  21. return <></>;
  22. }
  23. return isInTrash
  24. ? (
  25. <>
  26. <span className="path-segment">
  27. <Link href="/trash">
  28. <a ><i className="icon-trash"></i></a>
  29. </Link>
  30. </span>
  31. <span className="separator"><a href="/">/</a></span>
  32. </>
  33. )
  34. : (
  35. <>
  36. <span className="path-segment">
  37. <Link href="/">
  38. <a >
  39. <i className="icon-home"></i>
  40. <span className="separator">/</span>
  41. </a>
  42. </Link>
  43. </span>
  44. </>
  45. );
  46. }
  47. const isParentExists = linkedPagePath.parent != null;
  48. const isParentRoot = linkedPagePath.parent?.isRoot;
  49. const isSeparatorRequired = isParentExists && !isParentRoot;
  50. const shouldDangerouslySetInnerHTML = linkedPagePathByHtml != null;
  51. const href = encodeURI(urljoin(basePath || '/', linkedPagePath.href));
  52. // eslint-disable-next-line react/prop-types
  53. const RootElm = ({ children }) => {
  54. return props.isInnerElem
  55. ? <>{children}</>
  56. : <span className="grw-page-path-hierarchical-link text-break">{children}</span>;
  57. };
  58. return (
  59. <RootElm>
  60. { isParentExists && (
  61. <PagePathHierarchicalLink
  62. linkedPagePath={linkedPagePath.parent}
  63. linkedPagePathByHtml={linkedPagePathByHtml?.parent}
  64. basePath={basePath}
  65. isInTrash={isInTrash || linkedPagePath.isInTrash}
  66. isInnerElem
  67. />
  68. ) }
  69. { isSeparatorRequired && (
  70. <span className="separator">/</span>
  71. ) }
  72. <Link href={href}>
  73. {
  74. shouldDangerouslySetInnerHTML
  75. // eslint-disable-next-line react/no-danger
  76. ? <a className="page-segment" dangerouslySetInnerHTML={{ __html: linkedPagePathByHtml.pathName }}></a>
  77. : <a className="page-segment" >{linkedPagePath.pathName}</a>
  78. }
  79. </Link>
  80. </RootElm>
  81. );
  82. });
  83. PagePathHierarchicalLink.displayName = 'PagePathHierarchicalLink';
  84. export default PagePathHierarchicalLink;