1.6 KB61 lines
Blame
1/**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8import type {CommitInfo, Hash} from './types';
9
10import {atom, useSetAtom} from 'jotai';
11import {useEffect, useState} from 'react';
12import {atomFamilyWeak} from './jotaiUtils';
13
14export const highlightedCommits = atom<Set<Hash>>(new Set<Hash>());
15
16export const isHighlightedCommit = atomFamilyWeak((hash: Hash) =>
17 atom(get => get(highlightedCommits).has(hash)),
18);
19
20export function HighlightCommitsWhileHovering({
21 toHighlight,
22 children,
23 ...rest
24}: {
25 toHighlight: Array<CommitInfo | Hash>;
26 children: React.ReactNode;
27} & React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>) {
28 const setHighlighted = useSetAtom(highlightedCommits);
29 const [isSourceOfHighlight, setIsSourceOfHighlight] = useState(false);
30
31 useEffect(() => {
32 return () => {
33 if (isSourceOfHighlight) {
34 // if we started the highlight, make sure to unhighlight when unmounting
35 setHighlighted(new Set());
36 }
37 };
38 }, [isSourceOfHighlight, setHighlighted]);
39
40 return (
41 <div
42 {...rest}
43 onMouseOver={() => {
44 setHighlighted(
45 new Set(
46 toHighlight.map(commitOrHash =>
47 typeof commitOrHash === 'string' ? commitOrHash : commitOrHash.hash,
48 ),
49 ),
50 );
51 setIsSourceOfHighlight(true);
52 }}
53 onMouseOut={() => {
54 setHighlighted(new Set());
55 setIsSourceOfHighlight(false);
56 }}>
57 {children}
58 </div>
59 );
60}
61