summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src/components/diff.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/ui/src/components/diff.tsx')
-rw-r--r--packages/ui/src/components/diff.tsx76
1 files changed, 17 insertions, 59 deletions
diff --git a/packages/ui/src/components/diff.tsx b/packages/ui/src/components/diff.tsx
index 344ce3c8e..c895a6e29 100644
--- a/packages/ui/src/components/diff.tsx
+++ b/packages/ui/src/components/diff.tsx
@@ -1,7 +1,8 @@
import { type FileContents, FileDiff, type DiffLineAnnotation, FileDiffOptions } from "@pierre/precision-diffs"
import { PreloadMultiFileDiffResult } from "@pierre/precision-diffs/ssr"
-import { ComponentProps, createEffect, onCleanup, onMount, splitProps } from "solid-js"
+import { ComponentProps, createEffect, onCleanup, onMount, Show, splitProps } from "solid-js"
import { isServer } from "solid-js/web"
+import { createDefaultOptions, styleVariables } from "./pierre"
export type DiffProps<T = {}> = FileDiffOptions<T> & {
preloadedDiff?: PreloadMultiFileDiffResult<T>
@@ -15,6 +16,8 @@ export type DiffProps<T = {}> = FileDiffOptions<T> & {
// interface ThreadMetadata {
// threadId: string
// }
+//
+//
export function Diff<T>(props: DiffProps<T>) {
let container!: HTMLDivElement
@@ -24,27 +27,12 @@ export function Diff<T>(props: DiffProps<T>) {
let fileDiffInstance: FileDiff<T> | undefined
const cleanupFunctions: Array<() => void> = []
- const defaultOptions: FileDiffOptions<T> = {
- theme: "OpenCode",
- themeType: "system",
- disableLineNumbers: false,
- overflow: "wrap",
- diffStyle: "unified",
- diffIndicators: "bars",
- disableBackground: false,
- expansionLineCount: 20,
- lineDiffType: props.diffStyle === "split" ? "word-alt" : "none",
- maxLineDiffLength: 1000,
- maxLineLengthForHighlighting: 1000,
- disableFileHeader: true,
- }
-
createEffect(() => {
if (props.preloadedDiff) return
container.innerHTML = ""
if (!fileDiffInstance) {
fileDiffInstance = new FileDiff<T>({
- ...defaultOptions,
+ ...createDefaultOptions(props.diffStyle),
...others,
...(props.preloadedDiff ?? {}),
})
@@ -60,22 +48,19 @@ export function Diff<T>(props: DiffProps<T>) {
onMount(() => {
if (isServer) return
fileDiffInstance = new FileDiff<T>({
- ...defaultOptions,
- // You can optionally pass a render function for rendering out line
- // annotations. Just return the dom node to render
- // renderAnnotation(annotation: DiffLineAnnotation<T>): HTMLElement {
- // // Despite the diff itself being rendered in the shadow dom,
- // // annotations are inserted via the web components 'slots' api and you
- // // can use all your normal normal css and styling for them
- // const element = document.createElement("div")
- // element.innerText = annotation.metadata.threadId
- // return element
- // },
+ ...createDefaultOptions(props.diffStyle),
...others,
...(props.preloadedDiff ?? {}),
})
// @ts-expect-error - fileContainer is private but needed for SSR hydration
fileDiffInstance.fileContainer = fileDiffRef
+ fileDiffInstance.hydrate({
+ oldFile: local.before,
+ newFile: local.after,
+ lineAnnotations: local.annotations,
+ fileContainer: fileDiffRef,
+ containerWrapper: container,
+ })
// Hydrate annotation slots with interactive SolidJS components
// if (props.annotations.length > 0 && props.renderAnnotation != null) {
@@ -108,38 +93,11 @@ export function Diff<T>(props: DiffProps<T>) {
})
return (
- <div
- data-component="diff"
- style={{
- "--pjs-font-family": "var(--font-family-mono)",
- "--pjs-font-size": "var(--font-size-small)",
- "--pjs-line-height": "24px",
- "--pjs-tab-size": 2,
- "--pjs-font-features": "var(--font-family-mono--font-feature-settings)",
- "--pjs-header-font-family": "var(--font-family-sans)",
- "--pjs-gap-block": 0,
- "--pjs-min-number-column-width": "4ch",
- }}
- ref={container}
- >
+ <div data-component="diff" style={styleVariables} ref={container}>
<file-diff ref={fileDiffRef} id="ssr-diff">
- {/* Only render on server - client hydrates the existing content */}
- {isServer && props.preloadedDiff && (
- <>
- {/* Declarative Shadow DOM - browsers parse this and create a shadow root */}
- <template shadowrootmode="open">
- <div innerHTML={props.preloadedDiff!.prerenderedHTML} />
- </template>
- {/* Render static annotation slots on server.
- Client will clear these and mount interactive components. */}
- {/* <For each={props.annotations}> */}
- {/* {(annotation) => { */}
- {/* const slotName = `annotation-${annotation.side}-${annotation.lineNumber}` */}
- {/* return <div slot={slotName}>{props.renderAnnotation?.(annotation)}</div> */}
- {/* }} */}
- {/* </For> */}
- </>
- )}
+ <Show when={isServer && props.preloadedDiff}>
+ {(preloadedDiff) => <template shadowrootmode="open" innerHTML={preloadedDiff().prerenderedHTML} />}
+ </Show>
</file-diff>
</div>
)