I'm using Material-UI. As it supports CSS styling with JSS, I'm struggling to access rule names in a different component. As you see the below codes, MyComponent uses AppBar component and I need to access rule names in AppBar component. However, for some reason I can't access the rule names in it.
MyComponent.js
<div id="navigation-pills">
<div className={classes.root}>
<AppBar position="static" color="default">
<Tabs
...
>
...
</Tabs>
</AppBar>
</div>
</div>
styles.js
const styles = theme => ({
...
root: {
flexGrow: 1,
width: "100%",
backgroundColor: theme.palette.background.paper,
"& $flexContainer": {
display: "none"
}
},
...
});
JSS API says that I can access child rule names with $, but it doesn't work for some reason.
L
Like you see the below image, I would like to access flexContainer rule name on line 7.
It can only reference a rule from the same style sheet (styles object). In your code I can't tell, because you replaced it with "...".
Related
My HTML:
<my-dropdown label="dropdown" size="m" filter="true">
<select slot="filter" part="myselect">
<option>One</option>
<option>Two</option>
<option>Three</option>
</select>
</my-dropdown>
Inside the my-dropdown components, I have a slot:
<slot name="filter" />
The css stylesheet is inside the component, and in it, I have defined:
my-dropdown::part(myselect) {
..
}
The styles do not apply to the component! Why? Am I not doing it correctly?
Simple answer: Because it's not meant to work on slotted elements.
The CSS parts ::part() pseudo-element selector is used to apply style to elements that are within shadow DOM which use the part attribute.
In your example, you have added the part attribute to the element <select slot="filter" part="myselect"> which is in light DOM not shadow DOM.
Note that slotted elements are not actually moved to the shadow DOM; their position in the DOM is not affected by the slotting mechanism so they exist in regular light DOM like any other element. They are just rendered inside the shadow DOM structure of the parent web component, with both the component's shadow DOM style for that slot (::slotted()) and any regular DOM styling e.g. global stylesheet applied.
In order for the my-dropdown::part(myselect) selector to work, the element that has the part="myselect" attribute would have to be inside the shadow of the my-dropdown component - for example:
#Component({
tag: 'my-dropdown',
styleUrl: 'my-dropdown.scss',
shadow: true,
})
export class MyDropdown {
render() {
return (
<Host>
<div part="myselect">
<slot name="filter" />
</div>
</Host>
);
}
}
there is that annoying black outline that appears in my material Ui autocomplete component on hover and I cannot even find in the css to remove it. I feel like I've tried everything. Does somebody have an idea about it? It just doesn't match the style of my project and the whole page looks bad because of it.
You can override the input component using "renderInput". This will allow you to provide a custom input component that does not have the hover effect.
Docs: https://mui.com/material-ui/react-autocomplete/#custom-input
<Autocomplete
sx={{
display: 'inline-block',
'& input': {
width: 200,
bgcolor: 'background.paper',
color: (theme) =>
theme.palette.getContrastText(theme.palette.background.paper),
},
}}
id="custom-input-demo"
options={options}
renderInput={(params) => (
<div ref={params.InputProps.ref}>
<input type="text" {...params.inputProps} />
</div>
)}
/>
I struggled a lot to remove the hover effect too. In my case could chaneg it using the .MuiInput-underline:hover:not(.Mui-disabled):before selector. I think in your case you could do something like
.MuiInput-underline:hover:not(.Mui-disabled):before {
border-bottom: 0 !important;
}
or something among those lines. Hope that helps.
<Button variant="contained" color="success">save</Button>
<Button variant="contained" color="error">delete</Button>
Both buttons show the default color.
Most components behave the same way: success, info... none of them work as I expect them to.
I know this is not a bug, according to the API documentation, MaterialUI's components simply don’t recognize other palette's colors at all, but this bugs me.
Why components only recognize primary and secondary colors?
How should I use the colors of my theme.palette so that they are applied to my components?
Is changing the theme my only option to achieve the effect I am looking for?
According to the Button API documentation, the accepted values for the color prop are 'default', 'inherit', 'primary' and 'secondary' only. Therefore, Material UI will not recognize color='success' nor color='error' and show the corresponding colors.
I assume you are trying to use the success and error colors from the default theme. In the default theme object, the colors for success and error can be found in theme.palette.success and theme.palette.error respectively.
Therefore, we can access the default theme colors using the following way:
const useStyles = makeStyles((theme) => ({
success: {
backgroundColor: theme.palette.success.main
},
error: {
backgroundColor: theme.palette.error.main
}
}));
export default function ContainedButtons() {
const classes = useStyles();
return (
<div>
<Button variant="contained" classes={{ root: classes.success }}>
Save
</Button>
<Button variant="contained" classes={{ root: classes.error }}>
Delete
</Button>
</div>
);
}
I am trying to implement an angular material select component in the AG-GRID as per the example described here
However when I click on the cell that should make the select appear, it does not appear and in the console the following error appears:
core.js:4002 ERROR TypeError: Cannot read property 'element' of undefined
at mat-select.component.ts:37
This corresponds to the following method in the MatSelectComponent:
// dont use afterGuiAttached for post gui events - hook into ngAfterViewInit instead for this
ngAfterViewInit() {
window.setTimeout(() => {
this.group.element.nativeElement.focus();
});
this.selectFavouriteVegetableBasedOnSelectedIndex();
}
This component has been copied exactly from the example given, except that I put the template and styles in their own HTML/SCSS files respectively.
#Component({
selector: 'radio-cell',
template: './mat-select.component.html'
styles: ['./mat-slect.component.scss']
})
However, when I include the HTML template within the component like in the example it works!
#Component({
selector: 'radio-cell',
template: `
<mat-card>
<div class="container" #group tabindex="0" (keydown)="onKeyDown($event)">
<mat-form-field>
<mat-select panelClass="ag-custom-component-popup" [(ngModel)]="favouriteVegetable">
<mat-option *ngFor="let vegetable of vegetables" [value]="vegetable">
{{ vegetable }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</mat-card>
`,
styles: ['./mat-slect.component.scss']
})
Is there any explaination of this behaviour or way around putting all this HTML into the component?
EDIT 1:
The component includes the 'group' template reference variable in the component like below, so should it not be available to the ngAfterViewInit() method?
#ViewChild("group", { read: ViewContainerRef, static: true })
public group;
Your error Cannot read property 'element' of undefined comes from the fact that this.group is undefined because angular tries to query it in the template but doesn't find it <div class="container"#grouptabindex="0" (keydown)="onKeyDown($event)">
I'm using a very simple sample of the material ui Snackbar component, that renders the following HTML
<div class="MuiSnackbar-root-352 MuiSnackbar-anchorOriginBottomLeft-358">
<p class="MuiTypography-root-199 MuiTypography-body2-207 MuiPaper-root-121 MuiPaper-elevation6-129 MuiSnackbarContent-root-373" role="alertdialog" aria-describedby="message-id" direction="up" style="transform: translate(0px, 0px); transition: transform 225ms cubic-bezier(0, 0, 0.2, 1) 0ms;">
<div class="MuiSnackbarContent-message-374">
<span id="message-id">TunisiaNet created!</span>
</div>
</p>
</div>
for the following code
<Snackbar
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
open={this.state.entityGroupAdded}
autoHideDuration={4000}
onClose={this.handleClose}
ContentProps={{
'aria-describedby': 'message-id',
}}
message={<span id="message-id">{this.state.name} created!</span>}
/>
This naturally leads to an HTML specification incompatibility. The issue is that I don't know how to tell the Snackbar to create a div instead of a p element
I get the error:
0.chunk.js:101009 Warning: validateDOMNesting(...): <div> cannot appear as a descendant of <p>.
in div (created by SnackbarContent)
in p (created by Typography)
in Typography (created by WithStyles(Typography))
in WithStyles(Typography) (created by Paper)
in Paper (created by WithStyles(Paper))
in WithStyles(Paper) (created by SnackbarContent)
in SnackbarContent (created by WithStyles(SnackbarContent))
Might wanna check your Material UI version or any override settings you might have made which includes typography components. I just tested a snackbar with the exact same code and the p tag (which uses typography, this part is causing the error) does not exist as a p tag but a different classname
<div class="MuiSnackbar-root-185 MuiSnackbar-anchorOriginBottomLeft-191">
<div class="MuiTypography-root-313 MuiTypography-body1-322 MuiPaper-root-20 MuiPaper-elevation6-28 MuiSnackbarContent-root-310" role="alertdialog" aria-describedby="message-id" style="transform: translate(0px, 0px); transition: transform 225ms cubic-bezier(0, 0, 0.2, 1) 0ms;">
<div class="MuiSnackbarContent-message-311">
<span id="message-id">Note archived</span></div>
</div>
For other who is looking for an answer other than something wrong with the overrides, most likely if nothing wrong with your overrides, and even before you check for that. Look into your code if it contain a component that inherit the props of Typography component like DialogContentText and you also have another Typography component or a component that will transfer to <p> tag in HTML as a child of that component.
In the the error above message props will become
<p class="MuiTypography-root-199 MuiTypography-body2-207 MuiPaper-root-121 MuiPaper-elevation6-129 MuiSnackbarContent-root-373" role="alertdialog" aria-describedby="message-id" direction="up" style="transform: translate(0px, 0px); transition: transform 225ms cubic-bezier(0, 0, 0.2, 1) 0ms;">
<div class="MuiSnackbarContent-message-374">
<span id="message-id">TunisiaNet created!</span>
</div>
</p>
I think this is not showing anymore in the new versions of material. But if you want to fix something like that take a look;
This will give errors
const someFunction= (): JSX.Element => {
return (
<DialogTitle>
Some title
</DialogTitle>
<DialogContentText>
<Typography variant='h5'>
Sometext
<Typography />
</DialogContentText>
<TextField
autoComplete='off'
margin='dense'
variant="outlined"
id='name'
label='email'
type='email'
fullWidth
/>
);
};
this will fix it
const someFunction= (): JSX.Element => {
return (
<DialogTitle>
Some title
</DialogTitle>
<DialogContentText variant='h5'>
Sometext
</DialogContentText>
<TextField
autoComplete='off'
margin='dense'
variant="outlined"
id='name'
label='email'
type='email'
fullWidth
/>
);
};
In this case for example you can use the normal props of Typography with DialogContentText.
Also you can user component='div' as prop of Typography, it could fix it, I didn't test