From 84887cceba91331e5a6697d16cda00031d8a01b1 Mon Sep 17 00:00:00 2001 From: Nitzan Yizhar Date: Wed, 19 Feb 2025 17:11:17 +0200 Subject: [PATCH 1/6] Added hitslop calculation for button --- src/components/button/ButtonConstants.ts | 7 ++++++ src/components/button/index.tsx | 32 +++++++++++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/components/button/ButtonConstants.ts b/src/components/button/ButtonConstants.ts index f5a7bf516e..5f77f6e869 100644 --- a/src/components/button/ButtonConstants.ts +++ b/src/components/button/ButtonConstants.ts @@ -22,4 +22,11 @@ export const MIN_WIDTH = { LARGE: 90 }; +export const SIZE_TO_VERTICAL_HITSLOP = { + [ButtonSize.xSmall]: 30, + [ButtonSize.small]: 25, + [ButtonSize.medium]: 20, + [ButtonSize.large]: 15 +} as const; + export const DEFAULT_SIZE = ButtonSize.large; diff --git a/src/components/button/index.tsx b/src/components/button/index.tsx index 51631f21f0..1aaf6b623a 100644 --- a/src/components/button/index.tsx +++ b/src/components/button/index.tsx @@ -16,7 +16,7 @@ import { DEFAULT_PROPS, ButtonSizeProp } from './types'; -import {PADDINGS, HORIZONTAL_PADDINGS, MIN_WIDTH, DEFAULT_SIZE} from './ButtonConstants'; +import {PADDINGS, HORIZONTAL_PADDINGS, MIN_WIDTH, DEFAULT_SIZE, SIZE_TO_VERTICAL_HITSLOP} from './ButtonConstants'; export {ButtonSize, ButtonAnimationDirection, ButtonProps}; @@ -35,7 +35,7 @@ class Button extends PureComponent { super(props); } - state = { + state: Record<'size', undefined | number> = { size: undefined }; styles = createStyles(); @@ -152,7 +152,17 @@ class Button extends PureComponent { const {avoidMinWidth, avoidInnerPadding, round, size: propsSize} = this.props; const size = propsSize || DEFAULT_SIZE; - const CONTAINER_STYLE_BY_SIZE: Dictionary = {}; + const CONTAINER_STYLE_BY_SIZE: Record< + string, + Partial<{ + height: number; + width: number; + padding: number; + paddingVertical: number; + paddingHorizontal: number; + minWidth: number; + }> + > = {}; CONTAINER_STYLE_BY_SIZE[Button.sizes.xSmall] = round ? {height: this.state.size, width: this.state.size, padding: PADDINGS.XSMALL} : { @@ -339,6 +349,21 @@ class Button extends PureComponent { return null; } + getAccessibleHitSlop() { + const containerStyle = this.getContainerSizeStyle(); + const width = (containerStyle.width || containerStyle.minWidth || 0); + const widthWithPadding = width + (containerStyle.paddingHorizontal || containerStyle.padding || 0) * 2; + const horizontalHitslop = Math.max(0, (48 - widthWithPadding) / 2); + const verticalHitslop = SIZE_TO_VERTICAL_HITSLOP[this.props.size || DEFAULT_SIZE] / 2; + + return { + top: verticalHitslop, + bottom: verticalHitslop, + left: horizontalHitslop, + right: horizontalHitslop + }; + } + render() { const {onPress, disabled, style, testID, animateLayout, modifiers, forwardedRef, ...others} = this.props; const shadowStyle = this.getShadowStyle(); @@ -373,6 +398,7 @@ class Button extends PureComponent { testID={testID} {...others} ref={forwardedRef} + hitSlop={this.getAccessibleHitSlop()} > {this.props.children} {this.props.iconOnRight ? this.renderLabel() : this.renderIcon()} From 07a98bdc16b110f258f0448653d6dd95bc62888c Mon Sep 17 00:00:00 2001 From: Nitzan Yizhar Date: Wed, 19 Feb 2025 17:14:12 +0200 Subject: [PATCH 2/6] fixed ts error - not sure why it popped now --- src/components/button/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/button/index.tsx b/src/components/button/index.tsx index 1aaf6b623a..258a4f4379 100644 --- a/src/components/button/index.tsx +++ b/src/components/button/index.tsx @@ -277,10 +277,10 @@ class Button extends PureComponent { let style; switch (animateTo) { case 'left': - style = {alignSelf: 'flex-start'}; + style = {alignSelf: 'flex-start'} as const; break; case 'right': - style = {alignSelf: 'flex-end'}; + style = {alignSelf: 'flex-end'} as const; break; default: // 'center' is the default From 9214d713a1a14369d95ab2d9cd075291532721d4 Mon Sep 17 00:00:00 2001 From: Nitzan Yizhar Date: Sun, 23 Feb 2025 14:59:59 +0200 Subject: [PATCH 3/6] Updated snapshots with hitslop --- .../TextFieldScreen.spec.js.snap | 24 +- .../__snapshots__/index.spec.js.snap | 440 ++++++++++++++++++ src/components/button/index.tsx | 11 +- 3 files changed, 467 insertions(+), 8 deletions(-) diff --git a/demo/src/screens/__tests__/__snapshots__/TextFieldScreen.spec.js.snap b/demo/src/screens/__tests__/__snapshots__/TextFieldScreen.spec.js.snap index 234127c0c9..3225c66da1 100644 --- a/demo/src/screens/__tests__/__snapshots__/TextFieldScreen.spec.js.snap +++ b/demo/src/screens/__tests__/__snapshots__/TextFieldScreen.spec.js.snap @@ -3501,6 +3501,14 @@ exports[`TextField Screen renders screen 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 15, + "left": 0, + "right": 0, + "top": 15, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -3831,10 +3839,10 @@ exports[`TextField Screen renders screen 1`] = ` focusable={true} hitSlop={ { - "bottom": 20, - "left": 20, - "right": 20, - "top": 20, + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, } } onClick={[Function]} @@ -4541,6 +4549,14 @@ exports[`TextField Screen renders screen 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} diff --git a/src/components/button/__tests__/__snapshots__/index.spec.js.snap b/src/components/button/__tests__/__snapshots__/index.spec.js.snap index b0b2837880..c545920d3e 100644 --- a/src/components/button/__tests__/__snapshots__/index.spec.js.snap +++ b/src/components/button/__tests__/__snapshots__/index.spec.js.snap @@ -23,6 +23,14 @@ exports[`Button backgroundColor should return backgroundColor according to modif accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -111,6 +119,14 @@ exports[`Button backgroundColor should return backgroundColor according to prop accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -199,6 +215,14 @@ exports[`Button backgroundColor should return defined theme backgroundColor 1`] accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -287,6 +311,14 @@ exports[`Button backgroundColor should return theme disabled color if button is accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -375,6 +407,14 @@ exports[`Button backgroundColor should return undefined if this button is link 1 accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -463,6 +503,14 @@ exports[`Button backgroundColor should return undefined if this button is outlin accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -553,6 +601,14 @@ exports[`Button border radius should return 0 border radius when border radius p accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -641,6 +697,14 @@ exports[`Button border radius should return 0 border radius when button is full accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -729,6 +793,14 @@ exports[`Button border radius should return given border radius when use plain n accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -817,6 +889,14 @@ exports[`Button container size should avoid minWidth limitation if avoidMinWidth accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 10, + "left": 10, + "right": 10, + "top": 10, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -910,6 +990,14 @@ exports[`Button container size should have no padding if avoidInnerPadding prop accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 10, + "left": 0, + "right": 0, + "top": 10, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -1003,6 +1091,14 @@ exports[`Button container size should have no padding of button is a link nor mi accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 10, + "left": 10, + "right": 10, + "top": 10, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -1096,6 +1192,14 @@ exports[`Button container size should have no padding of button is an icon butto accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 10, + "left": 0, + "right": 0, + "top": 10, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -1211,6 +1315,14 @@ exports[`Button container size should reduce padding by outlineWidth in case of accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -1301,6 +1413,14 @@ exports[`Button container size should return style for large button 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -1389,6 +1509,14 @@ exports[`Button container size should return style for large button 2`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -1479,6 +1607,14 @@ exports[`Button container size should return style for medium button 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 10, + "left": 0, + "right": 0, + "top": 10, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -1572,6 +1708,14 @@ exports[`Button container size should return style for medium button 2`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 10, + "left": 0, + "right": 0, + "top": 10, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -1667,6 +1811,14 @@ exports[`Button container size should return style for round button 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -1755,6 +1907,14 @@ exports[`Button container size should return style for small button 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 12.5, + "left": 0, + "right": 0, + "top": 12.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -1848,6 +2008,14 @@ exports[`Button container size should return style for small button 2`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 12.5, + "left": 0, + "right": 0, + "top": 12.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -1943,6 +2111,14 @@ exports[`Button container size should return style for xSmall button 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 15, + "left": 0, + "right": 0, + "top": 15, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -2036,6 +2212,14 @@ exports[`Button container size should return style for xSmall button 2`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 15, + "left": 0, + "right": 0, + "top": 15, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -2131,6 +2315,14 @@ exports[`Button hyperlink should render button as a hyperlink 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -2221,6 +2413,14 @@ exports[`Button icon should apply color on icon 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -2289,6 +2489,14 @@ exports[`Button icon should apply color on icon 2`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -2357,6 +2565,14 @@ exports[`Button icon should apply the right icon color 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -2425,6 +2641,14 @@ exports[`Button icon should apply the right icon color 2`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -2495,6 +2719,14 @@ exports[`Button icon should apply the right icon color 3`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -2565,6 +2797,14 @@ exports[`Button icon should include custom iconStyle provided as a prop 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -2636,6 +2876,14 @@ exports[`Button icon should return icon style according to different variations accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -2706,6 +2954,14 @@ exports[`Button icon should return icon style according to different variations accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -2774,6 +3030,14 @@ exports[`Button icon should return icon style according to different variations accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -2842,6 +3106,14 @@ exports[`Button icon should return the right spacing according to button size wh accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -2930,6 +3202,14 @@ exports[`Button icon should return the right spacing according to button size wh accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 10, + "left": 0, + "right": 0, + "top": 10, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -3023,6 +3303,14 @@ exports[`Button icon should return the right spacing according to button size wh accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 12.5, + "left": 0, + "right": 0, + "top": 12.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -3116,6 +3404,14 @@ exports[`Button icon should return the right spacing according to button size wh accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 15, + "left": 0, + "right": 0, + "top": 15, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -3209,6 +3505,14 @@ exports[`Button label size should return style for large button 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -3297,6 +3601,14 @@ exports[`Button label size should return style for medium button 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 10, + "left": 0, + "right": 0, + "top": 10, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -3390,6 +3702,14 @@ exports[`Button label size should return style for small button 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 12.5, + "left": 0, + "right": 0, + "top": 12.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -3483,6 +3803,14 @@ exports[`Button label size should return style for xSmall button 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 15, + "left": 0, + "right": 0, + "top": 15, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -3576,6 +3904,14 @@ exports[`Button labelColor should return Theme linkColor color for link 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -3664,6 +4000,14 @@ exports[`Button labelColor should return color according to color modifier 1`] = accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -3752,6 +4096,14 @@ exports[`Button labelColor should return color according to color prop 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -3840,6 +4192,14 @@ exports[`Button labelColor should return disabled text color according to theme accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -3928,6 +4288,14 @@ exports[`Button labelColor should return linkColor color for link 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -4016,6 +4384,14 @@ exports[`Button labelColor should return undefined color if this is an icon butt accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -4084,6 +4460,14 @@ exports[`Button link should render button as a link 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -4172,6 +4556,14 @@ exports[`Button outline should render button with an outline 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -4262,6 +4654,14 @@ exports[`Button outline should render button with an outlineColor 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -4352,6 +4752,14 @@ exports[`Button outline should render button with outline and outlineColor 1`] = accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -4442,6 +4850,14 @@ exports[`Button outline should return custom borderWidth according to outlineWid accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -4532,6 +4948,14 @@ exports[`Button outline should return disabled color for outline if button is di accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -4622,6 +5046,14 @@ exports[`Button outline should return undefined when link is true, even when out accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 10, + "right": 10, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} @@ -4710,6 +5142,14 @@ exports[`Button should render default button 1`] = ` accessible={true} collapsable={false} focusable={true} + hitSlop={ + { + "bottom": 7.5, + "left": 0, + "right": 0, + "top": 7.5, + } + } onClick={[Function]} onLayout={[Function]} onResponderGrant={[Function]} diff --git a/src/components/button/index.tsx b/src/components/button/index.tsx index 258a4f4379..77dc47ed39 100644 --- a/src/components/button/index.tsx +++ b/src/components/button/index.tsx @@ -351,11 +351,14 @@ class Button extends PureComponent { getAccessibleHitSlop() { const containerStyle = this.getContainerSizeStyle(); - const width = (containerStyle.width || containerStyle.minWidth || 0); + const isWidthDefined = containerStyle.width !== undefined || containerStyle.minWidth !== undefined; + const width = containerStyle.width || containerStyle.minWidth || 0; const widthWithPadding = width + (containerStyle.paddingHorizontal || containerStyle.padding || 0) * 2; - const horizontalHitslop = Math.max(0, (48 - widthWithPadding) / 2); - const verticalHitslop = SIZE_TO_VERTICAL_HITSLOP[this.props.size || DEFAULT_SIZE] / 2; - + const horizontalHitslop = isWidthDefined ? Math.max(0, (48 - widthWithPadding) / 2) : 10; + const verticalHitslop = + (containerStyle.height + ? Math.max(0, 48 - containerStyle.height) + : SIZE_TO_VERTICAL_HITSLOP[this.props.size || DEFAULT_SIZE]) / 2; return { top: verticalHitslop, bottom: verticalHitslop, From c1b3ba15a472f66415ec82ae0f27b6815752bd1b Mon Sep 17 00:00:00 2001 From: Nitzan Yizhar Date: Mon, 24 Feb 2025 15:18:02 +0200 Subject: [PATCH 4/6] Refactor getAccessibleHitSlop to simplify width calculation and improve hit slop logic --- src/components/button/index.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/button/index.tsx b/src/components/button/index.tsx index 77dc47ed39..de7ea25cd5 100644 --- a/src/components/button/index.tsx +++ b/src/components/button/index.tsx @@ -351,10 +351,10 @@ class Button extends PureComponent { getAccessibleHitSlop() { const containerStyle = this.getContainerSizeStyle(); - const isWidthDefined = containerStyle.width !== undefined || containerStyle.minWidth !== undefined; - const width = containerStyle.width || containerStyle.minWidth || 0; - const widthWithPadding = width + (containerStyle.paddingHorizontal || containerStyle.padding || 0) * 2; - const horizontalHitslop = isWidthDefined ? Math.max(0, (48 - widthWithPadding) / 2) : 10; + const width = + (containerStyle.width || containerStyle.minWidth || 0) + + (containerStyle.paddingHorizontal || containerStyle.padding || 0) * 2; + const horizontalHitslop = width !== 0 ? Math.max(0, (48 - width) / 2) : 10; const verticalHitslop = (containerStyle.height ? Math.max(0, 48 - containerStyle.height) From 8b6de1bdf22e2f4363aedf98da3d4f973cc738dc Mon Sep 17 00:00:00 2001 From: Nitzan Yizhar Date: Thu, 27 Feb 2025 13:39:57 +0200 Subject: [PATCH 5/6] Revert "Refactor getAccessibleHitSlop to simplify width calculation and improve hit slop logic" This reverts commit c1b3ba15a472f66415ec82ae0f27b6815752bd1b. --- src/components/button/index.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/button/index.tsx b/src/components/button/index.tsx index de7ea25cd5..77dc47ed39 100644 --- a/src/components/button/index.tsx +++ b/src/components/button/index.tsx @@ -351,10 +351,10 @@ class Button extends PureComponent { getAccessibleHitSlop() { const containerStyle = this.getContainerSizeStyle(); - const width = - (containerStyle.width || containerStyle.minWidth || 0) + - (containerStyle.paddingHorizontal || containerStyle.padding || 0) * 2; - const horizontalHitslop = width !== 0 ? Math.max(0, (48 - width) / 2) : 10; + const isWidthDefined = containerStyle.width !== undefined || containerStyle.minWidth !== undefined; + const width = containerStyle.width || containerStyle.minWidth || 0; + const widthWithPadding = width + (containerStyle.paddingHorizontal || containerStyle.padding || 0) * 2; + const horizontalHitslop = isWidthDefined ? Math.max(0, (48 - widthWithPadding) / 2) : 10; const verticalHitslop = (containerStyle.height ? Math.max(0, 48 - containerStyle.height) From e073cf3dbb7d13562bc52d8af5c3ddfbac51ce77 Mon Sep 17 00:00:00 2001 From: Nitzan Yizhar Date: Thu, 27 Feb 2025 13:42:17 +0200 Subject: [PATCH 6/6] fix(button): rename variable for clarity in getAccessibleHitSlop method --- src/components/button/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/button/index.tsx b/src/components/button/index.tsx index 77dc47ed39..0000dea214 100644 --- a/src/components/button/index.tsx +++ b/src/components/button/index.tsx @@ -351,10 +351,10 @@ class Button extends PureComponent { getAccessibleHitSlop() { const containerStyle = this.getContainerSizeStyle(); - const isWidthDefined = containerStyle.width !== undefined || containerStyle.minWidth !== undefined; + const isWidthSet = containerStyle.width !== undefined || containerStyle.minWidth !== undefined; const width = containerStyle.width || containerStyle.minWidth || 0; const widthWithPadding = width + (containerStyle.paddingHorizontal || containerStyle.padding || 0) * 2; - const horizontalHitslop = isWidthDefined ? Math.max(0, (48 - widthWithPadding) / 2) : 10; + const horizontalHitslop = isWidthSet ? Math.max(0, (48 - widthWithPadding) / 2) : 10; const verticalHitslop = (containerStyle.height ? Math.max(0, 48 - containerStyle.height)