@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,17 @@
1
+ <script lang="ts">
2
+ import { Dialog as DialogPrimitive } from "bits-ui";
3
+ import { cn } from "@riducms/ui";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ ...restProps
9
+ }: DialogPrimitive.TitleProps = $props();
10
+ </script>
11
+
12
+ <DialogPrimitive.Title
13
+ bind:ref
14
+ data-slot="dialog-title"
15
+ class={cn("text-base leading-none font-medium", className)}
16
+ {...restProps}
17
+ />
@@ -0,0 +1,11 @@
1
+ <script lang="ts">
2
+ import { Dialog as DialogPrimitive } from "bits-ui";
3
+
4
+ let {
5
+ ref = $bindable(null),
6
+ type = "button",
7
+ ...restProps
8
+ }: DialogPrimitive.TriggerProps = $props();
9
+ </script>
10
+
11
+ <DialogPrimitive.Trigger bind:ref data-slot="dialog-trigger" {type} {...restProps} />
@@ -0,0 +1,7 @@
1
+ <script lang="ts">
2
+ import { Dialog as DialogPrimitive } from "bits-ui";
3
+
4
+ let { open = $bindable(false), ...restProps }: DialogPrimitive.RootProps = $props();
5
+ </script>
6
+
7
+ <DialogPrimitive.Root bind:open {...restProps} />
@@ -0,0 +1,8 @@
1
+ export { default as Dialog } from "@admin/components/ui/dialog/dialog.svelte";
2
+ export { default as DialogClose } from "@admin/components/ui/dialog/dialog-close.svelte";
3
+ export { default as DialogContent } from "@admin/components/ui/dialog/dialog-content.svelte";
4
+ export { default as DialogDescription } from "@admin/components/ui/dialog/dialog-description.svelte";
5
+ export { default as DialogFooter } from "@admin/components/ui/dialog/dialog-footer.svelte";
6
+ export { default as DialogHeader } from "@admin/components/ui/dialog/dialog-header.svelte";
7
+ export { default as DialogTitle } from "@admin/components/ui/dialog/dialog-title.svelte";
8
+ export { default as DialogTrigger } from "@admin/components/ui/dialog/dialog-trigger.svelte";
@@ -0,0 +1,27 @@
1
+ <script lang="ts">
2
+ import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
3
+ import { cn } from "@riducms/ui";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ sideOffset = 5,
9
+ align = "end",
10
+ ...restProps
11
+ }: DropdownMenuPrimitive.ContentProps = $props();
12
+ </script>
13
+
14
+ <DropdownMenuPrimitive.Portal>
15
+ <DropdownMenuPrimitive.Content
16
+ bind:ref
17
+ data-slot="dropdown-menu-content"
18
+ {sideOffset}
19
+ {align}
20
+ loop
21
+ class={cn(
22
+ "ridu-popover-enter z-50 min-w-44 origin-(--bits-menu-content-transform-origin) rounded-[4px] border border-control-border bg-popover p-1 text-[12.5px] text-popover-foreground shadow-[var(--shadow-popover)] outline-none",
23
+ className
24
+ )}
25
+ {...restProps}
26
+ />
27
+ </DropdownMenuPrimitive.Portal>
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
3
+ import { cn } from "@riducms/ui";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ ...restProps
9
+ }: DropdownMenuPrimitive.ItemProps = $props();
10
+ </script>
11
+
12
+ <DropdownMenuPrimitive.Item
13
+ bind:ref
14
+ data-slot="dropdown-menu-item"
15
+ class={cn(
16
+ "data-[highlighted]:bg-control-hover data-[highlighted]:text-foreground flex min-h-8 cursor-default select-none items-center rounded-[3px] px-2.5 py-1.5 text-foreground-muted outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-40",
17
+ className
18
+ )}
19
+ {...restProps}
20
+ />
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
3
+ import { cn } from "@riducms/ui";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ ...restProps
9
+ }: DropdownMenuPrimitive.SeparatorProps = $props();
10
+ </script>
11
+
12
+ <DropdownMenuPrimitive.Separator
13
+ bind:ref
14
+ data-slot="dropdown-menu-separator"
15
+ class={cn("-mx-1 my-1 h-px bg-control-border", className)}
16
+ {...restProps}
17
+ />
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
3
+
4
+ let {
5
+ ref = $bindable(null),
6
+ class: className,
7
+ ...restProps
8
+ }: DropdownMenuPrimitive.TriggerProps = $props();
9
+ </script>
10
+
11
+ <DropdownMenuPrimitive.Trigger
12
+ bind:ref
13
+ data-slot="dropdown-menu-trigger"
14
+ class={className}
15
+ {...restProps}
16
+ />
@@ -0,0 +1,7 @@
1
+ <script lang="ts">
2
+ import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
3
+
4
+ let { open = $bindable(false), ...restProps }: DropdownMenuPrimitive.RootProps = $props();
5
+ </script>
6
+
7
+ <DropdownMenuPrimitive.Root bind:open {...restProps} />
@@ -0,0 +1,5 @@
1
+ export { default as DropdownMenu } from "@admin/components/ui/dropdown-menu/dropdown-menu.svelte";
2
+ export { default as DropdownMenuContent } from "@admin/components/ui/dropdown-menu/dropdown-menu-content.svelte";
3
+ export { default as DropdownMenuItem } from "@admin/components/ui/dropdown-menu/dropdown-menu-item.svelte";
4
+ export { default as DropdownMenuSeparator } from "@admin/components/ui/dropdown-menu/dropdown-menu-separator.svelte";
5
+ export { default as DropdownMenuTrigger } from "@admin/components/ui/dropdown-menu/dropdown-menu-trigger.svelte";
@@ -0,0 +1,34 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from "svelte";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+
5
+ import { cn, type WithElementRef } from "@riducms/ui";
6
+
7
+ let {
8
+ ref = $bindable(null),
9
+ title,
10
+ description,
11
+ children,
12
+ class: className,
13
+ ...restProps
14
+ }: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
15
+ title: string;
16
+ description: string;
17
+ children?: Snippet;
18
+ } = $props();
19
+ </script>
20
+
21
+ <div
22
+ bind:this={ref}
23
+ data-slot="empty-state"
24
+ class={cn("grid min-h-52 place-items-center px-5 py-10 text-center", className)}
25
+ {...restProps}
26
+ >
27
+ <div class="max-w-md">
28
+ <h2 class="font-serif text-[22px] text-foreground-label">{title}</h2>
29
+ <p class="mt-2 text-[14px] leading-5 text-foreground-sub">{description}</p>
30
+ {#if children}
31
+ <div class="mt-5 flex justify-center">{@render children()}</div>
32
+ {/if}
33
+ </div>
34
+ </div>
@@ -0,0 +1 @@
1
+ export { default as EmptyState } from "@admin/components/ui/empty-state/empty-state.svelte";
@@ -0,0 +1 @@
1
+ export { Input } from "@riducms/ui";
@@ -0,0 +1 @@
1
+ export { default as Kbd } from "@admin/components/ui/kbd/kbd.svelte";
@@ -0,0 +1,24 @@
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from "svelte/elements";
3
+
4
+ import { cn, type WithElementRef } from "@riducms/ui";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ children,
10
+ ...restProps
11
+ }: WithElementRef<HTMLAttributes<HTMLElement>> = $props();
12
+ </script>
13
+
14
+ <kbd
15
+ bind:this={ref}
16
+ data-slot="kbd"
17
+ class={cn(
18
+ "font-mono inline-flex min-h-5 items-center justify-center rounded-[4px] border border-control-border px-1.5 text-[10px] leading-none text-foreground-faint",
19
+ className
20
+ )}
21
+ {...restProps}
22
+ >
23
+ {@render children?.()}
24
+ </kbd>
@@ -0,0 +1 @@
1
+ export { default as Pagination } from "@admin/components/ui/pagination/pagination.svelte";
@@ -0,0 +1,88 @@
1
+ <script lang="ts">
2
+ import ChevronLeftIcon from "~icons/lucide/chevron-left";
3
+ import ChevronRightIcon from "~icons/lucide/chevron-right";
4
+ import { getAdminI18n } from "@riducms/plugin";
5
+
6
+ import { Button } from "@admin/components/ui/button";
7
+
8
+ let {
9
+ start,
10
+ end,
11
+ total,
12
+ page,
13
+ totalPages,
14
+ hasPrevious,
15
+ hasNext,
16
+ busy = false,
17
+ label,
18
+ summary,
19
+ pageSummary,
20
+ previousLabel,
21
+ nextLabel,
22
+ onPrevious,
23
+ onNext,
24
+ }: {
25
+ start: number;
26
+ end: number;
27
+ total: number;
28
+ page: number;
29
+ totalPages: number;
30
+ hasPrevious: boolean;
31
+ hasNext: boolean;
32
+ busy?: boolean;
33
+ label?: string;
34
+ summary?: string;
35
+ pageSummary?: string;
36
+ previousLabel?: string;
37
+ nextLabel?: string;
38
+ onPrevious: () => void;
39
+ onNext: () => void;
40
+ } = $props();
41
+ const i18n = getAdminI18n();
42
+ const resolvedLabel = $derived(label ?? i18n.t("general:pagination"));
43
+ const resolvedSummary = $derived(
44
+ summary ?? `${i18n.formatNumber(start)}–${i18n.formatNumber(end)} / ${i18n.formatNumber(total)}`
45
+ );
46
+ const resolvedPageSummary = $derived(
47
+ pageSummary ??
48
+ i18n.t("collections:pageSummary", {
49
+ page: i18n.formatNumber(page),
50
+ pages: i18n.formatNumber(Math.max(totalPages, 1)),
51
+ })
52
+ );
53
+ const resolvedPreviousLabel = $derived(previousLabel ?? i18n.t("general:previous"));
54
+ const resolvedNextLabel = $derived(nextLabel ?? i18n.t("general:next"));
55
+ </script>
56
+
57
+ <nav
58
+ data-slot="pagination"
59
+ class="flex items-center justify-between gap-4 py-3"
60
+ aria-label={resolvedLabel}
61
+ >
62
+ <p class="font-mono text-[10.5px] text-foreground-faint">{resolvedSummary}</p>
63
+ {#if totalPages > 1}
64
+ <div class="flex items-center gap-2">
65
+ <Button
66
+ variant="outline"
67
+ size="icon-sm"
68
+ disabled={!hasPrevious || busy}
69
+ onclick={onPrevious}
70
+ aria-label={resolvedPreviousLabel}
71
+ >
72
+ <ChevronLeftIcon class="size-3.5 rtl:rotate-180" />
73
+ </Button>
74
+ <span class="font-mono min-w-12 text-center text-[10px] text-foreground-faint">
75
+ {resolvedPageSummary}
76
+ </span>
77
+ <Button
78
+ variant="outline"
79
+ size="icon-sm"
80
+ disabled={!hasNext || busy}
81
+ onclick={onNext}
82
+ aria-label={resolvedNextLabel}
83
+ >
84
+ <ChevronRightIcon class="size-3.5 rtl:rotate-180" />
85
+ </Button>
86
+ </div>
87
+ {/if}
88
+ </nav>
@@ -0,0 +1,3 @@
1
+ export { default as Popover } from "@admin/components/ui/popover/popover.svelte";
2
+ export { default as PopoverContent } from "@admin/components/ui/popover/popover-content.svelte";
3
+ export { default as PopoverTrigger } from "@admin/components/ui/popover/popover-trigger.svelte";
@@ -0,0 +1,29 @@
1
+ <script lang="ts">
2
+ import { Popover as PopoverPrimitive } from "bits-ui";
3
+ import { cn, type WithoutChildrenOrChild } from "@riducms/ui";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ sideOffset = 4,
9
+ align = "center",
10
+ portalProps,
11
+ ...restProps
12
+ }: PopoverPrimitive.ContentProps & {
13
+ portalProps?: WithoutChildrenOrChild<PopoverPrimitive.PortalProps>;
14
+ } = $props();
15
+ </script>
16
+
17
+ <PopoverPrimitive.Portal {...portalProps}>
18
+ <PopoverPrimitive.Content
19
+ bind:ref
20
+ data-slot="popover-content"
21
+ {sideOffset}
22
+ {align}
23
+ class={cn(
24
+ "ridu-popover-enter flex flex-col gap-4 rounded-[4px] border border-control-border bg-popover p-2 text-sm text-popover-foreground shadow-[var(--shadow-popover)] z-50 w-72 origin-(--bits-popover-content-transform-origin) outline-none",
25
+ className
26
+ )}
27
+ {...restProps}
28
+ />
29
+ </PopoverPrimitive.Portal>
@@ -0,0 +1,11 @@
1
+ <script lang="ts">
2
+ import { Popover as PopoverPrimitive } from "bits-ui";
3
+
4
+ let {
5
+ ref = $bindable(null),
6
+ class: className,
7
+ ...restProps
8
+ }: PopoverPrimitive.TriggerProps = $props();
9
+ </script>
10
+
11
+ <PopoverPrimitive.Trigger bind:ref data-slot="popover-trigger" class={className} {...restProps} />
@@ -0,0 +1,7 @@
1
+ <script lang="ts">
2
+ import { Popover as PopoverPrimitive } from "bits-ui";
3
+
4
+ let { open = $bindable(false), ...restProps }: PopoverPrimitive.RootProps = $props();
5
+ </script>
6
+
7
+ <PopoverPrimitive.Root bind:open {...restProps} />
@@ -0,0 +1,3 @@
1
+ export { default as RadioGroup } from "@admin/components/ui/radio-group/radio-group.svelte";
2
+ export { default as RadioGroupItem } from "@admin/components/ui/radio-group/radio-group-item.svelte";
3
+ export { default as RadioCardItem } from "@admin/components/ui/radio-group/radio-card-item.svelte";
@@ -0,0 +1,38 @@
1
+ <script lang="ts">
2
+ import { RadioGroup as RadioGroupPrimitive } from "bits-ui";
3
+
4
+ import { cn } from "@riducms/ui";
5
+
6
+ let {
7
+ value,
8
+ label,
9
+ disabled = false,
10
+ class: className,
11
+ }: {
12
+ value: string;
13
+ label: string;
14
+ disabled?: boolean;
15
+ class?: string;
16
+ } = $props();
17
+ </script>
18
+
19
+ <RadioGroupPrimitive.Item
20
+ {value}
21
+ {disabled}
22
+ data-slot="radio-card-item"
23
+ class={cn(
24
+ "group/radio inline-flex min-h-6 cursor-pointer items-center gap-2 text-left text-[13px] text-foreground-muted outline-none transition-colors hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring/70 focus-visible:ring-offset-2 focus-visible:ring-offset-background data-[state=checked]:text-foreground data-[disabled]:cursor-not-allowed data-[disabled]:text-foreground-faint",
25
+ className
26
+ )}
27
+ >
28
+ {#snippet children({ checked })}
29
+ <span
30
+ class="grid size-5 shrink-0 place-items-center rounded-full border border-control-border bg-control transition-[border-color,background-color] group-hover/radio:border-control-border-hover data-[checked=true]:border-foreground-muted"
31
+ data-checked={checked}
32
+ aria-hidden="true"
33
+ >
34
+ {#if checked}<span class="size-2 rounded-full bg-foreground"></span>{/if}
35
+ </span>
36
+ <span class="min-w-0">{label}</span>
37
+ {/snippet}
38
+ </RadioGroupPrimitive.Item>
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import { RadioGroup as RadioGroupPrimitive } from "bits-ui";
3
+ import { cn } from "@riducms/ui";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ ...restProps
9
+ }: RadioGroupPrimitive.ItemProps = $props();
10
+ </script>
11
+
12
+ <RadioGroupPrimitive.Item
13
+ bind:ref
14
+ data-slot="radio-group-item"
15
+ class={cn("outline-none focus-visible:ring-2 focus-visible:ring-primary/60", className)}
16
+ {...restProps}
17
+ />
@@ -0,0 +1,19 @@
1
+ <script lang="ts">
2
+ import { RadioGroup as RadioGroupPrimitive } from "bits-ui";
3
+ import { cn } from "@riducms/ui";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ value = $bindable(""),
8
+ class: className,
9
+ ...restProps
10
+ }: RadioGroupPrimitive.RootProps = $props();
11
+ </script>
12
+
13
+ <RadioGroupPrimitive.Root
14
+ bind:ref
15
+ bind:value
16
+ data-slot="radio-group"
17
+ class={cn("grid gap-2", className)}
18
+ {...restProps}
19
+ />
@@ -0,0 +1,4 @@
1
+ export { default as Select } from "@admin/components/ui/select/select.svelte";
2
+ export { default as SelectContent } from "@admin/components/ui/select/select-content.svelte";
3
+ export { default as SelectItem } from "@admin/components/ui/select/select-item.svelte";
4
+ export { default as SelectTrigger } from "@admin/components/ui/select/select-trigger.svelte";
@@ -0,0 +1,38 @@
1
+ <script lang="ts">
2
+ import { Select as SelectPrimitive } from "bits-ui";
3
+ import { cn, type WithoutChild, type WithoutChildrenOrChild } from "@riducms/ui";
4
+ import SelectScrollDownButton from "@admin/components/ui/select/select-scroll-down-button.svelte";
5
+ import SelectScrollUpButton from "@admin/components/ui/select/select-scroll-up-button.svelte";
6
+
7
+ let {
8
+ ref = $bindable(null),
9
+ class: className,
10
+ sideOffset = 4,
11
+ portalProps,
12
+ children,
13
+ preventScroll = true,
14
+ ...restProps
15
+ }: WithoutChild<SelectPrimitive.ContentProps> & {
16
+ portalProps?: WithoutChildrenOrChild<SelectPrimitive.PortalProps>;
17
+ } = $props();
18
+ </script>
19
+
20
+ <SelectPrimitive.Portal {...portalProps}>
21
+ <SelectPrimitive.Content
22
+ bind:ref
23
+ {sideOffset}
24
+ {preventScroll}
25
+ data-slot="select-content"
26
+ class={cn(
27
+ "ridu-popover-enter max-h-(--bits-select-content-available-height) min-w-36 rounded-[10px] border border-control-border bg-popover text-popover-foreground shadow-[var(--shadow-popover)] relative isolate z-50 overflow-x-hidden overflow-y-auto",
28
+ className
29
+ )}
30
+ {...restProps}
31
+ >
32
+ <SelectScrollUpButton />
33
+ <SelectPrimitive.Viewport class={cn("w-full min-w-(--bits-select-anchor-width) scroll-my-1")}>
34
+ {@render children?.()}
35
+ </SelectPrimitive.Viewport>
36
+ <SelectScrollDownButton />
37
+ </SelectPrimitive.Content>
38
+ </SelectPrimitive.Portal>
@@ -0,0 +1,40 @@
1
+ <script lang="ts">
2
+ import { Select as SelectPrimitive } from "bits-ui";
3
+ import CheckIcon from "~icons/lucide/check";
4
+ import { cn, type WithoutChild } from "@riducms/ui";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ value,
10
+ label,
11
+ children: childrenProp,
12
+ ...restProps
13
+ }: WithoutChild<SelectPrimitive.ItemProps> = $props();
14
+ </script>
15
+
16
+ <SelectPrimitive.Item
17
+ bind:ref
18
+ {value}
19
+ data-slot="select-item"
20
+ class={cn(
21
+ "min-h-9 gap-2 rounded-md py-2 pe-8 ps-3 text-[14px] text-foreground-body [&_svg:not([class*='size-'])]:size-3.5 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2 relative flex w-full cursor-default items-center outline-none select-none data-[highlighted]:bg-control-hover data-[highlighted]:text-foreground data-[selected]:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-45 [&_svg]:pointer-events-none [&_svg]:shrink-0",
22
+ className
23
+ )}
24
+ {...restProps}
25
+ >
26
+ {#snippet children({ selected, highlighted })}
27
+ <span class="absolute end-2 flex size-3.5 items-center justify-center">
28
+ {#if selected}
29
+ <CheckIcon class="cn-select-item-indicator-icon" />
30
+ {/if}
31
+ </span>
32
+ <span class="flex flex-1 gap-2 shrink-0 whitespace-nowrap">
33
+ {#if childrenProp}
34
+ {@render childrenProp({ selected, highlighted })}
35
+ {:else}
36
+ {label || value}
37
+ {/if}
38
+ </span>
39
+ {/snippet}
40
+ </SelectPrimitive.Item>
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import { Select as SelectPrimitive } from "bits-ui";
3
+ import ChevronDownIcon from "~icons/lucide/chevron-down";
4
+ import { cn, type WithoutChildrenOrChild } from "@riducms/ui";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ ...restProps
10
+ }: WithoutChildrenOrChild<SelectPrimitive.ScrollDownButtonProps> = $props();
11
+ </script>
12
+
13
+ <SelectPrimitive.ScrollDownButton
14
+ bind:ref
15
+ data-slot="select-scroll-down-button"
16
+ class={cn(
17
+ "z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4 bottom-0 w-full",
18
+ className
19
+ )}
20
+ {...restProps}
21
+ >
22
+ <ChevronDownIcon />
23
+ </SelectPrimitive.ScrollDownButton>
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import { Select as SelectPrimitive } from "bits-ui";
3
+ import ChevronUpIcon from "~icons/lucide/chevron-up";
4
+ import { cn, type WithoutChildrenOrChild } from "@riducms/ui";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ ...restProps
10
+ }: WithoutChildrenOrChild<SelectPrimitive.ScrollUpButtonProps> = $props();
11
+ </script>
12
+
13
+ <SelectPrimitive.ScrollUpButton
14
+ bind:ref
15
+ data-slot="select-scroll-up-button"
16
+ class={cn(
17
+ "z-10 flex cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4 top-0 w-full",
18
+ className
19
+ )}
20
+ {...restProps}
21
+ >
22
+ <ChevronUpIcon />
23
+ </SelectPrimitive.ScrollUpButton>
@@ -0,0 +1,29 @@
1
+ <script lang="ts">
2
+ import { Select as SelectPrimitive } from "bits-ui";
3
+ import ChevronDownIcon from "~icons/lucide/chevron-down";
4
+ import { cn, type WithoutChild } from "@riducms/ui";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ children,
10
+ size = "field",
11
+ ...restProps
12
+ }: WithoutChild<SelectPrimitive.TriggerProps> & {
13
+ size?: "field" | "compact" | "toolbar";
14
+ } = $props();
15
+ </script>
16
+
17
+ <SelectPrimitive.Trigger
18
+ bind:ref
19
+ data-slot="select-trigger"
20
+ data-size={size}
21
+ class={cn(
22
+ "gap-2 rounded-[3px] border border-control-border bg-control px-3 text-[13.5px] text-foreground-strong transition-[background-color,border-color,color] duration-150 hover:border-control-border-hover focus-visible:border-primary/65 aria-invalid:border-destructive/65 data-[placeholder]:text-foreground-placeholder data-[size=field]:h-10 data-[size=compact]:h-9 data-[size=toolbar]:h-[34px] data-[size=toolbar]:px-2.5 data-[size=toolbar]:text-[12.5px] *:data-[slot=select-value]:flex *:data-[slot=select-value]:gap-1.5 [&_svg:not([class*='size-'])]:size-3.5 flex w-fit items-center justify-between whitespace-nowrap outline-none disabled:cursor-not-allowed disabled:border-control-border-disabled disabled:bg-control-disabled disabled:opacity-45 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
23
+ className
24
+ )}
25
+ {...restProps}
26
+ >
27
+ {@render children?.()}
28
+ <ChevronDownIcon class="size-3.5 text-foreground-soft pointer-events-none" />
29
+ </SelectPrimitive.Trigger>
@@ -0,0 +1,11 @@
1
+ <script lang="ts">
2
+ import { Select as SelectPrimitive } from "bits-ui";
3
+
4
+ let {
5
+ open = $bindable(false),
6
+ value = $bindable(),
7
+ ...restProps
8
+ }: SelectPrimitive.RootProps = $props();
9
+ </script>
10
+
11
+ <SelectPrimitive.Root bind:open bind:value={value as never} {...restProps} />
@@ -0,0 +1,6 @@
1
+ export { default as Sheet } from "@admin/components/ui/sheet/sheet.svelte";
2
+ export { default as SheetClose } from "@admin/components/ui/sheet/sheet-close.svelte";
3
+ export { default as SheetContent } from "@admin/components/ui/sheet/sheet-content.svelte";
4
+ export { default as SheetDescription } from "@admin/components/ui/sheet/sheet-description.svelte";
5
+ export { default as SheetTitle } from "@admin/components/ui/sheet/sheet-title.svelte";
6
+ export { default as SheetTrigger } from "@admin/components/ui/sheet/sheet-trigger.svelte";
@@ -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} />