Spaces:
Running
Running
<script lang="ts"> | |
import { Container } from "threlte-uikit"; | |
interface Props { | |
minWidth?: number; | |
minHeight?: number; | |
color?: string; | |
opacity?: number; | |
borderOpacity?: number; | |
backgroundOpacity?: number; | |
disabled?: boolean; | |
clickable?: boolean; | |
children: import("svelte").Snippet; | |
onclick?: () => void; | |
} | |
let { | |
minWidth = 120, | |
minHeight = 100, | |
color = "rgb(139, 69, 219)", | |
opacity = 1, | |
borderOpacity = 0.6, | |
backgroundOpacity = 0.2, | |
disabled = false, | |
clickable = true, | |
onclick, | |
children | |
}: Props = $props(); | |
let isHovered = $state(false); | |
let hoverTimeout: ReturnType<typeof setTimeout>; | |
function handlePointerEnter() { | |
if (disabled) return; | |
clearTimeout(hoverTimeout); | |
hoverTimeout = setTimeout(() => { | |
isHovered = true; | |
}, 20); | |
} | |
function handlePointerLeave() { | |
clearTimeout(hoverTimeout); | |
hoverTimeout = setTimeout(() => { | |
isHovered = false; | |
}, 20); | |
} | |
function handleClick() { | |
if (disabled || !clickable) return; | |
onclick?.(); | |
} | |
let currentBorderOpacity = $derived(isHovered ? Math.min(borderOpacity * 1.5, 1) : borderOpacity); | |
let currentBackgroundOpacity = $derived( | |
isHovered ? Math.min(backgroundOpacity * 2, 0.5) : backgroundOpacity | |
); | |
</script> | |
<Container | |
{minWidth} | |
{minHeight} | |
borderRadius={12} | |
borderWidth={2} | |
borderColor={color} | |
borderOpacity={currentBorderOpacity} | |
backgroundColor={color} | |
backgroundOpacity={currentBackgroundOpacity} | |
padding={16} | |
pointerEvents="auto" | |
cursor={clickable && !disabled ? "pointer" : "default"} | |
{opacity} | |
onclick={handleClick} | |
onmousedown={handleClick} | |
onpointerenter={handlePointerEnter} | |
onpointerleave={handlePointerLeave} | |
> | |
<Container | |
flexDirection="column" | |
alignItems="center" | |
justifyContent="center" | |
gap={8} | |
width="100%" | |
height="100%" | |
> | |
{@render children()} | |
</Container> | |
</Container> | |