From a70e8cd7dcc51f68333fbd4c5e2695fe29139284 Mon Sep 17 00:00:00 2001 From: Zeno Kapitein Date: Thu, 3 Apr 2025 13:23:20 +0200 Subject: [PATCH] Refactor to split components into Link and LinkTooltip --- .../components/DocumentView/InlineLink.tsx | 194 +++--------------- .../DocumentView/InlineLinkTooltip.tsx | 173 ++++++++++++++++ 2 files changed, 205 insertions(+), 162 deletions(-) create mode 100644 packages/gitbook/src/components/DocumentView/InlineLinkTooltip.tsx diff --git a/packages/gitbook/src/components/DocumentView/InlineLink.tsx b/packages/gitbook/src/components/DocumentView/InlineLink.tsx index 2826ea637..e6ff38732 100644 --- a/packages/gitbook/src/components/DocumentView/InlineLink.tsx +++ b/packages/gitbook/src/components/DocumentView/InlineLink.tsx @@ -1,14 +1,10 @@ import { type DocumentInlineLink, SiteInsightsLinkPosition } from '@gitbook/api'; import { resolveContentRef } from '@/lib/references'; - -import { tcls } from '@/lib/tailwind'; import { Icon } from '@gitbook/icons'; -import * as Tooltip from '@radix-ui/react-tooltip'; -import { Fragment } from 'react'; -import { AIPageLinkSummary } from '../Adaptive/AIPageLinkSummary'; -import { Button, StyledLink } from '../primitives'; +import { StyledLink } from '../primitives'; import type { InlineProps } from './Inline'; +import { InlineLinkTooltip } from './InlineLinkTooltip'; import { Inlines } from './Inlines'; export async function InlineLink(props: InlineProps) { @@ -32,164 +28,38 @@ export async function InlineLink(props: InlineProps) { ); } - - let breadcrumbs = resolved.ancestors; const isExternal = inline.data.ref.kind === 'url'; - const isSamePage = inline.data.ref.kind === 'anchor' && inline.data.ref.page === undefined; - if (isExternal) { - breadcrumbs = [ - { - label: 'External link to', - }, - ]; - } - if (isSamePage) { - breadcrumbs = [ - { - label: 'Jump to section', - icon: , - }, - ]; - resolved.subText = undefined; - } return ( - - - - - - {isExternal ? ( - - ) : null} - - - - -
-
-
-
- {breadcrumbs ? ( -
- {breadcrumbs.map((crumb, index) => { - const Tag = crumb.href ? StyledLink : 'div'; - - return ( - - {index !== 0 ? ( - - ) : null} - - {crumb.icon ? ( - - {crumb.icon} - - ) : null} - {crumb.label} - - - ); - })} -
- ) : null} -
- {resolved.icon ? ( -
- {resolved.icon} -
- ) : null} -
{resolved.text}
-
-
- {!isSamePage && resolved.href ? ( -
- {resolved.subText ? ( -

{resolved.subText}

- ) : null} -
- - {!isExternal && - 'site' in context.contentContext && - 'page' in context.contentContext && - context.contentContext.site.adaptiveContent?.enabled && - inline.data.ref.kind === 'page' ? ( -
- { - if (node.object === 'text') { - return node.leaves - .map((leaf) => leaf.text) - .join(''); - } - return ''; - }) - .join('')} - linkPreview={`**${resolved.text}**: ${resolved.subText}`} - showTrademark={ - context.contentContext.customization.trademark.enabled - } - /> -
- ) : null} -
- -
-
-
-
+ + + + {isExternal ? ( + + ) : null} + + ); } diff --git a/packages/gitbook/src/components/DocumentView/InlineLinkTooltip.tsx b/packages/gitbook/src/components/DocumentView/InlineLinkTooltip.tsx new file mode 100644 index 000000000..fd3bcc290 --- /dev/null +++ b/packages/gitbook/src/components/DocumentView/InlineLinkTooltip.tsx @@ -0,0 +1,173 @@ +import type { DocumentInlineLink } from '@gitbook/api'; + +import { resolveContentRef } from '@/lib/references'; + +import { tcls } from '@/lib/tailwind'; +import { Icon } from '@gitbook/icons'; +import * as Tooltip from '@radix-ui/react-tooltip'; +import { Fragment } from 'react'; +import { AIPageLinkSummary } from '../Adaptive/AIPageLinkSummary'; +import { Button, StyledLink } from '../primitives'; +import type { InlineProps } from './Inline'; +import { Inlines } from './Inlines'; + +export async function InlineLinkTooltip( + props: InlineProps & { children: React.ReactNode } +) { + const { inline, document, context, ancestorInlines, children } = props; + + const resolved = context.contentContext + ? await resolveContentRef(inline.data.ref, context.contentContext, { + resolveAnchorText: true, + }) + : null; + + if (!context.contentContext || !resolved) { + return ( + + + + ); + } + + let breadcrumbs = resolved.ancestors; + const isExternal = inline.data.ref.kind === 'url'; + const isSamePage = inline.data.ref.kind === 'anchor' && inline.data.ref.page === undefined; + if (isExternal) { + breadcrumbs = [ + { + label: 'External link to', + }, + ]; + } + if (isSamePage) { + breadcrumbs = [ + { + label: 'Jump to section', + icon: , + }, + ]; + resolved.subText = undefined; + } + + return ( + + + {children} + + +
+
+
+
+ {breadcrumbs ? ( +
+ {breadcrumbs.map((crumb, index) => { + const Tag = crumb.href ? StyledLink : 'div'; + + return ( + + {index !== 0 ? ( + + ) : null} + + {crumb.icon ? ( + + {crumb.icon} + + ) : null} + {crumb.label} + + + ); + })} +
+ ) : null} +
+ {resolved.icon ? ( +
+ {resolved.icon} +
+ ) : null} +
{resolved.text}
+
+
+ {!isSamePage && resolved.href ? ( +
+ {resolved.subText ? ( +

{resolved.subText}

+ ) : null} +
+ + {!isExternal && + 'site' in context.contentContext && + 'page' in context.contentContext && + context.contentContext.site.adaptiveContent?.enabled && + inline.data.ref.kind === 'page' ? ( +
+ { + if (node.object === 'text') { + return node.leaves + .map((leaf) => leaf.text) + .join(''); + } + return ''; + }) + .join('')} + linkPreview={`**${resolved.text}**: ${resolved.subText}`} + showTrademark={ + context.contentContext.customization.trademark.enabled + } + /> +
+ ) : null} +
+ +
+
+
+
+ ); +}