Building a UI Kit with Vue3, Typescript, Vite, TailwindCSS and StorybookJs
Hello! ???? Today we’re going to be building a UI Kit with Vue3, Vite, Typescript, TailwindCSS for our styling and StorybookJs for easy documentation.
?
Scaffolding the project ??????
Our preferred package manager for setting up the project is Yarn. We start by scaffolding a Vite + Vue3 + Typescript project with Yarn. Once you’re done, go to your project folder and run yarn.
?
$ yarn create vite ui-kit --template vue-ts
?
Once that is done, go ahead and install TailwindCSS using the guide here and remember to use yarn to install tailwind. We will use tailwind classes to style our components.
?
$ yarn add -D tailwindcss postcss autoprefixer
?
Lastly, we set up Storybook using the guide here. Also remember to use yarn. Once that is done, we run storybook this way;
?
$ yarn storybook
?
Creating a component ??
By default, storybook comes with some components, so we’re going to work with that. These Storybook components can be found in src/stories. Head over to Button.vue and adjust a few things. First we want to use the Vue3 setup which works perfectly with Typescript. Clear out everything in the script tag. Your Button.vue component should look like this now
?
<template>
? <button type="button" :class="classes" @click="(event)=> emit(‘click’, event)">{{ label }}</button>
</template>
?
<script setup lang="ts">
import './button.css';
import { computed } from 'vue';
?
interface Props {
? label: string
? primary?: boolean
? outline?: boolean
? text?: boolean
? size?: string
}
?
const props = defineProps<Props>()
?
const emit = defineEmits<{
? (e: 'click', mouseEvent: MouseEvent): void
}>()
?
const classes = computed(() => ({
? 'storybook-button': true,
? 'storybook-button--primary': props.primary,
? 'storybook-button--secondary': props.outline,
? 'storybook-button--text': props.text,
领英推荐
? [`storybook-button--${props.size || 'medium'}`]: true,
}));
</script>
?
You can go ahead and style your button with storybook classes in button.css .'storybook-button {
? @apply font-normal text-sm rounded-xl cursor-pointer text-center inline-flex items-center space-x-2.5 w-min !important;
? height: fit-content;
? font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
.'storybook-button--primary {
? @apply text-white bg-blue-600 focus:ring focus:ring-blue-200 transition duration-300 ease-in !important;
}
.'storybook-button--secondary {
? @apply text-gray-600 bg-transparent border border-gray-600 focus:ring focus:ring-gray-200 transition duration-300 ease-in !important;
}
.'storybook-button--text {
? @apply text-gray-600 hover:text-gray-900 bg-transparent focus:bg-gray-100 transition duration-300 ease-in !important;
}
.'storybook-button--small {
? @apply py-2 px-3 !important;
}
.'storybook-button--medium {
? @apply py-2.5 px-3.5 !important;
}
.'storybook-button--large {
? @apply py-3 px-4 !important;
}
?
Head over to Button.vue and insert this in your style tag <style scoped>
@import url(./button.css);
</style>
?
Now, we want to register this component globally so we don’t have to import it every single time we want to make use of it. To achieve this, we create an index.ts file in /src
?
import Button from ‘./components/Button.vue’
?
export default {
??????????? install: (app, options) => {
??????????? app.component(“Button”, Button);
}
}
?
With this, we’ve successfully created a UI component and other components can be created using this same process.
?