feat: add button component

This commit is contained in:
Muhsin Keloth
2024-04-19 13:49:22 +05:30
parent 25ad9eee61
commit 7c28d2124c
8 changed files with 403 additions and 51 deletions
@@ -0,0 +1,140 @@
<template>
<button
class="inline-flex items-center gap-1 text-sm font-medium reset-base rounded-xl w-fit"
:type="type"
:class="buttonClasses"
:disabled="isDisabled || isLoading"
@click="handleClick"
>
<fluent-icon :size="iconSize" :icon="icon" class="flex-shrink-0" />
<span
v-if="$slots.default"
class="text-sm font-medium truncate"
:class="{ 'text-left rtl:text-right': size !== 'expanded' }"
>
<slot />
</span>
<fluent-icon :size="iconSize" icon="chevron-right" class="flex-shrink-0" />
</button>
</template>
<script>
export default {
props: {
type: {
type: String,
default: 'submit',
},
variant: {
type: String,
default: '',
},
size: {
type: String,
default: '',
},
icon: {
type: String,
default: '',
},
emoji: {
type: String,
default: '',
},
colorScheme: {
type: String,
default: 'primary',
},
classNames: {
type: [String, Object],
default: '',
},
isDisabled: {
type: Boolean,
default: false,
},
isLoading: {
type: Boolean,
default: false,
},
isExpanded: {
type: Boolean,
default: false,
},
},
computed: {
// variantClasses() {
// if (this.variant.includes('link')) {
// return `clear ${this.variant}`;
// }
// return this.variant;
// },
// hasOnlyIcon() {
// const hasEmojiOrIcon = this.emoji || this.icon;
// return !this.$slots.default && hasEmojiOrIcon;
// },
// hasOnlyIconClasses() {
// return this.hasOnlyIcon ? 'button--only-icon' : '';
// },
buttonClasses() {
return [
this.colorClass,
this.sizeClass,
// this.variantClasses,
// this.hasOnlyIconClasses,
// this.size,
// this.colorClass,
// this.classNames,
// this.isDisabled ? 'disabled' : '',
// this.isExpanded ? 'expanded' : '',
];
},
colorClass() {
if (this.colorScheme === 'primary') {
return 'bg-primary-600 text-white hover:bg-primary-700 active:bg-primary-700 focus:ring focus:ring-offset-1 focus:ring-primary-400';
}
if (this.colorScheme === 'secondary') {
return 'bg-ash-100 text-white hover:bg-ash-200 active:bg-ash-200 focus:ring focus:ring-offset-1 focus:ring-ash-400';
}
if (this.colorScheme === 'danger') {
return 'bg-ruby-600 text-white hover:bg-ruby-700 active:bg-ruby-700 focus:ring focus:ring-offset-1 focus:ring-ruby-400';
}
return 'bg-primary-500 text-white';
},
sizeClass() {
if (this.size === 'md') {
return 'px-3 py-2 text-sm';
}
return 'px-4 py-2.5 text';
},
iconSize() {
switch (this.size) {
case 'tiny':
return 12;
case 'small':
return 14;
case 'medium':
return 16;
case 'large':
return 18;
default:
return 16;
}
},
showDarkSpinner() {
return (
this.colorScheme === 'secondary' ||
this.variant === 'clear' ||
this.variant === 'link' ||
this.variant === 'hollow'
);
},
},
methods: {
handleClick(evt) {
this.$emit('click', evt);
},
},
};
</script>
+3 -5
View File
@@ -20,15 +20,13 @@
:data-testid="dataTestid"
:value="value"
:class="{
'focus:outline-red-600 outline-red-600 dark:focus:outline-red-600 dark:outline-red-600':
hasError,
'outline-slate-200 dark:outline-slate-600 dark:focus:outline-woot-500 focus:outline-woot-500':
!hasError,
'outline-ruby-600 focus:outline-ruby-600': hasError,
'outline-ash-200 focus:outline-primary-500': !hasError,
'px-3 py-3': spacing === 'base',
'px-3 py-2 mb-0': spacing === 'compact',
'pl-9': icon,
}"
class="block w-full border-none rounded-md shadow-sm appearance-none outline outline-1 focus:outline-2 text-slate-900 dark:text-slate-100 placeholder:text-slate-400 sm:text-sm sm:leading-6 dark:bg-slate-800"
class="block w-full h-10 ltr:pl-3 ltr:pr-2 rtl:pl-2 rtl:pr-3 py-2.5 !border-none shadow-sm appearance-none reset-base rounded-xl outline outline-1 focus:outline-1 text-ash-900 placeholder:text-ash-200 sm:text-sm sm:leading-6"
@input="onInput"
@blur="$emit('blur')"
/>
@@ -3,8 +3,7 @@
<label
v-if="label"
:for="name"
class="flex justify-between text-sm font-medium leading-6 text-slate-900 dark:text-white"
:class="{ 'text-red-500': hasError }"
class="flex justify-between text-sm font-medium leading-6 text-ash-900"
>
<slot name="label">
{{ label }}
@@ -12,18 +11,18 @@
<slot name="rightOfLabel" />
</label>
<div class="w-full">
<div class="flex items-center relative w-full">
<div class="relative flex items-center w-full">
<fluent-icon
v-if="icon"
size="16"
:icon="icon"
class="absolute left-2 transform text-slate-400 dark:text-slate-600 w-5 h-5"
class="absolute w-5 h-5 transform left-2 text-ash-400"
/>
<slot />
</div>
<span
v-if="errorMessage && hasError"
class="text-xs text-red-400 leading-2"
class="text-xs text-ruby-800 leading-2"
>
{{ errorMessage }}
</span>