Skip to content

Commit

Permalink
fix(comp:spin): compatible with the resize of target, when useSpin is…
Browse files Browse the repository at this point in the history
… used
  • Loading branch information
liuzaijiang committed Nov 13, 2022
1 parent 99e4ddd commit c5b8cfb
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// Vitest Snapshot v1

exports[`SpinProvider > basic > render work 1`] = `"<div class=\\"ix-spin-provider\\">content</div>"`;
exports[`SpinProvider > basic > render work 1`] = `"content"`;
2 changes: 1 addition & 1 deletion packages/components/spin/demo/UseSpin.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ hidden: true

## zh

你可以通过`useSpin`来灵活的使用`spin`组件,前提是需要把子组件包裹在`IxSpinProvider`里面
你可以通过`useSpin`来灵活的使用`spin`组件,前提是需要把子组件包裹在`IxSpinProvider`里面,此方法兼容`scroll``resize`存在的情况

``` html
<IxSpinProvider>
Expand Down
70 changes: 64 additions & 6 deletions packages/components/spin/demo/UseSpin.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
<template>
<IxSpace vertical :size="20">
<div class="card">
<div class="content">content</div>
<div class="resizable-container">
<CdkResizable
class="resizable-box"
free
:handlers="[]"
:maxWidth="800"
:maxHeight="400"
:minWidth="120"
:minHeight="140"
>
<div class="card">
<div class="content">Resizable!</div>
</div>
<CdkResizableHandle placement="end">
<div class="handle-end">
<IxIcon class="handle-end-icon" name="holder" />
</div>
</CdkResizableHandle>
<CdkResizableHandle placement="bottomEnd">
<IxIcon class="handle-bottom-end-icon" name="caret-up-filled" :rotate="135" />
</CdkResizableHandle>
</CdkResizable>
</div>
<IxSpace>
<IxButton @click="openSpin">Open</IxButton>
Expand Down Expand Up @@ -51,15 +71,53 @@ const destroyAllSpin = () => {
}
</script>
<style lang="less" scoped>
.resizable-container {
display: block;
height: 300px;
}
.resizable-box {
width: 300px;
height: 300px;
display: flex;
align-items: center;
justify-content: center;
background: #eee;
border: 1px solid #ddd;
}
.handle-end {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
&-icon {
background: #fff;
border: 1px solid #ddd;
text-align: center;
font-size: 12px;
height: 20px;
line-height: 20px;
}
}
.handle-bottom-end-icon {
position: absolute;
top: 0;
left: 0;
}
.card {
text-align: center;
padding: 50px;
background-color: #eee;
height: 300px;
background-color: #aea;
width: 90%;
height: 100%;
overflow: auto;
.content {
height: 500px;
width: 260px;
height: 260px;
}
}
</style>
45 changes: 35 additions & 10 deletions packages/components/spin/src/SpinProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
* found in the LICENSE file at https://github.com/IDuxFE/idux/blob/main/LICENSE
*/

import { ComputedRef, VNode, computed, defineComponent, normalizeStyle, provide, ref } from 'vue'
import { ComputedRef, VNode, computed, defineComponent, nextTick, normalizeStyle, provide, ref } from 'vue'

import { CdkPortal, type PortalTargetType } from '@idux/cdk/portal'
import { useResizeObserver } from '@idux/cdk/resize'
import { addClass, convertArray, convertCssPixel, removeClass } from '@idux/cdk/utils'
import { useGlobalConfig } from '@idux/components/config'
import { convertTarget } from '@idux/components/utils'
Expand Down Expand Up @@ -40,8 +41,8 @@ export default defineComponent({
const { spinning, target, width, height, isFullScreen, hasScroll, tip, zIndex } = spinOptions
const BaseZindex = zIndex ?? BASE_ZINDEX + index
const style = normalizeStyle({
width: !isFullScreen && hasScroll && convertCssPixel(width),
height: !isFullScreen && hasScroll && convertCssPixel(height),
width: !isFullScreen && hasScroll ? convertCssPixel(width) : null,
height: !isFullScreen && hasScroll ? convertCssPixel(height) : null,
position: isFullScreen ? 'fixed' : '',
zIndex: BaseZindex,
})
Expand All @@ -54,10 +55,10 @@ export default defineComponent({
})

return (
<div class={`${mergedPrefixCls.value}-provider`}>
<>
{children}
{slots.default?.()}
</div>
</>
)
}
},
Expand Down Expand Up @@ -111,9 +112,10 @@ function useSpin(mergedPrefixCls: ComputedRef<string>) {
targets.forEach(target => {
const currIndex = getCurrIndex(target)
if (currIndex !== -1) {
const item = spins.value.splice(currIndex, 1)
const targetElement = _convertTarget(item[0].target)
const item = spins.value.splice(currIndex, 1)[0]
const targetElement = _convertTarget(item.target)
targetElement && deleteClass(targetElement)
item.stopResizeWatch?.()
}
})
}
Expand All @@ -137,20 +139,43 @@ function useSpin(mergedPrefixCls: ComputedRef<string>) {
[
`${mergedPrefixCls.value}-target-container`,
staticPosition ? `${mergedPrefixCls.value}-target-container-relative` : '',
!isFullScreen && hasScroll ? `${mergedPrefixCls.value}-target-container-has-scroll` : '',
].filter(Boolean),
)

let stopResizeWatch: (() => void) | undefined

if (!isFullScreen) {
stopResizeWatch = useResizeObserver(targetElement, () => {
// 由于spin是传送到target内部,为了不影响target的真实宽高判断
// 为了兼容scroll和resize同时存在时spin依然能遮住target区域
// 所以每次resize时需要把spin宽高置为0,再nextTick中再判断是否出现滚轮
const currIndex = getCurrIndex(target)
spins.value[currIndex].width = 0
spins.value[currIndex].height = 0
nextTick(() => {
const hasScroll = elementHasScroll(targetElement)
spins.value[currIndex].hasScroll = hasScroll
const hasScrollClsName = `${mergedPrefixCls.value}-target-container-has-scroll`
if (hasScroll) {
addClass(targetElement, hasScrollClsName)
spins.value[currIndex].width = targetElement.scrollWidth
spins.value[currIndex].height = targetElement.scrollHeight
} else {
removeClass(targetElement, hasScrollClsName)
}
})
})
}

add({
spinning: true,
target,
hasScroll,
isFullScreen: targetElement === document.body,
staticPosition,
// 当存在滚动条且需要遮住全部除了全屏外(fixed可以解决)
// 其余几乎无此真实场景,所以不考虑resize时动态赋值width和height,目前也没办法解决
width: targetElement.scrollWidth,
height: targetElement.scrollHeight,
stopResizeWatch,
...reset,
})
}
Expand Down
2 changes: 2 additions & 0 deletions packages/components/spin/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ export interface SpinMergedOptions extends SpinOptions {
hasScroll: boolean
isFullScreen: boolean
staticPosition: boolean

stopResizeWatch?: () => void
}

export interface SpinRef {
Expand Down

0 comments on commit c5b8cfb

Please sign in to comment.