Pressable va tugmalar — bosish, uzoq bosish, feedback
Muammodan boshlaylik
Tugma yasadingiz. Bosganda ish bajariladi — lekin tugma o'zi hech qanday reaksiya bildirmaydi. Foydalanuvchi bosdimi, yo'qmi — bilmaydi va yana bosadi. Buyurtma ikki marta yuboriladi.
Mobil ilovada teginishga javob (feedback) — majburiy: tugma bosilganda xiralashishi, rangi o'zgarishi yoki to'lqin effekti. Bu darsda bosiladigan elementlarni to'g'ri yasashni o'rganamiz.
Button — eng oddiy, lekin cheklangan
import { Button } from 'react-native';
<Button title="Saqlash" onPress={saqlash} color="#0284c7" />
Har bir platformada tizim tugmasi. Lekin stil berib bo'lmaydi (shrift, padding, border-radius). Real ilovalarda deyarli ishlatilmaydi.
Pressable — zamonaviy yo'l
import { Pressable, Text, StyleSheet } from 'react-native';
<Pressable
onPress={saqlash}
style={({ pressed }) => [styles.tugma, pressed && styles.bosilgan]}
>
<Text style={styles.matn}>Saqlash</Text>
</Pressable>
const styles = StyleSheet.create({
tugma: {
backgroundColor: '#0284c7',
paddingVertical: 14,
paddingHorizontal: 24,
borderRadius: 12,
alignItems: 'center',
},
bosilgan: { opacity: 0.7, transform: [{ scale: 0.98 }] },
matn: { color: 'white', fontSize: 16, fontWeight: '600' },
});
style funksiya bo'lishi mumkin: u { pressed } ni oladi. Barmoq tegib turganda — xira va biroz kichikroq. Oddiy, lekin "jonli" his beradi.
Bolalar ham holatni olishi mumkin:
<Pressable onPress={...}>
{({ pressed }) => (
<Text style={{ color: pressed ? '#0369a1' : '#0284c7' }}>Havola</Text>
)}
</Pressable>
Hodisalar
<Pressable
onPress={() => console.log('bosildi')}
onLongPress={() => console.log('uzoq bosildi')} // kontekst menyu, o'chirish
delayLongPress={400}
onPressIn={() => console.log('tegdi')}
onPressOut={() => console.log("qo'yib yubordi")}
disabled={yuklanmoqda}
hitSlop={10}
/>
hitSlop — bosish maydonini kengaytirish
Kichik ikonka (20×20) ni barmoq bilan aniq bosish qiyin. hitSlop={10} — ko'rinishni o'zgartirmasdan har tomonga 10 birlik bosiladigan maydon qo'shadi.
[!TIP] Apple va Google tavsiyasi: bosiladigan element kamida 44×44 (iOS) / 48×48 (Android) bo'lsin. Kichik ikonkalar uchun
hitSlopyokipadding.
Android to'lqin effekti
<Pressable android_ripple={{ color: 'rgba(0,0,0,0.1)' }} style={styles.band}>
<Text>Sozlamalar</Text>
</Pressable>
Android foydalanuvchilariga tanish "ripple". iOS da e'tiborsiz qoldiriladi — u yerda pressed holatidagi opacity ishlatiladi.
Qayta ishlatiladigan Tugma komponenti
// components/Tugma.tsx
import { Pressable, Text, ActivityIndicator, StyleSheet, PressableProps } from 'react-native';
type Props = PressableProps & {
matn: string;
turi?: 'asosiy' | 'ikkinchi' | 'xavfli';
yuklanmoqda?: boolean;
};
export function Tugma({ matn, turi = 'asosiy', yuklanmoqda, disabled, ...props }: Props) {
const ochiq = disabled || yuklanmoqda;
return (
<Pressable
accessibilityRole="button"
accessibilityState={{ disabled: !!ochiq, busy: !!yuklanmoqda }}
disabled={ochiq}
style={({ pressed }) => [
styles.asos,
styles[turi],
pressed && { opacity: 0.8 },
ochiq && { opacity: 0.5 },
]}
{...props}
>
{yuklanmoqda
? <ActivityIndicator color={turi === 'ikkinchi' ? '#0284c7' : 'white'} />
: <Text style={[styles.matn, turi === 'ikkinchi' && { color: '#0284c7' }]}>{matn}</Text>}
</Pressable>
);
}
const styles = StyleSheet.create({
asos: { paddingVertical: 14, borderRadius: 12, alignItems: 'center', minHeight: 50, justifyContent: 'center' },
asosiy: { backgroundColor: '#0284c7' },
ikkinchi: { backgroundColor: 'white', borderWidth: 1, borderColor: '#0284c7' },
xavfli: { backgroundColor: '#dc2626' },
matn: { color: 'white', fontSize: 16, fontWeight: '600' },
});
<Tugma matn="Buyurtma berish" onPress={buyurtma} yuklanmoqda={yuborilmoqda} />
<Tugma matn="Bekor qilish" turi="ikkinchi" onPress={() => router.back()} />
yuklanmoqda paytida tugma disabled — ikki marta yuborish muammosi hal (boshidagi muammo).
accessibilityRole="button" — ekran o'quvchisi "Buyurtma berish, tugma" deb o'qiydi.
Eski komponentlar
Eski kodda ko'rasiz:
| Komponent | Nima qiladi |
|---|---|
TouchableOpacity |
Bosilganda xiralashadi |
TouchableHighlight |
Bosilganda fon rangi o'zgaradi |
TouchableWithoutFeedback |
Hech qanday effektsiz |
Ular hali ishlaydi, lekin rasmiy tavsiya — Pressable: barcha imkoniyatlar bitta komponentda va moslashuvchanroq.
Nima uchun shunday?
Nima uchun React Native da tugmalar vebdagi <button> kabi tayyor ko'rinishga ega emas?
Chunki "tugma" har bir platformada boshqacha ko'rinadi va har bir ilova o'z dizayn tizimiga ega. Agar React Native platformaning standart tugmasini majburlasa — ilovalar bir xil ko'rinardi va dizaynerlar cheklanib qolardi (Button aynan shunday — shuning uchun kam ishlatiladi). Pressable esa "bosish mantig'i" ni ko'rinishdan ajratadi: u faqat teginishni boshqaradi, ko'rinish — butunlay sizning qo'lingizda.
Xulosa
Eslab qoling:
Button— stilsiz, cheklangan; real ilovadaPressablestyle={({ pressed }) => [...]}— bosilgandagi feedbackonPress,onLongPress,disabled,hitSlop,android_ripple- Bosiladigan maydon — kamida 44-48 birlik
- Yuklanayotganda
disabled— ikki marta yuborishdan himoya accessibilityRole="button",accessibilityStateTouchableOpacity— eski; yangi koddaPressable
Keyingi dars
11-dars: Modal, Alert, ActivityIndicator, Switch