Skip to content

Commit 1e4a37c

Browse files
committed
feat: implement multiple image deletion with confirmation dialog
1 parent 35462d5 commit 1e4a37c

File tree

12 files changed

+339
-100
lines changed

12 files changed

+339
-100
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
"svelte-check": "^4.3.2",
7676
"svelte-sonner": "^1.0.5",
7777
"tailwind-merge": "^3.3.1",
78-
"tailwind-variants": "^1.0.0",
78+
"tailwind-variants": "^3.2.2",
7979
"tailwindcss": "^4.1.12",
8080
"tsx": "^4.20.3",
8181
"tw-animate-css": "^1.3.4",

pnpm-lock.yaml

Lines changed: 11 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lib/components/molecules/delete-confirmation-dialog.svelte

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
<script lang="ts">
22
import * as Dialog from '$lib/components/ui/dialog/index.js';
33
import { Button, buttonVariants } from '$lib/components/ui/button';
4+
import type { Snippet } from 'svelte';
45
56
type Props = {
67
title: string;
78
description: string;
89
open: boolean;
910
deleteAction: () => void;
1011
onClose: () => void;
12+
children?: Snippet
1113
};
1214
13-
let { title, description, open = $bindable(false), deleteAction, onClose }: Props = $props();
15+
let { title, description, open = $bindable(false), deleteAction, onClose, children }: Props = $props();
1416
</script>
1517

1618
<Dialog.Root bind:open onOpenChangeComplete={!open ? onClose : () => {}}>
@@ -21,6 +23,7 @@
2123
{description}
2224
</Dialog.Description>
2325
</Dialog.Header>
26+
{@render children?.()}
2427
<Dialog.Footer class="flex flex-row gap-x-4">
2528
<Dialog.Close class={buttonVariants({ variant: 'secondary' })}>Cancel</Dialog.Close>
2629
<Button variant="destructive" onclick={deleteAction}>Delete</Button>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<script lang="ts">
2+
import type { HTMLAttributes } from "svelte/elements";
3+
import { cn, type WithElementRef } from "$lib/utils.js";
4+
5+
let {
6+
ref = $bindable(null),
7+
class: className,
8+
children,
9+
...restProps
10+
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
11+
</script>
12+
13+
<div
14+
bind:this={ref}
15+
data-slot="alert-description"
16+
class={cn(
17+
"text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed",
18+
className
19+
)}
20+
{...restProps}
21+
>
22+
{@render children?.()}
23+
</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 { HTMLAttributes } from "svelte/elements";
3+
import { cn, type WithElementRef } from "$lib/utils.js";
4+
5+
let {
6+
ref = $bindable(null),
7+
class: className,
8+
children,
9+
...restProps
10+
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
11+
</script>
12+
13+
<div
14+
bind:this={ref}
15+
data-slot="alert-title"
16+
class={cn("col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight", className)}
17+
{...restProps}
18+
>
19+
{@render children?.()}
20+
</div>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<script lang="ts" module>
2+
import { type VariantProps, tv } from "tailwind-variants";
3+
4+
export const alertVariants = tv({
5+
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",
6+
variants: {
7+
variant: {
8+
default: "bg-card text-card-foreground",
9+
destructive:
10+
"text-destructive bg-card *:data-[slot=alert-description]:text-destructive/90 [&>svg]:text-current",
11+
},
12+
},
13+
defaultVariants: {
14+
variant: "default",
15+
},
16+
});
17+
18+
export type AlertVariant = VariantProps<typeof alertVariants>["variant"];
19+
</script>
20+
21+
<script lang="ts">
22+
import type { HTMLAttributes } from "svelte/elements";
23+
import { cn, type WithElementRef } from "$lib/utils.js";
24+
25+
let {
26+
ref = $bindable(null),
27+
class: className,
28+
variant = "default",
29+
children,
30+
...restProps
31+
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
32+
variant?: AlertVariant;
33+
} = $props();
34+
</script>
35+
36+
<div
37+
bind:this={ref}
38+
data-slot="alert"
39+
class={cn(alertVariants({ variant }), className)}
40+
{...restProps}
41+
role="alert"
42+
>
43+
{@render children?.()}
44+
</div>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Root from "./alert.svelte";
2+
import Description from "./alert-description.svelte";
3+
import Title from "./alert-title.svelte";
4+
export { alertVariants, type AlertVariant } from "./alert.svelte";
5+
6+
export {
7+
Root,
8+
Description,
9+
Title,
10+
//
11+
Root as Alert,
12+
Description as AlertDescription,
13+
Title as AlertTitle,
14+
};

src/lib/helpers/try-catch.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
type Success<T> = { data: T; error: null };
2+
type Failure<E> = { data: null; error: E };
3+
type Result<T, E = Error> = Success<T> | Failure<E>;
4+
5+
export const tryCatch = async <T, E = Error>(promise: Promise<T>): Promise<Result<T, E>> => {
6+
try {
7+
const data = await promise;
8+
return { data, error: null };
9+
} catch (error) {
10+
return { data: null, error: error as E };
11+
}
12+
};
13+
14+
export const tryCatchSync = <T, E = Error>(func: () => T): Result<T, E> => {
15+
try {
16+
const data = func();
17+
return { data, error: null };
18+
} catch (error) {
19+
return { data: null, error: error as E };
20+
}
21+
};

0 commit comments

Comments
 (0)