2021-11-27 10:29:23 +01:00
|
|
|
|
import { isScreenTouching } from '@/os';
|
2021-11-12 15:53:10 +01:00
|
|
|
|
import { Ref, ref } from 'vue';
|
2021-12-02 12:09:12 +01:00
|
|
|
|
import { isDeviceTouch } from './is-device-touch';
|
2021-11-12 15:53:10 +01:00
|
|
|
|
|
|
|
|
|
export function useTooltip(onShow: (showing: Ref<boolean>) => void) {
|
|
|
|
|
let isHovering = false;
|
|
|
|
|
let timeoutId: number;
|
|
|
|
|
|
|
|
|
|
let changeShowingState: (() => void) | null;
|
|
|
|
|
|
|
|
|
|
const open = () => {
|
|
|
|
|
close();
|
|
|
|
|
if (!isHovering) return;
|
|
|
|
|
|
2021-11-27 10:29:23 +01:00
|
|
|
|
// iOS(Androidも?)では、要素をタップした直後に(おせっかいで)mouseoverイベントを発火させたりするため、その対策
|
|
|
|
|
// これが無いと、画面に触れてないのにツールチップが出たりしてしまう
|
2021-12-02 12:09:12 +01:00
|
|
|
|
if (isDeviceTouch && !isScreenTouching) return;
|
2021-11-27 10:29:23 +01:00
|
|
|
|
|
2021-11-12 15:53:10 +01:00
|
|
|
|
const showing = ref(true);
|
|
|
|
|
onShow(showing);
|
|
|
|
|
changeShowingState = () => {
|
|
|
|
|
showing.value = false;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const close = () => {
|
|
|
|
|
if (changeShowingState != null) {
|
|
|
|
|
changeShowingState();
|
|
|
|
|
changeShowingState = null;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onMouseover = () => {
|
|
|
|
|
if (isHovering) return;
|
|
|
|
|
isHovering = true;
|
|
|
|
|
timeoutId = window.setTimeout(open, 300);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onMouseleave = () => {
|
|
|
|
|
if (!isHovering) return;
|
|
|
|
|
isHovering = false;
|
|
|
|
|
window.clearTimeout(timeoutId);
|
|
|
|
|
close();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
onMouseover,
|
|
|
|
|
onMouseleave,
|
|
|
|
|
};
|
|
|
|
|
}
|