first commit
This commit is contained in:
+70
@@ -0,0 +1,70 @@
|
||||
.height_40 {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.height_40_center {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.display_inline_block {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.text_center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.width_300 {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.width_400 {
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
.margin_3_0 {
|
||||
margin: 3px 0;
|
||||
}
|
||||
|
||||
.margin_10_20 {
|
||||
margin: 10px 20px;
|
||||
}
|
||||
|
||||
.margin_10_0 {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.margin_0_20 {
|
||||
margin: 0 20px;
|
||||
}
|
||||
|
||||
.margin_0_10 {
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
.margin_10_10 {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.margin_20_10 {
|
||||
margin: 20px 10px;
|
||||
}
|
||||
|
||||
.margin_0_5 {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.width_600 {
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.margin_left_600 {
|
||||
margin-left: 600px;
|
||||
}
|
||||
|
||||
.right-align-container {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
// import { useState } from 'react'
|
||||
import './App.css'
|
||||
|
||||
import { HomeOutlined, SettingOutlined, ApiOutlined, FolderOutlined, ClearOutlined, UserOutlined, CommentOutlined, AlertOutlined, UploadOutlined } from '@ant-design/icons';
|
||||
import type { MenuProps } from 'antd';
|
||||
import { Menu } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
import { Input, Avatar } from 'antd';
|
||||
import { SearchOutlined } from '@ant-design/icons';
|
||||
|
||||
const items: MenuProps['items'] = [
|
||||
|
||||
{
|
||||
label: '主页',
|
||||
key: 'home',
|
||||
icon: <HomeOutlined />,
|
||||
},
|
||||
{
|
||||
label: '工具大全',
|
||||
key: 'tools',
|
||||
icon: <ApiOutlined />,
|
||||
},
|
||||
{
|
||||
label: '文章资源',
|
||||
key: 'articles',
|
||||
icon: <FolderOutlined />,
|
||||
},
|
||||
{
|
||||
label: '消息',
|
||||
key: 'xx',
|
||||
icon: <CommentOutlined />,
|
||||
children:[
|
||||
{
|
||||
label: '回复我的',
|
||||
key: 'xx1',
|
||||
},
|
||||
{
|
||||
label: '@我的',
|
||||
key: 'xx2',
|
||||
},
|
||||
{
|
||||
label: '收到的赞',
|
||||
key: 'xx3',
|
||||
},
|
||||
{
|
||||
label: '系统消息',
|
||||
key: 'xx4',
|
||||
},
|
||||
{
|
||||
label: '我的消息',
|
||||
key: 'xx5',
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'bug反馈',
|
||||
key: 'bug',
|
||||
icon: <AlertOutlined />,
|
||||
},
|
||||
{
|
||||
label: (<Input
|
||||
placeholder="请输入搜索内容"
|
||||
className='width_600 height_40 margin_3_0 margin_left_600'
|
||||
prefix={<SearchOutlined />}
|
||||
/>),
|
||||
key: 'search',
|
||||
disabled: true,
|
||||
className: "right-align-container",
|
||||
},
|
||||
{
|
||||
label: (<span className='margin_0_20' >
|
||||
|
||||
<Avatar size={40} icon={<UserOutlined />} className='margin_3_0'/>
|
||||
<span className='height_40_center display_inline_block margin_0_10' >
|
||||
用户: 10086
|
||||
</span>
|
||||
</span>),
|
||||
key: 'home',
|
||||
children: [
|
||||
{
|
||||
className: "width_300",
|
||||
type: 'group',
|
||||
label: (
|
||||
<div className='height_40_center text_center'>用户10086</div>
|
||||
),
|
||||
children: [
|
||||
{
|
||||
label: '个人中心',
|
||||
key: 'setting:1',
|
||||
icon: <UserOutlined />
|
||||
},
|
||||
{
|
||||
label: '个人设置',
|
||||
key: 'setting:2',
|
||||
icon: <SettingOutlined />,
|
||||
},
|
||||
|
||||
{
|
||||
label: '浏览历史',
|
||||
key: 'setting:2',
|
||||
icon: <ClearOutlined />
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<div style={{
|
||||
borderBottom: "1px #eee solid",
|
||||
height:"20px"
|
||||
}}></div>
|
||||
),
|
||||
disabled: true,
|
||||
key: 'divider',
|
||||
},
|
||||
{
|
||||
label: '退出登录',
|
||||
key: 'setting:3',
|
||||
icon: <UploadOutlined />
|
||||
}
|
||||
],
|
||||
}
|
||||
],
|
||||
className: "right-align-container",
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [current, setCurrent] = useState('mail');
|
||||
|
||||
const onClick: MenuProps['onClick'] = e => {
|
||||
console.log('click ', e);
|
||||
setCurrent(e.key);
|
||||
};
|
||||
return (
|
||||
<div style={{
|
||||
borderBottom: "1px solid #eee",
|
||||
margin: "10px 10px"
|
||||
}}>
|
||||
|
||||
<Menu onClick={onClick} selectedKeys={[current]} mode="horizontal" items={items} style = {{
|
||||
border: "0"
|
||||
}} />
|
||||
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
@@ -0,0 +1,108 @@
|
||||
"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}
|
||||
/>
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,15 @@
|
||||
"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>
|
||||
)
|
||||
}
|
||||
@@ -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 (
|
||||
<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>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
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>
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,11 @@
|
||||
import { StrictMode } from 'react'
|
||||
import { createRoot } from 'react-dom/client'
|
||||
import './index.css'
|
||||
import 'antd/dist/antd.css';
|
||||
import App from './App.tsx'
|
||||
|
||||
createRoot(document.getElementById('root')!).render(
|
||||
<StrictMode>
|
||||
<App />
|
||||
</StrictMode>,
|
||||
)
|
||||
Reference in New Issue
Block a user