@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/README.md
CHANGED
|
@@ -10,7 +10,8 @@ Production-ready admin dashboard layout for React — sidebar, navbar, dark mode
|
|
|
10
10
|
- Mobile drawer menu
|
|
11
11
|
- Top navbar with search, notifications, user menu
|
|
12
12
|
- Breadcrumbs + auto-generation from route path
|
|
13
|
-
- Dark mode with `localStorage` persistence
|
|
13
|
+
- Dark mode with `localStorage` persistence
|
|
14
|
+
- Light, dark, and live system mode; custom palettes; modern, minimal, and compact styles
|
|
14
15
|
- RBAC permission filtering on sidebar items
|
|
15
16
|
- React Router support (optional peer)
|
|
16
17
|
- Tailwind CSS — modern SaaS aesthetic
|
|
@@ -84,7 +85,281 @@ export default function App() {
|
|
|
84
85
|
}
|
|
85
86
|
```
|
|
86
87
|
|
|
87
|
-
##
|
|
88
|
+
## Theming
|
|
89
|
+
|
|
90
|
+
The optional `theme` prop adds custom colors and three visual styles to the existing layout.
|
|
91
|
+
Keep using `sidebarItems`, `appName`, and the other existing props. Import the stylesheet once:
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
import {
|
|
95
|
+
AdminLayout,
|
|
96
|
+
type AdminLayoutTheme,
|
|
97
|
+
type AdminLayoutThemeMode,
|
|
98
|
+
type AdminLayoutStyle,
|
|
99
|
+
} from '@rqdhw3n/react-admin-layout'
|
|
100
|
+
import '@rqdhw3n/react-admin-layout/styles.css'
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The original `@rqdhw3n/react-admin-layout/style.css` import remains supported and points to the same file.
|
|
104
|
+
Consumers do not need Tailwind installed to use the shipped styles. Tailwind configuration is only
|
|
105
|
+
needed when generating additional utility classes in your own app.
|
|
106
|
+
|
|
107
|
+
### Basic dark mode
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
<AdminLayout sidebarItems={sidebarItems} theme={{ mode: 'dark' }}>
|
|
111
|
+
<YourPage />
|
|
112
|
+
</AdminLayout>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Built-in style
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
<AdminLayout sidebarItems={sidebarItems} theme={{ style: 'compact' }}>
|
|
119
|
+
<YourPage />
|
|
120
|
+
</AdminLayout>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Every style supports every mode and palette:
|
|
124
|
+
|
|
125
|
+
| Style | Sidebar / collapsed | Header | Navigation height | Content spacing | Radius | Appearance |
|
|
126
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
127
|
+
| `modern` (default) | 260 / 72 px | 64 px | 44 px | 24 px | 10 px | Rounded navigation and cards, subtle shadows |
|
|
128
|
+
| `minimal` | 260 / 72 px | 64 px | 46 px | 32 px | 4 px | Flat surfaces, borders, extra whitespace |
|
|
129
|
+
| `compact` | 220 / 60 px | 52 px | 34 px | 16 px | 6 px | Dense navigation and content, smaller header |
|
|
130
|
+
|
|
131
|
+
`adminLayoutPresets.modern`, `.minimal`, and `.compact` are immutable, optional convenience objects:
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
import { adminLayoutPresets } from '@rqdhw3n/react-admin-layout'
|
|
135
|
+
|
|
136
|
+
<AdminLayout sidebarItems={sidebarItems} theme={{
|
|
137
|
+
...adminLayoutPresets.modern,
|
|
138
|
+
colors: { primary: '#15803d', activeText: '#ffffff', onPrimary: '#ffffff' },
|
|
139
|
+
}}>
|
|
140
|
+
<YourPage />
|
|
141
|
+
</AdminLayout>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Custom colors
|
|
145
|
+
|
|
146
|
+
```tsx
|
|
147
|
+
<AdminLayout sidebarItems={sidebarItems} theme={{
|
|
148
|
+
colors: {
|
|
149
|
+
primary: '#7c3aed',
|
|
150
|
+
activeText: '#ffffff',
|
|
151
|
+
onPrimary: '#ffffff',
|
|
152
|
+
sidebarBackground: '#111827',
|
|
153
|
+
sidebarText: '#cbd5e1',
|
|
154
|
+
},
|
|
155
|
+
}}>
|
|
156
|
+
<YourPage />
|
|
157
|
+
</AdminLayout>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
All colors accept CSS color values, including CSS variables. Default text/foreground pairs meet
|
|
161
|
+
4.5:1 contrast. When providing custom backgrounds, choose readable matching foregrounds:
|
|
162
|
+
`sidebarText`, `headerText`, `hoverText`, `activeText`, `onPrimary`, and `onDanger`.
|
|
163
|
+
The library does not infer contrast for arbitrary CSS colors.
|
|
164
|
+
|
|
165
|
+
### Custom light/dark
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
<AdminLayout sidebarItems={sidebarItems} theme={{
|
|
169
|
+
mode: 'system',
|
|
170
|
+
light: { primary: '#2563eb' },
|
|
171
|
+
dark: { primary: '#60a5fa', activeText: '#0f172a', onPrimary: '#0f172a' },
|
|
172
|
+
}}>
|
|
173
|
+
<YourPage />
|
|
174
|
+
</AdminLayout>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Resolution order is **selected built-in light/dark palette → `colors` → selected `light` or `dark` overrides**.
|
|
178
|
+
Missing, `undefined`, and empty color values retain the earlier value. An overridden `primary` also
|
|
179
|
+
sets `activeBackground` unless an explicit `activeBackground` override exists. Other color slots
|
|
180
|
+
remain independent. Neither the input configuration nor the built-in defaults are mutated.
|
|
181
|
+
|
|
182
|
+
### Runtime switching and the existing toggle
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
import { useState } from 'react'
|
|
186
|
+
import { AdminLayout, type AdminLayoutThemeMode } from '@rqdhw3n/react-admin-layout'
|
|
187
|
+
|
|
188
|
+
function App() {
|
|
189
|
+
const [mode, setMode] = useState<AdminLayoutThemeMode>('system')
|
|
190
|
+
return (
|
|
191
|
+
<AdminLayout
|
|
192
|
+
sidebarItems={sidebarItems}
|
|
193
|
+
theme={{ mode, style: 'modern' }}
|
|
194
|
+
onThemeModeChange={setMode}
|
|
195
|
+
>
|
|
196
|
+
<YourPage />
|
|
197
|
+
</AdminLayout>
|
|
198
|
+
)
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
An explicit `theme.mode` is **controlled**: it always wins over storage and `initialDarkMode`.
|
|
203
|
+
Prop changes apply immediately. Connect `onThemeModeChange` to update parent state when the
|
|
204
|
+
built-in `ThemeToggle`, `useDarkMode()`, or new hook requests a mode. Without that callback,
|
|
205
|
+
the controlled mode stays fixed. Toggling from system selects the opposite of the effective mode.
|
|
206
|
+
|
|
207
|
+
When `theme.mode` is omitted, the layout manages and persists the mode internally under the
|
|
208
|
+
existing `storageKey`. Existing stored `darkMode` values and `initialDarkMode` still work;
|
|
209
|
+
the saved state now also supports `mode: 'system'`. Controlled modes do not overwrite the
|
|
210
|
+
saved uncontrolled preference. Use distinct storage keys for independent layout preferences.
|
|
211
|
+
|
|
212
|
+
```tsx
|
|
213
|
+
import { useAdminLayoutTheme } from '@rqdhw3n/react-admin-layout'
|
|
214
|
+
|
|
215
|
+
function FollowSystemButton() {
|
|
216
|
+
const { mode, resolvedMode, style, colors, setMode } = useAdminLayoutTheme()
|
|
217
|
+
return <button onClick={() => setMode('system')}>Follow system ({resolvedMode})</button>
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Render this hook beneath `AdminLayout` or `LayoutProvider`. `mode` is the requested mode;
|
|
222
|
+
`resolvedMode` is always `light` or `dark`. The existing `useDarkMode()` API is unchanged.
|
|
223
|
+
System mode subscribes to `prefers-color-scheme` changes and cleans up its listener. Server
|
|
224
|
+
rendering uses light for system mode; hydration then reads the OS preference and stored state.
|
|
225
|
+
Blocked storage and unavailable `matchMedia` are handled safely.
|
|
226
|
+
|
|
227
|
+
### Public TypeScript API
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
export type AdminLayoutThemeMode = 'light' | 'dark' | 'system'
|
|
231
|
+
export type AdminLayoutResolvedMode = 'light' | 'dark'
|
|
232
|
+
export type AdminLayoutStyle = 'modern' | 'minimal' | 'compact'
|
|
233
|
+
|
|
234
|
+
export interface AdminLayoutColors {
|
|
235
|
+
primary?: string
|
|
236
|
+
secondary?: string
|
|
237
|
+
background?: string
|
|
238
|
+
surface?: string
|
|
239
|
+
text?: string
|
|
240
|
+
textSecondary?: string
|
|
241
|
+
sidebarBackground?: string
|
|
242
|
+
sidebarText?: string
|
|
243
|
+
headerBackground?: string
|
|
244
|
+
headerText?: string
|
|
245
|
+
hoverBackground?: string
|
|
246
|
+
hoverText?: string
|
|
247
|
+
activeBackground?: string
|
|
248
|
+
activeText?: string
|
|
249
|
+
border?: string
|
|
250
|
+
onPrimary?: string
|
|
251
|
+
danger?: string
|
|
252
|
+
onDanger?: string
|
|
253
|
+
overlay?: string
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export interface AdminLayoutTheme {
|
|
257
|
+
mode?: AdminLayoutThemeMode
|
|
258
|
+
style?: AdminLayoutStyle
|
|
259
|
+
colors?: AdminLayoutColors
|
|
260
|
+
light?: AdminLayoutColors
|
|
261
|
+
dark?: AdminLayoutColors
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
`AdminLayoutProps` and `LayoutProviderProps` add `theme?: AdminLayoutTheme` and
|
|
266
|
+
`onThemeModeChange?: (mode: AdminLayoutThemeMode) => void`. All existing props remain.
|
|
267
|
+
Also exported: `ResolvedAdminLayoutTheme`, `lightThemeColors`, `darkThemeColors`,
|
|
268
|
+
`adminLayoutPresets`, `resolveTheme(theme?, systemMode?)`, and `themeToCSSVariables(resolvedTheme)`.
|
|
269
|
+
The pure resolver defaults its system-mode argument to light; automatic OS tracking belongs to the provider.
|
|
270
|
+
|
|
271
|
+
### CSS variables and scope
|
|
272
|
+
|
|
273
|
+
The root exposes `.ral-layout.admin-layout-root`, `data-theme="light|dark"`, and
|
|
274
|
+
`data-style="modern|minimal|compact"`. Palette variables are applied once at that boundary.
|
|
275
|
+
Layouts with an explicit theme have independent colors and density, including nested layouts.
|
|
276
|
+
The `.dark` class is also present on dark layout roots for existing descendant Tailwind utilities.
|
|
277
|
+
For backward compatibility, **only layouts without any `theme` prop** still synchronize the
|
|
278
|
+
document's `.dark` class. Use `theme={{}}` to opt into scoped theming with an uncontrolled toggle.
|
|
279
|
+
|
|
280
|
+
| Palette fields | CSS variables |
|
|
281
|
+
| --- | --- |
|
|
282
|
+
| `primary`, `secondary` | `--ral-primary`, `--ral-secondary` |
|
|
283
|
+
| `background`, `surface` | `--ral-background`, `--ral-surface` |
|
|
284
|
+
| `text`, `textSecondary` | `--ral-text`, `--ral-text-secondary` |
|
|
285
|
+
| `sidebarBackground`, `sidebarText` | `--ral-sidebar-bg`, `--ral-sidebar-text` |
|
|
286
|
+
| `headerBackground`, `headerText` | `--ral-header-bg`, `--ral-header-text` |
|
|
287
|
+
| `hoverBackground`, `hoverText` | `--ral-hover-bg`, `--ral-hover-text` |
|
|
288
|
+
| `activeBackground`, `activeText` | `--ral-active-bg`, `--ral-active-text` |
|
|
289
|
+
| `border`, `onPrimary` | `--ral-border`, `--ral-on-primary` |
|
|
290
|
+
| `danger`, `onDanger`, `overlay` | `--ral-danger`, `--ral-on-danger`, `--ral-overlay` |
|
|
291
|
+
|
|
292
|
+
Density tokens include `--ral-sidebar-width`, `--ral-sidebar-collapsed`, `--ral-header-height`,
|
|
293
|
+
`--ral-radius`, `--ral-spacing`, `--ral-nav-item-height`, and `--ral-shadow`.
|
|
294
|
+
Existing `--admin-*` variables remain as aliases. The optional `.ral-card` class gives consumer
|
|
295
|
+
cards the selected surface, border, radius, padding, and shadow. Other consumer components
|
|
296
|
+
must use these variables or their own theme integration; arbitrary child markup is not restyled.
|
|
297
|
+
|
|
298
|
+
```css
|
|
299
|
+
.ral-layout.my-layout { --ral-sidebar-width: 280px; }
|
|
300
|
+
.my-card { background: var(--ral-surface); color: var(--ral-text); border: 1px solid var(--ral-border); }
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Use `className="my-layout"` on `AdminLayout` and load your overrides after the package CSS.
|
|
304
|
+
Transitions respect `prefers-reduced-motion`. Keyboard focus remains visible, nested navigation
|
|
305
|
+
works when collapsed, user menu supports arrow keys/Escape, and the mobile drawer traps and restores focus.
|
|
306
|
+
|
|
307
|
+
### Demo and verification
|
|
308
|
+
|
|
309
|
+
Development scripts require Node.js 22.18+ (native TypeScript stripping for the CSS generator).
|
|
310
|
+
This is a contributor requirement; the published package contains compiled JavaScript.
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
npm install
|
|
314
|
+
npm run build
|
|
315
|
+
npm run demo
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Open `http://127.0.0.1:4173`. The demo includes light/dark/system, modern/minimal/compact,
|
|
319
|
+
default/indigo/blue/green/rose/orange palettes, separate mode palettes, and custom sidebar/header
|
|
320
|
+
colors. It consumes public package exports. `/?legacy` exercises the old uncontrolled API;
|
|
321
|
+
`/?isolation` demonstrates independent nested layouts.
|
|
322
|
+
|
|
323
|
+
```bash
|
|
324
|
+
npm run typecheck
|
|
325
|
+
npm test
|
|
326
|
+
npm run verify:package
|
|
327
|
+
npx playwright install chromium
|
|
328
|
+
npm run test:browser
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
`verify:package` packs the local build, installs that tarball into an isolated Vite app under
|
|
332
|
+
`.tmp`, checks every export target, compiles ESM/CommonJS type consumers, and builds the demo.
|
|
333
|
+
The browser suite then runs that installed app, including screenshots in `test-results`.
|
|
334
|
+
It tests with React 18 and React Router 6; the library's development build uses Router 7.
|
|
335
|
+
On Windows, an existing Edge installation can be used instead of downloading Chromium:
|
|
336
|
+
|
|
337
|
+
```powershell
|
|
338
|
+
$env:PLAYWRIGHT_CHANNEL = 'msedge'
|
|
339
|
+
npm.cmd run test:browser
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Publishing (manual)
|
|
343
|
+
|
|
344
|
+
No automatic publishing is configured. For the next minor release from the existing 1.0.1:
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
npm version minor --no-git-tag-version
|
|
348
|
+
npm install
|
|
349
|
+
npm run build
|
|
350
|
+
npm run typecheck
|
|
351
|
+
npm test
|
|
352
|
+
npm run verify:package
|
|
353
|
+
npm run test:browser
|
|
354
|
+
npm pack --dry-run
|
|
355
|
+
npm login
|
|
356
|
+
npm publish --access public
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
Use `npm.cmd` on Windows if PowerShell blocks `npm.ps1`. The package name remains
|
|
360
|
+
`@rqdhw3n/react-admin-layout`; the version is left unchanged until you run the release commands.
|
|
361
|
+
|
|
362
|
+
## React Router
|
|
88
363
|
|
|
89
364
|
```tsx
|
|
90
365
|
import { BrowserRouter, Routes, Route } from 'react-router-dom'
|
|
@@ -113,7 +388,8 @@ function App() {
|
|
|
113
388
|
| Hook | Description |
|
|
114
389
|
|------|-------------|
|
|
115
390
|
| `useSidebar()` | Collapsed state, mobile drawer |
|
|
116
|
-
| `useDarkMode()` | Theme toggle |
|
|
391
|
+
| `useDarkMode()` | Theme toggle |
|
|
392
|
+
| `useAdminLayoutTheme()` | Requested/effective mode, palette, style, mode setter |
|
|
117
393
|
| `useLayoutState()` | Full layout context |
|
|
118
394
|
| `useBreadcrumbs()` | Breadcrumb items |
|
|
119
395
|
|
|
@@ -134,7 +410,8 @@ permissions={{ users: ['view', 'create'], roles: ['view'] }}
|
|
|
134
410
|
|
|
135
411
|
- [`examples/basic/App.example.tsx`](./examples/basic/App.example.tsx)
|
|
136
412
|
- [`examples/dark-mode/App.example.tsx`](./examples/dark-mode/App.example.tsx)
|
|
137
|
-
- [`examples/sidebar-collapse/App.example.tsx`](./examples/sidebar-collapse/App.example.tsx)
|
|
413
|
+
- [`examples/sidebar-collapse/App.example.tsx`](./examples/sidebar-collapse/App.example.tsx)
|
|
414
|
+
- [`examples/theming/App.tsx`](./examples/theming/App.tsx)
|
|
138
415
|
|
|
139
416
|
## Build (library)
|
|
140
417
|
|
|
@@ -147,7 +424,8 @@ Outputs:
|
|
|
147
424
|
|
|
148
425
|
- `dist/index.js` (ESM)
|
|
149
426
|
- `dist/index.cjs` (CJS)
|
|
150
|
-
- `dist/index.d.ts`
|
|
427
|
+
- `dist/index.d.ts`
|
|
428
|
+
- `dist/index.d.cts` (CommonJS declarations)
|
|
151
429
|
- `dist/style.css`
|
|
152
430
|
|
|
153
431
|
## Peer dependencies
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),u=require("react"),T=require("react-router-dom"),x=require("lucide-react");function re(t){if(typeof window>"u")return{};try{const a=localStorage.getItem(t);return a?JSON.parse(a):{}}catch{return{}}}function ne(t,a){if(!(typeof window>"u"))try{localStorage.setItem(t,JSON.stringify(a))}catch{}}const U=u.createContext(null);function $({children:t,storageKey:a="rqdhw3n-admin-layout",defaultCollapsed:s=!1,permissions:r={},initialBreadcrumbs:l=[],initialActivePath:i="/",initialDarkMode:n}){const d=re(a),[o,b]=u.useState(d.sidebarCollapsed??s),[f,v]=u.useState(!1),[h,c]=u.useState(d.darkMode??n??!1),[p,N]=u.useState(l),[S,g]=u.useState(i);u.useEffect(()=>{ne(a,{sidebarCollapsed:o,darkMode:h})},[a,o,h]),u.useEffect(()=>{const y=document.documentElement;h?y.classList.add("dark"):y.classList.remove("dark")},[h]);const k=u.useCallback(()=>b(y=>!y),[]),j=u.useCallback(()=>v(y=>!y),[]),C=u.useCallback(()=>c(y=>!y),[]),A=u.useMemo(()=>({sidebarCollapsed:o,mobileOpen:f,darkMode:h,toggleSidebar:k,setSidebarCollapsed:b,toggleMobile:j,setMobileOpen:v,toggleDarkMode:C,setDarkMode:c,permissions:r,breadcrumbs:p,setBreadcrumbs:N,activePath:S,setActivePath:g}),[o,f,h,k,j,C,r,p,S]);return e.jsx(U.Provider,{value:A,children:t})}function w(){const t=u.useContext(U);if(!t)throw new Error("useLayoutContext must be used within LayoutProvider / AdminLayout");return t}function M(){const{sidebarCollapsed:t,mobileOpen:a,toggleSidebar:s,setSidebarCollapsed:r,toggleMobile:l,setMobileOpen:i}=w();return{collapsed:t,mobileOpen:a,toggle:s,setCollapsed:r,toggleMobile:l,setMobileOpen:i,closeMobile:()=>i(!1)}}function P(t){const a=t.split("/").filter(Boolean);return a.length?a.map((s,r)=>{const l="/"+a.slice(0,r+1).join("/");return{label:s.replace(/-/g," ").replace(/\b\w/g,n=>n.toUpperCase()),path:r<a.length-1?l:void 0}}):[{label:"Home",path:"/"}]}function z(t){var a,s,r="";if(typeof t=="string"||typeof t=="number")r+=t;else if(typeof t=="object")if(Array.isArray(t)){var l=t.length;for(a=0;a<l;a++)t[a]&&(s=z(t[a]))&&(r&&(r+=" "),r+=s)}else for(s in t)t[s]&&(r&&(r+=" "),r+=s);return r}function ie(){for(var t,a,s=0,r="",l=arguments.length;s<l;s++)(t=arguments[s])&&(a=z(t))&&(r&&(r+=" "),r+=a);return r}function m(...t){return ie(t)}function G({children:t}){const{pathname:a}=T.useLocation(),{setActivePath:s,setBreadcrumbs:r,breadcrumbs:l}=w();return u.useEffect(()=>{s(a),l.length||r(P(a))},[a,s,r,l.length]),e.jsx(e.Fragment,{children:t})}function H({children:t,className:a}){return e.jsx("footer",{className:m("mt-auto border-t border-admin-border bg-admin-surface px-6 py-4 text-sm text-admin-muted",a),children:t??e.jsxs("p",{className:"text-center",children:["© ",new Date().getFullYear()," Admin Layout · Built with @rqdhw3n/react-admin-layout"]})})}function le(t){const a=t.indexOf(".");return a===-1?{resource:t,action:"view"}:{resource:t.slice(0,a),action:t.slice(a+1)}}function J(t,a){if(!a)return!0;const{resource:s,action:r}=le(a),l=t[s];return l!=null&&l.length?l.includes(r)||l.includes("*"):!1}function L(t,a){return t.filter(s=>J(a,s.permission)).map(s=>({...s,children:s.children?L(s.children,a):void 0})).filter(s=>{var r;return!((r=s.children)!=null&&r.length)||s.children.length>0||s.path})}function O({label:t,children:a,collapsed:s,className:r}){return e.jsxs("div",{className:m("mb-4",r),children:[t&&!s&&e.jsx("p",{className:"mb-2 px-3 text-[11px] font-semibold uppercase tracking-wider text-admin-muted",children:t}),e.jsx("ul",{className:"space-y-0.5",children:a})]})}function q(t,a){return t?a===t||a.startsWith(`${t}/`):!1}function B({item:t,collapsed:a=!1,depth:s=0,activePath:r="/",onNavigate:l,LinkComponent:i,onItemClick:n}){var g,k;const d=!!((g=t.children)!=null&&g.length),o=t.path?q(t.path,r):!1,b=(k=t.children)==null?void 0:k.some(j=>j.path&&q(j.path,r)),[f,v]=u.useState(o||b),h=t.icon,c=m("group flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-all duration-200","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-admin-primary",o||b?"bg-admin-primary text-white shadow-sm":"text-admin-muted hover:bg-admin-bg hover:text-admin-text",t.disabled&&"pointer-events-none opacity-50",s>0&&"text-[13px] py-2"),p=e.jsxs(e.Fragment,{children:[h&&e.jsx(h,{className:m("h-[18px] w-[18px] shrink-0",o||b?"text-white":""),"aria-hidden":!0}),!a&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"flex-1 truncate text-left",children:t.label}),t.badge!=null&&e.jsx("span",{className:m("rounded-full px-2 py-0.5 text-[11px] font-semibold",o?"bg-white/20 text-white":"bg-admin-primary/10 text-admin-primary"),children:t.badge}),d&&e.jsx(x.ChevronDown,{className:m("h-4 w-4 shrink-0 transition-transform",f&&"rotate-180"),"aria-hidden":!0})]})]}),N=()=>{if(d){v(j=>!j);return}t.path&&(l==null||l(t.path),n==null||n())},S=t.path&&!d&&i?e.jsx(i,{to:t.path,className:c,onClick:()=>{n==null||n()},children:p}):e.jsx("button",{type:"button",className:c,onClick:N,disabled:t.disabled,children:p});return e.jsxs("li",{children:[S,d&&f&&!a&&e.jsx("ul",{className:"mt-1 space-y-0.5 border-l border-admin-border ml-5 pl-2",children:t.children.map(j=>e.jsx(B,{item:j,collapsed:a,depth:s+1,activePath:r,onNavigate:l,LinkComponent:i,onItemClick:n},j.label+(j.path??"")))})]})}function Q({items:t,appName:a="Admin",appLogo:s,onNavigate:r,activePath:l,LinkComponent:i}){const{mobileOpen:n,closeMobile:d}=M(),{permissions:o,activePath:b}=w(),f=l??b,v=L(t,o);if(u.useEffect(()=>{if(!n)return;const c=p=>{p.key==="Escape"&&d()};return document.addEventListener("keydown",c),document.body.style.overflow="hidden",()=>{document.removeEventListener("keydown",c),document.body.style.overflow=""}},[n,d]),!n)return null;const h=c=>{r==null||r(c),d()};return e.jsxs("div",{className:"fixed inset-0 z-50 lg:hidden",role:"dialog","aria-modal":"true",children:[e.jsx("button",{type:"button",className:"absolute inset-0 bg-slate-900/50 backdrop-blur-sm animate-fade-in","aria-label":"Close menu",onClick:d}),e.jsxs("aside",{className:m("absolute left-0 top-0 flex h-full w-[min(280px,85vw)] flex-col","border-r border-admin-border bg-admin-surface shadow-admin-lg animate-slide-in"),children:[e.jsxs("div",{className:"flex h-16 items-center justify-between border-b border-admin-border px-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[s??e.jsx("div",{className:"flex h-9 w-9 items-center justify-center rounded-xl bg-admin-primary text-sm font-bold text-white",children:a.charAt(0)}),e.jsx("span",{className:"font-semibold text-admin-text",children:a})]}),e.jsx("button",{type:"button",onClick:d,className:"rounded-lg p-2 text-admin-muted hover:bg-admin-bg","aria-label":"Close sidebar",children:e.jsx(x.X,{className:"h-5 w-5"})})]}),e.jsx("nav",{className:"flex-1 overflow-y-auto p-3",children:e.jsx(O,{children:v.map(c=>e.jsx(B,{item:c,activePath:f,onNavigate:h,LinkComponent:i,onItemClick:d},c.label+(c.path??"")))})})]})]})}function W({items:t,className:a,LinkComponent:s,onNavigate:r}){if(!t.length)return null;const l=(i,n)=>{const d=m("text-sm transition-colors",n?"font-medium text-admin-text":"text-admin-muted hover:text-admin-text");return!i.path||n?e.jsx("span",{className:d,children:i.label}):s?e.jsx(s,{to:i.path,className:d,children:i.label}):e.jsx("button",{type:"button",className:d,onClick:()=>r==null?void 0:r(i.path),children:i.label})};return e.jsxs("nav",{"aria-label":"Breadcrumb",className:m("flex items-center gap-1.5",a),children:[e.jsx(x.Home,{className:"h-4 w-4 text-admin-muted shrink-0","aria-hidden":!0}),t.map((i,n)=>{const d=n===t.length-1;return e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx(x.ChevronRight,{className:"h-3.5 w-3.5 text-admin-muted","aria-hidden":!0}),l(i,d)]},`${i.label}-${n}`)})]})}function X({placeholder:t="Search...",onSearch:a,className:s}){const[r,l]=u.useState(""),i=n=>{n.preventDefault(),a==null||a(r.trim())};return e.jsxs("form",{onSubmit:i,className:m("relative w-full max-w-md",s),children:[e.jsx(x.Search,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-admin-muted","aria-hidden":!0}),e.jsx("input",{type:"search",value:r,onChange:n=>l(n.target.value),placeholder:t,className:m("h-10 w-full rounded-xl border border-admin-border bg-admin-bg pl-10 pr-4 text-sm text-admin-text","placeholder:text-admin-muted focus:border-admin-primary focus:outline-none focus:ring-2 focus:ring-admin-primary/20"),"aria-label":"Search"})]})}function Y({notifications:t=[],className:a}){const[s,r]=u.useState(!1),l=u.useRef(null),i=t.filter(n=>!n.read).length;return u.useEffect(()=>{const n=d=>{l.current&&!l.current.contains(d.target)&&r(!1)};return document.addEventListener("mousedown",n),()=>document.removeEventListener("mousedown",n)},[]),e.jsxs("div",{ref:l,className:m("relative",a),children:[e.jsxs("button",{type:"button",onClick:()=>r(n=>!n),className:m("relative inline-flex h-9 w-9 items-center justify-center rounded-lg border border-admin-border","bg-admin-surface text-admin-muted transition-colors hover:bg-admin-bg hover:text-admin-text","focus-visible:ring-2 focus-visible:ring-admin-primary"),"aria-label":`Notifications${i?`, ${i} unread`:""}`,"aria-expanded":s,children:[e.jsx(x.Bell,{className:"h-4 w-4","aria-hidden":!0}),i>0&&e.jsx("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",children:i>9?"9+":i})]}),s&&e.jsxs("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",children:[e.jsx("div",{className:"border-b border-admin-border px-4 py-3",children:e.jsx("p",{className:"text-sm font-semibold text-admin-text",children:"Notifications"})}),e.jsx("ul",{className:"max-h-72 overflow-y-auto p-2",children:t.length===0?e.jsx("li",{className:"px-3 py-6 text-center text-sm text-admin-muted",children:"No notifications"}):t.map(n=>e.jsxs("li",{className:m("rounded-lg px-3 py-2.5 transition-colors hover:bg-admin-bg",!n.read&&"bg-admin-primary/5"),children:[e.jsx("p",{className:"text-sm font-medium text-admin-text",children:n.title}),n.description&&e.jsx("p",{className:"mt-0.5 text-xs text-admin-muted line-clamp-2",children:n.description}),n.time&&e.jsx("p",{className:"mt-1 text-[11px] text-admin-muted",children:n.time})]},n.id))})]})]})}function _(){const{darkMode:t,toggleDarkMode:a,setDarkMode:s}=w();return{isDark:t,toggle:a,setDarkMode:s}}function K({className:t}){const{isDark:a,toggle:s}=_();return e.jsx("button",{type:"button",onClick:s,className:m("inline-flex h-9 w-9 items-center justify-center rounded-lg border border-admin-border","bg-admin-surface text-admin-muted transition-colors hover:bg-admin-bg hover:text-admin-text","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-admin-primary focus-visible:ring-offset-2",t),"aria-label":a?"Switch to light mode":"Switch to dark mode",children:a?e.jsx(x.Sun,{className:"h-4 w-4","aria-hidden":!0}):e.jsx(x.Moon,{className:"h-4 w-4","aria-hidden":!0})})}function V({user:t,onLogout:a,onSettings:s,className:r}){const[l,i]=u.useState(!1),n=u.useRef(null);u.useEffect(()=>{const o=b=>{n.current&&!n.current.contains(b.target)&&i(!1)};return document.addEventListener("mousedown",o),()=>document.removeEventListener("mousedown",o)},[]);const d=t.name.split(" ").map(o=>o[0]).join("").slice(0,2).toUpperCase();return e.jsxs("div",{ref:n,className:m("relative",r),children:[e.jsxs("button",{type:"button",onClick:()=>i(o=>!o),className:m("flex items-center gap-2 rounded-xl border border-admin-border bg-admin-surface px-2 py-1.5","transition-colors hover:bg-admin-bg focus-visible:ring-2 focus-visible:ring-admin-primary"),"aria-expanded":l,"aria-haspopup":"menu",children:[t.avatar?e.jsx("img",{src:t.avatar,alt:"",className:"h-8 w-8 rounded-lg object-cover"}):e.jsx("div",{className:"flex h-8 w-8 items-center justify-center rounded-lg bg-admin-primary text-xs font-semibold text-white",children:d}),e.jsxs("div",{className:"hidden text-left sm:block",children:[e.jsx("p",{className:"text-sm font-medium text-admin-text leading-tight",children:t.name}),e.jsx("p",{className:"text-xs text-admin-muted leading-tight",children:t.email})]}),e.jsx(x.ChevronDown,{className:"hidden h-4 w-4 text-admin-muted sm:block","aria-hidden":!0})]}),l&&e.jsxs("div",{role:"menu",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",children:[e.jsxs("button",{type:"button",role:"menuitem",className:"flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-admin-text hover:bg-admin-bg",onClick:()=>{s==null||s(),i(!1)},children:[e.jsx(x.Settings,{className:"h-4 w-4 text-admin-muted"}),"Settings"]}),e.jsxs("button",{type:"button",role:"menuitem",className:"flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm text-admin-text hover:bg-admin-bg",children:[e.jsx(x.User,{className:"h-4 w-4 text-admin-muted"}),"Profile"]}),e.jsx("hr",{className:"my-1 border-admin-border"}),e.jsxs("button",{type:"button",role:"menuitem",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",onClick:()=>{a==null||a(),i(!1)},children:[e.jsx(x.LogOut,{className:"h-4 w-4"}),"Log out"]})]})]})}function Z({user:t,notifications:a=[],onSearch:s,searchPlaceholder:r="Search...",showSearch:l=!0,className:i,breadcrumbs:n=[],onMenuClick:d,sidebarCollapsed:o,onToggleSidebar:b}){return e.jsxs("header",{className:m("sticky top-0 z-40 flex h-16 shrink-0 items-center gap-4 border-b border-admin-border","admin-glass bg-admin-surface px-4 lg:px-6",i),children:[e.jsx("button",{type:"button",className:"rounded-lg p-2 text-admin-muted hover:bg-admin-bg lg:hidden",onClick:d,"aria-label":"Open menu",children:e.jsx(x.Menu,{className:"h-5 w-5"})}),e.jsx("button",{type:"button",className:"hidden rounded-lg p-2 text-admin-muted hover:bg-admin-bg lg:inline-flex",onClick:b,"aria-label":o?"Expand sidebar":"Collapse sidebar",children:o?e.jsx(x.PanelLeftOpen,{className:"h-5 w-5"}):e.jsx(x.PanelLeftClose,{className:"h-5 w-5"})}),e.jsx("div",{className:"hidden min-w-0 flex-1 md:block",children:e.jsx(W,{items:n})}),e.jsxs("div",{className:"flex flex-1 items-center justify-end gap-2 sm:gap-3",children:[l&&e.jsx("div",{className:"hidden flex-1 sm:flex sm:max-w-md",children:e.jsx(X,{placeholder:r,onSearch:s})}),e.jsx(K,{}),e.jsx(Y,{notifications:a}),t&&e.jsx(V,{user:t})]})]})}function I({items:t,collapsed:a,appName:s="Admin",appLogo:r,className:l,onNavigate:i,activePath:n,LinkComponent:d}){const{collapsed:o,toggle:b,closeMobile:f}=M(),{permissions:v,activePath:h}=w(),c=a??o,p=n??h,N=L(t,v),S=g=>{i==null||i(g),f()};return e.jsxs("aside",{className:m("hidden lg:flex flex-col border-r border-admin-border bg-admin-surface transition-all duration-300 ease-in-out",c?"w-[var(--admin-sidebar-collapsed)]":"w-[var(--admin-sidebar-width)]",l),"aria-label":"Sidebar navigation",children:[e.jsxs("div",{className:m("flex h-16 items-center border-b border-admin-border px-4",c?"justify-center":"justify-between gap-2"),children:[e.jsxs("div",{className:m("flex items-center gap-3 min-w-0",c&&"justify-center"),children:[r??e.jsx("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",children:s.charAt(0)}),!c&&e.jsx("span",{className:"truncate text-base font-semibold text-admin-text",children:s})]}),!c&&e.jsx("button",{type:"button",onClick:b,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","aria-label":"Collapse sidebar",children:e.jsx(x.PanelLeftClose,{className:"h-4 w-4"})})]}),c&&e.jsx("div",{className:"flex justify-center py-2 border-b border-admin-border",children:e.jsx("button",{type:"button",onClick:b,className:"rounded-lg p-2 text-admin-muted hover:bg-admin-bg","aria-label":"Expand sidebar",children:e.jsx(x.PanelLeftOpen,{className:"h-4 w-4"})})}),e.jsx("nav",{className:"flex-1 overflow-y-auto p-3",children:e.jsx(O,{collapsed:c,children:N.map(g=>e.jsx(B,{item:g,collapsed:c,activePath:p,onNavigate:S,LinkComponent:d},g.label+(g.path??"")))})})]})}function F({children:t,sidebarItems:a,appName:s="Admin",appLogo:r,user:l,notifications:i=[],footer:n,showFooter:d=!0,showSearch:o=!0,searchPlaceholder:b,onSearch:f,breadcrumbs:v,contentClassName:h,activePath:c,onNavigate:p,LinkComponent:N,enableRouter:S=!1}){const{sidebarCollapsed:g,toggleSidebar:k,toggleMobile:j,breadcrumbs:C,setBreadcrumbs:A,activePath:y,setActivePath:ee}=w(),{closeMobile:te}=M(),D=c??y,ae=v??C,R=E=>{ee(E),v||A(P(E)),p==null||p(E),te()},se=g?"lg:pl-[var(--admin-sidebar-collapsed)]":"lg:pl-[var(--admin-sidebar-width)]";return e.jsxs("div",{className:"admin-layout-root min-h-screen bg-admin-bg text-admin-text",children:[e.jsx(I,{items:a,appName:s,appLogo:r,activePath:D,onNavigate:R,LinkComponent:N}),e.jsx(Q,{items:a,appName:s,appLogo:r,activePath:D,onNavigate:R,LinkComponent:N}),e.jsxs("div",{className:m("flex min-h-screen flex-col transition-all duration-300",se),children:[e.jsx(Z,{user:l,notifications:i,onSearch:f,searchPlaceholder:b,showSearch:o,breadcrumbs:ae,onMenuClick:j,sidebarCollapsed:g,onToggleSidebar:k}),e.jsx("main",{className:m("flex-1 p-4 lg:p-6",h),children:t}),d&&e.jsx(H,{children:n})]})]})}function de(t){const{storageKey:a="rqdhw3n-admin-layout",defaultCollapsed:s=!1,initialDarkMode:r=!1,permissions:l={},breadcrumbs:i=[],activePath:n="/",enableRouter:d=!1,children:o,...b}=t,f=u.useMemo(()=>i.length?i:P(n),[i,n]);return e.jsx($,{storageKey:a,defaultCollapsed:s,permissions:l,initialBreadcrumbs:f,initialActivePath:n,initialDarkMode:r,children:d?e.jsx(G,{children:e.jsx(F,{...b,enableRouter:d,children:o})}):e.jsx(F,{...b,enableRouter:d,children:o})})}function oe({to:t,className:a,children:s,onClick:r}){return e.jsx(T.NavLink,{to:t,className:a,onClick:r,children:s})}function ce(){return w()}function ue(){const{breadcrumbs:t,setBreadcrumbs:a}=w(),s=u.useCallback(r=>a(r),[a]);return{items:t,setBreadcrumbs:s}}exports.AdminLayout=de;exports.AdminLayoutRouterSync=G;exports.Breadcrumbs=W;exports.Footer=H;exports.LayoutProvider=$;exports.MobileSidebar=Q;exports.Navbar=Z;exports.NavbarSearch=X;exports.NotificationMenu=Y;exports.RouterLink=oe;exports.Sidebar=I;exports.SidebarGroup=O;exports.SidebarItem=B;exports.ThemeToggle=K;exports.UserMenu=V;exports.cn=m;exports.filterSidebarByPermissions=L;exports.generateBreadcrumbsFromPath=P;exports.hasPermission=J;exports.useBreadcrumbs=ue;exports.useDarkMode=_;exports.useLayoutContext=w;exports.useLayoutState=ce;exports.useSidebar=M;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),c=require("react"),Q=require("react-router-dom"),g=require("lucide-react");function G(e){if(typeof window>"u")return{};try{const r=localStorage.getItem(e),n=r?JSON.parse(r):null;if(!n||typeof n!="object")return{};const a=n;return{sidebarCollapsed:typeof a.sidebarCollapsed=="boolean"?a.sidebarCollapsed:void 0,darkMode:typeof a.darkMode=="boolean"?a.darkMode:void 0,mode:a.mode==="light"||a.mode==="dark"||a.mode==="system"?a.mode:void 0}}catch{return{}}}function pe(e,r){if(!(typeof window>"u"))try{localStorage.setItem(e,JSON.stringify(r))}catch{}}const H=Object.freeze({primary:"#2563eb",secondary:"#7c3aed",background:"#f8fafc",surface:"#ffffff",text:"#0f172a",textSecondary:"#64748b",sidebarBackground:"#ffffff",sidebarText:"#64748b",headerBackground:"#ffffff",headerText:"#0f172a",hoverBackground:"#f1f5f9",hoverText:"#0f172a",activeBackground:"#2563eb",activeText:"#ffffff",border:"#e2e8f0",onPrimary:"#ffffff",danger:"#dc2626",onDanger:"#ffffff",overlay:"rgb(15 23 42 / 0.5)"}),W=Object.freeze({...H,primary:"#3b82f6",secondary:"#a78bfa",background:"#0b1220",surface:"#111827",text:"#f1f5f9",textSecondary:"#94a3b8",sidebarBackground:"#111827",sidebarText:"#cbd5e1",headerBackground:"#111827",headerText:"#f1f5f9",hoverBackground:"#1e293b",hoverText:"#ffffff",activeBackground:"#3b82f6",activeText:"#020617",onPrimary:"#020617",border:"#334155",danger:"#f87171",onDanger:"#020617",overlay:"rgb(2 6 23 / 0.7)"}),ve=Object.freeze({modern:Object.freeze({style:"modern"}),minimal:Object.freeze({style:"minimal"}),compact:Object.freeze({style:"compact"})}),J={primary:"--ral-primary",secondary:"--ral-secondary",background:"--ral-background",surface:"--ral-surface",text:"--ral-text",textSecondary:"--ral-text-secondary",sidebarBackground:"--ral-sidebar-bg",sidebarText:"--ral-sidebar-text",headerBackground:"--ral-header-bg",headerText:"--ral-header-text",hoverBackground:"--ral-hover-bg",hoverText:"--ral-hover-text",activeBackground:"--ral-active-bg",activeText:"--ral-active-text",border:"--ral-border",onPrimary:"--ral-on-primary",danger:"--ral-danger",onDanger:"--ral-on-danger",overlay:"--ral-overlay"};function X(e={},r="light"){const n=e.mode==="system"?r:e.mode??"light",a={...n==="dark"?W:H},i={};for(const d of[e.colors,e[n]])if(d)for(const s of Object.keys(a)){const o=d[s];typeof o=="string"&&o.trim()&&(i[s]=o)}return Object.assign(a,i),i.primary&&!i.activeBackground&&(a.activeBackground=i.primary),{mode:n,style:e.style??"modern",colors:a}}function Y(e){return Object.fromEntries(Object.keys(J).map(r=>[J[r],e.colors[r]]))}const _=c.createContext(null);function Z(){const e=c.useContext(_);if(!e)throw new Error("useAdminLayoutTheme must be used within LayoutProvider / AdminLayout");return{mode:e.requestedMode,resolvedMode:e.mode,style:e.style,colors:e.colors,setMode:e.setMode}}const K="(prefers-color-scheme: dark)",ye=()=>"light";function ge(e){const r=c.useCallback(a=>{if(!e||typeof window>"u"||!window.matchMedia)return()=>{};const i=window.matchMedia(K);return i.addEventListener?(i.addEventListener("change",a),()=>i.removeEventListener("change",a)):(i.addListener(a),()=>i.removeListener(a))},[e]),n=c.useCallback(()=>{var a;return e&&typeof window<"u"&&((a=window.matchMedia)!=null&&a.call(window,K).matches)?"dark":"light"},[e]);return c.useSyncExternalStore(r,n,ye)}const ee=c.createContext(null);function te({children:e,storageKey:r="rqdhw3n-admin-layout",defaultCollapsed:n=!1,permissions:a={},initialBreadcrumbs:i=[],initialActivePath:d="/",initialDarkMode:s,theme:o,onThemeModeChange:l}){const[u,p]=c.useState(n),[w,y]=c.useState(!1),[f,h]=c.useState(s?"dark":"light"),[k,S]=c.useState(null),v=(o==null?void 0:o.mode)??f,b=ge(v==="system"),A=X({...o,mode:v},b),N=A.mode==="dark",P=c.useCallback(x=>{(o==null?void 0:o.mode)===void 0&&h(x),l==null||l(x)},[o==null?void 0:o.mode,l]),L=c.useCallback(x=>P(x?"dark":"light"),[P]),[T,j]=c.useState(i),[C,M]=c.useState(d);c.useEffect(()=>{const x=G(r);p(x.sidebarCollapsed??n),h(x.mode??(x.darkMode??s?"dark":"light")),S(r)},[r]),c.useEffect(()=>{if(k!==r)return;const x=G(r);pe(r,(o==null?void 0:o.mode)===void 0?{sidebarCollapsed:u,darkMode:N,mode:v}:{...x,sidebarCollapsed:u})},[r,u,N,v,o==null?void 0:o.mode,k]),c.useEffect(()=>{if(o!==void 0)return;const x=document.documentElement,D=x.classList.contains("dark");return N?x.classList.add("dark"):x.classList.remove("dark"),()=>{x.classList.toggle("dark",D)}},[N,o]);const B=c.useCallback(()=>p(x=>!x),[]),q=c.useCallback(()=>y(x=>!x),[]),O=c.useCallback(()=>L(!N),[L,N]),$=c.useMemo(()=>({sidebarCollapsed:u,mobileOpen:w,darkMode:N,toggleSidebar:B,setSidebarCollapsed:p,toggleMobile:q,setMobileOpen:y,toggleDarkMode:O,setDarkMode:L,permissions:a,breadcrumbs:T,setBreadcrumbs:j,activePath:C,setActivePath:M}),[u,w,N,B,q,O,L,a,T,C]);return t.jsx(ee.Provider,{value:$,children:t.jsx(_.Provider,{value:{...A,requestedMode:v,setMode:P},children:e})})}function E(){const e=c.useContext(ee);if(!e)throw new Error("useLayoutContext must be used within LayoutProvider / AdminLayout");return e}function R(){const{sidebarCollapsed:e,mobileOpen:r,toggleSidebar:n,setSidebarCollapsed:a,toggleMobile:i,setMobileOpen:d}=E(),s=c.useCallback(()=>d(!1),[d]);return{collapsed:e,mobileOpen:r,toggle:n,setCollapsed:a,toggleMobile:i,setMobileOpen:d,closeMobile:s}}function z(e){const r=e.split("/").filter(Boolean);return r.length?r.map((n,a)=>{const i="/"+r.slice(0,a+1).join("/");return{label:n.replace(/-/g," ").replace(/\b\w/g,s=>s.toUpperCase()),path:a<r.length-1?i:void 0}}):[{label:"Home",path:"/"}]}function re(e){var r,n,a="";if(typeof e=="string"||typeof e=="number")a+=e;else if(typeof e=="object")if(Array.isArray(e)){var i=e.length;for(r=0;r<i;r++)e[r]&&(n=re(e[r]))&&(a&&(a+=" "),a+=n)}else for(n in e)e[n]&&(a&&(a+=" "),a+=n);return a}function je(){for(var e,r,n=0,a="",i=arguments.length;n<i;n++)(e=arguments[n])&&(r=re(e))&&(a&&(a+=" "),a+=r);return a}function m(...e){return je(e)}function ae({children:e}){const{pathname:r}=Q.useLocation(),{setActivePath:n,setBreadcrumbs:a,breadcrumbs:i}=E();return c.useEffect(()=>{n(r),i.length||a(z(r))},[r,n,a,i.length]),t.jsx(t.Fragment,{children:e})}function ne({children:e,className:r}){return t.jsx("footer",{className:m("mt-auto border-t border-admin-border bg-admin-surface px-6 py-4 text-sm text-admin-muted",r),children:e??t.jsxs("p",{className:"text-center",children:["© ",new Date().getFullYear()," Admin Layout · Built with @rqdhw3n/react-admin-layout"]})})}function we(e){const r=e.indexOf(".");return r===-1?{resource:e,action:"view"}:{resource:e.slice(0,r),action:e.slice(r+1)}}function se(e,r){if(!r)return!0;const{resource:n,action:a}=we(r),i=e[n];return i!=null&&i.length?i.includes(a)||i.includes("*"):!1}function F(e,r){return e.filter(n=>se(r,n.permission)).map(n=>({...n,children:n.children?F(n.children,r):void 0})).filter(n=>{var a;return!((a=n.children)!=null&&a.length)||n.children.length>0||n.path})}function V({label:e,children:r,collapsed:n,className:a}){return t.jsxs("div",{className:m("ral-sidebar-group mb-4",a),children:[e&&!n&&t.jsx("p",{className:"ral-sidebar-brand mb-2 px-3 text-[11px] font-semibold uppercase tracking-wider",children:e}),t.jsx("ul",{className:"space-y-0.5",children:r})]})}function ie(e,r){return e?r===e||r.startsWith(`${e}/`):!1}function oe(e,r){var n;return!!((n=e.children)!=null&&n.some(a=>ie(a.path,r)||oe(a,r)))}function U({item:e,collapsed:r=!1,depth:n=0,activePath:a="/",onNavigate:i,LinkComponent:d,onItemClick:s}){var v;const o=!!((v=e.children)!=null&&v.length),l=e.path?ie(e.path,a):!1,u=oe(e,a),[p,w]=c.useState(l||u);c.useEffect(()=>{u&&w(!0)},[a,u]);const y=e.icon,f=m("ral-nav-item group flex w-full items-center gap-3 px-3 text-sm font-medium","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-admin-primary",e.disabled&&"pointer-events-none opacity-50",n>0&&"text-[13px]",r&&"justify-center",(l||u)&&"ral-nav-active"),h=t.jsxs(t.Fragment,{children:[y&&t.jsx(y,{className:"h-[18px] w-[18px] shrink-0","aria-hidden":!0}),r&&!y&&t.jsx("span",{"aria-hidden":!0,children:e.label.charAt(0)}),r&&t.jsx("span",{className:"sr-only",children:e.label}),!r&&t.jsxs(t.Fragment,{children:[t.jsx("span",{className:"flex-1 truncate text-left",children:e.label}),e.badge!=null&&t.jsx("span",{className:m("ral-nav-badge rounded-full px-2 py-0.5 text-[11px] font-semibold"),children:e.badge}),o&&t.jsx(g.ChevronDown,{className:m("h-4 w-4 shrink-0 transition-transform",p&&"rotate-180"),"aria-hidden":!0})]})]}),k=()=>{if(!e.disabled){if(o){w(b=>!b);return}e.path&&(i==null||i(e.path),s==null||s())}},S=e.path&&!o&&d&&!e.disabled?t.jsx(d,{to:e.path,className:f,onClick:k,children:h}):t.jsx("button",{type:"button",className:f,onClick:k,disabled:e.disabled,"data-active":l||u,"aria-label":r?e.label:void 0,title:r?e.label:void 0,"aria-expanded":o?!!p:void 0,"aria-current":l&&!o?"page":void 0,children:h});return t.jsxs("li",{"data-active":l||u,"aria-label":r?e.label:void 0,children:[S,o&&p&&t.jsx("ul",{className:m("mt-1 space-y-0.5",!r&&"border-l border-admin-border ml-5 pl-2"),children:e.children.map(b=>t.jsx(U,{item:b,collapsed:r,depth:n+1,activePath:a,onNavigate:i,LinkComponent:d,onItemClick:s},b.label+(b.path??"")))})]})}function de({items:e,appName:r="Admin",appLogo:n,onNavigate:a,activePath:i,LinkComponent:d}){const{mobileOpen:s,closeMobile:o}=R(),{permissions:l,activePath:u}=E(),p=i??u,w=F(e,l),y=c.useRef(null);if(c.useEffect(()=>{var N,P,L,T;if(!s)return;const h=document.activeElement,k=document.body.style.overflow,S=()=>{var j;return Array.from(((j=y.current)==null?void 0:j.querySelectorAll('button:not(:disabled), a[href], input, [tabindex="0"]'))??[]).filter(C=>C.getClientRects().length>0)};(P=(N=y.current)==null?void 0:N.querySelector('[aria-label="Close sidebar"]'))==null||P.focus();const v=j=>{if(j.key==="Escape"&&o(),j.key==="Tab"){const C=S(),M=C[0],B=C[C.length-1];j.shiftKey&&document.activeElement===M?(j.preventDefault(),B==null||B.focus()):!j.shiftKey&&document.activeElement===B&&(j.preventDefault(),M==null||M.focus())}},b=(L=window.matchMedia)==null?void 0:L.call(window,"(min-width: 1024px)"),A=()=>{b!=null&&b.matches&&o()};return(T=b==null?void 0:b.addEventListener)==null||T.call(b,"change",A),document.addEventListener("keydown",v),document.body.style.overflow="hidden",()=>{var j;document.removeEventListener("keydown",v),(j=b==null?void 0:b.removeEventListener)==null||j.call(b,"change",A),document.body.style.overflow=k,h==null||h.focus()}},[s,o]),!s)return null;const f=h=>{a==null||a(h),o()};return t.jsxs("div",{ref:y,className:"fixed inset-0 z-50 lg:hidden",role:"dialog","aria-modal":"true","aria-label":"Navigation menu",children:[t.jsx("button",{type:"button",className:"ral-overlay absolute inset-0 backdrop-blur-sm animate-fade-in","aria-label":"Close menu",onClick:o}),t.jsxs("aside",{className:m("ral-sidebar absolute left-0 top-0 flex h-full w-[min(var(--ral-sidebar-width),85vw)] flex-col","border-r border-admin-border shadow-admin-lg animate-slide-in"),children:[t.jsxs("div",{className:"ral-sidebar-top flex items-center justify-between border-b border-admin-border px-4",children:[t.jsxs("div",{className:"flex items-center gap-3",children:[n??t.jsx("div",{className:"flex h-9 w-9 items-center justify-center rounded-admin bg-admin-primary text-sm font-bold text-admin-on-primary",children:r.charAt(0)}),t.jsx("span",{className:"ral-sidebar-brand font-semibold",children:r})]}),t.jsx("button",{type:"button",onClick:o,className:"rounded-admin p-2 text-admin-muted hover:bg-admin-hover","aria-label":"Close sidebar",children:t.jsx(g.X,{className:"h-5 w-5"})})]}),t.jsx("nav",{className:"flex-1 overflow-y-auto p-3",children:t.jsx(V,{children:w.map(h=>t.jsx(U,{item:h,activePath:p,onNavigate:f,LinkComponent:d,onItemClick:o},h.label+(h.path??"")))})})]})]})}function le({items:e,className:r,LinkComponent:n,onNavigate:a}){if(!e.length)return null;const i=(d,s)=>{const o=m("text-sm transition-colors",s?"font-medium text-admin-text":"text-admin-muted hover:text-admin-hover-text");return!d.path||s?t.jsx("span",{className:o,children:d.label}):n?t.jsx(n,{to:d.path,className:o,children:d.label}):t.jsx("button",{type:"button",className:o,onClick:()=>a==null?void 0:a(d.path),children:d.label})};return t.jsxs("nav",{"aria-label":"Breadcrumb",className:m("flex items-center gap-1.5",r),children:[t.jsx(g.Home,{className:"h-4 w-4 text-admin-muted shrink-0","aria-hidden":!0}),e.map((d,s)=>{const o=s===e.length-1;return t.jsxs("span",{className:"flex items-center gap-1.5",children:[t.jsx(g.ChevronRight,{className:"h-3.5 w-3.5 text-admin-muted","aria-hidden":!0}),i(d,o)]},`${d.label}-${s}`)})]})}function ce({placeholder:e="Search...",onSearch:r,className:n}){const[a,i]=c.useState(""),d=s=>{s.preventDefault(),r==null||r(a.trim())};return t.jsxs("form",{onSubmit:d,className:m("relative w-full max-w-md",n),children:[t.jsx(g.Search,{className:"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-admin-muted","aria-hidden":!0}),t.jsx("input",{type:"search",value:a,onChange:s=>i(s.target.value),placeholder:e,className:m("h-10 w-full rounded-admin border border-admin-border bg-admin-bg pl-10 pr-4 text-sm text-admin-text","placeholder:text-admin-muted focus:border-admin-primary focus:outline-none focus:ring-2 focus:ring-admin-primary"),"aria-label":"Search"})]})}function ue({notifications:e=[],className:r}){const[n,a]=c.useState(!1),i=c.useRef(null),d=e.filter(s=>!s.read).length;return c.useEffect(()=>{const s=o=>{i.current&&!i.current.contains(o.target)&&a(!1)};return document.addEventListener("mousedown",s),()=>document.removeEventListener("mousedown",s)},[]),t.jsxs("div",{ref:i,className:m("relative",r),onKeyDown:s=>{var o,l;s.key==="Escape"&&(a(!1),(l=(o=i.current)==null?void 0:o.querySelector("button"))==null||l.focus())},children:[t.jsxs("button",{type:"button",onClick:()=>a(s=>!s),className:m("relative inline-flex h-9 w-9 items-center justify-center rounded-admin border border-admin-border","bg-admin-surface text-admin-muted transition-colors hover:bg-admin-hover hover:text-admin-hover-text","focus-visible:ring-2 focus-visible:ring-admin-primary"),"aria-label":`Notifications${d?`, ${d} unread`:""}`,"aria-expanded":n,children:[t.jsx(g.Bell,{className:"h-4 w-4","aria-hidden":!0}),d>0&&t.jsx("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",children:d>9?"9+":d})]}),n&&t.jsxs("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",children:[t.jsx("div",{className:"border-b border-admin-border px-4 py-3",children:t.jsx("p",{className:"text-sm font-semibold text-admin-text",children:"Notifications"})}),t.jsx("ul",{className:"max-h-72 overflow-y-auto p-2",children:e.length===0?t.jsx("li",{className:"px-3 py-6 text-center text-sm text-admin-muted",children:"No notifications"}):e.map(s=>t.jsxs("li",{className:m("rounded-admin px-3 py-2.5 transition-colors hover:bg-admin-hover",!s.read&&"ral-unread"),children:[t.jsx("p",{className:"text-sm font-medium text-admin-text",children:s.title}),s.description&&t.jsx("p",{className:"mt-0.5 text-xs text-admin-muted line-clamp-2",children:s.description}),s.time&&t.jsx("p",{className:"mt-1 text-[11px] text-admin-muted",children:s.time})]},s.id))})]})]})}function me(){const{darkMode:e,toggleDarkMode:r,setDarkMode:n}=E();return{isDark:e,toggle:r,setDarkMode:n}}function fe({className:e}){const{isDark:r,toggle:n}=me();return t.jsx("button",{type:"button",onClick:n,className:m("inline-flex h-9 w-9 items-center justify-center rounded-admin border border-admin-border","bg-admin-surface text-admin-muted transition-colors hover:bg-admin-hover hover:text-admin-hover-text","focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-admin-primary focus-visible:ring-offset-2",e),"aria-label":r?"Switch to light mode":"Switch to dark mode",children:r?t.jsx(g.Sun,{className:"h-4 w-4","aria-hidden":!0}):t.jsx(g.Moon,{className:"h-4 w-4","aria-hidden":!0})})}function be({user:e,onLogout:r,onSettings:n,className:a}){const[i,d]=c.useState(!1),s=c.useRef(null);c.useEffect(()=>{const l=u=>{s.current&&!s.current.contains(u.target)&&d(!1)};return document.addEventListener("mousedown",l),()=>document.removeEventListener("mousedown",l)},[]),c.useEffect(()=>{var l,u;i&&((u=(l=s.current)==null?void 0:l.querySelector('[role="menuitem"]'))==null||u.focus())},[i]);const o=e.name.split(" ").map(l=>l[0]).join("").slice(0,2).toUpperCase();return t.jsxs("div",{ref:s,className:m("relative",a),onKeyDown:l=>{var p,w,y;const u=(p=s.current)==null?void 0:p.querySelector("[aria-haspopup]");if(l.key==="Escape"&&i&&(l.preventDefault(),d(!1),u==null||u.focus()),l.key==="Tab"&&d(!1),["ArrowDown","ArrowUp","Home","End"].includes(l.key)){if(l.preventDefault(),!i){d(!0);return}const f=Array.from(((w=s.current)==null?void 0:w.querySelectorAll('[role="menuitem"]'))??[]),h=f.indexOf(document.activeElement),k=l.key==="Home"?0:l.key==="End"?f.length-1:(h+(l.key==="ArrowDown"?1:-1)+f.length)%f.length;(y=f[k])==null||y.focus()}},children:[t.jsxs("button",{type:"button",onClick:()=>d(l=>!l),className:m("flex items-center gap-2 rounded-admin border border-admin-border bg-admin-surface px-2 py-1.5","transition-colors hover:bg-admin-hover focus-visible:ring-2 focus-visible:ring-admin-primary"),"aria-expanded":i,"aria-haspopup":"menu","aria-label":`User menu for ${e.name}`,children:[e.avatar?t.jsx("img",{src:e.avatar,alt:"",className:"h-8 w-8 rounded-admin object-cover"}):t.jsx("div",{className:"flex h-8 w-8 items-center justify-center rounded-admin bg-admin-primary text-xs font-semibold text-admin-on-primary",children:o}),t.jsxs("div",{className:"hidden text-left sm:block",children:[t.jsx("p",{className:"text-sm font-medium text-admin-text leading-tight",children:e.name}),t.jsx("p",{className:"text-xs text-admin-muted leading-tight",children:e.email})]}),t.jsx(g.ChevronDown,{className:"hidden h-4 w-4 text-admin-muted sm:block","aria-hidden":!0})]}),i&&t.jsxs("div",{role:"menu",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",children:[t.jsxs("button",{type:"button",role:"menuitem",className:"flex w-full items-center gap-2 rounded-admin px-3 py-2 text-sm text-admin-text hover:bg-admin-hover",onClick:()=>{n==null||n(),d(!1)},children:[t.jsx(g.Settings,{className:"h-4 w-4 text-admin-muted"}),"Settings"]}),t.jsxs("button",{type:"button",role:"menuitem",className:"flex w-full items-center gap-2 rounded-admin px-3 py-2 text-sm text-admin-text hover:bg-admin-hover",children:[t.jsx(g.User,{className:"h-4 w-4 text-admin-muted"}),"Profile"]}),t.jsx("hr",{className:"my-1 border-admin-border"}),t.jsxs("button",{type:"button",role:"menuitem",className:"flex w-full items-center gap-2 rounded-admin px-3 py-2 text-sm ral-danger",onClick:()=>{r==null||r(),d(!1)},children:[t.jsx(g.LogOut,{className:"h-4 w-4"}),"Log out"]})]})]})}function xe({user:e,notifications:r=[],onSearch:n,searchPlaceholder:a="Search...",showSearch:i=!0,className:d,breadcrumbs:s=[],onMenuClick:o,sidebarCollapsed:l,onToggleSidebar:u}){return t.jsxs("header",{className:m("ral-header sticky top-0 z-40 flex shrink-0 items-center gap-4 border-b border-admin-border",d),children:[t.jsx("button",{type:"button",className:"rounded-admin p-2 text-admin-muted hover:bg-admin-hover lg:hidden",onClick:o,"aria-label":"Open menu",children:t.jsx(g.Menu,{className:"h-5 w-5"})}),t.jsx("button",{type:"button",className:"hidden rounded-admin p-2 text-admin-muted hover:bg-admin-hover lg:inline-flex",onClick:u,"aria-label":l?"Expand sidebar":"Collapse sidebar",children:l?t.jsx(g.PanelLeftOpen,{className:"h-5 w-5"}):t.jsx(g.PanelLeftClose,{className:"h-5 w-5"})}),t.jsx("div",{className:"hidden min-w-0 flex-1 md:block",children:t.jsx(le,{items:s})}),t.jsxs("div",{className:"flex flex-1 items-center justify-end gap-2 sm:gap-3",children:[i&&t.jsx("div",{className:"hidden flex-1 sm:flex sm:max-w-md",children:t.jsx(ce,{placeholder:a,onSearch:n})}),t.jsx(fe,{}),t.jsx(ue,{notifications:r}),e&&t.jsx(be,{user:e})]})]})}function he({items:e,collapsed:r,appName:n="Admin",appLogo:a,className:i,onNavigate:d,activePath:s,LinkComponent:o}){const{collapsed:l,toggle:u,closeMobile:p}=R(),{permissions:w,activePath:y}=E(),f=r??l,h=s??y,k=F(e,w),S=v=>{d==null||d(v),p()};return t.jsxs("aside",{className:m("ral-sidebar hidden lg:flex shrink-0 flex-col border-r border-admin-border","h-screen sticky top-0 transition-[width] duration-300 ease-in-out",f?"w-[var(--admin-sidebar-collapsed)]":"w-[var(--admin-sidebar-width)]",i),"aria-label":"Sidebar navigation",children:[t.jsxs("div",{className:m("ral-sidebar-top flex items-center border-b border-admin-border px-4",f?"justify-center":"justify-between gap-2"),children:[t.jsxs("div",{className:m("flex items-center gap-3 min-w-0",f&&"justify-center"),children:[a??t.jsx("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",children:n.charAt(0)}),!f&&t.jsx("span",{className:"ral-sidebar-brand truncate text-base font-semibold",children:n})]}),!f&&t.jsx("button",{type:"button",onClick:u,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","aria-label":"Collapse sidebar",children:t.jsx(g.PanelLeftClose,{className:"h-4 w-4"})})]}),f&&t.jsx("div",{className:"flex justify-center py-2 border-b border-admin-border",children:t.jsx("button",{type:"button",onClick:u,className:"rounded-admin p-2 text-admin-muted hover:bg-admin-hover","aria-label":"Expand sidebar",children:t.jsx(g.PanelLeftOpen,{className:"h-4 w-4"})})}),t.jsx("nav",{className:"flex-1 overflow-y-auto p-3",children:t.jsx(V,{collapsed:f,children:k.map(v=>t.jsx(U,{item:v,collapsed:f,activePath:h,onNavigate:S,LinkComponent:o},v.label+(v.path??"")))})})]})}function I({children:e,sidebarItems:r,appName:n="Admin",appLogo:a,user:i,notifications:d=[],footer:s,showFooter:o=!0,showSearch:l=!0,searchPlaceholder:u,onSearch:p,breadcrumbs:w,contentClassName:y,className:f,activePath:h,onNavigate:k,LinkComponent:S,enableRouter:v=!1}){const{sidebarCollapsed:b,toggleSidebar:A,toggleMobile:N,breadcrumbs:P,setBreadcrumbs:L,activePath:T,setActivePath:j}=E(),{closeMobile:C}=R(),{resolvedMode:M,style:B,colors:q}=Z(),O=h??T,$=w??P,x=D=>{j(D),w||L(z(D)),k==null||k(D),C()};return t.jsxs("div",{className:m("ral-layout admin-layout-root min-h-screen bg-admin-bg text-admin-text",M==="dark"&&"dark",f),"data-theme":M,"data-style":B,style:Y({colors:q}),children:[t.jsx(de,{items:r,appName:n,appLogo:a,activePath:O,onNavigate:x,LinkComponent:S}),t.jsxs("div",{className:"flex min-h-screen w-full",children:[t.jsx(he,{items:r,appName:n,appLogo:a,activePath:O,onNavigate:x,LinkComponent:S}),t.jsxs("div",{className:"flex min-h-screen min-w-0 flex-1 flex-col",children:[t.jsx(xe,{user:i,notifications:d,onSearch:p,searchPlaceholder:u,showSearch:l,breadcrumbs:$,onMenuClick:N,sidebarCollapsed:b,onToggleSidebar:A}),t.jsx("main",{className:m("ral-content flex-1",y),children:e}),o&&t.jsx(ne,{children:s})]})]})]})}function ke(e){const{storageKey:r="rqdhw3n-admin-layout",defaultCollapsed:n=!1,initialDarkMode:a=!1,permissions:i={},breadcrumbs:d=[],activePath:s="/",enableRouter:o=!1,children:l,...u}=e,p=c.useMemo(()=>d.length?d:z(s),[d,s]);return t.jsx(te,{storageKey:r,defaultCollapsed:n,permissions:i,initialBreadcrumbs:p,initialActivePath:s,initialDarkMode:a,theme:e.theme,onThemeModeChange:e.onThemeModeChange,children:o?t.jsx(ae,{children:t.jsx(I,{...u,enableRouter:o,children:l})}):t.jsx(I,{...u,enableRouter:o,children:l})})}function Ne({to:e,className:r,children:n,onClick:a}){return t.jsx(Q.NavLink,{to:e,className:r,onClick:a,children:n})}function Se(){return E()}function Ce(){const{breadcrumbs:e,setBreadcrumbs:r}=E(),n=c.useCallback(a=>r(a),[r]);return{items:e,setBreadcrumbs:n}}exports.AdminLayout=ke;exports.AdminLayoutRouterSync=ae;exports.Breadcrumbs=le;exports.Footer=ne;exports.LayoutProvider=te;exports.MobileSidebar=de;exports.Navbar=xe;exports.NavbarSearch=ce;exports.NotificationMenu=ue;exports.RouterLink=Ne;exports.Sidebar=he;exports.SidebarGroup=V;exports.SidebarItem=U;exports.ThemeToggle=fe;exports.UserMenu=be;exports.adminLayoutPresets=ve;exports.cn=m;exports.darkThemeColors=W;exports.filterSidebarByPermissions=F;exports.generateBreadcrumbsFromPath=z;exports.hasPermission=se;exports.lightThemeColors=H;exports.resolveTheme=X;exports.themeToCSSVariables=Y;exports.useAdminLayoutTheme=Z;exports.useBreadcrumbs=Ce;exports.useDarkMode=me;exports.useLayoutContext=E;exports.useLayoutState=Se;exports.useSidebar=R;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|