diff --git a/packages/components/spin/__tests__/__snapshots__/spinProvider.spec.ts.snap b/packages/components/spin/__tests__/__snapshots__/spinProvider.spec.ts.snap
index c79d824c0..fe4393fb7 100644
--- a/packages/components/spin/__tests__/__snapshots__/spinProvider.spec.ts.snap
+++ b/packages/components/spin/__tests__/__snapshots__/spinProvider.spec.ts.snap
@@ -1,3 +1,3 @@
// Vitest Snapshot v1
-exports[`SpinProvider > basic > render work 1`] = `"
content
"`;
+exports[`SpinProvider > basic > render work 1`] = `"content"`;
diff --git a/packages/components/spin/demo/UseSpin.md b/packages/components/spin/demo/UseSpin.md
index c3f502bfe..77c0211ba 100644
--- a/packages/components/spin/demo/UseSpin.md
+++ b/packages/components/spin/demo/UseSpin.md
@@ -8,7 +8,7 @@ hidden: true
## zh
-你可以通过`useSpin`来灵活的使用`spin`组件,前提是需要把子组件包裹在`IxSpinProvider`里面
+你可以通过`useSpin`来灵活的使用`spin`组件,前提是需要把子组件包裹在`IxSpinProvider`里面,此方法兼容`scroll`和`resize`存在的情况
``` html
diff --git a/packages/components/spin/demo/UseSpin.vue b/packages/components/spin/demo/UseSpin.vue
index 29c5f4715..06eaf5d5b 100644
--- a/packages/components/spin/demo/UseSpin.vue
+++ b/packages/components/spin/demo/UseSpin.vue
@@ -1,7 +1,27 @@
-
-
content
+
Open
@@ -51,15 +71,53 @@ const destroyAllSpin = () => {
}
diff --git a/packages/components/spin/src/SpinProvider.tsx b/packages/components/spin/src/SpinProvider.tsx
index a9353ad23..75f745cdb 100644
--- a/packages/components/spin/src/SpinProvider.tsx
+++ b/packages/components/spin/src/SpinProvider.tsx
@@ -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'
@@ -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,
})
@@ -54,10 +55,10 @@ export default defineComponent({
})
return (
-
+ <>
{children}
{slots.default?.()}
-
+ >
)
}
},
@@ -111,9 +112,10 @@ function useSpin(mergedPrefixCls: ComputedRef) {
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?.()
}
})
}
@@ -137,20 +139,43 @@ function useSpin(mergedPrefixCls: ComputedRef) {
[
`${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,
})
}
diff --git a/packages/components/spin/src/types.ts b/packages/components/spin/src/types.ts
index eb4c21bc5..0d9a4d241 100644
--- a/packages/components/spin/src/types.ts
+++ b/packages/components/spin/src/types.ts
@@ -50,6 +50,8 @@ export interface SpinMergedOptions extends SpinOptions {
hasScroll: boolean
isFullScreen: boolean
staticPosition: boolean
+
+ stopResizeWatch?: () => void
}
export interface SpinRef {