diff --git a/CHANGELOG.en-US.md b/CHANGELOG.en-US.md
index 915e45299..a0edce710 100644
--- a/CHANGELOG.en-US.md
+++ b/CHANGELOG.en-US.md
@@ -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
diff --git a/CHANGELOG.zh-CN.md b/CHANGELOG.zh-CN.md
index 0df90a48a..adcc166d4 100644
--- a/CHANGELOG.zh-CN.md
+++ b/CHANGELOG.zh-CN.md
@@ -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
diff --git a/src/popover/demos/enUS/index.demo-entry.md b/src/popover/demos/enUS/index.demo-entry.md
index 713910761..c2ad7ff22 100644
--- a/src/popover/demos/enUS/index.demo-entry.md
+++ b/src/popover/demos/enUS/index.demo-entry.md
@@ -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). |
diff --git a/src/popover/demos/enUS/trigger.demo.md b/src/popover/demos/enUS/trigger.demo.md
index 9a2a20945..33a6296a3 100644
--- a/src/popover/demos/enUS/trigger.demo.md
+++ b/src/popover/demos/enUS/trigger.demo.md
@@ -6,19 +6,25 @@
Hover
- I wish they all could be California girls
+ I wish they all could be California girls
- Click
+ Click
- I wish they all could be California girls
+ I wish they all could be California girls
+
+
+
+ Click
+
+ I wish they all could be California girls
- Manual
+ Manual
- I wish they all could be California girls
+ I wish they all could be California girls
```
diff --git a/src/popover/demos/zhCN/index.demo-entry.md b/src/popover/demos/zhCN/index.demo-entry.md
index e4715cf40..246b7a489 100644
--- a/src/popover/demos/zhCN/index.demo-entry.md
+++ b/src/popover/demos/zhCN/index.demo-entry.md
@@ -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 都设置才能生效) |
diff --git a/src/popover/demos/zhCN/trigger.demo.md b/src/popover/demos/zhCN/trigger.demo.md
index 21cc5184b..56066b92c 100644
--- a/src/popover/demos/zhCN/trigger.demo.md
+++ b/src/popover/demos/zhCN/trigger.demo.md
@@ -6,19 +6,25 @@
悬浮
- I wish they all could be California girls
+ I wish they all could be California girls
- 点击
+ 点击
- I wish they all could be California girls
+ I wish they all could be California girls
+
+
+
+ 聚焦
+
+ I wish they all could be California girls
- 手动
+ 手动
- I wish they all could be California girls
+ I wish they all could be California girls
```
diff --git a/src/popover/src/Popover.ts b/src/popover/src/Popover.ts
index e09728025..1976da7ee 100644
--- a/src/popover/src/Popover.ts
+++ b/src/popover/src/Popover.ts
@@ -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)
diff --git a/src/popover/src/interface.ts b/src/popover/src/interface.ts
index 5ae4480ce..ea75072bf 100644
--- a/src/popover/src/interface.ts
+++ b/src/popover/src/interface.ts
@@ -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