import type { ChangeEvent } from 'react'; import { useState, useCallback, useEffect } from 'react'; import nodePath from 'path'; import type { IPagePopulatedToShowRevision } from '@growi/core'; import { DevidedPagePath } from '@growi/core/dist/models'; import { pathUtils } from '@growi/core/dist/utils'; import { isMovablePage } from '@growi/core/dist/utils/page-path-utils'; import { useTranslation } from 'next-i18next'; import type { InputValidationResult } from '~/client/util/use-input-validator'; import { ValidationTarget, useInputValidator } from '~/client/util/use-input-validator'; import { EditorMode, useEditorMode, useIsUntitledPage } from '~/stores/ui'; import { CopyDropdown } from '../Common/CopyDropdown'; import { AutosizeSubmittableInput, getAdjustedMaxWidthForAutosizeInput } from '../Common/SubmittableInput'; import { usePagePathRenameHandler } from '../PageEditor/page-path-rename-utils'; import styles from './PageTitleHeader.module.scss'; const moduleClass = styles['page-title-header'] ?? ''; const borderColorClass = styles['page-title-header-border-color'] ?? ''; type Props = { currentPage: IPagePopulatedToShowRevision, className?: string, maxWidth?: number, onMoveTerminated?: () => void, }; export const PageTitleHeader = (props: Props): JSX.Element => { const { t } = useTranslation(); const { currentPage, maxWidth, onMoveTerminated } = props; const currentPagePath = currentPage.path; const isMovable = isMovablePage(currentPagePath); const dPagePath = new DevidedPagePath(currentPage.path, true); const pageTitle = dPagePath.latter; const [isRenameInputShown, setRenameInputShown] = useState(false); const [editedPagePath, setEditedPagePath] = useState(currentPagePath); const [validationResult, setValidationResult] = useState(); const pagePathRenameHandler = usePagePathRenameHandler(currentPage); const inputValidator = useInputValidator(ValidationTarget.PAGE); const editedPageTitle = nodePath.basename(editedPagePath); const { data: editorMode } = useEditorMode(); const { data: isUntitledPage } = useIsUntitledPage(); const changeHandler = useCallback(async(e: ChangeEvent) => { const newPageTitle = pathUtils.removeHeadingSlash(e.target.value); const parentPagePath = pathUtils.addTrailingSlash(nodePath.dirname(currentPage.path)); const newPagePath = nodePath.resolve(parentPagePath, newPageTitle); setEditedPagePath(newPagePath); // validation const validationResult = inputValidator(e.target.value); setValidationResult(validationResult ?? undefined); }, [currentPage.path, inputValidator]); const rename = useCallback(() => { pagePathRenameHandler(editedPagePath, () => { setRenameInputShown(false); setValidationResult(undefined); onMoveTerminated?.(); }, () => { setRenameInputShown(true); }); }, [editedPagePath, onMoveTerminated, pagePathRenameHandler]); const cancel = useCallback(() => { setEditedPagePath(currentPagePath); setValidationResult(undefined); setRenameInputShown(false); }, [currentPagePath]); const onClickPageTitle = useCallback(() => { if (!isMovable) { return; } setEditedPagePath(currentPagePath); setRenameInputShown(true); }, [currentPagePath, isMovable]); useEffect(() => { setEditedPagePath(currentPagePath); if (isUntitledPage && editorMode === EditorMode.Editor) { setRenameInputShown(true); } }, [currentPage._id, currentPagePath, editorMode, isUntitledPage]); const isInvalid = validationResult != null; const inputMaxWidth = maxWidth != null ? getAdjustedMaxWidthForAutosizeInput(maxWidth, 'md', validationResult != null ? false : undefined) - 16 : undefined; return (
{ isRenameInputShown && (
) }

{pageTitle}

{ currentPage.wip && ( WIP )} content_paste
); };