Packages
moon
2.87.7
2.90.5
retired
2.90.4
2.90.3
2.90.2
2.90.1
2.90.0
2.89.4
2.89.1
2.89.0
2.88.0
2.87.11
2.87.10
2.87.9
2.87.8
2.87.7
2.87.6
2.87.5
2.87.4
2.87.3
2.87.2
2.87.1
2.87.0
2.86.1
2.86.0
2.85.1
2.85.0
2.84.0
2.83.0
2.82.0
2.81.4
2.81.3
2.81.2
2.81.1
2.81.0
2.80.2
2.80.1
2.80.0
2.79.13
2.79.12
2.79.11
2.79.10
2.79.9
2.79.8
2.79.7
2.79.6
2.79.5
2.79.4
2.79.3
2.79.2
2.79.1
2.79.0
2.78.4
2.78.3
2.78.2
2.78.1
2.78.0
2.77.0
2.76.5
2.76.4
2.76.3
2.76.2
2.76.1
2.76.0
2.75.0
2.74.1
2.74.0
2.73.8
2.73.7
2.73.6
2.73.5
2.73.4
2.73.3
2.73.2
2.73.1
2.73.0
2.72.5
2.72.4
2.72.3
2.72.2
2.72.1
2.72.0
2.71.1
2.71.0
2.70.0
2.69.2
2.69.1
2.69.0
2.68.11
2.68.10
Components-based design system written in elixir
Current section
Files
Jump to
Current section
Files
lib/moon/components/tooltip.ex
defmodule Moon.Components.Tooltip do
@moduledoc false
use Moon.StatelessComponent
prop(clicked_text, :string, default: nil)
prop(text, :string, required: true)
prop(placement, :string,
values: ["top", "right", "bottom", "left"],
required: true
)
slot(default, required: true)
# TODO:
# Right now the tooltip does not align properly for "left" and "right" placements.
# we need to figure out another way to position it properly.
def render(assigns) do
~F"""
<div class="relative inline-block" x-data="{ tooltip: false, timeout: null, clicked: false}">
{#case @placement}
{#match "top"}
<div x-cloak x-show="tooltip" class="absolute left-0 top-0 right-0 flex flex-col items-center">
<div class="-translate-y-full">
<div x-show="!clicked" class="w-48 p-4 text-moon-14 text-center bg-goku shadow rounded">
{@text}
</div>
<div x-show="clicked" class="w-48 p-4 text-moon-14 text-center bg-goku shadow rounded">
{@clicked_text || @text}
</div>
<div class="w-full overflow-hidden">
<div class="h-3 w-3 mx-auto bg-goku -rotate-45 -translate-y-1/2 shadow" />
</div>
</div>
</div>
{#match "right"}
<div x-cloak x-show="tooltip" class="absolute left-0 top-0 right-0">
<div class="flex items-center translate-x-full -translate-y-1/4">
<div class="p-1 overflow-hidden">
<div class="h-4 w-4 bg-goku -rotate-45 translate-x-1/2 shadow" />
</div>
<div x-show="!clicked" class="w-48 p-4 text-moon-14 text-center bg-goku shadow rounded">
{@text}
</div>
<div x-show="clicked" class="w-48 p-4 text-moon-14 text-center bg-goku shadow rounded">
{@clicked_text || @text}
</div>
</div>
</div>
{#match "bottom"}
<div x-cloak x-show="tooltip" class="absolute left-0 bottom-0 right-0 flex flex-col items-center">
<div class="translate-y-full">
<div class="w-full overflow-hidden">
<div class="h-3 w-3 mx-auto bg-goku -rotate-45 translate-y-1/2 shadow" />
</div>
<div x-show="!clicked" class="w-48 p-4 text-moon-14 text-center bg-goku shadow rounded">
{@text}
</div>
<div x-show="clicked" class="w-48 p-4 text-moon-14 text-center bg-goku shadow rounded">
{@clicked_text || @text}
</div>
</div>
</div>
{#match "left"}
<div x-cloak x-show="tooltip" class="absolute left-0 bottom-0 right-0">
<div class="absolute -translate-x-full -translate-y-full">
<div class="flex items-center top-0 right-0">
<div x-show="!clicked" class="w-48 p-4 text-moon-14 text-center bg-goku shadow rounded">
{@text}
</div>
<div x-show="clicked" class="w-48 p-4 text-moon-14 text-center bg-goku shadow rounded">
{@clicked_text || @text}
</div>
<div class="py-1 overflow-hidden">
<div class="h-3 w-3 bg-goku -rotate-45 -translate-x-1/2 shadow" />
</div>
</div>
</div>
</div>
{/case}
<div
class="inline-block"
x-on:mouseover="!!timeout && clearTimeout(timeout)
timeout = setTimeout(() => {
tooltip = true
}, 500)"
x-on:mouseleave="!!timeout && clearTimeout(timeout)
timeout = null
tooltip = false
clicked = false"
x-on:click="clicked = true"
>
<#slot />
</div>
</div>
"""
end
end