Skip to content

useClipboard Hook - Guida Utilizzo ​

⚠️ [DEV-166] Documentazione obsoleta. L'API copy(text, context?) descritta in questo file non Γ¨ piΓΉ disponibile. Consultare lo Storybook di @elerama/ui β†’ sezione Hooks/useClipboard per la documentazione aggiornata. Vedere README.md per i dettagli della migrazione.


πŸ“‹ Descrizione (storica) ​

useClipboard() Γ¨ un hook React per copiare testo negli appunti con feedback visivo automatico e gestione dello stato.

File: app/hooks/useClipboard.ts

🎯 Caratteristiche ​

βœ… Hook React nativo - Integrazione perfetta con React components βœ… Stato automatico - Gestisce copied, error automaticamente βœ… Auto-reset - Resetta lo stato dopo timeout configurabile βœ… Clipboard API moderna - HTTPS ready βœ… Fallback automatico - Supporta HTTP e browser vecchi βœ… Error handling - Gestione completa degli errori βœ… TypeScript - Full type safety

πŸš€ Utilizzo Base ​

Componente Simple ​

typescript
import { useClipboard } from "@/hooks/utils/useClipboard";

export function CopyButton() {
  const { copy, copied } = useClipboard();

  const handleCopy = async () => {
    await copy("Testo da copiare", "CopyButton");
  };

  return (
    <button onClick={handleCopy}>
      {copied ? "βœ… Copiato!" : "πŸ“‹ Copia"}
    </button>
  );
}

Con Error Handling ​

typescript
import { useClipboard } from "@/hooks/utils/useClipboard";

export function AdvancedCopy() {
  const { copy, copied, error } = useClipboard(3000); // 3 secondi di timeout

  const handleCopy = async () => {
    const success = await copy("Testo", "AdvancedCopy");
    if (!success && error) {
      alert(`Errore: ${error}`);
    }
  };

  return (
    <div>
      <button onClick={handleCopy}>Copia</button>
      {copied && <span>βœ… Copiato negli appunti!</span>}
      {error && <span style={{color: 'red'}}>❌ {error}</span>}
    </div>
  );
}

πŸ“š Signature Hook ​

typescript
export function useClipboard(resetTimeMs = 2000) {
  // resetTimeMs: tempo (ms) prima di resettare lo stato 'copied'
  // Default: 2000ms (2 secondi)

  return {
    copy, // (text: string, context?: string) => Promise<boolean>
    copied, // boolean - true se il testo Γ¨ stato copiato
    error, // string | null - messaggio di errore (se presente)
  };
}

Parametri ​

ParametroTipoDefaultDescrizione
resetTimeMsnumber2000Millisecondi prima di resettare copied a false

Ritorno ​

ChiaveTipoDescrizione
copy(text, context?)async functionFunzione per copiare testo
copiedbooleantrue se ultimo copy Γ¨ riuscito
errorstring | nullMessaggio errore (se presente)

πŸ’‘ Esempi Pratici ​

1. Badge con Feedback ​

typescript
export function CopyWithBadge() {
  const { copy, copied } = useClipboard();

  return (
    <button onClick={() => copy("Code123")}>
      πŸ“‹ {copied ? "βœ…" : "Copy"}
    </button>
  );
}

2. Multi-Copy ​

typescript
export function MultiCopy() {
  const { copy, copied } = useClipboard(2000);

  return (
    <div>
      <button onClick={() => copy("Fastlabel", "fastlabel")}>
        Fastlabel {copied ? "βœ…" : ""}
      </button>
      <button onClick={() => copy("Offline", "offline")}>
        Offline {copied ? "βœ…" : ""}
      </button>
    </div>
  );
}

3. Con Loader ​

typescript
import { useState } from "react";
import { useClipboard } from "@/hooks/utils/useClipboard";

export function CopyWithLoader() {
  const { copy, copied, error } = useClipboard();
  const [loading, setLoading] = useState(false);

  const handleCopy = async () => {
    setLoading(true);
    await copy("Large text...", "loader");
    setLoading(false);
  };

  return (
    <button onClick={handleCopy} disabled={loading}>
      {loading ? "Copiando..." : copied ? "βœ… Copiato" : "πŸ“‹ Copia"}
    </button>
  );
}

4. Uso in Hook (useTopbarCart) ​

typescript
// Nel hook useTopbarCart
const { copy } = useClipboard();

const fastlabel = async () => {
  const fastlabelText = iframeWindow.fastlabel_response;
  const success = await copy(fastlabelText, 'useTopbarCart');
  if (success) {
    notifySuccess();
  }
};

πŸ” Debug e Logging ​

L'hook logga automaticamente nel console:

[useClipboard] βœ… Testo copiato negli appunti (Clipboard API)
[useClipboard] ⚠️ Clipboard API error: NotAllowedError
[useClipboard] βœ… Testo copiato negli appunti (legacy method)

πŸ› Troubleshooting ​

"Errore: Impossibile copiare negli appunti" ​

Cause comuni:

  • Mancanza di permessi clipboard (browser chiede primo accesso)
  • Ambiente non-HTTPS senza fallback disponibile
  • Browser non supportato (molto raro)

Soluzione:

typescript
const { copy, error } = useClipboard();

await copy('text');
if (error) {
  console.log(`Fallback usato: ${error}`);
}

Copy non funziona in iframe ​

Possibili cause:

  • CORS policy
  • Same-origin requirement

Test:

typescript
// Controlla se Γ¨ iframe
console.log(window !== window.parent);

State non si resetta ​

Soluzione: Aumenta il timeout

typescript
const { copy, copied } = useClipboard(5000); // 5 secondi

πŸ“– Riferimenti Tecnici ​


Versione: 2.0.0 (Hook React) Ultima Aggiornamento: 2025-10-21

if (success) { // Notificare all'iframe che la copia Γ¨ riuscita notifyClipboardSuccess(); } else { // Mostrare errore all'utente showError("Impossibile copiare negli appunti"); } }


## πŸ” Debug e Logging

La funzione registra automaticamente nel console:

[useTopbarCart] βœ… Testo copiato negli appunti (Clipboard API) [useTopbarCart] ⚠️ Clipboard API error: ... Trying legacy method... [useTopbarCart] βœ… Testo copiato negli appunti (legacy method) [useTopbarCart] ❌ Errore metodo legacy: ...


## 🧩 Componenti che Usano

- `useTopbarCart.ts` - Hook per il carrello della topbar
- `test-iframe.html` - Pagina di test iframe

## πŸ’‘ Note Tecniche

### Fallback Legacy (execCommand)

Il fallback utilizza `document.execCommand('copy')` che:
- βœ… Funziona in HTTP (non secure)
- βœ… Funziona in iframe cross-origin (con restrizioni)
- ⚠️ È deprecato ma ampiamente supportato
- ⚠️ Potrebbe non funzionare in alcuni browser ultra-moderni

### Permessi Richiesti

La Clipboard API richiede:
- HTTPS (in ambienti di produzione)
- Permesso dell'utente (mostrato dal browser al primo utilizzo)
- Stesso origin (non cross-domain)

Il fallback **non** richiede permessi espliciti.

## πŸ› Troubleshooting

### Errore: "navigator.clipboard is undefined"
β†’ La Clipboard API non Γ¨ disponibile, ma il fallback legacy funzionerΓ  automaticamente

### Errore: "Failed to copy text with legacy method"
β†’ Il browser potrebbe non supportare `execCommand('copy')`. Verifica che:
- Il testo Γ¨ valido (non null/undefined)
- Il browser Γ¨ supportato (IE 9+)
- Non stai operando in un worker thread

### Errore: "Clipboard is not available"
β†’ Potresti avere CORS issues. Il fallback dovrebbe funzionare comunque.

## πŸ“š Riferimenti

- [MDN - Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard_API)
- [MDN - document.execCommand](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand)

Documentazione Elerama Frontend