diff options
| author | Jay V <[email protected]> | 2025-06-26 13:06:37 -0400 |
|---|---|---|
| committer | Jay V <[email protected]> | 2025-06-26 13:06:41 -0400 |
| commit | e6bfa95758d242e9ecb332f1e0e8fd3b8c5f83f9 (patch) | |
| tree | a18130900073f51a476b3a68956ac9f04798c9c3 /packages/web/src/components | |
| parent | e4120b628799288419fec9606604066011b649a4 (diff) | |
| download | opencode-e6bfa95758d242e9ecb332f1e0e8fd3b8c5f83f9.tar.gz opencode-e6bfa95758d242e9ecb332f1e0e8fd3b8c5f83f9.zip | |
docs: share page responsive diff
Diffstat (limited to 'packages/web/src/components')
| -rw-r--r-- | packages/web/src/components/DiffView.tsx | 191 | ||||
| -rw-r--r-- | packages/web/src/components/diffview.module.css | 33 | ||||
| -rw-r--r-- | packages/web/src/components/markdownview.module.css | 2 |
3 files changed, 139 insertions, 87 deletions
diff --git a/packages/web/src/components/DiffView.tsx b/packages/web/src/components/DiffView.tsx index 237f25bdf..66dd7f0fc 100644 --- a/packages/web/src/components/DiffView.tsx +++ b/packages/web/src/components/DiffView.tsx @@ -54,8 +54,8 @@ const DiffView: Component<DiffViewProps> = (props) => { // Pair removals with additions const maxLength = Math.max(removals.length, additions.length) for (let k = 0; k < maxLength; k++) { - const hasLeft = !!removals[k] - const hasRight = !!additions[k] + const hasLeft = k < removals.length + const hasRight = k < additions.length if (hasLeft && hasRight) { // Replacement - left is removed, right is added @@ -71,8 +71,8 @@ const DiffView: Component<DiffViewProps> = (props) => { right: "", type: "removed" }) - } else { - // Pure addition + } else if (hasRight) { + // Pure addition - only create if we actually have content diffRows.push({ left: "", right: additions[k], @@ -111,85 +111,136 @@ const DiffView: Component<DiffViewProps> = (props) => { return diffRows }) + const mobileRows = createMemo(() => { + const mobileBlocks: { type: 'removed' | 'added' | 'unchanged', lines: string[] }[] = [] + const currentRows = rows() + + let i = 0 + while (i < currentRows.length) { + const removedLines: string[] = [] + const addedLines: string[] = [] + + // Collect consecutive modified/removed/added rows + while (i < currentRows.length && + (currentRows[i].type === 'modified' || + currentRows[i].type === 'removed' || + currentRows[i].type === 'added')) { + const row = currentRows[i] + if (row.left && (row.type === 'removed' || row.type === 'modified')) { + removedLines.push(row.left) + } + if (row.right && (row.type === 'added' || row.type === 'modified')) { + addedLines.push(row.right) + } + i++ + } + + // Add grouped blocks + if (removedLines.length > 0) { + mobileBlocks.push({ type: 'removed', lines: removedLines }) + } + if (addedLines.length > 0) { + mobileBlocks.push({ type: 'added', lines: addedLines }) + } + + // Add unchanged rows as-is + if (i < currentRows.length && currentRows[i].type === 'unchanged') { + mobileBlocks.push({ + type: 'unchanged', + lines: [currentRows[i].left] + }) + i++ + } + } + + return mobileBlocks + }) + return ( <div class={`${styles.diff} ${props.class ?? ""}`}> - {rows().map((r) => ( - <div class={styles.row}> - <div class={styles.beforeColumn}> - <CodeBlock - code={r.left} - lang={props.lang} - data-section="cell" - data-diff-type={r.type === "removed" || r.type === "modified" ? "removed" : ""} - data-display-mobile={r.type === "added" && !r.left ? "false" : undefined} - /> - {(r.type === "added" || r.type === "modified") && r.right !== undefined && ( + <div class={styles.desktopView}> + {rows().map((r) => ( + <div class={styles.row}> + <div class={styles.beforeColumn}> + <CodeBlock + code={r.left} + lang={props.lang} + data-section="cell" + data-diff-type={r.type === "removed" || r.type === "modified" ? "removed" : ""} + /> + </div> + <div class={styles.afterColumn}> <CodeBlock code={r.right} lang={props.lang} data-section="cell" - data-diff-type="added" - data-display-mobile="true" + data-diff-type={r.type === "added" || r.type === "modified" ? "added" : ""} /> - )} + </div> </div> + ))} + </div> - <div class={styles.afterColumn}> - <CodeBlock - code={r.right} - lang={props.lang} - data-section="cell" - data-diff-type={r.type === "added" || r.type === "modified" ? "added" : ""} - /> + <div class={styles.mobileView}> + {mobileRows().map((block) => ( + <div class={styles.mobileBlock}> + {block.lines.map((line) => ( + <CodeBlock + code={line} + lang={props.lang} + data-section="cell" + data-diff-type={block.type === 'removed' ? 'removed' : + block.type === 'added' ? 'added' : ''} + /> + ))} </div> - </div> - ))} + ))} + </div> </div> ) } export default DiffView -// String to test diff viewer with -const testDiff = `--- combined_before.txt 2025-06-24 16:38:08 -+++ combined_after.txt 2025-06-24 16:38:12 -@@ -1,21 +1,25 @@ - unchanged line --deleted line --old content -+added line -+new content - --removed empty line below -+added empty line above - -- tab indented --trailing spaces --very long line that will definitely wrap in most editors and cause potential alignment issues when displayed in a two column diff view --unicode content: π β¨ δΈζ --mixed content with tabs and spaces -+ space indented -+no trailing spaces -+short line -+very long replacement line that will also wrap and test how the diff viewer handles long line additions after short line removals -+different unicode: π π» ζ₯ζ¬θͺ -+normalized content with consistent spacing -+newline to content - --content to remove --whitespace only: --multiple --consecutive --deletions --single deletion -+ -+single addition -+first addition -+second addition -+third addition - line before addition -+first added line -+ -+third added line - line after addition - final unchanged line` +// const testDiff = `--- combined_before.txt 2025-06-24 16:38:08 +// +++ combined_after.txt 2025-06-24 16:38:12 +// @@ -1,21 +1,25 @@ +// unchanged line +// -deleted line +// -old content +// +added line +// +new content +// +// -removed empty line below +// +added empty line above +// +// - tab indented +// -trailing spaces +// -very long line that will definitely wrap in most editors and cause potential alignment issues when displayed in a two column diff view +// -unicode content: π β¨ δΈζ +// -mixed content with tabs and spaces +// + space indented +// +no trailing spaces +// +short line +// +very long replacement line that will also wrap and test how the diff viewer handles long line additions after short line removals +// +different unicode: π π» ζ₯ζ¬θͺ +// +normalized content with consistent spacing +// +newline to content +// +// -content to remove +// -whitespace only: +// -multiple +// -consecutive +// -deletions +// -single deletion +// + +// +single addition +// +first addition +// +second addition +// +third addition +// line before addition +// +first added line +// + +// +third added line +// line after addition +// final unchanged line` diff --git a/packages/web/src/components/diffview.module.css b/packages/web/src/components/diffview.module.css index b3f61ac02..a748c5d02 100644 --- a/packages/web/src/components/diffview.module.css +++ b/packages/web/src/components/diffview.module.css @@ -6,6 +6,19 @@ border-radius: 0.25rem; } +.desktopView { + display: block; +} + +.mobileView { + display: none; +} + +.mobileBlock { + display: flex; + flex-direction: column; +} + .row { display: grid; grid-template-columns: 1fr 1fr; @@ -98,25 +111,11 @@ } @media (max-width: 40rem) { - .row { - grid-template-columns: 1fr; - } - - .afterColumn { + .desktopView { display: none; } - .beforeColumn { - border-right: none; - } - - [data-section="cell"] { - &[data-display-mobile="true"] { - display: flex; - } - - &[data-display-mobile="false"] { - display: none; - } + .mobileView { + display: block; } } diff --git a/packages/web/src/components/markdownview.module.css b/packages/web/src/components/markdownview.module.css index 37a10dfa9..a4360bde9 100644 --- a/packages/web/src/components/markdownview.module.css +++ b/packages/web/src/components/markdownview.module.css @@ -30,6 +30,8 @@ h4, h5, h6 { + font-size: 0.875rem; + font-weight: 600; margin-bottom: 0.5rem; } |
