כפתור העתקה

navigator.clipboard עובד רק בהקשר מאובטח, ובתוך iframe הוא נחסם גם שם. הנפילה לשדה זמני היא לא שריד לדפדפנים ישנים אלא מה שמציל את הרכיב בדיוק במצבים האלה. ההודעה לקורא מסך יושבת באזור aria-live נפרד, אחרת שינוי הטקסט בכפתור לא מוכרז. כפתור העתקה הוא רכיב מתוך רכיבים של כליקס. מה שמורידים הוא רכיב שלם, גם כ-HTML עצמאי וגם כרכיב React. אין ספרייה חיצונית, אין שלב בנייה, ואם כליקס ייעלם מחר הקוד ימשיך לעבוד.

רכיב · ממשק · נגישות · בלי ספריות

<!-- כפתור העתקה — הטקסט להעתקה יושב ב-data-copy -->
<style>
  .klix-copy { display: inline-flex; align-items: center; gap: .5rem;
    font: inherit; font-weight: 700; padding: .55rem 1rem; border: 0; border-radius: .8rem;
    background: #1e293b; color: #e2e8f0; cursor: pointer }
  .klix-copy[data-done="1"] { background: #065f46; color: #d1fae5 }
  .klix-sr { position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap }
</style>

<button class="klix-copy" type="button" data-copy="050-1234567">
  <span aria-hidden="true">⧉</span><span class="klix-copy-label">העתקת הטלפון</span>
</button>
<span class="klix-sr" id="klix-copy-status" role="status" aria-live="polite"></span>

<script>
(function () {
  var status = document.getElementById('klix-copy-status');

  function fallback(text) {
    // הקשר לא מאובטח, או שההרשאה נדחתה — שדה זמני עדיין עובד
    var ta = document.createElement('textarea');
    ta.value = text;
    ta.style.position = 'fixed';
    ta.style.opacity = '0';
    document.body.appendChild(ta);
    ta.select();
    try { document.execCommand('copy'); } catch (e) {}
    ta.remove();
    return Promise.resolve();
  }

  function write(text) {
    if (navigator.clipboard && window.isSecureContext) {
      // writeText נדחה גם כשהמסמך לא במיקוד. בלי catch המשתמש לא מקבל כלום
      return navigator.clipboard.writeText(text).catch(function () { return fallback(text); });
    }
    return fallback(text);
  }

  document.querySelectorAll('.klix-copy').forEach(function (btn) {
    var label = btn.querySelector('.klix-copy-label');
    var original = label ? label.textContent : '';

    btn.addEventListener('click', function () {
      write(btn.getAttribute('data-copy') || '').then(function () {
        btn.setAttribute('data-done', '1');
        if (label) label.textContent = 'הועתק';
        if (status) status.textContent = 'הועתק ללוח';
        setTimeout(function () {
          btn.removeAttribute('data-done');
          if (label) label.textContent = original;
          if (status) status.textContent = '';
        }, 2000);
      });
    });
  });
})();
</script>