ryosei-f 1 неделя назад
Родитель
Сommit
aafc934c4b

+ 4 - 4
packages/editor/src/client/components-internal/CodeMirrorEditor/Toolbar/AttachmentsDropup.tsx

@@ -1,4 +1,4 @@
-import { type JSX, useRef, useState } from 'react';
+import { type JSX, useId, useState } from 'react';
 import { AcceptedUploadFileType } from '@growi/core';
 import {
   Dropdown,
@@ -27,7 +27,7 @@ export const AttachmentsDropup = (props: Props): JSX.Element => {
 
   const [isOpen, setOpen] = useState(false);
 
-  const buttonRef = useRef<HTMLButtonElement>(null);
+  const id = useId();
 
   return (
     <>
@@ -38,7 +38,7 @@ export const AttachmentsDropup = (props: Props): JSX.Element => {
         className="lh-1"
       >
         <DropdownToggle
-          innerRef={buttonRef}
+          id={id}
           className={`${btnAttachmentToggleClass} btn-toolbar-button rounded-circle`}
           color="unset"
         >
@@ -79,7 +79,7 @@ export const AttachmentsDropup = (props: Props): JSX.Element => {
         </DropdownMenu>
       </Dropdown>
       {!isOpen && (
-        <UncontrolledTooltip placement="top" target={buttonRef}>
+        <UncontrolledTooltip placement="top" target={CSS.escape(id)}>
           Attachments
         </UncontrolledTooltip>
       )}

+ 4 - 4
packages/editor/src/client/components-internal/CodeMirrorEditor/Toolbar/DiagramButton.tsx

@@ -1,4 +1,4 @@
-import { type JSX, useCallback, useRef } from 'react';
+import { type JSX, useCallback, useId } from 'react';
 import { UncontrolledTooltip } from 'reactstrap';
 
 import { useDrawioModalForEditorActions } from '../../../../states/modal/drawio-for-editor';
@@ -10,7 +10,7 @@ type Props = {
 export const DiagramButton = (props: Props): JSX.Element => {
   const { editorKey } = props;
   const { open: openDrawioModal } = useDrawioModalForEditorActions();
-  const buttonRef = useRef<HTMLButtonElement>(null);
+  const id = useId();
 
   const onClickDiagramButton = useCallback(() => {
     openDrawioModal(editorKey);
@@ -19,7 +19,7 @@ export const DiagramButton = (props: Props): JSX.Element => {
   return (
     <>
       <button
-        ref={buttonRef}
+        id={id}
         type="button"
         className="btn btn-toolbar-button"
         onClick={onClickDiagramButton}
@@ -27,7 +27,7 @@ export const DiagramButton = (props: Props): JSX.Element => {
         {/* TODO: chack and fix font-size. see: https://redmine.weseek.co.jp/issues/143015 */}
         <span className="growi-custom-icons fs-6">drawer_io</span>
       </button>
-      <UncontrolledTooltip placement="top" target={buttonRef}>
+      <UncontrolledTooltip placement="top" target={CSS.escape(id)}>
         Diagram
       </UncontrolledTooltip>
     </>

+ 4 - 4
packages/editor/src/client/components-internal/CodeMirrorEditor/Toolbar/EmojiButton.tsx

@@ -4,7 +4,7 @@ import {
   type JSX,
   useCallback,
   useEffect,
-  useRef,
+  useId,
   useState,
 } from 'react';
 import { Modal, UncontrolledTooltip } from 'reactstrap';
@@ -25,7 +25,7 @@ type Props = {
 export const EmojiButton = (props: Props): JSX.Element => {
   const { editorKey } = props;
 
-  const buttonRef = useRef<HTMLButtonElement>(null);
+  const id = useId();
 
   const [isOpen, setIsOpen] = useState(false);
   const [Picker, setPicker] = useState<ComponentType<PickerProps> | null>(null);
@@ -93,14 +93,14 @@ export const EmojiButton = (props: Props): JSX.Element => {
   return (
     <>
       <button
-        ref={buttonRef}
+        id={id}
         type="button"
         className="btn btn-toolbar-button"
         onClick={toggle}
       >
         <span className="material-symbols-outlined fs-5">emoji_emotions</span>
       </button>
-      <UncontrolledTooltip placement="top" target={buttonRef}>
+      <UncontrolledTooltip placement="top" target={CSS.escape(id)}>
         Emoji
       </UncontrolledTooltip>
       {isOpen && Picker != null && emojiData != null && (

+ 4 - 4
packages/editor/src/client/components-internal/CodeMirrorEditor/Toolbar/TableButton.tsx

@@ -1,4 +1,4 @@
-import { type JSX, useCallback, useRef } from 'react';
+import { type JSX, useCallback, useId } from 'react';
 import { UncontrolledTooltip } from 'reactstrap';
 
 import { useHandsontableModalForEditorActions } from '../../../../states/modal/handsontable';
@@ -11,7 +11,7 @@ type Props = {
 export const TableButton = (props: Props): JSX.Element => {
   const { editorKey } = props;
 
-  const buttonRef = useRef<HTMLButtonElement>(null);
+  const id = useId();
 
   const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(editorKey);
   const { open: openTableModal } = useHandsontableModalForEditorActions();
@@ -23,14 +23,14 @@ export const TableButton = (props: Props): JSX.Element => {
   return (
     <>
       <button
-        ref={buttonRef}
+        id={id}
         type="button"
         className="btn btn-toolbar-button"
         onClick={onClickTableButton}
       >
         <span className="material-symbols-outlined fs-5">table</span>
       </button>
-      <UncontrolledTooltip placement="top" target={buttonRef}>
+      <UncontrolledTooltip placement="top" target={CSS.escape(id)}>
         Table
       </UncontrolledTooltip>
     </>

+ 4 - 4
packages/editor/src/client/components-internal/CodeMirrorEditor/Toolbar/TemplateButton.tsx

@@ -1,4 +1,4 @@
-import { type JSX, useCallback, useRef } from 'react';
+import { type JSX, useCallback, useId } from 'react';
 import { UncontrolledTooltip } from 'reactstrap';
 
 import { useTemplateModalActions } from '../../../../states/modal/template';
@@ -11,7 +11,7 @@ type Props = {
 export const TemplateButton = (props: Props): JSX.Element => {
   const { editorKey } = props;
 
-  const buttonRef = useRef<HTMLButtonElement>(null);
+  const id = useId();
 
   const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(editorKey);
   const { open: openTemplateModal } = useTemplateModalActions();
@@ -29,7 +29,7 @@ export const TemplateButton = (props: Props): JSX.Element => {
   return (
     <>
       <button
-        ref={buttonRef}
+        id={id}
         type="button"
         className="btn btn-toolbar-button"
         onClick={onClickTempleteButton}
@@ -37,7 +37,7 @@ export const TemplateButton = (props: Props): JSX.Element => {
       >
         <span className="material-symbols-outlined fs-5">file_copy</span>
       </button>
-      <UncontrolledTooltip placement="top" target={buttonRef}>
+      <UncontrolledTooltip placement="top" target={CSS.escape(id)}>
         Template
       </UncontrolledTooltip>
     </>

+ 50 - 32
packages/editor/src/client/components-internal/CodeMirrorEditor/Toolbar/TextFormatTools.tsx

@@ -1,4 +1,4 @@
-import { type JSX, useCallback, useRef, useState } from 'react';
+import { type JSX, useCallback, useId, useState } from 'react';
 import { Collapse, UncontrolledTooltip } from 'reactstrap';
 
 import type { GlobalCodeMirrorEditorKey } from '../../../../consts';
@@ -16,20 +16,20 @@ type TogglarProps = {
 const TextFormatToolsToggler = (props: TogglarProps): JSX.Element => {
   const { isOpen, onClick } = props;
 
-  const buttonRef = useRef<HTMLButtonElement>(null);
+  const id = useId();
   const activeClass = isOpen ? 'active' : '';
 
   return (
     <>
       <button
-        ref={buttonRef}
+        id={id}
         type="button"
         className={`btn btn-toolbar-button ${btnTextFormatToolsTogglerClass} ${activeClass}`}
         onClick={onClick}
       >
         <span className="material-symbols-outlined fs-3">match_case</span>
       </button>
-      <UncontrolledTooltip placement="top" target={buttonRef}>
+      <UncontrolledTooltip placement="top" target={CSS.escape(id)}>
         Text Formatting
       </UncontrolledTooltip>
     </>
@@ -44,18 +44,9 @@ type TextFormatToolsType = {
 export const TextFormatTools = (props: TextFormatToolsType): JSX.Element => {
   const { editorKey, onTextFormatToolsCollapseChange } = props;
   const [isOpen, setOpen] = useState(false);
+  const baseId = useId();
   const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(editorKey);
 
-  const boldRef = useRef<HTMLButtonElement>(null);
-  const italicRef = useRef<HTMLButtonElement>(null);
-  const strikethroughRef = useRef<HTMLButtonElement>(null);
-  const headingRef = useRef<HTMLButtonElement>(null);
-  const codeRef = useRef<HTMLButtonElement>(null);
-  const bulletListRef = useRef<HTMLButtonElement>(null);
-  const numberedListRef = useRef<HTMLButtonElement>(null);
-  const quoteRef = useRef<HTMLButtonElement>(null);
-  const checklistRef = useRef<HTMLButtonElement>(null);
-
   const toggle = useCallback(() => {
     setOpen((bool) => !bool);
   }, []);
@@ -83,18 +74,21 @@ export const TextFormatTools = (props: TextFormatToolsType): JSX.Element => {
       >
         <div className="d-flex px-1 gap-1" style={{ width: '220px' }}>
           <button
-            ref={boldRef}
+            id={`${baseId}-bold`}
             type="button"
             className="btn btn-toolbar-button"
             onClick={() => onClickInsertMarkdownElements('**', '**')}
           >
             <span className="material-symbols-outlined fs-5">format_bold</span>
           </button>
-          <UncontrolledTooltip placement="top" target={boldRef}>
+          <UncontrolledTooltip
+            placement="top"
+            target={CSS.escape(`${baseId}-bold`)}
+          >
             Bold
           </UncontrolledTooltip>
           <button
-            ref={italicRef}
+            id={`${baseId}-italic`}
             type="button"
             className="btn btn-toolbar-button"
             onClick={() => onClickInsertMarkdownElements('*', '*')}
@@ -103,11 +97,14 @@ export const TextFormatTools = (props: TextFormatToolsType): JSX.Element => {
               format_italic
             </span>
           </button>
-          <UncontrolledTooltip placement="top" target={italicRef}>
+          <UncontrolledTooltip
+            placement="top"
+            target={CSS.escape(`${baseId}-italic`)}
+          >
             Italic
           </UncontrolledTooltip>
           <button
-            ref={strikethroughRef}
+            id={`${baseId}-strikethrough`}
             type="button"
             className="btn btn-toolbar-button"
             onClick={() => onClickInsertMarkdownElements('~', '~')}
@@ -116,11 +113,14 @@ export const TextFormatTools = (props: TextFormatToolsType): JSX.Element => {
               format_strikethrough
             </span>
           </button>
-          <UncontrolledTooltip placement="top" target={strikethroughRef}>
+          <UncontrolledTooltip
+            placement="top"
+            target={CSS.escape(`${baseId}-strikethrough`)}
+          >
             Strikethrough
           </UncontrolledTooltip>
           <button
-            ref={headingRef}
+            id={`${baseId}-heading`}
             type="button"
             className="btn btn-toolbar-button"
             onClick={() => onClickInsertPrefix('#', true)}
@@ -128,22 +128,28 @@ export const TextFormatTools = (props: TextFormatToolsType): JSX.Element => {
             {/* TODO: chack and fix font-size. see: https://redmine.weseek.co.jp/issues/143015 */}
             <span className="growi-custom-icons">header</span>
           </button>
-          <UncontrolledTooltip placement="top" target={headingRef}>
+          <UncontrolledTooltip
+            placement="top"
+            target={CSS.escape(`${baseId}-heading`)}
+          >
             Heading
           </UncontrolledTooltip>
           <button
-            ref={codeRef}
+            id={`${baseId}-code`}
             type="button"
             className="btn btn-toolbar-button"
             onClick={() => onClickInsertMarkdownElements('`', '`')}
           >
             <span className="material-symbols-outlined fs-5">code</span>
           </button>
-          <UncontrolledTooltip placement="top" target={codeRef}>
+          <UncontrolledTooltip
+            placement="top"
+            target={CSS.escape(`${baseId}-code`)}
+          >
             Code
           </UncontrolledTooltip>
           <button
-            ref={bulletListRef}
+            id={`${baseId}-bullet-list`}
             type="button"
             className="btn btn-toolbar-button"
             onClick={() => onClickInsertPrefix('-')}
@@ -152,11 +158,14 @@ export const TextFormatTools = (props: TextFormatToolsType): JSX.Element => {
               format_list_bulleted
             </span>
           </button>
-          <UncontrolledTooltip placement="top" target={bulletListRef}>
+          <UncontrolledTooltip
+            placement="top"
+            target={CSS.escape(`${baseId}-bullet-list`)}
+          >
             Bullet List
           </UncontrolledTooltip>
           <button
-            ref={numberedListRef}
+            id={`${baseId}-numbered-list`}
             type="button"
             className="btn btn-toolbar-button"
             onClick={() => onClickInsertPrefix('1.')}
@@ -165,11 +174,14 @@ export const TextFormatTools = (props: TextFormatToolsType): JSX.Element => {
               format_list_numbered
             </span>
           </button>
-          <UncontrolledTooltip placement="top" target={numberedListRef}>
+          <UncontrolledTooltip
+            placement="top"
+            target={CSS.escape(`${baseId}-numbered-list`)}
+          >
             Numbered List
           </UncontrolledTooltip>
           <button
-            ref={quoteRef}
+            id={`${baseId}-quote`}
             type="button"
             className="btn btn-toolbar-button"
             onClick={() => onClickInsertPrefix('>')}
@@ -177,18 +189,24 @@ export const TextFormatTools = (props: TextFormatToolsType): JSX.Element => {
             {/* TODO: chack and fix font-size. see: https://redmine.weseek.co.jp/issues/143015 */}
             <span className="growi-custom-icons">format_quote</span>
           </button>
-          <UncontrolledTooltip placement="top" target={quoteRef}>
+          <UncontrolledTooltip
+            placement="top"
+            target={CSS.escape(`${baseId}-quote`)}
+          >
             Quote
           </UncontrolledTooltip>
           <button
-            ref={checklistRef}
+            id={`${baseId}-checklist`}
             type="button"
             className="btn btn-toolbar-button"
             onClick={() => onClickInsertPrefix('- [ ]')}
           >
             <span className="material-symbols-outlined fs-5">checklist</span>
           </button>
-          <UncontrolledTooltip placement="top" target={checklistRef}>
+          <UncontrolledTooltip
+            placement="top"
+            target={CSS.escape(`${baseId}-checklist`)}
+          >
             Checklist
           </UncontrolledTooltip>
         </div>