The TextField API doesn't mention anything about how one could style the pseudo placeholder element of the input element.
Basically, I would like to change the default styling of the placeholder text, and the normal bag of tricks doesn't work, as I cannot access the element.
Is there a way I can get to it? And if so, what is the JSS/React/DOM equivalent way of writing ::-webkit-input-placeholder?
Case 1
Put the desired placeholder text in the label property of the TextField component, and use the labelClassName property of the TextField to customize it. You could also pass InputLabelProps with a className, classes or style attribute.
Case 2
Refrain from using the label property of TextField and put the placeholder text on its placeholder property instead. Leverage InputProps to override the generated HTML input element's class.
Code
The code below covers both aforementioned cases. CodeSandbox snippet.
import React from 'react';
import TextField from 'material-ui/TextField';
import { withStyles } from 'material-ui/styles';
import withRoot from '../components/withRoot';
const styles = {
'input-label': {
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
overflow: 'hidden',
width: '100%',
color: 'red'
},
'input': {
'&::placeholder': {
textOverflow: 'ellipsis !important',
color: 'blue'
}
}
};
class Index extends React.Component {
render() {
return <div style={ {width: 150, margin: '0 auto'} }>
{/* Uses "label" and "labelClassName". */}
<TextField
fullWidth
label='I am a really really long red TextField label'
labelClassName={ this.props.classes['input-label'] } />
{/* Uses "label" and "InputLabelProps" with inline styles. */}
<TextField
fullWidth
label='I am a really really long green TextField label'
InputLabelProps={{
style: {
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
overflow: 'hidden',
width: '100%',
color: 'green'
} }} />
{/* Uses "placeholder" and "InputProps" with "classes". */}
<TextField
fullWidth
margin='normal'
placeholder='I am a really really long glue TextField label'
InputProps={{ classes: {input: this.props.classes['input']} }} />
</div>;
}
}
export default withStyles(styles)(Index);
EDIT
The previous solutions are good if you'd like to personalize a specific component instance. To change the placeholder globally, see ninjaPixel's answer.
You can style the input at the top-level of your app, which will save you from having to create a custom input component with your styles applied to it (as suggested in other answers).
import { ThemeProvider } from "#material-ui/styles";
import { createMuiTheme } from "#material-ui/core/styles";
const customTheme = createMuiTheme({
overrides: {
MuiInput: {
input: {
"&::placeholder": {
color: "gray"
},
color: "white", // if you also want to change the color of the input, this is the prop you'd use
}
}
});
// Render it like this
<ThemeProvider theme={customTheme}>
<App />
</ThemeProvider>
You can use the following code to apply the placeholder style.
const styles = (theme: any) => createStyles({
input: {
'&::placeholder': {
fontStyle: 'italic',
},
},
});
<TextField
margin="normal"
variant="outlined"
placeholder="Filter..."
InputProps={{
classes: { input: classes.input}
}}
/>
Use InputLabelProps on TextField
<TextField
InputLabelProps={{
style: { color: '#fff', some other Styles },
}}
/>
I haven't found a proper answer to how I can access the inner input element, but as to how one could target the placeholder element using JSS, I found the answer in the source of the Input element, of which TextField is composed.
Basically, it's using the straight css names, just enclosed in quotes:
'&::-webkit-input-placeholder': { color: 'blue' }
you can add styling to your input using ::placeholder selector in css it'll work
::-webkit-input-placeholder { /* Chrome/Opera/Safari */
color: pink;
}
::-moz-placeholder { /* Firefox 19+ */
color: pink;
}
:-ms-input-placeholder { /* IE 10+ */
color: pink;
}
:-moz-placeholder { /* Firefox 18- */
color: pink;
}
To style only the placeholder without the label on top when focused - do the following:
const useStyles = makeStyles(theme => ({
label: {
color: 'rgba(0, 0, 0, 0.26)'
}
}));
const LoginForm = () => {
const classes = useStyles();
return (
<TextField
...
InputLabelProps={{
classes: {
root: classes.label,
}
}}
/>
)
}
Whether you are using the outlined, filled, or standard variants, the placeholder you might be referring to is actually the label and not the ::placeholder.
You can use sx in newest MUI versions.
<TextField
label="Username"
variant="standard"
sx={{ input: { color: "yellow" }, "label": {color: "blue"} }}
/>
With styled components I just use:
const StyledTextField = styled(TextField)`
label {
font-style: italic;
}
`;
Related
I'm trying to make different icons in the footer, with different brands. I want them to change color when I'm hovering over them. I've created a CSS class with the hover pseudo-class, but I want to make a sort of parameter in my JSX file which tells the class that a certain color should be applied to a certain icon
This Is my CSS class:
.icon-background {
color: rgb(49, 45, 44, 0.8);
}
.icon-background:focus,
.icon-background:hover {
background-color: var(--color);
transition-duration: 0.2s;
padding: 2.5px;
}
An easy way to accomplish this would be through utility css classes. For instance, you could insert an icon in the jsx file like this:
<div className="blue default_icon">ICON</div>
With corresponding css:
.blue:hover,
.blue:focus {
background-color: #0000ff;
}
.default_icon {
color: rgb(49, 45, 44, 0.8);
}
.default_icon:hover {
transition-duration: 0.2s;
padding: 2.5px;
}
A better way you could do this is with React state. Basically, create an icon component and pass a color as a prop. This will be much less css and will be more scalable:
import { useState } from 'react';
const Icon = (props) => {
const hoverColor = props.hoverColor;
const [isHover, setIsHover] = useState(false);
const handleMouseEnter = () => {
setIsHover(true);
};
const handleMouseLeave = () => {
setIsHover(false);
};
const hoverStyle = {
backgroundColor: isHover ? hoverColor : "defaultColor",
};
return (
<div
style={hoverStyle}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
ICON
</div>
);
};
export default Icon;
You can then use the icon anywhere in your project like so:
<Icon hoverColor={"#0000ff"} /> // This would turn blue on hover
I have a button web component built that I am trying to style using CSS parts. In my web component below you can see that the button is colored tomato because I have used exportparts and then in my consumer CSS I have styled it using btn-comp::part(btn) { ... }.
However, I would prefer to not have to style it using btn-comp, instead I would like to just use :root to style it like this author does.
For example I should be able to do this:
:root::part(btn) { /* my styles here */ }
But that does not work, it only works when I use the component name. How can I style my CSS parts using :root?
const template = document.createElement('template');
template.innerHTML = `<button part="btn">I should be a green button</button>`;
class BtnComp extends HTMLElement {
connectedCallback() {
this.attachShadow({mode: 'open'});
this.shadowRoot.appendChild(template.content.cloneNode(true));
const button = this.shadowRoot.querySelector("button");
button.addEventListener("click", () => alert('Clicked'));
}
}
window.customElements.define('btn-comp', BtnComp);
:root::part(btn) {
background-color: green !important; /* I want this color to be applied! */
}
btn-comp::part(btn) {
background-color: tomato;
color: white;
padding: 1rem 2rem;
border: 0;
cursor: pointer;
}
<btn-comp exportparts="btn" />
In "DataGrid" material UI I am trying to modify the css properties like font weight, overflow of header.
Here is my jsx code
import React, {useState, useEffect} from 'react';
import {DataGrid, GridToolbarContainer, GridToolbarExport} from '#material- ui/data-grid';
import {makeStyles} from '#material-ui/styles';
const useStyles = makeStyles({
root: {
'& .super-app-theme--header': {
backgroundColor: 'white'
}
},
'.MuiDataGrid-root .MuiDataGrid-columnHeaderTitle': {
fontWeight: 'bold',
overFlow: 'visible'
}
});
function CustomToolbar() {
return (
<GridToolbarContainer>
<GridToolbarExport />
</GridToolbarContainer>
);
}
export default function DataTable(props) {
const classes = useStyles();
return (
<div style={{height: '700px', width: '100%'}} className={classes.root}>
<DataGrid
rows={props.records}
columns={props.headers}
pageSize={12}
components={{
Toolbar: CustomToolbar
}}
/>
</div>
);
}
I also tried to add properties like font weight and overflow in super-app-theme--header but it didn't work. Some properties like background colour are working but the properties which are already there in MuiDataGrid-columnHeaderTitle are not getting overridden.
I created a css file and in that overridden the properties with same class name and imported that css file
Here is the css code
.MuiDataGrid-columnHeaderTitle { font-weight: bold !important; overflow: visible !important; }
Using MUI V5+ and building on Pravin's answer you can define the header style this way:
<Datagrid
sx={{
'.MuiDataGrid-columnHeaderTitle': {
fontWeight: 'bold !important',
overflow: 'visible !important'
}
}}
/>
I am passing various amounts of data in react markdown sich as tables, lists and h tags. I wanted to know how to style each element separately. I searched everywhere but there is no mention of how to style the elements other than just bold or emphasize, etc. I thought I could pass a class name in the ReactMarkdown component to style it but would that not just provide styling only for the component. How do I style the various elements within it?
const ReadMePreviewer = ({ readMeCode }) => {
return (
<ReactMarkdown
plugins={[[gfm, { singleTilde: false }]]}
className={style.reactMarkDown}
// className={style.reactMarkDownRemovingExtraGlobal}
renderers={renderers}
source={readMeCode}
/>
);
};
This is how I would make it work for me. I do it explicit with CSS and not, e.g., SCSS or CSS-in-JS so as not to bother you with extra libraries nor webpack/babel finetuning:
Create a separate markdown-styles.module.css CSS-module file with your styles, e.g.,
.reactMarkDown {
// some root styles here
}
.reactMarkDown ul {
margin-top: 1em;
margin-bottom: 1em;
list-style: disc outside none;
}
.reactMarkDown ul li {
margin-left: 2em;
display: list-item;
text-align: -webkit-match-parent;
}
// your other styles but all under .reactMarkDown blocks
Then you can import it in your component and use as you did:
import style from './markdown-styles.module.css';
...
const ReadMePreviewer = ({ readMeCode }) => {
return (
<ReactMarkdown
plugins={[[gfm, { singleTilde: false }]]}
className={style.reactMarkDown}
renderers={renderers}
children={readMeCode}
/>
);
};
This seem to work to wrap into new line
App.css
.markdown code {
display: block;
white-space: pre-wrap;
}
Component:
<ReactMarkdown className="markdown">{page.Content}</ReactMarkdown>
How could I change the mat-radio-button to check-mark and cross-mark looks like following?
Thank you!
My code is here:
<mat-radio-group class="radio" (change)="onChange($event)"
name="exemplars">
<mat-radio-button class="radio-custom" [value]="true" [checked]="function()"> Accept </mat-radio-button>
<mat-radio-button class="radio-custom" [value]="false" [checked]="function()"> Reject</mat-radio-button>
</mat-radio-group>
icons I want to use :
Don't think this is the most elegant solution but it does the job.
In my case I'm using Angular 10 (2+) with all the ::ng-deep stuff so align the code for your needs.
I'm using an icomoon font with the icons my company is using so take this into consideration when applying this solution.
In my app.component. styling file:
::ng-deep {
.mat-radio-button {
.mat-radio-container {
.mat-radio-outer-circle:before {
font-family: "icomoon" !important; // here comes the icomoon font reference that defines the actual icon to be shown
content: "\e901"; // the code of the icon from my iconfont => change this one to the X icon of yours
position: absolute; // this and next 3 lines are for centering the icon in the circle of the radio button
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.mat-radio-inner-circle {
/* feel free to design the actual inner radiobutton circle as you wish*/
}
}
.mat-radio-button .mat-radio-checked {
.mat-radio-container {
.mat-radio-outer-circle:before {
content: "\e900"; // the code of the icon from my iconfont => change this one to V icon of yours
}
}
}
}
}
Feel free to enhance the code with all other stuff: sizes, borders, coloring, etc.
Create a new directive that binds to mat-radio-button or any other selector you need, e.g. mat-radio-button.radio-custom
Inject ElementRef into the directive's constructor
Use the instance of ElementRef to find .mat-radio-inner-circle
Set the innerHTML of the found html element to the svg of your desired icon.
Example:
#Directive({
selector: 'mat-radio-button',
})
export class CustomRadioButton implements OnInit {
constructor(private elementRef: ElementRef) {}
ngOnInit() {
this.appendIcon();
}
appendIcon() {
const innerCircle = this.elementRef.nativeElement.querySelector('.mat-radio-inner-circle');
innerCircle.innerHTML = YOUR_SVG_CODE;
}
}