develop → main: 合并开发分支 (#51)

* fix(ci): fix release workflow artifact upload issue

- Split artifact upload into 3 separate steps (Chrome, Firefox, Source)
- Update download steps to match new artifact names
- Add if-no-files-found: error for better error handling
- Fix Node.js 20 compatibility issue with upload-artifact@v4 glob pattern

* docs: 更新 AGENTS.md,添加测试工具和翻译文件结构说明

* docs: 更新 AGENTS.md,完善 CI 步骤和存储键名格式说明

* fix: remove unnecessary animations from StorageCleaner page

- Remove entrance animations (animate-in, fade-in, zoom-in) from all components
- Remove scale effect (active:scale-[0.99]) from clean button
- Remove transition effects (transition-all, transition-colors) from OptionItem, StorageOptionsGrid, AutoRefreshToggle
- Remove bouncing animation from error icon
- Remove pulsing animation from warning banner
- Keep animate-spin on button loading spinner as functional indicator

* fix: remove unnecessary animations from RightClickRestorer page

* fix: remove all unnecessary animations from all pages

- Remove dead code animations (animate-in, fade-in, slide-in, zoom-in, shake) from tailwindcss-animate plugin (not installed)
- Remove decorative transition effects (transition-all, transition-colors) from all page components
- Remove scale effects (active:scale-95) from buttons
- Remove bounce animations (animate-bounce) from icons
- Keep functional animate-spin on loading spinners as they provide essential loading feedback

Affected pages: Dashboard, Timestamp, Jwt, JsonTools, Base64Converter, HtmlToMarkdown, MarkdownToHtml, QrCode, TextStatistics

---------

Co-authored-by: Ubuntu <ubuntu@localhost.localdomain>
This commit is contained in:
LingandRX
2026-05-26 15:08:53 +08:00
committed by GitHub
parent 92d524d832
commit 42d3fedbaa
32 changed files with 108 additions and 113 deletions
+5 -5
View File
@@ -30,7 +30,7 @@ export default function DiffNavigator({
return (
<div
className={cn(
'flex items-center justify-center gap-3 px-4 py-2 rounded-lg border border-border bg-muted/30 select-none animate-in fade-in duration-200',
'flex items-center justify-center gap-3 px-4 py-2 rounded-lg border border-border bg-muted/30 select-none',
className,
)}
{...props}
@@ -60,9 +60,9 @@ export default function DiffNavigator({
aria-label={t('jsonDiff:previousDiff')}
onClick={onPrev}
className={cn(
'p-1 rounded-md text-muted-foreground transition-all hover:bg-accent hover:text-foreground',
'p-1 rounded-md text-muted-foreground hover:bg-accent hover:text-foreground',
'focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring',
'disabled:pointer-events-none disabled:opacity-30 active:scale-95', // 4. 边界拦截:触顶时优雅淡化并锁死点击
'disabled:pointer-events-none disabled:opacity-30', // 4. 边界拦截:触顶时优雅淡化并锁死点击
)}
>
<ChevronLeft className="h-4 w-4" />
@@ -81,9 +81,9 @@ export default function DiffNavigator({
aria-label={t('jsonDiff:nextDiff')}
onClick={onNext}
className={cn(
'p-1 rounded-md text-muted-foreground transition-all hover:bg-accent hover:text-foreground',
'p-1 rounded-md text-muted-foreground hover:bg-accent hover:text-foreground',
'focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring',
'disabled:pointer-events-none disabled:opacity-30 active:scale-95', // 4. 边界拦截:触底时优雅淡化并锁死点击
'disabled:pointer-events-none disabled:opacity-30', // 4. 边界拦截:触底时优雅淡化并锁死点击
)}
>
<ChevronRight className="h-4 w-4" />
+1 -1
View File
@@ -197,7 +197,7 @@ const UnifiedRow = ({ depth, type, text, active, multiline }: UnifiedRowProps) =
return (
<div
className={cn(
'flex items-start w-full font-mono py-0.5 select-text group transition-colors',
'flex items-start w-full font-mono py-0.5 select-text group',
currentTheme.bg,
currentTheme.text,
// 4. 高亮定位条:不再使用生硬的蓝圆环,改为现代编辑器的“侧边左高亮带”设计,质感直接拉满
+2 -5
View File
@@ -74,10 +74,7 @@ export default function JsonConvertSection({
: null;
return (
<div
className={cn('w-full flex flex-col gap-4 animate-in fade-in duration-300', className)}
{...props}
>
<div className={cn('w-full flex flex-col gap-4', className)} {...props}>
{/* 输入区 */}
<TextInputArea
placeholder={t(`jsonFormat:${pk}InputPlaceholder`)}
@@ -93,7 +90,7 @@ export default function JsonConvertSection({
{/* 4. 结果展示或状态引导卡片区 */}
{result && result.output ? (
<div className="relative rounded-xl border border-border bg-card text-card-foreground shadow-sm overflow-hidden animate-in slide-in-from-bottom-2 duration-300">
<div className="relative rounded-xl border border-border bg-card text-card-foreground shadow-sm overflow-hidden">
{/* 结果栏精致头部 */}
<div className="flex h-9 items-center justify-between px-4 border-b border-border bg-muted/50 select-none">
<div className="flex gap-4 items-center">
+3 -3
View File
@@ -62,7 +62,7 @@ export default function JsonFormatSection() {
: null;
return (
<div className="w-full flex flex-col gap-4 animate-in fade-in duration-300">
<div className="w-full flex flex-col gap-4">
{/* 工具控制栏 */}
<div className="flex h-10 items-center justify-between px-1.5 bg-secondary/40 rounded-xl border border-border/60">
<div className="flex gap-4 items-center w-full">
@@ -95,7 +95,7 @@ export default function JsonFormatSection() {
/>
<Label
htmlFor="sort-keys-checkbox"
className="text-xs font-bold text-foreground/80 cursor-pointer tracking-tight group-hover:text-foreground transition-colors"
className="text-xs font-bold text-foreground/80 cursor-pointer tracking-tight group-hover:text-foreground"
>
{t('jsonFormat:sortKeys')}
</Label>
@@ -118,7 +118,7 @@ export default function JsonFormatSection() {
{/* 格式化结果流面板展示 */}
{result && result.formatted ? (
<div className="relative rounded-xl border border-border bg-card text-card-foreground shadow-sm overflow-hidden animate-in slide-in-from-bottom-2 duration-300">
<div className="relative rounded-xl border border-border bg-card text-card-foreground shadow-sm overflow-hidden">
{/* 结果栏头部 */}
<div className="flex h-9 items-center justify-between px-4 border-b border-border bg-muted/50 select-none">
<div className="flex gap-4 items-center">
+2 -2
View File
@@ -135,7 +135,7 @@ const NodeRow = React.memo(
<div
onClick={() => setOverride(expanded ? 'closed' : 'open')}
className={cn(
'group flex items-center gap-1 py-0.5 pr-2 text-xs font-mono select-none cursor-pointer rounded-sm transition-colors w-full h-[22px] leading-relaxed',
'group flex items-center gap-1 py-0.5 pr-2 text-xs font-mono select-none cursor-pointer rounded-sm w-full h-[22px] leading-relaxed',
theme.bg,
isActive &&
'bg-primary/10 relative before:absolute before:left-0 before:top-0 before:bottom-0 before:w-0.5 before:bg-blue-500 rounded-none ring-0',
@@ -207,7 +207,7 @@ const NodeRow = React.memo(
<div
ref={rowRef}
className={cn(
'flex items-center gap-1 py-0.5 pr-2 font-mono text-xs w-full h-[22px] leading-relaxed rounded-sm transition-colors',
'flex items-center gap-1 py-0.5 pr-2 font-mono text-xs w-full h-[22px] leading-relaxed rounded-sm',
theme.bg,
isActive &&
'bg-primary/10 relative before:absolute before:left-0 before:top-0 before:bottom-0 before:w-0.5 before:bg-blue-500 rounded-none ring-0',
+2 -2
View File
@@ -113,7 +113,7 @@ export default function Index() {
}, []);
return (
<div className="p-4 w-full flex flex-col space-y-4 min-h-[500px] select-none animate-in fade-in duration-300">
<div className="p-4 w-full flex flex-col space-y-4 min-h-[500px] select-none">
<SwitchButtonGroup
value={pageMode}
onChange={(v: PageMode) => setPageMode(v)}
@@ -129,7 +129,7 @@ export default function Index() {
/>
{pageMode === 'diff' ? (
<div className="flex flex-col space-y-4 animate-in fade-in duration-200">
<div className="flex flex-col space-y-4">
<div className="flex h-10 items-center justify-between px-1.5 bg-secondary/40 rounded-xl border border-border/60">
<SwitchButtonGroup
value={viewMode}