دراسة حالة · مفتوح المصدر

react-smart-copy

مكتبة React مفتوحة المصدر وبلا واجهة مفروضة لتفاعلات الحافظة. تصمم التفاعل الكامل حول النسخ (جارٍ النسخ، تم النسخ، فشل، إعادة المحاولة، واللصق) لتحصل الفرق على استجابة صادقة وعناصر تحكم متاحة وأخطاء مضبوطة الأنواع دون إعادة كتابة الشيفرة الهشة نفسها.

npm install react-smart-copy

إثبات المشروع

دوري

  • صممت الواجهة البرمجية ونموذج الحالات وعقد الإتاحة، وكتبت المكتبة بلغة TypeScript الصارمة.
  • كتبت التوثيق وجدول ما تستطيع المتصفحات نسخه وما لا تستطيع، والعرض الحي.
  • أنشر الحزمة على npm وأتولى صيانتها بترخيص MIT.

القيود

  • لم يكن للمكتبة أن تعد إلا بما تدعمه المتصفحات فعلًا، وأن تبلغ عن كل ما عداه كخطأ مضبوط النوع.
  • كان عليها أن تبقى بلا تنسيقات وأن تعمل مع Tailwind وCSS modules وCSS-in-JS ومكتبات المكونات.
  • كان عليها أن تكون آمنة مع العرض على الخادم وReact StrictMode وReact 18 و19.

القرارات الرئيسية

  • فصلت نواة مستقلة عن الإطار عن طبقة React لتعمل آلة الحالات نفسها في أي بيئة.
  • فصلت الحالة الفعلية عن حالة العرض لمنع الوميض وتغير الحجم.
  • دمجت الوصول بلوحة المفاتيح والأسماء الثابتة وإعلانات المنطقة الحية في المكونات افتراضيًا.
نوع المشروع
مكتبة React مفتوحة المصدر على npm
الدور
المؤلف والمشرف على الصيانة
التركيز الأساسي
الإتاحة والأخطاء المضبوطة وتجربة المطور
النطاق التقني
TypeScript وReact 18+ وClipboard API
  • مفتوح المصدر
  • React
  • TypeScript
  • Clipboard API
  • إمكانية الوصول
  • حزمة npm

السياق

تظهر أزرار النسخ في معظم المنتجات تقريبًا: مفاتيح API والمعرفات وعناوين البريد وروابط الدعوة وأمثلة الشيفرة. غالبًا ما تُكتب كاستدعاء واحد للحافظة مع رسالة "تم النسخ"، وتُعاد كتابتها في كل قاعدة شيفرة.

يخفي ذلك الاستدعاء معظم السلوك الحقيقي. ترفض المتصفحات الكتابة خارج HTTPS، وتمنعها عند انتقال التركيز، وتدعم بعض الصيغ فقط، وتبلغ عن الفشل بطرق غير متسقة. على الواجهة أن تشرح كل ذلك لمن ضغط الزر.

المشكلة

تفشل تطبيقات النسخ المعتادة بطرق لا يراها المستخدم ونادرًا ما تختبرها الفرق. كان الهدف مكتبة تتعامل مع النسخ كسلوك منتج بحالات محددة، لا كدالة مساعدة.

  • أخطاء مثل السياق غير الآمن أو رفض الإذن كثيرًا ما تمر بصمت دون أي أثر.
  • يستغرق النسخ بضع أجزاء من الثانية، فيظهر نص "جارٍ النسخ…" لإطار واحد ويتغير حجم الزر.
  • أزرار النسخ المخفية بـ display: none عند المرور لا يمكن الوصول إليها بلوحة المفاتيح.
  • نادرًا ما تُعلن النتيجة لمستخدمي قارئات الشاشة.
  • قد لا يتطابق العرض على الخادم عندما يقرأ المكون الحافظة أثناء العرض.

النهج

بُنيت المكتبة على طبقات. تضم نواة مستقلة عن الإطار آلة حالات للنسخ، والتحقق من المحتوى، ومحول حافظة المتصفح، وتصنيف الأخطاء. وتضيف طبقة React خطافات ومكون CopyField مركبًا فوق تلك النواة.

كل حالة صريحة وقابلة للمراقبة: idle وcopying وcopied وerror. وتفصل حالتان بين المنطق والعرض: تتغير الحالة الفعلية فورًا للمنطق والاختبارات، بينما لا تُظهر حالة العرض "جارٍ النسخ…" إلا عندما يكون النسخ بطيئًا ثم تبقيها مدة كافية لتجنب الوميض.

  • تنسخ النص وHTML الغني مع نص بديل إلزامي وصور PNG وJSON وعدة صيغ معًا.
  • تلصق النص وHTML ولقطات الشاشة عبر usePaste، واللصق بلوحة المفاتيح لا يطلب إذنًا.
  • ينسق CopyGroup الصفوف بحيث يظهر "تم النسخ" في صف واحد فقط في كل مرة.
  • تنسخ نقطة دخول الالتقاط عنصر SVG أو جزءًا من الواجهة كصورة PNG.
  • تتيح المحولات المخصصة لبيئات مثل Electron توفير حافظتها الخاصة.

قرارات إمكانية الوصول

قواعد الإتاحة جزء من المكونات نفسها، لا توثيقًا على الفريق تذكره. زر التشغيل دائمًا زر حقيقي، ويبقى اسمه المتاح ثابتًا بينما تُعلن النتيجة بشكل منفصل.

  • يمكن الوصول إلى الأزرار بمفتاح Tab وتفعيلها بمفتاح Enter أو المسافة.
  • تبقى الإجراءات المخفية في DOM وترتيب التنقل، وتُخفى بالشفافية وليس بـ display: none.
  • يثبت تركيز لوحة المفاتيح الإظهار، أما نقرة الفأرة فلا.
  • لا يُعطل الزر أثناء النسخ، فلا يضيع تركيز لوحة المفاتيح.
  • تُركب المنطقة الحية قبل رسالتها الأولى حتى لا يضيع الإعلان الأول.
  • تحترم الحركات تفضيل prefers-reduced-motion.

الأخطاء وSSR والحجم

كل فشل خطأ مصنف ومضبوط النوع مثل unsupported وinsecure-context وpermission-denied وnot-focused وunsupported-format وtoo-large، ويوضح كل منها هل تفيد إعادة المحاولة. لا شيء يفشل بصمت.

تأتي نقطة دخول React مع "use client" ولا تصل إلى window أثناء العرض، فيتطابق عرض الخادم وأول عرض للعميل في Next.js. لا تملك الحزمة اعتماديات وقت تشغيل، ويذكر README نحو 3.2 كيلوبايت لـ useCopy و5.4 كيلوبايت لكل ميزات النسخ بعد التصغير والضغط بـ Brotli.

النتائج

  • منشورة على npm باسم react-smart-copy بترخيص MIT، مع توثيق وعرض حي على GitHub Pages.
  • تدعم نسخ النص وHTML الغني وPNG وJSON والمحتوى متعدد الصيغ، ولصق النص وHTML والصور.
  • تستبدل فشل الحافظة الصامت بأخطاء مضبوطة الأنواع توضح هل تفيد إعادة المحاولة.
  • تعمل في هذه المحفظة عبر نواتها المستقلة عن الإطار لتشغيل أزرار النسخ دون تحميل React.

الخطوات التالية

  • اقرأ التوثيق وجرّب العرض الحي.
  • ثبّتها بالأمر npm install react-smart-copy.
  • أبلغ عن المشكلات أو ساهم على GitHub.