Просмотр исходного кода

docs: Share page diff view improvements (#373)

Jay 8 месяцев назад
Родитель
Сommit
a2d3b9f0c8
2 измененных файлов с 126 добавлено и 35 удалено
  1. 75 21
      packages/web/src/components/DiffView.tsx
  2. 51 14
      packages/web/src/components/diffview.module.css

+ 75 - 21
packages/web/src/components/DiffView.tsx

@@ -113,29 +113,83 @@ const DiffView: Component<DiffViewProps> = (props) => {
 
 
   return (
   return (
     <div class={`${styles.diff} ${props.class ?? ""}`}>
     <div class={`${styles.diff} ${props.class ?? ""}`}>
-      <div class={styles.column}>
-        {rows().map((r) => (
-          <CodeBlock
-            code={r.left}
-            lang={props.lang}
-            data-section="cell"
-            data-diff-type={r.type === "removed" || r.type === "modified" ? "removed" : ""}
-          />
-        ))}
-      </div>
-
-      <div class={styles.column}>
-        {rows().map((r) => (
-          <CodeBlock
-            code={r.right}
-            lang={props.lang}
-            data-section="cell"
-            data-diff-type={r.type === "added" || r.type === "modified" ? "added" : ""}
-          />
-        ))}
-      </div>
+      {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 && (
+              <CodeBlock
+                code={r.right}
+                lang={props.lang}
+                data-section="cell"
+                data-diff-type="added"
+                data-display-mobile="true"
+              />
+            )}
+          </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>
+        </div>
+      ))}
     </div>
     </div>
   )
   )
 }
 }
 
 
 export default DiffView
 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`

+ 51 - 14
packages/web/src/components/diffview.module.css

@@ -1,39 +1,52 @@
 .diff {
 .diff {
-  display: grid;
-  grid-template-columns: 1fr 1fr;
+  display: flex;
+  flex-direction: column;
   border: 1px solid var(--sl-color-divider);
   border: 1px solid var(--sl-color-divider);
   background-color: var(--sl-color-bg-surface);
   background-color: var(--sl-color-bg-surface);
   border-radius: 0.25rem;
   border-radius: 0.25rem;
 }
 }
 
 
-.column {
+.row {
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+  align-items: stretch;
+}
+
+.beforeColumn,
+.afterColumn {
   display: flex;
   display: flex;
   flex-direction: column;
   flex-direction: column;
-
   overflow-x: visible;
   overflow-x: visible;
   min-width: 0;
   min-width: 0;
   align-items: stretch;
   align-items: stretch;
+}
 
 
-  &:first-child {
-    border-right: 1px solid var(--sl-color-divider);
-  }
+.beforeColumn {
+  border-right: 1px solid var(--sl-color-divider);
+}
 
 
-  & > [data-section="cell"]:first-child {
-    padding-top: 0.5rem;
-  }
-  & > [data-section="cell"]:last-child {
-    padding-bottom: 0.5rem;
-  }
+.diff > .row:first-child [data-section="cell"]:first-child {
+  padding-top: 0.5rem;
+}
+
+.diff > .row:last-child [data-section="cell"]:last-child {
+  padding-bottom: 0.5rem;
 }
 }
 
 
 [data-section="cell"] {
 [data-section="cell"] {
   position: relative;
   position: relative;
-  flex: none;
+  flex: 1;
+  display: flex;
+  flex-direction: column;
 
 
   width: 100%;
   width: 100%;
   padding: 0.1875rem 0.5rem 0.1875rem 2.2ch;
   padding: 0.1875rem 0.5rem 0.1875rem 2.2ch;
   margin: 0;
   margin: 0;
 
 
+  &[data-display-mobile="true"] {
+    display: none;
+  }
+
   pre {
   pre {
     --shiki-dark-bg: var(--sl-color-bg-surface) !important;
     --shiki-dark-bg: var(--sl-color-bg-surface) !important;
     background-color: var(--sl-color-bg-surface) !important;
     background-color: var(--sl-color-bg-surface) !important;
@@ -83,3 +96,27 @@
     color: var(--sl-color-green-high);
     color: var(--sl-color-green-high);
   }
   }
 }
 }
+
+@media (max-width: 40rem) {
+  .row {
+    grid-template-columns: 1fr;
+  }
+
+  .afterColumn {
+    display: none;
+  }
+
+  .beforeColumn {
+    border-right: none;
+  }
+
+  [data-section="cell"] {
+    &[data-display-mobile="true"] {
+      display: flex;
+    }
+
+    &[data-display-mobile="false"] {
+      display: none;
+    }
+  }
+}