@prenta/admin 2.6.1 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +132 -0
- package/design-system/tokens.css +196 -85
- package/design-system/tokens.json +310 -85
- package/design-system/tokens.scss +163 -44
- package/design-system/tokens.tailwind.cjs +64 -1
- package/dist/AdminRoot.d.ts.map +1 -1
- package/dist/AdminRoot.js +43 -21
- package/dist/AdminRoot.js.map +1 -1
- package/dist/LoginRoot.d.ts.map +1 -1
- package/dist/LoginRoot.js +2 -1
- package/dist/LoginRoot.js.map +1 -1
- package/dist/__tests__/components/author-avatar.test.js +3 -17
- package/dist/__tests__/components/author-avatar.test.js.map +1 -1
- package/dist/__tests__/components/notification-bell.test.js +86 -15
- package/dist/__tests__/components/notification-bell.test.js.map +1 -1
- package/dist/__tests__/components/responsive-tiers.render.test.d.ts +2 -0
- package/dist/__tests__/components/responsive-tiers.render.test.d.ts.map +1 -0
- package/dist/__tests__/components/responsive-tiers.render.test.js +313 -0
- package/dist/__tests__/components/responsive-tiers.render.test.js.map +1 -0
- package/dist/__tests__/components/serp-preview.render.test.js +6 -3
- package/dist/__tests__/components/serp-preview.render.test.js.map +1 -1
- package/dist/__tests__/components/shell-primitives.render.test.d.ts +2 -0
- package/dist/__tests__/components/shell-primitives.render.test.d.ts.map +1 -0
- package/dist/__tests__/components/shell-primitives.render.test.js +716 -0
- package/dist/__tests__/components/shell-primitives.render.test.js.map +1 -0
- package/dist/__tests__/components/theme-provider-accent.test.js +49 -7
- package/dist/__tests__/components/theme-provider-accent.test.js.map +1 -1
- package/dist/__tests__/components/toggle.test.js +10 -3
- package/dist/__tests__/components/toggle.test.js.map +1 -1
- package/dist/__tests__/components/ui-primitives.test.js +3 -7
- package/dist/__tests__/components/ui-primitives.test.js.map +1 -1
- package/dist/__tests__/layout/build-nav-items.test.js +1 -1
- package/dist/__tests__/layout/build-nav-items.test.js.map +1 -1
- package/dist/__tests__/layout/shell-nav.render.test.d.ts +2 -0
- package/dist/__tests__/layout/shell-nav.render.test.d.ts.map +1 -0
- package/dist/__tests__/layout/shell-nav.render.test.js +736 -0
- package/dist/__tests__/layout/shell-nav.render.test.js.map +1 -0
- package/dist/__tests__/layout/sidebar-forms-submenu.render.test.js +8 -4
- package/dist/__tests__/layout/sidebar-forms-submenu.render.test.js.map +1 -1
- package/dist/__tests__/layout/sidebar-groups.render.test.d.ts +2 -0
- package/dist/__tests__/layout/sidebar-groups.render.test.d.ts.map +1 -0
- package/dist/__tests__/layout/sidebar-groups.render.test.js +56 -0
- package/dist/__tests__/layout/sidebar-groups.render.test.js.map +1 -0
- package/dist/__tests__/layout/sidebar-menus.render.test.d.ts +2 -0
- package/dist/__tests__/layout/sidebar-menus.render.test.d.ts.map +1 -0
- package/dist/__tests__/layout/sidebar-menus.render.test.js +82 -0
- package/dist/__tests__/layout/sidebar-menus.render.test.js.map +1 -0
- package/dist/__tests__/layout/sidebar-plugin-nav.test.js +1 -1
- package/dist/__tests__/layout/sidebar-plugin-nav.test.js.map +1 -1
- package/dist/__tests__/layout/sidebar-posts.test.js +48 -38
- package/dist/__tests__/layout/sidebar-posts.test.js.map +1 -1
- package/dist/__tests__/layout/sidebar-submenu.render.test.js +26 -10
- package/dist/__tests__/layout/sidebar-submenu.render.test.js.map +1 -1
- package/dist/__tests__/layout/topbar.render.test.d.ts +2 -0
- package/dist/__tests__/layout/topbar.render.test.d.ts.map +1 -0
- package/dist/__tests__/layout/topbar.render.test.js +406 -0
- package/dist/__tests__/layout/topbar.render.test.js.map +1 -0
- package/dist/__tests__/lib/api.test.js +2 -0
- package/dist/__tests__/lib/api.test.js.map +1 -1
- package/dist/__tests__/lib/batch-wizard.test.d.ts +2 -0
- package/dist/__tests__/lib/batch-wizard.test.d.ts.map +1 -0
- package/dist/__tests__/lib/batch-wizard.test.js +144 -0
- package/dist/__tests__/lib/batch-wizard.test.js.map +1 -0
- package/dist/__tests__/lib/job-drawer.test.d.ts +2 -0
- package/dist/__tests__/lib/job-drawer.test.d.ts.map +1 -0
- package/dist/__tests__/lib/job-drawer.test.js +395 -0
- package/dist/__tests__/lib/job-drawer.test.js.map +1 -0
- package/dist/__tests__/lib/job-view.test.d.ts +2 -0
- package/dist/__tests__/lib/job-view.test.d.ts.map +1 -0
- package/dist/__tests__/lib/job-view.test.js +484 -0
- package/dist/__tests__/lib/job-view.test.js.map +1 -0
- package/dist/__tests__/lib/jobs-service.test.d.ts +2 -0
- package/dist/__tests__/lib/jobs-service.test.d.ts.map +1 -0
- package/dist/__tests__/lib/jobs-service.test.js +142 -0
- package/dist/__tests__/lib/jobs-service.test.js.map +1 -0
- package/dist/__tests__/router/admin-route-order.test.d.ts +2 -0
- package/dist/__tests__/router/admin-route-order.test.d.ts.map +1 -0
- package/dist/__tests__/router/admin-route-order.test.js +36 -0
- package/dist/__tests__/router/admin-route-order.test.js.map +1 -0
- package/dist/__tests__/styles/ai-gradient-contrast.test.d.ts +2 -0
- package/dist/__tests__/styles/ai-gradient-contrast.test.d.ts.map +1 -0
- package/dist/__tests__/styles/ai-gradient-contrast.test.js +110 -0
- package/dist/__tests__/styles/ai-gradient-contrast.test.js.map +1 -0
- package/dist/__tests__/styles/breakpoint-order.test.d.ts +2 -0
- package/dist/__tests__/styles/breakpoint-order.test.d.ts.map +1 -0
- package/dist/__tests__/styles/breakpoint-order.test.js +52 -0
- package/dist/__tests__/styles/breakpoint-order.test.js.map +1 -0
- package/dist/__tests__/styles/responsive-layer.test.js +303 -12
- package/dist/__tests__/styles/responsive-layer.test.js.map +1 -1
- package/dist/__tests__/styles/tailwind-preset.test.d.ts +2 -0
- package/dist/__tests__/styles/tailwind-preset.test.d.ts.map +1 -0
- package/dist/__tests__/styles/tailwind-preset.test.js +147 -0
- package/dist/__tests__/styles/tailwind-preset.test.js.map +1 -0
- package/dist/__tests__/styles/theme-token-scope.test.js +9 -3
- package/dist/__tests__/styles/theme-token-scope.test.js.map +1 -1
- package/dist/__tests__/styles/tiers.test.d.ts +2 -0
- package/dist/__tests__/styles/tiers.test.d.ts.map +1 -0
- package/dist/__tests__/styles/tiers.test.js +121 -0
- package/dist/__tests__/styles/tiers.test.js.map +1 -0
- package/dist/__tests__/styles/tokens-drift.test.js +57 -6
- package/dist/__tests__/styles/tokens-drift.test.js.map +1 -1
- package/dist/__tests__/views/admin-lazy-route.render.test.js +27 -1
- package/dist/__tests__/views/admin-lazy-route.render.test.js.map +1 -1
- package/dist/__tests__/views/ai-settings.render.test.js +4 -4
- package/dist/__tests__/views/appearance-chrome.render.test.d.ts +2 -0
- package/dist/__tests__/views/appearance-chrome.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/appearance-chrome.render.test.js +688 -0
- package/dist/__tests__/views/appearance-chrome.render.test.js.map +1 -0
- package/dist/__tests__/views/appearance-menus-route.render.test.d.ts +2 -0
- package/dist/__tests__/views/appearance-menus-route.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/appearance-menus-route.render.test.js +50 -0
- package/dist/__tests__/views/appearance-menus-route.render.test.js.map +1 -0
- package/dist/__tests__/views/appearance-settings.render.test.js +8 -6
- package/dist/__tests__/views/appearance-settings.render.test.js.map +1 -1
- package/dist/__tests__/views/appearance-theme-provider.render.test.d.ts +2 -0
- package/dist/__tests__/views/appearance-theme-provider.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/appearance-theme-provider.render.test.js +286 -0
- package/dist/__tests__/views/appearance-theme-provider.render.test.js.map +1 -0
- package/dist/__tests__/views/dashboard.test.js +37 -0
- package/dist/__tests__/views/dashboard.test.js.map +1 -1
- package/dist/__tests__/views/document-edit-navigation.render.test.d.ts +2 -0
- package/dist/__tests__/views/document-edit-navigation.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/document-edit-navigation.render.test.js +101 -0
- package/dist/__tests__/views/document-edit-navigation.render.test.js.map +1 -0
- package/dist/__tests__/views/document-edit-routes.render.test.d.ts +2 -0
- package/dist/__tests__/views/document-edit-routes.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/document-edit-routes.render.test.js +113 -0
- package/dist/__tests__/views/document-edit-routes.render.test.js.map +1 -0
- package/dist/__tests__/views/email-settings.render.test.js +2 -2
- package/dist/__tests__/views/form-entries.render.test.js +15 -0
- package/dist/__tests__/views/form-entries.render.test.js.map +1 -1
- package/dist/__tests__/views/form-submissions.render.test.js +18 -0
- package/dist/__tests__/views/form-submissions.render.test.js.map +1 -1
- package/dist/__tests__/views/forms-list.render.test.js +12 -0
- package/dist/__tests__/views/forms-list.render.test.js.map +1 -1
- package/dist/__tests__/views/general-settings.render.test.js +26 -10
- package/dist/__tests__/views/general-settings.render.test.js.map +1 -1
- package/dist/__tests__/views/header-footer-form.test.d.ts +2 -0
- package/dist/__tests__/views/header-footer-form.test.d.ts.map +1 -0
- package/dist/__tests__/views/header-footer-form.test.js +266 -0
- package/dist/__tests__/views/header-footer-form.test.js.map +1 -0
- package/dist/__tests__/views/jobs-drawer.render.test.d.ts +2 -0
- package/dist/__tests__/views/jobs-drawer.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/jobs-drawer.render.test.js +1348 -0
- package/dist/__tests__/views/jobs-drawer.render.test.js.map +1 -0
- package/dist/__tests__/views/jobs-list.render.test.d.ts +2 -0
- package/dist/__tests__/views/jobs-list.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/jobs-list.render.test.js +697 -0
- package/dist/__tests__/views/jobs-list.render.test.js.map +1 -0
- package/dist/__tests__/views/jobs-wizard.render.test.d.ts +2 -0
- package/dist/__tests__/views/jobs-wizard.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/jobs-wizard.render.test.js +588 -0
- package/dist/__tests__/views/jobs-wizard.render.test.js.map +1 -0
- package/dist/__tests__/views/kpi-grid.test.d.ts +2 -0
- package/dist/__tests__/views/kpi-grid.test.d.ts.map +1 -0
- package/dist/__tests__/views/kpi-grid.test.js +26 -0
- package/dist/__tests__/views/kpi-grid.test.js.map +1 -0
- package/dist/__tests__/views/post-section-editor.test.js +3 -1
- package/dist/__tests__/views/post-section-editor.test.js.map +1 -1
- package/dist/__tests__/views/script-tags.render.test.js +25 -0
- package/dist/__tests__/views/script-tags.render.test.js.map +1 -1
- package/dist/__tests__/views/security-settings.render.test.js +9 -8
- package/dist/__tests__/views/security-settings.render.test.js.map +1 -1
- package/dist/__tests__/views/seo-settings.render.test.js +7 -7
- package/dist/__tests__/views/seo-settings.render.test.js.map +1 -1
- package/dist/__tests__/views/settings-save-bar.render.test.d.ts +2 -0
- package/dist/__tests__/views/settings-save-bar.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/settings-save-bar.render.test.js +68 -0
- package/dist/__tests__/views/settings-save-bar.render.test.js.map +1 -0
- package/dist/__tests__/views/settings-save-footer.render.test.js +23 -15
- package/dist/__tests__/views/settings-save-footer.render.test.js.map +1 -1
- package/dist/__tests__/views/settings-tabs.render.test.d.ts +2 -0
- package/dist/__tests__/views/settings-tabs.render.test.d.ts.map +1 -0
- package/dist/__tests__/views/settings-tabs.render.test.js +319 -0
- package/dist/__tests__/views/settings-tabs.render.test.js.map +1 -0
- package/dist/__tests__/views/updates-tab.render.test.js +4 -3
- package/dist/__tests__/views/updates-tab.render.test.js.map +1 -1
- package/dist/components/Breadcrumbs.d.ts +8 -1
- package/dist/components/Breadcrumbs.d.ts.map +1 -1
- package/dist/components/Breadcrumbs.js +6 -0
- package/dist/components/Breadcrumbs.js.map +1 -1
- package/dist/components/CommandPalette.d.ts.map +1 -1
- package/dist/components/CommandPalette.js +40 -4
- package/dist/components/CommandPalette.js.map +1 -1
- package/dist/components/LocaleSwitcher.d.ts.map +1 -1
- package/dist/components/LocaleSwitcher.js +1 -1
- package/dist/components/LocaleSwitcher.js.map +1 -1
- package/dist/components/NotificationBell.d.ts.map +1 -1
- package/dist/components/NotificationBell.js +44 -3
- package/dist/components/NotificationBell.js.map +1 -1
- package/dist/components/OfflineStatus.js +1 -1
- package/dist/components/OfflineStatus.js.map +1 -1
- package/dist/components/PresenceIndicator.d.ts.map +1 -1
- package/dist/components/PresenceIndicator.js +2 -1
- package/dist/components/PresenceIndicator.js.map +1 -1
- package/dist/components/ReflowMeter.js +2 -2
- package/dist/components/ReflowMeter.js.map +1 -1
- package/dist/components/SEOPanel.js +2 -2
- package/dist/components/SEOPanel.js.map +1 -1
- package/dist/components/ThemeProvider.d.ts +24 -4
- package/dist/components/ThemeProvider.d.ts.map +1 -1
- package/dist/components/ThemeProvider.js +80 -22
- package/dist/components/ThemeProvider.js.map +1 -1
- package/dist/components/TipTapEditor.d.ts.map +1 -1
- package/dist/components/TipTapEditor.js +3 -4
- package/dist/components/TipTapEditor.js.map +1 -1
- package/dist/components/forms/EmbedPanel.js +1 -1
- package/dist/components/forms/EmbedPanel.js.map +1 -1
- package/dist/components/forms/FormEntryDetailPane.js +6 -1
- package/dist/components/forms/FormEntryDetailPane.js.map +1 -1
- package/dist/components/forms/ShortcodeGlossary.d.ts.map +1 -1
- package/dist/components/forms/ShortcodeGlossary.js +6 -1
- package/dist/components/forms/ShortcodeGlossary.js.map +1 -1
- package/dist/components/forms/primitives.d.ts +15 -5
- package/dist/components/forms/primitives.d.ts.map +1 -1
- package/dist/components/forms/primitives.js +11 -11
- package/dist/components/forms/primitives.js.map +1 -1
- package/dist/components/pages/tag-badges.d.ts +2 -1
- package/dist/components/pages/tag-badges.d.ts.map +1 -1
- package/dist/components/pages/tag-badges.js +4 -3
- package/dist/components/pages/tag-badges.js.map +1 -1
- package/dist/components/seo/PageAuditPanel.js +2 -2
- package/dist/components/seo/PageAuditPanel.js.map +1 -1
- package/dist/components/seo/SerpPreview.d.ts +4 -4
- package/dist/components/seo/SerpPreview.js +1 -1
- package/dist/components/seo/SerpPreview.js.map +1 -1
- package/dist/components/seo/primitives.js +2 -2
- package/dist/components/seo/primitives.js.map +1 -1
- package/dist/components/ui/AuthorAvatar.d.ts +4 -4
- package/dist/components/ui/AuthorAvatar.d.ts.map +1 -1
- package/dist/components/ui/AuthorAvatar.js +11 -10
- package/dist/components/ui/AuthorAvatar.js.map +1 -1
- package/dist/components/ui/Badge.d.ts +1 -1
- package/dist/components/ui/Badge.js +1 -1
- package/dist/components/ui/Badge.js.map +1 -1
- package/dist/components/ui/Breadcrumb.d.ts +27 -0
- package/dist/components/ui/Breadcrumb.d.ts.map +1 -0
- package/dist/components/ui/Breadcrumb.js +41 -0
- package/dist/components/ui/Breadcrumb.js.map +1 -0
- package/dist/components/ui/Button.d.ts +2 -2
- package/dist/components/ui/Button.d.ts.map +1 -1
- package/dist/components/ui/Button.js +31 -16
- package/dist/components/ui/Button.js.map +1 -1
- package/dist/components/ui/Card.d.ts +8 -4
- package/dist/components/ui/Card.d.ts.map +1 -1
- package/dist/components/ui/Card.js +21 -13
- package/dist/components/ui/Card.js.map +1 -1
- package/dist/components/ui/CardListControls.d.ts +34 -0
- package/dist/components/ui/CardListControls.d.ts.map +1 -0
- package/dist/components/ui/CardListControls.js +25 -0
- package/dist/components/ui/CardListControls.js.map +1 -0
- package/dist/components/ui/CountChip.d.ts +20 -0
- package/dist/components/ui/CountChip.d.ts.map +1 -0
- package/dist/components/ui/CountChip.js +48 -0
- package/dist/components/ui/CountChip.js.map +1 -0
- package/dist/components/ui/FilterPill.d.ts +2 -1
- package/dist/components/ui/FilterPill.d.ts.map +1 -1
- package/dist/components/ui/FilterPill.js +3 -2
- package/dist/components/ui/FilterPill.js.map +1 -1
- package/dist/components/ui/Input.d.ts +1 -1
- package/dist/components/ui/InspectorPane.d.ts +1 -1
- package/dist/components/ui/InspectorPane.d.ts.map +1 -1
- package/dist/components/ui/InspectorPane.js +15 -4
- package/dist/components/ui/InspectorPane.js.map +1 -1
- package/dist/components/ui/Modal.d.ts.map +1 -1
- package/dist/components/ui/Modal.js +10 -2
- package/dist/components/ui/Modal.js.map +1 -1
- package/dist/components/ui/PageHeader.d.ts +28 -0
- package/dist/components/ui/PageHeader.d.ts.map +1 -0
- package/dist/components/ui/PageHeader.js +18 -0
- package/dist/components/ui/PageHeader.js.map +1 -0
- package/dist/components/ui/RowActions.d.ts +5 -0
- package/dist/components/ui/RowActions.d.ts.map +1 -1
- package/dist/components/ui/RowActions.js +7 -2
- package/dist/components/ui/RowActions.js.map +1 -1
- package/dist/components/ui/Segmented.d.ts +21 -0
- package/dist/components/ui/Segmented.d.ts.map +1 -0
- package/dist/components/ui/Segmented.js +41 -0
- package/dist/components/ui/Segmented.js.map +1 -0
- package/dist/components/ui/Toaster.d.ts +12 -0
- package/dist/components/ui/Toaster.d.ts.map +1 -0
- package/dist/components/ui/Toaster.js +103 -0
- package/dist/components/ui/Toaster.js.map +1 -0
- package/dist/components/ui/Toggle.d.ts +4 -3
- package/dist/components/ui/Toggle.d.ts.map +1 -1
- package/dist/components/ui/Toggle.js +16 -12
- package/dist/components/ui/Toggle.js.map +1 -1
- package/dist/components/ui/UnderlineTabs.d.ts +56 -0
- package/dist/components/ui/UnderlineTabs.d.ts.map +1 -0
- package/dist/components/ui/UnderlineTabs.js +205 -0
- package/dist/components/ui/UnderlineTabs.js.map +1 -0
- package/dist/components/ui/UnsavedBar.d.ts +25 -0
- package/dist/components/ui/UnsavedBar.d.ts.map +1 -0
- package/dist/components/ui/UnsavedBar.js +22 -0
- package/dist/components/ui/UnsavedBar.js.map +1 -0
- package/dist/components/ui/admin-links.d.ts +11 -0
- package/dist/components/ui/admin-links.d.ts.map +1 -0
- package/dist/components/ui/admin-links.js +10 -0
- package/dist/components/ui/admin-links.js.map +1 -0
- package/dist/components/ui/card-table.d.ts +43 -0
- package/dist/components/ui/card-table.d.ts.map +1 -0
- package/dist/components/ui/card-table.js +31 -0
- package/dist/components/ui/card-table.js.map +1 -0
- package/dist/components/virtual-window.d.ts +7 -0
- package/dist/components/virtual-window.d.ts.map +1 -1
- package/dist/components/virtual-window.js +5 -2
- package/dist/components/virtual-window.js.map +1 -1
- package/dist/fields/RelationshipField.js +1 -1
- package/dist/fields/RelationshipField.js.map +1 -1
- package/dist/files/dm-mono-latin-400-normal.woff +0 -0
- package/dist/files/dm-mono-latin-400-normal.woff2 +0 -0
- package/dist/files/dm-mono-latin-500-normal.woff +0 -0
- package/dist/files/dm-mono-latin-500-normal.woff2 +0 -0
- package/dist/files/dm-mono-latin-ext-400-normal.woff +0 -0
- package/dist/files/dm-mono-latin-ext-400-normal.woff2 +0 -0
- package/dist/files/dm-mono-latin-ext-500-normal.woff +0 -0
- package/dist/files/dm-mono-latin-ext-500-normal.woff2 +0 -0
- package/dist/files/dm-sans-latin-400-normal.woff +0 -0
- package/dist/files/dm-sans-latin-400-normal.woff2 +0 -0
- package/dist/files/dm-sans-latin-500-normal.woff +0 -0
- package/dist/files/dm-sans-latin-500-normal.woff2 +0 -0
- package/dist/files/dm-sans-latin-600-normal.woff +0 -0
- package/dist/files/dm-sans-latin-600-normal.woff2 +0 -0
- package/dist/files/dm-sans-latin-700-normal.woff +0 -0
- package/dist/files/dm-sans-latin-700-normal.woff2 +0 -0
- package/dist/files/dm-sans-latin-ext-400-normal.woff +0 -0
- package/dist/files/dm-sans-latin-ext-400-normal.woff2 +0 -0
- package/dist/files/dm-sans-latin-ext-500-normal.woff +0 -0
- package/dist/files/dm-sans-latin-ext-500-normal.woff2 +0 -0
- package/dist/files/dm-sans-latin-ext-600-normal.woff +0 -0
- package/dist/files/dm-sans-latin-ext-600-normal.woff2 +0 -0
- package/dist/files/dm-sans-latin-ext-700-normal.woff +0 -0
- package/dist/files/dm-sans-latin-ext-700-normal.woff2 +0 -0
- package/dist/hooks/useAppearanceBootstrap.d.ts.map +1 -1
- package/dist/hooks/useAppearanceBootstrap.js +9 -3
- package/dist/hooks/useAppearanceBootstrap.js.map +1 -1
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/layout/Header.d.ts +14 -5
- package/dist/layout/Header.d.ts.map +1 -1
- package/dist/layout/Header.js +78 -13
- package/dist/layout/Header.js.map +1 -1
- package/dist/layout/Layout.d.ts +5 -3
- package/dist/layout/Layout.d.ts.map +1 -1
- package/dist/layout/Layout.js +45 -54
- package/dist/layout/Layout.js.map +1 -1
- package/dist/layout/MobileTabBar.d.ts +20 -0
- package/dist/layout/MobileTabBar.d.ts.map +1 -0
- package/dist/layout/MobileTabBar.js +29 -0
- package/dist/layout/MobileTabBar.js.map +1 -0
- package/dist/layout/Sidebar.d.ts +8 -26
- package/dist/layout/Sidebar.d.ts.map +1 -1
- package/dist/layout/Sidebar.js +309 -345
- package/dist/layout/Sidebar.js.map +1 -1
- package/dist/layout/nav-config.d.ts +101 -0
- package/dist/layout/nav-config.d.ts.map +1 -0
- package/dist/layout/nav-config.js +297 -0
- package/dist/layout/nav-config.js.map +1 -0
- package/dist/layout/primitives/AdminShell.d.ts +10 -2
- package/dist/layout/primitives/AdminShell.d.ts.map +1 -1
- package/dist/layout/primitives/AdminShell.js +114 -6
- package/dist/layout/primitives/AdminShell.js.map +1 -1
- package/dist/layout/topbar-classes.d.ts +8 -0
- package/dist/layout/topbar-classes.d.ts.map +1 -0
- package/dist/layout/topbar-classes.js +8 -0
- package/dist/layout/topbar-classes.js.map +1 -0
- package/dist/layout/use-nav-items.d.ts +10 -0
- package/dist/layout/use-nav-items.d.ts.map +1 -0
- package/dist/layout/use-nav-items.js +39 -0
- package/dist/layout/use-nav-items.js.map +1 -0
- package/dist/lib/api.d.ts +8 -0
- package/dist/lib/api.d.ts.map +1 -1
- package/dist/lib/api.js +8 -1
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/appearance-api.d.ts +3 -1
- package/dist/lib/appearance-api.d.ts.map +1 -1
- package/dist/lib/appearance-api.js +1 -0
- package/dist/lib/appearance-api.js.map +1 -1
- package/dist/lib/batch-wizard.d.ts +84 -0
- package/dist/lib/batch-wizard.d.ts.map +1 -0
- package/dist/lib/batch-wizard.js +122 -0
- package/dist/lib/batch-wizard.js.map +1 -0
- package/dist/lib/chrome-service.d.ts +69 -0
- package/dist/lib/chrome-service.d.ts.map +1 -0
- package/dist/lib/chrome-service.js +108 -0
- package/dist/lib/chrome-service.js.map +1 -0
- package/dist/lib/job-drawer.d.ts +128 -0
- package/dist/lib/job-drawer.d.ts.map +1 -0
- package/dist/lib/job-drawer.js +351 -0
- package/dist/lib/job-drawer.js.map +1 -0
- package/dist/lib/job-view.d.ts +230 -0
- package/dist/lib/job-view.d.ts.map +1 -0
- package/dist/lib/job-view.js +419 -0
- package/dist/lib/job-view.js.map +1 -0
- package/dist/lib/jobs-service.d.ts +152 -0
- package/dist/lib/jobs-service.d.ts.map +1 -0
- package/dist/lib/jobs-service.js +220 -0
- package/dist/lib/jobs-service.js.map +1 -0
- package/dist/lib/sheet-focus.d.ts +24 -0
- package/dist/lib/sheet-focus.d.ts.map +1 -0
- package/dist/lib/sheet-focus.js +61 -0
- package/dist/lib/sheet-focus.js.map +1 -0
- package/dist/lib/tiers.d.ts +30 -0
- package/dist/lib/tiers.d.ts.map +1 -0
- package/dist/lib/tiers.js +43 -0
- package/dist/lib/tiers.js.map +1 -0
- package/dist/prenta-admin.css +1 -1
- package/dist/router/admin-routes.d.ts.map +1 -1
- package/dist/router/admin-routes.js +8 -0
- package/dist/router/admin-routes.js.map +1 -1
- package/dist/router/index.d.ts +5 -1
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +7 -0
- package/dist/router/index.js.map +1 -1
- package/dist/views/ApiKeys.js +2 -2
- package/dist/views/ApiKeys.js.map +1 -1
- package/dist/views/AppearanceChrome.d.ts +24 -0
- package/dist/views/AppearanceChrome.d.ts.map +1 -0
- package/dist/views/AppearanceChrome.js +461 -0
- package/dist/views/AppearanceChrome.js.map +1 -0
- package/dist/views/CollectionList.d.ts.map +1 -1
- package/dist/views/CollectionList.js +73 -53
- package/dist/views/CollectionList.js.map +1 -1
- package/dist/views/Dashboard.d.ts.map +1 -1
- package/dist/views/Dashboard.js +14 -8
- package/dist/views/Dashboard.js.map +1 -1
- package/dist/views/DocumentEdit.d.ts +6 -1
- package/dist/views/DocumentEdit.d.ts.map +1 -1
- package/dist/views/DocumentEdit.js +44 -8
- package/dist/views/DocumentEdit.js.map +1 -1
- package/dist/views/FormDeliveries.d.ts.map +1 -1
- package/dist/views/FormDeliveries.js +7 -1
- package/dist/views/FormDeliveries.js.map +1 -1
- package/dist/views/FormEntries.d.ts.map +1 -1
- package/dist/views/FormEntries.js +11 -2
- package/dist/views/FormEntries.js.map +1 -1
- package/dist/views/FormSubmissions.d.ts +1 -1
- package/dist/views/FormSubmissions.d.ts.map +1 -1
- package/dist/views/FormSubmissions.js +15 -4
- package/dist/views/FormSubmissions.js.map +1 -1
- package/dist/views/Forms.d.ts.map +1 -1
- package/dist/views/Forms.js +6 -4
- package/dist/views/Forms.js.map +1 -1
- package/dist/views/FormsSettings.d.ts +2 -0
- package/dist/views/FormsSettings.d.ts.map +1 -0
- package/dist/views/FormsSettings.js +37 -0
- package/dist/views/FormsSettings.js.map +1 -0
- package/dist/views/Jobs/BusyButton.d.ts +15 -0
- package/dist/views/Jobs/BusyButton.d.ts.map +1 -0
- package/dist/views/Jobs/BusyButton.js +26 -0
- package/dist/views/Jobs/BusyButton.js.map +1 -0
- package/dist/views/Jobs/CancelJobDialog.d.ts +27 -0
- package/dist/views/Jobs/CancelJobDialog.d.ts.map +1 -0
- package/dist/views/Jobs/CancelJobDialog.js +76 -0
- package/dist/views/Jobs/CancelJobDialog.js.map +1 -0
- package/dist/views/Jobs/DrawerActivity.d.ts +16 -0
- package/dist/views/Jobs/DrawerActivity.d.ts.map +1 -0
- package/dist/views/Jobs/DrawerActivity.js +59 -0
- package/dist/views/Jobs/DrawerActivity.js.map +1 -0
- package/dist/views/Jobs/DrawerOverview.d.ts +28 -0
- package/dist/views/Jobs/DrawerOverview.d.ts.map +1 -0
- package/dist/views/Jobs/DrawerOverview.js +32 -0
- package/dist/views/Jobs/DrawerOverview.js.map +1 -0
- package/dist/views/Jobs/DrawerResults.d.ts +25 -0
- package/dist/views/Jobs/DrawerResults.d.ts.map +1 -0
- package/dist/views/Jobs/DrawerResults.js +50 -0
- package/dist/views/Jobs/DrawerResults.js.map +1 -0
- package/dist/views/Jobs/DrawerReview.d.ts +51 -0
- package/dist/views/Jobs/DrawerReview.d.ts.map +1 -0
- package/dist/views/Jobs/DrawerReview.js +110 -0
- package/dist/views/Jobs/DrawerReview.js.map +1 -0
- package/dist/views/Jobs/JobDrawer.d.ts +51 -0
- package/dist/views/Jobs/JobDrawer.d.ts.map +1 -0
- package/dist/views/Jobs/JobDrawer.js +378 -0
- package/dist/views/Jobs/JobDrawer.js.map +1 -0
- package/dist/views/Jobs/JobsTable.d.ts +21 -0
- package/dist/views/Jobs/JobsTable.d.ts.map +1 -0
- package/dist/views/Jobs/JobsTable.js +81 -0
- package/dist/views/Jobs/JobsTable.js.map +1 -0
- package/dist/views/Jobs/NewBatchJob.d.ts +34 -0
- package/dist/views/Jobs/NewBatchJob.d.ts.map +1 -0
- package/dist/views/Jobs/NewBatchJob.js +282 -0
- package/dist/views/Jobs/NewBatchJob.js.map +1 -0
- package/dist/views/Jobs/WorkerStrip.d.ts +24 -0
- package/dist/views/Jobs/WorkerStrip.d.ts.map +1 -0
- package/dist/views/Jobs/WorkerStrip.js +63 -0
- package/dist/views/Jobs/WorkerStrip.js.map +1 -0
- package/dist/views/Jobs/atoms.d.ts +19 -0
- package/dist/views/Jobs/atoms.d.ts.map +1 -0
- package/dist/views/Jobs/atoms.js +52 -0
- package/dist/views/Jobs/atoms.js.map +1 -0
- package/dist/views/Jobs/focus.d.ts +29 -0
- package/dist/views/Jobs/focus.d.ts.map +1 -0
- package/dist/views/Jobs/focus.js +64 -0
- package/dist/views/Jobs/focus.js.map +1 -0
- package/dist/views/Jobs/icons.d.ts +22 -0
- package/dist/views/Jobs/icons.d.ts.map +1 -0
- package/dist/views/Jobs/icons.js +23 -0
- package/dist/views/Jobs/icons.js.map +1 -0
- package/dist/views/Jobs/useJobDetail.d.ts +21 -0
- package/dist/views/Jobs/useJobDetail.d.ts.map +1 -0
- package/dist/views/Jobs/useJobDetail.js +39 -0
- package/dist/views/Jobs/useJobDetail.js.map +1 -0
- package/dist/views/Jobs/useJobsFeed.d.ts +35 -0
- package/dist/views/Jobs/useJobsFeed.d.ts.map +1 -0
- package/dist/views/Jobs/useJobsFeed.js +231 -0
- package/dist/views/Jobs/useJobsFeed.js.map +1 -0
- package/dist/views/Jobs/useReviewItems.d.ts +39 -0
- package/dist/views/Jobs/useReviewItems.d.ts.map +1 -0
- package/dist/views/Jobs/useReviewItems.js +140 -0
- package/dist/views/Jobs/useReviewItems.js.map +1 -0
- package/dist/views/Jobs.d.ts +19 -1
- package/dist/views/Jobs.d.ts.map +1 -1
- package/dist/views/Jobs.js +204 -35
- package/dist/views/Jobs.js.map +1 -1
- package/dist/views/MediaBrowser.d.ts.map +1 -1
- package/dist/views/MediaBrowser.js +37 -9
- package/dist/views/MediaBrowser.js.map +1 -1
- package/dist/views/Pages/PagesListView.d.ts +1 -1
- package/dist/views/Pages/PagesListView.d.ts.map +1 -1
- package/dist/views/Pages/PagesListView.js +34 -5
- package/dist/views/Pages/PagesListView.js.map +1 -1
- package/dist/views/Posts/NewPostTypeInstructions.d.ts.map +1 -1
- package/dist/views/Posts/NewPostTypeInstructions.js +12 -2
- package/dist/views/Posts/NewPostTypeInstructions.js.map +1 -1
- package/dist/views/Posts/PostTypesView.d.ts.map +1 -1
- package/dist/views/Posts/PostTypesView.js +10 -1
- package/dist/views/Posts/PostTypesView.js.map +1 -1
- package/dist/views/Posts/PostsListView.d.ts +1 -2
- package/dist/views/Posts/PostsListView.d.ts.map +1 -1
- package/dist/views/Posts/PostsListView.js +31 -3
- package/dist/views/Posts/PostsListView.js.map +1 -1
- package/dist/views/SEO.d.ts.map +1 -1
- package/dist/views/SEO.js +3 -3
- package/dist/views/SEO.js.map +1 -1
- package/dist/views/ScriptTags.d.ts.map +1 -1
- package/dist/views/ScriptTags.js +20 -15
- package/dist/views/ScriptTags.js.map +1 -1
- package/dist/views/Settings.d.ts.map +1 -1
- package/dist/views/Settings.js +115 -51
- package/dist/views/Settings.js.map +1 -1
- package/dist/views/SpamFolder.d.ts +2 -0
- package/dist/views/SpamFolder.d.ts.map +1 -0
- package/dist/views/SpamFolder.js +14 -0
- package/dist/views/SpamFolder.js.map +1 -0
- package/dist/views/Trash.d.ts +6 -1
- package/dist/views/Trash.d.ts.map +1 -1
- package/dist/views/Trash.js +7 -2
- package/dist/views/Trash.js.map +1 -1
- package/dist/views/Users.js +2 -2
- package/dist/views/Users.js.map +1 -1
- package/dist/views/WidgetsPlaceholder.d.ts +2 -0
- package/dist/views/WidgetsPlaceholder.d.ts.map +1 -0
- package/dist/views/WidgetsPlaceholder.js +15 -0
- package/dist/views/WidgetsPlaceholder.js.map +1 -0
- package/dist/views/dashboard/kpi-grid.d.ts +18 -0
- package/dist/views/dashboard/kpi-grid.d.ts.map +1 -0
- package/dist/views/dashboard/kpi-grid.js +36 -0
- package/dist/views/dashboard/kpi-grid.js.map +1 -0
- package/dist/views/header-footer/AnnouncementTab.d.ts +15 -0
- package/dist/views/header-footer/AnnouncementTab.d.ts.map +1 -0
- package/dist/views/header-footer/AnnouncementTab.js +43 -0
- package/dist/views/header-footer/AnnouncementTab.js.map +1 -0
- package/dist/views/header-footer/ChromeField.d.ts +25 -0
- package/dist/views/header-footer/ChromeField.d.ts.map +1 -0
- package/dist/views/header-footer/ChromeField.js +99 -0
- package/dist/views/header-footer/ChromeField.js.map +1 -0
- package/dist/views/header-footer/ChromePreview.d.ts +31 -0
- package/dist/views/header-footer/ChromePreview.d.ts.map +1 -0
- package/dist/views/header-footer/ChromePreview.js +195 -0
- package/dist/views/header-footer/ChromePreview.js.map +1 -0
- package/dist/views/header-footer/DeveloperTab.d.ts +17 -0
- package/dist/views/header-footer/DeveloperTab.d.ts.map +1 -0
- package/dist/views/header-footer/DeveloperTab.js +98 -0
- package/dist/views/header-footer/DeveloperTab.js.map +1 -0
- package/dist/views/header-footer/RegionTab.d.ts +27 -0
- package/dist/views/header-footer/RegionTab.d.ts.map +1 -0
- package/dist/views/header-footer/RegionTab.js +80 -0
- package/dist/views/header-footer/RegionTab.js.map +1 -0
- package/dist/views/header-footer/chrome-form.d.ts +137 -0
- package/dist/views/header-footer/chrome-form.d.ts.map +1 -0
- package/dist/views/header-footer/chrome-form.js +518 -0
- package/dist/views/header-footer/chrome-form.js.map +1 -0
- package/dist/views/header-footer/code-samples.d.ts +30 -0
- package/dist/views/header-footer/code-samples.d.ts.map +1 -0
- package/dist/views/header-footer/code-samples.js +127 -0
- package/dist/views/header-footer/code-samples.js.map +1 -0
- package/dist/views/header-footer/controls.d.ts +57 -0
- package/dist/views/header-footer/controls.d.ts.map +1 -0
- package/dist/views/header-footer/controls.js +43 -0
- package/dist/views/header-footer/controls.js.map +1 -0
- package/dist/views/lazy-views.d.ts +4 -0
- package/dist/views/lazy-views.d.ts.map +1 -1
- package/dist/views/lazy-views.js +4 -0
- package/dist/views/lazy-views.js.map +1 -1
- package/dist/views/page-editor/PageTab.js +1 -1
- package/dist/views/page-editor/PageTab.js.map +1 -1
- package/dist/views/page-editor/ReviewBar.js +1 -1
- package/dist/views/page-editor/ReviewBar.js.map +1 -1
- package/dist/views/page-editor/VersionHistoryPanel.js +1 -1
- package/dist/views/page-editor/VersionHistoryPanel.js.map +1 -1
- package/dist/views/seo/AuditTab.js +1 -1
- package/dist/views/seo/AuditTab.js.map +1 -1
- package/dist/views/seo/OverviewTab.d.ts.map +1 -1
- package/dist/views/seo/OverviewTab.js +2 -2
- package/dist/views/seo/OverviewTab.js.map +1 -1
- package/dist/views/seo/ProposalsTab.js +1 -1
- package/dist/views/seo/ProposalsTab.js.map +1 -1
- package/dist/views/settings/AISettingsTab.d.ts.map +1 -1
- package/dist/views/settings/AISettingsTab.js +4 -2
- package/dist/views/settings/AISettingsTab.js.map +1 -1
- package/dist/views/settings/AccessProtectionCard.js +1 -1
- package/dist/views/settings/AccessProtectionCard.js.map +1 -1
- package/dist/views/settings/AdminThemeCard.d.ts.map +1 -1
- package/dist/views/settings/AdminThemeCard.js +63 -15
- package/dist/views/settings/AdminThemeCard.js.map +1 -1
- package/dist/views/settings/AppearanceTab.d.ts.map +1 -1
- package/dist/views/settings/AppearanceTab.js +4 -2
- package/dist/views/settings/AppearanceTab.js.map +1 -1
- package/dist/views/settings/BrandPreviewCard.js +1 -1
- package/dist/views/settings/BrandPreviewCard.js.map +1 -1
- package/dist/views/settings/BrandVoiceCard.js +1 -1
- package/dist/views/settings/BrandVoiceCard.js.map +1 -1
- package/dist/views/settings/EmailSettingsTab.d.ts.map +1 -1
- package/dist/views/settings/EmailSettingsTab.js +5 -3
- package/dist/views/settings/EmailSettingsTab.js.map +1 -1
- package/dist/views/settings/GeneralSettingsTab.d.ts.map +1 -1
- package/dist/views/settings/GeneralSettingsTab.js +4 -2
- package/dist/views/settings/GeneralSettingsTab.js.map +1 -1
- package/dist/views/settings/ProviderConnectionCard.js +1 -1
- package/dist/views/settings/ProviderConnectionCard.js.map +1 -1
- package/dist/views/settings/SearchDataCard.js +1 -1
- package/dist/views/settings/SearchDataCard.js.map +1 -1
- package/dist/views/settings/SecurityStatusCard.js +2 -2
- package/dist/views/settings/SecurityStatusCard.js.map +1 -1
- package/dist/views/settings/SecurityTab.d.ts.map +1 -1
- package/dist/views/settings/SecurityTab.js +4 -2
- package/dist/views/settings/SecurityTab.js.map +1 -1
- package/dist/views/settings/SeoAutopilotCard.js +2 -2
- package/dist/views/settings/SeoAutopilotCard.js.map +1 -1
- package/dist/views/settings/SeoSettingsTab.d.ts.map +1 -1
- package/dist/views/settings/SeoSettingsTab.js +5 -3
- package/dist/views/settings/SeoSettingsTab.js.map +1 -1
- package/dist/views/settings/SiteIndexStatusCard.js +1 -1
- package/dist/views/settings/SiteIndexStatusCard.js.map +1 -1
- package/dist/views/settings/SiteThemeCard.js +1 -1
- package/dist/views/settings/UpdatesTab.d.ts.map +1 -1
- package/dist/views/settings/UpdatesTab.js +6 -5
- package/dist/views/settings/UpdatesTab.js.map +1 -1
- package/dist/views/settings/components.d.ts +7 -11
- package/dist/views/settings/components.d.ts.map +1 -1
- package/dist/views/settings/components.js +18 -12
- package/dist/views/settings/components.js.map +1 -1
- package/dist/views/settings/useAppearanceSettings.d.ts +7 -1
- package/dist/views/settings/useAppearanceSettings.d.ts.map +1 -1
- package/dist/views/settings/useAppearanceSettings.js +89 -22
- package/dist/views/settings/useAppearanceSettings.js.map +1 -1
- package/dist/views/users/UserDetailDrawer.js +1 -1
- package/dist/views/users/UserDetailDrawer.js.map +1 -1
- package/package.json +10 -8
- package/src/AdminRoot.tsx +103 -31
- package/src/LoginRoot.tsx +2 -1
- package/src/__tests__/components/author-avatar.test.tsx +3 -20
- package/src/__tests__/components/notification-bell.test.tsx +146 -14
- package/src/__tests__/components/responsive-tiers.render.test.tsx +461 -0
- package/src/__tests__/components/serp-preview.render.test.tsx +6 -3
- package/src/__tests__/components/shell-primitives.render.test.tsx +951 -0
- package/src/__tests__/components/theme-provider-accent.test.tsx +83 -8
- package/src/__tests__/components/toggle.test.tsx +11 -3
- package/src/__tests__/components/ui-primitives.test.tsx +5 -8
- package/src/__tests__/layout/build-nav-items.test.ts +1 -1
- package/src/__tests__/layout/shell-nav.render.test.tsx +983 -0
- package/src/__tests__/layout/sidebar-forms-submenu.render.test.tsx +8 -4
- package/src/__tests__/layout/sidebar-groups.render.test.tsx +116 -0
- package/src/__tests__/layout/sidebar-menus.render.test.tsx +116 -0
- package/src/__tests__/layout/sidebar-plugin-nav.test.ts +1 -1
- package/src/__tests__/layout/sidebar-posts.test.ts +48 -40
- package/src/__tests__/layout/sidebar-submenu.render.test.tsx +35 -10
- package/src/__tests__/layout/topbar.render.test.tsx +464 -0
- package/src/__tests__/lib/api.test.ts +2 -0
- package/src/__tests__/lib/batch-wizard.test.ts +199 -0
- package/src/__tests__/lib/job-drawer.test.ts +495 -0
- package/src/__tests__/lib/job-view.test.ts +558 -0
- package/src/__tests__/lib/jobs-service.test.ts +167 -0
- package/src/__tests__/router/admin-route-order.test.ts +39 -0
- package/src/__tests__/styles/ai-gradient-contrast.test.ts +135 -0
- package/src/__tests__/styles/breakpoint-order.test.ts +68 -0
- package/src/__tests__/styles/responsive-layer.test.ts +367 -12
- package/src/__tests__/styles/tailwind-preset.test.ts +154 -0
- package/src/__tests__/styles/theme-token-scope.test.ts +10 -3
- package/src/__tests__/styles/tiers.test.ts +136 -0
- package/src/__tests__/styles/tokens-drift.test.ts +67 -6
- package/src/__tests__/views/admin-lazy-route.render.test.tsx +41 -1
- package/src/__tests__/views/ai-settings.render.test.tsx +4 -4
- package/src/__tests__/views/appearance-chrome.render.test.tsx +818 -0
- package/src/__tests__/views/appearance-menus-route.render.test.tsx +58 -0
- package/src/__tests__/views/appearance-settings.render.test.tsx +10 -8
- package/src/__tests__/views/appearance-theme-provider.render.test.tsx +347 -0
- package/src/__tests__/views/dashboard.test.tsx +48 -0
- package/src/__tests__/views/document-edit-navigation.render.test.tsx +130 -0
- package/src/__tests__/views/document-edit-routes.render.test.tsx +130 -0
- package/src/__tests__/views/email-settings.render.test.tsx +2 -2
- package/src/__tests__/views/form-entries.render.test.tsx +22 -0
- package/src/__tests__/views/form-submissions.render.test.tsx +22 -0
- package/src/__tests__/views/forms-list.render.test.tsx +13 -0
- package/src/__tests__/views/general-settings.render.test.tsx +38 -11
- package/src/__tests__/views/header-footer-form.test.ts +333 -0
- package/src/__tests__/views/jobs-drawer.render.test.tsx +1553 -0
- package/src/__tests__/views/jobs-list.render.test.tsx +853 -0
- package/src/__tests__/views/jobs-wizard.render.test.tsx +707 -0
- package/src/__tests__/views/kpi-grid.test.ts +29 -0
- package/src/__tests__/views/post-section-editor.test.tsx +5 -1
- package/src/__tests__/views/script-tags.render.test.tsx +29 -0
- package/src/__tests__/views/security-settings.render.test.tsx +9 -10
- package/src/__tests__/views/seo-settings.render.test.tsx +7 -9
- package/src/__tests__/views/settings-save-bar.render.test.tsx +91 -0
- package/src/__tests__/views/settings-save-footer.render.test.tsx +25 -15
- package/src/__tests__/views/settings-tabs.render.test.tsx +371 -0
- package/src/__tests__/views/updates-tab.render.test.tsx +4 -3
- package/src/components/Breadcrumbs.tsx +7 -1
- package/src/components/CommandPalette.tsx +51 -3
- package/src/components/LocaleSwitcher.tsx +5 -6
- package/src/components/NotificationBell.tsx +74 -18
- package/src/components/OfflineStatus.tsx +1 -1
- package/src/components/PresenceIndicator.tsx +2 -1
- package/src/components/ReflowMeter.tsx +3 -3
- package/src/components/SEOPanel.tsx +2 -2
- package/src/components/ThemeProvider.tsx +122 -42
- package/src/components/TipTapEditor.tsx +3 -4
- package/src/components/forms/EmbedPanel.tsx +1 -1
- package/src/components/forms/FormEntryDetailPane.tsx +7 -1
- package/src/components/forms/ShortcodeGlossary.tsx +7 -1
- package/src/components/forms/primitives.tsx +37 -21
- package/src/components/pages/tag-badges.tsx +4 -3
- package/src/components/seo/PageAuditPanel.tsx +2 -2
- package/src/components/seo/SerpPreview.tsx +5 -5
- package/src/components/seo/primitives.tsx +2 -2
- package/src/components/ui/AuthorAvatar.tsx +11 -10
- package/src/components/ui/Badge.tsx +1 -1
- package/src/components/ui/Breadcrumb.tsx +109 -0
- package/src/components/ui/Button.tsx +40 -15
- package/src/components/ui/Card.tsx +35 -32
- package/src/components/ui/CardListControls.tsx +90 -0
- package/src/components/ui/CountChip.tsx +90 -0
- package/src/components/ui/FilterPill.tsx +5 -3
- package/src/components/ui/InspectorPane.tsx +21 -7
- package/src/components/ui/Modal.tsx +20 -6
- package/src/components/ui/PageHeader.tsx +63 -0
- package/src/components/ui/RowActions.tsx +7 -2
- package/src/components/ui/Segmented.tsx +97 -0
- package/src/components/ui/Toaster.tsx +139 -0
- package/src/components/ui/Toggle.tsx +18 -14
- package/src/components/ui/UnderlineTabs.tsx +373 -0
- package/src/components/ui/UnsavedBar.tsx +119 -0
- package/src/components/ui/admin-links.tsx +20 -0
- package/src/components/ui/card-table.ts +34 -0
- package/src/components/virtual-window.tsx +13 -2
- package/src/fields/RelationshipField.tsx +1 -1
- package/src/hooks/useAppearanceBootstrap.ts +9 -3
- package/src/index.ts +19 -0
- package/src/layout/Header.tsx +210 -135
- package/src/layout/Layout.tsx +61 -108
- package/src/layout/MobileTabBar.tsx +92 -0
- package/src/layout/Sidebar.tsx +555 -593
- package/src/layout/nav-config.tsx +425 -0
- package/src/layout/primitives/AdminShell.tsx +154 -6
- package/src/layout/topbar-classes.ts +8 -0
- package/src/layout/use-nav-items.ts +40 -0
- package/src/lib/api.ts +18 -1
- package/src/lib/appearance-api.ts +4 -0
- package/src/lib/batch-wizard.ts +188 -0
- package/src/lib/chrome-service.ts +200 -0
- package/src/lib/job-drawer.ts +424 -0
- package/src/lib/job-view.ts +550 -0
- package/src/lib/jobs-service.ts +345 -0
- package/src/lib/sheet-focus.ts +71 -0
- package/src/lib/tiers.ts +43 -0
- package/src/router/admin-routes.ts +8 -0
- package/src/router/index.ts +9 -1
- package/src/styles/prenta-tokens.css +280 -82
- package/src/styles/responsive.css +460 -22
- package/src/styles/theme.css +192 -28
- package/src/views/ApiKeys.tsx +2 -2
- package/src/views/AppearanceChrome.tsx +732 -0
- package/src/views/CollectionList.tsx +264 -205
- package/src/views/Dashboard.tsx +26 -13
- package/src/views/DocumentEdit.tsx +111 -56
- package/src/views/FormDeliveries.tsx +30 -17
- package/src/views/FormEntries.tsx +28 -20
- package/src/views/FormSubmissions.tsx +32 -34
- package/src/views/Forms.tsx +55 -34
- package/src/views/FormsSettings.tsx +94 -0
- package/src/views/Jobs/BusyButton.tsx +56 -0
- package/src/views/Jobs/CancelJobDialog.tsx +145 -0
- package/src/views/Jobs/DrawerActivity.tsx +142 -0
- package/src/views/Jobs/DrawerOverview.tsx +139 -0
- package/src/views/Jobs/DrawerResults.tsx +155 -0
- package/src/views/Jobs/DrawerReview.tsx +464 -0
- package/src/views/Jobs/JobDrawer.tsx +636 -0
- package/src/views/Jobs/JobsTable.tsx +267 -0
- package/src/views/Jobs/NewBatchJob.tsx +857 -0
- package/src/views/Jobs/WorkerStrip.tsx +149 -0
- package/src/views/Jobs/atoms.tsx +93 -0
- package/src/views/Jobs/focus.ts +67 -0
- package/src/views/Jobs/icons.tsx +111 -0
- package/src/views/Jobs/useJobDetail.ts +64 -0
- package/src/views/Jobs/useJobsFeed.ts +249 -0
- package/src/views/Jobs/useReviewItems.ts +187 -0
- package/src/views/Jobs.tsx +396 -105
- package/src/views/MediaBrowser.tsx +71 -21
- package/src/views/Pages/PagesListView.tsx +115 -39
- package/src/views/Posts/NewPostTypeInstructions.tsx +15 -10
- package/src/views/Posts/PostTypesView.tsx +28 -6
- package/src/views/Posts/PostsListView.tsx +130 -40
- package/src/views/SEO.tsx +23 -8
- package/src/views/ScriptTags.tsx +233 -153
- package/src/views/Settings.tsx +215 -256
- package/src/views/SpamFolder.tsx +32 -0
- package/src/views/Trash.tsx +12 -1
- package/src/views/Users.tsx +2 -2
- package/src/views/WidgetsPlaceholder.tsx +33 -0
- package/src/views/dashboard/kpi-grid.ts +38 -0
- package/src/views/header-footer/AnnouncementTab.tsx +231 -0
- package/src/views/header-footer/ChromeField.tsx +358 -0
- package/src/views/header-footer/ChromePreview.tsx +497 -0
- package/src/views/header-footer/DeveloperTab.tsx +331 -0
- package/src/views/header-footer/RegionTab.tsx +398 -0
- package/src/views/header-footer/chrome-form.ts +603 -0
- package/src/views/header-footer/code-samples.ts +146 -0
- package/src/views/header-footer/controls.tsx +166 -0
- package/src/views/lazy-views.tsx +12 -0
- package/src/views/page-editor/PageTab.tsx +2 -2
- package/src/views/page-editor/ReviewBar.tsx +1 -1
- package/src/views/page-editor/VersionHistoryPanel.tsx +1 -1
- package/src/views/seo/AuditTab.tsx +1 -1
- package/src/views/seo/OverviewTab.tsx +6 -5
- package/src/views/seo/ProposalsTab.tsx +1 -1
- package/src/views/settings/AISettingsTab.tsx +10 -6
- package/src/views/settings/AccessProtectionCard.tsx +1 -1
- package/src/views/settings/AdminThemeCard.tsx +228 -35
- package/src/views/settings/AppearanceTab.tsx +10 -6
- package/src/views/settings/BrandPreviewCard.tsx +1 -1
- package/src/views/settings/BrandVoiceCard.tsx +1 -1
- package/src/views/settings/EmailSettingsTab.tsx +11 -7
- package/src/views/settings/GeneralSettingsTab.tsx +10 -6
- package/src/views/settings/ProviderConnectionCard.tsx +1 -1
- package/src/views/settings/SearchDataCard.tsx +1 -1
- package/src/views/settings/SecurityStatusCard.tsx +2 -2
- package/src/views/settings/SecurityTab.tsx +10 -6
- package/src/views/settings/SeoAutopilotCard.tsx +2 -2
- package/src/views/settings/SeoSettingsTab.tsx +13 -9
- package/src/views/settings/SiteIndexStatusCard.tsx +1 -1
- package/src/views/settings/SiteThemeCard.tsx +1 -1
- package/src/views/settings/UpdatesTab.tsx +107 -101
- package/src/views/settings/components.tsx +26 -62
- package/src/views/settings/useAppearanceSettings.ts +116 -25
- package/src/views/users/UserDetailDrawer.tsx +1 -1
- package/dist/components/ui/StatPill.d.ts +0 -18
- package/dist/components/ui/StatPill.d.ts.map +0 -1
- package/dist/components/ui/StatPill.js +0 -5
- package/dist/components/ui/StatPill.js.map +0 -1
- package/src/components/ui/StatPill.tsx +0 -37
package/dist/layout/Sidebar.js
CHANGED
|
@@ -2,28 +2,15 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect, useRef, useState } from 'react';
|
|
4
4
|
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
|
|
5
|
+
import { accentPickCssVars, generateAdminThemeTokens } from '@prenta/core/appearance';
|
|
6
|
+
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
|
5
7
|
import { adminPortalContainer } from '../lib/portal-container.js';
|
|
8
|
+
import { TIER_MEDIA } from '../lib/tiers.js';
|
|
6
9
|
import { useTheme } from '../components/ThemeProvider.js';
|
|
7
|
-
import { fetchFormsSidebarCounts } from '../lib/forms-service.js';
|
|
8
|
-
import { onFormsChanged } from '../lib/forms-events.js';
|
|
9
|
-
import { LayoutDashboard, FileText, File, Image, Settings, ChevronDown, ClipboardList, Inbox, AlertTriangle, Search as SearchIcon, Briefcase, FolderOpen, BookOpen, HelpCircle, Newspaper, PanelTop, PanelBottom, Layers, Code2, ListTree, Menu as MenuIcon, PanelLeftClose, PanelLeftOpen, Trash2, ListTodo, } from 'lucide-react';
|
|
10
10
|
import { PrentaBrandLogo, PrentaMark } from '../assets/prenta-logo.js';
|
|
11
11
|
import { LogoPlaceholder } from '../components/LogoPlaceholder.js';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
'file-text': FileText,
|
|
15
|
-
briefcase: Briefcase,
|
|
16
|
-
folder: FolderOpen,
|
|
17
|
-
book: BookOpen,
|
|
18
|
-
help: HelpCircle,
|
|
19
|
-
newspaper: Newspaper,
|
|
20
|
-
navigation: ListTree,
|
|
21
|
-
menu: MenuIcon,
|
|
22
|
-
'list-tree': ListTree,
|
|
23
|
-
PanelTop: PanelTop,
|
|
24
|
-
PanelBottom: PanelBottom,
|
|
25
|
-
Layers: Layers,
|
|
26
|
-
};
|
|
12
|
+
import { activeChildPath, hasActiveDescendant, isPathActive } from './nav-config.js';
|
|
13
|
+
import { useNavItems } from './use-nav-items.js';
|
|
27
14
|
/**
|
|
28
15
|
* Sidebar brand lockup.
|
|
29
16
|
*
|
|
@@ -34,7 +21,8 @@ const ICON_MAP = {
|
|
|
34
21
|
* un-branded installs. The placeholder replaces the old initials badge, which
|
|
35
22
|
* read as a user avatar (the real account avatar already sits top-right).
|
|
36
23
|
* Dark-mode uses the dark logo when one is configured. Logos are never
|
|
37
|
-
* stretched/cropped (object-contain).
|
|
24
|
+
* stretched/cropped (object-contain). Kit sizes (cms-responsive.css): the
|
|
25
|
+
* full logo is 24px tall and at most 150px wide; the rail mark is 26px.
|
|
38
26
|
*/
|
|
39
27
|
function BrandLogo({ config, collapsed }) {
|
|
40
28
|
const { adminBrand, resolvedTheme } = useTheme();
|
|
@@ -59,241 +47,279 @@ function BrandLogo({ config, collapsed }) {
|
|
|
59
47
|
const mark = usable(adminBrand.markUrl);
|
|
60
48
|
const cfg = usable(configLogo);
|
|
61
49
|
const alt = brandName ?? 'Admin';
|
|
62
|
-
// Wide horizontal logos
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
const logoClass = 'h-8 w-auto max-w-full object-contain';
|
|
50
|
+
// Wide horizontal logos scale down to fit the rail / sidebar header instead
|
|
51
|
+
// of overflowing: height-capped, width auto, never wider than the slot.
|
|
52
|
+
const logoClass = 'h-6 w-auto max-w-full object-contain';
|
|
66
53
|
if (collapsed) {
|
|
67
54
|
// Collapsed rail prefers a dedicated square mark; otherwise it shows the
|
|
68
55
|
// logo (scaled to fit) — never the favicon.
|
|
69
56
|
if (mark)
|
|
70
|
-
return _jsx("img", { src: mark, alt: alt, className: "h-
|
|
57
|
+
return (_jsx("img", { src: mark, alt: alt, className: "h-[26px] w-[26px] object-contain", onError: onErr(mark) }));
|
|
71
58
|
if (primary)
|
|
72
59
|
return _jsx("img", { src: primary, alt: alt, className: logoClass, onError: onErr(primary) });
|
|
73
60
|
if (cfg)
|
|
74
61
|
return _jsx("img", { src: cfg, alt: alt, className: logoClass, onError: onErr(cfg) });
|
|
75
62
|
if (hasInitials)
|
|
76
63
|
return _jsx(LogoPlaceholder, { tone: "sidebar" });
|
|
77
|
-
return _jsx(PrentaMark, { className: "h-
|
|
64
|
+
return _jsx(PrentaMark, { className: "h-[26px] w-[26px]" });
|
|
78
65
|
}
|
|
79
66
|
if (primary) {
|
|
80
|
-
return (_jsx("div", { className: "flex min-w-0 items-center gap-2.5", children: _jsx("img", { src: primary, alt: alt, className: logoClass, onError: onErr(primary) }) }));
|
|
67
|
+
return (_jsx("div", { className: "flex max-w-[150px] min-w-0 items-center gap-2.5", children: _jsx("img", { src: primary, alt: alt, className: logoClass, onError: onErr(primary) }) }));
|
|
81
68
|
}
|
|
82
69
|
if (cfg) {
|
|
83
|
-
return (_jsx("div", { className: "flex min-w-0 items-center gap-2.5", children: _jsx("img", { src: cfg, alt: alt, className: logoClass, onError: onErr(cfg) }) }));
|
|
70
|
+
return (_jsx("div", { className: "flex max-w-[150px] min-w-0 items-center gap-2.5", children: _jsx("img", { src: cfg, alt: alt, className: logoClass, onError: onErr(cfg) }) }));
|
|
84
71
|
}
|
|
85
72
|
if (mark) {
|
|
86
|
-
return (_jsxs("div", { className: "flex min-w-0 items-center gap-2.5", children: [_jsx("img", { src: mark, alt: alt, className: "h-
|
|
73
|
+
return (_jsxs("div", { className: "flex min-w-0 items-center gap-2.5", children: [_jsx("img", { src: mark, alt: alt, className: "h-[26px] w-[26px] shrink-0 object-contain", onError: onErr(mark) }), _jsx("span", { className: "text-body text-txt truncate font-medium", children: brandName ?? alt })] }));
|
|
87
74
|
}
|
|
88
75
|
if (hasInitials) {
|
|
89
76
|
return _jsx(LogoPlaceholder, { tone: "sidebar", label: brandName ?? alt });
|
|
90
77
|
}
|
|
91
78
|
if (brandName) {
|
|
92
|
-
return (_jsxs("div", { className: "flex min-w-0 items-center gap-2.5", children: [_jsx(PrentaMark, { className: "h-
|
|
79
|
+
return (_jsxs("div", { className: "flex min-w-0 items-center gap-2.5", children: [_jsx(PrentaMark, { className: "h-[26px] w-[26px] shrink-0" }), _jsx("span", { className: "text-body text-txt truncate font-medium", children: brandName })] }));
|
|
93
80
|
}
|
|
94
|
-
return _jsx(PrentaBrandLogo, { className: "h-
|
|
81
|
+
return _jsx(PrentaBrandLogo, { className: "h-6 w-auto" });
|
|
95
82
|
}
|
|
96
83
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* the
|
|
84
|
+
* The admin sidebar (SHELL.md §2). Expanded: section labels, rows and
|
|
85
|
+
* collapsible sub-groups. Collapsed or at ≤1024px: a 60px icon rail with no
|
|
86
|
+
* sub-items, the parent active for any child page, children in a flyout and
|
|
87
|
+
* labels kept for screen readers. The nav itself comes from `nav-config`.
|
|
100
88
|
*/
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
]
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
* Posts (with All Posts + Post Types), followed by Media / Forms / SEO /
|
|
109
|
-
* Script Tags, then a SETTINGS group (Users / API Keys / Settings).
|
|
110
|
-
*/
|
|
111
|
-
const defaultNavItems = [
|
|
112
|
-
{ path: '/', label: 'Dashboard', icon: LayoutDashboard },
|
|
113
|
-
{ path: '/pages', label: 'Pages', icon: File, group: 'Content' },
|
|
114
|
-
{ path: '/posts', label: 'Posts', icon: FileText, group: 'Content', children: POSTS_CHILDREN },
|
|
115
|
-
{ path: '/media', label: 'Media', icon: Image, group: 'Content' },
|
|
116
|
-
{ path: '/forms', label: 'Forms', icon: ClipboardList, group: 'Content' },
|
|
117
|
-
{ path: '/seo', label: 'SEO', icon: SearchIcon, group: 'Content' },
|
|
118
|
-
{ path: '/script-tags', label: 'Script Tags', icon: Code2, group: 'Content' },
|
|
119
|
-
{ path: '/trash', label: 'Trash', icon: Trash2, group: 'Content' },
|
|
120
|
-
{ path: '/jobs', label: 'Jobs', icon: ListTodo, group: 'Settings' },
|
|
121
|
-
{ path: '/settings', label: 'Settings', icon: Settings, group: 'Settings' },
|
|
122
|
-
];
|
|
123
|
-
export function Sidebar({ collapsed, onToggleCollapse, currentPath, onNavigate, config, }) {
|
|
124
|
-
const formsSidebar = useFormsSidebar();
|
|
125
|
-
const navItems = applyFormsNav(buildNavItems(config), formsSidebar);
|
|
126
|
-
const { density } = useTheme();
|
|
127
|
-
const compact = density === 'compact';
|
|
128
|
-
return (_jsxs("aside", { className: `bg-sidebar border-sidebar-border flex h-full flex-col border-r transition-[width] duration-[var(--motion-layout)] ${collapsed ? 'w-[var(--sbw-col)]' : 'w-[var(--sbw)]'}`, children: [_jsx("div", { className: `border-sidebar-border flex h-[var(--tbh)] shrink-0 items-center border-b px-4 ${collapsed ? 'justify-center' : ''}`, children: _jsx(BrandLogo, { config: config, collapsed: collapsed }) }), _jsx("nav", { className: `flex-1 overflow-y-auto ${compact ? 'space-y-0.5 p-2' : 'space-y-1 p-3'}`, "aria-label": "Primary", children: renderNavTree(navItems, { collapsed, currentPath, onNavigate, compact }) }), _jsx("div", { className: "border-sidebar-border hidden shrink-0 border-t p-3 md:block", children: _jsx("button", { onClick: onToggleCollapse, className: `text-sidebar-foreground/80 hover:bg-sidebar-accent hover:text-sidebar-foreground flex w-full items-center gap-2.5 rounded-lg px-3 py-2 text-sm transition-colors ${collapsed ? 'justify-center' : ''}`, "aria-label": collapsed ? 'Expand sidebar' : 'Collapse sidebar', title: collapsed ? 'Expand sidebar' : 'Collapse sidebar', children: collapsed ? (_jsx(PanelLeftOpen, { className: "h-4 w-4 shrink-0", "aria-hidden": true })) : (_jsxs(_Fragment, { children: [_jsx(PanelLeftClose, { className: "h-4 w-4 shrink-0", "aria-hidden": true }), _jsx("span", { className: "font-medium", children: "Collapse sidebar" })] })) }) })] }));
|
|
89
|
+
export function Sidebar({ collapsed, onToggleCollapse, currentPath, onNavigate, config, items, }) {
|
|
90
|
+
const ownItems = useNavItems(config, !items);
|
|
91
|
+
const navItems = items ?? ownItems;
|
|
92
|
+
return (_jsxs("aside", { className: `bg-sb border-bdr flex h-full flex-col border-r transition-[width] duration-[var(--mo-slow)] ease-[cubic-bezier(.4,0,.2,1)] ${collapsed ? 'w-[var(--sbw-col)]' : 'w-[var(--sbw)]'}`, children: [_jsx("div", { className: `border-bdr flex h-[var(--tbh)] shrink-0 items-center gap-2.5 overflow-hidden border-b ${
|
|
93
|
+
// Below 769px the drawer's Close button (36px, 44px on touch, at
|
|
94
|
+
// right 10px) sits in this row; keep a long brand name clear of it.
|
|
95
|
+
collapsed ? 'justify-center px-0' : 'mobile:pr-14 px-[14px]'}`, children: _jsx(BrandLogo, { config: config, collapsed: collapsed }) }), _jsx("nav", { className: "[&::-webkit-scrollbar-thumb]:rounded-pill [&::-webkit-scrollbar-thumb]:bg-bdr relative flex-1 overflow-x-hidden overflow-y-auto py-2 [&::-webkit-scrollbar]:w-[3px]", "aria-label": "Primary", children: _jsx(NavTree, { items: navItems, ctx: { collapsed, currentPath, onNavigate } }) }), _jsx("div", { className: "border-bdr not-narrow:block hidden shrink-0 border-t p-2", children: _jsxs("button", { type: "button", onClick: onToggleCollapse, className: `rounded-7 text-meta text-sub hover:bg-acc-l hover:text-acc flex w-full cursor-pointer items-center gap-[9px] overflow-hidden border-0 bg-transparent px-2.5 py-[7px] leading-[normal] font-normal whitespace-nowrap ${collapsed ? 'justify-center' : ''}`, "aria-expanded": !collapsed, "aria-label": collapsed ? 'Expand sidebar' : 'Collapse sidebar', children: [_jsx("span", { className: "flex h-[19px] shrink-0 items-center", children: collapsed ? (_jsx(ChevronRight, { className: "h-[15px] w-[15px]", strokeWidth: 1.75, "aria-hidden": true })) : (_jsx(ChevronLeft, { className: "h-[15px] w-[15px]", strokeWidth: 1.75, "aria-hidden": true })) }), _jsx("span", { className: collapsed ? 'sr-only' : '', children: "Collapse sidebar" })] }) })] }));
|
|
129
96
|
}
|
|
97
|
+
/** Kit `.ni`: 13px --sub, 7px 10px, margin 1px 8px, radius 7, gap 9. */
|
|
98
|
+
const ROW = 'rounded-7 text-body flex w-full cursor-pointer items-center gap-[9px] overflow-hidden border-0 leading-[normal] whitespace-nowrap';
|
|
99
|
+
const ROW_IDLE = 'bg-transparent font-[450] text-sub hover:bg-acc-l hover:text-acc';
|
|
100
|
+
// Forced colors drop the fill, so the current row also gets an outline there.
|
|
101
|
+
const FORCED_ACTIVE = 'forced-colors:outline-solid forced-colors:outline-2 forced-colors:-outline-offset-2';
|
|
102
|
+
const ROW_ACTIVE = `bg-acc-l font-[550] text-acc ${FORCED_ACTIVE}`;
|
|
130
103
|
/**
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
104
|
+
* At >=1025px a parent row toggles its group (the kit's `onClickCapture`);
|
|
105
|
+
* below that, in the mobile drawer, it opens the parent page.
|
|
106
|
+
*
|
|
107
|
+
* Starts wide and corrects after mount, so a server render and the browser's
|
|
108
|
+
* first render agree (the row's `aria-expanded` depends on it).
|
|
136
109
|
*/
|
|
137
|
-
function
|
|
138
|
-
const [
|
|
110
|
+
function useWideNav() {
|
|
111
|
+
const [wide, setWide] = useState(true);
|
|
139
112
|
useEffect(() => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
totalUnread: counts.reduce((sum, c) => sum + (c.unread ?? 0), 0),
|
|
148
|
-
forms: counts,
|
|
149
|
-
});
|
|
150
|
-
})
|
|
151
|
-
.catch(() => {
|
|
152
|
-
/* keep the last known value; nav must never break on a fetch error */
|
|
153
|
-
});
|
|
154
|
-
};
|
|
155
|
-
load();
|
|
156
|
-
const off = onFormsChanged(load);
|
|
157
|
-
return () => {
|
|
158
|
-
active = false;
|
|
159
|
-
off();
|
|
160
|
-
};
|
|
113
|
+
if (typeof window.matchMedia !== 'function')
|
|
114
|
+
return;
|
|
115
|
+
const mq = window.matchMedia(TIER_MEDIA.narrow);
|
|
116
|
+
const apply = () => setWide(!mq.matches);
|
|
117
|
+
apply();
|
|
118
|
+
mq.addEventListener?.('change', apply);
|
|
119
|
+
return () => mq.removeEventListener?.('change', apply);
|
|
161
120
|
}, []);
|
|
162
|
-
return
|
|
121
|
+
return wide;
|
|
163
122
|
}
|
|
164
|
-
/**
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
return items.map((item) => {
|
|
171
|
-
if (item.path !== '/forms')
|
|
172
|
-
return item;
|
|
173
|
-
const children = [
|
|
174
|
-
{ path: '/forms/entries', label: 'All Entries', icon: Inbox },
|
|
175
|
-
{ path: '/forms/deliveries', label: 'Deliveries', icon: AlertTriangle },
|
|
176
|
-
...state.forms.map((f) => ({
|
|
177
|
-
path: `/forms/${f.formId}/submissions`,
|
|
178
|
-
label: f.name,
|
|
179
|
-
icon: ClipboardList,
|
|
180
|
-
badge: f.unread,
|
|
181
|
-
})),
|
|
182
|
-
];
|
|
183
|
-
return {
|
|
184
|
-
...item,
|
|
185
|
-
badge: state.totalUnread > 0 ? state.totalUnread : undefined,
|
|
186
|
-
children,
|
|
187
|
-
};
|
|
188
|
-
});
|
|
123
|
+
/** A parent is current for any page under its path or any of its children. */
|
|
124
|
+
function isSectionActive(currentPath, item) {
|
|
125
|
+
const path = currentPath.split(/[?#]/)[0];
|
|
126
|
+
return (path === item.path ||
|
|
127
|
+
(item.path !== '/' && path.startsWith(item.path + '/')) ||
|
|
128
|
+
hasActiveDescendant(item.children ?? [], currentPath));
|
|
189
129
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
//
|
|
204
|
-
//
|
|
205
|
-
return
|
|
130
|
+
/** 16px for top-level rows; sub-items default to the kit's 14px. */
|
|
131
|
+
function NavIcon({ item, size: fallback = 16 }) {
|
|
132
|
+
const Icon = item.icon;
|
|
133
|
+
const size = item.iconSize ?? fallback;
|
|
134
|
+
return (_jsx("span", { className: "flex h-4 w-4 shrink-0 items-center justify-center", "aria-hidden": true, children: _jsx(Icon, { className: "shrink-0", size: size, strokeWidth: 1.75 }) }));
|
|
135
|
+
}
|
|
136
|
+
/** Kit `.ni-badge`: 16px pill, --err fill, 9.5px / 700. */
|
|
137
|
+
function NavBadge({ count, className = '' }) {
|
|
138
|
+
if (!count || count <= 0)
|
|
139
|
+
return null;
|
|
140
|
+
return (_jsx("span", { className: `rounded-pill bg-err text-badge text-acc-on flex h-4 min-w-4 shrink-0 items-center justify-center px-1 leading-none font-bold tabular-nums ${className}`, "aria-label": `${count} unread`, children: count > 99 ? '99+' : count }));
|
|
141
|
+
}
|
|
142
|
+
function SectionLabel({ label, collapsed }) {
|
|
143
|
+
// Kit: the collapsed sidebar keeps the label's space but hides it; the
|
|
144
|
+
// 769–1024px rail drops it entirely. The mobile drawer shows it.
|
|
145
|
+
return (_jsx("div", { className: `text-label text-faint tablet:hidden overflow-hidden px-4 pt-2.5 pb-1 leading-[normal] font-semibold tracking-[0.8px] whitespace-nowrap uppercase ${collapsed ? 'pointer-events-none opacity-0' : ''}`, children: label }));
|
|
206
146
|
}
|
|
207
|
-
function
|
|
147
|
+
function NavTree({ items, ctx }) {
|
|
208
148
|
const nodes = [];
|
|
209
149
|
let lastGroup = undefined;
|
|
210
150
|
for (const item of items) {
|
|
211
151
|
if (item.group && item.group !== lastGroup) {
|
|
212
|
-
nodes.push(
|
|
213
|
-
lastGroup = item.group;
|
|
214
|
-
}
|
|
215
|
-
else if (!item.group) {
|
|
216
|
-
lastGroup = undefined;
|
|
152
|
+
nodes.push(_jsx(SectionLabel, { label: item.group, collapsed: ctx.collapsed }, `g-${item.group}`));
|
|
217
153
|
}
|
|
154
|
+
lastGroup = item.group;
|
|
218
155
|
const hasChildren = !!item.children && item.children.length > 0;
|
|
219
|
-
//
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
156
|
+
// Keys are namespaced: a parent and its first child can share a path.
|
|
157
|
+
if (ctx.collapsed) {
|
|
158
|
+
nodes.push(_jsx(RailItem, { item: item, ctx: ctx }, `rail:${item.label}:${item.path}`));
|
|
159
|
+
}
|
|
160
|
+
else if (hasChildren) {
|
|
161
|
+
nodes.push(_jsx(NavGroup, { item: item, ctx: ctx }, `group:${item.label}:${item.path}`));
|
|
224
162
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
if (hasChildren) {
|
|
228
|
-
nodes.push(_jsx(NavSection, { item: item, ctx: ctx }, `section:${item.path}`));
|
|
229
|
-
continue;
|
|
163
|
+
else {
|
|
164
|
+
nodes.push(_jsx(NavRow, { item: item, ctx: ctx }, `item:${item.path}`));
|
|
230
165
|
}
|
|
231
|
-
// Keys are namespaced because a parent and its first child can share
|
|
232
|
-
// the same path (e.g. the Posts parent and its "All Posts" child are
|
|
233
|
-
// both `/posts`). Using the raw path as the key collided and made
|
|
234
|
-
// React warn about — and risk dropping — duplicate siblings.
|
|
235
|
-
nodes.push(_jsx(NavLink, { item: item, ctx: ctx }, `item:${item.path}`));
|
|
236
166
|
}
|
|
237
|
-
return nodes;
|
|
167
|
+
return _jsx(_Fragment, { children: nodes });
|
|
168
|
+
}
|
|
169
|
+
function NavRow({ item, ctx }) {
|
|
170
|
+
const active = isPathActive(ctx.currentPath, item.path);
|
|
171
|
+
return (_jsx("div", { className: "mx-2 my-px", children: _jsxs("button", { type: "button", onClick: () => ctx.onNavigate(item.path), className: `${ROW} px-2.5 py-[7px] ${active ? ROW_ACTIVE : ROW_IDLE}`, "aria-current": active ? 'page' : undefined, children: [_jsx(NavIcon, { item: item }), _jsx("span", { className: "truncate", children: item.label }), _jsx(NavBadge, { count: item.badge, className: "ml-auto" })] }) }));
|
|
238
172
|
}
|
|
239
173
|
/**
|
|
240
|
-
* Expanded parent with a
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
* the
|
|
244
|
-
* section
|
|
174
|
+
* Expanded parent with a sub-group. Groups start closed and open on their
|
|
175
|
+
* own when the current page is one of their children; a manual toggle holds
|
|
176
|
+
* until the route changes. At ≥1025px clicking the row toggles the group, as
|
|
177
|
+
* in the kit; below that (the mobile drawer) it opens the parent page. The
|
|
178
|
+
* parent stays filled while its section holds the current page, and the
|
|
179
|
+
* current child is filled too (Inbox.html).
|
|
245
180
|
*/
|
|
246
|
-
function
|
|
247
|
-
const
|
|
248
|
-
const
|
|
249
|
-
const childActive =
|
|
250
|
-
const [open, setOpen] = useState(
|
|
251
|
-
|
|
252
|
-
//
|
|
253
|
-
// (
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
181
|
+
function NavGroup({ item, ctx }) {
|
|
182
|
+
const children = item.children;
|
|
183
|
+
const sectionActive = isSectionActive(ctx.currentPath, item);
|
|
184
|
+
const childActive = hasActiveDescendant(children, ctx.currentPath);
|
|
185
|
+
const [open, setOpen] = useState(childActive);
|
|
186
|
+
// Re-sync on navigation. Adjusting state during render (rather than in an
|
|
187
|
+
// effect) avoids painting the old open state for a frame. Query/hash-only
|
|
188
|
+
// changes (filters, tabs) keep the user's toggle.
|
|
189
|
+
const route = ctx.currentPath.split(/[?#]/)[0];
|
|
190
|
+
const [syncedRoute, setSyncedRoute] = useState(route);
|
|
191
|
+
if (syncedRoute !== route) {
|
|
192
|
+
setSyncedRoute(route);
|
|
193
|
+
setOpen(childActive);
|
|
194
|
+
}
|
|
195
|
+
const listId = `nav-group-${item.label.replace(/[^a-z0-9]+/gi, '-').toLowerCase()}`;
|
|
196
|
+
const current = activeChildPath(children, ctx.currentPath);
|
|
197
|
+
const wide = useWideNav();
|
|
198
|
+
const onRowClick = () => {
|
|
199
|
+
if (wide)
|
|
200
|
+
setOpen((value) => !value);
|
|
201
|
+
else
|
|
202
|
+
ctx.onNavigate(item.path);
|
|
203
|
+
};
|
|
204
|
+
// Kit `.ni` with `.ni-tog`: the 22px toggle sits inside the 7px padding, so
|
|
205
|
+
// parent rows are 36px tall; the toggle ends 10px from the row's edge.
|
|
206
|
+
return (_jsxs("div", { children: [_jsxs("div", { className: `rounded-7 mx-2 my-px flex h-9 items-center pr-2.5 ${sectionActive
|
|
207
|
+
? `bg-acc-l text-acc ${FORCED_ACTIVE}`
|
|
208
|
+
: 'text-sub hover:bg-acc-l hover:text-acc'}`, children: [_jsxs("button", { type: "button", onClick: onRowClick, className: `${ROW} h-full min-w-0 flex-1 bg-transparent py-0 pl-2.5 text-inherit ${sectionActive ? 'font-[550]' : 'font-[450]'}`, "aria-current": sectionActive && !open ? 'page' : undefined, "aria-expanded": wide ? open : undefined, "aria-controls": wide ? listId : undefined, children: [_jsx(NavIcon, { item: item }), _jsx("span", { className: "truncate", children: item.label }), _jsx(NavBadge, { count: item.badge, className: "ml-1.5" })] }), _jsx("button", { type: "button", onClick: () => setOpen((value) => !value), className: "prenta-touch-hit rounded-5 text-faint hover:text-txt relative ml-auto flex h-6 w-6 shrink-0 cursor-pointer items-center justify-center border-0 bg-transparent p-0 [--touch-hit-block:-6px] [--touch-hit-inline:-10px] hover:bg-[color-mix(in_srgb,var(--txt)_8%,transparent)]", "aria-label": `${open ? 'Collapse' : 'Expand'} ${item.label}`, "aria-expanded": open, "aria-controls": listId, children: _jsx(ChevronRight, { className: `h-3 w-3 motion-safe:transition-transform motion-safe:duration-[var(--mo-base)] ${open ? 'rotate-90' : ''}`, strokeWidth: 2.2, "aria-hidden": true }) })] }), open && (
|
|
209
|
+
// Kit `.sub-group`: margin 2px 8px 4px 18px, a 1.5px guide on the left
|
|
210
|
+
// and a 13px connector into each row.
|
|
211
|
+
_jsx("div", { id: listId, className: "before:rounded-pill before:bg-bdr relative mt-0.5 mr-2 mb-1 ml-[18px] before:absolute before:top-1 before:bottom-[18px] before:left-0 before:w-[1.5px]", children: children.map((child) => child.children?.length ? (_jsx(NestedSubGroup, { item: child, ctx: ctx, current: current }, `nest:${child.label}:${child.path}`)) : (_jsx(SubRow, { item: child, ctx: ctx, active: child.path === current }, `child:${child.label}:${child.path}`))) }))] }));
|
|
258
212
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
const badge = item.badge && item.badge > 0 ? item.badge : 0;
|
|
263
|
-
const button = (_jsxs("button", { onClick: () => ctx.onNavigate(item.path), className: `flex w-full items-center gap-3 rounded-lg text-left transition-colors ${nested
|
|
264
|
-
? ctx.compact
|
|
265
|
-
? 'py-1 pr-3 pl-9'
|
|
266
|
-
: 'py-1.5 pr-3 pl-9'
|
|
267
|
-
: ctx.compact
|
|
268
|
-
? 'px-3 py-1.5'
|
|
269
|
-
: 'px-3 py-2.5'} ${isActive
|
|
270
|
-
? 'bg-sidebar-accent text-sidebar-primary'
|
|
271
|
-
: 'text-sidebar-foreground hover:bg-sidebar-accent'} ${ctx.collapsed ? 'justify-center px-3' : ''}`, title: ctx.collapsed ? item.label : '', "aria-current": isActive ? 'page' : undefined, children: [_jsxs("span", { className: "relative flex shrink-0 items-center", children: [!nested && _jsx(Icon, { className: "h-5 w-5 shrink-0", "aria-hidden": true }), nested && !ctx.collapsed && (_jsx(Icon, { className: "text-sidebar-foreground/60 h-4 w-4 shrink-0", "aria-hidden": true })), ctx.collapsed && badge > 0 && (_jsx("span", { className: "bg-destructive absolute -top-0.5 -right-0.5 h-2 w-2 rounded-full", "aria-hidden": true }))] }), !ctx.collapsed && (_jsx("span", { className: `truncate font-medium ${nested ? 'text-[13px]' : 'text-sm'}`, children: item.label })), !ctx.collapsed && badge > 0 && (_jsx("span", { className: "bg-destructive text-destructive-foreground ml-auto inline-flex min-w-5 items-center justify-center rounded-full px-1.5 py-0.5 text-xs font-medium tabular-nums", "aria-label": `${badge} unread`, children: badge > 99 ? '99+' : badge }))] }));
|
|
272
|
-
if (!nested || ctx.collapsed)
|
|
273
|
-
return button;
|
|
274
|
-
// Curved-elbow tree connector (expanded only). The elbow draws the vertical
|
|
275
|
-
// run from the row top to its vertical center, curves at the bottom-left
|
|
276
|
-
// corner, then runs horizontally into the row. Non-last rows continue the
|
|
277
|
-
// vertical line to the row bottom so it meets the next sibling's elbow.
|
|
278
|
-
// The guide is centered (~21px) under the parent item's 20px icon.
|
|
279
|
-
return (_jsxs("div", { className: "relative", children: [_jsx("span", { "aria-hidden": true, className: "border-sidebar-border absolute top-0 left-[21px] h-1/2 w-[15px] rounded-bl-lg border-b border-l" }), !isLast && (_jsx("span", { "aria-hidden": true, className: "border-sidebar-border absolute top-1/2 bottom-0 left-[21px] border-l" })), button] }));
|
|
213
|
+
/** Kit `.sub-group .ni`: 12.5px, inset 20px past the guide, with a connector. */
|
|
214
|
+
function SubRow({ item, ctx, active, kid = false, className = '', }) {
|
|
215
|
+
return (_jsxs("button", { type: "button", onClick: () => ctx.onNavigate(item.path), className: `${ROW} text-sm2 relative my-px py-[7px] pr-2.5 before:absolute before:top-1/2 before:left-0 before:h-[1.5px] before:w-[13px] before:-translate-y-1/2 ${kid ? 'pl-[30px]' : 'pl-5'} ${active ? `${ROW_ACTIVE} before:bg-acc-m` : `${ROW_IDLE} before:bg-bdr hover:before:bg-acc-m`} ${className}`, "aria-current": active ? 'page' : undefined, children: [_jsx("span", { className: kid ? 'flex opacity-50' : 'flex', children: _jsx(NavIcon, { item: item, size: 14 }) }), _jsx("span", { className: "truncate", children: item.label }), _jsx(NavBadge, { count: item.badge, className: "ml-auto" })] }));
|
|
280
216
|
}
|
|
281
217
|
/**
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
* controlled manually; we suppress Radix's auto-focus when opened by pointer
|
|
287
|
-
* so hovering doesn't steal focus, while keyboard opening still moves focus
|
|
288
|
-
* into the menu.
|
|
218
|
+
* Third level (`cms-layouts.js` "3rd-level nav nesting"): All Entries and All
|
|
219
|
+
* Forms open one row per form. The row itself navigates; the chevron at its
|
|
220
|
+
* right edge toggles the rows, which start closed and open when one of them
|
|
221
|
+
* is the current page.
|
|
289
222
|
*/
|
|
290
|
-
function
|
|
291
|
-
const
|
|
292
|
-
const
|
|
293
|
-
const
|
|
223
|
+
function NestedSubGroup({ item, ctx, current, }) {
|
|
224
|
+
const kids = item.children;
|
|
225
|
+
const kidActive = kids.some((kid) => kid.path === current);
|
|
226
|
+
const [open, setOpen] = useState(kidActive);
|
|
227
|
+
const route = ctx.currentPath.split(/[?#]/)[0];
|
|
228
|
+
const [syncedRoute, setSyncedRoute] = useState(route);
|
|
229
|
+
if (syncedRoute !== route) {
|
|
230
|
+
setSyncedRoute(route);
|
|
231
|
+
setOpen(kidActive);
|
|
232
|
+
}
|
|
233
|
+
const listId = `nav-nest-${item.label.replace(/[^a-z0-9]+/gi, '-').toLowerCase()}`;
|
|
234
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "relative", children: [_jsx(SubRow, { item: item, ctx: ctx, active: item.path === current, className: "pr-[30px]!" }), _jsx("button", { type: "button", onClick: () => setOpen((value) => !value),
|
|
235
|
+
// Touch hit area: 44px wide, the 30px row tall.
|
|
236
|
+
className: `prenta-touch-hit rounded-5 absolute top-1/2 right-1 flex h-6 w-6 -translate-y-1/2 cursor-pointer items-center justify-center border-0 bg-transparent p-0 [--touch-hit-block:-3px] [--touch-hit-inline:-10px] ${item.path === current ? 'text-acc' : 'text-sub'}`, "aria-label": `${open ? 'Collapse' : 'Expand'} ${item.label}`, "aria-expanded": open, "aria-controls": listId, children: _jsx(ChevronRight, { className: `h-[14px] w-[14px] opacity-55 motion-safe:transition-transform motion-safe:duration-[var(--mo-base)] ${open ? 'rotate-90' : ''}`, strokeWidth: 2.4, "aria-hidden": true }) })] }), open && (_jsx("div", { id: listId, children: kids.map((kid) => (_jsx(SubRow, { item: kid, ctx: ctx, active: kid.path === current, kid: true }, `kid:${kid.label}:${kid.path}`))) }))] }));
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Rail item (collapsed sidebar or ≤1024px). The label stays in the
|
|
240
|
+
* accessibility tree (`sr-only`). Parents never render sub-items here: the
|
|
241
|
+
* parent is active for any child page and the children open in a flyout.
|
|
242
|
+
*/
|
|
243
|
+
function RailItem({ item, ctx }) {
|
|
244
|
+
const hasChildren = !!item.children && item.children.length > 0;
|
|
245
|
+
const active = hasChildren
|
|
246
|
+
? isSectionActive(ctx.currentPath, item)
|
|
247
|
+
: isPathActive(ctx.currentPath, item.path);
|
|
248
|
+
const trigger = (_jsxs("button", { type: "button", onClick: () => ctx.onNavigate(item.path), className: `${ROW} justify-center px-0 py-[9px] ${active ? ROW_ACTIVE : ROW_IDLE}`, "aria-current": active ? 'page' : undefined, children: [_jsx(NavIcon, { item: item }), _jsx("span", { className: "sr-only", children: item.label }), _jsx(NavBadge, { count: item.badge })] }));
|
|
249
|
+
if (hasChildren)
|
|
250
|
+
return _jsx(RailFlyout, { item: item, ctx: ctx, trigger: trigger });
|
|
251
|
+
return _jsx(RailLabel, { label: item.label, children: trigger });
|
|
252
|
+
}
|
|
253
|
+
/** Kit `.flyout-panel` chrome, shared by the label tip and the menu. */
|
|
254
|
+
const FLYOUT_PANEL = 'bg-card border-bdr rounded-12 shadow-shd2 min-w-[200px] overflow-hidden border pb-2 motion-safe:animate-in motion-safe:fade-in';
|
|
255
|
+
const FLYOUT_LABEL = 'text-body text-txt flex items-center gap-2 px-[14px] py-2.5 leading-[normal] font-medium';
|
|
256
|
+
/**
|
|
257
|
+
* Hover/focus label for a childless rail item (the kit's label-only flyout).
|
|
258
|
+
* Visual only: the button already carries its label for screen readers.
|
|
259
|
+
* WCAG 1.4.13: Esc dismisses it, the pointer can move onto it, and it shows
|
|
260
|
+
* for mouse and keyboard only, so a tap on a touch tablet doesn't leave it
|
|
261
|
+
* stuck after navigating.
|
|
262
|
+
*/
|
|
263
|
+
function RailLabel({ label, children }) {
|
|
264
|
+
const [top, setTop] = useState(null);
|
|
265
|
+
const hideTimer = useRef(null);
|
|
266
|
+
const cancelHide = () => {
|
|
267
|
+
if (hideTimer.current)
|
|
268
|
+
clearTimeout(hideTimer.current);
|
|
269
|
+
hideTimer.current = null;
|
|
270
|
+
};
|
|
271
|
+
const show = (el) => {
|
|
272
|
+
cancelHide();
|
|
273
|
+
setTop(el.getBoundingClientRect().top);
|
|
274
|
+
};
|
|
275
|
+
const hide = () => {
|
|
276
|
+
cancelHide();
|
|
277
|
+
setTop(null);
|
|
278
|
+
};
|
|
279
|
+
// Crossing the 6px gap to the label briefly leaves the trigger.
|
|
280
|
+
const scheduleHide = () => {
|
|
281
|
+
cancelHide();
|
|
282
|
+
hideTimer.current = setTimeout(() => setTop(null), 120);
|
|
283
|
+
};
|
|
284
|
+
const visible = top !== null;
|
|
285
|
+
useEffect(() => {
|
|
286
|
+
if (!visible)
|
|
287
|
+
return;
|
|
288
|
+
const onKey = (e) => {
|
|
289
|
+
if (e.key === 'Escape')
|
|
290
|
+
setTop(null);
|
|
291
|
+
};
|
|
292
|
+
document.addEventListener('keydown', onKey);
|
|
293
|
+
return () => document.removeEventListener('keydown', onKey);
|
|
294
|
+
}, [visible]);
|
|
295
|
+
useEffect(() => () => cancelHide(), []);
|
|
296
|
+
return (_jsxs("div", { className: "mx-1.5 my-px", onPointerEnter: (e) => {
|
|
297
|
+
if (e.pointerType === 'mouse')
|
|
298
|
+
show(e.currentTarget);
|
|
299
|
+
}, onPointerLeave: scheduleHide, onFocus: (e) => {
|
|
300
|
+
if (e.currentTarget.querySelector(':focus-visible'))
|
|
301
|
+
show(e.currentTarget);
|
|
302
|
+
}, onBlur: hide, onClick: hide, children: [children, visible && (_jsx("div", { "aria-hidden": true, className: `${FLYOUT_PANEL} fixed left-[var(--sbw-col)] z-[var(--z-menu)] min-w-0 pb-0`, style: { top }, onPointerEnter: cancelHide, onPointerLeave: scheduleHide, children: _jsx("div", { className: FLYOUT_LABEL, children: label }) }))] }));
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Rail parent with a flyout listing its children. Built on Radix
|
|
306
|
+
* DropdownMenu so the panel is portaled (escaping the nav's `overflow` clip),
|
|
307
|
+
* dismissable and keyboard-navigable. Hover opens it; Radix's auto-focus is
|
|
308
|
+
* suppressed for pointer opens so hovering doesn't steal focus, while
|
|
309
|
+
* keyboard opens still move focus into the menu.
|
|
310
|
+
*/
|
|
311
|
+
function RailFlyout({ item, ctx, trigger, }) {
|
|
312
|
+
const children = item.children;
|
|
313
|
+
const { resolvedTheme, lightBase, accent } = useTheme();
|
|
294
314
|
const [open, setOpen] = useState(false);
|
|
295
315
|
const openedByPointer = useRef(false);
|
|
316
|
+
const focusEntered = useRef(false);
|
|
317
|
+
const closingByHover = useRef(false);
|
|
318
|
+
const pointerSelect = useRef(false);
|
|
319
|
+
const wrapRef = useRef(null);
|
|
320
|
+
const contentRef = useRef(null);
|
|
296
321
|
const closeTimer = useRef(null);
|
|
322
|
+
const current = activeChildPath(children, ctx.currentPath);
|
|
297
323
|
const cancelClose = () => {
|
|
298
324
|
if (closeTimer.current) {
|
|
299
325
|
clearTimeout(closeTimer.current);
|
|
@@ -302,153 +328,91 @@ function CollapsedFlyout({ item, ctx }) {
|
|
|
302
328
|
};
|
|
303
329
|
const scheduleClose = () => {
|
|
304
330
|
cancelClose();
|
|
305
|
-
closeTimer.current = setTimeout(() =>
|
|
331
|
+
closeTimer.current = setTimeout(() => {
|
|
332
|
+
closingByHover.current = true;
|
|
333
|
+
setOpen(false);
|
|
334
|
+
}, 120);
|
|
306
335
|
};
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
336
|
+
// Only a hover-opened menu closes when the pointer leaves; a keyboard user
|
|
337
|
+
// inside a menu keeps it while the mouse happens to cross the rail.
|
|
338
|
+
const hoverLeave = () => {
|
|
339
|
+
if (openedByPointer.current)
|
|
340
|
+
scheduleClose();
|
|
341
|
+
};
|
|
342
|
+
const onOpenChange = (next) => {
|
|
343
|
+
if (next)
|
|
344
|
+
closingByHover.current = false;
|
|
345
|
+
setOpen(next);
|
|
346
|
+
};
|
|
347
|
+
// `openedByPointer` records how the menu last opened, set by the opening
|
|
348
|
+
// input itself: a mouse hover on a closed menu sets it, while a key or a
|
|
349
|
+
// touch/pen press on the trigger clears it before Radix toggles. Hovering an
|
|
350
|
+
// already open menu leaves it alone, and so do close paths, so the close
|
|
351
|
+
// focus handling below still knows how the closing menu was opened. (Esc
|
|
352
|
+
// needs no listener here: Radix dismisses the top layer on Esc wherever
|
|
353
|
+
// focus is.)
|
|
354
|
+
return (_jsxs(DropdownMenu.Root, { open: open, onOpenChange: onOpenChange, modal: false, children: [_jsx("div", { ref: wrapRef, className: "mx-1.5 my-px", onMouseEnter: () => {
|
|
355
|
+
if (!open) {
|
|
356
|
+
openedByPointer.current = true;
|
|
357
|
+
closingByHover.current = false;
|
|
358
|
+
}
|
|
313
359
|
cancelClose();
|
|
314
360
|
setOpen(true);
|
|
315
|
-
}, onMouseLeave:
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
361
|
+
}, onMouseLeave: hoverLeave, onKeyDownCapture: (e) => {
|
|
362
|
+
openedByPointer.current = false;
|
|
363
|
+
// The mouse already opened the menu while focus sat on the trigger:
|
|
364
|
+
// Radix would treat these keys as a no-op (ArrowDown) or a toggle
|
|
365
|
+
// closed (Enter/Space), so take the keyboard user into the menu.
|
|
366
|
+
if (open && (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ')) {
|
|
367
|
+
const first = contentRef.current?.querySelector('[role="menuitem"]:not([data-disabled])');
|
|
368
|
+
if (first) {
|
|
369
|
+
e.preventDefault();
|
|
370
|
+
e.stopPropagation();
|
|
371
|
+
first.focus();
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}, onPointerDownCapture: (e) => {
|
|
375
|
+
if (e.pointerType !== 'mouse')
|
|
376
|
+
openedByPointer.current = false;
|
|
377
|
+
}, children: _jsx(DropdownMenu.Trigger, { asChild: true, children: trigger }) }), _jsx(DropdownMenu.Portal, { container: adminPortalContainer(), children: _jsxs(DropdownMenu.Content, { ref: contentRef, side: "right", align: "start",
|
|
378
|
+
// The trigger ends 6px inside the 60px rail; the kit panel starts at 60px.
|
|
379
|
+
sideOffset: 6, onMouseEnter: cancelClose, onMouseLeave: hoverLeave, ...{
|
|
380
|
+
onOpenAutoFocus: (e) => {
|
|
381
|
+
focusEntered.current = false;
|
|
382
|
+
pointerSelect.current = false;
|
|
383
|
+
if (openedByPointer.current)
|
|
384
|
+
e.preventDefault();
|
|
385
|
+
},
|
|
386
|
+
}, onFocusCapture: () => {
|
|
387
|
+
focusEntered.current = true;
|
|
388
|
+
}, onCloseAutoFocus: (e) => {
|
|
389
|
+
// After a pointer-driven open that never took focus, leave focus
|
|
390
|
+
// where the user had it (e.g. a field they're typing in) instead
|
|
391
|
+
// of yanking it to the rail trigger. Once focus has been inside
|
|
392
|
+
// the menu (keyboard open, or Radix focusing items under the
|
|
393
|
+
// pointer), Esc or picking an item returns it to the trigger;
|
|
394
|
+
// otherwise it would fall to <body> as the focused item unmounts.
|
|
395
|
+
// A close because the pointer left never moves focus: focusing
|
|
396
|
+
// this trigger would dismiss the next flyout the pointer opened.
|
|
397
|
+
if (openedByPointer.current && (!focusEntered.current || closingByHover.current)) {
|
|
322
398
|
e.preventDefault();
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
399
|
+
}
|
|
400
|
+
else if (pointerSelect.current) {
|
|
401
|
+
// A mouse pick still returns focus to the trigger, but without
|
|
402
|
+
// the keyboard focus ring (Radix's item focus under the pointer
|
|
403
|
+
// would otherwise make Chromium show it).
|
|
404
|
+
e.preventDefault();
|
|
405
|
+
wrapRef.current
|
|
406
|
+
?.querySelector('button')
|
|
407
|
+
?.focus({ preventScroll: true, focusVisible: false });
|
|
408
|
+
}
|
|
409
|
+
}, "data-light": lightBase, style: accentPickCssVars(generateAdminThemeTokens({ adminAccentColor: accent }, resolvedTheme)), className: `prenta-admin ${resolvedTheme === 'dark' ? 'dark' : ''} ${FLYOUT_PANEL} z-[var(--z-menu)]`, children: [_jsxs("div", { className: `${FLYOUT_LABEL} border-bdr mb-1 border-b pb-2`, children: [_jsx("span", { className: "text-acc flex", children: _jsx(NavIcon, { item: item }) }), item.label, _jsx(NavBadge, { count: item.badge })] }), children.map((child) => {
|
|
410
|
+
const active = child.path === current;
|
|
411
|
+
return (_jsxs(DropdownMenu.Item, {
|
|
412
|
+
// Radix's Enter/Space select clicks the item with detail 0.
|
|
413
|
+
onClick: (e) => {
|
|
414
|
+
pointerSelect.current = e.detail !== 0;
|
|
415
|
+
}, onSelect: () => ctx.onNavigate(child.path), className: `text-body rounded-6 data-highlighted:bg-acc-l data-highlighted:text-acc mx-1 my-px flex cursor-pointer items-center gap-2 px-[14px] py-1.5 leading-[normal] outline-none select-none ${active ? `bg-acc-l text-acc font-[550] ${FORCED_ACTIVE}` : 'text-sub'}`, "aria-current": active ? 'page' : undefined, children: [_jsx("span", { className: "text-faint flex", children: _jsx(NavIcon, { item: child, size: 14 }) }), _jsx("span", { className: "flex-1 truncate", children: child.label }), _jsx(NavBadge, { count: child.badge })] }, `flyout:${child.label}:${child.path}`));
|
|
333
416
|
})] }) })] }));
|
|
334
417
|
}
|
|
335
|
-
// ─── Config-driven nav builder ──────────────────────────────────────────────
|
|
336
|
-
function resolveIcon(collection) {
|
|
337
|
-
const mapped = collection.admin?.icon ? ICON_MAP[collection.admin.icon] : undefined;
|
|
338
|
-
if (mapped)
|
|
339
|
-
return mapped;
|
|
340
|
-
return collection.type === 'page' ? File : FileText;
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* Build the sidebar nav tree from the CMS config. If no collections are
|
|
344
|
-
* configured, returns the curated `defaultNavItems` tree. When
|
|
345
|
-
* collections ARE configured, page-type collections render as Content
|
|
346
|
-
* entries, and every static destination (Media, Forms, SEO, Script Tags,
|
|
347
|
-
* Users, API Keys, Settings) is anchored under the right group.
|
|
348
|
-
*/
|
|
349
|
-
export function buildNavItems(config) {
|
|
350
|
-
if (!config?.collections)
|
|
351
|
-
return defaultNavItems;
|
|
352
|
-
const raw = config.collections;
|
|
353
|
-
const collectionsList = Array.isArray(raw) ? raw : Object.values(raw);
|
|
354
|
-
const visible = collectionsList.filter((c) => !c.admin?.hidden);
|
|
355
|
-
// Treat `admin.group: 'Posts'` (case-insensitive) as a synonym for
|
|
356
|
-
// `type: 'post'` so consumers can tag arbitrary collections into
|
|
357
|
-
// the Posts area without changing the discriminator they already
|
|
358
|
-
// use elsewhere (sitemaps, schema.org, etc.).
|
|
359
|
-
const isPostsGroup = (c) => typeof c.admin?.group === 'string' && c.admin.group.toLowerCase() === 'posts';
|
|
360
|
-
const pages = visible.filter((c) => c.type === 'page' && !c.admin?.group);
|
|
361
|
-
const posts = visible.filter((c) => c.type === 'post' || isPostsGroup(c));
|
|
362
|
-
const otherUngrouped = visible.filter((c) => c.type !== 'page' && c.type !== 'post' && !c.admin?.group);
|
|
363
|
-
// Anything explicitly grouped that isn't a posts collection.
|
|
364
|
-
const grouped = visible.filter((c) => c.admin?.group && !isPostsGroup(c) && c.type !== 'post');
|
|
365
|
-
const items = [{ path: '/', label: 'Dashboard', icon: LayoutDashboard }];
|
|
366
|
-
// Ungrouped collections that are neither page- nor post-type stay at
|
|
367
|
-
// the top level, directly under Dashboard, before the CONTENT group.
|
|
368
|
-
for (const collection of otherUngrouped) {
|
|
369
|
-
items.push({
|
|
370
|
-
label: collection.labels?.plural ?? collection.slug,
|
|
371
|
-
path: `/${collection.slug}`,
|
|
372
|
-
icon: resolveIcon(collection),
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
// CONTENT group. Everything below shares `group: 'Content'`, so the
|
|
376
|
-
// renderer emits the "CONTENT" header once — above Pages. Order:
|
|
377
|
-
// Pages → Posts → static content destinations (Media / Forms / SEO /
|
|
378
|
-
// Script Tags).
|
|
379
|
-
// Pages-style collections render as plain Content entries (no nested
|
|
380
|
-
// children).
|
|
381
|
-
pages.forEach((collection) => {
|
|
382
|
-
items.push({
|
|
383
|
-
label: collection.labels?.plural ?? collection.slug,
|
|
384
|
-
path: `/${collection.slug}`,
|
|
385
|
-
icon: resolveIcon(collection),
|
|
386
|
-
group: 'Content',
|
|
387
|
-
});
|
|
388
|
-
});
|
|
389
|
-
// Posts area — collapses every post-type collection under a single
|
|
390
|
-
// "Posts" parent. The aggregated table at /posts and the type cards
|
|
391
|
-
// at /posts/types are the entry points; individual post-type
|
|
392
|
-
// collections are not enumerated in the sidebar to avoid the
|
|
393
|
-
// duplicate-nav problem when a project has many types.
|
|
394
|
-
if (posts.length > 0) {
|
|
395
|
-
items.push({
|
|
396
|
-
path: '/posts',
|
|
397
|
-
label: 'Posts',
|
|
398
|
-
icon: FileText,
|
|
399
|
-
group: 'Content',
|
|
400
|
-
children: POSTS_CHILDREN,
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
// Standard Content destinations (always present — they map to CMS
|
|
404
|
-
// features, not collections).
|
|
405
|
-
items.push({ path: '/media', label: 'Media', icon: Image, group: 'Content' }, { path: '/forms', label: 'Forms', icon: ClipboardList, group: 'Content' }, { path: '/seo', label: 'SEO', icon: SearchIcon, group: 'Content' }, { path: '/script-tags', label: 'Script Tags', icon: Code2, group: 'Content' }, { path: '/trash', label: 'Trash', icon: Trash2, group: 'Content' });
|
|
406
|
-
// Plugin-contributed custom nav links (PluginDefinition.adminNavItems,
|
|
407
|
-
// collected onto `_pluginNavItems` by cms-core's applyPlugins). Deduped by
|
|
408
|
-
// path against everything already present so a plugin can't double a built-in
|
|
409
|
-
// destination or one of its own collections. Emitted HERE — inside the Content
|
|
410
|
-
// block, before the custom collection groups below — so their `group: 'Content'`
|
|
411
|
-
// stays contiguous and doesn't start a second "CONTENT" header after the groups.
|
|
412
|
-
const pluginNav = Array.isArray(config?._pluginNavItems)
|
|
413
|
-
? config._pluginNavItems
|
|
414
|
-
: [];
|
|
415
|
-
for (const item of pluginNav) {
|
|
416
|
-
if (!item?.path || items.some((n) => n.path === item.path))
|
|
417
|
-
continue;
|
|
418
|
-
items.push({
|
|
419
|
-
label: item.label ?? item.path,
|
|
420
|
-
path: item.path,
|
|
421
|
-
icon: (item.icon && ICON_MAP[item.icon]) || FileText,
|
|
422
|
-
group: 'Content',
|
|
423
|
-
});
|
|
424
|
-
}
|
|
425
|
-
// Config-supplied custom groups land after the standard Content block and
|
|
426
|
-
// before Settings. Each renders under its own header. Skip any collection
|
|
427
|
-
// whose path a built-in Content destination (or an already-added item) already
|
|
428
|
-
// provides — otherwise a grouped collection like plugin-forms' `forms`
|
|
429
|
-
// (admin.group: 'Forms', path `/forms`) duplicates the static Forms entry, and
|
|
430
|
-
// `applyFormsNav` then attaches "All Entries" to BOTH.
|
|
431
|
-
const groupBuckets = new Map();
|
|
432
|
-
for (const col of grouped) {
|
|
433
|
-
const path = `/${col.slug}`;
|
|
434
|
-
if (items.some((n) => n.path === path))
|
|
435
|
-
continue;
|
|
436
|
-
const group = col.admin.group;
|
|
437
|
-
const bucket = groupBuckets.get(group) ?? [];
|
|
438
|
-
bucket.push({
|
|
439
|
-
label: col.labels?.plural ?? col.slug,
|
|
440
|
-
path,
|
|
441
|
-
icon: resolveIcon(col),
|
|
442
|
-
group,
|
|
443
|
-
});
|
|
444
|
-
groupBuckets.set(group, bucket);
|
|
445
|
-
}
|
|
446
|
-
for (const bucket of groupBuckets.values())
|
|
447
|
-
items.push(...bucket);
|
|
448
|
-
// Settings destinations — always last. Users + API Keys now live inside
|
|
449
|
-
// the Settings view as tabs (see Settings.tsx), so only Settings is anchored
|
|
450
|
-
// here.
|
|
451
|
-
items.push({ path: '/jobs', label: 'Jobs', icon: ListTodo, group: 'Settings' }, { path: '/settings', label: 'Settings', icon: Settings, group: 'Settings' });
|
|
452
|
-
return items;
|
|
453
|
-
}
|
|
454
418
|
//# sourceMappingURL=Sidebar.js.map
|