mirror of
https://github.com/hanzo-docs/docs.git
synced 2026-10-25 04:20:02 +00:00
UI: Improve performance by reducing usage of @radix-ui/react-scroll-area
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'fumadocs-ui': patch
|
||||
---
|
||||
|
||||
Improve performance by reducing usage of `@radix-ui/react-scroll-area`
|
||||
@@ -38,12 +38,10 @@ export function useAnchorObserver(watch: string[], single: boolean): string[] {
|
||||
function onScroll(): void {
|
||||
const element = document.scrollingElement;
|
||||
if (!element) return;
|
||||
const top = element.scrollTop;
|
||||
|
||||
if (element.scrollTop === 0 && single) setActiveAnchor(watch.slice(0, 1));
|
||||
else if (
|
||||
element.scrollTop + element.clientHeight >=
|
||||
element.scrollHeight - 6
|
||||
) {
|
||||
if (top <= 0 && single) setActiveAnchor(watch.slice(0, 1));
|
||||
else if (top + element.clientHeight >= element.scrollHeight - 6) {
|
||||
setActiveAnchor((active) => {
|
||||
return active.length > 0 && !single
|
||||
? watch.slice(watch.indexOf(active[0]))
|
||||
|
||||
@@ -8,14 +8,8 @@ import {
|
||||
useRef,
|
||||
} from 'react';
|
||||
import { cn } from '@/utils/cn';
|
||||
import {
|
||||
ScrollArea,
|
||||
ScrollBar,
|
||||
ScrollViewport,
|
||||
} from '@/components/ui/scroll-area';
|
||||
import { useCopyButton } from '@/utils/use-copy-button';
|
||||
import { buttonVariants } from '@/components/ui/button';
|
||||
import type { ScrollAreaViewportProps } from '@radix-ui/react-scroll-area';
|
||||
|
||||
export type CodeBlockProps = HTMLAttributes<HTMLElement> & {
|
||||
/**
|
||||
@@ -39,7 +33,7 @@ export type CodeBlockProps = HTMLAttributes<HTMLElement> & {
|
||||
*/
|
||||
keepBackground?: boolean;
|
||||
|
||||
viewportProps?: ScrollAreaViewportProps;
|
||||
viewportProps?: HTMLAttributes<HTMLElement>;
|
||||
|
||||
/**
|
||||
* show line numbers
|
||||
@@ -97,6 +91,7 @@ export const CodeBlock = forwardRef<HTMLElement, CodeBlockProps>(
|
||||
return (
|
||||
<figure
|
||||
ref={ref}
|
||||
dir="ltr"
|
||||
{...props}
|
||||
className={cn(
|
||||
'not-prose group relative my-4 overflow-hidden rounded-lg border bg-fd-card text-sm outline-none',
|
||||
@@ -135,25 +130,23 @@ export const CodeBlock = forwardRef<HTMLElement, CodeBlockProps>(
|
||||
/>
|
||||
)
|
||||
)}
|
||||
<ScrollArea ref={areaRef} dir="ltr">
|
||||
<ScrollViewport
|
||||
{...viewportProps}
|
||||
className={cn(
|
||||
'text-[13px] py-3.5 [&_.line]:px-4 max-h-[600px]',
|
||||
props['data-line-numbers'] && '[&_.line]:pl-3',
|
||||
viewportProps?.className,
|
||||
)}
|
||||
style={{
|
||||
counterSet: props['data-line-numbers']
|
||||
? `line ${Number(props['data-line-numbers-start'] ?? 1) - 1}`
|
||||
: undefined,
|
||||
...viewportProps?.style,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</ScrollViewport>
|
||||
<ScrollBar orientation="horizontal" />
|
||||
</ScrollArea>
|
||||
<div
|
||||
ref={areaRef}
|
||||
{...viewportProps}
|
||||
className={cn(
|
||||
'text-[13px] py-3.5 overflow-auto [&_.line]:px-4 max-h-[600px] [scrollbar-width:thin]',
|
||||
props['data-line-numbers'] && '[&_.line]:pl-3',
|
||||
viewportProps?.className,
|
||||
)}
|
||||
style={{
|
||||
counterSet: props['data-line-numbers']
|
||||
? `line ${Number(props['data-line-numbers-start'] ?? 1) - 1}`
|
||||
: undefined,
|
||||
...viewportProps?.style,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</figure>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
import { cn } from '@/utils/cn';
|
||||
import { useI18n } from '@/contexts/i18n';
|
||||
import { TocThumb } from '@/components/layout/toc-thumb';
|
||||
import { ScrollArea, ScrollViewport } from '../ui/scroll-area';
|
||||
import { usePageStyles } from '@/contexts/layout';
|
||||
|
||||
export interface TOCProps {
|
||||
@@ -47,7 +46,7 @@ export function Toc(props: HTMLAttributes<HTMLDivElement>) {
|
||||
} as object
|
||||
}
|
||||
>
|
||||
<div className="flex h-full w-(--fd-toc-width) max-w-full flex-col gap-3 pe-4">
|
||||
<div className="flex h-full w-(--fd-toc-width) max-w-full flex-col pe-4">
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
@@ -64,30 +63,22 @@ export function TocItemsEmpty() {
|
||||
);
|
||||
}
|
||||
|
||||
export function TOCScrollArea({
|
||||
isMenu,
|
||||
...props
|
||||
}: ComponentProps<typeof ScrollArea> & { isMenu?: boolean }) {
|
||||
export function TOCScrollArea(props: ComponentProps<'div'>) {
|
||||
const viewRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
return (
|
||||
<ScrollArea
|
||||
<div
|
||||
{...props}
|
||||
className={cn('flex flex-col ps-px', props.className)}
|
||||
ref={viewRef}
|
||||
className={cn(
|
||||
'relative min-h-0 text-sm ms-px overflow-auto [scrollbar-width:none] [mask-image:linear-gradient(to_bottom,transparent,white_16px,white_calc(100%-16px),transparent)] py-3',
|
||||
props.className,
|
||||
)}
|
||||
>
|
||||
<ScrollViewport
|
||||
ref={viewRef}
|
||||
className={cn(
|
||||
'relative min-h-0 text-sm',
|
||||
isMenu &&
|
||||
'[mask-image:linear-gradient(to_bottom,transparent,white_16px,white_calc(100%-16px),transparent)] px-4 md:px-6 py-2',
|
||||
)}
|
||||
>
|
||||
<Primitive.ScrollProvider containerRef={viewRef}>
|
||||
{props.children}
|
||||
</Primitive.ScrollProvider>
|
||||
</ScrollViewport>
|
||||
</ScrollArea>
|
||||
<Primitive.ScrollProvider containerRef={viewRef}>
|
||||
{props.children}
|
||||
</Primitive.ScrollProvider>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ export function DocsPage({
|
||||
<TocPopoverTrigger className="w-full" items={toc} />
|
||||
<TocPopoverContent>
|
||||
{tocPopoverOptions.header}
|
||||
<TOCScrollArea isMenu>
|
||||
<TOCScrollArea className="px-4 md:px-6">
|
||||
{tocPopoverOptions.style === 'clerk' ? (
|
||||
<ClerkTOCItems items={toc} />
|
||||
) : (
|
||||
|
||||
Reference in New Issue
Block a user