diff --git a/src/components/DocumentView/Caption.tsx b/src/components/DocumentView/Caption.tsx new file mode 100644 index 000000000..a56334f47 --- /dev/null +++ b/src/components/DocumentView/Caption.tsx @@ -0,0 +1,75 @@ +import { + DocumentBlockDrawing, + DocumentBlockEmbed, + DocumentBlockImage, + JSONDocument, +} from '@gitbook/api'; + +import { getNodeFragmentByName, isNodeEmpty } from '@/lib/document'; +import { ClassValue, tcls } from '@/lib/tailwind'; + +import { DocumentContextProps } from './DocumentView'; +import { Inlines } from './Inlines'; + +/** + * Wrap a content of a block that has a potential caption. + */ +export function Caption( + props: { + children: React.ReactNode; + document: JSONDocument; + style?: ClassValue; + wrapperStyle?: ClassValue; + block: DocumentBlockImage | DocumentBlockDrawing | DocumentBlockEmbed; + } & DocumentContextProps, +) { + const { + children, + document, + block, + context, + wrapperStyle = [ + 'relative', + 'overflow-hidden', + 'rounded', + 'after:block', + 'after:absolute', + 'after:-inset-[0]', + 'after:border-dark/2', + 'after:border', + 'after:rounded', + 'dark:after:border-light/1', + 'dark:after:mix-blend-plus-lighter', + 'after:pointer-events-none', + ], + style, + } = props; + + const caption = getNodeFragmentByName(block, 'caption'); + const captionParagraph = caption?.nodes[0]; + + if ( + !captionParagraph || + captionParagraph.type !== 'paragraph' || + isNodeEmpty(captionParagraph) + ) { + return
{children}
; + } + + return ( + +
{children}
+
+ +
+
+ ); +} diff --git a/src/components/DocumentView/CodeBlock/CodeBlock.tsx b/src/components/DocumentView/CodeBlock/CodeBlock.tsx index 3fa232530..1867a73bd 100644 --- a/src/components/DocumentView/CodeBlock/CodeBlock.tsx +++ b/src/components/DocumentView/CodeBlock/CodeBlock.tsx @@ -191,10 +191,7 @@ function CodeHighlightLine(props: { 'dark:before:text-light/4', line.highlighted - ? [ - 'before:text-dark/6', - 'dark:before:text-light/8', - ] + ? ['before:text-dark/6', 'dark:before:text-light/8'] : null, ] : [], diff --git a/src/components/DocumentView/Drawing.tsx b/src/components/DocumentView/Drawing.tsx index 601f75b08..b8dafb774 100644 --- a/src/components/DocumentView/Drawing.tsx +++ b/src/components/DocumentView/Drawing.tsx @@ -1,11 +1,28 @@ import { DocumentBlockDrawing } from '@gitbook/api'; -import { tcls } from '@/lib/tailwind'; - import { BlockProps } from './Block'; +import { Caption } from './Caption'; +import { Image } from '../utils'; -export function Drawing(props: BlockProps) { - const { style } = props; +export async function Drawing(props: BlockProps) { + const { block, context } = props; - return
TODO
; + const resolved = block.data.ref ? await context.resolveContentRef(block.data.ref) : null; + if (!resolved) { + return null; + } + + return ( + + Drawing + + ); } diff --git a/src/components/DocumentView/Embed.tsx b/src/components/DocumentView/Embed.tsx index 033ed1220..f36d6d98d 100644 --- a/src/components/DocumentView/Embed.tsx +++ b/src/components/DocumentView/Embed.tsx @@ -6,59 +6,34 @@ import { getNodeFragmentByName, isNodeEmpty } from '@/lib/document'; import { ClassValue, tcls } from '@/lib/tailwind'; import { BlockProps } from './Block'; +import { Caption } from './Caption'; import { Inlines } from './Inlines'; export async function Embed(props: BlockProps) { - const { block, style, document, context } = props; + const { block } = props; const { data: embed } = await api().urls.getEmbedByUrl({ url: block.data.url }); - const caption = getNodeFragmentByName(block, 'caption'); - const captionParagraph = caption?.nodes[0]; - - const content = (wrapStyle: ClassValue) => - embed.type === 'rich' ? ( -
- ) : ( - - ) : null - } - href={block.data.url} - title={embed.title} - postTitle={embed.site} - style={wrapStyle} - /> - ); - - if ( - !captionParagraph || - captionParagraph.type !== 'paragraph' || - isNodeEmpty(captionParagraph) - ) { - return content(style); - } return ( -
- {content(null)} -
- -
-
+ + {embed.type === 'rich' ? ( +
+ ) : ( + + ) : null + } + href={block.data.url} + title={embed.title} + postTitle={embed.site} + /> + )} + ); } diff --git a/src/components/DocumentView/Images.tsx b/src/components/DocumentView/Images.tsx index 2e7003fe7..ff3dd0f46 100644 --- a/src/components/DocumentView/Images.tsx +++ b/src/components/DocumentView/Images.tsx @@ -1,12 +1,11 @@ import { DocumentBlockImage, DocumentBlockImages, JSONDocument } from '@gitbook/api'; import { Image } from '@/components/utils'; -import { getNodeFragmentByName, isNodeEmpty } from '@/lib/document'; import { ClassValue, tcls } from '@/lib/tailwind'; import { BlockProps } from './Block'; +import { Caption } from './Caption'; import { DocumentContext } from './DocumentView'; -import { Inlines } from './Inlines'; import { isBlockOffscreen } from './utils'; export function Images(props: BlockProps) { @@ -55,7 +54,7 @@ async function ImageBlock(props: { siblings: number; isOffscreen: boolean; }) { - const { block, document, context, isOffscreen } = props; + const { block, context, isOffscreen } = props; const [src, darkSrc] = await Promise.all([ context.resolveContentRef(block.data.ref), @@ -66,75 +65,34 @@ async function ImageBlock(props: { return null; } - const imageBorder = tcls( - 'relative', - 'overflow-hidden', - 'rounded', - 'after:block', - 'after:absolute', - 'after:-inset-[0]', - 'after:border-dark/2', - 'after:border', - 'after:rounded', - 'dark:after:border-light/1', - 'dark:after:mix-blend-plus-lighter', - 'after:pointer-events-none', - ); - - const caption = getNodeFragmentByName(block, 'caption'); - const captionParagraph = caption?.nodes[0]; - - const image = ( - {block.data.alt - ); - - if ( - !captionParagraph || - captionParagraph.type !== 'paragraph' || - isNodeEmpty(captionParagraph) - ) { - return image; - } - return ( - -
{image}
-
- -
-
+ + {block.data.alt + ); } diff --git a/src/lib/document.ts b/src/lib/document.ts index c4df0d1c8..29a129779 100644 --- a/src/lib/document.ts +++ b/src/lib/document.ts @@ -140,7 +140,7 @@ export function isNodeEmpty( node: DocumentText | DocumentFragment | DocumentInline | DocumentBlock | JSONDocument, ): boolean { if (node.object !== 'text' && 'nodes' in node) { - if (node.nodes.length > 0) { + if (node.nodes.length > 1) { return false; } diff --git a/tests/visual-testing.ts b/tests/visual-testing.ts index e1ac8ccac..edd8216c6 100644 --- a/tests/visual-testing.ts +++ b/tests/visual-testing.ts @@ -60,10 +60,6 @@ const testCases: TestsCase[] = [ name: 'Encoded URL', url: 'scan-using-snyk/supported-languages-and-frameworks/c-c++', }, - { - name: 'Redirect', - url: 'products/snyk-open-source/use-snyk-open-source-from-the-cli', - }, { name: 'Revision', url: '~/revisions/H41VQ6cIvd5hyUwcnwbC',