diff --git a/content/show/highlight/index-en-US.md b/content/show/highlight/index-en-US.md
index 2a3f5be3fd..4a8878d813 100644
--- a/content/show/highlight/index-en-US.md
+++ b/content/show/highlight/index-en-US.md
@@ -71,6 +71,32 @@ import { Highlight } from '@douyinfe/semi-ui';
};
```
+### Use Different Styles for Different Texts
+After v2.71.0, it supports using different highlight styles for different highlighted texts.
+The `searchWords` is a string array by default. When an array of objects is passed in, the highlighted text can be specified through `text`, and the `className` and `style` can be specified separately at the same time.
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Highlight } from '@douyinfe/semi-ui';
+
+() => {
+ return (
+
+
+
+ );
+};
+```
+
### Specify the highlight tag
diff --git a/content/show/highlight/index.md b/content/show/highlight/index.md
index 6100ac0752..9ee35a65cb 100644
--- a/content/show/highlight/index.md
+++ b/content/show/highlight/index.md
@@ -89,6 +89,32 @@ import { Highlight } from '@douyinfe/semi-ui';
};
```
+### 不同文本使用差异化样式
+v2.71.0 后,支持针对不同的高亮文本使用不同的高亮样式
+searchWords 默认为字符串数组。当传入对象数组时,可以通过 text指定高亮文本,同时单独指定 className、style
+
+```jsx live=true dir="column"
+import React from 'react';
+import { Highlight } from '@douyinfe/semi-ui';
+
+() => {
+ return (
+
+
+
+ );
+};
+```
+
### 指定高亮标签
@@ -112,16 +138,17 @@ import { Highlight } from '@douyinfe/semi-ui';
};
```
+
## API 参考
### Highlight
| 属性 | 说明 | 类型 | 默认值 |
| ------------ | -------------------------------------------------------- | -------------------------------- | ---------- |
-| searchWords | 期望高亮显示的文本 | string[] | '' |
+| searchWords | 期望高亮显示的文本(对象数组在v2.71后支持) | string[]\|object[] | [] |
| sourceString | 源文本 | string | |
| component | 高亮标签 | string | `mark` |
-| highlightClassName | 高亮标签的样式类名 | ReactNode | - |
-| highlightStyle | 高亮标签的内联样式 | ReactNode | - |
+| highlightClassName | 高亮标签的样式类名 | string | - |
+| highlightStyle | 高亮标签的内联样式 | CSSProperties | - |
| caseSensitive | 是否大小写敏感 | false | - |
| autoEscape | 是否自动转义 | true | - |
diff --git a/packages/semi-foundation/highlight/foundation.ts b/packages/semi-foundation/highlight/foundation.ts
new file mode 100644
index 0000000000..a88681d53c
--- /dev/null
+++ b/packages/semi-foundation/highlight/foundation.ts
@@ -0,0 +1,211 @@
+// Modified version based on 'highlight-words-core'
+import { isString } from 'lodash';
+import BaseFoundation, { DefaultAdapter } from '../base/foundation';
+
+interface HighlightAdapter extends Partial {}
+
+interface ChunkQuery {
+ autoEscape?: boolean;
+ caseSensitive?: boolean;
+ searchWords: SearchWords;
+ sourceString: string
+}
+export interface Chunk {
+ start: number;
+ end: number;
+ highlight: boolean;
+ className: string;
+ style: Record
+}
+
+export interface ComplexSearchWord {
+ text: string;
+ className?: string;
+ style?: Record
+}
+
+export type SearchWord = string | ComplexSearchWord | undefined;
+export type SearchWords = SearchWord[];
+
+const escapeRegExpFn = (string: string) => string.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
+
+export default class HighlightFoundation extends BaseFoundation {
+
+ constructor(adapter?: HighlightAdapter) {
+ super({
+ ...adapter,
+ });
+ }
+
+ /**
+ * Creates an array of chunk objects representing both higlightable and non highlightable pieces of text that match each search word.
+ *
+ findAll ['z'], 'aaazaaazaaa'
+ result #=> [
+ { start: 0, end: 3, highlight: false }
+ { start: 3, end: 4, highlight: true }
+ { start: 4, end: 7, highlight: false }
+ { start: 7, end: 8, highlight: true }
+ { start: 8, end: 11, highlight: false }
+ ]
+
+ findAll ['do', 'dollar'], 'aaa do dollar aaa'
+ #=> chunks: [
+ { start: 4, end: 6 },
+ { start: 7, end: 9 },
+ { start: 7, end: 13 },
+ ]
+ #=> chunksToHight: [
+ { start: 4, end: 6 },
+ { start: 7, end: 13 },
+ ]
+ #=> result: [
+ { start: 0, end: 4, highlight: false },
+ { start: 4, end: 6, highlight: true },
+ { start: 6, end: 7, highlight: false },
+ { start: 7, end: 13, highlight: true },
+ { start: 13, end: 17, highlight: false },
+ ]
+
+ * @return Array of "chunks" (where a Chunk is { start:number, end:number, highlight:boolean })
+ */
+ findAll = ({
+ autoEscape = true,
+ caseSensitive = false,
+ searchWords,
+ sourceString
+ }: ChunkQuery) => {
+ if (isString(searchWords)) {
+ searchWords = [searchWords];
+ }
+
+ const chunks = this.findChunks({
+ autoEscape,
+ caseSensitive,
+ searchWords,
+ sourceString
+ });
+ const chunksToHighlight = this.combineChunks({ chunks });
+ const result = this.fillInChunks({
+ chunksToHighlight,
+ totalLength: sourceString ? sourceString.length : 0
+ });
+ return result;
+ };
+
+ /**
+ * Examine text for any matches.
+ * If we find matches, add them to the returned array as a "chunk" object ({start:number, end:number}).
+ * @return { start:number, end:number }[]
+ */
+ findChunks = ({
+ autoEscape,
+ caseSensitive,
+ searchWords,
+ sourceString
+ }: ChunkQuery): Chunk[] => (
+ searchWords
+ .map(searchWord => typeof searchWord === 'string' ? { text: searchWord } : searchWord)
+ .filter(searchWord => searchWord.text) // Remove empty words
+ .reduce((chunks, searchWord) => {
+ let searchText = searchWord.text;
+ if (autoEscape) {
+ searchText = escapeRegExpFn(searchText);
+ }
+ const regex = new RegExp(searchText, caseSensitive ? 'g' : 'gi');
+
+ let match;
+ while ((match = regex.exec(sourceString))) {
+ const start = match.index;
+ const end = regex.lastIndex;
+ if (end > start) {
+ chunks.push({
+ highlight: true,
+ start,
+ end,
+ className: searchWord.className,
+ style: searchWord.style
+ });
+ }
+ if (match.index === regex.lastIndex) {
+ regex.lastIndex++;
+ }
+ }
+ return chunks;
+ }, [])
+ );
+
+ /**
+ * Takes an array of {start:number, end:number} objects and combines chunks that overlap into single chunks.
+ * @return {start:number, end:number}[]
+ */
+ combineChunks = ({ chunks }: { chunks: Chunk[] }): Chunk[] => {
+ return chunks
+ .sort((first, second) => first.start - second.start)
+ .reduce((processedChunks, nextChunk) => {
+ // First chunk just goes straight in the array...
+ if (processedChunks.length === 0) {
+ return [nextChunk];
+ } else {
+ // ... subsequent chunks get checked to see if they overlap...
+ const prevChunk = processedChunks.pop();
+ if (nextChunk.start <= prevChunk.end) {
+ // It may be the case that prevChunk completely surrounds nextChunk, so take the
+ // largest of the end indeces.
+ const endIndex = Math.max(prevChunk.end, nextChunk.end);
+ processedChunks.push({
+ highlight: true,
+ start: prevChunk.start,
+ end: endIndex,
+ className: prevChunk.className || nextChunk.className,
+ style: { ...prevChunk.style, ...nextChunk.style }
+ });
+ } else {
+ processedChunks.push(prevChunk, nextChunk);
+ }
+ return processedChunks;
+ }
+ }, []);
+ };
+
+ /**
+ * Given a set of chunks to highlight, create an additional set of chunks
+ * to represent the bits of text between the highlighted text.
+ * @param chunksToHighlight {start:number, end:number}[]
+ * @param totalLength number
+ * @return {start:number, end:number, highlight:boolean}[]
+ */
+ fillInChunks = ({ chunksToHighlight, totalLength }: { chunksToHighlight: Chunk[]; totalLength: number }): Chunk[] => {
+ const allChunks: Chunk[] = [];
+ const append = (start: number, end: number, highlight: boolean, className?: string, style?: Record) => {
+ if (end - start > 0) {
+ allChunks.push({
+ start,
+ end,
+ highlight,
+ className,
+ style
+ });
+ }
+ };
+
+ if (chunksToHighlight.length === 0) {
+ append(0, totalLength, false);
+ } else {
+ let lastIndex = 0;
+ chunksToHighlight.forEach(chunk => {
+ append(lastIndex, chunk.start, false);
+ append(chunk.start, chunk.end, true, chunk.className, chunk.style);
+ lastIndex = chunk.end;
+ });
+ append(lastIndex, totalLength, false);
+ }
+ return allChunks;
+ };
+
+}
+
+
+
+
+
diff --git a/packages/semi-foundation/tree/tree.scss b/packages/semi-foundation/tree/tree.scss
index f1f8ac9fbd..ffc53fdce2 100644
--- a/packages/semi-foundation/tree/tree.scss
+++ b/packages/semi-foundation/tree/tree.scss
@@ -137,6 +137,8 @@ $module: #{$prefix}-tree;
&-highlight {
font-weight: $font-tree_option_hightlight-fontWeight;
color: $color-tree_option_hightlight-text;
+ // set inherit to override highlight component default bgc
+ background-color: inherit;
}
&-hidden {
diff --git a/packages/semi-foundation/utils/getHighlight.ts b/packages/semi-foundation/utils/getHighlight.ts
deleted file mode 100644
index f08d5e4bc9..0000000000
--- a/packages/semi-foundation/utils/getHighlight.ts
+++ /dev/null
@@ -1,178 +0,0 @@
-// Modified version based on 'highlight-words-core'
-import { isString } from 'lodash';
-
-const escapeRegExpFn = (string: string) => string.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
-interface ChunkQuery {
- autoEscape?: boolean;
- caseSensitive?: boolean;
- searchWords: string[];
- sourceString: string
-}
-interface Chunk {
- start: number;
- end: number;
- highlight: boolean
-}
-/**
- * Examine text for any matches.
- * If we find matches, add them to the returned array as a "chunk" object ({start:number, end:number}).
- * @return { start:number, end:number }[]
- */
-const findChunks = ({
- autoEscape,
- caseSensitive,
- searchWords,
- sourceString
-}: ChunkQuery): Chunk[] => (
- searchWords
- .filter(searchWord => searchWord) // Remove empty words
- .reduce((chunks, searchWord) => {
- if (autoEscape) {
- searchWord = escapeRegExpFn(searchWord);
- }
- const regex = new RegExp(searchWord, caseSensitive ? 'g' : 'gi');
-
- let match;
- while ((match = regex.exec(sourceString))) {
- const start = match.index;
- const end = regex.lastIndex;
- // We do not return zero-length matches
- if (end > start) {
- chunks.push({ highlight: false, start, end });
- }
- // Prevent browsers like Firefox from getting stuck in an infinite loop
- // See http://www.regexguru.com/2008/04/watch-out-for-zero-length-matches/
- if (match.index === regex.lastIndex) {
- regex.lastIndex++;
- }
- }
- return chunks;
- }, [])
-);
-
-/**
- * Takes an array of {start:number, end:number} objects and combines chunks that overlap into single chunks.
- * @return {start:number, end:number}[]
- */
-const combineChunks = ({ chunks }: { chunks: Chunk[] }) => {
- chunks = chunks
- .sort((first, second) => first.start - second.start)
- .reduce((processedChunks, nextChunk) => {
- // First chunk just goes straight in the array...
- if (processedChunks.length === 0) {
- return [nextChunk];
- } else {
- // ... subsequent chunks get checked to see if they overlap...
- const prevChunk = processedChunks.pop();
- if (nextChunk.start <= prevChunk.end) {
- // It may be the case that prevChunk completely surrounds nextChunk, so take the
- // largest of the end indeces.
- const endIndex = Math.max(prevChunk.end, nextChunk.end);
- processedChunks.push({
- highlight: false,
- start: prevChunk.start,
- end: endIndex
- });
- } else {
- processedChunks.push(prevChunk, nextChunk);
- }
- return processedChunks;
- }
- }, []);
-
- return chunks;
-};
-
-
-/**
- * Given a set of chunks to highlight, create an additional set of chunks
- * to represent the bits of text between the highlighted text.
- * @param chunksToHighlight {start:number, end:number}[]
- * @param totalLength number
- * @return {start:number, end:number, highlight:boolean}[]
- */
-const fillInChunks = ({ chunksToHighlight, totalLength }: { chunksToHighlight: Chunk[]; totalLength: number }) => {
- const allChunks: Chunk[] = [];
- const append = (start: number, end: number, highlight: boolean) => {
- if (end - start > 0) {
- allChunks.push({
- start,
- end,
- highlight
- });
- }
- };
-
- if (chunksToHighlight.length === 0) {
- append(0, totalLength, false);
- } else {
- let lastIndex = 0;
- chunksToHighlight.forEach(chunk => {
- append(lastIndex, chunk.start, false);
- append(chunk.start, chunk.end, true);
- lastIndex = chunk.end;
- });
- append(lastIndex, totalLength, false);
- }
- return allChunks;
-};
-
-
-/**
- * Creates an array of chunk objects representing both higlightable and non highlightable pieces of text that match each search word.
- *
- findAll ['z'], 'aaazaaazaaa'
- result #=> [
- { start: 0, end: 3, highlight: false }
- { start: 3, end: 4, highlight: true }
- { start: 4, end: 7, highlight: false }
- { start: 7, end: 8, highlight: true }
- { start: 8, end: 11, highlight: false }
- ]
-
- findAll ['do', 'dollar'], 'aaa do dollar aaa'
- #=> chunks: [
- { start: 4, end: 6 },
- { start: 7, end: 9 },
- { start: 7, end: 13 },
- ]
- #=> chunksToHight: [
- { start: 4, end: 6 },
- { start: 7, end: 13 },
- ]
- #=> result: [
- { start: 0, end: 4, highlight: false },
- { start: 4, end: 6, highlight: true },
- { start: 6, end: 7, highlight: false },
- { start: 7, end: 13, highlight: true },
- { start: 13, end: 17, highlight: false },
- ]
-
- * @return Array of "chunks" (where a Chunk is { start:number, end:number, highlight:boolean })
- */
-
-const findAll = ({
- autoEscape = true,
- caseSensitive = false,
- searchWords,
- sourceString
-}: ChunkQuery) => {
- if (isString(searchWords)) {
- searchWords = [searchWords];
- }
-
- const chunks = findChunks({
- autoEscape,
- caseSensitive,
- searchWords,
- sourceString
- });
- const chunksToHighlight = combineChunks({ chunks });
- const result = fillInChunks({
- chunksToHighlight,
- totalLength: sourceString ? sourceString.length : 0
- });
- return result;
-};
-
-export { findAll };
\ No newline at end of file
diff --git a/packages/semi-ui/_utils/index.tsx b/packages/semi-ui/_utils/index.tsx
index 8f6d6dd0d5..d40892eae2 100644
--- a/packages/semi-ui/_utils/index.tsx
+++ b/packages/semi-ui/_utils/index.tsx
@@ -1,7 +1,6 @@
import React from 'react';
import { cloneDeepWith, set, get } from 'lodash';
import warning from '@douyinfe/semi-foundation/utils/warning';
-import { findAll } from '@douyinfe/semi-foundation/utils/getHighlight';
import { isHTMLElement } from '@douyinfe/semi-foundation/utils/dom';
import semiGlobal from "./semi-global";
/**
@@ -66,48 +65,6 @@ export function cloneDeep(value: any, customizer?: (value: any) => any) {
return undefined;
});
}
-
-/**
- * [getHighLightTextHTML description]
- *
- * @param {string} sourceString [source content text]
- * @param {Array} searchWords [keywords to be highlighted]
- * @param {object} option
- * @param {true} option.highlightTag [The tag wrapped by the highlighted content, mark is used by default]
- * @param {true} option.highlightClassName
- * @param {true} option.highlightStyle
- * @param {boolean} option.caseSensitive
- *
- * @return {Array}
- */
-export const getHighLightTextHTML = ({
- sourceString = '',
- searchWords = [],
- option = { autoEscape: true, caseSensitive: false }
-}: GetHighLightTextHTMLProps) => {
- const chunks: HighLightTextHTMLChunk[] = findAll({ sourceString, searchWords, ...option });
- const markEle = option.highlightTag || 'mark';
- const highlightClassName = option.highlightClassName || '';
- const highlightStyle = option.highlightStyle || {};
- return chunks.map((chunk: HighLightTextHTMLChunk, index: number) => {
- const { end, start, highlight } = chunk;
- const text = sourceString.substr(start, end - start);
- if (highlight) {
- return React.createElement(
- markEle,
- {
- style: highlightStyle,
- className: highlightClassName,
- key: text + index
- },
- text
- );
- } else {
- return text;
- }
- });
-};
-
export interface RegisterMediaQueryOption {
match?: (e: MediaQueryList | MediaQueryListEvent) => void;
unmatch?: (e: MediaQueryList | MediaQueryListEvent) => void;
@@ -140,25 +97,6 @@ export const registerMediaQuery = (media: string, { match, unmatch, callInInit =
}
return () => undefined;
};
-export interface GetHighLightTextHTMLProps {
- sourceString?: string;
- searchWords?: string[];
- option: HighLightTextHTMLOption
-}
-
-export interface HighLightTextHTMLOption {
- highlightTag?: string;
- highlightClassName?: string;
- highlightStyle?: React.CSSProperties;
- caseSensitive: boolean;
- autoEscape: boolean
-}
-
-export interface HighLightTextHTMLChunk {
- start?: number;
- end?: number;
- highlight?: any
-}
/**
* Determine whether the incoming element is a built-in icon
diff --git a/packages/semi-ui/autoComplete/option.tsx b/packages/semi-ui/autoComplete/option.tsx
index 6fd07a9843..76158f4075 100644
--- a/packages/semi-ui/autoComplete/option.tsx
+++ b/packages/semi-ui/autoComplete/option.tsx
@@ -5,7 +5,7 @@ import { isString } from 'lodash';
import { cssClasses } from '@douyinfe/semi-foundation/autoComplete/constants';
import LocaleConsumer from '../locale/localeConsumer';
import { IconTick } from '@douyinfe/semi-icons';
-import { getHighLightTextHTML } from '../_utils/index';
+import Highlight from '../highlight';
import { Locale } from '../locale/interface';
import { BasicOptionProps } from '@douyinfe/semi-foundation/autoComplete/optionFoundation';
@@ -19,15 +19,6 @@ export interface OptionProps extends BasicOptionProps {
className?: string;
style?: React.CSSProperties
}
-interface renderOptionContentArgument {
- config: {
- searchWords: any;
- sourceString: React.ReactNode
- };
- children: React.ReactNode;
- inputValue: string;
- prefixCls: string
-}
class Option extends PureComponent {
static isSelectOption = true;
@@ -62,9 +53,13 @@ class Option extends PureComponent {
}
}
- renderOptionContent({ config, children, inputValue, prefixCls }: renderOptionContentArgument) {
+ renderOptionContent({ children, inputValue, prefixCls }) {
if (isString(children) && inputValue) {
- return getHighLightTextHTML(config as any);
+ return ( );
}
return children;
}
@@ -129,13 +124,6 @@ class Option extends PureComponent {
});
}
- const config = {
- searchWords: inputValue,
- sourceString: children,
- option: {
- highlightClassName: `${prefixCls}-keyword`
- }
- };
return (
// eslint-disable-next-line jsx-a11y/interactive-supports-focus,jsx-a11y/click-events-have-key-events
{
) : null}
- {isString(children) ? {this.renderOptionContent({ children, config, inputValue, prefixCls })}
: children}
+ {isString(children) ? {this.renderOptionContent({ children, inputValue, prefixCls })}
: children}
);
}
diff --git a/packages/semi-ui/highlight/_story/highlight.stories.jsx b/packages/semi-ui/highlight/_story/highlight.stories.jsx
index c776022186..e412256bec 100644
--- a/packages/semi-ui/highlight/_story/highlight.stories.jsx
+++ b/packages/semi-ui/highlight/_story/highlight.stories.jsx
@@ -1,8 +1,6 @@
import React from 'react';
import ReactDOM from 'react-dom';
-
-import { Skeleton, Avatar, Button, ButtonGroup, Spin, Highlight } from '../../index';
-
+import { Highlight } from '../../index';
const searchWords = ['do', 'dollar'];
const sourceString = 'aaa do dollar aaa';
@@ -11,7 +9,7 @@ export default {
title: 'Highlight'
}
-export const HighlightTag = () => (
+export const HighlightBase = () => (
(
);
-HighlightTag.story = {
- name: 'different tag',
-};
export const HighlightStyle = () => (
@@ -36,6 +31,29 @@ export const HighlightStyle = () => (
);
-HighlightStyle.story = {
- name: 'custom style',
+export const HighlightClassName = () => (
+
+
+
+);
+
+export const MutilpleSearchWords = () => {
+ return (
+
+ )
};
+
diff --git a/packages/semi-ui/highlight/index.tsx b/packages/semi-ui/highlight/index.tsx
index 6a6d7e8c18..25a8a59513 100644
--- a/packages/semi-ui/highlight/index.tsx
+++ b/packages/semi-ui/highlight/index.tsx
@@ -2,14 +2,32 @@ import React, { PureComponent } from 'react';
import cls from 'classnames';
import PropTypes, { string } from 'prop-types';
import { cssClasses } from '@douyinfe/semi-foundation/highlight/constants';
-import { getHighLightTextHTML } from '../_utils/index';
+import HighlightFoundation from '@douyinfe/semi-foundation/highlight/foundation';
+import type { SearchWords, Chunk } from '@douyinfe/semi-foundation/highlight/foundation';
+
import '@douyinfe/semi-foundation/highlight/highlight.scss';
+interface GetHighLightTextHTMLProps {
+ sourceString?: string;
+ searchWords?: SearchWords;
+ option: HighLightTextHTMLOption
+}
+
+interface HighLightTextHTMLOption {
+ highlightTag?: string;
+ highlightClassName?: string;
+ highlightStyle?: React.CSSProperties;
+ caseSensitive: boolean;
+ autoEscape: boolean
+}
+
+interface HighLightTextHTMLChunk extends Chunk { }
+
export interface HighlightProps {
autoEscape?: boolean;
caseSensitive?: boolean;
sourceString?: string;
- searchWords?: Array;
+ searchWords?: SearchWords;
highlightStyle?: React.CSSProperties;
highlightClassName?: string;
component?: string
@@ -38,6 +56,34 @@ class Highlight extends PureComponent {
sourceString: '',
};
+ getHighLightTextHTML = ({
+ sourceString = '',
+ searchWords = [],
+ option = { autoEscape: true, caseSensitive: false }
+ }: GetHighLightTextHTMLProps) => {
+ const chunks: HighLightTextHTMLChunk[] = new HighlightFoundation().findAll({ sourceString, searchWords, ...option });
+ const markEle = option.highlightTag || 'mark';
+ const highlightClassName = option.highlightClassName || '';
+ const highlightStyle = option.highlightStyle || {};
+ return chunks.map((chunk: HighLightTextHTMLChunk, index: number) => {
+ const { end, start, highlight, style, className } = chunk;
+ const text = sourceString.substr(start, end - start);
+ if (highlight) {
+ return React.createElement(
+ markEle,
+ {
+ style: { ...highlightStyle, ...style },
+ className: `${highlightClassName} ${className || ''}`.trim(),
+ key: text + index
+ },
+ text
+ );
+ } else {
+ return text;
+ }
+ });
+ };
+
render() {
const {
searchWords,
@@ -62,7 +108,7 @@ class Highlight extends PureComponent {
};
return (
- getHighLightTextHTML({ sourceString, searchWords, option })
+ this.getHighLightTextHTML({ sourceString, searchWords, option })
);
}
}
diff --git a/packages/semi-ui/select/option.tsx b/packages/semi-ui/select/option.tsx
index 379c9bb1ff..fa6d0963e4 100644
--- a/packages/semi-ui/select/option.tsx
+++ b/packages/semi-ui/select/option.tsx
@@ -5,7 +5,7 @@ import { isString } from 'lodash';
import { cssClasses } from '@douyinfe/semi-foundation/select/constants';
import LocaleConsumer from '../locale/localeConsumer';
import { IconTick } from '@douyinfe/semi-icons';
-import { getHighLightTextHTML } from '../_utils/index';
+import Highlight, { HighlightProps } from '../highlight';
import { Locale } from '../locale/interface';
import getDataAttr from '@douyinfe/semi-foundation/utils/getDataAttr';
import type { BasicOptionProps } from '@douyinfe/semi-foundation/select/optionFoundation';
@@ -20,15 +20,6 @@ export interface OptionProps extends BasicOptionProps {
className?: string;
style?: React.CSSProperties
}
-interface renderOptionContentArgument {
- config: {
- searchWords: any;
- sourceString: React.ReactNode
- };
- children: React.ReactNode;
- inputValue: string;
- prefixCls: string
-}
class Option extends PureComponent {
static isSelectOption = true;
@@ -63,9 +54,15 @@ class Option extends PureComponent {
}
}
- renderOptionContent({ config, children, inputValue, prefixCls }: renderOptionContentArgument) {
+ renderOptionContent({ config, children, inputValue, prefixCls }) {
if (isString(children) && inputValue) {
- return getHighLightTextHTML(config as any);
+ return (
+
+ );
}
return children;
}
@@ -139,12 +136,11 @@ class Option extends PureComponent {
}
const config = {
- searchWords: inputValue,
+ searchWords: [inputValue],
sourceString: children,
- option: {
- highlightClassName: `${prefixCls}-keyword`
- }
+ highlightClassName: `${prefixCls}-keyword`
};
+
return (
// eslint-disable-next-line jsx-a11y/interactive-supports-focus,jsx-a11y/click-events-have-key-events
+ );
} else {
return label;
}