funkwhale/front/src/components/ui/Link.vue

85 lines
1.8 KiB
Vue

<script setup lang="ts">
import { computed } from 'vue'
import { type RouterLinkProps, RouterLink } from 'vue-router'
import { type ColorProps, type VariantProps, propsToColor } from '~/composables/colors';
const { to, icon, inline, round, ...otherProps } = defineProps<RouterLinkProps
& {
icon?: string;
round?: boolean
inline?: true
} & ColorProps & VariantProps>()
const isExternalLink = computed(() => {
return typeof to === 'string' && to.startsWith('http')
})
</script>
<template>
<a v-if="isExternalLink"
v-bind="propsToColor(otherProps)"
:class="[
'interactive',
$style.link,
$style.external,
round && $style['is-round']
]"
:href="to?.toString()"
target="_blank"
>
<i v-if="icon" :class="['bi', icon]" />
<slot />
</a>
<RouterLink v-else
:to="to"
v-bind="propsToColor(otherProps)"
:class="[
'interactive',
$style.link,
round && $style['is-round']
]"
>
<i v-if="icon" :class="['bi', icon]" />
<slot />
</RouterLink>
</template>
<style module lang="scss">
.active { outline: 3px solid red; }
.external { outline: 3px dotted blue; }
.link {
display: inline-flex;
align-items: center;
white-space: nowrap;
font-family: $font-main;
font-weight: 900;
font-size: 0.875em;
line-height: 1em;
padding: 0.642857142857em;
border-radius: var(--fw-border-radius);
margin: 0 0.5ch;
transform: translateX(var(--fw-translate-x)) translateY(var(--fw-translate-y)) scale(var(--fw-scale));
transition:background-color .3s, border-color .2s;
i {
margin-right:1ch;
font-size:1.4em;
}
&:not(:hover):not(:global(.active)) {
text-decoration:none;
background-color:transparent;
border-color:transparent;
}
&.is-round {
border-radius: 100vh;
}
}
</style>