diff --git a/libs/extension/src/components/FilterTree.ts b/libs/extension/src/components/FilterTree.ts new file mode 100644 index 00000000..4660c1b0 --- /dev/null +++ b/libs/extension/src/components/FilterTree.ts @@ -0,0 +1,77 @@ +// 过滤树的抽象逻辑实现 +// 需要知道渲染了哪些数据,搜索的字符串 +// 控制Tree组件位置跳转,告知搜索文本 +// 清空搜索框,告知搜索框当前是第几个结果,跳转搜索结果接口 + +import { useState, useRef } from 'horizon'; +import { createRegExp } from '../utils'; + +export function FilterTree(props: { data: T[] }) { + const { data } = props; + const [filterValue, setFilterValue] = useState(''); + const [selectId, setSelectId] = useState(null); + const showItems = useRef([]); + const matchItemsRef = useRef([]); + const matchItems = matchItemsRef.current; + const onChangeSearchValue = (search: string) => { + const reg = createRegExp(search); + let matchShowId = null; + let newMatchItems = []; + if (search !== '') { + newMatchItems = data.reduce((pre, current) => { + const { id, name } = current; + if (reg && name.match(reg)) { + pre.push(id); + if (matchShowId === null) { + matchShowId = id; + } + } + return pre; + }, []); + if (newMatchItems.length === 0) { + setSelectId(null); + } else { + if (matchShowId === null) { + setSelectId(newMatchItems[0]); + } else { + setSelectId(matchShowId); + } + } + } + matchItemsRef.current = newMatchItems; + setFilterValue(search); + }; + const onSelectNext = () => { + const index = matchItems.indexOf(selectId); + const nextIndex = index + 1; + if (nextIndex < matchItemsRef.current.length) { + setSelectId(matchItems[nextIndex]); + } + }; + const onSelectLast = () => { + const index = matchItems.indexOf(selectId); + const last = index - 1; + if (last >= 0) { + setSelectId(matchItems[last]); + } + }; + const setShowItems = (items) => { + showItems.current = [...items]; + }; + const onClear = () => { + onChangeSearchValue(''); + }; + return { + filterValue, + setFilterValue: onChangeSearchValue, + onClear, + selectId, + matchItems, + onSelectNext, + onSelectLast, + setShowItems, + }; +} diff --git a/libs/extension/src/components/Search.tsx b/libs/extension/src/components/Search.tsx index ce644325..1ea264d3 100644 --- a/libs/extension/src/components/Search.tsx +++ b/libs/extension/src/components/Search.tsx @@ -2,10 +2,11 @@ import styles from './Search.less'; interface SearchProps { onChange: (event: any) => void, + value: string, } export default function Search(props: SearchProps) { - const { onChange } = props; + const { onChange, value } = props; const handleChange = (event) => { onChange(event.target.value); }; @@ -13,6 +14,7 @@ export default function Search(props: SearchProps) { ); diff --git a/libs/extension/src/panel/App.less b/libs/extension/src/panel/App.less index f48e225a..dc0da330 100644 --- a/libs/extension/src/panel/App.less +++ b/libs/extension/src/panel/App.less @@ -17,6 +17,7 @@ flex: 0 0 @top-height; display: flex; align-items: center; + padding-right: 0.4rem; .select { padding: 0 0.25rem 0 0.25rem; @@ -33,6 +34,23 @@ .search { flex: 1 1 0; } + + .searchResult{ + flex: 0 0 ; + padding: 0 0.4rem; + } + + .searchAction { + padding: 0; + flex: 0 0 1rem; + border: none; + background: none; + height: 1rem; + color: @arrow-color; + &:hover{ + color: @hover-color; + } + } } .left_bottom { diff --git a/libs/extension/src/panel/App.tsx b/libs/extension/src/panel/App.tsx index 2b9ef6bc..1e9a9ae0 100644 --- a/libs/extension/src/panel/App.tsx +++ b/libs/extension/src/panel/App.tsx @@ -5,11 +5,14 @@ import ComponentInfo from '../components/ComponentInfo'; import styles from './App.less'; import Select from '../svgs/Select'; import { mockParsedVNodeData, parsedMockState } from '../devtools/mock'; +import { FilterTree } from '../components/FilterTree'; +import Close from '../svgs/Close'; +import Arrow from './../svgs/Arrow'; function App() { const [parsedVNodeData, setParsedVNodeData] = useState([]); const [componentInfo, setComponentInfo] = useState({ name: null, attrs: {} }); - const [filterValue, setFilterValue] = useState(''); + useEffect(() => { if (isDev) { setParsedVNodeData(mockParsedVNodeData); @@ -43,11 +46,25 @@ function App() { }; data.push(item); } + const { + filterValue, + setFilterValue, + onClear, + selectId, + matchItems, + onSelectNext, + onSelectLast, + setShowItems, + } = FilterTree({ data }); const handleSearchChange = (str: string) => { setFilterValue(str); }; + const onRendered = (info) => { + setShowItems(info.visibleItems); + }; + return (
@@ -57,11 +74,22 @@ function App() {
- +
+ {filterValue !== '' && <> + {`${matchItems.indexOf(selectId) + 1}/${matchItems.length}`} +
+ + + + }
- +