UI: improve codeblocks

This commit is contained in:
Fuma Nama
2025-08-28 15:58:48 +08:00
parent e1b61ea6e2
commit 02d34530bb
4 changed files with 50 additions and 27 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'fumadocs-ui': patch
---
Make codeblocks flat & improve paddings
+6 -4
View File
@@ -1,6 +1,6 @@
.shiki:not(.not-fumadocs-codeblock *) {
--padding-left: calc(var(--spacing) * 3);
--padding-right: calc(var(--spacing) * 3);
--padding-left: calc(var(--spacing) * 4);
--padding-right: calc(var(--spacing) * 4);
code span {
color: var(--shiki-light);
@@ -44,7 +44,7 @@
code .diff::before {
position: absolute;
left: var(--spacing);
left: calc(var(--spacing) * 1.5);
}
code .diff.remove {
@@ -70,7 +70,9 @@
code .highlighted {
--fd-counter-color: var(--color-fd-primary);
@apply bg-fd-primary/10;
padding-left: calc(var(--padding-left) - 2px);
@apply border-l-2 border-fd-primary/50 bg-fd-primary/10;
}
code .highlighted-word {
+17 -23
View File
@@ -1,5 +1,5 @@
'use client';
import { Check, Copy } from 'lucide-react';
import { Check, Clipboard } from 'lucide-react';
import {
type ComponentProps,
createContext,
@@ -87,13 +87,9 @@ export function CodeBlock({
),
...props
}: CodeBlockProps) {
const isTab = useContext(TabsContext) !== null;
const inTab = useContext(TabsContext) !== null;
const areaRef = useRef<HTMLDivElement>(null);
allowCopy ??= !isTab;
const bg = cn(
'bg-fd-secondary',
keepBackground && 'bg-(--shiki-light-bg) dark:bg-(--shiki-dark-bg)',
);
allowCopy ??= !inTab;
return (
<figure
@@ -101,18 +97,15 @@ export function CodeBlock({
dir="ltr"
{...props}
className={cn(
isTab ? [bg, 'rounded-lg'] : 'my-4 rounded-xl bg-fd-card p-1',
'shiki relative border shadow-sm outline-none not-prose overflow-hidden text-sm',
inTab ? 'rounded-lg bg-fd-secondary' : 'my-4 rounded-xl bg-fd-card',
keepBackground && 'bg-(--shiki-light-bg) dark:bg-(--shiki-dark-bg)',
'shiki relative border shadow-md outline-none not-prose overflow-hidden text-sm',
props.className,
)}
>
{title ? (
<div
className={cn(
'flex text-fd-muted-foreground items-center gap-2 ps-3 h-9.5',
isTab && 'border-b',
)}
>
<div className="flex text-fd-muted-foreground items-center gap-2 h-9.5 border-b px-4">
{typeof icon === 'string' ? (
<div
className="[&_svg]:size-3.5"
@@ -125,13 +118,14 @@ export function CodeBlock({
)}
<figcaption className="flex-1 truncate">{title}</figcaption>
{Actions({
className: '-me-2',
children: allowCopy && <CopyButton containerRef={areaRef} />,
})}
</div>
) : (
Actions({
className:
'absolute top-1 right-1 z-2 bg-fd-card rounded-bl-lg border-l border-b text-fd-muted-foreground',
'absolute top-2 right-2 z-2 backdrop-blur-lg rounded-lg text-fd-muted-foreground',
children: allowCopy && <CopyButton containerRef={areaRef} />,
})
)}
@@ -139,7 +133,6 @@ export function CodeBlock({
ref={areaRef}
{...viewportProps}
className={cn(
!isTab && [bg, 'rounded-lg border'],
'text-[13px] py-3.5 overflow-auto max-h-[600px] fd-scroll-container',
viewportProps.className,
)}
@@ -184,7 +177,8 @@ function CopyButton({
type="button"
className={cn(
buttonVariants({
className: '[&_svg]:size-3.5 hover:text-fd-accent-foreground',
className: 'hover:text-fd-accent-foreground',
size: 'icon-xs',
}),
className,
)}
@@ -192,7 +186,7 @@ function CopyButton({
onClick={onClick}
{...props}
>
{checked ? <Check /> : <Copy />}
{checked ? <Check /> : <Clipboard />}
</button>
);
}
@@ -207,7 +201,7 @@ export function CodeBlockTabs({ ref, ...props }: ComponentProps<typeof Tabs>) {
{...props}
className={cn(
'bg-fd-card p-1 rounded-xl border overflow-hidden',
!nested && 'my-4',
nested ? 'shadow-sm' : '-m-1 my-4',
props.className,
)}
>
@@ -233,14 +227,14 @@ export function CodeBlockTabsList(props: ComponentProps<typeof TabsList>) {
<TabsList
{...props}
className={cn(
'flex flex-row overflow-x-auto px-1 -mx-1 text-fd-muted-foreground',
'flex flex-row *:first:ms-2 overflow-x-auto text-fd-muted-foreground',
props.className,
)}
>
{props.children}
{!nested && (
<CopyButton
className="sticky ms-auto right-0 bg-fd-card backdrop-blur-sm"
className="sticky ms-auto right-2 bg-fd-card backdrop-blur-sm"
containerRef={containerRef}
/>
)}
@@ -256,7 +250,7 @@ export function CodeBlockTabsTrigger({
<TabsTrigger
{...props}
className={cn(
'relative group inline-flex text-sm font-medium text-nowrap items-center transition-colors gap-2 px-2 first:ms-1 py-1.5 hover:text-fd-accent-foreground data-[state=active]:text-fd-primary [&_svg]:size-3.5',
'relative group inline-flex text-sm font-medium text-nowrap items-center transition-colors gap-2 px-2 py-1.5 hover:text-fd-accent-foreground data-[state=active]:text-fd-primary [&_svg]:size-3.5',
props.className,
)}
>
+22
View File
@@ -204,6 +204,28 @@ export const Copy = createLucideIcon('copy', [
],
]);
export const Clipboard = createLucideIcon('clipboard', [
[
'rect',
{
width: '8',
height: '4',
x: '8',
y: '2',
rx: '1',
ry: '1',
key: '1',
},
],
[
'path',
{
d: 'M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2',
key: '2',
},
],
]);
export const FileText = createLucideIcon('file-text', [
[
'path',