From d136d38deb79dd51a376d434b40b5af49ac7ef44 Mon Sep 17 00:00:00 2001 From: Carla Goncalves Date: Tue, 29 Jul 2025 12:58:46 +0100 Subject: [PATCH 1/6] Add new dropdown to toc section --- src/components/Icon.tsx | 14 ++- src/components/content-dropdown/index.tsx | 83 +++++++++++++ .../content-dropdown/styles.module.scss | 105 ++++++++++++++++ src/css/all.css | 8 ++ src/css/theming.css | 5 +- src/theme/DocBreadcrumbs/index.tsx | 2 +- src/theme/DocItem/Content/index.js | 114 ------------------ src/theme/DocItem/Layout/index.tsx | 69 +++++++++++ src/theme/DocItem/Layout/styles.module.css | 10 ++ src/theme/DocItem/Metadata/index.tsx | 27 ----- src/theme/DocItem/TOC/Desktop/index.tsx | 17 +++ src/theme/TOC/index.tsx | 52 ++++++++ src/theme/TOC/styles.module.css | 20 +++ src/theme/TOCItems/icons.tsx | 29 +++++ src/theme/Tabs/index.tsx | 2 - 15 files changed, 409 insertions(+), 148 deletions(-) create mode 100644 src/components/content-dropdown/index.tsx create mode 100644 src/components/content-dropdown/styles.module.scss delete mode 100644 src/theme/DocItem/Content/index.js create mode 100644 src/theme/DocItem/Layout/index.tsx create mode 100644 src/theme/DocItem/Layout/styles.module.css delete mode 100644 src/theme/DocItem/Metadata/index.tsx create mode 100644 src/theme/DocItem/TOC/Desktop/index.tsx create mode 100644 src/theme/TOC/index.tsx create mode 100644 src/theme/TOC/styles.module.css create mode 100644 src/theme/TOCItems/icons.tsx diff --git a/src/components/Icon.tsx b/src/components/Icon.tsx index 0c24fbc76b..ef2d142ef6 100644 --- a/src/components/Icon.tsx +++ b/src/components/Icon.tsx @@ -2,7 +2,8 @@ import clsx from "clsx"; import React, { useEffect, useRef, useState } from "react"; interface IconProps { - icon: string; + icon?: string; + customicon?: any; color?: string; className?: string; size?: string; @@ -10,7 +11,7 @@ interface IconProps { fit?: "width" | "height"; } -export const Icon = ({ icon, color, className, size, btn, fit }: IconProps) => { +export const Icon = ({ customicon, icon, color, className, size, btn, fit }: IconProps) => { const iconRef = useRef(null); const [font, setFontSize] = useState(0); const [measure, setMeasure] = useState("vw"); @@ -34,8 +35,15 @@ export const Icon = ({ icon, color, className, size, btn, fit }: IconProps) => { window.addEventListener("resize", setFont); return () => window.removeEventListener("resize", setFont); }, []); + return ( - {customicon} : ; + anchorText: string; + dark?: boolean; + rightClick?: boolean; + pos?: "top" | "bottom"; +}; +const Dropdown = ({ + anchorText, + items, + dark = false, + rightClick = false, + pos = "bottom", +}: DropdownType) => { + const [isOpen, openDrop] = useState(false); + const { ref, isComponentVisible, setIsComponentVisible } = useComponentVisible(true); + + useEffect(() => { + if (!isComponentVisible) openDrop(false); + }, [isComponentVisible]); + + const escEvent = (e: KeyboardEvent) => { + if (e.key === "Escape") openDrop(false); + }; + + useEffect(() => { + window.addEventListener("keydown", escEvent); + return () => window.removeEventListener("keydown", escEvent); + }, []); + + return ( +
{ + if (!rightClick) { + setIsComponentVisible(true); + openDrop(!isOpen); + } + }} + onContextMenu={(e) => { + if (rightClick && window.innerWidth > 940) { + e.preventDefault(); + setIsComponentVisible(true); + openDrop(true); + } + }} + > +
+ + {anchorText} + +
+
{ + e.stopPropagation(); + openDrop(false); + }} + > +
+ {items.map((item: any, idx: number) => ( +
+ {item} +
+ ))} +
+
+
+ ); +}; + +export default Dropdown; diff --git a/src/components/content-dropdown/styles.module.scss b/src/components/content-dropdown/styles.module.scss new file mode 100644 index 0000000000..cf469dda4d --- /dev/null +++ b/src/components/content-dropdown/styles.module.scss @@ -0,0 +1,105 @@ +$border-color: #2d3748; + +.root { + position: relative; + color: var(--primary-font-color); + font-family: var(--font-family-body, Inter); + font-size: var(--font-size-xs, 14px); + font-style: normal; + font-weight: 400; + line-height: 140%; /* 19.6px */ + width: fit-content; + position: absolute; + right: 0; + top: 0; +} + +.anchor { + border-radius: 8px; + padding: 4px 8px; + cursor: pointer; + width: fit-content; + border: 1px solid var(--disabled-font-color); + background: var(--surface-primary); + &.active { + background: var(--surface-brand-grey); + } +} + +.overlayWrapper { + opacity: 0; + pointer-events: none; + @media (max-width: 599px) { + position: fixed; + height: 100vh; + z-index: 102; + width: 100vw; + background: rgb(9, 10, 21, 0.75); + top: 0; + left: 0; + } + .container { + transform: translateY(-8px); + } + &.showOverlay { + .container { + transform: translateY(0); + } + } +} + +.showOverlay { + opacity: 1; + pointer-events: auto; +} + +.container { + background: var(--surface-primary); + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.10), 0 2px 4px -2px rgba(0, 0, 0, 0.10); + border-radius: 8px; + bottom: 0; + position: absolute; + width: 100%; + overflow: hidden; + right: 0; + transition: transform 300ms ease; + display: flex; + flex-direction: column; + gap: 8px; + @media (min-width: 600px) { + top: 100%; + margin-top: 16px; + bottom: unset; + width: auto; + } +} + +.item { + color: var(--primary-font-color); + width: max-content; + min-width: 100%; + cursor: pointer; + padding: 6px 12px; + background: var(--surface-primary); + transition: background 300ms ease-out; + &:hover { + background: var(--surface-brand-grey-strong); + } +} + +.topPos { + @media (min-width: 600px) { + top: unset !important; + left: 0 !important; + transform: unset !important; + bottom: 100% !important; + } + & > * { + width: 100%; + display: inline-block; + } + + a { + color: inherit; + } +} diff --git a/src/css/all.css b/src/css/all.css index c24242ad49..d5b3294268 100644 --- a/src/css/all.css +++ b/src/css/all.css @@ -844,6 +844,14 @@ content: "\f09b"; } +.fa-markdown::before { + content: "\f60f"; +} + +.fa-openai::before { + content: "\e7cf"; +} + .fa-globe::before { content: "\f0ac"; } diff --git a/src/css/theming.css b/src/css/theming.css index e0fa8efea6..28ead3d261 100644 --- a/src/css/theming.css +++ b/src/css/theming.css @@ -69,11 +69,11 @@ --surface-brand-light: #d9f9f6; --primary-font-color: var(--gray-800); --surface-primary: #ffffff; + --disabled-font-color: #CBD5E0; --navbar-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.1); --navbar-gradient: linear-gradient(180deg, #fff, transparent); --navbar-items-bg: #ffffffcc; --surface-secondary: #2d3748; - --surface-primary: #fff; --secondary-font-color: #4a5568; --tertiary-font-color: #718096; --ifm-dropdown-background-color: #fff; @@ -222,6 +222,7 @@ html[data-theme="dark"] { --ifm-tabs-bg-color-active: #2d3748; --main-font-color: #e2e8f0; --primary-font-color: rgb(247, 250, 252); + --disabled-font-color: #4A5568; --surface-primary: var(--gray-1000); --navbar-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.5); --navbar-gradient: linear-gradient(180deg, #090a15, rgba(9, 10, 21, 0)); @@ -363,6 +364,7 @@ html[data-theme="dark"] { --navbar-items-bg: #ffffffcc; --surface-secondary: #2d3748; --surface-primary: #ffffff; + --disabled-font-color: #CBD5E0; --icon-wrapper-bg: rgb(5, 7, 10); --icon-svg-color: #5a67d8; --teal-link-color: #16a394; @@ -493,6 +495,7 @@ html[data-theme="dark"] { --ifm-tabs-bg-color-active: #2d3748; --main-font-color: #e2e8f0; --primary-font-color: rgb(247, 250, 252); + --disabled-font-color: #4A5568; --surface-primary: var(--gray-1000); --navbar-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.5); --navbar-gradient: linear-gradient(180deg, #090a15, rgba(9, 10, 21, 0)); diff --git a/src/theme/DocBreadcrumbs/index.tsx b/src/theme/DocBreadcrumbs/index.tsx index 093c252db7..9524377550 100644 --- a/src/theme/DocBreadcrumbs/index.tsx +++ b/src/theme/DocBreadcrumbs/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React from "react"; import clsx from "clsx"; import { ThemeClassNames } from "@docusaurus/theme-common"; import { useHomePageRoute } from "@docusaurus/theme-common/internal"; diff --git a/src/theme/DocItem/Content/index.js b/src/theme/DocItem/Content/index.js deleted file mode 100644 index 7bd75b3819..0000000000 --- a/src/theme/DocItem/Content/index.js +++ /dev/null @@ -1,114 +0,0 @@ -import React from "react"; -import clsx from "clsx"; -import { ThemeClassNames } from "@docusaurus/theme-common"; -import { useDoc } from "@docusaurus/plugin-content-docs/client"; -import Heading from "@theme/Heading"; -import MDXContent from "@theme/MDXContent"; -import TopSection from "@site/src/components/topSection"; -import { useLocation } from "@docusaurus/router"; -/** - Title can be declared inside md content or declared through - front matter and added manually. To make both cases consistent, - the added title is added under the same div.markdown block - See https://github.com/facebook/docusaurus/pull/4882#issuecomment-853021120 - - We render a "synthetic title" if: - - user doesn't ask to hide it with front matter - - the markdown content does not already contain a top-level h1 heading -*/ -function useSyntheticTitle() { - const { metadata, frontMatter, contentTitle } = useDoc(); - const shouldRender = !frontMatter.hide_title && typeof contentTitle === "undefined"; - if (!shouldRender) { - return null; - } - return metadata.title; -} -export default function DocItemContent({ children }) { - const { frontMatter } = useDoc(); - const syntheticTitle = useSyntheticTitle(); - const location = useLocation(); - return ( -
- {syntheticTitle && ( -
- {syntheticTitle} - {(frontMatter.langSwitcher || frontMatter.dbSwitcher) && ( -
- -
- )} - {frontMatter.completion_time && ( -
-
{frontMatter.completion_time}
-
- )} -
- )} - - {children}{" "} - {frontMatter.community_section && ( -
-
-

Stay connected with Prisma

-

- Continue your Prisma journey by connecting with{" "} - - {" "} - our active community - - . Stay informed, get involved, and collaborate with other developers: -
-

- We genuinely value your involvement and look forward to having you as part of our - community! -

-
- )} -
-
- ); -} diff --git a/src/theme/DocItem/Layout/index.tsx b/src/theme/DocItem/Layout/index.tsx new file mode 100644 index 0000000000..f192bf9cae --- /dev/null +++ b/src/theme/DocItem/Layout/index.tsx @@ -0,0 +1,69 @@ +import React, {type ReactNode} from 'react'; +import clsx from 'clsx'; +import {useWindowSize} from '@docusaurus/theme-common'; +import {useDoc} from '@docusaurus/plugin-content-docs/client'; +import DocItemPaginator from '@theme/DocItem/Paginator'; +import DocVersionBanner from '@theme/DocVersionBanner'; +import DocVersionBadge from '@theme/DocVersionBadge'; +import DocItemFooter from '@theme/DocItem/Footer'; +import DocItemTOCMobile from '@theme/DocItem/TOC/Mobile'; +import DocItemTOCDesktop from '@theme/DocItem/TOC/Desktop'; +import DocItemContent from '@theme/DocItem/Content'; +import DocBreadcrumbs from '@theme/DocBreadcrumbs'; +import ContentVisibility from '@theme/ContentVisibility'; +import type {Props} from '@theme/DocItem/Layout'; + +import styles from './styles.module.css'; + +/** + * Decide if the toc should be rendered, on mobile or desktop viewports + */ +function useDocTOC() { + const {frontMatter, toc} = useDoc(); + const windowSize = useWindowSize(); + + const hidden = frontMatter.hide_table_of_contents; + const canRender = !hidden && toc.length > 0; + + const mobile = canRender ? : undefined; + + const desktop = + canRender && (windowSize === 'desktop' || windowSize === 'ssr') ? ( + + ) : undefined; + + return { + hidden, + mobile, + desktop, + }; +} + +export default function DocItemLayout({children}: Props): ReactNode { + const docTOC = useDocTOC(); + const {metadata} = useDoc(); + return ( +
+
+ + +
+
+ + + {docTOC.mobile} + {children} + +
+ +
+
+ {docTOC.desktop &&
+ {React.cloneElement(docTOC.desktop as React.ReactElement, { + //@ts-ignore + metadata, + })} +
} +
+ ); +} diff --git a/src/theme/DocItem/Layout/styles.module.css b/src/theme/DocItem/Layout/styles.module.css new file mode 100644 index 0000000000..d5aaec1322 --- /dev/null +++ b/src/theme/DocItem/Layout/styles.module.css @@ -0,0 +1,10 @@ +.docItemContainer header + *, +.docItemContainer article > *:first-child { + margin-top: 0; +} + +@media (min-width: 997px) { + .docItemCol { + max-width: 75% !important; + } +} diff --git a/src/theme/DocItem/Metadata/index.tsx b/src/theme/DocItem/Metadata/index.tsx deleted file mode 100644 index e2ecb866f3..0000000000 --- a/src/theme/DocItem/Metadata/index.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from "react"; -import { PageMetadata } from "@docusaurus/theme-common"; -import { useDoc } from "@docusaurus/plugin-content-docs/client"; - -import type { DocFrontMatter } from "@docusaurus/plugin-content-docs"; - -type PrismaDocFrontMatter = DocFrontMatter & { - metaTitle: string; - metaDescription: string; -}; - -export default function DocItemMetadata(): JSX.Element { - const { metadata, frontMatter, assets } = useDoc(); - const prismaFrontMatter = frontMatter as PrismaDocFrontMatter; - - const title = prismaFrontMatter.metaTitle ?? prismaFrontMatter.title ?? metadata.title; - const description = prismaFrontMatter.metaDescription ?? metadata.description; - const keywords = prismaFrontMatter.keywords; - const image = assets.image ?? prismaFrontMatter.image; - - return ( - - - - - ); -} diff --git a/src/theme/DocItem/TOC/Desktop/index.tsx b/src/theme/DocItem/TOC/Desktop/index.tsx new file mode 100644 index 0000000000..ee13bced27 --- /dev/null +++ b/src/theme/DocItem/TOC/Desktop/index.tsx @@ -0,0 +1,17 @@ +import React, {type ReactNode} from 'react'; +import {ThemeClassNames} from '@docusaurus/theme-common'; +import {useDoc} from '@docusaurus/plugin-content-docs/client'; +import TOC from '@site/src/theme/TOC'; + +export default function DocItemTOCDesktop({metadata}: any): ReactNode { + const {toc, frontMatter} = useDoc(); + return ( + + ); +} diff --git a/src/theme/TOC/index.tsx b/src/theme/TOC/index.tsx new file mode 100644 index 0000000000..8e3f8d83b9 --- /dev/null +++ b/src/theme/TOC/index.tsx @@ -0,0 +1,52 @@ +import TOCItems from '@theme/TOCItems'; +import clsx from 'clsx'; +import React, { type ReactNode } from 'react'; +import Dropdown from '@site/src/components/content-dropdown'; +import { Icon } from '@site/src/components/Icon'; + +import type {Props} from '@theme/TOC'; + +import styles from './styles.module.css'; +import { anthropic, cursor, openai } from '../TOCItems/icons'; + +// Using a custom className +// This prevents TOCInline/TOCCollapsible getting highlighted by mistake +const LINK_CLASS_NAME = 'table-of-contents__link toc-highlight'; +const LINK_ACTIVE_CLASS_NAME = 'table-of-contents__link--active'; + +export default function TOC({className, metadata, ...props}: Props & {metadata: any }): ReactNode { + return ( + + ); +} diff --git a/src/theme/TOC/styles.module.css b/src/theme/TOC/styles.module.css new file mode 100644 index 0000000000..d02c7ba954 --- /dev/null +++ b/src/theme/TOC/styles.module.css @@ -0,0 +1,20 @@ +.tableOfContentsWrapper { + max-height: calc(100vh - (var(--ifm-navbar-height) + 2rem)); + position: sticky; + top: calc(var(--ifm-navbar-height) + 1rem); +} + +.tableOfContents { + overflow-y: auto; + overflow-x: visible; +} + +@media (max-width: 996px) { + .tableOfContents { + display: none; + } + + .docItemContainer { + padding: 0 0.3rem; + } +} diff --git a/src/theme/TOCItems/icons.tsx b/src/theme/TOCItems/icons.tsx new file mode 100644 index 0000000000..0564ce7667 --- /dev/null +++ b/src/theme/TOCItems/icons.tsx @@ -0,0 +1,29 @@ +export const openai = ; + +export const anthropic = + + +; + +export const cursor = + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/theme/Tabs/index.tsx b/src/theme/Tabs/index.tsx index acada1426f..0007c0d592 100644 --- a/src/theme/Tabs/index.tsx +++ b/src/theme/Tabs/index.tsx @@ -93,7 +93,6 @@ function TabContent({ } return cloneElement(selectedTabItem, { className: "margin-top--md" }); } - console.log("code: " + code) return (
From 926e668c877edfbde8ce4acbb286f37a44297ff5 Mon Sep 17 00:00:00 2001 From: Carla Goncalves Date: Tue, 29 Jul 2025 15:31:39 +0100 Subject: [PATCH 2/6] Update hrefs on dropdown --- src/theme/TOC/index.tsx | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/theme/TOC/index.tsx b/src/theme/TOC/index.tsx index 8e3f8d83b9..d8d6dacccb 100644 --- a/src/theme/TOC/index.tsx +++ b/src/theme/TOC/index.tsx @@ -1,8 +1,8 @@ -import TOCItems from '@theme/TOCItems'; -import clsx from 'clsx'; -import React, { type ReactNode } from 'react'; import Dropdown from '@site/src/components/content-dropdown'; import { Icon } from '@site/src/components/Icon'; +import TOCItems from '@theme/TOCItems'; +import clsx from 'clsx'; +import React, { ReactNode } from 'react'; import type {Props} from '@theme/TOC'; @@ -13,28 +13,35 @@ import { anthropic, cursor, openai } from '../TOCItems/icons'; // This prevents TOCInline/TOCCollapsible getting highlighted by mistake const LINK_CLASS_NAME = 'table-of-contents__link toc-highlight'; const LINK_ACTIVE_CLASS_NAME = 'table-of-contents__link--active'; +const getMarkdown = async (link: string) => { + const response = await fetch(link); + const mdx = await response.text(); + navigator.clipboard.writeText(mdx); + return mdx; +} export default function TOC({className, metadata, ...props}: Props & {metadata: any }): ReactNode { + const url = `https://prisma.io/docs${metadata.slug}`; + const externalProps = { + target:'__blank', + rel:'openeer noreferrer' + } + const markdown = metadata.editUrl.replace("github", "raw.githubusercontent").replace("/blob", "").replace("/tree", ""); return (
Copy as Markdown, - +
getMarkdown(markdown)}>Copy as Markdown
, +
Open in Claude , - + Open in ChatGPT , - - - Open in Cursor - - , - + Edit in GitHub From cd3c8dfd1802057c7be1c22cf0ed9e349755e5cd Mon Sep 17 00:00:00 2001 From: Carla Goncalves Date: Tue, 29 Jul 2025 16:11:12 +0100 Subject: [PATCH 3/6] Update icons and add T3 --- src/theme/TOC/index.tsx | 8 +++++++- src/theme/TOCItems/icons.tsx | 9 ++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/theme/TOC/index.tsx b/src/theme/TOC/index.tsx index d8d6dacccb..7e88d628b1 100644 --- a/src/theme/TOC/index.tsx +++ b/src/theme/TOC/index.tsx @@ -7,7 +7,7 @@ import React, { ReactNode } from 'react'; import type {Props} from '@theme/TOC'; import styles from './styles.module.css'; -import { anthropic, cursor, openai } from '../TOCItems/icons'; +import { anthropic, cursor, openai, t3 } from '../TOCItems/icons'; // Using a custom className // This prevents TOCInline/TOCCollapsible getting highlighted by mistake @@ -45,7 +45,13 @@ export default function TOC({className, metadata, ...props}: Props & {metadata: Edit in GitHub + , + + + Open in T3.chat + + ]} />
- \ No newline at end of file + + +export const t3 = + + + + + From e2d80abcf20d99d9280562f17339368e4b4b7df5 Mon Sep 17 00:00:00 2001 From: Carla Goncalves Date: Wed, 30 Jul 2025 08:35:54 +0100 Subject: [PATCH 4/6] Update link text Update dropdown order --- src/theme/TOC/index.tsx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/theme/TOC/index.tsx b/src/theme/TOC/index.tsx index 7e88d628b1..c79ab5b625 100644 --- a/src/theme/TOC/index.tsx +++ b/src/theme/TOC/index.tsx @@ -36,22 +36,21 @@ export default function TOC({className, metadata, ...props}: Props & {metadata: Open in Claude , - + Open in ChatGPT , - - - Edit in GitHub - - , Open in T3.chat + , + + + Edit in GitHub + - ]} />
Date: Fri, 1 Aug 2025 14:19:57 +0100 Subject: [PATCH 5/6] revert deleted files --- src/theme/DocItem/Content/index.js | 114 +++++++++++++++++++++++++++ src/theme/DocItem/Metadata/index.tsx | 27 +++++++ 2 files changed, 141 insertions(+) create mode 100644 src/theme/DocItem/Content/index.js create mode 100644 src/theme/DocItem/Metadata/index.tsx diff --git a/src/theme/DocItem/Content/index.js b/src/theme/DocItem/Content/index.js new file mode 100644 index 0000000000..7bd75b3819 --- /dev/null +++ b/src/theme/DocItem/Content/index.js @@ -0,0 +1,114 @@ +import React from "react"; +import clsx from "clsx"; +import { ThemeClassNames } from "@docusaurus/theme-common"; +import { useDoc } from "@docusaurus/plugin-content-docs/client"; +import Heading from "@theme/Heading"; +import MDXContent from "@theme/MDXContent"; +import TopSection from "@site/src/components/topSection"; +import { useLocation } from "@docusaurus/router"; +/** + Title can be declared inside md content or declared through + front matter and added manually. To make both cases consistent, + the added title is added under the same div.markdown block + See https://github.com/facebook/docusaurus/pull/4882#issuecomment-853021120 + + We render a "synthetic title" if: + - user doesn't ask to hide it with front matter + - the markdown content does not already contain a top-level h1 heading +*/ +function useSyntheticTitle() { + const { metadata, frontMatter, contentTitle } = useDoc(); + const shouldRender = !frontMatter.hide_title && typeof contentTitle === "undefined"; + if (!shouldRender) { + return null; + } + return metadata.title; +} +export default function DocItemContent({ children }) { + const { frontMatter } = useDoc(); + const syntheticTitle = useSyntheticTitle(); + const location = useLocation(); + return ( +
+ {syntheticTitle && ( +
+ {syntheticTitle} + {(frontMatter.langSwitcher || frontMatter.dbSwitcher) && ( +
+ +
+ )} + {frontMatter.completion_time && ( +
+
{frontMatter.completion_time}
+
+ )} +
+ )} + + {children}{" "} + {frontMatter.community_section && ( +
+
+

Stay connected with Prisma

+

+ Continue your Prisma journey by connecting with{" "} + + {" "} + our active community + + . Stay informed, get involved, and collaborate with other developers: +
+

+ We genuinely value your involvement and look forward to having you as part of our + community! +

+
+ )} +
+
+ ); +} diff --git a/src/theme/DocItem/Metadata/index.tsx b/src/theme/DocItem/Metadata/index.tsx new file mode 100644 index 0000000000..e2ecb866f3 --- /dev/null +++ b/src/theme/DocItem/Metadata/index.tsx @@ -0,0 +1,27 @@ +import React from "react"; +import { PageMetadata } from "@docusaurus/theme-common"; +import { useDoc } from "@docusaurus/plugin-content-docs/client"; + +import type { DocFrontMatter } from "@docusaurus/plugin-content-docs"; + +type PrismaDocFrontMatter = DocFrontMatter & { + metaTitle: string; + metaDescription: string; +}; + +export default function DocItemMetadata(): JSX.Element { + const { metadata, frontMatter, assets } = useDoc(); + const prismaFrontMatter = frontMatter as PrismaDocFrontMatter; + + const title = prismaFrontMatter.metaTitle ?? prismaFrontMatter.title ?? metadata.title; + const description = prismaFrontMatter.metaDescription ?? metadata.description; + const keywords = prismaFrontMatter.keywords; + const image = assets.image ?? prismaFrontMatter.image; + + return ( + + + + + ); +} From 86bfb925a9cf99575b746ae423348628869b1890 Mon Sep 17 00:00:00 2001 From: Carla Goncalves Date: Mon, 4 Aug 2025 11:03:20 +0100 Subject: [PATCH 6/6] cleanup --- src/components/content-dropdown/styles.module.scss | 1 - src/theme/TOC/index.tsx | 14 +++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/components/content-dropdown/styles.module.scss b/src/components/content-dropdown/styles.module.scss index cf469dda4d..109943c2f6 100644 --- a/src/components/content-dropdown/styles.module.scss +++ b/src/components/content-dropdown/styles.module.scss @@ -1,7 +1,6 @@ $border-color: #2d3748; .root { - position: relative; color: var(--primary-font-color); font-family: var(--font-family-body, Inter); font-size: var(--font-size-xs, 14px); diff --git a/src/theme/TOC/index.tsx b/src/theme/TOC/index.tsx index c79ab5b625..fa94c101be 100644 --- a/src/theme/TOC/index.tsx +++ b/src/theme/TOC/index.tsx @@ -23,30 +23,30 @@ const getMarkdown = async (link: string) => { export default function TOC({className, metadata, ...props}: Props & {metadata: any }): ReactNode { const url = `https://prisma.io/docs${metadata.slug}`; const externalProps = { - target:'__blank', - rel:'openeer noreferrer' + target: '_blank', + rel: 'opener noreferrer' } const markdown = metadata.editUrl.replace("github", "raw.githubusercontent").replace("/blob", "").replace("/tree", ""); return (
getMarkdown(markdown)}>Copy as Markdown
, - +
getMarkdown(markdown)}>Copy as Markdown
, +
Open in Claude , - + Open in ChatGPT , - + Open in T3.chat , - + Edit in GitHub