feat: shadow and gradient outline

This commit is contained in:
Alexandr
2022-07-01 00:16:52 +03:00
parent dfc683a40a
commit a36c3b6b65
4 changed files with 144 additions and 12 deletions

View File

@@ -7,6 +7,8 @@ import ButtonGradientDuotoneExample from './examples/ButtonGradientDuotoneExampl
import ButtonOutlineColorExample from './examples/ButtonOutlineColorExample.vue'; import ButtonOutlineColorExample from './examples/ButtonOutlineColorExample.vue';
import ButtonPrefixExample from './examples/ButtonPrefixExample.vue'; import ButtonPrefixExample from './examples/ButtonPrefixExample.vue';
import ButtonSuffixExample from './examples/ButtonSuffixExample.vue'; import ButtonSuffixExample from './examples/ButtonSuffixExample.vue';
import ButtonOutlineGradientExample from './examples/ButtonOutlineGradientExample.vue';
import ButtonGradientShadowExample from './examples/ButtonGradientShadowExample.vue';
</script> </script>
# Button # Button
@@ -187,6 +189,46 @@ import { Button } from 'flowbite-vue'
``` ```
## Prop - outline (gradient)
<ButtonOutlineGradientExample />
```vue
<script setup>
import { Button } from 'flowbite-vue'
</script>
<template>
<Button gradient="purple-blue" outline>Purple to blue</Button>
<Button gradient="cyan-blue" outline>Cyan to blue</Button>
<Button gradient="green-blue" outline>Green to blue</Button>
<Button gradient="purple-pink" outline>Purple to pink</Button>
<Button gradient="pink-orange" outline>Pink to orange</Button>
<Button gradient="teal-lime" outline>Teal to lime</Button>
<Button gradient="red-yellow" outline>Red to yellow</Button>
</template>
```
## Prop - shadow
<ButtonGradientShadowExample />
```vue
<script setup>
import { Button } from 'flowbite-vue'
</script>
<template>
<Button gradient="blue" shadow>Blue</Button>
<Button gradient="cyan" shadow>Cyan</Button>
<Button gradient="green" shadow>Green</Button>
<Button gradient="lime" shadow>Lime</Button>
<Button gradient="pink" shadow>Pink</Button>
<Button gradient="purple" shadow>Purple</Button>
<Button gradient="red" shadow>Red</Button>
<Button gradient="teal" shadow>Teal</Button>
</template>
```
## Slot - prefix ## Slot - prefix
<ButtonPrefixExample /> <ButtonPrefixExample />
@@ -222,3 +264,5 @@ import { Button } from 'flowbite-vue'
</Button> </Button>
</template> </template>
``` ```

View File

@@ -0,0 +1,18 @@
<template>
<div class="inline-flex align-center gap-2 flex-wrap">
<Button gradient="blue" shadow>Blue with blue</Button>
<Button gradient="cyan" shadow>Cyan with cyan</Button>
<Button gradient="green" shadow>Green with green</Button>
<Button gradient="lime" shadow>Lime with lime</Button>
<Button gradient="pink" shadow>Pink with pink</Button>
<Button gradient="purple" shadow>Purple with purple</Button>
<Button gradient="red" shadow>Red with red</Button>
<Button gradient="teal" shadow>Teal with teal</Button>
<Button gradient="blue" shadow="red">Blue with red</Button>
<Button gradient="cyan" shadow="teal">Cyan with teal</Button>
<Button gradient="teal" shadow="purple">Teal with purple</Button>
</div>
</template>
<script setup>
import { Button } from '../../../../src/index'
</script>

View File

@@ -0,0 +1,14 @@
<template>
<div class="inline-flex align-center gap-2 flex-wrap">
<Button gradient="purple-blue" outline>Purple to blue</Button>
<Button gradient="cyan-blue" outline>Cyan to blue</Button>
<Button gradient="green-blue" outline>Green to blue</Button>
<Button gradient="purple-pink" outline>Purple to pink</Button>
<Button gradient="pink-orange" outline>Pink to orange</Button>
<Button gradient="teal-lime" outline>Teal to lime</Button>
<Button gradient="red-yellow" outline>Red to yellow</Button>
</div>
</template>
<script setup>
import { Button } from '../../../../src/index'
</script>

View File

@@ -1,7 +1,9 @@
<template> <template>
<button type="button" :class="bindClasses"> <button type="button" :class="bindClasses">
<slot name="prefix" /> <slot name="prefix" />
<slot/> <span :class="spanClasses">
<slot/>
</span>
<slot name="suffix" /> <slot name="suffix" />
</button> </button>
</template> </template>
@@ -39,34 +41,68 @@ const props = defineProps({
type: Boolean, type: Boolean,
default: false, default: false,
}, },
shadow: {
type: [String, null] as PropType<ButtonMonochromeGradient | '' | null>,
default: null,
},
}) })
const slots = useSlots() const slots = useSlots()
const bindClasses = computed(() => { const bindClasses = computed(() => {
const isGradient = !!props.gradient
const isColor = !!props.color
const isOutline = props.outline
let backgroundClass = '' let backgroundClass = ''
if(props.gradient) {
backgroundClass = buttonGradientClasses[props.gradient] if(isGradient && isOutline) {
} else { if(['blue', 'green', 'cyan', 'teal', 'lime', 'red', 'pink', 'purple'].includes(props.gradient)) { // invalid gradients for outline
if(props.outline) { // if outline and no gradient backgroundClass = buttonGradientClasses[props.gradient]
if(['alternative', 'light'].includes(props.color)) { // invalid colors for outline
backgroundClass = buttonColorClasses[props.color]
} else {
backgroundClass = buttonOutlineColorClasses[props.color as unknown as keyof typeof buttonOutlineColorClasses]
}
} else { } else {
backgroundClass = buttonOutlineGradientClasses[props.gradient as unknown as keyof typeof buttonOutlineGradientClasses]
}
} else if(isGradient) {
backgroundClass = buttonGradientClasses[props.gradient]
} else if(isColor && isOutline) {
if(['alternative', 'light'].includes(props.color)) { // invalid colors for outline
backgroundClass = buttonColorClasses[props.color] backgroundClass = buttonColorClasses[props.color]
} else {
backgroundClass = buttonOutlineColorClasses[props.color as unknown as keyof typeof buttonOutlineColorClasses]
}
} else {
backgroundClass = buttonColorClasses[props.color]
}
let shadowClass = ''
if(props.shadow === '') {
if(props.gradient && ['blue', 'green', 'cyan', 'teal', 'lime', 'red', 'pink', 'purple'].includes(props.gradient)) {
shadowClass = buttonShadowClasses[props.gradient as unknown as keyof typeof buttonShadowClasses]
}
} else if(typeof props.shadow === 'string') {
if(['blue', 'green', 'cyan', 'teal', 'lime', 'red', 'pink', 'purple'].includes(props.shadow)) {
shadowClass = buttonShadowClasses[props.shadow as unknown as keyof typeof buttonShadowClasses]
} }
} }
return classNames( return classNames(
backgroundClass, backgroundClass,
buttonSizeClasses[props.size], shadowClass,
(isGradient && isOutline) ? 'p-0.5' : buttonSizeClasses[props.size],
props.pill ? '!rounded-full' : '', props.pill ? '!rounded-full' : '',
(slots.prefix || slots.suffix) ? 'inline-flex items-center' : '', (slots.prefix || slots.suffix) ? 'inline-flex items-center' : '',
) )
}) })
const spanClasses = computed(() => {
if(!!props.gradient && props.outline)
return classNames(
'relative transition-all ease-in duration-75 bg-white dark:bg-gray-900 rounded-md group-hover:bg-opacity-0',
buttonSizeClasses[props.size],
)
return ''
})
const buttonColorClasses: Record<ButtonVariant, string> = { const buttonColorClasses: Record<ButtonVariant, string> = {
default: 'text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800', default: 'text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800',
alternative: 'font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700', alternative: 'font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700',
@@ -105,6 +141,16 @@ const buttonGradientClasses: Record<ButtonGradient, string> = {
'teal': 'text-white bg-gradient-to-r from-teal-500 via-teal-600 to-teal-700 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-teal-300 dark:focus:ring-teal-800 rounded-lg', 'teal': 'text-white bg-gradient-to-r from-teal-500 via-teal-600 to-teal-700 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-teal-300 dark:focus:ring-teal-800 rounded-lg',
} }
const buttonOutlineGradientClasses: Record<ButtonDuotoneGradient, string> = {
'cyan-blue': 'relative inline-flex items-center justify-center overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-cyan-500 to-blue-500 group-hover:from-cyan-500 group-hover:to-blue-500 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-cyan-200 dark:focus:ring-cyan-800',
'green-blue': 'relative inline-flex items-center justify-center overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-green-400 to-blue-600 group-hover:from-green-400 group-hover:to-blue-600 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-green-200 dark:focus:ring-green-800',
'pink-orange': 'relative inline-flex items-center justify-center overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-pink-500 to-orange-400 group-hover:from-pink-500 group-hover:to-orange-400 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-pink-200 dark:focus:ring-pink-800',
'purple-blue': 'relative inline-flex items-center justify-center overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-purple-600 to-blue-500 group-hover:from-purple-600 group-hover:to-blue-500 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-blue-300 dark:focus:ring-blue-800',
'purple-pink': 'relative inline-flex items-center justify-center overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-purple-500 to-pink-500 group-hover:from-purple-500 group-hover:to-pink-500 hover:text-white dark:text-white focus:ring-4 focus:outline-none focus:ring-purple-200 dark:focus:ring-purple-800',
'red-yellow': 'relative inline-flex items-center justify-center overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-red-200 via-red-300 to-yellow-200 group-hover:from-red-200 group-hover:via-red-300 group-hover:to-yellow-200 dark:text-white dark:hover:text-gray-900 focus:ring-4 focus:outline-none focus:ring-red-100 dark:focus:ring-red-400',
'teal-lime': 'relative inline-flex items-center justify-center overflow-hidden font-medium text-gray-900 rounded-lg group bg-gradient-to-br from-teal-300 to-lime-300 group-hover:from-teal-300 group-hover:to-lime-300 dark:text-white dark:hover:text-gray-900 focus:ring-4 focus:outline-none focus:ring-lime-200 dark:focus:ring-lime-800',
}
const buttonSizeClasses: Record<ButtonSize, string> = { const buttonSizeClasses: Record<ButtonSize, string> = {
xs: 'text-xs px-2 py-1', xs: 'text-xs px-2 py-1',
sm: 'text-sm px-3 py-1.5', sm: 'text-sm px-3 py-1.5',
@@ -113,4 +159,14 @@ const buttonSizeClasses: Record<ButtonSize, string> = {
xl: 'text-base px-6 py-3', xl: 'text-base px-6 py-3',
} }
const buttonShadowClasses: Record<ButtonMonochromeGradient, string> = {
'blue': 'shadow-lg shadow-blue-500/50 dark:shadow-lg dark:shadow-blue-800/80',
'cyan': 'shadow-lg shadow-cyan-500/50 dark:shadow-lg dark:shadow-cyan-800/80',
'green': 'shadow-lg shadow-green-500/50 dark:shadow-lg dark:shadow-green-800/80',
'lime': 'shadow-lg shadow-lime-500/50 dark:shadow-lg dark:shadow-lime-800/80',
'pink': 'shadow-lg shadow-pink-500/50 dark:shadow-lg dark:shadow-pink-800/80',
'purple': 'shadow-lg shadow-purple-500/50 dark:shadow-lg dark:shadow-purple-800/80',
'red': 'shadow-lg shadow-red-500/50 dark:shadow-lg dark:shadow-red-800/80',
'teal': 'shadow-lg shadow-teal-500/50 dark:shadow-lg dark:shadow-teal-800/80',
}
</script> </script>