-
Notifications
You must be signed in to change notification settings - Fork 14
/
Suggestion.tsx
75 lines (69 loc) · 1.81 KB
/
Suggestion.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import React from "react";
import styled from "styled-components";
import { SuggestionProps } from "./types";
const Suggestion = ({
id,
value,
onClick,
suggestion,
isLast,
visuallyFocused,
highlighted,
}: SuggestionProps): JSX.Element => {
const regEx = new RegExp(value, "i");
const matchedWords = suggestion.match(regEx);
const noMatchedWords = suggestion.replace(regEx, "");
return (
<SuggestionContainer
id={id}
onClick={() => {
onClick(suggestion);
}}
visuallyFocused={visuallyFocused}
role="option"
aria-selected={visuallyFocused ? true : undefined}
>
<StyledSuggestion last={isLast} visuallyFocused={visuallyFocused}>
{highlighted ? (
<>
<strong>{matchedWords}</strong>
{noMatchedWords}
</>
) : (
suggestion
)}
</StyledSuggestion>
</SuggestionContainer>
);
};
const SuggestionContainer = styled.li<{
visuallyFocused: boolean;
}>`
display: flex;
padding: 0 0.5rem;
line-height: 1.715em;
cursor: pointer;
box-shadow: inset 0 0 0 2px
${(props) => (props.visuallyFocused ? props.theme.focusListOptionBorderColor : "transparent")};
&:hover {
background-color: ${(props) => props.theme.hoverListOptionBackgroundColor};
}
&:active {
background-color: ${(props) => props.theme.activeListOptionBackgroundColor};
}
`;
const StyledSuggestion = styled.span<{
visuallyFocused: boolean;
last: boolean;
}>`
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding: 0.25rem 0.5rem 0.188rem 0.5rem;
${(props) =>
props.last || props.visuallyFocused
? `border-bottom: 1px solid transparent`
: `border-bottom: 1px solid ${props.theme.listOptionDividerColor}`};
`;
export default React.memo(Suggestion);