mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-03-09 21:50:36 +00:00
feat: Improve DiffView theme and color consistency
- Added dark/light theme support for syntax highlighting - Enhanced color styles for added/removed lines and characters - Integrated theme store to dynamically adjust syntax highlighter theme - Refined color contrast for better readability across themes
This commit is contained in:
parent
afb82e2cf9
commit
1098188427
@ -10,6 +10,7 @@ import { diffFiles, extractRelativePath } from '~/utils/diff';
|
|||||||
import { ActionRunner } from '~/lib/runtime/action-runner';
|
import { ActionRunner } from '~/lib/runtime/action-runner';
|
||||||
import type { FileHistory } from '~/types/actions';
|
import type { FileHistory } from '~/types/actions';
|
||||||
import { getLanguageFromExtension } from '~/utils/getLanguageFromExtension';
|
import { getLanguageFromExtension } from '~/utils/getLanguageFromExtension';
|
||||||
|
import { themeStore } from '~/lib/stores/theme';
|
||||||
|
|
||||||
interface CodeComparisonProps {
|
interface CodeComparisonProps {
|
||||||
beforeCode: string;
|
beforeCode: string;
|
||||||
@ -302,12 +303,20 @@ const processChanges = (beforeCode: string, afterCode: string) => {
|
|||||||
const lineNumberStyles = "w-9 shrink-0 pl-2 py-1 text-left font-mono text-bolt-elements-textTertiary border-r border-bolt-elements-borderColor bg-bolt-elements-background-depth-1";
|
const lineNumberStyles = "w-9 shrink-0 pl-2 py-1 text-left font-mono text-bolt-elements-textTertiary border-r border-bolt-elements-borderColor bg-bolt-elements-background-depth-1";
|
||||||
const lineContentStyles = "px-1 py-1 font-mono whitespace-pre flex-1 group-hover:bg-bolt-elements-background-depth-2 text-bolt-elements-textPrimary";
|
const lineContentStyles = "px-1 py-1 font-mono whitespace-pre flex-1 group-hover:bg-bolt-elements-background-depth-2 text-bolt-elements-textPrimary";
|
||||||
const diffPanelStyles = "h-full overflow-auto diff-panel-content";
|
const diffPanelStyles = "h-full overflow-auto diff-panel-content";
|
||||||
|
|
||||||
|
// Updated color styles for better consistency
|
||||||
const diffLineStyles = {
|
const diffLineStyles = {
|
||||||
added: 'bg-green-500/20 border-l-4 border-green-500',
|
added: 'bg-green-500/10 dark:bg-green-500/20 border-l-4 border-green-500',
|
||||||
removed: 'bg-red-500/20 border-l-4 border-red-500',
|
removed: 'bg-red-500/10 dark:bg-red-500/20 border-l-4 border-red-500',
|
||||||
unchanged: ''
|
unchanged: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const changeColorStyles = {
|
||||||
|
added: 'text-green-700 dark:text-green-500 bg-green-500/10 dark:bg-green-500/20',
|
||||||
|
removed: 'text-red-700 dark:text-red-500 bg-red-500/10 dark:bg-red-500/20',
|
||||||
|
unchanged: 'text-bolt-elements-textPrimary'
|
||||||
|
};
|
||||||
|
|
||||||
const renderContentWarning = (type: 'binary' | 'error') => (
|
const renderContentWarning = (type: 'binary' | 'error') => (
|
||||||
<div className="h-full flex items-center justify-center p-4">
|
<div className="h-full flex items-center justify-center p-4">
|
||||||
<div className="text-center text-bolt-elements-textTertiary">
|
<div className="text-center text-bolt-elements-textTertiary">
|
||||||
@ -324,10 +333,11 @@ const renderContentWarning = (type: 'binary' | 'error') => (
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
const NoChangesView = memo(({ beforeCode, language, highlighter }: {
|
const NoChangesView = memo(({ beforeCode, language, highlighter, theme }: {
|
||||||
beforeCode: string;
|
beforeCode: string;
|
||||||
language: string;
|
language: string;
|
||||||
highlighter: any;
|
highlighter: any;
|
||||||
|
theme: string;
|
||||||
}) => (
|
}) => (
|
||||||
<div className="h-full flex flex-col items-center justify-center p-4">
|
<div className="h-full flex flex-col items-center justify-center p-4">
|
||||||
<div className="text-center text-bolt-elements-textTertiary">
|
<div className="text-center text-bolt-elements-textTertiary">
|
||||||
@ -347,7 +357,7 @@ const NoChangesView = memo(({ beforeCode, language, highlighter }: {
|
|||||||
<span className="mr-2"> </span>
|
<span className="mr-2"> </span>
|
||||||
<span dangerouslySetInnerHTML={{
|
<span dangerouslySetInnerHTML={{
|
||||||
__html: highlighter ?
|
__html: highlighter ?
|
||||||
highlighter.codeToHtml(line, { lang: language, theme: 'github-dark' })
|
highlighter.codeToHtml(line, { lang: language, theme: theme === 'dark' ? 'github-dark' : 'github-light' })
|
||||||
.replace(/<\/?pre[^>]*>/g, '')
|
.replace(/<\/?pre[^>]*>/g, '')
|
||||||
.replace(/<\/?code[^>]*>/g, '')
|
.replace(/<\/?code[^>]*>/g, '')
|
||||||
: line
|
: line
|
||||||
@ -372,7 +382,8 @@ const CodeLine = memo(({
|
|||||||
type,
|
type,
|
||||||
highlighter,
|
highlighter,
|
||||||
language,
|
language,
|
||||||
block
|
block,
|
||||||
|
theme
|
||||||
}: {
|
}: {
|
||||||
lineNumber: number;
|
lineNumber: number;
|
||||||
content: string;
|
content: string;
|
||||||
@ -380,17 +391,14 @@ const CodeLine = memo(({
|
|||||||
highlighter: any;
|
highlighter: any;
|
||||||
language: string;
|
language: string;
|
||||||
block: DiffBlock;
|
block: DiffBlock;
|
||||||
|
theme: string;
|
||||||
}) => {
|
}) => {
|
||||||
const bgColor = {
|
const bgColor = diffLineStyles[type];
|
||||||
added: 'bg-green-500/20 border-l-4 border-green-500',
|
|
||||||
removed: 'bg-red-500/20 border-l-4 border-red-500',
|
|
||||||
unchanged: ''
|
|
||||||
}[type];
|
|
||||||
|
|
||||||
const renderContent = () => {
|
const renderContent = () => {
|
||||||
if (type === 'unchanged' || !block.charChanges) {
|
if (type === 'unchanged' || !block.charChanges) {
|
||||||
const highlightedCode = highlighter ?
|
const highlightedCode = highlighter ?
|
||||||
highlighter.codeToHtml(content, { lang: language, theme: 'github-dark' })
|
highlighter.codeToHtml(content, { lang: language, theme: theme === 'dark' ? 'github-dark' : 'github-light' })
|
||||||
.replace(/<\/?pre[^>]*>/g, '')
|
.replace(/<\/?pre[^>]*>/g, '')
|
||||||
.replace(/<\/?code[^>]*>/g, '')
|
.replace(/<\/?code[^>]*>/g, '')
|
||||||
: content;
|
: content;
|
||||||
@ -400,14 +408,10 @@ const CodeLine = memo(({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{block.charChanges.map((change, index) => {
|
{block.charChanges.map((change, index) => {
|
||||||
const changeClass = {
|
const changeClass = changeColorStyles[change.type];
|
||||||
added: 'text-green-500 bg-green-500/20',
|
|
||||||
removed: 'text-red-500 bg-red-500/20',
|
|
||||||
unchanged: ''
|
|
||||||
}[change.type];
|
|
||||||
|
|
||||||
const highlightedCode = highlighter ?
|
const highlightedCode = highlighter ?
|
||||||
highlighter.codeToHtml(change.value, { lang: language, theme: 'github-dark' })
|
highlighter.codeToHtml(change.value, { lang: language, theme: theme === 'dark' ? 'github-dark' : 'github-light' })
|
||||||
.replace(/<\/?pre[^>]*>/g, '')
|
.replace(/<\/?pre[^>]*>/g, '')
|
||||||
.replace(/<\/?code[^>]*>/g, '')
|
.replace(/<\/?code[^>]*>/g, '')
|
||||||
: change.value;
|
: change.value;
|
||||||
@ -429,8 +433,8 @@ const CodeLine = memo(({
|
|||||||
<div className={lineNumberStyles}>{lineNumber + 1}</div>
|
<div className={lineNumberStyles}>{lineNumber + 1}</div>
|
||||||
<div className={`${lineContentStyles} ${bgColor}`}>
|
<div className={`${lineContentStyles} ${bgColor}`}>
|
||||||
<span className="mr-2 text-bolt-elements-textTertiary">
|
<span className="mr-2 text-bolt-elements-textTertiary">
|
||||||
{type === 'added' && '+'}
|
{type === 'added' && <span className="text-green-700 dark:text-green-500">+</span>}
|
||||||
{type === 'removed' && '-'}
|
{type === 'removed' && <span className="text-red-700 dark:text-red-500">-</span>}
|
||||||
{type === 'unchanged' && ' '}
|
{type === 'unchanged' && ' '}
|
||||||
</span>
|
</span>
|
||||||
{renderContent()}
|
{renderContent()}
|
||||||
@ -488,20 +492,20 @@ const FileInfo = memo(({
|
|||||||
{showStats && (
|
{showStats && (
|
||||||
<div className="flex items-center gap-1 text-xs">
|
<div className="flex items-center gap-1 text-xs">
|
||||||
{additions > 0 && (
|
{additions > 0 && (
|
||||||
<span className="text-green-500">+{additions}</span>
|
<span className="text-green-700 dark:text-green-500">+{additions}</span>
|
||||||
)}
|
)}
|
||||||
{deletions > 0 && (
|
{deletions > 0 && (
|
||||||
<span className="text-red-500">-{deletions}</span>
|
<span className="text-red-700 dark:text-red-500">-{deletions}</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<span className="text-yellow-400">Modified</span>
|
<span className="text-yellow-600 dark:text-yellow-400">Modified</span>
|
||||||
<span className="text-bolt-elements-textTertiary text-xs">
|
<span className="text-bolt-elements-textTertiary text-xs">
|
||||||
{new Date().toLocaleTimeString()}
|
{new Date().toLocaleTimeString()}
|
||||||
</span>
|
</span>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<span className="text-green-400">No Changes</span>
|
<span className="text-green-700 dark:text-green-400">No Changes</span>
|
||||||
)}
|
)}
|
||||||
<FullscreenButton onClick={onToggleFullscreen} isFullscreen={isFullscreen} />
|
<FullscreenButton onClick={onToggleFullscreen} isFullscreen={isFullscreen} />
|
||||||
</span>
|
</span>
|
||||||
@ -512,6 +516,7 @@ const FileInfo = memo(({
|
|||||||
const InlineDiffComparison = memo(({ beforeCode, afterCode, filename, language, lightTheme, darkTheme }: CodeComparisonProps) => {
|
const InlineDiffComparison = memo(({ beforeCode, afterCode, filename, language, lightTheme, darkTheme }: CodeComparisonProps) => {
|
||||||
const [isFullscreen, setIsFullscreen] = useState(false);
|
const [isFullscreen, setIsFullscreen] = useState(false);
|
||||||
const [highlighter, setHighlighter] = useState<any>(null);
|
const [highlighter, setHighlighter] = useState<any>(null);
|
||||||
|
const theme = useStore(themeStore);
|
||||||
|
|
||||||
const toggleFullscreen = useCallback(() => {
|
const toggleFullscreen = useCallback(() => {
|
||||||
setIsFullscreen(prev => !prev);
|
setIsFullscreen(prev => !prev);
|
||||||
@ -521,7 +526,7 @@ const InlineDiffComparison = memo(({ beforeCode, afterCode, filename, language,
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getHighlighter({
|
getHighlighter({
|
||||||
themes: ['github-dark'],
|
themes: ['github-dark', 'github-light'],
|
||||||
langs: ['typescript', 'javascript', 'json', 'html', 'css', 'jsx', 'tsx']
|
langs: ['typescript', 'javascript', 'json', 'html', 'css', 'jsx', 'tsx']
|
||||||
}).then(setHighlighter);
|
}).then(setHighlighter);
|
||||||
}, []);
|
}, []);
|
||||||
@ -551,6 +556,7 @@ const InlineDiffComparison = memo(({ beforeCode, afterCode, filename, language,
|
|||||||
highlighter={highlighter}
|
highlighter={highlighter}
|
||||||
language={language}
|
language={language}
|
||||||
block={block}
|
block={block}
|
||||||
|
theme={theme}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@ -559,6 +565,7 @@ const InlineDiffComparison = memo(({ beforeCode, afterCode, filename, language,
|
|||||||
beforeCode={beforeCode}
|
beforeCode={beforeCode}
|
||||||
language={language}
|
language={language}
|
||||||
highlighter={highlighter}
|
highlighter={highlighter}
|
||||||
|
theme={theme}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user