mirror of
https://github.com/JOYCEQL/magic-resume.git
synced 2026-07-03 14:07:11 +02:00
refactor: remove redundant 'use client' directives from numerous components.
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useTranslations } from "@/i18n/compat/client";
|
||||
import { ExternalLink } from "lucide-react";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { useEffect, useState } from "react";
|
||||
import { IconResumes, IconTemplates, IconSettings, IconAI } from "@/components/shared/icons/SidebarIcons";
|
||||
import { usePathname, useRouter } from "@/lib/navigation";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import React, { useEffect } from "react";
|
||||
import { useTranslations, useLocale } from "@/i18n/compat/client";
|
||||
import { useRouter } from "@/lib/navigation";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { useState, useEffect } from "react";
|
||||
import { Folder, Trash2 } from "lucide-react";
|
||||
import { useTranslations } from "@/i18n/compat/client";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { useState, useRef } from "react";
|
||||
import { useTranslations } from "@/i18n/compat/client";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import React, { useState, useEffect, memo } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
@@ -344,7 +343,10 @@ export default function Home() {
|
||||
defaultSize={panelSizes?.[2]}
|
||||
className="bg-gray-100"
|
||||
>
|
||||
<div className="h-full overflow-y-auto">
|
||||
<div
|
||||
className="h-full overflow-y-auto"
|
||||
data-preview-scroll-container="true"
|
||||
>
|
||||
<PreviewPanel
|
||||
sidePanelCollapsed={sidePanelCollapsed}
|
||||
editPanelCollapsed={editPanelCollapsed}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { ThemeProvider } from "next-themes";
|
||||
import { HeroUIProvider } from "@heroui/react";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
import { Pencil } from "lucide-react";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { useTranslations } from "@/i18n/compat/client";
|
||||
import { AlertCircle } from "lucide-react";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { useState, useEffect, useMemo } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { CalendarIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { useMemo } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { Layout, Type, SpaceIcon, Palette, Zap } from "lucide-react";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import React, { useState } from "react";
|
||||
import { PlusCircle, GripVertical, Trash2, Eye, EyeOff } from "lucide-react";
|
||||
import { Reorder, AnimatePresence, motion } from "framer-motion";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useResumeStore } from "@/store/useResumeStore";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useResumeStore } from "@/store/useResumeStore";
|
||||
import { Reorder } from "framer-motion";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Reorder } from "framer-motion";
|
||||
import { PlusCircle } from "lucide-react";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { useGrammarCheck } from "@/hooks/useGrammarCheck";
|
||||
import { useResumeStore } from "@/store/useResumeStore";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { motion, Reorder, useDragControls } from "framer-motion";
|
||||
import { Eye, EyeOff, GripVertical, Trash2 } from "lucide-react";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { Reorder } from "framer-motion";
|
||||
import { MenuSection } from "@/types/resume";
|
||||
import LayoutItem from "./LayoutItem";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useResumeStore } from "@/store/useResumeStore";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { useResumeStore } from "@/store/useResumeStore";
|
||||
import { cn } from "@/lib/utils";
|
||||
import Field from "../Field";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { useTranslations } from "@/i18n/compat/client";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { useTranslations } from "@/i18n/compat/client";
|
||||
import Image from "@/lib/image";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { useNavigate } from "@tanstack/react-router";
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { usePathname } from "@/lib/navigation";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
interface AnimatedFeatureProps {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { useState } from "react";
|
||||
import { X, Menu } from "lucide-react";
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
import { useTranslations, useLocale } from "@/i18n/compat/client";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { motion, useScroll } from "framer-motion";
|
||||
|
||||
export default function ScrollBackground() {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useScroll } from "framer-motion";
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
@@ -124,6 +123,7 @@ export function MobileWorkbench() {
|
||||
exit={{ opacity: 0, scale: 1.05 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
className="h-full overflow-y-auto bg-gray-100"
|
||||
data-preview-scroll-container="true"
|
||||
>
|
||||
<PreviewPanel
|
||||
sidePanelCollapsed={true}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import SectionTitle from "./SectionTitle";
|
||||
import { GlobalSettings, CustomItem } from "@/types/resume";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { Education, GlobalSettings } from "@/types/resume";
|
||||
import SectionTitle from "./SectionTitle";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { Experience, GlobalSettings } from "@/types/resume";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import React, { useMemo } from "react";
|
||||
import { useParams } from "@tanstack/react-router";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import React, { useCallback, useState } from "react";
|
||||
import {
|
||||
Edit2,
|
||||
@@ -392,14 +391,24 @@ const PreviewDock = ({
|
||||
// ... (keep other hooks)
|
||||
|
||||
const handleGrammarCheck = useCallback(async () => {
|
||||
if (!resumeContentRef.current) return;
|
||||
|
||||
if (!checkConfiguration()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const text = resumeContentRef.current.innerText;
|
||||
const previewContent =
|
||||
resumeContentRef.current || document.getElementById("resume-preview");
|
||||
if (!previewContent) {
|
||||
toast.error(t("grammarCheck.errorToast"));
|
||||
return;
|
||||
}
|
||||
|
||||
const text = previewContent.innerText?.trim();
|
||||
if (!text) {
|
||||
toast.error(t("grammarCheck.errorToast"));
|
||||
return;
|
||||
}
|
||||
|
||||
await checkGrammar(text);
|
||||
} catch (error) {
|
||||
toast.error(t("grammarCheck.errorToast"));
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { useMemo } from "react";
|
||||
import { GlobalSettings } from "@/types/resume";
|
||||
import { useResumeStore } from "@/store/useResumeStore";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { motion } from "framer-motion";
|
||||
import SectionTitle from "./SectionTitle";
|
||||
import { GlobalSettings } from "@/types/resume";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import React, { useEffect, useMemo, useState, useRef } from "react";
|
||||
import throttle from "lodash/throttle";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Star } from "lucide-react";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { useLocale } from "@/i18n/compat/client";
|
||||
import { useLocation, useNavigate } from "@tanstack/react-router";
|
||||
import { Languages } from "lucide-react";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
import Image from "@/lib/image";
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import React, { useState, useRef } from "react";
|
||||
import { useTranslations } from "@/i18n/compat/client";
|
||||
import {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import React, { useState, useRef, useEffect } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { Upload, X } from "lucide-react";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import React, { useState } from "react";
|
||||
import { Settings2, Image, EyeOff, Eye } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { ArrowUp } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { Layout, PanelsLeftBottom } from "lucide-react";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import * as React from "react";
|
||||
import { Moon, Sun } from "lucide-react";
|
||||
import { useTheme } from "next-themes";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import { useEffect, useState, useRef } from "react";
|
||||
import { Loader2, Sparkles } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
import React, { useEffect } from "react";
|
||||
import { useEditor, EditorContent } from "@tiptap/react";
|
||||
import { useTranslations } from "@/i18n/compat/client";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as AccordionPrimitive from "@radix-ui/react-accordion"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { ChevronLeft, ChevronRight } from "lucide-react"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { forwardRef, useMemo, useState } from "react";
|
||||
import { HexColorPicker } from "react-colorful";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { type DialogProps } from "@radix-ui/react-dialog"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { Drawer as DrawerPrimitive } from "vaul"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as HoverCardPrimitive from "@radix-ui/react-hover-card"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as LabelPrimitive from "@radix-ui/react-label"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as PopoverPrimitive from "@radix-ui/react-popover"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import { GripVertical } from "lucide-react"
|
||||
import * as ResizablePrimitive from "react-resizable-panels"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as SelectPrimitive from "@radix-ui/react-select"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as SeparatorPrimitive from "@radix-ui/react-separator"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as SheetPrimitive from "@radix-ui/react-dialog"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import { Slot } from "@radix-ui/react-slot";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as SliderPrimitive from "@radix-ui/react-slider"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import { useTheme } from "next-themes"
|
||||
import { Toaster as Sonner } from "sonner"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as SwitchPrimitives from "@radix-ui/react-switch"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as TabsPrimitive from "@radix-ui/react-tabs"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import * as TooltipPrimitive from "@radix-ui/react-tooltip"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { DateInput } from "@heroui/date-input";
|
||||
import { HeroUIProvider } from "@heroui/react";
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use client";
|
||||
|
||||
import { DateInput } from "@heroui/date-input";
|
||||
import { HeroUIProvider } from "@heroui/react";
|
||||
|
||||
@@ -5,6 +5,7 @@ export const Route = createFileRoute("/app/dashboard")({
|
||||
head: () => ({
|
||||
meta: [{ name: "robots", content: "noindex,nofollow" }]
|
||||
}),
|
||||
ssr: false,
|
||||
component: DashboardRouteLayout
|
||||
});
|
||||
|
||||
|
||||
@@ -2,5 +2,6 @@ import { createFileRoute } from '@tanstack/react-router'
|
||||
import IframeTemplateViewer from '../../../components/preview/IframeTemplateViewer'
|
||||
|
||||
export const Route = createFileRoute('/app/preview-template/$id')({
|
||||
ssr: false,
|
||||
component: IframeTemplateViewer,
|
||||
})
|
||||
|
||||
@@ -28,6 +28,55 @@ interface GrammarStore {
|
||||
dismissError: (index: number) => void;
|
||||
}
|
||||
|
||||
const markSingleError = (
|
||||
marker: Mark,
|
||||
error: GrammarError,
|
||||
options?: { selected?: boolean; activeIndex?: number }
|
||||
) => {
|
||||
const keyword = (error.text || "").trim();
|
||||
if (!keyword) return;
|
||||
|
||||
let hasMarked = false;
|
||||
marker.mark(keyword, {
|
||||
separateWordSearch: false,
|
||||
acrossElements: true,
|
||||
className: cn(
|
||||
"grammar-error",
|
||||
error.type,
|
||||
options?.selected && options?.activeIndex !== undefined && `active-${options.activeIndex}`
|
||||
),
|
||||
filter: () => {
|
||||
if (hasMarked) return false;
|
||||
hasMarked = true;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const getPreviewScrollContainer = (element: HTMLElement): HTMLElement | null => {
|
||||
const containers = Array.from(
|
||||
document.querySelectorAll<HTMLElement>('[data-preview-scroll-container="true"]')
|
||||
);
|
||||
|
||||
for (const container of containers) {
|
||||
if (container.contains(element)) {
|
||||
return container;
|
||||
}
|
||||
}
|
||||
|
||||
let current: HTMLElement | null = element.parentElement;
|
||||
while (current) {
|
||||
const style = window.getComputedStyle(current);
|
||||
const canScrollY = /(auto|scroll)/.test(style.overflowY);
|
||||
if (canScrollY && current.scrollHeight > current.clientHeight) {
|
||||
return current;
|
||||
}
|
||||
current = current.parentElement;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export const useGrammarStore = create<GrammarStore>((set, get) => ({
|
||||
isChecking: false,
|
||||
errors: [],
|
||||
@@ -104,9 +153,8 @@ export const useGrammarStore = create<GrammarStore>((set, get) => ({
|
||||
const marker = new Mark(preview);
|
||||
marker.unmark();
|
||||
grammarErrors.errors.forEach((error: GrammarError) => {
|
||||
marker.mark(error.context || error.text || "", {
|
||||
className: "bg-yellow-200 dark:bg-yellow-900",
|
||||
});
|
||||
// 仅标注错误片段,避免整句/全局模糊匹配造成误高亮
|
||||
markSingleError(marker, error);
|
||||
});
|
||||
}
|
||||
} catch (parseError) {
|
||||
@@ -143,21 +191,36 @@ export const useGrammarStore = create<GrammarStore>((set, get) => ({
|
||||
marker.unmark();
|
||||
|
||||
errors.forEach((err, i) => {
|
||||
marker.mark(err.context || err.text || "", {
|
||||
className: cn(
|
||||
"bg-yellow-200 dark:bg-yellow-900",
|
||||
i === index && "bg-green-200 dark:bg-green-900"
|
||||
),
|
||||
markSingleError(marker, err, {
|
||||
selected: i === index,
|
||||
activeIndex: index
|
||||
});
|
||||
});
|
||||
|
||||
const marks = preview.querySelectorAll("mark");
|
||||
const selectedMark = marks[index];
|
||||
if (selectedMark) {
|
||||
selectedMark.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "center",
|
||||
});
|
||||
const scrollContainer = getPreviewScrollContainer(selectedMark as HTMLElement);
|
||||
|
||||
if (scrollContainer) {
|
||||
const containerRect = scrollContainer.getBoundingClientRect();
|
||||
const markRect = selectedMark.getBoundingClientRect();
|
||||
const currentTop = scrollContainer.scrollTop;
|
||||
const nextTop =
|
||||
currentTop +
|
||||
(markRect.top - containerRect.top) -
|
||||
scrollContainer.clientHeight / 2 +
|
||||
markRect.height / 2;
|
||||
const maxTop = Math.max(
|
||||
0,
|
||||
scrollContainer.scrollHeight - scrollContainer.clientHeight
|
||||
);
|
||||
|
||||
scrollContainer.scrollTo({
|
||||
top: Math.max(0, Math.min(nextTop, maxTop)),
|
||||
behavior: "smooth"
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
dismissError: (index: number) => {
|
||||
@@ -171,14 +234,10 @@ export const useGrammarStore = create<GrammarStore>((set, get) => ({
|
||||
const marker = new Mark(preview);
|
||||
marker.unmark();
|
||||
newErrors.forEach((error, i) => {
|
||||
marker.mark(error.context || error.text || "", {
|
||||
className: cn(
|
||||
"bg-yellow-200 dark:bg-yellow-900",
|
||||
state.selectedErrorIndex === i && "bg-green-200 dark:bg-green-900"
|
||||
// 注意:selectedErrorIndex 可能因为删除而需要调整,这里简化处理,稍后在选中逻辑中可能需要优化
|
||||
// 为了保持一致性,最好是重新选中当前索引或重置选中
|
||||
)
|
||||
});
|
||||
markSingleError(marker, error, {
|
||||
selected: state.selectedErrorIndex === i,
|
||||
activeIndex: state.selectedErrorIndex ?? undefined
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user