المكون Text في React Native
مكوّن React لعرض النصوص.
يدعم المكوّن Text
النصوص المتداخلة والتنسيق ومعالجة اللمسات.
في المثال التالي، يرث العنوان المتداخل والنص الأساسي خاصيّة fontFamily
من styles.baseText
، لكن العنوان يوفّر أنماطا إضافية خاصة به. سيتم تكديس العنوان والنص الأساسي فوق بعضهما البعض عند الوصول إلى محارف الأسطر الجديدة (literal newlines):
import React, { useState } from "react";
import { Text, StyleSheet } from "react-native";
const TextInANest = () => {
const [titleText, setTitleText] = useState("Bird's Nest");
const bodyText = "This is not really a bird nest.";
const onPressTitle = () => {
setTitleText("Bird's Nest [pressed]");
};
return (
<Text style={styles.baseText}>
<Text style={styles.titleText} onPress={onPressTitle}>
{titleText}
{"\n"}
{"\n"}
</Text>
<Text numberOfLines={5}>{bodyText}</Text>
</Text>
);
};
const styles = StyleSheet.create({
baseText: {
fontFamily: "Cochin"
},
titleText: {
fontSize: 20,
fontWeight: "bold"
}
});
export default TextInANest;
import React, { Component } from "react";
import { Text, StyleSheet } from "react-native";
class TextInANest extends Component {
constructor(props) {
super(props);
this.state = {
titleText: "Bird's Nest",
bodyText: "This is not really a bird nest."
};
}
onPressTitle = () => {
this.setState({ titleText: "Bird's Nest [pressed]" });
};
render() {
return (
<Text style={styles.baseText}>
<Text
style={styles.titleText}
onPress={this.onPressTitle}
>
{this.state.titleText}
{"\n"}
{"\n"}
</Text>
<Text numberOfLines={5}>{this.state.bodyText}</Text>
</Text>
);
}
}
const styles = StyleSheet.create({
baseText: {
fontFamily: "Cochin"
},
titleText: {
fontSize: 20,
fontWeight: "bold"
}
});
export default TextInANest;
النصوص المتداخلة
يتيح كل من نظامي iOS وAndroid عرض نص منسق عن طريق التعليق (annotating) على نطاقاتِ سلسلةٍ نصيّة بتنسيقات محددة لجعله نصًّا غامقًا أو ملونًا مثلًا (NSAttributedString
على iOS وSpannableString
على Android). عمليًّا، هذا شاق للغاية. في React Native، يُمكن استخدام صيغة الويب لهذا الغرض، حيث يمكنك تدخيل النص لتحقيق التأثير نفسه.
إليك المثال التالي (تجربة حية):
import React from 'react';
import { Text, StyleSheet } from 'react-native';
const BoldAndBeautiful = () => {
return (
<Text style={styles.baseText}>
I am bold
<Text style={styles.innerText}> and red</Text>
</Text>
);
};
const styles = StyleSheet.create({
baseText: {
fontWeight: 'bold'
},
innerText: {
color: 'red'
}
});
export default BoldAndBeautiful;
وراء الكواليس، يُحوِّل React Native هذا إلى سلسلة NSAttributedString
نصيّة مسطحة أو سلسلة SpannableString
نصيّة تحتوي على المعلومات التالية:
"I am bold and red"
0-9: bold
9-17: bold, red
الحاويات
عنصرُ <Text>
فريدٌ (unique) بالنسبة إلى التخطيط (relative to layout): لم يعد كل شيء بداخله يستخدم تخطيط flexbox بل يستخدم تخطيط النص. هذا يعني أن العناصر الموجودة داخل عنصر <Text>
لم تعد مستطيلة الشكل، ولكنها تلتف (wrap) عندما تصل إلى نهاية السطر.
<Text>
<Text>First part and </Text>
<Text>second part</Text>
</Text>
// Text حاوية
// سيكون النص في نفس السطر إن سمحت المساحة بذلك
// |First part and second part|
// إن نفِدَت المساحة، فسيتصرف النص وكأنه كتلة واحدة
// |First part |
// |and second |
// |part |
<View>
<Text>First part and </Text>
<Text>second part</Text>
</View>
// View حاوية
// كل نصّ يُعدّ كتلة منفصلة
// |First part and|
// |second part |
// إن نفِدَت المساحة، سيجري النص داخل كتلته الخاصة
// |First part |
// |and |
// |second part|
وراثة أنماط محدودة
على الويب، الطريقة المعتادة لتعيين خطٍّ وحجم خطٍّ للمستند بأكمله هي الاستفادة من خصائص CSS الموروثة كما يلي:
html {
font-family: 'lucida grande', tahoma, verdana, arial, sans-serif;
font-size: 11px;
color: #141823;
}
سوف ترث جميع العناصر الموجودة في المستند هذا الخط ما لم تُحدِّد هي (أي العناصر) أو أحد عناصرها الأجداد قاعدةً جديدة.
في React Native، الأمر أشدّ صرامة، إذ عليك تغليف جميع العقد النصية (text nodes) داخل مكوّن <Text>
. لا يمكن وضع عقدة نصية مباشرة أسفل مكوّن <View>
.
// سيرمي هذا خطأً، لا يمكن وضع عقدة نصية داخل المكون
// <View>
<View>
Some text
</View>
// هذا هو الصواب
<View>
<Text>
Some text
</Text>
</View>
ستفقد أيضًا القدرة على تعيين خطٍّ افتراضيّ لشجرة فرعية بالكامل. و الخاصيّة fontFamily
لا تقبل سوى اسم خط واحد، وهذا مختلف عن الخاصية font-family
في CSS. الطريقة الموصى بها لاستخدام خطوطٍ وأحجامٍ موحّدة عبر تطبيقك هي إنشاء مكوّن باسم MyAppText
مثلًا يتضمن هذه الخاصيات واستخدام هذا المكون في تطبيقك. يمكنك أيضًا استخدام هذا المكون لإنشاء مكونات أكثر تحديدًا مثل مكوّنِ MyAppHeaderText
لأنواع أخرى من النصوص.
<View>
<MyAppText>
Text styled with the default font for the entire application
</MyAppText>
<MyAppHeaderText>Text styled as a header</MyAppHeaderText>
</View>
بافتراض أن MyAppText
مكونٌ لا يعرض سوى مكوناته الأبناء داخل مُكون Text
مع تنسيق محدّد، فيمكن تعريف المكوّن MyAppHeaderText
على النحو التالي:
class MyAppHeaderText extends Component {
render() {
return (
<MyAppText>
<Text style={{ fontSize: 20 }}>
{this.props.children}
</Text>
</MyAppText>
);
}
}
تركيب المكوّن MyAppText
بهذه الطريقة يضمن الحصول على الأنماط من أحد مكوّنات المستوى الأعلى، مع إمكانية تعديلها أو إضافة أنماط جديدة في حالات استخدامٍ محددة.
مفهوم وراثة الأنماط ما زال موجودًا في React Native، ولكنّه يقتصر على أشجار النصوص الفرعيّة (text subtrees). في هذه الحالة، سيكون الجزء الثاني غامقًا وأحمرًا:
<Text style={{fontWeight: 'bold'}}>
I am bold
<Text style={{color: 'red'}}>and red</Text>
</Text>
نعتقد أن هذه الطريقة الأكثر تقييدًا لتنسيق النصوص ستوفر تطبيقاتٍ أفضل:
- (المطور) صُمِّمَت مكوّنات React مع أخذ العزل التام بعين الاعتبار: يجب أن تكون قادرًا على إسقاط مكون في أي مكان في تطبيقك، واثقًا من أنه طالما أن الخاصيّات متشابهة، فستبدو وتتصرف بنفس الطريقة. خصائص النصوص القادرة على الوراثة من خارج الخاصيات ستكسر هذا العزل.
- (المُطبِّق [Implementor]) تطبيق شيفرة React Native تُبسَّط كذلك: لا نحتاج إلى حقلِ
fontFamily
في كل عنصرٍ، ولا نحتاج إلى عبور الشجرة إلى الجذر في كل مرة تُعرَض فيها عقدة نصية. لا تُشفَّر وراثة النمط إلا داخل مكون النص الأصيل ولا يُسرَّبُ إلى مُكوِّنات أخرى أو إلى النظام نفسه.
الخاصيات
accessible
عندما تكون قيمتُها القيمةَ true
(القيمة الافتراضية)، فهذا يُشير إلى أنّ العرضَ هو عنصرُ سهل الوصول (accessibility element) لمن يملك أي إعاقة (سواءً دائمة أو مؤقتة). افتراضيًّا، جميع العناصر القابلة للمس هي عناصر مهيأة لتكون سهلة الوصول.
انظر دليل إمكانية الوصول لمزيد من المعلومات.
النوع | مطلوب |
---|---|
قيمة منطقيّة | لا |
accessibilityLabel
يستبدِل النص الذي يقرأه قارئ الشاشة عندما يتفاعل المستخدم مع العنصر. افتراضيًا، يُنشأ الملصق (label) عن طريق العبور عبر جميع المكوّنات الأبناء وتجميع كافة العقد النصية مفصولةً بمسافة.
النوع | مطلوب |
---|---|
سلسلة نصيّة | لا |
accessibilityHint
يُساعد تلميح سهولة الوصول (accessibility hint) المستخدمينَ على فهم ما سيحدث عندما يقومون بإجراءٍ على عنصر مهيئأة ليكون سهل الوصول عندما لا تكون النتيجة واضحةً من العنوان المساعد لسهولة الوصول accessibilityLabel
.
النوع | مطلوب |
---|---|
سلسلة نصيّة | لا |
accessibilityRole
تقوم الخاصيّة accessibilityRole
بتوصيل الغرض من المكون (أي دَوره) إلى المستخدم عبر تقنيةٍ مساعدة (assistive technology) مثل قارئات الشاشة.
تترجم هذه الأدوار إلى تقنية Accessibility Traits المقابلة على نظام iOS. الزر Image يملك الوظيفة نفسها كما لو أن صفته (دوره) حُدِّد إلى 'image' أو 'button'. انظر دليل سهولة الوصول لمزيد من التفاصيل.
أما على نظام Android، فلهذه الأدوار قيمة مقابلة على تقنية TalkBack بالمثل كما في نظام iOS الذي تحدثنا عنه آنفًا.
النوع | مطلوب |
---|---|
النوع accessibilityRole | لا |
accessibilityState
تحدد قيمة هذه الخاصية التقنيةٍ المساعدة مثل قارئ الشاشة بحالة العنصر المحدد (المركز) عليه آنذاك، ويمكنك أن لا تحدد أي حالة أو تحدد حالة واحدة أو عدة حالات بتمريرها عبر كائن مثل {selected: true, disabled: true}
.
النوع | مطلوب |
---|---|
AccessibilityState | لا |
adjustsFontSizeToFit
تُحدِّد ما إذا كان يجب تصغير الخطوط تلقائيًا لتناسب قيود النمط المُعطاة. القيمة الافتراضية false
.
النوع | مطلوب | المنصة |
---|---|---|
قيمة منطقيّة | لا | iOS |
allowFontScaling
لتحديد ما إذا كان يجب تغيير حجم الخطوط لاحترام إعدادات حجم النص الخاصة بإمكانية الوصول. القيمة الافتراضية هي true
.
النوع | مطلوب |
---|---|
قيمة منطقيّة | لا |
android_hyphenationFrequency
تحدد تكرار عملية فصل الكلمات الأجنبية بفاصلة (شرطة - ) التلقائية لتُستخدَم متى ما سُمِح بفصل الكلمات الواحدة بفاصل على واجهة Android API المستوى 23 وما بعد. القيمة الافتراضية 'none'.
النوع | مطلوب | المنصة |
---|---|---|
('none', 'full', 'balanced', 'high') | لا | Android API Level 23+ |
dataDetectorType
يُحدِّد أنواع البيانات المحوَّلَة إلى عناوين URL قابلةٍ للنقر في عنصر النص. افتراضيًا، لا يتم اكتشاف أي أنواع بيانات.
يمكنك تحديد نوع واحد فقط.
القيم المحتملة للخاصيّة dataDetectorType
موضحة بالجدول. القيمة الافتراضية 'none'.
النوع | مطلوب | المنصة |
---|---|---|
('phoneNumber', 'link', 'email', 'none', 'all') | لا | Android |
disabled
يُحدّد الحالة المعطلة لعرض النص لأغراض الاختبار. القيمة الافتراضية false
.
النوع | مطلوب | المنصة |
---|---|---|
قيمة منطقيّة | لا | Android |
ellipsizeMode
عندما تُعيَّن قيمة للخاصيّة numberOfLines
، فإنّ هذه الخاصيَّة تُحدِّد كيفية اقتطاع النص. يجب تعيين قيمة للخاصيّة numberOfLines
بالتزامن مع هذه الخاصيّة.
يمكن أن تحمل أحد القيم التالية:
-
head
: يُعرَض السطر بحيث توضع النهاية في الحاوية ويتم الإشارة إلى النص المفقود في بداية السطر بواسطة علامة إضمار. أي ...wxyz
مثلا. -
middle
: يُعرض السطر بحيث يتم احتواء البداية والنهاية في الحاوية ويتم الإشارة إلى النص المفقود في المنتصف بواسطة علامة إضمار. أي ab...yz
مثلا. -
tail
: (القيمة الافتراضية) يتم عرض السطر بحيث يتم احتواء البداية في الحاوية ويتم الإشارة إلى النص المفقود في نهاية السطر بواسطة علامة إضمار. أي abcd...
مثلا. -
clip
: لا يتم رسم الأسطر بعد حافة حاوية النص.
القيمة الافتراضيّة هي tail
.
إن ضبط قيمة الخاصة numberOfLines في نظام Android إلى قيمة أعلى من 1، فلن تعمل سوى القيمة 'tail'
مع هذه الخاصية.
النوع | مطلوب |
---|---|
('head', 'middle', 'tail', 'clip') | لا |
maxFontSizeMultiplier
يُحدد أكبر مقياس ممكن يمكن أن يصل إليه الخط عند تمكين الخاصيّة allowFontScaling
. القيم الممكنة:
-
null/undefined
: (القيمة الافتراضية): ترث من العقدة الأب أو القيمة الافتراضيّة العامّة (0
).
-
0
: لا حدَّ أقصى، وتَجاهَل قيمة الأب أو القيمة الافتراضية العامّة.
-
>= 1
: تُعيِّن قيمةَ الخاصيّةِ maxFontSizeMultiplier
الخاصة بهذه العقدة إلى هذه القيمة.
النوع | مطلوب |
---|---|
عدد | لا |
minimumFontScale
يُحدِّد أصغر مقياس ممكن يمكن أن يصل إليه الخط عند تمكين الخاصية adjustsFontSizeToFit
. (القيم من 0.01
إلى 1.0
).
النوع | مطلوب | المنصة |
---|---|---|
عدد | لا | iOS |
nativeID
تُستخدَم لتحديد موقع هذا العرض من الشيفرة الأصيلة.
النوع | مطلوب |
---|---|
سلسلة نصيّة | لا |
numberOfLines
تُستخدم لاقتطاع النص باستخدام علامة إضمار بعد حساب تخطيط النص، بما في ذلك التفاف الأسطر، بحيث لا يتجاوز العدد الإجمالي للخطوط هذا العدد.
تُستخدم هذه الخاصيّة بشكل شائع مع الخاصية ellipsizeMode
. القيمة الافتراضية 0.
النوع | مطلوب |
---|---|
عدد | لا |
onLayout
دالةٌ تُستدعى عند وصل العنصر (تصييره أول مرة) أو حدوث تغيّرات في التخطيط.
النوع | مطلوب |
---|---|
دالة
({ nativeEvent: LayoutEvent }) => void |
لا |
onLongPress
تُستدعى هذه الدالة عند الضغط لفترة طويلة.
النوع | مطلوب |
---|---|
دالة
({ nativeEvent: PressEvent }) => void |
لا |
onMoveShouldSetResponder
هل هذا العرض "يتطلّب" الاستجابة للّمس (touch responsiveness)؟ تُستدعى هذه الدالة في كل حركة لمسٍ على المكوّن View
عندما لا يكون المستجيب (the responder).
النوع | مطلوب |
---|---|
دالة
({ nativeEvent: PressEvent }) => void |
لا |
onPress
تُستدعى هذه الدالة عند الضغط على العرض.
النوع | مطلوب |
---|---|
دالة
({ nativeEvent: PressEvent }) => void |
لا |
onResponderGrant
يستجيب العرض الآن لأحداث اللمس. هذا هو الوقت المناسب لإبراز وإظهار ما يحدث للمستخدم.
النوع | مطلوب |
---|---|
دالة
({ nativeEvent: PressEvent }) => void |
لا |
onResponderMove
عندما يُحرِّك المستخدمُ إصبعه.
النوع | مطلوب |
---|---|
دالة
({ nativeEvent: PressEvent }) => void |
لا |
onResponderRelease
دالةٌ تُستدعى عند نهاية اللمس.
النوع | مطلوب |
---|---|
دالة
({ nativeEvent: PressEvent }) => void |
لا |
onResponderTerminate
دالةٌ تُستدعى عندما يُأخَذ المستجيب من العرض. قد تأخذه عروض أخرى بعد استدعاء onResponderTerminationRequest
، أو قد يأخذه نظام التشغيل دون طلب (يحدث هذا مع مركز التحكم أو مركز التنبيهات على iOS مثلًا).
النوع | مطلوب |
---|---|
دالة
({ nativeEvent: PressEvent }) => void |
لا |
onResponderTerminationRequest
دالة تُستدعى عندما يريد عرضٌ آخر أن يصبح مستجيبًا ويطلب من هذا العرض تحرير المستجيب الخاص به. إعادة القيمة true
يسمح بإطلاقه.
النوع | مطلوب |
---|---|
دالة
({ nativeEvent: PressEvent }) => void |
لا |
onStartShouldSetResponderCapture
إذا أراد مُكوِّن View
منع مُكوِّنِ View
ابنٍ من أن يصبح مستجيبًا عند بداية اللمس، فيجب أن يحتويَ على هذا المعالج مُعيدًا القيمة true
.
النوع | مطلوب |
---|---|
دالة
({ nativeEvent: PressEvent }) => void |
لا |
onTextLayout
تُستدعى عندما حدوث أي تغيير في تخطيط النص Text.
pressRetentionOffset
عند تعطيل واجهة التمرير (scroll view)، تُحدِّد هذه الخاصيّة مدى المسافة التي يمكن أن تتحرك بها اللمسة بعيدًا عن الزر قبل إلغاء تنشيطه. بمجرد إلغاء تنشيط الزر، حاول تحريك لمستك للخلف وسترى أن الزر قد نُشِّطَ مرة أخرى! حركه للخلف وللأمام عدة مرات أثناء تعطيل عرض التمرير. تأكد من تمرير ثابتٍ لتقليل تخصيصات الذاكرة.
النوع | مطلوب |
---|---|
كائن Rect، عدد number | لا |
selectable
يتيح للمستخدم تحديد النص لاستخدام وظيفة النسخ واللصق الأصيلتين. القيمة الافتراضية false
.
النوع | مطلوب |
---|---|
قيمة منطقيّة | لا |
selectionColor
لون إبراز (highlight color) النص.
النوع | مطلوب | المنصة |
---|---|---|
لون | لا | Android |
style
تنسيق النص.
النوع | مطلوب |
---|---|
خاصيات تنسيق النص Text Style, خاصيات تنسيق الواجهة View Style Props | لا |
suppressHighlighting
عندما تكون قيمتها القيمةَ true
، لا يُجرى أي تغيير مرئي عند الضغط على النص. افتراضيًا، يُبرِز شكلٌ بيضاوي رمادي النصَّ عند الضغط لأسفل. القيمة الافتراضية false
.
النوع | مطلوب | المنصة |
---|---|---|
قيمة منطقيّة | لا | iOS |
testID
يُستخدَم لتحديد موقع هذا العرض في الاختبارات الشاملة (end-to-end tests).
النوع | مطلوب |
---|---|
سلسلة نصيّة | لا |
textBreakStrategy
تضبط استراتيجية فاصل النص (text break) على المستوى 23 من واجهة برمجة تطبيقات Android أو أحدث، القيم المحتملة هي: highQuality
، simple
(القيمة الافتراضية)، balanced
.
النوع | مطلوب | المنصة |
---|---|---|
('simple', 'highQuality', 'balanced') | لا | Android |
تعريفات النوع
TextLayout
الكائن TextLayout
هو جزء من رد النداء TextLayoutEvent
(مشروح تاليًا) ويحوي بيانات القياس لسطر النص Text
.
إليك مثال:
{
capHeight: 10.496,
ascender: 14.624,
descender: 4,
width: 28.224,
height: 18.624,
xHeight: 6.048,
x: 0,
y: 0
}
الخاصيات:
الاسم | النوع | مطلوب | الوصف |
---|---|---|---|
ascender | عدد | لا | ارتفاع السطر الصاعد / المرتفع (line ascender height) بعد تغيير تخطيط النص. |
capHeight | عدد | لا | ارتفاع الحرف الكبير عن خط الأساس (baseline). |
descender | عدد | لا | ارتفاع النازل / المنخفض (line ascender height) بعد تغيير تخطيط النص. |
height | عدد | لا | ارتفاع السطر بعد تغيير تخطيط النص. |
width | عدد | لا | عرض السطر بعد تغيير تخطيط النص. |
x | عدد | لا | إحداثيات X للسطر ضمن مكون النص Text. |
xHeight | عدد | لا | المسافية بين الخط الأساس ومتوسط السطر (حجم الجزء الأساسي corpus size). |
y | عدد | لا | إحداثيات Y للسطر ضمن مكون النص Text. |
TextLayoutEvent
يُعاد الكائن TextLayoutEvent
من دالة رد نداء نتيجة حدوثٍ تغيير في تخطيط المكون، وتحوي مفتاحًا يدعى lines
قيمته مصفوفة من كائنات TextLayout
مقابلة لكل سطر جرى تصييره.
إليك مثال:
{
lines: [
TextLayout,
TextLayout
// ...
];
target: 1127;
}
الخاصيات:
الاسم | النوع | مطلوب | الوصف |
---|---|---|---|
lines | مصفوفة من كائنات TextLayout
|
لا | يوفر معلومات عن تخطيط النص TextLayout لكل سطر جرى تصييره.
|
target | عدد | لا | مُعرِّف العقدة للعنصر. |