Skip to content

Commit f372eec

Browse files
authored
Make annotations visible on hover, fix accessibility and outro animations (#3822)
1 parent 65ae941 commit f372eec

File tree

5 files changed

+37
-81
lines changed

5 files changed

+37
-81
lines changed

packages/gitbook/src/components/DocumentView/Annotation/Annotation.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export function Annotation(props: InlineProps<DocumentInlineAnnotation>) {
2727
ancestorBlocks={[]}
2828
context={context}
2929
nodes={fragment.nodes}
30-
style={['space-y-4']}
30+
style={['contents']}
3131
/>
3232
}
3333
>
Lines changed: 19 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,30 @@
11
'use client';
22

3-
import * as Popover from '@radix-ui/react-popover';
43
import type React from 'react';
54

6-
import { tString, useLanguage } from '@/intl/client';
7-
import { tcls } from '@/lib/tailwind';
5+
import { Tooltip } from '@/components/primitives';
86

97
export function AnnotationPopover(props: { children: React.ReactNode; body: React.ReactNode }) {
108
const { children, body } = props;
11-
const language = useLanguage();
129

1310
return (
14-
<Popover.Root>
15-
<Popover.Trigger asChild>
16-
<button
17-
data-testid="annotation-button"
18-
aria-label={tString(language, 'annotation_button_label')}
19-
className={tcls(
20-
'decoration-dotted',
21-
'decoration-1',
22-
'underline',
23-
'underline-offset-2'
24-
)}
25-
>
26-
{children}
27-
</button>
28-
</Popover.Trigger>
29-
<Popover.Portal>
30-
<Popover.Content
31-
className={tcls(
32-
'text-sm',
33-
'max-w-[280px]',
34-
'bg-tint',
35-
'ring-1',
36-
'ring-tint',
37-
'rounded-sm',
38-
'shadow-1xs',
39-
'shadow-tint-12/1',
40-
'dark:shadow-tint-1/2',
41-
'p-3',
42-
'[&_p]:leading-snug',
43-
'-outline-offset-2',
44-
'outline-2',
45-
'outline-primary/8',
46-
'z-20'
47-
)}
48-
sideOffset={4}
49-
>
50-
{body}
51-
<Popover.Arrow asChild>
52-
<svg
53-
viewBox="0 0 8 5"
54-
className={tcls(
55-
'relative',
56-
'z-2',
57-
'fill-tint-3', // Same as bg-tint
58-
'stroke-tint-7', // Same as ring-tint
59-
'[paint-order:stroke_fill]'
60-
)}
61-
fill="none"
62-
xmlns="http://www.w3.org/2000/svg"
63-
>
64-
<g clip-path="url(#clipAnnotation)">
65-
<path
66-
d="M0 0L4 4L8 0"
67-
strokeWidth="2"
68-
strokeLinecap="round"
69-
stroke="inherit"
70-
fill="inherit"
71-
/>
72-
</g>
73-
<defs>
74-
<clipPath id="clipAnnotation">
75-
<rect width="8" height="5" fill="white" />
76-
</clipPath>
77-
</defs>
78-
</svg>
79-
</Popover.Arrow>
80-
</Popover.Content>
81-
</Popover.Portal>
82-
</Popover.Root>
11+
<Tooltip
12+
label={body}
13+
contentProps={{
14+
role: 'definition',
15+
}}
16+
className="bg-tint-base px-4 py-3 text-sm text-tint-strong shadow-lg shadow-tint-12/4 ring-1 ring-tint-subtle dark:shadow-tint-1"
17+
arrow={true}
18+
arrowProps={{ className: 'fill-tint-1' }}
19+
>
20+
<dfn
21+
data-testid="annotation-button"
22+
className="cursor-help underline decoration-1 decoration-dotted underline-offset-2"
23+
// biome-ignore lint/a11y/noNoninteractiveTabindex: we want to be able to focus the definition to open the tooltip
24+
tabIndex={0}
25+
>
26+
{children}
27+
</dfn>
28+
</Tooltip>
8329
);
8430
}

packages/gitbook/src/components/primitives/HoverCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export function HoverCard(
2828
<RadixHoverCard.Portal>
2929
<RadixHoverCard.Content
3030
side={props.side ?? 'top'}
31-
className="z-40 w-screen max-w-md animate-present px-4 sm:w-auto"
31+
className="z-40 w-screen max-w-md animate-scale-in px-4 data-[state='closed']:animate-scale-out sm:w-auto"
3232
>
3333
<div
3434
className={tcls(

packages/gitbook/src/components/primitives/Popover.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export function Popover(props: {
2020
collisionPadding={contentProps?.collisionPadding ?? 16}
2121
sideOffset={contentProps?.sideOffset ?? 4}
2222
className={tcls(
23-
'z-50 max-h-(--radix-popover-content-available-height) max-w-xs animate-scale-in overflow-y-auto overflow-x-hidden circular-corners:rounded-3xl rounded-corners:rounded-md bg-tint px-4 py-3 text-sm text-tint depth-subtle:shadow-xl shadow-tint-12/4 outline-hidden ring-1 ring-tint transition-all empty:hidden dark:shadow-tint-1/6',
23+
'z-50 max-h-(--radix-popover-content-available-height) max-w-xs animate-scale-in overflow-y-auto overflow-x-hidden circular-corners:rounded-3xl rounded-corners:rounded-md bg-tint px-4 py-3 text-sm text-tint depth-subtle:shadow-xl shadow-tint-12/4 outline-hidden ring-1 ring-tint transition-all empty:hidden data-[state="closed"]:animate-scale-out dark:shadow-tint-1/6',
2424
contentProps?.className
2525
)}
2626
style={{

packages/gitbook/src/components/primitives/Tooltip.tsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22

33
import { tcls } from '@/lib/tailwind';
44
import * as RadixTooltip from '@radix-ui/react-tooltip';
5+
import { useState } from 'react';
56

67
export function Tooltip(props: {
78
children: React.ReactNode;
89
label?: string | React.ReactNode;
910
triggerProps?: RadixTooltip.TooltipTriggerProps;
1011
contentProps?: RadixTooltip.TooltipContentProps;
12+
portalProps?: RadixTooltip.TooltipPortalProps;
1113
rootProps?: RadixTooltip.TooltipProps;
14+
arrowProps?: RadixTooltip.TooltipArrowProps;
1215
arrow?: boolean;
1316
className?: string;
1417
}) {
@@ -17,27 +20,34 @@ export function Tooltip(props: {
1720
label,
1821
triggerProps,
1922
contentProps,
23+
portalProps,
2024
rootProps,
25+
arrowProps,
2126
arrow = false,
2227
className,
2328
} = props;
2429

30+
const [open, setOpen] = useState(false);
31+
const [clicked, setClicked] = useState(false);
32+
2533
return (
26-
<RadixTooltip.Root delayDuration={300} {...rootProps}>
27-
<RadixTooltip.Trigger asChild {...triggerProps}>
34+
<RadixTooltip.Root open={open || clicked} onOpenChange={setOpen} {...rootProps}>
35+
<RadixTooltip.Trigger asChild onClick={() => setClicked(true)} {...triggerProps}>
2836
{children}
2937
</RadixTooltip.Trigger>
30-
<RadixTooltip.Portal>
38+
<RadixTooltip.Portal {...portalProps}>
3139
<RadixTooltip.Content
3240
sideOffset={4}
41+
collisionPadding={8}
3342
className={tcls(
34-
'z-50 max-w-xs animate-scale-in circular-corners:rounded-2xl rounded-corners:rounded-md bg-tint-12 px-2 py-1 text-contrast-tint-12 text-sm',
43+
'z-50 max-w-xs circular-corners:rounded-2xl rounded-corners:rounded-md bg-tint-12 px-2 py-1 text-contrast-tint-12 text-sm data-[state$="closed"]:animate-scale-out data-[state$="open"]:animate-scale-in',
3544
className
3645
)}
46+
onPointerDownOutside={() => setClicked(false)}
3747
{...contentProps}
3848
>
3949
{label}
40-
{arrow && <RadixTooltip.Arrow />}
50+
{arrow && <RadixTooltip.Arrow {...arrowProps} />}
4151
</RadixTooltip.Content>
4252
</RadixTooltip.Portal>
4353
</RadixTooltip.Root>

0 commit comments

Comments
 (0)