From c11fd7658d6a796b5c3f54129dc8316bbfb85c91 Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Sun, 25 Jul 2021 14:34:13 +0800 Subject: [PATCH] feat(popover): `trigger` prop support `'focus'`, closes #477 --- CHANGELOG.en-US.md | 7 ++-- CHANGELOG.zh-CN.md | 1 + src/popover/demos/enUS/index.demo-entry.md | 2 +- src/popover/demos/enUS/trigger.demo.md | 16 ++++++--- src/popover/demos/zhCN/index.demo-entry.md | 2 +- src/popover/demos/zhCN/trigger.demo.md | 16 ++++++--- src/popover/src/Popover.ts | 42 ++++++++++++++++++---- src/popover/src/interface.ts | 2 +- 8 files changed, 65 insertions(+), 23 deletions(-) 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 @@ - 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/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