use:components and remove storybook integration

This commit is contained in:
2025-09-28 15:44:02 +02:00
parent bc8a76b9f5
commit 62b2108434
44 changed files with 273 additions and 1019 deletions

View File

@@ -0,0 +1,65 @@
<script lang="ts">
interface Props {
type?: 'button' | 'submit' | 'reset';
variant?: 'primary' | 'secondary';
disabled?: boolean;
formaction?: string;
children?: import('svelte').Snippet;
}
let {
type = 'button',
variant = 'primary',
disabled = false,
formaction,
children
}: Props = $props();
</script>
<button class="button {variant}" {type} {disabled} {formaction}>
{@render children?.()}
</button>
<style>
.button {
flex: 1;
padding: 1.25rem 2rem;
border: none;
border-radius: 2rem;
font-size: 1rem;
font-weight: 500;
transition: all 0.2s ease;
cursor: pointer;
height: 3.5rem;
}
.button:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
.button:disabled:hover {
transform: none;
}
.primary {
background-color: #3a4553;
color: white;
}
.primary:hover:not(:disabled) {
background-color: #2d3441;
transform: translateY(-1px);
}
.secondary {
background-color: #6c757d;
color: white;
}
.secondary:hover:not(:disabled) {
background-color: #5a6268;
transform: translateY(-1px);
}
</style>

View File

@@ -0,0 +1,22 @@
<script lang="ts">
interface Props {
message?: string;
show?: boolean;
}
let { message, show = true }: Props = $props();
</script>
{#if message && show}
<p class="error-message">{message}</p>
{/if}
<style>
.error-message {
color: #e53e3e;
font-size: 0.875rem;
text-align: center;
margin-top: 1rem;
padding: 0.5rem;
}
</style>

View File

@@ -0,0 +1,42 @@
<script lang="ts">
interface Props {
name: string;
type?: 'text' | 'email' | 'password';
placeholder?: string;
required?: boolean;
value?: string;
}
let { name, type = 'text', placeholder, required = false, value = $bindable() }: Props = $props();
</script>
<div class="input-group">
<input class="input-field" {name} {type} {placeholder} {required} bind:value />
</div>
<style>
.input-group {
display: flex;
flex-direction: column;
}
.input-field {
padding: 1.25rem 1.5rem;
border: none;
border-radius: 2rem;
background-color: #e0e0e0;
font-size: 1rem;
color: #333;
outline: none;
transition: background-color 0.2s ease;
height: 3.5rem;
}
.input-field:focus {
background-color: #d5d5d5;
}
.input-field::placeholder {
color: #888;
}
</style>

View File

@@ -0,0 +1,47 @@
<script lang="ts">
interface Props {
username: string;
id: string;
showId?: boolean;
}
let { username, id, showId = true }: Props = $props();
</script>
<div class="user-info">
<p class="greeting">Hi, {username}!</p>
{#if showId}
<p class="user-id">Your user ID is {id}.</p>
{/if}
</div>
<style>
.user-info {
margin-bottom: 2rem;
text-align: center;
}
.greeting {
font-size: 1.25rem;
color: #333;
margin-bottom: 0.5rem;
font-weight: 500;
}
.user-id {
font-size: 0.95rem;
color: #666;
margin-bottom: 0;
font-family: monospace;
}
@media (max-width: 480px) {
.greeting {
font-size: 1.1rem;
}
.user-id {
font-size: 0.85rem;
}
}
</style>

View File

@@ -1 +1,5 @@
// place files you want to import through the `$lib` alias in this folder.
// Reusable UI Components
export { default as Input } from './components/Input.svelte';
export { default as Button } from './components/Button.svelte';
export { default as ErrorMessage } from './components/ErrorMessage.svelte';
export { default as UserInfo } from './components/UserInfo.svelte';

View File

@@ -1,4 +1,4 @@
import { pgTable, serial, integer, text, timestamp } from 'drizzle-orm/pg-core';
import { pgTable, integer, text, timestamp } from 'drizzle-orm/pg-core';
export const user = pgTable('user', {
id: text('id').primaryKey(),