นากกายต้นฉบับวัดพื้นที่แตะรอบปุ่มเล็กบนโทรศัพท์โดยไม่ขยายตัวปุ่ม

React Native Pressable: ขยายจุดเริ่มแตะโดยไม่ทำปุ่มดูใหญ่ขึ้น

พี่โชว์Engineering

ไอคอนปิดหน้าต่างที่ดูเรียบร้อยอาจเล็กจนกดพลาดบนจอมือถือครับ Pressable แยกพื้นที่ที่เริ่มแตะได้ (HitRect) ออกจากขนาดภาพของปุ่ม เราจึงเพิ่ม hitSlop รอบปุ่มโดยไม่ทำให้ไอคอนหรือ layout ใหญ่ขึ้น เหมือนวางแผ่นใสรอบปุ่มกริ่งเพื่อให้ปลายนิ้วแตะง่ายขึ้น

เอกสารระบุอีกพื้นที่คือ PressRect ที่ควบคุมว่าหลังแตะแล้วนิ้วเลื่อนออกไปไกลเท่าไรยังถือเป็น press ผ่าน pressRetentionOffset สองอย่างตอบคนละคำถาม: เริ่มแตะได้ตรงไหน กับ เลื่อนไปได้ไกลเท่าไรหลังเริ่ม และพื้นที่แตะไม่ขยายเกินขอบ parent; sibling ที่ z-index สูงกว่ายังมีลำดับเหนือกว่า

ตัวอย่างต่อไปเป็น โค้ด UI สำหรับนำไปวางในโปรเจกต์ React Native ตรวจชื่อ prop และ import จากเอกสาร official แล้ว แต่ไม่ได้รันบน simulator หรืออุปกรณ์ในงานนี้

import { Pressable, Text, View } from "react-native";

export function CloseControl({ onClose }: { onClose: () => void }) {
  return (
    <View style={{ padding: 12 }}>
      <Pressable
        accessibilityRole="button"
        accessibilityLabel="ปิดหน้าต่าง"
        hitSlop={12}
        pressRetentionOffset={20}
        onPress={onClose}
        style={({ pressed }) => ({ opacity: pressed ? 0.6 : 1 })}
      >
        <Text>ปิด</Text>
      </Pressable>
    </View>
  );
}

ทดสอบด้วยนิ้วจริง

hitSlop เพิ่มโอกาสแตะโดน แต่ถ้า parent ชิดปุ่มข้าง ๆ หรือ clip พื้นที่ไว้ ผลอาจไม่ตรงที่คิด ต้องทดสอบ touch target จริงบนจอเล็กและกับ screen reader ด้วย accessibilityRole/accessibilityLabel การเพิ่ม hitSlop สองปุ่มให้ทับกันอาจทำให้ปุ่มที่อยู่เหนือรับ press แทน จึงควรจัด spacing ให้พอด้วย

สำหรับ long press เอกสารบอกว่า onLongPress เริ่มหลังค่า default 500 ms จาก onPressIn และ onPressOut ยังเกิดเมื่อปล่อยนิ้ว อย่าผูก action สำคัญสองแบบเข้ากับ press และ long press โดยไม่ลองลำดับ event บนอุปกรณ์จริง ค่า pressRetentionOffset ควรช่วยการเลื่อนนิ้วเล็กน้อย ไม่ใช่ทำให้ gesture ไปชนบริเวณอื่นครับ

Recap

  • hitSlop ขยายจุดเริ่มแตะ ส่วน pressRetentionOffset คุมการเลื่อนหลังแตะ
  • parent bounds และ z-index ยังคุมผลสุดท้าย
  • เพิ่ม accessibility label ให้ปุ่มที่เป็นไอคอนหรือคำสั้น
  • ตรวจด้วยนิ้วและ screen reader บนอุปกรณ์จริงก่อนรับงาน