feat: nextui
This commit is contained in:
3
hero.ts
Normal file
3
hero.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// hero.ts
|
||||||
|
import { heroui } from "@heroui/react";
|
||||||
|
export default heroui();
|
||||||
4480
package-lock.json
generated
4480
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
22
package.json
22
package.json
@@ -14,6 +14,17 @@
|
|||||||
"dev": "webpack serve --mode development --open",
|
"dev": "webpack serve --mode development --open",
|
||||||
"build": "webpack --mode production"
|
"build": "webpack --mode production"
|
||||||
},
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@heroui/react": "^2.8.5",
|
||||||
|
"@tailwindcss/postcss": "^4.1.16",
|
||||||
|
"axios": "^1.13.1",
|
||||||
|
"framer-motion": "^12.23.24",
|
||||||
|
"next-themes": "^0.4.6",
|
||||||
|
"react": "^19.2.0",
|
||||||
|
"react-dom": "^19.2.0",
|
||||||
|
"react-icons": "^5.5.0",
|
||||||
|
"zustand": "^5.0.8"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.28.5",
|
"@babel/core": "^7.28.5",
|
||||||
"@babel/preset-env": "^7.28.5",
|
"@babel/preset-env": "^7.28.5",
|
||||||
@@ -43,16 +54,5 @@
|
|||||||
"webpack": "^5.102.1",
|
"webpack": "^5.102.1",
|
||||||
"webpack-cli": "^6.0.1",
|
"webpack-cli": "^6.0.1",
|
||||||
"webpack-dev-server": "^5.2.2"
|
"webpack-dev-server": "^5.2.2"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@chakra-ui/react": "^3.28.0",
|
|
||||||
"@emotion/react": "^11.14.0",
|
|
||||||
"@tailwindcss/postcss": "^4.1.16",
|
|
||||||
"axios": "^1.13.1",
|
|
||||||
"next-themes": "^0.4.6",
|
|
||||||
"react": "^19.2.0",
|
|
||||||
"react-dom": "^19.2.0",
|
|
||||||
"react-icons": "^5.5.0",
|
|
||||||
"zustand": "^5.0.8"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
import Demo from '@/pages/demo';
|
import Demo from '@/pages/demo';
|
||||||
import { Provider } from '@/components/ui/provider';
|
import { HeroUIProvider as Provider } from "@heroui/react" ;
|
||||||
|
import './styles/globals.css';
|
||||||
import './styles/main.scss';
|
import './styles/main.scss';
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
|
|||||||
@@ -1,108 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import type { IconButtonProps, SpanProps } from "@chakra-ui/react"
|
|
||||||
import { ClientOnly, IconButton, Skeleton, Span } from "@chakra-ui/react"
|
|
||||||
import { ThemeProvider, useTheme } from "next-themes"
|
|
||||||
import type { ThemeProviderProps } from "next-themes"
|
|
||||||
import * as React from "react"
|
|
||||||
import { LuMoon, LuSun } from "react-icons/lu"
|
|
||||||
|
|
||||||
export interface ColorModeProviderProps extends ThemeProviderProps {}
|
|
||||||
|
|
||||||
export function ColorModeProvider(props: ColorModeProviderProps) {
|
|
||||||
return (
|
|
||||||
<ThemeProvider attribute="class" disableTransitionOnChange {...props} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ColorMode = "light" | "dark"
|
|
||||||
|
|
||||||
export interface UseColorModeReturn {
|
|
||||||
colorMode: ColorMode
|
|
||||||
setColorMode: (colorMode: ColorMode) => void
|
|
||||||
toggleColorMode: () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useColorMode(): UseColorModeReturn {
|
|
||||||
const { resolvedTheme, setTheme, forcedTheme } = useTheme()
|
|
||||||
const colorMode = forcedTheme || resolvedTheme
|
|
||||||
const toggleColorMode = () => {
|
|
||||||
setTheme(resolvedTheme === "dark" ? "light" : "dark")
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
colorMode: colorMode as ColorMode,
|
|
||||||
setColorMode: setTheme,
|
|
||||||
toggleColorMode,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useColorModeValue<T>(light: T, dark: T) {
|
|
||||||
const { colorMode } = useColorMode()
|
|
||||||
return colorMode === "dark" ? dark : light
|
|
||||||
}
|
|
||||||
|
|
||||||
export function ColorModeIcon() {
|
|
||||||
const { colorMode } = useColorMode()
|
|
||||||
return colorMode === "dark" ? <LuMoon /> : <LuSun />
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ColorModeButtonProps extends Omit<IconButtonProps, "aria-label"> {}
|
|
||||||
|
|
||||||
export const ColorModeButton = React.forwardRef<
|
|
||||||
HTMLButtonElement,
|
|
||||||
ColorModeButtonProps
|
|
||||||
>(function ColorModeButton(props, ref) {
|
|
||||||
const { toggleColorMode } = useColorMode()
|
|
||||||
return (
|
|
||||||
<ClientOnly fallback={<Skeleton boxSize="9" />}>
|
|
||||||
<IconButton
|
|
||||||
onClick={toggleColorMode}
|
|
||||||
variant="ghost"
|
|
||||||
aria-label="Toggle color mode"
|
|
||||||
size="sm"
|
|
||||||
ref={ref}
|
|
||||||
{...props}
|
|
||||||
css={{
|
|
||||||
_icon: {
|
|
||||||
width: "5",
|
|
||||||
height: "5",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ColorModeIcon />
|
|
||||||
</IconButton>
|
|
||||||
</ClientOnly>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
export const LightMode = React.forwardRef<HTMLSpanElement, SpanProps>(
|
|
||||||
function LightMode(props, ref) {
|
|
||||||
return (
|
|
||||||
<Span
|
|
||||||
color="fg"
|
|
||||||
display="contents"
|
|
||||||
className="chakra-theme light"
|
|
||||||
colorPalette="gray"
|
|
||||||
colorScheme="light"
|
|
||||||
ref={ref}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
export const DarkMode = React.forwardRef<HTMLSpanElement, SpanProps>(
|
|
||||||
function DarkMode(props, ref) {
|
|
||||||
return (
|
|
||||||
<Span
|
|
||||||
color="fg"
|
|
||||||
display="contents"
|
|
||||||
className="chakra-theme dark"
|
|
||||||
colorPalette="gray"
|
|
||||||
colorScheme="dark"
|
|
||||||
ref={ref}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { ChakraProvider, defaultSystem } from "@chakra-ui/react"
|
|
||||||
import {
|
|
||||||
ColorModeProvider,
|
|
||||||
type ColorModeProviderProps,
|
|
||||||
} from "./color-mode"
|
|
||||||
|
|
||||||
export function Provider(props: ColorModeProviderProps) {
|
|
||||||
return (
|
|
||||||
<ChakraProvider value={defaultSystem}>
|
|
||||||
<ColorModeProvider {...props} />
|
|
||||||
</ChakraProvider>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
"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 (
|
|
||||||
<Portal>
|
|
||||||
<ChakraToaster toaster={toaster} insetInline={{ mdDown: "4" }}>
|
|
||||||
{(toast) => (
|
|
||||||
<Toast.Root width={{ md: "sm" }}>
|
|
||||||
{toast.type === "loading" ? (
|
|
||||||
<Spinner size="sm" color="blue.solid" />
|
|
||||||
) : (
|
|
||||||
<Toast.Indicator />
|
|
||||||
)}
|
|
||||||
<Stack gap="1" flex="1" maxWidth="100%">
|
|
||||||
{toast.title && <Toast.Title>{toast.title}</Toast.Title>}
|
|
||||||
{toast.description && (
|
|
||||||
<Toast.Description>{toast.description}</Toast.Description>
|
|
||||||
)}
|
|
||||||
</Stack>
|
|
||||||
{toast.action && (
|
|
||||||
<Toast.ActionTrigger>{toast.action.label}</Toast.ActionTrigger>
|
|
||||||
)}
|
|
||||||
{toast.closable && <Toast.CloseTrigger />}
|
|
||||||
</Toast.Root>
|
|
||||||
)}
|
|
||||||
</ChakraToaster>
|
|
||||||
</Portal>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
import { Tooltip as ChakraTooltip, Portal } from "@chakra-ui/react"
|
|
||||||
import * as React from "react"
|
|
||||||
|
|
||||||
export interface TooltipProps extends ChakraTooltip.RootProps {
|
|
||||||
showArrow?: boolean
|
|
||||||
portalled?: boolean
|
|
||||||
portalRef?: React.RefObject<HTMLElement | null>
|
|
||||||
content: React.ReactNode
|
|
||||||
contentProps?: ChakraTooltip.ContentProps
|
|
||||||
disabled?: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>(
|
|
||||||
function Tooltip(props, ref) {
|
|
||||||
const {
|
|
||||||
showArrow,
|
|
||||||
children,
|
|
||||||
disabled,
|
|
||||||
portalled = true,
|
|
||||||
content,
|
|
||||||
contentProps,
|
|
||||||
portalRef,
|
|
||||||
...rest
|
|
||||||
} = props
|
|
||||||
|
|
||||||
if (disabled) return children
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ChakraTooltip.Root {...rest}>
|
|
||||||
<ChakraTooltip.Trigger asChild>{children}</ChakraTooltip.Trigger>
|
|
||||||
<Portal disabled={!portalled} container={portalRef}>
|
|
||||||
<ChakraTooltip.Positioner>
|
|
||||||
<ChakraTooltip.Content ref={ref} {...contentProps}>
|
|
||||||
{showArrow && (
|
|
||||||
<ChakraTooltip.Arrow>
|
|
||||||
<ChakraTooltip.ArrowTip />
|
|
||||||
</ChakraTooltip.Arrow>
|
|
||||||
)}
|
|
||||||
{content}
|
|
||||||
</ChakraTooltip.Content>
|
|
||||||
</ChakraTooltip.Positioner>
|
|
||||||
</Portal>
|
|
||||||
</ChakraTooltip.Root>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
5
src/styles/globals.css
Normal file
5
src/styles/globals.css
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
@import "tailwindcss";
|
||||||
|
@plugin './hero.ts';
|
||||||
|
/* Note: You may need to change the path to fit your project structure */
|
||||||
|
@source '../../node_modules/@heroui/theme/dist/**/*.{js,ts,jsx,tsx}';
|
||||||
|
@custom-variant dark (&:is(.dark *));
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
// 或者保留命名空间(更推荐,避免全局污染)
|
|
||||||
@use "tailwindcss";
|
|
||||||
|
|
||||||
// 全局样式重置
|
// 全局样式重置
|
||||||
* {
|
* {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user