Spin an icon when the Button it is inside of is clicked

I am currently using a Material-UI button with the following code:

<Button
  disableFocusRipple={true}
  disableRipple={true}
  color="inherit"
  onClick={openBlogMenu}
  className={classes.blogButtonStyle}
>
  <LibraryBooksIcon />
  Blog
  {!blogMenu && <KeyboardArrowDownIcon />}
  {blogMenu && <KeyboardArrowUpIcon />}
</Button>
<BlogDropDown pageURL={pageURL} />

In this setup, the openBlogMenu function alters the state of blogMenu in Redux which controls the visibility of the BlogDropDown. Additionally, I use this state to toggle between two arrow icons, KeyboardArrowDownIcon and KeyboardArrowUpIcon.

While this system is functioning well, I want to enhance it by eliminating the need for the KeyboardArrowUpIcon entirely. Instead, I would like the KeyboardArrowDownIcon to rotate 180 degrees when clicked.

I understand that one way to achieve this is by adding a pseudo-class such as :active or :focus to the icon element. However, this method only rotates the icon itself upon click rather than the entire button.

An alternative solution could be dynamically applying a transform attribute (transform: rotate(180deg);) to the icon's CSS within the click handler. Nevertheless, this approach might lack smooth animation during transition.

Any suggestions on how to implement this?

P.S.: To better visualize my objective, you can refer to the menu option More on

Answer №1

You have the option to use CSS solely for flipping the icon without affecting the button. This is the solution that has worked perfectly well for me:

const customStyles = makeStyles (theme => ({
    open : {
         transform: "scaleX(1)",
    },
    close: {
         transform: "scaleX(-1)",
    },
}));

export default function Example() {
    const classes = customStyles();
    const toggleDrawer = () => { setOpen(!open) };
    const [open, setOpen] = React.useState(false);
    return (
        <IconButton aria-label="expand drawer" onClick={toggleDrawer} edge="left">
            <MenuOpenRoundedIcon className={clsx(!open && classes.close, open && classes.open)}/>
        </IconButton>
    )
}

Utilize clsx (or any similar conditional class selector) to determine when the icon should be flipped based on the button's state. In this scenario, I utilize a state hook, open, toggling its boolean value upon click. Subsequently, I use clsx to make a decision depending on the value of open, assigning the appropriate class to the icon in order to flip it correctly.

If you wish to flip vertically, you can apply scaleY instead.

Below is the code I crafted within the code sandbox featuring examples with both Button and IconButton (vertical and horizontal): https://codesandbox.io/s/festive-maxwell-3kcge?file=/src/App.js

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

What is the best way to cancel a request within an HTTP-interceptor?

Within an application, I have established the following URL structure for the API: // public public/url-xyz // private dashboard/url-xyz To avoid unnecessary requests, what is the most effective method for canceling a request? My current approach involv ...

default selection in AngularJS select box determined by database ID

Here is the scenario: ... <select ng-model="customer" ng-options="c.name for c in customers"> <option value="">-- choose customer --</option> </select> .... In my controller: $scope.customers = [ {"id":4,"name":"aaaa", ...

Manipulating data rows in a table using jquery

I have a button called #add that, when clicked, adds a new row to a table. The last cell of the newly inserted row contains a delete icon that, when clicked, should remove the entire row. I thought I had everything set up correctly, but for some reason, c ...

Encountering a problem while submitting the form - there appears to be an unexpected "s" token in the

This is my first attempt at creating a contact form using Node.js with Nodemailer. The goal is to have the form submitted through the website and sent directly to your inbox. Here is a snippet of my app.js file in the public folder: const form = document. ...

How to address additional attributes received from the server in Next.JS

Encountering an error while trying to render a canvas with specified height and width within a child component in a NextJs app. The issue arises when attempting to integrate this mouse effect into my NextJS application. Everything functions correctly until ...

Unable to utilize the .keyCode method within a query selector

Trying to utilize .keyCode in JavaScript to identify a pressed key, but the console consistently displays null after each key press. Below is the relevant CSS code: <audio data-key="65" src="sounds\crash.mp3"></audio> ...

Tips for creating a tabbed form that easily glides between tabs

After coming across this form design, I am inspired to create something similar with a twist. Instead of having each tab display all content at once, I want the tabs to scroll from right to left, giving it a more animated effect. Can someone offer suggesti ...

Utilizing ng-model to control the visibility of a label or anchor tag

Here is the code snippet I am working with: <div class="tabs DeliveryRightDiv"> <label class="selected"><a>One</a></label> <label> <a>Two</a> </label> <label> ...

Looking to enhance my current workaround for utilizing Google Spreadsheet's ImportRange feature

I recently joined this forum and have just started using Google Scripts. I don't have any prior experience with JavaScript or programming languages, but had to learn them when I decided to use Google Apps as the main platform for my small business. M ...

NextJS is throwing an error stating that the element type is invalid. It was expecting either a string for built-in components or a class/function for composite components, but instead received an object

I encountered the following issue: Error - Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but received an object. Here's the code from my \components\LayoutWrapper.js: i ...

Using jQuery or JavaScript, extract JSON data from Yahoo Pipes

Here is the JSON format that I receive from Yahoo pipes: {"count":3, "value":{ "title":"Freak count feed", "description":"Pipes Output", "link":"http:\/\/pipes.yahoo.com\/pipes\/pipe.info?_id=565sdf6as5d4fas ...

The button's color cannot be modified due to a malfunctioning event script that is not

Seeking an explanation for why my current implementation isn't working. I'm attempting to create a quiz with a multiple choice section where the correct answer turns green when clicked, and incorrect answers turn red. Despite validating the code ...

The functionality of app.get('') is malfunctioning in Node.js when it comes to handling query parameters

I'm currently working on updating my conversation application to handle new routes that accept parameters and pass them along to the client side. However, I'm facing an issue with the .get() method not rendering the HTML as expected. 'use s ...

I am currently attempting to generate a chart that displays information on countries utilizing the restcountries API. Despite being a beginner in this area, I have encountered some challenges and am seeking guidance

I'm struggling to display detailed information for each country separately. Whenever I try to loop through the data, all the contents end up getting merged into a single cell. What can I do to achieve the desired result? https://i.stack.imgur.com/dZS ...

Automatically reset the form after submission in CakePHP 1.3

I've encountered an issue with my report form that is linked multiple times on a page to a jQuery dialog box. To prevent cross-posting, I added a random string to the submission process. After successfully submitting the form on a single page access, ...

Generating interactive cards using an array

In an attempt to showcase information for three separate months using a single component, I am creating cards titled "Month 1," "Month 2," and "Month 3." Each card contains a table, and I am aiming to add headers to each card based on an array of titles. ...

Adding a PHP file into an HTML page using JavaScript include

Recently, I was assigned to collaborate with a third-party vendor who displays movie times on their platform. We were given the opportunity to co-brand our website on their platform by creating a wrapper for our site. This wrapper would allow the movie tim ...

Strategies for streamlining repetitive code within a closure in Angularjs

We are currently utilizing Angularjs 1x and I am in the process of refactoring some repetitive code within an Angularjs filter. However, I am facing challenges in getting it to function correctly. It should be a straightforward task. Our standard approach ...

My Node.Js app refuses to run using my computer's IP address, yet works perfectly with localhost

My Node.js application is set up to listen on port 5050 of my machine: Visiting http://localhost:5050/myapp loads the app successfully. I am using the Express framework, so my listening framework looks like this: var server = app.listen(5050, '0.0.0 ...

Verify if data already exists in an HTML table column using JavaScript

As a beginner in web programming, I am currently trying to dynamically add data to a table. But before inserting the data into the table, my requirement is to first verify if the data already exists in a specific column, such as the name column. function ...