flotilla/src/lib/components/EmojiButton.svelte

46 lines
1.3 KiB
Svelte
Raw Normal View History

2024-10-23 23:16:28 +00:00
<script lang="ts">
import type {NativeEmoji} from "emoji-picker-element/shared"
2024-12-12 00:59:16 +00:00
import {between, throttle} from "@welshman/lib"
2026-08-29 17:20:39 +00:00
import type {Maybe} from "@welshman/lib"
2024-10-23 23:16:28 +00:00
import Button from "@lib/components/Button.svelte"
import Tippy from "@lib/components/Tippy.svelte"
2026-08-29 17:20:39 +00:00
import type {TippyController} from "@lib/components/Tippy.svelte"
2024-10-23 23:16:28 +00:00
import EmojiPicker from "@lib/components/EmojiPicker.svelte"
2026-01-29 18:56:44 +00:00
const {tippyParams = {}, ...props} = $props()
2024-10-23 23:16:28 +00:00
2026-08-29 17:20:39 +00:00
const open = () => tippy?.show()
2024-10-23 23:16:28 +00:00
const onClick = (emoji: NativeEmoji) => {
2025-02-04 00:37:14 +00:00
props.onEmoji(emoji)
2026-08-29 17:20:39 +00:00
tippy?.hide()
2026-07-28 00:13:14 +00:00
}
const onMouseMove = throttle(300, ({clientX, clientY}: MouseEvent) => {
2026-08-29 17:20:39 +00:00
const rect = tippy?.rect()
if (rect) {
const {x, y, width, height} = rect
2024-10-23 23:16:28 +00:00
2025-07-04 13:22:19 +00:00
if (!between([x, x + width], clientX) || !between([y - 100, y + height + 100], clientY)) {
2026-08-29 17:20:39 +00:00
tippy!.hide()
2024-10-24 18:52:02 +00:00
}
2024-10-23 23:16:28 +00:00
}
})
2026-08-29 17:20:39 +00:00
let tippy: Maybe<TippyController> = $state()
2024-10-23 23:16:28 +00:00
</script>
2026-08-29 17:20:39 +00:00
<svelte:document onmousemove={tippy?.visible ? onMouseMove : undefined} />
2024-10-23 23:16:28 +00:00
<Button onclick={open} class={props.class}>
<Tippy
2026-08-29 17:20:39 +00:00
bind:controller={tippy}
class="flex"
component={EmojiPicker}
props={{onClick}}
2026-08-29 17:20:39 +00:00
params={{trigger: "manual", interactive: true, ...tippyParams}}>
2025-02-04 00:37:14 +00:00
{@render props.children?.()}
</Tippy>
</Button>