mirror of
https://github.com/kogakure/website-astro-stefanimhoff.de.git
synced 2026-02-03 20:15:27 +00:00
refactor: migrate components to Preact
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
---
|
||||
import { Sprite } from 'astro-icon';
|
||||
import Link from '../components/Link.astro';
|
||||
|
||||
import { Link } from '../components';
|
||||
|
||||
export interface Props {
|
||||
backLink?: string;
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
interface Props {
|
||||
as?: string;
|
||||
children?: any;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
const { as = 'h2', class: className, ...props } = Astro.props;
|
||||
const Element = as;
|
||||
---
|
||||
|
||||
<Element
|
||||
class:list={[
|
||||
'text-5 font-black tracking-tight mbe-10 mbs-16 first-of-type:mbs-0 dark:font-extrabold',
|
||||
className,
|
||||
]}
|
||||
{...props}
|
||||
>
|
||||
<slot />
|
||||
</Element>
|
||||
28
src/components/Headline.tsx
Normal file
28
src/components/Headline.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import cx from 'classnames';
|
||||
|
||||
import type { ComponentChild, FunctionalComponent } from 'preact';
|
||||
|
||||
interface Props {
|
||||
as?: any;
|
||||
class?: string;
|
||||
children: ComponentChild;
|
||||
}
|
||||
|
||||
export const Headline: FunctionalComponent<Props> = ({
|
||||
as = 'h2',
|
||||
class: className,
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
const Tag = as;
|
||||
const classes = cx(
|
||||
'text-5 font-black tracking-tight mbe-10 mbs-16 first-of-type:mbs-0 dark:font-extrabold',
|
||||
className
|
||||
);
|
||||
|
||||
return (
|
||||
<Tag class={classes} {...props}>
|
||||
{children}
|
||||
</Tag>
|
||||
);
|
||||
};
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
import { LegalDate } from './LegalDate';
|
||||
import { LegalDate } from '.';
|
||||
|
||||
import { site } from '../data/site';
|
||||
---
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
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>
|
||||
27
src/components/Link.tsx
Normal file
27
src/components/Link.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import cx from 'classnames';
|
||||
|
||||
import type { FunctionalComponent, JSX } from 'preact';
|
||||
|
||||
interface Props extends JSX.HTMLAttributes<HTMLAnchorElement> {}
|
||||
|
||||
export const Link: FunctionalComponent<Props> = ({
|
||||
class: className,
|
||||
children,
|
||||
href = '#',
|
||||
...props
|
||||
}: Props) => {
|
||||
const isExternal = (href as string).startsWith('http');
|
||||
const classes = cx('link', { external: isExternal }, className as string);
|
||||
|
||||
return (
|
||||
<a
|
||||
class={classes}
|
||||
href={href}
|
||||
rel={isExternal ? 'nofollow noopener noreferrer' : undefined}
|
||||
target={isExternal ? '_blank' : undefined}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
};
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
import Link from './Link.astro';
|
||||
import cx from 'classnames';
|
||||
|
||||
import { Link } from '.';
|
||||
|
||||
import navigation from '../data/navigation.json';
|
||||
|
||||
@@ -12,9 +14,10 @@ const currentPath = new URL(Astro.request.url).pathname;
|
||||
navigation.map(({ title, url }) => (
|
||||
<li class="mie-[10px] xs:mie-[15px]">
|
||||
<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'
|
||||
}`}
|
||||
class={cx(
|
||||
'text-3 font-light decoration-4 underline-offset-auto hover:underline hover:decoration-shibui-900/20 dark:hover:decoration-shibui-100/20',
|
||||
{ 'underline !decoration-accent decoration-4': currentPath === url }
|
||||
)}
|
||||
href={url}
|
||||
>
|
||||
{title}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
import RSSLink from './RSSLink.astro';
|
||||
import Subnavigation from './Subnavigation.astro';
|
||||
import Legal from './Legal.astro';
|
||||
import RSSLink from './RSSLink.astro';
|
||||
import SocialLinks from './SocialLinks.astro';
|
||||
import Subnavigation from './Subnavigation.astro';
|
||||
import UpLink from './UpLink.astro';
|
||||
---
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
---
|
||||
import { Sprite } from 'astro-icon';
|
||||
|
||||
import Link from './Link.astro';
|
||||
import Subsubheadline from './Subsubheadline.astro';
|
||||
import { Link, Subsubheadline } from '.';
|
||||
---
|
||||
|
||||
<div class="grow mbe-5 sm:mbe-0">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
import { Sprite } from 'astro-icon';
|
||||
|
||||
import Link from './Link.astro';
|
||||
import { Link } from '.';
|
||||
|
||||
import data from '../data/social-links.json';
|
||||
---
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
interface Props {
|
||||
as?: string;
|
||||
children?: any;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
const { as = 'h3', class: className, ...props } = Astro.props;
|
||||
const Element = as;
|
||||
---
|
||||
|
||||
<Element
|
||||
class:list={[
|
||||
'text-4 font-black tracking-tight mbe-8 mbs-14 first-of-type:mbs-0 dark:font-extrabold',
|
||||
className,
|
||||
]}
|
||||
{...props}
|
||||
>
|
||||
<slot />
|
||||
</Element>
|
||||
28
src/components/Subheadline.tsx
Normal file
28
src/components/Subheadline.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import cx from 'classnames';
|
||||
|
||||
import type { ComponentChild, FunctionalComponent } from 'preact';
|
||||
|
||||
interface Props {
|
||||
as?: any;
|
||||
class?: string;
|
||||
children: ComponentChild;
|
||||
}
|
||||
|
||||
export const Subheadline: FunctionalComponent<Props> = ({
|
||||
as = 'h3',
|
||||
class: className,
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
const Tag = as;
|
||||
const classes = cx(
|
||||
'text-4 font-black tracking-tight mbe-8 mbs-14 first-of-type:mbs-0 dark:font-extrabold',
|
||||
className
|
||||
);
|
||||
|
||||
return (
|
||||
<Tag class={classes} {...props}>
|
||||
{children}
|
||||
</Tag>
|
||||
);
|
||||
};
|
||||
@@ -1,7 +1,9 @@
|
||||
---
|
||||
import cx from 'classnames';
|
||||
|
||||
import data from '../data/subnavigation.json';
|
||||
|
||||
import Link from './Link.astro';
|
||||
import { Link } from '.';
|
||||
|
||||
const currentPath = new URL(Astro.request.url).pathname;
|
||||
---
|
||||
@@ -13,9 +15,10 @@ const currentPath = new URL(Astro.request.url).pathname;
|
||||
<li>
|
||||
<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'
|
||||
}`}
|
||||
class={cx(
|
||||
'font-light decoration-4 underline-offset-auto hover:underline hover:decoration-shibui-900/20 dark:hover:decoration-shibui-100/20',
|
||||
{ 'underline !decoration-accent decoration-4': currentPath === url }
|
||||
)}
|
||||
>
|
||||
{title}
|
||||
</Link>
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
interface Props {
|
||||
as?: string;
|
||||
children?: any;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
const { as = 'h4', class: className, ...props } = Astro.props;
|
||||
const Element = as;
|
||||
---
|
||||
|
||||
<Element
|
||||
class:list={[
|
||||
'text-3 font-black tracking-tight mbe-5 mbs-14 first-of-type:mbs-0 dark:font-extrabold',
|
||||
className,
|
||||
]}
|
||||
{...props}
|
||||
>
|
||||
<slot />
|
||||
</Element>
|
||||
28
src/components/Subsubheadline.tsx
Normal file
28
src/components/Subsubheadline.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import cx from 'classnames';
|
||||
|
||||
import type { ComponentChild, FunctionalComponent } from 'preact';
|
||||
|
||||
interface Props {
|
||||
as?: any;
|
||||
class?: string;
|
||||
children: ComponentChild;
|
||||
}
|
||||
|
||||
export const Subsubheadline: FunctionalComponent<Props> = ({
|
||||
as = 'h4',
|
||||
class: className,
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
const Tag = as;
|
||||
const classes = cx(
|
||||
'text-3 font-black tracking-tight mbe-5 mbs-14 first-of-type:mbs-0 dark:font-extrabold',
|
||||
className
|
||||
);
|
||||
|
||||
return (
|
||||
<Tag class={classes} {...props}>
|
||||
{children}
|
||||
</Tag>
|
||||
);
|
||||
};
|
||||
28
src/components/Text.tsx
Normal file
28
src/components/Text.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import cx from 'classnames';
|
||||
|
||||
import type { ComponentChild, FunctionalComponent } from 'preact';
|
||||
|
||||
interface Props {
|
||||
as?: any;
|
||||
class?: string;
|
||||
children: ComponentChild;
|
||||
}
|
||||
|
||||
export const Text: FunctionalComponent<Props> = ({
|
||||
as = 'p',
|
||||
class: className,
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
const Tag = as;
|
||||
const classes = cx(
|
||||
'text-3 font-normal tracking-normal mbe-10 mbs-0 last-of-type:mbe-0 dark:font-light',
|
||||
className
|
||||
);
|
||||
|
||||
return (
|
||||
<Tag class={classes} {...props}>
|
||||
{children}
|
||||
</Tag>
|
||||
);
|
||||
};
|
||||
24
src/components/TextLink.tsx
Normal file
24
src/components/TextLink.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import cx from 'classnames';
|
||||
|
||||
import type { FunctionalComponent, JSX } from 'preact';
|
||||
|
||||
import { Link } from '.';
|
||||
|
||||
interface Props extends JSX.HTMLAttributes<HTMLAnchorElement> {}
|
||||
|
||||
export const TextLink: FunctionalComponent<Props> = ({
|
||||
class: className,
|
||||
children,
|
||||
...props
|
||||
}: Props) => {
|
||||
const classes = cx(
|
||||
'font-semibold text-shibui-950 underline decoration-shibui-900/20 decoration-4 underline-offset-auto no-common-ligatures no-discretionary-ligatures hover:!decoration-accent focus:!decoration-accent dark:text-shibui-200/[0.87] dark:decoration-shibui-100/20',
|
||||
className as string
|
||||
);
|
||||
|
||||
return (
|
||||
<Link class={classes} {...props}>
|
||||
{children}
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
interface Props {
|
||||
as?: string;
|
||||
children?: any;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
const { as = 'h1', class: className, ...props } = Astro.props;
|
||||
const Element = as;
|
||||
---
|
||||
|
||||
<Element
|
||||
class:list={['text-7 font-black tracking-tight mbe-13 dark:font-extrabold', className]}
|
||||
{...props}
|
||||
>
|
||||
<slot />
|
||||
</Element>
|
||||
25
src/components/Title.tsx
Normal file
25
src/components/Title.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import cx from 'classnames';
|
||||
|
||||
import type { ComponentChild, FunctionalComponent } from 'preact';
|
||||
|
||||
interface Props {
|
||||
as?: any;
|
||||
class?: string;
|
||||
children: ComponentChild;
|
||||
}
|
||||
|
||||
export const Title: FunctionalComponent<Props> = ({
|
||||
as = 'h1',
|
||||
class: className,
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
const Tag = as;
|
||||
const classes = cx('text-7 font-black tracking-tight mbe-13 dark:font-extrabold', className);
|
||||
|
||||
return (
|
||||
<Tag class={classes} {...props}>
|
||||
{children}
|
||||
</Tag>
|
||||
);
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
import { Sprite } from 'astro-icon';
|
||||
|
||||
import Link from './Link.astro';
|
||||
import { Link } from '.';
|
||||
---
|
||||
|
||||
<div class="flex flex-1 justify-end">
|
||||
|
||||
8
src/components/index.ts
Normal file
8
src/components/index.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export * from './Headline';
|
||||
export * from './LegalDate';
|
||||
export * from './Link';
|
||||
export * from './Subheadline';
|
||||
export * from './Subsubheadline';
|
||||
export * from './Text';
|
||||
export * from './TextLink';
|
||||
export * from './Title';
|
||||
Reference in New Issue
Block a user