@dyrected/admin 2.5.45 → 2.5.46

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.
package/dist/admin.css CHANGED
@@ -191,10 +191,60 @@
191
191
  --sidebar-accent-foreground: 259 100% 62%;
192
192
  --sidebar-border: 256 51% 90%;
193
193
  --sidebar-ring: 259 100% 62%;
194
+ }
195
+
196
+ .dy-admin-ui.dark,
197
+ .dy-admin-ui[data-theme="dark"] {
198
+ --background: 240 10% 4%; /* #09090B charcoal */
199
+ --foreground: 78 38% 95%; /* warm lime-white */
200
+
201
+ --card: 240 8% 7%; /* #111114 */
202
+ --card-foreground: 78 38% 95%;
203
+
204
+ --popover: 240 8% 7%;
205
+ --popover-foreground: 78 38% 95%;
206
+
207
+ --primary: 81 100% 59%; /* Signal Lime */
208
+ --primary-foreground: 60 3% 6%;
209
+ --intelligence: 259 100% 70%; /* Brighter Violet */
210
+ --intelligence-foreground: 0 0% 100%;
211
+
212
+ --secondary: 259 45% 15%;
213
+ --secondary-foreground: 266 82% 92%;
214
+
215
+ --muted: 240 7% 13%;
216
+ --muted-foreground: 252 9% 68%;
217
+
218
+ --accent: 259 44% 16%;
219
+ --accent-foreground: 266 82% 88%;
220
+
221
+ --destructive: 0 72% 58%;
222
+ --destructive-foreground: 0 0% 100%;
223
+
224
+ --border: 256 20% 21%;
225
+ --input: 256 20% 21%;
226
+ --ring: 259 100% 70% / 0.34;
227
+
228
+ --sidebar-background: 240 10% 4%;
229
+ --sidebar-foreground: 78 38% 95%;
230
+ --sidebar-primary: 81 100% 59%;
231
+ --sidebar-primary-foreground: 60 3% 6%;
232
+ --sidebar-accent: 259 44% 16%;
233
+ --sidebar-accent-foreground: 266 82% 88%;
234
+ --sidebar-border: 256 20% 21%;
235
+ --sidebar-ring: 259 100% 70%;
236
+ }
237
+
238
+ .dy-admin-ui {
194
239
  color-scheme: light;
195
240
  font-family: var(--font-sans), ui-sans-serif, system-ui, sans-serif;
196
241
  }
197
242
 
243
+ .dy-admin-ui.dark,
244
+ .dy-admin-ui[data-theme="dark"] {
245
+ color-scheme: dark;
246
+ }
247
+
198
248
  .dy-admin-ui :where(h1, h2, h3, h4, h5, h6){
199
249
  font-family: var(--font-serif), ui-serif, Georgia, serif;
200
250
  font-weight: 500;
@@ -2,7 +2,7 @@ import { VariantProps } from 'class-variance-authority';
2
2
  import * as React from "react";
3
3
  declare const buttonVariants: (props?: {
4
4
  variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost";
5
- size?: "icon" | "default" | "sm" | "lg";
5
+ size?: "default" | "sm" | "lg" | "icon";
6
6
  } & import('class-variance-authority/types').ClassProp) => string;
7
7
  export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
8
8
  asChild?: boolean;
@@ -0,0 +1,9 @@
1
+ import { AdminThemePreference, ResolvedAdminTheme } from './admin-theme';
2
+ import * as React from "react";
3
+ export interface AdminThemeContextValue {
4
+ theme: AdminThemePreference;
5
+ resolvedTheme: ResolvedAdminTheme;
6
+ setTheme: (theme: AdminThemePreference) => void;
7
+ themeClassName: string;
8
+ }
9
+ export declare const AdminThemeContext: React.Context<AdminThemeContextValue>;
@@ -0,0 +1,7 @@
1
+ import * as React from "react";
2
+ export declare function AdminThemeProvider({ children }: {
3
+ children: React.ReactNode;
4
+ }): import("react/jsx-runtime").JSX.Element;
5
+ export declare function AdminThemedRoot({ children }: {
6
+ children: React.ReactNode;
7
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ export type AdminThemePreference = "system" | "light" | "dark";
2
+ export type ResolvedAdminTheme = "light" | "dark";
3
+ export declare function resolveAdminTheme(preference: AdminThemePreference, systemTheme: ResolvedAdminTheme): ResolvedAdminTheme;
4
+ export declare function adminThemeClassName(resolvedTheme: ResolvedAdminTheme): "dy-admin-ui dark" | "dy-admin-ui";
@@ -0,0 +1,2 @@
1
+ export type { AdminThemePreference, ResolvedAdminTheme } from './admin-theme';
2
+ export declare function useAdminTheme(): import('./admin-theme-context').AdminThemeContextValue;
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.mjs CHANGED
@@ -5,7 +5,7 @@ import { HashRouter, Link, MemoryRouter, Route, Routes, useLocation, useNavigate
5
5
  import { QueryClient, QueryClientProvider, useInfiniteQuery, useMutation, useQueries, useQuery, useQueryClient } from "@tanstack/react-query";
6
6
  import { createClient } from "@dyrected/sdk";
7
7
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
- import { AlertCircle, AlertTriangle, AlignCenter, AlignLeft, AlignRight, Archive, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, ArrowUpRight, Bold, BookOpen, Braces, Calendar, Check, CheckCircle, CheckCircle2, ChevronDown, ChevronDownIcon, ChevronLeft, ChevronLeftIcon, ChevronRight, ChevronRightIcon, ChevronUp, ChevronsUpDown, Circle, Clock, Clock3, Code, Code2, Compass, Copy, Database, Download, ExternalLink, Eye, EyeOff, FileDown, FileIcon, FileText, FileUp, Filter, Globe, GripVertical, Heading1, Heading2, Image as Image$1, Info, Italic, KeyRound, Layers, LayoutDashboard, Library, Link as Link$1, List, ListOrdered, Loader2, Lock, LogOut, Mail, Menu, Monitor, MoreHorizontal, PanelLeftClose, PanelLeftOpen, Pencil, Play, Plus, Quote, RotateCcw, Save, Scissors, Search, Settings, Settings2, Share2, Shield, Smartphone, Sparkles, Strikethrough, Table, Trash2, Underline, Undo2, Upload, UploadCloud, Users, Video, Volume2, X, XCircle, icons } from "lucide-react";
8
+ import { AlertCircle, AlertTriangle, AlignCenter, AlignLeft, AlignRight, Archive, ArrowDown, ArrowLeft, ArrowRight, ArrowUp, ArrowUpRight, Bold, BookOpen, Braces, Calendar, Check, CheckCircle, CheckCircle2, ChevronDown, ChevronDownIcon, ChevronLeft, ChevronLeftIcon, ChevronRight, ChevronRightIcon, ChevronUp, ChevronsUpDown, Circle, Clock, Clock3, Code, Code2, Compass, Copy, Database, Download, ExternalLink, Eye, EyeOff, FileDown, FileIcon, FileText, FileUp, Filter, Globe, GripVertical, Heading1, Heading2, Image as Image$1, Info, Italic, KeyRound, Layers, LayoutDashboard, Library, Link as Link$1, List, ListOrdered, Loader2, Lock, LogOut, Mail, Menu, Monitor, Moon, MoreHorizontal, PanelLeftClose, PanelLeftOpen, Pencil, Play, Plus, Quote, RotateCcw, Save, Scissors, Search, Settings, Settings2, Share2, Shield, Smartphone, Sparkles, Strikethrough, Sun, Table, Trash2, Underline, Undo2, Upload, UploadCloud, Users, Video, Volume2, X, XCircle, icons } from "lucide-react";
9
9
  import { clsx } from "clsx";
10
10
  import { extendTailwindMerge } from "tailwind-merge";
11
11
  import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
@@ -376,9 +376,40 @@ function BrandingProvider({ children }) {
376
376
  ]), children] });
377
377
  }
378
378
  //#endregion
379
+ //#region src/hooks/admin-theme.ts
380
+ function resolveAdminTheme(preference, systemTheme) {
381
+ return preference === "system" ? systemTheme : preference;
382
+ }
383
+ function adminThemeClassName(resolvedTheme) {
384
+ return resolvedTheme === "dark" ? "dy-admin-ui dark" : "dy-admin-ui";
385
+ }
386
+ //#endregion
387
+ //#region src/hooks/admin-theme-context.ts
388
+ var AdminThemeContext = React$1.createContext(null);
389
+ //#endregion
390
+ //#region src/hooks/use-admin-theme.ts
391
+ function getSystemTheme$1() {
392
+ if (typeof window === "undefined" || !window.matchMedia) return "light";
393
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
394
+ }
395
+ function useAdminTheme() {
396
+ const context = React$1.useContext(AdminThemeContext);
397
+ if (!context) {
398
+ const resolvedTheme = getSystemTheme$1();
399
+ return {
400
+ theme: "system",
401
+ resolvedTheme,
402
+ setTheme: () => void 0,
403
+ themeClassName: adminThemeClassName(resolvedTheme)
404
+ };
405
+ }
406
+ return context;
407
+ }
408
+ //#endregion
379
409
  //#region src/components/ui/dropdown-menu.tsx
380
410
  var DropdownMenu = DropdownMenuPrimitive.Root;
381
411
  var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
412
+ var DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
382
413
  var DropdownMenuSubTrigger = React$1.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(DropdownMenuPrimitive.SubTrigger, {
383
414
  ref,
384
415
  className: cn("dy-flex dy-cursor-default dy-select-none dy-items-center dy-gap-2 dy-rounded-sm dy-px-2 dy-py-1.5 dy-text-sm dy-outline-none focus:dy-bg-accent data-[state=open]:dy-bg-accent [&_svg]:dy-pointer-events-none [&_svg]:dy-size-4 [&_svg]:dy-shrink-0", inset && "dy-pl-8", className),
@@ -392,15 +423,19 @@ var DropdownMenuSubContent = React$1.forwardRef(({ className, ...props }, ref) =
392
423
  ...props
393
424
  }));
394
425
  DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
395
- var DropdownMenuContent = React$1.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx("div", {
396
- className: "dy-admin-ui",
397
- children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.Content, {
398
- ref,
399
- sideOffset,
400
- className: cn("dy-z-50 dy-max-h-[var(--radix-dropdown-menu-content-available-height)] dy-min-w-[8rem] dy-overflow-y-auto dy-overflow-x-hidden dy-rounded-md dy-border dy-bg-popover dy-p-1 dy-text-popover-foreground dy-shadow-md data-[state=open]:dy-animate-in data-[state=closed]:dy-animate-out data-[state=closed]:dy-fade-out-0 data-[state=open]:dy-fade-in-0 data-[state=closed]:dy-zoom-out-95 data-[state=open]:dy-zoom-in-95 data-[side=bottom]:dy-slide-in-from-top-2 data-[side=left]:dy-slide-in-from-right-2 data-[side=right]:dy-slide-in-from-left-2 data-[side=top]:dy-slide-in-from-bottom-2 dy-origin-[--radix-dropdown-menu-content-transform-origin]", className),
401
- ...props
402
- })
403
- }) }));
426
+ var DropdownMenuContent = React$1.forwardRef(({ className, sideOffset = 4, ...props }, ref) => {
427
+ const { resolvedTheme, themeClassName } = useAdminTheme();
428
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { children: /* @__PURE__ */ jsx("div", {
429
+ className: themeClassName,
430
+ "data-theme": resolvedTheme,
431
+ children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.Content, {
432
+ ref,
433
+ sideOffset,
434
+ className: cn("dy-z-50 dy-max-h-[var(--radix-dropdown-menu-content-available-height)] dy-min-w-[8rem] dy-overflow-y-auto dy-overflow-x-hidden dy-rounded-md dy-border dy-bg-popover dy-p-1 dy-text-popover-foreground dy-shadow-md data-[state=open]:dy-animate-in data-[state=closed]:dy-animate-out data-[state=closed]:dy-fade-out-0 data-[state=open]:dy-fade-in-0 data-[state=closed]:dy-zoom-out-95 data-[state=open]:dy-zoom-in-95 data-[side=bottom]:dy-slide-in-from-top-2 data-[side=left]:dy-slide-in-from-right-2 data-[side=right]:dy-slide-in-from-left-2 data-[side=top]:dy-slide-in-from-bottom-2 dy-origin-[--radix-dropdown-menu-content-transform-origin]", className),
435
+ ...props
436
+ })
437
+ }) });
438
+ });
404
439
  DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
405
440
  var DropdownMenuItem = React$1.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Item, {
406
441
  ref,
@@ -449,6 +484,42 @@ var DropdownMenuShortcut = ({ className, ...props }) => {
449
484
  };
450
485
  DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
451
486
  //#endregion
487
+ //#region src/components/ui/button.tsx
488
+ var buttonVariants = cva("dy-inline-flex dy-items-center dy-justify-center dy-gap-2 dy-whitespace-nowrap dy-rounded-md dy-text-sm dy-font-medium dy-ring-offset-background dy-transition-colors focus-visible:dy-outline-none focus-visible:dy-ring-2 focus-visible:dy-ring-ring focus-visible:dy-ring-offset-2 disabled:dy-pointer-events-none disabled:dy-opacity-50 [&_svg]:dy-pointer-events-none [&_svg]:dy-size-4 [&_svg]:dy-shrink-0", {
489
+ variants: {
490
+ variant: {
491
+ default: "dy-bg-primary dy-text-primary-foreground hover:dy-bg-primary/90",
492
+ destructive: "dy-bg-destructive dy-text-destructive-foreground hover:dy-bg-destructive/90",
493
+ outline: "dy-border dy-border-input dy-bg-background hover:dy-bg-accent hover:dy-text-accent-foreground",
494
+ secondary: "dy-bg-secondary dy-text-secondary-foreground hover:dy-bg-secondary/80",
495
+ ghost: "hover:dy-bg-accent hover:dy-text-accent-foreground",
496
+ link: "dy-text-primary dy-underline-offset-4 hover:dy-underline"
497
+ },
498
+ size: {
499
+ default: "dy-h-10 dy-px-4 dy-py-2",
500
+ sm: "dy-h-9 dy-rounded-md dy-px-3",
501
+ lg: "dy-h-11 dy-rounded-md dy-px-8",
502
+ icon: "dy-h-10 dy-w-10"
503
+ }
504
+ },
505
+ defaultVariants: {
506
+ variant: "default",
507
+ size: "default"
508
+ }
509
+ });
510
+ var Button = React$1.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => {
511
+ return /* @__PURE__ */ jsx(asChild ? Slot : "button", {
512
+ className: cn(buttonVariants({
513
+ variant,
514
+ size,
515
+ className
516
+ })),
517
+ ref,
518
+ ...props
519
+ });
520
+ });
521
+ Button.displayName = "Button";
522
+ //#endregion
452
523
  //#region src/components/layout/admin-shell.tsx
453
524
  function getUserString(user, key) {
454
525
  const value = user?.[key];
@@ -496,6 +567,63 @@ function NavGroup({ label, children, collapsed, defaultExpanded = true }) {
496
567
  })]
497
568
  });
498
569
  }
570
+ function ThemeSelector({ collapsed = false, mobile = false }) {
571
+ const { resolvedTheme, setTheme, theme } = useAdminTheme();
572
+ const Icon = resolvedTheme === "dark" ? Moon : Sun;
573
+ const options = [
574
+ {
575
+ value: "system",
576
+ label: "System",
577
+ icon: Monitor
578
+ },
579
+ {
580
+ value: "light",
581
+ label: "Light",
582
+ icon: Sun
583
+ },
584
+ {
585
+ value: "dark",
586
+ label: "Dark",
587
+ icon: Moon
588
+ }
589
+ ];
590
+ return /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
591
+ asChild: true,
592
+ children: /* @__PURE__ */ jsxs(Button, {
593
+ type: "button",
594
+ variant: "ghost",
595
+ size: mobile || collapsed ? "icon" : "sm",
596
+ className: cn("dy-text-muted-foreground hover:dy-bg-accent hover:dy-text-foreground", collapsed || mobile ? "dy-h-8 dy-w-8" : "dy-h-7 dy-w-full dy-justify-start dy-px-2.5 dy-text-[11px]"),
597
+ title: "Theme",
598
+ "aria-label": "Change admin theme",
599
+ children: [/* @__PURE__ */ jsx(Icon, { className: "dy-h-3.5 dy-w-3.5" }), !collapsed && !mobile && /* @__PURE__ */ jsx("span", { children: "Theme" })]
600
+ })
601
+ }), /* @__PURE__ */ jsxs(DropdownMenuContent, {
602
+ side: collapsed || mobile ? "bottom" : "top",
603
+ align: "end",
604
+ sideOffset: 8,
605
+ className: "dy-w-40",
606
+ children: [
607
+ /* @__PURE__ */ jsx(DropdownMenuLabel, {
608
+ className: "dy-px-2 dy-py-1.5 dy-text-xs dy-text-muted-foreground",
609
+ children: "Theme"
610
+ }),
611
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
612
+ /* @__PURE__ */ jsx(DropdownMenuRadioGroup, {
613
+ value: theme,
614
+ onValueChange: (value) => setTheme(value),
615
+ children: options.map((option) => {
616
+ const OptionIcon = option.icon;
617
+ return /* @__PURE__ */ jsxs(DropdownMenuRadioItem, {
618
+ value: option.value,
619
+ className: "dy-cursor-pointer",
620
+ children: [/* @__PURE__ */ jsx(OptionIcon, { className: "dy-h-4 dy-w-4" }), option.label]
621
+ }, option.value);
622
+ })
623
+ })
624
+ ]
625
+ })] });
626
+ }
499
627
  function SidebarInner({ schemas, isLoading, location, logout, isEmbedded, collapsed, onToggleCollapse, onNavigate }) {
500
628
  const { client, user } = useDyrected();
501
629
  const collections = schemas?.collections?.filter((c) => !c?.admin?.hidden && !c?.slug.startsWith("platform_")) ?? [];
@@ -507,7 +635,7 @@ function SidebarInner({ schemas, isLoading, location, logout, isEmbedded, collap
507
635
  }) : /* @__PURE__ */ jsx("div", { className: "dy-my-2 dy-mx-3 dy-h-px dy-bg-border" });
508
636
  const branding = schemas?.admin?.branding;
509
637
  return /* @__PURE__ */ jsxs("div", {
510
- className: "dy-flex dy-flex-col dy-min-h-screen dy-admin-ui",
638
+ className: "dy-flex dy-flex-col dy-min-h-screen",
511
639
  children: [
512
640
  !isEmbedded && /* @__PURE__ */ jsx("div", {
513
641
  className: cn("dy-flex dy-items-center dy-h-14 dy-shrink-0 dy-transition-all", collapsed ? "dy-justify-center dy-px-2" : "dy-gap-2.5 dy-px-4"),
@@ -641,6 +769,7 @@ function SidebarInner({ schemas, isLoading, location, logout, isEmbedded, collap
641
769
  collapsed,
642
770
  onClick: onNavigate
643
771
  }),
772
+ /* @__PURE__ */ jsx(ThemeSelector, { collapsed }),
644
773
  !isEmbedded && user && /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
645
774
  asChild: true,
646
775
  children: /* @__PURE__ */ jsxs("button", {
@@ -782,9 +911,12 @@ function AdminShell({ children, isEmbedded = false }) {
782
911
  className: "dy-h-7 dy-w-auto"
783
912
  })
784
913
  }),
785
- user && /* @__PURE__ */ jsx("div", {
786
- className: "dy-ml-auto dy-flex dy-h-8 dy-w-8 dy-items-center dy-justify-center dy-rounded-full dy-bg-primary/10 dy-text-primary dy-font-semibold dy-text-xs dy-shrink-0",
787
- children: (user.name || user.email || "?")[0].toUpperCase()
914
+ /* @__PURE__ */ jsxs("div", {
915
+ className: "dy-ml-auto dy-flex dy-items-center dy-gap-1.5",
916
+ children: [/* @__PURE__ */ jsx(ThemeSelector, { mobile: true }), user && /* @__PURE__ */ jsx("div", {
917
+ className: "dy-flex dy-h-8 dy-w-8 dy-items-center dy-justify-center dy-rounded-full dy-bg-primary/10 dy-text-primary dy-font-semibold dy-text-xs dy-shrink-0",
918
+ children: (user.name || user.email || "?")[0].toUpperCase()
919
+ })]
788
920
  })
789
921
  ]
790
922
  }), /* @__PURE__ */ jsx("div", {
@@ -796,42 +928,6 @@ function AdminShell({ children, isEmbedded = false }) {
796
928
  }) });
797
929
  }
798
930
  //#endregion
799
- //#region src/components/ui/button.tsx
800
- var buttonVariants = cva("dy-inline-flex dy-items-center dy-justify-center dy-gap-2 dy-whitespace-nowrap dy-rounded-md dy-text-sm dy-font-medium dy-ring-offset-background dy-transition-colors focus-visible:dy-outline-none focus-visible:dy-ring-2 focus-visible:dy-ring-ring focus-visible:dy-ring-offset-2 disabled:dy-pointer-events-none disabled:dy-opacity-50 [&_svg]:dy-pointer-events-none [&_svg]:dy-size-4 [&_svg]:dy-shrink-0", {
801
- variants: {
802
- variant: {
803
- default: "dy-bg-primary dy-text-primary-foreground hover:dy-bg-primary/90",
804
- destructive: "dy-bg-destructive dy-text-destructive-foreground hover:dy-bg-destructive/90",
805
- outline: "dy-border dy-border-input dy-bg-background hover:dy-bg-accent hover:dy-text-accent-foreground",
806
- secondary: "dy-bg-secondary dy-text-secondary-foreground hover:dy-bg-secondary/80",
807
- ghost: "hover:dy-bg-accent hover:dy-text-accent-foreground",
808
- link: "dy-text-primary dy-underline-offset-4 hover:dy-underline"
809
- },
810
- size: {
811
- default: "dy-h-10 dy-px-4 dy-py-2",
812
- sm: "dy-h-9 dy-rounded-md dy-px-3",
813
- lg: "dy-h-11 dy-rounded-md dy-px-8",
814
- icon: "dy-h-10 dy-w-10"
815
- }
816
- },
817
- defaultVariants: {
818
- variant: "default",
819
- size: "default"
820
- }
821
- });
822
- var Button = React$1.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => {
823
- return /* @__PURE__ */ jsx(asChild ? Slot : "button", {
824
- className: cn(buttonVariants({
825
- variant,
826
- size,
827
- className
828
- })),
829
- ref,
830
- ...props
831
- });
832
- });
833
- Button.displayName = "Button";
834
- //#endregion
835
931
  //#region src/components/ui/badge.tsx
836
932
  var badgeVariants = cva("dy-inline-flex dy-items-center dy-rounded-full dy-border dy-px-2.5 dy-py-0.5 dy-text-xs dy-font-semibold dy-transition-colors focus:dy-outline-none focus:dy-ring-2 focus:dy-ring-ring focus:dy-ring-offset-2", {
837
933
  variants: { variant: {
@@ -1222,13 +1318,17 @@ Input.displayName = "Input";
1222
1318
  //#region src/components/ui/popover.tsx
1223
1319
  var Popover = PopoverPrimitive.Root;
1224
1320
  var PopoverTrigger = PopoverPrimitive.Trigger;
1225
- var PopoverContent = React$1.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(PopoverPrimitive.Content, {
1226
- ref,
1227
- align,
1228
- sideOffset,
1229
- className: cn("dy-admin-ui dy-z-[100] dy-w-72 dy-rounded-md dy-border dy-bg-popover dy-p-0 dy-text-popover-foreground dy-shadow-md dy-outline-none data-[state=open]:dy-animate-in data-[state=closed]:dy-animate-out data-[state=closed]:dy-fade-out-0 data-[state=open]:dy-fade-in-0 data-[state=closed]:dy-zoom-out-95 data-[state=open]:dy-zoom-in-95 data-[side=bottom]:dy-slide-in-from-top-2 data-[side=left]:dy-slide-in-from-right-2 data-[side=right]:dy-slide-in-from-left-2 data-[side=top]:dy-slide-in-from-bottom-2 dy-origin-[--radix-popover-content-transform-origin]", className),
1230
- ...props
1231
- }) }));
1321
+ var PopoverContent = React$1.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => {
1322
+ const { resolvedTheme, themeClassName } = useAdminTheme();
1323
+ return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { children: /* @__PURE__ */ jsx(PopoverPrimitive.Content, {
1324
+ ref,
1325
+ align,
1326
+ sideOffset,
1327
+ "data-theme": resolvedTheme,
1328
+ className: cn(themeClassName, "dy-z-[100] dy-w-72 dy-rounded-md dy-border dy-bg-popover dy-p-0 dy-text-popover-foreground dy-shadow-md dy-outline-none data-[state=open]:dy-animate-in data-[state=closed]:dy-animate-out data-[state=closed]:dy-fade-out-0 data-[state=open]:dy-fade-in-0 data-[state=closed]:dy-zoom-out-95 data-[state=open]:dy-zoom-in-95 data-[side=bottom]:dy-slide-in-from-top-2 data-[side=left]:dy-slide-in-from-right-2 data-[side=right]:dy-slide-in-from-left-2 data-[side=top]:dy-slide-in-from-bottom-2 dy-origin-[--radix-popover-content-transform-origin]", className),
1329
+ ...props
1330
+ }) });
1331
+ });
1232
1332
  PopoverContent.displayName = PopoverPrimitive.Content.displayName;
1233
1333
  var PopoverAnchor = PopoverPrimitive.Anchor;
1234
1334
  //#endregion
@@ -1259,23 +1359,27 @@ var SelectScrollDownButton = React$1.forwardRef(({ className, ...props }, ref) =
1259
1359
  children: /* @__PURE__ */ jsx(ChevronDown, { className: "dy-h-4 dy-w-4" })
1260
1360
  }));
1261
1361
  SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
1262
- var SelectContent = React$1.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsx("div", {
1263
- className: "dy-admin-ui",
1264
- children: /* @__PURE__ */ jsxs(SelectPrimitive.Content, {
1265
- ref,
1266
- className: cn("dy-relative dy-z-[100] dy-max-h-[--radix-select-content-available-height] dy-min-w-[8rem] dy-overflow-y-auto dy-overflow-x-hidden dy-rounded-md dy-border dy-bg-popover dy-text-popover-foreground dy-shadow-md data-[state=open]:dy-animate-in data-[state=closed]:dy-animate-out data-[state=closed]:dy-fade-out-0 data-[state=open]:dy-fade-in-0 data-[state=closed]:dy-zoom-out-95 data-[state=open]:dy-zoom-in-95 data-[side=bottom]:dy-slide-in-from-top-2 data-[side=left]:dy-slide-in-from-right-2 data-[side=right]:dy-translate-x-1 data-[side=top]:dy--translate-y-1 dy-origin-[--radix-select-content-transform-origin]", position === "popper" && "data-[side=bottom]:dy-translate-y-1 data-[side=left]:dy--translate-x-1 data-[side=right]:dy-translate-x-1 data-[side=top]:dy--translate-y-1", className),
1267
- position,
1268
- ...props,
1269
- children: [
1270
- /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
1271
- /* @__PURE__ */ jsx(SelectPrimitive.Viewport, {
1272
- className: cn("dy-p-1", position === "popper" && "dy-h-[var(--radix-select-trigger-height)] dy-w-full dy-min-w-[var(--radix-select-trigger-width)]"),
1273
- children
1274
- }),
1275
- /* @__PURE__ */ jsx(SelectScrollDownButton, {})
1276
- ]
1277
- })
1278
- }) }));
1362
+ var SelectContent = React$1.forwardRef(({ className, children, position = "popper", ...props }, ref) => {
1363
+ const { resolvedTheme, themeClassName } = useAdminTheme();
1364
+ return /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsx("div", {
1365
+ className: themeClassName,
1366
+ "data-theme": resolvedTheme,
1367
+ children: /* @__PURE__ */ jsxs(SelectPrimitive.Content, {
1368
+ ref,
1369
+ className: cn("dy-relative dy-z-[100] dy-max-h-[--radix-select-content-available-height] dy-min-w-[8rem] dy-overflow-y-auto dy-overflow-x-hidden dy-rounded-md dy-border dy-bg-popover dy-text-popover-foreground dy-shadow-md data-[state=open]:dy-animate-in data-[state=closed]:dy-animate-out data-[state=closed]:dy-fade-out-0 data-[state=open]:dy-fade-in-0 data-[state=closed]:dy-zoom-out-95 data-[state=open]:dy-zoom-in-95 data-[side=bottom]:dy-slide-in-from-top-2 data-[side=left]:dy-slide-in-from-right-2 data-[side=right]:dy-translate-x-1 data-[side=top]:dy--translate-y-1 dy-origin-[--radix-select-content-transform-origin]", position === "popper" && "data-[side=bottom]:dy-translate-y-1 data-[side=left]:dy--translate-x-1 data-[side=right]:dy-translate-x-1 data-[side=top]:dy--translate-y-1", className),
1370
+ position,
1371
+ ...props,
1372
+ children: [
1373
+ /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
1374
+ /* @__PURE__ */ jsx(SelectPrimitive.Viewport, {
1375
+ className: cn("dy-p-1", position === "popper" && "dy-h-[var(--radix-select-trigger-height)] dy-w-full dy-min-w-[var(--radix-select-trigger-width)]"),
1376
+ children
1377
+ }),
1378
+ /* @__PURE__ */ jsx(SelectScrollDownButton, {})
1379
+ ]
1380
+ })
1381
+ }) });
1382
+ });
1279
1383
  SelectContent.displayName = SelectPrimitive.Content.displayName;
1280
1384
  var SelectLabel = React$1.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Label, {
1281
1385
  ref,
@@ -1953,21 +2057,25 @@ var DialogOverlay = React$1.forwardRef(({ className, ...props }, ref) => /* @__P
1953
2057
  ...props
1954
2058
  }));
1955
2059
  DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
1956
- var DialogContent = React$1.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(DialogPortal, { children: /* @__PURE__ */ jsxs("div", {
1957
- className: "dy-admin-ui",
1958
- children: [/* @__PURE__ */ jsx(DialogOverlay, {}), /* @__PURE__ */ jsxs(DialogPrimitive.Content, {
1959
- ref,
1960
- className: cn("dy-fixed dy-left-[50%] dy-top-[50%] dy-z-50 dy-grid dy-w-full dy-max-w-lg dy-translate-x-[-50%] dy-translate-y-[-50%] dy-gap-4 dy-border dy-bg-background dy-p-6 dy-shadow-2xl dy-duration-200 data-[state=open]:dy-animate-in data-[state=closed]:dy-animate-out data-[state=closed]:dy-fade-out-0 data-[state=open]:dy-fade-in-0 data-[state=closed]:dy-zoom-out-95 data-[state=open]:dy-zoom-in-95 data-[state=closed]:dy-slide-out-to-left-1/2 data-[state=closed]:dy-slide-out-to-top-[48%] data-[state=open]:dy-slide-in-from-left-1/2 data-[state=open]:dy-slide-in-from-top-[48%] sm:dy-rounded-xl", className),
1961
- ...props,
1962
- children: [children, /* @__PURE__ */ jsxs(DialogPrimitive.Close, {
1963
- className: "dy-absolute dy-right-4 dy-top-4 dy-rounded-sm dy-opacity-70 dy-ring-offset-background dy-transition-opacity hover:dy-opacity-100 focus:dy-outline-none focus:dy-ring-2 focus:dy-ring-ring focus:dy-ring-offset-2 disabled:dy-pointer-events-none data-[state=open]:dy-bg-accent data-[state=open]:dy-text-muted-foreground",
1964
- children: [/* @__PURE__ */ jsx(X, { className: "dy-h-4 dy-w-4" }), /* @__PURE__ */ jsx("span", {
1965
- className: "dy-sr-only",
1966
- children: "Close"
2060
+ var DialogContent = React$1.forwardRef(({ className, children, ...props }, ref) => {
2061
+ const { resolvedTheme, themeClassName } = useAdminTheme();
2062
+ return /* @__PURE__ */ jsx(DialogPortal, { children: /* @__PURE__ */ jsxs("div", {
2063
+ className: themeClassName,
2064
+ "data-theme": resolvedTheme,
2065
+ children: [/* @__PURE__ */ jsx(DialogOverlay, {}), /* @__PURE__ */ jsxs(DialogPrimitive.Content, {
2066
+ ref,
2067
+ className: cn("dy-fixed dy-left-[50%] dy-top-[50%] dy-z-50 dy-grid dy-w-full dy-max-w-lg dy-translate-x-[-50%] dy-translate-y-[-50%] dy-gap-4 dy-border dy-bg-background dy-p-6 dy-shadow-2xl dy-duration-200 data-[state=open]:dy-animate-in data-[state=closed]:dy-animate-out data-[state=closed]:dy-fade-out-0 data-[state=open]:dy-fade-in-0 data-[state=closed]:dy-zoom-out-95 data-[state=open]:dy-zoom-in-95 data-[state=closed]:dy-slide-out-to-left-1/2 data-[state=closed]:dy-slide-out-to-top-[48%] data-[state=open]:dy-slide-in-from-left-1/2 data-[state=open]:dy-slide-in-from-top-[48%] sm:dy-rounded-xl", className),
2068
+ ...props,
2069
+ children: [children, /* @__PURE__ */ jsxs(DialogPrimitive.Close, {
2070
+ className: "dy-absolute dy-right-4 dy-top-4 dy-rounded-sm dy-opacity-70 dy-ring-offset-background dy-transition-opacity hover:dy-opacity-100 focus:dy-outline-none focus:dy-ring-2 focus:dy-ring-ring focus:dy-ring-offset-2 disabled:dy-pointer-events-none data-[state=open]:dy-bg-accent data-[state=open]:dy-text-muted-foreground",
2071
+ children: [/* @__PURE__ */ jsx(X, { className: "dy-h-4 dy-w-4" }), /* @__PURE__ */ jsx("span", {
2072
+ className: "dy-sr-only",
2073
+ children: "Close"
2074
+ })]
1967
2075
  })]
1968
2076
  })]
1969
- })]
1970
- }) }));
2077
+ }) });
2078
+ });
1971
2079
  DialogContent.displayName = DialogPrimitive.Content.displayName;
1972
2080
  var DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
1973
2081
  className: cn("dy-flex dy-flex-col dy-space-y-1.5 dy-text-center sm:dy-text-left", className),
@@ -2826,21 +2934,25 @@ var sheetVariants = cva("dy-fixed dy-z-50 dy-gap-4 dy-bg-background dy-p-6 dy-sh
2826
2934
  } },
2827
2935
  defaultVariants: { side: "right" }
2828
2936
  });
2829
- var SheetContent = React$1.forwardRef(({ side = "right", className, children, ...props }, ref) => /* @__PURE__ */ jsx(SheetPortal, { children: /* @__PURE__ */ jsxs("div", {
2830
- className: "dy-admin-ui",
2831
- children: [/* @__PURE__ */ jsx(SheetOverlay, {}), /* @__PURE__ */ jsxs(DialogPrimitive.Content, {
2832
- ref,
2833
- className: cn(sheetVariants({ side }), className),
2834
- ...props,
2835
- children: [children, /* @__PURE__ */ jsxs(DialogPrimitive.Close, {
2836
- className: "dy-absolute dy-right-4 dy-top-4 dy-rounded-sm dy-opacity-70 dy-ring-offset-background dy-transition-opacity hover:dy-opacity-100 focus:dy-outline-none focus:dy-ring-2 focus:dy-ring-ring focus:dy-ring-offset-2 disabled:dy-pointer-events-none data-[state=open]:dy-bg-secondary",
2837
- children: [/* @__PURE__ */ jsx(X, { className: "dy-h-4 dy-w-4" }), /* @__PURE__ */ jsx("span", {
2838
- className: "dy-sr-only",
2839
- children: "Close"
2937
+ var SheetContent = React$1.forwardRef(({ side = "right", className, children, ...props }, ref) => {
2938
+ const { resolvedTheme, themeClassName } = useAdminTheme();
2939
+ return /* @__PURE__ */ jsx(SheetPortal, { children: /* @__PURE__ */ jsxs("div", {
2940
+ className: themeClassName,
2941
+ "data-theme": resolvedTheme,
2942
+ children: [/* @__PURE__ */ jsx(SheetOverlay, {}), /* @__PURE__ */ jsxs(DialogPrimitive.Content, {
2943
+ ref,
2944
+ className: cn(sheetVariants({ side }), className),
2945
+ ...props,
2946
+ children: [children, /* @__PURE__ */ jsxs(DialogPrimitive.Close, {
2947
+ className: "dy-absolute dy-right-4 dy-top-4 dy-rounded-sm dy-opacity-70 dy-ring-offset-background dy-transition-opacity hover:dy-opacity-100 focus:dy-outline-none focus:dy-ring-2 focus:dy-ring-ring focus:dy-ring-offset-2 disabled:dy-pointer-events-none data-[state=open]:dy-bg-secondary",
2948
+ children: [/* @__PURE__ */ jsx(X, { className: "dy-h-4 dy-w-4" }), /* @__PURE__ */ jsx("span", {
2949
+ className: "dy-sr-only",
2950
+ children: "Close"
2951
+ })]
2840
2952
  })]
2841
2953
  })]
2842
- })]
2843
- }) }));
2954
+ }) });
2955
+ });
2844
2956
  SheetContent.displayName = DialogPrimitive.Content.displayName;
2845
2957
  var SheetHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
2846
2958
  className: cn("dy-flex dy-flex-col dy-space-y-2 dy-text-center sm:dy-text-left", className),
@@ -13297,6 +13409,49 @@ var Toaster$1 = ({ ...props }) => {
13297
13409
  });
13298
13410
  };
13299
13411
  //#endregion
13412
+ //#region src/hooks/admin-theme-provider.tsx
13413
+ function getSystemTheme() {
13414
+ if (typeof window === "undefined" || !window.matchMedia) return "light";
13415
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
13416
+ }
13417
+ function AdminThemeProvider({ children }) {
13418
+ const [theme, setTheme] = usePreferences("theme", "system");
13419
+ const [systemTheme, setSystemTheme] = React$1.useState(() => getSystemTheme());
13420
+ React$1.useEffect(() => {
13421
+ if (typeof window === "undefined" || !window.matchMedia) return;
13422
+ const media = window.matchMedia("(prefers-color-scheme: dark)");
13423
+ const syncSystemTheme = () => {
13424
+ setSystemTheme(media.matches ? "dark" : "light");
13425
+ };
13426
+ syncSystemTheme();
13427
+ media.addEventListener("change", syncSystemTheme);
13428
+ return () => media.removeEventListener("change", syncSystemTheme);
13429
+ }, []);
13430
+ const resolvedTheme = resolveAdminTheme(theme, systemTheme);
13431
+ const value = React$1.useMemo(() => ({
13432
+ theme,
13433
+ resolvedTheme,
13434
+ setTheme,
13435
+ themeClassName: adminThemeClassName(resolvedTheme)
13436
+ }), [
13437
+ resolvedTheme,
13438
+ setTheme,
13439
+ theme
13440
+ ]);
13441
+ return /* @__PURE__ */ jsx(AdminThemeContext.Provider, {
13442
+ value,
13443
+ children
13444
+ });
13445
+ }
13446
+ function AdminThemedRoot({ children }) {
13447
+ const { resolvedTheme, themeClassName } = useAdminTheme();
13448
+ return /* @__PURE__ */ jsx("div", {
13449
+ className: `${themeClassName} dy-h-full`,
13450
+ "data-theme": resolvedTheme,
13451
+ children
13452
+ });
13453
+ }
13454
+ //#endregion
13300
13455
  //#region src/index.tsx
13301
13456
  function CollectionRoute() {
13302
13457
  const { slug } = useParams();
@@ -13383,21 +13538,21 @@ function AdminUI({ apiKey, baseUrl = "/dyrected", siteId, onNavigate, isEmbedded
13383
13538
  });
13384
13539
  return /* @__PURE__ */ jsx("div", {
13385
13540
  className: "dy-admin-ui dy-h-full",
13386
- children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxs(DyrectedProvider, {
13541
+ children: /* @__PURE__ */ jsx(ErrorBoundary, { children: /* @__PURE__ */ jsx(DyrectedProvider, {
13387
13542
  apiKey,
13388
13543
  baseUrl,
13389
13544
  siteId,
13390
13545
  components,
13391
13546
  initialToken,
13392
13547
  defaultTechStack,
13393
- children: [/* @__PURE__ */ jsx(QueryProvider, { children: /* @__PURE__ */ jsx(HashRouter, { children: /* @__PURE__ */ jsx(AdminRoutes, {
13548
+ children: /* @__PURE__ */ jsx(AdminThemeProvider, { children: /* @__PURE__ */ jsxs(AdminThemedRoot, { children: [/* @__PURE__ */ jsx(QueryProvider, { children: /* @__PURE__ */ jsx(HashRouter, { children: /* @__PURE__ */ jsx(AdminRoutes, {
13394
13549
  onNavigate,
13395
13550
  isEmbedded
13396
13551
  }) }) }), /* @__PURE__ */ jsx(Toaster$1, {
13397
13552
  position: "top-right",
13398
13553
  expand: true,
13399
13554
  richColors: true
13400
- })]
13555
+ })] }) })
13401
13556
  }) })
13402
13557
  });
13403
13558
  }
@@ -13429,15 +13584,15 @@ function renderAdminUI(container, props) {
13429
13584
  function AdminStandalone({ apiKey, baseUrl, siteId }) {
13430
13585
  return /* @__PURE__ */ jsx("div", {
13431
13586
  className: "dy-admin-ui dy-h-full",
13432
- children: /* @__PURE__ */ jsxs(DyrectedProvider, {
13587
+ children: /* @__PURE__ */ jsx(DyrectedProvider, {
13433
13588
  apiKey,
13434
13589
  baseUrl,
13435
13590
  siteId,
13436
- children: [/* @__PURE__ */ jsx(QueryProvider, { children: /* @__PURE__ */ jsx(MemoryRouter, { children: /* @__PURE__ */ jsx(AdminRoutes, {}) }) }), /* @__PURE__ */ jsx(Toaster$1, {
13591
+ children: /* @__PURE__ */ jsx(AdminThemeProvider, { children: /* @__PURE__ */ jsxs(AdminThemedRoot, { children: [/* @__PURE__ */ jsx(QueryProvider, { children: /* @__PURE__ */ jsx(MemoryRouter, { children: /* @__PURE__ */ jsx(AdminRoutes, {}) }) }), /* @__PURE__ */ jsx(Toaster$1, {
13437
13592
  position: "top-right",
13438
13593
  expand: true,
13439
13594
  richColors: true
13440
- })]
13595
+ })] }) })
13441
13596
  })
13442
13597
  });
13443
13598
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dyrected/admin",
3
- "version": "2.5.45",
3
+ "version": "2.5.46",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
@@ -64,8 +64,8 @@
64
64
  "tailwind-merge": "^3.5.0",
65
65
  "tailwindcss-animate": "^1.0.7",
66
66
  "zod": "^3.25.76",
67
- "@dyrected/core": "^2.5.45",
68
- "@dyrected/sdk": "^2.5.45"
67
+ "@dyrected/core": "^2.5.46",
68
+ "@dyrected/sdk": "^2.5.46"
69
69
  },
70
70
  "peerDependencies": {
71
71
  "@tanstack/react-query": "^5.0.0",