TextInputForPageTitleAndPath.tsx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import { useCallback } from 'react';
  2. import type { Dispatch, SetStateAction, FC } from 'react';
  3. import type { IPagePopulatedToShowRevision } from '@growi/core';
  4. import { useTranslation } from 'next-i18next';
  5. import { ValidationTarget } from '~/client/util/input-validator';
  6. import ClosableTextInput from '../Common/ClosableTextInput';
  7. import { usePagePathRenameHandler } from './page-header-utils';
  8. export type editedPagePathState = {
  9. editedPagePath: string
  10. setEditedPagePath: Dispatch<SetStateAction<string>>
  11. }
  12. type StateHandler = {
  13. isRenameInputShown: boolean
  14. setRenameInputShown: Dispatch<SetStateAction<boolean>>
  15. }
  16. type Props = {
  17. currentPage: IPagePopulatedToShowRevision
  18. stateHandler: StateHandler
  19. inputValue: string
  20. CustomComponent: JSX.Element
  21. onInputChange?: (string) => void
  22. onPressEscape?: () => void
  23. }
  24. export const TextInputForPageTitleAndPath: FC<Props> = (props) => {
  25. const {
  26. currentPage, stateHandler, inputValue, CustomComponent, onInputChange, onPressEscape,
  27. } = props;
  28. const { t } = useTranslation();
  29. const { isRenameInputShown, setRenameInputShown } = stateHandler;
  30. const pagePathRenameHandler = usePagePathRenameHandler(currentPage);
  31. const onPressEnter = useCallback((inputPagePath: string) => {
  32. const parentPath = pathUtils.addTrailingSlash(nodePath.dirname(currentPage.path ?? ''));
  33. const newPagePath = nodePath.resolve(parentPath, inputPagePath);
  34. const onRenameFinish = () => {
  35. setRenameInputShown(false);
  36. };
  37. const onRenameFailure = () => {
  38. setRenameInputShown(true);
  39. };
  40. pagePathRenameHandler(newPagePath, onRenameFinish, onRenameFailure);
  41. }, [currentPage.path, pagePathRenameHandler, setRenameInputShown]);
  42. return (
  43. <>
  44. {isRenameInputShown ? (
  45. <div className="flex-fill">
  46. <ClosableTextInput
  47. value={inputValue}
  48. placeholder={t('Input page name')}
  49. onPressEnter={onPressEnter}
  50. onPressEscape={onPressEscape}
  51. validationTarget={ValidationTarget.PAGE}
  52. handleInputChange={onInputChange}
  53. />
  54. </div>
  55. ) : (
  56. <>{ CustomComponent }</>
  57. )}
  58. </>
  59. );
  60. };