Commit 5559551b by HoMeTown

feat: 侧边栏样式

parent 375a6f9e
import './App.css' import './App.css'
import { Button } from '@nextui-org/button'
import { useToggle } from '@reactuses/core'
import { motion } from 'framer-motion'
import React from 'react' import React from 'react'
import { BrowserRouter as Router } from 'react-router-dom'
import { MainLayout } from './layouts'
import { AppRoutes } from './routes/AppRoutes'
const App: React.FC = () => { const App: React.FC = () => {
const [on, toggle] = useToggle(true)
return ( return (
<div> <Router>
<motion.div <MainLayout>
className="w-[100px] h-[100px] bg-slate-300" <AppRoutes />
> </MainLayout>
{on ? 'ON' : 'OFF'} </Router>
</motion.div>
<Button color="primary" onClick={toggle}>Toggle</Button>
</div>
) )
} }
......
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>对话</title>
<defs>
<rect id="path-1" x="0" y="0" width="24" height="24"></rect>
</defs>
<g id="晓得---PC端页面-草稿" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="晓得-PC端---默认页" transform="translate(-32.000000, -413.000000)">
<g id="左侧导航栏" transform="translate(12.000000, 290.000000)">
<g id="新建对话" transform="translate(8.000000, 115.000000)">
<rect id="矩形" x="4" y="0" width="40" height="40" rx="14.2857143"></rect>
<g id="对话" transform="translate(12.000000, 8.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<path d="M18,0 C21.3137085,-6.08718376e-16 24,2.6862915 24,6 L24,15 C24,15.5182152 23.9343031,16.0210861 23.8107837,16.5007383 C23.1450654,13.912286 20.7958519,12 18,12 C14.6862915,12 12,14.6862915 12,18 C12,19.6568542 12.6715729,21.1568542 13.7573593,22.2426407 L13.0606602,22.9393398 C12.4748737,23.5251263 11.5251263,23.5251263 10.9393398,22.9393398 L9,21 L6,21 C2.6862915,21 4.05812251e-16,18.3137085 0,15 L0,6 C-4.05812251e-16,2.6862915 2.6862915,6.08718376e-16 6,0 L18,0 Z M8.5,12 L5.5,12 C4.67157288,12 4,12.6715729 4,13.5 C4,14.2796961 4.59488808,14.9204487 5.35553999,14.9931334 L5.5,15 L8.5,15 C9.32842712,15 10,14.3284271 10,13.5 C10,12.6715729 9.32842712,12 8.5,12 Z M18.5,6 L5.5,6 C4.67157288,6 4,6.67157288 4,7.5 C4,8.27969612 4.59488808,8.92044868 5.35553999,8.99313342 L5.5,9 L18.5,9 C19.3284271,9 20,8.32842712 20,7.5 C20,6.67157288 19.3284271,6 18.5,6 Z" id="形状结合" fill="#8C989C" mask="url(#mask-2)"></path>
<path d="M15,17 L17,17 L17,17 L17,15 C17,14.4477153 17.4477153,14 18,14 C18.5522847,14 19,14.4477153 19,15 L19,17 L19,17 L21,17 C21.5522847,17 22,17.4477153 22,18 C22,18.5522847 21.5522847,19 21,19 L19,19 L19,19 L19,21 C19,21.5522847 18.5522847,22 18,22 C17.4477153,22 17,21.5522847 17,21 L17,19 L17,19 L15,19 C14.4477153,19 14,18.5522847 14,18 C14,17.4477153 14.4477153,17 15,17 Z" id="矩形" fill="#8C989C" mask="url(#mask-2)"></path>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>历史对话</title>
<defs>
<rect id="path-1" x="0" y="0" width="24" height="24"></rect>
</defs>
<g id="晓得---PC端页面-草稿" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="晓得-PC端---默认页" transform="translate(-32.000000, -601.000000)">
<g id="左侧导航栏" transform="translate(12.000000, 290.000000)">
<g id="历史对话备份" transform="translate(12.000000, 303.000000)">
<rect id="矩形" x="0" y="0" width="40" height="40" rx="14.2857143"></rect>
<g id="历史对话" transform="translate(8.000000, 8.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<path d="M19.5758925,-5.86197757e-14 C21.4669749,-5.85230727e-14 23,1.53302514 23,3.42410748 L23,19.8028645 C23,22.0120035 21.209139,23.8028645 19,23.8028645 C18.3314655,23.8028645 17.673593,23.6353027 17.0865143,23.3154949 L12,20.5446449 L6.91348566,23.3154949 C4.97351344,24.3722839 2.54415851,23.6563224 1.48736956,21.7163501 C1.16756177,21.1292715 1,20.4713989 1,19.8028645 L1,3.42410748 C1,1.53302514 2.53302514,-5.87164787e-14 4.42410748,-5.86197757e-14 L19.5758925,-5.86197757e-14 Z M12,4 C11.1715729,4 10.5,4.67157288 10.5,5.5 L10.5,5.5 L10.5,8.5 L7.5,8.5 C6.67157288,8.5 6,9.17157288 6,10 C6,10.8284271 6.67157288,11.5 7.5,11.5 L7.5,11.5 L10.5,11.5 L10.5,14.5 C10.5,15.3284271 11.1715729,16 12,16 C12.8284271,16 13.5,15.3284271 13.5,14.5 L13.5,14.5 L13.5,11.5 L16.5,11.5 C17.3284271,11.5 18,10.8284271 18,10 C18,9.17157288 17.3284271,8.5 16.5,8.5 L16.5,8.5 L13.5,8.5 L13.5,5.5 C13.5,4.67157288 12.8284271,4 12,4 Z" id="形状结合" fill="#8C989C" fill-rule="nonzero" mask="url(#mask-2)"></path>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>历史对话</title>
<defs>
<rect id="path-1" x="0" y="0" width="24" height="24"></rect>
</defs>
<g id="晓得---PC端页面-草稿" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="晓得-PC端---默认页" transform="translate(-32.000000, -507.000000)">
<g id="左侧导航栏" transform="translate(12.000000, 290.000000)">
<g id="历史对话" transform="translate(8.000000, 209.000000)">
<rect id="矩形" x="4" y="0" width="40" height="40" rx="14.2857143"></rect>
<g transform="translate(12.000000, 8.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<path d="M7.5,16 L6.5,16 C5.67157288,16 5,16.6715729 5,17.5 C5,18.2796961 5.59488808,18.9204487 6.35553999,18.9931334 L6.5,19 L7.5,19 C8.32842712,19 9,18.3284271 9,17.5 C9,16.6715729 8.32842712,16 7.5,16 Z M9.5,10 L6.5,10 C5.67157288,10 5,10.6715729 5,11.5 C5,12.2796961 5.59488808,12.9204487 6.35553999,12.9931334 L6.5,13 L9.5,13 C10.3284271,13 11,12.3284271 11,11.5 C11,10.6715729 10.3284271,10 9.5,10 Z M17.5,4 L6.5,4 C5.67157288,4 5,4.67157288 5,5.5 C5,6.27969612 5.59488808,6.92044868 6.35553999,6.99313342 L6.5,7 L17.5,7 C18.3284271,7 19,6.32842712 19,5.5 C19,4.67157288 18.3284271,4 17.5,4 Z M17,12 C13.6862915,12 11,14.6862915 11,18 C11,21.3137085 13.6862915,24 17,24 L7,24 C3.6862915,24 1,21.3137085 1,18 L1,6 C1,2.6862915 3.6862915,6.08718376e-16 7,0 L17,0 C20.3137085,-6.08718376e-16 23,2.6862915 23,6 L23,18 C23,14.6862915 20.3137085,12 17,12 Z" id="形状结合" fill="#8C989C" mask="url(#mask-2)"></path>
<path d="M17,14 C17.5522847,14 18,14.4477153 18,15 L18,18 L20,18 C20.5522847,18 21,18.4477153 21,19 C21,19.5522847 20.5522847,20 20,20 L17,20 L17,20 C16.4477153,20 16,19.5522847 16,19 L16,15 C16,14.4477153 16.4477153,14 17,14 Z" id="形状结合" fill="#8C989C" mask="url(#mask-2)"></path>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>产品</title>
<defs>
<rect id="path-1" x="0" y="0" width="24" height="24"></rect>
</defs>
<g id="晓得---PC端页面-草稿" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="晓得-PC端---默认页" transform="translate(-32.000000, -704.000000)">
<g id="左侧导航栏" transform="translate(12.000000, 290.000000)">
<g id="产品" transform="translate(12.000000, 406.000000)">
<g transform="translate(8.000000, 8.000000)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="蒙版"></g>
<path d="M9.75,12.75 C10.5784271,12.75 11.25,13.4215729 11.25,14.25 L11.25,18.375 C11.25,21.4816017 8.73160172,24 5.625,24 C2.51839828,24 3.80448985e-16,21.4816017 0,18.375 C-3.80448985e-16,15.2683983 2.51839828,12.75 5.625,12.75 L9.75,12.75 Z M5.625,0 C8.73160172,-5.70673477e-16 11.25,2.51839828 11.25,5.625 L11.25,9.75 C11.25,10.5784271 10.5784271,11.25 9.75,11.25 L5.625,11.25 C2.51839828,11.25 3.80448985e-16,8.73160172 0,5.625 C-3.80448985e-16,2.51839828 2.51839828,5.70673477e-16 5.625,0 Z M21.2857143,19.1428571 C22.0746925,19.1428571 22.7142857,19.7824504 22.7142857,20.5714286 C22.7142857,21.3604068 22.0746925,22 21.2857143,22 L14.4285714,22 C13.6395932,22 13,21.3604068 13,20.5714286 C13,19.7824504 13.6395932,19.1428571 14.4285714,19.1428571 L21.2857143,19.1428571 Z M21.2857143,14 C22.0746925,14 22.7142857,14.6395932 22.7142857,15.4285714 C22.7142857,16.2175496 22.0746925,16.8571429 21.2857143,16.8571429 L14.4285714,16.8571429 C13.6395932,16.8571429 13,16.2175496 13,15.4285714 C13,14.6395932 13.6395932,14 14.4285714,14 L21.2857143,14 Z M18.375,0 C21.4816017,-5.70673477e-16 24,2.51839828 24,5.625 C24,8.73160172 21.4816017,11.25 18.375,11.25 L14.25,11.25 C13.4215729,11.25 12.75,10.5784271 12.75,9.75 L12.75,5.625 C12.75,2.51839828 15.2683983,5.70673477e-16 18.375,0 Z" id="形状结合" fill="#8C989C" mask="url(#mask-2)"></path>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
/// <reference types="@rsbuild/core/types" /> /// <reference types="@rsbuild/core/types" />
declare module '*.svg' {
const content: string
export default content
}
declare module '*.svg?react' {
const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>
export default ReactComponent
}
import React from 'react' import React from 'react'
import ReactDOM from 'react-dom/client' import ReactDOM from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'
import { NextUIProvider } from '@nextui-org/react' import { NextUIProvider } from '@nextui-org/react'
import { motion } from 'framer-motion'
import App from './App' import App from './App'
import './styles/index.less' import './styles/index.less'
...@@ -15,11 +13,7 @@ if (rootEl) { ...@@ -15,11 +13,7 @@ if (rootEl) {
root.render( root.render(
<React.StrictMode> <React.StrictMode>
<NextUIProvider className="h-full"> <NextUIProvider className="h-full">
<BrowserRouter> <App />
<motion.main className="h-full">
<App />
</motion.main>
</BrowserRouter>
</NextUIProvider> </NextUIProvider>
</React.StrictMode>, </React.StrictMode>,
) )
......
.layoutMain {
height: 100%;
display: flex;
}
.layoutContent {
flex: 1 1;
height: 100%;
width: 100%;
position: relative;
}
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
layoutContent: string
layoutMain: string
}
declare const cssExports: CssExports
export default cssExports
import type React from 'react'
import { motion } from 'framer-motion'
import { useToggle } from '@reactuses/core'
import { Navbar } from '../Navbar'
import styles from './MainLayout.module.less'
interface MainLayoutProps {
children: React.ReactNode
}
export const MainLayout: React.FC<MainLayoutProps> = ({ children }) => {
const [isNavCollapsed, toggleNav] = useToggle(true)
return (
<motion.main className={styles.layoutMain}>
<Navbar isCollapsed={isNavCollapsed} onToggle={toggleNav} />
<motion.div className={styles.layoutContent}>
{children}
</motion.div>
</motion.main>
)
}
export { MainLayout } from './MainLayout'
.layoutNav {
height: 100%;
position: relative;
transition: width .2s ease;
}
.collapsed {
width: 68px;
z-index: 1030;
}
.layoutNavBar {
position: absolute;
top: 50%;
right: -8px;
transform: translateY(-50%);
z-index: 101;
}
.layoutNavBarAgent {
width: 64px;
background: #FFFFFF;
border-radius: var(--sdream-radius-large);
box-sizing: border-box;
padding: 24px 8px;
display: flex;
flex-direction: column;
align-items: center;
// box-shadow: var(--sdream-box-shadow-small);
}
.layoutNavHot {
width: 96px;
height: 100%;
}
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
collapsed: string
layoutNav: string
layoutNavBar: string
layoutNavBarAgent: string
layoutNavHot: string
}
declare const cssExports: CssExports
export default cssExports
import type React from 'react'
import { motion } from 'framer-motion'
import styles from './Navbar.module.less'
import { NavBarItem } from './components/NavBarItem'
import Logo from '@/assets/svg/logo.svg?react'
import AddNewChat from '@/assets/svg/addNewChat.svg?react'
import HistoryChat from '@/assets/svg/historyChat.svg?react'
import Collect from '@/assets/svg/collect.svg?react'
import Tools from '@/assets/svg/tools.svg?react'
interface NavbarProps {
isCollapsed: boolean
onToggle: () => void
}
const NAV_BAR_ITEMS = [
{ icon: Logo, label: '', key: 'logo' },
{ icon: '', label: '', key: 'line1' },
{ icon: AddNewChat, label: '新建对话', key: 'add' },
{ icon: HistoryChat, label: '历史对话', key: 'history' },
{ icon: Collect, label: '收藏', key: 'collect' },
{ icon: '', label: '', key: 'line2' },
{ icon: Tools, label: '工具', key: 'tools' },
]
// onToggle
export const Navbar: React.FC<NavbarProps> = ({ isCollapsed }) => {
return (
<motion.nav className={`${styles.layoutNav} ${isCollapsed ? styles.collapsed : ''}`}>
<motion.div className={styles.layoutNavBar}>
<motion.div className={`${styles.layoutNavBarAgent} bg-white gap-[32px]`}>
{NAV_BAR_ITEMS.map((item) => {
return (
<NavBarItem icon={item.icon} label={item.label} key={item.key} />
)
})}
</motion.div>
</motion.div>
<motion.div className={styles.layoutNavHot}></motion.div>
</motion.nav>
)
}
.navBarDivider {
width: 40px;
height: 1px;
background: #EFF8FD;
border-radius: 1px;
margin: -12px 0;
}
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
navBarDivider: string
}
declare const cssExports: CssExports
export default cssExports
import { motion } from 'framer-motion'
import styles from './NavBarDivider.module.less'
export const NavBarDivider: React.FC = () => {
return <motion.div className={styles.navBarDivider}></motion.div>
}
export { NavBarDivider } from './NavBarDivider'
.NavBarItem {
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
&:hover {
.icon {
background: hsl(var(--sdream-default) / 0.4) !important;
}
}
}
.icon {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
transition-property: transform, color, background, background-color, border-color, text-decoration-color, fill, stroke, opacity;
transition-timing-function: ease;
transition-duration: 250ms;
border-radius: var(--sdream-radius-medium);
}
.label {
user-select: none;
font-size: 12px;
color: #82969C;
line-height: 14px;
margin-top: 8px;
}
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
NavBarItem: string
icon: string
label: string
navBarItem: string
}
declare const cssExports: CssExports
export default cssExports
import React from 'react'
import { motion } from 'framer-motion'
import { Button } from '@nextui-org/react'
import { NavBarDivider } from '../NavBarDivider'
import styles from './NavBarItem.module.less'
import Logo from '@/assets/svg/logo.svg?react'
interface NavBarItemProps {
icon: React.FunctionComponent<React.SVGProps<SVGSVGElement>> | string
label: string
}
export const NavBarItem: React.FC<NavBarItemProps> = ({ icon, label }) => {
if (label === '' && icon === '') {
return <NavBarDivider />
}
if (label === '' && icon !== '') {
return (
<motion.div className="nav-logo">
<Logo />
</motion.div>
)
}
return (
<motion.div className={`${styles.NavBarItem}`}>
<div className={`${styles.icon}`}>
<Button variant="light" isIconOnly aria-label="Like">
{React.createElement(icon)}
</Button>
</div>
<div className={styles.label}>{label}</div>
</motion.div>
)
}
export { NavBarItem } from './NavBarItem'
export { Navbar } from './Navbar'
export * from './MainLayout'
export * from './Navbar'
import React from 'react'
import { useParams } from 'react-router-dom'
export const Chat: React.FC = () => {
const { chatId } = useParams<{ chatId: string }>()
return (
<h1>
聊天页面 - Chat ID:
{chatId}
</h1>
)
}
export { Chat } from './Chat'
import type React from 'react'
export const Home: React.FC = () => {
return <h1>首页</h1>
}
export { Home } from './Home'
import React from 'react'
import { Route, Routes } from 'react-router-dom'
import { Home } from '../pages/Home'
import { Chat } from '../pages/Chat'
export const AppRoutes: React.FC = () => {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/chat/:chatId" element={<Chat />} />
</Routes>
)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment