Applying specific theme for react material-table - reactjs

I'm trying to integrate react material-table (https://github.com/mbrn/material-table) with my project.
I want to update the styling/theme.
I used something like.
<MaterialTable options={{
rowStyle: x => {
if ( x.id % 2 ) {
return { backgroundColor: "#f2f2f2" }
}
},
'headerStyle' : {
backgroundColor: 'red',
color: theme.palette.common.white
}
}}
columns={columns}
data={data}
title="New Table"
/>
However I want to have a generic styling and theme like
const CustomTableCell = withStyles(theme => ({
head: {
backgroundColor: theme.palette.common.black,
color: theme.palette.common.white,
},
body: {
fontSize: 14,
},
}))(TableCell);
Basically i want to have something like CustomMaterialTable which is nothing but my theme/style.
Striping the table rows.
In the above code snippet, I used a logic to have striped rows.
if ( x.id % 2 ) {
return { backgroundColor: "#f2f2f2" }
}
Since my table will be having sorting, I want the it to be on a auto generated row id rather than x.id (where x is my data).
I want to use rtl and text in multiple languages based on the language selection (dynamic).

You can overrides components. Look at example: https://mbrn.github.io/material-table/#/docz-examples-10-example-component-overriding
Can you try x.tableData.id instead of x.id, please?
You should use material-ui theme with direction (ltr or rtl): https://material-ui.com/customization/themes/

you can use material-UI makeStyles for changing material-table theme.
This example when I'm changing the look for material-table
I implemented striped rows using
'&:nth-child(even)': {
backgroundColor: '#FAF7FA',
},
because when using rowStyle and after changing the table sorting, the stripped rows remain attached to their main fields.
Here is the full example:
export const useClasses = makeStyles(({ palette }) => ({
root: {
borderTopRightRadius: '12px',
borderTopLeftRadius: '12px',
boxShadow: '0px 5px 40px rgb(0 0 0 / 10%)',
fontFamily: 'Montserrat',
overflow: 'hidden',
'& .MuiPaper-root ': {
boxShadow: 'none',
},
'& .MuiTable-root': {
color: palette.text.textPrimary,
'& .MuiTableHead-root': {
'& .MuiTableRow-head': {
'& .MuiTableCell-head': {
background: 'rgba(90, 0, 90, 0.09)',
color: palette.text.textPrimary,
},
},
},
'& .MuiTableRow-root': {
'&:nth-child(even)': {
backgroundColor: '#FAF7FA',
},
},
},
},
}));

Related

How to change the Background Color of the Ant-Design 'Select' component?

Suppose I want to change the standard white background color of the Select component dynamically based on selection. I found a solution
on the internet .ant-select-selection { background-color: green; } but this is static.
It should be like this:
Here is my codesandbox link
Here is a sample code:
const RBICOptions = [
{
background: "#00CC00",
color: "#fff",
title: "Low",
value: "low"
},
{
background: "#FFFF00",
color: "#000",
title: "Medium",
value: "medium"
},
{
background: "#FFC000",
color: "#000",
title: "High",
value: "high"
},
{
background: "#FF0000",
color: "#fff",
title: "Very High",
value: "very_high"
}
];
const App: React.FC = () => {
const [selectedIPSS, setSelectedIPSS] = useState("#fff");
console.log("selectedIPSS", selectedIPSS);
return (
<Select
style={{
width: "50vw",
marginBottom: "5%",
backgroundColor: selectedIPSS
}}
onChange={(_, option) => {
setSelectedIPSS("style" in option ? option.style.background : "#fff");
}}
>
{RBICOptions.map((op) => (
<Select.Option
key={op.value}
value={op.value}
style={{ background: op.background, color: op.color }}
>
{op.title}
</Select.Option>
))}
</Select>
);
};
Please help me out with this issue. Thanks in advance.
Its because the ant-select class already defines a white background. You can remove it with setting the style to inherit:
.ant-select:not(.ant-select-customize-input) .ant-select-selector {
background-color: inherit;
}
Here is a codesandbox: https://codesandbox.io/s/select-with-search-field-antd-4-24-1-forked-rzln9z?file=/index.css:0-99

Passing sx prop to a custom component

I have a component that I use as a layout component, and in nearly all cases it works just fine, however there are one or two places where I need to be able to adjust the styles, and I would like to be able to do this by simply passing the exact styles that I need instead of adding some custom prop that will toggle them on or off.
The component looks like this:
const BlockLayout: React.FC<IProps> = ({
children,
id,
forceToBottom,
sxProps, // <--- What I want to add
}) => {
return (
<Box
id={id}
sx={[
{
backgroundColor: (theme) => theme.palette.background.paper,
mt: forceToBottom ? 'auto' : 1,
borderRadius: 0.5,
display: 'flex',
border: '1px solid rgba(0, 0, 0, 0.1)',
flexWrap: 'wrap-reverse',
},
sxProps, //<--- How I could use it?
(theme) => ({
...(theme.palette.mode === 'dark' && {
border: `1px solid ${lighten(
theme.palette.background.paper,
0.15
)}`,
}),
}),
]}
>
{children}
</Box>
)
}
How can this be done, and what type do the props need to have?
In the documentation they just cast the type to const.
You can add them as follows using the spread operator:
},
sxProps && ...sxProps,
(theme) => ({

How to change table row background color on hover or mouseover in Material ui datatable

Very very new to React and Material-UI.
I'm trying to change the color of the table rows when the pointer / mouse is moved over the rows , i.e. on hover.
I have tried 'solutions' from other posts but no success.
(e.g. Root and cell and tableRow)
The xx.js
export const xxTheme = createTheme({
typography: {
fontFamily: 'xxText',
fontSize: 11,
},
tableRow: {
"&$hover:hover": { backgroundColor: "blue" }
},
tableCell: {
"$hover:hover &": { color: "pink"
}
},
hover: {},
overrides: {
MuiTableCell: {
root:{
color: xxColors.grey2,
'& .MuiCheckbox': { color: xxColors.grey2, },
"&$hover:hover" : { backgroundColor: "blue" }
},
head: {...}
tableRow: { "&$hover:hover": { backgroundColor: "cyan" }
},
},
In the xxTableBody.js
import {Table, TableContainer} from "#material-ui/core";
import {Checkbox, TableBody, TableCell, TableRow} from "#material-ui/core";
import {xxColors} from "../styles/xx";
<TableRow
key={step.workStepId}
ref={dragProvided.innerRef}
selected={isItemSelected}
aria-checked={isItemSelected}
{...dragProvided.draggableProps}
classes={{'hover':{color:'#7EA55FF'}}}
style={{
...dragProvided.draggableProps.style,
background: snapshot.isDragging ? xxColors.blue1 : "none",
}}
>
<TableCell key={'drag'} align={'left'}>
<div {...dragProvided.dragHandleProps}>
<ReorderIcon/>
</div>
</TableCell>
What needs doing/fixing?
TIA
By removing the jss conditional 'snapshot.isDragging' thru to setting background = none, and using std css, resolved that problem.

How to select only one day in react-big-calendar month view

I'm using react-big-calendar for calendar purpose in month view. https://github.com/jquense/react-big-calendar and i want to implement Add a new event by clicking on any cell (day) and i'm not sure what props should i use.
I know onSelectEvent will select only existing events no the entire day and this is not what i need and also selectable={true} will enable multi-selecting which in my case is useless.
so i need something like onDayClick or something but i wasn't so much lucky so far
I finally came up with using onSelectSlot and hiding multi-selecting effect manually using css, it's not perfect but its working!
<BigCalendar
view="month"
onNavigate={onNavigate}
culture="en-GB"
date={currentDate}
selectable={true}
onSelectEvent={onSelectEvent}
onSelectSlot={onSelectSlot}
onView={() => {}}
localizer={localizer}
events={events}
/>
Using end of selected slot as selected day: (I know it's not perfect!)
const onSelectSlot = (slotInfo: {
start: stringOrDate;
end: stringOrDate;
slots: Date[] | string[];
action: 'select' | 'click' | 'doubleClick';
}) => {
// use moment(slotInfo.end) as selected day!
};
Hiding multi-selecting effect using css:
calendar: {
'& > .rbc-calendar': {
width: '100%',
minHeight: '500px',
},
'& .rbc-month-view': {
border: 'none',
'& .rbc-event': {
paddingLeft: '2px',
borderRadius: 3,
backgroundColor: theme.palette.secondary.main,
},
'& .rbc-now': {
color: theme.palette.secondary.main,
},
'& .rbc-selected-cell': {
backgroundColor: '#fff',
},
'& .rbc-today.rbc-selected-cell': {
backgroundColor: '#eaf6ff',
},
'& .rbc-off-range-bg.rbc-selected-cell': {
background: '#e6e6e6',
},
'& .rbc-month-row': {
cursor: 'pointer',
},
},
},
You can do it like this it will work.
I just made a modal popup on click of a slot, you can put an alert or a console log
const handleSelectSlot = (start) => {
this.getModalData(start);
this.setState({ modalOpen: true });
this.setState({ valueIntoModal: start.start });
};
<Calendar
selectable={true}
formats={formats}
localizer={localizer}
events={[
...this.state.submittedData.data,
...this.state.savedData.data,
]}
view="month"
views={["month"]}
onSelectSlot={handleSelectSlot}
startAccessor="start"
endAccessor="end"
/>

changing style object at index of array in state in react

i'm trying to update a style object inside my options array inside my apps state when an option is clicked in another component using toggleSelected (). Does anyone know how to best access the object and set the background color to something different?
App.js
this.state = {
options: [
{
id: 0,
label: "Industrial Truck and Tractor Operators",
value: "53-7051",
style: {
display: "flex",
margin: "auto",
paddingTop: "1em",
paddingBottom: "1em",
paddingLeft: "1em",
borderBottom: "solid",
borderColor: "black",
borderWidth: ".1em",
color: "#64bd9a",
backgroundColor: "white"
},
tooltip_text:
'Operate industrial trucks or tractors equipped to move materials around a warehouse, storage yard, factory, construction site, or similar location. Excludes “Logging Equipment Operators" (45-4022).'
},
{
id: 1,
label: "Order Clerks",
value: "43-4151",
style: {
display: "flex",
margin: "auto",
paddingTop: "1em",
paddingBottom: "1em",
paddingLeft: "1em",
borderBottom: "solid",
borderColor: "black",
borderWidth: ".1em",
color: "#64bd9a",
backgroundColor: "white"
},
tooltip_text:
'Receive and process incoming orders for materials, merchandise, classified ads, or services such as repairs, installations, or rental of facilities. Generally receives orders via mail, phone, fax, or other electronic means. Duties include informing customers of receipt, prices, shipping dates, and delays; preparing contracts; and handling complaints. Excludes "Dispatchers, Except Police, Fire, and Ambulance" (43-5032) who both dispatch and take orders for services.'
}
],
value: null,
styles: {
//container style is working
marginTop: "2em",
marginLeft: "2em",
borderStyle: "solid",
borderWidth: ".1em",
borderBottom: "none",
borderRight: "solid",
width: "19em",
textAlign: "justify",
backgroundColor: "white",
boxShadow: "3px 6px 5px #9E9E9E"
},
className: "",
selectedClassName: "",
loading_State: true, //this changes to false when the component loads
childrenCount: 0
};
toggleSelected = child => {
this.setProps({options.indexOf('1').style.backgroundColor: "gray" })
};
Component.js
render() {
return (
<div style={this.props.styles}>
{this.props.options.map(option => (
<div
key={option}
id={"option" + option.id}
style={option.style}
onClick={e => {
if (this.props.setProps) {
this.props.setProps({ value: e.target.value });
} else {
this.setState({ value: e.target.value });
}
this.props.toggleSelected(option.id); //passing my index here to the function
}}
>
<span id={option.id}> {option.label} </span>
<UncontrolledTooltip
placement="right"
target={"option" + option.id}
>
{option.tooltip_text}
</UncontrolledTooltip>
</div>
))}
</div>
);
}
Am I going about this the right way in terms of updating the styles object here. Should I use a different approach. Also I would like to do this without using CSS so adding classNames is not what I want to do.
I believe the following should work, assuming childIndex here represents the index of the state.options array that you want to modify.
toggleSelected = (childIndex) => {
const newOptions = this.state.options.map((option, i) => {
if (i !== childIndex) {
return option;
}
return {
...option,
style: {
...option.style,
backgroundColor: "green" // your color here
}
}
});
this.setState({ options: newOptions });
}
Edit: If you need to change all the other colors to white, you can do the following:
toggleSelected = (childIndex) => {
const newOptions = this.state.options.map((option, i) => {
return {
...option,
style: {
...option.style,
backgroundColor: i === childIndex ? "green" : "white"
}
}
});
this.setState({ options: newOptions });
}

Resources