Преглед изворни кода

fix: `excalidrawAPI.toggleSidebar` not switching between tabs correctly (#7821)

David Luzar пре 1 година
родитељ
комит
65bc500598

+ 15 - 3
packages/excalidraw/components/App.tsx

@@ -3684,17 +3684,29 @@ class App extends React.Component<AppProps, AppState> {
     tab,
     tab,
     force,
     force,
   }: {
   }: {
-    name: SidebarName;
+    name: SidebarName | null;
     tab?: SidebarTabName;
     tab?: SidebarTabName;
     force?: boolean;
     force?: boolean;
   }): boolean => {
   }): boolean => {
     let nextName;
     let nextName;
     if (force === undefined) {
     if (force === undefined) {
-      nextName = this.state.openSidebar?.name === name ? null : name;
+      nextName =
+        this.state.openSidebar?.name === name &&
+        this.state.openSidebar?.tab === tab
+          ? null
+          : name;
     } else {
     } else {
       nextName = force ? name : null;
       nextName = force ? name : null;
     }
     }
-    this.setState({ openSidebar: nextName ? { name: nextName, tab } : null });
+
+    const nextState: AppState["openSidebar"] = nextName
+      ? { name: nextName }
+      : null;
+    if (nextState && tab) {
+      nextState.tab = tab;
+    }
+
+    this.setState({ openSidebar: nextState });
 
 
     return !!nextName;
     return !!nextName;
   };
   };

+ 81 - 1
packages/excalidraw/components/Sidebar/Sidebar.test.tsx

@@ -85,7 +85,7 @@ describe("Sidebar", () => {
       });
       });
     });
     });
 
 
-    it("should toggle sidebar using props.toggleMenu()", async () => {
+    it("should toggle sidebar using excalidrawAPI.toggleSidebar()", async () => {
       const { container } = await render(
       const { container } = await render(
         <Excalidraw>
         <Excalidraw>
           <Sidebar name="customSidebar">
           <Sidebar name="customSidebar">
@@ -158,6 +158,20 @@ describe("Sidebar", () => {
         const sidebars = container.querySelectorAll(".sidebar");
         const sidebars = container.querySelectorAll(".sidebar");
         expect(sidebars.length).toBe(1);
         expect(sidebars.length).toBe(1);
       });
       });
+
+      // closing sidebar using `{ name: null }`
+      // -------------------------------------------------------------------------
+      expect(window.h.app.toggleSidebar({ name: "customSidebar" })).toBe(true);
+      await waitFor(() => {
+        const node = container.querySelector("#test-sidebar-content");
+        expect(node).not.toBe(null);
+      });
+
+      expect(window.h.app.toggleSidebar({ name: null })).toBe(false);
+      await waitFor(() => {
+        const node = container.querySelector("#test-sidebar-content");
+        expect(node).toBe(null);
+      });
     });
     });
   });
   });
 
 
@@ -329,4 +343,70 @@ describe("Sidebar", () => {
       );
       );
     });
     });
   });
   });
+
+  describe("Sidebar.tab", () => {
+    it("should toggle sidebars tabs correctly", async () => {
+      const { container } = await render(
+        <Excalidraw>
+          <Sidebar name="custom" docked>
+            <Sidebar.Tabs>
+              <Sidebar.Tab tab="library">Library</Sidebar.Tab>
+              <Sidebar.Tab tab="comments">Comments</Sidebar.Tab>
+            </Sidebar.Tabs>
+          </Sidebar>
+        </Excalidraw>,
+      );
+
+      await withExcalidrawDimensions(
+        { width: 1920, height: 1080 },
+        async () => {
+          expect(
+            container.querySelector<HTMLElement>(
+              "[role=tabpanel][data-testid=library]",
+            ),
+          ).toBeNull();
+
+          // open library sidebar
+          expect(
+            window.h.app.toggleSidebar({ name: "custom", tab: "library" }),
+          ).toBe(true);
+          expect(
+            container.querySelector<HTMLElement>(
+              "[role=tabpanel][data-testid=library]",
+            ),
+          ).not.toBeNull();
+
+          // switch to comments tab
+          expect(
+            window.h.app.toggleSidebar({ name: "custom", tab: "comments" }),
+          ).toBe(true);
+          expect(
+            container.querySelector<HTMLElement>(
+              "[role=tabpanel][data-testid=comments]",
+            ),
+          ).not.toBeNull();
+
+          // toggle sidebar closed
+          expect(
+            window.h.app.toggleSidebar({ name: "custom", tab: "comments" }),
+          ).toBe(false);
+          expect(
+            container.querySelector<HTMLElement>(
+              "[role=tabpanel][data-testid=comments]",
+            ),
+          ).toBeNull();
+
+          // toggle sidebar open
+          expect(
+            window.h.app.toggleSidebar({ name: "custom", tab: "comments" }),
+          ).toBe(true);
+          expect(
+            container.querySelector<HTMLElement>(
+              "[role=tabpanel][data-testid=comments]",
+            ),
+          ).not.toBeNull();
+        },
+      );
+    });
+  });
 });
 });

+ 1 - 1
packages/excalidraw/components/Sidebar/SidebarTab.tsx

@@ -10,7 +10,7 @@ export const SidebarTab = ({
   children: React.ReactNode;
   children: React.ReactNode;
 } & React.HTMLAttributes<HTMLDivElement>) => {
 } & React.HTMLAttributes<HTMLDivElement>) => {
   return (
   return (
-    <RadixTabs.Content {...rest} value={tab}>
+    <RadixTabs.Content {...rest} value={tab} data-testid={tab}>
       {children}
       {children}
     </RadixTabs.Content>
     </RadixTabs.Content>
   );
   );