Animate switching grid sizing - css

I have a project with React and Material UI.
I need some guidance on how to animate a grid item size change. The item is by default sm={3}, when the user hovers the item, this changes to sm={6}.
Here is my code:
<Grid
item
xs={this.state.hoverItem ? 6 : 3}
spacing={24}
onMouseEnter={this.handleItemHover}
onMouseLeave={this.handleItemHoverLeave}
>
<Paper
elevation={this.state.hoverItem ? 5 : 1}
className={classNames(
classes.card,
this.state.hoverItem && classes.cardHover
)}
>
</Paper>
</Grid>
And this is how I am doing my JSS:
card: {
...theme.mixins.gutters(),
paddingTop: theme.spacing.unit * 2,
paddingBottom: theme.spacing.unit * 2,
transition: theme.transitions.create("width", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen
})
},
cardHover: {
transition: theme.transitions.create("width", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
})
},
I thought this should animate it. However, the transitions are not doing anything.

Hi it was really an interesting problem of the day, I have tried to implement with simple transitions on hover. You can see here on codesandbox :
Animate Switching Grid Size
PS I have added your transition property as comment without giving width It worked great. You can report issue on Material-UI this is the right time.
Please let me know if you the issue still persists.

Related

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

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

React onMount animations

I'm trying to create an onMount animation using React (and Tailwind but it doesn't matter). My current implementation is this:
const Component = () => {
const [mounted, setMounted] = useState(false)
useEffect(() => {
setTimeout(() => {
setMounted(true)
}, 250)
}, [])
return(
<nav
className={classNames(
'flex justify-between items-center transform-gpu transition-transform duration-500',
mounted ? 'translate-x-0' : '-translate-x-full')}> Some nav components </nav>
)
}
Basically, this code timeouts the state's change, which indicates when the component is mounted, and then applies CSS translate to the element.
I'm thinking about optimizing the current solution but was wondering if there are any other ways to do an onMount animations. I appreciate any advice.
I can create a SandBox example if that's necessary.
Not sure if this precisely answers your question, but I personally like to use framer-motion for stuff like this. For example, if you want to apply an animated translateX once the component is mounted you could do something like this:
import { motion } from "framer-motion";
function Component() {
return (
<motion.nav
initial={{ translateX: 0 }}
animate={{ translateX: 100 }}
transition={{ ease: "easeOut", duration: 2 }}
>
Some components
</motion.nav>
);
}
See this codesandbox. (Click the refresh button within the codesandbox-browser to retrigger the animation or use the mount/unmount button)
So instead of <nav> just use <motion.nav> and specify the animation via the framer-motion props. You can still style that element with other classes as before if you need them in addition.
Note that an even shorter way of expressing that is using the x property, as shown here:
<motion.nav
animate={{ x: 100 }}
transition={{ ease: "easeOut", duration: 2 }}
>
Some components
</motion.nav>
You can control the animations directly as attributes or use Animate Presence to control an animation for the component when it is unmounted.

Can't achieve smooth transition between react router pages with Framer Motion

It is been over a week now, and I can't get it to work!, I am trying to make a transition between react pages components to have it scroll up and down for each page.however, on exit page the second page takes longer to be displayed and I can't figure out how to sync it so while the first page goes up, the second page start to goes up as well at the same time.
I am using AnimatePresence with exitBeforeEnter wrapping the app component.
Appreciate any help to the right directions.
Below are my variants for each component
const containerVariants = {
hidden: {
opacity: 0,
y: "-100vh",
},
visible: {
opacity: 1,
y: 0,
transition: {
type: "spring",
stiffness: 15,
damping: 10,
mass: 0.4,
staggerChildern: 0.4,
// opacity: { duration: 0.02 },
when: "beforeChildren",
},
},
exit: {
opacity: 0,
y: "-100vh",
zIndex: 0,
transition: {
type: "spring",
stiffness: 15,
opacity: { duration: 3 },
},
},
};
const Home = () => {
return (
<motion.div
variants={containerVariants}
initial="hidden"
animate="visible"
exit="exit"
>
< code goes here>
</motion.div>
You might already have it, but did you add the keys to pages inside <AnimatePresence? In my experience forgetting them caused issues with animating between pages/components.
Another issue I encountered was because of the key not being set on the immediate child of <AnimatePresence> (I had layout components between AnimatePresence and the pages).
Maybe you already have this all setup correctly, just to be sure :)
In my current project:
<AnimatePresence exitBeforeEnter>
<Component
{...pageProps}
key={router.route}
err={err}
/>
</AnimatePresence>

React-Native: Margin with percentage value

I'm trying to use percentage value for margin style attribute on my React Native project but it seems to reduce the height of one of my View component. If I replace percentage value by an absolute value, there is no more issue and it works fine. Did you try to use percentage value as margin in React Native ? Here is a little sample of code to reproduce this issue:
import React, { Component } from 'react';
import { Text, View, StyleSheet } from 'react-native';
export default class App extends Component {
render() {
return (
<View style={styles.scene}>
<View style={styles.card}>
<View style={styles.container}>
<Text>Hello World</Text>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
scene: {
backgroundColor: '#F9E8D5',
flex: 1,
justifyContent: 'flex-start',
alignItems: 'center',
flexDirection: 'column'
},
card: {
backgroundColor: '#E6D5C3',
flex: 0.2,
flexDirection: 'column',
marginTop: '20%' // Replace by 20
},
container: {
backgroundColor: '#FFFFFF',
flex: 1,
flexDirection: 'column',
justifyContent: 'center'
}
});
Thank you very much !
A component's height and width determine its size on the screen.
The simplest way to set the dimensions of a component is by adding a fixed width and height to style. All dimensions in React Native are unitless, and represent density-independent pixels.
Setting dimensions this way is common for components that should always render at exactly the same size, regardless of screen dimensions.
Use flex in a component's style to have the component expand and shrink dynamically based on available space. Normally you will use flex: 1.
The following references will be use for styling
https://facebook.github.io/react-native/docs/height-and-width.html
https://medium.com/the-react-native-log/tips-for-styling-your-react-native-apps-3f61608655eb
https://facebook.github.io/react-native/docs/layout-props.html#paddingtop
Use Dimensions to calculate to get the height and width of the screen.
var {height, width} = Dimensions.get('window');
To specify percentage by getting the screen size and convert it into percentage.
Sample example:
const { height } = Dimensions.get('window');
paddingTop: height * 0.1 // 10 percentage of the screen height
This is a real bug but Facebook does not care.
https://github.com/facebook/react-native/issues/19164

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