{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "notebook-layout",
  "title": "Notebook layout",
  "description": "DocsLayout from layouts/notebook: a more compact docs layout on the shadcn/ui sidebar, with a navbar beside or above the sidebar, and layout tabs in the sidebar or the navbar.",
  "dependencies": [
    "cn",
    "fumadocs-core@^16.17.8",
    "lucide-react"
  ],
  "registryDependencies": [
    "sidebar",
    "button",
    "popover",
    "@docscn/docs-sidebar",
    "@docscn/sidebar-tabs",
    "@docscn/theme-switch",
    "@docscn/search-trigger",
    "@docscn/tree-context",
    "@docscn/layout-shared",
    "@docscn/docs-utils",
    "@docscn/i18n-context",
    "@docscn/language-select"
  ],
  "files": [
    {
      "path": "registry/base/docs/layouts/notebook/index.tsx",
      "content": "// Adapted from Fumadocs UI (https://github.com/fuma-nama/fumadocs)\n// Copyright (c) 2023 Fuma, MIT License\nimport type * as PageTree from \"fumadocs-core/page-tree\";\nimport type { ComponentProps } from \"react\";\nimport type { SidebarTreeOptions } from \"../../components/sidebar/page-tree\";\nimport {\n  type AIChatOptions,\n  type BaseLayoutProps,\n  getLayoutTabs,\n  type GetLayoutTabsOptions,\n  type LayoutTab,\n  type NavOptions,\n} from \"../shared\";\nimport { LayoutBody } from \"./client\";\nimport type { SidebarProps } from \"./slots/sidebar\";\n\nexport interface DocsLayoutProps extends Omit<BaseLayoutProps, \"nav\"> {\n  tree: PageTree.Root;\n  tabs?: LayoutTab[] | GetLayoutTabsOptions | false;\n  /**\n   * Show layout tabs as a dropdown in the sidebar, or below the navbar on\n   * desktop\n   *\n   * @defaultValue 'sidebar'\n   */\n  tabMode?: \"sidebar\" | \"navbar\";\n  sidebar?: SidebarOptions;\n  nav?: NavOptions & {\n    /**\n     * `top` places the navbar above the sidebar, across the whole width.\n     * `auto` places it beside the sidebar.\n     *\n     * @defaultValue 'auto'\n     */\n    mode?: \"top\" | \"auto\";\n  };\n  containerProps?: ComponentProps<\"div\">;\n  aiChat?: AIChatOptions;\n}\n\nexport interface SidebarOptions extends SidebarProps, SidebarTreeOptions {\n  /**\n   * Whether the sidebar is open on desktop at first. Read the `sidebar_state`\n   * cookie in your layout and pass it here to keep the state across page loads.\n   *\n   * @defaultValue true\n   */\n  defaultOpen?: boolean;\n\n  /** Control the desktop open state */\n  open?: boolean;\n  onOpenChange?: (open: boolean) => void;\n}\n\nexport function DocsLayout({\n  tree,\n  tabs: layoutTabs,\n  children,\n  ...props\n}: DocsLayoutProps) {\n  let tabs: LayoutTab[] = [];\n  if (Array.isArray(layoutTabs)) {\n    tabs = layoutTabs;\n  } else if (typeof layoutTabs === \"object\") {\n    tabs = getLayoutTabs(tree, layoutTabs);\n  } else if (layoutTabs !== false) {\n    tabs = getLayoutTabs(tree);\n  }\n\n  return (\n    <LayoutBody tree={tree} tabs={tabs} {...props}>\n      {children}\n    </LayoutBody>\n  );\n}\n\nexport { useNotebookLayout } from \"./client\";\n",
      "type": "registry:component",
      "target": "@components/docs/layouts/notebook/index.tsx"
    },
    {
      "path": "registry/base/docs/layouts/notebook/client.tsx",
      "content": "// Adapted from Fumadocs UI (https://github.com/fuma-nama/fumadocs)\n// Copyright (c) 2023 Fuma, MIT License\n\"use client\";\n\nimport { cn } from \"cn\";\nimport { createContext, use } from \"react\";\nimport { SidebarInset, SidebarProvider } from \"@/components/ui/sidebar\";\nimport { SidebarTreeOptionsProvider } from \"../../components/sidebar/page-tree\";\nimport { TreeContextProvider } from \"../../contexts/tree\";\nimport { useIsScrollTop } from \"../../utils/use-is-scroll-top\";\nimport { type LayoutTab, type LinkItemType, useLinkItems } from \"../shared\";\nimport { AIChatPanel, AIChatTrigger, SkipToContent } from \"../shared/client\";\nimport type { DocsLayoutProps } from \".\";\nimport { Container } from \"./slots/container\";\nimport { Header } from \"./slots/header\";\nimport { Sidebar } from \"./slots/sidebar\";\n\ninterface LayoutProps extends Pick<\n  DocsLayoutProps,\n  \"nav\" | \"themeSwitch\" | \"searchToggle\" | \"aiChat\"\n> {\n  tabs: LayoutTab[];\n  tabMode: NonNullable<DocsLayoutProps[\"tabMode\"]>;\n  sidebarCollapsible: boolean;\n}\n\nconst LayoutContext = createContext<{\n  props: LayoutProps;\n  isNavTransparent: boolean;\n  navItems: LinkItemType[];\n  menuItems: LinkItemType[];\n} | null>(null);\n\nexport function useNotebookLayout() {\n  const context = use(LayoutContext);\n  if (!context)\n    throw new Error(\n      \"Please use <DocsPage /> (`components/docs/layouts/notebook/page`) under <DocsLayout /> (`components/docs/layouts/notebook`).\",\n    );\n  return context;\n}\n\nexport function LayoutBody(\n  props: Omit<DocsLayoutProps, \"tabs\"> & {\n    tabs: LayoutTab[];\n  },\n) {\n  const {\n    nav,\n    themeSwitch,\n    searchToggle,\n    sidebar: {\n      defaultOpenLevel,\n      prefetch,\n      defaultOpen,\n      open,\n      onOpenChange,\n      collapsible = true,\n      ...sidebarProps\n    } = {},\n    tabs,\n    tabMode = \"sidebar\",\n    tree,\n    containerProps,\n    aiChat,\n    children,\n  } = props;\n  const {\n    enabled: navEnabled = true,\n    transparentMode = \"none\",\n    mode: navMode = \"auto\",\n  } = nav ?? {};\n  const isTop = useIsScrollTop({ enabled: transparentMode === \"top\" }) ?? true;\n  const isNavTransparent =\n    transparentMode === \"top\" ? isTop : transparentMode === \"always\";\n  const linkItems = useLinkItems(props);\n\n  return (\n    <TreeContextProvider tree={tree}>\n      <LayoutContext\n        value={{\n          props: {\n            tabMode,\n            tabs,\n            nav,\n            themeSwitch,\n            searchToggle,\n            sidebarCollapsible: collapsible,\n            aiChat,\n          },\n          isNavTransparent,\n          ...linkItems,\n        }}\n      >\n        <SidebarTreeOptionsProvider\n          defaultOpenLevel={defaultOpenLevel}\n          prefetch={prefetch}\n        >\n          <SidebarProvider\n            defaultOpen={defaultOpen}\n            open={collapsible ? open : true}\n            onOpenChange={onOpenChange}\n          >\n            <SkipToContent />\n            <Container navEnabled={navEnabled} {...containerProps}>\n              {navEnabled && navMode === \"top\" && <Header />}\n              <div className=\"flex flex-1\">\n                <Sidebar collapsible={collapsible} {...sidebarProps} />\n                <SidebarInset className=\"min-w-0\">\n                  {navEnabled && navMode === \"auto\" && <Header />}\n                  {children}\n                </SidebarInset>\n                {aiChat?.panel && (\n                  <AIChatPanel\n                    open={aiChat.open}\n                    className={cn(\n                      \"xl:sticky xl:data-[state=open]:border-s\",\n                      navEnabled && navMode === \"top\"\n                        ? // below the navbar\n                          \"xl:top-[calc(var(--docs-banner-height,0px)+var(--docs-header-height))] xl:h-[calc(100svh-var(--docs-banner-height,0px)-var(--docs-header-height))]\"\n                        : \"xl:top-(--docs-banner-height,0px) xl:h-[calc(100svh-var(--docs-banner-height,0px))]\",\n                    )}\n                  >\n                    {aiChat.panel}\n                  </AIChatPanel>\n                )}\n                {aiChat?.trigger && <AIChatTrigger {...aiChat} />}\n              </div>\n            </Container>\n          </SidebarProvider>\n        </SidebarTreeOptionsProvider>\n      </LayoutContext>\n    </TreeContextProvider>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/docs/layouts/notebook/client.tsx"
    },
    {
      "path": "registry/base/docs/layouts/notebook/slots/header.tsx",
      "content": "// Adapted from Fumadocs UI (https://github.com/fuma-nama/fumadocs)\n// Copyright (c) 2023 Fuma, MIT License\n\"use client\";\n\nimport { cn } from \"cn\";\nimport { usePathname } from \"fumadocs-core/framework\";\nimport Link from \"fumadocs-core/link\";\nimport { ChevronDown, Languages } from \"lucide-react\";\nimport {\n  type ComponentProps,\n  Fragment,\n  type HTMLAttributes,\n  useMemo,\n} from \"react\";\nimport { buttonVariants } from \"@/components/ui/button\";\nimport {\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport { useSidebar } from \"@/components/ui/sidebar\";\nimport { SidebarTrigger } from \"../../../components/sidebar/base\";\nimport { SidebarTabsDropdown } from \"../../../components/sidebar/tabs/dropdown\";\nimport { useI18n } from \"../../../contexts/i18n\";\nimport { useTabsGroups, useTreePath } from \"../../../contexts/tree\";\nimport { findLast, findLastIndex } from \"../../../utils/array\";\nimport {\n  isLayoutTabActive,\n  isLinkItemActive,\n  type LayoutTab,\n  type LinkItemType,\n  type MenuItemType,\n} from \"../../shared\";\nimport { LinkItem, NavTitle } from \"../../shared/client\";\nimport { LanguageSelect } from \"../../shared/slots/language-select\";\nimport {\n  FullSearchTrigger,\n  SearchTrigger,\n} from \"../../shared/slots/search-trigger\";\nimport { ThemeSwitch } from \"../../shared/slots/theme-switch\";\nimport { useNotebookLayout } from \"../client\";\n\n/**\n * The navbar, with the title, search, links, the theme switch and the sidebar\n * trigger, plus the layout tabs on desktop when `tabMode` is `navbar`.\n */\nexport function Header(props: ComponentProps<\"header\">) {\n  const {\n    navItems,\n    isNavTransparent,\n    props: {\n      tabMode,\n      nav,\n      tabs,\n      themeSwitch,\n      searchToggle,\n      sidebarCollapsible,\n    },\n  } = useNotebookLayout();\n  const { state, openMobile } = useSidebar();\n  const { locales = [] } = useI18n();\n  const navMode = nav?.mode ?? \"auto\";\n  const collapsed = state === \"collapsed\";\n  const groups = useTabsGroups(tabs);\n  const showLayoutTabs = tabMode === \"navbar\" && groups.length > 0;\n  const { enabled: themeSwitchEnabled = true, ...themeSwitchProps } =\n    themeSwitch ?? {};\n  const {\n    enabled: searchEnabled = true,\n    sm: searchSmProps,\n    full: searchFullProps,\n  } = searchToggle ?? {};\n\n  return (\n    <header\n      id=\"nd-subnav\"\n      data-transparent={isNavTransparent && !openMobile}\n      {...props}\n      className={cn(\n        \"sticky top-(--docs-banner-height,0px) z-30 flex flex-col backdrop-blur-sm transition-colors data-[transparent=false]:bg-background/80\",\n        props.className,\n      )}\n    >\n      <div\n        data-header-body=\"\"\n        className={cn(\n          \"flex h-14 gap-2 border-b px-4\",\n          navMode === \"top\" && \"md:px-6\",\n        )}\n      >\n        <div\n          className={cn(\n            \"flex items-center gap-2\",\n            navMode === \"top\" && \"flex-1\",\n            // beside an open sidebar, which shows the title instead\n            navMode === \"auto\" && !collapsed && \"md:hidden\",\n          )}\n        >\n          {sidebarCollapsible && navMode === \"auto\" && (\n            <SidebarTrigger className=\"-ms-1.5 text-muted-foreground max-md:hidden\" />\n          )}\n          <NavTitle\n            nav={nav}\n            className=\"inline-flex items-center gap-2.5 font-semibold\"\n          />\n          {nav?.children}\n        </div>\n        {searchEnabled && (\n          <FullSearchTrigger\n            hideIfDisabled\n            {...searchFullProps}\n            className={cn(\n              \"my-auto w-full max-md:hidden\",\n              navMode === \"top\" ? \"max-w-sm\" : \"max-w-[240px]\",\n              searchFullProps?.className,\n            )}\n          />\n        )}\n        <div className=\"flex flex-1 items-center justify-end md:gap-2\">\n          <div className=\"flex items-center gap-6 empty:hidden max-lg:hidden\">\n            {navItems\n              .filter((item) => item.type !== \"icon\")\n              .map((item, i) => (\n                <NavbarLinkItem key={i} item={item} />\n              ))}\n          </div>\n          {navItems\n            .filter((item) => item.type === \"icon\")\n            .map((item, i) => (\n              <LinkItem\n                key={i}\n                item={item}\n                className={cn(\n                  buttonVariants({ size: \"icon-sm\", variant: \"ghost\" }),\n                  \"text-muted-foreground max-lg:hidden [&_svg]:size-4\",\n                )}\n                aria-label={item.label}\n              >\n                {item.icon}\n              </LinkItem>\n            ))}\n\n          <div className=\"flex items-center md:hidden\">\n            {searchEnabled && (\n              <SearchTrigger hideIfDisabled {...searchSmProps} />\n            )}\n            <SidebarTrigger className=\"-me-1.5\" />\n          </div>\n\n          <div className=\"flex items-center gap-2 max-md:hidden\">\n            {locales.length > 1 && (\n              <LanguageSelect className=\"text-muted-foreground\">\n                <Languages />\n              </LanguageSelect>\n            )}\n            {themeSwitchEnabled && <ThemeSwitch {...themeSwitchProps} />}\n            {sidebarCollapsible && navMode === \"top\" && (\n              <SidebarTrigger className=\"-me-1.5 text-muted-foreground\" />\n            )}\n          </div>\n        </div>\n      </div>\n      {showLayoutTabs && (\n        <LayoutHeaderTabs\n          data-header-tabs=\"\"\n          className=\"h-10 overflow-x-auto border-b px-6 max-lg:hidden\"\n          tabs={tabs}\n        />\n      )}\n    </header>\n  );\n}\n\nfunction LayoutHeaderTabs({\n  tabs: allTabs,\n  className,\n  ...props\n}: ComponentProps<\"div\"> & {\n  tabs: LayoutTab[];\n}) {\n  const pathname = usePathname();\n  const path = useTreePath();\n  const tabs = findLast(\n    useTabsGroups(allTabs),\n    (group) => typeof group.active?.root !== \"string\",\n  )?.options;\n  // tabs of typed root folders, which switch between themselves\n  const typedTabs = useMemo(() => {\n    return allTabs.filter((tab) => typeof tab.$folder?.root === \"string\");\n  }, [allTabs]);\n  const selectedIdx = useMemo(() => {\n    if (!tabs) return -1;\n    return findLastIndex(tabs, (option) =>\n      isLayoutTabActive(option, path, pathname),\n    );\n  }, [tabs, path, pathname]);\n\n  return (\n    <div className={cn(\"flex flex-row items-end gap-6\", className)} {...props}>\n      {typedTabs.length > 0 && (\n        <SidebarTabsDropdown\n          options={typedTabs}\n          className=\"my-auto w-auto p-1\"\n        />\n      )}\n      {tabs?.map((option, i) => {\n        const {\n          title,\n          url,\n          unlisted,\n          props: { className, ...rest } = {},\n        } = option;\n        const isSelected = selectedIdx === i;\n\n        return (\n          <Link\n            key={i}\n            href={url}\n            className={cn(\n              \"inline-flex items-center gap-2 border-b-2 border-transparent pb-1.5 text-sm font-medium text-nowrap text-muted-foreground transition-colors hover:text-foreground\",\n              unlisted && !isSelected && \"hidden\",\n              isSelected && \"border-primary text-foreground\",\n              className,\n            )}\n            {...rest}\n          >\n            {title}\n          </Link>\n        );\n      })}\n    </div>\n  );\n}\n\nfunction NavbarLinkItem({\n  item,\n  className,\n  ...props\n}: { item: LinkItemType } & HTMLAttributes<HTMLElement>) {\n  if (item.type === \"custom\") return item.children;\n\n  if (item.type === \"menu\") {\n    return <NavbarLinkItemMenu item={item} className={className} {...props} />;\n  }\n\n  return (\n    <LinkItem\n      item={item}\n      className={cn(\n        \"text-sm text-muted-foreground transition-colors hover:text-foreground data-[active=true]:text-foreground\",\n        className,\n      )}\n      {...props}\n    >\n      {item.text}\n    </LinkItem>\n  );\n}\n\nfunction NavbarLinkItemMenu({\n  item,\n  className,\n  ...props\n}: { item: MenuItemType } & HTMLAttributes<HTMLElement>) {\n  const pathname = usePathname();\n  const active = item.items.some((child) => isLinkItemActive(child, pathname));\n\n  return (\n    <Popover>\n      <PopoverTrigger\n        openOnHover\n        delay={50}\n        // a menu with a url is also a link\n        {...(item.url && {\n          nativeButton: false,\n          render: <Link href={item.url} external={item.external} />,\n        })}\n        data-active={active || isLinkItemActive(item, pathname)}\n        className={cn(\n          \"inline-flex items-center gap-1.5 p-1 text-sm text-muted-foreground transition-colors outline-none hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring data-popup-open:text-foreground data-[active=true]:text-foreground\",\n          className,\n        )}\n        {...props}\n      >\n        {item.text}\n        <ChevronDown className=\"size-3\" />\n      </PopoverTrigger>\n      <PopoverContent className=\"w-auto min-w-40 gap-0 p-1 text-start text-muted-foreground\">\n        {item.items.map((child, i) => {\n          if (child.type === \"custom\")\n            return <Fragment key={i}>{child.children}</Fragment>;\n\n          return (\n            <LinkItem\n              key={i}\n              item={child}\n              className=\"inline-flex items-center gap-2 rounded-md p-2 transition-colors hover:bg-accent hover:text-accent-foreground data-[active=true]:text-foreground [&_svg]:size-4\"\n            >\n              {child.icon}\n              {child.text}\n            </LinkItem>\n          );\n        })}\n      </PopoverContent>\n    </Popover>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/docs/layouts/notebook/slots/header.tsx"
    },
    {
      "path": "registry/base/docs/layouts/notebook/slots/sidebar.tsx",
      "content": "// Adapted from Fumadocs UI (https://github.com/fuma-nama/fumadocs)\n// Copyright (c) 2023 Fuma, MIT License\n\"use client\";\n\nimport { cn } from \"cn\";\nimport { Languages } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { buttonVariants } from \"@/components/ui/button\";\nimport {\n  Sidebar as SidebarRoot,\n  SidebarContent,\n  SidebarFooter,\n  SidebarGroup,\n  SidebarGroupContent,\n  SidebarHeader,\n  SidebarMenu,\n} from \"@/components/ui/sidebar\";\nimport { SidebarRail, SidebarTrigger } from \"../../../components/sidebar/base\";\nimport { SidebarLinkItem } from \"../../../components/sidebar/link-item\";\nimport {\n  SidebarPageTree,\n  type SidebarPageTreeComponents,\n} from \"../../../components/sidebar/page-tree\";\nimport { SidebarTabsDropdown } from \"../../../components/sidebar/tabs/dropdown\";\nimport { useI18n } from \"../../../contexts/i18n\";\nimport { LinkItem, NavTitle } from \"../../shared/client\";\nimport { LanguageSelect } from \"../../shared/slots/language-select\";\nimport { ThemeSwitch } from \"../../shared/slots/theme-switch\";\nimport { useNotebookLayout } from \"../client\";\n\nexport interface SidebarProps extends Omit<\n  ComponentProps<typeof SidebarRoot>,\n  \"collapsible\"\n> {\n  components?: Partial<SidebarPageTreeComponents>;\n  banner?: ReactNode;\n  footer?: ReactNode;\n\n  /**\n   * Support collapsing the sidebar on desktop mode\n   *\n   * @defaultValue true\n   */\n  collapsible?: boolean;\n}\n\nexport function Sidebar({\n  footer,\n  banner,\n  collapsible = true,\n  components,\n  className,\n  ...rest\n}: SidebarProps) {\n  const {\n    menuItems,\n    props: { tabs, nav, tabMode, themeSwitch },\n  } = useNotebookLayout();\n  const navMode = nav?.mode ?? \"auto\";\n  const iconLinks = menuItems.filter((item) => item.type === \"icon\");\n  const links = menuItems.filter((item) => item.type !== \"icon\");\n  const { enabled: themeSwitchEnabled = true, ...themeSwitchProps } =\n    themeSwitch ?? {};\n  const { locales = [] } = useI18n();\n  const languageSelect = locales.length > 1;\n  // the navbar shows links from `lg`, and the language and theme switches\n  // from `md`\n  const footerItemsHidden = iconLinks.length > 0 ? \"lg:hidden\" : \"md:hidden\";\n\n  return (\n    <SidebarRoot\n      collapsible=\"offcanvas\"\n      className={cn(\n        \"text-sm\",\n        navMode === \"top\"\n          ? // below the navbar, on the page's background\n            \"top-[calc(var(--docs-banner-height,0px)+var(--docs-header-height))] h-[calc(100svh-var(--docs-banner-height,0px)-var(--docs-header-height))] *:data-[sidebar=sidebar]:bg-background\"\n          : // below a Banner, if there is one\n            \"top-(--docs-banner-height,0px) h-[calc(100svh-var(--docs-banner-height,0px))]\",\n        className,\n      )}\n      {...rest}\n    >\n      <SidebarHeader className=\"gap-3 p-4 pb-2 empty:hidden\">\n        {navMode === \"auto\" && (\n          <div className=\"flex items-center gap-2\">\n            <NavTitle\n              nav={nav}\n              className=\"ms-2 me-auto inline-flex items-center gap-2.5 text-[0.9375rem] font-medium\"\n            />\n            {nav?.children}\n            {collapsible && (\n              <SidebarTrigger className=\"-me-1.5 text-muted-foreground max-md:hidden\" />\n            )}\n          </div>\n        )}\n        {tabs.length > 0 && (\n          <SidebarTabsDropdown\n            options={tabs}\n            className={cn(tabMode === \"navbar\" && \"lg:hidden\")}\n          />\n        )}\n        {banner}\n      </SidebarHeader>\n      <SidebarContent className=\"[scrollbar-width:thin] gap-0 px-2\">\n        {links.length > 0 && (\n          // shown in the navbar on desktop\n          <SidebarGroup className=\"lg:hidden\">\n            <SidebarGroupContent>\n              <SidebarMenu>\n                {links.map((item, i) => (\n                  <SidebarLinkItem key={i} item={item} />\n                ))}\n              </SidebarMenu>\n            </SidebarGroupContent>\n          </SidebarGroup>\n        )}\n        <SidebarPageTree {...components} />\n      </SidebarContent>\n      {(iconLinks.length > 0 ||\n        languageSelect ||\n        themeSwitchEnabled ||\n        footer) && (\n        <SidebarFooter className={cn(\"p-4 pt-2\", !footer && footerItemsHidden)}>\n          {(iconLinks.length > 0 || languageSelect || themeSwitchEnabled) && (\n            <div\n              className={cn(\n                \"flex items-center text-muted-foreground\",\n                footerItemsHidden,\n              )}\n            >\n              {iconLinks.map((item, i) => (\n                <LinkItem\n                  key={i}\n                  item={item}\n                  className={cn(\n                    buttonVariants({ size: \"icon-sm\", variant: \"ghost\" }),\n                    \"lg:hidden [&_svg]:size-4\",\n                  )}\n                  aria-label={item.label}\n                >\n                  {item.icon}\n                </LinkItem>\n              ))}\n              {languageSelect && (\n                <LanguageSelect className=\"ms-auto md:hidden\">\n                  <Languages />\n                </LanguageSelect>\n              )}\n              {themeSwitchEnabled && (\n                <ThemeSwitch\n                  {...themeSwitchProps}\n                  className={cn(\n                    \"md:hidden\",\n                    !languageSelect && \"ms-auto\",\n                    themeSwitchProps.className,\n                  )}\n                />\n              )}\n            </div>\n          )}\n          {footer}\n        </SidebarFooter>\n      )}\n      {collapsible && <SidebarRail />}\n    </SidebarRoot>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/docs/layouts/notebook/slots/sidebar.tsx"
    },
    {
      "path": "registry/base/docs/layouts/notebook/slots/container.tsx",
      "content": "// Adapted from Fumadocs UI (https://github.com/fuma-nama/fumadocs)\n// Copyright (c) 2023 Fuma, MIT License\n\"use client\";\n\nimport { cn } from \"cn\";\nimport type { ComponentProps } from \"react\";\n\n/**\n * Wraps the navbar, sidebar and page. It sets `--docs-header-height`, the\n * height of the navbar (taller with layout tabs below it), which the sidebar\n * and pages use to offset sticky elements.\n */\nexport function Container({\n  navEnabled = true,\n  className,\n  ...props\n}: ComponentProps<\"div\"> & {\n  navEnabled?: boolean;\n}) {\n  return (\n    <div\n      id=\"nd-notebook-layout\"\n      {...props}\n      className={cn(\n        \"flex w-full min-w-0 flex-col [--docs-header-height:0px]\",\n        navEnabled &&\n          \"[--docs-header-height:--spacing(14)] lg:has-data-header-tabs:[--docs-header-height:--spacing(24)]\",\n        className,\n      )}\n    />\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/docs/layouts/notebook/slots/container.tsx"
    }
  ],
  "type": "registry:component"
}