From c5d16d0080dcdd56d1abf5cfbbb448f5a83cbbaa Mon Sep 17 00:00:00 2001 From: Rumbustious <99288580+Rumbustious@users.noreply.github.com> Date: Tue, 22 Aug 2023 13:08:58 +0300 Subject: [PATCH 01/19] Edit adding-interactivity.md --- src/content/learn/adding-interactivity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/learn/adding-interactivity.md b/src/content/learn/adding-interactivity.md index 936c27214..d860b436c 100644 --- a/src/content/learn/adding-interactivity.md +++ b/src/content/learn/adding-interactivity.md @@ -798,4 +798,4 @@ function ItemList({ artworks, onToggle }) { إذهب الى [الإستجابة الى الاحداث](/learn/responding-to-events) لتقرأ هذا الفصل صفحة بصفحة! -أو، إذا كنت تفهم هذه المواضيع بالفعل، لماذا لا تقرأ عن [التحكم فى الحالة](/learn/managing-state)؟ +أو، إذا كنت تفهم هذه المواضيع بالفعل، لماذا لا تقرأ عن [إدارة الحالة](/learn/managing-state)؟ From 7fdd2a74fbee22a0f3cf8b2baa3148d9ddb951e4 Mon Sep 17 00:00:00 2001 From: Rumbustious <99288580+Rumbustious@users.noreply.github.com> Date: Thu, 31 Aug 2023 21:27:24 +0300 Subject: [PATCH 02/19] Translation of (Reacting to input): until step 2 - Translated `intro` - Translated `What you will learn` - Translated Imperative & Declartive programming - Translated Step 1 --- .../learn/reacting-to-input-with-state.md | 119 +++++++++--------- 1 file changed, 60 insertions(+), 59 deletions(-) diff --git a/src/content/learn/reacting-to-input-with-state.md b/src/content/learn/reacting-to-input-with-state.md index 522aa63a1..326d0158d 100644 --- a/src/content/learn/reacting-to-input-with-state.md +++ b/src/content/learn/reacting-to-input-with-state.md @@ -1,37 +1,39 @@ --- -title: Reacting to Input with State +title: الاستجابة للمدخلات باستخدام الحالة --- -React provides a declarative way to manipulate the UI. Instead of manipulating individual pieces of the UI directly, you describe the different states that your component can be in, and switch between them in response to the user input. This is similar to how designers think about the UI. +React توفر طريقة تصريحيّة (declarative) لتعديل واجهة المستخدم (UI). بدلا من تعديل أجزاء منفردة من واجهة المستخدم مباشرة، يمكنك وصف الحالات المختلفة التي يأخذها مكوّنك، والانتقال بينهم كاستجابة لمدخلات المستخدم. هذا مشابه لتصور المصممين عن واجهة المستخدم. + -* How declarative UI programming differs from imperative UI programming -* How to enumerate the different visual states your component can be in -* How to trigger the changes between the different visual states from code - +* كيف تختلف البرمجة التصريحية لواجهة المستخدم (declarative UI programming) عن البرمجة الأمرية لواجهة المستخدم (imperative UI programming) +* كيفية استعراض الحالات المرئية المختلفة التي يأخذها مكوّنك +* كيفية تنشيط التغييرات بين الحالات المرئية المختلفة من خلال الكود + -## How declarative UI compares to imperative {/*how-declarative-ui-compares-to-imperative*/} +## كيف تُقارَن واجهة المستخدم التصريحية (declarative UI) بالأمرية (imperative) {/*how-declarative-ui-compares-to-imperative*/} -When you design UI interactions, you probably think about how the UI *changes* in response to user actions. Consider a form that lets the user submit an answer: +عندما تصمم تعاملات واجهة المستخدم، عليك غالبًا التفكير في كيفية *تغيّر* واجهة المستخدم كاستجابة لاجراءات المستخدم. فكر في نموذج يسمح للمستخدم بإرسال إجابة: -* When you type something into the form, the "Submit" button **becomes enabled.** -* When you press "Submit", both the form and the button **become disabled,** and a spinner **appears.** -* If the network request succeeds, the form **gets hidden,** and the "Thank you" message **appears.** -* If the network request fails, an error message **appears,** and the form **becomes enabled** again. +* عندما تكتب شيئًا داخل النموذج، الزر "أرسل" **يصبح مفعلًا.** +* عندما تضغط على "أرسل"، كلٌ من النموذج والزر **يصبح معطلا** ومؤشر التحميل **يظهر.** +* لو نجح طلب الشبكة، النموج **يبدأ بالاختفاء،** ورسالة "شكرًا لك" **تظهر.** +* لو فشل طلب الشبكة، رسالة خطأٍ **تظهر،** والنموذج **يصبح مفعلًا** مجددا. -In **imperative programming,** the above corresponds directly to how you implement interaction. You have to write the exact instructions to manipulate the UI depending on what just happened. Here's another way to think about this: imagine riding next to someone in a car and telling them turn by turn where to go. +في **البرمجة الأمرية (imperative programming)**، يتوافق ما ذُكر أعلاه مباشرة مع طريقة تطبيق التعاملات. عليك أن تكتب التعليمات التامة لتعديل واجهة المستخدم معتمدا على ما حصل للتو. إليك طريقة أخرى لتفكر في هذا الأمر: تخيل نفسك راكبا إلى جانب أحدهم في سيارة مع إخباره في كل منعطف تلو الآخر عن وجهة الذهاب. -They don't know where you want to go, they just follow your commands. (And if you get the directions wrong, you end up in the wrong place!) It's called *imperative* because you have to "command" each element, from the spinner to the button, telling the computer *how* to update the UI. +هم لا يعلمون إلى أين تريد أن تذهب، هم يتبعون أوامرك فقط. (ولو أنك أعطيتهم الاتجاهات الخاطئة، سوف ينتهي بك المطاف لوجهة خاطئة!) هذا يطلق عليه *أمري (imperative)* لأن عليك أن "تأمر" كل عنصر، بداية من مؤشر التحميل إلى الزر، مخبرًا +الكمبيوتر عن *كيفية* تحديث واجهة المستخدم (UI). -In this example of imperative UI programming, the form is built *without* React. It only uses the browser [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model): +في هذا المثال للبرمجة الأمرية لواجهة المستخدم، النموذج مبنيّ *بدون* React. إنه يستخدم [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model) المتصفح فقط: @@ -84,10 +86,10 @@ function submitForm(answer) { // Pretend it's hitting the network. return new Promise((resolve, reject) => { setTimeout(() => { - if (answer.toLowerCase() == 'istanbul') { + if (answer.toLowerCase() == 'إسطنبول') { resolve(); } else { - reject(new Error('Good guess but a wrong answer. Try again!')); + reject(new Error('توقع جيد ولكن إجابة خاطئة. حاول مرة أخرى!')); } }, 1500); }); @@ -111,17 +113,17 @@ textarea.oninput = handleTextareaChange; ```html public/index.html
-

City quiz

+

اختبار المدينة

- What city is located on two continents? + ما هي المدينة الواقعة على قارتين؟


- - + +
-

That's right!

+

هذا صحيح!

```
-تعديل واجهة المستخدم (UI) أمريًّا يعمل بشكل جيد كفاية للأمثلة المعزولة، ولكنه يصبح أكثر صعوبة بشكل استثنائي عندما تدير أنظمة أكثر تعقيدًا. تخيل تحديث صفحة مليئة بالنماذج المختلفة مثل هذه هنا. إضافة عنصر واجهة مستخدم جديد سيتطلب فحص كامل الكود الموجود بحرص للتأكد من أنك لم تقم بعمل خطأ(على سبيل المثال، نسيان إظهار أو إخفاء شيء ما). +تعديل واجهة المستخدم (UI) أمريًّا يعمل بشكل جيد كفاية للأمثلة المعزولة، ولكنه يصبح أكثر صعوبة بشكل استثنائي عندما تدير أنظمة أكثر تعقيدًا. تخيل تحديث صفحة مليئة بالنماذج المختلفة مثل هذه هنا. إضافة عنصر واجهة مستخدم جديد سيتطلب فحص كامل الكود الموجود بحرص للتأكد من أنك لم تقم بعمل خطأ (على سبيل المثال، نسيان إظهار أو إخفاء شيء ما). React صُنعت لحل هذه المشكلة. -في React، لن تقوم بتعديل واجهة المستخدم مباشرة -- يعني أنك لن تقوم بتفعيل، تعطيل، إظهار، أو إخفاء مكوّنات مباشرة. بدلا عن ذلك، سوف **تصف ما تريده أن يظهر،** و React سوف تدبر كيفية تحديث واجهة المستخدم. فكر في أخذ سيارة أجرة وإخبار السائق إلي أين تريد أنت تذهب بدلا من إخباره إلي أين ينعطف. وظيفة السائق هي أن يوصلك إلى هناك، وربما قد يعرف اختصارات لم تأخذها أنت بالحسبان. +في React، لن تقوم بتعديل واجهة المستخدم مباشرة -- يعني أنك لن تقوم بتفعيل، تعطيل، إظهار، أو إخفاء مكوّنات مباشرة. بدلًا عن ذلك، سوف **تصف ما تريده أن يظهر،** و React سوف تدبر كيفية تحديث واجهة المستخدم. فكر في أخذ سيارة أجرة وإخبار السائق إلي أين تريد أنت تذهب بدلًا من إخباره إلي أين ينعطف. وظيفة السائق هي أن يوصلك إلى هناك، وربما قد يعرف اختصارات لم تأخذها أنت بالحُسبان. @@ -146,18 +145,18 @@ React صُنعت لحل هذه المشكلة. لقد رأيت كيفية تنفيذ نموذج أمريَّا أعلاه. لفهم أفضل لكيفية التفكير في React، سوف تمر بإعادة تنفيذ واجهة المستخدم (UI) هذه باستخدام React أدناه: 1. **عيّن** الحالات المرئية المختلفة لمكوّنك -2. **حدد** ما ينشط تغيرات تلك الحالات +2. **حدد** ما ينشط تغييرات تلك الحالات 3. **مثّل** الحالة في الذاكرة باستخدام `useState` 4. **احذف** أيّ متغيرات حالة غير ضرورية 5. **اربط** معالجات الأحداث لتعيين الحالة -### الخطوة 1: عين الحالات المرئية المختلفة لمكوّنك {/*step-1-identify-your-components-different-visual-states*/} +### الخطوة 1: عيّن الحالات المرئية المختلفة لمكوّنك {/*step-1-identify-your-components-different-visual-states*/} -في علوم الحاسب، ربما تسمع عن ["آلة حالة (state machine)"](https://en.wikipedia.org/wiki/Finite-state_machine) كونها واحدة من ضمن "حالات" متعددة.إذا كنت تعمل مع مصمم، لربما رأيت نماذج تجريبية لـ"الحالات المرئية" المختلفة +في علوم الحاسب، ربما تسمع عن ["آلة الحالة (state machine)"](https://en.wikipedia.org/wiki/Finite-state_machine) كونها واحدة من ضمن "حالات" متعددة. إذا كنت تعمل مع مصمم، لربما رأيت نماذج تجريبية لـ"الحالات المرئية" المختلفة -أولًا، أنت تحتاج لتصور جميع "الحالات" المختلفة لواجهة المستخدم (UI) التي قد يراها المستخدم: -* **فارغة**: النموذج يحتوي زر "إرسال" معطل. -* **كتابة**: النموذج يحتوي زر "إرسال" مفعّل. +أولًا، أنت تحتاج لتصوّر جميع "الحالات" المختلفة لواجهة المستخدم (UI) التي قد يراها المستخدم: +* **فارغة**: النموذج يحتوي على زر "إرسال" معطل. +* **كتابة**: النموذج يحتوي على زر "إرسال" مفعّل. * **إرسال**: النموذج معطل تمامًا. يتم عرض مؤشر التحميل. * **نجاح**: يتم عرض رسالة "شكرًا لك" بدلًا من النموذج. * **خطأ**: مثل حالة الكتابة، ولكن مع رسالة خطأ إضافية @@ -193,7 +192,7 @@ export default function Form({ -يمكنك تسمية الخاصيّة أيّ شيء تريد، التسمية ليست مهمة. جرب تعديل `status = 'empty'` إلى `status = 'success'` لترى رسالة النجاح تظهر. التجربة تتيح لك التكرار السريع على واجهة المستخدم قبل ربط أي منطق. ها هو نموذج تجريبي أكثر تفصيلًا لنفس المكوّن، يظل "متحكم" بواسطة الخاصية `status`: +يمكنك تسمية الخاصيّة أيّ شيء تريد، التسمية ليست مهمة. جرب تعديل `status = 'empty'` إلى `status = 'success'` لترى رسالة النجاح تظهر. التجربة تتيح لك التكرار السريع على واجهة المستخدم قبل ربط أي منطق. ها هو نموذج تجريبي أكثر تفصيلًا لنفس المكوّن، يظل "متحكمًا به" بواسطة الخاصية `status`: @@ -234,6 +233,7 @@ export default function Form({ ``` ```css +body { direction: rtl; } .Error { color: red; } ``` @@ -243,7 +243,7 @@ export default function Form({ #### عرض عديد من الحالات المرئية مرة واحدة {/*displaying-many-visual-states-at-once*/} -لو أن لمكون العديد من الحالات المرئية، قد يكون ملائما عرضها جميعها في صفحة واحدة: +لو أن لمكون العديد من الحالات المرئية، قد يكون ملائمًا عرضها جميعها في صفحة واحدة: @@ -302,7 +302,7 @@ export default function Form({ status }) { ```css section { border-bottom: 1px solid #aaa; padding: 20px; } h4 { color: #222; } -body { margin: 0; } +body { margin: 0; direction: rtl; } .Error { color: red; } ``` @@ -312,22 +312,22 @@ body { margin: 0; } -### الخطوة 2: حدد ما ينشط تغيرات تلك الحالة {/*step-2-determine-what-triggers-those-state-changes*/} +### الخطوة 2: حدد ما ينشط تغييرات تلك الحالة {/*step-2-determine-what-triggers-those-state-changes*/} يمكنك تنشيط تحديثات الحالة كاستجابة إلى نوعين من المدخلات: * **مدخلات الإنسان،** مثل الضغط على زر، الكتابة في حقل، زيارة رابط. -* **مدخلات الكمبيوتر** مثل وصول رد الشبكة، استكمال المؤقت، تحميل الصورة +* **مدخلات الكمبيوتر،** مثل وصول رد الشبكة، استكمال المؤقت، تحميل الصورة. - - + + -في كلتا الحالتين، **يجب عليك تعيين [متغيرات الحالة (state variables)](/learn/state-a-components-memory#anatomy-of-usestate) لتُحدّث واجهة المستخدم (UI).** من أجل النموذج الذي تطوره، سوف تحتاج لتغيير الحالة كنتيجة لقليل من المدخلات المختلفة: +في كلتا الحالتين، **يجب عليك تعيين [متغيرات الحالة (state variables)](/learn/state-a-components-memory#anatomy-of-usestate) لتُحدّث واجهة المستخدم (UI).** من أجل تطوير النموذج سوف تحتاج لتغيير الحالة كنتيجة لبعض من المدخلات المختلفة: -* **تغيرت مدخل النص** (الإنسان) سوف يغيرها من الحالة *الفارغة* إلى حالة *الكتابة* أو العكس، يعتمد على ما إذا كان حقل النص فارغًا أم لا. -* **الضغط على زر الإرسال** (الإنسان) سوف يغيرها إلى حالة *الإرسال* +* **تغيّر حقل إدخال النص** (الإنسان) سوف يغيرها من الحالة *الفارغة* إلى حالة *الكتابة* أو العكس، يعتمد على ما إذا كان حقل النص فارغًا أم لا. +* **الضغط على زر الإرسال** (الإنسان) سوف يغيرها إلى حالة *الإرسال*. * **استجابة ناجحة للشبكة** (الكمبيوتر) سوف يغيرها إلى حالة *النجاح*. * **استجابة فاشلة للشبكة** (الكمبيوتر) سوف يغيرها إلى حالة *الخطأ* مع رسالة الخطأ المناسبة. @@ -372,17 +372,17 @@ const [isSuccess, setIsSuccess] = useState(false); const [isError, setIsError] = useState(false); ``` -خطوتك المبدأئية على الأرجح لن تكون هي الأفضل، ولكن هذا لا بأس به -- إعادة تصميم الحالة هو جزء من العملية! +خطوتك المبدئية على الأرجح لن تكون هي الأفضل، ولكن هذا لا بأس به -- إعادة تصميم الحالة هو جزء من العملية! -### خطوة 4: احذف أيّ متغيرات حالة غير ضرورية {/*step-4-remove-any-non-essential-state-variables*/} +### الخطوة 4: احذف أيّ متغيرات حالة غير ضرورية {/*step-4-remove-any-non-essential-state-variables*/} -ما تريده هو تجنب تكرار محتوى الحالة لذلك أنت فقط تقوم بتعقب ما هو ضروري. قضاء قليل من الوقت في إعادة تصميم هيكل حالتك سوف يجعل مكوّنك أسهل للفهم، يقلل التكرار، ويتجنب المعاني غير المقصودة. هدفك هو **منع الأوضاع التي تكون بها الحالة في الذاكرة لا تمثل أي واجهة مستخدم صالحة تود للمستخدم أن يراها.** (على سبيل المثال، لن تريد أبدًا إظهار رسالة خطأ مع تعطيل الإدخال في نفس الوقت، أو أن المستخدم لن يكون قادرًا على تصحيح الخطأ!) +ما تريده هو تجنب تكرار محتوى الحالة لذلك أنت تقوم بتعقب ما هو ضروري فقط. قضاء قليل من الوقت في إعادة تصميم هيكل حالتك سوف يجعل مكوّنك أسهل للفهم، يقلل التكرار، ويتجنب المعاني غير المقصودة. هدفك هو **منع الأوضاع التي تكون بها الحالة في الذاكرة لا تمثل أي واجهة مستخدم صالحة من التي تود للمستخدم أن يراها.** (على سبيل المثال، لن تريد أبدًا إظهار رسالة خطأ مع تعطيل الإدخال في نفس الوقت، أو أن المستخدم لن يكون قادرًا على تصحيح الخطأ!) هنا بعض الاسئلة التي يمكن أن تسألها عن متغيرات الحالة: -* **هل هذه الحالة تسبب معضلة؟** على سبيل المثال، `isTyping` و `isSubmitting` لا يمكن لكليهما أن يكونا بقيمة `true`. المعضلة غالبا تعني أن الحالة ليست مقيدة بالشكل الكافي. هناك أربع احتمالات ممكنة لقيميتين منطقيتين (boolean). لكن ثلاث منها فقط يوافقن حالات صالحة. لحذف الحالة "المستحيلة"، يمكنك جمع تلك الحالات داخل `status` التي يجب يجب أن تكون واحدة من ثلاث قيم: `'typing'`, `'submitting'`, أو `'success'`. +* **هل هذه الحالة تسبب معضلة؟** على سبيل المثال، `isTyping` و `isSubmitting` لا يمكن لكليهما أن يكونا بقيمة `true`. المعضلة غالبًا تعني أن الحالة ليست مقيدة بالشكل الكافي. هناك أربع احتمالات ممكنة لقيميتين منطقيتين (boolean). لكن ثلاث منهن فقط يوافقن حالات صالحة. لحذف الحالة "المستحيلة"، يمكنك جمع تلك الحالات داخل `status` التي يجب أن تكون واحدة من ثلاث قيم: `'typing'`, `'submitting'`, أو `'success'`. * **هل نفس المعلومات متاحة بالفعل لمتغير حالة آخر؟** معضلة أخرى: `isEmpty` و `isTyping` لا يمكنها أن يكونا `true` في نفس الوقت. بجعلهما متغيرين حالة منفصلين، تخاطر بفقدان الترابط بينهما وإحداث الأخطاء. لحسن الحظ، يمكن حذف `isEmpty` والتحقق من `answer.length === 0` بدلًا عن ذلك. -* **هل يمكنك الحصول على نفس المعلومات من من عكس متغير حالة آخر؟** `isError` غير ضروري لأنه يمكنك التحقق من `error !== null` بدلًا عن ذلك. +* **هل يمكنك الحصول على نفس المعلومات من عكس متغير حالة آخر؟** `isError` غير ضروري لأنه يمكنك التحقق من `error !== null` بدلًا عن ذلك. بعد هذا التبسيط، تبقى لديك 3 (من أصل 7!) متغيرات حالة *ضرورية*: @@ -392,13 +392,13 @@ const [error, setError] = useState(null); const [status, setStatus] = useState('typing'); // 'typing', 'submitting', or 'success' ``` -أنت تعلم أنها ضرورية، لأنك لا تستطيع إزالة أيّ منها بدون تخريب آلية العمل +أنت تعلم أنها ضرورية، لأنك لا تستطيع إزالة أيّ منها بدون تخريب آلية العمل. #### إزالة الحالات "المستحيلة" باستخدام مخفض (reducer) {/*eliminating-impossible-states-with-a-reducer*/} -هذه الثلاث متغيرات تمثيل جيد كفاية لحالة النموذج. مع ذلك، لا تزال هناك بعض الحالات المتوسطة التي لا تشكّل معنى بصورة تامة. على سبيل المثال، `error` التي لا تحمل القيمة null ليس لها معنى عندما تكون `status` تحمل قيمة `success`. لتمثيل الحالة بطريقة أكثر دقة، يمكنك [استخلاصها إلى مخفض.](/learn/extracting-state-logic-into-a-reducer) المخفضات تتيح ليك توحيد العديد من متغيرات الحالة داخل كائن (object) واحد وتجميع كل المنطق المتعلق بها. +هذه الثلاث متغيرات تمثيل جيد كفاية لحالة النموذج. مع ذلك، لا تزال هناك بعض الحالات المتوسطة الغير منطقية بشكل كافٍ. على سبيل المثال، `error` التي لا تحمل القيمة null غير منطقية عندما تكون `status` تحمل قيمة `success`. لتمثيل الحالة بطريقة أكثر دقة، يمكنك [استخلاصها إلى مخفض.](/learn/extracting-state-logic-into-a-reducer) المخفضات تتيح ليك توحيد العديد من متغيرات الحالة داخل كائن (object) واحد وتجميع كل المنطق المتعلق بها. @@ -471,7 +471,7 @@ function submitForm(answer) { setTimeout(() => { let shouldError = answer.toLowerCase() !== 'lima' if (shouldError) { - reject(new Error('Good guess but a wrong answer. Try again!')); + reject(new Error('توقع جيد ولكن إجابة خاطئة. حاول مرة أخرى!')); } else { resolve(); } @@ -481,6 +481,7 @@ function submitForm(answer) { ``` ```css +body { direction: rtl; } .Error { color: red; } ``` @@ -493,7 +494,7 @@ function submitForm(answer) { * البرمجة التصريحية تعني وصف واجهة المستخدم لكل حالة مرئية عوضًا عن الإدارة التفصيلية لواجهة المستخدم (الأمريّة). * عند تطوير مكوّن: 1. حدد كل حالاته المرئية. - 2. عيّن منشطات الإنسان والكمبيوتر لتغيّرات الحالة. + 2. عيّن المنشطات الوادة الإنسان والكمبيوتر لتغيّرات الحالة. 3. مثل الحالة عن طريق `useState`. 4. احذف الحالة غير الضرورية لتجنب الأخطاء والمعضلات. 5. اربط معالجات الأحداث لتعيين الحالة. @@ -561,7 +562,7 @@ body { margin: 0; padding: 0; height: 250px; } * عندما تكون الصورة نشطة، أصناف CSS هي `background` و `picture picture--active`. * عندما تكون الصورة غير نشطة، أصناف CSS هي `background background--active` و `picture`. -متغير حالة قيمة منطقية (boolean) واحد كافي لتذكر ما إذا كانت نشطة. المهمة الأصلية كانت إزالة أو إضافة أصناف CSS. على أية حال، في React تحتاج لـ*تصف* ما تريد رؤيته فضلًا عن *تعديل* عناصر واجهة المستخدم. لذلك تحتاج لحساب كلا صنفيّ CSS اعتمادًا على الحالة الحالية. تحتاج أيضًا إلى [إيقاف الانتشار (propagation)](/learn/responding-to-events#stopping-propagation) بحيث لا يتم تسجيل النقر على الصورة كنقر على الخلفية. +متغير حالة قيمة منطقية (boolean) واحد يكفي لتذكر ما إذا كانت نشطة. المهمة الأصلية كانت إزالة أو إضافة أصناف CSS. على أية حال، في React تحتاج لـ*تصف* ما تريد رؤيته فضلًا عن *تعديل* عناصر واجهة المستخدم. لذلك تحتاج لحساب كلا صنفيّ CSS اعتمادًا على الحالة الحالية. تحتاج أيضًا إلى [إيقاف الانتشار (propagation)](/learn/responding-to-events#stopping-propagation) بحيث لا يتم تسجيل النقر على الصورة كنقر على الخلفية. تأكد من أن هذا الإصدار يعمل عن طريق النقر على الصور وخارجها: @@ -697,7 +698,7 @@ body { margin: 0; padding: 0; height: 250px; } -ضع في الحسبان أنه إذا وصف جزئين مختلفين من JSX الشجرة نفسها، فتضمينهما (أول `
` → أول ``) يجب أن يصطف. وإلا تغيّر `isActive` سوف يعيد إنشاء الشجرة بأكملها أدناه و [يعيد تعيين حالتها.](/learn/preserving-and-resetting-state) هذا هو السبب، إذا كان يتم إرجاع شجرة JSX مشابهة في كلا الحالتين، فمن الأفضل كتابتهما على كجزء واحد من JSX. +ضع في الحسبان أنه إذا وصف جزئين مختلفين من JSX الشجرة نفسها، فتضمينهما (أول `
` ← أول ``) يجب أن يصطف. وإلا تغيّر `isActive` سوف يعيد إنشاء الشجرة بأكملها أدناه و [يعيد تعيين حالتها.](/learn/preserving-and-resetting-state) هذا هو السبب، إذا كان يتم إرجاع شجرة JSX مشابهة في كلا الحالتين، فمن الأفضل كتابتهما كجزء واحد من JSX. @@ -793,18 +794,18 @@ lastNameInput.oninput = handleLastNameChange; ``` -هذا النموذج يتغيّر بين وضعين: في وضع التعديل، ترى حقول الإدخال، وفي وضع المعاينة، ترى النتيجة فقط. عنوان الزر يتغيّر ما بين "عدّل" و"احفظ" اعتمادًا على الوضع الذي أنت عليه. عندما تقوم بتغيير حقول الإدخال، رسالة الترحيب في الأسفل يتم تحديثها للوقت الحالي. +هذا النموذج يتغيّر بين وضعين: في وضع التعديل، ترى حقول الإدخال، وفي وضع المعاينة، ترى النتيجة فقط. عنوان الزر يتغيّر ما بين "عدّل" و"احفظ" اعتمادًا على الوضع الذي أنت عليه. عندما تقوم بتغيير حقول الإدخال، يتم تحديث رسالة الترحيب في الأسفل للوقت الحالي. مهمتك هي إعادة تنفيذها بواسطة React في الـsandbox أدناه. لضمان راحتك، تم تحويل التوصيف (markup) إلى JSX, لكن يتعين عليك جعلها تُظهر وتُخفي المدخلات كما تفعل الأصلية. -تأكد من أنها تقوم بتحد النص في الأسفل أيضًا! +تأكد من أنها تقوم بتحديث النص في الأسفل أيضًا! @@ -832,6 +833,7 @@ export default function EditProfile() { ``` ```css +body { direction: rtl; } label { display: block; margin-bottom: 20px; } ``` @@ -859,7 +861,7 @@ export default function EditProfile() { setIsEditing(!isEditing); }}>