@elytracms/studio 0.0.39 → 0.0.41
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/dist/components/cms/collection-table.js +13 -1
- package/dist/components/cms/collection-table.js.map +1 -1
- package/dist/components/cms/detail-editor.js +116 -72
- package/dist/components/cms/detail-editor.js.map +1 -1
- package/dist/components/cms/details-pane.d.ts +21 -8
- package/dist/components/cms/details-pane.js +31 -11
- package/dist/components/cms/details-pane.js.map +1 -1
- package/dist/components/cms/field-control.js +21 -12
- package/dist/components/cms/field-control.js.map +1 -1
- package/dist/components/cms/prop-fields.js +25 -1
- package/dist/components/cms/prop-fields.js.map +1 -1
- package/dist/components/cms/rich-text/component-embed.d.ts +7 -2
- package/dist/components/cms/rich-text/component-embed.js +60 -5
- package/dist/components/cms/rich-text/component-embed.js.map +1 -1
- package/dist/components/cms/rich-text/editor.js +24 -5
- package/dist/components/cms/rich-text/editor.js.map +1 -1
- package/dist/components/cms/rich-text/embed-inspector-context.d.ts +50 -0
- package/dist/components/cms/rich-text/embed-inspector-context.js +12 -0
- package/dist/components/cms/rich-text/embed-inspector-context.js.map +1 -0
- package/dist/components/cms/rich-text/embed-inspector.d.ts +25 -0
- package/dist/components/cms/rich-text/embed-inspector.js +48 -0
- package/dist/components/cms/rich-text/embed-inspector.js.map +1 -0
- package/dist/components/cms/rich-text/embed-picker.d.ts +0 -2
- package/dist/components/cms/rich-text/embed-picker.js +0 -4
- package/dist/components/cms/rich-text/embed-picker.js.map +1 -1
- package/dist/components/cms/rich-text/embed-props.d.ts +7 -0
- package/dist/components/cms/rich-text/embed-props.js +9 -0
- package/dist/components/cms/rich-text/embed-props.js.map +1 -1
- package/dist/components/cms/rich-text/insert.d.ts +8 -2
- package/dist/components/cms/rich-text/insert.js +32 -3
- package/dist/components/cms/rich-text/insert.js.map +1 -1
- package/dist/components/cms/rich-text/link-control.js +3 -1
- package/dist/components/cms/rich-text/link-control.js.map +1 -1
- package/dist/components/cms/rich-text/slash-command.d.ts +23 -6
- package/dist/components/cms/rich-text/slash-command.js +31 -23
- package/dist/components/cms/rich-text/slash-command.js.map +1 -1
- package/dist/components/cms/rich-text/toolbar-state.d.ts +45 -0
- package/dist/components/cms/rich-text/toolbar-state.js +66 -0
- package/dist/components/cms/rich-text/toolbar-state.js.map +1 -0
- package/dist/components/cms/rich-text/toolbar.js +7 -15
- package/dist/components/cms/rich-text/toolbar.js.map +1 -1
- package/dist/components/cms/version-compare.js +51 -22
- package/dist/components/cms/version-compare.js.map +1 -1
- package/dist/components/components/component-preview.d.ts +36 -0
- package/dist/components/components/component-preview.js +157 -5
- package/dist/components/components/component-preview.js.map +1 -1
- package/dist/lib/i18n/messages.en.js +18 -3
- package/dist/lib/i18n/messages.en.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version-compare.js","sourceRoot":"","sources":["../../../src/components/cms/version-compare.tsx"],"names":[],"mappings":"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","sourcesContent":["import { createContext, useCallback, useContext, useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { ArrowRight, ChevronDown, ChevronLeft, ChevronRight, Image as ImageIcon, RotateCcw } from 'lucide-react'\nimport { diffDocuments } from '@elytracms/core/content'\nimport type { BlockChange, ChangeKind, FieldChange, PropChange } from '@elytracms/core/content'\nimport { isAssetNode, readAssetId, readDocumentRef } from '@elytracms/core/cms-core'\nimport type { CmsDocument, FieldDef, RestoreScope } from '@elytracms/core/cms-core'\nimport {\n Badge,\n Button,\n Code,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n Row,\n Spacer,\n Stack,\n Text,\n} from '@elytracms/studio/ui'\nimport { useOperationCache } from '@elytracms/studio/lib/query'\nimport { translate } from '@elytracms/studio/lib/i18n'\nimport { localeChipLabel } from '@elytracms/studio/lib/locale'\nimport { cn } from '@elytracms/studio/lib/utils'\nimport { readDiffViewMode, storeDiffViewMode } from '@elytracms/studio/lib/diff-view-preference'\nimport type { DiffViewMode } from '@elytracms/studio/lib/diff-view-preference'\nimport { useCollectionView } from '../collection-view/collection-view-context'\nimport { fieldLabel } from './cms-store'\nimport { toRefArray } from './cell'\nimport {\n DIFF_TRUNCATE_THRESHOLD,\n mergeWordDiff,\n richTextToText,\n truncateText,\n truncateTokens,\n wordDiff,\n} from './version-compare-text'\nimport type { MergedDiffToken, WordToken } from './version-compare-text'\nimport { useDocumentEditor } from './document-editor-context'\nimport { useDocumentVersionsQuery } from './use-document-versions'\nimport { formatVersionTimestamp } from './versions-model'\n\n/**\n * EC-298 — the version compare view. Renders as the sticky **Compare** content tab\n * (the Versions sidebar pane stays on as the navigator).\n *\n * A calm change-list grouped BY FIELD (a localized field's per-locale variants sit\n * together): a left **descriptor lane** (EC-317 — field label + locale) identifies\n * each row, next to its before | after value (or one merged **unified** lane —\n * a persisted transient view preference, EC-317). Text reads as a prose diff\n * (changed words lit in place — rich text via its markdown projection); assets as\n * thumbnails; relations as titles. A value past a length threshold collapses\n * behind a per-row \"Show more\" (+ a global \"Expand/Collapse all\") — presentation\n * only, the semantic/identity diff underneath (EC-298) is never touched. Rows\n * zebra-stripe for scanability. Each field/locale (and each block, at property\n * level) restores back to the base version with a single ↩.\n */\nexport function VersionCompare() {\n const source = useCollectionView()\n const {\n collection,\n docRef,\n draft,\n dirty,\n viewReadOnly,\n save,\n replaceDraft,\n compare,\n setCompareBase,\n setCompareTarget,\n } = useDocumentEditor()\n const { versionsQuery, versionKey } = useDocumentVersionsQuery(docRef)\n const cache = useOperationCache()\n const [busy, setBusy] = useState(false)\n\n // EC-317 — the unified/side-by-side toggle is a transient, personal-local view\n // preference (same class as the theme/rail prefs): read once at mount, written\n // back on every change, never round-tripped through the project graph.\n const [mode, setModeState] = useState<DiffViewMode>(() => readDiffViewMode())\n const setMode = useCallback((next: DiffViewMode) => {\n setModeState(next)\n storeDiffViewMode(next)\n }, [])\n\n // EC-317 — long-value truncation state: an `expandAll` flag plus per-row\n // overrides. Presentation-only (never recomputes the diff), reset is implicit\n // (in-session state, like the rest of the compare selection).\n const [expandAll, setExpandAll] = useState(false)\n const [expandedRows, setExpandedRows] = useState<ReadonlySet<string>>(() => new Set())\n const toggleExpand = useCallback((id: string) => {\n setExpandedRows((prev) => {\n const next = new Set(prev)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n return next\n })\n }, [])\n const isExpanded = useCallback((id: string) => expandAll || expandedRows.has(id), [expandAll, expandedRows])\n const toggleExpandAll = useCallback(() => {\n setExpandAll((prev) => {\n const next = !prev\n // Collapsing all clears per-row overrides too, so \"Collapse all\" always\n // means \"everything is collapsed\" rather than \"back to before I expanded\".\n if (!next) setExpandedRows(new Set())\n return next\n })\n }, [])\n const diffDisplay = useMemo<DiffDisplayState>(\n () => ({ mode, expandAll, isExpanded, toggleExpand }),\n [mode, expandAll, isExpanded, toggleExpand],\n )\n\n const view = versionsQuery.data ?? null\n const versions = useMemo(() => view?.versions ?? [], [view])\n\n const baseRecord = compare ? versions.find((v) => v.version === compare.base) : undefined\n const targetSnapshot: CmsDocument | undefined =\n compare?.target === 'draft' ? draft : versions.find((v) => v.version === compare?.target)?.snapshot\n\n const diff = useMemo(\n () =>\n baseRecord && targetSnapshot\n ? diffDocuments(collection, baseRecord.snapshot, targetSnapshot)\n : { changes: [], unchangedCount: 0 },\n [collection, baseRecord, targetSnapshot],\n )\n\n const fieldOrder = useMemo(() => new Map(collection.fields.map((f, i) => [f.name, i])), [collection])\n const fieldByName = useMemo(() => new Map(collection.fields.map((f) => [f.name, f])), [collection])\n const localeRank = useMemo(() => new Map(source.localeConfig.locales.map((l, i) => [l, i])), [source.localeConfig])\n const groups = useMemo(\n () => groupByField(diff.changes, fieldOrder, localeRank),\n [diff.changes, fieldOrder, localeRank],\n )\n // EC-317 zebra striping: a running index across every rendered row (not reset\n // per field group), so consecutive groups keep alternating rather than each\n // restarting on the same shade.\n const groupRows = useMemo(() => {\n let rowIndex = 0\n return groups.map((group) => {\n const zebraStart = rowIndex\n rowIndex += group.entries.length\n return { group, field: fieldByName.get(group.field), zebraStart }\n })\n }, [groups, fieldByName])\n\n const restore = useCallback(\n async (scope: RestoreScope) => {\n if (!compare) return\n setBusy(true)\n try {\n if (dirty) save()\n const restored = await source.versioning?.restore(docRef, compare.base, scope)\n if (restored) replaceDraft(restored)\n await cache.invalidate(versionKey)\n } finally {\n setBusy(false)\n }\n },\n [compare, dirty, save, source, docRef, replaceDraft, cache, versionKey],\n )\n\n if (!compare) return null\n if (view === null) return <CompareNotice>{translate('cms.version.loadingHistory')}</CompareNotice>\n if (!baseRecord || !targetSnapshot)\n return <CompareNotice>{translate('cms.version.versionUnavailable')}</CompareNotice>\n\n const canRestore = compare.target === 'draft' && !viewReadOnly\n const targetLabel = compare.target === 'draft' ? translate('cms.version.currentDraft') : `v${compare.target}`\n\n // Step the base through history, skipping the target so the sides never collapse.\n const baseIndex = versions.findIndex((v) => v.version === compare.base)\n const nextBaseFor = (dir: -1 | 1): number | undefined => {\n let i = baseIndex + dir\n while (i >= 0 && i < versions.length && versions[i]!.version === compare.target) i += dir\n return i >= 0 && i < versions.length ? versions[i]!.version : undefined\n }\n const newerBase = nextBaseFor(-1) // versions are newest-first\n const olderBase = nextBaseFor(1)\n\n const baseOptions = versions\n .filter((v) => v.version !== compare.target)\n .map((v) => ({ value: v.version, label: `v${v.version}`, meta: formatVersionTimestamp(v.createdAt) }))\n const targetOptions = [\n {\n value: 'draft' as const,\n label: translate('cms.version.currentDraft'),\n meta: dirty ? translate('cms.version.unsavedEdits') : undefined,\n },\n ...versions\n .filter((v) => v.version !== compare.base)\n .map((v) => ({ value: v.version, label: `v${v.version}`, meta: formatVersionTimestamp(v.createdAt) })),\n ]\n\n return (\n <Stack gap=\"3\" className=\"mx-auto w-full max-w-5xl p-4 sm:p-6\">\n {/* The two sides — both re-pickable, so any pair can be compared; the\n Versions pane also sets the base on click. Stepper walks the base. */}\n <Row gap=\"2\" align=\"center\" wrap className=\"rounded-md border border-border/70 bg-muted/30 px-3 py-2\">\n <VersionMenu\n caption={translate('cms.version.baseCaption')}\n current={`v${compare.base}`}\n meta={formatVersionTimestamp(baseRecord.createdAt)}\n options={baseOptions}\n onSelect={(v) => setCompareBase(v as number)}\n />\n <ArrowRight className=\"size-4 shrink-0 text-muted-foreground\" aria-hidden />\n <VersionMenu\n caption={translate('cms.version.compareWithCaption')}\n current={targetLabel}\n options={targetOptions}\n onSelect={(v) => setCompareTarget(v as number | 'draft')}\n />\n <Spacer />\n <Row gap=\"1\">\n <Button\n variant=\"outline\"\n size=\"icon-sm\"\n onClick={() => newerBase !== undefined && setCompareBase(newerBase)}\n disabled={newerBase === undefined}\n title={translate('cms.version.compareNewer')}\n aria-label={translate('cms.version.compareNewer')}\n >\n <ChevronLeft />\n </Button>\n <Button\n variant=\"outline\"\n size=\"icon-sm\"\n onClick={() => olderBase !== undefined && setCompareBase(olderBase)}\n disabled={olderBase === undefined}\n title={translate('cms.version.compareOlder')}\n aria-label={translate('cms.version.compareOlder')}\n >\n <ChevronRight />\n </Button>\n </Row>\n {canRestore ? (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => void restore({ kind: 'all' })}\n disabled={busy || diff.changes.length === 0}\n title={translate('cms.version.restoreWholeTitle', { version: compare.base })}\n >\n <RotateCcw /> {translate('cms.version.restoreVersion')}\n </Button>\n ) : null}\n </Row>\n\n {/* EC-317 — the diff-layout toolbar: unified/side-by-side (persisted) + expand-all.\n Only meaningful once there is a diff to lay out, so it's gated the same\n as the change-list below. */}\n {diff.changes.length > 0 ? (\n <Row gap=\"2\" align=\"center\" justify=\"between\" wrap className=\"px-0.5\">\n <DiffViewToggle mode={mode} onChange={setMode} />\n <Button variant=\"ghost\" size=\"sm\" onClick={toggleExpandAll}>\n {translate(expandAll ? 'cms.field.collapseAll' : 'cms.field.expandAll')}\n </Button>\n </Row>\n ) : null}\n\n <Text size=\"xs\" tone=\"muted\" className=\"px-0.5\">\n {diff.changes.length === 0\n ? translate('cms.version.noDifferences')\n : translate(diff.changes.length === 1 ? 'cms.version.changeSummary.one' : 'cms.version.changeSummary.other', {\n count: diff.changes.length,\n unchanged: diff.unchangedCount,\n })}\n {!canRestore && diff.changes.length > 0 ? translate('cms.version.comparingPastVersionsHint') : ''}\n </Text>\n\n {diff.changes.length === 0 ? (\n <CompareNotice>{translate('cms.version.versionsIdentical')}</CompareNotice>\n ) : (\n <DiffDisplayContext.Provider value={diffDisplay}>\n <div className=\"pb-1\">\n <div className={cn(DIFF_ROW_GRID, 'px-2 pb-1.5')}>\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {translate('cms.version.fieldColumnHeader')}\n </Text>\n {mode === 'unified' ? (\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {translate('cms.version.unifiedCaption', { base: compare.base, target: targetLabel })}\n </Text>\n ) : (\n <TwoCol\n before={\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {translate('cms.version.beforeVersion', { version: compare.base })}\n </Text>\n }\n after={\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {translate('cms.version.afterTarget', { target: targetLabel })}\n </Text>\n }\n />\n )}\n </div>\n {groupRows.map(({ group, field, zebraStart }) => (\n <FieldGroup\n key={group.field}\n group={group}\n field={field}\n zebraStart={zebraStart}\n canRestore={canRestore}\n busy={busy}\n onRestore={restore}\n />\n ))}\n </div>\n </DiffDisplayContext.Provider>\n )}\n </Stack>\n )\n}\n\n// --- EC-317 diff-display context (mode + truncation) ------------------------------\n\ninterface DiffDisplayState {\n mode: DiffViewMode\n expandAll: boolean\n isExpanded: (id: string) => boolean\n toggleExpand: (id: string) => void\n}\n\nconst DiffDisplayContext = createContext<DiffDisplayState | null>(null)\n\nfunction useDiffDisplay(): DiffDisplayState {\n const ctx = useContext(DiffDisplayContext)\n if (!ctx) throw new Error('useDiffDisplay must be rendered under the VersionCompare diff area')\n return ctx\n}\n\n/** Shared grid template so the descriptor lane + header captions line up. */\nconst DIFF_ROW_GRID = 'grid grid-cols-[7.5rem_1fr] items-start gap-x-4'\n\n/** A before | after grid; a divider sits at the midline (its own, scoped to this\n * instance — every row uses the same proportions, so they all line up). */\nfunction TwoCol({ before, after, className }: { before: ReactNode; after: ReactNode; className?: string }) {\n return (\n <div className={cn('relative grid grid-cols-2 gap-x-6', className)}>\n <div className=\"pointer-events-none absolute inset-y-0 left-1/2 w-px -translate-x-1/2 bg-border\" aria-hidden />\n <div className=\"min-w-0\">{before}</div>\n <div className=\"min-w-0\">{after}</div>\n </div>\n )\n}\n\n/**\n * Mode-aware value display (EC-317): side-by-side keeps the before | after\n * columns; unified stacks a single \"− before\" / \"+ after\" pair in one lane,\n * omitting whichever side doesn't exist (`added`/`removed` kind).\n */\nfunction DiffColumns({ before, after, kind }: { before: ReactNode; after: ReactNode; kind: ChangeKind }) {\n const { mode } = useDiffDisplay()\n if (mode === 'unified') {\n return (\n <Stack gap=\"1\">\n {kind !== 'added' ? <UnifiedLine tone=\"removed\">{before}</UnifiedLine> : null}\n {kind !== 'removed' ? <UnifiedLine tone=\"added\">{after}</UnifiedLine> : null}\n </Stack>\n )\n }\n return <TwoCol before={before} after={after} />\n}\n\nfunction UnifiedLine({ tone, children }: { tone: 'removed' | 'added'; children: ReactNode }) {\n return (\n <Row\n gap=\"2\"\n align=\"start\"\n className={cn('rounded-sm px-1.5 py-1', tone === 'removed' ? 'bg-destructive/10' : 'bg-success/10')}\n >\n <Text\n size=\"xs\"\n mono\n aria-hidden\n className={cn('mt-0.5 shrink-0 select-none', tone === 'removed' ? 'text-destructive' : 'text-success')}\n >\n {tone === 'removed' ? '−' : '+'}\n </Text>\n <div className=\"min-w-0 flex-1\">{children}</div>\n </Row>\n )\n}\n\n/** Wraps truncatable content with its per-row \"Show more\"/\"Show less\" control —\n * hidden while the global \"expand all\" is active (nothing left to toggle). */\nfunction ExpandToggle({\n id,\n isLong,\n expanded,\n children,\n}: {\n id: string\n isLong: boolean\n expanded: boolean\n children: ReactNode\n}) {\n const { expandAll, toggleExpand } = useDiffDisplay()\n return (\n <div>\n {children}\n {isLong && !expandAll ? (\n <Button variant=\"link\" size=\"sm\" className=\"h-auto p-0 text-xs\" onClick={() => toggleExpand(id)}>\n {expanded ? translate('cms.version.showLess') : translate('cms.version.showMore')}\n </Button>\n ) : null}\n </div>\n )\n}\n\nfunction VersionMenu({\n caption,\n current,\n meta,\n options,\n onSelect,\n}: {\n caption: string\n current: string\n meta?: string\n options: { value: number | 'draft'; label: string; meta?: string }[]\n onSelect: (value: number | 'draft') => void\n}) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"sm\" className=\"gap-1.5\">\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {caption}\n </Text>\n <Text size=\"sm\" weight=\"medium\" mono>\n {current}\n </Text>\n {meta ? (\n <Text size=\"xs\" tone=\"muted\" className=\"hidden sm:inline\">\n {meta}\n </Text>\n ) : null}\n <ChevronDown className=\"size-3.5 text-muted-foreground\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"max-h-72 overflow-auto\">\n {options.map((o) => (\n <DropdownMenuItem key={String(o.value)} onClick={() => onSelect(o.value)} className=\"gap-2\">\n <Text size=\"sm\" weight=\"medium\" mono={o.value !== 'draft'}>\n {o.label}\n </Text>\n {o.meta ? (\n <Text size=\"xs\" tone=\"muted\">\n {o.meta}\n </Text>\n ) : null}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\n/** The unified/side-by-side segmented toggle (EC-317) — same pill language as\n * the header's `ViewTabs`/locale switcher, so it reads as one lens control. */\nfunction DiffViewToggle({ mode, onChange }: { mode: DiffViewMode; onChange: (mode: DiffViewMode) => void }) {\n return (\n <Row\n gap=\"px\"\n className=\"rounded-md bg-muted/50 p-0.5\"\n role=\"group\"\n aria-label={translate('cms.version.viewModeAriaLabel')}\n data-testid=\"diff-view-toggle\"\n >\n <DiffViewOption\n active={mode === 'sideBySide'}\n label={translate('cms.version.viewSideBySide')}\n onClick={() => onChange('sideBySide')}\n />\n <DiffViewOption\n active={mode === 'unified'}\n label={translate('cms.version.viewUnified')}\n onClick={() => onChange('unified')}\n />\n </Row>\n )\n}\n\nfunction DiffViewOption({ active, label, onClick }: { active: boolean; label: string; onClick: () => void }) {\n return (\n <button\n type=\"button\"\n aria-pressed={active}\n data-testid={`diff-view-option-${active ? 'active' : 'inactive'}`}\n onClick={onClick}\n className={cn(\n 'rounded-[5px] px-2.5 py-1 text-xs font-medium transition-colors',\n active ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground',\n )}\n >\n {label}\n </button>\n )\n}\n\ninterface FieldGroupData {\n field: string\n label: string\n type: FieldDef['type']\n entries: FieldChange[]\n}\n\n/**\n * One field's diff rows (EC-317: each locale variant is its own zebra-striped\n * row with a descriptor lane — label reused from the studio's EC-241\n * `fieldLabel` active-locale resolver where a schema field exists, falling\n * back to the diff engine's default-locale label for a schema-drift key).\n */\nfunction FieldGroup({\n group,\n field,\n zebraStart,\n canRestore,\n busy,\n onRestore,\n}: {\n group: FieldGroupData\n field: FieldDef | undefined\n zebraStart: number\n canRestore: boolean\n busy: boolean\n onRestore: (scope: RestoreScope) => void\n}) {\n const label = field ? fieldLabel(field) : group.label\n return (\n <div className=\"border-t border-border/30\">\n {group.entries.map((entry, i) => {\n const rowId = `${group.field}:${entry.locale ?? '_'}`\n return (\n <FieldRow\n key={entry.locale ?? '__base__'}\n zebra={(zebraStart + i) % 2 === 1}\n descriptor={<FieldDescriptor label={label} locale={entry.locale} kind={entry.kind} />}\n restore={\n canRestore ? (\n <RestoreIcon\n busy={busy}\n title={\n entry.locale\n ? translate('cms.version.restoreFieldLocale', {\n field: label,\n locale: localeChipLabel(entry.locale),\n })\n : translate('cms.version.restoreField', { field: label })\n }\n onClick={() => onRestore(fieldScope(entry))}\n />\n ) : null\n }\n >\n <EntryBody change={entry} rowId={rowId} canRestore={canRestore} busy={busy} onRestore={onRestore} />\n </FieldRow>\n )\n })}\n </div>\n )\n}\n\n/** The descriptor lane + value area, one grid row (EC-317). Zebra alternates\n * by the row's position across the WHOLE change-list, not per field group. */\nfunction FieldRow({\n descriptor,\n restore,\n zebra,\n children,\n}: {\n descriptor: ReactNode\n restore: ReactNode\n zebra: boolean\n children: ReactNode\n}) {\n return (\n <div className={cn(DIFF_ROW_GRID, 'rounded-sm px-2 py-2.5', zebra && 'bg-muted/40')}>\n <div className=\"flex flex-col gap-1.5\">\n {descriptor}\n {restore}\n </div>\n <div className=\"min-w-0\">{children}</div>\n </div>\n )\n}\n\n/** The descriptor lane's content (EC-317): field label always, locale chip only\n * when this row is a localized variant, plus the quiet added/removed kind tag. */\nfunction FieldDescriptor({ label, locale, kind }: { label: string; locale?: string; kind: ChangeKind }) {\n return (\n <Stack gap=\"1\">\n <Text size=\"sm\" weight=\"medium\" className=\"min-w-0 truncate\">\n {label}\n </Text>\n <Row gap=\"1\" wrap>\n {locale ? (\n <Badge variant=\"outline\" className=\"px-1 py-0 text-[0.6rem] uppercase tracking-wide text-muted-foreground\">\n {localeChipLabel(locale)}\n </Badge>\n ) : null}\n <KindTag kind={kind} />\n </Row>\n </Stack>\n )\n}\n\nfunction EntryBody({\n change,\n rowId,\n canRestore,\n busy,\n onRestore,\n}: {\n change: FieldChange\n rowId: string\n canRestore: boolean\n busy: boolean\n onRestore: (scope: RestoreScope) => void\n}) {\n const localeScope = change.locale !== undefined ? { locale: change.locale } : {}\n if (change.blocks) {\n return (\n <Stack gap=\"3\" className=\"mt-1\">\n {change.blocks.map((block) => (\n <BlockSection\n key={block.blockId}\n block={block}\n rowId={`${rowId}|block:${block.blockId}`}\n canRestore={canRestore}\n busy={busy}\n onRestore={() => onRestore({ kind: 'block', field: change.field, blockId: block.blockId, ...localeScope })}\n />\n ))}\n </Stack>\n )\n }\n if (change.type === 'richText') {\n const before = richTextToText(change.before)\n const after = richTextToText(change.after)\n if (before === after)\n return (\n <MutedNote>\n {before ? translate('cms.version.textUnchanged') : translate('cms.version.contentChanged')}\n </MutedNote>\n )\n return <WordDiffCols id={rowId} before={before} after={after} />\n }\n if (change.kind === 'changed' && typeof change.before === 'string' && typeof change.after === 'string') {\n return <WordDiffCols id={rowId} before={change.before} after={change.after} />\n }\n return (\n <DiffColumns\n kind={change.kind}\n before={<SideValue value={change.before} other={change.after} typeHint={change.type} id={`${rowId}|before`} />}\n after={<SideValue value={change.after} other={change.before} typeHint={change.type} id={`${rowId}|after`} />}\n />\n )\n}\n\nfunction BlockSection({\n block,\n rowId,\n canRestore,\n busy,\n onRestore,\n}: {\n block: BlockChange\n rowId: string\n canRestore: boolean\n busy: boolean\n onRestore: () => void\n}) {\n const name = block.componentId.split('.').pop() ?? block.componentId\n return (\n <div>\n <Row gap=\"2\" align=\"center\" className=\"mb-1\">\n <Text size=\"xs\" weight=\"medium\" className=\"min-w-0 truncate\">\n {name}\n </Text>\n <Code tone=\"muted\">{block.componentId}</Code>\n <KindTag kind={block.kind} />\n <Spacer />\n {canRestore ? (\n <RestoreIcon busy={busy} title={translate('cms.version.restoreBlock')} onClick={onRestore} />\n ) : null}\n </Row>\n {block.props && block.props.length > 0 ? (\n <Stack gap=\"2\">\n {block.props.map((prop) => (\n <PropRow key={prop.name} prop={prop} rowId={`${rowId}|prop:${prop.name}`} />\n ))}\n </Stack>\n ) : null}\n {block.slotsChanged ? <MutedNote>{translate('cms.version.nestedContentChanged')}</MutedNote> : null}\n {block.kind !== 'changed' && !block.props?.length ? (\n <MutedNote>\n {block.kind === 'added' ? translate('cms.version.blockAdded') : translate('cms.version.blockRemoved')}\n </MutedNote>\n ) : null}\n </div>\n )\n}\n\nfunction PropRow({ prop, rowId }: { prop: PropChange; rowId: string }) {\n const useWordDiff = prop.kind === 'changed' && typeof prop.before === 'string' && typeof prop.after === 'string'\n return (\n <div>\n <Text size=\"xs\" tone=\"subtle\" className=\"mb-0.5 block uppercase tracking-wide\">\n {prettyName(prop.name)}\n </Text>\n {useWordDiff ? (\n <WordDiffCols id={rowId} before={String(prop.before)} after={String(prop.after)} />\n ) : (\n <DiffColumns\n kind={prop.kind}\n before={<SideValue value={prop.before} other={prop.after} id={`${rowId}|before`} />}\n after={<SideValue value={prop.after} other={prop.before} id={`${rowId}|after`} />}\n />\n )}\n </div>\n )\n}\n\n/** One side of a non-text change — the value, or an \"empty\" placeholder. */\nfunction SideValue({\n value,\n other,\n typeHint,\n id,\n}: {\n value: unknown\n other?: unknown\n typeHint?: FieldDef['type']\n id: string\n}) {\n if (value === undefined || value === null || value === '') {\n return (\n <Text size=\"sm\" tone=\"subtle\" className=\"italic\">\n {translate('cms.version.emptyValue')}\n </Text>\n )\n }\n return <ValueView value={value} other={other} typeHint={typeHint} id={id} />\n}\n\n/**\n * Read-only value display, dispatching on the field type where known and on the\n * self-describing value shape otherwise (block props carry no schema) — assets as\n * thumbnails, relations as titles, everything else as calm text (EC-317: the\n * plain-text fallback truncates past the shared length threshold).\n */\nfunction ValueView({\n value,\n other,\n typeHint,\n id,\n}: {\n value: unknown\n other?: unknown\n typeHint?: FieldDef['type']\n id: string\n}) {\n // Called unconditionally up front (rules-of-hooks) even though only the plain-\n // text fallback branch below needs it — the early returns above it don't hook.\n const { isExpanded } = useDiffDisplay()\n if (typeHint === 'asset' || isAssetNode(value)) return <AssetValue value={value} />\n if (typeHint === 'relation' || readDocumentRef(value)) return <RelationValue value={value} other={other} />\n if (typeHint === 'richText')\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words\">\n {richTextToText(value) || translate('cms.version.richText')}\n </Text>\n )\n if (typeHint === 'boolean' || typeof value === 'boolean')\n return (\n <Text size=\"sm\" mono>\n {value === true ? translate('common.yes') : translate('common.no')}\n </Text>\n )\n if (typeHint === 'date')\n return (\n <Text size=\"sm\" mono>\n {String(value).slice(0, 10)}\n </Text>\n )\n if (typeof value === 'object')\n return (\n <Text size=\"sm\" tone=\"muted\">\n {Array.isArray(value)\n ? translate(value.length === 1 ? 'cms.version.itemCount.one' : 'cms.version.itemCount.other', {\n count: value.length,\n })\n : translate('cms.version.objectValue')}\n </Text>\n )\n const expanded = isExpanded(id)\n const { shown, isLong } = truncateText(String(value), expanded)\n return (\n <ExpandToggle id={id} isLong={isLong} expanded={expanded}>\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words\">\n {shown}\n </Text>\n </ExpandToggle>\n )\n}\n\nfunction RelationValue({ value, other }: { value: unknown; other?: unknown }) {\n const source = useCollectionView()\n const refs = toRefArray(value)\n if (refs.length === 0)\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words\">\n {String(value)}\n </Text>\n )\n const otherRefs = other !== undefined ? toRefArray(other) : []\n // Disambiguate a same-titled but different target (the \"Ada → Ada\" trap): show\n // the id only when the titles would otherwise read identically.\n const label = refs\n .map((ref) => {\n const title = source.titleOf(ref)\n const collision = otherRefs.some((o) => o.id !== ref.id && source.titleOf(o) === title)\n return collision ? `${title} · ${ref.id}` : title\n })\n .join(', ')\n return <Text size=\"sm\">{label}</Text>\n}\n\nfunction AssetValue({ value }: { value: unknown }) {\n const ids = (Array.isArray(value) ? value : [value]).map(readAssetId).filter((id): id is string => id !== undefined)\n if (ids.length === 0)\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words\">\n {String(value)}\n </Text>\n )\n return (\n <div className=\"flex flex-wrap gap-2\">\n {ids.map((id) => (\n <AssetThumb key={id} id={id} />\n ))}\n </div>\n )\n}\n\n/** An asset as a thumbnail (image with a resolvable URL) or a labelled badge —\n * the visual diff for a cover-image change, not two identical filenames. */\nfunction AssetThumb({ id }: { id: string }) {\n const source = useCollectionView()\n const assetCollectionId = source.assetCollectionId ?? 'asset'\n const record = source.resolveAsset?.(id)\n const label = record?.title ?? record?.filename ?? source.titleOf({ collection: assetCollectionId, id })\n const isImage = record?.contentType?.startsWith('image/') ?? false\n const url = record?.url\n if (isImage && url && url.startsWith('http')) {\n return (\n <span className=\"inline-flex min-w-0 items-center gap-2\">\n <img\n src={url}\n alt={record?.alt ?? label}\n loading=\"lazy\"\n className=\"size-12 shrink-0 rounded border border-border bg-muted object-cover\"\n />\n <Text size=\"xs\" tone=\"muted\" className=\"min-w-0 truncate\">\n {label}\n </Text>\n </span>\n )\n }\n return (\n <Badge variant=\"outline\">\n <ImageIcon className=\"size-3\" /> {label}\n </Badge>\n )\n}\n\n// --- Prose word diff --------------------------------------------------------------\n\n/**\n * Prose diff across a row (EC-317): side-by-side reads as two word-diffed\n * columns; unified merges into ONE reading lane (`mergeWordDiff`). Either way,\n * a value past the length threshold collapses behind the row's expand control\n * — the full `wordDiff`/`mergeWordDiff` computation underneath is untouched.\n */\nfunction WordDiffCols({ id, before, after }: { id: string; before: string; after: string }) {\n const { mode, isExpanded } = useDiffDisplay()\n const expanded = isExpanded(id)\n const wd = useMemo(() => wordDiff(before, after), [before, after])\n const merged = useMemo(() => mergeWordDiff(wd.before, wd.after), [wd])\n\n if (mode === 'unified') {\n const { shown, isLong } = truncateTokens(merged, expanded, DIFF_TRUNCATE_THRESHOLD)\n return (\n <ExpandToggle id={id} isLong={isLong} expanded={expanded}>\n <UnifiedWordTokens tokens={shown} />\n </ExpandToggle>\n )\n }\n\n const beforeSlice = truncateTokens(wd.before, expanded, DIFF_TRUNCATE_THRESHOLD)\n const afterSlice = truncateTokens(wd.after, expanded, DIFF_TRUNCATE_THRESHOLD)\n const isLong = beforeSlice.isLong || afterSlice.isLong\n return (\n <ExpandToggle id={id} isLong={isLong} expanded={expanded}>\n <TwoCol\n before={<WordTokens tokens={beforeSlice.shown} side=\"before\" />}\n after={<WordTokens tokens={afterSlice.shown} side=\"after\" />}\n />\n </ExpandToggle>\n )\n}\n\nfunction WordTokens({ tokens, side }: { tokens: WordToken[]; side: 'before' | 'after' }) {\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words leading-relaxed\">\n {tokens.map((token, i) =>\n token.changed ? (\n <mark\n key={i}\n className={cn(\n 'rounded-sm px-0.5',\n side === 'before'\n ? 'bg-destructive/15 text-destructive line-through decoration-destructive/40'\n : 'bg-success/20 text-foreground',\n )}\n >\n {token.text}\n </mark>\n ) : (\n <span key={i} className=\"text-muted-foreground\">\n {token.text}\n </span>\n ),\n )}\n </Text>\n )\n}\n\n/** The unified lane's merged token stream — same marks as `WordTokens`, one\n * continuous reading order instead of two columns. */\nfunction UnifiedWordTokens({ tokens }: { tokens: MergedDiffToken[] }) {\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words leading-relaxed\">\n {tokens.map((token, i) =>\n token.kind === 'same' ? (\n <span key={i} className=\"text-muted-foreground\">\n {token.text}\n </span>\n ) : (\n <mark\n key={i}\n className={cn(\n 'rounded-sm px-0.5',\n token.kind === 'removed'\n ? 'bg-destructive/15 text-destructive line-through decoration-destructive/40'\n : 'bg-success/20 text-foreground',\n )}\n >\n {token.text}\n </mark>\n ),\n )}\n </Text>\n )\n}\n\n// --- Small shared bits ------------------------------------------------------------\n\n/** A quiet \"· new\" / \"· removed\" tag; nothing for a plain change (implicit). */\nfunction KindTag({ kind }: { kind: FieldChange['kind'] }) {\n if (kind === 'changed') return null\n return (\n <Text size=\"xs\" tone=\"subtle\">\n · {kind === 'added' ? translate('cms.version.kindNew') : translate('cms.version.kindRemoved')}\n </Text>\n )\n}\n\nfunction RestoreIcon({ busy, title, onClick }: { busy: boolean; title: string; onClick: () => void }) {\n return (\n <Button variant=\"ghost\" size=\"icon-sm\" disabled={busy} title={title} aria-label={title} onClick={onClick}>\n <RotateCcw />\n </Button>\n )\n}\n\nfunction MutedNote({ children }: { children: ReactNode }) {\n return (\n <Text size=\"sm\" tone=\"muted\" className=\"italic\">\n {children}\n </Text>\n )\n}\n\nfunction CompareNotice({ children }: { children: ReactNode }) {\n return (\n <div className=\"mx-auto w-full max-w-5xl p-4 sm:p-6\">\n <div className=\"rounded-md border border-dashed border-border/70 px-4 py-8 text-center\">\n <Text size=\"sm\" tone=\"muted\">\n {children}\n </Text>\n </div>\n </div>\n )\n}\n\nfunction fieldScope(change: FieldChange): RestoreScope {\n return { kind: 'field', field: change.field, ...(change.locale !== undefined ? { locale: change.locale } : {}) }\n}\n\n/**\n * Group changes BY FIELD (a localized field's per-locale variants together),\n * fields in schema order, locales in project order (base bucket first).\n */\nfunction groupByField(\n changes: FieldChange[],\n fieldOrder: Map<string, number>,\n localeRank: Map<string, number>,\n): FieldGroupData[] {\n const map = new Map<string, FieldGroupData>()\n for (const change of changes) {\n let group = map.get(change.field)\n if (!group) {\n group = { field: change.field, label: change.label, type: change.type, entries: [] }\n map.set(change.field, group)\n }\n group.entries.push(change)\n }\n const groups = [...map.values()]\n groups.sort(\n (a, b) =>\n (fieldOrder.get(a.field) ?? Number.MAX_SAFE_INTEGER) - (fieldOrder.get(b.field) ?? Number.MAX_SAFE_INTEGER),\n )\n for (const group of groups) {\n group.entries.sort((a, b) => localeCompare(a.locale, b.locale, localeRank))\n }\n return groups\n}\n\nfunction localeCompare(a: string | undefined, b: string | undefined, rank: Map<string, number>): number {\n if (a === b) return 0\n if (a === undefined) return -1 // base bucket first\n if (b === undefined) return 1\n return (rank.get(a) ?? 99) - (rank.get(b) ?? 99)\n}\n\n/** camelCase / snake prop name → a readable label. */\nfunction prettyName(name: string): string {\n const spaced = name.replace(/[_-]+/g, ' ').replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n return spaced.charAt(0).toUpperCase() + spaced.slice(1)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"version-compare.js","sourceRoot":"","sources":["../../../src/components/cms/version-compare.tsx"],"names":[],"mappings":"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","sourcesContent":["import { createContext, useCallback, useContext, useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { ArrowRight, ChevronDown, ChevronLeft, ChevronRight, Image as ImageIcon, RotateCcw } from 'lucide-react'\nimport { diffDocuments } from '@elytracms/core/content'\nimport type { BlockChange, ChangeKind, FieldChange, PropChange } from '@elytracms/core/content'\nimport { assetSubfieldsOf, isAssetNode, readAssetId, readDocumentRef } from '@elytracms/core/cms-core'\nimport type { CmsDocument, FieldDef, RestoreScope } from '@elytracms/core/cms-core'\nimport {\n Badge,\n Button,\n Code,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n Row,\n Spacer,\n Stack,\n Text,\n} from '@elytracms/studio/ui'\nimport { useOperationCache } from '@elytracms/studio/lib/query'\nimport { translate } from '@elytracms/studio/lib/i18n'\nimport { localeChipLabel } from '@elytracms/studio/lib/locale'\nimport { cn } from '@elytracms/studio/lib/utils'\nimport { readDiffViewMode, storeDiffViewMode } from '@elytracms/studio/lib/diff-view-preference'\nimport type { DiffViewMode } from '@elytracms/studio/lib/diff-view-preference'\nimport { useCollectionView } from '../collection-view/collection-view-context'\nimport { fieldLabel } from './cms-store'\nimport { toRefArray } from './cell'\nimport {\n DIFF_TRUNCATE_THRESHOLD,\n mergeWordDiff,\n richTextToText,\n truncateText,\n truncateTokens,\n wordDiff,\n} from './version-compare-text'\nimport type { MergedDiffToken, WordToken } from './version-compare-text'\nimport { useDocumentEditor } from './document-editor-context'\nimport { useDocumentVersionsQuery } from './use-document-versions'\nimport { formatVersionTimestamp } from './versions-model'\n\n/**\n * EC-298 — the version compare view. Renders as the sticky **Compare** content tab\n * (the Versions sidebar pane stays on as the navigator).\n *\n * A calm change-list grouped BY FIELD (a localized field's per-locale variants sit\n * together): a left **descriptor lane** (EC-317 — field label + locale) identifies\n * each row, next to its before | after value (or one merged **unified** lane —\n * a persisted transient view preference, EC-317). Text reads as a prose diff\n * (changed words lit in place — rich text via its markdown projection); assets as\n * thumbnails; relations as titles. A value past a length threshold collapses\n * behind a per-row \"Show more\" (+ a global \"Expand/Collapse all\") — presentation\n * only, the semantic/identity diff underneath (EC-298) is never touched. Rows\n * zebra-stripe for scanability. Each field/locale (and each block, at property\n * level) restores back to the base version with a single ↩.\n */\nexport function VersionCompare() {\n const source = useCollectionView()\n const {\n collection,\n docRef,\n draft,\n dirty,\n viewReadOnly,\n save,\n replaceDraft,\n compare,\n setCompareBase,\n setCompareTarget,\n } = useDocumentEditor()\n const { versionsQuery, versionKey } = useDocumentVersionsQuery(docRef)\n const cache = useOperationCache()\n const [busy, setBusy] = useState(false)\n\n // EC-317 — the unified/side-by-side toggle is a transient, personal-local view\n // preference (same class as the theme/rail prefs): read once at mount, written\n // back on every change, never round-tripped through the project graph.\n const [mode, setModeState] = useState<DiffViewMode>(() => readDiffViewMode())\n const setMode = useCallback((next: DiffViewMode) => {\n setModeState(next)\n storeDiffViewMode(next)\n }, [])\n\n // EC-317 — long-value truncation state: an `expandAll` flag plus per-row\n // overrides. Presentation-only (never recomputes the diff), reset is implicit\n // (in-session state, like the rest of the compare selection).\n const [expandAll, setExpandAll] = useState(false)\n const [expandedRows, setExpandedRows] = useState<ReadonlySet<string>>(() => new Set())\n const toggleExpand = useCallback((id: string) => {\n setExpandedRows((prev) => {\n const next = new Set(prev)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n return next\n })\n }, [])\n const isExpanded = useCallback((id: string) => expandAll || expandedRows.has(id), [expandAll, expandedRows])\n const toggleExpandAll = useCallback(() => {\n setExpandAll((prev) => {\n const next = !prev\n // Collapsing all clears per-row overrides too, so \"Collapse all\" always\n // means \"everything is collapsed\" rather than \"back to before I expanded\".\n if (!next) setExpandedRows(new Set())\n return next\n })\n }, [])\n const diffDisplay = useMemo<DiffDisplayState>(\n () => ({ mode, expandAll, isExpanded, toggleExpand }),\n [mode, expandAll, isExpanded, toggleExpand],\n )\n\n const view = versionsQuery.data ?? null\n const versions = useMemo(() => view?.versions ?? [], [view])\n\n const baseRecord = compare ? versions.find((v) => v.version === compare.base) : undefined\n const targetSnapshot: CmsDocument | undefined =\n compare?.target === 'draft' ? draft : versions.find((v) => v.version === compare?.target)?.snapshot\n\n const diff = useMemo(\n () =>\n baseRecord && targetSnapshot\n ? diffDocuments(collection, baseRecord.snapshot, targetSnapshot)\n : { changes: [], unchangedCount: 0 },\n [collection, baseRecord, targetSnapshot],\n )\n\n const fieldOrder = useMemo(() => new Map(collection.fields.map((f, i) => [f.name, i])), [collection])\n const fieldByName = useMemo(() => new Map(collection.fields.map((f) => [f.name, f])), [collection])\n const localeRank = useMemo(() => new Map(source.localeConfig.locales.map((l, i) => [l, i])), [source.localeConfig])\n const groups = useMemo(\n () => groupByField(diff.changes, fieldOrder, localeRank),\n [diff.changes, fieldOrder, localeRank],\n )\n // EC-317 zebra striping: a running index across every rendered row (not reset\n // per field group), so consecutive groups keep alternating rather than each\n // restarting on the same shade.\n const groupRows = useMemo(() => {\n let rowIndex = 0\n return groups.map((group) => {\n const zebraStart = rowIndex\n rowIndex += group.entries.length\n return { group, field: fieldByName.get(group.field), zebraStart }\n })\n }, [groups, fieldByName])\n\n const restore = useCallback(\n async (scope: RestoreScope) => {\n if (!compare) return\n setBusy(true)\n try {\n if (dirty) save()\n const restored = await source.versioning?.restore(docRef, compare.base, scope)\n if (restored) replaceDraft(restored)\n await cache.invalidate(versionKey)\n } finally {\n setBusy(false)\n }\n },\n [compare, dirty, save, source, docRef, replaceDraft, cache, versionKey],\n )\n\n if (!compare) return null\n if (view === null) return <CompareNotice>{translate('cms.version.loadingHistory')}</CompareNotice>\n if (!baseRecord || !targetSnapshot)\n return <CompareNotice>{translate('cms.version.versionUnavailable')}</CompareNotice>\n\n const canRestore = compare.target === 'draft' && !viewReadOnly\n const targetLabel = compare.target === 'draft' ? translate('cms.version.currentDraft') : `v${compare.target}`\n\n // Step the base through history, skipping the target so the sides never collapse.\n const baseIndex = versions.findIndex((v) => v.version === compare.base)\n const nextBaseFor = (dir: -1 | 1): number | undefined => {\n let i = baseIndex + dir\n while (i >= 0 && i < versions.length && versions[i]!.version === compare.target) i += dir\n return i >= 0 && i < versions.length ? versions[i]!.version : undefined\n }\n const newerBase = nextBaseFor(-1) // versions are newest-first\n const olderBase = nextBaseFor(1)\n\n const baseOptions = versions\n .filter((v) => v.version !== compare.target)\n .map((v) => ({ value: v.version, label: `v${v.version}`, meta: formatVersionTimestamp(v.createdAt) }))\n const targetOptions = [\n {\n value: 'draft' as const,\n label: translate('cms.version.currentDraft'),\n meta: dirty ? translate('cms.version.unsavedEdits') : undefined,\n },\n ...versions\n .filter((v) => v.version !== compare.base)\n .map((v) => ({ value: v.version, label: `v${v.version}`, meta: formatVersionTimestamp(v.createdAt) })),\n ]\n\n return (\n <Stack gap=\"3\" className=\"mx-auto w-full max-w-5xl p-4 sm:p-6\">\n {/* The two sides — both re-pickable, so any pair can be compared; the\n Versions pane also sets the base on click. Stepper walks the base. */}\n <Row gap=\"2\" align=\"center\" wrap className=\"rounded-md border border-border/70 bg-muted/30 px-3 py-2\">\n <VersionMenu\n caption={translate('cms.version.baseCaption')}\n current={`v${compare.base}`}\n meta={formatVersionTimestamp(baseRecord.createdAt)}\n options={baseOptions}\n onSelect={(v) => setCompareBase(v as number)}\n />\n <ArrowRight className=\"size-4 shrink-0 text-muted-foreground\" aria-hidden />\n <VersionMenu\n caption={translate('cms.version.compareWithCaption')}\n current={targetLabel}\n options={targetOptions}\n onSelect={(v) => setCompareTarget(v as number | 'draft')}\n />\n <Spacer />\n <Row gap=\"1\">\n <Button\n variant=\"outline\"\n size=\"icon-sm\"\n onClick={() => newerBase !== undefined && setCompareBase(newerBase)}\n disabled={newerBase === undefined}\n title={translate('cms.version.compareNewer')}\n aria-label={translate('cms.version.compareNewer')}\n >\n <ChevronLeft />\n </Button>\n <Button\n variant=\"outline\"\n size=\"icon-sm\"\n onClick={() => olderBase !== undefined && setCompareBase(olderBase)}\n disabled={olderBase === undefined}\n title={translate('cms.version.compareOlder')}\n aria-label={translate('cms.version.compareOlder')}\n >\n <ChevronRight />\n </Button>\n </Row>\n {canRestore ? (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => void restore({ kind: 'all' })}\n disabled={busy || diff.changes.length === 0}\n title={translate('cms.version.restoreWholeTitle', { version: compare.base })}\n >\n <RotateCcw /> {translate('cms.version.restoreVersion')}\n </Button>\n ) : null}\n </Row>\n\n {/* EC-317 — the diff-layout toolbar: unified/side-by-side (persisted) + expand-all.\n Only meaningful once there is a diff to lay out, so it's gated the same\n as the change-list below. */}\n {diff.changes.length > 0 ? (\n <Row gap=\"2\" align=\"center\" justify=\"between\" wrap className=\"px-0.5\">\n <DiffViewToggle mode={mode} onChange={setMode} />\n <Button variant=\"ghost\" size=\"sm\" onClick={toggleExpandAll}>\n {translate(expandAll ? 'cms.field.collapseAll' : 'cms.field.expandAll')}\n </Button>\n </Row>\n ) : null}\n\n <Text size=\"xs\" tone=\"muted\" className=\"px-0.5\">\n {diff.changes.length === 0\n ? translate('cms.version.noDifferences')\n : translate(diff.changes.length === 1 ? 'cms.version.changeSummary.one' : 'cms.version.changeSummary.other', {\n count: diff.changes.length,\n unchanged: diff.unchangedCount,\n })}\n {!canRestore && diff.changes.length > 0 ? translate('cms.version.comparingPastVersionsHint') : ''}\n </Text>\n\n {diff.changes.length === 0 ? (\n <CompareNotice>{translate('cms.version.versionsIdentical')}</CompareNotice>\n ) : (\n <DiffDisplayContext.Provider value={diffDisplay}>\n <div className=\"pb-1\">\n <div className={cn(DIFF_ROW_GRID, 'px-2 pb-1.5')}>\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {translate('cms.version.fieldColumnHeader')}\n </Text>\n {mode === 'unified' ? (\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {translate('cms.version.unifiedCaption', { base: compare.base, target: targetLabel })}\n </Text>\n ) : (\n <TwoCol\n before={\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {translate('cms.version.beforeVersion', { version: compare.base })}\n </Text>\n }\n after={\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {translate('cms.version.afterTarget', { target: targetLabel })}\n </Text>\n }\n />\n )}\n </div>\n {groupRows.map(({ group, field, zebraStart }) => (\n <FieldGroup\n key={group.field}\n group={group}\n field={field}\n zebraStart={zebraStart}\n baseVersion={compare.base}\n canRestore={canRestore}\n busy={busy}\n onRestore={restore}\n />\n ))}\n </div>\n </DiffDisplayContext.Provider>\n )}\n </Stack>\n )\n}\n\n// --- EC-317 diff-display context (mode + truncation) ------------------------------\n\ninterface DiffDisplayState {\n mode: DiffViewMode\n expandAll: boolean\n isExpanded: (id: string) => boolean\n toggleExpand: (id: string) => void\n}\n\nconst DiffDisplayContext = createContext<DiffDisplayState | null>(null)\n\nfunction useDiffDisplay(): DiffDisplayState {\n const ctx = useContext(DiffDisplayContext)\n if (!ctx) throw new Error('useDiffDisplay must be rendered under the VersionCompare diff area')\n return ctx\n}\n\n/** Shared grid template so the descriptor lane + header captions line up. 0.0.41:\n * a third slim column holds the field-row restore action — see {@link FieldRow}. */\nconst DIFF_ROW_GRID = 'grid grid-cols-[7.5rem_1fr_1.75rem] items-start gap-x-4'\n\n/** A before | after grid with a clear central divider (0.0.39: a full-height ruled\n * gutter — the same proportions in every row type, so the before/after split reads\n * consistently across field rows, block-prop rows and word diffs). The columns keep\n * a symmetric inset off the divider so values never touch it. */\nfunction TwoCol({ before, after, className }: { before: ReactNode; after: ReactNode; className?: string }) {\n return (\n <div className={cn('relative grid grid-cols-2 gap-x-8', className)}>\n <div className=\"pointer-events-none absolute inset-y-0 left-1/2 w-px -translate-x-1/2 bg-border\" aria-hidden />\n <div className=\"min-w-0 pr-1\">{before}</div>\n <div className=\"min-w-0 pl-1\">{after}</div>\n </div>\n )\n}\n\n/**\n * Mode-aware value display (EC-317): side-by-side keeps the before | after\n * columns; unified stacks a single \"− before\" / \"+ after\" pair in one lane,\n * omitting whichever side doesn't exist (`added`/`removed` kind).\n */\nfunction DiffColumns({ before, after, kind }: { before: ReactNode; after: ReactNode; kind: ChangeKind }) {\n const { mode } = useDiffDisplay()\n if (mode === 'unified') {\n return (\n <Stack gap=\"1\">\n {kind !== 'added' ? <UnifiedLine tone=\"removed\">{before}</UnifiedLine> : null}\n {kind !== 'removed' ? <UnifiedLine tone=\"added\">{after}</UnifiedLine> : null}\n </Stack>\n )\n }\n return <TwoCol before={before} after={after} />\n}\n\nfunction UnifiedLine({ tone, children }: { tone: 'removed' | 'added'; children: ReactNode }) {\n return (\n <Row\n gap=\"2\"\n align=\"start\"\n className={cn('rounded-sm px-1.5 py-1', tone === 'removed' ? 'bg-destructive/10' : 'bg-success/10')}\n >\n <Text\n size=\"xs\"\n mono\n aria-hidden\n className={cn('mt-0.5 shrink-0 select-none', tone === 'removed' ? 'text-destructive' : 'text-success')}\n >\n {tone === 'removed' ? '−' : '+'}\n </Text>\n <div className=\"min-w-0 flex-1\">{children}</div>\n </Row>\n )\n}\n\n/** Wraps truncatable content with its per-row \"Show more\"/\"Show less\" control —\n * hidden while the global \"expand all\" is active (nothing left to toggle). */\nfunction ExpandToggle({\n id,\n isLong,\n expanded,\n children,\n}: {\n id: string\n isLong: boolean\n expanded: boolean\n children: ReactNode\n}) {\n const { expandAll, toggleExpand } = useDiffDisplay()\n return (\n <div>\n {children}\n {isLong && !expandAll ? (\n <Button variant=\"link\" size=\"sm\" className=\"h-auto p-0 text-xs\" onClick={() => toggleExpand(id)}>\n {expanded ? translate('cms.version.showLess') : translate('cms.version.showMore')}\n </Button>\n ) : null}\n </div>\n )\n}\n\nfunction VersionMenu({\n caption,\n current,\n meta,\n options,\n onSelect,\n}: {\n caption: string\n current: string\n meta?: string\n options: { value: number | 'draft'; label: string; meta?: string }[]\n onSelect: (value: number | 'draft') => void\n}) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"sm\" className=\"gap-1.5\">\n <Text size=\"xs\" tone=\"subtle\" className=\"uppercase tracking-wide\">\n {caption}\n </Text>\n <Text size=\"sm\" weight=\"medium\" mono>\n {current}\n </Text>\n {meta ? (\n <Text size=\"xs\" tone=\"muted\" className=\"hidden sm:inline\">\n {meta}\n </Text>\n ) : null}\n <ChevronDown className=\"size-3.5 text-muted-foreground\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\" className=\"max-h-72 overflow-auto\">\n {options.map((o) => (\n <DropdownMenuItem key={String(o.value)} onClick={() => onSelect(o.value)} className=\"gap-2\">\n <Text size=\"sm\" weight=\"medium\" mono={o.value !== 'draft'}>\n {o.label}\n </Text>\n {o.meta ? (\n <Text size=\"xs\" tone=\"muted\">\n {o.meta}\n </Text>\n ) : null}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )\n}\n\n/** The unified/side-by-side segmented toggle (EC-317) — same pill language as\n * the header's `ViewTabs`/locale switcher, so it reads as one lens control. */\nfunction DiffViewToggle({ mode, onChange }: { mode: DiffViewMode; onChange: (mode: DiffViewMode) => void }) {\n return (\n <Row\n gap=\"px\"\n className=\"rounded-md bg-muted/50 p-0.5\"\n role=\"group\"\n aria-label={translate('cms.version.viewModeAriaLabel')}\n data-testid=\"diff-view-toggle\"\n >\n <DiffViewOption\n active={mode === 'sideBySide'}\n label={translate('cms.version.viewSideBySide')}\n onClick={() => onChange('sideBySide')}\n />\n <DiffViewOption\n active={mode === 'unified'}\n label={translate('cms.version.viewUnified')}\n onClick={() => onChange('unified')}\n />\n </Row>\n )\n}\n\nfunction DiffViewOption({ active, label, onClick }: { active: boolean; label: string; onClick: () => void }) {\n return (\n <button\n type=\"button\"\n aria-pressed={active}\n data-testid={`diff-view-option-${active ? 'active' : 'inactive'}`}\n onClick={onClick}\n className={cn(\n 'rounded-[5px] px-2.5 py-1 text-xs font-medium transition-colors',\n active ? 'bg-background text-foreground shadow-sm' : 'text-muted-foreground hover:text-foreground',\n )}\n >\n {label}\n </button>\n )\n}\n\ninterface FieldGroupData {\n field: string\n label: string\n type: FieldDef['type']\n entries: FieldChange[]\n}\n\n/**\n * One field's diff rows (EC-317: each locale variant is its own zebra-striped\n * row with a descriptor lane — label reused from the studio's EC-241\n * `fieldLabel` active-locale resolver where a schema field exists, falling\n * back to the diff engine's default-locale label for a schema-drift key).\n */\nfunction FieldGroup({\n group,\n field,\n zebraStart,\n baseVersion,\n canRestore,\n busy,\n onRestore,\n}: {\n group: FieldGroupData\n field: FieldDef | undefined\n zebraStart: number\n baseVersion: number\n canRestore: boolean\n busy: boolean\n onRestore: (scope: RestoreScope) => void\n}) {\n const label = field ? fieldLabel(field) : group.label\n return (\n <div className=\"border-t border-border/30\">\n {group.entries.map((entry, i) => {\n const rowId = `${group.field}:${entry.locale ?? '_'}`\n // 0.0.39: ONE restore per row, right-aligned in the descriptor lane. A blocks\n // field restores per BLOCK (each block owns its own restore in its header), so\n // the field-level restore is dropped there — no more two icons per row.\n const fieldRestore =\n canRestore && !entry.blocks ? (\n <RestoreIcon\n busy={busy}\n title={\n entry.locale\n ? translate('cms.version.restoreFieldLocale', {\n field: label,\n locale: localeChipLabel(entry.locale),\n version: baseVersion,\n })\n : translate('cms.version.restoreField', { field: label, version: baseVersion })\n }\n onClick={() => onRestore(fieldScope(entry))}\n />\n ) : null\n return (\n <FieldRow\n key={entry.locale ?? '__base__'}\n zebra={(zebraStart + i) % 2 === 1}\n descriptor={<FieldDescriptor label={label} locale={entry.locale} kind={entry.kind} />}\n restore={fieldRestore}\n >\n <EntryBody\n change={entry}\n rowId={rowId}\n baseVersion={baseVersion}\n canRestore={canRestore}\n busy={busy}\n onRestore={onRestore}\n />\n </FieldRow>\n )\n })}\n </div>\n )\n}\n\n/** The descriptor lane + value area, one grid row (EC-317). Zebra alternates\n * by the row's position across the WHOLE change-list, not per field group. */\nfunction FieldRow({\n descriptor,\n restore,\n zebra,\n children,\n}: {\n descriptor: ReactNode\n restore: ReactNode\n zebra: boolean\n children: ReactNode\n}) {\n return (\n <div className={cn(DIFF_ROW_GRID, 'rounded-sm px-2 py-2.5', zebra && 'bg-muted/40')}>\n {/* 0.0.41: every restore affordance lives at the SAME right-aligned position —\n its own slim rightmost column, matching where a block-header's restore\n already sits (the far right of its full-width card). Previously the\n field-level restore was right-aligned WITHIN the narrow descriptor lane,\n which read as \"near the left\" next to the field name — confusing next to\n the block restores at the far right. The descriptor lane and value area\n keep their own widths untouched (this is a genuine grid column, not a\n flex squeeze inside the value cell), so the before/after divider never\n shifts depending on whether a given row happens to show a restore icon. */}\n <div className=\"min-w-0\">{descriptor}</div>\n <div className=\"min-w-0\">{children}</div>\n <div className=\"flex justify-end\">{restore}</div>\n </div>\n )\n}\n\n/** The descriptor lane's content (EC-317): field label always, locale chip only\n * when this row is a localized variant, plus the quiet added/removed kind tag. */\nfunction FieldDescriptor({ label, locale, kind }: { label: string; locale?: string; kind: ChangeKind }) {\n return (\n <Stack gap=\"1\">\n <Text size=\"sm\" weight=\"medium\" className=\"min-w-0 truncate\">\n {label}\n </Text>\n <Row gap=\"1\" wrap>\n {locale ? (\n <Badge variant=\"outline\" className=\"px-1 py-0 text-[0.6rem] uppercase tracking-wide text-muted-foreground\">\n {localeChipLabel(locale)}\n </Badge>\n ) : null}\n <KindTag kind={kind} />\n </Row>\n </Stack>\n )\n}\n\nfunction EntryBody({\n change,\n rowId,\n baseVersion,\n canRestore,\n busy,\n onRestore,\n}: {\n change: FieldChange\n rowId: string\n baseVersion: number\n canRestore: boolean\n busy: boolean\n onRestore: (scope: RestoreScope) => void\n}) {\n const localeScope = change.locale !== undefined ? { locale: change.locale } : {}\n if (change.blocks) {\n return (\n <Stack gap=\"2\" className=\"mt-1\">\n {change.blocks.map((block) => (\n <BlockSection\n key={block.blockId}\n block={block}\n rowId={`${rowId}|block:${block.blockId}`}\n baseVersion={baseVersion}\n canRestore={canRestore}\n busy={busy}\n onRestore={() => onRestore({ kind: 'block', field: change.field, blockId: block.blockId, ...localeScope })}\n />\n ))}\n </Stack>\n )\n }\n if (change.type === 'richText') {\n const before = richTextToText(change.before)\n const after = richTextToText(change.after)\n if (before === after)\n return (\n <MutedNote>\n {before ? translate('cms.version.textUnchanged') : translate('cms.version.contentChanged')}\n </MutedNote>\n )\n return <WordDiffCols id={rowId} before={before} after={after} />\n }\n if (change.kind === 'changed' && typeof change.before === 'string' && typeof change.after === 'string') {\n return <WordDiffCols id={rowId} before={change.before} after={change.after} />\n }\n return (\n <DiffColumns\n kind={change.kind}\n before={<SideValue value={change.before} other={change.after} typeHint={change.type} id={`${rowId}|before`} />}\n after={<SideValue value={change.after} other={change.before} typeHint={change.type} id={`${rowId}|after`} />}\n />\n )\n}\n\nfunction BlockSection({\n block,\n rowId,\n baseVersion,\n canRestore,\n busy,\n onRestore,\n}: {\n block: BlockChange\n rowId: string\n baseVersion: number\n canRestore: boolean\n busy: boolean\n onRestore: () => void\n}) {\n const name = block.componentId.split('.').pop() ?? block.componentId\n // 0.0.39: each block is its own owned row — a header band (block name + id + kind,\n // restore right-aligned) over the prop changes, indented under it with a left rail\n // so the nesting (field → block → props) reads at a glance.\n return (\n <div className=\"overflow-hidden rounded-md border border-border/60\">\n <Row gap=\"2\" align=\"center\" className=\"border-b border-border/50 bg-muted/30 px-2 py-1.5\">\n <Text size=\"xs\" weight=\"semibold\" className=\"min-w-0 truncate\">\n {name}\n </Text>\n <Code tone=\"muted\">{block.componentId}</Code>\n <KindTag kind={block.kind} />\n <Spacer />\n {canRestore ? (\n <RestoreIcon\n busy={busy}\n title={translate('cms.version.restoreBlock', { version: baseVersion })}\n onClick={onRestore}\n />\n ) : null}\n </Row>\n <div className=\"px-2 py-2\">\n {block.props && block.props.length > 0 ? (\n <Stack gap=\"3\" className=\"border-l-2 border-border/50 pl-3\">\n {block.props.map((prop) => (\n <PropRow key={prop.name} prop={prop} rowId={`${rowId}|prop:${prop.name}`} />\n ))}\n </Stack>\n ) : null}\n {block.slotsChanged ? <MutedNote>{translate('cms.version.nestedContentChanged')}</MutedNote> : null}\n {block.kind !== 'changed' && !block.props?.length ? (\n <MutedNote>\n {block.kind === 'added' ? translate('cms.version.blockAdded') : translate('cms.version.blockRemoved')}\n </MutedNote>\n ) : null}\n </div>\n </div>\n )\n}\n\nfunction PropRow({ prop, rowId }: { prop: PropChange; rowId: string }) {\n const useWordDiff = prop.kind === 'changed' && typeof prop.before === 'string' && typeof prop.after === 'string'\n return (\n <div>\n <Text size=\"xs\" tone=\"subtle\" className=\"mb-0.5 block uppercase tracking-wide\">\n {prettyName(prop.name)}\n </Text>\n {useWordDiff ? (\n <WordDiffCols id={rowId} before={String(prop.before)} after={String(prop.after)} />\n ) : (\n <DiffColumns\n kind={prop.kind}\n before={<SideValue value={prop.before} other={prop.after} id={`${rowId}|before`} />}\n after={<SideValue value={prop.after} other={prop.before} id={`${rowId}|after`} />}\n />\n )}\n </div>\n )\n}\n\n/** One side of a non-text change — the value, or an \"empty\" placeholder. */\nfunction SideValue({\n value,\n other,\n typeHint,\n id,\n}: {\n value: unknown\n other?: unknown\n typeHint?: FieldDef['type']\n id: string\n}) {\n if (value === undefined || value === null || value === '') {\n return (\n <Text size=\"sm\" tone=\"subtle\" className=\"italic\">\n {translate('cms.version.emptyValue')}\n </Text>\n )\n }\n return <ValueView value={value} other={other} typeHint={typeHint} id={id} />\n}\n\n/**\n * Read-only value display, dispatching on the field type where known and on the\n * self-describing value shape otherwise (block props carry no schema) — assets as\n * thumbnails, relations as titles, everything else as calm text (EC-317: the\n * plain-text fallback truncates past the shared length threshold).\n */\nfunction ValueView({\n value,\n other,\n typeHint,\n id,\n}: {\n value: unknown\n other?: unknown\n typeHint?: FieldDef['type']\n id: string\n}) {\n // Called unconditionally up front (rules-of-hooks) even though only the plain-\n // text fallback branch below needs it — the early returns above it don't hook.\n const { isExpanded } = useDiffDisplay()\n if (typeHint === 'asset' || isAssetNode(value)) return <AssetValue value={value} />\n if (typeHint === 'relation' || readDocumentRef(value)) return <RelationValue value={value} other={other} />\n if (typeHint === 'richText')\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words\">\n {richTextToText(value) || translate('cms.version.richText')}\n </Text>\n )\n if (typeHint === 'boolean' || typeof value === 'boolean')\n return (\n <Text size=\"sm\" mono>\n {value === true ? translate('common.yes') : translate('common.no')}\n </Text>\n )\n if (typeHint === 'date')\n return (\n <Text size=\"sm\" mono>\n {String(value).slice(0, 10)}\n </Text>\n )\n if (typeof value === 'object')\n return (\n <Text size=\"sm\" tone=\"muted\">\n {Array.isArray(value)\n ? translate(value.length === 1 ? 'cms.version.itemCount.one' : 'cms.version.itemCount.other', {\n count: value.length,\n })\n : translate('cms.version.objectValue')}\n </Text>\n )\n const expanded = isExpanded(id)\n const { shown, isLong } = truncateText(String(value), expanded)\n return (\n <ExpandToggle id={id} isLong={isLong} expanded={expanded}>\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words\">\n {shown}\n </Text>\n </ExpandToggle>\n )\n}\n\nfunction RelationValue({ value, other }: { value: unknown; other?: unknown }) {\n const source = useCollectionView()\n const refs = toRefArray(value)\n if (refs.length === 0)\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words\">\n {String(value)}\n </Text>\n )\n const otherRefs = other !== undefined ? toRefArray(other) : []\n // Disambiguate a same-titled but different target (the \"Ada → Ada\" trap): show\n // the id only when the titles would otherwise read identically.\n const label = refs\n .map((ref) => {\n const title = source.titleOf(ref)\n const collision = otherRefs.some((o) => o.id !== ref.id && source.titleOf(o) === title)\n return collision ? `${title} · ${ref.id}` : title\n })\n .join(', ')\n return <Text size=\"sm\">{label}</Text>\n}\n\n/**\n * Asset-record-owned keys — resolved off the asset RECORD at render (url, alt,\n * dimensions, focal point, …), never authored on the referencing document. Mirrors\n * the diff engine's own denylist (`document-diff.ts`): those keys never register as a\n * change, so they are never worth SHOWING as one either. Only authored per-use\n * sub-fields (EC-301, e.g. a placement's `caption`) surface beneath the thumbnail.\n */\nconst ASSET_RECORD_KEYS = new Set<string>([\n 'url', 'alt', 'width', 'height', 'focalPoint', 'contentType', 'mimeType',\n 'byteSize', 'storageKey', 'title', 'filename', 'meta', 'createdAt', 'updatedAt',\n])\n\nfunction authoredAssetSubfields(value: unknown): [string, unknown][] {\n return Object.entries(assetSubfieldsOf(value)).filter(([key]) => !ASSET_RECORD_KEYS.has(key))\n}\n\nfunction AssetValue({ value }: { value: unknown }) {\n const items = (Array.isArray(value) ? value : [value])\n .map((entry) => ({ id: readAssetId(entry), sub: authoredAssetSubfields(entry) }))\n .filter((a): a is { id: string; sub: [string, unknown][] } => a.id !== undefined)\n if (items.length === 0)\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words\">\n {String(value)}\n </Text>\n )\n return (\n <div className=\"flex flex-wrap gap-2\">\n {items.map(({ id, sub }, i) => (\n <div key={`${id}-${i}`} className=\"flex flex-col gap-1\">\n <AssetThumb id={id} />\n {/* 0.0.39: a placement's authored sub-fields (EC-301, e.g. `caption`) are\n shown beneath the thumbnail — the same image can differ only in these, so\n the diff is never invisible (record-owned metadata is filtered out). */}\n {sub.length > 0 ? (\n <Stack gap=\"1\" className=\"pl-0.5\">\n {sub.map(([key, val]) => (\n <Text key={key} size=\"xs\" tone=\"muted\" className=\"break-words\">\n <span className=\"uppercase tracking-wide text-muted-foreground/70\">{prettyName(key)}:</span>{' '}\n {typeof val === 'object' && val !== null\n ? translate('cms.version.objectValue')\n : String(val)}\n </Text>\n ))}\n </Stack>\n ) : null}\n </div>\n ))}\n </div>\n )\n}\n\n/** An asset as a thumbnail (image with a resolvable URL) or a labelled badge —\n * the visual diff for a cover-image change, not two identical filenames. */\nfunction AssetThumb({ id }: { id: string }) {\n const source = useCollectionView()\n const assetCollectionId = source.assetCollectionId ?? 'asset'\n const record = source.resolveAsset?.(id)\n const label = record?.title ?? record?.filename ?? source.titleOf({ collection: assetCollectionId, id })\n const isImage = record?.contentType?.startsWith('image/') ?? false\n const url = record?.url\n if (isImage && url && url.startsWith('http')) {\n return (\n <span className=\"inline-flex min-w-0 items-center gap-2\">\n <img\n src={url}\n alt={record?.alt ?? label}\n loading=\"lazy\"\n className=\"size-12 shrink-0 rounded border border-border bg-muted object-cover\"\n />\n <Text size=\"xs\" tone=\"muted\" className=\"min-w-0 truncate\">\n {label}\n </Text>\n </span>\n )\n }\n return (\n <Badge variant=\"outline\">\n <ImageIcon className=\"size-3\" /> {label}\n </Badge>\n )\n}\n\n// --- Prose word diff --------------------------------------------------------------\n\n/**\n * Prose diff across a row (EC-317): side-by-side reads as two word-diffed\n * columns; unified merges into ONE reading lane (`mergeWordDiff`). Either way,\n * a value past the length threshold collapses behind the row's expand control\n * — the full `wordDiff`/`mergeWordDiff` computation underneath is untouched.\n */\nfunction WordDiffCols({ id, before, after }: { id: string; before: string; after: string }) {\n const { mode, isExpanded } = useDiffDisplay()\n const expanded = isExpanded(id)\n const wd = useMemo(() => wordDiff(before, after), [before, after])\n const merged = useMemo(() => mergeWordDiff(wd.before, wd.after), [wd])\n\n if (mode === 'unified') {\n const { shown, isLong } = truncateTokens(merged, expanded, DIFF_TRUNCATE_THRESHOLD)\n return (\n <ExpandToggle id={id} isLong={isLong} expanded={expanded}>\n <UnifiedWordTokens tokens={shown} />\n </ExpandToggle>\n )\n }\n\n const beforeSlice = truncateTokens(wd.before, expanded, DIFF_TRUNCATE_THRESHOLD)\n const afterSlice = truncateTokens(wd.after, expanded, DIFF_TRUNCATE_THRESHOLD)\n const isLong = beforeSlice.isLong || afterSlice.isLong\n return (\n <ExpandToggle id={id} isLong={isLong} expanded={expanded}>\n <TwoCol\n before={<WordTokens tokens={beforeSlice.shown} side=\"before\" />}\n after={<WordTokens tokens={afterSlice.shown} side=\"after\" />}\n />\n </ExpandToggle>\n )\n}\n\nfunction WordTokens({ tokens, side }: { tokens: WordToken[]; side: 'before' | 'after' }) {\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words leading-relaxed\">\n {tokens.map((token, i) =>\n token.changed ? (\n <mark\n key={i}\n className={cn(\n 'rounded-sm px-0.5',\n side === 'before'\n ? 'bg-destructive/15 text-destructive line-through decoration-destructive/40'\n : 'bg-success/20 text-foreground',\n )}\n >\n {token.text}\n </mark>\n ) : (\n <span key={i} className=\"text-muted-foreground\">\n {token.text}\n </span>\n ),\n )}\n </Text>\n )\n}\n\n/** The unified lane's merged token stream — same marks as `WordTokens`, one\n * continuous reading order instead of two columns. */\nfunction UnifiedWordTokens({ tokens }: { tokens: MergedDiffToken[] }) {\n return (\n <Text size=\"sm\" className=\"whitespace-pre-wrap break-words leading-relaxed\">\n {tokens.map((token, i) =>\n token.kind === 'same' ? (\n <span key={i} className=\"text-muted-foreground\">\n {token.text}\n </span>\n ) : (\n <mark\n key={i}\n className={cn(\n 'rounded-sm px-0.5',\n token.kind === 'removed'\n ? 'bg-destructive/15 text-destructive line-through decoration-destructive/40'\n : 'bg-success/20 text-foreground',\n )}\n >\n {token.text}\n </mark>\n ),\n )}\n </Text>\n )\n}\n\n// --- Small shared bits ------------------------------------------------------------\n\n/** A quiet \"· new\" / \"· removed\" tag; nothing for a plain change (implicit). */\nfunction KindTag({ kind }: { kind: FieldChange['kind'] }) {\n if (kind === 'changed') return null\n return (\n <Text size=\"xs\" tone=\"subtle\">\n · {kind === 'added' ? translate('cms.version.kindNew') : translate('cms.version.kindRemoved')}\n </Text>\n )\n}\n\nfunction RestoreIcon({ busy, title, onClick }: { busy: boolean; title: string; onClick: () => void }) {\n return (\n <Button variant=\"ghost\" size=\"icon-sm\" disabled={busy} title={title} aria-label={title} onClick={onClick}>\n <RotateCcw />\n </Button>\n )\n}\n\nfunction MutedNote({ children }: { children: ReactNode }) {\n return (\n <Text size=\"sm\" tone=\"muted\" className=\"italic\">\n {children}\n </Text>\n )\n}\n\nfunction CompareNotice({ children }: { children: ReactNode }) {\n return (\n <div className=\"mx-auto w-full max-w-5xl p-4 sm:p-6\">\n <div className=\"rounded-md border border-dashed border-border/70 px-4 py-8 text-center\">\n <Text size=\"sm\" tone=\"muted\">\n {children}\n </Text>\n </div>\n </div>\n )\n}\n\nfunction fieldScope(change: FieldChange): RestoreScope {\n return { kind: 'field', field: change.field, ...(change.locale !== undefined ? { locale: change.locale } : {}) }\n}\n\n/**\n * Group changes BY FIELD (a localized field's per-locale variants together),\n * fields in schema order, locales in project order (base bucket first).\n */\nfunction groupByField(\n changes: FieldChange[],\n fieldOrder: Map<string, number>,\n localeRank: Map<string, number>,\n): FieldGroupData[] {\n const map = new Map<string, FieldGroupData>()\n for (const change of changes) {\n let group = map.get(change.field)\n if (!group) {\n group = { field: change.field, label: change.label, type: change.type, entries: [] }\n map.set(change.field, group)\n }\n group.entries.push(change)\n }\n const groups = [...map.values()]\n groups.sort(\n (a, b) =>\n (fieldOrder.get(a.field) ?? Number.MAX_SAFE_INTEGER) - (fieldOrder.get(b.field) ?? Number.MAX_SAFE_INTEGER),\n )\n for (const group of groups) {\n group.entries.sort((a, b) => localeCompare(a.locale, b.locale, localeRank))\n }\n return groups\n}\n\nfunction localeCompare(a: string | undefined, b: string | undefined, rank: Map<string, number>): number {\n if (a === b) return 0\n if (a === undefined) return -1 // base bucket first\n if (b === undefined) return 1\n return (rank.get(a) ?? 99) - (rank.get(b) ?? 99)\n}\n\n/** camelCase / snake prop name → a readable label. */\nfunction prettyName(name: string): string {\n const spaced = name.replace(/[_-]+/g, ' ').replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n return spaced.charAt(0).toUpperCase() + spaced.slice(1)\n}\n"]}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Component } from 'react';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
1
3
|
import type { ComponentNode, JsonValue } from '@elytracms/core/project-graph';
|
|
2
4
|
import type { ComponentManifest } from '@elytracms/core/component-registry';
|
|
3
5
|
import type { StudioRegistry } from '@elytracms/studio/lib/registry';
|
|
@@ -40,6 +42,39 @@ export declare function ComponentPreview({ manifest, studio, state, }: {
|
|
|
40
42
|
studio: StudioRegistry;
|
|
41
43
|
state: PreviewState;
|
|
42
44
|
}): import("react").JSX.Element;
|
|
45
|
+
interface PreviewBoundaryState {
|
|
46
|
+
error: Error | null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* EC-191 resilience for the Components view: a component whose render throws — a
|
|
50
|
+
* missing provider/context (e.g. a prop control that needs a document's
|
|
51
|
+
* `CollectionViewSource`), a runtime bug — shows the documented "preview
|
|
52
|
+
* unavailable" fallback ({@link PreviewUnavailable}) instead of taking the whole
|
|
53
|
+
* view down. It resets when the previewed `resetKey` (the node) changes, so
|
|
54
|
+
* switching the fixture state or editing a prop retries the render.
|
|
55
|
+
*/
|
|
56
|
+
export declare class PreviewErrorBoundary extends Component<{
|
|
57
|
+
children: ReactNode;
|
|
58
|
+
displayName: string;
|
|
59
|
+
resetKey: unknown;
|
|
60
|
+
}, PreviewBoundaryState> {
|
|
61
|
+
state: PreviewBoundaryState;
|
|
62
|
+
static getDerivedStateFromError(error: Error): PreviewBoundaryState;
|
|
63
|
+
componentDidUpdate(prev: Readonly<{
|
|
64
|
+
resetKey: unknown;
|
|
65
|
+
}>): void;
|
|
66
|
+
render(): ReactNode;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The EC-191 fallback panel — component name + "preview unavailable" + the error.
|
|
70
|
+
* Rendered INTO the preview iframe (which carries only the project stylesheet, and
|
|
71
|
+
* may carry none in tests), so it uses inline styles rather than studio UI classes
|
|
72
|
+
* — matching the canvas's own in-iframe placeholder convention.
|
|
73
|
+
*/
|
|
74
|
+
export declare function PreviewUnavailable({ displayName, error }: {
|
|
75
|
+
displayName: string;
|
|
76
|
+
error: Error;
|
|
77
|
+
}): import("react").JSX.Element;
|
|
43
78
|
/**
|
|
44
79
|
* The editable Props pane (right inspector). Every non-`blocks` prop is edited
|
|
45
80
|
* through the shared {@link PropValueControl} — the exact control set documents
|
|
@@ -59,3 +94,4 @@ export declare function PropsEditorPane({ manifest, state, }: {
|
|
|
59
94
|
export declare function SlotsInfoPane({ manifest }: {
|
|
60
95
|
manifest: ComponentManifest;
|
|
61
96
|
}): import("react").JSX.Element;
|
|
97
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo, useState } from 'react';
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Component, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { createPortal } from 'react-dom';
|
|
3
4
|
import { MonitorOff, RotateCcw } from 'lucide-react';
|
|
4
5
|
import { renderNode } from '@elytracms/core/runtime-renderer';
|
|
5
6
|
import { staticProp } from '@elytracms/core/project-graph';
|
|
@@ -8,6 +9,8 @@ import { previewSpecs } from '@elytracms/studio/lib/registry/preview';
|
|
|
8
9
|
import { Badge, Button, Code, Field, Row, Spacer, Stack, Text } from '@elytracms/studio/ui';
|
|
9
10
|
import { localizedLabel, translate } from '@elytracms/studio/lib/i18n';
|
|
10
11
|
import { cn } from '@elytracms/studio/lib/utils';
|
|
12
|
+
import { getCanvasStylesheetUrl } from '../builder/canvas-stylesheet';
|
|
13
|
+
import { useCanvasViewports, viewportWidth } from '../builder/canvas-breakpoints';
|
|
11
14
|
import { PropValueControl } from '../cms/prop-fields';
|
|
12
15
|
/** Preview state for a manifest: the fixture selection + the live prop overrides. */
|
|
13
16
|
export function usePreviewState(manifest) {
|
|
@@ -61,13 +64,162 @@ export function ComponentPreview({ manifest, studio, state, }) {
|
|
|
61
64
|
const ctx = useMemo(() => previewContext(studio), [studio]);
|
|
62
65
|
const serverOnly = manifest.clientRenderable === false;
|
|
63
66
|
const status = componentStatus(studio, manifest);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
const displayName = manifest.title ?? manifest.id;
|
|
68
|
+
// EC-330: the same config-sourced breakpoint set the builder canvas toolbar
|
|
69
|
+
// offers (`canvas-breakpoints.ts`) — reused, not redefined, so a preview and
|
|
70
|
+
// the real canvas never disagree about the site's responsive widths.
|
|
71
|
+
// Defaults to the always-present 'full' (responsive) option.
|
|
72
|
+
const { viewports } = useCanvasViewports();
|
|
73
|
+
const [viewport, setViewport] = useState(viewports[0].key);
|
|
74
|
+
return (_jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [_jsxs(Row, { gap: "1", wrap: true, align: "center", className: "shrink-0 border-b border-border px-3 py-2", children: [state.specs.length > 1 ? (_jsx(Row, { gap: "1", wrap: true, role: "group", "aria-label": translate('components.fixtureRunner.statesAria'), children: state.specs.map((spec, i) => (_jsx("button", { type: "button", "aria-pressed": i === state.index, onClick: () => state.setIndex(i), className: cn('rounded-md px-2.5 py-1 text-xs font-medium transition-colors', i === state.index
|
|
75
|
+
? 'bg-accent text-accent-foreground'
|
|
76
|
+
: 'text-muted-foreground hover:bg-muted hover:text-foreground'), children: spec.name }, spec.name))) })) : null, _jsx(Spacer, {}), _jsx(Row, { gap: "1", wrap: true, role: "group", "aria-label": translate('components.preview.breakpointAria'), children: viewports.map((option) => (_jsx(PreviewBreakpointButton, { option: option, active: option.key === viewport, onSelect: () => setViewport(option.key) }, option.key))) }), state.dirty ? (_jsxs(Button, { variant: "ghost", size: "sm", onClick: state.resetAll, "data-testid": "preview-reset", children: [_jsx(RotateCcw, {}), " ", translate('components.preview.reset')] })) : null] }), _jsxs("div", { className: "canvas-grid min-h-0 flex-1 overflow-auto p-6", "data-fixture-state": state.specs[state.index]?.name, children: [serverOnly ? (_jsx(ServerOnlyNotice, {})) : (_jsx(ComponentPreviewFrame, { node: state.node, ctx: ctx, displayName: displayName, width: viewportWidth(viewports, viewport) })), status === 'incompatible' && !serverOnly ? (_jsx(Text, { size: "xs", tone: "muted", className: "mx-auto mt-3 max-w-2xl", children: translate('components.preview.incompatibleNote') })) : null] })] }));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* One breakpoint option in the preview's width switcher. Mirrors the builder
|
|
80
|
+
* canvas toolbar's `ViewportButton` (`composition-field-editor.tsx`) — same
|
|
81
|
+
* `Button`/active-state styling — but drives LOCAL preview state instead of
|
|
82
|
+
* the builder store (this surface has no composition/undo stack).
|
|
83
|
+
*/
|
|
84
|
+
function PreviewBreakpointButton({ option, active, onSelect, }) {
|
|
85
|
+
return (_jsx(Button, { size: "sm", variant: "ghost", "aria-label": translate('builder.canvas.viewportPreviewAria', { label: option.label }), "aria-pressed": active, title: option.px !== undefined
|
|
86
|
+
? `${option.label} · ${option.px}px`
|
|
87
|
+
: translate('builder.canvas.viewportWidthTitle', { label: option.label }), onClick: onSelect, className: cn('px-2 text-xs', active && 'bg-accent text-accent-foreground'), children: option.label }));
|
|
67
88
|
}
|
|
68
89
|
function ServerOnlyNotice() {
|
|
69
90
|
return (_jsx("div", { className: "mx-auto grid max-w-2xl place-items-center rounded-lg border border-dashed border-border bg-muted/30 p-8 text-center", children: _jsxs(Stack, { gap: "2", align: "center", children: [_jsx(MonitorOff, { className: "size-5 text-muted-foreground", "aria-hidden": true }), _jsx(Text, { size: "sm", weight: "medium", children: translate('components.preview.serverOnlyTitle') }), _jsx(Text, { size: "xs", tone: "muted", className: "max-w-sm", children: translate('components.preview.serverOnlyBody') })] }) }));
|
|
70
91
|
}
|
|
92
|
+
/** Floor for the auto-height iframe — never collapses to a sliver while empty/loading. */
|
|
93
|
+
const MIN_PREVIEW_HEIGHT = 360;
|
|
94
|
+
/**
|
|
95
|
+
* The live preview render surface. Reuses the BuilderCanvas styling mechanism
|
|
96
|
+
* (EC-061, `canvas.tsx`): the component renders inside an ISOLATED same-origin
|
|
97
|
+
* iframe that `<link>`s the project's canvas stylesheet
|
|
98
|
+
* (`getCanvasStylesheetUrl()` — the consuming app's delivery CSS + studio CSS), so
|
|
99
|
+
* a component built with the site's Tailwind theme previews with the site's styles,
|
|
100
|
+
* exactly as it does on the canvas and in delivery. Using the iframe (not the
|
|
101
|
+
* studio DOM) is what keeps the delivery CSS scoped and off the studio chrome.
|
|
102
|
+
*
|
|
103
|
+
* Unlike the builder canvas, this iframe's document is deliberately left OUT of
|
|
104
|
+
* the studio's own dark/light class: this is a standalone-component reference
|
|
105
|
+
* surface (not a full page), so its own negative space around the component must
|
|
106
|
+
* read as a light, site-like backdrop — never the studio chrome's current theme
|
|
107
|
+
* (a black frame is exactly what leaks through when the studio is dark-themed and
|
|
108
|
+
* the iframe root inherits that class). The canvas stylesheet's `:root` (light)
|
|
109
|
+
* tokens supply that backdrop for free once the `.dark` class is never added here.
|
|
110
|
+
*
|
|
111
|
+
* Sizing: width is driven by the caller (the breakpoint selector); height is
|
|
112
|
+
* measured live from the rendered content via `ResizeObserver` (EC-330) so a
|
|
113
|
+
* preset switch or a prop edit — both of which change what's portaled into
|
|
114
|
+
* `doc.body` — always show without clipping or dead space.
|
|
115
|
+
*
|
|
116
|
+
* The render is wrapped in {@link PreviewErrorBoundary} so a component that throws
|
|
117
|
+
* shows the EC-191 fallback instead of taking the whole Components view down.
|
|
118
|
+
*/
|
|
119
|
+
function ComponentPreviewFrame({ node, ctx, displayName, width, }) {
|
|
120
|
+
const iframeRef = useRef(null);
|
|
121
|
+
const [doc, setDoc] = useState(null);
|
|
122
|
+
const [height, setHeight] = useState(MIN_PREVIEW_HEIGHT);
|
|
123
|
+
const wireUp = useCallback(() => {
|
|
124
|
+
const d = iframeRef.current?.contentDocument;
|
|
125
|
+
if (!d || !d.body)
|
|
126
|
+
return;
|
|
127
|
+
// Deliberately no `.dark` here (see the surface note above) — the light
|
|
128
|
+
// `:root` tokens from the injected stylesheet are the intended backdrop.
|
|
129
|
+
// Unset stylesheet (tests / an app that never called
|
|
130
|
+
// `setCanvasStylesheetUrl`) → skip the link.
|
|
131
|
+
const appCss = getCanvasStylesheetUrl();
|
|
132
|
+
if (appCss && !d.getElementById('ec-app-css')) {
|
|
133
|
+
const link = d.createElement('link');
|
|
134
|
+
link.id = 'ec-app-css';
|
|
135
|
+
link.rel = 'stylesheet';
|
|
136
|
+
link.href = appCss;
|
|
137
|
+
d.head.appendChild(link);
|
|
138
|
+
}
|
|
139
|
+
d.body.className = 'bg-background text-foreground font-sans';
|
|
140
|
+
d.body.style.margin = '0';
|
|
141
|
+
d.body.style.padding = '24px';
|
|
142
|
+
setDoc(d);
|
|
143
|
+
}, []);
|
|
144
|
+
// Handle the already-loaded case (srcDoc can load before onLoad attaches).
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
if (iframeRef.current?.contentDocument?.readyState === 'complete')
|
|
147
|
+
wireUp();
|
|
148
|
+
}, [wireUp]);
|
|
149
|
+
// Auto-height (EC-330): a same-origin iframe exposes its own document, so a
|
|
150
|
+
// `ResizeObserver` on the BODY tracks its live (height: auto) content size —
|
|
151
|
+
// re-firing on its own whenever the portaled render changes (preset switch,
|
|
152
|
+
// prop edit), no manual re-measure wiring needed. Attached per `doc` (re-runs
|
|
153
|
+
// whenever the iframe reloads), not just on mount. Loop-safety: the observed
|
|
154
|
+
// element (the iframe's body) is never the element this effect resizes (the
|
|
155
|
+
// IFRAME itself) — writing height never feeds back into the observed box, and
|
|
156
|
+
// width is never derived from height, so there is no growth loop. Guarded for
|
|
157
|
+
// environments without ResizeObserver (jsdom/tests, older embeds).
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
const body = doc?.body;
|
|
160
|
+
if (!body || typeof ResizeObserver === 'undefined')
|
|
161
|
+
return;
|
|
162
|
+
const measure = () => setHeight(Math.max(body.scrollHeight, MIN_PREVIEW_HEIGHT));
|
|
163
|
+
measure();
|
|
164
|
+
const observer = new ResizeObserver(measure);
|
|
165
|
+
observer.observe(body);
|
|
166
|
+
return () => observer.disconnect();
|
|
167
|
+
}, [doc]);
|
|
168
|
+
return (_jsxs(_Fragment, { children: [_jsx("iframe", { ref: iframeRef, onLoad: wireUp, title: translate('components.detail.tab.preview'), style: { width, height, maxWidth: '100%' }, className: "mx-auto block rounded-lg border border-border bg-background shadow-sm", srcDoc: "<!doctype html><html><head></head><body></body></html>" }), doc
|
|
169
|
+
? createPortal(_jsx(PreviewErrorBoundary, { displayName: displayName, resetKey: node, children: _jsx(PreviewLiveRender, { node: node, ctx: ctx }) }), doc.body)
|
|
170
|
+
: null] }));
|
|
171
|
+
}
|
|
172
|
+
/** Renders the node through the runtime renderer, INSIDE a component render so the
|
|
173
|
+
* error boundary catches synchronous render throws (mirrors the blocks-panel
|
|
174
|
+
* thumbnail's `LiveRender`). */
|
|
175
|
+
function PreviewLiveRender({ node, ctx }) {
|
|
176
|
+
return _jsx(_Fragment, { children: renderNode(node, ctx) });
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* EC-191 resilience for the Components view: a component whose render throws — a
|
|
180
|
+
* missing provider/context (e.g. a prop control that needs a document's
|
|
181
|
+
* `CollectionViewSource`), a runtime bug — shows the documented "preview
|
|
182
|
+
* unavailable" fallback ({@link PreviewUnavailable}) instead of taking the whole
|
|
183
|
+
* view down. It resets when the previewed `resetKey` (the node) changes, so
|
|
184
|
+
* switching the fixture state or editing a prop retries the render.
|
|
185
|
+
*/
|
|
186
|
+
export class PreviewErrorBoundary extends Component {
|
|
187
|
+
state = { error: null };
|
|
188
|
+
static getDerivedStateFromError(error) {
|
|
189
|
+
return { error };
|
|
190
|
+
}
|
|
191
|
+
componentDidUpdate(prev) {
|
|
192
|
+
if (this.state.error && prev.resetKey !== this.props.resetKey) {
|
|
193
|
+
this.setState({ error: null });
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
render() {
|
|
197
|
+
if (this.state.error) {
|
|
198
|
+
return _jsx(PreviewUnavailable, { displayName: this.props.displayName, error: this.state.error });
|
|
199
|
+
}
|
|
200
|
+
return this.props.children;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* The EC-191 fallback panel — component name + "preview unavailable" + the error.
|
|
205
|
+
* Rendered INTO the preview iframe (which carries only the project stylesheet, and
|
|
206
|
+
* may carry none in tests), so it uses inline styles rather than studio UI classes
|
|
207
|
+
* — matching the canvas's own in-iframe placeholder convention.
|
|
208
|
+
*/
|
|
209
|
+
export function PreviewUnavailable({ displayName, error }) {
|
|
210
|
+
return (_jsxs("div", { "data-preview-unavailable": true, style: {
|
|
211
|
+
boxSizing: 'border-box',
|
|
212
|
+
maxWidth: '42rem',
|
|
213
|
+
margin: '0 auto',
|
|
214
|
+
border: '1px dashed rgba(120,120,120,0.5)',
|
|
215
|
+
borderRadius: 8,
|
|
216
|
+
padding: '24px 28px',
|
|
217
|
+
background: 'rgba(127,127,127,0.06)',
|
|
218
|
+
color: 'rgba(90,90,90,0.95)',
|
|
219
|
+
font: '14px/1.5 system-ui, -apple-system, sans-serif',
|
|
220
|
+
textAlign: 'center',
|
|
221
|
+
}, children: [_jsxs("div", { style: { fontWeight: 600 }, children: ["\u26A0 ", translate('components.preview.unavailableTitle')] }), _jsx("div", { style: { marginTop: 4, fontWeight: 600, opacity: 0.9 }, children: displayName }), _jsx("div", { style: { marginTop: 6, fontSize: 13, opacity: 0.85, wordBreak: 'break-word' }, children: error.message })] }));
|
|
222
|
+
}
|
|
71
223
|
/**
|
|
72
224
|
* The editable Props pane (right inspector). Every non-`blocks` prop is edited
|
|
73
225
|
* through the shared {@link PropValueControl} — the exact control set documents
|