PanelEdit: Highlight matched words when searching options (#33717)

This commit is contained in:
Torkel Ödegaard
2021-05-05 09:12:06 +02:00
committed by GitHub
parent 86f2ed8ef2
commit 1e810b3d59
9 changed files with 51 additions and 18 deletions

View File

@@ -37,7 +37,7 @@ export class OptionsPaneCategoryDescriptor {
return this;
}
render(isSearching?: boolean) {
render(searchQuery?: string) {
if (this.props.customRender) {
return this.props.customRender();
}

View File

@@ -1,6 +1,7 @@
import { selectors } from '@grafana/e2e-selectors';
import { Field, Label } from '@grafana/ui';
import React, { ReactNode } from 'react';
import Highlighter from 'react-highlight-words';
import { OptionsPaneCategoryDescriptor } from './OptionsPaneCategoryDescriptor';
export interface OptionsPaneItemProps {
@@ -21,10 +22,10 @@ export class OptionsPaneItemDescriptor {
constructor(public props: OptionsPaneItemProps) {}
getLabel(isSearching?: boolean): ReactNode {
getLabel(searchQuery?: string): ReactNode {
const { title, description } = this.props;
if (!isSearching) {
if (!searchQuery) {
// Do not render label for categories with only one child
if (this.parent.props.title === title) {
return null;
@@ -33,24 +34,30 @@ export class OptionsPaneItemDescriptor {
return title;
}
const categories: string[] = [];
const categories: React.ReactNode[] = [];
if (this.parent.parent) {
categories.push(this.parent.parent.props.title);
categories.push(this.highlightWord(this.parent.parent.props.title, searchQuery));
}
if (this.parent.props.title !== title) {
categories.push(this.parent.props.title);
categories.push(this.highlightWord(this.parent.props.title, searchQuery));
}
return (
<Label description={description} category={categories}>
{title}
<Label description={description && this.highlightWord(description, searchQuery)} category={categories}>
{this.highlightWord(title, searchQuery)}
</Label>
);
}
render(isSearching?: boolean) {
highlightWord(word: string, query: string) {
return (
<Highlighter textToHighlight={word} searchWords={[query]} highlightClassName={'search-fragment-highlight'} />
);
}
render(searchQuery?: string) {
const { title, description, render, showIf, skipField } = this.props;
const key = `${this.parent.props.id} ${title}`;
@@ -64,7 +71,7 @@ export class OptionsPaneItemDescriptor {
return (
<Field
label={this.getLabel(isSearching)}
label={this.getLabel(searchQuery)}
description={description}
key={key}
aria-label={selectors.components.PanelEditor.OptionsPane.fieldLabel(key)}

View File

@@ -139,9 +139,9 @@ function renderSearchHits(
key="Normal options"
forceOpen={1}
>
{optionHits.map((hit) => hit.render(true))}
{optionHits.map((hit) => hit.render(searchQuery))}
</OptionsPaneCategory>
{overrideHits.map((override) => override.render(true))}
{overrideHits.map((override) => override.render(searchQuery))}
</div>
);
}
@@ -152,6 +152,11 @@ const getStyles = (theme: GrafanaTheme2) => ({
display: flex;
flex-direction: column;
flex: 1 1 0;
.search-fragment-highlight {
color: ${theme.colors.warning.text};
background: transparent;
}
`,
searchBox: css`
display: flex;