Skip to content

Instantly share code, notes, and snippets.

@SazzadR
Created January 4, 2021 19:01
Show Gist options
  • Save SazzadR/d79279a5748c90bdbc1d2ea6daca33ff to your computer and use it in GitHub Desktop.
Save SazzadR/d79279a5748c90bdbc1d2ea6daca33ff to your computer and use it in GitHub Desktop.
Button Component Vue and Tailwind
<div id="app">
<div class="h-2 w-100 bg-blue-500"></div>
<div class="max-w-lg mx-auto my-12">
<!-- primary started -->
<h2 class="flex text-xl mb-3 text-gray-700">
<span class="text-lg bg-gray-200 text-gray-800 h-6 w-6 rounded-full inline-flex justify-center items-center mt-px mr-3">1</span>
Primary Loading Button
</h2>
<loading-button ref="primaryLoadingButton" @click="click('primaryLoadingButton')">Save Changes</loading-button>
<h2 class="flex text-xl mb-3 text-gray-700 mt-6">
<span class="text-lg bg-gray-200 text-gray-800 h-6 w-6 rounded-full inline-flex justify-center items-center mt-px mr-3">2</span>
Primary Disabled Button
</h2>
<loading-button ref="primaryDisabledButton" @click="click" :disabled="true">Save Changes</loading-button>
<h2 class="flex text-xl mb-3 text-gray-700 mt-6">
<span class="text-lg bg-gray-200 text-gray-800 h-6 w-6 rounded-full inline-flex justify-center items-center mt-px mr-3">3</span>
Primary Outline Button
</h2>
<loading-button ref="primaryOutlineButton" @click="alert('Editing work :)')" variant-type="outline">Edit</loading-button>
<!-- primary ended -->
<!-- danger started -->
<h2 class="flex text-xl mb-3 text-gray-700 mt-6">
<span class="text-lg bg-gray-200 text-gray-800 h-6 w-6 rounded-full inline-flex justify-center items-center mt-px mr-3">4</span>
Danger Loading Button
</h2>
<loading-button ref="dangerLoadingButton" @click="click('dangerLoadingButton')" variant="danger">Confirm Delete</loading-button>
<h2 class="flex text-xl mb-3 text-gray-700 mt-6">
<span class="text-lg bg-gray-200 text-gray-800 h-6 w-6 rounded-full inline-flex justify-center items-center mt-px mr-3">5</span>
Danger Disabled Button
</h2>
<loading-button ref="dangerDisabledButton" @click="click" :disabled="true" variant="danger">Delete Project</loading-button>
<h2 class="flex text-xl mb-3 text-gray-700 mt-6">
<span class="text-lg bg-gray-200 text-gray-800 h-6 w-6 rounded-full inline-flex justify-center items-center mt-px mr-3">6</span>
Danger Outline Button
</h2>
<loading-button ref="primaryOutlineButton" @click="alert('Delete work :)')" variant-type="outline" variant="danger">Delete</loading-button>
<!-- danger ended -->
<!-- success started -->
<h2 class="flex text-xl mb-3 text-gray-700 mt-6">
<span class="text-lg bg-gray-200 text-gray-800 h-6 w-6 rounded-full inline-flex justify-center items-center mt-px mr-3">7</span>
Success Loading Button
</h2>
<loading-button ref="successLoadingButton" @click="click('successLoadingButton')" variant="success">Pay Now</loading-button>
<h2 class="flex text-xl mb-3 text-gray-700 mt-6">
<span class="text-lg bg-gray-200 text-gray-800 h-6 w-6 rounded-full inline-flex justify-center items-center mt-px mr-3">8</span>
Success Disabled Button
</h2>
<loading-button ref="dangerDisabledButton" @click="click" :disabled="true" variant="success">Processing ...</loading-button>
<h2 class="flex text-xl mb-3 text-gray-700 mt-6">
<span class="text-lg bg-gray-200 text-gray-800 h-6 w-6 rounded-full inline-flex justify-center items-center mt-px mr-3">9</span>
Success Outline Button
</h2>
<loading-button ref="primaryOutlineButton" @click="alert('Signing up:)')" variant-type="outline" variant="success">Sign Up</loading-button>
<!-- success ended -->
<!-- warning started -->
<h2 class="flex text-xl mb-3 text-gray-700 mt-6">
<span class="text-lg bg-gray-200 text-gray-800 h-6 w-6 rounded-full inline-flex justify-center items-center mt-px mr-3">10</span>
Warning Button
</h2>
<loading-button ref="warningLoadingButton" @click="click('warningLoadingButton')" variant="warning">Warning !</loading-button>
<!-- warning ended -->
<!-- secondary started -->
<h2 class="flex text-xl mb-3 text-gray-700 mt-6">
<span class="text-lg bg-gray-200 text-gray-800 h-6 w-6 rounded-full inline-flex justify-center items-center mt-px mr-3">11</span>
Secondary Button
</h2>
<loading-button ref="secondaryLoadingButton" @click="click('secondaryLoadingButton')" variant="secondary" variant-type="outline">Cancel</loading-button>
<!-- secondary ended -->
</div>
</div>
const LoadingButton = {
name: "LoadingButton",
template: `
<component
:is="tag"
:type="type"
v-on="$listeners"
:disabled="disableButton"
:class="[btnClass, colorVariants]"
:variant="variant"
:variant-type="variantType"
:size="size"
:href="to"
>
<slot />
</component>`,
props: {
tag: {
type: String,
default: "button"
},
disabled: {
type: Boolean,
default: false
},
variant: {
type: String,
default: "primary"
},
variantType: {
type: String,
default: "normal"
},
size: {
type: String,
default: "normal"
},
rounded: {
type: String,
default: "medium"
},
type: {
type: String,
default: ""
},
to: {
type: String
}
},
data() {
return {
loading: false,
disableButton: this.disabled
};
},
methods: {
startLoading() {
this.loading = true;
this.disableButton = true;
},
stopLoading() {
this.loading = false;
this.disableButton = false;
}
},
computed: {
btnClass() {
return {
"base-spinner": this.loading == true,
"cursor-not-allowed": this.disableButton == true,
"base-button inline-flex align-middle align-items-center justify-center font-medium focus:outline-none border-2": true,
"rounded-lg": this.rounded === "medium",
"rounded-full": this.rounded === "large",
"px-6 py-3": this.size == "normal",
"px-4 py-2": this.size == "small"
};
},
colorVariants() {
switch (this.variant) {
case "primary":
switch (this.variantType) {
case "normal":
switch (this.disableButton) {
case true:
return "border-blue-300 bg-blue-300 text-white";
break;
default:
break;
}
return "border-blue-600 bg-blue-600 hover:bg-blue-700 hover:border-blue-700 text-white";
break;
case "outline":
return "border-gray-200 text-blue-500 hover:text-blue-700";
break;
default:
break;
}
break;
case "danger":
switch (this.variantType) {
case "normal":
switch (this.disableButton) {
case true:
return "border-red-300 bg-red-300 text-white";
break;
default:
break;
}
return "border-red-600 bg-red-600 hover:bg-red-700 hover:border-red-700 text-white";
break;
case "outline":
return "border-gray-200 text-red-500 hover:text-red-600";
break;
default:
break;
}
break;
case "warning":
switch (this.variantType) {
case "normal":
return "border-orange-600 bg-orange-600 hover:bg-orange-700 hover:border-orange-700 text-white";
break;
default:
break;
}
break;
case "success":
switch (this.variantType) {
case "normal":
switch (this.disableButton) {
case true:
return "border-green-300 bg-green-300 text-white";
break;
default:
break;
}
return "border-green-600 bg-green-600 hover:bg-green-700 hover:border-green-700 text-white";
break;
case "outline":
return "border-2 border-gray-200 text-green-500 hover:text-green-700";
break;
default:
break;
}
break;
case "white":
switch (this.variantType) {
case "normal":
return "border-white bg-white bg-white text-blue-600 hover:text-blue-800";
break;
default:
break;
}
break;
case "secondary":
switch (this.variantType) {
case "outline":
return "border-gray-300 text-gray-500 hover:text-blue-500";
break;
default:
break;
}
break;
default:
break;
}
}
}
};
new Vue({
el: "#app",
components: {
LoadingButton
},
methods: {
click(ref) {
this.$refs[`${ref}`].startLoading();
setTimeout(() => this.$refs[`${ref}`].stopLoading(), 3000);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js"></script>
.base-button + .base-button {
margin-left: 1em;
}
@keyframes spinner {
to {
transform: rotate(360deg);
}
}
.base-spinner {
position: relative;
overflow: hidden;
}
.base-spinner:before {
content: "";
box-sizing: border-box;
position: absolute;
background-color: inherit;
width: 100%;
height: 100%;
display: block;
z-index: 1;
top: 0;
left: 0;
}
.base-spinner:after {
content: "";
box-sizing: border-box;
position: absolute;
top: 50%;
left: 50%;
width: 20px;
height: 20px;
margin-top: -10px;
margin-left: -10px;
border-radius: 50%;
border: 2px solid rgba(255, 255, 255, 0.45);
border-top-color: inherit;
animation: spinner 0.6s linear infinite;
z-index: 2;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/1.2.0/tailwind.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment