// refCell(index, recordType, id) โ†’ HTMLElement // // Renders a 1-based row number in a table cell. // Single click โ€” copies deep-link to clipboard and flashes "Copied!". // Double click โ€” opens deep-link in a new tab. // // Deep-link format: /data// // // Usage: // import {refCell} from "./components/ref-cell.js"; // // in an Inputs.table format callback: // format: { id: (_, i) => refCell(i + 1, "token-events", row.id) } const _STYLE_ID = "refcell-global-style"; if (!document.getElementById(_STYLE_ID)) { const s = document.createElement("style"); s.id = _STYLE_ID; s.textContent = ` .ref-cell { display: inline-block; font-family: var(--monospace, monospace); font-size: 0.78rem; color: var(--theme-foreground-focus, #3b82f6); cursor: pointer; user-select: none; padding: 0 2px; border-radius: 3px; transition: background 0.1s; } .ref-cell:hover { background: var(--theme-foreground-faint, #e8f0fe); } .ref-cell-toast { position: fixed; z-index: 10000; background: var(--theme-background, #fff); border: 1px solid var(--theme-foreground-faint, #ddd); border-radius: 6px; padding: 0.3rem 0.65rem; font-size: 0.75rem; color: var(--theme-foreground, #333); box-shadow: 0 4px 14px rgba(0,0,0,0.12); opacity: 0; transition: opacity 0.1s ease; pointer-events: none; } .ref-cell-toast.ref-cell-toast-visible { opacity: 1; } `; document.head.appendChild(s); } function _showToast(anchorEl, text) { const toast = document.createElement("div"); toast.className = "ref-cell-toast"; toast.textContent = text; document.body.appendChild(toast); const rect = anchorEl.getBoundingClientRect(); const gap = 6; toast.style.left = `${rect.left}px`; toast.style.top = `${rect.top - toast.offsetHeight - gap}px`; requestAnimationFrame(() => toast.classList.add("ref-cell-toast-visible")); setTimeout(() => { toast.classList.remove("ref-cell-toast-visible"); toast.addEventListener("transitionend", () => toast.remove(), {once: true}); }, 1200); } export function refCell(index, recordType, id) { const deepLink = `${location.origin}/${recordType}/${id}`; const el = document.createElement("span"); el.className = "ref-cell"; el.title = `Click to copy link ยท Double-click to open\n${deepLink}`; el.textContent = String(index); let clickTimer = null; el.addEventListener("click", (e) => { e.stopPropagation(); // Use a short delay so a double-click cancels the single-click handler. clickTimer = setTimeout(async () => { try { await navigator.clipboard.writeText(deepLink); _showToast(el, "Copied!"); } catch { // Fallback for environments where clipboard API is blocked. _showToast(el, deepLink); } }, 180); }); el.addEventListener("dblclick", (e) => { e.stopPropagation(); clearTimeout(clickTimer); window.open(deepLink, "_blank", "noopener,noreferrer"); }); return el; }