Skip to content

Commit

Permalink
feat(pro:search): searchField supports keywordFallback option (#1698)
Browse files Browse the repository at this point in the history
  • Loading branch information
sallerli1 committed Oct 7, 2023
1 parent 271ef83 commit 430c740
Show file tree
Hide file tree
Showing 21 changed files with 569 additions and 265 deletions.
24 changes: 12 additions & 12 deletions packages/components/select/src/composables/usePanelActiveState.ts
Expand Up @@ -47,27 +47,27 @@ export function usePanelActiveState(
key !== activeValue.value && setActiveValue(flattenedOptions.value[index]?.key)
}

watch(
[() => props.activeValue, flattenedOptions],
([value, options]) => {
const targetIndex = isNil(value) ? -1 : keyIndexMap.value.get(value) ?? -1
setActiveIndex(targetIndex !== -1 ? getEnabledActiveIndex(options, targetIndex, 1) : -1)
},
{
flush: 'post',
},
)

const scrollToActivated = () => {
scrollTo({ index: activeIndex.value })
}

onMounted(() => {
const options = flattenedOptions.value
const currValue = selectedKeys.value
const currValue = selectedKeys.value.length ? selectedKeys.value : [activeValue.value]
const currIndex = options.findIndex(option => currValue.some(value => option.key === value))
setActiveIndex(currIndex !== -1 ? getEnabledActiveIndex(options, currIndex, 1) : -1)

watch(
[() => props.activeValue, flattenedOptions],
([value, options]) => {
const targetIndex = isNil(value) ? -1 : keyIndexMap.value.get(value) ?? -1
setActiveIndex(targetIndex !== -1 ? getEnabledActiveIndex(options, targetIndex, 1) : -1)
},
{
flush: 'post',
},
)

scrollToActivated()
})

Expand Down
4 changes: 2 additions & 2 deletions packages/components/select/src/panel/ListBox.tsx
Expand Up @@ -15,8 +15,8 @@ import { renderOptionLabel } from '../utils/renderOptionLabel'

const defaultStyle = { height: 0, width: 0, overflow: 'hidden' }

const ListBox: FunctionalComponent = () => {
const { slots, selectedKeys, activeIndex, flattenedOptions } = inject(selectPanelContext)!
const ListBox: FunctionalComponent = (_, { slots }) => {
const { selectedKeys, activeIndex, flattenedOptions } = inject(selectPanelContext)!
const currSelectedKeys = selectedKeys.value

return (
Expand Down
3 changes: 1 addition & 2 deletions packages/components/select/src/panel/Option.tsx
Expand Up @@ -18,11 +18,10 @@ import { renderOptionLabel } from '../utils/renderOptionLabel'

export default defineComponent({
props: optionProps,
setup(props) {
setup(props, { slots }) {
const key = useKey()
const {
props: selectPanelProps,
slots,
mergedPrefixCls,
selectedKeys,
selectedLimit,
Expand Down
4 changes: 2 additions & 2 deletions packages/components/select/src/panel/OptionGroup.tsx
Expand Up @@ -14,8 +14,8 @@ import { optionGroupProps } from '../types'

export default defineComponent({
props: optionGroupProps,
setup(props) {
const { props: selectProps, slots, mergedPrefixCls } = inject(selectPanelContext)!
setup(props, { slots }) {
const { props: selectProps, mergedPrefixCls } = inject(selectPanelContext)!

return () => {
const { label, rawData } = props
Expand Down
9 changes: 6 additions & 3 deletions packages/components/select/src/panel/Panel.tsx
Expand Up @@ -54,7 +54,6 @@ export default defineComponent({

provide(selectPanelContext, {
props,
slots,
mergedPrefixCls,
flattenedOptions,
...selectedStateContext,
Expand Down Expand Up @@ -90,12 +89,16 @@ export default defineComponent({
return () => {
const { _virtualScrollHeight, virtualItemHeight, virtual, onScroll, onScrolledBottom } = props
const options = flattenedOptions.value
const children = [<ListBox />]
const children = [<ListBox v-slots={slots} />]

if (options.length > 0) {
const itemRender: VirtualItemRenderFn<FlattenedOption> = ({ item, index }) => {
const { type, ...rest } = item
return type === 'group' ? <OptionGroup index={index} {...rest} /> : <Option index={index} {...rest} />
return type === 'group' ? (
<OptionGroup v-slots={slots} index={index} {...rest} />
) : (
<Option v-slots={slots} index={index} {...rest} />
)
}

children.push(
Expand Down
3 changes: 1 addition & 2 deletions packages/components/select/src/token.ts
Expand Up @@ -11,15 +11,14 @@ import type { FlattenedOption } from './composables/useOptions'
import type { PanelActiveStateContext } from './composables/usePanelActiveState'
import type { SelectPanelProps } from './types'
import type { VKey } from '@idux/cdk/utils'
import type { ComputedRef, InjectionKey, Slots } from 'vue'
import type { ComputedRef, InjectionKey } from 'vue'

export interface SelectPanelDataContext {
flattenedOptions: ComputedRef<FlattenedOption[]>
}

export interface SelectPanelContext extends PanelActiveStateContext {
props: SelectPanelProps
slots: Slots
mergedPrefixCls: ComputedRef<string>
flattenedOptions: ComputedRef<FlattenedOption[]>
selectedKeys: ComputedRef<VKey[]>
Expand Down
1 change: 1 addition & 0 deletions packages/pro/locales/src/langs/en-US.ts
Expand Up @@ -37,6 +37,7 @@ const enUS: ProLocale = {
},
search: {
keyword: 'Search',
keywordFallbackLabel: 'Search with "${0}: ${1}"',
ok: 'OK',
cancel: 'Cancel',
selectAll: 'Select All',
Expand Down
1 change: 1 addition & 0 deletions packages/pro/locales/src/langs/zh-CN.ts
Expand Up @@ -37,6 +37,7 @@ const zhCN: ProLocale = {
},
search: {
keyword: '关键字',
keywordFallbackLabel: '以"${0}: ${1}"搜索',
ok: '确定',
cancel: '取消',
selectAll: '全选',
Expand Down
1 change: 1 addition & 0 deletions packages/pro/locales/src/types.ts
Expand Up @@ -33,6 +33,7 @@ export interface ProTreeLocale {

export interface ProSearchLocale {
keyword: string
keywordFallbackLabel: string
ok: string
cancel: string
selectAll: string
Expand Down
4 changes: 2 additions & 2 deletions packages/pro/search/demo/ConvertToKeyword.md
Expand Up @@ -7,8 +7,8 @@ title:

## zh

使用 `onItemConfirm` 事件将非法搜索项转换为关键字。
使用 `onItemConfirm` `onItemCreate` 事件将非法搜索项转换为关键字。

## en

convert illgale search value to keyword via `onItemConfirm` event.
convert illgale search value to keyword via `onItemConfirm` and `onItemCreate` event.
14 changes: 14 additions & 0 deletions packages/pro/search/demo/ConvertToKeywordWithPanel.md
@@ -0,0 +1,14 @@
---
order: 22
title:
zh: 内置自由输入转关键字功能
en: Convert unmatched input to keywords
---

## zh

使用 `searchField` 中的 `keywordFallback` 选项支持将未匹配到的自由输入转换该搜索项进行搜索。

## en

convert unmatched casual input to keyword search field value by setting `keywordFallback` of a `searchField`.
129 changes: 129 additions & 0 deletions packages/pro/search/demo/ConvertToKeywordWithPanel.vue
@@ -0,0 +1,129 @@
<template>
<IxProSearch
v-model:value="searchValues"
style="width: 100%"
:searchFields="searchFields"
:onChange="onChange"
:onSearch="onSearch"
></IxProSearch>
</template>

<script setup lang="ts">
import type { SearchField, SearchValue } from '@idux/pro/search'
import { ref } from 'vue'
const levelDataSource = [
{
key: 'level1',
label: 'Level 1',
},
{
key: 'level2',
label: 'Level 2',
},
{
key: 'level3',
label: 'Level 3',
},
]
const searchValues = ref<SearchValue[]>([])
const searchFields: SearchField[] = [
{
key: 'keyword',
type: 'input',
label: 'Keyword',
multiple: true,
keywordFallback: true,
fieldConfig: {
trim: true,
},
},
{
key: 'asset_name',
type: 'input',
label: 'Asset Name',
multiple: true,
keywordFallback: true,
fieldConfig: {
trim: true,
},
},
{
type: 'select',
label: 'Level',
key: 'level',
operators: ['=', '!='],
defaultOperator: '=',
keywordFallback: {
parse: input => {
const item = levelDataSource.find(data => data.key === input || data.label === input)
if (item) {
return item.key
}
return 'level1'
},
},
fieldConfig: {
multiple: false,
searchable: true,
dataSource: levelDataSource,
},
},
{
type: 'select',
label: 'Security State',
key: 'security_state',
fieldConfig: {
multiple: true,
searchable: true,
dataSource: [
{
key: 'fatal',
label: 'fatal',
},
{
key: 'high',
label: 'high',
},
{
key: 'mediumn',
label: 'mediumn',
},
{
key: 'low',
label: 'low',
},
],
},
},
{
type: 'datePicker',
label: 'Date',
key: 'date',
fieldConfig: {
type: 'datetime',
},
},
{
type: 'dateRangePicker',
label: 'Date Range',
key: 'date_range',
fieldConfig: {
type: 'datetime',
},
},
]
const onChange = (value: SearchValue[] | undefined, oldValue: SearchValue[] | undefined) => {
console.log(value, oldValue)
}
const onSearch = () => {
console.log('onSearch')
}
</script>

<style scoped lang="less"></style>
1 change: 1 addition & 0 deletions packages/pro/search/docs/Api.zh.md
Expand Up @@ -73,6 +73,7 @@ interface SearchItemCreateContext<V = unknown> extends Partial<SearchValue<V>> {
| `label` | 搜索条件的词条名称 | `string` | - | - | 必填 |
| `multiple` | 是否允许重复 | `boolean` | - | - |`true` 时,该搜索条件可以被输入多次 |
| `quickSelect` | 是否在快捷面板中展示 | `boolean \| SearchFieldQuickSelect` | - | - | 是否启用快捷面板, `multiple` 的搜索项该配置不生效。 |
| `keywordFallback` | 在搜索项名称输入过滤结果为空时支持以该搜索项进行搜索 | `boolean` | - | - | - |
| `operators` | 搜索条件的中间操作符 | `string[]` | - | - | 提供时,会在搜索词条名称中间增加一个操作符,如 `'='`, `'!='` |
| `defaultOperator` | 默认的操作符 | `string` | - | - | 提供时,会自动填入默认的操作符 |
| `defaultValue` | 默认值 | - | - | - | 提供时,会自动填入默认值 |
Expand Down

0 comments on commit 430c740

Please sign in to comment.