FolderItem.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import { Details2Svg } from '../../_shared/svg/Details2Svg';
  2. import AddSvg from '../../_shared/svg/AddSvg';
  3. import { NavItemOptionsPopup } from './NavItemOptionsPopup';
  4. import { NewPagePopup } from './NewPagePopup';
  5. import { IFolder } from '../../../stores/reducers/folders/slice';
  6. import { useFolderEvents } from './FolderItem.hooks';
  7. import { IPage } from '../../../stores/reducers/pages/slice';
  8. import { PageItem } from './PageItem';
  9. import { Button } from '../../_shared/Button';
  10. import { RenamePopup } from './RenamePopup';
  11. import { useEffect, useRef, useState } from 'react';
  12. import { DropDownShowSvg } from '../../_shared/svg/DropDownShowSvg';
  13. import { ANIMATION_DURATION } from '../../_shared/constants';
  14. let timeoutHandle: any;
  15. export const FolderItem = ({
  16. folder,
  17. pages,
  18. onPageClick,
  19. }: {
  20. folder: IFolder;
  21. pages: IPage[];
  22. onPageClick: (page: IPage) => void;
  23. }) => {
  24. const {
  25. showPages,
  26. onFolderNameClick,
  27. showFolderOptions,
  28. onFolderOptionsClick,
  29. showNewPageOptions,
  30. onNewPageClick,
  31. showRenamePopup,
  32. startFolderRename,
  33. changeFolderTitle,
  34. closeRenamePopup,
  35. deleteFolder,
  36. duplicateFolder,
  37. onAddNewDocumentPage,
  38. onAddNewBoardPage,
  39. onAddNewGridPage,
  40. closePopup,
  41. folderHeight,
  42. setOffsetTop,
  43. } = useFolderEvents(folder, pages);
  44. const [hideOverflow, setHideOverflow] = useState(!showPages);
  45. useEffect(() => {
  46. clearTimeout(timeoutHandle);
  47. if (showPages) {
  48. timeoutHandle = setTimeout(() => {
  49. setHideOverflow(!showPages);
  50. }, ANIMATION_DURATION);
  51. } else {
  52. setHideOverflow(!showPages);
  53. }
  54. }, [showPages]);
  55. const el = useRef<HTMLDivElement>(null);
  56. useEffect(() => {
  57. setOffsetTop(el.current?.offsetTop || 0);
  58. }, [el, showPages]);
  59. return (
  60. <div className={'relative'} ref={el}>
  61. <div
  62. className={`relative my-2 ${hideOverflow ? 'overflow-hidden' : ''} transition-all `}
  63. style={{ height: folderHeight, transitionDuration: `${ANIMATION_DURATION}ms` }}
  64. >
  65. <div
  66. onClick={() => onFolderNameClick()}
  67. className={'flex cursor-pointer items-center justify-between rounded-lg px-4 py-2 hover:bg-surface-2'}
  68. >
  69. <button className={'flex min-w-0 flex-1 items-center'}>
  70. <i className={`mr-2 h-5 w-5 transition-transform duration-500 ${showPages && 'rotate-180'}`}>
  71. {pages.length > 0 && <DropDownShowSvg></DropDownShowSvg>}
  72. </i>
  73. <span className={'min-w-0 flex-1 overflow-hidden overflow-ellipsis whitespace-nowrap text-left'}>
  74. {folder.title}
  75. </span>
  76. </button>
  77. <div className={'relative flex items-center'}>
  78. <Button size={'box-small-transparent'} onClick={() => onFolderOptionsClick()}>
  79. <Details2Svg></Details2Svg>
  80. </Button>
  81. <Button size={'box-small-transparent'} onClick={() => onNewPageClick()}>
  82. <AddSvg></AddSvg>
  83. </Button>
  84. </div>
  85. </div>
  86. {pages.map((page, index) => (
  87. <PageItem key={index} page={page} onPageClick={() => onPageClick(page)}></PageItem>
  88. ))}
  89. </div>
  90. {showFolderOptions && (
  91. <NavItemOptionsPopup
  92. onRenameClick={() => startFolderRename()}
  93. onDeleteClick={() => deleteFolder()}
  94. onDuplicateClick={() => duplicateFolder()}
  95. onClose={() => closePopup()}
  96. ></NavItemOptionsPopup>
  97. )}
  98. {showNewPageOptions && (
  99. <NewPagePopup
  100. onDocumentClick={() => onAddNewDocumentPage()}
  101. onBoardClick={() => onAddNewBoardPage()}
  102. onGridClick={() => onAddNewGridPage()}
  103. onClose={() => closePopup()}
  104. ></NewPagePopup>
  105. )}
  106. {showRenamePopup && (
  107. <RenamePopup
  108. value={folder.title}
  109. onChange={(newTitle) => changeFolderTitle(newTitle)}
  110. onClose={closeRenamePopup}
  111. ></RenamePopup>
  112. )}
  113. </div>
  114. );
  115. };