Merge branch 'main' into breadcrumb-component

# Conflicts:
#	docs/.vitepress/config.ts
This commit is contained in:
Ilya Sosidka
2022-09-17 18:00:47 +03:00
11 changed files with 266 additions and 31 deletions

View File

@@ -38,6 +38,7 @@ function getComponents() {
{ text: 'Avatar', link: 'components/avatar/avatar.md' },
{ text: 'Breadcrumb', link: 'components/breadcrumb/breadcrumb.md' },
{ text: 'Button', link: '/components/button/button.md' },
{ text: 'Badge', link: 'components/badge/badge.md' },
{ text: 'Button Group', link: '/components/buttonGroup/buttonGroup.md' },
{ text: 'Dropdown', link: '/components/dropdown/dropdown.md' },
{ text: 'Spinner', link: '/components/spinner/spinner.md' },
@@ -46,7 +47,7 @@ function getComponents() {
{ text: 'Toast', link: 'components/toast/toast.md' },
{ text: '- Accordion', link: 'components/accordion/accordion.md' },
{ text: '- Badge', link: 'components/badge/badge.md' },
{ text: '- Breadcrumb', link: 'components/breadcrumb/breadcrumb.md' },
{ text: '- Card', link: 'components/card/card.md' },
{ text: '- Carousel', link: 'components/carousel/carousel.md' },
{ text: '- Footer', link: 'components/footer/footer.md' },

View File

@@ -1,15 +1,114 @@
<script setup>
import BadgeExample from './examples/BadgeExample.vue'
import BadgeTypesExample from './examples/BadgeTypesExample.vue'
import BadgeSizesExample from './examples/BadgeSizesExample.vue'
import BadgeLinksExample from './examples/BadgeLinksExample.vue'
import BadgeIconsExample from './examples/BadgeIconsExample.vue'
import BadgeOnlyIconsExample from './examples/BadgeOnlyIconsExample.vue'
</script>
# Badge
#### Use Tailwind CSS badges as elements to show counts or labels separately or inside other components
---
:::tip
Original reference: [https://flowbite.com/docs/components/badge/](https://flowbite.com/docs/components/badge/)
:::
The badge component can be used to complement other elements such as buttons or text elements as a label or to show the count of a given data, such as the number of comments for an article or how much time has passed by since a comment has been made.
Alternatively, badges can also be used as standalone elements that link to a certain page by using the anchor tag instead of a span element.
## Default badge
Prop type
<BadgeTypesExample />
```vue
<script setup>
import { Badge } from 'flowbite-vue'
</script>
<template>
<Badge></Badge>
<Badge />
<Badge type="dark" />
<Badge type="red" />
<Badge type="green" />
<Badge type="yellow" />
<Badge type="indigo" />
<Badge type="purple" />
<Badge type="pink" />
</template>
```
<BadgeExample />
## Large badges
Prop size
<BadgeSizesExample />
```vue
<script setup>
import { Badge } from 'flowbite-vue'
</script>
<template>
<Badge />
<Badge type="dark" />
<Badge type="red" />
<Badge type="green" />
<Badge type="yellow" />
<Badge type="indigo" />
<Badge type="purple" />
<Badge type="pink" />
</template>
```
## Badges as links
You can also use badges as anchor elements to link to another page.
Prop href
```vue
<script setup>
import { Badge } from 'flowbite-vue'
</script>
<template>
<Badge href="#">Link</Badge>
</template>
```
<BadgeLinksExample />
## Badges with icon
You can also use SVG icons inside the badge elements.
slot icon
```vue
<script setup>
import { Badge } from 'flowbite-vue'
</script>
<template>
<Badge>
<template #icon>
<svg aria-hidden="true" class="mr-1 w-3 h-3" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd"></path></svg>
</template>
Default
</Badge>
</template>
```
<BadgeIconsExample />
## Badge with icon only
```vue
<script setup>
import { Badge } from 'flowbite-vue'
</script>
<template>
<Badge>
<template #icon>
<svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd"></path></svg>
</template>
</Badge>
</template>
```
<BadgeOnlyIconsExample />

View File

@@ -1,8 +0,0 @@
<template>
<div class="vp-raw flex flex-col">
<Badge></Badge>
</div>
</template>
<script setup>
import { Badge } from '../../../../src/index'
</script>

View File

@@ -0,0 +1,19 @@
<template>
<div class="vp-raw flex items-end">
<Badge>
<template #icon>
<svg aria-hidden="true" class="mr-1 w-3 h-3" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd"></path></svg>
</template>
Default
</Badge>
<Badge type="dark" size="sm">
<template #icon>
<svg aria-hidden="true" class="mr-1 w-3 h-3" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd"></path></svg>
</template>
Dark
</Badge>
</div>
</template>
<script setup>
import Badge from '@/components/Badge/Badge.vue'
</script>

View File

@@ -0,0 +1,9 @@
<template>
<div class="vp-raw flex items-end">
<Badge href="#">Link</Badge>
<Badge size="sm" href="#">Link</Badge>
</div>
</template>
<script setup>
import { Badge } from '../../../../src/index'
</script>

View File

@@ -0,0 +1,22 @@
<template>
<div class="vp-raw flex items-end">
<Badge>
<template #icon>
<svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd"></path></svg>
</template>
</Badge>
<Badge type="dark">
<template #icon>
<svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd"></path></svg>
</template>
</Badge>
<Badge type="green" size="sm">
<template #icon>
<svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd"></path></svg>
</template>
</Badge>
</div>
</template>
<script setup>
import Badge from '@/components/Badge/Badge.vue'
</script>

View File

@@ -0,0 +1,15 @@
<template>
<div class="vp-raw flex">
<Badge size="sm">Default</Badge>
<Badge type="dark" size="sm">Dark</Badge>
<Badge type="red" size="sm">Red</Badge>
<Badge type="green" size="sm">Green</Badge>
<Badge type="yellow" size="sm">Yellow</Badge>
<Badge type="indigo" size="sm">Indigo</Badge>
<Badge type="purple" size="sm">Purple</Badge>
<Badge type="pink" size="sm">Pink</Badge>
</div>
</template>
<script setup>
import { Badge } from '../../../../src/index'
</script>

View File

@@ -0,0 +1,15 @@
<template>
<div class="vp-raw flex">
<Badge>Default</Badge>
<Badge type="dark">Dark</Badge>
<Badge type="red">Red</Badge>
<Badge type="green">Green</Badge>
<Badge type="yellow">Yellow</Badge>
<Badge type="indigo">Indigo</Badge>
<Badge type="purple">Purple</Badge>
<Badge type="pink">Pink</Badge>
</div>
</template>
<script setup>
import { Badge } from '../../../../src/index'
</script>

View File

@@ -1,33 +1,33 @@
<template>
<span class="bg-blue-100 text-blue-800 text-xs font-semibold mr-2 px-2.5 py-0.5 rounded dark:bg-blue-200 dark:text-blue-800">Default</span>
<component :is="wrapperType" :class="badgeClasses" :href="href">
<slot name="icon"/>
<slot name="default" />
</component>
</template>
<script lang="ts" setup>
import { computed, toRefs } from 'vue'
import { computed, toRefs, useSlots } from 'vue'
import type { PropType } from 'vue'
import type { BadgeType, BadgeSize } from './types'
import { useBadgeClasses } from '@/components/Badge/composables/useBadgeClasses'
const props = defineProps({
children: {
type: Array,
default() {
return []
},
type: {
type: String as PropType<BadgeType>,
default: 'default',
},
color: {
type: String, // 'failure' | 'gray' | 'indigo' | 'info' | 'pink' | 'purple' | 'success'
default: 'info',
size: {
type: String as PropType<BadgeSize>,
default: 'xs',
},
href: {
type: String,
default: '',
},
icon: {
type: String,
default: '',
},
size: {
type: String, // 'xs' | 'sm'
default: 'xs',
default: null,
},
})
const slots = useSlots()
const isContentEmpty = computed(() => !slots.default)
const wrapperType = computed(() => props.href ? 'a' : 'span')
const { badgeClasses } = useBadgeClasses(toRefs(props), { isContentEmpty })
</script>

View File

@@ -0,0 +1,61 @@
import type { BadgeType, BadgeSize } from '../types'
import { computed } from 'vue'
import type { Ref } from 'vue'
import classNames from 'classnames'
const defaultBadgeClasses = 'mr-2 px-2.5 py-0.5 rounded flex items-center justify-center'
const badgeLinkClasses = 'bg-blue-100 hover:bg-blue-200 text-blue-800 dark:text-blue-800 dark:hover:bg-blue-300'
const onlyIconClasses = 'p-1 rounded-full mr-2'
const badgeTextClasses: Record<BadgeType, string> = {
default: 'text-blue-800 dark:text-blue-800',
dark: 'text-gray-800 dark:bg-gray-700',
red: 'text-red-800 dark:text-red-900',
green: 'text-green-800 dark:text-green-900',
yellow: 'text-yellow-800 dark:text-yellow-900',
indigo: 'text-indigo-800 dark:text-indigo-900',
purple: 'text-purple-800 dark:text-purple-900',
pink: 'text-pink-800 dark:text-pink-900',
}
const badgeTypeClasses: Record<BadgeType, string> = {
default: 'bg-blue-100 dark:bg-blue-200',
dark: 'bg-gray-100 dark:bg-gray-700',
red: 'bg-red-100 dark:bg-red-200',
green: 'bg-green-100 dark:bg-green-200',
yellow: 'bg-yellow-100 dark:bg-yellow-200',
indigo: 'bg-indigo-100 dark:bg-indigo-200',
purple: 'bg-purple-100 dark:bg-purple-200',
pink: 'bg-pink-100 dark:bg-pink-200',
}
const badgeSizeClasses: Record<BadgeSize, string> = {
xs: 'text-xs font-semibold',
sm: 'text-sm font-medium',
}
export type UseBadgeClassesProps = {
type: Ref<BadgeType>
size: Ref<BadgeSize>
href: Ref<string>
}
export type UseBadgeClassesOptions = {
isContentEmpty: Ref<boolean>
}
export function useBadgeClasses(props: UseBadgeClassesProps, options: UseBadgeClassesOptions): {
badgeClasses: Ref<string>
} {
const badgeClasses = computed<string>(() => {
return classNames(
badgeSizeClasses[props.size.value],
props.href.value ? '' : badgeTypeClasses[props.type.value],
props.href.value ? '' : badgeTextClasses[props.type.value],
props.href.value ? badgeLinkClasses : '',
options.isContentEmpty.value ? onlyIconClasses : defaultBadgeClasses,
)
})
return {
badgeClasses,
}
}

View File

@@ -0,0 +1,2 @@
export type BadgeType = 'default' | 'dark' | 'red' | 'green' | 'yellow' | 'indigo' | 'purple' | 'pink'
export type BadgeSize = 'xs' | 'sm'