mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-30 11:47:55 +01:00
chore(Avatar): use preset system
This commit is contained in:
@@ -68,7 +68,9 @@ const components = [
|
|||||||
{
|
{
|
||||||
label: 'Avatar',
|
label: 'Avatar',
|
||||||
to: '/components/Avatar',
|
to: '/components/Avatar',
|
||||||
nuxt3: true
|
nuxt3: true,
|
||||||
|
preset: true,
|
||||||
|
capi: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'AvatarGroup',
|
label: 'AvatarGroup',
|
||||||
|
|||||||
@@ -93,6 +93,9 @@ export default defineNuxtModule<ModuleOptions>({
|
|||||||
// Safelist dynamic colors used in preset
|
// Safelist dynamic colors used in preset
|
||||||
safelist: [
|
safelist: [
|
||||||
'dark',
|
'dark',
|
||||||
|
{
|
||||||
|
pattern: new RegExp(`bg-(${safeColorsAsRegex})-400`)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
pattern: new RegExp(`bg-(${safeColorsAsRegex})-(100|600|700)`),
|
pattern: new RegExp(`bg-(${safeColorsAsRegex})-(100|600|700)`),
|
||||||
variants: ['hover', 'disabled', 'dark']
|
variants: ['hover', 'disabled', 'dark']
|
||||||
|
|||||||
@@ -1,151 +1,100 @@
|
|||||||
<template>
|
<template>
|
||||||
<span class="relative inline-flex items-center justify-center" :class="avatarClass" @click="goto">
|
<span :class="wrapperClass">
|
||||||
<img v-if="url" :src="url" :alt="alt" :class="[sizeClass, roundedClass]">
|
<img v-if="src" :class="avatarClass" :src="src" :alt="alt">
|
||||||
<span
|
<span v-else-if="text || placeholder" :class="placeholderClass">{{ text || placeholder }}</span>
|
||||||
v-else-if="placeholder"
|
|
||||||
class="font-medium leading-none uppercase u-text-gray-900"
|
|
||||||
>{{ placeholder }}</span>
|
|
||||||
<span
|
|
||||||
v-else-if="text"
|
|
||||||
>{{ text }}</span>
|
|
||||||
<svg
|
|
||||||
v-else
|
|
||||||
class="w-full h-full u-text-gray-300"
|
|
||||||
:class="roundedClass"
|
|
||||||
fill="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M24 20.993V24H0v-2.996A14.977 14.977 0 0112.004 15c4.904 0 9.26 2.354 11.996 5.993zM16.002 8.999a4 4 0 11-8 0 4 4 0 018 0z"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
|
|
||||||
|
<span v-if="chip" :class="chipClass" />
|
||||||
<slot />
|
<slot />
|
||||||
|
|
||||||
<span
|
|
||||||
v-if="status"
|
|
||||||
class="absolute top-0 right-0 block rounded-full ring-1 u-ring-white"
|
|
||||||
:class="statusClass"
|
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
export default {
|
import { computed } from 'vue'
|
||||||
props: {
|
import { classNames } from '../../utils'
|
||||||
src: {
|
import $ui from '#build/ui'
|
||||||
type: [String, Boolean],
|
|
||||||
default: null
|
const props = defineProps({
|
||||||
},
|
src: {
|
||||||
text: {
|
type: [String, Boolean],
|
||||||
type: String,
|
default: null
|
||||||
default: null
|
},
|
||||||
},
|
alt: {
|
||||||
alt: {
|
type: String,
|
||||||
type: String,
|
default: null
|
||||||
default: null
|
},
|
||||||
},
|
text: {
|
||||||
to: {
|
type: String,
|
||||||
type: String,
|
default: null
|
||||||
default: null
|
},
|
||||||
},
|
size: {
|
||||||
size: {
|
type: String,
|
||||||
type: String,
|
default: 'md',
|
||||||
default: 'md',
|
validator (value) {
|
||||||
validator (value) {
|
return Object.keys($ui.avatar.size).includes(value)
|
||||||
return ['xxxs', 'xxs', 'xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl'].includes(value)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
rounded: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
status: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
validator (value) {
|
|
||||||
return ['online', 'idle', 'invisible', 'donotdisturb', 'focus'].includes(value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
rounded: {
|
||||||
url () {
|
type: Boolean,
|
||||||
if (typeof this.src === 'boolean') {
|
default: true
|
||||||
return null
|
},
|
||||||
}
|
chip: {
|
||||||
return this.src
|
type: Boolean,
|
||||||
},
|
default: false
|
||||||
placeholder () {
|
},
|
||||||
if (!this.alt) {
|
chipVariant: {
|
||||||
return
|
type: String,
|
||||||
}
|
default: 'primary',
|
||||||
return this.alt.split(' ').map(word => word.charAt(0)).join('').substr(0, 2)
|
validator (value) {
|
||||||
},
|
return Object.keys($ui.avatar.chip.variant).includes(value)
|
||||||
sizeClass () {
|
|
||||||
return ({
|
|
||||||
xxxs: 'h-4 w-4 text-xs',
|
|
||||||
xxs: 'h-5 w-5 text-xs',
|
|
||||||
xs: 'h-6 w-6 text-xs',
|
|
||||||
sm: 'h-8 w-8 text-sm',
|
|
||||||
md: 'h-10 w-10 text-md',
|
|
||||||
lg: 'h-12 w-12 text-lg',
|
|
||||||
xl: 'h-14 w-14 text-xl',
|
|
||||||
'2xl': 'h-16 w-16 text-2xl',
|
|
||||||
'3xl': 'h-20 w-20 text-3xl'
|
|
||||||
})[this.size]
|
|
||||||
},
|
|
||||||
roundedClass () {
|
|
||||||
return ({
|
|
||||||
true: 'rounded-lg',
|
|
||||||
false: 'rounded-full'
|
|
||||||
})[this.rounded]
|
|
||||||
},
|
|
||||||
placeholderClass () {
|
|
||||||
return ({
|
|
||||||
true: 'u-bg-gray-100',
|
|
||||||
false: 'u-bg-gray-100'
|
|
||||||
})[!!this.alt]
|
|
||||||
},
|
|
||||||
avatarClass () {
|
|
||||||
return [
|
|
||||||
this.sizeClass,
|
|
||||||
this.roundedClass,
|
|
||||||
this.placeholderClass,
|
|
||||||
this.to ? 'cursor-pointer' : ''
|
|
||||||
].join(' ')
|
|
||||||
},
|
|
||||||
statusClass () {
|
|
||||||
return [
|
|
||||||
({
|
|
||||||
online: 'bg-green-400',
|
|
||||||
idle: 'bg-yellow-400',
|
|
||||||
invisible: 'u-bg-gray-300',
|
|
||||||
donotdisturb: 'bg-red-400',
|
|
||||||
focus: 'bg-primary-500'
|
|
||||||
})[this.status],
|
|
||||||
({
|
|
||||||
xxxs: 'h-1 w-1',
|
|
||||||
xxs: 'h-1 w-1',
|
|
||||||
xs: 'h-1.5 w-1.5',
|
|
||||||
sm: 'h-2 w-2',
|
|
||||||
md: 'h-2.5 w-2.5',
|
|
||||||
lg: 'h-3 w-3',
|
|
||||||
xl: 'h-3.5 w-3.5',
|
|
||||||
'2xl': 'h-3.5 w-3.5',
|
|
||||||
'3xl': 'h-4 w-4'
|
|
||||||
})[this.size],
|
|
||||||
({
|
|
||||||
true: 'transform -translate-y-1/2 translate-x-1/2'
|
|
||||||
})[this.rounded]
|
|
||||||
].join(' ')
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
chipPosition: {
|
||||||
goto (e) {
|
type: String,
|
||||||
if (!this.to || !this.$router) { return }
|
default: 'top-right',
|
||||||
e.preventDefault()
|
validator (value) {
|
||||||
this.$router.push(this.to)
|
return Object.keys($ui.avatar.chip.position).includes(value)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
wrapperClass: {
|
||||||
|
type: String,
|
||||||
|
default: () => $ui.avatar.wrapper
|
||||||
|
},
|
||||||
|
backgroundClass: {
|
||||||
|
type: String,
|
||||||
|
default: () => $ui.avatar.background
|
||||||
|
},
|
||||||
|
placeholderClass: {
|
||||||
|
type: String,
|
||||||
|
default: () => $ui.avatar.placeholder
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
|
const wrapperClass = computed(() => {
|
||||||
|
return classNames(
|
||||||
|
props.wrapperClass,
|
||||||
|
props.backgroundClass,
|
||||||
|
$ui.avatar.size[props.size],
|
||||||
|
props.rounded ? 'rounded-full' : 'rounded-md'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const avatarClass = computed(() => {
|
||||||
|
return classNames(
|
||||||
|
$ui.avatar.size[props.size],
|
||||||
|
props.rounded ? 'rounded-full' : 'rounded-md'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const chipClass = computed(() => {
|
||||||
|
return classNames(
|
||||||
|
$ui.avatar.chip.base,
|
||||||
|
$ui.avatar.chip.position[props.chipPosition],
|
||||||
|
$ui.avatar.chip.variant[props.chipVariant],
|
||||||
|
$ui.avatar.chip.size[props.size]
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const placeholder = computed(() => {
|
||||||
|
return (props.alt || '').split(' ').map(word => word.charAt(0)).join('').substr(0, 2)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -307,6 +307,49 @@ const pills = {
|
|||||||
inactive: 'u-text-gray-500 hover:u-text-gray-700'
|
inactive: 'u-text-gray-500 hover:u-text-gray-700'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const avatar = {
|
||||||
|
wrapper: 'relative inline-flex items-center justify-center',
|
||||||
|
background: 'u-bg-gray-100',
|
||||||
|
placeholder: 'text-xs font-medium leading-none u-text-black',
|
||||||
|
size: {
|
||||||
|
xxxs: 'h-4 w-4 text-xs',
|
||||||
|
xxs: 'h-5 w-5 text-xs',
|
||||||
|
xs: 'h-6 w-6 text-xs',
|
||||||
|
sm: 'h-8 w-8 text-sm',
|
||||||
|
md: 'h-10 w-10 text-md',
|
||||||
|
lg: 'h-12 w-12 text-lg',
|
||||||
|
xl: 'h-14 w-14 text-xl',
|
||||||
|
'2xl': 'h-16 w-16 text-2xl',
|
||||||
|
'3xl': 'h-20 w-20 text-3xl'
|
||||||
|
},
|
||||||
|
chip: {
|
||||||
|
base: 'absolute block rounded-full ring-2 u-ring-white',
|
||||||
|
position: {
|
||||||
|
'top-right': 'top-0 right-0',
|
||||||
|
'bottom-right': 'bottom-0 right-0',
|
||||||
|
'top-left': 'top-0 left-0',
|
||||||
|
'bottom-left': 'bottom-0 left-0'
|
||||||
|
},
|
||||||
|
variant: {
|
||||||
|
...safeColors.reduce((acc: any, color) => {
|
||||||
|
acc[color] = `bg-${color}-400`
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
xxxs: 'h-1 w-1',
|
||||||
|
xxs: 'h-1 w-1',
|
||||||
|
xs: 'h-1.5 w-1.5',
|
||||||
|
sm: 'h-2 w-2',
|
||||||
|
md: 'h-2.5 w-2.5',
|
||||||
|
lg: 'h-3 w-3',
|
||||||
|
xl: 'h-3.5 w-3.5',
|
||||||
|
'2xl': 'h-3.5 w-3.5',
|
||||||
|
'3xl': 'h-4 w-4'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
card,
|
card,
|
||||||
button,
|
button,
|
||||||
@@ -324,5 +367,6 @@ export default {
|
|||||||
alertDialog,
|
alertDialog,
|
||||||
dropdown,
|
dropdown,
|
||||||
tabs,
|
tabs,
|
||||||
pills
|
pills,
|
||||||
|
avatar
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user