feat(input): add count slot, closes #1314

This commit is contained in:
07akioni 2021-10-17 19:20:58 +08:00
parent 4ac6be229a
commit 23a7f24888
12 changed files with 48 additions and 24 deletions

View File

@ -10,6 +10,7 @@
### Feats
- `n-menu` add `dropdown-props` prop, closes [#1345](https://github.com/TuSimple/naive-ui/issues/1345).
- `n-input` add `count` slot, closes [#1314](https://github.com/TuSimple/naive-ui/issues/1314).
## 2.19.8 (2021-10-14)

View File

@ -10,6 +10,7 @@
### Feats
- `n-menu` 新增 `dropdown-props` 属性,关闭 [#1345](https://github.com/TuSimple/naive-ui/issues/1345)
- `n-input` 新增 `count` slot关闭 [#1314](https://github.com/TuSimple/naive-ui/issues/1314)
## 2.19.8 (2021-10-14)

View File

@ -24,7 +24,7 @@ show-options-by-value
| clearable | `boolean` | `false` | Whether auto complete is clearable. |
| default-value | `string` | `null` | Default value of auto complete. |
| disabled | `boolean` | `false` | Whether the auto complete is disabled. |
| get-show | `(value: string \| null) => boolean` | `undefined` | Based on value to determine whether to show menu when focusing. |
| get-show | `(value: string) => boolean` | `undefined` | Based on value to determine whether to show menu when focusing. |
| loading | `boolean` | `false` | Whether to show a loading status. |
| options | `Array<string \| AutoCompleteOption \| AutoCompleteGroupOption>` | `[]` | Auto complete options. |
| placeholder | `string` | `'Please Input'` | Auto complete's placeholder. |

View File

@ -24,7 +24,7 @@ show-options-by-value
| clearable | `boolean` | `false` | 自动填充是否支持可清除 |
| default-value | `string` | `null` | 自动填充的默认值 |
| disabled | `boolean` | `false` | 自动填充是否禁用 |
| get-show | `(value: string \| null) => boolean` | `undefined` | 根据输入值在聚焦的状态中决定是否显示菜单 |
| get-show | `(value: string) => boolean` | `undefined` | 根据输入值在聚焦的状态中决定是否显示菜单 |
| loading | `boolean` | `false` | 是否展示加载状态 |
| options | `Array<string \| AutoCompleteOption \| AutoCompleteGroupOption>` | `[]` | 自动填充的自定义选项 |
| placeholder | `string` | `'请输入'` | 自动填充的提示信息 |

View File

@ -70,7 +70,7 @@ const autoCompleteProps = {
value: String,
blurAfterSelect: Boolean,
clearAfterSelect: Boolean,
getShow: Function as PropType<(inputValue: string | null) => boolean>,
getShow: Function as PropType<(inputValue: string) => boolean>,
size: String as PropType<'small' | 'medium' | 'large'>,
options: {
type: Array as PropType<AutoCompleteOptions>,
@ -134,7 +134,7 @@ export default defineComponent({
const mergedShowOptionsRef = computed(() => {
const { getShow } = props
if (getShow) {
return getShow(mergedValueRef.value)
return getShow(mergedValueRef.value || '')
}
return !!mergedValueRef.value
})

View File

@ -6,5 +6,10 @@ Don't waste words.
<n-space vertical>
<n-input maxlength="30" show-count clearable />
<n-input type="textarea" maxlength="30" show-count />
<n-input type="textarea" show-count #count="{ value }">
<n-input type="textarea" default-value="What" show-count #count="{ value }">
{{ value.includes('What') ? '99+' : value.length }}
</n-input>
</n-input>
</n-space>
```

View File

@ -59,9 +59,10 @@ event
| Name | Parameters | Description |
| --- | --- | --- |
| count | `(value: string)` | Word count. |
| prefix | `()` | Prefix content slot. |
| suffix | `()` | Suffix content slot. |
| separator | `()` | The separator content of the input, only works when `pair` is true. This will take priority over the separator property. |
| suffix | `()` | Suffix content slot. |
### InputGroup Slots

View File

@ -6,5 +6,8 @@
<n-space vertical>
<n-input maxlength="30" show-count clearable />
<n-input type="textarea" maxlength="30" show-count />
<n-input type="textarea" default-value="啥" show-count #count="{ value }">
{{ value.includes('啥') ? '99+' : value.length }}
</n-input>
</n-space>
```

View File

@ -56,21 +56,22 @@ focus
### Input Slots
| 属性 | 类型 | 说明 |
| 属性 | 参数 | 说明 |
| --- | --- | --- |
| count | `(value: string)` | 字数统计 |
| prefix | `()` | 输入框头部内容 |
| suffix | `()` | 输入框尾部内容 |
| separator | `()` | 成对输入框之间分隔符,仅 `pair` = true 生效且优先级高于 separator 属性 |
| suffix | `()` | 输入框尾部内容 |
### InputGroup Slots
| 属性 | 类型 | 说明 |
| 属性 | 参数 | 说明 |
| ------- | ---- | ------------ |
| default | `()` | 输入组的内容 |
### InputGroupLabel Slots
| 属性 | 类型 | 说明 |
| 属性 | 参数 | 说明 |
| ------- | ---- | ---------------- |
| default | `()` | 输入组标签的内容 |

View File

@ -35,7 +35,7 @@ import {
InputWrappedRef,
inputInjectionKey
} from './interface'
import { len, isEmptyValue } from './utils'
import { isEmptyValue } from './utils'
import WordCount from './WordCount'
import style from './styles/input.cssr'
import { off, on } from 'evtd'
@ -658,11 +658,7 @@ export default defineComponent({
})
provide(inputInjectionKey, {
wordCountRef: computed(() => {
const { value: mergedValue } = mergedValueRef
if (mergedValue === null || Array.isArray(mergedValue)) return 0
return len(mergedValue)
}),
mergedValueRef,
maxlengthRef,
mergedClsPrefixRef
})
@ -1082,7 +1078,9 @@ export default defineComponent({
{this.mergedBordered ? (
<div class={`${mergedClsPrefix}-input__state-border`} />
) : null}
{this.showCount && this.type === 'textarea' ? <WordCount /> : null}
{this.showCount && this.type === 'textarea' ? (
<WordCount>{{ default: this.$slots.count }}</WordCount>
) : null}
</div>
)
}

View File

@ -1,19 +1,33 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { defineComponent, inject, h } from 'vue'
import { defineComponent, inject, h, computed } from 'vue'
import { inputInjectionKey } from './interface'
import { len } from './utils'
export default defineComponent({
name: 'InputWordCount',
setup () {
const { wordCountRef, maxlengthRef, mergedClsPrefixRef } =
setup (_, { slots }) {
const { mergedValueRef, maxlengthRef, mergedClsPrefixRef } =
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
inject(inputInjectionKey)!
const wordCountRef = computed(() => {
const { value: mergedValue } = mergedValueRef
if (mergedValue === null || Array.isArray(mergedValue)) return 0
return len(mergedValue)
})
return () => {
const { value: maxlength } = maxlengthRef
const { value: mergedValue } = mergedValueRef
return (
<span class={`${mergedClsPrefixRef.value}-input-word-count`}>
{maxlength === undefined
? wordCountRef.value
: `${wordCountRef.value} / ${maxlength}`}
{slots.default
? slots.default({
value:
mergedValue === null || Array.isArray(mergedValue)
? ''
: mergedValue
})
: maxlength === undefined
? wordCountRef.value
: `${wordCountRef.value} / ${maxlength}`}
</span>
)
}

View File

@ -22,7 +22,7 @@ export interface InputWrappedRef {
export type InputInst = UnwrapRef<InputWrappedRef>
export const inputInjectionKey: InjectionKey<{
wordCountRef: Ref<number>
mergedValueRef: Ref<string | [string, string] | null>
maxlengthRef: Ref<number | undefined>
mergedClsPrefixRef: Ref<string>
}> = Symbol('input')