From b37e8b09757062df62dc32e894f81d2b29932341 Mon Sep 17 00:00:00 2001 From: Suhaha Date: Thu, 18 Dec 2025 15:15:02 +0800 Subject: [PATCH 1/5] feat: implement new LeftNav and RightNav components for improved navigation - Introduced LeftNavDesktop and LeftNavMobile components to enhance the layout and navigation experience. - Added RightNav and RightNavMobile components for better accessibility and organization of content. - Integrated a new H1 component with TitleAction for enhanced header functionality. - Updated translation strings and styles for consistency across the application. - Removed the deprecated Contributors component to streamline the codebase. --- locale/en/translation.json | 2 +- src/components/Contributors/index.tsx | 251 ---------------- .../{Navigation => LeftNav}/LeftNav.tsx | 0 .../{Navigation => LeftNav}/LeftNavTree.tsx | 0 .../RightNav.tsx => RightNav/RightNav.bk.tsx} | 0 src/components/Layout/RightNav/RightNav.tsx | 269 ++++++++++++++++++ .../Layout/TitleAction/TitleAction.tsx | 242 ++++++++++++++++ src/components/MDXComponents/H1.module.css | 3 + .../MDXComponents/H1.module.css.d.ts | 2 + src/components/MDXComponents/H1.tsx | 22 ++ src/components/MDXContent.tsx | 27 +- src/media/icons/copy.svg | 3 + src/media/icons/edit.svg | 3 + src/media/icons/file.svg | 3 + src/media/icons/markdown.svg | 3 + src/styles/docTemplate.css | 1 + src/templates/DocTemplate.tsx | 7 +- src/theme/index.tsx | 6 +- 18 files changed, 574 insertions(+), 270 deletions(-) delete mode 100644 src/components/Contributors/index.tsx rename src/components/Layout/{Navigation => LeftNav}/LeftNav.tsx (100%) rename src/components/Layout/{Navigation => LeftNav}/LeftNavTree.tsx (100%) rename src/components/Layout/{Navigation/RightNav.tsx => RightNav/RightNav.bk.tsx} (100%) create mode 100644 src/components/Layout/RightNav/RightNav.tsx create mode 100644 src/components/Layout/TitleAction/TitleAction.tsx create mode 100644 src/components/MDXComponents/H1.module.css create mode 100644 src/components/MDXComponents/H1.module.css.d.ts create mode 100644 src/components/MDXComponents/H1.tsx create mode 100644 src/media/icons/copy.svg create mode 100644 src/media/icons/edit.svg create mode 100644 src/media/icons/file.svg create mode 100644 src/media/icons/markdown.svg diff --git a/locale/en/translation.json b/locale/en/translation.json index 5efb5d0d..7a8afee4 100644 --- a/locale/en/translation.json +++ b/locale/en/translation.json @@ -40,7 +40,7 @@ }, "doc": { "notExist": "This doc does not exist", - "toc": "What's on this page", + "toc": "ON THIS PAGE", "download-pdf": "Download PDF", "improve": "Edit this page", "feedback": "Request docs changes", diff --git a/src/components/Contributors/index.tsx b/src/components/Contributors/index.tsx deleted file mode 100644 index 1a9a360f..00000000 --- a/src/components/Contributors/index.tsx +++ /dev/null @@ -1,251 +0,0 @@ -import * as React from "react"; -import * as ReactDOM from "react-dom"; -import axios from "axios"; -import Avatar from "@mui/material/Avatar"; -import AvatarGroup from "@mui/material/AvatarGroup"; -import Stack from "@mui/material/Stack"; -import Typography from "@mui/material/Typography"; -import Menu from "@mui/material/Menu"; -import MenuItem from "@mui/material/MenuItem"; -import Button from "@mui/material/Button"; - -import { PathConfig } from "shared/interface"; -import { getRepo } from "../../../gatsby/path"; -import { ThemeProvider } from "@mui/material"; -import theme from "theme/index"; -import { Link } from "gatsby"; - -export interface TotalAvatarsProps { - avatars: AvatarItem[]; -} - -export type AvatarItem = { - src: string; - alt: string; - id: string; - name: string; - pageUrl: string; -}; - -export default function TotalAvatars(props: TotalAvatarsProps) { - const { avatars } = props; - const [anchorEl, setAnchorEl] = React.useState(null); - - const open = Boolean(anchorEl); - const handleClick = (event: React.MouseEvent) => { - setAnchorEl(event.currentTarget); - }; - const handleClose = () => { - setAnchorEl(null); - }; - - return ( - - - - {avatars.map((avatar, index) => ( - - ))} - - - - - {avatars.map((avatar) => ( - - - - {avatar.name} - - - ))} - - - ); -} - -export const useTotalContributors = ( - pathConfig: PathConfig, - filePath: string -) => { - const [totalContributors, setTotalContributors] = React.useState< - AvatarItem[] - >([]); - const [loading, setLoading] = React.useState(true); - - const repo = React.useMemo(() => getRepo(pathConfig), [pathConfig]); - - const filterCommitAuthors = (commits: any[]) => { - // const authors: AvatarItem[] = []; - const authorLoginList: string[] = []; - const authors = commits.reduce( - (prev, commit): AvatarItem[] => { - if (!commit.author) { - return prev; - } - - const { - login, - avatar_url, - html_url, - }: { login: string; avatar_url: string; html_url: string } = - commit.author; - - if (login === "ti-chi-bot") { - return prev; - } - - if (!authorLoginList.includes(login)) { - authorLoginList.push(login); - prev.push({ - id: login, - src: avatar_url, - alt: login, - name: commit?.commit?.author?.name || login, - pageUrl: html_url, - }); - } - return prev; - }, - [] - ); - return authors; - }; - - React.useEffect(() => { - async function fetchLatestCommit() { - try { - setLoading(true); - const res = ( - await axios.get(`https://api.github.com/repos/${repo}/commits`, { - params: { - sha: pathConfig.branch, - path: filePath, - }, - }) - ).data; - - const results = filterCommitAuthors(res); - - setTotalContributors(results); - } catch (err) { - // TODO: perform error handling - console.error(`useTotalContributors`, err); - } finally { - setLoading(false); - } - } - pathConfig && filePath && fetchLatestCommit(); - }, [pathConfig, filePath]); - - React.useEffect(() => { - // Create a new node(a sibling node after h1) to render the total contributors - const mdTitleElement = document.querySelector(".markdown-body > h1"); - const contributorNode = document.createElement("div"); - const appendedNode = mdTitleElement?.parentElement?.insertBefore( - contributorNode, - mdTitleElement?.nextSibling - ); - - if (!!totalContributors.length) { - try { - appendedNode && - ReactDOM.render( - , - appendedNode - ); - } catch (error) {} - } - - return () => { - if (!appendedNode) { - return; - } - ReactDOM.unmountComponentAtNode(appendedNode); - // Check if the node is still a child of its parent before removing - if ( - appendedNode.parentNode && - appendedNode.parentNode.contains(appendedNode) - ) { - appendedNode.parentNode.removeChild(appendedNode); - } - }; - }, [totalContributors]); - - return { totalContributors, loading }; -}; diff --git a/src/components/Layout/Navigation/LeftNav.tsx b/src/components/Layout/LeftNav/LeftNav.tsx similarity index 100% rename from src/components/Layout/Navigation/LeftNav.tsx rename to src/components/Layout/LeftNav/LeftNav.tsx diff --git a/src/components/Layout/Navigation/LeftNavTree.tsx b/src/components/Layout/LeftNav/LeftNavTree.tsx similarity index 100% rename from src/components/Layout/Navigation/LeftNavTree.tsx rename to src/components/Layout/LeftNav/LeftNavTree.tsx diff --git a/src/components/Layout/Navigation/RightNav.tsx b/src/components/Layout/RightNav/RightNav.bk.tsx similarity index 100% rename from src/components/Layout/Navigation/RightNav.tsx rename to src/components/Layout/RightNav/RightNav.bk.tsx diff --git a/src/components/Layout/RightNav/RightNav.tsx b/src/components/Layout/RightNav/RightNav.tsx new file mode 100644 index 00000000..e6221a5f --- /dev/null +++ b/src/components/Layout/RightNav/RightNav.tsx @@ -0,0 +1,269 @@ +import * as React from "react"; +import { Trans } from "gatsby-plugin-react-i18next"; +import { useLocation } from "@reach/router"; +import Box from "@mui/material/Box"; +import Typography from "@mui/material/Typography"; +import { useTheme } from "@mui/material/styles"; +import Button from "@mui/material/Button"; +import Menu from "@mui/material/Menu"; +import MenuItem from "@mui/material/MenuItem"; +import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; + +import { TableOfContent, PathConfig, BuildType } from "shared/interface"; +import { transformCustomId, removeHtmlTag } from "shared/utils"; +import { sliceVersionMark } from "shared/utils/anchor"; + +interface RightNavProps { + toc?: TableOfContent[]; + pathConfig: PathConfig; + filePath: string; + buildType?: BuildType; + pageUrl?: string; + bannerVisible?: boolean; +} + +export default function RightNav(props: RightNavProps) { + const { toc = [], bannerVisible } = props; + + const theme = useTheme(); + + let { pathname } = useLocation(); + if (pathname.endsWith("/")) { + pathname = pathname.slice(0, -1); // unify client and ssr + } + + // Track active heading for scroll highlighting + const [activeId, setActiveId] = React.useState(""); + + React.useEffect(() => { + // Collect all heading IDs from the TOC + const headingIds: string[] = []; + const collectIds = (items: TableOfContent[]) => { + items.forEach((item) => { + if (item.url) { + const id = item.url.replace(/^#/, ""); + if (id) { + headingIds.push(id); + } + } + if (item?.items) { + collectIds(item.items); + } + }); + }; + collectIds(toc); + + if (headingIds.length === 0) return; + + // Create an intersection observer + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + setActiveId(entry.target.id); + } + }); + }, + { + rootMargin: "-80px 0px -80% 0px", + threshold: 0, + } + ); + + setTimeout(() => { + // Observe all heading elements + headingIds.forEach((id) => { + const element = document.getElementById(id); + if (element) { + observer.observe(element); + } + }); + }, 1000); + + // Cleanup + return () => { + headingIds.forEach((id) => { + const element = document.getElementById(id); + if (element) { + observer.unobserve(element); + } + }); + }; + }, [toc]); + + return ( + <> + + + + + + {generateToc(toc, 0, activeId)} + + + + ); +} + +const generateToc = (items: TableOfContent[], level = 0, activeId = "") => { + const theme = useTheme(); + + return ( + + {items.map((item) => { + const { url, title, items } = item; + const { label: newLabel, anchor: newAnchor } = transformCustomId( + title, + url + ); + const itemId = url?.replace(/^#/, "") || ""; + const isActive = itemId && itemId === activeId; + + return ( + + + {removeHtmlTag(newLabel)} + + {items && generateToc(items, level + 1, activeId)} + + ); + })} + + ); +}; + +export function RightNavMobile(props: RightNavProps) { + const { toc = [], pathConfig, filePath, buildType } = props; + + const [anchorEl, setAnchorEl] = React.useState(null); + const open = Boolean(anchorEl); + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + const handleClose = () => { + setAnchorEl(null); + }; + + const generateMobileTocList = (items: TableOfContent[], level = 0) => { + const result: { label: string; anchor: string; depth: number }[] = []; + items.forEach((item) => { + const { url, title, items: children } = item; + const { label: newLabel, anchor: newAnchor } = transformCustomId( + title, + url + ); + result.push({ + label: newLabel, + anchor: newAnchor, + depth: level, + }); + if (children) { + const childrenresult = generateMobileTocList(children, level + 1); + result.push(...childrenresult); + } + }); + return result; + }; + + return ( + + + + {generateMobileTocList(toc).map((item) => { + return ( + + + {item.label} + + + ); + })} + + + ); +} diff --git a/src/components/Layout/TitleAction/TitleAction.tsx b/src/components/Layout/TitleAction/TitleAction.tsx new file mode 100644 index 00000000..b3094403 --- /dev/null +++ b/src/components/Layout/TitleAction/TitleAction.tsx @@ -0,0 +1,242 @@ +import * as React from "react"; +import { useI18next } from "gatsby-plugin-react-i18next"; +import { useStaticQuery, graphql } from "gatsby"; +import copy from "copy-to-clipboard"; + +import Box from "@mui/material/Box"; +import Typography from "@mui/material/Typography"; +import Stack from "@mui/material/Stack"; +import { useTheme } from "@mui/material/styles"; +import Button from "@mui/material/Button"; +import Menu from "@mui/material/Menu"; +import MenuItem from "@mui/material/MenuItem"; +import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; + +import EditIcon from "media/icons/edit.svg"; +import CopyIcon from "media/icons/copy.svg"; +import MarkdownIcon from "media/icons/markdown.svg"; +import FileIcon from "media/icons/file.svg"; + +import { BuildType, PathConfig } from "shared/interface"; +import { calcPDFUrl, getPageType, getRepoFromPathCfg } from "shared/utils"; +import { Tooltip, Divider } from "@mui/material"; + +interface TitleActionProps { + pathConfig: PathConfig; + filePath: string; + pageUrl: string; + buildType: BuildType; + language: string; +} + +export const TitleAction = (props: TitleActionProps) => { + const { pathConfig, filePath, pageUrl, buildType, language } = props; + const { t } = useI18next(); + const theme = useTheme(); + const [contributeAnchorEl, setContributeAnchorEl] = + React.useState(null); + const [copied, setCopied] = React.useState(false); + const isArchive = buildType === "archive"; + const pageType = React.useMemo( + () => getPageType(language, pageUrl), + [pageUrl] + ); + + const contributeOpen = Boolean(contributeAnchorEl); + + // Get site metadata for feedback URL + const { site } = useStaticQuery(graphql` + query { + site { + siteMetadata { + siteUrl + } + } + } + `); + + const handleContributeClick = (event: React.MouseEvent) => { + setContributeAnchorEl(event.currentTarget); + }; + + const handleContributeClose = () => { + setContributeAnchorEl(null); + }; + + const handleCopyMarkdown = async () => { + if (!pageUrl) return; + + try { + // Fetch markdown content from public path + const markdownUrl = `${pageUrl}.md`; + const response = await fetch(markdownUrl); + if (response.ok) { + const markdownContent = await response.text(); + copy(markdownContent); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } + } catch (e) { + console.error("Failed to copy markdown:", e); + } + }; + + const handleViewMarkdown = () => { + if (!pageUrl) return; + window.open(`${pageUrl}.md`, "_blank"); + }; + + const handleDownloadPDF = () => { + if (!pathConfig) return; + const pdfUrl = `https://docs-download.pingcap.com/pdf/${calcPDFUrl( + pathConfig + )}`; + window.open(pdfUrl, "_blank"); + }; + + // Generate feedback URL + const feedbackUrl = React.useMemo(() => { + if (!pathConfig || !filePath) return null; + try { + return `https://github.com/${getRepoFromPathCfg( + pathConfig + )}/issues/new?body=File:%20[/${pathConfig.branch}/${filePath}](${ + site.siteMetadata.siteUrl + }${pageUrl})`; + } catch (e) { + return null; + } + }, [pathConfig, filePath, pageUrl, site.siteMetadata.siteUrl]); + + return ( + + } + > + {/* Contribute Menu */} + {!isArchive && ( + + + + {feedbackUrl && ( + + + {t("doc.feedback")} + + + )} + + + )} + + {/* Copy Markdown for LLM */} + {!isArchive && ( + + + + )} + + {/* View as Markdown */} + {!isArchive && ( + + )} + + {/* Download PDF */} + {pageType === "tidb" && language !== "ja" && ( + + )} + + ); +}; diff --git a/src/components/MDXComponents/H1.module.css b/src/components/MDXComponents/H1.module.css new file mode 100644 index 00000000..fac8326e --- /dev/null +++ b/src/components/MDXComponents/H1.module.css @@ -0,0 +1,3 @@ +.header-actions { + margin-bottom: 32px; +} diff --git a/src/components/MDXComponents/H1.module.css.d.ts b/src/components/MDXComponents/H1.module.css.d.ts new file mode 100644 index 00000000..7d1889c6 --- /dev/null +++ b/src/components/MDXComponents/H1.module.css.d.ts @@ -0,0 +1,2 @@ +// This file is automatically generated. Do not modify this file manually -- YOUR CHANGES WILL BE ERASED! +export const headerActions: string; diff --git a/src/components/MDXComponents/H1.tsx b/src/components/MDXComponents/H1.tsx new file mode 100644 index 00000000..51a343e9 --- /dev/null +++ b/src/components/MDXComponents/H1.tsx @@ -0,0 +1,22 @@ +import { TitleAction } from "components/Layout/TitleAction/TitleAction"; +import { headerActions } from "./H1.module.css"; +import { BuildType, PathConfig } from "shared/interface"; + +export const H1 = (props: { + children: React.ReactNode; + pathConfig: PathConfig; + filePath: string; + pageUrl: string; + buildType: BuildType; + language: string; +}) => { + const { children, ...restProps } = props; + return ( + <> +

{children}

+
+ +
+ + ); +}; diff --git a/src/components/MDXContent.tsx b/src/components/MDXContent.tsx index 615c03ba..87ccfc3e 100644 --- a/src/components/MDXContent.tsx +++ b/src/components/MDXContent.tsx @@ -8,17 +8,12 @@ import Box from "@mui/material/Box"; import * as MDXComponents from "components/MDXComponents"; import { CustomNotice } from "components/Card/CustomNotice"; -import { - PathConfig, - FrontMatter, - BuildType, - CloudPlan, -} from "shared/interface"; -import { useTotalContributors } from "components/Contributors"; +import { PathConfig, BuildType, CloudPlan } from "shared/interface"; import replaceInternalHref from "shared/utils/anchor"; import { Pre } from "components/MDXComponents/Pre"; import { useCustomContent } from "components/MDXComponents/CustomContent"; import { getPageType } from "shared/utils"; +import { H1 } from "./MDXComponents/H1"; export default function MDXContent(props: { data: any; @@ -26,7 +21,6 @@ export default function MDXContent(props: { name: string; pathConfig: PathConfig; filePath: string; - frontmatter: FrontMatter; availIn: string[]; language: string; buildType: BuildType; @@ -39,7 +33,6 @@ export default function MDXContent(props: { name, pathConfig, filePath, - frontmatter, availIn, language, buildType, @@ -62,7 +55,20 @@ export default function MDXContent(props: { ); }); - !frontmatter?.hide_commit && useTotalContributors(pathConfig, filePath); + // Create H1 wrapper with props + const H1WithProps = React.useCallback( + (props: { children: React.ReactNode }) => ( +

+ ), + [pathConfig, filePath, pageUrl] + ); return ( @@ -74,6 +80,7 @@ export default function MDXContent(props: { components={{ ...MDXComponents, pre: Pre, + h1: H1WithProps, CustomContent, }} > diff --git a/src/media/icons/copy.svg b/src/media/icons/copy.svg new file mode 100644 index 00000000..f0135e86 --- /dev/null +++ b/src/media/icons/copy.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/media/icons/edit.svg b/src/media/icons/edit.svg new file mode 100644 index 00000000..3e9c928d --- /dev/null +++ b/src/media/icons/edit.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/media/icons/file.svg b/src/media/icons/file.svg new file mode 100644 index 00000000..f69374b4 --- /dev/null +++ b/src/media/icons/file.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/media/icons/markdown.svg b/src/media/icons/markdown.svg new file mode 100644 index 00000000..3cba8622 --- /dev/null +++ b/src/media/icons/markdown.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/styles/docTemplate.css b/src/styles/docTemplate.css index 1bbc345d..806d57da 100644 --- a/src/styles/docTemplate.css +++ b/src/styles/docTemplate.css @@ -144,6 +144,7 @@ .markdown-body { h1 { font-weight: 400; + border-bottom: 0; } h2, diff --git a/src/templates/DocTemplate.tsx b/src/templates/DocTemplate.tsx index 7fcfccaa..a0b85b38 100644 --- a/src/templates/DocTemplate.tsx +++ b/src/templates/DocTemplate.tsx @@ -11,11 +11,9 @@ import Layout from "components/Layout"; import { LeftNavDesktop, LeftNavMobile, -} from "components/Layout/Navigation/LeftNav"; +} from "components/Layout/LeftNav/LeftNav"; import MDXContent from "components/MDXContent"; -import RightNav, { - RightNavMobile, -} from "components/Layout/Navigation/RightNav"; +import RightNav, { RightNavMobile } from "components/Layout/RightNav/RightNav"; import { TableOfContent, PageContext, @@ -288,7 +286,6 @@ function DocTemplate({ name={name} pathConfig={pathConfig} filePath={filePath} - frontmatter={frontmatter} availIn={availIn.version} language={language} buildType={buildType} diff --git a/src/theme/index.tsx b/src/theme/index.tsx index e8151258..df34343b 100644 --- a/src/theme/index.tsx +++ b/src/theme/index.tsx @@ -175,10 +175,10 @@ theme = createTheme(theme, { 100: "#FBFDFD", 200: "#F5F8FA", 300: "#EDF0F1", - 400: "#E3E8EA", + 400: "#ECE3E5", 500: "#C8CED0", - 600: "#9FAAAD", - 700: "#6C7679", + 600: "#9FA9AD", + 700: "#6F787B", 800: "#3D4143", 900: "#262A2C", }, From e39608cee3f5e7cb23608959ea6cf5536b643797 Mon Sep 17 00:00:00 2001 From: Suhaha Date: Thu, 18 Dec 2025 17:27:42 +0800 Subject: [PATCH 2/5] chore: update subproject commit reference in docs --- docs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs b/docs index 0d2c6cf3..631b8250 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit 0d2c6cf365673ac810cda415604458bf713b9faa +Subproject commit 631b8250ef16f47f73c2387221b9d8a18107f7f1 From 0254666ad1632d83f7495474940823fba28c4c17 Mon Sep 17 00:00:00 2001 From: Suhaha Date: Thu, 18 Dec 2025 17:47:27 +0800 Subject: [PATCH 3/5] feat: add "Improve this document" link in TitleAction component - Introduced a new feature that generates a GitHub edit link for the current document, allowing users to easily contribute improvements. - The link is conditionally rendered based on the presence of pathConfig and filePath, enhancing user engagement with documentation. --- .../Layout/TitleAction/TitleAction.tsx | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/components/Layout/TitleAction/TitleAction.tsx b/src/components/Layout/TitleAction/TitleAction.tsx index b3094403..e26b2dd2 100644 --- a/src/components/Layout/TitleAction/TitleAction.tsx +++ b/src/components/Layout/TitleAction/TitleAction.tsx @@ -108,6 +108,13 @@ export const TitleAction = (props: TitleActionProps) => { } }, [pathConfig, filePath, pageUrl, site.siteMetadata.siteUrl]); + const improveUrl = React.useMemo(() => { + if (!pathConfig || !filePath) return null; + return `https://github.com/${getRepoFromPathCfg(pathConfig)}/edit/${ + pathConfig.branch + }/${filePath}`; + }, [pathConfig.branch, filePath]); + return ( { )} + {improveUrl && ( + + + {t("doc.improve")} + + + )} )} From 468fbf050c0928f77bdf7355c5b229ceecbd850c Mon Sep 17 00:00:00 2001 From: Suhaha Date: Thu, 18 Dec 2025 17:49:45 +0800 Subject: [PATCH 4/5] fix: update feedback translation for clarity in English and Japanese - Changed the feedback string from "Request docs changes" to "Report a doc issue" in both English and Japanese translation files for improved clarity and user understanding. --- locale/en/translation.json | 2 +- locale/ja/translation.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/locale/en/translation.json b/locale/en/translation.json index 7a8afee4..43c8601e 100644 --- a/locale/en/translation.json +++ b/locale/en/translation.json @@ -43,7 +43,7 @@ "toc": "ON THIS PAGE", "download-pdf": "Download PDF", "improve": "Edit this page", - "feedback": "Request docs changes", + "feedback": "Report a doc issue", "feedbackAskTug": "Ask the community", "latestCommit": "was last updated", "deprecation": { diff --git a/locale/ja/translation.json b/locale/ja/translation.json index bd181e96..10d7c0c2 100644 --- a/locale/ja/translation.json +++ b/locale/ja/translation.json @@ -40,7 +40,7 @@ "toc": "このページの内容", "download-pdf": "PDFをダウンロード", "improve": "このページを編集", - "feedback": "ドキュメントの変更をリクエストする", + "feedback": "ドキュメントの問題を報告する", "latestCommit": "最終更新日", "deprecation": { "tidb": { From af715b7ae7e5042639398add0ae5135e51100c06 Mon Sep 17 00:00:00 2001 From: Suhaha Date: Fri, 19 Dec 2025 14:10:37 +0800 Subject: [PATCH 5/5] fix: update TitleAction component for improved layout and button text - Added flexWrap property to the TitleAction component to enhance layout responsiveness. - Changed button text from "Copy Markdown for LLM" to "Copy for LLM" for brevity and clarity. --- src/components/Layout/TitleAction/TitleAction.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/Layout/TitleAction/TitleAction.tsx b/src/components/Layout/TitleAction/TitleAction.tsx index e26b2dd2..5eb283e5 100644 --- a/src/components/Layout/TitleAction/TitleAction.tsx +++ b/src/components/Layout/TitleAction/TitleAction.tsx @@ -121,6 +121,7 @@ export const TitleAction = (props: TitleActionProps) => { spacing={3} alignItems="center" justifyItems="center" + flexWrap="wrap" divider={ { color: theme.palette.carbon[700], }} > - Copy Markdown for LLM + Copy for LLM )}