SurfSense/surfsense_web/lib/utils.ts

56 lines
1.4 KiB
TypeScript
Raw Normal View History

2025-07-27 10:05:37 -07:00
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
2025-04-07 23:47:06 -07:00
export function cn(...inputs: ClassValue[]) {
2025-07-27 10:05:37 -07:00
return twMerge(clsx(inputs));
2025-04-07 23:47:06 -07:00
}
2025-11-14 00:25:08 +02:00
2025-12-24 18:03:22 -08:00
export const formatDate = (date: Date): string => {
return date.toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "numeric",
});
};
/**
* Copy text to clipboard with fallback for older browsers and non-secure contexts.
* Returns true if successful, false otherwise.
*/
export async function copyToClipboard(text: string): Promise<boolean> {
// Use modern Clipboard API if available and in secure context
if (navigator.clipboard && window.isSecureContext) {
try {
await navigator.clipboard.writeText(text);
return true;
} catch (err) {
console.error("Clipboard API failed:", err);
return false;
}
}
// Fallback for non-secure contexts or browsers without Clipboard API
const textArea = document.createElement("textarea");
textArea.value = text;
// Avoid scrolling to bottom
textArea.style.top = "0";
textArea.style.left = "0";
textArea.style.position = "fixed";
textArea.style.opacity = "0";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
const successful = document.execCommand("copy");
document.body.removeChild(textArea);
return successful;
} catch (err) {
console.error("Fallback copy failed:", err);
document.body.removeChild(textArea);
return false;
}
}