94 lines
3.1 KiB
Vue
94 lines
3.1 KiB
Vue
<template>
|
|
<flowbite-themable-child tag="button" :apply="appliableTheme" :class="wrapperClasses" :disabled="disabled">
|
|
<div v-if="!isOutlineGradient && ($slots.prefix || loadingPrefix)" class="mr-2"> <!--automatically add mr class if slot provided or loading -->
|
|
<spinner :color="spinnerColor" :size="spinnerSize" v-if="loadingPrefix" />
|
|
<slot name="prefix" v-else />
|
|
</div>
|
|
|
|
<span :class="spanClasses">
|
|
<div v-if="isOutlineGradient && ($slots.prefix || loadingPrefix)" class="mr-2"> <!--if outline gradient - need to place slots inside span -->
|
|
<spinner :color="spinnerColor" :size="spinnerSize" v-if="loadingPrefix" />
|
|
<slot name="prefix" v-else />
|
|
</div>
|
|
|
|
<slot/>
|
|
|
|
<div v-if="isOutlineGradient && ($slots.suffix || loadingSuffix)" class="ml-2"> <!--if outline gradient - need to place slots inside span -->
|
|
<spinner :color="spinnerColor" :size="spinnerSize" v-if="loadingSuffix" />
|
|
<slot name="suffix" v-else />
|
|
</div>
|
|
</span>
|
|
|
|
<div v-if="!isOutlineGradient && ($slots.suffix || loadingSuffix)" class="ml-2"> <!--automatically add ml class if slot provided or loading -->
|
|
<spinner :color="spinnerColor" :size="spinnerSize" v-if="loadingSuffix" />
|
|
<slot name="suffix" v-else />
|
|
</div>
|
|
</flowbite-themable-child>
|
|
</template>
|
|
<script lang="ts" setup>
|
|
import { computed, toRefs } from 'vue'
|
|
import type { PropType } from 'vue'
|
|
import Spinner from '../Spinner/Spinner.vue'
|
|
import { useButtonClasses } from './composables/useButtonClasses'
|
|
import { useButtonSpinner } from './composables/useButtonSpinner'
|
|
import FlowbiteThemableChild from '@/components/utils/FlowbiteThemable/components/FlowbiteThemableChild/FlowbiteThemableChild.vue'
|
|
|
|
import type { ButtonGradient, ButtonMonochromeGradient, ButtonSize, ButtonVariant } from './types'
|
|
const props = defineProps({
|
|
color: {
|
|
type: String as PropType<ButtonVariant>,
|
|
default: 'default',
|
|
},
|
|
gradient: {
|
|
type: [String, null] as PropType<ButtonGradient | null>,
|
|
default: null,
|
|
},
|
|
size: {
|
|
type: String as PropType<ButtonSize>,
|
|
default: 'md',
|
|
},
|
|
shadow: {
|
|
type: [String, null] as PropType<ButtonMonochromeGradient | '' | null>,
|
|
default: null,
|
|
},
|
|
pill: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
square: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
outline: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
loading: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
loadingPosition: {
|
|
type: String as PropType<'suffix' | 'prefix'>,
|
|
default: 'prefix',
|
|
},
|
|
disabled: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
})
|
|
|
|
const isOutlineGradient = computed(() => props.outline && props.gradient)
|
|
|
|
const loadingPrefix = computed(() => props.loading && props.loadingPosition === 'prefix')
|
|
const loadingSuffix = computed(() => props.loading && props.loadingPosition === 'suffix')
|
|
|
|
const { wrapperClasses, spanClasses } = useButtonClasses(toRefs(props))
|
|
const { color: spinnerColor, size: spinnerSize } = useButtonSpinner(toRefs(props))
|
|
|
|
const appliableTheme = computed(() => {
|
|
if(['alternative', 'light'].includes(props.color)) return []
|
|
return ['background', 'hover', 'focus']
|
|
})
|
|
|
|
</script>
|