React Native keyboard is dismissed automatically in react-native-tab-view - react-native

Here is my code
<TabView
keyboardDismissMode='none'
navigationState={{index, routes}}
renderTabBar={renderTabBar}
renderScene={renderScene}
initialLayout={{width: layout.width}}
onIndexChange={() => {}}
/>
I am using react-native-tab-view with three tabs in my application also I have TextInput inside third tab. I had set autofocus={true} to open the keyboard automatically when third tab is opened. But the issue is when I swipe second tab to third tab the keyboard is closing automatically. I want the keyboard should not close until the user tries to close.

My render scene is
const scaneMap = ({route}) => {
switch (route?.key) {
case "stepOne":
return stepOne()
case "stepTwo":
return stepTwo()
case "stepThree":
return stepThree()
default:
return stepOne()
}
}
Similar to your problem, the keyboard was closing every time I pressed a key on the input. As a solution, I changed the structure as follows and the problem was fixed.
const scaneMap = ({route}) => {
switch (route?.key) {
case "stepOne":
return stepOne()
case "stepTwo":
return stepTwo()
case "stepThree":
return stepThree()
default:
return stepOne()
}
}

Related

How to disable animations when the user scrolls (react-native-reanimated 2)

Here's a weekly mini calendar, that turns into a monthly mini calendar component.
When it turns from weekly to monthly we have some entering/exiting animations
So far so good.
Problem:
The problem is, that those animations (being entering/exiting animations) also take place while the user is scrolling.
As you can see in the gif, animations play when I scroll horizontally, which isn't what I want, I only want animations when the component changes from weekly to monthly (expands/collapses)
Code:
import Animated, {
FadeInDown,
FadeInUp,
SlideOutUp,
SlideOutDown,
} from 'react-native-reanimated';
const MiniCalendarItem = () => {
let animationEnter;
let animationExit;
if (this.props.itemRepresents === ITEM_REPRESENTS.MONTH) {
if (this.dayIsPartOfCurrentWeek(day)) {
animationEnter = FadeInUp;
} else {
animationEnter = FadeInUp.delay((weekIndex * 150)).duration(350)
}
animationExit = SlideOutDown.duration(400);
} else {
animationEnter = FadeInDown.duration(500);
animationExit = SlideOutUp.duration(400);
}
return (
<Animated.View
entering={animationEnter}
exiting={animationExit}
key={`dayData_${dayProps.id}`}
>
{...}
</Animated.View>
);
};
and here's the parent:
renderItem = () => {
return (
<MiniCalendarItem
animationsEnabled
key={itemKey}
mode={mode}
itemRepresents={visible ? ITEM_REPRESENTS.MONTH : ITEM_REPRESENTS.WEEK}
/>
)
}
}
Essentially the parent is a ScrollView (not a FlatList)
Question:
How can I stop react-native-reanimated#2 from playing any animations and when is it a good time to do that.
I added a animationsEnabled prop, but ideally I'd love to feed it with an Animated.Value(true) object. I'm just not sure how to conditionally disable animations based on that prop, from within the MiniCalendarItem.

react native gifted chat can not hide Typing Indicator

i want to using Typing Indicator from Gifted Chat, here is my code to show typing state:
const [isTyping, setIsTyping] = useState(false)
const renderFooter = (props) => {
return <TypingIndicator isTyping={isTyping}/>
}
<GiftedChat>
....
renderFooter={renderFooter}
isTyping={isTyping}
onPressAvatar={() => {
console.log('longpressavt', isTyping)
setIsTyping(!isTyping)
}}
</GiftedChat>
i can show typing indicator in first avatar click, but next time click the Typing Indicator does not dismiss, can anyone guide me to know problem? Thanks
Try this: - shouldUpdateMessage={() => { return true; }}
I got it from this link - https://github.com/FaridSafi/react-native-gifted-chat/issues/2186

PrimeNg TabView with ConfirmDialog not working

I'm trying to use PrimeNg TabView component along with confirmDialog unsuccessfully
I am able to show this confirm dialog but it appears after user switch to target tab panel which is wrong.
<p-tabView (onChange)="handleChange($event)" [(activeIndex)]="index">...</p-tabView>
handleChange(e) {
this.confirmationService.confirm({
message: 'There are unsaved changes, do you want to proceed?',
accept: () => {
this.index = e.index;
},
reject:() =>{ }
});
}
Do you have an idea on how to prevent or allow tab change using confirm dialog ?
Thanks
there is no official way to prevent change to another tab by press on that tab , but 😅 there is a work around it first we need to prevent the tab change by tab click,
1️⃣ we need to set the header by ng-template or it called a custom header
template
<p-tabPanel >
<ng-template pTemplate="header">
<div (click)="handleChange($event,0)">
Godfather I
</div>
</ng-template>
.....
</p-tabPanel>
2️⃣ we bind a click event to the new header text and by using mouse event stopPropagation method we can prevent the change 👌,now we can control the change by confirm result but you need to pass the current tab index, that why I add another parameter to handleChange
component
handleChange(e:MouseEvent,tabIndex:number) {
e.stopPropagation();
if (this.index == tabIndex){
return;
}
// console.log(tabIndex)
this.confirmationService.confirm({
message: "There are unsaved changes, do you want to proceed?",
accept: () => {
this.index = tabIndex;
},
reject: () => {}
});
}
the if block if (this.index == tabIndex){return;} use to prevent showing the confirm dialog if we click on the same active tab again
demo 🚀🚀

React DnD change div style only when dragging

I am implementing the drag and drop mechanic using react-dnd library, but I find it hard to style my drop targets. I want to show the user which drop target is available to drop on, but using the isOver and canDrop will only style the item that is currently being hovered on.
If I use the !isOver value, all the divs are being styled, without even dragging any of the elements.
How can I style the drop targets only when the dragging of an element happens?
This is my code so far, for a #DropTarget:
import React from 'react';
import {DropTarget} from 'react-dnd';
import {ItemTypes} from './Constants';
const target = {
drop(props, monitor, component){
// console.log("Dropped on", props.id);
},
canDrop(props, monitor, component){
var cardColumn = monitor.getItem().column;
var targetColumn = props.column;
return false; // still testing styling when only an element is being dragged on the page
}
};
#DropTarget(ItemTypes.CARD, target, (connect, monitor) => ({
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver({shallow: true}),
canDrop: monitor.canDrop(),
}))
class CardList extends React.Component{
constructor(props){
super(props);
this.addClass = this.addClass.bind(this);
}
addClass(){
const {isOver, canDrop} = this.props;
if(isOver && canDrop){
return "willDrop"; // green background for .card-list
}
if(isOver && !canDrop){
return "noDrop"; // red background for .card-list
}
if(!isOver && !canDrop){
return ""; // will style all the backgrounds in a color, but not when dragging
}
}
render(){
const {connectDropTarget} = this.props;
return connectDropTarget(
<div class={"card-list col-xl-12 col-lg-12 col-md-12 col-sm-12 col-xs-12 " + this.addClass()} id={this.props.id}>
{this.props.children}
</div>
);
}
}
export default CardList;
Is there a way to get the isDragging value when an element is being dragged on the page, since this is the only possibility to obtain what I want.
Thanks!
Both isOver and canDrop implicitly do the isDragging check, per http://react-dnd.github.io/react-dnd/docs-drop-target-monitor.html - note that they only return true if a drag operation is in progress. Therefore, if you want to style drop targets such that only when something that can be dragged is being dragged, then I think you need another case in your addClass() function to handle that, like this:
addClass(){
const {isOver, canDrop} = this.props;
if(isOver && canDrop){
return "willDrop"; // green background for .card-list
}
if(isOver && !canDrop){
return "noDrop"; // red background for .card-list
}
if(!isOver && canDrop){
return ""; // THIS BLOCK WILL EXECUTE IF SOMETHING IS BEING DRAGGED THAT *COULD* BE DROPPED HERE
}
}
And I don't think you want the !isOver && !canDrop block - this will execute even when nothing is being dragged at all.

Is it possible to change transitions in react native navigator?

I have 3 different react native components and I am using the Navigator to navigate between them. In my first view I define the navigator:
View 1
<Navigator
ref="nav"
renderScene={#renderScene}
initialRoute={#renderContent(I18n.t("Incidents"))}
configureScene={ ->
transition = Navigator.SceneConfigs.HorizontalSwipeJump
transition.gestures = null
transition
}
/>
As you can see the transition is HorizontalSwipeJump.
View 2
#props.navigator.push
component: IncidentScreen
incidentId: incident.id
sceneConfig: -> Navigator.SceneConfigs.FloatFromBottomAndroid
As you can see, I am trying move into view #3 using FloatFromBottomAndroid, however, it's not working.
By looking at the source code for RN I can see that the navigator.push method get's the animation from the props:
var nextAnimationConfigStack = activeAnimationConfigStack.concat([
this.props.configureScene(route),
]);
So what can I do?
Thanks a lot.
You have to go digging into the react-native source here for the list of SceneConfigs, but here's the current list as of writing:
PushFromRight
FloatFromRight
FloatFromLeft
FloatFromBottom
FloatFromBottomAndroid
FadeAndroid
HorizontalSwipeJump
HorizontalSwipeJumpFromRight
VerticalUpSwipeJump
VerticalDownSwipeJump
Example usage:
<Navigator
configureScene={(route) => {
if (someCondition) {
return Navigator.SceneConfigs.HorizontalSwipeJump;
} else {
return Navigator.SceneConfigs.PushFromRight;
}
}}
/>
Ok, I figure it out. I was missing this part in View 1:
configureScene={ (route) ->
if route.sceneConfig
route.sceneConfig
else
transition = Navigator.SceneConfigs.HorizontalSwipeJump
transition.gestures = null
transition
}
If anyone is still looking at this, you can push without animation by just reseting the routes to what you want them to end up being. This is assuming that you don't do anything special with your routes like save the forward routes or anything.
if( !shouldAnimate )
{
var routeStack = this.refs.mainNav.state.routeStack;
routeStack.push(newRoute);
this.refs.mainNav.immediatelyResetRouteStack(routeStack);
}
else
{
this.refs.mainNav.push(feature);
}
Where mainNav is the ref of my Navigator. Hope this helps.