@riducms/admin 0.1.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 (226) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +31 -0
  3. package/THIRD_PARTY_NOTICES.md +217 -0
  4. package/package.json +62 -0
  5. package/src/app/admin-core-view-route.svelte +89 -0
  6. package/src/app/admin-layout.svelte +457 -0
  7. package/src/app/admin-navigation-progress.svelte +204 -0
  8. package/src/app/admin-page-title.svelte +94 -0
  9. package/src/app/admin-provider-layer.svelte +26 -0
  10. package/src/app/admin-router-root.svelte +9 -0
  11. package/src/app/admin-routes.svelte +116 -0
  12. package/src/app/deferred-redirect.svelte +23 -0
  13. package/src/app/loading-boundary.svelte +70 -0
  14. package/src/app/not-found-route.svelte +29 -0
  15. package/src/app-meta.ts +2 -0
  16. package/src/app.css +467 -0
  17. package/src/app.svelte +88 -0
  18. package/src/assets/ridu-logo-arch.svg +3 -0
  19. package/src/assets/ridu-word-logo.svg +7 -0
  20. package/src/components/brand/ridu-logo.svelte +24 -0
  21. package/src/components/code-block/code-block.svelte +107 -0
  22. package/src/components/json-tree/json-tree-node.svelte +77 -0
  23. package/src/components/json-tree/json-viewer.svelte +113 -0
  24. package/src/components/ui/banner/banner.svelte +41 -0
  25. package/src/components/ui/banner/index.ts +5 -0
  26. package/src/components/ui/bulk-action-bar/bulk-action-bar.svelte +50 -0
  27. package/src/components/ui/bulk-action-bar/index.ts +1 -0
  28. package/src/components/ui/button/index.ts +8 -0
  29. package/src/components/ui/calendar/calendar-caption.svelte +72 -0
  30. package/src/components/ui/calendar/calendar-cell.svelte +20 -0
  31. package/src/components/ui/calendar/calendar-day.svelte +27 -0
  32. package/src/components/ui/calendar/calendar-grid-row.svelte +13 -0
  33. package/src/components/ui/calendar/calendar-grid.svelte +17 -0
  34. package/src/components/ui/calendar/calendar-head-cell.svelte +20 -0
  35. package/src/components/ui/calendar/calendar-header.svelte +20 -0
  36. package/src/components/ui/calendar/calendar-heading.svelte +17 -0
  37. package/src/components/ui/calendar/calendar-month-select.svelte +45 -0
  38. package/src/components/ui/calendar/calendar-month.svelte +16 -0
  39. package/src/components/ui/calendar/calendar-months.svelte +20 -0
  40. package/src/components/ui/calendar/calendar-nav.svelte +20 -0
  41. package/src/components/ui/calendar/calendar-next-button.svelte +30 -0
  42. package/src/components/ui/calendar/calendar-prev-button.svelte +30 -0
  43. package/src/components/ui/calendar/calendar-year-select.svelte +44 -0
  44. package/src/components/ui/calendar/calendar.svelte +118 -0
  45. package/src/components/ui/calendar/index.ts +1 -0
  46. package/src/components/ui/checkbox/checkbox.svelte +35 -0
  47. package/src/components/ui/checkbox/index.ts +1 -0
  48. package/src/components/ui/confirmation-dialog/confirmation-dialog.svelte +37 -0
  49. package/src/components/ui/confirmation-dialog/index.ts +1 -0
  50. package/src/components/ui/date-value-control/date-value-calendar.svelte +37 -0
  51. package/src/components/ui/date-value-control/date-value-control-loader.svelte +36 -0
  52. package/src/components/ui/date-value-control/date-value-control.svelte +177 -0
  53. package/src/components/ui/date-value-control/index.ts +3 -0
  54. package/src/components/ui/dialog/dialog-close.svelte +11 -0
  55. package/src/components/ui/dialog/dialog-content.svelte +52 -0
  56. package/src/components/ui/dialog/dialog-description.svelte +20 -0
  57. package/src/components/ui/dialog/dialog-footer.svelte +20 -0
  58. package/src/components/ui/dialog/dialog-header.svelte +20 -0
  59. package/src/components/ui/dialog/dialog-overlay.svelte +20 -0
  60. package/src/components/ui/dialog/dialog-title.svelte +17 -0
  61. package/src/components/ui/dialog/dialog-trigger.svelte +11 -0
  62. package/src/components/ui/dialog/dialog.svelte +7 -0
  63. package/src/components/ui/dialog/index.ts +8 -0
  64. package/src/components/ui/dropdown-menu/dropdown-menu-content.svelte +27 -0
  65. package/src/components/ui/dropdown-menu/dropdown-menu-item.svelte +20 -0
  66. package/src/components/ui/dropdown-menu/dropdown-menu-separator.svelte +17 -0
  67. package/src/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +16 -0
  68. package/src/components/ui/dropdown-menu/dropdown-menu.svelte +7 -0
  69. package/src/components/ui/dropdown-menu/index.ts +5 -0
  70. package/src/components/ui/empty-state/empty-state.svelte +34 -0
  71. package/src/components/ui/empty-state/index.ts +1 -0
  72. package/src/components/ui/input/index.ts +1 -0
  73. package/src/components/ui/kbd/index.ts +1 -0
  74. package/src/components/ui/kbd/kbd.svelte +24 -0
  75. package/src/components/ui/pagination/index.ts +1 -0
  76. package/src/components/ui/pagination/pagination.svelte +88 -0
  77. package/src/components/ui/popover/index.ts +3 -0
  78. package/src/components/ui/popover/popover-content.svelte +29 -0
  79. package/src/components/ui/popover/popover-trigger.svelte +11 -0
  80. package/src/components/ui/popover/popover.svelte +7 -0
  81. package/src/components/ui/radio-group/index.ts +3 -0
  82. package/src/components/ui/radio-group/radio-card-item.svelte +38 -0
  83. package/src/components/ui/radio-group/radio-group-item.svelte +17 -0
  84. package/src/components/ui/radio-group/radio-group.svelte +19 -0
  85. package/src/components/ui/select/index.ts +4 -0
  86. package/src/components/ui/select/select-content.svelte +38 -0
  87. package/src/components/ui/select/select-item.svelte +40 -0
  88. package/src/components/ui/select/select-scroll-down-button.svelte +23 -0
  89. package/src/components/ui/select/select-scroll-up-button.svelte +23 -0
  90. package/src/components/ui/select/select-trigger.svelte +29 -0
  91. package/src/components/ui/select/select.svelte +11 -0
  92. package/src/components/ui/sheet/index.ts +6 -0
  93. package/src/components/ui/sheet/sheet-close.svelte +7 -0
  94. package/src/components/ui/sheet/sheet-content.svelte +77 -0
  95. package/src/components/ui/sheet/sheet-description.svelte +17 -0
  96. package/src/components/ui/sheet/sheet-overlay.svelte +36 -0
  97. package/src/components/ui/sheet/sheet-title.svelte +17 -0
  98. package/src/components/ui/sheet/sheet-trigger.svelte +7 -0
  99. package/src/components/ui/sheet/sheet.svelte +7 -0
  100. package/src/components/ui/skeleton/index.ts +1 -0
  101. package/src/components/ui/skeleton/skeleton.svelte +31 -0
  102. package/src/components/ui/slider/index.ts +3 -0
  103. package/src/components/ui/slider/slider-content.svelte +59 -0
  104. package/src/components/ui/slider/slider.svelte +35 -0
  105. package/src/components/ui/sonner/index.ts +1 -0
  106. package/src/components/ui/sonner/sonner.svelte +55 -0
  107. package/src/components/ui/status-indicator/index.ts +5 -0
  108. package/src/components/ui/status-indicator/status-indicator.svelte +54 -0
  109. package/src/components/ui/table/index.ts +6 -0
  110. package/src/components/ui/table/table-body.svelte +20 -0
  111. package/src/components/ui/table/table-cell.svelte +23 -0
  112. package/src/components/ui/table/table-head.svelte +23 -0
  113. package/src/components/ui/table/table-header.svelte +20 -0
  114. package/src/components/ui/table/table-row.svelte +23 -0
  115. package/src/components/ui/table/table.svelte +22 -0
  116. package/src/components/ui/tabs/index.ts +8 -0
  117. package/src/components/ui/tabs/tabs-content.svelte +17 -0
  118. package/src/components/ui/tabs/tabs-list.svelte +40 -0
  119. package/src/components/ui/tabs/tabs-trigger.svelte +23 -0
  120. package/src/components/ui/tabs/tabs.svelte +19 -0
  121. package/src/components/ui/textarea/index.ts +1 -0
  122. package/src/components/ui/tooltip/index.ts +4 -0
  123. package/src/components/ui/tooltip/tooltip-content.svelte +50 -0
  124. package/src/components/ui/tooltip/tooltip-provider.svelte +7 -0
  125. package/src/components/ui/tooltip/tooltip-trigger.svelte +7 -0
  126. package/src/components/ui/tooltip/tooltip.svelte +7 -0
  127. package/src/core/api/admin-client.ts +45 -0
  128. package/src/core/forms/field-condition.ts +63 -0
  129. package/src/core/forms/form-controller.svelte.ts +369 -0
  130. package/src/core/forms/form-draft-recovery.ts +80 -0
  131. package/src/core/forms/form-schema.ts +609 -0
  132. package/src/core/forms/form-validation.ts +750 -0
  133. package/src/core/i18n/admin-i18n.svelte.ts +364 -0
  134. package/src/core/i18n/localized-schema.ts +111 -0
  135. package/src/core/notifications/notification-center.svelte.ts +69 -0
  136. package/src/core/notifications/validation-toast.svelte +18 -0
  137. package/src/core/plugins/field-registry.ts +60 -0
  138. package/src/core/plugins/row-label-registry.ts +62 -0
  139. package/src/core/preferences/preference-write-queue.ts +107 -0
  140. package/src/core/routing/admin-paths.ts +137 -0
  141. package/src/core/runtime/admin-runtime.svelte.ts +625 -0
  142. package/src/features/auth/account-menu.svelte +159 -0
  143. package/src/features/auth/account-navigation.svelte +44 -0
  144. package/src/features/auth/account-route.svelte +395 -0
  145. package/src/features/auth/account-security-controller.svelte.ts +119 -0
  146. package/src/features/auth/account-security-route.svelte +460 -0
  147. package/src/features/auth/auth-brand.svelte +17 -0
  148. package/src/features/auth/auth-frame.svelte +18 -0
  149. package/src/features/auth/create-first-user-controller.svelte.ts +220 -0
  150. package/src/features/auth/create-first-user-route.svelte +174 -0
  151. package/src/features/auth/forgot-password-route.svelte +78 -0
  152. package/src/features/auth/login-route.svelte +221 -0
  153. package/src/features/auth/request-verification-route.svelte +73 -0
  154. package/src/features/auth/reset-password-route.svelte +107 -0
  155. package/src/features/auth/verify-email-route.svelte +60 -0
  156. package/src/features/collections/collection-list-bulk-actions.svelte +143 -0
  157. package/src/features/collections/collection-list-bulk-editor.svelte +157 -0
  158. package/src/features/collections/collection-list-controller.svelte.ts +717 -0
  159. package/src/features/collections/collection-list-filter-popover.svelte +238 -0
  160. package/src/features/collections/collection-list-preferences-controller.svelte.ts +393 -0
  161. package/src/features/collections/collection-list-results.svelte +410 -0
  162. package/src/features/collections/collection-list-route.svelte +951 -0
  163. package/src/features/collections/collection-list-workspace-toolbar.svelte +409 -0
  164. package/src/features/collections/collection-table-skeleton.svelte +44 -0
  165. package/src/features/collections/list-workspace.ts +265 -0
  166. package/src/features/dashboard/dashboard-route.svelte +141 -0
  167. package/src/features/development/development-tools.svelte +217 -0
  168. package/src/features/documents/document-api-view-loader.svelte +31 -0
  169. package/src/features/documents/document-api-view.svelte +547 -0
  170. package/src/features/documents/document-controller.svelte.ts +1252 -0
  171. package/src/features/documents/document-field-partition.ts +18 -0
  172. package/src/features/documents/document-field-sections.svelte +46 -0
  173. package/src/features/documents/document-heading.ts +20 -0
  174. package/src/features/documents/document-route-dirty.ts +43 -0
  175. package/src/features/documents/document-route-loader.svelte +22 -0
  176. package/src/features/documents/document-route.svelte +1124 -0
  177. package/src/features/documents/live-preview-panel.svelte +390 -0
  178. package/src/features/documents/live-preview.ts +61 -0
  179. package/src/features/documents/upload-document-preview-loader.svelte +40 -0
  180. package/src/features/documents/upload-document-preview.svelte +525 -0
  181. package/src/features/localization/content-locale-switcher.svelte +93 -0
  182. package/src/features/navigation/admin-breadcrumbs.svelte +124 -0
  183. package/src/features/navigation/admin-command-menu.svelte +245 -0
  184. package/src/features/navigation/admin-resource-groups.ts +72 -0
  185. package/src/features/reference-browser/reference-browser-loader.svelte +15 -0
  186. package/src/features/reference-browser/reference-browser-workflow.svelte.ts +691 -0
  187. package/src/features/reference-browser/reference-browser.svelte +844 -0
  188. package/src/features/uploads/bulk-upload-route.svelte +624 -0
  189. package/src/features/uploads/bulk-upload.ts +39 -0
  190. package/src/features/uploads/upload-metadata-fields.svelte +112 -0
  191. package/src/features/versions/version-diff.ts +72 -0
  192. package/src/features/versions/version-history-route.svelte +581 -0
  193. package/src/fields/field-clipboard.ts +132 -0
  194. package/src/fields/field-layout.svelte +60 -0
  195. package/src/fields/field-layout.ts +57 -0
  196. package/src/fields/field-messages.svelte +29 -0
  197. package/src/fields/field-renderer.svelte +152 -0
  198. package/src/fields/field-shell.svelte +30 -0
  199. package/src/fields/field-tab-layout.svelte +99 -0
  200. package/src/fields/join/join-field.svelte +358 -0
  201. package/src/fields/localized-field-presentation.ts +17 -0
  202. package/src/fields/nested/nested-field.svelte +602 -0
  203. package/src/fields/nested/scoped-field.ts +78 -0
  204. package/src/fields/nested/sortable-row.svelte +32 -0
  205. package/src/fields/point/point-field.svelte +52 -0
  206. package/src/fields/radio/radio-field.svelte +34 -0
  207. package/src/fields/relationship/relationship-field-controller.svelte.ts +245 -0
  208. package/src/fields/relationship/relationship-field.svelte +258 -0
  209. package/src/fields/relationship/relationship-lookup-controller.svelte.ts +129 -0
  210. package/src/fields/relationship/relationship-query.ts +88 -0
  211. package/src/fields/relationship/relationship-quick-picker-controller.svelte.ts +198 -0
  212. package/src/fields/relationship/relationship-quick-picker.svelte +327 -0
  213. package/src/fields/relationship/relationship-value.ts +47 -0
  214. package/src/fields/scalar/date-control-value.ts +60 -0
  215. package/src/fields/scalar/date-value.ts +26 -0
  216. package/src/fields/scalar/scalar-field.svelte +137 -0
  217. package/src/fields/select/select-field.svelte +132 -0
  218. package/src/fields/select/select-value.ts +14 -0
  219. package/src/fields/text/slug-field.svelte +87 -0
  220. package/src/fields/text/slug.ts +38 -0
  221. package/src/fields/text/text-field.svelte +41 -0
  222. package/src/fields/ui/ui-field.svelte +12 -0
  223. package/src/fields/virtual/virtual-field.svelte +28 -0
  224. package/src/index.ts +49 -0
  225. package/src/main.ts +12 -0
  226. package/src/vite-env.d.ts +9 -0
@@ -0,0 +1,77 @@
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 XIcon from "~icons/lucide/x";
8
+ import { getAdminI18n } from "@riducms/plugin";
9
+ import { buttonVariants } from "@admin/components/ui/button/index.js";
10
+ import { cn, type WithoutChildrenOrChild } from "@riducms/ui";
11
+ import SheetOverlay from "@admin/components/ui/sheet/sheet-overlay.svelte";
12
+ import type { Snippet } from "svelte";
13
+
14
+ let {
15
+ ref = $bindable(null),
16
+ class: className,
17
+ side = "right",
18
+ showCloseButton = true,
19
+ portalProps,
20
+ children,
21
+ ...restProps
22
+ }: WithoutChildrenOrChild<SheetPrimitive.ContentProps> & {
23
+ portalProps?: WithoutChildrenOrChild<SheetPrimitive.PortalProps>;
24
+ side?: Side;
25
+ showCloseButton?: boolean;
26
+ children: Snippet;
27
+ } = $props();
28
+ const i18n = getAdminI18n();
29
+ </script>
30
+
31
+ <SheetPrimitive.Portal {...portalProps}>
32
+ <SheetOverlay />
33
+ <SheetPrimitive.Content
34
+ bind:ref
35
+ data-slot="sheet-content"
36
+ data-side={side}
37
+ class={cn(
38
+ "fixed z-50 flex flex-col bg-popover bg-clip-padding text-sm text-popover-foreground shadow-xl 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-[state=open]:animate-in data-[state=open]:fade-in-0 data-[side=bottom]:data-[state=open]:slide-in-from-bottom data-[side=left]:data-[state=open]:slide-in-from-left data-[side=right]:data-[state=open]:slide-in-from-right data-[side=top]:data-[state=open]:slide-in-from-top data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[side=bottom]:data-[state=closed]:slide-out-to-bottom data-[side=left]:data-[state=closed]:slide-out-to-left data-[side=right]:data-[state=closed]:slide-out-to-right data-[side=top]:data-[state=closed]:slide-out-to-top",
39
+ className
40
+ )}
41
+ {...restProps}
42
+ >
43
+ {@render children?.()}
44
+ {#if showCloseButton}
45
+ <SheetPrimitive.Close
46
+ type="button"
47
+ data-slot="sheet-close"
48
+ class={buttonVariants({
49
+ variant: "ghost",
50
+ size: "icon-sm",
51
+ class: "absolute top-4 end-4 bg-secondary",
52
+ })}
53
+ >
54
+ <XIcon />
55
+ <span class="sr-only">{i18n.t("general:close")}</span>
56
+ </SheetPrimitive.Close>
57
+ {/if}
58
+ </SheetPrimitive.Content>
59
+ </SheetPrimitive.Portal>
60
+
61
+ <style>
62
+ :global([data-slot="sheet-content"][data-state="open"]) {
63
+ animation-duration: 300ms;
64
+ animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
65
+ }
66
+
67
+ :global([data-slot="sheet-content"][data-state="closed"]) {
68
+ animation-duration: 220ms;
69
+ animation-timing-function: cubic-bezier(0.4, 0, 1, 1);
70
+ }
71
+
72
+ @media (prefers-reduced-motion: reduce) {
73
+ :global([data-slot="sheet-content"]) {
74
+ animation-duration: 1ms;
75
+ }
76
+ }
77
+ </style>
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import { Dialog as SheetPrimitive } from "bits-ui";
3
+ import { cn } from "@riducms/ui";
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-sm text-muted-foreground", className)}
16
+ {...restProps}
17
+ />
@@ -0,0 +1,36 @@
1
+ <script lang="ts">
2
+ import { Dialog as SheetPrimitive } from "bits-ui";
3
+ import { cn } from "@riducms/ui";
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(
16
+ "fixed inset-0 z-50 bg-backdrop supports-backdrop-filter:backdrop-blur-sm data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
17
+ className
18
+ )}
19
+ {...restProps}
20
+ />
21
+
22
+ <style>
23
+ :global([data-slot="sheet-overlay"][data-state="open"]) {
24
+ animation-duration: 240ms;
25
+ }
26
+
27
+ :global([data-slot="sheet-overlay"][data-state="closed"]) {
28
+ animation-duration: 180ms;
29
+ }
30
+
31
+ @media (prefers-reduced-motion: reduce) {
32
+ :global([data-slot="sheet-overlay"]) {
33
+ animation-duration: 1ms;
34
+ }
35
+ }
36
+ </style>
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import { Dialog as SheetPrimitive } from "bits-ui";
3
+ import { cn } from "@riducms/ui";
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-base font-medium text-foreground", 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 @@
1
+ export { default as Skeleton } from "@admin/components/ui/skeleton/skeleton.svelte";
@@ -0,0 +1,31 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef, type WithoutChildren } from "@riducms/ui";
3
+ import { onMount } from "svelte";
4
+ import type { HTMLAttributes } from "svelte/elements";
5
+
6
+ const revealDelayMilliseconds = 180;
7
+
8
+ let {
9
+ ref = $bindable(null),
10
+ class: className,
11
+ ...restProps
12
+ }: WithoutChildren<WithElementRef<HTMLAttributes<HTMLDivElement>>> = $props();
13
+ let revealed = $state(false);
14
+
15
+ onMount(() => {
16
+ const timer = window.setTimeout(() => (revealed = true), revealDelayMilliseconds);
17
+ return () => window.clearTimeout(timer);
18
+ });
19
+ </script>
20
+
21
+ <div
22
+ bind:this={ref}
23
+ data-slot="skeleton"
24
+ class={cn(
25
+ "rounded bg-muted transition-opacity duration-150 ease-out motion-reduce:transition-none",
26
+ revealed ? "opacity-100" : "opacity-0",
27
+ className
28
+ )}
29
+ {...restProps}
30
+ aria-hidden={!revealed}
31
+ ></div>
@@ -0,0 +1,3 @@
1
+ import Slider from "@admin/components/ui/slider/slider.svelte";
2
+
3
+ export { Slider };
@@ -0,0 +1,59 @@
1
+ <script lang="ts">
2
+ import { Slider as SliderPrimitive } from "bits-ui";
3
+
4
+ import { cn } from "@riducms/ui";
5
+
6
+ let {
7
+ id,
8
+ value,
9
+ min = 0,
10
+ max = 100,
11
+ step = 1,
12
+ disabled = false,
13
+ label,
14
+ describedBy,
15
+ class: className,
16
+ onValueChange,
17
+ }: {
18
+ id?: string;
19
+ value: number;
20
+ min?: number;
21
+ max?: number;
22
+ step?: number;
23
+ disabled?: boolean;
24
+ label: string;
25
+ describedBy?: string;
26
+ class?: string;
27
+ onValueChange: (value: number) => void;
28
+ } = $props();
29
+ </script>
30
+
31
+ <SliderPrimitive.Root
32
+ {id}
33
+ type="single"
34
+ {value}
35
+ {min}
36
+ {max}
37
+ {step}
38
+ {disabled}
39
+ {onValueChange}
40
+ data-slot="slider"
41
+ class={cn(
42
+ "relative flex h-5 w-full touch-none items-center select-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-45",
43
+ className
44
+ )}
45
+ >
46
+ {#snippet children({ thumbItems })}
47
+ <span class="relative h-1.5 w-full grow overflow-hidden rounded-full bg-control-disabled">
48
+ <SliderPrimitive.Range class="absolute h-full rounded-full bg-primary" />
49
+ </span>
50
+ {#each thumbItems as thumb (thumb.index)}
51
+ <SliderPrimitive.Thumb
52
+ index={thumb.index}
53
+ aria-label={label}
54
+ aria-describedby={describedBy}
55
+ class="block size-4 rounded-full border-2 border-primary-foreground bg-primary shadow-sm outline-none transition-[box-shadow,transform] hover:scale-110 focus-visible:scale-110 focus-visible:ring-2 focus-visible:ring-primary/45 focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none"
56
+ />
57
+ {/each}
58
+ {/snippet}
59
+ </SliderPrimitive.Root>
@@ -0,0 +1,35 @@
1
+ <script lang="ts">
2
+ import type { Component } from "svelte";
3
+
4
+ type SliderProps = {
5
+ id?: string;
6
+ value: number;
7
+ min?: number;
8
+ max?: number;
9
+ step?: number;
10
+ disabled?: boolean;
11
+ label: string;
12
+ describedBy?: string;
13
+ class?: string;
14
+ onValueChange: (value: number) => void;
15
+ };
16
+
17
+ let props: SliderProps = $props();
18
+ let Control = $state<Component<SliderProps> | undefined>(undefined);
19
+
20
+ void import("@admin/components/ui/slider/slider-content.svelte").then(
21
+ ({ default: component }) => (Control = component)
22
+ );
23
+ </script>
24
+
25
+ {#if Control !== undefined}
26
+ <Control {...props} />
27
+ {:else}
28
+ <div
29
+ class={props.class ??
30
+ "relative flex h-5 w-full animate-pulse items-center rounded-full bg-control-disabled"}
31
+ role="status"
32
+ aria-label={props.label}
33
+ aria-busy="true"
34
+ ></div>
35
+ {/if}
@@ -0,0 +1 @@
1
+ export { default as Toaster } from "@admin/components/ui/sonner/sonner.svelte";
@@ -0,0 +1,55 @@
1
+ <script lang="ts">
2
+ import LoaderCircleIcon from "~icons/lucide/loader-circle";
3
+ import { Toaster as Sonner, type ToasterProps } from "svelte-sonner";
4
+ import { getAdminI18n } from "@riducms/plugin";
5
+
6
+ const i18n = getAdminI18n();
7
+
8
+ let {
9
+ theme = "dark",
10
+ position,
11
+ closeButton = true,
12
+ pauseWhenPageIsHidden = true,
13
+ visibleToasts = 4,
14
+ offset = 16,
15
+ mobileOffset = 12,
16
+ toastOptions,
17
+ ...restProps
18
+ }: ToasterProps = $props();
19
+ const resolvedPosition = $derived(
20
+ position ?? (i18n.direction === "rtl" ? "bottom-left" : "bottom-right")
21
+ );
22
+
23
+ const options = $derived({
24
+ unstyled: true,
25
+ ...toastOptions,
26
+ classes: {
27
+ toast:
28
+ "ridu-toast flex w-[min(calc(100vw-2rem),390px)] items-start gap-2.5 rounded-[10px] py-3 pe-3.5 ps-5 shadow-[var(--shadow-popover)]",
29
+ content: "min-w-0 flex-1",
30
+ title: "text-[13.5px] leading-5 font-semibold",
31
+ description: "mt-0.5 text-[12.5px] leading-5",
32
+ icon: "mt-0.75 shrink-0",
33
+ closeButton: "outline-none focus-visible:outline-2 focus-visible:outline-primary/60",
34
+ ...toastOptions?.classes,
35
+ },
36
+ });
37
+ </script>
38
+
39
+ <Sonner
40
+ {theme}
41
+ position={resolvedPosition}
42
+ {closeButton}
43
+ {pauseWhenPageIsHidden}
44
+ {visibleToasts}
45
+ {offset}
46
+ {mobileOffset}
47
+ toastOptions={options}
48
+ containerAriaLabel={i18n.t("general:notifications")}
49
+ closeButtonAriaLabel={i18n.t("general:dismissNotification")}
50
+ {...restProps}
51
+ >
52
+ {#snippet loadingIcon()}
53
+ <LoaderCircleIcon class="size-3.5 animate-spin" aria-hidden="true" />
54
+ {/snippet}
55
+ </Sonner>
@@ -0,0 +1,5 @@
1
+ export {
2
+ default as StatusIndicator,
3
+ statusIndicatorVariants,
4
+ type StatusTone,
5
+ } from "@admin/components/ui/status-indicator/status-indicator.svelte";
@@ -0,0 +1,54 @@
1
+ <script lang="ts" module>
2
+ import { tv, type VariantProps } from "@riducms/ui";
3
+
4
+ export const statusIndicatorVariants = tv({
5
+ base: "inline-flex items-center gap-1.75 text-[12.5px] text-foreground-muted",
6
+ variants: {
7
+ tone: {
8
+ live: "text-primary",
9
+ warning: "text-warning",
10
+ muted: "text-foreground-muted",
11
+ destructive: "text-destructive",
12
+ success: "text-success",
13
+ },
14
+ },
15
+ defaultVariants: { tone: "muted" },
16
+ });
17
+
18
+ export type StatusTone = VariantProps<typeof statusIndicatorVariants>["tone"];
19
+ </script>
20
+
21
+ <script lang="ts">
22
+ import type { HTMLAttributes } from "svelte/elements";
23
+
24
+ import { cn, type WithElementRef } from "@riducms/ui";
25
+
26
+ let {
27
+ ref = $bindable(null),
28
+ tone = "muted",
29
+ pulse = false,
30
+ class: className,
31
+ children,
32
+ ...restProps
33
+ }: WithElementRef<HTMLAttributes<HTMLSpanElement>> & {
34
+ tone?: StatusTone;
35
+ pulse?: boolean;
36
+ } = $props();
37
+ </script>
38
+
39
+ <span
40
+ bind:this={ref}
41
+ data-slot="status-indicator"
42
+ class={cn(statusIndicatorVariants({ tone }), className)}
43
+ {...restProps}
44
+ >
45
+ <span
46
+ class={[
47
+ "size-1.75 shrink-0 rounded-full",
48
+ tone === "muted" ? "border border-current bg-transparent" : "bg-current",
49
+ pulse && "shadow-[0_0_9px_currentColor]",
50
+ ]}
51
+ aria-hidden="true"
52
+ ></span>
53
+ {@render children?.()}
54
+ </span>
@@ -0,0 +1,6 @@
1
+ export { default as Table } from "@admin/components/ui/table/table.svelte";
2
+ export { default as TableBody } from "@admin/components/ui/table/table-body.svelte";
3
+ export { default as TableCell } from "@admin/components/ui/table/table-cell.svelte";
4
+ export { default as TableHead } from "@admin/components/ui/table/table-head.svelte";
5
+ export { default as TableHeader } from "@admin/components/ui/table/table-header.svelte";
6
+ export { default as TableRow } from "@admin/components/ui/table/table-row.svelte";
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "@riducms/ui";
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
14
+ bind:this={ref}
15
+ data-slot="table-body"
16
+ class={cn("[&_tr:last-child]:border-0", className)}
17
+ {...restProps}
18
+ >
19
+ {@render children?.()}
20
+ </tbody>
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "@riducms/ui";
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
14
+ bind:this={ref}
15
+ data-slot="table-cell"
16
+ class={cn(
17
+ "px-2.5 py-2.5 align-middle whitespace-nowrap [&:has([role=checkbox])]:pe-0",
18
+ className
19
+ )}
20
+ {...restProps}
21
+ >
22
+ {@render children?.()}
23
+ </td>
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "@riducms/ui";
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
14
+ bind:this={ref}
15
+ data-slot="table-head"
16
+ class={cn(
17
+ "h-[31px] px-2.5 text-start align-middle text-[11.5px] font-medium whitespace-nowrap text-foreground-muted [&:has([role=checkbox])]:pe-0",
18
+ className
19
+ )}
20
+ {...restProps}
21
+ >
22
+ {@render children?.()}
23
+ </th>
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "@riducms/ui";
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 [&_tr]:border-control-border", className)}
17
+ {...restProps}
18
+ >
19
+ {@render children?.()}
20
+ </thead>
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "@riducms/ui";
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
14
+ bind:this={ref}
15
+ data-slot="table-row"
16
+ class={cn(
17
+ "border-b border-control-border transition-colors hover:bg-control data-[state=selected]:bg-primary/5",
18
+ className
19
+ )}
20
+ {...restProps}
21
+ >
22
+ {@render children?.()}
23
+ </tr>
@@ -0,0 +1,22 @@
1
+ <script lang="ts">
2
+ import { cn, type WithElementRef } from "@riducms/ui";
3
+ import type { HTMLTableAttributes } from "svelte/elements";
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
15
+ bind:this={ref}
16
+ data-slot="table"
17
+ class={cn("w-full caption-bottom text-sm", className)}
18
+ {...restProps}
19
+ >
20
+ {@render children?.()}
21
+ </table>
22
+ </div>
@@ -0,0 +1,8 @@
1
+ export {
2
+ default as TabsList,
3
+ tabsListVariants,
4
+ type TabsListVariant,
5
+ } from "@admin/components/ui/tabs/tabs-list.svelte";
6
+ export { default as Tabs } from "@admin/components/ui/tabs/tabs.svelte";
7
+ export { default as TabsContent } from "@admin/components/ui/tabs/tabs-content.svelte";
8
+ export { default as TabsTrigger } from "@admin/components/ui/tabs/tabs-trigger.svelte";
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import { Tabs as TabsPrimitive } from "bits-ui";
3
+ import { cn } from "@riducms/ui";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ ...restProps
9
+ }: TabsPrimitive.ContentProps = $props();
10
+ </script>
11
+
12
+ <TabsPrimitive.Content
13
+ bind:ref
14
+ data-slot="tabs-content"
15
+ class={cn("text-sm flex-1 outline-none", className)}
16
+ {...restProps}
17
+ />
@@ -0,0 +1,40 @@
1
+ <script lang="ts" module>
2
+ import { tv, type VariantProps } from "@riducms/ui";
3
+
4
+ export const tabsListVariants = tv({
5
+ base: "rounded-lg p-0.5 group-data-horizontal/tabs:h-8 group-data-vertical/tabs:p-1 data-[variant=line]:rounded-none group/tabs-list inline-flex w-fit items-center justify-center text-muted-foreground group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col",
6
+ variants: {
7
+ variant: {
8
+ default: "cn-tabs-list-variant-default border border-control-border bg-tabs-surface",
9
+ line: "cn-tabs-list-variant-line gap-1 bg-transparent",
10
+ },
11
+ },
12
+ defaultVariants: {
13
+ variant: "default",
14
+ },
15
+ });
16
+
17
+ export type TabsListVariant = VariantProps<typeof tabsListVariants>["variant"];
18
+ </script>
19
+
20
+ <script lang="ts">
21
+ import { Tabs as TabsPrimitive } from "bits-ui";
22
+ import { cn } from "@riducms/ui";
23
+
24
+ let {
25
+ ref = $bindable(null),
26
+ variant = "default",
27
+ class: className,
28
+ ...restProps
29
+ }: TabsPrimitive.ListProps & {
30
+ variant?: TabsListVariant;
31
+ } = $props();
32
+ </script>
33
+
34
+ <TabsPrimitive.List
35
+ bind:ref
36
+ data-slot="tabs-list"
37
+ data-variant={variant}
38
+ class={cn(tabsListVariants({ variant }), className)}
39
+ {...restProps}
40
+ />
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import { Tabs as TabsPrimitive } from "bits-ui";
3
+ import { cn } from "@riducms/ui";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ ...restProps
9
+ }: TabsPrimitive.TriggerProps = $props();
10
+ </script>
11
+
12
+ <TabsPrimitive.Trigger
13
+ bind:ref
14
+ data-slot="tabs-trigger"
15
+ class={cn(
16
+ "gap-1.5 rounded-md border border-transparent! px-3.5 py-1 text-[13px] font-medium group-data-vertical/tabs:px-3 group-data-vertical/tabs:py-1 [&_svg:not([class*='size-'])]:size-3.5 relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center whitespace-nowrap text-foreground-sub transition-[background-color,color] duration-150 group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start data-[state=inactive]:hover:text-foreground-muted focus-visible:outline-2 focus-visible:outline-primary/60 focus-visible:outline-offset-2 disabled:pointer-events-none disabled:opacity-45 [&_svg]:pointer-events-none [&_svg]:shrink-0",
17
+ "group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-[state=active]:bg-transparent",
18
+ "data-[state=active]:bg-tabs-active data-[state=active]:text-tabs-text-active",
19
+ "after:absolute after:bg-foreground-strong after:opacity-0 after:transition-opacity data-[orientation=horizontal]:after:inset-x-0 data-[orientation=horizontal]:after:bottom-0 data-[orientation=horizontal]:after:h-0.5 data-[orientation=vertical]:after:inset-y-0 data-[orientation=vertical]:after:-end-1 data-[orientation=vertical]:after:w-0.5 group-data-[variant=line]/tabs-list:data-[state=active]:after:opacity-100",
20
+ className
21
+ )}
22
+ {...restProps}
23
+ />