Skip to content

Commit

Permalink
✨ Added icon on project links && Added custom error page && Fixed mys…
Browse files Browse the repository at this point in the history
…terious vanishing of cursor when out of content height
  • Loading branch information
nwrenger committed Aug 29, 2024
1 parent 91712ee commit ab5787b
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 57 deletions.
13 changes: 13 additions & 0 deletions src/lib/components/ui/alert/alert-description.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement>;
let className: $$Props["class"] = undefined;
export { className as class };
</script>

<div class={cn("text-sm [&_p]:leading-relaxed", className)} {...$$restProps}>
<slot />
</div>
21 changes: 21 additions & 0 deletions src/lib/components/ui/alert/alert-title.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import type { HeadingLevel } from "./index.js";
import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLHeadingElement> & {
level?: HeadingLevel;
};
let className: $$Props["class"] = undefined;
export let level: $$Props["level"] = "h5";
export { className as class };
</script>

<svelte:element
this={level}
class={cn("mb-1 font-medium leading-none tracking-tight", className)}
{...$$restProps}
>
<slot />
</svelte:element>
17 changes: 17 additions & 0 deletions src/lib/components/ui/alert/alert.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import { type Variant, alertVariants } from "./index.js";
import { cn } from "$lib/utils.js";
type $$Props = HTMLAttributes<HTMLDivElement> & {
variant?: Variant;
};
let className: $$Props["class"] = undefined;
export let variant: $$Props["variant"] = "default";
export { className as class };
</script>

<div class={cn(alertVariants({ variant }), className)} {...$$restProps} role="alert">
<slot />
</div>
33 changes: 33 additions & 0 deletions src/lib/components/ui/alert/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { type VariantProps, tv } from "tailwind-variants";

import Root from "./alert.svelte";
import Description from "./alert-description.svelte";
import Title from "./alert-title.svelte";

export const alertVariants = tv({
base: "[&>svg]:text-foreground relative w-full rounded-lg border p-4 [&:has(svg)]:pl-11 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4",

variants: {
variant: {
default: "bg-background text-foreground",
destructive:
"border-destructive/50 text-destructive text-destructive dark:border-destructive [&>svg]:text-destructive",
},
},
defaultVariants: {
variant: "default",
},
});

export type Variant = VariantProps<typeof alertVariants>["variant"];
export type HeadingLevel = "h1" | "h2" | "h3" | "h4" | "h5" | "h6";

export {
Root,
Description,
Title,
//
Root as Alert,
Description as AlertDescription,
Title as AlertTitle,
};
14 changes: 14 additions & 0 deletions src/routes/+error.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script lang="ts">
import * as Alert from '$lib/components/ui/alert';
import { page } from '$app/stores';
import { CircleAlert } from 'lucide-svelte';
</script>

<Alert.Root>
<CircleAlert class="h-4 w-4" />
<Alert.Title>Error: {$page.status} - {$page.error?.message || 'Unknown Error'}</Alert.Title>
<Alert.Description>
<p>URL: <code>{$page.url}</code></p>
<p>Timestamp: {new Date().toLocaleString()}</p>
</Alert.Description>
</Alert.Root>
99 changes: 44 additions & 55 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -74,83 +74,72 @@

<ModeWatcher disableTransitions={false} />

<svelte:document on:visibilitychange={!isTouchDevice ? handleVisibilityChange : null} />

<div
<svelte:body
on:pointerleave={!isTouchDevice ? handleLeave : null}
on:pointerenter={!isTouchDevice ? handleEnter : null}
on:pointerdown={!isTouchDevice ? handleDown : null}
on:pointerup={!isTouchDevice ? handleUp : null}
on:pointermove={!isTouchDevice ? handleMove : null}
>
<header
class="sticky top-0 z-50 w-full border-b border-border/40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60"
>
<div class="container max-w-7xl pl-4 pr-4">
<nav class="flex h-[70px] items-center justify-between gap-3" data-sveltekit-preload-data>
<div class="hidden items-center gap-1.5 sm:flex">
<Button href="/" variant="link" class="p-0">
<Avatar.Root>
<Avatar.Image src="favicon.png" alt="portfolio" class="rounded-md" />
<Avatar.Fallback>PF</Avatar.Fallback>
</Avatar.Root>
</Button>
</div>
<div class="flex items-center gap-1.5">
<Button href="/" variant="link" class={$page.url.pathname == '/' ? 'underline' : ''}
>Home</Button
>
<Button
href="/projects"
variant="link"
class={$page.url.pathname == '/projects' ? 'underline' : ''}>Projects</Button
>
<Button href="https://github.com/nwrenger" target="_blank" variant="link">Github</Button>
</div>
<div class="flex items-center justify-end gap-2.5">
<Button on:click={toggleMode} variant="outline" size="icon">
<Sun
class="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0"
/>
<Moon
class="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100"
/>
<span class="sr-only">Toggle theme</span>
</Button>
</div>
</nav>
</div>
</header>
on:visibilitychange={!isTouchDevice ? handleVisibilityChange : null}
/>

<div class="container max-w-6xl space-y-8 px-4 py-5">
<slot />
<header
class="sticky top-0 z-50 w-full border-b border-border/40 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60"
>
<div class="container max-w-7xl pl-4 pr-4">
<nav class="flex h-[70px] items-center justify-between gap-3" data-sveltekit-preload-data>
<div class="hidden items-center gap-1.5 sm:flex">
<Button href="/" variant="link" class="p-0">
<Avatar.Root>
<Avatar.Image src="favicon.png" alt="portfolio" class="rounded-md" />
<Avatar.Fallback>PF</Avatar.Fallback>
</Avatar.Root>
</Button>
</div>
<div class="flex items-center gap-1.5">
<Button href="/" variant="link" class={$page.url.pathname == '/' ? 'underline' : ''}
>Home</Button
>
<Button
href="/projects"
variant="link"
class={$page.url.pathname == '/projects' ? 'underline' : ''}>Projects</Button
>
<Button href="https://github.com/nwrenger" target="_blank" variant="link">Github</Button>
</div>
<div class="flex items-center justify-end gap-2.5">
<Button on:click={toggleMode} variant="outline" size="icon">
<Sun
class="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0"
/>
<Moon
class="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100"
/>
<span class="sr-only">Toggle theme</span>
</Button>
</div>
</nav>
</div>
</header>

<div class="container max-w-6xl space-y-8 px-4 py-5">
<slot />
</div>

{#if !isTouchDevice}
<div
class="pointer-events-none fixed left-0 top-0 z-[1000]"
class="pointer-events-none fixed left-0 top-0 z-[1000] rounded-[50%] bg-white mix-blend-difference"
style="
width: 100%;
height: 100%;
transition: width 0.15s ease-out, height 0.15s ease-out;
transform: translate(calc({coords.x}px - 50%), calc({coords.y}px - 50%));
width: {size * 2}px;
height: {size * 2}px;
background-color: white;
border-radius: 50%;
mix-blend-mode: difference;
"
></div>
{#if mounted && size === 0}
<div
transition:fade
class="fixed left-0 top-0 z-[999] flex h-full w-full items-center justify-center bg-background/30 text-lg backdrop-blur supports-[backdrop-filter]:bg-background/30"
on:pointerleave={!isTouchDevice ? handleLeave : null}
on:pointerenter={!isTouchDevice ? handleEnter : null}
on:pointerdown={!isTouchDevice ? handleDown : null}
on:pointerup={!isTouchDevice ? handleUp : null}
on:pointermove={!isTouchDevice ? handleMove : null}
>
<div in:fade class="animate-pulse text-center">
<p>Move, click, or interact using your cursor!</p>
Expand Down
7 changes: 5 additions & 2 deletions src/routes/projects/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { projects } from '$lib';
import { Badge } from '$lib/components/ui/badge';
import * as Card from '$lib/components/ui/card';
import { ExternalLink } from 'lucide-svelte';
import ImageLoader from './../ImageLoader.svelte';
</script>

Expand Down Expand Up @@ -47,8 +48,10 @@
>
<p>{@html description}</p>
<div class="mt-4">
<a href={link} class="link" target="_blank">
See the {archived ? 'archived' : ''} Project here
<a href={link} class="link flex items-center" target="_blank">
See the {archived ? 'archived' : ''} Project here <ExternalLink
class="size- pl-2 pt-[2px]"
/>
</a>
</div>
</Card.Header>
Expand Down

0 comments on commit ab5787b

Please sign in to comment.