So now what I want to do is that when we click on one of these elements in the sidebar, I want additional options to appear. And we're gonna start with the shapes sidebar because it's the simplest one to add as our editor functionality. That being said, we actually don't have any editor functionality at the moment besides this so our first step is just to create the UI when we click on the shapes and then in the next chapter we're gonna go ahead and add some necessary methods inside of our use editor hook which will enable the end user to actually add the shapes. So let's go ahead and let's go inside of our editor component so this is inside of features editor components editor here and in here we have the sidebar so what I want to do now is below that I'm going to add shape sidebar like this and I'm going to give this a active tool prop whoops and I'm also going to pass the on change active tool so if you save you're going to get an error because it does not exist at the moment. Let's go inside of components here and we're gonna add shape sidebar dsx like this.
Let's go ahead and create an interface shape sidebar. It will accept an active tool and on change active tool which will be a tool active tool and a void. Now let's export const shape sidebar. Let's go ahead and extract the props. We should have named this shape sidebar props like this.
And then in here we can extract the active tool and on change active tool. And I want to change these two features, editor. There we go. So now let's import the shape sidebar. Right here I'm gonna change these two components.
There we go. And nothing should appear just yet. And I'm not gonna use the div instead I'm gonna use the aside element like this. Let's go ahead and give this some dynamic class names by using the CNLibUtil. I'm just gonna separate these two imports.
In the first argument of the CNUtil I'm gonna write some default classes. So this will be background color of white, relative, border on the right side, z-index of 40 and a width of 360 pixels. Like this. And let's also give it a full height and let's give it flex and flex-core. Like this.
There we go. And now I'm gonna go ahead and do the following. If active tool is equal to shapes in that case it's gonna be visible otherwise it's gonna be hidden like this and I'm gonna write shapes sidebar. So now if I go ahead and I refresh and I click on shapes, There we go. The shapes sidebar opens and you can see how our auto zoom is working nicely.
So it keeps our content centered and scaled even when being pushed by our sidebar here. Perfect. Now let's go ahead and let's create some additional components here and we can start by creating the tool sidebar header. So inside of these components here let's create a tool dash sidebar dash header component. I'm going to create an interface tool sidebar header props which will add a title and a description which can be optional.
We're not always going to need it. Let's export the tool sidebar header. Let's assign the tool sidebar header props here. We can destructure those two immediately. And let's go ahead and return a div with a class name padding of 4 border bottom space y1 and height of 68 pixels.
Inside let's add a paragraph which will render the title and let's give our paragraph a text small and font medium. Below the paragraph we're gonna check if we have the description. We're gonna render a paragraph again which will render our description with the class name text extra small and text muted foreground. Now let's go back inside of the shape sidebar here and we're gonna go ahead and remove these text and add pull sidebar header component. It's going to be a self-closing tag which will accept the title shapes and description add shapes to your canvas and I'm just gonna fix the import here.
You of course don't have to change the import but I like it like this. All right, so now if I go ahead and try it again. Make sure you resize the desktop mode so you can see it properly. There we go. Shapes, add shapes to your canvas.
Perfect. What we need now is we need a close button here. So we can close it by clicking again on shapes or clicking on something else, right? But I want an explicit close button for this sidebar right here. So let's go ahead and create that tool.
So that's gonna be tool sidebar close and it's gonna be a very specific tool. So let me go ahead and close these things. Inside of the same components folder we're gonna create tool sidebar close. Let's go ahead and create an interface tool sidebar close props which will accept a very simple onClick method. So toolSidebarClose will accept the toolSidebarClose props.
Let's immediately destructure the onClick method and now we're gonna return a native button element so we are not importing this from Shazam this is just a native element here and we're gonna add Chevron's left here from Lucid React so Chevron's multiple from Lucid React And let's go ahead and do the following. Let's give it a class name of size four. Let's give it a class name of text, black, group, hover, opacity, 75, and transition. And I closed my component. There we go.
Now let's go back inside of the shape sidebar here and I want to go ahead and immediately render this. So at the bottom of a side here, we're going to add tool sidebar close. And the onClick method here can be onClose method and we can define onClose here, which will very simply call the on change active tool back to the select option. So we can actually render this in one line. It's not taking up too much space.
So now I'm gonna go ahead and try and keep both of my things open so you can kind of see. So there we go. We have these two chevrons right here which when clicked seem to not be doing anything. That's because we have not added an on click here so let's just quickly do that. So to this button let's add an on click, on click prop.
So now if you click on shapes and then click on these two chevrons it closes. Now we need to position these two chevrons properly. I want to position them right here. I kind of want them floating around here. Same as some other popular editors.
So for that we're gonna have to do quite a bit of complicated class name here so go ahead and follow along. First of all, the button will need to have an absolute property and you can always check whenever you write a class name you can hover over to confirm that the class name exists. Because if you make a typo like this and then you hover nothing happens. If you hover on a class name and nothing appears it means it doesn't exist in Tailwind and it's most likely a typo. So when you fix it, it exists.
There we go. Now let's go ahead and do minus write dash 1.80 rem. Like this. Then let's give it a height of 70 pixels. Then a background color of white.
A top of 1.5. Transform. Let me scroll up so you can see, after transform we're gonna have minus translate, minus y, minus one and a half, flex item center, justify center, rounded, whoops, on the right side, extra large, px will be one, pr will be two, border will be only on the right side and on top and bottom. And this will be the group which means when the user hovers on the button I just want the chevron icon to change the opacity. That's what the group hover does.
When you hover on my group, then do the change here. So I don't want to make the entire button change the opacity. I just want the icon to change the opacity. Let's try it out. There we go.
So this is how I imagine this to look like. When I click, there we go. Let me zoom out in its natural 100% width. This is how it is going to look like. We click on shapes, we're going to have some shapes to select here and then we can easily close our sidebar here and we're gonna reuse this kind of code for the rest of our sidebars.
Perfect! So what I want to do now is I want to go ahead and go back inside of the actual shape sidebar here. And I wanna go ahead and add some shape tools to prepare to be clicked for when we add the functionality to actually add them to our canvas. So first of all, I wanna go ahead and add a package from ShadCNUI. So bunnx or npx ShadCNUI latest add scroll area.
So I want to have some nice scrolling area here. Remember to refresh your page if you've shut down the server. And we're going to write our code in between the tool sidebar header and the tool sidebar close. So in here, I'm going to go ahead and add a scroll area from components UI scroll area. So make sure that's where you added the import from.
And I'm also gonna change this to use the components import. Let me just zoom out so you can see how this looks like. There we go. Now that we have the scroll area in here, we don't have to give it any special classes, but let's write a div inside with a class name of grid, grid calls three, gap four, and padding of four. And then in here, we're gonna use something called shape tool.
We don't have any shape tool yet, but we are gonna create it right now. So in the same components folder in our features editor components add a shape-tool.tsx component. We're gonna go ahead and import a lucid icon type from Lucid React. You can also add the type here to be more specific. And let's also import icon type from react icons and you can also add type here as well so we can have either the type from lucid icons or react icons let's also prepare by importing the cn from our lib utils Let's create an interface shape tool props.
OnClick method here will be a very simple void. Icon will be either a type of lcd icon or a type of icon type. And we're gonna have an icon class name, which will be an optional string. This can help us later. Let's export const shape tool here.
Let's assign shape tool props. Let me just fix the typo. Let's extract the props here on click, icon and icon class name. And let's return a native button element so we are not importing this from chat.cnui and let's render our icon and in order to render it, we have to remap it here to an icon with a capital I as we did one time before. Now let's give this a class name of cn We're gonna give it some default classes.
Full height, full width. And then for the dynamic class we're just gonna pass the icon class name, whatever that might be. For the button let's go ahead and pass in or forward the on click prop. And for the class name we're gonna be using the aspect square we're gonna define the border for our full element roundedness and a padding of 5 like this. That's our shape tool.
So we can now go ahead and import shape tool from .slash shape tool or you already know how I'm going to change it to right here. Zoom out so you can see. There we go. And now let's go ahead and assign all the shape tools we want. So for the first shape tool, the onClick is just going to be an empty arrow function.
And the icon is going to be FA Circle. From React, icons FA. I'm just going to move those to the top here. There we go. And I'm gonna go ahead and copy these.
So this one is gonna be FA square from the same react-icons import. After that fa square full from the same import and then we're gonna have io triangle this one is gonna come from a package react dash icon slash io5 I'm gonna move them together here Let me just add a semicolon here. There we go. So IO triangle from react icons IO5. So we have that.
And let's go ahead and add another one. So this is also gonna be IO triangle, but we're gonna have icon class name rotate 180 like this and then let's copy and paste this this one is not gonna have a class name it's gonna be fa diamond this one from react icons fa6 So you cannot import the diamond from the normal FA. You have to import FADiamond from FA6. So we have react icons IO5 for the triangle, react icons FA6 for the diamond and react icons FA for the circle, square and square full. Let's go ahead and see if this is looking good or not.
When I click on the shapes here, there we go. These are all of my elements and now when I click on these elements, they will subsequently appear the same way this rectangle is right here right now because we added it initially, right? But later when we click on the circle, the circle will be centered here. When I click here, the triangle will be. When I click on the diamond, the diamond will be centered.
And using the same logic, you will be able to of course add as many of these shapes and tools as you want. Great, great job!