I'm using react-data-table-component in my project to create a datatable.
However, the checkboxes are appearing too large.
After checking the docs, I found this page - Overidding Styling Using css-in-js with customStyles, and this example:
// Internally, customStyles will deep merges your customStyles with the default styling.
const customStyles = {
rows: {
style: {
minHeight: '72px', // override the row height
},
},
headCells: {
style: {
paddingLeft: '8px', // override the cell padding for head cells
paddingRight: '8px',
},
},
cells: {
style: {
paddingLeft: '8px', // override the cell padding for data cells
paddingRight: '8px',
},
},
};
There are no mentions on there about checkbox styling, so I attempt this:
const customStyles = {
checkbox: {
style: {
maxHeight: '18px',
maxWidth: '18px',
},
},
};
Unfortunately, the checkboxes remained large sized.
How do I solve this so it makes the checkboxes like the size shown in their example in the screenshots?
Screenshots.
Here is how I solved it:
Create a Checkbox component, like so:
const Checkbox = React.forwardRef(({ onClick, ...rest }, ref) =>
{
return(
<>
<div className="form-check pb-5" style={{ backgroundColor: '' }}>
<input
type="checkbox"
className="form-check-input"
style={{ height: '20px', width: '20px' }}
ref={ref}
onClick={ onClick }
{...rest}
/>
<label className="form-check-label" id="booty-check" />
</div>
</>
)
})
Add Checkbox component to DataTable, like so:
<DataTable
title="Products"
columns={columns}
data={ data }
subHeader
subHeaderComponent={subHeaderComponentMemo}
onRowClicked={ handleRowClicked }
selectableRows
selectableRowsComponent={Checkbox} // Pass the Checkbox component only
responsive
persistTableHead
/>
Related
Have looked at other examples and trying to do the same thing but not sure why my code is not working. I have code which loops through some keys and renders a div. I want to conditionally apply some styles based on whether the key is even or odd. Example:
<div className={parseInt(key) % 2 === 0 ? 'label1' : 'label2' }>
<span style={{ marginLeft: "10px" }}>{key}:00</span>
</div>
The styles are accessible in the same file and look something like:
# Material UI
const useStyles = makeStyles((theme) => ({
label1: {
width: "50px",
height: "16px",
top: "458px",
background: "yellow",
fontSize: "12px",
},
label2: {
width: "50px",
height: "16px",
top: "458px",
background: "red",
fontSize: "12px",
},
}));
What am I doing wrong? Currently no style is getting applied to the div
You need to use the classes from the material ui useStyles hook.
const classes = useStyles()
....
<div className={parseInt(key) % 2 === 0 ? classes.label1 : classes.label2 }>
<span style={{ marginLeft: "10px" }}>{key}:00</span>
</div>
Check the useStyles hook api: https://material-ui.com/styles/basics/
If you have a class component and you can use hooks then you can do it with the withStyles higher order component, like this example:
import { withStyles } from "#material-ui/core/styles"
const styles = theme => ({
label1: {
backgroundColor: "red",
},
label2: {
backgroundColor: "red",
},
})
class ClassComponent extends Component {
state = {
searchNodes: "",
}
render() {
const { classes } = this.props
return (
<div className={parseInt(key) % 2 === 0 ? classes.label1 : classes.label2}>
<span style={{ marginLeft: "10px" }}>{key}:00</span>
</div>
)
}
}
export default withStyles(styles, { withTheme: true })(ClassComponent)
const styles = makeStyles((theme) => ({
root: { margin: "0px 20px" },
textStyle: {
fontFamily: "Comfortaa",
},
container: {},
textField: {
fontFamily: "Comfortaa",
},
dropDownFormSize: {
width: "100%",
fontFamily: "Comfortaa",
},
optionDropdown: {
color: "black",
},
dropDownSelector: {
color: "black",
backgroundColor: "tomato",
},
nativeInput: {
opacity: "1",
},
}));
const MainTable: React.FC = () => {
const classes = styles();
<FormControl
classes={{
root: classes.dropDownFormSize,
}}
>
<Select
required
className={classes.dropDownSelector}
value={emotion[i]}
name="emotion"
onChange={handleChangeEmotion(i)}
classes={{
root: classes.optionDropdown,
select: classes.optionDropdown,
// using nativeInput here gives me error
nativeInput: classes.nativeInput,
}}
MenuProps={{
anchorOrigin: {
vertical: "bottom",
horizontal: "left",
},
getContentAnchorEl: null,
MenuListProps: {
className: classes.optionDropdown,
},
}}
placeholder="Select Something"
native={false}
>
<MenuItem
value=""
disabled
// className={
// classes.optionItems
// }
>
Select Emotion
</MenuItem>
{emotions.map((emotion, i) => {
return (
<MenuItem
key={i}
// className={
// classes.optionItems
// }
value={emotion}
>
{emotion}
</MenuItem>
);
})}
</Select>
</FormControl>;
};
I want to remove opacity from the .MuiSelect-nativeInput Class. When I try to override this class using the nativeInput rule, I get this error message :-
Object literal may only specify known properties, and 'nativeInput' does not exist in type 'Partial<ClassNameMap<SelectClassKey>>'. Eventhough, nativeInput rule is given in the documentation of Select API. I have tried to override it in the Theme file but again, I get the error that nativeInput does not exist. How can I remove the opacity from the MuiSelect-nativeInput class.
You can instead use a TextField rendered as a select input.
const useStyles = makeStyles({
root: {
"& .MuiSelect-nativeInput": {
opacity: 1,
},
},
});
<TextField
select
classes = {{ root: classes.root }}
/>
I'm using the Autocomplete of Material UI and I have a list with the attribute Color. I have to render option by option with the respective color in option background.
Here's a example:
import React from "react";
import TextField from "#material-ui/core/TextField";
import Autocomplete from "#material-ui/lab/Autocomplete";
export default function ComboBox() {
return (
<Autocomplete
id="combo-box-demo"
options={top100Films}
getOptionLabel={option => option.title}
style={{ width: 300 }}
renderInput={params => {
return (
<TextField
{...params}
label="Combo box"
variant="outlined"
fullWidth
/>
);
}}
/>
);
}
const top100Films = [
{ title: "The Shawshank Redemption", year: 1994, color: '#FF0000' },
{ title: "The Godfather", year: 1972, color: '#FF5555' },
{ title: "Avatar", year: 2010, color: '#FFFFFF' },
// Plus a bunch more
];
You can use renderOption to render the style conditionally for each option in the latest version of MUI.
<Autocomplete
renderOption={(props, option) => {
const { title, color } = option;
return (
<span {...props} style={{ backgroundColor: color }}>
{title}
</span>
);
}}
{...}
/>
Live Demo
You can change the CSS like this:
.MuiAutocomplete-inputRoot[class*="MuiOutlinedInput-root"] {
background: #ffff
}
This will to change the options color.
In the code, the sx prop I have included the css properties for the whole option menu, selected option and while hovered in the selected option for the Autocomplete component:
<Autocomplete
limitTags={1}
disablePortal
id="simple-search"
value={select.region}
onChange={handleChange("region")}
options={region}
sx={{
width: { sm: "100%", md: 340 },
"& + .MuiAutocomplete-popper .MuiAutocomplete-option": {
backgroundColor: "#363636",
},
"& + .MuiAutocomplete-popper .MuiAutocomplete-option[aria-selected='true']":
{
backgroundColor: "#4396e6",
},
"& + .MuiAutocomplete-popper .MuiAutocomplete-option[aria-selected ='true']
.Mui-focused":
{
backgroundColor: "#3878b4",
},
}}
disableCloseOnSelect
multiple
renderInput={(params) => (
<TextField {...params} label="Region" color="info" />
)}
/>
I'm using MaterialUI's tabs in my React project.
This is the JSX for the tabs:
<AppBar color="default" position="static">
<Tabs indicatorColor="primary" textColor="primary" value={tabIndex} onChange={this.handleChange}>
{instances.map(instance =>
<StyledTab
style={{ textTransform: 'initial' }}
onClick={() => { this.changeActiveInstance(instance.id) }}
label={this.getTabAddress(instance)}
icon={<ClearIcon ></ClearIcon>}
>
</StyledTab>
)}
</Tabs>
This is how i inject the css:
const StyledTab = withStyles({
root: {
textTransform: 'initial'
},
})(Tab);
The result is this:
I would like to position the "ClearIcon" elsewhere. I tried playing with the style injection a bit, with no success.
Can somebody point me to the right direction?
When trying to customize any Material-UI component, the starting point is the CSS portion of the API documentation. The most relevant classes that you may want to override in this case are wrapper, labelContainer, and label.
The best way to fully understand how these are used and how they are styled by default (and therefore what you may want to override) is to look at the source code.
Here are the most relevant portions of the styles from Tab.js:
/* Styles applied to the `icon` and `label`'s wrapper element. */
wrapper: {
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
width: '100%',
flexDirection: 'column',
},
/* Styles applied to the label container element if `label` is provided. */
labelContainer: {
width: '100%', // Fix an IE 11 issue
boxSizing: 'border-box',
padding: '6px 12px',
[theme.breakpoints.up('md')]: {
padding: '6px 24px',
},
},
And here is the relevant code for understanding how these are used:
if (labelProp !== undefined) {
label = (
<span className={classes.labelContainer}>
<span
className={classNames(classes.label, {
[classes.labelWrapped]: this.state.labelWrapped,
})}
ref={ref => {
this.labelRef = ref;
}}
>
{labelProp}
</span>
</span>
);
}
<span className={classes.wrapper}>
{icon}
{label}
</span>
Below are some examples of possible ways to customize this.
import React from "react";
import PropTypes from "prop-types";
import Paper from "#material-ui/core/Paper";
import { withStyles } from "#material-ui/core/styles";
import Tabs from "#material-ui/core/Tabs";
import Tab from "#material-ui/core/Tab";
import PhoneIcon from "#material-ui/icons/Phone";
import FavoriteIcon from "#material-ui/icons/Favorite";
import PersonPinIcon from "#material-ui/icons/PersonPin";
const styles = {
root: {
flexGrow: 1,
maxWidth: 700
},
firstIcon: {
paddingLeft: 70
},
labelContainer: {
width: "auto",
padding: 0
},
iconLabelWrapper: {
flexDirection: "row"
},
iconLabelWrapper2: {
flexDirection: "row-reverse"
}
};
class IconLabelTabs extends React.Component {
state = {
value: 0
};
handleChange = (event, value) => {
this.setState({ value });
};
render() {
const { classes } = this.props;
return (
<Paper square className={classes.root}>
<Tabs
value={this.state.value}
onChange={this.handleChange}
variant="fullWidth"
indicatorColor="secondary"
textColor="secondary"
>
<Tab
icon={<PhoneIcon className={classes.firstIcon} />}
label="Class On Icon"
/>
<Tab
classes={{
wrapper: classes.iconLabelWrapper,
labelContainer: classes.labelContainer
}}
icon={<FavoriteIcon />}
label="Row"
/>
<Tab
classes={{
wrapper: classes.iconLabelWrapper2,
labelContainer: classes.labelContainer
}}
icon={<PersonPinIcon />}
label="Row-Reverse"
/>
<Tab icon={<PersonPinIcon />} label="Default" />
</Tabs>
</Paper>
);
}
}
IconLabelTabs.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(IconLabelTabs);
We have a inbuilt property to set the icon position of tab in material ui. Document link
iconPosition:'bottom' | 'end' | 'start' | 'top'
Still very new to Material-UI. Using the default theme/colors, I want to create an AppBar that has a FormControl/InputLabel/Select/MenuItem in it. With the defaults, I get a black input field on blue, which isn't great. I think probably having the input field and labels be theme.palette.primary.light would make more sense. I started to look in to how to do this and got in to setting FormLabelClasses to the InputLabel, setting inputProps to Select to set classes on the icon, and setting &:before and &:after to borders on the Select and so on... I feel like I'm doing this wrong since that seems to be quite a bit of work for something I think would be somewhat normal to do? To top it off, it's still not right (when you hover, the underline border goes black and I can't figure out how to fix that!)
Here's my code:
const styles = theme => ({
root: {
minWidth: 200,
marginTop: '-10px',
},
inputLabel: {
color: theme.palette.primary.light,
'&$inputLabelFocused': {
color: theme.palette.primary.light,
},
},
inputLabelFocused: {
},
icon: {
fill: theme.palette.primary.light,
},
select: {
color: theme.palette.primary.light,
'&:before': {
borderColor: theme.palette.primary.light,
},
'&:after': {
borderColor: theme.palette.primary.light,
},
},
})
class CustomSelector extends React.Component {
render() {
const { classes } = this.props;
return(
<div>
<FormControl className={classes.root}>
<InputLabel FormLabelClasses={{ root: classes.inputLabel, focused: classes.inputLabelFocused }}>Choose</InputLabel>
<Select value="" className={classes.select} inputProps={{ classes: { icon: classes.icon } }} autoWidth="true">
<MenuItem value=""><em>None</em></MenuItem>
<MenuItem value="Value 1">Value 1</MenuItem>
</Select>
</FormControl>
</div>
)
}
}