@elytracms/studio 0.0.39 → 0.0.40
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 +58 -27
- 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/link-control.js +3 -1
- package/dist/components/cms/rich-text/link-control.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 +48 -20
- 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 +102 -3
- package/dist/components/components/component-preview.js.map +1 -1
- package/dist/lib/i18n/messages.en.js +15 -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. */\nconst DIFF_ROW_GRID = 'grid grid-cols-[7.5rem_1fr] 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.39: the restore control is right-aligned at the TOP of the descriptor\n lane — one consistent place across every row type (never stacked under the\n label). The descriptor (label + locale/kind) sits to its left. */}\n <div className=\"flex items-start justify-between gap-1\">\n <div className=\"min-w-0\">{descriptor}</div>\n {restore ? <div className=\"shrink-0\">{restore}</div> : null}\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 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,7 @@ 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';
|
|
11
13
|
import { PropValueControl } from '../cms/prop-fields';
|
|
12
14
|
/** Preview state for a manifest: the fixture selection + the live prop overrides. */
|
|
13
15
|
export function usePreviewState(manifest) {
|
|
@@ -61,13 +63,110 @@ export function ComponentPreview({ manifest, studio, state, }) {
|
|
|
61
63
|
const ctx = useMemo(() => previewContext(studio), [studio]);
|
|
62
64
|
const serverOnly = manifest.clientRenderable === false;
|
|
63
65
|
const status = componentStatus(studio, manifest);
|
|
66
|
+
const displayName = manifest.title ?? manifest.id;
|
|
64
67
|
return (_jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [state.specs.length > 1 ? (_jsxs(Row, { gap: "1", wrap: true, className: "shrink-0 border-b border-border px-3 py-2", 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
|
|
65
68
|
? 'bg-accent text-accent-foreground'
|
|
66
|
-
: 'text-muted-foreground hover:bg-muted hover:text-foreground'), children: spec.name }, spec.name))), _jsx(Spacer, {}), state.dirty ? (_jsxs(Button, { variant: "ghost", size: "sm", onClick: state.resetAll, "data-testid": "preview-reset", children: [_jsx(RotateCcw, {}), " ", translate('components.preview.reset')] })) : null] })) : 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(
|
|
69
|
+
: 'text-muted-foreground hover:bg-muted hover:text-foreground'), children: spec.name }, spec.name))), _jsx(Spacer, {}), state.dirty ? (_jsxs(Button, { variant: "ghost", size: "sm", onClick: state.resetAll, "data-testid": "preview-reset", children: [_jsx(RotateCcw, {}), " ", translate('components.preview.reset')] })) : null] })) : 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 })), status === 'incompatible' && !serverOnly ? (_jsx(Text, { size: "xs", tone: "muted", className: "mx-auto mt-3 max-w-2xl", children: translate('components.preview.incompatibleNote') })) : null] })] }));
|
|
67
70
|
}
|
|
68
71
|
function ServerOnlyNotice() {
|
|
69
72
|
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
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* The live preview render surface. Reuses the BuilderCanvas styling mechanism
|
|
76
|
+
* (EC-061, `canvas.tsx`): the component renders inside an ISOLATED same-origin
|
|
77
|
+
* iframe that `<link>`s the project's canvas stylesheet
|
|
78
|
+
* (`getCanvasStylesheetUrl()` — the consuming app's delivery CSS + studio CSS), so
|
|
79
|
+
* a component built with the site's Tailwind theme previews with the site's styles,
|
|
80
|
+
* exactly as it does on the canvas and in delivery. Using the iframe (not the
|
|
81
|
+
* studio DOM) is what keeps the delivery CSS scoped and off the studio chrome.
|
|
82
|
+
*
|
|
83
|
+
* The render is wrapped in {@link PreviewErrorBoundary} so a component that throws
|
|
84
|
+
* shows the EC-191 fallback instead of taking the whole Components view down.
|
|
85
|
+
*/
|
|
86
|
+
function ComponentPreviewFrame({ node, ctx, displayName, }) {
|
|
87
|
+
const iframeRef = useRef(null);
|
|
88
|
+
const [doc, setDoc] = useState(null);
|
|
89
|
+
const wireUp = useCallback(() => {
|
|
90
|
+
const d = iframeRef.current?.contentDocument;
|
|
91
|
+
if (!d || !d.body)
|
|
92
|
+
return;
|
|
93
|
+
// The SAME injection the canvas performs: the studio is dark-themed, and the
|
|
94
|
+
// delivery stylesheet is scoped to this iframe alone (no chrome leak). Unset
|
|
95
|
+
// (tests / an app that never called `setCanvasStylesheetUrl`) → skip the link.
|
|
96
|
+
d.documentElement.classList.add('dark');
|
|
97
|
+
const appCss = getCanvasStylesheetUrl();
|
|
98
|
+
if (appCss && !d.getElementById('ec-app-css')) {
|
|
99
|
+
const link = d.createElement('link');
|
|
100
|
+
link.id = 'ec-app-css';
|
|
101
|
+
link.rel = 'stylesheet';
|
|
102
|
+
link.href = appCss;
|
|
103
|
+
d.head.appendChild(link);
|
|
104
|
+
}
|
|
105
|
+
d.body.className = 'bg-background text-foreground font-sans';
|
|
106
|
+
d.body.style.margin = '0';
|
|
107
|
+
d.body.style.padding = '24px';
|
|
108
|
+
setDoc(d);
|
|
109
|
+
}, []);
|
|
110
|
+
// Handle the already-loaded case (srcDoc can load before onLoad attaches).
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
if (iframeRef.current?.contentDocument?.readyState === 'complete')
|
|
113
|
+
wireUp();
|
|
114
|
+
}, [wireUp]);
|
|
115
|
+
return (_jsxs(_Fragment, { children: [_jsx("iframe", { ref: iframeRef, onLoad: wireUp, title: translate('components.detail.tab.preview'), className: "mx-auto block min-h-[360px] w-full max-w-2xl rounded-lg border border-border bg-background shadow-sm", srcDoc: "<!doctype html><html><head></head><body></body></html>" }), doc
|
|
116
|
+
? createPortal(_jsx(PreviewErrorBoundary, { displayName: displayName, resetKey: node, children: _jsx(PreviewLiveRender, { node: node, ctx: ctx }) }), doc.body)
|
|
117
|
+
: null] }));
|
|
118
|
+
}
|
|
119
|
+
/** Renders the node through the runtime renderer, INSIDE a component render so the
|
|
120
|
+
* error boundary catches synchronous render throws (mirrors the blocks-panel
|
|
121
|
+
* thumbnail's `LiveRender`). */
|
|
122
|
+
function PreviewLiveRender({ node, ctx }) {
|
|
123
|
+
return _jsx(_Fragment, { children: renderNode(node, ctx) });
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* EC-191 resilience for the Components view: a component whose render throws — a
|
|
127
|
+
* missing provider/context (e.g. a prop control that needs a document's
|
|
128
|
+
* `CollectionViewSource`), a runtime bug — shows the documented "preview
|
|
129
|
+
* unavailable" fallback ({@link PreviewUnavailable}) instead of taking the whole
|
|
130
|
+
* view down. It resets when the previewed `resetKey` (the node) changes, so
|
|
131
|
+
* switching the fixture state or editing a prop retries the render.
|
|
132
|
+
*/
|
|
133
|
+
export class PreviewErrorBoundary extends Component {
|
|
134
|
+
state = { error: null };
|
|
135
|
+
static getDerivedStateFromError(error) {
|
|
136
|
+
return { error };
|
|
137
|
+
}
|
|
138
|
+
componentDidUpdate(prev) {
|
|
139
|
+
if (this.state.error && prev.resetKey !== this.props.resetKey) {
|
|
140
|
+
this.setState({ error: null });
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
render() {
|
|
144
|
+
if (this.state.error) {
|
|
145
|
+
return _jsx(PreviewUnavailable, { displayName: this.props.displayName, error: this.state.error });
|
|
146
|
+
}
|
|
147
|
+
return this.props.children;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* The EC-191 fallback panel — component name + "preview unavailable" + the error.
|
|
152
|
+
* Rendered INTO the preview iframe (which carries only the project stylesheet, and
|
|
153
|
+
* may carry none in tests), so it uses inline styles rather than studio UI classes
|
|
154
|
+
* — matching the canvas's own in-iframe placeholder convention.
|
|
155
|
+
*/
|
|
156
|
+
export function PreviewUnavailable({ displayName, error }) {
|
|
157
|
+
return (_jsxs("div", { "data-preview-unavailable": true, style: {
|
|
158
|
+
boxSizing: 'border-box',
|
|
159
|
+
maxWidth: '42rem',
|
|
160
|
+
margin: '0 auto',
|
|
161
|
+
border: '1px dashed rgba(120,120,120,0.5)',
|
|
162
|
+
borderRadius: 8,
|
|
163
|
+
padding: '24px 28px',
|
|
164
|
+
background: 'rgba(127,127,127,0.06)',
|
|
165
|
+
color: 'rgba(90,90,90,0.95)',
|
|
166
|
+
font: '14px/1.5 system-ui, -apple-system, sans-serif',
|
|
167
|
+
textAlign: 'center',
|
|
168
|
+
}, 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 })] }));
|
|
169
|
+
}
|
|
71
170
|
/**
|
|
72
171
|
* The editable Props pane (right inspector). Every non-`blocks` prop is edited
|
|
73
172
|
* through the shared {@link PropValueControl} — the exact control set documents
|