mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-25 16:56:22 +02:00
55 lines
1.4 KiB
TypeScript
55 lines
1.4 KiB
TypeScript
import { type ClassValue, clsx } from "clsx";
|
|
import { twMerge } from "tailwind-merge";
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs));
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|