How to Imitate the Look of the Outline and Label from Material-Ui's Outlined Textfield

How can I imitate the look of the outline and label from Material-UI's outlined textfield?

UPDATE

For many scenarios, my later answer (which avoids using TextField and therefore has no side-effects on FormControl context) may be more appropriate: How can I set an static outlined div similar to Material-UI's outlined textfield?


There is a great deal of flexibility in what you can do with TextField. TextField supports plugging in different types of inputs (e.g. Select, input, custom pickers) via the inputComponent property. You could leverage this to put anything inside its labelled outline by creating a custom component like this OutlinedDiv:

import React from "react";

import TextField from "@material-ui/core/TextField";

const InputComponent = ({ inputRef, ...other }) => <div {...other} />;
const OutlinedDiv = ({ children, label }) => {
return (
<TextField
variant="outlined"
label={label}
multiline
InputLabelProps={{ shrink: true }}
InputProps={{
inputComponent: InputComponent
}}
inputProps={{ children: children }}
/>
);
};
export default OutlinedDiv;

The className passed to the inputComponent takes care of the CSS that makes this all work. You can then use this like in the following:

import React from "react";
import ReactDOM from "react-dom";

import OutlinedDiv from "./OutlinedDiv";
import Avatar from "@material-ui/core/Avatar";
import deepOrange from "@material-ui/core/colors/deepOrange";
import deepPurple from "@material-ui/core/colors/deepPurple";
import red from "@material-ui/core/colors/red";
import green from "@material-ui/core/colors/green";
import blue from "@material-ui/core/colors/blue";
import Grid from "@material-ui/core/Grid";

function App() {
return (
<div className="App">
<OutlinedDiv label="Color Picker">
<Grid container justify="center" alignItems="center">
<Avatar style={{ backgroundColor: deepOrange[500] }} />
<Avatar style={{ backgroundColor: deepPurple[500] }} />
<Avatar style={{ backgroundColor: red[500] }} />
<Avatar style={{ backgroundColor: green[500] }} />
<Avatar style={{ backgroundColor: blue[500] }} />
</Grid>
</OutlinedDiv>
<br />
<br />
<OutlinedDiv label="Custom Outlined Thing">
You can put whatever you want in here.
</OutlinedDiv>
</div>
);
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Edit Custom Outlined Component

How can I set an static outlined div similar to Material-UI's outlined textfield?

Below is an approach that does not leverage TextField or FormControl and thus can be safely used to wrap other inputs. This copies some styles from OutlinedInput and the InputLabel styles applied when within a FormControl.

import React from "react";
import ReactDOM from "react-dom";
import InputLabel from "@material-ui/core/InputLabel";
import NotchedOutline from "@material-ui/core/OutlinedInput/NotchedOutline";
import { withStyles } from "@material-ui/core/styles";
import clsx from "clsx";

const styles = {
root: {
position: "relative",
marginTop: "8px"
},
contentWrapper: {
position: "relative"
},
content: {
padding: "18.5px 14px"
},
inputLabel: {
position: "absolute",
left: 0,
top: 0,
// slight alteration to spec spacing to match visual spec result
transform: "translate(0, 24px) scale(1)"
},
notchedOutline: {}
};

const LabelledOutline = ({ classes, id, label, children, className }) => {
const [labelWidth, setLabelWidth] = React.useState(0);
const labelRef = React.useRef(null);
React.useEffect(() => {
const labelNode = ReactDOM.findDOMNode(labelRef.current);
setLabelWidth(labelNode != null ? labelNode.offsetWidth : 0);
}, [label]);

return (
<div className={clsx(className, classes.root)}>
<InputLabel
ref={labelRef}
htmlFor={id}
variant="outlined"
className={classes.inputLabel}
shrink
>
{label}
</InputLabel>
<div className={classes.contentWrapper}>
<div id={id} className={classes.content}>
{children}
<NotchedOutline
className={classes.notchedOutline}
notched
labelWidth={labelWidth}
/>
</div>
</div>
</div>
);
};
export default withStyles(styles)(LabelledOutline);

And below is an example using it both without customization and once with customized colors for the label, outline, and content that changes on hover.

import React from "react";
import ReactDOM from "react-dom";
import { withStyles } from "@material-ui/core/styles";

import LabelledOutline from "./LabelledOutline";

const CustomColorLabelledOutline = withStyles({
root: {
"& $notchedOutline": {
borderColor: "purple"
},
"&:hover $notchedOutline": {
borderColor: "orange"
},
"& $inputLabel": {
color: "green"
},
"&:hover $inputLabel": {
color: "blue"
},
"& $content": {
color: "black"
},
"&:hover $content": {
color: "purple"
}
},
notchedOutline: {},
inputLabel: {},
content: {}
})(LabelledOutline);

function App() {
return (
<div>
<LabelledOutline id="myID" label="My Label">
My Content
</LabelledOutline>
<CustomColorLabelledOutline label="My Label">
My Content with custom label and outline color
</CustomColorLabelledOutline>
</div>
);
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Edit LabelledOutline

Remove Material-Ui TextField border

If you would like a TextField without the outline border, the best thing to do would be to use the Standard variant of the TextField Component.

By default the Standard variant will have an underline beneath the text, but this can be removed by adding InputProps prop and passing in disableUnderline: true:

  <TextField
InputProps={{disableUnderline: true}}
variant="standard"
label=""
multiline
rows={55}
placeholder="# Hello World"
style={{ width: '90%' }}
/>

The result will look exactly the same as if you had an outlined TextField without the outline.

Note that it's not recommended you do this, though, for usability reasons; it'll make the text field less distinguishable and less of a clear touch target for users on mobile. Make sure you have some other kind of indication that it's a text field.
https://medium.com/google-design/the-evolution-of-material-designs-text-fields-603688b3fe03

How to customize the border color, width, and height of Material-UI Text Field with styled-components

IIUC styled-components is not a requirement for you. MUI has several built-in ways to override styles, you can learn more about it here. Alternatively you can look at the many code examples for each component, which almost always include style overrides (click on the Show full source icon). In this case, Text Fields.

To make it a bit more obvious in my example below, I changed the style values, you just need to put in your own.

const { TextField, makeStyles } = MaterialUI

const useStyles = makeStyles({
input: {
width: 400,
height: 150,
'& input + fieldset': {
borderColor: 'hotpink',
},
},
});

function InputBox() {
const classes = useStyles();

return (
<TextField
InputProps={{
className: classes.input,
}}
id="outlined-basic"
variant="outlined"
label="Default"
defaultValue="Input Text"
/>
);
}

ReactDOM.render(<InputBox />, document.getElementById('root'))
<script src="https://unpkg.com/react@latest/umd/react.development.js" crossorigin="anonymous"></script>
<script src="https://unpkg.com/react-dom@latest/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@material-ui/core@latest/umd/material-ui.development.js" crossorigin="anonymous"></script>
<script src="https://unpkg.com/babel-standalone@latest/babel.min.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
<div id="root"></div>

FormControl Label is crossed by Outline border in Material UI - ReactJs

You need to add labelId and label to your Select component.

<InputLabel required={true} id="label-for-appliances" >Appliances</InputLabel>

<Select labelId="label-for-appliances" label="Appliances" />

Change border color of MUI disabled outline input

I have done this by using the theme palatte. I am using mui 5.5.0

import {createTheme} from "@mui/material"; 
const theme = createTheme({
palette: {
action: {
disabled: 'your color here e.g #000000',
}
},
});

By doing this, every disabled field through out the app will have the color defined in the palatte.
And if you want to do this for a single/specific input field or you want to override this palatte disabled defined color. you can do it by following:

<TextField
value={value}
variant="outlined"
label="label"
disabled
sx={{
"& .MuiInputBase-root.Mui-disabled": {
"& > fieldset": {
borderColor: "your color here e.g #8cffcb"
}
}
}}
/>

How to change TextField input's focus border using Material-UI theme

Since I wasn't able to tell exactly what your desired effect was on focus vs not focused, I decided to just create a generic example, with overly dramatic styling, that may be useful to modify for your needs:

Essentially, I'm just overriding .MuiOutlinedInput-notchedOutline for both the focused an unfocused states:

const theme = createTheme({
components: {
// Inputs
MuiOutlinedInput: {
styleOverrides: {
root: {
...
"& .MuiOutlinedInput-notchedOutline": {
border: `5px solid green`,
},
"&.Mui-focused": {
"& .MuiOutlinedInput-notchedOutline": {
border: `5px dotted red`,
},
}
},
}
}
}
});

Working example CodeSandbox: https://codesandbox.io/s/customstyles-material-demo-forked-uri26?file=/theme.js:84-531



Related Topics



Leave a reply



Submit