Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@necolas
Forked from trueadm/flare-ideas.jsx
Last active July 10, 2019 11:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save necolas/c42e76ff5a212893c1fa234d94aec0a4 to your computer and use it in GitHub Desktop.
Save necolas/c42e76ff5a212893c1fa234d94aec0a4 to your computer and use it in GitHub Desktop.
React event responders
// 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>
);
}
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