Added color options for highlighting search terms

Summary:
This diff builds on the previous ones by enabling other colors to be used as highlights for the search terms. Current color options are: yellow(default), red, blue, green. Possible extensions to this feature could include allow the user to enter a custom hex-color string and use that as the highlight color.

Changelog: DataTable will now have option to have its search terms highlighted in the search results by toggling and customizing the highlight colors in the menu bar

Reviewed By: mweststrate

Differential Revision: D37383163

fbshipit-source-id: c81e383c0570ef5efbf3171b92b81a8fb2e55ea7
This commit is contained in:
Feiyu Wong
2022-06-29 10:36:52 -07:00
committed by Facebook GitHub Bot
parent 2f39ede6f7
commit f46cf2b0ce
10 changed files with 106 additions and 32 deletions

View File

@@ -7,7 +7,6 @@
* @format
*/
import styled from '@emotion/styled';
import React, {
useEffect,
memo,
@@ -19,19 +18,20 @@ import React, {
import {debounce} from 'lodash';
import {theme} from './theme';
const Highlighted = styled.span({
backgroundColor: theme.searchHighlightBackground,
});
export interface HighlightManager {
setFilter(text: string | undefined): void;
render(text: string): React.ReactNode;
setHighlightColor(color: string | undefined): void;
}
function createHighlightManager(initialText: string = ''): HighlightManager {
function createHighlightManager(
initialText: string = '',
initialHighlightColor: string = theme.searchHighlightBackground.yellow,
): HighlightManager {
const callbacks = new Set<(prev: string, next: string) => void>();
let matches = 0;
let currentFilter = initialText;
let currHighlightColor = initialHighlightColor;
const Highlight: React.FC<{text: string}> = memo(({text}) => {
const [, setUpdate] = useState(0);
@@ -65,9 +65,9 @@ function createHighlightManager(initialText: string = ''): HighlightManager {
) : (
<>
{text.substr(0, index)}
<Highlighted>
<span style={{backgroundColor: currHighlightColor}}>
{text.substr(index, currentFilter.length)}
</Highlighted>
</span>
{text.substr(index + currentFilter.length)}
</>
)}
@@ -87,6 +87,12 @@ function createHighlightManager(initialText: string = ''): HighlightManager {
render(text: string) {
return <Highlight text={text} />;
},
setHighlightColor(color: string) {
if (color !== currHighlightColor) {
currHighlightColor = color;
callbacks.forEach((cb) => cb(currentFilter, currentFilter));
}
},
};
}
@@ -98,21 +104,32 @@ export const HighlightContext = createContext<HighlightManager>({
// stub implementation in case we render a component without a Highlight context
return text;
},
setHighlightColor(_color: string) {
throw new Error('Cannot set the color of a stub highlight manager');
},
});
export function HighlightProvider({
text,
highlightColor,
children,
}: {
text: string | undefined;
highlightColor?: string | undefined;
children: React.ReactElement;
}) {
const [highlightManager] = useState(() => createHighlightManager(text));
const [highlightManager] = useState(() =>
createHighlightManager(text, highlightColor),
);
useEffect(() => {
highlightManager.setFilter(text);
}, [text, highlightManager]);
useEffect(() => {
highlightManager.setHighlightColor(highlightColor);
}, [highlightColor, highlightManager]);
return (
<HighlightContext.Provider value={highlightManager}>
{children}