mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2024-12-21 04:50:14 +08:00
feat(form): add show-label
prop (#865)
* feat(form): add show-label prop and test (#858) * docs(form): add show-label doc and fix form item label desc (#858) * Update CHANGELOG.en-US.md Co-authored-by: Yugang Cao <34439652+Talljack@users.noreply.github.com> * Update CHANGELOG.zh-CN.md Co-authored-by: Yugang Cao <34439652+Talljack@users.noreply.github.com> * feat(form): rewrite show-label and add tests (#858) * docs(form): add show-label demo (#858) * feat(form): change show-label computed (#858) * feat(form): fix show-label (#858) * feat(form): fix bug (#858) * feat(form): update show-label scripts (#858) * docs(form): update show-label order and label description (#858) * Apply suggestions from code review Co-authored-by: kev1nzh <kev1nzh@app-ark.com> Co-authored-by: Yugang Cao <34439652+Talljack@users.noreply.github.com> Co-authored-by: kev1nzh_ark <kevin@app-ark.com> Co-authored-by: 07akioni <07akioni2@gmail.com>
This commit is contained in:
parent
19282b6d56
commit
b401ff4793
@ -9,6 +9,7 @@
|
||||
### Feats
|
||||
|
||||
- `n-input-number` add `clearable` prop.
|
||||
- `n-form` add `show-label` prop, closes [#858](https://github.com/TuSimple/naive-ui/issues/858).
|
||||
|
||||
## 2.16.4 (2021-08-16)
|
||||
|
||||
@ -24,6 +25,7 @@
|
||||
|
||||
### Feats
|
||||
|
||||
- `n-message-provider` add `container-style` prop
|
||||
- `n-message-provider` add `container-style` prop.
|
||||
- `n-message-provider` add `placement` prop.
|
||||
- `n-message` add class to distinguish type.
|
||||
|
@ -9,6 +9,7 @@
|
||||
### Feats
|
||||
|
||||
- `n-input-number` 新增 `clearable` 属性
|
||||
- `n-form` 新增 `show-label` 属性,关闭 [#858](https://github.com/TuSimple/naive-ui/issues/858)
|
||||
|
||||
## 2.16.4 (2021-08-16)
|
||||
|
||||
|
@ -15,6 +15,7 @@ left
|
||||
item-only
|
||||
async
|
||||
disabled
|
||||
show-label
|
||||
```
|
||||
|
||||
## Props
|
||||
@ -31,6 +32,7 @@ disabled
|
||||
| model | `Object` | `{}` | The object to get collected value from form items. |
|
||||
| rules | `type FormRules = { [itemValidatePath: string]: FormItemRule \| Array<FormItemRule> \| FormRules }` | `{}` | The rules to validate form items. |
|
||||
| show-feedback | `boolean` | `true` | Whether to show feedback. |
|
||||
| show-label | `boolean` | `true` | Whether to show label. |
|
||||
| show-require-mark | `'left' \| 'right' \| 'boolean'` | `'right'` | Whether to show require mark when form item is required. |
|
||||
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | Size. |
|
||||
|
||||
@ -51,7 +53,7 @@ disabled
|
||||
| feedback | `string` | `undefined` | The feedback message of the form item. If not set to `undefined`, it will take place of the result of rule-based validation. |
|
||||
| first | `boolean` | `false` | Whether only to show the first validation error message. |
|
||||
| ingore-path-change | `boolean` | `false` | Usually, the change of `path` will cause the data source's variation. So naive-ui will clear the validation result. If it is not expected, you can set it to `true` |
|
||||
| label | `string` | `undefined` | Lbale information. |
|
||||
| label | `string` | `undefined` | Label information. |
|
||||
| label-align | `'left' \| 'right'` | `undefined` | Text align in label. If not set, use `label-align` from wrapper form. |
|
||||
| label-placement | `'left' \| 'top'` | `undefined` | If not set, use `label-placement` from wrapper form. |
|
||||
| label-style | `Object` | `{}` | Label style. |
|
||||
@ -61,6 +63,7 @@ disabled
|
||||
| rule | `FormItemRule \| Array<FormItemRule>` | `undefined` | The rule to validate the form item. It will be merged with the rules acquired by `rule-path` from wrapper form's rules. It's recommend to set all rules on wrapper form. |
|
||||
| rule-path | `string` | `undefined` | The path to get rule from wrapper form's rule object. If not set, use path of the form item instead. |
|
||||
| show-feedback | `boolean` | `true` | Whether to show feedback. |
|
||||
| show-label | `boolean` | `true` | Whether to show label. If not set, use `show-label` from wrapper form. |
|
||||
| show-require-mark | `'left' \| 'right' \| 'boolean'` | `'right'` | Whether to show require mark. If not set, use `show-require-mark` from wrapper form. |
|
||||
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | Size. |
|
||||
| validation-status | `'error' \| 'success' \| 'warning'` | `undefined` | The validation status of the form item. If not set to `undefined`, it will take place of the result of rule-based validation. |
|
||||
|
55
src/form/demos/enUS/show-label.demo.md
Normal file
55
src/form/demos/enUS/show-label.demo.md
Normal file
@ -0,0 +1,55 @@
|
||||
# Show/hide Label
|
||||
|
||||
`show-label`: When the value is `false`, the `label` element and placeholder for `n-form-item` will be hidden.
|
||||
|
||||
`n-form-item` will use the `show-label` of the enclosing `n-form` if it is not set, or default to `true` if neither is set.
|
||||
|
||||
```html
|
||||
<div :style="switchStyle">
|
||||
<label>n-form:</label>
|
||||
<n-switch v-model:value="formShowLabel" />
|
||||
</div>
|
||||
<div :style="switchStyle">
|
||||
<label>n-form-item:</label>
|
||||
<n-switch v-model:value="formItemShowLabel" />
|
||||
</div>
|
||||
|
||||
<n-form :model="formValue" ref="formRef" :show-label="formShowLabel">
|
||||
<n-form-item label="Name" path="user.name" :show-label="formItemShowLabel">
|
||||
<n-input v-model:value="formValue.user.name" placeholder="Input Name" />
|
||||
</n-form-item>
|
||||
<n-form-item label="Age" path="user.age">
|
||||
<n-input placeholder="Input Age" v-model:value="formValue.user.age" />
|
||||
</n-form-item>
|
||||
<n-form-item label="Phone" path="user.phone">
|
||||
<n-input placeholder="Input Phone" v-model:value="formValue.phone" />
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
```
|
||||
|
||||
```js
|
||||
import { defineComponent, ref } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
const formRef = ref(null)
|
||||
const formShowLabel = ref(true)
|
||||
const formItemShowLabel = ref(true)
|
||||
return {
|
||||
formRef,
|
||||
formValue: ref({
|
||||
user: {
|
||||
name: '',
|
||||
age: ''
|
||||
},
|
||||
phone: ''
|
||||
}),
|
||||
formShowLabel,
|
||||
formItemShowLabel,
|
||||
switchStyle: {
|
||||
marginBottom: '12px'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
@ -17,6 +17,7 @@ async
|
||||
disabled
|
||||
height-debug
|
||||
validator-debug
|
||||
show-label
|
||||
```
|
||||
|
||||
## Props
|
||||
@ -33,6 +34,7 @@ validator-debug
|
||||
| model | `Object` | `{}` | 获取表项中收集到的值的对象 |
|
||||
| rules | `type FormRules = { [itemValidatePath: string]: FormItemRule \| Array<FormItemRule> \| FormRules }` | `{}` | 验证表项的规则 |
|
||||
| show-feedback | `boolean` | `true` | 是否展示校验反馈 |
|
||||
| show-label | `boolean` | `true` | 是否展示标签 |
|
||||
| show-require-mark | `'left' \| 'right' \| 'boolean'` | `'right'` | 是否展示必填的星号 |
|
||||
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | 尺寸 |
|
||||
|
||||
@ -62,6 +64,7 @@ validator-debug
|
||||
| rule | `FormItemRule \| Array<FormItemRule>` | `undefined` | 验证表项的规则,它会被通过 `rule-path` 从外层表单获取的规则合并来作为表项的验证规则。推荐还是在外层表单设置所有规则 |
|
||||
| rule-path | `string` | `undefined` | 从外层表单的 `rules` 对象获取规则的路径。如果没有设定,使用表项的 `path` 代替 |
|
||||
| show-feedback | `boolean` | `true` | 是否展示校验反馈 |
|
||||
| show-label | `boolean` | `true` | 是否展示标签。如果没有被设定,使用外层 `n-form` 的 `show-label` |
|
||||
| show-require-mark | `'left' \| 'right' \| 'boolean'` | `'right'` | 是否展示必填的星号。如果没有被设定,使用外层 `n-form` 的 `show-require-mark` |
|
||||
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | 尺寸 |
|
||||
| validation-status | `'error' \| 'success' \| 'warning'` | `undefined` | 表单的验证状态。不设为 `undefined`时,会覆盖规则验证的结果 |
|
||||
|
55
src/form/demos/zhCN/show-label.demo.md
Normal file
55
src/form/demos/zhCN/show-label.demo.md
Normal file
@ -0,0 +1,55 @@
|
||||
# 显示/隐藏标签
|
||||
|
||||
`show-label`: 当值为 `false` 时,会隐藏 `n-form-item` 的 `label` 元素和占位。
|
||||
|
||||
`n-form-item` 若未被设定,则会使用外层 `n-form` 的 `show-label`, 若都未被设定,则默认为 `true`。
|
||||
|
||||
```html
|
||||
<div :style="switchStyle">
|
||||
<label>n-form:</label>
|
||||
<n-switch v-model:value="formShowLabel" />
|
||||
</div>
|
||||
<div :style="switchStyle">
|
||||
<label>n-form-item:</label>
|
||||
<n-switch v-model:value="formItemShowLabel" />
|
||||
</div>
|
||||
|
||||
<n-form :model="formValue" ref="formRef" :show-label="formShowLabel">
|
||||
<n-form-item label="姓名" path="user.name" :show-label="formItemShowLabel">
|
||||
<n-input v-model:value="formValue.user.name" placeholder="输入姓名" />
|
||||
</n-form-item>
|
||||
<n-form-item label="年龄" path="user.age">
|
||||
<n-input placeholder="输入年龄" v-model:value="formValue.user.age" />
|
||||
</n-form-item>
|
||||
<n-form-item label="电话号码" path="user.phone">
|
||||
<n-input placeholder="电话号码" v-model:value="formValue.phone" />
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
```
|
||||
|
||||
```js
|
||||
import { defineComponent, ref } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
setup () {
|
||||
const formRef = ref(null)
|
||||
const formShowLabel = ref(true)
|
||||
const formItemShowLabel = ref(true)
|
||||
return {
|
||||
formRef,
|
||||
formValue: ref({
|
||||
user: {
|
||||
name: '',
|
||||
age: ''
|
||||
},
|
||||
phone: ''
|
||||
}),
|
||||
formShowLabel,
|
||||
formItemShowLabel,
|
||||
switchStyle: {
|
||||
marginBottom: '12px'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
@ -48,6 +48,10 @@ const formProps = {
|
||||
onSubmit: {
|
||||
type: Function as PropType<(e: Event) => void>,
|
||||
default: (e: Event) => e.preventDefault()
|
||||
},
|
||||
showLabel: {
|
||||
type: Boolean as PropType<boolean | undefined>,
|
||||
default: undefined
|
||||
}
|
||||
} as const
|
||||
|
||||
|
@ -52,7 +52,7 @@ import {
|
||||
export const formItemProps = {
|
||||
...(useTheme.props as ThemeProps<FormTheme>),
|
||||
label: {
|
||||
type: [String, Boolean] as PropType<string | false | undefined>,
|
||||
type: String as PropType<string | undefined>,
|
||||
default: undefined
|
||||
},
|
||||
labelWidth: [Number, String] as PropType<string | number>,
|
||||
@ -84,7 +84,11 @@ export const formItemProps = {
|
||||
default: false
|
||||
},
|
||||
validationStatus: String as PropType<'error' | 'warning' | 'success'>,
|
||||
feedback: String
|
||||
feedback: String,
|
||||
showLabel: {
|
||||
type: Boolean as PropType<boolean | undefined>,
|
||||
default: undefined
|
||||
}
|
||||
} as const
|
||||
|
||||
export type FormItemSetupProps = ExtractPropTypes<typeof formItemProps>
|
||||
@ -412,11 +416,11 @@ export default defineComponent({
|
||||
`${mergedClsPrefix}-form-item`,
|
||||
`${mergedClsPrefix}-form-item--${this.mergedSize}-size`,
|
||||
`${mergedClsPrefix}-form-item--${this.mergedLabelPlacement}-labelled`,
|
||||
this.label === false && `${mergedClsPrefix}-form-item--no-label`
|
||||
!this.mergedShowLabel && `${mergedClsPrefix}-form-item--no-label`
|
||||
]}
|
||||
style={this.cssVars as CSSProperties}
|
||||
>
|
||||
{this.label || $slots.label ? (
|
||||
{this.mergedShowLabel && (this.label || $slots.label) ? (
|
||||
<label
|
||||
class={`${mergedClsPrefix}-form-item-label`}
|
||||
style={this.mergedLabelStyle as any}
|
||||
|
@ -72,6 +72,12 @@ export function formItemMisc (props: FormItemSetupProps) {
|
||||
if (NForm?.showFeedback !== undefined) return NForm.showFeedback
|
||||
return true
|
||||
})
|
||||
const mergedShowLabelRef = computed(() => {
|
||||
const { showLabel } = props
|
||||
if (showLabel !== undefined) return showLabel
|
||||
if (NForm?.showLabel !== undefined) return NForm.showLabel
|
||||
return true
|
||||
})
|
||||
return {
|
||||
validationErrored: validationErroredRef,
|
||||
mergedLabelStyle: mergedLabelStyleRef,
|
||||
@ -79,7 +85,8 @@ export function formItemMisc (props: FormItemSetupProps) {
|
||||
mergedLabelAlign: mergedLabelAlignRef,
|
||||
mergedShowRequireMark: mergedShowRequireMarkRef,
|
||||
mergedValidationStatus: mergedValidationStatusRef,
|
||||
mergedShowFeedback: mergedShowFeedbackRef
|
||||
mergedShowFeedback: mergedShowFeedbackRef,
|
||||
mergedShowLabel: mergedShowLabelRef
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,4 +89,48 @@ describe('n-form', () => {
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
it('should work with `show-label` prop', async () => {
|
||||
let wrapper = mount(NForm, {
|
||||
slots: {
|
||||
default: () =>
|
||||
[1, 2, 3].map((num) => (
|
||||
<NFormItem label={`label${num}`}>
|
||||
{{
|
||||
default: () => <NInput />
|
||||
}}
|
||||
</NFormItem>
|
||||
))
|
||||
}
|
||||
})
|
||||
// show-label default is true in component
|
||||
expect(wrapper.findAll('.n-form-item-label').length).toBe(3)
|
||||
expect(wrapper.findAll('.n-form-item--no-label').length).toBe(0)
|
||||
|
||||
await wrapper.setProps({ showLabel: true })
|
||||
expect(wrapper.findAll('.n-form-item-label').length).toBe(3)
|
||||
expect(wrapper.findAll('.n-form-item--no-label').length).toBe(0)
|
||||
|
||||
await wrapper.setProps({ showLabel: false })
|
||||
expect(wrapper.findAll('.n-form-item-label').length).toBe(0)
|
||||
expect(wrapper.findAll('.n-form-item--no-label').length).toBe(3)
|
||||
|
||||
// The NFormItem show-label has a higher weight than the NForm
|
||||
wrapper = mount(NForm, {
|
||||
props: { showLabel: true },
|
||||
slots: {
|
||||
default: () => (
|
||||
<NFormItem label="label" show-label={false}>
|
||||
{{
|
||||
default: () => <NInput />
|
||||
}}
|
||||
</NFormItem>
|
||||
)
|
||||
}
|
||||
})
|
||||
expect(
|
||||
wrapper.find('.n-form-item').classes().includes('n-form-item--no-label')
|
||||
).toBe(true)
|
||||
expect(wrapper.findAll('.n-form-item-label').length).toBe(0)
|
||||
})
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user