feat(web): initialize react 19 vite typescript scaffold and token design system
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
weichen
co-authored by
Cursor
parent
ff0262c182
commit
36afce14e6
@@ -48,6 +48,7 @@ temp/
|
||||
dist/
|
||||
build/
|
||||
bin/
|
||||
node_modules/
|
||||
*.exe
|
||||
*.o
|
||||
*.a
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN" data-theme="dark">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>水木东方 · 医疗器械现代 AI 协同工作台</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap"
|
||||
rel="stylesheet"
|
||||
/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
Generated
+1911
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "shuimu-workbench",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build",
|
||||
"preview": "vite preview",
|
||||
"test": "node --test"
|
||||
},
|
||||
"dependencies": {
|
||||
"lucide-react": "^1.16.0",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.10.1",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react": "^5.1.0",
|
||||
"typescript": "~5.9.3",
|
||||
"vite": "^7.1.14"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
export default function App() {
|
||||
const [theme, setTheme] = useState<'dark' | 'light'>('dark');
|
||||
|
||||
const toggleTheme = () => {
|
||||
const next = theme === 'dark' ? 'light' : 'dark';
|
||||
setTheme(next);
|
||||
document.documentElement.setAttribute('data-theme', next);
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ padding: '24px', display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
||||
<h1>水木东方 · 医疗器械现代 AI 协同工作台</h1>
|
||||
<p>当前主题: {theme}</p>
|
||||
<button
|
||||
onClick={toggleTheme}
|
||||
style={{
|
||||
width: '120px',
|
||||
padding: '8px 16px',
|
||||
background: 'var(--brand-500)',
|
||||
color: '#fff',
|
||||
borderRadius: 'var(--r-md)',
|
||||
}}
|
||||
>
|
||||
切换主题
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import App from './App';
|
||||
import './styles/index.css';
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
||||
<App />
|
||||
);
|
||||
@@ -0,0 +1,81 @@
|
||||
@import './tokens.css';
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body, #root {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
font-family: var(--font-sans);
|
||||
background-color: var(--bg-app);
|
||||
color: var(--text);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
统一 6px 自定义极简圆角滚动条
|
||||
============================================================ */
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--border-strong);
|
||||
border-radius: 6px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-faint);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
智能体准备回复中:微光脉冲呼吸动效 (Breathing Pulse)
|
||||
============================================================ */
|
||||
@keyframes agent-pulse {
|
||||
0% {
|
||||
box-shadow: 0 0 0 0 rgba(79, 107, 255, 0.45);
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0 0 16px 4px rgba(107, 132, 255, 0.7);
|
||||
transform: scale(1.02);
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0 0 0 0 rgba(79, 107, 255, 0.45);
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.agent-pulse-active {
|
||||
animation: agent-pulse 2s infinite ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.animate-spin-fast {
|
||||
animation: spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
/* 按钮通用重置 */
|
||||
button {
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
font-family: inherit;
|
||||
outline: none;
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/* ============================================================
|
||||
水木东方医疗器械 AI 协同工作台 — 核心设计变量系统 (Tokens)
|
||||
============================================================ */
|
||||
|
||||
:root {
|
||||
/* 浅色主题 Tokens (Default fallback) */
|
||||
--bg-app: #F4F6FA;
|
||||
--bg-panel: #FFFFFF;
|
||||
--bg-subtle: #F7F8FB;
|
||||
--bg-hover: #EFF1F7;
|
||||
--bg-active: #E9EDF7;
|
||||
--bg-card: #FFFFFF;
|
||||
|
||||
--border: #E4E7F0;
|
||||
--border-strong: #D4D9E5;
|
||||
--border-light: #EEF0F7;
|
||||
|
||||
--text-strong: #1A2233;
|
||||
--text: #3A4356;
|
||||
--text-muted: #7A8299;
|
||||
--text-faint: #A8AFC2;
|
||||
--text-inverse: #FFFFFF;
|
||||
|
||||
--brand-50: #EEF2FF;
|
||||
--brand-100: #DDE5FF;
|
||||
--brand-500: #4F6BFF;
|
||||
--brand-600: #3D55E8;
|
||||
--brand-grad: linear-gradient(135deg, #5A75FF 0%, #3D55E8 100%);
|
||||
|
||||
--amber-50: #FFF7E8;
|
||||
--amber-500: #F2A93B;
|
||||
--amber-600: #DE9420;
|
||||
|
||||
--success: #21A66A;
|
||||
--success-bg: #E8F7F0;
|
||||
--danger: #E4574B;
|
||||
--danger-bg: #FDEBEA;
|
||||
--info: #2B6CC9;
|
||||
--info-bg: #E8F0FE;
|
||||
|
||||
--shadow-xs: 0 1px 2px rgba(26, 34, 51, 0.04);
|
||||
--shadow-sm: 0 1px 3px rgba(26, 34, 51, 0.06), 0 1px 2px rgba(26, 34, 51, 0.04);
|
||||
--shadow-md: 0 6px 20px rgba(26, 34, 51, 0.08), 0 2px 6px rgba(26, 34, 51, 0.05);
|
||||
--shadow-lg: 0 16px 40px rgba(26, 34, 51, 0.12), 0 4px 12px rgba(26, 34, 51, 0.06);
|
||||
|
||||
--ease: cubic-bezier(0.16, 1, 0.3, 1);
|
||||
--font-sans: "Inter", "HarmonyOS Sans", "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
--font-mono: "JetBrains Mono", "SF Mono", monospace;
|
||||
|
||||
--r-sm: 6px;
|
||||
--r-md: 10px;
|
||||
--r-lg: 14px;
|
||||
--r-pill: 999px;
|
||||
}
|
||||
|
||||
/* 深色主题 Tokens */
|
||||
[data-theme="dark"] {
|
||||
--bg-app: #0B0E14;
|
||||
--bg-panel: #131820;
|
||||
--bg-subtle: #1A212C;
|
||||
--bg-hover: #212A37;
|
||||
--bg-active: #27303F;
|
||||
--bg-card: #151B25;
|
||||
|
||||
--border: #242E3F;
|
||||
--border-strong: #334052;
|
||||
--border-light: #1E2735;
|
||||
|
||||
--text-strong: #E7EBF3;
|
||||
--text: #B9C1D0;
|
||||
--text-muted: #8993A7;
|
||||
--text-faint: #5D687C;
|
||||
--text-inverse: #0B0E14;
|
||||
|
||||
--brand-50: #202A4D;
|
||||
--brand-100: #27345E;
|
||||
--brand-500: #6B84FF;
|
||||
--brand-600: #8498FF;
|
||||
--brand-grad: linear-gradient(135deg, #7B92FF 0%, #5A75FF 100%);
|
||||
|
||||
--amber-50: #33290F;
|
||||
--amber-500: #F5B94C;
|
||||
--amber-600: #E5A73A;
|
||||
|
||||
--success: #35C77E;
|
||||
--success-bg: #10301F;
|
||||
--danger: #F06B5F;
|
||||
--danger-bg: #3A1B18;
|
||||
--info: #6FA3F5;
|
||||
--info-bg: #11263F;
|
||||
|
||||
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.3);
|
||||
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.4), 0 1px 2px rgba(0, 0, 0, 0.3);
|
||||
--shadow-md: 0 8px 24px rgba(0, 0, 0, 0.5), 0 2px 6px rgba(0, 0, 0, 0.35);
|
||||
--shadow-lg: 0 18px 48px rgba(0, 0, 0, 0.6), 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": false,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { defineConfig } from 'vite';
|
||||
import react from '@vitejs/plugin-react';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
server: {
|
||||
port: 3000,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://127.0.0.1:8080',
|
||||
changeOrigin: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
emptyOutDir: true,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user