@svadmin/ui 0.0.6 → 0.4.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 (120) hide show
  1. package/package.json +8 -3
  2. package/src/actions.ts +110 -0
  3. package/src/components/AdminApp.svelte +8 -4
  4. package/src/components/Authenticated.svelte +38 -13
  5. package/src/components/AutoForm.svelte +163 -74
  6. package/src/components/AutoSaveIndicator.svelte +35 -0
  7. package/src/components/AutoTable.svelte +476 -183
  8. package/src/components/Breadcrumbs.svelte +22 -17
  9. package/src/components/CatchAllNavigate.svelte +21 -0
  10. package/src/components/ComboboxField.svelte +122 -0
  11. package/src/components/CommandPalette.svelte +93 -0
  12. package/src/components/ConfigErrorScreen.svelte +53 -151
  13. package/src/components/ConfirmDialog.svelte +25 -17
  14. package/src/components/CreatePage.svelte +43 -0
  15. package/src/components/DevTools.svelte +99 -230
  16. package/src/components/DrawerForm.svelte +19 -10
  17. package/src/components/EditPage.svelte +71 -0
  18. package/src/components/EmptyState.svelte +21 -31
  19. package/src/components/ErrorBoundary.svelte +38 -40
  20. package/src/components/ErrorComponent.svelte +36 -0
  21. package/src/components/FieldRenderer.svelte +240 -75
  22. package/src/components/ForgotPasswordPage.svelte +20 -111
  23. package/src/components/Header.svelte +46 -57
  24. package/src/components/InferencerPanel.svelte +136 -110
  25. package/src/components/InfiniteList.svelte +93 -0
  26. package/src/components/Layout.svelte +85 -22
  27. package/src/components/ListPage.svelte +71 -0
  28. package/src/components/LiveIndicator.svelte +58 -0
  29. package/src/components/LoginPage.svelte +33 -154
  30. package/src/components/ModalForm.svelte +6 -2
  31. package/src/components/NavigateToResource.svelte +20 -0
  32. package/src/components/PageSkeleton.svelte +71 -0
  33. package/src/components/PasswordInput.svelte +95 -0
  34. package/src/components/RegisterPage.svelte +35 -164
  35. package/src/components/ShowPage.svelte +35 -36
  36. package/src/components/Sidebar.svelte +212 -81
  37. package/src/components/StatsCard.svelte +12 -3
  38. package/src/components/StepsForm.svelte +139 -0
  39. package/src/components/ThemedTitle.svelte +32 -0
  40. package/src/components/Toast.svelte +15 -44
  41. package/src/components/TooltipButton.svelte +52 -0
  42. package/src/components/UndoableNotification.svelte +28 -96
  43. package/src/components/UpdatePasswordPage.svelte +32 -160
  44. package/src/components/buttons/CloneButton.svelte +1 -1
  45. package/src/components/buttons/CreateButton.svelte +1 -1
  46. package/src/components/buttons/DeleteButton.svelte +3 -4
  47. package/src/components/buttons/EditButton.svelte +1 -1
  48. package/src/components/buttons/ImportButton.svelte +29 -7
  49. package/src/components/buttons/RefreshButton.svelte +11 -5
  50. package/src/components/fieldComponentMap.ts +79 -0
  51. package/src/components/fields/BooleanField.svelte +13 -0
  52. package/src/components/fields/DateField.svelte +6 -0
  53. package/src/components/fields/EmailField.svelte +9 -0
  54. package/src/components/fields/FileField.svelte +14 -0
  55. package/src/components/fields/ImageField.svelte +9 -0
  56. package/src/components/fields/JsonField.svelte +72 -0
  57. package/src/components/fields/MarkdownField.svelte +9 -0
  58. package/src/components/fields/MultiSelectField.svelte +20 -0
  59. package/src/components/fields/NumberField.svelte +6 -0
  60. package/src/components/fields/RelationField.svelte +24 -0
  61. package/src/components/fields/RichTextField.svelte +35 -0
  62. package/src/components/fields/SelectField.svelte +14 -0
  63. package/src/components/fields/TagField.svelte +12 -0
  64. package/src/components/fields/TextField.svelte +11 -0
  65. package/src/components/fields/UrlField.svelte +14 -0
  66. package/src/components/ui/alert-dialog/alert-dialog-content.svelte +25 -0
  67. package/src/components/ui/alert-dialog/alert-dialog-description.svelte +16 -0
  68. package/src/components/ui/alert-dialog/alert-dialog-footer.svelte +8 -0
  69. package/src/components/ui/alert-dialog/alert-dialog-header.svelte +8 -0
  70. package/src/components/ui/alert-dialog/alert-dialog-overlay.svelte +16 -0
  71. package/src/components/ui/alert-dialog/alert-dialog-portal.svelte +6 -0
  72. package/src/components/ui/alert-dialog/alert-dialog-title.svelte +16 -0
  73. package/src/components/ui/alert-dialog/index.ts +20 -0
  74. package/src/components/ui/avatar/avatar.svelte +2 -1
  75. package/src/components/ui/breadcrumb/breadcrumb-ellipsis.svelte +18 -0
  76. package/src/components/ui/breadcrumb/breadcrumb-item.svelte +15 -0
  77. package/src/components/ui/breadcrumb/breadcrumb-link.svelte +15 -0
  78. package/src/components/ui/breadcrumb/breadcrumb-list.svelte +15 -0
  79. package/src/components/ui/breadcrumb/breadcrumb-page.svelte +18 -0
  80. package/src/components/ui/breadcrumb/breadcrumb-separator.svelte +22 -0
  81. package/src/components/ui/breadcrumb/breadcrumb.svelte +11 -0
  82. package/src/components/ui/breadcrumb/index.ts +7 -0
  83. package/src/components/ui/collapsible/index.ts +7 -0
  84. package/src/components/ui/command/command-dialog.svelte +31 -0
  85. package/src/components/ui/command/index.ts +2 -0
  86. package/src/components/ui/context-menu/index.ts +11 -0
  87. package/src/components/ui/drawer/drawer-content.svelte +21 -0
  88. package/src/components/ui/drawer/drawer-description.svelte +11 -0
  89. package/src/components/ui/drawer/drawer-footer.svelte +11 -0
  90. package/src/components/ui/drawer/drawer-header.svelte +11 -0
  91. package/src/components/ui/drawer/drawer-title.svelte +11 -0
  92. package/src/components/ui/drawer/drawer.svelte +18 -0
  93. package/src/components/ui/drawer/index.ts +6 -0
  94. package/src/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +43 -0
  95. package/src/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +27 -0
  96. package/src/components/ui/dropdown-menu/index.ts +6 -0
  97. package/src/components/ui/label/index.ts +1 -0
  98. package/src/components/ui/label/label.svelte +18 -0
  99. package/src/components/ui/pagination/index.ts +7 -0
  100. package/src/components/ui/pagination/pagination-content.svelte +11 -0
  101. package/src/components/ui/pagination/pagination-ellipsis.svelte +12 -0
  102. package/src/components/ui/pagination/pagination-item.svelte +11 -0
  103. package/src/components/ui/pagination/pagination-link.svelte +26 -0
  104. package/src/components/ui/pagination/pagination-next.svelte +22 -0
  105. package/src/components/ui/pagination/pagination-previous.svelte +22 -0
  106. package/src/components/ui/pagination/pagination.svelte +11 -0
  107. package/src/components/ui/popover/index.ts +12 -0
  108. package/src/components/ui/popover/popover-content.svelte +25 -0
  109. package/src/components/ui/progress/index.ts +1 -0
  110. package/src/components/ui/progress/progress.svelte +22 -0
  111. package/src/components/ui/scroll-area/index.ts +1 -0
  112. package/src/components/ui/scroll-area/scroll-area.svelte +20 -0
  113. package/src/components/ui/sheet/index.ts +15 -1
  114. package/src/components/ui/sheet/sheet-content.svelte +28 -0
  115. package/src/components/ui/sheet/sheet-description.svelte +22 -0
  116. package/src/components/ui/sheet/sheet-footer.svelte +22 -0
  117. package/src/components/ui/sheet/sheet-header.svelte +22 -0
  118. package/src/components/ui/sheet/sheet-title.svelte +22 -0
  119. package/src/index.ts +52 -1
  120. package/src/router-state.svelte.ts +16 -9
@@ -0,0 +1,6 @@
1
+ <script lang="ts">
2
+ interface Props { value: string | number | Date | null | undefined; locale?: string; options?: Intl.DateTimeFormatOptions }
3
+ let { value, locale = 'en-US', options = { dateStyle: 'medium' } }: Props = $props();
4
+ const formatted = $derived(value != null ? new Intl.DateTimeFormat(locale, options).format(new Date(value as string | number | Date)) : '—');
5
+ </script>
6
+ <span class="field-date">{formatted}</span>
@@ -0,0 +1,9 @@
1
+ <script lang="ts">
2
+ interface Props { value: string | null | undefined }
3
+ let { value }: Props = $props();
4
+ </script>
5
+ {#if value}
6
+ <a href="mailto:{value}" class="text-primary hover:underline no-underline">{value}</a>
7
+ {:else}
8
+ <span class="text-muted-foreground">—</span>
9
+ {/if}
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ import { Download } from 'lucide-svelte';
3
+ interface Props { value: string | null | undefined; title?: string }
4
+ let { value, title }: Props = $props();
5
+ const fileName = $derived(value ? value.split('/').pop() ?? value : null);
6
+ </script>
7
+ {#if value}
8
+ <a href={value} download class="text-primary hover:underline no-underline inline-flex items-center gap-1" title={title ?? fileName ?? ''}>
9
+ <Download class="h-3.5 w-3.5 opacity-60" />
10
+ {fileName}
11
+ </a>
12
+ {:else}
13
+ <span class="text-muted-foreground">—</span>
14
+ {/if}
@@ -0,0 +1,9 @@
1
+ <script lang="ts">
2
+ interface Props { value: string | null | undefined; alt?: string; width?: number; height?: number }
3
+ let { value, alt = '', width = 80, height = 80 }: Props = $props();
4
+ </script>
5
+ {#if value}
6
+ <img src={value} {alt} {width} {height} class="rounded-lg object-cover border border-border" />
7
+ {:else}
8
+ <span class="inline-flex items-center justify-center w-20 h-20 bg-muted rounded-lg text-muted-foreground">—</span>
9
+ {/if}
@@ -0,0 +1,72 @@
1
+ <script lang="ts">
2
+ import { t } from '@svadmin/core/i18n';
3
+ import { Button } from '../ui/button/index.js';
4
+ import { Copy, Check, ChevronDown, ChevronRight } from 'lucide-svelte';
5
+
6
+ let { value } = $props<{
7
+ value: unknown;
8
+ }>();
9
+
10
+ let expanded = $state(false);
11
+ let copied = $state(false);
12
+ let copyTimer: ReturnType<typeof setTimeout> | undefined;
13
+
14
+ $effect(() => {
15
+ return () => { if (copyTimer) clearTimeout(copyTimer); };
16
+ });
17
+
18
+ const formatted = $derived(
19
+ value != null ? JSON.stringify(value, null, 2) : '—'
20
+ );
21
+
22
+ const preview = $derived(
23
+ value != null ? JSON.stringify(value).slice(0, 80) + (JSON.stringify(value).length > 80 ? '...' : '') : '—'
24
+ );
25
+
26
+ function copyJson() {
27
+ navigator.clipboard.writeText(formatted);
28
+ copied = true;
29
+ if (copyTimer) clearTimeout(copyTimer);
30
+ copyTimer = setTimeout(() => { copied = false; }, 2000);
31
+ }
32
+ </script>
33
+
34
+ {#if value == null}
35
+ <span class="text-muted-foreground">—</span>
36
+ {:else}
37
+ <div class="space-y-1">
38
+ <div class="flex items-center gap-2">
39
+ <Button
40
+ variant="ghost"
41
+ size="sm"
42
+ class="flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground h-auto py-0.5 px-1"
43
+ onclick={() => { expanded = !expanded; }}
44
+ >
45
+ {#if expanded}
46
+ <ChevronDown class="h-3 w-3" />
47
+ {:else}
48
+ <ChevronRight class="h-3 w-3" />
49
+ {/if}
50
+ {expanded ? t('common.collapse') : t('common.expand')}
51
+ </Button>
52
+ <Button
53
+ variant="ghost"
54
+ size="sm"
55
+ class="flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground h-auto py-0.5 px-1"
56
+ onclick={copyJson}
57
+ aria-label={t('common.copy')}
58
+ >
59
+ {#if copied}
60
+ <Check class="h-3 w-3 text-emerald-500" />
61
+ {:else}
62
+ <Copy class="h-3 w-3" />
63
+ {/if}
64
+ </Button>
65
+ </div>
66
+ {#if expanded}
67
+ <pre class="rounded-lg bg-muted p-3 text-xs overflow-auto max-h-64 font-mono">{formatted}</pre>
68
+ {:else}
69
+ <code class="text-xs font-mono bg-muted px-1.5 py-0.5 rounded">{preview}</code>
70
+ {/if}
71
+ </div>
72
+ {/if}
@@ -0,0 +1,9 @@
1
+ <script lang="ts">
2
+ interface Props { value: string | null | undefined }
3
+ let { value }: Props = $props();
4
+ </script>
5
+ {#if value}
6
+ <div class="prose prose-sm dark:prose-invert max-w-none leading-relaxed [&_code]:bg-muted [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:rounded [&_code]:text-[0.875em] [&_pre]:bg-muted [&_pre]:p-3 [&_pre]:rounded-lg [&_pre]:overflow-x-auto [&_a]:text-primary">{@html value}</div>
7
+ {:else}
8
+ <span class="text-muted-foreground">—</span>
9
+ {/if}
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { Badge } from '../ui/badge/index.js';
3
+
4
+ let { value } = $props<{
5
+ value: (string | number)[] | null | undefined;
6
+ options?: { label: string; value: string | number }[];
7
+ }>();
8
+
9
+ const items = $derived(Array.isArray(value) ? value : []);
10
+ </script>
11
+
12
+ {#if items.length > 0}
13
+ <div class="flex flex-wrap gap-1">
14
+ {#each items as item}
15
+ <Badge variant="secondary">{String(item)}</Badge>
16
+ {/each}
17
+ </div>
18
+ {:else}
19
+ <span class="text-muted-foreground">—</span>
20
+ {/if}
@@ -0,0 +1,6 @@
1
+ <script lang="ts">
2
+ interface Props { value: number | string | null | undefined; locale?: string; options?: Intl.NumberFormatOptions }
3
+ let { value, locale = 'en-US', options = {} }: Props = $props();
4
+ const formatted = $derived(value != null ? new Intl.NumberFormat(locale, options).format(Number(value)) : '—');
5
+ </script>
6
+ <span class="field-number">{formatted}</span>
@@ -0,0 +1,24 @@
1
+ <script lang="ts">
2
+ import { ExternalLink } from 'lucide-svelte';
3
+
4
+ let { value, resourceName, displayValue } = $props<{
5
+ value: string | number | null | undefined;
6
+ resourceName?: string;
7
+ displayValue?: string;
8
+ }>();
9
+
10
+ const display = $derived(displayValue ?? (value != null ? `#${value}` : '—'));
11
+ const href = $derived(resourceName && value != null ? `#/${resourceName}/show/${value}` : undefined);
12
+ </script>
13
+
14
+ {#if href}
15
+ <a
16
+ {href}
17
+ class="inline-flex items-center gap-1 text-primary hover:underline text-sm"
18
+ >
19
+ {display}
20
+ <ExternalLink class="h-3 w-3" />
21
+ </a>
22
+ {:else}
23
+ <span class="text-muted-foreground">{display}</span>
24
+ {/if}
@@ -0,0 +1,35 @@
1
+ <script lang="ts">
2
+ import { t } from '@svadmin/core/i18n';
3
+ import { Button } from '../ui/button/index.js';
4
+
5
+ let { value, maxLength = 200 } = $props<{
6
+ value: string | null | undefined;
7
+ maxLength?: number;
8
+ }>();
9
+
10
+ const text = $derived(value ?? '');
11
+ const truncated = $derived(text.length > maxLength);
12
+ const display = $derived(truncated ? text.slice(0, maxLength) + '...' : text);
13
+
14
+ let showFull = $state(false);
15
+ </script>
16
+
17
+ {#if !text}
18
+ <span class="text-muted-foreground">—</span>
19
+ {:else}
20
+ <div class="prose prose-sm dark:prose-invert max-w-none">
21
+ <p class="whitespace-pre-wrap text-sm leading-relaxed">
22
+ {showFull ? text : display}
23
+ </p>
24
+ {#if truncated}
25
+ <Button
26
+ variant="link"
27
+ size="sm"
28
+ class="text-xs text-primary h-auto p-0"
29
+ onclick={() => { showFull = !showFull; }}
30
+ >
31
+ {showFull ? t('common.showLess') : t('common.showMore')}
32
+ </Button>
33
+ {/if}
34
+ </div>
35
+ {/if}
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ import { Badge } from '../ui/badge/index.js';
3
+
4
+ let { value, options } = $props<{
5
+ value: string | number | null | undefined;
6
+ options?: { label: string; value: string | number }[];
7
+ }>();
8
+
9
+ const label = $derived(
10
+ options?.find(o => o.value === value)?.label ?? (value != null ? String(value) : '—')
11
+ );
12
+ </script>
13
+
14
+ <Badge variant="outline">{label}</Badge>
@@ -0,0 +1,12 @@
1
+ <script lang="ts">
2
+ import { Badge } from '../ui/badge/index.js';
3
+ interface Props { value: string | string[] | null | undefined }
4
+ let { value }: Props = $props();
5
+ const tags = $derived(Array.isArray(value) ? value : value ? [value] : []);
6
+ </script>
7
+ <span class="inline-flex flex-wrap gap-1">
8
+ {#each tags as tag}
9
+ <Badge variant="secondary">{tag}</Badge>
10
+ {/each}
11
+ {#if tags.length === 0}<span class="text-muted-foreground">—</span>{/if}
12
+ </span>
@@ -0,0 +1,11 @@
1
+ <script lang="ts">
2
+ interface Props { value: string | null | undefined; maxLength?: number }
3
+ let { value, maxLength }: Props = $props();
4
+ const display = $derived(value && maxLength && value.length > maxLength ? value.slice(0, maxLength) + '…' : value);
5
+ const needsTooltip = $derived(value && maxLength && value.length > maxLength);
6
+ </script>
7
+ {#if value}
8
+ <span class="inline-block" title={needsTooltip ? value : undefined}>{display}</span>
9
+ {:else}
10
+ <span class="text-muted-foreground">—</span>
11
+ {/if}
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ import { ExternalLink } from 'lucide-svelte';
3
+ interface Props { value: string | null | undefined; label?: string }
4
+ let { value, label }: Props = $props();
5
+ const display = $derived(label ?? value ?? '');
6
+ </script>
7
+ {#if value}
8
+ <a href={value} target="_blank" rel="noopener noreferrer" class="text-primary hover:underline no-underline inline-flex items-center gap-1">
9
+ {display}
10
+ <ExternalLink class="h-3 w-3 opacity-60" />
11
+ </a>
12
+ {:else}
13
+ <span class="text-muted-foreground">—</span>
14
+ {/if}
@@ -0,0 +1,25 @@
1
+ <script lang="ts">
2
+ import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
3
+ import type { WithoutChildrenOrChild } from "bits-ui";
4
+ import { cn } from "../../../utils.js";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ ...restProps
10
+ }: WithoutChildrenOrChild<AlertDialogPrimitive.ContentProps> & { class?: string } = $props();
11
+ </script>
12
+
13
+ <AlertDialogPrimitive.Portal>
14
+ <AlertDialogPrimitive.Overlay
15
+ class="fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0"
16
+ />
17
+ <AlertDialogPrimitive.Content
18
+ bind:ref
19
+ class={cn(
20
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
21
+ className,
22
+ )}
23
+ {...restProps}
24
+ />
25
+ </AlertDialogPrimitive.Portal>
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
3
+ import { cn } from "../../../utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ ...restProps
9
+ }: AlertDialogPrimitive.DescriptionProps & { class?: string } = $props();
10
+ </script>
11
+
12
+ <AlertDialogPrimitive.Description
13
+ bind:ref
14
+ class={cn("text-sm text-muted-foreground", className)}
15
+ {...restProps}
16
+ />
@@ -0,0 +1,8 @@
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ import { cn } from "../../../utils.js";
4
+
5
+ let { class: className, ...restProps }: HTMLAttributes<HTMLDivElement> = $props();
6
+ </script>
7
+
8
+ <div class={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)} {...restProps}></div>
@@ -0,0 +1,8 @@
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ import { cn } from "../../../utils.js";
4
+
5
+ let { class: className, ...restProps }: HTMLAttributes<HTMLDivElement> = $props();
6
+ </script>
7
+
8
+ <div class={cn("flex flex-col space-y-2 text-center sm:text-left", className)} {...restProps}></div>
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
3
+ import { cn } from "../../../utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ ...restProps
9
+ }: AlertDialogPrimitive.OverlayProps & { class?: string } = $props();
10
+ </script>
11
+
12
+ <AlertDialogPrimitive.Overlay
13
+ bind:ref
14
+ class={cn("fixed inset-0 z-50 bg-black/80", className)}
15
+ {...restProps}
16
+ />
@@ -0,0 +1,6 @@
1
+ <script lang="ts">
2
+ import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
3
+ let { ...restProps }: AlertDialogPrimitive.PortalProps = $props();
4
+ </script>
5
+
6
+ <AlertDialogPrimitive.Portal {...restProps} />
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
3
+ import { cn } from "../../../utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ ...restProps
9
+ }: AlertDialogPrimitive.TitleProps & { class?: string } = $props();
10
+ </script>
11
+
12
+ <AlertDialogPrimitive.Title
13
+ bind:ref
14
+ class={cn("text-lg font-semibold", className)}
15
+ {...restProps}
16
+ />
@@ -0,0 +1,20 @@
1
+ import { AlertDialog as AlertDialogPrimitive } from "bits-ui";
2
+
3
+ const Root = AlertDialogPrimitive.Root;
4
+ const Trigger = AlertDialogPrimitive.Trigger;
5
+ const Action = AlertDialogPrimitive.Action;
6
+ const Cancel = AlertDialogPrimitive.Cancel;
7
+
8
+ export {
9
+ Root,
10
+ Trigger,
11
+ Action,
12
+ Cancel,
13
+ };
14
+ export { default as Content } from "./alert-dialog-content.svelte";
15
+ export { default as Description } from "./alert-dialog-description.svelte";
16
+ export { default as Footer } from "./alert-dialog-footer.svelte";
17
+ export { default as Header } from "./alert-dialog-header.svelte";
18
+ export { default as Overlay } from "./alert-dialog-overlay.svelte";
19
+ export { default as Portal } from "./alert-dialog-portal.svelte";
20
+ export { default as Title } from "./alert-dialog-title.svelte";
@@ -16,7 +16,8 @@
16
16
  defaultVariants: { size: "default" },
17
17
  });
18
18
 
19
- export type AvatarSize = VariantProps<typeof avatarVariants>["size"];
19
+ // AvatarSize type is exported from the package index.ts
20
+ type AvatarSize = VariantProps<typeof avatarVariants>["size"];
20
21
 
21
22
  type Props = WithElementRef<HTMLImgAttributes> & {
22
23
  size?: AvatarSize;
@@ -0,0 +1,18 @@
1
+ <script lang="ts">
2
+ import { cn } from '../../../utils.js';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import { Ellipsis } from 'lucide-svelte';
5
+
6
+ let { class: className, ...restProps }: HTMLAttributes<HTMLSpanElement> = $props();
7
+ </script>
8
+
9
+ <span
10
+ role="presentation"
11
+ aria-hidden="true"
12
+ data-slot="breadcrumb-ellipsis"
13
+ class={cn("flex size-9 items-center justify-center", className)}
14
+ {...restProps}
15
+ >
16
+ <Ellipsis class="size-4" />
17
+ <span class="sr-only">More</span>
18
+ </span>
@@ -0,0 +1,15 @@
1
+ <script lang="ts">
2
+ import { cn } from '../../../utils.js';
3
+ import type { Snippet } from 'svelte';
4
+ import type { HTMLLiAttributes } from 'svelte/elements';
5
+
6
+ let { class: className, children, ...restProps }: HTMLLiAttributes & { children?: Snippet } = $props();
7
+ </script>
8
+
9
+ <li
10
+ data-slot="breadcrumb-item"
11
+ class={cn("inline-flex items-center gap-1.5", className)}
12
+ {...restProps}
13
+ >
14
+ {@render children?.()}
15
+ </li>
@@ -0,0 +1,15 @@
1
+ <script lang="ts">
2
+ import { cn } from '../../../utils.js';
3
+ import type { Snippet } from 'svelte';
4
+ import type { HTMLAnchorAttributes } from 'svelte/elements';
5
+
6
+ let { class: className, children, ...restProps }: HTMLAnchorAttributes & { children?: Snippet } = $props();
7
+ </script>
8
+
9
+ <a
10
+ data-slot="breadcrumb-link"
11
+ class={cn("hover:text-foreground transition-colors", className)}
12
+ {...restProps}
13
+ >
14
+ {@render children?.()}
15
+ </a>
@@ -0,0 +1,15 @@
1
+ <script lang="ts">
2
+ import { cn } from '../../../utils.js';
3
+ import type { Snippet } from 'svelte';
4
+ import type { HTMLOlAttributes } from 'svelte/elements';
5
+
6
+ let { class: className, children, ...restProps }: HTMLOlAttributes & { children?: Snippet } = $props();
7
+ </script>
8
+
9
+ <ol
10
+ data-slot="breadcrumb-list"
11
+ class={cn("text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5", className)}
12
+ {...restProps}
13
+ >
14
+ {@render children?.()}
15
+ </ol>
@@ -0,0 +1,18 @@
1
+ <script lang="ts">
2
+ import { cn } from '../../../utils.js';
3
+ import type { Snippet } from 'svelte';
4
+ import type { HTMLAttributes } from 'svelte/elements';
5
+
6
+ let { class: className, children, ...restProps }: HTMLAttributes<HTMLSpanElement> & { children?: Snippet } = $props();
7
+ </script>
8
+
9
+ <span
10
+ role="link"
11
+ aria-disabled="true"
12
+ aria-current="page"
13
+ data-slot="breadcrumb-page"
14
+ class={cn("text-foreground font-normal", className)}
15
+ {...restProps}
16
+ >
17
+ {@render children?.()}
18
+ </span>
@@ -0,0 +1,22 @@
1
+ <script lang="ts">
2
+ import { cn } from '../../../utils.js';
3
+ import type { Snippet } from 'svelte';
4
+ import type { HTMLLiAttributes } from 'svelte/elements';
5
+ import { ChevronRight } from 'lucide-svelte';
6
+
7
+ let { class: className, children, ...restProps }: HTMLLiAttributes & { children?: Snippet } = $props();
8
+ </script>
9
+
10
+ <li
11
+ role="presentation"
12
+ aria-hidden="true"
13
+ data-slot="breadcrumb-separator"
14
+ class={cn("[&>svg]:size-3.5", className)}
15
+ {...restProps}
16
+ >
17
+ {#if children}
18
+ {@render children()}
19
+ {:else}
20
+ <ChevronRight />
21
+ {/if}
22
+ </li>
@@ -0,0 +1,11 @@
1
+ <script lang="ts">
2
+ import { cn } from '../../../utils.js';
3
+ import type { Snippet } from 'svelte';
4
+ import type { HTMLAttributes } from 'svelte/elements';
5
+
6
+ let { class: className, children, ...restProps }: HTMLAttributes<HTMLElement> & { children?: Snippet } = $props();
7
+ </script>
8
+
9
+ <nav aria-label="breadcrumb" data-slot="breadcrumb" class={cn("", className)} {...restProps}>
10
+ {@render children?.()}
11
+ </nav>
@@ -0,0 +1,7 @@
1
+ export { default as Root } from './breadcrumb.svelte';
2
+ export { default as Item } from './breadcrumb-item.svelte';
3
+ export { default as Link } from './breadcrumb-link.svelte';
4
+ export { default as Page } from './breadcrumb-page.svelte';
5
+ export { default as Separator } from './breadcrumb-separator.svelte';
6
+ export { default as Ellipsis } from './breadcrumb-ellipsis.svelte';
7
+ export { default as List } from './breadcrumb-list.svelte';
@@ -0,0 +1,7 @@
1
+ import { Collapsible as CollapsiblePrimitive } from 'bits-ui';
2
+
3
+ const Root = CollapsiblePrimitive.Root;
4
+ const Trigger = CollapsiblePrimitive.Trigger;
5
+ const Content = CollapsiblePrimitive.Content;
6
+
7
+ export { Root, Trigger, Content };
@@ -0,0 +1,31 @@
1
+ <script lang="ts">
2
+ import { Command } from 'cmdk-sv';
3
+ import * as Dialog from '../dialog/index.js';
4
+ import { cn } from '../../../utils.js';
5
+ import type { Snippet } from 'svelte';
6
+
7
+ let {
8
+ open = $bindable(false),
9
+ class: className,
10
+ children,
11
+ ...restProps
12
+ }: {
13
+ open?: boolean;
14
+ class?: string;
15
+ children?: Snippet;
16
+ [key: string]: unknown;
17
+ } = $props();
18
+ </script>
19
+
20
+ <Dialog.Dialog bind:open {...restProps}>
21
+ <Dialog.DialogContent class="overflow-hidden p-0">
22
+ <Command.Root
23
+ class={cn(
24
+ "[&_[data-cmdk-group-heading]]:text-muted-foreground flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground [&_[data-cmdk-group-heading]]:px-2 [&_[data-cmdk-group-heading]]:font-medium [&_[data-cmdk-group]:not([hidden])_~[data-cmdk-group]]:pt-0 [&_[data-cmdk-input-wrapper]_svg]:h-5 [&_[data-cmdk-input-wrapper]_svg]:w-5 [&_[data-cmdk-input]]:h-12 [&_[data-cmdk-item]]:px-2 [&_[data-cmdk-item]]:py-3",
25
+ className
26
+ )}
27
+ >
28
+ {@render children?.()}
29
+ </Command.Root>
30
+ </Dialog.DialogContent>
31
+ </Dialog.Dialog>
@@ -0,0 +1,2 @@
1
+ export { Command as Root, Command } from 'cmdk-sv';
2
+ export { default as CommandDialog } from './command-dialog.svelte';
@@ -0,0 +1,11 @@
1
+ import { ContextMenu as ContextMenuPrimitive } from 'bits-ui';
2
+
3
+ const Root = ContextMenuPrimitive.Root;
4
+ const Trigger = ContextMenuPrimitive.Trigger;
5
+ const Content = ContextMenuPrimitive.Content;
6
+ const Item = ContextMenuPrimitive.Item;
7
+ const Separator = ContextMenuPrimitive.Separator;
8
+ const Group = ContextMenuPrimitive.Group;
9
+ const GroupHeading = ContextMenuPrimitive.GroupHeading;
10
+
11
+ export { Root, Trigger, Content, Item, Separator, Group, GroupHeading };
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import { Drawer as DrawerPrimitive } from 'vaul-svelte';
3
+ import { cn } from '../../../utils.js';
4
+ import type { Snippet } from 'svelte';
5
+
6
+ let { class: className, children, ...restProps }: { class?: string; children?: Snippet; [key: string]: unknown } = $props();
7
+ </script>
8
+
9
+ <DrawerPrimitive.Portal>
10
+ <DrawerPrimitive.Overlay class="fixed inset-0 z-50 bg-black/80" />
11
+ <DrawerPrimitive.Content
12
+ class={cn(
13
+ "bg-background fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border",
14
+ className
15
+ )}
16
+ {...restProps}
17
+ >
18
+ <div class="bg-muted mx-auto mt-4 h-2 w-[100px] rounded-full"></div>
19
+ {@render children?.()}
20
+ </DrawerPrimitive.Content>
21
+ </DrawerPrimitive.Portal>
@@ -0,0 +1,11 @@
1
+ <script lang="ts">
2
+ import { Drawer as DrawerPrimitive } from 'vaul-svelte';
3
+ import { cn } from '../../../utils.js';
4
+ import type { Snippet } from 'svelte';
5
+
6
+ let { class: className, children, ...restProps }: { class?: string; children?: Snippet; [key: string]: unknown } = $props();
7
+ </script>
8
+
9
+ <DrawerPrimitive.Description class={cn("text-muted-foreground text-sm", className)} {...restProps}>
10
+ {@render children?.()}
11
+ </DrawerPrimitive.Description>