From 7424b2bfde302c7e3baabb9658e5790336efe20b Mon Sep 17 00:00:00 2001 From: hamster1963 <1410514192@qq.com> Date: Sun, 5 Jul 2026 13:43:41 +0800 Subject: [PATCH] refactor: remove @numeric-text/react dependency and implement NumericText component --- package.json | 1 - pnpm-lock.yaml | 18 ----------- src/components/Header.tsx | 2 +- src/components/NumericText.tsx | 30 +++++++++++++++++++ src/components/ServerDetailOverview.tsx | 2 +- src/components/ServerOverview.tsx | 2 +- src/test/components/basic-components.test.tsx | 12 +------- src/test/components/header.test.tsx | 8 +---- .../server-detail-components.test.tsx | 4 --- 9 files changed, 35 insertions(+), 44 deletions(-) create mode 100644 src/components/NumericText.tsx diff --git a/package.json b/package.json index 3502da6..db4c0fa 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,6 @@ "dependencies": { "@fontsource/inter": "5.2.8", "@heroicons/react": "2.2.0", - "@numeric-text/react": "^0.1.4", "@radix-ui/react-accordion": "1.2.13", "@radix-ui/react-checkbox": "1.3.4", "@radix-ui/react-dialog": "^1.1.18", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9e8b3fb..aa482ee 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,9 +14,6 @@ importers: '@heroicons/react': specifier: 2.2.0 version: 2.2.0(react@19.2.7) - '@numeric-text/react': - specifier: ^0.1.4 - version: 0.1.4(react@19.2.7) '@radix-ui/react-accordion': specifier: 1.2.13 version: 1.2.13(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) @@ -394,14 +391,6 @@ packages: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 - '@numeric-text/core@0.1.4': - resolution: {integrity: sha512-tMaH5u/kdpw3AP+XJMnDWyq39zVHoP80NCLTFwzVept64dIAMKBNLlYtUK0+EULiyFg6IiSwswmc9tMukV1tLw==} - - '@numeric-text/react@0.1.4': - resolution: {integrity: sha512-i1t18jSzn168nl9jYrC+W1FlPexjy0dbAa9bofykaL44ogu+puLg2f5roVA3xOUgjL6bSojv+wKUA/ZRRshwEw==} - peerDependencies: - react: ^18 || ^19 - '@oxc-project/types@0.137.0': resolution: {integrity: sha512-WT+Gb24i8hmvo85AIv2oEYouEXkRlKAlT9WaCa3TfLgNCN+GhrJOGZuIlMouAh38Qe4QOx26eUOVsq70qXrywA==} @@ -2270,13 +2259,6 @@ snapshots: '@tybys/wasm-util': 0.10.3 optional: true - '@numeric-text/core@0.1.4': {} - - '@numeric-text/react@0.1.4(react@19.2.7)': - dependencies: - '@numeric-text/core': 0.1.4 - react: 19.2.7 - '@oxc-project/types@0.137.0': {} '@radix-ui/number@1.1.2': {} diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 26455cf..5534689 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -1,4 +1,3 @@ -import NumericText from "@numeric-text/react"; import { useQuery } from "@tanstack/react-query"; import { ImageMinus } from "lucide-react"; import { DateTime } from "luxon"; @@ -16,6 +15,7 @@ import { cn } from "@/lib/utils"; import AnimateCountClient from "./AnimatedCount"; import { LanguageSwitcher } from "./LanguageSwitcher"; import { Loader, LoadingSpinner } from "./loading/Loader"; +import NumericText from "./NumericText"; import { SearchButton } from "./SearchButton"; import { Button } from "./ui/button"; diff --git a/src/components/NumericText.tsx b/src/components/NumericText.tsx new file mode 100644 index 0000000..ca90127 --- /dev/null +++ b/src/components/NumericText.tsx @@ -0,0 +1,30 @@ +import type { ComponentPropsWithoutRef } from "react"; + +type NumericTextTransition = { + duration?: number; + easing?: string; +}; + +type NumericTextProps = Omit, "children"> & { + animated?: boolean; + respectMotionPreference?: boolean; + transition?: NumericTextTransition; + trend?: -1 | 0 | 1; + value: number | string; +}; + +export default function NumericText({ + animated, + respectMotionPreference, + transition, + trend, + value, + ...spanProps +}: NumericTextProps) { + void animated; + void respectMotionPreference; + void transition; + void trend; + + return {value}; +} diff --git a/src/components/ServerDetailOverview.tsx b/src/components/ServerDetailOverview.tsx index 66688d6..d02d537 100644 --- a/src/components/ServerDetailOverview.tsx +++ b/src/components/ServerDetailOverview.tsx @@ -1,4 +1,3 @@ -import NumericText from "@numeric-text/react"; import countries from "i18n-iso-countries"; import enLocale from "i18n-iso-countries/langs/en.json"; import { useEffect, useState } from "react"; @@ -12,6 +11,7 @@ import { Card, CardContent } from "@/components/ui/card"; import { useWebSocketContext } from "@/hooks/use-websocket-context"; import { formatBytes } from "@/lib/format"; import { cn, formatNezhaInfo } from "@/lib/utils"; +import NumericText from "./NumericText"; import { Accordion, AccordionContent, diff --git a/src/components/ServerOverview.tsx b/src/components/ServerOverview.tsx index f8e80eb..ed80fcc 100644 --- a/src/components/ServerOverview.tsx +++ b/src/components/ServerOverview.tsx @@ -2,12 +2,12 @@ import { ArrowDownCircleIcon, ArrowUpCircleIcon, } from "@heroicons/react/20/solid"; -import NumericText from "@numeric-text/react"; import { useTranslation } from "react-i18next"; import { Card, CardContent } from "@/components/ui/card"; import { useStatus } from "@/hooks/use-status"; import { formatBytes } from "@/lib/format"; import { cn } from "@/lib/utils"; +import NumericText from "./NumericText"; type ServerOverviewProps = { online: number; diff --git a/src/test/components/basic-components.test.tsx b/src/test/components/basic-components.test.tsx index 6d16986..07ec5a1 100644 --- a/src/test/components/basic-components.test.tsx +++ b/src/test/components/basic-components.test.tsx @@ -1,6 +1,6 @@ import { fireEvent, render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; -import { describe, expect, it, vi } from "vitest"; +import { describe, expect, it } from "vitest"; import AnimateCountClient, { AnimateCount } from "@/components/AnimatedCount"; import ErrorBoundary from "@/components/ErrorBoundary"; import ChartSkeleton from "@/components/loading/ChartSkeleton"; @@ -14,16 +14,6 @@ import { Input } from "@/components/ui/input"; import { Separator } from "@/components/ui/separator"; import { Skeleton } from "@/components/ui/skeleton"; -vi.mock("@numeric-text/react", () => ({ - default: ({ - className, - value, - }: { - className?: string; - value: string | number; - }) => {value}, -})); - import { CommandProvider } from "@/context/command-provider"; import { StatusProvider } from "@/context/status-provider"; import { useCommand } from "@/hooks/use-command"; diff --git a/src/test/components/header.test.tsx b/src/test/components/header.test.tsx index 97a8649..ce3ccf2 100644 --- a/src/test/components/header.test.tsx +++ b/src/test/components/header.test.tsx @@ -21,12 +21,6 @@ const headerMocks = vi.hoisted(() => ({ updateBackground: vi.fn(), })); -vi.mock("@numeric-text/react", () => ({ - default: ({ value }: { value: string | number }) => ( - {value} - ), -})); - vi.mock("@/hooks/use-background", () => ({ useBackground: () => ({ backgroundImage: headerMocks.backgroundImage, @@ -150,7 +144,7 @@ describe("Header", () => { ); expect(screen.getAllByRole("link", { name: "Docs" })).toHaveLength(2); expect(await screen.findAllByText("dashboard")).toHaveLength(2); - expect(screen.getByTestId("numeric-text")).toHaveTextContent("4"); + expect(screen.getByText("online").closest("button")).toHaveTextContent("4"); expect(screen.getByText("online")).toBeInTheDocument(); await waitFor(() => { diff --git a/src/test/components/server-detail-components.test.tsx b/src/test/components/server-detail-components.test.tsx index 9c9f2a7..c687be6 100644 --- a/src/test/components/server-detail-components.test.tsx +++ b/src/test/components/server-detail-components.test.tsx @@ -14,10 +14,6 @@ const websocketMocks = vi.hoisted(() => ({ } | null, })); -vi.mock("@numeric-text/react", () => ({ - default: ({ value }: { value: string | number }) => {value}, -})); - vi.mock("@/hooks/use-websocket-context", () => ({ useWebSocketContext: () => websocketMocks, }));