PageEditorModeManager.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import React, { type ReactNode, useCallback, useState } from 'react';
  2. import type { IGrantedGroup } from '@growi/core';
  3. import { useTranslation } from 'next-i18next';
  4. import { EditorMode, useIsDeviceLargerThanMd } from '~/stores/ui';
  5. import { useOnPageEditorModeButtonClicked } from './hooks';
  6. import styles from './PageEditorModeManager.module.scss';
  7. type PageEditorModeButtonProps = {
  8. currentEditorMode: EditorMode,
  9. editorMode: EditorMode,
  10. children?: ReactNode,
  11. isBtnDisabled?: boolean,
  12. onClick?: (mode: EditorMode) => void,
  13. }
  14. const PageEditorModeButton = React.memo((props: PageEditorModeButtonProps) => {
  15. const {
  16. currentEditorMode, isBtnDisabled, editorMode, children, onClick,
  17. } = props;
  18. const classNames = ['btn py-1 px-2 d-flex align-items-center justify-content-center'];
  19. if (currentEditorMode === editorMode) {
  20. classNames.push('active');
  21. }
  22. if (isBtnDisabled) {
  23. classNames.push('disabled');
  24. }
  25. return (
  26. <button
  27. type="button"
  28. className={classNames.join(' ')}
  29. onClick={() => onClick?.(editorMode)}
  30. data-testid={`${editorMode}-button`}
  31. >
  32. {children}
  33. </button>
  34. );
  35. });
  36. type Props = {
  37. editorMode: EditorMode | undefined,
  38. isBtnDisabled: boolean,
  39. path?: string,
  40. grant?: number,
  41. // grantUserGroupId?: string
  42. grantUserGroupIds?: IGrantedGroup[]
  43. }
  44. export const PageEditorModeManager = (props: Props): JSX.Element => {
  45. const {
  46. editorMode = EditorMode.View,
  47. isBtnDisabled,
  48. path,
  49. // grant,
  50. // grantUserGroupId,
  51. } = props;
  52. const { t } = useTranslation();
  53. const [isCreating, setIsCreating] = useState(false);
  54. const { data: isDeviceLargerThanMd } = useIsDeviceLargerThanMd();
  55. const onPageEditorModeButtonClicked = useOnPageEditorModeButtonClicked(setIsCreating, path);
  56. const _isBtnDisabled = isCreating || isBtnDisabled;
  57. const pageEditorModeButtonClickedHandler = useCallback((viewType: EditorMode) => {
  58. if (_isBtnDisabled) {
  59. return;
  60. }
  61. onPageEditorModeButtonClicked?.(viewType);
  62. }, [_isBtnDisabled, onPageEditorModeButtonClicked]);
  63. return (
  64. <>
  65. <div
  66. className={`btn-group grw-page-editor-mode-manager ${styles['grw-page-editor-mode-manager']}`}
  67. role="group"
  68. aria-label="page-editor-mode-manager"
  69. id="grw-page-editor-mode-manager"
  70. >
  71. {(isDeviceLargerThanMd || editorMode !== EditorMode.View) && (
  72. <PageEditorModeButton
  73. currentEditorMode={editorMode}
  74. editorMode={EditorMode.View}
  75. isBtnDisabled={_isBtnDisabled}
  76. onClick={pageEditorModeButtonClickedHandler}
  77. >
  78. <span className="material-symbols-outlined fs-4">play_arrow</span>{t('View')}
  79. </PageEditorModeButton>
  80. )}
  81. {(isDeviceLargerThanMd || editorMode === EditorMode.View) && (
  82. <PageEditorModeButton
  83. currentEditorMode={editorMode}
  84. editorMode={EditorMode.Editor}
  85. isBtnDisabled={_isBtnDisabled}
  86. onClick={pageEditorModeButtonClickedHandler}
  87. >
  88. <span className="material-symbols-outlined me-1 fs-5">edit_square</span>{t('Edit')}
  89. </PageEditorModeButton>
  90. )}
  91. </div>
  92. </>
  93. );
  94. };