Chakra UI: how to make sx property apply only to selected breakpoints - css

What would be the best (I'd be interested even in 2nd best) approach to make a component define some sx style that applies only starting from particular breakpoint?
<MyComponent
transition="1s"
sx={{
...
transform: 'translateY(-100%)',
...
}}
>
{componentContent}
</MyComponent>
In the example above everything inside sx should be applied only to lg+ breakpoints (targeting Desktop) and nothing should be applied to lower breakpoints (mobile/tablet).
As far as I understand there is a way around my issue with using useBreakpointValue to manually check whether the breakpoint is the one where i apply the style or not, but I'm wondering if there is a better approach to achieve the result

Here are some options:
https://codesandbox.io/s/sx-breakpoint-mdsjhz?file=/src/index.js
<Box
width="100px"
height="100px"
sx={{
// one-liner
// https://chakra-ui.com/docs/styled-system/responsive-styles
bg: { base: "pink.200", md: "green.200" },
// equivalent array syntax
// bg: ["pink.200", null, "green.200"],
// alternatively, multiple properties in a single condition
// https://chakra-ui.com/docs/styled-system/the-sx-prop#custom-media-queries
"#media screen and (min-width: 768px)": {
borderWidth: 16,
borderColor: "purple.500"
}
}}
/>
https://chakra-ui.com/docs/styled-system/responsive-styles
https://chakra-ui.com/docs/styled-system/the-sx-prop#custom-media-queries

Related

How can a prop value be used in an Stitches js component?

How to pass a prop value into a Stitchesjs component and use it in the component definition?
This is a common pattern in styled-components. In Stitches, however, I can't seem to find a way. Take this component for example:
const Spacer = styled('div', {
'16': {marginBottom: '$16'},
variants: {
size: {
'20': {marginBottom: '$20'}
}
}
});
Instead of creating 10 variants, I want to pass the amount trough a prop:
<Spacer size={'30px'} />
or even better:
<Spacer size={'$sizes$3'} />
How can I use this value so that the marginBottom matches whatever I give it?
Take a look at https://stitches.dev/docs/utils.
And then you can use like this:
<div css={{ mb: '$40' }} />
I was looking for this answer and tried a few different ways.
The easiest way for me turned out to be locally scoped theme-tokens.
So your styled component would look like this:
const Spacer = styled('div', {
marginBottom: '$$marginSize',
});
And then pass the locally scoped token into the css prop:
<Spacer css={{ $$marginSize: '$sizes$3' }} />
There was a discussion on Stitches Github about the possibility to pass dynamic values as property.
But the goal of stitches is to have the smallest runTime possible, so it was not implemented !
Github PR stitches
When you need to use a JSX variable in stitches that can be any value, one solution would be to use CSS variables;
All stitches elements get the css property, and you can pass new properties through it!
Styled component:
export const Box = styled('div', {
marginTop: 'var(--margin-top)',
backgroundColor: 'red',
width: '200px',
height: '200px',
})
Component:
export function Hero({props = 200 }) {
const variableExample = `${props}px`
return (
<>
<Box css={{ '--margin-top': '10px' }} />
<Box css={{ '--margin-top': '150px' }} />
<Box css={{ '--margin-top': variableExample }} />
</>
)
}
By far the best solution that has worked for me for this very problem. simplifies the code and is better to maintain later!

How to use #media to change width in prop styled components

I am not sure if what they called but I have a component which takes its style as an object with its props.
const PricingSection = ({
secDesc,
}) => {
return (
<Text
{...secDesc}
content={intl.formatMessage({ id: 'packages.description' })}
/>
);
};
PricingSection.propTypes = {
secDesc: PropTypes.object
};
PricingSection.defaultProps = {
secDesc: {
width: '50%',
m: 'auto',
textAlign: 'center',
pt: '20px',
color: '#6a7a8d',
lineHeight: '1.5rem',
},
}
I want to apply different witdh for mobile devices. I know how to use #media tag in css but I dont know where to write #media in this component or how achieve what I want.
Instead of passing style object, it would be better if you apply a class to the component for easy maintenance. It'll also solve your problem for width for different size devices as you can add media query for the class in its css file.
Another suggestion would be to use styled-components. They provide great support for adding media queries inside the component file.
Refer:styled-components
you can use 'react-device-detect' and pass the different width from parent component like this:
enter code here
import isMobile from 'react-device-detect'
secDesc: {
width: isMobile ? '50%' : 'your value',
m: 'auto',
textAlign: 'center',
pt: '20px',
color: '#6a7a8d',
lineHeight: '1.5rem',
}
< PricingSection
secDesc={secDesc}
/>

Apply style to ButtonBase in a Tab component

I am trying to figure out Material UI style overriding with a nested component. Say I want to increase bottom border height on a active Tab. This border is applied by the underlying ButtonBase.
Here is the style definition:
const useStyles = makeStyles(theme => ({
root: {
// an example brutal overriding, not clean, I'd like a better approach for the button
"& .MuiSvgIcon-root": {
marginRight: "8px"
}
},
// override Tab
tabWrapper: {
flexDirection: "row"
},
tabSelected: {
color: theme.palette.primary.main
},
tabLabelIcon: theme.mixins.toolbar, // same minHeight than toolbar
// TODO override buttonBase ???
// ...
}));
An example usage:
<Tab
value="/"
classes={{
wrapper: classes.tabWrapper,
selected: classes.tabSelected,
labelIcon: classes.tabLabelIcon
}}
icon={
<React.Fragment>
<DashboardIcon />
</React.Fragment>
}
label="Home"
// TODO: is this the expected syntax? TypeScript is not happy with this prop...
buttonBaseProps={{ classes: {} }}
/>
I have no idea how to define the ButtonBase classes in this example.
How should I define my props to override the ButtonBase style?
Edit: doc is here https://material-ui.com/api/tab/, the last section describe the inheritance process but the documentation is very terse.
Edit 2: the example use case is bad as you should override ".MuiTabs-indicator" to increase the bottom border height (it's actually an additional span not a border) but the question stands. Imagine that I want to change the ButtonBase background-color for example.
So as it turns out, There is no separate ButtonBase component inside the Tab component. So you won't find prop called buttonBaseProps. The tab itself is rendered as the button component.
Whatever style you wanna pass, pass it to the root inside classes. See below
<Tab classes={{
root: classes.customButtonBaseRoot,
wrapper: classes.tabWrapper,
selected: classes.tabSelected,
labelIcon: classes.tabLabelIcon
}}
/>
https://codesandbox.io/s/apply-style-to-buttonbase-in-a-tab-component-izgj5

Media query in jss not responive

I am using style props in my react element with #media query. But for some reason it isn't responding. I am using JSS. Here is my code
const style = {
usernameConatiner: {
display: "flex",
alignItems: "center",
backgroundColor: "red"
},
"#media screen and minWidth(32em)": {
usernameConatiner: {
backgroundColor: "blue"
}
}
}
There is obviously a whole bunch of other css rules in the middle. I have also tried to nest the media query which isn't working either.
It is rendered in the following way
<div style={styles.usernameConatiner} />
Am I missing something very obvious here?
It's happening because your media query is not being defined correctly on the styles object.
The correct media query would be #media screen and (min-width: 32em), notice min-width: 32em is inside the parenthesis, and also notice that is written as min-width (separated with a dash) instead of minWidth (camelCase)
Check it working on CodePen: https://codepen.io/anon/pen/yGEXox
To summarize, your styles object should look like this:
const style = {
usernameContainer: {
display: 'flex',
alignItems: 'center',
backgroundColor: 'red'
},
'#media screen and (min-width: 32em)': {
usernameContainer: {
backgroundColor: "blue"
}
}
}
Hope this works for you.
As you already are in JS and want to write a style that depends on width, wouldn't be easier to get the window.width and define your style objects accordingly?
Always remembering you may use window.addEventListener('resize', this.updateWindowWidth); to handle the changes.
Two things here.
Your media query syntax is not correct.
You can't use media queries / pseudo selectors like &:hover, &:disabled and so on in JSS (CSS in JS) directly. To do this, you must install a thrid party package Radium https://www.npmjs.com/package/radium
Installation - npm install --save radium
How to use it?
Once you install radium, your entire app should be enclosed with <StyleRoot/> which is a named export from radium. The best place to do this is in index.js.
index.js
import { StyleRoot } from "radium";
ReactDOM.render(
<StyleRoot>
<App />
</StyleRoot>,
document.getElementById("root")
);
You now need to wrap the component that you are using your media queries in with Radium like this. This can be done for both class and functional components.
MyComponent.js
import Radium from 'radium'
function MyComponent(){
const myStyle = {
color: 'blue',
backgroundColor : 'red',
// media query
"#media (max-width: 1100px)": {
color:'orange',
backgoundColor : 'black'
},
}
return (
<p style = {myStyle}>Enter your text here</p>
)
}
export default Radium(MyComponent);

How to style React Native <CheckBox> component?

Is it possible to style the React Native CheckBox component?
There is no style property listed here: https://facebook.github.io/react-native/docs/checkbox.html
I put an invalid style property on it, and the RN warning message that popped up told me all the valid CSS properties, but none of them did anything beneficial towards styling.
The component looks decent, but I want to change it from that teal color to a brand color.
Is it possible?
These properties are not working but are listed as valid style props for CheckBox:
{
height: 50, // changes the hitspace but not the checkbox itself
width: 50,
borderWidth: 1, // does nothing
backgroundColor: 'red', // makes the area around and inside the checkbox red
borderColor: 'green', // does nothing
borderStyle: 'dotted' // does nothing
}
I don't understand why it even exists if everyone just makes their own checkbox. If I did that, I wouldn't really have any use for because all it gives is
value={this.state.rememberMe}
onValueChange={() => this.toggleRememberMe()}
unless there is something magic it does under the hood. It has a decent onChange animation, but that would be deprecated instantly when I make my own and use something like <TouchableHighlight or Opacity> wrapped around an on/off image or <View>.
I can't find any info on Google except hundreds of custom checkboxes. It's actually really hard to search around them.
You can use https://github.com/react-native-community/react-native-checkbox
Android: you can use tintColors.
import CheckBox from '#react-native-community/checkbox';
.
.
.
<CheckBox
value={option.item.selected}
onValueChange={() => {}}
tintColors={{ true: '#F15927', false: 'black' }}
/>
Transform can be used to change CheckBox size.
<CheckBox
style={{ transform: [{ scaleX: 0.8 }, { scaleY: 0.8 }] }}
/>
checkbox examples
https://github.com/react-native-checkbox/react-native-checkbox
No I couldn't find a way, but wrapping it in a View was one option:
<View style={{
position: 'absolute',
right: 0,
width: 50,
height: 50,
margin: 10,
zIndex: 100,
}}>
<Checkbox
status={i === index ? 'checked' : 'unchecked'}
className=""
/>
</View>
Short answer is you simply can't. React Native uses the native Android Checkbox component, and the only customization you get to do is changing the tint colors, as seen in the react-native-checkbox community project. This prop is undocumented in the official React Native docs.
Additionally, here's the TypeScript definition for this component: AndroidCheckBoxNativeComponent.js. Notice how the only props relayed to the native component are onChange, onValueChange, testID, on, enabled and tintColors.
Yes, you can, i recommend you that use react native elements, and with this library you have 2 options, checkedColor and uncheckedColor, by default in checkedColor is green, but you can change it to what you want, for example, checkedColor={"#fff"} or checkedColor="#fff" try them, it apply for 2 options, good luck!
For IOS use onTintColor and pass the value in string onTintColor={'red'}
<CheckBox
onTintColor={Color.theme}
onCheckColor={Color.theme}
value={isSelected}
onValueChange={setSelection}
style={Style OBJECT}
/>
import CheckBox from '#react-native-community/checkbox';
const Checkbox = (props) => {
// const [isSelected, setSelection] = useState(false);
const [toggleCheckBox, setToggleCheckBox] = useState(false)
return (
<View style={[useTailwind``, styles.container]}>
<View style={styles.checkboxContainer}>
<CheckBox
disabled={false}
value={toggleCheckBox}
tintColors={{true: '#368098'}}
onCheckColor={'#6F763F'}
onValueChange={(newValue) => setToggleCheckBox(newValue)}
/>
<Text style={[useTailwind`font-normal text-base font-sans`, styles.label]}>{props.value}</Text>
</View>
{/* <Text>Is CheckBox selected: {isSelected ? "👍" : "👎"}</Text> */}
</View>
);
};
its possible now..
just simply gives tint color of the same color of background

Resources