From 7f7d4870d08b143cb91701e1b4da89c2a37fd404 Mon Sep 17 00:00:00 2001 From: Justin Reiners Date: Thu, 26 Mar 2026 12:02:19 -0500 Subject: [PATCH] feat: add UI component library (toast, search, badges, modals, upload, table) Co-Authored-By: Claude Sonnet 4.6 --- src/lib/components/admin/DataTable.svelte | 23 ++++++++++ src/lib/components/ui/ConfirmModal.svelte | 29 ++++++++++++ src/lib/components/ui/FileUpload.svelte | 40 ++++++++++++++++ src/lib/components/ui/Pagination.svelte | 27 +++++++++++ src/lib/components/ui/PetSearchSelect.svelte | 48 ++++++++++++++++++++ src/lib/components/ui/SearchBar.svelte | 22 +++++++++ src/lib/components/ui/StatusBadge.svelte | 28 ++++++++++++ src/lib/components/ui/Toast.svelte | 22 +++++++++ 8 files changed, 239 insertions(+) create mode 100644 src/lib/components/admin/DataTable.svelte create mode 100644 src/lib/components/ui/ConfirmModal.svelte create mode 100644 src/lib/components/ui/FileUpload.svelte create mode 100644 src/lib/components/ui/Pagination.svelte create mode 100644 src/lib/components/ui/PetSearchSelect.svelte create mode 100644 src/lib/components/ui/SearchBar.svelte create mode 100644 src/lib/components/ui/StatusBadge.svelte create mode 100644 src/lib/components/ui/Toast.svelte diff --git a/src/lib/components/admin/DataTable.svelte b/src/lib/components/admin/DataTable.svelte new file mode 100644 index 0000000..a39a6ac --- /dev/null +++ b/src/lib/components/admin/DataTable.svelte @@ -0,0 +1,23 @@ + + +
+ + + + {#each headers as header} + + {/each} + + + + {@render children()} + +
{header}
+
diff --git a/src/lib/components/ui/ConfirmModal.svelte b/src/lib/components/ui/ConfirmModal.svelte new file mode 100644 index 0000000..bfeab08 --- /dev/null +++ b/src/lib/components/ui/ConfirmModal.svelte @@ -0,0 +1,29 @@ + + +{#if open} +
+
{ open = false; oncancel?.(); }} role="button" tabindex="-1" onkeydown={() => {}}>
+
+

{title}

+

{message}

+
+ + +
+
+
+{/if} diff --git a/src/lib/components/ui/FileUpload.svelte b/src/lib/components/ui/FileUpload.svelte new file mode 100644 index 0000000..0e3d425 --- /dev/null +++ b/src/lib/components/ui/FileUpload.svelte @@ -0,0 +1,40 @@ + + +
{ e.preventDefault(); dragging = true; }} + ondragleave={() => dragging = false} + ondrop={handleDrop} + onclick={() => input.click()} + role="button" + tabindex="0" + onkeydown={(e) => { if (e.key === 'Enter') input.click(); }} +> + +

Drop files here or click to browse

+
diff --git a/src/lib/components/ui/Pagination.svelte b/src/lib/components/ui/Pagination.svelte new file mode 100644 index 0000000..58ecf4c --- /dev/null +++ b/src/lib/components/ui/Pagination.svelte @@ -0,0 +1,27 @@ + + +{#if totalPages > 1} + +{/if} diff --git a/src/lib/components/ui/PetSearchSelect.svelte b/src/lib/components/ui/PetSearchSelect.svelte new file mode 100644 index 0000000..8de7226 --- /dev/null +++ b/src/lib/components/ui/PetSearchSelect.svelte @@ -0,0 +1,48 @@ + + +
+ open = true} + class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary" + /> + {#if open && results.length > 0} +
    + {#each results as pet} +
  • + +
  • + {/each} +
+ {/if} +
diff --git a/src/lib/components/ui/SearchBar.svelte b/src/lib/components/ui/SearchBar.svelte new file mode 100644 index 0000000..cd391a0 --- /dev/null +++ b/src/lib/components/ui/SearchBar.svelte @@ -0,0 +1,22 @@ + + +
{ e.preventDefault(); onsubmit?.(value); }} +> + + + + +
diff --git a/src/lib/components/ui/StatusBadge.svelte b/src/lib/components/ui/StatusBadge.svelte new file mode 100644 index 0000000..376d418 --- /dev/null +++ b/src/lib/components/ui/StatusBadge.svelte @@ -0,0 +1,28 @@ + + + + {label} + diff --git a/src/lib/components/ui/Toast.svelte b/src/lib/components/ui/Toast.svelte new file mode 100644 index 0000000..21a69c1 --- /dev/null +++ b/src/lib/components/ui/Toast.svelte @@ -0,0 +1,22 @@ + + +{#if toasts.length > 0} +
+ {#each toasts as toast (toast.id)} +
+ {toast.message} + +
+ {/each} +
+{/if}