-
- So when we left off with our accordion component, we left it in a bit of a disarray. We have the capability of having multiple accordions,
-
but each accordion itself is an entire accordion component, which isn't what we want at all. We want one accordion with multiple items inside of it. So let's jump back into our code base and get this cleaned up.
-
So before we touch anything here, we can see that the main root of the problem is that we're binding the title and the item all together to the root accordion.
-
Whereas we kind of need two separate components going on here. We need the base accordion that adds in the base div and the x-data functionality. And then we need separate items to rest
-
inside of that accordion. So let's go and get rid of the duplicate accordion that we have there. And let's jump back into our accordion component. The collapsed item that we cut down to just one item
-
in the last lesson right here, we'll want to extract out of this component altogether. So we can create a new file underneath accordion
-
called item.edge, jump back into our index, and let's just cut that item out of there. Jump into our item and paste it in.
-
So now we have the item successfully separated from the root accordion functionality, but now we need some way to render each of those items inside of this base accordion,
-
because it needs to rest in between the starting and end div right here. The easiest way to do that is to just use a slot. So let's await slots,
-
and we can just use the main slot here. So we'll give this a save, and let's jump back into our accordion component page. At this point, we can go ahead and switch this accordion
-
to accordion.item to call the single item that we just extracted out of our base accordion. And then we can wrap this accordion item
-
in an @accordion base. And we'll just end it there, and then give this an indent. So now let's give this a save, jump back into our browser.
-
And now we have still one single accordion item that works just fine. Let's go ahead and give this accordion item here a duplication, jump back into our browser again.
-
And now we have a more appropriate base accordion with several accordion items inside of it. And as you can see, when you expand one, the other collapses automatically.
-
Now, if we give the page a refresh, you'll notice the same as the documentation, neither of them start as expanded. However, what if we want to support that within this accordion?
-
There's often times where you want the very first one to start out expanded to show exactly what this is, or maybe just provide additional context to that item. So let's go ahead and jump back
-
into our base accordion item, which is where the active accordion state is initially set. And we can have this be bound based off of the ID that we have.
-
However, if we take a quick look at the actual items that we have here, so let's go and give this a right click and inspect. And we can see that our x-data is being set
-
to the ID helper. So it's going to be some form of accordion with some suffix depending on what number of the accordion it is on the page. And if we have multiple accordions on the page,
-
it could be any number. Now it looks like my AlpineJS helper doesn't want to work right now. So what we'll do instead is jump back into our code base,
-
jump into our item, and we're using a explicit title, not a title prop. So I'm just going to go ahead and add a suffix,
-
a span X text of the ID so that we can see exactly what the ID is. We'll jump back in here and you can see it's accordion-1 and accordion-2.
-
Within AlpineJS's documentation for this ID magic property, if we jump down to the keyed ID section, we have the ability to add in an active key suffix
-
to the end of the generated ID that we can then use for identifying what the particular item is. So let's jump back into our accordion page,
-
jump back into our code base, and within our item as the second argument to the ID,
-
let's accept an additional prop as the ID itself. If this isn't provided, we'll want to default to an empty string so that we don't accidentally suffix all of our items with undefined.
-
And we're also going to want to stringify that as well. So we'll wrap that in the stringify utility. We'll give this a save. And now within our component page, we'll want to just apply an ID.
-
So I'm just going to do ID. And so that we're not doing hyphen-1 and hyphen-2 again, we'll just go ahead and do first so that we can designate that this is different. And again, here we'll do ID and we'll do second
-
so that it's not two. Give that a save, jump back into our browser. And now you can see it's accordion-1-1st and accordion-2-2nd. So now no matter how many accordions we have on the page,
-
we now have a distinct identifier that we can append onto the suffix of our accordion IDs to note which one is the active accordion.
-
So one thing to note here is that we only know the ID for the particular item at the item level. We don't know it at the base accordion level. So what we can do is at the ID level,
-
determine whether or not that is our active ID or pass in whether or not we want that to be the first expanded and then pass that up to the base accordion. So let's go ahead and jump back into our code base here
-
within our accordion item. I'm going to collapse this x-data down into a separate line with our class as well. I'm going to accept a prop. I'm going to wrap this in an if statement
-
that says whether or not this is our active item. So if it is active, then we'll go ahead and enter if. Let's do X init equals, and then we can simply set this directly on the parent
-
using the property name active accordion. So we'll go ahead and just do active accordion equals ID. We'll jump back down to our accordion page.
-
And now let's go ahead and set this first one as active to true, give that a save. And there we go. So now we start with that one there, expanded.
-
We can move this down here as well. And now our second one starts as expanded. So here we're really just making use of the fact that you can reach directly for your parent scope
-
via the child scope and mutate it directly without having to deal with events or anything of the sort. And if you need to do anything more advanced to that approach, you then have the ID suffixes
-
that you can then reach for as a secondary fallback to determine what the particular item is anywhere on the page. So for example, if we have multiple accordions,
-
give this a copy, give this a paste. You can see it goes accordion one, accordion two. And despite these being two different accordions all together, we then jumped down to accordion three and you can see it's back to first
-
because this is the specific suffix that we've supplied directly via our props. And then it goes on to accordion four.