Skip to content

Commit

Permalink
fix(useDialog): renders component with popup content with unexpected …
Browse files Browse the repository at this point in the history
…focus management behavior, closes tusen-ai#2612
  • Loading branch information
07akioni authored and Julian Hundeloh committed Mar 11, 2022
1 parent 70ed7e4 commit bfa0e6a
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 42 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- Fix `n-tree-select`s in `multiple` mode cannot delete options whose `default-value` attribute contains parent node, closes [#2605](https://github.com/TuSimple/naive-ui/issues/2605).
- Fix `n-tree` may throw error when node is removed, closes [#2597](https://github.com/TuSimple/naive-ui/issues/2597).
- Fix `useDialog` renders component with popup content with unexpected focus management behavior, closes [#2612](https://github.com/TuSimple/naive-ui/issues/2612).

### Feats

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- 修复 `n-tree-select` 在 multiple 模式下不能删除 default-value 属性包含父节点的选项,关闭 [#2605](https://github.com/TuSimple/naive-ui/issues/2605)
- 修复 `n-tree` 在移除节点时可能抛出异常,关闭 [#2597](https://github.com/TuSimple/naive-ui/issues/2597)
- 修复 `useDialog` 中使用带有弹出层的元素有异常的焦点管理行为,关闭 [#2612](https://github.com/TuSimple/naive-ui/issues/2612)

### Feats

Expand Down
28 changes: 28 additions & 0 deletions src/dialog/demos/zhCN/focus-debug.demo.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<markdown>
# Focus debug
</markdown>

<template>
<n-button @click="handleClick">
Click me
</n-button>
</template>

<script lang="ts">
import { defineComponent, h } from 'vue'
import { useDialog, NTimePicker } from 'naive-ui'
export default defineComponent({
setup () {
const dialog = useDialog()
return {
handleClick: () => {
dialog.info({
title: 'test',
content: () => h('div', [h(NTimePicker), h(NTimePicker)])
})
}
}
}
})
</script>
1 change: 1 addition & 0 deletions src/dialog/demos/zhCN/index.demo-entry.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ async.vue
use-component.vue
mask.vue
action.vue
focus-debug.vue
```

## API
Expand Down
87 changes: 47 additions & 40 deletions src/dialog/src/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,46 @@ export const NDialog = defineComponent({
</NBaseIcon>
) : null

const actionNode = resolveWrappedSlot(this.$slots.action, (children) =>
children || positiveText || negativeText || action ? (
<div class={`${mergedClsPrefix}-dialog__action`}>
{children ||
(action
? [render(action)]
: [
this.negativeText && (
<NButton
theme={mergedTheme.peers.Button}
themeOverrides={mergedTheme.peerOverrides.Button}
ghost
size="small"
onClick={handleNegativeClick}
>
{{
default: () => render(this.negativeText)
}}
</NButton>
),
this.positiveText && (
<NButton
theme={mergedTheme.peers.Button}
themeOverrides={mergedTheme.peerOverrides.Button}
disabled={loading}
loading={loading}
size="small"
type={type === 'default' ? 'primary' : type}
onClick={handlePositiveClick}
>
{{
default: () => render(this.positiveText)
}}
</NButton>
)
])}
</div>
) : null
)

return (
<div
class={[
Expand All @@ -208,48 +248,15 @@ export const NDialog = defineComponent({
{showIcon && mergedIconPlacement === 'left' ? icon : null}
{resolveSlot(this.$slots.header, () => [render(title)])}
</div>
<div class={`${mergedClsPrefix}-dialog__content`}>
<div
class={[
`${mergedClsPrefix}-dialog__content`,
actionNode ? '' : `${mergedClsPrefix}-dialog__content--last`
]}
>
{resolveSlot(this.$slots.default, () => [render(content)])}
</div>
{resolveWrappedSlot(this.$slots.action, (children) =>
children || positiveText || negativeText || action ? (
<div class={`${mergedClsPrefix}-dialog__action`}>
{children ||
(action
? [render(action)]
: [
this.negativeText && (
<NButton
theme={mergedTheme.peers.Button}
themeOverrides={mergedTheme.peerOverrides.Button}
ghost
size="small"
onClick={handleNegativeClick}
>
{{
default: () => render(this.negativeText)
}}
</NButton>
),
this.positiveText && (
<NButton
theme={mergedTheme.peers.Button}
themeOverrides={mergedTheme.peerOverrides.Button}
disabled={loading}
loading={loading}
size="small"
type={type === 'default' ? 'primary' : type}
onClick={handlePositiveClick}
>
{{
default: () => render(this.positiveText)
}}
</NButton>
)
])}
</div>
) : null
)}
{actionNode}
</div>
)
}
Expand Down
2 changes: 1 addition & 1 deletion src/dialog/src/styles/index.cssr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export default c([
position: relative;
word-break: break-word;
`, [
c('&:last-child', 'margin-bottom: 0;')
cM('last', 'margin-bottom: 0;')
]),
cE('action', `
display: flex;
Expand Down
14 changes: 13 additions & 1 deletion src/modal/src/BodyWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,17 @@ export default defineComponent({
function handleClickOutside (e: MouseEvent): void {
props.onClickoutside(e)
}
const childNodeRef = ref<VNode | null>(null)
watch(childNodeRef, (node) => {
if (node) {
void nextTick(() => {
const el = node.el as HTMLElement | null
if (el && bodyRef.value !== el) {
bodyRef.value = el
}
})
}
})
provide(modalBodyInjectionKey, bodyRef)
provide(drawerBodyInjectionKey, null)
provide(popoverBodyInjectionKey, null)
Expand All @@ -164,6 +175,7 @@ export default defineComponent({
bodyRef,
scrollbarRef,
displayed: displayedRef,
childNodeRef,
handleClickOutside,
handlePositiveClick,
handleNegativeClick,
Expand Down Expand Up @@ -267,7 +279,7 @@ export default defineComponent({
{$slots}
</NCard>
) : (
childNode
(this.childNodeRef = childNode)
)) as any,
[
[vShow, this.show],
Expand Down

0 comments on commit bfa0e6a

Please sign in to comment.