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:
committed by
Facebook GitHub Bot
parent
2f39ede6f7
commit
f46cf2b0ce
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user