Skip to content

Commit

Permalink
fix: shiki highlight line
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <i@innei.in>
  • Loading branch information
Innei committed Mar 20, 2024
1 parent 65897b4 commit a3769cb
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 24 deletions.
7 changes: 6 additions & 1 deletion src/components/modules/toc/TocTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ export const TocTree: Component<
const toc: ITocItem[] = useMemo(() => {
return Array.from($headings).map((el, idx) => {
const depth = +el.tagName.slice(1)
const title = el.textContent || ''
const elClone = el.cloneNode(true) as HTMLElement
elClone.querySelectorAll('del').forEach((del) => {
del.remove()
})

const title = elClone.textContent || ''

const index = idx

Expand Down
4 changes: 3 additions & 1 deletion src/components/ui/code-highlighter/CodeHighlighter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { FC } from 'react'

import { useIsPrintMode } from '~/atoms/css-media'
import { useIsDark } from '~/hooks/common/use-is-dark'
import { stopPropagation } from '~/lib/dom'
import { clsxm } from '~/lib/helper'
import { loadScript, loadStyleSheet } from '~/lib/load-script'
import { toast } from '~/lib/toast'
Expand Down Expand Up @@ -36,7 +37,7 @@ export const HighLighterPrismCdn: FC<Props> = (props) => {
const ref = useRef<HTMLElement>(null)
useLoadHighlighter(ref)
return (
<div className={styles['code-wrap']}>
<div className={styles['code-wrap']} onCopy={stopPropagation}>
<span className={styles['language-tip']} aria-hidden>
{language?.toUpperCase()}
</span>
Expand Down Expand Up @@ -70,6 +71,7 @@ export const BaseCodeHighlighter: Component<
}, [content, lang])
return (
<pre
onCopy={stopPropagation}
className={clsxm('!bg-transparent', className)}
style={style}
data-start="1"
Expand Down
22 changes: 7 additions & 15 deletions src/components/ui/code-highlighter/shiki/Shiki.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,22 @@
@apply flex flex-col;
}

code {
counter-reset: step;
counter-increment: step 0;
}

.shiki,
code {
@apply !bg-transparent;
}

.line {
@apply block min-h-[1em] px-4;
@apply block min-h-[1em] px-5;

& > span:last-child {
@apply mr-5;
}
}

.highlighted,
.diff {
@apply relative break-all;
white-space: pre-wrap;
word-wrap: break-word;
overflow: auto;

&::before {
@apply absolute left-0 top-0 h-full w-[2px];
Expand Down Expand Up @@ -67,19 +63,15 @@
.highlighted {
@apply bg-accent/20;

white-space: pre-wrap;
word-wrap: break-word;
overflow: auto;

&::before {
@apply bg-accent;
}
}
}

.scroll-container pre::-webkit-scrollbar-track {
margin-left: 3rem;
margin-right: 8rem;
margin-left: 1rem;
margin-right: var(--sr-margin, 0);
}

.scroll-container pre::-webkit-scrollbar {
Expand Down
48 changes: 42 additions & 6 deletions src/components/ui/code-highlighter/shiki/Shiki.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type { HighlighterCore } from 'shiki'
import { getViewport } from '~/atoms/hooks'
import { AutoResizeHeight } from '~/components/modules/shared/AutoResizeHeight'
import { useMaskScrollArea } from '~/hooks/shared/use-mask-scrollarea'
import { stopPropagation } from '~/lib/dom'
import { clsxm } from '~/lib/helper'

import { MotionButtonBase } from '../../button'
Expand Down Expand Up @@ -97,15 +98,38 @@ export const ShikiHighLighter: FC<Props> = (props) => {
}
}, [value, codeBlockRef])

const renderedHtml = useMemo(() => {
const highlightedHtml = useMemo(() => {
if (!highlighter) return ''
return codeHighlighter(highlighter, {
attrs: attrs || '',
// code: `${value.split('\n')[0].repeat(10)} // [!code highlight]\n${value}`,
code: value,
lang: language ? language.toLowerCase() : '',
})
}, [attrs, language, value, highlighter])

const [renderedHtml, setRenderedHtml] = useState(highlightedHtml)
useEffect(() => {
setRenderedHtml(highlightedHtml)
requestAnimationFrame(() => {
if (!highlightedHtml) return
if (!codeBlockRef) return

const $lines = codeBlockRef.querySelectorAll('.line')
const maxLineWidth = Math.max(
...Array.from($lines).map((el) => {
return (el as HTMLElement).scrollWidth
}),
)
$lines.forEach((el) => {
;(el as HTMLElement).style.width = `${maxLineWidth}px`
})

const pre = codeBlockRef.querySelector('pre')
if (pre) setRenderedHtml(pre.outerHTML)
})
}, [codeBlockRef, highlightedHtml])

const filename = useMemo(() => {
return parseFilenameFromAttrs(attrs || '')
}, [attrs])
Expand All @@ -114,10 +138,15 @@ export const ShikiHighLighter: FC<Props> = (props) => {
size: 'lg',
})

const hasHeader = !!filename

return (
<div className={clsx(styles['code-card'], 'group')}>
<div
className={clsx(styles['code-card'], 'group')}
onCopy={stopPropagation}
>
{!!filename && (
<div className="z-10 flex w-full items-center justify-between rounded-t-xl bg-accent/20 px-4 py-2 text-sm">
<div className="z-10 flex w-full items-center justify-between rounded-t-xl bg-accent/20 px-5 py-2 text-sm">
<span className="shrink-0 flex-grow truncate">{filename}</span>
<span
className="pointer-events-none flex-shrink-0 flex-grow-0"
Expand All @@ -136,7 +165,7 @@ export const ShikiHighLighter: FC<Props> = (props) => {
{language.toUpperCase()}
</div>
)}
<div className="bg-accent/10 py-4">
<div className="bg-accent/5 py-4">
<MotionButtonBase
onClick={handleCopy}
className={clsx(
Expand All @@ -156,6 +185,13 @@ export const ShikiHighLighter: FC<Props> = (props) => {
!isCollapsed ? '!max-h-[100%]' : isOverflow ? maskClassName : '',
styles['scroll-container'],
)}
style={
{
'--sr-margin': !hasHeader
? `${(language?.length || 0) + 1}em`
: '1rem',
} as any
}
dangerouslySetInnerHTML={
renderedHtml
? {
Expand All @@ -165,8 +201,8 @@ export const ShikiHighLighter: FC<Props> = (props) => {
}
>
{renderedHtml ? undefined : (
<pre className="bg-transparent px-4">
<code className="!px-4">{value}</code>
<pre className="bg-transparent px-5">
<code className="!px-5">{value}</code>
</pre>
)}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/link/MLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const MLink: FC<{
type="tooltip"
TriggerComponent={useCallback(
() => (
<span className="inline items-center">
<span className="inline items-center font-sans">
<Favicon href={href} />
<a
className="shiro-link--underline"
Expand Down

0 comments on commit a3769cb

Please sign in to comment.