element-plus/packages/hooks/use-z-index/index.ts
qiang 1621b6a2d5
fix(hooks): SSR hydration error caused by z-index (#16175)
* fix(hooks): SSR hydration error caused by z-index

* test(hooks): test error

* chore: optimize name

* update

Co-authored-by: btea <2356281422@qq.com>

---------

Co-authored-by: btea <2356281422@qq.com>
2024-03-22 16:36:25 +08:00

65 lines
1.7 KiB
TypeScript

import { computed, getCurrentInstance, inject, ref, unref } from 'vue'
import { debugWarn, isClient, isNumber } from '@element-plus/utils'
import type { InjectionKey, Ref } from 'vue'
export interface ElZIndexInjectionContext {
current: number
}
const initial: ElZIndexInjectionContext = {
current: 0,
}
const zIndex = ref(0)
export const defaultInitialZIndex = 2000
// For SSR
export const ZINDEX_INJECTION_KEY: InjectionKey<ElZIndexInjectionContext> =
Symbol('elZIndexContextKey')
export const zIndexContextKey: InjectionKey<Ref<number | undefined>> =
Symbol('zIndexContextKey')
export const useZIndex = (zIndexOverrides?: Ref<number>) => {
const increasingInjection = getCurrentInstance()
? inject(ZINDEX_INJECTION_KEY, initial)
: initial
const zIndexInjection =
zIndexOverrides ||
(getCurrentInstance() ? inject(zIndexContextKey, undefined) : undefined)
const initialZIndex = computed(() => {
const zIndexFromInjection = unref(zIndexInjection)
return isNumber(zIndexFromInjection)
? zIndexFromInjection
: defaultInitialZIndex
})
const currentZIndex = computed(() => initialZIndex.value + zIndex.value)
const nextZIndex = () => {
increasingInjection.current++
zIndex.value = increasingInjection.current
return currentZIndex.value
}
if (!isClient && !inject(ZINDEX_INJECTION_KEY)) {
debugWarn(
'ZIndexInjection',
`Looks like you are using server rendering, you must provide a z-index provider to ensure the hydration process to be succeed
usage: app.provide(ZINDEX_INJECTION_KEY, { current: 0 })`
)
}
return {
initialZIndex,
currentZIndex,
nextZIndex,
}
}
export type UseZIndexReturn = ReturnType<typeof useZIndex>