Search code examples
reactjscss-transitionsreact-bootstrap

How to add a smooth sliding transition effect to a react-bootstrap based Column component?


To summarize the problem, I am trying to work through a component that has 2 columns (react-bootstrap Column component). The left container being collapsible and the right always there. On a click of a button, I will toggle show/hide on the left column. It works fine but the behavior is rugged. Whereas, I want to add a transition effect to achieve a smoother slide behavior.

More info...I have a page where I want to display products and filter the products based on different properties such as cost, size, category etc. So, I use a container inside and got 2 columns inside it a row.

Problem: Transition not so smooth...

my sample

Something like this in the code below,

import React, { Component } from 'react';
import { ProductsViewFilter } from '../../Controls/ProductsViewFilter/ProductsViewFilter';
import { ProductsView } from '../../Controls/ProductsView/ProductsView';
import { Container, Row, Col, Collapse } from 'react-bootstrap';
import './ProductsViewContainer.css';

export class ProductsViewContainer extends Component {

  constructor(props) {
    super(props);
    this.state = {
      filterExpanded: false
    }
  }

  render() {
    return (
      <Container className='products-view-filter-container'>
        <Row>
          <Collapse in={this.state.filterExpanded}>
            <Col sm={2} className={this.state.filterExpanded ? 'products-view-filter products-view-filter-transition-slide-in' : 'products-view-filter products-view-filter-transition-slide-out'}>
              <ProductsViewFilter></ProductsViewFilter>
            </Col>
          </Collapse>
          <Col className='products-view-container-productsview'>
            <div className='slider-icon-div' >
              <img className='slider-icon' src='/images/icons/slider.svg'
                onClick={(e) => { e.preventDefault(); this.setState({ filterExpanded: !this.state.filterExpanded }); }} />
            </div>
            <ProductsView></ProductsView>
          </Col>
        </Row>
      </Container>);
  }
}

.products-view-filter-container
{
  max-width: 100% !important;
}

.products-view-filter
{
  background-color: wheat;
  transform: translateX(-150px);
  transition: transform 400ms ease-in;
}

.products-view-filter-transition-enter
{
  transform: scale(0.8);
  opacity: 0;
}

.products-view-filter-transition-enter-active 
{
  opacity: 1;
  transform: translateX(0);
  transition: opacity 300ms, transform 300ms;
}

.products-view-filter-transition-exit
{
  opacity: 1;
}

.products-view-filter-transition-exit-active
{
  opacity: 0;
  transform: scale(0.9);
  transition: opacity 300ms, transform 300ms;
}

.products-view-filter-transition-slide-in {
  transform: translateX(0);
}

.products-view-filter-transition-slide-out {
  transform: translateX(-100%);
}

.products-view-container-productsview
{
  background-color: lavender;
}

.slider-icon
{
  height: 1.5rem;
}

.slider-icon:hover
{
  cursor: pointer;
}

.slider-icon-div
{
  margin-top: 15px;
  text-align: left;
}

I would like to see the behavior as something like https://codepen.io/bjornholdt/pen/MpXmmL/.

I know this is easily achievable by using bunch of pure divs. But, my desire is to use bootstrap components as it responsive in mobile devices.

Any advice, suggestion as to how to achieve sticking to Col and Row components with a smooth transitions will be really helpful.


Solution

  • This might be too late, but in case anyone else has this issue... I have not tested this myself, but try what the docs (https://react-bootstrap.netlify.app/docs/utilities/transitions/) suggest.

    ... Collapse# Add a collapse toggle animation to an element or component.

    Smooth animations If you're noticing choppy animations, and the component that's being collapsed has non-zero margin or padding, try wrapping the contents of your inside a node with no margin or padding, like the in the example below. This will allow the height to be computed properly, so the animation can proceed smoothly. ...