2023-08-05 20:33:07 +02:00
|
|
|
<script>
|
|
|
|
import { onDestroy } from 'svelte'
|
|
|
|
import ClipboardIcon from '~icons/mingcute/copy-2-line'
|
|
|
|
|
|
|
|
/** @type {string} */
|
|
|
|
export let command
|
|
|
|
/** @type {string} */
|
|
|
|
export let image
|
|
|
|
/** @type {string} */
|
|
|
|
export let name
|
|
|
|
|
|
|
|
let isShowingCopied = false
|
|
|
|
let timeoutId
|
|
|
|
|
|
|
|
async function copyCommand() {
|
|
|
|
await navigator.clipboard.writeText(command).then(() => (isShowingCopied = true))
|
|
|
|
clearTimeout(timeoutId)
|
|
|
|
timeoutId = setTimeout(() => (isShowingCopied = false), 1400)
|
|
|
|
}
|
|
|
|
|
|
|
|
onDestroy(() => {
|
|
|
|
clearTimeout(timeoutId)
|
|
|
|
})
|
|
|
|
</script>
|
|
|
|
|
2023-08-17 16:45:47 +02:00
|
|
|
<div class="flex group flex-col md:flex-row md:gap-4 gap-2 items-center">
|
2023-08-05 20:33:07 +02:00
|
|
|
<div
|
2023-08-17 16:45:47 +02:00
|
|
|
class="flex group-focus-within:-translate-y-1 transition-transform flex-col gap-3 justify-center items-center text-primary text-lg font-medium rounded-full w-32 h-32"
|
2023-08-05 20:33:07 +02:00
|
|
|
>
|
|
|
|
<img src={image} alt="Arch Logo" />{name}
|
|
|
|
</div>
|
|
|
|
|
2023-08-07 19:59:22 +02:00
|
|
|
<div class="flex flex-col relative font-mono mb-2">
|
2023-08-05 20:33:07 +02:00
|
|
|
<button
|
2023-08-17 16:45:47 +02:00
|
|
|
class="flex text-base transition-transform min-w-[18rem] items-center font-medium rounded-full border-primary border py-3 pl-6 pr-6 gap-4 justify-center active:scale-[1.01]"
|
2023-08-05 20:33:07 +02:00
|
|
|
on:click={$$slots.default ? undefined : copyCommand}
|
|
|
|
>
|
|
|
|
<slot>
|
|
|
|
<div class="flex gap-4 relative justify-between w-full">
|
|
|
|
<div class="flex gap-4">
|
|
|
|
<div class="text-primary select-none font-bold">></div>
|
|
|
|
<span>{command}</span>
|
|
|
|
</div>
|
|
|
|
<ClipboardIcon
|
2023-08-17 16:45:47 +02:00
|
|
|
class="group-hover:opacity-80 text-white group-active:opacity-100 opacity-0 w-6 h-6 hover:!opacity-100 transition-opacity duration-100"
|
2023-08-05 20:33:07 +02:00
|
|
|
/>
|
2023-08-17 16:45:47 +02:00
|
|
|
</div>
|
|
|
|
</slot>
|
2023-08-05 20:33:07 +02:00
|
|
|
</button>
|
2023-08-07 19:59:22 +02:00
|
|
|
|
2023-08-05 20:33:07 +02:00
|
|
|
<div
|
2023-08-17 16:45:47 +02:00
|
|
|
class="text-green-400 [translate:-50%_0px] select-none pointer-events-none absolute md:-top-8 max-md:-bottom-6 bg-black/10 backdrop-blur rounded-full z-20 px-2 w-full left-1/2 hidden max-w-max"
|
2023-08-05 20:33:07 +02:00
|
|
|
class:copy={isShowingCopied}
|
|
|
|
>
|
|
|
|
Copied to clipboard ✔
|
|
|
|
</div>
|
2023-08-07 19:59:22 +02:00
|
|
|
|
2023-08-05 20:33:07 +02:00
|
|
|
{#if $$slots.extra}
|
|
|
|
<div class="text-xs font-sans opacity-80 absolute -bottom-6 w-full flex justify-center">
|
|
|
|
<slot name="extra" />
|
|
|
|
</div>
|
|
|
|
{/if}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<style lang="postcss">
|
|
|
|
.copy {
|
|
|
|
animation: 80ms cubic-bezier(0.5, 0.2, 0, 1.5) 1 copy;
|
|
|
|
display: block;
|
|
|
|
}
|
|
|
|
|
|
|
|
@keyframes copy {
|
|
|
|
from {
|
|
|
|
opacity: 0.8;
|
|
|
|
scale: 0.98;
|
|
|
|
}
|
|
|
|
to {
|
|
|
|
opacity: 1;
|
|
|
|
scale: 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|