diff --git a/pages/JsonTools/DiffNavigator.tsx b/pages/JsonTools/DiffNavigator.tsx
index 96004c1..45ca5c6 100644
--- a/pages/JsonTools/DiffNavigator.tsx
+++ b/pages/JsonTools/DiffNavigator.tsx
@@ -1,8 +1,5 @@
-import { Box, IconButton, Typography } from '@mui/material';
-import NavigateBeforeIcon from '@mui/icons-material/NavigateBefore';
-import NavigateNextIcon from '@mui/icons-material/NavigateNext';
+import { ChevronLeft, ChevronRight } from 'lucide-react';
import { useLazyTranslation } from '@/utils/useLazyTranslation';
-import { jsonDiffPageStyles } from '@/config/pageTheme';
interface DiffNavigatorProps {
total: number;
@@ -17,29 +14,34 @@ export default function DiffNavigator({ total, currentIndex, onPrev, onNext }: D
if (total === 0) {
return (
-
-
- {t('jsonDiff:noDiffs')}
-
-
+
+ {t('jsonDiff:noDiffs')}
+
);
}
return (
-
-
-
-
-
+
+
{currentIndex + 1} / {total}
-
-
-
-
-
+
+
+
);
}
diff --git a/pages/JsonTools/DiffResult.tsx b/pages/JsonTools/DiffResult.tsx
index ef043e3..cbde70f 100644
--- a/pages/JsonTools/DiffResult.tsx
+++ b/pages/JsonTools/DiffResult.tsx
@@ -1,7 +1,4 @@
-import { Box, Stack, Typography, useTheme } from '@mui/material';
-import type { Theme } from '@mui/material/styles';
import { useLazyTranslation } from '@/utils/useLazyTranslation';
-import { jsonDiffPageStyles, surfaceTint } from '@/config/pageTheme';
import JsonTree from './JsonTree';
import type { DiffNode, DiffResult as DiffResultType, DiffType, ViewMode } from './types';
@@ -16,41 +13,30 @@ export default function DiffResult({ result, viewMode, activePath }: DiffResultP
if (viewMode === 'sideBySide') {
return (
-
-
+
);
}
return (
-
+
-
+
);
}
const SectionLabel = ({ text }: { text: string }) => (
-
+
{text}
-
+
);
const formatPrimitive = (v: unknown): string => {
@@ -71,17 +57,17 @@ const prefixForType = (type: DiffType): string => {
return ' ';
};
-const colorForType = (type: DiffType): string | undefined => {
- if (type === 'added') return jsonDiffPageStyles.addedText;
- if (type === 'removed') return jsonDiffPageStyles.removedText;
- if (type === 'modified') return jsonDiffPageStyles.modifiedText;
- return undefined;
+const colorForType = (type: DiffType): string => {
+ if (type === 'added') return 'text-green-600';
+ if (type === 'removed') return 'text-red-600';
+ if (type === 'modified') return 'text-amber-600';
+ return 'text-gray-900';
};
-const bgForType = (type: DiffType, theme: Theme): string | undefined => {
- if (type === 'added') return surfaceTint(theme, theme.palette.success.main, 0.15);
- if (type === 'removed') return surfaceTint(theme, theme.palette.error.main, 0.15);
- if (type === 'modified') return surfaceTint(theme, theme.palette.warning.main, 0.15);
+const bgForType = (type: DiffType): string | undefined => {
+ if (type === 'added') return 'bg-green-50';
+ if (type === 'removed') return 'bg-red-50';
+ if (type === 'modified') return 'bg-amber-50';
return undefined;
};
@@ -177,29 +163,18 @@ interface UnifiedRowProps {
}
const UnifiedRow = ({ depth, type, text, active, multiline }: UnifiedRowProps) => {
- const theme = useTheme();
const color = colorForType(type);
- const bg = bgForType(type, theme);
+ const bg = bgForType(type);
return (
-
-
- {prefixForType(type)}
-
- {text}
-
+ {prefixForType(type)}
+ {text}
+
);
};
diff --git a/pages/JsonTools/JsonConvertSection.tsx b/pages/JsonTools/JsonConvertSection.tsx
index c99beb8..8717cbf 100644
--- a/pages/JsonTools/JsonConvertSection.tsx
+++ b/pages/JsonTools/JsonConvertSection.tsx
@@ -1,5 +1,5 @@
import { useEffect, useMemo, useState } from 'react';
-import { Box, Button, Stack, Typography } from '@mui/material';
+import { Button } from '@/components/ui/button';
import { useLazyTranslation } from '@/utils/useLazyTranslation';
import { formatByteSize } from '@/utils/textStatistics';
import { useSnackbar } from '@/components/GlobalSnackbar';
@@ -88,29 +88,24 @@ export default function JsonConvertSection({
};
return (
-
+
{/* 工具栏 */}
-
-
-
-
+
);
}
diff --git a/pages/JsonTools/JsonDiffInput.tsx b/pages/JsonTools/JsonDiffInput.tsx
index 5e10150..7ab3541 100644
--- a/pages/JsonTools/JsonDiffInput.tsx
+++ b/pages/JsonTools/JsonDiffInput.tsx
@@ -1,4 +1,3 @@
-import { Box, Typography } from '@mui/material';
import TextInputArea from '@/components/TextInputArea';
interface JsonDiffInputProps {
@@ -17,21 +16,10 @@ export default function JsonDiffInput({
error,
}: JsonDiffInputProps) {
return (
-
-
+
+
{label}
-
+
-
+
);
}
diff --git a/pages/JsonTools/JsonFormatSection.tsx b/pages/JsonTools/JsonFormatSection.tsx
index 966d797..412dbdd 100644
--- a/pages/JsonTools/JsonFormatSection.tsx
+++ b/pages/JsonTools/JsonFormatSection.tsx
@@ -1,14 +1,5 @@
import { useEffect, useMemo, useState } from 'react';
-import {
- Box,
- Button,
- FormControlLabel,
- FormHelperText,
- Stack,
- Switch,
- TextField,
- Typography,
-} from '@mui/material';
+import { Button } from '@/components/ui/button';
import { useLazyTranslation } from '@/utils/useLazyTranslation';
import {
formatJson,
@@ -18,7 +9,6 @@ import {
} from '@/utils/jsonFormatter';
import { formatByteSize } from '@/utils/textStatistics';
import { useSnackbar } from '@/components/GlobalSnackbar';
-import { jsonDiffPageStyles } from '@/config/pageTheme';
import CopyButton from '@/components/CopyButton';
import SwitchButtonGroup from '@/components/SwitchButtonGroup';
@@ -78,22 +68,14 @@ export default function JsonFormatSection() {
};
return (
-
+
{/* 工具栏 */}
-
-
+
+
{/* 缩进选择 */}
-
+
{t('jsonFormat:indentSize')}
-
+
setIndentSize(v)}
@@ -103,134 +85,79 @@ export default function JsonFormatSection() {
/>
{/* 键名排序开关 */}
- setSortKeys(e.target.checked)}
- />
- }
- label={
-
- {t('jsonFormat:sortKeys')}
-
- }
- sx={{ ml: 1 }}
- />
-
+
+
-
-
+
+
{t('jsonFormat:clearButton')}
{t('jsonFormat:formatButton')}
-
-
+
+
{/* 输入区 */}
-
-
+
+
{/* 格式化结果 */}
{result && result.formatted ? (
-
+
{/* 结果头部 */}
-
- theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.03)' : 'grey.50',
- }}
- >
-
-
+
+
+
{t('jsonFormat:outputLabel')}
-
-
+
+
{t('jsonFormat:originalSize')}: {formatByteSize(result.originalBytes)}
-
-
+
+
{t('jsonFormat:formattedSize')}: {formatByteSize(result.formattedBytes)}
-
-
+
+
-
+
{/* 格式化内容 */}
-
+
{result.formatted}
-
-
+
+
) : (
-
- theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.03)' : 'grey.50',
- border: '1px dashed',
- borderColor: (theme) =>
- theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.15)' : 'grey.300',
- textAlign: 'center',
- }}
- >
-
- {t('jsonFormat:emptyHint')}
-
-
+
+
{t('jsonFormat:emptyHint')}
+
)}
-
+
);
}
diff --git a/pages/JsonTools/JsonTree.tsx b/pages/JsonTools/JsonTree.tsx
index 332cf59..96bf739 100644
--- a/pages/JsonTools/JsonTree.tsx
+++ b/pages/JsonTools/JsonTree.tsx
@@ -1,7 +1,4 @@
-import { Box, Collapse, useTheme } from '@mui/material';
-import type { Theme } from '@mui/material/styles';
import { useEffect, useMemo, useRef, useState } from 'react';
-import { surfaceTint } from '@/config/pageTheme';
import type { DiffNode, DiffType } from './types';
export type TreeSide = 'left' | 'right';
@@ -43,19 +40,19 @@ const getValueForSide = (node: DiffNode, side: TreeSide): unknown => {
return side === 'left' ? node.oldValue : node.newValue;
};
-const getRowBg = (type: DiffType, side: TreeSide, theme: Theme): string | undefined => {
+const getRowBg = (type: DiffType, side: TreeSide): string | undefined => {
if (!shouldRenderOnSide(type, side)) return undefined;
- if (type === 'added') return surfaceTint(theme, theme.palette.success.main, 0.15);
- if (type === 'removed') return surfaceTint(theme, theme.palette.error.main, 0.15);
- if (type === 'modified') return surfaceTint(theme, theme.palette.warning.main, 0.15);
+ if (type === 'added') return 'bg-green-50';
+ if (type === 'removed') return 'bg-red-50';
+ if (type === 'modified') return 'bg-amber-50';
return undefined;
};
const getValueColor = (type: DiffType, side: TreeSide): string | undefined => {
if (!shouldRenderOnSide(type, side)) return undefined;
- if (type === 'added') return 'success.main';
- if (type === 'removed') return 'error.main';
- if (type === 'modified') return 'warning.main';
+ if (type === 'added') return 'text-green-600';
+ if (type === 'removed') return 'text-red-600';
+ if (type === 'modified') return 'text-amber-600';
return undefined;
};
@@ -74,7 +71,6 @@ const NodeRow = ({
// 'auto' = follow defaults + activePath; otherwise user explicitly toggled
const [override, setOverride] = useState<'auto' | 'open' | 'closed'>('auto');
const rowRef = useRef(null);
- const theme = useTheme();
const onActivePath = Boolean(
activePath &&
@@ -99,13 +95,17 @@ const NodeRow = ({
if (!shouldRenderOnSide(node.type, side)) {
// 渲染占位空行以保持左右两侧高度一致
- return ·;
+ return (
+
+ ·
+
+ );
}
const value = getValueForSide(node, side);
const isContainer = isContainerValue(value) && Array.isArray(node.children);
const isArray = Array.isArray(value);
- const bg = getRowBg(node.type, side, theme);
+ const bg = getRowBg(node.type, side);
const valueColor = getValueColor(node.type, side);
const isActive = activePath === node.path;
@@ -116,50 +116,29 @@ const NodeRow = ({
const open = isArray ? '[' : '{';
const close = isArray ? ']' : '}';
return (
-
-
+ setOverride(expanded ? 'closed' : 'open')}
- sx={{
- cursor: 'pointer',
- pl: depth * 1.5,
- pr: 1,
- py: 0.2,
- bgcolor: bg,
- outline: isActive ? '2px solid' : 'none',
- outlineColor: 'primary.main',
- borderRadius: 0.5,
- display: 'flex',
- alignItems: 'center',
- gap: 0.5,
- whiteSpace: 'nowrap',
- '&:hover': { bgcolor: bg ?? 'action.hover' },
- }}
+ className={`cursor-pointer pr-1 py-0.5 ${bg ?? ''} ${
+ isActive ? 'ring-2 ring-blue-500 rounded' : ''
+ } flex items-center gap-1 whitespace-nowrap hover:${bg ? 'bg-opacity-80' : 'bg-gray-50'}`}
+ style={{ paddingLeft: `${depth * 1.5}rem` }}
>
-
- {expanded ? '▾' : '▸'}
-
+ {expanded ? '▾' : '▸'}
{!isRoot && (
-
- {isArrayKeyDisplay(node.key)}:
-
+ {isArrayKeyDisplay(node.key)}:
)}
-
- {open}
-
+ {open}
+ {!expanded && {summarize(value)}}
{!expanded && (
-
- {summarize(value)}
-
- )}
- {!expanded && (
-
+
{close}
{isLastChild ? '' : ','}
-
+
)}
-
-
-
+
+ {expanded && (
+
{node.children.map((child, idx) => (
))}
-
-
+ )}
+ {expanded && (
+
{close}
{isLastChild ? '' : ','}
-
-
-
+
+ )}
+
);
}
// 叶子节点
return (
-
-
- {!isRoot && (
-
- {isArrayKeyDisplay(node.key)}:
-
- )}
-
+
+ {!isRoot && {isArrayKeyDisplay(node.key)}:}
+
{formatPrimitive(value)}
{isLastChild ? '' : ','}
-
-
+
+
);
};
@@ -242,21 +206,7 @@ export default function JsonTree({
}: JsonTreeProps) {
const sideKey = useMemo(() => side, [side]);
return (
-
+
-
+
);
}
diff --git a/pages/JsonTools/index.tsx b/pages/JsonTools/index.tsx
index 3135eaa..7d55361 100644
--- a/pages/JsonTools/index.tsx
+++ b/pages/JsonTools/index.tsx
@@ -1,12 +1,8 @@
import { useEffect, useMemo, useState, useCallback } from 'react';
-import { Box, Button, Container, Stack, Typography } from '@mui/material';
-import CompareArrowsIcon from '@mui/icons-material/CompareArrows';
-import DataObjectIcon from '@mui/icons-material/DataObject';
-import TransformIcon from '@mui/icons-material/Transform';
-import CompressIcon from '@mui/icons-material/Compress';
+import { Button } from '@/components/ui/button';
+import { GitCompareArrows, Braces, ArrowRightLeft, Minimize2 } from 'lucide-react';
import { useLazyTranslation } from '@/utils/useLazyTranslation';
import PageHeader from '@/components/PageHeader';
-import { jsonDiffPageStyles } from '@/config/pageTheme';
import JsonDiffInput from './JsonDiffInput';
import DiffResult from './DiffResult';
import DiffNavigator from './DiffNavigator';
@@ -20,7 +16,7 @@ import { jsonToToml } from '@/utils/jsonToToml';
import { minifyJson } from '@/utils/jsonFormatter';
import { useStorageState } from '@/utils/useStorageState';
import type { JsonToolsPageMode } from '@/types/storage';
-import SwtichButtonGroup from '@/components/SwitchButtonGroup';
+import SwitchButtonGroup from '@/components/SwitchButtonGroup';
interface ParseState {
value: unknown;
@@ -118,11 +114,11 @@ export default function Index() {
};
const modeIcon: Record = {
- diff: ,
- format: ,
- yaml: ,
- toml: ,
- minify: ,
+ diff: ,
+ format: ,
+ yaml: ,
+ toml: ,
+ minify: ,
};
const yamlConvert: ConvertFunction = useCallback((text: string) => {
@@ -141,18 +137,18 @@ export default function Index() {
}, []);
return (
-
-
+
+
-
+
{/* 页面模式切换器 */}
-
setPageMode(v)}
options={[
@@ -168,13 +164,8 @@ export default function Index() {
{pageMode === 'diff' ? (
<>
{/* 工具栏 */}
-
-
+ setViewMode(v)}
options={[
@@ -183,23 +174,23 @@ export default function Index() {
]}
size="small"
/>
-
-
+
+
{t('jsonDiff:clearButton')}
{t('jsonDiff:compareButton')}
-
-
+
+
{/* 输入区 */}
-
+
-
+
{/* 差异展示 */}
{diffResult ? (
@@ -228,22 +219,9 @@ export default function Index() {
>
) : (
-
- theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.03)' : 'grey.50',
- border: '1px dashed',
- borderColor: (theme) =>
- theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.15)' : 'grey.300',
- textAlign: 'center',
- }}
- >
-
- {t('jsonDiff:emptyHint')}
-
-
+
+
{t('jsonDiff:emptyHint')}
+
)}
>
) : pageMode === 'format' ? (
@@ -259,8 +237,8 @@ export default function Index() {
convertButtonKey="minifyButton"
/>
)}
-
-
-
+
+
+
);
}