@podosoft/podokit 0.3.0 → 0.4.0

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 (151) hide show
  1. package/dist/templates/fullstack-nest-svelte/apps/api/package.json +20 -2
  2. package/dist/templates/fullstack-nest-svelte/apps/api/tsconfig.json +14 -5
  3. package/dist/templates/fullstack-nest-svelte/apps/web/package.json +3 -2
  4. package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/api.ts +5 -0
  5. package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/server/api.ts +19 -0
  6. package/dist/templates/fullstack-nest-svelte/apps/web/src/lib/server/backend-proxy.ts +43 -4
  7. package/dist/templates/fullstack-nest-svelte/apps/web/src/routes/+page.svelte +8 -3
  8. package/dist/templates/fullstack-nest-svelte/apps/web/src/routes/api/[...path]/+server.ts +12 -0
  9. package/dist/templates/fullstack-nest-svelte/apps/web/src/routes/api/auth/[...all]/+server.ts +12 -0
  10. package/dist/templates/fullstack-nest-svelte/dot-gitignore +5 -0
  11. package/dist/templates/fullstack-nest-svelte/package.json +11 -3
  12. package/dist/templates/fullstack-nest-svelte/tests/README.md +15 -0
  13. package/dist/templates/fullstack-nest-svelte/tests/api/health.api.spec.ts +14 -0
  14. package/dist/templates/fullstack-nest-svelte/tests/package.json +14 -0
  15. package/dist/templates/fullstack-nest-svelte/tests/playwright.config.ts +25 -0
  16. package/dist/templates/fullstack-nest-svelte/tests/ui/smoke.ui.spec.ts +8 -0
  17. package/dist/templates/modules/admin-dashboard/files/apps/web/src/app.d.ts +23 -0
  18. package/dist/templates/modules/admin-dashboard/files/apps/web/src/hooks.server.ts +20 -0
  19. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/app-sidebar.svelte +59 -0
  20. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/language-switch.svelte +33 -0
  21. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/sidebar-user-menu.svelte +44 -0
  22. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/table-pagination.svelte +40 -0
  23. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/theme-toggle.svelte +27 -0
  24. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/collapsible/collapsible-content.svelte +7 -0
  25. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/collapsible/collapsible-trigger.svelte +7 -0
  26. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/collapsible/collapsible.svelte +11 -0
  27. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/collapsible/index.ts +13 -0
  28. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/index.ts +31 -0
  29. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-content.svelte +20 -0
  30. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-ellipsis.svelte +22 -0
  31. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-item.svelte +14 -0
  32. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-link.svelte +42 -0
  33. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-next-button.svelte +31 -0
  34. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-next.svelte +26 -0
  35. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-prev-button.svelte +31 -0
  36. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination-previous.svelte +26 -0
  37. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/pagination/pagination.svelte +28 -0
  38. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/index.ts +34 -0
  39. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-close.svelte +7 -0
  40. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-content.svelte +55 -0
  41. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-description.svelte +17 -0
  42. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-footer.svelte +20 -0
  43. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-header.svelte +20 -0
  44. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-overlay.svelte +17 -0
  45. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-portal.svelte +7 -0
  46. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-title.svelte +17 -0
  47. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet-trigger.svelte +7 -0
  48. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sheet/sheet.svelte +7 -0
  49. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/constants.ts +6 -0
  50. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/context.svelte.ts +81 -0
  51. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/index.ts +75 -0
  52. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-content.svelte +24 -0
  53. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-footer.svelte +21 -0
  54. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-group-action.svelte +33 -0
  55. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-group-content.svelte +21 -0
  56. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-group-label.svelte +33 -0
  57. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-group.svelte +21 -0
  58. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-header.svelte +21 -0
  59. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-input.svelte +21 -0
  60. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-inset.svelte +20 -0
  61. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-action.svelte +37 -0
  62. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte +24 -0
  63. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-button.svelte +102 -0
  64. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-item.svelte +21 -0
  65. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte +36 -0
  66. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte +39 -0
  67. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte +21 -0
  68. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte +21 -0
  69. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-menu.svelte +21 -0
  70. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-provider.svelte +53 -0
  71. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-rail.svelte +36 -0
  72. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-separator.svelte +19 -0
  73. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar-trigger.svelte +36 -0
  74. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/ui/sidebar/sidebar.svelte +108 -0
  75. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/components/user-avatar.svelte +12 -0
  76. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/hooks/is-mobile.svelte.ts +9 -0
  77. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/i18n/index.ts +27 -0
  78. package/dist/templates/modules/admin-dashboard/files/apps/web/src/lib/i18n/messages.ts +359 -0
  79. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/+layout.server.ts +14 -0
  80. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/+layout.svelte +50 -0
  81. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/+page.svelte +25 -0
  82. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/account/+page.server.ts +5 -0
  83. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/account/+page.svelte +374 -0
  84. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/audit/+page.server.ts +8 -0
  85. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/audit/+page.svelte +78 -0
  86. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/sessions/+page.server.ts +8 -0
  87. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/sessions/+page.svelte +122 -0
  88. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/users/+page.server.ts +9 -0
  89. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(app)/admin/users/+page.svelte +406 -0
  90. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/+layout.svelte +13 -0
  91. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/forgot-password/+page.svelte +54 -0
  92. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/login/+page.svelte +59 -0
  93. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/reset-password/+page.svelte +51 -0
  94. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/(auth)/signup/+page.svelte +60 -0
  95. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/+layout.server.ts +22 -0
  96. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/+layout.svelte +20 -0
  97. package/dist/templates/modules/admin-dashboard/files/apps/web/src/routes/+page.svelte +22 -0
  98. package/dist/templates/modules/admin-dashboard/files/tests/api/audit.api.spec.ts +48 -0
  99. package/dist/templates/modules/admin-dashboard/files/tests/api/auth.api.spec.ts +43 -0
  100. package/dist/templates/modules/admin-dashboard/files/tests/api/users-admin.api.spec.ts +134 -0
  101. package/dist/templates/modules/admin-dashboard/files/tests/helpers/accounts.ts +6 -0
  102. package/dist/templates/modules/admin-dashboard/files/tests/helpers/hydration.ts +9 -0
  103. package/dist/templates/modules/admin-dashboard/files/tests/playwright.config.ts +26 -0
  104. package/dist/templates/modules/admin-dashboard/files/tests/seed.setup.ts +29 -0
  105. package/dist/templates/modules/admin-dashboard/files/tests/ui/account.ui.spec.ts +55 -0
  106. package/dist/templates/modules/admin-dashboard/files/tests/ui/audit.ui.spec.ts +16 -0
  107. package/dist/templates/modules/admin-dashboard/files/tests/ui/auth.ui.spec.ts +45 -0
  108. package/dist/templates/modules/admin-dashboard/files/tests/ui/dashboard.ui.spec.ts +25 -0
  109. package/dist/templates/modules/admin-dashboard/files/tests/ui/guards.ui.spec.ts +21 -0
  110. package/dist/templates/modules/admin-dashboard/files/tests/ui/i18n.ui.spec.ts +13 -0
  111. package/dist/templates/modules/admin-dashboard/files/tests/ui/sessions.ui.spec.ts +15 -0
  112. package/dist/templates/modules/admin-dashboard/files/tests/ui/sidebar.ui.spec.ts +16 -0
  113. package/dist/templates/modules/admin-dashboard/files/tests/ui/users-crud.ui.spec.ts +129 -0
  114. package/dist/templates/modules/admin-dashboard/files/tests/ui/users.ui.spec.ts +19 -0
  115. package/dist/templates/modules/admin-dashboard/module.manifest.json +41 -0
  116. package/dist/templates/modules/audit-log/files/apps/api/src/audit/README.md +59 -0
  117. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit-events.ts +34 -0
  118. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit-hook.ts +70 -0
  119. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit-log.entity.ts +29 -8
  120. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit.controller.ts +7 -2
  121. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit.decorator.ts +23 -0
  122. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit.interceptor.ts +36 -21
  123. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit.module.ts +2 -1
  124. package/dist/templates/modules/audit-log/files/apps/api/src/audit/audit.service.ts +36 -0
  125. package/dist/templates/modules/audit-log/files/apps/api/src/migrations/1720300000000-InitAuditLogs.ts +10 -4
  126. package/dist/templates/modules/audit-log/module.manifest.json +30 -7
  127. package/dist/templates/modules/auth/files/apps/api/src/account/account.controller.ts +17 -0
  128. package/dist/templates/modules/auth/files/apps/api/src/auth/auth.ts +26 -3
  129. package/dist/templates/todo/apps/api/package.json +20 -2
  130. package/dist/templates/todo/apps/api/tsconfig.json +14 -5
  131. package/dist/templates/todo/apps/web/package.json +3 -2
  132. package/dist/templates/todo/apps/web/src/lib/api.ts +5 -0
  133. package/dist/templates/todo/apps/web/src/lib/server/api.ts +19 -0
  134. package/dist/templates/todo/apps/web/src/lib/server/backend-proxy.ts +43 -4
  135. package/dist/templates/todo/apps/web/src/routes/+page.svelte +19 -18
  136. package/dist/templates/todo/apps/web/src/routes/api/[...path]/+server.ts +12 -0
  137. package/dist/templates/todo/apps/web/src/routes/api/auth/[...all]/+server.ts +12 -0
  138. package/dist/templates/todo/dot-gitignore +5 -0
  139. package/dist/templates/todo/package.json +11 -3
  140. package/dist/templates/todo/tests/README.md +15 -0
  141. package/dist/templates/todo/tests/api/health.api.spec.ts +14 -0
  142. package/dist/templates/todo/tests/package.json +14 -0
  143. package/dist/templates/todo/tests/playwright.config.ts +25 -0
  144. package/dist/templates/todo/tests/ui/smoke.ui.spec.ts +8 -0
  145. package/package.json +1 -1
  146. package/dist/templates/fullstack-nest-svelte/apps/api/test/health.e2e-spec.ts +0 -23
  147. package/dist/templates/fullstack-nest-svelte/apps/web/src/routes/api/health/+server.ts +0 -12
  148. package/dist/templates/todo/apps/api/test/health.e2e-spec.ts +0 -23
  149. package/dist/templates/todo/apps/web/src/routes/api/health/+server.ts +0 -12
  150. package/dist/templates/todo/apps/web/src/routes/api/todos/+server.ts +0 -24
  151. package/dist/templates/todo/apps/web/src/routes/api/todos/[id]/+server.ts +0 -24
@@ -0,0 +1,13 @@
1
+ import Root from "./collapsible.svelte";
2
+ import Trigger from "./collapsible-trigger.svelte";
3
+ import Content from "./collapsible-content.svelte";
4
+
5
+ export {
6
+ Root,
7
+ Content,
8
+ Trigger,
9
+ //
10
+ Root as Collapsible,
11
+ Content as CollapsibleContent,
12
+ Trigger as CollapsibleTrigger,
13
+ };
@@ -0,0 +1,31 @@
1
+ import Root from "./pagination.svelte";
2
+ import Content from "./pagination-content.svelte";
3
+ import Item from "./pagination-item.svelte";
4
+ import Link from "./pagination-link.svelte";
5
+ import PrevButton from "./pagination-prev-button.svelte";
6
+ import NextButton from "./pagination-next-button.svelte";
7
+ import Ellipsis from "./pagination-ellipsis.svelte";
8
+ import Previous from "./pagination-previous.svelte";
9
+ import Next from "./pagination-next.svelte";
10
+
11
+ export {
12
+ Root,
13
+ Content,
14
+ Item,
15
+ Link,
16
+ PrevButton, // old
17
+ NextButton, // old
18
+ Ellipsis,
19
+ Previous,
20
+ Next,
21
+ //
22
+ Root as Pagination,
23
+ Content as PaginationContent,
24
+ Item as PaginationItem,
25
+ Link as PaginationLink,
26
+ PrevButton as PaginationPrevButton, // old
27
+ NextButton as PaginationNextButton, // old
28
+ Ellipsis as PaginationEllipsis,
29
+ Previous as PaginationPrevious,
30
+ Next as PaginationNext,
31
+ };
@@ -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<HTMLUListElement>> = $props();
11
+ </script>
12
+
13
+ <ul
14
+ bind:this={ref}
15
+ data-slot="pagination-content"
16
+ class={cn("gap-0.5 flex items-center", className)}
17
+ {...restProps}
18
+ >
19
+ {@render children?.()}
20
+ </ul>
@@ -0,0 +1,22 @@
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+ import { cn, type WithElementRef, type WithoutChildren } from "$lib/utils.js";
4
+ import MoreHorizontalIcon from '@lucide/svelte/icons/more-horizontal';
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ ...restProps
10
+ }: WithoutChildren<WithElementRef<HTMLAttributes<HTMLSpanElement>>> = $props();
11
+ </script>
12
+
13
+ <span
14
+ bind:this={ref}
15
+ aria-hidden="true"
16
+ data-slot="pagination-ellipsis"
17
+ class={cn("size-8 items-center justify-center [&_svg:not([class*='size-'])]:size-4 flex items-center justify-center", className)}
18
+ {...restProps}
19
+ >
20
+ <MoreHorizontalIcon />
21
+ <span class="sr-only">More pages</span>
22
+ </span>
@@ -0,0 +1,14 @@
1
+ <script lang="ts">
2
+ import type { HTMLLiAttributes } from "svelte/elements";
3
+ import type { WithElementRef } from "$lib/utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ children,
8
+ ...restProps
9
+ }: WithElementRef<HTMLLiAttributes> = $props();
10
+ </script>
11
+
12
+ <li bind:this={ref} data-slot="pagination-item" {...restProps}>
13
+ {@render children?.()}
14
+ </li>
@@ -0,0 +1,42 @@
1
+ <script lang="ts">
2
+ import { Pagination as PaginationPrimitive } from "bits-ui";
3
+ import { cn } from "$lib/utils.js";
4
+ import { buttonVariants, type ButtonSize } from "$lib/components/ui/button/index.js";
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ size = "icon",
9
+ isActive,
10
+ page,
11
+ children,
12
+ ...restProps
13
+ }: PaginationPrimitive.PageProps & {
14
+ size?: ButtonSize;
15
+ isActive: boolean;
16
+ } = $props();
17
+ </script>
18
+
19
+ {#snippet Fallback()}
20
+ {page.value}
21
+ {/snippet}
22
+
23
+ <PaginationPrimitive.Page
24
+ bind:ref
25
+ {page}
26
+ aria-current={isActive ? "page" : undefined}
27
+ data-slot="pagination-link"
28
+ data-active={isActive}
29
+ data-size={size}
30
+ class={cn(
31
+ buttonVariants({ size, variant: isActive ? "outline" : "ghost" }),
32
+ "cn-pagination-link",
33
+ className
34
+ )}
35
+ {...restProps}
36
+ >
37
+ {#if children}
38
+ {@render children?.()}
39
+ {:else}
40
+ {@render Fallback()}
41
+ {/if}
42
+ </PaginationPrimitive.Page>
@@ -0,0 +1,31 @@
1
+ <script lang="ts">
2
+ import { Pagination as PaginationPrimitive } from "bits-ui";
3
+ import ChevronRightIcon from '@lucide/svelte/icons/chevron-right';
4
+ import { cn } from "$lib/utils.js";
5
+ import { buttonVariants } from "../button/index.js";
6
+
7
+ let {
8
+ ref = $bindable(null),
9
+ class: className,
10
+ children,
11
+ ...restProps
12
+ }: PaginationPrimitive.NextButtonProps = $props();
13
+ </script>
14
+
15
+ {#snippet Fallback()}
16
+ <span>Next</span>
17
+ <ChevronRightIcon class={cn("size-4", className)} />
18
+ {/snippet}
19
+
20
+ <PaginationPrimitive.NextButton
21
+ bind:ref
22
+ aria-label="Go to next page"
23
+ class={cn(buttonVariants({ variant: "ghost" }), "pr-1.5!", className)}
24
+ {...restProps}
25
+ >
26
+ {#if children}
27
+ {@render children?.()}
28
+ {:else}
29
+ {@render Fallback()}
30
+ {/if}
31
+ </PaginationPrimitive.NextButton>
@@ -0,0 +1,26 @@
1
+ <script lang="ts">
2
+ import { Pagination as PaginationPrimitive } from "bits-ui";
3
+ import { cn } from "$lib/utils.js";
4
+ import { buttonVariants } from "$lib/components/ui/button/index.js";
5
+ import ChevronRightIcon from '@lucide/svelte/icons/chevron-right';
6
+
7
+ let {
8
+ ref = $bindable(null),
9
+ class: className,
10
+ ...restProps
11
+ }: PaginationPrimitive.NextButtonProps = $props();
12
+ </script>
13
+
14
+ <PaginationPrimitive.NextButton
15
+ bind:ref
16
+ aria-label="Go to next page"
17
+ class={cn(
18
+ buttonVariants({ variant: "ghost", size: "default" }),
19
+ "pr-1.5!",
20
+ className
21
+ )}
22
+ {...restProps}
23
+ >
24
+ <span class="cn-pagination-next-text hidden sm:block">Next</span>
25
+ <ChevronRightIcon data-icon="inline-end" />
26
+ </PaginationPrimitive.NextButton>
@@ -0,0 +1,31 @@
1
+ <script lang="ts">
2
+ import { Pagination as PaginationPrimitive } from "bits-ui";
3
+ import ChevronLeftIcon from '@lucide/svelte/icons/chevron-left';
4
+ import { cn } from "$lib/utils.js";
5
+ import { buttonVariants } from "../button/index.js";
6
+
7
+ let {
8
+ ref = $bindable(null),
9
+ class: className,
10
+ children,
11
+ ...restProps
12
+ }: PaginationPrimitive.PrevButtonProps = $props();
13
+ </script>
14
+
15
+ {#snippet Fallback()}
16
+ <ChevronLeftIcon class={cn("size-4", className)} />
17
+ <span>Previous</span>
18
+ {/snippet}
19
+
20
+ <PaginationPrimitive.PrevButton
21
+ bind:ref
22
+ aria-label="Go to previous page"
23
+ class={cn(buttonVariants({ variant: "ghost" }), "pl-1.5!", className)}
24
+ {...restProps}
25
+ >
26
+ {#if children}
27
+ {@render children?.()}
28
+ {:else}
29
+ {@render Fallback()}
30
+ {/if}
31
+ </PaginationPrimitive.PrevButton>
@@ -0,0 +1,26 @@
1
+ <script lang="ts">
2
+ import { Pagination as PaginationPrimitive } from "bits-ui";
3
+ import { cn } from "$lib/utils.js";
4
+ import { buttonVariants } from "$lib/components/ui/button/index.js";
5
+ import ChevronLeftIcon from '@lucide/svelte/icons/chevron-left';
6
+
7
+ let {
8
+ ref = $bindable(null),
9
+ class: className,
10
+ ...restProps
11
+ }: PaginationPrimitive.PrevButtonProps = $props();
12
+ </script>
13
+
14
+ <PaginationPrimitive.PrevButton
15
+ bind:ref
16
+ aria-label="Go to previous page"
17
+ class={cn(
18
+ buttonVariants({ variant: "ghost", size: "default" }),
19
+ "pl-1.5!",
20
+ className
21
+ )}
22
+ {...restProps}
23
+ >
24
+ <ChevronLeftIcon data-icon="inline-start" />
25
+ <span class="cn-pagination-previous-text hidden sm:block">Previous</span>
26
+ </PaginationPrimitive.PrevButton>
@@ -0,0 +1,28 @@
1
+ <script lang="ts">
2
+ import { Pagination as PaginationPrimitive } from "bits-ui";
3
+
4
+ import { cn } from "$lib/utils.js";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ count = 0,
10
+ perPage = 10,
11
+ page = $bindable(1),
12
+ siblingCount = 1,
13
+ ...restProps
14
+ }: PaginationPrimitive.RootProps = $props();
15
+ </script>
16
+
17
+ <PaginationPrimitive.Root
18
+ bind:ref
19
+ bind:page
20
+ role="navigation"
21
+ aria-label="pagination"
22
+ data-slot="pagination"
23
+ {count}
24
+ {perPage}
25
+ {siblingCount}
26
+ class={cn("cn-pagination mx-auto flex w-full justify-center", className)}
27
+ {...restProps}
28
+ />
@@ -0,0 +1,34 @@
1
+ import Root from "./sheet.svelte";
2
+ import Portal from "./sheet-portal.svelte";
3
+ import Trigger from "./sheet-trigger.svelte";
4
+ import Close from "./sheet-close.svelte";
5
+ import Overlay from "./sheet-overlay.svelte";
6
+ import Content from "./sheet-content.svelte";
7
+ import Header from "./sheet-header.svelte";
8
+ import Footer from "./sheet-footer.svelte";
9
+ import Title from "./sheet-title.svelte";
10
+ import Description from "./sheet-description.svelte";
11
+
12
+ export {
13
+ Root,
14
+ Close,
15
+ Trigger,
16
+ Portal,
17
+ Overlay,
18
+ Content,
19
+ Header,
20
+ Footer,
21
+ Title,
22
+ Description,
23
+ //
24
+ Root as Sheet,
25
+ Close as SheetClose,
26
+ Trigger as SheetTrigger,
27
+ Portal as SheetPortal,
28
+ Overlay as SheetOverlay,
29
+ Content as SheetContent,
30
+ Header as SheetHeader,
31
+ Footer as SheetFooter,
32
+ Title as SheetTitle,
33
+ Description as SheetDescription,
34
+ };
@@ -0,0 +1,7 @@
1
+ <script lang="ts">
2
+ import { Dialog as SheetPrimitive } from "bits-ui";
3
+
4
+ let { ref = $bindable(null), ...restProps }: SheetPrimitive.CloseProps = $props();
5
+ </script>
6
+
7
+ <SheetPrimitive.Close bind:ref data-slot="sheet-close" {...restProps} />
@@ -0,0 +1,55 @@
1
+ <script lang="ts" module>
2
+ export type Side = "top" | "right" | "bottom" | "left";
3
+ </script>
4
+
5
+ <script lang="ts">
6
+ import { Dialog as SheetPrimitive } from "bits-ui";
7
+ import type { Snippet } from "svelte";
8
+ import SheetPortal from "./sheet-portal.svelte";
9
+ import SheetOverlay from "./sheet-overlay.svelte";
10
+ import { Button } from "$lib/components/ui/button/index.js";
11
+ import XIcon from '@lucide/svelte/icons/x';
12
+ import { cn, type WithoutChildrenOrChild } from "$lib/utils.js";
13
+ import type { ComponentProps } from "svelte";
14
+
15
+ let {
16
+ ref = $bindable(null),
17
+ class: className,
18
+ side = "right",
19
+ showCloseButton = true,
20
+ portalProps,
21
+ children,
22
+ ...restProps
23
+ }: WithoutChildrenOrChild<SheetPrimitive.ContentProps> & {
24
+ portalProps?: WithoutChildrenOrChild<ComponentProps<typeof SheetPortal>>;
25
+ side?: Side;
26
+ showCloseButton?: boolean;
27
+ children: Snippet;
28
+ } = $props();
29
+ </script>
30
+
31
+ <SheetPortal {...portalProps}>
32
+ <SheetOverlay />
33
+ <SheetPrimitive.Content
34
+ bind:ref
35
+ data-slot="sheet-content"
36
+ data-side={side}
37
+ class={cn(
38
+ "bg-popover text-popover-foreground fixed z-50 flex flex-col gap-4 bg-clip-padding text-sm shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=right]:data-closed:slide-out-to-right-10 data-[side=top]:data-closed:slide-out-to-top-10",
39
+ className
40
+ )}
41
+ {...restProps}
42
+ >
43
+ {@render children?.()}
44
+ {#if showCloseButton}
45
+ <SheetPrimitive.Close data-slot="sheet-close">
46
+ {#snippet child({ props })}
47
+ <Button variant="ghost" class="absolute top-3 right-3" size="icon-sm" {...props}>
48
+ <XIcon />
49
+ <span class="sr-only">Close</span>
50
+ </Button>
51
+ {/snippet}
52
+ </SheetPrimitive.Close>
53
+ {/if}
54
+ </SheetPrimitive.Content>
55
+ </SheetPortal>
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import { Dialog as SheetPrimitive } from "bits-ui";
3
+ import { cn } from "$lib/utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ ...restProps
9
+ }: SheetPrimitive.DescriptionProps = $props();
10
+ </script>
11
+
12
+ <SheetPrimitive.Description
13
+ bind:ref
14
+ data-slot="sheet-description"
15
+ class={cn("text-muted-foreground text-sm", className)}
16
+ {...restProps}
17
+ />
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "$lib/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<HTMLDivElement>> = $props();
11
+ </script>
12
+
13
+ <div
14
+ bind:this={ref}
15
+ data-slot="sheet-footer"
16
+ class={cn("gap-2 p-4 mt-auto flex flex-col", className)}
17
+ {...restProps}
18
+ >
19
+ {@render children?.()}
20
+ </div>
@@ -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="sheet-header"
16
+ class={cn("gap-0.5 p-4 flex flex-col", className)}
17
+ {...restProps}
18
+ >
19
+ {@render children?.()}
20
+ </div>
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import { Dialog as SheetPrimitive } from "bits-ui";
3
+ import { cn } from "$lib/utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ ...restProps
9
+ }: SheetPrimitive.OverlayProps = $props();
10
+ </script>
11
+
12
+ <SheetPrimitive.Overlay
13
+ bind:ref
14
+ data-slot="sheet-overlay"
15
+ class={cn("bg-black/10 supports-backdrop-filter:backdrop-blur-xs fixed inset-0 z-50", className)}
16
+ {...restProps}
17
+ />
@@ -0,0 +1,7 @@
1
+ <script lang="ts">
2
+ import { Dialog as SheetPrimitive } from "bits-ui";
3
+
4
+ let { ...restProps }: SheetPrimitive.PortalProps = $props();
5
+ </script>
6
+
7
+ <SheetPrimitive.Portal {...restProps} />
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import { Dialog as SheetPrimitive } from "bits-ui";
3
+ import { cn } from "$lib/utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ ...restProps
9
+ }: SheetPrimitive.TitleProps = $props();
10
+ </script>
11
+
12
+ <SheetPrimitive.Title
13
+ bind:ref
14
+ data-slot="sheet-title"
15
+ class={cn("text-foreground text-base font-medium", className)}
16
+ {...restProps}
17
+ />
@@ -0,0 +1,7 @@
1
+ <script lang="ts">
2
+ import { Dialog as SheetPrimitive } from "bits-ui";
3
+
4
+ let { ref = $bindable(null), ...restProps }: SheetPrimitive.TriggerProps = $props();
5
+ </script>
6
+
7
+ <SheetPrimitive.Trigger bind:ref data-slot="sheet-trigger" {...restProps} />
@@ -0,0 +1,7 @@
1
+ <script lang="ts">
2
+ import { Dialog as SheetPrimitive } from "bits-ui";
3
+
4
+ let { open = $bindable(false), ...restProps }: SheetPrimitive.RootProps = $props();
5
+ </script>
6
+
7
+ <SheetPrimitive.Root bind:open {...restProps} />
@@ -0,0 +1,6 @@
1
+ export const SIDEBAR_COOKIE_NAME = "sidebar_state";
2
+ export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
3
+ export const SIDEBAR_WIDTH = "16rem";
4
+ export const SIDEBAR_WIDTH_MOBILE = "18rem";
5
+ export const SIDEBAR_WIDTH_ICON = "3rem";
6
+ export const SIDEBAR_KEYBOARD_SHORTCUT = "b";
@@ -0,0 +1,81 @@
1
+ import { IsMobile } from "$lib/hooks/is-mobile.svelte.js";
2
+ import { getContext, setContext } from "svelte";
3
+ import { SIDEBAR_KEYBOARD_SHORTCUT } from "./constants.js";
4
+
5
+ type Getter<T> = () => T;
6
+
7
+ export type SidebarStateProps = {
8
+ /**
9
+ * A getter function that returns the current open state of the sidebar.
10
+ * We use a getter function here to support `bind:open` on the `Sidebar.Provider`
11
+ * component.
12
+ */
13
+ open: Getter<boolean>;
14
+
15
+ /**
16
+ * A function that sets the open state of the sidebar. To support `bind:open`, we need
17
+ * a source of truth for changing the open state to ensure it will be synced throughout
18
+ * the sub-components and any `bind:` references.
19
+ */
20
+ setOpen: (open: boolean) => void;
21
+ };
22
+
23
+ class SidebarState {
24
+ readonly props: SidebarStateProps;
25
+ open = $derived.by(() => this.props.open());
26
+ openMobile = $state(false);
27
+ setOpen: SidebarStateProps["setOpen"];
28
+ #isMobile: IsMobile;
29
+ state = $derived.by(() => (this.open ? "expanded" : "collapsed"));
30
+
31
+ constructor(props: SidebarStateProps) {
32
+ this.setOpen = props.setOpen;
33
+ this.#isMobile = new IsMobile();
34
+ this.props = props;
35
+ }
36
+
37
+ // Convenience getter for checking if the sidebar is mobile
38
+ // without this, we would need to use `sidebar.isMobile.current` everywhere
39
+ get isMobile() {
40
+ return this.#isMobile.current;
41
+ }
42
+
43
+ // Event handler to apply to the `<svelte:window>`
44
+ handleShortcutKeydown = (e: KeyboardEvent) => {
45
+ if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) {
46
+ e.preventDefault();
47
+ this.toggle();
48
+ }
49
+ };
50
+
51
+ setOpenMobile = (value: boolean) => {
52
+ this.openMobile = value;
53
+ };
54
+
55
+ toggle = () => {
56
+ return this.#isMobile.current
57
+ ? (this.openMobile = !this.openMobile)
58
+ : this.setOpen(!this.open);
59
+ };
60
+ }
61
+
62
+ const SYMBOL_KEY = "scn-sidebar";
63
+
64
+ /**
65
+ * Instantiates a new `SidebarState` instance and sets it in the context.
66
+ *
67
+ * @param props The constructor props for the `SidebarState` class.
68
+ * @returns The `SidebarState` instance.
69
+ */
70
+ export function setSidebar(props: SidebarStateProps): SidebarState {
71
+ return setContext(Symbol.for(SYMBOL_KEY), new SidebarState(props));
72
+ }
73
+
74
+ /**
75
+ * Retrieves the `SidebarState` instance from the context. This is a class instance,
76
+ * so you cannot destructure it.
77
+ * @returns The `SidebarState` instance.
78
+ */
79
+ export function useSidebar(): SidebarState {
80
+ return getContext(Symbol.for(SYMBOL_KEY));
81
+ }