docs: add LLM dropdown menu to documentation pages (#12235)
* docs: add LLM dropdown menu to documentation pages * fix build errors
This commit is contained in:
@@ -1,19 +1,24 @@
|
||||
import clsx from "clsx"
|
||||
import React from "react"
|
||||
import { LlmDropdown } from "../../LlmDropdown"
|
||||
|
||||
type H1Props = React.HTMLAttributes<HTMLHeadingElement> & {
|
||||
id?: string
|
||||
hideLlmDropdown?: boolean
|
||||
}
|
||||
|
||||
export const H1 = ({ className, ...props }: H1Props) => {
|
||||
export const H1 = ({ className, hideLlmDropdown, ...props }: H1Props) => {
|
||||
return (
|
||||
<h1
|
||||
className={clsx(
|
||||
"h1-docs [&_code]:!h1-docs [&_code]:!font-mono mb-docs_1 text-medusa-fg-base",
|
||||
props.id && "scroll-m-docs_7",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<h1
|
||||
className={clsx(
|
||||
"h1-docs [&_code]:!h1-docs [&_code]:!font-mono mb-docs_1 text-medusa-fg-base",
|
||||
props.id && "scroll-m-docs_7",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
{!hideLlmDropdown && <LlmDropdown />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
25
www/packages/docs-ui/src/components/Icons/Markdown/index.tsx
Normal file
25
www/packages/docs-ui/src/components/Icons/Markdown/index.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from "react"
|
||||
import { IconProps } from "@medusajs/icons/dist/types"
|
||||
|
||||
export const MarkdownIcon = (props: IconProps) => {
|
||||
return (
|
||||
<svg
|
||||
fill="currentColor"
|
||||
viewBox="0 0 32 32"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={15}
|
||||
height={15}
|
||||
{...props}
|
||||
>
|
||||
<g id="SVGRepo_bgCarrier" strokeWidth="0"></g>
|
||||
<g
|
||||
id="SVGRepo_tracerCarrier"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
></g>
|
||||
<g id="SVGRepo_iconCarrier">
|
||||
<path d="M 2.875 6 C 1.320313 6 0 7.253906 0 8.8125 L 0 23.1875 C 0 24.746094 1.320313 26 2.875 26 L 29.125 26 C 30.679688 26 32 24.746094 32 23.1875 L 32 8.8125 C 32 7.253906 30.679688 6 29.125 6 Z M 2.875 8 L 29.125 8 C 29.640625 8 30 8.382813 30 8.8125 L 30 23.1875 C 30 23.617188 29.640625 24 29.125 24 L 2.875 24 C 2.359375 24 2 23.617188 2 23.1875 L 2 8.8125 C 2 8.382813 2.359375 8 2.875 8 Z M 5 11 L 5 21 L 8 21 L 8 14.34375 L 11 18.3125 L 14 14.34375 L 14 21 L 17 21 L 17 11 L 14 11 L 11 15 L 8 11 Z M 22 11 L 22 16 L 19 16 L 23.5 21 L 28 16 L 25 16 L 25 11 Z"></path>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
72
www/packages/docs-ui/src/components/LlmDropdown/index.tsx
Normal file
72
www/packages/docs-ui/src/components/LlmDropdown/index.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
"use client"
|
||||
|
||||
import React, { useRef, useState } from "react"
|
||||
import { useAiAssistant, useSiteConfig } from "../../providers"
|
||||
import { usePathname } from "next/navigation"
|
||||
import { Button } from "../Button"
|
||||
import { AiAssistent, Book } from "@medusajs/icons"
|
||||
import { Menu } from "../Menu"
|
||||
import { MarkdownIcon } from "../Icons/Markdown"
|
||||
import { useAiAssistantChat } from "../../providers/AiAssistant/Chat"
|
||||
import clsx from "clsx"
|
||||
import { useClickOutside } from "../.."
|
||||
|
||||
export const LlmDropdown = () => {
|
||||
const {
|
||||
config: { baseUrl, basePath },
|
||||
} = useSiteConfig()
|
||||
const pathname = usePathname()
|
||||
const [open, setOpen] = useState(false)
|
||||
const { setChatOpened } = useAiAssistant()
|
||||
const { setQuestion, loading } = useAiAssistantChat()
|
||||
const ref = useRef<HTMLButtonElement | null>(null)
|
||||
useClickOutside({
|
||||
elmRef: ref,
|
||||
onClickOutside: () => {
|
||||
setOpen(false)
|
||||
},
|
||||
})
|
||||
|
||||
const pageUrl = `${baseUrl}${basePath}${pathname}`
|
||||
|
||||
return (
|
||||
<div className="relative hidden md:block">
|
||||
<Button
|
||||
variant="transparent"
|
||||
onClick={() => setOpen(!open)}
|
||||
className="!p-[6px] text-medusa-fg-subtle"
|
||||
buttonRef={ref}
|
||||
>
|
||||
<Book />
|
||||
</Button>
|
||||
<Menu
|
||||
items={[
|
||||
{
|
||||
type: "link",
|
||||
title: "View as Markdown",
|
||||
link: `${pageUrl}/index.html.md`,
|
||||
icon: <MarkdownIcon width={19} height={19} />,
|
||||
openInNewTab: true,
|
||||
},
|
||||
{
|
||||
type: "action",
|
||||
title: "Ask AI Assistant",
|
||||
action: () => {
|
||||
if (loading) {
|
||||
return
|
||||
}
|
||||
setQuestion(`Explain the page ${pageUrl}`)
|
||||
setChatOpened(true)
|
||||
setOpen(false)
|
||||
},
|
||||
icon: <AiAssistent />,
|
||||
},
|
||||
]}
|
||||
className={clsx(
|
||||
"absolute right-0 top-[calc(100%+8px)] w-max",
|
||||
!open && "hidden"
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -22,6 +22,8 @@ export const MenuItem = ({ item, onClick }: MenuItemProps) => {
|
||||
)}
|
||||
href={item.link}
|
||||
onClick={() => onClick?.(item)}
|
||||
target={item.openInNewTab ? "_blank" : undefined}
|
||||
rel={item.openInNewTab ? "noopener noreferrer" : undefined}
|
||||
>
|
||||
{item.icon && (
|
||||
<span className="text-medusa-fg-subtle mt-[2.5px] block">
|
||||
|
||||
Reference in New Issue
Block a user