Просмотр исходного кода

fix non-autofixable biome errors

Futa Arai 3 месяцев назад
Родитель
Сommit
3d23bfbb33

+ 3 - 1
apps/app/src/client/components/Hotkeys/HotkeysManager.jsx

@@ -27,7 +27,9 @@ SUPPORTED_COMPONENTS.forEach((comp) => {
 
   strokes.forEach((stroke) => {
     // register key
-    stroke.forEach((key) => KEY_SET.add(key));
+    stroke.forEach((key) => {
+      KEY_SET.add(key);
+    });
     // register stroke
     STROKE_SET.add(stroke);
     // register component

+ 16 - 11
apps/app/src/client/components/Navbar/GrowiNavbarBottom.tsx

@@ -30,43 +30,48 @@ export const GrowiNavbarBottom = (): JSX.Element => {
       <div className="navbar navbar-expand px-4 px-sm-5">
         <ul className="navbar-nav flex-grow-1 d-flex align-items-center justify-content-between">
           <li className="nav-item">
-            <a
-              role="button"
+            <button
+              type="button"
               className="nav-link btn-lg"
               onClick={() => setIsDrawerOpened(true)}
             >
               <span className="material-symbols-outlined fs-2">reorder</span>
-            </a>
+            </button>
           </li>
 
           <li className="nav-item">
-            <a
-              role="button"
+            <button
+              type="button"
               className="nav-link btn-lg"
               onClick={() => openCreateModal(currentPagePath || '')}
             >
               <span className="material-symbols-outlined fs-2">edit</span>
-            </a>
+            </button>
           </li>
 
           {!isSearchPage && (
             <li className="nav-item">
-              <a
-                role="button"
+              <button
+                type="button"
                 className="nav-link btn-lg"
                 onClick={searchButtonClickHandler}
               >
                 <span className="material-symbols-outlined fs-2">search</span>
-              </a>
+              </button>
             </li>
           )}
 
           <li className="nav-item">
-            <a role="button" className="nav-link btn-lg" onClick={() => {}}>
+            <button
+              type="button"
+              className="nav-link btn-lg"
+              onClick={() => {}}
+              aria-label="Notifications"
+            >
               <span className="material-symbols-outlined fs-2">
                 notifications
               </span>
-            </a>
+            </button>
           </li>
         </ul>
       </div>

+ 2 - 3
apps/app/src/client/components/Navbar/PageEditorModeManager.tsx

@@ -83,9 +83,8 @@ export const PageEditorModeManager = (props: Props): JSX.Element => {
 
   return (
     <>
-      <div
+      <fieldset
         className={`btn-group grw-page-editor-mode-manager ${styles['grw-page-editor-mode-manager']}`}
-        role="group"
         aria-label="page-editor-mode-manager"
         id="grw-page-editor-mode-manager"
         data-testid="grw-page-editor-mode-manager"
@@ -119,7 +118,7 @@ export const PageEditorModeManager = (props: Props): JSX.Element => {
             )}
           </PageEditorModeButton>
         )}
-      </div>
+      </fieldset>
     </>
   );
 };

+ 1 - 0
apps/app/src/client/components/PageEditor/ConflictDiffModal/ConflictDiffModal.tsx

@@ -93,6 +93,7 @@ const ConflictDiffModalSubstance = (
   }, [codeMirrorEditor, conflictDiffModalStatus]);
 
   useEffect(() => {
+    void revisionSelectedToggler;
     codeMirrorEditor?.initDoc(resolvedRevision);
     // Enable selecting the same revision after editing by including revisionSelectedToggler in the dependency array of useEffect
   }, [codeMirrorEditor, resolvedRevision, revisionSelectedToggler]);

+ 2 - 1
apps/app/src/client/components/PageEditor/DrawioModal/DrawioModal.tsx

@@ -84,7 +84,7 @@ const DrawioModalSubstance = (): JSX.Element => {
       return undefined;
     }
 
-    let url;
+    let url: URL;
     try {
       url = new URL(drawioUri);
     } catch (err) {
@@ -192,6 +192,7 @@ const DrawioModalSubstance = (): JSX.Element => {
               <iframe
                 src={drawioUriWithParams.href}
                 className="border-0 flex-grow-1"
+                title="Draw.io editor"
               ></iframe>
             )}
           </div>

+ 3 - 3
apps/app/src/client/components/PageEditor/EditorNavbarBottom/EditorNavbarBottom.tsx

@@ -29,13 +29,13 @@ export const EditorNavbarBottom = (): JSX.Element => {
       <div
         className={`flex-expand-horiz align-items-center p-2 ps-md-3 pe-md-4 ${moduleClass}`}
       >
-        <a
-          role="button"
+        <button
+          type="button"
           className="nav-link btn-lg p-2 d-md-none me-3 opacity-50"
           onClick={() => setIsDrawerOpened(true)}
         >
           <span className="material-symbols-outlined fs-2">reorder</span>
-        </a>
+        </button>
         <form className="me-auto d-flex gap-2">
           <OptionsSelector />
           {isAiEnabled && <EditorAssistantToggleButton />}

+ 10 - 4
apps/app/src/client/components/PageEditor/EditorNavbarBottom/GrantSelector.tsx

@@ -1,4 +1,10 @@
-import React, { type JSX, useCallback, useEffect, useState } from 'react';
+import React, {
+  type JSX,
+  type ReactNode,
+  useCallback,
+  useEffect,
+  useState,
+} from 'react';
 import { GroupType, getIdForRef, PageGrant } from '@growi/core';
 import { LoadingSpinner } from '@growi/ui/dist/components';
 import { useTranslation } from 'next-i18next';
@@ -153,8 +159,8 @@ export const GrantSelector = (props: Props): JSX.Element => {
    * Render grant selector DOM.
    */
   const renderGrantSelector = useCallback(() => {
-    let dropdownToggleBtnColor;
-    let dropdownToggleLabelElm;
+    let dropdownToggleBtnColor: string | undefined;
+    let dropdownToggleLabelElm: ReactNode | undefined;
 
     const userRelatedGrantedGroups =
       groupGrantData?.userRelatedGroups.filter((group) => {
@@ -377,7 +383,7 @@ export const GrantSelector = (props: Props): JSX.Element => {
         <span className="material-symbols-outlined">close</span>
       </button>
     );
-  }, [setIsSelectGroupModalShown]);
+  }, []);
 
   return (
     <>

+ 11 - 7
apps/app/src/client/components/PageEditor/EditorNavbarBottom/OptionsSelector.tsx

@@ -75,7 +75,7 @@ const Selector = (props: SelectorProps): JSX.Element => {
         <span className="material-symbols-outlined fs-5 py-0 me-1">
           navigate_before
         </span>
-        <label>{header}</label>
+        <span>{header}</span>
       </button>
       <hr className="my-1" />
       <ul className="list-group d-flex ms-2">{items}</ul>
@@ -114,6 +114,7 @@ const ThemeSelector = memo(
               const themeLabel = EDITORTHEME_LABEL_MAP[theme];
               return (
                 <RadioListItem
+                  key={theme}
                   onClick={() => update({ theme })}
                   text={themeLabel}
                   checked={theme === selectedTheme}
@@ -171,6 +172,7 @@ const KeymapSelector = memo(
               ) : null;
             return (
               <RadioListItem
+                key={keymapMode}
                 onClick={() => update({ keymapMode })}
                 icon={icon}
                 text={keymapLabel}
@@ -208,6 +210,7 @@ const IndentSizeSelector = memo(
           {TYPICAL_INDENT_SIZE.map((indent) => {
             return (
               <RadioListItem
+                key={indent}
                 onClick={() => mutateCurrentIndentSize(indent)}
                 text={indent.toString()}
                 checked={indent === currentIndentSize}
@@ -242,6 +245,7 @@ const PasteSelector = memo(
           {AllPasteMode.map((pasteMode) => {
             return (
               <RadioListItem
+                key={pasteMode}
                 onClick={() => update({ pasteMode })}
                 text={t(`page_edit.paste.${pasteMode}`) ?? ''}
                 checked={pasteMode === selectedPasteMode}
@@ -343,13 +347,13 @@ const ChangeStateButton = memo((props: ChangeStateButtonProps): JSX.Element => {
       disabled={disabled}
       onClick={onClick}
     >
-      <label className="ms-2 me-auto">{header}</label>
-      <label className="text-muted d-flex align-items-center ms-2 me-1">
+      <span className="ms-2 me-auto">{header}</span>
+      <span className="text-muted d-flex align-items-center ms-2 me-1">
         {data}
         <span className="material-symbols-outlined fs-5 py-0">
           navigate_next
         </span>
-      </label>
+      </span>
     </button>
   );
 });
@@ -400,7 +404,7 @@ export const OptionsSelector = (): JSX.Element => {
       >
         <span className="material-symbols-outlined py-0 fs-5"> settings </span>
         {isDeviceLargerThanMd ? (
-          <label className="ms-1 me-1">{t('page_edit.editor_config')}</label>
+          <span className="ms-1 me-1">{t('page_edit.editor_config')}</span>
         ) : (
           <></>
         )}
@@ -408,9 +412,9 @@ export const OptionsSelector = (): JSX.Element => {
       <DropdownMenu container="body">
         {status === OptionsStatus.Home && (
           <div className="d-flex flex-column">
-            <label className="text-muted ms-3">
+            <span className="text-muted ms-3">
               {t('page_edit.editor_config')}
-            </label>
+            </span>
             <hr className="my-1" />
             <ChangeStateButton
               onClick={() => setStatus(OptionsStatus.Theme)}

+ 1 - 1
apps/app/src/client/components/PageEditor/EditorNavbarBottom/SavePageControls.tsx

@@ -191,7 +191,7 @@ const SavePageButton = (props: {
                   className="btn btn-outline-neutral-secondary mx-auto mt-1"
                   onClick={() => setIsSavePageModalShown(false)}
                 >
-                  <label className="mx-2">{t('Cancel')}</label>
+                  <span className="mx-2">{t('Cancel')}</span>
                 </button>
               </div>
             </Modal>

+ 1 - 0
apps/app/src/client/components/PageEditor/GridEditModal.jsx

@@ -240,6 +240,7 @@ class GridEditModal extends React.Component {
                     </button>
                     <div
                       className="dropdown-menu grid-division-menu"
+                      role="menu"
                       aria-labelledby="dropdownMenuButton"
                     >
                       {this.renderGridDivisionMenu()}

+ 2 - 2
apps/app/src/client/components/PageEditor/HandsontableModal/HandsontableModal.tsx

@@ -523,7 +523,7 @@ const HandsontableModalSubstance = (
               {isDataImportAreaExpanded ? 'expand_less' : 'expand_more'}
             </span>
           </button>
-          <div role="group" className="btn-group">
+          <fieldset className="btn-group border-0 m-0 p-0">
             <button
               type="button"
               className="btn btn-outline-neutral-secondary"
@@ -557,7 +557,7 @@ const HandsontableModalSubstance = (
                 format_align_right
               </span>
             </button>
-          </div>
+          </fieldset>
           <Collapse isOpen={isDataImportAreaExpanded}>
             <div className="py-3 border-bottom">
               <MarkdownTableDataImportForm

+ 4 - 4
apps/app/src/client/components/PageEditor/LinkEditModal/LinkEditModal.tsx

@@ -74,9 +74,9 @@ const LinkEditModalSubstance: React.FC = () => {
       // ex-2. link = 'hoge' -> url = 'http://example.com/hoge' (case-2,3,5)
       let isFqcn = false;
       let isUseRelativePath = false;
-      let url;
+      let url: URL | undefined;
       try {
-        const url = new URL(link, 'http://example.com');
+        url = new URL(link, 'http://example.com');
         isFqcn = url.origin !== 'http://example.com';
       } catch (err) {
         logger.debug(err);
@@ -357,9 +357,9 @@ const LinkEditModalSubstance: React.FC = () => {
       <div className="card custom-card pt-3">
         <form className="mb-0">
           <div className="mb-0 row">
-            <label className="form-label col-sm-3">
+            <span className="form-label col-sm-3">
               {t('link_edit.path_format')}
-            </label>
+            </span>
             <div className="col-sm-9">
               <div className="form-check form-check-info form-check-inline">
                 <input

+ 3 - 1
apps/app/src/client/components/PageEditor/MarkdownTableDataImportForm.tsx

@@ -22,7 +22,7 @@ export const MarkdownTableDataImportForm = (
   const [parserErrorMessage, setParserErrorMessage] = useState(null);
 
   const convertFormDataToMarkdownTable = () => {
-    let result;
+    let result: MarkdownTable;
     switch (dataFormat) {
       case 'csv':
         result = MarkdownTable.fromDSV(data, ',');
@@ -33,6 +33,8 @@ export const MarkdownTableDataImportForm = (
       case 'html':
         result = MarkdownTable.fromHTMLTableTag(data);
         break;
+      default:
+        throw new Error(`Unsupported format: ${dataFormat}`);
     }
     return result.normalizeCells();
   };

+ 2 - 2
apps/app/src/client/components/PageEditor/ScrollSyncHelper.tsx

@@ -234,7 +234,7 @@ export const useScrollSync = (
 
     isOriginOfScrollSyncEditor.current = true;
     scrollEditor(codeMirrorEditor.view.scrollDOM, previewRef.current);
-  }, [codeMirrorEditor, isOriginOfScrollSyncPreview, previewRef]);
+  }, [codeMirrorEditor, previewRef]);
 
   const scrollPreviewHandler = useCallback(() => {
     if (
@@ -251,7 +251,7 @@ export const useScrollSync = (
 
     isOriginOfScrollSyncPreview.current = true;
     scrollPreview(codeMirrorEditor.view.scrollDOM, previewRef.current);
-  }, [codeMirrorEditor, isOriginOfScrollSyncEditor, previewRef]);
+  }, [codeMirrorEditor, previewRef]);
 
   return { scrollEditorHandler, scrollPreviewHandler };
 };

+ 3 - 3
apps/app/src/client/components/PageEditor/markdown-table-util-for-editor.ts

@@ -105,9 +105,9 @@ export const isEndOfLine = (editor: EditorView): boolean => {
 export const addRowToMarkdownTable = (mdtable: MarkdownTable): any => {
   const numCol = mdtable.table.length > 0 ? mdtable.table[0].length : 1;
   const newRow: string[] = [];
-  new Array(numCol).forEach(() => {
-    return newRow.push('');
-  }); // create cols
+  for (let index = 0; index < numCol; index += 1) {
+    newRow.push('');
+  } // create cols
   mdtable.table.push(newRow);
 };
 

+ 6 - 3
apps/app/src/client/components/PageHeader/PagePathHeader.tsx

@@ -129,11 +129,14 @@ export const PagePathHeader = memo((props: Props): JSX.Element => {
       : undefined;
 
   return (
-    <div
+    <fieldset
       id="page-path-header"
-      className={`d-flex ${moduleClass} ${className ?? ''} small position-relative ms-2`}
+      className={`d-flex ${moduleClass} ${className ?? ''} small position-relative ms-2 border-0 p-0 m-0`}
+      aria-label="Page path header"
       onMouseEnter={() => setHover(true)}
       onMouseLeave={() => setHover(false)}
+      onFocus={() => setHover(true)}
+      onBlur={() => setHover(false)}
     >
       <div
         className="page-path-header-input d-inline-block"
@@ -181,6 +184,6 @@ export const PagePathHeader = memo((props: Props): JSX.Element => {
           <span className="material-symbols-outlined fs-6">account_tree</span>
         </button>
       </div>
-    </div>
+    </fieldset>
   );
 });

+ 19 - 2
apps/app/src/client/components/PageHeader/PageTitleHeader.tsx

@@ -1,4 +1,4 @@
-import type { ChangeEvent, JSX } from 'react';
+import type { ChangeEvent, JSX, KeyboardEvent } from 'react';
 import { useCallback, useEffect, useMemo, useState } from 'react';
 import type { IPagePopulatedToShowRevision } from '@growi/core';
 import { DevidedPagePath } from '@growi/core/dist/models';
@@ -104,12 +104,26 @@ export const PageTitleHeader = (props: Props): JSX.Element => {
     setRenameInputShown(true);
   }, [currentPagePath, isMovable]);
 
+  const onKeyDownPageTitle = useCallback(
+    (event: KeyboardEvent<HTMLHeadingElement>) => {
+      if (!isMovable) {
+        return;
+      }
+
+      if (event.key === 'Enter' || event.key === ' ') {
+        event.preventDefault();
+        onClickPageTitle();
+      }
+    },
+    [isMovable, onClickPageTitle],
+  );
+
   useEffect(() => {
     setEditedPagePath(currentPagePath);
     if (isUntitledPage != null) {
       setRenameInputShown(isUntitledPage && editorMode === EditorMode.Editor);
     }
-  }, [currentPage._id, currentPagePath, editorMode, isUntitledPage]);
+  }, [currentPagePath, editorMode, isUntitledPage]);
 
   const isInvalid = validationResult != null;
 
@@ -170,6 +184,9 @@ export const PageTitleHeader = (props: Props): JSX.Element => {
           `}
           style={{ maxWidth: h1MaxWidth }}
           onClick={onClickPageTitle}
+          onKeyDown={onKeyDownPageTitle}
+          role={isMovable ? 'button' : undefined}
+          tabIndex={isMovable ? 0 : -1}
         >
           {pageTitle}
         </h1>