-
-
Save necolas/c42e76ff5a212893c1fa234d94aec0a4 to your computer and use it in GitHub Desktop.
React event responders
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
// We can listen for events (e.g., 'press. or 'focuswithin') that are fired from responders, | |
// if they are allowed to bubble. | |
// | |
// context.dispatchEvent(eventObject, listener, eventPriority, bubbles) | |
// | |
// This allows us to prevent certain events from bubbling up the tree, e.g., 'focus', 'scroll'. | |
import React, {useRef, useState} from 'react'; | |
import {Pressable, Text, View} from 'react-ui'; | |
import {PressListener} from 'react-events/press'; | |
function Cell(props) { | |
function handlePressOne(event) { | |
console.log('You pressed "Hello world"!'); | |
} | |
function handlePressTwo(event) { | |
console.log('You pressed "Goodbye world"!'); | |
} | |
return ( | |
<View style={[props.style, { padding: 10 }]}> | |
<Pressable onPress={handlePressOne}> | |
<Text>Hello world</Text> | |
</Pressable> | |
<Pressable onPress={handlePressTwo}> | |
<Text>Goodbye world</Text> | |
</Pressable> | |
<Text>The end</Text> | |
</View> | |
); | |
} | |
export default function App() { | |
// This is only called if a <Pressable> within <Cell> is the target, | |
// because the PressResponder bubbles the 'press' event. | |
function handlePressCell(event) { | |
console.log('You pressed a <Pressable> within <Cell>!'); | |
} | |
// This is only called if a non-<Pressable> in the subtree is the target, | |
// i.e., siblings of <Cell>, or the wrapping <View> and ending <Text> within <Cell> | |
function handlePressApp(event) { | |
console.log('You pressed a <Pressable> within <App>!'); | |
} | |
const [pressWithinCell, setPressWithinCell] = useState(false); | |
return ( | |
<Pressable onPress={handlePressApp}> | |
<View> | |
<Text>This is my app</Text> | |
</View> | |
<PressListener | |
onPress={handlePressCell} | |
onPressChange={setPressWithinCell} | |
> | |
<Cell style={{ backgroundColor: pressWithinCell ? 'gray' : 'transparent' }} /> | |
</PressListener> | |
</Pressable> | |
); | |
} |
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
import React, {useRef} from 'react'; | |
import {usePressResponder} from 'react-events/press'; | |
import {useFocusResponder} from 'react-events/focus'; | |
import {useHoverResponder} from 'react-events/hover'; | |
export default function Pressable(props) { | |
const { | |
children, | |
focusable, | |
onBlur, | |
onFocus, | |
onFocusChange, | |
onFocusVisibleChange, | |
onHover, | |
onHoverChange, | |
onLongPress, | |
onLongPressChange, | |
onPress, | |
onPressChange | |
} = props; | |
const focusEvents = { | |
onBlur, | |
onFocus, | |
onFocusChange, | |
onFocusVisibleChange | |
}; | |
const hoverEvents = { | |
onHover, | |
onHoverChange | |
}; | |
const pressEvents = { | |
onLongPress, | |
onLongPressChange, | |
onPress, | |
onPressChange | |
}; | |
const targetRef = useRef(null); | |
const [focused, focusVisible] = useFocusResponder(targetRef, focusEvents) | |
const [hovered] = useHoverResponder(targetRef, hoverEvents) | |
const [longPressed, pressed] = usePressResponder(targetRef, pressEvents) | |
const forwardedState = { | |
focused, | |
focusVisible, | |
hovered, | |
longPressed, | |
pressed | |
}; | |
return ( | |
<View | |
children={typeof children === 'function' ? children(forwardedState) : children} | |
focusable={focusable} | |
forwardedRef={targetRef} | |
style={typeof style === 'function' ? style(forwardedState) : style} | |
/> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment