"use client"; // 종목 페이지 공유 버튼 — 현재 URL 을 공유 / 클립보드에 복사. // Toss 의 종목 공유 패턴 (개별 모달 없이 즉시 시도 + 짧은 토스트). // // 동작 우선순위: // 1) navigator.share (모바일 native sheet — 성공 시 OS 시트가 피드백, 토스트 안 띄움) // 2) navigator.clipboard.writeText (HTTPS or localhost — 클립보드에 복사 + "링크 복사됨") // 3) document.execCommand("copy") (legacy, http LAN 등 secure context 아닌 경우) // 4) 모두 실패면 "복사 안됨" 안내 import { useEffect, useState } from "react"; type Props = { code: string; name?: string; }; async function copyToClipboard(text: string): Promise { // Modern path — secure context 에서만 사용 가능. if (typeof navigator !== "undefined" && navigator.clipboard?.writeText) { try { await navigator.clipboard.writeText(text); return true; } catch { // 권한 거부 등 — fallback 시도. } } // Legacy fallback. document.execCommand 는 deprecated 지만 비-HTTPS LAN 환경 호환용. if (typeof document === "undefined") return false; try { const ta = document.createElement("textarea"); ta.value = text; ta.setAttribute("readonly", ""); ta.style.position = "fixed"; ta.style.opacity = "0"; document.body.appendChild(ta); ta.select(); const ok = document.execCommand("copy"); document.body.removeChild(ta); return ok; } catch { return false; } } export function ShareButton({ code, name }: Props) { const [feedback, setFeedback] = useState(null); useEffect(() => { if (!feedback) return; const h = window.setTimeout(() => setFeedback(null), 2000); return () => window.clearTimeout(h); }, [feedback]); const onClick = async () => { if (typeof window === "undefined") return; const url = window.location.href; // Web Share API 우선 — 모바일에서 native sheet 뜸. 데스크탑/실패 시 클립보드로 폴백. const shareData = { title: name ? `${name} (${code})` : code, text: name ? `${name} 종목 정보` : code, url, }; if ( typeof navigator !== "undefined" && typeof navigator.share === "function" ) { try { await navigator.share(shareData); return; // 사용자가 native sheet 에서 처리. 토스트 안 띄움. } catch { // AbortError(사용자 취소) 또는 미지원 — 클립보드로 폴백. } } const ok = await copyToClipboard(url); setFeedback(ok ? "링크 복사됨" : "복사 안됨"); }; return (
{feedback && ( {feedback} )}
); }