Files
tibi-svelte-starter/frontend/src/widgets/Button.svelte
Sebastian Frank 602fd6101f feat: Add new input, select, and tooltip components with validation and accessibility features
- Introduced Input component with support for various input types, validation, and error handling.
- Added MedialibImage component for displaying images with lazy loading and caption support.
- Implemented Pagination component for navigating through pages with ellipsis for large page sets.
- Created SearchableSelect component allowing users to search and select options from a dropdown.
- Developed Select component with integrated styling and validation.
- Added Tooltip component for displaying additional information on hover/focus.
2026-02-25 20:15:23 +00:00

60 lines
2.2 KiB
Svelte

<script lang="ts">
import type { MouseEventHandler } from "svelte/elements"
import type { Snippet } from "svelte"
type Props = {
text?: string
variant?: "primary" | "secondary" | "outline" | "text" | "danger" | "ghost"
size?: "sm" | "md" | "lg"
type?: "button" | "submit"
disabled?: boolean
onclick?: MouseEventHandler<HTMLButtonElement>
class?: string
children?: Snippet
}
let {
text = "Button",
variant = "primary",
size = "md",
type = "button",
disabled = false,
onclick = undefined,
class: className = "",
children,
}: Props = $props()
// Base classes
const baseClasses =
"font-sans font-bold rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2 flex items-center justify-center"
// Variant classes
const variantClasses = {
primary: "bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-600 disabled:bg-gray-300",
secondary:
"bg-gray-200 text-gray-900 hover:bg-gray-300 focus:ring-gray-500 disabled:bg-gray-100 disabled:text-gray-400",
outline:
"bg-transparent border-2 border-blue-600 text-blue-600 hover:bg-blue-50 focus:ring-blue-600 disabled:border-gray-300 disabled:text-gray-400",
text: "bg-transparent text-blue-600 hover:bg-blue-50 hover:text-blue-700 focus:ring-blue-600 disabled:text-gray-400",
danger: "bg-transparent border-2 border-red-200 text-red-600 hover:bg-red-50 hover:border-red-300 focus:ring-red-500 disabled:border-gray-300 disabled:text-gray-400",
ghost: "bg-transparent text-gray-900 hover:text-blue-600 focus:ring-blue-600 disabled:text-gray-400 p-0",
}
// Size classes
const sizeClasses = {
sm: "px-4 py-2 text-base",
md: "px-6 py-2.5 text-lg leading-relaxed",
lg: "px-8 py-4 text-xl",
}
let classes = $derived(`${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]} ${className}`)
</script>
<button {type} class={classes} {onclick} {disabled}>
{#if children}
{@render children()}
{:else}
{text}
{/if}
</button>