@svadmin/ui 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/package.json +44 -0
  2. package/src/app.css +113 -0
  3. package/src/components/AdminApp.svelte +127 -0
  4. package/src/components/AutoForm.svelte +192 -0
  5. package/src/components/AutoTable.svelte +343 -0
  6. package/src/components/Breadcrumbs.svelte +51 -0
  7. package/src/components/ConfirmDialog.svelte +45 -0
  8. package/src/components/EmptyState.svelte +41 -0
  9. package/src/components/ErrorBoundary.svelte +51 -0
  10. package/src/components/FieldRenderer.svelte +154 -0
  11. package/src/components/Header.svelte +66 -0
  12. package/src/components/Layout.svelte +66 -0
  13. package/src/components/PageHeader.svelte +39 -0
  14. package/src/components/ShowPage.svelte +71 -0
  15. package/src/components/Sidebar.svelte +169 -0
  16. package/src/components/StatsCard.svelte +49 -0
  17. package/src/components/Toast.svelte +48 -0
  18. package/src/components/ui/alert/alert-description.svelte +17 -0
  19. package/src/components/ui/alert/alert-title.svelte +17 -0
  20. package/src/components/ui/alert/alert.svelte +44 -0
  21. package/src/components/ui/alert/index.ts +14 -0
  22. package/src/components/ui/avatar/avatar.svelte +62 -0
  23. package/src/components/ui/avatar/index.ts +2 -0
  24. package/src/components/ui/badge/badge.svelte +49 -0
  25. package/src/components/ui/badge/index.ts +2 -0
  26. package/src/components/ui/button/button.svelte +82 -0
  27. package/src/components/ui/button/index.ts +17 -0
  28. package/src/components/ui/card/card-action.svelte +23 -0
  29. package/src/components/ui/card/card-content.svelte +20 -0
  30. package/src/components/ui/card/card-description.svelte +20 -0
  31. package/src/components/ui/card/card-footer.svelte +20 -0
  32. package/src/components/ui/card/card-header.svelte +23 -0
  33. package/src/components/ui/card/card-title.svelte +15 -0
  34. package/src/components/ui/card/card.svelte +22 -0
  35. package/src/components/ui/card/index.ts +25 -0
  36. package/src/components/ui/checkbox/checkbox.svelte +39 -0
  37. package/src/components/ui/checkbox/index.ts +6 -0
  38. package/src/components/ui/dialog/dialog-close.svelte +11 -0
  39. package/src/components/ui/dialog/dialog-content.svelte +48 -0
  40. package/src/components/ui/dialog/dialog-description.svelte +17 -0
  41. package/src/components/ui/dialog/dialog-footer.svelte +32 -0
  42. package/src/components/ui/dialog/dialog-header.svelte +20 -0
  43. package/src/components/ui/dialog/dialog-overlay.svelte +17 -0
  44. package/src/components/ui/dialog/dialog-portal.svelte +7 -0
  45. package/src/components/ui/dialog/dialog-title.svelte +17 -0
  46. package/src/components/ui/dialog/dialog-trigger.svelte +11 -0
  47. package/src/components/ui/dialog/dialog.svelte +7 -0
  48. package/src/components/ui/dialog/index.ts +34 -0
  49. package/src/components/ui/dropdown-menu/dropdown-menu-content.svelte +30 -0
  50. package/src/components/ui/dropdown-menu/dropdown-menu-item.svelte +36 -0
  51. package/src/components/ui/dropdown-menu/dropdown-menu-separator.svelte +10 -0
  52. package/src/components/ui/dropdown-menu/dropdown-menu.svelte +41 -0
  53. package/src/components/ui/dropdown-menu/index.ts +15 -0
  54. package/src/components/ui/input/index.ts +7 -0
  55. package/src/components/ui/input/input.svelte +48 -0
  56. package/src/components/ui/select/index.ts +2 -0
  57. package/src/components/ui/select/select.svelte +34 -0
  58. package/src/components/ui/separator/index.ts +7 -0
  59. package/src/components/ui/separator/separator.svelte +23 -0
  60. package/src/components/ui/sheet/index.ts +2 -0
  61. package/src/components/ui/sheet/sheet.svelte +77 -0
  62. package/src/components/ui/skeleton/index.ts +2 -0
  63. package/src/components/ui/skeleton/skeleton.svelte +21 -0
  64. package/src/components/ui/switch/index.ts +2 -0
  65. package/src/components/ui/switch/switch.svelte +49 -0
  66. package/src/components/ui/table/index.ts +28 -0
  67. package/src/components/ui/table/table-body.svelte +15 -0
  68. package/src/components/ui/table/table-caption.svelte +20 -0
  69. package/src/components/ui/table/table-cell.svelte +15 -0
  70. package/src/components/ui/table/table-footer.svelte +20 -0
  71. package/src/components/ui/table/table-head.svelte +15 -0
  72. package/src/components/ui/table/table-header.svelte +20 -0
  73. package/src/components/ui/table/table-row.svelte +15 -0
  74. package/src/components/ui/table/table.svelte +17 -0
  75. package/src/components/ui/tabs/index.ts +15 -0
  76. package/src/components/ui/tabs/tabs-content.svelte +30 -0
  77. package/src/components/ui/tabs/tabs-list.svelte +26 -0
  78. package/src/components/ui/tabs/tabs-trigger.svelte +37 -0
  79. package/src/components/ui/tabs/tabs.svelte +27 -0
  80. package/src/components/ui/textarea/index.ts +2 -0
  81. package/src/components/ui/textarea/textarea.svelte +24 -0
  82. package/src/components/ui/tooltip/index.ts +19 -0
  83. package/src/components/ui/tooltip/tooltip-content.svelte +52 -0
  84. package/src/components/ui/tooltip/tooltip-portal.svelte +7 -0
  85. package/src/components/ui/tooltip/tooltip-provider.svelte +7 -0
  86. package/src/components/ui/tooltip/tooltip-trigger.svelte +7 -0
  87. package/src/components/ui/tooltip/tooltip.svelte +10 -0
  88. package/src/index.ts +43 -0
  89. package/src/utils.ts +28 -0
@@ -0,0 +1,36 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../../utils.js";
3
+ import type { HTMLButtonAttributes } from "svelte/elements";
4
+
5
+ type Props = WithElementRef<HTMLButtonAttributes> & {
6
+ inset?: boolean;
7
+ destructive?: boolean;
8
+ };
9
+
10
+ let {
11
+ ref = $bindable(null),
12
+ inset = false,
13
+ destructive = false,
14
+ class: className,
15
+ children,
16
+ ...restProps
17
+ }: Props = $props();
18
+ </script>
19
+
20
+ <button
21
+ bind:this={ref}
22
+ type="button"
23
+ data-slot="dropdown-menu-item"
24
+ class={cn(
25
+ "relative flex w-full cursor-pointer select-none items-center gap-2 rounded-md px-2 py-1.5 text-sm outline-none transition-colors [&_svg]:size-4 [&_svg]:shrink-0",
26
+ destructive
27
+ ? "text-destructive hover:bg-destructive/10 focus:bg-destructive/10"
28
+ : "hover:bg-accent focus:bg-accent focus:text-accent-foreground",
29
+ "disabled:pointer-events-none disabled:opacity-50",
30
+ inset && "pl-8",
31
+ className
32
+ )}
33
+ {...restProps}
34
+ >
35
+ {@render children?.()}
36
+ </button>
@@ -0,0 +1,10 @@
1
+ <script lang="ts">
2
+ import { cn } from "../../../utils.js";
3
+
4
+ let { class: className }: { class?: string } = $props();
5
+ </script>
6
+
7
+ <div
8
+ data-slot="dropdown-menu-separator"
9
+ class={cn("-mx-1 my-1 h-px bg-border", className)}
10
+ ></div>
@@ -0,0 +1,41 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../../utils.js";
3
+ import type { HTMLAttributes, HTMLButtonAttributes } from "svelte/elements";
4
+
5
+ type Props = WithElementRef<HTMLAttributes<HTMLDivElement>> & {
6
+ open?: boolean;
7
+ onOpenChange?: (open: boolean) => void;
8
+ };
9
+
10
+ let {
11
+ ref = $bindable(null),
12
+ open = $bindable(false),
13
+ onOpenChange,
14
+ class: className,
15
+ children,
16
+ ...restProps
17
+ }: Props = $props();
18
+
19
+ function handleClickOutside(e: MouseEvent) {
20
+ if (ref && !ref.contains(e.target as Node)) {
21
+ open = false;
22
+ onOpenChange?.(false);
23
+ }
24
+ }
25
+
26
+ $effect(() => {
27
+ if (open) {
28
+ document.addEventListener('click', handleClickOutside, true);
29
+ return () => document.removeEventListener('click', handleClickOutside, true);
30
+ }
31
+ });
32
+ </script>
33
+
34
+ <div
35
+ bind:this={ref}
36
+ data-slot="dropdown-menu"
37
+ class={cn("relative inline-block", className)}
38
+ {...restProps}
39
+ >
40
+ {@render children?.()}
41
+ </div>
@@ -0,0 +1,15 @@
1
+ import DropdownMenu from "./dropdown-menu.svelte";
2
+ import DropdownMenuContent from "./dropdown-menu-content.svelte";
3
+ import DropdownMenuItem from "./dropdown-menu-item.svelte";
4
+ import DropdownMenuSeparator from "./dropdown-menu-separator.svelte";
5
+
6
+ export {
7
+ DropdownMenu,
8
+ DropdownMenuContent,
9
+ DropdownMenuItem,
10
+ DropdownMenuSeparator,
11
+ DropdownMenu as Root,
12
+ DropdownMenuContent as Content,
13
+ DropdownMenuItem as Item,
14
+ DropdownMenuSeparator as Separator,
15
+ };
@@ -0,0 +1,7 @@
1
+ import Root from "./input.svelte";
2
+
3
+ export {
4
+ Root,
5
+ //
6
+ Root as Input,
7
+ };
@@ -0,0 +1,48 @@
1
+ <script lang="ts">
2
+ import type { HTMLInputAttributes, HTMLInputTypeAttribute } from "svelte/elements";
3
+ import { cn, type WithElementRef } from "../../../utils.js";
4
+
5
+ type InputType = Exclude<HTMLInputTypeAttribute, "file">;
6
+
7
+ type Props = WithElementRef<
8
+ Omit<HTMLInputAttributes, "type"> &
9
+ ({ type: "file"; files?: FileList } | { type?: InputType; files?: undefined })
10
+ >;
11
+
12
+ let {
13
+ ref = $bindable(null),
14
+ value = $bindable(),
15
+ type,
16
+ files = $bindable(),
17
+ class: className,
18
+ "data-slot": dataSlot = "input",
19
+ ...restProps
20
+ }: Props = $props();
21
+ </script>
22
+
23
+ {#if type === "file"}
24
+ <input
25
+ bind:this={ref}
26
+ data-slot={dataSlot}
27
+ class={cn(
28
+ "dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 rounded-lg border bg-transparent px-2.5 py-1 text-base transition-colors file:h-6 file:text-sm file:font-medium focus-visible:ring-3 aria-invalid:ring-3 md:text-sm file:text-foreground placeholder:text-muted-foreground w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
29
+ className
30
+ )}
31
+ type="file"
32
+ bind:files
33
+ bind:value
34
+ {...restProps}
35
+ />
36
+ {:else}
37
+ <input
38
+ bind:this={ref}
39
+ data-slot={dataSlot}
40
+ class={cn(
41
+ "dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 rounded-lg border bg-transparent px-2.5 py-1 text-base transition-colors file:h-6 file:text-sm file:font-medium focus-visible:ring-3 aria-invalid:ring-3 md:text-sm file:text-foreground placeholder:text-muted-foreground w-full min-w-0 outline-none file:inline-flex file:border-0 file:bg-transparent disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
42
+ className
43
+ )}
44
+ {type}
45
+ bind:value
46
+ {...restProps}
47
+ />
48
+ {/if}
@@ -0,0 +1,2 @@
1
+ import Root from "./select.svelte";
2
+ export { Root, Root as Select };
@@ -0,0 +1,34 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../../utils.js";
3
+ import type { HTMLSelectAttributes } from "svelte/elements";
4
+
5
+ type Props = WithElementRef<HTMLSelectAttributes> & {
6
+ placeholder?: string;
7
+ };
8
+
9
+ let {
10
+ ref = $bindable(null),
11
+ value = $bindable(""),
12
+ class: className,
13
+ placeholder,
14
+ children,
15
+ ...restProps
16
+ }: Props = $props();
17
+ </script>
18
+
19
+ <select
20
+ bind:this={ref}
21
+ data-slot="select"
22
+ class={cn(
23
+ "dark:bg-input/30 border-input focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 disabled:bg-input/50 dark:disabled:bg-input/80 h-8 w-full appearance-none rounded-lg border bg-transparent px-2.5 py-1 text-base transition-colors focus-visible:ring-3 aria-invalid:ring-3 md:text-sm placeholder:text-muted-foreground outline-none disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 bg-[length:16px] bg-[right_8px_center] bg-no-repeat",
24
+ "bg-[url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e\")]",
25
+ className
26
+ )}
27
+ bind:value
28
+ {...restProps}
29
+ >
30
+ {#if placeholder}
31
+ <option value="" disabled selected>{placeholder}</option>
32
+ {/if}
33
+ {@render children?.()}
34
+ </select>
@@ -0,0 +1,7 @@
1
+ import Root from "./separator.svelte";
2
+
3
+ export {
4
+ Root,
5
+ //
6
+ Root as Separator,
7
+ };
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import { Separator as SeparatorPrimitive } from "bits-ui";
3
+ import { cn } from "../../../utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ "data-slot": dataSlot = "separator",
9
+ ...restProps
10
+ }: SeparatorPrimitive.RootProps = $props();
11
+ </script>
12
+
13
+ <SeparatorPrimitive.Root
14
+ bind:ref
15
+ data-slot={dataSlot}
16
+ class={cn(
17
+ "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px",
18
+ // this is different in shadcn/ui but self-stretch breaks things for us
19
+ "data-[orientation=vertical]:h-full",
20
+ className
21
+ )}
22
+ {...restProps}
23
+ />
@@ -0,0 +1,2 @@
1
+ import Root from "./sheet.svelte";
2
+ export { Root, Root as Sheet };
@@ -0,0 +1,77 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../../utils.js";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ type Props = WithElementRef<HTMLAttributes<HTMLDivElement>> & {
6
+ open?: boolean;
7
+ side?: "left" | "right";
8
+ onClose?: () => void;
9
+ };
10
+
11
+ let {
12
+ ref = $bindable(null),
13
+ open = $bindable(false),
14
+ side = "right",
15
+ onClose,
16
+ class: className,
17
+ children,
18
+ ...restProps
19
+ }: Props = $props();
20
+
21
+ function close() {
22
+ open = false;
23
+ onClose?.();
24
+ }
25
+
26
+ function handleKeydown(e: KeyboardEvent) {
27
+ if (e.key === "Escape") close();
28
+ }
29
+
30
+ $effect(() => {
31
+ if (open) {
32
+ document.addEventListener("keydown", handleKeydown);
33
+ document.body.style.overflow = "hidden";
34
+ return () => {
35
+ document.removeEventListener("keydown", handleKeydown);
36
+ document.body.style.overflow = "";
37
+ };
38
+ }
39
+ });
40
+ </script>
41
+
42
+ {#if open}
43
+ <!-- Overlay -->
44
+ <!-- svelte-ignore a11y_click_events_have_key_events a11y_no_static_element_interactions -->
45
+ <div
46
+ class="fixed inset-0 z-50 bg-black/80 animate-in fade-in-0"
47
+ onclick={close}
48
+ ></div>
49
+
50
+ <!-- Sheet panel -->
51
+ <div
52
+ bind:this={ref}
53
+ data-slot="sheet"
54
+ class={cn(
55
+ "fixed z-50 flex flex-col gap-4 bg-background p-6 shadow-lg transition-transform",
56
+ side === "right"
57
+ ? "inset-y-0 right-0 h-full w-3/4 max-w-sm border-l animate-in slide-in-from-right"
58
+ : "inset-y-0 left-0 h-full w-3/4 max-w-sm border-r animate-in slide-in-from-left",
59
+ className
60
+ )}
61
+ {...restProps}
62
+ >
63
+ {@render children?.()}
64
+
65
+ <!-- Close button -->
66
+ <button
67
+ type="button"
68
+ class="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2"
69
+ onclick={close}
70
+ >
71
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
72
+ <path d="M18 6 6 18"/><path d="m6 6 12 12"/>
73
+ </svg>
74
+ <span class="sr-only">Close</span>
75
+ </button>
76
+ </div>
77
+ {/if}
@@ -0,0 +1,2 @@
1
+ import Root from "./skeleton.svelte";
2
+ export { Root, Root as Skeleton };
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../../utils.js";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ type Props = WithElementRef<HTMLAttributes<HTMLDivElement>> & {
6
+ class?: string;
7
+ };
8
+
9
+ let {
10
+ ref = $bindable(null),
11
+ class: className,
12
+ ...restProps
13
+ }: Props = $props();
14
+ </script>
15
+
16
+ <div
17
+ bind:this={ref}
18
+ data-slot="skeleton"
19
+ class={cn("animate-pulse rounded-md bg-muted", className)}
20
+ {...restProps}
21
+ ></div>
@@ -0,0 +1,2 @@
1
+ import Root from "./switch.svelte";
2
+ export { Root, Root as Switch };
@@ -0,0 +1,49 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../../utils.js";
3
+ import type { HTMLButtonAttributes } from "svelte/elements";
4
+
5
+ type Props = WithElementRef<HTMLButtonAttributes> & {
6
+ checked?: boolean;
7
+ disabled?: boolean;
8
+ onCheckedChange?: (checked: boolean) => void;
9
+ };
10
+
11
+ let {
12
+ ref = $bindable(null),
13
+ checked = $bindable(false),
14
+ disabled = false,
15
+ onCheckedChange,
16
+ class: className,
17
+ ...restProps
18
+ }: Props = $props();
19
+
20
+ function toggle() {
21
+ if (disabled) return;
22
+ checked = !checked;
23
+ onCheckedChange?.(checked);
24
+ }
25
+ </script>
26
+
27
+ <button
28
+ bind:this={ref}
29
+ type="button"
30
+ role="switch"
31
+ aria-checked={checked}
32
+ data-state={checked ? "checked" : "unchecked"}
33
+ data-slot="switch"
34
+ {disabled}
35
+ class={cn(
36
+ "peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-xs transition-all outline-none focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50",
37
+ checked ? "bg-primary" : "bg-input dark:bg-input/80",
38
+ className
39
+ )}
40
+ onclick={toggle}
41
+ {...restProps}
42
+ >
43
+ <span
44
+ class={cn(
45
+ "pointer-events-none block size-4 rounded-full bg-background shadow-lg ring-0 transition-transform",
46
+ checked ? "translate-x-4" : "translate-x-0"
47
+ )}
48
+ ></span>
49
+ </button>
@@ -0,0 +1,28 @@
1
+ import Root from "./table.svelte";
2
+ import Body from "./table-body.svelte";
3
+ import Caption from "./table-caption.svelte";
4
+ import Cell from "./table-cell.svelte";
5
+ import Footer from "./table-footer.svelte";
6
+ import Head from "./table-head.svelte";
7
+ import Header from "./table-header.svelte";
8
+ import Row from "./table-row.svelte";
9
+
10
+ export {
11
+ Root,
12
+ Body,
13
+ Caption,
14
+ Cell,
15
+ Footer,
16
+ Head,
17
+ Header,
18
+ Row,
19
+ //
20
+ Root as Table,
21
+ Body as TableBody,
22
+ Caption as TableCaption,
23
+ Cell as TableCell,
24
+ Footer as TableFooter,
25
+ Head as TableHead,
26
+ Header as TableHeader,
27
+ Row as TableRow,
28
+ };
@@ -0,0 +1,15 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../../utils.js";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLTableSectionElement>> = $props();
11
+ </script>
12
+
13
+ <tbody bind:this={ref} data-slot="table-body" class={cn("[&_tr:last-child]:border-0", className)} {...restProps}>
14
+ {@render children?.()}
15
+ </tbody>
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../../utils.js";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
11
+ </script>
12
+
13
+ <caption
14
+ bind:this={ref}
15
+ data-slot="table-caption"
16
+ class={cn("text-muted-foreground mt-4 text-sm", className)}
17
+ {...restProps}
18
+ >
19
+ {@render children?.()}
20
+ </caption>
@@ -0,0 +1,15 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../../utils.js";
3
+ import type { HTMLTdAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLTdAttributes> = $props();
11
+ </script>
12
+
13
+ <td bind:this={ref} data-slot="table-cell" class={cn("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0", className)} {...restProps}>
14
+ {@render children?.()}
15
+ </td>
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../../utils.js";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLTableSectionElement>> = $props();
11
+ </script>
12
+
13
+ <tfoot
14
+ bind:this={ref}
15
+ data-slot="table-footer"
16
+ class={cn("bg-muted/50 border-t font-medium [&>tr]:last:border-b-0", className)}
17
+ {...restProps}
18
+ >
19
+ {@render children?.()}
20
+ </tfoot>
@@ -0,0 +1,15 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../../utils.js";
3
+ import type { HTMLThAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLThAttributes> = $props();
11
+ </script>
12
+
13
+ <th bind:this={ref} data-slot="table-head" class={cn("text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0", className)} {...restProps}>
14
+ {@render children?.()}
15
+ </th>
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../../utils.js";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLTableSectionElement>> = $props();
11
+ </script>
12
+
13
+ <thead
14
+ bind:this={ref}
15
+ data-slot="table-header"
16
+ class={cn("[&_tr]:border-b", className)}
17
+ {...restProps}
18
+ >
19
+ {@render children?.()}
20
+ </thead>
@@ -0,0 +1,15 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../../utils.js";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLTableRowElement>> = $props();
11
+ </script>
12
+
13
+ <tr bind:this={ref} data-slot="table-row" class={cn("hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors", className)} {...restProps}>
14
+ {@render children?.()}
15
+ </tr>
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import type { HTMLTableAttributes } from "svelte/elements";
3
+ import { cn, type WithElementRef } from "../../../utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLTableAttributes> = $props();
11
+ </script>
12
+
13
+ <div data-slot="table-container" class="relative w-full overflow-x-auto">
14
+ <table bind:this={ref} data-slot="table" class={cn("w-full caption-bottom text-sm", className)} {...restProps}>
15
+ {@render children?.()}
16
+ </table>
17
+ </div>
@@ -0,0 +1,15 @@
1
+ import Tabs from "./tabs.svelte";
2
+ import TabsList from "./tabs-list.svelte";
3
+ import TabsTrigger from "./tabs-trigger.svelte";
4
+ import TabsContent from "./tabs-content.svelte";
5
+
6
+ export {
7
+ Tabs,
8
+ TabsList,
9
+ TabsTrigger,
10
+ TabsContent,
11
+ Tabs as Root,
12
+ TabsList as List,
13
+ TabsTrigger as Trigger,
14
+ TabsContent as Content,
15
+ };
@@ -0,0 +1,30 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../../utils.js";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ type Props = WithElementRef<HTMLAttributes<HTMLDivElement>> & {
6
+ value: string;
7
+ active?: boolean;
8
+ };
9
+
10
+ let {
11
+ ref = $bindable(null),
12
+ value,
13
+ active = false,
14
+ class: className,
15
+ children,
16
+ ...restProps
17
+ }: Props = $props();
18
+ </script>
19
+
20
+ {#if active}
21
+ <div
22
+ bind:this={ref}
23
+ data-slot="tabs-content"
24
+ role="tabpanel"
25
+ class={cn("flex-1 outline-none", className)}
26
+ {...restProps}
27
+ >
28
+ {@render children?.()}
29
+ </div>
30
+ {/if}
@@ -0,0 +1,26 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "../../../utils.js";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ type Props = WithElementRef<HTMLAttributes<HTMLDivElement>>;
6
+
7
+ let {
8
+ ref = $bindable(null),
9
+ class: className,
10
+ children,
11
+ ...restProps
12
+ }: Props = $props();
13
+ </script>
14
+
15
+ <div
16
+ bind:this={ref}
17
+ data-slot="tabs-list"
18
+ class={cn(
19
+ "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px] gap-1",
20
+ className
21
+ )}
22
+ role="tablist"
23
+ {...restProps}
24
+ >
25
+ {@render children?.()}
26
+ </div>