feat(popselect): support class attr (#189)

* feat(popselect): support class attr

* test: update snapshot
This commit is contained in:
07akioni 2021-06-18 22:28:22 +08:00 committed by GitHub
parent 4afacaa2b4
commit dbcf7a2b73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 106 additions and 64 deletions

View File

@ -2,12 +2,12 @@
## Pending
- `n-input` add show-password-toggle prop.
### Feats
- `n-form`, `n-form-item` enhance show-require-mark propcloses [#171](https://github.com/TuSimple/naive-ui/issues/171)
- `n-dropdown` support class attr, closes [#180](https://github.com/TuSimple/naive-ui/issues/180).
- `n-input` add `show-password-toggle` prop.
- `n-popselect` support class attr.
### Fixes

View File

@ -2,12 +2,12 @@
## Pending
- 为 `n-input` 组件中 password 属性增加查看隐藏功能
### Feats
- `n-form`, `n-form-item` 增强 show-require-mark 属性,关闭 [#171](https://github.com/TuSimple/naive-ui/issues/171)
- `n-dropdown` 支持 class 属性,关闭 [#180](https://github.com/TuSimple/naive-ui/issues/180)
- `n-input` 新增 `show-password-toggle` 属性
- `n-popselect` 支持 class 属性
### Fixes

View File

@ -28,3 +28,19 @@
#### 注意事项
- `feat(xxx)` 必须是组件,不能加 `n``feat(input)` ✅,`feat(n-input)` ❌
## Changelog
- 新增属性
```
- `n-xxx` add xxx prop.
- `n-xxx` 新增 xxx 属性
```
- 修复 Bug
```
- Fix `n-xxx` ...
- 修复 `n-xxx` ...
```

View File

@ -107,6 +107,8 @@ export default defineComponent({
onKeyup: Function as PropType<(e: KeyboardEvent) => void>,
onKeydown: Function as PropType<(e: KeyboardEvent) => void>,
onTabOut: Function as PropType<() => void>,
onMouseenter: Function as PropType<(e: MouseEvent) => void>,
onMouseleave: Function as PropType<(e: MouseEvent) => void>,
// deprecated
onMenuToggleOption: Function as PropType<(value: SelectBaseOption) => void>
},
@ -378,6 +380,8 @@ export default defineComponent({
onKeyup={this.handleKeyUp}
onKeydown={this.handleKeyDown}
onMousedown={this.handleMouseDown}
onMouseenter={this.onMouseenter}
onMouseleave={this.onMouseleave}
>
{this.loading ? (
<div class={`${clsPrefix}-base-select-menu__loading`}>

View File

@ -309,7 +309,6 @@ export default defineComponent({
padding,
dividerColor,
borderRadius,
boxShadow,
optionOpacityDisabled,
[createKey('optionIconSuffixWidth', size)]: optionIconSuffixWidth,
[createKey('optionSuffixWidth', size)]: optionSuffixWidth,
@ -324,7 +323,6 @@ export default defineComponent({
'--font-size': fontSize,
'--padding': padding,
'--border-radius': borderRadius,
'--box-shadow': boxShadow,
'--option-height': optionHeight,
'--option-prefix-width': optionPrefixWidth,
'--option-icon-prefix-width': optionIconPrefixWidth,
@ -396,8 +394,13 @@ export default defineComponent({
internalRenderBody: renderPopoverBody,
onUpdateShow: this.doUpdateShow
}
return h(NPopover, keep(this.$props, popoverPropKeys, popoverProps), {
trigger: this.$slots.default
})
return (
<NPopover {...keep(this.$props, popoverPropKeys)} {...popoverProps}>
{{
trigger: this.$slots.default,
_: true
}}
</NPopover>
)
}
})

View File

@ -6,7 +6,6 @@ import fadeInScaleUpTransition from '../../../_styles/transitions/fade-in-scale-
// --font-size
// --padding
// --border-radius
// --box-shadow
// --option-height
// --option-prefix-width
// --option-icon-prefix-width
@ -25,6 +24,9 @@ import fadeInScaleUpTransition from '../../../_styles/transitions/fade-in-scale-
// --option-icon-size
// --option-opacity-disabled
// shared with popover
// --box-shadow
export default cB('dropdown-menu', `
transform-origin: inherit;
padding: var(--padding);

View File

@ -9,7 +9,6 @@ export const self = (vars: ThemeCommonVars) => {
const {
primaryColor,
textColor2,
boxShadow2,
dividerColor,
hoverColor,
popoverColor,
@ -33,7 +32,6 @@ export const self = (vars: ThemeCommonVars) => {
optionHeightLarge: heightLarge,
optionHeightHuge: heightHuge,
borderRadius,
boxShadow: boxShadow2,
fontSizeSmall,
fontSizeMedium,
fontSizeLarge,

View File

@ -2,7 +2,7 @@
exports[`n-dropdown inverted style 1`] = `
<div
class="n-dropdown-menu n-popover n-dropdown"
class="n-dropdown-menu n-popover n-popover--shadow n-dropdown"
style="--box-shadow: 0 3px 6px -4px rgba(0, 0, 0, .12), 0 6px 16px 0 rgba(0, 0, 0, .08), 0 9px 28px 8px rgba(0, 0, 0, .05); --bezier: cubic-bezier(.4, 0, .2, 1); --bezier-ease-in: cubic-bezier(.4, 0, 1, 1); --bezier-ease-out: cubic-bezier(0, 0, .2, 1); --font-size: 14px; --text-color: rgb(51, 54, 57); --color: rgb(0, 20, 40); --border-radius: 3px; --arrow-height: 6px; --arrow-offset: 10px; --arrow-offset-vertical: 10px; --padding: 4px 0; --space: 6px; --space-arrow: 10px; --option-height: 34px; --option-prefix-width: 14px; --option-icon-prefix-width: 36px; --option-suffix-width: 14px; --option-icon-suffix-width: 32px; --option-icon-size: 16px; --divider-color: rgb(239, 239, 245); --option-opacity-disabled: 0.5; --option-color-hover: #18a058; --option-color-active: #18a058; --option-text-color: #BBB; --option-text-color-hover: #FFF; --option-text-color-active: #FFF; --option-text-color-child-active: #FFF; --prefix-color: #BBB; --suffix-color: #BBB; --group-header-text-color: #AAA;"
>
@ -224,7 +224,7 @@ exports[`n-dropdown inverted style 1`] = `
exports[`n-dropdown shows menu after click 1`] = `
<div
class="n-dropdown-menu n-popover n-dropdown"
class="n-dropdown-menu n-popover n-popover--shadow n-dropdown"
style="--box-shadow: 0 3px 6px -4px rgba(0, 0, 0, .12), 0 6px 16px 0 rgba(0, 0, 0, .08), 0 9px 28px 8px rgba(0, 0, 0, .05); --bezier: cubic-bezier(.4, 0, .2, 1); --bezier-ease-in: cubic-bezier(.4, 0, 1, 1); --bezier-ease-out: cubic-bezier(0, 0, .2, 1); --font-size: 14px; --text-color: rgb(51, 54, 57); --color: #fff; --border-radius: 3px; --arrow-height: 6px; --arrow-offset: 10px; --arrow-offset-vertical: 10px; --padding: 4px 0; --space: 6px; --space-arrow: 10px; --option-height: 34px; --option-prefix-width: 14px; --option-icon-prefix-width: 36px; --option-suffix-width: 14px; --option-icon-suffix-width: 32px; --option-icon-size: 16px; --divider-color: rgb(239, 239, 245); --option-opacity-disabled: 0.5; --option-color-hover: rgb(243, 243, 245); --option-color-active: rgba(24, 160, 88, 0.1); --option-text-color: rgb(51, 54, 57); --option-text-color-hover: rgb(51, 54, 57); --option-text-color-active: #18a058; --option-text-color-child-active: #18a058; --prefix-color: rgb(51, 54, 57); --suffix-color: rgb(51, 54, 57); --group-header-text-color: rgb(158, 164, 170);"
>

View File

@ -241,9 +241,11 @@ export default defineComponent({
contentNode = renderBody(
// The popover class and overlap class must exists, they will be used
// to place the body & transition animation.
// Shadow class exists for reuse box-shadow.
[
`${mergedClsPrefix}-popover`,
props.overlap && `${mergedClsPrefix}-popover--overlap`
props.overlap && `${mergedClsPrefix}-popover--overlap`,
props.shadow && `${mergedClsPrefix}-popover--shadow`
],
bodyRef,
styleRef.value as any,

View File

@ -2,7 +2,7 @@
```html
<n-popselect v-model:value="value" :options="options">
<n-tag>{{ value || 'Popselect' }}</n-tag>
<n-button>{{ value || 'Popselect' }}</n-button>
</n-popselect>
```

View File

@ -4,7 +4,7 @@ Make single value popselect cancelable.
```html
<n-popselect v-model:value="value" cancelable :options="options">
<n-tag>{{ value || 'Popselect' }}</n-tag>
<n-button>{{ value || 'Popselect' }}</n-button>
</n-popselect>
```

View File

@ -4,8 +4,8 @@ Select multiple value in popselect.
```html
<n-popselect v-model:value="value" multiple :options="options">
<n-tag
>{{ (Array.isArray(value) && value.length) ? value : 'Nothing' }}</n-tag
<n-button
>{{ (Array.isArray(value) && value.length) ? value : 'Nothing' }}</n-button
>
</n-popselect>
```

View File

@ -2,7 +2,7 @@
```html
<n-popselect v-model:value="value" :options="options" size="medium" scrollable>
<n-tag style="margin-right: 8px;">{{ value || 'Popselect' }}</n-tag>
<n-button style="margin-right: 8px;">{{ value || 'Popselect' }}</n-button>
</n-popselect>
```

View File

@ -2,10 +2,10 @@
```html
<n-popselect v-model:value="value" :options="options" size="medium">
<n-tag style="margin-right: 8px;">{{ value || 'Popselect' }}</n-tag>
<n-button style="margin-right: 8px;">{{ value || 'Popselect' }}</n-button>
</n-popselect>
<n-popselect v-model:value="value" :options="options" size="large">
<n-tag>{{ value || 'Popselect' }}</n-tag>
<n-button>{{ value || 'Popselect' }}</n-button>
</n-popselect>
```

View File

@ -1,8 +1,8 @@
# 基础用法
```html
<n-popselect v-model:value="value" :options="options">
<n-tag>{{ value || '弹出选择' }}</n-tag>
<n-popselect v-model:value="value" :options="options" trigger="click">
<n-button>{{ value || '弹出选择' }}</n-button>
</n-popselect>
```

View File

@ -4,7 +4,7 @@
```html
<n-popselect v-model:value="value" cancelable :options="options">
<n-tag>{{ value || '弹出选择' }}</n-tag>
<n-button>{{ value || '弹出选择' }}</n-button>
</n-popselect>
```

View File

@ -4,7 +4,9 @@
```html
<n-popselect v-model:value="value" multiple :options="options">
<n-tag>{{ (Array.isArray(value) && value.length) ? value : '没了' }}</n-tag>
<n-button
>{{ (Array.isArray(value) && value.length) ? value : '没了' }}</n-button
>
</n-popselect>
```

View File

@ -2,7 +2,7 @@
```html
<n-popselect v-model:value="value" :options="options" size="medium" scrollable>
<n-tag style="margin-right: 8px;">{{ value || 'Popselect' }}</n-tag>
<n-button style="margin-right: 8px;">{{ value || 'Popselect' }}</n-button>
</n-popselect>
```

View File

@ -2,10 +2,10 @@
```html
<n-popselect v-model:value="value" :options="options" size="medium">
<n-tag style="margin-right: 8px;">{{ value || 'Popselect' }}</n-tag>
<n-button style="margin-right: 8px;">{{ value || 'Popselect' }}</n-button>
</n-popselect>
<n-popselect v-model:value="value" :options="options" size="large">
<n-tag>{{ value || 'Popselect' }}</n-tag>
<n-button>{{ value || 'Popselect' }}</n-button>
</n-popselect>
```

View File

@ -1,6 +1,7 @@
import { h, ref, provide, defineComponent, PropType } from 'vue'
import { h, ref, provide, defineComponent, PropType, mergeProps } from 'vue'
import { NPopover } from '../../popover'
import { popoverBaseProps } from '../../popover/src/Popover'
import type { PopoverInternalProps } from '../../popover/src/Popover'
import type { PopoverInst, PopoverTrigger } from '../../popover'
import NPopselectPanel, { panelPropKeys, panelProps } from './PopselectPanel'
import { omit, keep } from '../../_utils'
@ -14,16 +15,11 @@ import { popselectInjectionKey } from './interface'
const popselectProps = {
...(useTheme.props as ThemeProps<PopselectTheme>),
...popoverBaseProps,
// eslint-disable-next-line vue/require-prop-types
trigger: {
type: String as PropType<PopoverTrigger>,
default: 'hover'
},
// eslint-disable-next-line vue/require-prop-types
showArrow: {
type: Boolean,
default: false
},
showArrow: Boolean,
...panelProps
}
@ -58,22 +54,47 @@ export default defineComponent({
}
},
render () {
const { mergedTheme } = this
return h(
NPopover,
omit(this.$props, panelPropKeys, {
padded: false,
ref: 'popoverInstRef',
internalExtraClass: 'popselect',
theme: mergedTheme.peers.Popover,
themeOverrides: mergedTheme.peerOverrides.Popover
}),
{
trigger: this.$slots.default,
default: () => {
return h(NPopselectPanel, keep(this.$props, panelPropKeys))
}
const { mergedTheme, $attrs } = this
const popoverProps: PopoverInternalProps & { ref: string } = {
theme: mergedTheme.peers.Popover,
themeOverrides: mergedTheme.peerOverrides.Popover,
ref: 'popoverInstRef',
internalRenderBody: (
className,
ref,
style,
onMouseenter,
onMouseleave
) => {
return (
<NPopselectPanel
{...mergeProps($attrs, {
class: className,
style
})}
{...keep(this.$props, panelPropKeys)}
ref={
((inst: { $el: HTMLElement | null } | null) => {
if (inst) {
ref.value = inst.$el
} else {
ref.value = null
}
}) as any
}
onMouseenter={onMouseenter}
onMouseleave={onMouseleave}
/>
)
}
}
return (
<NPopover {...omit(this.$props, panelPropKeys)} {...popoverProps}>
{{
trigger: this.$slots.default,
_: true
}}
</NPopover>
)
}
})

View File

@ -28,18 +28,12 @@ import { tmOptions } from '../../select/src/utils'
import { useConfig } from '../../_mixins'
export const panelProps = {
multiple: {
type: Boolean,
default: false
},
multiple: Boolean,
value: {
type: [String, Number, Array] as PropType<Value | null>,
default: null
},
cancelable: {
type: Boolean,
default: false
},
cancelable: Boolean,
width: [Number, String] as PropType<string | number>,
options: {
type: Array as PropType<SelectMixedOption[]>,
@ -49,13 +43,11 @@ export const panelProps = {
type: String as PropType<PopselectSize>,
default: 'medium'
},
scrollable: {
type: Boolean,
default: false
},
// eslint-disable-next-line vue/prop-name-casing
scrollable: Boolean,
'onUpdate:value': [Function, Array] as PropType<MaybeArray<OnUpdateValue>>,
onUpdateValue: [Function, Array] as PropType<MaybeArray<OnUpdateValue>>,
onMouseenter: Function as PropType<(e: MouseEvent) => void>,
onMouseleave: Function as PropType<(e: MouseEvent) => void>,
// deprecated
onChange: {
type: [Function, Array] as PropType<MaybeArray<OnUpdateValue> | undefined>,
@ -155,6 +147,8 @@ export default defineComponent({
virtualScroll={false}
scrollable={this.scrollable}
onMenuToggleOption={this.handleMenuToggleOption}
onMouseenter={this.onMouseenter}
onMouseleave={this.onMouseenter}
/>
)
}