diff --git a/packages/pro/search/demo/Parser.md b/packages/pro/search/demo/Parser.md
new file mode 100644
index 000000000..615e02f57
--- /dev/null
+++ b/packages/pro/search/demo/Parser.md
@@ -0,0 +1,6 @@
+---
+order: 50
+title:
+ zh: 使用 `useParser` 解析搜索值
+ en: Parse search value using `useParser`
+---
diff --git a/packages/pro/search/demo/Parser.vue b/packages/pro/search/demo/Parser.vue
new file mode 100644
index 000000000..abb040f4e
--- /dev/null
+++ b/packages/pro/search/demo/Parser.vue
@@ -0,0 +1,305 @@
+
+
+
+
+
+
+
+
diff --git a/packages/pro/search/index.ts b/packages/pro/search/index.ts
index 1d0923e91..c02a66933 100644
--- a/packages/pro/search/index.ts
+++ b/packages/pro/search/index.ts
@@ -14,6 +14,7 @@ const IxProSearch = ProSearch as unknown as ProSearchComponent
const IxProSearchShortcut = ProSearchShortcut as unknown as ProSearchShortcutComponent
export { IxProSearch, IxProSearchShortcut }
+export { useParser } from './src/useParser'
export type {
ProSearchSize,
@@ -29,3 +30,5 @@ export type {
SearchItemCreateContext,
SearchItemConfirmContext,
} from './src/types'
+
+export type { ParserContext, ParseResult } from './src/useParser'
diff --git a/packages/pro/search/src/ProSearch.tsx b/packages/pro/search/src/ProSearch.tsx
index 1ef249e49..74cc0948c 100644
--- a/packages/pro/search/src/ProSearch.tsx
+++ b/packages/pro/search/src/ProSearch.tsx
@@ -46,6 +46,7 @@ export default defineComponent({
() => !!props.searchFields?.some(field => !!field.quickSelect && !field.multiple),
)
+ const searchFields = computed(() => props.searchFields ?? [])
const quickSelectOverlayOpened = computed(() => quickSelectActive.value && overlayOpened.value)
const elementRef = ref()
@@ -54,7 +55,7 @@ export default defineComponent({
const searchValueContext = useSearchValues(props)
const { searchValues } = searchValueContext
- const resolvedSearchFieldsContext = useResolvedSearchFields(props, mergedPrefixCls, dateConfig)
+ const resolvedSearchFieldsContext = useResolvedSearchFields(searchFields, mergedPrefixCls, dateConfig)
const { fieldKeyMap } = resolvedSearchFieldsContext
const searchStateContext = useSearchStates(props, fieldKeyMap, searchValueContext)
const { searchStates, initSearchStates, clearSearchState, updateSearchValues, isSegmentVisible } =
diff --git a/packages/pro/search/src/composables/useResolvedSearchFields.ts b/packages/pro/search/src/composables/useResolvedSearchFields.ts
index 36170c902..12de6ef76 100644
--- a/packages/pro/search/src/composables/useResolvedSearchFields.ts
+++ b/packages/pro/search/src/composables/useResolvedSearchFields.ts
@@ -5,7 +5,7 @@
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
*/
-import type { ProSearchProps, ResolvedSearchField, SearchField, Segment } from '../types'
+import type { ResolvedSearchField, SearchField, Segment } from '../types'
import type { VKey } from '@idux/cdk/utils'
import type { DateConfig } from '@idux/components/config'
@@ -26,13 +26,13 @@ export interface ResolvedSearchFieldsContext {
}
export function useResolvedSearchFields(
- props: ProSearchProps,
+ searchFields: ComputedRef,
mergedPrefixCls: ComputedRef,
dateConfig: DateConfig,
): ResolvedSearchFieldsContext {
const resolvedSearchFields = computed(
() =>
- props.searchFields?.map(searchField => {
+ searchFields.value.map(searchField => {
return {
...searchField,
segments: [
diff --git a/packages/pro/search/src/composables/useSearchStates.ts b/packages/pro/search/src/composables/useSearchStates.ts
index 99dbed69b..9a6321697 100644
--- a/packages/pro/search/src/composables/useSearchStates.ts
+++ b/packages/pro/search/src/composables/useSearchStates.ts
@@ -12,7 +12,9 @@ import { type ComputedRef, type Ref, computed, ref, toRaw } from 'vue'
import { isEqual, isNil } from 'lodash-es'
-import { type VKey, callEmit, convertArray } from '@idux/cdk/utils'
+import { type VKey, callEmit } from '@idux/cdk/utils'
+
+import { generateSegmentStates } from '../utils'
export interface SearchState {
key: VKey
@@ -443,24 +445,6 @@ function createStateKeyGetter() {
}
}
-function generateSegmentStates(
- searchField: ResolvedSearchField,
- searchValue?: Omit,
-): SegmentState[] {
- const segments = searchField.segments
- const hasOperators = searchField.operators && searchField.operators.length > 0
- const operator = searchValue?.operator ?? searchField.operators?.find(op => op === searchField.defaultOperator)
- const value = searchValue?.value ?? searchField.defaultValue
- const valueArr = segments.length > (hasOperators ? 2 : 1) ? convertArray(value) : [value]
- const segmentValues = hasOperators ? [operator, ...valueArr] : valueArr
-
- return segments.map((segment, idx) => ({
- name: segment.name,
- value: segmentValues[idx],
- input: segment.format(segmentValues[idx], []),
- }))
-}
-
function compareSearchValues(newSearchValues: SearchValue[] | undefined, oldSearchValues: SearchValue[] | undefined) {
if (!newSearchValues && !oldSearchValues) {
return true
diff --git a/packages/pro/search/src/useParser.ts b/packages/pro/search/src/useParser.ts
new file mode 100644
index 000000000..7adec45d0
--- /dev/null
+++ b/packages/pro/search/src/useParser.ts
@@ -0,0 +1,57 @@
+/**
+ * @license
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
+ */
+
+import type { SearchField, SearchValue, SegmentState } from './types'
+import type { VKey } from '@idux/cdk/utils'
+
+import { type Ref, computed } from 'vue'
+
+import { useDateConfig } from '@idux/components/config'
+
+import { useResolvedSearchFields } from './composables/useResolvedSearchFields'
+import { generateSegmentStates } from './utils'
+
+export interface ParseResult {
+ key: VKey
+ label?: string
+ segments: SegmentState[]
+}
+
+export interface ParserContext {
+ parse: (searchValues: SearchValue[]) => ParseResult[]
+}
+
+export function useParser(searchFields: Ref | SearchField[]): ParserContext {
+ const dateConfig = useDateConfig()
+ const { fieldKeyMap } = useResolvedSearchFields(
+ computed(() => ('value' in searchFields ? searchFields.value : searchFields)),
+ computed(() => '__pro-search-parser__'),
+ dateConfig,
+ )
+
+ const parse = (searchValues: SearchValue[]) => {
+ return searchValues
+ .map(value => {
+ const field = fieldKeyMap.value.get(value.key)
+
+ if (field) {
+ return {
+ key: value.key,
+ label: field.label,
+ segments: generateSegmentStates(field, value),
+ }
+ }
+
+ return
+ })
+ .filter(Boolean) as ParseResult[]
+ }
+
+ return {
+ parse,
+ }
+}
diff --git a/packages/pro/search/src/utils/generateSegmentStates.ts b/packages/pro/search/src/utils/generateSegmentStates.ts
new file mode 100644
index 000000000..3e3202689
--- /dev/null
+++ b/packages/pro/search/src/utils/generateSegmentStates.ts
@@ -0,0 +1,28 @@
+/**
+ * @license
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
+ */
+
+import type { ResolvedSearchField, SearchValue, SegmentState } from '../types'
+
+import { convertArray } from '@idux/cdk/utils'
+
+export function generateSegmentStates(
+ searchField: ResolvedSearchField,
+ searchValue?: Omit,
+): SegmentState[] {
+ const segments = searchField.segments
+ const hasOperators = searchField.operators && searchField.operators.length > 0
+ const operator = searchValue?.operator ?? searchField.operators?.find(op => op === searchField.defaultOperator)
+ const value = searchValue?.value ?? searchField.defaultValue
+ const valueArr = segments.length > (hasOperators ? 2 : 1) ? convertArray(value) : [value]
+ const segmentValues = hasOperators ? [operator, ...valueArr] : valueArr
+
+ return segments.map((segment, idx) => ({
+ name: segment.name,
+ value: segmentValues[idx],
+ input: segment.format(segmentValues[idx], []),
+ }))
+}
diff --git a/packages/pro/search/src/utils/index.ts b/packages/pro/search/src/utils/index.ts
index be026cd43..650831d08 100644
--- a/packages/pro/search/src/utils/index.ts
+++ b/packages/pro/search/src/utils/index.ts
@@ -9,3 +9,4 @@ export * from './getSelectableCommonParams'
export * from './RenderIcon'
export * from './selectData'
export * from './measureTextWidth'
+export * from './generateSegmentStates'