Add Link and InlineLink reusable components

Link wraps RouterLink or <a> with consistent styling and automatic rel attributes. InlineLink adds bold italic inline link styling.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-25 02:43:12 +00:00
parent 8627a7945e
commit c2bbd7ad88
2 changed files with 77 additions and 0 deletions

View File

@@ -0,0 +1,39 @@
<script setup>
import { computed } from "vue";
const props = defineProps({
href: { type: String, default: "" },
to: { type: String, default: "" },
target: { type: String, default: undefined },
rel: { type: String, default: undefined },
});
const computedRel = computed(() => {
if (props.rel !== undefined) return props.rel;
if (props.target === "_blank") return "noopener noreferrer";
return undefined;
});
</script>
<template>
<RouterLink v-if="to" :to="to" class="inline-link">
<slot />
</RouterLink>
<a v-else :href="href" :target="target" :rel="computedRel" class="inline-link">
<slot />
</a>
</template>
<style scoped>
.inline-link {
color: var(--primary);
font-weight: bold;
font-style: italic;
text-decoration: none;
transition: color 0.15s ease;
}
.inline-link:hover {
color: var(--tertiary);
}
</style>

View File

@@ -0,0 +1,38 @@
<script setup>
import { computed } from "vue";
const props = defineProps({
href: { type: String, default: "" },
to: { type: String, default: "" },
target: { type: String, default: undefined },
rel: { type: String, default: undefined },
bare: { type: Boolean, default: false },
});
const computedRel = computed(() => {
if (props.rel !== undefined) return props.rel;
if (props.target === "_blank") return "noopener noreferrer";
return undefined;
});
</script>
<template>
<RouterLink v-if="to" :to="to" :class="{ link: !bare }">
<slot />
</RouterLink>
<a v-else :href="href" :target="target" :rel="computedRel" :class="{ link: !bare }">
<slot />
</a>
</template>
<style scoped>
.link {
color: var(--primary);
text-decoration: none;
transition: color 0.15s ease;
}
.link:hover {
color: var(--tertiary);
}
</style>