Skip to content

Commit 75ebe1d

Browse files
committed
shadcn and supporting components
1 parent 08231dc commit 75ebe1d

18 files changed

+460
-0
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<script lang="ts">
2+
import { Button } from '@/lib/components/ui/button';
3+
import * as Card from '@/lib/components/ui/card/index';
4+
import { Input } from '@/lib/components/ui/input/index';
5+
import { Label } from '@/lib/components/ui/label/index';
6+
import { GitGraph, Linkedin, User } from '@lucide/svelte';
7+
</script>
8+
9+
<Card.Root>
10+
<Card.Header>
11+
<Card.Title>Create an account</Card.Title>
12+
<Card.Description>Enter your email below to create your account</Card.Description>
13+
</Card.Header>
14+
<Card.Content>
15+
<div class="grid grid-cols-2 gap-6">
16+
<Button variant="outline">
17+
<GitGraph class="mr-2 h-4 w-4" />
18+
Git
19+
</Button>
20+
<Button variant="outline">
21+
<Linkedin class="mr-2 h-4 w-4" />
22+
Linkedin
23+
</Button>
24+
</div>
25+
<div class="relative">
26+
<div class="absolute inset-0 flex items-center">
27+
<span class="w-full border-t"></span>
28+
</div>
29+
<div class="relative my-4 flex justify-center text-xs uppercase">
30+
<span class="bg-background text-muted-foreground px-2"> Or continue with </span>
31+
</div>
32+
</div>
33+
<div class="grid gap-2">
34+
<Label for="email">Email</Label>
35+
<Input id="email" type="email" placeholder="[email protected]" />
36+
</div>
37+
<div class="grid gap-2">
38+
<Label for="password">Password</Label>
39+
<Input id="password" type="password" />
40+
</div>
41+
</Card.Content>
42+
<Card.Footer>
43+
<Button class="w-full">
44+
<User class="mr-2 h-4 w-4" /> Create Account
45+
</Button>
46+
</Card.Footer>
47+
</Card.Root>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script lang="ts">
2+
import { Button } from '@/lib/components/ui/button';
3+
</script>
4+
5+
<div class="flex flex-wrap items-center gap-2">
6+
<Button>Primary</Button>
7+
<Button variant="secondary">Secondary</Button>
8+
<Button variant="outline">Outline</Button>
9+
<Button variant="destructive">Destructive</Button>
10+
<Button variant="link">Link</Button>
11+
</div>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<script lang="ts">
2+
import { Button } from '@/lib/components/ui/button';
3+
import * as Card from '@/lib/components/ui/card/index';
4+
import { Switch } from '@/lib/components/ui/switch';
5+
import { Bell, Check } from '@lucide/svelte';
6+
7+
const notifications = [
8+
{
9+
title: 'Your call has been confirmed.',
10+
description: '1 hour ago'
11+
},
12+
{
13+
title: 'You have a new message!',
14+
description: '1 hour ago'
15+
},
16+
{
17+
title: 'Your subscription is expiring soon!',
18+
description: '2 hours ago'
19+
}
20+
];
21+
</script>
22+
23+
<Card.Root>
24+
<Card.Header>
25+
<Card.Title>Notifications</Card.Title>
26+
<Card.Description>You have 3 unread messages.</Card.Description>
27+
</Card.Header>
28+
<Card.Content>
29+
<div class=" mb-4 flex items-center space-x-4 rounded-md border p-4">
30+
<Bell />
31+
<div class="flex-1 space-y-1">
32+
<p class="text-sm leading-none font-medium">Push Notifications</p>
33+
<p class="text-muted-foreground text-sm">Send notifications to device.</p>
34+
</div>
35+
<Switch />
36+
</div>
37+
<div>
38+
{#each notifications as notification, index (index)}
39+
<div class="mb-4 grid grid-cols-[25px_1fr] items-start pb-4 last:mb-0 last:pb-0">
40+
<span class="flex h-2 w-2 translate-y-1 rounded-full bg-sky-500"></span>
41+
<div class="space-y-1">
42+
<p class="text-sm leading-none font-medium">
43+
{notification.title}
44+
</p>
45+
<p class="text-muted-foreground text-sm">
46+
{notification.description}
47+
</p>
48+
</div>
49+
</div>
50+
{/each}
51+
</div>
52+
</Card.Content>
53+
<Card.Footer>
54+
<Button class="w-full">
55+
<Check class="mr-2 h-4 w-4" /> Mark all as read
56+
</Button>
57+
</Card.Footer>
58+
</Card.Root>
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<script lang="ts">
2+
import * as Card from '@/lib/components/ui/card/index';
3+
import { ScrollArea } from '@/lib/components/ui/scroll-area/index';
4+
import { themes, type ThemeOptions } from '@/lib/utils/themes';
5+
import { Sun, Moon } from '@lucide/svelte';
6+
import * as RadioGroup from '@/lib/components/ui/radio-group/index';
7+
import Label from '@/lib/components/ui/label/label.svelte';
8+
import { onMount } from 'svelte';
9+
10+
let currentTheme = $state(themes[0]);
11+
12+
onMount(() => {
13+
const storedTheme = localStorage.getItem('theme');
14+
if (storedTheme) return handleThemeChange(storedTheme);
15+
checkSystemColorPreference();
16+
});
17+
18+
const handleThemeChange = (theme: ThemeOptions) => {
19+
currentTheme = theme;
20+
document.documentElement.className = '';
21+
document.documentElement.classList.add(theme);
22+
localStorage.setItem('theme', theme);
23+
};
24+
25+
const checkSystemColorPreference = () => {
26+
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)').matches;
27+
currentTheme = prefersDarkScheme ? 'dark' : 'light';
28+
};
29+
</script>
30+
31+
<Card.Root>
32+
<Card.Header>
33+
<Card.Title>Theme Settings</Card.Title>
34+
<Card.Description>Manage your theme here</Card.Description>
35+
</Card.Header>
36+
<Card.Content>
37+
<ScrollArea class="h-[300px] w-full rounded-md border p-4">
38+
<RadioGroup.Root value={currentTheme} onValueChange={handleThemeChange}>
39+
{#each themes as theme}
40+
<div class="flex items-center space-x-2">
41+
<RadioGroup.Item value={theme} id={theme} />
42+
<Label for={theme} class="flex items-center gap-2">
43+
{#if theme.includes('light')}
44+
<Sun />
45+
{:else}
46+
<Moon />
47+
{/if}
48+
{theme}
49+
</Label>
50+
</div>
51+
{/each}
52+
</RadioGroup.Root>
53+
</ScrollArea>
54+
</Card.Content>
55+
</Card.Root>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<script lang="ts">
2+
import type { WithElementRef } from "bits-ui";
3+
import type { HTMLAttributes } from "svelte/elements";
4+
import { cn } from "$lib/utils.js";
5+
6+
let {
7+
ref = $bindable(null),
8+
class: className,
9+
children,
10+
...restProps
11+
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
12+
</script>
13+
14+
<div bind:this={ref} class={cn("p-6", className)} {...restProps}>
15+
{@render children?.()}
16+
</div>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<script lang="ts">
2+
import type { WithElementRef } from "bits-ui";
3+
import type { HTMLAttributes } from "svelte/elements";
4+
import { cn } from "$lib/utils.js";
5+
6+
let {
7+
ref = $bindable(null),
8+
class: className,
9+
children,
10+
...restProps
11+
}: WithElementRef<HTMLAttributes<HTMLParagraphElement>> = $props();
12+
</script>
13+
14+
<p bind:this={ref} class={cn("text-muted-foreground text-sm", className)} {...restProps}>
15+
{@render children?.()}
16+
</p>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<script lang="ts">
2+
import type { WithElementRef } from "bits-ui";
3+
import type { HTMLAttributes } from "svelte/elements";
4+
import { cn } from "$lib/utils.js";
5+
6+
let {
7+
ref = $bindable(null),
8+
class: className,
9+
children,
10+
...restProps
11+
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
12+
</script>
13+
14+
<div bind:this={ref} class={cn("flex items-center p-6 pt-0", className)} {...restProps}>
15+
{@render children?.()}
16+
</div>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<script lang="ts">
2+
import type { WithElementRef } from "bits-ui";
3+
import type { HTMLAttributes } from "svelte/elements";
4+
import { cn } from "$lib/utils.js";
5+
6+
let {
7+
ref = $bindable(null),
8+
class: className,
9+
children,
10+
...restProps
11+
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
12+
</script>
13+
14+
<div bind:this={ref} class={cn("flex flex-col space-y-1.5 p-6 pb-0", className)} {...restProps}>
15+
{@render children?.()}
16+
</div>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<script lang="ts">
2+
import type { WithElementRef } from "bits-ui";
3+
import type { HTMLAttributes } from "svelte/elements";
4+
import { cn } from "$lib/utils.js";
5+
6+
let {
7+
ref = $bindable(null),
8+
class: className,
9+
level = 3,
10+
children,
11+
...restProps
12+
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
13+
level?: 1 | 2 | 3 | 4 | 5 | 6;
14+
} = $props();
15+
</script>
16+
17+
<div
18+
role="heading"
19+
aria-level={level}
20+
bind:this={ref}
21+
class={cn("text-2xl font-semibold leading-none tracking-tight", className)}
22+
{...restProps}
23+
>
24+
{@render children?.()}
25+
</div>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<script lang="ts">
2+
import type { WithElementRef } from "bits-ui";
3+
import type { HTMLAttributes } from "svelte/elements";
4+
import { cn } from "$lib/utils.js";
5+
6+
let {
7+
ref = $bindable(null),
8+
class: className,
9+
children,
10+
...restProps
11+
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
12+
</script>
13+
14+
<div
15+
bind:this={ref}
16+
class={cn("bg-card text-card-foreground rounded-lg border shadow-sm", className)}
17+
{...restProps}
18+
>
19+
{@render children?.()}
20+
</div>

0 commit comments

Comments
 (0)