I have created custom MUI TextField
const CustomDisableInput = styled(TextField)(() => ({
".MuiInputBase-input.Mui-disabled": {
WebkitTextFillColor: "#000",
color: "#000",
},
input: {
"&[type=number]": {
"-moz-appearance": "textfield",
},
"&::-webkit-outer-spin-button": {
"-webkit-appearance": "none",
margin: 0,
},
"&::-webkit-inner-spin-button": {
"-webkit-appearance": "none",
margin: 0,
},
},
}));
<CustomDisableInput
fullWidth
variant="standard"
size="small"
type="text"
sx={{
backgroundColor: "grey.300",
borderRadius: "3px",
paddingX: "3px",
}}
InputProps={{
disableUnderline: true,
}}
disabled={!isEditMode}
/>
now I want to apply
sx={{ backgroundColor: "grey.300",borderRadius: "3px",paddingX: "3px"}}
only when isEditMode is true.
What i tried ?
<CustomDisableInput
fullWidth
variant="standard"
size="small"
type="text"
sx={ isEditMode && {
backgroundColor: "grey.300",
borderRadius: "3px",
paddingX: "3px",
}}
InputProps={{
disableUnderline: true,
}}
disabled={!isEditMode}
/>
but it gives error
Type 'false | { backgroundColor: "grey.300"; borderRadius: string; paddingX: string; }' is not assignable to type 'SxProps<Theme> | undefined'.
Type 'false' is not assignable to type 'SxProps<Theme> | undefined'. TS2322
...
sx={isEditMode ? {
backgroundColor: "grey.300",
borderRadius: "3px",
paddingX: "3px",
} : {}}
or
const CustomDisableInput = styled(({ isEditMode, ...props }) => (
<TextField {...props} />
))(({ theme, isEditMode }) => ({
".MuiInputBase-input.Mui-disabled": {
WebkitTextFillColor: "#000",
color: "#000",
},
input: {
"&[type=number]": {
"-moz-appearance": "textfield",
},
"&::-webkit-outer-spin-button": {
"-webkit-appearance": "none",
margin: 0,
},
"&::-webkit-inner-spin-button": {
"-webkit-appearance": "none",
margin: 0,
},
},
...isEditMode && {
backgroundColor: "grey.300",
borderRadius: "3px",
paddingX: "3px",
}
}));
Related
Hello I tried implementing Material UI Autocomplete component to use it as a search input. I used styled function from "#mui/material/styles" and added some custom CSS but when the page first loads you can see the CSS code instead of the actual component for a split second before appearing. Here is a screenshot of the problem:
The source code appears for a split second on the first load of the page before the Autocomplete component appears
Here is the Autocomplete component:
<Autocomplete
value={undefined || autoValue}
freeSolo
id="autocomplete"
autoHighlight={true}
autoSelect={true}
autoComplete={true}
open={open}
onClose={() => setOpen(false)}
onOpen={() => setOpen(true)}
disableClearable
// className="w-full"
fullWidth
options={items.map((item: string) => ({
url: item,
title: makeTitle(item),
}))}
getOptionLabel={(option: any) => option.title || ""}
renderOption={(props, option: Item) => {
return (
<li
key={option.url}
className=" hover:bg-slate-200 "
onClick={handleOptionClick}
>
<Link
href={`/calculators/${option.url}`}
className="block p-4 w-full"
>
{makeTitle(option.title)}
</Link>
</li>
);
}}
renderInput={(params) => (
<SearchTextField
{...params}
ref={textInput}
// onChange={(e) => console.log(e.target.value)}
// value="Hello"
variant="outlined"
// onChange={handleChange}
InputProps={{
...params.InputProps,
type: "search",
startAdornment: (
<InputAdornment position="start">
<SearchIcon style={{ color: "white" }} />
</InputAdornment>
),
}}
/>
)}
/>
And here is the CSS:
const SearchTextField = styled(TextField)({
"& .MuiInputBase-root": {
backgroundColor: "rgb(40,80,170)",
"&:hover": {
backgroundColor: "rgb(36,69,159)",
},
"&.Mui-focused": {
backgroundColor: "rgb(36,69,159)",
},
},
// "& .MuiAutocomplete-input": {
// paddingLeft: "10px !important",
// },
"& .MuiInputBase-input": {
backgroundColor: "white",
borderRadius: `90px`,
paddingLeft: "16px !important",
},
"& label.Mui-focused": {
color: "white",
},
"& .MuiInput-underline:after": {
borderBottomColor: "white",
},
"& .MuiOutlinedInput-root": {
borderRadius: `90px`,
"& fieldset": {
borderStyle: "none",
borderRadius: `90px`,
paddingRight: "10px",
},
"&:hover fieldset": {
borderStyle: "none",
borderColor: "white",
},
"&.Mui-focused fieldset": {
borderStyle: "none",
borderColor: "white",
},
},
});
I've never seen CSS source code rendering on the browser tried looking in Material UI forums but could not find anything. It does not look to happen in mobile browsers only desktop.
I can't figure out how my InputAdornment is getting improperly placed.
I can't see anything in my styles that would influence the position of the icon within the TextField (e.g. padding, flex stuff).
How it currently looks - calendar does not sit on the line/within text field input
How I would like it to look - but of course with a calendar icon and not a 'kg' :)
My styles object (with some ... used for brevity)
const useStyles = makeStyles(theme => ({
input: {
'& input, textarea': {
paddingTop: 8,
paddingBottom: 12,
fontSize: 15,
marginTop: 15,
'&:focus': {
borderBottomColor: COLORS.BLACK
},
'&::placeholder': {
fontSize: 15
}
},
},
...
dashboardInput: {
'& .MuiInputLabel-root': {
color: theme.palette.text.primary,
fontSize: 16,
},
'& input, textarea': {
borderBottom: `1px solid ${COLORS.BLACK}`,
fontSize: 16,
'&::placeholder': {
color: theme.palette.grey[400],
},
'&:disabled': {
color: COLORS.BLACK
}
},
'& .MuiFormHelperText-root': {
color: theme.palette.grey[500],
fontSize: 10
},
},
...
inputLimiter: {
textAlign: 'right',
fontSize: 10
},
...
},
}));
The relevant guts of the component:
<FormControl
fullWidth
className={classNames(classes.input, getInputStyle(appearance), {
[classes.error]: error
})}
>
<InputLabel shrink htmlFor={name}>
<div className={classes.divcontrol}><div>{label}</div><div className={classes.redAsterisk}>*</div></div>
</InputLabel>
<TextField
id={name}
placeholder={placeholder}
fullWidth
multiline={multiline}
rows={multiline ? rows : 0}
type={type}
style={style}
inputProps={{
maxLength,
}}
defaultValue={defaultValue}
disabled={disabled}
onChange={e => onChangeWithRightType(e)}
InputLabelProps={{
shrink: true,
}}
value={value}
{...props}
InputProps={{
disableUnderline: true,
endAdornment: (
<InputAdornment position="end">
<DateRange />
</InputAdornment>
),
}}
error
helperText={helperText}
/>
{maxLength && (
<Typography variant="body2" className={classes.inputLimiter}>
{value ? String(value).length : 0}/{maxLength}
</Typography>
)}
</FormControl>
About your question, I think you should set disableUnderline in InputProps to false.
InputProps={{
disableUnderline: false,
......
}}
I am trying to use the GooglePlacesAutocomplete, but once I make the address query, for example: "São C" and the "listView" return something like: "São Caetano, São Paulo ...", but when I try to select one option it seems like the list is not visible, because and the selection do not affect the item list.
this is the code I am using:
import * as React from 'react';
import { Platform, StyleSheet, Text, View } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
import { colors, device, fonts } from '../constants';
// icons
import SvgTruck from './icons/Svg.Truck';
//const { onLocationSelected } = this.props
// constants
const GOOGLE_MAPS_APIKEY = '[API KEY]'
const WhereTo = () => (
<View style={styles.container}>
<View style={styles.containerBanner}>
<Text style={styles.bannerText}>15% off, up to $6.00</Text>
<Text style={styles.bannerMuted}>3 days</Text>
</View>
<View style={styles.containerInput} >
<View style={styles.containerSquare}>
<View style={styles.square} />
</View>
<GooglePlacesAutocomplete
styles={{
textInputContainer: {
flex: 1,
backgroundColor: 'transparent',
height: 54,
marginHorizontal: 20,
borderTopWidth: 0,
borderBottomWidth:0
},
textInput: {
height: 45,
left:0,
margin: 0,
borderRadius: 0,
paddingTop: 0,
paddingBottom: 0,
paddingLeft: 0,
paddingRight: 0,
padding: 0,
marginTop: 0,
marginLeft: 0,
marginRight: 0,
fontSize:18
},
listView: {
position:'absolute',
marginTop: 50
},
description: {
fontSize:16
},
row: {
padding: 18,
height:58
}
}}
placeholder="Para onde?"
onPress={(data, details) => {
// 'details' is provided when fetchDetails = true
console.log(data, details);
}}
query={{
key: GOOGLE_MAPS_APIKEY,
language: 'pt',
components: "country:br"
}}
textInputProps={{
autoCapitalize: "none",
autoCorrect: false
}}
fetchDetails
enablePoweredByContainer={false}
/>
<View style={styles.containerIcon}>
<SvgTruck />
</View>
</View>
</View>
);
const styles = StyleSheet.create({
container: {
top: Platform.select({ ios: 60, android: 40 }),
alignSelf: 'center',
position: 'absolute',
shadowColor: colors.black,
shadowOffset: { height: 2, width: 0 },
shadowOpacity: 0.2,
shadowRadius: 8,
top: device.iPhoneX ? 144 : 120,
width: device.width - 40
},
containerBanner: {
backgroundColor: colors.green,
borderTopLeftRadius: 4,
borderTopRightRadius: 4,
flexDirection: 'row',
justifyContent: 'space-between',
paddingHorizontal: 16,
paddingVertical: 8
},
bannerText: {
color: colors.white,
fontFamily: fonts.uberMedium,
fontSize: 12
},
bannerMuted: {
color: colors.mint,
fontFamily: fonts.uberMedium,
fontSize: 12
},
containerInput: {
alignItems: 'center',
backgroundColor: colors.white,
flexDirection: 'row',
height: 48
},
containerSquare: {
alignItems: 'center',
flex: 0.15
},
square: {
backgroundColor: colors.black,
height: 8,
width: 8
},
containerIcon: {
alignItems: 'center',
borderLeftColor: colors.greyMercury,
borderLeftWidth: 1,
flex: 0.2
}
});
export default WhereTo;
Can anyone trying to help me to solve it?
I recreated the Expo project and now it works, I could not found the root cause, but once that other project was made by other person and Expo make it easy to do and configure, it was fast enoght to create.
export default function AskForDriver () {
const [location, setLocation] = useState("");
const [errorMsg, setErrorMsg] = useState("");
useEffect(() => {
(async () => {
let { status } = await Location.requestPermissionsAsync();
if (status !== 'granted') {
setErrorMsg('Permission to access location was denied');
}
let location = await Location.getCurrentPositionAsync({});
setLocation(location);
})();
}, []);
let text = 'Waiting..';
if (errorMsg) {
text = errorMsg;
} else if (location) {
text = JSON.stringify(location);
console.log('location - latitude: ', location.coords.latitude)
console.log('location - longitude: ', location.coords.longitude)
}
return (
<View style={styles.container}>
<View style={styles.mainHeader}>
<Text style={styles.fontHeader}>Incluir flatlist com promoções e mensagens de incentivos</Text>
</View>
<View style={styles.searchHeader}>
<GooglePlacesAutocomplete
currentLocation
//styles={styles.placesautocomplete}
styles={{
textInputContainer: {
backgroundColor: 'grey',
},
placesautocomplete: {
flex:1,
},
textInput: {
height: 38,
color: '#5d5d5d',
fontSize: 16,
},
predefinedPlacesDescription: {
color: '#1faadb',
},
}}
placeholder='Search'
onPress={(data, details = null) => {
// 'details' is provided when fetchDetails = true
console.log(data, details);
}}
query={{
key: 'YOUR API KEY',
language: 'pt',
components: 'country:br',
}}
/>
</View>
<MapView
style={styles.mapStyle}
showsMyLocationButton
initialRegion={{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
>
</MapView>
{//<Text>{text}</Text>
}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
position: 'absolute',
alignContent:'center',
margin:0
},
mainHeader: {
backgroundColor: '#10002b',
padding:10,
},
fontHeader: {
color: '#e0aaff',
fontSize: 15,
},
searchHeader: {
borderColor: '#333',
borderWidth:5,
},
mapStyle: {
flex:1,
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
},
});
I currently need to add marginLeft of 8px to FormHelperText. But havent been able to do it on the MuiInput formControl rule or in MuiSelect.
This is the React code:
<FormControl error className={classes.margin} fullWidth>
<InputLabel className={classes.label} id="demo-error-select-label">
Error select
</InputLabel>
<Select
labelId="demo-error-select-label"
id="demo-error-select"
value={option}
onChange={handleChange}
IconComponent={() => <Icon24UtilityChevron component="select" height="20px" />}>
<MenuItem value="">Select</MenuItem>
<MenuItem value={1}>Option1</MenuItem>
<MenuItem value={2}>Option2</MenuItem>
<MenuItem value={3}>Option3</MenuItem>
</Select>
<FormHelperText>Error</FormHelperText>
</FormControl>
This is the MuiSelect object that override default styles with createMuiTheme (ommited for briefly explanation):
const MuiSelect = {
select: {
backgroundColor: selectColors.background,
padding: '12px 16px 12px 16px !important',
fontSize: '18px',
borderRadius: 12,
borderWidth: '1px',
borderStyle: 'solid',
borderColor: selectColors.border,
'&:focus': {
borderRadius: 12,
borderWidth: '2px',
borderStyle: 'solid',
borderColor: selectColors.borderFocus,
},
},
selectMenu: {
'&:hover:not(.Mui-disabled):not(.Mui-error)': {
backgroundColor: selectColors.hoverBackground,
},
},
};
This is the MuiInput object that override default styles with createMuiTheme (ommited for briefly explanation):
This is an example of the FormControl being created (need to move the Error label 8px to the left):
[![enter image description here][1]][1]
const MuiInput = {
formControl: {
'label + &': {
marginTop: '2px',
},
},
root: {
borderRadius: '12px',
borderColor: inputColors.inputBorder,
borderWidth: '1px',
borderStyle: 'solid',
'&$error': {
borderColor: inputColors.inputError,
},
'&:focus-within': {
borderColor: inputColors.inputBorderFocus,
},
'& svg': {
marginRight: '16px',
},
},
input: {
backgroundColor: inputColors.inputBackground,
caretColor: inputColors.inputCaret,
paddingLeft: '8px',
paddingRight: '8px',
color: inputColors.inputText,
borderRadius: '12px',
},
multiline: {
paddingTop: '0px',
paddingBottom: '0px',
},
underline: {
'&:hover:not(.Mui-disabled):before': { borderBottomWidth: '0px' },
'&:before': { borderBottomWidth: '0px' },
'&:after': { borderBottomWidth: '0px' },
},
};
Take a look at the visual example of the code (the lower error text is the one that needs to be moved):
I could solve it by using ~ selector. Code:
const MuiInput = {
formControl: {
'label + &': {
marginTop: '2px',
},
'& ~ p': {
marginTop: '4px',
marginLeft: '8px',
},
},
...
This question already has answers here:
How can I vertically align elements in a div?
(28 answers)
Closed 2 years ago.
I try to align my menu properly but it's not working properly. So the way it's done is that when you arrive on my website and not logged in, the header below is displayed:
When the user is loggedin, the login/register is replaced by a scrolldown menu which is triggered by the click of an avatar. The scroll down works fine but the render of the menu is not aligned as you see below:
I am not able to make the avatar and the menu properly aligned as it's done at first.
below is code:
const fakeName = "First Last";
const isGuest = false;
const StyledProfileMenu = withStyles({
paper: {
border: '1px none',
borderRadius: "21px",
boxShadow: "0px 8px 18px 0 rgba(0,0,0,0.14)",
},
})((props) => (
<Menu
elevation={0}
getContentAnchorEl={null}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
{...props}
/>
));
const StyledProfileMenuItem = withStyles((theme) => ({
root: {
margin: "2px 30px 1px 10px",
fontFamily: "Source Sans Pro",
fontSize: "",
'&:hover': {
backgroundColor: "#ffffff",
color: '#ff7255'},
'&:focus': {
backgroundColor: "#ffffff",
color: '#ff7255'},
},
}))(MenuItem);
const useStyles = makeStyles(theme => ({
root: {
boxShadow: "none",
backgroundColor: "#ffffff",
marginTop: theme.spacing(3)
},
logo: {
width:"214px",
height:"28px",
marginLeft: theme.spacing(20),
marginRight: theme.spacing(3)
},
search: {
position: 'relative',
borderRadius: "21px",
backgroundColor: "#f4f7f8",
marginRight: theme.spacing(2),
marginLeft: theme.spacing(3),
width: "467px",
height: "40px",
// [theme.breakpoints.up('sm')]: {
// marginLeft: theme.spacing(3),
// width: 'auto',
// },
},
searchIcon: {
padding: theme.spacing(1, 2),
height: '18px',
width: '18px',
position: 'absolute',
pointerEvents: 'none',
alignItems: 'center',
justifyContent: 'center',
color: "#cecece"
},
inputRoot: {
color: "#cecece",
fontFamily: "Source Sans Pro",
fontSize: "18px"
},
inputInput: {
paddingLeft: `calc(1em + ${theme.spacing(4)}px)`,
width: "467px",
// [theme.breakpoints.up('md')]: {
// width: '20ch',
// },
},
menu: {
display: "flex",
marginLeft: theme.spacing(2),
margin: "auto",
},
menuItem: {
color: "#cecece",
fontSize: "20px",
fontFamily: "Fredoka One",
fontWeight: "bold",
'&:hover': {
backgroundColor: "#ffffff",
color: '#ff7255'},
'&:focus': {
backgroundColor: "#ffffff",
color: '#ff7255'},
marginRight: theme.spacing(3),
marginLeft: theme.spacing(3),
},
userName: {
fontFamily: "Source Sans Pro",
fontWeight: "Bold",
borderBottom: '3px solid #ff7255',
textAlign: "center",
margin: "2px 10px 2px 10px",
paddingBottom: "2px"
}
}));
function Header(){
let loginOrProfile;
const styles = useStyles();
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const profileMenu =
<div>
<IconButton
aria-controls="customized-menu"
aria-haspopup="true"
variant="contained"
color="primary"
onClick={handleClick}>
<Avatar alt="Avatar" src={DefaultAvatar} />
<ArrowDropDownIcon style={{ color: "#ff7255" }}/>
</IconButton>
<StyledProfileMenu
id="customized-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}>
<p className={styles.userName}> {fakeName} </p>
<StyledProfileMenuItem>
<ListItemText primary={TextContents.MenuProfile} />
</StyledProfileMenuItem>
<StyledProfileMenuItem>
<ListItemText primary={TextContents.MenuMessages} />
</StyledProfileMenuItem>
<StyledProfileMenuItem>
<ListItemText primary={TextContents.MenuSettings} />
</StyledProfileMenuItem>
<StyledProfileMenuItem>
<ListItemText primary={TextContents.MenuLogout} />
</StyledProfileMenuItem>
</StyledProfileMenu>
</div>;
const loginMenu =
<Typography className={styles.menuItem}> {TextContents.MenuLoginRegister} </Typography>;
if(isGuest){
loginOrProfile = loginMenu;
} else {
loginOrProfile = profileMenu;
}
return (
<div className={styles.root}>
<AppBar position="static" className={styles.root}>
<Toolbar>
<img src={VillageLogo} alt="logo" className={styles.logo}/>
<div className={styles.search}>
<div className={styles.searchIcon}>
<SearchIcon />
</div>
<InputBase
placeholder={TextContents.SearchPlaceHolder}
classes={{
root: styles.inputRoot,
input: styles.inputInput,
}}
inputProps={{ 'aria-label': 'search' }}
/>
</div>
<div className={styles.menu}>
<Typography className={styles.menuItem}> {TextContents.MenuDiscover} </Typography>
<Typography className={styles.menuItem}> {TextContents.MenuCreate} </Typography>
<Typography className={styles.menuItem}> {TextContents.MenuHiW} </Typography>
{isGuest && loginMenu}
{!isGuest && profileMenu}
</div>
</Toolbar>
</AppBar>
</div>
);
}
export default Header
If someone may have any idea how to make the alignment proper, I would be super happy
try this:
display: flex;
align-items: center;