diff --git a/packages/apollo-vertex/registry/command/command.test.tsx b/packages/apollo-vertex/registry/command/command.test.tsx new file mode 100644 index 0000000000..3a20257c7f --- /dev/null +++ b/packages/apollo-vertex/registry/command/command.test.tsx @@ -0,0 +1,78 @@ +import { cleanup, render } from "@testing-library/react"; +import { afterEach, describe, expect, it, vi } from "vitest"; + +import { + Command, + CommandGroup, + CommandInput, + CommandItem, + CommandList, + CommandSeparator, +} from "./command"; + +vi.stubGlobal( + "ResizeObserver", + class { + observe = vi.fn(); + unobserve = vi.fn(); + disconnect = vi.fn(); + }, +); + +Element.prototype.scrollIntoView = vi.fn(); + +afterEach(cleanup); + +function renderCommand({ + search, + alwaysRender, +}: { + search?: string; + alwaysRender?: boolean; +} = {}) { + return render( + + + + + {"Calendar"} + + + + {"Profile"} + + + , + ); +} + +describe("CommandSeparator", () => { + it("renders inside the listbox without the separator role", () => { + const { container, getByRole } = renderCommand(); + + const separator = container.querySelector( + '[data-slot="command-separator"]', + ); + + expect(separator).not.toBeNull(); + expect(separator?.getAttribute("role")).toBe("none"); + expect(getByRole("listbox").contains(separator)).toBe(true); + expect(container.querySelector('[role="separator"]')).toBeNull(); + }); + + it("is hidden while searching", () => { + const { container } = renderCommand({ search: "cal" }); + + expect( + container.querySelector('[data-slot="command-separator"]'), + ).toBeNull(); + }); + + it("stays visible while searching when alwaysRender is set", () => { + const { container } = renderCommand({ search: "cal", alwaysRender: true }); + + expect( + container.querySelector('[data-slot="command-separator"]'), + ).not.toBeNull(); + }); +}); diff --git a/packages/apollo-vertex/registry/command/command.tsx b/packages/apollo-vertex/registry/command/command.tsx index cab3c271b2..916773be59 100644 --- a/packages/apollo-vertex/registry/command/command.tsx +++ b/packages/apollo-vertex/registry/command/command.tsx @@ -1,6 +1,6 @@ "use client"; -import { Command as CommandPrimitive } from "cmdk"; +import { Command as CommandPrimitive, useCommandState } from "cmdk"; import { SearchIcon } from "lucide-react"; import * as React from "react"; import { @@ -125,13 +125,25 @@ function CommandGroup({ ); } +interface CommandSeparatorProps extends React.ComponentProps<"div"> { + alwaysRender?: boolean; +} + function CommandSeparator({ className, + alwaysRender = false, ...props -}: React.ComponentProps) { +}: CommandSeparatorProps) { + const isSearchEmpty = useCommandState((state) => !state.search); + + if (!alwaysRender && !isSearchEmpty) { + return null; + } + return ( - @@ -181,3 +193,4 @@ export { CommandShortcut, CommandSeparator, }; +export type { CommandSeparatorProps }; diff --git a/packages/apollo-vertex/vitest.config.ts b/packages/apollo-vertex/vitest.config.ts index 5f63b1ed24..b98e9f3b4a 100644 --- a/packages/apollo-vertex/vitest.config.ts +++ b/packages/apollo-vertex/vitest.config.ts @@ -1,9 +1,8 @@ -import { resolve } from "node:path"; import { defineConfig } from "vitest/config"; export default defineConfig({ resolve: { - alias: { "@": resolve(__dirname, ".") }, + tsconfigPaths: true, }, test: { environment: "jsdom",