diff --git a/showcase/shell-docs/src/app/__tests__/globals-css.test.ts b/showcase/shell-docs/src/app/__tests__/globals-css.test.ts index 23d7504d31..fd5b2d2cf0 100644 --- a/showcase/shell-docs/src/app/__tests__/globals-css.test.ts +++ b/showcase/shell-docs/src/app/__tests__/globals-css.test.ts @@ -81,23 +81,6 @@ describe("globals.css cookbook sidebar", () => { }); }); -describe("globals.css sidebar Intelligence pin", () => { - it("stays muted until hover, then fills like the header Intelligence control", () => { - const idleBlock = globalsCss.match( - /\.shell-docs-intelligence-entry \{[\s\S]*?\n\}/, - )?.[0]; - expect(idleBlock).toContain("background: transparent;"); - expect(idleBlock).toContain("color: var(--text-muted);"); - expect(idleBlock).not.toContain("background: var(--accent);"); - - const hoverBlock = globalsCss.match( - /\.shell-docs-intelligence-entry:hover,\s*\.shell-docs-intelligence-entry:focus-visible \{[\s\S]*?\n\}/, - )?.[0]; - expect(hoverBlock).toContain("background: var(--accent);"); - expect(hoverBlock).toContain("color: #fff;"); - }); -}); - describe("globals.css sidebar section folders", () => { it("styles collapsible section triggers separately from page links", () => { expect(globalsCss).toContain(".shell-docs-sidebar-section-label"); diff --git a/showcase/shell-docs/src/app/globals.css b/showcase/shell-docs/src/app/globals.css index 9a0aa40e9b..979927204c 100644 --- a/showcase/shell-docs/src/app/globals.css +++ b/showcase/shell-docs/src/app/globals.css @@ -314,63 +314,6 @@ color: var(--accent); } -.shell-docs-intelligence-entry { - display: flex; - align-items: center; - gap: 0.5rem; - min-height: 2.5rem; - padding: 0.5rem 0.75rem; - border-radius: var(--shell-docs-radius-control); - background: transparent; - color: var(--text-muted); - font-size: 0.8125rem; - font-weight: 500; - text-decoration: none; - transition: - background-color 150ms ease-out, - color 150ms ease-out, - transform 100ms ease-out; -} - -.shell-docs-intelligence-entry svg { - fill: none; -} - -.shell-docs-intelligence-entry:hover, -.shell-docs-intelligence-entry:focus-visible { - background: var(--accent); - color: #fff; -} - -.shell-docs-intelligence-entry:hover svg, -.shell-docs-intelligence-entry:focus-visible svg { - fill: currentColor; -} - -.shell-docs-intelligence-entry:focus-visible { - outline: 2px solid var(--accent); - outline-offset: 2px; -} - -.shell-docs-intelligence-entry:active { - transform: scale(0.96); -} - -.shell-docs-intelligence-entry-active { - background: color-mix(in oklch, var(--accent) 13%, transparent); - color: var(--accent); -} - -.shell-docs-intelligence-entry-active:hover, -.shell-docs-intelligence-entry-active:focus-visible { - background: var(--accent); - color: #fff; -} - -.dark .shell-docs-intelligence-entry-active { - background: color-mix(in oklch, var(--accent) 20%, transparent); -} - .shell-docs-mega-menu { padding: 1.25rem 1.5rem; } @@ -455,14 +398,9 @@ } @media (prefers-reduced-motion: reduce) { - .shell-docs-intelligence-entry, .shell-docs-mega-menu-link { transition: none; } - - .shell-docs-intelligence-entry:active { - transform: none; - } } .shell-docs-warning-surface { @@ -583,20 +521,6 @@ color: var(--accent); } -.shell-docs-nav-link-idle.shell-docs-nav-link-intelligence:hover, -.shell-docs-nav-link-active.shell-docs-nav-link-intelligence:hover, -.shell-docs-nav-link-intelligence:focus-visible { - background: var(--accent); - color: #fff; - box-shadow: none; -} - -.dark .shell-docs-nav-link-idle.shell-docs-nav-link-intelligence:hover, -.dark .shell-docs-nav-link-active.shell-docs-nav-link-intelligence:hover { - background: var(--accent); - color: #fff; -} - /* shell-docs sidebar overrides. * * Fumadocs's DocsLayout sidebar reserves a header row with the home diff --git a/showcase/shell-docs/src/components/__tests__/brand-nav.test.tsx b/showcase/shell-docs/src/components/__tests__/brand-nav.test.tsx index f3a4f209a2..03c264832c 100644 --- a/showcase/shell-docs/src/components/__tests__/brand-nav.test.tsx +++ b/showcase/shell-docs/src/components/__tests__/brand-nav.test.tsx @@ -48,6 +48,7 @@ vi.mock("@clerk/nextjs", () => { }); import { BrandNav, buildDocsAuthEntryHref } from "../brand-nav"; +import { PrimaryDocsTabs } from "../primary-docs-tabs"; import { buildDocsUserMenuHref, DocsAuthFallbackBoundary, @@ -70,28 +71,31 @@ const globalsCss = readFileSync( "utf8", ); -test("BrandNav opens docs from an Explore docs mega menu", () => { +test("BrandNav opens Docs from a mega menu", () => { expect(brandNavSource).toContain("DocsMegaMenu"); expect(brandNavSource).not.toContain('label: "Docs"'); expect(brandNavSource).not.toContain('href: "/"'); }); -test("BrandNav puts Intelligence next to Cookbook", () => { +test("BrandNav keeps Intelligence out of the primary header links", () => { expect(brandNavSource).toContain('label: "Cookbook"'); - expect(brandNavSource).toContain('label: "Intelligence"'); - expect(brandNavSource).toContain("INTELLIGENCE_DOCS_HREF"); - expect(brandNavSource.indexOf('label: "Cookbook"')).toBeLessThan( - brandNavSource.indexOf('label: "Intelligence"'), - ); + expect(brandNavSource).not.toContain('label: "Intelligence"'); + expect(brandNavSource).not.toContain("INTELLIGENCE_DOCS_HREF"); +}); + +test("PrimaryDocsTabs keeps Intelligence out of the mobile links", () => { + const markup = renderToStaticMarkup(); + + expect(markup).toContain(">Docs<"); + expect(markup).toContain(">Reference<"); + expect(markup).toContain(">Cookbook<"); + expect(markup).not.toContain(">Intelligence<"); }); test("BrandNav keeps space between the center rail and search", () => { expect(brandNavSource).toContain("grid-cols-[auto_minmax(0,1fr)_auto]"); expect(brandNavSource).toContain("gap-x-8"); expect(brandNavSource).toContain("pl-4"); - expect(globalsCss).toContain( - ".shell-docs-nav-link-idle.shell-docs-nav-link-intelligence:hover", - ); }); test("BrandNav uses the docs grid desktop layout cap", () => { diff --git a/showcase/shell-docs/src/components/__tests__/docs-mega-menu.test.tsx b/showcase/shell-docs/src/components/__tests__/docs-mega-menu.test.tsx index c4d4e0f8b2..dbfffe5769 100644 --- a/showcase/shell-docs/src/components/__tests__/docs-mega-menu.test.tsx +++ b/showcase/shell-docs/src/components/__tests__/docs-mega-menu.test.tsx @@ -23,9 +23,9 @@ afterEach(cleanup); test("opens a five-column docs map with Intelligence featured", () => { render(); - fireEvent.pointerEnter(screen.getByRole("button", { name: "Explore docs" })); + fireEvent.pointerEnter(screen.getByRole("button", { name: "Docs" })); - expect(screen.getByRole("navigation", { name: "Explore docs" })).toBeTruthy(); + expect(screen.getByRole("navigation", { name: "Docs" })).toBeTruthy(); expect(screen.getByRole("heading", { name: "Start" })).toBeTruthy(); expect(screen.getByRole("heading", { name: "Build" })).toBeTruthy(); expect(screen.getByRole("heading", { name: "Connect" })).toBeTruthy(); @@ -37,6 +37,12 @@ test("opens a five-column docs map with Intelligence featured", () => { expect(intelligence.className).toContain( "shell-docs-mega-menu-link-featured", ); + expect(intelligence.querySelector("svg")?.getAttribute("viewBox")).toBe( + "0 0 24 24", + ); + expect(intelligence.querySelector("svg")?.getAttribute("fill")).toBe( + "currentColor", + ); expect( screen.getByRole("link", { name: "Threads" }).getAttribute("href"), ).toBe("/threads"); diff --git a/showcase/shell-docs/src/components/__tests__/shell-docs-layout.test.ts b/showcase/shell-docs/src/components/__tests__/shell-docs-layout.test.ts index f9c4c9ec35..636365269e 100644 --- a/showcase/shell-docs/src/components/__tests__/shell-docs-layout.test.ts +++ b/showcase/shell-docs/src/components/__tests__/shell-docs-layout.test.ts @@ -6,16 +6,13 @@ const layoutSource = readFileSync( "utf8", ); -test("sidebar banner puts pickers above the Intelligence pin", () => { +test("sidebar banner keeps the pickers above the mobile docs tabs", () => { const bannerIndex = layoutSource.lastIndexOf("{banner}"); - const intelligenceIndex = layoutSource.lastIndexOf( - "', ); expect(bannerIndex).toBeGreaterThanOrEqual(0); - expect(intelligenceIndex).toBeGreaterThan(bannerIndex); - expect(tabsIndex).toBeGreaterThan(intelligenceIndex); + expect(tabsIndex).toBeGreaterThan(bannerIndex); + expect(layoutSource).not.toContain("SidebarIntelligenceEntry"); }); diff --git a/showcase/shell-docs/src/components/__tests__/sidebar-intelligence-entry.test.tsx b/showcase/shell-docs/src/components/__tests__/sidebar-intelligence-entry.test.tsx deleted file mode 100644 index c9f3f2f182..0000000000 --- a/showcase/shell-docs/src/components/__tests__/sidebar-intelligence-entry.test.tsx +++ /dev/null @@ -1,51 +0,0 @@ -// @vitest-environment jsdom - -import React from "react"; -import { cleanup, render, screen } from "@testing-library/react"; -import { afterEach, expect, test, vi } from "vitest"; - -const navigation = vi.hoisted(() => ({ - pathname: "/", -})); - -vi.mock("next/navigation", () => ({ - usePathname: () => navigation.pathname, -})); - -vi.mock("next/link", () => ({ - default: ({ children, href, ...props }: React.ComponentProps<"a">) => ( - - {children} - - ), -})); - -import { SidebarIntelligenceEntry } from "../sidebar-intelligence-entry"; - -afterEach(cleanup); - -test("pins Intelligence at the top of the sidebar as a docs link", () => { - navigation.pathname = "/quickstart"; - render(); - - const link = screen.getByRole("link", { name: "Intelligence" }); - expect(link.getAttribute("href")).toBe("/intelligence/overview"); - expect(link.getAttribute("aria-current")).toBeNull(); - expect(link.className).toContain("shell-docs-intelligence-entry"); - expect(link.className).not.toContain("shell-docs-intelligence-entry-active"); - expect(link.querySelector("svg")?.getAttribute("class")).not.toContain( - "fill-current", - ); -}); - -test("marks the Intelligence pin current on Intelligence docs", () => { - navigation.pathname = "/intelligence/overview"; - render(); - - const link = screen.getByRole("link", { name: "Intelligence" }); - expect(link.getAttribute("aria-current")).toBe("page"); - expect(link.className).toContain("shell-docs-intelligence-entry-active"); - expect(link.querySelector("svg")?.getAttribute("class")).not.toContain( - "fill-current", - ); -}); diff --git a/showcase/shell-docs/src/components/brand-nav.tsx b/showcase/shell-docs/src/components/brand-nav.tsx index ccce9f6137..36e690ca45 100644 --- a/showcase/shell-docs/src/components/brand-nav.tsx +++ b/showcase/shell-docs/src/components/brand-nav.tsx @@ -3,18 +3,14 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; import { usePostHog } from "posthog-js/react"; -import { CalendarDays, ChefHat, Star } from "lucide-react"; +import { CalendarDays, ChefHat } from "lucide-react"; import { SearchTrigger } from "./search-trigger"; import { CopilotKitMark } from "./copilotkit-mark"; import { ThemeSwitch } from "./theme-switch"; import ConsoleIcon from "./icons/console"; import ExternalLinkIcon from "./icons/external-link"; import { DocsMegaMenu } from "./docs-mega-menu"; -import { - INTELLIGENCE_DOCS_HREF, - isDocsExplorePath, - isIntelligenceDocsPath, -} from "@/lib/docs-mega-menu"; +import { isDocsExplorePath } from "@/lib/docs-mega-menu"; import { DocsPublicAuthControl, buildDocsAuthEntryHref, @@ -50,11 +46,6 @@ const LEFT_LINKS: LeftLink[] = [ label: "Cookbook", href: "/cookbook", }, - { - icon: , - label: "Intelligence", - href: INTELLIGENCE_DOCS_HREF, - }, ]; export interface BrandNavProps { @@ -69,18 +60,15 @@ export function BrandNav(_props: BrandNavProps = {}) { const posthog = usePostHog(); const authEntryHref = useDocsAuthEntryHref(); - // Active-route detection: Reference, Cookbook, and Intelligence each own - // their prefix. Everything else (root and framework-scoped pages) - // highlights Explore docs. + // Active-route detection: Reference and Cookbook each own their prefix. + // Everything else highlights Docs. const firstSegment = pathname === "/" ? "/" : `/${pathname.split("/")[1]}`; const activeRoute = firstSegment === "/reference" ? "/reference" : firstSegment === "/cookbook" ? "/cookbook" - : isIntelligenceDocsPath(pathname) - ? INTELLIGENCE_DOCS_HREF - : "/"; + : "/"; const handleTalkToEngineersClick = () => { posthog?.capture("talk_to_us_clicked", { location: "docs_nav" }); @@ -122,7 +110,6 @@ export function BrandNav(_props: BrandNavProps = {}) { {LEFT_LINKS.map((link) => { const isActive = activeRoute === link.href; - const isIntelligence = link.href === INTELLIGENCE_DOCS_HREF; return (
  • diff --git a/showcase/shell-docs/src/components/copilotkit-icon.tsx b/showcase/shell-docs/src/components/copilotkit-icon.tsx new file mode 100644 index 0000000000..a6547d20bb --- /dev/null +++ b/showcase/shell-docs/src/components/copilotkit-icon.tsx @@ -0,0 +1,21 @@ +export function CopilotKitIcon({ className }: { className?: string }) { + return ( + + ); +} diff --git a/showcase/shell-docs/src/components/docs-mega-menu.tsx b/showcase/shell-docs/src/components/docs-mega-menu.tsx index 13a58ab287..752de4122d 100644 --- a/showcase/shell-docs/src/components/docs-mega-menu.tsx +++ b/showcase/shell-docs/src/components/docs-mega-menu.tsx @@ -23,16 +23,17 @@ import { Server, Sparkles, Terminal, - type LucideIcon, } from "lucide-react"; +import type { LucideIcon } from "lucide-react"; import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover"; +import { CopilotKitIcon } from "./copilotkit-icon"; import { DOCS_MEGA_MENU_COLUMNS, isDocsExplorePath, - type MegaMenuIconName, } from "@/lib/docs-mega-menu"; +import type { MegaMenuIconName } from "@/lib/docs-mega-menu"; -const MEGA_MENU_ICONS: Record = { +const MEGA_MENU_ICONS: Record, LucideIcon> = { book: BookOpen, rocket: Rocket, terminal: Terminal, @@ -118,7 +119,7 @@ export function DocsMegaMenu({ className="h-4 w-4 shrink-0 text-current" aria-hidden="true" /> - Explore docs + Docs -