Perfect! I've successfully added a text wrap toggle to the frontend diff viewer. Here's a summary of the changes: (#1219)

## Changes Made

### 1. **State Management** (`frontend/src/stores/useDiffViewStore.ts:11-13,22-23,29`)
   - Added `wrapText` boolean state (defaults to `false`)
   - Added `setWrapText` action to update the state
   - Exported `useWrapTextDiff` hook for components to access the state

### 2. **UI Toggle Component** (`frontend/src/components/diff-view-switch.tsx:1,8,28-29,32,100-121`)
   - Imported `WrapText` icon from `lucide-react`
   - Added a new toggle group for the text wrap feature
   - The toggle appears alongside the existing view mode and whitespace toggles
   - Uses the same UI pattern as the "Ignore Whitespace" toggle
   - Includes tooltip with internationalization support

### 3. **Diff Viewer Integration** (`frontend/src/components/DiffCard.tsx:31,84,300`)
   - Imported and used the `useWrapTextDiff` hook
   - Connected the `wrapText` state to the `DiffView` component's `diffViewWrap` prop
   - The `DiffView` component now responds to the toggle state

## How It Works

- The toggle button appears in the diff view controls with a `WrapText` icon
- Clicking the toggle switches between wrapped and unwrapped text in the diff viewer
- The state is managed globally via Zustand, so all diff viewers share the same wrap preference
- The default is set to `false` (no wrapping), preserving the original behavior
- The feature follows the existing architectural patterns for the ignore whitespace and view mode toggles

The implementation is complete and ready to use!
This commit is contained in:
Stephan Fitzpatrick
2025-11-24 06:10:22 -08:00
committed by GitHub
parent 44b7f749c5
commit f651c64f7d
3 changed files with 36 additions and 2 deletions

View File

@@ -32,6 +32,7 @@ import { ReviewCommentRenderer } from '@/components/diff/ReviewCommentRenderer';
import {
useDiffViewMode,
useIgnoreWhitespaceDiff,
useWrapTextDiff,
} from '@/stores/useDiffViewStore';
import { useProject } from '@/contexts/ProjectContext';
@@ -84,6 +85,7 @@ export default function DiffCard({
const { comments, drafts, setDraft } = useReview();
const globalMode = useDiffViewMode();
const ignoreWhitespace = useIgnoreWhitespaceDiff();
const wrapText = useWrapTextDiff();
const { projectId } = useProject();
const oldName = diff.oldPath || undefined;
@@ -301,7 +303,7 @@ export default function DiffCard({
<div>
<DiffView
diffFile={diffFile}
diffViewWrap={false}
diffViewWrap={wrapText}
diffViewTheme={theme}
diffViewHighlight
diffViewMode={

View File

@@ -1,10 +1,11 @@
import { Columns, FileText, Pilcrow } from 'lucide-react';
import { Columns, FileText, Pilcrow, WrapText } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import { cn } from '@/lib/utils';
import {
useDiffViewMode,
useDiffViewStore,
useIgnoreWhitespaceDiff,
useWrapTextDiff,
} from '@/stores/useDiffViewStore';
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group';
import {
@@ -24,8 +25,11 @@ export default function DiffViewSwitch({ className }: Props) {
const setMode = useDiffViewStore((s) => s.setMode);
const ignoreWhitespace = useIgnoreWhitespaceDiff();
const setIgnoreWhitespace = useDiffViewStore((s) => s.setIgnoreWhitespace);
const wrapText = useWrapTextDiff();
const setWrapText = useDiffViewStore((s) => s.setWrapText);
const whitespaceValue = ignoreWhitespace ? ['ignoreWhitespace'] : [];
const wrapTextValue = wrapText ? ['wrapText'] : [];
return (
<TooltipProvider>
@@ -92,6 +96,29 @@ export default function DiffViewSwitch({ className }: Props) {
</TooltipContent>
</Tooltip>
</ToggleGroup>
<ToggleGroup
type="multiple"
value={wrapTextValue}
onValueChange={(values) => setWrapText(values.includes('wrapText'))}
className="inline-flex gap-4"
aria-label={t('diff.wrapText', 'Wrap text')}
>
<Tooltip>
<TooltipTrigger asChild>
<ToggleGroupItem
value="wrapText"
aria-label={t('diff.wrapText', 'Wrap text')}
active={wrapText}
>
<WrapText className="h-4 w-4" />
</ToggleGroupItem>
</TooltipTrigger>
<TooltipContent side="bottom">
{t('diff.wrapText', 'Wrap text')}
</TooltipContent>
</Tooltip>
</ToggleGroup>
</div>
</TooltipProvider>
);

View File

@@ -8,6 +8,8 @@ type State = {
toggle: () => void;
ignoreWhitespace: boolean;
setIgnoreWhitespace: (value: boolean) => void;
wrapText: boolean;
setWrapText: (value: boolean) => void;
};
export const useDiffViewStore = create<State>((set) => ({
@@ -17,8 +19,11 @@ export const useDiffViewStore = create<State>((set) => ({
set((s) => ({ mode: s.mode === 'unified' ? 'split' : 'unified' })),
ignoreWhitespace: true,
setIgnoreWhitespace: (value) => set({ ignoreWhitespace: value }),
wrapText: false,
setWrapText: (value) => set({ wrapText: value }),
}));
export const useDiffViewMode = () => useDiffViewStore((s) => s.mode);
export const useIgnoreWhitespaceDiff = () =>
useDiffViewStore((s) => s.ignoreWhitespace);
export const useWrapTextDiff = () => useDiffViewStore((s) => s.wrapText);