mirror of
https://github.com/kogakure/website-astro-stefanimhoff.de.git
synced 2026-02-03 20:15:27 +00:00
feat(astro): create Link component
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
---
|
||||
import { Sprite } from 'astro-icon';
|
||||
import Link from '../components/Link.astro';
|
||||
|
||||
export interface Props {
|
||||
backLink?: string;
|
||||
@@ -10,7 +11,7 @@ const { backLink } = Astro.props;
|
||||
|
||||
{
|
||||
backLink && (
|
||||
<a
|
||||
<Link
|
||||
class="col-span-2 col-start-1 h-clickarea w-clickarea items-center justify-center self-center justify-self-center transition-transform duration-500 ease-in-out hover:-translate-x-1 focus:-translate-x-1 print:hidden md:col-span-1"
|
||||
href={backLink}
|
||||
>
|
||||
@@ -21,6 +22,6 @@ const { backLink } = Astro.props;
|
||||
>
|
||||
<Sprite name="ri:arrow-left-line" class="h-icon w-icon" />
|
||||
</button>
|
||||
</a>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
22
src/components/Link.astro
Normal file
22
src/components/Link.astro
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
import type { HTMLAttributes } from 'astro/types';
|
||||
|
||||
type Props = HTMLAttributes<'a'>;
|
||||
|
||||
const props = { ...Astro.props };
|
||||
const { class: className } = props;
|
||||
|
||||
if (typeof props.href !== 'string') props.href = '#';
|
||||
|
||||
const isExternal = props.href.startsWith('http');
|
||||
---
|
||||
|
||||
<a
|
||||
class:list={['link', className, { external: isExternal }]}
|
||||
href={props.href}
|
||||
rel={isExternal ? 'nofollow noopener noreferrer' : null}
|
||||
target={isExternal ? '_blank' : null}
|
||||
{...props}
|
||||
>
|
||||
<slot />
|
||||
</a>
|
||||
@@ -1,4 +1,6 @@
|
||||
---
|
||||
import Link from './Link.astro';
|
||||
|
||||
import navigation from '../data/navigation.json';
|
||||
|
||||
const currentPath = new URL(Astro.request.url).pathname;
|
||||
@@ -9,14 +11,14 @@ const currentPath = new URL(Astro.request.url).pathname;
|
||||
{
|
||||
navigation.map(({ title, url }) => (
|
||||
<li class="mie-[10px] xs:mie-[15px]">
|
||||
<a
|
||||
<Link
|
||||
class={`text-3 font-light decoration-4 underline-offset-auto hover:underline hover:decoration-shibui-900/20 dark:hover:decoration-shibui-100/20 ${
|
||||
currentPath === url && 'underline !decoration-accent decoration-4'
|
||||
}`}
|
||||
href={url}
|
||||
>
|
||||
{title}
|
||||
</a>
|
||||
</Link>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
import { Sprite } from 'astro-icon';
|
||||
|
||||
import Link from './Link.astro';
|
||||
import Subsubheadline from './Subsubheadline.astro';
|
||||
---
|
||||
|
||||
@@ -8,13 +9,12 @@ import Subsubheadline from './Subsubheadline.astro';
|
||||
<Subsubheadline>Stay up to date.</Subsubheadline>
|
||||
<p>
|
||||
<Sprite name="ri:rss-fill" class="h-icon w-icon inline" />
|
||||
<a
|
||||
<Link
|
||||
class="font-light decoration-4 underline-offset-auto hover:underline hover:decoration-shibui-900/20 dark:hover:decoration-shibui-100/20"
|
||||
href="/rss.xml"
|
||||
rel="nofollow noopener noreferrer external"
|
||||
target="_blank"
|
||||
>
|
||||
Subscribe via RSS
|
||||
</a>
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
---
|
||||
import { Sprite } from 'astro-icon';
|
||||
|
||||
import Link from './Link.astro';
|
||||
|
||||
import data from '../data/social-links.json';
|
||||
---
|
||||
|
||||
<div class="flex flex-1 sm:justify-center">
|
||||
{
|
||||
data.map(({ text, url, icon, props = {} }) => (
|
||||
<a
|
||||
<Link
|
||||
aria-label={text}
|
||||
class="flex h-clickarea w-clickarea cursor-pointer items-center justify-center"
|
||||
href={url}
|
||||
rel="nofollow noopener noreferrer external"
|
||||
target="_blank"
|
||||
title={text}
|
||||
{...props}
|
||||
>
|
||||
<Sprite name={icon} class="h-icon-small w-icon-small" />
|
||||
</a>
|
||||
</Link>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
import data from '../data/subnavigation.json';
|
||||
|
||||
import Link from './Link.astro';
|
||||
|
||||
const currentPath = new URL(Astro.request.url).pathname;
|
||||
---
|
||||
|
||||
@@ -9,14 +11,14 @@ const currentPath = new URL(Astro.request.url).pathname;
|
||||
{
|
||||
data.main.map(({ title, url }) => (
|
||||
<li>
|
||||
<a
|
||||
<Link
|
||||
href={url}
|
||||
class={`font-light decoration-4 underline-offset-auto hover:underline hover:decoration-shibui-900/20 dark:hover:decoration-shibui-100/20 ${
|
||||
currentPath === url && 'underline !decoration-accent decoration-4'
|
||||
}`}
|
||||
>
|
||||
{title}
|
||||
</a>
|
||||
</Link>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
@@ -25,14 +27,14 @@ const currentPath = new URL(Astro.request.url).pathname;
|
||||
{
|
||||
data.misc.map(({ title, url }) => (
|
||||
<li>
|
||||
<a
|
||||
<Link
|
||||
href={url}
|
||||
class={`font-light decoration-4 underline-offset-auto hover:underline hover:decoration-shibui-900/20 dark:hover:decoration-shibui-100/20 ${
|
||||
currentPath === url && 'underline !decoration-accent decoration-4'
|
||||
}`}
|
||||
>
|
||||
{title}
|
||||
</a>
|
||||
</Link>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
---
|
||||
import { Sprite } from 'astro-icon';
|
||||
|
||||
import Link from './Link.astro';
|
||||
---
|
||||
|
||||
<div class="flex flex-1 justify-end">
|
||||
<a
|
||||
<Link
|
||||
id="up-link"
|
||||
class="transition-transform duration-500 ease-in-out hover:-translate-y-1 focus:-translate-y-1"
|
||||
href="#top"
|
||||
@@ -14,7 +16,7 @@ import { Sprite } from 'astro-icon';
|
||||
>
|
||||
<Sprite name="ri:arrow-up-line" class="h-icon-small w-icon-small" />
|
||||
</button>
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
<script>
|
||||
const button = document.getElementById('up-link');
|
||||
|
||||
Reference in New Issue
Block a user