Changing the style of "Actions" in material-table react - reactjs

I have been using material-table in one of my projects.
While I am able to change the style ( font-size, color) of the user defined columns, I am not able to do so for the "Actions" column.
I am specially interested in changing the font-size.
Same issue with the pagenation: I need to change its font-size however it seems there is no option available.
Please take an example from :
https://material-ui.com/components/tables/#complementary-projects

For pagination, you should override pagination component.issue, documentation
const useStyles = makeStyles({
root: {
backgroundColor: "blue",
color: "green"
},
toolbar: {
backgroundColor: "white"
},
caption: {
color: "red",
fontSize: "20px"
},
selectIcon: {
color: "green"
},
select: {
color: "green",
fontSize: "20px"
},
actions: {
color: "blue"
}
});
...
<MaterialTable
.....
components={{
Pagination: props => (
console.log(props),
(
<TablePagination
{props.labelDisplayedRows(row)}</div>}
component="div"
colSpan={props.colSpan}
count={props.count}
rowsPerPage={props.rowsPerPage}
page={props.page}
onChangePage={props.onChangePage}
onChangeRowsPerPage={this.onChangeRowsPerPage}
classes={{
root: classes.root,
toolbar: classes.toolbar,
caption: classes.caption,
selectIcon: classes.selectIcon,
select: classes.select,
actions: classes.actions
}}
/>
)
)
}}
For for the "Actions" column, I've used actions property
actions={[
{
icon: "save",
iconProps: { style: { fontSize: "14px", color: "green" } },
tooltip: "Save User",
onClick: (event, rowData) => alert("You saved " + rowData.name)
}
]}
have look at this codesandbox,would be helpful.

if you want to stick to the user-defined theme then use props from icon api of material-ui.
actions={[
{
icon: "save",
iconProps: { fontSize: "small", color: "primary" },
tooltip: "Save User",
onClick: (event, rowData) => alert("You saved " + rowData.name)
}
]}

Related

Trying to get Yup validation working on Controller and custom components based on react-select for overall form validity and error style

New to React here so I do appreciate any insight others may have on this.
I am trying to validate a custom select component based on react-select. I am having trouble with the following:
Showing the error styling for the select field while also having it work for the overall form validity. I am using react-hook-form and Yup validation.
I have a custom component here called CreditAppCustomSelect:
import { TextField } from '#mui/material';
import Image from 'next/image';
import React from 'react';
import Select, { components } from 'react-select';
import Arrow from '../../assets/images/icon/Icon.png';
export interface CustomStyles {
isHover: boolean;
isFocused: boolean;
isSelected: boolean;
}
const colourStyles = (isError: boolean) => ({
control: (styles: object, { isHover, isFocused }: CustomStyles) => {
return {
...styles,
borderRadius: '0px',
backgroundColor: 'white',
border: isFocused
? '0.1875rem solid #00B0C7'
: isError
? '0.1875rem solid #F6AE55'
: '0.1875rem solid #000000',
boxShadow: isHover ? '0.1875rem solid #00B0C7' : undefined,
'&:hover': {
border: isHover ? '0.1875rem solid #00B0C7' : undefined,
},
fontFamily: 'Avenir',
fontStyle: 'normal',
fontWeight: 500,
fontSize: '1.25rem',
/* or 30px */
color: '#969696',
textTransform: 'capitalize',
'#media only screen and (max-width:991px)': {
// #ts-ignore
...styles['#media only screen and (max-width:991px)'],
height: '3rem',
},
minHeight: '3rem',
};
},
dropdownIndicator: (
styles: object,
{ isFocused, isSelected, isHover }: CustomStyles
) => {
return {
color: '#242424',
marginInline: '0.2rem',
width: '0.625rem',
minWidth: '0.5rem',
};
},
option: (styles: object, { isFocused, isSelected }: CustomStyles) => {
return {
...styles,
backgroundColor: isFocused ? '#BBE8EE' : undefined,
color: 'black',
cursor: 'default',
'&:active': {
backgroundColor:
isSelected || isFocused ? 'rgba(176, 117, 251, 0.3)' : undefined,
},
};
},
menu: (styles: object) => {
return {
...styles,
boder: '0.0625rem solid #242424',
outline: '0.0625rem solid #242424',
color: '#242424',
// top: "0rem",
margin: '0 0.0625rem',
boxSizing: 'border-box',
width: 'calc(100% - 2px)',
borderRadius: '0px',
zIndex: 99,
fontFamily: 'Avenir',
fontStyle: 'normal',
fontWeight: 500,
fontSize: '1.25rem',
textTransform: 'capitalize',
};
},
input: (styles: object) => ({
...styles,
fontSize: '1.25rem',
}),
placeholder: (styles: object) => {
return {
...styles,
fontFamily: 'Avenir',
fontStyle: 'normal',
fontWeight: 500,
fontSize: '1.25rem',
/* or 30px */
color: '#969696',
textTransform: 'capitalize',
};
},
container: (
styles: object,
{ isFocused, isSelected, isHover }: CustomStyles
) => {
return {
...styles,
// borderRadius: "4px",
outline: 'none',
height: '3rem',
};
},
singleValue: (styles: object, { isFocused, isSelected }: CustomStyles) => {
return {
...styles,
fontSize: '1.25rem',
color: '#211e3b',
};
},
valueContainer: (styles: object) => {
return {
...styles,
paddingLeft: '0.75rem',
};
},
});
const CreditAppCustomSelect = (props: any) => (
<div className='credit-app-select-container'>
<label className={props.isError ? 'error' : ''}>
{props.label}
<Select
{...props}
styles={colourStyles(props.isError)}
components={{
IndicatorSeparator: () => null,
// eslint-disable-next-line #next/next/no-img-element
DropdownIndicator: (props) => (
<components.DropdownIndicator {...props}>
<Image src={Arrow} alt='down' />
</components.DropdownIndicator>
),
}}
isSearchable={false}
placeholder={props.placeholder}
onChange={props.onChange}
value={props.value} // This can be set like this as a result of the change
/>
{props.isError ? <span>{props.message}</span> : ''}
</label>
</div>
);
export default CreditAppCustomSelect;
in my form schema I have the following - one works for overall form validity and the other works for error styling - I know I can't use both so not sure what to do?:
// this works for overall form validity based on having a selected value (isValid)
employeeNumbers: Yup.object().shape({
label: Yup.string().nullable().required('Required'),
value: Yup.string().nullable().required('Required'),
}),
// the following works for the error styling and message but I know I can't do both this and the above
// employeeNumbers: Yup.string().nullable().required('Required'),
I am using a Controller around the CreditAppCustomSelect component:
<Controller
defaultValue=''
control={control}
{...register('employeeNumbers', { required: true })}
render={({ field }: any) => (
<CreditAppCustomSelect
{...field}
label='Number of Employees/Contractors'
name='employeeNumbers'
placeholder='Select range'
isError={
errors.employeeNumbers &&
errors.employeeNumbers.type === 'required'
}
message={'Required'}
options={numberEmployeesOptions}
/>
)}
/>
The options look like this
const numberEmployeesOptions = [
{ label: '1 - 4', value: '1 - 4' },
{ label: '5 - 9', value: '5 - 9' },
{ label: '10 - 19', value: '10 - 19' },
{ label: '20 - 49', value: '20 - 49' },
{ label: '50 - 99', value: '50 - 99' },
{ label: '100+', value: '100+' },
];
in the interface for the form I have the following for employee numbers:
employeeNumbers: { label: string; value: string };
I have not posted the entire form since it is so long but I am using mode:onBlur for the overall form and working in tsx files. Just trying to reconcile how I can achieve both form validity as well as error styling. I have searched for related issues in StackOverflow and I know there probably are solutions but have not yet managed to solve this and have been spinning my wheels for a while.
Thanks for any suggestions anyone may have!

React Material UI - DataGrid onRowClick

I am completely new to React and Material UI. I had followed the step from YouTube to create DataGrid, but now I want to create one more function which when I click on a row of DataGrid, the interface will jump to the detail page of the row.
Thank you so much!!
`
import { Box } from "#mui/material";
import { DataGrid, GridToolbar } from "#mui/x-data-grid";
import { tokens } from "../../theme";
import { mockDatareworks } from "../../data/mockData";
import Header from "../../components/Header";
import { useTheme } from "#mui/material";
const Reworks = () => {
const theme = useTheme();
const colors = tokens(theme.palette.mode);
const columns = [
{ field: "id", headerName: "ID", flex: 0.5 },
{ field: "return_date", headerName: "Date" },
{
field: "customer_name",
headerName: "Customer",
flex: 1,
cellClassName: "name-column--cell",
},
{
field: "product_name",
headerName: 'Product',
flex: 1,
},
{
field: "rework_quantity",
headerName: "Quantity",
type: "number",
headerAlign: "left",
align: "left",
},
];
return (
<Box m="20px">
<Header
title="Rework"
subtitle="List of reworks for Future Reference"
/>
<Box
m="40px 0 0 0"
height="75vh"
sx={{
"& .MuiDataGrid-root": {
border: "none",
},
"& .MuiDataGrid-cell": {
borderBottom: "none",
},
"& .name-column--cell": {
color: colors.greenAccent[300],
},
"& .MuiDataGrid-columnHeaders": {
backgroundColor: colors.blueAccent[700],
borderBottom: "none",
},
"& .MuiDataGrid-virtualScroller": {
backgroundColor: colors.primary[400],
},
"& .MuiDataGrid-footerContainer": {
borderTop: "none",
backgroundColor: colors.blueAccent[700],
},
"& .MuiCheckbox-root": {
color: `${colors.greenAccent[200]} !important`,
},
"& .MuiDataGrid-toolbarContainer .MuiButton-text": {
color: `${colors.grey[100]} !important`,
},
}}
>
<DataGrid
rows={mockDatareworks}
columns={columns}
components={{ Toolbar: GridToolbar }}
/>
</Box>
</Box>
);
};
export default Reworks;
`
This is my current code for the DataGrid page, how can I add the function of clicking and jump to the detail page of the row?
Please use onRowClick prop
https://mui.com/x/react-data-grid/events/
<DataGrid
rows={mockDatareworks}
columns={columns}
components={{ Toolbar: GridToolbar }}
onRowClick={handleRowClick} // here
/>
Here are handleRowClick paras
const handleRowClick = (
params, // GridRowParams
event, // MuiEvent<React.MouseEvent<HTMLElement>>
details, // GridCallbackDetails
) => {
setMessage(params);
};

How to style 'disabled' class in TextField in Material UI 5 using global CreateTheme?

I want to style differently TextFiled component , variant outlined once disabled={true}.
The way it was catched in material ui v.4 don't work in material ui v.5. I cannot also google the solution how to customize disabled version.
Below You can see how it was styled in material ui4 and it worked, not it does not.
export const MainTheme: Theme = createTheme({
components: {
MuiInputLabel: {
styleOverrides: {
root: {
fontSize: '13px',
'&$focused': {
borderColor: '#000',
},
'&$disabled': {
color: '#724a4a',
},
},
},
},
MuiInputBase: {
styleOverrides: {
root: {
'&$disabled': {
'& fieldset.MuiOutlinedInput-notchedOutline': {
borderColor: 'transparent',
background: 'rgb(0 0 0 / 4%)',
},
},
},
input: {
height: 'unset',
color: '#000000',
},
},
},
},
)}
You can do it like this SandBox
const finalTheme = createTheme({
components: {
MuiTextField: {
variants: [ // variants will help you define the props given by Mui and the styles you want to apply for it
{
props: { variant: 'outlined', disabled: true },
style: {
backgroundColor: 'green',
color: 'red',
fontSize: '5rem'
}
}
]
}
}
})
<ThemeProvider theme={finalTheme}>
<TextField
disabled
id="outlined-basic"
label="Outlined"
variant="outlined"
/>
</ThemeProvider>
Reference : https://mui.com/customization/theme-components/#global-style-overrides

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