Twoslash: Fix popups focus outline

This commit is contained in:
Fuma Nama
2024-12-09 20:09:06 +08:00
parent 7f53da43f9
commit 9585561a82
3 changed files with 36 additions and 27 deletions
+6
View File
@@ -0,0 +1,6 @@
---
'fumadocs-twoslash': patch
'fumadocs-ui': patch
---
Fix Twoslash popups focus outline
+29 -26
View File
@@ -5,6 +5,9 @@ import {
useContext,
createContext,
useMemo,
type ReactNode,
type ComponentRef,
type ComponentPropsWithoutRef,
} from 'react';
import { Popover, PopoverContent, PopoverTrigger } from './popover';
@@ -23,30 +26,12 @@ function Popup({
children,
}: {
delay?: number;
children: React.ReactNode;
children: ReactNode;
}) {
const [open, setOpen] = useState(false);
const openTimeoutRef = useRef<number>(undefined);
const closeTimeoutRef = useRef<number>(undefined);
const handleOpen = (e: React.PointerEvent): void => {
if (e.pointerType === 'touch') return;
if (closeTimeoutRef.current) clearTimeout(closeTimeoutRef.current);
openTimeoutRef.current = window.setTimeout(() => {
setOpen(true);
}, delay);
};
const handleClose = (e: React.PointerEvent): void => {
if (e.pointerType === 'touch') return;
if (openTimeoutRef.current) clearTimeout(openTimeoutRef.current);
closeTimeoutRef.current = window.setTimeout(() => {
setOpen(false);
}, delay);
};
return (
<Popover open={open} onOpenChange={setOpen}>
<PopupContext.Provider
@@ -54,10 +39,25 @@ function Popup({
() => ({
open,
setOpen,
handleOpen,
handleClose,
handleOpen(e) {
if (e.pointerType === 'touch') return;
if (closeTimeoutRef.current)
clearTimeout(closeTimeoutRef.current);
openTimeoutRef.current = window.setTimeout(() => {
setOpen(true);
}, delay);
},
handleClose(e) {
if (e.pointerType === 'touch') return;
if (openTimeoutRef.current) clearTimeout(openTimeoutRef.current);
closeTimeoutRef.current = window.setTimeout(() => {
setOpen(false);
}, delay);
},
}),
[handleClose, handleOpen, open],
[delay, open],
)}
>
{children}
@@ -67,8 +67,8 @@ function Popup({
}
const PopupTrigger = forwardRef<
React.ElementRef<typeof PopoverTrigger>,
React.ComponentPropsWithoutRef<typeof PopoverTrigger>
ComponentRef<typeof PopoverTrigger>,
ComponentPropsWithoutRef<typeof PopoverTrigger>
>((props, ref) => {
const ctx = useContext(PopupContext);
if (!ctx) throw new Error('Missing Popup Context');
@@ -86,8 +86,8 @@ const PopupTrigger = forwardRef<
PopupTrigger.displayName = 'PopupTrigger';
const PopupContent = forwardRef<
React.ComponentRef<typeof PopoverContent>,
React.ComponentPropsWithoutRef<typeof PopoverContent>
ComponentRef<typeof PopoverContent>,
ComponentPropsWithoutRef<typeof PopoverContent>
>((props, ref) => {
const ctx = useContext(PopupContext);
if (!ctx) throw new Error('Missing Popup Context');
@@ -97,6 +97,9 @@ const PopupContent = forwardRef<
ref={ref}
onPointerEnter={ctx.handleOpen}
onPointerLeave={ctx.handleClose}
onOpenAutoFocus={(e) => {
e.preventDefault();
}}
onCloseAutoFocus={(e) => {
e.preventDefault();
}}
+1 -1
View File
@@ -131,7 +131,7 @@ export const CodeBlock = forwardRef<HTMLElement, CodeBlockProps>(
<ScrollArea ref={areaRef} dir="ltr">
<ScrollViewport
{...viewportProps}
className={cn('max-h-[400px]', viewportProps?.className)}
className={cn('max-h-[600px]', viewportProps?.className)}
>
{props.children}
</ScrollViewport>