66 lines
1.3 KiB
JavaScript
66 lines
1.3 KiB
JavaScript
/**
|
|
* Clipboard Composable
|
|
* Handles clipboard operations with feedback
|
|
*/
|
|
|
|
import { ref } from 'vue';
|
|
|
|
/**
|
|
* Clipboard operations composable
|
|
* @returns {Object} Clipboard functions and state
|
|
*/
|
|
export function useClipboard() {
|
|
const copied = ref(false);
|
|
const error = ref(null);
|
|
|
|
/**
|
|
* Copy text to clipboard
|
|
* @param {string} text - Text to copy
|
|
* @returns {Promise<boolean>} Success status
|
|
*/
|
|
const copyToClipboard = async text => {
|
|
error.value = null;
|
|
copied.value = false;
|
|
|
|
try {
|
|
await navigator.clipboard.writeText(text);
|
|
copied.value = true;
|
|
|
|
// Reset after 2 seconds
|
|
setTimeout(() => {
|
|
copied.value = false;
|
|
}, 2000);
|
|
|
|
return true;
|
|
} catch (err) {
|
|
error.value = err.message;
|
|
console.error('Failed to copy to clipboard:', err);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Read text from clipboard
|
|
* @returns {Promise<string|null>} Clipboard text or null
|
|
*/
|
|
const readFromClipboard = async () => {
|
|
error.value = null;
|
|
|
|
try {
|
|
const text = await navigator.clipboard.readText();
|
|
return text;
|
|
} catch (err) {
|
|
error.value = err.message;
|
|
console.error('Failed to read from clipboard:', err);
|
|
return null;
|
|
}
|
|
};
|
|
|
|
return {
|
|
copied,
|
|
error,
|
|
copyToClipboard,
|
|
readFromClipboard
|
|
};
|
|
}
|