Skip to content

Commit

Permalink
feat(comp:*): container is supported for all overlay related components
Browse files Browse the repository at this point in the history
  • Loading branch information
danranVm committed Sep 7, 2022
1 parent 96aa237 commit 6d30cd3
Show file tree
Hide file tree
Showing 108 changed files with 694 additions and 525 deletions.
2 changes: 1 addition & 1 deletion packages/cdk/popper/demo/Placement.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<IxButton ref="triggerRef" v-bind="triggerEvents">Hover</IxButton>
<CdkPortal target="ix-overlay">
<CdkPortal target=".ix-popper-container">
<div v-if="visibility" ref="popperRef" v-bind="popperEvents" class="popper">Popper Element</div>
</CdkPortal>
<br />
Expand Down
2 changes: 1 addition & 1 deletion packages/cdk/popper/demo/Trigger.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<IxButton ref="contextmenuTriggerRef" v-bind="contextmenuTriggerEvents">Contextmenu</IxButton>
<IxButton ref="manualTriggerRef" @click="manualUpdate({ visible: !manualVisibility })">Manual</IxButton>
</IxSpace>
<CdkPortal target="ix-popper">
<CdkPortal target=".ix-popper-container">
<div v-if="hoverVisibility" ref="hoverPopperRef" class="popper popper-hover" v-bind="hoverPopperEvents">Hover</div>
<div v-if="focusVisibility" ref="focusPopperRef" class="popper popper-focus">Focus</div>
<div v-if="clickVisibility" ref="clickPopperRef" class="popper popper-click">Click</div>
Expand Down
22 changes: 16 additions & 6 deletions packages/cdk/portal/__tests__/portal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('Portal', () => {
})

test('render work', () => {
const wrapper = PortalMount({ props: { target: 'render-container' } })
const wrapper = PortalMount({ props: { target: '.render-container' } })
expect(document.body.querySelector('.render-container')!.querySelector('#content')).toBeDefined()

expect(() => {
Expand All @@ -26,7 +26,7 @@ describe('Portal', () => {
})

test('disabled work', async () => {
const wrapper = PortalMount({ props: { target: 'disabled-container', disabled: true } })
const wrapper = PortalMount({ props: { target: '.disabled-container', disabled: true } })
const container = document.body.querySelector('.disabled-container')!
expect(container.querySelector('#content')).toBeNull()

Expand All @@ -36,7 +36,7 @@ describe('Portal', () => {
})

test('target work', async () => {
const wrapper = PortalMount({ props: { target: 'target-container1' } })
const wrapper = PortalMount({ props: { target: '.target-container1' } })
const container1 = document.body.querySelector('.target-container1')!
expect(container1.querySelector('#content')).not.toBeNull()

Expand All @@ -56,14 +56,24 @@ describe('Portal', () => {
expect(container1.querySelector('#content')).toBeNull()
expect(container2.querySelector('#content')).toBeNull()
expect(container3.querySelector('#content')).not.toBeNull()

const container4 = document.createElement('div')
container4.id = 'target-container4'
document.body.appendChild(container4)

await wrapper.setProps({ target: '#target-container4' })
expect(container1.querySelector('#content')).toBeNull()
expect(container2.querySelector('#content')).toBeNull()
expect(container3.querySelector('#content')).toBeNull()
expect(container4.querySelector('#content')).not.toBeNull()
})

test('load work', async () => {
const wrapper = PortalMount({ props: { target: 'test-container', load: false } })
expect(document.body.querySelector('.test-container')).toBeNull()
const wrapper = PortalMount({ props: { target: '.load-container', load: false } })
expect(document.body.querySelector('.load-container')).toBeNull()

await wrapper.setProps({ load: true })

expect(document.body.querySelector('.test-container')).not.toBeNull()
expect(document.body.querySelector('.load-container')).not.toBeNull()
})
})
29 changes: 27 additions & 2 deletions packages/cdk/portal/demo/Basic.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
<script setup lang="ts">
import { ref } from 'vue'
const open = ref(false)
</script>

<template>
<CdkPortal target="ix-container">
<div>Portal</div>
<IxButton @click="open = !open">Open Modal</IxButton>
<CdkPortal target="body">
<div v-if="open" class="portal-modal">
<p>Hello modal!</p>
<IxButton @click="open = false">Close</IxButton>
</div>
</CdkPortal>
</template>

<style scoped>
.portal-modal {
position: fixed;
z-index: 1000;
top: 30%;
left: 50%;
width: 300px;
margin-left: -150px;
padding: 48px;
border-radius: 4px;
background-color: #fff;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.05);
}
</style>
4 changes: 2 additions & 2 deletions packages/cdk/portal/demo/Disabled.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
order: 2
order: 1
title:
zh: 禁止传送
en: Disabled
---

## zh

`disabled` 设置为true可以禁止传送,直接以 `v-dom` 的上下文进行渲染
`disabled` 设置为 `true` 可以禁止传送,直接在当前 `DOM` 中进行渲染
39 changes: 28 additions & 11 deletions packages/cdk/portal/demo/Disabled.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
<template>
<CdkPortal target="ix-container" :disabled="disabled">
<div>Portal</div>
</CdkPortal>
<IxButton @click="handleDisable">Disabled</IxButton>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const open = ref(false)
const disabled = ref(false)
</script>

const handleDisable = () => {
disabled.value = !disabled.value
<template>
<IxSpace>
<IxButton @click="open = !open">Open Modal</IxButton>
<IxButton @click="disabled = !disabled">Disabled</IxButton>
</IxSpace>
<CdkPortal :disabled="disabled" target="body">
<div v-if="open" class="portal-modal">
<p>Hello modal!</p>
<IxButton @click="open = false">Close</IxButton>
</div>
</CdkPortal>
</template>

<style scoped>
.portal-modal {
position: fixed;
z-index: 1000;
top: 30%;
left: 50%;
width: 300px;
margin-left: -150px;
padding: 48px;
border-radius: 4px;
background-color: #fff;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.05);
}
</script>
</style>
35 changes: 29 additions & 6 deletions packages/cdk/portal/demo/Element.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,34 @@
<script setup lang="ts">
import { ref } from 'vue'
const open = ref(false)
const container = document.createElement('div')
container.classList.add('portal-element-demo-container')
document.body.appendChild(container)
</script>

<template>
<IxButton @click="open = !open">Open Modal</IxButton>
<CdkPortal :target="container">
<div>Portal</div>
<div v-if="open" class="portal-modal">
<p>Hello modal!</p>
<IxButton @click="open = false">Close</IxButton>
</div>
</CdkPortal>
</template>

<script setup lang="ts">
const container = document.createElement('div')
container.classList.add('custom-container')
document.body.appendChild(container)
</script>
<style scoped>
.portal-modal {
position: fixed;
z-index: 1000;
top: 30%;
left: 50%;
width: 300px;
margin-left: -150px;
padding: 48px;
border-radius: 4px;
background-color: #fff;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
}
</style>
34 changes: 26 additions & 8 deletions packages/cdk/portal/demo/Load.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
<template>
<CdkPortal target="ix-container" :load="load">
<div>Portal</div>
</CdkPortal>
<IxButton @click="load = !load">Load</IxButton>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const load = ref(false)
const open = ref(false)
</script>

<template>
<IxButton @click="open = !open">Open Modal</IxButton>
<CdkPortal target=".portal-load-demo-container" :load="open">
<div v-if="open" class="portal-modal portal-modal-lazy-load">
<p>Hello modal!</p>
<IxButton @click="open = false">Close</IxButton>
</div>
</CdkPortal>
</template>

<style scoped>
.portal-modal {
position: fixed;
z-index: 1000;
top: 30%;
left: 50%;
width: 300px;
margin-left: -150px;
padding: 48px;
border-radius: 4px;
background-color: #fff;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.05);
}
</style>
8 changes: 3 additions & 5 deletions packages/cdk/portal/docs/Api.zh.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
## API

`@idux/cdk/popper``Teleport` 进行了简单的封装.

### CdkPortal

#### PortalProps

| 名称 | 说明 | 类型 | 默认值 | 备注 |
| 名称 | 说明 | 类型 | 默认值 | 备注 |
| --- | --- | --- | --- | --- |
| `disabled` | 是否禁用传送 | `boolean` | - | - |
| `load` | 是否立即加载节点 | `boolean` | `true` | 传入 `false` 可以懒加载节点 <br />节点加载后,再修改此值将不再生效。 |
| `target` | 被传送的目标元素 | `string \| HTMLElement \| () => string \| HTMLElement` | - | 如果传入一个元素,组件直接传送到该元素上 <br /> 如果是一个字符串,会判断是否可以通过此字符串可以找到相应元素,若找到,则直接插入该元素下<br /> 反之会在 `body` 的最后一个元素上创建元素,并将组件传送到该元素, 传入的字符串将作为其类名 |
| `load` | 是否立即加载节点 | `boolean` | `true` | 传入 `false` 可以懒加载节点, 节点加载后,再修改此值将不再生效。 |
| `target` | 被传送的目标元素或者一个 [querySelector](https://developer.mozilla.org/zh-CN/docs/Web/API/Document/querySelector) 支持的 css 选择器 | `string \| HTMLElement \| () => string \| HTMLElement` | - | 当传入 css 选择器时,如果能找到,则直接返回。如果未查找到对应元素,就会在 `body` 中插入一个 `div`, 并设置对应的属性(仅支持简单的 `id``class` 选择器) |
2 changes: 2 additions & 0 deletions packages/cdk/portal/docs/Index.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ title: Portal
subtitle: 传送门
cover:
---

`Teleport` 进行了简单的封装,可以打开 `devtools` 来观察 `DOM` 元素的插入位置变化。
1 change: 0 additions & 1 deletion packages/cdk/portal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,5 @@ import Portal from './src/Portal'
const CdkPortal = Portal as unknown as PortalComponent

export { CdkPortal }
export { convertTarget as convertPortalTarget } from './src/convertTarget'

export type { PortalInstance, PortalComponent, PortalPublicProps as PortalProps, PortalTargetType } from './src/types'
57 changes: 49 additions & 8 deletions packages/cdk/portal/src/Portal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@

import { Teleport, computed, defineComponent, ref, watch } from 'vue'

import { convertTarget } from './convertTarget'
import { portalProps } from './types'
import { isFunction, isString } from 'lodash-es'

import { Logger } from '@idux/cdk/utils'

import { type PortalTargetType, portalProps } from './types'

export default defineComponent({
name: 'CdkPortal',
props: portalProps,
setup(props, { slots }) {
const loaded = ref(props.load)

watch(
() => props.load,
load => {
Expand All @@ -24,19 +26,58 @@ export default defineComponent({
}
},
)
const target = computed(() => loaded.value && convertTarget(props.target))

const elementRef = computed(() => convertTargetElement(props.target))

return () => {
const _target = target.value
if (!_target) {
if (!loaded.value) {
return null
}

return (
<Teleport to={_target} disabled={props.disabled}>
{slots.default?.()}
<Teleport to={elementRef.value} disabled={props.disabled}>
{slots.default && slots.default()}
</Teleport>
)
}
},
})

function convertTargetElement(target: PortalTargetType) {
const elementOrSelector = isFunction(target) ? target() : target

if (!isString(elementOrSelector)) {
return elementOrSelector
}

return getTargetElement(elementOrSelector)
}

function getTargetElement(selector: string) {
let element = document.querySelector(selector)
if (element) {
return element
}

const selectorType = selector.startsWith('.') ? 'class' : selector.startsWith('#') ? 'id' : undefined
// TODO: 临时兼容性处理
// 如果不是 class 或者 id 选择器,就尝试添加 class 前缀再查找一次
if (!selectorType) {
__DEV__ && Logger.warn('cdk/portal', 'the selector of target supports only simple id or class')
element = document.querySelector(`.${selector}`)
if (element) {
return element
}
}

const attrName = selectorType || 'class'
const attrValue = selectorType ? selector.substring(1) : selector
return createDivElement(attrName, attrValue)
}

function createDivElement(attrName: string, attrValue: string) {
const element = document.createElement('div')
element.setAttribute(attrName, attrValue)
document.body.appendChild(element)
return element
}
32 changes: 0 additions & 32 deletions packages/cdk/portal/src/convertTarget.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/components/_private/mask/style/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@

height: 100%;
background-color: @mask-background-color;
z-index: @zindex-l4-base;
z-index: 1000;
}
Loading

0 comments on commit 6d30cd3

Please sign in to comment.