@arqel-dev/ui 0.18.0 → 0.19.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 (60) hide show
  1. package/dist/ArqelCreatePage-SUQTG7LF.js +9 -0
  2. package/dist/{ArqelCreatePage-UZAHV4DK.js.map → ArqelCreatePage-SUQTG7LF.js.map} +1 -1
  3. package/dist/ArqelEditPage-TC6CY66H.js +13 -0
  4. package/dist/{ArqelEditPage-7OFWPULE.js.map → ArqelEditPage-TC6CY66H.js.map} +1 -1
  5. package/dist/ArqelIndexPage-3DPWRK2Q.js +15 -0
  6. package/dist/{ArqelIndexPage-ZAVCCM6V.js.map → ArqelIndexPage-3DPWRK2Q.js.map} +1 -1
  7. package/dist/ArqelNotificationsPage-VCNRIN6A.js +7 -0
  8. package/dist/{ArqelNotificationsPage-MBJBYFHW.js.map → ArqelNotificationsPage-VCNRIN6A.js.map} +1 -1
  9. package/dist/action.js +5 -4
  10. package/dist/{chunk-7NGUPQON.js → chunk-4XV35QZA.js} +5 -5
  11. package/dist/{chunk-7NGUPQON.js.map → chunk-4XV35QZA.js.map} +1 -1
  12. package/dist/{chunk-GJ2FKAOM.js → chunk-5ETNGNVM.js} +17 -4
  13. package/dist/chunk-5ETNGNVM.js.map +1 -0
  14. package/dist/chunk-CZUV5WCY.js +3 -0
  15. package/dist/chunk-CZUV5WCY.js.map +1 -0
  16. package/dist/{chunk-DO3PRGVV.js → chunk-FVKM6FDW.js} +3 -3
  17. package/dist/{chunk-DO3PRGVV.js.map → chunk-FVKM6FDW.js.map} +1 -1
  18. package/dist/{chunk-KGAY2AZH.js → chunk-HOJEO5LX.js} +3 -3
  19. package/dist/{chunk-KGAY2AZH.js.map → chunk-HOJEO5LX.js.map} +1 -1
  20. package/dist/{chunk-CH7YLELO.js → chunk-NFP2EB7Y.js} +3 -3
  21. package/dist/{chunk-CH7YLELO.js.map → chunk-NFP2EB7Y.js.map} +1 -1
  22. package/dist/{chunk-DOQUHQND.js → chunk-P64TZA7T.js} +4 -4
  23. package/dist/{chunk-DOQUHQND.js.map → chunk-P64TZA7T.js.map} +1 -1
  24. package/dist/{chunk-WKIYS2FQ.js → chunk-RKWHRD75.js} +53 -10
  25. package/dist/chunk-RKWHRD75.js.map +1 -0
  26. package/dist/{chunk-MZMYV43C.js → chunk-SVCWLDZ4.js} +3 -3
  27. package/dist/{chunk-MZMYV43C.js.map → chunk-SVCWLDZ4.js.map} +1 -1
  28. package/dist/{chunk-YEPQWAD6.js → chunk-TBDWW6L5.js} +3 -3
  29. package/dist/{chunk-YEPQWAD6.js.map → chunk-TBDWW6L5.js.map} +1 -1
  30. package/dist/{chunk-3E66JNQO.js → chunk-VO5KYIHC.js} +3 -30
  31. package/dist/chunk-VO5KYIHC.js.map +1 -0
  32. package/dist/{chunk-IO6RMVUF.js → chunk-WXPBHB7R.js} +3 -3
  33. package/dist/{chunk-IO6RMVUF.js.map → chunk-WXPBHB7R.js.map} +1 -1
  34. package/dist/{chunk-EXA6DWLB.js → chunk-YDUL7HFU.js} +7 -3
  35. package/dist/chunk-YDUL7HFU.js.map +1 -0
  36. package/dist/{chunk-H23VX3RR.js → chunk-YF2RINPG.js} +2 -2
  37. package/dist/{chunk-H23VX3RR.js.map → chunk-YF2RINPG.js.map} +1 -1
  38. package/dist/{chunk-53J74IYR.js → chunk-ZZKWQO3W.js} +30 -3
  39. package/dist/chunk-ZZKWQO3W.js.map +1 -0
  40. package/dist/flash.d.ts +2 -1
  41. package/dist/flash.js +2 -1
  42. package/dist/form.js +3 -2
  43. package/dist/index.js +11 -10
  44. package/dist/pages.js +16 -15
  45. package/dist/pages.js.map +1 -1
  46. package/dist/resource.js +4 -3
  47. package/dist/shell.js +4 -2
  48. package/dist/shell.js.map +1 -1
  49. package/dist/table.js +3 -2
  50. package/dist/utility.js +2 -2
  51. package/package.json +6 -6
  52. package/dist/ArqelCreatePage-UZAHV4DK.js +0 -8
  53. package/dist/ArqelEditPage-7OFWPULE.js +0 -12
  54. package/dist/ArqelIndexPage-ZAVCCM6V.js +0 -14
  55. package/dist/ArqelNotificationsPage-MBJBYFHW.js +0 -6
  56. package/dist/chunk-3E66JNQO.js.map +0 -1
  57. package/dist/chunk-53J74IYR.js.map +0 -1
  58. package/dist/chunk-EXA6DWLB.js.map +0 -1
  59. package/dist/chunk-GJ2FKAOM.js.map +0 -1
  60. package/dist/chunk-WKIYS2FQ.js.map +0 -1
@@ -1,7 +1,8 @@
1
1
  import { CommandPalette } from './chunk-HNUUZEOL.js';
2
2
  import { resolveLucideIcon } from './chunk-RMPOR2YZ.js';
3
3
  import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuItem, Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription } from './chunk-VKZY6J6G.js';
4
- import { Button } from './chunk-H23VX3RR.js';
4
+ import { FlashContainer } from './chunk-5ETNGNVM.js';
5
+ import { Button } from './chunk-YF2RINPG.js';
5
6
  import { cn } from './chunk-B7ULUJVO.js';
6
7
  import * as React3 from 'react';
7
8
  import { useMemo } from 'react';
@@ -473,6 +474,7 @@ function AppShell({
473
474
  className: cn("min-h-screen bg-background text-foreground", className),
474
475
  children: [
475
476
  /* @__PURE__ */ jsx(CommandPalette, {}),
477
+ /* @__PURE__ */ jsx(FlashContainer, {}),
476
478
  children
477
479
  ]
478
480
  }
@@ -486,6 +488,7 @@ function AppShell({
486
488
  className: cn("flex min-h-screen flex-col bg-background text-foreground", className),
487
489
  children: [
488
490
  /* @__PURE__ */ jsx(CommandPalette, {}),
491
+ /* @__PURE__ */ jsx(FlashContainer, {}),
489
492
  topbar,
490
493
  /* @__PURE__ */ jsx("main", { className: "min-w-0 flex-1 p-4 md:p-6", children }),
491
494
  footer
@@ -506,6 +509,7 @@ function AppShell({
506
509
  ),
507
510
  children: [
508
511
  /* @__PURE__ */ jsx(CommandPalette, {}),
512
+ /* @__PURE__ */ jsx(FlashContainer, {}),
509
513
  sidebar,
510
514
  /* @__PURE__ */ jsxs(SidebarInset, { children: [
511
515
  topbar,
@@ -729,5 +733,5 @@ function UserMenu({ user, logoutUrl, profileUrl, className }) {
729
733
  }
730
734
 
731
735
  export { AppShell, Footer, MainContent, Sidebar2 as Sidebar, Topbar, UserMenu };
732
- //# sourceMappingURL=chunk-EXA6DWLB.js.map
733
- //# sourceMappingURL=chunk-EXA6DWLB.js.map
736
+ //# sourceMappingURL=chunk-YDUL7HFU.js.map
737
+ //# sourceMappingURL=chunk-YDUL7HFU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shadcn/hooks/use-mobile.ts","../src/shadcn/ui/tooltip.tsx","../src/shadcn/ui/sidebar.tsx","../src/shell/AppShell.tsx","../src/shell/Footer.tsx","../src/shell/MainContent.tsx","../src/shell/Sidebar.tsx","../src/shell/Topbar.tsx","../src/shell/UserMenu.tsx"],"names":["React","TooltipPrimitive","open","jsx","jsxs","Sidebar","useMemo","Fragment"],"mappings":"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","file":"chunk-YDUL7HFU.js","sourcesContent":["import * as React from \"react\"\n\nconst MOBILE_BREAKPOINT = 768\n\nexport function useIsMobile() {\n const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)\n\n React.useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)\n const onChange = () => {\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)\n }\n mql.addEventListener(\"change\", onChange)\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)\n return () => mql.removeEventListener(\"change\", onChange)\n }, [])\n\n return !!isMobile\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\"\n\nimport { cn } from \"@/utils/cn\"\n\nfunction TooltipProvider({\n delayDuration = 0,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Provider>) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delayDuration={delayDuration}\n {...props}\n />\n )\n}\n\nfunction Tooltip({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n}\n\nfunction TooltipTrigger({\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n className,\n sideOffset = 0,\n children,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Content>) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n \"z-50 w-fit origin-(--radix-tooltip-content-transform-origin) animate-in rounded-md bg-foreground px-3 py-1.5 text-xs text-balance text-background fade-in-0 zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95\",\n className\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n","\"use client\"\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { PanelLeftIcon } from \"lucide-react\"\nimport { Slot } from \"radix-ui\"\n\nimport { useIsMobile } from \"@/shadcn/hooks/use-mobile\"\nimport { cn } from \"@/utils/cn\"\nimport { Button } from \"@/shadcn/ui/button\"\nimport { Input } from \"@/shadcn/ui/input\"\nimport { Separator } from \"@/shadcn/ui/separator\"\nimport {\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n} from \"@/shadcn/ui/sheet\"\nimport { Skeleton } from \"@/shadcn/ui/skeleton\"\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"@/shadcn/ui/tooltip\"\n\nconst SIDEBAR_COOKIE_NAME = \"sidebar_state\"\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\nconst SIDEBAR_WIDTH = \"16rem\"\nconst SIDEBAR_WIDTH_MOBILE = \"18rem\"\nconst SIDEBAR_WIDTH_ICON = \"3rem\"\nconst SIDEBAR_KEYBOARD_SHORTCUT = \"b\"\n\ntype SidebarContextProps = {\n state: \"expanded\" | \"collapsed\"\n open: boolean\n setOpen: (open: boolean) => void\n openMobile: boolean\n setOpenMobile: (open: boolean) => void\n isMobile: boolean\n toggleSidebar: () => void\n}\n\nconst SidebarContext = React.createContext<SidebarContextProps | null>(null)\n\nfunction useSidebar() {\n const context = React.useContext(SidebarContext)\n if (!context) {\n throw new Error(\"useSidebar must be used within a SidebarProvider.\")\n }\n\n return context\n}\n\nfunction SidebarProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n defaultOpen?: boolean\n open?: boolean\n onOpenChange?: (open: boolean) => void\n}) {\n const isMobile = useIsMobile()\n const [openMobile, setOpenMobile] = React.useState(false)\n\n // This is the internal state of the sidebar.\n // We use openProp and setOpenProp for control from outside the component.\n const [_open, _setOpen] = React.useState(defaultOpen)\n const open = openProp ?? _open\n const setOpen = React.useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === \"function\" ? value(open) : value\n if (setOpenProp) {\n setOpenProp(openState)\n } else {\n _setOpen(openState)\n }\n\n // This sets the cookie to keep the sidebar state.\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\n },\n [setOpenProp, open]\n )\n\n // Helper to toggle the sidebar.\n const toggleSidebar = React.useCallback(() => {\n return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)\n }, [isMobile, setOpen, setOpenMobile])\n\n // Adds a keyboard shortcut to toggle the sidebar.\n React.useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (\n event.key === SIDEBAR_KEYBOARD_SHORTCUT &&\n (event.metaKey || event.ctrlKey)\n ) {\n event.preventDefault()\n toggleSidebar()\n }\n }\n\n window.addEventListener(\"keydown\", handleKeyDown)\n return () => window.removeEventListener(\"keydown\", handleKeyDown)\n }, [toggleSidebar])\n\n // We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n // This makes it easier to style the sidebar with Tailwind classes.\n const state = open ? \"expanded\" : \"collapsed\"\n\n const contextValue = React.useMemo<SidebarContextProps>(\n () => ({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n }),\n [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]\n )\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <TooltipProvider delayDuration={0}>\n <div\n data-slot=\"sidebar-wrapper\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH,\n \"--sidebar-width-icon\": SIDEBAR_WIDTH_ICON,\n ...style,\n } as React.CSSProperties\n }\n className={cn(\n \"group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n </TooltipProvider>\n </SidebarContext.Provider>\n )\n}\n\nfunction Sidebar({\n side = \"left\",\n variant = \"sidebar\",\n collapsible = \"offcanvas\",\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n side?: \"left\" | \"right\"\n variant?: \"sidebar\" | \"floating\" | \"inset\"\n collapsible?: \"offcanvas\" | \"icon\" | \"none\"\n}) {\n const { isMobile, state, openMobile, setOpenMobile } = useSidebar()\n\n if (collapsible === \"none\") {\n return (\n <div\n data-slot=\"sidebar\"\n className={cn(\n \"flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n }\n\n if (isMobile) {\n return (\n <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\n <SheetContent\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n className=\"w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH_MOBILE,\n } as React.CSSProperties\n }\n side={side}\n >\n <SheetHeader className=\"sr-only\">\n <SheetTitle>Sidebar</SheetTitle>\n <SheetDescription>Displays the mobile sidebar.</SheetDescription>\n </SheetHeader>\n <div className=\"flex h-full w-full flex-col\">{children}</div>\n </SheetContent>\n </Sheet>\n )\n }\n\n return (\n <div\n className=\"group peer hidden text-sidebar-foreground md:block\"\n data-state={state}\n data-collapsible={state === \"collapsed\" ? collapsible : \"\"}\n data-variant={variant}\n data-side={side}\n data-slot=\"sidebar\"\n >\n {/* This is what handles the sidebar gap on desktop */}\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n \"relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear\",\n \"group-data-[collapsible=offcanvas]:w-0\",\n \"group-data-[side=right]:rotate-180\",\n variant === \"floating\" || variant === \"inset\"\n ? \"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon)\"\n )}\n />\n <div\n data-slot=\"sidebar-container\"\n className={cn(\n \"fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex\",\n side === \"left\"\n ? \"left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]\"\n : \"right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]\",\n // Adjust the padding for floating and inset variants.\n variant === \"floating\" || variant === \"inset\"\n ? \"p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l\",\n className\n )}\n {...props}\n >\n <div\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar-inner\"\n className=\"flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow-sm\"\n >\n {children}\n </div>\n </div>\n </div>\n )\n}\n\nfunction SidebarTrigger({\n className,\n onClick,\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn(\"size-7\", className)}\n onClick={(event) => {\n onClick?.(event)\n toggleSidebar()\n }}\n {...props}\n >\n <PanelLeftIcon />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n )\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<\"button\">) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <button\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n \"absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border sm:flex\",\n \"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize\",\n \"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize\",\n \"group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar\",\n \"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2\",\n \"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInset({ className, ...props }: React.ComponentProps<\"main\">) {\n return (\n <main\n data-slot=\"sidebar-inset\"\n className={cn(\n \"relative flex w-full min-w-0 flex-1 flex-col bg-background\",\n \"md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInput({\n className,\n ...props\n}: React.ComponentProps<typeof Input>) {\n return (\n <Input\n data-slot=\"sidebar-input\"\n data-sidebar=\"input\"\n className={cn(\"h-8 w-full bg-background shadow-none\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-header\"\n data-sidebar=\"header\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-footer\"\n data-sidebar=\"footer\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"sidebar-separator\"\n data-sidebar=\"separator\"\n className={cn(\"mx-2 w-auto bg-sidebar-border\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn(\n \"flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group\"\n data-sidebar=\"group\"\n className={cn(\"relative flex w-full min-w-0 flex-col p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupLabel({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"div\"> & { asChild?: boolean }) {\n const Comp = asChild ? Slot.Root : \"div\"\n\n return (\n <Comp\n data-slot=\"sidebar-group-label\"\n data-sidebar=\"group-label\"\n className={cn(\n \"flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n \"group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupAction({\n className,\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> & { asChild?: boolean }) {\n const Comp = asChild ? Slot.Root : \"button\"\n\n return (\n <Comp\n data-slot=\"sidebar-group-action\"\n data-sidebar=\"group-action\"\n className={cn(\n \"absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n // Increases the hit area of the button on mobile.\n \"after:absolute after:-inset-2 md:after:hidden\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupContent({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group-content\"\n data-sidebar=\"group-content\"\n className={cn(\"w-full text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenu({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu\"\n data-sidebar=\"menu\"\n className={cn(\"flex w-full min-w-0 flex-col gap-1\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuItem({ className, ...props }: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-item\"\n data-sidebar=\"menu-item\"\n className={cn(\"group/menu-item relative\", className)}\n {...props}\n />\n )\n}\n\nconst sidebarMenuButtonVariants = cva(\n \"peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n outline:\n \"bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]\",\n },\n size: {\n default: \"h-8 text-sm\",\n sm: \"h-7 text-xs\",\n lg: \"h-12 text-sm group-data-[collapsible=icon]:p-0!\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction SidebarMenuButton({\n asChild = false,\n isActive = false,\n variant = \"default\",\n size = \"default\",\n tooltip,\n className,\n ...props\n}: React.ComponentProps<\"button\"> & {\n asChild?: boolean\n isActive?: boolean\n tooltip?: string | React.ComponentProps<typeof TooltipContent>\n} & VariantProps<typeof sidebarMenuButtonVariants>) {\n const Comp = asChild ? Slot.Root : \"button\"\n const { isMobile, state } = useSidebar()\n\n const button = (\n <Comp\n data-slot=\"sidebar-menu-button\"\n data-sidebar=\"menu-button\"\n data-size={size}\n data-active={isActive}\n className={cn(sidebarMenuButtonVariants({ variant, size }), className)}\n {...props}\n />\n )\n\n if (!tooltip) {\n return button\n }\n\n if (typeof tooltip === \"string\") {\n tooltip = {\n children: tooltip,\n }\n }\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent\n side=\"right\"\n align=\"center\"\n hidden={state !== \"collapsed\" || isMobile}\n {...tooltip}\n />\n </Tooltip>\n )\n}\n\nfunction SidebarMenuAction({\n className,\n asChild = false,\n showOnHover = false,\n ...props\n}: React.ComponentProps<\"button\"> & {\n asChild?: boolean\n showOnHover?: boolean\n}) {\n const Comp = asChild ? Slot.Root : \"button\"\n\n return (\n <Comp\n data-slot=\"sidebar-menu-action\"\n data-sidebar=\"menu-action\"\n className={cn(\n \"absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform peer-hover/menu-button:text-sidebar-accent-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n // Increases the hit area of the button on mobile.\n \"after:absolute after:-inset-2 md:after:hidden\",\n \"peer-data-[size=sm]/menu-button:top-1\",\n \"peer-data-[size=default]/menu-button:top-1.5\",\n \"peer-data-[size=lg]/menu-button:top-2.5\",\n \"group-data-[collapsible=icon]:hidden\",\n showOnHover &&\n \"group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground data-[state=open]:opacity-100 md:opacity-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuBadge({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n \"pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none\",\n \"peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground\",\n \"peer-data-[size=sm]/menu-button:top-1\",\n \"peer-data-[size=default]/menu-button:top-1.5\",\n \"peer-data-[size=lg]/menu-button:top-2.5\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showIcon?: boolean\n}) {\n // Random width between 50 to 90%.\n const width = React.useMemo(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n }, [])\n\n return (\n <div\n data-slot=\"sidebar-menu-skeleton\"\n data-sidebar=\"menu-skeleton\"\n className={cn(\"flex h-8 items-center gap-2 rounded-md px-2\", className)}\n {...props}\n >\n {showIcon && (\n <Skeleton\n className=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n )}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n data-sidebar=\"menu-skeleton-text\"\n style={\n {\n \"--skeleton-width\": width,\n } as React.CSSProperties\n }\n />\n </div>\n )\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n \"mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubItem({\n className,\n ...props\n}: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-sub-item\"\n data-sidebar=\"menu-sub-item\"\n className={cn(\"group/menu-sub-item relative\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubButton({\n asChild = false,\n size = \"md\",\n isActive = false,\n className,\n ...props\n}: React.ComponentProps<\"a\"> & {\n asChild?: boolean\n size?: \"sm\" | \"md\"\n isActive?: boolean\n}) {\n const Comp = asChild ? Slot.Root : \"a\"\n\n return (\n <Comp\n data-slot=\"sidebar-menu-sub-button\"\n data-sidebar=\"menu-sub-button\"\n data-size={size}\n data-active={isActive}\n className={cn(\n \"flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground ring-sidebar-ring outline-hidden hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground\",\n \"data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground\",\n size === \"sm\" && \"text-xs\",\n size === \"md\" && \"text-sm\",\n \"group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarInset,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n useSidebar,\n}\n","/**\n * `<AppShell>` — top-level admin layout wrapper.\n *\n * Four variants control where structural slots land:\n * - `sidebar-left` (default): sidebar on the left, topbar above main\n * - `sidebar-right`: sidebar on the right\n * - `topbar-only`: full-width content under the topbar (no sidebar)\n * - `full-width`: bare content, no chrome\n *\n * For sidebar variants, `<AppShell>` wraps content in shadcn's\n * `<SidebarProvider>` so the rail's collapsed/expanded state, mobile\n * sheet, and keyboard shortcuts work out of the box.\n *\n * Slots (`sidebar`, `topbar`, `footer`, `children`) are passed as React\n * nodes so callers can compose `<Sidebar />` / `<Topbar />` themselves\n * or substitute custom shells per panel.\n */\n\nimport type { ReactNode } from 'react';\nimport { FlashContainer } from '../flash/FlashContainer.js';\nimport { CommandPalette } from '../palette/CommandPalette.js';\nimport { SidebarInset, SidebarProvider } from '../shadcn/ui/sidebar.js';\nimport { cn } from '../utils/cn.js';\n\nexport type AppShellVariant = 'sidebar-left' | 'sidebar-right' | 'topbar-only' | 'full-width';\n\nexport interface AppShellProps {\n variant?: AppShellVariant;\n sidebar?: ReactNode;\n topbar?: ReactNode;\n footer?: ReactNode;\n children: ReactNode;\n className?: string;\n}\n\nexport function AppShell({\n variant = 'sidebar-left',\n sidebar,\n topbar,\n footer,\n children,\n className,\n}: AppShellProps) {\n if (variant === 'full-width') {\n return (\n <div\n data-arqel-shell=\"full-width\"\n className={cn('min-h-screen bg-background text-foreground', className)}\n >\n <CommandPalette />\n <FlashContainer />\n {children}\n </div>\n );\n }\n\n if (variant === 'topbar-only') {\n return (\n <div\n data-arqel-shell=\"topbar-only\"\n className={cn('flex min-h-screen flex-col bg-background text-foreground', className)}\n >\n <CommandPalette />\n <FlashContainer />\n {topbar}\n <main className=\"min-w-0 flex-1 p-4 md:p-6\">{children}</main>\n {footer}\n </div>\n );\n }\n\n const sidebarSide = variant === 'sidebar-right' ? 'right' : 'left';\n\n return (\n <SidebarProvider>\n <div\n data-arqel-shell={variant}\n data-sidebar-side={sidebarSide}\n className={cn(\n 'flex min-h-svh w-full bg-background text-foreground',\n sidebarSide === 'right' && 'flex-row-reverse',\n className,\n )}\n >\n <CommandPalette />\n <FlashContainer />\n {sidebar}\n <SidebarInset>\n {topbar}\n <main className=\"min-w-0 flex-1 p-4 md:p-6\">{children}</main>\n {footer}\n </SidebarInset>\n </div>\n </SidebarProvider>\n );\n}\n","/**\n * `<Footer>` — minimal optional footer rendered below `<MainContent>`.\n */\n\nimport type { ReactNode } from 'react';\nimport { cn } from '../utils/cn.js';\n\nexport interface FooterProps {\n children: ReactNode;\n className?: string;\n}\n\nexport function Footer({ children, className }: FooterProps) {\n return (\n <footer\n data-arqel-footer=\"\"\n className={cn(\n 'shrink-0 border-t border-border bg-background px-4 py-3 text-sm text-muted-foreground',\n className,\n )}\n >\n {children}\n </footer>\n );\n}\n","/**\n * `<MainContent>` — padded content wrapper used inside `<AppShell>`.\n *\n * Accepts breadcrumb and header slots so pages don't need to redefine\n * their own scaffolding. `maxWidth` mirrors the Tailwind container scale\n * — `none` opts out of any constraint (useful for full-bleed dashboards).\n */\n\nimport type { ReactNode } from 'react';\nimport { cn } from '../utils/cn.js';\n\nexport type MainContentMaxWidth = 'none' | 'md' | 'lg' | 'xl' | '2xl' | '4xl' | '6xl' | '7xl';\n\nexport interface MainContentProps {\n breadcrumbs?: ReactNode;\n header?: ReactNode;\n children: ReactNode;\n maxWidth?: MainContentMaxWidth;\n className?: string;\n}\n\nconst MAX_WIDTH_CLASSES: Record<MainContentMaxWidth, string> = {\n none: '',\n md: 'max-w-md',\n lg: 'max-w-lg',\n xl: 'max-w-xl',\n '2xl': 'max-w-2xl',\n '4xl': 'max-w-4xl',\n '6xl': 'max-w-6xl',\n '7xl': 'max-w-7xl',\n};\n\nexport function MainContent({\n breadcrumbs,\n header,\n children,\n maxWidth = '7xl',\n className,\n}: MainContentProps) {\n return (\n <div\n data-arqel-main=\"\"\n className={cn(\n 'mx-auto w-full px-4 py-6 sm:px-6 lg:px-8',\n MAX_WIDTH_CLASSES[maxWidth],\n className,\n )}\n >\n {breadcrumbs && <div className=\"mb-3\">{breadcrumbs}</div>}\n {header && <div className=\"mb-6\">{header}</div>}\n {children}\n </div>\n );\n}\n","/**\n * `<Sidebar>` — primary navigation rail.\n *\n * Wraps the shadcn `Sidebar` block. Items come from `useNavigation()`\n * shared props (Inertia panel.navigation) by default, but the component\n * also accepts an `items` override for custom panels. The shadcn block\n * already handles desktop rail, mobile sheet, collapsed/icon mode, and\n * keyboard/cookie state via `<SidebarProvider>` (rendered by `<AppShell>`).\n */\n\nimport { type NavigationItemPayload, useNavigation } from '@arqel-dev/hooks';\nimport { type ReactNode, useMemo } from 'react';\nimport {\n Sidebar as ShadcnSidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from '../shadcn/ui/sidebar.js';\nimport { resolveLucideIcon } from '../utils/icon.js';\n\nexport interface SidebarProps {\n items?: NavigationItemPayload[];\n brand?: ReactNode;\n footer?: ReactNode;\n className?: string;\n}\n\nexport function Sidebar({ items: itemsProp, brand, footer, className }: SidebarProps) {\n const { items: sharedItems } = useNavigation();\n const items = itemsProp ?? sharedItems;\n const grouped = useMemo(() => groupItems(items), [items]);\n\n return (\n <ShadcnSidebar collapsible=\"icon\" className={className}>\n {brand ? (\n <SidebarHeader>\n <div className=\"flex items-center gap-2 px-2 py-1.5 text-sm font-semibold\">{brand}</div>\n </SidebarHeader>\n ) : null}\n <SidebarContent>\n {grouped.map(([group, list]) => (\n <SidebarGroup key={group ?? '__ungrouped__'}>\n {group ? <SidebarGroupLabel>{group}</SidebarGroupLabel> : null}\n <SidebarGroupContent>\n <SidebarMenu>\n {list.map((item) => {\n const Icon = resolveLucideIcon(item.icon);\n return (\n <SidebarMenuItem key={item.url ?? item.label}>\n <SidebarMenuButton\n asChild={Boolean(item.url)}\n isActive={Boolean(item.active)}\n >\n {item.url ? (\n <a href={item.url}>\n {Icon ? <Icon /> : null}\n <span>{item.label}</span>\n </a>\n ) : (\n <>\n {Icon ? <Icon /> : null}\n <span>{item.label}</span>\n </>\n )}\n </SidebarMenuButton>\n </SidebarMenuItem>\n );\n })}\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n ))}\n </SidebarContent>\n {footer ? <SidebarFooter>{footer}</SidebarFooter> : null}\n </ShadcnSidebar>\n );\n}\n\nfunction groupItems(\n items: NavigationItemPayload[],\n): Array<[string | undefined, NavigationItemPayload[]]> {\n const groups = new Map<string | undefined, NavigationItemPayload[]>();\n for (const item of items) {\n const key = item.group ?? undefined;\n const list = groups.get(key) ?? [];\n list.push(item);\n groups.set(key, list);\n }\n return Array.from(groups.entries());\n}\n","/**\n * `<Topbar>` — header strip above the main content.\n *\n * Phase 1 wires the brand slot and a mobile menu trigger. Search and\n * tenant switcher are reserved slots for Phase 2 (command palette +\n * multi-tenancy). The user menu (including theme control) is exposed as\n * a slot so apps can plug in any dropdown impl — see `<UserMenu>`.\n */\n\nimport type { ReactNode } from 'react';\nimport { SidebarTrigger } from '../shadcn/ui/sidebar.js';\nimport { cn } from '../utils/cn.js';\n\nexport interface TopbarProps {\n brand?: ReactNode;\n search?: ReactNode;\n notifications?: ReactNode;\n userMenu?: ReactNode;\n tenantSwitcher?: ReactNode;\n className?: string;\n}\n\nexport function Topbar({\n brand,\n search,\n notifications,\n userMenu,\n tenantSwitcher,\n className,\n}: TopbarProps) {\n return (\n <header\n data-arqel-topbar=\"\"\n className={cn(\n // `min-w-0 overflow-hidden` keep the topbar from ever pushing the body\n // wide: as a flex child it must be allowed to shrink below its content\n // (min-w-0), and any control cluster that still can't fit is clipped\n // here instead of overflowing the viewport. Radix popovers (tenant /\n // locale / user menus) render in a portal, so clipping the bar never\n // hides their open content.\n 'flex h-14 min-w-0 shrink-0 items-center gap-2 overflow-hidden border-b border-border bg-background px-4',\n className,\n )}\n >\n <SidebarTrigger className=\"-ml-1\" />\n {brand && <div className=\"flex min-w-0 items-center\">{brand}</div>}\n <div className=\"hidden min-w-0 flex-1 md:block\">{search}</div>\n <div className=\"ml-auto flex min-w-0 items-center gap-2 md:ml-0\">\n {tenantSwitcher}\n {notifications}\n {userMenu}\n </div>\n </header>\n );\n}\n","/**\n * `<UserMenu>` — authenticated-user dropdown for the Topbar `userMenu` slot.\n *\n * Presentational: reads `user`/`logoutUrl`/`profileUrl` via props (no\n * data-fetching). Built on the vendored shadcn DropdownMenu. Logout posts\n * via Inertia (CSRF + redirect handled server-side). Theme control lives\n * here (moved out of the Topbar). Usable standalone — the Profile item and\n * the theme group are each conditional.\n */\n\nimport { useThemeOptional } from '@arqel-dev/react/providers';\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport { Link, router } from '@inertiajs/react';\nimport { ChevronDown, LogOut, Moon, Sun, SunMoon, User } from 'lucide-react';\nimport type { ComponentType, ReactElement } from 'react';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../shadcn/ui/dropdown-menu.js';\nimport { cn } from '../utils/cn.js';\n\nexport interface UserMenuProps {\n user: { name?: string | null; email?: string | null };\n logoutUrl: string;\n profileUrl?: string;\n className?: string;\n}\n\ntype ThemeValue = 'light' | 'dark' | 'system';\n\nconst THEME_OPTIONS: ReadonlyArray<{\n value: ThemeValue;\n icon: ComponentType<{ className?: string }>;\n labelKey: string;\n fallback: string;\n}> = [\n { value: 'light', icon: Sun, labelKey: 'arqel.auth.menu.theme_light', fallback: 'Light' },\n { value: 'dark', icon: Moon, labelKey: 'arqel.auth.menu.theme_dark', fallback: 'Dark' },\n { value: 'system', icon: SunMoon, labelKey: 'arqel.auth.menu.theme_system', fallback: 'System' },\n];\n\nexport function UserMenu({ user, logoutUrl, profileUrl, className }: UserMenuProps): ReactElement {\n const t = useArqelTranslations();\n const themeCtx = useThemeOptional();\n const theme = themeCtx?.theme;\n const setTheme = themeCtx?.setTheme;\n\n const name = user.name ?? undefined;\n const email = user.email ?? undefined;\n const label = name ?? email ?? t('arqel.auth.menu.account', 'Account');\n const initial = (name ?? email ?? '?').trim().charAt(0).toUpperCase();\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger\n aria-label={t('arqel.auth.menu.open', 'Open user menu')}\n className={cn(\n 'inline-flex items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-muted focus:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n className,\n )}\n >\n <span\n aria-hidden=\"true\"\n className=\"flex h-7 w-7 items-center justify-center rounded-full bg-muted text-muted-foreground\"\n >\n {initial}\n </span>\n <span className=\"hidden max-w-[10rem] truncate md:inline\">{label}</span>\n <ChevronDown aria-hidden=\"true\" className=\"h-4 w-4 text-muted-foreground\" />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-64\">\n <DropdownMenuLabel className=\"flex flex-col\">\n {name && <span className=\"font-medium\">{name}</span>}\n {email && <span className=\"truncate text-xs text-muted-foreground\">{email}</span>}\n {!name && !email && <span className=\"font-medium\">{label}</span>}\n </DropdownMenuLabel>\n\n {setTheme && (\n <>\n <DropdownMenuSeparator />\n {/*\n Theme control as a horizontal segmented control: the \"Theme\" label\n on the left, a grouped set of icon buttons on the right. Rendered\n outside a menu item (a plain row) so the icon buttons don't dismiss\n the dropdown on click — `onSelect={(e) => e.preventDefault()}` is\n not needed because these are bare <button>s, not DropdownMenuItems.\n */}\n <div className=\"flex items-center justify-between px-2 py-1.5\">\n <span className=\"text-sm text-muted-foreground\">\n {t('arqel.auth.menu.theme', 'Theme')}\n </span>\n <div className=\"inline-flex items-center gap-0.5 rounded-md bg-muted p-0.5\">\n {THEME_OPTIONS.map(({ value, icon: Icon, labelKey, fallback }) => {\n const active = (theme ?? 'system') === value;\n return (\n <button\n key={value}\n type=\"button\"\n aria-label={t(labelKey, fallback)}\n aria-pressed={active}\n onClick={() => setTheme(value)}\n className={cn(\n 'flex h-7 w-8 items-center justify-center rounded-sm text-muted-foreground transition-colors',\n 'hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n active && 'bg-background text-foreground shadow-sm',\n )}\n >\n <Icon className=\"h-4 w-4\" />\n </button>\n );\n })}\n </div>\n </div>\n </>\n )}\n\n {profileUrl && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem asChild>\n <Link href={profileUrl} className=\"flex items-center gap-2\">\n <User aria-hidden=\"true\" className=\"h-4 w-4\" />\n {t('arqel.auth.menu.profile', 'Profile')}\n </Link>\n </DropdownMenuItem>\n </>\n )}\n\n <DropdownMenuSeparator />\n <DropdownMenuItem\n className=\"flex items-center gap-2 text-destructive focus:text-destructive\"\n onSelect={() => router.post(logoutUrl)}\n >\n <LogOut aria-hidden=\"true\" className=\"h-4 w-4\" />\n {t('arqel.auth.menu.logout', 'Log out')}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"]}
@@ -55,5 +55,5 @@ function Button({
55
55
  }
56
56
 
57
57
  export { Button, buttonVariants };
58
- //# sourceMappingURL=chunk-H23VX3RR.js.map
59
- //# sourceMappingURL=chunk-H23VX3RR.js.map
58
+ //# sourceMappingURL=chunk-YF2RINPG.js.map
59
+ //# sourceMappingURL=chunk-YF2RINPG.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shadcn/ui/button.tsx"],"names":[],"mappings":";;;;;;AAMA,IAAM,cAAA,GAAiB,GAAA;AAAA,EACrB,6bAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EAAS,wDAAA;AAAA,QACT,WAAA,EACE,mJAAA;AAAA,QACF,OAAA,EACE,uIAAA;AAAA,QACF,SAAA,EACE,8DAAA;AAAA,QACF,KAAA,EACE,sEAAA;AAAA,QACF,IAAA,EAAM;AAAA,OACR;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS,+BAAA;AAAA,QACT,EAAA,EAAI,0FAAA;AAAA,QACJ,EAAA,EAAI,+CAAA;AAAA,QACJ,EAAA,EAAI,sCAAA;AAAA,QACJ,IAAA,EAAM,QAAA;AAAA,QACN,SAAA,EAAW,wDAAA;AAAA,QACX,SAAA,EAAW,QAAA;AAAA,QACX,SAAA,EAAW,SAAA;AAAA,QACX,YAAA,EAAc;AAAA;AAChB,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ;AAEA,SAAS,MAAA,CAAO;AAAA,EACd,SAAA;AAAA,EACA,OAAA,GAAU,SAAA;AAAA,EACV,IAAA,GAAO,SAAA;AAAA,EACP,OAAA,GAAU,KAAA;AAAA,EACV,GAAG;AACL,CAAA,EAGK;AACH,EAAA,MAAM,IAAA,GAAO,OAAA,GAAU,IAAA,CAAK,IAAA,GAAO,QAAA;AAEnC,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,QAAA;AAAA,MACV,cAAA,EAAc,OAAA;AAAA,MACd,WAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAW,GAAG,cAAA,CAAe,EAAE,SAAS,IAAA,EAAM,SAAA,EAAW,CAAC,CAAA;AAAA,MACzD,GAAG;AAAA;AAAA,GACN;AAEJ","file":"chunk-H23VX3RR.js","sourcesContent":["import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\n\nimport { cn } from \"@/utils/cn\"\n\nconst buttonVariants = cva(\n \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40\",\n outline:\n \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n xs: \"h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n \"icon-xs\": \"size-6 rounded-md [&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\": \"size-8\",\n \"icon-lg\": \"size-10\",\n \"icon-touch\": \"size-11\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot.Root : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n"]}
1
+ {"version":3,"sources":["../src/shadcn/ui/button.tsx"],"names":[],"mappings":";;;;;;AAMA,IAAM,cAAA,GAAiB,GAAA;AAAA,EACrB,6bAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EAAS,wDAAA;AAAA,QACT,WAAA,EACE,mJAAA;AAAA,QACF,OAAA,EACE,uIAAA;AAAA,QACF,SAAA,EACE,8DAAA;AAAA,QACF,KAAA,EACE,sEAAA;AAAA,QACF,IAAA,EAAM;AAAA,OACR;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS,+BAAA;AAAA,QACT,EAAA,EAAI,0FAAA;AAAA,QACJ,EAAA,EAAI,+CAAA;AAAA,QACJ,EAAA,EAAI,sCAAA;AAAA,QACJ,IAAA,EAAM,QAAA;AAAA,QACN,SAAA,EAAW,wDAAA;AAAA,QACX,SAAA,EAAW,QAAA;AAAA,QACX,SAAA,EAAW,SAAA;AAAA,QACX,YAAA,EAAc;AAAA;AAChB,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ;AAEA,SAAS,MAAA,CAAO;AAAA,EACd,SAAA;AAAA,EACA,OAAA,GAAU,SAAA;AAAA,EACV,IAAA,GAAO,SAAA;AAAA,EACP,OAAA,GAAU,KAAA;AAAA,EACV,GAAG;AACL,CAAA,EAGK;AACH,EAAA,MAAM,IAAA,GAAO,OAAA,GAAU,IAAA,CAAK,IAAA,GAAO,QAAA;AAEnC,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,QAAA;AAAA,MACV,cAAA,EAAc,OAAA;AAAA,MACd,WAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAW,GAAG,cAAA,CAAe,EAAE,SAAS,IAAA,EAAM,SAAA,EAAW,CAAC,CAAA;AAAA,MACzD,GAAG;AAAA;AAAA,GACN;AAEJ","file":"chunk-YF2RINPG.js","sourcesContent":["import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\n\nimport { cn } from \"@/utils/cn\"\n\nconst buttonVariants = cva(\n \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n destructive:\n \"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40\",\n outline:\n \"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost:\n \"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n xs: \"h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5\",\n lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n icon: \"size-9\",\n \"icon-xs\": \"size-6 rounded-md [&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\": \"size-8\",\n \"icon-lg\": \"size-10\",\n \"icon-touch\": \"size-11\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot.Root : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n"]}
@@ -16,7 +16,34 @@ function ErrorState({ status, title, description, action, className }) {
16
16
  }
17
17
  );
18
18
  }
19
+ var VARIANT_CLASSES = {
20
+ line: "h-4 w-full",
21
+ block: "h-24 w-full",
22
+ circle: "h-10 w-10 rounded-full"
23
+ };
24
+ function LoadingSkeleton({
25
+ variant = "line",
26
+ width,
27
+ height,
28
+ count = 1,
29
+ className
30
+ }) {
31
+ const items = Array.from({ length: count }, (_, i) => i);
32
+ return /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", "aria-hidden": "true", children: items.map((i) => /* @__PURE__ */ jsx(
33
+ "div",
34
+ {
35
+ style: { width, height },
36
+ className: cn(
37
+ "animate-pulse bg-muted",
38
+ variant !== "circle" && "rounded-sm",
39
+ VARIANT_CLASSES[variant],
40
+ className
41
+ )
42
+ },
43
+ i
44
+ )) });
45
+ }
19
46
 
20
- export { ErrorState };
21
- //# sourceMappingURL=chunk-53J74IYR.js.map
22
- //# sourceMappingURL=chunk-53J74IYR.js.map
47
+ export { ErrorState, LoadingSkeleton };
48
+ //# sourceMappingURL=chunk-ZZKWQO3W.js.map
49
+ //# sourceMappingURL=chunk-ZZKWQO3W.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utility/ErrorState.tsx","../src/utility/LoadingSkeleton.tsx"],"names":["jsx"],"mappings":";;;AAkBO,SAAS,WAAW,EAAE,MAAA,EAAQ,OAAO,WAAA,EAAa,MAAA,EAAQ,WAAU,EAAoB;AAC7F,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,OAAA;AAAA,MACL,SAAA,EAAW,EAAA,CAAG,yDAAA,EAA2D,SAAS,CAAA;AAAA,MAEjF,QAAA,EAAA;AAAA,QAAA,MAAA,oBAAU,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yCAAA,EAA2C,QAAA,EAAA,MAAA,EAAO,CAAA;AAAA,wBAC7E,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,uCAAA,EAAyC,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,QAC5D,WAAA,oBAAe,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,0CAA0C,QAAA,EAAA,WAAA,EAAY,CAAA;AAAA,QAClF,MAAA,oBAAU,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,QAAQ,QAAA,EAAA,MAAA,EAAO;AAAA;AAAA;AAAA,GAC3C;AAEJ;ACNA,IAAM,eAAA,GAAmD;AAAA,EACvD,IAAA,EAAM,YAAA;AAAA,EACN,KAAA,EAAO,aAAA;AAAA,EACP,MAAA,EAAQ;AACV,CAAA;AAEO,SAAS,eAAA,CAAgB;AAAA,EAC9B,OAAA,GAAU,MAAA;AAAA,EACV,KAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA,GAAQ,CAAA;AAAA,EACR;AACF,CAAA,EAAyB;AACvB,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,CAAK,EAAE,MAAA,EAAQ,OAAM,EAAG,CAAC,CAAA,EAAG,CAAA,KAAM,CAAC,CAAA;AACvD,EAAA,uBACEA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EAAsB,aAAA,EAAY,MAAA,EAC9C,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,qBACVA,GAAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MAEC,KAAA,EAAO,EAAE,KAAA,EAAO,MAAA,EAAO;AAAA,MACvB,SAAA,EAAW,EAAA;AAAA,QACT,wBAAA;AAAA,QACA,YAAY,QAAA,IAAY,YAAA;AAAA,QACxB,gBAAgB,OAAO,CAAA;AAAA,QACvB;AAAA;AACF,KAAA;AAAA,IAPK;AAAA,GASR,CAAA,EACH,CAAA;AAEJ","file":"chunk-ZZKWQO3W.js","sourcesContent":["/**\n * `<ErrorState>` — generic error block (404 / 403 / 500).\n *\n * Phase 1 ships a plain layout; richer illustrations / Heroicons land\n * with `@arqel-dev/fields` icon registry.\n */\n\nimport type { ReactNode } from 'react';\nimport { cn } from '../utils/cn.js';\n\nexport interface ErrorStateProps {\n status?: number;\n title: ReactNode;\n description?: ReactNode;\n action?: ReactNode;\n className?: string;\n}\n\nexport function ErrorState({ status, title, description, action, className }: ErrorStateProps) {\n return (\n <div\n role=\"alert\"\n className={cn('flex flex-col items-center gap-3 px-4 py-16 text-center', className)}\n >\n {status && <span className=\"text-sm font-mono text-muted-foreground\">{status}</span>}\n <h1 className=\"text-2xl font-semibold tracking-tight\">{title}</h1>\n {description && <p className=\"max-w-md text-sm text-muted-foreground\">{description}</p>}\n {action && <div className=\"mt-2\">{action}</div>}\n </div>\n );\n}\n","/**\n * `<LoadingSkeleton>` — animated placeholder block.\n *\n * Variants:\n * - `line`: single text line (default)\n * - `block`: rectangular block (cards, hero areas)\n * - `circle`: circular (avatars)\n *\n * Heights / widths default to readable values; override via Tailwind\n * classes or explicit `height` / `width` props for bespoke layouts.\n */\n\nimport { cn } from '../utils/cn.js';\n\nexport type SkeletonVariant = 'line' | 'block' | 'circle';\n\nexport interface LoadingSkeletonProps {\n variant?: SkeletonVariant;\n width?: number | string;\n height?: number | string;\n count?: number;\n className?: string;\n}\n\nconst VARIANT_CLASSES: Record<SkeletonVariant, string> = {\n line: 'h-4 w-full',\n block: 'h-24 w-full',\n circle: 'h-10 w-10 rounded-full',\n};\n\nexport function LoadingSkeleton({\n variant = 'line',\n width,\n height,\n count = 1,\n className,\n}: LoadingSkeletonProps) {\n const items = Array.from({ length: count }, (_, i) => i);\n return (\n <div className=\"flex flex-col gap-2\" aria-hidden=\"true\">\n {items.map((i) => (\n <div\n key={i}\n style={{ width, height }}\n className={cn(\n 'animate-pulse bg-muted',\n variant !== 'circle' && 'rounded-sm',\n VARIANT_CLASSES[variant],\n className,\n )}\n />\n ))}\n </div>\n );\n}\n"]}
package/dist/flash.d.ts CHANGED
@@ -31,7 +31,8 @@ interface FlashToastProps {
31
31
  onDismiss: () => void;
32
32
  durationMs?: number;
33
33
  className?: string;
34
+ downloadUrl?: string | null | undefined;
34
35
  }
35
- declare function FlashToast({ kind, message, onDismiss, durationMs, className, }: FlashToastProps): react_jsx_runtime.JSX.Element;
36
+ declare function FlashToast({ kind, message, onDismiss, durationMs, className, downloadUrl, }: FlashToastProps): react_jsx_runtime.JSX.Element;
36
37
 
37
38
  export { FlashContainer, type FlashContainerProps, type FlashKind, type FlashPosition, FlashToast, type FlashToastProps };
package/dist/flash.js CHANGED
@@ -1,4 +1,5 @@
1
- export { FlashContainer, FlashToast } from './chunk-GJ2FKAOM.js';
1
+ export { FlashContainer, FlashToast } from './chunk-5ETNGNVM.js';
2
+ import './chunk-YF2RINPG.js';
2
3
  import './chunk-B7ULUJVO.js';
3
4
  //# sourceMappingURL=flash.js.map
4
5
  //# sourceMappingURL=flash.js.map
package/dist/form.js CHANGED
@@ -1,6 +1,7 @@
1
- export { FormActions } from './chunk-MZMYV43C.js';
1
+ export { FormActions } from './chunk-SVCWLDZ4.js';
2
2
  export { FieldRenderer, FormFieldset, FormGrid, FormRenderer, FormSection, FormTabs, NativeFieldInput, clearFieldRegistry, getFieldComponent, getRegisteredFields, registerField, unregisterField } from './chunk-CMNZLA32.js';
3
- import './chunk-H23VX3RR.js';
3
+ import './chunk-CZUV5WCY.js';
4
+ import './chunk-YF2RINPG.js';
4
5
  import './chunk-B7ULUJVO.js';
5
6
  //# sourceMappingURL=form.js.map
6
7
  //# sourceMappingURL=form.js.map
package/dist/index.js CHANGED
@@ -1,24 +1,25 @@
1
- export { Breadcrumbs, EmptyState, LoadingSkeleton } from './chunk-3E66JNQO.js';
2
- export { ErrorState } from './chunk-53J74IYR.js';
1
+ export { Breadcrumbs, EmptyState } from './chunk-VO5KYIHC.js';
2
+ export { ErrorState, LoadingSkeleton } from './chunk-ZZKWQO3W.js';
3
3
  export { StatCard, WidgetWrapper } from './chunk-WMOBLT3Z.js';
4
4
  export { Alert, AlertDescription, AlertTitle, Checkbox, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Label, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectSeparator, SelectTrigger, SelectValue, Textarea } from './chunk-D2MUCHFN.js';
5
5
  export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './chunk-6YGRTXEL.js';
6
6
  export { PageHeader } from './chunk-MXUXMHOK.js';
7
- export { AppShell, Footer, MainContent, Sidebar, Topbar, UserMenu } from './chunk-EXA6DWLB.js';
7
+ export { AppShell, Footer, MainContent, Sidebar, Topbar, UserMenu } from './chunk-YDUL7HFU.js';
8
8
  export { CommandPalette } from './chunk-HNUUZEOL.js';
9
9
  export { Badge, Input, Separator, Skeleton, badgeVariants } from './chunk-U4MPY2XT.js';
10
- export { ResourceIndex } from './chunk-KGAY2AZH.js';
11
- export { TableFilters, TablePagination, TableToolbar } from './chunk-YEPQWAD6.js';
10
+ export { ResourceIndex } from './chunk-HOJEO5LX.js';
11
+ export { TableFilters, TablePagination, TableToolbar } from './chunk-TBDWW6L5.js';
12
12
  export { DataTable } from './chunk-JKD6SE75.js';
13
13
  import './chunk-RMPOR2YZ.js';
14
- export { ActionButton, ActionFormModal, ActionMenu } from './chunk-7NGUPQON.js';
15
- export { ConfirmDialog } from './chunk-DO3PRGVV.js';
14
+ export { ActionButton, ActionFormModal, ActionMenu } from './chunk-4XV35QZA.js';
15
+ export { ConfirmDialog } from './chunk-FVKM6FDW.js';
16
16
  import './chunk-VKZY6J6G.js';
17
- export { FormActions } from './chunk-MZMYV43C.js';
17
+ export { FormActions } from './chunk-SVCWLDZ4.js';
18
18
  export { FieldRenderer, FormRenderer, clearFieldRegistry, getFieldComponent, registerField } from './chunk-CMNZLA32.js';
19
- export { Button, buttonVariants } from './chunk-H23VX3RR.js';
19
+ import './chunk-CZUV5WCY.js';
20
20
  export { CanAccess } from './chunk-RNAMHQM6.js';
21
- export { FlashContainer, FlashToast } from './chunk-GJ2FKAOM.js';
21
+ export { FlashContainer, FlashToast } from './chunk-5ETNGNVM.js';
22
+ export { Button, buttonVariants } from './chunk-YF2RINPG.js';
22
23
  export { cn } from './chunk-B7ULUJVO.js';
23
24
  //# sourceMappingURL=index.js.map
24
25
  //# sourceMappingURL=index.js.map
package/dist/pages.js CHANGED
@@ -1,34 +1,35 @@
1
- export { ArqelNotificationsPage } from './chunk-CH7YLELO.js';
1
+ export { ArqelNotificationsPage } from './chunk-NFP2EB7Y.js';
2
2
  export { ArqelShowPage } from './chunk-Q7WGPKUN.js';
3
3
  export { ArqelDashboardPage } from './chunk-3VSDQCFO.js';
4
- export { ArqelEditPage } from './chunk-WKIYS2FQ.js';
5
- export { ArqelIndexPage } from './chunk-DOQUHQND.js';
4
+ export { ArqelEditPage } from './chunk-RKWHRD75.js';
5
+ export { ArqelIndexPage } from './chunk-P64TZA7T.js';
6
6
  import './chunk-YYQ45W25.js';
7
- export { ArqelCreatePage } from './chunk-IO6RMVUF.js';
8
- import './chunk-53J74IYR.js';
7
+ export { ArqelCreatePage } from './chunk-WXPBHB7R.js';
8
+ import './chunk-ZZKWQO3W.js';
9
9
  import './chunk-WMOBLT3Z.js';
10
10
  import './chunk-6YGRTXEL.js';
11
11
  import './chunk-MXUXMHOK.js';
12
- import './chunk-KGAY2AZH.js';
13
- import './chunk-YEPQWAD6.js';
12
+ import './chunk-HOJEO5LX.js';
13
+ import './chunk-TBDWW6L5.js';
14
14
  import './chunk-JKD6SE75.js';
15
15
  import './chunk-RMPOR2YZ.js';
16
- import './chunk-7NGUPQON.js';
17
- import './chunk-DO3PRGVV.js';
16
+ import './chunk-4XV35QZA.js';
17
+ import './chunk-FVKM6FDW.js';
18
18
  import './chunk-VKZY6J6G.js';
19
- import './chunk-MZMYV43C.js';
19
+ import './chunk-SVCWLDZ4.js';
20
20
  import './chunk-CMNZLA32.js';
21
- import './chunk-H23VX3RR.js';
21
+ import './chunk-CZUV5WCY.js';
22
+ import './chunk-YF2RINPG.js';
22
23
  import './chunk-B7ULUJVO.js';
23
24
 
24
25
  // src/pages/index.ts
25
26
  var arqelPages = {
26
- "arqel::index": () => import('./ArqelIndexPage-ZAVCCM6V.js'),
27
- "arqel::create": () => import('./ArqelCreatePage-UZAHV4DK.js'),
28
- "arqel::edit": () => import('./ArqelEditPage-7OFWPULE.js'),
27
+ "arqel::index": () => import('./ArqelIndexPage-3DPWRK2Q.js'),
28
+ "arqel::create": () => import('./ArqelCreatePage-SUQTG7LF.js'),
29
+ "arqel::edit": () => import('./ArqelEditPage-TC6CY66H.js'),
29
30
  "arqel::show": () => import('./ArqelShowPage-TVCJAV2F.js'),
30
31
  "arqel::dashboard": () => import('./ArqelDashboardPage-Z5R4XSH4.js'),
31
- "arqel::notifications": () => import('./ArqelNotificationsPage-MBJBYFHW.js')
32
+ "arqel::notifications": () => import('./ArqelNotificationsPage-VCNRIN6A.js')
32
33
  };
33
34
 
34
35
  export { arqelPages };
package/dist/pages.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/pages/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AA0BO,IAAM,UAAA,GAAuC;AAAA,EAClD,cAAA,EAAgB,MACd,OAAO,8BAAqB,CAAA;AAAA,EAC9B,eAAA,EAAiB,MACf,OAAO,+BAAsB,CAAA;AAAA,EAC/B,aAAA,EAAe,MAAM,OAAO,6BAAoB,CAAA;AAAA,EAChD,aAAA,EAAe,MAAM,OAAO,6BAAoB,CAAA;AAAA,EAChD,kBAAA,EAAoB,MAClB,OAAO,kCAAyB,CAAA;AAAA,EAClC,sBAAA,EAAwB,MACtB,OAAO,sCAA6B;AACxC","file":"pages.js","sourcesContent":["/**\n * Built-in Inertia page registry for `arqel::*`.\n *\n * `createArqelApp({ pages })` from `@arqel-dev/react/inertia` accepts\n * one or more `PageRegistry` records — merge `arqelPages` first so\n * user-defined pages can override per-resource:\n *\n * ```ts\n * import { arqelPages } from '@arqel-dev/ui/pages';\n * import { createArqelApp } from '@arqel-dev/react/inertia';\n *\n * const userPages = import.meta.glob('./Pages/**\\/*.tsx');\n *\n * createArqelApp({\n * pages: { ...arqelPages, ...userPages },\n * });\n * ```\n *\n * Names match what `ResourceController` emits via\n * `Inertia::render('arqel::index', ...)`.\n */\n\nimport type { ComponentType } from 'react';\n\ntype LazyPage = () => Promise<{ default: ComponentType<unknown> }>;\n\nexport const arqelPages: Record<string, LazyPage> = {\n 'arqel::index': () =>\n import('./ArqelIndexPage.js') as Promise<{ default: ComponentType<unknown> }>,\n 'arqel::create': () =>\n import('./ArqelCreatePage.js') as Promise<{ default: ComponentType<unknown> }>,\n 'arqel::edit': () => import('./ArqelEditPage.js') as Promise<{ default: ComponentType<unknown> }>,\n 'arqel::show': () => import('./ArqelShowPage.js') as Promise<{ default: ComponentType<unknown> }>,\n 'arqel::dashboard': () =>\n import('./ArqelDashboardPage.js') as Promise<{ default: ComponentType<unknown> }>,\n 'arqel::notifications': () =>\n import('./ArqelNotificationsPage.js') as Promise<{ default: ComponentType<unknown> }>,\n};\n\nexport { default as ArqelCreatePage } from './ArqelCreatePage.js';\nexport { default as ArqelDashboardPage } from './ArqelDashboardPage.js';\nexport { default as ArqelEditPage } from './ArqelEditPage.js';\nexport { default as ArqelIndexPage } from './ArqelIndexPage.js';\nexport { default as ArqelNotificationsPage } from './ArqelNotificationsPage.js';\nexport { default as ArqelShowPage } from './ArqelShowPage.js';\n"]}
1
+ {"version":3,"sources":["../src/pages/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA0BO,IAAM,UAAA,GAAuC;AAAA,EAClD,cAAA,EAAgB,MACd,OAAO,8BAAqB,CAAA;AAAA,EAC9B,eAAA,EAAiB,MACf,OAAO,+BAAsB,CAAA;AAAA,EAC/B,aAAA,EAAe,MAAM,OAAO,6BAAoB,CAAA;AAAA,EAChD,aAAA,EAAe,MAAM,OAAO,6BAAoB,CAAA;AAAA,EAChD,kBAAA,EAAoB,MAClB,OAAO,kCAAyB,CAAA;AAAA,EAClC,sBAAA,EAAwB,MACtB,OAAO,sCAA6B;AACxC","file":"pages.js","sourcesContent":["/**\n * Built-in Inertia page registry for `arqel::*`.\n *\n * `createArqelApp({ pages })` from `@arqel-dev/react/inertia` accepts\n * one or more `PageRegistry` records — merge `arqelPages` first so\n * user-defined pages can override per-resource:\n *\n * ```ts\n * import { arqelPages } from '@arqel-dev/ui/pages';\n * import { createArqelApp } from '@arqel-dev/react/inertia';\n *\n * const userPages = import.meta.glob('./Pages/**\\/*.tsx');\n *\n * createArqelApp({\n * pages: { ...arqelPages, ...userPages },\n * });\n * ```\n *\n * Names match what `ResourceController` emits via\n * `Inertia::render('arqel::index', ...)`.\n */\n\nimport type { ComponentType } from 'react';\n\ntype LazyPage = () => Promise<{ default: ComponentType<unknown> }>;\n\nexport const arqelPages: Record<string, LazyPage> = {\n 'arqel::index': () =>\n import('./ArqelIndexPage.js') as Promise<{ default: ComponentType<unknown> }>,\n 'arqel::create': () =>\n import('./ArqelCreatePage.js') as Promise<{ default: ComponentType<unknown> }>,\n 'arqel::edit': () => import('./ArqelEditPage.js') as Promise<{ default: ComponentType<unknown> }>,\n 'arqel::show': () => import('./ArqelShowPage.js') as Promise<{ default: ComponentType<unknown> }>,\n 'arqel::dashboard': () =>\n import('./ArqelDashboardPage.js') as Promise<{ default: ComponentType<unknown> }>,\n 'arqel::notifications': () =>\n import('./ArqelNotificationsPage.js') as Promise<{ default: ComponentType<unknown> }>,\n};\n\nexport { default as ArqelCreatePage } from './ArqelCreatePage.js';\nexport { default as ArqelDashboardPage } from './ArqelDashboardPage.js';\nexport { default as ArqelEditPage } from './ArqelEditPage.js';\nexport { default as ArqelIndexPage } from './ArqelIndexPage.js';\nexport { default as ArqelNotificationsPage } from './ArqelNotificationsPage.js';\nexport { default as ArqelShowPage } from './ArqelShowPage.js';\n"]}
package/dist/resource.js CHANGED
@@ -1,8 +1,9 @@
1
- export { ResourceIndex } from './chunk-KGAY2AZH.js';
2
- import './chunk-YEPQWAD6.js';
1
+ export { ResourceIndex } from './chunk-HOJEO5LX.js';
2
+ import './chunk-TBDWW6L5.js';
3
3
  import './chunk-JKD6SE75.js';
4
4
  import './chunk-RMPOR2YZ.js';
5
- import './chunk-H23VX3RR.js';
5
+ import './chunk-CZUV5WCY.js';
6
+ import './chunk-YF2RINPG.js';
6
7
  import './chunk-B7ULUJVO.js';
7
8
  //# sourceMappingURL=resource.js.map
8
9
  //# sourceMappingURL=resource.js.map
package/dist/shell.js CHANGED
@@ -1,10 +1,12 @@
1
1
  import { isSameOriginRelativeUrl } from './chunk-XK2P6CSK.js';
2
- export { AppShell, Footer, MainContent, Sidebar, Topbar, UserMenu } from './chunk-EXA6DWLB.js';
2
+ export { AppShell, Footer, MainContent, Sidebar, Topbar, UserMenu } from './chunk-YDUL7HFU.js';
3
3
  import './chunk-HNUUZEOL.js';
4
4
  import { Badge } from './chunk-U4MPY2XT.js';
5
5
  import './chunk-RMPOR2YZ.js';
6
6
  import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuLabel, DropdownMenuItem, DropdownMenuSeparator } from './chunk-VKZY6J6G.js';
7
- import { Button } from './chunk-H23VX3RR.js';
7
+ import './chunk-CZUV5WCY.js';
8
+ import './chunk-5ETNGNVM.js';
9
+ import { Button } from './chunk-YF2RINPG.js';
8
10
  import { cn } from './chunk-B7ULUJVO.js';
9
11
  import { useArqelTranslations } from '@arqel-dev/react/utils';
10
12
  import { Link, usePage, router } from '@inertiajs/react';
package/dist/shell.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/shell/NotificationList.tsx","../src/shell/NotificationBell.tsx","../src/shell/TenantSwitcher.tsx"],"names":["jsxs","jsx","Bell","Link","useArqelTranslations","router"],"mappings":"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","file":"shell.js","sourcesContent":["/**\n * `<NotificationList>` — renders the `recent` notifications inside the\n * `<NotificationBell>` dropdown content.\n *\n * Extracted from `NotificationBell` so it can be exercised directly in\n * tests without depending on Radix `DropdownMenu` mounting its portal\n * content in jsdom.\n */\n\nimport type { NotificationItem } from '@arqel-dev/types/inertia';\nimport { Link } from '@inertiajs/react';\nimport { AlertTriangle, Bell, Check, Info, type LucideIcon, Mail, User } from 'lucide-react';\nimport type { JSX } from 'react';\nimport { cn } from '../utils/cn.js';\nimport { isSameOriginRelativeUrl } from '../utils/url.js';\n\nexport interface NotificationListProps {\n items: ReadonlyArray<NotificationItem>;\n emptyLabel: string;\n onItemClick: (item: NotificationItem) => void;\n}\n\n/**\n * Allowlist of `data.icon` values accepted from notification payloads.\n *\n * Only these lucide-react icons may be rendered — no dynamic/arbitrary\n * lookup into the lucide namespace, to keep the bundle small and avoid\n * exposing an unbounded icon surface to server-controlled data.\n *\n * Supported keys: `bell` (default), `check`, `info`, `alert`, `mail`, `user`.\n */\nconst NOTIFICATION_ICONS: Record<string, LucideIcon> = {\n bell: Bell,\n check: Check,\n info: Info,\n alert: AlertTriangle,\n mail: Mail,\n user: User,\n};\n\nfunction readTitle(item: NotificationItem): string {\n const title = item.data['title'];\n if (typeof title === 'string' && title.trim()) return title;\n return item.type;\n}\n\nfunction readBody(item: NotificationItem): string | undefined {\n const body = item.data['body'] ?? item.data['message'];\n return typeof body === 'string' && body.trim() ? body : undefined;\n}\n\n/**\n * Only same-origin relative URLs (`/foo`, never `//evil.com`,\n * `https://…`, or `javascript:…`) unlock a navigable `Link` — mirrors\n * the `data.icon` allowlist below: server-controlled notification\n * payloads get a narrow, safe subset of behavior, never arbitrary\n * navigation. Anything else renders the item as a non-navigable button.\n */\nfunction readActionUrl(item: NotificationItem): string | undefined {\n const url = item.data['action_url'];\n return typeof url === 'string' && isSameOriginRelativeUrl(url) ? url : undefined;\n}\n\nfunction readIcon(item: NotificationItem): LucideIcon {\n const icon = item.data['icon'];\n if (typeof icon === 'string' && icon in NOTIFICATION_ICONS) {\n return NOTIFICATION_ICONS[icon] ?? Bell;\n }\n return Bell;\n}\n\nexport function NotificationList({\n items,\n emptyLabel,\n onItemClick,\n}: NotificationListProps): JSX.Element {\n if (items.length === 0) {\n return <div className=\"px-2 py-4 text-center text-sm text-muted-foreground\">{emptyLabel}</div>;\n }\n\n return (\n <div className=\"flex max-h-80 flex-col gap-0.5 overflow-y-auto\">\n {items.map((item) => {\n const title = readTitle(item);\n const body = readBody(item);\n const actionUrl = readActionUrl(item);\n const unread = item.read_at === null;\n const Icon = readIcon(item);\n\n const itemContent = (\n <>\n <span\n aria-hidden=\"true\"\n className={cn(\n 'mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full',\n unread ? 'bg-primary' : 'bg-transparent',\n )}\n />\n <Icon aria-hidden=\"true\" className=\"mt-0.5 h-4 w-4 shrink-0 text-muted-foreground\" />\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate font-medium\">{title}</span>\n {body && <span className=\"truncate text-xs text-muted-foreground\">{body}</span>}\n </span>\n </>\n );\n const itemClassName = cn(\n 'flex w-full items-start gap-2 rounded-sm px-2 py-2 text-left text-sm hover:bg-accent hover:text-accent-foreground',\n unread && 'bg-accent/50',\n );\n\n // The item's root must be either a `Link` (navigable) or a\n // `button` (action-only) — never one nested inside the other,\n // which produces invalid `<a>`-inside-`<button>` HTML.\n return actionUrl ? (\n <Link\n key={item.id}\n href={actionUrl}\n onClick={() => onItemClick(item)}\n className={itemClassName}\n >\n {itemContent}\n </Link>\n ) : (\n <button\n key={item.id}\n type=\"button\"\n onClick={() => onItemClick(item)}\n className={itemClassName}\n >\n {itemContent}\n </button>\n );\n })}\n </div>\n );\n}\n","/**\n * `<NotificationBell>` — database-notifications trigger for the Topbar\n * `notifications` slot.\n *\n * Reads the shared `notifications` prop (`NotificationPayload | null`,\n * see `HandleArqelInertiaRequests`) via `usePage()`. Mounts a bell icon\n * with an unread-count `Badge` (shown only when `unread_count > 0`) and\n * a `DropdownMenu` listing the `recent` notifications. Marking a single\n * notification read, or all of them, does a scoped Inertia partial\n * reload (`only: ['notifications']`) — no full page reload.\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { NotificationItem, NotificationPayload } from '@arqel-dev/types/inertia';\nimport { Link, router, usePage } from '@inertiajs/react';\nimport { Bell } from 'lucide-react';\nimport type { JSX } from 'react';\nimport { Badge } from '../shadcn/ui/badge.js';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../shadcn/ui/dropdown-menu.js';\nimport { cn } from '../utils/cn.js';\nimport { NotificationList } from './NotificationList.js';\n\nexport interface NotificationBellProps {\n className?: string;\n}\n\ninterface NotificationBellPageProps {\n notifications: NotificationPayload | null;\n [key: string]: unknown;\n}\n\nfunction markRead(id: string): void {\n router.post(\n `/admin/notifications/${id}/read`,\n {},\n { preserveScroll: true, only: ['notifications'] },\n );\n}\n\nfunction markAllRead(): void {\n router.post(\n '/admin/notifications/read-all',\n {},\n { preserveScroll: true, only: ['notifications'] },\n );\n}\n\nexport function NotificationBell({ className }: NotificationBellProps): JSX.Element {\n const t = useArqelTranslations();\n const { notifications } = usePage<NotificationBellPageProps>().props;\n\n const unreadCount = notifications?.unread_count ?? 0;\n const recent = notifications?.recent ?? [];\n\n const handleItemClick = (item: NotificationItem): void => {\n if (item.read_at === null) markRead(item.id);\n };\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger\n aria-label={t('arqel.notifications.title', 'Notifications')}\n className={cn(\n 'relative inline-flex h-9 w-9 items-center justify-center rounded-md hover:bg-muted focus:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n className,\n )}\n >\n <Bell aria-hidden=\"true\" className=\"h-4 w-4 text-muted-foreground\" />\n {unreadCount > 0 && (\n <Badge\n variant=\"destructive\"\n className=\"absolute -right-1 -top-1 h-4 min-w-4 justify-center px-1 text-[10px] leading-none\"\n >\n {unreadCount}\n </Badge>\n )}\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-80\">\n <div className=\"flex items-center justify-between px-2 py-1.5\">\n <DropdownMenuLabel className=\"p-0 font-medium\">\n {t('arqel.notifications.title', 'Notifications')}\n </DropdownMenuLabel>\n {unreadCount > 0 && (\n <DropdownMenuItem\n className=\"w-auto justify-end p-0 text-xs text-muted-foreground hover:text-foreground\"\n onSelect={(event) => {\n event.preventDefault();\n markAllRead();\n }}\n >\n {t('arqel.notifications.mark_all_read', 'Mark all as read')}\n </DropdownMenuItem>\n )}\n </div>\n\n <DropdownMenuSeparator />\n\n <NotificationList\n items={recent}\n emptyLabel={t('arqel.notifications.empty', 'No notifications')}\n onItemClick={handleItemClick}\n />\n\n <DropdownMenuSeparator />\n\n <DropdownMenuItem asChild className=\"justify-center text-sm\">\n <Link href=\"/admin/notifications\">{t('arqel.notifications.view_all', 'View all')}</Link>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n","/**\n * `<TenantSwitcher>` — dropdown that lists tenants the user can\n * access and dispatches `POST /admin/tenants/{id}/switch` via\n * Inertia router. Renders nothing when there is no current tenant\n * or the user only has access to one tenant.\n *\n * Mounts in the `tenantSwitcher` slot of `<Topbar>`. The current\n * tenant is read from `props.tenant.current` shared by the\n * server-side `HandleArqelInertiaRequests`; available tenants\n * come from the same payload.\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { TenantSummary } from '@arqel-dev/types/tenant';\nimport { router } from '@inertiajs/react';\nimport type { JSX } from 'react';\nimport { Button } from '../action/Button.js';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../shadcn/ui/dropdown-menu.js';\n\nexport interface TenantSwitcherProps {\n current: TenantSummary | null;\n available: ReadonlyArray<TenantSummary>;\n /**\n * Path template for switching; defaults to\n * `/admin/tenants/{id}/switch`.\n */\n switchUrl?: (tenantId: string | number) => string;\n}\n\nconst DEFAULT_SWITCH_URL = (id: string | number): string => `/admin/tenants/${id}/switch`;\n\nexport function TenantSwitcher({\n current,\n available,\n switchUrl,\n}: TenantSwitcherProps): JSX.Element | null {\n const t = useArqelTranslations();\n if (!current || available.length <= 1) return null;\n\n const buildUrl = switchUrl ?? DEFAULT_SWITCH_URL;\n const labelFor = (tenant: TenantSummary): string =>\n tenant.name?.trim()\n ? tenant.name\n : t('arqel.tenant.unnamed', `Tenant ${tenant.id}`, { id: tenant.id });\n const currentLabel = labelFor(current);\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n data-testid=\"tenant-switcher-trigger\"\n aria-label={t('arqel.aria.tenant_switch', `Switch tenant (current: ${currentLabel})`, {\n tenant: currentLabel,\n })}\n >\n {currentLabel}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {available.map((tenant) => {\n const isCurrent = tenant.id === current.id;\n return (\n <DropdownMenuItem\n key={String(tenant.id)}\n data-testid={`tenant-switcher-option-${String(tenant.id)}`}\n disabled={isCurrent}\n onSelect={() => {\n router.post(buildUrl(tenant.id), {}, { preserveScroll: true });\n }}\n >\n {labelFor(tenant)}\n {isCurrent ? ' ✓' : ''}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/shell/NotificationList.tsx","../src/shell/NotificationBell.tsx","../src/shell/TenantSwitcher.tsx"],"names":["jsxs","jsx","Bell","Link","useArqelTranslations","router"],"mappings":"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","file":"shell.js","sourcesContent":["/**\n * `<NotificationList>` — renders the `recent` notifications inside the\n * `<NotificationBell>` dropdown content.\n *\n * Extracted from `NotificationBell` so it can be exercised directly in\n * tests without depending on Radix `DropdownMenu` mounting its portal\n * content in jsdom.\n */\n\nimport type { NotificationItem } from '@arqel-dev/types/inertia';\nimport { Link } from '@inertiajs/react';\nimport { AlertTriangle, Bell, Check, Info, type LucideIcon, Mail, User } from 'lucide-react';\nimport type { JSX } from 'react';\nimport { cn } from '../utils/cn.js';\nimport { isSameOriginRelativeUrl } from '../utils/url.js';\n\nexport interface NotificationListProps {\n items: ReadonlyArray<NotificationItem>;\n emptyLabel: string;\n onItemClick: (item: NotificationItem) => void;\n}\n\n/**\n * Allowlist of `data.icon` values accepted from notification payloads.\n *\n * Only these lucide-react icons may be rendered — no dynamic/arbitrary\n * lookup into the lucide namespace, to keep the bundle small and avoid\n * exposing an unbounded icon surface to server-controlled data.\n *\n * Supported keys: `bell` (default), `check`, `info`, `alert`, `mail`, `user`.\n */\nconst NOTIFICATION_ICONS: Record<string, LucideIcon> = {\n bell: Bell,\n check: Check,\n info: Info,\n alert: AlertTriangle,\n mail: Mail,\n user: User,\n};\n\nfunction readTitle(item: NotificationItem): string {\n const title = item.data['title'];\n if (typeof title === 'string' && title.trim()) return title;\n return item.type;\n}\n\nfunction readBody(item: NotificationItem): string | undefined {\n const body = item.data['body'] ?? item.data['message'];\n return typeof body === 'string' && body.trim() ? body : undefined;\n}\n\n/**\n * Only same-origin relative URLs (`/foo`, never `//evil.com`,\n * `https://…`, or `javascript:…`) unlock a navigable `Link` — mirrors\n * the `data.icon` allowlist below: server-controlled notification\n * payloads get a narrow, safe subset of behavior, never arbitrary\n * navigation. Anything else renders the item as a non-navigable button.\n */\nfunction readActionUrl(item: NotificationItem): string | undefined {\n const url = item.data['action_url'];\n return typeof url === 'string' && isSameOriginRelativeUrl(url) ? url : undefined;\n}\n\nfunction readIcon(item: NotificationItem): LucideIcon {\n const icon = item.data['icon'];\n if (typeof icon === 'string' && icon in NOTIFICATION_ICONS) {\n return NOTIFICATION_ICONS[icon] ?? Bell;\n }\n return Bell;\n}\n\nexport function NotificationList({\n items,\n emptyLabel,\n onItemClick,\n}: NotificationListProps): JSX.Element {\n if (items.length === 0) {\n return <div className=\"px-2 py-4 text-center text-sm text-muted-foreground\">{emptyLabel}</div>;\n }\n\n return (\n <div className=\"flex max-h-80 flex-col gap-0.5 overflow-y-auto\">\n {items.map((item) => {\n const title = readTitle(item);\n const body = readBody(item);\n const actionUrl = readActionUrl(item);\n const unread = item.read_at === null;\n const Icon = readIcon(item);\n\n const itemContent = (\n <>\n <span\n aria-hidden=\"true\"\n className={cn(\n 'mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full',\n unread ? 'bg-primary' : 'bg-transparent',\n )}\n />\n <Icon aria-hidden=\"true\" className=\"mt-0.5 h-4 w-4 shrink-0 text-muted-foreground\" />\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate font-medium\">{title}</span>\n {body && <span className=\"truncate text-xs text-muted-foreground\">{body}</span>}\n </span>\n </>\n );\n const itemClassName = cn(\n 'flex w-full items-start gap-2 rounded-sm px-2 py-2 text-left text-sm hover:bg-accent hover:text-accent-foreground',\n unread && 'bg-accent/50',\n );\n\n // The item's root must be either a `Link` (navigable) or a\n // `button` (action-only) — never one nested inside the other,\n // which produces invalid `<a>`-inside-`<button>` HTML.\n return actionUrl ? (\n <Link\n key={item.id}\n href={actionUrl}\n onClick={() => onItemClick(item)}\n className={itemClassName}\n >\n {itemContent}\n </Link>\n ) : (\n <button\n key={item.id}\n type=\"button\"\n onClick={() => onItemClick(item)}\n className={itemClassName}\n >\n {itemContent}\n </button>\n );\n })}\n </div>\n );\n}\n","/**\n * `<NotificationBell>` — database-notifications trigger for the Topbar\n * `notifications` slot.\n *\n * Reads the shared `notifications` prop (`NotificationPayload | null`,\n * see `HandleArqelInertiaRequests`) via `usePage()`. Mounts a bell icon\n * with an unread-count `Badge` (shown only when `unread_count > 0`) and\n * a `DropdownMenu` listing the `recent` notifications. Marking a single\n * notification read, or all of them, does a scoped Inertia partial\n * reload (`only: ['notifications']`) — no full page reload.\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { NotificationItem, NotificationPayload } from '@arqel-dev/types/inertia';\nimport { Link, router, usePage } from '@inertiajs/react';\nimport { Bell } from 'lucide-react';\nimport type { JSX } from 'react';\nimport { Badge } from '../shadcn/ui/badge.js';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../shadcn/ui/dropdown-menu.js';\nimport { cn } from '../utils/cn.js';\nimport { NotificationList } from './NotificationList.js';\n\nexport interface NotificationBellProps {\n className?: string;\n}\n\ninterface NotificationBellPageProps {\n notifications: NotificationPayload | null;\n [key: string]: unknown;\n}\n\nfunction markRead(id: string): void {\n router.post(\n `/admin/notifications/${id}/read`,\n {},\n { preserveScroll: true, only: ['notifications'] },\n );\n}\n\nfunction markAllRead(): void {\n router.post(\n '/admin/notifications/read-all',\n {},\n { preserveScroll: true, only: ['notifications'] },\n );\n}\n\nexport function NotificationBell({ className }: NotificationBellProps): JSX.Element {\n const t = useArqelTranslations();\n const { notifications } = usePage<NotificationBellPageProps>().props;\n\n const unreadCount = notifications?.unread_count ?? 0;\n const recent = notifications?.recent ?? [];\n\n const handleItemClick = (item: NotificationItem): void => {\n if (item.read_at === null) markRead(item.id);\n };\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger\n aria-label={t('arqel.notifications.title', 'Notifications')}\n className={cn(\n 'relative inline-flex h-9 w-9 items-center justify-center rounded-md hover:bg-muted focus:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n className,\n )}\n >\n <Bell aria-hidden=\"true\" className=\"h-4 w-4 text-muted-foreground\" />\n {unreadCount > 0 && (\n <Badge\n variant=\"destructive\"\n className=\"absolute -right-1 -top-1 h-4 min-w-4 justify-center px-1 text-[10px] leading-none\"\n >\n {unreadCount}\n </Badge>\n )}\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-80\">\n <div className=\"flex items-center justify-between px-2 py-1.5\">\n <DropdownMenuLabel className=\"p-0 font-medium\">\n {t('arqel.notifications.title', 'Notifications')}\n </DropdownMenuLabel>\n {unreadCount > 0 && (\n <DropdownMenuItem\n className=\"w-auto justify-end p-0 text-xs text-muted-foreground hover:text-foreground\"\n onSelect={(event) => {\n event.preventDefault();\n markAllRead();\n }}\n >\n {t('arqel.notifications.mark_all_read', 'Mark all as read')}\n </DropdownMenuItem>\n )}\n </div>\n\n <DropdownMenuSeparator />\n\n <NotificationList\n items={recent}\n emptyLabel={t('arqel.notifications.empty', 'No notifications')}\n onItemClick={handleItemClick}\n />\n\n <DropdownMenuSeparator />\n\n <DropdownMenuItem asChild className=\"justify-center text-sm\">\n <Link href=\"/admin/notifications\">{t('arqel.notifications.view_all', 'View all')}</Link>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n","/**\n * `<TenantSwitcher>` — dropdown that lists tenants the user can\n * access and dispatches `POST /admin/tenants/{id}/switch` via\n * Inertia router. Renders nothing when there is no current tenant\n * or the user only has access to one tenant.\n *\n * Mounts in the `tenantSwitcher` slot of `<Topbar>`. The current\n * tenant is read from `props.tenant.current` shared by the\n * server-side `HandleArqelInertiaRequests`; available tenants\n * come from the same payload.\n */\n\nimport { useArqelTranslations } from '@arqel-dev/react/utils';\nimport type { TenantSummary } from '@arqel-dev/types/tenant';\nimport { router } from '@inertiajs/react';\nimport type { JSX } from 'react';\nimport { Button } from '../action/Button.js';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '../shadcn/ui/dropdown-menu.js';\n\nexport interface TenantSwitcherProps {\n current: TenantSummary | null;\n available: ReadonlyArray<TenantSummary>;\n /**\n * Path template for switching; defaults to\n * `/admin/tenants/{id}/switch`.\n */\n switchUrl?: (tenantId: string | number) => string;\n}\n\nconst DEFAULT_SWITCH_URL = (id: string | number): string => `/admin/tenants/${id}/switch`;\n\nexport function TenantSwitcher({\n current,\n available,\n switchUrl,\n}: TenantSwitcherProps): JSX.Element | null {\n const t = useArqelTranslations();\n if (!current || available.length <= 1) return null;\n\n const buildUrl = switchUrl ?? DEFAULT_SWITCH_URL;\n const labelFor = (tenant: TenantSummary): string =>\n tenant.name?.trim()\n ? tenant.name\n : t('arqel.tenant.unnamed', `Tenant ${tenant.id}`, { id: tenant.id });\n const currentLabel = labelFor(current);\n\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n data-testid=\"tenant-switcher-trigger\"\n aria-label={t('arqel.aria.tenant_switch', `Switch tenant (current: ${currentLabel})`, {\n tenant: currentLabel,\n })}\n >\n {currentLabel}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {available.map((tenant) => {\n const isCurrent = tenant.id === current.id;\n return (\n <DropdownMenuItem\n key={String(tenant.id)}\n data-testid={`tenant-switcher-option-${String(tenant.id)}`}\n disabled={isCurrent}\n onSelect={() => {\n router.post(buildUrl(tenant.id), {}, { preserveScroll: true });\n }}\n >\n {labelFor(tenant)}\n {isCurrent ? ' ✓' : ''}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n"]}
package/dist/table.js CHANGED
@@ -1,7 +1,8 @@
1
- export { TableFilters, TablePagination, TableToolbar } from './chunk-YEPQWAD6.js';
1
+ export { TableFilters, TablePagination, TableToolbar } from './chunk-TBDWW6L5.js';
2
2
  export { DataTable, TableCell } from './chunk-JKD6SE75.js';
3
3
  import './chunk-RMPOR2YZ.js';
4
- import './chunk-H23VX3RR.js';
4
+ import './chunk-CZUV5WCY.js';
5
+ import './chunk-YF2RINPG.js';
5
6
  import './chunk-B7ULUJVO.js';
6
7
  //# sourceMappingURL=table.js.map
7
8
  //# sourceMappingURL=table.js.map
package/dist/utility.js CHANGED
@@ -1,5 +1,5 @@
1
- export { Breadcrumbs, EmptyState, LoadingSkeleton } from './chunk-3E66JNQO.js';
2
- export { ErrorState } from './chunk-53J74IYR.js';
1
+ export { Breadcrumbs, EmptyState } from './chunk-VO5KYIHC.js';
2
+ export { ErrorState, LoadingSkeleton } from './chunk-ZZKWQO3W.js';
3
3
  export { PageHeader } from './chunk-MXUXMHOK.js';
4
4
  import './chunk-B7ULUJVO.js';
5
5
  //# sourceMappingURL=utility.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arqel-dev/ui",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "description": "Structural React components (AppShell, DataTable, FormRenderer, etc.) for Arqel admin panels.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://arqel.dev",
@@ -92,7 +92,7 @@
92
92
  "clsx": "^2.1.1",
93
93
  "radix-ui": "^1.4.3",
94
94
  "tailwind-merge": "^2.5.5",
95
- "@arqel-dev/types": "0.18.0"
95
+ "@arqel-dev/types": "0.19.0"
96
96
  },
97
97
  "peerDependencies": {
98
98
  "@inertiajs/react": "^3.0.0",
@@ -102,8 +102,8 @@
102
102
  "react-dom": "^19.2.0",
103
103
  "recharts": "^2.15.0",
104
104
  "tailwindcss": "^4.0.0",
105
- "@arqel-dev/hooks": "0.18.0",
106
- "@arqel-dev/react": "0.18.0"
105
+ "@arqel-dev/hooks": "0.19.0",
106
+ "@arqel-dev/react": "0.19.0"
107
107
  },
108
108
  "devDependencies": {
109
109
  "@base-ui-components/react": "^1.0.0-alpha.0",
@@ -125,8 +125,8 @@
125
125
  "tsup": "^8.5.0",
126
126
  "typescript": "^5.6.3",
127
127
  "vitest": "^4.1.0",
128
- "@arqel-dev/hooks": "0.18.0",
129
- "@arqel-dev/react": "0.18.0"
128
+ "@arqel-dev/hooks": "0.19.0",
129
+ "@arqel-dev/react": "0.19.0"
130
130
  },
131
131
  "publishConfig": {
132
132
  "access": "public"