Examples
Here are some examples featuring some of Mercury’s capabilites.
Basic Animation
<script lang="ts">
import { mercury } from '@omicrxn/mercury';
</script>
<div class="h-16 w-16 rounded-md bg-blue-300"
use:mercury={{
initial: { scale: 0.5 },
animate: { scale: 1.5 },
transition: { ease: 'circInOut', duration: 1 }
}}
></div>
Rotation Animation
<script lang="ts">
import { mercury } from '@omicrxn/mercury';
</script>
<div
class="h-16 w-16 rounded-md bg-blue-300"
use:mercury={{
animate: { rotate: 360 },
transition: { ease: 'circInOut', duration: 1 }
}}
></div>
Stagger Animation
<script lang="ts">
import { mercury } from '@omicrxn/mercury';
</script>
<div class="flex justify-center gap-2">
{#each { length: 5 }, i}
<div
class="h-16 w-16 rounded-md bg-blue-300"
use:mercury={{
initial: { y: 50, opacity: 0 },
animate: { y: 0, opacity: 1 },
transition: { delay: 0.05 * i }
}}
></div>
{/each}
</div>
Layout Animation
<script lang="ts">
import { mercury } from '@omicrxn/mercury';
let justify = $state('justify-start');
const onclick = () => {
justify = justify === 'justify-start' ? 'justify-end' : 'justify-start';
};
</script>
<div class="flex w-[120px] {justify} gap-2 rounded-full bg-blue-200 px-4 py-2" use:mercury layout>
<div {onclick} class="h-12 w-12 rounded-full bg-blue-300" use:mercury layout></div>
</div>
Exit Animation
<script lang="ts">
import Button from '$lib/components/ui/button/button.svelte';
import { animateExit, mercury } from '@omicrxn/mercury';
let show = true;
const onclick = () => {
show = !show;
};
</script>
<div class="flex flex-col gap-2">
{#if show}
<div
class="h-16 w-16 rounded-md bg-blue-300"
use:mercury={{ initial: { opacity: 0, y: -25 }, animate: { opacity: 1, y: 0 } }}
out:animateExit={{
animate: { opacity: 0, y: -25 },
transition: { duration: 0.3 }
}}
></div>
{/if}
<Button {onclick}>Hide</Button>
</div>
Loading Button
<script lang="ts">
import Button from '$lib/components/ui/button/button.svelte';
import { mercury, animateExit, ExitMode } from '@omicrxn/mercury';
import Loader from 'lucide-svelte/icons/loader';
import { type ComponentType } from 'svelte';
let buttonState = $state('idle');
interface ButtonCopy {
idle: string;
loading: ComponentType;
success: string;
}
const buttonCopy: ButtonCopy = {
idle: 'Send me a login link',
loading: Loader,
success: 'Login link sent!'
};
const handleClick = () => {
buttonState = 'loading';
setTimeout(() => {
buttonState = 'success';
}, 1750);
setTimeout(() => {
buttonState = 'idle';
}, 3500);
};
</script>
{#snippet spanContent(buttonState: string)}
{#if buttonState === 'loading'}
<Loader class="animate-spin" />
{:else}
{buttonCopy[buttonState]}
{/if}
{/snippet}
<Button class=" w-[148px]" disabled={buttonState !== 'idle'} onclick={handleClick}>
{#key buttonState}
<span
use:mercury={{ animate: { opacity: [0, 1], y: [-25, 0] }, transition: { duration: 0.3 } }}
out:animateExit={{
animate: { opacity: 0, y: 25 },
transition: { duration: 0.3 },
mode: ExitMode.POP_LAYOUT
}}
>
{@render spanContent(buttonState)}
</span>
{/key}
</Button>
Toolbar
<script lang="ts">
import { mercury } from '@omicrxn/mercury';
import type ToolbarItem from './toolbar-item';
import { Briefcase, FlaskConical, House, Library } from 'lucide-svelte';
import Button from '$lib/components/ui/button/button.svelte';
import getRandomTailwindColor from '$lib/utils/random-color';
import { Debounced } from 'runed';
let {
items = [
{ icon: House, title: 'Home', link: '/', color: '#f7d7f6' },
{ icon: Library, title: 'Libraries', link: '/libraries', color: '#fde58a' },
{ icon: Briefcase, title: 'Work', link: '/work', color: '#d9ceff' },
{ icon: FlaskConical, title: 'Alchemy', link: '/alchemy', color: '#b8fadd' }
]
}: { items?: ToolbarItem[] } = $props();
let hoveredIndex = $state(0);
const debouncedHoveredIndex = new Debounced(() => hoveredIndex, 120);
</script>
<div class="flex items-center justify-center gap-2 rounded-md border p-2" use:mercury layout="root">
{#each items as item, i}
<Button
class=" text-foreground"
style="background-color:{item.color}"
onmouseover={() => (hoveredIndex = i)}
>
<span use:mercury layout> <item.icon /></span>
{#if i === debouncedHoveredIndex.current}
<p use:mercury layout="title">
{item.title}
</p>
{/if}
</Button>
{/each}
</div>