Parcourir la source

feat: add mouse down handler to prevent input blur and implement rapid click guard

Yuki Takei il y a 4 mois
Parent
commit
1ba3429a26

+ 7 - 0
apps/app/src/features/page-tree/hooks/use-page-create.tsx

@@ -42,6 +42,12 @@ const CreateButtonInner: FC<CreateButtonInnerProps> = ({
     return null;
     return null;
   }
   }
 
 
+  const handleMouseDown = (e: React.MouseEvent) => {
+    // Prevent focus change which would trigger blur on the input field
+    // and cause cancelCreating to be called
+    e.preventDefault();
+  };
+
   const handleClick = (e: React.MouseEvent) => {
   const handleClick = (e: React.MouseEvent) => {
     // Always stop propagation to prevent parent item click handlers
     // Always stop propagation to prevent parent item click handlers
     e.stopPropagation();
     e.stopPropagation();
@@ -59,6 +65,7 @@ const CreateButtonInner: FC<CreateButtonInnerProps> = ({
           id={`page-create-button-in-page-tree-${buttonId}`}
           id={`page-create-button-in-page-tree-${buttonId}`}
           type="button"
           type="button"
           className="border-0 rounded btn btn-page-item-control p-0"
           className="border-0 rounded btn btn-page-item-control p-0"
+          onMouseDown={handleMouseDown}
           onClick={handleClick}
           onClick={handleClick}
         >
         >
           <span className="material-symbols-outlined p-0">add_circle</span>
           <span className="material-symbols-outlined p-0">add_circle</span>

+ 11 - 0
apps/app/src/features/page-tree/states/_inner/page-tree-create.ts

@@ -32,6 +32,10 @@ type CreatingParentInfo = {
 
 
 const creatingParentInfoAtom = atom<CreatingParentInfo>(null);
 const creatingParentInfoAtom = atom<CreatingParentInfo>(null);
 
 
+// Module-level flag for synchronous guard against rapid clicks
+// This is shared across all hook instances
+let isCreatingFlag = false;
+
 /**
 /**
  * Hook to get the current creating parent ID
  * Hook to get the current creating parent ID
  */
  */
@@ -75,12 +79,19 @@ export const usePageTreeCreateActions = (): PageTreeCreateActions => {
 
 
   const startCreating = useCallback(
   const startCreating = useCallback(
     (parentId: string, parentPath: string) => {
     (parentId: string, parentPath: string) => {
+      // Synchronous check to prevent rapid clicks
+      // Uses module-level flag shared across all hook instances
+      if (isCreatingFlag) {
+        return;
+      }
+      isCreatingFlag = true;
       setCreatingParentInfo({ id: parentId, path: parentPath });
       setCreatingParentInfo({ id: parentId, path: parentPath });
     },
     },
     [setCreatingParentInfo],
     [setCreatingParentInfo],
   );
   );
 
 
   const cancelCreating = useCallback(() => {
   const cancelCreating = useCallback(() => {
+    isCreatingFlag = false;
     setCreatingParentInfo(null);
     setCreatingParentInfo(null);
   }, [setCreatingParentInfo]);
   }, [setCreatingParentInfo]);