Reputation: 6347
export enum SizeEnum {
Small,
Large
}
export interface ICheckbox {
Size: SizeEnum;
}
const Box = styled.div`
height: 20px;
width: 20px;
`
In the above code I want to be able to conditionally change the height and width value of <Box>
based on the prop. How do I do this?
Upvotes: 8
Views: 36447
Reputation: 542
I know that this question is pretty old but I would like to contribute with one suggestion
Lately I've come up with a pattern to compute the value using an object, I think this ended up being pretty interesting!
// types.ts
export type CheckboxSize: 'Small' | 'Large'
export interface ICheckbox {
Size: CheckboxSize;
}
// styles.ts
import styled, { css } from 'styled-components'
import type { CheckboxSize } from './types.ts'
interface GetBoxSizeProps {
size: CheckboxSize
}
function getBoxSize ({ size }: GetBoxSizeProps) => ({
'Small': css`
height: 16px;
width: 16px;
`,
'Large': css`
height: 20px;
width: 20px;
`,
}[size])
interface BoxProps {
size: CheckboxSize
}
/*
Just by placing the function here, it will be automatically
called by styled components and computed
*/
const Box = styled.div<BoxProps>`
${getBoxSize}
//other styles...
`
// usage
<Box size="Small" />
<Box size="Large" />
My problem with the old "if" and "switch" styles was that after some props, the styles logic often times grow up into something that's quite verbose and hard to mantain
I'm not clamming this pattern as my invention, but I wasn't able to find something similar anywhere!
Hope this help someone :)
Ps: if you use themes, is possible to pass the property to the function and keep it pure!
Upvotes: 0
Reputation: 3472
Another way to do this, if you want to add several css styles.
import css from "styled-jsx/css";
const Box = styled.div`
height:100px;
width:100px;
${props => props.Size === 'Small' && css`
height:20px;
width:20px;
`}
`
Upvotes: 24
Reputation: 4074
Actual if/else syntax may be used as well, what matters is, the returned value should be a string:
const DrawerItemTitle = styled.div<{isExpanded: boolean}>(props => {
const baseStyles = `
white-space: nowrap;
`;
const expandedStyles = baseStyles + `
opacity: 1;
transition: opacity 0.4s;
text-align: center;
flex-grow: 1;`
const notExpandedStyles = baseStyles + `
opacity: 0;
transition: opacity 0s;
position: absolute;
width: 100%;
`;
if(props.isExpanded) {
return expandedStyles;
}
else {
return notExpandedStyles;
}
);
Upvotes: 1
Reputation: 822
You can add interface in TypeScript and use booleans for default, small and large boxes. This example is for those who has more than two choices. In case of two choices, I would use arrow function and ? :
operators.
interface Sizes {
small?: boolean,
large?: boolean
}
// Box.
const Box = styled.div<Sizes>`
// p in this case means parameter which can have small and large booleans
height: ${p =>
(p.small && '25px') ||
(large && '100px') ||
'50px'
};
width: ${({Size}) =>
(small && '25px') ||
(large && '100px') ||
'50px'
};
`
// Render.
<Box/> // 50px - Normal.
<Box small/> // 25px - Small.
<Box large/> // 100px - Large.
Upvotes: 1
Reputation: 5628
You can use the elvis operator in something like this:
${(props) => props.someValue ? css` width: 20px;` : css` width: 100px; `}
Hope this helps someone looking into how to use logical operators in React styled components.
Upvotes: 3
Reputation: 4380
We can add the if-checks just like jsx
const Box = styled.div`
height:100px;
width:100px;
${props => props.Size === 'Small' && `
height:20px;
width:20px;
`}
`
Note: No need to include the word css
Upvotes: 2
Reputation: 5797
See Logical Operators
and Adapting based on props
for more info.
// Box.
const Box = styled.div`
height: ${({Size}) =>
Size === 'Small' && '25px' ||
Size === 'Large' && '100px' ||
'50px'
};
width: ${({Size}) =>
Size === 'Small' && '25px' ||
Size === 'Large' && '100px' ||
'50px'
};
`
// Render.
<Box/> // 50px - Normal.
<Box Size="Small"/> // 25px - Small.
<Box Size="Large"/> // 100px - Large.
Upvotes: 15
Reputation: 113
You can use the ternary operator
const Box = styled.div`
height: ${props => props.Size === 'Small' ? '20px' : '40px'}
width: ${props => props.Size === 'Small' ? '20px' : '40px'}
`
Reference: https://www.styled-components.com/docs/basics
Upvotes: 6