feat(dynamic-tags): create new doc page

This commit is contained in:
07akioni 2021-02-02 15:47:21 +08:00
parent 8336f3b1c4
commit eb5c759d2e
16 changed files with 127 additions and 60 deletions

View File

@ -295,6 +295,10 @@ export const childRoutes = withPrefix('/:lang/:theme/doc', [
path: '/n-rate',
component: () => import('../../src/rate/demos/index.entry')
},
{
path: '/n-dynamic-tags',
component: () => import('../../src/dynamic-tags/demos/index.entry')
},
// deprecated
{
path: '/n-nimbus-service-layout',

View File

@ -219,6 +219,12 @@ export default function (instance) {
titleExtra: 'Dynamic Input',
path: `/${lang}/${theme}/doc` + '/n-dynamic-input'
},
{
name: 'Dynamic Tags',
title: '动态标签',
titleExtra: 'Dynamic Tags',
path: `/${lang}/${theme}/doc` + '/n-dynamic-tags'
},
{
name: 'Form',
title: '表单',

View File

@ -23,6 +23,7 @@ export default defineComponent({
'n-base-close--disabled': props.disabled
}
]}
onClick={props.onClick}
>
{{ default: () => <CloseIcon /> }}
</NBaseIcon>

View File

@ -84,7 +84,9 @@ export default defineComponent({
}
},
setup (props) {
const uncontrolledExpandedNamesRef = ref(null)
const uncontrolledExpandedNamesRef = ref<
string | number | Array<string | number> | null
>(null)
const controlledExpandedNamesRef = computed(() => props.expandedNames)
const mergedExpandedNames = useMergedState(
controlledExpandedNamesRef,
@ -115,6 +117,7 @@ export default defineComponent({
if (onExpandedNamesChange) {
call(onExpandedNamesChange as OnUpdateExpandedNamesImpl, names)
}
uncontrolledExpandedNamesRef.value = names
}
function doItemHeaderClick<T extends string | number> (
info: HeaderClickInfo<T>

View File

@ -82,7 +82,7 @@ export default defineComponent({
return false
})
const shouldDelayRef = computed(() => {
return NDropdown.keyboardKey === null && NDropdown.animated
return NDropdown.keyboardKey === null && !NDropdown.animated
})
const deferredShowSubmenuRef = useDeferredTrue(
showSubmenuRef,

View File

@ -0,0 +1,15 @@
# Basic
```html
<n-dynamic-tags v-model:value="tags" />
```
```js
export default {
data () {
return {
tags: ['teacher', 'programmer']
}
}
}
```

View File

@ -1,14 +1,11 @@
# Edit Dynamically
# Use in Form
```html
<n-dynamic-tags v-model:value="model.tags" />
<p style="margin: 20px 0 16px 0;">Use in form.</p>
<n-form :model="model" :rules="rules">
<n-form-item style="padding-top:0" path="tags">
<n-dynamic-tags v-model:value="model.tags" />
</n-form-item>
</n-form>
{{model.tags}}
```
```js

View File

@ -0,0 +1,25 @@
# Dynamic Tags
Make tags inputable.
## Demos
```demo
basic
form
```
## Props
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| closable | `boolean` | `false` | |
| default-value | `string[]` | `[]` | |
| disabled | `boolean` | `false` | |
| input-style | `Object` | `{ width: '64px' }` | |
| round | `boolean` | `false` | |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | |
| tag-style | `Object` | `{ marginRight: '6px' }` | |
| type | `'default' \| 'info' \| 'success' \| 'warning' \| 'error'` | `'default'` | |
| value | `string[]` | `undefined` | |
| on-update:value | `(value: boolean) => any` | `undefined` | |

View File

View File

@ -0,0 +1,15 @@
# 基础用法
```html
<n-dynamic-tags v-model:value="tags" />
```
```js
export default {
data () {
return {
tags: ['教师', '程序员']
}
}
}
```

View File

@ -1,14 +1,11 @@
# 动态编辑标签
# 在表单中使用
```html
<n-dynamic-tags v-model:value="model.tags" />
<p style="margin: 20px 0 16px 0;">在表单中使用</p>
<n-form :model="model" :rules="rules">
<n-form-item style="padding-top:0" path="tags">
<n-dynamic-tags v-model:value="model.tags" />
</n-form-item>
</n-form>
{{model.tags}}
```
```js
@ -16,13 +13,13 @@ export default {
data () {
return {
model: {
tags: ['武汉', '广东']
tags: ['教师', '程序员']
},
rules: {
tags: {
trigger: ['change'],
validator (rule, value) {
if (value.length >= 5) return new Error('最多允许四个标签')
if (value.length >= 5) return new Error('不得超过四个标签')
return true
}
}

View File

@ -0,0 +1,25 @@
# 动态标签 Dynamic Tags
把标签变得可以输入。
## 演示
```demo
basic
form
```
## Props
| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| closable | `boolean` | `false` | |
| default-value | `string[]` | `[]` | |
| disabled | `boolean` | `false` | |
| input-style | `Object` | `{ width: '64px' }` | |
| round | `boolean` | `false` | |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | |
| tag-style | `Object` | `{ marginRight: '6px' }` | |
| type | `'default' \| 'info' \| 'success' \| 'warning' \| 'error'` | `'default'` | |
| value | `string[]` | `undefined` | |
| on-update:value | `(value: boolean) => any` | `undefined` | |

View File

@ -5,7 +5,8 @@ import {
PropType,
CSSProperties,
computed,
nextTick
nextTick,
toRef
} from 'vue'
import commonProps from '../../tag/src/common-props'
import { AddIcon } from '../../_internal/icons'
@ -21,6 +22,7 @@ import type { DynamicTagsTheme } from '../styles'
import type { OnUpdateValue } from './interface'
import style from './styles/index.cssr'
import { useMergedState } from 'vooks'
export default defineComponent({
name: 'DynamicTags',
@ -31,12 +33,11 @@ export default defineComponent({
type: Boolean,
default: true
},
value: {
defaultValue: {
type: Array as PropType<string[]>,
default: () => {
return []
}
default: () => []
},
value: Array as PropType<string[]>,
tagStyle: {
type: Object as PropType<CSSProperties>,
default: () => {
@ -55,6 +56,7 @@ export default defineComponent({
},
// eslint-disable-next-line vue/prop-name-casing
'onUpdate:value': [Function, Array] as PropType<MaybeArray<OnUpdateValue>>,
onUpdateValue: [Function, Array] as PropType<MaybeArray<OnUpdateValue>>,
// deprecated
onChange: {
type: [Function, Array] as PropType<
@ -86,6 +88,13 @@ export default defineComponent({
dynamicTagsLight,
props
)
const uncontrolledValueRef = ref(props.defaultValue)
const controlledValueRef = toRef(props, 'value')
const mergedValueRef = useMergedState(
controlledValueRef,
uncontrolledValueRef
)
const localizedAddRef = computed(() => {
return locale.value.add
})
@ -93,15 +102,21 @@ export default defineComponent({
return smallerSize(props.size)
})
function doChange (value: string[]): void {
const { onChange, 'onUpdate:value': onUpdateValue } = props
const {
onChange,
'onUpdate:value': _onUpdateValue,
onUpdateValue
} = props
const { nTriggerFormInput, nTriggerFormChange } = formItem
if (onChange) call(onChange, value)
if (onUpdateValue) call(onUpdateValue, value)
if (_onUpdateValue) call(_onUpdateValue, value)
uncontrolledValueRef.value = value
nTriggerFormInput()
nTriggerFormChange()
}
function handleCloseClick (index: number): void {
const tags = props.value.slice(0)
const tags = mergedValueRef.value.slice(0)
tags.splice(index, 1)
doChange(tags)
}
@ -113,7 +128,7 @@ export default defineComponent({
}
function handleInputConfirm (): void {
if (inputValueRef.value) {
const tags = props.value.slice(0)
const tags = mergedValueRef.value.slice(0)
tags.push(inputValueRef.value)
doChange(tags)
}
@ -138,6 +153,7 @@ export default defineComponent({
inputValue: inputValueRef,
showInput: showInputRef,
inputForceFocused: inputForceFocusedRef,
mergedValue: mergedValueRef,
handleInputKeyUp,
handleAddClick,
handleInputBlur,
@ -149,7 +165,7 @@ export default defineComponent({
const { mergedTheme } = this
return (
<div class="n-dynamic-tags">
{this.value.map((tag, index) => (
{this.mergedValue.map((tag, index) => (
<NTag
key={index}
theme={mergedTheme.peers.Tag}
@ -162,7 +178,7 @@ export default defineComponent({
disabled={this.disabled}
onClose={() => this.handleCloseClick(index)}
>
{{ defualt: () => tag }}
{{ default: () => tag }}
</NTag>
))}
{this.showInput ? (

View File

@ -11,7 +11,6 @@ disabled
size
checkable
shape
dynamic-tags
```
## Props
@ -29,24 +28,8 @@ dynamic-tags
| type | `'default' \| 'info' \| 'success' \| 'warning' \| 'error'` | `'default'` | |
| on-update:checked | `(value: boolean) => any` | `undefined` | |
### DynamicTags
| Name | Type | Default | Description |
| --- | --- | --- | --- |
| closable | `boolean` | `false` | |
| disabled | `boolean` | `false` | |
| input-style | `Object` | `{ width: '50px' }` | |
| round | `boolean` | `false` | |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | |
| tag-style | `Object` | `{ marginRight: '5px', marginBottom: '5px' }` | |
| type | `'default' \| 'info' \| 'success' \| 'warning' \| 'error'` | `'default'` | |
| value | `Array<string>` | `[]` | |
| on-update:value | `(value: boolean) => any` | `undefined` | |
## Slots
### Tag
| Name | Parameters | Description |
| ------- | ---------- | ----------- |
| default | `()` | |

View File

@ -11,7 +11,6 @@ disabled
size
checkable
shape
dynamic-tags
```
## Props
@ -29,24 +28,8 @@ dynamic-tags
| type | `'default' \| 'info' \| 'success' \| 'warning' \| 'error'` | `'default'` | |
| on-update:checked | `(value: boolean) => any` | `undefined` | |
### DynamicTags
| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| closable | `boolean` | `false` | |
| disabled | `boolean` | `false` | |
| input-style | `Object` | `{ width: '50px' }` | |
| round | `boolean` | `false` | |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | |
| tag-style | `Object` | `{ marginRight: '5px', marginBottom: '5px' }` | |
| type | `'default' \| 'info' \| 'success' \| 'warning' \| 'error'` | `'default'` | |
| value | `Array<string>` | `[]` | |
| on-update:value | `(value: boolean) => any` | `undefined` | |
## Slots
### Tag
| 名称 | 参数 | 说明 |
| ------- | ---- | ---- |
| default | `()` | |

View File

@ -21,10 +21,7 @@ export default defineComponent({
type: Boolean,
default: false
},
onClose: {
type: Function,
default: undefined
},
onClose: Function,
// eslint-disable-next-line vue/prop-name-casing
'onUpdate:checked': {
type: Function,