Building Collapsible Categories with Rotating Arrow Icons

Sam Selikoff
InstructorSam Selikoff
Share this video with your friends

Social Share Links

Send Tweet
Published 3 years ago
Updated 2 years ago

Use some simple React state to toggle categories open and closed. Filter out channels based on their unread and closed state. Use Tailwind's transform and transition utilities to animate a category's arrow to the right.

The code for this lesson is divided into two sections, with this you can see the progress on the code.

  1. Begin
  2. End

Instructor: [0:00] To build out this category toggling behavior, we'll see that there's actually two elements. First, when we close a category, we'll see that the arrow rotates to the right. Then second, we'll see that all red channels are no longer visible.

[0:15] To build this out in our clone, we first need to add some state. Let's grab the useState hook from React. We'll start out with an empty array here and we'll call this closed categories. Then we'll use set closed categories as the setter.

[0:37] Here is the button element that contains each category label right here. When we click on it, we want to run a new function we'll call toggle category, and we'll pass in the category ID. This is going to come from our loop right here.

[0:57] Let's go ahead and implement this toggle category function, right up here. This takes in a category ID.

[1:08] This will update the closed categories array right here. We'll call set closed categories. Instead of just passing in the new array, we want to use the function version here since the new array depends on the current value.

[1:23] We can pass in closed categories, and then an arrow function, and now we can write our logic. If the closed categories includes the category ID that were passing in right here, then we want to remove it. We'll return closed categories.filter.

[1:43] We'll only return categories whose ID is not equal to the category ID we passed in. Otherwise, we want to add this category ID to the array. We'll create a new array and we'll splat in all of the existing categories. Then we'll append our new category ID to the end.

[2:07] That should be it for the logic. Now we can actually use this array to update our UI. We have our arrow icon right here. Tailwind comes with some transform utilities we can use to rotate the arrow. We have some low numbers here, but then we can see, we have 90.

[2:24] That points the arrow to the left, but we also have -90 to point it to the right. If we look at Discord, whenever we close a group, we see that the arrow points to the right. We should just be able to make this dynamic by turning it into an expression. Then we'll just add a tertiary right here.

[2:46] If closed categories includes this category ID, which again is coming from this loop right here, we'll apply some classes. Otherwise, we'll apply some others. We'll just move this rotate 90 right here. With any luck, whenever we click a category, we see that we toggle the arrow.

[3:10] To get that transition in here, we can just drop a transition class, and we can see that rotates nicely. It looks like it's a little bit slower over here in Discord, so let's drop this duration down to 200. That looks pretty nice.

[3:32] Finally, let's go ahead and filter out the channels if we are viewing a closed category. We can do that right down here where we're looping over the channels. Right before we loop, let's add a filter here for each channel. Here's where we can write our logic.

[3:49] If we look over in Discord, we always want to show a channel if it's unread or if the category is open. Otherwise, we'll filter it out. First, we can see if the category is open. We're still inside the loop for this category, so we can say, closed categories includes the category ID.

[4:12] If this is true, the category is closed. If we invert it, we'll say that the category is open. Again, in that case, we always want to return the channel or we want to return it if the channel is unread. We should be able to say, return category is open or channel is unread.

[4:33] Let's check it out. If we close this category, we see we hide the read channels. That's pretty neat. These transform utilities, like rotate and scale, are really nice especially if you have animations on icons. You don't want to be swapping icons.

[4:49] You just want to be applying these handy little utilities to a single icon to achieve this result.

~ 25 minutes ago

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today