@rqdhw3n/react-admin-layout 1.0.0 → 1.0.2
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/README.md +283 -5
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +327 -0
- package/dist/index.d.ts +71 -2
- package/dist/index.js +677 -475
- package/dist/index.js.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +35 -8
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/utils/storage.ts","../src/context/LayoutContext.tsx","../src/hooks/useSidebar.ts","../src/utils/breadcrumbs.ts","../node_modules/clsx/dist/clsx.mjs","../src/utils/cn.ts","../src/components/AdminLayoutRouterSync.tsx","../src/components/Footer.tsx","../src/utils/permissions.ts","../src/components/SidebarGroup.tsx","../src/components/SidebarItem.tsx","../src/components/MobileSidebar.tsx","../src/components/Breadcrumbs.tsx","../src/components/NavbarSearch.tsx","../src/components/NotificationMenu.tsx","../src/hooks/useDarkMode.ts","../src/components/ThemeToggle.tsx","../src/components/UserMenu.tsx","../src/components/Navbar.tsx","../src/components/Sidebar.tsx","../src/components/AdminLayout.tsx","../src/components/RouterLink.tsx","../src/hooks/useLayoutState.ts","../src/hooks/useBreadcrumbs.ts"],"sourcesContent":["import type { LayoutState } from '../types'\r\n\r\nexport type PersistedLayout = Pick<LayoutState, 'sidebarCollapsed' | 'darkMode'>\r\n\r\nexport function loadLayoutState(key: string): Partial<PersistedLayout> {\r\n if (typeof window === 'undefined') return {}\r\n try {\r\n const raw = localStorage.getItem(key)\r\n return raw ? (JSON.parse(raw) as Partial<PersistedLayout>) : {}\r\n } catch {\r\n return {}\r\n }\r\n}\r\n\r\nexport function saveLayoutState(key: string, state: PersistedLayout): void {\r\n if (typeof window === 'undefined') return\r\n try {\r\n localStorage.setItem(key, JSON.stringify(state))\r\n } catch {\r\n /* ignore quota errors */\r\n }\r\n}\r\n","import {\r\n createContext,\r\n useCallback,\r\n useContext,\r\n useEffect,\r\n useMemo,\r\n useState,\r\n type ReactNode,\r\n} from 'react'\r\nimport type { BreadcrumbItem, LayoutContextValue, PermissionsMap } from '../types'\r\nimport { loadLayoutState, saveLayoutState } from '../utils/storage'\r\n\r\nconst LayoutContext = createContext<LayoutContextValue | null>(null)\r\n\r\nexport type LayoutProviderProps = {\r\n children: ReactNode\r\n storageKey?: string\r\n defaultCollapsed?: boolean\r\n permissions?: PermissionsMap\r\n initialBreadcrumbs?: BreadcrumbItem[]\r\n initialActivePath?: string\r\n initialDarkMode?: boolean\r\n}\r\n\r\nexport function LayoutProvider({\r\n children,\r\n storageKey = 'rqdhw3n-admin-layout',\r\n defaultCollapsed = false,\r\n permissions = {},\r\n initialBreadcrumbs = [],\r\n initialActivePath = '/',\r\n initialDarkMode,\r\n}: LayoutProviderProps) {\r\n const persisted = loadLayoutState(storageKey)\r\n\r\n const [sidebarCollapsed, setSidebarCollapsed] = useState(\r\n persisted.sidebarCollapsed ?? defaultCollapsed,\r\n )\r\n const [mobileOpen, setMobileOpen] = useState(false)\r\n const [darkMode, setDarkMode] = useState(\r\n persisted.darkMode ?? initialDarkMode ?? false,\r\n )\r\n const [breadcrumbs, setBreadcrumbs] = useState<BreadcrumbItem[]>(initialBreadcrumbs)\r\n const [activePath, setActivePath] = useState(initialActivePath)\r\n\r\n useEffect(() => {\r\n saveLayoutState(storageKey, { sidebarCollapsed, darkMode })\r\n }, [storageKey, sidebarCollapsed, darkMode])\r\n\r\n useEffect(() => {\r\n const root = document.documentElement\r\n if (darkMode) root.classList.add('dark')\r\n else root.classList.remove('dark')\r\n }, [darkMode])\r\n\r\n const toggleSidebar = useCallback(() => setSidebarCollapsed((v) => !v), [])\r\n const toggleMobile = useCallback(() => setMobileOpen((v) => !v), [])\r\n const toggleDarkMode = useCallback(() => setDarkMode((v) => !v), [])\r\n\r\n const value = useMemo<LayoutContextValue>(\r\n () => ({\r\n sidebarCollapsed,\r\n mobileOpen,\r\n darkMode,\r\n toggleSidebar,\r\n setSidebarCollapsed,\r\n toggleMobile,\r\n setMobileOpen,\r\n toggleDarkMode,\r\n setDarkMode,\r\n permissions,\r\n breadcrumbs,\r\n setBreadcrumbs,\r\n activePath,\r\n setActivePath,\r\n }),\r\n [\r\n sidebarCollapsed,\r\n mobileOpen,\r\n darkMode,\r\n toggleSidebar,\r\n toggleMobile,\r\n toggleDarkMode,\r\n permissions,\r\n breadcrumbs,\r\n activePath,\r\n ],\r\n )\r\n\r\n return <LayoutContext.Provider value={value}>{children}</LayoutContext.Provider>\r\n}\r\n\r\nexport function useLayoutContext(): LayoutContextValue {\r\n const ctx = useContext(LayoutContext)\r\n if (!ctx) {\r\n throw new Error('useLayoutContext must be used within LayoutProvider / AdminLayout')\r\n }\r\n return ctx\r\n}\r\n","import { useLayoutContext } from '../context/LayoutContext'\r\n\r\nexport function useSidebar() {\r\n const {\r\n sidebarCollapsed,\r\n mobileOpen,\r\n toggleSidebar,\r\n setSidebarCollapsed,\r\n toggleMobile,\r\n setMobileOpen,\r\n } = useLayoutContext()\r\n\r\n return {\r\n collapsed: sidebarCollapsed,\r\n mobileOpen,\r\n toggle: toggleSidebar,\r\n setCollapsed: setSidebarCollapsed,\r\n toggleMobile,\r\n setMobileOpen,\r\n closeMobile: () => setMobileOpen(false),\r\n }\r\n}\r\n","import type { BreadcrumbItem } from '../types'\r\n\r\nexport function generateBreadcrumbsFromPath(pathname: string): BreadcrumbItem[] {\r\n const segments = pathname.split('/').filter(Boolean)\r\n if (!segments.length) return [{ label: 'Home', path: '/' }]\r\n\r\n return segments.map((seg, i) => {\r\n const path = '/' + segments.slice(0, i + 1).join('/')\r\n const label = seg\r\n .replace(/-/g, ' ')\r\n .replace(/\\b\\w/g, (c) => c.toUpperCase())\r\n return { label, path: i < segments.length - 1 ? path : undefined }\r\n })\r\n}\r\n","function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","import clsx, { type ClassValue } from 'clsx'\r\n\r\nexport function cn(...inputs: ClassValue[]): string {\r\n return clsx(inputs)\r\n}\r\n","import { useEffect, type ReactNode } from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\nimport { useLayoutContext } from '../context/LayoutContext'\r\nimport { generateBreadcrumbsFromPath } from '../utils/breadcrumbs'\r\n\r\nexport type AdminLayoutRouterSyncProps = {\r\n children: ReactNode\r\n}\r\n\r\nexport function AdminLayoutRouterSync({ children }: AdminLayoutRouterSyncProps) {\r\n const { pathname } = useLocation()\r\n const { setActivePath, setBreadcrumbs, breadcrumbs: manualBreadcrumbs } = useLayoutContext()\r\n\r\n useEffect(() => {\r\n setActivePath(pathname)\r\n if (!manualBreadcrumbs.length) {\r\n setBreadcrumbs(generateBreadcrumbsFromPath(pathname))\r\n }\r\n }, [pathname, setActivePath, setBreadcrumbs, manualBreadcrumbs.length])\r\n\r\n return <>{children}</>\r\n}\r\n","import { cn } from '../utils/cn'\r\n\r\nexport type FooterProps = {\r\n children?: React.ReactNode\r\n className?: string\r\n}\r\n\r\nexport function Footer({ children, className }: FooterProps) {\r\n return (\r\n <footer\r\n className={cn(\r\n 'mt-auto border-t border-admin-border bg-admin-surface px-6 py-4 text-sm text-admin-muted',\r\n className,\r\n )}\r\n >\r\n {children ?? (\r\n <p className='text-center'>\r\n © {new Date().getFullYear()} Admin Layout · Built with @rqdhw3n/react-admin-layout\r\n </p>\r\n )}\r\n </footer>\r\n )\r\n}\r\n","import type { PermissionsMap, SidebarItemType } from '../types'\r\n\r\nexport function parsePermission(permission: string): { resource: string; action: string } {\r\n const dot = permission.indexOf('.')\r\n if (dot === -1) return { resource: permission, action: 'view' }\r\n return {\r\n resource: permission.slice(0, dot),\r\n action: permission.slice(dot + 1),\r\n }\r\n}\r\n\r\nexport function hasPermission(\r\n permissions: PermissionsMap,\r\n permission?: string,\r\n): boolean {\r\n if (!permission) return true\r\n const { resource, action } = parsePermission(permission)\r\n const allowed = permissions[resource]\r\n if (!allowed?.length) return false\r\n return allowed.includes(action) || allowed.includes('*')\r\n}\r\n\r\nexport function filterSidebarByPermissions(\r\n items: SidebarItemType[],\r\n permissions: PermissionsMap,\r\n): SidebarItemType[] {\r\n return items\r\n .filter((item) => hasPermission(permissions, item.permission))\r\n .map((item) => ({\r\n ...item,\r\n children: item.children\r\n ? filterSidebarByPermissions(item.children, permissions)\r\n : undefined,\r\n }))\r\n .filter((item) => !item.children?.length || item.children.length > 0 || item.path)\r\n}\r\n","import type { ReactNode } from 'react'\r\nimport { cn } from '../utils/cn'\r\n\r\nexport type SidebarGroupProps = {\r\n label?: string\r\n children: ReactNode\r\n collapsed?: boolean\r\n className?: string\r\n}\r\n\r\nexport function SidebarGroup({ label, children, collapsed, className }: SidebarGroupProps) {\r\n return (\r\n <div className={cn('mb-4', className)}>\r\n {label && !collapsed && (\r\n <p className='mb-2 px-3 text-[11px] font-semibold uppercase tracking-wider text-admin-muted'>\r\n {label}\r\n </p>\r\n )}\r\n <ul className='space-y-0.5'>{children}</ul>\r\n </div>\r\n )\r\n}\r\n","import { ChevronDown } from 'lucide-react'\r\nimport { useState } from 'react'\r\nimport type { SidebarItemType } from '../types'\r\nimport { cn } from '../utils/cn'\r\n\r\nexport type SidebarItemProps = {\r\n item: SidebarItemType\r\n collapsed?: boolean\r\n depth?: number\r\n activePath?: string\r\n onNavigate?: (path: string) => void\r\n LinkComponent?: React.ComponentType<{\r\n to: string\r\n className?: string\r\n children: React.ReactNode\r\n onClick?: () => void\r\n }>\r\n onItemClick?: () => void\r\n}\r\n\r\nfunction isActive(path: string | undefined, activePath: string): boolean {\r\n if (!path) return false\r\n return activePath === path || activePath.startsWith(`${path}/`)\r\n}\r\n\r\nexport function SidebarItem({\r\n item,\r\n collapsed = false,\r\n depth = 0,\r\n activePath = '/',\r\n onNavigate,\r\n LinkComponent,\r\n onItemClick,\r\n}: SidebarItemProps) {\r\n const hasChildren = Boolean(item.children?.length)\r\n const active = item.path ? isActive(item.path, activePath) : false\r\n const childActive = item.children?.some((c) => c.path && isActive(c.path, activePath))\r\n const [open, setOpen] = useState(active || childActive)\r\n\r\n const Icon = item.icon\r\n\r\n const baseClass = cn(\r\n 'group flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-all duration-200',\r\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-admin-primary',\r\n active || childActive\r\n ? 'bg-admin-primary text-white shadow-sm'\r\n : 'text-admin-muted hover:bg-admin-bg hover:text-admin-text',\r\n item.disabled && 'pointer-events-none opacity-50',\r\n depth > 0 && 'text-[13px] py-2',\r\n )\r\n\r\n const content = (\r\n <>\r\n {Icon && (\r\n <Icon\r\n className={cn('h-[18px] w-[18px] shrink-0', active || childActive ? 'text-white' : '')}\r\n aria-hidden\r\n />\r\n )}\r\n {!collapsed && (\r\n <>\r\n <span className='flex-1 truncate text-left'>{item.label}</span>\r\n {item.badge != null && (\r\n <span\r\n className={cn(\r\n 'rounded-full px-2 py-0.5 text-[11px] font-semibold',\r\n active ? 'bg-white/20 text-white' : 'bg-admin-primary/10 text-admin-primary',\r\n )}\r\n >\r\n {item.badge}\r\n </span>\r\n )}\r\n {hasChildren && (\r\n <ChevronDown\r\n className={cn('h-4 w-4 shrink-0 transition-transform', open && 'rotate-180')}\r\n aria-hidden\r\n />\r\n )}\r\n </>\r\n )}\r\n </>\r\n )\r\n\r\n const handleClick = () => {\r\n if (hasChildren) {\r\n setOpen((v) => !v)\r\n return\r\n }\r\n if (item.path) {\r\n onNavigate?.(item.path)\r\n onItemClick?.()\r\n }\r\n }\r\n\r\n const row =\r\n item.path && !hasChildren && LinkComponent ? (\r\n <LinkComponent\r\n to={item.path}\r\n className={baseClass}\r\n onClick={() => {\r\n onItemClick?.()\r\n }}\r\n >\r\n {content}\r\n </LinkComponent>\r\n ) : (\r\n <button type='button' className={baseClass} onClick={handleClick} disabled={item.disabled}>\r\n {content}\r\n </button>\r\n )\r\n\r\n return (\r\n <li>\r\n {row}\r\n {hasChildren && open && !collapsed && (\r\n <ul className='mt-1 space-y-0.5 border-l border-admin-border ml-5 pl-2'>\r\n {item.children!.map((child) => (\r\n <SidebarItem\r\n key={child.label + (child.path ?? '')}\r\n item={child}\r\n collapsed={collapsed}\r\n depth={depth + 1}\r\n activePath={activePath}\r\n onNavigate={onNavigate}\r\n LinkComponent={LinkComponent}\r\n onItemClick={onItemClick}\r\n />\r\n ))}\r\n </ul>\r\n )}\r\n </li>\r\n )\r\n}\r\n","import { X } from 'lucide-react'\r\nimport { useEffect } from 'react'\r\nimport { useSidebar } from '../hooks/useSidebar'\r\nimport { useLayoutContext } from '../context/LayoutContext'\r\nimport type { SidebarProps } from '../types'\r\nimport { filterSidebarByPermissions } from '../utils/permissions'\r\nimport { cn } from '../utils/cn'\r\nimport { SidebarGroup } from './SidebarGroup'\r\nimport { SidebarItem } from './SidebarItem'\r\n\r\nexport type MobileSidebarProps = SidebarProps\r\n\r\nexport function MobileSidebar({\r\n items,\r\n appName = 'Admin',\r\n appLogo,\r\n onNavigate,\r\n activePath: activePathProp,\r\n LinkComponent,\r\n}: MobileSidebarProps) {\r\n const { mobileOpen, closeMobile } = useSidebar()\r\n const { permissions, activePath: ctxPath } = useLayoutContext()\r\n const activePath = activePathProp ?? ctxPath\r\n const filtered = filterSidebarByPermissions(items, permissions)\r\n\r\n useEffect(() => {\r\n if (!mobileOpen) return\r\n const onKey = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') closeMobile()\r\n }\r\n document.addEventListener('keydown', onKey)\r\n document.body.style.overflow = 'hidden'\r\n return () => {\r\n document.removeEventListener('keydown', onKey)\r\n document.body.style.overflow = ''\r\n }\r\n }, [mobileOpen, closeMobile])\r\n\r\n if (!mobileOpen) return null\r\n\r\n const handleNavigate = (path: string) => {\r\n onNavigate?.(path)\r\n closeMobile()\r\n }\r\n\r\n return (\r\n <div className='fixed inset-0 z-50 lg:hidden' role='dialog' aria-modal='true'>\r\n <button\r\n type='button'\r\n className='absolute inset-0 bg-slate-900/50 backdrop-blur-sm animate-fade-in'\r\n aria-label='Close menu'\r\n onClick={closeMobile}\r\n />\r\n <aside\r\n className={cn(\r\n 'absolute left-0 top-0 flex h-full w-[min(280px,85vw)] flex-col',\r\n 'border-r border-admin-border bg-admin-surface shadow-admin-lg animate-slide-in',\r\n )}\r\n >\r\n <div className='flex h-16 items-center justify-between border-b border-admin-border px-4'>\r\n <div className='flex items-center gap-3'>\r\n {appLogo ?? (\r\n <div className='flex h-9 w-9 items-center justify-center rounded-xl bg-admin-primary text-sm font-bold text-white'>\r\n {appName.charAt(0)}\r\n </div>\r\n )}\r\n <span className='font-semibold text-admin-text'>{appName}</span>\r\n </div>\r\n <button\r\n type='button'\r\n onClick={closeMobile}\r\n className='rounded-lg p-2 text-admin-muted hover:bg-admin-bg'\r\n aria-label='Close sidebar'\r\n >\r\n <X className='h-5 w-5' />\r\n </button>\r\n </div>\r\n <nav className='flex-1 overflow-y-auto p-3'>\r\n <SidebarGroup>\r\n {filtered.map((item) => (\r\n <SidebarItem\r\n key={item.label + (item.path ?? '')}\r\n item={item}\r\n activePath={activePath}\r\n onNavigate={handleNavigate}\r\n LinkComponent={LinkComponent}\r\n onItemClick={closeMobile}\r\n />\r\n ))}\r\n </SidebarGroup>\r\n </nav>\r\n </aside>\r\n </div>\r\n )\r\n}\r\n","import { ChevronRight, Home } from 'lucide-react'\r\nimport type { BreadcrumbItem } from '../types'\r\nimport { cn } from '../utils/cn'\r\n\r\nexport type BreadcrumbsProps = {\r\n items: BreadcrumbItem[]\r\n className?: string\r\n LinkComponent?: React.ComponentType<{\r\n to: string\r\n className?: string\r\n children: React.ReactNode\r\n }>\r\n onNavigate?: (path: string) => void\r\n}\r\n\r\nexport function Breadcrumbs({\r\n items,\r\n className,\r\n LinkComponent,\r\n onNavigate,\r\n}: BreadcrumbsProps) {\r\n if (!items.length) return null\r\n\r\n const renderLink = (item: BreadcrumbItem, isLast: boolean) => {\r\n const classNames = cn(\r\n 'text-sm transition-colors',\r\n isLast ? 'font-medium text-admin-text' : 'text-admin-muted hover:text-admin-text',\r\n )\r\n\r\n if (!item.path || isLast) {\r\n return <span className={classNames}>{item.label}</span>\r\n }\r\n\r\n if (LinkComponent) {\r\n return (\r\n <LinkComponent to={item.path} className={classNames}>\r\n {item.label}\r\n </LinkComponent>\r\n )\r\n }\r\n\r\n return (\r\n <button type='button' className={classNames} onClick={() => onNavigate?.(item.path!)}>\r\n {item.label}\r\n </button>\r\n )\r\n }\r\n\r\n return (\r\n <nav aria-label='Breadcrumb' className={cn('flex items-center gap-1.5', className)}>\r\n <Home className='h-4 w-4 text-admin-muted shrink-0' aria-hidden />\r\n {items.map((item, index) => {\r\n const isLast = index === items.length - 1\r\n return (\r\n <span key={`${item.label}-${index}`} className='flex items-center gap-1.5'>\r\n <ChevronRight className='h-3.5 w-3.5 text-admin-muted' aria-hidden />\r\n {renderLink(item, isLast)}\r\n </span>\r\n )\r\n })}\r\n </nav>\r\n )\r\n}\r\n","import { Search } from 'lucide-react'\r\nimport { useState, type FormEvent } from 'react'\r\nimport { cn } from '../utils/cn'\r\n\r\nexport type NavbarSearchProps = {\r\n placeholder?: string\r\n onSearch?: (query: string) => void\r\n className?: string\r\n}\r\n\r\nexport function NavbarSearch({\r\n placeholder = 'Search...',\r\n onSearch,\r\n className,\r\n}: NavbarSearchProps) {\r\n const [query, setQuery] = useState('')\r\n\r\n const handleSubmit = (e: FormEvent) => {\r\n e.preventDefault()\r\n onSearch?.(query.trim())\r\n }\r\n\r\n return (\r\n <form onSubmit={handleSubmit} className={cn('relative w-full max-w-md', className)}>\r\n <Search\r\n className='pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-admin-muted'\r\n aria-hidden\r\n />\r\n <input\r\n type='search'\r\n value={query}\r\n onChange={(e) => setQuery(e.target.value)}\r\n placeholder={placeholder}\r\n className={cn(\r\n 'h-10 w-full rounded-xl border border-admin-border bg-admin-bg pl-10 pr-4 text-sm text-admin-text',\r\n 'placeholder:text-admin-muted focus:border-admin-primary focus:outline-none focus:ring-2 focus:ring-admin-primary/20',\r\n )}\r\n aria-label='Search'\r\n />\r\n </form>\r\n )\r\n}\r\n","import { Bell } from 'lucide-react'\r\nimport { useEffect, useRef, useState } from 'react'\r\nimport type { NotificationItem } from '../types'\r\nimport { cn } from '../utils/cn'\r\n\r\nexport type NotificationMenuProps = {\r\n notifications?: NotificationItem[]\r\n className?: string\r\n}\r\n\r\nexport function NotificationMenu({ notifications = [], className }: NotificationMenuProps) {\r\n const [open, setOpen] = useState(false)\r\n const ref = useRef<HTMLDivElement>(null)\r\n const unread = notifications.filter((n) => !n.read).length\r\n\r\n useEffect(() => {\r\n const handler = (e: MouseEvent) => {\r\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)\r\n }\r\n document.addEventListener('mousedown', handler)\r\n return () => document.removeEventListener('mousedown', handler)\r\n }, [])\r\n\r\n return (\r\n <div ref={ref} className={cn('relative', className)}>\r\n <button\r\n type='button'\r\n onClick={() => setOpen((v) => !v)}\r\n className={cn(\r\n 'relative inline-flex h-9 w-9 items-center justify-center rounded-lg border border-admin-border',\r\n 'bg-admin-surface text-admin-muted transition-colors hover:bg-admin-bg hover:text-admin-text',\r\n 'focus-visible:ring-2 focus-visible:ring-admin-primary',\r\n )}\r\n aria-label={`Notifications${unread ? `, ${unread} unread` : ''}`}\r\n aria-expanded={open}\r\n >\r\n <Bell className='h-4 w-4' aria-hidden />\r\n {unread > 0 && (\r\n <span className='absolute -right-0.5 -top-0.5 flex h-4 min-w-4 items-center justify-center rounded-full bg-red-500 px-1 text-[10px] font-bold text-white'>\r\n {unread > 9 ? '9+' : unread}\r\n </span>\r\n )}\r\n </button>\r\n\r\n {open && (\r\n <div className='absolute right-0 top-full z-50 mt-2 w-80 rounded-xl border border-admin-border bg-admin-surface shadow-admin-lg animate-fade-in'>\r\n <div className='border-b border-admin-border px-4 py-3'>\r\n <p className='text-sm font-semibold text-admin-text'>Notifications</p>\r\n </div>\r\n <ul className='max-h-72 overflow-y-auto p-2'>\r\n {notifications.length === 0 ? (\r\n <li className='px-3 py-6 text-center text-sm text-admin-muted'>No notifications</li>\r\n ) : (\r\n notifications.map((n) => (\r\n <li\r\n key={n.id}\r\n className={cn(\r\n 'rounded-lg px-3 py-2.5 transition-colors hover:bg-admin-bg',\r\n !n.read && 'bg-admin-primary/5',\r\n )}\r\n >\r\n <p className='text-sm font-medium text-admin-text'>{n.title}</p>\r\n {n.description && (\r\n <p className='mt-0.5 text-xs text-admin-muted line-clamp-2'>{n.description}</p>\r\n )}\r\n {n.time && <p className='mt-1 text-[11px] text-admin-muted'>{n.time}</p>}\r\n </li>\r\n ))\r\n )}\r\n </ul>\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n","import { useLayoutContext } from '../context/LayoutContext'\r\n\r\nexport function useDarkMode() {\r\n const { darkMode, toggleDarkMode, setDarkMode } = useLayoutContext()\r\n return {\r\n isDark: darkMode,\r\n toggle: toggleDarkMode,\r\n setDarkMode,\r\n }\r\n}\r\n","import { Moon, Sun } from 'lucide-react'\r\nimport { useDarkMode } from '../hooks/useDarkMode'\r\nimport { cn } from '../utils/cn'\r\n\r\nexport type ThemeToggleProps = {\r\n className?: string\r\n}\r\n\r\nexport function ThemeToggle({ className }: ThemeToggleProps) {\r\n const { isDark, toggle } = useDarkMode()\r\n\r\n return (\r\n <button\r\n type='button'\r\n onClick={toggle}\r\n className={cn(\r\n 'inline-flex h-9 w-9 items-center justify-center rounded-lg border border-admin-border',\r\n 'bg-admin-surface text-admin-muted transition-colors hover:bg-admin-bg hover:text-admin-text',\r\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-admin-primary focus-visible:ring-offset-2',\r\n className,\r\n )}\r\n aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}\r\n >\r\n {isDark ? <Sun className='h-4 w-4' aria-hidden /> : <Moon className='h-4 w-4' aria-hidden />}\r\n </button>\r\n )\r\n}\r\n","import { ChevronDown, LogOut, Settings, User } from 'lucide-react'\r\nimport { useEffect, useRef, useState } from 'react'\r\nimport type { AdminUser } from '../types'\r\nimport { cn } from '../utils/cn'\r\n\r\nexport type UserMenuProps = {\r\n user: AdminUser\r\n onLogout?: () => void\r\n onSettings?: () => void\r\n className?: string\r\n}\r\n\r\nexport function UserMenu({ user, onLogout, onSettings, className }: UserMenuProps) {\r\n const [open, setOpen] = useState(false)\r\n const ref = useRef<HTMLDivElement>(null)\r\n\r\n useEffect(() => {\r\n const handler = (e: MouseEvent) => {\r\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)\r\n }\r\n document.addEventListener('mousedown', handler)\r\n return () => document.removeEventListener('mousedown', handler)\r\n }, [])\r\n\r\n const initials = user.name\r\n .split(' ')\r\n .map((n) => n[0])\r\n .join('')\r\n .slice(0, 2)\r\n .toUpperCase()\r\n\r\n return (\r\n <div ref={ref} className={cn('relative', className)}>\r\n <button\r\n type='button'\r\n onClick={() => setOpen((v) => !v)}\r\n className={cn(\r\n 'flex items-center gap-2 rounded-xl border border-admin-border bg-admin-surface px-2 py-1.5',\r\n 'transition-colors hover:bg-admin-bg focus-visible:ring-2 focus-visible:ring-admin-primary',\r\n )}\r\n aria-expanded={open}\r\n aria-haspopup='menu'\r\n >\r\n {user.avatar ? (\r\n <img src={user.avatar} alt='' className='h-8 w-8 rounded-lg object-cover' />\r\n ) : (\r\n <div className='flex h-8 w-8 items-center justify-center rounded-lg bg-admin-primary text-xs font-semibold text-white'>\r\n {initials}\r\n </div>\r\n )}\r\n <div className='hidden text-left sm:block'>\r\n <p className='text-sm font-medium text-admin-text leading-tight'>{user.name}</p>\r\n <p className='text-xs text-admin-muted leading-tight'>{user.email}</p>\r\n </div>\r\n <ChevronDown className='hidden h-4 w-4 text-admin-muted sm:block' aria-hidden />\r\n </button>\r\n\r\n {open && (\r\n <div\r\n role='menu'\r\n className='absolute right-0 top-full z-50 mt-2 w-56 rounded-xl border border-admin-border bg-admin-surface p-1.5 shadow-admin-lg animate-fade-in'\r\n >\r\n <button\r\n type='button'\r\n role='menuitem'\r\n className='flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-admin-text hover:bg-admin-bg'\r\n onClick={() => {\r\n onSettings?.()\r\n setOpen(false)\r\n }}\r\n >\r\n <Settings className='h-4 w-4 text-admin-muted' />\r\n Settings\r\n </button>\r\n <button\r\n type='button'\r\n role='menuitem'\r\n className='flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-admin-text hover:bg-admin-bg'\r\n >\r\n <User className='h-4 w-4 text-admin-muted' />\r\n Profile\r\n </button>\r\n <hr className='my-1 border-admin-border' />\r\n <button\r\n type='button'\r\n role='menuitem'\r\n className='flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-red-600 hover:bg-red-50 dark:hover:bg-red-950/30'\r\n onClick={() => {\r\n onLogout?.()\r\n setOpen(false)\r\n }}\r\n >\r\n <LogOut className='h-4 w-4' />\r\n Log out\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n","import { Menu, PanelLeftClose, PanelLeftOpen } from 'lucide-react'\r\nimport type { NavbarProps } from '../types'\r\nimport { cn } from '../utils/cn'\r\nimport { Breadcrumbs } from './Breadcrumbs'\r\nimport { NavbarSearch } from './NavbarSearch'\r\nimport { NotificationMenu } from './NotificationMenu'\r\nimport { ThemeToggle } from './ThemeToggle'\r\nimport { UserMenu } from './UserMenu'\r\n\r\nexport function Navbar({\r\n user,\r\n notifications = [],\r\n onSearch,\r\n searchPlaceholder = 'Search...',\r\n showSearch = true,\r\n className,\r\n breadcrumbs = [],\r\n onMenuClick,\r\n sidebarCollapsed,\r\n onToggleSidebar,\r\n}: NavbarProps) {\r\n return (\r\n <header\r\n className={cn(\r\n 'sticky top-0 z-40 flex h-16 shrink-0 items-center gap-4 border-b border-admin-border',\r\n 'admin-glass bg-admin-surface px-4 lg:px-6',\r\n className,\r\n )}\r\n >\r\n <button\r\n type='button'\r\n className='rounded-lg p-2 text-admin-muted hover:bg-admin-bg lg:hidden'\r\n onClick={onMenuClick}\r\n aria-label='Open menu'\r\n >\r\n <Menu className='h-5 w-5' />\r\n </button>\r\n\r\n <button\r\n type='button'\r\n className='hidden rounded-lg p-2 text-admin-muted hover:bg-admin-bg lg:inline-flex'\r\n onClick={onToggleSidebar}\r\n aria-label={sidebarCollapsed ? 'Expand sidebar' : 'Collapse sidebar'}\r\n >\r\n {sidebarCollapsed ? (\r\n <PanelLeftOpen className='h-5 w-5' />\r\n ) : (\r\n <PanelLeftClose className='h-5 w-5' />\r\n )}\r\n </button>\r\n\r\n <div className='hidden min-w-0 flex-1 md:block'>\r\n <Breadcrumbs items={breadcrumbs} />\r\n </div>\r\n\r\n <div className='flex flex-1 items-center justify-end gap-2 sm:gap-3'>\r\n {showSearch && (\r\n <div className='hidden flex-1 sm:flex sm:max-w-md'>\r\n <NavbarSearch placeholder={searchPlaceholder} onSearch={onSearch} />\r\n </div>\r\n )}\r\n <ThemeToggle />\r\n <NotificationMenu notifications={notifications} />\r\n {user && <UserMenu user={user} />}\r\n </div>\r\n </header>\r\n )\r\n}\r\n","import { PanelLeftClose, PanelLeftOpen } from 'lucide-react'\r\nimport { useSidebar } from '../hooks/useSidebar'\r\nimport { useLayoutContext } from '../context/LayoutContext'\r\nimport type { SidebarProps } from '../types'\r\nimport { filterSidebarByPermissions } from '../utils/permissions'\r\nimport { cn } from '../utils/cn'\r\nimport { SidebarGroup } from './SidebarGroup'\r\nimport { SidebarItem } from './SidebarItem'\r\n\r\nexport function Sidebar({\r\n items,\r\n collapsed: collapsedProp,\r\n appName = 'Admin',\r\n appLogo,\r\n className,\r\n onNavigate,\r\n activePath: activePathProp,\r\n LinkComponent,\r\n}: SidebarProps) {\r\n const { collapsed: ctxCollapsed, toggle, closeMobile } = useSidebar()\r\n const { permissions, activePath: ctxPath } = useLayoutContext()\r\n\r\n const collapsed = collapsedProp ?? ctxCollapsed\r\n const activePath = activePathProp ?? ctxPath\r\n const filtered = filterSidebarByPermissions(items, permissions)\r\n\r\n const handleNavigate = (path: string) => {\r\n onNavigate?.(path)\r\n closeMobile()\r\n }\r\n\r\n return (\r\n <aside\r\n className={cn(\r\n 'hidden lg:flex flex-col border-r border-admin-border bg-admin-surface transition-all duration-300 ease-in-out',\r\n collapsed ? 'w-[var(--admin-sidebar-collapsed)]' : 'w-[var(--admin-sidebar-width)]',\r\n className,\r\n )}\r\n aria-label='Sidebar navigation'\r\n >\r\n <div\r\n className={cn(\r\n 'flex h-16 items-center border-b border-admin-border px-4',\r\n collapsed ? 'justify-center' : 'justify-between gap-2',\r\n )}\r\n >\r\n <div className={cn('flex items-center gap-3 min-w-0', collapsed && 'justify-center')}>\r\n {appLogo ?? (\r\n <div className='flex h-9 w-9 shrink-0 items-center justify-center rounded-xl bg-admin-primary text-sm font-bold text-white shadow-admin'>\r\n {appName.charAt(0)}\r\n </div>\r\n )}\r\n {!collapsed && (\r\n <span className='truncate text-base font-semibold text-admin-text'>{appName}</span>\r\n )}\r\n </div>\r\n {!collapsed && (\r\n <button\r\n type='button'\r\n onClick={toggle}\r\n className='rounded-lg p-2 text-admin-muted hover:bg-admin-bg hover:text-admin-text focus-visible:ring-2 focus-visible:ring-admin-primary'\r\n aria-label='Collapse sidebar'\r\n >\r\n <PanelLeftClose className='h-4 w-4' />\r\n </button>\r\n )}\r\n </div>\r\n\r\n {collapsed && (\r\n <div className='flex justify-center py-2 border-b border-admin-border'>\r\n <button\r\n type='button'\r\n onClick={toggle}\r\n className='rounded-lg p-2 text-admin-muted hover:bg-admin-bg'\r\n aria-label='Expand sidebar'\r\n >\r\n <PanelLeftOpen className='h-4 w-4' />\r\n </button>\r\n </div>\r\n )}\r\n\r\n <nav className='flex-1 overflow-y-auto p-3'>\r\n <SidebarGroup collapsed={collapsed}>\r\n {filtered.map((item) => (\r\n <SidebarItem\r\n key={item.label + (item.path ?? '')}\r\n item={item}\r\n collapsed={collapsed}\r\n activePath={activePath}\r\n onNavigate={handleNavigate}\r\n LinkComponent={LinkComponent}\r\n />\r\n ))}\r\n </SidebarGroup>\r\n </nav>\r\n </aside>\r\n )\r\n}\r\n","import { useMemo } from 'react'\r\nimport { LayoutProvider } from '../context/LayoutContext'\r\nimport { useLayoutContext } from '../context/LayoutContext'\r\nimport { useSidebar } from '../hooks/useSidebar'\r\nimport type { AdminLayoutProps } from '../types'\r\nimport { generateBreadcrumbsFromPath } from '../utils/breadcrumbs'\r\nimport { cn } from '../utils/cn'\r\nimport { AdminLayoutRouterSync } from './AdminLayoutRouterSync'\r\nimport { Footer } from './Footer'\r\nimport { MobileSidebar } from './MobileSidebar'\r\nimport { Navbar } from './Navbar'\r\nimport { Sidebar } from './Sidebar'\r\n\r\nfunction AdminLayoutInner({\r\n children,\r\n sidebarItems,\r\n appName = 'Admin',\r\n appLogo,\r\n user,\r\n notifications = [],\r\n footer,\r\n showFooter = true,\r\n showSearch = true,\r\n searchPlaceholder,\r\n onSearch,\r\n breadcrumbs: breadcrumbsProp,\r\n contentClassName,\r\n activePath: activePathProp,\r\n onNavigate,\r\n LinkComponent,\r\n enableRouter: _enableRouter = false,\r\n}: AdminLayoutProps) {\r\n const {\r\n sidebarCollapsed,\r\n toggleSidebar,\r\n toggleMobile,\r\n breadcrumbs: ctxBreadcrumbs,\r\n setBreadcrumbs,\r\n activePath: ctxPath,\r\n setActivePath,\r\n } = useLayoutContext()\r\n const { closeMobile } = useSidebar()\r\n\r\n const activePath = activePathProp ?? ctxPath\r\n const breadcrumbs = breadcrumbsProp ?? ctxBreadcrumbs\r\n\r\n const handleNavigate = (path: string) => {\r\n setActivePath(path)\r\n if (!breadcrumbsProp) {\r\n setBreadcrumbs(generateBreadcrumbsFromPath(path))\r\n }\r\n onNavigate?.(path)\r\n closeMobile()\r\n }\r\n\r\n const mainOffset = sidebarCollapsed\r\n ? 'lg:pl-[var(--admin-sidebar-collapsed)]'\r\n : 'lg:pl-[var(--admin-sidebar-width)]'\r\n\r\n return (\r\n <div className='admin-layout-root min-h-screen bg-admin-bg text-admin-text'>\r\n <Sidebar\r\n items={sidebarItems}\r\n appName={appName}\r\n appLogo={appLogo}\r\n activePath={activePath}\r\n onNavigate={handleNavigate}\r\n LinkComponent={LinkComponent}\r\n />\r\n <MobileSidebar\r\n items={sidebarItems}\r\n appName={appName}\r\n appLogo={appLogo}\r\n activePath={activePath}\r\n onNavigate={handleNavigate}\r\n LinkComponent={LinkComponent}\r\n />\r\n\r\n <div className={cn('flex min-h-screen flex-col transition-all duration-300', mainOffset)}>\r\n <Navbar\r\n user={user}\r\n notifications={notifications}\r\n onSearch={onSearch}\r\n searchPlaceholder={searchPlaceholder}\r\n showSearch={showSearch}\r\n breadcrumbs={breadcrumbs}\r\n onMenuClick={toggleMobile}\r\n sidebarCollapsed={sidebarCollapsed}\r\n onToggleSidebar={toggleSidebar}\r\n />\r\n\r\n <main className={cn('flex-1 p-4 lg:p-6', contentClassName)}>{children}</main>\r\n\r\n {showFooter && <Footer>{footer}</Footer>}\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nexport function AdminLayout(props: AdminLayoutProps) {\r\n const {\r\n storageKey = 'rqdhw3n-admin-layout',\r\n defaultCollapsed = false,\r\n initialDarkMode = false,\r\n permissions = {},\r\n breadcrumbs: initialBreadcrumbs = [],\r\n activePath: initialActivePath = '/',\r\n enableRouter = false,\r\n children,\r\n ...rest\r\n } = props\r\n\r\n const initialBc = useMemo(\r\n () =>\r\n initialBreadcrumbs.length\r\n ? initialBreadcrumbs\r\n : generateBreadcrumbsFromPath(initialActivePath),\r\n [initialBreadcrumbs, initialActivePath],\r\n )\r\n\r\n return (\r\n <LayoutProvider\r\n storageKey={storageKey}\r\n defaultCollapsed={defaultCollapsed}\r\n permissions={permissions}\r\n initialBreadcrumbs={initialBc}\r\n initialActivePath={initialActivePath}\r\n initialDarkMode={initialDarkMode}\r\n >\r\n {enableRouter ? (\r\n <AdminLayoutRouterSync>\r\n <AdminLayoutInner {...rest} enableRouter={enableRouter}>\r\n {children}\r\n </AdminLayoutInner>\r\n </AdminLayoutRouterSync>\r\n ) : (\r\n <AdminLayoutInner {...rest} enableRouter={enableRouter}>\r\n {children}\r\n </AdminLayoutInner>\r\n )}\r\n </LayoutProvider>\r\n )\r\n}\r\n","import { NavLink } from 'react-router-dom'\r\nimport type { ReactNode } from 'react'\r\n\r\nexport type RouterLinkProps = {\r\n to: string\r\n className?: string\r\n children: ReactNode\r\n onClick?: () => void\r\n}\r\n\r\nexport function RouterLink({ to, className, children, onClick }: RouterLinkProps) {\r\n return (\r\n <NavLink to={to} className={className} onClick={onClick}>\r\n {children}\r\n </NavLink>\r\n )\r\n}\r\n","import { useLayoutContext } from '../context/LayoutContext'\r\n\r\nexport function useLayoutState() {\r\n return useLayoutContext()\r\n}\r\n","import { useCallback } from 'react'\r\nimport { useLayoutContext } from '../context/LayoutContext'\r\nimport type { BreadcrumbItem } from '../types'\r\n\r\nexport function useBreadcrumbs() {\r\n const { breadcrumbs, setBreadcrumbs } = useLayoutContext()\r\n\r\n const update = useCallback(\r\n (items: BreadcrumbItem[]) => setBreadcrumbs(items),\r\n [setBreadcrumbs],\r\n )\r\n\r\n return {\r\n items: breadcrumbs,\r\n setBreadcrumbs: update,\r\n }\r\n}\r\n"],"names":["loadLayoutState","key","raw","saveLayoutState","state","LayoutContext","createContext","LayoutProvider","children","storageKey","defaultCollapsed","permissions","initialBreadcrumbs","initialActivePath","initialDarkMode","persisted","sidebarCollapsed","setSidebarCollapsed","useState","mobileOpen","setMobileOpen","darkMode","setDarkMode","breadcrumbs","setBreadcrumbs","activePath","setActivePath","useEffect","root","toggleSidebar","useCallback","v","toggleMobile","toggleDarkMode","value","useMemo","jsx","useLayoutContext","ctx","useContext","useSidebar","generateBreadcrumbsFromPath","pathname","segments","seg","i","path","c","r","f","n","o","clsx","cn","inputs","AdminLayoutRouterSync","useLocation","manualBreadcrumbs","Footer","className","jsxs","parsePermission","permission","dot","hasPermission","resource","action","allowed","filterSidebarByPermissions","items","item","_a","SidebarGroup","label","collapsed","isActive","SidebarItem","depth","onNavigate","LinkComponent","onItemClick","hasChildren","active","childActive","_b","open","setOpen","Icon","baseClass","content","Fragment","ChevronDown","handleClick","row","child","MobileSidebar","appName","appLogo","activePathProp","closeMobile","ctxPath","filtered","onKey","e","handleNavigate","X","Breadcrumbs","renderLink","isLast","classNames","Home","index","ChevronRight","NavbarSearch","placeholder","onSearch","query","setQuery","Search","NotificationMenu","notifications","ref","useRef","unread","handler","Bell","useDarkMode","ThemeToggle","isDark","toggle","Sun","Moon","UserMenu","user","onLogout","onSettings","initials","Settings","User","LogOut","Navbar","searchPlaceholder","showSearch","onMenuClick","onToggleSidebar","Menu","PanelLeftOpen","PanelLeftClose","Sidebar","collapsedProp","ctxCollapsed","AdminLayoutInner","sidebarItems","footer","showFooter","breadcrumbsProp","contentClassName","_enableRouter","ctxBreadcrumbs","AdminLayout","props","enableRouter","rest","initialBc","RouterLink","to","onClick","NavLink","useLayoutState","useBreadcrumbs","update"],"mappings":"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","x_google_ignoreList":[4]}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/utils/storage.ts","../src/theme/defaults.ts","../src/theme/variables.ts","../src/theme/resolveTheme.ts","../src/theme/ThemeContext.ts","../src/theme/useSystemMode.ts","../src/context/LayoutContext.tsx","../src/hooks/useSidebar.ts","../src/utils/breadcrumbs.ts","../node_modules/clsx/dist/clsx.mjs","../src/utils/cn.ts","../src/components/AdminLayoutRouterSync.tsx","../src/components/Footer.tsx","../src/utils/permissions.ts","../src/components/SidebarGroup.tsx","../src/components/SidebarItem.tsx","../src/components/MobileSidebar.tsx","../src/components/Breadcrumbs.tsx","../src/components/NavbarSearch.tsx","../src/components/NotificationMenu.tsx","../src/hooks/useDarkMode.ts","../src/components/ThemeToggle.tsx","../src/components/UserMenu.tsx","../src/components/Navbar.tsx","../src/components/Sidebar.tsx","../src/components/AdminLayout.tsx","../src/components/RouterLink.tsx","../src/hooks/useLayoutState.ts","../src/hooks/useBreadcrumbs.ts"],"sourcesContent":["import type { LayoutState } from '../types'\nimport type { AdminLayoutThemeMode } from '../theme/types'\n\r\nexport type PersistedLayout = Partial<Pick<LayoutState, 'sidebarCollapsed' | 'darkMode'>> & {\n mode?: AdminLayoutThemeMode\n}\n\r\nexport function loadLayoutState(key: string): Partial<PersistedLayout> {\r\n if (typeof window === 'undefined') return {}\r\n try {\r\n const raw = localStorage.getItem(key)\r\n const value: unknown = raw ? JSON.parse(raw) : null\n if (!value || typeof value !== 'object') return {}\n const data = value as Record<string, unknown>\n return {\n sidebarCollapsed: typeof data.sidebarCollapsed === 'boolean' ? data.sidebarCollapsed : undefined,\n darkMode: typeof data.darkMode === 'boolean' ? data.darkMode : undefined,\n mode: data.mode === 'light' || data.mode === 'dark' || data.mode === 'system' ? data.mode : undefined,\n }\n } catch {\r\n return {}\r\n }\r\n}\r\n\r\nexport function saveLayoutState(key: string, state: PersistedLayout): void {\r\n if (typeof window === 'undefined') return\r\n try {\r\n localStorage.setItem(key, JSON.stringify(state))\r\n } catch {\r\n /* ignore quota errors */\r\n }\r\n}\r\n","import type { AdminLayoutColors, AdminLayoutStyle, AdminLayoutTheme } from './types'\n\nexport const lightThemeColors: Readonly<Required<AdminLayoutColors>> = Object.freeze({\n primary: '#2563eb',\n secondary: '#7c3aed',\n background: '#f8fafc',\n surface: '#ffffff',\n text: '#0f172a',\n textSecondary: '#64748b',\n sidebarBackground: '#ffffff',\n sidebarText: '#64748b',\n headerBackground: '#ffffff',\n headerText: '#0f172a',\n hoverBackground: '#f1f5f9',\n hoverText: '#0f172a',\n activeBackground: '#2563eb',\n activeText: '#ffffff',\n border: '#e2e8f0',\n onPrimary: '#ffffff',\n danger: '#dc2626',\n onDanger: '#ffffff',\n overlay: 'rgb(15 23 42 / 0.5)',\n})\n\nexport const darkThemeColors: Readonly<Required<AdminLayoutColors>> = Object.freeze({\n ...lightThemeColors,\n primary: '#3b82f6',\n secondary: '#a78bfa',\n background: '#0b1220',\n surface: '#111827',\n text: '#f1f5f9',\n textSecondary: '#94a3b8',\n sidebarBackground: '#111827',\n sidebarText: '#cbd5e1',\n headerBackground: '#111827',\n headerText: '#f1f5f9',\n hoverBackground: '#1e293b',\n hoverText: '#ffffff',\n activeBackground: '#3b82f6',\n activeText: '#020617',\n onPrimary: '#020617',\n border: '#334155',\n danger: '#f87171',\n onDanger: '#020617',\n overlay: 'rgb(2 6 23 / 0.7)',\n})\n\nexport const adminLayoutPresets: Readonly<Record<AdminLayoutStyle, Readonly<AdminLayoutTheme>>> =\n Object.freeze({\n modern: Object.freeze({ style: 'modern' }),\n minimal: Object.freeze({ style: 'minimal' }),\n compact: Object.freeze({ style: 'compact' }),\n })\n","import type { AdminLayoutColors } from './types'\n\nexport const colorVariables: Readonly<Record<keyof AdminLayoutColors, `--ral-${string}`>> = {\n primary: '--ral-primary', secondary: '--ral-secondary',\n background: '--ral-background', surface: '--ral-surface',\n text: '--ral-text', textSecondary: '--ral-text-secondary',\n sidebarBackground: '--ral-sidebar-bg', sidebarText: '--ral-sidebar-text',\n headerBackground: '--ral-header-bg', headerText: '--ral-header-text',\n hoverBackground: '--ral-hover-bg', hoverText: '--ral-hover-text',\n activeBackground: '--ral-active-bg', activeText: '--ral-active-text',\n border: '--ral-border', onPrimary: '--ral-on-primary', danger: '--ral-danger',\n onDanger: '--ral-on-danger', overlay: '--ral-overlay',\n}\n","import type { CSSProperties } from 'react'\nimport { darkThemeColors, lightThemeColors } from './defaults'\nimport { colorVariables } from './variables'\nimport type { AdminLayoutColors, AdminLayoutResolvedMode, AdminLayoutTheme, ResolvedAdminLayoutTheme } from './types'\n\n/** Defaults < generic colors < selected mode colors. Undefined values never erase defaults. */\nexport function resolveTheme(\n theme: AdminLayoutTheme = {},\n systemMode: AdminLayoutResolvedMode = 'light',\n): ResolvedAdminLayoutTheme {\n const mode = theme.mode === 'system' ? systemMode : (theme.mode ?? 'light')\n const colors = { ...(mode === 'dark' ? darkThemeColors : lightThemeColors) }\n const overrides: AdminLayoutColors = {}\n for (const palette of [theme.colors, theme[mode]]) {\n if (!palette) continue\n for (const key of Object.keys(colors) as (keyof AdminLayoutColors)[]) {\n const value = palette[key]\n if (typeof value === 'string' && value.trim()) overrides[key] = value\n }\n }\n Object.assign(colors, overrides)\n // A brand color also colors active navigation unless explicitly overridden.\n if (overrides.primary && !overrides.activeBackground) colors.activeBackground = overrides.primary\n return { mode, style: theme.style ?? 'modern', colors }\n}\n\n/** Apply once at a layout boundary; every descendant inherits the palette. */\nexport function themeToCSSVariables(theme: ResolvedAdminLayoutTheme): CSSProperties {\n return Object.fromEntries(\n (Object.keys(colorVariables) as (keyof AdminLayoutColors)[]).map(\n (key) => [colorVariables[key], theme.colors[key]],\n ),\n ) as CSSProperties\n}\n","import { createContext, useContext } from 'react'\nimport type { AdminLayoutThemeContextValue } from './types'\n\nexport const ThemeContext = createContext<AdminLayoutThemeContextValue | null>(null)\n\nexport function useAdminLayoutTheme() {\n const context = useContext(ThemeContext)\n if (!context) throw new Error('useAdminLayoutTheme must be used within LayoutProvider / AdminLayout')\n return {\n mode: context.requestedMode,\n resolvedMode: context.mode,\n style: context.style,\n colors: context.colors,\n setMode: context.setMode,\n }\n}\n","import { useCallback, useSyncExternalStore } from 'react'\nimport type { AdminLayoutResolvedMode } from './types'\n\nconst query = '(prefers-color-scheme: dark)'\nconst serverSnapshot = (): AdminLayoutResolvedMode => 'light'\n\nexport function useSystemMode(enabled: boolean): AdminLayoutResolvedMode {\n const subscribe = useCallback((onChange: () => void) => {\n if (!enabled || typeof window === 'undefined' || !window.matchMedia) return () => {}\n const media = window.matchMedia(query)\n if (media.addEventListener) {\n media.addEventListener('change', onChange)\n return () => media.removeEventListener('change', onChange)\n }\n media.addListener(onChange)\n return () => media.removeListener(onChange)\n }, [enabled])\n const getSnapshot = useCallback((): AdminLayoutResolvedMode =>\n enabled && typeof window !== 'undefined' && window.matchMedia?.(query).matches ? 'dark' : 'light',\n [enabled])\n return useSyncExternalStore(subscribe, getSnapshot, serverSnapshot)\n}\n","import {\r\n createContext,\r\n useCallback,\r\n useContext,\r\n useEffect,\r\n useMemo,\r\n useState,\r\n type ReactNode,\r\n} from 'react'\r\nimport type { BreadcrumbItem, LayoutContextValue, PermissionsMap } from '../types'\r\nimport { loadLayoutState, saveLayoutState } from '../utils/storage'\nimport { resolveTheme } from '../theme/resolveTheme'\nimport { ThemeContext } from '../theme/ThemeContext'\nimport { useSystemMode } from '../theme/useSystemMode'\nimport type { AdminLayoutTheme, AdminLayoutThemeMode } from '../theme/types'\n\r\nconst LayoutContext = createContext<LayoutContextValue | null>(null)\r\n\r\nexport type LayoutProviderProps = {\r\n children: ReactNode\r\n storageKey?: string\r\n defaultCollapsed?: boolean\r\n permissions?: PermissionsMap\r\n initialBreadcrumbs?: BreadcrumbItem[]\r\n initialActivePath?: string\r\n initialDarkMode?: boolean\n theme?: AdminLayoutTheme\n onThemeModeChange?: (mode: AdminLayoutThemeMode) => void\n}\r\n\r\nexport function LayoutProvider({\r\n children,\r\n storageKey = 'rqdhw3n-admin-layout',\r\n defaultCollapsed = false,\r\n permissions = {},\r\n initialBreadcrumbs = [],\r\n initialActivePath = '/',\r\n initialDarkMode,\n theme,\n onThemeModeChange,\n}: LayoutProviderProps) {\n const [sidebarCollapsed, setSidebarCollapsed] = useState(defaultCollapsed)\n const [mobileOpen, setMobileOpen] = useState(false)\n const [localMode, setLocalMode] = useState<AdminLayoutThemeMode>(initialDarkMode ? 'dark' : 'light')\n const [loadedKey, setLoadedKey] = useState<string | null>(null)\n const mode = theme?.mode ?? localMode\n const systemMode = useSystemMode(mode === 'system')\n const resolved = resolveTheme({ ...theme, mode }, systemMode)\n const darkMode = resolved.mode === 'dark'\n const setMode = useCallback((next: AdminLayoutThemeMode) => {\n if (theme?.mode === undefined) setLocalMode(next)\n onThemeModeChange?.(next)\n }, [theme?.mode, onThemeModeChange])\n const setDarkMode = useCallback((value: boolean) => setMode(value ? 'dark' : 'light'), [setMode])\n const [breadcrumbs, setBreadcrumbs] = useState<BreadcrumbItem[]>(initialBreadcrumbs)\r\n const [activePath, setActivePath] = useState(initialActivePath)\r\n\r\n useEffect(() => {\n const persisted = loadLayoutState(storageKey)\n setSidebarCollapsed(persisted.sidebarCollapsed ?? defaultCollapsed)\n setLocalMode(persisted.mode ?? (persisted.darkMode ?? initialDarkMode ? 'dark' : 'light'))\n setLoadedKey(storageKey)\n // Defaults are initial values; changing storageKey switches the persisted profile.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [storageKey])\n\n useEffect(() => {\n if (loadedKey !== storageKey) return\n const persisted = loadLayoutState(storageKey)\n saveLayoutState(storageKey, theme?.mode === undefined\n ? { sidebarCollapsed, darkMode, mode }\n : { ...persisted, sidebarCollapsed })\n }, [storageKey, sidebarCollapsed, darkMode, mode, theme?.mode, loadedKey])\n\r\n useEffect(() => {\n // Preserve the original document-wide dark class only for legacy consumers.\n if (theme !== undefined) return\n const root = document.documentElement\n const wasDark = root.classList.contains('dark')\n if (darkMode) root.classList.add('dark')\n else root.classList.remove('dark')\n return () => { root.classList.toggle('dark', wasDark) }\n }, [darkMode, theme])\n\r\n const toggleSidebar = useCallback(() => setSidebarCollapsed((v) => !v), [])\r\n const toggleMobile = useCallback(() => setMobileOpen((v) => !v), [])\r\n const toggleDarkMode = useCallback(() => setDarkMode(!darkMode), [setDarkMode, darkMode])\n\r\n const value = useMemo<LayoutContextValue>(\r\n () => ({\r\n sidebarCollapsed,\r\n mobileOpen,\r\n darkMode,\r\n toggleSidebar,\r\n setSidebarCollapsed,\r\n toggleMobile,\r\n setMobileOpen,\r\n toggleDarkMode,\r\n setDarkMode,\r\n permissions,\r\n breadcrumbs,\r\n setBreadcrumbs,\r\n activePath,\r\n setActivePath,\r\n }),\r\n [\r\n sidebarCollapsed,\r\n mobileOpen,\r\n darkMode,\r\n toggleSidebar,\r\n toggleMobile,\r\n toggleDarkMode,\n setDarkMode,\n permissions,\n breadcrumbs,\r\n activePath,\r\n ],\r\n )\r\n\r\n return (\n <LayoutContext.Provider value={value}>\n <ThemeContext.Provider value={{ ...resolved, requestedMode: mode, setMode }}>\n {children}\n </ThemeContext.Provider>\n </LayoutContext.Provider>\n )\n}\n\r\nexport function useLayoutContext(): LayoutContextValue {\r\n const ctx = useContext(LayoutContext)\r\n if (!ctx) {\r\n throw new Error('useLayoutContext must be used within LayoutProvider / AdminLayout')\r\n }\r\n return ctx\r\n}\r\n","import { useLayoutContext } from '../context/LayoutContext'\nimport { useCallback } from 'react'\n\r\nexport function useSidebar() {\r\n const {\r\n sidebarCollapsed,\r\n mobileOpen,\r\n toggleSidebar,\r\n setSidebarCollapsed,\r\n toggleMobile,\r\n setMobileOpen,\r\n } = useLayoutContext()\r\n\r\n const closeMobile = useCallback(() => setMobileOpen(false), [setMobileOpen])\n return {\n collapsed: sidebarCollapsed,\r\n mobileOpen,\r\n toggle: toggleSidebar,\r\n setCollapsed: setSidebarCollapsed,\r\n toggleMobile,\r\n setMobileOpen,\r\n closeMobile,\n }\r\n}\r\n","import type { BreadcrumbItem } from '../types'\r\n\r\nexport function generateBreadcrumbsFromPath(pathname: string): BreadcrumbItem[] {\r\n const segments = pathname.split('/').filter(Boolean)\r\n if (!segments.length) return [{ label: 'Home', path: '/' }]\r\n\r\n return segments.map((seg, i) => {\r\n const path = '/' + segments.slice(0, i + 1).join('/')\r\n const label = seg\r\n .replace(/-/g, ' ')\r\n .replace(/\\b\\w/g, (c) => c.toUpperCase())\r\n return { label, path: i < segments.length - 1 ? path : undefined }\r\n })\r\n}\r\n","function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","import clsx, { type ClassValue } from 'clsx'\r\n\r\nexport function cn(...inputs: ClassValue[]): string {\r\n return clsx(inputs)\r\n}\r\n","import { useEffect, type ReactNode } from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\nimport { useLayoutContext } from '../context/LayoutContext'\r\nimport { generateBreadcrumbsFromPath } from '../utils/breadcrumbs'\r\n\r\nexport type AdminLayoutRouterSyncProps = {\r\n children: ReactNode\r\n}\r\n\r\nexport function AdminLayoutRouterSync({ children }: AdminLayoutRouterSyncProps) {\r\n const { pathname } = useLocation()\r\n const { setActivePath, setBreadcrumbs, breadcrumbs: manualBreadcrumbs } = useLayoutContext()\r\n\r\n useEffect(() => {\r\n setActivePath(pathname)\r\n if (!manualBreadcrumbs.length) {\r\n setBreadcrumbs(generateBreadcrumbsFromPath(pathname))\r\n }\r\n }, [pathname, setActivePath, setBreadcrumbs, manualBreadcrumbs.length])\r\n\r\n return <>{children}</>\r\n}\r\n","import { cn } from '../utils/cn'\r\n\r\nexport type FooterProps = {\r\n children?: React.ReactNode\r\n className?: string\r\n}\r\n\r\nexport function Footer({ children, className }: FooterProps) {\r\n return (\r\n <footer\r\n className={cn(\r\n 'mt-auto border-t border-admin-border bg-admin-surface px-6 py-4 text-sm text-admin-muted',\r\n className,\r\n )}\r\n >\r\n {children ?? (\r\n <p className='text-center'>\r\n © {new Date().getFullYear()} Admin Layout · Built with @rqdhw3n/react-admin-layout\r\n </p>\r\n )}\r\n </footer>\r\n )\r\n}\r\n","import type { PermissionsMap, SidebarItemType } from '../types'\r\n\r\nexport function parsePermission(permission: string): { resource: string; action: string } {\r\n const dot = permission.indexOf('.')\r\n if (dot === -1) return { resource: permission, action: 'view' }\r\n return {\r\n resource: permission.slice(0, dot),\r\n action: permission.slice(dot + 1),\r\n }\r\n}\r\n\r\nexport function hasPermission(\r\n permissions: PermissionsMap,\r\n permission?: string,\r\n): boolean {\r\n if (!permission) return true\r\n const { resource, action } = parsePermission(permission)\r\n const allowed = permissions[resource]\r\n if (!allowed?.length) return false\r\n return allowed.includes(action) || allowed.includes('*')\r\n}\r\n\r\nexport function filterSidebarByPermissions(\r\n items: SidebarItemType[],\r\n permissions: PermissionsMap,\r\n): SidebarItemType[] {\r\n return items\r\n .filter((item) => hasPermission(permissions, item.permission))\r\n .map((item) => ({\r\n ...item,\r\n children: item.children\r\n ? filterSidebarByPermissions(item.children, permissions)\r\n : undefined,\r\n }))\r\n .filter((item) => !item.children?.length || item.children.length > 0 || item.path)\r\n}\r\n","import type { ReactNode } from 'react'\r\nimport { cn } from '../utils/cn'\r\n\r\nexport type SidebarGroupProps = {\r\n label?: string\r\n children: ReactNode\r\n collapsed?: boolean\r\n className?: string\r\n}\r\n\r\nexport function SidebarGroup({ label, children, collapsed, className }: SidebarGroupProps) {\r\n return (\r\n <div className={cn('ral-sidebar-group mb-4', className)}>\n {label && !collapsed && (\r\n <p className='ral-sidebar-brand mb-2 px-3 text-[11px] font-semibold uppercase tracking-wider'>\n {label}\r\n </p>\r\n )}\r\n <ul className='space-y-0.5'>{children}</ul>\r\n </div>\r\n )\r\n}\r\n","import { ChevronDown } from 'lucide-react'\r\nimport { useEffect, useState } from 'react'\nimport type { SidebarItemType } from '../types'\r\nimport { cn } from '../utils/cn'\r\n\r\nexport type SidebarItemProps = {\r\n item: SidebarItemType\r\n collapsed?: boolean\r\n depth?: number\r\n activePath?: string\r\n onNavigate?: (path: string) => void\r\n LinkComponent?: React.ComponentType<{\r\n to: string\r\n className?: string\r\n children: React.ReactNode\r\n onClick?: () => void\r\n }>\r\n onItemClick?: () => void\r\n}\r\n\r\nfunction isActive(path: string | undefined, activePath: string): boolean {\n if (!path) return false\r\n return activePath === path || activePath.startsWith(`${path}/`)\r\n}\n\nfunction hasActiveChild(item: SidebarItemType, activePath: string): boolean {\n return Boolean(item.children?.some((child) => isActive(child.path, activePath) || hasActiveChild(child, activePath)))\n}\n\r\nexport function SidebarItem({\r\n item,\r\n collapsed = false,\r\n depth = 0,\r\n activePath = '/',\r\n onNavigate,\r\n LinkComponent,\r\n onItemClick,\r\n}: SidebarItemProps) {\r\n const hasChildren = Boolean(item.children?.length)\r\n const active = item.path ? isActive(item.path, activePath) : false\r\n const childActive = hasActiveChild(item, activePath)\n const [open, setOpen] = useState(active || childActive)\n useEffect(() => { if (childActive) setOpen(true) }, [activePath, childActive])\n\r\n const Icon = item.icon\r\n\r\n const baseClass = cn(\r\n 'ral-nav-item group flex w-full items-center gap-3 px-3 text-sm font-medium',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-admin-primary',\r\n item.disabled && 'pointer-events-none opacity-50',\r\n depth > 0 && 'text-[13px]',\n collapsed && 'justify-center',\n (active || childActive) && 'ral-nav-active',\n )\r\n\r\n const content = (\r\n <>\r\n {Icon && (\r\n <Icon\r\n className='h-[18px] w-[18px] shrink-0'\n aria-hidden\r\n />\r\n )}\n {collapsed && !Icon && <span aria-hidden>{item.label.charAt(0)}</span>}\n {collapsed && <span className='sr-only'>{item.label}</span>}\n {!collapsed && (\r\n <>\r\n <span className='flex-1 truncate text-left'>{item.label}</span>\r\n {item.badge != null && (\r\n <span\r\n className={cn(\r\n 'ral-nav-badge rounded-full px-2 py-0.5 text-[11px] font-semibold',\n )}\r\n >\r\n {item.badge}\r\n </span>\r\n )}\r\n {hasChildren && (\r\n <ChevronDown\r\n className={cn('h-4 w-4 shrink-0 transition-transform', open && 'rotate-180')}\r\n aria-hidden\r\n />\r\n )}\r\n </>\r\n )}\r\n </>\r\n )\r\n\r\n const handleClick = () => {\n if (item.disabled) return\n if (hasChildren) {\r\n setOpen((v) => !v)\r\n return\r\n }\r\n if (item.path) {\r\n onNavigate?.(item.path)\r\n onItemClick?.()\r\n }\r\n }\r\n\r\n const row =\r\n item.path && !hasChildren && LinkComponent && !item.disabled ? (\n <LinkComponent\r\n to={item.path}\r\n className={baseClass}\n onClick={handleClick}\n >\r\n {content}\r\n </LinkComponent>\r\n ) : (\r\n <button type='button' className={baseClass} onClick={handleClick} disabled={item.disabled}\n data-active={active || childActive}\n aria-label={collapsed ? item.label : undefined}\n title={collapsed ? item.label : undefined}\n aria-expanded={hasChildren ? Boolean(open) : undefined}\n aria-current={active && !hasChildren ? 'page' : undefined}>\n {content}\r\n </button>\r\n )\r\n\r\n return (\r\n <li data-active={active || childActive} aria-label={collapsed ? item.label : undefined}>\n {row}\r\n {hasChildren && open && (\n <ul className={cn('mt-1 space-y-0.5', !collapsed && 'border-l border-admin-border ml-5 pl-2')}>\n {item.children!.map((child) => (\r\n <SidebarItem\r\n key={child.label + (child.path ?? '')}\r\n item={child}\r\n collapsed={collapsed}\r\n depth={depth + 1}\r\n activePath={activePath}\r\n onNavigate={onNavigate}\r\n LinkComponent={LinkComponent}\r\n onItemClick={onItemClick}\r\n />\r\n ))}\r\n </ul>\r\n )}\r\n </li>\r\n )\r\n}\r\n","import { X } from 'lucide-react'\r\nimport { useEffect, useRef } from 'react'\nimport { useSidebar } from '../hooks/useSidebar'\r\nimport { useLayoutContext } from '../context/LayoutContext'\r\nimport type { SidebarProps } from '../types'\r\nimport { filterSidebarByPermissions } from '../utils/permissions'\r\nimport { cn } from '../utils/cn'\r\nimport { SidebarGroup } from './SidebarGroup'\r\nimport { SidebarItem } from './SidebarItem'\r\n\r\nexport type MobileSidebarProps = SidebarProps\r\n\r\nexport function MobileSidebar({\r\n items,\r\n appName = 'Admin',\r\n appLogo,\r\n onNavigate,\r\n activePath: activePathProp,\r\n LinkComponent,\r\n}: MobileSidebarProps) {\r\n const { mobileOpen, closeMobile } = useSidebar()\r\n const { permissions, activePath: ctxPath } = useLayoutContext()\r\n const activePath = activePathProp ?? ctxPath\r\n const filtered = filterSidebarByPermissions(items, permissions)\n const dialogRef = useRef<HTMLDivElement>(null)\n\r\n useEffect(() => {\r\n if (!mobileOpen) return\n const previousFocus = document.activeElement as HTMLElement | null\n const previousOverflow = document.body.style.overflow\n const focusable = () => Array.from(dialogRef.current?.querySelectorAll<HTMLElement>(\n 'button:not(:disabled), a[href], input, [tabindex=\"0\"]',\n ) ?? []).filter((element) => element.getClientRects().length > 0)\n dialogRef.current?.querySelector<HTMLElement>('[aria-label=\"Close sidebar\"]')?.focus()\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') closeMobile()\n if (e.key === 'Tab') {\n const elements = focusable()\n const first = elements[0]\n const last = elements[elements.length - 1]\n if (e.shiftKey && document.activeElement === first) { e.preventDefault(); last?.focus() }\n else if (!e.shiftKey && document.activeElement === last) { e.preventDefault(); first?.focus() }\n }\n }\n const desktop = window.matchMedia?.('(min-width: 1024px)')\n const onResize = () => { if (desktop?.matches) closeMobile() }\n desktop?.addEventListener?.('change', onResize)\n document.addEventListener('keydown', onKey)\r\n document.body.style.overflow = 'hidden'\r\n return () => {\r\n document.removeEventListener('keydown', onKey)\r\n desktop?.removeEventListener?.('change', onResize)\n document.body.style.overflow = previousOverflow\n previousFocus?.focus()\n }\r\n }, [mobileOpen, closeMobile])\r\n\r\n if (!mobileOpen) return null\r\n\r\n const handleNavigate = (path: string) => {\r\n onNavigate?.(path)\r\n closeMobile()\r\n }\r\n\r\n return (\r\n <div ref={dialogRef} className='fixed inset-0 z-50 lg:hidden' role='dialog' aria-modal='true' aria-label='Navigation menu'>\n <button\r\n type='button'\r\n className='ral-overlay absolute inset-0 backdrop-blur-sm animate-fade-in'\n aria-label='Close menu'\r\n onClick={closeMobile}\r\n />\r\n <aside\r\n className={cn(\r\n 'ral-sidebar absolute left-0 top-0 flex h-full w-[min(var(--ral-sidebar-width),85vw)] flex-col',\n 'border-r border-admin-border shadow-admin-lg animate-slide-in',\n )}\r\n >\r\n <div className='ral-sidebar-top flex items-center justify-between border-b border-admin-border px-4'>\n <div className='flex items-center gap-3'>\r\n {appLogo ?? (\r\n <div className='flex h-9 w-9 items-center justify-center rounded-admin bg-admin-primary text-sm font-bold text-admin-on-primary'>\r\n {appName.charAt(0)}\r\n </div>\r\n )}\r\n <span className='ral-sidebar-brand font-semibold'>{appName}</span>\n </div>\r\n <button\r\n type='button'\r\n onClick={closeMobile}\r\n className='rounded-admin p-2 text-admin-muted hover:bg-admin-hover'\r\n aria-label='Close sidebar'\r\n >\r\n <X className='h-5 w-5' />\r\n </button>\r\n </div>\r\n <nav className='flex-1 overflow-y-auto p-3'>\r\n <SidebarGroup>\r\n {filtered.map((item) => (\r\n <SidebarItem\r\n key={item.label + (item.path ?? '')}\r\n item={item}\r\n activePath={activePath}\r\n onNavigate={handleNavigate}\r\n LinkComponent={LinkComponent}\r\n onItemClick={closeMobile}\r\n />\r\n ))}\r\n </SidebarGroup>\r\n </nav>\r\n </aside>\r\n </div>\r\n )\r\n}\r\n","import { ChevronRight, Home } from 'lucide-react'\r\nimport type { BreadcrumbItem } from '../types'\r\nimport { cn } from '../utils/cn'\r\n\r\nexport type BreadcrumbsProps = {\r\n items: BreadcrumbItem[]\r\n className?: string\r\n LinkComponent?: React.ComponentType<{\r\n to: string\r\n className?: string\r\n children: React.ReactNode\r\n }>\r\n onNavigate?: (path: string) => void\r\n}\r\n\r\nexport function Breadcrumbs({\r\n items,\r\n className,\r\n LinkComponent,\r\n onNavigate,\r\n}: BreadcrumbsProps) {\r\n if (!items.length) return null\r\n\r\n const renderLink = (item: BreadcrumbItem, isLast: boolean) => {\r\n const classNames = cn(\r\n 'text-sm transition-colors',\r\n isLast ? 'font-medium text-admin-text' : 'text-admin-muted hover:text-admin-hover-text',\r\n )\r\n\r\n if (!item.path || isLast) {\r\n return <span className={classNames}>{item.label}</span>\r\n }\r\n\r\n if (LinkComponent) {\r\n return (\r\n <LinkComponent to={item.path} className={classNames}>\r\n {item.label}\r\n </LinkComponent>\r\n )\r\n }\r\n\r\n return (\r\n <button type='button' className={classNames} onClick={() => onNavigate?.(item.path!)}>\r\n {item.label}\r\n </button>\r\n )\r\n }\r\n\r\n return (\r\n <nav aria-label='Breadcrumb' className={cn('flex items-center gap-1.5', className)}>\r\n <Home className='h-4 w-4 text-admin-muted shrink-0' aria-hidden />\r\n {items.map((item, index) => {\r\n const isLast = index === items.length - 1\r\n return (\r\n <span key={`${item.label}-${index}`} className='flex items-center gap-1.5'>\r\n <ChevronRight className='h-3.5 w-3.5 text-admin-muted' aria-hidden />\r\n {renderLink(item, isLast)}\r\n </span>\r\n )\r\n })}\r\n </nav>\r\n )\r\n}\r\n","import { Search } from 'lucide-react'\r\nimport { useState, type FormEvent } from 'react'\r\nimport { cn } from '../utils/cn'\r\n\r\nexport type NavbarSearchProps = {\r\n placeholder?: string\r\n onSearch?: (query: string) => void\r\n className?: string\r\n}\r\n\r\nexport function NavbarSearch({\r\n placeholder = 'Search...',\r\n onSearch,\r\n className,\r\n}: NavbarSearchProps) {\r\n const [query, setQuery] = useState('')\r\n\r\n const handleSubmit = (e: FormEvent) => {\r\n e.preventDefault()\r\n onSearch?.(query.trim())\r\n }\r\n\r\n return (\r\n <form onSubmit={handleSubmit} className={cn('relative w-full max-w-md', className)}>\r\n <Search\r\n className='pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-admin-muted'\r\n aria-hidden\r\n />\r\n <input\r\n type='search'\r\n value={query}\r\n onChange={(e) => setQuery(e.target.value)}\r\n placeholder={placeholder}\r\n className={cn(\r\n 'h-10 w-full rounded-admin border border-admin-border bg-admin-bg pl-10 pr-4 text-sm text-admin-text',\r\n 'placeholder:text-admin-muted focus:border-admin-primary focus:outline-none focus:ring-2 focus:ring-admin-primary',\n )}\r\n aria-label='Search'\r\n />\r\n </form>\r\n )\r\n}\r\n","import { Bell } from 'lucide-react'\r\nimport { useEffect, useRef, useState } from 'react'\r\nimport type { NotificationItem } from '../types'\r\nimport { cn } from '../utils/cn'\r\n\r\nexport type NotificationMenuProps = {\r\n notifications?: NotificationItem[]\r\n className?: string\r\n}\r\n\r\nexport function NotificationMenu({ notifications = [], className }: NotificationMenuProps) {\r\n const [open, setOpen] = useState(false)\r\n const ref = useRef<HTMLDivElement>(null)\r\n const unread = notifications.filter((n) => !n.read).length\r\n\r\n useEffect(() => {\r\n const handler = (e: MouseEvent) => {\r\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)\r\n }\r\n document.addEventListener('mousedown', handler)\r\n return () => document.removeEventListener('mousedown', handler)\r\n }, [])\r\n\r\n return (\r\n <div ref={ref} className={cn('relative', className)} onKeyDown={(event) => {\n if (event.key === 'Escape') { setOpen(false); ref.current?.querySelector('button')?.focus() }\n }}>\n <button\r\n type='button'\r\n onClick={() => setOpen((v) => !v)}\r\n className={cn(\r\n 'relative inline-flex h-9 w-9 items-center justify-center rounded-admin border border-admin-border',\r\n 'bg-admin-surface text-admin-muted transition-colors hover:bg-admin-hover hover:text-admin-hover-text',\r\n 'focus-visible:ring-2 focus-visible:ring-admin-primary',\r\n )}\r\n aria-label={`Notifications${unread ? `, ${unread} unread` : ''}`}\r\n aria-expanded={open}\r\n >\r\n <Bell className='h-4 w-4' aria-hidden />\r\n {unread > 0 && (\r\n <span className='absolute -right-0.5 -top-0.5 flex h-4 min-w-4 items-center justify-center rounded-full bg-admin-danger px-1 text-[10px] font-bold text-admin-on-danger'>\n {unread > 9 ? '9+' : unread}\r\n </span>\r\n )}\r\n </button>\r\n\r\n {open && (\r\n <div className='absolute right-0 top-full z-50 mt-2 w-80 max-w-[calc(100vw-6rem)] rounded-admin border border-admin-border bg-admin-surface shadow-admin-lg animate-fade-in'>\n <div className='border-b border-admin-border px-4 py-3'>\r\n <p className='text-sm font-semibold text-admin-text'>Notifications</p>\r\n </div>\r\n <ul className='max-h-72 overflow-y-auto p-2'>\r\n {notifications.length === 0 ? (\r\n <li className='px-3 py-6 text-center text-sm text-admin-muted'>No notifications</li>\r\n ) : (\r\n notifications.map((n) => (\r\n <li\r\n key={n.id}\r\n className={cn(\r\n 'rounded-admin px-3 py-2.5 transition-colors hover:bg-admin-hover',\r\n !n.read && 'ral-unread',\r\n )}\r\n >\r\n <p className='text-sm font-medium text-admin-text'>{n.title}</p>\r\n {n.description && (\r\n <p className='mt-0.5 text-xs text-admin-muted line-clamp-2'>{n.description}</p>\r\n )}\r\n {n.time && <p className='mt-1 text-[11px] text-admin-muted'>{n.time}</p>}\r\n </li>\r\n ))\r\n )}\r\n </ul>\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n","import { useLayoutContext } from '../context/LayoutContext'\r\n\r\nexport function useDarkMode() {\r\n const { darkMode, toggleDarkMode, setDarkMode } = useLayoutContext()\r\n return {\r\n isDark: darkMode,\r\n toggle: toggleDarkMode,\r\n setDarkMode,\r\n }\r\n}\r\n","import { Moon, Sun } from 'lucide-react'\r\nimport { useDarkMode } from '../hooks/useDarkMode'\r\nimport { cn } from '../utils/cn'\r\n\r\nexport type ThemeToggleProps = {\r\n className?: string\r\n}\r\n\r\nexport function ThemeToggle({ className }: ThemeToggleProps) {\r\n const { isDark, toggle } = useDarkMode()\r\n\r\n return (\r\n <button\r\n type='button'\r\n onClick={toggle}\r\n className={cn(\r\n 'inline-flex h-9 w-9 items-center justify-center rounded-admin border border-admin-border',\r\n 'bg-admin-surface text-admin-muted transition-colors hover:bg-admin-hover hover:text-admin-hover-text',\r\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-admin-primary focus-visible:ring-offset-2',\r\n className,\r\n )}\r\n aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}\r\n >\r\n {isDark ? <Sun className='h-4 w-4' aria-hidden /> : <Moon className='h-4 w-4' aria-hidden />}\r\n </button>\r\n )\r\n}\r\n","import { ChevronDown, LogOut, Settings, User } from 'lucide-react'\r\nimport { useEffect, useRef, useState } from 'react'\r\nimport type { AdminUser } from '../types'\r\nimport { cn } from '../utils/cn'\r\n\r\nexport type UserMenuProps = {\r\n user: AdminUser\r\n onLogout?: () => void\r\n onSettings?: () => void\r\n className?: string\r\n}\r\n\r\nexport function UserMenu({ user, onLogout, onSettings, className }: UserMenuProps) {\r\n const [open, setOpen] = useState(false)\r\n const ref = useRef<HTMLDivElement>(null)\r\n\r\n useEffect(() => {\r\n const handler = (e: MouseEvent) => {\r\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)\r\n }\r\n document.addEventListener('mousedown', handler)\r\n return () => document.removeEventListener('mousedown', handler)\r\n }, [])\n\n useEffect(() => {\n if (open) ref.current?.querySelector<HTMLElement>('[role=\"menuitem\"]')?.focus()\n }, [open])\n\r\n const initials = user.name\r\n .split(' ')\r\n .map((n) => n[0])\r\n .join('')\r\n .slice(0, 2)\r\n .toUpperCase()\r\n\r\n return (\r\n <div ref={ref} className={cn('relative', className)} onKeyDown={(event) => {\n const trigger = ref.current?.querySelector<HTMLButtonElement>('[aria-haspopup]')\n if (event.key === 'Escape' && open) { event.preventDefault(); setOpen(false); trigger?.focus() }\n if (event.key === 'Tab') setOpen(false)\n if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {\n event.preventDefault()\n if (!open) { setOpen(true); return }\n const entries = Array.from(ref.current?.querySelectorAll<HTMLButtonElement>('[role=\"menuitem\"]') ?? [])\n const current = entries.indexOf(document.activeElement as HTMLButtonElement)\n const next = event.key === 'Home' ? 0 : event.key === 'End' ? entries.length - 1\n : (current + (event.key === 'ArrowDown' ? 1 : -1) + entries.length) % entries.length\n entries[next]?.focus()\n }\n }}>\n <button\r\n type='button'\r\n onClick={() => setOpen((v) => !v)}\r\n className={cn(\r\n 'flex items-center gap-2 rounded-admin border border-admin-border bg-admin-surface px-2 py-1.5',\r\n 'transition-colors hover:bg-admin-hover focus-visible:ring-2 focus-visible:ring-admin-primary',\r\n )}\r\n aria-expanded={open}\r\n aria-haspopup='menu'\n aria-label={`User menu for ${user.name}`}\n >\r\n {user.avatar ? (\r\n <img src={user.avatar} alt='' className='h-8 w-8 rounded-admin object-cover' />\r\n ) : (\r\n <div className='flex h-8 w-8 items-center justify-center rounded-admin bg-admin-primary text-xs font-semibold text-admin-on-primary'>\r\n {initials}\r\n </div>\r\n )}\r\n <div className='hidden text-left sm:block'>\r\n <p className='text-sm font-medium text-admin-text leading-tight'>{user.name}</p>\r\n <p className='text-xs text-admin-muted leading-tight'>{user.email}</p>\r\n </div>\r\n <ChevronDown className='hidden h-4 w-4 text-admin-muted sm:block' aria-hidden />\r\n </button>\r\n\r\n {open && (\r\n <div\r\n role='menu'\r\n className='absolute right-0 top-full z-50 mt-2 w-56 rounded-admin border border-admin-border bg-admin-surface p-1.5 shadow-admin-lg animate-fade-in'\r\n >\r\n <button\r\n type='button'\r\n role='menuitem'\r\n className='flex w-full items-center gap-2 rounded-admin px-3 py-2 text-sm text-admin-text hover:bg-admin-hover'\r\n onClick={() => {\r\n onSettings?.()\r\n setOpen(false)\r\n }}\r\n >\r\n <Settings className='h-4 w-4 text-admin-muted' />\r\n Settings\r\n </button>\r\n <button\r\n type='button'\r\n role='menuitem'\r\n className='flex w-full items-center gap-2 rounded-admin px-3 py-2 text-sm text-admin-text hover:bg-admin-hover'\r\n >\r\n <User className='h-4 w-4 text-admin-muted' />\r\n Profile\r\n </button>\r\n <hr className='my-1 border-admin-border' />\r\n <button\r\n type='button'\r\n role='menuitem'\r\n className='flex w-full items-center gap-2 rounded-admin px-3 py-2 text-sm ral-danger'\r\n onClick={() => {\r\n onLogout?.()\r\n setOpen(false)\r\n }}\r\n >\r\n <LogOut className='h-4 w-4' />\r\n Log out\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n","import { Menu, PanelLeftClose, PanelLeftOpen } from 'lucide-react'\r\nimport type { NavbarProps } from '../types'\r\nimport { cn } from '../utils/cn'\r\nimport { Breadcrumbs } from './Breadcrumbs'\r\nimport { NavbarSearch } from './NavbarSearch'\r\nimport { NotificationMenu } from './NotificationMenu'\r\nimport { ThemeToggle } from './ThemeToggle'\r\nimport { UserMenu } from './UserMenu'\r\n\r\nexport function Navbar({\r\n user,\r\n notifications = [],\r\n onSearch,\r\n searchPlaceholder = 'Search...',\r\n showSearch = true,\r\n className,\r\n breadcrumbs = [],\r\n onMenuClick,\r\n sidebarCollapsed,\r\n onToggleSidebar,\r\n}: NavbarProps) {\r\n return (\r\n <header\r\n className={cn(\r\n 'ral-header sticky top-0 z-40 flex shrink-0 items-center gap-4 border-b border-admin-border',\n className,\r\n )}\r\n >\r\n <button\r\n type='button'\r\n className='rounded-admin p-2 text-admin-muted hover:bg-admin-hover lg:hidden'\r\n onClick={onMenuClick}\r\n aria-label='Open menu'\r\n >\r\n <Menu className='h-5 w-5' />\r\n </button>\r\n\r\n <button\r\n type='button'\r\n className='hidden rounded-admin p-2 text-admin-muted hover:bg-admin-hover lg:inline-flex'\r\n onClick={onToggleSidebar}\r\n aria-label={sidebarCollapsed ? 'Expand sidebar' : 'Collapse sidebar'}\r\n >\r\n {sidebarCollapsed ? (\r\n <PanelLeftOpen className='h-5 w-5' />\r\n ) : (\r\n <PanelLeftClose className='h-5 w-5' />\r\n )}\r\n </button>\r\n\r\n <div className='hidden min-w-0 flex-1 md:block'>\r\n <Breadcrumbs items={breadcrumbs} />\r\n </div>\r\n\r\n <div className='flex flex-1 items-center justify-end gap-2 sm:gap-3'>\r\n {showSearch && (\r\n <div className='hidden flex-1 sm:flex sm:max-w-md'>\r\n <NavbarSearch placeholder={searchPlaceholder} onSearch={onSearch} />\r\n </div>\r\n )}\r\n <ThemeToggle />\r\n <NotificationMenu notifications={notifications} />\r\n {user && <UserMenu user={user} />}\r\n </div>\r\n </header>\r\n )\r\n}\r\n","import { PanelLeftClose, PanelLeftOpen } from 'lucide-react'\r\nimport { useSidebar } from '../hooks/useSidebar'\r\nimport { useLayoutContext } from '../context/LayoutContext'\r\nimport type { SidebarProps } from '../types'\r\nimport { filterSidebarByPermissions } from '../utils/permissions'\r\nimport { cn } from '../utils/cn'\r\nimport { SidebarGroup } from './SidebarGroup'\r\nimport { SidebarItem } from './SidebarItem'\r\n\r\nexport function Sidebar({\r\n items,\r\n collapsed: collapsedProp,\r\n appName = 'Admin',\r\n appLogo,\r\n className,\r\n onNavigate,\r\n activePath: activePathProp,\r\n LinkComponent,\r\n}: SidebarProps) {\r\n const { collapsed: ctxCollapsed, toggle, closeMobile } = useSidebar()\r\n const { permissions, activePath: ctxPath } = useLayoutContext()\r\n\r\n const collapsed = collapsedProp ?? ctxCollapsed\r\n const activePath = activePathProp ?? ctxPath\r\n const filtered = filterSidebarByPermissions(items, permissions)\r\n\r\n const handleNavigate = (path: string) => {\r\n onNavigate?.(path)\r\n closeMobile()\r\n }\r\n\r\n return (\r\n <aside\r\n className={cn(\r\n 'ral-sidebar hidden lg:flex shrink-0 flex-col border-r border-admin-border',\n 'h-screen sticky top-0 transition-[width] duration-300 ease-in-out',\r\n collapsed ? 'w-[var(--admin-sidebar-collapsed)]' : 'w-[var(--admin-sidebar-width)]',\r\n className,\r\n )}\r\n aria-label='Sidebar navigation'\r\n >\r\n <div\r\n className={cn(\r\n 'ral-sidebar-top flex items-center border-b border-admin-border px-4',\n collapsed ? 'justify-center' : 'justify-between gap-2',\r\n )}\r\n >\r\n <div className={cn('flex items-center gap-3 min-w-0', collapsed && 'justify-center')}>\r\n {appLogo ?? (\r\n <div className='flex h-9 w-9 shrink-0 items-center justify-center rounded-admin bg-admin-primary text-sm font-bold text-admin-on-primary shadow-admin'>\r\n {appName.charAt(0)}\r\n </div>\r\n )}\r\n {!collapsed && (\r\n <span className='ral-sidebar-brand truncate text-base font-semibold'>{appName}</span>\n )}\r\n </div>\r\n {!collapsed && (\r\n <button\r\n type='button'\r\n onClick={toggle}\r\n className='rounded-admin p-2 text-admin-muted hover:bg-admin-hover hover:text-admin-hover-text focus-visible:ring-2 focus-visible:ring-admin-primary'\r\n aria-label='Collapse sidebar'\r\n >\r\n <PanelLeftClose className='h-4 w-4' />\r\n </button>\r\n )}\r\n </div>\r\n\r\n {collapsed && (\r\n <div className='flex justify-center py-2 border-b border-admin-border'>\r\n <button\r\n type='button'\r\n onClick={toggle}\r\n className='rounded-admin p-2 text-admin-muted hover:bg-admin-hover'\r\n aria-label='Expand sidebar'\r\n >\r\n <PanelLeftOpen className='h-4 w-4' />\r\n </button>\r\n </div>\r\n )}\r\n\r\n <nav className='flex-1 overflow-y-auto p-3'>\r\n <SidebarGroup collapsed={collapsed}>\r\n {filtered.map((item) => (\r\n <SidebarItem\r\n key={item.label + (item.path ?? '')}\r\n item={item}\r\n collapsed={collapsed}\r\n activePath={activePath}\r\n onNavigate={handleNavigate}\r\n LinkComponent={LinkComponent}\r\n />\r\n ))}\r\n </SidebarGroup>\r\n </nav>\r\n </aside>\r\n )\r\n}\r\n","import { useMemo } from 'react'\r\nimport { LayoutProvider } from '../context/LayoutContext'\r\nimport { useLayoutContext } from '../context/LayoutContext'\r\nimport { useSidebar } from '../hooks/useSidebar'\r\nimport type { AdminLayoutProps } from '../types'\r\nimport { generateBreadcrumbsFromPath } from '../utils/breadcrumbs'\r\nimport { cn } from '../utils/cn'\r\nimport { AdminLayoutRouterSync } from './AdminLayoutRouterSync'\r\nimport { Footer } from './Footer'\r\nimport { MobileSidebar } from './MobileSidebar'\r\nimport { Navbar } from './Navbar'\r\nimport { Sidebar } from './Sidebar'\nimport { useAdminLayoutTheme } from '../theme/ThemeContext'\nimport { themeToCSSVariables } from '../theme/resolveTheme'\n\r\nfunction AdminLayoutInner({\r\n children,\r\n sidebarItems,\r\n appName = 'Admin',\r\n appLogo,\r\n user,\r\n notifications = [],\r\n footer,\r\n showFooter = true,\r\n showSearch = true,\r\n searchPlaceholder,\r\n onSearch,\r\n breadcrumbs: breadcrumbsProp,\r\n contentClassName,\n className,\n activePath: activePathProp,\r\n onNavigate,\r\n LinkComponent,\r\n enableRouter: _enableRouter = false,\r\n}: AdminLayoutProps) {\r\n const {\r\n sidebarCollapsed,\r\n toggleSidebar,\r\n toggleMobile,\r\n breadcrumbs: ctxBreadcrumbs,\r\n setBreadcrumbs,\r\n activePath: ctxPath,\r\n setActivePath,\r\n } = useLayoutContext()\r\n const { closeMobile } = useSidebar()\n const { resolvedMode, style, colors } = useAdminLayoutTheme()\n\r\n const activePath = activePathProp ?? ctxPath\r\n const breadcrumbs = breadcrumbsProp ?? ctxBreadcrumbs\r\n\r\n const handleNavigate = (path: string) => {\r\n setActivePath(path)\r\n if (!breadcrumbsProp) {\r\n setBreadcrumbs(generateBreadcrumbsFromPath(path))\r\n }\r\n onNavigate?.(path)\r\n closeMobile()\r\n }\r\n\r\n return (\r\n <div\n className={cn('ral-layout admin-layout-root min-h-screen bg-admin-bg text-admin-text', resolvedMode === 'dark' && 'dark', className)}\n data-theme={resolvedMode}\n data-style={style}\n style={themeToCSSVariables({ mode: resolvedMode, style, colors })}\n >\n <MobileSidebar\r\n items={sidebarItems}\r\n appName={appName}\r\n appLogo={appLogo}\r\n activePath={activePath}\r\n onNavigate={handleNavigate}\r\n LinkComponent={LinkComponent}\r\n />\r\n\r\n <div className='flex min-h-screen w-full'>\r\n <Sidebar\r\n items={sidebarItems}\r\n appName={appName}\r\n appLogo={appLogo}\r\n activePath={activePath}\r\n onNavigate={handleNavigate}\r\n LinkComponent={LinkComponent}\r\n />\r\n\r\n <div className='flex min-h-screen min-w-0 flex-1 flex-col'>\r\n <Navbar\r\n user={user}\r\n notifications={notifications}\r\n onSearch={onSearch}\r\n searchPlaceholder={searchPlaceholder}\r\n showSearch={showSearch}\r\n breadcrumbs={breadcrumbs}\r\n onMenuClick={toggleMobile}\r\n sidebarCollapsed={sidebarCollapsed}\r\n onToggleSidebar={toggleSidebar}\r\n />\r\n\r\n <main className={cn('ral-content flex-1', contentClassName)}>{children}</main>\n\r\n {showFooter && <Footer>{footer}</Footer>}\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\nexport function AdminLayout(props: AdminLayoutProps) {\r\n const {\r\n storageKey = 'rqdhw3n-admin-layout',\r\n defaultCollapsed = false,\r\n initialDarkMode = false,\r\n permissions = {},\r\n breadcrumbs: initialBreadcrumbs = [],\r\n activePath: initialActivePath = '/',\r\n enableRouter = false,\r\n children,\r\n ...rest\r\n } = props\r\n\r\n const initialBc = useMemo(\r\n () =>\r\n initialBreadcrumbs.length\r\n ? initialBreadcrumbs\r\n : generateBreadcrumbsFromPath(initialActivePath),\r\n [initialBreadcrumbs, initialActivePath],\r\n )\r\n\r\n return (\r\n <LayoutProvider\r\n storageKey={storageKey}\r\n defaultCollapsed={defaultCollapsed}\r\n permissions={permissions}\r\n initialBreadcrumbs={initialBc}\r\n initialActivePath={initialActivePath}\r\n initialDarkMode={initialDarkMode}\n theme={props.theme}\n onThemeModeChange={props.onThemeModeChange}\n >\r\n {enableRouter ? (\r\n <AdminLayoutRouterSync>\r\n <AdminLayoutInner {...rest} enableRouter={enableRouter}>\r\n {children}\r\n </AdminLayoutInner>\r\n </AdminLayoutRouterSync>\r\n ) : (\r\n <AdminLayoutInner {...rest} enableRouter={enableRouter}>\r\n {children}\r\n </AdminLayoutInner>\r\n )}\r\n </LayoutProvider>\r\n )\r\n}\r\n","import { NavLink } from 'react-router-dom'\r\nimport type { ReactNode } from 'react'\r\n\r\nexport type RouterLinkProps = {\r\n to: string\r\n className?: string\r\n children: ReactNode\r\n onClick?: () => void\r\n}\r\n\r\nexport function RouterLink({ to, className, children, onClick }: RouterLinkProps) {\r\n return (\r\n <NavLink to={to} className={className} onClick={onClick}>\r\n {children}\r\n </NavLink>\r\n )\r\n}\r\n","import { useLayoutContext } from '../context/LayoutContext'\r\n\r\nexport function useLayoutState() {\r\n return useLayoutContext()\r\n}\r\n","import { useCallback } from 'react'\r\nimport { useLayoutContext } from '../context/LayoutContext'\r\nimport type { BreadcrumbItem } from '../types'\r\n\r\nexport function useBreadcrumbs() {\r\n const { breadcrumbs, setBreadcrumbs } = useLayoutContext()\r\n\r\n const update = useCallback(\r\n (items: BreadcrumbItem[]) => setBreadcrumbs(items),\r\n [setBreadcrumbs],\r\n )\r\n\r\n return {\r\n items: breadcrumbs,\r\n setBreadcrumbs: update,\r\n }\r\n}\r\n"],"names":["loadLayoutState","key","raw","value","data","saveLayoutState","state","lightThemeColors","darkThemeColors","adminLayoutPresets","colorVariables","resolveTheme","theme","systemMode","mode","colors","overrides","palette","themeToCSSVariables","ThemeContext","createContext","useAdminLayoutTheme","context","useContext","query","serverSnapshot","useSystemMode","enabled","subscribe","useCallback","onChange","media","getSnapshot","_a","useSyncExternalStore","LayoutContext","LayoutProvider","children","storageKey","defaultCollapsed","permissions","initialBreadcrumbs","initialActivePath","initialDarkMode","onThemeModeChange","sidebarCollapsed","setSidebarCollapsed","useState","mobileOpen","setMobileOpen","localMode","setLocalMode","loadedKey","setLoadedKey","resolved","darkMode","setMode","next","setDarkMode","breadcrumbs","setBreadcrumbs","activePath","setActivePath","useEffect","persisted","root","wasDark","toggleSidebar","v","toggleMobile","toggleDarkMode","useMemo","jsx","useLayoutContext","ctx","useSidebar","closeMobile","generateBreadcrumbsFromPath","pathname","segments","seg","i","path","c","r","t","f","n","clsx","cn","inputs","AdminLayoutRouterSync","useLocation","manualBreadcrumbs","Footer","className","jsxs","parsePermission","permission","dot","hasPermission","resource","action","allowed","filterSidebarByPermissions","items","item","SidebarGroup","label","collapsed","isActive","hasActiveChild","child","SidebarItem","depth","onNavigate","LinkComponent","onItemClick","hasChildren","active","childActive","open","setOpen","Icon","baseClass","content","Fragment","ChevronDown","handleClick","row","MobileSidebar","appName","appLogo","activePathProp","ctxPath","filtered","dialogRef","useRef","previousFocus","previousOverflow","focusable","element","_b","onKey","e","elements","first","last","desktop","_c","onResize","_d","handleNavigate","X","Breadcrumbs","renderLink","isLast","classNames","Home","index","ChevronRight","NavbarSearch","placeholder","onSearch","setQuery","Search","NotificationMenu","notifications","ref","unread","handler","event","Bell","useDarkMode","ThemeToggle","isDark","toggle","Sun","Moon","UserMenu","user","onLogout","onSettings","initials","trigger","entries","current","Settings","User","LogOut","Navbar","searchPlaceholder","showSearch","onMenuClick","onToggleSidebar","Menu","PanelLeftOpen","PanelLeftClose","Sidebar","collapsedProp","ctxCollapsed","AdminLayoutInner","sidebarItems","footer","showFooter","breadcrumbsProp","contentClassName","_enableRouter","ctxBreadcrumbs","resolvedMode","style","AdminLayout","props","enableRouter","rest","initialBc","RouterLink","to","onClick","NavLink","useLayoutState","useBreadcrumbs","update"],"mappings":"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","x_google_ignoreList":[9]}
|
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--admin-bg: #f8fafc;--admin-surface: #ffffff;--admin-border: #e2e8f0;--admin-text: #0f172a;--admin-muted: #64748b;--admin-primary: #2563eb;--admin-primary-hover: #1d4ed8;--admin-sidebar-width: 260px;--admin-sidebar-collapsed: 72px}.dark{--admin-bg: #0b1220;--admin-surface: #111827;--admin-border: #1e293b;--admin-text: #f1f5f9;--admin-muted: #94a3b8;--admin-primary: #3b82f6;--admin-primary-hover: #60a5fa}.admin-layout-root{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.admin-glass{border-width:1px;border-color:var(--admin-border);--tw-backdrop-blur: blur(24px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);background-color:color-mix(in srgb,var(--admin-surface) 88%,transparent)}.pointer-events-none{pointer-events:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.-right-0\.5{right:-.125rem}.-top-0\.5{top:-.125rem}.left-0{left:0}.left-3{left:.75rem}.right-0{right:0}.top-0{top:0}.top-1\/2{top:50%}.top-full{top:100%}.z-40{z-index:40}.z-50{z-index:50}.my-1{margin-top:.25rem;margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.ml-5{margin-left:1.25rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-auto{margin-top:auto}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.flex{display:flex}.inline-flex{display:inline-flex}.hidden{display:none}.h-10{height:2.5rem}.h-16{height:4rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[18px\]{height:18px}.h-full{height:100%}.max-h-72{max-height:18rem}.min-h-screen{min-height:100vh}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-56{width:14rem}.w-8{width:2rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-\[18px\]{width:18px}.w-\[min\(280px\,85vw\)\]{width:min(280px,85vw)}.w-\[var\(--admin-sidebar-collapsed\)\]{width:var(--admin-sidebar-collapsed)}.w-\[var\(--admin-sidebar-width\)\]{width:var(--admin-sidebar-width)}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-4{min-width:1rem}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.animate-fade-in{animation:fadeIn .2s ease-out}@keyframes slideIn{0%{transform:translate(-100%)}to{transform:translate(0)}}.animate-slide-in{animation:slideIn .25s ease-out}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-admin-border{border-color:var(--admin-border)}.bg-admin-bg{background-color:var(--admin-bg)}.bg-admin-primary{background-color:var(--admin-primary)}.bg-admin-surface{background-color:var(--admin-surface)}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-slate-900\/50{background-color:#0f172a80}.bg-white\/20{background-color:#fff3}.object-cover{-o-object-fit:cover;object-fit:cover}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pl-10{padding-left:2.5rem}.pl-2{padding-left:.5rem}.pr-4{padding-right:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-tight{line-height:1.25}.tracking-wider{letter-spacing:.05em}.text-admin-muted{color:var(--admin-muted)}.text-admin-primary{color:var(--admin-primary)}.text-admin-text{color:var(--admin-text)}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.opacity-50{opacity:.5}.shadow-admin{--tw-shadow: 0 1px 3px rgba(15, 23, 42, .06), 0 8px 24px rgba(15, 23, 42, .08);--tw-shadow-colored: 0 1px 3px var(--tw-shadow-color), 0 8px 24px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-admin-lg{--tw-shadow: 0 4px 24px rgba(15, 23, 42, .12);--tw-shadow-colored: 0 4px 24px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.placeholder\:text-admin-muted::-moz-placeholder{color:var(--admin-muted)}.placeholder\:text-admin-muted::placeholder{color:var(--admin-muted)}.hover\:bg-admin-bg:hover{background-color:var(--admin-bg)}.hover\:bg-red-50:hover{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.hover\:text-admin-text:hover{color:var(--admin-text)}.focus\:border-admin-primary:focus{border-color:var(--admin-primary)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-admin-primary:focus-visible{--tw-ring-color: var(--admin-primary)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.dark\:hover\:bg-red-950\/30:hover:is(.dark *){background-color:#450a0a4d}@media(min-width:640px){.sm\:block{display:block}.sm\:flex{display:flex}.sm\:max-w-md{max-width:28rem}.sm\:gap-3{gap:.75rem}}@media(min-width:768px){.md\:block{display:block}}@media(min-width:1024px){.lg\:flex{display:flex}.lg\:inline-flex{display:inline-flex}.lg\:hidden{display:none}.lg\:p-6{padding:1.5rem}.lg\:px-6{padding-left:1.5rem;padding-right:1.5rem}.lg\:pl-\[var\(--admin-sidebar-collapsed\)\]{padding-left:var(--admin-sidebar-collapsed)}.lg\:pl-\[var\(--admin-sidebar-width\)\]{padding-left:var(--admin-sidebar-width)}}
|
|
1
|
+
:root,.ral-layout[data-theme=light]{--ral-primary: #2563eb;--ral-secondary: #7c3aed;--ral-background: #f8fafc;--ral-surface: #ffffff;--ral-text: #0f172a;--ral-text-secondary: #64748b;--ral-sidebar-bg: #ffffff;--ral-sidebar-text: #64748b;--ral-header-bg: #ffffff;--ral-header-text: #0f172a;--ral-hover-bg: #f1f5f9;--ral-hover-text: #0f172a;--ral-active-bg: #2563eb;--ral-active-text: #ffffff;--ral-border: #e2e8f0;--ral-on-primary: #ffffff;--ral-danger: #dc2626;--ral-on-danger: #ffffff;--ral-overlay: rgb(15 23 42 / .5)}.dark,.ral-layout[data-theme=dark]{--ral-primary: #3b82f6;--ral-secondary: #a78bfa;--ral-background: #0b1220;--ral-surface: #111827;--ral-text: #f1f5f9;--ral-text-secondary: #94a3b8;--ral-sidebar-bg: #111827;--ral-sidebar-text: #cbd5e1;--ral-header-bg: #111827;--ral-header-text: #f1f5f9;--ral-hover-bg: #1e293b;--ral-hover-text: #ffffff;--ral-active-bg: #3b82f6;--ral-active-text: #020617;--ral-border: #334155;--ral-on-primary: #020617;--ral-danger: #f87171;--ral-on-danger: #020617;--ral-overlay: rgb(2 6 23 / .7)}:root,.ral-layout{--ral-sidebar-width: 260px;--ral-sidebar-collapsed: 72px;--ral-header-height: 64px;--ral-radius: 10px;--ral-spacing: 24px;--ral-nav-item-height: 44px;--ral-nav-padding: 10px;--ral-nav-gap: 2px;--ral-shadow: 0 1px 3px rgb(15 23 42 / .06), 0 8px 24px rgb(15 23 42 / .08);--ral-shadow-lg: 0 4px 24px rgb(15 23 42 / .12);--ral-active-shadow: var(--ral-shadow)}.ral-layout[data-style=minimal]{--ral-radius: 4px;--ral-spacing: 32px;--ral-nav-item-height: 46px;--ral-nav-padding: 11px;--ral-nav-gap: 4px;--ral-shadow: none;--ral-shadow-lg: none;--ral-active-shadow: inset 3px 0 var(--ral-primary)}.ral-layout[data-style=compact]{--ral-sidebar-width: 220px;--ral-sidebar-collapsed: 60px;--ral-header-height: 52px;--ral-radius: 6px;--ral-spacing: 16px;--ral-nav-item-height: 34px;--ral-nav-padding: 5px;--ral-nav-gap: 1px;--ral-shadow: 0 1px 3px rgb(15 23 42 / .06);--ral-shadow-lg: 0 4px 16px rgb(15 23 42 / .12)}:root,.dark,.ral-layout{--admin-bg: var(--ral-background);--admin-surface: var(--ral-surface);--admin-border: var(--ral-border);--admin-text: var(--ral-text);--admin-muted: var(--ral-text-secondary);--admin-primary: var(--ral-primary);--admin-primary-hover: var(--ral-secondary);--admin-sidebar-width: var(--ral-sidebar-width);--admin-sidebar-collapsed: var(--ral-sidebar-collapsed)}.ral-layout[data-theme=light]{color-scheme:light}.ral-layout[data-theme=dark]{color-scheme:dark}.ral-layout :where(button,a,input,select,textarea):focus-visible{outline:2px solid var(--ral-primary);outline-offset:3px;--tw-ring-offset-color: var(--ral-surface)}.ral-layout,.ral-layout :where(aside,header,footer,button,a,input,[role=menu],.ral-card,.ral-nav-item){transition:background-color .2s ease,color .2s ease,border-color .2s ease}.ral-content{padding:var(--ral-spacing)}.ral-sidebar{background:var(--ral-sidebar-bg);color:var(--ral-sidebar-text)}.ral-sidebar-brand{color:var(--ral-sidebar-text)}.ral-sidebar-top{height:var(--ral-header-height);flex-shrink:0}.ral-sidebar nav{padding:calc(var(--ral-spacing) / 2)}.ral-sidebar-group>ul>li+li{margin-top:var(--ral-nav-gap)}.ral-header{height:var(--ral-header-height);padding-inline:var(--ral-spacing);background:var(--ral-header-bg);color:var(--ral-header-text)}.ral-header>button,.ral-header [aria-label=Breadcrumb]{--admin-muted: var(--ral-header-text);--admin-text: var(--ral-header-text)}.ral-nav-item{min-height:var(--ral-nav-item-height);padding-block:var(--ral-nav-padding);border-radius:var(--ral-radius);color:var(--ral-sidebar-text)}.ral-nav-item:hover{background:var(--ral-hover-bg);color:var(--ral-hover-text)}.ral-nav-item.ral-nav-active{background:var(--ral-active-bg);color:var(--ral-active-text);box-shadow:var(--ral-active-shadow)}.ral-sidebar button:not(.ral-nav-item){color:var(--ral-sidebar-text)}.ral-sidebar button:not(.ral-nav-item):hover{color:var(--ral-hover-text)}.ral-nav-badge{background:color-mix(in srgb,currentColor 15%,transparent);color:inherit}.ral-unread{background:color-mix(in srgb,var(--ral-primary) 8%,var(--ral-surface))}.ral-danger{color:var(--ral-danger)}.ral-danger:hover{background:color-mix(in srgb,var(--ral-danger) 12%,var(--ral-surface))}.ral-overlay{background:var(--ral-overlay)}.ral-card{border:1px solid var(--ral-border);border-radius:var(--ral-radius);padding:var(--ral-spacing);background:var(--ral-surface);box-shadow:var(--ral-shadow)}.ral-layout :where(nav,main,ul){scrollbar-color:var(--ral-border) transparent;scrollbar-width:thin}@media(max-width:639px){.ral-content,.ral-header{padding-inline:min(var(--ral-spacing),16px)}}@media(prefers-reduced-motion:reduce){.ral-layout,.ral-layout *,.ral-layout *:before,.ral-layout *:after{transition:none!important;animation:none!important}}*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.admin-layout-root{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.-right-0\.5{right:-.125rem}.-top-0\.5{top:-.125rem}.left-0{left:0}.left-3{left:.75rem}.right-0{right:0}.top-0{top:0}.top-1\/2{top:50%}.top-full{top:100%}.z-40{z-index:40}.z-50{z-index:50}.my-1{margin-top:.25rem;margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.ml-5{margin-left:1.25rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-auto{margin-top:auto}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.flex{display:flex}.inline-flex{display:inline-flex}.hidden{display:none}.h-10{height:2.5rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[18px\]{height:18px}.h-full{height:100%}.h-screen{height:100vh}.max-h-72{max-height:18rem}.min-h-screen{min-height:100vh}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-56{width:14rem}.w-8{width:2rem}.w-80{width:20rem}.w-9{width:2.25rem}.w-\[18px\]{width:18px}.w-\[min\(var\(--ral-sidebar-width\)\,85vw\)\]{width:min(var(--ral-sidebar-width),85vw)}.w-\[var\(--admin-sidebar-collapsed\)\]{width:var(--admin-sidebar-collapsed)}.w-\[var\(--admin-sidebar-width\)\]{width:var(--admin-sidebar-width)}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-4{min-width:1rem}.max-w-\[calc\(100vw-6rem\)\]{max-width:calc(100vw - 6rem)}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.animate-fade-in{animation:fadeIn .2s ease-out}@keyframes slideIn{0%{transform:translate(-100%)}to{transform:translate(0)}}.animate-slide-in{animation:slideIn .25s ease-out}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rounded-admin{border-radius:var(--ral-radius)}.rounded-full{border-radius:9999px}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-admin-border{border-color:var(--admin-border)}.bg-admin-bg{background-color:var(--admin-bg)}.bg-admin-danger{background-color:var(--ral-danger)}.bg-admin-primary{background-color:var(--admin-primary)}.bg-admin-surface{background-color:var(--admin-surface)}.object-cover{-o-object-fit:cover;object-fit:cover}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pl-10{padding-left:2.5rem}.pl-2{padding-left:.5rem}.pr-4{padding-right:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-tight{line-height:1.25}.tracking-wider{letter-spacing:.05em}.text-admin-muted{color:var(--admin-muted)}.text-admin-on-danger{color:var(--ral-on-danger)}.text-admin-on-primary{color:var(--ral-on-primary)}.text-admin-text{color:var(--admin-text)}.opacity-50{opacity:.5}.shadow-admin{--tw-shadow: var(--ral-shadow);--tw-shadow-colored: var(--ral-shadow);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-admin-lg{--tw-shadow: var(--ral-shadow-lg);--tw-shadow-colored: var(--ral-shadow-lg);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition-\[width\]{transition-property:width;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-300{transition-duration:.3s}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.placeholder\:text-admin-muted::-moz-placeholder{color:var(--admin-muted)}.placeholder\:text-admin-muted::placeholder{color:var(--admin-muted)}.hover\:bg-admin-hover:hover{background-color:var(--ral-hover-bg)}.hover\:text-admin-hover-text:hover{color:var(--ral-hover-text)}.focus\:border-admin-primary:focus{border-color:var(--admin-primary)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-admin-primary:focus{--tw-ring-color: var(--admin-primary)}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-admin-primary:focus-visible{--tw-ring-color: var(--admin-primary)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}@media(min-width:640px){.sm\:block{display:block}.sm\:flex{display:flex}.sm\:max-w-md{max-width:28rem}.sm\:gap-3{gap:.75rem}}@media(min-width:768px){.md\:block{display:block}}@media(min-width:1024px){.lg\:flex{display:flex}.lg\:inline-flex{display:inline-flex}.lg\:hidden{display:none}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rqdhw3n/react-admin-layout",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Production-ready admin dashboard layout for React — sidebar, navbar, dark mode, breadcrumbs, RBAC",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -17,15 +17,28 @@
|
|
|
17
17
|
"default": "./dist/index.cjs"
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
|
-
"./style.css": "./dist/style.css"
|
|
20
|
+
"./style.css": "./dist/style.css",
|
|
21
|
+
"./styles.css": "./dist/style.css"
|
|
21
22
|
},
|
|
22
|
-
"files": [
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"README.md"
|
|
26
|
+
],
|
|
23
27
|
"scripts": {
|
|
28
|
+
"theme:css": "node scripts/generate-theme-css.mjs",
|
|
29
|
+
"prebuild": "npm run theme:css",
|
|
24
30
|
"build": "tsc -p tsconfig.build.json --noEmit && vite build",
|
|
25
31
|
"dev": "vite build --watch",
|
|
26
32
|
"typecheck": "tsc --noEmit",
|
|
27
|
-
"preview:basic": "vite --config examples/
|
|
33
|
+
"preview:basic": "vite --config examples/theming/vite.config.ts",
|
|
34
|
+
"demo": "vite --config examples/theming/vite.config.ts",
|
|
35
|
+
"test": "node --test tests/*.test.mjs",
|
|
36
|
+
"test:browser": "playwright test",
|
|
37
|
+
"verify:package": "node scripts/verify-package.mjs"
|
|
28
38
|
},
|
|
39
|
+
"sideEffects": [
|
|
40
|
+
"**/*.css"
|
|
41
|
+
],
|
|
29
42
|
"peerDependencies": {
|
|
30
43
|
"lucide-react": ">=0.400.0",
|
|
31
44
|
"react": ">=18.0.0",
|
|
@@ -33,13 +46,18 @@
|
|
|
33
46
|
"react-router-dom": ">=6.0.0"
|
|
34
47
|
},
|
|
35
48
|
"peerDependenciesMeta": {
|
|
36
|
-
"react-router-dom": {
|
|
37
|
-
|
|
49
|
+
"react-router-dom": {
|
|
50
|
+
"optional": true
|
|
51
|
+
},
|
|
52
|
+
"framer-motion": {
|
|
53
|
+
"optional": true
|
|
54
|
+
}
|
|
38
55
|
},
|
|
39
56
|
"dependencies": {
|
|
40
57
|
"clsx": "^2.1.1"
|
|
41
58
|
},
|
|
42
59
|
"devDependencies": {
|
|
60
|
+
"@playwright/test": "^1.63.0",
|
|
43
61
|
"@types/react": "^19.1.2",
|
|
44
62
|
"@types/react-dom": "^19.1.2",
|
|
45
63
|
"autoprefixer": "^10.4.21",
|
|
@@ -54,7 +72,16 @@
|
|
|
54
72
|
"vite": "^6.3.5",
|
|
55
73
|
"vite-plugin-dts": "^4.5.3"
|
|
56
74
|
},
|
|
57
|
-
"keywords": [
|
|
75
|
+
"keywords": [
|
|
76
|
+
"react",
|
|
77
|
+
"admin",
|
|
78
|
+
"dashboard",
|
|
79
|
+
"layout",
|
|
80
|
+
"sidebar",
|
|
81
|
+
"tailwind"
|
|
82
|
+
],
|
|
58
83
|
"license": "MIT",
|
|
59
|
-
"publishConfig": {
|
|
84
|
+
"publishConfig": {
|
|
85
|
+
"access": "public"
|
|
86
|
+
}
|
|
60
87
|
}
|