-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
[Docs] Touchable
#4022
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
m-bert
wants to merge
82
commits into
main
Choose a base branch
from
@mbert/clickable-docs
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
[Docs] Touchable
#4022
Changes from all commits
Commits
Show all changes
82 commits
Select commit
Hold shift + click to select a range
9fb1120
Base implementation
m-bert 093630b
Merge branch 'main' into @mbert/clickable
m-bert f1134cb
Do not use animated button if not necessary
m-bert 9461ecc
Use props
m-bert ab6ced1
Types
m-bert 27b3d0c
Additional props
m-bert c0d4960
Working component
m-bert 25ed517
Small refactor
m-bert 5e4262b
Add example
m-bert 5646775
Looks good
m-bert 202a999
Unified, without ripple
m-bert dd2c3bf
Rippleeeee
m-bert 2cf923b
clear activeState also in onFinalize
m-bert 8059e40
Fix borderless
m-bert 6b043a9
Default ripple color
m-bert 1eb680e
Rename file
m-bert b2f7e05
Fix index
m-bert 44bbcc6
Split component and types
m-bert f4d895e
Add presets
m-bert 491c27a
Update gitignore
m-bert e404f8a
Renames
m-bert 583e864
Remove preset
m-bert 769adb4
Ripple
m-bert e4bb348
Example
m-bert 96c016b
Rename in example
m-bert fe9f47f
Opacity fix
m-bert aca162b
JSDocs
m-bert c6f27e7
Vibe stress test
m-bert 4200868
First refactor
m-bert beb6710
Second optimization
m-bert 1a23339
Change props
m-bert 0e5b735
Bring back use callback
m-bert ef24b2f
Merge branch 'main' into @mbert/clickable
m-bert d6113c6
Tests
m-bert ac02b27
Reset longpress outside of if
m-bert 8864e89
Easier stress test
m-bert b74ce61
Deprecate old buttons
m-bert d422f33
Update SKILL
m-bert 822ba83
Add onPressIn and onPressOut
m-bert db37209
Merge branch '@mbert/clickable' into @mbert/clickable-docs
m-bert ff74f2b
Docs
m-bert c9aba4d
Revert changes in button
m-bert f2b3bb9
Merge branch 'main' into @mbert/clickable
m-bert a9688b5
Merge branch '@mbert/clickable' into @mbert/clickable-docs
m-bert 78d4273
update SKILL
m-bert 050f122
Fix deprecation message for `RectButton` to reference `underlayActive…
m-bert 270b111
Call onPressIn when e.pointerInsideis true
m-bert 77d411d
Stress test example timeout cleanup
m-bert 08e5e2e
Merge branch '@mbert/clickable' of github.com:software-mansion/react-…
m-bert d80e5cf
Colooooooors
m-bert 95a887f
Update underlayColor description to require underlayActiveOpacity
m-bert 25126cf
Add default values for underlayInitialOpacity and initialOpacity in C…
m-bert 45ffb2f
Remove unnecessary border styles
m-bert 6888721
Merge branch '@mbert/clickable' into @mbert/clickable-docs
m-bert a3b2c87
Minor adjustments
m-bert 90197cf
Update onPressIn and onPressOut type definitions to include GestureEv…
m-bert bce2aa5
rephrase
m-bert cad279b
Copilot review
m-bert 4fb5ab2
Merge branch 'main' into @mbert/clickable-docs
m-bert c21dfd3
Update props names
m-bert bafbc07
Merge branch 'main' into @mbert/clickable-docs
m-bert 0f3528a
Change props order
m-bert 8ef412f
Grammar
m-bert 20f82bb
Correct prop in SKILL
m-bert ec80be4
RawButton deprecations
m-bert 3db2cd1
Add replacement info to migration guide
m-bert f4c02fc
Update packages/docs-gesture-handler/docs/components/clickable.mdx
m-bert fed7981
Update packages/docs-gesture-handler/docs/components/clickable.mdx
m-bert 8f336b4
Merge branch '@mbert/clickable-docs' of github.com:software-mansion/r…
m-bert a2ed828
Update packages/docs-gesture-handler/docs/components/clickable.mdx
m-bert 2f074ce
Update packages/docs-gesture-handler/docs/components/clickable.mdx
m-bert 224e02e
Update packages/docs-gesture-handler/docs/components/clickable.mdx
m-bert ef7020e
Update packages/docs-gesture-handler/docs/components/clickable.mdx
m-bert b0ed1d4
Review
m-bert 5c6e5e8
Merge branch '@mbert/clickable-docs' of github.com:software-mansion/r…
m-bert cb43f81
Merge branch 'main' into @mbert/clickable-docs
m-bert d3c4337
Mimic Touchable
m-bert 46eba22
Add Touchable migration to SKILL
m-bert aeaef39
Rename to Touchable
m-bert 1cd3061
Other renames
m-bert 5007490
Merge branch 'main' into @mbert/clickable-docs
m-bert 2cee2c4
Touchable replacement note
m-bert File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
326 changes: 326 additions & 0 deletions
326
packages/docs-gesture-handler/docs/components/touchable.mdx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,326 @@ | ||
| --- | ||
| id: touchable | ||
| title: Touchable | ||
| sidebar_label: Touchable | ||
| --- | ||
|
|
||
| import HeaderWithBadges from '@site/src/components/HeaderWithBadges'; | ||
|
|
||
| :::note | ||
| This section refers to new `Touchable` component, meant to replace both buttons and touchables. If you are looking for documentation for the deprecated touchable components, check out the [Legacy Touchables](/docs/components/legacy-touchables) section. | ||
| ::: | ||
|
|
||
| `Touchable` is a versatile new component introduced in Gesture Handler 3 to supersede previous button implementations. Designed for maximum flexibility, it provides a highly customizable interface for native touch handling while ensuring consistent behavior across platforms. | ||
|
|
||
| `Touchable` provides a simple interface for the common animations like opacity, underlay, and scale, implemented entirely on the platform. On Android, it also exposes the native ripple effect on press (turned off by default). | ||
|
|
||
| If the provided animations are not sufficient, it's possible to use `Touchable` to create fully custom interactions using either [Reanimated](https://docs.swmansion.com/react-native-reanimated/) or [Animated API](https://reactnative.dev/docs/animated). | ||
|
|
||
| ## Replacing old buttons | ||
|
|
||
| If you were using `RectButton` or `BorderlessButton` in your app, you should replace them with `Touchable`. Check out the full code in the [example](#example) section below. | ||
|
|
||
| ### RectButton | ||
|
|
||
| To replace `RectButton` with `Touchable`, simply add `activeUnderlayOpacity={0.105}` to your `Touchable`. This will animate the underlay when the button is pressed. | ||
|
|
||
| ```tsx | ||
| <Touchable | ||
| ... | ||
| activeUnderlayOpacity={0.105}/> | ||
| ``` | ||
|
|
||
| ### BorderlessButton | ||
|
|
||
| Replacing `BorderlessButton` with `Touchable` is as easy as replacing `RectButton`. Just add `activeOpacity={0.3}` to your `Touchable`. This will animate the whole component when the button is pressed. | ||
|
|
||
| ```tsx | ||
| <Touchable | ||
| ... | ||
| activeOpacity={0.3}/> | ||
| ``` | ||
|
|
||
| ## Migrating from legacy Touchable variants | ||
|
|
||
| If you were using the specialized touchable components (`TouchableOpacity`, `TouchableHighlight`, `TouchableWithoutFeedback`, or `TouchableNativeFeedback`), you can replicate their behavior with the unified `Touchable` component. | ||
|
|
||
| ### TouchableOpacity | ||
|
|
||
| To replace `TouchableOpacity`, add `activeOpacity={0.2}`. | ||
|
|
||
| ```tsx | ||
| <Touchable | ||
| ... | ||
| activeOpacity={0.2}/> | ||
| ``` | ||
|
|
||
| ### TouchableHighlight | ||
|
|
||
| To replace `TouchableHighlight`, add `activeUnderlayOpacity={1}`. | ||
|
|
||
| ```tsx | ||
| <Touchable | ||
| ... | ||
| activeUnderlayOpacity={1}/> | ||
| ``` | ||
|
|
||
| ### TouchableWithoutFeedback | ||
|
|
||
| To replace `TouchableWithoutFeedback`, use a plain `Touchable`. | ||
|
|
||
| ```tsx | ||
| <Touchable ... /> | ||
| ``` | ||
|
|
||
| ### TouchableNativeFeedback | ||
|
|
||
| To replicate `TouchableNativeFeedback` behavior, use the [`androidRipple`](#androidripple) prop. Make sure to set `foreground={true}`. | ||
|
|
||
| ```tsx | ||
| <Touchable | ||
| ... | ||
| androidRipple={{ | ||
| foreground: true, | ||
| }}/> | ||
| ``` | ||
|
|
||
| ## Example | ||
|
|
||
| In this example we will demonstrate how to recreate `RectButton` and `BorderlessButton` effects using the `Touchable` component. | ||
|
|
||
| <CollapsibleCode | ||
| label="Show full example" | ||
| expandedLabel="Hide full example" | ||
| lineBounds={[7, 40]} | ||
| src={` | ||
| import React from 'react'; | ||
| import { StyleSheet, Text } from 'react-native'; | ||
| import { | ||
| GestureHandlerRootView, | ||
| Touchable, | ||
| } from 'react-native-gesture-handler'; | ||
|
|
||
| export default function TouchableExample() { | ||
| return ( | ||
| <GestureHandlerRootView style={styles.container}> | ||
| <Touchable | ||
| onPress={() => { | ||
| console.log('BaseButton built with Touchable'); | ||
| }} | ||
| style={[styles.button, { backgroundColor: '#7d63d9' }]}> | ||
| <Text style={styles.buttonText}>BaseButton</Text> | ||
| </Touchable> | ||
|
|
||
| <Touchable | ||
| onPress={() => { | ||
| console.log('RectButton built with Touchable'); | ||
| }} | ||
| style={[styles.button, { backgroundColor: '#4f9a84' }]} | ||
| activeUnderlayOpacity={0.105}> | ||
| <Text style={styles.buttonText}>RectButton</Text> | ||
| </Touchable> | ||
|
|
||
| <Touchable | ||
| onPress={() => { | ||
| console.log('BorderlessButton built with Touchable'); | ||
| }} | ||
| style={[styles.button, { backgroundColor: '#5f97c8' }]} | ||
| activeOpacity={0.3}> | ||
| <Text style={styles.buttonText}>BorderlessButton</Text> | ||
| </Touchable> | ||
| </GestureHandlerRootView> | ||
| ); | ||
| } | ||
|
|
||
| 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 | ||
|
|
||
| ### activeOpacity | ||
|
|
||
| ```ts | ||
| activeOpacity?: number; | ||
| ``` | ||
|
|
||
| Defines the opacity of the whole component when the button is active. | ||
|
|
||
| ### defaultOpacity | ||
|
|
||
| ```ts | ||
| defaultOpacity?: number; | ||
| ``` | ||
|
|
||
| Defines the opacity of the whole component when the button is active. By default set to `1`. | ||
|
|
||
| ### activeUnderlayOpacity | ||
|
|
||
| ```ts | ||
| activeUnderlayOpacity?: number; | ||
| ``` | ||
|
|
||
| Defines the opacity of the underlay when the button is active. By default set to `0`. | ||
|
|
||
| ### defaultUnderlayOpacity | ||
|
|
||
| ```ts | ||
| defaultUnderlayOpacity?: number; | ||
| ``` | ||
|
|
||
| Defines the initial opacity of underlay when the button is inactive. By default set to `0`. | ||
|
|
||
| ### underlayColor | ||
|
|
||
| ```ts | ||
| underlayColor?: string; | ||
| ``` | ||
|
|
||
| Background color of the underlay. This only takes effect when `activeUnderlayOpacity` or `defaultUnderlayOpacity` is set. | ||
|
|
||
| ### exclusive | ||
|
|
||
| ```ts | ||
| exclusive?: boolean; | ||
| ``` | ||
|
|
||
| Defines whether pressing this button prevents other buttons exported by Gesture Handler from being pressed. By default set to `true`. | ||
|
|
||
| <HeaderWithBadges platforms={['android']}> | ||
| ### touchSoundDisabled | ||
| </HeaderWithBadges> | ||
|
|
||
| ```ts | ||
| touchSoundDisabled?: boolean; | ||
| ``` | ||
|
|
||
| If set to `true`, the system will not play a sound when the button is pressed. | ||
|
|
||
| ### onPressIn | ||
|
|
||
| <CollapsibleCode | ||
| label="Show composed types definitions" | ||
| expandedLabel="Hide composed types definitions" | ||
| lineBounds={[0, 1]} | ||
| src={` | ||
| onPressIn?: (e: GestureEvent<NativeHandlerData>) => void; | ||
|
|
||
| type GestureEvent<NativeHandlerData> = { | ||
| 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 `Pressable` from RN core). | ||
|
|
||
| ### onPressOut | ||
|
|
||
| <CollapsibleCode | ||
| label="Show composed types definitions" | ||
| expandedLabel="Hide composed types definitions" | ||
| lineBounds={[0, 1]} | ||
| src={` | ||
| onPressOut?: (e: GestureEvent<NativeHandlerData>) => void; | ||
|
|
||
| type GestureEvent<NativeHandlerData> = { | ||
| handlerTag: number; | ||
| numberOfPointers: number; | ||
| pointerType: PointerType; | ||
| pointerInside: boolean; | ||
| } | ||
|
|
||
| enum PointerType { | ||
| TOUCH, | ||
| STYLUS, | ||
| MOUSE, | ||
| KEY, | ||
| OTHER, | ||
| } | ||
| `}/> | ||
|
|
||
| Triggered when the button gets released or the pointer moves outside of the button area (analogous to `onPressOut` in `Pressable` from RN core). | ||
|
|
||
| ### onPress | ||
|
|
||
| ```ts | ||
| onPress?: (pointerInside: boolean) => void; | ||
| ``` | ||
|
|
||
| Triggered when the button gets pressed (analogous to `onPress` in `Pressable` 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`. | ||
|
|
||
|
|
||
| <HeaderWithBadges platforms={['android']}> | ||
| ### androidRipple | ||
| </HeaderWithBadges> | ||
|
|
||
| <CollapsibleCode | ||
| label="Show composed types definitions" | ||
| expandedLabel="Hide composed types definitions" | ||
| lineBounds={[0, 1]} | ||
| src={` | ||
| androidRipple?: PressableAndroidRippleConfig; | ||
|
|
||
| type PressableAndroidRippleConfig = { | ||
| color?: (string | OpaqueColorValue); | ||
| borderless?: boolean; | ||
| radius?: number; | ||
| foreground?: boolean; | ||
| } | ||
| `}/> | ||
|
|
||
| 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. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.