مكون Quill لـ React.
شاهد العرض التجريبي المباشر أو Codepen.
هذه هي الوثائق الخاصة بـ ReactQuill v2 — الإصدارات السابقة: v1
؟ رياكت كويل v2
ReactQuill 2 هنا يا عزيزي! كما أنه يوفر منفذًا كاملاً لـ TypeScript وReact 16+، ونظام إنشاء مُعاد هيكلته، وتشديدًا عامًا للمنطق الداخلي.
لقد عملنا بجد لتجنب إدخال أي تغييرات سلوكية. بالنسبة للغالبية العظمى من الحالات، لا توجد حاجة للهجرة على الإطلاق. ومع ذلك، تمت إزالة الدعم للدعائم التي تم إهمالها منذ فترة طويلة، وReactQuill Mixin، ومكون شريط الأدوات. تأكد من قراءة دليل الهجرة.
نتوقع أن يكون هذا الإصدار عبارة عن ترقية بسيطة - إذا لم يكن الأمر كذلك، فيرجى الإبلاغ عن مشكلة تتعلق بملصق v2
.
تأكد من أن لديك react
و react-dom
، وطريقة ما لتحميل الأنماط، مثل محمل النمط. راجع الوثائق الخاصة بالمواضيع لمزيد من المعلومات.
npm install react-quill --save
import React , { useState } from 'react' ;
import ReactQuill from 'react-quill' ;
import 'react-quill/dist/quill.snow.css' ;
function MyComponent ( ) {
const [ value , setValue ] = useState ( '' ) ;
return < ReactQuill theme = "snow" value = { value } onChange = { setValue } / > ;
}
< link
rel =" stylesheet "
href =" https://unpkg.com/[email protected]/dist/quill.snow.css "
/>
< script
src =" https://unpkg.com/react@16/umd/react.development.js "
crossorigin
> </ script >
< script
src =" https://unpkg.com/react-dom@16/umd/react-dom.development.js "
crossorigin
> </ script >
< script src =" https://unpkg.com/[email protected]/dist/react-quill.js " > </ script >
< script src =" https://unpkg.com/babel-standalone@6/babel.min.js " > </ script >
< script type =" text/babel " src =" /my-scripts.js " > </ script >
في الوضع المتحكم فيه، من المفترض أن تمنع المكونات تغييرات الحالة المحلية، وبدلاً من ذلك تحدث فقط من خلال onChange
و value
.
نظرًا لأن Quill يتعامل مع التغييرات الخاصة به، ولا يسمح بمنع التعديلات، يجب على ReactQuill أن يستقر على مزيج بين الوضع المتحكم فيه والوضع غير المتحكم فيه. لا يمكنه منع التغيير، لكنه سيستمر في تجاوز المحتوى عندما تختلف value
عن الحالة الحالية.
إذا كنت تحتاج بشكل متكرر إلى التعامل مع DOM أو استخدام Quill APIs بشكل حتمي، فقد تفكر في التبديل إلى الوضع غير المتحكم فيه بالكامل. سيقوم ReactQuill بتهيئة المحرر باستخدام defaultValue
، لكنه لن يحاول إعادة تعيينه بعد ذلك. سيظل رد الاتصال onChange
يعمل كما هو متوقع.
اقرأ المزيد حول المكونات غير المنضبطة في مستندات React.
يمكنك تمرير Quill Delta، بدلاً من سلسلة HTML، value
وخصائص defaultValue
. تتمتع دلتا بعدد من المزايا مقارنة بسلاسل HTML، لذا قد ترغب في استخدامها بدلاً من ذلك. ومع ذلك، عليك أن تدرك أن مقارنة دلتا للتغييرات أكثر تكلفة من مقارنة سلاسل HTML، لذلك قد يكون من المفيد تحديد أنماط الاستخدام الخاصة بك.
لاحظ أن تحويل value
من سلسلة HTML إلى سلسلة Delta، أو العكس، سيؤدي إلى حدوث تغيير، بغض النظر عما إذا كانت تمثل نفس المستند، لذلك قد ترغب في الالتزام بالتنسيق والاستمرار في استخدامه باستمرار طوال الوقت.
delta
الذي تتلقاه من حدث onChange
value
. لا يحتوي هذا الكائن على المستند الكامل، ولكن على التعديلات الأخيرة فقط، ومن المرجح أن يؤدي القيام بذلك إلى تشغيل حلقة لا نهائية حيث يتم تطبيق نفس التغييرات مرارًا وتكرارًا. استخدم editor.getContents()
أثناء الحدث للحصول على دلتا للمستند الكامل بدلاً من ذلك. سيمنعك ReactQuill من ارتكاب مثل هذا الخطأ، ولكن إذا كنت متأكدًا تمامًا من أن هذا هو ما تريده، فيمكنك تمرير الكائن عبر new Delta()
مرة أخرى لإزالة الشوائب عنه.
محرر Quill يدعم المواضيع. يتضمن سمة كاملة تسمى ثلج ، وهو المظهر القياسي لـ Quill، وسمة فقاعية مشابهة للمحرر المضمّن في Medium. على أقل تقدير، يجب تضمين السمة الأساسية حتى تعمل الوحدات النمطية مثل أشرطة الأدوات أو تلميحات الأدوات.
لتنشيط السمة، قم بتمرير اسم السمة إلى دعامة theme
. قم بتمرير قيمة خاطئة (على سبيل المثال. null
) لاستخدام السمة الأساسية.
< ReactQuill theme = "snow" . . . / >
ثم قم باستيراد ورقة الأنماط للموضوعات التي تريد استخدامها.
قد يختلف هذا اعتمادًا على كيفية تنظيم التطبيق أو الدلائل أو غير ذلك. على سبيل المثال، إذا كنت تستخدم معالجًا أوليًا لـ CSS مثل SASS، فقد ترغب في استيراد ورقة الأنماط هذه داخل ورقتك الخاصة. يمكن العثور على أوراق الأنماط هذه في توزيع Quill، ولكن من أجل الراحة يتم ربطها أيضًا في مجلد dist
الخاص بـ ReactQuill.
فيما يلي مثال على استخدام style-loader لـ Webpack، أو create-react-app
، الذي سيُدخل الأنماط في الصفحة تلقائيًا:
import 'react-quill/dist/quill.snow.css' ;
الأنماط متاحة أيضًا عبر CDN:
< link
rel =" stylesheet "
href =" https://unpkg.com/[email protected]/dist/quill.snow.css "
/>
توفر واجهة برمجة تطبيقات Quill Toolbar Module طريقة سهلة لتكوين أيقونات شريط الأدوات الافتراضية باستخدام مجموعة من أسماء التنسيقات.
class MyComponent extends Component {
constructor ( props ) {
super ( props ) ;
this . state = {
text : "" ,
}
}
modules = {
toolbar : [
[ { 'header' : [ 1 , 2 , false ] } ] ,
[ 'bold' , 'italic' , 'underline' , 'strike' , 'blockquote' ] ,
[ { 'list' : 'ordered' } , { 'list' : 'bullet' } , { 'indent' : '-1' } , { 'indent' : '+1' } ] ,
[ 'link' , 'image' ] ,
[ 'clean' ]
] ,
} ,
formats = [
'header' ,
'bold' , 'italic' , 'underline' , 'strike' , 'blockquote' ,
'list' , 'bullet' , 'indent' ,
'link' , 'image'
] ,
render ( ) {
return (
< div className = "text-editor" >
< ReactQuill theme = "snow"
modules = { this . modules }
formats = { this . formats } >
< / ReactQuill >
< / div >
) ;
}
}
export default MyComponent ;
يمكنك أيضًا تزويد شريط أدوات HTML/JSX الخاص بك بعناصر مخصصة ليست جزءًا من سمة Quill.
شاهد هذا المثال مباشرة على Codepen: مثال على شريط الأدوات المخصص
/*
* Custom "star" icon for the toolbar using an Octicon
* https://octicons.github.io
*/
const CustomButton = ( ) => < span className = "octicon octicon-star" / > ;
/*
* Event handler to be attached using Quill toolbar module
* http://quilljs.com/docs/modules/toolbar/
*/
function insertStar ( ) {
const cursorPosition = this . quill . getSelection ( ) . index ;
this . quill . insertText ( cursorPosition , '★' ) ;
this . quill . setSelection ( cursorPosition + 1 ) ;
}
/*
* Custom toolbar component including insertStar button and dropdowns
*/
const CustomToolbar = ( ) => (
< div id = "toolbar" >
< select
className = "ql-header"
defaultValue = { '' }
onChange = { ( e ) => e . persist ( ) }
>
< option value = "1" > < / option >
< option value = "2" > < / option >
< option selected > < / option >
< / select >
< button className = "ql-bold" > < / button >
< button className = "ql-italic" > < / button >
< select className = "ql-color" >
< option value = "red" > < / option >
< option value = "green" > < / option >
< option value = "blue" > < / option >
< option value = "orange" > < / option >
< option value = "violet" > < / option >
< option value = "#d0d1d2" > < / option >
< option selected > < / option >
< / select >
< button className = "ql-insertStar" >
< CustomButton / >
< / button >
< / div >
) ;
/*
* Editor component with custom toolbar and content containers
*/
class Editor extends React . Component {
constructor ( props ) {
super ( props ) ;
this . state = { editorHtml : '' } ;
this . handleChange = this . handleChange . bind ( this ) ;
}
handleChange ( html ) {
this . setState ( { editorHtml : html } ) ;
}
render ( ) {
return (
< div className = "text-editor" >
< CustomToolbar / >
< ReactQuill
onChange = { this . handleChange }
placeholder = { this . props . placeholder }
modules = { Editor . modules }
/ >
< / div >
) ;
}
}
/*
* Quill modules to attach to editor
* See http://quilljs.com/docs/modules/ for complete options
*/
Editor . modules = {
toolbar : {
container : '#toolbar' ,
handlers : {
insertStar : insertStar ,
} ,
} ,
} ;
/*
* Quill editor formats
* See http://quilljs.com/docs/formats/
*/
Editor . formats = [
'header' ,
'font' ,
'size' ,
'bold' ,
'italic' ,
'underline' ,
'strike' ,
'blockquote' ,
'list' ,
'bullet' ,
'indent' ,
'link' ,
'image' ,
'color' ,
] ;
/*
* PropType validation
*/
Editor . propTypes = {
placeholder : React . PropTypes . string ,
} ;
/*
* Render component on page
*/
ReactDOM . render (
< Editor placeholder = { 'Write something or insert a star ★' } / > ,
document . querySelector ( '.app' )
) ;
يحتوي المكون على نوعين من التنسيقات:
formats
. يتم تمكين جميع التنسيقات بشكل افتراضي. import ReactQuill , { Quill } from 'react-quill' ; // ES6
const ReactQuill = require ( 'react-quill' ) ; // CommonJS
/*
* Example Parchment format from
* https://quilljs.com/guides/cloning-medium-with-parchment/
* See the video example in the guide for a complex format
*/
let Inline = Quill . import ( 'blots/inline' ) ;
class BoldBlot extends Inline { }
BoldBlot . blotName = 'bold' ;
BoldBlot . tagName = 'strong' ;
Quill . register ( 'formats/bold' , BoldBlot ) ;
const formats = [ 'bold' ] ; // add custom format name + any built-in formats you need
/*
* Editor component with default and custom formats
*/
class MyComponent extends React . Component {
constructor ( props ) {
this . formats = formats ;
this . state = { text : '' } ;
}
handleChange ( value ) {
this . setState ( { text : value } ) ;
}
render ( ) {
return (
< ReactQuill
value = { this . state . text }
onChange = { this . handleChange }
formats = { this . formats }
/ >
) ;
}
}
إذا قمت بإنشاء مثيل ReactQuill بدون أطفال، فسيتم إنشاء <div>
لك، لاستخدامه كمنطقة تحرير لـ Quill. إذا كنت تفضل ذلك، يمكنك تحديد العنصر الخاص بك لاستخدام ReactQuill. لاحظ أن ملفات <textarea>
غير مدعومة بواسطة Quill في الوقت الحالي.
ملاحظة: تفقد مناطق التحرير المخصصة التركيز عند استخدام React 16 كقسم نظير في هذا الوقت (خطأ).
class MyComponent extends React . Component {
render ( ) {
return (
< ReactQuill >
< div className = "my-editing-area" / >
< / ReactQuill >
) ;
}
} ) ;
يجب أن تكون الترقية إلى ReactQuill v2 بسيطة مثل تحديث التبعية الخاصة بك. ومع ذلك، فإنه يزيل أيضًا الدعم للدعائم التي تم إهمالها منذ فترة طويلة، وReactQuill Mixin، ومكون شريط الأدوات.
تم تعطيل دعم خيارات toolbar
styles
و pollInterval
Quill منذ فترة طويلة. بدءًا من هذا الإصدار، لن يحذرك ReactQuill بعد الآن إذا حاولت استخدامها.
سمح ReactQuill Mixin بإدخال الوظيفة الأساسية التي جعلت ReactQuill يتدخل في مكوناتك الخاصة، وإنشاء إصدارات مخصصة بشكل عميق.
لقد تم اعتبار Mixin نموذجًا مضادًا لفترة طويلة الآن، لذلك قررنا الانتهاء من إيقافه.
لا يوجد مسار للترقية. إذا كانت لديك حالة استخدام تعتمد على Mixin، فنحن نشجعك على فتح مشكلة، وسنحاول أن نقدم لك ميزة جديدة لجعل ذلك ممكنًا، أو دعمًا مخصصًا للترحيل منها.
لقد وفرت Quill منذ فترة طويلة دعمًا مدمجًا لأشرطة الأدوات المخصصة، والتي حلت محل مكون شريط الأدوات ReactQuill (غير المرن تمامًا).
استخدم وحدة شريط الأدوات أو ميزة شريط أدوات HTML بدلاً من ذلك.
// ES6
import ReactQuill , { Quill } from 'react-quill' ;
// CommonJS
const ReactQuill = require ( 'react-quill' ) ;
const { Quill } = ReactQuill ;
Quill
: مساحة اسم Quill
التي يمكنك الاتصال register
.
id
: المعرف الذي سيتم تطبيقه على عنصر DOM.
className
: الفئات التي سيتم تطبيقها على عنصر DOM.
value
: قيمة المحرر كمكون متحكم فيه. يمكن أن تكون سلسلة تحتوي على HTML، أو مثيل Quill Delta، أو كائنًا عاديًا يمثل Delta. لاحظ أنه بسبب القيود الموجودة في Quill، يعد هذا في الواقع وضعًا شبه متحكم فيه ، مما يعني أنه لا يتم منع التحرير، ولكن تغيير value
سيظل يحل محل المحتويات. لاحظ أيضًا أن تمرير Quill Delta هنا، ثم سلسلة HTML، أو العكس، سيؤدي دائمًا إلى حدوث تغيير، بغض النظر عما إذا كانوا يمثلون نفس المستند.delta
من حدث onChange
value
، لأنه سيؤدي إلى حدوث حلقة. راجع استخدام دلتا للحصول على التفاصيل.
defaultValue
: القيمة الأولية للمحرر كمكون غير متحكم فيه. يمكن أن تكون سلسلة تحتوي على HTML أو Quill Delta أو كائن عادي يمثل Delta.
readOnly
: إذا كان صحيحًا، فلن يسمح المحرر بتغيير محتوياته. يلتف API disable
Quill.
placeholder
: القيمة الافتراضية للمحرر الفارغ. ملاحظة: لا تدعم Quill API تغيير هذه القيمة ديناميكيًا. استخدم المراجع وسمات البيانات بدلاً من ذلك (انظر #340).
modules
: كائن يحدد الوحدات التي تم تمكينها وتكوينها. يعد شريط أدوات المحرر وحدة مخصصة بشكل شائع. راجع قسم الوحدات في وثائق Quill لمزيد من المعلومات حول الوحدات المتوفرة.
formats
: مجموعة من التنسيقات التي سيتم تمكينها أثناء التحرير. يتم تمكين كافة التنسيقات المنفذة بشكل افتراضي. راجع التنسيقات للحصول على قائمة. لا ينبغي تضمين التنسيقات المخصصة في المصفوفة اعتبارًا من الإصدار 1.0.0. وبدلاً من ذلك، ينبغي إنشاؤها من خلال Parchment وتسجيلها في تصدير Quill الخاص بالوحدة.
style
: كائن بقواعد CSS مخصصة لتطبيقه على حاوية المحرر. يجب أن تكون القواعد بأسلوب تسمية React "camelCased".
theme
: اسم الموضوع الذي سيتم تطبيقه على المحرر. الإعدادات الافتراضية هي snow
، وهو موضوع Quill القياسي. مرر null
لاستخدام الحد الأدنى من السمة الأساسية. راجع المستندات الخاصة بالمواضيع لمزيد من المعلومات حول تضمين أوراق الأنماط المطلوبة.
tabIndex
: الترتيب الذي يركز عليه المحرر، من بين عناصر التحكم الأخرى في الصفحة، أثناء التنقل عبر لوحة المفاتيح.
bounds
: عنصر التحديد أو عنصر DOM الذي يستخدمه Quill لتقييد موضع النوافذ المنبثقة. الإعدادات الافتراضية هي document.body
.
children
: عنصر React واحد سيتم استخدامه كمنطقة تحرير لـ Quill بدلاً من العنصر الافتراضي، وهو <div>
. لاحظ أنه لا يمكنك استخدام <textarea>
، لأنه ليس هدفًا مدعومًا. لاحظ أيضًا أن تحديث العناصر الفرعية أمر مكلف، لأنه سيؤدي إلى إعادة إنشاء محرر Quill. قم بتعيين value
الخاصية إذا كنت تريد التحكم في محتويات html الخاصة بالمحرر.
onChange(content, delta, source, editor)
: يتم الاتصال مرة أخرى بالمحتوى الجديد للمحرر بعد التغيير. سيتم تمرير محتويات HTML الخاصة بالمحرر، وكائن دلتا الذي يعبر عن التغيير، ومصدر التغيير، وأخيرًا وكيل للقراءة فقط لأدوات وصول المحرر مثل getHTML()
.delta
هذا value
، لأنه سيؤدي إلى حدوث حلقة. استخدم editor.getContents()
بدلاً من ذلك. راجع استخدام دلتا للحصول على التفاصيل.
onChangeSelection(range, source, editor)
: يتم الاتصال مرة أخرى باستخدام النطاق المحدد الجديد، أو يكون خاليًا عند عدم التركيز. سيتم تمرير نطاق التحديد ومصدر التغيير وأخيرًا وكيل للقراءة فقط لأدوات الوصول إلى المحرر مثل getBounds()
.
onFocus(range, source, editor)
: يتم استدعاؤه عندما يصبح المحرر مركزًا. وسوف تتلقى نطاق الاختيار الجديد.
onBlur(previousRange, source, editor)
: يتم استدعاؤه عندما يفقد المحرر التركيز. سوف يتلقى نطاق التحديد الذي كان لديه قبل أن يفقد التركيز.
onKeyPress(event)
: يتم الاتصال به بعد الضغط على المفتاح وتحريره. : لاحظ أنه، مثل نظيره الأصلي، لن يتم استدعاء هذا لمفاتيح خاصة مثل Shift أو Enter . إذا كنت بحاجة إليها، فاتصل بـ onKeyDown
أو onKeyUp
.
onKeyDown(event)
: يتم الاتصال به بعد الضغط على المفتاح، ولكن قبل تحريره. : لاحظ أنه نظرًا لكيفية عمل Quill، فمن المحتمل ألا تتلقى أحداثًا للمفاتيح مثل enter أو backspace أو delete . إذا كان الأمر كذلك، فحاول الاتصال بـ onKeyUp
بدلاً من ذلك.
onKeyUp(event)
: يتم الاتصال به بعد تحرير المفتاح.
preserveWhitespace
: إذا كان صحيحًا، فسيتم استخدام علامة pre
لمنطقة المحرر بدلاً من علامة div
الافتراضية. وهذا يمنع Quill من طي المسافات البيضاء المستمرة على اللصق. قضية ذات صلة.
إذا كان لديك مرجع لعقدة ReactQuill، فستتمكن من استدعاء الطرق التالية:
focus()
: يركز على المحرر.
blur()
: يزيل التركيز من المحرر.
getEditor()
: إرجاع نسخة Quill التي تدعم المحرر. بينما يمكنك استخدام هذا بحرية للوصول إلى طرق مثل getText()
، يرجى تجنب التعامل مع المثيل بشكل حتمي، لتجنب عدم مزامنة ReactQuill و Quill. يتوفر محرر غير مميز أكثر أمانًا كبديل.
شاهد هذا المثال على Codepen
class Editor extends React . Component {
constructor ( props ) {
super ( props ) ;
this . quillRef = null ; // Quill instance
this . reactQuillRef = null ; // ReactQuill component
}
componentDidMount ( ) {
this . attachQuillRefs ( ) ;
}
componentDidUpdate ( ) {
this . attachQuillRefs ( ) ;
}
attachQuillRefs = ( ) => {
if ( typeof this . reactQuillRef . getEditor !== 'function' ) return ;
this . quillRef = this . reactQuillRef . getEditor ( ) ;
} ;
insertText = ( ) => {
var range = this . quillRef . getSelection ( ) ;
let position = range ? range . index : 0 ;
this . quillRef . insertText ( position , 'Hello, World! ' ) ;
} ;
render ( ) {
return (
< div >
< ReactQuill
ref = { ( el ) => {
this . reactQuillRef = el ;
} }
theme = { 'snow' }
/ >
< button onClick = { this . insertText } > Insert Text < / button >
< / div >
) ;
}
}
makeUnprivilegedEditor
: لإنشاء محرر لا يتمتع بأي امتيازات. قم بتمرير هذه الطريقة كمرجع إلى مثيل Quill من getEditor
. لا تحتاج عادةً إلى استخدام هذه الطريقة نظرًا لأن المحرر الذي يتعرض لمعالجات الأحداث لا يتمتع بأي امتيازات بالفعل.
const editor = this . reactQuillRef . getEditor ( ) ;
const unprivilegedEditor = this . reactQuillRef . makeUnprivilegedEditor ( editor ) ;
// You may now use the unprivilegedEditor proxy methods
unprivilegedEditor . getText ( ) ;
أثناء الأحداث، سيجعل ReactQuill مجموعة فرعية مقيدة من Quill API متاحة كوسيطة editor
. يمنع هذا الوصول إلى الأساليب التدميرية، والتي قد تتسبب في عدم مزامنة ReactQuill مع المكون. وهو يوفر الطرق التالية، والتي تكون في الغالب وكلاء لطرق Quill الموجودة:
getLength()
: إرجاع طول محتويات المحرر، بالأحرف، وليس inc