Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/form: add show-label prop #865

Merged
merged 15 commits into from
Aug 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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.
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
5 changes: 4 additions & 1 deletion src/form/demos/enUS/index.demo-entry.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ left
item-only
async
disabled
show-label
```

## Props
Expand All @@ -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. |
07akioni marked this conversation as resolved.
Show resolved Hide resolved
| show-require-mark | `'left' \| 'right' \| 'boolean'` | `'right'` | Whether to show require mark when form item is required. |
| size | `'small' \| 'medium' \| 'large'` | `'medium'` | Size. |

Expand All @@ -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. |
Expand All @@ -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. |
07akioni marked this conversation as resolved.
Show resolved Hide resolved
| 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. |
Expand Down
55 changes: 55 additions & 0 deletions src/form/demos/enUS/show-label.demo.md
Original file line number Diff line number Diff line change
@@ -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'
}
}
}
})
```
3 changes: 3 additions & 0 deletions src/form/demos/zhCN/index.demo-entry.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ async
disabled
height-debug
validator-debug
show-label
```

## Props
Expand All @@ -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'` | 尺寸 |

Expand Down Expand Up @@ -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`时,会覆盖规则验证的结果 |
Expand Down
55 changes: 55 additions & 0 deletions src/form/demos/zhCN/show-label.demo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# 显示/隐藏标签

`show-label`: 当值为 `false` 时,会隐藏 `n-form-item` 的 `label` 元素和占位。

`n-form-item` 若未被设定,则会使用外层 `n-form` 的 `show-label`, 若都未被设定,则默认为 `true`。
kev1nzh37 marked this conversation as resolved.
Show resolved Hide resolved

```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'
}
}
}
})
```
4 changes: 4 additions & 0 deletions src/form/src/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 8 additions & 4 deletions src/form/src/FormItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
kev1nzh37 marked this conversation as resolved.
Show resolved Hide resolved
labelWidth: [Number, String] as PropType<string | number>,
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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}
Expand Down
9 changes: 8 additions & 1 deletion src/form/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,21 @@ 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,
mergedLabelPlacement: mergedLabelPlacementRef,
mergedLabelAlign: mergedLabelAlignRef,
mergedShowRequireMark: mergedShowRequireMarkRef,
mergedValidationStatus: mergedValidationStatusRef,
mergedShowFeedback: mergedShowFeedbackRef
mergedShowFeedback: mergedShowFeedbackRef,
mergedShowLabel: mergedShowLabelRef
}
}

Expand Down
44 changes: 44 additions & 0 deletions src/form/tests/Form.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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)
})
})