خطاف رد فعل صغير لتحويل العناصر إلى أسطح محتوى قابلة للتحرير وقابلة للتحرير بالكامل ، مثل محرري التعليمات البرمجية ، باستخدام محتوى (والسحر)
useEditable هو خطاف صغير يتيح أن تكون العناصر contenteditable مع الاستمرار في تقديمها بالكامل. هذا مثالي لإنشاء محررين رمز صغير أو نص نثر في 2kB فقط!
يهدف إلى السماح لأي عنصر أن يكون قابلاً للتحرير مع الاستمرار في تقديم عناصر رد فعل عادية - لا يوجد innerHTML والاضطرار إلى التعامل مع العمل مع HTML الخام أو تقديمه ، أو بدء مشروع محرر كامل من نقطة الصفر.
تحقق من العرض التوضيحي الكامل على codesandbox مع prism-react-renderer !
قم بتثبيت use-editable أولاً إلى جانب react :
yarn add use-editable
# or
npm install --save use-editable ستتمكن بعد ذلك من استيراد useEditable وتمريره مرجع HTMLElement ومعالج onChange .
import React , { useState , useRef } from 'react' ;
import { useEditable } from 'use-editable' ;
const RainbowCode = ( ) => {
const [ code , setCode ] = useState ( 'function test() {}nconsole.log("hello");' ) ;
const editorRef = useRef ( null ) ;
useEditable ( editorRef , setCode ) ;
return (
< div className = "App" >
< pre
style = { { whiteSpace : 'pre-wrap' , fontFamily : 'monospace' } }
ref = { editorRef }
>
{ code . split ( / r?n / ) . map ( ( content , i , arr ) => (
< React . Fragment key = { i } >
< span style = { { color : `hsl( ${ ( ( i % 20 ) * 17 ) | 0 } , 80%, 50%)` } } >
{ content }
</ span >
{ i < arr . length - 1 ? 'n' : null }
</ React . Fragment >
) ) }
</ pre >
</ div >
) ;
} ; ومثل هذا ، قمنا بتوصيل useEditable editorRef ، والذي يشير إلى العنصر <pre> الذي يتم تقديمه ، وإلى setCode الذي يدفع حالتنا التي تحتوي على بعض التعليمات البرمجية.
تم اختبار هذه المكتبة ضد وينبغي أن تعمل بشكل صحيح باستخدام:
هناك مشكلات معروفة في IE 11 نظرًا لطريقة MutationObserver غير قادرة على قراءة العقد النصية التي تمت إزالتها عبر contenteditable .
تقليديًا ، كان هناك ثلاثة خيارات عند اختيار أسطح التحرير في React. يمكن للمرء أن يذهب لمشروع كبير مثل Prosemirror / codemirror أو ما شابه ذلك يتحكم في جزء كبير من أحداث التحرير وتقديمه ، وبالتالي فهو مُلاحظ إلى حد ما ، أو أنه من الممكن مجرد استخدام contenteditable وتقديمه إلى HTML الخام الذي يتم استبداله في محتوى العنصر ، أو يمكن للمرء أن يجمع بين textarea مع div تامة.
لا تسمح جميع الخيارات الثلاثة بتخصيص الكثير من التخصيص من حيث ما يتم تقديمه بالفعل أو وضع قيود غير معقولة على مدى سهولة عرض محتوى القابل للتحرير وإدارته.
إذن ما الذي يجعل العرض لعنصر contenteditable صعبًا جدًا؟
عادةً ما يكون هذا صعبًا لأنهم يقومون بتحرير DOM مباشرة. يؤدي هذا إلى الخلط بين معظم المكتبات المقدمة ، مثل React و Preact ، لأن DOMs الافتراضية الأساسية لم تعد متطابقة مع بنية DOM الفعلية. لمنع هذه المشكلة ، يخلق use-editable MutationObserver ، الذي يراقب جميع التغييرات التي يتم إجراؤها على العنصر contenteditable . قبل أن تقارير هذه التغييرات لتفاعلها ، تراجع كل التغييرات إلى DOM بحيث يرى React ما تتوقعه.
علاوة على ذلك ، فإنه يحافظ أيضًا على الموضع الحالي للسيارة ، والتحديد ، واستعادته بمجرد رد الفعل قد قام بتحديث DOM نفسه. هذه تقنية شائعة إلى حد ما للمحررين contenteditable ، ولكن إضافة MutationObserver هي ما يتيح use-editable للسماح لمكتبة عرض أخرى بتحديث محتوى العنصر.
في الوقت الحالي ، يجب أن يتطابق محتوى نص العناصر المقدمة في النهاية مع إدخال الرمز ، أو يجب أن يكون تطبيقك قادرًا على تحويل محتوى النص المقدم إلى ما تستخدمه كدولة. هذا هو قيود على كيفية عمل contenteditable ، لأنهم سيلتقطون محتوى DOM الفعلي فقط. نظرًا لأن use-editable لا يهدف إلى أن يكون مكونًا كاملاً يدير دورة العرض ، فليس من الضروري الاحتفاظ بأي حالة إضافية ، ولكنه لن ينقل نص DOM إلا إلى رد اتصال onChange .
باستخدام رد اتصال onChange ، ستحصل أيضًا على كائن Position يصف موضع المؤشر ، ورقم السطر الحالي ، ومحتويات السطر حتى حتى المؤشر ، وهو أمر مفيد للاضغالات التلقائية ، والتي يمكن بعد ذلك تطبيقها مع وظيفة update التي تستخدم العائدات useEditable لتحديث موضع المؤشر.
الوسيطة الأولى هي elementRef وتقبل كائن Ref من النوع RefObject<HTMLElement> الذي يشير إلى العنصر الذي يجب أن يصبح قابلاً للتحرير. يُسمح لهذا المرجع أن يكون null أو يتغير أثناء وقت تشغيل الخطاف. طالما أن التغييرات في المرجع يتم تشغيلها بواسطة React ، يجب أن يتصرف كل شيء كما هو متوقع.
الوسيطة الثانية هي onChange وتقبل رد الاتصال من النوع (text: string, pos: Position) => void الذي يسمى كلما يتغير محتوى contenteditable . يجب إعداد هذا بحيث سيؤدي إلى إرجاع محتويات العنصر.
text الذي يتلقاه onChange هو مجرد تمثيل نصي لمحتويات العنصر ، في حين أن Position الذي يتلقاه يحتوي على الموضع الحالي للمؤشر ، ورقم السطر (محترف الصفر) ، ومحتوى الخط الحالي حتى المؤشر ، وهو مفيد للضغط التلقائي.
الوسيطة الثالثة هي كائن options اختياري. هذا يقبل حاليًا خيارين لتغيير سلوك التحرير للخطاف:
disabled التحرير على التحرير من خلال إزالة السمة contentEditable منه مرة أخرى.indentation عدد من المساحات المعروضة للمسافة البادئة. يمكّن هذا أيضًا سلوك مفتاح Tab المحسّن ، والذي سيؤدي إلى الدفاع عن السطر الحالي أو الدنيوي للخط الحالي عند الاحتفاظ بالتحول (كن على علم بأن هذا سيجعل المحرر بمثابة فخ تركيز!) عندما يتم تعيين options.indentation useEditable
بالإضافة إلى ذلك ، يقوم الخطاف useEditable بإرجاع مقبض Edit مع عدة طرق ، كما هو موثق أدناه.
Edit.update(content: string): void
يحل محل المحتوى الكامل للتحرير أثناء تعديل موضع الأذن. سيؤدي ذلك إلى تحويل الكاريت بالفرق في الطول بين المحتوى الحالي والمحتوى الذي تم تمريره.
Edit.insert(append: string, offset?: number): void
إدراج نص جديد في موضع الذبابة أثناء حذف النص في نطاق الإزاحة (الذي يقبل الإزاحة السلبية). على سبيل المثال ، عندما يتم ضبط offset على -1 ، يتم حذف حرف واحد على يسار الإشعاع قبل إدخال أي نص جديد. عندما يتم ضبطه على 2 ثم يتم حذف حرفين على يمين الكاريت. يمكن أيضًا تعيين نص append على سلسلة فارغة لتطبيق عمليات الحذف فقط دون إدخال أي نص. عند تحديد أي نص ، يتم محوها أولاً ويتم تجاهل offset .
Edit.move(pos: number | { row: number; column: number }): void
هذا ينقل الكاريت إلى الموضع المحدد. قد يكون الموضع إما فهرس أحرف ( number ) أو إحداثيات تحدد row column بشكل منفصل.
Edit.getState(): { text: string; position: Position }
تتيح هذه الطريقة الحصول على الوضع الحالي للقابل للتحرير ، وهو نفس ما يتلقاه onChange . يكون هذا مفيدًا عند إضافة إجراءات التحرير المخصصة في معالج أسفل المفتاح أو عند تقليد onChange برمجيًا على خلاف ذلك ، بينما يتم تحديد القابل للتحرير.
react-live ، الذي عملت عليه كان لديه واحد من المحررين contenteditable في وقت مبكر. (ولكن مع تحديثات HTML الخام)react-simple-code-editor أول مكتبة (؟) تستخدم نصًا منقسمًا وتقديم تطبيق السطح ، والذي قدم كيف يجب أن تبدو واجهة برمجة تطبيقات التحرير اللطيفة.codejar على أفضل الحيل لإدارة الاختيارات ، على الرغم من أنه يفتقر إلى بعض الحلول الفايرفوكس. كما أنه يستخدم تمييز / تحديث HTML الخام.codemirror.next هو مصدر لا يقدر بثمن لرؤية تقنيات مختلفة عند التعامل مع إدخال النص وحيل DOM. مستقر: لا يخطط هائلة لتطوير أي ميزات جديدة لهذا المشروع. ما زلنا نستجيب لتقارير الأخطاء والمخاوف الأمنية. ما زلنا نرحب بـ PRS لهذا المشروع ، ولكن يجب أن تكون PRS التي تتضمن ميزات جديدة صغيرة وسهلة الاندماج ويجب ألا تتضمن كسر التغييرات.