diff --git a/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm b/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm
index 3b4109c44aec..90448421b399 100644
--- a/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm
+++ b/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm
@@ -260,18 +260,18 @@ - (SharedEventEmitter)getEventEmitterWithAttributeString:(AttributedString)attri
_textStorageAndLayoutManagerWithAttributesString:[self _nsAttributedStringFromAttributedString:attributedString]
paragraphAttributes:paragraphAttributes
size:frame.size];
+
NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
CGFloat fraction;
NSUInteger characterIndex = [layoutManager characterIndexForPoint:point
- inTextContainer:textContainer
- fractionOfDistanceBetweenInsertionPoints:&fraction];
+ inTextContainer:textContainer
+ fractionOfDistanceBetweenInsertionPoints:&fraction];
- // If the point is not before (fraction == 0.0) the first character and not
- // after (fraction == 1.0) the last character, then the attribute is valid.
- if (textStorage.length > 0 && (fraction > 0 || characterIndex > 0) &&
- (fraction < 1 || characterIndex < textStorage.length - 1)) {
+ // Modified: Allow clicks anywhere in the text storage bounds, not just on characters
+ // This fixes the issue where padding areas are not clickable
+ if (textStorage.length > 0 && characterIndex < textStorage.length) {
NSData *eventEmitterWrapper = (NSData *)[textStorage attribute:RCTAttributedStringEventEmitterKey
atIndex:characterIndex
effectiveRange:NULL];
diff --git a/packages/rn-tester/js/examples/Text/TextExample.ios.js b/packages/rn-tester/js/examples/Text/TextExample.ios.js
index 5fdff36d3bc2..87532bdd8ea8 100644
--- a/packages/rn-tester/js/examples/Text/TextExample.ios.js
+++ b/packages/rn-tester/js/examples/Text/TextExample.ios.js
@@ -1574,6 +1574,77 @@ const examples = [
);
},
},
+ {
+ title: 'Text with Padding - Touch Area Test (Issue #54056)',
+ name: 'textPaddingTouchArea',
+ render: function (): React.Node {
+ const [count, setCount] = React.useState(0);
+ return (
+
+
+ Click on the BLUE padding area (not the text itself):
+
+ {
+ setCount(count + 1);
+ }}
+ style={{
+ padding: 50,
+ backgroundColor: 'lightblue',
+ fontSize: 20,
+ marginBottom: 10,
+ }}>
+ Click me!
+
+
+ Touch count: {count}
+
+
+ Expected: Both padding AND text should be clickable
+
+
+ );
+ },
+ },
+ {
+ title: 'Text Padding Boundary Test (Issue #54056)',
+ name: 'textPaddingBoundaryTest',
+ render: function (): React.Node {
+ const [lastTouch, setLastTouch] = React.useState('None');
+ return (
+
+
+ The blue text should only capture touches within its bounds:
+
+ setLastTouch('Container')}>
+ setLastTouch('Text (including padding)')}
+ style={{
+ padding: 30,
+ backgroundColor: 'lightblue',
+ fontSize: 16,
+ }}>
+ Small text with padding
+
+
+
+ Last touch: {lastTouch}
+
+
+ Expected: Pink area outside blue text should show "Container"
+
+
+ );
+ },
+ },
...TextSharedExamples,
];