From 8560e107bca9ec48b47df5863e2f0d9bf9658183 Mon Sep 17 00:00:00 2001 From: syuilo Date: Mon, 31 Jan 2022 21:07:33 +0900 Subject: enhance(client): Chartjsのツールチップを自前に MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/client/src/components/ui/tooltip.vue | 42 ++++++++++++++++++--------- 1 file changed, 28 insertions(+), 14 deletions(-) (limited to 'packages/client/src/components/ui') diff --git a/packages/client/src/components/ui/tooltip.vue b/packages/client/src/components/ui/tooltip.vue index e2721ed69a..1892877cc1 100644 --- a/packages/client/src/components/ui/tooltip.vue +++ b/packages/client/src/components/ui/tooltip.vue @@ -12,9 +12,11 @@ import * as os from '@/os'; const props = withDefaults(defineProps<{ showing: boolean; - source: HTMLElement; + targetElement?: HTMLElement; + x?: number; + y?: number; text?: string; - maxWidth?; number; + maxWidth?: number; }>(), { maxWidth: 250, }); @@ -29,13 +31,25 @@ const zIndex = os.claimZIndex('high'); const setPosition = () => { if (el.value == null) return; - const rect = props.source.getBoundingClientRect(); - const contentWidth = el.value.offsetWidth; const contentHeight = el.value.offsetHeight; - let left = rect.left + window.pageXOffset + (props.source.offsetWidth / 2); - let top = rect.top + window.pageYOffset - contentHeight; + let left: number; + let top: number; + + let rect: DOMRect; + + if (props.targetElement) { + rect = props.targetElement.getBoundingClientRect(); + + left = rect.left + window.pageXOffset + (props.targetElement.offsetWidth / 2); + top = rect.top + window.pageYOffset - contentHeight; + + el.value.style.transformOrigin = 'center bottom'; + } else { + left = props.x; + top = props.y - contentHeight; + } left -= (el.value.offsetWidth / 2); @@ -43,9 +57,14 @@ const setPosition = () => { left = window.innerWidth - contentWidth + window.pageXOffset - 1; } + // ツールチップを上に向かって表示するスペースがなければ下に向かって出す if (top - window.pageYOffset < 0) { - top = rect.top + window.pageYOffset + props.source.offsetHeight; - el.value.style.transformOrigin = 'center top'; + if (props.targetElement) { + top = rect.top + window.pageYOffset + props.targetElement.offsetHeight; + el.value.style.transformOrigin = 'center top'; + } else { + top = props.y; + } } el.value.style.left = left + 'px'; @@ -54,11 +73,6 @@ const setPosition = () => { onMounted(() => { nextTick(() => { - if (props.source == null) { - emit('closed'); - return; - } - setPosition(); let loopHandler; @@ -101,6 +115,6 @@ onMounted(() => { border-radius: 4px; border: solid 0.5px var(--divider); pointer-events: none; - transform-origin: center bottom; + transform-origin: center center; } -- cgit v1.2.3-freya