How to style react autocomplete input box? - reactjs

I am trying to use react-autocomplete in my component. Everything is working fine results are shown. But I am not able to style the default input box.
this is autocomplete
<Autocomplete
getItemValue={this.getItemValue}
items={this.state.autocompleteData}
renderItem={this.renderItem}
value={this.state.value}
onChange={this.onChange}
onSelect={this.onSelect}
menuStyle={menuStyle}
/>
style for dropdown menu is working fine.
const menuStyle = {
borderRadius: '3px',
boxShadow: '0 2px 12px rgba(0, 0, 0, 0.1)',
background: 'rgba(255, 255, 255, 0.9)',
padding: '2px 0',
fontSize: '90%',
position: 'fixed',
overflow: 'auto',
maxHeight: '50%', // TODO: don't cheat, let it flow to the bottom
"zIndex": 100,
};
i tried to add style as per answer in this question but it's not working.
how to increase input text box size in react-autocomplete?
How to add style to input box?

The object given to prop inputProps is used as props for the input, so you can give an object with a style property containing your menuStyles to that.
<Autocomplete
getItemValue={this.getItemValue}
items={this.state.autocompleteData}
renderItem={this.renderItem}
value={this.state.value}
onChange={this.onChange}
onSelect={this.onSelect}
inputProps={{ style: menuStyle }}
/>

inputProps={{ style: menuStyle }}
or you can do
styling={
borderRadius: '3px',
boxShadow: '0 2px 12px rgba(0, 0, 0, 0.1)',
background: 'rgba(255, 255, 255, 0.9)',
padding: '2px 0',
fontSize: '90%',
position: 'fixed',
overflow: 'auto',
maxHeight: '50%', // TODO: don't cheat, let it flow to the bottom
"zIndex": 100,
}

Related

How to add a label to a border in mui?

I would like to have a list wrapped in a border which looks and behaves the same as a textfield border:
Example textfield and list which should have both same border.
In the image, the border around the list looks similar than the one around the textfield but most notably, the label is missing. How can I add the label and how would I set up the focus listeners to get the same hover and selection behaviour?
The typescript code for the list:
<List dense sx={{ borderRadius: 1, border: 1, borderColor: 'grey.600'}}>
<ListItem secondaryAction={<IconButton edge="end" aria-label="delete"><DeleteIcon /></IconButton>}>
<ListItemText primary="primary" secondary="group id"/>
</ListItem>
</List>
I am also open for alternative approaches. Thanks for the help.
Here is my answer using React and Mui (only for icon).
It relies on flex.
We have a main container that only draws its left, bottom and right borders.
Then we have a header container in charge of drawing the top border in two parts (before and after) and a section with an icon and title.
You can either pass an icon and a title, just a title, just an icon, or nothing at all.
borderedSection.js:
import React from "react";
import SvgIcon from "#mui/material/SvgIcon";
import styles from "./borderedSection.module.scss";
function BorderedSection({ icon, title, children }) {
return (
<div className={styles.mainContainer}>
<div className={styles.header}>
<div className={styles.headerBorderBefore}></div>
{(icon || title) && (
<div className={styles.headerTitle}>
{icon && <SvgIcon component={icon} />}
{title && <span className={styles.title}>{title}</span>}
</div>
)}
<div className={styles.headerBorderAfter}></div>
</div>
<div className={styles.childrenContainer}>{children}</div>
</div>
);
}
export default BorderedSection;
borderedSection.module.scss:
$border-color: #b2b2b2;
.mainContainer {
display: flex;
flex-direction: column;
max-width: 100%;
border-left: 1px solid $border-color;
border-bottom: 1px solid $border-color;
border-right: 1px solid $border-color;
border-radius: 5px;
margin: 1em;
.childrenContainer {
padding: 1em;
}
.header {
display: flex;
flex-direction: row;
width: 100% !important;
.headerBorderBefore {
border-top: 1px solid $border-color;
width: 1em;
border-top-left-radius: 5px;
}
.headerTitle {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
gap: 0.25em;
width: fit-content;
height: 2em;
margin: -1em 0.5em 0em 0.5em;
overflow: hidden;
text-overflow: ellipsis;
font-size: 1em;
font-weight: 600;
}
.headerBorderAfter {
border-top: 1px solid $border-color;
width: 1em;
flex-grow: 2;
border-top-right-radius: 5px;
}
}
}
usage:
import React from "react";
import BorderedSection from "./borderedSection";
import InfoIcon from "#mui/icons-material/Info";
function Example() {
return (
<div style={{ padding: "2em" }}>
<BorderedSection icon={InfoIcon} title="Icon and title">
<div>a first child with quite a long text</div>
<div>a second child</div>
</BorderedSection>
<BorderedSection title="Title only">
<div>a first child with quite a long text</div>
<div>a second child</div>
</BorderedSection>
<BorderedSection icon={InfoIcon} >
<div>Icon only</div>
<div>a second child with quite a long text</div>
</BorderedSection>
<BorderedSection >
<div>No icon and no title</div>
<div>a second child with quite a long text</div>
</BorderedSection>
</div>
);
}
Here is how it looks:
I hope it helps
I now managed to hack a solution which looks the same. I do still hope though that there is a clean way to do this: result.
<FormLabel style={{marginLeft: "0.71em", marginTop: "-0.71em", paddingLeft: "0.44em", zIndex: 2, width: "4.2em", backgroundColor: "#383838", position: "absolute", fontSize: "0.75em"}}>Damage</FormLabel>
<List dense sx={{ borderRadius: 1, border: 1, borderColor: 'grey.600', "&:hover": { borderColor: 'grey.200' }}}>
<ListItem secondaryAction={<IconButton edge="end" aria-label="delete"><DeleteIcon /></IconButton>}>
<ListItemText primary="primary" secondary="group id"/>
</ListItem>
</List>
I needed the same thing. As I was poking around I noticed that MUI accomplished this by using the fieldset tag. I created a quick and dirty component (OutlinedBox) to get this effect:
import React from "react";
import {Box, FormLabel} from "#mui/material";
const OutlinedBox = (props) => {
const {
label,
children
} = props;
return (
<Box>
<FormLabel
sx={{
marginLeft: "0.71em",
marginTop: "-0.71em",
paddingLeft: "0.44em",
paddingRight: '0.44em',
zIndex: 2,
backgroundColor: (theme) => theme.palette.background.default,
position: "absolute",
fontSize: "0.75em",
width: 'auto',
}}>{label}</FormLabel>
<Box
sx={{
position: 'relative',
borderRadius: theme => theme.shape.borderRadius + 'px',
fontSize: '0.875rem',
}}
>
<Box
sx={{
padding: (theme) => theme.spacing(1),
display: 'flex',
gap: (theme) => theme.spacing(1),
flexWrap: 'wrap',
overflow: 'auto'
}}
>
{children}
</Box>
<fieldset aria-hidden={"true"} style={{
textAlign: 'left',
position: 'absolute',
bottom: 0,
right: 0,
top: '-5px',
left: 0,
margin: 0,
padding: '0 8px',
pointerEvents: 'none',
borderRadius: 'inherit',
borderStyle: 'solid',
borderWidth: '1px',
overflow: 'hidden',
minWidth: '0%',
borderColor: 'rgba(255, 255, 255, 0.23)',
}}
>
<legend style={{
float: 'unset',
overflow: 'hidden',
display: 'block',
width: 'auto',
padding: 0,
height: '11px',
fontSize: '0.75em',
visibility: 'hidden',
maxWidth: '100%',
'-webkit-transition': 'max-width 100ms cubic-bezier(0.0, 0, 0.2, 1) 50ms',
transition: 'max-width 100ms cubic-bezier(0.0, 0, 0.2, 1) 50ms',
whiteSpace: 'nowrap',
}}><span>{label}</span></legend>
</fieldset>
</Box>
</Box>
);
}
export { OutlinedBox };
// Example usage: <OutlinedBox label="Test">Some content here</OutlinedBox>
I figured I'd post it here in case anyone needs the same thing and comes across this question. All the styling stuff was copied from the styles MUI was using. There may be a better way to read some of this off of the theme, so if anyone decides to use this you may want to tweak it some.

My custom makeStyles for MaterialUI Button component is getting overriden by ..css-zln006-MuiButtonBase-root-MuiButton-root

My custom makeStyles for MaterialUI Button component is getting overridden by .css-zln006-MuiButtonBase-root-MuiButton-root.
I have a Material UI Button component:
import { Button } from "#mui/material";
import useStyles from "./HeaderStyles.js";
const Header = () => {
const classes = useStyles();
return (
<React.Fragment>
<AppBar position="fixed">
<Toolbar disableGutters>
<Button
className={classes.button}
variant="contained"
color="secondary"
>
Click me
</Button>
</Toolbar>
</AppBar>
</React.Fragment>
);
};
export default Header;
My HeaderStyles.js file:
import { makeStyles } from "#mui/styles";
const useStyles = makeStyles((theme) => ({
button: {
fontFamily: "Pacifico",
textTransform: "none",
fontSize: "1rem",
borderRadius: "50px",
marginLeft: "50px",
marginRight: "25px",
height: "45px",
},
}));
export default useStyles;
My styles are getting overridden by the .css-zln006-MuiButtonBase-root-MuiButton-root class.
This class is replacing my button style.
.css-zln006-MuiButtonBase-root-MuiButton-root {
display: '-webkit-inline-box',
display: '-webkit-inline-flex',
display: '-ms-inline-flexbox',
display: 'inline-flex',
WebkitAlignItems: 'center',
WebkitBoxAlign: 'center',
MsFlexAlign: 'center',
alignItems: 'center',
WebkitBoxPack: 'center',
MsFlexPack: 'center',
WebkitJustifyContent: 'center',
justifyContent: 'center',
position: 'relative',
boxSizing: 'border-box',
WebkitTapHighlightColor: 'transparent',
backgroundColor: 'transparent',
outline: '0',
border: '0',
margin: '0',
borderRadius: '0',
padding: '0',
cursor: 'pointer',
WebkitUserSelect: 'none',
MozUserSelect: 'none',
MsUserSelect: 'none',
userSelect: 'none',
verticalAlign: 'middle',
MozAppearance: 'none',
WebkitAppearance: 'none',
WebkitTextDecoration: 'none',
textDecoration: 'none',
color: 'inherit',
fontFamily: '"Roboto","Helvetica","Arial",sans-serif',
fontWeight: '500',
fontSize: '0.875rem',
lineHeight: '1.75',
letterSpacing: '0.02857em',
textTransform: 'uppercase',
minWidth: '64px',
padding: '6px 16px',
borderRadius: '4px',
WebkitTransition: 'background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,border-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',
transition: 'background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,border-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms',
color: 'rgba(0, 0, 0, 0.87)',
backgroundColor: '#FFBA60',
boxShadow: '0px 3px 1px -2px rgba(0,0,0,0.2),0px 2px 2px 0px rgba(0,0,0,0.14),0px 1px 5px 0px rgba(0,0,0,0.12)'
}
My button style
.makeStyles-button-59 {{
height: '45px',
fontSize: '1rem',
fontFamily: 'Pacifico',
marginLeft: '50px',
marginRight: '25px',
borderRadius: '50px',
textTransform: 'none'
}
How to solve this?
#mui/styles is the legacy styling solution for MUI. It is deprecated
in v5. It depends on JSS as a styling solution, which is not used in
the #mui/material anymore. If you don't want to have both emotion &
JSS in your bundle, please refer to the #mui/system documentation
which is the recommended alternative.
Use sx prop instead
const buttonStyles = {
borderRadius: 50,
fontFamily: "Pacifico",
fontSize: "1rem",
textTransform: "none",
};
<Button sx={buttonStyles} variant="contained" color="secondary">
Click me
</Button>

Smooth transition with React Modal

I am trying to make React modal have a smooth transition when it appears on the screen but can't seem to get the transition property to do anything. Right now, the modal pops onto the screen in a jarring manner but I'd like to get it to slowly fade in. Here is my modal with the styles:
const customStyles = {
content: {
top: "50%",
left: "50%",
right: "auto",
bottom: "auto",
marginRight: "-50%",
transform: "translate(-50%, -50%)",
transition: "opacity .5s",
width: "90%",
maxHeight: "600px",
overflow: "auto",
padding: "40px",
maxWidth: "500px",
borderRadius: "10px",
boxShadow: "0px 0px 15px 1px gray",
},
};
<Modal
ariaHideApp={false}
isOpen={modalIsOpen}
onRequestClose={() => setIsOpen(false)}
style={customStyles}
contentLabel="Example Modal"
>
Anyone have any suggestions?
I think you need to put opacity as a property itself.
const customStyles = {
content: {
top: "50%",
left: "50%",
right: "auto",
bottom: "auto",
marginRight: "-50%",
transform: "translate(-50%, -50%)",
opacity: "20%",
transition: ".5s",
width: "90%",
maxHeight: "600px",
overflow: "auto",
padding: "40px",
maxWidth: "500px",
borderRadius: "10px",
boxShadow: "0px 0px 15px 1px gray",
},
};

Tailwind CSS :before pseudo class

I've now been working in circles trying to understand what is happening. I'm making a design library using storybook with Tailwind. I can't seem to get the :before pseudo class to work. No matter where I place it in the styling, then it's never rendered.
An example is that I am trying to make a component which uses react-slick, and want to style the navigation:
'& .slick-dots': {
bottom: -30,
display: 'block',
left: 4,
listStyle: 'none',
margin: 0,
padding: 0,
position: 'absolute',
textAlign: 'center',
width: '100%',
'& li': {
cursor: 'pointer',
display: 'inline-block',
height: 20,
margin: '0 5px',
padding: 0,
position: 'relative',
width: 20,
'& button': {
border: 0,
background: 'transparent',
display: 'block',
height: 20,
width: 20,
outline: 'none',
lineHeight: 0,
fontSize: 0,
color: 'transparent',
padding: 5,
cursor: 'pointer',
'&:before': {
position: 'absolute',
top: 0,
left: 0,
content: '',
width: 20,
height: 20,
fontFamily: 'sans-serif',
fontSize: 20,
lineHeight: 20,
textAlign: 'center',
color: '#000000',
opacity: 0.75,
display: 'inline-block',
},
},
},
},
Found the problem. The :before pseudo class won't render unless there is content, but in the case of css in js, then content needs to look like this content: '"text"', and not content: 'text',
Another way is to define your content in the tailwind.config.js
theme: {
extend: {
content: {
'arrowNeonGreen': 'url("../src/images/icons/arrow-neon-green.svg")',
},
fontSize: {
...
You can render it using the following className. Make sure to include an inline-block and width.
<Link className="after:content-arrowNeonGreen after:inline-block after:w-8">Learn More</Link>
You can also apply a hover state like this hover:after:content-arrowNeonGreen
<Link className="hover:after:content-arrowNeonGreen after:content-arrowBlack after:inline-block after:w-8">Learn More</Link>
to get the :before class to work, you have to use tailwindcss-pseudo-elements package to customize your pseudo elements. check the docs below
https://www.npmjs.com/package/tailwindcss-pseudo-elements

ReactJS + MaterialUI: SelectField height change

I'm using React material-ui SelectField on my page. I'm not able to adjust the height of the select field. Here is my code snippet:
<SelectField
underlineStyle={{
display: 'none'
}}
style={{
width: '49%',
padding: '0 0 5em 5em',
border: '1px solid #ccc',
borderRadius: '5px',
backgroundColor: '#fff',
margin: '16px 0px 0px 28px',
}}
floatingLabelText="Select Stack*"
value={this.state.stack}
onChange={this.handleStackChange.bind(this)}
>
{this.state.dropDownStack}
</SelectField>
My UI is looking as below
I need to reduce the height of dropdown box, how can I do it?
You have to set it using following:
<SelectField
className="custom-selectfield"
underlineStyle={{
visibility: 'hidden',
}}
floatingLabelStyle={{
top: '14px',
}}
style={{
border: '1px solid #ccc',
height: '45px',
}}
floatingLabelText="Select Stack*"
value={this.state.stack}
onChange={this.handleStackChange.bind(this)}>
{this.state.dropDownStack}
</SelectField>
There is some internal CSS applied in material UI so in order to overwrite it added a custom class to SelectPicker component named custom-selectfield
Add following lines in your CSS file
.custom-selectfield > div:nth-child(2) {
margin-top: -6px !important;
}

Resources