Button
A button component is a clickable element that triggers actions when clicked. It can contain text or icons, has different styles, and plays a role in user interaction and navigation.
Import
import { Button } from '@johngerome/vue-ui'
import { Button } from '@johngerome/vue-ui'
Composition
We highly recommend creating a Button wrapper instead of utilizing the Button component directly. Doing so will provide you with the flexibility to customize its appearance effortlessly through themes or Tailwind classes. This approach ensures greater control and consistency in your design.
<script lang="ts" setup>
import Button from '@/components/Button/Button.vue'
import { THEME, Props } from '@/components/Button/Button.vue'
defineProps<Props>()
const theme = {
...THEME,
variants: {
...THEME.variants,
primary: 'bg-red-500 hover:bg-red-600',
},
}
</script>
<template>
<Button :theme="theme" class="rounded-none">Button</Button>
</template>
<script lang="ts" setup>
import Button from '@/components/Button/Button.vue'
import { THEME, Props } from '@/components/Button/Button.vue'
defineProps<Props>()
const theme = {
...THEME,
variants: {
...THEME.variants,
primary: 'bg-red-500 hover:bg-red-600',
},
}
</script>
<template>
<Button :theme="theme" class="rounded-none">Button</Button>
</template>
<template>
<MyButton>Button</MyButton>
</template>
<template>
<MyButton>Button</MyButton>
</template>
Preview
Variants
Use variant
prop to change the appearance of the Button. Available variants are primary
, outline
, ghost
,or link
.
Click me to view the code
<Button>Button</Button>
<Button variant="outline">Button</Button>
<Button variant="ghost">Button</Button>
<Button variant="link">Button</Button>
<Button>Button</Button>
<Button variant="outline">Button</Button>
<Button variant="ghost">Button</Button>
<Button variant="link">Button</Button>
Sizes
Use the size
props to change the size of the Button. Available sizes are sm
, md
, lg
, xl
or 2xl
Click me to view the code
<Button size="sm">Button</Button>
<Button size="md">Button</Button>
<Button size="lg">Button</Button>
<Button size="xl">Button</Button>
<Button size="2xl">Button</Button>
<Button size="sm">Button</Button>
<Button size="md">Button</Button>
<Button size="lg">Button</Button>
<Button size="xl">Button</Button>
<Button size="2xl">Button</Button>
Loading
Pass the is-loading
props to show its loading state. To override loading icon use template #loading
.
Click me to view the code
<Button is-loading>Submitting</Button>
<Button class="flex-row-reverse space-x-0" is-loading>
<span class="mr-2">Submitting</span>
</Button>
<Button is-loading></Button>
<Button is-loading>
<span class="mr-3">Submitting</span>
<template #loading>
<Icon icon="eos-icons:three-dots-loading" class="text-3xl" />
</template>
</Button>
<Button is-disabled>
<span>Submitting</span>
<Icon icon="eos-icons:three-dots-loading" class="text-3xl" />
</Button>
<Button is-loading>Submitting</Button>
<Button class="flex-row-reverse space-x-0" is-loading>
<span class="mr-2">Submitting</span>
</Button>
<Button is-loading></Button>
<Button is-loading>
<span class="mr-3">Submitting</span>
<template #loading>
<Icon icon="eos-icons:three-dots-loading" class="text-3xl" />
</template>
</Button>
<Button is-disabled>
<span>Submitting</span>
<Icon icon="eos-icons:three-dots-loading" class="text-3xl" />
</Button>
Theme
export const THEME = {
disabled: 'opacity-50 cursor-not-allowed',
variants: {
primary: 'bg-primary text-gray-100 hover:bg-primary/90',
outline:
'border border-primary/30 text-primary hover:bg-primary hover:text-gray-100',
ghost: 'text-primary hover:bg-primary/10',
link: 'text-primary hover:underline',
},
sizes: {
sm: 'px-2 py-1 text-xs rounded h-6',
md: 'py-2 px-3 text-base rounded-md h-10',
lg: 'p-3 text-lg rounded-md h-13',
xl: 'p-4 text-xl rounded-lg h-16',
'2xl': 'p-6 text-xl rounded-lg h-19',
},
loading: {
sm: 'text-sm',
md: 'text-lg',
lg: 'text-xl',
xl: 'text-2xl',
'2xl': 'text-3xl',
},
}
export const THEME = {
disabled: 'opacity-50 cursor-not-allowed',
variants: {
primary: 'bg-primary text-gray-100 hover:bg-primary/90',
outline:
'border border-primary/30 text-primary hover:bg-primary hover:text-gray-100',
ghost: 'text-primary hover:bg-primary/10',
link: 'text-primary hover:underline',
},
sizes: {
sm: 'px-2 py-1 text-xs rounded h-6',
md: 'py-2 px-3 text-base rounded-md h-10',
lg: 'p-3 text-lg rounded-md h-13',
xl: 'p-4 text-xl rounded-lg h-16',
'2xl': 'p-6 text-xl rounded-lg h-19',
},
loading: {
sm: 'text-sm',
md: 'text-lg',
lg: 'text-xl',
xl: 'text-2xl',
'2xl': 'text-3xl',
},
}
Props
export type Props = {
theme?: typeof THEME
size?: keyof (typeof THEME)['sizes']
variant?: keyof (typeof THEME)['variants']
isDisabled?: boolean
isLoading?: boolean
}
export type Props = {
theme?: typeof THEME
size?: keyof (typeof THEME)['sizes']
variant?: keyof (typeof THEME)['variants']
isDisabled?: boolean
isLoading?: boolean
}