@fiscozen/composables 0.1.18 → 0.1.20-autovertical.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/composables.js +160 -149
- package/dist/composables.umd.cjs +1 -1
- package/package.json +3 -3
- package/src/FzFloating.vue +31 -3
- package/src/__tests__/__snapshots__/FzFloating.spec.ts.snap +24 -12
- package/src/composables/index.ts +1 -1
- package/src/composables/useClickOutside.ts +12 -9
- package/src/composables/useCurrency.ts +7 -2
- package/src/composables/useFloating.ts +127 -79
- package/src/composables/useKeyDown.ts +4 -1
- package/src/composables/useKeyUp.ts +6 -4
- package/src/types.ts +10 -1
- package/src/utils/index.ts +16 -7
package/src/FzFloating.vue
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import { ref, useSlots, watch, toRef, computed } from 'vue'
|
|
2
|
+
import { ref, useSlots, watch, toRef, computed, onMounted, onBeforeUnmount } from 'vue'
|
|
3
3
|
import { useFloating } from './composables'
|
|
4
4
|
import { FzFloatingProps, FzUseFloatingArgs } from './types'
|
|
5
5
|
|
|
@@ -9,18 +9,28 @@ const props = withDefaults(defineProps<FzFloatingProps>(), {
|
|
|
9
9
|
teleport: false
|
|
10
10
|
})
|
|
11
11
|
|
|
12
|
+
const emits = defineEmits(['fzfloating:setPosition'])
|
|
13
|
+
|
|
12
14
|
const opener = ref(null)
|
|
13
15
|
const content = ref<HTMLElement | null>(null)
|
|
14
16
|
|
|
15
17
|
const slots = useSlots()
|
|
16
18
|
|
|
19
|
+
let scheduledAnimationFrame = false;
|
|
20
|
+
|
|
17
21
|
const useFloatingOpts: FzUseFloatingArgs = {
|
|
18
22
|
position: computed(() => props.position),
|
|
19
23
|
element: {
|
|
24
|
+
// @ts-ignore
|
|
20
25
|
domRef: content
|
|
21
26
|
},
|
|
22
27
|
container: {
|
|
28
|
+
// @ts-ignore
|
|
23
29
|
domRef: toRef(props.container || document.body)
|
|
30
|
+
},
|
|
31
|
+
useViewport: computed(() => props.useViewport),
|
|
32
|
+
callback(...args) {
|
|
33
|
+
emits('fzfloating:setPosition', ...args)
|
|
24
34
|
}
|
|
25
35
|
}
|
|
26
36
|
if (slots.opener) {
|
|
@@ -31,9 +41,21 @@ if (slots.opener) {
|
|
|
31
41
|
|
|
32
42
|
const floating = useFloating(useFloatingOpts)
|
|
33
43
|
|
|
44
|
+
const setPositionWhenOpen = () => {
|
|
45
|
+
if (scheduledAnimationFrame){
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
scheduledAnimationFrame = true;
|
|
50
|
+
requestAnimationFrame(() => {
|
|
51
|
+
props.isOpen && floating.setPosition();
|
|
52
|
+
scheduledAnimationFrame = false;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
34
56
|
watch(
|
|
35
57
|
() => props.position,
|
|
36
|
-
() =>
|
|
58
|
+
() => setPositionWhenOpen()
|
|
37
59
|
)
|
|
38
60
|
watch(
|
|
39
61
|
() => props.isOpen,
|
|
@@ -47,6 +69,12 @@ watch(
|
|
|
47
69
|
floating.setPosition()
|
|
48
70
|
}
|
|
49
71
|
)
|
|
72
|
+
onMounted(() => {
|
|
73
|
+
window.addEventListener('scroll', setPositionWhenOpen);
|
|
74
|
+
})
|
|
75
|
+
onBeforeUnmount(() => {
|
|
76
|
+
window.removeEventListener('scroll', setPositionWhenOpen);
|
|
77
|
+
})
|
|
50
78
|
|
|
51
79
|
const contentClass = computed(() => {
|
|
52
80
|
if (props.overrideContentClass) {
|
|
@@ -77,7 +105,7 @@ const contentClass = computed(() => {
|
|
|
77
105
|
<div
|
|
78
106
|
ref="content"
|
|
79
107
|
v-show="$slots.default && (!$slots.opener || ($slots.opener && isOpen))"
|
|
80
|
-
class="fz__floating__content bg-core-white
|
|
108
|
+
class="fz__floating__content bg-core-white fixed p-4 z-10"
|
|
81
109
|
:class="contentClass"
|
|
82
110
|
>
|
|
83
111
|
<slot :isOpen :floating></slot>
|
|
@@ -3,107 +3,119 @@
|
|
|
3
3
|
exports[`FzFloating > should match snapshot 1`] = `
|
|
4
4
|
"<div>
|
|
5
5
|
<div class="inline-flex"><button>opener</button></div>
|
|
6
|
-
<div class="bg-core-white
|
|
6
|
+
<div class="fz__floating__content bg-core-white fixed z-10 p-4 bg-core-white fixed p-4 z-10">
|
|
7
7
|
<div>content</div>
|
|
8
8
|
</div>
|
|
9
|
+
<!--v-if-->
|
|
9
10
|
</div>"
|
|
10
11
|
`;
|
|
11
12
|
|
|
12
13
|
exports[`FzFloating > should match snapshot 2`] = `
|
|
13
14
|
"<div>
|
|
14
15
|
<div class="inline-flex"><button>opener</button></div>
|
|
15
|
-
<div class="bg-core-white
|
|
16
|
+
<div class="fz__floating__content bg-core-white fixed z-10 p-4 bg-core-white fixed p-4 z-10">
|
|
16
17
|
<div>content</div>
|
|
17
18
|
</div>
|
|
19
|
+
<!--v-if-->
|
|
18
20
|
</div>"
|
|
19
21
|
`;
|
|
20
22
|
|
|
21
23
|
exports[`FzFloating > should match snapshot 3`] = `
|
|
22
24
|
"<div>
|
|
23
25
|
<div class="inline-flex"><button>opener</button></div>
|
|
24
|
-
<div class="bg-core-white
|
|
26
|
+
<div class="fz__floating__content bg-core-white fixed z-10 p-4 bg-core-white fixed p-4 z-10">
|
|
25
27
|
<div>content</div>
|
|
26
28
|
</div>
|
|
29
|
+
<!--v-if-->
|
|
27
30
|
</div>"
|
|
28
31
|
`;
|
|
29
32
|
|
|
30
33
|
exports[`FzFloating > should match snapshot 4`] = `
|
|
31
34
|
"<div>
|
|
32
35
|
<div class="inline-flex"><button>opener</button></div>
|
|
33
|
-
<div class="bg-core-white
|
|
36
|
+
<div class="fz__floating__content bg-core-white fixed z-10 p-4 bg-core-white fixed p-4 z-10">
|
|
34
37
|
<div>content</div>
|
|
35
38
|
</div>
|
|
39
|
+
<!--v-if-->
|
|
36
40
|
</div>"
|
|
37
41
|
`;
|
|
38
42
|
|
|
39
43
|
exports[`FzFloating > should match snapshot 5`] = `
|
|
40
44
|
"<div>
|
|
41
45
|
<div class="inline-flex"><button>opener</button></div>
|
|
42
|
-
<div class="bg-core-white
|
|
46
|
+
<div class="fz__floating__content bg-core-white fixed z-10 p-4 bg-core-white fixed p-4 z-10">
|
|
43
47
|
<div>content</div>
|
|
44
48
|
</div>
|
|
49
|
+
<!--v-if-->
|
|
45
50
|
</div>"
|
|
46
51
|
`;
|
|
47
52
|
|
|
48
53
|
exports[`FzFloating > should match snapshot 6`] = `
|
|
49
54
|
"<div>
|
|
50
55
|
<div class="inline-flex"><button>opener</button></div>
|
|
51
|
-
<div class="bg-core-white
|
|
56
|
+
<div class="fz__floating__content bg-core-white fixed z-10 p-4 bg-core-white fixed p-4 z-10">
|
|
52
57
|
<div>content</div>
|
|
53
58
|
</div>
|
|
59
|
+
<!--v-if-->
|
|
54
60
|
</div>"
|
|
55
61
|
`;
|
|
56
62
|
|
|
57
63
|
exports[`FzFloating > should match snapshot 7`] = `
|
|
58
64
|
"<div>
|
|
59
65
|
<div class="inline-flex"><button>opener</button></div>
|
|
60
|
-
<div class="bg-core-white
|
|
66
|
+
<div class="fz__floating__content bg-core-white fixed z-10 p-4 bg-core-white fixed p-4 z-10">
|
|
61
67
|
<div>content</div>
|
|
62
68
|
</div>
|
|
69
|
+
<!--v-if-->
|
|
63
70
|
</div>"
|
|
64
71
|
`;
|
|
65
72
|
|
|
66
73
|
exports[`FzFloating > should match snapshot 8`] = `
|
|
67
74
|
"<div>
|
|
68
75
|
<div class="inline-flex"><button>opener</button></div>
|
|
69
|
-
<div class="bg-core-white
|
|
76
|
+
<div class="fz__floating__content bg-core-white fixed z-10 p-4 bg-core-white fixed p-4 z-10">
|
|
70
77
|
<div>content</div>
|
|
71
78
|
</div>
|
|
79
|
+
<!--v-if-->
|
|
72
80
|
</div>"
|
|
73
81
|
`;
|
|
74
82
|
|
|
75
83
|
exports[`FzFloating > should match snapshot 9`] = `
|
|
76
84
|
"<div>
|
|
77
85
|
<div class="inline-flex"><button>opener</button></div>
|
|
78
|
-
<div class="bg-core-white
|
|
86
|
+
<div class="fz__floating__content bg-core-white fixed z-10 p-4 bg-core-white fixed p-4 z-10">
|
|
79
87
|
<div>content</div>
|
|
80
88
|
</div>
|
|
89
|
+
<!--v-if-->
|
|
81
90
|
</div>"
|
|
82
91
|
`;
|
|
83
92
|
|
|
84
93
|
exports[`FzFloating > should match snapshot 10`] = `
|
|
85
94
|
"<div>
|
|
86
95
|
<div class="inline-flex"><button>opener</button></div>
|
|
87
|
-
<div class="bg-core-white
|
|
96
|
+
<div class="fz__floating__content bg-core-white fixed z-10 p-4 bg-core-white fixed p-4 z-10">
|
|
88
97
|
<div>content</div>
|
|
89
98
|
</div>
|
|
99
|
+
<!--v-if-->
|
|
90
100
|
</div>"
|
|
91
101
|
`;
|
|
92
102
|
|
|
93
103
|
exports[`FzFloating > should match snapshot 11`] = `
|
|
94
104
|
"<div>
|
|
95
105
|
<div class="inline-flex"><button>opener</button></div>
|
|
96
|
-
<div class="bg-core-white
|
|
106
|
+
<div class="fz__floating__content bg-core-white fixed z-10 p-4 bg-core-white fixed p-4 z-10">
|
|
97
107
|
<div>content</div>
|
|
98
108
|
</div>
|
|
109
|
+
<!--v-if-->
|
|
99
110
|
</div>"
|
|
100
111
|
`;
|
|
101
112
|
|
|
102
113
|
exports[`FzFloating > should match snapshot 12`] = `
|
|
103
114
|
"<div>
|
|
104
115
|
<div class="inline-flex"><button>opener</button></div>
|
|
105
|
-
<div class="bg-core-white
|
|
116
|
+
<div class="fz__floating__content bg-core-white fixed z-10 p-4 bg-core-white fixed p-4 z-10">
|
|
106
117
|
<div>content</div>
|
|
107
118
|
</div>
|
|
119
|
+
<!--v-if-->
|
|
108
120
|
</div>"
|
|
109
121
|
`;
|
package/src/composables/index.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { onBeforeUnmount, onMounted, Ref, watch } from 'vue'
|
|
2
2
|
|
|
3
3
|
function useClickOutside(
|
|
4
|
-
component: Ref<HTMLElement | undefined>,
|
|
4
|
+
component: Ref<HTMLElement | undefined>,
|
|
5
5
|
callback: () => void,
|
|
6
|
-
elementToListenClicksOn?: Ref<HTMLElement | undefined
|
|
6
|
+
elementToListenClicksOn?: Ref<HTMLElement | undefined>
|
|
7
7
|
) {
|
|
8
8
|
// fail early if any of the required params is missing
|
|
9
9
|
if (!component) {
|
|
@@ -14,7 +14,7 @@ function useClickOutside(
|
|
|
14
14
|
throw new Error('A callback has to be provided.')
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
const listener = (event:
|
|
17
|
+
const listener = (event: Event) => {
|
|
18
18
|
if (
|
|
19
19
|
!component.value ||
|
|
20
20
|
event.target === component.value ||
|
|
@@ -28,12 +28,15 @@ function useClickOutside(
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
if (elementToListenClicksOn) {
|
|
31
|
-
watch(
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
watch(
|
|
32
|
+
elementToListenClicksOn,
|
|
33
|
+
(newVal: Element | undefined, oldVal: Element | undefined) => {
|
|
34
|
+
if (oldVal) {
|
|
35
|
+
oldVal.removeEventListener('click', listener)
|
|
36
|
+
}
|
|
37
|
+
newVal?.addEventListener('click', listener)
|
|
34
38
|
}
|
|
35
|
-
|
|
36
|
-
});
|
|
39
|
+
)
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
onMounted(() => {
|
|
@@ -45,7 +48,7 @@ function useClickOutside(
|
|
|
45
48
|
onBeforeUnmount(() => {
|
|
46
49
|
if (elementToListenClicksOn) {
|
|
47
50
|
elementToListenClicksOn.value!.removeEventListener('click', listener)
|
|
48
|
-
return
|
|
51
|
+
return
|
|
49
52
|
}
|
|
50
53
|
document.removeEventListener('click', listener)
|
|
51
54
|
})
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {Ref, watch, getCurrentInstance, computed, ref} from 'vue'
|
|
1
|
+
import {Ref, watch, getCurrentInstance, computed, ref, onMounted} from 'vue'
|
|
2
2
|
|
|
3
3
|
export const useCurrency = () => {
|
|
4
4
|
const inputRef: Ref<HTMLInputElement|null> = ref(null)
|
|
5
5
|
const vm = getCurrentInstance()
|
|
6
6
|
|
|
7
|
-
const modelValue = computed(() => vm?.props.modelValue)
|
|
7
|
+
const modelValue = computed<number|undefined>(() => vm?.props.modelValue as unknown as number|undefined)
|
|
8
8
|
|
|
9
9
|
const format = (input: number) => {
|
|
10
10
|
return input.toLocaleString('it-IT', {
|
|
@@ -63,9 +63,14 @@ export const useCurrency = () => {
|
|
|
63
63
|
newVal.addEventListener('input', onInput(newVal))
|
|
64
64
|
newVal.addEventListener('blur', onBlur)
|
|
65
65
|
|
|
66
|
+
if (modelValue.value) {
|
|
67
|
+
newVal.value = format(modelValue.value)
|
|
68
|
+
}
|
|
69
|
+
|
|
66
70
|
})
|
|
67
71
|
|
|
68
72
|
|
|
73
|
+
|
|
69
74
|
return {
|
|
70
75
|
inputRef,
|
|
71
76
|
parse,
|
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
import { FzFloatingPosition, FzRect, FzUseFloatingArgs } from '../types'
|
|
2
|
-
import { ref, reactive, onUnmounted, Ref, nextTick
|
|
2
|
+
import { ref, reactive, onUnmounted, Ref, nextTick } from 'vue'
|
|
3
3
|
import { calcRealPos, getHighestAvailableSpacePos } from '../utils'
|
|
4
4
|
|
|
5
5
|
export const useFloating = (
|
|
6
6
|
args: FzUseFloatingArgs
|
|
7
7
|
): {
|
|
8
8
|
float: FzRect
|
|
9
|
-
rect: Ref<DOMRect |
|
|
10
|
-
floatObserver: Ref<IntersectionObserver>
|
|
9
|
+
rect: Ref<DOMRect | undefined>
|
|
11
10
|
setPosition: () => Promise<void>
|
|
11
|
+
position: Ref<FzFloatingPosition>
|
|
12
|
+
actualPosition?: Ref<FzFloatingPosition|undefined>
|
|
13
|
+
openerRect: Ref<DOMRect | undefined>
|
|
14
|
+
containerRect: Ref<DOMRect | undefined>
|
|
12
15
|
} => {
|
|
13
16
|
const safeElementDomRef = ref<HTMLElement | null>(null)
|
|
14
17
|
const safeContainerDomRef = ref<HTMLElement | null>(null)
|
|
15
18
|
const safeOpenerDomRef = ref<HTMLElement | null>(null)
|
|
16
|
-
const
|
|
19
|
+
const openerRect = ref<DOMRect | undefined>()
|
|
20
|
+
const containerRect = ref<DOMRect | undefined>()
|
|
21
|
+
const position = ref<FzFloatingPosition>('auto')
|
|
22
|
+
const rect = ref<DOMRect | undefined>()
|
|
17
23
|
const float = reactive<FzRect>({
|
|
18
24
|
position: { x: 0, y: 0 }
|
|
19
25
|
})
|
|
@@ -30,20 +36,23 @@ export const useFloating = (
|
|
|
30
36
|
) => {}
|
|
31
37
|
|
|
32
38
|
const floatObserver = ref(new IntersectionObserver(handleIntersect, options))
|
|
39
|
+
const actualPosition = ref<FzFloatingPosition>();
|
|
40
|
+
|
|
33
41
|
|
|
34
42
|
const setPosition = () =>
|
|
35
43
|
nextTick(() => {
|
|
44
|
+
actualPosition.value = args.position ? args.position.value : 'auto';
|
|
36
45
|
safeElementDomRef.value =
|
|
37
|
-
typeof args.element.domRef.value === 'string'
|
|
38
|
-
? document.querySelector(args.element.domRef.value)
|
|
39
|
-
: args.element.domRef.value
|
|
46
|
+
(typeof args.element.domRef.value === 'string'
|
|
47
|
+
? document.querySelector(args.element.domRef.value)
|
|
48
|
+
: args.element.domRef.value) as HTMLElement
|
|
40
49
|
if (!args.container) {
|
|
41
50
|
safeContainerDomRef.value = document.body
|
|
42
51
|
} else {
|
|
43
52
|
safeContainerDomRef.value =
|
|
44
|
-
typeof args.container.domRef.value === 'string'
|
|
53
|
+
(typeof args.container.domRef.value === 'string'
|
|
45
54
|
? document.querySelector(args.container.domRef.value)
|
|
46
|
-
: args.container.domRef.value
|
|
55
|
+
: args.container.domRef.value) as HTMLElement
|
|
47
56
|
safeContainerDomRef.value ??= document.body
|
|
48
57
|
}
|
|
49
58
|
|
|
@@ -53,77 +62,102 @@ export const useFloating = (
|
|
|
53
62
|
|
|
54
63
|
if (args.opener) {
|
|
55
64
|
safeOpenerDomRef.value =
|
|
56
|
-
typeof args.opener.domRef.value === 'string'
|
|
65
|
+
(typeof args.opener.domRef.value === 'string'
|
|
57
66
|
? document.querySelector(args.opener.domRef.value)
|
|
58
|
-
: args.opener.domRef.value
|
|
67
|
+
: args.opener.domRef.value) as HTMLElement
|
|
59
68
|
}
|
|
60
69
|
|
|
61
70
|
rect.value = safeElementDomRef.value.getBoundingClientRect()
|
|
62
|
-
|
|
63
|
-
|
|
71
|
+
openerRect.value = safeOpenerDomRef.value?.getBoundingClientRect()
|
|
72
|
+
containerRect.value = safeContainerDomRef.value.getBoundingClientRect()
|
|
64
73
|
|
|
65
|
-
const elStyle = window.getComputedStyle(safeElementDomRef.value)
|
|
74
|
+
const elStyle = window.getComputedStyle(safeElementDomRef.value as HTMLElement)
|
|
66
75
|
|
|
67
76
|
// multiple observer calls on same target do not cause multiple registrations
|
|
68
|
-
floatObserver.value.observe(safeElementDomRef.value)
|
|
69
|
-
floatObserver.value.observe(safeContainerDomRef.value)
|
|
70
|
-
|
|
71
|
-
let position: FzFloatingPosition = args.position ? args.position.value : 'auto'
|
|
77
|
+
floatObserver.value.observe(safeElementDomRef.value as HTMLElement)
|
|
78
|
+
floatObserver.value.observe(safeContainerDomRef.value as HTMLElement)
|
|
72
79
|
|
|
73
80
|
let translateY = 0
|
|
74
81
|
let translateX = 0
|
|
75
82
|
|
|
76
|
-
if (args.opener && safeOpenerDomRef.value && openerRect) {
|
|
83
|
+
if (args.opener && safeOpenerDomRef.value && openerRect && openerRect.value) {
|
|
77
84
|
const leftWithoutXMargin =
|
|
78
|
-
openerRect.left - parseFloat(elStyle.marginLeft) - parseFloat(elStyle.marginRight)
|
|
79
|
-
const leftWithoutLeftMargin = openerRect.left - parseFloat(elStyle.marginLeft)
|
|
85
|
+
openerRect.value.left - parseFloat(elStyle.marginLeft) - parseFloat(elStyle.marginRight)
|
|
86
|
+
const leftWithoutLeftMargin = openerRect.value.left - parseFloat(elStyle.marginLeft)
|
|
80
87
|
const topWithoutYMargin =
|
|
81
|
-
openerRect.top - parseFloat(elStyle.marginTop) - parseFloat(elStyle.marginBottom)
|
|
82
|
-
const topWithoutTopMargin = openerRect.top - parseFloat(elStyle.marginTop)
|
|
88
|
+
openerRect.value.top - parseFloat(elStyle.marginTop) - parseFloat(elStyle.marginBottom)
|
|
89
|
+
const topWithoutTopMargin = openerRect.value.top - parseFloat(elStyle.marginTop)
|
|
83
90
|
|
|
84
|
-
switch (
|
|
91
|
+
switch (actualPosition.value) {
|
|
85
92
|
case 'auto':
|
|
86
|
-
|
|
87
|
-
safeContainerDomRef.value,
|
|
88
|
-
safeElementDomRef.value,
|
|
89
|
-
safeOpenerDomRef.value
|
|
93
|
+
actualPosition.value = getHighestAvailableSpacePos(
|
|
94
|
+
args.useViewport ? null : safeContainerDomRef.value as HTMLElement,
|
|
95
|
+
safeElementDomRef.value as HTMLElement,
|
|
96
|
+
safeOpenerDomRef.value as HTMLElement
|
|
97
|
+
)
|
|
98
|
+
break
|
|
99
|
+
case 'auto-vertical':
|
|
100
|
+
actualPosition.value = getHighestAvailableSpacePos(
|
|
101
|
+
args.useViewport ? null : safeContainerDomRef.value as HTMLElement,
|
|
102
|
+
safeElementDomRef.value as HTMLElement,
|
|
103
|
+
safeOpenerDomRef.value as HTMLElement,
|
|
104
|
+
undefined,
|
|
105
|
+
true
|
|
90
106
|
)
|
|
91
107
|
break
|
|
92
108
|
case 'auto-start':
|
|
93
|
-
|
|
94
|
-
safeContainerDomRef.value,
|
|
95
|
-
safeElementDomRef.value,
|
|
96
|
-
safeOpenerDomRef.value,
|
|
109
|
+
actualPosition.value = getHighestAvailableSpacePos(
|
|
110
|
+
args.useViewport ? null : safeContainerDomRef.value as HTMLElement,
|
|
111
|
+
safeElementDomRef.value as HTMLElement,
|
|
112
|
+
safeOpenerDomRef.value as HTMLElement,
|
|
97
113
|
'start'
|
|
98
114
|
)
|
|
99
115
|
break
|
|
116
|
+
case 'auto-vertical-start':
|
|
117
|
+
actualPosition.value = getHighestAvailableSpacePos(
|
|
118
|
+
args.useViewport ? null : safeContainerDomRef.value as HTMLElement,
|
|
119
|
+
safeElementDomRef.value as HTMLElement,
|
|
120
|
+
safeOpenerDomRef.value as HTMLElement,
|
|
121
|
+
'start',
|
|
122
|
+
true
|
|
123
|
+
)
|
|
124
|
+
break
|
|
100
125
|
case 'auto-end':
|
|
101
|
-
|
|
102
|
-
safeContainerDomRef.value,
|
|
103
|
-
safeElementDomRef.value,
|
|
104
|
-
safeOpenerDomRef.value,
|
|
126
|
+
actualPosition.value = getHighestAvailableSpacePos(
|
|
127
|
+
args.useViewport ? null : safeContainerDomRef.value as HTMLElement,
|
|
128
|
+
safeElementDomRef.value as HTMLElement,
|
|
129
|
+
safeOpenerDomRef.value as HTMLElement,
|
|
105
130
|
'end'
|
|
106
131
|
)
|
|
107
132
|
break
|
|
133
|
+
case 'auto-vertical-end':
|
|
134
|
+
actualPosition.value = getHighestAvailableSpacePos(
|
|
135
|
+
args.useViewport ? null : safeContainerDomRef.value as HTMLElement,
|
|
136
|
+
safeElementDomRef.value as HTMLElement,
|
|
137
|
+
safeOpenerDomRef.value as HTMLElement,
|
|
138
|
+
'end',
|
|
139
|
+
true
|
|
140
|
+
)
|
|
141
|
+
break
|
|
108
142
|
default:
|
|
109
143
|
break
|
|
110
144
|
}
|
|
111
|
-
switch (
|
|
145
|
+
switch (actualPosition.value) {
|
|
112
146
|
case 'bottom':
|
|
113
|
-
float.position.y = openerRect.bottom
|
|
114
|
-
float.position.x = leftWithoutLeftMargin + openerRect.width / 2
|
|
147
|
+
float.position.y = openerRect.value.bottom
|
|
148
|
+
float.position.x = leftWithoutLeftMargin + openerRect.value.width / 2
|
|
115
149
|
translateX = -50
|
|
116
150
|
translateY = 0
|
|
117
151
|
break
|
|
118
152
|
case 'bottom-start':
|
|
119
|
-
float.position.y = openerRect.bottom
|
|
153
|
+
float.position.y = openerRect.value.bottom
|
|
120
154
|
float.position.x = leftWithoutXMargin
|
|
121
155
|
translateX = 0
|
|
122
156
|
translateY = 0
|
|
123
157
|
break
|
|
124
158
|
case 'bottom-end':
|
|
125
|
-
float.position.y = openerRect.bottom
|
|
126
|
-
float.position.x = openerRect.right
|
|
159
|
+
float.position.y = openerRect.value.bottom
|
|
160
|
+
float.position.x = openerRect.value.right
|
|
127
161
|
translateX = -100
|
|
128
162
|
translateY = 0
|
|
129
163
|
break
|
|
@@ -134,13 +168,13 @@ export const useFloating = (
|
|
|
134
168
|
translateY = 0
|
|
135
169
|
break
|
|
136
170
|
case 'left':
|
|
137
|
-
float.position.y = topWithoutTopMargin + openerRect.height / 2
|
|
171
|
+
float.position.y = topWithoutTopMargin + openerRect.value.height / 2
|
|
138
172
|
float.position.x = leftWithoutXMargin
|
|
139
173
|
translateY = -50
|
|
140
174
|
translateX = -100
|
|
141
175
|
break
|
|
142
176
|
case 'left-end':
|
|
143
|
-
float.position.y = openerRect.bottom
|
|
177
|
+
float.position.y = openerRect.value.bottom
|
|
144
178
|
float.position.x = leftWithoutXMargin
|
|
145
179
|
translateY = -100
|
|
146
180
|
translateX = -100
|
|
@@ -153,31 +187,31 @@ export const useFloating = (
|
|
|
153
187
|
break
|
|
154
188
|
case 'top':
|
|
155
189
|
float.position.y = topWithoutYMargin
|
|
156
|
-
float.position.x = leftWithoutLeftMargin + openerRect.width / 2
|
|
190
|
+
float.position.x = leftWithoutLeftMargin + openerRect.value.width / 2
|
|
157
191
|
translateX = -50
|
|
158
192
|
translateY = -100
|
|
159
193
|
break
|
|
160
194
|
case 'top-end':
|
|
161
195
|
float.position.y = topWithoutYMargin
|
|
162
|
-
float.position.x = openerRect.right
|
|
196
|
+
float.position.x = openerRect.value.right
|
|
163
197
|
translateX = -100
|
|
164
198
|
translateY = -100
|
|
165
199
|
break
|
|
166
200
|
case 'right-start':
|
|
167
201
|
float.position.y = topWithoutYMargin
|
|
168
|
-
float.position.x = openerRect.right
|
|
202
|
+
float.position.x = openerRect.value.right
|
|
169
203
|
translateX = 0
|
|
170
204
|
translateY = 0
|
|
171
205
|
break
|
|
172
206
|
case 'right':
|
|
173
|
-
float.position.y = topWithoutTopMargin + openerRect.height / 2
|
|
174
|
-
float.position.x = openerRect.right
|
|
207
|
+
float.position.y = topWithoutTopMargin + openerRect.value.height / 2
|
|
208
|
+
float.position.x = openerRect.value.right
|
|
175
209
|
translateY = -50
|
|
176
210
|
translateX = 0
|
|
177
211
|
break
|
|
178
212
|
case 'right-end':
|
|
179
|
-
float.position.y = openerRect.bottom
|
|
180
|
-
float.position.x = openerRect.right
|
|
213
|
+
float.position.y = openerRect.value.bottom
|
|
214
|
+
float.position.x = openerRect.value.right
|
|
181
215
|
translateY = -100
|
|
182
216
|
translateX = 0
|
|
183
217
|
break
|
|
@@ -185,42 +219,45 @@ export const useFloating = (
|
|
|
185
219
|
break
|
|
186
220
|
}
|
|
187
221
|
} else {
|
|
188
|
-
switch (
|
|
222
|
+
switch (actualPosition.value) {
|
|
189
223
|
case 'bottom':
|
|
190
|
-
float.position.y = containerRect.bottom - rect.value.height
|
|
191
|
-
float.position.x = containerRect.left + containerRect.width / 2
|
|
224
|
+
float.position.y = containerRect.value.bottom - rect.value.height
|
|
225
|
+
float.position.x = containerRect.value.left + containerRect.value.width / 2
|
|
192
226
|
translateX = -50
|
|
193
227
|
break
|
|
194
228
|
case 'left-end':
|
|
195
229
|
case 'bottom-start':
|
|
196
|
-
float.position.y = containerRect.bottom - rect.value.height
|
|
197
|
-
float.position.x = containerRect.left
|
|
230
|
+
float.position.y = containerRect.value.bottom - rect.value.height
|
|
231
|
+
float.position.x = containerRect.value.left
|
|
198
232
|
break
|
|
199
233
|
case 'right-end':
|
|
200
234
|
case 'bottom-end':
|
|
201
|
-
float.position.y = containerRect.bottom - rect.value.height
|
|
202
|
-
float.position.x = containerRect.right - rect.value.width
|
|
235
|
+
float.position.y = containerRect.value.bottom - rect.value.height
|
|
236
|
+
float.position.x = containerRect.value.right - rect.value.width
|
|
203
237
|
break
|
|
204
238
|
case 'left':
|
|
205
|
-
float.position.y =
|
|
206
|
-
|
|
239
|
+
float.position.y =
|
|
240
|
+
containerRect.value.top + (containerRect.value.height - rect.value.height) / 2
|
|
241
|
+
float.position.x = containerRect.value.left
|
|
207
242
|
break
|
|
208
243
|
case 'top-start':
|
|
209
244
|
case 'left-start':
|
|
210
|
-
float.position.y = containerRect.top
|
|
211
|
-
float.position.x = containerRect.left
|
|
245
|
+
float.position.y = containerRect.value.top
|
|
246
|
+
float.position.x = containerRect.value.left
|
|
212
247
|
break
|
|
213
248
|
case 'top':
|
|
214
|
-
float.position.y = containerRect.top
|
|
215
|
-
float.position.x =
|
|
249
|
+
float.position.y = containerRect.value.top
|
|
250
|
+
float.position.x =
|
|
251
|
+
containerRect.value.left + (containerRect.value.width - rect.value.width) / 2
|
|
216
252
|
break
|
|
217
253
|
case 'top-end':
|
|
218
254
|
case 'right-start':
|
|
219
|
-
float.position.y = containerRect.top
|
|
220
|
-
float.position.x = containerRect.right - rect.value.width
|
|
255
|
+
float.position.y = containerRect.value.top
|
|
256
|
+
float.position.x = containerRect.value.right - rect.value.width
|
|
221
257
|
case 'right':
|
|
222
|
-
float.position.y =
|
|
223
|
-
|
|
258
|
+
float.position.y =
|
|
259
|
+
containerRect.value.top + (containerRect.value.height - rect.value.height) / 2
|
|
260
|
+
float.position.x = containerRect.value.right - rect.value.width
|
|
224
261
|
break
|
|
225
262
|
default:
|
|
226
263
|
break
|
|
@@ -232,32 +269,40 @@ export const useFloating = (
|
|
|
232
269
|
float.position.x = realPos.x
|
|
233
270
|
float.position.y = realPos.y
|
|
234
271
|
|
|
235
|
-
if (realPos.x < containerRect.left) {
|
|
236
|
-
float.position.x = containerRect.left
|
|
272
|
+
if (realPos.x < containerRect.value.left) {
|
|
273
|
+
float.position.x = containerRect.value.left
|
|
237
274
|
translateX = 0
|
|
238
275
|
}
|
|
239
276
|
|
|
240
|
-
if (realPos.x + rect.value.width > containerRect.right) {
|
|
241
|
-
|
|
277
|
+
if (realPos.x + rect.value.width > containerRect.value.right) {
|
|
278
|
+
const fixVal = containerRect.value.right - rect.value.width
|
|
279
|
+
if (fixVal > 0) {
|
|
280
|
+
float.position.x = fixVal
|
|
281
|
+
}
|
|
242
282
|
translateX = 0
|
|
243
283
|
}
|
|
244
284
|
|
|
245
|
-
if (realPos.y < containerRect.top) {
|
|
246
|
-
float.position.y = containerRect.top
|
|
285
|
+
if (realPos.y < containerRect.value.top) {
|
|
286
|
+
float.position.y = containerRect.value.top
|
|
247
287
|
translateY = 0
|
|
248
288
|
}
|
|
249
289
|
|
|
250
|
-
if (realPos.y + rect.value.height > containerRect.bottom) {
|
|
251
|
-
|
|
290
|
+
if (realPos.y + rect.value.height > containerRect.value.bottom) {
|
|
291
|
+
const fixVal = containerRect.value.bottom - rect.value.height
|
|
292
|
+
if (fixVal > 0) {
|
|
293
|
+
float.position.y = fixVal
|
|
294
|
+
}
|
|
252
295
|
translateY = 0
|
|
253
296
|
}
|
|
254
297
|
|
|
255
298
|
safeElementDomRef.value.style.top = `${float.position.y}px`
|
|
256
299
|
safeElementDomRef.value.style.left = `${float.position.x}px`
|
|
257
|
-
|
|
300
|
+
safeElementDomRef.value.style.position = 'fixed'
|
|
258
301
|
safeElementDomRef.value.style.display = 'flex'
|
|
259
302
|
|
|
260
303
|
rect.value = safeElementDomRef.value.getBoundingClientRect()
|
|
304
|
+
|
|
305
|
+
args.callback && args.callback(rect, openerRect, containerRect, position, actualPosition)
|
|
261
306
|
})
|
|
262
307
|
|
|
263
308
|
onUnmounted(() => {
|
|
@@ -267,7 +312,10 @@ export const useFloating = (
|
|
|
267
312
|
return {
|
|
268
313
|
float,
|
|
269
314
|
rect,
|
|
270
|
-
|
|
271
|
-
|
|
315
|
+
setPosition,
|
|
316
|
+
position,
|
|
317
|
+
actualPosition,
|
|
318
|
+
openerRect,
|
|
319
|
+
containerRect
|
|
272
320
|
}
|
|
273
321
|
}
|