From fdeaa056129e237c495aff2532a575a3ab4d3aa4 Mon Sep 17 00:00:00 2001 From: Jerry Date: Wed, 28 May 2025 14:02:50 +0800 Subject: [PATCH] =?UTF-8?q?=E8=83=BD=E8=B7=91=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frontend/package.json | 2 + src/frontend/pnpm-lock.yaml | 26 ++++++ src/frontend/src/App.jsx | 23 ++--- src/frontend/src/components/ui/color-mode.jsx | 90 +++++++++++++++++++ src/frontend/src/components/ui/provider.jsx | 12 +++ src/frontend/src/components/ui/toaster.jsx | 43 +++++++++ src/frontend/src/components/ui/tooltip.jsx | 35 ++++++++ src/frontend/src/index.js | 6 +- 8 files changed, 224 insertions(+), 13 deletions(-) create mode 100644 src/frontend/src/components/ui/color-mode.jsx create mode 100644 src/frontend/src/components/ui/provider.jsx create mode 100644 src/frontend/src/components/ui/toaster.jsx create mode 100644 src/frontend/src/components/ui/tooltip.jsx diff --git a/src/frontend/package.json b/src/frontend/package.json index 391129e..2a32a7b 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -12,9 +12,11 @@ "@testing-library/user-event": "^13.5.0", "axios": "^1.9.0", "framer-motion": "^12.14.0", + "next-themes": "^0.4.6", "prettierrc": "0.0.0-5", "react": "^19.1.0", "react-dom": "^19.1.0", + "react-icons": "^5.5.0", "react-router-dom": "^7.6.1", "react-scripts": "^5.0.1", "recharts": "^2.15.3", diff --git a/src/frontend/pnpm-lock.yaml b/src/frontend/pnpm-lock.yaml index 174c7a0..1473485 100644 --- a/src/frontend/pnpm-lock.yaml +++ b/src/frontend/pnpm-lock.yaml @@ -35,6 +35,9 @@ importers: framer-motion: specifier: ^12.14.0 version: 12.15.0(@emotion/is-prop-valid@1.3.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next-themes: + specifier: ^0.4.6 + version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) prettierrc: specifier: 0.0.0-5 version: 0.0.0-5(prettier@1.19.1) @@ -44,6 +47,9 @@ importers: react-dom: specifier: ^19.1.0 version: 19.1.0(react@19.1.0) + react-icons: + specifier: ^5.5.0 + version: 5.5.0(react@19.1.0) react-router-dom: specifier: ^7.6.1 version: 7.6.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -4438,6 +4444,12 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + next-themes@0.4.6: + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} + peerDependencies: + react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc + no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} @@ -5271,6 +5283,11 @@ packages: react-error-overlay@6.1.0: resolution: {integrity: sha512-SN/U6Ytxf1QGkw/9ve5Y+NxBbZM6Ht95tuXNMKs8EJyFa/Vy/+Co3stop3KBHARfn/giv+Lj1uUnTfOJ3moFEQ==} + react-icons@5.5.0: + resolution: {integrity: sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==} + peerDependencies: + react: '*' + react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -12021,6 +12038,11 @@ snapshots: neo-async@2.6.2: {} + next-themes@0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + no-case@3.0.4: dependencies: lower-case: 2.0.2 @@ -12881,6 +12903,10 @@ snapshots: react-error-overlay@6.1.0: {} + react-icons@5.5.0(react@19.1.0): + dependencies: + react: 19.1.0 + react-is@16.13.1: {} react-is@17.0.2: {} diff --git a/src/frontend/src/App.jsx b/src/frontend/src/App.jsx index b9bcde6..2aa2790 100644 --- a/src/frontend/src/App.jsx +++ b/src/frontend/src/App.jsx @@ -1,17 +1,20 @@ import React from 'react'; -import { Routes, Route } from 'react-router-dom'; -import Dashboard from './pages/Dashboard'; -import Configuration from './pages/Configuration'; -import Header from './components/Header'; +//import { Button, HStack } from '@chakra-ui/react'; +//import { Routes, Route } from 'react-router-dom'; +//import Dashboard from './pages/Dashboard'; +//import Configuration from './pages/Configuration'; +//import Header from './components/Header'; +//import { Box, Button } from '@chakra-ui/react'; -const App = () => ( +const App = () => (//待扩展 <> -
- - } /> - } /> - ); +/**备用 + * + * } /> + * } /> + * + */ export default App; \ No newline at end of file diff --git a/src/frontend/src/components/ui/color-mode.jsx b/src/frontend/src/components/ui/color-mode.jsx new file mode 100644 index 0000000..b2d1cd6 --- /dev/null +++ b/src/frontend/src/components/ui/color-mode.jsx @@ -0,0 +1,90 @@ +'use client' + +import { ClientOnly, IconButton, Skeleton, Span } from '@chakra-ui/react' +import { ThemeProvider, useTheme } from 'next-themes' + +import * as React from 'react' +import { LuMoon, LuSun } from 'react-icons/lu' + +export function ColorModeProvider(props) { + return ( + + ) +} + +export function useColorMode() { + const { resolvedTheme, setTheme, forcedTheme } = useTheme() + const colorMode = forcedTheme || resolvedTheme + const toggleColorMode = () => { + setTheme(resolvedTheme === 'dark' ? 'light' : 'dark') + } + return { + colorMode: colorMode, + setColorMode: setTheme, + toggleColorMode, + } +} + +export function useColorModeValue(light, dark) { + const { colorMode } = useColorMode() + return colorMode === 'dark' ? dark : light +} + +export function ColorModeIcon() { + const { colorMode } = useColorMode() + return colorMode === 'dark' ? : +} + +export const ColorModeButton = React.forwardRef( + function ColorModeButton(props, ref) { + const { toggleColorMode } = useColorMode() + return ( + }> + + + + + ) + }, +) + +export const LightMode = React.forwardRef(function LightMode(props, ref) { + return ( + + ) +}) + +export const DarkMode = React.forwardRef(function DarkMode(props, ref) { + return ( + + ) +}) diff --git a/src/frontend/src/components/ui/provider.jsx b/src/frontend/src/components/ui/provider.jsx new file mode 100644 index 0000000..80e3e01 --- /dev/null +++ b/src/frontend/src/components/ui/provider.jsx @@ -0,0 +1,12 @@ +'use client' + +import { ChakraProvider, defaultSystem } from '@chakra-ui/react' +import { ColorModeProvider } from './color-mode' + +export function Provider(props) { + return ( + + + + ) +} diff --git a/src/frontend/src/components/ui/toaster.jsx b/src/frontend/src/components/ui/toaster.jsx new file mode 100644 index 0000000..6af2b70 --- /dev/null +++ b/src/frontend/src/components/ui/toaster.jsx @@ -0,0 +1,43 @@ +'use client' + +import { + Toaster as ChakraToaster, + Portal, + Spinner, + Stack, + Toast, + createToaster, +} from '@chakra-ui/react' + +export const toaster = createToaster({ + placement: 'bottom-end', + pauseOnPageIdle: true, +}) + +export const Toaster = () => { + return ( + + + {(toast) => ( + + {toast.type === 'loading' ? ( + + ) : ( + + )} + + {toast.title && {toast.title}} + {toast.description && ( + {toast.description} + )} + + {toast.action && ( + {toast.action.label} + )} + {toast.closable && } + + )} + + + ) +} diff --git a/src/frontend/src/components/ui/tooltip.jsx b/src/frontend/src/components/ui/tooltip.jsx new file mode 100644 index 0000000..ab225cc --- /dev/null +++ b/src/frontend/src/components/ui/tooltip.jsx @@ -0,0 +1,35 @@ +import { Tooltip as ChakraTooltip, Portal } from '@chakra-ui/react' +import * as React from 'react' + +export const Tooltip = React.forwardRef(function Tooltip(props, ref) { + const { + showArrow, + children, + disabled, + portalled = true, + content, + contentProps, + portalRef, + ...rest + } = props + + if (disabled) return children + + return ( + + {children} + + + + {showArrow && ( + + + + )} + {content} + + + + + ) +}) diff --git a/src/frontend/src/index.js b/src/frontend/src/index.js index 97f201d..5ac5ed0 100644 --- a/src/frontend/src/index.js +++ b/src/frontend/src/index.js @@ -1,14 +1,14 @@ import React from 'react' import ReactDOM from 'react-dom/client' import App from './App' -import {ChakraProvider} from '@chakra-ui/react'; import { BrowserRouter } from 'react-router-dom'; +import {Provider} from './components/ui/provider' const root = ReactDOM.createRoot(document.getElementById('root')); root.render( - + - + )