From d422f332905029cc91aa8307540b228d50efd5f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Thu, 12 Mar 2026 14:00:28 +0100 Subject: [PATCH 1/7] Update SKILL --- skills/gesture-handler-3-migration/SKILL.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/skills/gesture-handler-3-migration/SKILL.md b/skills/gesture-handler-3-migration/SKILL.md index 888238fe2e..45e3bc5c4c 100644 --- a/skills/gesture-handler-3-migration/SKILL.md +++ b/skills/gesture-handler-3-migration/SKILL.md @@ -169,6 +169,8 @@ The implementation of buttons has been updated, resolving most button-related is `PureNativeButton` has been removed. If encountered, inform the user that it has been removed and let them decide how to handle that case. They can achieve similar functionality with other buttons. +When migrating buttons, you should use `Clickable` component instead. To replace `BaseButton` use `Clickable` with default props, to replace `RectButton` use `Clickable` with `underlayInitialOpacity={0.7}` and to replace `BorderlessButton` use `Clickable` with `activeOpacity={0.3}`. + Other components have also been internally rewritten using the new hook API but are exported under their original names, so no changes are necessary on your part. However, if you need to use the previous implementation for any reason, the legacy components are also available and are prefixed with `Legacy`, e.g., `ScrollView` is now available as `LegacyScrollView`. Rename all instances of createNativeWrapper to legacy_createNativeWrapper. This includes both the import statements and the function calls. From ff74f2b806055b626d8faf0dddcfe770d26189f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Thu, 12 Mar 2026 16:39:31 +0100 Subject: [PATCH 2/7] Docs --- .../docs/components/buttons.mdx | 4 + .../docs/components/clickable.mdx | 239 ++++++++++++++++++ .../docs/guides/upgrading-to-3.mdx | 10 +- 3 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 packages/docs-gesture-handler/docs/components/clickable.mdx diff --git a/packages/docs-gesture-handler/docs/components/buttons.mdx b/packages/docs-gesture-handler/docs/components/buttons.mdx index 041d387fbe..7b895a26f5 100644 --- a/packages/docs-gesture-handler/docs/components/buttons.mdx +++ b/packages/docs-gesture-handler/docs/components/buttons.mdx @@ -9,6 +9,10 @@ import GifGallery from '@site/components/GifGallery'; import HeaderWithBadges from '@site/src/components/HeaderWithBadges'; +:::danger +Button components described in this section are deprecated and will be removed in the future. Please use [`Clickable`](/docs/components/clickable) instead. +::: + diff --git a/packages/docs-gesture-handler/docs/components/clickable.mdx b/packages/docs-gesture-handler/docs/components/clickable.mdx new file mode 100644 index 0000000000..82c577b57b --- /dev/null +++ b/packages/docs-gesture-handler/docs/components/clickable.mdx @@ -0,0 +1,239 @@ +--- +id: clickable +title: Clickable +sidebar_label: Clickable +--- + +import HeaderWithBadges from '@site/src/components/HeaderWithBadges'; + +`Clickable` is a new component introduced in Gesture Handler 3, designed to replace the previous button components. It provides a more flexible and customizable way to create buttons with native touch handling. + +With `Clickable`, you can decide whether to animate whole component, or just the underlay. This allows to easily recreate both `RectButton` and `BorderlessButton` effects with the same component. + +It also provides consistent behavior across platforms, and resolves most of the button-related issues that were present in previous versions. On android, you can decide whether to use native ripple effect, or JS based animation with Animated API + +## Replacing old buttons + +If you were using `RectButton`, or `BorderlessButton` in your app, you can easily replace them with `Clickable`. Check out full code in [example](#example) section below. + +### RectButton + +To replace `RectButton` with `Clickable`, simply add `underlayActiveOpacity={0.105}` to your `Clickable` component. This will animate the underlay when the button is pressed. + +```tsx + +``` + +### BorderlessButton + +Replacing `BorderlessButton` with `Clickable` is as easy as replacing `RectButton`. Just add `activeOpacity={0.3}` to your `Clickable` component. This will animate the whole component when the button is pressed. + +```tsx + +``` + +## Example + +In this example we will demonstrate how to recreate `RectButton` and `BorderlessButton` effects using `Clickable` component. + + + { + console.log('BaseButton built with Clickable'); + }} + style={[styles.button, { backgroundColor: '#7d63d9' }]}> + BaseButton + + + { + console.log('RectButton built with Clickable'); + }} + style={[styles.button, { backgroundColor: '#4f9a84' }]} + underlayActiveOpacity={0.105}> + RectButton + + + { + console.log('BorderlessButton built with Clickable'); + }} + style={[styles.button, { backgroundColor: '#5f97c8' }]} + activeOpacity={0.3}> + BorderlessButton + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + + gap: 20, + }, + button: { + width: 200, + height: 70, + borderRadius: 15, + alignItems: 'center', + justifyContent: 'center', + }, + buttonText: { + color: 'white', + fontSize: 14, + fontWeight: '600', + }, +}); +`}/> + + +## Properties + +### exclusive + +```ts +exclusive?: boolean; +``` + +Defines if more than one button could be pressed simultaneously. By default set to `true`. + + +### touchSoundDisabled + + +```ts +touchSoundDisabled?: boolean; +``` + +If set to `true`, the system will not play a sound when the button is pressed. + +### onPressIn + +```ts +onPressIn?: (pointerInside: boolean) => void; +``` + +Triggered when the button gets pressed (analogous to `onPressIn` in `TouchableHighlight` from RN core). + +### onPressOut + +```ts +onPressOut?: (pointerInside: boolean) => void; +``` + +Triggered when the button gets released (analogous to `onPressOut` in `TouchableHighlight` from RN core). + +### onPress + +```ts +onPress?: (pointerInside: boolean) => void; +``` + +Triggered when the button gets pressed (analogous to `onPress` in `TouchableHighlight` from RN core). + +### onLongPress + +```ts +onLongPress?: () => void; +``` + +Triggered when the button gets pressed for at least [`delayLongPress`](#delaylongpress) milliseconds. + + +### onActiveStateChange + +```ts +onActiveStateChange?: (active: boolean) => void; +``` + +Triggered when the button transitions between active and inactive states. It passes the current active state as a boolean variable to the method as the first parameter. + +### delayLongPress + +```ts +delayLongPress?: number; +``` + +Defines the delay, in milliseconds, after which the [`onLongPress`](#onlongpress) callback gets called. By default set to `600`. + +### underlayColor + +```ts +underlayColor?: string; +``` + +Background color of underlay. + +### underlayActiveOpacity + +```ts +underlayActiveOpacity?: number; +``` + +Defines the opacity of underlay when the button is active. + +### activeOpacity + +```ts +activeOpacity?: number; +``` + +Defines the opacity of the whole component when the button is active. + +### underlayInitialOpacity + +```ts +underlayInitialOpacity?: number; +``` + +Defines the initial opacity of underlay when the button is inactive. By default set to `0`. + +### initialOpacity + +```ts +initialOpacity?: number; +``` + +Defines the initial opacity of the whole component when the button is inactive. By default set to `1` + + +### androidRipple + + + + +Configuration for the ripple effect on Android. If not provided, the ripple effect will be disabled. If `{}` is provided, the ripple effect will be enabled with default configuration. diff --git a/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx b/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx index e5b0812531..45c77c9527 100644 --- a/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx +++ b/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx @@ -246,7 +246,15 @@ code2={ ### Buttons -The implementation of buttons has been updated, resolving most button-related issues. They have also been internally rewritten to utilize the new hook API. The original button components are still accessible but have been renamed with the prefix `Legacy`, e.g., `RectButton` is now available as `LegacyRectButton`. +RNGH3 introduces the [`Clickable`](/docs/components/clickable) component — a flexible, unified replacement for all previous button types. While `Clickable` shares the same logic as our standard buttons, it offers a more customizable API. + +To help you migrate, here is the current state of our button components: + +- [`Clickable`](/docs/components/clickable) - The recommended component for all new development. + +- Standard Buttons (Deprecated) - `BaseButton`, `RectButton` and `BorderlessButton` are still available but are now deprecated. They have been internally rewritten using the new Hooks API to resolve long-standing issues. + +- Legacy Buttons (Deprecated): The original, pre-rewrite versions are still accessible for backward compatibility but have been renamed with a `Legacy` prefix (e.g., `LegacyRectButton`). Although the legacy JS implementation of the buttons is still available, they also use the new host component internally. Because of that, `PureNativeButton` is no longer available in Gesture Handler 3. From 78d427369e737af759dd1ba498bebf037852efd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Fri, 13 Mar 2026 13:39:31 +0100 Subject: [PATCH 3/7] update SKILL --- skills/gesture-handler-3-migration/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skills/gesture-handler-3-migration/SKILL.md b/skills/gesture-handler-3-migration/SKILL.md index 45e3bc5c4c..63f1bf94c9 100644 --- a/skills/gesture-handler-3-migration/SKILL.md +++ b/skills/gesture-handler-3-migration/SKILL.md @@ -169,7 +169,7 @@ The implementation of buttons has been updated, resolving most button-related is `PureNativeButton` has been removed. If encountered, inform the user that it has been removed and let them decide how to handle that case. They can achieve similar functionality with other buttons. -When migrating buttons, you should use `Clickable` component instead. To replace `BaseButton` use `Clickable` with default props, to replace `RectButton` use `Clickable` with `underlayInitialOpacity={0.7}` and to replace `BorderlessButton` use `Clickable` with `activeOpacity={0.3}`. +When migrating buttons, you should use `Clickable` component instead. To replace `BaseButton` use `Clickable` with default props, to replace `RectButton` use `Clickable` with `underlayActiveOpacity={0.105}` and to replace `BorderlessButton` use `Clickable` with `activeOpacity={0.3}`. Other components have also been internally rewritten using the new hook API but are exported under their original names, so no changes are necessary on your part. However, if you need to use the previous implementation for any reason, the legacy components are also available and are prefixed with `Legacy`, e.g., `ScrollView` is now available as `LegacyScrollView`. From a3b2c87d9593667abb41bb9714010665dfcdba0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Mon, 16 Mar 2026 14:25:26 +0100 Subject: [PATCH 4/7] Minor adjustments --- .../docs-gesture-handler/docs/guides/upgrading-to-3.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx b/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx index 45c77c9527..16518df37d 100644 --- a/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx +++ b/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx @@ -246,15 +246,15 @@ code2={ ### Buttons -RNGH3 introduces the [`Clickable`](/docs/components/clickable) component — a flexible, unified replacement for all previous button types. While `Clickable` shares the same logic as our standard buttons, it offers a more customizable API. +RNGH3 introduces the [`Clickable`](/docs/components/clickable) component — a flexible, unified replacement for all previous button types. While `Clickable` shares the same logic as our standard buttons, it offers a more customizable API. To help you migrate, here is the current state of our button components: -- [`Clickable`](/docs/components/clickable) - The recommended component for all new development. +- [`Clickable`](/docs/components/clickable) - The recommended component. - Standard Buttons (Deprecated) - `BaseButton`, `RectButton` and `BorderlessButton` are still available but are now deprecated. They have been internally rewritten using the new Hooks API to resolve long-standing issues. -- Legacy Buttons (Deprecated): The original, pre-rewrite versions are still accessible for backward compatibility but have been renamed with a `Legacy` prefix (e.g., `LegacyRectButton`). +- Legacy Buttons (Deprecated): The original, pre-rewrite versions are still accessible, but have been renamed with a `Legacy` prefix (e.g., `LegacyRectButton`). Although the legacy JS implementation of the buttons is still available, they also use the new host component internally. Because of that, `PureNativeButton` is no longer available in Gesture Handler 3. From 90197cfb5f4192e8d709abfa9ef15478dd26e752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Mon, 16 Mar 2026 14:35:33 +0100 Subject: [PATCH 5/7] Update onPressIn and onPressOut type definitions to include GestureEvent details --- .../docs/components/clickable.mdx | 50 ++++++++++++++++--- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/packages/docs-gesture-handler/docs/components/clickable.mdx b/packages/docs-gesture-handler/docs/components/clickable.mdx index 82c577b57b..a58e2f5ac9 100644 --- a/packages/docs-gesture-handler/docs/components/clickable.mdx +++ b/packages/docs-gesture-handler/docs/components/clickable.mdx @@ -130,17 +130,55 @@ If set to `true`, the system will not play a sound when the button is pressed. ### onPressIn -```ts -onPressIn?: (pointerInside: boolean) => void; -``` +) => void; + +type GestureEvent = { + handlerTag: number; + numberOfPointers: number; + pointerType: PointerType; + pointerInside: boolean; +} + +enum PointerType { + TOUCH, + STYLUS, + MOUSE, + KEY, + OTHER, +} +`}/> Triggered when the button gets pressed (analogous to `onPressIn` in `TouchableHighlight` from RN core). ### onPressOut -```ts -onPressOut?: (pointerInside: boolean) => void; -``` +) => void; + +type GestureEvent = { + handlerTag: number; + numberOfPointers: number; + pointerType: PointerType; + pointerInside: boolean; +} + +enum PointerType { + TOUCH, + STYLUS, + MOUSE, + KEY, + OTHER, +} +`}/> Triggered when the button gets released (analogous to `onPressOut` in `TouchableHighlight` from RN core). From bce2aa58797c32cba3cfd4ca3d80f6883ebf9c44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Mon, 16 Mar 2026 14:45:39 +0100 Subject: [PATCH 6/7] rephrase --- packages/docs-gesture-handler/docs/components/clickable.mdx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/docs-gesture-handler/docs/components/clickable.mdx b/packages/docs-gesture-handler/docs/components/clickable.mdx index a58e2f5ac9..f19fa52d37 100644 --- a/packages/docs-gesture-handler/docs/components/clickable.mdx +++ b/packages/docs-gesture-handler/docs/components/clickable.mdx @@ -6,11 +6,9 @@ sidebar_label: Clickable import HeaderWithBadges from '@site/src/components/HeaderWithBadges'; -`Clickable` is a new component introduced in Gesture Handler 3, designed to replace the previous button components. It provides a more flexible and customizable way to create buttons with native touch handling. +`Clickable` is a versatile new component introduced in Gesture Handler 3 to succeed previous button implementations. Designed for maximum flexibility, it provides a highly customizable interface for native touch handling while ensuring consistent behavior across platforms. -With `Clickable`, you can decide whether to animate whole component, or just the underlay. This allows to easily recreate both `RectButton` and `BorderlessButton` effects with the same component. - -It also provides consistent behavior across platforms, and resolves most of the button-related issues that were present in previous versions. On android, you can decide whether to use native ripple effect, or JS based animation with Animated API +With `Clickable`, you have more control over animations. It is possible to choose between animating the entire component or just the underlay, along with specifying desired `opacity` values. This allows you to effortlessly replicate both `RectButton` and `BorderlessButton` effects using a single unified component. Furthermore, it resolves many legacy issues found in earlier versions. On Android, you can opt for the native ripple effect or leverage JS-based animations via the [Animated API](https://reactnative.dev/docs/animated). ## Replacing old buttons From cad279b7fedef0cd8e675879f2f39e6b878680e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82?= Date: Mon, 16 Mar 2026 15:03:29 +0100 Subject: [PATCH 7/7] Copilot review --- packages/docs-gesture-handler/docs/components/clickable.mdx | 4 ++-- packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/docs-gesture-handler/docs/components/clickable.mdx b/packages/docs-gesture-handler/docs/components/clickable.mdx index f19fa52d37..3983be883d 100644 --- a/packages/docs-gesture-handler/docs/components/clickable.mdx +++ b/packages/docs-gesture-handler/docs/components/clickable.mdx @@ -219,7 +219,7 @@ Defines the delay, in milliseconds, after which the [`onLongPress`](#onlongpress underlayColor?: string; ``` -Background color of underlay. +Background color of underlay. This only takes effect when `underlayActiveOpacity` is set. ### underlayActiveOpacity @@ -227,7 +227,7 @@ Background color of underlay. underlayActiveOpacity?: number; ``` -Defines the opacity of underlay when the button is active. +Defines the opacity of underlay when the button is active. If not set, underlay won't be rendered. ### activeOpacity diff --git a/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx b/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx index 16518df37d..fe0fa85d3a 100644 --- a/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx +++ b/packages/docs-gesture-handler/docs/guides/upgrading-to-3.mdx @@ -246,7 +246,7 @@ code2={ ### Buttons -RNGH3 introduces the [`Clickable`](/docs/components/clickable) component — a flexible, unified replacement for all previous button types. While `Clickable` shares the same logic as our standard buttons, it offers a more customizable API. +RNGH3 introduces the [`Clickable`](/docs/components/clickable) component — a flexible, unified replacement for all previous button types. While `Clickable` shares the same logic as our standard buttons, it offers a more customizable API. To help you migrate, here is the current state of our button components: