Hide element when keyboard is shown - reactjs

I want to hide my button when keyboard is shown and and move it back when User closes keyboard. It works but I've noticed really annyoing effect of jumping button, really ugly 0.0001 animation. I think that the problem exsists because my code hides element right after my component rerenders. Could you help me to avoid this type of "jumping"?
const [isKeyboardVisible, setKeyboardVisible] = React.useState();
useEffect(() => {
Keyboard.addListener('keyboardDidShow', function() {
setKeyboardVisible(false);
});
Keyboard.addListener('keyboardDidHide', function() {
setKeyboardVisible(true);
});
});
{isKeyboardVisible && (
<Button
style={{
position: 'absolute',
borderRadius: 0,
bottom: 0,
width: '100%',}}
title="Delete"
}}
/>
)}

Related

Making signaturePad component take up full screen

Within one of my components a user can click a button that pulls up a signaturePad they can sign on. This is working, however, I'd like the signaturePad to take up the full screen, whereas now it appears between the footer and header. How can I accomplish this? I played around with using { flex: 1 } on the View of the SignaturePad, but this had no visible effect.
Here is the relevant code from the parent component. If a certain state is true, the signaturePad displays:
{this.state.signaturePanelIsVisible && (
<SignaturePanel
session={this.props?.session}
signaturePanelIsVisible={this.state.signaturePanelIsVisible}
/>
)}
And the signaturePad component code looks like this:
const SignaturePanel = (props) => {
const dispatch = useDispatch();
return (
<SignaturePanel
actionStyle={{
...styles.texts.mediumText,
color: styles.colors.primary,
textDecorationLine: 'underline',
}}
onCancel={async () => {
props.hideSignaturePanel();
}}
onSave={async (base64) => {
const base64Result = base64.base64DataUrl.substr(base64.base64DataUrl.indexOf(',') + 1);
dispatch(
await updateSignature({
...props.signature,
guid: props.session.guid,
value: base64Result,
lastUpdate: Date.serverTime(),
})
);
}}
/>
);
};
export default SignaturePanel;
And the styling applied looks like this:
container: {
width: '100%',
height: '100%',
zIndex: 98,
position: 'absolute',
backgroundColor: '#fff',
},
You'll need to add position: 'absolute' to the style of your modal. Setting the height and width to 100% as well sometimes works, depending on how your app is set up. This will either cover the screen with the component, or make the component appear under the header and overflow the bottom of the screen. To fix the latter issue, add top: -<height of header>. This way the component will move up and cover the header.
<Modal style={styles.modal}>
<View style={styles.signaturePad}>
</View>
</Modal>
modal: {
position: 'absolute',
height: '100%',
width: '100%',
top: -n, //(where n = height of your header)
}
signaturePad: {
height: '100%',
width: '100%',
}
Depending on how your project is set up, you may not need the top value. These are general settings that you should usually put on a modal component. It's considered best practice to have a modal cover the whole screen, then add the component you want to display as a subcomponent.

How to make background parallax in React?

I am trying to make a parallax background like the react-parallax package.
I couldn't use react-parallax package it gives me 504 error (problem with vite).
I tried to use #react-spring/parallax but it didn't do the job.
Finally I wrote my own code but I still confused wether my code has a bad performace.
I've made a scroll listener with a callback which sets scroll state to scrollY value
then using this value with background position y
useEffect(() => {
window.addEventListener("scroll", () => setscroll(window.scrollY));
return () => {
window.removeEventListener("scroll", () =>
setscroll(window.scrollY)
);
};
}, []);
<Swiper>
<SwiperSlide
style={{
backgroundImage: `url(${Img[0]})`,
backgroundSize: "cover",
backgroundPositionX: "center",
backgroundPositionY: `${(scroll - 60) * 0.3}px`,
width: "100%",
backgroundRepeat: "no-repeat",
overflow: "hidden",
position: "relative",
}}></SwiperSlide>
</Swiper>
The performace issue I touched is this component renders every time I scroll.
What should I do?

Apply styles only during animation in framer-motion

I have a collapsible panels animated with framer motion. When the panel switches from collapsed to open the overflow is visible. This breaks the layout somewhat as the content of the panel body then overlays the content below. However, I need the overflow to properly display a dropdown list inside the panels.
I came up with the following idea.
Basically I want to apply "overflow:hidden" to the StyledPanelBody when the framer animation is being executed. This would prevent the ugly effect with the overlay. However, I couldn't find any way to do that from the documentation. There is just a "transitionEnd" property.
const PanelBody = ({children, isFramed, isOpen}) => {
const currentVariant = isOpen ? 'open' : 'closed'
const loadFeatures = () =>
import('./framerMotionFeatures.js').then(res => res.default)
return (
<LazyMotion features={loadFeatures}>
<StyledPanelBody
initial={currentVariant}
animate={currentVariant}
variants={{
closed: {height: 0},
open: {height: 'auto'}
}}
transition={{ease: 'easeInOut', duration: 0.3}}
isFramed={isFramed}
isOpen={isOpen}
>
<div>
{children}
</div>
</StyledPanelBody>
</LazyMotion>
)
}
You can try this as a workaround:
variants={{
closed: {
height: 0,
overflow: 'hidden',
},
open: {
height: 'auto',
transitionEnd: {
overflow: 'unset',
}
}
}}

React onClick not working in device with <Image>

I'm trying to add a border to the image when its clicked, like a radio button, but only with an image.
The code works perfectly on web but when I try to click the image on the device it doesn't do anything!
I tried to do Alert.alert() and it's like it doesn't register the click.
let stylereg_na = { borderRadius: 3, height: hp('7%'), width: wp('25%')};
let stylereg_eu = { borderRadius: 3, height: hp('7%'), width: wp('25%')};
if(regNA)
{
stylereg_na = {borderWidth: 2, borderColor:'black', borderRadius: 3, height: hp('8%'), width: wp('26%')};
}
return (
<Image style={stylereg_na} source={na} onClick={() =>
{
if(regNA)
setRegNAStatus(false);
else
{
setRegNAStatus(true);
}
}
);
You need to wrap it Touchable component like this
<TouchableWithoutFeedback onPress={() => alert('Pressed!')}>
<Image style={stylereg_na} source={na} />
</TouchableWithoutFeedback>;
refer to the documentation if you wanna learn more about it, like TouchableHighlight or TouchableOpacity https://reactnative.dev/docs/touchablewithoutfeedback

Setting state of button inside mapped DIV and only having the state effect the button inside that DIV

.map((value, index) => (
<div
className="cardControl"
id={value.titles}
style={{
width: "700px",
minHeight: "325px",
border: "1px solid white",
backgroundColor: "RGB(67, 80, 88, 0.9)",
color: "white",
display: props.display,
}}
>
So I am mapping an array to create div's to display the results in the DIV. Then inside these DIVs I have this button below
<Button
id="favButton"
style={{
backgroundColor: "#D4AF37",
height: 40,
width: 190,
color: "white",
}}
type="submit"
onClick={() => favPressed(value)}
>
{favButtonText}
</Button>
```
and then once this button is clicked I am changing the state of favButtonText via this function
let favPressed = (value) => {
setfavButtonText(<Spinner size="sm" color="danger" />);
setTimeout(() => {
setfavButtonText("Favorite Listing");
}, 1000);
Now the issue is, obviously because I am using the same state for all the buttons, when 1 button is pressed, the state is changed for every button in every div in the map.
What I am trying to do is make it to where when the button is pressed in 1 DIV, only that button in that mapped DIV changes state. However, I am unsure how to handle this.
I basically have a list of results which is the mapped divs, and have it setup where they can save a result via pressing the button, and I want to be able to change the button text on the specific result when they press the button in that specific DIV instead of all of them. Hoping someone can point me in the right direction for this and hopefully I worded this question right lol.
I would suggest moving the logic for setfavButtonText and favPressed into another component, e.g. <FavButton />
This way, setfavButtonText won't be shared across the list of fav buttons.

Resources