Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tooltip]: adds arrow on tooltip default mode #457

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/floating/floating.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
}
</script>

<div bind:this={floating} class="leo-floating">
<div on:mouseenter on:mouseleave bind:this={floating} class="leo-floating">
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to expose these so I can control when the tooltip should close

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I feel like we should do this more!

<slot />
</div>

Expand Down
102 changes: 81 additions & 21 deletions src/components/tooltip/tooltip.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,21 @@
let arrow: HTMLElement
let trigger: HTMLElement

let arrowPlacement: string = undefined
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is used as a classname to style the arrow borders


function positionArrow(
e: CustomEvent<{ middlewareData: MiddlewareData; placement: Placement }>
) {
const { x: arrowX, y: arrowY } = e.detail.middlewareData.arrow

arrowPlacement = e.detail.placement.split('-')[0]

const staticSide = {
top: 'bottom',
right: 'left',
bottom: 'top',
left: 'right'
}[e.detail.placement.split('-')[0]]
}[arrowPlacement]

if (!arrow) return

Expand All @@ -54,6 +58,37 @@
})
}

let tooltipHovered = false
let triggerHovered = false

const handleMouseleave = (() => {
let timeout

return () => {
clearTimeout(timeout)
timeout = setTimeout(() => {
if (!triggerHovered && !tooltipHovered) {
setVisible(false)
}
}, 150)
}
})()

const handleTriggerMouseenter = () => {
triggerHovered = true
setVisible(true)
}

const handleTriggerMouseleave = () => {
triggerHovered = false
handleMouseleave()
}

const handleTooltipMouseleave = () => {
tooltipHovered = false
handleMouseleave()
}

function setVisible(newVisible: boolean) {
if (newVisible === visible) return

Expand All @@ -62,13 +97,7 @@
}
</script>

<div
class="leo-tooltip"
on:mouseenter={() => setVisible(true)}
on:mouseleave={() => setVisible(false)}
on:focusin={() => setVisible(true)}
on:focusout={() => setVisible(false)}
>
<div class="leo-tooltip">
{#key visibleInternal}
<Floating
target={trigger}
Expand All @@ -77,6 +106,8 @@
{placement}
{shift}
autoUpdate
on:mouseleave={handleTooltipMouseleave}
on:mouseenter={() => (tooltipHovered = true)}
middleware={[arrowMiddleware({ padding: 0, element: arrow })]}
on:computedposition={positionArrow}
>
Expand All @@ -93,16 +124,19 @@
<slot name="content">
{text}
</slot>
<div
class="arrow"
hidden={mode === 'default' || mode === 'mini'}
bind:this={arrow}
/>
<div class={`arrow ${arrowPlacement}`} bind:this={arrow} />
</div>
</Floating>
{/key}

<div class="trigger" bind:this={trigger}>
<div
on:focusin={() => setVisible(true)}
on:focusout={() => setVisible(false)}
on:mouseenter={handleTriggerMouseenter}
on:mouseleave={handleTriggerMouseleave}
class="trigger"
bind:this={trigger}
>
<slot />
</div>
</div>
Expand Down Expand Up @@ -131,13 +165,39 @@
font: var(--leo-font-primary-default-regular);
}

.leo-tooltip .tooltip .arrow {
position: absolute;
background: var(--background);
width: 8px;
height: 8px;
transform: rotate(45deg);
z-index: -1;
.leo-tooltip .tooltip {
& .arrow {
position: absolute;
background: var(--background);
width: 8px;
height: 8px;
transform: rotate(45deg);
z-index: -1;
}

&.default .arrow {
border: var(--border-width) solid var(--border-color);
z-index: 10;
&.left,
&.bottom {
border-bottom: 0;
}

&.right,
&.bottom {
border-right: 0;
}

&.right,
&.top {
border-top: 0;
}

&.left,
&.top {
border-left: 0;
}
}
}

.leo-tooltip .tooltip.hero {
Expand Down