v1.0-230926 #27

Merged
FatttSnake merged 81 commits from dev into master 2023-09-26 11:06:08 +08:00
17 changed files with 304 additions and 32 deletions
Showing only changes of commit 2c7b5fd6e0 - Show all commits

View File

@@ -24,11 +24,10 @@ module.exports = {
rules: { rules: {
'no-cond-assign': 'error', 'no-cond-assign': 'error',
'eqeqeq': 'error', 'eqeqeq': 'error',
'indent': ['error', 4, { 'SwitchCase': 1 }],
'prettier/prettier': [ 'prettier/prettier': [
'error', 'error',
{ {
endOfLine: 'auto' endOfLine: 'auto',
} }
], ],
'react-refresh/only-export-components': [ 'react-refresh/only-export-components': [

8
package-lock.json generated
View File

@@ -24,7 +24,7 @@
"@svgr/core": "^8.1.0", "@svgr/core": "^8.1.0",
"@svgr/plugin-jsx": "^8.1.0", "@svgr/plugin-jsx": "^8.1.0",
"@types/jsdom": "^21.1.2", "@types/jsdom": "^21.1.2",
"@types/lodash": "^4.14.197", "@types/lodash": "^4.14.198",
"@types/node": "^20.5.9", "@types/node": "^20.5.9",
"@types/react": "^18.2.21", "@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7", "@types/react-dom": "^18.2.7",
@@ -1519,9 +1519,9 @@
"dev": true "dev": true
}, },
"node_modules/@types/lodash": { "node_modules/@types/lodash": {
"version": "4.14.197", "version": "4.14.198",
"resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.197.tgz", "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.198.tgz",
"integrity": "sha512-BMVOiWs0uNxHVlHBgzTIqJYmj+PgCo4euloGF+5m4okL3rEYzM2EEv78mw8zWSMM57dM7kVIgJ2QDvwHSoCI5g==", "integrity": "sha512-trNJ/vtMZYMLhfN45uLq4ShQSw0/S7xCTLLVM+WM1rmFpba/VS42jVUgaO3w/NOLiWR/09lnYk0yMaA/atdIsg==",
"dev": true "dev": true
}, },
"node_modules/@types/minimist": { "node_modules/@types/minimist": {

View File

@@ -6,7 +6,7 @@
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"dev-host": "vite --host 0.0.0.0", "dev-host": "vite --host 0.0.0.0",
"build": "vite build && tsc && vite build", "build": "vite build",
"clean": "rimraf dist .eslintrc-auto-import.json auto-imports.d.ts", "clean": "rimraf dist .eslintrc-auto-import.json auto-imports.d.ts",
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"format": "prettier --write src/", "format": "prettier --write src/",
@@ -29,7 +29,7 @@
"@svgr/core": "^8.1.0", "@svgr/core": "^8.1.0",
"@svgr/plugin-jsx": "^8.1.0", "@svgr/plugin-jsx": "^8.1.0",
"@types/jsdom": "^21.1.2", "@types/jsdom": "^21.1.2",
"@types/lodash": "^4.14.197", "@types/lodash": "^4.14.198",
"@types/node": "^20.5.9", "@types/node": "^20.5.9",
"@types/react": "^18.2.21", "@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7", "@types/react-dom": "^18.2.7",

View File

@@ -1,10 +1,13 @@
import React from 'react' import React from 'react'
import router from '@/router' import router from '@/router'
import LoadingMask from '@/components/LoadingMask.tsx'
const App: React.FC = () => { const App: React.FC = () => {
return ( return (
<> <>
<Suspense fallback={<LoadingMask />}>
<RouterProvider router={router} /> <RouterProvider router={router} />
</Suspense>
</> </>
) )
} }

View File

@@ -0,0 +1,22 @@
@mixin keyframes($animationName) {
@-webkit-keyframes #{$animationName} {
@content
}
@-moz-keyframes #{$animationName} {
@content
}
@-o-keyframes #{$animationName} {
@content
}
@keyframes #{$animationName} {
@content
}
}
@mixin unique-keyframes {
$animationName: unique-id();
animation-name: $animationName;
@include keyframes($animationName) {
@content
}
}

View File

@@ -6,7 +6,7 @@ $font-secondary-color: #9E9E9E;
.body { .body {
color: $font-main-color; color: $font-main-color;
user-select: none; user-select: none;
min-width: 1800px; min-width: 900px;
min-height: 400px; min-height: 400px;
} }
@@ -103,3 +103,19 @@ $font-secondary-color: #9E9E9E;
height: 23px; height: 23px;
} }
} }
#loading-mask {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
z-index: 100;
background-color: rgba(200, 200, 200, 0.2);
}
#fit-fullscreen {
width: 100vw;
height: 100vh;
}

View File

@@ -1,3 +1,5 @@
@use "mixins" as mixins;
.nav { .nav {
display: flex; display: flex;
position: fixed; position: fixed;
@@ -13,6 +15,16 @@
color: rgba(204, 204, 204, .33); color: rgba(204, 204, 204, .33);
} }
} }
animation: .5s ease both;
@include mixins.unique-keyframes {
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0);
}
}
.logo { .logo {
padding: 0 40px; padding: 0 40px;
@@ -22,4 +34,60 @@
font-family: century gothic, texgyreadventor, stheiti, sans-serif; font-family: century gothic, texgyreadventor, stheiti, sans-serif;
} }
} }
nav {
display: flex;
justify-content: end;
flex: 1;
transition: {
property: all;
duration: .5s;
};
.menu {
padding: 0 30px;
.item {
display: inline-block;
font-size: 1.5em;
transition: {
property: all;
duration: .3s;
};
a {
padding: 5px 20px;
color: rgba(102, 102, 102, .8);
}
}
.active {
border: {
bottom: {
width: 2px;
style: solid;
color: #CCC;
};
};
}
:hover {
transform: translateY(-5px);
}
}
}
}
.nav.hide {
animation: .5s ease both;
@include mixins.unique-keyframes {
0% {
transform: translateY(0);
}
100% {
display: none;
transform: translateY(-100%);
}
}
} }

View File

@@ -1 +0,0 @@
@import url(header.scss);

View File

@@ -0,0 +1 @@
<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="64" height="64"><path d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3 0.1 19.9-16 36-35.9 36z" /></svg>

After

Width:  |  Height:  |  Size: 439 B

View File

@@ -0,0 +1,11 @@
import React from 'react'
const FitFullScreen: React.FC<PropsWithChildren> = (props: PropsWithChildren) => {
return (
<>
<div id={'fit-fullscreen'}>{props.children}</div>
</>
)
}
export default FitFullScreen

24
src/components/Home.tsx Normal file
View File

@@ -0,0 +1,24 @@
import React from 'react'
import '@/assets/css/home.scss'
import { MainFrameworkContext } from '@/pages/MainFramework'
const Home: React.FC = () => {
const {
navbarHiddenState: { navbarHidden, setNavbarHidden }
} = useContext(MainFrameworkContext)
const handleButtonClick = () => {
setNavbarHidden(!navbarHidden)
}
return (
<>
<h1>Home</h1>
<div style={{ marginTop: '100px' }}>
<AntdButton onClick={handleButtonClick}>
{navbarHidden ? '显示' : '隐藏'}
</AntdButton>
</div>
</>
)
}
export default Home

View File

@@ -0,0 +1,27 @@
import React from 'react'
import Icon from '@ant-design/icons'
import FitFullScreen from '@/components/FitFullScreen.tsx'
import { COLOR_FONT_MAIN } from '@/constants/Common.constants.ts'
const LoadingMask: React.FC = () => {
const loadingIcon = (
<>
<Icon
component={IconFatwebLoading as React.ComponentType}
style={{ fontSize: 24, color: COLOR_FONT_MAIN }}
spin
/>
</>
)
return (
<>
<FitFullScreen>
<div id={'loading-mask'}>
<AntdSpin indicator={loadingIcon} />
</div>
</FitFullScreen>
</>
)
}
export default LoadingMask

View File

@@ -0,0 +1,11 @@
import React from 'react'
const Project: React.FC = () => {
return (
<>
<h1>App</h1>
</>
)
}
export default Project

View File

@@ -1,16 +0,0 @@
import React from 'react'
import '@/assets/css/home.scss'
const Home: React.FC = () => {
return (
<>
<header className={'nav'}>
<a className={'logo'} href={'https://fatweb.top'}>
<span className={'title'}>FatWeb</span>
</a>
</header>
</>
)
}
export default Home

View File

@@ -0,0 +1,81 @@
import React, { createContext } from 'react'
import '@/assets/css/header.scss'
import LoadingMask from '@/components/LoadingMask.tsx'
export const MainFrameworkContext = createContext<{
navbarHiddenState: {
navbarHidden: boolean
setNavbarHidden: (newValue: boolean) => void
}
}>({
navbarHiddenState: {
navbarHidden: false,
setNavbarHidden: () => undefined
}
})
const MainFramework: React.FC = () => {
const [navbarHidden, setNavbarHidden] = useState(false)
return (
<>
<div className={'body'}>
<header className={'nav ' + (navbarHidden ? 'hide' : '')}>
<a className={'logo'} href={'https://fatweb.top'}>
<span className={'title'}>FatWeb</span>
</a>
<nav>
<ul className={'menu'}>
<li className={'item'}>
<NavLink
to={''}
className={({ isActive, isPending }) =>
isPending ? 'pending' : isActive ? 'active' : ''
}
>
</NavLink>
</li>
<li className={'item'}>
<NavLink
to={'https://blog.fatweb.top'}
className={({ isActive, isPending }) =>
isPending ? 'pending' : isActive ? 'active' : ''
}
>
</NavLink>
</li>
<li className={'item'}>
<NavLink
to={'project'}
className={({ isActive, isPending }) =>
isPending ? 'pending' : isActive ? 'active' : ''
}
>
App
</NavLink>
</li>
</ul>
</nav>
</header>
<MainFrameworkContext.Provider
value={{ navbarHiddenState: { navbarHidden, setNavbarHidden } }}
>
<Suspense
fallback={
<>
<LoadingMask />
</>
}
>
<Outlet />
</Suspense>
</MainFrameworkContext.Provider>
</div>
</>
)
}
export default MainFramework

View File

@@ -10,14 +10,34 @@ const routes: RouteObject[] = [
id: 'login', id: 'login',
Component: React.lazy(() => import('@/pages/Login')) Component: React.lazy(() => import('@/pages/Login'))
}, },
{
path: '/loading',
id: 'loading',
Component: React.lazy(() => import('@/components/LoadingMask'))
},
{
path: '',
id: 'mainFramework',
Component: React.lazy(() => import('@/pages/MainFramework')),
children: [
{ {
path: '', path: '',
id: 'home', id: 'home',
Component: React.lazy(() => import('@/pages/Home')), Component: React.lazy(() => import('@/components/Home')),
handle: { handle: {
auth: false auth: false
} }
}, },
{
path: 'project',
id: 'project',
Component: React.lazy(() => import('@/components/Project')),
handle: {
auth: false
}
}
]
},
{ {
path: '*', path: '*',
element: <Navigate to="/" replace /> element: <Navigate to="/" replace />

View File

@@ -26,6 +26,7 @@ export default defineConfig({
'react-router', 'react-router',
'react-router-dom', 'react-router-dom',
{ {
react: ['Suspense'],
'react-router': ['useMatches', 'RouterProvider'], 'react-router': ['useMatches', 'RouterProvider'],
'react-router-dom': ['createBrowserRouter'], 'react-router-dom': ['createBrowserRouter'],
antd: ['message'] antd: ['message']
@@ -34,6 +35,11 @@ export default defineConfig({
from: 'react-router', from: 'react-router',
imports: ['RouteObject'], imports: ['RouteObject'],
type: true type: true
},
{
from: 'react',
imports: ['PropsWithChildren'],
type: true
} }
], ],