@prenta/admin 2.6.0 → 2.7.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 +104 -0
- package/design-system/tokens.css +179 -85
- package/design-system/tokens.json +276 -85
- package/design-system/tokens.scss +148 -44
- package/design-system/tokens.tailwind.cjs +50 -1
- package/dist/AdminRoot.d.ts.map +1 -1
- package/dist/AdminRoot.js +42 -20
- 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/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 +393 -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 +387 -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 +88 -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-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/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 +908 -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 +695 -0
- package/dist/__tests__/views/jobs-list.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/mcp-connect.render.test.js +1 -0
- package/dist/__tests__/views/mcp-connect.render.test.js.map +1 -1
- 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 +6 -0
- package/dist/lib/api.d.ts.map +1 -1
- package/dist/lib/api.js +1 -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/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 +187 -0
- package/dist/lib/job-view.d.ts.map +1 -0
- package/dist/lib/job-view.js +363 -0
- package/dist/lib/job-view.js.map +1 -0
- package/dist/lib/jobs-service.d.ts +134 -0
- package/dist/lib/jobs-service.d.ts.map +1 -0
- package/dist/lib/jobs-service.js +179 -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 +6 -0
- package/dist/views/AppearanceChrome.d.ts.map +1 -0
- package/dist/views/AppearanceChrome.js +25 -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 +21 -0
- package/dist/views/Jobs/CancelJobDialog.d.ts.map +1 -0
- package/dist/views/Jobs/CancelJobDialog.js +66 -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 +44 -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 +31 -0
- package/dist/views/Jobs/JobDrawer.d.ts.map +1 -0
- package/dist/views/Jobs/JobDrawer.js +353 -0
- package/dist/views/Jobs/JobDrawer.js.map +1 -0
- package/dist/views/Jobs/JobsTable.d.ts +19 -0
- package/dist/views/Jobs/JobsTable.d.ts.map +1 -0
- package/dist/views/Jobs/JobsTable.js +80 -0
- package/dist/views/Jobs/JobsTable.js.map +1 -0
- package/dist/views/Jobs/WorkerStrip.d.ts +22 -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 +23 -0
- package/dist/views/Jobs/focus.d.ts.map +1 -0
- package/dist/views/Jobs/focus.js +54 -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/placeholders.d.ts +6 -0
- package/dist/views/Jobs/placeholders.d.ts.map +1 -0
- package/dist/views/Jobs/placeholders.js +20 -0
- package/dist/views/Jobs/placeholders.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 +10 -1
- package/dist/views/Jobs.d.ts.map +1 -1
- package/dist/views/Jobs.js +126 -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/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/McpConnectTab.d.ts.map +1 -1
- package/dist/views/settings/McpConnectTab.js +1 -1
- package/dist/views/settings/McpConnectTab.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 +11 -9
- package/src/AdminRoot.tsx +88 -30
- 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/job-drawer.test.ts +493 -0
- package/src/__tests__/lib/job-view.test.ts +437 -0
- package/src/__tests__/lib/jobs-service.test.ts +98 -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-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/jobs-drawer.render.test.tsx +1047 -0
- package/src/__tests__/views/jobs-list.render.test.tsx +850 -0
- package/src/__tests__/views/kpi-grid.test.ts +29 -0
- package/src/__tests__/views/mcp-connect.render.test.tsx +1 -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 +7 -1
- package/src/lib/appearance-api.ts +4 -0
- package/src/lib/job-drawer.ts +424 -0
- package/src/lib/job-view.ts +456 -0
- package/src/lib/jobs-service.ts +290 -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 +263 -82
- package/src/styles/responsive.css +460 -22
- package/src/styles/theme.css +177 -28
- package/src/views/ApiKeys.tsx +2 -2
- package/src/views/AppearanceChrome.tsx +74 -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 +127 -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 +556 -0
- package/src/views/Jobs/JobsTable.tsx +260 -0
- package/src/views/Jobs/WorkerStrip.tsx +144 -0
- package/src/views/Jobs/atoms.tsx +93 -0
- package/src/views/Jobs/focus.ts +56 -0
- package/src/views/Jobs/icons.tsx +111 -0
- package/src/views/Jobs/placeholders.tsx +66 -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 +282 -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/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/McpConnectTab.tsx +2 -1
- 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
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
export interface CountChipProps {
|
|
4
|
+
/** The count. A string for formatted values ("2.4 GB"). */
|
|
5
|
+
n: number | string
|
|
6
|
+
label: string
|
|
7
|
+
/** `ok` colours the number `--suc`; `bad` the chip `--err`; `muted` the number `--muted`. */
|
|
8
|
+
tone?: 'ok' | 'bad' | 'muted'
|
|
9
|
+
/** Leading 12px icon (Script Tags' "Consent-gated" shield). */
|
|
10
|
+
icon?: ReactNode
|
|
11
|
+
href?: string
|
|
12
|
+
onClick?: () => void
|
|
13
|
+
selected?: boolean
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Page-header count chip (SHELL.md §4 "Count chip", `.stat-pill` in
|
|
18
|
+
* cms-layouts.css), one look on Forms, Inbox, Media and Script Tags.
|
|
19
|
+
* Renders a link or button when it navigates; otherwise a static span.
|
|
20
|
+
*/
|
|
21
|
+
export function CountChip({ n, label, tone, icon, href, onClick, selected }: CountChipProps) {
|
|
22
|
+
const interactive = Boolean(href || onClick)
|
|
23
|
+
const className = [
|
|
24
|
+
// Explicit leading: the admin base layer styles `button` at 1.5 / 500.
|
|
25
|
+
'inline-flex items-center gap-[5px] rounded-pill border px-2.5 py-[3px] text-sm2 leading-[1.5] font-[450] whitespace-nowrap no-underline',
|
|
26
|
+
// Forced colors flatten the selected fill and border, so a selected chip
|
|
27
|
+
// gets an outline there (as the current nav row does).
|
|
28
|
+
selected
|
|
29
|
+
? 'border-acc bg-acc-l text-acc forced-colors:outline-2 forced-colors:outline-offset-1 forced-colors:outline-solid'
|
|
30
|
+
: tone === 'bad'
|
|
31
|
+
? 'border-[color-mix(in_srgb,var(--err)_35%,var(--bdr))] bg-card text-err'
|
|
32
|
+
: 'border-bdr bg-card text-sub',
|
|
33
|
+
interactive ? 'cursor-pointer hover:border-acc-m hover:text-acc' : '',
|
|
34
|
+
]
|
|
35
|
+
.filter(Boolean)
|
|
36
|
+
.join(' ')
|
|
37
|
+
|
|
38
|
+
const numberClass = `font-bold tabular-nums ${
|
|
39
|
+
tone === 'ok'
|
|
40
|
+
? 'text-suc'
|
|
41
|
+
: tone === 'bad'
|
|
42
|
+
? 'text-err'
|
|
43
|
+
: tone === 'muted'
|
|
44
|
+
? 'text-faint'
|
|
45
|
+
: selected
|
|
46
|
+
? 'text-acc'
|
|
47
|
+
: 'text-txt'
|
|
48
|
+
}`
|
|
49
|
+
|
|
50
|
+
const inner: ReactNode = (
|
|
51
|
+
<>
|
|
52
|
+
{icon ? (
|
|
53
|
+
<span aria-hidden="true" className="flex [&>svg]:h-3 [&>svg]:w-3">
|
|
54
|
+
{icon}
|
|
55
|
+
</span>
|
|
56
|
+
) : null}
|
|
57
|
+
<b className={numberClass}>{n}</b>
|
|
58
|
+
{label}
|
|
59
|
+
</>
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
if (href) {
|
|
63
|
+
return (
|
|
64
|
+
<a
|
|
65
|
+
href={href}
|
|
66
|
+
className={className}
|
|
67
|
+
aria-current={selected ? 'true' : undefined}
|
|
68
|
+
onClick={
|
|
69
|
+
onClick
|
|
70
|
+
? (event) => {
|
|
71
|
+
if (event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey) return
|
|
72
|
+
event.preventDefault()
|
|
73
|
+
onClick()
|
|
74
|
+
}
|
|
75
|
+
: undefined
|
|
76
|
+
}
|
|
77
|
+
>
|
|
78
|
+
{inner}
|
|
79
|
+
</a>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
if (onClick) {
|
|
83
|
+
return (
|
|
84
|
+
<button type="button" onClick={onClick} className={className} aria-pressed={selected}>
|
|
85
|
+
{inner}
|
|
86
|
+
</button>
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
return <span className={className}>{inner}</span>
|
|
90
|
+
}
|
|
@@ -5,7 +5,8 @@ import type { ButtonHTMLAttributes, ReactNode } from 'react'
|
|
|
5
5
|
/**
|
|
6
6
|
* Design-system filter pill (`.pill` / `.pill.act`): bordered card-surface
|
|
7
7
|
* chip that fills with the accent color when active. Used for status / role /
|
|
8
|
-
* category filter rows above list views.
|
|
8
|
+
* category filter rows above list views. Never wraps its label ("Body start"
|
|
9
|
+
* stays on one line; ScriptTags.html `.filter-pill { white-space: nowrap }`).
|
|
9
10
|
*/
|
|
10
11
|
export interface FilterPillProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'type'> {
|
|
11
12
|
active?: boolean
|
|
@@ -25,9 +26,10 @@ export function FilterPill({
|
|
|
25
26
|
<button
|
|
26
27
|
type="button"
|
|
27
28
|
aria-pressed={active}
|
|
28
|
-
className={`inline-flex items-center gap-1.5 rounded-[7px] border px-3 py-1.5 text-[12.5px] font-medium transition-colors duration-[var(--motion-fast)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none ${
|
|
29
|
+
className={`inline-flex items-center gap-1.5 rounded-[7px] border px-3 py-1.5 text-[12.5px] font-medium whitespace-nowrap transition-colors duration-[var(--motion-fast)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none ${
|
|
29
30
|
active
|
|
30
|
-
?
|
|
31
|
+
? // Forced colors drop the fill: the active pill keeps an outline.
|
|
32
|
+
'border-[var(--acc)] bg-[var(--acc)] text-white forced-colors:outline-2 forced-colors:outline-offset-1 forced-colors:outline-solid'
|
|
31
33
|
: 'border-[var(--bdr)] bg-[var(--card)] text-[var(--sub)] hover:border-[var(--acc-m)] hover:text-[var(--acc)]'
|
|
32
34
|
} ${className ?? ''}`}
|
|
33
35
|
{...rest}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import type
|
|
3
|
+
import { useRef, type ReactNode } from 'react'
|
|
4
4
|
import { X } from 'lucide-react'
|
|
5
|
+
import { useSheetFocus } from '../../lib/sheet-focus.js'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Design-system inline split-pane pattern: a list that shrinks while a
|
|
@@ -53,21 +54,33 @@ export function InspectorPane({
|
|
|
53
54
|
children,
|
|
54
55
|
'aria-label': ariaLabel,
|
|
55
56
|
}: InspectorPaneProps) {
|
|
57
|
+
const regionRef = useRef<HTMLDivElement>(null)
|
|
58
|
+
|
|
59
|
+
// Below 769px the open pane is a sheet over the content column (kit
|
|
60
|
+
// `.sp.open`; `[data-inspector-open]` in responsive.css hides the list and
|
|
61
|
+
// the page header around it), so the row that opened it is no longer on
|
|
62
|
+
// screen: focus moves into the pane, and back to that row when it closes.
|
|
63
|
+
useSheetFocus(open, regionRef)
|
|
64
|
+
|
|
56
65
|
// Cap at the split row's width (100% of the flex container) so the pane
|
|
57
|
-
// never overflows
|
|
66
|
+
// never overflows tablets. Below the cap the pane fills the row
|
|
58
67
|
// master–detail style: the list yields, and the close button returns to
|
|
59
68
|
// it. On desktop the min() resolves to the design's fixed px width, so
|
|
60
|
-
// nothing changes there.
|
|
69
|
+
// nothing changes there. Below 769px it is a sheet: the whole content
|
|
70
|
+
// column, no gutter, border or radius.
|
|
61
71
|
return (
|
|
62
72
|
<div
|
|
63
|
-
|
|
73
|
+
data-inspector-open={open ? '' : undefined}
|
|
74
|
+
className="mobile:motion-safe:transition-none shrink-0 overflow-hidden bg-[var(--bg)] motion-safe:transition-[width] motion-safe:duration-200"
|
|
64
75
|
style={{ width: open ? `min(${width}px, 100%)` : 0 }}
|
|
65
76
|
aria-hidden={!open}
|
|
66
77
|
>
|
|
67
78
|
<div
|
|
79
|
+
ref={regionRef}
|
|
68
80
|
role="region"
|
|
69
81
|
aria-label={ariaLabel}
|
|
70
|
-
|
|
82
|
+
tabIndex={-1}
|
|
83
|
+
className="mobile:m-0 mobile:h-full mobile:w-full! mobile:rounded-none mobile:border-0 mobile:shadow-none my-3 mr-3 ml-4 flex h-[calc(100%-24px)] flex-col overflow-hidden rounded-[var(--r)] border border-[var(--bdr)] bg-[var(--sb)] shadow-[var(--shd2)]"
|
|
71
84
|
style={{ width: `min(${width - 28}px, calc(100% - 28px))` }}
|
|
72
85
|
>
|
|
73
86
|
{open ? children : null}
|
|
@@ -92,9 +105,10 @@ export function InspectorPaneHeader({
|
|
|
92
105
|
type="button"
|
|
93
106
|
onClick={onClose}
|
|
94
107
|
aria-label={closeLabel}
|
|
95
|
-
|
|
108
|
+
// The only way out of the mobile sheet: 44px there, and on touch.
|
|
109
|
+
className="prenta-touch-target mobile:-my-2 mobile:-mr-2 mobile:h-11 mobile:w-11 flex h-7 w-7 shrink-0 items-center justify-center rounded-[6px] text-[var(--muted)] transition-colors duration-[var(--motion-fast)] hover:bg-[var(--bg)] hover:text-[var(--txt)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none"
|
|
96
110
|
>
|
|
97
|
-
<X size={16} />
|
|
111
|
+
<X size={16} aria-hidden />
|
|
98
112
|
</button>
|
|
99
113
|
</div>
|
|
100
114
|
)
|
|
@@ -12,6 +12,16 @@ const MODAL_SIZE_CLASS = {
|
|
|
12
12
|
xl: 'flex max-h-[min(92vh,880px)] max-w-5xl flex-col',
|
|
13
13
|
} as const
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Below 769px every size is a bottom sheet (cms-layouts.css `.modal`): full
|
|
17
|
+
* width, at most 92dvh (the visible height, so a mobile browser's toolbar
|
|
18
|
+
* doesn't push it off screen), 16px top corners, the body scrolling between a fixed
|
|
19
|
+
* title row and footer, clear of the home indicator. Footer buttons share the
|
|
20
|
+
* row at 44px.
|
|
21
|
+
*/
|
|
22
|
+
const SHEET_CLASS =
|
|
23
|
+
'mobile:top-auto mobile:bottom-0 mobile:left-0 mobile:flex mobile:max-h-[92dvh] mobile:w-full mobile:max-w-none mobile:translate-x-0 mobile:translate-y-0 mobile:flex-col mobile:rounded-t-[16px] mobile:rounded-b-none mobile:border-x-0 mobile:border-b-0 mobile:pb-[env(safe-area-inset-bottom,0px)]'
|
|
24
|
+
|
|
15
25
|
type ModalSize = keyof typeof MODAL_SIZE_CLASS
|
|
16
26
|
|
|
17
27
|
export interface ModalProps {
|
|
@@ -98,7 +108,7 @@ export function Modal({
|
|
|
98
108
|
<Dialog.Overlay className="fixed inset-0 z-60 bg-black/50" />
|
|
99
109
|
<Dialog.Content
|
|
100
110
|
ref={contentRef}
|
|
101
|
-
className={`bg-card text-card-foreground border-border fixed top-1/2 left-1/2 z-60 w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 rounded-lg border shadow-xl focus:outline-none ${MODAL_SIZE_CLASS[size]}`}
|
|
111
|
+
className={`bg-card text-card-foreground border-border fixed top-1/2 left-1/2 z-60 w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 rounded-lg border shadow-xl focus:outline-none ${MODAL_SIZE_CLASS[size]} ${SHEET_CLASS}`}
|
|
102
112
|
onInteractOutside={(event) => {
|
|
103
113
|
// Radix dispatches this custom event on the outside target, so
|
|
104
114
|
// `event.currentTarget` is not the parent Dialog.Content.
|
|
@@ -126,28 +136,32 @@ export function Modal({
|
|
|
126
136
|
: undefined
|
|
127
137
|
}
|
|
128
138
|
>
|
|
129
|
-
<div className="border-border flex items-center justify-between border-b px-6 py-4">
|
|
139
|
+
<div className="border-border mobile:px-4 flex shrink-0 items-center justify-between border-b px-6 py-4">
|
|
130
140
|
<Dialog.Title className="text-foreground text-lg font-medium">{title}</Dialog.Title>
|
|
131
141
|
<Dialog.Close asChild>
|
|
132
142
|
<button
|
|
133
143
|
type="button"
|
|
134
144
|
aria-label="Close dialog"
|
|
135
|
-
className="text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:ring-ring rounded-md p-1 transition-colors focus-visible:ring-2 focus-visible:outline-none"
|
|
145
|
+
className="text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:ring-ring prenta-touch-target mobile:h-11 mobile:w-11 flex items-center justify-center rounded-md p-1 transition-colors focus-visible:ring-2 focus-visible:outline-none"
|
|
136
146
|
>
|
|
137
147
|
<X className="h-4 w-4" aria-hidden />
|
|
138
148
|
</button>
|
|
139
149
|
</Dialog.Close>
|
|
140
150
|
</div>
|
|
141
151
|
{description && (
|
|
142
|
-
<Dialog.Description className="text-muted-foreground px-6 pt-4 text-sm">
|
|
152
|
+
<Dialog.Description className="text-muted-foreground mobile:px-4 shrink-0 px-6 pt-4 text-sm">
|
|
143
153
|
{description}
|
|
144
154
|
</Dialog.Description>
|
|
145
155
|
)}
|
|
146
|
-
<div
|
|
156
|
+
<div
|
|
157
|
+
className={`${scrollBody ? 'min-h-0 flex-1 overflow-y-auto' : ''} mobile:min-h-0 mobile:flex-1 mobile:overflow-y-auto mobile:px-4 px-6 py-4`}
|
|
158
|
+
>
|
|
147
159
|
{children}
|
|
148
160
|
</div>
|
|
149
161
|
{actions && (
|
|
150
|
-
<div className="border-border flex justify-end gap-2 border-t px-6 py-4">
|
|
162
|
+
<div className="border-border mobile:px-4 mobile:py-3 mobile:[&>*]:min-h-11 mobile:[&>*]:flex-[1_1_0] flex shrink-0 justify-end gap-2 border-t px-6 py-4">
|
|
163
|
+
{actions}
|
|
164
|
+
</div>
|
|
151
165
|
)}
|
|
152
166
|
</Dialog.Content>
|
|
153
167
|
</Dialog.Portal>
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
export interface PageHeaderProps {
|
|
4
|
+
/** Page title. It equals the screen's sidebar label. */
|
|
5
|
+
title: string
|
|
6
|
+
subtitle?: ReactNode
|
|
7
|
+
/** Right-aligned header actions (buttons, AI button, live toggle). */
|
|
8
|
+
actions?: ReactNode
|
|
9
|
+
/** A `<Breadcrumb>`, on second-level screens only. */
|
|
10
|
+
breadcrumb?: ReactNode
|
|
11
|
+
/**
|
|
12
|
+
* Drop the page gutter padding, for screens whose wrapper already pads the
|
|
13
|
+
* content (the kit's Jobs and Appearance layouts, `padding: 22px 28px`).
|
|
14
|
+
*/
|
|
15
|
+
flush?: boolean
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Page title row (SHELL.md §4): padding 14px var(--gut) 0; title 21 / 700 /
|
|
20
|
+
* -0.5px; subtitle 13px --sub, max 640px; actions right-aligned, gap 8.
|
|
21
|
+
*
|
|
22
|
+
* Tiers (cms-layouts.css): the title is 19px at tablet, 18px on mobile and
|
|
23
|
+
* 26px at 4K; the subtitle 12.5px on mobile, 14.5px at 4K, and a plain-text
|
|
24
|
+
* subtitle hides below 461px. On mobile the actions wrap under the title
|
|
25
|
+
* (row gap 10px). The actions cluster is `data-header-actions`, so its
|
|
26
|
+
* buttons collapse to icons at tablet and mobile and its `data-fab` action
|
|
27
|
+
* floats on mobile (responsive.css).
|
|
28
|
+
*/
|
|
29
|
+
export function PageHeader({
|
|
30
|
+
title,
|
|
31
|
+
subtitle,
|
|
32
|
+
actions,
|
|
33
|
+
breadcrumb,
|
|
34
|
+
flush = false,
|
|
35
|
+
}: PageHeaderProps) {
|
|
36
|
+
return (
|
|
37
|
+
<header
|
|
38
|
+
className={`mobile:gap-y-2.5 flex flex-wrap items-start gap-4 ${flush ? '' : 'px-[var(--gut)] pt-3.5'}`}
|
|
39
|
+
>
|
|
40
|
+
<div className="min-w-0 flex-[1_1_360px]">
|
|
41
|
+
{breadcrumb ? <div className="mb-1">{breadcrumb}</div> : null}
|
|
42
|
+
<h1 className="text-page text-txt tablet:text-[19px] mobile:text-[18px] 4k:text-[26px] m-0 leading-[normal]">
|
|
43
|
+
{title}
|
|
44
|
+
</h1>
|
|
45
|
+
{typeof subtitle === 'string' ? (
|
|
46
|
+
<p className="text-body text-sub mobile:text-[12.5px] 4k:text-[14.5px] m-0 mt-[3px] max-w-[640px] leading-[normal] text-pretty [@media(width<461px)]:hidden">
|
|
47
|
+
{subtitle}
|
|
48
|
+
</p>
|
|
49
|
+
) : subtitle ? (
|
|
50
|
+
// Rich subtitles (status pills, presence) may hold block elements.
|
|
51
|
+
<div className="text-body text-sub mobile:text-[12.5px] 4k:text-[14.5px] mt-[3px] flex flex-wrap items-center gap-3 leading-[normal]">
|
|
52
|
+
{subtitle}
|
|
53
|
+
</div>
|
|
54
|
+
) : null}
|
|
55
|
+
</div>
|
|
56
|
+
{actions ? (
|
|
57
|
+
<div data-header-actions="" className="ml-auto flex flex-wrap items-center gap-2">
|
|
58
|
+
{actions}
|
|
59
|
+
</div>
|
|
60
|
+
) : null}
|
|
61
|
+
</header>
|
|
62
|
+
)
|
|
63
|
+
}
|
|
@@ -6,11 +6,16 @@ import type { ButtonHTMLAttributes, ReactNode } from 'react'
|
|
|
6
6
|
* Design-system table row actions (`.row-actions` / `.ra-icon-btn`): a
|
|
7
7
|
* right-aligned cluster of 27px bordered icon buttons that fades in on row
|
|
8
8
|
* hover (the row must have the `group` class) and on keyboard focus.
|
|
9
|
+
*
|
|
10
|
+
* At 1024px and below, and on screens that can't hover, the actions are
|
|
11
|
+
* always shown (cms-layouts.css): there is no hover to reveal them. On a
|
|
12
|
+
* mobile card they line up at the start of its actions row, 44px each
|
|
13
|
+
* (responsive.css); on touch screens they are 44px everywhere.
|
|
9
14
|
*/
|
|
10
15
|
export function RowActions({ children, className }: { children: ReactNode; className?: string }) {
|
|
11
16
|
return (
|
|
12
17
|
<div
|
|
13
|
-
className={`flex items-center justify-end gap-1 opacity-0 transition-opacity duration-[var(--motion-fast)] group-hover:opacity-100 focus-within:opacity-100 ${className ?? ''}`}
|
|
18
|
+
className={`narrow:opacity-100 mobile:justify-start flex items-center justify-end gap-1 opacity-0 transition-opacity duration-[var(--motion-fast)] group-hover:opacity-100 focus-within:opacity-100 [@media(hover:none)]:opacity-100 ${className ?? ''}`}
|
|
14
19
|
>
|
|
15
20
|
{children}
|
|
16
21
|
</div>
|
|
@@ -37,7 +42,7 @@ export function RowActionButton({
|
|
|
37
42
|
return (
|
|
38
43
|
<button
|
|
39
44
|
type="button"
|
|
40
|
-
className={`flex h-[27px] w-[27px] items-center justify-center rounded-[6px] border border-[var(--bdr)] bg-[var(--card)] text-[var(--muted)] transition-colors duration-[var(--motion-fast)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 ${
|
|
45
|
+
className={`prenta-touch-target flex h-[27px] w-[27px] items-center justify-center rounded-[6px] border border-[var(--bdr)] bg-[var(--card)] text-[var(--muted)] transition-colors duration-[var(--motion-fast)] focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 ${
|
|
41
46
|
danger
|
|
42
47
|
? 'hover:border-[var(--err)] hover:bg-[var(--err-l)] hover:text-[var(--err)]'
|
|
43
48
|
: 'hover:border-[var(--acc-m)] hover:bg-[var(--acc-l)] hover:text-[var(--acc)]'
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { useRef, type KeyboardEvent } from 'react'
|
|
4
|
+
|
|
5
|
+
export interface SegmentedOption {
|
|
6
|
+
id: string
|
|
7
|
+
label: string
|
|
8
|
+
count?: number
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface SegmentedProps {
|
|
12
|
+
options: SegmentedOption[]
|
|
13
|
+
value: string
|
|
14
|
+
onChange: (id: string) => void
|
|
15
|
+
/** Accessible name for the control. */
|
|
16
|
+
label: string
|
|
17
|
+
/** Optional counts by option id; an option's own `count` wins. */
|
|
18
|
+
counts?: Record<string, number | undefined>
|
|
19
|
+
className?: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Segmented control (SHELL.md §6, `.jb-seg`). The active segment is a raised
|
|
24
|
+
* card, not a filled accent. Arrow keys, Home and End move between segments.
|
|
25
|
+
*/
|
|
26
|
+
export function Segmented({
|
|
27
|
+
options,
|
|
28
|
+
value,
|
|
29
|
+
onChange,
|
|
30
|
+
label,
|
|
31
|
+
counts,
|
|
32
|
+
className = '',
|
|
33
|
+
}: SegmentedProps) {
|
|
34
|
+
const refs = useRef<Array<HTMLButtonElement | null>>([])
|
|
35
|
+
// Roving tab stop only: with no matching value no option is selected, but
|
|
36
|
+
// the first one still takes focus.
|
|
37
|
+
const selectedIndex = Math.max(
|
|
38
|
+
0,
|
|
39
|
+
options.findIndex((option) => option.id === value),
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
function onKeyDown(event: KeyboardEvent<HTMLDivElement>) {
|
|
43
|
+
const last = options.length - 1
|
|
44
|
+
let next: number
|
|
45
|
+
if (event.key === 'ArrowRight' || event.key === 'ArrowDown')
|
|
46
|
+
next = selectedIndex === last ? 0 : selectedIndex + 1
|
|
47
|
+
else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp')
|
|
48
|
+
next = selectedIndex === 0 ? last : selectedIndex - 1
|
|
49
|
+
else if (event.key === 'Home') next = 0
|
|
50
|
+
else if (event.key === 'End') next = last
|
|
51
|
+
else return
|
|
52
|
+
event.preventDefault()
|
|
53
|
+
const option = options[next]
|
|
54
|
+
if (!option) return
|
|
55
|
+
onChange(option.id)
|
|
56
|
+
refs.current[next]?.focus()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<div
|
|
61
|
+
role="tablist"
|
|
62
|
+
aria-label={label}
|
|
63
|
+
onKeyDown={onKeyDown}
|
|
64
|
+
className={`rounded-9 border-bdr bg-bg inline-flex w-fit max-w-full gap-0.5 overflow-x-auto border p-0.5 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden ${className}`}
|
|
65
|
+
>
|
|
66
|
+
{options.map((option, index) => {
|
|
67
|
+
const selected = option.id === value
|
|
68
|
+
const count = option.count ?? counts?.[option.id]
|
|
69
|
+
return (
|
|
70
|
+
<button
|
|
71
|
+
key={option.id}
|
|
72
|
+
ref={(el) => {
|
|
73
|
+
refs.current[index] = el
|
|
74
|
+
}}
|
|
75
|
+
type="button"
|
|
76
|
+
role="tab"
|
|
77
|
+
aria-selected={selected}
|
|
78
|
+
tabIndex={index === selectedIndex ? 0 : -1}
|
|
79
|
+
onClick={() => onChange(option.id)}
|
|
80
|
+
className={`rounded-7 text-sm2 flex cursor-pointer items-center gap-1.5 border-0 px-[11px] py-[5px] leading-[normal] font-semibold whitespace-nowrap ${
|
|
81
|
+
selected ? 'bg-card text-txt shadow-shd' : 'text-sub hover:text-txt bg-transparent'
|
|
82
|
+
}`}
|
|
83
|
+
>
|
|
84
|
+
{option.label}
|
|
85
|
+
{typeof count === 'number' ? (
|
|
86
|
+
<b
|
|
87
|
+
className={`text-micro font-bold tabular-nums ${selected ? 'text-acc' : 'text-faint'}`}
|
|
88
|
+
>
|
|
89
|
+
{count}
|
|
90
|
+
</b>
|
|
91
|
+
) : null}
|
|
92
|
+
</button>
|
|
93
|
+
)
|
|
94
|
+
})}
|
|
95
|
+
</div>
|
|
96
|
+
)
|
|
97
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { isValidElement, useEffect } from 'react'
|
|
4
|
+
import { Toaster as SonnerToaster, toast } from 'sonner'
|
|
5
|
+
|
|
6
|
+
/** Kit toast lifetime (SHELL.md §7: auto-hides after 2–2.6s). */
|
|
7
|
+
const TOAST_DURATION_MS = 2400
|
|
8
|
+
/**
|
|
9
|
+
* Errors and warnings (the kit shows none) often carry a server message;
|
|
10
|
+
* 2.4s is too short to read one.
|
|
11
|
+
*/
|
|
12
|
+
const ALERT_TOAST_DURATION_MS = 6000
|
|
13
|
+
|
|
14
|
+
type ToastFn = typeof toast.error
|
|
15
|
+
type PromiseFn = typeof toast.promise
|
|
16
|
+
type PromiseData = NonNullable<Parameters<PromiseFn>[1]>
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* `toast.promise`'s `error` option, resolved to settings with the longer
|
|
20
|
+
* lifetime. A `duration` the caller set, on the error result or for the whole
|
|
21
|
+
* promise toast, still wins.
|
|
22
|
+
*/
|
|
23
|
+
function longerError(
|
|
24
|
+
error: PromiseData['error'],
|
|
25
|
+
callerDuration: number | undefined,
|
|
26
|
+
): PromiseData['error'] {
|
|
27
|
+
const duration = callerDuration ?? ALERT_TOAST_DURATION_MS
|
|
28
|
+
const withDuration = (result: unknown) =>
|
|
29
|
+
typeof result === 'object' && result !== null && !isValidElement(result)
|
|
30
|
+
? { duration, ...result }
|
|
31
|
+
: { message: result, duration }
|
|
32
|
+
if (error === undefined) return undefined
|
|
33
|
+
return (async (reason: unknown) =>
|
|
34
|
+
withDuration(
|
|
35
|
+
typeof error === 'function' ? await (error as (reason: unknown) => unknown)(reason) : error,
|
|
36
|
+
)) as PromiseData['error']
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let installs = 0
|
|
40
|
+
let installed: {
|
|
41
|
+
originals: { error: ToastFn; warning: ToastFn; promise: PromiseFn }
|
|
42
|
+
wrappers: { error: ToastFn; warning: ToastFn; promise: PromiseFn }
|
|
43
|
+
} | null = null
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Sonner has no per-type default duration, so while an admin toaster is
|
|
47
|
+
* mounted, `toast.error`, `toast.warning` and the error state of
|
|
48
|
+
* `toast.promise` default to the longer lifetime. A duration passed by the
|
|
49
|
+
* caller still wins. Installed once however many toasters mount, and on the
|
|
50
|
+
* last unmount each function is restored only if ours is still in place.
|
|
51
|
+
*/
|
|
52
|
+
function useAlertDurations() {
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
if (installs++ === 0) {
|
|
55
|
+
const originals = { error: toast.error, warning: toast.warning, promise: toast.promise }
|
|
56
|
+
const longer =
|
|
57
|
+
(fn: ToastFn): ToastFn =>
|
|
58
|
+
(message, data) =>
|
|
59
|
+
fn(message, { duration: ALERT_TOAST_DURATION_MS, ...data })
|
|
60
|
+
const promise = ((p, data) =>
|
|
61
|
+
originals.promise(
|
|
62
|
+
p,
|
|
63
|
+
data && { ...data, error: longerError(data.error, data.duration) },
|
|
64
|
+
)) as PromiseFn
|
|
65
|
+
const wrappers = {
|
|
66
|
+
error: longer(originals.error),
|
|
67
|
+
warning: longer(originals.warning),
|
|
68
|
+
promise,
|
|
69
|
+
}
|
|
70
|
+
Object.assign(toast, wrappers)
|
|
71
|
+
installed = { originals, wrappers }
|
|
72
|
+
}
|
|
73
|
+
return () => {
|
|
74
|
+
if (--installs > 0 || !installed) return
|
|
75
|
+
const { originals, wrappers } = installed
|
|
76
|
+
for (const key of ['error', 'warning', 'promise'] as const) {
|
|
77
|
+
if (toast[key] === wrappers[key]) Object.assign(toast, { [key]: originals[key] })
|
|
78
|
+
}
|
|
79
|
+
installed = null
|
|
80
|
+
}
|
|
81
|
+
}, [])
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Above the mobile tab bar and the home indicator. sonner switches to
|
|
85
|
+
// `mobileOffset` at 600px and below, where its own gap is 16px and a toast
|
|
86
|
+
// is as wide as the screen, so it also clears a floating action button
|
|
87
|
+
// (`--fab-clear`, set in responsive.css while a page has one). Wider than
|
|
88
|
+
// that, a centred 356px toast doesn't reach the FAB's corner.
|
|
89
|
+
const ABOVE_TAB_BAR = 'var(--tabbar-h) + env(safe-area-inset-bottom)'
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The admin's toast host: sonner, unstyled, painted as the kit toast
|
|
93
|
+
* (SHELL.md §7, `.jb-toast`): fixed 24px above the bottom, centred, --txt
|
|
94
|
+
* background with --bg text, padding 10px 16px, radius 9, 13px / 500.
|
|
95
|
+
* Call sites keep using `toast()` from `sonner`.
|
|
96
|
+
*
|
|
97
|
+
* `aboveTabBar`: lift the toasts clear of the mobile tab bar.
|
|
98
|
+
*/
|
|
99
|
+
export function Toaster({ aboveTabBar = false }: { aboveTabBar?: boolean } = {}) {
|
|
100
|
+
useAlertDurations()
|
|
101
|
+
return (
|
|
102
|
+
<SonnerToaster
|
|
103
|
+
position="bottom-center"
|
|
104
|
+
offset={aboveTabBar ? { bottom: `calc(${ABOVE_TAB_BAR} + 24px)` } : 24}
|
|
105
|
+
mobileOffset={
|
|
106
|
+
aboveTabBar
|
|
107
|
+
? { bottom: `calc(${ABOVE_TAB_BAR} + 16px + var(--fab-clear, 0px))` }
|
|
108
|
+
: undefined
|
|
109
|
+
}
|
|
110
|
+
duration={TOAST_DURATION_MS}
|
|
111
|
+
// Inline, because sonner's injected stylesheet is unlayered and would beat
|
|
112
|
+
// utilities: the admin font (it sets a system stack) and the kit toast layer.
|
|
113
|
+
style={{ fontFamily: 'inherit', zIndex: 'var(--z-toast)' }}
|
|
114
|
+
toastOptions={{
|
|
115
|
+
unstyled: true,
|
|
116
|
+
classNames: {
|
|
117
|
+
// `prenta-inverse`: focus rings on the dark toast use --bg. Toasts
|
|
118
|
+
// stacked behind the front one hide their content, as sonner's own
|
|
119
|
+
// styles do for styled toasts.
|
|
120
|
+
toast:
|
|
121
|
+
'prenta-inverse right-0 left-0 mx-auto flex w-fit max-w-[calc(100vw-32px)] items-center gap-2 rounded-9 bg-txt px-4 py-2.5 text-body leading-[normal] font-medium text-bg shadow-shd2 [&[data-expanded=false][data-front=false]>*]:opacity-0',
|
|
122
|
+
content: 'flex min-w-0 flex-col gap-0.5',
|
|
123
|
+
description: 'text-meta opacity-80',
|
|
124
|
+
// Unstyled sonner drops the icon slot's box; loading spinners need it.
|
|
125
|
+
icon: 'relative flex size-4 shrink-0 items-center justify-center text-bg',
|
|
126
|
+
// The kit toast is text only. Success and info drop sonner's icon;
|
|
127
|
+
// error and warning (which the kit doesn't show) keep theirs.
|
|
128
|
+
success: '[&_[data-icon]]:hidden!',
|
|
129
|
+
info: '[&_[data-icon]]:hidden!',
|
|
130
|
+
actionButton:
|
|
131
|
+
'ml-1 inline-flex h-7 shrink-0 cursor-pointer items-center rounded-7 border-0 bg-acc px-2.5 text-meta font-semibold text-acc-on hover:brightness-[1.07]',
|
|
132
|
+
cancelButton:
|
|
133
|
+
'inline-flex h-7 shrink-0 cursor-pointer items-center rounded-7 border-0 bg-transparent px-2.5 text-meta font-semibold text-bg opacity-85 hover:opacity-100 focus-visible:opacity-100',
|
|
134
|
+
closeButton: 'text-bg',
|
|
135
|
+
},
|
|
136
|
+
}}
|
|
137
|
+
/>
|
|
138
|
+
)
|
|
139
|
+
}
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import * as
|
|
3
|
+
import * as SwitchPrimitive from '@radix-ui/react-switch'
|
|
4
4
|
import { cv, type VariantProps } from '../../lib/cv.js'
|
|
5
5
|
|
|
6
|
+
// Kit switch (SHELL.md §7, `.ap-sw`): 34×19 track, 15px knob at left 2px
|
|
7
|
+
// (17px when on), .15s. Radix renders role="switch" with aria-checked.
|
|
6
8
|
const toggleTrack = cv(
|
|
7
|
-
|
|
9
|
+
// `prenta-touch-hit` grows the hit area to 44px on touch without stretching the track.
|
|
10
|
+
'prenta-touch-hit rounded-pill relative inline-block shrink-0 cursor-pointer border-0 p-0 transition-[background-color] duration-[var(--mo-base)] disabled:cursor-not-allowed disabled:opacity-50',
|
|
8
11
|
{
|
|
9
12
|
variants: {
|
|
10
13
|
variant: {
|
|
11
14
|
/** Design system default — accent when on. */
|
|
12
|
-
accent: 'bg-
|
|
15
|
+
accent: 'bg-bdr data-[state=checked]:bg-acc',
|
|
13
16
|
/** Semantic enable/disable — success green when on (tables, script tags). */
|
|
14
|
-
enabled: 'bg-
|
|
17
|
+
enabled: 'bg-bdr data-[state=checked]:bg-suc',
|
|
15
18
|
},
|
|
16
19
|
size: {
|
|
17
|
-
|
|
18
|
-
md: 'h-[21px] w-[38px]',
|
|
20
|
+
md: 'h-[19px] w-[34px]',
|
|
19
21
|
},
|
|
20
22
|
},
|
|
21
23
|
defaultVariants: {
|
|
@@ -26,12 +28,11 @@ const toggleTrack = cv(
|
|
|
26
28
|
)
|
|
27
29
|
|
|
28
30
|
const toggleThumb = cv(
|
|
29
|
-
'pointer-events-none absolute top-
|
|
31
|
+
'shadow-knob pointer-events-none absolute top-0.5 left-0.5 block rounded-full bg-[var(--toggle-thumb)] transition-[left] duration-[var(--mo-base)]',
|
|
30
32
|
{
|
|
31
33
|
variants: {
|
|
32
34
|
size: {
|
|
33
|
-
|
|
34
|
-
md: 'h-4 w-4',
|
|
35
|
+
md: 'h-[15px] w-[15px] data-[state=checked]:left-[17px]',
|
|
35
36
|
},
|
|
36
37
|
},
|
|
37
38
|
defaultVariants: {
|
|
@@ -53,8 +54,8 @@ export interface ToggleProps extends ToggleVariants {
|
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
/**
|
|
56
|
-
* Design-system
|
|
57
|
-
*
|
|
57
|
+
* Design-system switch (`role="switch"`). Use `variant="enabled"` for on/off
|
|
58
|
+
* tables where green communicates active state. Also exported as `Switch`.
|
|
58
59
|
*/
|
|
59
60
|
export function Toggle({
|
|
60
61
|
checked,
|
|
@@ -68,7 +69,7 @@ export function Toggle({
|
|
|
68
69
|
'aria-describedby': ariaDescribedBy,
|
|
69
70
|
}: ToggleProps) {
|
|
70
71
|
return (
|
|
71
|
-
<
|
|
72
|
+
<SwitchPrimitive.Root
|
|
72
73
|
id={id}
|
|
73
74
|
checked={checked}
|
|
74
75
|
onCheckedChange={onCheckedChange}
|
|
@@ -78,7 +79,10 @@ export function Toggle({
|
|
|
78
79
|
aria-describedby={ariaDescribedBy}
|
|
79
80
|
className={toggleTrack({ variant, size })}
|
|
80
81
|
>
|
|
81
|
-
<
|
|
82
|
-
</
|
|
82
|
+
<SwitchPrimitive.Thumb className={toggleThumb({ size })} />
|
|
83
|
+
</SwitchPrimitive.Root>
|
|
83
84
|
)
|
|
84
85
|
}
|
|
86
|
+
|
|
87
|
+
/** The kit's name for {@link Toggle}. */
|
|
88
|
+
export { Toggle as Switch }
|