How to customize button css in react-admin - javascript

I am new to react-admin, and how to customize react admin buttons?
In my scenario I have a list also in create, edit, and export button there and I don't know which is the best way to change button css in react-admin. Can anyone solve this?
By default I have button like above mentioned, so I need to add css for this two buttons.
Here is my sample code
// style list
const useStyles = makeStyles((theme) => ({
userCard: {
padding: "20px",
borderRadius: "12px",
},
btn_edit: {
background: "#5E35B1",
color: "#fff",
fontSize: "10px",
},
mainList: {
boxShadow: "none !important",
borderRadius: "0px",
},
listCreateIcon: {
padding: "0px !important",
},
}));
//main
export const UserList = (props) => {
const classes = useStyles();
return (
<Card className={classes.userCard}>
<List
{...props}
pagination={null}
perPage={9999}
className={classes.mainList}
>
<Datagrid className={classes.listCard}>
<TextField source="username" />
<BooleanField source="enabled" />
<ReferenceArrayField reference="_roles" source="roles">
<SingleFieldList>
<ChipField source="name" />
</SingleFieldList>
</ReferenceArrayField>
<EditButton className={classes.btn_edit} />
</Datagrid>
</List>
</Card>
);
};
export const UserCreate = (props) => {
const classes = useStyles();
return (
<Create {...props} className={classes.listCreateIcon}>
<SimpleForm style={{ padding: "0px !important" }}>
<TextInput source="username" />
<TextInput type="password" source="password" />
<ReferenceArrayInput source="roles" reference="_roles" allowEmpty>
<SelectArrayInput optionText="name" />
</ReferenceArrayInput>
<BooleanInput source="enabled" defaultValue={true} />
</SimpleForm>
</Create>
);
};
export const UserEdit = (props) => (
<Edit {...props}>
<SimpleForm>
<TextField source="username" />
<ReferenceArrayInput source="roles" reference="_roles">
<SelectArrayInput optionText="name" />
</ReferenceArrayInput>
<BooleanInput source="enabled" />
</SimpleForm>
</Edit>
);

This will work for you.
btn_create: {
display: "inline-flex",
alignItems: "center",
gridGap: 4,
backgroundColor: "transparent",
borderColor: "transparent",
fontSize: 16,
color: "blue" // the text color you want
// if you are using the svg icon
svg : {
width: 16,
height: 16,
path: {
fill : "blue" //color code of icon
}
}
},
btn_group: {
display:"flex",
gridGap: "16px",
alignItems: "Center",
}
on Component
<div className={classes.btn_group}>
<EditButton className={classes.btn_create} />
<EditButton className={classes.btn_create} />
</div>
PS. If the icon is font icon, you may not use the svg styling.

Related

How to make a custom search input reusable?

In my application, one of the most used elements is the search input, which makes it possible to search for products, topics, categories, etc.
I have already created the search input element, see below.
How to make the navbar search input reusable so that I can use it in other places?
import React from 'react'
import { Box, FormControl, InputBase } from '#mui/material'
import { styled } from '#mui/material/styles';
import { ContainedButton } from '../../ui-kit';
const StyledInput = styled(InputBase)(({ theme }) => ({
color: 'inherit',
border: 'none',
outline: 'none',
'& .MuiInputBase-input': {
maxHeight: '30px',
padding: '4px 16px',
maxWidth: '100%',
borderLeft: `1px solid ${theme.palette.grey[100]}`,
fontSize: 16,
lineHeight: 1.125,
color: theme.palette.text.primary,
},
width: '100%',
}));
const CONTAINED_BUTTON_STYLED = {
minWidth: '111px',
borderRadius: '0 2px 2px 0',
};
export const SearchInput = () => {
return (
<Box>
<FormControl sx={{ flexDirection: 'row', ml: '16px', width: '100%' }}>
<StyledInput placeholder="Search on Website" />
<ContainedButton sx={CONTAINED_BUTTON_STYLED} title="Search" />
</FormControl>
</Box>
)
}
You can simply expose all of the InputBase props as props of your custom SearchInput component, so that you maintain the same full API, and apply these props on the underlying InputBase component (possibly styled), typically using the JSX spread attributes syntax:
If you already have props as an object, and you want to pass it in JSX, you can use ... as a “spread” syntax to pass the whole props object.
export const SearchInput = (props: React.ComponentProps<typeof InputBase>) => {
return (
<Box>
<FormControl sx={{ flexDirection: 'row', ml: '16px', width: '100%' }}>
<StyledInput placeholder="Search on Website" {...props} />
<Button sx={CONTAINED_BUTTON_STYLED} title="Search" />
</FormControl>
</Box>
)
}
Then you can use it as a "normal" InputBase:
function ParentComponent() {
return (
<SearchInput value="hello" onChange={(event) => console.log(event)} />
)
}
Playground Link

Styling TextField in DesktopDatePicker Material UI

Self-taught dev here.
I am trying to style a textfield rendered by a DesktopDatePicker in a react application. I can change the width using MakeStyles, but can't seem to change the height of the box, or the font of the input text. My code is as follows:
const useStyles = makeStyles(() => ({
textField: {
width: "90%",
height: "75%",
marginLeft: "auto",
marginRight: "auto",
paddingBottom: 0,
marginTop: 0,
},
input: {
height: "70%",
fontSize: "small",
}
}));
const classes = useStyles();
return (
<div >
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DesktopDatePicker
inputFormat="MM/dd/yyyy"
selected={new Date(initialVal)}
size="small"
onChange={(newDate) => {
setDateBirth(newDate);
setFieldValue("dateBirth", newDate);
}}
renderInput={(params) => <TextField
className={classes.textField}
sx={{ color: 'red', display: 'inline', fontSize: 8, height: "75%" }}
variant='outlined'
size="small"
InputProps={{
className: classes.input,
}}
{...params} />}
/>
</LocalizationProvider>
</div>
)
}
This renders the following:
MUI styling
The only thing I have been able to do to change the box size is the inline size="small" property. Thanks in advance.

Navigation inside TabBar React Native

I'm pretty new to React Native, I have the following tab bar navigation page:
const TabBar = () => {
return (
<BottomTab.Navigator
screenOptions={{
showIcon: true,
tabBarShowLabel: false,
tabBarStyle: {
position: "absolute",
bottom: 25,
left: 20,
right: 20,
elevation: 0,
backgroundColor: global.GUI.WHITE,
borderRadius: 15,
height: 90,
...styles.shadow,
},
header: ({ navigation, route, options }) => {
return (
<View
style={{
justifyContent: "space-between",
height: 110,
backgroundColor: global.GUI.WHITE,
alignItems: "center",
width: "100%",
flexDirection: "row",
...styles.shadow,
}}
>
<Image
source={ctsLogo}
style={{
resizeMode: "contain",
width: 100,
height: 70,
marginTop: 40,
marginLeft: 10,
}}
/>
<Button title="test" onPress={()=>{
}}>
<FontAwesomeIcon
icon={faCog}
style={{
color: global.GUI.ORANGE,
marginTop: 40,
marginRight: 20,
}}
size={30}
/>
</Button>
</View>
);
},
}}
>
<BottomTab.Screen
name="Home"
component={Main}
options={{
...
}}
/>
<BottomTab.Screen
name="Flyers"
component={Flyers}
options={{
...
}}
/>
<BottomTab.Screen
name="OnlineShop"
component={OnlineShop}
options={{
...
}}
/>
<BottomTab.Screen
name="Cards"
component={Cards}
options={{...}}
/>
<BottomTab.Screen
name="Shops"
component={Shops}
options={{
....
}}
/>
</BottomTab.Navigator>
);
};
I want to add navigate to another page while remaining in the context of the tab bar (let's says I want to go to another component called "Settings") programmatically by triggering the test button:
<Button title="test" onPress={()=>{...}}>
Inside the custom header, is it possible to do that? Thanks
EDIT:
I've changed my App.js code to this:
import { NavigationContainer } from "#react-navigation/native";
import { createNativeStackNavigator } from "#react-navigation/native-stack";
import TabBar from "./navigation/TabBar";
import Settings from "./page/Settings";
const Stack = createNativeStackNavigator();
export default function App() {
function Tabs() {
return <TabBar />;
}
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Tabs" component={Tabs}
options={{ headerShown: false }}/>
<Stack.Screen name="Settings" component={Settings} />
</Stack.Navigator>
</NavigationContainer>
);
}
And now I'm able to navigate, thanks!
inside your SCREEN call navigation hook
const navigation = useNavigation();
then u can use NAVIGATION functions anywhere you want :) even inside Button
Button
<Button title="test" onPress={()=>{
navigation.navigate('Settings') // param here is "name" prop from your navigator
// navigation.goBack()
}}>
Try using this
props.navigation.navigate('Settings')

Custom Drawer in react navigation

In my react native project I have custom drawer with screens like screen1 and screen2. Screen1 is used for stack navigator and in Screen 2 it contains tab navigator. How to enable this kind of nesting navigation.
I am using react navigation 5 in order to build custom drawer.
Here is my code:
import { DrawerContentScrollView, DrawerItem } from "#react-navigation/drawer";
.............
render = () => {
<DrawerContentScrollView {...props}>
<View style={styles.menuContainer}>
<View style={[styles.menuItemsCard, { backgroundColor: "#fff2df" }]}>
<View style={[styles.circleContainer, { backgroundColor: "#FFC56F" }]}>
<Icon travel name="suitcase" type="font-awesome" color="#fbae41" />
</View>
<DrawerItem
label="Screen1"
labelStyle={{ color: "#fbae41", fontSize: 10 }}
onPress={() => {
props.navigation.navigate("PatientInfo");
}}
/>
</View>
<View style={[styles.itemCard, { backgroundColor: "#EFFFD5" }]}>
<View style={[styles.circleContainer, { backgroundColor: "#b5ff39" }]}>
<Icon Medical name="briefcase" type="font-awesome" color="#609806"></Icon>
</View>
<DrawerItem
label="Screen2"
labelStyle={{ color: "#609806" }}
onPress={() => {
props.navigation.navigate("Diagnose");
}}
/>
</View>
</View>
</DrawerContentScrollView>
}
mainNaviagtor:
const MainNavigator = () => {
return (
<Drawer.Navigator drawerContent={props => <Menu {...props} />} drawerStyle={{ width:
"100%" }}>
<Stack.Screen name="Screen1" component={PatientInfoScreen} screenOptions={headerOptions} />
<Stack.Screen name="Screen2" component={DiagnoseScreen} /> //Here i need tab navigator
</Drawer.Navigator>
);
};
My older code: (react navigation 4.x)
createDrawerNavigator(
{
Screen1: {
screen: createStackNavigator(
{
PatientInfo: { screen: PatientInfoScreen }
},
headerOptions
)
},
Screen2: {
screen: createBottomTabNavigator({
Diagnose: {
screen: diagnoseNavigation
},
Causes: { screen: causeNavigation },
})
},
})
Output:
How should I solve this issue? I also referred to the https://reactnavigation.org/docs/nesting-navigators/.
Any one please help me to solve this issue.
Working Example: Expo Snack
Final Output:
Full source Code:
import * as React from 'react';
import {
View,
Text,
StyleSheet,
useWindowDimensions,
Button,
} from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { Feather } from '#expo/vector-icons';
import { createStackNavigator } from '#react-navigation/stack';
import {
createDrawerNavigator,
DrawerContentScrollView,
DrawerItemList,
DrawerItem,
} from '#react-navigation/drawer';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
const Drawer = createDrawerNavigator();
const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();
function TabNav() {
return (
<Tab.Navigator>
<Tab.Screen
name="TabOne"
component={() => (
<View style={styles.container}>
<Text>TabOne</Text>
</View>
)}
/>
<Tab.Screen
name="TabTwo"
component={() => (
<View style={styles.container}>
<Text>TabTwo</Text>
</View>
)}
/>
</Tab.Navigator>
);
}
const StackNav = () => {
return (
<Stack.Navigator>
<Stack.Screen name="Feed" component={Feed} />
<Stack.Screen name="Article" component={Article} />
</Stack.Navigator>
);
};
function CustomDrawerContent(props) {
const width = useWindowDimensions().width * 0.3;
return (
<DrawerContentScrollView {...props}>
<View style={styles.menuContainer}>
<View
style={[
styles.menuItemsCard,
{ backgroundColor: '#fff2df', width: width, height: width },
]}>
<>
<View
style={[styles.circleContainer, { backgroundColor: '#FFC56F' }]}>
<Feather travel name="briefcase" size={25} color="#fbae41" />
<DrawerItem
label="Screen1"
labelStyle={{ color: '#fbae41', fontSize: 10 }}
onPress={() => {
props.navigation.navigate('Screen1');
}}
/>
</View>
</>
<DrawerItem
style={{
position: 'absolute',
left: 0,
width: width,
height: width,
}}
label="Screen2"
labelStyle={{ color: '#609806' }}
onPress={() => {
props.navigation.navigate('Screen1');
}}
/>
</View>
<View
style={[
styles.menuItemsCard,
{ backgroundColor: '#EFFFD5', width: width, height: width },
]}>
<View
style={[styles.circleContainer, { backgroundColor: '#b5ff39' }]}>
<Feather Medical name="briefcase" size={25} color="#609806" />
</View>
<DrawerItem
style={{
position: 'absolute',
left: 0,
width: width,
height: width,
}}
label="Screen2"
labelStyle={{ color: '#609806' }}
onPress={() => {
props.navigation.navigate('StackNav');
}}
/>
</View>
</View>
</DrawerContentScrollView>
);
}
function MyDrawer() {
return (
<Drawer.Navigator
drawerContent={(props) => <CustomDrawerContent {...props} />}>
<Drawer.Screen name="Screen1" component={StackNav} />
<Drawer.Screen name="StackNav" component={TabNav} />
</Drawer.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<MyDrawer />
</NavigationContainer>
);
}
function Feed({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Feed Screen</Text>
<Button
title={'Article'}
onPress={() => navigation.navigate('Article')}
/>
</View>
);
}
function Article({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Article Screen</Text>
<Button title={'Feed'} onPress={() => navigation.navigate('Feed')} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
menuContainer: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-evenly',
},
menuItemsCard: {
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
borderRadius: 10,
},
circleContainer: {
width: 50,
height: 50,
borderRadius: 25,
padding: 10,
},
});

How do I pass a Prop to a Navigation Screen Component - React Native

I'm fairly new to React native . I have created a Drawer Navigator in my App.js file.
One of my navigation Components is a component named LoginScreen.
I am trying to to pass a prop to LoginScreen to display when the user navigates to it.
App.js (Navigator)
const Tab = createMaterialBottomTabNavigator()
const Stack = createStackNavigator()
const Drawer = createDrawerNavigator()
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
isAdmin: 'false',
checked: false,
}
}
async componentDidMount() {
try {
const adm = await AsyncStorage.getItem('is_admin')
if (adm == null) {
adm = await AsyncStorage.setItem('is_admin', 'false')
}
this.setState({ isAdmin: adm, checked: true })
} catch (error) {
console.log(error)
}
}
render() {
const { isAdmin } = this.state
console.log(isAdmin)
//is admin
return isAdmin == 'true' ? (
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={MyStack} />
<Drawer.Screen
name="Admin Panel"
component={props => {
return <LoginScreen props={props} propName = {'Hello'} />
}}
/>
</Drawer.Navigator>
</NavigationContainer>
) : (
//ISNOT ADMIN
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={MyStack} />
<Drawer.Screen name="Login" component={LoginScreen} />
</Drawer.Navigator>
</NavigationContainer>
)
}
}
LginScreen.js
const LoginScreen = ({ navigation, propName }) => {
// const [bridge, setB] = useState(false)
return (
<SafeAreaView style={{ flex: 1, backgroundColor: '#376772' }}>
<TopHeader
onRefresh={() => fetch_crossings}
onMenuToggle={() => navigation.toggleDrawer()}
/>
<View style={{ flex: 1 }}>
<View
style={{
backgroundColor: '#fff',
margin: 10,
borderRadius: 5,
alignItems: 'center',
padding: 10,
paddingBottom: scale(20),
}}
>
<Avatar
rounded
size={'xlarge'}
overlayContainerStyle={{
backgroundColor: '#185a9d',
}}
icon={{
color: 'orange',
type: 'ionicon',
name: 'ios-log-in',
}}
/>
<Input
placeholder=" Email"
placeholderTextColor={'#292b2c'}
style={{ margin: 5 }}
errorStyle={{ color: '#d9534f' }}
leftIcon={<Icon name="mail" color="#292b2c" />}
errorMessage="Enter a valid Email"
/>
<Divider
style={{
backgroundColor: 'orange',
height: 3,
margin: scale(20),
borderRadius: 3,
}}
/>
<Input
placeholder=" Password"
placeholderTextColor={'#292b2c'}
secureTextEntry={true}
style={{ margin: 5 }}
errorStyle={{ color: '#d9534f' }}
leftIcon={<Icon name={'lock'} color="#292b2c" />}
errorMessage="Enter a valid Email"
/>
</View>
<View
style={{
backgroundColor: '#fff',
margin: 10,
marginTop: 0,
borderRadius: 5,
padding: 10,
}}
>
<Button
buttonStyle={{
margin: 10,
backgroundColor: '#5cb85c',
borderRadius: 4,
alignSelf: 'stretch',
}}
onPress={async () => {
try {
await AsyncStorage.setItem('is_admin', 'false')
**console.log(propName);** //<--Right HERE
navigation.navigate('Home')
} catch (error) {
console.log(error)
}
}}
icon={<Icon name="send" size={15} color="white" />}
iconRight
titleStyle={{ fontWeight: 'bold' }}
title="Submit "
/>
<Button
buttonStyle={{
margin: 10,
backgroundColor: '#d9534f',
borderRadius: 4,
alignSelf: 'stretch',
}}
onPress={() => {
navigation.navigate('Home')
}}
icon={<Icon name="close" size={15} color="white" />}
iconRight
titleStyle={{ fontWeight: 'bold' }}
title={'Close '}
/>
</View>
</View>
</SafeAreaView>
)
}
export default LoginScreen
Whenever I console.log(propName), it says that its undefined.
Asad's Answer actually helped me get to this :
App.js (Navigation)
Here, we can add the 'initialParams' parameter to <Drawer.Screen/> :
<Drawer.Screen
name="Login"
component={LoginScreen}
initialParams={{ post: this.state.isAdmin }} //<-- Right here
/>
Then we can receive as such in LoginScreen.js as such :
const LoginScreen = ({ navigation, route }) => {
console.log(route.params.post)
return (
<Text>{route.params.post}</Text>
)
}
Another way:
<Drawer.Navigator
initialRouteName="Updates"
drawerContentOptions={{ style: { paddingVertical: 50 } }}>
<Drawer.Screen name="Updates" options={screenOptions}>
{props => (
<UpdatesScreen myProp={this.state.someProp} />
)}
</Drawer.Screen>
...
</Drawer.Navigator>

Categories