This commit is contained in:
2026-01-05 12:47:14 +08:00
commit 1fc846fae3
1614 changed files with 162035 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
.nut-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: $overlay-bg-color;
}
.nut-overflow-hidden {
overflow: hidden !important;
}

View File

@@ -0,0 +1 @@
export * from './overlay'

View File

@@ -0,0 +1,48 @@
import type { CSSProperties, ExtractPropTypes, PropType } from 'vue'
import { CLICK_EVENT, UPDATE_VISIBLE_EVENT } from '../_constants'
import { commonProps, isBoolean, makeNumericProp, makeStringProp, truthProp } from '../_utils'
export const overlayProps = {
...commonProps,
/**
* @description 控制遮罩的显示/隐藏
*/
visible: Boolean,
/**
* @description 自定义遮罩层级
*/
zIndex: Number,
/**
* @description 显示/隐藏的动画时长,单位毫秒
*/
duration: makeNumericProp(300),
/**
* @description 自定义遮罩类名
*/
overlayClass: makeStringProp(''),
/**
* @description 自定义遮罩样式
*/
overlayStyle: Object as PropType<CSSProperties>,
/**
* @description 遮罩显示时的背景是否锁定
*/
lockScroll: Boolean,
/**
* @description 点击遮罩时是否关闭
*/
closeOnClickOverlay: truthProp,
/**
* @description 是否保留遮罩关闭后的内容
*/
destroyOnClose: Boolean,
}
export type OverlayProps = ExtractPropTypes<typeof overlayProps>
export const overlayEmits = {
[UPDATE_VISIBLE_EVENT]: (visible: boolean) => isBoolean(visible),
[CLICK_EVENT]: (evt: any) => evt instanceof Object,
}
export type OverlayEmits = typeof overlayEmits

View File

@@ -0,0 +1,82 @@
<script setup lang="ts">
import { computed, defineComponent, watchEffect } from 'vue'
import { CLICK_EVENT, PREFIX, UPDATE_VISIBLE_EVENT } from '../_constants'
import { useLockScroll } from '../_hooks'
import { getMainClass, getMainStyle } from '../_utils'
import NutTransition from '../transition/transition.vue'
import { overlayEmits, overlayProps } from './overlay'
const props = defineProps(overlayProps)
const emit = defineEmits(overlayEmits)
const classes = computed(() => {
return getMainClass(props, componentName, {
[props.overlayClass]: true,
})
})
const innerDuration = computed(() => {
if (typeof props.duration === 'number')
return props.duration
return Number(props.duration)
})
const styles = computed(() => {
return getMainStyle(props, {
transitionDuration: `${innerDuration.value}ms`,
zIndex: props.zIndex,
...props.overlayStyle,
})
})
function onClick(event: any) {
emit(CLICK_EVENT, event)
if (props.closeOnClickOverlay)
emit(UPDATE_VISIBLE_EVENT, false)
}
// #ifdef H5
const [lock, unlock] = useLockScroll(() => props.lockScroll)
watchEffect(() => {
if (props.visible)
lock()
else
unlock()
})
// #endif
</script>
<script lang="ts">
const componentName = `${PREFIX}-overlay`
export default defineComponent({
name: componentName,
options: {
virtualHost: true,
addGlobalClass: true,
styleIsolation: 'shared',
},
})
</script>
<template>
<NutTransition
:custom-class="classes"
:custom-style="styles"
:show="props.visible"
name="fade"
:duration="innerDuration"
:destroy-on-close="props.destroyOnClose"
@click="onClick"
>
<slot />
</NutTransition>
</template>
<style lang="scss">
@import "./index";
</style>