Multi-Style Tailwind Components 23 exercises

Implementing the getStyles Function

Let's create a getStatus function to handle the calendar day statuses in the app.

We'll define the function like so:

const getStatus: () => Status = () => { }

We know that there are five possible statuses: SELECTED, DISABLED, VACANCY, NO_VACANCY, and TODAY_NO_VACANCY.

Loading solution


Instructor: 0:00 Let's figure out these calendar day statuses, shall we? We got the list of statuses here, and let me get rid of this comment here. I like the idea of creating a function called getStatus. Here, we want to return one of the status variants. I can type this function to be a function that returns a status.

0:23 We get the squiggles, but if I was to return -- we should have autocomplete, yep, check this out -- if I was to return one of these statuses, the type would be satisfied. If we had a typo, it would not be happy. That's perfect. Let's delete all this.

0:39 We want this getStatus function to return each of the possible statuses based on different conditions. The philosophy here is to start by short-circuiting the system as early as possible. Let's go with the low-hanging fruits to begin with.

0:54 If we go and have a look at what we were doing before, you could see that we were checking this isSelected to determine if the dynamicClasses should have the selected style. Same with isDisabled. These, if I scroll up, come from this React area's useCalendarCell hook.

1:11 You can see here with this structuring, isSelected and isDisabled from this useCalendarCell call, and that's where the calendar logic state is handled to determine if a day is selected, or if it's disabled, meaning that it's in the past, before today, or after the select range, which we have set to 6 months. Anything after 6 months from today is also disabled.

1:35 These are going to make our job easy for the first two conditions of our getStatus function. We can immediately check if isSelected, in that case, we can return "selected." Boom, that's one condition down. We can do the same with disabled. If isDisabled, return "disabled." We're already catering for these two scenarios, so we have these three left.

2:01 If I look at these three, two of them mention "no vacancy." To me, that tells me that the third one, "vacancy," can be determined quite easily. Let's look at what we were doing, and it looks like we have this hasAvailability variable here that seems to be helpful. Let's check what it's all about.

2:21 OK, so it's here. Basically, hasAvailability is signifying that a given calendar day has bookable times for that given day. Remember, in our calendar app, we have some days highlighted in blue, and these days have availability. If I select any of the days not in blue, they don't have any vacancy. Once again, that makes our job really simple here. If hasAvailability, return "vacancy."

2:52 So far, our getStatus function is extremely simple to reason about. We have two more statuses to handle, "no vacancy" and "today no vacancy." The difference between these two is quite obvious. One is today, and the other one is not. Once again, we have that information already.

3:09 You can see this isCurrentDay that we were using in multiple places. In the code, you can see that isCurrentDay checks if the day is today. This isToday function comes from the @internationalized/date package, and we can use that to continue making our function super simple, but also complete.

3:29 Because this is the last return statement, we can return and check isCurrentDay? If it is, we're going to return "today," but with "no vacancy." If it's not today, we're going to return just "no vacancy." Check this out. This very simple getStatus function returns each of the five possible statuses.

3:52 All we need to know to get the correct status is to do const status, which is a Status, equals, and we can call the getStatus function. Now, this status variable will hold the correct status based on what this getStatus function has determined.

4:11 We can scroll down, and instead of doing all this convoluted logic, we can reach for the statusClasses object, which holds all our variants, and reach for the status. What I'm hoping here is when I switch to the UI, the calendar on the left looks exactly like the calendar on the right.

4:31 And boom! Bingo! Look at this. The calendar days look identical, but this calendar on the right is using that styling approach, whereas the calendar on the left is getting everything it needs from the statusClasses using the getStatus function. If you wanted, you could skip this status variable here, and in there, directly, call the getStatus function. That works as well.

4:59 Now that everything is working, we can remove the old stuff here and there, and we're left with a pretty tidy Calendar Day component. A bunch of the complexity is in the calendar logic state, but then style-wise, we have our status type, we have baseClasses, we have a statusClasses lookup object, and a getStatus function to determine which is the current status.

5:24 Then all we do is compose the baseClasses and the statusClasses together in the className attribute. Hopefully, that lets you visualize how you would approach your specific case scenario. You can see that this technique is very scalable, flexible, and works in a lot of different cases.