@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,37 @@
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
+ 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
+ <button
21
+ bind:this={ref}
22
+ type="button"
23
+ role="tab"
24
+ data-slot="tabs-trigger"
25
+ data-state={active ? "active" : "inactive"}
26
+ aria-selected={active}
27
+ class={cn(
28
+ "inline-flex items-center justify-center gap-1.5 whitespace-nowrap rounded-md px-2.5 py-1 text-sm font-medium transition-all outline-none focus-visible:ring-2 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0",
29
+ active
30
+ ? "bg-background text-foreground shadow-sm"
31
+ : "text-muted-foreground hover:text-foreground",
32
+ className
33
+ )}
34
+ {...restProps}
35
+ >
36
+ {@render children?.()}
37
+ </button>
@@ -0,0 +1,27 @@
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
+ onValueChange?: (value: string) => void;
8
+ };
9
+
10
+ let {
11
+ ref = $bindable(null),
12
+ value = $bindable(""),
13
+ onValueChange,
14
+ class: className,
15
+ children,
16
+ ...restProps
17
+ }: Props = $props();
18
+ </script>
19
+
20
+ <div
21
+ bind:this={ref}
22
+ data-slot="tabs"
23
+ class={cn("flex flex-col gap-2", className)}
24
+ {...restProps}
25
+ >
26
+ {@render children?.()}
27
+ </div>
@@ -0,0 +1,2 @@
1
+ import Root from "./textarea.svelte";
2
+ export { Root, Root as Textarea };
@@ -0,0 +1,24 @@
1
+ <script lang="ts">
2
+ import type { HTMLTextareaAttributes } from "svelte/elements";
3
+ import { cn, type WithElementRef } from "../../../utils.js";
4
+
5
+ type Props = WithElementRef<HTMLTextareaAttributes>;
6
+
7
+ let {
8
+ ref = $bindable(null),
9
+ value = $bindable(),
10
+ class: className,
11
+ ...restProps
12
+ }: Props = $props();
13
+ </script>
14
+
15
+ <textarea
16
+ bind:this={ref}
17
+ data-slot="textarea"
18
+ class={cn(
19
+ "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 w-full rounded-lg border bg-transparent px-3 py-2 text-base transition-colors focus-visible:ring-3 aria-invalid:ring-3 md:text-sm placeholder:text-muted-foreground min-h-[80px] outline-none disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 resize-y",
20
+ className
21
+ )}
22
+ bind:value
23
+ {...restProps}
24
+ ></textarea>
@@ -0,0 +1,19 @@
1
+ import Root from "./tooltip.svelte";
2
+ import Trigger from "./tooltip-trigger.svelte";
3
+ import Content from "./tooltip-content.svelte";
4
+ import Provider from "./tooltip-provider.svelte";
5
+ import Portal from "./tooltip-portal.svelte";
6
+
7
+ export {
8
+ Root,
9
+ Trigger,
10
+ Content,
11
+ Provider,
12
+ Portal,
13
+ //
14
+ Root as Tooltip,
15
+ Content as TooltipContent,
16
+ Trigger as TooltipTrigger,
17
+ Provider as TooltipProvider,
18
+ Portal as TooltipPortal,
19
+ };
@@ -0,0 +1,52 @@
1
+ <script lang="ts">
2
+ import { Tooltip as TooltipPrimitive } from "bits-ui";
3
+ import { cn } from "../../../utils.js";
4
+ import TooltipPortal from "./tooltip-portal.svelte";
5
+ import type { ComponentProps } from "svelte";
6
+ import type { WithoutChildrenOrChild } from "../../../utils.js";
7
+
8
+ let {
9
+ ref = $bindable(null),
10
+ class: className,
11
+ sideOffset = 0,
12
+ side = "top",
13
+ children,
14
+ arrowClasses,
15
+ portalProps,
16
+ ...restProps
17
+ }: TooltipPrimitive.ContentProps & {
18
+ arrowClasses?: string;
19
+ portalProps?: WithoutChildrenOrChild<ComponentProps<typeof TooltipPortal>>;
20
+ } = $props();
21
+ </script>
22
+
23
+ <TooltipPortal {...portalProps}>
24
+ <TooltipPrimitive.Content
25
+ bind:ref
26
+ data-slot="tooltip-content"
27
+ {sideOffset}
28
+ {side}
29
+ class={cn(
30
+ "data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-xs has-data-[slot=kbd]:pr-1.5 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm bg-foreground text-background z-50 w-fit max-w-xs origin-(--bits-tooltip-content-transform-origin)",
31
+ className
32
+ )}
33
+ {...restProps}
34
+ >
35
+ {@render children?.()}
36
+ <TooltipPrimitive.Arrow>
37
+ {#snippet child({ props })}
38
+ <div
39
+ class={cn(
40
+ "size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground z-50",
41
+ "data-[side=top]:translate-x-1/2 data-[side=top]:translate-y-[calc(-50%+2px)]",
42
+ "data-[side=bottom]:-translate-x-1/2 data-[side=bottom]:-translate-y-[calc(-50%+1px)]",
43
+ "data-[side=right]:translate-x-[calc(50%+2px)] data-[side=right]:translate-y-1/2",
44
+ "data-[side=left]:-translate-y-[calc(50%-3px)]",
45
+ arrowClasses
46
+ )}
47
+ {...props}
48
+ ></div>
49
+ {/snippet}
50
+ </TooltipPrimitive.Arrow>
51
+ </TooltipPrimitive.Content>
52
+ </TooltipPortal>
@@ -0,0 +1,7 @@
1
+ <script lang="ts">
2
+ import { Tooltip as TooltipPrimitive } from "bits-ui";
3
+
4
+ let { ...restProps }: TooltipPrimitive.PortalProps = $props();
5
+ </script>
6
+
7
+ <TooltipPrimitive.Portal {...restProps} />
@@ -0,0 +1,7 @@
1
+ <script lang="ts">
2
+ import { Tooltip as TooltipPrimitive } from "bits-ui";
3
+
4
+ let { delayDuration = 0, ...restProps }: TooltipPrimitive.ProviderProps = $props();
5
+ </script>
6
+
7
+ <TooltipPrimitive.Provider {delayDuration} {...restProps} />
@@ -0,0 +1,7 @@
1
+ <script lang="ts">
2
+ import { Tooltip as TooltipPrimitive } from "bits-ui";
3
+
4
+ let { ref = $bindable(null), ...restProps }: TooltipPrimitive.TriggerProps = $props();
5
+ </script>
6
+
7
+ <TooltipPrimitive.Trigger bind:ref data-slot="tooltip-trigger" {...restProps} />
@@ -0,0 +1,10 @@
1
+ <script lang="ts">
2
+ import { Tooltip as TooltipPrimitive } from "bits-ui";
3
+ import TooltipProvider from "./tooltip-provider.svelte";
4
+
5
+ let { open = $bindable(false), ...restProps }: TooltipPrimitive.RootProps = $props();
6
+ </script>
7
+
8
+ <TooltipProvider>
9
+ <TooltipPrimitive.Root bind:open {...restProps} />
10
+ </TooltipProvider>
package/src/index.ts ADDED
@@ -0,0 +1,43 @@
1
+ // @svadmin/ui — Pre-built admin UI components
2
+
3
+ // Entry component
4
+ export { default as AdminApp } from './components/AdminApp.svelte';
5
+
6
+ // Admin components
7
+ export { default as AutoTable } from './components/AutoTable.svelte';
8
+ export { default as AutoForm } from './components/AutoForm.svelte';
9
+ export { default as ShowPage } from './components/ShowPage.svelte';
10
+ export { default as ConfirmDialog } from './components/ConfirmDialog.svelte';
11
+ export { default as Sidebar } from './components/Sidebar.svelte';
12
+ export { default as Layout } from './components/Layout.svelte';
13
+ export { default as Header } from './components/Header.svelte';
14
+ export { default as ErrorBoundary } from './components/ErrorBoundary.svelte';
15
+ export { default as Toast } from './components/Toast.svelte';
16
+ export { default as Breadcrumbs } from './components/Breadcrumbs.svelte';
17
+ export { default as FieldRenderer } from './components/FieldRenderer.svelte';
18
+ export { default as EmptyState } from './components/EmptyState.svelte';
19
+ export { default as StatsCard } from './components/StatsCard.svelte';
20
+ export { default as PageHeader } from './components/PageHeader.svelte';
21
+
22
+ // Base UI components (shadcn-svelte)
23
+ export { Button, buttonVariants } from './components/ui/button/index.js';
24
+ export { Input } from './components/ui/input/index.js';
25
+ export { Textarea } from './components/ui/textarea/index.js';
26
+ export { Select } from './components/ui/select/index.js';
27
+ export { Switch } from './components/ui/switch/index.js';
28
+ export { Checkbox } from './components/ui/checkbox/index.js';
29
+ export { Badge } from './components/ui/badge/index.js';
30
+ export { Separator } from './components/ui/separator/index.js';
31
+ export { Avatar } from './components/ui/avatar/index.js';
32
+ export { Skeleton } from './components/ui/skeleton/index.js';
33
+ export { Sheet } from './components/ui/sheet/index.js';
34
+ export * as Alert from './components/ui/alert/index.js';
35
+ export * as Card from './components/ui/card/index.js';
36
+ export * as Dialog from './components/ui/dialog/index.js';
37
+ export * as Table from './components/ui/table/index.js';
38
+ export * as Tabs from './components/ui/tabs/index.js';
39
+ export * as Tooltip from './components/ui/tooltip/index.js';
40
+ export * as DropdownMenu from './components/ui/dropdown-menu/index.js';
41
+
42
+ // Utils
43
+ export { cn } from './utils';
package/src/utils.ts ADDED
@@ -0,0 +1,28 @@
1
+ import { type ClassValue, clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+ import type { Snippet } from "svelte";
4
+
5
+ export function cn(...inputs: ClassValue[]) {
6
+ return twMerge(clsx(inputs));
7
+ }
8
+
9
+ /**
10
+ * A utility type that makes the `ref` prop optional and adds it to the given props type.
11
+ */
12
+ export type WithElementRef<T, E extends HTMLElement = HTMLElement> = T & {
13
+ ref?: E | null;
14
+ };
15
+
16
+ /**
17
+ * A utility type that removes `children` and `child` from the given props type.
18
+ */
19
+ export type WithoutChildrenOrChild<T> = T extends infer U
20
+ ? Omit<U, "children" | "child">
21
+ : never;
22
+
23
+ /**
24
+ * A utility type that removes `children` from the given props type (keeps `child`).
25
+ */
26
+ export type WithoutChildren<T> = T extends infer U
27
+ ? Omit<U, "children">
28
+ : never;