mirror of
https://github.com/tusen-ai/naive-ui.git
synced 2025-03-07 13:48:31 +08:00
feat(popover): trigger
prop support 'focus'
, closes #477
This commit is contained in:
parent
a78c6de0d3
commit
c11fd7658d
@ -7,9 +7,10 @@
|
||||
- `n-time-picker` add `actions` prop, closes [#401](https://github.com/TuSimple/naive-ui/issues/401).
|
||||
- `n-switch` add `checked`, `unchecked` slots.
|
||||
- `n-switch` add `loading` prop, closes [#301](https://github.com/TuSimple/naive-ui/issues/301).
|
||||
- `n-select` pressing arrow down can open menu, ref [#300](https://github.com/TuSimple/naive-ui/issues/300)
|
||||
- `n-tree-select` pressing arrow down can open menu, ref [#300](https://github.com/TuSimple/naive-ui/issues/300)
|
||||
- `n-cascader` pressing arrow down can open menu, ref [#300](https://github.com/TuSimple/naive-ui/issues/300)
|
||||
- `n-select` pressing arrow down can open menu, ref [#300](https://github.com/TuSimple/naive-ui/issues/300).
|
||||
- `n-tree-select` pressing arrow down can open menu, ref [#300](https://github.com/TuSimple/naive-ui/issues/300).
|
||||
- `n-cascader` pressing arrow down can open menu, ref [#300](https://github.com/TuSimple/naive-ui/issues/300).
|
||||
- `n-popover`'s `trigger` prop support `'focus'`, closes [#477](https://github.com/TuSimple/naive-ui/issues/477).
|
||||
|
||||
### Fixes
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
- `n-select` 按下箭头会打开菜单,有关 [#300](https://github.com/TuSimple/naive-ui/issues/300)
|
||||
- `n-tree-select` 按下箭头会打开菜单,有关 [#300](https://github.com/TuSimple/naive-ui/issues/300)
|
||||
- `n-cascader` 按下箭头会打开菜单,有关 [#300](https://github.com/TuSimple/naive-ui/issues/300)
|
||||
- `n-popover` 的 `trigger` 属性支持 `'focus'`,关闭 [#477](https://github.com/TuSimple/naive-ui/issues/477)
|
||||
|
||||
### Fixes
|
||||
|
||||
|
@ -37,7 +37,7 @@ header
|
||||
| show-arrow | `boolean` | `true` | Whether to show arrow if set. |
|
||||
| show | `boolean` | `undefined` | Whether to show arrow. |
|
||||
| title | `string` | `undefined` | Popover title. |
|
||||
| trigger | `'hover' \| 'click' \| 'manual'` | `'hover'` | The popover trigger type. |
|
||||
| trigger | `'hover' \| 'click' \| 'focus' \| 'manual'` | `'hover'` | The popover trigger type. |
|
||||
| width | `number \| 'trigger'` | `undefined` | `'trigger'` means popover's witdh will follow its trigger's width. |
|
||||
| x | `number` | `undefined` | The CSS `left` pixel value when popover manually positioned (x, y need to be set together). |
|
||||
| y | `number` | `undefined` | The CSS `top` pixel value when popover manually positioned (x, y need to be set together). |
|
||||
|
@ -6,19 +6,25 @@
|
||||
<template #trigger>
|
||||
<n-button>Hover</n-button>
|
||||
</template>
|
||||
<span> I wish they all could be California girls </span>
|
||||
<span>I wish they all could be California girls</span>
|
||||
</n-popover>
|
||||
<n-popover trigger="click">
|
||||
<template #trigger>
|
||||
<n-button> Click </n-button>
|
||||
<n-button>Click</n-button>
|
||||
</template>
|
||||
<span> I wish they all could be California girls </span>
|
||||
<span>I wish they all could be California girls</span>
|
||||
</n-popover>
|
||||
<n-popover trigger="focus">
|
||||
<template #trigger>
|
||||
<n-button>Click</n-button>
|
||||
</template>
|
||||
<span>I wish they all could be California girls</span>
|
||||
</n-popover>
|
||||
<n-popover trigger="manual" :show="showPopover">
|
||||
<template #trigger>
|
||||
<n-button @click="showPopover = !showPopover"> Manual </n-button>
|
||||
<n-button @click="showPopover = !showPopover">Manual</n-button>
|
||||
</template>
|
||||
<span> I wish they all could be California girls </span>
|
||||
<span>I wish they all could be California girls</span>
|
||||
</n-popover>
|
||||
</n-space>
|
||||
```
|
||||
|
@ -38,7 +38,7 @@ header
|
||||
| show-arrow | `boolean` | `true` | 是否显示箭头 |
|
||||
| show | `boolean` | `undefined` | 是否展示 popover |
|
||||
| title | `string` | `undefined` | popover 的 title 信息 |
|
||||
| trigger | `'hover' \| 'click' \| 'manual'` | `'hover'` | popover 的触发方式 |
|
||||
| trigger | `'hover' \| 'click' \| 'focus' \| 'manual'` | `'hover'` | popover 的触发方式 |
|
||||
| width | `number \| 'trigger'` | `undefined` | `'trigger'` 表示 popover 的宽度会和它的触发元素一致 |
|
||||
| x | `number` | `undefined` | 手动控制位置时弹出内容的 CSS `left` 的像素值(x,y 都设置才能生效) |
|
||||
| y | `number` | `undefined` | 手动控制位置时弹出内容的 CSS `top` 的像素值(x,y 都设置才能生效) |
|
||||
|
@ -6,19 +6,25 @@
|
||||
<template #trigger>
|
||||
<n-button>悬浮</n-button>
|
||||
</template>
|
||||
<span> I wish they all could be California girls </span>
|
||||
<span>I wish they all could be California girls</span>
|
||||
</n-popover>
|
||||
<n-popover trigger="click">
|
||||
<template #trigger>
|
||||
<n-button> 点击 </n-button>
|
||||
<n-button>点击</n-button>
|
||||
</template>
|
||||
<span> I wish they all could be California girls </span>
|
||||
<span>I wish they all could be California girls</span>
|
||||
</n-popover>
|
||||
<n-popover trigger="focus">
|
||||
<template #trigger>
|
||||
<n-button>聚焦</n-button>
|
||||
</template>
|
||||
<span>I wish they all could be California girls</span>
|
||||
</n-popover>
|
||||
<n-popover trigger="manual" :show="showPopover">
|
||||
<template #trigger>
|
||||
<n-button @click="showPopover = !showPopover"> 手动 </n-button>
|
||||
<n-button @click="showPopover = !showPopover">手动</n-button>
|
||||
</template>
|
||||
<span> I wish they all could be California girls </span>
|
||||
<span>I wish they all could be California girls</span>
|
||||
</n-popover>
|
||||
</n-space>
|
||||
```
|
||||
|
@ -30,23 +30,34 @@ const bodyPropKeys = Object.keys(popoverBodyProps) as Array<
|
||||
keyof typeof popoverBodyProps
|
||||
>
|
||||
|
||||
const triggerEventMap = {
|
||||
focus: ['onFocus', 'onBlur'],
|
||||
click: ['onClick'],
|
||||
hover: ['onMouseenter', 'onMouseleave'],
|
||||
manual: []
|
||||
} as const
|
||||
|
||||
function appendEvents (
|
||||
vNode: VNode,
|
||||
trigger: PopoverTrigger,
|
||||
events: {
|
||||
onClick: (e: MouseEvent) => void
|
||||
onMouseenter: (e: MouseEvent) => void
|
||||
onMouseleave: (e: MouseEvent) => void
|
||||
onFocus: (e: FocusEvent) => void
|
||||
onBlur: (e: FocusEvent) => void
|
||||
}
|
||||
): void {
|
||||
Object.entries(events).forEach(([key, handler]) => {
|
||||
triggerEventMap[trigger].forEach((eventName) => {
|
||||
if (!vNode.props) vNode.props = {}
|
||||
else {
|
||||
vNode.props = Object.assign({}, vNode.props)
|
||||
}
|
||||
const originalHandler = vNode.props[key]
|
||||
if (!originalHandler) vNode.props[key] = handler
|
||||
const originalHandler = vNode.props[eventName]
|
||||
const handler = events[eventName]
|
||||
if (!originalHandler) vNode.props[eventName] = handler
|
||||
else {
|
||||
vNode.props[key] = (...args: unknown[]) => {
|
||||
vNode.props[eventName] = (...args: unknown[]) => {
|
||||
originalHandler(...args)
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
;(handler as any)(...args)
|
||||
@ -263,6 +274,20 @@ export default defineComponent({
|
||||
hideTimerIdRef.value = null
|
||||
}
|
||||
}
|
||||
function handleFocus (): void {
|
||||
const mergedDisabled = getMergedDisabled()
|
||||
if (props.trigger === 'focus' && !mergedDisabled) {
|
||||
if (getMergedShow()) return
|
||||
doUpdateShow(true)
|
||||
}
|
||||
}
|
||||
function handleBlur (): void {
|
||||
const mergedDisabled = getMergedDisabled()
|
||||
if (props.trigger === 'focus' && !mergedDisabled) {
|
||||
if (!getMergedShow()) return
|
||||
doUpdateShow(false)
|
||||
}
|
||||
}
|
||||
function handleMouseEnter (): void {
|
||||
const mergedDisabled = getMergedDisabled()
|
||||
if (props.trigger === 'hover' && !mergedDisabled) {
|
||||
@ -352,6 +377,8 @@ export default defineComponent({
|
||||
handleClick,
|
||||
handleMouseEnter,
|
||||
handleMouseLeave,
|
||||
handleFocus,
|
||||
handleBlur,
|
||||
setTriggerVNode (v: VNode | null) {
|
||||
triggerVNode = v
|
||||
},
|
||||
@ -373,11 +400,12 @@ export default defineComponent({
|
||||
triggerVNode.type === textVNodeType
|
||||
? h('span', [triggerVNode])
|
||||
: triggerVNode
|
||||
|
||||
appendEvents(triggerVNode, {
|
||||
appendEvents(triggerVNode, this.trigger, {
|
||||
onClick: this.handleClick,
|
||||
onMouseenter: this.handleMouseEnter,
|
||||
onMouseleave: this.handleMouseLeave
|
||||
onMouseleave: this.handleMouseLeave,
|
||||
onFocus: this.handleFocus,
|
||||
onBlur: this.handleBlur
|
||||
})
|
||||
}
|
||||
this.setTriggerVNode(triggerVNode)
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Ref, InjectionKey, CSSProperties, VNode } from 'vue'
|
||||
|
||||
export type PopoverTrigger = 'click' | 'hover' | 'manual'
|
||||
export type PopoverTrigger = 'click' | 'hover' | 'focus' | 'manual'
|
||||
|
||||
export interface PopoverInst {
|
||||
syncPosition: () => void
|
||||
|
Loading…
Reference in New Issue
Block a user