mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
4bbb0f3aff
Adds components/MarkdownDiff.tsx, a theme-bridging shim over @plannotator/markdown-editor's frozen two-revision diff, mirroring the MarkdownEditor shim exactly: ThemeProvider mode bridge, plannotator.css theme import, extensions passthrough (wikiLinks composes), gridEnabled -> the same design-system card chrome. Hosts import it from @plannotator/ui/components/MarkdownDiff; AtomicDiffEditor and @plannotator/atomic-editor stay off the allowlist. Deps: @plannotator/markdown-editor ^0.4.0, @plannotator/atomic-editor ^0.8.0 (single lockfile copy each), plus @codemirror/merge — the engine's new required peer — declared directly per the CM6 single-copy discipline. Tests pin the seam end-to-end: public export surface + types, byte-exact getMarkdown()/getOriginalMarkdown() incl. CRLF/trailing-space fixtures, contenteditable="false" frozen contract, change navigation, wiki-link composition through the shim, and theme/host-class forwarding. The strict-consumer tsconfig now typechecks the new module.
64 lines
2.5 KiB
TypeScript
64 lines
2.5 KiB
TypeScript
/**
|
|
* Re-export surface test: hosts import MarkdownDiff (and its handle/prop
|
|
* types) from @plannotator/ui's MarkdownDiff module — never from
|
|
* @plannotator/markdown-editor's MarkdownDiff or @plannotator/atomic-editor's
|
|
* AtomicDiffEditor directly (both are outside the consumer import allowlist).
|
|
*
|
|
* Runs without DOM: it pins availability and the type surface, not diff
|
|
* behavior (the mounted surface is covered by MarkdownDiff.frozen.test.tsx).
|
|
*/
|
|
import { describe, test, expect } from 'bun:test';
|
|
import { EditorView } from '@codemirror/view';
|
|
import { MarkdownDiff, type MarkdownDiffHandle, type MarkdownDiffProps } from './MarkdownDiff';
|
|
import { wikiLinks } from './MarkdownEditor';
|
|
|
|
describe('MarkdownDiff module: public re-export surface', () => {
|
|
test('MarkdownDiff is exported as a renderable component', () => {
|
|
expect(typeof MarkdownDiff).toBe('function');
|
|
});
|
|
|
|
test('the handle type round-trips through the ui surface', () => {
|
|
// Compile-time assertion: fails typecheck (not just this test) if the
|
|
// re-exported handle drifts from the engine's navigation/byte contract.
|
|
const handle: MarkdownDiffHandle = {
|
|
goToNextChange: () => true,
|
|
goToPreviousChange: () => false,
|
|
getMarkdown: () => 'newer',
|
|
getOriginalMarkdown: () => 'older',
|
|
getChangeCount: () => 1,
|
|
getContentDOM: () => null,
|
|
};
|
|
expect(handle.getMarkdown()).toBe('newer');
|
|
expect(handle.getOriginalMarkdown()).toBe('older');
|
|
});
|
|
|
|
test('the props type round-trips, including the extensions seam', () => {
|
|
// Compile-time assertions: the shim keeps the packaged prop surface
|
|
// (minus mode/cardClassName, which the shim owns) and adds gridEnabled.
|
|
// wikiLinks comes from the ui MarkdownEditor surface and must be
|
|
// assignable to the diff's extensions seam so consumer extensions compose.
|
|
const props: MarkdownDiffProps = {
|
|
originalMarkdown: 'older\n',
|
|
modifiedMarkdown: 'newer\n',
|
|
documentId: 'doc-1',
|
|
ariaLabel: 'Document changes',
|
|
showToolbar: true,
|
|
showOverview: true,
|
|
gutter: true,
|
|
allowInlineDiffs: true,
|
|
highlightChanges: true,
|
|
syntaxHighlightDeletions: true,
|
|
gridEnabled: true,
|
|
mode: 'light',
|
|
maxWidth: 720,
|
|
className: 'host-outer',
|
|
onLinkClick: () => {},
|
|
extensions: [
|
|
wikiLinks({ suggest: async () => [], resolve: async () => null }),
|
|
EditorView.editorAttributes.of({ 'data-host-probe': 'ok' }),
|
|
],
|
|
};
|
|
expect(props.modifiedMarkdown).toBe('newer\n');
|
|
});
|
|
});
|