Skip to content

Commit 386c4cb

Browse files
fix(ui): keyword dropdown selector (#7171)
It was not opening because the clicked element was the referenceEl
1 parent 51f9cf6 commit 386c4cb

File tree

2 files changed

+30
-15
lines changed

2 files changed

+30
-15
lines changed

src/components/codeBlock.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {CodeContext} from './codeContext';
1313

1414
const KEYWORDS_REGEX = /\b___(?:([A-Z_][A-Z0-9_]*)\.)?([A-Z_][A-Z0-9_]*)___\b/g;
1515

16-
function makeKeywordsClickable(children: React.ReactChildren) {
16+
function makeKeywordsClickable(children: React.ReactNode) {
1717
const items = Children.toArray(children);
1818

1919
KEYWORDS_REGEX.lastIndex = 0;
@@ -35,9 +35,10 @@ function makeKeywordsClickable(children: React.ReactChildren) {
3535
}
3636
arr.push(
3737
<KeywordSelector
38+
key={lastIndex}
39+
index={lastIndex}
3840
group={match[1] || 'PROJECT'}
3941
keyword={match[2]}
40-
index={lastIndex}
4142
/>
4243
);
4344
lastIndex = KEYWORDS_REGEX.lastIndex;
@@ -76,8 +77,8 @@ function KeywordSelector({keyword, group, index}: KeywordSelectorProps) {
7677
const codeContext = useContext(CodeContext);
7778

7879
const [isOpen, setIsOpen] = useState(false);
79-
const [referenceEl, setReferenceEl] = useState(null);
80-
const [dropdownEl, setDropdownEl] = useState(null);
80+
const [referenceEl, setReferenceEl] = useState<HTMLSpanElement>(null);
81+
const [dropdownEl, setDropdownEl] = useState<HTMLElement>(null);
8182

8283
const {styles, state, attributes} = usePopper(referenceEl, dropdownEl, {
8384
placement: 'bottom',
@@ -90,7 +91,11 @@ function KeywordSelector({keyword, group, index}: KeywordSelectorProps) {
9091
],
9192
});
9293

93-
useOnClickOutside({current: dropdownEl}, () => isOpen && setIsOpen(false));
94+
useOnClickOutside({
95+
ref: {current: referenceEl},
96+
enabled: isOpen,
97+
handler: () => setIsOpen(false),
98+
});
9499

95100
const [sharedSelection, setSharedSelection] = codeContext.sharedKeywordSelection;
96101

src/utils.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,32 @@ import qs from 'query-string';
44

55
type ClickOutsideCallback = (event: MouseEvent) => void;
66

7-
export function useOnClickOutside<T>(
8-
ref: React.RefObject<T>,
9-
handler: ClickOutsideCallback
10-
) {
7+
interface UseClickOutsideOpts<E extends HTMLElement> {
8+
enabled: boolean;
9+
handler: ClickOutsideCallback;
10+
ref: React.RefObject<E>;
11+
}
12+
13+
export function useOnClickOutside<E extends HTMLElement>({
14+
ref,
15+
enabled,
16+
handler,
17+
}: UseClickOutsideOpts<E>) {
1118
useEffect(() => {
1219
const cb = (event: MouseEvent) => {
13-
// TODO(dcramer): fix any type here
14-
if (!ref.current || !(ref.current as any).contains(event.target)) {
20+
if (!enabled) {
21+
return;
22+
}
23+
if (!(event.target instanceof Element)) {
24+
return;
25+
}
26+
if (!ref.current.contains(event.target)) {
1527
handler(event);
1628
}
1729
};
1830
document.addEventListener('click', cb);
19-
return () => {
20-
document.removeEventListener('click', cb);
21-
};
22-
}, [ref, handler]);
31+
return () => document.removeEventListener('click', cb);
32+
}, [enabled, handler, ref]);
2333
}
2434

2535
export const sortBy = (arr: any[], comp: (any) => any): any[] => {

0 commit comments

Comments
 (0)