Skip to content

Commit

Permalink
feat(useZIndex): new composable (#156)
Browse files Browse the repository at this point in the history
this composable allows handling z-index dynamically avoiding issues where floating elements open behind another floating element
  • Loading branch information
IcetCode committed Jun 13, 2023
1 parent 7ae732f commit 975121d
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 4 deletions.
18 changes: 14 additions & 4 deletions packages/anu-vue/src/components/floating/AFloating.vue
@@ -1,10 +1,12 @@
<script lang="ts" setup>
import { autoUpdate, useFloating } from '@floating-ui/vue'
import { onClickOutside, useEventListener, useMounted } from '@vueuse/core'
import type { CSSProperties } from 'vue'
import { ref } from 'vue'
import type { AFloatingEvents, aFloatingSlots } from './meta'
import { aFloatingProps } from './meta'
import { useTeleport } from '@/composables/useTeleport'
import { useZIndex } from '@/composables/useZIndex'
const props = defineProps(aFloatingProps)
const emit = defineEmits<AFloatingEvents>()
Expand Down Expand Up @@ -47,6 +49,17 @@ const { x, y, strategy } = useFloating(toRef(props, 'referenceEl'), refFloating,
whileElementsMounted: autoUpdate,
})
const { nextZIndex } = useZIndex()
const zIndex = nextZIndex()
const contentStyle = computed<CSSProperties>(() => {
return {
top: `${unref(y) ?? 0}px`,
left: `${unref(x) ?? 0}px`,
zIndex,
}
})
// onMounted(() => {
// const vm = getCurrentInstance()
// console.log('vm?.proxy?.$el :>> ', vm?.proxy?.$parent)
Expand Down Expand Up @@ -119,10 +132,7 @@ defineExpose({
v-bind="$attrs"
ref="refFloating"
class="a-floating transform"
:style="{
top: `${y ?? 0}px`,
left: `${x ?? 0}px`,
}"
:style="contentStyle"
:class="strategy"
>
<slot />
Expand Down
35 changes: 35 additions & 0 deletions packages/anu-vue/src/composables/useZIndex.ts
@@ -0,0 +1,35 @@
import type { InjectionKey, Ref } from 'vue'
import { computed, inject, ref, unref } from 'vue'
import { isNumber } from '@vueuse/core'

Check failure on line 3 in packages/anu-vue/src/composables/useZIndex.ts

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest, lts/*)

isNumber not found in '@vueuse/core'

// TODO add Config Provider Component
export const zIndexContextKey: InjectionKey<Ref<number | undefined>> = Symbol('zIndexContextKey')

const zIndexCounter = ref(0)
export const defaultBaseZIndex = 2000 as const

export function useZIndex() {
const injectedZIndex = inject(zIndexContextKey)

const baseZIndex = computed(() => {
const injectedZIndexValue = unref(injectedZIndex)

return isNumber(injectedZIndexValue)
? injectedZIndexValue
: defaultBaseZIndex
})

const activeZIndex = computed(() => baseZIndex.value + zIndexCounter.value)

const nextZIndex = () => {
zIndexCounter.value++

return activeZIndex.value
}

return {
baseZIndex,
activeZIndex,
nextZIndex,
}
}
51 changes: 51 additions & 0 deletions packages/anu-vue/test/composables/useZIndex.test.ts
@@ -0,0 +1,51 @@
import { describe, expect, it } from 'vitest'
import type { ComponentPublicInstance } from 'vue'
import { defineComponent, nextTick, ref } from 'vue'
import type { VueWrapper } from '@vue/test-utils'
import { mount } from '@vue/test-utils'
import { defaultBaseZIndex, useZIndex, zIndexContextKey } from '../../src/composables/useZIndex'

describe('useZIndex', () => {
let wrapper: VueWrapper<ComponentPublicInstance>

const mountComponent = (provideZIndex?: number) => mount(
defineComponent({

Check failure on line 12 in packages/anu-vue/test/composables/useZIndex.test.ts

View workflow job for this annotation

GitHub Actions / lint (ubuntu-latest, lts/*)

Required name property is not set
setup(_, { expose }) {
const zIndex = useZIndex()
expose(zIndex)
},
template: '<div></div>',
}),
{
global: {
provide: {
[zIndexContextKey]: ref(provideZIndex),
},
},
},
)

it('should have the default baseZIndex when no custom zIndex is provided', async () => {
wrapper = mountComponent()
await nextTick()
expect(wrapper.vm.baseZIndex).toBe(defaultBaseZIndex)
})

it('should use the provided custom zIndex', async () => {
const zIndex = 1000
wrapper = mountComponent(zIndex)
const { vm } = wrapper
await nextTick()
expect(vm.baseZIndex).toBe(zIndex)
})

it('should increment zIndex correctly', async () => {
wrapper = mountComponent()
const { vm } = wrapper
await nextTick()
const initialZIndex = vm.activeZIndex
const incrementedZIndex = vm.nextZIndex()
expect(incrementedZIndex).toBe(initialZIndex + 1)
expect(vm.activeZIndex).toBe(initialZIndex + 1)
})
})

0 comments on commit 975121d

Please sign in to comment.