refactor: migrate shadcn-components to Svelte 5 and TW4 (#551)

Co-authored-by: Elias Schneider <login@eliasschneider.com>
This commit is contained in:
Kyle Mendell
2025-05-21 12:15:27 -05:00
committed by Elias Schneider
parent 05b443d984
commit 28c85990ba
197 changed files with 8142 additions and 7471 deletions

View File

@@ -1,13 +1,23 @@
<script lang="ts">
import type { HTMLAttributes } from 'svelte/elements';
import { cn } from '$lib/utils/style.js';
import { cn, type WithElementRef } from '$lib/utils/style.js';
type $$Props = HTMLAttributes<HTMLDivElement>;
let className: $$Props['class'] = undefined;
export { className as class };
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<div class={cn('text-sm [&_p]:leading-relaxed', className)} {...$$restProps}>
<slot />
<div
bind:this={ref}
data-slot="alert-description"
class={cn(
'text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed',
className
)}
{...restProps}
>
{@render children?.()}
</div>

View File

@@ -1,21 +1,20 @@
<script lang="ts">
import type { HTMLAttributes } from 'svelte/elements';
import type { HeadingLevel } from './index.js';
import { cn } from '$lib/utils/style.js';
import { cn, type WithElementRef } from '$lib/utils/style.js';
type $$Props = HTMLAttributes<HTMLHeadingElement> & {
level?: HeadingLevel;
};
let className: $$Props['class'] = undefined;
export let level: $$Props['level'] = 'h5';
export { className as class };
let {
ref = $bindable(null),
class: className,
children,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
</script>
<svelte:element
this={level}
class={cn('mb-1 leading-none font-medium tracking-tight', className)}
{...$$restProps}
<div
bind:this={ref}
data-slot="alert-title"
class={cn('col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight', className)}
{...restProps}
>
<slot />
</svelte:element>
{@render children?.()}
</div>

View File

@@ -1,21 +1,44 @@
<script lang="ts" module>
import { type VariantProps, tv } from 'tailwind-variants';
export const alertVariants = tv({
base: 'relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border px-4 py-3 text-sm has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-3 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current',
variants: {
variant: {
default: 'bg-card text-card-foreground',
destructive:
'text-destructive bg-card *:data-[slot=alert-description]:text-destructive/90 [&>svg]:text-current',
warning:
'bg-amber-100 text-amber-900 dark:bg-amber-900 dark:text-amber-100 [&>svg]:text-amber-900 dark:[&>svg]:text-amber-100'
}
},
defaultVariants: {
variant: 'default'
}
});
export type AlertVariant = VariantProps<typeof alertVariants>['variant'];
</script>
<script lang="ts">
import { cn } from '$lib/utils/style.js';
import { LucideX } from 'lucide-svelte';
import { onMount } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
import { type Variant, alertVariants } from './index.js';
import { cn, type WithElementRef } from '$lib/utils/style.js';
import { onMount } from 'svelte';
import { LucideX } from '@lucide/svelte';
type $$Props = HTMLAttributes<HTMLDivElement> & {
variant?: Variant;
let {
ref = $bindable(null),
class: className,
variant = 'default',
children,
dismissibleId = undefined,
...restProps
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
variant?: AlertVariant;
dismissibleId?: string;
};
} = $props();
let className: $$Props['class'] = undefined;
export let variant: $$Props['variant'] = 'default';
export let dismissibleId: $$Props['dismissibleId'] = undefined;
export { className as class };
let isVisible = !dismissibleId;
let isVisible = $state(!dismissibleId);
onMount(() => {
if (dismissibleId) {
@@ -34,11 +57,17 @@
</script>
{#if isVisible}
<div class={cn(alertVariants({ variant }), className)} {...$$restProps} role="alert">
<slot />
<div
bind:this={ref}
data-slot="alert"
class={cn(alertVariants({ variant }), className)}
{...restProps}
role="alert"
>
{@render children?.()}
{#if dismissibleId}
<button on:click={dismiss} class="absolute top-0 right-0 m-3 text-black dark:text-white"
><LucideX class="w-4" /></button
<button onclick={dismiss} class="absolute top-0 right-0 m-3 text-black dark:text-white"
><LucideX class="size-4" /></button
>
{/if}
</div>

View File

@@ -1,35 +1,14 @@
import { type VariantProps, tv } from 'tailwind-variants';
import Root from './alert.svelte';
import Description from './alert-description.svelte';
import Title from './alert-title.svelte';
import Root from './alert.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',
warning:
'bg-amber-100 text-amber-900 dark:bg-amber-900 dark:text-amber-100 [&>svg]:text-amber-900 dark:[&>svg]:text-amber-100'
}
},
defaultVariants: {
variant: 'default'
}
});
export type Variant = VariantProps<typeof alertVariants>['variant'];
export type HeadingLevel = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
export { alertVariants, type AlertVariant } from './alert.svelte';
export {
Root,
Description,
Title,
//
Root as Alert,
Description as AlertDescription,
Title as AlertTitle,
Description,
Root,
Title
Title as AlertTitle
};