Skip to main content
Glama
ContentSelector.svelte3.13 kB
<script lang="ts"> import { onDestroy, onMount } from 'svelte'; // Props // biome-ignore lint/style/useConst: Svelte props need let export let onClickOutside: (() => void) | undefined = undefined; // biome-ignore lint/style/useConst: Svelte props need let export let pressDuration = 250; // biome-ignore lint/style/useConst: Svelte props need let export let isSelecting = false; // Event props // biome-ignore lint/style/useConst: Svelte props need let export let onPress: (() => void) | undefined = undefined; // biome-ignore lint/style/useConst: Svelte props need let export let onUnhover: (() => void) | undefined = undefined; // biome-ignore lint/style/useConst: Svelte props need let export let onHover: (() => void) | undefined = undefined; // biome-ignore lint/style/useConst: Svelte props need let export let onClick: ((event: MouseEvent) => void) | undefined = undefined; // biome-ignore lint/style/useConst: don't transform to const let containerRef: HTMLElement | null = null; let isHovered = false; let isSelectingState = isSelecting; let pressTimerRef: ReturnType<typeof setTimeout> | null = null; $: currentIsSelecting = isSelecting || isSelectingState; const handleOnLongPress = () => { isSelectingState = true; onPress?.(); }; const startPressTimer = () => { pressTimerRef = setTimeout(() => { handleOnLongPress(); }, pressDuration); }; const clearPressTimer = () => { if (pressTimerRef) { clearTimeout(pressTimerRef); pressTimerRef = null; } }; const handleMouseDown = () => { clearPressTimer(); startPressTimer(); }; const handleMouseUp = () => { if (isHovered) { isHovered = false; onUnhover?.(); } clearPressTimer(); }; const handleMouseLeave = () => { if (isHovered) { isHovered = false; onUnhover?.(); } clearPressTimer(); }; const handleClickOutside = (event: MouseEvent) => { if (containerRef && !containerRef.contains(event.target as Node)) { isSelectingState = false; if (onClickOutside) onClickOutside(); } }; const handleClick = (e: MouseEvent) => { if (currentIsSelecting) { e.preventDefault(); e.stopPropagation(); } else { onClick?.(e); } }; onMount(() => { document.addEventListener('mousedown', handleClickOutside); }); onDestroy(() => { if (typeof document !== 'undefined') { document.removeEventListener('mousedown', handleClickOutside); } clearPressTimer(); }); </script> <span bind:this={containerRef} role="button" tabindex="0" onclick={handleClick} onkeydown={() => {}} onmousedown={handleMouseDown} onmouseup={handleMouseUp} onmouseleave={handleMouseLeave} ontouchstart={handleMouseDown} ontouchend={handleMouseUp} ontouchcancel={handleMouseLeave} onmouseenter={() => { isHovered = true; onHover?.(); }} style={`display: inline-block; cursor: pointer; user-select: none; border-radius: 0.375rem; outline-width: 2px; outline-offset: 4px; outline-style: solid; outline-color: ${currentIsSelecting || isHovered ? 'inherit' : 'transparent'}; transition: all 100ms 50ms ease-in-out; `} > <slot /> </span>

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aymericzip/intlayer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server