From 2e56e30af6ed37b16afc6993ccc9a94d6e255e78 Mon Sep 17 00:00:00 2001 From: xiamiao1121 <74885998+xiamiao1121@users.noreply.github.com> Date: Fri, 28 Jun 2024 15:36:45 +0800 Subject: [PATCH] =?UTF-8?q?feat(search):=20=E6=94=AF=E6=8C=81=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E5=AD=97=E6=AE=B5=E5=88=AB=E5=90=8D(#2886)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(search): 新增支持配置字段别名(#2886) * chore: 生成变更记录文件 * feat(search): 修改fieldNames类型 * feat(search): 代码规范 * feat(search): 去掉条件判断 --------- Co-authored-by: xiamiao --- .changeset/olive-mails-grin.md | 5 ++++ .changeset/soft-cobras-film.md | 5 ++++ packages/ui/search/src/Search.tsx | 45 ++++++++++++++++++------------- packages/ui/search/src/util.ts | 31 +++++++++++++++++++++ 4 files changed, 68 insertions(+), 18 deletions(-) create mode 100644 .changeset/olive-mails-grin.md create mode 100644 .changeset/soft-cobras-film.md create mode 100644 packages/ui/search/src/util.ts diff --git a/.changeset/olive-mails-grin.md b/.changeset/olive-mails-grin.md new file mode 100644 index 000000000..e0e473375 --- /dev/null +++ b/.changeset/olive-mails-grin.md @@ -0,0 +1,5 @@ +--- +"@hi-ui/hiui": patch +--- + +feat(search): 支持配置字段别名 diff --git a/.changeset/soft-cobras-film.md b/.changeset/soft-cobras-film.md new file mode 100644 index 000000000..837411bce --- /dev/null +++ b/.changeset/soft-cobras-film.md @@ -0,0 +1,5 @@ +--- +"@hi-ui/search": minor +--- + +feat: 支持配置字段别名 diff --git a/packages/ui/search/src/Search.tsx b/packages/ui/search/src/Search.tsx index 1bd5afba0..656b62cdb 100644 --- a/packages/ui/search/src/Search.tsx +++ b/packages/ui/search/src/Search.tsx @@ -1,4 +1,4 @@ -import React, { forwardRef, useState, useCallback, useRef } from 'react' +import React, { forwardRef, useState, useCallback, useRef, useMemo } from 'react' import { cx, getPrefixCls } from '@hi-ui/classname' import { __DEV__ } from '@hi-ui/env' import { Input, InputProps } from '@hi-ui/input' @@ -11,6 +11,8 @@ import { SearchDataItem } from './types' import { callAllFuncs } from '@hi-ui/func-utils' import type { PopperOverlayProps } from '@hi-ui/popper' import { SearchDropdown } from './SearchDropdown' +import { transformData } from './util' +import { HiBaseFieldNames } from '@hi-ui/core' const SEARCH_PREFIX = getPrefixCls('search') const NOOP_ARRAY = [] as [] @@ -32,6 +34,7 @@ export const Search = forwardRef( onChange, onSearch: onSearchProp, data = NOOP_ARRAY, + fieldNames, overlayClassName, // input onFocus, @@ -41,6 +44,8 @@ export const Search = forwardRef( }, ref ) => { + const transformedData = useMemo(() => transformData(data, fieldNames), [data, fieldNames]) + const [visible, setVisible] = useState(false) const targetElRef = useRef(null) @@ -73,17 +78,17 @@ export const Search = forwardRef( if (direction === 'up') { if (focusIndex === null) { - newFocusIndex = data.length - 1 - const focusItem = data[newFocusIndex] + newFocusIndex = transformedData.length - 1 + const focusItem = transformedData[newFocusIndex] if (focusItem && isArrayNonEmpty(focusItem.children)) { newSubFocusIndex = focusItem.children.length - 1 } } else { - const focusItem = data[focusIndex] + const focusItem = transformedData[focusIndex] if (focusItem && isArrayNonEmpty(focusItem.children)) { if (subFocusIndex === 0) { - newFocusIndex = focusIndex === 0 ? data.length - 1 : focusIndex - 1 - const nextFocusItem = data[newFocusIndex] + newFocusIndex = focusIndex === 0 ? transformedData.length - 1 : focusIndex - 1 + const nextFocusItem = transformedData[newFocusIndex] if (nextFocusItem && isArrayNonEmpty(nextFocusItem.children)) { newSubFocusIndex = nextFocusItem.children.length - 1 } @@ -92,8 +97,8 @@ export const Search = forwardRef( newSubFocusIndex = subFocusIndex !== null ? subFocusIndex - 1 : 0 } } else { - newFocusIndex = focusIndex === 0 ? data.length - 1 : focusIndex - 1 - const nextFocusItem = data[newFocusIndex] + newFocusIndex = focusIndex === 0 ? transformedData.length - 1 : focusIndex - 1 + const nextFocusItem = transformedData[newFocusIndex] if (nextFocusItem && isArrayNonEmpty(nextFocusItem.children)) { newSubFocusIndex = nextFocusItem.children.length - 1 @@ -104,7 +109,7 @@ export const Search = forwardRef( // 不存在 focusIndex if (focusIndex === null) { newFocusIndex = 0 - const nextFocusItem = data[newFocusIndex] + const nextFocusItem = transformedData[newFocusIndex] if (nextFocusItem && isArrayNonEmpty(nextFocusItem.children)) { newSubFocusIndex = 0 @@ -112,12 +117,12 @@ export const Search = forwardRef( } else { // 存在 focusIndex // 当前focus 项没有子项 - const focusItem = data[focusIndex] + const focusItem = transformedData[focusIndex] if (focusItem && isArrayNonEmpty(focusItem.children)) { // 当前focus 有子项 if (subFocusIndex === focusItem.children.length - 1) { - newFocusIndex = focusIndex === data.length - 1 ? 0 : focusIndex + 1 - const nextFocusItem = data[newFocusIndex] + newFocusIndex = focusIndex === transformedData.length - 1 ? 0 : focusIndex + 1 + const nextFocusItem = transformedData[newFocusIndex] if (nextFocusItem && isArrayNonEmpty(nextFocusItem.children)) { newSubFocusIndex = 0 @@ -127,8 +132,8 @@ export const Search = forwardRef( newSubFocusIndex = subFocusIndex !== null ? subFocusIndex + 1 : 0 } } else { - newFocusIndex = focusIndex === data.length - 1 ? 0 : focusIndex + 1 - const nextFocusItem = data[newFocusIndex] + newFocusIndex = focusIndex === transformedData.length - 1 ? 0 : focusIndex + 1 + const nextFocusItem = transformedData[newFocusIndex] if (nextFocusItem && isArrayNonEmpty(nextFocusItem.children)) { newSubFocusIndex = 0 @@ -167,8 +172,8 @@ export const Search = forwardRef( evt.preventDefault() let nextValue = '' as React.ReactText - if (focusIndex !== null && isArrayNonEmpty(data)) { - const focusItem = data[focusIndex] + if (focusIndex !== null && isArrayNonEmpty(transformedData)) { + const focusItem = transformedData[focusIndex] if (subFocusIndex !== null && isArrayNonEmpty(focusItem.children)) { nextValue = focusItem.children[subFocusIndex].title @@ -222,7 +227,7 @@ export const Search = forwardRef( } {...rest} /> - {loading || isArrayNonEmpty(data) ? ( + {loading || isArrayNonEmpty(transformedData) ? ( ( className: overlayClassName, }} loading={loading} - data={data} + data={transformedData} focusIndex={focusIndex} subFocusIndex={subFocusIndex} keyword={value} @@ -277,6 +282,10 @@ export interface SearchProps extends Omit * 搜索结果的数据 */ data?: SearchDataItem[] + /** + * 设置 data 中 id, title, children 对应的 key + */ + fieldNames?: HiBaseFieldNames /** * 自定义控制 popper 行为 */ diff --git a/packages/ui/search/src/util.ts b/packages/ui/search/src/util.ts new file mode 100644 index 000000000..c10531ef5 --- /dev/null +++ b/packages/ui/search/src/util.ts @@ -0,0 +1,31 @@ +import { HiBaseFieldNameKeys, HiBaseFieldNames } from '@hi-ui/core' +import { SearchDataItem } from './types' +import React from 'react' + +export const transformData = ( + data: SearchDataItem[], + fieldNames?: HiBaseFieldNames +): SearchDataItem[] => { + /** + * 转换对象 + */ + const getKeyFields = (node: SearchDataItem, key: HiBaseFieldNameKeys) => { + if (fieldNames) { + return node[(fieldNames[key] || key) as keyof SearchDataItem] + } + return node[key as keyof SearchDataItem] + } + + const traverseTreeNode = (node: SearchDataItem): SearchDataItem => { + const newNode: SearchDataItem = { ...node } + + newNode.id = getKeyFields(newNode, 'id') as React.ReactText + newNode.title = getKeyFields(newNode, 'title') as string + newNode.children = getKeyFields(newNode, 'children') as SearchDataItem[] + if (newNode.children) newNode.children = newNode.children.map(traverseTreeNode) + + return newNode + } + + return data.map(traverseTreeNode) +}