Utilizing CSS transitions to smoothly adjust the width of an element until it completely fills the container div in ReactJS

import React from 'react';
import PropTypes from 'prop-types';
import SearchIcon from '@material-ui/icons/Search';
import InputBase from '@material-ui/core/InputBase';
import { AccountCircle } from '@material-ui/icons';
import { withStyles, AppBar, Toolbar, Paper, Typography, IconButton } from '@material-ui/core';

const styles = (theme) => ({

    root: {
        borderRadius: theme.shape.borderRadius * 0.5,
        backgroundColor: theme.palette.primary.main,
        display: 'flex',
    },

    logo: {
        borderRadius: theme.shape.borderRadius * 0.5,
        backgroundColor: theme.palette.secondary.main,
        marginTop: theme.spacing.unit * 2,
        marginBottom: theme.spacing.unit * 2,
        marginLeft: theme.spacing.unit * 3,
        marginRight: theme.spacing.unit * 5,
        flex: 0.5,
    },

    logoFont: {
        color: theme.palette.primary.main,
        fontWeight: 'bolder',
        paddingTop: theme.spacing.unit * 0.5,
        paddingBottom: theme.spacing.unit * 0.5,
        paddingLeft: theme.spacing.unit * 2,
        paddingRight: theme.spacing.unit * 2,
    },

    headerPads: {
        paddingTop: theme.spacing.unit * 3,
        paddingBottom: theme.spacing.unit * 2,
        paddingRight: theme.spacing.unit * 10,
        paddingLeft: theme.spacing.unit * 10,
    },

    containerHorizontalAlignment: {
        display: 'flex',
        flexDirection: 'row',
        justifyContent: 'end',
        paddingTop: theme.spacing.unit,
        paddingBottom: theme.spacing.unit,
        flex: 10,
    },

    searchBar: {
        marginTop: theme.spacing.unit,
        marginBottom: theme.spacing.unit,
        marginLeft: theme.spacing.unit,
        marginRight: theme.spacing.unit * 5,
        borderRadius: theme.shape.borderRadius * 0.5,
        backgroundColor: theme.palette.secondary.main,
        width: 'auto',
        /* [theme.breakpoints.up('sm')]: {
            marginLeft: theme.spacing.unit,
            width: 'auto',
        }, */
        display: 'flex',
        flexDirection: 'row',
    },

    searchIcon: {
        color: theme.palette.primary.main,
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'space-between',
        marginLeft: 20,
        height: '100%',
        width: theme.spacing.unit * 7,
    },

    inputRoot: {
        color: theme.palette.primary.main,
        width: '100%',
    },

    inputInput: {
        transition: theme.transitions.create('width'),
        width: 'auto',
        [theme.breakpoints.up('sm')]: {
            width: '25%', //change it to 250(number)
            '&:focus': {
                width: '100%', //change it to 1000(number), it will work fine, but I need percentages. 
            },
        },
    },

    loginButtonContainer: {
         flex: 1,
    },

    loginButton: {
        justifyContent: 'right',
        marginTop: theme.spacing.unit * 0.5,
        color: theme.palette.secondary.main,
    },
});

function StylishSearchBar(props) {

    const { classes} = props;

    return (
        <div className={classes.headerPads}>
            <Paper square className={ classes.root }>
                    <div className={classes.logo}>
                        <Typography variant="h5" className={classes.logoFont}>
                            PlaceHolder
                        </Typography>
                    </div>
//Problematic div: the search bar
                    <div style={{border: '1px solid white'}} className={ classes.containerHorizontalAlignment }>
                        <div className={classes.searchBar}>
                            <div className={classes.searchIcon}>
                                <SearchIcon />
                            </div>
                            <InputBase 
                                placeholder='Search'
                                classes={{
                                    root: classes.inputRoot,
                                    input: classes.inputInput,
                                }}
                            />
                        </div>
                    </div>
                    <div className={classes.loginButton}>
                        <IconButton className={classes.loginButton}>
                            <AccountCircle fontSize='large'/>
                        </IconButton>
                    </div>
            </Paper>
        </div>
    );
}

StylishSearchBar.propTypes = {
    classes: PropTypes.object.isRequired,
}

export default withStyles(styles)(StylishSearchBar);

Issues:

  1. in styles.inputInput a transition is created using material-ui's theme.transition.create, however when passing percentages as widths, the component has a fixed width with no expansion or transitions.

  2. If the width of the searchBar exceeds its parent's capacity, it won't push the 'PlaceHolder' out of the Paper element, but instead will extend beyond the right boundary of the Paper. At the same time, it may also impact the position of the button at the end of the Paper.

The use of theme.create.transitions() from material-ui is incorporated here, but suggestions involving only CSS are welcome for resolving the mentioned issues.

Feel free to test it in the sandbox here, and maximize the browser window within the sandbox for optimal viewing.

Thank you

Answer №1

The main issue that was identified is related to the "searchBar" div, which was limiting the interpretation of "100%" for your input. To resolve this, it is recommended to utilize InputBase for the entire search input and include a startAdornment for the search icon:

      <div className={classes.searchBar}>
        <InputBase
          startAdornment={<SearchIcon />}
          placeholder="Search"
          classes={{
            root: classes.inputRoot,
            focused: classes.inputFocused
          }}
        />
      </div>

Furthermore, some adjustments need to be made in terms of styling by transferring certain styles from searchBar to inputRoot and from inputInput to inputRoot:

  searchBar: {
    width: "100%",
    display: "flex",
    flexDirection: "row"
  },
  inputRoot: {
    marginTop: theme.spacing.unit,
    marginBottom: theme.spacing.unit,
    marginLeft: theme.spacing.unit,
    marginRight: theme.spacing.unit * 5,
    borderRadius: theme.shape.borderRadius * 0.5,
    backgroundColor: theme.palette.secondary.main,
    color: theme.palette.primary.main,
    transition: theme.transitions.create("width"),
    width: "auto",
    [theme.breakpoints.up("sm")]: {
      width: "25%" //update to 250(number)
    },
    "&$inputFocused": {
      [theme.breakpoints.up("sm")]: {
        width: "100%" //adjust to 1000(number) if needed, preferring percentages.
      }
    }
  },
  inputFocused: {},

You can view the updated sandbox with these modifications here:

https://codesandbox.io/s/4x967yk7z7?fontsize=14

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieve the JSON element from a Backbone model by its unique identifier

I'm diving into Backbone for the first time and I'm facing difficulties making it work smoothly with a JSON data file. Here's how my model looks: window.Test = Backbone.Model.extend({ defaults: { id: null, name: null, }, url: f ...

How to automatically reset a form after submission in React using Ant Design?

When using the antd template for form design, I encountered an issue where form input values were not getting cleared after submission. I attempted to use this.props.form.resetFields(), but it resulted in the following error: Unhandled Rejection (TypeErro ...

Align the dimensions of the table to match with the background image in a proportional

Seeking a contemporary method to match a table with a background image, ensuring all content scales proportionally. Mobile visibility is not a concern for this specific project. Using Wordpress with a starter bootstrap theme. Check out the code on jsfidd ...

Choose an option from a Material UI Listbox with Autocomplete feature using Cypress

This specific element is crucial for the functionality of the application. <input aria-invalid="false" autocomplete="off" placeholder="Category" type="text" class="MuiOutlinedInput-input MuiInputBase-input ...

Dealing with multiple ajax requests while utilizing a single fail callback

Looking for a solution: I have two arrays containing deferreds. In order to detect failures in the outer or inner 'when' statements, I currently need to use double 'fail' callbacks. Is there a way to consolidate errors from the inner &a ...

Steps to insert a new row for a grid item using material-ui

When it comes to breaking a line of grid item like this, the image shown below illustrates how the rest space of the grid should be empty. https://i.stack.imgur.com/pvSwo.png <Grid container spacing={3} <Grid item xs={12}> "Grid Item xs ...

Difficulty in properly updating React state within setInterval functions

I have a button in the user interface and when the OnClick event handler is triggered, a setInterval timer needs to run. Within this interval timer, I am checking for a specific condition. If the condition is met, I update the state accordingly. However, I ...

Node express not serving Gzip file properly

I'm having trouble serving a gzipped file using node/express for a react app. Despite my efforts, I keep receiving the large 1.2MB file instead of the expected gzipped 300kb file. Below is the code snippet for the express route handler that I am curre ...

Tips for resolving asynchronous s3 resolver uploads using Node.js and GraphQL

My goal is to upload an image and then save the link to a user in the database. Below is my GraphQL resolver implementation: resolve: async (_root, args, { user, prisma }) => { .... const params = { Bucket: s3BucketName, ...

grabbing data from different domains using jQuery

I attempted to implement cross-domain AJAX examples, but unfortunately, it did not function as expected. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr"> <head> <meta http-equiv="Content-Type" content="text/ht ...

Creating a custom PHP webpage and integrating it with a WordPress theme

I'm looking to develop a unique php and javascript page that is integrated with my existing Wordpress theme. Can anyone provide guidance on how to achieve this? Appreciate the help! ...

Alert: It is invalid for an <a> element to be nested inside another <a> element according to validateDOMNesting

I've been experimenting with using react-router in conjunction with reactstrap and create-react-app. While setting up the routing within my application, I encountered a need to utilize state for the reactstrap components. To achieve this, I converted ...

Executing a file upload using ng-click="upload('files')" within Selenium Webdriver

Is it possible to automate a file upload when the HTML code does not include an < input type='file' > instead, uses a link <a ng-click="upload('files')"> File Upload </a> Clicking this link opens a file selector f ...

Generate PDF Files Using Ajax

Currently, I am utilizing FPDF to generate my report. $pdf = new Report('P','mm','A4', $_POST); $pdf->AddPage(); $pdf->Output('file.pdf','I'); Furthermore, I am employing ajax to send a request to t ...

Challenges compiling 'vue-loader' in Webpack caused by '@vue/compiler-sfc' issues

The Challenge Embarking on the development of a new application, we decided to implement a GULP and Webpack pipeline for compiling SCSS, Vue 3, and Typescript files. However, my recent endeavors have been consumed by a perplexing dilemma. Every time I add ...

Adding a pair of labelled angled columns in a container that spans the full width is a breeze

I'm in pursuit of this: https://i.sstatic.net/HYbC1.jpg What I currently possess is: <div class="row slantrow"> <div class="row slant-inner"> <div class="col-md-6 slant-left"> <p>text</p> ...

The 'mat-table' component is triggering an error indicating that the 'dataSource' attribute is unrecognized in the table

Recently, I have been diving into the world of Material Library for Angular. Working with Angular version 15.0.1 and Material version 15.0.1, I decided to include a mat-table in my form (schedule.allocator.component.html): https://i.stack.imgur.com/c7bsO. ...

What is the process of transforming the content of a file into an array using JavaScript?

I have a file named "temperatures.txt" that contains the following text: 22, 21, 23 Is there a way to transfer the contents of this file into a JavaScript array? const weatherData = [22, 21, 23]; ...

Is there a way for me to store the retrieved information from an API into a global variable using Node.js?

function request2API(option){ const XMLHttpRequest = require('xhr2');//Cargar módulo para solicitudes xhr2 const request = new XMLHttpRequest(); request.open('GET', urlStart + ChList[option].videosList + keyPrefix + key); request. ...

Tips for integrating styled components with Material UI icons

Is there a way to style the override "! if it's not working?" I couldn't find any solutions online. import React from 'react'; import styled from 'styled-components'; import SearchIcon from '@material-ui/icons ...