If/Else if/Else Ternary - css

I am trying to do some coniditonal styling in react js. Very new to react, so there may be a better way to do this, but have searched the internet to no avail. I am trying to check the screen size and style based off of said screen size. In this use case I am wanting to center some text based off of screen size. Can someone please tell me if there is a better way to do this? This is not working for me currently.
Edit: Placed some logs in there and what it is doing exactly is when the page loads "textAlign" is not applied to the element at all even though the screen size is > 993px. Once I shrink the screen down to < 993px and > 578px is applies the "textAlign: center" to the element and then once it shrinks down < 578px it does not set it back to none. It keeps it centered.
const styles = {
footerColOne:{
textAlign: deviceSize > 993 ? "none" : (deviceSize < 993 && deviceSize > 578) ? "center" : "none",
paddingLeft: deviceSize < 993 ? "26px" : "80px",
paddingTop: deviceSize < 993 ? "28px" : "63px",
},
footerColTwo:{
textAlign: deviceSize > 993 ? "none" : (deviceSize < 993 && deviceSize > 578) ? "center" : "none",
paddingLeft: deviceSize < 993 ? "26px" : deviceSize < 578 ? "51px" : "50px",
paddingTop: deviceSize < 993 ? "40px" : "86px",
},
}
I am then calling that style like this
<Col lg={3} style={ styles.footerColOne }>
Any help is greatly appreciated.
Last Edit:
So I have found media queries is indeed the preferred way to go here, my ternary condition above worked though I made an idiot mistake and was setting textAlign to none when that value does not exist for that property. It should be set to initial in this case.

media query will be good fit here.
#media screen and (min-width: 578px) and (max-width: 993px) {
.someclass {
text-align:center;
}
}
#media screen and (max-width: 993px) {
.someclass {
text-align:center;
padding-left:26px;
padding-right:28px;
}
}
#media screen and (min-width: 993px) {
.someclass {
text-align:left /* none as you wanted. /*;
}
}
So given,
max-width all the styles inside this media query will be applied if screen size is below this max-width.
min-width all the styles inside this media query will be applied if the screen size is greater than the min-width.

const getDevice = (deviceSize) =>
deviceSize < 993
? (deviceSize < 993 && deviceSize > 578)
? 'tablet'
: 'mobile'
: 'web'
// if declare css -> return class
// component use className instead of styles
// <Col lg={3} className={...} />
const footerColOne = {
'web': () => {
return {
textAlign: 'none',
paddingLeft: '26px',
paddingTop: '28px'
}
},
'tablet': () => {
return {
textAlign: 'center',
paddingLeft: '80px',
paddingTop: '63px'
}
},
'mobile': () => {
return {
textAlign: 'none',
paddingLeft: '80px',
paddingTop: '63px'
}
}
}
const styles = {
footerColOne: footerColOne[getDevice(deviceSize)]()
}
console.log(styles.footerColOne)
// <Col lg={3} style={ styles.footerColOne }>

Related

How to implement responsive width for Drawer MUI v5 component?

I am using Material UI v5, and am trying to make a responsive drawer where for smaller devices it will take up 100% of screen width while for larger devices it should only take 1/3 of screen width. But I have no idea how to access Paper property to modify the actual width and make it responsive.
My code:
import { Drawer, styled } from "#mui/material";
const ResponsiveDrawer = styled(Drawer)(({ theme }) => ({
[theme.breakpoints.up("md")]: {
width: "33%", // THIS ONLY CHANGES DRAWER WIDTH NOT PAPER WIDTH INSIDE THE DRAWER
},
[theme.breakpoints.down("md")]: {
width: "100%",
},
}));
export { ResponsiveDrawer };
How I use it:
import { ResponsiveDrawer } from "./Style";
<ResponsiveDrawer
anchor="right"
open={drawer.state}
onClose={() => drawer.onClick(false)}
>
...
</ResponsiveDrawer>
I figured it out shortly after posting the question. This involves inline styling using useMediaQuery.
const largeScreen = useMediaQuery(theme.breakpoints.up("sm"))
<Drawer
anchor="right"
open={drawer.state}
onClose={() => drawer.onClick(false)}
PaperProps={largeScreen ? {
sx: {
width: 450,
}
} : {
sx: {
width: "100%",
}
}
}
>
<CartContent cart={cart} drawer={drawer}/>
</Drawer>
You can add a div inside the <Drawer> or <SwipeableDrawer> component like so and control the width of the div through CSS (or emotion/styled, if you prefer).
<Drawer ...>
<div className="container">...</div>
</Drawer>
.container {
width: 95vw; // for mobile
... add media queries for rest of the screen sizes here
}
In their docs (expand the code blow) they give an example how to access the paper CSS, where you could add your width settings:
const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open' })(
({ theme, open }) => ({
width: drawerWidth,
flexShrink: 0,
whiteSpace: 'nowrap',
boxSizing: 'border-box',
...(open && {
...openedMixin(theme),
'& .MuiDrawer-paper': openedMixin(theme),
}),
...(!open && {
...closedMixin(theme),
'& .MuiDrawer-paper': closedMixin(theme),
}),
}),
);
They add the same mixin to '& .MuiDrawer-paper' in the main drawer css.
So for your responsive drawer you should add this paper selector to your styled CSS (maybe check with the inspector, if its the right one):
const ResponsiveDrawer = styled(Drawer)(({ theme }) => ({
[theme.breakpoints.up("md")]: {
width: "33%",
'& .MuiDrawer-paper': {
width: "33%",
},
},
[theme.breakpoints.down("md")]: {
width: "100%",
'& .MuiDrawer-paper': {
width: "100%",
},
},
}));
More information about customizing nested elements can be found on https://mui.com/material-ui/customization/how-to-customize/#the-sx-prop.

styling material-table (specifically height)

I'm using material table from material UI react from here and I can't figure out how to style the table properly, especially the height of rows.
I've tried all the ways explained in doc, alternatively and altogether and nothing makes it.
But there seems to be something somewhere that takes precedence over my css. Some of these CSS prop do have effects (like textAlign and vertical align), but most don't.
What am I missing here ?
I also overrode some css directly, without any effect
tr {
height: 100px;
}
tr td {
height: auto !important;
overflow:scroll;
}
MuiTableRow-root.{
height:50px;
max-height:50px;
}
here's my code:
let columns = [];
//console.log(this.props.data.matrix[0][0])
for(var i=0;i<this.props.headers.length;i++){
let filtering = false;
let obj = {'title':this.props.headers[i].display,'field':this.props.headers[i].accessor,headerStyle: {
backgroundColor: '#315481',
color: '#FFF',
},cellStyle:{maxHeight:50,height:50,overflow:'scroll',padding:1}}
columns.push(obj)
}
return(
<div>
<a className="anchor" id={this.props.id}></a>
<div className="centeringDiv"><h3>{this.props.title}</h3></div>
{this.props.infoText && <SectionInfo infoText = {this.props.infoText} />}
<div style={{ maxWidth: '100%',marginTop:15}}>
<MaterialTable
columns={columns}
data={this.props.dataToDisplay}
title={''}
onRowClick={((evt, selectedRow) => this.setState({ selectedRow }))}
options={{
pageSize:pageSizeCalc,
maxBodyHeight:400,
paging:true,
filtering:this.props.filtering,
pageSizeOptions: pageSizeOptionsCalc,
//fixedColumns: {left: 1},
rowStyle: rowData => ({backgroundColor: (this.state.selectedRow && this.state.selectedRow.tableData.id === rowData.tableData.id) ? '#EEE' : '#FFF',maxHeight:100}),
headerStyle:{height:60,maxHeight:60,padding:0,overflow:'none',lineHeight:1,textAlign:'center',fontSize:'2.5vh'},
cellStyle:{height:100,overflowY:'scroll',verticalAlign:'top',fontSize:'2vh',overflow:'scroll',padding:1}
}}
/>
finally the computed css
Try to style cell with cellStyle property like:
const cellStyle = {
padding: '0 14px',
};
const [state, setState] = React.useState<TableState>({
columns: [
{ title: 'ID', field: 'id', cellStyle }...
]
...
})

Setting a conditional background linear gradient for getTrProps in react-table not rendering correctly

I'm trying to stylize a row in my react table so that when a certain row's data changes, the background has a linear-gradient applied to the row's background. I've tried a couple of things and looked up their documentation with examples with no luck.
I've tried a couple of things and looked up their documentation with examples with no luck.
I've made the linear gradient a variable and then plugged it into the conditional like so:
const gradient = {
linearGradient: `(to left, #27293d 99%, #344675 1%)`
}
const getTrProps = (rowInfo) => {
if (rowInfo) {
return {
style: {
height: `60px`,
padding: `5px`,
margin: `5px`,
borderRadius: `5px`,
backdropFilter: `blur(15px)`,
background: rowInfo.status === 'created' ? linearGradient : `red`
}
}
}
return {};
}
The column associated with the status in question is this:
{
Header: 'Status',
accessor: 'status',
Cell: row => (
<div style={{
width: `${row.value}%`
}}>
<span>
{
row.value === 'created' ? <GreenStatusCircle /> :
row.value === 'awaiting_driver' ? <YellowStatusCircle /> :
row.value === 'delivered' ? <RedStatusCircle /> : "None Found"
}
</span>
</div>
)
},
It should be rendering with the linear-gradient, but instead all of my rows are red. I've looked at the example shown here:
https://codesandbox.io/s/k3q43jpl47
And it seems I'm doing it just fine, but it won't render correctly.
You could pass it as HTML attribute but not as style
Instead of:
const gradient = {
linearGradient: `(to left, #27293d 99%, #344675 1%)`
}
Change it to
const gradient = {
someColor: 'linear-gradient(to left, #27293d 99%, #344675 1%)'
}
and us it as
const getTrProps = (rowInfo) => {
if (rowInfo) {
return {
style: {
height: `60px`,
padding: `5px`,
margin: `5px`,
borderRadius: `5px`,
backdropFilter: `blur(15px)`,
background: rowInfo.status === 'created' ? gradient.someColor: `red`
}
}
}
return {};
}
Example: https://codesandbox.io/s/react-table-gettrprops-h0oht

How to removing the padding for card in and design?

I am using ant design to react UI components. I need to remove the padding given for the ant design card.
So I need to remove the padding given for the classes .ant-card-wider-padding and .ant-card-body.I am using JSS for styling the UI components.
cardStyle: {
marginTop: '30px',
boxShadow: '0px 1px 10px rgba(0,1,1,0.15)',
backgroundColor: '#ffffff',
borderStyle: 'solid',
outline: 'none',
width: '100%',
},
i am using cardStyle class to styling ant design card.Now i need to remove the padding in that card.
From the documentation of Ant Design
You need to override the style in bodyStyle not cardStyle
bodyStyle: Inline style to apply to the card content
<Card title="Card title" bodyStyle={{padding: "0"}}>Card content</Card>
use fullWidth props for removing padding..,
<Card.Section fullWidth>
<ResourceList
items={[
{
id: 341,
url: 'customers/341',
name: 'Mae Jemison',
location: 'Decatur, USA',
}
]}
renderItem={
(item) => {
const {id, url, name, location} = item;
const defaultImage = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48cGF0aCBkPSJNLS4wMi0uMDFoMTAwdjEwMGgtMTAweiIgZmlsbD0iI2ZmZTBjMyIvPjxwYXRoIGZpbGw9IiNmZjk2N2QiIGQ9Ik0wIDBoNjkuNDF2MTAwSDB6Ii8+PHBhdGggZD0iTTY5LjkyIDB2NDQuMzJMNTEuMzQgNTV2NDVIMTAwVjB6IiBmaWxsPSIjZmZlMGMzIi8+PHBhdGggZmlsbD0iIzMyY2FjNiIgZD0iTTM5LjMyIDc2YTExLjg1IDExLjg1IDAgMCAwIDEyIDExLjYyVjc2Ii8+PHBhdGggZmlsbD0iIzAwOTc5NiIgZD0iTTM5LjMyIDc2YTEyIDEyIDAgMCAxIDEyLTExLjgyVjc2Ii8+PHBhdGggZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI1IiBkPSJNNDMuNzQgMTkuODNhMTIuODIgMTIuODIgMCAxIDEtMjUuNjQgMCIvPjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNCIgZD0iTTI3LjM5IDMxLjZsLTEuNTggNS45Nm05LjM3LTUuNzJsMi41NSA1LjQ3bTQuMjYtOS44NWwzLjUzIDQuNW0tMjUuNDMtNC41bC0zLjUzIDQuNSIvPjwvc3ZnPgo=" ;
const media = <Thumbnail source={defaultImage} size="small" name={name} />;
return (
<ResourceList.Item id={id} url={url} media={media}>
<Stack alignment="center">
<Stack.Item fill>
<TextStyle>{name}</TextStyle>
</Stack.Item>
<Stack.Item>
<TextStyle>Last changed</TextStyle>
</Stack.Item>
<Stack.Item>
<Button>Edit Giffy</Button>
</Stack.Item>
</Stack>
</ResourceList.Item>
);
}
}
/>
</Card.Section>
very simple just add bodyStyle in Card Component
<Card bodyStyle={{ padding: "0"}}>
You can use this:
.cardStyle {
padding: 0;
}
If didn't work, use this:
.cardStyle {
padding: 0 !important;
}
I'm not too familiar with JSS but if your other styles are being applied then I assume the issue is not with that.
I was able to remove the padding from the card with the following code.
//style.less
.panelcard { ... }
.panelcard .ant-card-body {
padding: 0;
}
// panelCard.js
import { Card } from 'antd';
require('./style.less');
const PanelCard = ({ children }) => {
return (
<Card className='panelcard'>
{children} // <p>Some Child Component(s)</p>
</Card>
);
}
// invocation
<PanelCard label='Panel Title'>
<p>Some Child Component(s)</p>
</PanelCard>
This gave me the following output (card is the white box):
I am not sure if this is the preferred way of customizing antd's components but I didn't really find too much on antd's website about overriding styles, only on extending components.
Try using :global in you scss/less
div { // or any parent element/class
:global {
.ant-card-body {
passing: <number>px; // number can be 0 onwards
}
}
}

How do I control style of material-ui SelectField

I am using material-ui with react "material-ui": "^0.19.2" and am trying to place a SelectField in a table. This much is working fine but the margin and/or padding applied to the select component is doing 2 unwanted things. First is the table rows now adjust to the height of the select which is making the size of the entire row too high. Secondly the alignment of everything else in the row is off.
My code:
<SelectField
value={ props.value }
hintText="Select location.."
style={ {
width: 150,
padding: 0,
margin: 0
} }
onChange={ (event, key, payload) => this.updateLocation(event, payload, props.index, props.original.something) }>
{ ::this.createMenu() }
</SelectField>
createMenu = () => {
const { locations } = this.props.list;
return locations.map((location, i) => {
return <MenuItem key={ i } value={ location } primaryText={ location } />
});
}
If I could control the styling around the component(Textfield??) that is rendered I would try and make it fit properly but the style prop on the SelectField only seems to style the dropdown list.
Another option for me here could be to go with a popover for the field and render a custom component to attach it to - but I haven't had much luck when trying use that.
The following props on the SelectField give me what I want:
<SelectField
value={props.value}
hintText="Select location.."
style={{
width: 150,
height: 15,
lineHeight: 15,
position: 'relative',
textAlign: 'center',
fontSize: '0.9em'
}}
menuStyle={{
position: 'absolute',
top: -12.5,
}}
underlineStyle={{
position: 'relative',
top: 20,
}}
onChange={(event, key, payload)=>this.updateLocation(event,payload,props.index,props.original.something)}
>
{
::this.createMenu()
}
</SelectField>
if anyone knows a better way please add an answer but for now this will answer my question.
<b>Just add maxHeight={200} inside SelectField</b>
< SelectField
multiple
fullWidth = {true}
value={this.state.candidate_profile_arr}
onChange = {this.handleChange}
maxHeight = {200}
>
{this.state.profile.map((profile, i) =>
<MenuItem value={profile.id} key={i} primaryText={profile.name} />)
}
</SelectField>

Resources