docs: redesign code highlights + add default code titles (#8628)
* docs: code highlights improvements + default titles * spacing fixes * fix terminal detection * add padding for non-terminal one liners
This commit is contained in:
@@ -28,11 +28,8 @@ export const CodeBlockCopyAction = ({
|
||||
<CopyButton
|
||||
text={source}
|
||||
tooltipClassName="font-base"
|
||||
className={clsx(
|
||||
"h-fit",
|
||||
!inHeader && "p-[6px]",
|
||||
inHeader && "px-[6px] pb-[6px]"
|
||||
)}
|
||||
className={clsx("h-fit", !inHeader && "p-[6px]", inHeader && "p-[4.5px]")}
|
||||
tooltipInnerClassName={clsx(inHeader && "flex")}
|
||||
onCopy={() => setCopied(true)}
|
||||
>
|
||||
{!copied && <SquareTwoStack className={clsx(iconColor)} />}
|
||||
|
||||
@@ -51,26 +51,29 @@ export const CodeBlockActions = ({
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"absolute hidden md:block",
|
||||
"xs:rounded xs:absolute xs:right-0 xs:top-0 xs:w-[calc(17%+10px)] xs:h-full"
|
||||
"hidden md:block",
|
||||
!inHeader &&
|
||||
"xs:rounded xs:absolute xs:right-0 xs:top-0 xs:w-[calc(17%+10px)] xs:h-full"
|
||||
)}
|
||||
>
|
||||
{!inHeader && (
|
||||
<div
|
||||
className={clsx(
|
||||
!inHeader &&
|
||||
showGradientBg && [
|
||||
inInnerCode &&
|
||||
"xs:bg-subtle-code-fade-right-to-left dark:xs:bg-subtle-code-fade-right-to-left-dark",
|
||||
!inInnerCode &&
|
||||
"xs:bg-base-code-fade-right-to-left dark:xs:bg-base-code-fade-right-to-left-dark",
|
||||
],
|
||||
(inHeader || !showGradientBg) && "xs:bg-transparent",
|
||||
"z-[9] w-full h-full absolute top-0 left-0"
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
className={clsx(
|
||||
!inHeader &&
|
||||
showGradientBg && [
|
||||
inInnerCode &&
|
||||
"xs:bg-subtle-code-fade-right-to-left dark:xs:bg-subtle-code-fade-right-to-left-dark",
|
||||
!inInnerCode &&
|
||||
"xs:bg-base-code-fade-right-to-left dark:xs:bg-base-code-fade-right-to-left-dark",
|
||||
],
|
||||
(inHeader || !showGradientBg) && "xs:bg-transparent",
|
||||
"z-[9] w-full h-full absolute top-0 left-0"
|
||||
)}
|
||||
/>
|
||||
<div
|
||||
className={clsx(
|
||||
"md:flex md:justify-end z-[11] relative",
|
||||
"md:flex md:justify-end md:gap-docs_0.25 z-[11] relative",
|
||||
!inHeader && [
|
||||
"md:pr-docs_0.5",
|
||||
isCollapsed && "md:pt-docs_2.5",
|
||||
@@ -78,8 +81,7 @@ export const CodeBlockActions = ({
|
||||
isSingleLine && "md:pt-docs_0.25",
|
||||
!isSingleLine && "md:pt-docs_0.5",
|
||||
],
|
||||
],
|
||||
inHeader && "md:pr-docs_1 md:pt-docs_0.5"
|
||||
]
|
||||
)}
|
||||
>
|
||||
{canShowApiTesting && (
|
||||
@@ -89,8 +91,9 @@ export const CodeBlockActions = ({
|
||||
className={clsx(
|
||||
"h-fit",
|
||||
!inHeader && "p-[6px]",
|
||||
inHeader && "px-[6px] pb-[6px]"
|
||||
inHeader && "p-[4.5px]"
|
||||
)}
|
||||
innerClassName={clsx(inHeader && "flex")}
|
||||
>
|
||||
<PlaySolid
|
||||
className={clsx("cursor-pointer", iconColor)}
|
||||
@@ -105,8 +108,9 @@ export const CodeBlockActions = ({
|
||||
className={clsx(
|
||||
"h-fit",
|
||||
!inHeader && "p-[6px]",
|
||||
inHeader && "px-[6px] pb-[6px]"
|
||||
inHeader && "p-[4.5px]"
|
||||
)}
|
||||
innerClassName={clsx(inHeader && "flex")}
|
||||
>
|
||||
<Link
|
||||
href={`${GITHUB_ISSUES_PREFIX}&title=${encodeURIComponent(
|
||||
|
||||
@@ -54,7 +54,7 @@ export const CodeBlockHeader = ({
|
||||
<div
|
||||
className={clsx(
|
||||
"py-docs_0.5 px-docs_1 mb-0",
|
||||
"rounded-t-docs_lg relative",
|
||||
"rounded-t-docs_lg relative flex justify-between items-center",
|
||||
blockStyle === "subtle" && [
|
||||
"border border-solid border-b-0",
|
||||
colorMode === "light" && "border-medusa-border-base",
|
||||
@@ -63,7 +63,7 @@ export const CodeBlockHeader = ({
|
||||
bgColor
|
||||
)}
|
||||
>
|
||||
<div className={clsx("xs:max-w-[83%]", "flex gap-docs_0.75 items-start")}>
|
||||
<div className={clsx("flex-1", "flex gap-docs_0.75 items-start")}>
|
||||
{badgeLabel && (
|
||||
<Badge variant={badgeColor || "code"} className="font-base">
|
||||
{badgeLabel}
|
||||
|
||||
@@ -23,6 +23,7 @@ type CodeBlockLineProps = {
|
||||
showLineNumber: boolean
|
||||
lineNumberColorClassName: string
|
||||
lineNumberBgClassName: string
|
||||
isTerminal: boolean
|
||||
} & Pick<RenderProps, "getLineProps" | "getTokenProps">
|
||||
|
||||
export const CodeBlockLine = ({
|
||||
@@ -34,6 +35,7 @@ export const CodeBlockLine = ({
|
||||
showLineNumber,
|
||||
lineNumberColorClassName,
|
||||
lineNumberBgClassName,
|
||||
isTerminal,
|
||||
}: CodeBlockLineProps) => {
|
||||
const lineProps = getLineProps({ line, key: lineNumber })
|
||||
|
||||
@@ -194,19 +196,18 @@ export const CodeBlockLine = ({
|
||||
|
||||
const getTokensElm = ({
|
||||
tokens,
|
||||
isHighlighted,
|
||||
isTokenHighlighted,
|
||||
isLineHighlighted,
|
||||
offset,
|
||||
}: {
|
||||
tokens: Token[]
|
||||
isHighlighted: boolean
|
||||
isTokenHighlighted: boolean
|
||||
isLineHighlighted: boolean
|
||||
offset: number
|
||||
}) => (
|
||||
<span
|
||||
className={clsx(
|
||||
isHighlighted && [
|
||||
"lg:py-px lg:px-[6px] lg:border-medusa-contrast-border-top lg:rounded-docs_sm",
|
||||
"lg:bg-medusa-contrast-bg-highlight lg:cursor-pointer",
|
||||
]
|
||||
isTokenHighlighted && "lg:bg-medusa-contrast-border-base cursor-default"
|
||||
)}
|
||||
>
|
||||
{tokens.map((token, key) => {
|
||||
@@ -216,14 +217,22 @@ export const CodeBlockLine = ({
|
||||
key: tokenKey,
|
||||
})
|
||||
return (
|
||||
<span key={tokenKey} className={clsx(tokenClassName)} {...rest} />
|
||||
<span
|
||||
key={tokenKey}
|
||||
className={clsx(
|
||||
tokenClassName,
|
||||
(isTerminal || isTokenHighlighted || isLineHighlighted) &&
|
||||
"!text-medusa-contrast-fg-primary"
|
||||
)}
|
||||
{...rest}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</span>
|
||||
)
|
||||
|
||||
const isHighlightedLine = useMemo(
|
||||
() => highlights.length && !highlightedTokens.length,
|
||||
() => highlights.length !== 0 && highlightedTokens.length === 0,
|
||||
[highlights, highlightedTokens]
|
||||
)
|
||||
|
||||
@@ -233,11 +242,11 @@ export const CodeBlockLine = ({
|
||||
{...lineProps}
|
||||
className={clsx(
|
||||
"table-row",
|
||||
isHighlightedLine && "bg-medusa-contrast-bg-highlight",
|
||||
isHighlightedLine && "bg-medusa-contrast-border-base",
|
||||
lineProps.className
|
||||
)}
|
||||
>
|
||||
{showLineNumber && (
|
||||
{(showLineNumber || isTerminal) && (
|
||||
<span
|
||||
className={clsx(
|
||||
"mr-docs_1 table-cell select-none",
|
||||
@@ -246,7 +255,7 @@ export const CodeBlockLine = ({
|
||||
lineNumberBgClassName
|
||||
)}
|
||||
>
|
||||
{lineNumber + 1}
|
||||
{isTerminal ? "❯" : showLineNumber ? lineNumber + 1 : ""}
|
||||
</span>
|
||||
)}
|
||||
<span>
|
||||
@@ -274,10 +283,21 @@ export const CodeBlockLine = ({
|
||||
</MarkdownContent>
|
||||
)}
|
||||
>
|
||||
{getTokensElm({ tokens, isHighlighted, offset })}
|
||||
{getTokensElm({
|
||||
tokens,
|
||||
isTokenHighlighted: isHighlighted,
|
||||
offset,
|
||||
isLineHighlighted: isHighlightedLine,
|
||||
})}
|
||||
</Tooltip>
|
||||
)}
|
||||
{!tooltipText && getTokensElm({ tokens, isHighlighted, offset })}
|
||||
{!tooltipText &&
|
||||
getTokensElm({
|
||||
tokens,
|
||||
isTokenHighlighted: isHighlighted,
|
||||
offset,
|
||||
isLineHighlighted: isHighlightedLine,
|
||||
})}
|
||||
</React.Fragment>
|
||||
)
|
||||
})}
|
||||
|
||||
@@ -38,6 +38,7 @@ export type CodeBlockMetaFields = {
|
||||
noLineNumbers?: boolean
|
||||
collapsibleLines?: string
|
||||
expandButtonLabel?: string
|
||||
isTerminal?: boolean
|
||||
} & CodeBlockHeaderMeta
|
||||
|
||||
export type CodeBlockStyle = "loud" | "subtle"
|
||||
@@ -68,6 +69,7 @@ export const CodeBlock = ({
|
||||
children,
|
||||
collapsibleLines,
|
||||
expandButtonLabel,
|
||||
isTerminal,
|
||||
...rest
|
||||
}: CodeBlockProps) => {
|
||||
if (!source && typeof children === "string") {
|
||||
@@ -80,9 +82,25 @@ export const CodeBlock = ({
|
||||
const codeRef = useRef<HTMLElement>(null)
|
||||
const apiRunnerRef = useRef<HTMLDivElement>(null)
|
||||
const [scrollable, setScrollable] = useState(false)
|
||||
const isTerminalCode = useMemo(() => {
|
||||
return isTerminal === undefined
|
||||
? lang === "bash" && !source.startsWith("curl")
|
||||
: isTerminal
|
||||
}, [isTerminal, lang])
|
||||
const codeTitle = useMemo(() => {
|
||||
if (title || hasTabs) {
|
||||
return title
|
||||
}
|
||||
|
||||
if (isTerminalCode) {
|
||||
return "Terminal"
|
||||
}
|
||||
|
||||
return "Code"
|
||||
}, [title, isTerminalCode, hasTabs])
|
||||
const hasInnerCodeBlock = useMemo(
|
||||
() => hasTabs || title.length > 0,
|
||||
[hasTabs, title]
|
||||
() => hasTabs || codeTitle.length > 0,
|
||||
[hasTabs, codeTitle]
|
||||
)
|
||||
const canShowApiTesting = useMemo(
|
||||
() =>
|
||||
@@ -198,6 +216,7 @@ export const CodeBlock = ({
|
||||
key={offsettedLineNumber}
|
||||
lineNumberColorClassName={lineNumbersColor}
|
||||
lineNumberBgClassName={innerBgColor}
|
||||
isTerminal={isTerminalCode}
|
||||
{...highlightProps}
|
||||
/>
|
||||
)
|
||||
@@ -260,16 +279,15 @@ export const CodeBlock = ({
|
||||
hasInnerCodeBlock && "rounded-docs_lg",
|
||||
!hasInnerCodeBlock && "rounded-docs_DEFAULT",
|
||||
!hasTabs && boxShadow,
|
||||
(blockStyle === "loud" || colorMode !== "light") &&
|
||||
"code-block-highlight-dark",
|
||||
blockStyle === "loud" && "code-block-highlight",
|
||||
blockStyle === "subtle" &&
|
||||
colorMode === "light" &&
|
||||
"code-block-highlight-light"
|
||||
)}
|
||||
>
|
||||
{title && (
|
||||
{codeTitle && (
|
||||
<CodeBlockHeader
|
||||
title={title}
|
||||
title={codeTitle}
|
||||
blockStyle={blockStyle}
|
||||
badgeLabel={rest.badgeLabel}
|
||||
badgeColor={rest.badgeColor}
|
||||
@@ -334,17 +352,20 @@ export const CodeBlock = ({
|
||||
"rounded-docs_DEFAULT",
|
||||
!hasInnerCodeBlock &&
|
||||
tokens.length <= 1 &&
|
||||
"px-docs_0.5 py-[6px]",
|
||||
!title.length && (!noCopy || !noReport) && "xs:max-w-[83%]",
|
||||
noLineNumbers && "pl-docs_1",
|
||||
"px-docs_1 py-[6px]",
|
||||
!codeTitle.length &&
|
||||
(!noCopy || !noReport) &&
|
||||
"xs:max-w-[83%]",
|
||||
(noLineNumbers ||
|
||||
(tokens.length <= 1 && !isTerminalCode)) &&
|
||||
"pl-docs_1",
|
||||
preClassName
|
||||
)}
|
||||
>
|
||||
<code
|
||||
className={clsx(
|
||||
"text-code-body font-monospace table min-w-full print:whitespace-pre-wrap",
|
||||
tokens.length > 1 && "py-docs_0.75",
|
||||
tokens.length <= 1 && "!py-[6px] px-docs_0.5"
|
||||
"py-docs_0.75"
|
||||
)}
|
||||
ref={codeRef}
|
||||
>
|
||||
@@ -364,7 +385,7 @@ export const CodeBlock = ({
|
||||
})}
|
||||
</code>
|
||||
</pre>
|
||||
{!title && (
|
||||
{!hasInnerCodeBlock && (
|
||||
<CodeBlockActions
|
||||
{...actionsProps}
|
||||
inHeader={false}
|
||||
|
||||
@@ -9,6 +9,7 @@ export type CopyButtonProps = {
|
||||
text: string
|
||||
buttonClassName?: string
|
||||
tooltipClassName?: string
|
||||
tooltipInnerClassName?: string
|
||||
tooltipText?: string
|
||||
onCopy?: (
|
||||
e:
|
||||
@@ -27,6 +28,7 @@ export const CopyButton = ({
|
||||
className,
|
||||
onCopy,
|
||||
handleTouch,
|
||||
tooltipInnerClassName,
|
||||
}: CopyButtonProps) => {
|
||||
const { isCopied, handleCopy } = useCopy(text)
|
||||
const [touchCount, setTouchCount] = useState(0)
|
||||
@@ -36,6 +38,7 @@ export const CopyButton = ({
|
||||
text={isCopied ? `Copied!` : tooltipText}
|
||||
tooltipClassName={clsx(tooltipClassName, handleTouch && "!block")}
|
||||
className={className}
|
||||
innerClassName={tooltipInnerClassName}
|
||||
>
|
||||
<span
|
||||
className={clsx("cursor-pointer", buttonClassName)}
|
||||
|
||||
@@ -11,6 +11,7 @@ export type TooltipProps = {
|
||||
tooltipClassName?: string
|
||||
html?: string
|
||||
tooltipChildren?: React.ReactNode
|
||||
innerClassName?: string
|
||||
} & React.HTMLAttributes<HTMLSpanElement> &
|
||||
ITooltip
|
||||
|
||||
@@ -21,6 +22,7 @@ export const Tooltip = ({
|
||||
html = "",
|
||||
tooltipChildren,
|
||||
className,
|
||||
innerClassName,
|
||||
...tooltipProps
|
||||
}: TooltipProps) => {
|
||||
const elementId = useId()
|
||||
@@ -32,6 +34,7 @@ export const Tooltip = ({
|
||||
data-tooltip-content={text}
|
||||
data-tooltip-html={html}
|
||||
data-tooltip-id={elementId}
|
||||
className={innerClassName}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
|
||||
@@ -768,9 +768,10 @@ module.exports = {
|
||||
".animate-bg-surface": {
|
||||
"--animation-color": "var(--docs-bg-subtle-pressed)",
|
||||
},
|
||||
".code-block-highlight-dark": {
|
||||
".code-block-highlight": {
|
||||
"*::selection": {
|
||||
"background-color": "var(--docs-contrast-bg-highlight)",
|
||||
"background-color": "var(--docs-contrast-fg-secondary)",
|
||||
color: "var(--docs-contrast-bg-base)",
|
||||
},
|
||||
},
|
||||
".code-block-highlight-light": {
|
||||
|
||||
@@ -96,7 +96,7 @@ const light = {
|
||||
"--docs-contrast-bg-alpha": "rgba(9, 9, 11, 0.8)",
|
||||
"--docs-contrast-fg-primary": "rgba(255, 255, 255, 0.88)",
|
||||
"--docs-contrast-fg-secondary": "rgba(255, 255, 255, 0.56)",
|
||||
"--docs-contrast-border-base": "rgba(255, 255, 255, 0.15)",
|
||||
"--docs-contrast-border-base": "rgba(255, 255, 255, 0.16)",
|
||||
"--docs-contrast-border-top": "rgba(9, 9, 11, 1)",
|
||||
"--docs-contrast-border-bot": "rgba(255, 255, 255, 0.1)",
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user