at main 2.1 kB view raw
1<script lang="ts"> 2 interface Props { 3 url: string; 4 title?: string; 5 } 6 7 let { url, title = 'share' }: Props = $props(); 8 9 let showCopied = $state(false); 10 11 async function copyLink() { 12 try { 13 await navigator.clipboard.writeText(url); 14 showCopied = true; 15 setTimeout(() => { 16 showCopied = false; 17 }, 2000); 18 } catch (err) { 19 console.error('failed to copy:', err); 20 } 21 } 22</script> 23 24<button class="share-btn" onclick={copyLink} {title}> 25 <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> 26 <circle cx="18" cy="5" r="3"></circle> 27 <circle cx="6" cy="12" r="3"></circle> 28 <circle cx="18" cy="19" r="3"></circle> 29 <line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line> 30 <line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line> 31 </svg> 32 {#if showCopied} 33 <span class="copied">copied!</span> 34 {/if} 35</button> 36 37<style> 38 .share-btn { 39 background: var(--glass-btn-bg, transparent); 40 border: 1px solid var(--glass-btn-border, var(--border-default)); 41 border-radius: var(--radius-base); 42 width: 32px; 43 height: 32px; 44 padding: 0; 45 color: var(--text-tertiary); 46 cursor: pointer; 47 display: flex; 48 align-items: center; 49 justify-content: center; 50 gap: 0.5rem; 51 transition: all 0.2s; 52 position: relative; 53 } 54 55 .share-btn:hover { 56 background: var(--glass-btn-bg-hover, transparent); 57 border-color: var(--accent); 58 color: var(--accent); 59 } 60 61 .copied { 62 position: absolute; 63 top: -2rem; 64 left: 50%; 65 transform: translateX(-50%); 66 background: var(--bg-tertiary); 67 border: 1px solid var(--accent); 68 color: var(--accent); 69 padding: 0.25rem 0.75rem; 70 border-radius: var(--radius-sm); 71 font-size: var(--text-xs); 72 white-space: nowrap; 73 pointer-events: none; 74 animation: fadeIn 0.2s ease-in; 75 } 76 77 @keyframes fadeIn { 78 from { 79 opacity: 0; 80 transform: translateX(-50%) translateY(-0.25rem); 81 } 82 to { 83 opacity: 1; 84 transform: translateX(-50%) translateY(0); 85 } 86 } 87 88 @media (max-width: 768px) { 89 .share-btn { 90 width: 28px; 91 height: 28px; 92 } 93 94 .share-btn svg { 95 width: 14px; 96 height: 14px; 97 } 98 } 99</style>