For the third part of this series, it is time to build out the UI a little bit. In the last post we took our web setup and used electron to make a desktop app out of it. But now we have a problem. We haven't decided what this app is going to be. For the sake of the example, let's say a CRM (Customer Relationship Management). It is a good pick because they are universally known and fairly boring. It will be easy to focus on the build.
Before we dive in it is worth simplifying things a bit. Starting a new app is so exciting because there are endless possibilities. That can also make it hard to focus on what matters. For us that means setting up a toolkit that will enable us to make an amazing desktop app.
So let's set a few ground rules to get started:
- no routing
- static, inline data
- black and white design
We'll address these points in later posts.
In the first post we setup tailwind to work with vue, but we never really implemented it. Let's jump over to tailwindui's docs to get some components that will make sense for a CRM. One of the many things that I love about Tailwind is the documentation is absolutely terrific.
- tailwindui - sidebar navigation - a nice setup for a CRM
- tailwindui - various elements - various elements that can get us started
The sidebar nav will set a nice base for our whole app, so I definitely suggest grabbing that. I also took a couple random elements from the tailwind components. Check them out and play around with some different ideas.
Throwing it all together in our App.vue.
We barfed up a lot of HTML. That is fine to start. This is the moment that there might be some skepticism about tailwind too. There are classes EVERYWHERE and it doesn't seem sustainable. If we kept writing static html like this, it probably wouldn't be. But we are going to use it with
Vue and that is where it is really going to shine. After we break down the page into reusable components it will be obvious that Vue + Tailwind were made to be together.
Let's start with the component we'll want on all pages, the sidebar. Because we will always have it present but have the content change to the right of it
let's consider it the default layout.
➜ mkdir src/layouts && touch src/layouts/DefaultLayout.vue
And we'll just take out the sidebar HTML from our App.vue.
The only real change at this point is adding a slot in the part of the page that we will change.
<template> <div class="flex flex-row bg-gray-100"> <div class="flex flex-col h-0 border-r border-gray-200 bg-white w-64 min-h-screen h-screen pt-12" > ... </div> <div class="absolute inset-y-0 right-0 left-64 overflow-auto"> <slot></slot> </div> </div> </template>
Now it is time to break down the rest of the elements that we started with into smaller, resuable pieces.
As we inspect what we have everything falls into two categories. Either elements are simple (like a button) or a component of components (like a list). So let's separate them into the following directories:
➜ mkdir src/components/compound && mkdir src/components/simple
This will keep us focused on making simple, resuable components.
Some examples of simple components (src/components/simple) from our initial design:
Some examples of compound components (src/components/compound) from our initial design:
If you noticed I built out the components but the content of the page is still static. For what we are doing, which is setting up a UI to work with, that is perfectly fine. We don't want to lose focus on the task at hand and there are other libraries we'll use to work with data which we haven't added yet.
Now that we have some structure to our UI and a way to build it out, it is time to add some functional aspects to it.
- Routing Using vue-router to navigate between pages.
- Mocked Data Prepping the components to handle real data.
- State Management Using vuex to create a central place to store data.