Change all button style with theming - react-native

I want to change all button style, without having to add style one after another like that:
<Button mode="contained" style={{ backgroundColor: "#FF6766" }} >
I'm trying to do something with that:
const theme = {
...DefaultTheme,
roundness: 2,
colors: {
...DefaultTheme.colors,
primary: '#ffffff',
accent: '#f1c40f',
text: '#515151',
surface: '#FF6766',
underlineColor: 'transparent',
background: '#ffffff',
contained: '#000000',
}
};
But I don't know if it's possible here, I found this on this link: https://callstack.github.io/react-native-paper/theming.html
App.js
export default function App() {
const theme = {
...DefaultTheme,
roundness: 2,
colors: {
...DefaultTheme.colors,
primary: '#ffffff',
accent: '#f1c40f',
text: '#515151',
surface: '#FF6766',
underlineColor: 'transparent',
background: '#ffffff',
contained: '#000000',
}
};
return (
<PaperProvider theme={theme}>
<AppNavigator />
</PaperProvider>
)
}

Related

How to do shared element transitions in React Native Web?

I'm using react-native-web to develop a web&mobile application. I've reached the point when I'd like to introduce better transitions between the screens, and for that reason I'd like to do shared element transitions like the one below:
Because I started with #react-navigation/stack for my routing, I wanted to use a library that would support the same structure I have. It took me quite some time to get the react-navigation-shared-element library working, but it has finally compiled. Unfortunately, the animations aren't looking like I wanted them to:
As you can see, there is no animation really. It simply switches the page. I've spent weeks on this issue attempting different config, libraries, and generally everything, and I have nearly given up and started looking for web-only libraries to split the code into two different versions.
Therefore, I kindly request assistance to get the code working with one library or, if you think there are better solutions, an alternative selection of web-only and mobile-only libraries which I could use to keep roughly the same codebase (for example by wrapping library components into something I can use in the code).
Here's the code I have for my current animation:
import React from 'react';
import {NavigationContainer} from '#react-navigation/native';
import {createSharedElementStackNavigator, SharedElement} from 'react-navigation-shared-element';
import {View, TouchableOpacity, Text} from 'react-native';
const Stack = createSharedElementStackNavigator();
function A({navigation}) {
return (
<View>
<TouchableOpacity onPress={() => navigation.navigate('B')}>GO</TouchableOpacity>
<SharedElement id={'shared'}>
<Text style={{position: 'absolute', top: 50, background: 'yellow'}}>Start screen</Text>
</SharedElement>
</View>
);
}
function B({navigation}) {
return (
<View>
<TouchableOpacity onPress={() => navigation.navigate('A')}>GO</TouchableOpacity>
<SharedElement id={'shared'}>
<Text style={{position: 'absolute', top: 100, background: 'yellow'}}>Start screen</Text>
</SharedElement>
</View>
);
}
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name={'A'} component={A} />
<Stack.Screen
name={'B'}
component={B}
sharedElements={(route, otherRoute, showing) => {
return [
{
id: 'shared',
animation: 'move',
},
];
}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
Here are the relevant libraries I am using:
"#react-navigation/native": "^6.0.2",
"#react-navigation/stack": "^6.0.7",
"react-native-shared-element": "^0.8.2",
"react-navigation-shared-element": "^3.1.3"
And, finally, here's my webpack config, which I added it only to support the shared elements library, so I have no idea if it's good or not. I'm quite new to React, so I don't know if there are things like loaders or presets required to support the shared elements animations missing.
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const Dotenv = require('dotenv-webpack');
const appDirectory = path.resolve(__dirname);
const babelLoaderConfiguration = {
test: /\.js$/,
include: [
path.resolve(appDirectory, 'src'),
],
use: {
loader: 'babel-loader',
options: {
presets: ['module:metro-react-native-babel-preset'],
plugins: ['react-native-web'],
},
},
};
const imageLoaderConfiguration = {
test: /\.(gif|jpe?g|png|svg)$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]',
esModule: false,
},
},
};
module.exports = {
entry: path.resolve(appDirectory, 'src', 'index.js'),
output: {
filename: 'bundle.web.js',
path: path.resolve(appDirectory, 'build'),
},
devtool: 'source-map',
module: {
rules: [babelLoaderConfiguration, imageLoaderConfiguration],
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(appDirectory, 'public', 'index.html'),
filename: 'index.html',
}),
new Dotenv({
path: path.resolve(appDirectory, '.env'),
safe: true,
}),
],
resolve: {
alias: {
'react-native$': 'react-native-web',
},
extensions: ['.web.js', '.js'],
},
};
Try to use minus margin with useState in one component :
LIVE example - https://snack.expo.dev/8ZCuner6B
import React, { Component } from 'react';
import { Alert, Button, Text, TouchableOpacity, TextInput, View, StyleSheet } from 'react-native';
const App = () => {
const [animationStyle , setAnimationStyle] = React.useState({
width: 200,
fontFamily: 'Baskerville',
fontSize: 20,
height: 44,
padding: 10,
borderWidth: 1,
borderColor: 'white',
marginTop:30,
marginVertical: 10,
zIndex:2,
})
const frogotPasswordHandler = () => {
let margin = 30;
let step = 3.5
const timerId = setInterval(() =>{
if (margin > -50){
margin = margin - step
updateMarginStyle(margin);
}
if (margin < -50) {
console.log("cleared")
clearInterval(timerId)
}
} , 2);
}
const updateMarginStyle = (num) =>{
setAnimationStyle({
...animationStyle,
marginTop:num,
})
}
return (
<View style={styles.container}>
<Text style={styles.titleText}>Hi, Welcome To</Text>
<Text style={styles.titleText}>Momento</Text>
<View style={styles.textWrapper}>
<TextInput
keyboardType = 'email-address'
onChangeText={(email) => this.setState({ email })}
placeholder='email'
placeholderTextColor = 'white'
style={styles.input}
/>
</View>
<TextInput
onChangeText={(password) => this.setState({ password })}
placeholder={'password'}
secureTextEntry={true}
placeholderTextColor = 'white'
style={animationStyle}
/>
<TouchableOpacity
style={styles.forgotButton}
onPress={frogotPasswordHandler}
>
<Text style={styles.defaultText}>Forgot password</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
>
<Text style={styles.buttonText}> Sign Up / Login </Text>
</TouchableOpacity>
</View>
);
}
export default App;
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'salmon',
},
textWrapper:{
backgroundColor:'green',
zIndex:10,
},
titleText:{
fontFamily: 'Baskerville',
fontSize: 50,
alignItems: 'center',
justifyContent: 'center',
},
button: {
alignItems: 'center',
backgroundColor: 'powderblue',
width: 200,
height: 44,
padding: 10,
borderWidth: 1,
borderColor: 'white',
borderRadius: 25,
marginBottom: 10,
},
buttonText:{
fontFamily: 'Baskerville',
fontSize: 20,
alignItems: 'center',
justifyContent: 'center',
},
input: {
width: 200,
fontFamily: 'Baskerville',
fontSize: 20,
height: 44,
padding: 10,
marginTop:20,
borderWidth: 1,
borderColor: 'white',
marginVertical: 10,
},
defaultText:{
},
forgotButton:{
backgroundColor:'gray',
marginBottom:20,
marginTop:10,
}
});

change active tab background color in react navigation material top tabs

How can I change the background color of the active tab while using material-top-tabs from React Navigation?
Here's what things look like right now:
Screenshot 1
Screenshot 2
Here's my code:
import React from 'react'
import { createMaterialTopTabNavigator } from '#react-navigation/material-top-tabs';
import CrurrentOrders from './CrurrentOrders';
import PastOrders from './PastOrders';
const Tab = createMaterialTopTabNavigator();
const OrdersTabs = () => {
return (
<Tab.Navigator
initialRouteName='CrurrentOrders'
backBehavior='initialRoute'
tabBarPosition='top'
swipeEnabled={true}
swipeVelocityImpact={0.2}
springVelocityScale={0}
sceneContainerStyle={{ backgroundColor: '#d1dfff', margin: 10, borderRadius: 20 }}
style={{ backgroundColor: '#ffffff' }}
tabBarOptions={{
activeTintColor: '#ffffff',
inactiveTintColor: '#ffffff',
showIcon: true,
pressColor: '#856',
scrollEnabled: false,
tabStyle: { backgroundColor: '#36A7E7', borderRadius: 30, margin: 12, justifyContent: 'center', alignContent: 'center' },
indicatorStyle: { backgroundColor: '#987', opacity: 0.05 },
style: { backgroundColor: '#ffffff', borderRadius: 30, margin: 24, height: 72, width: '90%' },
labelStyle: { fontSize: 14 },
}}
>
<Tab.Screen
name="CrurrentOrders"
component={CrurrentOrders}
options={{
title: 'Awsome app',
tabBarTestID: 'werwer',
}}
/>
<Tab.Screen
name="PastOrders"
component={PastOrders}
/>
</Tab.Navigator>
)
}
export default OrdersTabs
I had this exact challenge and was able to solve it by specifying the background color and full height in the indicatorStyle option:
import * as React from 'react';
import { createMaterialTopTabNavigator } from '#react-navigation/material-top-tabs';
import HomeScreen from './HomeScreen';
import AboutScreen from './AboutScreen';
import ContactScreen from './ContactScreen';
const Tab = createMaterialTopTabNavigator();
export default function TopTabs() {
const tabBarOptions = {
activeTintColor: 'white',
inactiveTintColor: 'black',
indicatorStyle: { backgroundColor: 'red', height: '100%' },
pressOpacity: 1,
}
return (
<Tab.Navigator tabBarOptions={tabBarOptions}>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="About" component={AboutScreen} />
<Tab.Screen name="Contact" component={ContactScreen} />
</Tab.Navigator>
);
}
Like Defined here material-top-tab-navigator/ changed the layer color (text color) of the active tab
For background change, you can do something like
function MyTabBar({ state, descriptors, navigation, position }) {
return (
<View style={{ flexDirection: 'row' }}>
{state.routes.map((route, index) => {
const { options } = descriptors[route.key];
const label =
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
? options.title
: route.name;
const isFocused = state.index === index;
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true,
});
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
};
const inputRange = state.routes.map((_, i) => i);
const bgColor = isFocused ? "blue" : "black"; <!-- Here is bg color -->
return (
<TouchableOpacity
accessibilityRole="button"
accessibilityState={isFocused ? { selected: true } : {}}
accessibilityLabel={options.tabBarAccessibilityLabel}
testID={options.tabBarTestID}
onPress={onPress}
onLongPress={onLongPress}
style={{ flex: 1 }}
>
<View style={{backgroundColor: bgColor}}>
<Animated.Text style={{ opacity }}>
{label}
</Animated.Text>
</View>
</TouchableOpacity>
);
})}
</View>
);
}
Thank you for the link , the hack was in indicatorStyle with activeTintColor
tabBarOptions={{
activeTintColor: '#ffffff',
inactiveTintColor: '#36A7E7',
showIcon: true,
pressColor: '#9BC9E2',
scrollEnabled: false,
tabStyle: {
borderRadius: 30,
margin: 12,
justifyContent: 'center',
alignContent: 'center'
},
indicatorStyle: {
backgroundColor: '#36A7E7',
height: '80%',
borderRadius: 30,
marginBottom: 8,
marginLeft: 12,
width: '45%'
},
style: {
backgroundColor: '#ffffff',
borderRadius: 36,
margin: 24,
height: 76,
width: '90%'
},
labelStyle: { fontSize: 14 },
}}
enter image description here

Why won't my top level react-native component expand to the full dimensions?

I'm using next.js if that matters and my pages/_app.tsx has:
function MyApp({ Component, pageProps }: AppProps) {
return (
<PaperProvider theme={customTheme}>
<View style={{ flex: 1, top: 0, left: 0, height: '100%', width: '100%', zIndex: 10, position: 'absolute', backgroundColor: 'red' }}>
<Text> Here</Text>
</View>
</PaperProvider>
)
}
export default MyApp
and customTheme is:
import { DefaultTheme } from 'react-native-paper';
export const customTheme = {
...DefaultTheme,
dark: false,
colors: {
...DefaultTheme.colors,
primary: '#247BA0',
accent: '#70C1B3',
error: '#FF1654',
disabled: '#F3FFBD',
placeholder: '#D3EDBE',
}
}
I see Text, but no red background. What am I missing?
Ok the problem here is the use of position: 'absolute' with height: '100%', delete one of these properties in your style object and it should work.
If you want the full screen to have background color change height: '100%' to height: Dimensions.get("window").height

How to style the tab bar in react native?

Can someone help to solve this out i used the react native 0.54.0,
react-native-navigation, i use it on android device
thanks in advance.
this is the code for tab bar inside tab bar navigator.......
const { width, height } = Dimensions.get("window");
var myTabs = TabNavigator(
tabs:[
Setting: {
screen: SetttingScreen,
navigationOptions: {
tabBarLabel: "Settings",
tabBarIcon: ({ focused }) =>
focused ? (
<Image
style={{ width: 24, height: 24, tintColor: "white" }}
source={require("./app/components/Screens/Images/setting.png")}
/>
) : (
<Image
style={{ width: 24, height: 24, tintColor: "white" }}
source={require("./app/components/Screens/Images/setting.png")}
/>
),
title: "Settings",
headerTitleStyle: {
alignSelf: "center",
color: "white",
fontWeight: "normal"
},
headerStyle: { backgroundColor: "#333333" },
headerLeft: null,
headerRight: null
}
}
and this is the code of tab option
now someone ans me thanks in advance
`{
tabBarPosition: "bottom",
animationEnabled: true,
swipeEnabled: false,
forceTitlesDisplay: true,
tabBarOptions: {
pressColor: "blue",
indicatorStyle: {
opacity: 0
},
allowFontScaling: true,
upperCaseLabel: false,
showLabel: true,
activeTintColor: "blue",
labelStyle: {
fontSize: width * 0.022,
textAlign: "center"
},
showIcon: true,
style: {
// borderTopWidth: 0,
backgroundColor: "#221f1f",
tabBarButtonColor: "#000",
navBarTextFontSize: 34,
forceTitlesDisplay: true,
tabFontFamily: "Avenir-Medium"
}
}
}`

Modal component is undefined in react-native 0.10.1

I'm trying to use the Modal component from react-native and it's value is undefined. Here is the component I'm trying to build:
'use strict';
var React = require('react-native');
var {
Modal,
StyleSheet,
Text,
View,
TouchableHighlight
} = React;
var Button = React.createClass({
getInitialState() {
return {
active: false,
};
},
onHighlight: function() {
this.setState({active: true});
},
onUnhighlight: function() {
this.setState({active: false});
},
render: function() {
var colorStyle = {
color: this.state.active ? '#fff' : '#000',
};
return (
<TouchableHighlight
onHideUnderlay={this.onUnhighlight}
onPress={this.props.onPress}
onShowUnderlay={this.onHighlight}
style={[styles.button, this.props.style]}
underlayColor='#a9d9d4'>
<Text style={[styles.buttonText, colorStyle]}>{this.props.children}</Text>
</TouchableHighlight>
);
}
});
var ModalBox = React.createClass({
getInitialState: function() {
return {
animated: true,
modalVisible: true,
transparent: false,
};
},
setModalVisible: function(visible) {
this.setState({modalVisible: visible});
},
render: function() {
var modalBackgroundStyle = {
backgroundColor: this.state.transparent ? 'rgba(0, 0, 0, 0.5)' : '#f5fcff',
};
var innerContainerTransparentStyle = this.state.transparent
? {backgroundColor: '#fff', padding: 20}
: null;
return (
<View>
<Modal
animated={this.state.animated}
transparent={this.state.transparent}
visible={this.state.modalVisible}>
<View style={[styles.container, modalBackgroundStyle]}>
<View style={[styles.innerContainer, innerContainerTransparentStyle]}>
<Text>This modal was presented {this.state.animated ? 'with' : 'without'} animation.</Text>
</View>
<Button
onPress={this.setModalVisible.bind(this, false)}
style={styles.modalButton}>
Close
</Button>
</View>
</Modal>
</View>
);
},
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
innerContainer: {
borderRadius: 10,
},
button: {
borderRadius: 5,
flex: 1,
height: 44,
justifyContent: 'center',
overflow: 'hidden',
},
buttonText: {
fontSize: 18,
margin: 5,
textAlign: 'center',
},
button: {
borderRadius: 5,
flex: 1,
height: 44,
justifyContent: 'center',
overflow: 'hidden',
},
buttonText: {
fontSize: 18,
margin: 5,
textAlign: 'center',
},
modalButton: {
marginTop: 10,
},
modalButton: {
marginTop: 10,
},
});
module.exports = ModalBox;
And this is the error I get when I add <ModalBox/> component to my index.ios.js:
Error: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.
I don't where you're requiring the modal module.
Make sure you npm install and include the below line in your js file.
Upgrading to react-native 0.11.0 fixed the problem for me