diff --git a/libs/extension/src/components/Search.tsx b/libs/extension/src/components/Search.tsx index 0686a79b..7418bc71 100644 --- a/libs/extension/src/components/Search.tsx +++ b/libs/extension/src/components/Search.tsx @@ -1,7 +1,19 @@ import styles from './Search.less'; -export default function Search() { +interface SearchProps { + onChange: (event: any) => void, +} + +export default function Search(props: SearchProps) { + const { onChange } = props; + const handleChange = (event) => { + onChange(event.target.value); + } return ( - + ) } \ No newline at end of file diff --git a/libs/extension/src/components/VTree.tsx b/libs/extension/src/components/VTree.tsx index 6e594539..91a7c42e 100644 --- a/libs/extension/src/components/VTree.tsx +++ b/libs/extension/src/components/VTree.tsx @@ -1,6 +1,7 @@ import { useState } from 'horizon'; import styles from './VTree.less'; import Arrow from '../svgs/Arrow'; +import { createRegExp } from './../utils'; export interface IData { id: string; @@ -16,6 +17,7 @@ type IItem = { onClick: (id: string) => void, isCollapsed: boolean, isSelect: boolean, + highlightValue: string, } & IData // TODO: 计算可以展示的最多数量,并且监听显示器高度变化修改数值 @@ -35,6 +37,7 @@ function Item(props: IItem) { indentation, onClick, isSelect, + highlightValue, } = props; const isShowKey = userKey !== ''; const showIcon = hasChild ? : ''; @@ -49,13 +52,30 @@ function Item(props: IItem) { itemAttr.tabIndex = 0; itemAttr.className = styles.treeItem + ' ' + styles.select } + const reg = createRegExp(highlightValue); + const heightCharacters = name.match(reg); + let showName; + if (heightCharacters) { + let cutName = name; + showName = []; + // 高亮第一次匹配即可 + const char = heightCharacters[0]; + let index = name.search(char); + const notHighlightStr = cutName.slice(0, index); + showName.push(notHighlightStr); + showName.push({char}); + cutName = cutName.slice(index + char.length); + showName.push(cutName); + } else { + showName = name; + } return (
{showIcon}
- {name} + {showName} {isShowKey && ( <> @@ -73,7 +93,7 @@ function Item(props: IItem) { ) } -function VTree({ data }: { data: IData[] }) { +function VTree({ data, highlightValue }: { data: IData[], highlightValue: string }) { const [scrollTop, setScrollTop] = useState(0); const [collapseNode, setCollapseNode] = useState(new Set()); const [selectItem, setSelectItem] = useState(); @@ -124,6 +144,7 @@ function VTree({ data }: { data: IData[] }) { onClick={handleClickItem} isCollapsed={isCollapsed} isSelect={id === selectItem} + highlightValue={highlightValue} {...item} /> ) } diff --git a/libs/extension/src/panel/App.tsx b/libs/extension/src/panel/App.tsx index 73b409ac..871ad0ad 100644 --- a/libs/extension/src/panel/App.tsx +++ b/libs/extension/src/panel/App.tsx @@ -9,6 +9,7 @@ import { mockParsedVNodeData, parsedMockState } from '../devtools/mock'; function App() { const [parsedVNodeData, setParsedVNodeData] = useState([]); const [componentInfo, setComponentInfo] = useState({name: null, attrs: {}}); + const [filterValue, setFilterValue] = useState(''); useEffect(() => { if (isDev) { setParsedVNodeData(mockParsedVNodeData); @@ -42,6 +43,11 @@ function App() { }; data.push(item); } + + const handleSearchChange = (str: string) => { + setFilterValue(str); + } + return (
@@ -51,11 +57,11 @@ function App() {
- +
- +
diff --git a/libs/extension/src/utils.ts b/libs/extension/src/utils.ts new file mode 100644 index 00000000..727c672d --- /dev/null +++ b/libs/extension/src/utils.ts @@ -0,0 +1,15 @@ + +export function createRegExp(expression: string){ + let str = expression; + if (str[0] === '/') { + str = str.slice(1); + } + if (str[str.length - 1] === '/') { + str = str.slice(0, str.length - 1); + } + try { + return new RegExp(str, 'i'); + }catch(err) { + return null; + } +} \ No newline at end of file