@prenta/admin 1.17.0 → 1.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/dist/__tests__/lib/seo-service-errors.test.js +2 -6
- package/dist/__tests__/lib/seo-service-errors.test.js.map +1 -1
- package/dist/__tests__/views/ai-settings.render.test.js +67 -1
- package/dist/__tests__/views/ai-settings.render.test.js.map +1 -1
- package/dist/components/CoauthorResultPopover.d.ts.map +1 -1
- package/dist/components/CoauthorResultPopover.js +4 -1
- package/dist/components/CoauthorResultPopover.js.map +1 -1
- package/dist/components/CommentSidePanel.d.ts +0 -7
- package/dist/components/CommentSidePanel.d.ts.map +1 -1
- package/dist/components/CommentSidePanel.js +0 -2
- package/dist/components/CommentSidePanel.js.map +1 -1
- package/dist/components/EditorRail.d.ts +2 -1
- package/dist/components/EditorRail.d.ts.map +1 -1
- package/dist/components/MediaPickerModal.d.ts +2 -1
- package/dist/components/MediaPickerModal.d.ts.map +1 -1
- package/dist/components/TipTapEditor.d.ts +3 -2
- package/dist/components/TipTapEditor.d.ts.map +1 -1
- package/dist/components/forms/EntriesTable.d.ts +0 -1
- package/dist/components/forms/EntriesTable.d.ts.map +1 -1
- package/dist/components/forms/EntriesTable.js +1 -1
- package/dist/components/forms/EntriesTable.js.map +1 -1
- package/dist/components/pages/tag-badges.d.ts +2 -2
- package/dist/components/pages/tag-badges.d.ts.map +1 -1
- package/dist/components/pages/tag-badges.js.map +1 -1
- package/dist/components/seo/FaqProposalPreview.d.ts +2 -3
- package/dist/components/seo/FaqProposalPreview.d.ts.map +1 -1
- package/dist/components/seo/FaqProposalPreview.js +1 -1
- package/dist/components/seo/FaqProposalPreview.js.map +1 -1
- package/dist/components/seo/SeoCopilotDrawer.js +1 -1
- package/dist/components/seo/SeoCopilotDrawer.js.map +1 -1
- package/dist/components/seo/SeoEditorPane.d.ts.map +1 -1
- package/dist/components/seo/SeoEditorPane.js +4 -1
- package/dist/components/seo/SeoEditorPane.js.map +1 -1
- package/dist/components/ui/Badge.d.ts +3 -9
- package/dist/components/ui/Badge.d.ts.map +1 -1
- package/dist/components/ui/Badge.js +2 -3
- package/dist/components/ui/Badge.js.map +1 -1
- 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 +0 -1
- package/dist/components/ui/Button.js.map +1 -1
- package/dist/components/ui/Card.d.ts +2 -3
- package/dist/components/ui/Card.d.ts.map +1 -1
- package/dist/components/ui/Card.js +0 -4
- package/dist/components/ui/Card.js.map +1 -1
- package/dist/components/ui/Input.d.ts +6 -8
- package/dist/components/ui/Input.d.ts.map +1 -1
- package/dist/components/ui/Input.js +6 -6
- package/dist/components/ui/Input.js.map +1 -1
- package/dist/components/ui/Modal.d.ts +1 -1
- package/dist/components/ui/Modal.d.ts.map +1 -1
- package/dist/components/ui/ResizableAside.d.ts +0 -13
- package/dist/components/ui/ResizableAside.d.ts.map +1 -1
- package/dist/components/ui/ResizableAside.js +5 -5
- package/dist/components/ui/ResizableAside.js.map +1 -1
- package/dist/components/ui/StatusBadge.d.ts +2 -2
- package/dist/components/ui/StatusBadge.d.ts.map +1 -1
- package/dist/components/ui/StatusBadge.js +0 -1
- package/dist/components/ui/StatusBadge.js.map +1 -1
- package/dist/components/ui/Toggle.d.ts +2 -8
- package/dist/components/ui/Toggle.d.ts.map +1 -1
- package/dist/components/ui/Toggle.js +0 -1
- package/dist/components/ui/Toggle.js.map +1 -1
- package/dist/fields/FieldRenderer.d.ts +2 -1
- package/dist/fields/FieldRenderer.d.ts.map +1 -1
- package/dist/fields/index.d.ts +0 -17
- package/dist/fields/index.d.ts.map +1 -1
- package/dist/fields/index.js +0 -15
- package/dist/fields/index.js.map +1 -1
- package/dist/layout/primitives/tokens.d.ts +0 -2
- package/dist/layout/primitives/tokens.d.ts.map +1 -1
- package/dist/layout/primitives/tokens.js +0 -6
- package/dist/layout/primitives/tokens.js.map +1 -1
- package/dist/lib/brand-voice-client.d.ts +14 -1
- package/dist/lib/brand-voice-client.d.ts.map +1 -1
- package/dist/lib/brand-voice-client.js +7 -0
- package/dist/lib/brand-voice-client.js.map +1 -1
- package/dist/lib/coauthor-client.d.ts +2 -1
- package/dist/lib/coauthor-client.d.ts.map +1 -1
- package/dist/lib/collection-schema.d.ts +0 -9
- package/dist/lib/collection-schema.d.ts.map +1 -1
- package/dist/lib/collection-schema.js +2 -2
- package/dist/lib/collection-schema.js.map +1 -1
- package/dist/lib/editor-seo-content.d.ts +0 -10
- package/dist/lib/editor-seo-content.d.ts.map +1 -1
- package/dist/lib/editor-seo-content.js +0 -13
- package/dist/lib/editor-seo-content.js.map +1 -1
- package/dist/lib/forms-service.d.ts +3 -21
- package/dist/lib/forms-service.d.ts.map +1 -1
- package/dist/lib/forms-service.js +0 -25
- package/dist/lib/forms-service.js.map +1 -1
- package/dist/lib/notifications-client.d.ts +4 -3
- package/dist/lib/notifications-client.d.ts.map +1 -1
- package/dist/lib/page-audit-input.d.ts +0 -10
- package/dist/lib/page-audit-input.d.ts.map +1 -1
- package/dist/lib/page-audit-input.js +1 -1
- package/dist/lib/page-audit-input.js.map +1 -1
- package/dist/lib/page-editor-service.d.ts +2 -4
- package/dist/lib/page-editor-service.d.ts.map +1 -1
- package/dist/lib/page-editor-service.js +3 -3
- package/dist/lib/page-editor-service.js.map +1 -1
- package/dist/lib/pages-service.d.ts +2 -13
- package/dist/lib/pages-service.d.ts.map +1 -1
- package/dist/lib/pages-service.js +3 -24
- package/dist/lib/pages-service.js.map +1 -1
- package/dist/lib/plan.d.ts +2 -1
- package/dist/lib/plan.d.ts.map +1 -1
- package/dist/lib/post-editor-service.d.ts +3 -13
- package/dist/lib/post-editor-service.d.ts.map +1 -1
- package/dist/lib/post-editor-service.js +5 -6
- package/dist/lib/post-editor-service.js.map +1 -1
- package/dist/lib/post-types-service.d.ts +2 -3
- package/dist/lib/post-types-service.d.ts.map +1 -1
- package/dist/lib/post-types-service.js +1 -1
- package/dist/lib/post-types-service.js.map +1 -1
- package/dist/lib/posts-service.d.ts +2 -1
- package/dist/lib/posts-service.d.ts.map +1 -1
- package/dist/lib/preview-link.d.ts +0 -9
- package/dist/lib/preview-link.d.ts.map +1 -1
- package/dist/lib/preview-link.js +0 -15
- package/dist/lib/preview-link.js.map +1 -1
- package/dist/lib/rail-width.d.ts +0 -1
- package/dist/lib/rail-width.d.ts.map +1 -1
- package/dist/lib/rail-width.js +1 -1
- package/dist/lib/rail-width.js.map +1 -1
- package/dist/lib/reflow-probe.d.ts +0 -67
- package/dist/lib/reflow-probe.d.ts.map +1 -1
- package/dist/lib/reflow-probe.js +4 -4
- package/dist/lib/reflow-probe.js.map +1 -1
- package/dist/lib/seo-service.d.ts +14 -37
- package/dist/lib/seo-service.d.ts.map +1 -1
- package/dist/lib/seo-service.js +7 -37
- package/dist/lib/seo-service.js.map +1 -1
- package/dist/lib/theme-chrome.d.ts +0 -1
- package/dist/lib/theme-chrome.d.ts.map +1 -1
- package/dist/lib/theme-chrome.js +1 -1
- package/dist/lib/theme-chrome.js.map +1 -1
- package/dist/lib/version-history.d.ts +2 -2
- package/dist/lib/version-history.d.ts.map +1 -1
- package/dist/lib/workflow-chrome.d.ts +0 -3
- package/dist/lib/workflow-chrome.d.ts.map +1 -1
- package/dist/lib/workflow-chrome.js +3 -3
- package/dist/lib/workflow-chrome.js.map +1 -1
- package/dist/prenta-admin.css +1 -1
- package/dist/views/Login.d.ts +2 -1
- package/dist/views/Login.d.ts.map +1 -1
- package/dist/views/MediaBrowser.d.ts.map +1 -1
- package/dist/views/MediaBrowser.js +3 -2
- package/dist/views/MediaBrowser.js.map +1 -1
- package/dist/views/PageEditor.d.ts +2 -1
- package/dist/views/PageEditor.d.ts.map +1 -1
- package/dist/views/Pages/PagesListView.d.ts +0 -1
- package/dist/views/Pages/PagesListView.d.ts.map +1 -1
- package/dist/views/Pages/PagesListView.js +1 -1
- package/dist/views/Pages/PagesListView.js.map +1 -1
- package/dist/views/Pages.d.ts +2 -1
- package/dist/views/Pages.d.ts.map +1 -1
- package/dist/views/Redirects.d.ts +2 -1
- package/dist/views/Redirects.d.ts.map +1 -1
- package/dist/views/page-editor/section-types.d.ts +2 -2
- package/dist/views/page-editor/section-types.d.ts.map +1 -1
- package/dist/views/page-editor/section-types.js +1 -1
- package/dist/views/page-editor/section-types.js.map +1 -1
- package/dist/views/page-editor/sections/admin-renderers.d.ts +2 -1
- package/dist/views/page-editor/sections/admin-renderers.d.ts.map +1 -1
- package/dist/views/page-editor/theme-chrome/index.d.ts +1 -6
- package/dist/views/page-editor/theme-chrome/index.d.ts.map +1 -1
- package/dist/views/page-editor/theme-chrome/index.js +1 -3
- package/dist/views/page-editor/theme-chrome/index.js.map +1 -1
- package/dist/views/page-editor/viewports.d.ts +1 -1
- package/dist/views/page-editor/viewports.d.ts.map +1 -1
- package/dist/views/page-editor/viewports.js +1 -1
- package/dist/views/page-editor/viewports.js.map +1 -1
- package/dist/views/settings/AISettingsTab.d.ts.map +1 -1
- package/dist/views/settings/AISettingsTab.js +13 -3
- package/dist/views/settings/AISettingsTab.js.map +1 -1
- package/dist/views/settings/BrandVoiceCard.d.ts +3 -0
- package/dist/views/settings/BrandVoiceCard.d.ts.map +1 -1
- package/dist/views/settings/BrandVoiceCard.js +2 -2
- package/dist/views/settings/BrandVoiceCard.js.map +1 -1
- package/dist/views/settings/brand-voice/BrandVoiceAlignmentPanel.d.ts.map +1 -1
- package/dist/views/settings/brand-voice/BrandVoiceAlignmentPanel.js +4 -1
- package/dist/views/settings/brand-voice/BrandVoiceAlignmentPanel.js.map +1 -1
- package/dist/views/settings/featureModel.d.ts +0 -3
- package/dist/views/settings/featureModel.d.ts.map +1 -1
- package/dist/views/settings/featureModel.js +2 -2
- package/dist/views/settings/featureModel.js.map +1 -1
- package/dist/views/settings/useAiSettings.d.ts +2 -2
- package/dist/views/settings/useAiSettings.d.ts.map +1 -1
- package/dist/views/settings/useAiSettings.js +6 -2
- package/dist/views/settings/useAiSettings.js.map +1 -1
- package/dist/views/settings/useAppearanceSettings.d.ts +5 -6
- package/dist/views/settings/useAppearanceSettings.d.ts.map +1 -1
- package/dist/views/settings/useAppearanceSettings.js +1 -1
- package/dist/views/settings/useAppearanceSettings.js.map +1 -1
- package/dist/views/settings/useEmailSettings.d.ts +3 -2
- package/dist/views/settings/useEmailSettings.d.ts.map +1 -1
- package/dist/views/settings/useGeneralSettings.d.ts +2 -11
- package/dist/views/settings/useGeneralSettings.d.ts.map +1 -1
- package/dist/views/settings/useGeneralSettings.js +3 -3
- package/dist/views/settings/useGeneralSettings.js.map +1 -1
- package/dist/views/settings/useSeoSettings.d.ts +1 -1
- package/dist/views/settings/useSeoSettings.d.ts.map +1 -1
- package/dist/views/settings/useUpdates.d.ts +1 -3
- package/dist/views/settings/useUpdates.d.ts.map +1 -1
- package/dist/views/settings/useUpdates.js +1 -1
- package/dist/views/settings/useUpdates.js.map +1 -1
- package/package.json +5 -5
- package/src/__tests__/lib/seo-service-errors.test.ts +1 -9
- package/src/__tests__/views/ai-settings.render.test.tsx +86 -2
- package/src/components/CoauthorResultPopover.tsx +3 -1
- package/src/components/CommentSidePanel.tsx +0 -1
- package/src/components/EditorRail.tsx +1 -1
- package/src/components/MediaPickerModal.tsx +1 -1
- package/src/components/TipTapEditor.tsx +2 -2
- package/src/components/forms/EntriesTable.tsx +1 -1
- package/src/components/pages/tag-badges.tsx +1 -1
- package/src/components/seo/FaqProposalPreview.tsx +2 -2
- package/src/components/seo/SeoCopilotDrawer.tsx +1 -1
- package/src/components/seo/SeoEditorPane.tsx +3 -1
- package/src/components/ui/Badge.tsx +4 -6
- package/src/components/ui/Button.tsx +1 -3
- package/src/components/ui/Card.tsx +1 -14
- package/src/components/ui/Input.tsx +7 -15
- package/src/components/ui/Modal.tsx +1 -1
- package/src/components/ui/ResizableAside.tsx +5 -5
- package/src/components/ui/StatusBadge.tsx +1 -3
- package/src/components/ui/Toggle.tsx +1 -3
- package/src/fields/FieldRenderer.tsx +1 -1
- package/src/fields/index.ts +0 -17
- package/src/layout/primitives/tokens.ts +0 -7
- package/src/lib/brand-voice-client.ts +18 -1
- package/src/lib/coauthor-client.ts +1 -1
- package/src/lib/collection-schema.ts +2 -2
- package/src/lib/editor-seo-content.ts +0 -22
- package/src/lib/forms-service.ts +2 -42
- package/src/lib/notifications-client.ts +3 -3
- package/src/lib/page-audit-input.ts +1 -1
- package/src/lib/page-editor-service.ts +1 -3
- package/src/lib/pages-service.ts +4 -29
- package/src/lib/plan.ts +1 -1
- package/src/lib/post-editor-service.ts +4 -10
- package/src/lib/post-types-service.ts +2 -2
- package/src/lib/posts-service.ts +1 -1
- package/src/lib/preview-link.ts +0 -14
- package/src/lib/rail-width.ts +1 -1
- package/src/lib/reflow-probe.ts +4 -4
- package/src/lib/seo-service.ts +20 -74
- package/src/lib/theme-chrome.ts +1 -1
- package/src/lib/version-history.ts +2 -2
- package/src/lib/workflow-chrome.ts +3 -3
- package/src/views/Login.tsx +1 -1
- package/src/views/MediaBrowser.tsx +3 -2
- package/src/views/PageEditor.tsx +1 -1
- package/src/views/Pages/PagesListView.tsx +1 -1
- package/src/views/Pages.tsx +1 -1
- package/src/views/Redirects.tsx +1 -1
- package/src/views/page-editor/section-types.ts +0 -9
- package/src/views/page-editor/sections/admin-renderers.tsx +1 -1
- package/src/views/page-editor/theme-chrome/index.ts +2 -10
- package/src/views/page-editor/viewports.ts +0 -3
- package/src/views/settings/AISettingsTab.tsx +15 -3
- package/src/views/settings/BrandVoiceCard.tsx +11 -1
- package/src/views/settings/brand-voice/BrandVoiceAlignmentPanel.tsx +3 -1
- package/src/views/settings/featureModel.ts +2 -2
- package/src/views/settings/useAiSettings.ts +8 -3
- package/src/views/settings/useAppearanceSettings.ts +4 -6
- package/src/views/settings/useEmailSettings.ts +2 -2
- package/src/views/settings/useGeneralSettings.ts +5 -10
- package/src/views/settings/useSeoSettings.ts +1 -1
- package/src/views/settings/useUpdates.ts +2 -2
- package/dist/components/ContentOverviewChart.d.ts +0 -8
- package/dist/components/ContentOverviewChart.d.ts.map +0 -1
- package/dist/components/ContentOverviewChart.js +0 -20
- package/dist/components/ContentOverviewChart.js.map +0 -1
- package/dist/components/SEOPerformance.d.ts +0 -5
- package/dist/components/SEOPerformance.d.ts.map +0 -1
- package/dist/components/SEOPerformance.js +0 -29
- package/dist/components/SEOPerformance.js.map +0 -1
- package/dist/components/ui/Avatar.d.ts +0 -9
- package/dist/components/ui/Avatar.d.ts.map +0 -1
- package/dist/components/ui/Avatar.js +0 -21
- package/dist/components/ui/Avatar.js.map +0 -1
- package/dist/components/ui/CommandPalette.d.ts +0 -14
- package/dist/components/ui/CommandPalette.d.ts.map +0 -1
- package/dist/components/ui/CommandPalette.js +0 -58
- package/dist/components/ui/CommandPalette.js.map +0 -1
- package/dist/components/ui/DataTable.d.ts +0 -30
- package/dist/components/ui/DataTable.d.ts.map +0 -1
- package/dist/components/ui/DataTable.js +0 -44
- package/dist/components/ui/DataTable.js.map +0 -1
- package/dist/components/ui/Pagination.d.ts +0 -9
- package/dist/components/ui/Pagination.d.ts.map +0 -1
- package/dist/components/ui/Pagination.js +0 -26
- package/dist/components/ui/Pagination.js.map +0 -1
- package/dist/components/ui/Select.d.ts +0 -16
- package/dist/components/ui/Select.d.ts.map +0 -1
- package/dist/components/ui/Select.js +0 -24
- package/dist/components/ui/Select.js.map +0 -1
- package/dist/components/ui/Toast.d.ts +0 -18
- package/dist/components/ui/Toast.d.ts.map +0 -1
- package/dist/components/ui/Toast.js +0 -29
- package/dist/components/ui/Toast.js.map +0 -1
- package/dist/components/ui/index.d.ts +0 -46
- package/dist/components/ui/index.d.ts.map +0 -1
- package/dist/components/ui/index.js +0 -24
- package/dist/components/ui/index.js.map +0 -1
- package/dist/hooks/useContentLock.d.ts +0 -12
- package/dist/hooks/useContentLock.d.ts.map +0 -1
- package/dist/hooks/useContentLock.js +0 -38
- package/dist/hooks/useContentLock.js.map +0 -1
- package/dist/hooks/useDebounce.d.ts +0 -2
- package/dist/hooks/useDebounce.d.ts.map +0 -1
- package/dist/hooks/useDebounce.js +0 -11
- package/dist/hooks/useDebounce.js.map +0 -1
- package/src/components/ContentOverviewChart.tsx +0 -75
- package/src/components/SEOPerformance.tsx +0 -163
- package/src/components/ui/Avatar.tsx +0 -42
- package/src/components/ui/CommandPalette.tsx +0 -133
- package/src/components/ui/DataTable.tsx +0 -204
- package/src/components/ui/Pagination.tsx +0 -94
- package/src/components/ui/Select.tsx +0 -53
- package/src/components/ui/Toast.tsx +0 -72
- package/src/components/ui/index.ts +0 -61
- package/src/hooks/useContentLock.ts +0 -55
- package/src/hooks/useDebounce.ts +0 -14
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { cv, type VariantProps } from '../../lib/cv.js'
|
|
1
|
+
import { cv } from '../../lib/cv.js'
|
|
3
2
|
import { formControlBase, formControlState } from './form-control.js'
|
|
4
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Input class-variance recipe shared by the header search and `SearchInput`.
|
|
6
|
+
* Consumers render their own `<input>` with `inputVariants({ size, state })`;
|
|
7
|
+
* there is no wrapper component.
|
|
8
|
+
*/
|
|
5
9
|
const input = cv(formControlBase, {
|
|
6
10
|
variants: {
|
|
7
11
|
size: {
|
|
@@ -18,16 +22,4 @@ const input = cv(formControlBase, {
|
|
|
18
22
|
defaultVariants: { size: 'md', state: 'default' },
|
|
19
23
|
})
|
|
20
24
|
|
|
21
|
-
export
|
|
22
|
-
|
|
23
|
-
export interface InputProps
|
|
24
|
-
extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'>, InputVariants {}
|
|
25
|
-
|
|
26
|
-
export const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
|
|
27
|
-
{ size, state, className, ...rest },
|
|
28
|
-
ref,
|
|
29
|
-
) {
|
|
30
|
-
return <input ref={ref} className={input({ size, state, class: className })} {...rest} />
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
export { input as inputVariants, formControlBase, formControlState }
|
|
25
|
+
export { input as inputVariants }
|
|
@@ -12,7 +12,7 @@ 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
|
-
|
|
15
|
+
type ModalSize = keyof typeof MODAL_SIZE_CLASS
|
|
16
16
|
|
|
17
17
|
export interface ModalProps {
|
|
18
18
|
open: boolean
|
|
@@ -17,11 +17,11 @@ import { Maximize2, Minimize2 } from 'lucide-react'
|
|
|
17
17
|
export const SECTION_INSPECTOR_WIDTH_KEY = 'prenta:section-inspector-width'
|
|
18
18
|
export const SECTION_INSPECTOR_DEFAULT_WIDTH = 320
|
|
19
19
|
export const SECTION_INSPECTOR_MIN_WIDTH = 280
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
const SECTION_INSPECTOR_MAX_WIDTH = 640
|
|
21
|
+
const SECTION_INSPECTOR_MIN_CANVAS_WIDTH = 96
|
|
22
22
|
/** Below this editor-row width the expand action uses an overlay panel. */
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
const SECTION_INSPECTOR_OVERLAY_BREAKPOINT = 768
|
|
24
|
+
const SECTION_INSPECTOR_OVERLAY_MAX_WIDTH = 480
|
|
25
25
|
|
|
26
26
|
function clampWidth(width: number, max = SECTION_INSPECTOR_MAX_WIDTH): number {
|
|
27
27
|
return Math.min(max, Math.max(SECTION_INSPECTOR_MIN_WIDTH, width))
|
|
@@ -81,7 +81,7 @@ interface InspectorResizeContextValue {
|
|
|
81
81
|
|
|
82
82
|
const InspectorResizeContext = createContext<InspectorResizeContextValue | null>(null)
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
function useInspectorResize(): InspectorResizeContextValue | null {
|
|
85
85
|
return useContext(InspectorResizeContext)
|
|
86
86
|
}
|
|
87
87
|
|
|
@@ -40,7 +40,7 @@ const DOT_CLASS: Record<NonNullable<StatusBadgeVariants['tone']>, string> = {
|
|
|
40
40
|
muted: 'bg-[var(--muted)]',
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
type StatusBadgeVariants = VariantProps<typeof statusBadge>
|
|
44
44
|
export type StatusBadgeTone = NonNullable<StatusBadgeVariants['tone']>
|
|
45
45
|
|
|
46
46
|
export interface StatusBadgeProps extends HTMLAttributes<HTMLSpanElement>, StatusBadgeVariants {
|
|
@@ -62,5 +62,3 @@ export function StatusBadge({ tone, dot = true, className, children, ...rest }:
|
|
|
62
62
|
</span>
|
|
63
63
|
)
|
|
64
64
|
}
|
|
65
|
-
|
|
66
|
-
export { statusBadge as statusBadgeVariants }
|
|
@@ -40,7 +40,7 @@ const toggleThumb = cv(
|
|
|
40
40
|
},
|
|
41
41
|
)
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
type ToggleVariants = VariantProps<typeof toggleTrack>
|
|
44
44
|
|
|
45
45
|
export interface ToggleProps extends ToggleVariants {
|
|
46
46
|
checked: boolean
|
|
@@ -82,5 +82,3 @@ export function Toggle({
|
|
|
82
82
|
</Switch.Root>
|
|
83
83
|
)
|
|
84
84
|
}
|
|
85
|
-
|
|
86
|
-
export { toggleTrack as toggleTrackVariants, toggleThumb as toggleThumbVariants }
|
|
@@ -15,7 +15,7 @@ import { NavBuilderField } from './NavBuilderField.js'
|
|
|
15
15
|
import { NumberField } from './NumberField.js'
|
|
16
16
|
import { ComponentBlockField } from './ComponentBlockField.js'
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
interface FieldDefinition {
|
|
19
19
|
name: string
|
|
20
20
|
type: string
|
|
21
21
|
label: string
|
package/src/fields/index.ts
CHANGED
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
export { FieldRenderer } from './FieldRenderer.js'
|
|
2
|
-
export type { FieldRendererProps, FieldDefinition } from './FieldRenderer.js'
|
|
3
|
-
export { TextField } from './TextField.js'
|
|
4
|
-
export { RichTextField } from './RichTextField.js'
|
|
5
|
-
export { SlugField } from './SlugField.js'
|
|
6
|
-
export { SelectField } from './SelectField.js'
|
|
7
|
-
export { MediaField } from './MediaField.js'
|
|
8
|
-
export { RelationshipField } from './RelationshipField.js'
|
|
9
|
-
export { DateField } from './DateField.js'
|
|
10
|
-
export { ToggleField } from './ToggleField.js'
|
|
11
|
-
export { ArrayField } from './ArrayField.js'
|
|
12
|
-
export { BlockBuilderField } from './BlockBuilderField.js'
|
|
13
|
-
export { PRESET_BLOCKS } from './block-types.js'
|
|
14
|
-
export type { BlockTypeDefinition } from './block-types.js'
|
|
15
|
-
export { GroupField } from './GroupField.js'
|
|
16
|
-
export { NavBuilderField } from './NavBuilderField.js'
|
|
17
|
-
export { NumberField } from './NumberField.js'
|
|
18
1
|
export { ComponentBlockField } from './ComponentBlockField.js'
|
|
19
2
|
export type { ComponentBlockFieldProps, ComponentBlockValue } from './ComponentBlockField.js'
|
|
20
3
|
export { PropInput, defaultForType } from './PropInput.js'
|
|
@@ -74,10 +74,3 @@ export const tokens = {
|
|
|
74
74
|
'2xl': 1536,
|
|
75
75
|
} as const,
|
|
76
76
|
}
|
|
77
|
-
|
|
78
|
-
/** Map a space token to the corresponding Tailwind `space-y-*` / `gap-*` value. */
|
|
79
|
-
export function spaceToTw(t: SpaceToken): string {
|
|
80
|
-
// Tailwind's spacing utility already accepts the same scale, so we map
|
|
81
|
-
// 1:1. Centralizing here means callers don't repeat the string literal.
|
|
82
|
-
return t
|
|
83
|
-
}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import type { BrandAlignmentScoreResult } from '@prenta/core/brand-voice'
|
|
2
2
|
import { cmsApi } from './api.js'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Present only when an AI rewrite was wanted (`useAi`, remaining issues) but
|
|
6
|
+
* the governed runtime refused — `code` is the runtime refusal code and `hint`
|
|
7
|
+
* the operator-facing next step for the 503 "not configured" cases.
|
|
8
|
+
*/
|
|
9
|
+
interface BrandVoiceFixAiUnavailable {
|
|
10
|
+
code: string
|
|
11
|
+
message: string
|
|
12
|
+
hint?: string
|
|
13
|
+
}
|
|
5
14
|
|
|
6
15
|
export interface BrandVoiceFixResult {
|
|
7
16
|
text: string
|
|
@@ -9,6 +18,14 @@ export interface BrandVoiceFixResult {
|
|
|
9
18
|
beforeScore: BrandAlignmentScoreResult
|
|
10
19
|
afterScore: BrandAlignmentScoreResult
|
|
11
20
|
usedAi: boolean
|
|
21
|
+
aiUnavailable?: BrandVoiceFixAiUnavailable
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Toast copy for a fix that fell back to rule-only edits because AI refused. */
|
|
25
|
+
export function brandVoiceFixAiNotice(result: BrandVoiceFixResult): string | null {
|
|
26
|
+
if (result.usedAi || !result.aiUnavailable) return null
|
|
27
|
+
const { message, hint } = result.aiUnavailable
|
|
28
|
+
return hint ? `${message} ${hint}` : message
|
|
12
29
|
}
|
|
13
30
|
|
|
14
31
|
export async function fixBrandVoiceContent(input: {
|
|
@@ -19,7 +19,7 @@ interface CollectionLike {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/** Look up a collection by slug; `collections` may be a record or an array. */
|
|
22
|
-
|
|
22
|
+
function findCollection(config: unknown, slug: string): CollectionLike | null {
|
|
23
23
|
const collections = (config as { collections?: unknown } | null | undefined)?.collections
|
|
24
24
|
if (!collections) return null
|
|
25
25
|
if (Array.isArray(collections)) {
|
|
@@ -32,7 +32,7 @@ export function findCollection(config: unknown, slug: string): CollectionLike |
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
/** Field definitions may be a record (keyed by name) or an array of `{ name }`. */
|
|
35
|
-
|
|
35
|
+
function declaredFieldNames(fields: unknown): Set<string> | null {
|
|
36
36
|
if (!fields) return null
|
|
37
37
|
if (Array.isArray(fields)) {
|
|
38
38
|
return new Set(
|
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
isSectionEffectivelyVisible,
|
|
4
4
|
type PageSection,
|
|
5
5
|
} from '@prenta/core/page-sections'
|
|
6
|
-
import { analyzeContent } from '@prenta/core/seo/analysis'
|
|
7
6
|
|
|
8
7
|
const HTML_LIKE = /<\/?[a-z][\s\S]*>/i
|
|
9
8
|
|
|
@@ -19,27 +18,6 @@ export function buildEditorContentHtml(sections: PageSection[], body = ''): stri
|
|
|
19
18
|
return parts.join('\n')
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
/** Live 0–100 SEO score from the current in-editor document state. */
|
|
23
|
-
export function computeLiveSeoScore(input: {
|
|
24
|
-
title: string
|
|
25
|
-
slug: string
|
|
26
|
-
seoTitle: string
|
|
27
|
-
seoDescription: string
|
|
28
|
-
focusKeyword?: string
|
|
29
|
-
sections: PageSection[]
|
|
30
|
-
bodyHtml?: string
|
|
31
|
-
}): number {
|
|
32
|
-
const content = buildEditorContentHtml(input.sections, input.bodyHtml ?? '')
|
|
33
|
-
return analyzeContent({
|
|
34
|
-
title: input.title,
|
|
35
|
-
slug: input.slug,
|
|
36
|
-
content,
|
|
37
|
-
metaTitle: input.seoTitle,
|
|
38
|
-
metaDescription: input.seoDescription,
|
|
39
|
-
focusKeyphrase: input.focusKeyword,
|
|
40
|
-
}).score
|
|
41
|
-
}
|
|
42
|
-
|
|
43
21
|
function extractSectionContentHtml(section: PageSection): string {
|
|
44
22
|
const content = section.content
|
|
45
23
|
if (!content || typeof content !== 'object') return ''
|
package/src/lib/forms-service.ts
CHANGED
|
@@ -34,21 +34,16 @@ export type {
|
|
|
34
34
|
FormSchemaVersion,
|
|
35
35
|
FormField,
|
|
36
36
|
FormFieldType,
|
|
37
|
-
FormFieldOption,
|
|
38
|
-
FieldValidationRules,
|
|
39
37
|
FormAnalyticsConfig,
|
|
40
38
|
FormNotificationSettings,
|
|
41
39
|
FormEmbedSettings,
|
|
42
40
|
FormWebhookConfig,
|
|
43
|
-
FormWebhookEvent,
|
|
44
41
|
FormStatus,
|
|
45
42
|
FormStats,
|
|
46
43
|
FormsSidebarCount,
|
|
47
44
|
FormSubmission,
|
|
48
|
-
FormSubmissionFile,
|
|
49
45
|
FetchFormEntriesParams,
|
|
50
46
|
EntryCounts,
|
|
51
|
-
SpamStatus,
|
|
52
47
|
} from '@prenta/core'
|
|
53
48
|
|
|
54
49
|
/**
|
|
@@ -170,34 +165,6 @@ export async function updateForm(
|
|
|
170
165
|
return { data: res.data, error: res.error }
|
|
171
166
|
}
|
|
172
167
|
|
|
173
|
-
export async function duplicateForm(
|
|
174
|
-
id: string,
|
|
175
|
-
): Promise<{ data?: FormDefinition; error?: string }> {
|
|
176
|
-
const res = await cmsApi<FormDefinition>(`/forms/${encodeURIComponent(id)}/duplicate`, {
|
|
177
|
-
method: 'POST',
|
|
178
|
-
})
|
|
179
|
-
return { data: res.data, error: res.error }
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/** Move a form to the archived state (hidden from embed pickers, no new submissions). */
|
|
183
|
-
export async function archiveForm(id: string): Promise<{ error?: string }> {
|
|
184
|
-
return updateForm(id, { status: 'archived' })
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/** Restore an archived form back to draft. */
|
|
188
|
-
export async function restoreForm(id: string): Promise<{ error?: string }> {
|
|
189
|
-
return updateForm(id, { status: 'draft' })
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
export async function deleteForm(
|
|
193
|
-
id: string,
|
|
194
|
-
opts: { force?: boolean } = {},
|
|
195
|
-
): Promise<{ error?: string }> {
|
|
196
|
-
const qs = opts.force ? '?force=true' : ''
|
|
197
|
-
const res = await cmsApi(`/forms/${encodeURIComponent(id)}${qs}`, { method: 'DELETE' })
|
|
198
|
-
return { error: res.error }
|
|
199
|
-
}
|
|
200
|
-
|
|
201
168
|
// ─── Schema ──────────────────────────────────────────────────────────────
|
|
202
169
|
|
|
203
170
|
export async function fetchFormSchema(id: string): Promise<FormSchemaResult> {
|
|
@@ -496,8 +463,8 @@ export async function downloadEntriesExport(
|
|
|
496
463
|
|
|
497
464
|
// ─── Delivery attempts (#675) ─────────────────────────────────────────────
|
|
498
465
|
|
|
499
|
-
|
|
500
|
-
|
|
466
|
+
type FormDeliveryChannel = 'email_notify' | 'email_autoresponder' | 'form_webhook'
|
|
467
|
+
type FormDeliveryStatus = 'pending' | 'retrying' | 'success' | 'failed' | 'skipped'
|
|
501
468
|
|
|
502
469
|
export interface FormDeliveryAttempt {
|
|
503
470
|
id: string
|
|
@@ -560,10 +527,3 @@ export async function retryFormDelivery(
|
|
|
560
527
|
)
|
|
561
528
|
return { data: res.data, error: res.error }
|
|
562
529
|
}
|
|
563
|
-
|
|
564
|
-
export async function fetchFailedDeliveryCount(formId?: string): Promise<number> {
|
|
565
|
-
const qs = formId ? `?formId=${encodeURIComponent(formId)}` : ''
|
|
566
|
-
const res = await cmsApi<{ count: number }>(`/forms/deliveries/failed-count${qs}`)
|
|
567
|
-
throwIfError(res)
|
|
568
|
-
return res.data?.count ?? 0
|
|
569
|
-
}
|
|
@@ -15,21 +15,21 @@ import { cmsApi, getApiBase } from './api.js'
|
|
|
15
15
|
|
|
16
16
|
export type NotificationKind = 'comment_reply' | 'comment_resolved' | 'comment_mention'
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
interface CommentReplyPayload {
|
|
19
19
|
kind: 'comment_reply'
|
|
20
20
|
actorId: string | null
|
|
21
21
|
actorName: string | null
|
|
22
22
|
excerpt: string
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
interface CommentResolvedPayload {
|
|
26
26
|
kind: 'comment_resolved'
|
|
27
27
|
actorId: string | null
|
|
28
28
|
actorName: string | null
|
|
29
29
|
rootExcerpt: string
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
interface CommentMentionPayload {
|
|
33
33
|
kind: 'comment_mention'
|
|
34
34
|
actorId: string | null
|
|
35
35
|
actorName: string | null
|
|
@@ -78,7 +78,7 @@ function stripHtml(html: string): string {
|
|
|
78
78
|
* when one is set — otherwise `imageSlots` would count an empty media field
|
|
79
79
|
* and fail alt-text for an image that is not on the page.
|
|
80
80
|
*/
|
|
81
|
-
|
|
81
|
+
function withPostAuditSlots(sections: PageSection[], post?: PostAuditExtras): PageSection[] {
|
|
82
82
|
if (!post) return sections
|
|
83
83
|
|
|
84
84
|
const extras: PageSection[] = []
|
|
@@ -27,7 +27,6 @@ import {
|
|
|
27
27
|
moveSection,
|
|
28
28
|
reorderSections,
|
|
29
29
|
updateSectionContent,
|
|
30
|
-
updateSectionContentAtPath,
|
|
31
30
|
updateSectionSettings,
|
|
32
31
|
updateSectionMeta,
|
|
33
32
|
coerceSections as coerceSectionsCore,
|
|
@@ -55,7 +54,6 @@ export {
|
|
|
55
54
|
moveSection,
|
|
56
55
|
reorderSections,
|
|
57
56
|
updateSectionContent,
|
|
58
|
-
updateSectionContentAtPath,
|
|
59
57
|
updateSectionSettings,
|
|
60
58
|
updateSectionMeta,
|
|
61
59
|
}
|
|
@@ -278,7 +276,7 @@ function toWriteBody(page: EditorPage, extra?: Record<string, unknown>): string
|
|
|
278
276
|
}
|
|
279
277
|
|
|
280
278
|
/** Create a new page document, returning the new id. */
|
|
281
|
-
|
|
279
|
+
async function createPage(page: EditorPage): Promise<EditorPage> {
|
|
282
280
|
const res = await cmsApi<DocumentApiRow>(`/collections/${PAGES_COLLECTION}`, {
|
|
283
281
|
method: 'POST',
|
|
284
282
|
body: toWriteBody(page),
|
package/src/lib/pages-service.ts
CHANGED
|
@@ -30,8 +30,8 @@ import { cmsApi } from './api.js'
|
|
|
30
30
|
|
|
31
31
|
export type PageStatus = 'DRAFT' | 'PUBLISHED' | 'SCHEDULED' | 'ARCHIVED'
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
const PAGES_COLLECTION = 'pages'
|
|
34
|
+
const PAGE_TAGS_COLLECTION = 'page-tags'
|
|
35
35
|
|
|
36
36
|
export interface PageTag {
|
|
37
37
|
id: string // == slug (stable join key; pages store slugs in data.tags)
|
|
@@ -47,7 +47,7 @@ export interface PageTag {
|
|
|
47
47
|
updatedAt: string | null
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
interface PageAuthor {
|
|
51
51
|
id: string
|
|
52
52
|
name: string
|
|
53
53
|
initials: string
|
|
@@ -222,22 +222,6 @@ async function fetchTagDocs(): Promise<DocumentApiRow[]> {
|
|
|
222
222
|
return (res.data?.docs ?? []) as DocumentApiRow[]
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
/**
|
|
226
|
-
* Fetch all tags. `pageCounts` (slug → count) is optional so the tag
|
|
227
|
-
* manager / pickers can render before page data is loaded.
|
|
228
|
-
*/
|
|
229
|
-
export async function fetchPageTags(pageCounts?: Map<string, number>): Promise<PageTag[]> {
|
|
230
|
-
const docs = await fetchTagDocs()
|
|
231
|
-
const tags = docs.map((d) => docToTag(d, pageCounts?.get(d.slug ?? d.id) ?? 0))
|
|
232
|
-
tags.sort((a, b) => a.sortOrder - b.sortOrder || a.name.localeCompare(b.name))
|
|
233
|
-
return tags
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
export async function fetchAuthors(): Promise<PageAuthor[]> {
|
|
237
|
-
const map = await fetchAuthorsMap()
|
|
238
|
-
return [...map.values()].sort((a, b) => a.name.localeCompare(b.name))
|
|
239
|
-
}
|
|
240
|
-
|
|
241
225
|
// ─── Pages ───────────────────────────────────────────────────────────
|
|
242
226
|
|
|
243
227
|
function docToPage(d: DocumentApiRow, authors: Map<string, PageAuthor>): Page {
|
|
@@ -439,15 +423,6 @@ export async function fetchPages(query: PagesQuery = {}): Promise<PagesResult> {
|
|
|
439
423
|
}
|
|
440
424
|
}
|
|
441
425
|
|
|
442
|
-
export async function fetchPageById(pageId: string): Promise<Page | null> {
|
|
443
|
-
const res = await cmsApi<DocumentApiRow>(
|
|
444
|
-
`/collections/${PAGES_COLLECTION}/${encodeURIComponent(pageId)}`,
|
|
445
|
-
)
|
|
446
|
-
if (res.error || !res.data) return null
|
|
447
|
-
const authors = await fetchAuthorsMap()
|
|
448
|
-
return docToPage(res.data, authors)
|
|
449
|
-
}
|
|
450
|
-
|
|
451
426
|
// ─── Bulk page mutations ─────────────────────────────────────────────
|
|
452
427
|
|
|
453
428
|
export interface BulkResult {
|
|
@@ -621,7 +596,7 @@ export async function updatePageTag(
|
|
|
621
596
|
return res.error ? { error: res.error } : {}
|
|
622
597
|
}
|
|
623
598
|
|
|
624
|
-
|
|
599
|
+
async function deletePageTag(tagDocId: string): Promise<{ error?: string }> {
|
|
625
600
|
const res = await cmsApi(`/collections/${PAGE_TAGS_COLLECTION}/${encodeURIComponent(tagDocId)}`, {
|
|
626
601
|
method: 'DELETE',
|
|
627
602
|
})
|
package/src/lib/plan.ts
CHANGED
|
@@ -30,10 +30,8 @@ import {
|
|
|
30
30
|
removeSection,
|
|
31
31
|
duplicateSection,
|
|
32
32
|
toggleSectionVisibility,
|
|
33
|
-
moveSection,
|
|
34
33
|
reorderSections,
|
|
35
34
|
updateSectionContent,
|
|
36
|
-
updateSectionContentAtPath,
|
|
37
35
|
updateSectionSettings,
|
|
38
36
|
updateSectionMeta,
|
|
39
37
|
coerceSections,
|
|
@@ -56,17 +54,13 @@ export {
|
|
|
56
54
|
removeSection,
|
|
57
55
|
duplicateSection,
|
|
58
56
|
toggleSectionVisibility,
|
|
59
|
-
moveSection,
|
|
60
57
|
reorderSections,
|
|
61
58
|
updateSectionContent,
|
|
62
|
-
updateSectionContentAtPath,
|
|
63
59
|
updateSectionSettings,
|
|
64
60
|
updateSectionMeta,
|
|
65
61
|
}
|
|
66
62
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
export const TEMPLATES_COLLECTION = 'post-templates'
|
|
63
|
+
type PostStatus = 'DRAFT' | 'PUBLISHED' | 'SCHEDULED' | 'ARCHIVED'
|
|
70
64
|
|
|
71
65
|
export interface EditorPost {
|
|
72
66
|
id: string | null
|
|
@@ -230,7 +224,7 @@ export interface FeaturedImageRef {
|
|
|
230
224
|
}
|
|
231
225
|
|
|
232
226
|
/** True for paths and http(s) URLs — never a bare media cuid. */
|
|
233
|
-
|
|
227
|
+
function isDisplayableImageSrc(value: string): boolean {
|
|
234
228
|
const v = value.trim()
|
|
235
229
|
return v.startsWith('/') || /^https?:\/\//i.test(v)
|
|
236
230
|
}
|
|
@@ -272,7 +266,7 @@ export function parseFeaturedImage(raw: unknown): string {
|
|
|
272
266
|
* `[{ tag: 'AI' }]` rows; older/hand-rolled configs may store `['AI']`
|
|
273
267
|
* directly — accept both so no site loses tags in the editor.
|
|
274
268
|
*/
|
|
275
|
-
|
|
269
|
+
function parseTags(raw: unknown): string[] {
|
|
276
270
|
if (!Array.isArray(raw)) return []
|
|
277
271
|
const out: string[] = []
|
|
278
272
|
for (const item of raw) {
|
|
@@ -435,7 +429,7 @@ function toWriteBody(post: EditorPost, extra?: Record<string, unknown>): string
|
|
|
435
429
|
return JSON.stringify(payload)
|
|
436
430
|
}
|
|
437
431
|
|
|
438
|
-
|
|
432
|
+
async function createPost(post: EditorPost): Promise<EditorPost> {
|
|
439
433
|
const res = await cmsApi<DocumentApiRow>(`/collections/${encodeURIComponent(post.postType)}`, {
|
|
440
434
|
method: 'POST',
|
|
441
435
|
body: toWriteBody(post),
|
|
@@ -6,7 +6,7 @@ import { cmsApi } from './api.js'
|
|
|
6
6
|
* schemas are file-defined in `prenta.config.ts`, so the Post Type editor
|
|
7
7
|
* inspects the live schema and generates config snippets for changes.
|
|
8
8
|
*/
|
|
9
|
-
|
|
9
|
+
interface PostTypeFieldSummary {
|
|
10
10
|
name: string
|
|
11
11
|
type: string
|
|
12
12
|
required: boolean
|
|
@@ -57,7 +57,7 @@ export async function fetchPostTypeDetail(slug: string): Promise<PostTypeDetail
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
/** Friendly display names for cms-core field types (design's type badges). */
|
|
60
|
-
|
|
60
|
+
const FIELD_TYPE_LABELS: Record<string, string> = {
|
|
61
61
|
text: 'Short Text',
|
|
62
62
|
richText: 'Rich Text',
|
|
63
63
|
number: 'Number',
|
package/src/lib/posts-service.ts
CHANGED
package/src/lib/preview-link.ts
CHANGED
|
@@ -101,20 +101,6 @@ export function buildPublicUrl({
|
|
|
101
101
|
return resolveDocumentUrl({ siteUrl, urlPrefix, slug, path, data, trailingSlash })
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
/**
|
|
105
|
-
* Resolve the public site origin for link building.
|
|
106
|
-
*
|
|
107
|
-
* Prefer an explicit URL (effective public apex from `/site/public-url` or
|
|
108
|
-
* `config.seo.siteUrl`). Falling back to `window.location.origin` is a last
|
|
109
|
-
* resort — on Astro-split installs the admin tab is the Next CMS host, so that
|
|
110
|
-
* fallback opens the wrong site. Callers should prefer {@link usePublicSiteUrl}.
|
|
111
|
-
*/
|
|
112
|
-
export function resolveSiteUrl(configSiteUrl?: string | null): string {
|
|
113
|
-
if (configSiteUrl && configSiteUrl.trim()) return configSiteUrl.trim().replace(/\/+$/, '')
|
|
114
|
-
if (typeof window !== 'undefined') return window.location.origin
|
|
115
|
-
return ''
|
|
116
|
-
}
|
|
117
|
-
|
|
118
104
|
/** True when `siteUrl` shares an origin with the admin tab (split-deploy smell). */
|
|
119
105
|
export function siteUrlMatchesAdminOrigin(
|
|
120
106
|
siteUrl: string | null | undefined,
|
package/src/lib/rail-width.ts
CHANGED
|
@@ -10,7 +10,7 @@ export const RAIL_DEFAULT_WIDTH = 360
|
|
|
10
10
|
/** Width of the strip that replaces the rail when it is collapsed. */
|
|
11
11
|
export const RAIL_COLLAPSED_WIDTH = 38
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
const RAIL_WIDTH_STORAGE_KEY = 'pb.panelW'
|
|
14
14
|
|
|
15
15
|
/** Constrain a candidate width to the rail's range, rejecting junk. */
|
|
16
16
|
export function clampRailWidth(width: number): number {
|
package/src/lib/reflow-probe.ts
CHANGED
|
@@ -66,7 +66,7 @@ export function linesFromMetrics(height: number, lineHeight: number, fontSize: n
|
|
|
66
66
|
* whose content is a single replaced node, or a layout engine that gives no
|
|
67
67
|
* rects for empty text.
|
|
68
68
|
*/
|
|
69
|
-
|
|
69
|
+
function countLines(el: HTMLElement): number {
|
|
70
70
|
const doc = el.ownerDocument
|
|
71
71
|
try {
|
|
72
72
|
const range = doc.createRange()
|
|
@@ -106,7 +106,7 @@ export function countLines(el: HTMLElement): number {
|
|
|
106
106
|
*
|
|
107
107
|
* Use `mountProbeHost` rather than appending by hand.
|
|
108
108
|
*/
|
|
109
|
-
|
|
109
|
+
function createProbeHost(doc: Document = document): HTMLElement {
|
|
110
110
|
const host = doc.createElement('div')
|
|
111
111
|
host.setAttribute('aria-hidden', 'true')
|
|
112
112
|
host.dataset.reflowProbe = 'true'
|
|
@@ -128,7 +128,7 @@ export function createProbeHost(doc: Document = document): HTMLElement {
|
|
|
128
128
|
* root exists (it always does in the app) — and callers should treat a
|
|
129
129
|
* fallback mount as untrustworthy rather than silently measuring.
|
|
130
130
|
*/
|
|
131
|
-
|
|
131
|
+
function mountProbeHost(
|
|
132
132
|
host: HTMLElement,
|
|
133
133
|
doc: Document = document,
|
|
134
134
|
): { detach: () => void; scoped: boolean } {
|
|
@@ -156,7 +156,7 @@ export function mountProbeHost(
|
|
|
156
156
|
* Reporting a line count from the wrong element would be worse than reporting
|
|
157
157
|
* none: an editor reads a number as a fact.
|
|
158
158
|
*/
|
|
159
|
-
|
|
159
|
+
function measureFieldAcrossBreakpoints(
|
|
160
160
|
container: HTMLElement,
|
|
161
161
|
fieldPath: string,
|
|
162
162
|
scope?: string,
|